diff options
author | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-05 22:49:58 +0000 |
---|---|---|
committer | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-05 22:49:58 +0000 |
commit | 0f28580a84220d218288bfdec6bb689b2e1b8d29 (patch) | |
tree | 2034a137103f04f513b6ab0d4cc3cbb13ccdd30f | |
parent | 4a4d141960653d52e80b52c92358b6f19fc21b1b (diff) | |
download | chromium_src-0f28580a84220d218288bfdec6bb689b2e1b8d29.zip chromium_src-0f28580a84220d218288bfdec6bb689b2e1b8d29.tar.gz chromium_src-0f28580a84220d218288bfdec6bb689b2e1b8d29.tar.bz2 |
GTK: make tab context menu use tab_menu_model
flesh out some more menu model implementation for MenuGtk
BUG=28977
TEST=menu still works as before
Review URL: http://codereview.chromium.org/523049
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@35569 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | app/app_base.gypi | 1 | ||||
-rw-r--r-- | app/menus/accelerator_gtk.h | 46 | ||||
-rw-r--r-- | chrome/browser/gtk/browser_actions_toolbar_gtk.cc | 5 | ||||
-rw-r--r-- | chrome/browser/gtk/location_bar_view_gtk.cc | 2 | ||||
-rw-r--r-- | chrome/browser/gtk/location_bar_view_gtk.h | 3 | ||||
-rw-r--r-- | chrome/browser/gtk/menu_gtk.cc | 60 | ||||
-rw-r--r-- | chrome/browser/gtk/menu_gtk.h | 1 | ||||
-rw-r--r-- | chrome/browser/gtk/tabs/tab_gtk.cc | 84 |
8 files changed, 138 insertions, 64 deletions
diff --git a/app/app_base.gypi b/app/app_base.gypi index 9c15d4c..f0aacef 100644 --- a/app/app_base.gypi +++ b/app/app_base.gypi @@ -159,6 +159,7 @@ 'l10n_util_win.cc', 'l10n_util_win.h', 'menus/accelerator.h', + 'menus/accelerator_gtk.h', 'menus/menu_model.cc', 'menus/menu_model.h', 'menus/simple_menu_model.cc', diff --git a/app/menus/accelerator_gtk.h b/app/menus/accelerator_gtk.h new file mode 100644 index 0000000..ad74b4e --- /dev/null +++ b/app/menus/accelerator_gtk.h @@ -0,0 +1,46 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef APP_MENUS_ACCELERATOR_GTK_H_ +#define APP_MENUS_ACCELERATOR_GTK_H_ + +#include <gdk/gdk.h> + +#include "app/menus/accelerator.h" +#include "base/keyboard_code_conversion_gtk.h" +#include "base/keyboard_codes_posix.h" + +namespace menus { + +class AcceleratorGtk : public Accelerator { + public: + AcceleratorGtk(base::KeyboardCode key_code, + bool shift_pressed, bool ctrl_pressed, bool alt_pressed) { + key_code_ = key_code; + modifiers_ = 0; + if (shift_pressed) + modifiers_ |= GDK_SHIFT_MASK; + if (ctrl_pressed) + modifiers_ |= GDK_CONTROL_MASK; + if (alt_pressed) + modifiers_ |= GDK_MOD1_MASK; + } + + AcceleratorGtk() { } + virtual ~AcceleratorGtk() { } + + guint GetGdkKeyCode() { + // The second parameter is false because accelerator keys are expressed in + // terms of the non-shift-modified key. + return base::GdkKeyCodeForWindowsKeyCode(GetKeyCode(), false); + } + + GdkModifierType gdk_modifier_type() { + return static_cast<GdkModifierType>(modifiers()); + } +}; + +} + +#endif // APP_MENUS_ACCELERATOR_GTK_H_ diff --git a/chrome/browser/gtk/browser_actions_toolbar_gtk.cc b/chrome/browser/gtk/browser_actions_toolbar_gtk.cc index cc43f3e..4da93f9 100644 --- a/chrome/browser/gtk/browser_actions_toolbar_gtk.cc +++ b/chrome/browser/gtk/browser_actions_toolbar_gtk.cc @@ -51,8 +51,7 @@ GtkTargetEntry GetDragTargetEntry() { } // namespace class BrowserActionButton : public NotificationObserver, - public ImageLoadingTracker::Observer, - public MenuGtk::Delegate { + public ImageLoadingTracker::Observer { public: BrowserActionButton(BrowserActionsToolbarGtk* toolbar, Extension* extension) @@ -182,7 +181,7 @@ class BrowserActionButton : public NotificationObserver, } action->context_menu_.reset( - new MenuGtk(action, action->context_menu_model_.get())); + new MenuGtk(NULL, action->context_menu_model_.get())); action->context_menu_->Popup(widget, event); return TRUE; diff --git a/chrome/browser/gtk/location_bar_view_gtk.cc b/chrome/browser/gtk/location_bar_view_gtk.cc index 186b575..0f037c8 100644 --- a/chrome/browser/gtk/location_bar_view_gtk.cc +++ b/chrome/browser/gtk/location_bar_view_gtk.cc @@ -887,7 +887,7 @@ gboolean LocationBarViewGtk::PageActionViewGtk::OnButtonPressed( context_menu_model_.reset(new ExtensionActionContextMenuModel(extension)); context_menu_.reset( - new MenuGtk(this, context_menu_model_.get())); + new MenuGtk(NULL, context_menu_model_.get())); context_menu_->Popup(sender, event); } diff --git a/chrome/browser/gtk/location_bar_view_gtk.h b/chrome/browser/gtk/location_bar_view_gtk.h index 078ebd60..03ca90e 100644 --- a/chrome/browser/gtk/location_bar_view_gtk.h +++ b/chrome/browser/gtk/location_bar_view_gtk.h @@ -107,8 +107,7 @@ class LocationBarViewGtk : public AutocompleteEditController, static const GdkColor kBackgroundColorByLevel[3]; private: - class PageActionViewGtk : public ImageLoadingTracker::Observer, - public MenuGtk::Delegate { + class PageActionViewGtk : public ImageLoadingTracker::Observer { public: PageActionViewGtk( LocationBarViewGtk* owner, Profile* profile, diff --git a/chrome/browser/gtk/menu_gtk.cc b/chrome/browser/gtk/menu_gtk.cc index 592d9d3..e5b421f 100644 --- a/chrome/browser/gtk/menu_gtk.cc +++ b/chrome/browser/gtk/menu_gtk.cc @@ -6,6 +6,7 @@ #include "app/gfx/gtk_util.h" #include "app/l10n_util.h" +#include "app/menus/accelerator_gtk.h" #include "app/menus/menu_model.h" #include "base/logging.h" #include "base/message_loop.h" @@ -35,9 +36,10 @@ MenuGtk::MenuGtk(MenuGtk::Delegate* delegate, menus::MenuModel* model) : delegate_(delegate), model_(model), - dummy_accel_group_(NULL), + dummy_accel_group_(gtk_accel_group_new()), menu_(gtk_menu_new()), factory_(this) { + DCHECK(delegate || model); ConnectSignalHandlers(); if (model) BuildMenuFromModel(); @@ -45,8 +47,7 @@ MenuGtk::MenuGtk(MenuGtk::Delegate* delegate, MenuGtk::~MenuGtk() { STLDeleteContainerPointers(submenus_we_own_.begin(), submenus_we_own_.end()); - if (dummy_accel_group_) - g_object_unref(dummy_accel_group_); + g_object_unref(dummy_accel_group_); } void MenuGtk::ConnectSignalHandlers() { @@ -219,7 +220,7 @@ GtkWidget* MenuGtk::BuildMenuItemWithImage(const std::string& label, gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item), gtk_image_new_from_pixbuf(pixbuf)); g_object_unref(pixbuf); - if (delegate_->AlwaysShowImages()) + if (delegate_ && delegate_->AlwaysShowImages()) gtk_util::SetAlwaysShowImage(menu_item); return menu_item; @@ -230,19 +231,41 @@ void MenuGtk::BuildMenuFromModel() { GtkWidget* menu_item = NULL; // TODO(estade): support these commands. - DCHECK_NE(model_->GetTypeAt(i), menus::MenuModel::TYPE_CHECK); DCHECK_NE(model_->GetTypeAt(i), menus::MenuModel::TYPE_RADIO); DCHECK_NE(model_->GetTypeAt(i), menus::MenuModel::TYPE_SUBMENU); SkBitmap icon; - if (model_->GetTypeAt(i) == menus::MenuModel::TYPE_SEPARATOR) { - menu_item = gtk_separator_menu_item_new(); - } else if (model_->GetIconAt(i, &icon)) { - menu_item = BuildMenuItemWithImage(UTF16ToUTF8(model_->GetLabelAt(i)), - icon); - } else { - menu_item = gtk_menu_item_new_with_label( - UTF16ToUTF8(model_->GetLabelAt(i)).c_str()); + std::string label = + ConvertAcceleratorsFromWindowsStyle(UTF16ToUTF8(model_->GetLabelAt(i))); + + switch (model_->GetTypeAt(i)) { + case menus::MenuModel::TYPE_SEPARATOR: + menu_item = gtk_separator_menu_item_new(); + break; + + case menus::MenuModel::TYPE_CHECK: + menu_item = gtk_check_menu_item_new_with_mnemonic(label.c_str()); + break; + + case menus::MenuModel::TYPE_COMMAND: + if (model_->GetIconAt(i, &icon)) + menu_item = BuildMenuItemWithImage(label, icon); + else + menu_item = gtk_menu_item_new_with_mnemonic(label.c_str()); + break; + + default: + NOTREACHED(); + } + + menus::AcceleratorGtk accelerator; + if (model_->GetAcceleratorAt(i, &accelerator)) { + gtk_widget_add_accelerator(menu_item, + "activate", + dummy_accel_group_, + accelerator.GetGdkKeyCode(), + accelerator.gdk_modifier_type(), + GTK_ACCEL_VISIBLE); } AppendMenuItem(i, menu_item); @@ -365,6 +388,12 @@ void MenuGtk::ExecuteCommand(int id) { delegate_->ExecuteCommand(id); } +// http://crbug.com/31365 +bool MenuGtk::IsItemChecked(int id) { + return model_ ? model_->IsItemCheckedAt(id) : + delegate_->IsItemChecked(id); +} + // static void MenuGtk::OnMenuShow(GtkWidget* widget, MenuGtk* menu) { MessageLoop::current()->PostTask(FROM_HERE, @@ -373,7 +402,8 @@ void MenuGtk::OnMenuShow(GtkWidget* widget, MenuGtk* menu) { // static void MenuGtk::OnMenuHidden(GtkWidget* widget, MenuGtk* menu) { - menu->delegate_->StoppedShowing(); + if (menu->delegate_) + menu->delegate_->StoppedShowing(); } // static @@ -410,7 +440,7 @@ void MenuGtk::SetMenuItemInfo(GtkWidget* widget, gpointer userdata) { // root of the MenuGtk and we want to disable *all* MenuGtks, including // submenus. block_activation_ = true; - gtk_check_menu_item_set_active(item, menu->delegate_->IsItemChecked(id)); + gtk_check_menu_item_set_active(item, menu->IsItemChecked(id)); block_activation_ = false; } diff --git a/chrome/browser/gtk/menu_gtk.h b/chrome/browser/gtk/menu_gtk.h index 2438e4e..427abbb 100644 --- a/chrome/browser/gtk/menu_gtk.h +++ b/chrome/browser/gtk/menu_gtk.h @@ -139,6 +139,7 @@ class MenuGtk { // http://crbug.com/31365 bool IsCommandEnabled(int id); void ExecuteCommand(int id); + bool IsItemChecked(int id); // Callback for when a menu item is clicked. static void OnMenuItemActivated(GtkMenuItem* menuitem, MenuGtk* menu); diff --git a/chrome/browser/gtk/tabs/tab_gtk.cc b/chrome/browser/gtk/tabs/tab_gtk.cc index 299c2be..023e272 100644 --- a/chrome/browser/gtk/tabs/tab_gtk.cc +++ b/chrome/browser/gtk/tabs/tab_gtk.cc @@ -9,9 +9,12 @@ #include "app/gtk_dnd_util.h" #include "app/gfx/path.h" #include "app/l10n_util.h" +#include "app/menus/accelerator_gtk.h" #include "app/resource_bundle.h" +#include "base/keyboard_codes_posix.h" #include "chrome/browser/gtk/menu_gtk.h" #include "chrome/browser/gtk/standard_menus.h" +#include "chrome/browser/tab_menu_model.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" @@ -28,39 +31,12 @@ int GetTitleWidth(gfx::Font* font, std::wstring title) { } // namespace -class TabGtk::ContextMenuController : public MenuGtk::Delegate { +class TabGtk::ContextMenuController : public menus::SimpleMenuModel::Delegate { public: explicit ContextMenuController(TabGtk* tab) - : tab_(tab) { - static const MenuCreateMaterial context_menu_blueprint[] = { - { MENU_NORMAL, TabStripModel::CommandNewTab, IDS_TAB_CXMENU_NEWTAB, - 0, NULL, GDK_t, GDK_CONTROL_MASK, true }, - { MENU_SEPARATOR }, - { MENU_NORMAL, TabStripModel::CommandReload, IDS_TAB_CXMENU_RELOAD, - 0, NULL, GDK_r, GDK_CONTROL_MASK, true }, - { MENU_NORMAL, TabStripModel::CommandDuplicate, - IDS_TAB_CXMENU_DUPLICATE }, - { MENU_CHECKBOX, TabStripModel::CommandTogglePinned, - IDS_TAB_CXMENU_PIN_TAB }, - { MENU_SEPARATOR }, - { MENU_NORMAL, TabStripModel::CommandCloseTab, IDS_TAB_CXMENU_CLOSETAB, - 0, NULL, GDK_w, GDK_CONTROL_MASK, true }, - { MENU_NORMAL, TabStripModel::CommandCloseOtherTabs, - IDS_TAB_CXMENU_CLOSEOTHERTABS }, - { MENU_NORMAL, TabStripModel::CommandCloseTabsToRight, - IDS_TAB_CXMENU_CLOSETABSTORIGHT }, - { MENU_NORMAL, TabStripModel::CommandCloseTabsOpenedBy, - IDS_TAB_CXMENU_CLOSETABSOPENEDBY }, - { MENU_SEPARATOR }, - { MENU_NORMAL, TabStripModel::CommandRestoreTab, IDS_RESTORE_TAB, - 0, NULL, GDK_t, GDK_CONTROL_MASK | GDK_SHIFT_MASK, true }, - { MENU_NORMAL, TabStripModel::CommandBookmarkAllTabs, - IDS_TAB_CXMENU_BOOKMARK_ALL_TABS, 0, NULL, GDK_d, - GDK_CONTROL_MASK | GDK_SHIFT_MASK, true }, - { MENU_END }, - }; - - menu_.reset(new MenuGtk(this, context_menu_blueprint, NULL)); + : tab_(tab), + model_(this) { + menu_.reset(new MenuGtk(NULL, &model_)); } virtual ~ContextMenuController() {} @@ -75,25 +51,44 @@ class TabGtk::ContextMenuController : public MenuGtk::Delegate { } private: - // MenuGtk::Delegate implementation: - virtual bool IsCommandEnabled(int command_id) const { - if (!tab_) - return false; - - return tab_->delegate()->IsCommandEnabledForTab( - static_cast<TabStripModel::ContextMenuCommand>(command_id), tab_); - } - - virtual bool IsItemChecked(int command_id) const { + // Overridden from menus::SimpleMenuModel::Delegate: + virtual bool IsCommandIdChecked(int command_id) const { if (!tab_ || command_id != TabStripModel::CommandTogglePinned) return false; return tab_->is_pinned(); } - + virtual bool IsCommandIdEnabled(int command_id) const { + return tab_ && tab_->delegate()->IsCommandEnabledForTab( + static_cast<TabStripModel::ContextMenuCommand>(command_id), + tab_); + } + virtual bool GetAcceleratorForCommandId( + int command_id, + menus::Accelerator* accelerator) { + switch (command_id) { + case TabStripModel::CommandNewTab: + *accelerator = menus::AcceleratorGtk(base::VKEY_T, false, true, false); + break; + case TabStripModel::CommandReload: + *accelerator = menus::AcceleratorGtk(base::VKEY_R, false, true, false); + break; + case TabStripModel::CommandCloseTab: + *accelerator = menus::AcceleratorGtk(base::VKEY_W, false, true, false); + break; + case TabStripModel::CommandRestoreTab: + *accelerator = menus::AcceleratorGtk(base::VKEY_T, true, true, false); + break; + case TabStripModel::CommandBookmarkAllTabs: + *accelerator = menus::AcceleratorGtk(base::VKEY_D, true, true, false); + break; + default: + return false; + } + return true; + } virtual void ExecuteCommand(int command_id) { if (!tab_) return; - tab_->delegate()->ExecuteCommandForTab( static_cast<TabStripModel::ContextMenuCommand>(command_id), tab_); } @@ -105,6 +100,9 @@ class TabGtk::ContextMenuController : public MenuGtk::Delegate { // is canceled. TabGtk* tab_; + // The model. + TabMenuModel model_; + DISALLOW_COPY_AND_ASSIGN(ContextMenuController); }; |