Mercurial > geeqie
annotate src/pan-calendar.c @ 1802:956aab097ea7
added 2010 to copyright text
| author | nadvornik |
|---|---|
| date | Tue, 16 Feb 2010 21:18:03 +0000 |
| parents | 2abdd6e50120 |
| 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 | |
| 1305 | 17 #include <glib/gprintf.h> |
| 105 | 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; | |
| 442 | 64 |
| 105 | 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 #if 0 | |
| 90 if (!list) return; | |
| 91 #endif | |
| 92 | |
| 93 grid = (gint)(sqrt(g_list_length(list)) + 0.5); | |
| 94 | |
| 95 x = pi_day->x + pi_day->width + 4; | |
| 96 y = pi_day->y; | |
| 97 | |
| 98 #if 0 | |
| 99 if (y + grid * (PAN_THUMB_SIZE + PAN_THUMB_GAP) + PAN_BOX_BORDER * 4 > pw->pr->image_height) | |
| 100 { | |
| 101 y = pw->pr->image_height - (grid * (PAN_THUMB_SIZE + PAN_THUMB_GAP) + PAN_BOX_BORDER * 4); | |
| 102 } | |
| 103 #endif | |
| 104 | |
| 105 pbox = pan_item_box_new(pw, NULL, x, y, PAN_BOX_BORDER, PAN_BOX_BORDER, | |
| 106 PAN_CAL_POPUP_BORDER, | |
| 107 PAN_CAL_POPUP_COLOR, PAN_CAL_POPUP_ALPHA, | |
| 108 PAN_CAL_POPUP_BORDER_COLOR, PAN_CAL_POPUP_ALPHA); | |
| 109 pan_item_set_key(pbox, "day_bubble"); | |
| 110 | |
| 111 if (pi_day->fd) | |
| 112 { | |
| 113 PanItem *plabel; | |
| 114 gchar *buf; | |
| 115 | |
| 116 buf = pan_date_value_string(pi_day->fd->date, PAN_DATE_LENGTH_WEEK); | |
| 117 plabel = pan_item_text_new(pw, x, y, buf, PAN_TEXT_ATTR_BOLD | PAN_TEXT_ATTR_HEADING, | |
| 118 PAN_TEXT_BORDER_SIZE, | |
| 119 PAN_CAL_POPUP_TEXT_COLOR, 255); | |
| 120 pan_item_set_key(plabel, "day_bubble"); | |
| 121 g_free(buf); | |
| 122 | |
| 123 pan_item_size_by_item(pbox, plabel, 0); | |
| 124 | |
| 125 y += plabel->height; | |
| 126 } | |
| 127 | |
| 128 if (list) | |
| 129 { | |
| 130 column = 0; | |
| 131 | |
| 132 x += PAN_BOX_BORDER; | |
| 133 y += PAN_BOX_BORDER; | |
| 134 | |
| 135 work = list; | |
| 136 while (work) | |
| 137 { | |
| 138 PanItem *dot; | |
| 139 | |
| 140 dot = work->data; | |
| 141 work = work->next; | |
| 142 | |
| 143 if (dot->fd) | |
| 144 { | |
| 145 PanItem *pimg; | |
| 146 | |
| 138 | 147 pimg = pan_item_thumb_new(pw, file_data_ref(dot->fd), x, y); |
| 105 | 148 pan_item_set_key(pimg, "day_bubble"); |
| 149 | |
| 150 pan_item_size_by_item(pbox, pimg, PAN_BOX_BORDER); | |
| 151 | |
| 152 column++; | |
| 153 if (column < grid) | |
| 154 { | |
| 155 x += PAN_THUMB_SIZE + PAN_THUMB_GAP; | |
| 156 } | |
| 157 else | |
| 158 { | |
| 159 column = 0; | |
| 160 x = pbox->x + PAN_BOX_BORDER; | |
| 161 y += PAN_THUMB_SIZE + PAN_THUMB_GAP; | |
| 162 } | |
| 163 } | |
| 164 } | |
| 165 } | |
| 166 | |
| 167 x1 = pi_day->x + pi_day->width - 8; | |
| 168 y1 = pi_day->y + 8; | |
| 169 x2 = pbox->x + 1; | |
| 170 y2 = pbox->y + MIN(42, pbox->height); | |
| 171 x3 = pbox->x + 1; | |
| 172 y3 = MAX(pbox->y, y2 - 30); | |
| 173 util_clip_triangle(x1, y1, x2, y2, x3, y3, | |
| 174 &x, &y, &w, &h); | |
| 175 | |
| 176 pi = pan_item_tri_new(pw, NULL, x, y, w, h, | |
| 177 x1, y1, x2, y2, x3, y3, | |
| 178 PAN_CAL_POPUP_COLOR, PAN_CAL_POPUP_ALPHA); | |
| 179 pan_item_tri_border(pi, PAN_BORDER_1 | PAN_BORDER_3, PAN_CAL_POPUP_BORDER_COLOR, PAN_CAL_POPUP_ALPHA); | |
| 180 pan_item_set_key(pi, "day_bubble"); | |
| 181 pan_item_added(pw, pi); | |
| 182 | |
| 183 pan_item_box_shadow(pbox, PAN_SHADOW_OFFSET * 2, PAN_SHADOW_FADE * 2); | |
| 184 pan_item_added(pw, pbox); | |
| 185 | |
| 186 pan_layout_resize(pw); | |
| 187 } | |
| 188 | |
| 783 | 189 void pan_calendar_compute(PanWindow *pw, FileData *dir_fd, gint *width, gint *height) |
| 105 | 190 { |
| 191 GList *list; | |
| 192 GList *work; | |
| 193 gint x, y; | |
| 194 time_t tc; | |
| 195 gint count; | |
| 196 gint day_max; | |
| 197 gint day_width; | |
| 198 gint day_height; | |
| 199 gint grid; | |
| 200 gint year = 0; | |
| 201 gint month = 0; | |
| 202 gint end_year = 0; | |
| 203 gint end_month = 0; | |
| 204 | |
| 783 | 205 list = pan_list_tree(dir_fd, SORT_NONE, TRUE, pw->ignore_symlinks); |
| 105 | 206 |
| 207 if (pw->cache_list && pw->exif_date_enable) | |
| 208 { | |
| 138 | 209 pw->cache_list = pan_cache_sort(pw->cache_list, SORT_NAME, TRUE); |
| 105 | 210 list = filelist_sort(list, SORT_NAME, TRUE); |
| 211 pan_cache_sync_date(pw, list); | |
| 212 } | |
| 213 | |
| 138 | 214 pw->cache_list = pan_cache_sort(pw->cache_list, SORT_TIME, TRUE); |
| 105 | 215 list = filelist_sort(list, SORT_TIME, TRUE); |
| 216 | |
| 217 day_max = 0; | |
| 218 count = 0; | |
| 219 tc = 0; | |
| 220 work = list; | |
| 221 while (work) | |
| 222 { | |
| 223 FileData *fd; | |
| 224 | |
| 225 fd = work->data; | |
| 226 work = work->next; | |
| 227 | |
| 228 if (!pan_date_compare(fd->date, tc, PAN_DATE_LENGTH_DAY)) | |
| 229 { | |
| 230 count = 0; | |
| 231 tc = fd->date; | |
| 232 } | |
| 233 else | |
| 234 { | |
| 235 count++; | |
| 236 if (day_max < count) day_max = count; | |
| 237 } | |
| 238 } | |
| 239 | |
|
506
fc9c8a3e1a8b
Handle the newline in DEBUG_N() macro instead of adding one
zas_
parents:
495
diff
changeset
|
240 DEBUG_1("biggest day contains %d images", day_max); |
| 105 | 241 |
|
1000
4fe8f9656107
For the sake of consistency, use glib basic types everywhere.
zas_
parents:
783
diff
changeset
|
242 grid = (gint)(sqrt((gdouble)day_max) + 0.5) * (PAN_THUMB_SIZE + PAN_SHADOW_OFFSET * 2 + PAN_THUMB_GAP); |
| 105 | 243 day_width = MAX(PAN_CAL_DAY_WIDTH, grid); |
| 244 day_height = MAX(PAN_CAL_DAY_HEIGHT, grid); | |
| 245 | |
| 246 if (list) | |
| 247 { | |
| 248 FileData *fd = list->data; | |
| 249 | |
| 250 year = pan_date_value(fd->date, PAN_DATE_LENGTH_YEAR); | |
| 251 month = pan_date_value(fd->date, PAN_DATE_LENGTH_MONTH); | |
| 252 } | |
| 253 | |
| 254 work = g_list_last(list); | |
| 255 if (work) | |
| 256 { | |
| 257 FileData *fd = work->data; | |
| 258 end_year = pan_date_value(fd->date, PAN_DATE_LENGTH_YEAR); | |
| 259 end_month = pan_date_value(fd->date, PAN_DATE_LENGTH_MONTH); | |
| 260 } | |
| 261 | |
| 262 *width = PAN_BOX_BORDER * 2; | |
| 263 *height = PAN_BOX_BORDER * 2; | |
| 264 | |
| 265 x = PAN_BOX_BORDER; | |
| 266 y = PAN_BOX_BORDER; | |
| 267 | |
| 268 work = list; | |
| 269 while (work && (year < end_year || (year == end_year && month <= end_month))) | |
| 270 { | |
| 271 PanItem *pi_month; | |
| 272 PanItem *pi_text; | |
| 273 gint day; | |
| 274 gint days; | |
| 275 gint col; | |
| 276 gint row; | |
| 277 time_t dt; | |
| 278 gchar *buf; | |
| 279 | |
| 280 /* figure last second of this month */ | |
| 281 dt = pan_date_to_time((month == 12) ? year + 1 : year, (month == 12) ? 1 : month + 1, 1); | |
| 282 dt -= 60 * 60 * 24; | |
| 283 | |
| 284 /* anything to show this month? */ | |
| 285 if (!pan_date_compare(((FileData *)(work->data))->date, dt, PAN_DATE_LENGTH_MONTH)) | |
| 286 { | |
| 287 month ++; | |
| 288 if (month > 12) | |
| 289 { | |
| 290 year++; | |
| 291 month = 1; | |
| 292 } | |
| 293 continue; | |
| 294 } | |
| 295 | |
| 296 days = pan_date_value(dt, PAN_DATE_LENGTH_DAY); | |
| 297 dt = pan_date_to_time(year, month, 1); | |
| 298 col = pan_date_value(dt, PAN_DATE_LENGTH_WEEK); | |
| 299 row = 1; | |
| 300 | |
| 301 x = PAN_BOX_BORDER; | |
| 302 | |
| 303 pi_month = pan_item_box_new(pw, NULL, x, y, PAN_CAL_DAY_WIDTH * 7, PAN_CAL_DAY_HEIGHT / 4, | |
| 304 PAN_CAL_MONTH_BORDER, | |
| 305 PAN_CAL_MONTH_COLOR, PAN_CAL_MONTH_ALPHA, | |
| 306 PAN_CAL_MONTH_BORDER_COLOR, PAN_CAL_MONTH_ALPHA); | |
| 307 buf = pan_date_value_string(dt, PAN_DATE_LENGTH_MONTH); | |
| 308 pi_text = pan_item_text_new(pw, x, y, buf, | |
| 309 PAN_TEXT_ATTR_BOLD | PAN_TEXT_ATTR_HEADING, | |
| 310 PAN_TEXT_BORDER_SIZE, | |
| 311 PAN_CAL_MONTH_TEXT_COLOR, 255); | |
| 312 g_free(buf); | |
| 313 pi_text->x = pi_month->x + (pi_month->width - pi_text->width) / 2; | |
| 314 | |
| 315 pi_month->height = pi_text->y + pi_text->height - pi_month->y; | |
| 316 | |
| 317 x = PAN_BOX_BORDER + col * PAN_CAL_DAY_WIDTH; | |
| 318 y = pi_month->y + pi_month->height + PAN_BOX_BORDER; | |
| 319 | |
| 320 for (day = 1; day <= days; day++) | |
| 321 { | |
| 322 FileData *fd; | |
| 323 PanItem *pi_day; | |
| 324 gint dx, dy; | |
| 325 gint n = 0; | |
|
1000
4fe8f9656107
For the sake of consistency, use glib basic types everywhere.
zas_
parents:
783
diff
changeset
|
326 gchar fake_path[20]; |
| 105 | 327 |
| 328 dt = pan_date_to_time(year, month, day); | |
| 442 | 329 |
| 330 /* | |
| 331 * Create a FileData entry that represents the given day. | |
| 301 | 332 * It does not correspond to any real file |
| 442 | 333 */ |
| 334 | |
| 335 g_snprintf(fake_path, sizeof(fake_path), "//%04d-%02d-%02d", year, month, day); | |
| 301 | 336 fd = file_data_new_simple(fake_path); |
| 105 | 337 fd->date = dt; |
| 338 pi_day = pan_item_box_new(pw, fd, x, y, PAN_CAL_DAY_WIDTH, PAN_CAL_DAY_HEIGHT, | |
| 339 PAN_CAL_DAY_BORDER, | |
| 340 PAN_CAL_DAY_COLOR, PAN_CAL_DAY_ALPHA, | |
| 341 PAN_CAL_DAY_BORDER_COLOR, PAN_CAL_DAY_ALPHA); | |
| 342 pan_item_set_key(pi_day, "day"); | |
| 343 | |
| 344 dx = x + PAN_CAL_DOT_GAP * 2; | |
| 345 dy = y + PAN_CAL_DOT_GAP * 2; | |
| 346 | |
| 347 fd = (work) ? work->data : NULL; | |
| 348 while (fd && pan_date_compare(fd->date, dt, PAN_DATE_LENGTH_DAY)) | |
| 349 { | |
| 350 PanItem *pi; | |
| 351 | |
| 352 pi = pan_item_box_new(pw, fd, dx, dy, PAN_CAL_DOT_SIZE, PAN_CAL_DOT_SIZE, | |
| 353 0, | |
| 354 PAN_CAL_DOT_COLOR, PAN_CAL_DOT_ALPHA, | |
| 355 0, 0, 0, 0); | |
| 356 pan_item_set_key(pi, "dot"); | |
| 357 | |
| 358 dx += PAN_CAL_DOT_SIZE + PAN_CAL_DOT_GAP; | |
| 359 if (dx + PAN_CAL_DOT_SIZE > pi_day->x + pi_day->width - PAN_CAL_DOT_GAP * 2) | |
| 360 { | |
| 361 dx = x + PAN_CAL_DOT_GAP * 2; | |
| 362 dy += PAN_CAL_DOT_SIZE + PAN_CAL_DOT_GAP; | |
| 363 } | |
| 364 if (dy + PAN_CAL_DOT_SIZE > pi_day->y + pi_day->height - PAN_CAL_DOT_GAP * 2) | |
| 365 { | |
| 366 /* must keep all dots within respective day even if it gets ugly */ | |
| 367 dy = y + PAN_CAL_DOT_GAP * 2; | |
| 368 } | |
| 369 | |
| 370 n++; | |
| 371 | |
| 372 work = work->next; | |
| 373 fd = (work) ? work->data : NULL; | |
| 374 } | |
| 375 | |
| 376 if (n > 0) | |
| 377 { | |
| 378 PanItem *pi; | |
| 379 | |
| 380 pi_day->color_r = MAX(pi_day->color_r - 61 - n * 3, 80); | |
| 381 pi_day->color_g = pi_day->color_r; | |
| 382 | |
| 383 buf = g_strdup_printf("( %d )", n); | |
| 384 pi = pan_item_text_new(pw, x, y, buf, PAN_TEXT_ATTR_NONE, | |
| 385 PAN_TEXT_BORDER_SIZE, | |
| 386 PAN_CAL_DAY_TEXT_COLOR, 255); | |
| 387 g_free(buf); | |
| 388 | |
| 389 pi->x = pi_day->x + (pi_day->width - pi->width) / 2; | |
| 390 pi->y = pi_day->y + (pi_day->height - pi->height) / 2; | |
| 391 } | |
| 392 | |
| 393 buf = g_strdup_printf("%d", day); | |
| 394 pan_item_text_new(pw, x + 4, y + 4, buf, PAN_TEXT_ATTR_BOLD | PAN_TEXT_ATTR_HEADING, | |
| 395 PAN_TEXT_BORDER_SIZE, | |
| 396 PAN_CAL_DAY_TEXT_COLOR, 255); | |
| 397 g_free(buf); | |
| 398 | |
| 399 | |
| 400 pan_item_size_coordinates(pi_day, PAN_BOX_BORDER, width, height); | |
| 401 | |
| 402 col++; | |
| 403 if (col > 6) | |
| 404 { | |
| 405 col = 0; | |
| 406 row++; | |
| 407 x = PAN_BOX_BORDER; | |
| 408 y += PAN_CAL_DAY_HEIGHT; | |
| 409 } | |
| 410 else | |
| 411 { | |
| 412 x += PAN_CAL_DAY_WIDTH; | |
| 413 } | |
| 414 } | |
| 415 | |
| 416 if (col > 0) y += PAN_CAL_DAY_HEIGHT; | |
| 417 y += PAN_BOX_BORDER * 2; | |
| 418 | |
| 419 month ++; | |
| 420 if (month > 12) | |
| 421 { | |
| 422 year++; | |
| 423 month = 1; | |
| 424 } | |
| 425 } | |
| 426 | |
| 427 *width += grid; | |
| 428 *height = MAX(*height, grid + PAN_BOX_BORDER * 2 * 2); | |
| 429 | |
| 430 g_list_free(list); | |
| 431 } | |
|
1055
1646720364cf
Adding a vim modeline to all files - patch by Klaus Ethgen
nadvornik
parents:
1000
diff
changeset
|
432 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */ |
