OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #ifndef CHROME_BROWSER_GTK_GTK_CUSTOM_MENU_ITEM_H_ |
| 6 #define CHROME_BROWSER_GTK_GTK_CUSTOM_MENU_ITEM_H_ |
| 7 |
| 8 // GtkCustomMenuItem is a GtkMenuItem subclass that has buttons in it and acts |
| 9 // to support this. GtkCustomMenuItems only render properly when put in a |
| 10 // GtkCustomMenu; there's a lot of collaboration between these two classes |
| 11 // necessary to work around how gtk normally does menus. |
| 12 // |
| 13 // We can't rely on the normal event infrastructure. While a menu is up, the |
| 14 // GtkMenu has a grab on all events. Instead of trying to pump events through |
| 15 // the normal channels, we have the GtkCustomMenu selectively forward mouse |
| 16 // motion through a back channel. The GtkCustomMenu only listens for button |
| 17 // press information so it can block the effects of the click if the cursor |
| 18 // isn't in a button in the menu item. |
| 19 // |
| 20 // A GtkCustomMenuItem doesn't try to take these signals and forward them to |
| 21 // the buttons it owns. The GtkCustomMenu class keeps track of which button is |
| 22 // selected (due to key events and mouse movement) and otherwise acts like a |
| 23 // normal GtkItem. The buttons are only for sizing and rendering; they don't |
| 24 // respond to events. Instead, when the GtkCustomMenuItem is activated by the |
| 25 // GtkMenu, it uses which button was selected as a signal of what to do. |
| 26 // |
| 27 // Users should connect to the "button-pushed" signal to be notified when a |
| 28 // button was pushed. We don't go through the normal "activate" signal because |
| 29 // we need to communicate additional information, namely which button was |
| 30 // activated. |
| 31 |
| 32 #include <gdk/gdk.h> |
| 33 #include <gtk/gtk.h> |
| 34 |
| 35 G_BEGIN_DECLS |
| 36 |
| 37 #define GTK_TYPE_CUSTOM_MENU_ITEM \ |
| 38 (gtk_custom_menu_item_get_type()) |
| 39 #define GTK_CUSTOM_MENU_ITEM(obj) \ |
| 40 (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_CUSTOM_MENU_ITEM, \ |
| 41 GtkCustomMenuItem)) |
| 42 #define GTK_CUSTOM_MENU_ITEM_CLASS(klass) \ |
| 43 (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_CUSTOM_MENU_ITEM, \ |
| 44 GtkCustomMenuItemClass)) |
| 45 #define GTK_IS_CUSTOM_MENU_ITEM(obj) \ |
| 46 (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_CUSTOM_MENU_ITEM)) |
| 47 #define GTK_IS_CUSTOM_MENU_ITEM_CLASS(klass) \ |
| 48 (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_CUSTOM_MENU_ITEM)) |
| 49 #define GTK_CUSTOM_MENU_ITEM_GET_CLASS(obj) \ |
| 50 (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_CUSTOM_MENU_ITEM, \ |
| 51 GtkCustomMenuItemClass)) |
| 52 |
| 53 typedef struct _GtkCustomMenuItem GtkCustomMenuItem; |
| 54 typedef struct _GtkCustomMenuItemClass GtkCustomMenuItemClass; |
| 55 |
| 56 struct _GtkCustomMenuItem { |
| 57 GtkMenuItem menu_item; |
| 58 |
| 59 // Container for button widgets. |
| 60 GtkWidget* hbox; |
| 61 |
| 62 // Label on left side of menu item. |
| 63 GtkWidget* label; |
| 64 |
| 65 // Possible button widgets |
| 66 GList* button_widgets; |
| 67 |
| 68 // The widget that currently has highlight. |
| 69 GtkWidget* currently_selected_button; |
| 70 |
| 71 // The widget that was selected *before* |currently_selected_button|. Why do |
| 72 // we hang on to this? Because the menu system sends us a deselect signal |
| 73 // right before activating us. We need to listen to deselect since that's |
| 74 // what we receive when the mouse cursor leaves us entirely. |
| 75 GtkWidget* previously_selected_button; |
| 76 }; |
| 77 |
| 78 struct _GtkCustomMenuItemClass { |
| 79 GtkMenuItemClass parent_class; |
| 80 }; |
| 81 |
| 82 GType gtk_custom_menu_item_get_type(void) G_GNUC_CONST; |
| 83 GtkWidget* gtk_custom_menu_item_new(const char* title); |
| 84 |
| 85 // Adds a button to our list of items in the |hbox|. |
| 86 GtkWidget* gtk_custom_menu_item_add_button(GtkCustomMenuItem* menu_item, |
| 87 int command_id); |
| 88 |
| 89 // Adds a vertical space in the |hbox|. |
| 90 void gtk_custom_menu_item_add_space(GtkCustomMenuItem* menu_item); |
| 91 |
| 92 // Receives a motion event from the GtkCustomMenu that contains us. We can't |
| 93 // just subscribe to motion-event or the individual widget enter/leave events |
| 94 // because the top level GtkMenu has an event grab. |
| 95 void gtk_custom_menu_item_receive_motion_event(GtkCustomMenuItem* menu_item, |
| 96 gdouble x, gdouble y); |
| 97 |
| 98 // Notification that the menu got a cursor key event. Used to move up/down |
| 99 // within the menu buttons. Returns TRUE to stop the default signal handler |
| 100 // from running. |
| 101 gboolean gtk_custom_menu_item_handle_move(GtkCustomMenuItem* menu_item, |
| 102 GtkMenuDirectionType direction); |
| 103 |
| 104 // Because we only get a generic "selected" signal when we've changed, we need |
| 105 // to have a way for the GtkCustomMenu to tell us that we were just |
| 106 // selected. |
| 107 void gtk_custom_menu_item_select_item_by_direction( |
| 108 GtkCustomMenuItem* menu_item, GtkMenuDirectionType direction); |
| 109 |
| 110 // Whether we are currently hovering over a clickable region on the menu |
| 111 // item. Used by GtkCustomMenu to determine whether it should discard click |
| 112 // events. |
| 113 gboolean gtk_custom_menu_item_is_in_clickable_region( |
| 114 GtkCustomMenuItem* menu_item); |
| 115 |
| 116 G_END_DECLS |
| 117 |
| 118 #endif // CHROME_BROWSER_GTK_GTK_CUSTOM_MENU_ITEM_H_ |
OLD | NEW |