aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/idoactionhelper.c25
-rw-r--r--src/idoactionhelper.h3
-rw-r--r--src/idomenuitemfactory.c4
-rw-r--r--src/idoscalemenuitem.c133
-rw-r--r--src/idoscalemenuitem.h3
5 files changed, 165 insertions, 3 deletions
diff --git a/src/idoactionhelper.c b/src/idoactionhelper.c
index fdd9479..f0e300b 100644
--- a/src/idoactionhelper.c
+++ b/src/idoactionhelper.c
@@ -401,3 +401,28 @@ ido_action_helper_activate (IdoActionHelper *helper)
if (helper->actions && helper->action_name)
g_action_group_activate_action (helper->actions, helper->action_name, helper->action_target);
}
+
+/**
+ * ido_action_helper_change_action_state:
+ * @helper: an #IdoActionHelper
+ * @state: the proposed new state of the action
+ *
+ * Requests changing the state of the action that is associated with
+ * @helper to @state.
+ *
+ * If @state is floating, it is consumed.
+ */
+void
+ido_action_helper_change_action_state (IdoActionHelper *helper,
+ GVariant *state)
+{
+ g_return_if_fail (IDO_IS_ACTION_HELPER (helper));
+ g_return_if_fail (state != NULL);
+
+ g_variant_ref_sink (state);
+
+ if (helper->actions && helper->action_name)
+ g_action_group_change_action_state (helper->actions, helper->action_name, state);
+
+ g_variant_unref (state);
+}
diff --git a/src/idoactionhelper.h b/src/idoactionhelper.h
index 22cdcae..27dafb7 100644
--- a/src/idoactionhelper.h
+++ b/src/idoactionhelper.h
@@ -41,4 +41,7 @@ GVariant * ido_action_helper_get_action_target (IdoActionHelper *helper
void ido_action_helper_activate (IdoActionHelper *helper);
+void ido_action_helper_change_action_state (IdoActionHelper *helper,
+ GVariant *state);
+
#endif
diff --git a/src/idomenuitemfactory.c b/src/idomenuitemfactory.c
index 59f3630..0ff84a8 100644
--- a/src/idomenuitemfactory.c
+++ b/src/idomenuitemfactory.c
@@ -21,6 +21,7 @@
#include <gtk/ubuntu-private.h>
#include "idousermenuitem.h"
+#include "idoscalemenuitem.h"
#define IDO_TYPE_MENU_ITEM_FACTORY (ido_menu_item_factory_get_type ())
#define IDO_MENU_ITEM_FACTORY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), IDO_TYPE_MENU_ITEM_FACTORY, IdoMenuItemFactory))
@@ -48,6 +49,9 @@ ido_menu_item_factory_create_menu_item (UbuntuMenuItemFactory *factory,
if (g_str_equal (type, "indicator.user-menu-item"))
item = ido_user_menu_item_new_from_model (menuitem, actions);
+ else if (g_str_equal (type, "com.canonical.unity.slider"))
+ item = ido_scale_menu_item_new_from_model (menuitem, actions);
+
return item;
}
diff --git a/src/idoscalemenuitem.c b/src/idoscalemenuitem.c
index 25460bb..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,
@@ -389,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;
}
@@ -803,6 +804,37 @@ 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
*
@@ -942,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__
diff --git a/src/idoscalemenuitem.h b/src/idoscalemenuitem.h
index 2d63f3c..2c32a49 100644
--- a/src/idoscalemenuitem.h
+++ b/src/idoscalemenuitem.h
@@ -92,6 +92,9 @@ void ido_scale_menu_item_set_secondary_label (IdoScaleMenuItem
void ido_scale_menu_item_primary_clicked (IdoScaleMenuItem *menuitem);
void ido_scale_menu_item_secondary_clicked (IdoScaleMenuItem *menuitem);
+GtkMenuItem * ido_scale_menu_item_new_from_model (GMenuItem *menuitem,
+ GActionGroup *actions);
+
G_END_DECLS
#endif /* __IDO_SCALE_MENU_ITEM_H__ */