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

📄 list-box.zc

📁 实现树形结构
💻 ZC
字号:
//[of]:description
//[c]A simple list-box
//[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 "base/memory"
import "text/vector-of-strings"
import "text/string"
import "text/string-buffer"
//[c]
import "graphics/geometry"
import "graphics/graphics"
import "user/box"
//[c]
import "glib/glib"
import "glib/glib-object"
import "gdk/gdk"
import "gtk/gtk"
//[cf]
//[c]
//[of]:list box
//[of]:type
public struct list box : local box

	private
		number of items : dword
		tree view : GtkTreeView
		indices : [] local GtkTreeIter
		list store : GtkListStore

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

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

end
//[cf]
//[cf]
//[of]:index
//[of]:index
//[c]Returns the index of the currently selected item, 
//[c]if any, in the list box of a list box.
//[c]
public func index (m: list box)

	if not nil (indices (m))
		def iter : local GtkTreeIter
		def model : [1] GtkTreeModel
		
		def sel = gtk selection (m)
		gtk_tree_selection_get_selected (sel, model, iter)
	
		def i = 0
		def n = number of items (m) : int
		while i < n
			if user_data (iter) == user_data (indices (m) [i])
				return i
			end
			++i
		end
	end	
	return -1

end
//[cf]
//[of]:set index (index)
//[c]Specifies the zero-based index of the string to select. 
//[c]If the index parameter is -1, any current selection in the list 
//[c]is removed.
//[c]
public func set index (m: list box, index: int)

	def sel = gtk selection (m)
	if index == -1
		gtk_tree_selection_unselect_all (sel)
	else
		def t := temp string buffer
		t << index
		def path = gtk_tree_path_new_from_string (as string (t))
		gtk_tree_selection_select_path (sel, path)
		gtk_tree_view_set_cursor (tree view (m), path, nil, FALSE)
		gtk_tree_path_free (path)
		release (t)
	end

end
//[cf]
//[cf]
//[of]:list
//[of]:size of list
//[c]Returns the number of items in the list
//[c]
public func size of list (m: list box)
	return number of items (m)
end
//[cf]
//[of]:set list (vector of strings, index)
public func set list (m: list box, list: vector of strings, index: int)

	def cols : [1] GType
	cols [] = G_TYPE_STRING
	def store = gtk_list_store_newv (1, cols)
	list store (m) = store
	
	def n = size (list)
	number of items (m) = n

	if not nil (indices (m))
		free memory (indices (m))
	end
	indices (m) = allocate memory (sizeof local GtkTreeIter * n) : [] local GtkTreeIter

	def i = 0
	each (list) ? s
		def iter = indices (m) [i++]
		gtk_list_store_append (store, iter)
		gtk_list_store_set_1 (store, iter, 0, to UTF8 (s), -1)
	end

	gtk_tree_view_set_model (tree view (m), store:GtkTreeModel)
	
	set index (m, index)

end
//[cf]
//[of]:set list (vector of strings)
public func set list (m: list box, list: vector of strings)
	set list (m, list, 0)
end
//[cf]
//[of]:remove (index)
//[c]
public func remove (m: list box, index: int)

	def old index = index (m)
	def new index = old index
	def n = size of list (m) : int
	if n == 0
		new index = -1
	elsif new index == n - 1
		-- new index
	end
	if old index == index
		old index = -1
	end

	// remove item
	def iter = indices (m) [index]
	gtk_list_store_remove (list store (m), iter)
	
	def dst = indices (m) + index
	def src = dst + 1
	def size = (sizeof local GtkTreeIter) * (number of items (m) - index - 1)
	copy (dst : mem, src : mem, size)
	-- number of items (m)

	if old index <> new index
		set index (m, new index)
	end
	invalidate min size (m)
	
end
//[cf]
//[cf]
//[c]
//[of]:restricted
//[of]:initialize (parent)
public func initialize (m: list box, parent: box)

	// Create the tree view
	def p = gtk_tree_view_new
	tree view (m) = p : GtkTreeView
	def renderer = gtk_cell_renderer_text_new
	def column = gtk_tree_view_column_new
	gtk_tree_view_column_pack_start (column, renderer, TRUE)
	gtk_tree_view_column_add_attribute (column, renderer, "text", 0)
	gtk_tree_view_append_column (p: GtkTreeView, column)
	gtk_tree_view_set_headers_visible (p: GtkTreeView, FALSE)
	gtk_widget_show (p)
	
	// 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)

	// ... so much code for a so simple listbox

	g_signal_connect(
		gtk selection (m), 
		"changed", 
		^changed (GtkTreeSelection, list box): GCallback,
		m)
		
	g_signal_connect(
		p,
		"button-press-event",
		^button press 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)

	initialize (super (m), parent)
	class (m) = list box class
	indices (m) = nil

end
//[cf]
//[c]
//[of]:actual release
//[c]Releases any allocated resource
//[c]
public func actual release (m: list box)

	def items = indices (m)
	if not nil (items)
		free memory (items)
	end

	actual release (super (m))

end
//[cf]
//[c]
//[cf]
//[of]:private
//[of]:gtk selection
private equ gtk selection (m: list box) = 
	gtk_tree_view_get_selection (tree view (m))
//[cf]
//[of]:class
private equ class (m: list box) = 
	class (super (m)) : list box class
//[cf]
//[c]
//[of]:changed (tree selection, list box)
//[c]
private func changed (w: GtkTreeSelection, m: list box)
	on index changed (m)
end
//[cf]
//[cf]
//[cf]
//[of]:list box class
//[of]:type
public struct list box class : local box class
end
//[cf]
//[of]:list box class
public func list box class

	def c = the list box class
	if ~ initialized
		initialized = true
		c . copy (box class)
		c . mem size = sizeof local list box class
		c . release = ^actual release (list box)
		c . accept focus = ^yes (box)
	end
	return c

end

private def initialized = false
private def the list box class: local list box class
//[cf]
//[cf]

⌨️ 快捷键说明

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