2 * This file is a part of hildon
4 * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
6 * Contact: Rodrigo Novo <rodrigo.novo@nokia.com>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; version 2.1 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
26 * SECTION:hildon-volumebar-range
27 * @short_description: This widget is an "workhorse" for #HildonVolumebar
28 * widget. It is not designed to be used as a standalone widget.
30 * Purpose of this widget is to act as an "container" for GtkScale
31 * widget. #HildonVolumebarRange changes some event parameters so
32 * that #HildonVolumebar can meet its specifications.
34 * Currently #HildonVolumebarRange models range of [0..100].
38 #include <gdk/gdkkeysyms.h>
40 #include "hildon-volumebar-range.h"
42 #define VOLUMEBAR_RANGE_INITIAL_VALUE 50.0
44 #define VOLUMEBAR_RANGE_MINIMUM_VALUE 0.0
46 #define VOLUMEBAR_RANGE_MAXIMUM_VALUE 100.0
48 #define VOLUMEBAR_RANGE_STEP_INCREMENT_VALUE 5.0
50 #define VOLUMEBAR_RANGE_PAGE_INCREMENT_VALUE 5.0
52 #define VOLUMEBAR_RANGE_PAGE_SIZE_VALUE 0.0
54 #define CHANGE_THRESHOLD 0.001
56 static GtkScaleClass* parent_class;
59 hildon_volumebar_range_class_init (HildonVolumebarRangeClass*
63 hildon_volumebar_range_init (HildonVolumebarRange*
67 hildon_volumebar_range_set_property (GObject *object,
73 hildon_volumebar_range_get_property (GObject *object,
79 hildon_volumebar_range_button_press_event (GtkWidget *widget,
80 GdkEventButton *event);
83 hildon_volumebar_range_button_release_event (GtkWidget *widget,
84 GdkEventButton *event);
87 hildon_volumebar_range_keypress (GtkWidget *widget,
97 * hildon_volumebar_range_get_type:
99 * Initializes and returns the type of a hildon volumebar range.
101 * Returns: GType of #HildonVolumebarRange
104 hildon_volumebar_range_get_type (void)
106 static GType volumerange_type = 0;
108 if (!volumerange_type) {
109 static const GTypeInfo volumerange_info = {
110 sizeof (HildonVolumebarRangeClass),
111 NULL, /* base_init */
112 NULL, /* base_finalize */
113 (GClassInitFunc) hildon_volumebar_range_class_init,
114 NULL, /* class_finalize */
115 NULL, /* class_data */
116 sizeof (HildonVolumebarRange),
118 (GInstanceInitFunc) hildon_volumebar_range_init,
120 volumerange_type = g_type_register_static (GTK_TYPE_SCALE,
121 "HildonVolumebarRange",
122 &volumerange_info, 0);
125 return volumerange_type;
129 hildon_volumebar_range_class_init (HildonVolumebarRangeClass *volumerange_class)
131 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (volumerange_class);
132 GObjectClass *object_class = G_OBJECT_CLASS (volumerange_class);
134 parent_class = g_type_class_peek_parent (volumerange_class);
136 widget_class->button_press_event =
137 hildon_volumebar_range_button_press_event;
138 widget_class->button_release_event =
139 hildon_volumebar_range_button_release_event;
140 widget_class->key_press_event = hildon_volumebar_range_keypress;
142 object_class->set_property = hildon_volumebar_range_set_property;
143 object_class->get_property = hildon_volumebar_range_get_property;
146 * HildonVolumebarRange:level:
148 * Current volume level.
150 g_object_class_install_property (object_class,
152 g_param_spec_double ("level",
154 "Current volume level",
155 VOLUMEBAR_RANGE_MINIMUM_VALUE,
156 VOLUMEBAR_RANGE_MAXIMUM_VALUE,
157 VOLUMEBAR_RANGE_INITIAL_VALUE,
163 hildon_volumebar_range_init (HildonVolumebarRange *volumerange)
169 hildon_volumebar_range_set_property (GObject *object,
174 HildonVolumebarRange *range = HILDON_VOLUMEBAR_RANGE (object);
178 hildon_volumebar_range_set_level (range, g_value_get_double (value));
182 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
189 hildon_volumebar_range_get_property (GObject *object,
194 HildonVolumebarRange *range = HILDON_VOLUMEBAR_RANGE (object);
199 g_value_set_double (value, hildon_volumebar_range_get_level(range));
203 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
209 hildon_volumebar_range_keypress (GtkWidget *widget,
212 /* Accept arrow keys only if they match the orientation of the widget */
213 if (GTK_RANGE (widget)->orientation == GTK_ORIENTATION_HORIZONTAL)
215 if (event->keyval == GDK_Up || event->keyval == GDK_Down) {
221 if (event->keyval == GDK_Left || event->keyval == GDK_Right) {
226 return ((GTK_WIDGET_CLASS (parent_class)->key_press_event) (widget,
231 hildon_volumebar_range_new (GtkOrientation orientation)
233 GtkAdjustment * adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (VOLUMEBAR_RANGE_INITIAL_VALUE,
234 VOLUMEBAR_RANGE_MINIMUM_VALUE,
235 VOLUMEBAR_RANGE_MAXIMUM_VALUE,
236 VOLUMEBAR_RANGE_STEP_INCREMENT_VALUE,
237 VOLUMEBAR_RANGE_PAGE_INCREMENT_VALUE,
238 VOLUMEBAR_RANGE_PAGE_SIZE_VALUE));
240 HildonVolumebarRange *self =
241 g_object_new(HILDON_TYPE_VOLUMEBAR_RANGE,
242 "adjustment", adjustment,
245 GTK_RANGE (self)->orientation = orientation;
247 /* Default vertical range is upside down for purposes of this widget */
248 gtk_range_set_inverted (GTK_RANGE (self),
249 (orientation == GTK_ORIENTATION_VERTICAL));
251 return GTK_WIDGET(self);
255 hildon_volumebar_range_get_level (HildonVolumebarRange *self)
257 g_return_val_if_fail (HILDON_IS_VOLUMEBAR_RANGE(self), -1.0);
259 return gtk_adjustment_get_value (gtk_range_get_adjustment(GTK_RANGE (self)));
263 hildon_volumebar_range_set_level (HildonVolumebarRange * self,
266 GtkAdjustment *adjustment;
268 g_return_if_fail (HILDON_IS_VOLUMEBAR_RANGE (self));
270 adjustment = gtk_range_get_adjustment (GTK_RANGE (self));
272 /* Check that value has actually changed. Note that it's not safe to
273 * just compare if floats are equivalent or not */
274 if (ABS (gtk_adjustment_get_value (adjustment) - level) > CHANGE_THRESHOLD) {
275 gtk_adjustment_set_value(adjustment, level);
280 hildon_volumebar_range_button_press_event (GtkWidget *widget,
281 GdkEventButton *event)
283 gboolean result = FALSE;
285 /* FIXME: By default, clicking left mouse button on GtkRange moves the
286 slider by one step towards the click location. However, we want stylus
287 taps to move the slider to the position of the tap, which by default
288 is the middle button behaviour. To avoid breaking default GtkRange
289 behaviour, this has been implemented by faking a middle button press. */
291 event->button = (event->button == 1) ? 2 : event->button;
292 if (GTK_WIDGET_CLASS (parent_class)->button_press_event) {
293 result = GTK_WIDGET_CLASS (parent_class)->button_press_event(widget, event);
300 hildon_volumebar_range_button_release_event (GtkWidget *widget,
301 GdkEventButton *event)
303 gboolean result = FALSE;
305 /* FIXME: By default, clicking left mouse button on GtkRange moves the
306 slider by one step towards the click location. However, we want stylus
307 taps to move the slider to the position of the tap, which by default
308 is the middle button behaviour. To avoid breaking default GtkRange
309 behaviour, this has been implemented by faking a middle button press. */
311 event->button = event->button == 1 ? 2 : event->button;
312 if (GTK_WIDGET_CLASS (parent_class)->button_release_event) {
313 result = GTK_WIDGET_CLASS(parent_class)->button_release_event(widget, event);