diff --git a/area.go b/area.go index 93f319e..b63bfe3 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 8815d21..b5e02a6 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 85eec5a..68fb0ef 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 65e25c4..2ca81cd 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 41960c4..ae2edfd 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 11d9034..2a44b02 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 e914453..5999941 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 309c5db..064dcab 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 82b8731..36bdb3f 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 2d89a5c..71f4529 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 36064f2..fae3582 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 cd4dc98..bbc7f1b 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 b37b935..2820ef7 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 727158d..54cec7d 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 b31a24e..cdf6a14 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 +}