Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / ui / views / touchui / touch_editing_menu.cc
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 "ui/base/l10n/l10n_util.h"
9 #include "ui/base/resource/resource_bundle.h"
10 #include "ui/gfx/canvas.h"
11 #include "ui/gfx/font_list.h"
12 #include "ui/gfx/insets.h"
13 #include "ui/gfx/text_utils.h"
14 #include "ui/strings/grit/ui_strings.h"
15 #include "ui/views/bubble/bubble_border.h"
16 #include "ui/views/bubble/bubble_frame_view.h"
17 #include "ui/views/controls/button/custom_button.h"
18 #include "ui/views/controls/button/label_button.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 kMenuButtonMinHeight = 38;
30 const int kMenuButtonMinWidth = 63;
31 const int kMenuMargin = 1;
32
33 const char* kEllipsesButtonText = "...";
34 const int kEllipsesButtonTag = -1;
35 }  // namespace
36
37 namespace views {
38
39 TouchEditingMenuView::TouchEditingMenuView(
40     TouchEditingMenuController* controller,
41     const gfx::Rect& anchor_rect,
42     const gfx::Size& handle_image_size,
43     gfx::NativeView context)
44     : BubbleDelegateView(NULL, views::BubbleBorder::BOTTOM_CENTER),
45       controller_(controller) {
46   set_shadow(views::BubbleBorder::SMALL_SHADOW);
47   set_parent_window(context);
48   set_margins(gfx::Insets(kMenuMargin, kMenuMargin, kMenuMargin, kMenuMargin));
49   set_can_activate(false);
50   set_adjust_if_offscreen(true);
51
52   SetLayoutManager(new BoxLayout(BoxLayout::kHorizontal, 0, 0,
53       kSpacingBetweenButtons));
54   CreateButtons();
55
56   // After buttons are created, check if there is enough room between handles to
57   // show the menu and adjust anchor rect properly if needed, just in case the
58   // menu is needed to be shown under the selection.
59   gfx::Rect adjusted_anchor_rect(anchor_rect);
60   int menu_width = GetPreferredSize().width();
61   if (menu_width > anchor_rect.width() - handle_image_size.width())
62     adjusted_anchor_rect.Inset(0, 0, 0, -handle_image_size.height());
63   SetAnchorRect(adjusted_anchor_rect);
64
65   views::BubbleDelegateView::CreateBubble(this);
66   GetWidget()->Show();
67 }
68
69 TouchEditingMenuView::~TouchEditingMenuView() {
70 }
71
72 // static
73 TouchEditingMenuView* TouchEditingMenuView::Create(
74     TouchEditingMenuController* controller,
75     const gfx::Rect& anchor_rect,
76     const gfx::Size& handle_image_size,
77     gfx::NativeView context) {
78   if (controller) {
79     for (size_t i = 0; i < arraysize(kMenuCommands); i++) {
80       if (controller->IsCommandIdEnabled(kMenuCommands[i])) {
81         return new TouchEditingMenuView(controller, anchor_rect,
82                                         handle_image_size, context);
83       }
84     }
85   }
86   return NULL;
87 }
88
89 void TouchEditingMenuView::Close() {
90   if (GetWidget()) {
91     controller_ = NULL;
92     GetWidget()->Close();
93   }
94 }
95
96 void TouchEditingMenuView::WindowClosing() {
97   views::BubbleDelegateView::WindowClosing();
98   if (controller_)
99     controller_->OnMenuClosed(this);
100 }
101
102 void TouchEditingMenuView::ButtonPressed(Button* sender,
103                                          const ui::Event& event) {
104   if (controller_) {
105     if (sender->tag() != kEllipsesButtonTag)
106       controller_->ExecuteCommand(sender->tag(), event.flags());
107     else
108       controller_->OpenContextMenu();
109   }
110 }
111
112 void TouchEditingMenuView::OnPaint(gfx::Canvas* canvas) {
113   BubbleDelegateView::OnPaint(canvas);
114
115   // Draw separator bars.
116   for (int i = 0; i < child_count() - 1; ++i) {
117     View* child = child_at(i);
118     int x = child->bounds().right() + kSpacingBetweenButtons / 2;
119     canvas->FillRect(gfx::Rect(x, 0, 1, child->height()),
120         kButtonSeparatorColor);
121   }
122 }
123
124 void TouchEditingMenuView::CreateButtons() {
125   RemoveAllChildViews(true);
126   for (size_t i = 0; i < arraysize(kMenuCommands); i++) {
127     int command_id = kMenuCommands[i];
128     if (controller_ && controller_->IsCommandIdEnabled(command_id)) {
129       Button* button = CreateButton(l10n_util::GetStringUTF16(command_id),
130           command_id);
131       AddChildView(button);
132     }
133   }
134
135   // Finally, add ellipses button.
136   AddChildView(CreateButton(
137       base::UTF8ToUTF16(kEllipsesButtonText), kEllipsesButtonTag));
138   Layout();
139 }
140
141 Button* TouchEditingMenuView::CreateButton(const base::string16& title,
142                                            int tag) {
143   base::string16 label = gfx::RemoveAcceleratorChar(title, '&', NULL, NULL);
144   LabelButton* button = new LabelButton(this, label);
145   button->SetMinSize(gfx::Size(kMenuButtonMinWidth, kMenuButtonMinHeight));
146   button->SetFocusable(true);
147   button->set_request_focus_on_press(false);
148   const gfx::FontList& font_list =
149       ui::ResourceBundle::GetSharedInstance().GetFontList(
150           ui::ResourceBundle::SmallFont);
151   button->SetFontList(font_list);
152   button->SetHorizontalAlignment(gfx::ALIGN_CENTER);
153   button->set_tag(tag);
154   return button;
155 }
156
157 }  // namespace views