Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(82)

Side by Side Diff: chrome/browser/ui/gtk/browser_actions_toolbar_gtk.cc

Issue 10959028: Make disabled browser actions on GTK right-clickable and draggable. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: estade's and skia Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/ui/gtk/browser_actions_toolbar_gtk.h" 5 #include "chrome/browser/ui/gtk/browser_actions_toolbar_gtk.h"
6 6
7 #include <gtk/gtk.h> 7 #include <gtk/gtk.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/i18n/rtl.h" 13 #include "base/i18n/rtl.h"
14 #include "base/message_loop.h" 14 #include "base/message_loop.h"
15 #include "base/utf_string_conversions.h" 15 #include "base/utf_string_conversions.h"
16 #include "chrome/browser/extensions/api/commands/command_service.h" 16 #include "chrome/browser/extensions/api/commands/command_service.h"
17 #include "chrome/browser/extensions/api/commands/command_service_factory.h" 17 #include "chrome/browser/extensions/api/commands/command_service_factory.h"
18 #include "chrome/browser/extensions/extension_action_icon_factory.h" 18 #include "chrome/browser/extensions/extension_action_icon_factory.h"
19 #include "chrome/browser/extensions/extension_context_menu_model.h" 19 #include "chrome/browser/extensions/extension_context_menu_model.h"
20 #include "chrome/browser/extensions/extension_service.h" 20 #include "chrome/browser/extensions/extension_service.h"
21 #include "chrome/browser/profiles/profile.h" 21 #include "chrome/browser/profiles/profile.h"
22 #include "chrome/browser/sessions/session_tab_helper.h" 22 #include "chrome/browser/sessions/session_tab_helper.h"
23 #include "chrome/browser/ui/browser.h" 23 #include "chrome/browser/ui/browser.h"
24 #include "chrome/browser/ui/browser_tabstrip.h" 24 #include "chrome/browser/ui/browser_tabstrip.h"
25 #include "chrome/browser/ui/gtk/browser_window_gtk.h" 25 #include "chrome/browser/ui/gtk/browser_window_gtk.h"
26 #include "chrome/browser/ui/gtk/custom_button.h"
26 #include "chrome/browser/ui/gtk/extensions/extension_popup_gtk.h" 27 #include "chrome/browser/ui/gtk/extensions/extension_popup_gtk.h"
27 #include "chrome/browser/ui/gtk/gtk_chrome_button.h" 28 #include "chrome/browser/ui/gtk/gtk_chrome_button.h"
28 #include "chrome/browser/ui/gtk/gtk_chrome_shrinkable_hbox.h" 29 #include "chrome/browser/ui/gtk/gtk_chrome_shrinkable_hbox.h"
29 #include "chrome/browser/ui/gtk/gtk_theme_service.h" 30 #include "chrome/browser/ui/gtk/gtk_theme_service.h"
30 #include "chrome/browser/ui/gtk/gtk_util.h" 31 #include "chrome/browser/ui/gtk/gtk_util.h"
31 #include "chrome/browser/ui/gtk/hover_controller_gtk.h" 32 #include "chrome/browser/ui/gtk/hover_controller_gtk.h"
32 #include "chrome/browser/ui/gtk/menu_gtk.h" 33 #include "chrome/browser/ui/gtk/menu_gtk.h"
33 #include "chrome/browser/ui/gtk/view_id_util.h" 34 #include "chrome/browser/ui/gtk/view_id_util.h"
34 #include "chrome/browser/ui/tab_contents/tab_contents.h" 35 #include "chrome/browser/ui/tab_contents/tab_contents.h"
35 #include "chrome/common/chrome_notification_types.h" 36 #include "chrome/common/chrome_notification_types.h"
36 #include "chrome/common/extensions/extension.h" 37 #include "chrome/common/extensions/extension.h"
37 #include "chrome/common/extensions/extension_action.h" 38 #include "chrome/common/extensions/extension_action.h"
38 #include "chrome/common/extensions/extension_manifest_constants.h" 39 #include "chrome/common/extensions/extension_manifest_constants.h"
39 #include "chrome/common/extensions/extension_resource.h" 40 #include "chrome/common/extensions/extension_resource.h"
40 #include "content/public/browser/notification_details.h" 41 #include "content/public/browser/notification_details.h"
41 #include "content/public/browser/notification_source.h" 42 #include "content/public/browser/notification_source.h"
42 #include "grit/theme_resources.h" 43 #include "grit/theme_resources.h"
43 #include "grit/ui_resources.h" 44 #include "grit/ui_resources.h"
44 #include "ui/base/accelerators/accelerator_gtk.h" 45 #include "ui/base/accelerators/accelerator_gtk.h"
45 #include "ui/base/gtk/gtk_compat.h" 46 #include "ui/base/gtk/gtk_compat.h"
46 #include "ui/base/resource/resource_bundle.h" 47 #include "ui/base/resource/resource_bundle.h"
47 #include "ui/gfx/canvas_skia_paint.h" 48 #include "ui/gfx/canvas_skia_paint.h"
48 #include "ui/gfx/gtk_util.h" 49 #include "ui/gfx/gtk_util.h"
49 #include "ui/gfx/image/image.h" 50 #include "ui/gfx/image/image.h"
51 #include "ui/gfx/image/image_skia_operations.h"
50 52
51 using extensions::Extension; 53 using extensions::Extension;
52 54
53 namespace { 55 namespace {
54 56
55 // The width of the browser action buttons. 57 // The width of the browser action buttons.
56 const int kButtonWidth = 27; 58 const int kButtonWidth = 27;
57 59
58 // The padding between browser action buttons. 60 // The padding between browser action buttons.
59 const int kButtonPadding = 4; 61 const int kButtonPadding = 4;
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 119
118 DCHECK(extension_->browser_action()); 120 DCHECK(extension_->browser_action());
119 121
120 UpdateState(); 122 UpdateState();
121 123
122 signals_.Connect(button(), "button-press-event", 124 signals_.Connect(button(), "button-press-event",
123 G_CALLBACK(OnButtonPress), this); 125 G_CALLBACK(OnButtonPress), this);
124 signals_.Connect(button(), "clicked", 126 signals_.Connect(button(), "clicked",
125 G_CALLBACK(OnClicked), this); 127 G_CALLBACK(OnClicked), this);
126 signals_.Connect(button(), "drag-begin", 128 signals_.Connect(button(), "drag-begin",
127 G_CALLBACK(&OnDragBegin), this); 129 G_CALLBACK(OnDragBegin), this);
128 signals_.ConnectAfter(widget(), "expose-event", 130 signals_.ConnectAfter(widget(), "expose-event",
129 G_CALLBACK(OnExposeEvent), this); 131 G_CALLBACK(OnExposeEvent), this);
130 if (toolbar_->browser()->window()) { 132 if (toolbar_->browser()->window()) {
131 // If the window exists already, then the browser action button has been 133 // If the window exists already, then the browser action button has been
132 // recreated after the window was created, for example when the extension 134 // recreated after the window was created, for example when the extension
133 // is reloaded. 135 // is reloaded.
134 ConnectBrowserActionPopupAccelerator(); 136 ConnectBrowserActionPopupAccelerator();
135 } else { 137 } else {
136 // Window doesn't exist yet, wait for it. 138 // Window doesn't exist yet, wait for it.
137 signals_.Connect(toolbar->widget(), "realize", 139 signals_.Connect(toolbar->widget(), "realize",
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 int tab_id = toolbar_->GetCurrentTabId(); 213 int tab_id = toolbar_->GetCurrentTabId();
212 if (tab_id < 0) 214 if (tab_id < 0)
213 return; 215 return;
214 216
215 std::string tooltip = extension_->browser_action()->GetTitle(tab_id); 217 std::string tooltip = extension_->browser_action()->GetTitle(tab_id);
216 if (tooltip.empty()) 218 if (tooltip.empty())
217 gtk_widget_set_has_tooltip(button(), FALSE); 219 gtk_widget_set_has_tooltip(button(), FALSE);
218 else 220 else
219 gtk_widget_set_tooltip_text(button(), tooltip.c_str()); 221 gtk_widget_set_tooltip_text(button(), tooltip.c_str());
220 222
223 enabled_ = extension_->browser_action()->GetIsVisible(tab_id);
224 if (!enabled_)
225 button_->SetPaintOverride(GTK_STATE_INSENSITIVE);
226 else
227 button_->UnsetPaintOverride();
228
221 gfx::Image image = icon_factory_.GetIcon(tab_id); 229 gfx::Image image = icon_factory_.GetIcon(tab_id);
222 if (!image.IsEmpty()) 230 if (!image.IsEmpty()) {
223 SetImage(image.ToGdkPixbuf()); 231 if (enabled_) {
224 bool enabled = extension_->browser_action()->GetIsVisible(tab_id); 232 SetImage(image);
225 gtk_widget_set_sensitive(button(), enabled); 233 } else {
234 SetImage(gfx::Image(gfx::ImageSkiaOperations::CreateTransparentImage(
235 image.AsImageSkia(), .25)));
236 }
237 }
226 238
227 gtk_widget_queue_draw(button()); 239 gtk_widget_queue_draw(button());
228 } 240 }
229 241
230 gfx::Image GetIcon() { 242 gfx::Image GetIcon() {
231 return icon_factory_.GetIcon(toolbar_->GetCurrentTabId()); 243 return icon_factory_.GetIcon(toolbar_->GetCurrentTabId());
232 } 244 }
233 245
234 MenuGtk* GetContextMenu() { 246 MenuGtk* GetContextMenu() {
235 if (!extension_->ShowConfigureContextMenus()) 247 if (!extension_->ShowConfigureContextMenus())
(...skipping 19 matching lines...) Expand all
255 break; 267 break;
256 case ExtensionToolbarModel::ACTION_SHOW_POPUP: 268 case ExtensionToolbarModel::ACTION_SHOW_POPUP:
257 ExtensionPopupGtk::Show(popup_url, browser, widget, 269 ExtensionPopupGtk::Show(popup_url, browser, widget,
258 ExtensionPopupGtk::SHOW); 270 ExtensionPopupGtk::SHOW);
259 break; 271 break;
260 } 272 }
261 } 273 }
262 274
263 // MenuGtk::Delegate implementation. 275 // MenuGtk::Delegate implementation.
264 virtual void StoppedShowing() { 276 virtual void StoppedShowing() {
265 button_->UnsetPaintOverride(); 277 if (enabled_)
278 button_->UnsetPaintOverride();
279 else
280 button_->SetPaintOverride(GTK_STATE_INSENSITIVE);
266 281
267 // If the context menu was showing for the overflow menu, re-assert the 282 // If the context menu was showing for the overflow menu, re-assert the
268 // grab that was shadowed. 283 // grab that was shadowed.
269 if (toolbar_->overflow_menu_.get()) 284 if (toolbar_->overflow_menu_.get())
270 gtk_util::GrabAllInput(toolbar_->overflow_menu_->widget()); 285 gtk_util::GrabAllInput(toolbar_->overflow_menu_->widget());
271 } 286 }
272 287
273 virtual void CommandWillBeExecuted() { 288 virtual void CommandWillBeExecuted() {
274 // If the context menu was showing for the overflow menu, and a command 289 // If the context menu was showing for the overflow menu, and a command
275 // is executed, then stop showing the overflow menu. 290 // is executed, then stop showing the overflow menu.
276 if (toolbar_->overflow_menu_.get()) 291 if (toolbar_->overflow_menu_.get())
277 toolbar_->overflow_menu_->Cancel(); 292 toolbar_->overflow_menu_->Cancel();
278 } 293 }
279 294
280 // ExtensionContextMenuModel::PopupDelegate implementation. 295 // ExtensionContextMenuModel::PopupDelegate implementation.
281 virtual void InspectPopup(ExtensionAction* action) { 296 virtual void InspectPopup(ExtensionAction* action) {
282 GURL popup_url = action->GetPopupUrl(toolbar_->GetCurrentTabId()); 297 GURL popup_url = action->GetPopupUrl(toolbar_->GetCurrentTabId());
283 ExtensionPopupGtk::Show(popup_url, toolbar_->browser(), widget(), 298 ExtensionPopupGtk::Show(popup_url, toolbar_->browser(), widget(),
284 ExtensionPopupGtk::SHOW_AND_INSPECT); 299 ExtensionPopupGtk::SHOW_AND_INSPECT);
285 } 300 }
286 301
287 void SetImage(GdkPixbuf* image) { 302 void SetImage(const gfx::Image& image) {
288 if (!image_) { 303 if (!image_) {
289 image_ = gtk_image_new_from_pixbuf(image); 304 image_ = gtk_image_new_from_pixbuf(image.ToGdkPixbuf());
290 gtk_button_set_image(GTK_BUTTON(button()), image_); 305 gtk_button_set_image(GTK_BUTTON(button()), image_);
291 } else { 306 } else {
292 gtk_image_set_from_pixbuf(GTK_IMAGE(image_), image); 307 gtk_image_set_from_pixbuf(GTK_IMAGE(image_), image.ToGdkPixbuf());
293 } 308 }
294 } 309 }
295 310
296 static gboolean OnButtonPress(GtkWidget* widget, 311 static gboolean OnButtonPress(GtkWidget* widget,
297 GdkEventButton* event, 312 GdkEventButton* event,
298 BrowserActionButton* action) { 313 BrowserActionButton* button) {
299 if (event->button != 3) 314 if (event->button != 3)
300 return FALSE; 315 return FALSE;
301 316
302 MenuGtk* menu = action->GetContextMenu(); 317 MenuGtk* menu = button->GetContextMenu();
303 if (!menu) 318 if (!menu)
304 return FALSE; 319 return FALSE;
305 320
306 action->button_->SetPaintOverride(GTK_STATE_ACTIVE); 321 button->button_->SetPaintOverride(GTK_STATE_ACTIVE);
307 menu->PopupForWidget(widget, event->button, event->time); 322 menu->PopupForWidget(widget, event->button, event->time);
308 323
309 return TRUE; 324 return TRUE;
310 } 325 }
311 326
312 static void OnClicked(GtkWidget* widget, BrowserActionButton* action) { 327 static void OnClicked(GtkWidget* widget, BrowserActionButton* button) {
313 action->Activate(widget); 328 if (button->enabled_)
329 button->Activate(widget);
314 } 330 }
315 331
316 static gboolean OnExposeEvent(GtkWidget* widget, 332 static gboolean OnExposeEvent(GtkWidget* widget,
317 GdkEventExpose* event, 333 GdkEventExpose* event,
318 BrowserActionButton* button) { 334 BrowserActionButton* button) {
319 int tab_id = button->toolbar_->GetCurrentTabId(); 335 int tab_id = button->toolbar_->GetCurrentTabId();
320 if (tab_id < 0) 336 if (tab_id < 0)
321 return FALSE; 337 return FALSE;
322 338
323 ExtensionAction* action = button->extension_->browser_action(); 339 ExtensionAction* action = button->extension_->browser_action();
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 439
424 // The toolbar containing this button. 440 // The toolbar containing this button.
425 BrowserActionsToolbarGtk* toolbar_; 441 BrowserActionsToolbarGtk* toolbar_;
426 442
427 // The extension that contains this browser action. 443 // The extension that contains this browser action.
428 const Extension* extension_; 444 const Extension* extension_;
429 445
430 // The button for this browser action. 446 // The button for this browser action.
431 scoped_ptr<CustomDrawButton> button_; 447 scoped_ptr<CustomDrawButton> button_;
432 448
449 // Whether the browser action is enabled (equivalent to whether a page action
450 // is visible).
451 bool enabled_;
452
433 // The top level widget (parent of |button_|). 453 // The top level widget (parent of |button_|).
434 ui::OwnedWidgetGtk alignment_; 454 ui::OwnedWidgetGtk alignment_;
435 455
436 // The one image subwidget in |button_|. We keep this out so we don't alter 456 // The one image subwidget in |button_|. We keep this out so we don't alter
437 // the widget hierarchy while changing the button image because changing the 457 // the widget hierarchy while changing the button image because changing the
438 // GTK widget hierarchy invalidates all tooltips and several popular 458 // GTK widget hierarchy invalidates all tooltips and several popular
439 // extensions change browser action icon in a loop. 459 // extensions change browser action icon in a loop.
440 GtkWidget* image_; 460 GtkWidget* image_;
441 461
442 // The object that will be used to get the browser action icon for us. 462 // The object that will be used to get the browser action icon for us.
(...skipping 625 matching lines...) Expand 10 before | Expand all | Expand 10 after
1068 1088
1069 menu->PopupAsContext(gfx::Point(event->x_root, event->y_root), 1089 menu->PopupAsContext(gfx::Point(event->x_root, event->y_root),
1070 event->time); 1090 event->time);
1071 return TRUE; 1091 return TRUE;
1072 } 1092 }
1073 1093
1074 void BrowserActionsToolbarGtk::OnButtonShowOrHide(GtkWidget* sender) { 1094 void BrowserActionsToolbarGtk::OnButtonShowOrHide(GtkWidget* sender) {
1075 if (!resize_animation_.is_animating()) 1095 if (!resize_animation_.is_animating())
1076 UpdateChevronVisibility(); 1096 UpdateChevronVisibility();
1077 } 1097 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698