diff options
Diffstat (limited to 'mate-volume-control/src/gvc-level-bar.c')
-rw-r--r-- | mate-volume-control/src/gvc-level-bar.c | 542 |
1 files changed, 309 insertions, 233 deletions
diff --git a/mate-volume-control/src/gvc-level-bar.c b/mate-volume-control/src/gvc-level-bar.c index fbc0538..0f3dc1b 100644 --- a/mate-volume-control/src/gvc-level-bar.c +++ b/mate-volume-control/src/gvc-level-bar.c @@ -1,6 +1,7 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2008 William Jon McCann <[email protected]> + * Copyright (C) 2014 Michal Ratajsky <[email protected]> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,54 +19,50 @@ * */ -#include "config.h" +// XXX on gtk3 the last two squares don't get filled -#include <stdlib.h> -#include <stdio.h> -#include <unistd.h> #include <math.h> - #include <glib.h> #include <glib/gi18n.h> +#include <glib-object.h> #include <gtk/gtk.h> #include "gvc-level-bar.h" - -#define NUM_BOXES 15 +#include "mvc-helpers.h" #define GVC_LEVEL_BAR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GVC_TYPE_LEVEL_BAR, GvcLevelBarPrivate)) +#define NUM_BOXES 15 #define MIN_HORIZONTAL_BAR_WIDTH 150 #define HORIZONTAL_BAR_HEIGHT 6 #define VERTICAL_BAR_WIDTH 6 #define MIN_VERTICAL_BAR_HEIGHT 400 typedef struct { - int peak_num; - int max_peak_num; - - GdkRectangle area; - int delta; - int box_width; - int box_height; - int box_radius; - double bg_r; - double bg_g; - double bg_b; - double bdr_r; - double bdr_g; - double bdr_b; - double fl_r; - double fl_g; - double fl_b; + int peak_num; + int max_peak_num; + GdkRectangle area; + int delta; + int box_width; + int box_height; + int box_radius; +#if GTK_CHECK_VERSION (3, 0, 0) + GdkRGBA color_bg; + GdkRGBA color_fg; + GdkRGBA color_dark; +#else + GdkColor color_bg; + GdkColor color_fg; + GdkColor color_dark; +#endif } LevelBarLayout; -struct GvcLevelBarPrivate +struct _GvcLevelBarPrivate { GtkOrientation orientation; GtkAdjustment *peak_adjustment; GtkAdjustment *rms_adjustment; - int scale; + GvcLevelScale scale; gdouble peak_fraction; gdouble rms_fraction; gdouble max_peak; @@ -80,47 +77,51 @@ enum PROP_RMS_ADJUSTMENT, PROP_SCALE, PROP_ORIENTATION, + N_PROPERTIES }; -static void gvc_level_bar_class_init (GvcLevelBarClass *klass); -static void gvc_level_bar_init (GvcLevelBar *level_bar); -static void gvc_level_bar_finalize (GObject *object); +static GParamSpec *properties[N_PROPERTIES] = { NULL, }; -#if GTK_CHECK_VERSION (3, 0, 0) -G_DEFINE_TYPE (GvcLevelBar, gvc_level_bar, GTK_TYPE_BOX) -#else -G_DEFINE_TYPE (GvcLevelBar, gvc_level_bar, GTK_TYPE_HBOX) -#endif +static void gvc_level_bar_class_init (GvcLevelBarClass *klass); +static void gvc_level_bar_init (GvcLevelBar *bar); +static void gvc_level_bar_finalize (GObject *object); -#define check_rectangle(rectangle1, rectangle2) \ - { \ - if (rectangle1.x != rectangle2.x) return TRUE; \ - if (rectangle1.y != rectangle2.y) return TRUE; \ - if (rectangle1.width != rectangle2.width) return TRUE; \ - if (rectangle1.height != rectangle2.height) return TRUE; \ - } +G_DEFINE_TYPE (GvcLevelBar, gvc_level_bar, GTK_TYPE_WIDGET) static gboolean -layout_changed (LevelBarLayout *layout1, - LevelBarLayout *layout2) +layout_changed (LevelBarLayout *layout1, LevelBarLayout *layout2) { - check_rectangle (layout1->area, layout2->area); - if (layout1->delta != layout2->delta) return TRUE; - if (layout1->peak_num != layout2->peak_num) return TRUE; - if (layout1->max_peak_num != layout2->max_peak_num) return TRUE; - if (layout1->bg_r != layout2->bg_r - || layout1->bg_g != layout2->bg_g - || layout1->bg_b != layout2->bg_b) + if (layout1->area.x != layout2->area.x) + return TRUE; + if (layout1->area.y != layout2->area.y) return TRUE; - if (layout1->bdr_r != layout2->bdr_r - || layout1->bdr_g != layout2->bdr_g - || layout1->bdr_b != layout2->bdr_b) + if (layout1->area.width != layout2->area.width) return TRUE; - if (layout1->fl_r != layout2->fl_r - || layout1->fl_g != layout2->fl_g - || layout1->fl_b != layout2->fl_b) + if (layout1->area.height != layout2->area.height) return TRUE; + if (layout1->delta != layout2->delta) + return TRUE; + if (layout1->peak_num != layout2->peak_num) + return TRUE; + if (layout1->max_peak_num != layout2->max_peak_num) + return TRUE; + +#if GTK_CHECK_VERSION (3, 0, 0) + if (!gdk_rgba_equal (&layout1->color_fg, &layout2->color_fg)) + return TRUE; + if (!gdk_rgba_equal (&layout1->color_bg, &layout2->color_bg)) + return TRUE; + if (!gdk_rgba_equal (&layout1->color_dark, &layout2->color_dark)) + return TRUE; +#else + if (!gdk_color_equal (&layout1->color_fg, &layout2->color_fg)) + return TRUE; + if (!gdk_color_equal (&layout1->color_bg, &layout2->color_bg)) + return TRUE; + if (!gdk_color_equal (&layout1->color_dark, &layout2->color_dark)) + return TRUE; +#endif return FALSE; } @@ -129,14 +130,13 @@ fraction_from_adjustment (GvcLevelBar *bar, GtkAdjustment *adjustment) { gdouble level; - gdouble fraction; + gdouble fraction = 0.0; gdouble min; gdouble max; level = gtk_adjustment_get_value (adjustment); - - min = gtk_adjustment_get_lower (adjustment); - max = gtk_adjustment_get_upper (adjustment); + min = gtk_adjustment_get_lower (adjustment); + max = gtk_adjustment_get_upper (adjustment); switch (bar->priv->scale) { case GVC_LEVEL_SCALE_LINEAR: @@ -145,8 +145,6 @@ fraction_from_adjustment (GvcLevelBar *bar, case GVC_LEVEL_SCALE_LOG: fraction = log10 ((level - min + 1) / (max - min + 1)); break; - default: - g_assert_not_reached (); } return fraction; @@ -155,12 +153,12 @@ fraction_from_adjustment (GvcLevelBar *bar, static gboolean reset_max_peak (GvcLevelBar *bar) { - gdouble min; + bar->priv->max_peak = gtk_adjustment_get_lower (bar->priv->peak_adjustment); - min = gtk_adjustment_get_lower (bar->priv->peak_adjustment); - bar->priv->max_peak = min; bar->priv->layout.max_peak_num = 0; + gtk_widget_queue_draw (GTK_WIDGET (bar)); + bar->priv->max_peak_id = 0; return FALSE; } @@ -168,30 +166,43 @@ reset_max_peak (GvcLevelBar *bar) static void bar_calc_layout (GvcLevelBar *bar) { - GdkColor color; - int peak_level; - int max_peak_level; + int peak_level; + int max_peak_level; GtkAllocation allocation; + +#if GTK_CHECK_VERSION (3, 0, 0) + GtkStyleContext *context; + + context = gtk_widget_get_style_context (GTK_WIDGET (bar)); + + gtk_style_context_get_background_color (context, + GTK_STATE_FLAG_NORMAL, + &bar->priv->layout.color_bg); + gtk_style_context_get_background_color (context, + GTK_STATE_FLAG_SELECTED, + &bar->priv->layout.color_fg); + gtk_style_context_get_color (context, + GTK_STATE_FLAG_NORMAL, + &bar->priv->layout.color_dark); + + mvc_color_shade (&bar->priv->layout.color_dark, + &bar->priv->layout.color_dark, + 0.7); +#else GtkStyle *style; + style = gtk_widget_get_style (GTK_WIDGET (bar)); + + bar->priv->layout.color_bg = style->bg[GTK_STATE_NORMAL]; + bar->priv->layout.color_fg = style->bg[GTK_STATE_SELECTED]; + bar->priv->layout.color_dark = style->dark[GTK_STATE_NORMAL]; +#endif + gtk_widget_get_allocation (GTK_WIDGET (bar), &allocation); + bar->priv->layout.area.width = allocation.width - 2; bar->priv->layout.area.height = allocation.height - 2; - style = gtk_widget_get_style (GTK_WIDGET (bar)); - color = style->bg [GTK_STATE_NORMAL]; - bar->priv->layout.bg_r = (float)color.red / 65535.0; - bar->priv->layout.bg_g = (float)color.green / 65535.0; - bar->priv->layout.bg_b = (float)color.blue / 65535.0; - color = style->dark [GTK_STATE_NORMAL]; - bar->priv->layout.bdr_r = (float)color.red / 65535.0; - bar->priv->layout.bdr_g = (float)color.green / 65535.0; - bar->priv->layout.bdr_b = (float)color.blue / 65535.0; - color = style->bg [GTK_STATE_SELECTED]; - bar->priv->layout.fl_r = (float)color.red / 65535.0; - bar->priv->layout.fl_g = (float)color.green / 65535.0; - bar->priv->layout.fl_b = (float)color.blue / 65535.0; - if (bar->priv->orientation == GTK_ORIENTATION_VERTICAL) { peak_level = bar->priv->peak_fraction * bar->priv->layout.area.height; max_peak_level = bar->priv->max_peak * bar->priv->layout.area.height; @@ -200,7 +211,7 @@ bar_calc_layout (GvcLevelBar *bar) bar->priv->layout.area.x = 0; bar->priv->layout.area.y = 0; bar->priv->layout.box_height = bar->priv->layout.delta / 2; - bar->priv->layout.box_width = bar->priv->layout.area.width; + bar->priv->layout.box_width = bar->priv->layout.area.width; bar->priv->layout.box_radius = bar->priv->layout.box_width / 2; } else { peak_level = bar->priv->peak_fraction * bar->priv->layout.area.width; @@ -209,7 +220,7 @@ bar_calc_layout (GvcLevelBar *bar) bar->priv->layout.delta = bar->priv->layout.area.width / NUM_BOXES; bar->priv->layout.area.x = 0; bar->priv->layout.area.y = 0; - bar->priv->layout.box_width = bar->priv->layout.delta / 2; + bar->priv->layout.box_width = bar->priv->layout.delta / 2; bar->priv->layout.box_height = bar->priv->layout.area.height; bar->priv->layout.box_radius = bar->priv->layout.box_height / 2; } @@ -221,42 +232,41 @@ bar_calc_layout (GvcLevelBar *bar) static void update_peak_value (GvcLevelBar *bar) { - gdouble val; + gdouble value; LevelBarLayout layout; - layout = bar->priv->layout; + value = fraction_from_adjustment (bar, bar->priv->peak_adjustment); - val = fraction_from_adjustment (bar, bar->priv->peak_adjustment); - bar->priv->peak_fraction = val; + bar->priv->peak_fraction = value; - if (val > bar->priv->max_peak) { - if (bar->priv->max_peak_id > 0) { + if (value > bar->priv->max_peak) { + if (bar->priv->max_peak_id > 0) g_source_remove (bar->priv->max_peak_id); - } - bar->priv->max_peak_id = g_timeout_add_seconds (1, (GSourceFunc)reset_max_peak, bar); - bar->priv->max_peak = val; + + bar->priv->max_peak_id = + g_timeout_add_seconds (1, (GSourceFunc) reset_max_peak, bar); + bar->priv->max_peak = value; } + layout = bar->priv->layout; + bar_calc_layout (bar); - if (layout_changed (&bar->priv->layout, &layout)) { + if (layout_changed (&bar->priv->layout, &layout)) gtk_widget_queue_draw (GTK_WIDGET (bar)); - } } static void update_rms_value (GvcLevelBar *bar) { - gdouble val; - - val = fraction_from_adjustment (bar, bar->priv->rms_adjustment); - bar->priv->rms_fraction = val; + bar->priv->rms_fraction = fraction_from_adjustment (bar, bar->priv->rms_adjustment); } GtkOrientation gvc_level_bar_get_orientation (GvcLevelBar *bar) { g_return_val_if_fail (GVC_IS_LEVEL_BAR (bar), 0); + return bar->priv->orientation; } @@ -267,9 +277,17 @@ gvc_level_bar_set_orientation (GvcLevelBar *bar, g_return_if_fail (GVC_IS_LEVEL_BAR (bar)); if (orientation != bar->priv->orientation) { + if (G_UNLIKELY (orientation != GTK_ORIENTATION_VERTICAL && + orientation != GTK_ORIENTATION_HORIZONTAL)) { + g_warn_if_reached (); + return; + } + bar->priv->orientation = orientation; + gtk_widget_queue_draw (GTK_WIDGET (bar)); - g_object_notify (G_OBJECT (bar), "orientation"); + + g_object_notify_by_pspec (G_OBJECT (bar), properties[PROP_ORIENTATION]); } } @@ -295,7 +313,7 @@ gvc_level_bar_set_peak_adjustment (GvcLevelBar *bar, g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment)); if (bar->priv->peak_adjustment != NULL) { - g_signal_handlers_disconnect_by_func (bar->priv->peak_adjustment, + g_signal_handlers_disconnect_by_func (G_OBJECT (bar->priv->peak_adjustment), G_CALLBACK (on_peak_adjustment_value_changed), bar); g_object_unref (bar->priv->peak_adjustment); @@ -303,14 +321,14 @@ gvc_level_bar_set_peak_adjustment (GvcLevelBar *bar, bar->priv->peak_adjustment = g_object_ref_sink (adjustment); - g_signal_connect (bar->priv->peak_adjustment, + g_signal_connect (G_OBJECT (bar->priv->peak_adjustment), "value-changed", G_CALLBACK (on_peak_adjustment_value_changed), bar); update_peak_value (bar); - g_object_notify (G_OBJECT (bar), "peak-adjustment"); + g_object_notify_by_pspec (G_OBJECT (bar), properties[PROP_PEAK_ADJUSTMENT]); } void @@ -321,7 +339,7 @@ gvc_level_bar_set_rms_adjustment (GvcLevelBar *bar, g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment)); if (bar->priv->rms_adjustment != NULL) { - g_signal_handlers_disconnect_by_func (bar->priv->peak_adjustment, + g_signal_handlers_disconnect_by_func (G_OBJECT (bar->priv->rms_adjustment), G_CALLBACK (on_rms_adjustment_value_changed), bar); g_object_unref (bar->priv->rms_adjustment); @@ -329,15 +347,14 @@ gvc_level_bar_set_rms_adjustment (GvcLevelBar *bar, bar->priv->rms_adjustment = g_object_ref_sink (adjustment); - - g_signal_connect (bar->priv->peak_adjustment, + g_signal_connect (G_OBJECT (bar->priv->rms_adjustment), "value-changed", - G_CALLBACK (on_peak_adjustment_value_changed), + G_CALLBACK (on_rms_adjustment_value_changed), bar); update_rms_value (bar); - g_object_notify (G_OBJECT (bar), "rms-adjustment"); + g_object_notify_by_pspec (G_OBJECT (bar), properties[PROP_RMS_ADJUSTMENT]); } GtkAdjustment * @@ -357,26 +374,30 @@ gvc_level_bar_get_rms_adjustment (GvcLevelBar *bar) } void -gvc_level_bar_set_scale (GvcLevelBar *bar, - GvcLevelScale scale) +gvc_level_bar_set_scale (GvcLevelBar *bar, GvcLevelScale scale) { g_return_if_fail (GVC_IS_LEVEL_BAR (bar)); if (scale != bar->priv->scale) { + if (G_UNLIKELY (scale != GVC_LEVEL_SCALE_LINEAR && + scale != GVC_LEVEL_SCALE_LOG)) { + g_warn_if_reached (); + return; + } bar->priv->scale = scale; update_peak_value (bar); update_rms_value (bar); - g_object_notify (G_OBJECT (bar), "scale"); + g_object_notify_by_pspec (G_OBJECT (bar), properties[PROP_SCALE]); } } static void gvc_level_bar_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) + guint prop_id, + const GValue *value, + GParamSpec *pspec) { GvcLevelBar *self = GVC_LEVEL_BAR (object); @@ -401,9 +422,9 @@ gvc_level_bar_set_property (GObject *object, static void gvc_level_bar_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) + guint prop_id, + GValue *value, + GParamSpec *pspec) { GvcLevelBar *self = GVC_LEVEL_BAR (object); @@ -426,14 +447,6 @@ gvc_level_bar_get_property (GObject *object, } } -static GObject * -gvc_level_bar_constructor (GType type, - guint n_construct_properties, - GObjectConstructParam *construct_params) -{ - return G_OBJECT_CLASS (gvc_level_bar_parent_class)->constructor (type, n_construct_properties, construct_params); -} - static void gvc_level_bar_size_request (GtkWidget *widget, GtkRequisition *requisition) @@ -447,19 +460,17 @@ gvc_level_bar_size_request (GtkWidget *widget, switch (bar->priv->orientation) { case GTK_ORIENTATION_VERTICAL: - requisition->width = VERTICAL_BAR_WIDTH; + requisition->width = VERTICAL_BAR_WIDTH; requisition->height = MIN_VERTICAL_BAR_HEIGHT; break; case GTK_ORIENTATION_HORIZONTAL: - requisition->width = MIN_HORIZONTAL_BAR_WIDTH; + requisition->width = MIN_HORIZONTAL_BAR_WIDTH; requisition->height = HORIZONTAL_BAR_HEIGHT; break; - default: - g_assert_not_reached (); - break; } } +#if GTK_CHECK_VERSION (3, 0, 0) static void gvc_level_bar_get_preferred_width (GtkWidget *widget, gint *minimum, @@ -469,7 +480,10 @@ gvc_level_bar_get_preferred_width (GtkWidget *widget, gvc_level_bar_size_request (widget, &requisition); - *minimum = *natural = requisition.width; + if (minimum != NULL) + *minimum = requisition.width; + if (natural != NULL) + *natural = requisition.width; } static void @@ -481,18 +495,18 @@ gvc_level_bar_get_preferred_height (GtkWidget *widget, gvc_level_bar_size_request (widget, &requisition); - *minimum = *natural = requisition.height; + if (minimum != NULL) + *minimum = requisition.height; + if (natural != NULL) + *natural = requisition.height; } +#endif static void -gvc_level_bar_size_allocate (GtkWidget *widget, - GtkAllocation *allocation) +gvc_level_bar_size_allocate (GtkWidget *widget, GtkAllocation *allocation) { GvcLevelBar *bar; - g_return_if_fail (GVC_IS_LEVEL_BAR (widget)); - g_return_if_fail (allocation != NULL); - bar = GVC_LEVEL_BAR (widget); /* FIXME: add height property, labels, etc */ @@ -503,9 +517,9 @@ gvc_level_bar_size_allocate (GtkWidget *widget, if (bar->priv->orientation == GTK_ORIENTATION_VERTICAL) { allocation->height = MIN (allocation->height, MIN_VERTICAL_BAR_HEIGHT); - allocation->width = MAX (allocation->width, VERTICAL_BAR_WIDTH); + allocation->width = MAX (allocation->width, VERTICAL_BAR_WIDTH); } else { - allocation->width = MIN (allocation->width, MIN_HORIZONTAL_BAR_WIDTH); + allocation->width = MIN (allocation->width, MIN_HORIZONTAL_BAR_WIDTH); allocation->height = MAX (allocation->height, HORIZONTAL_BAR_HEIGHT); } @@ -526,9 +540,8 @@ curved_rectangle (cairo_t *cr, x1 = x0 + width; y1 = y0 + height; - if (!width || !height) { + if (!width || !height) return; - } if (width / 2 < radius) { if (height / 2 < radius) { @@ -541,7 +554,7 @@ curved_rectangle (cairo_t *cr, cairo_move_to (cr, x0, y0 + radius); cairo_curve_to (cr, x0, y0, x0, y0, (x0 + x1) / 2, y0); cairo_curve_to (cr, x1, y0, x1, y0, x1, y0 + radius); - cairo_line_to (cr, x1, y1 - radius); + cairo_line_to (cr, x1, y1 - radius); cairo_curve_to (cr, x1, y1, x1, y1, (x1 + x0) / 2, y1); cairo_curve_to (cr, x0, y1, x0, y1, x0, y1 - radius); } @@ -549,19 +562,19 @@ curved_rectangle (cairo_t *cr, if (height / 2 < radius) { cairo_move_to (cr, x0, (y0 + y1) / 2); cairo_curve_to (cr, x0, y0, x0 , y0, x0 + radius, y0); - cairo_line_to (cr, x1 - radius, y0); + cairo_line_to (cr, x1 - radius, y0); cairo_curve_to (cr, x1, y0, x1, y0, x1, (y0 + y1) / 2); cairo_curve_to (cr, x1, y1, x1, y1, x1 - radius, y1); - cairo_line_to (cr, x0 + radius, y1); + cairo_line_to (cr, x0 + radius, y1); cairo_curve_to (cr, x0, y1, x0, y1, x0, (y0 + y1) / 2); } else { cairo_move_to (cr, x0, y0 + radius); cairo_curve_to (cr, x0 , y0, x0 , y0, x0 + radius, y0); - cairo_line_to (cr, x1 - radius, y0); + cairo_line_to (cr, x1 - radius, y0); cairo_curve_to (cr, x1, y0, x1, y0, x1, y0 + radius); - cairo_line_to (cr, x1, y1 - radius); + cairo_line_to (cr, x1, y1 - radius); cairo_curve_to (cr, x1, y1, x1, y1, x1 - radius, y1); - cairo_line_to (cr, x0 + radius, y1); + cairo_line_to (cr, x0 + radius, y1); cairo_curve_to (cr, x0, y1, x0, y1, x0, y1 - radius); } } @@ -570,40 +583,13 @@ curved_rectangle (cairo_t *cr, } static int -#if GTK_CHECK_VERSION (3, 0, 0) -gvc_level_bar_draw (GtkWidget *widget, - cairo_t *cr) -#else -gvc_level_bar_expose (GtkWidget *widget, - GdkEventExpose *event) -#endif +gvc_level_bar_draw (GtkWidget *widget, cairo_t *cr) { - GvcLevelBar *bar; -#if !GTK_CHECK_VERSION (3, 0, 0) - cairo_t *cr; - GtkAllocation allocation; -#endif - - g_return_val_if_fail (GVC_IS_LEVEL_BAR (widget), FALSE); -#if !GTK_CHECK_VERSION (3, 0, 0) - g_return_val_if_fail (event != NULL, FALSE); - - /* event queue compression */ - if (event->count > 0) { - return FALSE; - } -#endif + GvcLevelBar *bar; bar = GVC_LEVEL_BAR (widget); -#if !GTK_CHECK_VERSION (3, 0, 0) - cr = gdk_cairo_create (gtk_widget_get_window (widget)); - - gtk_widget_get_allocation (widget, &allocation); - cairo_translate (cr, - allocation.x, - allocation.y); -#endif + cairo_save (cr); if (bar->priv->orientation == GTK_ORIENTATION_VERTICAL) { int i; @@ -619,31 +605,68 @@ gvc_level_bar_expose (GtkWidget *widget, bar->priv->layout.box_radius); if ((bar->priv->layout.max_peak_num - 1) == i) { /* fill peak foreground */ - cairo_set_source_rgb (cr, bar->priv->layout.fl_r, bar->priv->layout.fl_g, bar->priv->layout.fl_b); +#if GTK_CHECK_VERSION (3, 0, 0) + gdk_cairo_set_source_rgba (cr, &bar->priv->layout.color_fg); +#else + gdk_cairo_set_source_color (cr, &bar->priv->layout.color_fg); +#endif cairo_fill_preserve (cr); } else if ((bar->priv->layout.peak_num - 1) >= i) { /* fill background */ - cairo_set_source_rgb (cr, bar->priv->layout.bg_r, bar->priv->layout.bg_g, bar->priv->layout.bg_b); +#if GTK_CHECK_VERSION (3, 0, 0) + gdk_cairo_set_source_rgba (cr, &bar->priv->layout.color_bg); +#else + gdk_cairo_set_source_color (cr, &bar->priv->layout.color_bg); +#endif cairo_fill_preserve (cr); + /* fill foreground */ - cairo_set_source_rgba (cr, bar->priv->layout.fl_r, bar->priv->layout.fl_g, bar->priv->layout.fl_b, 0.5); +#if GTK_CHECK_VERSION (3, 0, 0) + cairo_set_source_rgba (cr, + bar->priv->layout.color_fg.red, + bar->priv->layout.color_fg.green, + bar->priv->layout.color_fg.blue, + 0.5); +#else + cairo_set_source_rgba (cr, + bar->priv->layout.color_fg.red / 65535.0, + bar->priv->layout.color_fg.green / 65535.0, + bar->priv->layout.color_fg.blue / 65535.0, + 0.5); +#endif cairo_fill_preserve (cr); } else { /* fill background */ - cairo_set_source_rgb (cr, bar->priv->layout.bg_r, bar->priv->layout.bg_g, bar->priv->layout.bg_b); +#if GTK_CHECK_VERSION (3, 0, 0) + gdk_cairo_set_source_rgba (cr, &bar->priv->layout.color_bg); +#else + gdk_cairo_set_source_color (cr, &bar->priv->layout.color_bg); +#endif cairo_fill_preserve (cr); } /* stroke border */ - cairo_set_source_rgb (cr, bar->priv->layout.bdr_r, bar->priv->layout.bdr_g, bar->priv->layout.bdr_b); +#if GTK_CHECK_VERSION (3, 0, 0) + gdk_cairo_set_source_rgba (cr, &bar->priv->layout.color_dark); +#else + gdk_cairo_set_source_color (cr, &bar->priv->layout.color_dark); +#endif cairo_set_line_width (cr, 1); cairo_stroke (cr); } - } else { int i; int bx; + if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) { + GtkAllocation allocation; + + gtk_widget_get_allocation (widget, &allocation); + + cairo_scale (cr, -1, 1); + cairo_translate (cr, -allocation.width, 0); + } + for (i = 0; i < NUM_BOXES; i++) { bx = i * bar->priv->layout.delta; curved_rectangle (cr, @@ -655,33 +678,88 @@ gvc_level_bar_expose (GtkWidget *widget, if ((bar->priv->layout.max_peak_num - 1) == i) { /* fill peak foreground */ - cairo_set_source_rgb (cr, bar->priv->layout.fl_r, bar->priv->layout.fl_g, bar->priv->layout.fl_b); +#if GTK_CHECK_VERSION (3, 0, 0) + gdk_cairo_set_source_rgba (cr, &bar->priv->layout.color_fg); +#else + gdk_cairo_set_source_color (cr, &bar->priv->layout.color_fg); +#endif cairo_fill_preserve (cr); } else if ((bar->priv->layout.peak_num - 1) >= i) { /* fill background */ - cairo_set_source_rgb (cr, bar->priv->layout.bg_r, bar->priv->layout.bg_g, bar->priv->layout.bg_b); +#if GTK_CHECK_VERSION (3, 0, 0) + gdk_cairo_set_source_rgba (cr, &bar->priv->layout.color_bg); +#else + gdk_cairo_set_source_color (cr, &bar->priv->layout.color_bg); +#endif cairo_fill_preserve (cr); + /* fill foreground */ - cairo_set_source_rgba (cr, bar->priv->layout.fl_r, bar->priv->layout.fl_g, bar->priv->layout.fl_b, 0.5); +#if GTK_CHECK_VERSION (3, 0, 0) + cairo_set_source_rgba (cr, + bar->priv->layout.color_fg.red, + bar->priv->layout.color_fg.green, + bar->priv->layout.color_fg.blue, + 0.5); +#else + cairo_set_source_rgba (cr, + bar->priv->layout.color_fg.red / 65535.0, + bar->priv->layout.color_fg.green / 65535.0, + bar->priv->layout.color_fg.blue / 65535.0, + 0.5); +#endif cairo_fill_preserve (cr); } else { /* fill background */ - cairo_set_source_rgb (cr, bar->priv->layout.bg_r, bar->priv->layout.bg_g, bar->priv->layout.bg_b); +#if GTK_CHECK_VERSION (3, 0, 0) + gdk_cairo_set_source_rgba (cr, &bar->priv->layout.color_bg); +#else + gdk_cairo_set_source_color (cr, &bar->priv->layout.color_bg); +#endif cairo_fill_preserve (cr); } /* stroke border */ - cairo_set_source_rgb (cr, bar->priv->layout.bdr_r, bar->priv->layout.bdr_g, bar->priv->layout.bdr_b); +#if GTK_CHECK_VERSION (3, 0, 0) + gdk_cairo_set_source_rgba (cr, &bar->priv->layout.color_dark); +#else + gdk_cairo_set_source_color (cr, &bar->priv->layout.color_dark); +#endif cairo_set_line_width (cr, 1); cairo_stroke (cr); } } + + cairo_restore (cr); + + return FALSE; +} + #if !GTK_CHECK_VERSION (3, 0, 0) - cairo_destroy (cr); -#endif +static int +gvc_level_bar_expose (GtkWidget *widget, GdkEventExpose *event) +{ + cairo_t *cr; + GtkAllocation allocation; + g_return_val_if_fail (event != NULL, FALSE); + + /* Event queue compression */ + if (event->count > 0) + return FALSE; + + gtk_widget_get_allocation (widget, &allocation); + + cr = gdk_cairo_create (gtk_widget_get_window (widget)); + cairo_translate (cr, + allocation.x, + allocation.y); + + gvc_level_bar_draw (widget, cr); + + cairo_destroy (cr); return FALSE; } +#endif static void gvc_level_bar_class_init (GvcLevelBarClass *klass) @@ -689,7 +767,6 @@ gvc_level_bar_class_init (GvcLevelBarClass *klass) GObjectClass *object_class = G_OBJECT_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); - object_class->constructor = gvc_level_bar_constructor; object_class->finalize = gvc_level_bar_finalize; object_class->set_property = gvc_level_bar_set_property; object_class->get_property = gvc_level_bar_get_property; @@ -704,37 +781,43 @@ gvc_level_bar_class_init (GvcLevelBarClass *klass) #endif widget_class->size_allocate = gvc_level_bar_size_allocate; - g_object_class_install_property (object_class, - PROP_ORIENTATION, - g_param_spec_enum ("orientation", - "Orientation", - "The orientation of the bar", - GTK_TYPE_ORIENTATION, - GTK_ORIENTATION_HORIZONTAL, - G_PARAM_READWRITE)); - g_object_class_install_property (object_class, - PROP_PEAK_ADJUSTMENT, - g_param_spec_object ("peak-adjustment", - "Peak Adjustment", - "The GtkAdjustment that contains the current peak value", - GTK_TYPE_ADJUSTMENT, - G_PARAM_READWRITE)); - g_object_class_install_property (object_class, - PROP_RMS_ADJUSTMENT, - g_param_spec_object ("rms-adjustment", - "RMS Adjustment", - "The GtkAdjustment that contains the current rms value", - GTK_TYPE_ADJUSTMENT, - G_PARAM_READWRITE)); - g_object_class_install_property (object_class, - PROP_SCALE, - g_param_spec_int ("scale", - "Scale", - "Scale", - 0, - G_MAXINT, - GVC_LEVEL_SCALE_LINEAR, - G_PARAM_READWRITE|G_PARAM_CONSTRUCT)); + properties[PROP_ORIENTATION] = + g_param_spec_enum ("orientation", + "Orientation", + "The orientation of the bar", + GTK_TYPE_ORIENTATION, + GTK_ORIENTATION_HORIZONTAL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS); + + properties[PROP_PEAK_ADJUSTMENT] = + g_param_spec_object ("peak-adjustment", + "Peak Adjustment", + "The GtkAdjustment that contains the current peak value", + GTK_TYPE_ADJUSTMENT, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS); + + properties[PROP_RMS_ADJUSTMENT] = + g_param_spec_object ("rms-adjustment", + "RMS Adjustment", + "The GtkAdjustment that contains the current rms value", + GTK_TYPE_ADJUSTMENT, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS); + + properties[PROP_SCALE] = + g_param_spec_int ("scale", + "Scale", + "Scale", + 0, + G_MAXINT, + GVC_LEVEL_SCALE_LINEAR, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, N_PROPERTIES, properties); g_type_class_add_private (klass, sizeof (GvcLevelBarPrivate)); } @@ -751,6 +834,7 @@ gvc_level_bar_init (GvcLevelBar *bar) 0.1, 0.1)); g_object_ref_sink (bar->priv->peak_adjustment); + g_signal_connect (bar->priv->peak_adjustment, "value-changed", G_CALLBACK (on_peak_adjustment_value_changed), @@ -763,6 +847,7 @@ gvc_level_bar_init (GvcLevelBar *bar) 0.1, 0.1)); g_object_ref_sink (bar->priv->rms_adjustment); + g_signal_connect (bar->priv->rms_adjustment, "value-changed", G_CALLBACK (on_rms_adjustment_value_changed), @@ -776,16 +861,10 @@ gvc_level_bar_finalize (GObject *object) { GvcLevelBar *bar; - g_return_if_fail (object != NULL); - g_return_if_fail (GVC_IS_LEVEL_BAR (object)); - bar = GVC_LEVEL_BAR (object); - if (bar->priv->max_peak_id > 0) { + if (bar->priv->max_peak_id > 0) g_source_remove (bar->priv->max_peak_id); - } - - g_return_if_fail (bar->priv != NULL); G_OBJECT_CLASS (gvc_level_bar_parent_class)->finalize (object); } @@ -793,8 +872,5 @@ gvc_level_bar_finalize (GObject *object) GtkWidget * gvc_level_bar_new (void) { - GObject *bar; - bar = g_object_new (GVC_TYPE_LEVEL_BAR, - NULL); - return GTK_WIDGET (bar); + return g_object_new (GVC_TYPE_LEVEL_BAR, NULL); } |