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

📄 ui_tree_edit.c

📁 Gqview,Linux下基于GTK+库写成的轻量级而能丰富的图像浏览程序。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * (SLIK) SimpLIstic sKin functions * (C) 2004 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! */#ifdef HAVE_CONFIG_H#  include "config.h"#endif#include "intl.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include <gtk/gtk.h>#include <gdk/gdkkeysyms.h>#include "ui_tree_edit.h"/* *------------------------------------------------------------------- * cell popup editor *------------------------------------------------------------------- */static void tree_edit_close(TreeEditData *ted){	gtk_grab_remove(ted->window);	gdk_keyboard_ungrab(GDK_CURRENT_TIME);	gdk_pointer_ungrab(GDK_CURRENT_TIME);	gtk_widget_destroy(ted->window);	g_free(ted->old_name);	g_free(ted->new_name);	gtk_tree_path_free(ted->path);	g_free(ted);}static void tree_edit_do(TreeEditData *ted){	ted->new_name = g_strdup(gtk_entry_get_text(GTK_ENTRY(ted->entry)));	if (strcmp(ted->new_name, ted->old_name) != 0)		{		if (ted->edit_func)			{			if (ted->edit_func(ted, ted->old_name, ted->new_name, ted->edit_data))				{				/* hmm, should the caller be required to set text instead ? */				}			}		}}static gint tree_edit_click_end_cb(GtkWidget *widget, GdkEventButton *event, gpointer data){	TreeEditData *ted = data;	tree_edit_do(ted);	tree_edit_close(ted);	return TRUE;}static gint tree_edit_click_cb(GtkWidget *widget, GdkEventButton *event, gpointer data){	TreeEditData *ted = data;	gint x, y;	gint w, h;	gint xr, yr;	xr = (gint)event->x_root;	yr = (gint)event->y_root;	gdk_window_get_origin(ted->window->window, &x, &y);	gdk_drawable_get_size(ted->window->window, &w, &h);	if (xr < x || yr < y || xr > x + w || yr > y + h)		{		/* gobble the release event, so it does not propgate to an underlying widget */		g_signal_connect(G_OBJECT(ted->window), "button_release_event",				 G_CALLBACK(tree_edit_click_end_cb), ted);		return TRUE;		}	return FALSE;}static gint tree_edit_key_press_cb(GtkWidget *widget, GdkEventKey *event, gpointer data){	TreeEditData *ted = data;	switch (event->keyval)		{		case GDK_Return:		case GDK_KP_Enter:		case GDK_Tab: 		/* ok, we are going to intercept the focus change					   from keyboard and act like return was hit */		case GDK_ISO_Left_Tab:		case GDK_Up:		case GDK_Down:		case GDK_KP_Up:		case GDK_KP_Down:		case GDK_KP_Left:		case GDK_KP_Right:			tree_edit_do(ted);			tree_edit_close(ted);			break;		case GDK_Escape:			tree_edit_close(ted);			break;		default:			break;		}	return FALSE;}static gboolean tree_edit_by_path_idle_cb(gpointer data){	TreeEditData *ted = data;	GdkRectangle rect;	gint x, y, w, h;	/* geometry of cell within tree */	gint wx, wy;		/* geometry of tree from root window */	gint sx, sw;	gtk_tree_view_get_cell_area(ted->tree, ted->path, ted->column, &rect);	x = rect.x;	y = rect.y;	w = rect.width + 4;	h = rect.height + 4;	if (gtk_tree_view_column_cell_get_position(ted->column, ted->cell, &sx, &sw))		{		x += sx;		w = MAX(w - sx, sw);		}	gdk_window_get_origin(gtk_tree_view_get_bin_window(ted->tree), &wx, &wy);	x += wx - 2; /* the -val is to 'fix' alignment of entry position */	y += wy - 2;	/* now show it */	gtk_widget_set_size_request(ted->window, w, h);	gtk_widget_realize(ted->window);	gtk_window_move(GTK_WINDOW(ted->window), x, y);	gtk_window_resize(GTK_WINDOW(ted->window), w, h);	gtk_widget_show(ted->window);	/* grab it */	gtk_widget_grab_focus(ted->entry);	/* explicitely set the focus flag for the entry, for some reason on popup windows this	 * is not set, and causes no edit cursor to appear ( popups not allowed focus? )	 */	GTK_WIDGET_SET_FLAGS(ted->entry, GTK_HAS_FOCUS);	gtk_grab_add(ted->window);	gdk_pointer_grab(ted->window->window, TRUE,			 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_MOTION_MASK,			 NULL, NULL, GDK_CURRENT_TIME);	gdk_keyboard_grab(ted->window->window, TRUE, GDK_CURRENT_TIME);	return FALSE;}gint tree_edit_by_path(GtkTreeView *tree, GtkTreePath *tpath, gint column, const gchar *text,		       gint (*edit_func)(TreeEditData *, const gchar *, const gchar *, gpointer), gpointer data){	TreeEditData *ted;	GtkTreeViewColumn *tcolumn;	GtkCellRenderer *cell = NULL;	GList *list;	GList *work;	if (!edit_func) return FALSE;	if (!GTK_WIDGET_VISIBLE(tree)) return FALSE;	tcolumn = gtk_tree_view_get_column(tree, column);	if (!tcolumn) return FALSE;	list = gtk_tree_view_column_get_cell_renderers(tcolumn);	work = list;	while (work && !cell)		{		cell = work->data;		if (!GTK_IS_CELL_RENDERER_TEXT(cell))			{			cell = NULL;			}		work = work->next;		}	g_list_free(list);	if (!cell) return FALSE;	if (!text) text = "";	ted = g_new0(TreeEditData, 1);	ted->old_name = g_strdup(text);	ted->new_name = NULL;	ted->edit_func = edit_func;	ted->edit_data = data;	ted->tree = tree;	ted->path = gtk_tree_path_copy(tpath);	ted->column = tcolumn;	ted->cell = cell;	gtk_tree_view_scroll_to_cell(ted->tree, ted->path, ted->column, FALSE, 0.0, 0.0);	/* create the window */	ted->window = gtk_window_new(GTK_WINDOW_POPUP);	gtk_window_set_resizable(GTK_WINDOW(ted->window), FALSE);	g_signal_connect(G_OBJECT(ted->window), "button_press_event",			 G_CALLBACK(tree_edit_click_cb), ted);	g_signal_connect(G_OBJECT(ted->window), "key_press_event",			 G_CALLBACK(tree_edit_key_press_cb), ted);	ted->entry = gtk_entry_new();	gtk_entry_set_text(GTK_ENTRY(ted->entry), ted->old_name);	gtk_editable_select_region(GTK_EDITABLE(ted->entry), 0, strlen(ted->old_name));	gtk_container_add(GTK_CONTAINER(ted->window), ted->entry);	gtk_widget_show(ted->entry);	/* due to the fact that gtktreeview scrolls in an idle loop, we cannot	 * reliably get the cell position until those scroll priority signals are processed	 */	g_idle_add_full(G_PRIORITY_DEFAULT_IDLE - 2, tree_edit_by_path_idle_cb, ted, NULL);	return TRUE;}/* *------------------------------------------------------------------- * tree cell position retrieval *------------------------------------------------------------------- */gint tree_view_get_cell_origin(GtkTreeView *widget, GtkTreePath *tpath, gint column, gint text_cell_only,			       gint *x, gint *y, gint *width, gint *height){	gint x_origin, y_origin;	gint x_offset, y_offset;	gint header_size;	GtkTreeViewColumn *tv_column;	GdkRectangle rect;	tv_column = gtk_tree_view_get_column(widget, column);	if (!tv_column || !tpath) return FALSE;	/* hmm, appears the rect will not account for X scroll, but does for Y scroll	 * use x_offset instead for X scroll (sigh)	 */	gtk_tree_view_get_cell_area(widget, tpath, tv_column, &rect);	gtk_tree_view_tree_to_widget_coords(widget, 0, 0, &x_offset, &y_offset);	gdk_window_get_origin(GTK_WIDGET(widget)->window, &x_origin, &y_origin);	if (gtk_tree_view_get_headers_visible(widget))		{		header_size = tv_column->button->allocation.height;		}	else		{		header_size = 0;		}	if (text_cell_only)		{		GtkCellRenderer *cell = NULL;		GList *renderers;		GList *work;		gint cell_x;		gint cell_width;		renderers = gtk_tree_view_column_get_cell_renderers(tv_column);		work = renderers;		while (work && !cell)			{			cell = work->data;			work = work->next;			if (!GTK_IS_CELL_RENDERER_TEXT(cell)) cell = NULL;			}		g_list_free(renderers);		if (!cell) return FALSE;				if (!gtk_tree_view_column_cell_get_position(tv_column, cell, &cell_x, &cell_width))			{			cell_x = 0;			cell_width = rect.width;			}		*x = x_origin + x_offset + rect.x + cell_x;		*width = cell_width;		}	else		{		*x = x_origin + x_offset + rect.x;		*width = rect.width;		}	*y = y_origin + rect.y + header_size;	*height = rect.height;	return TRUE;}void tree_view_get_cell_clamped(GtkTreeView *widget, GtkTreePath *tpath, gint column, gint text_cell_only,				gint *x, gint *y, gint *width, gint *height){	gint wx, wy, ww, wh;	GdkWindow *window;	window = GTK_WIDGET(widget)->window;	gdk_window_get_origin(window, &wx, &wy);	gdk_drawable_get_size(window, &ww, &wh);	if (!tree_view_get_cell_origin(widget, tpath, column, text_cell_only, x,  y, width, height))		{		*x = wx;		*y = wy;		*width = ww;		*height = wh;		return;		}	*width = MIN(*width, ww);	*x = CLAMP(*x, wx, wx + ww - (*width));	*y = CLAMP(*y, wy, wy + wh);	*height = MIN(*height, wy + wh - (*y));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -