Mercurial > geeqie
annotate src/pan-folder.c @ 1808:6c61c246506b
Fix a small issue with strptime
strptime do not initialize all fields. So the undefined fields could end
in crash later on.
author | mow |
---|---|
date | Sun, 28 Feb 2010 15:17:12 +0000 |
parents | 956aab097ea7 |
children |
rev | line source |
---|---|
105 | 1 /* |
196 | 2 * Geeqie |
105 | 3 * (C) 2006 John Ellis |
1802 | 4 * Copyright (C) 2008 - 2010 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 #include <math.h> | |
18 | |
19 | |
20 static void pan_flower_size(PanWindow *pw, gint *width, gint *height) | |
21 { | |
22 GList *work; | |
23 gint x1, y1, x2, y2; | |
24 | |
25 x1 = 0; | |
26 y1 = 0; | |
27 x2 = 0; | |
28 y2 = 0; | |
29 | |
30 work = pw->list; | |
31 while (work) | |
32 { | |
33 PanItem *pi; | |
34 | |
35 pi = work->data; | |
36 work = work->next; | |
37 | |
38 if (x1 > pi->x) x1 = pi->x; | |
39 if (y1 > pi->y) y1 = pi->y; | |
40 if (x2 < pi->x + pi->width) x2 = pi->x + pi->width; | |
41 if (y2 < pi->y + pi->height) y2 = pi->y + pi->height; | |
42 } | |
43 | |
44 x1 -= PAN_BOX_BORDER; | |
45 y1 -= PAN_BOX_BORDER; | |
46 x2 += PAN_BOX_BORDER; | |
47 y2 += PAN_BOX_BORDER; | |
48 | |
49 work = pw->list; | |
50 while (work) | |
51 { | |
52 PanItem *pi; | |
53 | |
54 pi = work->data; | |
55 work = work->next; | |
56 | |
57 pi->x -= x1; | |
58 pi->y -= y1; | |
59 | |
60 if (pi->type == PAN_ITEM_TRIANGLE && pi->data) | |
61 { | |
62 gint *coord; | |
63 | |
64 coord = pi->data; | |
65 coord[0] -= x1; | |
66 coord[1] -= y1; | |
67 coord[2] -= x1; | |
68 coord[3] -= y1; | |
69 coord[4] -= x1; | |
70 coord[5] -= y1; | |
71 } | |
72 } | |
73 | |
74 if (width) *width = x2 - x1; | |
75 if (height) *height = y2 - y1; | |
76 } | |
77 | |
78 typedef struct _FlowerGroup FlowerGroup; | |
79 struct _FlowerGroup { | |
80 GList *items; | |
81 GList *children; | |
82 gint x; | |
83 gint y; | |
84 gint width; | |
85 gint height; | |
86 | |
87 gdouble angle; | |
88 gint circumference; | |
89 gint diameter; | |
90 }; | |
91 | |
92 static void pan_flower_move(FlowerGroup *group, gint x, gint y) | |
93 { | |
94 GList *work; | |
95 | |
96 work = group->items; | |
97 while (work) | |
98 { | |
99 PanItem *pi; | |
100 | |
101 pi = work->data; | |
102 work = work->next; | |
103 | |
104 pi->x += x; | |
105 pi->y += y; | |
106 } | |
107 | |
108 group->x += x; | |
109 group->y += y; | |
110 } | |
111 | |
1434 | 112 #define PI 3.14159265 |
105 | 113 |
114 static void pan_flower_position(FlowerGroup *group, FlowerGroup *parent, | |
115 gint *result_x, gint *result_y) | |
116 { | |
117 gint x, y; | |
118 gint radius; | |
119 gdouble a; | |
120 | |
121 radius = parent->circumference / (2*PI); | |
122 radius = MAX(radius, parent->diameter / 2 + group->diameter / 2); | |
123 | |
124 a = 2*PI * group->diameter / parent->circumference; | |
125 | |
1000
4fe8f9656107
For the sake of consistency, use glib basic types everywhere.
zas_
parents:
875
diff
changeset
|
126 x = (gint)((gdouble)radius * cos(parent->angle + a / 2)); |
4fe8f9656107
For the sake of consistency, use glib basic types everywhere.
zas_
parents:
875
diff
changeset
|
127 y = (gint)((gdouble)radius * sin(parent->angle + a / 2)); |
105 | 128 |
129 parent->angle += a; | |
130 | |
131 x += parent->x; | |
132 y += parent->y; | |
133 | |
134 x += parent->width / 2; | |
135 y += parent->height / 2; | |
136 | |
137 x -= group->width / 2; | |
138 y -= group->height / 2; | |
139 | |
140 *result_x = x; | |
141 *result_y = y; | |
142 } | |
143 | |
144 static void pan_flower_build(PanWindow *pw, FlowerGroup *group, FlowerGroup *parent) | |
145 { | |
146 GList *work; | |
147 gint x, y; | |
148 | |
149 if (!group) return; | |
150 | |
151 if (parent && parent->children) | |
152 { | |
153 pan_flower_position(group, parent, &x, &y); | |
154 } | |
155 else | |
156 { | |
157 x = 0; | |
158 y = 0; | |
159 } | |
160 | |
161 pan_flower_move(group, x, y); | |
162 | |
163 if (parent) | |
164 { | |
165 PanItem *pi; | |
166 gint px, py, gx, gy; | |
167 gint x1, y1, x2, y2; | |
168 | |
169 px = parent->x + parent->width / 2; | |
170 py = parent->y + parent->height / 2; | |
171 | |
172 gx = group->x + group->width / 2; | |
173 gy = group->y + group->height / 2; | |
174 | |
175 x1 = MIN(px, gx); | |
176 y1 = MIN(py, gy); | |
177 | |
178 x2 = MAX(px, gx + 5); | |
179 y2 = MAX(py, gy + 5); | |
180 | |
181 pi = pan_item_tri_new(pw, NULL, x1, y1, x2 - x1, y2 - y1, | |
182 px, py, gx, gy, gx + 5, gy + 5, | |
183 255, 40, 40, 128); | |
184 pan_item_tri_border(pi, PAN_BORDER_1 | PAN_BORDER_3, | |
185 255, 0, 0, 128); | |
186 } | |
187 | |
188 pw->list = g_list_concat(group->items, pw->list); | |
189 group->items = NULL; | |
190 | |
191 group->circumference = 0; | |
192 work = group->children; | |
193 while (work) | |
194 { | |
195 FlowerGroup *child; | |
196 | |
197 child = work->data; | |
198 work = work->next; | |
199 | |
200 group->circumference += child->diameter; | |
201 } | |
202 | |
203 work = g_list_last(group->children); | |
204 while (work) | |
205 { | |
206 FlowerGroup *child; | |
207 | |
208 child = work->data; | |
209 work = work->prev; | |
210 | |
211 pan_flower_build(pw, child, group); | |
212 } | |
213 | |
214 g_list_free(group->children); | |
215 g_free(group); | |
216 } | |
217 | |
783 | 218 static FlowerGroup *pan_flower_group(PanWindow *pw, FileData *dir_fd, gint x, gint y) |
105 | 219 { |
220 FlowerGroup *group; | |
221 GList *f; | |
222 GList *d; | |
223 GList *work; | |
224 PanItem *pi_box; | |
225 gint x_start; | |
226 gint y_height; | |
227 gint grid_size; | |
228 gint grid_count; | |
229 | |
783 | 230 if (!filelist_read(dir_fd, &f, &d)) return NULL; |
105 | 231 if (!f && !d) return NULL; |
232 | |
233 f = filelist_sort(f, SORT_NAME, TRUE); | |
234 d = filelist_sort(d, SORT_NAME, TRUE); | |
235 | |
783 | 236 pi_box = pan_item_text_new(pw, x, y, dir_fd->path, PAN_TEXT_ATTR_NONE, |
105 | 237 PAN_TEXT_BORDER_SIZE, |
238 PAN_TEXT_COLOR, 255); | |
239 | |
240 y += pi_box->height; | |
241 | |
875
f103af877504
Fix missing references for the current directory in pan folder stuff.
zas_
parents:
783
diff
changeset
|
242 pi_box = pan_item_box_new(pw, file_data_ref(dir_fd), |
105 | 243 x, y, |
244 PAN_BOX_BORDER * 2, PAN_BOX_BORDER * 2, | |
245 PAN_BOX_OUTLINE_THICKNESS, | |
246 PAN_BOX_COLOR, PAN_BOX_ALPHA, | |
247 PAN_BOX_OUTLINE_COLOR, PAN_BOX_OUTLINE_ALPHA); | |
248 | |
249 x += PAN_BOX_BORDER; | |
250 y += PAN_BOX_BORDER; | |
251 | |
252 grid_size = (gint)(sqrt(g_list_length(f)) + 0.9); | |
253 grid_count = 0; | |
254 x_start = x; | |
255 y_height = y; | |
256 | |
257 work = f; | |
258 while (work) | |
259 { | |
260 FileData *fd; | |
261 PanItem *pi; | |
262 | |
263 fd = work->data; | |
264 work = work->next; | |
265 | |
266 if (pw->size > PAN_IMAGE_SIZE_THUMB_LARGE) | |
267 { | |
268 pi = pan_item_image_new(pw, fd, x, y, 10, 10); | |
269 x += pi->width + PAN_THUMB_GAP; | |
270 if (pi->height > y_height) y_height = pi->height; | |
271 } | |
272 else | |
273 { | |
274 pi = pan_item_thumb_new(pw, fd, x, y); | |
275 x += PAN_THUMB_SIZE + PAN_THUMB_GAP; | |
276 y_height = PAN_THUMB_SIZE; | |
277 } | |
278 | |
279 grid_count++; | |
280 if (grid_count >= grid_size) | |
281 { | |
282 grid_count = 0; | |
283 x = x_start; | |
284 y += y_height + PAN_THUMB_GAP; | |
285 y_height = 0; | |
286 } | |
287 | |
288 pan_item_size_by_item(pi_box, pi, PAN_BOX_BORDER); | |
289 } | |
290 | |
291 group = g_new0(FlowerGroup, 1); | |
292 group->items = pw->list; | |
293 pw->list = NULL; | |
294 | |
295 group->width = pi_box->width; | |
296 group->height = pi_box->y + pi_box->height; | |
1000
4fe8f9656107
For the sake of consistency, use glib basic types everywhere.
zas_
parents:
875
diff
changeset
|
297 group->diameter = (gint)sqrt(group->width * group->width + group->height * group->height); |
105 | 298 |
299 group->children = NULL; | |
300 | |
301 work = d; | |
302 while (work) | |
303 { | |
304 FileData *fd; | |
305 FlowerGroup *child; | |
306 | |
307 fd = work->data; | |
308 work = work->next; | |
309 | |
310 if (!pan_is_ignored(fd->path, pw->ignore_symlinks)) | |
311 { | |
783 | 312 child = pan_flower_group(pw, fd, 0, 0); |
105 | 313 if (child) group->children = g_list_prepend(group->children, child); |
314 } | |
315 } | |
316 | |
317 if (!f && !group->children) | |
318 { | |
319 work = group->items; | |
320 while (work) | |
321 { | |
322 PanItem *pi; | |
323 | |
324 pi = work->data; | |
325 work = work->next; | |
326 | |
327 pan_item_free(pi); | |
328 } | |
329 | |
330 g_list_free(group->items); | |
331 g_free(group); | |
332 group = NULL; | |
333 } | |
334 | |
335 g_list_free(f); | |
336 filelist_free(d); | |
337 | |
338 return group; | |
339 } | |
340 | |
783 | 341 void pan_flower_compute(PanWindow *pw, FileData *dir_fd, |
105 | 342 gint *width, gint *height, |
343 gint *scroll_x, gint *scroll_y) | |
344 { | |
345 FlowerGroup *group; | |
346 GList *list; | |
347 | |
783 | 348 group = pan_flower_group(pw, dir_fd, 0, 0); |
105 | 349 pan_flower_build(pw, group, NULL); |
350 | |
351 pan_flower_size(pw, width, height); | |
352 | |
783 | 353 list = pan_item_find_by_fd(pw, PAN_ITEM_BOX, dir_fd, FALSE, FALSE); |
105 | 354 if (list) |
355 { | |
356 PanItem *pi = list->data; | |
357 *scroll_x = pi->x + pi->width / 2; | |
358 *scroll_y = pi->y + pi->height / 2; | |
359 } | |
360 g_list_free(list); | |
361 } | |
362 | |
783 | 363 static void pan_folder_tree_path(PanWindow *pw, FileData *dir_fd, |
105 | 364 gint *x, gint *y, gint *level, |
365 PanItem *parent, | |
366 gint *width, gint *height) | |
367 { | |
368 GList *f; | |
369 GList *d; | |
370 GList *work; | |
371 PanItem *pi_box; | |
372 gint y_height = 0; | |
373 | |
783 | 374 if (!filelist_read(dir_fd, &f, &d)) return; |
105 | 375 if (!f && !d) return; |
376 | |
377 f = filelist_sort(f, SORT_NAME, TRUE); | |
378 d = filelist_sort(d, SORT_NAME, TRUE); | |
379 | |
380 *x = PAN_BOX_BORDER + ((*level) * MAX(PAN_BOX_BORDER, PAN_THUMB_GAP)); | |
381 | |
783 | 382 pi_box = pan_item_text_new(pw, *x, *y, dir_fd->path, PAN_TEXT_ATTR_NONE, |
105 | 383 PAN_TEXT_BORDER_SIZE, |
384 PAN_TEXT_COLOR, 255); | |
385 | |
386 *y += pi_box->height; | |
387 | |
875
f103af877504
Fix missing references for the current directory in pan folder stuff.
zas_
parents:
783
diff
changeset
|
388 pi_box = pan_item_box_new(pw, file_data_ref(dir_fd), |
105 | 389 *x, *y, |
390 PAN_BOX_BORDER, PAN_BOX_BORDER, | |
391 PAN_BOX_OUTLINE_THICKNESS, | |
392 PAN_BOX_COLOR, PAN_BOX_ALPHA, | |
393 PAN_BOX_OUTLINE_COLOR, PAN_BOX_OUTLINE_ALPHA); | |
394 | |
395 *x += PAN_BOX_BORDER; | |
396 *y += PAN_BOX_BORDER; | |
397 | |
398 work = f; | |
399 while (work) | |
400 { | |
401 FileData *fd; | |
402 PanItem *pi; | |
403 | |
404 fd = work->data; | |
405 work = work->next; | |
406 | |
407 if (pw->size > PAN_IMAGE_SIZE_THUMB_LARGE) | |
408 { | |
409 pi = pan_item_image_new(pw, fd, *x, *y, 10, 10); | |
410 *x += pi->width + PAN_THUMB_GAP; | |
411 if (pi->height > y_height) y_height = pi->height; | |
412 } | |
413 else | |
414 { | |
415 pi = pan_item_thumb_new(pw, fd, *x, *y); | |
416 *x += PAN_THUMB_SIZE + PAN_THUMB_GAP; | |
417 y_height = PAN_THUMB_SIZE; | |
418 } | |
419 | |
420 pan_item_size_by_item(pi_box, pi, PAN_BOX_BORDER); | |
421 } | |
422 | |
423 if (f) *y = pi_box->y + pi_box->height; | |
424 | |
425 g_list_free(f); | |
426 | |
427 work = d; | |
428 while (work) | |
429 { | |
430 FileData *fd; | |
431 | |
432 fd = work->data; | |
433 work = work->next; | |
434 | |
435 if (!pan_is_ignored(fd->path, pw->ignore_symlinks)) | |
436 { | |
437 *level = *level + 1; | |
783 | 438 pan_folder_tree_path(pw, fd, x, y, level, pi_box, width, height); |
105 | 439 *level = *level - 1; |
440 } | |
441 } | |
442 | |
443 filelist_free(d); | |
444 | |
445 pan_item_size_by_item(parent, pi_box, PAN_BOX_BORDER); | |
446 | |
447 if (*y < pi_box->y + pi_box->height + PAN_BOX_BORDER) | |
448 *y = pi_box->y + pi_box->height + PAN_BOX_BORDER; | |
449 | |
450 pan_item_size_coordinates(pi_box, PAN_BOX_BORDER, width, height); | |
451 } | |
452 | |
783 | 453 void pan_folder_tree_compute(PanWindow *pw, FileData *dir_fd, gint *width, gint *height) |
105 | 454 { |
455 gint x, y; | |
456 gint level; | |
457 gint w, h; | |
458 | |
459 level = 0; | |
460 x = PAN_BOX_BORDER; | |
461 y = PAN_BOX_BORDER; | |
462 w = PAN_BOX_BORDER * 2; | |
463 h = PAN_BOX_BORDER * 2; | |
464 | |
783 | 465 pan_folder_tree_path(pw, dir_fd, &x, &y, &level, NULL, &w, &h); |
105 | 466 |
467 if (width) *width = w; | |
468 if (height) *height = h; | |
469 } | |
1055
1646720364cf
Adding a vim modeline to all files - patch by Klaus Ethgen
nadvornik
parents:
1000
diff
changeset
|
470 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */ |