• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
33 const char* kEllipsesButtonText = "...";
34 const int kEllipsesButtonTag = -1;
35 }  // namespace
36 
37 namespace views {
38 
TouchEditingMenuView(TouchEditingMenuController * controller,gfx::Rect anchor_rect,gfx::NativeView context)39 TouchEditingMenuView::TouchEditingMenuView(
40     TouchEditingMenuController* controller,
41     gfx::Rect anchor_rect,
42     gfx::NativeView context)
43     : BubbleDelegateView(NULL, views::BubbleBorder::BOTTOM_CENTER),
44       controller_(controller) {
45   SetAnchorRect(anchor_rect);
46   set_shadow(views::BubbleBorder::SMALL_SHADOW);
47   set_parent_window(context);
48   set_margins(gfx::Insets(kMenuMargin, kMenuMargin, kMenuMargin, kMenuMargin));
49   set_use_focusless(true);
50   set_adjust_if_offscreen(true);
51 
52   SetLayoutManager(new BoxLayout(BoxLayout::kHorizontal, 0, 0,
53       kSpacingBetweenButtons));
54   CreateButtons();
55   views::BubbleDelegateView::CreateBubble(this);
56   GetWidget()->Show();
57 }
58 
~TouchEditingMenuView()59 TouchEditingMenuView::~TouchEditingMenuView() {
60 }
61 
62 // static
Create(TouchEditingMenuController * controller,gfx::Rect anchor_rect,gfx::NativeView context)63 TouchEditingMenuView* TouchEditingMenuView::Create(
64     TouchEditingMenuController* controller,
65     gfx::Rect anchor_rect,
66     gfx::NativeView context) {
67   if (controller) {
68     for (size_t i = 0; i < arraysize(kMenuCommands); i++) {
69       if (controller->IsCommandIdEnabled(kMenuCommands[i]))
70         return new TouchEditingMenuView(controller, anchor_rect, context);
71     }
72   }
73   return NULL;
74 }
75 
Close()76 void TouchEditingMenuView::Close() {
77   if (GetWidget()) {
78     controller_ = NULL;
79     GetWidget()->Close();
80   }
81 }
82 
WindowClosing()83 void TouchEditingMenuView::WindowClosing() {
84   views::BubbleDelegateView::WindowClosing();
85   if (controller_)
86     controller_->OnMenuClosed(this);
87 }
88 
ButtonPressed(Button * sender,const ui::Event & event)89 void TouchEditingMenuView::ButtonPressed(Button* sender,
90                                          const ui::Event& event) {
91   if (controller_) {
92     if (sender->tag() != kEllipsesButtonTag)
93       controller_->ExecuteCommand(sender->tag(), event.flags());
94     else
95       controller_->OpenContextMenu();
96   }
97 }
98 
OnPaint(gfx::Canvas * canvas)99 void TouchEditingMenuView::OnPaint(gfx::Canvas* canvas) {
100   BubbleDelegateView::OnPaint(canvas);
101 
102   // Draw separator bars.
103   for (int i = 0; i < child_count() - 1; ++i) {
104     View* child = child_at(i);
105     int x = child->bounds().right() + kSpacingBetweenButtons / 2;
106     canvas->FillRect(gfx::Rect(x, 0, 1, child->height()),
107         kButtonSeparatorColor);
108   }
109 }
110 
CreateButtons()111 void TouchEditingMenuView::CreateButtons() {
112   RemoveAllChildViews(true);
113   for (size_t i = 0; i < arraysize(kMenuCommands); i++) {
114     int command_id = kMenuCommands[i];
115     if (controller_ && controller_->IsCommandIdEnabled(command_id)) {
116       Button* button = CreateButton(l10n_util::GetStringUTF16(command_id),
117           command_id);
118       AddChildView(button);
119     }
120   }
121 
122   // Finally, add ellipses button.
123   AddChildView(CreateButton(
124       UTF8ToUTF16(kEllipsesButtonText), kEllipsesButtonTag));
125   Layout();
126 }
127 
CreateButton(const string16 & title,int tag)128 Button* TouchEditingMenuView::CreateButton(const string16& title, int tag) {
129   string16 label = gfx::RemoveAcceleratorChar(title, '&', NULL, NULL);
130   LabelButton* button = new LabelButton(this, label);
131   button->SetFocusable(true);
132   button->set_request_focus_on_press(false);
133   gfx::Font font = ui::ResourceBundle::GetSharedInstance().GetFont(
134       ui::ResourceBundle::SmallFont);
135   scoped_ptr<LabelButtonBorder> button_border(
136       new LabelButtonBorder(button->style()));
137   int v_border = (kMenuButtonHeight - font.GetHeight()) / 2;
138   int h_border = (kMenuButtonWidth - font.GetStringWidth(label)) / 2;
139   button_border->set_insets(
140       gfx::Insets(v_border, h_border, v_border, h_border));
141   button->set_border(button_border.release());
142   button->SetFont(font);
143   button->set_tag(tag);
144   return button;
145 }
146 
147 }  // namespace views
148