Remove commented out code.
[geeqie.git] / src / pan-calendar.c
1 /*
2  * Geeqie
3  * (C) 2006 John Ellis
4  * Copyright (C) 2008 - 2012 The Geeqie Team
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
14 #include "main.h"
15 #include "pan-types.h"
16
17 #include <glib/gprintf.h>
18 #include <math.h>
19
20
21 #define PAN_CAL_POPUP_COLOR 220, 220, 220
22 #define PAN_CAL_POPUP_ALPHA 255
23 #define PAN_CAL_POPUP_BORDER 1
24 #define PAN_CAL_POPUP_BORDER_COLOR 0, 0, 0
25 #define PAN_CAL_POPUP_TEXT_COLOR 0, 0, 0
26
27 #define PAN_CAL_DAY_WIDTH 100
28 #define PAN_CAL_DAY_HEIGHT 80
29
30 #define PAN_CAL_DAY_COLOR 255, 255, 255
31 #define PAN_CAL_DAY_ALPHA 220
32 #define PAN_CAL_DAY_BORDER 2
33 #define PAN_CAL_DAY_BORDER_COLOR 0, 0, 0
34 #define PAN_CAL_DAY_TEXT_COLOR 0, 0, 0
35
36 #define PAN_CAL_MONTH_COLOR 255, 255, 255
37 #define PAN_CAL_MONTH_ALPHA 200
38 #define PAN_CAL_MONTH_BORDER 4
39 #define PAN_CAL_MONTH_BORDER_COLOR 0, 0, 0
40 #define PAN_CAL_MONTH_TEXT_COLOR 0, 0, 0
41
42 #define PAN_CAL_DOT_SIZE 3
43 #define PAN_CAL_DOT_GAP 2
44 #define PAN_CAL_DOT_COLOR 128, 128, 128
45 #define PAN_CAL_DOT_ALPHA 128
46
47
48 /*
49  *-----------------------------------------------------------------------------
50  * calendar
51  *-----------------------------------------------------------------------------
52  */
53
54 void pan_calendar_update(PanWindow *pw, PanItem *pi_day)
55 {
56         PanItem *pbox;
57         PanItem *pi;
58         GList *list;
59         GList *work;
60         gint x1, y1, x2, y2, x3, y3;
61         gint x, y, w, h;
62         gint grid;
63         gint column;
64
65         while ((pi = pan_item_find_by_key(pw, PAN_ITEM_NONE, "day_bubble"))) pan_item_remove(pw, pi);
66
67         if (!pi_day || pi_day->type != PAN_ITEM_BOX ||
68             !pi_day->key || strcmp(pi_day->key, "day") != 0) return;
69
70         list = pan_layout_intersect(pw, pi_day->x, pi_day->y, pi_day->width, pi_day->height);
71
72         work = list;
73         while (work)
74                 {
75                 PanItem *dot;
76                 GList *node;
77
78                 dot = work->data;
79                 node = work;
80                 work = work->next;
81
82                 if (dot->type != PAN_ITEM_BOX || !dot->fd ||
83                     !dot->key || strcmp(dot->key, "dot") != 0)
84                         {
85                         list = g_list_delete_link(list, node);
86                         }
87                 }
88
89         grid = (gint)(sqrt(g_list_length(list)) + 0.5);
90
91         x = pi_day->x + pi_day->width + 4;
92         y = pi_day->y;
93
94         pbox = pan_item_box_new(pw, NULL, x, y, PAN_BOX_BORDER, PAN_BOX_BORDER,
95                                 PAN_CAL_POPUP_BORDER,
96                                 PAN_CAL_POPUP_COLOR, PAN_CAL_POPUP_ALPHA,
97                                 PAN_CAL_POPUP_BORDER_COLOR, PAN_CAL_POPUP_ALPHA);
98         pan_item_set_key(pbox, "day_bubble");
99
100         if (pi_day->fd)
101                 {
102                 PanItem *plabel;
103                 gchar *buf;
104
105                 buf = pan_date_value_string(pi_day->fd->date, PAN_DATE_LENGTH_WEEK);
106                 plabel = pan_item_text_new(pw, x, y, buf, PAN_TEXT_ATTR_BOLD | PAN_TEXT_ATTR_HEADING,
107                                            PAN_TEXT_BORDER_SIZE,
108                                            PAN_CAL_POPUP_TEXT_COLOR, 255);
109                 pan_item_set_key(plabel, "day_bubble");
110                 g_free(buf);
111
112                 pan_item_size_by_item(pbox, plabel, 0);
113
114                 y += plabel->height;
115                 }
116
117         if (list)
118                 {
119                 column = 0;
120
121                 x += PAN_BOX_BORDER;
122                 y += PAN_BOX_BORDER;
123
124                 work = list;
125                 while (work)
126                         {
127                         PanItem *dot;
128
129                         dot = work->data;
130                         work = work->next;
131
132                         if (dot->fd)
133                                 {
134                                 PanItem *pimg;
135
136                                 pimg = pan_item_thumb_new(pw, file_data_ref(dot->fd), x, y);
137                                 pan_item_set_key(pimg, "day_bubble");
138
139                                 pan_item_size_by_item(pbox, pimg, PAN_BOX_BORDER);
140
141                                 column++;
142                                 if (column < grid)
143                                         {
144                                         x += PAN_THUMB_SIZE + PAN_THUMB_GAP;
145                                         }
146                                 else
147                                         {
148                                         column = 0;
149                                         x = pbox->x + PAN_BOX_BORDER;
150                                         y += PAN_THUMB_SIZE + PAN_THUMB_GAP;
151                                         }
152                                 }
153                         }
154                 }
155
156         x1 = pi_day->x + pi_day->width - 8;
157         y1 = pi_day->y + 8;
158         x2 = pbox->x + 1;
159         y2 = pbox->y + MIN(42, pbox->height);
160         x3 = pbox->x + 1;
161         y3 = MAX(pbox->y, y2 - 30);
162         util_clip_triangle(x1, y1, x2, y2, x3, y3,
163                            &x, &y, &w, &h);
164
165         pi = pan_item_tri_new(pw, NULL, x, y, w, h,
166                               x1, y1, x2, y2, x3, y3,
167                               PAN_CAL_POPUP_COLOR, PAN_CAL_POPUP_ALPHA);
168         pan_item_tri_border(pi, PAN_BORDER_1 | PAN_BORDER_3, PAN_CAL_POPUP_BORDER_COLOR, PAN_CAL_POPUP_ALPHA);
169         pan_item_set_key(pi, "day_bubble");
170         pan_item_added(pw, pi);
171
172         pan_item_box_shadow(pbox, PAN_SHADOW_OFFSET * 2, PAN_SHADOW_FADE * 2);
173         pan_item_added(pw, pbox);
174
175         pan_layout_resize(pw);
176 }
177
178 void pan_calendar_compute(PanWindow *pw, FileData *dir_fd, gint *width, gint *height)
179 {
180         GList *list;
181         GList *work;
182         gint x, y;
183         time_t tc;
184         gint count;
185         gint day_max;
186         gint grid;
187         gint year = 0;
188         gint month = 0;
189         gint end_year = 0;
190         gint end_month = 0;
191
192         list = pan_list_tree(dir_fd, SORT_NONE, TRUE, pw->ignore_symlinks);
193
194         if (pw->cache_list && pw->exif_date_enable)
195                 {
196                 pw->cache_list = pan_cache_sort(pw->cache_list, SORT_NAME, TRUE);
197                 list = filelist_sort(list, SORT_NAME, TRUE);
198                 pan_cache_sync_date(pw, list);
199                 }
200
201         pw->cache_list = pan_cache_sort(pw->cache_list, SORT_TIME, TRUE);
202         list = filelist_sort(list, SORT_TIME, TRUE);
203
204         day_max = 0;
205         count = 0;
206         tc = 0;
207         work = list;
208         while (work)
209                 {
210                 FileData *fd;
211
212                 fd = work->data;
213                 work = work->next;
214
215                 if (!pan_date_compare(fd->date, tc, PAN_DATE_LENGTH_DAY))
216                         {
217                         count = 0;
218                         tc = fd->date;
219                         }
220                 else
221                         {
222                         count++;
223                         if (day_max < count) day_max = count;
224                         }
225                 }
226
227         DEBUG_1("biggest day contains %d images", day_max);
228
229         grid = (gint)(sqrt((gdouble)day_max) + 0.5) * (PAN_THUMB_SIZE + PAN_SHADOW_OFFSET * 2 + PAN_THUMB_GAP);
230
231         if (list)
232                 {
233                 FileData *fd = list->data;
234
235                 year = pan_date_value(fd->date, PAN_DATE_LENGTH_YEAR);
236                 month = pan_date_value(fd->date, PAN_DATE_LENGTH_MONTH);
237                 }
238
239         work = g_list_last(list);
240         if (work)
241                 {
242                 FileData *fd = work->data;
243                 end_year = pan_date_value(fd->date, PAN_DATE_LENGTH_YEAR);
244                 end_month = pan_date_value(fd->date, PAN_DATE_LENGTH_MONTH);
245                 }
246
247         *width = PAN_BOX_BORDER * 2;
248         *height = PAN_BOX_BORDER * 2;
249
250         x = PAN_BOX_BORDER;
251         y = PAN_BOX_BORDER;
252
253         work = list;
254         while (work && (year < end_year || (year == end_year && month <= end_month)))
255                 {
256                 PanItem *pi_month;
257                 PanItem *pi_text;
258                 gint day;
259                 gint days;
260                 gint col;
261                 gint row;
262                 time_t dt;
263                 gchar *buf;
264
265                 /* figure last second of this month */
266                 dt = pan_date_to_time((month == 12) ? year + 1 : year, (month == 12) ? 1 : month + 1, 1);
267                 dt -= 60 * 60 * 24;
268
269                 /* anything to show this month? */
270                 if (!pan_date_compare(((FileData *)(work->data))->date, dt, PAN_DATE_LENGTH_MONTH))
271                         {
272                         month ++;
273                         if (month > 12)
274                                 {
275                                 year++;
276                                 month = 1;
277                                 }
278                         continue;
279                         }
280
281                 days = pan_date_value(dt, PAN_DATE_LENGTH_DAY);
282                 dt = pan_date_to_time(year, month, 1);
283                 col = pan_date_value(dt, PAN_DATE_LENGTH_WEEK);
284                 row = 1;
285
286                 x = PAN_BOX_BORDER;
287
288                 pi_month = pan_item_box_new(pw, NULL, x, y, PAN_CAL_DAY_WIDTH * 7, PAN_CAL_DAY_HEIGHT / 4,
289                                             PAN_CAL_MONTH_BORDER,
290                                             PAN_CAL_MONTH_COLOR, PAN_CAL_MONTH_ALPHA,
291                                             PAN_CAL_MONTH_BORDER_COLOR, PAN_CAL_MONTH_ALPHA);
292                 buf = pan_date_value_string(dt, PAN_DATE_LENGTH_MONTH);
293                 pi_text = pan_item_text_new(pw, x, y, buf,
294                                             PAN_TEXT_ATTR_BOLD | PAN_TEXT_ATTR_HEADING,
295                                             PAN_TEXT_BORDER_SIZE,
296                                             PAN_CAL_MONTH_TEXT_COLOR, 255);
297                 g_free(buf);
298                 pi_text->x = pi_month->x + (pi_month->width - pi_text->width) / 2;
299
300                 pi_month->height = pi_text->y + pi_text->height - pi_month->y;
301
302                 x = PAN_BOX_BORDER + col * PAN_CAL_DAY_WIDTH;
303                 y = pi_month->y + pi_month->height + PAN_BOX_BORDER;
304
305                 for (day = 1; day <= days; day++)
306                         {
307                         FileData *fd;
308                         PanItem *pi_day;
309                         gint dx, dy;
310                         gint n = 0;
311                         gchar fake_path[20];
312
313                         dt = pan_date_to_time(year, month, day);
314
315                         /*
316                          * Create a FileData entry that represents the given day.
317                          * It does not correspond to any real file
318                          */
319
320                         g_snprintf(fake_path, sizeof(fake_path), "//%04d-%02d-%02d", year, month, day);
321                         fd = file_data_new_no_grouping(fake_path);
322                         fd->date = dt;
323                         pi_day = pan_item_box_new(pw, fd, x, y, PAN_CAL_DAY_WIDTH, PAN_CAL_DAY_HEIGHT,
324                                                   PAN_CAL_DAY_BORDER,
325                                                   PAN_CAL_DAY_COLOR, PAN_CAL_DAY_ALPHA,
326                                                   PAN_CAL_DAY_BORDER_COLOR, PAN_CAL_DAY_ALPHA);
327                         pan_item_set_key(pi_day, "day");
328
329                         dx = x + PAN_CAL_DOT_GAP * 2;
330                         dy = y + PAN_CAL_DOT_GAP * 2;
331
332                         fd = (work) ? work->data : NULL;
333                         while (fd && pan_date_compare(fd->date, dt, PAN_DATE_LENGTH_DAY))
334                                 {
335                                 PanItem *pi;
336
337                                 pi = pan_item_box_new(pw, fd, dx, dy, PAN_CAL_DOT_SIZE, PAN_CAL_DOT_SIZE,
338                                                       0,
339                                                       PAN_CAL_DOT_COLOR, PAN_CAL_DOT_ALPHA,
340                                                       0, 0, 0, 0);
341                                 pan_item_set_key(pi, "dot");
342
343                                 dx += PAN_CAL_DOT_SIZE + PAN_CAL_DOT_GAP;
344                                 if (dx + PAN_CAL_DOT_SIZE > pi_day->x + pi_day->width - PAN_CAL_DOT_GAP * 2)
345                                         {
346                                         dx = x + PAN_CAL_DOT_GAP * 2;
347                                         dy += PAN_CAL_DOT_SIZE + PAN_CAL_DOT_GAP;
348                                         }
349                                 if (dy + PAN_CAL_DOT_SIZE > pi_day->y + pi_day->height - PAN_CAL_DOT_GAP * 2)
350                                         {
351                                         /* must keep all dots within respective day even if it gets ugly */
352                                         dy = y + PAN_CAL_DOT_GAP * 2;
353                                         }
354
355                                 n++;
356
357                                 work = work->next;
358                                 fd = (work) ? work->data : NULL;
359                                 }
360
361                         if (n > 0)
362                                 {
363                                 PanItem *pi;
364
365                                 pi_day->color_r = MAX(pi_day->color_r - 61 - n * 3, 80);
366                                 pi_day->color_g = pi_day->color_r;
367
368                                 buf = g_strdup_printf("( %d )", n);
369                                 pi = pan_item_text_new(pw, x, y, buf, PAN_TEXT_ATTR_NONE,
370                                                        PAN_TEXT_BORDER_SIZE,
371                                                        PAN_CAL_DAY_TEXT_COLOR, 255);
372                                 g_free(buf);
373
374                                 pi->x = pi_day->x + (pi_day->width - pi->width) / 2;
375                                 pi->y = pi_day->y + (pi_day->height - pi->height) / 2;
376                                 }
377
378                         buf = g_strdup_printf("%d", day);
379                         pan_item_text_new(pw, x + 4, y + 4, buf, PAN_TEXT_ATTR_BOLD | PAN_TEXT_ATTR_HEADING,
380                                           PAN_TEXT_BORDER_SIZE,
381                                           PAN_CAL_DAY_TEXT_COLOR, 255);
382                         g_free(buf);
383
384
385                         pan_item_size_coordinates(pi_day, PAN_BOX_BORDER, width, height);
386
387                         col++;
388                         if (col > 6)
389                                 {
390                                 col = 0;
391                                 row++;
392                                 x = PAN_BOX_BORDER;
393                                 y += PAN_CAL_DAY_HEIGHT;
394                                 }
395                         else
396                                 {
397                                 x += PAN_CAL_DAY_WIDTH;
398                                 }
399                         }
400
401                 if (col > 0) y += PAN_CAL_DAY_HEIGHT;
402                 y += PAN_BOX_BORDER * 2;
403
404                 month ++;
405                 if (month > 12)
406                         {
407                         year++;
408                         month = 1;
409                         }
410                 }
411
412         *width += grid;
413         *height = MAX(*height, grid + PAN_BOX_BORDER * 2 * 2);
414
415         g_list_free(list);
416 }
417 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */