aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorConor Curran <conor.curran@canonical.com>2010-09-30 14:01:33 +0100
committerConor Curran <conor.curran@canonical.com>2010-09-30 14:01:33 +0100
commit73222788ef78e4adad1c9e8b73ff786280ad6296 (patch)
tree5a69884feeecb9327e8e0f7b84605da680b8fb2a /src
parent28727032a4878897a30b3a81d6e2110f929d26ae (diff)
downloadayatana-indicator-sound-73222788ef78e4adad1c9e8b73ff786280ad6296.tar.gz
ayatana-indicator-sound-73222788ef78e4adad1c9e8b73ff786280ad6296.tar.bz2
ayatana-indicator-sound-73222788ef78e4adad1c9e8b73ff786280ad6296.zip
one big refactor
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am28
-rw-r--r--src/play-button.c1216
-rw-r--r--src/play-button.h68
-rw-r--r--src/title-widget.c2
-rw-r--r--src/transport-widget-old.c231
-rw-r--r--src/transport-widget-old.h51
-rw-r--r--src/transport-widget.c1250
-rw-r--r--src/transport-widget.h15
8 files changed, 1469 insertions, 1392 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index aa5fdc7..b23e9c1 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -7,21 +7,19 @@ libexec_PROGRAMS = indicator-sound-service
soundmenulibdir = $(INDICATORDIR)
soundmenulib_LTLIBRARIES = libsoundmenu.la
libsoundmenu_la_SOURCES = \
- common-defs.h \
- indicator-sound.h \
- transport-widget.c \
- transport-widget.h \
- metadata-widget.c \
- metadata-widget.h \
- play-button.c \
- play-button.h \
- indicator-sound.c \
- title-widget.c \
- title-widget.h \
- volume-widget.c \
- volume-widget.h \
- dbus-shared-names.h \
- sound-service-client.h
+ common-defs.h \
+ indicator-sound.h \
+ transport-widget.c \
+ transport-widget.h \
+ metadata-widget.c \
+ metadata-widget.h \
+ indicator-sound.c \
+ title-widget.c \
+ title-widget.h \
+ volume-widget.c \
+ volume-widget.h \
+ dbus-shared-names.h \
+ sound-service-client.h
libsoundmenu_la_CFLAGS = $(APPLET_CFLAGS) -Wall -DG_LOG_DOMAIN=\"Indicator-Sound\"
libsoundmenu_la_LIBADD = $(APPLET_LIBS)
diff --git a/src/play-button.c b/src/play-button.c
deleted file mode 100644
index 2ee304a..0000000
--- a/src/play-button.c
+++ /dev/null
@@ -1,1216 +0,0 @@
-/*
-Copyright 2010 Canonical Ltd.
-
-Authors:
- Conor Curran <conor.curran@canonical.com>
- Mirco Müller <mirco.mueller@canonical.com>
-
-This program is free software: you can redistribute it and/or modify it
-under the terms of the GNU General Public License version 3, as published
-by the Free Software Foundation.
-
-This program is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranties of
-MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
-PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with this program. If not, see <http://www.gnu.org/licenses/>.
-
-Uses code from ctk
-*/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <math.h>
-#include "play-button.h"
-
-#define RECT_WIDTH 130.0f
-#define Y 7.0f
-#define X 37.0f
-#define INNER_RADIUS 12.5
-#define MIDDLE_RADIUS 13.5f
-#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 35.0f
-#define PREV_Y 13.0f
-#define NEXT_X 113.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 78.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 0.7
-#define MIDDLE_END_SHADE 1.4
-#define OUTER_START_SHADE 0.96
-#define OUTER_END_SHADE 0.96
-#define BUTTON_START_SHADE 1.1
-#define BUTTON_END_SHADE 0.9
-#define BUTTON_SHADOW_SHADE 0.8
-#define INNER_COMPRESSED_START_SHADE 0.95
-#define INNER_COMPRESSED_END_SHADE 1.05
-
-
-typedef struct _PlayButtonPrivate PlayButtonPrivate;
-
-struct _PlayButtonPrivate
-{
- GdkColor background_colour_fg;
- GdkColor background_colour_bg_dark;
- GdkColor background_colour_bg_light;
- GdkColor foreground_colour_fg;
- GdkColor foreground_colour_bg;
- PlayButtonEvent current_command;
- PlayButtonState current_state;
- GHashTable* command_coordinates;
-};
-
-typedef struct
-{
- double r;
- double g;
- double b;
-} CairoColorRGB;
-
-
-#define PLAY_BUTTON_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PLAY_BUTTON_TYPE, PlayButtonPrivate))
-
-/* Gobject boiler plate */
-static void play_button_class_init (PlayButtonClass *klass);
-static void play_button_init (PlayButton *self);
-static void play_button_dispose (GObject *object);
-static void play_button_finalize (GObject *object);
-
-static gboolean play_button_expose (GtkWidget *button, GdkEventExpose *event);
-
-static void draw (GtkWidget* button, cairo_t *cr);
-
-G_DEFINE_TYPE (PlayButton, play_button, GTK_TYPE_MENU_ITEM);
-
-
-/// GObject functions //////////////////////////////////////////////////////////
-
-static void
-play_button_class_init (PlayButtonClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- GtkWidgetClass* widget_class = GTK_WIDGET_CLASS (klass);
-
- g_type_class_add_private (klass, sizeof (PlayButtonPrivate));
-
- widget_class->expose_event = play_button_expose;
-
- gobject_class->dispose = play_button_dispose;
- gobject_class->finalize = play_button_finalize;
-}
-
-static void
-play_button_init (PlayButton *self)
-{
- PlayButtonPrivate* priv = PLAY_BUTTON_GET_PRIVATE(self);
- priv->current_command = TRANSPORT_NADA;
- priv->current_state = PAUSE;
- 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_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_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_NEXT),
- next_list);
-
- gtk_widget_set_size_request(GTK_WIDGET(self), 200, 50);
-
-}
-
-static void
-play_button_dispose (GObject *object)
-{
- G_OBJECT_CLASS (play_button_parent_class)->dispose (object);
-}
-
-static void
-play_button_finalize (GObject *object)
-{
- G_OBJECT_CLASS (play_button_parent_class)->finalize (object);
-}
-
-static gboolean
-play_button_expose (GtkWidget *button, GdkEventExpose *event)
-{
- cairo_t *cr;
- cr = gdk_cairo_create (button->window);
-
- //GtkAllocation alloc;
- //gtk_widget_get_allocation (metadata, &alloc);
-/* */
-/* g_debug("In the playbutton's expose method, x = %i, y=%i and width: %i and height: %i'");*/
-/* 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;
-}
-
-
-PlayButtonEvent
-determine_button_event(GtkWidget* button, GdkEventButton* event)
-{
- g_debug("event x coordinate = %f", event->x);
- g_debug("event y coordinate = %f", event->y);
- PlayButtonEvent button_event = TRANSPORT_NADA;
- // For now very simple rectangular collision detection
- if(event->x > 67 && event->x < 112
- && event->y > 12 && event->y < 40){
- button_event = TRANSPORT_PREVIOUS;
- }
- else if(event->x > 111 && event->x < 153
- && event->y > 5 && event->y < 47){
- button_event = TRANSPORT_PLAY_PAUSE;
- }
- else if(event->x > 152 && event->x < 197
- && event->y > 12 && event->y < 40){
- button_event = TRANSPORT_NEXT;
- }
- return button_event;
-
-}
-
-void
-play_button_react_to_button_press(GtkWidget* button, PlayButtonEvent command)
-{
- g_return_if_fail(IS_PLAY_BUTTON(button));
- PlayButtonPrivate* priv = PLAY_BUTTON_GET_PRIVATE(button);
- priv->current_command = command;
-
- cairo_t *cr;
- cr = gdk_cairo_create (button->window);
-
- draw (button, cr);
- cairo_destroy (cr);
-}
-
-
-void
-play_button_react_to_button_release(GtkWidget* button, PlayButtonEvent command)
-{
- g_return_if_fail(IS_PLAY_BUTTON(button));
- PlayButtonPrivate* priv = PLAY_BUTTON_GET_PRIVATE(button);
- if(priv->current_command == TRANSPORT_NADA){
- g_debug("returning from the playbutton release because my previous command was nada");
- return;
- }
- else if(priv->current_command != TRANSPORT_NADA &&
- command != TRANSPORT_NADA){
- priv->current_command = command;
- }
-
- cairo_t *cr;
-
- cr = gdk_cairo_create (button->window);
-
- priv->current_command = TRANSPORT_NADA;
-
- draw (button, cr);
- cairo_destroy (cr);
-}
-
-void
-play_button_toggle_play_pause(GtkWidget* button, PlayButtonState update)
-{
- PlayButtonPrivate* priv = PLAY_BUTTON_GET_PRIVATE(button);
- priv->current_state = update;
- g_debug("PlayButton::toggle play state : %i", priv->current_state);
- gtk_widget_queue_draw (GTK_WIDGET(button));
-}
-
-
-void
-play_button_set_style(GtkWidget* button, GtkStyle* style)
-{
- PlayButtonPrivate* priv = PLAY_BUTTON_GET_PRIVATE(button);
- priv->background_colour_fg = style->fg[GTK_STATE_NORMAL];
- priv->background_colour_bg_dark = style->bg[GTK_STATE_NORMAL];
- priv->background_colour_bg_light = style->base[GTK_STATE_NORMAL];
- priv->foreground_colour_fg = style->fg[GTK_STATE_PRELIGHT];
- priv->foreground_colour_bg = style->bg[GTK_STATE_NORMAL];
-}
-
-/// 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
- /*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);
- 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
-_color_rgb_to_hls (gdouble *r,
- gdouble *g,
- gdouble *b)
-{
- gdouble min;
- gdouble max;
- gdouble red;
- gdouble green;
- gdouble blue;
- gdouble h, l, 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;
- }
-}
-
-static 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 void
-draw (GtkWidget* button, cairo_t *cr)
-{
- g_return_if_fail(IS_PLAY_BUTTON(button));
- PlayButtonPrivate* priv = PLAY_BUTTON_GET_PRIVATE(button);
-
- cairo_surface_t* surf = NULL;
- cairo_t* cr_surf = NULL;
-
- cairo_translate (cr, button->allocation.x, button->allocation.y);
-
- g_debug("button x allocation = %i", button->allocation.x);
- g_debug("button y allocation = %i", button->allocation.y);
-
- GtkStyle *style;
-
- CairoColorRGB bg_normal, fg_normal;
- CairoColorRGB color_inner[2], color_middle[2], color_outer[2], color_button[3], color_inner_compressed[2];
-
- style = gtk_widget_get_style (button);
-
- 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;
-
- 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 (&bg_normal, INNER_START_SHADE, &color_inner[0]);
- _color_shade (&bg_normal, INNER_END_SHADE, &color_inner[1]);
- _color_shade (&bg_normal, MIDDLE_START_SHADE, &color_middle[0]);
- _color_shade (&bg_normal, MIDDLE_END_SHADE, &color_middle[1]);
- _color_shade (&bg_normal, OUTER_START_SHADE, &color_outer[0]);
- _color_shade (&bg_normal, OUTER_END_SHADE, &color_outer[1]);
- _color_shade (&fg_normal, BUTTON_START_SHADE, &color_button[0]);
- _color_shade (&fg_normal, BUTTON_END_SHADE, &color_button[1]);
- _color_shade (&bg_normal, BUTTON_SHADOW_SHADE, &color_button[2]);
- _color_shade (&bg_normal, INNER_COMPRESSED_START_SHADE, &color_inner_compressed[0]);
- _color_shade (&bg_normal, 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 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 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 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};
-
- // prev/next-background
- 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);
-
- if(priv->current_command == TRANSPORT_PREVIOUS){
- draw_gradient (cr,
- X,
- Y + 2,
- RECT_WIDTH/2,
- INNER_RADIUS,
- INNER_COMPRESSED_START,
- INNER_COMPRESSED_END);
- }
- else if(priv->current_command == TRANSPORT_NEXT){
- draw_gradient (cr,
- RECT_WIDTH / 2 + X,
- Y + 2,
- (RECT_WIDTH - 7)/2,
- INNER_RADIUS,
- INNER_COMPRESSED_START,
- INNER_COMPRESSED_END);
- }
-
- // play/pause-background
- draw_circle (cr,
- X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f,
- Y - ((CIRCLE_RADIUS - OUTER_RADIUS)),
- CIRCLE_RADIUS,
- OUTER_START,
- OUTER_END);
- draw_circle (cr,
- X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f + 0.5f,
- Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) + 0.5f,
- CIRCLE_RADIUS - 0.75f,
- MIDDLE_START,
- MIDDLE_END);
-
- if(priv->current_command == TRANSPORT_PLAY_PAUSE){
- draw_circle (cr,
- X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f + 1.5f,
- Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) + 1.5f,
- CIRCLE_RADIUS - 1.5f,
- INNER_COMPRESSED_START,
- INNER_COMPRESSED_END);
- }
- else{
- draw_circle (cr,
- X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f + 1.5f,
- Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) + 1.5f,
- CIRCLE_RADIUS - 1.5f,
- MIDDLE_START,
- MIDDLE_END);
- }
- // draw previous-button drop-shadow
- _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
- _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 == PLAY){
- _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 == PAUSE){
- _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);
- }
-}
-
-
-
-/**
-* play_button_new:
-* @returns: a new #PlayButton.
-**/
-GtkWidget*
-play_button_new()
-{
- GtkWidget* widget = g_object_new(PLAY_BUTTON_TYPE, NULL);
- gtk_widget_set_app_paintable (widget, TRUE);
- return widget;
-}
-
diff --git a/src/play-button.h b/src/play-button.h
deleted file mode 100644
index 86d76ca..0000000
--- a/src/play-button.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
-Copyright 2010 Canonical Ltd.
-
-Authors:
- Conor Curran <conor.curran@canonical.com>
-
-This program is free software: you can redistribute it and/or modify it
-under the terms of the GNU General Public License version 3, as published
-by the Free Software Foundation.
-
-This program is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranties of
-MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
-PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-#ifndef __PLAY_BUTTON_H__
-#define __PLAY_BUTTON_H__
-
-#include <gtk/gtk.h>
-
-G_BEGIN_DECLS
-
-#define PLAY_BUTTON_TYPE (play_button_get_type ())
-#define PLAY_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PLAY_BUTTON_TYPE, PlayButton))
-#define PLAY_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PLAY_BUTTON_TYPE, PlayButtonClass))
-#define IS_PLAY_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PLAY_BUTTON_TYPE))
-#define IS_PLAY_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PLAY_BUTTON_TYPE))
-#define PLAY_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PLAY_BUTTON_TYPE, PlayButtonClass))
-
-typedef struct _PlayButton PlayButton;
-typedef struct _PlayButtonClass PlayButtonClass;
-
-typedef enum {
- TRANSPORT_PREVIOUS,
- TRANSPORT_PLAY_PAUSE,
- TRANSPORT_NEXT,
- TRANSPORT_NADA
-}PlayButtonEvent;
-
-typedef enum {
- PLAY,
- PAUSE
-}PlayButtonState;
-
-struct _PlayButtonClass {
- GtkMenuItemClass parent_class;
-};
-
-struct _PlayButton {
- GtkMenuItem parent;
-};
-
-GType play_button_get_type (void);
-void play_button_set_style(GtkWidget* button, GtkStyle* style);
-PlayButtonEvent determine_button_event(GtkWidget* button, GdkEventButton* event);
-void play_button_react_to_button_press(GtkWidget* button, PlayButtonEvent command);
-void play_button_react_to_button_release(GtkWidget* button, PlayButtonEvent command);
-void play_button_toggle_play_pause(GtkWidget* button, PlayButtonState update);
-
-GtkWidget* play_button_new();
-
-G_END_DECLS
-
-#endif
-
diff --git a/src/title-widget.c b/src/title-widget.c
index 3baeb19..af5a2cb 100644
--- a/src/title-widget.c
+++ b/src/title-widget.c
@@ -32,7 +32,7 @@ typedef struct _TitleWidgetPrivate TitleWidgetPrivate;
struct _TitleWidgetPrivate
{
- DbusmenuMenuitem* twin_item;
+ DbusmenuMenuitem* twin_item;
};
#define TITLE_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TITLE_WIDGET_TYPE, TitleWidgetPrivate))
diff --git a/src/transport-widget-old.c b/src/transport-widget-old.c
new file mode 100644
index 0000000..04fb92e
--- /dev/null
+++ b/src/transport-widget-old.c
@@ -0,0 +1,231 @@
+/*
+Copyright 2010 Canonical Ltd.
+
+Authors:
+ Conor Curran <conor.curran@canonical.com>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <glib/gi18n.h>
+#include "transport-widget.h"
+#include "common-defs.h"
+#include <gtk/gtk.h>
+#include "play-button.h"
+
+typedef struct _TransportWidgetPrivate TransportWidgetPrivate;
+
+struct _TransportWidgetPrivate
+{
+ GtkWidget* hbox;
+ GtkWidget* play_button;
+ DbusmenuMenuitem* twin_item;
+};
+
+#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);
+
+static void transport_widget_set_twin_item(TransportWidget* self,
+ DbusmenuMenuitem* twin_item);
+static gboolean transport_widget_expose_event(GtkWidget* widget,
+ GdkEventExpose* event);
+
+/* 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 void transport_widget_property_update( DbusmenuMenuitem* item,
+ gchar * property,
+ GValue * value,
+ gpointer userdata );
+static void transport_widget_menu_hidden ( GtkWidget *menu,
+ TransportWidget *transport);
+static void transport_widget_notify ( TransportWidget *item,
+ GParamSpec *pspec,
+ gpointer user_data );
+
+
+G_DEFINE_TYPE (TransportWidget, transport_widget, GTK_TYPE_MENU_ITEM);
+
+static void
+transport_widget_class_init (TransportWidgetClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+ GtkMenuItemClass *menu_item_class = GTK_MENU_ITEM_CLASS(klass);
+
+ menu_item_class->hide_on_activate = FALSE;
+ widget_class->button_press_event = transport_widget_button_press_event;
+ widget_class->button_release_event = transport_widget_button_release_event;
+ widget_class->expose_event = transport_widget_expose_event;
+ g_type_class_add_private (klass, sizeof (TransportWidgetPrivate));
+
+ gobject_class->dispose = transport_widget_dispose;
+ gobject_class->finalize = transport_widget_finalize;
+}
+
+static void
+transport_widget_init (TransportWidget *self)
+{
+ g_debug("TransportWidget::transport_widget_init");
+
+ TransportWidgetPrivate * priv = TRANSPORT_WIDGET_GET_PRIVATE(self);
+ GtkWidget* hbox;
+
+ hbox = gtk_hbox_new(TRUE, 2);
+
+ GtkStyle* style = gtk_rc_get_style(GTK_WIDGET(self));
+
+ priv->hbox = hbox;
+ priv->play_button = play_button_new();
+ play_button_set_style(priv->play_button, style);
+
+ gtk_box_pack_start (GTK_BOX (priv->hbox), priv->play_button, FALSE, FALSE, 0);
+
+ gtk_container_add (GTK_CONTAINER (self), priv->hbox);
+
+ gtk_widget_show_all (priv->hbox);
+
+ g_signal_connect (G_OBJECT(self),
+ "notify",
+ G_CALLBACK (transport_widget_notify),
+ NULL);
+}
+
+static void
+transport_widget_dispose (GObject *object)
+{
+ 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);
+}
+
+static gboolean
+transport_widget_expose_event(GtkWidget* widget, GdkEventExpose* event)
+{
+ return TRUE;
+}
+
+
+static void
+transport_widget_notify (TransportWidget *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_debug("Transport Widget's menu hidden method called");
+ g_return_if_fail(IS_TRANSPORT_WIDGET(transport));
+ TransportWidgetPrivate * priv = TRANSPORT_WIDGET_GET_PRIVATE(TRANSPORT_WIDGET(transport));
+ play_button_react_to_button_release(priv->play_button, TRANSPORT_NADA);
+}
+
+
+/* keyevents */
+static gboolean
+transport_widget_button_press_event (GtkWidget *menuitem,
+ GdkEventButton *event)
+{
+ g_return_val_if_fail(IS_TRANSPORT_WIDGET(menuitem), FALSE);
+ TransportWidgetPrivate * priv = TRANSPORT_WIDGET_GET_PRIVATE(TRANSPORT_WIDGET(menuitem));
+
+ PlayButtonEvent result = determine_button_event(priv->play_button, event);
+
+ if(result != TRANSPORT_NADA){
+ play_button_react_to_button_press(priv->play_button, result);
+ }
+ return TRUE;
+}
+
+
+static gboolean
+transport_widget_button_release_event (GtkWidget *menuitem,
+ GdkEventButton *event)
+{
+ g_debug("TransportWidget::menu_release_event");
+ g_return_val_if_fail(IS_TRANSPORT_WIDGET(menuitem), FALSE);
+ TransportWidgetPrivate * priv = TRANSPORT_WIDGET_GET_PRIVATE(TRANSPORT_WIDGET(menuitem));
+
+ PlayButtonEvent result = determine_button_event(priv->play_button, event);
+
+ if(result != TRANSPORT_NADA){
+ GValue value = {0};
+ g_value_init(&value, G_TYPE_INT);
+ g_debug("TransportWidget::menu_press_event - going to send value %i", (int)result);
+ g_value_set_int(&value, (int)result);
+ dbusmenu_menuitem_handle_event (priv->twin_item, "Transport state change", &value, 0);
+ }
+ play_button_react_to_button_release(priv->play_button, result);
+
+ return TRUE;
+}
+
+/**
+* transport_widget_update_state()
+* Callback for updates from the other side of dbus
+**/
+static void
+transport_widget_property_update(DbusmenuMenuitem* item, gchar* property,
+ GValue* 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));
+
+ if(g_ascii_strcasecmp(DBUSMENU_TRANSPORT_MENUITEM_PLAY_STATE, property) == 0)
+ {
+ TransportWidgetPrivate *priv = TRANSPORT_WIDGET_GET_PRIVATE(bar);
+ int update_value = g_value_get_int(value);
+ g_debug("transport_widget_update_state - with value %i", update_value);
+ play_button_toggle_play_pause(priv->play_button, (PlayButtonState)update_value);
+ }
+}
+
+/**
+* transport_new:
+* @returns: a new #TransportWidget.
+**/
+GtkWidget*
+transport_widget_new(DbusmenuMenuitem *item)
+{
+ GtkWidget* widget = g_object_new(TRANSPORT_WIDGET_TYPE, NULL);
+ transport_widget_set_twin_item((TransportWidget*)widget, item);
+ return widget;
+}
+
diff --git a/src/transport-widget-old.h b/src/transport-widget-old.h
new file mode 100644
index 0000000..c69836a
--- /dev/null
+++ b/src/transport-widget-old.h
@@ -0,0 +1,51 @@
+/*
+Copyright 2010 Canonical Ltd.
+
+Authors:
+ Conor Curran <conor.curran@canonical.com>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __TRANSPORT_WIDGET_H__
+#define __TRANSPORT_WIDGET_H__
+
+#include <gtk/gtkmenuitem.h>
+#include <libdbusmenu-gtk/menuitem.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;
+};
+
+GType transport_widget_get_type (void);
+GtkWidget* transport_widget_new(DbusmenuMenuitem *twin_item);
+
+G_END_DECLS
+
+#endif
+
diff --git a/src/transport-widget.c b/src/transport-widget.c
index ed27a07..c0f5363 100644
--- a/src/transport-widget.c
+++ b/src/transport-widget.c
@@ -3,6 +3,7 @@ Copyright 2010 Canonical Ltd.
Authors:
Conor Curran <conor.curran@canonical.com>
+ Mirco Müller <mirco.mueller@canonical.com>
This program is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License version 3, as published
@@ -15,27 +16,78 @@ PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program. If not, see <http://www.gnu.org/licenses/>.
+
+Uses code from ctk
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
-#include <glib/gi18n.h>
+#include <math.h>
#include "transport-widget.h"
#include "common-defs.h"
-#include <gtk/gtk.h>
-#include "play-button.h"
+
+
+#define RECT_WIDTH 130.0f
+#define Y 7.0f
+#define X 37.0f
+#define INNER_RADIUS 12.5
+#define MIDDLE_RADIUS 13.5f
+#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 35.0f
+#define PREV_Y 13.0f
+#define NEXT_X 113.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 78.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 0.7
+#define MIDDLE_END_SHADE 1.4
+#define OUTER_START_SHADE 0.96
+#define OUTER_END_SHADE 0.96
+#define BUTTON_START_SHADE 1.1
+#define BUTTON_END_SHADE 0.9
+#define BUTTON_SHADOW_SHADE 0.8
+#define INNER_COMPRESSED_START_SHADE 0.95
+#define INNER_COMPRESSED_END_SHADE 1.05
+
typedef struct _TransportWidgetPrivate TransportWidgetPrivate;
struct _TransportWidgetPrivate
{
- GtkWidget* hbox;
- GtkWidget* play_button;
- DbusmenuMenuitem* twin_item;
+ TransportWidgetEvent current_command;
+ TransportWidgetState current_state;
+ GHashTable* command_coordinates;
+ DbusmenuMenuitem* twin_item;
};
+typedef struct
+{
+ double r;
+ double g;
+ double b;
+} CairoColorRGB;
+
+
#define TRANSPORT_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TRANSPORT_WIDGET_TYPE, TransportWidgetPrivate))
/* Gobject boiler plate */
@@ -43,73 +95,98 @@ 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);
-static void transport_widget_set_twin_item(TransportWidget* self,
- DbusmenuMenuitem* twin_item);
-static gboolean transport_widget_expose_event(GtkWidget* widget,
- GdkEventExpose* event);
+/* essentials */
+static void transport_widget_set_twin_item ( TransportWidget* self,
+ DbusmenuMenuitem* twin_item);
+static gboolean transport_widget_expose ( GtkWidget *button, GdkEventExpose *event);
+static void 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,
+static gboolean transport_widget_button_release_event (GtkWidget *menuitem,
GdkEventButton *event);
-static void transport_widget_property_update( DbusmenuMenuitem* item,
- gchar * property,
- GValue * value,
- gpointer userdata );
+static void transport_widget_property_update ( DbusmenuMenuitem* item,
+ gchar * property,
+ GValue * value,
+ gpointer userdata );
static void transport_widget_menu_hidden ( GtkWidget *menu,
TransportWidget *transport);
static void transport_widget_notify ( TransportWidget *item,
GParamSpec *pspec,
gpointer user_data );
+static TransportWidgetEvent transport_widget_determine_button_event ( TransportWidget* button,
+ GdkEventButton* event);
+static void transport_widget_react_to_button_release ( TransportWidget* button,
+ TransportWidgetEvent command);
+static void transport_widget_toggle_play_pause ( TransportWidget* button,
+ TransportWidgetState update);
-G_DEFINE_TYPE (TransportWidget, transport_widget, GTK_TYPE_MENU_ITEM);
+/// Init functions //////////////////////////////////////////////////////////
static void
transport_widget_class_init (TransportWidgetClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
- GtkMenuItemClass *menu_item_class = GTK_MENU_ITEM_CLASS(klass);
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass* widget_class = GTK_WIDGET_CLASS (klass);
- menu_item_class->hide_on_activate = FALSE;
- widget_class->button_press_event = transport_widget_button_press_event;
- widget_class->button_release_event = transport_widget_button_release_event;
- widget_class->expose_event = transport_widget_expose_event;
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->expose_event = transport_widget_expose;
+
gobject_class->dispose = transport_widget_dispose;
- gobject_class->finalize = transport_widget_finalize;
+ gobject_class->finalize = transport_widget_finalize;
}
static void
transport_widget_init (TransportWidget *self)
{
- g_debug("TransportWidget::transport_widget_init");
+ TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE(self);
+ priv->current_command = TRANSPORT_NADA;
+ priv->current_state = PAUSE;
+ 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_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);
- TransportWidgetPrivate * priv = TRANSPORT_WIDGET_GET_PRIVATE(self);
- GtkWidget* hbox;
+ g_hash_table_insert(priv->command_coordinates,
+ GINT_TO_POINTER(TRANSPORT_PLAY_PAUSE),
+ play_list);
- hbox = gtk_hbox_new(TRUE, 2);
+ 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);
- GtkStyle* style = gtk_rc_get_style(GTK_WIDGET(self));
-
- priv->hbox = hbox;
- priv->play_button = play_button_new();
- play_button_set_style(priv->play_button, style);
+ g_hash_table_insert(priv->command_coordinates,
+ GINT_TO_POINTER(TRANSPORT_NEXT),
+ next_list);
- gtk_box_pack_start (GTK_BOX (priv->hbox), priv->play_button, FALSE, FALSE, 0);
-
- gtk_container_add (GTK_CONTAINER (self), priv->hbox);
-
- gtk_widget_show_all (priv->hbox);
-
- g_signal_connect (G_OBJECT(self),
+ gtk_widget_set_size_request(GTK_WIDGET(self), 200, 50);
+ g_signal_connect (G_OBJECT(self),
"notify",
G_CALLBACK (transport_widget_notify),
- NULL);
+ NULL);
}
static void
@@ -124,19 +201,32 @@ transport_widget_finalize (GObject *object)
G_OBJECT_CLASS (transport_widget_parent_class)->finalize (object);
}
-static gboolean
-transport_widget_expose_event(GtkWidget* widget, GdkEventExpose* event)
+static gboolean
+transport_widget_expose (GtkWidget *button, GdkEventExpose *event)
{
- return TRUE;
+ cairo_t *cr;
+ cr = gdk_cairo_create (button->window);
+
+ g_debug("In the playbutton's expose method, x = %i, y=%i and width: %i and height: %i'");
+ 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;
}
-static void transport_widget_set_twin_item(TransportWidget* self,
- DbusmenuMenuitem* twin_item)
+static void
+transport_widget_toggle_play_pause(TransportWidget* button,
+ TransportWidgetState update)
{
- 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);
+ TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE(button);
+ priv->current_state = update;
+ g_debug("TransportWidget::toggle play state : %i", priv->current_state);
+ gtk_widget_queue_draw (GTK_WIDGET(button));
}
static void
@@ -144,16 +234,12 @@ transport_widget_notify (TransportWidget *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);
+ 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);
}
}
}
@@ -162,50 +248,1029 @@ static void
transport_widget_menu_hidden ( GtkWidget *menu,
TransportWidget *transport)
{
- g_debug("Transport Widget's menu hidden method called");
+ g_debug("Transport Widget's menu hidden method called");
g_return_if_fail(IS_TRANSPORT_WIDGET(transport));
- TransportWidgetPrivate * priv = TRANSPORT_WIDGET_GET_PRIVATE(TRANSPORT_WIDGET(transport));
- play_button_react_to_button_release(priv->play_button, TRANSPORT_NADA);
+ play_button_react_to_button_release(transport, TRANSPORT_NADA);
}
-
/* keyevents */
static gboolean
transport_widget_button_press_event (GtkWidget *menuitem,
GdkEventButton *event)
{
g_return_val_if_fail(IS_TRANSPORT_WIDGET(menuitem), FALSE);
- TransportWidgetPrivate * priv = TRANSPORT_WIDGET_GET_PRIVATE(TRANSPORT_WIDGET(menuitem));
-
- PlayButtonEvent result = determine_button_event(priv->play_button, event);
+ TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE(button);
+ TransportButtonEvent result = transport_widget_determine_button_event ( TRANSPORT_WIDGET(menuitem),
+ event);
if(result != TRANSPORT_NADA){
- play_button_react_to_button_press(priv->play_button, result);
- }
+ priv->current_command = result;
+ cairo_t *cr;
+ cr = gdk_cairo_create (menuitem->window);
+ draw (button, cr);
+ cairo_destroy (cr);
+ }
return TRUE;
}
-
static gboolean
transport_widget_button_release_event (GtkWidget *menuitem,
- GdkEventButton *event)
+ GdkEventButton *event)
{
- g_debug("TransportWidget::menu_release_event");
- g_return_val_if_fail(IS_TRANSPORT_WIDGET(menuitem), FALSE);
- TransportWidgetPrivate * priv = TRANSPORT_WIDGET_GET_PRIVATE(TRANSPORT_WIDGET(menuitem));
+ g_debug("TransportWidget::menu_release_event");
+ g_return_val_if_fail(IS_TRANSPORT_WIDGET(menuitem), FALSE);
+ TransportWidget* transport = TRANSPORT_WIDGET(menuitem);
+ TransportWidgetPrivate * priv = TRANSPORT_WIDGET_GET_PRIVATE ( transport );
+
+ TransportButtonEvent result = transport_widget_determine_button_event ( transport,
+ event );
+ if(result != TRANSPORT_NADA){
+ GValue value = {0};
+ g_value_init(&value, G_TYPE_INT);
+ g_debug("TransportWidget::menu_press_event - going to send value %i", (int)result);
+ g_value_set_int(&value, (int)result);
+ dbusmenu_menuitem_handle_event ( priv->twin_item,
+ "Transport state change",
+ &value,
+ 0 );
+ }
+
+ transport_widget_react_to_button_release ( transport,
+ result );
+ return TRUE;
+}
+
+static TransportWidgetEvent
+transport_widget_determine_button_event(GtkWidget* button,
+ GdkEventButton* event)
+{
+ g_debug("event x coordinate = %f", event->x);
+ g_debug("event y coordinate = %f", event->y);
+ TransportWidgetEvent button_event = TRANSPORT_NADA;
+ // For now very simple rectangular collision detection
+ if(event->x > 67 && event->x < 112
+ && event->y > 12 && event->y < 40){
+ button_event = TRANSPORT_PREVIOUS;
+ }
+ else if(event->x > 111 && event->x < 153
+ && event->y > 5 && event->y < 47){
+ button_event = TRANSPORT_PLAY_PAUSE;
+ }
+ else if(event->x > 152 && event->x < 197
+ && event->y > 12 && event->y < 40){
+ button_event = TRANSPORT_NEXT;
+ }
+ return button_event;
+}
+
+
+static void
+transport_widget_react_to_button_release(GtkWidget* button,
+ TransportWidgetEvent command)
+{
+ g_return_if_fail(IS_TRANSPORT_WIDGET(button));
+ TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE(button);
+ if(priv->current_command == TRANSPORT_NADA){
+ g_debug("returning from the playbutton release because my previous command was nada");
+ return;
+ }
+ else if(priv->current_command != TRANSPORT_NADA &&
+ command != TRANSPORT_NADA){
+ priv->current_command = command;
+ }
+ cairo_t *cr;
+ cr = gdk_cairo_create (button->window);
+ priv->current_command = TRANSPORT_NADA;
+
+ draw (button, cr);
+ cairo_destroy (cr);
+}
+
+/// 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
+ /*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);
+ cairo_close_path (cr);
- PlayButtonEvent result = determine_button_event(priv->play_button, event);
+}
- if(result != TRANSPORT_NADA){
- GValue value = {0};
- g_value_init(&value, G_TYPE_INT);
- g_debug("TransportWidget::menu_press_event - going to send value %i", (int)result);
- g_value_set_int(&value, (int)result);
- dbusmenu_menuitem_handle_event (priv->twin_item, "Transport state change", &value, 0);
+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
+_color_rgb_to_hls (gdouble *r,
+ gdouble *g,
+ gdouble *b)
+{
+ gdouble min;
+ gdouble max;
+ gdouble red;
+ gdouble green;
+ gdouble blue;
+ gdouble h, l, 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;
}
- play_button_react_to_button_release(priv->play_button, result);
+ 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;
+ }
+}
+
+static 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 void
+draw (GtkWidget* button, cairo_t *cr)
+{
+ g_return_if_fail(IS_TRANSPORT_WIDGET(button));
+ TransportWidgetPrivate* priv = TRANSPORT_WIDGET_GET_PRIVATE(button);
+
+ cairo_surface_t* surf = NULL;
+ cairo_t* cr_surf = NULL;
+
+ cairo_translate (cr, button->allocation.x, button->allocation.y);
- return TRUE;
+ g_debug("button x allocation = %i", button->allocation.x);
+ g_debug("button y allocation = %i", button->allocation.y);
+
+ GtkStyle *style;
+
+ CairoColorRGB bg_normal, fg_normal;
+ CairoColorRGB color_inner[2], color_middle[2], color_outer[2], color_button[3], color_inner_compressed[2];
+
+ style = gtk_widget_get_style (button);
+
+ 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;
+
+ 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 (&bg_normal, INNER_START_SHADE, &color_inner[0]);
+ _color_shade (&bg_normal, INNER_END_SHADE, &color_inner[1]);
+ _color_shade (&bg_normal, MIDDLE_START_SHADE, &color_middle[0]);
+ _color_shade (&bg_normal, MIDDLE_END_SHADE, &color_middle[1]);
+ _color_shade (&bg_normal, OUTER_START_SHADE, &color_outer[0]);
+ _color_shade (&bg_normal, OUTER_END_SHADE, &color_outer[1]);
+ _color_shade (&fg_normal, BUTTON_START_SHADE, &color_button[0]);
+ _color_shade (&fg_normal, BUTTON_END_SHADE, &color_button[1]);
+ _color_shade (&bg_normal, BUTTON_SHADOW_SHADE, &color_button[2]);
+ _color_shade (&bg_normal, INNER_COMPRESSED_START_SHADE, &color_inner_compressed[0]);
+ _color_shade (&bg_normal, 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 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 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 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};
+
+ // prev/next-background
+ 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);
+
+ if(priv->current_command == TRANSPORT_PREVIOUS){
+ draw_gradient (cr,
+ X,
+ Y + 2,
+ RECT_WIDTH/2,
+ INNER_RADIUS,
+ INNER_COMPRESSED_START,
+ INNER_COMPRESSED_END);
+ }
+ else if(priv->current_command == TRANSPORT_NEXT){
+ draw_gradient (cr,
+ RECT_WIDTH / 2 + X,
+ Y + 2,
+ (RECT_WIDTH - 7)/2,
+ INNER_RADIUS,
+ INNER_COMPRESSED_START,
+ INNER_COMPRESSED_END);
+ }
+
+ // play/pause-background
+ draw_circle (cr,
+ X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f,
+ Y - ((CIRCLE_RADIUS - OUTER_RADIUS)),
+ CIRCLE_RADIUS,
+ OUTER_START,
+ OUTER_END);
+ draw_circle (cr,
+ X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f + 0.5f,
+ Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) + 0.5f,
+ CIRCLE_RADIUS - 0.75f,
+ MIDDLE_START,
+ MIDDLE_END);
+
+ if(priv->current_command == TRANSPORT_PLAY_PAUSE){
+ draw_circle (cr,
+ X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f + 1.5f,
+ Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) + 1.5f,
+ CIRCLE_RADIUS - 1.5f,
+ INNER_COMPRESSED_START,
+ INNER_COMPRESSED_END);
+ }
+ else{
+ draw_circle (cr,
+ X + RECT_WIDTH / 2.0f - 2.0f * OUTER_RADIUS - 5.5f + 1.5f,
+ Y - ((CIRCLE_RADIUS - OUTER_RADIUS)) + 1.5f,
+ CIRCLE_RADIUS - 1.5f,
+ MIDDLE_START,
+ MIDDLE_END);
+ }
+ // draw previous-button drop-shadow
+ _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
+ _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 == PLAY){
+ _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 == PAUSE){
+ _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);
+ }
+}
+
+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);
}
/**
@@ -216,7 +1281,7 @@ static void
transport_widget_property_update(DbusmenuMenuitem* item, gchar* property,
GValue* value, gpointer userdata)
{
- g_debug("transport_widget_update_state - with property %s", property);
+ g_debug("transport_widget_update_state - with property %s", property);
TransportWidget* bar = (TransportWidget*)userdata;
g_return_if_fail(IS_TRANSPORT_WIDGET(bar));
@@ -225,19 +1290,22 @@ transport_widget_property_update(DbusmenuMenuitem* item, gchar* property,
TransportWidgetPrivate *priv = TRANSPORT_WIDGET_GET_PRIVATE(bar);
int update_value = g_value_get_int(value);
g_debug("transport_widget_update_state - with value %i", update_value);
- play_button_toggle_play_pause(priv->play_button, (PlayButtonState)update_value);
+ transport_widget_toggle_play_pause(bar,
+ (TransportWidgetState)update_value);
}
}
+
+
/**
-* transport_new:
+* transport_widget_new:
* @returns: a new #TransportWidget.
**/
GtkWidget*
-transport_widget_new(DbusmenuMenuitem *item)
-{
- GtkWidget* widget = g_object_new(TRANSPORT_WIDGET_TYPE, NULL);
- transport_widget_set_twin_item((TransportWidget*)widget, item);
+transport_widget_new()
+{
+ GtkWidget* widget = g_object_new(TRANSPORT_WIDGET_TYPE, NULL);
+ gtk_widget_set_app_paintable (widget, TRUE);
return widget;
}
diff --git a/src/transport-widget.h b/src/transport-widget.h
index c69836a..f72dcfd 100644
--- a/src/transport-widget.h
+++ b/src/transport-widget.h
@@ -19,6 +19,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef __TRANSPORT_WIDGET_H__
#define __TRANSPORT_WIDGET_H__
+#include <gtk/gtk.h>
#include <gtk/gtkmenuitem.h>
#include <libdbusmenu-gtk/menuitem.h>
@@ -34,6 +35,18 @@ G_BEGIN_DECLS
typedef struct _TransportWidget TransportWidget;
typedef struct _TransportWidgetClass TransportWidgetClass;
+typedef enum {
+ TRANSPORT_PREVIOUS,
+ TRANSPORT_PLAY_PAUSE,
+ TRANSPORT_NEXT,
+ TRANSPORT_NADA
+}TransportWidgetEvent;
+
+typedef enum {
+ PLAY,
+ PAUSE
+}TransportWidgetState;
+
struct _TransportWidgetClass {
GtkMenuItemClass parent_class;
};
@@ -43,7 +56,7 @@ struct _TransportWidget {
};
GType transport_widget_get_type (void);
-GtkWidget* transport_widget_new(DbusmenuMenuitem *twin_item);
+GtkWidget* transport_widget_new();
G_END_DECLS