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;
+}
+
+