From 274fa0c2928e3d1573a83d2f68048963df5e16e4 Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Sat, 12 Apr 2014 21:49:41 -0400 Subject: [PATCH] Fixed Comboboxes on Mac OS X having an initial selection. This also lays the groundwork for adding Combobox/Listbox.Select() as a public function... --- combobox.go | 2 ++ sysdata.go | 1 + sysdata_darwin.go | 29 +++++++++++++++++++++++++++++ sysdata_unix.go | 4 ++++ sysdata_windows.go | 4 ++++ todo.md | 4 +--- 6 files changed, 41 insertions(+), 3 deletions(-) diff --git a/combobox.go b/combobox.go index ec90dc6..0afc79e 100644 --- a/combobox.go +++ b/combobox.go @@ -145,6 +145,8 @@ func (c *Combobox) make(window *sysData) (err error) { for _, s := range c.initItems { c.sysData.append(s) } + // some platforms automatically select an item; undo that + c.sysData.selectIndex(-1) c.created = true return nil } diff --git a/sysdata.go b/sysdata.go index 1507912..d2ac699 100644 --- a/sysdata.go +++ b/sysdata.go @@ -40,6 +40,7 @@ var _xSysData interface { setProgress(int) len() int setAreaSize(int, int) + selectIndex(int) } = &sysData{} // this line will error if there's an inconsistency // signal sends the event signal. This raise is done asynchronously to avoid deadlocking the UI task. diff --git a/sysdata_darwin.go b/sysdata_darwin.go index 1b6795c..cfbd00e 100644 --- a/sysdata_darwin.go +++ b/sysdata_darwin.go @@ -33,6 +33,7 @@ type classData struct { selTexts func(id C.id) []string delete func(id C.id, index int) len func(id C.id) int + selectIndex func(id C.id, index int, alternate bool) } var ( @@ -82,6 +83,8 @@ var ( _setIndeterminate = sel_getUid("setIndeterminate:") _setDoubleValue = sel_getUid("setDoubleValue:") _numberOfItems = sel_getUid("numberOfItems") + _selectItemAtIndex = sel_getUid("selectItemAtIndex:") + _deselectItemAtIndex = sel_getUid("deselectItemAtIndex:") ) // because the only way to make a new NSControl/NSView is with a frame (it gets overridden later) @@ -238,6 +241,22 @@ var classTypes = [nctypes]*classData{ len: func(id C.id) int { return int(C.objc_msgSend_intret_noargs(id, _numberOfItems)) }, + selectIndex: func(id C.id, index int, alternate bool) { + // NSPopUpButton makes this easy + if !alternate { + C.objc_msgSend_int(id, _selectItemAtIndex, C.intptr_t(index)) + return + } + // NSComboBox doesn't document that we can do [cb selectItemAtIndex:-1], so we have to do this to be safe + if index == -1 { + idx := C.objc_msgSend_intret_noargs(id, _indexOfSelectedItem) + if idx != -1 { + C.objc_msgSend_int(id, _deselectItemAtIndex, idx) + } + return + } + C.objc_msgSend_int(id, _selectItemAtIndex, C.intptr_t(index)) + }, }, c_lineedit: &classData{ make: func(parentWindow C.id, alternate bool) C.id { @@ -542,3 +561,13 @@ func (s *sysData) setAreaSize(width int, height int) { } <-ret } + +func (s *sysData) selectIndex(index int) { + ret := make(chan struct{}) + defer close(ret) + uitask <- func() { + classTypes[s.ctype].selectIndex(s.id, index, s.alternate) + ret <- struct{}{} + } + <-ret +} diff --git a/sysdata_unix.go b/sysdata_unix.go index 8e61a4f..93b3704 100644 --- a/sysdata_unix.go +++ b/sysdata_unix.go @@ -359,3 +359,7 @@ func (s *sysData) setAreaSize(width int, height int) { } <-ret } + +func (s *sysData) selectIndex(index int) { + // TODO not yet implemented on Unix (added for Mac only right now) +} diff --git a/sysdata_windows.go b/sysdata_windows.go index d7beb8f..ba3520e 100644 --- a/sysdata_windows.go +++ b/sysdata_windows.go @@ -641,3 +641,7 @@ func (s *sysData) setAreaSize(width int, height int) { } <-ret } + +func (s *sysData) selectIndex(index int) { + // TODO not yet implemented on Windows (added for Mac only right now) +} diff --git a/todo.md b/todo.md index 56a594b..5b87be6 100644 --- a/todo.md +++ b/todo.md @@ -1,7 +1,5 @@ important things: -- NSPopUpButton does allow no initial selection ([b setSelectedIndex:-1]); use it - - need to use it /after/ adding initial items, otherwise it won't work - - find out if I can do the same with the ListBoxes +- NSTableViews start out with an initial selection (which is against our docs) - 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) - some Cocoa controls don't seem to resize correctly: Buttons have space around the edges - LineEdit heights on Windows seem too big; either that or LineEdit, Button, and Label text is not vertically centered properly