Home | History | Annotate | Download | only in touchui
      1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "ui/views/touchui/touch_editing_menu.h"
      6 
      7 #include "base/strings/utf_string_conversions.h"
      8 #include "grit/ui_strings.h"
      9 #include "ui/base/l10n/l10n_util.h"
     10 #include "ui/base/resource/resource_bundle.h"
     11 #include "ui/gfx/canvas.h"
     12 #include "ui/gfx/insets.h"
     13 #include "ui/gfx/text_utils.h"
     14 #include "ui/views/bubble/bubble_border.h"
     15 #include "ui/views/bubble/bubble_frame_view.h"
     16 #include "ui/views/controls/button/custom_button.h"
     17 #include "ui/views/controls/button/label_button.h"
     18 #include "ui/views/controls/button/label_button_border.h"
     19 #include "ui/views/layout/box_layout.h"
     20 #include "ui/views/widget/widget.h"
     21 
     22 namespace {
     23 
     24 const int kMenuCommands[] = {IDS_APP_CUT,
     25                              IDS_APP_COPY,
     26                              IDS_APP_PASTE};
     27 const int kSpacingBetweenButtons = 2;
     28 const int kButtonSeparatorColor = SkColorSetARGB(13, 0, 0, 0);
     29 const int kMenuButtonHeight = 38;
     30 const int kMenuButtonWidth = 63;
     31 const int kMenuMargin = 1;
     32 const SkColor kMenuButtonColorNormal = SkColorSetARGB(102, 255, 255, 255);
     33 const SkColor kMenuButtonColorHover = SkColorSetARGB(13, 0, 0, 0);
     34 
     35 const char* kEllipsesButtonText = "...";
     36 const int kEllipsesButtonTag = -1;
     37 }  // namespace
     38 
     39 namespace views {
     40 
     41 class TouchEditingMenuButtonBorder : public LabelButtonBorder {
     42  public:
     43   TouchEditingMenuButtonBorder(Button::ButtonStyle style,
     44                                const gfx::Insets& insets)
     45       : LabelButtonBorder(style),
     46         insets_(insets) {
     47   }
     48 
     49   virtual ~TouchEditingMenuButtonBorder() {
     50   }
     51 
     52  private:
     53   // Overridden from LabelButtonBorder
     54   virtual gfx::Insets GetInsets() const OVERRIDE {
     55     return insets_;
     56   }
     57 
     58   gfx::Insets insets_;
     59 
     60   DISALLOW_COPY_AND_ASSIGN(TouchEditingMenuButtonBorder);
     61 };
     62 
     63 TouchEditingMenuView::TouchEditingMenuView(
     64     TouchEditingMenuController* controller,
     65     gfx::Rect anchor_rect,
     66     gfx::NativeView context)
     67     : BubbleDelegateView(NULL, views::BubbleBorder::BOTTOM_CENTER),
     68       controller_(controller) {
     69   set_anchor_rect(anchor_rect);
     70   set_shadow(views::BubbleBorder::SMALL_SHADOW);
     71   set_parent_window(context);
     72   set_margins(gfx::Insets(kMenuMargin, kMenuMargin, kMenuMargin, kMenuMargin));
     73   set_use_focusless(true);
     74   set_adjust_if_offscreen(true);
     75 
     76   SetLayoutManager(new BoxLayout(BoxLayout::kHorizontal, 0, 0,
     77       kSpacingBetweenButtons));
     78   CreateButtons();
     79   views::BubbleDelegateView::CreateBubble(this);
     80   GetWidget()->Show();
     81 }
     82 
     83 TouchEditingMenuView::~TouchEditingMenuView() {
     84 }
     85 
     86 // static
     87 TouchEditingMenuView* TouchEditingMenuView::Create(
     88     TouchEditingMenuController* controller,
     89     gfx::Rect anchor_rect,
     90     gfx::NativeView context) {
     91   if (controller) {
     92     for (size_t i = 0; i < arraysize(kMenuCommands); i++) {
     93       if (controller->IsCommandIdEnabled(kMenuCommands[i]))
     94         return new TouchEditingMenuView(controller, anchor_rect, context);
     95     }
     96   }
     97   return NULL;
     98 }
     99 
    100 void TouchEditingMenuView::Close() {
    101   if (GetWidget()) {
    102     controller_ = NULL;
    103     GetWidget()->Close();
    104   }
    105 }
    106 
    107 void TouchEditingMenuView::WindowClosing() {
    108   views::BubbleDelegateView::WindowClosing();
    109   if (controller_)
    110     controller_->OnMenuClosed(this);
    111 }
    112 
    113 void TouchEditingMenuView::ButtonPressed(Button* sender,
    114                                          const ui::Event& event) {
    115   if (controller_) {
    116     if (sender->tag() != kEllipsesButtonTag)
    117       controller_->ExecuteCommand(sender->tag(), event.flags());
    118     else
    119       controller_->OpenContextMenu();
    120   }
    121 }
    122 
    123 void TouchEditingMenuView::OnPaint(gfx::Canvas* canvas) {
    124   BubbleDelegateView::OnPaint(canvas);
    125 
    126   // Draw separator bars.
    127   for (int i = 0; i < child_count() - 1; ++i) {
    128     View* child = child_at(i);
    129     int x = child->bounds().right() + kSpacingBetweenButtons / 2;
    130     canvas->FillRect(gfx::Rect(x, 0, 1, child->height()),
    131         kButtonSeparatorColor);
    132   }
    133 }
    134 
    135 void TouchEditingMenuView::CreateButtons() {
    136   RemoveAllChildViews(true);
    137   for (size_t i = 0; i < arraysize(kMenuCommands); i++) {
    138     int command_id = kMenuCommands[i];
    139     if (controller_ && controller_->IsCommandIdEnabled(command_id)) {
    140       Button* button = CreateButton(l10n_util::GetStringUTF16(command_id),
    141           command_id);
    142       AddChildView(button);
    143     }
    144   }
    145 
    146   // Finally, add ellipses button.
    147   AddChildView(CreateButton(
    148       UTF8ToUTF16(kEllipsesButtonText), kEllipsesButtonTag));
    149   Layout();
    150 }
    151 
    152 Button* TouchEditingMenuView::CreateButton(const string16& title, int tag) {
    153   string16 label = gfx::RemoveAcceleratorChar(title, '&', NULL, NULL);
    154   LabelButton* button = new LabelButton(this, label);
    155   button->set_focusable(true);
    156   button->set_request_focus_on_press(false);
    157   gfx::Font font = ui::ResourceBundle::GetSharedInstance().GetFont(
    158       ui::ResourceBundle::SmallFont);
    159   int v_border = (kMenuButtonHeight - font.GetHeight()) / 2;
    160   int h_border = (kMenuButtonWidth - font.GetStringWidth(label)) / 2;
    161   button->set_border(new TouchEditingMenuButtonBorder(button->style(),
    162       gfx::Insets(v_border, h_border, v_border, h_border)));
    163   button->SetFont(font);
    164   button->set_tag(tag);
    165   return button;
    166 }
    167 
    168 }  // namespace views
    169