Fixed Mac OS X control placement flipping. This is done by passing the height of the window around setRect() calls to avoid polling the content view frame each time.

This commit is contained in:
Pietro Gagliardi 2014-03-03 17:44:03 -05:00
parent 6c33892831
commit 962a84e056
17 changed files with 37 additions and 30 deletions

View File

@ -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) {

View File

@ -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) {

View File

@ -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) {

View File

@ -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)
}

View File

@ -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())
}

View File

@ -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)
}

View File

@ -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) {

View File

@ -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) {

View File

@ -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) {

View File

@ -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) {

View File

@ -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)
}

View File

@ -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())
}

View File

@ -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 {

View File

@ -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
}

View File

@ -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

View File

@ -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)
}

View File

@ -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)