2 * This file is part of hildon-libs
4 * Copyright (C) 2005 Nokia Corporation.
6 * Contact: Luc Pionchon <luc.pionchon@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; either 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 * @file hildon-volumebar.c
28 * This file contains the implementation of the Hildon Volumebar.
29 * It is a base class for Hildon Vertical Volumebar and for
30 * Hildon Horizontal Volumebar classes.
34 #include <gtk/gtkwindow.h>
35 #include <gtk/gtksignal.h>
36 #include <gdk/gdkkeysyms.h>
38 #include "hildon-volumebar.h"
39 #include "hildon-volumebar-range.h"
40 #include "hildon-volumebar-private.h"
42 static GtkContainerClass *parent_class;
45 hildon_volumebar_class_init(HildonVolumebarClass * volumebar_class);
47 hildon_volumebar_init(HildonVolumebar * volumebar);
50 hildon_child_forall(GtkContainer * container,
51 gboolean include_internals,
53 gpointer callback_data);
55 hildon_volumebar_destroy(GtkObject * self);
57 static void hildon_volumebar_set_property(GObject * object,
61 static void hildon_volumebar_get_property(GObject * object,
66 static void mute_toggled (HildonVolumebar *self);
69 hildon_volumebar_key_press(GtkWidget * widget,
83 PROP_HILDON_FOCUSABLE,
88 static guint signals[LAST_SIGNAL] = { 0 };
91 hildon_volumebar_get_type(void)
93 static GType volumebar_type = 0;
95 if (!volumebar_type) {
96 static const GTypeInfo volumebar_info = {
97 sizeof(HildonVolumebarClass),
99 NULL, /* base_finalize */
100 (GClassInitFunc) hildon_volumebar_class_init,
101 NULL, /* class_finalize */
102 NULL, /* class_data */
103 sizeof(HildonVolumebar),
105 (GInstanceInitFunc) hildon_volumebar_init,
107 volumebar_type = g_type_register_static(GTK_TYPE_CONTAINER,
111 return volumebar_type;
115 hildon_volumebar_class_init(HildonVolumebarClass *volumebar_class)
117 GtkContainerClass *container_class =
118 GTK_CONTAINER_CLASS(volumebar_class);
119 GObjectClass *object_class = G_OBJECT_CLASS(volumebar_class);
121 parent_class = g_type_class_peek_parent(volumebar_class);
123 g_type_class_add_private(volumebar_class,
124 sizeof(HildonVolumebarPrivate));
126 /* Because we derived our widget from GtkContainer, we should also
127 override forall method */
128 volumebar_class->mute_toggled = mute_toggled;
129 container_class->forall = hildon_child_forall;
130 GTK_WIDGET_CLASS(volumebar_class)->key_press_event = hildon_volumebar_key_press;
131 GTK_OBJECT_CLASS(volumebar_class)->destroy = hildon_volumebar_destroy;
133 signals[MUTE_TOGGLED_SIGNAL] = g_signal_new("mute_toggled",
139 (HildonVolumebarClass,
140 mute_toggled), NULL, NULL,
141 gtk_marshal_VOID__VOID,
144 signals[LEVEL_CHANGED_SIGNAL] = g_signal_new("level_changed",
150 (HildonVolumebarClass,
151 level_changed), NULL,
153 gtk_marshal_VOID__VOID,
156 object_class->set_property = hildon_volumebar_set_property;
157 object_class->get_property = hildon_volumebar_get_property;
159 /*This kind of property could be usefull in the gtkcontainer*/
160 g_object_class_install_property(object_class,
161 PROP_HILDON_FOCUSABLE,
162 g_param_spec_boolean("can-focus",
163 "The widget focusablility",
164 "The widget focusablility. TRUE is focusable",
166 G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
168 g_object_class_install_property(object_class,
169 PROP_HILDON_HAS_MUTE,
170 g_param_spec_boolean("has_mute",
171 "Show/Hide the mute button",
172 "Whether the mute button is visible. Default value: TRUE",
174 G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
176 g_object_class_install_property(object_class,
178 g_param_spec_double("level",
180 "Current volume level",
186 g_object_class_install_property(object_class,
188 g_param_spec_boolean("mute",
190 "Whether volume is muted",
198 hildon_volumebar_init(HildonVolumebar * volumebar)
200 HildonVolumebarPrivate *priv;
202 priv = HILDON_VOLUMEBAR_GET_PRIVATE(volumebar);
204 /* Should set GTK_NO_WINDOW flag, because widget is derived from
206 GTK_WIDGET_SET_FLAGS(GTK_WIDGET(volumebar), GTK_NO_WINDOW);
207 GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(volumebar), GTK_CAN_FOCUS);
209 priv->tbutton = GTK_TOGGLE_BUTTON(gtk_toggle_button_new());
210 g_object_set (G_OBJECT (priv->tbutton), "can-focus", FALSE, NULL);
214 hildon_child_forall(GtkContainer * container,
215 gboolean include_internals,
216 GtkCallback callback, gpointer callback_data)
218 HildonVolumebar *vbar;
219 HildonVolumebarPrivate *priv;
221 vbar = HILDON_VOLUMEBAR(container);
222 priv = HILDON_VOLUMEBAR_GET_PRIVATE(vbar);
224 g_return_if_fail(callback != NULL);
226 if (!include_internals)
229 (*callback) (GTK_WIDGET(priv->tbutton), callback_data);
230 (*callback) (GTK_WIDGET(priv->volumebar), callback_data);
234 hildon_volumebar_destroy(GtkObject * self)
236 HildonVolumebarPrivate *priv;
238 priv = HILDON_VOLUMEBAR_GET_PRIVATE(self);
241 gtk_widget_unparent(GTK_WIDGET(priv->tbutton));
242 priv->tbutton = NULL;
244 if (priv->volumebar) {
245 gtk_widget_unparent(GTK_WIDGET(priv->volumebar));
246 priv->volumebar = NULL;
249 if (GTK_OBJECT_CLASS(parent_class)->destroy)
250 GTK_OBJECT_CLASS(parent_class)->destroy(self);
254 hildon_volumebar_set_property(GObject * object,
256 const GValue * value,
259 HildonVolumebar *vbar = HILDON_VOLUMEBAR(object);
260 HildonVolumebarPrivate *priv;
262 priv = HILDON_VOLUMEBAR_GET_PRIVATE(vbar)
265 case PROP_HILDON_HAS_MUTE:
266 if (g_value_get_boolean(value))
267 gtk_widget_show(GTK_WIDGET(priv->tbutton));
269 gtk_widget_hide(GTK_WIDGET(priv->tbutton));
271 case PROP_HILDON_FOCUSABLE:
272 g_object_set( G_OBJECT(priv->volumebar), "can-focus",
273 g_value_get_boolean(value), NULL );
275 case PROP_HILDON_LEVEL:
276 hildon_volumebar_set_level(HILDON_VOLUMEBAR(priv->volumebar),
277 g_value_get_double(value));
279 case PROP_HILDON_MUTE:
280 hildon_volumebar_set_mute(HILDON_VOLUMEBAR(priv->volumebar),
281 g_value_get_boolean(value));
284 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
291 hildon_volumebar_get_property(GObject * object,
292 guint prop_id, GValue * value,
295 HildonVolumebar *vb = HILDON_VOLUMEBAR(object);
296 HildonVolumebarPrivate *priv = HILDON_VOLUMEBAR_GET_PRIVATE(vb);
299 case PROP_HILDON_HAS_MUTE:
300 g_value_set_boolean(value, GTK_WIDGET_VISIBLE(priv->tbutton));
302 case PROP_HILDON_FOCUSABLE:
303 g_value_set_boolean(value, GTK_WIDGET_CAN_FOCUS(priv->volumebar));
305 case PROP_HILDON_LEVEL:
306 g_value_set_double(value, hildon_volumebar_get_level(vb));
308 case PROP_HILDON_MUTE:
309 g_value_set_boolean(value, hildon_volumebar_get_mute(vb));
312 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
318 * hildon_volumebar_level_change:
319 * @self: a HildonVolumebar widget.
321 * Emits "level_changed" signal to the given volumebar. This function
322 * is mainly used by derived classes.
325 hildon_volumebar_level_change(HildonVolumebar * self)
327 g_return_if_fail(HILDON_IS_VOLUMEBAR(self));
328 g_signal_emit_by_name(GTK_WIDGET(self), "level_changed");
332 * hildon_volumebar_set_level:
333 * @self: volumebar to change level on
336 * Sets new volumelevel for this #HildonVolumebar.
339 hildon_volumebar_set_level(HildonVolumebar * self, gdouble level)
341 HildonVolumebarPrivate *priv;
343 g_return_if_fail(self);
345 priv = HILDON_VOLUMEBAR_GET_PRIVATE(self);
347 /* No need to clamp the level to legal values here as volumebarrange
348 * will do it anyway. And here we don't know the correct values anyway.
350 hildon_volumebar_range_set_level(priv->volumebar, level);
354 * hildon_volumebar_get_level:
355 * @self: volumebar to query level on
357 * Gets the volumelevel of this #HildonVolumebar.
359 * Return value: Volume level.
362 hildon_volumebar_get_level(HildonVolumebar * self)
364 HildonVolumebarPrivate *priv;
366 g_return_val_if_fail(self, -1);
368 priv = HILDON_VOLUMEBAR_GET_PRIVATE(self);
370 return hildon_volumebar_range_get_level(priv->volumebar);
374 * hildon_volumebar_set_mute:
375 * @self: volumebar to work on
378 * Sets mute status for this #HildonVolumebar.
382 hildon_volumebar_set_mute(HildonVolumebar * self, gboolean mute)
384 HildonVolumebarPrivate *priv;
385 gboolean focusable = TRUE;
387 g_return_if_fail(self);
389 priv = HILDON_VOLUMEBAR_GET_PRIVATE(self);
390 gtk_widget_set_sensitive(GTK_WIDGET(priv->volumebar), !mute);
392 focusable = GTK_WIDGET_CAN_FOCUS (GTK_WIDGET (priv->volumebar));
397 g_object_set (G_OBJECT (priv->tbutton), "can-focus", TRUE, NULL);
398 gtk_widget_grab_focus (GTK_WIDGET(priv->tbutton));
403 g_object_set (G_OBJECT (priv->tbutton), "can-focus", FALSE, NULL);
406 gtk_widget_grab_focus (GTK_WIDGET (self));
409 GtkWidget *win = gtk_widget_get_ancestor (GTK_WIDGET (self),
411 gtk_window_set_focus (GTK_WINDOW (win), NULL);
415 gtk_toggle_button_set_active(priv->tbutton, mute);
417 gtk_widget_queue_draw (GTK_WIDGET (self));
421 * hildon_volumebar_get_mute:
422 * @self: volumebar to query mute status
424 * Gets mute status of this #HildonVolumebar (ON/OFF).
426 * Return value: Mute status as #gboolean value.
429 hildon_volumebar_get_mute(HildonVolumebar * self)
431 HildonVolumebarPrivate *priv;
433 g_return_val_if_fail(self, TRUE);
435 priv = HILDON_VOLUMEBAR_GET_PRIVATE(self);
437 return gtk_toggle_button_get_active(priv->tbutton);
441 * hildon_volumebar_get_adjustment
442 * @self : A #HildonVolumebar
444 * Gets the GtkAdjustment used in volumebar. This can be handy
445 * to give to hildon_appview_set_connected_adjustment which
446 * will allow changing the volume with increase / decrease
449 * This is a temporary solution until volumebar is restructured to
450 * be a child class of GtkRange.
452 * Return value: A @GtkAdjustment used by volumebar.
455 hildon_volumebar_get_adjustment (HildonVolumebar * self)
457 HildonVolumebarPrivate *priv;
459 g_return_val_if_fail(self, NULL);
461 priv = HILDON_VOLUMEBAR_GET_PRIVATE(self);
463 return gtk_range_get_adjustment (GTK_RANGE (priv->volumebar));
467 mute_toggled (HildonVolumebar *self)
469 /* only call hildon_volumebar_set_mute. everything is done there */
470 hildon_volumebar_set_mute (self, hildon_volumebar_get_mute(self));
474 hildon_volumebar_key_press (GtkWidget * widget,
477 HildonVolumebarPrivate *priv;
479 g_return_val_if_fail(widget, FALSE);
480 g_return_val_if_fail(event, FALSE);
482 priv = HILDON_VOLUMEBAR_GET_PRIVATE(widget);
484 if (event->keyval == GDK_Return && GTK_WIDGET_VISIBLE(priv->tbutton)) {
485 gtk_toggle_button_set_active(priv->tbutton,
486 !hildon_volumebar_get_mute(HILDON_VOLUMEBAR(widget)));
490 return GTK_WIDGET_CLASS(parent_class)->key_press_event(widget, event);