| Index: chrome/browser/ui/gtk/gtk_custom_menu_item.h
|
| diff --git a/chrome/browser/ui/gtk/gtk_custom_menu_item.h b/chrome/browser/ui/gtk/gtk_custom_menu_item.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..b1a0c6ebd28f6414481347565bf6aa22fd35fe33
|
| --- /dev/null
|
| +++ b/chrome/browser/ui/gtk/gtk_custom_menu_item.h
|
| @@ -0,0 +1,141 @@
|
| +// Copyright (c) 2010 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#ifndef CHROME_BROWSER_UI_GTK_GTK_CUSTOM_MENU_ITEM_H_
|
| +#define CHROME_BROWSER_UI_GTK_GTK_CUSTOM_MENU_ITEM_H_
|
| +#pragma once
|
| +
|
| +// GtkCustomMenuItem is a GtkMenuItem subclass that has buttons in it and acts
|
| +// to support this. GtkCustomMenuItems only render properly when put in a
|
| +// GtkCustomMenu; there's a lot of collaboration between these two classes
|
| +// necessary to work around how gtk normally does menus.
|
| +//
|
| +// We can't rely on the normal event infrastructure. While a menu is up, the
|
| +// GtkMenu has a grab on all events. Instead of trying to pump events through
|
| +// the normal channels, we have the GtkCustomMenu selectively forward mouse
|
| +// motion through a back channel. The GtkCustomMenu only listens for button
|
| +// press information so it can block the effects of the click if the cursor
|
| +// isn't in a button in the menu item.
|
| +//
|
| +// A GtkCustomMenuItem doesn't try to take these signals and forward them to
|
| +// the buttons it owns. The GtkCustomMenu class keeps track of which button is
|
| +// selected (due to key events and mouse movement) and otherwise acts like a
|
| +// normal GtkItem. The buttons are only for sizing and rendering; they don't
|
| +// respond to events. Instead, when the GtkCustomMenuItem is activated by the
|
| +// GtkMenu, it uses which button was selected as a signal of what to do.
|
| +//
|
| +// Users should connect to the "button-pushed" signal to be notified when a
|
| +// button was pushed. We don't go through the normal "activate" signal because
|
| +// we need to communicate additional information, namely which button was
|
| +// activated.
|
| +
|
| +#include <gdk/gdk.h>
|
| +#include <gtk/gtk.h>
|
| +
|
| +G_BEGIN_DECLS
|
| +
|
| +#define GTK_TYPE_CUSTOM_MENU_ITEM \
|
| + (gtk_custom_menu_item_get_type())
|
| +#define GTK_CUSTOM_MENU_ITEM(obj) \
|
| + (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_CUSTOM_MENU_ITEM, \
|
| + GtkCustomMenuItem))
|
| +#define GTK_CUSTOM_MENU_ITEM_CLASS(klass) \
|
| + (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_CUSTOM_MENU_ITEM, \
|
| + GtkCustomMenuItemClass))
|
| +#define GTK_IS_CUSTOM_MENU_ITEM(obj) \
|
| + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_CUSTOM_MENU_ITEM))
|
| +#define GTK_IS_CUSTOM_MENU_ITEM_CLASS(klass) \
|
| + (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_CUSTOM_MENU_ITEM))
|
| +#define GTK_CUSTOM_MENU_ITEM_GET_CLASS(obj) \
|
| + (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_CUSTOM_MENU_ITEM, \
|
| + GtkCustomMenuItemClass))
|
| +
|
| +typedef struct _GtkCustomMenuItem GtkCustomMenuItem;
|
| +typedef struct _GtkCustomMenuItemClass GtkCustomMenuItemClass;
|
| +
|
| +struct _GtkCustomMenuItem {
|
| + GtkMenuItem menu_item;
|
| +
|
| + // Container for button widgets.
|
| + GtkWidget* hbox;
|
| +
|
| + // Label on left side of menu item.
|
| + GtkWidget* label;
|
| +
|
| + // List of all widgets we added. Used to find the leftmost and rightmost
|
| + // continuous buttons.
|
| + GList* all_widgets;
|
| +
|
| + // Possible button widgets. Used for keyboard navigation.
|
| + GList* button_widgets;
|
| +
|
| + // The widget that currently has highlight.
|
| + GtkWidget* currently_selected_button;
|
| +
|
| + // The widget that was selected *before* |currently_selected_button|. Why do
|
| + // we hang on to this? Because the menu system sends us a deselect signal
|
| + // right before activating us. We need to listen to deselect since that's
|
| + // what we receive when the mouse cursor leaves us entirely.
|
| + GtkWidget* previously_selected_button;
|
| +};
|
| +
|
| +struct _GtkCustomMenuItemClass {
|
| + GtkMenuItemClass parent_class;
|
| +};
|
| +
|
| +GType gtk_custom_menu_item_get_type(void) G_GNUC_CONST;
|
| +GtkWidget* gtk_custom_menu_item_new(const char* title);
|
| +
|
| +// Adds a button to our list of items in the |hbox|.
|
| +GtkWidget* gtk_custom_menu_item_add_button(GtkCustomMenuItem* menu_item,
|
| + int command_id);
|
| +
|
| +// Adds a button to our list of items in the |hbox|, but that isn't part of
|
| +// |button_widgets| to prevent it from being activatable.
|
| +GtkWidget* gtk_custom_menu_item_add_button_label(GtkCustomMenuItem* menu_item,
|
| + int command_id);
|
| +
|
| +// Adds a vertical space in the |hbox|.
|
| +void gtk_custom_menu_item_add_space(GtkCustomMenuItem* menu_item);
|
| +
|
| +// Receives a motion event from the GtkCustomMenu that contains us. We can't
|
| +// just subscribe to motion-event or the individual widget enter/leave events
|
| +// because the top level GtkMenu has an event grab.
|
| +void gtk_custom_menu_item_receive_motion_event(GtkCustomMenuItem* menu_item,
|
| + gdouble x, gdouble y);
|
| +
|
| +// Notification that the menu got a cursor key event. Used to move up/down
|
| +// within the menu buttons. Returns TRUE to stop the default signal handler
|
| +// from running.
|
| +gboolean gtk_custom_menu_item_handle_move(GtkCustomMenuItem* menu_item,
|
| + GtkMenuDirectionType direction);
|
| +
|
| +// Because we only get a generic "selected" signal when we've changed, we need
|
| +// to have a way for the GtkCustomMenu to tell us that we were just
|
| +// selected.
|
| +void gtk_custom_menu_item_select_item_by_direction(
|
| + GtkCustomMenuItem* menu_item, GtkMenuDirectionType direction);
|
| +
|
| +// Whether we are currently hovering over a clickable region on the menu
|
| +// item. Used by GtkCustomMenu to determine whether it should discard click
|
| +// events.
|
| +gboolean gtk_custom_menu_item_is_in_clickable_region(
|
| + GtkCustomMenuItem* menu_item);
|
| +
|
| +// If the button is released while the |currently_selected_button| isn't
|
| +// supposed to dismiss the menu, this signals to our listeners that we want to
|
| +// run this command if it doesn't dismiss the menu. Returns TRUE if we acted
|
| +// on this button click (and should prevent the normal GtkMenu machinery from
|
| +// firing an "activate" signal).
|
| +gboolean gtk_custom_menu_item_try_no_dismiss_command(
|
| + GtkCustomMenuItem* menu_item);
|
| +
|
| +// Calls |callback| with every button and button-label in the container.
|
| +void gtk_custom_menu_item_foreach_button(GtkCustomMenuItem* menu_item,
|
| + GtkCallback callback,
|
| + gpointer callback_data);
|
| +
|
| +G_END_DECLS
|
| +
|
| +#endif // CHROME_BROWSER_UI_GTK_GTK_CUSTOM_MENU_ITEM_H_
|
|
|