2 * This file is part of hildon-libs
4 * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
6 * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@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 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-hvolumebar
27 * @short_description: A widget that displays a horizontal volume bar
28 * @see_also: #HildonVVolumebar, #HildonVolumebar
30 * The #HildonHVolumebar widget displays a horizontal volume bar that allows
31 * increasing or decreasing volume within a pre-defined range, and includes
32 * a mute icon which users can click to mute the sound.
36 /* Horizontal volumebar subclass */
38 #include <gtk/gtktoolbar.h>
39 #include "hildon-hvolumebar.h"
40 #include "hildon-volumebar.h"
41 #include "hildon-volumebar-range.h"
42 #include "hildon-volumebar-private.h"
44 /* Defines for normal version of HVolumebar */
46 #define DEFAULT_TBUTTON_WIDTH 26
47 #define DEFAULT_TBUTTON_HEIGHT 26
49 #define MINIMUM_BAR_WIDTH 147
50 #define DEFAULT_BAR_HEIGHT 58
51 #define DEFAULT_ENDING_SIZE 20
53 /* Gap to leave for mute button */
54 #define VERTICAL_MUTE_GAP 16
55 #define HORIZONTAL_MUTE_GAP 6
57 /* Sizes inside a toolbar */
59 #define TOOL_DEFAULT_TBUTTON_WIDTH 26
60 #define TOOL_DEFAULT_TBUTTON_HEIGHT 26
62 #define TOOL_MINIMUM_BAR_WIDTH 121
63 #define TOOL_DEFAULT_BAR_HEIGHT 40
64 #define TOOL_DEFAULT_ENDING_SIZE 0
65 #define TOOL_VERTICAL_MUTE_GAP ((TOOL_DEFAULT_BAR_HEIGHT - TOOL_DEFAULT_TBUTTON_HEIGHT) / 2)
67 static HildonVolumebarClass *parent_class;
68 static void hildon_hvolumebar_class_init(HildonHVolumebarClass * klass);
69 static void hildon_hvolumebar_init(HildonHVolumebar * hvolumebar);
71 static gboolean hildon_hvolumebar_expose(GtkWidget * widget,
72 GdkEventExpose * event);
73 static void hildon_hvolumebar_size_request(GtkWidget * widget,
74 GtkRequisition * requisition);
75 static void hildon_hvolumebar_size_allocate(GtkWidget * widget,
76 GtkAllocation * allocation);
77 static void hildon_hvolumebar_map(GtkWidget * widget);
80 GType hildon_hvolumebar_get_type(void)
82 static GType type = 0;
85 static const GTypeInfo info = {
86 sizeof(HildonHVolumebarClass),
88 NULL, /* base_finalize */
89 (GClassInitFunc) hildon_hvolumebar_class_init, /* class_init */
90 NULL, /* class_finalize */
91 NULL, /* class_data */
92 sizeof(HildonHVolumebar),
94 (GInstanceInitFunc) hildon_hvolumebar_init,
96 type = g_type_register_static(HILDON_TYPE_VOLUMEBAR,
97 "HildonHVolumebar", &info, 0);
103 static void hildon_hvolumebar_class_init(HildonHVolumebarClass * klass)
105 GtkWidgetClass *volumebar_class = GTK_WIDGET_CLASS(klass);
107 parent_class = g_type_class_peek_parent(klass);
109 volumebar_class->size_request = hildon_hvolumebar_size_request;
110 volumebar_class->size_allocate = hildon_hvolumebar_size_allocate;
111 volumebar_class->map = hildon_hvolumebar_map;
112 volumebar_class->expose_event = hildon_hvolumebar_expose;
116 static void hildon_hvolumebar_init(HildonHVolumebar * hvolumebar)
118 HildonVolumebarPrivate *priv;
120 priv = HILDON_VOLUMEBAR_GET_PRIVATE(hvolumebar);
123 HILDON_VOLUMEBAR_RANGE(hildon_volumebar_range_new
124 (GTK_ORIENTATION_HORIZONTAL));
126 GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(hvolumebar), GTK_CAN_FOCUS);
128 gtk_widget_set_parent(GTK_WIDGET(priv->tbutton), GTK_WIDGET(hvolumebar));
129 gtk_widget_set_parent(GTK_WIDGET(priv->volumebar), GTK_WIDGET(hvolumebar));
131 gtk_scale_set_draw_value(GTK_SCALE(priv->volumebar), FALSE);
134 g_signal_connect_swapped(G_OBJECT(priv->volumebar), "value-changed",
135 G_CALLBACK(hildon_volumebar_level_change),
137 g_signal_connect_swapped(priv->tbutton, "toggled",
138 G_CALLBACK(_hildon_volumebar_mute_toggled), hvolumebar);
140 gtk_widget_show(GTK_WIDGET(priv->volumebar));
144 * hildon_hvolumebar_new:
146 * Creates a new #HildonHVolumebar widget.
148 * Returns: a new #HildonHVolumebar
150 GtkWidget *hildon_hvolumebar_new(void)
152 return GTK_WIDGET(g_object_new(HILDON_TYPE_HVOLUMEBAR, NULL));
155 static void hildon_hvolumebar_map(GtkWidget * widget)
157 HildonVolumebarPrivate *priv;
160 g_assert(HILDON_IS_HVOLUMEBAR(widget));
162 priv = HILDON_VOLUMEBAR_GET_PRIVATE(widget);
163 parent = gtk_widget_get_ancestor(GTK_WIDGET(widget), GTK_TYPE_TOOLBAR);
165 /* Check if the volumebar is in a toolbar */
167 priv->is_toolbar = TRUE;
169 GTK_WIDGET_CLASS(parent_class)->map(widget);
172 static gboolean hildon_hvolumebar_expose(GtkWidget * widget,
173 GdkEventExpose * event)
175 HildonVolumebarPrivate *priv;
177 g_assert(HILDON_IS_HVOLUMEBAR(widget));
179 priv = HILDON_VOLUMEBAR_GET_PRIVATE(HILDON_VOLUMEBAR(widget));
181 if (GTK_WIDGET_DRAWABLE(widget)) {
182 /* Paint background */
183 gtk_paint_box(widget->style, widget->window,
184 GTK_WIDGET_STATE(priv->volumebar), GTK_SHADOW_OUT,
185 NULL, widget, "background",
186 widget->allocation.x,
187 widget->allocation.y,
188 widget->allocation.width,
189 widget->allocation.height);
191 /* The contents of the widget can paint themselves */
192 (*GTK_WIDGET_CLASS(parent_class)->expose_event) (widget, event);
199 hildon_hvolumebar_size_request(GtkWidget * widget,
200 GtkRequisition * requisition)
202 HildonVolumebarPrivate *priv;
204 g_assert(HILDON_IS_HVOLUMEBAR(widget));
206 priv = HILDON_VOLUMEBAR_GET_PRIVATE(HILDON_VOLUMEBAR(widget));
208 /* Volumebar has different dimensions in toolbar */
209 requisition->width = (priv->is_toolbar
210 ? TOOL_MINIMUM_BAR_WIDTH
211 : MINIMUM_BAR_WIDTH);
212 requisition->height = (priv->is_toolbar
213 ? TOOL_DEFAULT_BAR_HEIGHT
214 : DEFAULT_BAR_HEIGHT);
218 hildon_hvolumebar_size_allocate(GtkWidget * widget,
219 GtkAllocation * allocation)
221 HildonVolumebarPrivate *priv;
222 GtkAllocation button_allocation, range_allocation;
224 g_assert(HILDON_IS_HVOLUMEBAR(widget));
226 priv = HILDON_VOLUMEBAR_GET_PRIVATE(widget);
228 button_allocation.x = 0;
229 button_allocation.width = 0;
231 /* Center the widget vertically */
232 if (priv->is_toolbar && allocation->height > TOOL_DEFAULT_BAR_HEIGHT) {
233 allocation->y += (allocation->height - TOOL_DEFAULT_BAR_HEIGHT) / 2;
234 allocation->height = TOOL_DEFAULT_BAR_HEIGHT;
236 if (!priv->is_toolbar && allocation->height > DEFAULT_BAR_HEIGHT) {
237 allocation->y += (allocation->height - DEFAULT_BAR_HEIGHT) / 2;
238 allocation->height = DEFAULT_BAR_HEIGHT;
241 widget->allocation = *allocation;
243 if (priv->tbutton && GTK_WIDGET_VISIBLE(priv->tbutton)) {
245 /* Allocate space for the mute button */
246 if (priv->is_toolbar) {
247 button_allocation.x = allocation->x;
248 button_allocation.y = allocation->y + TOOL_VERTICAL_MUTE_GAP;
249 button_allocation.width = TOOL_DEFAULT_TBUTTON_WIDTH;
250 button_allocation.height = TOOL_DEFAULT_TBUTTON_HEIGHT;
252 button_allocation.x = allocation->x + DEFAULT_ENDING_SIZE;
253 button_allocation.y = allocation->y + VERTICAL_MUTE_GAP;
254 button_allocation.width = DEFAULT_TBUTTON_WIDTH;
255 button_allocation.height = DEFAULT_TBUTTON_HEIGHT;
257 gtk_widget_size_allocate(GTK_WIDGET(priv->tbutton),
260 if (priv->volumebar && GTK_WIDGET_VISIBLE(priv->volumebar)) {
262 /* Allocate space for the slider */
263 range_allocation.y = allocation->y;
265 if (priv->tbutton && GTK_WIDGET_VISIBLE(priv->tbutton))
267 /* Leave room for the mute button */
268 range_allocation.x = button_allocation.x
269 + button_allocation.width
270 + HORIZONTAL_MUTE_GAP;
272 if (priv->is_toolbar)
274 /* In toolbar with mute button */
275 range_allocation.width = MAX(0,
277 - 2 * TOOL_DEFAULT_ENDING_SIZE
278 - TOOL_DEFAULT_TBUTTON_WIDTH
279 - HORIZONTAL_MUTE_GAP);
281 range_allocation.height = TOOL_DEFAULT_BAR_HEIGHT;
287 /* Standalone with mute button */
288 range_allocation.width = MAX(0,
290 - 2 * DEFAULT_ENDING_SIZE
291 - DEFAULT_TBUTTON_WIDTH
292 - HORIZONTAL_MUTE_GAP);
294 range_allocation.height = DEFAULT_BAR_HEIGHT;
301 if (priv->is_toolbar)
303 /* In toolbar without mute button */
304 range_allocation.x = allocation->x;
306 range_allocation.width = MAX(0,
308 - 2 * TOOL_DEFAULT_ENDING_SIZE );
310 range_allocation.height = TOOL_DEFAULT_BAR_HEIGHT;
316 /* Standalone without mute button */
317 range_allocation.x = allocation->x + DEFAULT_ENDING_SIZE;
319 range_allocation.width = MAX(0,
321 - 2 * DEFAULT_ENDING_SIZE );
323 range_allocation.height = DEFAULT_BAR_HEIGHT;
327 gtk_widget_size_allocate(GTK_WIDGET(priv->volumebar),