105
|
1 /*
|
196
|
2 * Geeqie
|
105
|
3 * (C) 2006 John Ellis
|
475
|
4 * Copyright (C) 2008 The Geeqie Team
|
105
|
5 *
|
|
6 * Author: John Ellis
|
|
7 *
|
|
8 * This software is released under the GNU General Public License (GNU GPL).
|
|
9 * Please read the included file COPYING for more information.
|
|
10 * This software comes with no warranty of any kind, use at your own risk!
|
|
11 */
|
|
12
|
|
13
|
281
|
14 #include "main.h"
|
105
|
15 #include "pan-types.h"
|
|
16
|
|
17
|
|
18 /*
|
|
19 *-----------------------------------------------------------------------------
|
|
20 * item base functions
|
|
21 *-----------------------------------------------------------------------------
|
|
22 */
|
|
23
|
|
24 void pan_item_free(PanItem *pi)
|
|
25 {
|
|
26 if (!pi) return;
|
|
27
|
|
28 if (pi->pixbuf) g_object_unref(pi->pixbuf);
|
138
|
29 if (pi->fd) file_data_unref(pi->fd);
|
105
|
30 g_free(pi->text);
|
|
31 g_free(pi->key);
|
|
32 g_free(pi->data);
|
|
33
|
|
34 g_free(pi);
|
|
35 }
|
|
36
|
|
37 void pan_item_set_key(PanItem *pi, const gchar *key)
|
|
38 {
|
|
39 gchar *tmp;
|
|
40
|
|
41 if (!pi) return;
|
|
42
|
|
43 tmp = pi->key;
|
|
44 pi->key = g_strdup(key);
|
|
45 g_free(tmp);
|
|
46 }
|
|
47
|
|
48 void pan_item_added(PanWindow *pw, PanItem *pi)
|
|
49 {
|
|
50 if (!pi) return;
|
|
51 image_area_changed(pw->imd, pi->x, pi->y, pi->width, pi->height);
|
|
52 }
|
|
53
|
|
54 void pan_item_remove(PanWindow *pw, PanItem *pi)
|
|
55 {
|
|
56 if (!pi) return;
|
|
57
|
|
58 if (pw->click_pi == pi) pw->click_pi = NULL;
|
|
59 if (pw->queue_pi == pi) pw->queue_pi = NULL;
|
|
60 if (pw->search_pi == pi) pw->search_pi = NULL;
|
|
61 pw->queue = g_list_remove(pw->queue, pi);
|
|
62
|
|
63 pw->list = g_list_remove(pw->list, pi);
|
|
64 image_area_changed(pw->imd, pi->x, pi->y, pi->width, pi->height);
|
|
65 pan_item_free(pi);
|
|
66 }
|
|
67
|
|
68 void pan_item_size_by_item(PanItem *pi, PanItem *child, gint border)
|
|
69 {
|
|
70 if (!pi || !child) return;
|
|
71
|
|
72 if (pi->x + pi->width < child->x + child->width + border)
|
|
73 pi->width = child->x + child->width + border - pi->x;
|
|
74
|
|
75 if (pi->y + pi->height < child->y + child->height + border)
|
|
76 pi->height = child->y + child->height + border - pi->y;
|
|
77 }
|
|
78
|
|
79 void pan_item_size_coordinates(PanItem *pi, gint border, gint *w, gint *h)
|
|
80 {
|
|
81 if (!pi) return;
|
|
82
|
|
83 if (*w < pi->x + pi->width + border) *w = pi->x + pi->width + border;
|
|
84 if (*h < pi->y + pi->height + border) *h = pi->y + pi->height + border;
|
|
85 }
|
|
86
|
|
87
|
|
88 /*
|
|
89 *-----------------------------------------------------------------------------
|
|
90 * item box type
|
|
91 *-----------------------------------------------------------------------------
|
|
92 */
|
|
93
|
|
94 PanItem *pan_item_box_new(PanWindow *pw, FileData *fd, gint x, gint y, gint width, gint height,
|
|
95 gint border_size,
|
|
96 guint8 base_r, guint8 base_g, guint8 base_b, guint8 base_a,
|
|
97 guint8 bord_r, guint8 bord_g, guint8 bord_b, guint8 bord_a)
|
|
98 {
|
|
99 PanItem *pi;
|
|
100
|
|
101 pi = g_new0(PanItem, 1);
|
|
102 pi->type = PAN_ITEM_BOX;
|
|
103 pi->fd = fd;
|
|
104 pi->x = x;
|
|
105 pi->y = y;
|
|
106 pi->width = width;
|
|
107 pi->height = height;
|
|
108
|
|
109 pi->color_r = base_r;
|
|
110 pi->color_g = base_g;
|
|
111 pi->color_b = base_b;
|
|
112 pi->color_a = base_a;
|
|
113
|
|
114 pi->color2_r = bord_r;
|
|
115 pi->color2_g = bord_g;
|
|
116 pi->color2_b = bord_b;
|
|
117 pi->color2_a = bord_a;
|
|
118 pi->border = border_size;
|
|
119
|
|
120 pw->list = g_list_prepend(pw->list, pi);
|
|
121
|
|
122 return pi;
|
|
123 }
|
|
124
|
|
125 void pan_item_box_shadow(PanItem *pi, gint offset, gint fade)
|
|
126 {
|
|
127 gint *shadow;
|
|
128
|
|
129 if (!pi || pi->type != PAN_ITEM_BOX) return;
|
|
130
|
|
131 shadow = pi->data;
|
|
132 if (shadow)
|
|
133 {
|
|
134 pi->width -= shadow[0];
|
|
135 pi->height -= shadow[0];
|
|
136 }
|
|
137
|
|
138 shadow = g_new0(gint, 2);
|
|
139 shadow[0] = offset;
|
|
140 shadow[1] = fade;
|
|
141
|
|
142 pi->width += offset;
|
|
143 pi->height += offset;
|
|
144
|
|
145 g_free(pi->data);
|
|
146 pi->data = shadow;
|
|
147 }
|
|
148
|
|
149 gint pan_item_box_draw(PanWindow *pw, PanItem *pi, GdkPixbuf *pixbuf, PixbufRenderer *pr,
|
|
150 gint x, gint y, gint width, gint height)
|
|
151 {
|
|
152 gint bw, bh;
|
|
153 gint *shadow;
|
|
154 gint rx, ry, rw, rh;
|
|
155
|
|
156 bw = pi->width;
|
|
157 bh = pi->height;
|
|
158
|
|
159 shadow = pi->data;
|
|
160 if (shadow)
|
|
161 {
|
|
162 bw -= shadow[0];
|
|
163 bh -= shadow[0];
|
|
164
|
|
165 if (pi->color_a > 254)
|
|
166 {
|
|
167 pixbuf_draw_shadow(pixbuf, pi->x - x + bw, pi->y - y + shadow[0],
|
|
168 shadow[0], bh - shadow[0],
|
|
169 pi->x - x + shadow[0], pi->y - y + shadow[0], bw, bh,
|
|
170 shadow[1],
|
|
171 PAN_SHADOW_COLOR, PAN_SHADOW_ALPHA);
|
|
172 pixbuf_draw_shadow(pixbuf, pi->x - x + shadow[0], pi->y - y + bh,
|
|
173 bw, shadow[0],
|
|
174 pi->x - x + shadow[0], pi->y - y + shadow[0], bw, bh,
|
|
175 shadow[1],
|
|
176 PAN_SHADOW_COLOR, PAN_SHADOW_ALPHA);
|
|
177 }
|
|
178 else
|
|
179 {
|
|
180 gint a;
|
|
181 a = pi->color_a * PAN_SHADOW_ALPHA >> 8;
|
|
182 pixbuf_draw_shadow(pixbuf, pi->x - x + shadow[0], pi->y - y + shadow[0],
|
|
183 bw, bh,
|
|
184 pi->x - x + shadow[0], pi->y - y + shadow[0], bw, bh,
|
|
185 shadow[1],
|
|
186 PAN_SHADOW_COLOR, a);
|
|
187 }
|
|
188 }
|
|
189
|
|
190 if (util_clip_region(x, y, width, height,
|
|
191 pi->x, pi->y, bw, bh,
|
|
192 &rx, &ry, &rw, &rh))
|
|
193 {
|
|
194 pixbuf_draw_rect_fill(pixbuf,
|
|
195 rx - x, ry - y, rw, rh,
|
|
196 pi->color_r, pi->color_g, pi->color_b, pi->color_a);
|
|
197 }
|
|
198 if (util_clip_region(x, y, width, height,
|
|
199 pi->x, pi->y, bw, pi->border,
|
|
200 &rx, &ry, &rw, &rh))
|
|
201 {
|
|
202 pixbuf_draw_rect_fill(pixbuf,
|
|
203 rx - x, ry - y, rw, rh,
|
|
204 pi->color2_r, pi->color2_g, pi->color2_b, pi->color2_a);
|
|
205 }
|
|
206 if (util_clip_region(x, y, width, height,
|
|
207 pi->x, pi->y + pi->border, pi->border, bh - pi->border * 2,
|
|
208 &rx, &ry, &rw, &rh))
|
|
209 {
|
|
210 pixbuf_draw_rect_fill(pixbuf,
|
|
211 rx - x, ry - y, rw, rh,
|
|
212 pi->color2_r, pi->color2_g, pi->color2_b, pi->color2_a);
|
|
213 }
|
|
214 if (util_clip_region(x, y, width, height,
|
|
215 pi->x + bw - pi->border, pi->y + pi->border,
|
|
216 pi->border, bh - pi->border * 2,
|
|
217 &rx, &ry, &rw, &rh))
|
|
218 {
|
|
219 pixbuf_draw_rect_fill(pixbuf,
|
|
220 rx - x, ry - y, rw, rh,
|
|
221 pi->color2_r, pi->color2_g, pi->color2_b, pi->color2_a);
|
|
222 }
|
|
223 if (util_clip_region(x, y, width, height,
|
|
224 pi->x, pi->y + bh - pi->border,
|
|
225 bw, pi->border,
|
|
226 &rx, &ry, &rw, &rh))
|
|
227 {
|
|
228 pixbuf_draw_rect_fill(pixbuf,
|
|
229 rx - x, ry - y, rw, rh,
|
|
230 pi->color2_r, pi->color2_g, pi->color2_b, pi->color2_a);
|
|
231 }
|
|
232
|
|
233 return FALSE;
|
|
234 }
|
|
235
|
|
236
|
|
237 /*
|
|
238 *-----------------------------------------------------------------------------
|
|
239 * item triangle type
|
|
240 *-----------------------------------------------------------------------------
|
|
241 */
|
|
242
|
|
243 PanItem *pan_item_tri_new(PanWindow *pw, FileData *fd, gint x, gint y, gint width, gint height,
|
|
244 gint x1, gint y1, gint x2, gint y2, gint x3, gint y3,
|
|
245 guint8 r, guint8 g, guint8 b, guint8 a)
|
|
246 {
|
|
247 PanItem *pi;
|
|
248 gint *coord;
|
|
249
|
|
250 pi = g_new0(PanItem, 1);
|
|
251 pi->type = PAN_ITEM_TRIANGLE;
|
|
252 pi->x = x;
|
|
253 pi->y = y;
|
|
254 pi->width = width;
|
|
255 pi->height = height;
|
|
256
|
|
257 pi->color_r = r;
|
|
258 pi->color_g = g;
|
|
259 pi->color_b = b;
|
|
260 pi->color_a = a;
|
|
261
|
|
262 coord = g_new0(gint, 6);
|
|
263 coord[0] = x1;
|
|
264 coord[1] = y1;
|
|
265 coord[2] = x2;
|
|
266 coord[3] = y2;
|
|
267 coord[4] = x3;
|
|
268 coord[5] = y3;
|
|
269
|
|
270 pi->data = coord;
|
|
271
|
|
272 pi->border = PAN_BORDER_NONE;
|
|
273
|
|
274 pw->list = g_list_prepend(pw->list, pi);
|
|
275
|
|
276 return pi;
|
|
277 }
|
|
278
|
|
279 void pan_item_tri_border(PanItem *pi, gint borders,
|
|
280 guint8 r, guint8 g, guint8 b, guint8 a)
|
|
281 {
|
|
282 if (!pi || pi->type != PAN_ITEM_TRIANGLE) return;
|
|
283
|
|
284 pi->border = borders;
|
|
285
|
|
286 pi->color2_r = r;
|
|
287 pi->color2_g = g;
|
|
288 pi->color2_b = b;
|
|
289 pi->color2_a = a;
|
|
290 }
|
|
291
|
|
292 gint pan_item_tri_draw(PanWindow *pw, PanItem *pi, GdkPixbuf *pixbuf, PixbufRenderer *pr,
|
|
293 gint x, gint y, gint width, gint height)
|
|
294 {
|
|
295 gint rx, ry, rw, rh;
|
|
296
|
|
297 if (util_clip_region(x, y, width, height,
|
|
298 pi->x, pi->y, pi->width, pi->height,
|
|
299 &rx, &ry, &rw, &rh) && pi->data)
|
|
300 {
|
|
301 gint *coord = pi->data;
|
|
302 pixbuf_draw_triangle(pixbuf,
|
|
303 rx - x, ry - y, rw, rh,
|
|
304 coord[0] - x, coord[1] - y,
|
|
305 coord[2] - x, coord[3] - y,
|
|
306 coord[4] - x, coord[5] - y,
|
|
307 pi->color_r, pi->color_g, pi->color_b, pi->color_a);
|
|
308
|
|
309 if (pi->border & PAN_BORDER_1)
|
|
310 {
|
|
311 pixbuf_draw_line(pixbuf,
|
|
312 rx - x, ry - y, rw, rh,
|
|
313 coord[0] - x, coord[1] - y,
|
|
314 coord[2] - x, coord[3] - y,
|
|
315 pi->color2_r, pi->color2_g, pi->color2_b, pi->color2_a);
|
|
316 }
|
|
317 if (pi->border & PAN_BORDER_2)
|
|
318 {
|
|
319 pixbuf_draw_line(pixbuf,
|
|
320 rx - x, ry - y, rw, rh,
|
|
321 coord[2] - x, coord[3] - y,
|
|
322 coord[4] - x, coord[5] - y,
|
|
323 pi->color2_r, pi->color2_g, pi->color2_b, pi->color2_a);
|
|
324 }
|
|
325 if (pi->border & PAN_BORDER_3)
|
|
326 {
|
|
327 pixbuf_draw_line(pixbuf,
|
|
328 rx - x, ry - y, rw, rh,
|
|
329 coord[4] - x, coord[5] - y,
|
|
330 coord[0] - x, coord[1] - y,
|
|
331 pi->color2_r, pi->color2_g, pi->color2_b, pi->color2_a);
|
|
332 }
|
|
333 }
|
|
334
|
|
335 return FALSE;
|
|
336 }
|
|
337
|
|
338
|
|
339 /*
|
|
340 *-----------------------------------------------------------------------------
|
|
341 * item text type
|
|
342 *-----------------------------------------------------------------------------
|
|
343 */
|
|
344
|
|
345 static PangoLayout *pan_item_text_layout(PanItem *pi, GtkWidget *widget)
|
|
346 {
|
|
347 PangoLayout *layout;
|
|
348
|
|
349 layout = gtk_widget_create_pango_layout(widget, NULL);
|
|
350
|
|
351 if (pi->text_attr & PAN_TEXT_ATTR_MARKUP)
|
|
352 {
|
|
353 pango_layout_set_markup(layout, pi->text, -1);
|
|
354 return layout;
|
|
355 }
|
|
356
|
|
357 if (pi->text_attr & PAN_TEXT_ATTR_BOLD ||
|
|
358 pi->text_attr & PAN_TEXT_ATTR_HEADING)
|
|
359 {
|
|
360 PangoAttrList *pal;
|
|
361 PangoAttribute *pa;
|
442
|
362
|
105
|
363 pal = pango_attr_list_new();
|
|
364 if (pi->text_attr & PAN_TEXT_ATTR_BOLD)
|
|
365 {
|
|
366 pa = pango_attr_weight_new(PANGO_WEIGHT_BOLD);
|
|
367 pa->start_index = 0;
|
|
368 pa->end_index = G_MAXINT;
|
|
369 pango_attr_list_insert(pal, pa);
|
|
370 }
|
|
371 if (pi->text_attr & PAN_TEXT_ATTR_HEADING)
|
|
372 {
|
|
373 pa = pango_attr_scale_new(PANGO_SCALE_LARGE);
|
|
374 pa->start_index = 0;
|
|
375 pa->end_index = G_MAXINT;
|
|
376 pango_attr_list_insert(pal, pa);
|
|
377 }
|
|
378 pango_layout_set_attributes(layout, pal);
|
|
379 pango_attr_list_unref(pal);
|
|
380 }
|
|
381
|
|
382 pango_layout_set_text(layout, pi->text, -1);
|
|
383 return layout;
|
|
384 }
|
|
385
|
|
386 static void pan_item_text_compute_size(PanItem *pi, GtkWidget *widget)
|
|
387 {
|
|
388 PangoLayout *layout;
|
|
389
|
|
390 if (!pi || !pi->text || !widget) return;
|
|
391
|
|
392 layout = pan_item_text_layout(pi, widget);
|
|
393 pango_layout_get_pixel_size(layout, &pi->width, &pi->height);
|
|
394 g_object_unref(G_OBJECT(layout));
|
|
395
|
|
396 pi->width += pi->border * 2;
|
|
397 pi->height += pi->border * 2;
|
|
398 }
|
|
399
|
|
400 PanItem *pan_item_text_new(PanWindow *pw, gint x, gint y, const gchar *text,
|
|
401 PanTextAttrType attr, PanBorderType border,
|
|
402 guint8 r, guint8 g, guint8 b, guint8 a)
|
|
403 {
|
|
404 PanItem *pi;
|
|
405
|
|
406 pi = g_new0(PanItem, 1);
|
|
407 pi->type = PAN_ITEM_TEXT;
|
|
408 pi->x = x;
|
|
409 pi->y = y;
|
|
410 pi->text = g_strdup(text);
|
|
411 pi->text_attr = attr;
|
|
412
|
|
413 pi->color_r = r;
|
|
414 pi->color_g = g;
|
|
415 pi->color_b = b;
|
|
416 pi->color_a = a;
|
|
417
|
|
418 pi->border = border;
|
|
419
|
|
420 pan_item_text_compute_size(pi, pw->imd->pr);
|
|
421
|
|
422 pw->list = g_list_prepend(pw->list, pi);
|
|
423
|
|
424 return pi;
|
|
425 }
|
|
426
|
|
427 gint pan_item_text_draw(PanWindow *pw, PanItem *pi, GdkPixbuf *pixbuf, PixbufRenderer *pr,
|
|
428 gint x, gint y, gint width, gint height)
|
|
429 {
|
|
430 PangoLayout *layout;
|
|
431
|
|
432 layout = pan_item_text_layout(pi, (GtkWidget *)pr);
|
|
433 pixbuf_draw_layout(pixbuf, layout, (GtkWidget *)pr,
|
|
434 pi->x - x + pi->border, pi->y - y + pi->border,
|
|
435 pi->color_r, pi->color_g, pi->color_b, pi->color_a);
|
|
436 g_object_unref(G_OBJECT(layout));
|
|
437
|
|
438 return FALSE;
|
|
439 }
|
|
440
|
|
441
|
|
442 /*
|
|
443 *-----------------------------------------------------------------------------
|
|
444 * item thumbnail type
|
|
445 *-----------------------------------------------------------------------------
|
|
446 */
|
|
447
|
|
448 PanItem *pan_item_thumb_new(PanWindow *pw, FileData *fd, gint x, gint y)
|
|
449 {
|
|
450 PanItem *pi;
|
|
451
|
|
452 pi = g_new0(PanItem, 1);
|
|
453 pi->type = PAN_ITEM_THUMB;
|
|
454 pi->fd = fd;
|
|
455 pi->x = x;
|
|
456 pi->y = y;
|
|
457 pi->width = PAN_THUMB_SIZE + PAN_SHADOW_OFFSET * 2;
|
|
458 pi->height = PAN_THUMB_SIZE + PAN_SHADOW_OFFSET * 2;
|
|
459
|
|
460 pi->pixbuf = NULL;
|
|
461
|
|
462 pi->queued = FALSE;
|
|
463
|
|
464 pw->list = g_list_prepend(pw->list, pi);
|
|
465
|
|
466 return pi;
|
|
467 }
|
|
468
|
|
469 gint pan_item_thumb_draw(PanWindow *pw, PanItem *pi, GdkPixbuf *pixbuf, PixbufRenderer *pr,
|
|
470 gint x, gint y, gint width, gint height)
|
|
471 {
|
|
472 gint tx, ty, tw, th;
|
|
473 gint rx, ry, rw, rh;
|
|
474
|
|
475 if (pi->pixbuf)
|
|
476 {
|
|
477 tw = gdk_pixbuf_get_width(pi->pixbuf);
|
|
478 th = gdk_pixbuf_get_height(pi->pixbuf);
|
|
479
|
|
480 tx = pi->x + (pi->width - tw) / 2;
|
|
481 ty = pi->y + (pi->height - th) / 2;
|
|
482
|
|
483 if (gdk_pixbuf_get_has_alpha(pi->pixbuf))
|
|
484 {
|
|
485 if (util_clip_region(x, y, width, height,
|
|
486 tx + PAN_SHADOW_OFFSET, ty + PAN_SHADOW_OFFSET, tw, th,
|
|
487 &rx, &ry, &rw, &rh))
|
|
488 {
|
|
489 pixbuf_draw_shadow(pixbuf,
|
|
490 rx - x, ry - y, rw, rh,
|
|
491 tx + PAN_SHADOW_OFFSET - x, ty + PAN_SHADOW_OFFSET - y, tw, th,
|
|
492 PAN_SHADOW_FADE,
|
|
493 PAN_SHADOW_COLOR, PAN_SHADOW_ALPHA);
|
|
494 }
|
|
495 }
|
|
496 else
|
|
497 {
|
|
498 if (util_clip_region(x, y, width, height,
|
|
499 tx + tw, ty + PAN_SHADOW_OFFSET,
|
|
500 PAN_SHADOW_OFFSET, th - PAN_SHADOW_OFFSET,
|
|
501 &rx, &ry, &rw, &rh))
|
|
502 {
|
|
503 pixbuf_draw_shadow(pixbuf,
|
|
504 rx - x, ry - y, rw, rh,
|
|
505 tx + PAN_SHADOW_OFFSET - x, ty + PAN_SHADOW_OFFSET - y, tw, th,
|
|
506 PAN_SHADOW_FADE,
|
|
507 PAN_SHADOW_COLOR, PAN_SHADOW_ALPHA);
|
|
508 }
|
|
509 if (util_clip_region(x, y, width, height,
|
|
510 tx + PAN_SHADOW_OFFSET, ty + th, tw, PAN_SHADOW_OFFSET,
|
|
511 &rx, &ry, &rw, &rh))
|
|
512 {
|
|
513 pixbuf_draw_shadow(pixbuf,
|
|
514 rx - x, ry - y, rw, rh,
|
|
515 tx + PAN_SHADOW_OFFSET - x, ty + PAN_SHADOW_OFFSET - y, tw, th,
|
|
516 PAN_SHADOW_FADE,
|
|
517 PAN_SHADOW_COLOR, PAN_SHADOW_ALPHA);
|
|
518 }
|
|
519 }
|
|
520
|
|
521 if (util_clip_region(x, y, width, height,
|
|
522 tx, ty, tw, th,
|
|
523 &rx, &ry, &rw, &rh))
|
|
524 {
|
|
525 gdk_pixbuf_composite(pi->pixbuf, pixbuf, rx - x, ry - y, rw, rh,
|
|
526 (double) tx - x,
|
|
527 (double) ty - y,
|
|
528 1.0, 1.0, GDK_INTERP_NEAREST,
|
|
529 255);
|
|
530 }
|
|
531
|
|
532 if (util_clip_region(x, y, width, height,
|
|
533 tx, ty, tw, PAN_OUTLINE_THICKNESS,
|
|
534 &rx, &ry, &rw, &rh))
|
|
535 {
|
|
536 pixbuf_draw_rect_fill(pixbuf,
|
|
537 rx - x, ry - y, rw, rh,
|
|
538 PAN_OUTLINE_COLOR_1, PAN_OUTLINE_ALPHA);
|
|
539 }
|
|
540 if (util_clip_region(x, y, width, height,
|
|
541 tx, ty, PAN_OUTLINE_THICKNESS, th,
|
|
542 &rx, &ry, &rw, &rh))
|
|
543 {
|
|
544 pixbuf_draw_rect_fill(pixbuf,
|
|
545 rx - x, ry - y, rw, rh,
|
|
546 PAN_OUTLINE_COLOR_1, PAN_OUTLINE_ALPHA);
|
|
547 }
|
|
548 if (util_clip_region(x, y, width, height,
|
|
549 tx + tw - PAN_OUTLINE_THICKNESS, ty + PAN_OUTLINE_THICKNESS,
|
|
550 PAN_OUTLINE_THICKNESS, th - PAN_OUTLINE_THICKNESS,
|
|
551 &rx, &ry, &rw, &rh))
|
|
552 {
|
|
553 pixbuf_draw_rect_fill(pixbuf,
|
|
554 rx - x, ry - y, rw, rh,
|
|
555 PAN_OUTLINE_COLOR_2, PAN_OUTLINE_ALPHA);
|
|
556 }
|
|
557 if (util_clip_region(x, y, width, height,
|
|
558 tx + PAN_OUTLINE_THICKNESS, ty + th - PAN_OUTLINE_THICKNESS,
|
|
559 tw - PAN_OUTLINE_THICKNESS * 2, PAN_OUTLINE_THICKNESS,
|
|
560 &rx, &ry, &rw, &rh))
|
|
561 {
|
|
562 pixbuf_draw_rect_fill(pixbuf,
|
|
563 rx - x, ry - y, rw, rh,
|
|
564 PAN_OUTLINE_COLOR_2, PAN_OUTLINE_ALPHA);
|
|
565 }
|
|
566 }
|
|
567 else
|
|
568 {
|
|
569 tw = pi->width - PAN_SHADOW_OFFSET * 2;
|
|
570 th = pi->height - PAN_SHADOW_OFFSET * 2;
|
|
571 tx = pi->x + PAN_SHADOW_OFFSET;
|
|
572 ty = pi->y + PAN_SHADOW_OFFSET;
|
|
573
|
|
574 if (util_clip_region(x, y, width, height,
|
|
575 tx, ty, tw, th,
|
|
576 &rx, &ry, &rw, &rh))
|
|
577 {
|
|
578 gint d;
|
|
579
|
|
580 d = (pw->size <= PAN_IMAGE_SIZE_THUMB_NONE) ? 2 : 8;
|
|
581 pixbuf_draw_rect_fill(pixbuf,
|
|
582 rx - x, ry - y, rw, rh,
|
|
583 PAN_SHADOW_COLOR,
|
|
584 PAN_SHADOW_ALPHA / d);
|
|
585 }
|
|
586 }
|
|
587
|
|
588 return (pi->pixbuf == NULL);
|
|
589 }
|
|
590
|
|
591
|
|
592 /*
|
|
593 *-----------------------------------------------------------------------------
|
|
594 * item image type
|
|
595 *-----------------------------------------------------------------------------
|
|
596 */
|
|
597
|
|
598 static void pan_item_image_find_size(PanWindow *pw, PanItem *pi, gint w, gint h)
|
|
599 {
|
|
600 GList *work;
|
|
601
|
|
602 pi->width = w;
|
|
603 pi->height = h;
|
|
604
|
|
605 if (!pi->fd) return;
|
|
606
|
|
607 work = pw->cache_list;
|
|
608 while (work)
|
|
609 {
|
|
610 PanCacheData *pc;
|
|
611
|
|
612 pc = work->data;
|
|
613 work = work->next;
|
|
614
|
|
615 if (pc->cd && pc->cd->dimensions &&
|
138
|
616 pc->fd && pc->fd == pi->fd)
|
105
|
617 {
|
|
618 pi->width = MAX(1, pc->cd->width * pw->image_size / 100);
|
|
619 pi->height = MAX(1, pc->cd->height * pw->image_size / 100);
|
|
620
|
|
621 pw->cache_list = g_list_remove(pw->cache_list, pc);
|
|
622 cache_sim_data_free(pc->cd);
|
138
|
623 file_data_unref(pc->fd);
|
|
624 g_free(pc);
|
105
|
625 return;
|
|
626 }
|
|
627 }
|
|
628 }
|
|
629
|
|
630 PanItem *pan_item_image_new(PanWindow *pw, FileData *fd, gint x, gint y, gint w, gint h)
|
|
631 {
|
|
632 PanItem *pi;
|
|
633
|
|
634 pi = g_new0(PanItem, 1);
|
|
635 pi->type = PAN_ITEM_IMAGE;
|
|
636 pi->fd = fd;
|
|
637 pi->x = x;
|
|
638 pi->y = y;
|
|
639
|
|
640 pi->color_a = 255;
|
|
641
|
|
642 pi->color2_r = 0;
|
|
643 pi->color2_g = 0;
|
|
644 pi->color2_b = 0;
|
|
645 pi->color2_a = PAN_SHADOW_ALPHA / 2;
|
|
646
|
|
647 pan_item_image_find_size(pw, pi, w, h);
|
|
648
|
|
649 pw->list = g_list_prepend(pw->list, pi);
|
|
650
|
|
651 return pi;
|
|
652 }
|
|
653
|
|
654 gint pan_item_image_draw(PanWindow *pw, PanItem *pi, GdkPixbuf *pixbuf, PixbufRenderer *pr,
|
|
655 gint x, gint y, gint width, gint height)
|
|
656 {
|
|
657 gint rx, ry, rw, rh;
|
|
658
|
|
659 if (util_clip_region(x, y, width, height,
|
|
660 pi->x, pi->y, pi->width, pi->height,
|
|
661 &rx, &ry, &rw, &rh))
|
|
662 {
|
|
663 if (pi->pixbuf)
|
|
664 {
|
|
665 gdk_pixbuf_composite(pi->pixbuf, pixbuf, rx - x, ry - y, rw, rh,
|
|
666 (double) pi->x - x,
|
|
667 (double) pi->y - y,
|
|
668 1.0, 1.0, GDK_INTERP_NEAREST,
|
|
669 pi->color_a);
|
|
670 }
|
|
671 else
|
|
672 {
|
|
673 pixbuf_draw_rect_fill(pixbuf,
|
|
674 rx - x, ry - y, rw, rh,
|
|
675 pi->color2_r, pi->color2_g, pi->color2_b, pi->color2_a);
|
|
676 }
|
|
677 }
|
|
678
|
|
679 return (pi->pixbuf == NULL);
|
|
680 }
|
|
681
|
|
682
|
|
683 /*
|
|
684 *-----------------------------------------------------------------------------
|
|
685 * item lookup/search
|
|
686 *-----------------------------------------------------------------------------
|
|
687 */
|
|
688
|
|
689 PanItem *pan_item_find_by_key(PanWindow *pw, PanItemType type, const gchar *key)
|
|
690 {
|
|
691 GList *work;
|
|
692
|
|
693 if (!key) return NULL;
|
|
694
|
|
695 work = g_list_last(pw->list);
|
|
696 while (work)
|
|
697 {
|
|
698 PanItem *pi;
|
|
699
|
|
700 pi = work->data;
|
|
701 if ((pi->type == type || type == PAN_ITEM_NONE) &&
|
|
702 pi->key && strcmp(pi->key, key) == 0)
|
|
703 {
|
|
704 return pi;
|
|
705 }
|
|
706 work = work->prev;
|
|
707 }
|
|
708 work = g_list_last(pw->list_static);
|
|
709 while (work)
|
|
710 {
|
|
711 PanItem *pi;
|
|
712
|
|
713 pi = work->data;
|
|
714 if ((pi->type == type || type == PAN_ITEM_NONE) &&
|
|
715 pi->key && strcmp(pi->key, key) == 0)
|
|
716 {
|
|
717 return pi;
|
|
718 }
|
|
719 work = work->prev;
|
|
720 }
|
|
721
|
|
722 return NULL;
|
|
723 }
|
|
724
|
|
725 /* when ignore_case and partial are TRUE, path should be converted to lower case */
|
|
726 static GList *pan_item_find_by_path_l(GList *list, GList *search_list,
|
|
727 PanItemType type, const gchar *path,
|
|
728 gint ignore_case, gint partial)
|
|
729 {
|
|
730 GList *work;
|
|
731
|
|
732 work = g_list_last(search_list);
|
|
733 while (work)
|
|
734 {
|
|
735 PanItem *pi;
|
|
736
|
|
737 pi = work->data;
|
|
738 if ((pi->type == type || type == PAN_ITEM_NONE) && pi->fd)
|
|
739 {
|
|
740 gint match = FALSE;
|
|
741
|
|
742 if (path[0] == '/')
|
|
743 {
|
|
744 if (pi->fd->path && strcmp(path, pi->fd->path) == 0) match = TRUE;
|
|
745 }
|
|
746 else if (pi->fd->name)
|
|
747 {
|
|
748 if (partial)
|
|
749 {
|
|
750 if (ignore_case)
|
|
751 {
|
|
752 gchar *haystack;
|
|
753
|
|
754 haystack = g_utf8_strdown(pi->fd->name, -1);
|
|
755 match = (strstr(haystack, path) != NULL);
|
|
756 g_free(haystack);
|
|
757 }
|
|
758 else
|
|
759 {
|
|
760 if (strstr(pi->fd->name, path)) match = TRUE;
|
|
761 }
|
|
762 }
|
|
763 else if (ignore_case)
|
|
764 {
|
|
765 if (strcasecmp(path, pi->fd->name) == 0) match = TRUE;
|
|
766 }
|
|
767 else
|
|
768 {
|
|
769 if (strcmp(path, pi->fd->name) == 0) match = TRUE;
|
|
770 }
|
|
771 }
|
|
772
|
|
773 if (match) list = g_list_prepend(list, pi);
|
|
774 }
|
|
775 work = work->prev;
|
|
776 }
|
|
777
|
|
778 return list;
|
|
779 }
|
|
780
|
|
781 /* when ignore_case and partial are TRUE, path should be converted to lower case */
|
|
782 GList *pan_item_find_by_path(PanWindow *pw, PanItemType type, const gchar *path,
|
|
783 gint ignore_case, gint partial)
|
|
784 {
|
|
785 GList *list = NULL;
|
|
786
|
|
787 if (!path) return NULL;
|
|
788 if (partial && path[0] == '/') return NULL;
|
|
789
|
|
790 list = pan_item_find_by_path_l(list, pw->list_static, type, path, ignore_case, partial);
|
|
791 list = pan_item_find_by_path_l(list, pw->list, type, path, ignore_case, partial);
|
|
792
|
|
793 return g_list_reverse(list);
|
|
794 }
|
|
795
|
|
796 static PanItem *pan_item_find_by_coord_l(GList *list, PanItemType type, gint x, gint y, const gchar *key)
|
|
797 {
|
|
798 GList *work;
|
|
799
|
|
800 work = list;
|
|
801 while (work)
|
|
802 {
|
|
803 PanItem *pi;
|
|
804
|
|
805 pi = work->data;
|
|
806 if ((pi->type == type || type == PAN_ITEM_NONE) &&
|
|
807 x >= pi->x && x < pi->x + pi->width &&
|
|
808 y >= pi->y && y < pi->y + pi->height &&
|
|
809 (!key || (pi->key && strcmp(pi->key, key) == 0)))
|
|
810 {
|
|
811 return pi;
|
|
812 }
|
|
813 work = work->next;
|
|
814 }
|
|
815
|
|
816 return NULL;
|
|
817 }
|
|
818
|
|
819 PanItem *pan_item_find_by_coord(PanWindow *pw, PanItemType type,
|
|
820 gint x, gint y, const gchar *key)
|
|
821 {
|
|
822 PanItem *pi;
|
|
823
|
|
824 pi = pan_item_find_by_coord_l(pw->list, type, x, y, key);
|
|
825 if (pi) return pi;
|
|
826
|
|
827 return pan_item_find_by_coord_l(pw->list_static, type, x, y, key);
|
|
828 }
|
|
829
|
|
830
|
|
831 /*
|
|
832 *-----------------------------------------------------------------------------
|
|
833 * text alignments
|
|
834 *-----------------------------------------------------------------------------
|
|
835 */
|
|
836
|
|
837 PanTextAlignment *pan_text_alignment_new(PanWindow *pw, gint x, gint y, const gchar *key)
|
|
838 {
|
|
839 PanTextAlignment *ta;
|
|
840
|
|
841 ta = g_new0(PanTextAlignment, 1);
|
|
842
|
|
843 ta->pw = pw;
|
|
844 ta->column1 = NULL;
|
|
845 ta->column2 = NULL;
|
|
846 ta->x = x;
|
|
847 ta->y = y;
|
|
848 ta->key = g_strdup(key);
|
|
849
|
|
850 return ta;
|
|
851 }
|
|
852
|
|
853 void pan_text_alignment_free(PanTextAlignment *ta)
|
|
854 {
|
|
855 if (!ta) return;
|
|
856
|
|
857 g_list_free(ta->column1);
|
|
858 g_list_free(ta->column2);
|
|
859 g_free(ta->key);
|
|
860 g_free(ta);
|
|
861 }
|
|
862
|
|
863 PanItem *pan_text_alignment_add(PanTextAlignment *ta, const gchar *label, const gchar *text)
|
|
864 {
|
|
865 PanItem *item;
|
|
866
|
|
867 if (label)
|
|
868 {
|
|
869 item = pan_item_text_new(ta->pw, ta->x, ta->y, label,
|
|
870 PAN_TEXT_ATTR_BOLD, 0,
|
|
871 PAN_POPUP_TEXT_COLOR, 255);
|
|
872 pan_item_set_key(item, ta->key);
|
|
873 }
|
|
874 else
|
|
875 {
|
|
876 item = NULL;
|
|
877 }
|
|
878 ta->column1 = g_list_append(ta->column1, item);
|
|
879
|
|
880 if (text)
|
|
881 {
|
|
882 item = pan_item_text_new(ta->pw, ta->x, ta->y, text,
|
|
883 PAN_TEXT_ATTR_NONE, 0,
|
|
884 PAN_POPUP_TEXT_COLOR, 255);
|
|
885 pan_item_set_key(item, ta->key);
|
|
886 }
|
|
887 else
|
|
888 {
|
|
889 item = NULL;
|
|
890 }
|
|
891 ta->column2 = g_list_append(ta->column2, item);
|
|
892
|
|
893 return item;
|
|
894 }
|
|
895
|
|
896 void pan_text_alignment_calc(PanTextAlignment *ta, PanItem *box)
|
|
897 {
|
|
898 gint cw1, cw2;
|
|
899 gint x, y;
|
|
900 GList *work1;
|
|
901 GList *work2;
|
|
902
|
|
903 cw1 = 0;
|
|
904 cw2 = 0;
|
|
905
|
|
906 work1 = ta->column1;
|
|
907 while (work1)
|
|
908 {
|
|
909 PanItem *p;
|
|
910
|
|
911 p = work1->data;
|
|
912 work1 = work1->next;
|
|
913
|
|
914 if (p && p->width > cw1) cw1 = p->width;
|
|
915 }
|
|
916
|
|
917 work2 = ta->column2;
|
|
918 while (work2)
|
|
919 {
|
|
920 PanItem *p;
|
|
921
|
|
922 p = work2->data;
|
|
923 work2 = work2->next;
|
|
924
|
|
925 if (p && p->width > cw2) cw2 = p->width;
|
|
926 }
|
|
927
|
|
928 x = ta->x;
|
|
929 y = ta->y;
|
|
930 work1 = ta->column1;
|
|
931 work2 = ta->column2;
|
|
932 while (work1 && work2)
|
|
933 {
|
|
934 PanItem *p1;
|
|
935 PanItem *p2;
|
|
936 gint height = 0;
|
|
937
|
|
938 p1 = work1->data;
|
|
939 p2 = work2->data;
|
|
940 work1 = work1->next;
|
|
941 work2 = work2->next;
|
|
942
|
|
943 if (p1)
|
|
944 {
|
|
945 p1->x = x;
|
|
946 p1->y = y;
|
|
947 pan_item_size_by_item(box, p1, PREF_PAD_BORDER);
|
|
948 height = p1->height;
|
|
949 }
|
|
950 if (p2)
|
|
951 {
|
|
952 p2->x = x + cw1 + PREF_PAD_SPACE;
|
|
953 p2->y = y;
|
|
954 pan_item_size_by_item(box, p2, PREF_PAD_BORDER);
|
|
955 if (height < p2->height) height = p2->height;
|
|
956 }
|
|
957
|
|
958 if (!p1 && !p2) height = PREF_PAD_GROUP;
|
|
959
|
|
960 y += height;
|
|
961 }
|
|
962 }
|