📄 pan-view.c
字号:
static void pan_grid_clear(PanWindow *pw){ GList *work; work = pw->list_grid; while (work) { PanGrid *pg; pg = work->data; work = work->next; g_list_free(pg->list); g_free(pg); } g_list_free(pw->list_grid); pw->list_grid = NULL; pw->list = g_list_concat(pw->list, pw->list_static); pw->list_static = NULL;}static void pan_grid_build(PanWindow *pw, gint width, gint height, gint grid_size){ GList *work; gint col, row; gint cw, ch; gint l; gdouble total; gdouble s; gdouble aw, ah; gint i, j; pan_grid_clear(pw); l = g_list_length(pw->list); if (l < 1) return; total = (gdouble)width * (gdouble)height / (gdouble)l; s = sqrt(total); aw = (gdouble)width / s; ah = (gdouble)height / s; col = (gint)(sqrt((gdouble)l / grid_size) * width / height + 0.999); col = CLAMP(col, 1, l / grid_size + 1); row = (gint)((gdouble)l / grid_size / col); if (row < 1) row = 1; /* limit minimum size of grid so that a tile will always fit regardless of position */ cw = MAX((gint)ceil((gdouble)width / col), PAN_TILE_SIZE * 2); ch = MAX((gint)ceil((gdouble)height / row), PAN_TILE_SIZE * 2); row = row * 2 - 1; col = col * 2 - 1; printf("intersect speedup grid is %dx%d, based on %d average per grid\n", col, row, grid_size); for (j = 0; j < row; j++) for (i = 0; i < col; i++) { if ((i + 1) * cw / 2 < width && (j + 1) * ch / 2 < height) { PanGrid *pg; pg = g_new0(PanGrid, 1); pg->x = i * cw / 2; pg->y = j * ch / 2; pg->w = cw; pg->h = ch; pg->list = NULL; pw->list_grid = g_list_prepend(pw->list_grid, pg); if (debug) printf("grid section: %d,%d (%dx%d)\n", pg->x, pg->y, pg->w, pg->h); } } work = pw->list; while (work) { PanItem *pi; GList *grid; pi = work->data; work = work->next; grid = pw->list_grid; while (grid) { PanGrid *pg; gint rx, ry, rw, rh; pg = grid->data; grid = grid->next; if (util_clip_region(pi->x, pi->y, pi->width, pi->height, pg->x, pg->y, pg->w, pg->h, &rx, &ry, &rw, &rh)) { pg->list = g_list_prepend(pg->list, pi); } } } work = pw->list_grid; while (work) { PanGrid *pg; pg = work->data; work = work->next; pg->list = g_list_reverse(pg->list); } pw->list_static = pw->list; pw->list = NULL;}/* *----------------------------------------------------------------------------- * item objects *----------------------------------------------------------------------------- */static 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);}static void pan_window_items_free(PanWindow *pw){ GList *work; pan_grid_clear(pw); work = pw->list; while (work) { PanItem *pi = work->data; work = work->next; pan_item_free(pi); } g_list_free(pw->list); pw->list = NULL; g_list_free(pw->queue); pw->queue = NULL; pw->queue_pi = NULL; image_loader_free(pw->il); pw->il = NULL; thumb_loader_free(pw->tl); pw->tl = NULL; pw->click_pi = NULL; pw->search_pi = NULL;}static PanItem *pan_item_new_thumb(PanWindow *pw, FileData *fd, gint x, gint y){ PanItem *pi; pi = g_new0(PanItem, 1); pi->type = 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;}static PanItem *pan_item_new_box(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 = 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;}static void pan_item_box_shadow(PanItem *pi, gint offset, gint fade){ gint *shadow; if (!pi || pi->type != 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;}static PanItem *pan_item_new_tri(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 = 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 = BORDER_NONE; pw->list = g_list_prepend(pw->list, pi); return pi;}static void pan_item_tri_border(PanItem *pi, gint borders, guint8 r, guint8 g, guint8 b, guint8 a){ if (!pi || pi->type != ITEM_TRIANGLE) return; pi->border = borders; pi->color2_r = r; pi->color2_g = g; pi->color2_b = b; pi->color2_a = a;}static PangoLayout *pan_item_text_layout(PanItem *pi, GtkWidget *widget){ PangoLayout *layout; layout = gtk_widget_create_pango_layout(widget, NULL); if (pi->text_attr & TEXT_ATTR_MARKUP) { pango_layout_set_markup(layout, pi->text, -1); return layout; } if (pi->text_attr & TEXT_ATTR_BOLD || pi->text_attr & TEXT_ATTR_HEADING) { PangoAttrList *pal; PangoAttribute *pa; pal = pango_attr_list_new(); if (pi->text_attr & 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 & 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 += PAN_TEXT_BORDER_SIZE * 2; pi->height += PAN_TEXT_BORDER_SIZE * 2;}static PanItem *pan_item_new_text(PanWindow *pw, gint x, gint y, const gchar *text, TextAttrType attr, guint8 r, guint8 g, guint8 b, guint8 a){ PanItem *pi; pi = g_new0(PanItem, 1); pi->type = 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; pan_item_text_compute_size(pi, pw->imd->pr); pw->list = g_list_prepend(pw->list, pi); return pi;}static 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);}static void pan_item_added(PanWindow *pw, PanItem *pi){ if (!pi) return; image_area_changed(pw->imd, pi->x, pi->y, pi->width, pi->height);}static 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);}static 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;}static 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;}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; } }}static PanItem *pan_item_new_image(PanWindow *pw, FileData *fd, gint x, gint y, gint w, gint h){ PanItem *pi; pi = g_new0(PanItem, 1); pi->type = ITEM_IMAGE; pi->fd = fd; pi->x = x; pi->y = y; pan_item_image_find_size(pw, pi, w, h); pw->list = g_list_prepend(pw->list, pi); return pi;}static PanItem *pan_item_find_by_key(PanWindow *pw, ItemType 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 == 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 == 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, ItemType 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 == 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 */static GList *pan_item_find_by_path(PanWindow *pw, ItemType 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, ItemType type, gint x, gint y, const gchar *key){ GList *work; work = list; while (work) { PanItem *pi; pi = work->data; if ((pi->type == type || type == 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; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -