2008-07-29 Claudio Saavedra <csaavedra@igalia.com>
[hildon] / src / hildon-button.c
1 /*
2  * This file is a part of hildon
3  *
4  * Copyright (C) 2008 Nokia Corporation, all rights reserved.
5  *
6  * Contact: Karl Lattimer <karl.lattimer@nokia.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser Public License as published by
10  * the Free Software Foundation; version 2 of the license.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Lesser Public License for more details.
16  *
17  */
18
19 /**
20  * SECTION:hildon-button
21  * @short_description: Widget representing a button in the Hildon framework.
22  *
23  * The HildonButton is a GTK widget which represent a clickable
24  * button. It is derived from the GtkButton widget and provides
25  * additional commodities specific to the Hildon framework.
26  */
27
28 #include                                        "hildon-button.h"
29
30 #define FINGER_BUTTON_HEIGHT                    70
31 #define THUMB_BUTTON_HEIGHT                     105
32 #define HALFSCREEN_BUTTON_WIDTH                 400
33 #define FULLSCREEN_BUTTON_WIDTH                 800
34
35 G_DEFINE_TYPE                                   (HildonButton, hildon_button, GTK_TYPE_BUTTON);
36
37 #define                                         HILDON_BUTTON_GET_PRIVATE(obj) \
38                                                 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
39                                                 HILDON_TYPE_BUTTON, HildonButtonPrivate));
40
41 typedef struct                                  _HildonButtonPrivate HildonButtonPrivate;
42
43 struct                                          _HildonButtonPrivate
44 {
45     GtkLabel *title;
46     GtkLabel *value;
47 };
48
49 enum {
50   PROP_TITLE = 1,
51   PROP_VALUE,
52   PROP_ARRANGEMENT_FLAGS
53 };
54
55 static void hildon_button_set_arrangement (HildonButton *button, HildonButtonFlags flags);
56
57 static void
58 hildon_button_set_property                      (GObject      *object,
59                                                  guint         prop_id,
60                                                  const GValue *value,
61                                                  GParamSpec   *pspec)
62 {
63     HildonButton *button = HILDON_BUTTON (object);
64
65     switch (prop_id)
66     {
67     case PROP_TITLE:
68         hildon_button_set_title (button, g_value_get_string (value));
69         break;
70     case PROP_VALUE:
71         hildon_button_set_value (button, g_value_get_string (value));
72         break;
73     case PROP_ARRANGEMENT_FLAGS:
74         hildon_button_set_arrangement (button, g_value_get_int (value));
75         break;
76     default:
77         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
78         break;
79     }
80 }
81
82 static void
83 hildon_button_get_property                      (GObject    *object,
84                                                  guint       prop_id,
85                                                  GValue     *value,
86                                                  GParamSpec *pspec)
87 {
88     HildonButton *button = HILDON_BUTTON (object);
89     HildonButtonPrivate *priv = HILDON_BUTTON_GET_PRIVATE (button);
90
91     switch (prop_id)
92     {
93     case PROP_TITLE:
94         g_value_set_string (value, gtk_label_get_text (priv->title));
95         break;
96     case PROP_VALUE:
97         g_value_set_string (value, gtk_label_get_text (priv->value));
98         break;
99     default:
100         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
101         break;
102     }
103 }
104
105 static void
106 hildon_button_class_init                        (HildonButtonClass *klass)
107 {
108     GObjectClass *gobject_class = (GObjectClass *)klass;
109     GtkWidgetClass *widget_class = (GtkWidgetClass *)klass;
110
111     gobject_class->set_property = hildon_button_set_property;
112     gobject_class->get_property = hildon_button_get_property;
113
114     g_object_class_install_property (
115         gobject_class,
116         PROP_TITLE,
117         g_param_spec_string (
118             "title",
119             "Title",
120             "Text of the title label inside the button",
121             NULL,
122             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
123
124     g_object_class_install_property (
125         gobject_class,
126         PROP_VALUE,
127         g_param_spec_string (
128             "value",
129             "Value",
130             "Text of the value label inside the button",
131             NULL,
132             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
133
134     g_object_class_install_property (
135             gobject_class,
136             PROP_ARRANGEMENT_FLAGS,
137             g_param_spec_int ("arrangement-flags",
138                               "Arrangement flags",
139                               "How the button contents must be arranged",
140                               0, 64,
141                               HILDON_BUTTON_WITH_HORIZONTAL_VALUE,
142                               G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
143
144     gtk_widget_class_install_style_property (
145         widget_class,
146         g_param_spec_uint (
147             "horizontal-spacing",
148             "Horizontal spacing between labels",
149             "Horizontal spacing between the title and value labels, when in horizontal mode",
150             0, G_MAXUINT, 25,
151             G_PARAM_READABLE));
152
153     gtk_widget_class_install_style_property (
154         widget_class,
155         g_param_spec_uint (
156             "vertical-spacing",
157             "Vertical spacing between labels",
158             "Vertical spacing between the title and value labels, when in vertical mode",
159             0, G_MAXUINT, 5,
160             G_PARAM_READABLE));
161
162     g_type_class_add_private (klass, sizeof (HildonButtonPrivate));
163 }
164
165 static void
166 hildon_button_init                              (HildonButton *self)
167 {
168     HildonButtonPrivate *priv = HILDON_BUTTON_GET_PRIVATE (self);
169
170     priv->title = GTK_LABEL (gtk_label_new (NULL));
171     priv->value = GTK_LABEL (gtk_label_new (NULL));
172
173     gtk_widget_set_name (GTK_WIDGET (priv->title), "hildon-button-title");
174     gtk_widget_set_name (GTK_WIDGET (priv->value), "hildon-button-value");
175
176     gtk_misc_set_alignment (GTK_MISC (priv->title), 0, 0.5);
177     gtk_misc_set_alignment (GTK_MISC (priv->value), 0, 0.5);
178 }
179
180 void
181 hildon_button_set_size_groups                   (HildonButton *button,
182                                                  GtkSizeGroup *title_size_group,
183                                                  GtkSizeGroup *value_size_group)
184 {
185     HildonButtonPrivate *priv;
186
187     g_return_if_fail (HILDON_IS_BUTTON (button));
188
189     priv = HILDON_BUTTON_GET_PRIVATE (button);
190
191     if (title_size_group)
192         gtk_size_group_add_widget (title_size_group, GTK_WIDGET (priv->title));
193
194     if (value_size_group)
195         gtk_size_group_add_widget (value_size_group, GTK_WIDGET (priv->value));
196 }
197
198 GtkWidget *
199 hildon_button_new                               (HildonButtonFlags  flags,
200                                                  const char        *title,
201                                                  const char        *value)
202 {
203     return hildon_button_new_full (flags, title, value, NULL, NULL);
204 }
205
206 GtkWidget *
207 hildon_button_new_full                          (HildonButtonFlags  flags,
208                                                  const char        *title,
209                                                  const char        *value,
210                                                  GtkSizeGroup      *title_size_group,
211                                                  GtkSizeGroup      *value_size_group)
212 {
213     GtkWidget *button;
214
215     /* Create widget */
216     button = g_object_new (HILDON_TYPE_BUTTON,
217                            "arrangement-flags", flags,
218                            "title", title,
219                            "value", value,
220                            "name", "hildon-button",
221                            NULL);
222     /* Set size groups */
223     if (title_size_group || value_size_group)
224         hildon_button_set_size_groups (HILDON_BUTTON (button), title_size_group, value_size_group);
225
226     return button;
227 }
228
229 static void
230 hildon_button_set_arrangement (HildonButton *button,
231                                HildonButtonFlags flags)
232 {
233     GtkWidget *box;
234     GtkWidget *alignment;
235     HildonButtonPrivate *priv;
236     guint horizontal_spacing;
237     guint vertical_spacing;
238     gint width = -1;
239     gint height = -1;
240     const char *widget_name = NULL;
241
242     priv = HILDON_BUTTON_GET_PRIVATE (button);
243
244     /* Requested height */
245     if (flags & HILDON_BUTTON_FINGER_HEIGHT) {
246         height = FINGER_BUTTON_HEIGHT;
247         widget_name = "hildon-finger-button";
248     } else if (flags & HILDON_BUTTON_THUMB_HEIGHT) {
249         height = THUMB_BUTTON_HEIGHT;
250         widget_name = "hildon-thumb-button";
251     }
252
253     if (widget_name) {
254         gtk_widget_set_name (GTK_WIDGET (button), widget_name);
255     }
256
257     /* Requested width */
258     if (flags & HILDON_BUTTON_HALFSCREEN_WIDTH) {
259         width = HALFSCREEN_BUTTON_WIDTH;
260     } else if (flags & HILDON_BUTTON_FULLSCREEN_WIDTH) {
261         width = FULLSCREEN_BUTTON_WIDTH;
262     }
263
264     g_object_set (button,
265                   "width-request", width,
266                   "height-request", height,
267                   NULL);
268
269     /* Pack everything */
270     gtk_widget_style_get (GTK_WIDGET (button),
271                           "horizontal-spacing", &horizontal_spacing,
272                           "vertical-spacing", &vertical_spacing,
273                           NULL);
274
275     if (flags & HILDON_BUTTON_WITH_VERTICAL_VALUE) {
276         box = gtk_vbox_new (FALSE, vertical_spacing);
277     } else {
278         box = gtk_hbox_new (FALSE, horizontal_spacing);
279     }
280
281     alignment = gtk_alignment_new (0.5, 0.5, 0, 0);
282
283     gtk_box_pack_start (GTK_BOX (box), GTK_WIDGET (priv->title), TRUE, TRUE, 0);
284     gtk_box_pack_start (GTK_BOX (box), GTK_WIDGET (priv->value), TRUE, TRUE, 0);
285
286     gtk_container_add (GTK_CONTAINER (alignment), box);
287     gtk_container_add (GTK_CONTAINER (button), alignment);
288
289     gtk_widget_show_all (alignment);
290 }
291
292 void
293 hildon_button_set_title                         (HildonButton *button,
294                                                  const char   *title)
295 {
296     HildonButtonPrivate *priv;
297
298     g_return_if_fail (HILDON_IS_BUTTON (button));
299
300     priv = HILDON_BUTTON_GET_PRIVATE (button);
301     gtk_label_set_text (priv->title, title);
302
303     g_object_notify (G_OBJECT (button), "title");
304 }
305
306 void
307 hildon_button_set_value                         (HildonButton *button,
308                                                  const char   *value)
309 {
310     HildonButtonPrivate *priv;
311
312     g_return_if_fail (HILDON_IS_BUTTON (button));
313
314     priv = HILDON_BUTTON_GET_PRIVATE (button);
315     gtk_label_set_text (priv->value, value);
316
317     g_object_notify (G_OBJECT (button), "value");
318 }
319
320 const char *
321 hildon_button_get_title                         (HildonButton *button)
322 {
323     HildonButtonPrivate *priv;
324
325     g_return_val_if_fail (HILDON_IS_BUTTON (button), NULL);
326
327     priv = HILDON_BUTTON_GET_PRIVATE (button);
328
329     return gtk_label_get_text (priv->title);
330 }
331
332 const char *
333 hildon_button_get_value                         (HildonButton *button)
334 {
335     HildonButtonPrivate *priv;
336
337     g_return_val_if_fail (HILDON_IS_BUTTON (button), NULL);
338
339     priv = HILDON_BUTTON_GET_PRIVATE (button);
340
341     return gtk_label_get_text (priv->value);
342 }
343
344 void
345 hildon_button_set_title_and_value               (HildonButton *button,
346                                                  const char   *title,
347                                                  const char   *value)
348 {
349     hildon_button_set_title (button, title);
350     hildon_button_set_value (button, value);
351 }