📄 gtkctree.c
字号:
/* GTK - The GIMP Toolkit * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball, Josh MacDonald, * Copyright (C) 1997-1998 Jay Painter <jpaint@serv.net><jpaint@gimp.org> * * GtkCTree widget for GTK+ * Copyright (C) 1998 Lars Hamann and Stefan Jeske * * 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 <stdlib.h>#include "gtkctree.h"#include "gtkbindings.h"#include "gtkmain.h"#include "gtkdnd.h"#include <gdk/gdkx.h>#include <gdk/gdkkeysyms.h>#define PM_SIZE 8#define TAB_SIZE (PM_SIZE + 6)#define CELL_SPACING 1#define CLIST_OPTIMUM_SIZE 64#define COLUMN_INSET 3#define DRAG_WIDTH 6#define ROW_TOP_YPIXEL(clist, row) (((clist)->row_height * (row)) + \ (((row) + 1) * CELL_SPACING) + \ (clist)->voffset)#define ROW_FROM_YPIXEL(clist, y) (((y) - (clist)->voffset) / \ ((clist)->row_height + CELL_SPACING))#define COLUMN_LEFT_XPIXEL(clist, col) ((clist)->column[(col)].area.x \ + (clist)->hoffset)#define COLUMN_LEFT(clist, column) ((clist)->column[(column)].area.x)static inline gintCOLUMN_FROM_XPIXEL (GtkCList * clist, gint x){ gint i, cx; for (i = 0; i < clist->columns; i++) if (clist->column[i].visible) { cx = clist->column[i].area.x + clist->hoffset; if (x >= (cx - (COLUMN_INSET + CELL_SPACING)) && x <= (cx + clist->column[i].area.width + COLUMN_INSET)) return i; } /* no match */ return -1;}#define GTK_CLIST_CLASS_FW(_widget_) GTK_CLIST_CLASS (((GtkObject*) (_widget_))->klass)#define CLIST_UNFROZEN(clist) (((GtkCList*) (clist))->freeze_count == 0)#define CLIST_REFRESH(clist) G_STMT_START { \ if (CLIST_UNFROZEN (clist)) \ GTK_CLIST_CLASS_FW (clist)->refresh ((GtkCList*) (clist)); \} G_STMT_ENDenum { ARG_0, ARG_N_COLUMNS, ARG_TREE_COLUMN, ARG_INDENT, ARG_SPACING, ARG_SHOW_STUB, ARG_LINE_STYLE, ARG_EXPANDER_STYLE};static void gtk_ctree_class_init (GtkCTreeClass *klass);static void gtk_ctree_init (GtkCTree *ctree);static void gtk_ctree_set_arg (GtkObject *object, GtkArg *arg, guint arg_id);static void gtk_ctree_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);static void gtk_ctree_realize (GtkWidget *widget);static void gtk_ctree_unrealize (GtkWidget *widget);static gint gtk_ctree_button_press (GtkWidget *widget, GdkEventButton *event);static void ctree_attach_styles (GtkCTree *ctree, GtkCTreeNode *node, gpointer data);static void ctree_detach_styles (GtkCTree *ctree, GtkCTreeNode *node, gpointer data);static gint draw_cell_pixmap (GdkWindow *window, GdkRectangle *clip_rectangle, GdkGC *fg_gc, GdkPixmap *pixmap, GdkBitmap *mask, gint x, gint y, gint width, gint height);static void get_cell_style (GtkCList *clist, GtkCListRow *clist_row, gint state, gint column, GtkStyle **style, GdkGC **fg_gc, GdkGC **bg_gc);static gint gtk_ctree_draw_expander (GtkCTree *ctree, GtkCTreeRow *ctree_row, GtkStyle *style, GdkRectangle *clip_rectangle, gint x);static gint gtk_ctree_draw_lines (GtkCTree *ctree, GtkCTreeRow *ctree_row, gint row, gint column, gint state, GdkRectangle *clip_rectangle, GdkRectangle *cell_rectangle, GdkRectangle *crect, GdkRectangle *area, GtkStyle *style);static void draw_row (GtkCList *clist, GdkRectangle *area, gint row, GtkCListRow *clist_row);static void draw_drag_highlight (GtkCList *clist, GtkCListRow *dest_row, gint dest_row_number, GtkCListDragPos drag_pos);static void tree_draw_node (GtkCTree *ctree, GtkCTreeNode *node);static void set_cell_contents (GtkCList *clist, GtkCListRow *clist_row, gint column, GtkCellType type, const gchar *text, guint8 spacing, GdkPixmap *pixmap, GdkBitmap *mask);static void set_node_info (GtkCTree *ctree, GtkCTreeNode *node, const gchar *text, guint8 spacing, GdkPixmap *pixmap_closed, GdkBitmap *mask_closed, GdkPixmap *pixmap_opened, GdkBitmap *mask_opened, gboolean is_leaf, gboolean expanded);static GtkCTreeRow *row_new (GtkCTree *ctree);static void row_delete (GtkCTree *ctree, GtkCTreeRow *ctree_row);static void tree_delete (GtkCTree *ctree, GtkCTreeNode *node, gpointer data);static void tree_delete_row (GtkCTree *ctree, GtkCTreeNode *node, gpointer data);static void real_clear (GtkCList *clist);static void tree_update_level (GtkCTree *ctree, GtkCTreeNode *node, gpointer data);static void tree_select (GtkCTree *ctree, GtkCTreeNode *node, gpointer data);static void tree_unselect (GtkCTree *ctree, GtkCTreeNode *node, gpointer data);static void real_select_all (GtkCList *clist);static void real_unselect_all (GtkCList *clist);static void tree_expand (GtkCTree *ctree, GtkCTreeNode *node, gpointer data);static void tree_collapse (GtkCTree *ctree, GtkCTreeNode *node, gpointer data);static void tree_collapse_to_depth (GtkCTree *ctree, GtkCTreeNode *node, gint depth);static void tree_toggle_expansion (GtkCTree *ctree, GtkCTreeNode *node, gpointer data);static void change_focus_row_expansion (GtkCTree *ctree, GtkCTreeExpansionType expansion);static void real_select_row (GtkCList *clist, gint row, gint column, GdkEvent *event);static void real_unselect_row (GtkCList *clist, gint row, gint column, GdkEvent *event);static void real_tree_select (GtkCTree *ctree, GtkCTreeNode *node, gint column);static void real_tree_unselect (GtkCTree *ctree, GtkCTreeNode *node, gint column);static void real_tree_expand (GtkCTree *ctree, GtkCTreeNode *node);static void real_tree_collapse (GtkCTree *ctree, GtkCTreeNode *node);static void real_tree_move (GtkCTree *ctree, GtkCTreeNode *node, GtkCTreeNode *new_parent, GtkCTreeNode *new_sibling);static void real_row_move (GtkCList *clist, gint source_row, gint dest_row);static void gtk_ctree_link (GtkCTree *ctree, GtkCTreeNode *node, GtkCTreeNode *parent, GtkCTreeNode *sibling, gboolean update_focus_row);static void gtk_ctree_unlink (GtkCTree *ctree, GtkCTreeNode *node, gboolean update_focus_row);static GtkCTreeNode * gtk_ctree_last_visible (GtkCTree *ctree, GtkCTreeNode *node);static gboolean ctree_is_hot_spot (GtkCTree *ctree, GtkCTreeNode *node, gint row, gint x, gint y);static void tree_sort (GtkCTree *ctree, GtkCTreeNode *node, gpointer data);static void fake_unselect_all (GtkCList *clist, gint row);static GList * selection_find (GtkCList *clist, gint row_number, GList *row_list_element);static void resync_selection (GtkCList *clist, GdkEvent *event);static void real_undo_selection (GtkCList *clist);static void select_row_recursive (GtkCTree *ctree, GtkCTreeNode *node, gpointer data);static gint real_insert_row (GtkCList *clist, gint row, gchar *text[]);static void real_remove_row (GtkCList *clist, gint row);static void real_sort_list (GtkCList *clist);static void cell_size_request (GtkCList *clist, GtkCListRow *clist_row, gint column, GtkRequisition *requisition);static void column_auto_resize (GtkCList *clist, GtkCListRow *clist_row, gint column, gint old_width);static void auto_resize_columns (GtkCList *clist);static gboolean check_drag (GtkCTree *ctree, GtkCTreeNode *drag_source, GtkCTreeNode *drag_target, GtkCListDragPos insert_pos);static void gtk_ctree_drag_begin (GtkWidget *widget, GdkDragContext *context);static gint gtk_ctree_drag_motion (GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint time);static void gtk_ctree_drag_data_received (GtkWidget *widget, GdkDragContext *context, gint x, gint y, GtkSelectionData *selection_data, guint info, guint32 time);static void remove_grab (GtkCList *clist);static void drag_dest_cell (GtkCList *clist, gint x, gint y, GtkCListDestInfo *dest_info);enum{ TREE_SELECT_ROW, TREE_UNSELECT_ROW, TREE_EXPAND, TREE_COLLAPSE, TREE_MOVE, CHANGE_FOCUS_ROW_EXPANSION, LAST_SIGNAL};static GtkCListClass *parent_class = NULL;static GtkContainerClass *container_class = NULL;static guint ctree_signals[LAST_SIGNAL] = {0};GtkTypegtk_ctree_get_type (void){ static GtkType ctree_type = 0; if (!ctree_type) { static const GtkTypeInfo ctree_info = { "GtkCTree", sizeof (GtkCTree), sizeof (GtkCTreeClass), (GtkClassInitFunc) gtk_ctree_class_init, (GtkObjectInitFunc) gtk_ctree_init, /* reserved_1 */ NULL, /* reserved_2 */ NULL, (GtkClassInitFunc) NULL, }; ctree_type = gtk_type_unique (GTK_TYPE_CLIST, &ctree_info); } return ctree_type;}static voidgtk_ctree_class_init (GtkCTreeClass *klass){ GtkObjectClass *object_class; GtkWidgetClass *widget_class; GtkCListClass *clist_class; GtkBindingSet *binding_set; object_class = (GtkObjectClass *) klass; widget_class = (GtkWidgetClass *) klass; container_class = (GtkContainerClass *) klass; clist_class = (GtkCListClass *) klass; parent_class = gtk_type_class (GTK_TYPE_CLIST); container_class = gtk_type_class (GTK_TYPE_CONTAINER); gtk_object_add_arg_type ("GtkCTree::n_columns", GTK_TYPE_UINT, GTK_ARG_READWRITE | GTK_ARG_CONSTRUCT_ONLY, ARG_N_COLUMNS); gtk_object_add_arg_type ("GtkCTree::tree_column", GTK_TYPE_UINT, GTK_ARG_READWRITE | GTK_ARG_CONSTRUCT_ONLY, ARG_TREE_COLUMN); gtk_object_add_arg_type ("GtkCTree::indent", GTK_TYPE_UINT, GTK_ARG_READWRITE, ARG_INDENT); gtk_object_add_arg_type ("GtkCTree::spacing", GTK_TYPE_UINT, GTK_ARG_READWRITE, ARG_SPACING); gtk_object_add_arg_type ("GtkCTree::show_stub", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_SHOW_STUB); gtk_object_add_arg_type ("GtkCTree::line_style", GTK_TYPE_CTREE_LINE_STYLE, GTK_ARG_READWRITE, ARG_LINE_STYLE); gtk_object_add_arg_type ("GtkCTree::expander_style", GTK_TYPE_CTREE_EXPANDER_STYLE, GTK_ARG_READWRITE, ARG_EXPANDER_STYLE); object_class->set_arg = gtk_ctree_set_arg; object_class->get_arg = gtk_ctree_get_arg; ctree_signals[TREE_SELECT_ROW] = gtk_signal_new ("tree_select_row", GTK_RUN_FIRST, object_class->type, GTK_SIGNAL_OFFSET (GtkCTreeClass, tree_select_row), gtk_marshal_NONE__POINTER_INT, GTK_TYPE_NONE, 2, GTK_TYPE_CTREE_NODE, GTK_TYPE_INT); ctree_signals[TREE_UNSELECT_ROW] = gtk_signal_new ("tree_unselect_row", GTK_RUN_FIRST, object_class->type, GTK_SIGNAL_OFFSET (GtkCTreeClass, tree_unselect_row), gtk_marshal_NONE__POINTER_INT, GTK_TYPE_NONE, 2, GTK_TYPE_CTREE_NODE, GTK_TYPE_INT); ctree_signals[TREE_EXPAND] = gtk_signal_new ("tree_expand", GTK_RUN_LAST, object_class->type, GTK_SIGNAL_OFFSET (GtkCTreeClass, tree_expand), gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1, GTK_TYPE_CTREE_NODE); ctree_signals[TREE_COLLAPSE] = gtk_signal_new ("tree_collapse", GTK_RUN_LAST, object_class->type, GTK_SIGNAL_OFFSET (GtkCTreeClass, tree_collapse), gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1, GTK_TYPE_CTREE_NODE); ctree_signals[TREE_MOVE] = gtk_signal_new ("tree_move", GTK_RUN_LAST, object_class->type, GTK_SIGNAL_OFFSET (GtkCTreeClass, tree_move), gtk_marshal_NONE__POINTER_POINTER_POINTER, GTK_TYPE_NONE, 3, GTK_TYPE_CTREE_NODE, GTK_TYPE_CTREE_NODE, GTK_TYPE_CTREE_NODE); ctree_signals[CHANGE_FOCUS_ROW_EXPANSION] = gtk_signal_new ("change_focus_row_expansion", GTK_RUN_LAST | GTK_RUN_ACTION, object_class->type, GTK_SIGNAL_OFFSET (GtkCTreeClass, change_focus_row_expansion), gtk_marshal_NONE__ENUM, GTK_TYPE_NONE, 1, GTK_TYPE_CTREE_EXPANSION_TYPE); gtk_object_class_add_signals (object_class, ctree_signals, LAST_SIGNAL); widget_class->realize = gtk_ctree_realize; widget_class->unrealize = gtk_ctree_unrealize; widget_class->button_press_event = gtk_ctree_button_press;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -