X-Git-Url: https://vcs.maemo.org/git/?a=blobdiff_plain;f=src%2Fhildon-controlbar.c;h=44cddc42d91401ec2d70396ad60ef5e86e8e39f2;hb=7cc18180942701cf067dbfe71991afe9315c7485;hp=87e750d69ab321c94c4600d1cba0c4723c41691b;hpb=f6302d17784a0020efc9faef31b8d8c773b1ba44;p=hildon diff --git a/src/hildon-controlbar.c b/src/hildon-controlbar.c index 87e750d..44cddc4 100644 --- a/src/hildon-controlbar.c +++ b/src/hildon-controlbar.c @@ -1,5 +1,5 @@ /* - * This file is part of hildon-libs + * This file is a part of hildon * * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved. * @@ -25,309 +25,365 @@ /** * SECTION:hildon-controlbar * @short_description: A widget that allows increasing or decreasing - * a value within a pre-defined range + * a value within a pre-defined range. * * #HildonControlbar is a horizontally positioned range widget that is * visually divided into blocks and supports setting a minimum and * maximum value for the range. + * + * + * HildonControlbar example + * + * GtkWidget *cbar = hildon_controlbar_new(); + * hildon_controlbar_set_max (HILDON_CONTROLBAR (cbar), 12); + * hildon_controlbar_set_value (HILDON_CONTROLBAR (cbar), 6); + * + * + * */ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "hildon-controlbar.h" +#include +#include +#include +#include +#include +#include "hildon-controlbar-private.h" + +#define _(string)\ + dgettext("hildon-libs", string) + +#define DEFAULT_WIDTH 234 + +#define DEFAULT_HEIGHT 30 -#include -#include -#include -#include -#include "hildon-controlbar.h" +#define DEFAULT_BORDER_WIDTH 2 -#include -#define _(string) dgettext(PACKAGE, string) +#define HILDON_CONTROLBAR_STEP_INCREMENT 1 -#define HILDON_CONTROLBAR_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((obj),\ - HILDON_TYPE_CONTROLBAR, HildonControlbarPrivate)); +#define HILDON_CONTROLBAR_PAGE_INCREMENT 1 -#define DEFAULT_WIDTH 234 -#define DEFAULT_HEIGHT 30 -#define DEFAULT_BORDER_WIDTH 2 +#define HILDON_CONTROLBAR_PAGE_SIZE 0 -#define HILDON_CONTROLBAR_STEP_INCREMENT 1 -#define HILDON_CONTROLBAR_PAGE_INCREMENT 1 -#define HILDON_CONTROLBAR_PAGE_SIZE 0 -#define HILDON_CONTROLBAR_UPPER_VALUE 10 -#define HILDON_CONTROLBAR_LOWER_VALUE 0.0 -#define HILDON_CONTROLBAR_INITIAL_VALUE 0 +#define HILDON_CONTROLBAR_UPPER_VALUE 10 -static GtkScaleClass *parent_class; +#define HILDON_CONTROLBAR_LOWER_VALUE 0.0 -typedef struct _HildonControlbarPrivate HildonControlbarPrivate; +#define HILDON_CONTROLBAR_INITIAL_VALUE 0 + +static GtkScaleClass* parent_class; enum { - PROP_MIN = 1, - PROP_MAX, - PROP_VALUE + PROP_0, + PROP_MIN = 1, + PROP_MAX, + PROP_VALUE }; enum { - END_REACHED, - LAST_SIGNAL + END_REACHED, + LAST_SIGNAL }; -static guint signals[LAST_SIGNAL] = { 0 }; +static guint signals[LAST_SIGNAL] = { 0 }; static void -hildon_controlbar_class_init(HildonControlbarClass * controlbar_class); -static void hildon_controlbar_init(HildonControlbar * controlbar); -static GObject * -hildon_controlbar_constructor(GType type, guint n_construct_properties, - GObjectConstructParam *construct_properties); +hildon_controlbar_class_init (HildonControlbarClass *controlbar_class); + +static void +hildon_controlbar_init (HildonControlbar *controlbar); + +static GObject* +hildon_controlbar_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties); -static gint hildon_controlbar_button_press_event(GtkWidget * widget, +static gint +hildon_controlbar_button_press_event (GtkWidget *widget, GdkEventButton * event); -static gint hildon_controlbar_button_release_event(GtkWidget * widget, - GdkEventButton * event); + +static gint +hildon_controlbar_button_release_event (GtkWidget *widget, + GdkEventButton *event); + static gint -hildon_controlbar_expose_event(GtkWidget * widget, GdkEventExpose * event); +hildon_controlbar_expose_event (GtkWidget *widget, + GdkEventExpose *event); + static void -hildon_controlbar_size_request(GtkWidget * self, GtkRequisition * req); +hildon_controlbar_size_request (GtkWidget *self, + GtkRequisition *req); static void -hildon_controlbar_paint(HildonControlbar * self, GdkRectangle * area); +hildon_controlbar_paint (HildonControlbar *self, + GdkRectangle * area); + static gboolean -hildon_controlbar_keypress(GtkWidget * widget, GdkEventKey * event); +hildon_controlbar_keypress (GtkWidget *widget, + GdkEventKey * event); + +static void +hildon_controlbar_set_property (GObject *object, + guint param_id, + const GValue *value, + GParamSpec *pspec); -static void hildon_controlbar_set_property( GObject *object, guint param_id, - const GValue *value, GParamSpec *pspec ); -static void hildon_controlbar_get_property( GObject *object, guint param_id, - GValue *value, GParamSpec *pspec ); +static void +hildon_controlbar_get_property (GObject *object, + guint param_id, + GValue *value, + GParamSpec *pspec); static void -hildon_controlbar_value_changed( GtkAdjustment *adj, GtkRange *range ); +hildon_controlbar_value_changed (GtkAdjustment *adj, + GtkRange *range); -/* - * Purpose of this function is to prevent Up and Down keys from - * changing the widget's value (like Left and Right). Instead they - * are used for changing focus to other widgtes. - */ static gboolean -hildon_controlbar_change_value( GtkRange *range, GtkScrollType scroll, - gdouble new_value, gpointer data ); +hildon_controlbar_change_value (GtkRange *range, + GtkScrollType scroll, + gdouble new_value, + gpointer data); -GType hildon_controlbar_get_type(void) +/** + * hildon_controlbar_get_type: + * + * Initializes and returns the type of a hildon control bar. + * + * @Returns: GType of #HildonControlbar + */ +GType G_GNUC_CONST +hildon_controlbar_get_type (void) { static GType controlbar_type = 0; if (!controlbar_type) { static const GTypeInfo controlbar_info = { - sizeof(HildonControlbarClass), + sizeof (HildonControlbarClass), NULL, /* base_init */ NULL, /* base_finalize */ (GClassInitFunc) hildon_controlbar_class_init, NULL, /* class_finalize */ NULL, /* class_data */ - sizeof(HildonControlbar), + sizeof (HildonControlbar), 0, /* n_preallocs */ (GInstanceInitFunc) hildon_controlbar_init, }; - controlbar_type = g_type_register_static(GTK_TYPE_SCALE, - "HildonControlbar", - &controlbar_info, 0); + controlbar_type = g_type_register_static (GTK_TYPE_SCALE, + "HildonControlbar", + &controlbar_info, 0); } + return controlbar_type; } -struct _HildonControlbarPrivate { - gboolean button_press; - gint old_value; -}; - static void -hildon_controlbar_class_init(HildonControlbarClass * controlbar_class) +hildon_controlbar_class_init (HildonControlbarClass *controlbar_class) { - GObjectClass *gobject_class = G_OBJECT_CLASS(controlbar_class); - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(controlbar_class); - - parent_class = g_type_class_peek_parent(controlbar_class); - - g_type_class_add_private(controlbar_class, - sizeof(HildonControlbarPrivate)); - - gobject_class->get_property = hildon_controlbar_get_property; - gobject_class->set_property = hildon_controlbar_set_property; - widget_class->size_request = hildon_controlbar_size_request; - widget_class->button_press_event = hildon_controlbar_button_press_event; - widget_class->button_release_event = hildon_controlbar_button_release_event; - widget_class->expose_event = hildon_controlbar_expose_event; - widget_class->key_press_event = hildon_controlbar_keypress; - G_OBJECT_CLASS(controlbar_class)->constructor = hildon_controlbar_constructor; - controlbar_class->end_reached = NULL; - - /** - * HildonControlbar:min: - * - * Controlbar minimum value. - */ - g_object_class_install_property( gobject_class, PROP_MIN, - g_param_spec_int("min", - "Minimum value", - "Smallest possible value", - G_MININT, G_MAXINT, - HILDON_CONTROLBAR_LOWER_VALUE, - G_PARAM_READABLE | G_PARAM_WRITABLE) ); - - /** - * HildonControlbar:max: - * - * Controlbar maximum value. - */ - g_object_class_install_property( gobject_class, PROP_MAX, - g_param_spec_int("max", - "Maximum value", - "Greatest possible value", - G_MININT, G_MAXINT, - HILDON_CONTROLBAR_UPPER_VALUE, - G_PARAM_READABLE | G_PARAM_WRITABLE) ); - - /** - * HildonControlbar:value: - * - * Controlbar value. - */ - g_object_class_install_property( gobject_class, PROP_VALUE, - g_param_spec_int("value", - "Current value", - "Current value", - G_MININT, G_MAXINT, - HILDON_CONTROLBAR_INITIAL_VALUE, - G_PARAM_READABLE | G_PARAM_WRITABLE) ); - - - gtk_widget_class_install_style_property(widget_class, - g_param_spec_uint("inner_border_width", - "Inner border width", - "The border spacing between the controlbar border and controlbar blocks.", - 0, G_MAXINT, - DEFAULT_BORDER_WIDTH, - G_PARAM_READABLE)); - - signals[END_REACHED] = + GObjectClass *gobject_class = G_OBJECT_CLASS (controlbar_class); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (controlbar_class); + + parent_class = g_type_class_peek_parent(controlbar_class); + + g_type_class_add_private(controlbar_class, sizeof (HildonControlbarPrivate)); + + gobject_class->get_property = hildon_controlbar_get_property; + gobject_class->set_property = hildon_controlbar_set_property; + gobject_class->constructor = hildon_controlbar_constructor; + widget_class->size_request = hildon_controlbar_size_request; + widget_class->button_press_event = hildon_controlbar_button_press_event; + widget_class->button_release_event = hildon_controlbar_button_release_event; + widget_class->expose_event = hildon_controlbar_expose_event; + widget_class->key_press_event = hildon_controlbar_keypress; + controlbar_class->end_reached = NULL; + + /** + * HildonControlbar:min: + * + * Controlbar minimum value. + */ + g_object_class_install_property (gobject_class, PROP_MIN, + g_param_spec_int ("min", + "Minimum value", + "Smallest possible value", + G_MININT, G_MAXINT, + HILDON_CONTROLBAR_LOWER_VALUE, + G_PARAM_READABLE | G_PARAM_WRITABLE)); + + /** + * HildonControlbar:max: + * + * Controlbar maximum value. + */ + g_object_class_install_property (gobject_class, PROP_MAX, + g_param_spec_int ("max", + "Maximum value", + "Greatest possible value", + G_MININT, G_MAXINT, + HILDON_CONTROLBAR_UPPER_VALUE, + G_PARAM_READABLE | G_PARAM_WRITABLE)); + + /** + * HildonControlbar:value: + * + * Controlbar current value. + */ + g_object_class_install_property (gobject_class, PROP_VALUE, + g_param_spec_int ("value", + "Current value", + "Current value", + G_MININT, G_MAXINT, + HILDON_CONTROLBAR_INITIAL_VALUE, + G_PARAM_READABLE | G_PARAM_WRITABLE) ); + + + gtk_widget_class_install_style_property (widget_class, + g_param_spec_uint ("inner_border_width", + "Inner border width", + "The border spacing between the controlbar border and controlbar blocks.", + 0, G_MAXINT, + DEFAULT_BORDER_WIDTH, + G_PARAM_READABLE)); + + signals[END_REACHED] = g_signal_new("end-reached", - G_OBJECT_CLASS_TYPE(gobject_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET(HildonControlbarClass, end_reached), - NULL, NULL, - g_cclosure_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, - G_TYPE_BOOLEAN); + G_OBJECT_CLASS_TYPE (gobject_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (HildonControlbarClass, end_reached), + NULL, NULL, + g_cclosure_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, + G_TYPE_BOOLEAN); } -static void hildon_controlbar_init(HildonControlbar * controlbar) +static void +hildon_controlbar_init (HildonControlbar *controlbar) { GtkRange *range; HildonControlbarPrivate *priv; /* Initialize the private property */ priv = HILDON_CONTROLBAR_GET_PRIVATE(controlbar); + g_assert (priv); + priv->button_press = FALSE; priv->old_value = 0; - range = GTK_RANGE(controlbar); + range = GTK_RANGE (controlbar); range->has_stepper_a = TRUE; range->has_stepper_d = TRUE; range->round_digits = -1; - - gtk_widget_set_size_request( GTK_WIDGET(controlbar), DEFAULT_WIDTH, - DEFAULT_HEIGHT ); - g_signal_connect( range, "change-value", - G_CALLBACK(hildon_controlbar_change_value), NULL ); + + gtk_widget_set_size_request (GTK_WIDGET (controlbar), + DEFAULT_WIDTH, + DEFAULT_HEIGHT); + + g_signal_connect (range, "change-value", + G_CALLBACK (hildon_controlbar_change_value), NULL); } -static GObject *hildon_controlbar_constructor(GType type, - guint n_construct_properties, GObjectConstructParam *construct_properties) +static GObject* +hildon_controlbar_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties) { - GObject *obj; - GtkAdjustment *adj; - - obj = G_OBJECT_CLASS(parent_class)->constructor(type, - n_construct_properties, construct_properties); - - gtk_scale_set_draw_value (GTK_SCALE (obj), FALSE); - - /* Initialize the GtkAdjustment of the controlbar*/ - adj = GTK_RANGE(obj)->adjustment; - adj->step_increment = HILDON_CONTROLBAR_STEP_INCREMENT; - adj->page_increment = HILDON_CONTROLBAR_PAGE_INCREMENT; - adj->page_size = HILDON_CONTROLBAR_PAGE_SIZE; - - g_signal_connect( adj, "value-changed", - G_CALLBACK(hildon_controlbar_value_changed), obj ); - return obj; + GObject *obj; + GtkAdjustment *adj; + + obj = G_OBJECT_CLASS (parent_class)->constructor (type, + n_construct_properties, construct_properties); + + gtk_scale_set_draw_value (GTK_SCALE (obj), FALSE); + + /* Initialize the GtkAdjustment of the controlbar*/ + adj = GTK_RANGE (obj)->adjustment; + adj->step_increment = HILDON_CONTROLBAR_STEP_INCREMENT; + adj->page_increment = HILDON_CONTROLBAR_PAGE_INCREMENT; + adj->page_size = HILDON_CONTROLBAR_PAGE_SIZE; + + g_signal_connect (adj, "value-changed", + G_CALLBACK (hildon_controlbar_value_changed), obj); + return obj; } -static void hildon_controlbar_set_property (GObject *object, guint param_id, - const GValue *value, GParamSpec *pspec) +static void +hildon_controlbar_set_property (GObject *object, + guint param_id, + const GValue *value, + GParamSpec *pspec) { - HildonControlbar *controlbar = HILDON_CONTROLBAR(object); - switch (param_id) - { - case PROP_MIN: - hildon_controlbar_set_min (controlbar, g_value_get_int(value)); - break; - - case PROP_MAX: - hildon_controlbar_set_max (controlbar, g_value_get_int(value)); - break; - - case PROP_VALUE: - hildon_controlbar_set_value (controlbar, g_value_get_int(value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec); - break; - } + HildonControlbar *controlbar = HILDON_CONTROLBAR (object); + + switch (param_id) + { + case PROP_MIN: + hildon_controlbar_set_min (controlbar, g_value_get_int(value)); + break; + + case PROP_MAX: + hildon_controlbar_set_max (controlbar, g_value_get_int(value)); + break; + + case PROP_VALUE: + hildon_controlbar_set_value (controlbar, g_value_get_int(value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + } } -static void hildon_controlbar_get_property( GObject *object, guint param_id, - GValue *value, GParamSpec *pspec ) +static void hildon_controlbar_get_property (GObject *object, + guint param_id, + GValue *value, + GParamSpec *pspec) { - HildonControlbar *controlbar = HILDON_CONTROLBAR(object); - switch (param_id) - { - case PROP_MIN: - g_value_set_int (value, hildon_controlbar_get_min (controlbar)); - break; - - case PROP_MAX: - g_value_set_int (value, hildon_controlbar_get_max (controlbar)); - break; - - case PROP_VALUE: - g_value_set_int (value, hildon_controlbar_get_value (controlbar)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec); - break; - } + HildonControlbar *controlbar = HILDON_CONTROLBAR(object); + + switch (param_id) + { + case PROP_MIN: + g_value_set_int (value, hildon_controlbar_get_min (controlbar)); + break; + + case PROP_MAX: + g_value_set_int (value, hildon_controlbar_get_max (controlbar)); + break; + + case PROP_VALUE: + g_value_set_int (value, hildon_controlbar_get_value (controlbar)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + } } static void -hildon_controlbar_value_changed( GtkAdjustment *adj, GtkRange *range ) +hildon_controlbar_value_changed (GtkAdjustment *adj, + GtkRange *range) { - HildonControlbarPrivate *priv = HILDON_CONTROLBAR_GET_PRIVATE(range); - - /* Change the controlbar value if the adjusted value is large enough - * otherwise, keep the old value - */ - if( ABS(ceil(adj->value) - priv->old_value) >= 1 ) - { - priv->old_value = ceil(adj->value); - adj->value = priv->old_value; - } - else - g_signal_stop_emission_by_name( adj, "value-changed" ); - gtk_adjustment_set_value( adj, priv->old_value ); + HildonControlbarPrivate *priv = HILDON_CONTROLBAR_GET_PRIVATE(range); + g_assert (priv); + + /* Change the controlbar value if the adjusted value is large enough + * otherwise, keep the old value + */ + if (ABS(ceil (adj->value) - priv->old_value) >= 1) + { + priv->old_value = ceil (adj->value); + adj->value = priv->old_value; + } + else + g_signal_stop_emission_by_name (adj, "value-changed"); + + gtk_adjustment_set_value (adj, priv->old_value); } /** @@ -338,9 +394,10 @@ hildon_controlbar_value_changed( GtkAdjustment *adj, GtkRange *range ) * Returns: a #GtkWidget pointer of newly created control bar * widget */ -GtkWidget *hildon_controlbar_new(void) +GtkWidget* +hildon_controlbar_new (void) { - return GTK_WIDGET(g_object_new(HILDON_TYPE_CONTROLBAR, NULL)); + return GTK_WIDGET (g_object_new (HILDON_TYPE_CONTROLBAR, NULL)); } /* This function prevents Up and Down keys from changing the @@ -348,18 +405,21 @@ GtkWidget *hildon_controlbar_new(void) * Instead they are used for changing focus to other widgtes. */ static gboolean -hildon_controlbar_keypress(GtkWidget * widget, GdkEventKey * event) +hildon_controlbar_keypress (GtkWidget *widget, + GdkEventKey *event) { if (event->keyval == GDK_Up || event->keyval == GDK_Down) return FALSE; - return ((GTK_WIDGET_CLASS(parent_class)->key_press_event) (widget, event)); + + return ((GTK_WIDGET_CLASS (parent_class)->key_press_event) (widget, event)); } static void -hildon_controlbar_size_request(GtkWidget * self, GtkRequisition * req) +hildon_controlbar_size_request (GtkWidget *self, + GtkRequisition *req) { - if (GTK_WIDGET_CLASS(parent_class)->size_request) - GTK_WIDGET_CLASS(parent_class)->size_request(self, req); + if (GTK_WIDGET_CLASS (parent_class)->size_request) + GTK_WIDGET_CLASS (parent_class)->size_request(self, req); req->width = DEFAULT_WIDTH; req->height = DEFAULT_HEIGHT; @@ -370,15 +430,17 @@ hildon_controlbar_size_request(GtkWidget * self, GtkRequisition * req) * @self: pointer to #HildonControlbar * @value: value in range of >= 0 && < G_MAX_INT * - * Change the current value of the control bar to the specified value. + * Set the current value of the control bar to the specified value. */ -void hildon_controlbar_set_value(HildonControlbar * self, gint value) +void +hildon_controlbar_set_value (HildonControlbar * self, + gint value) { GtkAdjustment *adj; g_return_if_fail (HILDON_IS_CONTROLBAR (self)); - adj = GTK_RANGE(self)->adjustment; - - g_return_if_fail(value >= 0); + adj = GTK_RANGE (self)->adjustment; + + g_return_if_fail (value >= 0); if (value >= adj->upper) value = adj->upper; @@ -386,7 +448,7 @@ void hildon_controlbar_set_value(HildonControlbar * self, gint value) value = adj->lower; adj->value = value; - gtk_adjustment_value_changed(adj); + gtk_adjustment_value_changed (adj); g_object_notify (G_OBJECT(self), "value"); } @@ -397,12 +459,13 @@ void hildon_controlbar_set_value(HildonControlbar * self, gint value) * * Returns: current value as gint */ -gint hildon_controlbar_get_value(HildonControlbar * self) +gint +hildon_controlbar_get_value (HildonControlbar * self) { GtkAdjustment *adj; g_return_val_if_fail (HILDON_IS_CONTROLBAR (self), 0); adj = GTK_RANGE(self)->adjustment; - + return (gint) ceil(adj->value); } @@ -416,20 +479,22 @@ gint hildon_controlbar_get_value(HildonControlbar * self) * If the new maximum is smaller than current value, the value will be * adjusted so that it equals the new maximum. */ -void hildon_controlbar_set_max(HildonControlbar * self, gint max) +void +hildon_controlbar_set_max (HildonControlbar * self, + gint max) { GtkAdjustment *adj; g_return_if_fail (HILDON_IS_CONTROLBAR (self)); - adj = GTK_RANGE(self)->adjustment; + adj = GTK_RANGE (self)->adjustment; if (max < adj->lower) - max = adj->lower; - + max = adj->lower; + if (adj->value > max) hildon_controlbar_set_value (self, max); adj->upper = max; - gtk_adjustment_changed(adj); + gtk_adjustment_changed (adj); g_object_notify (G_OBJECT(self), "max"); } @@ -445,20 +510,22 @@ void hildon_controlbar_set_max(HildonControlbar * self, gint max) * If the new minimum is smaller than current value, the value will be * adjusted so that it equals the new minimum. */ -void hildon_controlbar_set_min(HildonControlbar * self, gint min) +void +hildon_controlbar_set_min (HildonControlbar *self, + gint min) { GtkAdjustment *adj; g_return_if_fail (HILDON_IS_CONTROLBAR (self)); - adj = GTK_RANGE(self)->adjustment; + adj = GTK_RANGE (self)->adjustment; if (min > adj->upper) - min = adj->upper; - + min = adj->upper; + if (adj->value < min) hildon_controlbar_set_value (self, min); adj->lower = min; - gtk_adjustment_changed(adj); + gtk_adjustment_changed (adj); g_object_notify (G_OBJECT(self), "min"); } @@ -477,13 +544,16 @@ void hildon_controlbar_set_min(HildonControlbar * self, gint min) * If the new minimum is smaller than current value, the value will be * adjusted so that it equals the new minimum. */ -void hildon_controlbar_set_range(HildonControlbar * self, gint min, - gint max) +void +hildon_controlbar_set_range (HildonControlbar *self, + gint min, + gint max) { g_return_if_fail (HILDON_IS_CONTROLBAR (self)); if (min > max) - min = max; + min = max; + /* We need to set max first here, because when min is set before * max is set, it would end up 0, because max can't be bigger than 0. */ @@ -497,11 +567,11 @@ void hildon_controlbar_set_range(HildonControlbar * self, gint min, * * Returns: maximum value of control bar */ -gint hildon_controlbar_get_max(HildonControlbar * self) +gint hildon_controlbar_get_max (HildonControlbar *self) { GtkAdjustment *adj; g_return_val_if_fail (HILDON_IS_CONTROLBAR (self), 0); - adj = GTK_RANGE(self)->adjustment; + adj = GTK_RANGE (self)->adjustment; return (gint) adj->upper; } @@ -512,9 +582,10 @@ gint hildon_controlbar_get_max(HildonControlbar * self) * * Returns: minimum value of controlbar */ -gint hildon_controlbar_get_min(HildonControlbar * self) +gint +hildon_controlbar_get_min (HildonControlbar *self) { - GtkAdjustment *adj = GTK_RANGE(self)->adjustment; + GtkAdjustment *adj = GTK_RANGE (self)->adjustment; return (gint) adj->lower; } @@ -522,21 +593,23 @@ gint hildon_controlbar_get_min(HildonControlbar * self) * Event handler for button press * Need to change button1 to button2 before passing this event to * parent handler. (see specs) - * Also updates button_press variable so that we can draw hilites + * Also updates button_press variable so that we can draw highlights * correctly */ -static gint hildon_controlbar_button_press_event(GtkWidget * widget, - GdkEventButton * event) +static gint +hildon_controlbar_button_press_event (GtkWidget *widget, + GdkEventButton *event) { HildonControlbar *self; HildonControlbarPrivate *priv; gboolean result = FALSE; - g_return_val_if_fail(widget, FALSE); - g_return_val_if_fail(event, FALSE); + g_return_val_if_fail (widget, FALSE); + g_return_val_if_fail (event, FALSE); - self = HILDON_CONTROLBAR(widget); - priv = HILDON_CONTROLBAR_GET_PRIVATE(self); + self = HILDON_CONTROLBAR (widget); + priv = HILDON_CONTROLBAR_GET_PRIVATE (self); + g_assert (priv); priv->button_press = TRUE; event->button = event->button == 1 ? 2 : event->button; @@ -556,9 +629,8 @@ static gint hildon_controlbar_button_press_event(GtkWidget * widget, /* call the parent handler */ - if (GTK_WIDGET_CLASS(parent_class)->button_press_event) - result = - GTK_WIDGET_CLASS(parent_class)->button_press_event(widget, event); + if (GTK_WIDGET_CLASS (parent_class)->button_press_event) + result = GTK_WIDGET_CLASS (parent_class)->button_press_event(widget, event); return result; } @@ -569,37 +641,43 @@ static gint hildon_controlbar_button_press_event(GtkWidget * widget, * are used for changing focus to other widgtes. */ static gboolean -hildon_controlbar_change_value( GtkRange *range, - GtkScrollType scroll, - gdouble new_value, - gpointer data ) +hildon_controlbar_change_value (GtkRange *range, + GtkScrollType scroll, + gdouble new_value, + gpointer data) { - HildonControlbarPrivate *priv; - GtkAdjustment *adj = range->adjustment; - - priv = HILDON_CONTROLBAR_GET_PRIVATE(range); - - /* Emit a signal when upper or lower limit is reached */ - switch (scroll) - { - case GTK_SCROLL_STEP_FORWARD : - case GTK_SCROLL_PAGE_FORWARD : - if( adj->value == priv->old_value ) - if( adj->value == adj->upper ) - g_signal_emit( G_OBJECT(range), signals[END_REACHED], 0, TRUE ); - break; - - case GTK_SCROLL_STEP_BACKWARD : - case GTK_SCROLL_PAGE_BACKWARD : - if( adj->value == priv->old_value ) - if( adj->value == adj->lower ) - g_signal_emit( G_OBJECT(range), signals[END_REACHED], 0, FALSE ); - break; - - default: - break; - } -return FALSE; + HildonControlbarPrivate *priv; + GtkAdjustment *adj = range->adjustment; + gdouble vv = adj->upper - adj->lower; + gint calc = ((new_value - adj->lower) / vv) * (vv + 1.0) + adj->lower; + + priv = HILDON_CONTROLBAR_GET_PRIVATE(range); + g_assert (priv); + + /* Emit a signal when upper or lower limit is reached */ + switch (scroll) + { + case GTK_SCROLL_STEP_FORWARD : + case GTK_SCROLL_PAGE_FORWARD : + if( adj->value == priv->old_value ) + if( adj->value == adj->upper ) + g_signal_emit( G_OBJECT(range), signals[END_REACHED], 0, TRUE ); + break; + + case GTK_SCROLL_STEP_BACKWARD : + case GTK_SCROLL_PAGE_BACKWARD : + if( adj->value == priv->old_value ) + if( adj->value == adj->lower ) + g_signal_emit( G_OBJECT(range), signals[END_REACHED], 0, FALSE ); + break; + + default: + break; + } + + GTK_RANGE_CLASS (parent_class)->change_value (range, scroll, calc); + + return TRUE; } /* @@ -609,34 +687,37 @@ return FALSE; * Also updates button_press variable so that we can draw hilites * correctly */ -static gint hildon_controlbar_button_release_event(GtkWidget * widget, - GdkEventButton * event) +static gint +hildon_controlbar_button_release_event (GtkWidget *widget, + GdkEventButton *event) { HildonControlbar *self; HildonControlbarPrivate *priv; gboolean result = FALSE; - g_return_val_if_fail(widget, FALSE); - g_return_val_if_fail(event, FALSE); + g_return_val_if_fail (widget, FALSE); + g_return_val_if_fail (event, FALSE); - self = HILDON_CONTROLBAR(widget); - priv = HILDON_CONTROLBAR_GET_PRIVATE(self); + self = HILDON_CONTROLBAR (widget); + priv = HILDON_CONTROLBAR_GET_PRIVATE (self); + g_assert (priv); priv->button_press = FALSE; event->button = event->button == 1 ? 2 : event->button; /* call the parent handler */ - if (GTK_WIDGET_CLASS(parent_class)->button_release_event) - result = - GTK_WIDGET_CLASS(parent_class)->button_release_event(widget, event); + if (GTK_WIDGET_CLASS (parent_class)->button_release_event) + result = GTK_WIDGET_CLASS (parent_class)->button_release_event (widget, event); + return result; } /* * Event handler for expose event */ -static gint hildon_controlbar_expose_event(GtkWidget * widget, - GdkEventExpose * event) +static gint +hildon_controlbar_expose_event (GtkWidget *widget, + GdkEventExpose * event) { HildonControlbar *self = NULL; @@ -644,9 +725,8 @@ static gint hildon_controlbar_expose_event(GtkWidget * widget, gint old_height = -1; gint old_y = -1; - g_return_val_if_fail(widget, FALSE); - g_return_val_if_fail(event, FALSE); - g_return_val_if_fail(HILDON_IS_CONTROLBAR(widget), FALSE); + g_return_val_if_fail (event, FALSE); + g_return_val_if_fail (HILDON_IS_CONTROLBAR(widget), FALSE); self = HILDON_CONTROLBAR(widget); @@ -658,6 +738,7 @@ static gint hildon_controlbar_expose_event(GtkWidget * widget, if (difference & 1) difference += 1; + difference = difference / 2; widget->allocation.y += difference; @@ -665,9 +746,10 @@ static gint hildon_controlbar_expose_event(GtkWidget * widget, } /* call the parent handler */ - if (GTK_WIDGET_CLASS(parent_class)->expose_event) - result = GTK_WIDGET_CLASS(parent_class)->expose_event(widget, event); - hildon_controlbar_paint(self, &event->area); + if (GTK_WIDGET_CLASS (parent_class)->expose_event) + result = GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event); + + hildon_controlbar_paint (self, &event->area); widget->allocation.height = old_height; widget->allocation.y = old_y; @@ -679,8 +761,9 @@ static gint hildon_controlbar_expose_event(GtkWidget * widget, * Paint method. * This is where all the work is actually done... */ -static void hildon_controlbar_paint(HildonControlbar * self, - GdkRectangle * area) +static void +hildon_controlbar_paint (HildonControlbar *self, + GdkRectangle *area) { HildonControlbarPrivate *priv; GtkWidget *widget = GTK_WIDGET(self); @@ -708,54 +791,55 @@ static void hildon_controlbar_paint(HildonControlbar * self, g_return_if_fail(area); priv = HILDON_CONTROLBAR_GET_PRIVATE(self); - if (GTK_WIDGET_SENSITIVE(self) == FALSE) + g_assert (priv); + + if (GTK_WIDGET_SENSITIVE (self) == FALSE) state = GTK_STATE_INSENSITIVE; - gtk_widget_style_get(GTK_WIDGET(self), - "stepper-size", &stepper_size, - "stepper-spacing", &stepper_spacing, - "inner_border_width", &inner_border_width, NULL); - g_object_get(G_OBJECT(self), "minimum_visible_bars", &block_min, NULL); + gtk_widget_style_get (GTK_WIDGET (self), + "stepper-size", &stepper_size, + "stepper-spacing", &stepper_spacing, + "inner_border_width", &inner_border_width, NULL); block_area = (w - 2 * stepper_size - 2 * stepper_spacing - 2 * inner_border_width); + if (block_area <= 0) return; + block_min = 1; block_max = ctrlbar->upper - ctrlbar->lower + block_min; - block_act = priv->old_value - GTK_RANGE(self)->adjustment->lower + block_min; - + block_act = priv->old_value - GTK_RANGE (self)->adjustment->lower + block_min; + /* We check border width and maximum value and adjust * separating pixels for block width here. If the block size would * become too small, we make the separators smaller. Graceful fallback. */ max = ctrlbar->upper; - if( ctrlbar->upper == 0 ) - { - separatingpixels = 3; - } - else if ((block_area - ((max - 1) * 3)) / max >= 4) { + if(ctrlbar->upper == 0) + separatingpixels = 3; + else if ((block_area - ((max - 1) * 3)) / max >= 4) separatingpixels = 3; - } else if ((block_area - ((max - 1) * 2)) / max >= 4) { + else if ((block_area - ((max - 1) * 2)) / max >= 4) separatingpixels = 2; - } else if ((block_area - ((max - 1) * 1)) / max >= 4) { + else if ((block_area - ((max - 1) * 1)) / max >= 4) separatingpixels = 1; - } else + else separatingpixels = 0; - if( block_max == 0 ) + if (block_max == 0) { - /* If block max is 0 then we dim the whole control. */ - state = GTK_STATE_INSENSITIVE; - block_width = block_area; - block_remains = 0; - block_max = 1; + /* If block max is 0 then we dim the whole control. */ + state = GTK_STATE_INSENSITIVE; + block_width = block_area; + block_remains = 0; + block_max = 1; } else { - block_width = - (block_area - (separatingpixels * (block_max - 1))) / block_max; - block_remains = - (block_area - (separatingpixels * (block_max - 1))) % block_max; + block_width = + (block_area - (separatingpixels * (block_max - 1))) / block_max; + block_remains = + (block_area - (separatingpixels * (block_max - 1))) % block_max; } block_x = x + stepper_size + stepper_spacing + inner_border_width; @@ -764,6 +848,8 @@ static void hildon_controlbar_paint(HildonControlbar * self, block_count = ctrlbar->value - ctrlbar->lower + block_min; + if (block_count == 0) + block_count = 1; /* Without this there is vertical block corruption when block_height = 1. This should work from 0 up to whatever */ @@ -785,11 +871,11 @@ static void hildon_controlbar_paint(HildonControlbar * self, end_x = block_width * i + (i * block_remains) / block_max; current_width = end_x - start_x; - gtk_paint_box(widget->style, widget->window, state, - (i <= block_count) ? GTK_SHADOW_IN : GTK_SHADOW_OUT, - NULL, widget, "hildon_block", - block_x, block_y, current_width, - block_height); + gtk_paint_box (widget->style, widget->window, state, + (i <= block_count) ? GTK_SHADOW_IN : GTK_SHADOW_OUT, + NULL, widget, "hildon_block", + block_x, block_y, current_width, + block_height); /* We keep the block_x separate because of the 'separatingpixels' */