gimp r26684 - in trunk: . app/widgets
- From: mitch svn gnome org
- To: svn-commits-list gnome org
- Subject: gimp r26684 - in trunk: . app/widgets
- Date: Wed, 20 Aug 2008 18:20:42 +0000 (UTC)
Author: mitch
Date: Wed Aug 20 18:20:42 2008
New Revision: 26684
URL: http://svn.gnome.org/viewvc/gimp?rev=26684&view=rev
Log:
2008-08-20 Michael Natterer <mitch gimp org>
* app/widgets/gimpuimanager.c: reindent prototypes.
Steal find_widget_under_pointer() from gtktooltip.c
(gimp_ui_manager_item_key_press): use the function to invoke help
for the widget under the pointer if there is no selected menu
item. Makes F1 work on insensitive menu items.
Modified:
trunk/ChangeLog
trunk/app/widgets/gimpuimanager.c
Modified: trunk/app/widgets/gimpuimanager.c
==============================================================================
--- trunk/app/widgets/gimpuimanager.c (original)
+++ trunk/app/widgets/gimpuimanager.c Wed Aug 20 18:20:42 2008
@@ -58,58 +58,60 @@
};
-static GObject * gimp_ui_manager_constructor (GType type,
- guint n_params,
- GObjectConstructParam *params);
-static void gimp_ui_manager_dispose (GObject *object);
-static void gimp_ui_manager_finalize (GObject *object);
-static void gimp_ui_manager_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec);
-static void gimp_ui_manager_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec);
-static void gimp_ui_manager_connect_proxy (GtkUIManager *manager,
- GtkAction *action,
- GtkWidget *proxy);
-static GtkWidget * gimp_ui_manager_get_widget (GtkUIManager *manager,
- const gchar *path);
-static GtkAction * gimp_ui_manager_get_action (GtkUIManager *manager,
- const gchar *path);
-static void gimp_ui_manager_real_update (GimpUIManager *manager,
- gpointer update_data);
+static GObject * gimp_ui_manager_constructor (GType type,
+ guint n_params,
+ GObjectConstructParam *params);
+static void gimp_ui_manager_dispose (GObject *object);
+static void gimp_ui_manager_finalize (GObject *object);
+static void gimp_ui_manager_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gimp_ui_manager_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void gimp_ui_manager_connect_proxy (GtkUIManager *manager,
+ GtkAction *action,
+ GtkWidget *proxy);
+static GtkWidget *gimp_ui_manager_get_widget (GtkUIManager *manager,
+ const gchar *path);
+static GtkAction *gimp_ui_manager_get_action (GtkUIManager *manager,
+ const gchar *path);
+static void gimp_ui_manager_real_update (GimpUIManager *manager,
+ gpointer update_data);
static GimpUIManagerUIEntry *
- gimp_ui_manager_entry_get (GimpUIManager *manager,
- const gchar *ui_path);
-static gboolean gimp_ui_manager_entry_load (GimpUIManager *manager,
- GimpUIManagerUIEntry *entry,
- GError **error);
+ gimp_ui_manager_entry_get (GimpUIManager *manager,
+ const gchar *ui_path);
+static gboolean gimp_ui_manager_entry_load (GimpUIManager *manager,
+ GimpUIManagerUIEntry *entry,
+ GError **error);
static GimpUIManagerUIEntry *
- gimp_ui_manager_entry_ensure (GimpUIManager *manager,
- const gchar *path);
-static void gimp_ui_manager_menu_position (GtkMenu *menu,
- gint *x,
- gint *y,
- gpointer data);
-static void gimp_ui_manager_menu_pos (GtkMenu *menu,
- gint *x,
- gint *y,
- gboolean *push_in,
- gpointer data);
-static void
- gimp_ui_manager_delete_popdown_data (GtkObject *object,
- GimpUIManager *manager);
-static void gimp_ui_manager_item_realize (GtkWidget *widget,
- GimpUIManager *manager);
-static void gimp_ui_manager_menu_item_select (GtkWidget *widget,
- GimpUIManager *manager);
-static void gimp_ui_manager_menu_item_deselect (GtkWidget *widget,
- GimpUIManager *manager);
-static gboolean gimp_ui_manager_item_key_press (GtkWidget *widget,
- GdkEventKey *kevent,
- GimpUIManager *manager);
+ gimp_ui_manager_entry_ensure (GimpUIManager *manager,
+ const gchar *path);
+static void gimp_ui_manager_menu_position (GtkMenu *menu,
+ gint *x,
+ gint *y,
+ gpointer data);
+static void gimp_ui_manager_menu_pos (GtkMenu *menu,
+ gint *x,
+ gint *y,
+ gboolean *push_in,
+ gpointer data);
+static void gimp_ui_manager_delete_popdown_data (GtkObject *object,
+ GimpUIManager *manager);
+static void gimp_ui_manager_item_realize (GtkWidget *widget,
+ GimpUIManager *manager);
+static void gimp_ui_manager_menu_item_select (GtkWidget *widget,
+ GimpUIManager *manager);
+static void gimp_ui_manager_menu_item_deselect (GtkWidget *widget,
+ GimpUIManager *manager);
+static gboolean gimp_ui_manager_item_key_press (GtkWidget *widget,
+ GdkEventKey *kevent,
+ GimpUIManager *manager);
+static GtkWidget *find_widget_under_pointer (GdkWindow *window,
+ gint *x,
+ gint *y);
G_DEFINE_TYPE (GimpUIManager, gimp_ui_manager, GTK_TYPE_UI_MANAGER)
@@ -942,6 +944,24 @@
{
GtkWidget *menu_item = GTK_MENU_SHELL (widget)->active_menu_item;
+ if (! menu_item)
+ {
+ GdkWindow *window = GTK_MENU (widget)->toplevel->window;
+ gint x, y;
+
+ gdk_window_get_pointer (window, &x, &y, NULL);
+ menu_item = find_widget_under_pointer (window, &x, &y);
+
+ if (menu_item && ! GTK_IS_MENU_ITEM (menu_item))
+ {
+ menu_item = gtk_widget_get_ancestor (menu_item,
+ GTK_TYPE_MENU_ITEM);
+
+ if (! GTK_IS_MENU_ITEM (menu_item))
+ menu_item = NULL;
+ }
+ }
+
/* first, get the help page from the item...
*/
if (menu_item)
@@ -1031,3 +1051,202 @@
return TRUE;
}
+
+
+/* Stuff below taken from gtktooltip.c
+ */
+
+#ifdef __GNUC__
+#warning FIXME: remove this crack as soon as a GTK+ widget_under_pointer() is available
+#endif
+
+struct ChildLocation
+{
+ GtkWidget *child;
+ GtkWidget *container;
+
+ gint x;
+ gint y;
+};
+
+static void
+child_location_foreach (GtkWidget *child,
+ gpointer data)
+{
+ gint x, y;
+ struct ChildLocation *child_loc = data;
+
+ /* Ignore invisible widgets */
+ if (!GTK_WIDGET_DRAWABLE (child))
+ return;
+
+ /* (child_loc->x, child_loc->y) are relative to
+ * child_loc->container's allocation.
+ */
+
+ if (!child_loc->child &&
+ gtk_widget_translate_coordinates (child_loc->container, child,
+ child_loc->x, child_loc->y,
+ &x, &y))
+ {
+#ifdef DEBUG_TOOLTIP
+ g_print ("candidate: %s alloc=[(%d,%d) %dx%d] (%d, %d)->(%d, %d)\n",
+ gtk_widget_get_name (child),
+ child->allocation.x,
+ child->allocation.y,
+ child->allocation.width,
+ child->allocation.height,
+ child_loc->x, child_loc->y,
+ x, y);
+#endif /* DEBUG_TOOLTIP */
+
+ /* (x, y) relative to child's allocation. */
+ if (x >= 0 && x < child->allocation.width
+ && y >= 0 && y < child->allocation.height)
+ {
+ if (GTK_IS_CONTAINER (child))
+ {
+ struct ChildLocation tmp = { NULL, NULL, 0, 0 };
+
+ /* Take (x, y) relative the child's allocation and
+ * recurse.
+ */
+ tmp.x = x;
+ tmp.y = y;
+ tmp.container = child;
+
+ gtk_container_forall (GTK_CONTAINER (child),
+ child_location_foreach, &tmp);
+
+ if (tmp.child)
+ child_loc->child = tmp.child;
+ else
+ child_loc->child = child;
+ }
+ else
+ child_loc->child = child;
+ }
+ }
+}
+
+/* Translates coordinates from dest_widget->window relative (src_x, src_y),
+ * to allocation relative (dest_x, dest_y) of dest_widget.
+ */
+static void
+window_to_alloc (GtkWidget *dest_widget,
+ gint src_x,
+ gint src_y,
+ gint *dest_x,
+ gint *dest_y)
+{
+ /* Translate from window relative to allocation relative */
+ if (!GTK_WIDGET_NO_WINDOW (dest_widget) && dest_widget->parent)
+ {
+ gint wx, wy;
+ gdk_window_get_position (dest_widget->window, &wx, &wy);
+
+ /* Offset coordinates if widget->window is smaller than
+ * widget->allocation.
+ */
+ src_x += wx - dest_widget->allocation.x;
+ src_y += wy - dest_widget->allocation.y;
+ }
+ else
+ {
+ src_x -= dest_widget->allocation.x;
+ src_y -= dest_widget->allocation.y;
+ }
+
+ if (dest_x)
+ *dest_x = src_x;
+ if (dest_y)
+ *dest_y = src_y;
+}
+
+static GtkWidget *
+find_widget_under_pointer (GdkWindow *window,
+ gint *x,
+ gint *y)
+{
+ GtkWidget *event_widget;
+ struct ChildLocation child_loc = { NULL, NULL, 0, 0 };
+
+ gdk_window_get_user_data (window, (void **)&event_widget);
+
+ if (!event_widget)
+ return NULL;
+
+#ifdef DEBUG_TOOLTIP
+ g_print ("event window %p (belonging to %p (%s)) (%d, %d)\n",
+ window, event_widget, gtk_widget_get_name (event_widget),
+ *x, *y);
+#endif
+
+ /* Coordinates are relative to event window */
+ child_loc.x = *x;
+ child_loc.y = *y;
+
+ /* We go down the window hierarchy to the widget->window,
+ * coordinates stay relative to the current window.
+ * We end up with window == widget->window, coordinates relative to that.
+ */
+ while (window && window != event_widget->window)
+ {
+ gint px, py;
+
+ gdk_window_get_position (window, &px, &py);
+ child_loc.x += px;
+ child_loc.y += py;
+
+ window = gdk_window_get_parent (window);
+ }
+
+ /* Failing to find widget->window can happen for e.g. a detached handle box;
+ * chaining ::query-tooltip up to its parent probably makes little sense,
+ * and users better implement tooltips on handle_box->child.
+ * so we simply ignore the event for tooltips here.
+ */
+ if (!window)
+ return NULL;
+
+ /* Convert the window relative coordinates to allocation
+ * relative coordinates.
+ */
+ window_to_alloc (event_widget,
+ child_loc.x, child_loc.y,
+ &child_loc.x, &child_loc.y);
+
+ if (GTK_IS_CONTAINER (event_widget))
+ {
+ GtkWidget *container = event_widget;
+
+ child_loc.container = event_widget;
+ child_loc.child = NULL;
+
+ gtk_container_forall (GTK_CONTAINER (event_widget),
+ child_location_foreach, &child_loc);
+
+ /* Here we have a widget, with coordinates relative to
+ * child_loc.container's allocation.
+ */
+
+ if (child_loc.child)
+ event_widget = child_loc.child;
+ else if (child_loc.container)
+ event_widget = child_loc.container;
+
+ /* Translate to event_widget's allocation */
+ gtk_widget_translate_coordinates (container, event_widget,
+ child_loc.x, child_loc.y,
+ &child_loc.x, &child_loc.y);
+
+ }
+
+ /* We return (x, y) relative to the allocation of event_widget. */
+ if (x)
+ *x = child_loc.x;
+ if (y)
+ *y = child_loc.y;
+
+ return event_widget;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]