2008-09-24 Claudio Saavedra <csaavedra@igalia.com>
[hildon] / src / hildon-gtk.c
1 /*
2  * This file is a part of hildon
3  *
4  * Copyright (C) 2008 Nokia Corporation, all rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser Public License as published by
8  * the Free Software Foundation; version 2 of the license.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser Public License for more details.
14  *
15  */
16
17 /**
18  * SECTION:hildon-gtk
19  * @short_description: Additional functions for Gtk widgets
20  * @see_also: #HildonButton
21  *
22  * Hildon provides some functions to extend the functionality of
23  * existing Gtk widgets. This also includes convenience functions to
24  * easily perform frequent tasks.
25  */
26
27 #include <X11/Xatom.h>
28 #include <gdk/gdkx.h>
29
30 #include "hildon-gtk.h"
31
32 #define                                         HILDON_HEIGHT_FINGER 70
33
34 #define                                         HILDON_HEIGHT_THUMB 105
35
36 #define                                         HILDON_WIDTH_FULLSCREEN \
37                                                 (gdk_screen_get_width (gdk_screen_get_default ()))
38
39 #define                                         HILDON_WIDTH_HALFSCREEN \
40                                                 (HILDON_WIDTH_FULLSCREEN / 2)
41
42 /**
43  * hildon_gtk_widget_set_theme_size:
44  * @widget: A #GtkWidget
45  * @size: Flags indicating the size of the widget
46  *
47  * This function sets the requested size of a widget.
48  **/
49 void
50 hildon_gtk_widget_set_theme_size                (GtkWidget      *widget,
51                                                  HildonSizeType  size)
52 {
53     gint width = -1;
54     gint height = -1;
55     const gchar *widget_name = NULL;
56
57     g_return_if_fail (GTK_IS_WIDGET (widget));
58
59     /* Requested height */
60     if (size & HILDON_SIZE_FINGER_HEIGHT) {
61         height = HILDON_HEIGHT_FINGER;
62         widget_name = "hildon-finger-widget";
63     } else if (size & HILDON_SIZE_THUMB_HEIGHT) {
64         height = HILDON_HEIGHT_THUMB;
65         widget_name = "hildon-thumb-widget";
66     }
67
68     /* Requested width */
69     if (size & HILDON_SIZE_HALFSCREEN_WIDTH) {
70         width = HILDON_WIDTH_HALFSCREEN;
71     } else if (size & HILDON_SIZE_FULLSCREEN_WIDTH) {
72         width = HILDON_WIDTH_FULLSCREEN;
73     }
74
75     gtk_widget_set_size_request (widget, width, height);
76
77     if (widget_name)
78         gtk_widget_set_name (widget, widget_name);
79 }
80
81 static void
82 image_visible_changed_cb                        (GtkWidget  *image,
83                                                  GParamSpec *arg1,
84                                                  gpointer   oldparent)
85 {
86     if (!GTK_WIDGET_VISIBLE (image))
87         gtk_widget_show (image);
88 }
89
90 static void
91 parent_changed_cb                               (GtkWidget  *image,
92                                                  GParamSpec *arg1,
93                                                  gpointer   oldparent)
94 {
95     /* If the parent has really changed, remove the old signal handlers */
96     if (image->parent != oldparent) {
97         g_signal_handlers_disconnect_by_func (image, parent_changed_cb, oldparent);
98         g_signal_handlers_disconnect_by_func (image, image_visible_changed_cb, NULL);
99     }
100 }
101
102 static void
103 image_changed_cb                                (GtkButton  *button,
104                                                  GParamSpec *arg1,
105                                                  gpointer    user_data)
106 {
107     GtkWidget *image = gtk_button_get_image (button);
108
109     g_return_if_fail (image == NULL || GTK_IS_WIDGET (image));
110
111     if (image != NULL) {
112         /* If the button has a new image, show it */
113         gtk_widget_show (image);
114         /* Show the image no matter the value of gtk-button-images */
115         g_signal_connect (image, "notify::visible", G_CALLBACK (image_visible_changed_cb), NULL);
116         /* If the image is removed from the button, disconnect these handlers */
117         g_signal_connect (image, "notify::parent", G_CALLBACK (parent_changed_cb), image->parent);
118     }
119 }
120
121 static void
122 button_common_init                              (GtkWidget      *button,
123                                                  HildonSizeType  size)
124 {
125     /* Set requested size */
126     hildon_gtk_widget_set_theme_size (button, size);
127
128     /* Make sure that all images in this button are always shown */
129     g_signal_connect (button, "notify::image", G_CALLBACK (image_changed_cb), NULL);
130 }
131
132 /**
133  * hildon_gtk_button_new:
134  * @size: Flags indicating the size of the new button
135  *
136  * This is a convenience function to create a #GtkButton setting its
137  * size to one of the pre-defined Hildon sizes.
138  *
139  * Buttons created with this function also override the
140  * "gtk-button-images" setting. Images set using
141  * gtk_button_set_image() are always shown.
142  *
143  * Return value: A newly created #GtkButton widget.
144  **/
145 GtkWidget *
146 hildon_gtk_button_new                           (HildonSizeType size)
147 {
148     GtkWidget *button = gtk_button_new ();
149     button_common_init (button, size);
150     return button;
151 }
152
153 /**
154  * hildon_gtk_toggle_button_new:
155  * @size: Flags indicating the size of the new button
156  *
157  * This is a convenience function to create a #GtkToggleButton setting
158  * its size to one of the pre-defined Hildon sizes.
159  *
160  * Buttons created with this function also override the
161  * "gtk-button-images" setting. Images set using
162  * gtk_button_set_image() are always shown.
163  *
164  * Return value: A newly created #GtkToggleButton widget.
165  **/
166 GtkWidget *
167 hildon_gtk_toggle_button_new                    (HildonSizeType size)
168 {
169     GtkWidget *button = gtk_toggle_button_new ();
170     button_common_init (button, size);
171     return button;
172 }
173
174 /**
175  * hildon_gtk_radio_button_new:
176  * @size: Flags indicating the size of the new button
177  * @group: An existing radio button group, or %NULL if you are
178  * creating a new group
179  *
180  * This is a convenience function to create a #GtkRadioButton setting
181  * its size to one of the pre-defined Hildon sizes.
182  *
183  * Buttons created with this function also override the
184  * "gtk-button-images" setting. Images set using
185  * gtk_button_set_image() are always shown.
186  *
187  * Return value: A newly created #GtkRadioButton widget.
188  **/
189 GtkWidget *
190 hildon_gtk_radio_button_new                     (HildonSizeType  size,
191                                                  GSList         *group)
192 {
193     GtkWidget *button = gtk_radio_button_new (group);
194     button_common_init (button, size);
195     return button;
196 }
197
198 /**
199  * hildon_gtk_radio_button_new_from_widget:
200  * @size: Flags indicating the size of the new button
201  * @radio_group_member: widget to get radio group from or %NULL
202  *
203  * This is a convenience function to create a #GtkRadioButton setting
204  * its size to one of the pre-defined Hildon sizes.
205  *
206  * Buttons created with this function also override the
207  * "gtk-button-images" setting. Images set using
208  * gtk_button_set_image() are always shown.
209  *
210  * Return value: A newly created #GtkRadioButton widget.
211  **/
212 GtkWidget *
213 hildon_gtk_radio_button_new_from_widget         (HildonSizeType  size,
214                                                  GtkRadioButton *radio_group_member)
215 {
216     GtkWidget *button = gtk_radio_button_new_from_widget (radio_group_member);
217     button_common_init (button, size);
218     return button;
219 }
220
221 /**
222  * hildon_gtk_tree_view_new:
223  * @mode: the Hildon UI mode
224  *
225  * Creates a new #GtkTreeView widget with the Hildon UI mode set to
226  * @mode
227  *
228  * Return value: A newly created #GtkTreeView widget.
229  **/
230 GtkWidget *
231 hildon_gtk_tree_view_new                        (HildonUIMode mode)
232 {
233     return g_object_new (GTK_TYPE_TREE_VIEW, "hildon-ui-mode", mode, NULL);
234 }
235
236 /**
237  * hildon_gtk_tree_view_new_with_model:
238  * @mode: the Hildon UI mode
239  * @model: the model.
240  *
241  * Creates a new #GtkTreeView widget with the Hildon UI mode set to
242  * @mode and the model initialized to @model.
243  *
244  * Return value: A newly created #GtkTreeView widget.
245  **/
246 GtkWidget *
247 hildon_gtk_tree_view_new_with_model             (HildonUIMode  mode,
248                                                  GtkTreeModel *model)
249 {
250     return g_object_new (GTK_TYPE_TREE_VIEW, "hildon-ui-mode", mode, "model", model, NULL);
251 }
252
253 /**
254  * hildon_gtk_icon_view_new:
255  * @mode: the Hildon UI mode
256  *
257  * Creates a new #GtkIconView widget with the Hildon UI mode set to
258  * @mode
259  *
260  * Return value: A newly created #GtkIconView widget
261  **/
262 GtkWidget *
263 hildon_gtk_icon_view_new                        (HildonUIMode mode)
264 {
265     return g_object_new (GTK_TYPE_ICON_VIEW, "hildon-ui-mode", mode, NULL);
266 }
267
268 /**
269  * hildon_gtk_icon_view_new_with_model:
270  * @mode: the Hildon UI mode
271  * @model: The model.
272  *
273  * Creates a new #GtkIconView widget with the Hildon UI mode set to
274  * @mode and the model intitialized to @model.
275  *
276  * Return value: A newly created #GtkIconView widget.
277  **/
278 GtkWidget *
279 hildon_gtk_icon_view_new_with_model             (HildonUIMode  mode,
280                                                  GtkTreeModel *model)
281 {
282     return g_object_new (GTK_TYPE_ICON_VIEW, "hildon-ui-mode", mode, "model", model, NULL);
283 }
284
285 /**
286  * hildon_gtk_window_set_progress_indicator:
287  * @window: The window, we want to define its state
288  * @state: The state we want to set: 1 -> show progress indicator, 0
289  *          -> hide progress indicator.
290  *
291  * This functions notifies the window manager that it should add a
292  * progress indicator in the title of the window. It applies to
293  * #HildonDialog and #HildonWindow.
294  *
295  **/
296 void
297 hildon_gtk_window_set_progress_indicator        (GtkWindow    *window,
298                                                  guint        state)
299 {
300   GtkWidget *widget = GTK_WIDGET (window);
301   GdkDisplay *display;
302   Atom atom;
303
304   display = gdk_drawable_get_display (widget->window);
305   atom = gdk_x11_get_xatom_by_name_for_display (display, "_HILDON_WM_WINDOW_PROGRESS_INDICATOR");
306
307   XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (widget->window),
308                    atom, XA_INTEGER, 32, PropModeReplace,
309                    (guchar *)&state, 1);
310 }