2014-07-25 14:58:24 -05:00
// 25 july 2014
package ui
import (
"unsafe"
)
// #include "winapi_windows.h"
import "C"
/ *
2014-08-06 19:53:11 -05:00
On Windows , container controls are just regular controls that notify their parent when the user wants to do things ; changing the contents of a switching container ( such as a tab control ) must be done manually .
2014-07-25 14:58:24 -05:00
2014-08-05 18:01:56 -05:00
We ' ll create a dummy window using the pre - existing Window window class for each tab page . This makes showing and hiding tabs a matter of showing and hiding one control .
2014-07-25 14:58:24 -05:00
* /
type tab struct {
2014-08-03 20:52:21 -05:00
_hwnd C . HWND
2014-08-04 19:04:16 -05:00
tabs [ ] * container
2014-07-25 14:58:24 -05:00
}
func newTab ( ) Tab {
2014-08-03 20:52:21 -05:00
hwnd := C . newControl ( C . xWC_TABCONTROL ,
2014-07-25 14:58:24 -05:00
C . TCS_TOOLTIPS | C . WS_TABSTOP ,
2014-08-12 16:18:45 -05:00
// this is needed to have the tab contents be tab stop
2014-08-12 16:24:14 -05:00
// TODO this seems to override WS_TABSTOP; it seems I have to undo making the containers children - http://stackoverflow.com/questions/1153981/tab-order-in-tab-control-with-nested-dialogs-ws-ex-controlparent
2014-08-12 16:04:04 -05:00
C . WS_EX_CONTROLPARENT )
2014-07-25 14:58:24 -05:00
t := & tab {
2014-08-03 20:52:21 -05:00
_hwnd : hwnd ,
2014-07-25 14:58:24 -05:00
}
2014-08-03 20:52:21 -05:00
C . controlSetControlFont ( t . _hwnd )
C . setTabSubclass ( t . _hwnd , unsafe . Pointer ( t ) )
2014-07-25 14:58:24 -05:00
return t
}
func ( t * tab ) Append ( name string , control Control ) {
2014-08-04 19:04:16 -05:00
c := newContainer ( control )
2014-08-06 19:53:11 -05:00
c . setParent ( & controlParent { t . _hwnd } )
2014-08-04 19:04:16 -05:00
t . tabs = append ( t . tabs , c )
2014-07-28 20:10:13 -05:00
// initially hide tab 1..n controls; if we don't, they'll appear over other tabs, resulting in weird behavior
if len ( t . tabs ) != 1 {
2014-08-04 20:33:58 -05:00
t . tabs [ len ( t . tabs ) - 1 ] . hide ( )
2014-07-28 20:10:13 -05:00
}
2014-08-03 20:52:21 -05:00
C . tabAppend ( t . _hwnd , toUTF16 ( name ) )
2014-07-25 14:58:24 -05:00
}
//export tabChanging
func tabChanging ( data unsafe . Pointer , current C . LRESULT ) {
t := ( * tab ) ( data )
2014-08-04 20:33:58 -05:00
t . tabs [ int ( current ) ] . hide ( )
2014-07-25 14:58:24 -05:00
}
//export tabChanged
func tabChanged ( data unsafe . Pointer , new C . LRESULT ) {
t := ( * tab ) ( data )
2014-08-04 20:33:58 -05:00
t . tabs [ int ( new ) ] . show ( )
2014-07-25 14:58:24 -05:00
}
2014-08-03 20:52:21 -05:00
func ( t * tab ) hwnd ( ) C . HWND {
return t . _hwnd
}
2014-08-03 08:18:35 -05:00
func ( t * tab ) setParent ( p * controlParent ) {
2014-08-03 20:52:21 -05:00
basesetParent ( t , p )
2014-08-03 08:18:35 -05:00
}
func ( t * tab ) allocate ( x int , y int , width int , height int , d * sizing ) [ ] * allocation {
return baseallocate ( t , x , y , width , height , d )
}
func ( t * tab ) preferredSize ( d * sizing ) ( width , height int ) {
2014-08-02 11:35:36 -05:00
for _ , s := range t . tabs {
w , h := s . child . preferredSize ( d )
if width < w {
width = w
}
if height < h {
height = h
}
}
2014-08-03 20:52:21 -05:00
return width , height + int ( C . tabGetTabHeight ( t . _hwnd ) )
2014-08-02 11:35:36 -05:00
}
2014-07-25 14:58:24 -05:00
// a tab control contains other controls; size appropriately
2014-08-03 08:18:35 -05:00
func ( t * tab ) commitResize ( c * allocation , d * sizing ) {
2014-07-25 14:58:24 -05:00
var r C . RECT
2014-07-28 14:02:27 -05:00
// figure out what the rect for each child is...
2014-08-06 19:53:11 -05:00
// the tab contents are children of the tab itself, so ignore c.x and c.y, which are relative to the window!
r . left = C . LONG ( 0 )
r . top = C . LONG ( 0 )
r . right = C . LONG ( c . width )
r . bottom = C . LONG ( c . height )
2014-08-03 20:52:21 -05:00
C . tabGetContentRect ( t . _hwnd , & r )
2014-08-03 08:18:35 -05:00
// and resize tabs
// don't resize just the current tab; resize all tabs!
2014-08-04 19:04:16 -05:00
for _ , c := range t . tabs {
2014-07-28 14:02:27 -05:00
// because each widget is actually a child of the Window, the origin is the one we calculated above
2014-08-04 20:27:35 -05:00
c . move ( & r )
2014-07-25 14:58:24 -05:00
}
2014-08-03 08:18:35 -05:00
// and now resize the tab control itself
2014-08-03 20:52:21 -05:00
basecommitResize ( t , c , d )
2014-08-03 08:18:35 -05:00
}
func ( t * tab ) getAuxResizeInfo ( d * sizing ) {
2014-08-03 19:42:45 -05:00
basegetAuxResizeInfo ( t , d )
2014-07-25 14:58:24 -05:00
}