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

📄 tree-box.zc

📁 实现树形结构
💻 ZC
📖 第 1 页 / 共 2 页
字号:
//[of]:description
//[c]tree-box - display a tree model
//[c]
//[cf]
//[of]:license
//[c]Code Browser - a folding text editor for programmers
//[c]Copyright (C) 2003-07 Marc Kerbiquet
//[c]
//[c]This program is free software; you can redistribute it and/or modify
//[c]it under the terms of the GNU General Public License as published by
//[c]the Free Software Foundation; either version 2 of the License, or
//[c](at your option) any later version.
//[c]
//[c]This program is distributed in the hope that it will be useful,
//[c]but WITHOUT ANY WARRANTY; without even the implied warranty of
//[c]MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//[c]GNU General Public License for more details.
//[c]
//[c]You should have received a copy of the GNU General Public License
//[c]along with this program; if not, write to the Free Software
//[c]Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//[cf]
//[of]:imports
import "base/types"
import "base/memory-allocator"
import "text/vector-of-strings"
import "text/string"
import "text/string-buffer"
//[c]
import "graphics/geometry"
import "graphics/graphics"
import "user/box"
import "image-list"
//[c]
import "glib/glib"
import "glib/glib-object"
import "gdk-pixbuf/gdk-pixbuf"
import "gdk/gdk"
import "gtk/gtk"
//[cf]
//[c]
//[of]:tree model
//[c]
public struct tree model
	class: tree model class
end

public struct tree model class
	root: {tree model} tree item
	add listener: {tree model, tree listener} void
	remove listener: {tree model, tree listener} void
end
//[c]
//[of]:root (m)
public func root (m: tree model)
	return root (class (m)) {m}
end
//[cf]
//[of]:add listener (m, listener)
//[c]
func add listener (m: tree model, listener: tree listener)
	add listener (class (m)) {m, listener}
end
//[cf]
//[of]:remove listener (m, listener)
//[c]
func remove listener (m: tree model, listener: tree listener)
	remove listener (class (m)) {m, listener}
end
//[cf]
//[c]
//[cf]
//[of]:tree item
//[of]:definition
//[c]
public struct tree item
	class: tree item class
end

public struct tree item class
	append text: {tree item, string buffer} void
	parent: {tree item} tree item
	first child: {tree item} tree item
	next sibling: {tree item} tree item
	open: {tree item} void
	close: {tree item} void
	has children: {tree item} bool
	image: {tree item} int
end
//[c]
//[cf]
//[c]
//[of]:append text
public func append text (m: tree item, s: string buffer)
	append text (class (m)) {m, s}
end
//[cf]
//[of]:parent
public func parent (m: tree item)
	return parent (class (m)) {m}
end
//[cf]
//[of]:first child
public func first child (m: tree item)
	return first child (class (m)) {m}
end
//[cf]
//[of]:next sibling
public func next sibling (m: tree item)
	return next sibling (class (m)) {m}
end
//[cf]
//[of]:open
public func open (m: tree item)
	open (class (m)) {m}
end
//[cf]
//[of]:close
public func close (m: tree item)
	close (class (m)) {m}
end
//[cf]
//[of]:has children
//[c]
public func has children (m: tree item)
	return has children (class (m)) {m}
end
//[cf]
//[of]:image
//[c]
public func image (m: tree item)
	return image (class (m)) {m}
end
//[cf]
//[cf]
//[of]:tree listener
//[of]:definition
//[c]
public struct tree listener
	recipient: object
	text changed: {object, tree item} void
	data changed: {object, tree item} void
	has children changed: {object, tree item} void
	children replaced: {object, tree replace event} void
end
//[c]
public struct tree replace event
	parent: tree item
	index: dword
	removed: dword
	inserted: dword
end
//[c]
public func text changed (m: tree listener, item: tree item)
	text changed (m) {recipient (m), item}
end
//[c]
public func data changed (m: tree listener, item: tree item)
	data changed (m) {recipient (m), item}
end
//[c]
public func has children changed (m: tree listener, item: tree item)
	has children changed (m) {recipient (m), item}
end
//[c]
public func children replaced (m: tree listener, e: tree replace event)
	children replaced (m) {recipient (m), e}
end
//[cf]
//[cf]
//[of]:tree item changed event
public struct tree item changed event : local event
	tree item : tree item
