aboutsummaryrefslogtreecommitdiff
path: root/src/idoscalemenuitem.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/idoscalemenuitem.c')
-rw-r--r--src/idoscalemenuitem.c217
1 files changed, 192 insertions, 25 deletions
diff --git a/src/idoscalemenuitem.c b/src/idoscalemenuitem.c
index 986d9a7..7aaf9d6 100644
--- a/src/idoscalemenuitem.c
+++ b/src/idoscalemenuitem.c
@@ -30,6 +30,7 @@
#include "idorange.h"
#include "idoscalemenuitem.h"
#include "idotypebuiltins.h"
+#include "idoactionhelper.h"
static void ido_scale_menu_item_set_property (GObject *object,
guint prop_id,
@@ -309,6 +310,12 @@ ido_scale_menu_item_class_init (IdoScaleMenuItemClass *item_class)
FALSE,
G_PARAM_READWRITE));
+ /**
+ * IdoScaleMenuItem::slider-grabbed:
+ * @menuitem: The #IdoScaleMenuItem emitting the signal.
+ *
+ * The ::slider-grabbed signal is emitted when the pointer selects the slider.
+ */
signals[SLIDER_GRABBED] = g_signal_new ("slider-grabbed",
G_OBJECT_CLASS_TYPE (gobject_class),
G_SIGNAL_RUN_FIRST,
@@ -317,6 +324,12 @@ ido_scale_menu_item_class_init (IdoScaleMenuItemClass *item_class)
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
+ /**
+ * IdoScaleMenuItem::slider-released:
+ * @menuitem: The #IdoScaleMenuItem emitting the signal.
+ *
+ * The ::slider-released signal is emitted when the pointer releases the slider.
+ */
signals[SLIDER_RELEASED] = g_signal_new ("slider-released",
G_OBJECT_CLASS_TYPE (gobject_class),
G_SIGNAL_RUN_FIRST,
@@ -325,6 +338,12 @@ ido_scale_menu_item_class_init (IdoScaleMenuItemClass *item_class)
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
+ /**
+ * IdoScaleMenuItem::primary-clicked:
+ * @menuitem: The #IdoScaleMenuItem emitting the signal.
+ *
+ * The ::primary-clicked signal is emitted when the pointer clicks the primary label.
+ */
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,
@@ -334,6 +353,12 @@ ido_scale_menu_item_class_init (IdoScaleMenuItemClass *item_class)
G_TYPE_NONE, /* return type */
0 /* n_params */);
+ /**
+ * IdoScaleMenuItem::secondary-clicked:
+ * @menuitem: The #IdoScaleMenuItem emitting the signal.
+ *
+ * The ::secondary-clicked signal is emitted when the pointer clicks the secondary label.
+ */
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,
@@ -365,18 +390,18 @@ update_packing (IdoScaleMenuItem *self, IdoScaleMenuItemStyle style)
{
case IDO_SCALE_MENU_ITEM_STYLE_IMAGE:
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->scale, TRUE, TRUE, 0);
gtk_box_pack_start (box, priv->secondary_image, FALSE, FALSE, 0);
break;
case IDO_SCALE_MENU_ITEM_STYLE_LABEL:
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->scale, TRUE, TRUE, 0);
gtk_box_pack_start (box, priv->secondary_label, FALSE, FALSE, 0);
break;
default:
- gtk_box_pack_start (box, priv->scale, FALSE, FALSE, 0);
+ gtk_box_pack_start (box, priv->scale, TRUE, TRUE, 0);
break;
}
@@ -625,9 +650,10 @@ ido_scale_menu_item_secondary_image_notify (GtkImage *image,
* @label: the text of the new menu item.
* @size: The size style of the range.
* @adjustment: A #GtkAdjustment describing the slider value.
- * @returns: a new #IdoScaleMenuItem.
*
* Creates a new #IdoScaleMenuItem with an empty label.
+ *
+ * Return Value: a new #IdoScaleMenuItem.
**/
GtkWidget*
ido_scale_menu_item_new (const gchar *label,
@@ -647,9 +673,10 @@ ido_scale_menu_item_new (const gchar *label,
* @min: The minimum value of the slider.
* @max: The maximum value of the slider.
* @step: The step increment of the slider.
- * @returns: a new #IdoScaleMenuItem.
*
* Creates a new #IdoScaleMenuItem containing a label.
+ *
+ * Return Value: a new #IdoScaleMenuItem.
**/
GtkWidget*
ido_scale_menu_item_new_with_range (const gchar *label,
@@ -671,9 +698,10 @@ ido_scale_menu_item_new_with_range (const gchar *label,
/**
* ido_scale_menu_item_get_scale:
* @menuitem: The #IdoScaleMenuItem
- * @returns: A pointer to the scale widget.
*
* Retrieves the scale widget.
+ *
+ * Return Value: (transfer none): The #IdoRange in this item
**/
GtkWidget*
ido_scale_menu_item_get_scale (IdoScaleMenuItem *menuitem)
@@ -690,10 +718,11 @@ ido_scale_menu_item_get_scale (IdoScaleMenuItem *menuitem)
/**
* ido_scale_menu_item_get_style:
* @menuitem: The #IdoScaleMenuItem
- * @returns: A #IdoScaleMenuItemStyle enum describing the style.
*
* Retrieves the type of widgets being used for the primary and
* secondary widget slots. This could be images, labels, or nothing.
+ *
+ * Return Value: A #IdoScaleMenuItemStyle enum describing the style.
**/
IdoScaleMenuItemStyle
ido_scale_menu_item_get_style (IdoScaleMenuItem *menuitem)
@@ -707,6 +736,14 @@ ido_scale_menu_item_get_style (IdoScaleMenuItem *menuitem)
return priv->style;
}
+/**
+ * ido_scale_menu_item_set_style:
+ * @menuitem: The #IdoScaleMenuItem
+ * @style: Set the style use for the primary and secondary widget slots.
+ *
+ * Sets the type of widgets being used for the primary and
+ * secondary widget slots. This could be images, labels, or nothing.
+ **/
void
ido_scale_menu_item_set_style (IdoScaleMenuItem *menuitem,
IdoScaleMenuItemStyle style)
@@ -725,11 +762,12 @@ ido_scale_menu_item_set_style (IdoScaleMenuItem *menuitem,
/**
* ido_scale_menu_item_get_primary_image:
* @menuitem: The #IdoScaleMenuItem
- * @returns: A #GtkWidget pointer for the primary image.
*
* Retrieves a pointer to the image widget used in the primary slot.
* Whether this is visible depends upon the return value from
* ido_scale_menu_item_get_style().
+ *
+ * Return Value: (transfer none): A #GtkWidget pointer for the primary image.
**/
GtkWidget *
ido_scale_menu_item_get_primary_image (IdoScaleMenuItem *menuitem)
@@ -746,11 +784,12 @@ ido_scale_menu_item_get_primary_image (IdoScaleMenuItem *menuitem)
/**
* ido_scale_menu_item_get_secondary_image:
* @menuitem: The #IdoScaleMenuItem
- * @returns: A #GtkWidget pointer for the secondary image.
*
* Retrieves a pointer to the image widget used in the secondary slot.
* Whether this is visible depends upon the return value from
* ido_scale_menu_item_get_style().
+ *
+ * Return Value: (transfer none): A #GtkWidget pointer for the secondary image.
**/
GtkWidget *
ido_scale_menu_item_get_secondary_image (IdoScaleMenuItem *menuitem)
@@ -765,13 +804,45 @@ ido_scale_menu_item_get_secondary_image (IdoScaleMenuItem *menuitem)
}
/**
+ * ido_scale_menu_item_set_icons:
+ * @item: a #IdoScaleMenuItem
+ * @primary-icon: (allow-none): the primary icon, or %NULL
+ * @secondary-icon: (allow-non): the secondary icon, %NULL
+ *
+ * Sets the icons of @item to @primary_icon and @secondary_icon.
+ * Pass %NULL for either of them to unset the icon.
+ */
+static void
+ido_scale_menu_item_set_icons (IdoScaleMenuItem *item,
+ GIcon *primary_icon,
+ GIcon *secondary_icon)
+{
+ GtkWidget *primary;
+ GtkWidget *secondary;
+
+ primary = ido_scale_menu_item_get_primary_image (item);
+ secondary = ido_scale_menu_item_get_secondary_image (item);
+
+ if (primary_icon)
+ gtk_image_set_from_gicon (GTK_IMAGE (primary), primary_icon, GTK_ICON_SIZE_MENU);
+ else
+ gtk_image_clear (GTK_IMAGE (primary));
+
+ if (secondary_icon)
+ gtk_image_set_from_gicon (GTK_IMAGE (secondary), secondary_icon, GTK_ICON_SIZE_MENU);
+ else
+ gtk_image_clear (GTK_IMAGE (secondary));
+}
+
+/**
* ido_scale_menu_item_get_primary_label:
* @menuitem: The #IdoScaleMenuItem
- * @returns: A const gchar* string of the label text.
*
* Retrieves a string of the text for the primary label widget.
* Whether this is visible depends upon the return value from
* ido_scale_menu_item_get_style().
+ *
+ * Return Value: The label text.
**/
const gchar*
ido_scale_menu_item_get_primary_label (IdoScaleMenuItem *menuitem)
@@ -786,13 +857,14 @@ ido_scale_menu_item_get_primary_label (IdoScaleMenuItem *menuitem)
}
/**
- * ido_scale_menu_item_get_primary_label:
+ * ido_scale_menu_item_get_secondary_label:
* @menuitem: The #IdoScaleMenuItem
- * @returns: A const gchar* string of the label text.
*
- * Retrieves a string of the text for the primary label widget.
+ * Retrieves a string of the text for the secondary label widget.
* Whether this is visible depends upon the return value from
* ido_scale_menu_item_get_style().
+ *
+ * Return Value: The label text.
**/
const gchar*
ido_scale_menu_item_get_secondary_label (IdoScaleMenuItem *menuitem)
@@ -809,7 +881,7 @@ ido_scale_menu_item_get_secondary_label (IdoScaleMenuItem *menuitem)
/**
* ido_scale_menu_item_set_primary_label:
* @menuitem: The #IdoScaleMenuItem
- * @label: A string containing the label text
+ * @label: The label text
*
* Sets the text for the label widget in the primary slot. This
* widget will only be visibile if the return value of
@@ -832,11 +904,11 @@ ido_scale_menu_item_set_primary_label (IdoScaleMenuItem *menuitem,
}
/**
- * ido_scale_menu_item_set_primary_label:
+ * ido_scale_menu_item_set_secondary_label:
* @menuitem: The #IdoScaleMenuItem
- * @label: A string containing the label text
+ * @label: The label text
*
- * Sets the text for the label widget in the primary slot. This
+ * Sets the text for the label widget in the secondary slot. This
* widget will only be visibile if the return value of
* ido_scale_menu_item_get_style() is set to %IDO_SCALE_MENU_ITEM_STYLE_LABEL.
**/
@@ -859,16 +931,16 @@ 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)
+ido_scale_menu_item_primary_clicked (IdoScaleMenuItem * menuitem)
{
- g_signal_emit (item, signals[PRIMARY_CLICKED], 0);
+ g_signal_emit (menuitem, signals[PRIMARY_CLICKED], 0);
}
static void
default_primary_clicked_handler (IdoScaleMenuItem * item)
@@ -880,18 +952,18 @@ default_primary_clicked_handler (IdoScaleMenuItem * item)
}
/**
- * ido_scale_menu_item_primary_clicked:
+ * ido_scale_menu_item_secondary_clicked:
* @menuitem: the #IdoScaleMenuItem
- *
- * Emits the "primary-clicked" signal.
+ *
+ * Emits the "secondary-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)
+ido_scale_menu_item_secondary_clicked (IdoScaleMenuItem * menuitem)
{
- g_signal_emit (item, signals[SECONDARY_CLICKED], 0);
+ g_signal_emit (menuitem, signals[SECONDARY_CLICKED], 0);
}
static void
default_secondary_clicked_handler (IdoScaleMenuItem * item)
@@ -902,4 +974,99 @@ default_secondary_clicked_handler (IdoScaleMenuItem * item)
gtk_adjustment_set_value (adj, gtk_adjustment_get_upper (adj));
}
+/**
+ * ido_scale_menu_item_state_changed:
+ *
+ * Updates a IdoScaleMenuItem from @state. State must be a double which
+ * contains the current value of the slider.
+ */
+static void
+ido_scale_menu_item_state_changed (IdoActionHelper *helper,
+ GVariant *state,
+ gpointer user_data)
+{
+ GtkWidget *scale;
+
+ scale = ido_scale_menu_item_get_scale (IDO_SCALE_MENU_ITEM (ido_action_helper_get_widget (helper)));
+ gtk_range_set_value (GTK_RANGE (scale), g_variant_get_double (state));
+}
+
+static void
+ido_scale_menu_item_value_changed (GtkScale *scale,
+ gpointer user_data)
+{
+ IdoActionHelper *helper = user_data;
+ gdouble value;
+
+ value = gtk_range_get_value (GTK_RANGE (scale));
+ ido_action_helper_change_action_state (helper, g_variant_new_double (value));
+}
+
+static GIcon *
+menu_item_get_icon (GMenuItem *menuitem,
+ const gchar *attribute)
+{
+ GVariant *value;
+
+ value = g_menu_item_get_attribute_value (menuitem, attribute, NULL);
+
+ return value ? g_icon_deserialize (value) : NULL;
+}
+
+/**
+ * ido_scale_menu_item_new_from_model:
+ *
+ * Creates a new #IdoScaleMenuItem. If @menuitem contains an action, it
+ * will be bound to that action in @actions.
+ *
+ * Returns: (transfer full): a new #IdoScaleMenuItem
+ */
+GtkMenuItem *
+ido_scale_menu_item_new_from_model (GMenuItem *menuitem,
+ GActionGroup *actions)
+{
+ GtkWidget *item;
+ gchar *action;
+ gdouble min = 0.0;
+ gdouble max = 100.0;
+ gdouble step = 1.0;
+ GIcon *min_icon;
+ GIcon *max_icon;
+
+ g_menu_item_get_attribute (menuitem, "min-value", "d", &min);
+ g_menu_item_get_attribute (menuitem, "max-value", "d", &max);
+ g_menu_item_get_attribute (menuitem, "step", "d", &step);
+
+ item = ido_scale_menu_item_new_with_range ("Volume", IDO_RANGE_STYLE_DEFAULT, 0.0, min, max, step);
+ ido_scale_menu_item_set_style (IDO_SCALE_MENU_ITEM (item), IDO_SCALE_MENU_ITEM_STYLE_IMAGE);
+
+ if (g_menu_item_get_attribute (menuitem, "action", "s", &action))
+ {
+ IdoActionHelper *helper;
+ GtkWidget *scale;
+
+ helper = ido_action_helper_new (item, actions, action, NULL);
+ g_signal_connect (helper, "action-state-changed",
+ G_CALLBACK (ido_scale_menu_item_state_changed), NULL);
+
+ scale = ido_scale_menu_item_get_scale (IDO_SCALE_MENU_ITEM (item));
+ g_signal_connect (scale, "value-changed", G_CALLBACK (ido_scale_menu_item_value_changed), helper);
+
+ g_signal_connect_swapped (item, "destroy", G_CALLBACK (g_object_unref), helper);
+
+ g_free (action);
+ }
+
+ min_icon = menu_item_get_icon (menuitem, "min-icon");
+ max_icon = menu_item_get_icon (menuitem, "max-icon");
+ ido_scale_menu_item_set_icons (IDO_SCALE_MENU_ITEM (item), min_icon, max_icon);
+
+ if (min_icon)
+ g_object_unref (min_icon);
+ if (max_icon)
+ g_object_unref (max_icon);
+
+ return GTK_MENU_ITEM (item);
+}
+
#define __IDO_SCALE_MENU_ITEM_C__