Mercurial > geeqie.yaz
diff src/pan-folder.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 | f6e307c7bad6 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pan-folder.c Thu Nov 09 22:53:11 2006 +0000 @@ -0,0 +1,470 @@ +/* + * 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> + + +static void pan_flower_size(PanWindow *pw, gint *width, gint *height) +{ + GList *work; + gint x1, y1, x2, y2; + + x1 = 0; + y1 = 0; + x2 = 0; + y2 = 0; + + work = pw->list; + while (work) + { + PanItem *pi; + + pi = work->data; + work = work->next; + + if (x1 > pi->x) x1 = pi->x; + if (y1 > pi->y) y1 = pi->y; + if (x2 < pi->x + pi->width) x2 = pi->x + pi->width; + if (y2 < pi->y + pi->height) y2 = pi->y + pi->height; + } + + x1 -= PAN_BOX_BORDER; + y1 -= PAN_BOX_BORDER; + x2 += PAN_BOX_BORDER; + y2 += PAN_BOX_BORDER; + + work = pw->list; + while (work) + { + PanItem *pi; + + pi = work->data; + work = work->next; + + pi->x -= x1; + pi->y -= y1; + + if (pi->type == PAN_ITEM_TRIANGLE && pi->data) + { + gint *coord; + + coord = pi->data; + coord[0] -= x1; + coord[1] -= y1; + coord[2] -= x1; + coord[3] -= y1; + coord[4] -= x1; + coord[5] -= y1; + } + } + + if (width) *width = x2 - x1; + if (height) *height = y2 - y1; +} + +typedef struct _FlowerGroup FlowerGroup; +struct _FlowerGroup { + GList *items; + GList *children; + gint x; + gint y; + gint width; + gint height; + + gdouble angle; + gint circumference; + gint diameter; +}; + +static void pan_flower_move(FlowerGroup *group, gint x, gint y) +{ + GList *work; + + work = group->items; + while (work) + { + PanItem *pi; + + pi = work->data; + work = work->next; + + pi->x += x; + pi->y += y; + } + + group->x += x; + group->y += y; +} + +#define PI 3.14159 + +static void pan_flower_position(FlowerGroup *group, FlowerGroup *parent, + gint *result_x, gint *result_y) +{ + gint x, y; + gint radius; + gdouble a; + + radius = parent->circumference / (2*PI); + radius = MAX(radius, parent->diameter / 2 + group->diameter / 2); + + a = 2*PI * group->diameter / parent->circumference; + + x = (gint)((double)radius * cos(parent->angle + a / 2)); + y = (gint)((double)radius * sin(parent->angle + a / 2)); + + parent->angle += a; + + x += parent->x; + y += parent->y; + + x += parent->width / 2; + y += parent->height / 2; + + x -= group->width / 2; + y -= group->height / 2; + + *result_x = x; + *result_y = y; +} + +static void pan_flower_build(PanWindow *pw, FlowerGroup *group, FlowerGroup *parent) +{ + GList *work; + gint x, y; + + if (!group) return; + + if (parent && parent->children) + { + pan_flower_position(group, parent, &x, &y); + } + else + { + x = 0; + y = 0; + } + + pan_flower_move(group, x, y); + + if (parent) + { + PanItem *pi; + gint px, py, gx, gy; + gint x1, y1, x2, y2; + + px = parent->x + parent->width / 2; + py = parent->y + parent->height / 2; + + gx = group->x + group->width / 2; + gy = group->y + group->height / 2; + + x1 = MIN(px, gx); + y1 = MIN(py, gy); + + x2 = MAX(px, gx + 5); + y2 = MAX(py, gy + 5); + + pi = pan_item_tri_new(pw, NULL, x1, y1, x2 - x1, y2 - y1, + px, py, gx, gy, gx + 5, gy + 5, + 255, 40, 40, 128); + pan_item_tri_border(pi, PAN_BORDER_1 | PAN_BORDER_3, + 255, 0, 0, 128); + } + + pw->list = g_list_concat(group->items, pw->list); + group->items = NULL; + + group->circumference = 0; + work = group->children; + while (work) + { + FlowerGroup *child; + + child = work->data; + work = work->next; + + group->circumference += child->diameter; + } + + work = g_list_last(group->children); + while (work) + { + FlowerGroup *child; + + child = work->data; + work = work->prev; + + pan_flower_build(pw, child, group); + } + + g_list_free(group->children); + g_free(group); +} + +static FlowerGroup *pan_flower_group(PanWindow *pw, const gchar *path, gint x, gint y) +{ + FlowerGroup *group; + GList *f; + GList *d; + GList *work; + PanItem *pi_box; + gint x_start; + gint y_height; + gint grid_size; + gint grid_count; + + if (!filelist_read(path, &f, &d)) return NULL; + if (!f && !d) return NULL; + + f = filelist_sort(f, SORT_NAME, TRUE); + d = filelist_sort(d, SORT_NAME, TRUE); + + pi_box = pan_item_text_new(pw, x, y, path, PAN_TEXT_ATTR_NONE, + PAN_TEXT_BORDER_SIZE, + PAN_TEXT_COLOR, 255); + + y += pi_box->height; + + pi_box = pan_item_box_new(pw, file_data_new_simple(path), + x, y, + PAN_BOX_BORDER * 2, PAN_BOX_BORDER * 2, + PAN_BOX_OUTLINE_THICKNESS, + PAN_BOX_COLOR, PAN_BOX_ALPHA, + PAN_BOX_OUTLINE_COLOR, PAN_BOX_OUTLINE_ALPHA); + + x += PAN_BOX_BORDER; + y += PAN_BOX_BORDER; + + grid_size = (gint)(sqrt(g_list_length(f)) + 0.9); + grid_count = 0; + x_start = x; + y_height = y; + + work = f; + while (work) + { + FileData *fd; + PanItem *pi; + + fd = work->data; + work = work->next; + + if (pw->size > PAN_IMAGE_SIZE_THUMB_LARGE) + { + pi = pan_item_image_new(pw, fd, x, y, 10, 10); + x += pi->width + PAN_THUMB_GAP; + if (pi->height > y_height) y_height = pi->height; + } + else + { + pi = pan_item_thumb_new(pw, fd, x, y); + x += PAN_THUMB_SIZE + PAN_THUMB_GAP; + y_height = PAN_THUMB_SIZE; + } + + grid_count++; + if (grid_count >= grid_size) + { + grid_count = 0; + x = x_start; + y += y_height + PAN_THUMB_GAP; + y_height = 0; + } + + pan_item_size_by_item(pi_box, pi, PAN_BOX_BORDER); + } + + group = g_new0(FlowerGroup, 1); + group->items = pw->list; + pw->list = NULL; + + group->width = pi_box->width; + group->height = pi_box->y + pi_box->height; + group->diameter = (int)sqrt(group->width * group->width + group->height * group->height); + + group->children = NULL; + + work = d; + while (work) + { + FileData *fd; + FlowerGroup *child; + + fd = work->data; + work = work->next; + + if (!pan_is_ignored(fd->path, pw->ignore_symlinks)) + { + child = pan_flower_group(pw, fd->path, 0, 0); + if (child) group->children = g_list_prepend(group->children, child); + } + } + + if (!f && !group->children) + { + work = group->items; + while (work) + { + PanItem *pi; + + pi = work->data; + work = work->next; + + pan_item_free(pi); + } + + g_list_free(group->items); + g_free(group); + group = NULL; + } + + g_list_free(f); + filelist_free(d); + + return group; +} + +void pan_flower_compute(PanWindow *pw, const gchar *path, + gint *width, gint *height, + gint *scroll_x, gint *scroll_y) +{ + FlowerGroup *group; + GList *list; + + group = pan_flower_group(pw, path, 0, 0); + pan_flower_build(pw, group, NULL); + + pan_flower_size(pw, width, height); + + list = pan_item_find_by_path(pw, PAN_ITEM_BOX, path, FALSE, FALSE); + if (list) + { + PanItem *pi = list->data; + *scroll_x = pi->x + pi->width / 2; + *scroll_y = pi->y + pi->height / 2; + } + g_list_free(list); +} + +static void pan_folder_tree_path(PanWindow *pw, const gchar *path, + gint *x, gint *y, gint *level, + PanItem *parent, + gint *width, gint *height) +{ + GList *f; + GList *d; + GList *work; + PanItem *pi_box; + gint y_height = 0; + + if (!filelist_read(path, &f, &d)) return; + if (!f && !d) return; + + f = filelist_sort(f, SORT_NAME, TRUE); + d = filelist_sort(d, SORT_NAME, TRUE); + + *x = PAN_BOX_BORDER + ((*level) * MAX(PAN_BOX_BORDER, PAN_THUMB_GAP)); + + pi_box = pan_item_text_new(pw, *x, *y, path, PAN_TEXT_ATTR_NONE, + PAN_TEXT_BORDER_SIZE, + PAN_TEXT_COLOR, 255); + + *y += pi_box->height; + + pi_box = pan_item_box_new(pw, file_data_new_simple(path), + *x, *y, + PAN_BOX_BORDER, PAN_BOX_BORDER, + PAN_BOX_OUTLINE_THICKNESS, + PAN_BOX_COLOR, PAN_BOX_ALPHA, + PAN_BOX_OUTLINE_COLOR, PAN_BOX_OUTLINE_ALPHA); + + *x += PAN_BOX_BORDER; + *y += PAN_BOX_BORDER; + + work = f; + while (work) + { + FileData *fd; + PanItem *pi; + + fd = work->data; + work = work->next; + + if (pw->size > PAN_IMAGE_SIZE_THUMB_LARGE) + { + pi = pan_item_image_new(pw, fd, *x, *y, 10, 10); + *x += pi->width + PAN_THUMB_GAP; + if (pi->height > y_height) y_height = pi->height; + } + else + { + pi = pan_item_thumb_new(pw, fd, *x, *y); + *x += PAN_THUMB_SIZE + PAN_THUMB_GAP; + y_height = PAN_THUMB_SIZE; + } + + pan_item_size_by_item(pi_box, pi, PAN_BOX_BORDER); + } + + if (f) *y = pi_box->y + pi_box->height; + + g_list_free(f); + + work = d; + while (work) + { + FileData *fd; + + fd = work->data; + work = work->next; + + if (!pan_is_ignored(fd->path, pw->ignore_symlinks)) + { + *level = *level + 1; + pan_folder_tree_path(pw, fd->path, x, y, level, pi_box, width, height); + *level = *level - 1; + } + } + + filelist_free(d); + + pan_item_size_by_item(parent, pi_box, PAN_BOX_BORDER); + + if (*y < pi_box->y + pi_box->height + PAN_BOX_BORDER) + *y = pi_box->y + pi_box->height + PAN_BOX_BORDER; + + pan_item_size_coordinates(pi_box, PAN_BOX_BORDER, width, height); +} + +void pan_folder_tree_compute(PanWindow *pw, const gchar *path, gint *width, gint *height) +{ + gint x, y; + gint level; + gint w, h; + + level = 0; + x = PAN_BOX_BORDER; + y = PAN_BOX_BORDER; + w = PAN_BOX_BORDER * 2; + h = PAN_BOX_BORDER * 2; + + pan_folder_tree_path(pw, path, &x, &y, &level, NULL, &w, &h); + + if (width) *width = w; + if (height) *height = h; +} + +