172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 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
572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/views/wrench_menu.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <cmath>
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
93345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_number_conversions.h"
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/utf_string_conversions.h"
11513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "chrome/app/chrome_command_ids.h"
1272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/metrics/user_metrics.h"
1321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h"
144a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/ui/browser.h"
15dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents.h"
16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_observer.h"
17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_registrar.h"
18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_source.h"
19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_type.h"
203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "grit/chromium_strings.h"
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/generated_resources.h"
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/theme_resources.h"
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "third_party/skia/include/core/SkPaint.h"
2472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util.h"
2572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/resource/resource_bundle.h"
2672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/canvas.h"
2772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/canvas_skia.h"
2872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/skia_util.h"
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/background.h"
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/controls/button/image_button.h"
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/controls/button/menu_button.h"
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/controls/button/text_button.h"
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/controls/label.h"
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/controls/menu/menu_config.h"
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/controls/menu/menu_item_view.h"
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/controls/menu/menu_scroll_view_container.h"
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/controls/menu/submenu_view.h"
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/window/window.h"
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenusing ui::MenuModel;
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing views::CustomButton;
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing views::ImageButton;
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing views::Label;
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing views::MenuConfig;
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing views::MenuItemView;
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing views::TextButton;
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing views::View;
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Colors used for buttons.
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst SkColor kHotBorderColor = SkColorSetARGB(72, 0, 0, 0);
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst SkColor kBorderColor = SkColorSetARGB(36, 0, 0, 0);
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst SkColor kPushedBorderColor = SkColorSetARGB(72, 0, 0, 0);
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst SkColor kHotBackgroundColor = SkColorSetARGB(204, 255, 255, 255);
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst SkColor kBackgroundColor = SkColorSetARGB(102, 255, 255, 255);
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst SkColor kPushedBackgroundColor = SkColorSetARGB(13, 0, 0, 0);
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Horizontal padding on the edges of the buttons.
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kHorizontalPadding = 6;
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Subclass of ImageButton whose preferred size includes the size of the border.
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass FullscreenButton : public ImageButton {
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  explicit FullscreenButton(views::ButtonListener* listener)
663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      : ImageButton(listener) { }
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual gfx::Size GetPreferredSize() {
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    gfx::Size pref = ImageButton::GetPreferredSize();
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    gfx::Insets insets;
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (border())
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      border()->GetInsets(&insets);
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    pref.Enlarge(insets.width(), insets.height());
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return pref;
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(FullscreenButton);
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Border for buttons contained in the menu. This is only used for getting the
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// insets, the actual painting is done in MenuButtonBackground.
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass MenuButtonBorder : public views::Border {
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MenuButtonBorder() {}
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void Paint(const View& view, gfx::Canvas* canvas) const {
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Painting of border is done in MenuButtonBackground.
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void GetInsets(gfx::Insets* insets) const {
923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    insets->Set(MenuConfig::instance().item_top_margin,
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                kHorizontalPadding,
943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                MenuConfig::instance().item_bottom_margin,
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                kHorizontalPadding);
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(MenuButtonBorder);
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Combination border/background for the buttons contained in the menu. The
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// painting of the border/background is done here as TextButton does not always
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// paint the border.
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass MenuButtonBackground : public views::Background {
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  enum ButtonType {
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    LEFT_BUTTON,
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CENTER_BUTTON,
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    RIGHT_BUTTON,
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    SINGLE_BUTTON,
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  explicit MenuButtonBackground(ButtonType type)
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      : type_(type),
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        left_button_(NULL),
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        right_button_(NULL) {}
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Used when the type is CENTER_BUTTON to determine if the left/right edge
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // needs to be rendered selected.
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void SetOtherButtons(CustomButton* left_button, CustomButton* right_button) {
1223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (base::i18n::IsRTL()) {
1233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      left_button_ = right_button;
1243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      right_button_ = left_button;
1253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    } else {
1263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      left_button_ = left_button;
1273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      right_button_ = right_button;
1283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void Paint(gfx::Canvas* canvas, View* view) const {
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CustomButton::ButtonState state =
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        (view->GetClassName() == views::Label::kViewClassName) ?
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        CustomButton::BS_NORMAL : static_cast<CustomButton*>(view)->state();
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int w = view->width();
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int h = view->height();
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    switch (TypeAdjustedForRTL()) {
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case LEFT_BUTTON:
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(background_color(state), 1, 1, w, h - 2);
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(border_color(state), 2, 0, w, 1);
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(border_color(state), 1, 1, 1, 1);
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(border_color(state), 0, 2, 1, h - 4);
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(border_color(state), 1, h - 2, 1, 1);
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(border_color(state), 2, h - 1, w, 1);
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case CENTER_BUTTON: {
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(background_color(state), 1, 1, w - 2, h - 2);
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        SkColor left_color = state != CustomButton::BS_NORMAL ?
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            border_color(state) : border_color(left_button_->state());
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(left_color, 0, 0, 1, h);
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(border_color(state), 1, 0, w - 2, 1);
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(border_color(state), 1, h - 1, w - 2, 1);
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        SkColor right_color = state != CustomButton::BS_NORMAL ?
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            border_color(state) : border_color(right_button_->state());
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(right_color, w - 1, 0, 1, h);
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case RIGHT_BUTTON:
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(background_color(state), 0, 1, w - 1, h - 2);
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(border_color(state), 0, 0, w - 2, 1);
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(border_color(state), w - 2, 1, 1, 1);
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(border_color(state), w - 1, 2, 1, h - 4);
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(border_color(state), w - 2, h - 2, 1, 1);
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(border_color(state), 0, h - 1, w - 2, 1);
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case SINGLE_BUTTON:
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(background_color(state), 1, 1, w - 2, h - 2);
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(border_color(state), 2, 0, w - 4, 1);
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(border_color(state), 1, 1, 1, 1);
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(border_color(state), 0, 2, 1, h - 4);
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(border_color(state), 1, h - 2, 1, 1);
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(border_color(state), 2, h - 1, w - 4, 1);
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(border_color(state), w - 2, 1, 1, 1);
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(border_color(state), w - 1, 2, 1, h - 4);
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        canvas->FillRectInt(border_color(state), w - 2, h - 2, 1, 1);
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      default:
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        NOTREACHED();
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static SkColor border_color(CustomButton::ButtonState state) {
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    switch (state) {
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case CustomButton::BS_HOT:    return kHotBorderColor;
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case CustomButton::BS_PUSHED: return kPushedBorderColor;
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      default:                      return kBorderColor;
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static SkColor background_color(CustomButton::ButtonState state) {
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    switch (state) {
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case CustomButton::BS_HOT:    return kHotBackgroundColor;
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case CustomButton::BS_PUSHED: return kPushedBackgroundColor;
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      default:                      return kBackgroundColor;
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ButtonType TypeAdjustedForRTL() const {
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!base::i18n::IsRTL())
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return type_;
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    switch (type_) {
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case LEFT_BUTTON:   return RIGHT_BUTTON;
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case RIGHT_BUTTON:  return LEFT_BUTTON;
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      default:            break;
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return type_;
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const ButtonType type_;
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // See description above setter for details.
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CustomButton* left_button_;
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CustomButton* right_button_;
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(MenuButtonBackground);
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A View subclass that forces SchedulePaint to paint all. Normally when the
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// mouse enters/exits a button the buttons invokes SchedulePaint. As part of the
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// button border (MenuButtonBackground) is rendered by the button to the
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// left/right of it SchedulePaint on the the button may not be enough, so this
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// forces a paint all.
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ScheduleAllView : public views::View {
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ScheduleAllView() {}
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
234dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  virtual void SchedulePaintInRect(const gfx::Rect& r) {
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!IsVisible())
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return;
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
23872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (parent())
239dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      parent()->SchedulePaintInRect(GetMirroredBounds());
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(ScheduleAllView);
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
24672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstring16 GetAccessibleNameForWrenchMenuItem(
247731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      MenuModel* model, int item_index, int accessible_string_id) {
24872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  string16 accessible_name = l10n_util::GetStringUTF16(accessible_string_id);
24972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  string16 accelerator_text;
250731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
25172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ui::Accelerator menu_accelerator;
252731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (model->GetAcceleratorAt(item_index, &menu_accelerator)) {
253731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    accelerator_text =
254731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        views::Accelerator(menu_accelerator.GetKeyCode(),
255731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                           menu_accelerator.modifiers()).GetShortcutText();
256731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
257731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
258731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  return MenuItemView::GetAccessibleNameForMenuItem(
259731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      accessible_name, accelerator_text);
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
262731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// WrenchMenuView is a view that can contain text buttons.
263731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickclass WrenchMenuView : public ScheduleAllView, public views::ButtonListener {
264731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick public:
265731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  WrenchMenuView(WrenchMenu* menu, MenuModel* menu_model)
266731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      : menu_(menu), menu_model_(menu_model) { }
267731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
268731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  TextButton* CreateAndConfigureButton(int string_id,
269731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                       MenuButtonBackground::ButtonType type,
270731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                       int index,
271731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                       MenuButtonBackground** background) {
272731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return CreateButtonWithAccName(
273731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      string_id, type, index, background, string_id);
274731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
275731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
276731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  TextButton* CreateButtonWithAccName(int string_id,
277731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                      MenuButtonBackground::ButtonType type,
278731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                      int index,
279731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                      MenuButtonBackground** background,
280731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                      int acc_string_id) {
281731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    TextButton* button =
2823f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        new TextButton(this, UTF16ToWide(l10n_util::GetStringUTF16(string_id)));
283731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    button->SetAccessibleName(
284731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        GetAccessibleNameForWrenchMenuItem(menu_model_, index, acc_string_id));
285731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    button->SetFocusable(true);
286731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    button->set_request_focus_on_press(false);
287731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    button->set_tag(index);
288731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    button->SetEnabled(menu_model_->IsEnabledAt(index));
289731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    button->set_prefix_type(TextButton::PREFIX_HIDE);
290731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    MenuButtonBackground* bg = new MenuButtonBackground(type);
291731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    button->set_background(bg);
292731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    button->SetEnabledColor(MenuConfig::instance().text_color);
293731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    if (background)
294731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      *background = bg;
295731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    button->set_border(new MenuButtonBorder());
296731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    button->set_alignment(TextButton::ALIGN_CENTER);
297731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    button->SetNormalHasBorder(true);
298731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    button->SetFont(views::MenuConfig::instance().font);
299731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    button->ClearMaxTextSize();
300731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    AddChildView(button);
301731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return button;
302731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
303731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
304731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick protected:
305731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Hosting WrenchMenu.
306731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  WrenchMenu* menu_;
307731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
308731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // The menu model containing the increment/decrement/reset items.
309731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  MenuModel* menu_model_;
310731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
311731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick private:
312731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DISALLOW_COPY_AND_ASSIGN(WrenchMenuView);
313731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick};
314731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace
316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// CutCopyPasteView ------------------------------------------------------------
318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// CutCopyPasteView is the view containing the cut/copy/paste buttons.
320731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickclass WrenchMenu::CutCopyPasteView : public WrenchMenuView {
321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CutCopyPasteView(WrenchMenu* menu,
323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   MenuModel* menu_model,
324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   int cut_index,
325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   int copy_index,
326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   int paste_index)
327731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      : WrenchMenuView(menu, menu_model) {
328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TextButton* cut = CreateAndConfigureButton(
329731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        IDS_CUT, MenuButtonBackground::LEFT_BUTTON, cut_index, NULL);
330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MenuButtonBackground* copy_background = NULL;
332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CreateAndConfigureButton(
333731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        IDS_COPY, MenuButtonBackground::CENTER_BUTTON, copy_index,
334731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        &copy_background);
335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TextButton* paste = CreateAndConfigureButton(
337731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        IDS_PASTE, MenuButtonBackground::RIGHT_BUTTON, paste_index, NULL);
338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    copy_background->SetOtherButtons(cut, paste);
340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::Size GetPreferredSize() {
343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Returned height doesn't matter as MenuItemView forces everything to the
344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // height of the menuitemview.
34572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return gfx::Size(GetMaxChildViewPreferredWidth() * child_count(), 0);
346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void Layout() {
349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // All buttons are given the same width.
350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int width = GetMaxChildViewPreferredWidth();
35172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    for (int i = 0; i < child_count(); ++i)
352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GetChildViewAt(i)->SetBounds(i * width, 0, width, height());
353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // ButtonListener
356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void ButtonPressed(views::Button* sender, const views::Event& event) {
357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    menu_->CancelAndEvaluate(menu_model_, sender->tag());
358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Returns the max preferred width of all the children.
362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int GetMaxChildViewPreferredWidth() {
363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int width = 0;
36472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    for (int i = 0; i < child_count(); ++i)
365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      width = std::max(width, GetChildViewAt(i)->GetPreferredSize().width());
366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return width;
367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(CutCopyPasteView);
370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ZoomView --------------------------------------------------------------------
373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Padding between the increment buttons and the reset button.
375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const int kZoomPadding = 6;
376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ZoomView contains the various zoom controls: two buttons to increase/decrease
378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the zoom, a label showing the current zoom percent, and a button to go
379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// full-screen.
380731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickclass WrenchMenu::ZoomView : public WrenchMenuView,
381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             public NotificationObserver {
382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ZoomView(WrenchMenu* menu,
384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch           MenuModel* menu_model,
385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch           int decrement_index,
386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch           int increment_index,
387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch           int fullscreen_index)
388731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      : WrenchMenuView(menu, menu_model),
389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        fullscreen_index_(fullscreen_index),
390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        increment_button_(NULL),
391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        zoom_label_(NULL),
392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        decrement_button_(NULL),
393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        fullscreen_button_(NULL),
394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        zoom_label_width_(0) {
395731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    decrement_button_ = CreateButtonWithAccName(
396731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        IDS_ZOOM_MINUS2, MenuButtonBackground::LEFT_BUTTON, decrement_index,
397731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        NULL, IDS_ACCNAME_ZOOM_MINUS2);
398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3993f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    zoom_label_ = new Label(
4003f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        UTF16ToWide(l10n_util::GetStringFUTF16Int(IDS_ZOOM_PERCENT, 100)));
401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    zoom_label_->SetColor(MenuConfig::instance().text_color);
402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    zoom_label_->SetHorizontalAlignment(Label::ALIGN_RIGHT);
403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MenuButtonBackground* center_bg =
404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        new MenuButtonBackground(MenuButtonBackground::CENTER_BUTTON);
405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    zoom_label_->set_background(center_bg);
406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    zoom_label_->set_border(new MenuButtonBorder());
407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    zoom_label_->SetFont(MenuConfig::instance().font);
408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AddChildView(zoom_label_);
409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    zoom_label_width_ = MaxWidthForZoomLabel();
410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
411731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    increment_button_ = CreateButtonWithAccName(
412731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        IDS_ZOOM_PLUS2, MenuButtonBackground::RIGHT_BUTTON, increment_index,
413731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        NULL, IDS_ACCNAME_ZOOM_PLUS2);
414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    center_bg->SetOtherButtons(decrement_button_, increment_button_);
416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    fullscreen_button_ = new FullscreenButton(this);
418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    fullscreen_button_->SetImage(
419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        ImageButton::BS_NORMAL,
420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        ResourceBundle::GetSharedInstance().GetBitmapNamed(
421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            IDR_FULLSCREEN_MENU_BUTTON));
422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    fullscreen_button_->SetFocusable(true);
423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    fullscreen_button_->set_request_focus_on_press(false);
424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    fullscreen_button_->set_tag(fullscreen_index);
425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    fullscreen_button_->SetImageAlignment(
426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        ImageButton::ALIGN_CENTER, ImageButton::ALIGN_MIDDLE);
427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    fullscreen_button_->set_border(views::Border::CreateEmptyBorder(
428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        0, kHorizontalPadding, 0, kHorizontalPadding));
429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    fullscreen_button_->set_background(
430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        new MenuButtonBackground(MenuButtonBackground::SINGLE_BUTTON));
4313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    fullscreen_button_->SetAccessibleName(
432731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        GetAccessibleNameForWrenchMenuItem(
433731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick            menu_model, fullscreen_index, IDS_ACCNAME_FULLSCREEN));
434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AddChildView(fullscreen_button_);
435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    UpdateZoomControls();
437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    registrar_.Add(this, NotificationType::ZOOM_LEVEL_CHANGED,
439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   Source<Profile>(menu->browser_->profile()));
440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::Size GetPreferredSize() {
443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // The increment/decrement button are forced to the same width.
444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int button_width = std::max(increment_button_->GetPreferredSize().width(),
445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                decrement_button_->GetPreferredSize().width());
446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int fullscreen_width = fullscreen_button_->GetPreferredSize().width();
447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Returned height doesn't matter as MenuItemView forces everything to the
448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // height of the menuitemview.
449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return gfx::Size(button_width + zoom_label_width_ + button_width +
450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                     kZoomPadding + fullscreen_width, 0);
451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void Layout() {
454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int x = 0;
455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int button_width = std::max(increment_button_->GetPreferredSize().width(),
456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                decrement_button_->GetPreferredSize().width());
457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    gfx::Rect bounds(0, 0, button_width, height());
458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
45972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    decrement_button_->SetBoundsRect(bounds);
460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    x += bounds.width();
462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bounds.set_x(x);
463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bounds.set_width(zoom_label_width_);
46472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    zoom_label_->SetBoundsRect(bounds);
465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    x += bounds.width();
467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bounds.set_x(x);
468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bounds.set_width(button_width);
46972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    increment_button_->SetBoundsRect(bounds);
470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    x += bounds.width() + kZoomPadding;
472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bounds.set_x(x);
473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bounds.set_width(fullscreen_button_->GetPreferredSize().width());
47472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    fullscreen_button_->SetBoundsRect(bounds);
475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // ButtonListener:
478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void ButtonPressed(views::Button* sender, const views::Event& event) {
479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (sender->tag() == fullscreen_index_) {
480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      menu_->CancelAndEvaluate(menu_model_, sender->tag());
481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else {
482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Zoom buttons don't close the menu.
483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      menu_model_->ActivatedAt(sender->tag());
484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // NotificationObserver:
488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void Observe(NotificationType type,
489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       const NotificationSource& source,
490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       const NotificationDetails& details) {
491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK_EQ(NotificationType::ZOOM_LEVEL_CHANGED, type.value);
492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    UpdateZoomControls();
493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void UpdateZoomControls() {
497731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    bool enable_increment = false;
498731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    bool enable_decrement = false;
499731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    TabContents* selected_tab = menu_->browser_->GetSelectedTabContents();
500731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    int zoom = 100;
501731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    if (selected_tab)
502731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      zoom = selected_tab->GetZoomPercent(&enable_increment, &enable_decrement);
503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    increment_button_->SetEnabled(enable_increment);
504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    decrement_button_->SetEnabled(enable_decrement);
5053f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    zoom_label_->SetText(UTF16ToWide(l10n_util::GetStringFUTF16Int(
5063f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                     IDS_ZOOM_PERCENT,
5073f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                     zoom)));
508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
509731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    zoom_label_width_ = MaxWidthForZoomLabel();
510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Calculates the max width the zoom string can be.
513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int MaxWidthForZoomLabel() {
514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    gfx::Font font = zoom_label_->font();
515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    gfx::Insets insets;
516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (zoom_label_->border())
517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      zoom_label_->border()->GetInsets(&insets);
518731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int max_w = 0;
520731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
521731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    TabContents* selected_tab = menu_->browser_->GetSelectedTabContents();
522731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    if (selected_tab) {
523731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      int min_percent = selected_tab->minimum_zoom_percent();
524731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      int max_percent = selected_tab->maximum_zoom_percent();
525731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
526731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      int step = (max_percent - min_percent) / 10;
527731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      for (int i = min_percent; i <= max_percent; i += step) {
5283f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        int w = font.GetStringWidth(
5293f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen            l10n_util::GetStringFUTF16Int(IDS_ZOOM_PERCENT, i));
530731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        max_w = std::max(w, max_w);
531731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      }
532731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    } else {
5333f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      max_w = font.GetStringWidth(
5343f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen          l10n_util::GetStringFUTF16Int(IDS_ZOOM_PERCENT, 100));
535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
536731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return max_w + insets.width();
538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Index of the fullscreen menu item in the model.
541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const int fullscreen_index_;
542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NotificationRegistrar registrar_;
544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Button for incrementing the zoom.
546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TextButton* increment_button_;
547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Label showing zoom as a percent.
549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Label* zoom_label_;
550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Button for decrementing the zoom.
552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TextButton* decrement_button_;
553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ImageButton* fullscreen_button_;
555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Width given to |zoom_label_|. This is the width at 100%.
557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int zoom_label_width_;
558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(ZoomView);
560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// WrenchMenu ------------------------------------------------------------------
563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
564c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochWrenchMenu::WrenchMenu(Browser* browser)
565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : browser_(browser),
566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      selected_menu_model_(NULL),
567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      selected_index_(0) {
568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
57072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid WrenchMenu::Init(ui::MenuModel* model) {
571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(!root_.get());
572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  root_.reset(new MenuItemView(this));
573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  root_->set_has_icons(true);  // We have checks, radios and icons, set this
574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               // so we get the taller menu style.
575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int next_id = 1;
576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  PopulateMenu(root_.get(), model, &next_id);
577c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
578c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WrenchMenu::RunMenu(views::MenuButton* host) {
580731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Up the ref count while the menu is displaying. This way if the window is
581731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // deleted while we're running we won't prematurely delete the menu.
582731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // TODO(sky): fix this, the menu should really take ownership of the menu
583731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // (57890).
584731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_refptr<WrenchMenu> dont_delete_while_running(this);
585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::Point screen_loc;
586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  views::View::ConvertPointToScreen(host, &screen_loc);
5873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  gfx::Rect bounds(screen_loc, host->size());
58872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  UserMetrics::RecordAction(UserMetricsAction("ShowAppMenu"));
589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  root_->RunMenuAt(host->GetWindow()->GetNativeWindow(), host, bounds,
5903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      base::i18n::IsRTL() ? MenuItemView::TOPLEFT : MenuItemView::TOPRIGHT,
5913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      true);
592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (selected_menu_model_)
593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    selected_menu_model_->ActivatedAt(selected_index_);
594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool WrenchMenu::IsItemChecked(int id) const {
597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const Entry& entry = id_to_entry_.find(id)->second;
598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return entry.first->IsItemCheckedAt(entry.second);
599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool WrenchMenu::IsCommandEnabled(int id) const {
602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (id == 0)
603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;  // The root item.
604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const Entry& entry = id_to_entry_.find(id)->second;
606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int command_id = entry.first->GetCommandIdAt(entry.second);
607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The items representing the cut (cut/copy/paste) and zoom menu
608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // (increment/decrement/reset) are always enabled. The child views of these
609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // items enabled state updates appropriately.
610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return command_id == IDC_CUT || command_id == IDC_ZOOM_MINUS ||
611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      entry.first->IsEnabledAt(entry.second);
612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WrenchMenu::ExecuteCommand(int id) {
615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const Entry& entry = id_to_entry_.find(id)->second;
616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int command_id = entry.first->GetCommandIdAt(entry.second);
617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (command_id == IDC_CUT || command_id == IDC_ZOOM_MINUS) {
619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // These items are represented by child views. If ExecuteCommand is invoked
620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // it means the user clicked on the area around the buttons and we should
621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // not do anyting.
622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
624c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
625c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return entry.first->ActivatedAt(entry.second);
626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
627c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
628c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool WrenchMenu::GetAccelerator(int id, views::Accelerator* accelerator) {
629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const Entry& entry = id_to_entry_.find(id)->second;
630c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int command_id = entry.first->GetCommandIdAt(entry.second);
631c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (command_id == IDC_CUT || command_id == IDC_ZOOM_MINUS) {
632c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // These have special child views; don't show the accelerator for them.
633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
63672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ui::Accelerator menu_accelerator;
637c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!entry.first->GetAcceleratorAt(entry.second, &menu_accelerator))
638c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  *accelerator = views::Accelerator(menu_accelerator.GetKeyCode(),
641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    menu_accelerator.modifiers());
642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return true;
643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
645731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickWrenchMenu::~WrenchMenu() {
646731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
647731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WrenchMenu::PopulateMenu(MenuItemView* parent,
649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                              MenuModel* model,
650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                              int* next_id) {
651c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int index_offset = model->GetFirstItemIndex(NULL);
652c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (int i = 0, max = model->GetItemCount(); i < max; ++i) {
653c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int index = i + index_offset;
654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MenuItemView* item =
656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        AppendMenuItem(parent, model, index, model->GetTypeAt(index), next_id);
657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (model->GetTypeAt(index) == MenuModel::TYPE_SUBMENU)
659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      PopulateMenu(item, model->GetSubmenuModelAt(index), next_id);
660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (model->GetCommandIdAt(index) == IDC_CUT) {
662c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DCHECK_EQ(MenuModel::TYPE_COMMAND, model->GetTypeAt(index));
663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DCHECK_LT(i + 2, max);
664c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DCHECK_EQ(IDC_COPY, model->GetCommandIdAt(index + 1));
665c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DCHECK_EQ(IDC_PASTE, model->GetCommandIdAt(index + 2));
6663f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      item->SetTitle(UTF16ToWide(l10n_util::GetStringUTF16(IDS_EDIT2)));
667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      item->AddChildView(
668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          new CutCopyPasteView(this, model, index, index + 1, index + 2));
669c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      i += 2;
670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else if (model->GetCommandIdAt(index) == IDC_ZOOM_MINUS) {
671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DCHECK_EQ(MenuModel::TYPE_COMMAND, model->GetTypeAt(index));
672c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DCHECK_EQ(IDC_ZOOM_PLUS, model->GetCommandIdAt(index + 1));
673c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DCHECK_EQ(IDC_FULLSCREEN, model->GetCommandIdAt(index + 2));
6743f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      item->SetTitle(UTF16ToWide(l10n_util::GetStringUTF16(IDS_ZOOM_MENU2)));
675c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      item->AddChildView(
676c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          new ZoomView(this, model, index, index + 1, index + 2));
677c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      i += 2;
678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
679c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
681c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
682c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochMenuItemView* WrenchMenu::AppendMenuItem(MenuItemView* parent,
683c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                         MenuModel* model,
684c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                         int index,
685c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                         MenuModel::ItemType menu_type,
686c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                         int* next_id) {
687c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int id = (*next_id)++;
688c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
689c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  id_to_entry_[id].first = model;
690c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  id_to_entry_[id].second = index;
691c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
69221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  MenuItemView* menu_item = parent->AppendMenuItemFromModel(model, index, id);
693c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
6943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (menu_item)
6953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    menu_item->SetVisible(model->IsVisibleAt(index));
6963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
697c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (menu_type == MenuModel::TYPE_COMMAND && model->HasIcons()) {
698c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    SkBitmap icon;
699c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (model->GetIconAt(index, &icon))
700c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      menu_item->SetIcon(icon);
701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
702c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
703c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return menu_item;
704c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
705c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
706c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WrenchMenu::CancelAndEvaluate(MenuModel* model, int index) {
707c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  selected_menu_model_ = model;
708c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  selected_index_ = index;
709c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  root_->Cancel();
710c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
711