diff --git a/button.go b/button.go index cd0d70b..f29d869 100644 --- a/button.go +++ b/button.go @@ -62,11 +62,11 @@ func (b *Button) make(window *sysData) error { return nil } -func (b *Button) setRect(x int, y int, width int, height int) error { +func (b *Button) setRect(x int, y int, width int, height int, winheight int) error { b.lock.Lock() defer b.lock.Unlock() - return b.sysData.setRect(x, y, width, height) + return b.sysData.setRect(x, y, width, height, winheight) } func (b *Button) preferredSize() (width int, height int, err error) { diff --git a/checkbox.go b/checkbox.go index 4e07a0d..5dfd3d1 100644 --- a/checkbox.go +++ b/checkbox.go @@ -68,11 +68,11 @@ func (c *Checkbox) make(window *sysData) error { return nil } -func (c *Checkbox) setRect(x int, y int, width int, height int) error { +func (c *Checkbox) setRect(x int, y int, width int, height int, winheight int) error { c.lock.Lock() defer c.lock.Unlock() - return c.sysData.setRect(x, y, width, height) + return c.sysData.setRect(x, y, width, height, winheight) } func (c *Checkbox) preferredSize() (width int, height int, err error) { diff --git a/combobox.go b/combobox.go index d01badd..ac3523a 100644 --- a/combobox.go +++ b/combobox.go @@ -113,11 +113,11 @@ func (c *Combobox) make(window *sysData) (err error) { return nil } -func (c *Combobox) setRect(x int, y int, width int, height int) error { +func (c *Combobox) setRect(x int, y int, width int, height int, winheight int) error { c.lock.Lock() defer c.lock.Unlock() - return c.sysData.setRect(x, y, width, height) + return c.sysData.setRect(x, y, width, height, winheight) } func (c *Combobox) preferredSize() (width int, height int, err error) { diff --git a/control.go b/control.go index 1c610b1..3f54afe 100644 --- a/control.go +++ b/control.go @@ -8,6 +8,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) error + setRect(x int, y int, width int, height int, winheight int) error preferredSize() (width int, height int, err error) } diff --git a/delegate_darwin.go b/delegate_darwin.go index 897cc28..82c536d 100644 --- a/delegate_darwin.go +++ b/delegate_darwin.go @@ -88,7 +88,8 @@ func appDelegate_windowDidResize(self C.id, sel C.SEL, notification C.id) { wincv := C.objc_msgSend_noargs(win, _contentView) // we want the content view's size, not the window's; selector defined in sysdata_darwin.go r := C.objc_msgSend_stret_rect_noargs(wincv, _frame) if sysData.resize != nil { - err := sysData.resize(int(r.x), int(r.y), int(r.width), int(r.height)) + // 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()) } diff --git a/grid.go b/grid.go index 63b7b52..b6f7e84 100644 --- a/grid.go +++ b/grid.go @@ -109,7 +109,7 @@ func (g *Grid) make(window *sysData) error { return nil } -func (g *Grid) setRect(x int, y int, width int, height int) error { +func (g *Grid) setRect(x int, y int, width int, height int, winheight int) error { g.lock.Lock() defer g.lock.Unlock() @@ -165,7 +165,7 @@ func (g *Grid) setRect(x int, y int, width int, height int) error { w = g.colwidths[col] h = g.rowheights[row] } - err := c.setRect(x, y, w, h) + 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) } diff --git a/label.go b/label.go index 25cdc5d..88e79af 100644 --- a/label.go +++ b/label.go @@ -56,11 +56,11 @@ func (l *Label) make(window *sysData) error { return nil } -func (l *Label) setRect(x int, y int, width int, height int) error { +func (l *Label) setRect(x int, y int, width int, height int, winheight int) error { l.lock.Lock() defer l.lock.Unlock() - return l.sysData.setRect(x, y, width, height) + return l.sysData.setRect(x, y, width, height, winheight) } func (l *Label) preferredSize() (width int, height int, err error) { diff --git a/lineedit.go b/lineedit.go index bcb28ac..037c858 100644 --- a/lineedit.go +++ b/lineedit.go @@ -68,11 +68,11 @@ func (l *LineEdit) make(window *sysData) error { return nil } -func (l *LineEdit) setRect(x int, y int, width int, height int) error { +func (l *LineEdit) setRect(x int, y int, width int, height int, winheight int) error { l.lock.Lock() defer l.lock.Unlock() - return l.sysData.setRect(x, y, width, height) + return l.sysData.setRect(x, y, width, height, winheight) } func (l *LineEdit) preferredSize() (width int, height int, err error) { diff --git a/listbox.go b/listbox.go index b333f79..9568375 100644 --- a/listbox.go +++ b/listbox.go @@ -104,11 +104,11 @@ func (l *Listbox) make(window *sysData) (err error) { return nil } -func (l *Listbox) setRect(x int, y int, width int, height int) error { +func (l *Listbox) setRect(x int, y int, width int, height int, winheight int) error { l.lock.Lock() defer l.lock.Unlock() - return l.sysData.setRect(x, y, width, height) + return l.sysData.setRect(x, y, width, height, winheight) } func (l *Listbox) preferredSize() (width int, height int, err error) { diff --git a/progressbar.go b/progressbar.go index c8b2bbf..4d41b28 100644 --- a/progressbar.go +++ b/progressbar.go @@ -49,11 +49,11 @@ func (p *ProgressBar) make(window *sysData) error { return nil } -func (p *ProgressBar) setRect(x int, y int, width int, height int) error { +func (p *ProgressBar) setRect(x int, y int, width int, height int, winheight int) error { p.lock.Lock() defer p.lock.Unlock() - return p.sysData.setRect(x, y, width, height) + return p.sysData.setRect(x, y, width, height, winheight) } func (p *ProgressBar) preferredSize() (width int, height int, err error) { diff --git a/stack.go b/stack.go index f66bc3d..171920b 100644 --- a/stack.go +++ b/stack.go @@ -63,7 +63,7 @@ func (s *Stack) make(window *sysData) error { return nil } -func (s *Stack) setRect(x int, y int, width int, height int) error { +func (s *Stack) setRect(x int, y int, width int, height int, winheight int) error { s.lock.Lock() defer s.lock.Unlock() @@ -112,7 +112,7 @@ func (s *Stack) setRect(x int, y int, width int, height int) error { } // 3) now actually place controls for i, c := range s.controls { - err := c.setRect(x, y, s.width[i], s.height[i]) + 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) } diff --git a/stdwndclass_windows.go b/stdwndclass_windows.go index 3f52ea5..4afe1c8 100644 --- a/stdwndclass_windows.go +++ b/stdwndclass_windows.go @@ -51,7 +51,8 @@ func stdWndProc(s *sysData) func(hwnd _HWND, uMsg uint32, wParam _WPARAM, lParam if r1 == 0 { panic("GetClientRect failed: " + err.Error()) } - err = s.resize(int(r.Left), int(r.Top), int(r.Right), int(r.Bottom)) + // 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()) } diff --git a/sysdata.go b/sysdata.go index f6a4455..4574684 100644 --- a/sysdata.go +++ b/sysdata.go @@ -16,7 +16,7 @@ func Event() chan struct{} { type cSysData struct { ctype int event chan struct{} - resize func(x int, y int, width int, height int) error + resize func(x int, y int, width int, height int, winheight int) error alternate bool // editable for Combobox, multi-select for listbox, password for lineedit } func (c *cSysData) make(initText string, window *sysData) error { @@ -31,7 +31,7 @@ func (c *cSysData) hide() error { func (c *cSysData) setText(text string) error { panic(runtime.GOOS + " sysData does not define setText()") } -func (c *cSysData) setRect(x int, y int, width int, height int) error { +func (c *cSysData) setRect(x int, y int, width int, height int, winheight int) error { panic(runtime.GOOS + " sysData does not define setRect()") } func (c *cSysData) isChecked() bool { diff --git a/sysdata_darwin.go b/sysdata_darwin.go index dba7983..eb3a76f 100644 --- a/sysdata_darwin.go +++ b/sysdata_darwin.go @@ -346,8 +346,10 @@ func (s *sysData) setText(text string) error { return nil } -func (s *sysData) setRect(x int, y int, width int, height int) error { - objc_msgSend_rect(s.id, _setFrame, x, y, width, height) +func (s *sysData) setRect(x int, y int, width int, height int, winheight int) error { + // winheight - y because (0,0) is the bottom-left corner of the window and not the top-left corner + // (winheight - y) - height because (x, y) is the bottom-left corner of the control and not the top-left + objc_msgSend_rect(s.id, _setFrame, x, (winheight - y) - height, width, height) return nil } diff --git a/sysdata_unix.go b/sysdata_unix.go index f309729..fbfbf80 100644 --- a/sysdata_unix.go +++ b/sysdata_unix.go @@ -45,7 +45,8 @@ var classTypes = [nctypes]*classData{ return func() bool { if s.container != nil && s.resize != nil { // wait for init width, height := gtk_window_get_size(s.widget) - err := s.resize(0, 0, width, height) + // 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()) } @@ -189,7 +190,7 @@ func (s *sysData) setText(text string) error { return nil } -func (s *sysData) setRect(x int, y int, width int, height int) error { +func (s *sysData) setRect(x int, y int, width int, height int, winheight int) error { gtk_fixed_move(s.container, s.widget, x, y) gtk_widget_set_size_request(s.widget, width, height) return nil diff --git a/sysdata_windows.go b/sysdata_windows.go index b541bee..b14161d 100644 --- a/sysdata_windows.go +++ b/sysdata_windows.go @@ -251,7 +251,7 @@ func (s *sysData) setText(text string) error { return nil } -func (s *sysData) setRect(x int, y int, width int, height int) error { +func (s *sysData) setRect(x int, y int, width int, height int, winheight int) error { r1, _, err := _moveWindow.Call( uintptr(s.hwnd), uintptr(x), @@ -481,7 +481,8 @@ func (s *sysData) setWindowSize(width int, height int) error { if r.ret == 0 { return fmt.Errorf("error getting upper-left of window for resize: %v", r.err) } - err := s.setRect(int(rect.Left), int(rect.Top), width, height) + // 0 because (0,0) is top-left so no winheight + err := s.setRect(int(rect.Left), int(rect.Top), width, height, 0) if err != nil { return fmt.Errorf("error actually resizing window: %v", err) } diff --git a/todo.md b/todo.md index f514e20..dd8a1d1 100644 --- a/todo.md +++ b/todo.md @@ -27,7 +27,8 @@ so I don't forget: important things: - ui.Go() should exit when the main() you pass in exits - because the main event loop is not called if initialization fails, it is presently impossible for MsgBoxError() to work if UI initialization fails; this basically means we cannot allow initializiation to fail on Mac OS X if we want to be able to report UI init failures to the user with one -- Cocoa coordinates have (0,0) at the bottom left: need to fix this somehow +- figure out where to auto-place windows in Cocoa (also window coordinates are still not flipped properly so (0,0) on screen is the bottom-left) + - also provide a method to center windoes; Cocoa provides one for us but - I think Cocoa NSButton text is not vertically aligned properly...? - NSPopUpButton doesn't seem to allow no initial selection? need to be sure - NSComboBox scans the entered text to see if it matches one of the items and returns the index of that item if it does; find out how to suppress this so that it returns -1 unless the item was chosen from the list (like the other platforms)