1
|
1 /*
|
|
2 * GQview image viewer
|
|
3 * (C)1999 John Ellis
|
|
4 *
|
|
5 * Author: John Ellis
|
|
6 *
|
|
7 */
|
|
8
|
|
9 #include "gqview.h"
|
|
10 #include "image.h"
|
|
11 #include "icons/img_unknown.xpm"
|
|
12
|
|
13 static gchar *zoom_as_text(gint zoom, gfloat scale);
|
|
14 static void set_zoom_label(GtkWidget *label, gint zoom, gfloat scale);
|
|
15 static void set_info_label(GtkWidget *label, gint width, gint height, gint size, gint unknown);
|
|
16 static void set_window_title(ImageWindow *imd, gchar *text);
|
|
17
|
|
18 static gint image_area_size_top_window(ImageWindow *imd, gint w, gint h);
|
|
19
|
|
20 static void image_area_recalc_size(ImageWindow *imd, GtkAllocation *allocation);
|
|
21
|
|
22 static void image_area_redraw(ImageWindow *imd);
|
|
23 static gint image_area_size_cb(GtkWidget *widget, GtkAllocation *allocation, gpointer data);
|
|
24 static gint image_area_update_cb(GtkWidget *widget, GdkEventConfigure *event, gpointer data);
|
|
25
|
|
26 static void set_mouse_cursor (GdkWindow *window, gint icon);
|
|
27 static void image_area_mouse_moved(GtkWidget *widget, GdkEventButton *bevent, gpointer data);
|
|
28 static void image_area_mouse_pressed(GtkWidget *widget, GdkEventButton *bevent, gpointer data);
|
|
29 static void image_area_mouse_released(GtkWidget *widget, GdkEventButton *bevent, gpointer data);
|
|
30 static void image_area_mouse_drag(GtkWidget *widget, GdkDragContext *context, gpointer data);
|
|
31
|
|
32 /*
|
|
33 *-----------------------------------------------------------------------------
|
|
34 * image status widget update routines (private)
|
|
35 *-----------------------------------------------------------------------------
|
|
36 */
|
|
37
|
|
38 static gchar *zoom_as_text(gint zoom, gfloat scale)
|
|
39 {
|
|
40 gint l = 1;
|
|
41 gint r = 1;
|
|
42 gchar *approx = " ";
|
|
43 if (zoom > 1) l = zoom;
|
|
44 if (zoom < -1) r = -zoom;
|
|
45 if (zoom == 0 && scale != 0)
|
|
46 {
|
|
47 if (scale < 1) r = 1 / scale + 0.5;
|
|
48 approx = " ~";
|
|
49 }
|
|
50 return g_strdup_printf("%d :%s%d", l, approx, r);
|
|
51 }
|
|
52
|
|
53 static void set_zoom_label(GtkWidget *label, gint zoom, gfloat scale)
|
|
54 {
|
|
55 gchar *buf;
|
|
56 buf = zoom_as_text(zoom, scale);
|
|
57 gtk_label_set(GTK_LABEL(label), buf);
|
|
58 g_free(buf);
|
|
59 }
|
|
60
|
|
61 static void set_info_label(GtkWidget *label, gint width, gint height, gint size, gint unknown)
|
|
62 {
|
|
63 gchar buf[64];
|
|
64 if (unknown)
|
|
65 sprintf(buf, _("( ? x ? ) %d bytes"), size);
|
|
66 else
|
|
67 sprintf(buf, _("( %d x %d ) %d bytes"), width, height, size);
|
|
68 gtk_label_set(GTK_LABEL(label), buf);
|
|
69 }
|
|
70
|
|
71 static void set_window_title(ImageWindow *imd, gchar *text)
|
|
72 {
|
|
73 gchar *title = NULL;
|
|
74 if (!imd->top_window) return;
|
|
75
|
|
76 if (imd->title)
|
|
77 {
|
|
78 title = g_strconcat(imd->title, imd->image_name, text, NULL);
|
|
79 }
|
|
80 else
|
|
81 {
|
|
82 title = g_strconcat(imd->image_name, text, NULL);
|
|
83 }
|
|
84
|
|
85 gtk_window_set_title(GTK_WINDOW(imd->top_window), title);
|
|
86 g_free(title);
|
|
87 }
|
|
88
|
|
89 /*
|
|
90 *-----------------------------------------------------------------------------
|
|
91 * fit window to image utility (private)
|
|
92 *-----------------------------------------------------------------------------
|
|
93 */
|
|
94
|
|
95 static gint image_area_size_top_window(ImageWindow *imd, gint w, gint h)
|
|
96 {
|
|
97 if (!imd->top_window) return FALSE;
|
|
98 if (imd == full_screen_image) return FALSE;
|
|
99 if (imd == normal_image && !toolwindow) return FALSE;
|
|
100 if (!fit_window) return FALSE;
|
|
101
|
|
102 if (imd == normal_image)
|
|
103 {
|
|
104 /* account for border frame */
|
|
105 w += 4;
|
|
106 h += 4;
|
|
107 }
|
|
108
|
|
109 if (limit_window_size)
|
|
110 {
|
|
111 gint sw = gdk_screen_width() * max_window_size / 100;
|
|
112 gint sh = gdk_screen_height() * max_window_size / 100;
|
|
113
|
|
114 if (w > sw) w = sw;
|
|
115 if (h > sh) h = sh;
|
|
116 }
|
|
117
|
|
118 /* to cheat on a prob a little, don't resize if within 1 either way...
|
|
119 ...dumb off by 1 errors! ;) */
|
|
120
|
|
121 /* if (w >= (imd->top_window)->allocation.width - 1 &&
|
|
122 w <= (imd->top_window)->allocation.width + 1 &&
|
|
123 h >= (imd->top_window)->allocation.height - 1 &&
|
|
124 h <= (imd->top_window)->allocation.height + 1)
|
|
125 return FALSE;
|
|
126 */
|
|
127 if (debug) printf("auto sized to %d x %d\n", w, h);
|
|
128
|
|
129 gdk_window_resize(imd->top_window->window, w, h);
|
|
130 gtk_widget_set_usize(imd->top_window, w, h);
|
|
131
|
|
132 return TRUE;
|
|
133 }
|
|
134
|
|
135 /*
|
|
136 *-----------------------------------------------------------------------------
|
|
137 * image widget zoom/recalc routines
|
|
138 *-----------------------------------------------------------------------------
|
|
139 */
|
|
140
|
|
141 void image_area_scroll(ImageWindow *imd, gint x, gint y)
|
|
142 {
|
|
143 if (x != 0)
|
|
144 {
|
|
145 GtkAdjustment *h = gtk_viewport_get_hadjustment(GTK_VIEWPORT(imd->viewport));
|
|
146 gfloat val = h->value + x;
|
|
147 if (val < h->lower) val = h->lower;
|
|
148 if (val > h->upper - h->page_size) val = h->upper - h->page_size;
|
|
149 gtk_adjustment_set_value(GTK_ADJUSTMENT(h), val);
|
|
150 }
|
|
151
|
|
152 if (y != 0)
|
|
153 {
|
|
154 GtkAdjustment *v = gtk_viewport_get_vadjustment(GTK_VIEWPORT(imd->viewport));
|
|
155 gfloat val = v->value + y;
|
|
156 if (val < v->lower) val = v->lower;
|
|
157 if (val > v->upper - v->page_size) val = v->upper - v->page_size;
|
|
158 gtk_adjustment_set_value(GTK_ADJUSTMENT(v), val);
|
|
159 }
|
|
160 }
|
|
161
|
|
162 gint image_area_get_zoom(ImageWindow *imd)
|
|
163 {
|
|
164 return imd->zoom;
|
|
165 }
|
|
166
|
|
167 void image_area_adjust_zoom(ImageWindow *imd, gint increment)
|
|
168 {
|
|
169 gint zoom = imd->zoom;
|
|
170 if (increment < 0)
|
|
171 {
|
|
172 while (increment < 0)
|
|
173 {
|
|
174 zoom--;
|
|
175 if (zoom == 0 || zoom == -1) zoom = -2;
|
|
176 increment++;
|
|
177 }
|
|
178 if (zoom < -8) zoom = -8;
|
|
179 }
|
|
180 else
|
|
181 {
|
|
182 while (increment > 0)
|
|
183 {
|
|
184 zoom++;
|
|
185 if (zoom == -1) zoom = 1;
|
|
186 increment--;
|
|
187 }
|
|
188 if (zoom > 3) zoom = 3;
|
|
189 }
|
|
190 if (zoom != imd->zoom)
|
|
191 image_area_set_zoom(imd, zoom);
|
|
192 }
|
|
193
|
|
194 void image_area_set_zoom(ImageWindow *imd, gint zoom)
|
|
195 {
|
|
196 if (zoom == imd->zoom && imd->width > 0 && imd->height > 0) return;
|
|
197
|
|
198 imd->zoom = zoom;
|
|
199 image_area_recalc_size(imd, NULL);
|
|
200
|
|
201 gtk_widget_set_usize (imd->table, imd->width, imd->height);
|
|
202 gtk_drawing_area_size(GTK_DRAWING_AREA(imd->image), imd->width, imd->height);
|
|
203 }
|
|
204
|
|
205 static void image_area_recalc_size(ImageWindow *imd, GtkAllocation *allocation)
|
|
206 {
|
|
207 gint w, h, ww, wh;
|
|
208 gfloat scale_factor = 1;
|
|
209
|
|
210 w = imd->image_data->rgb_width;
|
|
211 h = imd->image_data->rgb_height;
|
|
212 if (allocation)
|
|
213 {
|
|
214 ww = allocation->width;
|
|
215 wh = allocation->height;
|
|
216 }
|
|
217 else
|
|
218 {
|
|
219 ww = (imd->eventbox)->allocation.width;
|
|
220 wh = (imd->eventbox)->allocation.height;
|
|
221 }
|
|
222
|
|
223 if (imd == normal_image)
|
|
224 {
|
|
225 /* account for frame */
|
|
226 ww -= 4;
|
|
227 wh -= 4;
|
|
228 }
|
|
229
|
|
230 if (imd->zoom == 0) /* zoom to fit */
|
|
231 {
|
|
232 if (imd == normal_image && imd->width == 0 && imd->height == 0 &&
|
|
233 fit_window && toolwindow)
|
|
234 {
|
|
235 if (limit_window_size)
|
|
236 {
|
|
237 ww = (gdk_screen_width() * max_window_size / 100) - 4;
|
|
238 wh = (gdk_screen_height() * max_window_size / 100) - 4;
|
|
239 }
|
|
240 else
|
|
241 {
|
|
242 ww = w;
|
|
243 wh = h;
|
|
244 }
|
|
245 }
|
|
246 if (w > ww || h > wh)
|
|
247 {
|
|
248 if ((gfloat)ww / w > (gfloat)wh / h)
|
|
249 {
|
|
250 scale_factor = (gfloat) wh / h;
|
|
251 h = wh;
|
|
252 w = w * scale_factor + 0.5;
|
|
253 if (w > ww) w = ww;
|
|
254 }
|
|
255 else
|
|
256 {
|
|
257 scale_factor = (gfloat)ww / w;
|
|
258 w = ww;
|
|
259 h = h * scale_factor + 0.5;
|
|
260 if (h > wh) h = wh;
|
|
261 }
|
|
262 if (w < 1) w = 1;
|
|
263 if (h < 1) h = 1;
|
|
264 }
|
|
265 }
|
|
266 else if (imd->zoom > 0) /* zoom orig, in */
|
|
267 {
|
|
268 scale_factor = imd->zoom;
|
|
269 w = w * scale_factor;
|
|
270 h = h * scale_factor;
|
|
271 }
|
|
272 else if (imd->zoom < -1) /* zoom out */
|
|
273 {
|
|
274 scale_factor = (- imd->zoom);
|
|
275 w = w / scale_factor;
|
|
276 h = h / scale_factor;
|
|
277 }
|
|
278
|
|
279 imd->width = w;
|
|
280 imd->height = h;
|
|
281
|
|
282 if (debug) printf("recalc %d x %d @ %f\n", w, h, scale_factor);
|
|
283
|
|
284 if (imd->zoom_label)
|
|
285 {
|
|
286 set_zoom_label(imd->zoom_label, imd->zoom, scale_factor);
|
|
287 }
|
|
288
|
|
289 /* this is causing problems with resizing
|
|
290 if (imd->top_window && imd->show_title_zoom)
|
|
291 {
|
|
292 gchar *buf = zoom_as_text(imd->zoom, scale_factor);
|
|
293 gchar *zbuf = g_strconcat(" [ ", buf, "]", NULL);
|
|
294 g_free(buf);
|
|
295 set_window_title(imd, zbuf);
|
|
296 g_free(zbuf);
|
|
297 }
|
|
298 */
|
|
299
|
|
300 if (image_area_size_top_window(imd, w, h))
|
|
301 {
|
|
302 /* this is hacky */
|
|
303 imd->artificial_size = TRUE;
|
|
304 gtk_grab_add (info_zoom);
|
|
305 while(gtk_events_pending()) gtk_main_iteration();
|
|
306 gtk_grab_remove(info_zoom);
|
|
307 imd->artificial_size = FALSE;
|
|
308 }
|
|
309 }
|
|
310
|
|
311 /*
|
|
312 *-----------------------------------------------------------------------------
|
|
313 * image widget set/get image information
|
|
314 *-----------------------------------------------------------------------------
|
|
315 */
|
|
316
|
|
317 void image_area_set_path(ImageWindow *imd, gchar *newpath)
|
|
318 {
|
|
319 if (!imd->image_path || !newpath) return;
|
|
320
|
|
321 g_free(imd->image_path);
|
|
322 imd->image_path = g_strdup(newpath);
|
|
323 imd->image_name = filename_from_path(imd->image_path);
|
|
324
|
|
325 if (imd->top_window)
|
|
326 {
|
|
327 set_window_title(imd, NULL);
|
|
328 }
|
|
329 }
|
|
330
|
|
331 gchar *image_area_get_path(ImageWindow *imd)
|
|
332 {
|
|
333 return imd->image_path;
|
|
334 }
|
|
335
|
|
336 gchar *image_area_get_name(ImageWindow *imd)
|
|
337 {
|
|
338 return imd->image_name;
|
|
339 }
|
|
340
|
|
341 void image_area_set_image(ImageWindow *imd, gchar *path, gint zoom)
|
|
342 {
|
|
343 if (path && imd->image_path && !strcmp(path, imd->image_path)) return;
|
|
344
|
|
345 g_free(imd->image_path);
|
|
346 if (path)
|
|
347 {
|
|
348 imd->image_path = g_strdup(path);
|
|
349 imd->image_name = filename_from_path(imd->image_path);
|
|
350 }
|
|
351 else
|
|
352 {
|
|
353 imd->image_path = NULL;
|
|
354 imd->image_name = " ";
|
|
355 zoom = 1;
|
|
356 }
|
|
357
|
|
358 if (imd->image_data) gdk_imlib_destroy_image(imd->image_data);
|
|
359 if (path && isfile(path))
|
|
360 {
|
|
361 imd->image_data = gdk_imlib_load_image(path);
|
|
362 if (!imd->image_data)
|
|
363 {
|
|
364 imd->image_data = gdk_imlib_create_image_from_xpm_data((gchar **)img_unknown_xpm);
|
|
365 imd->unknown = TRUE;
|
|
366 }
|
|
367 else
|
|
368 {
|
|
369 imd->unknown = FALSE;
|
|
370 }
|
|
371 imd->size = filesize(path);
|
|
372 }
|
|
373 else
|
|
374 {
|
|
375 if (path)
|
|
376 imd->image_data = gdk_imlib_create_image_from_xpm_data((gchar **)img_unknown_xpm);
|
|
377 else
|
|
378 imd->image_data = gdk_imlib_create_image_from_data((char *)logo, NULL, logo_width, logo_height);
|
|
379 imd->unknown = TRUE;
|
|
380 imd->size = 0;
|
|
381 }
|
|
382
|
|
383 imd->width = imd->old_width = 0;
|
|
384 imd->height = imd->old_height = 0;
|
|
385
|
|
386 if (imd->top_window)
|
|
387 {
|
|
388 set_window_title(imd, NULL);
|
|
389 }
|
|
390 if (imd->info_label)
|
|
391 {
|
|
392 set_info_label(imd->info_label, imd->image_data->rgb_width, imd->image_data->rgb_height, imd->size, imd->unknown);
|
|
393 }
|
|
394
|
|
395 /* do info area updates here */
|
|
396
|
|
397 imd->new_img = TRUE;
|
|
398 image_area_set_zoom(imd, zoom);
|
|
399 }
|
|
400
|
|
401 /*
|
|
402 *-----------------------------------------------------------------------------
|
|
403 * image widget redraw/callbacks (private)
|
|
404 *-----------------------------------------------------------------------------
|
|
405 */
|
|
406
|
|
407 static void image_area_redraw(ImageWindow *imd)
|
|
408 {
|
|
409 GdkBitmap *mask = NULL;
|
|
410
|
|
411 if (debug) printf("redrawn %d x %d\n", imd->width, imd->height);
|
|
412
|
|
413 if (!imd->image_data) return;
|
|
414
|
|
415 if (imd->width == imd->old_width && imd->height == imd->old_height)
|
|
416 {
|
|
417 if (debug) printf("redraw cancelled\n");
|
|
418 return;
|
|
419 }
|
|
420
|
|
421 if (imd->image_pixmap) gdk_imlib_free_pixmap(imd->image_pixmap);
|
|
422 imd->image_pixmap = NULL;
|
|
423
|
|
424 gdk_imlib_render(imd->image_data, imd->width, imd->height);
|
|
425 imd->image_pixmap = gdk_imlib_move_image(imd->image_data);
|
|
426 mask = gdk_imlib_move_mask(imd->image_data);
|
|
427
|
|
428 gdk_window_set_back_pixmap(imd->image->window, imd->image_pixmap, FALSE);
|
|
429 gdk_window_shape_combine_mask (imd->image->window, mask, 0, 0);
|
|
430 gdk_window_clear(imd->image->window);
|
|
431 gdk_flush();
|
|
432
|
|
433 imd->old_width = imd->width;
|
|
434 imd->old_height = imd->height;
|
|
435 }
|
|
436
|
|
437 static gint image_area_size_cb(GtkWidget *widget, GtkAllocation *allocation, gpointer data)
|
|
438 {
|
|
439 ImageWindow *imd = data;
|
|
440 gint old_w, old_h;
|
|
441 GtkAdjustment *h;
|
|
442 GtkAdjustment *v;
|
|
443 gfloat h_pos;
|
|
444 gfloat v_pos;
|
|
445 gfloat h_max;
|
|
446 gfloat v_max;
|
|
447
|
|
448 if (imd->artificial_size) return FALSE;
|
|
449
|
|
450 h = gtk_viewport_get_hadjustment(GTK_VIEWPORT(imd->viewport));
|
|
451 v = gtk_viewport_get_vadjustment(GTK_VIEWPORT(imd->viewport));
|
|
452
|
|
453 h_pos = h->value;
|
|
454 h_max = allocation->width;
|
|
455 v_pos = v->value;
|
|
456 v_max = allocation->height;
|
|
457
|
|
458 if (imd == normal_image)
|
|
459 {
|
|
460 h_max -= 4.0;
|
|
461 v_max -= 4.0;
|
|
462 }
|
|
463
|
|
464 if (h_pos > h->upper - h_max) h_pos = h->upper - h_max;
|
|
465 if (v_pos > v->upper - v_max) v_pos = v->upper - v_max;
|
|
466
|
|
467 if (imd->new_img)
|
|
468 {
|
|
469 imd->new_img = FALSE;
|
|
470 gtk_adjustment_clamp_page(h, 0.0, h_max);
|
|
471 gtk_adjustment_clamp_page(v, 0.0, v_max);
|
|
472 }
|
|
473 else
|
|
474 {
|
|
475 gtk_adjustment_clamp_page(h, h_pos, h_max);
|
|
476 gtk_adjustment_clamp_page(v, v_pos, v_max);
|
|
477 }
|
|
478
|
|
479 gtk_adjustment_changed(h);
|
|
480 gtk_adjustment_changed(v);
|
|
481
|
|
482 if (!imd->image_data || imd->zoom != 0) return FALSE;
|
|
483
|
|
484 old_w = imd->width;
|
|
485 old_h = imd->height;
|
|
486 image_area_recalc_size(imd, allocation);
|
|
487 if (old_w != imd->width || old_h != imd->height)
|
|
488 {
|
|
489 gtk_widget_set_usize (imd->table, imd->width, imd->height);
|
|
490 gtk_drawing_area_size(GTK_DRAWING_AREA(imd->image), imd->width, imd->height);
|
|
491 }
|
|
492
|
|
493 if (debug) printf("sized %d x %d (%d x %d)\n", allocation->width, allocation->height, imd->width, imd->height);
|
|
494
|
|
495 return FALSE;
|
|
496 }
|
|
497
|
|
498 static gint image_area_update_cb(GtkWidget *widget, GdkEventConfigure *event, gpointer data)
|
|
499 {
|
|
500 ImageWindow *imd = data;
|
|
501
|
|
502 if (imd->artificial_size) return FALSE;
|
|
503
|
|
504 image_area_redraw(imd);
|
|
505
|
|
506 return FALSE;
|
|
507 }
|
|
508
|
|
509 /*
|
|
510 *-----------------------------------------------------------------------------
|
|
511 * image widget mouse routines (private)
|
|
512 *-----------------------------------------------------------------------------
|
|
513 */
|
|
514
|
|
515 static void set_mouse_cursor (GdkWindow *window, gint icon)
|
|
516 {
|
|
517 GdkCursor *cursor;
|
|
518
|
|
519 if (icon == -1)
|
|
520 {
|
|
521 cursor = NULL;
|
|
522 }
|
|
523 else
|
|
524 {
|
|
525 cursor = gdk_cursor_new (icon);
|
|
526 }
|
|
527
|
|
528 gdk_window_set_cursor (window, cursor);
|
|
529
|
|
530 if (cursor) gdk_cursor_destroy (cursor);
|
|
531 }
|
|
532
|
|
533 static void image_area_mouse_moved(GtkWidget *widget, GdkEventButton *bevent, gpointer data)
|
|
534 {
|
|
535 ImageWindow *imd = data;
|
|
536 GtkAdjustment* h;
|
|
537 GtkAdjustment* v;
|
|
538 gfloat x, y;
|
|
539 gfloat val;
|
|
540
|
|
541 if (!imd->in_drag || !gdk_pointer_is_grabbed()) return;
|
|
542
|
|
543 if (imd->drag_moved < 4)
|
|
544 {
|
|
545 imd->drag_moved++;
|
|
546 }
|
|
547 else
|
|
548 {
|
|
549 set_mouse_cursor (imd->eventbox->window, GDK_FLEUR);
|
|
550 }
|
|
551
|
|
552 h = gtk_viewport_get_hadjustment(GTK_VIEWPORT(imd->viewport));
|
|
553 v = gtk_viewport_get_vadjustment(GTK_VIEWPORT(imd->viewport));
|
|
554
|
|
555 x = imd->drag_last_x - bevent->x;
|
|
556 y = imd->drag_last_y - bevent->y;
|
|
557
|
|
558 /* x */
|
|
559 if (h->upper - h->page_size > 0)
|
|
560 {
|
|
561 val = (float)h->value + x;
|
|
562 if (val < 0 ) val = 0;
|
|
563 if (val > h->upper - h->page_size) val = h->upper - h->page_size;
|
|
564 h->value = val;
|
|
565 gtk_adjustment_set_value (GTK_ADJUSTMENT(h), val);
|
|
566 }
|
|
567
|
|
568 /* y */
|
|
569 if (v->upper - v->page_size > 0)
|
|
570 {
|
|
571 val = v->value + y;
|
|
572 if (val < 0 ) val = 0;
|
|
573 if (val > v->upper - v->page_size) val = v->upper - v->page_size;
|
|
574 v->value = val;
|
|
575 gtk_adjustment_set_value (GTK_ADJUSTMENT(v), val);
|
|
576 }
|
|
577
|
|
578 gtk_adjustment_value_changed(h);
|
|
579 gtk_adjustment_value_changed(v);
|
|
580
|
|
581 imd->drag_last_x = bevent->x;
|
|
582 imd->drag_last_y = bevent->y;
|
|
583 }
|
|
584
|
|
585 static void image_area_mouse_pressed(GtkWidget *widget, GdkEventButton *bevent, gpointer data)
|
|
586 {
|
|
587 ImageWindow *imd = data;
|
|
588 switch (bevent->button)
|
|
589 {
|
|
590 case 1:
|
|
591 imd->in_drag = TRUE;
|
|
592 imd->drag_last_x = bevent->x;
|
|
593 imd->drag_last_y = bevent->y;
|
|
594 imd->drag_moved = 0;
|
|
595 gdk_pointer_grab (imd->eventbox->window, FALSE,
|
|
596 GDK_POINTER_MOTION_MASK |
|
|
597 GDK_BUTTON_RELEASE_MASK,
|
|
598 NULL, NULL, bevent->time);
|
|
599 gtk_grab_add (imd->eventbox);
|
|
600 break;
|
|
601 case 2:
|
|
602 imd->drag_moved = 0;
|
|
603 break;
|
|
604 case 3:
|
|
605 if (imd->func_btn3)
|
|
606 imd->func_btn3(imd, bevent, imd->data_btn3);
|
|
607 break;
|
|
608 default:
|
|
609 break;
|
|
610 }
|
|
611 gtk_widget_grab_focus(imd->viewport);
|
|
612 }
|
|
613
|
|
614 static void image_area_mouse_released(GtkWidget *widget, GdkEventButton *bevent, gpointer data)
|
|
615 {
|
|
616 ImageWindow *imd = data;
|
|
617 if (gdk_pointer_is_grabbed() && GTK_WIDGET_HAS_GRAB (imd->eventbox))
|
|
618 {
|
|
619 gtk_grab_remove (imd->eventbox);
|
|
620 gdk_pointer_ungrab (bevent->time);
|
|
621 set_mouse_cursor (imd->eventbox->window, -1);
|
|
622 }
|
|
623
|
|
624 if (bevent->button == 1)
|
|
625 {
|
|
626 if (imd->drag_moved < 4 && imd->func_btn1)
|
|
627 imd->func_btn1(imd, bevent, imd->data_btn1);
|
|
628 }
|
|
629
|
|
630 if (bevent->button == 2)
|
|
631 {
|
|
632 if (imd->drag_moved < 4 && imd->func_btn2)
|
|
633 imd->func_btn2(imd, bevent, imd->data_btn2);
|
|
634 }
|
|
635
|
|
636 imd->in_drag = FALSE;
|
|
637 }
|
|
638
|
|
639 static void image_area_mouse_drag(GtkWidget *widget, GdkDragContext *context, gpointer data)
|
|
640 {
|
|
641 ImageWindow *imd = data;
|
|
642 imd->drag_moved = 4;
|
|
643 }
|
|
644
|
|
645 /*
|
|
646 *-----------------------------------------------------------------------------
|
|
647 * image widget setup routines
|
|
648 *-----------------------------------------------------------------------------
|
|
649 */
|
|
650
|
|
651 void image_area_set_topwindow(ImageWindow *imd, GtkWidget *window, gchar *title, gint show_zoom)
|
|
652 {
|
|
653 imd->top_window = window;
|
|
654 imd->show_title_zoom = show_zoom;
|
|
655
|
|
656 g_free(imd->title);
|
|
657 if (title)
|
|
658 imd->title = g_strdup(title);
|
|
659 else
|
|
660 imd->title = NULL;
|
|
661 }
|
|
662
|
|
663 void image_area_set_labels(ImageWindow *imd, GtkWidget *info, GtkWidget *zoom)
|
|
664 {
|
|
665 imd->info_label = info;
|
|
666 imd->zoom_label = zoom;
|
|
667 }
|
|
668
|
|
669 void image_area_set_button(ImageWindow *imd, gint button,
|
|
670 void (*func)(ImageWindow *, GdkEventButton *, gpointer), gpointer data)
|
|
671 {
|
|
672 switch (button)
|
|
673 {
|
|
674 case 1:
|
|
675 imd->func_btn1 = func;
|
|
676 imd->data_btn1 = data;
|
|
677 break;
|
|
678 case 2:
|
|
679 imd->func_btn2 = func;
|
|
680 imd->data_btn2 = data;
|
|
681 break;
|
|
682 case 3:
|
|
683 imd->func_btn3 = func;
|
|
684 imd->data_btn3 = data;
|
|
685 break;
|
|
686 }
|
|
687 }
|
|
688
|
|
689 ImageWindow *image_area_new(GtkWidget *top_window)
|
|
690 {
|
|
691 GtkObject *h_adj;
|
|
692 GtkObject *v_adj;
|
|
693 ImageWindow *imd;
|
|
694
|
|
695 imd = g_new0(ImageWindow, 1);
|
|
696 imd->zoom = 0;
|
|
697
|
|
698 imd->top_window = top_window;
|
|
699 imd->title = g_strdup("GQview - ");
|
|
700 imd->show_title_zoom = FALSE;
|
|
701 imd->new_img = FALSE;
|
|
702
|
|
703 imd->eventbox = gtk_event_box_new();
|
|
704
|
|
705 gtk_signal_connect(GTK_OBJECT(imd->eventbox),"motion_notify_event",
|
|
706 GTK_SIGNAL_FUNC(image_area_mouse_moved), imd);
|
|
707 gtk_signal_connect(GTK_OBJECT(imd->eventbox),"button_press_event",
|
|
708 GTK_SIGNAL_FUNC(image_area_mouse_pressed), imd);
|
|
709 gtk_signal_connect(GTK_OBJECT(imd->eventbox),"button_release_event",
|
|
710 GTK_SIGNAL_FUNC(image_area_mouse_released), imd);
|
|
711 gtk_widget_set_events(imd->eventbox, GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK);
|
|
712
|
|
713 /* viewer */
|
|
714 h_adj = gtk_adjustment_new(0.0,0.0,0.0,1.0,1.0,1.0);
|
|
715 v_adj = gtk_adjustment_new(0.0,0.0,0.0,1.0,1.0,1.0);
|
|
716
|
|
717 imd->viewport = gtk_viewport_new (GTK_ADJUSTMENT(h_adj), GTK_ADJUSTMENT(v_adj));
|
|
718 gtk_container_add(GTK_CONTAINER(imd->eventbox), imd->viewport);
|
|
719
|
|
720 /* table for resize */
|
|
721 imd->table = gtk_table_new (1,1,TRUE);
|
|
722 gtk_container_add(GTK_CONTAINER (imd->viewport), imd->table);
|
|
723
|
|
724 /* imagewindow */
|
|
725 imd->image = gtk_drawing_area_new();
|
|
726 gtk_table_attach(GTK_TABLE (imd->table),imd->image,0,1,0,1,GTK_EXPAND,GTK_EXPAND,0,0);
|
|
727
|
|
728 gtk_signal_connect(GTK_OBJECT(imd->eventbox),"size_allocate",GTK_SIGNAL_FUNC(image_area_size_cb), imd);
|
|
729 gtk_signal_connect(GTK_OBJECT(imd->image),"configure_event",GTK_SIGNAL_FUNC(image_area_update_cb), imd);
|
|
730
|
|
731 gtk_signal_connect(GTK_OBJECT(imd->viewport),"drag_begin",
|
|
732 GTK_SIGNAL_FUNC(image_area_mouse_drag), imd);
|
|
733
|
|
734 return imd;
|
|
735 }
|
|
736
|
|
737 void image_area_free(ImageWindow *imd)
|
|
738 {
|
|
739 g_free(imd->image_path);
|
|
740
|
|
741 if (imd->image_pixmap) gdk_imlib_free_pixmap(imd->image_pixmap);
|
|
742 if (imd->image_data) gdk_imlib_destroy_image(imd->image_data);
|
|
743
|
|
744 g_free(imd);
|
|
745 }
|
|
746
|
|
747 gint get_default_zoom(ImageWindow *imd)
|
|
748 {
|
|
749 gint zoom;
|
|
750
|
|
751 if (zoom_mode == ZOOM_RESET_ORIGINAL)
|
|
752 {
|
|
753 zoom = 1;
|
|
754 }
|
|
755 else if (zoom_mode == ZOOM_RESET_FIT_WINDOW)
|
|
756 {
|
|
757 zoom = 0;
|
|
758 }
|
|
759 else
|
|
760 {
|
|
761 if (imd)
|
|
762 {
|
|
763 zoom = image_area_get_zoom(imd);
|
|
764 }
|
|
765 else
|
|
766 {
|
|
767 zoom = 1;
|
|
768 }
|
|
769 }
|
|
770
|
|
771 return zoom;
|
|
772 }
|
|
773
|