diff options
author | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-07 00:37:53 +0000 |
---|---|---|
committer | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-07 00:37:53 +0000 |
commit | 7467340a80a0dce12fcaae5d5fc62ec56131b8bb (patch) | |
tree | 5a38c0636823a267369653500a96954b2e463103 /chrome/browser/gtk/menu_gtk.cc | |
parent | 3db3ff6a8ee531957ab460c5791243b4636d11e2 (diff) | |
download | chromium_src-7467340a80a0dce12fcaae5d5fc62ec56131b8bb.zip chromium_src-7467340a80a0dce12fcaae5d5fc62ec56131b8bb.tar.gz chromium_src-7467340a80a0dce12fcaae5d5fc62ec56131b8bb.tar.bz2 |
GTK: Use page and app menu models.
- implement more MenuModel support for MenuGtk
- copy some accelerators around
TODO: centralize accelerator list (currently they are all listed twice)
TODO: get rid of standard_menus.cc (it is still used by the popup favicon menu)
BUG=NONE
TEST=page and app menus still work, still display accelerators, accelerators still work
Review URL: http://codereview.chromium.org/523105
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@35671 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/gtk/menu_gtk.cc')
-rw-r--r-- | chrome/browser/gtk/menu_gtk.cc | 113 |
1 files changed, 78 insertions, 35 deletions
diff --git a/chrome/browser/gtk/menu_gtk.cc b/chrome/browser/gtk/menu_gtk.cc index e5b421f..2b2b354 100644 --- a/chrome/browser/gtk/menu_gtk.cc +++ b/chrome/browser/gtk/menu_gtk.cc @@ -21,15 +21,24 @@ using gtk_util::ConvertAcceleratorsFromWindowsStyle; bool MenuGtk::block_activation_ = false; MenuGtk::MenuGtk(MenuGtk::Delegate* delegate, - const MenuCreateMaterial* menu_data, - GtkAccelGroup* accel_group) + const MenuCreateMaterial* menu_data) + : delegate_(delegate), + model_(NULL), + dummy_accel_group_(gtk_accel_group_new()), + menu_(gtk_menu_new()), + factory_(this) { + DCHECK(menu_data); + ConnectSignalHandlers(); + BuildMenuIn(menu_, menu_data); +} + +MenuGtk::MenuGtk(MenuGtk::Delegate* delegate) : delegate_(delegate), model_(NULL), dummy_accel_group_(gtk_accel_group_new()), menu_(gtk_menu_new()), factory_(this) { ConnectSignalHandlers(); - BuildMenuIn(menu_, menu_data, accel_group); } MenuGtk::MenuGtk(MenuGtk::Delegate* delegate, @@ -39,7 +48,7 @@ MenuGtk::MenuGtk(MenuGtk::Delegate* delegate, dummy_accel_group_(gtk_accel_group_new()), menu_(gtk_menu_new()), factory_(this) { - DCHECK(delegate || model); + DCHECK(model); ConnectSignalHandlers(); if (model) BuildMenuFromModel(); @@ -87,6 +96,12 @@ void MenuGtk::AppendSeparator() { } void MenuGtk::AppendMenuItem(int command_id, GtkWidget* menu_item) { + AppendMenuItemToMenu(command_id, menu_item, menu_); +} + +void MenuGtk::AppendMenuItemToMenu(int command_id, + GtkWidget* menu_item, + GtkWidget* menu) { g_object_set_data(G_OBJECT(menu_item), "menu-id", reinterpret_cast<void*>(command_id)); @@ -94,7 +109,7 @@ void MenuGtk::AppendMenuItem(int command_id, GtkWidget* menu_item) { G_CALLBACK(OnMenuItemActivated), this); gtk_widget_show(menu_item); - gtk_menu_shell_append(GTK_MENU_SHELL(menu_), menu_item); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item); } void MenuGtk::Popup(GtkWidget* widget, GdkEvent* event) { @@ -132,8 +147,7 @@ void MenuGtk::Cancel() { } void MenuGtk::BuildMenuIn(GtkWidget* menu, - const MenuCreateMaterial* menu_data, - GtkAccelGroup* accel_group) { + const MenuCreateMaterial* menu_data) { // We keep track of the last menu item in order to group radio items. GtkWidget* last_menu_item = NULL; for (; menu_data->type != MENU_END; ++menu_data) { @@ -177,7 +191,7 @@ void MenuGtk::BuildMenuIn(GtkWidget* menu, if (menu_data->submenu) { GtkWidget* submenu = gtk_menu_new(); - BuildMenuIn(submenu, menu_data->submenu, accel_group); + BuildMenuIn(submenu, menu_data->submenu); gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item), submenu); } else if (menu_data->custom_submenu) { gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item), @@ -191,8 +205,7 @@ void MenuGtk::BuildMenuIn(GtkWidget* menu, // keys. gtk_widget_add_accelerator(menu_item, "activate", - menu_data->only_show || !accel_group ? - dummy_accel_group_ : accel_group, + dummy_accel_group_, menu_data->accel_key, GdkModifierType(menu_data->accel_modifiers), GTK_ACCEL_VISIBLE); @@ -227,18 +240,18 @@ GtkWidget* MenuGtk::BuildMenuItemWithImage(const std::string& label, } void MenuGtk::BuildMenuFromModel() { - for (int i = 0; i < model_->GetItemCount(); ++i) { - GtkWidget* menu_item = NULL; - - // TODO(estade): support these commands. - DCHECK_NE(model_->GetTypeAt(i), menus::MenuModel::TYPE_RADIO); - DCHECK_NE(model_->GetTypeAt(i), menus::MenuModel::TYPE_SUBMENU); + BuildSubmenuFromModel(model_, menu_); +} +void MenuGtk::BuildSubmenuFromModel(menus::MenuModel* model, GtkWidget* menu) { + GtkWidget* last_menu_item = NULL; + GtkWidget* menu_item = NULL; + for (int i = 0; i < model->GetItemCount(); ++i) { SkBitmap icon; std::string label = - ConvertAcceleratorsFromWindowsStyle(UTF16ToUTF8(model_->GetLabelAt(i))); + ConvertAcceleratorsFromWindowsStyle(UTF16ToUTF8(model->GetLabelAt(i))); - switch (model_->GetTypeAt(i)) { + switch (model->GetTypeAt(i)) { case menus::MenuModel::TYPE_SEPARATOR: menu_item = gtk_separator_menu_item_new(); break; @@ -247,8 +260,19 @@ void MenuGtk::BuildMenuFromModel() { menu_item = gtk_check_menu_item_new_with_mnemonic(label.c_str()); break; + case menus::MenuModel::TYPE_RADIO: + if (last_menu_item && GTK_IS_RADIO_MENU_ITEM(last_menu_item)) { + menu_item = gtk_radio_menu_item_new_with_mnemonic_from_widget( + GTK_RADIO_MENU_ITEM(last_menu_item), label.c_str()); + } else { + menu_item = gtk_radio_menu_item_new_with_mnemonic( + NULL, label.c_str()); + } + break; + + case menus::MenuModel::TYPE_SUBMENU: case menus::MenuModel::TYPE_COMMAND: - if (model_->GetIconAt(i, &icon)) + if (model->GetIconAt(i, &icon)) menu_item = BuildMenuItemWithImage(label, icon); else menu_item = gtk_menu_item_new_with_mnemonic(label.c_str()); @@ -258,8 +282,14 @@ void MenuGtk::BuildMenuFromModel() { NOTREACHED(); } + if (model->GetTypeAt(i) == menus::MenuModel::TYPE_SUBMENU) { + GtkWidget* submenu = gtk_menu_new(); + BuildSubmenuFromModel(model->GetSubmenuModelAt(i), submenu); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item), submenu); + } + menus::AcceleratorGtk accelerator; - if (model_->GetAcceleratorAt(i, &accelerator)) { + if (model->GetAcceleratorAt(i, &accelerator)) { gtk_widget_add_accelerator(menu_item, "activate", dummy_accel_group_, @@ -268,7 +298,12 @@ void MenuGtk::BuildMenuFromModel() { GTK_ACCEL_VISIBLE); } - AppendMenuItem(i, menu_item); + g_object_set_data(G_OBJECT(menu_item), "model", + reinterpret_cast<void*>(model)); + AppendMenuItemToMenu(i, menu_item, menu); + + last_menu_item = menu_item; + menu_item = NULL; } } @@ -301,9 +336,13 @@ void MenuGtk::OnMenuItemActivated(GtkMenuItem* menuitem, MenuGtk* menu) { "menu-id")); } + menus::MenuModel* model = + reinterpret_cast<menus::MenuModel*>( + g_object_get_data(G_OBJECT(menuitem), "model")); + // The menu item can still be activated by hotkeys even if it is disabled. - if (menu->IsCommandEnabled(id)) - menu->ExecuteCommand(id); + if (menu->IsCommandEnabled(model, id)) + menu->ExecuteCommand(model, id); } // static @@ -375,23 +414,23 @@ void MenuGtk::UpdateMenu() { } // http://crbug.com/31365 -bool MenuGtk::IsCommandEnabled(int id) { - return model_ ? model_->IsEnabledAt(id) : - delegate_->IsCommandEnabled(id); +bool MenuGtk::IsCommandEnabled(menus::MenuModel* model, int id) { + return model ? model->IsEnabledAt(id) : + delegate_->IsCommandEnabled(id); } // http://crbug.com/31365 -void MenuGtk::ExecuteCommand(int id) { - if (model_) - model_->ActivatedAt(id); +void MenuGtk::ExecuteCommand(menus::MenuModel* model, int id) { + if (model) + model->ActivatedAt(id); else - delegate_->ExecuteCommand(id); + delegate_->ExecuteCommandById(id); } // http://crbug.com/31365 -bool MenuGtk::IsItemChecked(int id) { - return model_ ? model_->IsItemCheckedAt(id) : - delegate_->IsItemChecked(id); +bool MenuGtk::IsItemChecked(menus::MenuModel* model, int id) { + return model ? model->IsItemCheckedAt(id) : + delegate_->IsItemChecked(id); } // static @@ -426,6 +465,10 @@ void MenuGtk::SetMenuItemInfo(GtkWidget* widget, gpointer userdata) { "menu-id")); } + menus::MenuModel* model = + reinterpret_cast<menus::MenuModel*>( + g_object_get_data(G_OBJECT(widget), "model")); + if (GTK_IS_CHECK_MENU_ITEM(widget)) { GtkCheckMenuItem* item = GTK_CHECK_MENU_ITEM(widget); @@ -440,12 +483,12 @@ 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->IsItemChecked(id)); + gtk_check_menu_item_set_active(item, menu->IsItemChecked(model, id)); block_activation_ = false; } if (GTK_IS_MENU_ITEM(widget)) { - gtk_widget_set_sensitive(widget, menu->IsCommandEnabled(id)); + gtk_widget_set_sensitive(widget, menu->IsCommandEnabled(model, id)); GtkWidget* submenu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(widget)); if (submenu) { |