0.8.0
[geeqie.git] / src / window.c
1 /*
2  * GQview image viewer
3  * (C)2000 John Ellis
4  *
5  * Author: John Ellis
6  *
7  */
8
9 #include "gqview.h"
10
11 #define MAINWINDOW_DEF_WIDTH 500
12 #define MAINWINDOW_DEF_HEIGHT 400
13 #define TOOLWINDOW_DEF_WIDTH 224
14 #define TOOLWINDOW_DEF_HEIGHT 450
15 #define LIST_DEFAULT_WIDTH -1
16 #define LIST_DEFAULT_HEIGHT 100
17
18 static GtkWidget *add_label(gchar *text, GtkWidget *box, gint start, gint size, gint expand);
19 static void info_area_create(GtkWidget *vbox);
20
21 static void toolwindow_create();
22 static void toolwindow_destroy();
23 static void toolwindow_show();
24
25 static void image_focus_paint(GtkWidget *widget);
26 static gint image_focus_expose (GtkWidget *widget, GdkEventExpose *event, gpointer data);
27 static gint image_focus_in_cb(GtkWidget *widget, GdkEventFocus *event, gpointer data);
28 static gint image_focus_out_cb(GtkWidget *widget, GdkEventFocus *event, gpointer data);
29
30 static void create_tools(GtkAccelGroup *accel_grp, GtkTooltips *tooltips);
31 static void mainwindow_destroy_cb(GtkWidget *widget, gpointer data);
32
33 /*
34  *-----------------------------------------------------------------------------
35  * information widget creation routines (private)
36  *-----------------------------------------------------------------------------
37  */ 
38
39 static GtkWidget *add_label(gchar *text, GtkWidget *box, gint start, gint size, gint expand)
40 {
41         GtkWidget *label;
42         GtkWidget *frame;
43
44         frame = gtk_frame_new (NULL);
45         if (size)
46                 gtk_widget_set_usize (frame, size, -1);
47         gtk_frame_set_shadow_type(GTK_FRAME(frame),GTK_SHADOW_IN);
48         if (start)
49                 gtk_box_pack_start(GTK_BOX(box), frame, expand, expand, 0);
50         else
51                 gtk_box_pack_end(GTK_BOX(box), frame, expand, expand, 0);
52         gtk_widget_show(frame);
53
54         label = gtk_label_new(text);
55         gtk_container_add (GTK_CONTAINER (frame), label);
56         gtk_widget_show(label);
57
58         return label;
59 }
60
61 static void info_area_create(GtkWidget *vbox)
62 {
63         gchar *status_text;
64         gchar *details_text;
65         gchar *zoom_text;
66         gchar *buf;
67
68         if (info_status)
69                 {
70                 gtk_label_get(GTK_LABEL(info_status), &buf);
71                 status_text = g_strdup(buf);
72
73                 gtk_label_get(GTK_LABEL(info_details), &buf);
74                 details_text = g_strdup(buf);
75
76                 gtk_label_get(GTK_LABEL(info_zoom), &buf);
77                 zoom_text = g_strdup(buf);
78                 }
79         else
80                 {
81                 status_text = g_strdup("");
82                 details_text = g_strdup("GQview");
83                 zoom_text = g_strdup(":");
84                 }
85
86         if (info_box)
87                 {
88                 gtk_widget_destroy(info_box);
89                 info_box = NULL;
90                 }
91
92         if (vbox)
93                 {
94                 GtkWidget *hbox;
95                 hbox = gtk_hbox_new(FALSE, 0);
96                 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
97                 gtk_widget_show(hbox);
98                         
99                 info_progress_bar = gtk_progress_bar_new();
100                 gtk_widget_set_usize(info_progress_bar,150,-1);
101                 gtk_box_pack_start (GTK_BOX (hbox), info_progress_bar, FALSE, FALSE, 0);
102                 gtk_widget_show(info_progress_bar);
103
104                 info_zoom = add_label(zoom_text, hbox, FALSE, 48, FALSE);
105
106                 info_status = add_label(status_text, vbox, TRUE, 0, FALSE);
107                 info_details = add_label(details_text, vbox, TRUE, 0, FALSE);
108                 }
109         else
110                 {
111                 info_box = gtk_hbox_new(FALSE, 0);
112
113                 info_progress_bar = gtk_progress_bar_new();
114                 gtk_widget_set_usize(info_progress_bar,150,-1);
115                 gtk_box_pack_start (GTK_BOX (info_box), info_progress_bar, FALSE, FALSE, 0);
116                 gtk_widget_show(info_progress_bar);
117
118                 info_status = add_label(status_text, info_box, TRUE, 0, TRUE);
119                 info_details = add_label(details_text, info_box, TRUE, 0, TRUE);
120                 info_zoom = add_label(zoom_text, info_box, FALSE, 48, FALSE);
121
122                 gtk_widget_show(info_box);
123                 }
124
125         image_set_labels(info_details, info_zoom);
126
127         g_free(status_text);
128         g_free(details_text);
129         g_free(zoom_text);
130 }
131
132 /*
133  *-----------------------------------------------------------------------------
134  * tool window create/show/hide routines (private)
135  *-----------------------------------------------------------------------------
136  */ 
137
138 static void toolwindow_destroy_cb(GtkWidget *widget, gpointer data)
139 {
140         toolwindow_float();
141 }
142
143 static void toolwindow_create()
144 {
145         GtkWidget *vbox;
146         GtkAllocation req_size;
147
148         toolwindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
149         gtk_signal_connect (GTK_OBJECT (toolwindow), "delete_event",(GtkSignalFunc) toolwindow_destroy_cb, NULL);
150         gtk_window_set_policy(GTK_WINDOW(toolwindow), TRUE, TRUE, FALSE);
151         gtk_window_set_title (GTK_WINDOW (toolwindow), _("GQview Tools"));
152         gtk_window_set_wmclass(GTK_WINDOW (toolwindow), "tools", "GQview");
153         gtk_container_border_width (GTK_CONTAINER (toolwindow), 0);
154         gtk_window_add_accel_group(GTK_WINDOW(toolwindow),mainwindow_accel_grp);
155
156         gtk_signal_connect(GTK_OBJECT(toolwindow), "key_press_event", GTK_SIGNAL_FUNC(key_press_cb), NULL);
157
158         if (save_window_positions)
159                 {
160                 gtk_window_set_default_size (GTK_WINDOW(toolwindow), float_window_w, float_window_h);
161                 gtk_widget_set_uposition(toolwindow, float_window_x, float_window_y);
162                 req_size.x = req_size.y = 0;
163                 req_size.width = float_window_w;
164                 req_size.height = float_window_h;
165                 }
166         else
167                 {
168                 gtk_window_set_default_size (GTK_WINDOW(toolwindow), TOOLWINDOW_DEF_WIDTH, TOOLWINDOW_DEF_HEIGHT);
169                 req_size.x = req_size.y = 0;
170                 req_size.width = TOOLWINDOW_DEF_WIDTH;
171                 req_size.height = TOOLWINDOW_DEF_HEIGHT;
172                 }
173         gtk_widget_size_allocate(toolwindow, &req_size);
174
175         vbox = gtk_vbox_new(FALSE, 0);
176         gtk_container_add(GTK_CONTAINER(toolwindow), vbox);
177
178         gtk_widget_realize(toolwindow);
179         gtk_widget_realize(vbox);
180
181         if (tool_vbox->parent)
182                 {
183                 gtk_widget_ref(tool_vbox);
184                 gtk_container_remove(GTK_CONTAINER(tool_vbox->parent), tool_vbox);
185                 gtk_box_pack_start(GTK_BOX(vbox), tool_vbox, TRUE, TRUE, 0);
186                 gtk_widget_unref(tool_vbox);
187                 }
188         else
189                 {
190                 gtk_box_pack_start(GTK_BOX(vbox), tool_vbox, TRUE, TRUE, 0);
191                 }
192
193         info_area_create(vbox);
194
195         gtk_widget_show_all(vbox);
196 }
197
198 static void toolwindow_destroy()
199 {
200         if (toolwindow && GTK_WIDGET_VISIBLE(toolwindow))
201                 {
202                 gdk_window_get_position (toolwindow->window, &float_window_x, &float_window_y);
203                 gdk_window_get_size(toolwindow->window, &float_window_w, &float_window_h);
204                 }
205
206         info_area_create(NULL);
207
208         gtk_widget_ref(tool_vbox);
209         gtk_container_remove(GTK_CONTAINER(tool_vbox->parent), tool_vbox);
210         gtk_box_pack_start(GTK_BOX(mainwindow_hbox), tool_vbox, FALSE, FALSE, 0);
211         gtk_widget_unref(tool_vbox);
212
213         gtk_box_pack_start(GTK_BOX(mainwindow_vbox), info_box, FALSE, FALSE, 0);
214         gtk_widget_destroy(toolwindow);
215         toolwindow = NULL;
216 }
217
218 static void toolwindow_show()
219 {
220         gtk_widget_show(toolwindow);
221         if (save_window_positions)
222                 gdk_window_move(toolwindow->window, float_window_x, float_window_y);
223
224 }
225
226 /*
227  *-----------------------------------------------------------------------------
228  * tool window hide/float routines (public)
229  *-----------------------------------------------------------------------------
230  */ 
231
232 void toolwindow_float()
233 {
234         if (toolwindow)
235                 {
236                 if (GTK_WIDGET_VISIBLE(toolwindow))
237                         {
238                         toolwindow_destroy();
239                         tools_float = FALSE;
240                         tools_hidden = FALSE;
241                         }
242                 else
243                         {
244                         toolwindow_show();
245                         tools_float = TRUE;
246                         tools_hidden = FALSE;
247                         }
248                 }
249         else
250                 {
251                 toolwindow_create();
252                 toolwindow_show();
253                 tools_float = TRUE;
254                 tools_hidden = FALSE;
255                 }
256 }
257
258 void toolwindow_hide()
259 {
260         if (toolwindow)
261                 {
262                 if (GTK_WIDGET_VISIBLE(toolwindow))
263                         {
264                         gtk_widget_hide(toolwindow);
265                         gdk_window_get_position (toolwindow->window, &float_window_x, &float_window_y);
266                         gdk_window_get_size(toolwindow->window, &float_window_w, &float_window_h);
267                         tools_hidden = TRUE;
268                         }
269                 else
270                         {
271                         if (tools_float)
272                                 toolwindow_show();
273                         else
274                                 toolwindow_destroy();
275                         tools_hidden = FALSE;
276                         }
277                 }
278         else
279                 {
280                 toolwindow_create();
281                 tools_hidden = TRUE;
282                 }
283 }
284
285 /*
286  *-----------------------------------------------------------------------------
287  * image viewport focus display (private)
288  *-----------------------------------------------------------------------------
289  */ 
290
291 static void image_focus_paint(GtkWidget *widget)
292 {
293         gint width, height;
294         gdk_window_get_size (widget->window, &width, &height);
295         gdk_draw_rectangle (widget->window,
296                             widget->style->black_gc,
297                             FALSE,
298                             0, 0, width - 1, height - 1);
299 }
300
301 static gint image_focus_expose (GtkWidget *widget, GdkEventExpose *event, gpointer data)
302 {
303         image_focus_paint (widget);
304         return TRUE;
305 }
306
307 static gint image_focus_in_cb(GtkWidget *widget, GdkEventFocus *event, gpointer data)
308 {
309         gtk_signal_connect_after (GTK_OBJECT (widget), "draw",
310                         GTK_SIGNAL_FUNC (image_focus_expose), NULL);
311         gtk_signal_connect (GTK_OBJECT (widget), "expose_event",
312                         GTK_SIGNAL_FUNC (image_focus_paint), NULL);
313         GTK_WIDGET_SET_FLAGS(widget, GTK_HAS_FOCUS);
314
315         gtk_widget_queue_draw (widget);
316         return FALSE;
317 }
318
319 static gint image_focus_out_cb(GtkWidget *widget, GdkEventFocus *event, gpointer data)
320 {
321         gtk_signal_disconnect_by_func (GTK_OBJECT (widget),
322                         GTK_SIGNAL_FUNC (image_focus_paint), NULL);
323         gtk_signal_disconnect_by_func (GTK_OBJECT (widget),
324                         GTK_SIGNAL_FUNC (image_focus_expose), NULL);
325         GTK_WIDGET_UNSET_FLAGS(widget, GTK_HAS_FOCUS);
326         gtk_widget_queue_clear (widget);
327         gtk_viewport_set_shadow_type (GTK_VIEWPORT(widget), GTK_SHADOW_IN);
328         return FALSE;
329 }
330
331 /*
332  *-----------------------------------------------------------------------------
333  * main window setup
334  *-----------------------------------------------------------------------------
335  */ 
336
337 static void create_tools(GtkAccelGroup *accel_grp, GtkTooltips *tooltips)
338 {
339         GtkWidget *menu_bar;
340         GtkWidget *button_bar;
341         GtkWidget *vpaned;
342         GtkWidget *scrolled;
343         GtkWidget *tabcomp;
344
345         tool_vbox = gtk_vbox_new(FALSE, 0);
346
347         menu_bar = create_menu_bar(accel_grp);
348         gtk_box_pack_start (GTK_BOX(tool_vbox), menu_bar,FALSE,FALSE,0);
349         gtk_widget_show(menu_bar);
350
351         button_bar = create_button_bar(tooltips);
352         gtk_box_pack_start (GTK_BOX(tool_vbox), button_bar,FALSE,FALSE,0);
353         gtk_widget_show(button_bar);
354
355         /* path entry */
356         tabcomp = tab_completion_new(&path_entry, mainwindow, NULL, path_entry_cb, NULL);
357         tab_completion_add_tab_func(path_entry, path_entry_tab_cb, NULL);
358         gtk_box_pack_start (GTK_BOX (tool_vbox), tabcomp, FALSE, FALSE, 0);
359         gtk_widget_show (tabcomp);
360
361         /* history button */
362         history_menu = gtk_option_menu_new ();
363         gtk_box_pack_start (GTK_BOX (tool_vbox), history_menu, FALSE, FALSE, 0);
364         gtk_widget_show (history_menu);
365
366         vpaned = gtk_vpaned_new ();
367         gtk_paned_handle_size (GTK_PANED(vpaned), 10);
368         gtk_paned_gutter_size (GTK_PANED(vpaned), 10);
369         gtk_box_pack_start (GTK_BOX (tool_vbox), vpaned, TRUE, TRUE, 0);
370         gtk_widget_show (vpaned);
371
372         /* dir list */
373         scrolled = gtk_scrolled_window_new(NULL, NULL);
374         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
375                                 GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
376         gtk_paned_add1 (GTK_PANED(vpaned), scrolled);
377         gtk_widget_show(scrolled);
378
379         dir_clist=gtk_clist_new(1);
380         gtk_signal_connect (GTK_OBJECT (dir_clist), "button_press_event",(GtkSignalFunc) dir_press_cb, NULL);
381         gtk_signal_connect (GTK_OBJECT (dir_clist), "select_row",(GtkSignalFunc) dir_select_cb, NULL);
382         gtk_clist_column_titles_passive (GTK_CLIST (dir_clist)); 
383         gtk_widget_set_usize(dir_clist, LIST_DEFAULT_WIDTH, LIST_DEFAULT_HEIGHT);
384         gtk_container_add (GTK_CONTAINER (scrolled), dir_clist);
385         gtk_widget_show(dir_clist);
386
387         /* file list */
388         scrolled = gtk_scrolled_window_new(NULL, NULL);
389         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
390                                 GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
391         gtk_paned_add2 (GTK_PANED(vpaned), scrolled);
392         gtk_widget_show(scrolled);
393
394         file_clist=gtk_clist_new(1);
395         gtk_clist_set_selection_mode(GTK_CLIST(file_clist), GTK_SELECTION_EXTENDED);
396         gtk_signal_connect (GTK_OBJECT (file_clist), "button_press_event",(GtkSignalFunc) file_press_cb, NULL);
397         gtk_signal_connect (GTK_OBJECT (file_clist), "select_row",(GtkSignalFunc) file_select_cb, NULL);
398         gtk_signal_connect_after (GTK_OBJECT (file_clist), "unselect_row",(GtkSignalFunc) file_unselect_cb, NULL);
399         gtk_clist_column_titles_passive (GTK_CLIST (file_clist)); 
400         gtk_widget_set_usize(file_clist, LIST_DEFAULT_WIDTH, LIST_DEFAULT_HEIGHT);
401         gtk_container_add (GTK_CONTAINER (scrolled), file_clist);
402         gtk_widget_show(file_clist);
403
404         gtk_widget_show(tool_vbox);
405 }
406
407 static void mainwindow_destroy_cb(GtkWidget *widget, gpointer data)
408 {
409         exit_gqview();
410 }
411
412 void create_main_window()
413 {
414         GtkWidget *image_window;
415         GtkAllocation req_size;
416         GtkTooltips *tooltips;
417         GdkColormap *colormap;
418         static GdkColor tooltip_color = { 0, 0xffff, 0xf9f9, 0xcbcb }; /*255 249 203*/
419
420         mainwindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
421         gtk_window_set_policy(GTK_WINDOW(mainwindow), TRUE, TRUE, FALSE);
422
423         gtk_signal_connect (GTK_OBJECT (mainwindow), "delete_event",(GtkSignalFunc) mainwindow_destroy_cb, NULL);
424
425         gtk_window_set_title(GTK_WINDOW (mainwindow), "GQview");
426         gtk_window_set_wmclass(GTK_WINDOW (mainwindow), "gqview", "GQview");
427         gtk_container_border_width (GTK_CONTAINER (mainwindow), 0);
428
429         gtk_signal_connect(GTK_OBJECT(mainwindow), "key_press_event", GTK_SIGNAL_FUNC(key_press_cb), NULL);
430
431         if (save_window_positions)
432                 {
433                 req_size.x = main_window_x;
434                 req_size.y = main_window_y;
435                 req_size.width = main_window_w;
436                 req_size.height = main_window_h;
437                 gtk_window_set_default_size (GTK_WINDOW(mainwindow), main_window_w, main_window_h);
438                 gtk_widget_set_uposition(mainwindow, main_window_x, main_window_y);
439
440                 }
441         else
442                 {
443                 req_size.x = 0;
444                 req_size.y = 0;
445                 req_size.width = MAINWINDOW_DEF_WIDTH;
446                 req_size.height = MAINWINDOW_DEF_HEIGHT;
447                 gtk_window_set_default_size (GTK_WINDOW(mainwindow), MAINWINDOW_DEF_WIDTH, MAINWINDOW_DEF_HEIGHT);
448                 }
449
450         gtk_widget_size_allocate(mainwindow, &req_size);
451
452         gtk_widget_realize(mainwindow);
453
454         mainwindow_accel_grp = gtk_accel_group_new ();
455         gtk_window_add_accel_group(GTK_WINDOW(mainwindow),mainwindow_accel_grp);
456
457         tooltips = gtk_tooltips_new();
458         colormap = gdk_window_get_colormap (mainwindow->window);
459         gdk_color_alloc (colormap, &tooltip_color);
460         gtk_tooltips_set_colors(tooltips, &tooltip_color, &mainwindow->style->fg[GTK_STATE_NORMAL]);
461
462         create_menu_popups();
463         create_tools(mainwindow_accel_grp, tooltips);
464
465         image_window = image_create();
466
467         mainwindow_vbox = gtk_vbox_new(FALSE, 0);
468         gtk_container_add (GTK_CONTAINER (mainwindow), mainwindow_vbox);
469         gtk_widget_show(mainwindow_vbox);
470
471         mainwindow_hbox = gtk_hbox_new(FALSE, 0);
472         gtk_box_pack_start(GTK_BOX(mainwindow_vbox), mainwindow_hbox, TRUE, TRUE, 0);
473         gtk_widget_show(mainwindow_hbox);
474
475         if (tools_float || tools_hidden)
476                 {
477                 toolwindow_create();
478                 if (!tools_hidden)
479                         {
480                         toolwindow_show();
481                         }
482                 }
483         else
484                 {
485                 info_area_create(NULL);
486                 gtk_box_pack_start(GTK_BOX(mainwindow_hbox), tool_vbox, FALSE, FALSE, 0);
487                 gtk_box_pack_start(GTK_BOX(mainwindow_vbox), info_box, FALSE, FALSE, 0);
488                 }
489
490         gtk_box_pack_end(GTK_BOX(mainwindow_hbox), image_window, TRUE, TRUE, 0);
491         gtk_widget_show_all(image_window);
492         
493         GTK_WIDGET_SET_FLAGS(main_image->viewport, GTK_CAN_FOCUS);
494         gtk_signal_connect(GTK_OBJECT(main_image->viewport), "focus_in_event", GTK_SIGNAL_FUNC(image_focus_in_cb), NULL);
495         gtk_signal_connect(GTK_OBJECT(main_image->viewport), "focus_out_event", GTK_SIGNAL_FUNC(image_focus_out_cb), NULL);
496
497         gtk_widget_show(mainwindow);
498
499         if (save_window_positions)
500                 gdk_window_move(mainwindow->window, main_window_x, main_window_y);
501 }
502