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