diff options
-rw-r--r-- | src/common-defs.h | 1 | ||||
-rw-r--r-- | src/indicator-sound.c | 29 | ||||
-rw-r--r-- | src/mpris2-controller.vala | 22 | ||||
-rw-r--r-- | src/play-button.c | 11 | ||||
-rw-r--r-- | src/player-controller.vala | 6 | ||||
-rw-r--r-- | src/title-menu-item.vala | 7 | ||||
-rw-r--r-- | src/title-widget.c | 130 | ||||
-rw-r--r-- | src/title-widget.h | 6 | ||||
-rw-r--r-- | src/transport-menu-item.vala | 11 | ||||
-rw-r--r-- | vapi/common-defs.vapi | 1 |
10 files changed, 148 insertions, 76 deletions
diff --git a/src/common-defs.h b/src/common-defs.h index e554c11..e268aaa 100644 --- a/src/common-defs.h +++ b/src/common-defs.h @@ -41,6 +41,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #define DBUSMENU_TITLE_MENUITEM_TYPE "x-canonical-sound-menu-player-title-type" #define DBUSMENU_TITLE_MENUITEM_NAME "x-canonical-sound-menu-player-title-name" +#define DBUSMENU_TITLE_MENUITEM_RUNNING "x-canonical-sound-menu-player-title-running" #define DBUSMENU_SCRUB_MENUITEM_TYPE "x-canonical-sound-menu-player-scrub-type" #define DBUSMENU_SCRUB_MENUITEM_DURATION "x-canonical-sound-menu-player-scrub-mpris:length" diff --git a/src/indicator-sound.c b/src/indicator-sound.c index b59eb98..0e631fa 100644 --- a/src/indicator-sound.c +++ b/src/indicator-sound.c @@ -196,8 +196,10 @@ get_label (IndicatorObject * io) static GtkImage * get_icon (IndicatorObject * io) { - gchar* current_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(current_state)); - g_debug("At start-up attempting to set the image to %s", current_name); + gchar* current_name = g_hash_table_lookup(volume_states, + GINT_TO_POINTER(current_state)); + g_debug("At start-up attempting to set the image to %s", + current_name); speaker_image = indicator_image_helper(current_name); gtk_widget_show(GTK_WIDGET(speaker_image)); return speaker_image; @@ -209,7 +211,8 @@ get_icon (IndicatorObject * io) static GtkMenu * get_menu (IndicatorObject * io) { - DbusmenuGtkMenu *menu = dbusmenu_gtkmenu_new(INDICATOR_SOUND_DBUS_NAME, INDICATOR_SOUND_DBUS_OBJECT); + DbusmenuGtkMenu* menu = dbusmenu_gtkmenu_new(INDICATOR_SOUND_DBUS_NAME, INDICATOR_SOUND_DBUS_OBJECT); + 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); @@ -217,10 +220,10 @@ get_menu (IndicatorObject * io) dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), DBUSMENU_METADATA_MENUITEM_TYPE, new_metadata_widget); dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), DBUSMENU_TITLE_MENUITEM_TYPE, new_title_widget); dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), DBUSMENU_SCRUB_MENUITEM_TYPE, new_scrub_bar_widget); - // register Key-press listening on the menu widget as the slider does not allow this. g_signal_connect(menu, "key-press-event", G_CALLBACK(key_press_cb), io); - return GTK_MENU(menu); + + return GTK_MENU(menu); } static void @@ -274,20 +277,22 @@ new_metadata_widget(DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, Dbusm static gboolean new_title_widget(DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client) { - g_debug("indicator-sound: new_title_widget"); - - GtkWidget* title = NULL; - + g_debug("indicator-sound: new_title_widget"); g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE); g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE); + g_debug ("%s (\"%s\")", __func__, dbusmenu_menuitem_property_get(newitem, DBUSMENU_TITLE_MENUITEM_NAME)); + + GtkWidget* title = NULL; + title = title_widget_new (newitem); GtkMenuItem *menu_title_widget = GTK_MENU_ITEM(title); - + gtk_widget_show_all(title); - dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, menu_title_widget, parent); - + dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), + newitem, + menu_title_widget, parent); return TRUE; } diff --git a/src/mpris2-controller.vala b/src/mpris2-controller.vala index cf5a39e..dab5e2c 100644 --- a/src/mpris2-controller.vala +++ b/src/mpris2-controller.vala @@ -105,7 +105,7 @@ public class Mpris2Controller : GLib.Object if(play_v != null){ string state = play_v.get_string(); debug("new playback state = %s", state); - int p = this.determine_play_state(state); + TransportMenuitem.state p = (TransportMenuitem.state)this.determine_play_state(state); (this.owner.custom_items[PlayerController.widget_order.TRANSPORT] as TransportMenuitem).change_play_state(p); } @@ -143,29 +143,29 @@ public class Mpris2Controller : GLib.Object } - private int determine_play_state(string status){ + private TransportMenuitem.state determine_play_state(string status){ if(status == null) - return 1; + return TransportMenuitem.state.PAUSED; if(status != null && status == "Playing"){ debug("determine play state - state = %s", status); - return 0; + return TransportMenuitem.state.PLAYING; } - return 1; + return TransportMenuitem.state.PAUSED; } public void initial_update() { - int32 status; + TransportMenuitem.state update; if(this.player.PlaybackStatus == null){ - status = 1; + update = TransportMenuitem.state.PAUSED; } else{ - status = determine_play_state(this.player.PlaybackStatus); + update = determine_play_state(this.player.PlaybackStatus); } - debug("initial update - play state %i", status); + debug("initial update - play state %i", (int)update); - (this.owner.custom_items[PlayerController.widget_order.TRANSPORT] as TransportMenuitem).change_play_state(status); + (this.owner.custom_items[PlayerController.widget_order.TRANSPORT] as TransportMenuitem).change_play_state(update); GLib.HashTable<string, Value?> cleaned_metadata = this.clean_metadata(); this.owner.custom_items[PlayerController.widget_order.METADATA].update(cleaned_metadata, MetadataMenuitem.attributes_format()); @@ -260,7 +260,7 @@ public class Mpris2Controller : GLib.Object this.mpris2_root.Raise(); } catch(DBus.Error e){ - error("Exception thrown while calling root function Raise - %s", e.message); + error("Exception thrown while calling function Raise - %s", e.message); } } } diff --git a/src/play-button.c b/src/play-button.c index ccc23cb..0c934e5 100644 --- a/src/play-button.c +++ b/src/play-button.c @@ -388,19 +388,20 @@ determine_button_event(GtkWidget* button, GdkEventButton* event) g_debug("event y coordinate = %f", event->y); PlayButtonEvent button_event = TRANSPORT_NADA; // For now very simple rectangular collision detection - if(event->x > 55 && event->x < 95 + if(event->x > 67 && event->x < 112 && event->y > 12 && event->y < 40){ button_event = TRANSPORT_PREVIOUS; } - else if(event->x > 99 && event->x < 136 + else if(event->x > 111 && event->x < 153 && event->y > 5 && event->y < 47){ button_event = TRANSPORT_PLAY_PAUSE; } - else if(event->x > 137 && event->x < 179 + else if(event->x > 152 && event->x < 197 && event->y > 12 && event->y < 40){ button_event = TRANSPORT_NEXT; } return button_event; + } void @@ -730,8 +731,8 @@ draw (GtkWidget* button, cairo_t *cr) cairo_surface_t* surf = NULL; cairo_t* cr_surf = NULL; - double INNER_START[] = {229.0f/255.0f, 223.0f/255.0f, 215.0f/255.0f, 1.0f}; - double INNER_END[] = {183.0f / 255.0f, 178.0f / 255.0f, 172.0f / 255.0f, 1.0f}; + //double INNER_START[] = {229.0f/255.0f, 223.0f/255.0f, 215.0f/255.0f, 1.0f}; + //double INNER_END[] = {183.0f / 255.0f, 178.0f / 255.0f, 172.0f / 255.0f, 1.0f}; double MIDDLE_START[] = {61.0f / 255.0f, 60.0f / 255.0f, 57.0f / 255.0f, 1.0f}; double MIDDLE_END[] = {94.0f / 255.0f,93.0f / 255.0f, 90.0f / 255.0f,1.0f}; double OUTER_START[] = {36.0f / 255.0f, 35.0f / 255.0f, 33.0f / 255.0f, 1.0f}; diff --git a/src/player-controller.vala b/src/player-controller.vala index 4d9f054..f5ec205 100644 --- a/src/player-controller.vala +++ b/src/player-controller.vala @@ -116,6 +116,8 @@ public class PlayerController : GLib.Object update_state(PlayerController.state.OFFLINE); this.custom_items[widget_order.TRANSPORT].reset(TransportMenuitem.attributes_format()); this.custom_items[widget_order.METADATA].reset(MetadataMenuitem.attributes_format()); + TitleMenuitem title = this.custom_items[widget_order.TITLE] as TitleMenuitem; + title.toggle_active_triangle(false); } public void update_layout() @@ -172,6 +174,10 @@ public class PlayerController : GLib.Object { if(this.mpris_bridge.connected() == true){ this.update_state(state.CONNECTED); + TitleMenuitem title = this.custom_items[widget_order.TITLE] as TitleMenuitem; + title.toggle_active_triangle(true); + TransportMenuitem transport = this.custom_items[widget_order.TRANSPORT] as TransportMenuitem; + transport.change_play_state(TransportMenuitem.state.PAUSED); } else{ this.update_state(state.DISCONNECTED); diff --git a/src/title-menu-item.vala b/src/title-menu-item.vala index ec1cc62..bb3d103 100644 --- a/src/title-menu-item.vala +++ b/src/title-menu-item.vala @@ -27,6 +27,7 @@ public class TitleMenuitem : PlayerItem { Object(item_type: MENUITEM_TYPE, owner: parent); this.property_set(MENUITEM_NAME, parent.name); + this.property_set_bool(MENUITEM_RUNNING, false); } public override void handle_event(string name, GLib.Value input_value, uint timestamp) @@ -39,7 +40,11 @@ public class TitleMenuitem : PlayerItem this.owner.mpris_bridge.expose(); } } - + + public void toggle_active_triangle(bool update) + { + this.property_set_bool(MENUITEM_RUNNING, update); + } public static HashSet<string> attributes_format() { diff --git a/src/title-widget.c b/src/title-widget.c index e9f34d6..1146818 100644 --- a/src/title-widget.c +++ b/src/title-widget.c @@ -32,10 +32,7 @@ typedef struct _TitleWidgetPrivate TitleWidgetPrivate; struct _TitleWidgetPrivate { - GtkWidget* hbox; - GtkWidget* name; - GtkWidget* player_icon; - DbusmenuMenuitem* twin_item; + DbusmenuMenuitem* twin_item; }; #define TITLE_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TITLE_WIDGET_TYPE, TitleWidgetPrivate)) @@ -54,10 +51,12 @@ static gboolean title_widget_button_press_event (GtkWidget *menuitem, static void title_widget_property_update(DbusmenuMenuitem* item, gchar* property, GValue* value, gpointer userdata); static void title_widget_set_twin_item( TitleWidget* self, - DbusmenuMenuitem* twin_item); -static void title_widget_style_name_text(TitleWidget* self); + DbusmenuMenuitem* twin_item); +static gboolean title_widget_triangle_draw_cb (GtkWidget *widget, + GdkEventExpose *event, + gpointer data); -G_DEFINE_TYPE (TitleWidget, title_widget, GTK_TYPE_MENU_ITEM); +G_DEFINE_TYPE (TitleWidget, title_widget, GTK_TYPE_IMAGE_MENU_ITEM); @@ -73,7 +72,6 @@ title_widget_class_init (TitleWidgetClass *klass) gobject_class->dispose = title_widget_dispose; gobject_class->finalize = title_widget_finalize; - } static void @@ -81,15 +79,22 @@ title_widget_init (TitleWidget *self) { g_debug("TitleWidget::title_widget_init"); - TitleWidgetPrivate * priv = TITLE_WIDGET_GET_PRIVATE(self); + gint padding = 0; + gtk_widget_style_get(GTK_WIDGET(self), "horizontal-padding", &padding, NULL); + + gint width, height; + gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height); - GtkWidget *hbox; + GtkWidget * icon = gtk_image_new_from_icon_name("sound_icon", GTK_ICON_SIZE_MENU); - hbox = gtk_hbox_new(FALSE, 0); - priv->hbox = hbox; + gtk_widget_set_size_request(icon, width + + 5 /* ref triangle is 5x9 pixels */ + + 1 /* padding */, + height); + gtk_misc_set_alignment(GTK_MISC(icon), 0.5 /* right aligned */, 0); + gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(self), GTK_WIDGET(icon)); + gtk_widget_show(icon); - priv->player_icon = indicator_image_helper("sound_icon"); - gtk_box_pack_start(GTK_BOX (priv->hbox), priv->player_icon, FALSE, FALSE, 0); } static void @@ -127,11 +132,10 @@ title_widget_property_update(DbusmenuMenuitem* item, gchar* property, { g_return_if_fail (IS_TITLE_WIDGET (userdata)); TitleWidget* mitem = TITLE_WIDGET(userdata); - TitleWidgetPrivate * priv = TITLE_WIDGET_GET_PRIVATE(mitem); - - if(g_ascii_strcasecmp(DBUSMENU_TITLE_MENUITEM_NAME, property) == 0){ - gtk_label_set_text(GTK_LABEL(priv->name), g_value_get_string(value)); - title_widget_style_name_text(mitem); + + if(g_ascii_strcasecmp(DBUSMENU_TITLE_MENUITEM_NAME, property) == 0){ + gtk_menu_item_set_label (GTK_MENU_ITEM(mitem), + g_value_get_string(value)); } } @@ -139,33 +143,72 @@ static void title_widget_set_twin_item(TitleWidget* self, DbusmenuMenuitem* twin_item) { - TitleWidgetPrivate * priv = TITLE_WIDGET_GET_PRIVATE(self); - priv->twin_item = twin_item; - g_signal_connect(G_OBJECT(twin_item), "property-changed", - G_CALLBACK(title_widget_property_update), self); - priv->name = gtk_label_new(dbusmenu_menuitem_property_get(priv->twin_item, - DBUSMENU_TITLE_MENUITEM_NAME)); - gtk_misc_set_padding(GTK_MISC(priv->name), 10, 0); - gtk_box_pack_start (GTK_BOX (priv->hbox), priv->name, FALSE, FALSE, 0); - - title_widget_style_name_text(self); - - gtk_widget_show_all (priv->hbox); - gtk_container_add (GTK_CONTAINER (self), priv->hbox); + TitleWidgetPrivate *priv = TITLE_WIDGET_GET_PRIVATE(self); + + priv->twin_item = twin_item; + + g_signal_connect (G_OBJECT (twin_item), + "property-changed", + G_CALLBACK (title_widget_property_update), + self); + g_signal_connect_after (G_OBJECT (self), + "expose_event", + G_CALLBACK (title_widget_triangle_draw_cb), + twin_item); + + gtk_menu_item_set_label (GTK_MENU_ITEM(self), + dbusmenu_menuitem_property_get(priv->twin_item, + DBUSMENU_TITLE_MENUITEM_NAME)); + } -static void -title_widget_style_name_text(TitleWidget* self) +static gboolean +title_widget_triangle_draw_cb (GtkWidget *widget, GdkEventExpose *event, gpointer data) { - TitleWidgetPrivate * priv = TITLE_WIDGET_GET_PRIVATE(self); + GtkStyle *style; + cairo_t *cr; + int x, y, arrow_width, arrow_height; + + if (!GTK_IS_WIDGET (widget)) return FALSE; + if (!DBUSMENU_IS_MENUITEM (data)) return FALSE; + + /* render the triangle indicator only if the application is running */ + if (! dbusmenu_menuitem_property_get_bool (DBUSMENU_MENUITEM(data), + DBUSMENU_TITLE_MENUITEM_RUNNING)){ + return FALSE; + } + + /* get style */ + style = gtk_widget_get_style (widget); + + /* set arrow position / dimensions */ + arrow_width = 5; /* the pixel-based reference triangle is 5x9 */ + arrow_height = 9; + x = widget->allocation.x; + y = widget->allocation.y + widget->allocation.height/2.0 - (double)arrow_height/2.0; + + /* initialize cairo drawing area */ + cr = (cairo_t*) gdk_cairo_create (widget->window); + + /* set line width */ + cairo_set_line_width (cr, 1.0); + + /* cairo drawing code */ + 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); + + /* remember to destroy cairo context to avoid leaks */ + cairo_destroy (cr); - char* markup; - markup = g_markup_printf_escaped ("<span size=\"medium\">%s</span>", - gtk_label_get_text(GTK_LABEL(priv->name))); - gtk_label_set_markup (GTK_LABEL (priv->name), markup); - g_free(markup); + return FALSE; } - + /** * transport_new: * @returns: a new #TitleWidget. @@ -173,8 +216,11 @@ title_widget_style_name_text(TitleWidget* self) GtkWidget* title_widget_new(DbusmenuMenuitem *item) { - GtkWidget* widget = g_object_new(TITLE_WIDGET_TYPE, NULL); + GtkWidget* widget = g_object_new (TITLE_WIDGET_TYPE, + NULL); + gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (widget), TRUE); title_widget_set_twin_item((TitleWidget*)widget, item); + return widget; } diff --git a/src/title-widget.h b/src/title-widget.h index fc8f169..574a2b1 100644 --- a/src/title-widget.h +++ b/src/title-widget.h @@ -19,7 +19,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #ifndef __TITLE_WIDGET_H__ #define __TITLE_WIDGET_H__ -#include <gtk/gtkmenuitem.h> +#include <gtk/gtkimagemenuitem.h> #include <libdbusmenu-gtk/menuitem.h> G_BEGIN_DECLS @@ -35,11 +35,11 @@ typedef struct _TitleWidget TitleWidget; typedef struct _TitleWidgetClass TitleWidgetClass; struct _TitleWidgetClass { - GtkMenuItemClass parent_class; + GtkImageMenuItemClass parent_class; }; struct _TitleWidget { - GtkMenuItem parent; + GtkImageMenuItem parent; }; GType title_widget_get_type (void); diff --git a/src/transport-menu-item.vala b/src/transport-menu-item.vala index 8bdd2c8..7faadb5 100644 --- a/src/transport-menu-item.vala +++ b/src/transport-menu-item.vala @@ -28,6 +28,11 @@ public class TransportMenuitem : PlayerItem PLAY_PAUSE, NEXT } + + public enum state{ + PLAYING, + PAUSED + } public TransportMenuitem(PlayerController parent) { @@ -35,9 +40,9 @@ public class TransportMenuitem : PlayerItem this.property_set_int(MENUITEM_PLAY_STATE, 1); } - public void change_play_state(int state) + public void change_play_state(state update) { - this.property_set_int(MENUITEM_PLAY_STATE, state); + this.property_set_int(MENUITEM_PLAY_STATE, update); } public override void handle_event(string name, GLib.Value input_value, uint timestamp) @@ -54,4 +59,6 @@ public class TransportMenuitem : PlayerItem attrs.add(MENUITEM_PLAY_STATE); return attrs; } + + }
\ No newline at end of file diff --git a/vapi/common-defs.vapi b/vapi/common-defs.vapi index 84fb924..9d49a92 100644 --- a/vapi/common-defs.vapi +++ b/vapi/common-defs.vapi @@ -36,6 +36,7 @@ namespace DbusmenuTransport{ namespace DbusmenuTitle{ public const string MENUITEM_TYPE; public const string MENUITEM_NAME; + public const string MENUITEM_RUNNING; } [CCode (cheader_filename = "common-defs.h")] |