📄 grid-box.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 + -