| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/gtk/menu_gtk.h" | 5 #include "chrome/browser/gtk/menu_gtk.h" |
| 6 | 6 |
| 7 #include "app/l10n_util.h" | 7 #include "app/l10n_util.h" |
| 8 #include "base/gfx/gtk_util.h" | 8 #include "base/gfx/gtk_util.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/message_loop.h" |
| 10 #include "base/stl_util-inl.h" | 11 #include "base/stl_util-inl.h" |
| 11 #include "base/string_util.h" | 12 #include "base/string_util.h" |
| 12 #include "chrome/browser/gtk/standard_menus.h" | 13 #include "chrome/browser/gtk/standard_menus.h" |
| 13 #include "chrome/common/gtk_util.h" | 14 #include "chrome/common/gtk_util.h" |
| 14 #include "third_party/skia/include/core/SkBitmap.h" | 15 #include "third_party/skia/include/core/SkBitmap.h" |
| 15 | 16 |
| 16 using gtk_util::ConvertAcceleratorsFromWindowsStyle; | 17 using gtk_util::ConvertAcceleratorsFromWindowsStyle; |
| 17 | 18 |
| 18 bool MenuGtk::block_activation_ = false; | 19 bool MenuGtk::block_activation_ = false; |
| 19 | 20 |
| 20 MenuGtk::MenuGtk(MenuGtk::Delegate* delegate, | 21 MenuGtk::MenuGtk(MenuGtk::Delegate* delegate, |
| 21 const MenuCreateMaterial* menu_data, | 22 const MenuCreateMaterial* menu_data, |
| 22 GtkAccelGroup* accel_group) | 23 GtkAccelGroup* accel_group) |
| 23 : delegate_(delegate), | 24 : delegate_(delegate), |
| 24 dummy_accel_group_(gtk_accel_group_new()), | 25 dummy_accel_group_(gtk_accel_group_new()), |
| 25 menu_(gtk_menu_new()) { | 26 menu_(gtk_menu_new()), |
| 27 factory_(this) { |
| 26 ConnectSignalHandlers(); | 28 ConnectSignalHandlers(); |
| 27 BuildMenuIn(menu_.get(), menu_data, accel_group); | 29 BuildMenuIn(menu_.get(), menu_data, accel_group); |
| 28 } | 30 } |
| 29 | 31 |
| 30 MenuGtk::MenuGtk(MenuGtk::Delegate* delegate, bool load) | 32 MenuGtk::MenuGtk(MenuGtk::Delegate* delegate, bool load) |
| 31 : delegate_(delegate), | 33 : delegate_(delegate), |
| 32 dummy_accel_group_(NULL), | 34 dummy_accel_group_(NULL), |
| 33 menu_(gtk_menu_new()) { | 35 menu_(gtk_menu_new()), |
| 36 factory_(this) { |
| 34 ConnectSignalHandlers(); | 37 ConnectSignalHandlers(); |
| 35 if (load) | 38 if (load) |
| 36 BuildMenuFromDelegate(); | 39 BuildMenuFromDelegate(); |
| 37 } | 40 } |
| 38 | 41 |
| 39 MenuGtk::~MenuGtk() { | 42 MenuGtk::~MenuGtk() { |
| 40 menu_.Destroy(); | 43 menu_.Destroy(); |
| 41 if (dummy_accel_group_) | 44 if (dummy_accel_group_) |
| 42 g_object_unref(dummy_accel_group_); | 45 g_object_unref(dummy_accel_group_); |
| 43 } | 46 } |
| 44 | 47 |
| 45 void MenuGtk::ConnectSignalHandlers() { | 48 void MenuGtk::ConnectSignalHandlers() { |
| 49 // We connect afterwards because OnMenuShow calls SetMenuItemInfo, which may |
| 50 // take a long time or even start a nested message loop. |
| 46 g_signal_connect(menu_.get(), "show", G_CALLBACK(OnMenuShow), this); | 51 g_signal_connect(menu_.get(), "show", G_CALLBACK(OnMenuShow), this); |
| 47 g_signal_connect(menu_.get(), "hide", G_CALLBACK(OnMenuHidden), this); | 52 g_signal_connect(menu_.get(), "hide", G_CALLBACK(OnMenuHidden), this); |
| 48 } | 53 } |
| 49 | 54 |
| 50 void MenuGtk::AppendMenuItemWithLabel(int command_id, | 55 void MenuGtk::AppendMenuItemWithLabel(int command_id, |
| 51 const std::string& label) { | 56 const std::string& label) { |
| 52 std::string converted_label = ConvertAcceleratorsFromWindowsStyle(label); | 57 std::string converted_label = ConvertAcceleratorsFromWindowsStyle(label); |
| 53 GtkWidget* menu_item = | 58 GtkWidget* menu_item = |
| 54 gtk_menu_item_new_with_mnemonic(converted_label.c_str()); | 59 gtk_menu_item_new_with_mnemonic(converted_label.c_str()); |
| 55 AppendMenuItem(command_id, menu_item); | 60 AppendMenuItem(command_id, menu_item); |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 286 | 291 |
| 287 if (!start_align) | 292 if (!start_align) |
| 288 *x += widget->allocation.width - menu_req.width; | 293 *x += widget->allocation.width - menu_req.width; |
| 289 | 294 |
| 290 if (*y + menu_req.height >= screen_rect.height) | 295 if (*y + menu_req.height >= screen_rect.height) |
| 291 *y -= menu_req.height; | 296 *y -= menu_req.height; |
| 292 | 297 |
| 293 *push_in = FALSE; | 298 *push_in = FALSE; |
| 294 } | 299 } |
| 295 | 300 |
| 301 void MenuGtk::UpdateMenu() { |
| 302 gtk_container_foreach(GTK_CONTAINER(menu_.get()), SetMenuItemInfo, this); |
| 303 } |
| 304 |
| 296 // static | 305 // static |
| 297 void MenuGtk::OnMenuShow(GtkWidget* widget, MenuGtk* menu) { | 306 void MenuGtk::OnMenuShow(GtkWidget* widget, MenuGtk* menu) { |
| 298 gtk_container_foreach(GTK_CONTAINER(menu->menu_.get()), | 307 MessageLoop::current()->PostTask(FROM_HERE, |
| 299 SetMenuItemInfo, menu); | 308 menu->factory_.NewRunnableMethod(&MenuGtk::UpdateMenu)); |
| 300 } | 309 } |
| 301 | 310 |
| 302 // static | 311 // static |
| 303 void MenuGtk::OnMenuHidden(GtkWidget* widget, MenuGtk* menu) { | 312 void MenuGtk::OnMenuHidden(GtkWidget* widget, MenuGtk* menu) { |
| 304 menu->delegate_->StoppedShowing(); | 313 menu->delegate_->StoppedShowing(); |
| 305 } | 314 } |
| 306 | 315 |
| 307 // static | 316 // static |
| 308 void MenuGtk::SetMenuItemInfo(GtkWidget* widget, gpointer userdata) { | 317 void MenuGtk::SetMenuItemInfo(GtkWidget* widget, gpointer userdata) { |
| 309 if (GTK_IS_SEPARATOR_MENU_ITEM(widget)) { | 318 if (GTK_IS_SEPARATOR_MENU_ITEM(widget)) { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 346 gtk_widget_set_sensitive( | 355 gtk_widget_set_sensitive( |
| 347 widget, menu->delegate_->IsCommandEnabled(id)); | 356 widget, menu->delegate_->IsCommandEnabled(id)); |
| 348 | 357 |
| 349 GtkWidget* submenu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(widget)); | 358 GtkWidget* submenu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(widget)); |
| 350 if (submenu) { | 359 if (submenu) { |
| 351 gtk_container_foreach(GTK_CONTAINER(submenu), &SetMenuItemInfo, | 360 gtk_container_foreach(GTK_CONTAINER(submenu), &SetMenuItemInfo, |
| 352 userdata); | 361 userdata); |
| 353 } | 362 } |
| 354 } | 363 } |
| 355 } | 364 } |
| OLD | NEW |