📄 gtktree.c
字号:
/* GTK - The GIMP Toolkit * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. *//* * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS * file for a list of people on the GTK+ Team. See the ChangeLog * files for a list of changes. These files are distributed with * GTK+ at ftp://ftp.gtk.org/pub/gtk/. */#include "gtktree.h"#include "gtktreeitem.h"#include "gtkmain.h"#include "gtksignal.h"#include "gtklist.h"enum { SELECTION_CHANGED, SELECT_CHILD, UNSELECT_CHILD, LAST_SIGNAL};static void gtk_tree_class_init (GtkTreeClass *klass);static void gtk_tree_init (GtkTree *tree);static void gtk_tree_destroy (GtkObject *object);static void gtk_tree_map (GtkWidget *widget);static void gtk_tree_unmap (GtkWidget *widget);static void gtk_tree_realize (GtkWidget *widget);static void gtk_tree_draw (GtkWidget *widget, GdkRectangle *area);static gint gtk_tree_expose (GtkWidget *widget, GdkEventExpose *event);static gint gtk_tree_motion_notify (GtkWidget *widget, GdkEventMotion *event);static gint gtk_tree_button_press (GtkWidget *widget, GdkEventButton *event);static gint gtk_tree_button_release (GtkWidget *widget, GdkEventButton *event);static void gtk_tree_size_request (GtkWidget *widget, GtkRequisition *requisition);static void gtk_tree_size_allocate (GtkWidget *widget, GtkAllocation *allocation);static void gtk_tree_add (GtkContainer *container, GtkWidget *widget);static void gtk_tree_forall (GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data);static void gtk_real_tree_select_child (GtkTree *tree, GtkWidget *child);static void gtk_real_tree_unselect_child (GtkTree *tree, GtkWidget *child);static GtkType gtk_tree_child_type (GtkContainer *container);static GtkContainerClass *parent_class = NULL;static guint tree_signals[LAST_SIGNAL] = { 0 };GtkTypegtk_tree_get_type (void){ static GtkType tree_type = 0; if (!tree_type) { static const GtkTypeInfo tree_info = { "GtkTree", sizeof (GtkTree), sizeof (GtkTreeClass), (GtkClassInitFunc) gtk_tree_class_init, (GtkObjectInitFunc) gtk_tree_init, /* reserved_1 */ NULL, /* reserved_2 */ NULL, (GtkClassInitFunc) NULL, }; tree_type = gtk_type_unique (gtk_container_get_type (), &tree_info); } return tree_type;}static voidgtk_tree_class_init (GtkTreeClass *class){ GtkObjectClass *object_class; GtkWidgetClass *widget_class; GtkContainerClass *container_class; object_class = (GtkObjectClass*) class; widget_class = (GtkWidgetClass*) class; container_class = (GtkContainerClass*) class; parent_class = gtk_type_class (gtk_container_get_type ()); tree_signals[SELECTION_CHANGED] = gtk_signal_new ("selection_changed", GTK_RUN_FIRST, object_class->type, GTK_SIGNAL_OFFSET (GtkTreeClass, selection_changed), gtk_marshal_NONE__NONE, GTK_TYPE_NONE, 0); tree_signals[SELECT_CHILD] = gtk_signal_new ("select_child", GTK_RUN_FIRST, object_class->type, GTK_SIGNAL_OFFSET (GtkTreeClass, select_child), gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1, GTK_TYPE_WIDGET); tree_signals[UNSELECT_CHILD] = gtk_signal_new ("unselect_child", GTK_RUN_FIRST, object_class->type, GTK_SIGNAL_OFFSET (GtkTreeClass, unselect_child), gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1, GTK_TYPE_WIDGET); gtk_object_class_add_signals (object_class, tree_signals, LAST_SIGNAL); object_class->destroy = gtk_tree_destroy; widget_class->map = gtk_tree_map; widget_class->unmap = gtk_tree_unmap; widget_class->realize = gtk_tree_realize; widget_class->draw = gtk_tree_draw; widget_class->expose_event = gtk_tree_expose; widget_class->motion_notify_event = gtk_tree_motion_notify; widget_class->button_press_event = gtk_tree_button_press; widget_class->button_release_event = gtk_tree_button_release; widget_class->size_request = gtk_tree_size_request; widget_class->size_allocate = gtk_tree_size_allocate; container_class->add = gtk_tree_add; container_class->remove = (void (*)(GtkContainer *, GtkWidget *)) gtk_tree_remove_item; container_class->forall = gtk_tree_forall; container_class->child_type = gtk_tree_child_type; class->selection_changed = NULL; class->select_child = gtk_real_tree_select_child; class->unselect_child = gtk_real_tree_unselect_child;}static GtkTypegtk_tree_child_type (GtkContainer *container){ return GTK_TYPE_TREE_ITEM;}static voidgtk_tree_init (GtkTree *tree){ tree->children = NULL; tree->root_tree = NULL; tree->selection = NULL; tree->tree_owner = NULL; tree->selection_mode = GTK_SELECTION_SINGLE; tree->indent_value = 9; tree->current_indent = 0; tree->level = 0; tree->view_mode = GTK_TREE_VIEW_LINE; tree->view_line = 1;}GtkWidget*gtk_tree_new (void){ return GTK_WIDGET (gtk_type_new (gtk_tree_get_type ()));}voidgtk_tree_append (GtkTree *tree, GtkWidget *tree_item){ g_return_if_fail (tree != NULL); g_return_if_fail (GTK_IS_TREE (tree)); g_return_if_fail (tree_item != NULL); g_return_if_fail (GTK_IS_TREE_ITEM (tree_item)); gtk_tree_insert (tree, tree_item, -1);}voidgtk_tree_prepend (GtkTree *tree, GtkWidget *tree_item){ g_return_if_fail (tree != NULL); g_return_if_fail (GTK_IS_TREE (tree)); g_return_if_fail (tree_item != NULL); g_return_if_fail (GTK_IS_TREE_ITEM (tree_item)); gtk_tree_insert (tree, tree_item, 0);}voidgtk_tree_insert (GtkTree *tree, GtkWidget *tree_item, gint position){ gint nchildren; g_return_if_fail (tree != NULL); g_return_if_fail (GTK_IS_TREE (tree)); g_return_if_fail (tree_item != NULL); g_return_if_fail (GTK_IS_TREE_ITEM (tree_item)); nchildren = g_list_length (tree->children); if ((position < 0) || (position > nchildren)) position = nchildren; if (position == nchildren) tree->children = g_list_append (tree->children, tree_item); else tree->children = g_list_insert (tree->children, tree_item, position); gtk_widget_set_parent (tree_item, GTK_WIDGET (tree)); if (GTK_WIDGET_REALIZED (tree_item->parent)) gtk_widget_realize (tree_item); if (GTK_WIDGET_VISIBLE (tree_item->parent) && GTK_WIDGET_VISIBLE (tree_item)) { if (GTK_WIDGET_MAPPED (tree_item->parent)) gtk_widget_map (tree_item); gtk_widget_queue_resize (tree_item); }}static voidgtk_tree_add (GtkContainer *container, GtkWidget *child){ GtkTree *tree; g_return_if_fail (container != NULL); g_return_if_fail (GTK_IS_TREE (container)); g_return_if_fail (GTK_IS_TREE_ITEM (child)); tree = GTK_TREE (container); tree->children = g_list_append (tree->children, child); gtk_widget_set_parent (child, GTK_WIDGET (container)); if (GTK_WIDGET_REALIZED (child->parent)) gtk_widget_realize (child); if (GTK_WIDGET_VISIBLE (child->parent) && GTK_WIDGET_VISIBLE (child)) { if (GTK_WIDGET_MAPPED (child->parent)) gtk_widget_map (child); gtk_widget_queue_resize (child); } if (!tree->selection && (tree->selection_mode == GTK_SELECTION_BROWSE)) gtk_tree_select_child (tree, child);}static gintgtk_tree_button_press (GtkWidget *widget, GdkEventButton *event){ GtkTree *tree; GtkWidget *item; g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_TREE (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); tree = GTK_TREE (widget); item = gtk_get_event_widget ((GdkEvent*) event); while (item && !GTK_IS_TREE_ITEM (item)) item = item->parent; if (!item || (item->parent != widget)) return FALSE; switch(event->button) { case 1: gtk_tree_select_child (tree, item); break; case 2: if(GTK_TREE_ITEM(item)->subtree) gtk_tree_item_expand(GTK_TREE_ITEM(item)); break; case 3: if(GTK_TREE_ITEM(item)->subtree) gtk_tree_item_collapse(GTK_TREE_ITEM(item)); break; } return TRUE;}static gintgtk_tree_button_release (GtkWidget *widget, GdkEventButton *event){ GtkTree *tree; GtkWidget *item; g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_TREE (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); tree = GTK_TREE (widget); item = gtk_get_event_widget ((GdkEvent*) event); return TRUE;}gintgtk_tree_child_position (GtkTree *tree, GtkWidget *child){ GList *children; gint pos; g_return_val_if_fail (tree != NULL, -1); g_return_val_if_fail (GTK_IS_TREE (tree), -1); g_return_val_if_fail (child != NULL, -1); pos = 0; children = tree->children; while (children) { if (child == GTK_WIDGET (children->data)) return pos; pos += 1; children = children->next; } return -1;}voidgtk_tree_clear_items (GtkTree *tree, gint start, gint end){ GtkWidget *widget; GList *clear_list; GList *tmp_list; guint nchildren; guint index; g_return_if_fail (tree != NULL); g_return_if_fail (GTK_IS_TREE (tree)); nchildren = g_list_length (tree->children); if (nchildren > 0) { if ((end < 0) || (end > nchildren)) end = nchildren; if (start >= end) return; tmp_list = g_list_nth (tree->children, start); clear_list = NULL; index = start; while (tmp_list && index <= end) { widget = tmp_list->data; tmp_list = tmp_list->next; index++; clear_list = g_list_prepend (clear_list, widget); } gtk_tree_remove_items (tree, clear_list); }}static voidgtk_tree_destroy (GtkObject *object){ GtkTree *tree; GtkWidget *child; GList *children; g_return_if_fail (object != NULL);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -