Mercurial > geeqie
diff src/pan-calendar.c @ 105:de64a683d5d0
Thu Nov 9 17:43:06 2006 John Ellis <johne@verizon.net>
* pan-view.c: Break this monstrosity of code into smaller files.
* pan-calendar.c, pan-folder.c, pan-grid.c, pan-timeline.c: Move the
layout types into their own files (for now flower is with folder tree).
* pan-item.c: PanItem creation, drawing, actions, and maintenance.
* pan-types.h: Defines, data types, function prototypes.
* pan-util.c: Various utilities.
* src/Makefile.am: Add new files above.
author | gqview |
---|---|
date | Thu, 09 Nov 2006 22:53:11 +0000 |
parents | |
children | 71e1ebee420e |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pan-calendar.c Thu Nov 09 22:53:11 2006 +0000 @@ -0,0 +1,427 @@ +/* + * GQview + * (C) 2006 John Ellis + * + * Author: John Ellis + * + * This software is released under the GNU General Public License (GNU GPL). + * Please read the included file COPYING for more information. + * This software comes with no warranty of any kind, use at your own risk! + */ + + +#include "gqview.h" +#include "pan-types.h" + +#include <math.h> + + +#define PAN_CAL_POPUP_COLOR 220, 220, 220 +#define PAN_CAL_POPUP_ALPHA 255 +#define PAN_CAL_POPUP_BORDER 1 +#define PAN_CAL_POPUP_BORDER_COLOR 0, 0, 0 +#define PAN_CAL_POPUP_TEXT_COLOR 0, 0, 0 + +#define PAN_CAL_DAY_WIDTH 100 +#define PAN_CAL_DAY_HEIGHT 80 + +#define PAN_CAL_DAY_COLOR 255, 255, 255 +#define PAN_CAL_DAY_ALPHA 220 +#define PAN_CAL_DAY_BORDER 2 +#define PAN_CAL_DAY_BORDER_COLOR 0, 0, 0 +#define PAN_CAL_DAY_TEXT_COLOR 0, 0, 0 + +#define PAN_CAL_MONTH_COLOR 255, 255, 255 +#define PAN_CAL_MONTH_ALPHA 200 +#define PAN_CAL_MONTH_BORDER 4 +#define PAN_CAL_MONTH_BORDER_COLOR 0, 0, 0 +#define PAN_CAL_MONTH_TEXT_COLOR 0, 0, 0 + +#define PAN_CAL_DOT_SIZE 3 +#define PAN_CAL_DOT_GAP 2 +#define PAN_CAL_DOT_COLOR 128, 128, 128 +#define PAN_CAL_DOT_ALPHA 128 + + +/* + *----------------------------------------------------------------------------- + * calendar + *----------------------------------------------------------------------------- + */ + +void pan_calendar_update(PanWindow *pw, PanItem *pi_day) +{ + PanItem *pbox; + PanItem *pi; + GList *list; + GList *work; + gint x1, y1, x2, y2, x3, y3; + gint x, y, w, h; + gint grid; + gint column; + + while ((pi = pan_item_find_by_key(pw, PAN_ITEM_NONE, "day_bubble"))) pan_item_remove(pw, pi); + + if (!pi_day || pi_day->type != PAN_ITEM_BOX || + !pi_day->key || strcmp(pi_day->key, "day") != 0) return; + + list = pan_layout_intersect(pw, pi_day->x, pi_day->y, pi_day->width, pi_day->height); + + work = list; + while (work) + { + PanItem *dot; + GList *node; + + dot = work->data; + node = work; + work = work->next; + + if (dot->type != PAN_ITEM_BOX || !dot->fd || + !dot->key || strcmp(dot->key, "dot") != 0) + { + list = g_list_delete_link(list, node); + } + } + +#if 0 + if (!list) return; +#endif + + grid = (gint)(sqrt(g_list_length(list)) + 0.5); + + x = pi_day->x + pi_day->width + 4; + y = pi_day->y; + +#if 0 + if (y + grid * (PAN_THUMB_SIZE + PAN_THUMB_GAP) + PAN_BOX_BORDER * 4 > pw->pr->image_height) + { + y = pw->pr->image_height - (grid * (PAN_THUMB_SIZE + PAN_THUMB_GAP) + PAN_BOX_BORDER * 4); + } +#endif + + pbox = pan_item_box_new(pw, NULL, x, y, PAN_BOX_BORDER, PAN_BOX_BORDER, + PAN_CAL_POPUP_BORDER, + PAN_CAL_POPUP_COLOR, PAN_CAL_POPUP_ALPHA, + PAN_CAL_POPUP_BORDER_COLOR, PAN_CAL_POPUP_ALPHA); + pan_item_set_key(pbox, "day_bubble"); + + if (pi_day->fd) + { + PanItem *plabel; + gchar *buf; + + buf = pan_date_value_string(pi_day->fd->date, PAN_DATE_LENGTH_WEEK); + plabel = pan_item_text_new(pw, x, y, buf, PAN_TEXT_ATTR_BOLD | PAN_TEXT_ATTR_HEADING, + PAN_TEXT_BORDER_SIZE, + PAN_CAL_POPUP_TEXT_COLOR, 255); + pan_item_set_key(plabel, "day_bubble"); + g_free(buf); + + pan_item_size_by_item(pbox, plabel, 0); + + y += plabel->height; + } + + if (list) + { + column = 0; + + x += PAN_BOX_BORDER; + y += PAN_BOX_BORDER; + + work = list; + while (work) + { + PanItem *dot; + + dot = work->data; + work = work->next; + + if (dot->fd) + { + PanItem *pimg; + + pimg = pan_item_thumb_new(pw, file_data_new_simple(dot->fd->path), x, y); + pan_item_set_key(pimg, "day_bubble"); + + pan_item_size_by_item(pbox, pimg, PAN_BOX_BORDER); + + column++; + if (column < grid) + { + x += PAN_THUMB_SIZE + PAN_THUMB_GAP; + } + else + { + column = 0; + x = pbox->x + PAN_BOX_BORDER; + y += PAN_THUMB_SIZE + PAN_THUMB_GAP; + } + } + } + } + + x1 = pi_day->x + pi_day->width - 8; + y1 = pi_day->y + 8; + x2 = pbox->x + 1; + y2 = pbox->y + MIN(42, pbox->height); + x3 = pbox->x + 1; + y3 = MAX(pbox->y, y2 - 30); + util_clip_triangle(x1, y1, x2, y2, x3, y3, + &x, &y, &w, &h); + + pi = pan_item_tri_new(pw, NULL, x, y, w, h, + x1, y1, x2, y2, x3, y3, + PAN_CAL_POPUP_COLOR, PAN_CAL_POPUP_ALPHA); + pan_item_tri_border(pi, PAN_BORDER_1 | PAN_BORDER_3, PAN_CAL_POPUP_BORDER_COLOR, PAN_CAL_POPUP_ALPHA); + pan_item_set_key(pi, "day_bubble"); + pan_item_added(pw, pi); + + pan_item_box_shadow(pbox, PAN_SHADOW_OFFSET * 2, PAN_SHADOW_FADE * 2); + pan_item_added(pw, pbox); + + pan_layout_resize(pw); +} + +void pan_calendar_compute(PanWindow *pw, const gchar *path, gint *width, gint *height) +{ + GList *list; + GList *work; + gint x, y; + time_t tc; + gint count; + gint day_max; + gint day_width; + gint day_height; + gint grid; + gint year = 0; + gint month = 0; + gint end_year = 0; + gint end_month = 0; + + list = pan_list_tree(path, SORT_NONE, TRUE, pw->ignore_symlinks); + + if (pw->cache_list && pw->exif_date_enable) + { + pw->cache_list = filelist_sort(pw->cache_list, SORT_NAME, TRUE); + list = filelist_sort(list, SORT_NAME, TRUE); + pan_cache_sync_date(pw, list); + } + + pw->cache_list = filelist_sort(pw->cache_list, SORT_TIME, TRUE); + list = filelist_sort(list, SORT_TIME, TRUE); + + day_max = 0; + count = 0; + tc = 0; + work = list; + while (work) + { + FileData *fd; + + fd = work->data; + work = work->next; + + if (!pan_date_compare(fd->date, tc, PAN_DATE_LENGTH_DAY)) + { + count = 0; + tc = fd->date; + } + else + { + count++; + if (day_max < count) day_max = count; + } + } + + if (debug) printf("biggest day contains %d images\n", day_max); + + grid = (gint)(sqrt((double)day_max) + 0.5) * (PAN_THUMB_SIZE + PAN_SHADOW_OFFSET * 2 + PAN_THUMB_GAP); + day_width = MAX(PAN_CAL_DAY_WIDTH, grid); + day_height = MAX(PAN_CAL_DAY_HEIGHT, grid); + + if (list) + { + FileData *fd = list->data; + + year = pan_date_value(fd->date, PAN_DATE_LENGTH_YEAR); + month = pan_date_value(fd->date, PAN_DATE_LENGTH_MONTH); + } + + work = g_list_last(list); + if (work) + { + FileData *fd = work->data; + end_year = pan_date_value(fd->date, PAN_DATE_LENGTH_YEAR); + end_month = pan_date_value(fd->date, PAN_DATE_LENGTH_MONTH); + } + + *width = PAN_BOX_BORDER * 2; + *height = PAN_BOX_BORDER * 2; + + x = PAN_BOX_BORDER; + y = PAN_BOX_BORDER; + + work = list; + while (work && (year < end_year || (year == end_year && month <= end_month))) + { + PanItem *pi_month; + PanItem *pi_text; + gint day; + gint days; + gint col; + gint row; + time_t dt; + gchar *buf; + + /* figure last second of this month */ + dt = pan_date_to_time((month == 12) ? year + 1 : year, (month == 12) ? 1 : month + 1, 1); + dt -= 60 * 60 * 24; + + /* anything to show this month? */ + if (!pan_date_compare(((FileData *)(work->data))->date, dt, PAN_DATE_LENGTH_MONTH)) + { + month ++; + if (month > 12) + { + year++; + month = 1; + } + continue; + } + + days = pan_date_value(dt, PAN_DATE_LENGTH_DAY); + dt = pan_date_to_time(year, month, 1); + col = pan_date_value(dt, PAN_DATE_LENGTH_WEEK); + row = 1; + + x = PAN_BOX_BORDER; + + pi_month = pan_item_box_new(pw, NULL, x, y, PAN_CAL_DAY_WIDTH * 7, PAN_CAL_DAY_HEIGHT / 4, + PAN_CAL_MONTH_BORDER, + PAN_CAL_MONTH_COLOR, PAN_CAL_MONTH_ALPHA, + PAN_CAL_MONTH_BORDER_COLOR, PAN_CAL_MONTH_ALPHA); + buf = pan_date_value_string(dt, PAN_DATE_LENGTH_MONTH); + pi_text = pan_item_text_new(pw, x, y, buf, + PAN_TEXT_ATTR_BOLD | PAN_TEXT_ATTR_HEADING, + PAN_TEXT_BORDER_SIZE, + PAN_CAL_MONTH_TEXT_COLOR, 255); + g_free(buf); + pi_text->x = pi_month->x + (pi_month->width - pi_text->width) / 2; + + pi_month->height = pi_text->y + pi_text->height - pi_month->y; + + x = PAN_BOX_BORDER + col * PAN_CAL_DAY_WIDTH; + y = pi_month->y + pi_month->height + PAN_BOX_BORDER; + + for (day = 1; day <= days; day++) + { + FileData *fd; + PanItem *pi_day; + gint dx, dy; + gint n = 0; + + dt = pan_date_to_time(year, month, day); + + fd = g_new0(FileData, 1); + /* path and name must be non NULL, so make them an invalid filename */ + fd->path = g_strdup("//"); + fd->name = path; + fd->date = dt; + pi_day = pan_item_box_new(pw, fd, x, y, PAN_CAL_DAY_WIDTH, PAN_CAL_DAY_HEIGHT, + PAN_CAL_DAY_BORDER, + PAN_CAL_DAY_COLOR, PAN_CAL_DAY_ALPHA, + PAN_CAL_DAY_BORDER_COLOR, PAN_CAL_DAY_ALPHA); + pan_item_set_key(pi_day, "day"); + + dx = x + PAN_CAL_DOT_GAP * 2; + dy = y + PAN_CAL_DOT_GAP * 2; + + fd = (work) ? work->data : NULL; + while (fd && pan_date_compare(fd->date, dt, PAN_DATE_LENGTH_DAY)) + { + PanItem *pi; + + pi = pan_item_box_new(pw, fd, dx, dy, PAN_CAL_DOT_SIZE, PAN_CAL_DOT_SIZE, + 0, + PAN_CAL_DOT_COLOR, PAN_CAL_DOT_ALPHA, + 0, 0, 0, 0); + pan_item_set_key(pi, "dot"); + + dx += PAN_CAL_DOT_SIZE + PAN_CAL_DOT_GAP; + if (dx + PAN_CAL_DOT_SIZE > pi_day->x + pi_day->width - PAN_CAL_DOT_GAP * 2) + { + dx = x + PAN_CAL_DOT_GAP * 2; + dy += PAN_CAL_DOT_SIZE + PAN_CAL_DOT_GAP; + } + if (dy + PAN_CAL_DOT_SIZE > pi_day->y + pi_day->height - PAN_CAL_DOT_GAP * 2) + { + /* must keep all dots within respective day even if it gets ugly */ + dy = y + PAN_CAL_DOT_GAP * 2; + } + + n++; + + work = work->next; + fd = (work) ? work->data : NULL; + } + + if (n > 0) + { + PanItem *pi; + + pi_day->color_r = MAX(pi_day->color_r - 61 - n * 3, 80); + pi_day->color_g = pi_day->color_r; + + buf = g_strdup_printf("( %d )", n); + pi = pan_item_text_new(pw, x, y, buf, PAN_TEXT_ATTR_NONE, + PAN_TEXT_BORDER_SIZE, + PAN_CAL_DAY_TEXT_COLOR, 255); + g_free(buf); + + pi->x = pi_day->x + (pi_day->width - pi->width) / 2; + pi->y = pi_day->y + (pi_day->height - pi->height) / 2; + } + + buf = g_strdup_printf("%d", day); + pan_item_text_new(pw, x + 4, y + 4, buf, PAN_TEXT_ATTR_BOLD | PAN_TEXT_ATTR_HEADING, + PAN_TEXT_BORDER_SIZE, + PAN_CAL_DAY_TEXT_COLOR, 255); + g_free(buf); + + + pan_item_size_coordinates(pi_day, PAN_BOX_BORDER, width, height); + + col++; + if (col > 6) + { + col = 0; + row++; + x = PAN_BOX_BORDER; + y += PAN_CAL_DAY_HEIGHT; + } + else + { + x += PAN_CAL_DAY_WIDTH; + } + } + + if (col > 0) y += PAN_CAL_DAY_HEIGHT; + y += PAN_BOX_BORDER * 2; + + month ++; + if (month > 12) + { + year++; + month = 1; + } + } + + *width += grid; + *height = MAX(*height, grid + PAN_BOX_BORDER * 2 * 2); + + g_list_free(list); +} + +