From 8fe2bdf722333305bdc4108c0a6a651cd17dbf78 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Mon, 21 Oct 2013 17:41:51 -0400 Subject: IdoScaleMenuItem: intercept left and right keys --- src/idoscalemenuitem.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) (limited to 'src') diff --git a/src/idoscalemenuitem.c b/src/idoscalemenuitem.c index 9b933cc..176d8d7 100644 --- a/src/idoscalemenuitem.c +++ b/src/idoscalemenuitem.c @@ -40,6 +40,13 @@ static void ido_scale_menu_item_get_property (GObject guint prop_id, GValue *value, GParamSpec *pspec); +static gboolean ido_scale_menu_item_parent_key_press_event (GtkWidget *widget, + GdkEventKey *event, + gpointer user_data); +static void ido_scale_menu_item_select (GtkMenuItem *item); +static void ido_scale_menu_item_deselect (GtkMenuItem *item); +static void ido_scale_menu_item_parent_set (GtkWidget *widget, + GtkWidget *old_parent); static gboolean ido_scale_menu_item_button_press_event (GtkWidget *menuitem, GdkEventButton *event); static gboolean ido_scale_menu_item_button_release_event (GtkWidget *menuitem, @@ -77,6 +84,7 @@ struct _IdoScaleMenuItemPrivate { IdoRangeStyle range_style; gint toggle_size; gboolean ignore_value_changed; + gboolean has_focus; }; enum { @@ -279,10 +287,15 @@ ido_scale_menu_item_class_init (IdoScaleMenuItemClass *item_class) { GObjectClass *gobject_class = G_OBJECT_CLASS (item_class); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (item_class); + GtkMenuItemClass *menuitem_class = GTK_MENU_ITEM_CLASS (item_class); item_class->primary_clicked = default_primary_clicked_handler; item_class->secondary_clicked = default_secondary_clicked_handler; + menuitem_class->select = ido_scale_menu_item_select; + menuitem_class->deselect = ido_scale_menu_item_deselect; + + widget_class->parent_set = ido_scale_menu_item_parent_set; widget_class->button_press_event = ido_scale_menu_item_button_press_event; widget_class->button_release_event = ido_scale_menu_item_button_release_event; widget_class->motion_notify_event = ido_scale_menu_item_motion_notify_event; @@ -526,6 +539,71 @@ translate_event_coordinates (GtkWidget *widget, *out_x = in_x - priv->child_allocation.x - priv->left_padding; } +static gboolean +ido_scale_menu_item_parent_key_press_event (GtkWidget *widget, + GdkEventKey *event, + gpointer user_data) +{ + IdoScaleMenuItemPrivate *priv = GET_PRIVATE (user_data); + + /* only listen to events when the playback menu item is selected */ + if (!priv->has_focus) + return FALSE; + + switch (event->keyval) + { + case GDK_KEY_Left: + GTK_RANGE_GET_CLASS (priv->scale)->move_slider (GTK_RANGE (priv->scale), GTK_SCROLL_STEP_LEFT); + return TRUE; + + case GDK_KEY_Right: + GTK_RANGE_GET_CLASS (priv->scale)->move_slider (GTK_RANGE (priv->scale), GTK_SCROLL_STEP_RIGHT); + return TRUE; + } + + return FALSE; +} + +static void +ido_scale_menu_item_select (GtkMenuItem *item) +{ + IdoScaleMenuItemPrivate *priv = GET_PRIVATE (item); + + priv->has_focus = TRUE; + + GTK_MENU_ITEM_CLASS (ido_scale_menu_item_parent_class)->select (item); +} + +static void +ido_scale_menu_item_deselect (GtkMenuItem *item) +{ + IdoScaleMenuItemPrivate *priv = GET_PRIVATE (item); + + priv->has_focus = FALSE; + + GTK_MENU_ITEM_CLASS (ido_scale_menu_item_parent_class)->deselect (item); +} + +static void +ido_scale_menu_item_parent_set (GtkWidget *widget, + GtkWidget *old_parent) +{ + GtkWidget *parent; + + /* Menus don't pass key events to their children. This works around + * that by listening to key events on the parent widget. */ + + if (old_parent) + g_signal_handlers_disconnect_by_func (old_parent, ido_scale_menu_item_parent_key_press_event, widget); + + parent = gtk_widget_get_parent (widget); + if (parent) + { + g_signal_connect (parent, "key-press-event", + G_CALLBACK (ido_scale_menu_item_parent_key_press_event), widget); + } +} + static gboolean ido_scale_menu_item_button_press_event (GtkWidget *menuitem, GdkEventButton *event) -- cgit v1.2.3