end
//[c]
public def tree item changed event type : local event type
//[cf]
//[c]
//[of]:tree box
//[of]:type
public struct tree box : local box

	private 
		tree view : GtkTreeView
		tree model: tree model
		selected item: tree item
		synchronizing selection: bool
		listener: local tree listener
		image list: image list
		original selected item: tree item

end
//[cf]
//[of]:instance creation
//[of]:new tree box (parent)
public func new tree box (parent: box)

	equ s = sizeof local tree box
	def e = allocate memory (s): tree box
	initialize (e, parent)
	return e

end
//[cf]
//[cf]
//[of]:tree
//[of]:tree
public func tree (m: tree box)

	return tree model (m)

end
//[cf]
//[of]:set tree (tree)
//[c]
public func set tree (m: tree box, tree: tree model)
	def selection = not nil (tree) -> root (tree), nil
	set tree (m, tree, selection)
end
//[cf]
//[of]:set tree (tree, selection)
//[c]Change the tree and selection
//[c]
//[c]ARGUMENTS
//[c]	tree -- the tree to show
//[c]	selection -- the node to select
//[c]
//[c]REMARKS
//[c]	tree must be the same as the one edited by the source box.
//[c]	
private func set tree (
		m: tree box, 
		tree: tree model,
		selection: tree item)

	def old tree = tree model (m)
	tree model (m) = tree

	if not nil (old tree)
		remove listener (old tree, listener (m))
	end
	if not nil (tree)
		add listener (tree, listener (m))
	end

	def p = tree view (m)
	if not nil (tree)
		def gtk model = new custom tree model (tree, image list (m))
		gtk_tree_view_set_model(p, gtk tree model (gtk model))
		g_object_unref (gtk model)
		
		def path = gtk_tree_path_new
		gtk_tree_path_append_index (path, 0)
		gtk_tree_view_expand_row (p, path, FALSE)
		gtk_tree_path_free (path)
	else
		gtk_tree_view_set_model (p, nil)
	end

	selected item (m) = nil	// force update
	set selection (m, selection)

end
//[cf]
//[cf]
//[of]:selection
//[of]:selection
//[c]Returns the the currently selected item or nil
//[c]
public func selection (m: tree box)
	return selected item (m)
end
//[cf]
//[of]:set selection (item)
//[c]Changes the current selection
//[c]to unselect, use nil as item
//[c]
public func set selection (m: tree box, item: tree item)

	if item <> selected item (m)
		selected item (m) = item

		def sel = gtk selection (m)
		if is nil (item)
			gtk_tree_selection_unselect_all (sel)
		else
			def gtk tree model = gtk_tree_view_get_model (tree view (m))
			
			// expand first
			def expand = get path (gtk tree model, item)
			gtk_tree_path_up (expand)
			gtk_tree_view_expand_to_path (tree view (m), expand)
			gtk_tree_path_free (expand)

			// select row			
			def path = get path (gtk tree model, item)
			gtk_tree_selection_select_path (sel, path)
			gtk_tree_view_set_cursor (tree view (m), path, nil, FALSE)
			gtk_tree_path_free (path)
		end

	end

end
//[cf]
//[cf]
//[of]:image list
//[of]:set image list (list)
public func set image list (m: tree box, list: image list)

	image list (m) = list

