aboutsummaryrefslogtreecommitdiff
path: root/src/idoscalemenuitem.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/idoscalemenuitem.c')
-rw-r--r--src/idoscalemenuitem.c261
1 files changed, 128 insertions, 133 deletions
diff --git a/src/idoscalemenuitem.c b/src/idoscalemenuitem.c
index f973f52..4b60b8b 100644
--- a/src/idoscalemenuitem.c
+++ b/src/idoscalemenuitem.c
@@ -31,10 +31,6 @@
#include "idoscalemenuitem.h"
#include "idotypebuiltins.h"
-#ifdef USE_GTK3
-#include "idooffscreenproxy.h"
-#endif
-
static void ido_scale_menu_item_set_property (GObject *object,
guint prop_id,
const GValue *value,
@@ -59,16 +55,12 @@ static void ido_scale_menu_item_notify (IdoScaleMenuItem
GParamSpec *pspec,
gpointer user_data);
static void update_packing (IdoScaleMenuItem *self,
- IdoScaleMenuItemStyle style,
- IdoScaleMenuItemStyle old_style);
+ IdoScaleMenuItemStyle style);
+static void default_primary_clicked_handler (IdoScaleMenuItem *self);
+static void default_secondary_clicked_handler (IdoScaleMenuItem *self);
struct _IdoScaleMenuItemPrivate {
GtkWidget *scale;
-
-#ifdef USE_GTK3
- GtkWidget *proxy;
-#endif
-
GtkAdjustment *adjustment;
GtkWidget *primary_image;
GtkWidget *secondary_image;
@@ -88,6 +80,8 @@ struct _IdoScaleMenuItemPrivate {
enum {
SLIDER_GRABBED,
SLIDER_RELEASED,
+ PRIMARY_CLICKED,
+ SECONDARY_CLICKED,
LAST_SIGNAL
};
@@ -105,13 +99,6 @@ G_DEFINE_TYPE (IdoScaleMenuItem, ido_scale_menu_item, GTK_TYPE_MENU_ITEM)
#define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), IDO_TYPE_SCALE_MENU_ITEM, IdoScaleMenuItemPrivate))
-static void
-ido_scale_menu_item_state_changed (GtkWidget *widget,
- GtkStateType previous_state)
-{
- gtk_widget_set_state (widget, GTK_STATE_NORMAL);
-}
-
static gboolean
ido_scale_menu_item_scroll_event (GtkWidget *menuitem,
GdkEventScroll *event)
@@ -230,6 +217,21 @@ ido_scale_menu_item_toggle_size_allocate (IdoScaleMenuItem *item,
priv->toggle_size = toggle_size;
}
+static gboolean
+on_scale_button_press_or_release_event (GtkWidget * widget G_GNUC_UNUSED,
+ GdkEventButton * event,
+ gpointer unused G_GNUC_UNUSED)
+{
+ /* HACK: we want the behaviour you get with the middle button, so we
+ * mangle the event. clicking with other buttons moves the slider in
+ * step increments, clicking with the middle button moves the slider to
+ * the location of the click. */
+ if (event->button == 1)
+ event->button = 2;
+
+ return FALSE;
+}
+
static void
ido_scale_menu_item_constructed (GObject *object)
{
@@ -248,15 +250,12 @@ ido_scale_menu_item_constructed (GObject *object)
priv->scale = ido_range_new (adj, range_style);
g_object_ref (priv->scale);
gtk_scale_set_draw_value (GTK_SCALE (priv->scale), FALSE);
-
-#ifdef USE_GTK3
- gtk_widget_set_can_focus (priv->scale, FALSE);
-
- priv->proxy = ido_offscreen_proxy_new ();
- g_object_ref (priv->proxy);
- gtk_container_add (GTK_CONTAINER (priv->proxy), priv->scale);
-#endif
+ g_signal_connect (G_OBJECT (priv->scale), "button-press-event",
+ G_CALLBACK (on_scale_button_press_or_release_event), NULL);
+ g_signal_connect (G_OBJECT (priv->scale), "button-release-event",
+ G_CALLBACK (on_scale_button_press_or_release_event), NULL);
+
#ifdef USE_GTK3
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
#else
@@ -278,7 +277,7 @@ ido_scale_menu_item_constructed (GObject *object)
priv->hbox = hbox;
- update_packing (self, priv->style, priv->style);
+ update_packing (self, priv->style);
g_signal_connect (self, "toggle-size-allocate",
G_CALLBACK (ido_scale_menu_item_toggle_size_allocate),
@@ -289,6 +288,8 @@ ido_scale_menu_item_constructed (GObject *object)
NULL);
gtk_container_add (GTK_CONTAINER (self), hbox);
+
+ gtk_widget_add_events (GTK_WIDGET(self), GDK_SCROLL_MASK);
}
static void
@@ -297,11 +298,13 @@ 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);
+ item_class->primary_clicked = default_primary_clicked_handler;
+ item_class->secondary_clicked = default_secondary_clicked_handler;
+
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;
widget_class->scroll_event = ido_scale_menu_item_scroll_event;
- widget_class->state_changed = ido_scale_menu_item_state_changed;
widget_class->size_allocate = ido_scale_menu_item_size_allocate;
gobject_class->constructed = ido_scale_menu_item_constructed;
@@ -358,95 +361,58 @@ ido_scale_menu_item_class_init (IdoScaleMenuItemClass *item_class)
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
+ signals[PRIMARY_CLICKED] = g_signal_new ("primary-clicked",
+ G_TYPE_FROM_CLASS (item_class),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
+ G_STRUCT_OFFSET (IdoScaleMenuItemClass, primary_clicked),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, /* return type */
+ 0 /* n_params */);
+
+ signals[SECONDARY_CLICKED] = g_signal_new ("secondary-clicked",
+ G_TYPE_FROM_CLASS (item_class),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
+ G_STRUCT_OFFSET (IdoScaleMenuItemClass, secondary_clicked),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, /* return type */
+ 0 /* n_params */);
+
g_type_class_add_private (item_class, sizeof (IdoScaleMenuItemPrivate));
}
static void
-update_packing (IdoScaleMenuItem *self, IdoScaleMenuItemStyle style, IdoScaleMenuItemStyle old_style)
+update_packing (IdoScaleMenuItem *self, IdoScaleMenuItemStyle style)
{
IdoScaleMenuItemPrivate *priv = GET_PRIVATE (self);
+ GtkBox * box = GTK_BOX (priv->hbox);
GtkContainer *container = GTK_CONTAINER (priv->hbox);
- if (style != old_style)
- {
- switch (old_style)
- {
- case IDO_SCALE_MENU_ITEM_STYLE_NONE:
-#ifdef USE_GTK3
- gtk_container_remove (container, priv->proxy);
-#else
- gtk_container_remove (container, priv->scale);
-#endif
- break;
-
- case IDO_SCALE_MENU_ITEM_STYLE_IMAGE:
- gtk_container_remove (container, priv->primary_image);
- gtk_container_remove (container, priv->secondary_image);
-#ifdef USE_GTK3
- gtk_container_remove (container, priv->proxy);
-#else
- gtk_container_remove (container, priv->scale);
-#endif
- break;
-
- case IDO_SCALE_MENU_ITEM_STYLE_LABEL:
- gtk_container_remove (container, priv->primary_label);
- gtk_container_remove (container, priv->secondary_label);
-#ifdef USE_GTK3
- gtk_container_remove (container, priv->proxy);
-#else
- gtk_container_remove (container, priv->scale);
-#endif
- break;
-
- default:
-#ifdef USE_GTK3
- gtk_container_remove (container, priv->proxy);
-#else
- gtk_container_remove (container, priv->scale);
-#endif
- break;
- }
- }
+ /* remove the old layout */
+ GList * children = gtk_container_get_children (container);
+ GList * l;
+ for (l=children; l!=NULL; l=l->next)
+ gtk_container_remove (container, l->data);
+ g_list_free (children);
+ /* add the new layout */
switch (style)
{
- case IDO_SCALE_MENU_ITEM_STYLE_NONE:
-#ifdef USE_GTK3
- gtk_box_pack_start (GTK_BOX (priv->hbox), priv->proxy, FALSE, FALSE, 0);
-#else
- gtk_box_pack_start (GTK_BOX (priv->hbox), priv->scale, FALSE, FALSE, 0);
-#endif
- break;
-
case IDO_SCALE_MENU_ITEM_STYLE_IMAGE:
- gtk_box_pack_start (GTK_BOX (priv->hbox), priv->primary_image, FALSE, FALSE, 0);
-
-#ifdef USE_GTK3
- gtk_box_pack_start (GTK_BOX (priv->hbox), priv->proxy, FALSE, FALSE, 0);
-#else
- gtk_box_pack_start (GTK_BOX (priv->hbox), priv->scale, FALSE, FALSE, 0);
-#endif
-
- gtk_box_pack_start (GTK_BOX (priv->hbox), priv->secondary_image, FALSE, FALSE, 0);
+ gtk_box_pack_start (box, priv->primary_image, FALSE, FALSE, 0);
+ gtk_box_pack_start (box, priv->scale, FALSE, FALSE, 0);
+ gtk_box_pack_start (box, priv->secondary_image, FALSE, FALSE, 0);
break;
case IDO_SCALE_MENU_ITEM_STYLE_LABEL:
- gtk_box_pack_start (GTK_BOX (priv->hbox), priv->primary_label, FALSE, FALSE, 0);
-#ifdef USE_GTK3
- gtk_box_pack_start (GTK_BOX (priv->hbox), priv->proxy, FALSE, FALSE, 0);
-#else
- gtk_box_pack_start (GTK_BOX (priv->hbox), priv->scale, FALSE, FALSE, 0);
-#endif
- gtk_box_pack_start (GTK_BOX (priv->hbox), priv->secondary_label, FALSE, FALSE, 0);
+ gtk_box_pack_start (box, priv->primary_label, FALSE, FALSE, 0);
+ gtk_box_pack_start (box, priv->scale, FALSE, FALSE, 0);
+ gtk_box_pack_start (box, priv->secondary_label, FALSE, FALSE, 0);
break;
default:
-#ifdef USE_GTK3
- gtk_box_pack_start (GTK_BOX (priv->hbox), priv->proxy, FALSE, FALSE, 0);
-#else
- gtk_box_pack_start (GTK_BOX (priv->hbox), priv->scale, FALSE, FALSE, 0);
-#endif
+ gtk_box_pack_start (box, priv->scale, FALSE, FALSE, 0);
break;
}
@@ -579,64 +545,50 @@ static gboolean
ido_scale_menu_item_button_release_event (GtkWidget *menuitem,
GdkEventButton *event)
{
+ IdoScaleMenuItem *item = IDO_SCALE_MENU_ITEM (menuitem);
IdoScaleMenuItemPrivate *priv = GET_PRIVATE (menuitem);
GtkWidget *scale = priv->scale;
gdouble x;
+ /* if user clicked to the left of the scale... */
if (event->x > priv->child_allocation.x &&
event->x < priv->child_allocation.x + priv->left_padding)
{
- GtkAdjustment *adj = gtk_range_get_adjustment (GTK_RANGE (priv->scale));
-
if (gtk_widget_get_direction (menuitem) == GTK_TEXT_DIR_LTR)
{
- gtk_adjustment_set_value (adj, gtk_adjustment_get_lower (adj));
+ ido_scale_menu_item_primary_clicked (item);
}
else
{
- gtk_adjustment_set_value (adj, gtk_adjustment_get_upper (adj));
+ ido_scale_menu_item_secondary_clicked (item);
}
-
- if (priv->grabbed)
- {
- priv->grabbed = FALSE;
- g_signal_emit (menuitem, signals[SLIDER_RELEASED], 0);
- }
-
- return TRUE;
}
- if (event->x < priv->child_allocation.x + priv->child_allocation.width + priv->right_padding + priv->left_padding &&
+ /* if user clicked to the right of the scale... */
+ else if (event->x < priv->child_allocation.x + priv->child_allocation.width + priv->right_padding + priv->left_padding &&
event->x > priv->child_allocation.x + priv->child_allocation.width + priv->left_padding)
{
- GtkAdjustment *adj = gtk_range_get_adjustment (GTK_RANGE (priv->scale));
-
if (gtk_widget_get_direction (menuitem) == GTK_TEXT_DIR_LTR)
{
- gtk_adjustment_set_value (adj, gtk_adjustment_get_upper (adj));
+ ido_scale_menu_item_secondary_clicked (item);
}
else
{
- gtk_adjustment_set_value (adj, gtk_adjustment_get_lower (adj));
+ ido_scale_menu_item_primary_clicked (item);
}
-
- if (priv->grabbed)
- {
- priv->grabbed = FALSE;
- g_signal_emit (menuitem, signals[SLIDER_RELEASED], 0);
- }
-
- return TRUE;
}
- translate_event_coordinates (menuitem, event->x, &x);
- event->x = x;
+ /* user clicked on the scale... */
+ else
+ {
+ translate_event_coordinates (menuitem, event->x, &x);
+ event->x = x;
- translate_event_coordinates (menuitem, event->x_root, &x);
- event->x_root= x;
+ translate_event_coordinates (menuitem, event->x_root, &x);
+ event->x_root= x;
- gtk_widget_event (scale,
- ((GdkEvent *)(void*)(event)));
+ gtk_widget_event (scale, (GdkEvent*)event);
+ }
if (priv->grabbed)
{
@@ -812,16 +764,14 @@ ido_scale_menu_item_set_style (IdoScaleMenuItem *menuitem,
IdoScaleMenuItemStyle style)
{
IdoScaleMenuItemPrivate *priv;
- IdoScaleMenuItemStyle old_style;
g_return_if_fail (IDO_IS_SCALE_MENU_ITEM (menuitem));
priv = GET_PRIVATE (menuitem);
- old_style = priv->style;
priv->style = style;
- update_packing (menuitem, style, old_style);
+ update_packing (menuitem, style);
}
/**
@@ -958,5 +908,50 @@ ido_scale_menu_item_set_secondary_label (IdoScaleMenuItem *menuitem,
}
}
+/**
+ * ido_scale_menu_item_primary_clicked:
+ * @menuitem: the #IdoScaleMenuItem
+ *
+ * Emits the "primary-clicked" signal.
+ *
+ * The default handler for this signal lowers the scale's
+ * adjustment to its lower bound.
+ */
+void
+ido_scale_menu_item_primary_clicked (IdoScaleMenuItem * item)
+{
+ g_signal_emit (item, signals[PRIMARY_CLICKED], 0);
+}
+static void
+default_primary_clicked_handler (IdoScaleMenuItem * item)
+{
+ g_debug ("%s: setting scale to lower bound", G_STRFUNC);
+ IdoScaleMenuItemPrivate * priv = GET_PRIVATE (item);
+ GtkAdjustment *adj = gtk_range_get_adjustment (GTK_RANGE (priv->scale));
+ gtk_adjustment_set_value (adj, gtk_adjustment_get_lower (adj));
+}
+
+/**
+ * ido_scale_menu_item_primary_clicked:
+ * @menuitem: the #IdoScaleMenuItem
+ *
+ * Emits the "primary-clicked" signal.
+ *
+ * The default handler for this signal raises the scale's
+ * adjustment to its upper bound.
+ */
+void
+ido_scale_menu_item_secondary_clicked (IdoScaleMenuItem * item)
+{
+ g_signal_emit (item, signals[SECONDARY_CLICKED], 0);
+}
+static void
+default_secondary_clicked_handler (IdoScaleMenuItem * item)
+{
+ g_debug ("%s: setting scale to upper bound", G_STRFUNC);
+ IdoScaleMenuItemPrivate * priv = GET_PRIVATE (item);
+ GtkAdjustment *adj = gtk_range_get_adjustment (GTK_RANGE (priv->scale));
+ gtk_adjustment_set_value (adj, gtk_adjustment_get_upper (adj));
+}
#define __IDO_SCALE_MENU_ITEM_C__