import SDK release
[hildon] / hildon-widgets / hildon-vvolumebar.c
1 /*
2  * This file is part of hildon-libs
3  *
4  * Copyright (C) 2005 Nokia Corporation.
5  *
6  * Contact: Luc Pionchon <luc.pionchon@nokia.com>
7  *
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.
12  *
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.
17  *
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
21  * 02110-1301 USA
22  *
23  */
24
25 /**
26  * @file hildon-vvolumebar.c
27  *
28  * This file contains the implementation of HildonVVolumebar.
29  * This widget is a subclass of HildonVolumebar and implements
30  * horizontal version of Volumebar.
31  */
32
33 #ifdef HAVE_CONFIG_H
34 #include <config.h>
35 #endif
36
37 #include <gtk/gtk.h>
38 #include "hildon-vvolumebar.h"
39 #include "hildon-volumebar.h"
40 #include "hildon-volumebar-range.h"
41 #include "hildon-volumebar-private.h"
42
43 #define DEFAULT_BAR_WIDTH               58
44 #define MINIMUM_BAR_HEIGHT             165
45 #define DEFAULT_VERTICAL_TBUTTON_WIDTH  26
46 #define DEFAULT_VERTICAL_TBUTTON_HEIGHT 26
47 #define DEFAULT_ENDING_SIZE             20
48 #define HORIZONTAL_MUTE_GAP             16
49 #define VERTICAL_MUTE_GAP                6
50
51 static HildonVolumebarClass *parent_class;
52 static void vvolumebar_class_init(HildonVVolumebarClass * klass);
53 static void vvolumebar_init(HildonVVolumebar * vvolumebar);
54 static void hildon_vvolumebar_mute(GtkWidget * widget,
55                                    HildonVVolumebar * self);
56 static gboolean hildon_vvolumebar_expose(GtkWidget * widget,
57                                          GdkEventExpose * event);
58 static void hildon_vvolumebar_size_request(GtkWidget * widget,
59                                            GtkRequisition * requisition);
60 static void hildon_vvolumebar_size_allocate(GtkWidget * widget,
61                                             GtkAllocation * allocation);
62
63 GType hildon_vvolumebar_get_type(void)
64 {
65     static GType type = 0;
66
67     if (!type) {
68         static const GTypeInfo info = {
69             sizeof(HildonVVolumebarClass),
70             NULL,       /* base_init */
71             NULL,       /* base_finalize */
72             (GClassInitFunc) vvolumebar_class_init,     /* class_init */
73             NULL,       /* class_finalize */
74             NULL,       /* class_data */
75             sizeof(HildonVVolumebar),
76             0,
77             (GInstanceInitFunc) vvolumebar_init,
78         };
79         type =
80             g_type_register_static(HILDON_TYPE_VOLUMEBAR,
81                                    "HildonVVolumebar", &info, 0);
82     }
83     return type;
84 }
85
86 static void vvolumebar_class_init(HildonVVolumebarClass * klass)
87 {
88     GtkWidgetClass *volumebar_class = GTK_WIDGET_CLASS(klass);
89
90     parent_class = g_type_class_peek_parent(klass);
91
92     volumebar_class->size_request = hildon_vvolumebar_size_request;
93     volumebar_class->size_allocate = hildon_vvolumebar_size_allocate;
94     volumebar_class->expose_event = hildon_vvolumebar_expose;
95 }
96
97 static void vvolumebar_init(HildonVVolumebar * vvolumebar)
98 {
99     HildonVolumebar *v_ptr = HILDON_VOLUMEBAR(vvolumebar);
100     HildonVolumebarPrivate *priv;
101
102     priv = HILDON_VOLUMEBAR_GET_PRIVATE(vvolumebar);
103
104     priv->ownorientation = GTK_ORIENTATION_VERTICAL;
105     priv->orientation = GTK_ORIENTATION_VERTICAL;
106
107     priv->volumebar =
108         HILDON_VOLUMEBAR_RANGE(hildon_volumebar_range_new
109                                (GTK_ORIENTATION_VERTICAL));
110
111     GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(vvolumebar), GTK_CAN_FOCUS);
112
113     gtk_widget_set_parent(GTK_WIDGET(priv->tbutton), GTK_WIDGET(v_ptr));
114     gtk_widget_set_parent(GTK_WIDGET(priv->volumebar), GTK_WIDGET(v_ptr));
115
116     gtk_scale_set_draw_value(GTK_SCALE(priv->volumebar), FALSE);
117
118     /* Signals */
119     g_signal_connect_swapped(G_OBJECT(priv->volumebar), "value-changed",
120                              G_CALLBACK(hildon_volumebar_level_change),
121                              vvolumebar);
122     g_signal_connect(G_OBJECT(priv->tbutton), "toggled",
123                      G_CALLBACK(hildon_vvolumebar_mute), vvolumebar);
124     /* end here */
125
126     gtk_widget_show(GTK_WIDGET(priv->volumebar));
127 }
128
129 /**
130  * hildon_vvolumebar_new:
131  *
132  * Creates a new #HildonVVolumebar widget.
133  *
134  * Returns: a new #HildonVVolumebar.
135  */
136 GtkWidget *hildon_vvolumebar_new()
137 {
138     return GTK_WIDGET(g_object_new(HILDON_TYPE_VVOLUMEBAR, NULL));
139 }
140
141 static gboolean hildon_vvolumebar_expose(GtkWidget * widget,
142                                          GdkEventExpose * event)
143 {
144     if (GTK_WIDGET_DRAWABLE(widget)) {
145         gtk_paint_box(widget->style, widget->window,
146                       GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
147                       NULL, widget, "background",
148                       widget->allocation.x,
149                       widget->allocation.y,
150                       widget->allocation.width,
151                       widget->allocation.height);
152
153         (*GTK_WIDGET_CLASS(parent_class)->expose_event) (widget, event);
154     }
155
156     return FALSE;
157 }
158
159 static void
160 hildon_vvolumebar_size_request(GtkWidget * widget,
161                                GtkRequisition * requisition)
162 {
163     requisition->height = MINIMUM_BAR_HEIGHT;
164     requisition->width = DEFAULT_BAR_WIDTH;
165 }
166
167 static void
168 hildon_vvolumebar_size_allocate(GtkWidget * widget,
169                                 GtkAllocation * allocation)
170 {
171     HildonVolumebar *vbar;
172     HildonVolumebarPrivate *priv;
173
174     GtkAllocation range_allocation, button_allocation;
175
176     vbar = HILDON_VOLUMEBAR(widget);
177     priv = HILDON_VOLUMEBAR_GET_PRIVATE(vbar);
178
179     if (allocation->width > DEFAULT_BAR_WIDTH) {
180         allocation->x +=
181           (allocation->width - DEFAULT_BAR_WIDTH) / 2;
182         allocation->width = DEFAULT_BAR_WIDTH;
183     }
184
185     widget->allocation = *allocation;
186
187     if (priv->volumebar && GTK_WIDGET_VISIBLE(priv->volumebar)) {
188         range_allocation.x = allocation->x;
189         range_allocation.y = allocation->y + DEFAULT_ENDING_SIZE;
190
191         range_allocation.width = DEFAULT_BAR_WIDTH;
192         
193         if (priv->tbutton && GTK_WIDGET_VISIBLE(priv->tbutton))
194         {
195             range_allocation.height = MAX(0,
196                                           allocation->height
197                                           - 2 * DEFAULT_ENDING_SIZE
198                                           - DEFAULT_VERTICAL_TBUTTON_HEIGHT
199                                           - VERTICAL_MUTE_GAP);
200         }
201         
202         else
203         {
204             range_allocation.height = MAX(0,
205                                           allocation->height
206                                           - 2 * DEFAULT_ENDING_SIZE);
207         }
208         
209         gtk_widget_size_allocate(GTK_WIDGET(priv->volumebar),
210                                  &range_allocation);
211     }
212     
213     if (priv->tbutton && GTK_WIDGET_VISIBLE(priv->tbutton)) {
214         button_allocation.x = allocation->x + HORIZONTAL_MUTE_GAP;
215         button_allocation.y = allocation->y + allocation->height -
216                               VERTICAL_MUTE_GAP - 2 * DEFAULT_ENDING_SIZE;
217         button_allocation.width = DEFAULT_VERTICAL_TBUTTON_WIDTH;
218         button_allocation.height = DEFAULT_VERTICAL_TBUTTON_HEIGHT;
219         gtk_widget_size_allocate(GTK_WIDGET(priv->tbutton),
220                                  &button_allocation);
221     }
222 }
223
224 static void
225 hildon_vvolumebar_mute(GtkWidget * widget, HildonVVolumebar * self)
226 {
227     g_signal_emit_by_name(GTK_WIDGET(self), "mute_toggled");
228 }