single zeemote support
[drnoksnes] / gui / controls.c
1 /*
2 * This file is part of DrNokSnes
3 *
4 * Copyright (C) 2009 Javier S. Pedro <maemo@javispedro.com>
5 *
6 * This software is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public License
8 * as published by the Free Software Foundation; either version 2.1 of
9 * the License, or (at your option) any later version.
10 *
11 * This software is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this software; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 *
21 */
22
23 #include <string.h>
24 #include <gtk/gtk.h>
25 #include <hildon/hildon-helper.h>
26
27 #if MAEMO_VERSION >= 5
28 #include <hildon/hildon-gtk.h>
29 #include <hildon/hildon-pannable-area.h>
30 #include <hildon/hildon-button.h>
31 #include <hildon/hildon-check-button.h>
32 #include <hildon/hildon-picker-button.h>
33 #include <hildon/hildon-touch-selector.h>
34 #include <pango/pango-attributes.h>
35 #else
36 #include <hildon/hildon-caption.h>
37 #endif
38
39 #include "plugin.h"
40 #include "gconf.h"
41 #include "i18n.h"
42
43 static GtkDialog* dialog;
44 static int current_player;
45 #if MAEMO_VERSION >= 5
46 static HildonCheckButton* keys_chk;
47 static HildonButton* keys_btn;
48 static HildonCheckButton* touch_chk;
49 static HildonCheckButton* touch_show_chk;
50 static HildonCheckButton* zeemote_chk;
51 #else
52 static GtkCheckButton* keys_chk;
53 static GtkButton* keys_btn;
54 static GtkCheckButton* touch_chk;
55 static GtkCheckButton* touch_show_chk;
56 static GtkCheckButton* zeemote_chk;
57 #endif
58
59 static void load_settings()
60 {
61         gchar key_base[kGConfPlayerPathBufferLen];
62         const int key_len = sprintf(key_base, kGConfPlayerPath, current_player);
63         gchar *key = key_base + key_len;
64
65 #if MAEMO_VERSION >= 5
66         strcpy(key, kGConfPlayerKeyboardEnable);
67         hildon_check_button_set_active(keys_chk,
68                 gconf_client_get_bool(gcc, key_base, NULL));
69
70         strcpy(key, kGConfPlayerTouchscreenEnable);
71         hildon_check_button_set_active(touch_chk,
72                 gconf_client_get_bool(gcc, key_base, NULL));
73         strcpy(key, kGConfPlayerTouchscreenShow);
74         hildon_check_button_set_active(touch_show_chk,
75                 gconf_client_get_bool(gcc, key_base, NULL));
76 #else
77         strcpy(key, kGConfPlayerKeyboardEnable);
78         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(keys_chk),
79                 gconf_client_get_bool(gcc, key_base, NULL));
80
81         strcpy(key, kGConfPlayerTouchscreenEnable);
82         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(touch_chk),
83                 gconf_client_get_bool(gcc, key_base, NULL));
84         strcpy(key, kGConfPlayerTouchscreenShow);
85         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(touch_show_chk),
86                 gconf_client_get_bool(gcc, key_base, NULL));
87 #endif
88 }
89
90 static void save_settings()
91 {
92         gchar key_base[kGConfPlayerPathBufferLen];
93         const int key_len = sprintf(key_base, kGConfPlayerPath, current_player);
94         gchar *key = key_base + key_len;
95
96 #if MAEMO_VERSION >= 5
97         // Keyboard
98         strcpy(key, kGConfPlayerKeyboardEnable);
99         gconf_client_set_bool(gcc, key_base,
100                 hildon_check_button_get_active(keys_chk), NULL);
101
102         // Touchscreen
103         strcpy(key, kGConfPlayerTouchscreenEnable);
104         gconf_client_set_bool(gcc, key_base,
105                 hildon_check_button_get_active(touch_chk), NULL);
106         strcpy(key, kGConfPlayerTouchscreenShow);
107         gconf_client_set_bool(gcc, key_base,
108                 hildon_check_button_get_active(touch_show_chk), NULL);
109
110         // Zeemote
111         strcpy(key, kGConfPlayerZeemoteEnable);
112         gconf_client_set_bool(gcc, key_base,
113                 hildon_check_button_get_active(zeemote_chk), NULL);
114 #else /* MAEMO_VERSION < 5 */
115         // Keyboard
116         strcpy(key, kGConfPlayerKeyboardEnable);
117         gconf_client_set_bool(gcc, key_base,
118                 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(keys_chk)), NULL);
119
120         // Touchscreen
121         strcpy(key, kGConfPlayerTouchscreenEnable);
122         gconf_client_set_bool(gcc, key_base,
123                 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(touch_chk)), NULL);
124         strcpy(key, kGConfPlayerTouchscreenShow);
125         gconf_client_set_bool(gcc, key_base,
126                 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(touch_show_chk)), NULL);
127
128         // Zeemote
129         strcpy(key, kGConfPlayerZeemoteEnable);
130         gconf_client_set_bool(gcc, key_base,
131                 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(zeemote_chk)), NULL);
132 #endif
133 }
134
135 static void keys_btn_callback(GtkWidget * button, gpointer data)
136 {
137         keys_dialog(GTK_WINDOW(dialog), GPOINTER_TO_INT(data));
138 }
139
140 static void cb_dialog_response(GtkWidget * button, gint response, gpointer data)
141 {
142         if (response == GTK_RESPONSE_OK) {
143                 save_settings();
144                 settings_update_controls(current_player);
145         }
146
147         gtk_widget_destroy(GTK_WIDGET(dialog));
148 }
149
150 #if MAEMO_VERSION >= 5
151 static void set_button_layout(HildonButton* button,
152  GtkSizeGroup* titles_size_group, GtkSizeGroup* values_size_group)
153 {
154         hildon_button_add_title_size_group(button, titles_size_group);
155         hildon_button_add_value_size_group(button, values_size_group);
156         hildon_button_set_alignment(button, 0.0, 0.5, 1.0, 0.0);
157 }
158 #endif
159
160 gchar* controls_describe(int player)
161 {
162         static gchar description[128];
163
164         gchar key_base[kGConfPlayerPathBufferLen];
165         const int key_len = sprintf(key_base, kGConfPlayerPath, player);
166         gchar *key = key_base + key_len;
167
168         description[0] = '\0';
169
170         strcpy(key, kGConfPlayerKeyboardEnable);
171         if (gconf_client_get_bool(gcc, key_base, NULL)) {
172                 strcpy(description, _("Keyboard"));
173         }
174
175         if (description[0] == '\0') {
176                 strcpy(description, _("Disabled"));
177         }
178
179         return description;
180 }
181
182 void controls_dialog(GtkWindow* parent, int player)
183 {
184         gchar* title = g_strdup_printf(_("Player %d controls"), player);
185         dialog = GTK_DIALOG(gtk_dialog_new_with_buttons(title,
186                 parent, GTK_DIALOG_MODAL,
187                 GTK_STOCK_SAVE, GTK_RESPONSE_OK,
188                 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL));
189         g_free(title);
190
191         current_player = player;
192
193 #if MAEMO_VERSION >= 5
194         GtkBox * box = GTK_BOX(gtk_vbox_new(FALSE, HILDON_MARGIN_HALF));
195         HildonPannableArea * pannable =
196                 HILDON_PANNABLE_AREA(hildon_pannable_area_new());
197         GtkSizeGroup * titles_size_group =
198                  gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
199         GtkSizeGroup * values_size_group =
200                  gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
201         PangoAttrList *pattrlist = pango_attr_list_new();
202         PangoAttribute *attr = pango_attr_size_new(22 * PANGO_SCALE);
203         attr->start_index = 0;
204         attr->end_index = G_MAXINT;
205         pango_attr_list_insert(pattrlist, attr);
206
207         GtkLabel* separator_1 = GTK_LABEL(gtk_label_new(_("Keys")));
208         gtk_label_set_attributes(separator_1, pattrlist);
209         gtk_label_set_justify(separator_1, GTK_JUSTIFY_CENTER);
210
211         keys_chk = HILDON_CHECK_BUTTON(hildon_check_button_new(
212                 HILDON_SIZE_AUTO_WIDTH | HILDON_SIZE_FINGER_HEIGHT));
213         gtk_button_set_label(GTK_BUTTON(keys_chk), _("Enable keyboard"));
214         set_button_layout(HILDON_BUTTON(keys_chk),
215                 titles_size_group, values_size_group);
216
217         keys_btn = HILDON_BUTTON(hildon_button_new_with_text(
218                 HILDON_SIZE_AUTO_WIDTH | HILDON_SIZE_FINGER_HEIGHT,
219                 HILDON_BUTTON_ARRANGEMENT_HORIZONTAL,
220                 _("Configure keys…"), NULL));
221         set_button_layout(HILDON_BUTTON(keys_btn),
222                 titles_size_group, values_size_group);
223         g_signal_connect(G_OBJECT(keys_btn), "clicked",
224                                         G_CALLBACK(keys_btn_callback), GINT_TO_POINTER(player));
225
226         GtkLabel* separator_2 = GTK_LABEL(gtk_label_new(_("Touchscreen")));
227         gtk_label_set_attributes(separator_2, pattrlist);
228         gtk_label_set_justify(separator_2, GTK_JUSTIFY_CENTER);
229
230         touch_chk = HILDON_CHECK_BUTTON(hildon_check_button_new(
231                 HILDON_SIZE_AUTO_WIDTH | HILDON_SIZE_FINGER_HEIGHT));
232         gtk_button_set_label(GTK_BUTTON(touch_chk),
233                 _("Enable touchscreen buttons"));
234         set_button_layout(HILDON_BUTTON(touch_chk),
235                 titles_size_group, values_size_group);
236                 
237         touch_show_chk = HILDON_CHECK_BUTTON(hildon_check_button_new(
238                 HILDON_SIZE_AUTO_WIDTH | HILDON_SIZE_FINGER_HEIGHT));
239         gtk_button_set_label(GTK_BUTTON(touch_show_chk),
240                 _("Show on-screen button grid"));
241         set_button_layout(HILDON_BUTTON(touch_show_chk),
242                 titles_size_group, values_size_group);
243
244 #if 0
245         GtkLabel* separator_3 = GTK_LABEL(gtk_label_new(_("Accelerometer")));
246         gtk_label_set_attributes(separator_3, pattrlist);
247         gtk_label_set_justify(separator_3, GTK_JUSTIFY_CENTER);
248         
249         GtkLabel* separator_4 = GTK_LABEL(gtk_label_new(_("Wiimote")));
250         gtk_label_set_attributes(separator_4, pattrlist);
251         gtk_label_set_justify(separator_4, GTK_JUSTIFY_CENTER);
252 #endif
253
254         GtkLabel* separator_5 = GTK_LABEL(gtk_label_new(_("Zeemote")));
255         gtk_label_set_attributes(separator_5, pattrlist);
256         gtk_label_set_justify(separator_5, GTK_JUSTIFY_CENTER);
257
258         zeemote_chk = HILDON_CHECK_BUTTON(hildon_check_button_new(
259                 HILDON_SIZE_AUTO_WIDTH | HILDON_SIZE_FINGER_HEIGHT));
260         gtk_button_set_label(GTK_BUTTON(zeemote_chk), _("Enable Zeemote joystick"));
261         set_button_layout(HILDON_BUTTON(zeemote_chk),
262                 titles_size_group, values_size_group);
263
264         gtk_box_pack_start(box, GTK_WIDGET(separator_1),
265                 FALSE, FALSE, HILDON_MARGIN_HALF);
266         gtk_box_pack_start(box, GTK_WIDGET(keys_chk),
267                 FALSE, FALSE, 0);
268         gtk_box_pack_start(box, GTK_WIDGET(keys_btn),
269                 FALSE, FALSE, 0);
270         gtk_box_pack_start(box, GTK_WIDGET(separator_2),
271                 FALSE, FALSE, HILDON_MARGIN_HALF);
272         gtk_box_pack_start(box, GTK_WIDGET(touch_chk),
273                 FALSE, FALSE, 0);
274         gtk_box_pack_start(box, GTK_WIDGET(touch_show_chk),
275                 FALSE, FALSE, 0);
276 #if 0
277         gtk_box_pack_start(box, GTK_WIDGET(separator_3),
278                 FALSE, FALSE, HILDON_MARGIN_HALF);
279         gtk_box_pack_start(box, GTK_WIDGET(separator_4),
280                 FALSE, FALSE, HILDON_MARGIN_HALF);
281 #endif
282         gtk_box_pack_start(box, GTK_WIDGET(separator_5),
283                 FALSE, FALSE, HILDON_MARGIN_HALF);
284         gtk_box_pack_start(box, GTK_WIDGET(zeemote_chk),
285                 FALSE, FALSE, 0);
286
287         hildon_pannable_area_add_with_viewport(pannable, GTK_WIDGET(box));
288         gtk_box_pack_start_defaults(GTK_BOX(dialog->vbox), GTK_WIDGET(pannable));
289
290         pango_attr_list_unref(pattrlist);
291         g_object_unref(titles_size_group);
292         g_object_unref(values_size_group);
293 #else
294         GtkBox* keys_box = GTK_BOX(gtk_hbox_new(FALSE, HILDON_MARGIN_DEFAULT));
295
296         keys_chk = GTK_CHECK_BUTTON(gtk_check_button_new_with_label(
297                 _("Enable keyboard")));
298         keys_btn = GTK_BUTTON(gtk_button_new_with_label(_("Configure keys…")));
299         g_signal_connect(G_OBJECT(keys_btn), "clicked",
300                                         G_CALLBACK(keys_btn_callback), GINT_TO_POINTER(player));
301
302         gtk_box_pack_start_defaults(keys_box, GTK_WIDGET(keys_chk));
303         gtk_box_pack_start_defaults(keys_box, GTK_WIDGET(keys_btn));
304
305         GtkWidget* sep_1 = GTK_WIDGET(gtk_hseparator_new());
306
307         GtkBox* touch_box = GTK_BOX(gtk_vbox_new(FALSE, HILDON_MARGIN_HALF));
308
309         touch_chk = GTK_CHECK_BUTTON(gtk_check_button_new_with_label(
310                 _("Enable touchscreen buttons")));
311         touch_show_chk = GTK_CHECK_BUTTON(gtk_check_button_new_with_label(
312                 _("Show on-screen button grid")));
313
314         GtkWidget* sep_2 = GTK_WIDGET(gtk_hseparator_new());
315         touch_show_chk = GTK_CHECK_BUTTON(gtk_check_button_new_with_label(
316                 _("Enable Zeemote joystick")));
317
318         gtk_box_pack_start_defaults(touch_box, GTK_WIDGET(touch_chk));
319         gtk_box_pack_start_defaults(touch_box, GTK_WIDGET(touch_show_chk));
320
321         gtk_box_pack_start_defaults(GTK_BOX(dialog->vbox), GTK_WIDGET(keys_box));
322         gtk_box_pack_start_defaults(GTK_BOX(dialog->vbox), sep_1);
323         gtk_box_pack_start_defaults(GTK_BOX(dialog->vbox), GTK_WIDGET(touch_box));
324         gtk_box_pack_start_defaults(GTK_BOX(dialog->vbox), sep_2);
325         gtk_box_pack_start_defaults(GTK_BOX(dialog->vbox), GTK_WIDGET(zeemote_chk));
326 #endif
327
328         load_settings();
329
330 #if MAEMO_VERSION >= 5
331         gtk_window_resize(GTK_WINDOW(dialog), 800, 360);
332 #else
333         gtk_window_resize(GTK_WINDOW(dialog), 400, 200);
334 #endif
335
336         g_signal_connect(G_OBJECT(dialog), "response",
337                                         G_CALLBACK (cb_dialog_response), NULL);
338         
339         gtk_widget_show_all(GTK_WIDGET(dialog));
340 }
341