Mercurial > geeqie
diff src/pan-item.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-item.c Thu Nov 09 22:53:11 2006 +0000 @@ -0,0 +1,965 @@ +/* + * 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" + + +/* + *----------------------------------------------------------------------------- + * item base functions + *----------------------------------------------------------------------------- + */ + +void pan_item_free(PanItem *pi) +{ + if (!pi) return; + + if (pi->pixbuf) g_object_unref(pi->pixbuf); + if (pi->fd) file_data_free(pi->fd); + g_free(pi->text); + g_free(pi->key); + g_free(pi->data); + + g_free(pi); +} + +void pan_item_set_key(PanItem *pi, const gchar *key) +{ + gchar *tmp; + + if (!pi) return; + + tmp = pi->key; + pi->key = g_strdup(key); + g_free(tmp); +} + +void pan_item_added(PanWindow *pw, PanItem *pi) +{ + if (!pi) return; + image_area_changed(pw->imd, pi->x, pi->y, pi->width, pi->height); +} + +void pan_item_remove(PanWindow *pw, PanItem *pi) +{ + if (!pi) return; + + if (pw->click_pi == pi) pw->click_pi = NULL; + if (pw->queue_pi == pi) pw->queue_pi = NULL; + if (pw->search_pi == pi) pw->search_pi = NULL; + pw->queue = g_list_remove(pw->queue, pi); + + pw->list = g_list_remove(pw->list, pi); + image_area_changed(pw->imd, pi->x, pi->y, pi->width, pi->height); + pan_item_free(pi); +} + +void pan_item_size_by_item(PanItem *pi, PanItem *child, gint border) +{ + if (!pi || !child) return; + + if (pi->x + pi->width < child->x + child->width + border) + pi->width = child->x + child->width + border - pi->x; + + if (pi->y + pi->height < child->y + child->height + border) + pi->height = child->y + child->height + border - pi->y; +} + +void pan_item_size_coordinates(PanItem *pi, gint border, gint *w, gint *h) +{ + if (!pi) return; + + if (*w < pi->x + pi->width + border) *w = pi->x + pi->width + border; + if (*h < pi->y + pi->height + border) *h = pi->y + pi->height + border; +} + + +/* + *----------------------------------------------------------------------------- + * item box type + *----------------------------------------------------------------------------- + */ + +PanItem *pan_item_box_new(PanWindow *pw, FileData *fd, gint x, gint y, gint width, gint height, + gint border_size, + guint8 base_r, guint8 base_g, guint8 base_b, guint8 base_a, + guint8 bord_r, guint8 bord_g, guint8 bord_b, guint8 bord_a) +{ + PanItem *pi; + + pi = g_new0(PanItem, 1); + pi->type = PAN_ITEM_BOX; + pi->fd = fd; + pi->x = x; + pi->y = y; + pi->width = width; + pi->height = height; + + pi->color_r = base_r; + pi->color_g = base_g; + pi->color_b = base_b; + pi->color_a = base_a; + + pi->color2_r = bord_r; + pi->color2_g = bord_g; + pi->color2_b = bord_b; + pi->color2_a = bord_a; + pi->border = border_size; + + pw->list = g_list_prepend(pw->list, pi); + + return pi; +} + +void pan_item_box_shadow(PanItem *pi, gint offset, gint fade) +{ + gint *shadow; + + if (!pi || pi->type != PAN_ITEM_BOX) return; + + shadow = pi->data; + if (shadow) + { + pi->width -= shadow[0]; + pi->height -= shadow[0]; + } + + shadow = g_new0(gint, 2); + shadow[0] = offset; + shadow[1] = fade; + + pi->width += offset; + pi->height += offset; + + g_free(pi->data); + pi->data = shadow; +} + +gint pan_item_box_draw(PanWindow *pw, PanItem *pi, GdkPixbuf *pixbuf, PixbufRenderer *pr, + gint x, gint y, gint width, gint height) +{ + gint bw, bh; + gint *shadow; + gint rx, ry, rw, rh; + + bw = pi->width; + bh = pi->height; + + shadow = pi->data; + if (shadow) + { + bw -= shadow[0]; + bh -= shadow[0]; + + if (pi->color_a > 254) + { + pixbuf_draw_shadow(pixbuf, pi->x - x + bw, pi->y - y + shadow[0], + shadow[0], bh - shadow[0], + pi->x - x + shadow[0], pi->y - y + shadow[0], bw, bh, + shadow[1], + PAN_SHADOW_COLOR, PAN_SHADOW_ALPHA); + pixbuf_draw_shadow(pixbuf, pi->x - x + shadow[0], pi->y - y + bh, + bw, shadow[0], + pi->x - x + shadow[0], pi->y - y + shadow[0], bw, bh, + shadow[1], + PAN_SHADOW_COLOR, PAN_SHADOW_ALPHA); + } + else + { + gint a; + a = pi->color_a * PAN_SHADOW_ALPHA >> 8; + pixbuf_draw_shadow(pixbuf, pi->x - x + shadow[0], pi->y - y + shadow[0], + bw, bh, + pi->x - x + shadow[0], pi->y - y + shadow[0], bw, bh, + shadow[1], + PAN_SHADOW_COLOR, a); + } + } + + if (util_clip_region(x, y, width, height, + pi->x, pi->y, bw, bh, + &rx, &ry, &rw, &rh)) + { + pixbuf_draw_rect_fill(pixbuf, + rx - x, ry - y, rw, rh, + pi->color_r, pi->color_g, pi->color_b, pi->color_a); + } + if (util_clip_region(x, y, width, height, + pi->x, pi->y, bw, pi->border, + &rx, &ry, &rw, &rh)) + { + pixbuf_draw_rect_fill(pixbuf, + rx - x, ry - y, rw, rh, + pi->color2_r, pi->color2_g, pi->color2_b, pi->color2_a); + } + if (util_clip_region(x, y, width, height, + pi->x, pi->y + pi->border, pi->border, bh - pi->border * 2, + &rx, &ry, &rw, &rh)) + { + pixbuf_draw_rect_fill(pixbuf, + rx - x, ry - y, rw, rh, + pi->color2_r, pi->color2_g, pi->color2_b, pi->color2_a); + } + if (util_clip_region(x, y, width, height, + pi->x + bw - pi->border, pi->y + pi->border, + pi->border, bh - pi->border * 2, + &rx, &ry, &rw, &rh)) + { + pixbuf_draw_rect_fill(pixbuf, + rx - x, ry - y, rw, rh, + pi->color2_r, pi->color2_g, pi->color2_b, pi->color2_a); + } + if (util_clip_region(x, y, width, height, + pi->x, pi->y + bh - pi->border, + bw, pi->border, + &rx, &ry, &rw, &rh)) + { + pixbuf_draw_rect_fill(pixbuf, + rx - x, ry - y, rw, rh, + pi->color2_r, pi->color2_g, pi->color2_b, pi->color2_a); + } + + return FALSE; +} + + +/* + *----------------------------------------------------------------------------- + * item triangle type + *----------------------------------------------------------------------------- + */ + +PanItem *pan_item_tri_new(PanWindow *pw, FileData *fd, gint x, gint y, gint width, gint height, + gint x1, gint y1, gint x2, gint y2, gint x3, gint y3, + guint8 r, guint8 g, guint8 b, guint8 a) +{ + PanItem *pi; + gint *coord; + + pi = g_new0(PanItem, 1); + pi->type = PAN_ITEM_TRIANGLE; + pi->x = x; + pi->y = y; + pi->width = width; + pi->height = height; + + pi->color_r = r; + pi->color_g = g; + pi->color_b = b; + pi->color_a = a; + + coord = g_new0(gint, 6); + coord[0] = x1; + coord[1] = y1; + coord[2] = x2; + coord[3] = y2; + coord[4] = x3; + coord[5] = y3; + + pi->data = coord; + + pi->border = PAN_BORDER_NONE; + + pw->list = g_list_prepend(pw->list, pi); + + return pi; +} + +void pan_item_tri_border(PanItem *pi, gint borders, + guint8 r, guint8 g, guint8 b, guint8 a) +{ + if (!pi || pi->type != PAN_ITEM_TRIANGLE) return; + + pi->border = borders; + + pi->color2_r = r; + pi->color2_g = g; + pi->color2_b = b; + pi->color2_a = a; +} + +gint pan_item_tri_draw(PanWindow *pw, PanItem *pi, GdkPixbuf *pixbuf, PixbufRenderer *pr, + gint x, gint y, gint width, gint height) +{ + gint rx, ry, rw, rh; + + if (util_clip_region(x, y, width, height, + pi->x, pi->y, pi->width, pi->height, + &rx, &ry, &rw, &rh) && pi->data) + { + gint *coord = pi->data; + pixbuf_draw_triangle(pixbuf, + rx - x, ry - y, rw, rh, + coord[0] - x, coord[1] - y, + coord[2] - x, coord[3] - y, + coord[4] - x, coord[5] - y, + pi->color_r, pi->color_g, pi->color_b, pi->color_a); + + if (pi->border & PAN_BORDER_1) + { + pixbuf_draw_line(pixbuf, + rx - x, ry - y, rw, rh, + coord[0] - x, coord[1] - y, + coord[2] - x, coord[3] - y, + pi->color2_r, pi->color2_g, pi->color2_b, pi->color2_a); + } + if (pi->border & PAN_BORDER_2) + { + pixbuf_draw_line(pixbuf, + rx - x, ry - y, rw, rh, + coord[2] - x, coord[3] - y, + coord[4] - x, coord[5] - y, + pi->color2_r, pi->color2_g, pi->color2_b, pi->color2_a); + } + if (pi->border & PAN_BORDER_3) + { + pixbuf_draw_line(pixbuf, + rx - x, ry - y, rw, rh, + coord[4] - x, coord[5] - y, + coord[0] - x, coord[1] - y, + pi->color2_r, pi->color2_g, pi->color2_b, pi->color2_a); + } + } + + return FALSE; +} + + +/* + *----------------------------------------------------------------------------- + * item text type + *----------------------------------------------------------------------------- + */ + +static PangoLayout *pan_item_text_layout(PanItem *pi, GtkWidget *widget) +{ + PangoLayout *layout; + + layout = gtk_widget_create_pango_layout(widget, NULL); + + if (pi->text_attr & PAN_TEXT_ATTR_MARKUP) + { + pango_layout_set_markup(layout, pi->text, -1); + return layout; + } + + if (pi->text_attr & PAN_TEXT_ATTR_BOLD || + pi->text_attr & PAN_TEXT_ATTR_HEADING) + { + PangoAttrList *pal; + PangoAttribute *pa; + + pal = pango_attr_list_new(); + if (pi->text_attr & PAN_TEXT_ATTR_BOLD) + { + pa = pango_attr_weight_new(PANGO_WEIGHT_BOLD); + pa->start_index = 0; + pa->end_index = G_MAXINT; + pango_attr_list_insert(pal, pa); + } + if (pi->text_attr & PAN_TEXT_ATTR_HEADING) + { + pa = pango_attr_scale_new(PANGO_SCALE_LARGE); + pa->start_index = 0; + pa->end_index = G_MAXINT; + pango_attr_list_insert(pal, pa); + } + pango_layout_set_attributes(layout, pal); + pango_attr_list_unref(pal); + } + + pango_layout_set_text(layout, pi->text, -1); + return layout; +} + +static void pan_item_text_compute_size(PanItem *pi, GtkWidget *widget) +{ + PangoLayout *layout; + + if (!pi || !pi->text || !widget) return; + + layout = pan_item_text_layout(pi, widget); + pango_layout_get_pixel_size(layout, &pi->width, &pi->height); + g_object_unref(G_OBJECT(layout)); + + pi->width += pi->border * 2; + pi->height += pi->border * 2; +} + +PanItem *pan_item_text_new(PanWindow *pw, gint x, gint y, const gchar *text, + PanTextAttrType attr, PanBorderType border, + guint8 r, guint8 g, guint8 b, guint8 a) +{ + PanItem *pi; + + pi = g_new0(PanItem, 1); + pi->type = PAN_ITEM_TEXT; + pi->x = x; + pi->y = y; + pi->text = g_strdup(text); + pi->text_attr = attr; + + pi->color_r = r; + pi->color_g = g; + pi->color_b = b; + pi->color_a = a; + + pi->border = border; + + pan_item_text_compute_size(pi, pw->imd->pr); + + pw->list = g_list_prepend(pw->list, pi); + + return pi; +} + +gint pan_item_text_draw(PanWindow *pw, PanItem *pi, GdkPixbuf *pixbuf, PixbufRenderer *pr, + gint x, gint y, gint width, gint height) +{ + PangoLayout *layout; + + layout = pan_item_text_layout(pi, (GtkWidget *)pr); + pixbuf_draw_layout(pixbuf, layout, (GtkWidget *)pr, + pi->x - x + pi->border, pi->y - y + pi->border, + pi->color_r, pi->color_g, pi->color_b, pi->color_a); + g_object_unref(G_OBJECT(layout)); + + return FALSE; +} + + +/* + *----------------------------------------------------------------------------- + * item thumbnail type + *----------------------------------------------------------------------------- + */ + +PanItem *pan_item_thumb_new(PanWindow *pw, FileData *fd, gint x, gint y) +{ + PanItem *pi; + + pi = g_new0(PanItem, 1); + pi->type = PAN_ITEM_THUMB; + pi->fd = fd; + pi->x = x; + pi->y = y; + pi->width = PAN_THUMB_SIZE + PAN_SHADOW_OFFSET * 2; + pi->height = PAN_THUMB_SIZE + PAN_SHADOW_OFFSET * 2; + + pi->pixbuf = NULL; + + pi->queued = FALSE; + + pw->list = g_list_prepend(pw->list, pi); + + return pi; +} + +gint pan_item_thumb_draw(PanWindow *pw, PanItem *pi, GdkPixbuf *pixbuf, PixbufRenderer *pr, + gint x, gint y, gint width, gint height) +{ + gint tx, ty, tw, th; + gint rx, ry, rw, rh; + + if (pi->pixbuf) + { + tw = gdk_pixbuf_get_width(pi->pixbuf); + th = gdk_pixbuf_get_height(pi->pixbuf); + + tx = pi->x + (pi->width - tw) / 2; + ty = pi->y + (pi->height - th) / 2; + + if (gdk_pixbuf_get_has_alpha(pi->pixbuf)) + { + if (util_clip_region(x, y, width, height, + tx + PAN_SHADOW_OFFSET, ty + PAN_SHADOW_OFFSET, tw, th, + &rx, &ry, &rw, &rh)) + { + pixbuf_draw_shadow(pixbuf, + rx - x, ry - y, rw, rh, + tx + PAN_SHADOW_OFFSET - x, ty + PAN_SHADOW_OFFSET - y, tw, th, + PAN_SHADOW_FADE, + PAN_SHADOW_COLOR, PAN_SHADOW_ALPHA); + } + } + else + { + if (util_clip_region(x, y, width, height, + tx + tw, ty + PAN_SHADOW_OFFSET, + PAN_SHADOW_OFFSET, th - PAN_SHADOW_OFFSET, + &rx, &ry, &rw, &rh)) + { + pixbuf_draw_shadow(pixbuf, + rx - x, ry - y, rw, rh, + tx + PAN_SHADOW_OFFSET - x, ty + PAN_SHADOW_OFFSET - y, tw, th, + PAN_SHADOW_FADE, + PAN_SHADOW_COLOR, PAN_SHADOW_ALPHA); + } + if (util_clip_region(x, y, width, height, + tx + PAN_SHADOW_OFFSET, ty + th, tw, PAN_SHADOW_OFFSET, + &rx, &ry, &rw, &rh)) + { + pixbuf_draw_shadow(pixbuf, + rx - x, ry - y, rw, rh, + tx + PAN_SHADOW_OFFSET - x, ty + PAN_SHADOW_OFFSET - y, tw, th, + PAN_SHADOW_FADE, + PAN_SHADOW_COLOR, PAN_SHADOW_ALPHA); + } + } + + if (util_clip_region(x, y, width, height, + tx, ty, tw, th, + &rx, &ry, &rw, &rh)) + { + gdk_pixbuf_composite(pi->pixbuf, pixbuf, rx - x, ry - y, rw, rh, + (double) tx - x, + (double) ty - y, + 1.0, 1.0, GDK_INTERP_NEAREST, + 255); + } + + if (util_clip_region(x, y, width, height, + tx, ty, tw, PAN_OUTLINE_THICKNESS, + &rx, &ry, &rw, &rh)) + { + pixbuf_draw_rect_fill(pixbuf, + rx - x, ry - y, rw, rh, + PAN_OUTLINE_COLOR_1, PAN_OUTLINE_ALPHA); + } + if (util_clip_region(x, y, width, height, + tx, ty, PAN_OUTLINE_THICKNESS, th, + &rx, &ry, &rw, &rh)) + { + pixbuf_draw_rect_fill(pixbuf, + rx - x, ry - y, rw, rh, + PAN_OUTLINE_COLOR_1, PAN_OUTLINE_ALPHA); + } + if (util_clip_region(x, y, width, height, + tx + tw - PAN_OUTLINE_THICKNESS, ty + PAN_OUTLINE_THICKNESS, + PAN_OUTLINE_THICKNESS, th - PAN_OUTLINE_THICKNESS, + &rx, &ry, &rw, &rh)) + { + pixbuf_draw_rect_fill(pixbuf, + rx - x, ry - y, rw, rh, + PAN_OUTLINE_COLOR_2, PAN_OUTLINE_ALPHA); + } + if (util_clip_region(x, y, width, height, + tx + PAN_OUTLINE_THICKNESS, ty + th - PAN_OUTLINE_THICKNESS, + tw - PAN_OUTLINE_THICKNESS * 2, PAN_OUTLINE_THICKNESS, + &rx, &ry, &rw, &rh)) + { + pixbuf_draw_rect_fill(pixbuf, + rx - x, ry - y, rw, rh, + PAN_OUTLINE_COLOR_2, PAN_OUTLINE_ALPHA); + } + } + else + { + tw = pi->width - PAN_SHADOW_OFFSET * 2; + th = pi->height - PAN_SHADOW_OFFSET * 2; + tx = pi->x + PAN_SHADOW_OFFSET; + ty = pi->y + PAN_SHADOW_OFFSET; + + if (util_clip_region(x, y, width, height, + tx, ty, tw, th, + &rx, &ry, &rw, &rh)) + { + gint d; + + d = (pw->size <= PAN_IMAGE_SIZE_THUMB_NONE) ? 2 : 8; + pixbuf_draw_rect_fill(pixbuf, + rx - x, ry - y, rw, rh, + PAN_SHADOW_COLOR, + PAN_SHADOW_ALPHA / d); + } + } + + return (pi->pixbuf == NULL); +} + + +/* + *----------------------------------------------------------------------------- + * item image type + *----------------------------------------------------------------------------- + */ + +static void pan_item_image_find_size(PanWindow *pw, PanItem *pi, gint w, gint h) +{ + GList *work; + + pi->width = w; + pi->height = h; + + if (!pi->fd) return; + + work = pw->cache_list; + while (work) + { + PanCacheData *pc; + gchar *path; + + pc = work->data; + work = work->next; + + path = ((FileData *)pc)->path; + + if (pc->cd && pc->cd->dimensions && + path && strcmp(path, pi->fd->path) == 0) + { + pi->width = MAX(1, pc->cd->width * pw->image_size / 100); + pi->height = MAX(1, pc->cd->height * pw->image_size / 100); + + pw->cache_list = g_list_remove(pw->cache_list, pc); + cache_sim_data_free(pc->cd); + file_data_free((FileData *)pc); + return; + } + } +} + +PanItem *pan_item_image_new(PanWindow *pw, FileData *fd, gint x, gint y, gint w, gint h) +{ + PanItem *pi; + + pi = g_new0(PanItem, 1); + pi->type = PAN_ITEM_IMAGE; + pi->fd = fd; + pi->x = x; + pi->y = y; + + pi->color_a = 255; + + pi->color2_r = 0; + pi->color2_g = 0; + pi->color2_b = 0; + pi->color2_a = PAN_SHADOW_ALPHA / 2; + + pan_item_image_find_size(pw, pi, w, h); + + pw->list = g_list_prepend(pw->list, pi); + + return pi; +} + +gint pan_item_image_draw(PanWindow *pw, PanItem *pi, GdkPixbuf *pixbuf, PixbufRenderer *pr, + gint x, gint y, gint width, gint height) +{ + gint rx, ry, rw, rh; + + if (util_clip_region(x, y, width, height, + pi->x, pi->y, pi->width, pi->height, + &rx, &ry, &rw, &rh)) + { + if (pi->pixbuf) + { + gdk_pixbuf_composite(pi->pixbuf, pixbuf, rx - x, ry - y, rw, rh, + (double) pi->x - x, + (double) pi->y - y, + 1.0, 1.0, GDK_INTERP_NEAREST, + pi->color_a); + } + else + { + pixbuf_draw_rect_fill(pixbuf, + rx - x, ry - y, rw, rh, + pi->color2_r, pi->color2_g, pi->color2_b, pi->color2_a); + } + } + + return (pi->pixbuf == NULL); +} + + +/* + *----------------------------------------------------------------------------- + * item lookup/search + *----------------------------------------------------------------------------- + */ + +PanItem *pan_item_find_by_key(PanWindow *pw, PanItemType type, const gchar *key) +{ + GList *work; + + if (!key) return NULL; + + work = g_list_last(pw->list); + while (work) + { + PanItem *pi; + + pi = work->data; + if ((pi->type == type || type == PAN_ITEM_NONE) && + pi->key && strcmp(pi->key, key) == 0) + { + return pi; + } + work = work->prev; + } + work = g_list_last(pw->list_static); + while (work) + { + PanItem *pi; + + pi = work->data; + if ((pi->type == type || type == PAN_ITEM_NONE) && + pi->key && strcmp(pi->key, key) == 0) + { + return pi; + } + work = work->prev; + } + + return NULL; +} + +/* when ignore_case and partial are TRUE, path should be converted to lower case */ +static GList *pan_item_find_by_path_l(GList *list, GList *search_list, + PanItemType type, const gchar *path, + gint ignore_case, gint partial) +{ + GList *work; + + work = g_list_last(search_list); + while (work) + { + PanItem *pi; + + pi = work->data; + if ((pi->type == type || type == PAN_ITEM_NONE) && pi->fd) + { + gint match = FALSE; + + if (path[0] == '/') + { + if (pi->fd->path && strcmp(path, pi->fd->path) == 0) match = TRUE; + } + else if (pi->fd->name) + { + if (partial) + { + if (ignore_case) + { + gchar *haystack; + + haystack = g_utf8_strdown(pi->fd->name, -1); + match = (strstr(haystack, path) != NULL); + g_free(haystack); + } + else + { + if (strstr(pi->fd->name, path)) match = TRUE; + } + } + else if (ignore_case) + { + if (strcasecmp(path, pi->fd->name) == 0) match = TRUE; + } + else + { + if (strcmp(path, pi->fd->name) == 0) match = TRUE; + } + } + + if (match) list = g_list_prepend(list, pi); + } + work = work->prev; + } + + return list; +} + +/* when ignore_case and partial are TRUE, path should be converted to lower case */ +GList *pan_item_find_by_path(PanWindow *pw, PanItemType type, const gchar *path, + gint ignore_case, gint partial) +{ + GList *list = NULL; + + if (!path) return NULL; + if (partial && path[0] == '/') return NULL; + + list = pan_item_find_by_path_l(list, pw->list_static, type, path, ignore_case, partial); + list = pan_item_find_by_path_l(list, pw->list, type, path, ignore_case, partial); + + return g_list_reverse(list); +} + +static PanItem *pan_item_find_by_coord_l(GList *list, PanItemType type, gint x, gint y, const gchar *key) +{ + GList *work; + + work = list; + while (work) + { + PanItem *pi; + + pi = work->data; + if ((pi->type == type || type == PAN_ITEM_NONE) && + x >= pi->x && x < pi->x + pi->width && + y >= pi->y && y < pi->y + pi->height && + (!key || (pi->key && strcmp(pi->key, key) == 0))) + { + return pi; + } + work = work->next; + } + + return NULL; +} + +PanItem *pan_item_find_by_coord(PanWindow *pw, PanItemType type, + gint x, gint y, const gchar *key) +{ + PanItem *pi; + + pi = pan_item_find_by_coord_l(pw->list, type, x, y, key); + if (pi) return pi; + + return pan_item_find_by_coord_l(pw->list_static, type, x, y, key); +} + + +/* + *----------------------------------------------------------------------------- + * text alignments + *----------------------------------------------------------------------------- + */ + +PanTextAlignment *pan_text_alignment_new(PanWindow *pw, gint x, gint y, const gchar *key) +{ + PanTextAlignment *ta; + + ta = g_new0(PanTextAlignment, 1); + + ta->pw = pw; + ta->column1 = NULL; + ta->column2 = NULL; + ta->x = x; + ta->y = y; + ta->key = g_strdup(key); + + return ta; +} + +void pan_text_alignment_free(PanTextAlignment *ta) +{ + if (!ta) return; + + g_list_free(ta->column1); + g_list_free(ta->column2); + g_free(ta->key); + g_free(ta); +} + +PanItem *pan_text_alignment_add(PanTextAlignment *ta, const gchar *label, const gchar *text) +{ + PanItem *item; + + if (label) + { + item = pan_item_text_new(ta->pw, ta->x, ta->y, label, + PAN_TEXT_ATTR_BOLD, 0, + PAN_POPUP_TEXT_COLOR, 255); + pan_item_set_key(item, ta->key); + } + else + { + item = NULL; + } + ta->column1 = g_list_append(ta->column1, item); + + if (text) + { + item = pan_item_text_new(ta->pw, ta->x, ta->y, text, + PAN_TEXT_ATTR_NONE, 0, + PAN_POPUP_TEXT_COLOR, 255); + pan_item_set_key(item, ta->key); + } + else + { + item = NULL; + } + ta->column2 = g_list_append(ta->column2, item); + + return item; +} + +void pan_text_alignment_calc(PanTextAlignment *ta, PanItem *box) +{ + gint cw1, cw2; + gint x, y; + GList *work1; + GList *work2; + + cw1 = 0; + cw2 = 0; + + work1 = ta->column1; + while (work1) + { + PanItem *p; + + p = work1->data; + work1 = work1->next; + + if (p && p->width > cw1) cw1 = p->width; + } + + work2 = ta->column2; + while (work2) + { + PanItem *p; + + p = work2->data; + work2 = work2->next; + + if (p && p->width > cw2) cw2 = p->width; + } + + x = ta->x; + y = ta->y; + work1 = ta->column1; + work2 = ta->column2; + while (work1 && work2) + { + PanItem *p1; + PanItem *p2; + gint height = 0; + + p1 = work1->data; + p2 = work2->data; + work1 = work1->next; + work2 = work2->next; + + if (p1) + { + p1->x = x; + p1->y = y; + pan_item_size_by_item(box, p1, PREF_PAD_BORDER); + height = p1->height; + } + if (p2) + { + p2->x = x + cw1 + PREF_PAD_SPACE; + p2->y = y; + pan_item_size_by_item(box, p2, PREF_PAD_BORDER); + if (height < p2->height) height = p2->height; + } + + if (!p1 && !p2) height = PREF_PAD_GROUP; + + y += height; + } +} + +