diff --git a/area.go b/area.go index 93f319ea..b63bfe33 100644 --- a/area.go +++ b/area.go @@ -121,8 +121,14 @@ func (a *Area) make(window *sysData) error { return nil } -func (a *Area) setRect(x int, y int, width int, height int, winheight int) error { - return a.sysData.setRect(x, y, width, height, winheight) +func (a *Area) setRect(x int, y int, width int, height int) []resizerequest { + return []resizerequest{resizerequest{ + sysData: a.sysData, + x: x, + y: y, + width: width, + height: height, + }} } func (a *Area) preferredSize() (width int, height int) { diff --git a/button.go b/button.go index 8815d213..b5e02a68 100644 --- a/button.go +++ b/button.go @@ -61,8 +61,14 @@ func (b *Button) make(window *sysData) error { return nil } -func (b *Button) setRect(x int, y int, width int, height int, winheight int) error { - return b.sysData.setRect(x, y, width, height, winheight) +func (b *Button) setRect(x int, y int, width int, height int) []resizerequest { + return []resizerequest{resizerequest{ + sysData: b.sysData, + x: x, + y: y, + width: width, + height: height, + }} } func (b *Button) preferredSize() (width int, height int) { diff --git a/callbacks_unix.go b/callbacks_unix.go index 85eec5a3..68fb0efa 100644 --- a/callbacks_unix.go +++ b/callbacks_unix.go @@ -42,9 +42,12 @@ func our_window_configure_event_callback(widget *C.GtkWidget, event *C.GdkEvent, if s.container != nil && s.resize != nil { // wait for init width, height := gtk_window_get_size(s.widget) // top-left is (0,0) so no need for winheight - err := s.resize(0, 0, width, height, 0) - if err != nil { - panic("child resize failed: " + err.Error()) + resizeList := s.resize(0, 0, width, height) + for _, s := range resizeList { + err := s.sysData.setRect(s.x, s.y, s.width, s.height, 0) + if err != nil { + panic("child resize failed: " + err.Error()) + } } } // returning false indicates that we continue processing events related to configure-event; if we choose not to, then after some controls have been added, the layout fails completely and everything stays in the starting position/size diff --git a/checkbox.go b/checkbox.go index 65e25c48..2ca81cde 100644 --- a/checkbox.go +++ b/checkbox.go @@ -68,8 +68,14 @@ func (c *Checkbox) make(window *sysData) error { return nil } -func (c *Checkbox) setRect(x int, y int, width int, height int, winheight int) error { - return c.sysData.setRect(x, y, width, height, winheight) +func (c *Checkbox) setRect(x int, y int, width int, height int) []resizerequest { + return []resizerequest{resizerequest{ + sysData: c.sysData, + x: x, + y: y, + width: width, + height: height, + }} } func (c *Checkbox) preferredSize() (width int, height int) { diff --git a/combobox.go b/combobox.go index 41960c4e..ae2edfdd 100644 --- a/combobox.go +++ b/combobox.go @@ -143,8 +143,14 @@ func (c *Combobox) make(window *sysData) (err error) { return nil } -func (c *Combobox) setRect(x int, y int, width int, height int, winheight int) error { - return c.sysData.setRect(x, y, width, height, winheight) +func (c *Combobox) setRect(x int, y int, width int, height int) []resizerequest { + return []resizerequest{resizerequest{ + sysData: c.sysData, + x: x, + y: y, + width: width, + height: height, + }} } func (c *Combobox) preferredSize() (width int, height int) { diff --git a/control.go b/control.go index 11d90347..2a44b02d 100644 --- a/control.go +++ b/control.go @@ -9,6 +9,6 @@ import ( // A Control represents an UI control. Note that Control contains unexported members; this has the consequence that you can't build custom controls that interface directly with the system-specific code (fo rinstance, to import an unsupported control), or at least not without some hackery. If you want to make your own controls, embed Area and provide its necessities. type Control interface { make(window *sysData) error - setRect(x int, y int, width int, height int, winheight int) error + setRect(x int, y int, width int, height int) []resizerequest preferredSize() (width int, height int) } diff --git a/delegate_darwin.go b/delegate_darwin.go index e9144537..59999413 100644 --- a/delegate_darwin.go +++ b/delegate_darwin.go @@ -90,9 +90,12 @@ func appDelegate_windowDidResize(self C.id, sel C.SEL, notification C.id) { r := C.objc_msgSend_stret_rect_noargs(wincv, _frame) if sysData.resize != nil { // winheight is used here because (0,0) is the bottom-left corner, not the top-left corner - err := sysData.resize(int(r.x), int(r.y), int(r.width), int(r.height), int(r.height)) - if err != nil { - panic("child resize failed: " + err.Error()) + resizeList := sysData.resize(int(r.x), int(r.y), int(r.width), int(r.height)) + for _, s := range resizeList { + err := s.sysData.setRect(s.x, s.y, s.width, s.height, int(r.height)) + if err != nil { + panic("child resize failed: " + err.Error()) + } } } C.objc_msgSend_noargs(win, _display) // redraw everything; TODO only if resize() was called? diff --git a/grid.go b/grid.go index 309c5db1..064dcabe 100644 --- a/grid.go +++ b/grid.go @@ -120,7 +120,7 @@ func (g *Grid) make(window *sysData) error { return nil } -func (g *Grid) setRect(x int, y int, width int, height int, winheight int) error { +func (g *Grid) setRect(x int, y int, width int, height int) (rr []resizerequest) { max := func(a int, b int) int { if a > b { return a @@ -171,16 +171,13 @@ func (g *Grid) setRect(x int, y int, width int, height int, winheight int) error w = g.colwidths[col] h = g.rowheights[row] } - err := c.setRect(x, y, w, h, winheight) - if err != nil { - return fmt.Errorf("error setting size of control (%d,%d) in Grid.setRect(): %v", row, col, err) - } + rr = append(rr, c.setRect(x, y, w, h)...) x += g.colwidths[col] } x = startx y += g.rowheights[row] } - return nil + return rr } // filling and stretchy are ignored for preferred size calculation diff --git a/label.go b/label.go index 82b8731d..36bdb3f9 100644 --- a/label.go +++ b/label.go @@ -55,8 +55,14 @@ func (l *Label) make(window *sysData) error { return nil } -func (l *Label) setRect(x int, y int, width int, height int, winheight int) error { - return l.sysData.setRect(x, y, width, height, winheight) +func (l *Label) setRect(x int, y int, width int, height int) []resizerequest { + return []resizerequest{resizerequest{ + sysData: l.sysData, + x: x, + y: y, + width: width, + height: height, + }} } func (l *Label) preferredSize() (width int, height int) { diff --git a/lineedit.go b/lineedit.go index 2d89a5cc..71f4529d 100644 --- a/lineedit.go +++ b/lineedit.go @@ -67,8 +67,14 @@ func (l *LineEdit) make(window *sysData) error { return nil } -func (l *LineEdit) setRect(x int, y int, width int, height int, winheight int) error { - return l.sysData.setRect(x, y, width, height, winheight) +func (l *LineEdit) setRect(x int, y int, width int, height int) []resizerequest { + return []resizerequest{resizerequest{ + sysData: l.sysData, + x: x, + y: y, + width: width, + height: height, + }} } func (l *LineEdit) preferredSize() (width int, height int) { diff --git a/listbox.go b/listbox.go index 36064f20..fae3582e 100644 --- a/listbox.go +++ b/listbox.go @@ -144,8 +144,14 @@ func (l *Listbox) make(window *sysData) (err error) { return nil } -func (l *Listbox) setRect(x int, y int, width int, height int, winheight int) error { - return l.sysData.setRect(x, y, width, height, winheight) +func (l *Listbox) setRect(x int, y int, width int, height int) []resizerequest { + return []resizerequest{resizerequest{ + sysData: l.sysData, + x: x, + y: y, + width: width, + height: height, + }} } func (l *Listbox) preferredSize() (width int, height int) { diff --git a/progressbar.go b/progressbar.go index cd4dc989..bbc7f1b6 100644 --- a/progressbar.go +++ b/progressbar.go @@ -55,8 +55,14 @@ func (p *ProgressBar) make(window *sysData) error { return nil } -func (p *ProgressBar) setRect(x int, y int, width int, height int, winheight int) error { - return p.sysData.setRect(x, y, width, height, winheight) +func (p *ProgressBar) setRect(x int, y int, width int, height int) []resizerequest { + return []resizerequest{resizerequest{ + sysData: p.sysData, + x: x, + y: y, + width: width, + height: height, + }} } func (p *ProgressBar) preferredSize() (width int, height int) { diff --git a/stack.go b/stack.go index b37b935a..2820ef72 100644 --- a/stack.go +++ b/stack.go @@ -77,7 +77,7 @@ func (s *Stack) make(window *sysData) error { return nil } -func (s *Stack) setRect(x int, y int, width int, height int, winheight int) error { +func (s *Stack) setRect(x int, y int, width int, height int) (rr []resizerequest) { var stretchywid, stretchyht int if len(s.controls) == 0 { // do nothing if there's nothing to do @@ -120,17 +120,14 @@ func (s *Stack) setRect(x int, y int, width int, height int, winheight int) erro } // 3) now actually place controls for i, c := range s.controls { - err := c.setRect(x, y, s.width[i], s.height[i], winheight) - if err != nil { - return fmt.Errorf("error setting size of control %d in Stack.setRect(): %v", i, err) - } + rr = append(rr, c.setRect(x, y, s.width[i], s.height[i])...) if s.orientation == horizontal { x += s.width[i] } else { y += s.height[i] } } - return nil + return rr } // 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). diff --git a/stdwndclass_windows.go b/stdwndclass_windows.go index 727158d0..54cec7d6 100644 --- a/stdwndclass_windows.go +++ b/stdwndclass_windows.go @@ -53,9 +53,12 @@ func stdWndProc(s *sysData) func(hwnd _HWND, uMsg uint32, wParam _WPARAM, lParam panic("GetClientRect failed: " + err.Error()) } // top-left corner is (0,0) so no need for winheight - err = s.resize(int(r.Left), int(r.Top), int(r.Right), int(r.Bottom), 0) - if err != nil { - panic("child resize failed: " + err.Error()) + resizeList := s.resize(int(r.Left), int(r.Top), int(r.Right), int(r.Bottom)) + for _, s := range resizeList { + err = s.sysData.setRect(s.x, s.y, s.width, s.height, 0) + if err != nil { + panic("child resize failed: " + err.Error()) + } } } return 0 diff --git a/sysdata.go b/sysdata.go index b31a24ec..cdf6a145 100644 --- a/sysdata.go +++ b/sysdata.go @@ -17,7 +17,7 @@ func newEvent() chan struct{} { type cSysData struct { ctype int event chan struct{} - resize func(x int, y int, width int, height int, winheight int) error + resize func(x int, y int, width int, height int) []resizerequest alternate bool // editable for Combobox, multi-select for listbox, password for lineedit handler AreaHandler // for Areas } @@ -109,3 +109,11 @@ func mksysdata(ctype int) *sysData { }, } } + +type resizerequest struct { + sysData *sysData + x int + y int + width int + height int +}