diff --git a/area.go b/area.go index 11ab272..3c7ff07 100644 --- a/area.go +++ b/area.go @@ -346,7 +346,7 @@ func (a *Area) setRect(x int, y int, width int, height int, rr *[]resizerequest) }) } -func (a *Area) preferredSize() (width int, height int) { +func (a *Area) preferredSize() (width int, height int, yoff int) { return a.sysData.preferredSize() } diff --git a/button.go b/button.go index 7f15d25..56d9c67 100644 --- a/button.go +++ b/button.go @@ -75,6 +75,6 @@ func (b *Button) setRect(x int, y int, width int, height int, rr *[]resizereques }) } -func (b *Button) preferredSize() (width int, height int) { +func (b *Button) preferredSize() (width int, height int, yoff int) { return b.sysData.preferredSize() } diff --git a/checkbox.go b/checkbox.go index 0bae487..71c2b77 100644 --- a/checkbox.go +++ b/checkbox.go @@ -80,6 +80,6 @@ func (c *Checkbox) setRect(x int, y int, width int, height int, rr *[]resizerequ }) } -func (c *Checkbox) preferredSize() (width int, height int) { +func (c *Checkbox) preferredSize() (width int, height int, yoff int) { return c.sysData.preferredSize() } diff --git a/combobox.go b/combobox.go index 83b58b7..5fa391f 100644 --- a/combobox.go +++ b/combobox.go @@ -157,6 +157,6 @@ func (c *Combobox) setRect(x int, y int, width int, height int, rr *[]resizerequ }) } -func (c *Combobox) preferredSize() (width int, height int) { +func (c *Combobox) preferredSize() (width int, height int, yoff int) { return c.sysData.preferredSize() } diff --git a/control.go b/control.go index 90ea014..5cf9359 100644 --- a/control.go +++ b/control.go @@ -6,5 +6,5 @@ package ui type Control interface { make(window *sysData) error setRect(x int, y int, width int, height int, rr *[]resizerequest) - preferredSize() (width int, height int) + preferredSize() (width int, height int, yoff int) } diff --git a/grid.go b/grid.go index ca2d5b9..087b333 100644 --- a/grid.go +++ b/grid.go @@ -21,7 +21,7 @@ type Grid struct { controls [][]Control filling [][]bool stretchyrow, stretchycol int - widths, heights [][]int // caches to avoid reallocating each time + widths, heights, yoff [][]int // caches to avoid reallocating each time rowheights, colwidths []int } @@ -42,12 +42,14 @@ func NewGrid(nPerRow int, controls ...Control) *Grid { cf := make([][]bool, nRows) cw := make([][]int, nRows) ch := make([][]int, nRows) + cyoff := make([][]int, nRows) i := 0 for row := 0; row < nRows; row++ { cc[row] = make([]Control, nPerRow) cf[row] = make([]bool, nPerRow) cw[row] = make([]int, nPerRow) ch[row] = make([]int, nPerRow) + cyoff[row] = make([]int, nPerRow) for x := 0; x < nPerRow; x++ { cc[row][x] = controls[i] i++ @@ -60,6 +62,7 @@ func NewGrid(nPerRow int, controls ...Control) *Grid { stretchycol: -1, widths: cw, heights: ch, + yoff: cyoff, rowheights: make([]int, nRows), colwidths: make([]int, nPerRow), } @@ -142,11 +145,12 @@ func (g *Grid) setRect(x int, y int, width int, height int, rr *[]resizerequest) // 2) get preferred sizes; compute row/column sizes for row, xcol := range g.controls { for col, c := range xcol { - w, h := c.preferredSize() + w, h, yoff := c.preferredSize() g.widths[row][col] = w g.heights[row][col] = h g.rowheights[row] = max(g.rowheights[row], h) g.colwidths[col] = max(g.colwidths[col], w) + g.yoff[row][col] = yoff } } // 3) handle the stretchy control @@ -174,7 +178,7 @@ func (g *Grid) setRect(x int, y int, width int, height int, rr *[]resizerequest) w = g.colwidths[col] h = g.rowheights[row] } - c.setRect(x, y, w, h, rr) + c.setRect(x, y + g.yoff[row][col], w, h - g.yoff[row][col], rr) x += g.colwidths[col] } x = startx @@ -184,7 +188,7 @@ func (g *Grid) setRect(x int, y int, width int, height int, rr *[]resizerequest) } // filling and stretchy are ignored for preferred size calculation -func (g *Grid) preferredSize() (width int, height int) { +func (g *Grid) preferredSize() (width int, height int, yoff int) { max := func(a int, b int) int { if a > b { return a @@ -202,7 +206,8 @@ func (g *Grid) preferredSize() (width int, height int) { // 2) get preferred sizes; compute row/column sizes for row, xcol := range g.controls { for col, c := range xcol { - w, h := c.preferredSize() + // ignore yoff for preferred size calculations + w, h, _ := c.preferredSize() g.widths[row][col] = w g.heights[row][col] = h g.rowheights[row] = max(g.rowheights[row], h) @@ -216,5 +221,7 @@ func (g *Grid) preferredSize() (width int, height int) { for _, h := range g.rowheights { height += h } - return width, height + + // yoff is always zero for grids + return width, height, 0 } diff --git a/label.go b/label.go index dfb6cb1..509c980 100644 --- a/label.go +++ b/label.go @@ -84,6 +84,6 @@ func (l *Label) setRect(x int, y int, width int, height int, rr *[]resizerequest }) } -func (l *Label) preferredSize() (width int, height int) { +func (l *Label) preferredSize() (width int, height int, yoff int) { return l.sysData.preferredSize() } diff --git a/lineedit.go b/lineedit.go index 17d0791..26fbaa1 100644 --- a/lineedit.go +++ b/lineedit.go @@ -78,6 +78,6 @@ func (l *LineEdit) setRect(x int, y int, width int, height int, rr *[]resizerequ }) } -func (l *LineEdit) preferredSize() (width int, height int) { +func (l *LineEdit) preferredSize() (width int, height int, yoff int) { return l.sysData.preferredSize() } diff --git a/listbox.go b/listbox.go index 6c8b149..dc4cb70 100644 --- a/listbox.go +++ b/listbox.go @@ -160,6 +160,6 @@ func (l *Listbox) setRect(x int, y int, width int, height int, rr *[]resizereque }) } -func (l *Listbox) preferredSize() (width int, height int) { +func (l *Listbox) preferredSize() (width int, height int, yoff int) { return l.sysData.preferredSize() } diff --git a/prefsize_unix.go b/prefsize_unix.go index 7aecdab..68ea589 100644 --- a/prefsize_unix.go +++ b/prefsize_unix.go @@ -12,11 +12,13 @@ package ui // There is a warning about height-for-width controls, but in my tests this isn't an issue. // For Areas, we manually save the Area size and use that, just to be safe. -func (s *sysData) preferredSize() (width int, height int) { +// We don't need to worry about y-offset because label alignment is "vertically center", which GtkLabel does for us. + +func (s *sysData) preferredSize() (width int, height int, yoff int) { if s.ctype == c_area { - return s.areawidth, s.areaheight + return s.areawidth, s.areaheight, 0 } _, _, width, height = gtk_widget_get_preferred_size(s.widget) - return width, height + return width, height, 0 } diff --git a/progressbar.go b/progressbar.go index 3e954cd..212620d 100644 --- a/progressbar.go +++ b/progressbar.go @@ -66,6 +66,6 @@ func (p *ProgressBar) setRect(x int, y int, width int, height int, rr *[]resizer }) } -func (p *ProgressBar) preferredSize() (width int, height int) { +func (p *ProgressBar) preferredSize() (width int, height int, yoff int) { return p.sysData.preferredSize() } diff --git a/stack.go b/stack.go index bbc78ec..17df63a 100644 --- a/stack.go +++ b/stack.go @@ -25,7 +25,7 @@ type Stack struct { orientation orientation controls []Control stretchy []bool - width, height []int // caches to avoid reallocating these each time + width, height, yoff []int // caches to avoid reallocating these each time } func newStack(o orientation, controls ...Control) *Stack { @@ -35,6 +35,7 @@ func newStack(o orientation, controls ...Control) *Stack { stretchy: make([]bool, len(controls)), width: make([]int, len(controls)), height: make([]int, len(controls)), + yoff: make([]int, len(controls)), } } @@ -92,7 +93,8 @@ func (s *Stack) setRect(x int, y int, width int, height int, rr *[]resizerequest nStretchy++ continue } - w, h := c.preferredSize() + w, h, yoff := c.preferredSize() + s.yoff[i] = yoff if s.orientation == horizontal { // all controls have same height s.width[i] = w s.height[i] = height @@ -120,7 +122,7 @@ func (s *Stack) setRect(x int, y int, width int, height int, rr *[]resizerequest } // 3) now actually place controls for i, c := range s.controls { - c.setRect(x, y, s.width[i], s.height[i], rr) + c.setRect(x, y + s.yoff[i], s.width[i], s.height[i] - s.yoff[i], rr) if s.orientation == horizontal { x += s.width[i] } else { @@ -131,7 +133,7 @@ func (s *Stack) setRect(x int, y int, width int, height int, rr *[]resizerequest } // The preferred size of a Stack is the sum of the preferred sizes of non-stretchy controls + (the number of stretchy controls * the largest preferred size among all stretchy controls). -func (s *Stack) preferredSize() (width int, height int) { +func (s *Stack) preferredSize() (width int, height int, yoff int) { max := func(a int, b int) int { if a > b { return a @@ -143,10 +145,11 @@ func (s *Stack) preferredSize() (width int, height int) { var maxswid, maxsht int if len(s.controls) == 0 { // no controls, so return emptiness - return 0, 0 + return 0, 0, 0 } for i, c := range s.controls { - w, h := c.preferredSize() + // ignore yoff for preferred size calculations + w, h, _ := c.preferredSize() if s.stretchy[i] { nStretchy++ maxswid = max(maxswid, w) @@ -169,6 +172,9 @@ func (s *Stack) preferredSize() (width int, height int) { } else { height += nStretchy * maxsht } + + // yoff is always zero for stacks + yoff = 0 return } diff --git a/sysdata.go b/sysdata.go index dec0e27..5a97514 100644 --- a/sysdata.go +++ b/sysdata.go @@ -36,7 +36,7 @@ var _xSysData interface { selectedTexts() []string setWindowSize(int, int) error delete(int) - preferredSize() (int, int) + preferredSize() (int, int, int) setProgress(int) len() int setAreaSize(int, int)