⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pan-view.c

📁 Gqview,Linux下基于GTK+库写成的轻量级而能丰富的图像浏览程序。
💻 C
📖 第 1 页 / 共 5 页
字号:
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 + -