aboutsummaryrefslogtreecommitdiff
path: root/src/idoscalemenuitem.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/idoscalemenuitem.c')
-rw-r--r--src/idoscalemenuitem.c74
1 files changed, 72 insertions, 2 deletions
diff --git a/src/idoscalemenuitem.c b/src/idoscalemenuitem.c
index fc39464..51e41b3 100644
--- a/src/idoscalemenuitem.c
+++ b/src/idoscalemenuitem.c
@@ -40,6 +40,11 @@ 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 gboolean ido_scale_menu_item_button_press_event (GtkWidget *menuitem,
GdkEventButton *event);
static gboolean ido_scale_menu_item_button_release_event (GtkWidget *menuitem,
@@ -76,6 +81,7 @@ struct _IdoScaleMenuItemPrivate {
IdoRangeStyle range_style;
gint toggle_size;
gboolean ignore_value_changed;
+ gboolean has_focus;
};
enum {
@@ -274,10 +280,14 @@ 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->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;
@@ -523,6 +533,55 @@ translate_event_coordinates (GtkWidget *widget,
}
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:
+ case GDK_KEY_minus:
+ case GDK_KEY_KP_Subtract:
+ GTK_RANGE_GET_CLASS (priv->scale)->move_slider (GTK_RANGE (priv->scale), GTK_SCROLL_STEP_LEFT);
+ return TRUE;
+
+ case GDK_KEY_Right:
+ case GDK_KEY_plus:
+ case GDK_KEY_KP_Add:
+ 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 gboolean
ido_scale_menu_item_button_press_event (GtkWidget *menuitem,
GdkEventButton *event)
{
@@ -648,11 +707,22 @@ ido_scale_menu_item_parent_set (GtkWidget *item,
GtkWidget *parent;
if (previous_parent)
- g_signal_handlers_disconnect_by_func (previous_parent, menu_hidden, item);
+ {
+ g_signal_handlers_disconnect_by_func (previous_parent, menu_hidden, item);
+ g_signal_handlers_disconnect_by_func (previous_parent, ido_scale_menu_item_parent_key_press_event, item);
+ }
parent = gtk_widget_get_parent (item);
+
if (parent)
- g_signal_connect (parent, "hide", G_CALLBACK (menu_hidden), item);
+ {
+ g_signal_connect (parent, "hide", G_CALLBACK (menu_hidden), item);
+
+ /* Menus don't pass key events to their children. This works around
+ * that by listening to key events on the parent widget. */
+ g_signal_connect (parent, "key-press-event",
+ G_CALLBACK (ido_scale_menu_item_parent_key_press_event), item);
+ }
}
static void