wrench_menu.cc revision 3f50c38dc070f4bb515c1b64450dae14f316474e
1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/views/wrench_menu.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <cmath>
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "app/l10n_util.h"
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "app/resource_bundle.h"
113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_number_conversions.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/utf_string_conversions.h"
13513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "chrome/app/chrome_command_ids.h"
1421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h"
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/tab_contents/tab_contents.h"
164a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/ui/browser.h"
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/notification_observer.h"
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/notification_registrar.h"
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/notification_source.h"
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/notification_type.h"
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "gfx/canvas.h"
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "gfx/canvas_skia.h"
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "gfx/skia_util.h"
243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "grit/chromium_strings.h"
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/generated_resources.h"
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/theme_resources.h"
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "third_party/skia/include/core/SkPaint.h"
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/background.h"
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/controls/button/image_button.h"
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/controls/button/menu_button.h"
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/controls/button/text_button.h"
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/controls/label.h"
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/controls/menu/menu_config.h"
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/controls/menu/menu_item_view.h"
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/controls/menu/menu_scroll_view_container.h"
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/controls/menu/submenu_view.h"
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/window/window.h"
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing menus::MenuModel;
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing views::CustomButton;
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing views::ImageButton;
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing views::Label;
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing views::MenuConfig;
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing views::MenuItemView;
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing views::TextButton;
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing views::View;
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Colors used for buttons.
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst SkColor kHotBorderColor = SkColorSetARGB(72, 0, 0, 0);
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst SkColor kBorderColor = SkColorSetARGB(36, 0, 0, 0);
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst SkColor kPushedBorderColor = SkColorSetARGB(72, 0, 0, 0);
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst SkColor kHotBackgroundColor = SkColorSetARGB(204, 255, 255, 255);
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst SkColor kBackgroundColor = SkColorSetARGB(102, 255, 255, 255);
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst SkColor kPushedBackgroundColor = SkColorSetARGB(13, 0, 0, 0);
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Horizontal padding on the edges of the buttons.
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kHorizontalPadding = 6;
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Subclass of ImageButton whose preferred size includes the size of the border.
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass FullscreenButton : public ImageButton {
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  explicit FullscreenButton(views::ButtonListener* listener)
653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      : ImageButton(listener) { }
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual gfx::Size GetPreferredSize() {
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    gfx::Size pref = ImageButton::GetPreferredSize();
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    gfx::Insets insets;
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (border())
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      border()->GetInsets(&insets);
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    pref.Enlarge(insets.width(), insets.height());
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return pref;
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(FullscreenButton);
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Border for buttons contained in the menu. This is only used for getting the
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// insets, the actual painting is done in MenuButtonBackground.
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass MenuButtonBorder : public views::Border {
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MenuButtonBorder() {}
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void Paint(const View& view, gfx::Canvas* canvas) const {
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Painting of border is done in MenuButtonBackground.
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void GetInsets(gfx::Insets* insets) const {
913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    insets->Set(MenuConfig::instance().item_top_margin,
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                kHorizontalPadding,
933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                MenuConfig::instance().item_bottom_margin,
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                kHorizontalPadding);
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(MenuButtonBorder);
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Combination border/background for the buttons contained in the menu. The
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// painting of the border/background is done here as TextButton does not always
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// paint the border.
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass MenuButtonBackground : public views::Background {
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  enum ButtonType {
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    LEFT_BUTTON,
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CENTER_BUTTON,
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    RIGHT_BUTTON,
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    SINGLE_BUTTON,
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  explicit MenuButtonBackground(ButtonType type)
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      : type_(type),
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        left_button_(NULL),
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        right_button_(NULL) {}
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Used when the type is CENTER_BUTTON to determine if the left/right edge
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // needs to be rendered selected.
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void SetOtherButtons(CustomButton* left_button, CustomButton* right_button) {
1213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (base::i18n::IsRTL()) {
1223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      left_button_ = right_button;
1233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      right_button_ = left_button;
1243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    } else {
1253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      left_button_ = left_button;
1263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      right_button_ = right_button;
1273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void Paint(gfx::Canvas* canvas, View* view) const {
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CustomButton::ButtonState state =
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        (view->GetClassName() == views::Label::kViewClassName) ?
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        CustomButton::BS_NORMAL : static_cast<CustomButton*>(view)->state();
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int w = view->width();
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int h = view->height();
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    switch (TypeAdjustedForRTL()) {
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case LEFT_BUTTON:
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(background_color(state), 1, 1, w, h - 2);
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(border_color(state), 2, 0, w, 1);
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(border_color(state), 1, 1, 1, 1);
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(border_color(state), 0, 2, 1, h - 4);
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(border_color(state), 1, h - 2, 1, 1);
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(border_color(state), 2, h - 1, w, 1);
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case CENTER_BUTTON: {
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(background_color(state), 1, 1, w - 2, h - 2);
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        SkColor left_color = state != CustomButton::BS_NORMAL ?
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            border_color(state) : border_color(left_button_->state());
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(left_color, 0, 0, 1, h);
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(border_color(state), 1, 0, w - 2, 1);
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(border_color(state), 1, h - 1, w - 2, 1);
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        SkColor right_color = state != CustomButton::BS_NORMAL ?
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            border_color(state) : border_color(right_button_->state());
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(right_color, w - 1, 0, 1, h);
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case RIGHT_BUTTON:
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(background_color(state), 0, 1, w - 1, h - 2);
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(border_color(state), 0, 0, w - 2, 1);
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(border_color(state), w - 2, 1, 1, 1);
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(border_color(state), w - 1, 2, 1, h - 4);
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(border_color(state), w - 2, h - 2, 1, 1);
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(border_color(state), 0, h - 1, w - 2, 1);
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case SINGLE_BUTTON:
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(background_color(state), 1, 1, w - 2, h - 2);
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(border_color(state), 2, 0, w - 4, 1);
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(border_color(state), 1, 1, 1, 1);
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(border_color(state), 0, 2, 1, h - 4);
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(border_color(state), 1, h - 2, 1, 1);
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(border_color(state), 2, h - 1, w - 4, 1);
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(border_color(state), w - 2, 1, 1, 1);
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(border_color(state), w - 1, 2, 1, h - 4);
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(border_color(state), w - 2, h - 2, 1, 1);
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      default:
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        NOTREACHED();
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static SkColor border_color(CustomButton::ButtonState state) {
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    switch (state) {
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case CustomButton::BS_HOT:    return kHotBorderColor;
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case CustomButton::BS_PUSHED: return kPushedBorderColor;
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      default:                      return kBorderColor;
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static SkColor background_color(CustomButton::ButtonState state) {
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    switch (state) {
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case CustomButton::BS_HOT:    return kHotBackgroundColor;
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case CustomButton::BS_PUSHED: return kPushedBackgroundColor;
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      default:                      return kBackgroundColor;
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ButtonType TypeAdjustedForRTL() const {
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!base::i18n::IsRTL())
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return type_;
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    switch (type_) {
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case LEFT_BUTTON:   return RIGHT_BUTTON;
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case RIGHT_BUTTON:  return LEFT_BUTTON;
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      default:            break;
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return type_;
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const ButtonType type_;
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // See description above setter for details.
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CustomButton* left_button_;
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CustomButton* right_button_;
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(MenuButtonBackground);
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A View subclass that forces SchedulePaint to paint all. Normally when the
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// mouse enters/exits a button the buttons invokes SchedulePaint. As part of the
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// button border (MenuButtonBackground) is rendered by the button to the
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// left/right of it SchedulePaint on the the button may not be enough, so this
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// forces a paint all.
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ScheduleAllView : public views::View {
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ScheduleAllView() {}
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void SchedulePaint(const gfx::Rect& r, bool urgent) {
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!IsVisible())
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return;
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (GetParent()) {
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GetParent()->SchedulePaint(GetBounds(APPLY_MIRRORING_TRANSFORMATION),
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                 urgent);
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(ScheduleAllView);
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
247731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstd::wstring GetAccessibleNameForWrenchMenuItem(
248731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      MenuModel* model, int item_index, int accessible_string_id) {
2493f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  std::wstring accessible_name =
2503f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      UTF16ToWide(l10n_util::GetStringUTF16(accessible_string_id));
251731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  std::wstring accelerator_text;
252731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
253731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  menus::Accelerator menu_accelerator;
254731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (model->GetAcceleratorAt(item_index, &menu_accelerator)) {
255731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    accelerator_text =
256731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        views::Accelerator(menu_accelerator.GetKeyCode(),
257731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                           menu_accelerator.modifiers()).GetShortcutText();
258731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
259731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
260731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  return MenuItemView::GetAccessibleNameForMenuItem(
261731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      accessible_name, accelerator_text);
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
264731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// WrenchMenuView is a view that can contain text buttons.
265731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickclass WrenchMenuView : public ScheduleAllView, public views::ButtonListener {
266731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick public:
267731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  WrenchMenuView(WrenchMenu* menu, MenuModel* menu_model)
268731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      : menu_(menu), menu_model_(menu_model) { }
269731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
270731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  TextButton* CreateAndConfigureButton(int string_id,
271731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                       MenuButtonBackground::ButtonType type,
272731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                       int index,
273731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                       MenuButtonBackground** background) {
274731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return CreateButtonWithAccName(
275731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      string_id, type, index, background, string_id);
276731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
277731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
278731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  TextButton* CreateButtonWithAccName(int string_id,
279731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                      MenuButtonBackground::ButtonType type,
280731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                      int index,
281731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                      MenuButtonBackground** background,
282731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                      int acc_string_id) {
283731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    TextButton* button =
2843f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        new TextButton(this, UTF16ToWide(l10n_util::GetStringUTF16(string_id)));
285731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    button->SetAccessibleName(
286731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        GetAccessibleNameForWrenchMenuItem(menu_model_, index, acc_string_id));
287731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    button->SetFocusable(true);
288731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    button->set_request_focus_on_press(false);
289731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    button->set_tag(index);
290731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    button->SetEnabled(menu_model_->IsEnabledAt(index));
291731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    button->set_prefix_type(TextButton::PREFIX_HIDE);
292731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    MenuButtonBackground* bg = new MenuButtonBackground(type);
293731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    button->set_background(bg);
294731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    button->SetEnabledColor(MenuConfig::instance().text_color);
295731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    if (background)
296731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      *background = bg;
297731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    button->set_border(new MenuButtonBorder());
298731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    button->set_alignment(TextButton::ALIGN_CENTER);
299731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    button->SetNormalHasBorder(true);
300731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    button->SetFont(views::MenuConfig::instance().font);
301731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    button->ClearMaxTextSize();
302731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    AddChildView(button);
303731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return button;
304731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
305731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
306731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick protected:
307731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Hosting WrenchMenu.
308731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  WrenchMenu* menu_;
309731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
310731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // The menu model containing the increment/decrement/reset items.
311731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MenuModel* menu_model_;
312731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
313731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick private:
314731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DISALLOW_COPY_AND_ASSIGN(WrenchMenuView);
315731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick};
316731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace
318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// CutCopyPasteView ------------------------------------------------------------
320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// CutCopyPasteView is the view containing the cut/copy/paste buttons.
322731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickclass WrenchMenu::CutCopyPasteView : public WrenchMenuView {
323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CutCopyPasteView(WrenchMenu* menu,
325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   MenuModel* menu_model,
326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   int cut_index,
327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   int copy_index,
328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   int paste_index)
329731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      : WrenchMenuView(menu, menu_model) {
330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TextButton* cut = CreateAndConfigureButton(
331731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        IDS_CUT, MenuButtonBackground::LEFT_BUTTON, cut_index, NULL);
332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MenuButtonBackground* copy_background = NULL;
334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CreateAndConfigureButton(
335731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        IDS_COPY, MenuButtonBackground::CENTER_BUTTON, copy_index,
336731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        &copy_background);
337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TextButton* paste = CreateAndConfigureButton(
339731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        IDS_PASTE, MenuButtonBackground::RIGHT_BUTTON, paste_index, NULL);
340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    copy_background->SetOtherButtons(cut, paste);
342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::Size GetPreferredSize() {
345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Returned height doesn't matter as MenuItemView forces everything to the
346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // height of the menuitemview.
347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return gfx::Size(GetMaxChildViewPreferredWidth() * GetChildViewCount(), 0);
348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void Layout() {
351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // All buttons are given the same width.
352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int width = GetMaxChildViewPreferredWidth();
353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (int i = 0; i < GetChildViewCount(); ++i)
354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GetChildViewAt(i)->SetBounds(i * width, 0, width, height());
355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // ButtonListener
358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void ButtonPressed(views::Button* sender, const views::Event& event) {
359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    menu_->CancelAndEvaluate(menu_model_, sender->tag());
360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Returns the max preferred width of all the children.
364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int GetMaxChildViewPreferredWidth() {
365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int width = 0;
366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (int i = 0; i < GetChildViewCount(); ++i)
367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      width = std::max(width, GetChildViewAt(i)->GetPreferredSize().width());
368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return width;
369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(CutCopyPasteView);
372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ZoomView --------------------------------------------------------------------
375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Padding between the increment buttons and the reset button.
377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const int kZoomPadding = 6;
378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ZoomView contains the various zoom controls: two buttons to increase/decrease
380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the zoom, a label showing the current zoom percent, and a button to go
381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// full-screen.
382731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickclass WrenchMenu::ZoomView : public WrenchMenuView,
383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             public NotificationObserver {
384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ZoomView(WrenchMenu* menu,
386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch           MenuModel* menu_model,
387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch           int decrement_index,
388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch           int increment_index,
389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch           int fullscreen_index)
390731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      : WrenchMenuView(menu, menu_model),
391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        fullscreen_index_(fullscreen_index),
392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        increment_button_(NULL),
393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        zoom_label_(NULL),
394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        decrement_button_(NULL),
395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        fullscreen_button_(NULL),
396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        zoom_label_width_(0) {
397731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    decrement_button_ = CreateButtonWithAccName(
398731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        IDS_ZOOM_MINUS2, MenuButtonBackground::LEFT_BUTTON, decrement_index,
399731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        NULL, IDS_ACCNAME_ZOOM_MINUS2);
400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4013f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    zoom_label_ = new Label(
4023f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        UTF16ToWide(l10n_util::GetStringFUTF16Int(IDS_ZOOM_PERCENT, 100)));
403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    zoom_label_->SetColor(MenuConfig::instance().text_color);
404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    zoom_label_->SetHorizontalAlignment(Label::ALIGN_RIGHT);
405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MenuButtonBackground* center_bg =
406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        new MenuButtonBackground(MenuButtonBackground::CENTER_BUTTON);
407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    zoom_label_->set_background(center_bg);
408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    zoom_label_->set_border(new MenuButtonBorder());
409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    zoom_label_->SetFont(MenuConfig::instance().font);
410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AddChildView(zoom_label_);
411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    zoom_label_width_ = MaxWidthForZoomLabel();
412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
413731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    increment_button_ = CreateButtonWithAccName(
414731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        IDS_ZOOM_PLUS2, MenuButtonBackground::RIGHT_BUTTON, increment_index,
415731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        NULL, IDS_ACCNAME_ZOOM_PLUS2);
416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    center_bg->SetOtherButtons(decrement_button_, increment_button_);
418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    fullscreen_button_ = new FullscreenButton(this);
420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    fullscreen_button_->SetImage(
421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        ImageButton::BS_NORMAL,
422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        ResourceBundle::GetSharedInstance().GetBitmapNamed(
423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            IDR_FULLSCREEN_MENU_BUTTON));
424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    fullscreen_button_->SetFocusable(true);
425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    fullscreen_button_->set_request_focus_on_press(false);
426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    fullscreen_button_->set_tag(fullscreen_index);
427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    fullscreen_button_->SetImageAlignment(
428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        ImageButton::ALIGN_CENTER, ImageButton::ALIGN_MIDDLE);
429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    fullscreen_button_->set_border(views::Border::CreateEmptyBorder(
430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        0, kHorizontalPadding, 0, kHorizontalPadding));
431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    fullscreen_button_->set_background(
432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        new MenuButtonBackground(MenuButtonBackground::SINGLE_BUTTON));
4333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    fullscreen_button_->SetAccessibleName(
434731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        GetAccessibleNameForWrenchMenuItem(
435731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick            menu_model, fullscreen_index, IDS_ACCNAME_FULLSCREEN));
436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AddChildView(fullscreen_button_);
437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    UpdateZoomControls();
439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    registrar_.Add(this, NotificationType::ZOOM_LEVEL_CHANGED,
441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   Source<Profile>(menu->browser_->profile()));
442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::Size GetPreferredSize() {
445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // The increment/decrement button are forced to the same width.
446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int button_width = std::max(increment_button_->GetPreferredSize().width(),
447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                decrement_button_->GetPreferredSize().width());
448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int fullscreen_width = fullscreen_button_->GetPreferredSize().width();
449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Returned height doesn't matter as MenuItemView forces everything to the
450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // height of the menuitemview.
451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return gfx::Size(button_width + zoom_label_width_ + button_width +
452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                     kZoomPadding + fullscreen_width, 0);
453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void Layout() {
456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int x = 0;
457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int button_width = std::max(increment_button_->GetPreferredSize().width(),
458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                decrement_button_->GetPreferredSize().width());
459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    gfx::Rect bounds(0, 0, button_width, height());
460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    decrement_button_->SetBounds(bounds);
462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    x += bounds.width();
464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bounds.set_x(x);
465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bounds.set_width(zoom_label_width_);
466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    zoom_label_->SetBounds(bounds);
467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    x += bounds.width();
469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bounds.set_x(x);
470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bounds.set_width(button_width);
471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    increment_button_->SetBounds(bounds);
472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    x += bounds.width() + kZoomPadding;
474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bounds.set_x(x);
475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bounds.set_width(fullscreen_button_->GetPreferredSize().width());
476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    fullscreen_button_->SetBounds(bounds);
477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // ButtonListener:
480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void ButtonPressed(views::Button* sender, const views::Event& event) {
481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (sender->tag() == fullscreen_index_) {
482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      menu_->CancelAndEvaluate(menu_model_, sender->tag());
483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else {
484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Zoom buttons don't close the menu.
485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      menu_model_->ActivatedAt(sender->tag());
486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // NotificationObserver:
490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void Observe(NotificationType type,
491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       const NotificationSource& source,
492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       const NotificationDetails& details) {
493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK_EQ(NotificationType::ZOOM_LEVEL_CHANGED, type.value);
494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    UpdateZoomControls();
495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void UpdateZoomControls() {
499731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    bool enable_increment = false;
500731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    bool enable_decrement = false;
501731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    TabContents* selected_tab = menu_->browser_->GetSelectedTabContents();
502731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    int zoom = 100;
503731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    if (selected_tab)
504731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      zoom = selected_tab->GetZoomPercent(&enable_increment, &enable_decrement);
505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    increment_button_->SetEnabled(enable_increment);
506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    decrement_button_->SetEnabled(enable_decrement);
5073f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    zoom_label_->SetText(UTF16ToWide(l10n_util::GetStringFUTF16Int(
5083f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                     IDS_ZOOM_PERCENT,
5093f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                     zoom)));
510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
511731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    zoom_label_width_ = MaxWidthForZoomLabel();
512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Calculates the max width the zoom string can be.
515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int MaxWidthForZoomLabel() {
516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    gfx::Font font = zoom_label_->font();
517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    gfx::Insets insets;
518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (zoom_label_->border())
519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      zoom_label_->border()->GetInsets(&insets);
520731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int max_w = 0;
522731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
523731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    TabContents* selected_tab = menu_->browser_->GetSelectedTabContents();
524731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    if (selected_tab) {
525731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      int min_percent = selected_tab->minimum_zoom_percent();
526731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      int max_percent = selected_tab->maximum_zoom_percent();
527731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
528731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      int step = (max_percent - min_percent) / 10;
529731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      for (int i = min_percent; i <= max_percent; i += step) {
5303f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        int w = font.GetStringWidth(
5313f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen            l10n_util::GetStringFUTF16Int(IDS_ZOOM_PERCENT, i));
532731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        max_w = std::max(w, max_w);
533731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      }
534731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    } else {
5353f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      max_w = font.GetStringWidth(
5363f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen          l10n_util::GetStringFUTF16Int(IDS_ZOOM_PERCENT, 100));
537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
538731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return max_w + insets.width();
540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Index of the fullscreen menu item in the model.
543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const int fullscreen_index_;
544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NotificationRegistrar registrar_;
546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Button for incrementing the zoom.
548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TextButton* increment_button_;
549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Label showing zoom as a percent.
551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Label* zoom_label_;
552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Button for decrementing the zoom.
554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TextButton* decrement_button_;
555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ImageButton* fullscreen_button_;
557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Width given to |zoom_label_|. This is the width at 100%.
559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int zoom_label_width_;
560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(ZoomView);
562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// WrenchMenu ------------------------------------------------------------------
565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
566c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochWrenchMenu::WrenchMenu(Browser* browser)
567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : browser_(browser),
568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      selected_menu_model_(NULL),
569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      selected_index_(0) {
570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WrenchMenu::Init(menus::MenuModel* model) {
573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(!root_.get());
574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  root_.reset(new MenuItemView(this));
5753f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  root_->SetAccessibleName(
5763f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      UTF16ToWide(l10n_util::GetStringUTF16(IDS_ACCNAME_APP)));
577c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  root_->set_has_icons(true);  // We have checks, radios and icons, set this
578c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               // so we get the taller menu style.
579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int next_id = 1;
580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  PopulateMenu(root_.get(), model, &next_id);
581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WrenchMenu::RunMenu(views::MenuButton* host) {
584731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Up the ref count while the menu is displaying. This way if the window is
585731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // deleted while we're running we won't prematurely delete the menu.
586731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // TODO(sky): fix this, the menu should really take ownership of the menu
587731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // (57890).
588731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_refptr<WrenchMenu> dont_delete_while_running(this);
589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::Point screen_loc;
590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  views::View::ConvertPointToScreen(host, &screen_loc);
5913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  gfx::Rect bounds(screen_loc, host->size());
592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  root_->RunMenuAt(host->GetWindow()->GetNativeWindow(), host, bounds,
5933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      base::i18n::IsRTL() ? MenuItemView::TOPLEFT : MenuItemView::TOPRIGHT,
5943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      true);
595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (selected_menu_model_)
596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    selected_menu_model_->ActivatedAt(selected_index_);
597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool WrenchMenu::IsItemChecked(int id) const {
600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const Entry& entry = id_to_entry_.find(id)->second;
601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return entry.first->IsItemCheckedAt(entry.second);
602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool WrenchMenu::IsCommandEnabled(int id) const {
605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (id == 0)
606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;  // The root item.
607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const Entry& entry = id_to_entry_.find(id)->second;
609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int command_id = entry.first->GetCommandIdAt(entry.second);
610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The items representing the cut (cut/copy/paste) and zoom menu
611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // (increment/decrement/reset) are always enabled. The child views of these
612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // items enabled state updates appropriately.
613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return command_id == IDC_CUT || command_id == IDC_ZOOM_MINUS ||
614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      entry.first->IsEnabledAt(entry.second);
615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WrenchMenu::ExecuteCommand(int id) {
618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const Entry& entry = id_to_entry_.find(id)->second;
619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int command_id = entry.first->GetCommandIdAt(entry.second);
620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (command_id == IDC_CUT || command_id == IDC_ZOOM_MINUS) {
622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // These items are represented by child views. If ExecuteCommand is invoked
623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // it means the user clicked on the area around the buttons and we should
624c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // not do anyting.
625c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
627c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
628c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return entry.first->ActivatedAt(entry.second);
629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
630c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
631c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool WrenchMenu::GetAccelerator(int id, views::Accelerator* accelerator) {
632c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const Entry& entry = id_to_entry_.find(id)->second;
633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int command_id = entry.first->GetCommandIdAt(entry.second);
634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (command_id == IDC_CUT || command_id == IDC_ZOOM_MINUS) {
635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // These have special child views; don't show the accelerator for them.
636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
637c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
638c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  menus::Accelerator menu_accelerator;
640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!entry.first->GetAcceleratorAt(entry.second, &menu_accelerator))
641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  *accelerator = views::Accelerator(menu_accelerator.GetKeyCode(),
644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    menu_accelerator.modifiers());
645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return true;
646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
648731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickWrenchMenu::~WrenchMenu() {
649731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
650731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
651c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WrenchMenu::PopulateMenu(MenuItemView* parent,
652c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                              MenuModel* model,
653c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                              int* next_id) {
654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int index_offset = model->GetFirstItemIndex(NULL);
655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (int i = 0, max = model->GetItemCount(); i < max; ++i) {
656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int index = i + index_offset;
657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MenuItemView* item =
659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        AppendMenuItem(parent, model, index, model->GetTypeAt(index), next_id);
660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (model->GetTypeAt(index) == MenuModel::TYPE_SUBMENU)
662c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      PopulateMenu(item, model->GetSubmenuModelAt(index), next_id);
663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
664c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (model->GetCommandIdAt(index) == IDC_CUT) {
665c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DCHECK_EQ(MenuModel::TYPE_COMMAND, model->GetTypeAt(index));
666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DCHECK_LT(i + 2, max);
667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DCHECK_EQ(IDC_COPY, model->GetCommandIdAt(index + 1));
668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DCHECK_EQ(IDC_PASTE, model->GetCommandIdAt(index + 2));
6693f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      item->SetTitle(UTF16ToWide(l10n_util::GetStringUTF16(IDS_EDIT2)));
670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      item->AddChildView(
671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          new CutCopyPasteView(this, model, index, index + 1, index + 2));
672c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      i += 2;
673c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else if (model->GetCommandIdAt(index) == IDC_ZOOM_MINUS) {
674c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DCHECK_EQ(MenuModel::TYPE_COMMAND, model->GetTypeAt(index));
675c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DCHECK_EQ(IDC_ZOOM_PLUS, model->GetCommandIdAt(index + 1));
676c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DCHECK_EQ(IDC_FULLSCREEN, model->GetCommandIdAt(index + 2));
6773f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      item->SetTitle(UTF16ToWide(l10n_util::GetStringUTF16(IDS_ZOOM_MENU2)));
678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      item->AddChildView(
679c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          new ZoomView(this, model, index, index + 1, index + 2));
680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      i += 2;
681c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
682c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
683c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
684c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
685c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochMenuItemView* WrenchMenu::AppendMenuItem(MenuItemView* parent,
686c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                         MenuModel* model,
687c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                         int index,
688c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                         MenuModel::ItemType menu_type,
689c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                         int* next_id) {
690c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int id = (*next_id)++;
691c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
692c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  id_to_entry_[id].first = model;
693c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  id_to_entry_[id].second = index;
694c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
69521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  MenuItemView* menu_item = parent->AppendMenuItemFromModel(model, index, id);
696c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
6973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (menu_item)
6983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    menu_item->SetVisible(model->IsVisibleAt(index));
6993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
700c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (menu_type == MenuModel::TYPE_COMMAND && model->HasIcons()) {
701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    SkBitmap icon;
702c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (model->GetIconAt(index, &icon))
703c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      menu_item->SetIcon(icon);
704c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
705c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
706c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return menu_item;
707c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
708c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
709c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WrenchMenu::CancelAndEvaluate(MenuModel* model, int index) {
710c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  selected_menu_model_ = model;
711c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  selected_index_ = index;
712c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  root_->Cancel();
713c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
714