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

📄 gnttree.c

📁 Linux下的多协议即时通讯程序源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	{		GntTree *tree = GNT_TREE(widget);		int i, width = 0;		for (i = 0; i < tree->ncol; i++)			if (!tree->columns[i].invisible)				width += tree->columns[i].width + 1;		widget->priv.width = width;	}}static voidgnt_tree_map(GntWidget *widget){	GntTree *tree = GNT_TREE(widget);	if (widget->priv.width == 0 || widget->priv.height == 0)	{		gnt_widget_size_request(widget);	}	tree->top = tree->root;	tree->current = tree->root;	GNTDEBUG;}static voidtree_selection_changed(GntTree *tree, GntTreeRow *old, GntTreeRow *current){	g_signal_emit(tree, signals[SIG_SELECTION_CHANGED], 0, old ? old->key : NULL,				current ? current->key : NULL);}static gbooleanaction_down(GntBindable *bind, GList *null){	int dist;	GntTree *tree = GNT_TREE(bind);	GntTreeRow *old = tree->current;	GntTreeRow *row = get_next(tree->current);	if (row == NULL)		return FALSE;	tree->current = row;	if ((dist = get_distance(tree->current, tree->bottom)) < 0)		gnt_tree_scroll(tree, -dist);	else		redraw_tree(tree);	if (old != tree->current)		tree_selection_changed(tree, old, tree->current);	return TRUE;}static gbooleanaction_move_parent(GntBindable *bind, GList *null){	GntTree *tree = GNT_TREE(bind);	GntTreeRow *row = tree->current;	int dist;	if (!row->parent || SEARCHING(tree))		return FALSE;	tree->current = row->parent;	if ((dist = get_distance(tree->current, tree->top)) > 0)		gnt_tree_scroll(tree, -dist);	else		redraw_tree(tree);	tree_selection_changed(tree, row, tree->current);	return TRUE;}static gbooleanaction_up(GntBindable *bind, GList *list){	int dist;	GntTree *tree = GNT_TREE(bind);	GntTreeRow *old = tree->current;	GntTreeRow *row = get_prev(tree->current);	if (!row)		return FALSE;	tree->current = row;	if ((dist = get_distance(tree->current, tree->top)) > 0)		gnt_tree_scroll(tree, -dist);	else		redraw_tree(tree);	if (old != tree->current)		tree_selection_changed(tree, old, tree->current);	return TRUE;}static gbooleanaction_page_down(GntBindable *bind, GList *null){	GntTree *tree = GNT_TREE(bind);	GntTreeRow *old = tree->current;	GntTreeRow *row = get_next(tree->bottom);	if (row)	{		int dist = get_distance(tree->top, tree->current);		tree->top = tree->bottom;		tree->current = get_next_n_opt(tree->top, dist, NULL);		redraw_tree(tree);	}	else if (tree->current != tree->bottom)	{		tree->current = tree->bottom;		redraw_tree(tree);	}	if (old != tree->current)		tree_selection_changed(tree, old, tree->current);	return TRUE;}static gbooleanaction_page_up(GntBindable *bind, GList *null){	GntWidget *widget = GNT_WIDGET(bind);	GntTree *tree = GNT_TREE(bind);	GntTreeRow *row;	GntTreeRow *old = tree->current;	if (tree->top != tree->root)	{		int dist = get_distance(tree->top, tree->current);		row = get_prev_n(tree->top, widget->priv.height - 1 -			tree->show_title * 2 - 2 * (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_BORDER) == 0));		if (row == NULL)			row = tree->root;		tree->top = row;		tree->current = get_next_n_opt(tree->top, dist, NULL);		redraw_tree(tree);	}	else if (tree->current != tree->top)	{		tree->current = tree->top;		redraw_tree(tree);	}	if (old != tree->current)		tree_selection_changed(tree, old, tree->current);	return TRUE;}static voidend_search(GntTree *tree){	if (tree->search) {		g_source_remove(tree->search_timeout);		g_string_free(tree->search, TRUE);		tree->search = NULL;		tree->search_timeout = 0;	}}static gbooleansearch_timeout(gpointer data){	GntTree *tree = data;	end_search(tree);	redraw_tree(tree);	return FALSE;}static gbooleangnt_tree_key_pressed(GntWidget *widget, const char *text){	GntTree *tree = GNT_TREE(widget);	GntTreeRow *old = tree->current;	if (text[0] == '\r') {		end_search(tree);		gnt_widget_activate(widget);	} else if (tree->search) {		gboolean changed = TRUE;		if (isalnum(*text)) {			tree->search = g_string_append_c(tree->search, *text);		} else if (g_utf8_collate(text, GNT_KEY_BACKSPACE) == 0) {			if (tree->search->len)				tree->search->str[--tree->search->len] = '\0';		} else			changed = FALSE;		if (changed) {			redraw_tree(tree);			g_source_remove(tree->search_timeout);			tree->search_timeout = g_timeout_add(SEARCH_TIMEOUT, search_timeout, tree);		}		return TRUE;	} else if (text[0] == ' ' && text[1] == 0) {		/* Space pressed */		GntTreeRow *row = tree->current;		if (row && row->child)		{			row->collapsed = !row->collapsed;			redraw_tree(tree);			g_signal_emit(tree, signals[SIG_COLLAPSED], 0, row->key, row->collapsed);		}		else if (row && row->choice)		{			row->isselected = !row->isselected;			g_signal_emit(tree, signals[SIG_TOGGLED], 0, row->key);			redraw_tree(tree);		}	}	if (old != tree->current)	{		tree_selection_changed(tree, old, tree->current);		return TRUE;	}	return FALSE;}static voidgnt_tree_destroy(GntWidget *widget){	GntTree *tree = GNT_TREE(widget);	int i;	end_search(tree);	if (tree->hash)		g_hash_table_destroy(tree->hash);	g_list_free(tree->list);	for (i = 0; i < tree->ncol; i++)	{		g_free(tree->columns[i].title);	}	g_free(tree->columns);}static gbooleangnt_tree_clicked(GntWidget *widget, GntMouseEvent event, int x, int y){	GntTree *tree = GNT_TREE(widget);	GntTreeRow *old = tree->current;	if (event == GNT_MOUSE_SCROLL_UP) {		action_up(GNT_BINDABLE(widget), NULL);	} else if (event == GNT_MOUSE_SCROLL_DOWN) {		action_down(GNT_BINDABLE(widget), NULL);	} else if (event == GNT_LEFT_MOUSE_DOWN) {		GntTreeRow *row;		GntTree *tree = GNT_TREE(widget);		int pos = 1;		if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_BORDER))			pos = 0;		if (tree->show_title)			pos += 2;		pos = y - widget->priv.y - pos;		row = get_next_n(tree->top, pos);		if (row && tree->current != row) {			GntTreeRow *old = tree->current;			tree->current = row;			redraw_tree(tree);			tree_selection_changed(tree, old, tree->current);		} else if (row && row == tree->current) {			if (row->choice) {				row->isselected = !row->isselected;				g_signal_emit(tree, signals[SIG_TOGGLED], 0, row->key);				redraw_tree(tree);			} else {				gnt_widget_activate(widget);			}		}	} else {		return FALSE;	}	if (old != tree->current) {		tree_selection_changed(tree, old, tree->current);	}	return TRUE;}static voidgnt_tree_size_changed(GntWidget *widget, int w, int h){	GntTree *tree = GNT_TREE(widget);	int i;	int n = 0;	if (widget->priv.width <= 0)		return;	for (i = 0; i < tree->ncol; ++i)		n += tree->columns[i].width;	if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_BORDER))		tree->columns[tree->ncol - 1].width += widget->priv.width - n - 1 * tree->ncol;	else		tree->columns[tree->ncol - 1].width += widget->priv.width - n - 2 - 1 * tree->ncol;}static gbooleanstart_search(GntBindable *bindable, GList *list){	GntTree *tree = GNT_TREE(bindable);	if (tree->search)		return FALSE;	tree->search = g_string_new(NULL);	tree->search_timeout = g_timeout_add(SEARCH_TIMEOUT, search_timeout, tree);	return TRUE;}static gbooleanend_search_action(GntBindable *bindable, GList *list){	GntTree *tree = GNT_TREE(bindable);	if (tree->search == NULL)		return FALSE;	end_search(tree);	redraw_tree(tree);	return TRUE;}static voidgnt_tree_class_init(GntTreeClass *klass){	GntBindableClass *bindable = GNT_BINDABLE_CLASS(klass);	parent_class = GNT_WIDGET_CLASS(klass);	parent_class->destroy = gnt_tree_destroy;	parent_class->draw = gnt_tree_draw;	parent_class->map = gnt_tree_map;	parent_class->size_request = gnt_tree_size_request;	parent_class->key_pressed = gnt_tree_key_pressed;	parent_class->clicked = gnt_tree_clicked;	parent_class->size_changed = gnt_tree_size_changed;	signals[SIG_SELECTION_CHANGED] = 		g_signal_new("selection-changed",					 G_TYPE_FROM_CLASS(klass),					 G_SIGNAL_RUN_LAST,					 G_STRUCT_OFFSET(GntTreeClass, selection_changed),					 NULL, NULL,					 gnt_closure_marshal_VOID__POINTER_POINTER,					 G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_POINTER);	signals[SIG_SCROLLED] = 		g_signal_new("scrolled",					 G_TYPE_FROM_CLASS(klass),					 G_SIGNAL_RUN_LAST,					 0,					 NULL, NULL,					 g_cclosure_marshal_VOID__INT,					 G_TYPE_NONE, 1, G_TYPE_INT);	signals[SIG_TOGGLED] = 		g_signal_new("toggled",					 G_TYPE_FROM_CLASS(klass),					 G_SIGNAL_RUN_LAST,					 G_STRUCT_OFFSET(GntTreeClass, toggled),					 NULL, NULL,					 g_cclosure_marshal_VOID__POINTER,					 G_TYPE_NONE, 1, G_TYPE_POINTER);	signals[SIG_COLLAPSED] = 		g_signal_new("collapse-toggled",					 G_TYPE_FROM_CLASS(klass),					 G_SIGNAL_RUN_LAST,					 0,					 NULL, NULL,					 gnt_closure_marshal_VOID__POINTER_BOOLEAN,					 G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_BOOLEAN);	gnt_bindable_class_register_action(bindable, "move-up", action_up,				GNT_KEY_UP, NULL);	gnt_bindable_register_binding(bindable, "move-up", GNT_KEY_CTRL_P, NULL);	gnt_bindable_class_register_action(bindable, "move-down", action_down,				GNT_KEY_DOWN, NULL);	gnt_bindable_register_binding(bindable, "move-down", GNT_KEY_CTRL_N, NULL);	gnt_bindable_class_register_action(bindable, "move-parent", action_move_parent,				GNT_KEY_BACKSPACE, NULL);	gnt_bindable_class_register_action(bindable, "page-up", action_page_up,				GNT_KEY_PGUP, NULL);	gnt_bindable_class_register_action(bindable, "page-down", action_page_down,				GNT_KEY_PGDOWN, NULL);	gnt_bindable_class_register_action(bindable, "start-search", start_search,				"/", NULL);	gnt_bindable_class_register_action(bindable, "end-search", end_search_action,				"\033", NULL);	gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), bindable);	GNTDEBUG;}static voidgnt_tree_init(GTypeInstance *instance, gpointer class){	GntWidget *widget = GNT_WIDGET(instance);	GntTree *tree = GNT_TREE(widget);	tree->show_separator = TRUE;	GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_GROW_X | GNT_WIDGET_GROW_Y);	widget->priv.minw = 4;	widget->priv.minh = 1;	GNTDEBUG;}/****************************************************************************** * GntTree API *****************************************************************************/GTypegnt_tree_get_gtype(void){	static GType type = 0;	if(type == 0)	{		static const GTypeInfo info = {			sizeof(GntTreeClass),			NULL,					/* base_init		*/			NULL,					/* base_finalize	*/			(GClassInitFunc)gnt_tree_class_init,			NULL,					/* class_finalize	*/			NULL,					/* class_data		*/			sizeof(GntTree),			0,						/* n_preallocs		*/			gnt_tree_init,			/* instance_init	*/			NULL					/* value_table		*/		};		type = g_type_register_static(GNT_TYPE_WIDGET,									  "GntTree",									  &info, 0);	}	return type;}static voidfree_tree_col(gpointer data){	GntTreeCol *col = data;	g_free(col->text);	g_free(col);}static voidfree_tree_row(gpointer data){	GntTreeRow *row = data;	if (!row)		return;	g_list_foreach(row->columns, (GFunc)free_tree_col, NULL);	g_list_free(row->columns);	g_free(row);}GntWidget *gnt_tree_new(){	return gnt_tree_new_with_columns(1);}void gnt_tree_set_visible_rows(GntTree *tree, int rows){	GntWidget *widget = GNT_WIDGET(tree);	widget->priv.height = rows;	if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_BORDER))		widget->priv.height += 2;}int gnt_tree_get_visible_rows(GntTree *tree){	GntWidget *widget = GNT_WIDGET(tree);	int ret = widget->priv.height;	if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_BORDER))		ret -= 2;	return ret;}const GList *gnt_tree_get_rows(GntTree *tree){	return tree->list;}void gnt_tree_scroll(GntTree *tree, int count){	GntTreeRow *row;	if (count < 0)	{		if (get_root_distance(tree->top) == 0)			return;		row = get_prev_n(tree->top, -count);		if (row == NULL)			row = tree->root;		tree->top = row;	}	else	{		get_next_n_opt(tree->bottom, count, &count);		tree->top = get_next_n(tree->top, count);	}	redraw_tree(tree);	g_signal_emit(tree, signals[SIG_SCROLLED], 0, count);}static gpointerfind_position(GntTree *tree, gpointer key, gpointer parent){	GntTreeRow *row;	if (tree->compare == NULL)		return NULL;	if (parent == NULL)		row = tree->root;	else		row = g_hash_table_lookup(tree->hash, parent);	if (!row)		return NULL;	if (parent)		row = row->child;	while (row)	{		if (tree->compare(key, row->key) < 0)			return (row->prev ? row->prev->key : NULL);		if (row->next)			row = row->next;		else			return row->key;	}	return NULL;}void gnt_tree_sort_row(GntTree *tree, gpointer key){	GntTreeRow *row, *q, *s;	int current, newp;	if (!tree->compare)		return;

⌨️ 快捷键说明

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