diff options
Diffstat (limited to '.pc/lp_902715.patch')
-rw-r--r-- | .pc/lp_902715.patch/src/volume-widget.c | 319 |
1 files changed, 319 insertions, 0 deletions
diff --git a/.pc/lp_902715.patch/src/volume-widget.c b/.pc/lp_902715.patch/src/volume-widget.c new file mode 100644 index 0000000..ac603c1 --- /dev/null +++ b/.pc/lp_902715.patch/src/volume-widget.c @@ -0,0 +1,319 @@ + +/* +Copyright 2010 Canonical Ltd. + +Authors: + Conor Curran <conor.curran@canonical.com> + +This program is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License version 3, as published +by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranties of +MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <glib/gi18n-lib.h> +#include <math.h> +#include <glib.h> +#include "volume-widget.h" +#include "common-defs.h" +#include <libido/idoscalemenuitem.h> +#include "indicator-sound.h" + +typedef struct _VolumeWidgetPrivate VolumeWidgetPrivate; + +struct _VolumeWidgetPrivate +{ + DbusmenuMenuitem* twin_item; + GtkWidget* ido_volume_slider; + gboolean grabbed; + IndicatorObject* indicator; +}; + +#define VOLUME_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), VOLUME_WIDGET_TYPE, VolumeWidgetPrivate)) + +/* Prototypes */ +static void volume_widget_class_init (VolumeWidgetClass *klass); +static void volume_widget_init (VolumeWidget *self); +static void volume_widget_dispose (GObject *object); +static void volume_widget_finalize (GObject *object); +static void volume_widget_set_twin_item( VolumeWidget* self, + DbusmenuMenuitem* twin_item); +static void volume_widget_property_update( DbusmenuMenuitem* item, gchar* property, + GVariant* value, gpointer userdata ); + +static gboolean volume_widget_change_value_cb (GtkRange *range, + GtkScrollType scroll, + gdouble value, + gpointer user_data); +static void volume_widget_primary_clicked(GtkWidget *widget, gpointer user_data); +static void volume_widget_secondary_clicked(GtkWidget *widget, gpointer user_data); +static void volume_widget_slider_grabbed(GtkWidget *widget, gpointer user_data); +static void volume_widget_slider_released(GtkWidget *widget, gpointer user_data); +static void volume_widget_parent_changed (GtkWidget *widget, gpointer user_data); + +G_DEFINE_TYPE (VolumeWidget, volume_widget, G_TYPE_OBJECT); + + +static void +volume_widget_class_init (VolumeWidgetClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (VolumeWidgetPrivate)); + + gobject_class->dispose = volume_widget_dispose; + gobject_class->finalize = volume_widget_finalize; +} + +static void +volume_widget_init (VolumeWidget *self) +{ + VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(self); + + priv->ido_volume_slider = ido_scale_menu_item_new_with_range ("VOLUME", IDO_RANGE_STYLE_DEFAULT, 0, 0, 100, 1); + g_object_ref (priv->ido_volume_slider); + ido_scale_menu_item_set_primary_label (IDO_SCALE_MENU_ITEM(priv->ido_volume_slider), "VOLUME"); + ido_scale_menu_item_set_style (IDO_SCALE_MENU_ITEM (priv->ido_volume_slider), IDO_SCALE_MENU_ITEM_STYLE_IMAGE); + g_object_set(priv->ido_volume_slider, "reverse-scroll-events", TRUE, NULL); + + g_signal_connect (priv->ido_volume_slider, + "notify::parent", G_CALLBACK (volume_widget_parent_changed), + NULL); + + GtkWidget* volume_widget = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_volume_slider); + + g_signal_connect(volume_widget, "change-value", G_CALLBACK(volume_widget_change_value_cb), self); + g_signal_connect(priv->ido_volume_slider, "primary-clicked", G_CALLBACK(volume_widget_primary_clicked), self); + g_signal_connect(priv->ido_volume_slider, "secondary-clicked", G_CALLBACK(volume_widget_secondary_clicked), self); + g_signal_connect(priv->ido_volume_slider, "slider-grabbed", G_CALLBACK(volume_widget_slider_grabbed), self); + g_signal_connect(priv->ido_volume_slider, "slider-released", G_CALLBACK(volume_widget_slider_released), self); + + GtkWidget* primary_image = ido_scale_menu_item_get_primary_image((IdoScaleMenuItem*)priv->ido_volume_slider); + GIcon * primary_gicon = g_themed_icon_new_with_default_fallbacks("audio-volume-low-zero-panel"); + gtk_image_set_from_gicon(GTK_IMAGE(primary_image), primary_gicon, GTK_ICON_SIZE_MENU); + g_object_unref(primary_gicon); + + GtkWidget* secondary_image = ido_scale_menu_item_get_secondary_image((IdoScaleMenuItem*)priv->ido_volume_slider); + GIcon * secondary_gicon = g_themed_icon_new_with_default_fallbacks("audio-volume-high-panel"); + gtk_image_set_from_gicon(GTK_IMAGE(secondary_image), secondary_gicon, GTK_ICON_SIZE_MENU); + g_object_unref(secondary_gicon); + + GtkAdjustment *adj = gtk_range_get_adjustment (GTK_RANGE (volume_widget)); + gtk_adjustment_set_step_increment(adj, 4); +} + +static void +volume_widget_dispose (GObject *object) +{ + G_OBJECT_CLASS (volume_widget_parent_class)->dispose (object); +} + +static void +volume_widget_finalize (GObject *object) +{ + G_OBJECT_CLASS (volume_widget_parent_class)->finalize (object); +} + +static void +volume_widget_property_update( DbusmenuMenuitem* item, gchar* property, + GVariant* value, gpointer userdata) +{ + g_return_if_fail (IS_VOLUME_WIDGET(userdata)); + VolumeWidget* mitem = VOLUME_WIDGET(userdata); + VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(mitem); + + if(g_ascii_strcasecmp(DBUSMENU_VOLUME_MENUITEM_LEVEL, property) == 0){ + g_return_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE_DOUBLE) ); + if(priv->grabbed == FALSE){ + GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_volume_slider); + GtkRange *range = (GtkRange*)slider; + gdouble update = g_variant_get_double (value); + gtk_range_set_value(range, update); +/* + g_debug ("volume-widget::volume_widget_property_update - volume - value %f", update); +*/ + update_accessible_desc(priv->indicator); + } + } + else if(g_ascii_strcasecmp(DBUSMENU_VOLUME_MENUITEM_MUTE, property) == 0){ + g_return_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE_BOOLEAN)); + if(priv->grabbed == FALSE){ + GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_volume_slider); + GtkRange *range = (GtkRange*)slider; + gboolean update = g_variant_get_boolean (value); + gdouble level; + + if (update == TRUE){ + level = 0; + } + else{ + GVariant* variant = dbusmenu_menuitem_property_get_variant (priv->twin_item, + DBUSMENU_VOLUME_MENUITEM_LEVEL); +/* + g_debug ("variant for the volume - is it null = %i", variant == NULL); +*/ + g_return_if_fail (g_variant_is_of_type (variant, G_VARIANT_TYPE_DOUBLE) ); + + level = g_variant_get_double (variant); + } +/* + g_debug ("volume-widget::volume_widget_property_update - mute - value %i and level = %f", update, level); +*/ + gtk_range_set_value(range, level); + } + } +} + +static void +volume_widget_set_twin_item(VolumeWidget* self, + DbusmenuMenuitem* twin_item) +{ + VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(self); + priv->twin_item = twin_item; + g_object_ref(priv->twin_item); + g_signal_connect(G_OBJECT(twin_item), "property-changed", + G_CALLBACK(volume_widget_property_update), self); + gdouble initial_level = g_variant_get_double (dbusmenu_menuitem_property_get_variant(twin_item, + DBUSMENU_VOLUME_MENUITEM_LEVEL)); + gboolean initial_mute = g_variant_get_boolean (dbusmenu_menuitem_property_get_variant(twin_item, + DBUSMENU_VOLUME_MENUITEM_MUTE)); + + //g_debug("volume_widget_set_twin_item initial level = %f", initial_level); + GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_volume_slider); + GtkRange *range = (GtkRange*)slider; + if(initial_mute == TRUE){ + initial_level = 0; + } + gtk_range_set_value(range, initial_level); +} + +static gboolean +volume_widget_change_value_cb (GtkRange *range, + GtkScrollType scroll, + gdouble new_value, + gpointer user_data) +{ + g_return_val_if_fail (IS_VOLUME_WIDGET (user_data), FALSE); + VolumeWidget* mitem = VOLUME_WIDGET(user_data); + +/* + g_debug ("changed value %f", new_value); +*/ + + volume_widget_update(mitem, new_value, "change-value"); + return FALSE; +} + +void +volume_widget_update(VolumeWidget* self, gdouble update, gchar* label) +{ + gchar* source = NULL; + source = label; + if (label == NULL){ + source = "v widget update"; + } + VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(self); + gdouble clamped = CLAMP(update, 0, 100); + GVariant* new_volume = g_variant_new_double(clamped); + dbusmenu_menuitem_handle_event (priv->twin_item, source, new_volume, 0); +} + +static void +volume_widget_update_from_scale (VolumeWidget *self) +{ + g_return_if_fail (IS_VOLUME_WIDGET (self)); + + VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(self); + GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_volume_slider); + const gdouble current_value = CLAMP(gtk_range_get_value(GTK_RANGE(slider)), 0, 100); + g_debug ("%s - setting value to %.0f", G_STRFUNC, current_value); + volume_widget_update (self, current_value, "value-changed"); +} + +static void +volume_widget_primary_clicked (GtkWidget *widget G_GNUC_UNUSED, gpointer user_data) +{ + volume_widget_update_from_scale (VOLUME_WIDGET(user_data)); +} + +static void +volume_widget_secondary_clicked(GtkWidget *widget, gpointer user_data) +{ + volume_widget_update_from_scale (VOLUME_WIDGET(user_data)); +} + +GtkWidget* +volume_widget_get_ido_slider(VolumeWidget* self) +{ + VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(self); + return priv->ido_volume_slider; +} + +static void +volume_widget_parent_changed (GtkWidget *widget, + gpointer user_data) +{ + gtk_widget_set_size_request (widget, 200, -1); + //g_debug("volume_widget_parent_changed"); +} + +static void +volume_widget_slider_grabbed(GtkWidget *widget, gpointer user_data) +{ + VolumeWidget* mitem = VOLUME_WIDGET(user_data); + VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(mitem); + priv->grabbed = TRUE; +} + +static void +volume_widget_slider_released(GtkWidget *widget, gpointer user_data) +{ + VolumeWidget* mitem = VOLUME_WIDGET(user_data); + VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(mitem); + priv->grabbed = FALSE; +} + +void +volume_widget_tidy_up (GtkWidget *widget) +{ + VolumeWidget* mitem = VOLUME_WIDGET(widget); + VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(mitem); + gtk_widget_destroy (priv->ido_volume_slider); +} + +gdouble +volume_widget_get_current_volume ( GtkWidget *widget ) +{ + VolumeWidget* mitem = VOLUME_WIDGET(widget); + VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(mitem); + gdouble vol = g_variant_get_double( dbusmenu_menuitem_property_get_variant( priv->twin_item, + DBUSMENU_VOLUME_MENUITEM_LEVEL)); + return vol; +} + +/** + * volume_widget_new: + * @returns: a new #VolumeWidget. + **/ +GtkWidget* +volume_widget_new(DbusmenuMenuitem *item, IndicatorObject* io) +{ + GtkWidget* widget = g_object_new(VOLUME_WIDGET_TYPE, NULL); + VolumeWidgetPrivate* priv = VOLUME_WIDGET_GET_PRIVATE(VOLUME_WIDGET(widget)); + priv->indicator = io; + volume_widget_set_twin_item((VolumeWidget*)widget, item); + return widget; +} + + |