2 * This file is part of DrNokSnes
4 * Copyright (C) 2009 Javier S. Pedro <maemo@javispedro.com>
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.
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.
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
25 #include <hildon/hildon-helper.h>
27 #if MAEMO_VERSION >= 5
28 #include <hildon/hildon-gtk.h>
29 #include <hildon/hildon-pannable-area.h>
30 #include <hildon/hildon-check-button.h>
33 #include "../platform/hgw.h"
36 #include "cellrendererkey.h"
39 static GtkDialog* dialog;
40 static int current_player;
41 #if MAEMO_VERSION >= 5
42 static HildonPannableArea* keys_scroll;
44 static GtkScrolledWindow* keys_scroll;
46 static GtkListStore* keys_store;
47 static GtkTreeView* keys_list;
49 #define DIALOG_RESPONSE_DEFAULTS 1
58 typedef struct ButtonEntry {
60 const char * gconf_key;
61 unsigned char scancode;
65 static ButtonEntry buttons[] = {
67 #define BUTTON(description, slug, actions, d, f) \
68 { description, G_STRINGIFY(slug), 0 },
69 #define ACTION(description, slug, actions, d, f) \
70 { description, G_STRINGIFY(slug), 0 },
73 #include "buttons.inc"
82 gchar key_base[kGConfPlayerPathBufferLen];
87 static gboolean load_key_config(GtkTreeModel *model, GtkTreePath *path,
88 GtkTreeIter *iter, gpointer data)
90 IteratorData *idata = (IteratorData*)data;
91 ButtonEntry *button_entry;
93 gtk_tree_model_get(model, iter,
94 BUTTONENTRY_COLUMN, &button_entry,
97 strcpy(idata->key, button_entry->gconf_key);
98 int scancode = gconf_client_get_int(gcc, idata->key_base, NULL);
100 button_entry->scancode = scancode;
101 button_entry->changed = FALSE;
103 gtk_tree_model_row_changed(GTK_TREE_MODEL(keys_store), path, iter);
108 static void load_settings()
111 idata.key_len = sprintf(idata.key_base,
112 kGConfPlayerPath kGConfPlayerKeyboardPath "/", current_player);
113 idata.key = idata.key_base + idata.key_len;
114 gtk_tree_model_foreach(GTK_TREE_MODEL(keys_store), load_key_config, &idata);
117 static gboolean save_key_config(GtkTreeModel *model, GtkTreePath *path,
118 GtkTreeIter *iter, gpointer data)
120 IteratorData *idata = (IteratorData*)data;
121 ButtonEntry *button_entry;
123 gtk_tree_model_get(model, iter,
124 BUTTONENTRY_COLUMN, &button_entry,
127 if (button_entry->changed) {
128 strcpy(idata->key, button_entry->gconf_key);
129 gconf_client_set_int(gcc, idata->key_base, button_entry->scancode, NULL);
130 button_entry->changed = FALSE;
133 gtk_tree_model_row_changed(GTK_TREE_MODEL(keys_store), path, iter);
138 static void save_settings()
141 idata.key_len = sprintf(idata.key_base,
142 kGConfPlayerPath kGConfPlayerKeyboardPath "/", current_player);
143 idata.key = idata.key_base + idata.key_len;
144 gtk_tree_model_foreach(GTK_TREE_MODEL(keys_store), save_key_config, &idata);
147 static gboolean get_default_key_config(GtkTreeModel *model, GtkTreePath *path,
148 GtkTreeIter *iter, gpointer data)
150 IteratorData *idata = (IteratorData*)data;
151 ButtonEntry *button_entry;
153 gtk_tree_model_get(model, iter,
154 BUTTONENTRY_COLUMN, &button_entry,
157 strcpy(idata->key, button_entry->gconf_key);
158 GConfValue *value = gconf_client_get_default_from_schema(gcc,
159 idata->key_base, NULL);
161 int scancode = gconf_value_get_int(value);
162 if (button_entry->scancode != scancode) {
163 button_entry->scancode = scancode;
164 button_entry->changed = TRUE;
166 gconf_value_free(value);
169 gtk_tree_model_row_changed(GTK_TREE_MODEL(keys_store), path, iter);
174 static void get_default_settings()
177 idata.key_len = sprintf(idata.key_base,
178 kGConfPlayerPath kGConfPlayerKeyboardPath "/", current_player);
179 idata.key = idata.key_base + idata.key_len;
180 gtk_tree_model_foreach(GTK_TREE_MODEL(keys_store),
181 get_default_key_config, &idata);
185 accel_set_func (GtkTreeViewColumn *tree_column,
186 GtkCellRenderer *cell,
191 ButtonEntry *button_entry;
193 gtk_tree_model_get (model, iter,
194 BUTTONENTRY_COLUMN, &button_entry,
197 if (button_entry == NULL) {
198 g_object_set (G_OBJECT (cell),
202 g_object_set (G_OBJECT (cell),
205 "scancode", button_entry->scancode,
206 "style", PANGO_STYLE_NORMAL,
212 cb_key_edited(GtkCellRendererText *cell, const char *path_string,
213 guint scancode, gpointer data)
215 GtkTreePath *path = gtk_tree_path_new_from_string(path_string);
217 ButtonEntry *button_entry;
219 gtk_tree_model_get_iter(GTK_TREE_MODEL(keys_store), &iter, path);
220 gtk_tree_model_get(GTK_TREE_MODEL(keys_store), &iter,
221 BUTTONENTRY_COLUMN, &button_entry,
224 button_entry->scancode = scancode;
225 button_entry->changed = TRUE;
227 gtk_tree_model_row_changed(GTK_TREE_MODEL(keys_store), path, &iter);
228 gtk_tree_path_free(path);
232 cb_key_cleared(GtkCellRendererText *cell, const char *path_string,
235 GtkTreePath *path = gtk_tree_path_new_from_string(path_string);
237 ButtonEntry *button_entry;
239 gtk_tree_model_get_iter(GTK_TREE_MODEL(keys_store), &iter, path);
240 gtk_tree_model_get(GTK_TREE_MODEL(keys_store), &iter,
241 BUTTONENTRY_COLUMN, &button_entry,
244 button_entry->scancode = 0;
245 button_entry->changed = TRUE;
247 gtk_tree_model_row_changed(GTK_TREE_MODEL(keys_store), path, &iter);
248 gtk_tree_path_free(path);
251 static void cb_dialog_response(GtkWidget * sender, gint response, gpointer data)
253 if (response == DIALOG_RESPONSE_DEFAULTS) {
254 get_default_settings();
258 if (response == GTK_RESPONSE_OK) {
262 gtk_widget_destroy(GTK_WIDGET(dialog));
265 void keys_dialog(GtkWindow* parent, int player)
267 gchar* title = g_strdup_printf(_("Player %d keys"), player);
268 dialog = GTK_DIALOG(gtk_dialog_new_with_buttons(title,
269 parent, GTK_DIALOG_MODAL,
270 _("Defaults"), DIALOG_RESPONSE_DEFAULTS,
271 GTK_STOCK_SAVE, GTK_RESPONSE_OK,
272 GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL));
275 current_player = player;
277 keys_store = GTK_LIST_STORE(gtk_list_store_new(N_COLUMNS,
278 G_TYPE_STRING, G_TYPE_POINTER));
279 #if MAEMO_VERSION >= 5
280 keys_list = GTK_TREE_VIEW(hildon_gtk_tree_view_new_with_model(
281 HILDON_UI_MODE_EDIT, GTK_TREE_MODEL(keys_store)));
282 keys_scroll = HILDON_PANNABLE_AREA(hildon_pannable_area_new());
284 keys_list = GTK_TREE_VIEW(
285 gtk_tree_view_new_with_model(GTK_TREE_MODEL(keys_store)));
286 keys_scroll = GTK_SCROLLED_WINDOW(gtk_scrolled_window_new(NULL, NULL));
287 gtk_scrolled_window_set_policy(keys_scroll,
288 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
291 GtkCellRenderer* renderer = GTK_CELL_RENDERER(gtk_cell_renderer_text_new());
292 GtkTreeViewColumn * column =
293 gtk_tree_view_column_new_with_attributes ("Button",
294 gtk_cell_renderer_text_new(),
295 "text", BUTTON_COLUMN,
297 gtk_tree_view_column_set_resizable(column, FALSE);
298 gtk_tree_view_column_set_expand(column, TRUE);
299 gtk_tree_view_append_column(keys_list, column);
301 renderer = GTK_CELL_RENDERER(cell_renderer_key_new());
302 column = gtk_tree_view_column_new_with_attributes("Key", renderer, NULL);
303 gtk_tree_view_column_set_cell_data_func(column, renderer, accel_set_func, NULL, NULL);
304 gtk_tree_view_column_set_resizable(column, FALSE);
305 #if MAEMO_VERSION >= 5
306 gtk_tree_view_column_set_min_width(column, 340);
308 gtk_tree_view_column_set_min_width(column, 250);
310 gtk_tree_view_append_column(keys_list, column);
311 gtk_tree_view_set_headers_visible(keys_list, TRUE);
314 for (i = 0; buttons[i].name; i++) {
316 gtk_list_store_append(keys_store, &iter);
317 gtk_list_store_set(keys_store, &iter,
318 BUTTON_COLUMN, buttons[i].name,
319 BUTTONENTRY_COLUMN, &buttons[i],
323 #if MAEMO_VERSION >= 5
324 gtk_window_resize(GTK_WINDOW(dialog), 800, 340);
326 gtk_window_resize(GTK_WINDOW(dialog), 600, 340);
328 gtk_container_add(GTK_CONTAINER(keys_scroll), GTK_WIDGET(keys_list));
329 gtk_box_pack_start_defaults(GTK_BOX(dialog->vbox), GTK_WIDGET(keys_scroll));
333 g_signal_connect(G_OBJECT(dialog), "response",
334 G_CALLBACK (cb_dialog_response), NULL);
335 g_signal_connect(G_OBJECT(renderer), "accel_edited",
336 G_CALLBACK(cb_key_edited), NULL);
337 g_signal_connect(G_OBJECT(renderer), "accel_cleared",
338 G_CALLBACK(cb_key_cleared), NULL);
340 gtk_widget_show_all(GTK_WIDGET(dialog));