2014-02-11 15:14:15 -06:00
// 11 february 2014
2014-03-12 20:55:45 -05:00
2014-02-19 10:41:10 -06:00
package ui
2014-02-11 15:14:15 -06:00
2014-02-18 09:53:15 -06:00
const eventbufsiz = 100 // suggested by skelterjohn
2014-03-12 20:47:39 -05:00
// newEvent returns a new channel suitable for listening for events.
func newEvent ( ) chan struct { } {
2014-02-18 09:53:15 -06:00
return make ( chan struct { } , eventbufsiz )
}
2014-02-11 15:14:15 -06:00
// The sysData type contains all system data. It provides the system-specific underlying implementation. It is guaranteed to have the following by embedding:
type cSysData struct {
2014-02-12 19:57:30 -06:00
ctype int
event chan struct { }
2014-03-17 20:09:03 -05:00
resize func ( x int , y int , width int , height int , rr * [ ] resizerequest )
resizes [ ] resizerequest
2014-03-16 20:40:33 -05:00
alternate bool // editable for Combobox, multi-select for listbox, password for lineedit
handler AreaHandler // for Areas
2014-02-11 15:14:15 -06:00
}
2014-04-01 14:34:51 -05:00
// this interface is used to make sure all sysDatas are synced
var _xSysData interface {
2014-04-01 15:43:56 -05:00
make ( window * sysData ) error
2014-04-01 14:34:51 -05:00
firstShow ( ) error
show ( )
hide ( )
setText ( text string )
setRect ( x int , y int , width int , height int , winheight int ) error
isChecked ( ) bool
text ( ) string
append ( string )
insertBefore ( string , int )
selectedIndex ( ) int
selectedIndices ( ) [ ] int
selectedTexts ( ) [ ] string
setWindowSize ( int , int ) error
delete ( int )
preferredSize ( ) ( int , int )
setProgress ( int )
len ( ) int
setAreaSize ( int , int )
} = & sysData { } // this line will error if there's an inconsistency
2014-02-11 15:14:15 -06:00
2014-02-18 08:57:19 -06:00
// signal sends the event signal. This raise is done asynchronously to avoid deadlocking the UI task.
2014-02-18 09:53:15 -06:00
// Thanks skelterjohn for this techinque: if we can't queue any more events, drop them
2014-02-18 08:57:19 -06:00
func ( s * cSysData ) signal ( ) {
if s . event != nil {
go func ( ) {
select {
case s . event <- struct { } { } :
default :
}
} ( )
}
}
2014-02-11 15:14:15 -06:00
const (
c_window = iota
c_button
2014-02-13 11:26:43 -06:00
c_checkbox
2014-02-14 11:16:27 -06:00
c_combobox
2014-02-14 14:00:59 -06:00
c_lineedit
2014-02-14 14:12:03 -06:00
c_label
2014-02-14 15:25:39 -06:00
c_listbox
2014-02-24 23:13:47 -06:00
c_progressbar
2014-03-14 17:47:18 -05:00
c_area
2014-02-11 18:09:10 -06:00
nctypes
2014-02-11 15:14:15 -06:00
)
2014-02-14 10:02:59 -06:00
func mksysdata ( ctype int ) * sysData {
2014-03-17 20:09:03 -05:00
s := & sysData {
2014-02-14 10:02:59 -06:00
cSysData : cSysData {
ctype : ctype ,
} ,
}
2014-03-17 20:09:03 -05:00
if ctype == c_window { // make resizes non-nil so it can be passed in
s . resizes = make ( [ ] resizerequest , 0 , 0 )
}
return s
2014-02-14 10:02:59 -06:00
}
2014-03-17 19:42:36 -05:00
type resizerequest struct {
sysData * sysData
x int
y int
width int
height int
}
2014-04-07 13:32:25 -05:00
func ( s * sysData ) doResize ( x int , y int , width int , height int , winheight int ) {
if s . resize != nil {
s . resizes = s . resizes [ 0 : 0 ] // set len to 0 without changing cap
s . resize ( x , y , width , height , & s . resizes )
for _ , s := range s . resizes {
err := s . sysData . setRect ( s . x , s . y , s . width , s . height , winheight )
if err != nil {
panic ( "child resize failed: " + err . Error ( ) )
}
}
}
}