7 * This software is released under the GNU General Public License (GNU GPL).
8 * Please read the included file COPYING for more information.
9 * This software comes with no warranty of any kind, use at your own risk!
14 #include "pan-types.h"
19 #define PAN_CAL_POPUP_COLOR 220, 220, 220
20 #define PAN_CAL_POPUP_ALPHA 255
21 #define PAN_CAL_POPUP_BORDER 1
22 #define PAN_CAL_POPUP_BORDER_COLOR 0, 0, 0
23 #define PAN_CAL_POPUP_TEXT_COLOR 0, 0, 0
25 #define PAN_CAL_DAY_WIDTH 100
26 #define PAN_CAL_DAY_HEIGHT 80
28 #define PAN_CAL_DAY_COLOR 255, 255, 255
29 #define PAN_CAL_DAY_ALPHA 220
30 #define PAN_CAL_DAY_BORDER 2
31 #define PAN_CAL_DAY_BORDER_COLOR 0, 0, 0
32 #define PAN_CAL_DAY_TEXT_COLOR 0, 0, 0
34 #define PAN_CAL_MONTH_COLOR 255, 255, 255
35 #define PAN_CAL_MONTH_ALPHA 200
36 #define PAN_CAL_MONTH_BORDER 4
37 #define PAN_CAL_MONTH_BORDER_COLOR 0, 0, 0
38 #define PAN_CAL_MONTH_TEXT_COLOR 0, 0, 0
40 #define PAN_CAL_DOT_SIZE 3
41 #define PAN_CAL_DOT_GAP 2
42 #define PAN_CAL_DOT_COLOR 128, 128, 128
43 #define PAN_CAL_DOT_ALPHA 128
47 *-----------------------------------------------------------------------------
49 *-----------------------------------------------------------------------------
52 void pan_calendar_update(PanWindow *pw, PanItem *pi_day)
58 gint x1, y1, x2, y2, x3, y3;
63 while ((pi = pan_item_find_by_key(pw, PAN_ITEM_NONE, "day_bubble"))) pan_item_remove(pw, pi);
65 if (!pi_day || pi_day->type != PAN_ITEM_BOX ||
66 !pi_day->key || strcmp(pi_day->key, "day") != 0) return;
68 list = pan_layout_intersect(pw, pi_day->x, pi_day->y, pi_day->width, pi_day->height);
80 if (dot->type != PAN_ITEM_BOX || !dot->fd ||
81 !dot->key || strcmp(dot->key, "dot") != 0)
83 list = g_list_delete_link(list, node);
91 grid = (gint)(sqrt(g_list_length(list)) + 0.5);
93 x = pi_day->x + pi_day->width + 4;
97 if (y + grid * (PAN_THUMB_SIZE + PAN_THUMB_GAP) + PAN_BOX_BORDER * 4 > pw->pr->image_height)
99 y = pw->pr->image_height - (grid * (PAN_THUMB_SIZE + PAN_THUMB_GAP) + PAN_BOX_BORDER * 4);
103 pbox = pan_item_box_new(pw, NULL, x, y, PAN_BOX_BORDER, PAN_BOX_BORDER,
104 PAN_CAL_POPUP_BORDER,
105 PAN_CAL_POPUP_COLOR, PAN_CAL_POPUP_ALPHA,
106 PAN_CAL_POPUP_BORDER_COLOR, PAN_CAL_POPUP_ALPHA);
107 pan_item_set_key(pbox, "day_bubble");
114 buf = pan_date_value_string(pi_day->fd->date, PAN_DATE_LENGTH_WEEK);
115 plabel = pan_item_text_new(pw, x, y, buf, PAN_TEXT_ATTR_BOLD | PAN_TEXT_ATTR_HEADING,
116 PAN_TEXT_BORDER_SIZE,
117 PAN_CAL_POPUP_TEXT_COLOR, 255);
118 pan_item_set_key(plabel, "day_bubble");
121 pan_item_size_by_item(pbox, plabel, 0);
145 pimg = pan_item_thumb_new(pw, file_data_ref(dot->fd), x, y);
146 pan_item_set_key(pimg, "day_bubble");
148 pan_item_size_by_item(pbox, pimg, PAN_BOX_BORDER);
153 x += PAN_THUMB_SIZE + PAN_THUMB_GAP;
158 x = pbox->x + PAN_BOX_BORDER;
159 y += PAN_THUMB_SIZE + PAN_THUMB_GAP;
165 x1 = pi_day->x + pi_day->width - 8;
168 y2 = pbox->y + MIN(42, pbox->height);
170 y3 = MAX(pbox->y, y2 - 30);
171 util_clip_triangle(x1, y1, x2, y2, x3, y3,
174 pi = pan_item_tri_new(pw, NULL, x, y, w, h,
175 x1, y1, x2, y2, x3, y3,
176 PAN_CAL_POPUP_COLOR, PAN_CAL_POPUP_ALPHA);
177 pan_item_tri_border(pi, PAN_BORDER_1 | PAN_BORDER_3, PAN_CAL_POPUP_BORDER_COLOR, PAN_CAL_POPUP_ALPHA);
178 pan_item_set_key(pi, "day_bubble");
179 pan_item_added(pw, pi);
181 pan_item_box_shadow(pbox, PAN_SHADOW_OFFSET * 2, PAN_SHADOW_FADE * 2);
182 pan_item_added(pw, pbox);
184 pan_layout_resize(pw);
187 void pan_calendar_compute(PanWindow *pw, const gchar *path, gint *width, gint *height)
203 list = pan_list_tree(path, SORT_NONE, TRUE, pw->ignore_symlinks);
205 if (pw->cache_list && pw->exif_date_enable)
207 pw->cache_list = pan_cache_sort(pw->cache_list, SORT_NAME, TRUE);
208 list = filelist_sort(list, SORT_NAME, TRUE);
209 pan_cache_sync_date(pw, list);
212 pw->cache_list = pan_cache_sort(pw->cache_list, SORT_TIME, TRUE);
213 list = filelist_sort(list, SORT_TIME, TRUE);
226 if (!pan_date_compare(fd->date, tc, PAN_DATE_LENGTH_DAY))
234 if (day_max < count) day_max = count;
238 if (debug) printf("biggest day contains %d images\n", day_max);
240 grid = (gint)(sqrt((double)day_max) + 0.5) * (PAN_THUMB_SIZE + PAN_SHADOW_OFFSET * 2 + PAN_THUMB_GAP);
241 day_width = MAX(PAN_CAL_DAY_WIDTH, grid);
242 day_height = MAX(PAN_CAL_DAY_HEIGHT, grid);
246 FileData *fd = list->data;
248 year = pan_date_value(fd->date, PAN_DATE_LENGTH_YEAR);
249 month = pan_date_value(fd->date, PAN_DATE_LENGTH_MONTH);
252 work = g_list_last(list);
255 FileData *fd = work->data;
256 end_year = pan_date_value(fd->date, PAN_DATE_LENGTH_YEAR);
257 end_month = pan_date_value(fd->date, PAN_DATE_LENGTH_MONTH);
260 *width = PAN_BOX_BORDER * 2;
261 *height = PAN_BOX_BORDER * 2;
267 while (work && (year < end_year || (year == end_year && month <= end_month)))
278 /* figure last second of this month */
279 dt = pan_date_to_time((month == 12) ? year + 1 : year, (month == 12) ? 1 : month + 1, 1);
282 /* anything to show this month? */
283 if (!pan_date_compare(((FileData *)(work->data))->date, dt, PAN_DATE_LENGTH_MONTH))
294 days = pan_date_value(dt, PAN_DATE_LENGTH_DAY);
295 dt = pan_date_to_time(year, month, 1);
296 col = pan_date_value(dt, PAN_DATE_LENGTH_WEEK);
301 pi_month = pan_item_box_new(pw, NULL, x, y, PAN_CAL_DAY_WIDTH * 7, PAN_CAL_DAY_HEIGHT / 4,
302 PAN_CAL_MONTH_BORDER,
303 PAN_CAL_MONTH_COLOR, PAN_CAL_MONTH_ALPHA,
304 PAN_CAL_MONTH_BORDER_COLOR, PAN_CAL_MONTH_ALPHA);
305 buf = pan_date_value_string(dt, PAN_DATE_LENGTH_MONTH);
306 pi_text = pan_item_text_new(pw, x, y, buf,
307 PAN_TEXT_ATTR_BOLD | PAN_TEXT_ATTR_HEADING,
308 PAN_TEXT_BORDER_SIZE,
309 PAN_CAL_MONTH_TEXT_COLOR, 255);
311 pi_text->x = pi_month->x + (pi_month->width - pi_text->width) / 2;
313 pi_month->height = pi_text->y + pi_text->height - pi_month->y;
315 x = PAN_BOX_BORDER + col * PAN_CAL_DAY_WIDTH;
316 y = pi_month->y + pi_month->height + PAN_BOX_BORDER;
318 for (day = 1; day <= days; day++)
325 dt = pan_date_to_time(year, month, day);
327 fd = g_new0(FileData, 1);
328 /* path and name must be non NULL, so make them an invalid filename */
329 fd->path = g_strdup("//");
332 pi_day = pan_item_box_new(pw, fd, x, y, PAN_CAL_DAY_WIDTH, PAN_CAL_DAY_HEIGHT,
334 PAN_CAL_DAY_COLOR, PAN_CAL_DAY_ALPHA,
335 PAN_CAL_DAY_BORDER_COLOR, PAN_CAL_DAY_ALPHA);
336 pan_item_set_key(pi_day, "day");
338 dx = x + PAN_CAL_DOT_GAP * 2;
339 dy = y + PAN_CAL_DOT_GAP * 2;
341 fd = (work) ? work->data : NULL;
342 while (fd && pan_date_compare(fd->date, dt, PAN_DATE_LENGTH_DAY))
346 pi = pan_item_box_new(pw, fd, dx, dy, PAN_CAL_DOT_SIZE, PAN_CAL_DOT_SIZE,
348 PAN_CAL_DOT_COLOR, PAN_CAL_DOT_ALPHA,
350 pan_item_set_key(pi, "dot");
352 dx += PAN_CAL_DOT_SIZE + PAN_CAL_DOT_GAP;
353 if (dx + PAN_CAL_DOT_SIZE > pi_day->x + pi_day->width - PAN_CAL_DOT_GAP * 2)
355 dx = x + PAN_CAL_DOT_GAP * 2;
356 dy += PAN_CAL_DOT_SIZE + PAN_CAL_DOT_GAP;
358 if (dy + PAN_CAL_DOT_SIZE > pi_day->y + pi_day->height - PAN_CAL_DOT_GAP * 2)
360 /* must keep all dots within respective day even if it gets ugly */
361 dy = y + PAN_CAL_DOT_GAP * 2;
367 fd = (work) ? work->data : NULL;
374 pi_day->color_r = MAX(pi_day->color_r - 61 - n * 3, 80);
375 pi_day->color_g = pi_day->color_r;
377 buf = g_strdup_printf("( %d )", n);
378 pi = pan_item_text_new(pw, x, y, buf, PAN_TEXT_ATTR_NONE,
379 PAN_TEXT_BORDER_SIZE,
380 PAN_CAL_DAY_TEXT_COLOR, 255);
383 pi->x = pi_day->x + (pi_day->width - pi->width) / 2;
384 pi->y = pi_day->y + (pi_day->height - pi->height) / 2;
387 buf = g_strdup_printf("%d", day);
388 pan_item_text_new(pw, x + 4, y + 4, buf, PAN_TEXT_ATTR_BOLD | PAN_TEXT_ATTR_HEADING,
389 PAN_TEXT_BORDER_SIZE,
390 PAN_CAL_DAY_TEXT_COLOR, 255);
394 pan_item_size_coordinates(pi_day, PAN_BOX_BORDER, width, height);
402 y += PAN_CAL_DAY_HEIGHT;
406 x += PAN_CAL_DAY_WIDTH;
410 if (col > 0) y += PAN_CAL_DAY_HEIGHT;
411 y += PAN_BOX_BORDER * 2;
422 *height = MAX(*height, grid + PAN_BOX_BORDER * 2 * 2);