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

📄 grid-box.zc

📁 实现树形结构
💻 ZC
字号:
//[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"
//[c]
import "graphics/geometry"
import "user/box"
import "user/blank-box"
//[c]
import "glib/glib"
import "glib/glib-object"
import "gtk/gtk"
//[cf]
//[of]:structures
//[c]
//[c]	Grid Cell
//[c]	A cell describes the position used by a box in a grid box.
//[c]
public struct grid cell

	// next chains all grid cells for a grid.
	next: grid cell

	// the box that occupy this cell
	box: box
	
	// the next attibutes define the rectangle in grid units
	left: int
	top: int
	width: int
	height: int

end
//[c]
//[c]	Grid Box Band
//[c]	A band defines a constraint for a single row or a 
//[c]	single column in the grid.
//[c]
struct grid box band

	// stretch 
	// the stretch attribute is set at initialization time
	// 0 = don't stretch
	// 1 = stretch (catch a part of the extra length)
	stretch: int
	
end
//[c]
//[c]	List of Bands
//[c]
typedef list of bands = [] local grid box band
//[c]
//[c]	Grid Box
//[c]
public struct grid box : local box
	
	elements: grid cell		// cells
	hband: list of bands	// horizontal bands
	vband: list of bands	// vertical bands
	
end

public struct grid box class : local box class
end

private equ table (m: grid box) = widget (m) : GtkTable
public equ class (m: grid box) = class (super (m)) : grid box class

//[cf]
//[c]
//[of]:grid box
//[of]:instance creation
//[of]:new grid box (parent box)
public func new grid box (parent: box)

	def b = allocate memory (sizeof local grid box):grid box
	initialize (b, parent)
	return b

end
//[cf]
//[cf]
//[of]:accessing
//[of]:configure (h, v, grid cell)
//[c]Configures the grid
//[c]
//[c]	horizontal and vertical are int arrays terminated by -1.
//[c]	- 0  means non stretchable columns
//[c]	- 1  means stretchable columns
//[c]	- -1 is the end of the list
//[c]
//[c]
func len (m: [] int)

	def index = 0
	while m[index]<>-1; index+=1; end
	return index

end
//[c]
public func configure (m: grid box, h: [] int, v: [] int, e: grid cell)

	def columns = len (h)
	def rows = len (v)
	
	gtk_table_resize (table (m), rows, columns)

	hband (m) = new bands (columns)
	vband (m) = new bands (rows)

	def band = hband (m)
	repeat
		def c = h[]
		if c==-1; break; end
		band[].stretch = c
		++h
		++band
	end

	band = vband (m)
	repeat
		def c = v[]
		if c==-1; break; end
		band[].stretch = c
		++v
		++band
	end

	elements (m) = e

end
//[cf]
//[of]:configure (h, v, grid cell, extern, intern)
//[c]Configures the grid with margins
//[c]
//[c]	horizontal and vertical are int arrays terminated by -1.
//[c]	- 0  means non stretchable columns
//[c]	- 1  means stretchable columns
//[c]	- -1 is the end of the list
//[c]
public func configure (
		m: grid box, 
		h: [] int, 
		v: [] int, 
		e: grid cell,
		extern: int,
		intern: int)

	def offset =  (extern == 0) -> 0, 1

	def columns = 2 * (len (h) + offset) - 1
	def rows = 2 * (len (v) + offset) - 1
	hband (m) = new bands (columns)
	vband (m) = new bands (rows)

	each (e) ? el
		left (el) = 2 * left (el) + offset
		width (el) = 2 * width (el) - 1
		top (el) = 2 * top (el) + offset
		height (el) = 2 * height (el) - 1
	end
	
	def band = hband (m)
	def sep = (offset == 1)
	repeat
		def c = h++[]
		if c==-1; break; end
		if sep
			band[].stretch = 0
			++band
		end
		sep = true
		band[].stretch = c
		++band
	end
	if offset == 1
		band[].stretch = 0
	end

	band = vband (m)
	sep = (offset == 1)
	repeat
		def c = v++[]
		if c==-1; break; end
		if sep
			band[].stretch = 0
			++band
		end
		sep = true
		band[].stretch = c
		++band
	end
	if offset == 1
		band[].stretch = 0
	end

	// external margins
	if extern > 0
		e = new grid cell (e, new blank box (m, extern), 0, 0, columns, 1)
		e = new grid cell (e, new blank box (m, extern), 0, rows-1, columns, 1)
		e = new grid cell (e, new blank box (m, extern), 0, 1, 1, rows-2)
		e = new grid cell (e, new blank box (m, extern), columns-1, 1, 1, rows-2)
	end

	// create internal margins
	def y = offset
	def wg = columns - offset
	def hg = rows - offset
	while y < hg
		def x = offset
		while x < wg
			def r := rectangle (x, y, 0, 1)
			
			while x < wg
				++ w (r)
				// interesect with a cell
				if intersects any (e, r)
					-- w (r)
					break
				end
				++ x
			end
			
			if w (r) > 0
				e = new grid cell (e, new blank box (m, intern), x (r), y (r), w (r), h (r))
			end
			
			++x
		end
		++y
	end
	
	elements (m) = e

