| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011 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_UI_GTK_GTK_CUSTOM_MENU_ITEM_H_ | |
| 6 #define CHROME_BROWSER_UI_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 <gtk/gtk.h> | |
| 33 | |
| 34 G_BEGIN_DECLS | |
| 35 | |
| 36 #define GTK_TYPE_CUSTOM_MENU_ITEM \ | |
| 37 (gtk_custom_menu_item_get_type()) | |
| 38 #define GTK_CUSTOM_MENU_ITEM(obj) \ | |
| 39 (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_CUSTOM_MENU_ITEM, \ | |
| 40 GtkCustomMenuItem)) | |
| 41 #define GTK_CUSTOM_MENU_ITEM_CLASS(klass) \ | |
| 42 (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_CUSTOM_MENU_ITEM, \ | |
| 43 GtkCustomMenuItemClass)) | |
| 44 #define GTK_IS_CUSTOM_MENU_ITEM(obj) \ | |
| 45 (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_CUSTOM_MENU_ITEM)) | |
| 46 #define GTK_IS_CUSTOM_MENU_ITEM_CLASS(klass) \ | |
| 47 (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_CUSTOM_MENU_ITEM)) | |
| 48 #define GTK_CUSTOM_MENU_ITEM_GET_CLASS(obj) \ | |
| 49 (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_CUSTOM_MENU_ITEM, \ | |
| 50 GtkCustomMenuItemClass)) | |
| 51 | |
| 52 typedef struct _GtkCustomMenuItem GtkCustomMenuItem; | |
| 53 typedef struct _GtkCustomMenuItemClass GtkCustomMenuItemClass; | |
| 54 | |
| 55 struct _GtkCustomMenuItem { | |
| 56 GtkMenuItem menu_item; | |
| 57 | |
| 58 // Container for button widgets. | |
| 59 GtkWidget* hbox; | |
| 60 | |
| 61 // Label on left side of menu item. | |
| 62 GtkWidget* label; | |
| 63 | |
| 64 // List of all widgets we added. Used to find the leftmost and rightmost | |
| 65 // continuous buttons. | |
| 66 GList* all_widgets; | |
| 67 | |
| 68 // Possible button widgets. Used for keyboard navigation. | |
| 69 GList* button_widgets; | |
| 70 | |
| 71 // The widget that currently has highlight. | |
| 72 GtkWidget* currently_selected_button; | |
| 73 | |
| 74 // The widget that was selected *before* |currently_selected_button|. Why do | |
| 75 // we hang on to this? Because the menu system sends us a deselect signal | |
| 76 // right before activating us. We need to listen to deselect since that's | |
| 77 // what we receive when the mouse cursor leaves us entirely. | |
| 78 GtkWidget* previously_selected_button; | |
| 79 }; | |
| 80 | |
| 81 struct _GtkCustomMenuItemClass { | |
| 82 GtkMenuItemClass parent_class; | |
| 83 }; | |
| 84 | |
| 85 GType gtk_custom_menu_item_get_type(void) G_GNUC_CONST; | |
| 86 GtkWidget* gtk_custom_menu_item_new(const char* title); | |
| 87 | |
| 88 // Adds a button to our list of items in the |hbox|. | |
| 89 GtkWidget* gtk_custom_menu_item_add_button(GtkCustomMenuItem* menu_item, | |
| 90 int command_id); | |
| 91 | |
| 92 // Adds a button to our list of items in the |hbox|, but that isn't part of | |
| 93 // |button_widgets| to prevent it from being activatable. | |
| 94 GtkWidget* gtk_custom_menu_item_add_button_label(GtkCustomMenuItem* menu_item, | |
| 95 int command_id); | |
| 96 | |
| 97 // Adds a vertical space in the |hbox|. | |
| 98 void gtk_custom_menu_item_add_space(GtkCustomMenuItem* menu_item); | |
| 99 | |
| 100 // Receives a motion event from the GtkCustomMenu that contains us. We can't | |
| 101 // just subscribe to motion-event or the individual widget enter/leave events | |
| 102 // because the top level GtkMenu has an event grab. | |
| 103 void gtk_custom_menu_item_receive_motion_event(GtkCustomMenuItem* menu_item, | |
| 104 gdouble x, gdouble y); | |
| 105 | |
| 106 // Notification that the menu got a cursor key event. Used to move up/down | |
| 107 // within the menu buttons. Returns TRUE to stop the default signal handler | |
| 108 // from running. | |
| 109 gboolean gtk_custom_menu_item_handle_move(GtkCustomMenuItem* menu_item, | |
| 110 GtkMenuDirectionType direction); | |
| 111 | |
| 112 // Because we only get a generic "selected" signal when we've changed, we need | |
| 113 // to have a way for the GtkCustomMenu to tell us that we were just | |
| 114 // selected. | |
| 115 void gtk_custom_menu_item_select_item_by_direction( | |
| 116 GtkCustomMenuItem* menu_item, GtkMenuDirectionType direction); | |
| 117 | |
| 118 // Whether we are currently hovering over a clickable region on the menu | |
| 119 // item. Used by GtkCustomMenu to determine whether it should discard click | |
| 120 // events. | |
| 121 gboolean gtk_custom_menu_item_is_in_clickable_region( | |
| 122 GtkCustomMenuItem* menu_item); | |
| 123 | |
| 124 // If the button is released while the |currently_selected_button| isn't | |
| 125 // supposed to dismiss the menu, this signals to our listeners that we want to | |
| 126 // run this command if it doesn't dismiss the menu. Returns TRUE if we acted | |
| 127 // on this button click (and should prevent the normal GtkMenu machinery from | |
| 128 // firing an "activate" signal). | |
| 129 gboolean gtk_custom_menu_item_try_no_dismiss_command( | |
| 130 GtkCustomMenuItem* menu_item); | |
| 131 | |
| 132 // Calls |callback| with every button and button-label in the container. | |
| 133 void gtk_custom_menu_item_foreach_button(GtkCustomMenuItem* menu_item, | |
| 134 GtkCallback callback, | |
| 135 gpointer callback_data); | |
| 136 | |
| 137 G_END_DECLS | |
| 138 | |
| 139 #endif // CHROME_BROWSER_UI_GTK_GTK_CUSTOM_MENU_ITEM_H_ | |
| OLD | NEW |