gliv-1.6
[gliv.git] / src / options.c
blob53321f09595738295cee15a805258201cc2f1bf4
1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16 * See the COPYING file for license information.
18 * Guillaume Chazarain <gfc@altern.org>
21 /******************************
22 * User configurable options. *
23 ******************************/
25 #include "gliv.h"
27 #include <string.h> /* memcmp() */
28 #include <gdk/gdkkeysyms.h> /* GDK_Escape, GDK_c, GDK_C, GDK_o, GDK_O */
30 extern rt_struct *rt;
31 extern options_struct *options;
32 extern gliv_image *current_image;
33 extern GtkWidget *gl_widget;
35 static GtkTable *buttons;
36 static options_struct *new_options;
37 static GtkWindow *options_win = NULL;
39 static GtkColorSelection *color_sel;
40 static gint *col_choice = NULL;
42 static gboolean save_options = FALSE;
44 static void toggle_delay(void)
46 gint events;
48 if (options->delay == 0)
49 /* Enable. */
50 gtk_widget_add_events(gl_widget, GDK_POINTER_MOTION_MASK);
52 else if (new_options->delay == 0) {
53 /* Disable. */
54 events = gtk_widget_get_events(gl_widget) & ~GDK_POINTER_MOTION_MASK;
55 gdk_window_set_events(gl_widget->window, events);
58 options->delay = new_options->delay;
59 schedule_hide_cursor();
62 static void toggle_history(void)
64 gboolean enable;
66 if (options->history_size == 0)
67 enable = TRUE;
68 else if (new_options->history_size == 0)
69 enable = FALSE;
70 else
71 return;
73 options->history_size = new_options->history_size;
75 if (enable)
76 init_history();
77 else
78 clear_history();
81 static void finish(gboolean apply)
83 guchar what = 0;
84 gboolean bg_color_changed;
86 gtk_widget_hide(GTK_WIDGET(options_win));
88 if (apply) {
90 if (options->fullscreen != new_options->fullscreen)
91 toggle_fullscreen(new_options->fullscreen);
93 if ((options->maximize == FALSE && new_options->maximize == TRUE) ||
94 (options->scaledown == FALSE && new_options->scaledown == TRUE)) {
96 options->maximize = new_options->maximize;
97 options->scaledown = new_options->scaledown;
99 matrix_set_max_zoom(-1, -1, TRUE);
100 what |= REFRESH_IMAGE | REFRESH_STATUS | APPEND_HISTORY;
103 if (options->menu_bar != new_options->menu_bar)
104 toggle_menu_bar();
106 if (options->status_bar != new_options->status_bar)
107 toggle_status_bar();
109 if (options->scrollbars != new_options->scrollbars)
110 toggle_scrollbars();
112 if (options->dither != new_options->dither ||
113 options->mipmap != new_options->mipmap) {
115 options->dither = new_options->dither;
116 options->mipmap = new_options->mipmap;
118 reload_all_images();
119 what |= REFRESH_IMAGE;
122 if (options->delay != new_options->delay)
123 toggle_delay();
125 if (options->history_size != new_options->history_size)
126 toggle_history();
128 bg_color_changed = (memcmp(options->bg_col, new_options->bg_col,
129 3 * sizeof(gint)) != 0);
131 if (memcmp(options->alpha1, new_options->alpha1, 6 * sizeof(gint))) {
132 /* 6: alpha1 and alpha2 */
133 rt->alpha_checks_changed = TRUE;
135 if (current_image != NULL && current_image->has_alpha)
136 what |= REFRESH_IMAGE;
139 g_free(options);
140 options = new_options;
142 if (save_options)
143 save_rc(options);
145 if (bg_color_changed) {
146 update_bg_color(TRUE);
147 what |= REFRESH_IMAGE;
149 } else
150 g_free(new_options);
152 gtk_widget_destroy(GTK_WIDGET(options_win));
153 options_win = NULL;
155 refresh(what);
158 static gboolean toggle_button(GtkToggleButton * button, gboolean * bool)
160 *bool = gtk_toggle_button_get_active(button);
161 return TRUE;
164 static void add_button(const gchar * name, guint x, guint y, gboolean * value)
166 GtkCheckButton *button;
168 name = locale_to_utf8(add_mnemonic(name));
169 button = GTK_CHECK_BUTTON(gtk_check_button_new_with_mnemonic(name));
171 gtk_table_attach_defaults(buttons, GTK_WIDGET(button), x, x + 1, y, y + 1);
172 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), *value);
173 g_signal_connect(button, "toggled", G_CALLBACK(toggle_button), value);
175 gtk_widget_show(GTK_WIDGET(button));
178 static gboolean value_changed(GtkAdjustment * widget, gint * val)
180 *val = (gint) gtk_adjustment_get_value(widget);
181 return TRUE;
184 static void add_spin_button(const gchar * text, guint pos, gint * value,
185 gdouble minimum)
187 GtkSpinButton *button;
188 GtkAdjustment *adjustment;
189 GtkLabel *label;
191 adjustment = GTK_ADJUSTMENT(gtk_adjustment_new((gdouble) (*value), minimum,
192 1e9, 1.0, 10.0, 10.0));
194 g_signal_connect(adjustment, "value_changed",
195 G_CALLBACK(value_changed), value);
197 label = GTK_LABEL(gtk_label_new(locale_to_utf8(text)));
199 button = GTK_SPIN_BUTTON(gtk_spin_button_new(adjustment, 1.0, 0));
200 gtk_spin_button_set_update_policy(button, GTK_UPDATE_IF_VALID);
201 gtk_spin_button_set_numeric(button, TRUE);
203 gtk_table_attach_defaults(buttons, GTK_WIDGET(label), 0, 1, pos, pos + 1);
204 gtk_table_attach_defaults(buttons, GTK_WIDGET(button), 1, 2, pos, pos + 1);
206 gtk_widget_show(GTK_WIDGET(button));
209 static gboolean key_press_event(GtkWidget * unused, GdkEventKey * event)
211 if (event->keyval == GDK_Escape) {
212 finish(FALSE);
213 return TRUE;
216 return FALSE;
219 /* One of the three radio buttons was activated. */
220 static void change_color_sel(gint * col)
222 GdkColor new_color;
224 if (col_choice == col)
225 return;
227 col_choice = col;
229 new_color.red = col[0];
230 new_color.green = col[1];
231 new_color.blue = col[2];
233 gtk_color_selection_set_current_color(color_sel, &new_color);
236 static void add_color_radio(const gchar * label, gint * color,
237 GtkHBox * container)
239 GtkRadioButton *radio;
240 gpointer parent;
242 parent = gtk_container_get_children(GTK_CONTAINER(container));
243 if (parent != NULL)
244 parent = ((GList *) parent)->data;
246 label = locale_to_utf8(add_mnemonic(label));
247 radio = GTK_RADIO_BUTTON(gtk_radio_button_new_with_mnemonic_from_widget
248 (parent, label));
250 g_signal_connect_swapped(radio, "pressed", G_CALLBACK(change_color_sel),
251 color);
253 gtk_box_pack_start_defaults(GTK_BOX(container), GTK_WIDGET(radio));
255 gtk_widget_show(GTK_WIDGET(radio));
258 static void add_widget(GtkWidget * widget, guint * pos)
260 gtk_table_attach_defaults(buttons, widget, 0, 2, *pos, *pos + 1);
261 (*pos)++;
263 gtk_widget_show(widget);
266 static void color_changed(void)
268 GdkColor col;
270 gtk_color_selection_get_current_color(color_sel, &col);
272 col_choice[0] = col.red;
273 col_choice[1] = col.green;
274 col_choice[2] = col.blue;
277 static void add_color_selection(guint * pos)
279 GtkHBox *color_radio;
281 color_sel = GTK_COLOR_SELECTION(gtk_color_selection_new());
283 /* Hide opacity choice. */
284 g_signal_connect(color_sel, "map",
285 G_CALLBACK(gtk_color_selection_set_has_opacity_control),
286 GINT_TO_POINTER(FALSE));
288 change_color_sel(new_options->bg_col);
289 g_signal_connect(color_sel, "color-changed",
290 G_CALLBACK(color_changed), NULL);
292 add_widget(GTK_WIDGET(color_sel), pos);
294 color_radio = GTK_HBOX(gtk_hbox_new(FALSE, 10));
296 add_color_radio(_("Background"), new_options->bg_col, color_radio);
297 add_color_radio(_("Alpha 1"), new_options->alpha1, color_radio);
298 add_color_radio(_("Alpha 2"), new_options->alpha2, color_radio);
300 add_widget(GTK_WIDGET(color_radio), pos);
303 static void create_buttons(void)
305 GtkButton *ok_button;
306 GtkButton *cancel_button;
307 const gchar *label;
308 guint pos = 0; /* Vertical position. */
310 new_options = g_memdup(options, sizeof(options_struct));
312 buttons = GTK_TABLE(gtk_table_new(0, 0, FALSE));
313 gtk_table_set_row_spacings(buttons, 5);
314 gtk_table_set_col_spacings(buttons, 0);
316 add_button(_("Fullscreen mode"), 0, pos, &new_options->fullscreen);
317 add_button(_("Zoom centered on pointer"), 1, pos++,
318 &new_options->zoom_pointer);
319 add_button(_("Menu bar enabled"), 0, pos, &new_options->menu_bar);
320 add_button(_("Status bar enabled"), 1, pos++, &new_options->status_bar);
321 add_button(_("Scrollbars enabled"), 0, pos, &new_options->scrollbars);
322 add_button(_("Alpha checks"), 1, pos++, &new_options->alpha_checks);
323 add_button(_("Scale down large images"), 0, pos, &new_options->scaledown);
324 add_button(_("Maximize small images"), 1, pos++, &new_options->maximize);
325 add_button(_("Dithering"), 0, pos, &new_options->dither);
326 add_button(_("Build Mipmaps"), 1, pos++, &new_options->mipmap);
327 add_button(_("Try to load every file"), 0, pos, &new_options->force);
328 add_button(_("Build images menus at startup"), 1, pos++,
329 &new_options->build_menus);
330 add_button(_("Save options in ~/.glivrc"), 0, pos++, &save_options);
332 add_spin_button(_("Delay before hiding the cursor\n0: feature disabled"),
333 pos++, &new_options->delay, 0.0);
335 add_spin_button(_("History length\n0: feature disabled\n-1: infinite"),
336 pos++, &new_options->history_size, -1.0);
338 gtk_widget_show(GTK_WIDGET(buttons));
340 /* The color selection. */
343 add_widget(gtk_hseparator_new(), &pos);
345 label = locale_to_utf8(_("Background and alpha checks color selection"));
346 add_widget(gtk_label_new(label), &pos);
348 add_color_selection(&pos);
350 /* The OK button. */
352 ok_button = GTK_BUTTON(gtk_button_new_from_stock(GTK_STOCK_OK));
354 GTK_WIDGET_SET_FLAGS(GTK_WIDGET(ok_button), GTK_CAN_DEFAULT);
355 g_signal_connect_swapped(ok_button, "clicked",
356 G_CALLBACK(finish), GINT_TO_POINTER(TRUE));
358 gtk_table_attach_defaults(buttons, GTK_WIDGET(ok_button), 0, 1,
359 pos, pos + 1);
361 gtk_widget_show(GTK_WIDGET(ok_button));
363 /* The Cancel button. */
365 cancel_button = GTK_BUTTON(gtk_button_new_from_stock(GTK_STOCK_CANCEL));
367 g_signal_connect_swapped(cancel_button, "clicked",
368 G_CALLBACK(finish), GINT_TO_POINTER(FALSE));
370 gtk_table_attach_defaults(buttons, GTK_WIDGET(cancel_button), 1, 2,
371 pos, pos + 1);
373 gtk_widget_show(GTK_WIDGET(cancel_button));
375 /* Misc. */
377 g_signal_connect_swapped(options_win, "delete_event",
378 G_CALLBACK(finish), GINT_TO_POINTER(FALSE));
380 g_signal_connect(options_win, "key_press_event",
381 G_CALLBACK(key_press_event), NULL);
383 gtk_container_set_border_width(GTK_CONTAINER(options_win), 10);
384 gtk_container_add(GTK_CONTAINER(options_win), GTK_WIDGET(buttons));
386 gtk_widget_grab_default(GTK_WIDGET(ok_button));
389 void show_options(void)
391 if (options_win != NULL)
392 return;
394 options_win = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
396 create_buttons();
397 show_dialog(GTK_WIDGET(options_win), _("Options"), TRUE);