From ea30986e03e54ee650a1cca610904de9f4d0f745 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Wed, 6 Mar 2013 22:40:55 -0500 Subject: Remove libsoundmenu (panel plugin) Indicator panel plugins are deprecated. --- src/Makefile.am | 38 - src/indicator-sound.c | 834 -------------------- src/indicator-sound.h | 59 -- src/metadata-widget.c | 880 --------------------- src/metadata-widget.h | 51 -- src/mute-widget.c | 134 ---- src/mute-widget.h | 63 -- src/sound-state-manager.c | 480 ------------ src/sound-state-manager.h | 67 -- src/transport-widget.c | 1886 --------------------------------------------- src/transport-widget.h | 67 -- src/voip-input-widget.c | 284 ------- src/voip-input-widget.h | 56 -- src/volume-widget.c | 338 -------- src/volume-widget.h | 58 -- 15 files changed, 5295 deletions(-) delete mode 100644 src/indicator-sound.c delete mode 100644 src/indicator-sound.h delete mode 100644 src/metadata-widget.c delete mode 100644 src/metadata-widget.h delete mode 100644 src/mute-widget.c delete mode 100644 src/mute-widget.h delete mode 100644 src/sound-state-manager.c delete mode 100644 src/sound-state-manager.h delete mode 100644 src/transport-widget.c delete mode 100644 src/transport-widget.h delete mode 100644 src/voip-input-widget.c delete mode 100644 src/voip-input-widget.h delete mode 100644 src/volume-widget.c delete mode 100644 src/volume-widget.h (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 5a36822..a56f82a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,43 +1,5 @@ libexec_PROGRAMS = indicator-sound-service -################### -# Indicator Stuff -################### - -soundmenulibdir = $(INDICATORDIR) -soundmenulib_LTLIBRARIES = libsoundmenu.la -libsoundmenu_la_SOURCES = \ - common-defs.h \ - indicator-sound.h \ - indicator-sound.c \ - sound-state.c \ - sound-state.h \ - sound-state-manager.c \ - sound-state-manager.h \ - transport-widget.c \ - transport-widget.h \ - metadata-widget.c \ - metadata-widget.h \ - mute-widget.c \ - mute-widget.h \ - volume-widget.c \ - volume-widget.h \ - voip-input-widget.c \ - voip-input-widget.h \ - gen-sound-service.xml.h \ - gen-sound-service.xml.c \ - dbus-shared-names.h - -libsoundmenu_la_CFLAGS = \ - $(APPLET_CFLAGS) \ - $(COVERAGE_CFLAGS) \ - -Wall -Werror -DG_LOG_DOMAIN=\"Indicator-Sound\" -libsoundmenu_la_LIBADD = $(APPLET_LIBS) -lm -libsoundmenu_la_LDFLAGS = \ - $(COVERAGE_LDFLAGS) \ - -module -avoid-version - - checkxml: $(srcdir)/sound-service.xml @xmllint -valid -noout $< @echo $< checks out ok diff --git a/src/indicator-sound.c b/src/indicator-sound.c deleted file mode 100644 index d21d722..0000000 --- a/src/indicator-sound.c +++ /dev/null @@ -1,834 +0,0 @@ -/* -Copyright 2010 Canonical Ltd. - -Authors: - Conor Curran - -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 . -*/ - -#include "config.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "indicator-sound.h" -#include "transport-widget.h" -#include "metadata-widget.h" -#include "volume-widget.h" -#include "voip-input-widget.h" -#include "dbus-shared-names.h" -#include "sound-state-manager.h" -#include "mute-widget.h" - -#include "gen-sound-service.xml.h" -#include "common-defs.h" - -typedef struct _IndicatorSoundPrivate IndicatorSoundPrivate; - -struct _IndicatorSoundPrivate -{ - GtkWidget* volume_widget; - GtkWidget* voip_widget; - MuteWidget *mute_widget; - GList* transport_widgets_list; - GDBusProxy *dbus_proxy; - SoundStateManager* state_manager; - gchar *accessible_desc; - GSettings *settings; -}; - -#define INDICATOR_SOUND_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), INDICATOR_SOUND_TYPE, IndicatorSoundPrivate)) - -#define SOUND_INDICATOR_GSETTINGS_SCHEMA_ID "com.canonical.indicator.sound" - -// GObject Boiler plate -INDICATOR_SET_VERSION -INDICATOR_SET_TYPE(INDICATOR_SOUND_TYPE) - -// GObject Boiler plate -static void indicator_sound_class_init (IndicatorSoundClass *klass); -static void indicator_sound_init (IndicatorSound *self); -static void indicator_sound_dispose (GObject *object); -static void indicator_sound_finalize (GObject *object); -G_DEFINE_TYPE (IndicatorSound, indicator_sound, INDICATOR_OBJECT_TYPE); - -//GTK+ items -static GtkLabel * get_label (IndicatorObject * io); -static GtkImage * get_icon (IndicatorObject * io); -static GtkMenu * get_menu (IndicatorObject * io); -static const gchar * get_accessible_desc (IndicatorObject * io); -static const gchar * get_name_hint (IndicatorObject * io); -static void indicator_sound_scroll (IndicatorObject * io, - IndicatorObjectEntry * entry, gint delta, - IndicatorScrollDirection direction); -static void indicator_sound_middle_click (IndicatorObject * io, - IndicatorObjectEntry * entry, - guint time, gpointer data); - -//key/moust event handlers -static gboolean key_press_cb(GtkWidget* widget, GdkEventKey* event, gpointer data); -static gboolean key_release_cb(GtkWidget* widget, GdkEventKey* event, gpointer data); - -//custom widget realisation methods -static gboolean new_volume_slider_widget (DbusmenuMenuitem * newitem, - DbusmenuMenuitem * parent, - DbusmenuClient * client, - gpointer user_data); -static gboolean new_voip_slider_widget (DbusmenuMenuitem * newitem, - DbusmenuMenuitem * parent, - DbusmenuClient * client, - gpointer user_data); -static gboolean new_transport_widget (DbusmenuMenuitem * newitem, - DbusmenuMenuitem * parent, - DbusmenuClient * client, - gpointer user_data); -static gboolean new_metadata_widget (DbusmenuMenuitem * newitem, - DbusmenuMenuitem * parent, - DbusmenuClient * client, - gpointer user_data); -static gboolean new_mute_widget (DbusmenuMenuitem * newitem, - DbusmenuMenuitem * parent, - DbusmenuClient * client, - gpointer user_data); - -// DBUS communication -static GDBusNodeInfo *node_info = NULL; -static GDBusInterfaceInfo *interface_info = NULL; -static void create_connection_to_service (GObject *source_object, - GAsyncResult *res, - gpointer user_data); -static void connection_changed (IndicatorServiceManager * sm, - gboolean connected, - gpointer userdata); - -// Visiblity -static void settings_init (IndicatorSound * self); - - -static void -indicator_sound_class_init (IndicatorSoundClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->dispose = indicator_sound_dispose; - object_class->finalize = indicator_sound_finalize; - - IndicatorObjectClass *io_class = INDICATOR_OBJECT_CLASS(klass); - - g_type_class_add_private (klass, sizeof (IndicatorSoundPrivate)); - - io_class->get_label = get_label; - io_class->get_image = get_icon; - io_class->get_menu = get_menu; - io_class->get_accessible_desc = get_accessible_desc; - io_class->get_name_hint = get_name_hint; - io_class->entry_scrolled = indicator_sound_scroll; - io_class->secondary_activate = indicator_sound_middle_click; -} - -static void -indicator_sound_init (IndicatorSound *self) -{ - self->service = NULL; - self->service = indicator_service_manager_new_version(INDICATOR_SOUND_DBUS_NAME, - INDICATOR_SOUND_DBUS_VERSION); - - IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(self); - priv->volume_widget = NULL; - priv->voip_widget = NULL; - priv->mute_widget = NULL; - priv->dbus_proxy = NULL; - GList* t_list = NULL; - priv->transport_widgets_list = t_list; - priv->state_manager = g_object_new (SOUND_TYPE_STATE_MANAGER, NULL); - priv->accessible_desc = NULL; - priv->settings = NULL; - - settings_init (self); - - g_signal_connect ( G_OBJECT(self->service), - INDICATOR_SERVICE_MANAGER_SIGNAL_CONNECTION_CHANGE, - G_CALLBACK(connection_changed), self ); -} - -static void -indicator_sound_dispose (GObject *object) -{ - IndicatorSound * self = INDICATOR_SOUND(object); - IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(self); - - if (priv->settings != NULL) { - g_object_unref (G_OBJECT(priv->settings)); - priv->settings = NULL; - } - - if (self->service != NULL) { - g_object_unref(G_OBJECT(self->service)); - self->service = NULL; - } - g_list_free (priv->transport_widgets_list); - - G_OBJECT_CLASS (indicator_sound_parent_class)->dispose (object); -} - -static void -indicator_sound_finalize (GObject *object) -{ - IndicatorSound * self = INDICATOR_SOUND(object); - IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(self); - - if (priv->accessible_desc) { - g_free (priv->accessible_desc); - priv->accessible_desc = NULL; - } - - G_OBJECT_CLASS (indicator_sound_parent_class)->finalize (object); -} - -static GtkLabel * -get_label (IndicatorObject * io) -{ - return NULL; -} - -static GtkImage * -get_icon (IndicatorObject * io) -{ - IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(INDICATOR_SOUND (io)); - gtk_widget_show( GTK_WIDGET(sound_state_manager_get_current_icon (priv->state_manager)) ); - return sound_state_manager_get_current_icon (priv->state_manager); -} - -/* Indicator based function to get the menu for the whole - applet. This starts up asking for the parts of the menu - from the various services. */ -static GtkMenu * -get_menu (IndicatorObject * io) -{ - DbusmenuGtkMenu* menu = dbusmenu_gtkmenu_new(INDICATOR_SOUND_DBUS_NAME, - INDICATOR_SOUND_MENU_DBUS_OBJECT_PATH); - - DbusmenuGtkClient *client = dbusmenu_gtkmenu_get_client(menu); - g_object_set_data (G_OBJECT (client), "indicator", io); - dbusmenu_client_add_type_handler (DBUSMENU_CLIENT(client), - DBUSMENU_VOLUME_MENUITEM_TYPE, - new_volume_slider_widget); - dbusmenu_client_add_type_handler (DBUSMENU_CLIENT(client), - DBUSMENU_VOIP_INPUT_MENUITEM_TYPE, - new_voip_slider_widget); - dbusmenu_client_add_type_handler (DBUSMENU_CLIENT(client), - DBUSMENU_TRANSPORT_MENUITEM_TYPE, - new_transport_widget); - dbusmenu_client_add_type_handler (DBUSMENU_CLIENT(client), - DBUSMENU_METADATA_MENUITEM_TYPE, - new_metadata_widget); - dbusmenu_client_add_type_handler (DBUSMENU_CLIENT(client), - DBUSMENU_MUTE_MENUITEM_TYPE, - new_mute_widget); - // Note: Not ideal but all key handling needs to be managed here and then - // delegated to the appropriate widget. - g_signal_connect (menu, "key-press-event", G_CALLBACK(key_press_cb), io); - g_signal_connect (menu, "key-release-event", G_CALLBACK(key_release_cb), io); - - return GTK_MENU(menu); -} - -static const gchar * -get_accessible_desc (IndicatorObject * io) -{ - IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(io); - return priv->accessible_desc; -} - -static const gchar *get_name_hint (IndicatorObject * io) -{ - return PACKAGE_NAME; -} - -static void -connection_changed (IndicatorServiceManager * sm, - gboolean connected, - gpointer user_data) -{ - IndicatorSound* indicator = INDICATOR_SOUND(user_data); - g_return_if_fail ( IS_INDICATOR_SOUND (indicator) ); - IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE (indicator); - GError *error = NULL; - - if (connected == FALSE){ - sound_state_manager_deal_with_disconnect (priv->state_manager); - return; - //TODO: Gracefully handle disconnection - // do a timeout to wait for reconnection - // for 5 seconds and then if no connection message - // is received put the state at 'sink not available' - } - // If the proxy is not null and connected is true => its a reconnect, - // we don't need to anything, gdbus takes care of the rest - bless. - // just fetch the state. - if (priv->dbus_proxy != NULL){ - g_dbus_proxy_call ( priv->dbus_proxy, - "GetSoundState", - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - (GAsyncReadyCallback)sound_state_manager_get_state_cb, - priv->state_manager); - return; - } - - if ( node_info == NULL ){ - node_info = g_dbus_node_info_new_for_xml ( _sound_service, - &error ); - if (error != NULL) { - g_critical ( "Failed to get create interface info from xml: %s", - error->message ); - g_error_free(error); - return; - } - } - - if (interface_info == NULL) { - interface_info = g_dbus_node_info_lookup_interface (node_info, - INDICATOR_SOUND_DBUS_INTERFACE); - if (interface_info == NULL) { - g_critical ("Unable to find interface '" INDICATOR_SOUND_DBUS_INTERFACE "'"); - } - } - - g_dbus_proxy_new_for_bus( G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_NONE, - interface_info, - INDICATOR_SOUND_DBUS_NAME, - INDICATOR_SOUND_SERVICE_DBUS_OBJECT_PATH, - INDICATOR_SOUND_DBUS_INTERFACE, - NULL, - create_connection_to_service, - indicator ); -} - -static void create_connection_to_service (GObject *source_object, - GAsyncResult *res, - gpointer user_data) -{ - IndicatorSound *self = INDICATOR_SOUND(user_data); - GError *error = NULL; - - g_return_if_fail( IS_INDICATOR_SOUND(self) ); - - IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(self); - - priv->dbus_proxy = g_dbus_proxy_new_finish(res, &error); - - if (error != NULL) { - g_critical ("Failed to get dbus proxy: %s", error->message); - g_error_free(error); - return; - } - sound_state_manager_connect_to_dbus (priv->state_manager, - priv->dbus_proxy); - -} - -static gboolean -new_transport_widget (DbusmenuMenuitem * newitem, - DbusmenuMenuitem * parent, - DbusmenuClient * client, - gpointer user_data) -{ - g_debug("indicator-sound: new_transport_bar() called "); - - GtkWidget* bar = NULL; - IndicatorObject *io = NULL; - - g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE); - g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE); - - bar = transport_widget_new(newitem); - io = g_object_get_data (G_OBJECT (client), "indicator"); - IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(INDICATOR_SOUND (io)); - priv->transport_widgets_list = g_list_append ( priv->transport_widgets_list, bar ); - - GtkMenuItem *menu_transport_bar = GTK_MENU_ITEM(bar); - - gtk_widget_show_all(bar); - dbusmenu_gtkclient_newitem_base (DBUSMENU_GTKCLIENT(client), - newitem, - menu_transport_bar, - parent); - return TRUE; -} - -static gboolean -new_metadata_widget (DbusmenuMenuitem * newitem, - DbusmenuMenuitem * parent, - DbusmenuClient * client, - gpointer user_data) -{ - g_debug("indicator-sound: new_metadata_widget"); - - GtkWidget* metadata = NULL; - - g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE); - g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE); - - - metadata = metadata_widget_new (newitem); - - g_debug ("%s (\"%s\")", __func__, - dbusmenu_menuitem_property_get(newitem, DBUSMENU_METADATA_MENUITEM_PLAYER_NAME)); - - GtkMenuItem *menu_metadata_widget = GTK_MENU_ITEM(metadata); - - gtk_widget_show_all(metadata); - dbusmenu_gtkclient_newitem_base (DBUSMENU_GTKCLIENT(client), - newitem, - menu_metadata_widget, - parent); - return TRUE; -} - -static gboolean -new_volume_slider_widget(DbusmenuMenuitem * newitem, - DbusmenuMenuitem * parent, - DbusmenuClient * client, - gpointer user_data) -{ - g_debug("indicator-sound: new_volume_slider_widget"); - - GtkWidget* volume_widget = NULL; - IndicatorObject *io = NULL; - - g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE); - g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE); - - io = g_object_get_data (G_OBJECT (client), "indicator"); - IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(INDICATOR_SOUND (io)); - - if (priv->volume_widget != NULL){ - volume_widget_tidy_up (priv->volume_widget); - gtk_widget_destroy (priv->volume_widget); - priv->volume_widget = NULL; - } - volume_widget = volume_widget_new (newitem, io); - priv->volume_widget = volume_widget; - // Don't forget to set the accessible desc. - update_accessible_desc (io); - - - GtkWidget* ido_slider_widget = volume_widget_get_ido_slider(VOLUME_WIDGET(priv->volume_widget)); - - gtk_widget_show_all(ido_slider_widget); - // register the style callback on this widget with state manager's style change - // handler (needs to remake the blocking animation for each style). - g_signal_connect (ido_slider_widget, "style-set", - G_CALLBACK(sound_state_manager_style_changed_cb), - priv->state_manager); - - GtkMenuItem *menu_volume_item = GTK_MENU_ITEM(ido_slider_widget); - dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), - newitem, - menu_volume_item, - parent); - return TRUE; -} -/** - * new_voip_slider_widget - * Create the voip menu item widget, must of the time this widget will be hidden. - * @param newitem - * @param parent - * @param client - * @param user_data - * @return - */ -static gboolean -new_voip_slider_widget (DbusmenuMenuitem * newitem, - DbusmenuMenuitem * parent, - DbusmenuClient * client, - gpointer user_data) -{ - g_debug("indicator-sound: new_voip_slider_widget"); - GtkWidget* voip_widget = NULL; - IndicatorObject *io = NULL; - - g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE); - g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE); - - io = g_object_get_data (G_OBJECT (client), "indicator"); - IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(INDICATOR_SOUND (io)); - - if (priv->voip_widget != NULL){ - voip_input_widget_tidy_up (priv->voip_widget); - gtk_widget_destroy (priv->voip_widget); - priv->voip_widget = NULL; - } - - voip_widget = voip_input_widget_new (newitem); - priv->voip_widget = voip_widget; - - GtkWidget* ido_slider_widget = voip_input_widget_get_ido_slider(VOIP_INPUT_WIDGET(voip_widget)); - - gtk_widget_show_all(ido_slider_widget); - - GtkMenuItem *menu_volume_item = GTK_MENU_ITEM(ido_slider_widget); - dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), - newitem, - menu_volume_item, - parent); - return TRUE; -} - -static gboolean -new_mute_widget(DbusmenuMenuitem * newitem, - DbusmenuMenuitem * parent, - DbusmenuClient * client, - gpointer user_data) -{ - IndicatorObject *io = NULL; - - g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE); - g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE); - - io = g_object_get_data (G_OBJECT (client), "indicator"); - IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(INDICATOR_SOUND (io)); - - if (priv->mute_widget != NULL){ - g_object_unref (priv->mute_widget); - priv->mute_widget = NULL; - } - - priv->mute_widget = mute_widget_new(newitem); - GtkMenuItem *item = mute_widget_get_menu_item (priv->mute_widget); - - dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), - newitem, - item, - parent); - - return TRUE; -} - -/*******************************************************************/ -//UI callbacks -/******************************************************************/ - -static GtkWidget * -get_current_item (GtkContainer * container) -{ - GList *children = gtk_container_get_children (container); - GList *iter; - GtkWidget *rv = NULL; - - /* Suprisingly, GTK+ doesn't really let us query "what is the currently - selected item?". But it does note it internally by prelighting the - widget, so we watch for that. */ - for (iter = children; iter; iter = iter->next) { - if (gtk_widget_get_state (GTK_WIDGET (iter->data)) & GTK_STATE_PRELIGHT) { - rv = GTK_WIDGET (iter->data); - break; - } - } - - return rv; -} - -/** -key_press_cb: -**/ -static gboolean -key_press_cb(GtkWidget* widget, GdkEventKey* event, gpointer data) -{ - gboolean digested = FALSE; - - g_return_val_if_fail(IS_INDICATOR_SOUND(data), FALSE); - - IndicatorSound *indicator = INDICATOR_SOUND (data); - - IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(indicator); - GtkWidget *menuitem; - menuitem = get_current_item (GTK_CONTAINER (widget)); - - if (IDO_IS_SCALE_MENU_ITEM(menuitem) == TRUE){ - gdouble current_value = 0; - gdouble new_value = 0; - const gdouble five_percent = 5; - gboolean is_voip_slider = FALSE; - - if (g_ascii_strcasecmp (ido_scale_menu_item_get_primary_label (IDO_SCALE_MENU_ITEM(menuitem)), "VOLUME") == 0) { - g_debug ("vOLUME SLIDER KEY PRESS"); - GtkWidget* slider_widget = volume_widget_get_ido_slider(VOLUME_WIDGET(priv->volume_widget)); - GtkWidget* slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)slider_widget); - GtkRange* range = (GtkRange*)slider; - g_return_val_if_fail(GTK_IS_RANGE(range), FALSE); - current_value = gtk_range_get_value(range); - new_value = current_value; - } - else if (g_ascii_strcasecmp (ido_scale_menu_item_get_primary_label (IDO_SCALE_MENU_ITEM(menuitem)), "VOIP") == 0) { - g_debug ("VOIP SLIDER KEY PRESS"); - GtkWidget* slider_widget = voip_input_widget_get_ido_slider(VOIP_INPUT_WIDGET(priv->voip_widget)); - GtkWidget* slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)slider_widget); - GtkRange* range = (GtkRange*)slider; - g_return_val_if_fail(GTK_IS_RANGE(range), FALSE); - current_value = gtk_range_get_value(range); - new_value = current_value; - is_voip_slider = TRUE; - } - - switch (event->keyval) { - case GDK_KEY_Right: - digested = TRUE; - new_value = current_value + five_percent; - break; - case GDK_KEY_Left: - digested = TRUE; - new_value = current_value - five_percent; - break; - case GDK_KEY_plus: - digested = TRUE; - new_value = current_value + five_percent; - break; - case GDK_KEY_minus: - digested = TRUE; - new_value = current_value - five_percent; - break; - default: - break; - } - new_value = CLAMP(new_value, 0, 100); - if (new_value != current_value){ - if (is_voip_slider == TRUE){ - voip_input_widget_update (VOIP_INPUT_WIDGET(priv->voip_widget), new_value); - } - else{ - volume_widget_update (VOLUME_WIDGET(priv->volume_widget), new_value, "keypress-update"); - } - } - } - else if (IS_TRANSPORT_WIDGET(menuitem) == TRUE) { - TransportWidget* transport_widget = NULL; - GList* elem; - - for ( elem = priv->transport_widgets_list; elem; elem = elem->next ) { - transport_widget = TRANSPORT_WIDGET ( elem->data ); - if ( transport_widget_is_selected( transport_widget ) ) - break; - } - - switch (event->keyval) { - case GDK_KEY_Right: - transport_widget_react_to_key_press_event ( transport_widget, - TRANSPORT_ACTION_NEXT ); - digested = TRUE; - break; - case GDK_KEY_Left: - transport_widget_react_to_key_press_event ( transport_widget, - TRANSPORT_ACTION_PREVIOUS ); - digested = TRUE; - break; - case GDK_KEY_space: - transport_widget_react_to_key_press_event ( transport_widget, - TRANSPORT_ACTION_PLAY_PAUSE ); - digested = TRUE; - break; - case GDK_KEY_Up: - case GDK_KEY_Down: - digested = FALSE; - break; - default: - break; - } - } - return digested; -} - - -/** -key_release_cb: -**/ -static gboolean -key_release_cb(GtkWidget* widget, GdkEventKey* event, gpointer data) -{ - gboolean digested = FALSE; - - g_return_val_if_fail(IS_INDICATOR_SOUND(data), FALSE); - - IndicatorSound *indicator = INDICATOR_SOUND (data); - - IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(indicator); - - GtkWidget *menuitem; - - menuitem = get_current_item (GTK_CONTAINER (widget)); - if (IS_TRANSPORT_WIDGET(menuitem) == TRUE) { - TransportWidget* transport_widget = NULL; - GList* elem; - - for(elem = priv->transport_widgets_list; elem; elem = elem->next) { - transport_widget = TRANSPORT_WIDGET (elem->data); - if ( transport_widget_is_selected( transport_widget ) ) - break; - } - - switch (event->keyval) { - case GDK_KEY_Right: - transport_widget_react_to_key_release_event ( transport_widget, - TRANSPORT_ACTION_NEXT ); - digested = TRUE; - break; - case GDK_KEY_Left: - transport_widget_react_to_key_release_event ( transport_widget, - TRANSPORT_ACTION_PREVIOUS ); - digested = TRUE; - break; - case GDK_KEY_space: - transport_widget_react_to_key_release_event ( transport_widget, - TRANSPORT_ACTION_PLAY_PAUSE ); - digested = TRUE; - break; - case GDK_KEY_Up: - case GDK_KEY_Down: - digested = FALSE; - break; - default: - break; - } - } - return digested; -} - -static void -indicator_sound_scroll (IndicatorObject * io, IndicatorObjectEntry * entry, - gint delta, IndicatorScrollDirection direction) -{ - //g_debug("indicator-sound-scroll - current slider value"); - IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(INDICATOR_SOUND (io)); - SoundState current_state = sound_state_manager_get_current_state (priv->state_manager); - - if (current_state == UNAVAILABLE || current_state == MUTED) - return; - - GtkWidget* slider_widget = volume_widget_get_ido_slider(VOLUME_WIDGET(priv->volume_widget)); - GtkWidget* slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)slider_widget); - GtkRange* range = (GtkRange*)slider; - g_return_if_fail(GTK_IS_RANGE(range)); - - gdouble value = gtk_range_get_value(range); - GtkAdjustment *adj = gtk_range_get_adjustment (GTK_RANGE (slider)); - //g_debug("indicator-sound-scroll - current slider value %f", value); - if (direction == INDICATOR_OBJECT_SCROLL_UP) { - value += gtk_adjustment_get_step_increment (adj); - } else { - value -= gtk_adjustment_get_step_increment (adj); - } - //g_debug("indicator-sound-scroll - update slider with value %f", value); - volume_widget_update(VOLUME_WIDGET(priv->volume_widget), value, "scroll updates"); - - if (!gtk_widget_get_mapped(GTK_WIDGET (entry->menu))) - sound_state_manager_show_notification (priv->state_manager, value); -} - -static void -indicator_sound_middle_click (IndicatorObject * io, IndicatorObjectEntry * entry, - guint time, gpointer data) -{ - IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(io); - g_return_if_fail (priv); - - mute_widget_toggle(priv->mute_widget); -} - -void -update_accessible_desc (IndicatorObject * io) -{ - GList *entries = indicator_object_get_entries(io); - if (!entries) - return; - IndicatorObjectEntry * entry = (IndicatorObjectEntry *)entries->data; - - IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(io); - gchar *old_desc = priv->accessible_desc; - - if (priv->volume_widget) { - priv->accessible_desc = g_strdup_printf(_("Volume (%'.0f%%)"), - volume_widget_get_current_volume (priv->volume_widget)); - } - else { - priv->accessible_desc = NULL; - } - - entry->accessible_desc = priv->accessible_desc; - g_free (old_desc); - g_signal_emit(G_OBJECT(io), - INDICATOR_OBJECT_SIGNAL_ACCESSIBLE_DESC_UPDATE_ID, - 0, - entry, - TRUE); - g_list_free(entries); -} - -/*** -**** -***/ - -#define VISIBLE_KEY "visible" - -static void -on_visible_changed (GSettings * settings, gchar * key, gpointer user_data) -{ - g_return_if_fail (!g_strcmp0 (key, VISIBLE_KEY)); - - IndicatorObject * io = INDICATOR_OBJECT(user_data); - const gboolean visible = g_settings_get_boolean (settings, key); - indicator_object_set_visible (io, visible); - if (visible) - update_accessible_desc (io); // requires an entry -} - -static void -settings_init (IndicatorSound *self) -{ - const char * schema = SOUND_INDICATOR_GSETTINGS_SCHEMA_ID; - - gint i; - gboolean schema_exists = FALSE; - const char * const * schemas = g_settings_list_schemas (); - for (i=0; !schema_exists && schemas && schemas[i]; i++) - if (!g_strcmp0 (schema, schemas[i])) - schema_exists = TRUE; - - IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(self); - if (schema_exists) { - priv->settings = g_settings_new (schema); - } else { - priv->settings = NULL; - } - - if (priv->settings != NULL) { - g_signal_connect (G_OBJECT(priv->settings), "changed::" VISIBLE_KEY, - G_CALLBACK(on_visible_changed), self); - const gboolean b = g_settings_get_boolean (priv->settings, VISIBLE_KEY); - g_object_set (G_OBJECT(self), - "indicator-object-default-visibility", b, - NULL); - } -} diff --git a/src/indicator-sound.h b/src/indicator-sound.h deleted file mode 100644 index c945efa..0000000 --- a/src/indicator-sound.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef __INCLUDE_INDICATOR_SOUND_H__ -#define __INCLUDE_INDICATOR_SOUND_H__ - -/* -A small wrapper utility to load indicators and put them as menu items -into the gnome-panel using it's applet interface. - -Copyright 2010 Canonical Ltd. - -Authors: - Conor Curran - Ted Gould - -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 . -*/ -#include "config.h" - -#include -#include -#include - -#define INDICATOR_SOUND_TYPE (indicator_sound_get_type ()) -#define INDICATOR_SOUND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), INDICATOR_SOUND_TYPE, IndicatorSound)) -#define INDICATOR_SOUND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), INDICATOR_SOUND_TYPE, IndicatorSoundClass)) -#define IS_INDICATOR_SOUND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), INDICATOR_SOUND_TYPE)) -#define IS_INDICATOR_SOUND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), INDICATOR_SOUND_TYPE)) -#define INDICATOR_SOUND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), INDICATOR_SOUND_TYPE, IndicatorSoundClass)) - -typedef struct _IndicatorSound IndicatorSound; -typedef struct _IndicatorSoundClass IndicatorSoundClass; - -//GObject class struct -struct _IndicatorSoundClass { - IndicatorObjectClass parent_class; -}; - -//GObject instance struct -struct _IndicatorSound { - IndicatorObject parent; - IndicatorServiceManager *service; -}; - -// GObject Boiler plate -GType indicator_sound_get_type (void); - -// Update the accessible description -void update_accessible_desc (IndicatorObject * io); - -#endif diff --git a/src/metadata-widget.c b/src/metadata-widget.c deleted file mode 100644 index 812f340..0000000 --- a/src/metadata-widget.c +++ /dev/null @@ -1,880 +0,0 @@ -/* -Copyright 2010 Canonical Ltd. - -Authors: - Conor Curran - Mirco Müller - -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 . -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include "metadata-widget.h" -#include "common-defs.h" -#include -#include -#include "transport-widget.h" -#include - -typedef struct _MetadataWidgetPrivate MetadataWidgetPrivate; - -struct _MetadataWidgetPrivate -{ - gboolean theme_change_occured; - GtkWidget* meta_data_h_box; - GtkWidget* meta_data_v_box; - GtkWidget* album_art; - GString* image_path; - GString* old_image_path; - GtkWidget* artist_label; - GtkWidget* piece_label; - GtkWidget* container_label; - GtkWidget* player_label; - GtkWidget* player_icon; - DbusmenuMenuitem* twin_item; - gint current_height; -}; - -#define METADATA_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), METADATA_WIDGET_TYPE, MetadataWidgetPrivate)) - -/* Prototypes */ -static void metadata_widget_class_init (MetadataWidgetClass *klass); -static void metadata_widget_init (MetadataWidget *self); -static void metadata_widget_dispose (GObject *object); -static void metadata_widget_finalize (GObject *object); -static void metadata_widget_set_style (GtkWidget* button, GtkStyle* style); -static void metadata_widget_set_twin_item (MetadataWidget* self, - DbusmenuMenuitem* twin_item); -// keyevent consumers -static gboolean metadata_widget_button_release_event (GtkWidget *menuitem, - GdkEventButton *event); -// Dbusmenuitem properties update callback -static void metadata_widget_property_update (DbusmenuMenuitem* item, - gchar* property, - GVariant* value, - gpointer userdata); -static void metadata_widget_style_labels ( MetadataWidget* self, - GtkLabel* label); -static void draw_album_art_placeholder (GtkWidget *metadata); - -static void draw_album_border (GtkWidget *metadata, gboolean selected); -static void metadata_widget_selection_received_event_callback( GtkWidget *widget, - GtkSelectionData *data, - guint time, - gpointer user_data); - - - -#if GTK_CHECK_VERSION(3, 0, 0) -static void metadata_widget_get_preferred_width (GtkWidget* self, - gint* minimum_width, - gint* natural_width); -static gboolean metadata_widget_icon_triangle_draw_cb_gtk_3 (GtkWidget *image, - cairo_t* cr, - gpointer user_data); -static gboolean metadata_image_expose_gtk_3 (GtkWidget *image, - cairo_t* cr, - gpointer user_data); -#else -static gboolean metadata_widget_icon_triangle_draw_cb (GtkWidget *image, - GdkEventExpose *event, - gpointer user_data); -static gboolean metadata_image_expose (GtkWidget *image, - GdkEventExpose *event, - gpointer user_data); -#endif - -static void metadata_widget_set_icon (MetadataWidget *self); -static void metadata_widget_handle_resizing (MetadataWidget* self); - - -G_DEFINE_TYPE (MetadataWidget, metadata_widget, GTK_TYPE_MENU_ITEM); - -static void -metadata_widget_class_init (MetadataWidgetClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); - - widget_class->button_release_event = metadata_widget_button_release_event; - #if GTK_CHECK_VERSION(3, 0, 0) - widget_class->get_preferred_width = metadata_widget_get_preferred_width; - #endif - g_type_class_add_private (klass, sizeof (MetadataWidgetPrivate)); - - gobject_class->dispose = metadata_widget_dispose; - gobject_class->finalize = metadata_widget_finalize; -} - -static void -metadata_widget_init (MetadataWidget *self) -{ - MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(self); - GtkWidget *hbox; - GtkWidget *outer_v_box; - - #if GTK_CHECK_VERSION(3, 0, 0) - outer_v_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); - #else - outer_v_box = gtk_vbox_new (FALSE, 0); - #endif - - #if GTK_CHECK_VERSION(3, 0, 0) - hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); - #else - hbox = gtk_hbox_new(FALSE, 0); - #endif - - priv->meta_data_h_box = hbox; - priv->current_height = 1; - - // image - priv->album_art = gtk_image_new(); - priv->image_path = g_string_new(""); - priv->old_image_path = g_string_new(""); - - #if GTK_CHECK_VERSION(3, 0, 0) - g_signal_connect(priv->album_art, "draw", - G_CALLBACK(metadata_image_expose_gtk_3), - GTK_WIDGET(self)); - - g_signal_connect_after (GTK_WIDGET(self), "draw", - G_CALLBACK(metadata_widget_icon_triangle_draw_cb_gtk_3), - GTK_WIDGET(self)); - #else - g_signal_connect(priv->album_art, "expose-event", - G_CALLBACK(metadata_image_expose), - GTK_WIDGET(self)); - - g_signal_connect_after (GTK_WIDGET(self), "expose-event", - G_CALLBACK(metadata_widget_icon_triangle_draw_cb), - GTK_WIDGET(self)); - #endif - gtk_box_pack_start (GTK_BOX (priv->meta_data_h_box), - priv->album_art, - FALSE, - FALSE, - 1); - priv->theme_change_occured = FALSE; - - #if GTK_CHECK_VERSION(3, 0, 0) - GtkWidget* vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); - #else - GtkWidget* vbox = gtk_vbox_new(FALSE, 0); - #endif - - // artist - GtkWidget* artist; - artist = gtk_label_new(""); - gtk_misc_set_alignment(GTK_MISC(artist), (gfloat)0, (gfloat)0); - gtk_misc_set_padding (GTK_MISC(artist), (gfloat)10, (gfloat)0); - gtk_widget_set_size_request (artist, 140, 15); - - gtk_label_set_ellipsize(GTK_LABEL(artist), PANGO_ELLIPSIZE_MIDDLE); - metadata_widget_style_labels(self, GTK_LABEL(artist)); - priv->artist_label = artist; - - // title - GtkWidget* piece; - piece = gtk_label_new(""); - gtk_misc_set_alignment(GTK_MISC(piece), (gfloat)0, (gfloat)0); - gtk_misc_set_padding (GTK_MISC(piece), (gfloat)10, (gfloat)-5); - - gtk_widget_set_size_request (piece, 140, 15); - gtk_label_set_ellipsize(GTK_LABEL(piece), PANGO_ELLIPSIZE_MIDDLE); - metadata_widget_style_labels(self, GTK_LABEL(piece)); - priv->piece_label = piece; - - // container - GtkWidget* container; - container = gtk_label_new(""); - gtk_misc_set_alignment(GTK_MISC(container), (gfloat)0, (gfloat)0); - gtk_misc_set_padding (GTK_MISC(container), (gfloat)10, (gfloat)0); - gtk_widget_set_size_request (container, 140, 15); - - gtk_label_set_ellipsize(GTK_LABEL(container), PANGO_ELLIPSIZE_MIDDLE); - metadata_widget_style_labels(self, GTK_LABEL(container)); - priv->container_label = container; - - gtk_box_pack_start (GTK_BOX (vbox), priv->piece_label, FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (vbox), priv->artist_label, FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (vbox), priv->container_label, FALSE, FALSE, 0); - - gtk_box_pack_start (GTK_BOX (priv->meta_data_h_box), vbox, FALSE, FALSE, 0); - - g_signal_connect(self, "style-set", - G_CALLBACK(metadata_widget_set_style), GTK_WIDGET(self)); - g_signal_connect (self, "selection-received", - G_CALLBACK(metadata_widget_selection_received_event_callback), - GTK_WIDGET(self)); - - gint padding = 4; - gtk_widget_style_get(GTK_WIDGET(self), "toggle-spacing", &padding, NULL); - -#if GTK_CHECK_VERSION(3, 0, 0) - GtkWidget * tophbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, padding); -#else - GtkWidget * tophbox = gtk_hbox_new(FALSE, padding); -#endif - - GtkWidget *player_icon; - player_icon = gtk_image_new(); - priv->player_icon = player_icon; - - gtk_misc_set_alignment (GTK_MISC(priv->player_icon), 1.0 /* right aligned */, 0.5); - gtk_box_pack_start (GTK_BOX (tophbox), priv->player_icon, FALSE, FALSE, 0); - GtkWidget* spacer; - spacer = gtk_alignment_new (0,0,0,0); - gtk_container_add (GTK_CONTAINER (spacer), priv->meta_data_h_box); - gtk_alignment_set_padding (GTK_ALIGNMENT (spacer),5,0,0,0); - - // player label - GtkWidget* player_label; - player_label = gtk_label_new (""); - gtk_misc_set_alignment(GTK_MISC(player_label), (gfloat)0, 0.5); - priv->player_label = player_label; - gtk_box_pack_start (GTK_BOX (tophbox), priv->player_label, TRUE, TRUE, 0); - - gtk_box_pack_start (GTK_BOX(outer_v_box), tophbox, FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX(outer_v_box), spacer, FALSE, FALSE, 0); - - gtk_container_add (GTK_CONTAINER (self), outer_v_box); - - gtk_widget_show_all (priv->meta_data_h_box); - gtk_widget_set_no_show_all (priv->meta_data_h_box, TRUE); - - gtk_widget_hide (priv->meta_data_h_box); -} - -static void -metadata_widget_dispose (GObject *object) -{ - G_OBJECT_CLASS (metadata_widget_parent_class)->dispose (object); -} - -static void -metadata_widget_finalize (GObject *object) -{ - MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(METADATA_WIDGET(object)); - g_string_free (priv->image_path, TRUE); - g_string_free (priv->old_image_path, TRUE); - - G_OBJECT_CLASS (metadata_widget_parent_class)->finalize (object); -} - -/** -* Make sure to only clear the album art only when it is not empty -* Otherwise it will continuously call queue_draw after each empty call. -*/ -static void -clear_album_art (GtkImage* album_art) -{ - if (gtk_image_get_storage_type(album_art) != GTK_IMAGE_EMPTY){ - gtk_image_clear (album_art); - } -} - - -#if GTK_CHECK_VERSION(3, 0, 0) -static void -metadata_widget_get_preferred_width (GtkWidget* self, - gint* minimum_width, - gint* natural_width) -{ - *minimum_width = *natural_width = 200; -} - -/** - * We override the expose method to enable primitive drawing of the - * empty album art image. - */ -static gboolean -metadata_image_expose_gtk_3 (GtkWidget *metadata, - cairo_t* cr, - gpointer user_data) -{ - g_return_val_if_fail(IS_METADATA_WIDGET(user_data), FALSE); - MetadataWidget* widget = METADATA_WIDGET(user_data); - MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(widget); - - if ( TRUE == dbusmenu_menuitem_property_get_bool (DBUSMENU_MENUITEM(priv->twin_item), - DBUSMENU_METADATA_MENUITEM_HIDE_TRACK_DETAILS)) - { - return FALSE; - } - - if((guint)priv->image_path->len != 0){ - - if(g_string_equal (priv->image_path, priv->old_image_path) == FALSE || - priv->theme_change_occured == TRUE){ - priv->theme_change_occured = FALSE; - GdkPixbuf* pixbuf; - pixbuf = gdk_pixbuf_new_from_file_at_size(priv->image_path->str, 60, 60, NULL); - - if(GDK_IS_PIXBUF(pixbuf) == FALSE){ - clear_album_art (GTK_IMAGE(priv->album_art)); - gtk_widget_set_size_request(GTK_WIDGET(priv->album_art), 60, 60); - draw_album_border (metadata, FALSE); - draw_album_art_placeholder(metadata); - return FALSE; - } - - gtk_image_set_from_pixbuf(GTK_IMAGE(priv->album_art), pixbuf); - gtk_widget_set_size_request(GTK_WIDGET(priv->album_art), - gdk_pixbuf_get_width(pixbuf), - gdk_pixbuf_get_height(pixbuf)); - - draw_album_border (metadata, FALSE); - g_string_erase (priv->old_image_path, 0, -1); - g_string_overwrite (priv->old_image_path, 0, priv->image_path->str); - g_object_unref(pixbuf); - } - return FALSE; - } - clear_album_art (GTK_IMAGE(priv->album_art)); - g_string_erase (priv->old_image_path, 0, -1); - gtk_widget_set_size_request(GTK_WIDGET(priv->album_art), 60, 60); - draw_album_border (metadata, FALSE); - draw_album_art_placeholder(metadata); - return FALSE; -} - -// Draw the triangle if the player is running ... -static gboolean -metadata_widget_icon_triangle_draw_cb_gtk_3 (GtkWidget *widget, - cairo_t* cr, - gpointer user_data) -{ - g_return_val_if_fail (IS_METADATA_WIDGET (user_data), FALSE); - MetadataWidget* meta = METADATA_WIDGET (user_data); - MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(meta); - - gboolean running = dbusmenu_menuitem_property_get_bool (priv->twin_item, - DBUSMENU_METADATA_MENUITEM_PLAYER_RUNNING); - - if (!running) - return FALSE; - - GtkStyle *style; - int x, y, arrow_width, arrow_height; - - arrow_width = 5; - arrow_height = 9; - - style = gtk_widget_get_style (widget); - - GtkAllocation allocation; - gtk_widget_get_allocation (widget, &allocation); - x = allocation.x; - y = 0; - - // Draw triangle but only if the player is running. - y += gtk_image_get_pixel_size (GTK_IMAGE (priv->player_icon)) / 3 + 5; - cairo_set_line_width (cr, 1.0); - - cairo_move_to (cr, x, y); - cairo_line_to (cr, x, y + arrow_height); - cairo_line_to (cr, x + arrow_width, y + (double)arrow_height/2.0); - cairo_close_path (cr); - cairo_set_source_rgb (cr, style->fg[gtk_widget_get_state(widget)].red/65535.0, - style->fg[gtk_widget_get_state(widget)].green/65535.0, - style->fg[gtk_widget_get_state(widget)].blue/65535.0); - cairo_fill (cr); - - return FALSE; -} - -// GTK 2 Expose handler -#else - -static gboolean -metadata_image_expose (GtkWidget *metadata, - GdkEventExpose *event, - gpointer user_data) -{ - g_return_val_if_fail(IS_METADATA_WIDGET(user_data), FALSE); - MetadataWidget* widget = METADATA_WIDGET(user_data); - MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(widget); - - if ( TRUE == dbusmenu_menuitem_property_get_bool (DBUSMENU_MENUITEM(priv->twin_item), - DBUSMENU_METADATA_MENUITEM_HIDE_TRACK_DETAILS)) - { - return FALSE; - } - - draw_album_border(metadata, FALSE); - - if(priv->image_path->len > 0){ - if(g_string_equal(priv->image_path, priv->old_image_path) == FALSE || - priv->theme_change_occured == TRUE){ - priv->theme_change_occured = FALSE; - GdkPixbuf* pixbuf; - pixbuf = gdk_pixbuf_new_from_file_at_size(priv->image_path->str, 60, 60, NULL); - - if(GDK_IS_PIXBUF(pixbuf) == FALSE){ - clear_album_art (GTK_IMAGE(priv->album_art)); - gtk_widget_set_size_request(GTK_WIDGET(priv->album_art), 60, 60); - draw_album_art_placeholder(metadata); - return FALSE; - } - - gtk_image_set_from_pixbuf(GTK_IMAGE(priv->album_art), pixbuf); - gtk_widget_set_size_request(GTK_WIDGET(priv->album_art), - gdk_pixbuf_get_width(pixbuf), - gdk_pixbuf_get_height(pixbuf)); - - g_string_erase (priv->old_image_path, 0, -1); - g_string_overwrite (priv->old_image_path, 0, priv->image_path->str); - g_object_unref(pixbuf); - } - return FALSE; - } - clear_album_art (GTK_IMAGE(priv->album_art)); - g_string_erase (priv->old_image_path, 0, -1); - gtk_widget_set_size_request(GTK_WIDGET(priv->album_art), 60, 60); - draw_album_art_placeholder(metadata); - return FALSE; -} - - -// Draw the triangle if the player is running ... -static gboolean -metadata_widget_icon_triangle_draw_cb (GtkWidget *widget, - GdkEventExpose *event, - gpointer user_data) -{ - g_return_val_if_fail(IS_METADATA_WIDGET(user_data), FALSE); - - MetadataWidget* meta = METADATA_WIDGET(user_data); - MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(meta); - - gboolean running = dbusmenu_menuitem_property_get_bool (priv->twin_item, - DBUSMENU_METADATA_MENUITEM_PLAYER_RUNNING); - - if (!running) - return FALSE; - - GtkStyle *style; - cairo_t *cr; - int x, y, arrow_width, arrow_height; - - arrow_width = 5; - arrow_height = 9; - - style = gtk_widget_get_style (widget); - - cr = (cairo_t*) gdk_cairo_create (gtk_widget_get_window (widget)); - - GtkAllocation allocation; - gtk_widget_get_allocation (widget, &allocation); - x = allocation.x; - y = allocation.y; - - // Draw triangle but only if the player is running. - y += allocation.height/2.0 - (double)arrow_height/2.0; - cairo_set_line_width (cr, 1.0); - - cairo_move_to (cr, x, y); - cairo_line_to (cr, x, y + arrow_height); - cairo_line_to (cr, x + arrow_width, y + (double)arrow_height/2.0); - cairo_close_path (cr); - cairo_set_source_rgb (cr, style->fg[gtk_widget_get_state(widget)].red/65535.0, - style->fg[gtk_widget_get_state(widget)].green/65535.0, - style->fg[gtk_widget_get_state(widget)].blue/65535.0); - cairo_fill (cr); - - cairo_destroy (cr); - return FALSE; -} -#endif - -static void -draw_album_border(GtkWidget *metadata, - gboolean selected) -{ - cairo_t *cr; - cr = gdk_cairo_create (gtk_widget_get_window (metadata)); - #if GTK_CHECK_VERSION(3, 0, 0) - gtk_style_context_add_class (gtk_widget_get_style_context (metadata), - "menu"); - #endif - - GtkStyle *style; - style = gtk_widget_get_style (metadata); - - GtkAllocation alloc; - gtk_widget_get_allocation (metadata, &alloc); - gint offset = 1; - - alloc.width = alloc.width + (offset * 2); - alloc.height = alloc.height + (offset * 2) - 7; - alloc.x = alloc.x - offset; - alloc.y = alloc.y - offset + 3; - - CairoColorRGB bg_normal, fg_normal; - - bg_normal.r = style->bg[0].red/65535.0; - bg_normal.g = style->bg[0].green/65535.0; - bg_normal.b = style->bg[0].blue/65535.0; - - const gint state = selected ? GTK_STATE_SELECTED : GTK_STATE_NORMAL; - - fg_normal.r = style->fg[state].red/65535.0; - fg_normal.g = style->fg[state].green/65535.0; - fg_normal.b = style->fg[state].blue/65535.0; - - CairoColorRGB dark_top_color; - CairoColorRGB light_bottom_color; - CairoColorRGB background_color; - - _color_shade ( &bg_normal, 0.93, &background_color ); - _color_shade ( &bg_normal, 0.23, &dark_top_color ); - _color_shade ( &fg_normal, 0.55, &light_bottom_color ); - - cairo_rectangle (cr, - alloc.x, alloc.y, - alloc.width, alloc.height); - - cairo_set_line_width (cr, 1.0); - - cairo_clip ( cr ); - - cairo_move_to (cr, alloc.x, alloc.y ); - cairo_line_to (cr, alloc.x + alloc.width, - alloc.y ); - cairo_line_to ( cr, alloc.x + alloc.width, - alloc.y + alloc.height ); - cairo_line_to ( cr, alloc.x, alloc.y + alloc.height ); - cairo_line_to ( cr, alloc.x, alloc.y); - cairo_close_path (cr); - - cairo_set_source_rgba ( cr, - background_color.r, - background_color.g, - background_color.b, - 1.0 ); - - cairo_fill ( cr ); - - cairo_move_to (cr, alloc.x, alloc.y ); - cairo_line_to (cr, alloc.x + alloc.width, - alloc.y ); - - cairo_close_path (cr); - cairo_set_source_rgba ( cr, - dark_top_color.r, - dark_top_color.g, - dark_top_color.b, - 1.0 ); - - cairo_stroke ( cr ); - - cairo_move_to ( cr, alloc.x + alloc.width, - alloc.y + alloc.height ); - cairo_line_to ( cr, alloc.x, alloc.y + alloc.height ); - - cairo_close_path (cr); - cairo_set_source_rgba ( cr, - light_bottom_color.r, - light_bottom_color.g, - light_bottom_color.b, - 1.0); - - cairo_stroke ( cr ); - cairo_destroy (cr); -} - -static void -draw_album_art_placeholder(GtkWidget *metadata) -{ - cairo_t *cr; - cr = gdk_cairo_create (gtk_widget_get_window (metadata)); - GtkStyle *style; - style = gtk_widget_get_style (metadata); - - GtkAllocation alloc; - gtk_widget_get_allocation (metadata, &alloc); - - PangoLayout *layout; - PangoFontDescription *desc; - layout = pango_cairo_create_layout(cr); - PangoContext* pcontext = pango_cairo_create_context(cr); - pango_cairo_context_set_resolution (pcontext, 96); - - GString* string = g_string_new(""); - gssize size = -1; - gunichar code = g_utf8_get_char_validated("\342\231\253", size); - g_string_append_unichar (string, code); - - pango_layout_set_text(layout, string->str, -1); - desc = pango_font_description_from_string("Sans Bold 30"); - pango_layout_set_font_description(layout, desc); - pango_font_description_free(desc); - - CairoColorRGB fg_normal, light_bottom_color; - - fg_normal.r = style->fg[0].red/65535.0; - fg_normal.g = style->fg[0].green/65535.0; - fg_normal.b = style->fg[0].blue/65535.0; - - _color_shade ( &fg_normal, 0.78, &light_bottom_color ); - - cairo_set_source_rgba (cr, - light_bottom_color.r, - light_bottom_color.g, - light_bottom_color.b, - 1.0); - - pango_cairo_update_layout(cr, layout); - cairo_move_to (cr, alloc.x + alloc.width/6, alloc.y + 3); - pango_cairo_show_layout(cr, layout); - - g_object_unref(layout); - g_object_unref(pcontext); - g_string_free (string, TRUE); - cairo_destroy (cr); -} - -static void -metadata_widget_selection_received_event_callback ( GtkWidget *widget, - GtkSelectionData *data, - guint time, - gpointer user_data ) - -{ - draw_album_border(widget, TRUE); -} - -/* Suppress/consume keyevents */ -static gboolean -metadata_widget_button_release_event (GtkWidget *menuitem, - GdkEventButton *event) -{ - g_return_val_if_fail (IS_METADATA_WIDGET (menuitem), FALSE); - MetadataWidgetPrivate* priv = METADATA_WIDGET_GET_PRIVATE(METADATA_WIDGET(menuitem)); - // For the left raise/launch the player - if (event->button == 1){ - GVariant* new_title_event = g_variant_new_boolean(TRUE); - dbusmenu_menuitem_handle_event (priv->twin_item, - "Title menu event", - new_title_event, - 0); - } - // For the right copy track details to clipboard only if the player is running - // and there is something there - else if (event->button == 3){ - gboolean running = dbusmenu_menuitem_property_get_bool (priv->twin_item, - DBUSMENU_METADATA_MENUITEM_PLAYER_RUNNING); - gboolean hidden = dbusmenu_menuitem_property_get_bool (priv->twin_item, - DBUSMENU_METADATA_MENUITEM_HIDE_TRACK_DETAILS); - g_return_val_if_fail ( running, FALSE ); - - g_return_val_if_fail ( !hidden, FALSE ); - - GtkClipboard* board = gtk_clipboard_get (GDK_NONE); - gchar* contents = g_strdup_printf("artist: %s \ntitle: %s \nalbum: %s", - dbusmenu_menuitem_property_get(priv->twin_item, - DBUSMENU_METADATA_MENUITEM_ARTIST), - dbusmenu_menuitem_property_get(priv->twin_item, - DBUSMENU_METADATA_MENUITEM_TITLE), - dbusmenu_menuitem_property_get(priv->twin_item, - DBUSMENU_METADATA_MENUITEM_ALBUM)); - gtk_clipboard_set_text (board, contents, -1); - gtk_clipboard_store (board); - g_free(contents); - } - return FALSE; -} - -static void -metadata_widget_property_update(DbusmenuMenuitem* item, gchar* property, - GVariant* value, gpointer userdata) -{ - g_return_if_fail (IS_METADATA_WIDGET (userdata)); - - if(g_variant_is_of_type(value, G_VARIANT_TYPE_INT32) == TRUE && - g_variant_get_int32(value) == DBUSMENU_PROPERTY_EMPTY){ - GVariant* new_value = g_variant_new_string (""); - value = new_value; - } - - MetadataWidget* mitem = METADATA_WIDGET(userdata); - MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(mitem); - - if(g_ascii_strcasecmp(DBUSMENU_METADATA_MENUITEM_ARTIST, property) == 0){ - gtk_label_set_text(GTK_LABEL(priv->artist_label), g_variant_get_string(value, NULL)); - metadata_widget_style_labels(mitem, GTK_LABEL(priv->artist_label)); - } - else if(g_ascii_strcasecmp(DBUSMENU_METADATA_MENUITEM_TITLE, property) == 0){ - gtk_label_set_text(GTK_LABEL(priv->piece_label), g_variant_get_string(value, NULL)); - metadata_widget_style_labels(mitem, GTK_LABEL(priv->piece_label)); - } - else if(g_ascii_strcasecmp(DBUSMENU_METADATA_MENUITEM_ALBUM, property) == 0){ - gtk_label_set_text(GTK_LABEL(priv->container_label), g_variant_get_string(value, NULL)); - metadata_widget_style_labels(mitem, GTK_LABEL(priv->container_label)); - } - else if(g_ascii_strcasecmp(DBUSMENU_METADATA_MENUITEM_ARTURL, property) == 0){ - g_string_erase(priv->image_path, 0, -1); - g_string_overwrite (priv->image_path, 0, g_variant_get_string (value, NULL)); - gtk_widget_queue_draw(GTK_WIDGET(mitem)); - } - else if (g_ascii_strcasecmp (DBUSMENU_METADATA_MENUITEM_PLAYER_NAME, property) == 0){ - gtk_label_set_label (GTK_LABEL (priv->player_label), - g_variant_get_string(value, NULL)); - } - else if (g_ascii_strcasecmp (DBUSMENU_METADATA_MENUITEM_PLAYER_ICON, property) == 0){ - metadata_widget_set_icon (mitem); - } - else if(g_ascii_strcasecmp(DBUSMENU_METADATA_MENUITEM_HIDE_TRACK_DETAILS, property) == 0){ - metadata_widget_handle_resizing (mitem); - } -} - -static void -metadata_widget_handle_resizing (MetadataWidget* self) -{ - MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(self); - - if (dbusmenu_menuitem_property_get_bool (priv->twin_item, - DBUSMENU_METADATA_MENUITEM_HIDE_TRACK_DETAILS) == TRUE){ - gtk_widget_hide (priv->meta_data_h_box); - } - else{ - gtk_widget_show (priv->meta_data_h_box); - } - gtk_widget_queue_draw(GTK_WIDGET(self)); -} - -static void -metadata_widget_style_labels(MetadataWidget* self, GtkLabel* label) -{ - char* markup; - markup = g_markup_printf_escaped ("%s", - gtk_label_get_text(GTK_LABEL(label))); - gtk_label_set_markup (GTK_LABEL (label), markup); - g_free(markup); -} - -static void -metadata_widget_set_style(GtkWidget* metadata, GtkStyle* style) -{ - g_return_if_fail(IS_METADATA_WIDGET(metadata)); - MetadataWidget* widg = METADATA_WIDGET(metadata); - MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(widg); - priv->theme_change_occured = TRUE; - gtk_widget_queue_draw (GTK_WIDGET(metadata)); -} - -static void -metadata_widget_set_icon (MetadataWidget *self) -{ - MetadataWidgetPrivate * priv = METADATA_WIDGET_GET_PRIVATE(self); - - GString* banshee_string = g_string_new ( "banshee" ); - gchar * tmp = g_utf8_strdown (dbusmenu_menuitem_property_get(priv->twin_item, DBUSMENU_METADATA_MENUITEM_PLAYER_NAME), -1); - GString* app_panel = g_string_new (tmp); - g_free (tmp); - - // Banshee Special case! - // Not ideal but apparently we want the banshee icon to be the greyscale one - // and any others to be the icon from the desktop file => colour. - if ( g_string_equal ( banshee_string, app_panel ) == TRUE && - gtk_icon_theme_has_icon ( gtk_icon_theme_get_default(), app_panel->str ) ){ - g_string_append ( app_panel, "-panel" ); - } - else{ - // Otherwise use what is stored in the props - g_string_erase (app_panel, 0, -1); - g_string_overwrite (app_panel, - 0, - dbusmenu_menuitem_property_get ( priv->twin_item, - DBUSMENU_METADATA_MENUITEM_PLAYER_ICON )); - } - - const GtkIconSize icon_size = GTK_ICON_SIZE_MENU; - if (g_path_is_absolute(app_panel->str) && g_file_test (app_panel->str, G_FILE_TEST_IS_REGULAR)){ - gint width, height; - gtk_icon_size_lookup (icon_size, &width, &height); - GdkPixbuf *pix = gdk_pixbuf_new_from_file_at_scale(app_panel->str, width, height, TRUE, NULL); - gtk_image_set_from_pixbuf (GTK_IMAGE (priv->player_icon), pix); - g_object_unref (pix); - } - else{ - gtk_image_set_from_icon_name(GTK_IMAGE (priv->player_icon), app_panel->str, icon_size); - } - - g_string_free ( app_panel, TRUE); - g_string_free ( banshee_string, TRUE); -} - -static void -metadata_widget_set_twin_item (MetadataWidget* self, - DbusmenuMenuitem* twin_item) -{ - MetadataWidgetPrivate* priv = METADATA_WIDGET_GET_PRIVATE(self); - priv->twin_item = twin_item; - g_signal_connect( G_OBJECT(priv->twin_item), "property-changed", - G_CALLBACK(metadata_widget_property_update), self); - gtk_label_set_text( GTK_LABEL(priv->container_label), - dbusmenu_menuitem_property_get( priv->twin_item, - DBUSMENU_METADATA_MENUITEM_ALBUM)); - metadata_widget_style_labels( self, GTK_LABEL(priv->container_label)); - - gtk_label_set_text( GTK_LABEL(priv->piece_label), - dbusmenu_menuitem_property_get( priv->twin_item, - DBUSMENU_METADATA_MENUITEM_TITLE)); - metadata_widget_style_labels( self, GTK_LABEL(priv->piece_label)); - gtk_label_set_text( GTK_LABEL(priv->artist_label), - dbusmenu_menuitem_property_get( priv->twin_item, - DBUSMENU_METADATA_MENUITEM_ARTIST)); - metadata_widget_style_labels( self, GTK_LABEL(priv->artist_label)); - - g_string_erase(priv->image_path, 0, -1); - const gchar *arturl = dbusmenu_menuitem_property_get( priv->twin_item, - DBUSMENU_METADATA_MENUITEM_ARTURL ); - - gtk_label_set_label (GTK_LABEL(priv->player_label), - dbusmenu_menuitem_property_get(priv->twin_item, - DBUSMENU_METADATA_MENUITEM_PLAYER_NAME)); - - metadata_widget_set_icon(self); - - if (arturl != NULL){ - g_string_overwrite( priv->image_path, - 0, - arturl); - // if its a remote image queue a redraw incase the download took too long - if (g_str_has_prefix (arturl, g_get_user_cache_dir())){ - gtk_widget_queue_draw(GTK_WIDGET(self)); - } - } - metadata_widget_handle_resizing (self); -} - - /** - * transport_new: - * @returns: a new #MetadataWidget. - **/ -GtkWidget* -metadata_widget_new(DbusmenuMenuitem *item) -{ - GtkWidget* widget = g_object_new(METADATA_WIDGET_TYPE, NULL); - metadata_widget_set_twin_item ( METADATA_WIDGET(widget), - item ); - return widget; -} - diff --git a/src/metadata-widget.h b/src/metadata-widget.h deleted file mode 100644 index fc6944e..0000000 --- a/src/metadata-widget.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -Copyright 2010 Canonical Ltd. - -Authors: - Conor Curran - -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 . -*/ -#ifndef __METADATA_WIDGET_H__ -#define __METADATA_WIDGET_H__ - -#include -#include - -G_BEGIN_DECLS - -#define METADATA_WIDGET_TYPE (metadata_widget_get_type ()) -#define METADATA_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), METADATA_WIDGET_TYPE, MetadataWidget)) -#define METADATA_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), METADATA_WIDGET_TYPE, MetadataWidgetClass)) -#define IS_METADATA_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), METADATA_WIDGET_TYPE)) -#define IS_METADATA_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), METADATA_WIDGET_TYPE)) -#define METADATA_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), METADATA_WIDGET_TYPE, MetadataWidgetClass)) - -typedef struct _MetadataWidget MetadataWidget; -typedef struct _MetadataWidgetClass MetadataWidgetClass; - -struct _MetadataWidgetClass { - GtkMenuItemClass parent_class; -}; - -struct _MetadataWidget { - GtkMenuItem parent; -}; - -GType metadata_widget_get_type (void); -GtkWidget* metadata_widget_new(DbusmenuMenuitem *twin_item); - -G_END_DECLS - -#endif - diff --git a/src/mute-widget.c b/src/mute-widget.c deleted file mode 100644 index 500f575..0000000 --- a/src/mute-widget.c +++ /dev/null @@ -1,134 +0,0 @@ -/* -Copyright 2011 Canonical Ltd. - -Authors: - Marco Trevisan (Treviño) - -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 . -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include "mute-widget.h" -#include "common-defs.h" -#include "indicator-sound.h" - -typedef struct _MuteWidgetPrivate MuteWidgetPrivate; - -struct _MuteWidgetPrivate -{ - DbusmenuMenuitem *item; - GtkMenuItem *gitem; -}; - -#define MUTE_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), MUTE_WIDGET_TYPE, MuteWidgetPrivate)) - -/* Prototypes */ -static void mute_widget_class_init (MuteWidgetClass *klass); -static void mute_widget_init (MuteWidget *self); -static void mute_widget_dispose (GObject *object); -static void mute_widget_finalize (GObject *object); - -G_DEFINE_TYPE (MuteWidget, mute_widget, G_TYPE_OBJECT); - -static void -mute_widget_class_init (MuteWidgetClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - gobject_class->dispose = mute_widget_dispose; - gobject_class->finalize = mute_widget_finalize; - g_type_class_add_private (klass, sizeof (MuteWidgetPrivate)); -} - -static void -mute_widget_init (MuteWidget *self) -{ - MuteWidgetPrivate *priv = MUTE_WIDGET_GET_PRIVATE(self); - priv->item = NULL; - priv->gitem = GTK_MENU_ITEM(gtk_menu_item_new ()); -} - -static void -mute_widget_dispose (GObject *object) -{ - G_OBJECT_CLASS (mute_widget_parent_class)->dispose (object); -} - -static void -mute_widget_finalize (GObject *object) -{ - MuteWidget *self = MUTE_WIDGET (object); - MuteWidgetPrivate *priv = MUTE_WIDGET_GET_PRIVATE(self); - - g_object_unref (priv->item); - g_object_unref (G_OBJECT (priv->gitem)); - G_OBJECT_CLASS (mute_widget_parent_class)->finalize (object); -} - -GtkMenuItem * -mute_widget_get_menu_item(MuteWidget *self) -{ - MuteWidgetPrivate *priv = MUTE_WIDGET_GET_PRIVATE(self); - return priv->gitem; -} - -MuteStatus -mute_widget_get_status (MuteWidget *self) -{ - g_return_val_if_fail(self, MUTE_STATUS_UNAVAILABLE); - MuteStatus status = MUTE_STATUS_UNAVAILABLE; - MuteWidgetPrivate *priv = MUTE_WIDGET_GET_PRIVATE(self); - - GVariant *vstatus = dbusmenu_menuitem_property_get_variant(priv->item, - DBUSMENU_MUTE_MENUITEM_VALUE); - - if (g_variant_is_of_type (vstatus, G_VARIANT_TYPE_BOOLEAN)) - { - if (g_variant_get_boolean (vstatus)) - status = MUTE_STATUS_MUTED; - else - status = MUTE_STATUS_UNMUTED; - } - - return status; -} - -void mute_widget_toggle (MuteWidget *self) -{ - g_return_if_fail (self); - MuteWidgetPrivate *priv = MUTE_WIDGET_GET_PRIVATE(self); - gtk_menu_item_activate (priv->gitem); -} - -/** - * mute_widget_new: - * @returns: a new #MuteWidget. - **/ -MuteWidget * -mute_widget_new (DbusmenuMenuitem *item) -{ - MuteWidget* widget = g_object_new(MUTE_WIDGET_TYPE, NULL); - MuteWidgetPrivate* priv = MUTE_WIDGET_GET_PRIVATE(widget); - priv->item = g_object_ref(item); - - GVariant *label = dbusmenu_menuitem_property_get_variant(priv->item, - DBUSMENU_MENUITEM_PROP_LABEL); - - if (g_variant_is_of_type(label, G_VARIANT_TYPE_STRING)) - gtk_menu_item_set_label(priv->gitem, g_variant_get_string(label, NULL)); - - return widget; -} diff --git a/src/mute-widget.h b/src/mute-widget.h deleted file mode 100644 index 88ddd41..0000000 --- a/src/mute-widget.h +++ /dev/null @@ -1,63 +0,0 @@ -/* -Copyright 2011 Canonical Ltd. - -Authors: - Marco Trevisan (Treviño) - -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 . -*/ -#ifndef __MUTE_WIDGET_H__ -#define __MUTE_WIDGET_H__ - -#include -#include -#include -#include -#include - -G_BEGIN_DECLS - -#define MUTE_WIDGET_TYPE (mute_widget_get_type ()) -#define MUTE_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MUTE_WIDGET_TYPE, MuteWidget)) -#define MUTE_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MUTE_WIDGET_TYPE, MuteWidgetClass)) -#define IS_MUTE_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MUTE_WIDGET_TYPE)) -#define IS_MUTE_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MUTE_WIDGET_TYPE)) -#define MUTE_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MUTE_WIDGET_TYPE, MuteWidgetClass)) - -typedef struct _MuteWidget MuteWidget; -typedef struct _MuteWidgetClass MuteWidgetClass; - -struct _MuteWidgetClass { - GObjectClass parent_class; -}; - -struct _MuteWidget { - GObject parent; -}; - -typedef enum { - MUTE_STATUS_UNAVAILABLE, - MUTE_STATUS_MUTED, - MUTE_STATUS_UNMUTED -} MuteStatus; - -GType mute_widget_get_type (void) G_GNUC_CONST; -MuteWidget* mute_widget_new (DbusmenuMenuitem *item); -MuteStatus mute_widget_get_status (MuteWidget *self); -void mute_widget_toggle (MuteWidget *self); -GtkMenuItem *mute_widget_get_menu_item (MuteWidget *self); - -G_END_DECLS - -#endif - diff --git a/src/sound-state-manager.c b/src/sound-state-manager.c deleted file mode 100644 index c6b14ca..0000000 --- a/src/sound-state-manager.c +++ /dev/null @@ -1,480 +0,0 @@ -/* -Copyright 2011 Canonical Ltd. - -Authors: - Conor Curran - -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 . -*/ - -#include -#include - -#include "config.h" - -#include "sound-state-manager.h" -#include "dbus-shared-names.h" -#include "sound-state.h" - -typedef struct _SoundStateManagerPrivate SoundStateManagerPrivate; - -struct _SoundStateManagerPrivate -{ - GDBusProxy* dbus_proxy; - GHashTable* volume_states; - GList* blocked_animation_list; - SoundState current_state; - GtkImage* speaker_image; - NotifyNotification* notification; - GSettings *settings_manager; -}; - -#define SOUND_STATE_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUND_TYPE_STATE_MANAGER, SoundStateManagerPrivate)) -G_DEFINE_TYPE (SoundStateManager, sound_state_manager, G_TYPE_OBJECT); - -static GtkIconSize design_team_size; -static gint blocked_id; -static gint animation_id; -static GList* blocked_iter = NULL; -static gboolean can_animate = FALSE; - -//Notifications -static void sound_state_manager_notification_init (SoundStateManager* self); - -//Animation/State related -static void sound_state_manager_prepare_blocked_animation (SoundStateManager* self); -static gboolean sound_state_manager_start_animation (gpointer user_data); -static gboolean sound_state_manager_fade_back_to_mute_image (gpointer user_data); -static void sound_state_manager_reset_mute_blocking_animation (SoundStateManager* self); -static void sound_state_manager_free_the_animation_list (SoundStateManager* self); -static void sound_state_manager_prepare_state_image_names (SoundStateManager* self); -static void sound_state_signal_cb ( GDBusProxy* proxy, - gchar* sender_name, - gchar* signal_name, - GVariant* parameters, - gpointer user_data ); -static gboolean sound_state_manager_can_proceed_with_blocking_animation (SoundStateManager* self); - - -static void -sound_state_manager_init (SoundStateManager* self) -{ - SoundStateManagerPrivate* priv = SOUND_STATE_MANAGER_GET_PRIVATE(self); - - priv->dbus_proxy = NULL; - priv->volume_states = NULL; - priv->speaker_image = NULL; - priv->blocked_animation_list = NULL; - priv->notification = NULL; - priv->settings_manager = NULL; - - priv->settings_manager = g_settings_new("com.canonical.indicator.sound"); - - sound_state_manager_prepare_state_image_names (self); - sound_state_manager_prepare_blocked_animation (self); - - priv->current_state = UNAVAILABLE; - priv->speaker_image = indicator_image_helper (g_hash_table_lookup (priv->volume_states, - GINT_TO_POINTER(priv->current_state))); -} - -static void -sound_state_manager_finalize (GObject *object) -{ - /* TODO: Add deinitalization code here */ - - G_OBJECT_CLASS (sound_state_manager_parent_class)->finalize (object); -} - -static void -sound_state_manager_dispose (GObject *object) -{ - SoundStateManager* self = SOUND_STATE_MANAGER (object); - SoundStateManagerPrivate* priv = SOUND_STATE_MANAGER_GET_PRIVATE(self); - - g_hash_table_destroy (priv->volume_states); - - sound_state_manager_free_the_animation_list (self); - - if (priv->notification) { - notify_uninit(); - } - - g_object_unref(priv->settings_manager); - - G_OBJECT_CLASS (sound_state_manager_parent_class)->dispose (object); -} - - -static void -sound_state_manager_class_init (SoundStateManagerClass *klass) -{ - GObjectClass* object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = sound_state_manager_finalize; - object_class->dispose = sound_state_manager_dispose; - - g_type_class_add_private (klass, sizeof (SoundStateManagerPrivate)); - - design_team_size = gtk_icon_size_register("design-team-size", 22, 22); -} - -static void -sound_state_manager_notification_init (SoundStateManager* self) -{ - static gboolean initialized = FALSE; - - /* one-time lazy initialization */ - if (initialized) - return; - initialized = TRUE; - - SoundStateManagerPrivate* priv = SOUND_STATE_MANAGER_GET_PRIVATE(self); - - if (!notify_init(PACKAGE_NAME)) - return; - - GList* caps = notify_get_server_caps(); - gboolean has_notify_osd = FALSE; - - if (caps) { - if (g_list_find_custom(caps, "x-canonical-private-synchronous", - (GCompareFunc) g_strcmp0)) { - has_notify_osd = TRUE; - } - g_list_foreach(caps, (GFunc) g_free, NULL); - g_list_free(caps); - } - - if (has_notify_osd) { - priv->notification = notify_notification_new(PACKAGE_NAME, NULL, NULL); - notify_notification_set_hint_string(priv->notification, - "x-canonical-private-synchronous", PACKAGE_NAME); - } -} - -void -sound_state_manager_show_notification (SoundStateManager *self, - double value) -{ - SoundStateManagerPrivate* priv = SOUND_STATE_MANAGER_GET_PRIVATE(self); - - sound_state_manager_notification_init (self); - - if (priv->notification == NULL || - g_settings_get_boolean (priv->settings_manager, "show-notify-osd-on-scroll") == FALSE){ - return; - } - - char *icon; - const int notify_value = CLAMP((int)value, -1, 101); - - SoundState state = sound_state_get_from_volume ((int)value); - - if (state == ZERO_LEVEL) { - // Not available for all the themes - icon = "notification-audio-volume-off"; - } else if (state == LOW_LEVEL) { - icon = "notification-audio-volume-low"; - } else if (state == MEDIUM_LEVEL) { - icon = "notification-audio-volume-medium"; - } else if (state == HIGH_LEVEL) { - icon = "notification-audio-volume-high"; - } else { - icon = "notification-audio-volume-muted"; - } - - notify_notification_update(priv->notification, PACKAGE_NAME, NULL, icon); - notify_notification_set_hint_int32(priv->notification, "value", notify_value); - notify_notification_show(priv->notification, NULL); -} - - -/* -Prepare states versus images names hash. -*/ -static void -sound_state_manager_prepare_state_image_names (SoundStateManager* self) -{ - SoundStateManagerPrivate* priv = SOUND_STATE_MANAGER_GET_PRIVATE(self); - priv->volume_states = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free); - - g_hash_table_insert (priv->volume_states, GINT_TO_POINTER(MUTED), g_strdup("audio-volume-muted-panel")); - g_hash_table_insert (priv->volume_states, GINT_TO_POINTER(ZERO_LEVEL), g_strdup("audio-volume-low-zero-panel")); - g_hash_table_insert (priv->volume_states, GINT_TO_POINTER(LOW_LEVEL), g_strdup("audio-volume-low-panel")); - g_hash_table_insert (priv->volume_states, GINT_TO_POINTER(MEDIUM_LEVEL), g_strdup("audio-volume-medium-panel")); - g_hash_table_insert (priv->volume_states, GINT_TO_POINTER(HIGH_LEVEL), g_strdup("audio-volume-high-panel")); - g_hash_table_insert (priv->volume_states, GINT_TO_POINTER(BLOCKED), g_strdup("audio-volume-muted-blocking-panel")); - g_hash_table_insert (priv->volume_states, GINT_TO_POINTER(UNAVAILABLE), g_strdup("audio-output-none-panel")); -} - -/* -prepare_blocked_animation: -Prepares the array of images to be used in the blocked animation. -Only called at startup. -*/ -static void -sound_state_manager_prepare_blocked_animation (SoundStateManager* self) -{ - SoundStateManagerPrivate* priv = SOUND_STATE_MANAGER_GET_PRIVATE(self); - - gchar* blocked_name = g_hash_table_lookup(priv->volume_states, - GINT_TO_POINTER(BLOCKED)); - gchar* muted_name = g_hash_table_lookup(priv->volume_states, - GINT_TO_POINTER(MUTED)); - - GtkImage* temp_image = indicator_image_helper(muted_name); - GdkPixbuf* mute_buf = gtk_image_get_pixbuf(temp_image); - - temp_image = indicator_image_helper(blocked_name); - GdkPixbuf* blocked_buf = gtk_image_get_pixbuf(temp_image); - - if (mute_buf == NULL || blocked_buf == NULL) { - //g_debug("Don bother with the animation, the theme aint got the goods !"); - return; - } - - int i; - - // sample 51 snapshots - range : 0-256 - for (i = 0; i < 51; i++) { - gdk_pixbuf_composite(mute_buf, blocked_buf, 0, 0, - gdk_pixbuf_get_width(mute_buf), - gdk_pixbuf_get_height(mute_buf), - 0, 0, 1, 1, GDK_INTERP_BILINEAR, MIN(255, i * 5)); - priv->blocked_animation_list = g_list_append(priv->blocked_animation_list, - gdk_pixbuf_copy(blocked_buf)); - } - can_animate = TRUE; - g_object_ref_sink(mute_buf); - g_object_unref(mute_buf); - g_object_ref_sink(blocked_buf); - g_object_unref(blocked_buf); -} - - -GtkImage* -sound_state_manager_get_current_icon (SoundStateManager* self) -{ - SoundStateManagerPrivate* priv = SOUND_STATE_MANAGER_GET_PRIVATE(self); - return priv->speaker_image; -} - -SoundState -sound_state_manager_get_current_state (SoundStateManager* self) -{ - SoundStateManagerPrivate* priv = SOUND_STATE_MANAGER_GET_PRIVATE(self); - return priv->current_state; -} - -/** - * sound_state_manager_connect_to_dbus: - * @returns: void - * When ready the indicator-sound calls this method to enable state communication - * between the indicator and the service. - **/ -void -sound_state_manager_connect_to_dbus (SoundStateManager* self, GDBusProxy* proxy) -{ - SoundStateManagerPrivate* priv = SOUND_STATE_MANAGER_GET_PRIVATE(self); - priv->dbus_proxy = proxy; - g_signal_connect (priv->dbus_proxy, "g-signal", - G_CALLBACK (sound_state_signal_cb), self); - - g_dbus_proxy_call ( priv->dbus_proxy, - "GetSoundState", - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - (GAsyncReadyCallback)sound_state_manager_get_state_cb, - self); -} - -void -sound_state_manager_get_state_cb (GObject *object, - GAsyncResult *res, - gpointer user_data) -{ - g_return_if_fail (SOUND_IS_STATE_MANAGER (user_data)); - SoundStateManager* self = SOUND_STATE_MANAGER (user_data); - SoundStateManagerPrivate* priv = SOUND_STATE_MANAGER_GET_PRIVATE(self); - - GVariant *result, *value; - GError *error = NULL; - result = g_dbus_proxy_call_finish ( priv->dbus_proxy, - res, - &error ); - - if (error != NULL) { - g_warning("get_sound_state call failed: %s", error->message); - g_error_free(error); - return; - } - - value = g_variant_get_child_value(result, 0); - priv->current_state = (SoundState)g_variant_get_int32(value); - - gchar* image_name = g_hash_table_lookup (priv->volume_states, - GINT_TO_POINTER(priv->current_state) ); - indicator_image_helper_update (priv->speaker_image, image_name); - - g_variant_unref(value); - g_variant_unref(result); -} - -void -sound_state_manager_deal_with_disconnect (SoundStateManager* self) -{ - SoundStateManagerPrivate* priv = SOUND_STATE_MANAGER_GET_PRIVATE(self); - priv->current_state = UNAVAILABLE; - - gchar* image_name = g_hash_table_lookup (priv->volume_states, - GINT_TO_POINTER(priv->current_state) ); - indicator_image_helper_update (priv->speaker_image, image_name); -} - -static void -sound_state_signal_cb ( GDBusProxy* proxy, - gchar* sender_name, - gchar* signal_name, - GVariant* parameters, - gpointer user_data) -{ - //g_debug ( "!!! sound state manager signal_cb" ); - - g_return_if_fail (SOUND_IS_STATE_MANAGER (user_data)); - SoundStateManager* self = SOUND_STATE_MANAGER (user_data); - SoundStateManagerPrivate* priv = SOUND_STATE_MANAGER_GET_PRIVATE(self); - - g_variant_ref (parameters); - GVariant *value = g_variant_get_child_value (parameters, 0); - gint update = g_variant_get_int32 (value); - - //g_debug ( "!!! signal_cb with value %i", update); - - priv->current_state = (SoundState)update; - - g_variant_unref (parameters); - - if (g_strcmp0(signal_name, INDICATOR_SOUND_SIGNAL_STATE_UPDATE) == 0){ - - gchar* image_name = g_hash_table_lookup (priv->volume_states, - GINT_TO_POINTER(priv->current_state) ); - if (priv->current_state == BLOCKED && - sound_state_manager_can_proceed_with_blocking_animation (self) == TRUE) { - blocked_id = g_timeout_add_seconds (4, - sound_state_manager_start_animation, - self); - indicator_image_helper_update (priv->speaker_image, image_name); - } - else{ - indicator_image_helper_update (priv->speaker_image, image_name); - } - } - else { - g_warning ("sorry don't know what signal this is - %s", signal_name); - } -} - -void -sound_state_manager_style_changed_cb (GtkWidget *widget, - GtkStyle *previous_style, - gpointer user_data) -{ - g_debug("Just caught a style change event"); - g_return_if_fail (SOUND_IS_STATE_MANAGER (user_data)); - SoundStateManager* self = SOUND_STATE_MANAGER (user_data); - sound_state_manager_reset_mute_blocking_animation (self); - sound_state_manager_free_the_animation_list (self); - sound_state_manager_prepare_blocked_animation (self); -} - -static void -sound_state_manager_reset_mute_blocking_animation (SoundStateManager* self) -{ - if (animation_id != 0) { - //g_debug("about to remove the animation_id callback from the mainloop!!**"); - g_source_remove(animation_id); - animation_id = 0; - } - if (blocked_id != 0) { - //g_debug("about to remove the blocked_id callback from the mainloop!!**"); - g_source_remove(blocked_id); - blocked_id = 0; - } -} - -static void -sound_state_manager_free_the_animation_list (SoundStateManager* self) -{ - SoundStateManagerPrivate* priv = SOUND_STATE_MANAGER_GET_PRIVATE(self); - - if (priv->blocked_animation_list != NULL) { - g_list_foreach (priv->blocked_animation_list, (GFunc)g_object_unref, NULL); - g_list_free (priv->blocked_animation_list); - priv->blocked_animation_list = NULL; - } -} - - -static gboolean -sound_state_manager_start_animation (gpointer userdata) -{ - g_return_val_if_fail (SOUND_IS_STATE_MANAGER (userdata), FALSE); - SoundStateManager* self = SOUND_STATE_MANAGER (userdata); - SoundStateManagerPrivate* priv = SOUND_STATE_MANAGER_GET_PRIVATE(self); - - blocked_iter = priv->blocked_animation_list; - blocked_id = 0; - animation_id = g_timeout_add (50, - sound_state_manager_fade_back_to_mute_image, - self); - return FALSE; -} - -static gboolean -sound_state_manager_fade_back_to_mute_image (gpointer user_data) -{ - g_return_val_if_fail (SOUND_IS_STATE_MANAGER (user_data), FALSE); - SoundStateManager* self = SOUND_STATE_MANAGER (user_data); - SoundStateManagerPrivate* priv = SOUND_STATE_MANAGER_GET_PRIVATE (self); - - if (blocked_iter != NULL) { - gtk_image_set_from_pixbuf (priv->speaker_image, blocked_iter->data); - blocked_iter = blocked_iter->next; - return TRUE; - } else { - animation_id = 0; - //g_debug("exit from animation now\n"); - g_dbus_proxy_call ( priv->dbus_proxy, - "GetSoundState", - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - (GAsyncReadyCallback)sound_state_manager_get_state_cb, - self); - - return FALSE; - } -} - - -// Simple static helper to determine if the coast is clear to animate -static -gboolean sound_state_manager_can_proceed_with_blocking_animation (SoundStateManager* self) -{ - return (can_animate && blocked_id == 0 && animation_id == 0 ); -} - diff --git a/src/sound-state-manager.h b/src/sound-state-manager.h deleted file mode 100644 index 9287897..0000000 --- a/src/sound-state-manager.h +++ /dev/null @@ -1,67 +0,0 @@ -/* -Copyright 2011 Canonical Ltd. - -Authors: - Conor Curran - -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 . -*/ - -#ifndef _SOUND_STATE_MANAGER_H_ -#define _SOUND_STATE_MANAGER_H_ - -#include -#include "common-defs.h" - -G_BEGIN_DECLS - -#define SOUND_TYPE_STATE_MANAGER (sound_state_manager_get_type ()) -#define SOUND_STATE_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SOUND_TYPE_STATE_MANAGER, SoundStateManager)) -#define SOUND_STATE_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SOUND_TYPE_STATE_MANAGER, SoundStateManagerClass)) -#define SOUND_IS_STATE_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SOUND_TYPE_STATE_MANAGER)) -#define SOUND_IS_STATE_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SOUND_TYPE_STATE_MANAGER)) -#define SOUND_STATE_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SOUND_TYPE_STATE_MANAGER, SoundStateManagerClass)) - -typedef struct _SoundStateManagerClass SoundStateManagerClass; -typedef struct _SoundStateManager SoundStateManager; - -struct _SoundStateManagerClass -{ - GObjectClass parent_class; -}; - -struct _SoundStateManager -{ - GObject parent_instance; -}; - -GType sound_state_manager_get_type (void) G_GNUC_CONST; - -void sound_state_manager_style_changed_cb (GtkWidget *widget, - GtkStyle *previous_style, - gpointer user_data); -GtkImage* sound_state_manager_get_current_icon (SoundStateManager* self); -SoundState sound_state_manager_get_current_state (SoundStateManager* self); -void sound_state_manager_connect_to_dbus (SoundStateManager* self, - GDBusProxy* proxy); -void sound_state_manager_deal_with_disconnect (SoundStateManager* self); -void sound_state_manager_get_state_cb (GObject *object, - GAsyncResult *res, - gpointer user_data); -void sound_state_manager_show_notification (SoundStateManager *self, - double value); - - -G_END_DECLS - -#endif /* _SOUND_STATE_MANAGER_H_ */ diff --git a/src/transport-widget.c b/src/transport-widget.c deleted file mode 100644 index ebe8282..0000000 --- a/src/transport-widget.c +++ /dev/null @@ -1,1886 +0,0 @@ -/* -Copyright 2010 Canonical Ltd. - -Authors: - Conor Curran - Mirco Müller - Andrea Cimitan - -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 . - -Uses code from ctk -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include "transport-widget.h" - - -#define RECT_WIDTH 130.0f -#define Y 7.0f -#define X 70.0f -#define INNER_RADIUS 12.5 -#define MIDDLE_RADIUS 13.0f -#define OUTER_RADIUS 14.5f -#define CIRCLE_RADIUS 21.0f -#define PREV_WIDTH 25.0f -#define PREV_HEIGHT 17.0f -#define NEXT_WIDTH 25.0f //PREV_WIDTH -#define NEXT_HEIGHT 17.0f //PREV_HEIGHT -#define TRI_WIDTH 11.0f -#define TRI_HEIGHT 13.0f -#define TRI_OFFSET 6.0f -#define PREV_X 68.0f -#define PREV_Y 13.0f -#define NEXT_X 146.0f -#define NEXT_Y 13.0f //prev_y -#define PAUSE_WIDTH 21.0f -#define PAUSE_HEIGHT 27.0f -#define BAR_WIDTH 4.5f -#define BAR_HEIGHT 24.0f -#define BAR_OFFSET 10.0f -#define PAUSE_X 111.0f -#define PAUSE_Y 7.0f -#define PLAY_WIDTH 28.0f -#define PLAY_HEIGHT 29.0f -#define PLAY_PADDING 5.0f -#define INNER_START_SHADE 0.98 -#define INNER_END_SHADE 0.98 -#define MIDDLE_START_SHADE 1.0 -#define MIDDLE_END_SHADE 1.0 -#define OUTER_START_SHADE 0.75 -#define OUTER_END_SHADE 1.3 -#define SHADOW_BUTTON_SHADE 0.8 -#define OUTER_PLAY_START_SHADE 0.7 -#define OUTER_PLAY_END_SHADE 1.38 -#define BUTTON_START_SHADE 1.1 -#define BUTTON_END_SHADE 0.9 -#define BUTTON_SHADOW_SHADE 0.8 -#define INNER_COMPRESSED_START_SHADE 1.0 -#define INNER_COMPRESSED_END_SHADE 1.0 - -typedef struct _TransportWidgetPrivate TransportWidgetPrivate; - -struct _TransportWidgetPrivate -{ - TransportAction current_command; - TransportAction key_event; - TransportAction motion_event; - TransportState current_state; - GHashTable* command_coordinates; - DbusmenuMenuitem* twin_item; - gboolean has_focus; - gint hold_timer; - gint skip_frequency; -}; - -#if GTK_CHECK_VERSION(3, 0, 0) -static GList *transport_widget_list = NULL; -static GtkStyleContext *spinner_style_context = NULL; -static GtkWidgetPath *spinner_widget_path = NULL; -#endif - -// TODO refactor the UI handlers, consolidate functionality between key press /release -// and button press / release. -#define TRANSPORT_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TRANSPORT_WIDGET_TYPE, TransportWidgetPrivate)) - -/* Gobject boiler plate */ -static void transport_widget_class_init (TransportWidgetClass *klass); -static void transport_widget_init (TransportWidget *self); -static void transport_widget_dispose (GObject *object); -static void transport_widget_finalize (GObject *object); -G_DEFINE_TYPE (TransportWidget, transport_widget, GTK_TYPE_MENU_ITEM); - -/* essentials */ -static void transport_widget_set_twin_item ( TransportWidget* self, - DbusmenuMenuitem* twin_item); -#if ! GTK_CHECK_VERSION(3, 0, 0) -static gboolean transport_widget_expose ( GtkWidget *button, GdkEventExpose *event); -#endif -static gboolean draw (GtkWidget* button, cairo_t *cr); - -/* UI and dbusmenu callbacks */ -static gboolean transport_widget_button_press_event (GtkWidget *menuitem, - GdkEventButton *event); -static gboolean transport_widget_button_release_event (GtkWidget *menuitem, - GdkEventButton *event); -static gboolean transport_widget_motion_notify_event (GtkWidget *menuitem, - GdkEventMotion *event); -static gboolean transport_widget_leave_notify_event (GtkWidget *menuitem, - GdkEventCrossing *event); -static void transport_widget_property_update ( DbusmenuMenuitem* item, - gchar * property, - GVariant * value, - gpointer userdata ); -static void transport_widget_menu_hidden ( GtkWidget *menu, - TransportWidget *transport); -static void transport_widget_notify ( GObject *item, - GParamSpec *pspec, - gpointer user_data ); -static TransportAction transport_widget_determine_button_event ( TransportWidget* button, - GdkEventButton* event); -static TransportAction transport_widget_determine_motion_event ( TransportWidget* button, - GdkEventMotion* event); -static void transport_widget_react_to_button_release ( TransportWidget* button, - TransportAction command); -static void transport_widget_toggle_play_pause ( TransportWidget* button, - TransportState update); -static void transport_widget_select (GtkWidget* menu, gpointer Userdata); -static void transport_widget_deselect (GtkWidget* menu, gpointer Userdata); -static TransportAction transport_widget_collision_detection (gint x, gint y); -static void transport_widget_start_timing (TransportWidget* widget); -static gboolean transport_widget_trigger_seek (gpointer userdata); -static gboolean transport_widget_seek (gpointer userdata); - - -/// Init functions ////////////////////////////////////////////////////////// -static void -transport_widget_class_init (TransportWidgetClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GtkWidgetClass* widget_class = GTK_WIDGET_CLASS (klass); - - g_type_class_add_private (klass, sizeof (TransportWidgetPrivate)); - - widget_class->button_press_event = transport_widget_button_press_event; - widget_class->button_release_event = transport_widget_button_release_event; - widget_class->motion_notify_event = transport_widget_motion_notify_event; - widget_class->leave_notify_event = transport_widget_leave_notify_event; -#if GTK_CHECK_VERSION(3, 0, 0) - widget_class->draw = draw; -#else - widget_class->expose_event = transport_widget_expose; -#endif - - gobject_class->dispose = transport_widget_dispose; - gobject_class->finalize = transport_widget_finalize; -} - -static void -transport_widget_init (TransportWidget *self) -{ - TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE(self); - #if GTK_CHECK_VERSION(3, 0, 0) - if (transport_widget_list == NULL){ - /* append the object to the static linked list. */ - transport_widget_list = g_list_append (transport_widget_list, self); - - /* create widget path */ - spinner_widget_path = gtk_widget_path_new(); - - gtk_widget_path_append_type (spinner_widget_path, GTK_TYPE_MENU); - gtk_widget_path_append_type (spinner_widget_path, GTK_TYPE_MENU_ITEM); - gint pos = gtk_widget_path_append_type (spinner_widget_path, GTK_TYPE_SPINNER); - gtk_widget_path_iter_set_name (spinner_widget_path, pos, "IndicatorSoundSpinner"); - - /* create style context and append path */ - spinner_style_context = gtk_style_context_new(); - - gtk_style_context_set_path (spinner_style_context, spinner_widget_path); - gtk_style_context_add_class (spinner_style_context, GTK_STYLE_CLASS_MENU); - gtk_style_context_add_class (spinner_style_context, GTK_STYLE_CLASS_MENUITEM); - gtk_style_context_add_class (spinner_style_context, GTK_STYLE_CLASS_SPINNER); - } - #endif - priv->current_command = TRANSPORT_ACTION_NO_ACTION; - priv->current_state = TRANSPORT_STATE_PAUSED; - priv->key_event = TRANSPORT_ACTION_NO_ACTION; - priv->motion_event = TRANSPORT_ACTION_NO_ACTION; - priv->has_focus = FALSE; - priv->hold_timer = 0; - priv->skip_frequency = 0; - priv->command_coordinates = g_hash_table_new_full(g_direct_hash, - g_direct_equal, - NULL, - (GDestroyNotify)g_list_free); - GList* previous_list = NULL; - previous_list = g_list_insert(previous_list, GINT_TO_POINTER(15), 0); - previous_list = g_list_insert(previous_list, GINT_TO_POINTER(5), 1); - previous_list = g_list_insert(previous_list, GINT_TO_POINTER(60), 2); - previous_list = g_list_insert(previous_list, GINT_TO_POINTER(34), 3); - g_hash_table_insert(priv->command_coordinates, - GINT_TO_POINTER(TRANSPORT_ACTION_PREVIOUS), - previous_list); - - GList* play_list = NULL; - play_list = g_list_insert(play_list, GINT_TO_POINTER(58), 0); - play_list = g_list_insert(play_list, GINT_TO_POINTER(0), 1); - play_list = g_list_insert(play_list, GINT_TO_POINTER(50), 2); - play_list = g_list_insert(play_list, GINT_TO_POINTER(43), 3); - - g_hash_table_insert(priv->command_coordinates, - GINT_TO_POINTER(TRANSPORT_ACTION_PLAY_PAUSE), - play_list); - - GList* next_list = NULL; - next_list = g_list_insert(next_list, GINT_TO_POINTER(100), 0); - next_list = g_list_insert(next_list, GINT_TO_POINTER(5), 1); - next_list = g_list_insert(next_list, GINT_TO_POINTER(60), 2); - next_list = g_list_insert(next_list, GINT_TO_POINTER(34), 3); - - g_hash_table_insert(priv->command_coordinates, - GINT_TO_POINTER(TRANSPORT_ACTION_NEXT), - next_list); - gtk_widget_set_size_request(GTK_WIDGET(self), 200, 43); - g_signal_connect (G_OBJECT(self), - "notify", - G_CALLBACK (transport_widget_notify), - NULL); - g_signal_connect (G_OBJECT(self), - "select", - G_CALLBACK (transport_widget_select), - NULL); - g_signal_connect (G_OBJECT(self), - "deselect", - G_CALLBACK (transport_widget_deselect), - NULL); - gtk_widget_realize ( GTK_WIDGET (self) ); - -} - -static void -transport_widget_dispose (GObject *object) -{ - #if GTK_CHECK_VERSION(3, 0, 0) - transport_widget_list = g_list_remove (transport_widget_list, object); - - if (transport_widget_list == NULL){ - if (spinner_widget_path != NULL){ - gtk_widget_path_free (spinner_widget_path); - spinner_widget_path = NULL; - } - - if (spinner_style_context != NULL){ - g_object_unref (spinner_style_context); - spinner_style_context = NULL; - } - } - #endif - - TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE(object); - if (priv->command_coordinates != NULL) { - g_hash_table_destroy (priv->command_coordinates); - priv->command_coordinates = NULL; - } - - G_OBJECT_CLASS (transport_widget_parent_class)->dispose (object); -} - -static void -transport_widget_finalize (GObject *object) -{ - - - G_OBJECT_CLASS (transport_widget_parent_class)->finalize (object); -} - -#if ! GTK_CHECK_VERSION(3, 0, 0) -static gboolean -transport_widget_expose (GtkWidget *button, GdkEventExpose *event) -{ - cairo_t *cr; - cr = gdk_cairo_create (gtk_widget_get_window (button)); - - cairo_rectangle (cr, - event->area.x, event->area.y, - event->area.width, event->area.height); - - cairo_clip(cr); - draw (button, cr); - - cairo_destroy (cr); - return FALSE; -} -#endif - -gboolean -transport_widget_is_selected ( TransportWidget* widget ) -{ - g_return_val_if_fail (IS_TRANSPORT_WIDGET (widget), FALSE); - TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE(widget); - return priv->has_focus; -} - -static void -transport_widget_toggle_play_pause(TransportWidget* button, - TransportState update) -{ - TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE(button); - priv->current_state = update; - gtk_widget_queue_draw (GTK_WIDGET(button)); -} - -static void -transport_widget_notify ( GObject *item, - GParamSpec *pspec, - gpointer user_data ) -{ - if (g_strcmp0 (pspec->name, "parent")){ - GtkWidget *parent = gtk_widget_get_parent (GTK_WIDGET (item)); - if (parent){ - g_signal_connect ( parent, "hide", - G_CALLBACK (transport_widget_menu_hidden), - item ); - } - } -} - -static void -transport_widget_menu_hidden ( GtkWidget *menu, - TransportWidget *transport) -{ - g_return_if_fail(IS_TRANSPORT_WIDGET(transport)); - transport_widget_react_to_button_release(transport, TRANSPORT_ACTION_NO_ACTION); -} - -static gboolean -transport_widget_motion_notify_event (GtkWidget *menuitem, - GdkEventMotion *event) -{ - //g_debug("transport_widget_motion_notify_event()"); - - g_return_val_if_fail ( IS_TRANSPORT_WIDGET(menuitem), FALSE ); - TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE ( TRANSPORT_WIDGET(menuitem) ); - TransportAction result = transport_widget_determine_motion_event ( TRANSPORT_WIDGET(menuitem), - event); - priv->motion_event = result; - gtk_widget_queue_draw (menuitem); - if (priv->hold_timer != 0){ - g_source_remove (priv->hold_timer); - priv->hold_timer = 0; - } - if(priv->skip_frequency != 0){ - g_source_remove (priv->skip_frequency); - priv->skip_frequency = 0; - } - return TRUE; -} - -static gboolean -transport_widget_leave_notify_event (GtkWidget *menuitem, - GdkEventCrossing *event) -{ - //g_debug("transport_widget_leave_notify_event()"); - - g_return_val_if_fail ( IS_TRANSPORT_WIDGET(menuitem), FALSE ); - TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE ( TRANSPORT_WIDGET(menuitem) ); - - priv->motion_event = TRANSPORT_ACTION_NO_ACTION; - priv->current_command = TRANSPORT_ACTION_NO_ACTION; - gtk_widget_queue_draw (GTK_WIDGET(menuitem)); - - return TRUE; -} - -static gboolean -transport_widget_button_press_event (GtkWidget *menuitem, - GdkEventButton *event) -{ - //g_debug("transport_widget_button_press_event()"); - - g_return_val_if_fail ( IS_TRANSPORT_WIDGET(menuitem), FALSE ); - TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE ( TRANSPORT_WIDGET(menuitem) ); - TransportAction result = transport_widget_determine_button_event ( TRANSPORT_WIDGET(menuitem), - event); - if(result != TRANSPORT_ACTION_NO_ACTION){ - priv->current_command = result; - gtk_widget_queue_draw (GTK_WIDGET(menuitem)); - if (priv->current_command == TRANSPORT_ACTION_PREVIOUS || - priv->current_command == TRANSPORT_ACTION_NEXT){ - transport_widget_start_timing (TRANSPORT_WIDGET(menuitem)); - } - } - return TRUE; -} -/** - * TODO rename or merge - * @param widget - */ -static void -transport_widget_start_timing (TransportWidget* widget) -{ - TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE (widget); - if (priv->hold_timer == 0){ - priv->hold_timer = g_timeout_add (800, - transport_widget_trigger_seek, - widget); - } -} - -static gboolean -transport_widget_trigger_seek (gpointer userdata) -{ - g_return_val_if_fail ( IS_TRANSPORT_WIDGET(userdata), FALSE ); - TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE (TRANSPORT_WIDGET(userdata)); - if (priv->skip_frequency == 0){ - priv->skip_frequency = g_timeout_add (100, - transport_widget_seek, - userdata); - } - priv->hold_timer = 0; - return FALSE; -} - -/** - * This will be called repeatedly until a key/button release is received - * @param userdata - * @return - */ -static gboolean -transport_widget_seek (gpointer userdata) -{ - g_return_val_if_fail ( IS_TRANSPORT_WIDGET(userdata), FALSE ); - TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE (TRANSPORT_WIDGET(userdata)); - GVariant* new_transport_state; - if(priv->current_command == TRANSPORT_ACTION_NEXT){ - //g_debug ("we should be skipping forward"); - new_transport_state = g_variant_new_int32 ((int)TRANSPORT_ACTION_FORWIND); - - dbusmenu_menuitem_handle_event ( priv->twin_item, - "Transport state change", - new_transport_state, - 0 ); - - } - else if(priv->current_command == TRANSPORT_ACTION_PREVIOUS){ - //g_debug ("we should be skipping back"); - new_transport_state = g_variant_new_int32 ((int)TRANSPORT_ACTION_REWIND); - - dbusmenu_menuitem_handle_event ( priv->twin_item, - "Transport state change", - new_transport_state, - 0 ); - } - - return TRUE; -} - -static gboolean -transport_widget_button_release_event (GtkWidget *menuitem, - GdkEventButton *event) -{ - g_return_val_if_fail(IS_TRANSPORT_WIDGET(menuitem), FALSE); - TransportWidget* transport = TRANSPORT_WIDGET(menuitem); - TransportWidgetPrivate * priv = TRANSPORT_WIDGET_GET_PRIVATE ( transport ); - TransportAction result = transport_widget_determine_button_event ( transport, - event ); - if (result != TRANSPORT_ACTION_NO_ACTION && - priv->current_command == result && - priv->skip_frequency == 0){ - GVariant* new_transport_state = g_variant_new_int32 ((int)result); - dbusmenu_menuitem_handle_event ( priv->twin_item, - "Transport state change", - new_transport_state, - 0 ); - } - transport_widget_react_to_button_release ( transport, - result ); - return TRUE; -} - -static void -transport_widget_select (GtkWidget* item, gpointer Userdata) -{ - TransportWidget* transport = TRANSPORT_WIDGET(item); - TransportWidgetPrivate * priv = TRANSPORT_WIDGET_GET_PRIVATE ( transport ); - priv->has_focus = TRUE; -} - -static void -transport_widget_deselect (GtkWidget* item, gpointer Userdata) -{ - TransportWidget* transport = TRANSPORT_WIDGET(item); - TransportWidgetPrivate * priv = TRANSPORT_WIDGET_GET_PRIVATE ( transport ); - priv->has_focus = FALSE; -} - -void -transport_widget_react_to_key_press_event ( TransportWidget* transport, - TransportAction transport_event ) -{ - if(transport_event != TRANSPORT_ACTION_NO_ACTION){ - TransportWidgetPrivate * priv = TRANSPORT_WIDGET_GET_PRIVATE ( transport ); - priv->current_command = transport_event; - priv->key_event = transport_event; - gtk_widget_realize ( GTK_WIDGET(transport) ); - gtk_widget_queue_draw (GTK_WIDGET(transport) ); - if (priv->current_command == TRANSPORT_ACTION_PREVIOUS || - priv->current_command == TRANSPORT_ACTION_NEXT){ - transport_widget_start_timing (transport); - } - } -} - -void -transport_widget_react_to_key_release_event ( TransportWidget* transport, - TransportAction transport_event ) -{ - if(transport_event != TRANSPORT_ACTION_NO_ACTION){ - TransportWidgetPrivate * priv = TRANSPORT_WIDGET_GET_PRIVATE ( transport ); - GVariant* new_transport_event = g_variant_new_int32((int)transport_event); - if (priv->skip_frequency == 0){ - dbusmenu_menuitem_handle_event ( priv->twin_item, - "Transport state change", - new_transport_event, - 0 ); - } - } - transport_widget_react_to_button_release ( transport, - transport_event ); -} - -void -transport_widget_focus_update ( TransportWidget* transport, gboolean focus ) -{ - TransportWidgetPrivate * priv = TRANSPORT_WIDGET_GET_PRIVATE ( transport ); - priv->has_focus = focus; -} - -static TransportAction -transport_widget_determine_button_event( TransportWidget* button, - GdkEventButton* event ) -{ - return transport_widget_collision_detection (event->x, event->y); -} - -static TransportAction -transport_widget_determine_motion_event( TransportWidget* button, - GdkEventMotion* event ) -{ - return transport_widget_collision_detection (event->x, event->y); -} - -static TransportAction -transport_widget_collision_detection ( gint x, - gint y ) -{ - TransportAction event = TRANSPORT_ACTION_NO_ACTION; - - if (x > 57 && x < 102 - && y > 12 && y < 40){ - event = TRANSPORT_ACTION_PREVIOUS; - } - else if (x > 101 && x < 143 - && y > 5 && y < 47){ - event = TRANSPORT_ACTION_PLAY_PAUSE; - } - else if (x > 142 && x < 187 - && y > 12 && y < 40){ - event = TRANSPORT_ACTION_NEXT; - } - return event; -} - -static void -transport_widget_react_to_button_release ( TransportWidget* button, - TransportAction command ) -{ - g_return_if_fail(IS_TRANSPORT_WIDGET(button)); - TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE(button); - - priv->current_command = TRANSPORT_ACTION_NO_ACTION; - priv->key_event = TRANSPORT_ACTION_NO_ACTION; - - gtk_widget_queue_draw (GTK_WIDGET(button)); - if (priv->hold_timer != 0){ - g_source_remove (priv->hold_timer); - priv->hold_timer = 0; - } - if(priv->skip_frequency != 0){ - g_source_remove (priv->skip_frequency); - priv->skip_frequency = 0; - } -} - -/// internal helper functions ////////////////////////////////////////////////// - -static void -draw_gradient (cairo_t* cr, - double x, - double y, - double w, - double r, - double* rgba_start, - double* rgba_end) -{ - cairo_pattern_t* pattern = NULL; - - cairo_move_to (cr, x, y); - cairo_line_to (cr, x + w - 2.0f * r, y); - cairo_arc (cr, - x + w - 2.0f * r, - y + r, - r, - -90.0f * G_PI / 180.0f, - 90.0f * G_PI / 180.0f); - cairo_line_to (cr, x, y + 2.0f * r); - cairo_arc (cr, - x, - y + r, - r, - 90.0f * G_PI / 180.0f, - 270.0f * G_PI / 180.0f); - cairo_close_path (cr); - - pattern = cairo_pattern_create_linear (x, y, x, y + 2.0f * r); - cairo_pattern_add_color_stop_rgba (pattern, - 0.0f, - rgba_start[0], - rgba_start[1], - rgba_start[2], - rgba_start[3]); - cairo_pattern_add_color_stop_rgba (pattern, - 1.0f, - rgba_end[0], - rgba_end[1], - rgba_end[2], - rgba_end[3]); - cairo_set_source (cr, pattern); - cairo_fill (cr); - cairo_pattern_destroy (pattern); -} - -static void -draw_circle (cairo_t* cr, - double x, - double y, - double r, - double* rgba_start, - double* rgba_end) -{ - cairo_pattern_t* pattern = NULL; - - cairo_move_to (cr, x, y); - cairo_arc (cr, - x + r, - y + r, - r, - 0.0f * G_PI / 180.0f, - 360.0f * G_PI / 180.0f); - - pattern = cairo_pattern_create_linear (x, y, x, y + 2.0f * r); - cairo_pattern_add_color_stop_rgba (pattern, - 0.0f, - rgba_start[0], - rgba_start[1], - rgba_start[2], - rgba_start[3]); - cairo_pattern_add_color_stop_rgba (pattern, - 1.0f, - rgba_end[0], - rgba_end[1], - rgba_end[2], - rgba_end[3]); - cairo_set_source (cr, pattern); - cairo_fill (cr); - cairo_pattern_destroy (pattern); -} - -static void -_setup (cairo_t** cr, - cairo_surface_t** surf, - gint width, - gint height) -{ - if (!cr || !surf) - return; - - *surf = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); - *cr = cairo_create (*surf); - cairo_scale (*cr, 1.0f, 1.0f); - cairo_set_operator (*cr, CAIRO_OPERATOR_CLEAR); - cairo_paint (*cr); - cairo_set_operator (*cr, CAIRO_OPERATOR_OVER); -} - -static void -_mask_prev (cairo_t* cr, - double x, - double y, - double tri_width, - double tri_height, - double tri_offset) -{ - if (!cr) - return; - - cairo_move_to (cr, x, y + tri_height / 2.0f); - cairo_line_to (cr, x + tri_width, y); - cairo_line_to (cr, x + tri_width, y + tri_height); - x += tri_offset; - cairo_move_to (cr, x, y + tri_height / 2.0f); - cairo_line_to (cr, x + tri_width, y); - cairo_line_to (cr, x + tri_width, y + tri_height); - x -= tri_offset; - cairo_rectangle (cr, x, y, 2.5f, tri_height); - cairo_close_path (cr); -} - -static void -_mask_next (cairo_t* cr, - double x, - double y, - double tri_width, - double tri_height, - double tri_offset) -{ - if (!cr) - return; - - cairo_move_to (cr, x, y); - cairo_line_to (cr, x + tri_width, y + tri_height / 2.0f); - cairo_line_to (cr, x, y + tri_height); - x += tri_offset; - cairo_move_to (cr, x, y); - cairo_line_to (cr, x + tri_width, y + tri_height / 2.0f); - cairo_line_to (cr, x, y + tri_height); - x -= tri_offset; - x += 2.0f * tri_width - tri_offset - 1.0f; - cairo_rectangle (cr, x, y, 2.5f, tri_height); - - cairo_close_path (cr); -} - -static void -_mask_pause (cairo_t* cr, - double x, - double y, - double bar_width, - double bar_height, - double bar_offset) -{ - if (!cr) - return; - - cairo_set_line_width (cr, bar_width); - cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); - - x += bar_width; - y += bar_width; - cairo_move_to (cr, x, y); - cairo_line_to (cr, x, y + bar_height); - cairo_move_to (cr, x + bar_offset, y); - cairo_line_to (cr, x + bar_offset, y + bar_height); - -} - -static void -_mask_play (cairo_t* cr, - double x, - double y, - double tri_width, - double tri_height) -{ - if (!cr) - return; - - cairo_move_to (cr, x, y); - cairo_line_to (cr, x + tri_width, y + tri_height / 2.0f); - cairo_line_to (cr, x, y + tri_height); - cairo_close_path (cr); - -} - -static void -_fill (cairo_t* cr, - double x_start, - double y_start, - double x_end, - double y_end, - double* rgba_start, - double* rgba_end, - gboolean stroke) -{ - cairo_pattern_t* pattern = NULL; - - if (!cr || !rgba_start || !rgba_end) - return; - - pattern = cairo_pattern_create_linear (x_start, y_start, x_end, y_end); - cairo_pattern_add_color_stop_rgba (pattern, - 0.0f, - rgba_start[0], - rgba_start[1], - rgba_start[2], - rgba_start[3]); - cairo_pattern_add_color_stop_rgba (pattern, - 1.0f, - rgba_end[0], - rgba_end[1], - rgba_end[2], - rgba_end[3]); - cairo_set_source (cr, pattern); - if (stroke) - cairo_stroke (cr); - else - cairo_fill (cr); - cairo_pattern_destroy (pattern); -} - -static void -_finalize (cairo_t* cr, - cairo_t** cr_surf, - cairo_surface_t** surf, - double x, - double y) -{ - if (!cr || !cr_surf || !surf) - return; - - cairo_set_source_surface (cr, *surf, x, y); - cairo_paint (cr); - cairo_surface_destroy (*surf); - cairo_destroy (*cr_surf); -} - -static void -_finalize_repaint (cairo_t* cr, - cairo_t** cr_surf, - cairo_surface_t** surf, - double x, - double y, - int repaints) -{ - if (!cr || !cr_surf || !surf) - return; - - while (repaints > 0) - { - cairo_set_source_surface (cr, *surf, x, y); - cairo_paint (cr); - repaints--; - } - - cairo_surface_destroy (*surf); - cairo_destroy (*cr_surf); -} - -static void -_color_rgb_to_hls (gdouble *r, - gdouble *g, - gdouble *b) -{ - gdouble min; - gdouble max; - gdouble red; - gdouble green; - gdouble blue; - gdouble h = 0; - gdouble l; - gdouble s; - gdouble delta; - - red = *r; - green = *g; - blue = *b; - - if (red > green) - { - if (red > blue) - max = red; - else - max = blue; - - if (green < blue) - min = green; - else - min = blue; - } - else - { - if (green > blue) - max = green; - else - max = blue; - - if (red < blue) - min = red; - else - min = blue; - } - l = (max+min)/2; - if (fabs (max-min) < 0.0001) - { - h = 0; - s = 0; - } - else - { - if (l <= 0.5) - s = (max-min)/(max+min); - else - s = (max-min)/(2-max-min); - - delta = (max -min) != 0 ? (max -min) : 1; - - if(delta == 0) - delta = 1; - if (red == max) - h = (green-blue)/delta; - else if (green == max) - h = 2+(blue-red)/delta; - else if (blue == max) - h = 4+(red-green)/delta; - - h *= 60; - if (h < 0.0) - h += 360; - } - - *r = h; - *g = l; - *b = s; -} - -static void -_color_hls_to_rgb (gdouble *h, - gdouble *l, - gdouble *s) -{ - gdouble hue; - gdouble lightness; - gdouble saturation; - gdouble m1, m2; - gdouble r, g, b; - - lightness = *l; - saturation = *s; - - if (lightness <= 0.5) - m2 = lightness*(1+saturation); - else - m2 = lightness+saturation-lightness*saturation; - - m1 = 2*lightness-m2; - - if (saturation == 0) - { - *h = lightness; - *l = lightness; - *s = lightness; - } - else - { - hue = *h+120; - while (hue > 360) - hue -= 360; - while (hue < 0) - hue += 360; - - if (hue < 60) - r = m1+(m2-m1)*hue/60; - else if (hue < 180) - r = m2; - else if (hue < 240) - r = m1+(m2-m1)*(240-hue)/60; - else - r = m1; - - hue = *h; - while (hue > 360) - hue -= 360; - while (hue < 0) - hue += 360; - - if (hue < 60) - g = m1+(m2-m1)*hue/60; - else if (hue < 180) - g = m2; - else if (hue < 240) - g = m1+(m2-m1)*(240-hue)/60; - else - g = m1; - - hue = *h-120; - while (hue > 360) - hue -= 360; - while (hue < 0) - hue += 360; - - if (hue < 60) - b = m1+(m2-m1)*hue/60; - else if (hue < 180) - b = m2; - else if (hue < 240) - b = m1+(m2-m1)*(240-hue)/60; - else - b = m1; - - *h = r; - *l = g; - *s = b; - } -} - -void -_color_shade (const CairoColorRGB *a, float k, CairoColorRGB *b) -{ - double red; - double green; - double blue; - - red = a->r; - green = a->g; - blue = a->b; - - if (k == 1.0) - { - b->r = red; - b->g = green; - b->b = blue; - return; - } - - _color_rgb_to_hls (&red, &green, &blue); - - green *= k; - if (green > 1.0) - green = 1.0; - else if (green < 0.0) - green = 0.0; - - blue *= k; - if (blue > 1.0) - blue = 1.0; - else if (blue < 0.0) - blue = 0.0; - - _color_hls_to_rgb (&red, &green, &blue); - - b->r = red; - b->g = green; - b->b = blue; -} - -static inline void -_blurinner (guchar* pixel, - gint* zR, - gint* zG, - gint* zB, - gint* zA, - gint alpha, - gint aprec, - gint zprec) -{ - gint R; - gint G; - gint B; - guchar A; - - R = *pixel; - G = *(pixel + 1); - B = *(pixel + 2); - A = *(pixel + 3); - - *zR += (alpha * ((R << zprec) - *zR)) >> aprec; - *zG += (alpha * ((G << zprec) - *zG)) >> aprec; - *zB += (alpha * ((B << zprec) - *zB)) >> aprec; - *zA += (alpha * ((A << zprec) - *zA)) >> aprec; - - *pixel = *zR >> zprec; - *(pixel + 1) = *zG >> zprec; - *(pixel + 2) = *zB >> zprec; - *(pixel + 3) = *zA >> zprec; -} - -static inline void -_blurrow (guchar* pixels, - gint width, - gint height, - gint channels, - gint line, - gint alpha, - gint aprec, - gint zprec) -{ - gint zR; - gint zG; - gint zB; - gint zA; - gint index; - guchar* scanline; - - scanline = &(pixels[line * width * channels]); - - zR = *scanline << zprec; - zG = *(scanline + 1) << zprec; - zB = *(scanline + 2) << zprec; - zA = *(scanline + 3) << zprec; - - for (index = 0; index < width; index ++) - _blurinner (&scanline[index * channels], - &zR, - &zG, - &zB, - &zA, - alpha, - aprec, - zprec); - - for (index = width - 2; index >= 0; index--) - _blurinner (&scanline[index * channels], - &zR, - &zG, - &zB, - &zA, - alpha, - aprec, - zprec); -} - -static inline void -_blurcol (guchar* pixels, - gint width, - gint height, - gint channels, - gint x, - gint alpha, - gint aprec, - gint zprec) -{ - gint zR; - gint zG; - gint zB; - gint zA; - gint index; - guchar* ptr; - - ptr = pixels; - - ptr += x * channels; - - zR = *((guchar*) ptr ) << zprec; - zG = *((guchar*) ptr + 1) << zprec; - zB = *((guchar*) ptr + 2) << zprec; - zA = *((guchar*) ptr + 3) << zprec; - - for (index = width; index < (height - 1) * width; index += width) - _blurinner ((guchar*) &ptr[index * channels], - &zR, - &zG, - &zB, - &zA, - alpha, - aprec, - zprec); - - for (index = (height - 2) * width; index >= 0; index -= width) - _blurinner ((guchar*) &ptr[index * channels], - &zR, - &zG, - &zB, - &zA, - alpha, - aprec, - zprec); -} - -void -_expblur (guchar* pixels, - gint width, - gint height, - gint channels, - gint radius, - gint aprec, - gint zprec) -{ - gint alpha; - gint row = 0; - gint col = 0; - - if (radius < 1) - return; - - // calculate the alpha such that 90% of - // the kernel is within the radius. - // (Kernel extends to infinity) - alpha = (gint) ((1 << aprec) * (1.0f - expf (-2.3f / (radius + 1.f)))); - - for (; row < height; row++) - _blurrow (pixels, - width, - height, - channels, - row, - alpha, - aprec, - zprec); - - for(; col < width; col++) - _blurcol (pixels, - width, - height, - channels, - col, - alpha, - aprec, - zprec); - - return; -} - -void -_surface_blur (cairo_surface_t* surface, - guint radius) -{ - guchar* pixels; - guint width; - guint height; - cairo_format_t format; - - // before we mess with the surface execute any pending drawing - cairo_surface_flush (surface); - - pixels = cairo_image_surface_get_data (surface); - width = cairo_image_surface_get_width (surface); - height = cairo_image_surface_get_height (surface); - format = cairo_image_surface_get_format (surface); - - switch (format) - { - case CAIRO_FORMAT_ARGB32: - _expblur (pixels, width, height, 4, radius, 16, 7); - break; - - case CAIRO_FORMAT_RGB24: - _expblur (pixels, width, height, 3, radius, 16, 7); - break; - - case CAIRO_FORMAT_A8: - _expblur (pixels, width, height, 1, radius, 16, 7); - break; - - default : - // do nothing - break; - } - - // inform cairo we altered the surfaces contents - cairo_surface_mark_dirty (surface); -} - -static gboolean -draw (GtkWidget* button, cairo_t *cr) -{ - g_return_val_if_fail(IS_TRANSPORT_WIDGET(button), FALSE); - g_return_val_if_fail(cr != NULL, FALSE); - TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE(button); - - //g_debug("transport-widget draw()"); - - cairo_surface_t* surf = NULL; - cairo_t* cr_surf = NULL; - -#if ! GTK_CHECK_VERSION(3, 0, 0) - GtkAllocation allocation; - gtk_widget_get_allocation (button, &allocation); - cairo_translate (cr, allocation.x, allocation.y); -#endif - - GtkStyle *style; - -#if GTK_CHECK_VERSION(3, 0, 0) - gtk_style_context_add_class (gtk_widget_get_style_context (button), - GTK_STYLE_CLASS_MENU); -#endif - CairoColorRGB bg_color, fg_color, bg_selected, bg_prelight; - CairoColorRGB color_middle[2], color_middle_prelight[2], color_outer[2], color_outer_prelight[2], - color_play_outer[2], color_play_outer_prelight[2], - color_button[4], color_button_shadow, color_inner[2], color_inner_compressed[2]; - - /* Use the menu's style instead of that of the menuitem ('button' is a - * menuitem that is packed in a menu directly). The menuitem's style - * can't be used due to a change in light-themes (lp #1130183). - * Menuitems now have a transparent background, which confuses - * GtkStyle. - * - * This is a workaround until this code gets refactored to use - * GtkStyleContext. - */ - style = gtk_widget_get_style (gtk_widget_get_parent (button)); - - bg_color.r = style->bg[0].red/65535.0; - bg_color.g = style->bg[0].green/65535.0; - bg_color.b = style->bg[0].blue/65535.0; - - bg_prelight.r = style->bg[GTK_STATE_PRELIGHT].red/65535.0; - bg_prelight.g = style->bg[GTK_STATE_PRELIGHT].green/65535.0; - bg_prelight.b = style->bg[GTK_STATE_PRELIGHT].blue/65535.0; - - bg_selected.r = style->bg[GTK_STATE_SELECTED].red/65535.0; - bg_selected.g = style->bg[GTK_STATE_SELECTED].green/65535.0; - bg_selected.b = style->bg[GTK_STATE_SELECTED].blue/65535.0; - - fg_color.r = style->fg[0].red/65535.0; - fg_color.g = style->fg[0].green/65535.0; - fg_color.b = style->fg[0].blue/65535.0; - - _color_shade (&bg_color, MIDDLE_START_SHADE, &color_middle[0]); - _color_shade (&bg_color, MIDDLE_END_SHADE, &color_middle[1]); - _color_shade (&bg_prelight, MIDDLE_START_SHADE, &color_middle_prelight[0]); - _color_shade (&bg_prelight, MIDDLE_END_SHADE, &color_middle_prelight[1]); - _color_shade (&bg_color, OUTER_START_SHADE, &color_outer[0]); - _color_shade (&bg_color, OUTER_END_SHADE, &color_outer[1]); - _color_shade (&bg_prelight, OUTER_START_SHADE, &color_outer_prelight[0]); - _color_shade (&bg_prelight, OUTER_END_SHADE, &color_outer_prelight[1]); - _color_shade (&bg_color, OUTER_PLAY_START_SHADE, &color_play_outer[0]); - _color_shade (&bg_color, OUTER_PLAY_END_SHADE, &color_play_outer[1]); - _color_shade (&bg_prelight, OUTER_PLAY_START_SHADE, &color_play_outer_prelight[0]); - _color_shade (&bg_prelight, OUTER_PLAY_END_SHADE, &color_play_outer_prelight[1]); - _color_shade (&bg_color, INNER_START_SHADE, &color_inner[0]); - _color_shade (&bg_color, INNER_END_SHADE, &color_inner[1]); - _color_shade (&fg_color, BUTTON_START_SHADE, &color_button[0]); - _color_shade (&fg_color, BUTTON_END_SHADE, &color_button[1]); - _color_shade (&bg_color, BUTTON_SHADOW_SHADE, &color_button[2]); - _color_shade (&bg_color, SHADOW_BUTTON_SHADE, &color_button_shadow); - _color_shade (&bg_selected, 1.0, &color_button[3]); - _color_shade (&bg_color, INNER_COMPRESSED_START_SHADE, &color_inner_compressed[0]); - _color_shade (&bg_color, INNER_COMPRESSED_END_SHADE, &color_inner_compressed[1]); - - double MIDDLE_END[] = {color_middle[0].r, color_middle[0].g, color_middle[0].b, 1.0f}; - double MIDDLE_START[] = {color_middle[1].r, color_middle[1].g, color_middle[1].b, 1.0f}; - double MIDDLE_END_PRELIGHT[] = {color_middle_prelight[0].r, color_middle_prelight[0].g, color_middle_prelight[0].b, 1.0f}; - double MIDDLE_START_PRELIGHT[] = {color_middle_prelight[1].r, color_middle_prelight[1].g, color_middle_prelight[1].b, 1.0f}; - double OUTER_END[] = {color_outer[0].r, color_outer[0].g, color_outer[0].b, 1.0f}; - double OUTER_START[] = {color_outer[1].r, color_outer[1].g, color_outer[1].b, 1.0f}; - double OUTER_END_PRELIGHT[] = {color_outer_prelight[0].r, color_outer_prelight[0].g, color_outer_prelight[0].b, 1.0f}; - double OUTER_START_PRELIGHT[] = {color_outer_prelight[1].r, color_outer_prelight[1].g, color_outer_prelight[1].b, 1.0f}; - double SHADOW_BUTTON[] = {color_button_shadow.r, color_button_shadow.g, color_button_shadow.b, 0.3f}; - double OUTER_PLAY_END[] = {color_play_outer[0].r, color_play_outer[0].g, color_play_outer[0].b, 1.0f}; - double OUTER_PLAY_START[] = {color_play_outer[1].r, color_play_outer[1].g, color_play_outer[1].b, 1.0f}; - double OUTER_PLAY_END_PRELIGHT[] = {color_play_outer_prelight[0].r, color_play_outer_prelight[0].g, color_play_outer_prelight[0].b, 1.0f}; - double OUTER_PLAY_START_PRELIGHT[] = {color_play_outer_prelight[1].r, color_play_outer_prelight[1].g, color_play_outer_prelight[1].b, 1.0f}; - double BUTTON_END[] = {color_button[0].r, color_button[0].g, color_button[0].b, 1.0f}; - double BUTTON_START[] = {color_button[1].r, color_button[1].g, color_button[1].b, 1.0f}; - double BUTTON_SHADOW[] = {color_button[2].r, color_button[2].g, color_button[2].b, 0.75f}; - double BUTTON_SHADOW_FOCUS[] = {color_button[3].r, color_button[3].g, color_button[3].b, 1.0f}; - double INNER_COMPRESSED_END[] = {color_inner_compressed[1].r, color_inner_compressed[1].g, color_inner_compressed[1].b, 1.0f}; - double INNER_COMPRESSED_START[] = {color_inner_compressed[0].r, color_inner_compressed[0].g, color_inner_compressed[0].b, 1.0f}; - - - draw_gradient (cr, - X, - Y, - RECT_WIDTH, - OUTER_RADIUS, - OUTER_START, - OUTER_END); - - draw_gradient (cr, - X, - Y + 1, - RECT_WIDTH - 2, - MIDDLE_RADIUS, - MIDDLE_START, - MIDDLE_END); - - draw_gradient (cr, - X, - Y + 2, - RECT_WIDTH - 4, - MIDDLE_RADIUS, - MIDDLE_START, - MIDDLE_END); - - //prev/next button - if(priv->current_command == TRANSPORT_ACTION_PREVIOUS) - { - draw_gradient (cr, - X, - Y, - RECT_WIDTH/2, - OUTER_RADIUS, - OUTER_END, - OUTER_START); - - draw_gradient (cr, - X, - Y + 1, - RECT_WIDTH/2, - MIDDLE_RADIUS, - INNER_COMPRESSED_START, - INNER_COMPRESSED_END); - - draw_gradient (cr, - X, - Y + 2, - RECT_WIDTH/2, - MIDDLE_RADIUS, - INNER_COMPRESSED_START, - INNER_COMPRESSED_END); - } - else if(priv->current_command == TRANSPORT_ACTION_NEXT) - { - draw_gradient (cr, - RECT_WIDTH / 2 + X, - Y, - RECT_WIDTH/2, - OUTER_RADIUS, - OUTER_END, - OUTER_START); - - draw_gradient (cr, - RECT_WIDTH / 2 + X, - Y + 1, - (RECT_WIDTH - 4.5)/2, - MIDDLE_RADIUS, - INNER_COMPRESSED_START, - INNER_COMPRESSED_END); - - draw_gradient (cr, - RECT_WIDTH / 2 + X, - Y + 2, - (RECT_WIDTH - 7)/2, - MIDDLE_RADIUS, - INNER_COMPRESSED_START, - INNER_COMPRESSED_END); - } - else if (priv->motion_event == TRANSPORT_ACTION_PREVIOUS) - { - draw_gradient (cr, - X, - Y, - RECT_WIDTH/2, - OUTER_RADIUS, - OUTER_START_PRELIGHT, - OUTER_END_PRELIGHT); - - draw_gradient (cr, - X, - Y + 1, - RECT_WIDTH/2, - MIDDLE_RADIUS, - MIDDLE_START_PRELIGHT, - MIDDLE_END_PRELIGHT); - - draw_gradient (cr, - X, - Y + 2, - RECT_WIDTH/2, - MIDDLE_RADIUS, - MIDDLE_START_PRELIGHT, - MIDDLE_END_PRELIGHT); - } - else if (priv->motion_event == TRANSPORT_ACTION_NEXT) - { - draw_gradient (cr, - RECT_WIDTH / 2 + X, - Y, - RECT_WIDTH/2, - OUTER_RADIUS, - OUTER_START_PRELIGHT, - OUTER_END_PRELIGHT); - - draw_gradient (cr, - RECT_WIDTH / 2 + X, - Y + 1, - (RECT_WIDTH - 4.5)/2, - MIDDLE_RADIUS, - MIDDLE_START_PRELIGHT, - MIDDLE_END_PRELIGHT); - - draw_gradient (cr, - RECT_WIDTH / 2 + X, - Y + 2, - (RECT_WIDTH - 7)/2, - MIDDLE_RADIUS, - MIDDLE_START_PRELIGHT, - MIDDLE_END_PRELIGHT); - } - - // play/pause shadow - if(priv->current_command != TRANSPORT_ACTION_PLAY_PAUSE) - { - cairo_save (cr); - cairo_rectangle (cr, X, Y, RECT_WIDTH, MIDDLE_RADIUS*2); - cairo_clip (cr); - - draw_circle (cr, - X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f - 1.0f, - Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) - 1.0f, - CIRCLE_RADIUS + 1.0f, - SHADOW_BUTTON, - SHADOW_BUTTON); - - cairo_restore (cr); - } - - // play/pause button - if(priv->current_command == TRANSPORT_ACTION_PLAY_PAUSE) - { - draw_circle (cr, - X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f, - Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) , - CIRCLE_RADIUS, - OUTER_PLAY_END, - OUTER_PLAY_START); - - draw_circle (cr, - X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f + 1.25f, - Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) + 1.25f, - CIRCLE_RADIUS - 1.25, - INNER_COMPRESSED_START, - INNER_COMPRESSED_END); - } - else if (priv->motion_event == TRANSPORT_ACTION_PLAY_PAUSE) - { - /* this subtle offset is to fix alpha borders, should be removed once this draw routine will be refactored */ - draw_circle (cr, - X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f + 0.1, - Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) + 0.1, - CIRCLE_RADIUS - 0.1, - OUTER_PLAY_START_PRELIGHT, - OUTER_PLAY_END_PRELIGHT); - - draw_circle (cr, - X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f + 1.25f, - Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) + 1.25f, - CIRCLE_RADIUS - 1.25, - MIDDLE_START_PRELIGHT, - MIDDLE_END_PRELIGHT); - } - else - { - draw_circle (cr, - X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f, - Y - ((CIRCLE_RADIUS - OUTER_RADIUS)), - CIRCLE_RADIUS, - OUTER_PLAY_START, - OUTER_PLAY_END); - - draw_circle (cr, - X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f + 1.25f, - Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) + 1.25f, - CIRCLE_RADIUS - 1.25, - MIDDLE_START, - MIDDLE_END); - } - - // draw previous-button drop-shadow - if (priv->has_focus && priv->key_event == TRANSPORT_ACTION_PREVIOUS) - { - _setup (&cr_surf, &surf, PREV_WIDTH+6, PREV_HEIGHT+6); - _mask_prev (cr_surf, - (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, - (PREV_HEIGHT - TRI_HEIGHT) / 2.0f, - TRI_WIDTH, - TRI_HEIGHT, - TRI_OFFSET); - _fill (cr_surf, - (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, - (PREV_HEIGHT - TRI_HEIGHT) / 2.0f, - (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, - (double) TRI_HEIGHT, - BUTTON_SHADOW_FOCUS, - BUTTON_SHADOW_FOCUS, - FALSE); - _surface_blur (surf, 3); - _finalize_repaint (cr, &cr_surf, &surf, PREV_X, PREV_Y + 0.5f, 3); - } - else - { - _setup (&cr_surf, &surf, PREV_WIDTH, PREV_HEIGHT); - _mask_prev (cr_surf, - (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, - (PREV_HEIGHT - TRI_HEIGHT) / 2.0f, - TRI_WIDTH, - TRI_HEIGHT, - TRI_OFFSET); - _fill (cr_surf, - (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, - (PREV_HEIGHT - TRI_HEIGHT) / 2.0f, - (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, - (double) TRI_HEIGHT, - BUTTON_SHADOW, - BUTTON_SHADOW, - FALSE); - _surface_blur (surf, 1); - _finalize (cr, &cr_surf, &surf, PREV_X, PREV_Y + 1.0f); - } - - // draw previous-button - _setup (&cr_surf, &surf, PREV_WIDTH, PREV_HEIGHT); - _mask_prev (cr_surf, - (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, - (PREV_HEIGHT - TRI_HEIGHT) / 2.0f, - TRI_WIDTH, - TRI_HEIGHT, - TRI_OFFSET); - _fill (cr_surf, - (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, - (PREV_HEIGHT - TRI_HEIGHT) / 2.0f, - (PREV_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, - (double) TRI_HEIGHT, - BUTTON_START, - BUTTON_END, - FALSE); - _finalize (cr, &cr_surf, &surf, PREV_X, PREV_Y); - - // draw next-button drop-shadow - if (priv->has_focus && priv->key_event == TRANSPORT_ACTION_NEXT) - { - _setup (&cr_surf, &surf, NEXT_WIDTH+6, NEXT_HEIGHT+6); - _mask_next (cr_surf, - (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, - (NEXT_HEIGHT - TRI_HEIGHT) / 2.0f, - TRI_WIDTH, - TRI_HEIGHT, - TRI_OFFSET); - _fill (cr_surf, - (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, - (NEXT_HEIGHT - TRI_HEIGHT) / 2.0f, - (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, - (double) TRI_HEIGHT, - BUTTON_SHADOW_FOCUS, - BUTTON_SHADOW_FOCUS, - FALSE); - _surface_blur (surf, 3); - _finalize_repaint (cr, &cr_surf, &surf, NEXT_X, NEXT_Y + 0.5f, 3); - } - else - { - _setup (&cr_surf, &surf, NEXT_WIDTH, NEXT_HEIGHT); - _mask_next (cr_surf, - (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, - (NEXT_HEIGHT - TRI_HEIGHT) / 2.0f, - TRI_WIDTH, - TRI_HEIGHT, - TRI_OFFSET); - _fill (cr_surf, - (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, - (NEXT_HEIGHT - TRI_HEIGHT) / 2.0f, - (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, - (double) TRI_HEIGHT, - BUTTON_SHADOW, - BUTTON_SHADOW, - FALSE); - _surface_blur (surf, 1); - _finalize (cr, &cr_surf, &surf, NEXT_X, NEXT_Y + 1.0f); - } - - // draw next-button - _setup (&cr_surf, &surf, NEXT_WIDTH, NEXT_HEIGHT); - _mask_next (cr_surf, - (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, - (NEXT_HEIGHT - TRI_HEIGHT) / 2.0f, - TRI_WIDTH, - TRI_HEIGHT, - TRI_OFFSET); - _fill (cr_surf, - (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, - (NEXT_HEIGHT - TRI_HEIGHT) / 2.0f, - (NEXT_WIDTH - (2.0f * TRI_WIDTH - TRI_OFFSET)) / 2.0f, - (double) TRI_HEIGHT, - BUTTON_START, - BUTTON_END, - FALSE); - _finalize (cr, &cr_surf, &surf, NEXT_X, NEXT_Y); - - // draw pause-button drop-shadow - if(priv->current_state == TRANSPORT_STATE_PLAYING) - { - if (priv->has_focus && (priv->key_event == TRANSPORT_ACTION_NO_ACTION || - priv->key_event == TRANSPORT_ACTION_PLAY_PAUSE)) - { - _setup (&cr_surf, &surf, PAUSE_WIDTH+6, PAUSE_HEIGHT+6); - _mask_pause (cr_surf, - (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, - (PAUSE_HEIGHT - BAR_HEIGHT) / 2.0f, - BAR_WIDTH, - BAR_HEIGHT - 2.0f * BAR_WIDTH, - BAR_OFFSET); - _fill (cr_surf, - (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, - (PAUSE_HEIGHT - BAR_HEIGHT) / 2.0f, - (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, - (double) BAR_HEIGHT, - BUTTON_SHADOW_FOCUS, - BUTTON_SHADOW_FOCUS, - TRUE); - _surface_blur (surf, 3); - _finalize_repaint (cr, &cr_surf, &surf, PAUSE_X, PAUSE_Y + 0.5f, 3); - } - else - { - _setup (&cr_surf, &surf, PAUSE_WIDTH, PAUSE_HEIGHT); - _mask_pause (cr_surf, - (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, - (PAUSE_HEIGHT - BAR_HEIGHT) / 2.0f, - BAR_WIDTH, - BAR_HEIGHT - 2.0f * BAR_WIDTH, - BAR_OFFSET); - _fill (cr_surf, - (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, - (PAUSE_HEIGHT - BAR_HEIGHT) / 2.0f, - (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, - (double) BAR_HEIGHT, - BUTTON_SHADOW, - BUTTON_SHADOW, - TRUE); - _surface_blur (surf, 1); - _finalize (cr, &cr_surf, &surf, PAUSE_X, PAUSE_Y + 1.0f); - } - - // draw pause-button - _setup (&cr_surf, &surf, PAUSE_WIDTH, PAUSE_HEIGHT); - _mask_pause (cr_surf, - (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, - (PAUSE_HEIGHT - BAR_HEIGHT) / 2.0f, - BAR_WIDTH, - BAR_HEIGHT - 2.0f * BAR_WIDTH, - BAR_OFFSET); - _fill (cr_surf, - (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, - (PAUSE_HEIGHT - BAR_HEIGHT) / 2.0f, - (PAUSE_WIDTH - (2.0f * BAR_WIDTH + BAR_OFFSET)) / 2.0f, - (double) BAR_HEIGHT, - BUTTON_START, - BUTTON_END, - TRUE); - _finalize (cr, &cr_surf, &surf, PAUSE_X, PAUSE_Y); - } - else if(priv->current_state == TRANSPORT_STATE_PAUSED) - { - if (priv->has_focus && (priv->key_event == TRANSPORT_ACTION_NO_ACTION || - priv->key_event == TRANSPORT_ACTION_PLAY_PAUSE)) - { - _setup (&cr_surf, &surf, PLAY_WIDTH+6, PLAY_HEIGHT+6); - _mask_play (cr_surf, - PLAY_PADDING, - PLAY_PADDING, - PLAY_WIDTH - (2*PLAY_PADDING), - PLAY_HEIGHT - (2*PLAY_PADDING)); - _fill (cr_surf, - PLAY_PADDING, - PLAY_PADDING, - PLAY_WIDTH - (2*PLAY_PADDING), - PLAY_HEIGHT - (2*PLAY_PADDING), - BUTTON_SHADOW_FOCUS, - BUTTON_SHADOW_FOCUS, - FALSE); - _surface_blur (surf, 3); - _finalize_repaint (cr, &cr_surf, &surf, PAUSE_X-0.5f, PAUSE_Y + 0.5f, 3); - } - else - { - _setup (&cr_surf, &surf, PLAY_WIDTH, PLAY_HEIGHT); - _mask_play (cr_surf, - PLAY_PADDING, - PLAY_PADDING, - PLAY_WIDTH - (2*PLAY_PADDING), - PLAY_HEIGHT - (2*PLAY_PADDING)); - _fill (cr_surf, - PLAY_PADDING, - PLAY_PADDING, - PLAY_WIDTH - (2*PLAY_PADDING), - PLAY_HEIGHT - (2*PLAY_PADDING), - BUTTON_SHADOW, - BUTTON_SHADOW, - FALSE); - _surface_blur (surf, 1); - _finalize (cr, &cr_surf, &surf, PAUSE_X-0.75f, PAUSE_Y + 1.0f); - } - - // draw play-button - _setup (&cr_surf, &surf, PLAY_WIDTH, PLAY_HEIGHT); - cairo_set_line_width (cr, 10.5); - cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); - cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND); - _mask_play (cr_surf, - PLAY_PADDING, - PLAY_PADDING, - PLAY_WIDTH - (2*PLAY_PADDING), - PLAY_HEIGHT - (2*PLAY_PADDING)); - _fill (cr_surf, - PLAY_PADDING, - PLAY_PADDING, - PLAY_WIDTH - (2*PLAY_PADDING), - PLAY_HEIGHT - (2*PLAY_PADDING), - BUTTON_START, - BUTTON_END, - FALSE); - _finalize (cr, &cr_surf, &surf, PAUSE_X-0.5f, PAUSE_Y); - } - #if GTK_CHECK_VERSION(3, 0, 0) - else if(priv->current_state == TRANSPORT_STATE_LAUNCHING) - { - // the spinner is not aligned, why? because the play button has odd width/height numbers - gtk_render_activity (spinner_style_context, cr, 106, 6, 30, 30); - } - #endif - return FALSE; -} - -static void -transport_widget_set_twin_item(TransportWidget* self, - DbusmenuMenuitem* twin_item) -{ - TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE(self); - priv->twin_item = twin_item; - g_signal_connect(G_OBJECT(priv->twin_item), "property-changed", - G_CALLBACK(transport_widget_property_update), self); - gint initial_state = dbusmenu_menuitem_property_get_int (twin_item, - DBUSMENU_TRANSPORT_MENUITEM_PLAY_STATE ); - //g_debug("TRANSPORT WIDGET - INITIAL UPDATE = %i", initial_state); - transport_widget_toggle_play_pause (self, - (TransportState)initial_state); -} - -/** -* transport_widget_update_state() -* Callback for updates from the other side of dbus -**/ -static void -transport_widget_property_update(DbusmenuMenuitem* item, gchar* property, - GVariant* value, gpointer userdata) -{ - //g_debug("transport_widget_update_state - with property %s", property); - TransportWidget* bar = (TransportWidget*)userdata; - g_return_if_fail(IS_TRANSPORT_WIDGET(bar)); - TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE(bar); - - if(g_ascii_strcasecmp(DBUSMENU_TRANSPORT_MENUITEM_PLAY_STATE, property) == 0) - { - TransportState new_state = (TransportState)g_variant_get_int32(value); - //g_debug("transport_widget_update_state - with value %i", new_state); - if (new_state == TRANSPORT_STATE_LAUNCHING){ - #if GTK_CHECK_VERSION(3, 0, 0) - gtk_style_context_set_state (spinner_style_context, GTK_STATE_FLAG_ACTIVE); - #endif - - priv->current_state = TRANSPORT_STATE_LAUNCHING; - g_debug("TransportWidget::toggle play state : %i", priv->current_state); - } - else{ - transport_widget_toggle_play_pause(bar, new_state); - } - } -} - - -/** -* transport_widget_new: -* @returns: a new #TransportWidget. -**/ -GtkWidget* -transport_widget_new ( DbusmenuMenuitem *item ) -{ - GtkWidget* widget = g_object_new(TRANSPORT_WIDGET_TYPE, NULL); - gtk_widget_set_app_paintable (widget, TRUE); - transport_widget_set_twin_item((TransportWidget*)widget, item); - return widget; -} - diff --git a/src/transport-widget.h b/src/transport-widget.h deleted file mode 100644 index b68845f..0000000 --- a/src/transport-widget.h +++ /dev/null @@ -1,67 +0,0 @@ -/* -Copyright 2010 Canonical Ltd. - -Authors: - Conor Curran - -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 . -*/ -#ifndef __TRANSPORT_WIDGET_H__ -#define __TRANSPORT_WIDGET_H__ - -#include -#include - -#include "common-defs.h" - -G_BEGIN_DECLS - -#define TRANSPORT_WIDGET_TYPE (transport_widget_get_type ()) -#define TRANSPORT_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TRANSPORT_WIDGET_TYPE, TransportWidget)) -#define TRANSPORT_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TRANSPORT_WIDGET_TYPE, TransportWidgetClass)) -#define IS_TRANSPORT_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TRANSPORT_WIDGET_TYPE)) -#define IS_TRANSPORT_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TRANSPORT_WIDGET_TYPE)) -#define TRANSPORT_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TRANSPORT_WIDGET_TYPE, TransportWidgetClass)) - -typedef struct _TransportWidget TransportWidget; -typedef struct _TransportWidgetClass TransportWidgetClass; - - -struct _TransportWidgetClass { - GtkMenuItemClass parent_class; -}; - -struct _TransportWidget { - GtkMenuItem parent; -}; - -typedef struct -{ - double r; - double g; - double b; -} CairoColorRGB; - - -void _color_shade (const CairoColorRGB *a, float k, CairoColorRGB *b); -GType transport_widget_get_type (void); -GtkWidget* transport_widget_new (DbusmenuMenuitem *item); -void transport_widget_react_to_key_press_event (TransportWidget* widget, - TransportAction transport_event); -void transport_widget_react_to_key_release_event (TransportWidget* widget, - TransportAction transport_event); -gboolean transport_widget_is_selected (TransportWidget* widget); -G_END_DECLS - -#endif - diff --git a/src/voip-input-widget.c b/src/voip-input-widget.c deleted file mode 100644 index 03879e7..0000000 --- a/src/voip-input-widget.c +++ /dev/null @@ -1,284 +0,0 @@ - -/* -Copyright 2011 Canonical Ltd. - -Authors: - Conor Curran - -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 . -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include "voip-input-widget.h" -#include "common-defs.h" -#include - -typedef struct _VoipInputWidgetPrivate VoipInputWidgetPrivate; - -struct _VoipInputWidgetPrivate -{ - DbusmenuMenuitem* twin_item; - GtkWidget* ido_voip_input_slider; - gboolean grabbed; -}; - -#define VOIP_INPUT_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), VOIP_INPUT_WIDGET_TYPE, VoipInputWidgetPrivate)) - -/* Prototypes */ -static void voip_input_widget_class_init (VoipInputWidgetClass *klass); -static void voip_input_widget_init (VoipInputWidget *self); -static void voip_input_widget_dispose (GObject *object); -static void voip_input_widget_finalize (GObject *object); -static void voip_input_widget_set_twin_item( VoipInputWidget* self, - DbusmenuMenuitem* twin_item); -static void voip_input_widget_property_update( DbusmenuMenuitem* item, gchar* property, - GVariant* value, gpointer userdata ); - -static gboolean voip_input_widget_change_value_cb (GtkRange *range, - GtkScrollType scroll, - gdouble value, - gpointer user_data); -static gboolean voip_input_widget_value_changed_cb(GtkRange *range, gpointer user_data); -static void voip_input_widget_slider_grabbed(GtkWidget *widget, gpointer user_data); -static void voip_input_widget_slider_released(GtkWidget *widget, gpointer user_data); -static void voip_input_widget_parent_changed (GtkWidget *widget, gpointer user_data); - -G_DEFINE_TYPE (VoipInputWidget, voip_input_widget, G_TYPE_OBJECT); - - -static void -voip_input_widget_class_init (VoipInputWidgetClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (VoipInputWidgetPrivate)); - - gobject_class->dispose = voip_input_widget_dispose; - gobject_class->finalize = voip_input_widget_finalize; -} - -static void -voip_input_widget_init (VoipInputWidget *self) -{ - VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(self); - - priv->ido_voip_input_slider = ido_scale_menu_item_new_with_range ("VOLUME", IDO_RANGE_STYLE_DEFAULT, 0, 0, 100, 1); - g_object_ref (priv->ido_voip_input_slider); - ido_scale_menu_item_set_primary_label (IDO_SCALE_MENU_ITEM(priv->ido_voip_input_slider), "VOIP"); - - ido_scale_menu_item_set_style (IDO_SCALE_MENU_ITEM (priv->ido_voip_input_slider), IDO_SCALE_MENU_ITEM_STYLE_IMAGE); - g_object_set(priv->ido_voip_input_slider, "reverse-scroll-events", TRUE, NULL); - - g_signal_connect (priv->ido_voip_input_slider, - "notify::parent", G_CALLBACK (voip_input_widget_parent_changed), - NULL); - - GtkWidget* voip_input_widget = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_voip_input_slider); - - g_signal_connect(voip_input_widget, "change-value", G_CALLBACK(voip_input_widget_change_value_cb), self); - g_signal_connect(voip_input_widget, "value-changed", G_CALLBACK(voip_input_widget_value_changed_cb), self); - g_signal_connect(priv->ido_voip_input_slider, "slider-grabbed", G_CALLBACK(voip_input_widget_slider_grabbed), self); - g_signal_connect(priv->ido_voip_input_slider, "slider-released", G_CALLBACK(voip_input_widget_slider_released), self); - - GtkWidget* primary_image = ido_scale_menu_item_get_primary_image((IdoScaleMenuItem*)priv->ido_voip_input_slider); - GIcon * primary_gicon = g_themed_icon_new_with_default_fallbacks("audio-input-microphone-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_voip_input_slider); - GIcon * secondary_gicon = g_themed_icon_new_with_default_fallbacks("audio-input-microphone-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 (voip_input_widget)); - gtk_adjustment_set_step_increment(adj, 4); -} - -static void -voip_input_widget_dispose (GObject *object) -{ - G_OBJECT_CLASS (voip_input_widget_parent_class)->dispose (object); -} - -static void -voip_input_widget_finalize (GObject *object) -{ - G_OBJECT_CLASS (voip_input_widget_parent_class)->finalize (object); -} - -static void -voip_input_widget_property_update (DbusmenuMenuitem* item, gchar* property, - GVariant* value, gpointer userdata) -{ - g_return_if_fail (IS_VOIP_INPUT_WIDGET (userdata)); - VoipInputWidget* mitem = VOIP_INPUT_WIDGET(userdata); - VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(mitem); - if(g_ascii_strcasecmp(DBUSMENU_VOIP_INPUT_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_voip_input_slider); - GtkRange *range = (GtkRange*)slider; - gdouble update = g_variant_get_double (value); - //g_debug("volume-widget - update level with value %f", update); - gtk_range_set_value(range, update); - } - } - if(g_ascii_strcasecmp(DBUSMENU_VOIP_INPUT_MENUITEM_MUTE, property) == 0){ - if(priv->grabbed == FALSE){ - g_return_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE_INT32)); - GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_voip_input_slider); - GtkRange *range = (GtkRange*)slider; - gint update = g_variant_get_int32 (value); - gdouble level; - if (update == 1){ - level = 0; - } - else{ - GVariant* variant = dbusmenu_menuitem_property_get_variant (priv->twin_item, - DBUSMENU_VOIP_INPUT_MENUITEM_LEVEL); - g_return_if_fail (g_variant_is_of_type (variant, G_VARIANT_TYPE_DOUBLE)); - level = g_variant_get_double (variant); - } - gtk_range_set_value(range, level); - - g_debug ("voip-item-widget - update mute with value %i", update); - } - } -} - -static void -voip_input_widget_set_twin_item (VoipInputWidget* self, - DbusmenuMenuitem* twin_item) -{ - VoipInputWidgetPrivate * priv = VOIP_INPUT_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(voip_input_widget_property_update), self); - gdouble initial_level = g_variant_get_double (dbusmenu_menuitem_property_get_variant(twin_item, - DBUSMENU_VOIP_INPUT_MENUITEM_LEVEL)); - //g_debug("voip_input_widget_set_twin_item initial level = %f", initial_level); - GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_voip_input_slider); - GtkRange *range = (GtkRange*)slider; - gtk_range_set_value(range, initial_level); - - gint mute = g_variant_get_int32 (dbusmenu_menuitem_property_get_variant (priv->twin_item, - DBUSMENU_VOIP_INPUT_MENUITEM_MUTE)); - if (mute == 1){ - gtk_range_set_value (range, 0.0); - } -} - -static gboolean -voip_input_widget_change_value_cb (GtkRange *range, - GtkScrollType scroll, - gdouble new_value, - gpointer user_data) -{ - g_return_val_if_fail (IS_VOIP_INPUT_WIDGET (user_data), FALSE); - VoipInputWidget* mitem = VOIP_INPUT_WIDGET(user_data); - voip_input_widget_update(mitem, new_value); - return FALSE; -} - - -/** - * We only want this callback to catch mouse icon press events which set the - * slider to 0 or 100. Ignore all other events including the new Mute behaviour - * (slider to go to 0 on mute without setting the level to 0 and return to - * previous level on unmute) - **/ -static gboolean -voip_input_widget_value_changed_cb(GtkRange *range, gpointer user_data) -{ - g_return_val_if_fail (IS_VOIP_INPUT_WIDGET (user_data), FALSE); - VoipInputWidget* mitem = VOIP_INPUT_WIDGET(user_data); - VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(mitem); - GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_voip_input_slider); - gdouble current_value = CLAMP(gtk_range_get_value(GTK_RANGE(slider)), 0, 100); - - gint mute = g_variant_get_int32 (dbusmenu_menuitem_property_get_variant (priv->twin_item, - DBUSMENU_VOIP_INPUT_MENUITEM_MUTE)); - if ((current_value == 0 && mute != 1) || current_value == 100 ){ - voip_input_widget_update(mitem, current_value); - } - return FALSE; -} - -void -voip_input_widget_update(VoipInputWidget* self, gdouble update) -{ - VoipInputWidgetPrivate * priv = VOIP_INPUT_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, "update", new_volume, 0); -} - -GtkWidget* -voip_input_widget_get_ido_slider(VoipInputWidget* self) -{ - VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(self); - return priv->ido_voip_input_slider; -} - -static void -voip_input_widget_parent_changed (GtkWidget *widget, - gpointer user_data) -{ - gtk_widget_set_size_request (widget, 200, -1); - //g_debug("voip_input_widget_parent_changed"); -} - -static void -voip_input_widget_slider_grabbed(GtkWidget *widget, gpointer user_data) -{ - VoipInputWidget* mitem = VOIP_INPUT_WIDGET(user_data); - VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(mitem); - priv->grabbed = TRUE; -} - -static void -voip_input_widget_slider_released(GtkWidget *widget, gpointer user_data) -{ - VoipInputWidget* mitem = VOIP_INPUT_WIDGET(user_data); - VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(mitem); - priv->grabbed = FALSE; -} - -void -voip_input_widget_tidy_up (GtkWidget *widget) -{ - VoipInputWidget* mitem = VOIP_INPUT_WIDGET(widget); - VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(mitem); - gtk_widget_destroy (priv->ido_voip_input_slider); -} - -/** - * voip_input_widget_new: - * @returns: a new #VoipInputWidget. - **/ -GtkWidget* -voip_input_widget_new(DbusmenuMenuitem *item) -{ - GtkWidget* widget = g_object_new(VOIP_INPUT_WIDGET_TYPE, NULL); - voip_input_widget_set_twin_item((VoipInputWidget*)widget, item); - return widget; -} - - diff --git a/src/voip-input-widget.h b/src/voip-input-widget.h deleted file mode 100644 index 72da80c..0000000 --- a/src/voip-input-widget.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -Copyright 2011 Canonical Ltd. - -Authors: - Conor Curran - -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 . -*/ -#ifndef __VOIP_INPUT_WIDGET_H__ -#define __VOIP_INPUT_WIDGET_H__ - -#include -#include -#include -#include - -G_BEGIN_DECLS - -#define VOIP_INPUT_WIDGET_TYPE (voip_input_widget_get_type ()) -#define VOIP_INPUT_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), VOIP_INPUT_WIDGET_TYPE, VoipInputWidget)) -#define VOIP_INPUT_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), VOIP_INPUT_WIDGET_TYPE, VoipInputWidgetClass)) -#define IS_VOIP_INPUT_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VOIP_INPUT_WIDGET_TYPE)) -#define IS_VOIP_INPUT_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), VOIP_INPUT_WIDGET_TYPE)) -#define VOIP_INPUT_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), VOIP_INPUT_WIDGET_TYPE, VoipInputWidgetClass)) - -typedef struct _VoipInputWidget VoipInputWidget; -typedef struct _VoipInputWidgetClass VoipInputWidgetClass; - -struct _VoipInputWidgetClass { - GObjectClass parent_class; -}; - -struct _VoipInputWidget { - GObject parent; -}; - -GType voip_input_widget_get_type (void) G_GNUC_CONST; -GtkWidget* voip_input_widget_new(DbusmenuMenuitem* twin_item); -GtkWidget* voip_input_widget_get_ido_slider(VoipInputWidget* self); -void voip_input_widget_update(VoipInputWidget* self, gdouble update); -void voip_input_widget_tidy_up (GtkWidget *widget); - -G_END_DECLS - -#endif - diff --git a/src/volume-widget.c b/src/volume-widget.c deleted file mode 100644 index 1258c20..0000000 --- a/src/volume-widget.c +++ /dev/null @@ -1,338 +0,0 @@ - -/* -Copyright 2010 Canonical Ltd. - -Authors: - Conor Curran - -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 . -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include "volume-widget.h" -#include "common-defs.h" -#include -#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) ); - gdouble update = g_variant_get_double (value); - - if(priv->grabbed == FALSE){ - GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_volume_slider); - GtkRange *range = (GtkRange*)slider; - gtk_range_set_value(range, update); -/* - g_debug ("volume-widget::volume_widget_property_update - volume - value %f", update); - AtkObject* atk_object; - atk_object = gtk_widget_get_accessible (priv->ido_volume_slider); - if (atk_object != NULL){ - atk_object_set_name (atk_object, desc); - - }*/ - } - gchar* desc = g_strdup_printf(_("Volume (%'.0f%%)"), - update); - dbusmenu_menuitem_property_set (priv->twin_item, - DBUSMENU_MENUITEM_PROP_ACCESSIBLE_DESC, - desc); - g_free (desc); - 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); - gchar* desc = g_strdup_printf(_("Volume (%'.0f%%)"), - initial_level); - dbusmenu_menuitem_property_set (priv->twin_item, - DBUSMENU_MENUITEM_PROP_ACCESSIBLE_DESC, - desc); - g_free (desc); - -} - -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; -} - - diff --git a/src/volume-widget.h b/src/volume-widget.h deleted file mode 100644 index 665f39b..0000000 --- a/src/volume-widget.h +++ /dev/null @@ -1,58 +0,0 @@ -/* -Copyright 2010 Canonical Ltd. - -Authors: - Conor Curran - -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 . -*/ -#ifndef __VOLUME_WIDGET_H__ -#define __VOLUME_WIDGET_H__ - -#include -#include -#include -#include -#include - -G_BEGIN_DECLS - -#define VOLUME_WIDGET_TYPE (volume_widget_get_type ()) -#define VOLUME_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), VOLUME_WIDGET_TYPE, VolumeWidget)) -#define VOLUME_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), VOLUME_WIDGET_TYPE, VolumeWidgetClass)) -#define IS_VOLUME_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VOLUME_WIDGET_TYPE)) -#define IS_VOLUME_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), VOLUME_WIDGET_TYPE)) -#define VOLUME_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), VOLUME_WIDGET_TYPE, VolumeWidgetClass)) - -typedef struct _VolumeWidget VolumeWidget; -typedef struct _VolumeWidgetClass VolumeWidgetClass; - -struct _VolumeWidgetClass { - GObjectClass parent_class; -}; - -struct _VolumeWidget { - GObject parent; -}; - -GType volume_widget_get_type (void) G_GNUC_CONST; -GtkWidget* volume_widget_new(DbusmenuMenuitem *item, IndicatorObject* io); -GtkWidget* volume_widget_get_ido_slider(VolumeWidget* self); -void volume_widget_update(VolumeWidget* self, gdouble update, gchar* label); -void volume_widget_tidy_up (GtkWidget *widget); -gdouble volume_widget_get_current_volume ( GtkWidget *widget ); - -G_END_DECLS - -#endif - -- cgit v1.2.3