2014-03-01 12:29:24 -06:00
// 1 march 2014
2014-03-12 20:55:45 -05:00
2014-03-01 12:29:24 -06:00
package ui
import (
2014-03-01 12:53:29 -06:00
"fmt"
2014-03-01 12:29:24 -06:00
"unsafe"
2014-03-01 16:06:06 -06:00
"sync"
2014-03-01 12:29:24 -06:00
)
// #cgo LDFLAGS: -lobjc -framework Foundation -framework AppKit
// #include "objc_darwin.h"
import "C"
type sysData struct {
cSysData
id C . id
}
type classData struct {
2014-03-02 13:43:31 -06:00
make func ( parentWindow C . id , alternate bool ) C . id
2014-03-30 10:19:13 -05:00
getinside func ( scrollview C . id ) C . id
2014-03-01 12:53:29 -06:00
show func ( what C . id )
hide func ( what C . id )
2014-03-01 12:29:24 -06:00
settextsel C . SEL
textsel C . SEL
2014-03-02 15:46:27 -06:00
alttextsel C . SEL
2014-03-02 16:19:25 -06:00
append func ( id C . id , what string , alternate bool )
2014-03-02 16:44:13 -06:00
insertBefore func ( id C . id , what string , before int , alternate bool )
2014-03-02 17:38:45 -06:00
selIndex func ( id C . id ) int
2014-03-02 22:11:29 -06:00
selIndices func ( id C . id ) [ ] int
selTexts func ( id C . id ) [ ] string
2014-03-02 16:44:13 -06:00
delete func ( id C . id , index int )
2014-03-08 16:25:19 -06:00
len func ( id C . id ) int
2014-03-01 12:29:24 -06:00
}
var (
_NSWindow = objc_getClass ( "NSWindow" )
2014-03-01 20:34:37 -06:00
_NSButton = objc_getClass ( "NSButton" )
2014-03-02 16:19:25 -06:00
_NSPopUpButton = objc_getClass ( "NSPopUpButton" )
_NSComboBox = objc_getClass ( "NSComboBox" )
2014-03-02 18:01:34 -06:00
_NSTextField = objc_getClass ( "NSTextField" )
_NSSecureTextField = objc_getClass ( "NSSecureTextField" )
2014-03-03 14:32:54 -06:00
_NSProgressIndicator = objc_getClass ( "NSProgressIndicator" )
2014-03-01 12:29:24 -06:00
_initWithContentRect = sel_getUid ( "initWithContentRect:styleMask:backing:defer:" )
2014-03-01 20:34:37 -06:00
_initWithFrame = sel_getUid ( "initWithFrame:" )
2014-04-04 14:07:43 -05:00
_setDelegate = sel_getUid ( "setDelegate:" )
2014-04-03 17:33:37 -05:00
_setAcceptsMouseMovedEvents = sel_getUid ( "setAcceptsMouseMovedEvents:" )
2014-03-01 12:29:24 -06:00
_makeKeyAndOrderFront = sel_getUid ( "makeKeyAndOrderFront:" )
_orderOut = sel_getUid ( "orderOut:" )
_setHidden = sel_getUid ( "setHidden:" )
_setTitle = sel_getUid ( "setTitle:" )
_setStringValue = sel_getUid ( "setStringValue:" )
_setFrame = sel_getUid ( "setFrame:" )
_state = sel_getUid ( "state" )
_title = sel_getUid ( "title" )
_stringValue = sel_getUid ( "stringValue" )
2014-03-01 14:35:42 -06:00
_frame = sel_getUid ( "frame" )
2014-03-01 12:29:24 -06:00
_setFrameDisplay = sel_getUid ( "setFrame:display:" )
2014-03-01 20:34:37 -06:00
_setBezelStyle = sel_getUid ( "setBezelStyle:" )
_setTarget = sel_getUid ( "setTarget:" )
_setAction = sel_getUid ( "setAction:" )
_contentView = sel_getUid ( "contentView" )
_addSubview = sel_getUid ( "addSubview:" )
2014-03-02 08:17:42 -06:00
_setButtonType = sel_getUid ( "setButtonType:" )
2014-03-02 16:19:25 -06:00
_initWithFramePullsDown = sel_getUid ( "initWithFrame:pullsDown:" )
_setUsesDataSource = sel_getUid ( "setUsesDataSource:" )
_addItemWithTitle = sel_getUid ( "addItemWithTitle:" )
_insertItemWithTitleAtIndex = sel_getUid ( "insertItemWithTitle:atIndex:" )
_removeItemAtIndex = sel_getUid ( "removeItemAtIndex:" )
_titleOfSelectedItem = sel_getUid ( "titleOfSelectedItem" )
_indexOfSelectedItem = sel_getUid ( "indexOfSelectedItem" )
_addItemWithObjectValue = sel_getUid ( "addItemWithObjectValue:" )
_insertItemWithObjectValueAtIndex = sel_getUid ( "insertItemWithObjectValue:atIndex:" )
2014-03-02 18:56:54 -06:00
_setEditable = sel_getUid ( "setEditable:" )
_setBordered = sel_getUid ( "setBordered:" )
_setDrawsBackground = sel_getUid ( "setDrawsBackground:" )
2014-03-03 14:32:54 -06:00
_setStyle = sel_getUid ( "setStyle:" )
_setControlSize = sel_getUid ( "setControlSize:" )
_setIndeterminate = sel_getUid ( "setIndeterminate:" )
_setDoubleValue = sel_getUid ( "setDoubleValue:" )
2014-03-08 16:25:19 -06:00
_numberOfItems = sel_getUid ( "numberOfItems" )
2014-03-01 12:29:24 -06:00
)
2014-04-04 18:51:23 -05:00
// because the only way to make a new NSControl/NSView is with a frame (it gets overridden later)
func initWithDummyFrame ( self C . id ) C . id {
return C . objc_msgSend_rect ( self , _initWithFrame ,
C . int64_t ( 0 ) , C . int64_t ( 0 ) , C . int64_t ( 100 ) , C . int64_t ( 100 ) )
}
2014-03-03 14:52:39 -06:00
func addControl ( parentWindow C . id , control C . id ) {
windowView := C . objc_msgSend_noargs ( parentWindow , _contentView )
C . objc_msgSend_id ( windowView , _addSubview , control )
}
2014-03-01 12:29:24 -06:00
func controlShow ( what C . id ) {
C . objc_msgSend_bool ( what , _setHidden , C . BOOL ( C . NO ) )
}
func controlHide ( what C . id ) {
C . objc_msgSend_bool ( what , _setHidden , C . BOOL ( C . YES ) )
}
2014-04-05 12:59:11 -05:00
const (
_NSRegularControlSize = 0
)
2014-03-01 12:29:24 -06:00
var classTypes = [ nctypes ] * classData {
c_window : & classData {
2014-03-02 13:43:31 -06:00
make : func ( parentWindow C . id , alternate bool ) C . id {
2014-03-01 12:29:24 -06:00
const (
2014-04-05 12:59:11 -05:00
_NSBorderlessWindowMask = 0
_NSTitledWindowMask = 1 << 0
_NSClosableWindowMask = 1 << 1
_NSMiniaturizableWindowMask = 1 << 2
_NSResizableWindowMask = 1 << 3
_NSTexturedBackgroundWindowMask = 1 << 8
_NSBackingStoreBuffered = 2 // the only backing store method that Apple says we should use (the others are legacy)
2014-03-01 12:29:24 -06:00
)
// we have to specify a content rect to start; it will be overridden soon though
2014-04-04 19:34:35 -05:00
win := C . objc_msgSend_noargs ( _NSWindow , _alloc )
2014-04-04 18:14:03 -05:00
win = C . objc_msgSend_rect_uint_uint_bool ( win ,
2014-03-01 12:29:24 -06:00
_initWithContentRect ,
2014-04-04 18:14:03 -05:00
C . int64_t ( 0 ) , C . int64_t ( 0 ) , C . int64_t ( 100 ) , C . int64_t ( 100 ) ,
2014-04-05 12:59:11 -05:00
C . uintptr_t ( _NSTitledWindowMask | _NSClosableWindowMask | _NSMiniaturizableWindowMask | _NSResizableWindowMask ) ,
C . uintptr_t ( _NSBackingStoreBuffered ) ,
2014-03-01 12:29:24 -06:00
C . BOOL ( C . YES ) ) // defer creation of device until we show the window
2014-04-04 14:07:43 -05:00
C . objc_msgSend_id ( win , _setDelegate , appDelegate )
2014-04-03 17:33:37 -05:00
// this is needed for Areas in the window to receive mouse move events
2014-04-04 13:52:38 -05:00
// C.objc_msgSend_bool(win, _setAcceptsMouseMovedEvents, C.BOOL(C.YES))
2014-03-01 16:15:26 -06:00
return win
2014-03-01 12:29:24 -06:00
} ,
show : func ( what C . id ) {
2014-03-01 12:53:29 -06:00
C . objc_msgSend_id ( what , _makeKeyAndOrderFront , what )
2014-03-01 12:29:24 -06:00
} ,
hide : func ( what C . id ) {
2014-03-01 12:53:29 -06:00
C . objc_msgSend_id ( what , _orderOut , what )
2014-03-01 12:29:24 -06:00
} ,
settextsel : _setTitle ,
textsel : _title ,
} ,
c_button : & classData {
2014-03-02 13:43:31 -06:00
make : func ( parentWindow C . id , alternate bool ) C . id {
2014-04-05 12:59:11 -05:00
const (
_NSRoundedBezelStyle = 1
)
2014-04-04 19:34:35 -05:00
button := C . objc_msgSend_noargs ( _NSButton , _alloc )
2014-04-04 18:51:23 -05:00
button = initWithDummyFrame ( button )
2014-04-05 12:59:11 -05:00
C . objc_msgSend_uint ( button , _setBezelStyle , C . uintptr_t ( _NSRoundedBezelStyle ) )
2014-03-01 20:34:37 -06:00
C . objc_msgSend_id ( button , _setTarget , appDelegate )
C . objc_msgSend_sel ( button , _setAction , _buttonClicked )
2014-04-04 13:52:38 -05:00
// by default the button uses the wrong text size
// TODO do this for all controls
2014-04-05 12:59:11 -05:00
C . objc_setFont ( button , _NSRegularControlSize )
2014-03-03 14:52:39 -06:00
addControl ( parentWindow , button )
2014-03-01 20:34:37 -06:00
return button
} ,
show : controlShow ,
hide : controlHide ,
settextsel : _setTitle ,
textsel : _title ,
2014-03-01 12:29:24 -06:00
} ,
c_checkbox : & classData {
2014-03-02 13:43:31 -06:00
make : func ( parentWindow C . id , alternate bool ) C . id {
2014-04-05 12:59:11 -05:00
const (
_NSSwitchButton = 3
)
2014-04-04 19:34:35 -05:00
checkbox := C . objc_msgSend_noargs ( _NSButton , _alloc )
2014-04-04 18:51:23 -05:00
checkbox = initWithDummyFrame ( checkbox )
2014-04-05 12:59:11 -05:00
C . objc_msgSend_uint ( checkbox , _setButtonType , C . uintptr_t ( _NSSwitchButton ) )
2014-03-03 14:52:39 -06:00
addControl ( parentWindow , checkbox )
2014-03-02 08:17:42 -06:00
return checkbox
} ,
show : controlShow ,
hide : controlHide ,
settextsel : _setTitle ,
textsel : _title ,
2014-03-01 12:29:24 -06:00
} ,
c_combobox : & classData {
2014-03-02 16:19:25 -06:00
make : func ( parentWindow C . id , alternate bool ) C . id {
var combobox C . id
if alternate {
2014-04-04 19:34:35 -05:00
combobox = C . objc_msgSend_noargs ( _NSComboBox , _alloc )
2014-04-04 18:51:23 -05:00
combobox = initWithDummyFrame ( combobox )
2014-03-02 16:19:25 -06:00
C . objc_msgSend_bool ( combobox , _setUsesDataSource , C . BOOL ( C . NO ) )
} else {
2014-04-04 19:34:35 -05:00
combobox = C . objc_msgSend_noargs ( _NSPopUpButton , _alloc )
2014-04-04 18:08:25 -05:00
combobox = C . objc_msgSend_rect_bool ( combobox , _initWithFramePullsDown ,
C . int64_t ( 0 ) , C . int64_t ( 0 ) , C . int64_t ( 100 ) , C . int64_t ( 100 ) ,
2014-03-02 16:19:25 -06:00
C . BOOL ( C . NO ) )
}
2014-03-03 14:52:39 -06:00
addControl ( parentWindow , combobox )
2014-03-02 16:19:25 -06:00
return combobox
} ,
show : controlShow ,
hide : controlHide ,
textsel : _titleOfSelectedItem ,
alttextsel : _stringValue ,
append : func ( id C . id , what string , alternate bool ) {
str := toNSString ( what )
if alternate {
C . objc_msgSend_id ( id , _addItemWithObjectValue , str )
} else {
C . objc_msgSend_id ( id , _addItemWithTitle , str )
}
} ,
2014-03-02 16:44:13 -06:00
insertBefore : func ( id C . id , what string , before int , alternate bool ) {
str := toNSString ( what )
if alternate {
C . objc_msgSend_id_int ( id , _insertItemWithObjectValueAtIndex , str , C . intptr_t ( before ) )
} else {
C . objc_msgSend_id_int ( id , _insertItemWithTitleAtIndex , str , C . intptr_t ( before ) )
}
} ,
2014-03-02 17:38:45 -06:00
selIndex : func ( id C . id ) int {
return int ( C . objc_msgSend_intret_noargs ( id , _indexOfSelectedItem ) )
} ,
2014-03-02 16:44:13 -06:00
delete : func ( id C . id , index int ) {
C . objc_msgSend_int ( id , _removeItemAtIndex , C . intptr_t ( index ) )
} ,
2014-03-08 16:25:19 -06:00
len : func ( id C . id ) int {
return int ( C . objc_msgSend_intret_noargs ( id , _numberOfItems ) )
} ,
2014-03-01 12:29:24 -06:00
} ,
c_lineedit : & classData {
2014-03-02 18:01:34 -06:00
make : func ( parentWindow C . id , alternate bool ) C . id {
var lineedit C . id
if alternate {
2014-04-04 19:34:35 -05:00
lineedit = C . objc_msgSend_noargs ( _NSSecureTextField , _alloc )
2014-03-02 18:01:34 -06:00
} else {
2014-04-04 19:34:35 -05:00
lineedit = C . objc_msgSend_noargs ( _NSTextField , _alloc )
2014-03-02 18:01:34 -06:00
}
2014-04-04 18:51:23 -05:00
lineedit = initWithDummyFrame ( lineedit )
2014-03-03 14:52:39 -06:00
addControl ( parentWindow , lineedit )
2014-03-02 18:01:34 -06:00
return lineedit
} ,
show : controlShow ,
hide : controlHide ,
settextsel : _setStringValue ,
textsel : _stringValue ,
alttextsel : _stringValue ,
2014-03-01 12:29:24 -06:00
} ,
c_label : & classData {
2014-03-02 18:56:54 -06:00
make : func ( parentWindow C . id , alternate bool ) C . id {
2014-04-04 19:34:35 -05:00
label := C . objc_msgSend_noargs ( _NSTextField , _alloc )
2014-04-04 18:51:23 -05:00
label = initWithDummyFrame ( label )
2014-03-02 18:56:54 -06:00
C . objc_msgSend_bool ( label , _setEditable , C . BOOL ( C . NO ) )
C . objc_msgSend_bool ( label , _setBordered , C . BOOL ( C . NO ) )
C . objc_msgSend_bool ( label , _setDrawsBackground , C . BOOL ( C . NO ) )
// TODO others?
2014-03-03 14:52:39 -06:00
addControl ( parentWindow , label )
2014-03-02 18:56:54 -06:00
return label
} ,
show : controlShow ,
hide : controlHide ,
settextsel : _setStringValue ,
textsel : _stringValue ,
2014-03-01 12:29:24 -06:00
} ,
c_listbox : & classData {
2014-03-02 22:11:29 -06:00
make : makeListbox ,
show : controlShow ,
hide : controlHide ,
append : appendListbox ,
insertBefore : insertListboxBefore ,
selIndices : selectedListboxIndices ,
selTexts : selectedListboxTexts ,
delete : deleteListbox ,
2014-03-08 16:25:19 -06:00
len : listboxLen ,
2014-03-01 12:29:24 -06:00
} ,
c_progressbar : & classData {
2014-03-03 14:32:54 -06:00
make : func ( parentWindow C . id , alternate bool ) C . id {
2014-04-05 12:59:11 -05:00
const (
_NSProgressIndicatorBarStyle = 0
)
2014-04-04 19:34:35 -05:00
pbar := C . objc_msgSend_noargs ( _NSProgressIndicator , _alloc )
2014-04-04 18:51:23 -05:00
pbar = initWithDummyFrame ( pbar )
2014-04-05 12:59:11 -05:00
// NSProgressIndicatorStyle doesn't have an explicit typedef; just use int for now
C . objc_msgSend_int ( pbar , _setStyle , _NSProgressIndicatorBarStyle )
C . objc_msgSend_uint ( pbar , _setControlSize , C . uintptr_t ( _NSRegularControlSize ) )
2014-03-03 14:32:54 -06:00
C . objc_msgSend_bool ( pbar , _setIndeterminate , C . BOOL ( C . NO ) )
2014-03-03 14:52:39 -06:00
addControl ( parentWindow , pbar )
2014-03-03 14:32:54 -06:00
return pbar
} ,
show : controlShow ,
hide : controlHide ,
2014-03-01 12:29:24 -06:00
} ,
2014-03-30 10:19:13 -05:00
c_area : & classData {
make : makeArea ,
getinside : areaInScrollView ,
show : controlShow ,
hide : controlHide ,
} ,
2014-03-01 12:29:24 -06:00
}
2014-03-01 16:06:06 -06:00
// I need to access sysData from appDelegate, but appDelegate doesn't store any data. So, this.
var (
sysdatas = make ( map [ C . id ] * sysData )
sysdatalock sync . Mutex
)
func addSysData ( key C . id , value * sysData ) {
sysdatalock . Lock ( )
sysdatas [ key ] = value
sysdatalock . Unlock ( )
}
func getSysData ( key C . id ) * sysData {
sysdatalock . Lock ( )
defer sysdatalock . Unlock ( )
v , ok := sysdatas [ key ]
if ! ok {
panic ( fmt . Errorf ( "internal error: getSysData(%v) unknown" , key ) )
}
return v
}
2014-04-01 16:05:16 -05:00
func ( s * sysData ) make ( window * sysData ) error {
2014-03-01 12:29:24 -06:00
var parentWindow C . id
ct := classTypes [ s . ctype ]
if window != nil {
parentWindow = window . id
}
ret := make ( chan C . id )
defer close ( ret )
uitask <- func ( ) {
2014-03-02 13:43:31 -06:00
ret <- ct . make ( parentWindow , s . alternate )
2014-03-01 12:29:24 -06:00
}
s . id = <- ret
2014-03-30 10:19:13 -05:00
if ct . getinside != nil {
uitask <- func ( ) {
ret <- ct . getinside ( s . id )
}
addSysData ( <- ret , s )
} else {
addSysData ( s . id , s )
}
2014-03-01 12:29:24 -06:00
return nil
}
2014-03-09 20:40:14 -05:00
// used for Windows; nothing special needed elsewhere
func ( s * sysData ) firstShow ( ) error {
s . show ( )
return nil
}
2014-03-09 20:56:17 -05:00
func ( s * sysData ) show ( ) {
2014-03-01 12:29:24 -06:00
ret := make ( chan struct { } )
defer close ( ret )
uitask <- func ( ) {
classTypes [ s . ctype ] . show ( s . id )
ret <- struct { } { }
}
<- ret
}
2014-03-09 20:56:17 -05:00
func ( s * sysData ) hide ( ) {
2014-03-01 12:29:24 -06:00
ret := make ( chan struct { } )
defer close ( ret )
uitask <- func ( ) {
classTypes [ s . ctype ] . hide ( s . id )
ret <- struct { } { }
}
<- ret
}
2014-03-10 09:39:08 -05:00
func ( s * sysData ) setText ( text string ) {
2014-03-01 12:29:24 -06:00
ret := make ( chan struct { } )
defer close ( ret )
uitask <- func ( ) {
C . objc_msgSend_id ( s . id , classTypes [ s . ctype ] . settextsel , toNSString ( text ) )
ret <- struct { } { }
}
<- ret
}
2014-03-03 16:44:03 -06:00
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
2014-04-04 18:51:23 -05:00
C . objc_msgSend_rect ( s . id , _setFrame ,
C . int64_t ( x ) , C . int64_t ( ( winheight - y ) - height ) , C . int64_t ( width ) , C . int64_t ( height ) )
2014-03-01 12:29:24 -06:00
return nil
}
func ( s * sysData ) isChecked ( ) bool {
const (
NSOnState = 1
)
ret := make ( chan bool )
defer close ( ret )
uitask <- func ( ) {
k := C . objc_msgSend_noargs ( s . id , _state )
ret <- uintptr ( unsafe . Pointer ( k ) ) == NSOnState
}
return <- ret
}
func ( s * sysData ) text ( ) string {
2014-03-02 15:46:27 -06:00
sel := classTypes [ s . ctype ] . textsel
if s . alternate {
sel = classTypes [ s . ctype ] . alttextsel
}
2014-03-01 12:29:24 -06:00
ret := make ( chan string )
defer close ( ret )
uitask <- func ( ) {
2014-03-02 15:46:27 -06:00
str := C . objc_msgSend_noargs ( s . id , sel )
2014-03-01 12:29:24 -06:00
ret <- fromNSString ( str )
}
return <- ret
}
2014-03-09 15:02:17 -05:00
func ( s * sysData ) append ( what string ) {
2014-03-02 16:19:25 -06:00
ret := make ( chan struct { } )
defer close ( ret )
uitask <- func ( ) {
classTypes [ s . ctype ] . append ( s . id , what , s . alternate )
ret <- struct { } { }
}
<- ret
2014-03-01 12:29:24 -06:00
}
2014-03-09 15:02:17 -05:00
func ( s * sysData ) insertBefore ( what string , before int ) {
2014-03-02 16:44:13 -06:00
ret := make ( chan struct { } )
defer close ( ret )
uitask <- func ( ) {
classTypes [ s . ctype ] . insertBefore ( s . id , what , before , s . alternate )
ret <- struct { } { }
}
<- ret
2014-03-01 12:29:24 -06:00
}
func ( s * sysData ) selectedIndex ( ) int {
2014-03-02 17:38:45 -06:00
ret := make ( chan int )
defer close ( ret )
uitask <- func ( ) {
ret <- classTypes [ s . ctype ] . selIndex ( s . id )
}
return <- ret
2014-03-01 12:29:24 -06:00
}
func ( s * sysData ) selectedIndices ( ) [ ] int {
2014-03-02 22:36:46 -06:00
ret := make ( chan [ ] int )
defer close ( ret )
uitask <- func ( ) {
ret <- classTypes [ s . ctype ] . selIndices ( s . id )
}
return <- ret
2014-03-01 12:29:24 -06:00
}
func ( s * sysData ) selectedTexts ( ) [ ] string {
2014-03-02 22:36:46 -06:00
ret := make ( chan [ ] string )
defer close ( ret )
uitask <- func ( ) {
ret <- classTypes [ s . ctype ] . selTexts ( s . id )
}
return <- ret
2014-03-01 12:29:24 -06:00
}
2014-03-01 12:53:29 -06:00
func ( s * sysData ) setWindowSize ( width int , height int ) error {
2014-03-01 12:29:24 -06:00
ret := make ( chan struct { } )
defer close ( ret )
uitask <- func ( ) {
2014-03-01 12:53:29 -06:00
// we need to get the top left point
2014-03-01 12:58:38 -06:00
r := C . objc_msgSend_stret_rect_noargs ( s . id , _frame )
2014-04-04 18:08:25 -05:00
C . objc_msgSend_rect_bool ( s . id , _setFrameDisplay ,
C . int64_t ( r . x ) , C . int64_t ( r . y ) , C . int64_t ( width ) , C . int64_t ( height ) ,
2014-03-01 12:29:24 -06:00
C . BOOL ( C . YES ) ) // TODO set to NO to prevent subviews from being redrawn before they are resized?
ret <- struct { } { }
}
<- ret
return nil
}
2014-03-11 12:50:02 -05:00
func ( s * sysData ) delete ( index int ) {
2014-03-02 16:44:13 -06:00
ret := make ( chan struct { } )
defer close ( ret )
uitask <- func ( ) {
classTypes [ s . ctype ] . delete ( s . id , index )
ret <- struct { } { }
}
<- ret
2014-03-01 12:29:24 -06:00
}
func ( s * sysData ) setProgress ( percent int ) {
2014-03-03 14:32:54 -06:00
ret := make ( chan struct { } )
defer close ( ret )
uitask <- func ( ) {
2014-03-12 18:40:01 -05:00
if percent == - 1 {
2014-04-04 16:59:23 -05:00
// At least on Mac OS X 10.8, if the progressbar was already on 0 or 100% when turning on indeterminate mode, the indeterminate animation won't play, leaving just a still progress bar. This is a workaround. Note the selector call order.
2014-04-04 17:00:22 -05:00
// TODO will the value chosen affect the animation speed?
2014-04-04 16:59:23 -05:00
C . objc_msgSend_double ( s . id , _setDoubleValue , C . double ( 50 ) )
2014-03-12 18:40:01 -05:00
C . objc_msgSend_bool ( s . id , _setIndeterminate , C . BOOL ( C . YES ) )
} else {
C . objc_msgSend_bool ( s . id , _setIndeterminate , C . BOOL ( C . NO ) )
C . objc_msgSend_double ( s . id , _setDoubleValue , C . double ( percent ) )
}
2014-03-03 14:32:54 -06:00
ret <- struct { } { }
}
<- ret
2014-03-01 12:29:24 -06:00
}
2014-03-08 16:25:19 -06:00
func ( s * sysData ) len ( ) int {
ret := make ( chan int )
defer close ( ret )
uitask <- func ( ) {
ret <- classTypes [ s . ctype ] . len ( s . id )
}
return <- ret
}
2014-03-30 10:19:13 -05:00
func ( s * sysData ) setAreaSize ( width int , height int ) {
ret := make ( chan struct { } )
defer close ( ret )
uitask <- func ( ) {
area := areaInScrollView ( s . id )
2014-04-04 18:51:23 -05:00
C . objc_msgSend_rect ( area , _setFrame ,
C . int64_t ( 0 ) , C . int64_t ( 0 ) , C . int64_t ( width ) , C . int64_t ( height ) )
2014-03-30 12:25:41 -05:00
C . objc_msgSend_noargs ( area , _display ) // and redraw
2014-03-30 10:19:13 -05:00
ret <- struct { } { }
}
<- ret
}