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>
35 #include "cellrendererkey.h"
38 static GtkDialog* dialog;
39 static int current_player;
40 #if MAEMO_VERSION >= 5
41 static HildonPannableArea* keys_scroll;
43 static GtkScrolledWindow* keys_scroll;
45 static GtkListStore* keys_store;
46 static GtkTreeView* keys_list;
48 #define DIALOG_RESPONSE_DEFAULTS 1
57 typedef struct ButtonEntry {
59 const char * gconf_key;
60 unsigned char scancode;
64 static ButtonEntry buttons[] = {
66 #define BUTTON(description, slug, actions, d, f) \
67 { description, G_STRINGIFY(slug), 0 },
68 #define ACTION(description, slug, actions, d, f) \
69 { description, G_STRINGIFY(slug), 0 },
72 #include "buttons.inc"
81 gchar key_base[kGConfPlayerPathBufferLen];
86 static gboolean load_key_config(GtkTreeModel *model, GtkTreePath *path,
87 GtkTreeIter *iter, gpointer data)
89 IteratorData *idata = (IteratorData*)data;
90 ButtonEntry *button_entry;
92 gtk_tree_model_get(model, iter,
93 BUTTONENTRY_COLUMN, &button_entry,
96 strcpy(idata->key, button_entry->gconf_key);
97 int scancode = gconf_client_get_int(gcc, idata->key_base, NULL);
99 button_entry->scancode = scancode;
100 button_entry->changed = FALSE;
102 gtk_tree_model_row_changed(GTK_TREE_MODEL(keys_store), path, iter);
107 static void load_settings()
110 idata.key_len = sprintf(idata.key_base,
111 kGConfPlayerPath kGConfPlayerKeyboardPath "/", current_player);
112 idata.key = idata.key_base + idata.key_len;
113 gtk_tree_model_foreach(GTK_TREE_MODEL(keys_store), load_key_config, &idata);
116 static gboolean save_key_config(GtkTreeModel *model, GtkTreePath *path,
117 GtkTreeIter *iter, gpointer data)
119 IteratorData *idata = (IteratorData*)data;
120 ButtonEntry *button_entry;
122 gtk_tree_model_get(model, iter,
123 BUTTONENTRY_COLUMN, &button_entry,
126 if (button_entry->changed) {
127 strcpy(idata->key, button_entry->gconf_key);
128 gconf_client_set_int(gcc, idata->key_base, button_entry->scancode, NULL);
129 button_entry->changed = FALSE;
132 gtk_tree_model_row_changed(GTK_TREE_MODEL(keys_store), path, iter);
137 static void save_settings()
140 idata.key_len = sprintf(idata.key_base,
141 kGConfPlayerPath kGConfPlayerKeyboardPath "/", current_player);
142 idata.key = idata.key_base + idata.key_len;
143 gtk_tree_model_foreach(GTK_TREE_MODEL(keys_store), save_key_config, &idata);
146 static gboolean get_default_key_config(GtkTreeModel *model, GtkTreePath *path,
147 GtkTreeIter *iter, gpointer data)
149 IteratorData *idata = (IteratorData*)data;
150 ButtonEntry *button_entry;
152 gtk_tree_model_get(model, iter,
153 BUTTONENTRY_COLUMN, &button_entry,
156 strcpy(idata->key, button_entry->gconf_key);
157 GConfValue *value = gconf_client_get_default_from_schema(gcc,
158 idata->key_base, NULL);
160 int scancode = gconf_value_get_int(value);
161 if (button_entry->scancode != scancode) {
162 button_entry->scancode = scancode;
163 button_entry->changed = TRUE;
165 gconf_value_free(value);
168 gtk_tree_model_row_changed(GTK_TREE_MODEL(keys_store), path, iter);
173 static void get_default_settings()
176 idata.key_len = sprintf(idata.key_base,
177 kGConfPlayerPath kGConfPlayerKeyboardPath "/", current_player);
178 idata.key = idata.key_base + idata.key_len;
179 gtk_tree_model_foreach(GTK_TREE_MODEL(keys_store),
180 get_default_key_config, &idata);
184 accel_set_func (GtkTreeViewColumn *tree_column,
185 GtkCellRenderer *cell,
190 ButtonEntry *button_entry;
192 gtk_tree_model_get (model, iter,
193 BUTTONENTRY_COLUMN, &button_entry,
196 if (button_entry == NULL) {
197 g_object_set (G_OBJECT (cell),
201 g_object_set (G_OBJECT (cell),
204 "scancode", button_entry->scancode,
205 "style", PANGO_STYLE_NORMAL,
211 cb_key_edited(GtkCellRendererText *cell, const char *path_string,
212 guint scancode, gpointer data)
214 GtkTreePath *path = gtk_tree_path_new_from_string(path_string);
216 ButtonEntry *button_entry;
218 gtk_tree_model_get_iter(GTK_TREE_MODEL(keys_store), &iter, path);
219 gtk_tree_model_get(GTK_TREE_MODEL(keys_store), &iter,
220 BUTTONENTRY_COLUMN, &button_entry,
223 button_entry->scancode = scancode;
224 button_entry->changed = TRUE;
226 gtk_tree_model_row_changed(GTK_TREE_MODEL(keys_store), path, &iter);
227 gtk_tree_path_free(path);
231 cb_key_cleared(GtkCellRendererText *cell, const char *path_string,
234 GtkTreePath *path = gtk_tree_path_new_from_string(path_string);
236 ButtonEntry *button_entry;
238 gtk_tree_model_get_iter(GTK_TREE_MODEL(keys_store), &iter, path);
239 gtk_tree_model_get(GTK_TREE_MODEL(keys_store), &iter,
240 BUTTONENTRY_COLUMN, &button_entry,
243 button_entry->scancode = 0;
244 button_entry->changed = TRUE;
246 gtk_tree_model_row_changed(GTK_TREE_MODEL(keys_store), path, &iter);
247 gtk_tree_path_free(path);
250 static void cb_dialog_response(GtkWidget * sender, gint response, gpointer data)
252 if (response == DIALOG_RESPONSE_DEFAULTS) {
253 get_default_settings();
257 if (response == GTK_RESPONSE_OK) {
261 gtk_widget_destroy(GTK_WIDGET(dialog));
264 void keys_dialog(GtkWindow* parent, int player)
266 gchar* title = g_strdup_printf(_("Player %d keys"), player);
267 dialog = GTK_DIALOG(gtk_dialog_new_with_buttons(title,
268 parent, GTK_DIALOG_MODAL,
269 _("Defaults"), DIALOG_RESPONSE_DEFAULTS,
270 GTK_STOCK_SAVE, GTK_RESPONSE_OK,
271 GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL));
274 current_player = player;
276 keys_store = GTK_LIST_STORE(gtk_list_store_new(N_COLUMNS,
277 G_TYPE_STRING, G_TYPE_POINTER));
278 #if MAEMO_VERSION >= 5
279 keys_list = GTK_TREE_VIEW(hildon_gtk_tree_view_new_with_model(
280 HILDON_UI_MODE_EDIT, GTK_TREE_MODEL(keys_store)));
281 keys_scroll = HILDON_PANNABLE_AREA(hildon_pannable_area_new());
283 keys_list = GTK_TREE_VIEW(
284 gtk_tree_view_new_with_model(GTK_TREE_MODEL(keys_store)));
285 keys_scroll = GTK_SCROLLED_WINDOW(gtk_scrolled_window_new(NULL, NULL));
286 gtk_scrolled_window_set_policy(keys_scroll,
287 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
290 GtkCellRenderer* renderer = GTK_CELL_RENDERER(gtk_cell_renderer_text_new());
291 GtkTreeViewColumn * column =
292 gtk_tree_view_column_new_with_attributes ("Button",
293 gtk_cell_renderer_text_new(),
294 "text", BUTTON_COLUMN,
296 gtk_tree_view_column_set_resizable(column, FALSE);
297 gtk_tree_view_column_set_expand(column, TRUE);
298 gtk_tree_view_append_column(keys_list, column);
300 renderer = GTK_CELL_RENDERER(cell_renderer_key_new());
301 column = gtk_tree_view_column_new_with_attributes("Key", renderer, NULL);
302 gtk_tree_view_column_set_cell_data_func(column, renderer, accel_set_func, NULL, NULL);
303 gtk_tree_view_column_set_resizable(column, FALSE);
304 #if MAEMO_VERSION >= 5
305 gtk_tree_view_column_set_min_width(column, 340);
307 gtk_tree_view_column_set_min_width(column, 250);
309 gtk_tree_view_append_column(keys_list, column);
310 gtk_tree_view_set_headers_visible(keys_list, TRUE);
313 for (i = 0; buttons[i].name; i++) {
315 gtk_list_store_append(keys_store, &iter);
316 gtk_list_store_set(keys_store, &iter,
317 BUTTON_COLUMN, buttons[i].name,
318 BUTTONENTRY_COLUMN, &buttons[i],
322 #if MAEMO_VERSION >= 5
323 gtk_window_resize(GTK_WINDOW(dialog), 800, 340);
325 gtk_window_resize(GTK_WINDOW(dialog), 600, 340);
327 gtk_container_add(GTK_CONTAINER(keys_scroll), GTK_WIDGET(keys_list));
328 gtk_box_pack_start_defaults(GTK_BOX(dialog->vbox), GTK_WIDGET(keys_scroll));
332 g_signal_connect(G_OBJECT(dialog), "response",
333 G_CALLBACK (cb_dialog_response), NULL);
334 g_signal_connect(G_OBJECT(renderer), "accel_edited",
335 G_CALLBACK(cb_key_edited), NULL);
336 g_signal_connect(G_OBJECT(renderer), "accel_cleared",
337 G_CALLBACK(cb_key_cleared), NULL);
339 gtk_widget_show_all(GTK_WIDGET(dialog));