Mercurial > geeqie.yaz
annotate src/layout_config.c @ 943:b483d8cdedb6
improved updating of view_dir_tree
author | nadvornik |
---|---|
date | Sun, 27 Jul 2008 08:57:12 +0000 |
parents | 985fdfebd89e |
children | 4fe8f9656107 |
rev | line source |
---|---|
9 | 1 /* |
196 | 2 * Geeqie |
9 | 3 * (C) 2004 John Ellis |
475 | 4 * Copyright (C) 2008 The Geeqie Team |
9 | 5 * |
6 * Author: John Ellis | |
7 * | |
8 * This software is released under the GNU General Public License (GNU GPL). | |
9 * Please read the included file COPYING for more information. | |
10 * This software comes with no warranty of any kind, use at your own risk! | |
11 */ | |
12 | |
281 | 13 #include "main.h" |
9 | 14 #include "layout_config.h" |
15 | |
16 | |
17 #include "layout.h" | |
18 | |
19 #include "ui_misc.h" | |
20 | |
21 | |
22 enum { | |
23 COLUMN_TEXT = 0, | |
24 COLUMN_KEY | |
25 }; | |
26 | |
27 | |
28 typedef struct _LayoutStyle LayoutStyle; | |
29 struct _LayoutStyle | |
30 { | |
31 LayoutLocation a, b, c; | |
32 }; | |
33 | |
34 typedef struct _LayoutConfig LayoutConfig; | |
35 struct _LayoutConfig | |
36 { | |
37 GtkWidget *box; | |
38 | |
39 GList *style_widgets; | |
40 | |
41 GtkWidget *listview; | |
42 | |
43 gint style; | |
44 gint a, b, c; | |
45 }; | |
46 | |
47 | |
48 static LayoutStyle layout_config_styles[] = { | |
49 /* 1, 2, 3 */ | |
50 { LAYOUT_LEFT | LAYOUT_TOP, LAYOUT_LEFT | LAYOUT_BOTTOM, LAYOUT_RIGHT }, | |
51 { LAYOUT_LEFT | LAYOUT_TOP, LAYOUT_RIGHT | LAYOUT_TOP, LAYOUT_BOTTOM }, | |
52 { LAYOUT_LEFT, LAYOUT_RIGHT | LAYOUT_TOP, LAYOUT_RIGHT | LAYOUT_BOTTOM }, | |
53 { LAYOUT_TOP, LAYOUT_LEFT | LAYOUT_BOTTOM, LAYOUT_RIGHT | LAYOUT_BOTTOM } | |
54 }; | |
55 | |
513
985fdfebd89e
Remove whitespace between function name and first parenthesis for the sake of consistency. (pass 2)
zas_
parents:
475
diff
changeset
|
56 static gint layout_config_style_count = sizeof(layout_config_styles) / sizeof(LayoutStyle); |
9 | 57 |
58 static gchar *layout_titles[] = { N_("Tools"), N_("Files"), N_("Image") }; | |
59 | |
60 | |
61 static void layout_config_destroy(GtkWidget *widget, gpointer data) | |
62 { | |
63 LayoutConfig * lc = data; | |
64 | |
65 g_list_free(lc->style_widgets); | |
66 g_free(lc); | |
67 } | |
68 | |
69 static void layout_config_set_order(LayoutLocation l, gint n, | |
70 LayoutLocation *a, LayoutLocation *b, LayoutLocation *c) | |
71 { | |
72 switch (n) | |
73 { | |
74 case 0: | |
75 *a = l; | |
76 break; | |
77 case 1: | |
78 *b = l; | |
79 break; | |
80 case 2: default: | |
81 *c = l; | |
82 break; | |
83 } | |
84 } | |
85 | |
86 static void layout_config_from_data(gint style, gint oa, gint ob, gint oc, | |
87 LayoutLocation *la, LayoutLocation *lb, LayoutLocation *lc) | |
88 { | |
89 LayoutStyle ls; | |
90 | |
91 style = CLAMP(style, 0, layout_config_style_count); | |
92 | |
93 ls = layout_config_styles[style]; | |
94 | |
95 layout_config_set_order(ls.a, oa, la, lb, lc); | |
96 layout_config_set_order(ls.b, ob, la, lb, lc); | |
97 layout_config_set_order(ls.c, oc, la, lb, lc); | |
98 } | |
99 | |
100 void layout_config_parse(gint style, const gchar *order, | |
101 LayoutLocation *a, LayoutLocation *b, LayoutLocation *c) | |
102 { | |
103 gint na, nb, nc; | |
104 | |
105 layout_config_order_from_text(order, &na, &nb, &nc); | |
106 layout_config_from_data(style, na, nb, nc, a, b, c); | |
107 } | |
108 | |
109 static void layout_config_list_order_set(LayoutConfig *lc, gint src, gint dest) | |
110 { | |
111 GtkListStore *store; | |
112 GtkTreeIter iter; | |
113 gint valid; | |
114 gint n; | |
115 | |
116 store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(lc->listview))); | |
117 | |
118 n = 0; | |
119 valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter); | |
120 while (valid) | |
121 { | |
122 if (n == dest) | |
123 { | |
124 gtk_list_store_set(store, &iter, COLUMN_TEXT, _(layout_titles[src]), COLUMN_KEY, src, -1); | |
125 return; | |
126 } | |
127 n++; | |
128 valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter); | |
129 } | |
130 } | |
131 | |
132 static gint layout_config_list_order_get(LayoutConfig *lc, gint n) | |
133 { | |
134 GtkTreeModel *store; | |
135 GtkTreeIter iter; | |
136 gint valid; | |
137 gint c = 0; | |
442 | 138 |
9 | 139 store = gtk_tree_view_get_model(GTK_TREE_VIEW(lc->listview)); |
442 | 140 |
9 | 141 valid = gtk_tree_model_get_iter_first(store, &iter); |
142 while (valid) | |
143 { | |
144 if (c == n) | |
145 { | |
146 gint val; | |
147 gtk_tree_model_get(store, &iter, COLUMN_KEY, &val, -1); | |
148 return val; | |
149 } | |
150 c++; | |
151 valid = gtk_tree_model_iter_next(store, &iter); | |
152 } | |
153 return 0; | |
154 } | |
155 | |
156 void layout_config_set(GtkWidget *widget, gint style, const gchar *order) | |
157 { | |
158 LayoutConfig *lc; | |
159 GtkWidget *button; | |
160 gint a, b, c; | |
161 | |
162 lc = g_object_get_data(G_OBJECT(widget), "layout_config"); | |
163 | |
164 if (!lc) return; | |
165 | |
166 style = CLAMP(style, 0, layout_config_style_count); | |
167 button = g_list_nth_data(lc->style_widgets, style); | |
168 if (!button) return; | |
169 | |
170 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE); | |
171 | |
172 layout_config_order_from_text(order, &a, &b, &c); | |
173 | |
174 layout_config_list_order_set(lc, a, 0); | |
175 layout_config_list_order_set(lc, b, 1); | |
176 layout_config_list_order_set(lc, c, 2); | |
177 } | |
178 | |
179 gchar *layout_config_get(GtkWidget *widget, gint *style) | |
180 { | |
181 LayoutConfig *lc; | |
182 | |
183 lc = g_object_get_data(G_OBJECT(widget), "layout_config"); | |
184 | |
185 /* this should not happen */ | |
186 if (!lc) return NULL; | |
187 | |
188 *style = lc->style; | |
189 | |
190 lc->a = layout_config_list_order_get(lc, 0); | |
191 lc->b = layout_config_list_order_get(lc, 1); | |
192 lc->c = layout_config_list_order_get(lc, 2); | |
193 | |
194 return layout_config_order_to_text(lc->a, lc->b, lc->c); | |
195 } | |
196 | |
197 static void layout_config_widget_click_cb(GtkWidget *widget, gpointer data) | |
198 { | |
199 LayoutConfig *lc; | |
200 | |
201 lc = g_object_get_data(G_OBJECT(widget), "layout_config"); | |
442 | 202 |
9 | 203 if (lc) lc->style = GPOINTER_TO_INT(data); |
204 } | |
205 | |
206 static void layout_config_table_button(GtkWidget *table, LayoutLocation l, const gchar *text) | |
207 { | |
208 GtkWidget *button; | |
209 | |
210 gint x1, y1; | |
211 gint x2, y2; | |
212 | |
213 x1 = 0; | |
214 y1 = 0; | |
215 x2 = 2; | |
216 y2 = 2; | |
217 | |
218 if (l & LAYOUT_LEFT) x2 = 1; | |
219 if (l & LAYOUT_RIGHT) x1 = 1; | |
220 if (l & LAYOUT_TOP) y2 = 1; | |
221 if (l & LAYOUT_BOTTOM) y1 = 1; | |
222 | |
223 button = gtk_button_new_with_label(text); | |
224 gtk_widget_set_sensitive(button, FALSE); | |
225 GTK_WIDGET_UNSET_FLAGS(button, GTK_CAN_FOCUS); | |
226 gtk_table_attach_defaults(GTK_TABLE(table), button, x1, x2, y1, y2); | |
227 gtk_widget_show(button); | |
228 } | |
229 | |
230 #define LAYOUT_STYLE_SIZE 48 | |
231 | |
232 static GtkWidget *layout_config_widget(GtkWidget *group, GtkWidget *box, gint style, LayoutConfig *lc) | |
233 { | |
234 GtkWidget *table; | |
235 LayoutStyle ls; | |
236 | |
237 ls = layout_config_styles[style]; | |
238 | |
239 if (group) | |
240 { | |
241 group = gtk_radio_button_new(gtk_radio_button_get_group(GTK_RADIO_BUTTON(group))); | |
242 } | |
243 else | |
244 { | |
245 group = gtk_radio_button_new(NULL); | |
246 } | |
247 g_object_set_data(G_OBJECT(group), "layout_config", lc); | |
248 g_signal_connect(G_OBJECT(group), "clicked", | |
249 G_CALLBACK(layout_config_widget_click_cb), GINT_TO_POINTER(style)); | |
250 gtk_box_pack_start(GTK_BOX(box), group, FALSE, FALSE, 0); | |
251 | |
252 table = gtk_table_new(2, 2, TRUE); | |
253 | |
254 layout_config_table_button(table, ls.a, "1"); | |
255 layout_config_table_button(table, ls.b, "2"); | |
256 layout_config_table_button(table, ls.c, "3"); | |
257 | |
258 gtk_widget_set_size_request(table, LAYOUT_STYLE_SIZE, LAYOUT_STYLE_SIZE); | |
259 gtk_container_add(GTK_CONTAINER(group), table); | |
260 gtk_widget_show(table); | |
261 | |
262 gtk_widget_show(group); | |
442 | 263 |
9 | 264 return group; |
265 } | |
266 | |
267 #if 0 | |
268 static void layout_config_row_move(GtkWidget *clist, gint source_row, gint dest_row, gpointer data) | |
269 { | |
270 gchar *text; | |
271 gint i; | |
272 | |
273 for (i = 0; i < 3; i++) | |
274 { | |
275 text = g_strdup_printf("%d", i + 1); | |
276 gtk_clist_set_text(GTK_CLIST(clist), i, 0, text); | |
277 g_free(text); | |
278 } | |
279 } | |
280 #endif | |
281 | |
282 static void layout_config_number_cb(GtkTreeViewColumn *tree_column, GtkCellRenderer *cell, | |
283 GtkTreeModel *store, GtkTreeIter *iter, gpointer data) | |
284 { | |
285 GtkTreePath *tpath; | |
286 gint *indices; | |
287 gchar *buf; | |
288 | |
289 tpath = gtk_tree_model_get_path(store, iter); | |
290 indices = gtk_tree_path_get_indices(tpath); | |
291 buf = g_strdup_printf("%d", indices[0] + 1); | |
292 gtk_tree_path_free(tpath); | |
293 g_object_set(G_OBJECT(cell), "text", buf, NULL); | |
294 g_free(buf); | |
295 } | |
296 | |
297 GtkWidget *layout_config_new(void) | |
298 { | |
299 LayoutConfig *lc; | |
300 GtkWidget *hbox; | |
301 GtkWidget *group = NULL; | |
302 GtkWidget *scrolled; | |
303 GtkListStore *store; | |
304 GtkTreeViewColumn *column; | |
305 GtkCellRenderer *renderer; | |
306 gint i; | |
307 | |
308 lc = g_new0(LayoutConfig, 1); | |
309 | |
310 lc->box = gtk_vbox_new(FALSE, PREF_PAD_GAP); | |
311 g_object_set_data(G_OBJECT(lc->box), "layout_config", lc); | |
312 | |
313 g_signal_connect(G_OBJECT(lc->box), "destroy", | |
314 G_CALLBACK(layout_config_destroy), lc); | |
315 | |
316 hbox = gtk_hbox_new(TRUE, PREF_PAD_SPACE); | |
317 gtk_box_pack_start(GTK_BOX(lc->box), hbox, FALSE, FALSE, 0); | |
318 for (i = 0; i < layout_config_style_count; i++) | |
319 { | |
320 group = layout_config_widget(group, hbox, i, lc); | |
321 lc->style_widgets = g_list_append(lc->style_widgets, group); | |
322 } | |
323 gtk_widget_show(hbox); | |
324 | |
325 scrolled = gtk_scrolled_window_new(NULL, NULL); | |
326 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN); | |
327 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), | |
328 GTK_POLICY_NEVER, GTK_POLICY_NEVER); | |
329 gtk_box_pack_start(GTK_BOX(lc->box), scrolled, FALSE, FALSE, 0); | |
330 gtk_widget_show(scrolled); | |
331 | |
332 store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT); | |
333 lc->listview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store)); | |
334 g_object_unref(store); | |
335 | |
336 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(lc->listview), FALSE); | |
337 gtk_tree_view_set_enable_search(GTK_TREE_VIEW(lc->listview), FALSE); | |
338 gtk_tree_view_set_reorderable(GTK_TREE_VIEW(lc->listview), TRUE); | |
339 | |
340 column = gtk_tree_view_column_new(); | |
341 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE); | |
342 | |
343 renderer = gtk_cell_renderer_text_new(); | |
344 gtk_tree_view_column_pack_start(column, renderer, FALSE); | |
345 gtk_tree_view_column_set_cell_data_func(column, renderer, layout_config_number_cb, lc, NULL); | |
346 | |
347 renderer = gtk_cell_renderer_text_new(); | |
348 gtk_tree_view_column_pack_start(column, renderer, TRUE); | |
349 gtk_tree_view_column_add_attribute(column, renderer, "text", COLUMN_TEXT); | |
350 | |
351 gtk_tree_view_append_column(GTK_TREE_VIEW(lc->listview), column); | |
352 | |
353 for (i = 0; i < 3; i++) | |
354 { | |
355 GtkTreeIter iter; | |
356 | |
357 gtk_list_store_append(store, &iter); | |
358 gtk_list_store_set(store, &iter, COLUMN_TEXT, _(layout_titles[i]), COLUMN_KEY, i, -1); | |
359 } | |
442 | 360 |
9 | 361 gtk_container_add(GTK_CONTAINER(scrolled), lc->listview); |
362 gtk_widget_show(lc->listview); | |
363 | |
364 pref_label_new(lc->box, _("(drag to change order)")); | |
442 | 365 |
9 | 366 return lc->box; |
367 } | |
368 | |
369 static char num_to_text_char(gint n) | |
370 { | |
371 switch (n) | |
372 { | |
373 case 1: | |
374 return '2'; | |
375 break; | |
376 case 2: | |
377 return '3'; | |
378 break; | |
379 } | |
380 return '1'; | |
381 } | |
382 | |
383 gchar *layout_config_order_to_text(gint a, gint b, gint c) | |
384 { | |
385 gchar *text; | |
386 | |
387 text = g_strdup(" "); | |
388 | |
389 text[0] = num_to_text_char(a); | |
390 text[1] = num_to_text_char(b); | |
391 text[2] = num_to_text_char(c); | |
392 | |
393 return text; | |
394 } | |
395 | |
396 static gint text_char_to_num(const gchar *text, gint n) | |
397 { | |
398 if (text[n] == '3') return 2; | |
399 if (text[n] == '2') return 1; | |
400 return 0; | |
401 } | |
402 | |
403 void layout_config_order_from_text(const gchar *text, gint *a, gint *b, gint *c) | |
404 { | |
405 if (!text || strlen(text) < 3) | |
406 { | |
407 *a = 0; | |
408 *b = 1; | |
409 *c = 2; | |
410 } | |
411 else | |
412 { | |
413 *a = text_char_to_num(text, 0); | |
414 *b = text_char_to_num(text, 1); | |
415 *c = text_char_to_num(text, 2); | |
416 } | |
417 } |