2008-12-09 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 static void
33 image_visible_changed_cb                        (GtkWidget  *image,
34                                                  GParamSpec *arg1,
35                                                  gpointer   oldparent)
36 {
37     if (!GTK_WIDGET_VISIBLE (image))
38         gtk_widget_show (image);
39 }
40
41 static void
42 parent_changed_cb                               (GtkWidget  *image,
43                                                  GParamSpec *arg1,
44                                                  gpointer   oldparent)
45 {
46     /* If the parent has really changed, remove the old signal handlers */
47     if (image->parent != oldparent) {
48         g_signal_handlers_disconnect_by_func (image, parent_changed_cb, oldparent);
49         g_signal_handlers_disconnect_by_func (image, image_visible_changed_cb, NULL);
50     }
51 }
52
53 static void
54 image_changed_cb                                (GtkButton  *button,
55                                                  GParamSpec *arg1,
56                                                  gpointer    user_data)
57 {
58     GtkWidget *image = gtk_button_get_image (button);
59
60     g_return_if_fail (image == NULL || GTK_IS_WIDGET (image));
61
62     if (image != NULL) {
63         /* If the button has a new image, show it */
64         gtk_widget_show (image);
65         /* Show the image no matter the value of gtk-button-images */
66         g_signal_connect (image, "notify::visible", G_CALLBACK (image_visible_changed_cb), NULL);
67         /* If the image is removed from the button, disconnect these handlers */
68         g_signal_connect (image, "notify::parent", G_CALLBACK (parent_changed_cb), image->parent);
69     }
70 }
71
72 static void
73 button_common_init                              (GtkWidget      *button,
74                                                  HildonSizeType  size)
75 {
76     /* Set requested size */
77     hildon_gtk_widget_set_theme_size (button, size);
78
79     /* Make sure that all images in this button are always shown */
80     g_signal_connect (button, "notify::image", G_CALLBACK (image_changed_cb), NULL);
81 }
82
83 /**
84  * hildon_gtk_menu_new:
85  *
86  * This is a convenience function to create a #GtkMenu setting its
87  * widget name to allow Hildon specific styling.
88  *
89  * Return value: A newly created #GtkMenu widget.
90  **/
91 GtkWidget *
92 hildon_gtk_menu_new                             (void)
93 {
94     GtkWidget *menu = gtk_menu_new ();
95     gtk_widget_set_name (menu, "hildon-context-sensitive-menu");
96     return menu;
97 }
98
99 /**
100  * hildon_gtk_button_new:
101  * @size: Flags indicating the size of the new button
102  *
103  * This is a convenience function to create a #GtkButton setting its
104  * size to one of the pre-defined Hildon sizes.
105  *
106  * Buttons created with this function also override the
107  * "gtk-button-images" setting. Images set using
108  * gtk_button_set_image() are always shown.
109  *
110  * Return value: A newly created #GtkButton widget.
111  **/
112 GtkWidget *
113 hildon_gtk_button_new                           (HildonSizeType size)
114 {
115     GtkWidget *button = gtk_button_new ();
116     button_common_init (button, size);
117     return button;
118 }
119
120 /**
121  * hildon_gtk_toggle_button_new:
122  * @size: Flags indicating the size of the new button
123  *
124  * This is a convenience function to create a #GtkToggleButton setting
125  * its size to one of the pre-defined Hildon sizes.
126  *
127  * Buttons created with this function also override the
128  * "gtk-button-images" setting. Images set using
129  * gtk_button_set_image() are always shown.
130  *
131  * Return value: A newly created #GtkToggleButton widget.
132  **/
133 GtkWidget *
134 hildon_gtk_toggle_button_new                    (HildonSizeType size)
135 {
136     GtkWidget *button = gtk_toggle_button_new ();
137     button_common_init (button, size);
138     return button;
139 }
140
141 /**
142  * hildon_gtk_radio_button_new:
143  * @size: Flags indicating the size of the new button
144  * @group: An existing radio button group, or %NULL if you are
145  * creating a new group
146  *
147  * This is a convenience function to create a #GtkRadioButton setting
148  * its size to one of the pre-defined Hildon sizes.
149  *
150  * Buttons created with this function also override the
151  * "gtk-button-images" setting. Images set using
152  * gtk_button_set_image() are always shown.
153  *
154  * Return value: A newly created #GtkRadioButton widget.
155  **/
156 GtkWidget *
157 hildon_gtk_radio_button_new                     (HildonSizeType  size,
158                                                  GSList         *group)
159 {
160     GtkWidget *button = gtk_radio_button_new (group);
161     button_common_init (button, size);
162     return button;
163 }
164
165 /**
166  * hildon_gtk_radio_button_new_from_widget:
167  * @size: Flags indicating the size of the new button
168  * @radio_group_member: widget to get radio group from or %NULL
169  *
170  * This is a convenience function to create a #GtkRadioButton setting
171  * its size to one of the pre-defined Hildon sizes.
172  *
173  * Buttons created with this function also override the
174  * "gtk-button-images" setting. Images set using
175  * gtk_button_set_image() are always shown.
176  *
177  * Return value: A newly created #GtkRadioButton widget.
178  **/
179 GtkWidget *
180 hildon_gtk_radio_button_new_from_widget         (HildonSizeType  size,
181                                                  GtkRadioButton *radio_group_member)
182 {
183     GtkWidget *button = gtk_radio_button_new_from_widget (radio_group_member);
184     button_common_init (button, size);
185     return button;
186 }
187
188 #ifdef MAEMO_GTK
189 /**
190  * hildon_gtk_tree_view_new:
191  * @mode: the Hildon UI mode
192  *
193  * Creates a new #GtkTreeView widget with the Hildon UI mode set to
194  * @mode
195  *
196  * Return value: A newly created #GtkTreeView widget.
197  **/
198 GtkWidget *
199 hildon_gtk_tree_view_new                        (HildonUIMode mode)
200 {
201     return g_object_new (GTK_TYPE_TREE_VIEW, "hildon-ui-mode", mode,
202                          "enable-search", FALSE, NULL);
203 }
204
205 /**
206  * hildon_gtk_tree_view_new_with_model:
207  * @mode: the Hildon UI mode
208  * @model: the model.
209  *
210  * Creates a new #GtkTreeView widget with the Hildon UI mode set to
211  * @mode and the model initialized to @model.
212  *
213  * Return value: A newly created #GtkTreeView widget.
214  **/
215 GtkWidget *
216 hildon_gtk_tree_view_new_with_model             (HildonUIMode  mode,
217                                                  GtkTreeModel *model)
218 {
219     return g_object_new (GTK_TYPE_TREE_VIEW, "hildon-ui-mode", mode, "model", model, NULL);
220 }
221
222 /**
223  * hildon_gtk_tree_view_set_ui_mode:
224  * @treeview: A #GtkTreeView
225  * @mode: The new #HildonUIMode
226  *
227  * Sets the UI mode of @treeview to @mode.
228  **/
229 void
230 hildon_gtk_tree_view_set_ui_mode                (GtkTreeView  *treeview,
231                                                  HildonUIMode  mode)
232 {
233     g_return_if_fail (GTK_IS_TREE_VIEW (treeview));
234     g_object_set (treeview, "hildon-ui-mode", mode, NULL);
235 }
236
237 /**
238  * hildon_gtk_icon_view_new:
239  * @mode: the Hildon UI mode
240  *
241  * Creates a new #GtkIconView widget with the Hildon UI mode set to
242  * @mode
243  *
244  * Return value: A newly created #GtkIconView widget
245  **/
246 GtkWidget *
247 hildon_gtk_icon_view_new                        (HildonUIMode mode)
248 {
249     return g_object_new (GTK_TYPE_ICON_VIEW, "hildon-ui-mode", mode, NULL);
250 }
251
252 /**
253  * hildon_gtk_icon_view_new_with_model:
254  * @mode: the Hildon UI mode
255  * @model: The model.
256  *
257  * Creates a new #GtkIconView widget with the Hildon UI mode set to
258  * @mode and the model intitialized to @model.
259  *
260  * Return value: A newly created #GtkIconView widget.
261  **/
262 GtkWidget *
263 hildon_gtk_icon_view_new_with_model             (HildonUIMode  mode,
264                                                  GtkTreeModel *model)
265 {
266     return g_object_new (GTK_TYPE_ICON_VIEW, "hildon-ui-mode", mode, "model", model, NULL);
267 }
268
269 /**
270  * hildon_gtk_icon_view_set_ui_mode:
271  * @iconview: A #GtkIconView
272  * @mode: The new #HildonUIMode
273  *
274  * Sets the UI mode of @iconview to @mode.
275  **/
276 void
277 hildon_gtk_icon_view_set_ui_mode                (GtkIconView  *iconview,
278                                                  HildonUIMode  mode)
279 {
280     g_return_if_fail (GTK_IS_ICON_VIEW (iconview));
281     g_object_set (iconview, "hildon-ui-mode", mode, NULL);
282 }
283 #endif /* MAEMO_GTK */
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 }