Reviewed the use of MAEMO_GTK define, now we add the define in the compilation line...
[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     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 = "-finger";
63     } else if (size & HILDON_SIZE_THUMB_HEIGHT) {
64         height = HILDON_HEIGHT_THUMB;
65         widget_name = "-thumb";
66     }
67
68     if (widget_name)
69         widget_name = g_strconcat (g_type_name (GTK_WIDGET_TYPE (widget)), widget_name, NULL);
70
71     /* Requested width */
72     if (size & HILDON_SIZE_HALFSCREEN_WIDTH) {
73         width = HILDON_WIDTH_HALFSCREEN;
74     } else if (size & HILDON_SIZE_FULLSCREEN_WIDTH) {
75         width = HILDON_WIDTH_FULLSCREEN;
76     }
77
78     gtk_widget_set_size_request (widget, width, height);
79
80     if (widget_name) {
81         gtk_widget_set_name (widget, widget_name);
82         g_free (widget_name);
83     }
84 }
85
86 static void
87 image_visible_changed_cb                        (GtkWidget  *image,
88                                                  GParamSpec *arg1,
89                                                  gpointer   oldparent)
90 {
91     if (!GTK_WIDGET_VISIBLE (image))
92         gtk_widget_show (image);
93 }
94
95 static void
96 parent_changed_cb                               (GtkWidget  *image,
97                                                  GParamSpec *arg1,
98                                                  gpointer   oldparent)
99 {
100     /* If the parent has really changed, remove the old signal handlers */
101     if (image->parent != oldparent) {
102         g_signal_handlers_disconnect_by_func (image, parent_changed_cb, oldparent);
103         g_signal_handlers_disconnect_by_func (image, image_visible_changed_cb, NULL);
104     }
105 }
106
107 static void
108 image_changed_cb                                (GtkButton  *button,
109                                                  GParamSpec *arg1,
110                                                  gpointer    user_data)
111 {
112     GtkWidget *image = gtk_button_get_image (button);
113
114     g_return_if_fail (image == NULL || GTK_IS_WIDGET (image));
115
116     if (image != NULL) {
117         /* If the button has a new image, show it */
118         gtk_widget_show (image);
119         /* Show the image no matter the value of gtk-button-images */
120         g_signal_connect (image, "notify::visible", G_CALLBACK (image_visible_changed_cb), NULL);
121         /* If the image is removed from the button, disconnect these handlers */
122         g_signal_connect (image, "notify::parent", G_CALLBACK (parent_changed_cb), image->parent);
123     }
124 }
125
126 static void
127 button_common_init                              (GtkWidget      *button,
128                                                  HildonSizeType  size)
129 {
130     /* Set requested size */
131     hildon_gtk_widget_set_theme_size (button, size);
132
133     /* Make sure that all images in this button are always shown */
134     g_signal_connect (button, "notify::image", G_CALLBACK (image_changed_cb), NULL);
135 }
136
137 /**
138  * hildon_gtk_menu_new:
139  *
140  * This is a convenience function to create a #GtkMenu setting its
141  * widget name to allow Hildon specific styling.
142  *
143  * Return value: A newly created #GtkMenu widget.
144  **/
145 GtkWidget *
146 hildon_gtk_menu_new                             (void)
147 {
148     GtkWidget *menu = gtk_menu_new ();
149     gtk_widget_set_name (menu, "hildon-context-sensitive-menu");
150     return menu;
151 }
152
153 /**
154  * hildon_gtk_button_new:
155  * @size: Flags indicating the size of the new button
156  *
157  * This is a convenience function to create a #GtkButton setting its
158  * 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 #GtkButton widget.
165  **/
166 GtkWidget *
167 hildon_gtk_button_new                           (HildonSizeType size)
168 {
169     GtkWidget *button = gtk_button_new ();
170     button_common_init (button, size);
171     return button;
172 }
173
174 /**
175  * hildon_gtk_toggle_button_new:
176  * @size: Flags indicating the size of the new button
177  *
178  * This is a convenience function to create a #GtkToggleButton setting
179  * its size to one of the pre-defined Hildon sizes.
180  *
181  * Buttons created with this function also override the
182  * "gtk-button-images" setting. Images set using
183  * gtk_button_set_image() are always shown.
184  *
185  * Return value: A newly created #GtkToggleButton widget.
186  **/
187 GtkWidget *
188 hildon_gtk_toggle_button_new                    (HildonSizeType size)
189 {
190     GtkWidget *button = gtk_toggle_button_new ();
191     button_common_init (button, size);
192     return button;
193 }
194
195 /**
196  * hildon_gtk_radio_button_new:
197  * @size: Flags indicating the size of the new button
198  * @group: An existing radio button group, or %NULL if you are
199  * creating a new group
200  *
201  * This is a convenience function to create a #GtkRadioButton setting
202  * its size to one of the pre-defined Hildon sizes.
203  *
204  * Buttons created with this function also override the
205  * "gtk-button-images" setting. Images set using
206  * gtk_button_set_image() are always shown.
207  *
208  * Return value: A newly created #GtkRadioButton widget.
209  **/
210 GtkWidget *
211 hildon_gtk_radio_button_new                     (HildonSizeType  size,
212                                                  GSList         *group)
213 {
214     GtkWidget *button = gtk_radio_button_new (group);
215     button_common_init (button, size);
216     return button;
217 }
218
219 /**
220  * hildon_gtk_radio_button_new_from_widget:
221  * @size: Flags indicating the size of the new button
222  * @radio_group_member: widget to get radio group from or %NULL
223  *
224  * This is a convenience function to create a #GtkRadioButton setting
225  * its size to one of the pre-defined Hildon sizes.
226  *
227  * Buttons created with this function also override the
228  * "gtk-button-images" setting. Images set using
229  * gtk_button_set_image() are always shown.
230  *
231  * Return value: A newly created #GtkRadioButton widget.
232  **/
233 GtkWidget *
234 hildon_gtk_radio_button_new_from_widget         (HildonSizeType  size,
235                                                  GtkRadioButton *radio_group_member)
236 {
237     GtkWidget *button = gtk_radio_button_new_from_widget (radio_group_member);
238     button_common_init (button, size);
239     return button;
240 }
241
242 #ifdef MAEMO_GTK
243 /**
244  * hildon_gtk_tree_view_new:
245  * @mode: the Hildon UI mode
246  *
247  * Creates a new #GtkTreeView widget with the Hildon UI mode set to
248  * @mode
249  *
250  * Return value: A newly created #GtkTreeView widget.
251  **/
252 GtkWidget *
253 hildon_gtk_tree_view_new                        (HildonUIMode mode)
254 {
255     return g_object_new (GTK_TYPE_TREE_VIEW, "hildon-ui-mode", mode, NULL);
256 }
257
258 /**
259  * hildon_gtk_tree_view_new_with_model:
260  * @mode: the Hildon UI mode
261  * @model: the model.
262  *
263  * Creates a new #GtkTreeView widget with the Hildon UI mode set to
264  * @mode and the model initialized to @model.
265  *
266  * Return value: A newly created #GtkTreeView widget.
267  **/
268 GtkWidget *
269 hildon_gtk_tree_view_new_with_model             (HildonUIMode  mode,
270                                                  GtkTreeModel *model)
271 {
272     return g_object_new (GTK_TYPE_TREE_VIEW, "hildon-ui-mode", mode, "model", model, NULL);
273 }
274
275 /**
276  * hildon_gtk_icon_view_new:
277  * @mode: the Hildon UI mode
278  *
279  * Creates a new #GtkIconView widget with the Hildon UI mode set to
280  * @mode
281  *
282  * Return value: A newly created #GtkIconView widget
283  **/
284 GtkWidget *
285 hildon_gtk_icon_view_new                        (HildonUIMode mode)
286 {
287     return g_object_new (GTK_TYPE_ICON_VIEW, "hildon-ui-mode", mode, NULL);
288 }
289
290 /**
291  * hildon_gtk_icon_view_new_with_model:
292  * @mode: the Hildon UI mode
293  * @model: The model.
294  *
295  * Creates a new #GtkIconView widget with the Hildon UI mode set to
296  * @mode and the model intitialized to @model.
297  *
298  * Return value: A newly created #GtkIconView widget.
299  **/
300 GtkWidget *
301 hildon_gtk_icon_view_new_with_model             (HildonUIMode  mode,
302                                                  GtkTreeModel *model)
303 {
304     return g_object_new (GTK_TYPE_ICON_VIEW, "hildon-ui-mode", mode, "model", model, NULL);
305 }
306 #endif /* MAEMO_GTK */
307
308 /**
309  * hildon_gtk_window_set_progress_indicator:
310  * @window: The window, we want to define its state
311  * @state: The state we want to set: 1 -> show progress indicator, 0
312  *          -> hide progress indicator.
313  *
314  * This functions notifies the window manager that it should add a
315  * progress indicator in the title of the window. It applies to
316  * #HildonDialog and #HildonWindow.
317  *
318  **/
319 void
320 hildon_gtk_window_set_progress_indicator        (GtkWindow    *window,
321                                                  guint        state)
322 {
323   GtkWidget *widget = GTK_WIDGET (window);
324   GdkDisplay *display;
325   Atom atom;
326
327   display = gdk_drawable_get_display (widget->window);
328   atom = gdk_x11_get_xatom_by_name_for_display (display, "_HILDON_WM_WINDOW_PROGRESS_INDICATOR");
329
330   XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (widget->window),
331                    atom, XA_INTEGER, 32, PropModeReplace,
332                    (guchar *)&state, 1);
333 }