end
//[cf]
//[cf]
//[c]
//[of]:restricted
//[of]:grid box class
public func grid box class

	def c = the grid box class
	if ~ initialized
		initialized = true
		c . copy (box class)
		c . mem size = sizeof local grid box class
		c . release = ^actual release (grid box)
		c . activate = ^actual activate (grid box)
	end
	return c

end

private def initialized = false
private def the grid box class : local grid box class
//[cf]
//[of]:initialize (parent)
public func initialize (m: grid box, parent: box)

	def t = gtk_table_new (1, 1, FALSE)
	widget (m) = t
	gtk_widget_show (t)

	initialize (super (m), parent)
	class (m) = grid box class
	elements (m) = nil
	hband (m) = nil
	vband (m) = nil

end
//[cf]
//[c]
//[of]:actual release
//[c]
public func actual release (m: grid box)

	free memory (hband (m):mem)
	free memory (vband (m):mem)
	
	def cell = elements (m)
	while not nil (cell)
		def next = next (cell)
		delete (cell)
		cell = next
	end
	
	actual release (super (m))
	
end
//[cf]
//[of]:actual activate
//[c]
public func actual activate (m: grid box)

	def e = elements (m)
	each (e) ? c
		activate (box (c))
	
		def hflags = GTK_FILL:int
		def left = left (c)
		//def width = width (c)
		if stretch (hband (m) [left]) == 1
			hflags |= GTK_EXPAND:int
		end
		
		def vflags = GTK_FILL:int
		def top = top (c)
		//def width = width (c)
		if stretch (vband (m) [top]) == 1
			vflags |= GTK_EXPAND:int
		end
		
		gtk_table_attach (
			table (m),
			widget (box (c)),
			left, left + width (c),
			top, top + height (c),
			hflags:GtkAttachOptions,
			vflags:GtkAttachOptions,
			0,
			0)
	end

end
//[cf]
//[cf]
//[of]:private
//[of]:each element
private equ each element (m: grid box)

	def e = elements (m)
	while not nil (e)
		yield (e)
		e = next (e)
	end

end
//[cf]
//[c]
//[of]:new bands (int)
private equ new bands(n: int) = 
	allocate memory (sizeof local grid box band * n:dword):list of bands
//[cf]
//[c]
//[cf]
//[cf]
//[of]:grid cell
//[of]:- Description -
//[c]A grid cell describes the location and constraints of
//[c]a widget in the grid box container
//[cf]
//[c]
//[of]:instance creation
//[of]:new grid cell (next, box, left, top, width, height)
//[c]
public func new grid cell (
		next: grid cell, 
		box: box, 
		left: int,
		top: int,
		width: int,
		height: int)

	def c = allocate memory (sizeof local grid cell): grid cell
	initialize (c, next, box, left, top, width, height)
	return c

end
//[cf]
//[of]:delete (m)
//[c]
public func delete (cell: grid cell)
	free memory (cell)
end
//[cf]
//[cf]
//[of]:initialize - release
//[of]:initialize (m, ...)
//[c]Initializes a cell
//[c]
public func initialize (
		m: grid cell, 
		next: grid cell, 
		box: box, 
		left: int,
		top: int,
		width: int,
		height: int)
		
	next (m) = next
	box (m) = box
	left (m) = left
	top (m) = top
	width (m) = width
	height (m) = height

end
//[cf]
//[cf]
//[c]
//[of]:private
//[of]:each (m)
//[c]Enumerates all cells (given the first cell of a linked list)
//[c]
private equ each (cell: grid cell)

	def e = cell
	while not nil (e)
		yield (e)
		e = next (e)
	end

end
//[cf]
//[of]:intersects (m, rectangle)
//[c]Returns true if the cell intersects with r
//[c]
private equ intersects (cell: grid cell, r: rectangle) = 

	overlaps (
		r, 
		rectangle (
			left (cell), 
			top (cell), 
			width (cell), 
			height (cell)))

//[cf]
//[of]:intersects any (m, rectangle)
//[c]Returns true if any of the cells instersects with the rectangle
//[c]
private func intersects any (cell: grid cell, r: rectangle)

	each (cell) ? e
		if intersects (e, r)
			return true
		end
	end
	
	return false

end
//[cf]
//[cf]
//[c]
//[cf]

⌨️ 快捷键说明

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