2015-05-17 12:01:42 -05:00
// 16 may 2015
2015-05-16 19:28:35 -05:00
# include "uipriv_windows.h"
struct tab {
uiTab t ;
HWND hwnd ;
2015-05-18 10:41:09 -05:00
struct ptrArray * pages ;
void ( * baseResize ) ( uiControl * , intmax_t , intmax_t , intmax_t , intmax_t , uiSizing * ) ;
2015-05-16 19:28:35 -05:00
} ;
2015-05-18 10:41:09 -05:00
struct tabPage {
uiControl * control ;
int margined ;
} ;
// utility functions
static LRESULT curpage ( struct tab * t )
{
return SendMessageW ( t - > hwnd , TCM_GETCURSEL , 0 , 0 ) ;
}
static void showHidePage ( struct tab * t , LRESULT which , int hide )
{
struct tabPage * page ;
if ( which = = ( LRESULT ) ( - 1 ) )
return ;
page = ptrArrayIndex ( t - > pages , struct tabPage * , which ) ;
if ( hide )
uiControlContainerHide ( page - > control ) ;
else {
uiControlContainerShow ( page - > control ) ;
// we only resize the current page, so we have to do this here
uiControlQueueResize ( page - > control ) ;
}
}
// control implementation
2015-05-16 19:28:35 -05:00
static BOOL onWM_COMMAND ( uiControl * c , WORD code , LRESULT * lResult )
{
return FALSE ;
}
static BOOL onWM_NOTIFY ( uiControl * c , NMHDR * nm , LRESULT * lResult )
{
2015-05-17 12:01:42 -05:00
return FALSE ;
2015-05-16 19:28:35 -05:00
}
static void onDestroy ( void * data )
{
2015-05-17 12:01:42 -05:00
// TODO
2015-05-16 19:28:35 -05:00
}
static void tabPreferredSize ( uiControl * c , uiSizing * d , intmax_t * width , intmax_t * height )
{
2015-05-17 12:01:42 -05:00
// TODO
2015-05-16 19:28:35 -05:00
}
2015-05-18 10:41:09 -05:00
static void tabResize ( uiControl * c , intmax_t x , intmax_t y , intmax_t width , intmax_t height , uiSizing * d )
{
struct tab * t = ( struct tab * ) c ;
LRESULT n ;
struct tabPage * page ;
RECT r ;
2015-05-18 11:04:52 -05:00
uiSizing * dchild ;
2015-05-18 10:41:09 -05:00
( * ( t - > baseResize ) ) ( uiControl ( t ) , x , y , width , height , d ) ;
n = curpage ( t ) ;
if ( n = = ( LRESULT ) ( - 1 ) )
return ;
page = ptrArrayIndex ( t - > pages , struct tabPage * , n ) ;
2015-05-18 11:04:52 -05:00
dchild = uiControlSizing ( uiControl ( t ) ) ;
// now we need to figure out what rect the child goes
// this rect needs to be in toplevel window coordinates, but TCM_ADJUSTRECT wants a window rect, which is screen coordinates
2015-05-18 10:41:09 -05:00
r . left = x ;
r . top = y ;
r . right = x + width ;
r . bottom = y + height ;
2015-05-18 11:04:52 -05:00
mapWindowRect ( dchild - > Sys - > CoordFrom , NULL , & r ) ;
2015-05-18 10:41:09 -05:00
SendMessageW ( t - > hwnd , TCM_ADJUSTRECT , ( WPARAM ) FALSE , ( LPARAM ) ( & r ) ) ;
2015-05-18 11:04:52 -05:00
mapWindowRect ( NULL , dchild - > Sys - > CoordFrom , & r ) ;
2015-05-18 10:41:09 -05:00
if ( page - > margined ) {
// TODO
}
2015-05-18 11:04:52 -05:00
uiControlResize ( page - > control , r . left , r . top , r . right - r . left , r . bottom - r . top , dchild ) ;
uiFreeSizing ( dchild ) ;
2015-05-18 10:41:09 -05:00
}
2015-05-18 09:20:11 -05:00
static void tabAppend ( uiTab * tt , const char * name , uiControl * child )
2015-05-16 19:28:35 -05:00
{
2015-05-18 10:41:09 -05:00
struct tab * t = ( struct tab * ) tt ;
uiTabInsertAt ( tt , name , t - > pages - > len , child ) ;
2015-05-16 19:28:35 -05:00
}
2015-05-18 09:32:08 -05:00
static void tabInsertAt ( uiTab * tt , const char * name , uintmax_t n , uiControl * child )
2015-05-16 19:28:35 -05:00
{
2015-05-18 10:41:09 -05:00
struct tab * t = ( struct tab * ) tt ;
struct tabPage * page ;
LRESULT hide , show ;
TCITEMW item ;
WCHAR * wname ;
// see below
hide = curpage ( t ) ;
page = uiNew ( struct tabPage ) ;
page - > control = child ;
uiControlSetParent ( page - > control , uiControl ( t ) ) ;
2015-05-18 11:04:52 -05:00
// and make it invisible at first; we show it later if needed
uiControlContainerHide ( page - > control ) ;
2015-05-18 10:41:09 -05:00
ptrArrayInsertAt ( t - > pages , n , page ) ;
ZeroMemory ( & item , sizeof ( TCITEMW ) ) ;
item . mask = TCIF_TEXT ;
wname = toUTF16 ( name ) ;
item . pszText = wname ;
if ( SendMessageW ( t - > hwnd , TCM_INSERTITEM , ( WPARAM ) n , ( LPARAM ) ( & item ) ) = = ( LRESULT ) - 1 )
logLastError ( " error adding tab to uiTab in uiTabInsertAt() " ) ;
uiFree ( wname ) ;
// we need to do this because adding the first tab doesn't send a TCN_SELCHANGE; it just shows the page
show = curpage ( t ) ;
if ( show ! = hide ) {
showHidePage ( t , hide , 1 ) ;
showHidePage ( t , show , 0 ) ;
}
2015-05-16 19:28:35 -05:00
}
2015-05-18 09:20:11 -05:00
static void tabDelete ( uiTab * tt , uintmax_t n )
2015-05-16 19:28:35 -05:00
{
2015-05-18 10:41:09 -05:00
// TODO
2015-05-16 19:28:35 -05:00
}
static uintmax_t tabNumPages ( uiTab * tt )
{
2015-05-18 10:41:09 -05:00
// TODO
2015-05-17 12:01:42 -05:00
return 0 ;
2015-05-16 19:28:35 -05:00
}
static int tabMargined ( uiTab * tt , uintmax_t n )
{
2015-05-18 10:41:09 -05:00
// TODO
2015-05-17 12:01:42 -05:00
return 0 ;
2015-05-16 19:28:35 -05:00
}
static void tabSetMargined ( uiTab * tt , uintmax_t n , int margined )
{
2015-05-18 10:41:09 -05:00
// TODO
2015-05-16 19:28:35 -05:00
}
uiTab * uiNewTab ( void )
{
struct tab * t ;
uiWindowsMakeControlParams p ;
t = uiNew ( struct tab ) ;
2015-05-17 18:07:07 -05:00
uiTyped ( t ) - > Type = uiTypeTab ( ) ;
2015-05-16 19:28:35 -05:00
p . dwExStyle = 0 ; // don't set WS_EX_CONTROLPARENT yet; we do that dynamically in the message loop (see main_windows.c)
p . lpClassName = WC_TABCONTROLW ;
p . lpWindowName = L " " ;
p . dwStyle = TCS_TOOLTIPS | WS_TABSTOP ; // start with this; we will alternate between this and WS_EX_CONTROLPARENT as needed (see main.c and msgHasTabStops above and the toggling functions below)
p . hInstance = hInstance ;
p . lpParam = NULL ;
p . useStandardControlFont = TRUE ;
p . onWM_COMMAND = onWM_COMMAND ;
p . onWM_NOTIFY = onWM_NOTIFY ;
p . onDestroy = onDestroy ;
p . onDestroyData = t ;
uiWindowsMakeControl ( uiControl ( t ) , & p ) ;
t - > hwnd = ( HWND ) uiControlHandle ( uiControl ( t ) ) ;
2015-05-18 10:41:09 -05:00
t - > pages = newPtrArray ( ) ;
2015-05-16 19:28:35 -05:00
uiControl ( t ) - > PreferredSize = tabPreferredSize ;
2015-05-18 10:41:09 -05:00
t - > baseResize = uiControl ( t ) - > Resize ;
uiControl ( t ) - > Resize = tabResize ;
2015-05-16 19:28:35 -05:00
2015-05-18 09:20:11 -05:00
uiTab ( t ) - > Append = tabAppend ;
2015-05-18 09:32:08 -05:00
uiTab ( t ) - > InsertAt = tabInsertAt ;
2015-05-18 09:20:11 -05:00
uiTab ( t ) - > Delete = tabDelete ;
2015-05-16 19:28:35 -05:00
uiTab ( t ) - > NumPages = tabNumPages ;
uiTab ( t ) - > Margined = tabMargined ;
uiTab ( t ) - > SetMargined = tabSetMargined ;
return uiTab ( t ) ;
}
2015-05-16 19:33:20 -05:00
// unfortunately WS_TABSTOP and WS_EX_CONTROLPARENT are mutually exclusive, so we have to toggle between them
// see main.c for more details
void tabEnterTabNavigation ( HWND hwnd )
{
setStyle ( hwnd , getStyle ( hwnd ) & ~ WS_TABSTOP ) ;
setExStyle ( hwnd , getExStyle ( hwnd ) | WS_EX_CONTROLPARENT ) ;
}
void tabLeaveTabNavigation ( HWND hwnd )
{
setExStyle ( hwnd , getExStyle ( hwnd ) & ~ WS_EX_CONTROLPARENT ) ;
setStyle ( hwnd , getStyle ( hwnd ) | WS_TABSTOP ) ;
}