end
//[cf]
//[cf]
//[c]
//[of]:restricted
//[of]:initialize (parent)
public func initialize (m: tree box, parent: box)

	// Create the widget before initializing super class
	// The super class needs widget to connect signals
	
	// Create the tree view
	def p = gtk_tree_view_new : GtkTreeView
	def pixbuf renderer = gtk_cell_renderer_pixbuf_new
	def text renderer = gtk_cell_renderer_text_new
	def column = gtk_tree_view_column_new
	gtk_tree_view_column_pack_start (column, pixbuf renderer, FALSE)
	gtk_tree_view_column_add_attribute (column, pixbuf renderer, "pixbuf", 0)
	gtk_tree_view_column_pack_start (column, text renderer, TRUE)
	gtk_tree_view_column_add_attribute (column, text renderer, "text", 1)
	gtk_tree_view_append_column (p: GtkTreeView, column)
	gtk_tree_view_set_headers_visible (p: GtkTreeView, FALSE)
	tree view (m) = p
	gtk_widget_show (p)
	
	def selection = gtk_tree_view_get_selection (p)
	gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE)

	// Create the scollers
	def s = gtk_scrolled_window_new (nil, nil)
	gtk_scrolled_window_set_policy (
		s: GtkScrolledWindow, 
		GTK_POLICY_AUTOMATIC, 
		GTK_POLICY_AUTOMATIC)
	gtk_container_add (s:GtkScrolledWindow, p)
	gtk_widget_show (s)

	// Create the border
	def f = gtk_frame_new (nil)
	widget (m) = f
	gtk_frame_set_shadow_type (f : GtkFrame, GTK_SHADOW_IN)
	gtk_container_add (f : GtkFrame, s)
	gtk_widget_show (f)
	
	g_signal_connect(
		gtk selection (m), 
		"changed", 
		^changed (GtkTreeSelection, tree box): GCallback,
		m)
		
	g_signal_connect(
		p,
		"button-press-event",
		^button press event (GtkWidget, GdkEventButton, box): GCallback,
		m)

	g_signal_connect(
		p,
		"button-release-event",
		^button release event (GtkWidget, GdkEventButton, box): GCallback,
		m)

	g_signal_connect(
		p,
		"key-press-event",
		^key press event (GtkWidget, GdkEventKey, box): GCallback,
		m)

	g_signal_connect(
		p,
		"key-release-event", 
		^key release event (GtkWidget, GdkEventKey, box): GCallback,
		m)

	g_signal_connect(
		p,
		"focus-in-event", 
		^focus in event (GtkWidget, GdkEventFocus, box): GCallback,
		m)

	g_signal_connect(
		p,
		"focus-out-event", 
		^focus out event (GtkWidget, GdkEventFocus, box): GCallback,
		m)

	g_signal_connect(
		p,
		"test-expand-row", 
		^test row expand (GtkTreeView, GtkTreeIter, GtkTreePath, tree box): GCallback,
		m)

	g_signal_connect(
		p,
		"popup-menu", 
		^popup menu (GtkWidget, tree box): GCallback,
		m)

	initialize (super (m), parent)
	class (m) = tree box class
	tree model (m) = nil
	selected item (m) = nil
	original selected item (m) = nil
	synchronizing selection (m) = false
	image list (m) = nil
	
	recipient (listener (m)) = m
	text changed (listener (m)) = ^text changed (tree box, tree item)
	data changed (listener (m)) = ^data changed (tree box, tree item)
	has children changed (listener (m)) = ^has children changed (tree box, tree item)
	children replaced (listener (m)) = ^children replaced (tree box, tree replace event)

end
//[cf]
//[c]
//[of]:actual set focus
public func actual set focus (m: tree box)
	gtk_widget_grab_focus (tree view (m))
end
//[cf]
//[of]:actual release
public func actual release (m: tree box)

	actual release (super (m))
	
	def tree = tree model (m)
	if not nil (tree)
		remove listener (tree, listener (m))
	end

end
//[cf]
//[c]
//[of]:handle mouse down (event)
public func handle mouse down (m: tree box, e:mouse button event)
	
	if button (e) == right mouse button

		// select item first
		def x = x (position (e))
		def y = y (position (e))
		def path : [1] GtkTreePath
		if gtk_tree_view_get_path_at_pos (tree view (m), x, y, path, nil, nil, nil) == TRUE
			def gtk tree model = gtk_tree_view_get_model (tree view (m))
			def item = get item (gtk tree model, path[])

			original selected item (m) = selected item (m)
			synchronizing selection (m) = true
			set selection (m, item)
			synchronizing selection (m) = false
		end
		gtk_tree_path_free (path[])

	end

	return handle mouse down (super (m), e)

end
//[cf]
//[of]:handle popup (event)
public func handle popup (m: tree box, e:popup event)

	def processed = handle popup (super (m), e)
	
	if not nil (original selected item (m)) && 	original selected item (m) <> selected item (m)
		synchronizing selection (m) = true
		set selection (m, original selected item (m))
		original selected item (m) = nil
		synchronizing selection (m) = false
	end

	return processed

end
//[cf]
//[cf]
//[of]:private
//[c]Events from tree model
//[of]:text changed
func text changed (m: tree box, item: tree item)

	def iter: local GtkTreeIter
	stamp (iter) = 0
	user_data (iter) = item
	
	def gtk tree model = gtk_tree_view_get_model (tree view (m))
	def path = get path (gtk tree model, item)
	gtk_tree_model_row_changed (gtk tree model, path, iter)
	gtk_tree_path_free (path)

end
//[cf]
//[of]:has children changed
func has children changed (m: tree box, item: tree item)

	def iter: local GtkTreeIter
	stamp (iter) = 0

⌨️ 快捷键说明

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