Commit 4de2665e authored by Shawn Amundson's avatar Shawn Amundson

Tree widget implementation by Bolliet Jerome.

There is also another tree widget implementation by
AOSASA Shigeru <aozasa@sakuranet.or.jp>:

ftp://ftp.gimp.org/pub/gtk/contrib/gtk-shige-971216-0.tar.gz

-Shawn
parent 865eab24
......@@ -8,3 +8,4 @@ testgtk
testinput
testselection
simple
testtree
......@@ -193,11 +193,15 @@ EXTRA_DIST = \
marble.xpm \
3DRings.xpm \
FilesQueue.xpm \
Modeller.xpm
Modeller.xpm \
tree_plus.xpm \
tree_minus.xpm \
tree_plus.xbm \
tree_minus.xbm
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/glib @x_cflags@
noinst_PROGRAMS = testgtk testinput testselection simple
noinst_PROGRAMS = testgtk testinput testselection simple testtree
testgtk_LDADD = \
libgtk.la \
$(top_builddir)/gdk/libgdk.la \
......@@ -230,6 +234,14 @@ simple_LDADD = \
$(top_builddir)/glib/libglib.la \
-lm
testtree_LDADD = \
libgtk.la \
$(top_builddir)/gdk/libgdk.la \
@x_ldflags@ \
@x_libs@ \
$(top_builddir)/glib/libglib.la \
-lm
DEPS = \
$(top_builddir)/gtk/libgtk.la \
$(top_builddir)/gdk/libgdk.la \
......@@ -239,6 +251,7 @@ testgtk_DEPENDENCIES = $(DEPS)
testinput_DEPENDENCIES = $(DEPS)
testselection_DEPENDENCIES = $(DEPS)
simple_DEPENDENCIES = $(DEPS)
testtree_DEPENDENCIES = $(DEPS)
.PHONY: files
......
......@@ -259,11 +259,15 @@ EXTRA_DIST = \
marble.xpm \
3DRings.xpm \
FilesQueue.xpm \
Modeller.xpm
Modeller.xpm \
tree_plus.xpm \
tree_minus.xpm \
tree_plus.xbm \
tree_minus.xbm
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/glib @x_cflags@
noinst_PROGRAMS = testgtk testinput testselection simple
noinst_PROGRAMS = testgtk testinput testselection simple testtree
testgtk_LDADD = \
libgtk.la \
$(top_builddir)/gdk/libgdk.la \
......@@ -296,6 +300,14 @@ simple_LDADD = \
$(top_builddir)/glib/libglib.la \
-lm
testtree_LDADD = \
libgtk.la \
$(top_builddir)/gdk/libgdk.la \
@x_ldflags@ \
@x_libs@ \
$(top_builddir)/glib/libglib.la \
-lm
DEPS = \
$(top_builddir)/gtk/libgtk.la \
$(top_builddir)/gdk/libgdk.la \
......@@ -305,6 +317,7 @@ testgtk_DEPENDENCIES = $(DEPS)
testinput_DEPENDENCIES = $(DEPS)
testselection_DEPENDENCIES = $(DEPS)
simple_DEPENDENCIES = $(DEPS)
testtree_DEPENDENCIES = $(DEPS)
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = ../config.h
CONFIG_CLEAN_FILES =
......@@ -352,6 +365,9 @@ testselection_LDFLAGS =
simple_SOURCES = simple.c
simple_OBJECTS = simple.o
simple_LDFLAGS =
testtree_SOURCES = testtree.c
testtree_OBJECTS = testtree.o
testtree_LDFLAGS =
CFLAGS = @CFLAGS@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
......@@ -363,7 +379,7 @@ DIST_COMMON = Makefile.am Makefile.in
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = gtar
TAR = tar
GZIP = --best
DEP_FILES = .deps/fnmatch.P .deps/gtkaccelerator.P \
.deps/gtkadjustment.P .deps/gtkalignment.P .deps/gtkarrow.P \
......@@ -391,9 +407,9 @@ DEP_FILES = .deps/fnmatch.P .deps/gtkaccelerator.P \
.deps/gtkviewport.P .deps/gtkvpaned.P .deps/gtkvruler.P \
.deps/gtkvscale.P .deps/gtkvscrollbar.P .deps/gtkvseparator.P \
.deps/gtkwidget.P .deps/gtkwindow.P .deps/simple.P .deps/testgtk.P \
.deps/testinput.P .deps/testselection.P
SOURCES = $(libgtk_la_SOURCES) testgtk.c testinput.c testselection.c simple.c
OBJECTS = $(libgtk_la_OBJECTS) testgtk.o testinput.o testselection.o simple.o
.deps/testinput.P .deps/testselection.P .deps/testtree.P
SOURCES = $(libgtk_la_SOURCES) testgtk.c testinput.c testselection.c simple.c testtree.c
OBJECTS = $(libgtk_la_OBJECTS) testgtk.o testinput.o testselection.o simple.o testtree.o
default: all
......@@ -498,6 +514,10 @@ simple: $(simple_OBJECTS) $(simple_DEPENDENCIES)
@rm -f simple
$(LINK) $(simple_LDFLAGS) $(simple_OBJECTS) $(simple_LDADD) $(LIBS)
testtree: $(testtree_OBJECTS) $(testtree_DEPENDENCIES)
@rm -f testtree
$(LINK) $(testtree_LDFLAGS) $(testtree_OBJECTS) $(testtree_LDADD) $(LIBS)
install-gtkincludeHEADERS: $(gtkinclude_HEADERS)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(gtkincludedir)
......
This diff is collapsed.
......@@ -32,6 +32,15 @@ extern "C" {
#define GTK_TREE_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, gtk_tree_get_type (), GtkTreeClass)
#define GTK_IS_TREE(obj) GTK_CHECK_TYPE (obj, gtk_tree_get_type ())
#define GTK_IS_ROOT_TREE(obj) (GTK_TREE(obj)->root_tree == NULL)
#define GTK_TREE_ROOT_TREE(obj) (GTK_TREE(obj)->root_tree ? GTK_TREE(obj)->root_tree : GTK_TREE(obj))
#define GTK_TREE_SELECTION(obj) (GTK_TREE_ROOT_TREE(obj)->selection)
typedef enum
{
GTK_TREE_VIEW_LINE, /* default view mode */
GTK_TREE_VIEW_ITEM
} GtkTreeViewMode;
typedef struct _GtkTree GtkTree;
typedef struct _GtkTreeClass GtkTreeClass;
......@@ -41,25 +50,58 @@ struct _GtkTree
GtkContainer container;
GList *children;
GtkTree* root_tree; /* owner of selection list */
GtkWidget* tree_owner;
GList *selection;
guint indent_value;
guint current_indent;
guint selection_mode : 2;
guint view_mode : 1;
};
struct _GtkTreeClass
{
GtkContainerClass parent_class;
};
guint gtk_tree_get_type (void);
GtkWidget* gtk_tree_new (void);
void gtk_tree_append (GtkTree *tree,
GtkWidget *child);
void gtk_tree_prepend (GtkTree *tree,
GtkWidget *child);
void gtk_tree_insert (GtkTree *tree,
GtkWidget *child,
gint position);
void (* selection_changed) (GtkTree *tree);
void (* select_child) (GtkTree *tree,
GtkWidget *child);
void (* unselect_child) (GtkTree *tree,
GtkWidget *child);
};
guint gtk_tree_get_type (void);
GtkWidget* gtk_tree_new (void);
void gtk_tree_append (GtkTree *tree,
GtkWidget *child);
void gtk_tree_prepend (GtkTree *tree,
GtkWidget *child);
void gtk_tree_insert (GtkTree *tree,
GtkWidget *child,
gint position);
void gtk_tree_remove_item (GtkTree *tree,
GtkWidget *child);
void gtk_tree_remove_items (GtkTree *tree,
GList *items);
void gtk_tree_clear_items (GtkTree *tree,
gint start,
gint end);
void gtk_tree_select_item (GtkTree *tree,
gint item);
void gtk_tree_unselect_item (GtkTree *tree,
gint item);
void gtk_tree_select_child (GtkTree *tree,
GtkWidget *child);
void gtk_tree_unselect_child (GtkTree *tree,
GtkWidget *child);
gint gtk_tree_child_position (GtkTree *tree,
GtkWidget *child);
void gtk_tree_set_selection_mode (GtkTree *tree,
GtkSelectionMode mode);
void gtk_tree_set_view_mode (GtkTree *tree,
GtkTreeViewMode mode);
#ifdef __cplusplus
}
#endif /* __cplusplus */
......
This diff is collapsed.
......@@ -32,6 +32,7 @@ extern "C" {
#define GTK_TREE_ITEM_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, gtk_tree_item_get_type (), GtkTreeItemClass)
#define GTK_IS_TREE_ITEM(obj) GTK_CHECK_TYPE (obj, gtk_tree_item_get_type ())
#define GTK_TREE_ITEM_SUBTREE(obj) GTK_TREE_ITEM(obj)->subtree;
typedef struct _GtkTreeItem GtkTreeItem;
typedef struct _GtkTreeItemClass GtkTreeItemClass;
......@@ -40,8 +41,11 @@ struct _GtkTreeItem
{
GtkItem item;
GtkWidget *child;
GtkWidget *subtree;
GtkWidget *pixmaps_box;
GtkWidget *plus_pix_widget, *minus_pix_widget;
guint expanded : 1;
};
struct _GtkTreeItemClass
......@@ -58,6 +62,7 @@ GtkWidget* gtk_tree_item_new (void);
GtkWidget* gtk_tree_item_new_with_label (gchar *label);
void gtk_tree_item_set_subtree (GtkTreeItem *tree_item,
GtkWidget *subtree);
void gtk_tree_item_remove_subtree (GtkTreeItem *tree_item);
void gtk_tree_item_select (GtkTreeItem *tree_item);
void gtk_tree_item_deselect (GtkTreeItem *tree_item);
void gtk_tree_item_expand (GtkTreeItem *tree_item);
......
#include "gtk.h"
typedef struct sTreeButtons {
GtkWidget *button_add, *button_remove;
} sTreeButton;
static gint cb_delete_event() {
return TRUE;
}
static void cb_destroy_event() {
gtk_main_quit();
}
static void cb_tree_changed(GtkTree* tree) {
sTreeButton* tree_buttons;
GList* selected;
gint nb_selected;
tree_buttons = gtk_object_get_user_data(GTK_OBJECT(tree));
selected = tree->selection;
nb_selected = g_list_length(selected);
if(nb_selected == 0) {
if(tree->children == NULL)
gtk_widget_set_sensitive(tree_buttons->button_add, TRUE);
else
gtk_widget_set_sensitive(tree_buttons->button_add, FALSE);
gtk_widget_set_sensitive(tree_buttons->button_remove, FALSE);
} else {
gtk_widget_set_sensitive(tree_buttons->button_remove, TRUE);
gtk_widget_set_sensitive(tree_buttons->button_add, (nb_selected == 1));
}
}
static void add_tree_item(GtkWidget* w, GtkTree* tree) {
static gint nb_item_add = 0;
GList* selected;
gint nb_selected;
GtkTreeItem *selected_item;
GtkWidget* new_item;
GtkWidget* subtree;
gchar buffer[255];
selected = GTK_TREE_SELECTION(tree);
nb_selected = g_list_length(selected);
if(nb_selected > 1) return;
if(nb_selected == 0 && tree->children != NULL) return;
if(tree->children == NULL) {
subtree = GTK_WIDGET(tree);
} else {
selected_item = GTK_TREE_ITEM(selected->data);
subtree = GTK_TREE_ITEM_SUBTREE(selected_item);
}
if(!subtree) { /* create a new subtree if not exist */
subtree = gtk_tree_new();
gtk_signal_connect(GTK_OBJECT(subtree), "selection_changed",
(GtkSignalFunc)cb_tree_changed,
(gpointer)NULL);
gtk_tree_item_set_subtree(GTK_TREE_ITEM(selected_item), subtree);
}
/* create a new item */
sprintf(buffer, "new item %d", nb_item_add++);
new_item = gtk_tree_item_new_with_label(buffer);
gtk_tree_append(GTK_TREE(subtree), new_item);
gtk_widget_show(new_item);
}
static void remove_tree_item(GtkWidget* w, GtkTree* tree) {
GList* selected, *clear_list;
GtkTree* root_tree;
root_tree = GTK_TREE_ROOT_TREE(tree);
selected = GTK_TREE_SELECTION(tree);
clear_list = NULL;
while (selected) {
clear_list = g_list_prepend (clear_list, selected->data);
selected = selected->next;
}
if(clear_list) {
clear_list = g_list_reverse (clear_list);
gtk_tree_remove_items(root_tree, clear_list);
selected = clear_list;
while (selected) {
gtk_widget_destroy (GTK_WIDGET (selected->data));
selected = selected->next;
}
g_list_free (clear_list);
}
}
void create_tree_item(GtkWidget* parent, int level, int nb_item, int level_max) {
int i;
char buffer[255];
GtkWidget *item, *tree;
for(i = 0; i<nb_item; i++) {
sprintf(buffer, "item %d-%d", level, i);
item = gtk_tree_item_new_with_label(buffer);
gtk_tree_append(GTK_TREE(parent), item);
gtk_widget_show(item);
/* g_print("item '%s' : 0x%x\n", buffer, (int)item); */
if(level < level_max) {
tree = gtk_tree_new();
/* g_print("subtree '%s' : 0x%x\n", buffer, (int)tree); */
gtk_signal_connect(GTK_OBJECT(tree), "selection_changed",
(GtkSignalFunc)cb_tree_changed,
(gpointer)NULL);
create_tree_item(tree, level+1, nb_item, level_max);
gtk_tree_item_set_subtree(GTK_TREE_ITEM(item), tree);
/* gtk_tree_item_expand(GTK_TREE_ITEM(item)); */
}
}
}
void create_tree_page(GtkWidget* parent, GtkSelectionMode mode,
char* page_name) {
GtkWidget *root, *scrolled_win;
GtkWidget *box, *label;
GtkWidget *button;
sTreeButton* tree_buttons;
/* create notebook page */
box = gtk_vbox_new(FALSE, 5);
gtk_container_border_width (GTK_CONTAINER (box), 5);
gtk_widget_show (box);
label = gtk_label_new(page_name);
gtk_notebook_append_page(GTK_NOTEBOOK(parent), box, label);
scrolled_win = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_box_pack_start (GTK_BOX (box), scrolled_win, TRUE, TRUE, 0);
gtk_widget_set_usize (scrolled_win, 200, 200);
gtk_widget_show (scrolled_win);
root = gtk_tree_new();
/* g_print("root: 0x%x\n", (int)root); */
gtk_container_add(GTK_CONTAINER(scrolled_win), root);
gtk_tree_set_selection_mode(GTK_TREE(root), mode);
/* gtk_tree_set_view_mode(GTK_TREE(root), GTK_TREE_VIEW_ITEM); */
gtk_signal_connect(GTK_OBJECT(root), "selection_changed",
(GtkSignalFunc)cb_tree_changed,
(gpointer)NULL);
gtk_widget_show(root);
create_tree_item(root, 1, 3, 3);
tree_buttons = g_malloc(sizeof(sTreeButton));
button = gtk_button_new_with_label("Add");
gtk_box_pack_start(GTK_BOX (box), button, TRUE, TRUE, 0);
gtk_signal_connect(GTK_OBJECT(button), "clicked",
(GtkSignalFunc)add_tree_item,
(gpointer)root);
gtk_widget_set_sensitive(button, FALSE);
gtk_widget_show(button);
tree_buttons->button_add = button;
button = gtk_button_new_with_label("Remove");
gtk_box_pack_start(GTK_BOX (box), button, TRUE, TRUE, 0);
gtk_signal_connect(GTK_OBJECT(button), "clicked",
(GtkSignalFunc)remove_tree_item,
(gpointer)root);
gtk_widget_set_sensitive(button, FALSE);
gtk_widget_show(button);
tree_buttons->button_remove = button;
gtk_object_set_user_data(GTK_OBJECT(root), (gpointer)tree_buttons);
}
void main(int argc, char** argv) {
GtkWidget* window, *notebook;
GtkWidget* box1;
GtkWidget* separator;
GtkWidget* button;
gtk_init (&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Test Tree");
gtk_signal_connect (GTK_OBJECT (window), "delete_event",
(GtkSignalFunc) cb_delete_event, NULL);
gtk_signal_connect (GTK_OBJECT (window), "destroy",
(GtkSignalFunc) cb_destroy_event, NULL);
box1 = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(window), box1);
gtk_widget_show(box1);
/* create notebook */
notebook = gtk_notebook_new ();
gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_TOP);
gtk_box_pack_start (GTK_BOX (box1), notebook, TRUE, TRUE, 0);
gtk_widget_show (notebook);
/* create unique selection page */
create_tree_page(notebook, GTK_SELECTION_SINGLE, "Single");
create_tree_page(notebook, GTK_SELECTION_BROWSE, "Browse");
create_tree_page(notebook, GTK_SELECTION_MULTIPLE, "Multiple");
separator = gtk_hseparator_new();
gtk_box_pack_start(GTK_BOX (box1), separator, TRUE, TRUE, 0);
gtk_widget_show (separator);
button = gtk_button_new_with_label("Close");
gtk_box_pack_start(GTK_BOX (box1), button, TRUE, TRUE, 0);
gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
(GtkSignalFunc)gtk_widget_destroy,
GTK_OBJECT(window));
gtk_widget_show(button);
gtk_widget_show(window);
gtk_main();
}
#define tree_minus_width 9
#define tree_minus_height 9
static char tree_minus_bits[] = {
0xff,0xff,0x01,0xff,0x01,0xff,0x01,0xff,0x7d,0xff,0x01,0xff,0x01,0xff,0x01,
0xff,0xff,0xff};
/* XPM */
static char *tree_minus[] = {
/* width height num_colors chars_per_pixel */
" 9 9 2 1",
/* colors */
". c #000000",
"# c #f8fcf8",
/* pixels */
".........",
".#######.",
".#######.",
".#######.",
".#.....#.",
".#######.",
".#######.",
".#######.",
"........."
};
#define tree_plus_width 9
#define tree_plus_height 9
static char tree_plus_bits[] = {
0xff,0xff,0x01,0xff,0x11,0xff,0x11,0xff,0x7d,0xff,0x11,0xff,0x11,0xff,0x01,
0xff,0xff,0xff};
/* XPM */
static char *tree_plus[] = {
/* width height num_colors chars_per_pixel */
" 9 9 2 1",
/* colors */
". c #000000",
"# c #f8fcf8",
/* pixels */
".........",
".#######.",
".###.###.",
".###.###.",
".#.....#.",
".###.###.",
".###.###.",
".#######.",
"........."
};
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment