1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/ui/views/toolbar/wrench_menu.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <cmath>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/app/chrome_command_ids.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/bookmarks/bookmark_model_factory.h"
1568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "chrome/browser/bookmarks/bookmark_stats.h"
167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/search/search.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_window.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h"
224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/ui/toolbar/wrench_menu_model.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.h"
24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/ui/views/toolbar/extension_toolbar_menu_view.h"
25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/ui/views/toolbar/wrench_menu_observer.h"
26116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/ui/zoom/zoom_controller.h"
27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/ui/zoom/zoom_event_manager.h"
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/grit/generated_resources.h"
29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/bookmarks/browser/bookmark_model.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/host_zoom_map.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_observer.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_registrar.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_types.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/user_metrics.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h"
37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "extensions/common/feature_switch.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/theme_resources.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkCanvas.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkPaint.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/layout.h"
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/canvas.h"
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gfx/font_list.h"
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image.h"
47a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ui/gfx/image/image_skia_source.h"
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/skia_util.h"
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/text_utils.h"
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/background.h"
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/button/image_button.h"
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/controls/button/label_button.h"
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/button/menu_button.h"
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/label.h"
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/menu/menu_config.h"
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/menu/menu_item_view.h"
574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ui/views/controls/menu/menu_model_adapter.h"
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/menu/menu_runner.h"
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/menu/menu_scroll_view_container.h"
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/menu/submenu_view.h"
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget.h"
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using base::UserMetricsAction;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::HostZoomMap;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ui::MenuModel;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using views::CustomButton;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using views::ImageButton;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using views::Label;
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using views::LabelButton;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using views::MenuConfig;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using views::MenuItemView;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using views::View;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Horizontal padding on the edges of the in-menu buttons.
785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const int kHorizontalPadding = 15;
795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if defined(OS_CHROMEOS)
815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Extra horizontal space to reserve for the fullscreen button.
825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const int kFullscreenPadding = 74;
835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Padding to left and right of the XX% label.
845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const int kZoomLabelHorizontalPadding = kHorizontalPadding;
855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#else
865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const int kFullscreenPadding = 38;
875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const int kZoomLabelHorizontalPadding = 2;
885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Returns true if |command_id| identifies a bookmark menu item.
914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool IsBookmarkCommand(int command_id) {
924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return command_id >= WrenchMenuModel::kMinBookmarkCommandId &&
934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      command_id <= WrenchMenuModel::kMaxBookmarkCommandId;
944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Returns true if |command_id| identifies a recent tabs menu item.
974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool IsRecentTabsCommand(int command_id) {
984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return command_id >= WrenchMenuModel::kMinRecentTabsCommandId &&
994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      command_id <= WrenchMenuModel::kMaxRecentTabsCommandId;
1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Subclass of ImageButton whose preferred size includes the size of the border.
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class FullscreenButton : public ImageButton {
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit FullscreenButton(views::ButtonListener* listener)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : ImageButton(listener) { }
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from ImageButton.
109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual gfx::Size GetPreferredSize() const OVERRIDE {
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::Size pref = ImageButton::GetPreferredSize();
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (border()) {
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Insets insets = border()->GetInsets();
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      pref.Enlarge(insets.width(), insets.height());
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return pref;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FullscreenButton);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Combination border/background for the buttons contained in the menu. The
123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// painting of the border/background is done here as LabelButton does not always
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// paint the border.
125f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class InMenuButtonBackground : public views::Background {
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum ButtonType {
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LEFT_BUTTON,
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CENTER_BUTTON,
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RIGHT_BUTTON,
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SINGLE_BUTTON,
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  explicit InMenuButtonBackground(ButtonType type)
1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      : type_(type), left_button_(NULL), right_button_(NULL) {}
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Used when the type is CENTER_BUTTON to determine if the left/right edge
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // needs to be rendered selected.
139f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void SetOtherButtons(const CustomButton* left_button,
140f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                       const CustomButton* right_button) {
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (base::i18n::IsRTL()) {
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      left_button_ = right_button;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      right_button_ = left_button;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      left_button_ = left_button;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      right_button_ = right_button;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from views::Background.
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Paint(gfx::Canvas* canvas, View* view) const OVERRIDE {
152a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    CustomButton* button = CustomButton::AsCustomButton(view);
153a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    views::Button::ButtonState state =
154a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        button ? button->state() : views::Button::STATE_NORMAL;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int h = view->height();
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Normal buttons get a border drawn on the right side and the rest gets
1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // filled in. The left button however does not get a line to combine
1595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // buttons.
1605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (type_ != RIGHT_BUTTON) {
1615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      canvas->FillRect(gfx::Rect(0, 0, 1, h),
1625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                       BorderColor(view, views::Button::STATE_NORMAL));
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    gfx::Rect bounds(view->GetLocalBounds());
1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    bounds.set_x(view->GetMirroredXForRect(bounds));
1675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    DrawBackground(canvas, view, bounds, state);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
171a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  static SkColor BorderColor(View* view, views::Button::ButtonState state) {
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui::NativeTheme* theme = view->GetNativeTheme();
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (state) {
174a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      case views::Button::STATE_HOVERED:
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return theme->GetSystemColor(
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            ui::NativeTheme::kColorId_HoverMenuButtonBorderColor);
177a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      case views::Button::STATE_PRESSED:
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return theme->GetSystemColor(
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            ui::NativeTheme::kColorId_FocusedMenuButtonBorderColor);
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      default:
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return theme->GetSystemColor(
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            ui::NativeTheme::kColorId_EnabledMenuButtonBorderColor);
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
186a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  static SkColor BackgroundColor(const View* view,
187a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                 views::Button::ButtonState state) {
188a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const ui::NativeTheme* theme = view->GetNativeTheme();
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (state) {
190a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      case views::Button::STATE_HOVERED:
191a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        // Hovered should be handled in DrawBackground.
192a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        NOTREACHED();
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return theme->GetSystemColor(
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            ui::NativeTheme::kColorId_HoverMenuItemBackgroundColor);
195a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      case views::Button::STATE_PRESSED:
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return theme->GetSystemColor(
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            ui::NativeTheme::kColorId_FocusedMenuItemBackgroundColor);
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      default:
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return theme->GetSystemColor(
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            ui::NativeTheme::kColorId_MenuBackgroundColor);
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
204a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void DrawBackground(gfx::Canvas* canvas,
205a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                      const views::View* view,
206a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                      const gfx::Rect& bounds,
207a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                      views::Button::ButtonState state) const {
2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (state == views::Button::STATE_HOVERED ||
2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        state == views::Button::STATE_PRESSED) {
210a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      view->GetNativeTheme()->Paint(canvas->sk_canvas(),
211a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                    ui::NativeTheme::kMenuItemBackground,
212a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                    ui::NativeTheme::kHovered,
213a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                    bounds,
214a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                    ui::NativeTheme::ExtraParams());
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ButtonType TypeAdjustedForRTL() const {
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!base::i18n::IsRTL())
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return type_;
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (type_) {
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case LEFT_BUTTON:   return RIGHT_BUTTON;
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case RIGHT_BUTTON:  return LEFT_BUTTON;
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default:            break;
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return type_;
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ButtonType type_;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See description above setter for details.
233f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  const CustomButton* left_button_;
234f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  const CustomButton* right_button_;
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
236f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(InMenuButtonBackground);
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
239a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)base::string16 GetAccessibleNameForWrenchMenuItem(
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MenuModel* model, int item_index, int accessible_string_id) {
241a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 accessible_name =
242a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      l10n_util::GetStringUTF16(accessible_string_id);
243a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 accelerator_text;
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::Accelerator menu_accelerator;
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (model->GetAcceleratorAt(item_index, &menu_accelerator)) {
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    accelerator_text =
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ui::Accelerator(menu_accelerator.key_code(),
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        menu_accelerator.modifiers()).GetShortcutText();
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return MenuItemView::GetAccessibleNameForMenuItem(
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      accessible_name, accelerator_text);
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
256f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// A button that lives inside a menu item.
257f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class InMenuButton : public LabelButton {
258f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) public:
2595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  InMenuButton(views::ButtonListener* listener, const base::string16& text)
2605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      : LabelButton(listener, text), in_menu_background_(NULL) {}
261f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual ~InMenuButton() {}
262f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
263f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void Init(InMenuButtonBackground::ButtonType type) {
264f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    SetFocusable(true);
265f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    set_request_focus_on_press(false);
266f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    SetHorizontalAlignment(gfx::ALIGN_CENTER);
267f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
2685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    in_menu_background_ = new InMenuButtonBackground(type);
269f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    set_background(in_menu_background_);
270f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
271f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    OnNativeThemeChanged(NULL);
272f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
273f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
274f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void SetOtherButtons(const InMenuButton* left, const InMenuButton* right) {
275f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    in_menu_background_->SetOtherButtons(left, right);
276f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
277f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
278f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // views::LabelButton
279f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual void OnNativeThemeChanged(const ui::NativeTheme* theme) OVERRIDE {
280f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const MenuConfig& menu_config = MenuConfig::instance(theme);
2815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    SetBorder(views::Border::CreateEmptyBorder(
2825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        0, kHorizontalPadding, 0, kHorizontalPadding));
283f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    SetFontList(menu_config.font_list);
284f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
285f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (theme) {
286f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      SetTextColor(
287f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          views::Button::STATE_DISABLED,
288f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          theme->GetSystemColor(
289f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)              ui::NativeTheme::kColorId_DisabledMenuItemForegroundColor));
290f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      SetTextColor(
291f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          views::Button::STATE_HOVERED,
292f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          theme->GetSystemColor(
293f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)              ui::NativeTheme::kColorId_SelectedMenuItemForegroundColor));
294f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      SetTextColor(
295f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          views::Button::STATE_PRESSED,
296f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          theme->GetSystemColor(
297f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)              ui::NativeTheme::kColorId_SelectedMenuItemForegroundColor));
298f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      SetTextColor(
299f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          views::Button::STATE_NORMAL,
300f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          theme->GetSystemColor(
301f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)              ui::NativeTheme::kColorId_EnabledMenuItemForegroundColor));
302f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }
303f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
304f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
305f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) private:
306f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  InMenuButtonBackground* in_menu_background_;
307f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
308f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(InMenuButton);
309f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)};
310f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// WrenchMenuView is a view that can contain label buttons.
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class WrenchMenuView : public views::View,
3133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                       public views::ButtonListener,
3143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                       public WrenchMenuObserver {
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WrenchMenuView(WrenchMenu* menu, MenuModel* menu_model)
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : menu_(menu),
3183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        menu_model_(menu_model) {
3193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    menu_->AddObserver(this);
3203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
3213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual ~WrenchMenuView() {
3233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (menu_)
3243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      menu_->RemoveObserver(this);
3253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from views::View.
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SchedulePaintInRect(const gfx::Rect& r) OVERRIDE {
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Normally when the mouse enters/exits a button the buttons invokes
330f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // SchedulePaint. As part of the button border (InMenuButtonBackground) is
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // rendered by the button to the left/right of it SchedulePaint on the the
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // button may not be enough, so this forces a paint all.
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    View::SchedulePaintInRect(gfx::Rect(size()));
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
336f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  InMenuButton* CreateAndConfigureButton(
337f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      int string_id,
338f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      InMenuButtonBackground::ButtonType type,
339f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      int index) {
340f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return CreateButtonWithAccName(string_id, type, index, string_id);
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
343f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  InMenuButton* CreateButtonWithAccName(int string_id,
344f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                        InMenuButtonBackground::ButtonType type,
345f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                        int index,
346f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                        int acc_string_id) {
3473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // Should only be invoked during construction when |menu_| is valid.
3483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    DCHECK(menu_);
349f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    InMenuButton* button = new InMenuButton(
350f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        this,
3515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        gfx::RemoveAcceleratorChar(
3525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            l10n_util::GetStringUTF16(string_id), '&', NULL, NULL));
353f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    button->Init(type);
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    button->SetAccessibleName(
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GetAccessibleNameForWrenchMenuItem(menu_model_, index, acc_string_id));
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    button->set_tag(index);
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    button->SetEnabled(menu_model_->IsEnabledAt(index));
358f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddChildView(button);
360a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // all buttons on menu should must be a custom button in order for
361a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // the keyboard nativigation work.
362a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    DCHECK(CustomButton::AsCustomButton(button));
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return button;
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Overridden from WrenchMenuObserver:
3673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual void WrenchMenuDestroyed() OVERRIDE {
3683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    menu_->RemoveObserver(this);
3693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    menu_ = NULL;
3703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    menu_model_ = NULL;
3713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
3723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
3743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  WrenchMenu* menu() { return menu_; }
3753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MenuModel* menu_model() { return menu_model_; }
3763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private:
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Hosting WrenchMenu.
3793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // WARNING: this may be NULL during shutdown.
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WrenchMenu* menu_;
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The menu model containing the increment/decrement/reset items.
3833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // WARNING: this may be NULL during shutdown.
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MenuModel* menu_model_;
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(WrenchMenuView);
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
389a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Generate the button image for hover state.
390a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class HoveredImageSource : public gfx::ImageSkiaSource {
391a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public:
392a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  HoveredImageSource(const gfx::ImageSkia& image, SkColor color)
393a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      : image_(image),
394a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        color_(color) {
395a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
396a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual ~HoveredImageSource() {}
397a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
398a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual gfx::ImageSkiaRep GetImageForScale(float scale) OVERRIDE {
399a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const gfx::ImageSkiaRep& rep = image_.GetRepresentation(scale);
400a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    SkBitmap bitmap = rep.sk_bitmap();
401a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    SkBitmap white;
402116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    white.allocN32Pixels(bitmap.width(), bitmap.height());
403a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    white.eraseARGB(0, 0, 0, 0);
404a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    bitmap.lockPixels();
405a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    for (int y = 0; y < bitmap.height(); ++y) {
406a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      uint32* image_row = bitmap.getAddr32(0, y);
407a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      uint32* dst_row = white.getAddr32(0, y);
408a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      for (int x = 0; x < bitmap.width(); ++x) {
409a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        uint32 image_pixel = image_row[x];
410a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        // Fill the non transparent pixels with |color_|.
411a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        dst_row[x] = (image_pixel & 0xFF000000) == 0x0 ? 0x0 : color_;
412a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      }
413a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
414a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    bitmap.unlockPixels();
415a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return gfx::ImageSkiaRep(white, scale);
416a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
417a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
418a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) private:
419a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const gfx::ImageSkia image_;
420a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const SkColor color_;
421a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(HoveredImageSource);
422a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)};
423a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// CutCopyPasteView ------------------------------------------------------------
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// CutCopyPasteView is the view containing the cut/copy/paste buttons.
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class WrenchMenu::CutCopyPasteView : public WrenchMenuView {
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CutCopyPasteView(WrenchMenu* menu,
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   MenuModel* menu_model,
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   int cut_index,
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   int copy_index,
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   int paste_index)
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : WrenchMenuView(menu, menu_model) {
437f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    InMenuButton* cut = CreateAndConfigureButton(
4385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        IDS_CUT, InMenuButtonBackground::LEFT_BUTTON, cut_index);
439f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    InMenuButton* copy = CreateAndConfigureButton(
4405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        IDS_COPY, InMenuButtonBackground::CENTER_BUTTON, copy_index);
441f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    InMenuButton* paste = CreateAndConfigureButton(
4425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        IDS_PASTE, InMenuButtonBackground::CENTER_BUTTON, paste_index);
443f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    copy->SetOtherButtons(cut, paste);
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from View.
447cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual gfx::Size GetPreferredSize() const OVERRIDE {
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Returned height doesn't matter as MenuItemView forces everything to the
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // height of the menuitemview.
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return gfx::Size(GetMaxChildViewPreferredWidth() * child_count(), 0);
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Layout() OVERRIDE {
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // All buttons are given the same width.
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int width = GetMaxChildViewPreferredWidth();
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 0; i < child_count(); ++i)
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      child_at(i)->SetBounds(i * width, 0, width, height());
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from ButtonListener.
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ButtonPressed(views::Button* sender,
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const ui::Event& event) OVERRIDE {
4633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    menu()->CancelAndEvaluate(menu_model(), sender->tag());
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the max preferred width of all the children.
468cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int GetMaxChildViewPreferredWidth() const {
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int width = 0;
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 0; i < child_count(); ++i)
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      width = std::max(width, child_at(i)->GetPreferredSize().width());
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return width;
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CutCopyPasteView);
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ZoomView --------------------------------------------------------------------
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ZoomView contains the various zoom controls: two buttons to increase/decrease
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the zoom, a label showing the current zoom percent, and a button to go
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// full-screen.
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class WrenchMenu::ZoomView : public WrenchMenuView {
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ZoomView(WrenchMenu* menu,
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           MenuModel* menu_model,
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           int decrement_index,
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           int increment_index,
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           int fullscreen_index)
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : WrenchMenuView(menu, menu_model),
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        fullscreen_index_(fullscreen_index),
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        increment_button_(NULL),
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        zoom_label_(NULL),
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        decrement_button_(NULL),
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        fullscreen_button_(NULL),
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        zoom_label_width_(0) {
4981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    content_zoom_subscription_ = HostZoomMap::GetDefaultForBrowserContext(
499116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        menu->browser_->profile())->AddZoomLevelChangedCallback(
500116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            base::Bind(&WrenchMenu::ZoomView::OnZoomLevelChanged,
501116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                       base::Unretained(this)));
502116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
503116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    browser_zoom_subscription_ = ZoomEventManager::GetForBrowserContext(
5044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        menu->browser_->profile())->AddZoomLevelChangedCallback(
5054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            base::Bind(&WrenchMenu::ZoomView::OnZoomLevelChanged,
5064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                       base::Unretained(this)));
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    decrement_button_ = CreateButtonWithAccName(
509f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        IDS_ZOOM_MINUS2, InMenuButtonBackground::LEFT_BUTTON,
510f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        decrement_index, IDS_ACCNAME_ZOOM_MINUS2);
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    zoom_label_ = new Label(
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        l10n_util::GetStringFUTF16Int(IDS_ZOOM_PERCENT, 100));
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    zoom_label_->SetAutoColorReadabilityEnabled(false);
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    zoom_label_->SetHorizontalAlignment(gfx::ALIGN_RIGHT);
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    InMenuButtonBackground* center_bg =
5185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        new InMenuButtonBackground(InMenuButtonBackground::RIGHT_BUTTON);
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    zoom_label_->set_background(center_bg);
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddChildView(zoom_label_);
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    zoom_label_width_ = MaxWidthForZoomLabel();
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    increment_button_ = CreateButtonWithAccName(
525f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        IDS_ZOOM_PLUS2, InMenuButtonBackground::RIGHT_BUTTON,
526f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        increment_index, IDS_ACCNAME_ZOOM_PLUS2);
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    center_bg->SetOtherButtons(decrement_button_, increment_button_);
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fullscreen_button_ = new FullscreenButton(this);
531a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // all buttons on menu should must be a custom button in order for
532a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // the keyboard nativigation work.
533a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    DCHECK(CustomButton::AsCustomButton(fullscreen_button_));
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::ImageSkia* full_screen_image =
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            IDR_FULLSCREEN_MENU_BUTTON);
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    fullscreen_button_->SetImage(ImageButton::STATE_NORMAL, full_screen_image);
538f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
5395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    fullscreen_button_->SetFocusable(true);
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fullscreen_button_->set_request_focus_on_press(false);
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fullscreen_button_->set_tag(fullscreen_index);
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fullscreen_button_->SetImageAlignment(
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ImageButton::ALIGN_CENTER, ImageButton::ALIGN_MIDDLE);
5445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    fullscreen_button_->set_background(
5455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        new InMenuButtonBackground(InMenuButtonBackground::SINGLE_BUTTON));
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fullscreen_button_->SetAccessibleName(
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GetAccessibleNameForWrenchMenuItem(
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            menu_model, fullscreen_index, IDS_ACCNAME_FULLSCREEN));
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddChildView(fullscreen_button_);
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
551f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // Need to set a font list for the zoom label width calculations.
552f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    OnNativeThemeChanged(NULL);
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UpdateZoomControls();
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual ~ZoomView() {}
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from View.
559cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual gfx::Size GetPreferredSize() const OVERRIDE {
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The increment/decrement button are forced to the same width.
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int button_width = std::max(increment_button_->GetPreferredSize().width(),
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                decrement_button_->GetPreferredSize().width());
5635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    int fullscreen_width =
5645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        fullscreen_button_->GetPreferredSize().width() + kFullscreenPadding;
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Returned height doesn't matter as MenuItemView forces everything to the
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // height of the menuitemview. Note that we have overridden the height when
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // constructing the menu.
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return gfx::Size(button_width + zoom_label_width_ + button_width +
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     fullscreen_width, 0);
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Layout() OVERRIDE {
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int x = 0;
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int button_width = std::max(increment_button_->GetPreferredSize().width(),
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                decrement_button_->GetPreferredSize().width());
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::Rect bounds(0, 0, button_width, height());
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    decrement_button_->SetBoundsRect(bounds);
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    x += bounds.width();
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bounds.set_x(x);
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bounds.set_width(zoom_label_width_);
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    zoom_label_->SetBoundsRect(bounds);
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    x += bounds.width();
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bounds.set_x(x);
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bounds.set_width(button_width);
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    increment_button_->SetBoundsRect(bounds);
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    x += bounds.width();
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bounds.set_x(x);
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bounds.set_width(fullscreen_button_->GetPreferredSize().width() +
5935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                     kFullscreenPadding);
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fullscreen_button_->SetBoundsRect(bounds);
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
597f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual void OnNativeThemeChanged(const ui::NativeTheme* theme) OVERRIDE {
598f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    WrenchMenuView::OnNativeThemeChanged(theme);
599f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
600f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const MenuConfig& menu_config = MenuConfig::instance(theme);
6015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    zoom_label_->SetBorder(views::Border::CreateEmptyBorder(
6025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        0, kZoomLabelHorizontalPadding, 0, kZoomLabelHorizontalPadding));
603f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    zoom_label_->SetFontList(menu_config.font_list);
604f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    zoom_label_width_ = MaxWidthForZoomLabel();
605f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
606f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (theme) {
607f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      zoom_label_->SetEnabledColor(theme->GetSystemColor(
608f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          ui::NativeTheme::kColorId_EnabledMenuItemForegroundColor));
609f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      gfx::ImageSkia* full_screen_image =
610f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
611f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)              IDR_FULLSCREEN_MENU_BUTTON);
612f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      SkColor fg_color = theme->GetSystemColor(
613f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          ui::NativeTheme::kColorId_SelectedMenuItemForegroundColor);
614f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      gfx::ImageSkia hovered_fullscreen_image(
615f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          new HoveredImageSource(*full_screen_image, fg_color),
616f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      full_screen_image->size());
617f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      fullscreen_button_->SetImage(
618f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          ImageButton::STATE_HOVERED, &hovered_fullscreen_image);
619f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      fullscreen_button_->SetImage(
620f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          ImageButton::STATE_PRESSED, &hovered_fullscreen_image);
621f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }
622f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
623f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from ButtonListener.
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ButtonPressed(views::Button* sender,
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const ui::Event& event) OVERRIDE {
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sender->tag() == fullscreen_index_) {
6283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      menu()->CancelAndEvaluate(menu_model(), sender->tag());
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Zoom buttons don't close the menu.
6313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      menu_model()->ActivatedAt(sender->tag());
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Overridden from WrenchMenuObserver.
6363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual void WrenchMenuDestroyed() OVERRIDE {
6373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    WrenchMenuView::WrenchMenuDestroyed();
6383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
6393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void OnZoomLevelChanged(const HostZoomMap::ZoomLevelChange& change) {
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UpdateZoomControls();
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void UpdateZoomControls() {
6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebContents* selected_tab =
6473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        menu()->browser_->tab_strip_model()->GetActiveWebContents();
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int zoom = 100;
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (selected_tab)
650116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      zoom = ZoomController::FromWebContents(selected_tab)->GetZoomPercent();
651116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    increment_button_->SetEnabled(zoom < selected_tab->GetMaximumZoomPercent());
652116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    decrement_button_->SetEnabled(zoom > selected_tab->GetMinimumZoomPercent());
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    zoom_label_->SetText(
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        l10n_util::GetStringFUTF16Int(IDS_ZOOM_PERCENT, zoom));
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    zoom_label_width_ = MaxWidthForZoomLabel();
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Calculates the max width the zoom string can be.
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int MaxWidthForZoomLabel() {
6615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const gfx::FontList& font_list = zoom_label_->font_list();
6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int border_width =
6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        zoom_label_->border() ? zoom_label_->border()->GetInsets().width() : 0;
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int max_w = 0;
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebContents* selected_tab =
6683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        menu()->browser_->tab_strip_model()->GetActiveWebContents();
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (selected_tab) {
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int min_percent = selected_tab->GetMinimumZoomPercent();
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int max_percent = selected_tab->GetMaximumZoomPercent();
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int step = (max_percent - min_percent) / 10;
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (int i = min_percent; i <= max_percent; i += step) {
6755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        int w = gfx::GetStringWidth(
6765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            l10n_util::GetStringFUTF16Int(IDS_ZOOM_PERCENT, i), font_list);
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        max_w = std::max(w, max_w);
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
6805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      max_w = gfx::GetStringWidth(
6815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          l10n_util::GetStringFUTF16Int(IDS_ZOOM_PERCENT, 100), font_list);
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return max_w + border_width;
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Index of the fullscreen menu item in the model.
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int fullscreen_index_;
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
690116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<content::HostZoomMap::Subscription> content_zoom_subscription_;
691116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<content::HostZoomMap::Subscription> browser_zoom_subscription_;
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NotificationRegistrar registrar_;
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Button for incrementing the zoom.
6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LabelButton* increment_button_;
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Label showing zoom as a percent.
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Label* zoom_label_;
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Button for decrementing the zoom.
7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LabelButton* decrement_button_;
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ImageButton* fullscreen_button_;
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Width given to |zoom_label_|. This is the width at 100%.
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int zoom_label_width_;
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ZoomView);
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// RecentTabsMenuModelDelegate  ------------------------------------------------
7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Provides the ui::MenuModelDelegate implementation for RecentTabsSubMenuModel
7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// items.
7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class WrenchMenu::RecentTabsMenuModelDelegate : public ui::MenuModelDelegate {
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
7174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  RecentTabsMenuModelDelegate(WrenchMenu* wrench_menu,
7184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                              ui::MenuModel* model,
7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              views::MenuItemView* menu_item)
7204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      : wrench_menu_(wrench_menu),
7214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        model_(model),
7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        menu_item_(menu_item) {
7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    model_->SetMenuModelDelegate(this);
7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~RecentTabsMenuModelDelegate() {
7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    model_->SetMenuModelDelegate(NULL);
7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const gfx::FontList* GetLabelFontListAt(int index) const {
7315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return model_->GetLabelFontListAt(index);
7327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
7337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
73423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  bool GetShouldUseDisabledEmphasizedForegroundColor(int index) const {
73523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    // The items for which we get a font list, should be shown in the bolded
73623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    // color.
73723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    return GetLabelFontListAt(index) ? true : false;
7387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
7397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
7404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // ui::MenuModelDelegate implementation:
7414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual void OnIconChanged(int index) OVERRIDE {
7434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    int command_id = model_->GetCommandIdAt(index);
7444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    views::MenuItemView* item = menu_item_->GetMenuItemByID(command_id);
7454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    DCHECK(item);
7464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    gfx::Image icon;
7474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    model_->GetIconAt(index, &icon);
7484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    item->SetIcon(*icon.ToImageSkia());
7494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
7504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual void OnMenuStructureChanged() OVERRIDE {
7524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (menu_item_->HasSubmenu()) {
7534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // Remove all menu items from submenu.
7544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      views::SubmenuView* submenu = menu_item_->GetSubmenu();
7554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      while (submenu->child_count() > 0)
7564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        menu_item_->RemoveMenuItemAt(submenu->child_count() - 1);
7574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // Remove all elements in |WrenchMenu::command_id_to_entry_| that map to
7594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // |model_|.
7604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      WrenchMenu::CommandIDToEntry::iterator iter =
7614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          wrench_menu_->command_id_to_entry_.begin();
7624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      while (iter != wrench_menu_->command_id_to_entry_.end()) {
7634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        if (iter->second.first == model_)
7644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          wrench_menu_->command_id_to_entry_.erase(iter++);
7654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        else
7664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          ++iter;
7674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      }
7684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
7694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Add all menu items from |model| to submenu.
7714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    for (int i = 0; i < model_->GetItemCount(); ++i) {
7725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      wrench_menu_->AddMenuItem(menu_item_, i, model_, i, model_->GetTypeAt(i));
7734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
7744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // In case recent tabs submenu was open when items were changing, force a
7764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // ChildrenChanged().
7774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    menu_item_->ChildrenChanged();
7784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
7794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
7814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  WrenchMenu* wrench_menu_;
7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::MenuModel* model_;
7832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  views::MenuItemView* menu_item_;
7842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(RecentTabsMenuModelDelegate);
7862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WrenchMenu ------------------------------------------------------------------
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)WrenchMenu::WrenchMenu(Browser* browser, int run_flags)
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : root_(NULL),
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser_(browser),
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      selected_menu_model_(NULL),
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      selected_index_(0),
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bookmark_menu_(NULL),
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      feedback_menu_item_(NULL),
7975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      run_flags_(run_flags) {
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  registrar_.Add(this, chrome::NOTIFICATION_GLOBAL_ERRORS_CHANGED,
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 content::Source<Profile>(browser_->profile()));
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WrenchMenu::~WrenchMenu() {
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (bookmark_menu_delegate_.get()) {
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BookmarkModel* model = BookmarkModelFactory::GetForProfile(
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        browser_->profile());
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (model)
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      model->RemoveObserver(this);
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FOR_EACH_OBSERVER(WrenchMenuObserver, observer_list_, WrenchMenuDestroyed());
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WrenchMenu::Init(ui::MenuModel* model) {
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!root_);
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  root_ = new MenuItemView(this);
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  root_->set_has_icons(true);  // We have checks, radios and icons, set this
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               // so we get the taller menu style.
8174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  PopulateMenu(root_, model);
8184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(DEBUG)
8204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Verify that the reserved command ID's for bookmarks menu are not used.
8214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  for (int i = WrenchMenuModel:kMinBookmarkCommandId;
8224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)       i <= WrenchMenuModel::kMaxBookmarkCommandId; ++i)
8234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    DCHECK(command_id_to_entry_.find(i) == command_id_to_entry_.end());
8244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif  // defined(DEBUG)
8254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  int32 types = views::MenuRunner::HAS_MNEMONICS;
8275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (for_drop()) {
8285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // We add NESTED_DRAG since currently the only operation to open the wrench
8295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // menu for is an extension action drag, which is controlled by the child
8305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // BrowserActionsContainer view.
8315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    types |= views::MenuRunner::FOR_DROP | views::MenuRunner::NESTED_DRAG;
8325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
8335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  menu_runner_.reset(new views::MenuRunner(root_, types));
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WrenchMenu::RunMenu(views::MenuButton* host) {
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point screen_loc;
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::View::ConvertPointToScreen(host, &screen_loc);
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect bounds(screen_loc, host->size());
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("ShowAppMenu"));
8415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (menu_runner_->RunMenuAt(host->GetWidget(),
8425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                              host,
8435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                              bounds,
8445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                              views::MENU_ANCHOR_TOPRIGHT,
845116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                              ui::MENU_SOURCE_NONE) ==
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      views::MenuRunner::MENU_DELETED)
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (bookmark_menu_delegate_.get()) {
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BookmarkModel* model = BookmarkModelFactory::GetForProfile(
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        browser_->profile());
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (model)
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      model->RemoveObserver(this);
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (selected_menu_model_)
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    selected_menu_model_->ActivatedAt(selected_index_);
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void WrenchMenu::CloseMenu() {
8595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (menu_runner_.get())
8605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    menu_runner_->Cancel();
8615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
8625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WrenchMenu::IsShowing() {
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return menu_runner_.get() && menu_runner_->IsRunning();
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void WrenchMenu::AddObserver(WrenchMenuObserver* observer) {
8683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  observer_list_.AddObserver(observer);
8693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
8703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
8713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void WrenchMenu::RemoveObserver(WrenchMenuObserver* observer) {
8723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  observer_list_.RemoveObserver(observer);
8733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
8743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
8755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const gfx::FontList* WrenchMenu::GetLabelFontList(int command_id) const {
8764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (IsRecentTabsCommand(command_id)) {
8775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return recent_tabs_menu_model_delegate_->GetLabelFontListAt(
8784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        ModelIndexFromCommandId(command_id));
8797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
8807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return NULL;
8817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
8827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
88323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)bool WrenchMenu::GetShouldUseDisabledEmphasizedForegroundColor(
88423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    int command_id) const {
8854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (IsRecentTabsCommand(command_id)) {
88623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    return recent_tabs_menu_model_delegate_->
88723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        GetShouldUseDisabledEmphasizedForegroundColor(
88823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)            ModelIndexFromCommandId(command_id));
8897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
8907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return false;
8917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
8927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
893a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)base::string16 WrenchMenu::GetTooltipText(int command_id,
894a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                          const gfx::Point& p) const {
8954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return IsBookmarkCommand(command_id) ?
896a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      bookmark_menu_delegate_->GetTooltipText(command_id, p) : base::string16();
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WrenchMenu::IsTriggerableEvent(views::MenuItemView* menu,
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    const ui::Event& e) {
9014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return IsBookmarkCommand(menu->GetCommand()) ?
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bookmark_menu_delegate_->IsTriggerableEvent(menu, e) :
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MenuDelegate::IsTriggerableEvent(menu, e);
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WrenchMenu::GetDropFormats(
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MenuItemView* menu,
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int* formats,
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::set<ui::OSExchangeData::CustomFormat>* custom_formats) {
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateBookmarkMenu();
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return bookmark_menu_delegate_.get() &&
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bookmark_menu_delegate_->GetDropFormats(menu, formats, custom_formats);
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WrenchMenu::AreDropTypesRequired(MenuItemView* menu) {
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateBookmarkMenu();
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return bookmark_menu_delegate_.get() &&
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bookmark_menu_delegate_->AreDropTypesRequired(menu);
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WrenchMenu::CanDrop(MenuItemView* menu,
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         const ui::OSExchangeData& data) {
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateBookmarkMenu();
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return bookmark_menu_delegate_.get() &&
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bookmark_menu_delegate_->CanDrop(menu, data);
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int WrenchMenu::GetDropOperation(
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MenuItemView* item,
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ui::DropTargetEvent& event,
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DropPosition* position) {
9324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return IsBookmarkCommand(item->GetCommand()) ?
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bookmark_menu_delegate_->GetDropOperation(item, event, position) :
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui::DragDropTypes::DRAG_NONE;
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int WrenchMenu::OnPerformDrop(MenuItemView* menu,
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              DropPosition position,
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              const ui::DropTargetEvent& event) {
9404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!IsBookmarkCommand(menu->GetCommand()))
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ui::DragDropTypes::DRAG_NONE;
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int result = bookmark_menu_delegate_->OnPerformDrop(menu, position, event);
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WrenchMenu::ShowContextMenu(MenuItemView* source,
9484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                 int command_id,
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 const gfx::Point& p,
9507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                 ui::MenuSourceType source_type) {
9514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return IsBookmarkCommand(command_id) ?
9524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      bookmark_menu_delegate_->ShowContextMenu(source, command_id, p,
9537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                               source_type) :
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false;
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WrenchMenu::CanDrag(MenuItemView* menu) {
9584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return IsBookmarkCommand(menu->GetCommand()) ?
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bookmark_menu_delegate_->CanDrag(menu) : false;
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WrenchMenu::WriteDragData(MenuItemView* sender,
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               ui::OSExchangeData* data) {
9644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(IsBookmarkCommand(sender->GetCommand()));
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return bookmark_menu_delegate_->WriteDragData(sender, data);
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int WrenchMenu::GetDragOperations(MenuItemView* sender) {
9694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return IsBookmarkCommand(sender->GetCommand()) ?
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bookmark_menu_delegate_->GetDragOperations(sender) :
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MenuDelegate::GetDragOperations(sender);
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int WrenchMenu::GetMaxWidthForMenu(MenuItemView* menu) {
9754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (IsBookmarkCommand(menu->GetCommand()))
9762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return bookmark_menu_delegate_->GetMaxWidthForMenu(menu);
9775b62eb5758cb7b791cfdd45cf78f35dc060631b6Ben Murdoch  return MenuDelegate::GetMaxWidthForMenu(menu);
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool WrenchMenu::IsItemChecked(int command_id) const {
9814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (IsBookmarkCommand(command_id))
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const Entry& entry = command_id_to_entry_.find(command_id)->second;
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return entry.first->IsItemCheckedAt(entry.second);
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool WrenchMenu::IsCommandEnabled(int command_id) const {
9894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (IsBookmarkCommand(command_id))
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (command_id == 0)
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;  // The root item.
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // The items representing the cut menu (cut/copy/paste), zoom menu
996116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // (increment/decrement/reset) and extension toolbar view are always enabled.
997116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // The child views of these items enabled state updates appropriately.
998116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (command_id == IDC_CUT || command_id == IDC_ZOOM_MINUS ||
999116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      command_id == IDC_EXTENSIONS_OVERFLOW_MENU)
10004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return true;
10014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
10024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const Entry& entry = command_id_to_entry_.find(command_id)->second;
10034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return entry.first->IsEnabledAt(entry.second);
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void WrenchMenu::ExecuteCommand(int command_id, int mouse_event_flags) {
10074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (IsBookmarkCommand(command_id)) {
10084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    bookmark_menu_delegate_->ExecuteCommand(command_id, mouse_event_flags);
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1012116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (command_id == IDC_CUT || command_id == IDC_ZOOM_MINUS ||
1013116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      command_id == IDC_EXTENSIONS_OVERFLOW_MENU) {
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // These items are represented by child views. If ExecuteCommand is invoked
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // it means the user clicked on the area around the buttons and we should
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // not do anyting.
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const Entry& entry = command_id_to_entry_.find(command_id)->second;
10212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return entry.first->ActivatedAt(entry.second, mouse_event_flags);
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1024cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool WrenchMenu::GetAccelerator(int command_id,
1025cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                ui::Accelerator* accelerator) const {
10264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (IsBookmarkCommand(command_id))
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1029116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (command_id == IDC_CUT || command_id == IDC_ZOOM_MINUS ||
1030116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      command_id == IDC_EXTENSIONS_OVERFLOW_MENU) {
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // These have special child views; don't show the accelerator for them.
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  CommandIDToEntry::const_iterator ix = command_id_to_entry_.find(command_id);
10364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const Entry& entry = ix->second;
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::Accelerator menu_accelerator;
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!entry.first->GetAcceleratorAt(entry.second, &menu_accelerator))
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *accelerator = ui::Accelerator(menu_accelerator.key_code(),
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 menu_accelerator.modifiers());
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WrenchMenu::WillShowMenu(MenuItemView* menu) {
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (menu == bookmark_menu_)
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateBookmarkMenu();
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WrenchMenu::WillHideMenu(MenuItemView* menu) {
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Turns off the fade out animation of the wrench menus if
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |feedback_menu_item_| is selected.  This excludes the wrench menu itself
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // from the snapshot in the feedback UI.
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (menu->HasSubmenu() && feedback_menu_item_ &&
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      feedback_menu_item_->IsSelected()) {
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // It's okay to just turn off the animation and no to take care the
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // animation back because the menu widget will be recreated next time
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // it's opened. See ToolbarView::RunMenu() and Init() of this class.
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    menu->GetSubmenu()->GetWidget()->
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        SetVisibilityChangedAnimationsEnabled(false);
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool WrenchMenu::ShouldCloseOnDragComplete() {
1066116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return false;
1067116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
1068116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WrenchMenu::BookmarkModelChanged() {
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(bookmark_menu_delegate_.get());
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!bookmark_menu_delegate_->is_mutating_model())
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    root_->Cancel();
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WrenchMenu::Observe(int type,
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         const content::NotificationSource& source,
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         const content::NotificationDetails& details) {
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (type) {
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case chrome::NOTIFICATION_GLOBAL_ERRORS_CHANGED:
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // A change in the global errors list can add or remove items from the
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // menu. Close the menu to avoid have a stale menu on-screen.
1082a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      if (root_)
1083a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        root_->Cancel();
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WrenchMenu::PopulateMenu(MenuItemView* parent,
10914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                              MenuModel* model) {
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0, max = model->GetItemCount(); i < max; ++i) {
10934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Add the menu item at the end.
10944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    int menu_index = parent->HasSubmenu() ?
10954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        parent->GetSubmenu()->child_count() : 0;
10965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    MenuItemView* item =
10975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        AddMenuItem(parent, menu_index, model, i, model->GetTypeAt(i));
10985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
10995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (model->GetCommandIdAt(i) == IDC_CUT ||
11005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        model->GetCommandIdAt(i) == IDC_ZOOM_MINUS) {
11015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      const MenuConfig& config = item->GetMenuConfig();
11025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      int top_margin = config.item_top_margin + config.separator_height / 2;
11035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      int bottom_margin =
11045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          config.item_bottom_margin + config.separator_height / 2;
11055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
11065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      // Chromeos adds extra vertical space for the menu buttons.
11075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if defined(OS_CHROMEOS)
11085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      top_margin += 4;
11095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      bottom_margin += 5;
11105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif
11115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
11125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      item->SetMargins(top_margin, bottom_margin);
11135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
11144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
11154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (model->GetTypeAt(i) == MenuModel::TYPE_SUBMENU)
11164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      PopulateMenu(item, model->GetSubmenuModelAt(i));
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    switch (model->GetCommandIdAt(i)) {
11195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      case IDC_EXTENSIONS_OVERFLOW_MENU: {
11205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        scoped_ptr<ExtensionToolbarMenuView> extension_toolbar(
11215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            new ExtensionToolbarMenuView(browser_, this));
11221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        if (extension_toolbar->ShouldShow())
11235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          item->AddChildView(extension_toolbar.release());
1124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        else
1125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          item->SetVisible(false);
1126116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        break;
11275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      }
11285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case IDC_CUT:
11302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DCHECK_EQ(MenuModel::TYPE_COMMAND, model->GetTypeAt(i));
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DCHECK_LT(i + 2, max);
11322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DCHECK_EQ(IDC_COPY, model->GetCommandIdAt(i + 1));
11332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DCHECK_EQ(IDC_PASTE, model->GetCommandIdAt(i + 2));
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        item->SetTitle(l10n_util::GetStringUTF16(IDS_EDIT2));
1135f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        item->AddChildView(new CutCopyPasteView(this, model,
11362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                i, i + 1, i + 2));
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        i += 2;
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case IDC_ZOOM_MINUS:
11412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DCHECK_EQ(MenuModel::TYPE_COMMAND, model->GetTypeAt(i));
11422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DCHECK_EQ(IDC_ZOOM_PLUS, model->GetCommandIdAt(i + 1));
11432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DCHECK_EQ(IDC_FULLSCREEN, model->GetCommandIdAt(i + 2));
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        item->SetTitle(l10n_util::GetStringUTF16(IDS_ZOOM_MENU2));
1145f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        item->AddChildView(new ZoomView(this, model, i, i + 1, i + 2));
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        i += 2;
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case IDC_BOOKMARKS_MENU:
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DCHECK(!bookmark_menu_);
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        bookmark_menu_ = item;
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#if defined(GOOGLE_CHROME_BUILD)
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case IDC_FEEDBACK:
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DCHECK(!feedback_menu_item_);
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        feedback_menu_item_ = item;
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
115958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#endif
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case IDC_RECENT_TABS_MENU:
11622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DCHECK(!recent_tabs_menu_model_delegate_.get());
11632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        recent_tabs_menu_model_delegate_.reset(
11644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            new RecentTabsMenuModelDelegate(this, model->GetSubmenuModelAt(i),
11652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                            item));
11662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
11672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default:
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)MenuItemView* WrenchMenu::AddMenuItem(MenuItemView* parent,
11754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                      int menu_index,
11764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                      MenuModel* model,
11774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                      int model_index,
11785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                      MenuModel::ItemType menu_type) {
11794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  int command_id = model->GetCommandIdAt(model_index);
11804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(command_id > -1 ||
11814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)         (command_id == -1 &&
11824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          model->GetTypeAt(model_index) == MenuModel::TYPE_SEPARATOR));
11834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
11844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (command_id > -1) {  // Don't add separators to |command_id_to_entry_|.
11854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // All command ID's should be unique except for IDC_SHOW_HISTORY which is
11864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // in both wrench menu and RecentTabs submenu,
11874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (command_id != IDC_SHOW_HISTORY) {
11884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      DCHECK(command_id_to_entry_.find(command_id) ==
11894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)             command_id_to_entry_.end())
11904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          << "command ID " << command_id << " already exists!";
11914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
11924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    command_id_to_entry_[command_id].first = model;
11934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    command_id_to_entry_[command_id].second = model_index;
11944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  MenuItemView* menu_item = views::MenuModelAdapter::AddMenuItemFromModelAt(
11975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      model, model_index, parent, menu_index, command_id);
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (menu_item) {
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Flush all buttons to the right side of the menu for the new menu type.
12015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    menu_item->set_use_right_margin(false);
12024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    menu_item->SetVisible(model->IsVisibleAt(model_index));
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (menu_type == MenuModel::TYPE_COMMAND && model->HasIcons()) {
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Image icon;
12064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      if (model->GetIconAt(model_index, &icon))
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        menu_item->SetIcon(*icon.ToImageSkia());
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return menu_item;
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WrenchMenu::CancelAndEvaluate(MenuModel* model, int index) {
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  selected_menu_model_ = model;
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  selected_index_ = index;
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  root_->Cancel();
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WrenchMenu::CreateBookmarkMenu() {
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (bookmark_menu_delegate_.get())
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;  // Already created the menu.
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1224b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  BookmarkModel* model =
1225b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      BookmarkModelFactory::GetForProfile(browser_->profile());
1226b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (!model->loaded())
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model->AddObserver(this);
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(oshima): Replace with views only API.
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::Widget* parent = views::Widget::GetWidgetForNativeWindow(
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser_->window()->GetNativeWindow());
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bookmark_menu_delegate_.reset(
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new BookmarkMenuDelegate(browser_,
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               browser_,
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               parent,
12384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                               WrenchMenuModel::kMinBookmarkCommandId,
12394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                               WrenchMenuModel::kMaxBookmarkCommandId));
124068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  bookmark_menu_delegate_->Init(this,
124168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                bookmark_menu_,
124268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                model->bookmark_bar_node(),
124368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                0,
124468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                BookmarkMenuDelegate::SHOW_PERMANENT_FOLDERS,
124568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                BOOKMARK_LAUNCH_LOCATION_WRENCH_MENU);
12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
12484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)int WrenchMenu::ModelIndexFromCommandId(int command_id) const {
12494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  CommandIDToEntry::const_iterator ix = command_id_to_entry_.find(command_id);
12504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(ix != command_id_to_entry_.end());
12514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return ix->second.second;
12524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1253