From 417ed1f72778721a0122932612bbeeba22c20d1e Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Wed, 26 Feb 2014 07:01:02 -0500 Subject: [PATCH] Added Grid.SetStretchy to allow one control in a Grid to fill the parent Control's space, even when resizing. --- grid.go | 40 ++++++++++++++++++++++++++++++++++++++-- main_test.go | 1 + 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/grid.go b/grid.go index 3cb09a4..63b7b52 100644 --- a/grid.go +++ b/grid.go @@ -11,6 +11,8 @@ import ( // 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. +// One Control can be marked as "stretchy": when the Window containing the Grid is resized, the cell containing that Control resizes to take any remaining space; its row and column are adjusted accordingly (so other filling controls in the same row and column will fill to the new height and width, respectively). +// A stretchy Control implicitly fills its cell. // 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. // TODO differnet row/column control alignment; stretchy controls or other resizing options @@ -19,6 +21,7 @@ type Grid struct { created bool controls [][]Control filling [][]bool + stretchyrow, stretchycol int widths, heights [][]int // caches to avoid reallocating each time rowheights, colwidths []int } @@ -54,6 +57,8 @@ func NewGrid(nPerRow int, controls ...Control) *Grid { return &Grid{ controls: cc, filling: cf, + stretchyrow: -1, + stretchycol: -1, widths: cw, heights: ch, rowheights: make([]int, nRows), @@ -61,7 +66,7 @@ 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. +// 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() @@ -73,6 +78,21 @@ func (g *Grid) SetFilling(row int, column int) { g.filling[row][column] = true } +// SetStretchy sets the given Control of the Grid as stretchy. +// Stretchy implies filling. +// This function cannot be called after the Window that contains the Grid has been created. +func (g *Grid) SetStretchy(row int, column int) { + g.lock.Lock() + defer g.lock.Unlock() + + if g.created { + panic("Grid.SetFilling() called after window create") // TODO + } + g.stretchyrow = row + g.stretchycol = column + g.filling[row][column] = true +} + func (g *Grid) make(window *sysData) error { g.lock.Lock() defer g.lock.Unlock() @@ -120,7 +140,22 @@ func (g *Grid) setRect(x int, y int, width int, height int) error { g.colwidths[col] = max(g.colwidths[col], w) } } - // 3) draw + // 3) handle the stretchy control + if g.stretchyrow != -1 && g.stretchycol != -1 { // TODO internal error if one is -1 but not both + for i, w := range g.colwidths { + if i != g.stretchycol { + width -= w + } + } + for i, h := range g.rowheights { + if i != g.stretchyrow { + height -= h + } + } + g.colwidths[g.stretchycol] = width + g.rowheights[g.stretchyrow] = height + } + // 4) draw startx := x for row, xcol := range g.controls { for col, c := range xcol { @@ -142,6 +177,7 @@ func (g *Grid) setRect(x int, y int, width int, height int) error { return nil } +// filling and stretchy are ignored for preferred size calculation func (g *Grid) preferredSize() (width int, height int, err error) { g.lock.Lock() defer g.lock.Unlock() diff --git a/main_test.go b/main_test.go index ae3e425..163024e 100644 --- a/main_test.go +++ b/main_test.go @@ -21,6 +21,7 @@ func gridWindow() (*Window, error) { Space(), l11, b12, l20, c21, l22) g.SetFilling(1, 2) + g.SetStretchy(1, 1) return w, w.Open(g) }