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