gliv-1.7
[gliv.git] / src / menus.c
blob2cc1581d732d4dbd3ded2bf536ce6addc895a9cd
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 * The menubar. *
23 ****************/
25 #include "gliv.h"
27 #include <gdk/gdkkeysyms.h> /* GDK_* */
29 extern options_struct *options;
30 extern GtkMenuBar *menu_bar;
32 void set_menu_label(GtkMenuItem * item, const gchar * text, gboolean mnemonic)
34 GList *children;
36 children = gtk_container_get_children(GTK_CONTAINER(item));
37 while (children != NULL && GTK_IS_ACCEL_LABEL(children->data) == FALSE)
38 children = children->next;
40 if (children != NULL) {
41 GtkLabel *label = children->data;
43 if (mnemonic)
44 gtk_label_set_text_with_mnemonic(GTK_LABEL(label),
45 add_mnemonic(text));
46 else
47 gtk_label_set_text(GTK_LABEL(label), text);
51 static GtkMenuShell *add_menu(const gchar * name)
53 GtkMenuShell *menu;
54 GtkMenuItem *item;
56 name = add_mnemonic(name);
57 item = GTK_MENU_ITEM(gtk_menu_item_new_with_mnemonic(name));
58 gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), GTK_WIDGET(item));
60 menu = GTK_MENU_SHELL(gtk_menu_new());
61 gtk_menu_shell_append(menu, gtk_tearoff_menu_item_new());
62 gtk_menu_item_set_submenu(item, GTK_WIDGET(menu));
64 return menu;
67 static GtkMenuItem *add_menu_item(GtkMenuShell * menu,
68 GtkAccelGroup * accel_group,
69 const gchar * menu_name, const gchar * name,
70 GCallback func, guint key, gpointer data)
72 GtkMenuItem *menu_item;
73 GdkModifierType mod;
74 gchar *accel_path;
75 const gchar *menu_item_name;
77 menu_item_name = add_mnemonic(name);
78 menu_item = GTK_MENU_ITEM(gtk_menu_item_new_with_mnemonic(menu_item_name));
80 gtk_menu_shell_append(menu, GTK_WIDGET(menu_item));
81 g_signal_connect_swapped(menu_item, "activate", func, data);
83 mod = (key >= GDK_A && key <= GDK_Z) ? GDK_SHIFT_MASK : 0;
85 accel_path = g_strconcat("<GLiv>/", menu_name, "/", name, NULL);
86 gtk_accel_map_add_entry(accel_path, key, mod);
87 gtk_menu_item_set_accel_path(menu_item, accel_path);
88 g_free(accel_path);
90 return menu_item;
93 static void toggle_alpha_checks(void)
95 options->alpha_checks ^= TRUE;
96 refresh(REFRESH_IMAGE);
99 static void menu_fullscreen(void)
101 toggle_fullscreen(!options->fullscreen);
104 #define MAXIMIZE (1 << 0)
105 #define SCALE_DOWN (1 << 1)
107 static void menu_maximize(gint what)
109 gboolean old_maximize, old_scale_down;
111 old_maximize = options->maximize;
112 old_scale_down = options->scaledown;
114 options->maximize = ((what & MAXIMIZE) != 0);
115 options->scaledown = ((what & SCALE_DOWN) != 0);
117 matrix_set_max_zoom(-1, -1, TRUE);
119 options->maximize = old_maximize;
120 options->scaledown = old_scale_down;
122 refresh(REFRESH_IMAGE | REFRESH_STATUS | APPEND_HISTORY);
125 enum {
126 TRANSFORMATION_MOVE_LEFT,
127 TRANSFORMATION_MOVE_RIGHT,
128 TRANSFORMATION_MOVE_UP,
129 TRANSFORMATION_MOVE_DOWN,
130 /* --- */
131 TRANSFORMATION_ROTATE_BIG_PLUS,
132 TRANSFORMATION_ROTATE_BIG_MINUS,
133 TRANSFORMATION_ROTATE_SMALL_PLUS,
134 TRANSFORMATION_ROTATE_SMALL_MINUS,
135 /* --- */
136 TRANSFORMATION_ZOOM_IN,
137 TRANSFORMATION_ZOOM_OUT,
138 TRANSFORMATION_FLIP_H,
139 TRANSFORMATION_FLIP_V,
140 TRANSFORMATION_RESET
143 static guchar menu_move(guchar action)
145 switch (action) {
146 case TRANSFORMATION_MOVE_LEFT:
147 matrix_move(MOVE_OFFSET, 0.0);
148 break;
150 case TRANSFORMATION_MOVE_RIGHT:
151 matrix_move(-MOVE_OFFSET, 0.0);
152 break;
154 case TRANSFORMATION_MOVE_UP:
155 matrix_move(0.0, MOVE_OFFSET);
156 break;
158 /* case TRANSFORMATION_MOVE_DOWN: */
159 default:
160 matrix_move(0.0, -MOVE_OFFSET);
163 return REFRESH_IMAGE | APPEND_HISTORY;
166 static guchar menu_rotate(guchar action)
168 switch (action) {
169 case TRANSFORMATION_ROTATE_BIG_PLUS:
170 matrix_rotate(BIG_ROTATION);
171 break;
173 case TRANSFORMATION_ROTATE_BIG_MINUS:
174 matrix_rotate(-BIG_ROTATION);
175 break;
177 case TRANSFORMATION_ROTATE_SMALL_PLUS:
178 matrix_rotate(SMALL_ROTATION);
179 break;
181 /* case TRANSFORMATION_ROTATE_SMALL_MINUS: */
182 default:
183 matrix_rotate(-SMALL_ROTATION);
186 return REFRESH_IMAGE | REFRESH_STATUS | APPEND_HISTORY;
189 static void menu_zoom(guchar action)
191 gboolean zoom_pointer;
193 zoom_pointer = options->zoom_pointer;
194 options->zoom_pointer = FALSE;
196 if (action == TRANSFORMATION_ZOOM_IN)
197 zoom_in(ZOOM_FACTOR);
198 else
199 zoom_in(1.0 / ZOOM_FACTOR);
201 options->zoom_pointer = zoom_pointer;
204 static void menu_transformation(guchar action)
206 gint what = 0;
208 switch (action) {
209 case TRANSFORMATION_MOVE_LEFT:
210 case TRANSFORMATION_MOVE_RIGHT:
211 case TRANSFORMATION_MOVE_UP:
212 case TRANSFORMATION_MOVE_DOWN:
213 what = menu_move(action);
214 break;
216 case TRANSFORMATION_ROTATE_BIG_PLUS:
217 case TRANSFORMATION_ROTATE_BIG_MINUS:
218 case TRANSFORMATION_ROTATE_SMALL_PLUS:
219 case TRANSFORMATION_ROTATE_SMALL_MINUS:
220 what = menu_rotate(action);
221 break;
223 case TRANSFORMATION_ZOOM_IN:
224 case TRANSFORMATION_ZOOM_OUT:
225 menu_zoom(action);
226 break;
228 case TRANSFORMATION_FLIP_H:
229 matrix_flip_h();
230 what = REFRESH_IMAGE | REFRESH_STATUS | APPEND_HISTORY;
231 break;
233 case TRANSFORMATION_FLIP_V:
234 matrix_flip_v();
235 what = REFRESH_IMAGE | REFRESH_STATUS | APPEND_HISTORY;
236 break;
238 /* case TRANSFORMATION_RESET: */
239 default:
240 matrix_reset();
241 what = REFRESH_IMAGE | REFRESH_STATUS | APPEND_HISTORY;
244 refresh(what);
247 #define SEPARATOR gtk_menu_shell_append(submenu, gtk_separator_menu_item_new())
249 #define ADD_MENU_ITEM(str, signal_func, key, val) \
250 add_menu_item(submenu, accel_group, menu_name, str, \
251 G_CALLBACK(signal_func), key, GINT_TO_POINTER(val))
253 #define ADD_MENU(str) \
254 do { \
255 submenu = add_menu(str); \
256 menu_name = str; \
257 gtk_menu_set_accel_group(GTK_MENU(submenu), accel_group); \
258 } while (0)
260 static GtkMenuItem *add_special_menu(GtkAccelGroup * accel_group,
261 const gchar * name, GCallback rebuild_menu)
263 GList *children;
264 GtkMenuShell *submenu;
265 GtkMenuItem *item;
266 gchar *menu_name = NULL;
268 submenu = add_menu(name);
270 children = gtk_container_get_children(GTK_CONTAINER(submenu));
271 item = GTK_MENU_ITEM(gtk_menu_get_attach_widget(GTK_MENU(submenu)));
272 g_list_free(children);
274 if (options->build_menus == FALSE || get_list_length() == 0)
275 ADD_MENU_ITEM(_("Rebuild this menu"), rebuild_menu, 0, 0);
277 return item;
280 #define ADD_SPECIAL_MENU(str, cb) cb(add_special_menu(accel_group, str, \
281 G_CALLBACK(cb)))
283 GtkAccelGroup *create_menus(void)
285 GtkMenuShell *submenu;
286 GtkAccelGroup *accel_group;
287 GtkMenuItem *item;
288 gchar *menu_name;
290 menu_bar = GTK_MENU_BAR(gtk_menu_bar_new());
291 accel_group = gtk_accel_group_new();
293 gtk_settings_set_long_property(gtk_settings_get_default(),
294 "gtk-can-change-accels", 1, "GLiv");
296 /* File menu. */
297 ADD_MENU(_("File"));
298 ADD_MENU_ITEM(_("Open..."), menu_open, GDK_o, 0);
299 ADD_MENU_ITEM(_("Quit"), quit, GDK_q, 0);
301 /* Commands menu. */
302 ADD_MENU(_("Commands"));
303 ADD_MENU_ITEM(_("Maximize small image"), menu_maximize, GDK_M, MAXIMIZE);
304 ADD_MENU_ITEM(_("Scale down large image"), menu_maximize, GDK_l,
305 SCALE_DOWN);
306 ADD_MENU_ITEM(_("Image fit window"), menu_maximize, GDK_m,
307 MAXIMIZE | SCALE_DOWN);
308 SEPARATOR; /* ------------------------------------ */
309 ADD_MENU_ITEM(_("Horizontal flip"), menu_transformation, GDK_z,
310 TRANSFORMATION_FLIP_H);
312 ADD_MENU_ITEM(_("Vertical flip"), menu_transformation, GDK_e,
313 TRANSFORMATION_FLIP_V);
314 SEPARATOR; /* ------------------------------------ */
315 ADD_MENU_ITEM(_("Load previous image"), load_direction, GDK_p, -1);
316 ADD_MENU_ITEM(_("Load next image"), load_direction, GDK_n, 1);
317 SEPARATOR; /* ------------------------------------ */
318 ADD_MENU_ITEM(_("Rebuild images menus"), rebuild_images_menus, 0, 0);
319 ADD_MENU_ITEM(_("Sort images list"), reorder_files, 0, FALSE);
320 ADD_MENU_ITEM(_("Shuffle images list"), reorder_files, 0, TRUE);
322 item = ADD_MENU_ITEM(_("Start the slide show"), toggle_slide_show, 0,
323 FALSE);
324 set_slide_show_menu(item);
326 ADD_MENU_ITEM(_("Remove the current file"), confirm_remove_current, GDK_x,
329 /* Transformations menu. */
330 ADD_MENU(_("Transformations"));
331 ADD_MENU_ITEM(_("Undo"), undo, GDK_u, 0);
332 ADD_MENU_ITEM(_("Redo"), redo, GDK_y, 0);
333 ADD_MENU_ITEM(_("Clear history"), clear_history, GDK_c, 0);
334 SEPARATOR; /* ------------------------------------ */
335 ADD_MENU_ITEM(_("Move left"), menu_transformation, 0,
336 TRANSFORMATION_MOVE_LEFT);
338 ADD_MENU_ITEM(_("Move right"), menu_transformation, 0,
339 TRANSFORMATION_MOVE_RIGHT);
341 ADD_MENU_ITEM(_("Move up"), menu_transformation, 0, TRANSFORMATION_MOVE_UP);
343 ADD_MENU_ITEM(_("Move down"), menu_transformation, 0,
344 TRANSFORMATION_MOVE_DOWN);
346 SEPARATOR; /* ------------------------------------ */
348 ADD_MENU_ITEM(_("Rotate +45 deg"), menu_transformation, 0,
349 TRANSFORMATION_ROTATE_BIG_PLUS);
351 ADD_MENU_ITEM(_("Rotate -45 deg"), menu_transformation, 0,
352 TRANSFORMATION_ROTATE_BIG_MINUS);
354 ADD_MENU_ITEM(_("Rotate +0.1 deg"), menu_transformation, 0,
355 TRANSFORMATION_ROTATE_SMALL_PLUS);
357 ADD_MENU_ITEM(_("Rotate -0.1 deg"), menu_transformation, 0,
358 TRANSFORMATION_ROTATE_SMALL_MINUS);
360 SEPARATOR; /* ------------------------------------ */
362 ADD_MENU_ITEM(_("Zoom in"), menu_transformation, 0, TRANSFORMATION_ZOOM_IN);
364 ADD_MENU_ITEM(_("Zoom out"), menu_transformation, 0,
365 TRANSFORMATION_ZOOM_OUT);
367 SEPARATOR; /* ------------------------------------ */
369 ADD_MENU_ITEM(_("Reset"), menu_transformation, GDK_r, TRANSFORMATION_RESET);
371 /* Options menu. */
372 ADD_MENU(_("Options"));
373 ADD_MENU_ITEM(_("Toggle Fullscreen mode"), menu_fullscreen, GDK_f, 0);
374 ADD_MENU_ITEM(_("Toggle Menu Bar"), toggle_menu_bar, GDK_b, 0);
375 ADD_MENU_ITEM(_("Toggle Status Bar"), toggle_status_bar, GDK_i, 0);
376 ADD_MENU_ITEM(_("Toggle Scrollbars"), toggle_scrollbars, GDK_s, 0);
377 ADD_MENU_ITEM(_("Toggle Alpha checks"), toggle_alpha_checks, GDK_a, 0);
378 SEPARATOR; /* ------------------------------------ */
379 ADD_MENU_ITEM(_("Hide the cursor"), toggle_cursor, GDK_d, FALSE);
380 SEPARATOR; /* ------------------------------------ */
381 ADD_MENU_ITEM(_("Options..."), show_options, GDK_t, 0);
383 /* Directories menu. */
384 ADD_SPECIAL_MENU(_("Directories"), rebuild_directories);
386 /* Images menu. */
387 ADD_SPECIAL_MENU(_("Images"), rebuild_images);
389 /* Menus rebuilding indicator. */
390 item = GTK_MENU_ITEM(gtk_menu_item_new_with_label(""));
391 set_rebuilding_entry(item);
392 gtk_widget_set_sensitive(GTK_WIDGET(item), FALSE);
393 gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), GTK_WIDGET(item));
395 /* Help menu. */
396 ADD_MENU(_("Help"));
397 ADD_MENU_ITEM(_("About..."), show_about_box, 0, 0);
398 ADD_MENU_ITEM(_("Controls..."), toggle_help, GDK_h, 0);
400 load_accelerators();
401 return accel_group;