2008-08-07 Alberto Garcia <agarcia@igalia.com>
[hildon] / src / hildon-picker-button.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 #include "hildon-picker-button.h"
18 #include "hildon-picker-dialog.h"
19
20 G_DEFINE_TYPE (HildonPickerButton, hildon_picker_button, HILDON_TYPE_BUTTON)
21
22 #define GET_PRIVATE(o)                                                  \
23   (G_TYPE_INSTANCE_GET_PRIVATE ((o), HILDON_TYPE_PICKER_BUTTON, HildonPickerButtonPrivate))
24
25 typedef struct _HildonPickerButtonPrivate HildonPickerButtonPrivate;
26
27 struct _HildonPickerButtonPrivate
28 {
29   GtkWidget *selector;
30   GtkWidget *dialog;
31 };
32
33 /* Signals */
34 enum
35 {
36   VALUE_CHANGED,
37   LAST_SIGNAL
38 };
39
40 enum
41 {
42   PROP_SELECTOR = 1,
43 };
44
45 static guint picker_button_signals[LAST_SIGNAL] = { 0 };
46
47 static void
48 hildon_picker_button_get_property (GObject * object, guint property_id,
49                                    GValue * value, GParamSpec * pspec)
50 {
51   switch (property_id) {
52   case PROP_SELECTOR:
53     g_value_set_object (value,
54                         hildon_picker_button_get_selector (HILDON_PICKER_BUTTON (object)));
55     break;
56   default:
57     G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
58   }
59 }
60
61 static void
62 hildon_picker_button_set_property (GObject * object, guint property_id,
63                                    const GValue * value, GParamSpec * pspec)
64 {
65   switch (property_id) {
66   case PROP_SELECTOR:
67     hildon_picker_button_set_selector (HILDON_PICKER_BUTTON (object),
68                                        g_value_get_object (value));
69     break;
70   default:
71     G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
72   }
73 }
74
75 static void
76 hildon_picker_button_clicked (GtkButton * button)
77 {
78   GtkWidget *parent;
79   HildonPickerButtonPrivate *priv;
80   gint response;
81
82   priv = GET_PRIVATE (HILDON_PICKER_BUTTON (button));
83
84   g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (priv->selector));
85
86   /* Create the dialog if it doesn't exist already.  */
87   if (!priv->dialog) {
88     parent = gtk_widget_get_toplevel (GTK_WIDGET (button));
89     if (GTK_WIDGET_TOPLEVEL (parent)) {
90       priv->dialog = hildon_picker_dialog_new (GTK_WINDOW (parent));
91     } else {
92       priv->dialog = hildon_picker_dialog_new (NULL);
93     }
94
95     hildon_picker_dialog_set_selector (HILDON_PICKER_DIALOG (priv->dialog),
96                                        HILDON_TOUCH_SELECTOR (priv->selector));
97
98     gtk_window_set_modal (GTK_WINDOW (priv->dialog),
99                           gtk_window_get_modal (GTK_WINDOW (parent)));
100     gtk_window_set_title (GTK_WINDOW (priv->dialog),
101                           hildon_button_get_title (HILDON_BUTTON (button)));
102   }
103
104   response = gtk_dialog_run (GTK_DIALOG (priv->dialog));
105   switch (response) {
106   case GTK_RESPONSE_OK:
107     hildon_button_set_value (HILDON_BUTTON (button),
108                              hildon_touch_selector_get_current_text
109                              (HILDON_TOUCH_SELECTOR (priv->selector)));
110     g_signal_emit (HILDON_PICKER_BUTTON (button),
111                    picker_button_signals[VALUE_CHANGED], 0);
112     break;
113   }
114   gtk_widget_hide (priv->dialog);
115 }
116
117 static void
118 hildon_picker_button_class_init (HildonPickerButtonClass * klass)
119 {
120   GObjectClass *object_class = G_OBJECT_CLASS (klass);
121   GtkButtonClass *button_class = GTK_BUTTON_CLASS (klass);
122
123   g_type_class_add_private (klass, sizeof (HildonPickerButtonPrivate));
124
125   object_class->get_property = hildon_picker_button_get_property;
126   object_class->set_property = hildon_picker_button_set_property;
127
128   button_class->clicked = hildon_picker_button_clicked;
129
130   g_object_class_install_property (object_class,
131                                    PROP_SELECTOR,
132                                    g_param_spec_object ("touch-selector",
133                                                         "HildonTouchSelector widget",
134                                                         "HildonTouchSelector widget to be launched on button clicked",
135                                                         HILDON_TYPE_TOUCH_SELECTOR,
136                                                         G_PARAM_READWRITE));
137
138   picker_button_signals[VALUE_CHANGED] =
139     g_signal_new ("value-changed",
140                   G_TYPE_FROM_CLASS (klass),
141                   G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
142                   0,
143                   NULL, NULL,
144                   g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0, NULL);
145 }
146
147 static void
148 hildon_picker_button_init (HildonPickerButton * self)
149 {
150   HildonPickerButtonPrivate *priv;
151
152   priv = GET_PRIVATE (self);
153
154   priv->dialog = NULL;
155   priv->selector = NULL;
156 }
157
158 GtkWidget *
159 hildon_picker_button_new (HildonSizeType          size,
160                           HildonButtonArrangement arrangement)
161 {
162   GtkWidget *button;
163
164   button = g_object_new (HILDON_TYPE_PICKER_BUTTON,
165                          "arrangement", arrangement, "size-flags", size, NULL);
166
167   return button;
168 }
169
170 void
171 hildon_picker_button_set_selector (HildonPickerButton * button,
172                                    HildonTouchSelector * selector)
173 {
174   HildonPickerButtonPrivate *priv;
175
176   g_return_if_fail (HILDON_IS_PICKER_BUTTON (button));
177   g_return_if_fail (HILDON_IS_TOUCH_SELECTOR (selector));
178
179   priv = GET_PRIVATE (button);
180
181   priv->selector = g_object_ref (selector);
182 }
183
184 HildonTouchSelector *
185 hildon_picker_button_get_selector (HildonPickerButton * button)
186 {
187   HildonPickerButtonPrivate *priv;
188
189   g_return_val_if_fail (HILDON_IS_PICKER_BUTTON (button), NULL);
190
191   priv = GET_PRIVATE (button);
192
193   return HILDON_TOUCH_SELECTOR (priv->selector);
194 }