summaryrefslogtreecommitdiffstats
path: root/chrome/browser/gtk/menu_gtk.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/gtk/menu_gtk.cc')
-rw-r--r--chrome/browser/gtk/menu_gtk.cc91
1 files changed, 84 insertions, 7 deletions
diff --git a/chrome/browser/gtk/menu_gtk.cc b/chrome/browser/gtk/menu_gtk.cc
index 6c24fd8..104b39f 100644
--- a/chrome/browser/gtk/menu_gtk.cc
+++ b/chrome/browser/gtk/menu_gtk.cc
@@ -8,17 +8,22 @@
#include "app/l10n_util.h"
#include "app/menus/accelerator_gtk.h"
+#include "app/menus/button_menu_item_model.h"
#include "app/menus/menu_model.h"
+#include "app/resource_bundle.h"
#include "base/i18n/rtl.h"
#include "base/logging.h"
#include "base/message_loop.h"
#include "base/stl_util-inl.h"
#include "base/utf_string_conversions.h"
+#include "chrome/browser/gtk/gtk_custom_menu.h"
+#include "chrome/browser/gtk/gtk_custom_menu_item.h"
#include "chrome/browser/gtk/gtk_util.h"
#include "gfx/gtk_util.h"
#include "third_party/skia/include/core/SkBitmap.h"
using gtk_util::ConvertAcceleratorsFromWindowsStyle;
+using gtk_util::RemoveWindowsStyleAccelerators;
bool MenuGtk::block_activation_ = false;
@@ -99,7 +104,7 @@ MenuGtk::MenuGtk(MenuGtk::Delegate* delegate,
: delegate_(delegate),
model_(model),
dummy_accel_group_(gtk_accel_group_new()),
- menu_(gtk_menu_new()),
+ menu_(gtk_custom_menu_new()),
factory_(this) {
DCHECK(model);
g_object_ref_sink(menu_);
@@ -156,15 +161,20 @@ GtkWidget* MenuGtk::AppendSeparator() {
}
GtkWidget* MenuGtk::AppendMenuItem(int command_id, GtkWidget* menu_item) {
- return AppendMenuItemToMenu(command_id, menu_item, menu_);
+ return AppendMenuItemToMenu(command_id, menu_item, menu_, true);
}
GtkWidget* MenuGtk::AppendMenuItemToMenu(int command_id,
GtkWidget* menu_item,
- GtkWidget* menu) {
- SetMenuItemID(menu_item, command_id);
- g_signal_connect(menu_item, "activate",
- G_CALLBACK(OnMenuItemActivated), this);
+ GtkWidget* menu,
+ bool connect_to_activate) {
+ // Native menu items do their own thing, so only selectively listen for the
+ // activate signal.
+ if (connect_to_activate) {
+ SetMenuItemID(menu_item, command_id);
+ g_signal_connect(menu_item, "activate",
+ G_CALLBACK(OnMenuItemActivated), this);
+ }
gtk_widget_show(menu_item);
gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
@@ -231,6 +241,7 @@ void MenuGtk::BuildSubmenuFromModel(menus::MenuModel* model, GtkWidget* menu) {
SkBitmap icon;
std::string label =
ConvertAcceleratorsFromWindowsStyle(UTF16ToUTF8(model->GetLabelAt(i)));
+ bool connect_to_activate = true;
switch (model->GetTypeAt(i)) {
case menus::MenuModel::TYPE_SEPARATOR:
@@ -255,6 +266,15 @@ void MenuGtk::BuildSubmenuFromModel(menus::MenuModel* model, GtkWidget* menu) {
}
break;
}
+ case menus::MenuModel::TYPE_BUTTON_ITEM: {
+ menus::ButtonMenuItemModel* button_menu_item_model =
+ model->GetButtonMenuItemAt(i);
+
+ menu_item = BuildButtomMenuItem(button_menu_item_model);
+
+ connect_to_activate = false;
+ break;
+ }
case menus::MenuModel::TYPE_SUBMENU:
case menus::MenuModel::TYPE_COMMAND:
if (model->GetIconAt(i, &icon))
@@ -285,7 +305,7 @@ void MenuGtk::BuildSubmenuFromModel(menus::MenuModel* model, GtkWidget* menu) {
g_object_set_data(G_OBJECT(menu_item), "model",
reinterpret_cast<void*>(model));
- AppendMenuItemToMenu(i, menu_item, menu);
+ AppendMenuItemToMenu(i, menu_item, menu, connect_to_activate);
if (model->IsLabelDynamicAt(i)) {
g_signal_connect(menu, "show", G_CALLBACK(OnSubmenuShow),
@@ -296,6 +316,50 @@ void MenuGtk::BuildSubmenuFromModel(menus::MenuModel* model, GtkWidget* menu) {
}
}
+GtkWidget* MenuGtk::BuildButtomMenuItem(menus::ButtonMenuItemModel* model) {
+ GtkWidget* menu_item = gtk_custom_menu_item_new(
+ RemoveWindowsStyleAccelerators(UTF16ToUTF8(model->label())).c_str());
+ for (int i = 0; i < model->GetItemCount(); ++i) {
+ switch (model->GetTypeAt(i)) {
+ case menus::ButtonMenuItemModel::TYPE_SPACE: {
+ gtk_custom_menu_item_add_space(GTK_CUSTOM_MENU_ITEM(menu_item));
+ break;
+ }
+ case menus::ButtonMenuItemModel::TYPE_BUTTON: {
+ GtkWidget* button = gtk_custom_menu_item_add_button(
+ GTK_CUSTOM_MENU_ITEM(menu_item),
+ model->GetCommandIdAt(i));
+
+ int icon_idr;
+ if (model->GetIconAt(i, &icon_idr)) {
+ // TODO(erg): This should go through the GtkThemeProvider so we can
+ // get a version tinted to label color.
+ gtk_button_set_image(
+ GTK_BUTTON(button),
+ gtk_image_new_from_pixbuf(
+ ResourceBundle::GetSharedInstance().
+ GetPixbufNamed(icon_idr)));
+ } else {
+ gtk_button_set_label(
+ GTK_BUTTON(button),
+ RemoveWindowsStyleAccelerators(
+ UTF16ToUTF8(model->GetLabelAt(i))).c_str());
+ }
+
+ // TODO(erg): Set up dynamic labels here.
+ break;
+ }
+ }
+ }
+
+ // Set up the callback to the model for when it is clicked.
+ g_object_set_data(G_OBJECT(menu_item), "button-model",
+ reinterpret_cast<void*>(model));
+ g_signal_connect(menu_item, "button-pushed",
+ G_CALLBACK(OnMenuButtonPressed), this);
+ return menu_item;
+}
+
// static
void MenuGtk::OnMenuItemActivated(GtkMenuItem* menuitem, MenuGtk* menu) {
if (block_activation_)
@@ -324,6 +388,19 @@ void MenuGtk::OnMenuItemActivated(GtkMenuItem* menuitem, MenuGtk* menu) {
menu->ExecuteCommand(model, id);
}
+void MenuGtk::OnMenuButtonPressed(GtkMenuItem* menu_item, int command_id,
+ MenuGtk* menu) {
+ menus::ButtonMenuItemModel* model =
+ reinterpret_cast<menus::ButtonMenuItemModel*>(
+ g_object_get_data(G_OBJECT(menu_item), "button-model"));
+ if (model) {
+ if (menu->delegate_)
+ menu->delegate_->CommandWillBeExecuted();
+
+ model->ActivatedCommand(command_id);
+ }
+}
+
// static
void MenuGtk::WidgetMenuPositionFunc(GtkMenu* menu,
int* x,