Added a way to let Controls in a Grid be sized to fill their cells.
This commit is contained in:
parent
5eed0db0cd
commit
e1677a8941
28
grid.go
28
grid.go
|
@ -7,15 +7,18 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// A Grid arranges Controls in a two-dimensional grid.
|
// A Grid arranges Controls in a two-dimensional grid.
|
||||||
// All Controls in a Grid maintain their preferred sizes.
|
|
||||||
// The height of each row and the width of each column is the maximum preferred height and width (respectively) of all the controls in that row or column (respectively).
|
// The height of each row and the width of each column is the maximum preferred height and width (respectively) of all the controls in that row or column (respectively).
|
||||||
// Controls are aligned to the top left corner of each cell.
|
// Controls are aligned to the top left corner of each cell.
|
||||||
|
// All Controls in a Grid maintain their preferred sizes by default; if a Control is marked as being "filling", it will be sized to fill its cell.
|
||||||
|
// Even if a Control is marked as filling, its preferred size is used to calculate cell sizes.
|
||||||
|
// All cooridnates in a Grid are given in (row,column) form with (0,0) being the top-left cell.
|
||||||
// Unlike other UI toolkit Grids, this Grid does not (yet? TODO) allow Controls to span multiple rows or columns.
|
// Unlike other UI toolkit Grids, this Grid does not (yet? TODO) allow Controls to span multiple rows or columns.
|
||||||
// TODO differnet row/column control alignment; stretchy controls or other resizing options
|
// TODO differnet row/column control alignment; stretchy controls or other resizing options
|
||||||
type Grid struct {
|
type Grid struct {
|
||||||
lock sync.Mutex
|
lock sync.Mutex
|
||||||
created bool
|
created bool
|
||||||
controls [][]Control
|
controls [][]Control
|
||||||
|
filling [][]bool
|
||||||
widths, heights [][]int // caches to avoid reallocating each time
|
widths, heights [][]int // caches to avoid reallocating each time
|
||||||
rowheights, colwidths []int
|
rowheights, colwidths []int
|
||||||
}
|
}
|
||||||
|
@ -34,11 +37,13 @@ func NewGrid(nPerRow int, controls ...Control) *Grid {
|
||||||
}
|
}
|
||||||
nRows := len(controls) / nPerRow
|
nRows := len(controls) / nPerRow
|
||||||
cc := make([][]Control, nRows)
|
cc := make([][]Control, nRows)
|
||||||
|
cf := make([][]bool, nRows)
|
||||||
cw := make([][]int, nRows)
|
cw := make([][]int, nRows)
|
||||||
ch := make([][]int, nRows)
|
ch := make([][]int, nRows)
|
||||||
i := 0
|
i := 0
|
||||||
for row := 0; row < nRows; row++ {
|
for row := 0; row < nRows; row++ {
|
||||||
cc[row] = make([]Control, nPerRow)
|
cc[row] = make([]Control, nPerRow)
|
||||||
|
cf[row] = make([]bool, nPerRow)
|
||||||
cw[row] = make([]int, nPerRow)
|
cw[row] = make([]int, nPerRow)
|
||||||
ch[row] = make([]int, nPerRow)
|
ch[row] = make([]int, nPerRow)
|
||||||
for x := 0; x < nPerRow; x++ {
|
for x := 0; x < nPerRow; x++ {
|
||||||
|
@ -48,6 +53,7 @@ func NewGrid(nPerRow int, controls ...Control) *Grid {
|
||||||
}
|
}
|
||||||
return &Grid{
|
return &Grid{
|
||||||
controls: cc,
|
controls: cc,
|
||||||
|
filling: cf,
|
||||||
widths: cw,
|
widths: cw,
|
||||||
heights: ch,
|
heights: ch,
|
||||||
rowheights: make([]int, nRows),
|
rowheights: make([]int, nRows),
|
||||||
|
@ -55,6 +61,18 @@ func NewGrid(nPerRow int, controls ...Control) *Grid {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetFilling sets the given control of the Grid as filling its cell instead of staying at its preferred size.
|
||||||
|
// This function cannot be called after the Window that contains the Grid has been created.
|
||||||
|
func (g *Grid) SetFilling(row int, column int) {
|
||||||
|
g.lock.Lock()
|
||||||
|
defer g.lock.Unlock()
|
||||||
|
|
||||||
|
if g.created {
|
||||||
|
panic("Grid.SetFilling() called after window create") // TODO
|
||||||
|
}
|
||||||
|
g.filling[row][column] = true
|
||||||
|
}
|
||||||
|
|
||||||
func (g *Grid) make(window *sysData) error {
|
func (g *Grid) make(window *sysData) error {
|
||||||
g.lock.Lock()
|
g.lock.Lock()
|
||||||
defer g.lock.Unlock()
|
defer g.lock.Unlock()
|
||||||
|
@ -106,7 +124,13 @@ func (g *Grid) setRect(x int, y int, width int, height int) error {
|
||||||
startx := x
|
startx := x
|
||||||
for row, xcol := range g.controls {
|
for row, xcol := range g.controls {
|
||||||
for col, c := range xcol {
|
for col, c := range xcol {
|
||||||
err := c.setRect(x, y, g.widths[row][col], g.heights[row][col])
|
w := g.widths[row][col]
|
||||||
|
h := g.heights[row][col]
|
||||||
|
if g.filling[row][col] {
|
||||||
|
w = g.colwidths[col]
|
||||||
|
h = g.rowheights[row]
|
||||||
|
}
|
||||||
|
err := c.setRect(x, y, w, h)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error setting size of control (%d,%d) in Grid.setRect(): %v", row, col, err)
|
return fmt.Errorf("error setting size of control (%d,%d) in Grid.setRect(): %v", row, col, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ func gridWindow() (*Window, error) {
|
||||||
b00, b01, b02,
|
b00, b01, b02,
|
||||||
Space(), l11, b12,
|
Space(), l11, b12,
|
||||||
l20, c21, l22)
|
l20, c21, l22)
|
||||||
|
g.SetFilling(1, 2)
|
||||||
return w, w.Open(g)
|
return w, w.Open(g)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue