2014-07-28 19:52:32 -05:00
// 28 july 2014
package ui
import (
2014-07-28 22:29:06 -05:00
"fmt"
2014-07-28 19:52:32 -05:00
"unsafe"
"reflect"
)
// #include "winapi_windows.h"
import "C"
type table struct {
2014-07-30 01:06:01 -05:00
* controlbase
2014-07-28 19:52:32 -05:00
* tablebase
}
func finishNewTable ( b * tablebase , ty reflect . Type ) Table {
t := & table {
2014-07-30 01:06:01 -05:00
controlbase : newControl ( C . xWC_LISTVIEW ,
2014-07-28 19:52:32 -05:00
C . LVS_REPORT | C . LVS_OWNERDATA | C . LVS_NOSORTHEADER | C . LVS_SHOWSELALWAYS | C . WS_HSCROLL | C . WS_VSCROLL ,
2014-07-28 21:16:45 -05:00
C . WS_EX_CLIENTEDGE ) , // WS_EX_CLIENTEDGE without WS_BORDER will show the canonical visual styles border (thanks to MindChild in irc.efnet.net/#winprog)
2014-07-28 19:52:32 -05:00
tablebase : b ,
}
2014-07-28 22:29:06 -05:00
C . setTableSubclass ( t . hwnd , unsafe . Pointer ( t ) )
2014-07-28 22:47:45 -05:00
// LVS_EX_FULLROWSELECT gives us selection across the whole row, not just the leftmost column; this makes the list view work like on other platforms
// LVS_EX_SUBITEMIMAGES gives us images in subitems, which will be important when both images and checkboxes are added
C . tableAddExtendedStyles ( t . hwnd , C . LVS_EX_FULLROWSELECT | C . LVS_EX_SUBITEMIMAGES )
2014-07-28 19:52:32 -05:00
for i := 0 ; i < ty . NumField ( ) ; i ++ {
C . tableAppendColumn ( t . hwnd , C . int ( i ) , toUTF16 ( ty . Field ( i ) . Name ) )
}
return t
}
func ( t * table ) Unlock ( ) {
t . unlock ( )
// TODO RACE CONDITION HERE
// I think there's a way to set the item count without causing a refetch of data that works around this...
t . RLock ( )
defer t . RUnlock ( )
C . tableUpdate ( t . hwnd , C . int ( reflect . Indirect ( reflect . ValueOf ( t . data ) ) . Len ( ) ) )
}
2014-07-28 22:29:06 -05:00
//export tableGetCellText
func tableGetCellText ( data unsafe . Pointer , row C . int , col C . int , str * C . LPWSTR ) {
t := ( * table ) ( data )
t . RLock ( )
defer t . RUnlock ( )
d := reflect . Indirect ( reflect . ValueOf ( t . data ) )
datum := d . Index ( int ( row ) ) . Field ( int ( col ) )
s := fmt . Sprintf ( "%v" , datum )
2014-08-01 17:30:07 -05:00
* str = toUTF16 ( s )
2014-07-28 22:29:06 -05:00
}
2014-08-03 08:18:35 -05:00
func ( t * table ) setParent ( p * controlParent ) {
basesetParent ( t . controlbase , p )
}
func ( t * table ) containerShow ( ) {
basecontainerShow ( t . controlbase )
}
func ( t * table ) containerHide ( ) {
basecontainerHide ( t . controlbase )
}
func ( t * table ) allocate ( x int , y int , width int , height int , d * sizing ) [ ] * allocation {
return baseallocate ( t , x , y , width , height , d )
}
const (
// from C++ Template 05 in http://msdn.microsoft.com/en-us/library/windows/desktop/bb226818%28v=vs.85%29.aspx as this is the best I can do for now... (TODO see if I can reliably get item width/height from text size)
tableWidth = 183
tableHeight = 50
)
func ( t * table ) preferredSize ( d * sizing ) ( width , height int ) {
return fromdlgunitsX ( tableWidth , d ) , fromdlgunitsY ( tableHeight , d )
}
func ( t * table ) commitResize ( a * allocation , d * sizing ) {
basecommitResize ( t . controlbase , a , d )
}
func ( t * table ) getAuxResizeInfo ( d * sizing ) {
basegetAuxResizeInfo ( d )
}