2015-05-17 12:01:42 -05:00
// 16 may 2015
2015-05-16 19:31:56 -05:00
# include "uipriv_windows.h"
struct group {
uiGroup g ;
HWND hwnd ;
2015-06-01 17:00:20 -05:00
uiControl * child ;
void ( * baseCommitDestroy ) ( uiControl * ) ;
2015-06-01 17:45:37 -05:00
int margined ;
void ( * baseResize ) ( uiControl * , intmax_t , intmax_t , intmax_t , intmax_t , uiSizing * ) ;
2015-05-16 19:31:56 -05:00
} ;
2015-05-29 17:03:24 -05:00
uiDefineControlType ( uiGroup , uiTypeGroup , struct group )
2015-05-16 19:31:56 -05:00
2015-06-01 17:00:20 -05:00
static void groupCommitDestroy ( uiControl * c )
{
struct group * g = ( struct group * ) c ;
if ( g - > child ! = NULL ) {
uiControlSetParent ( g - > child , NULL ) ;
uiControlDestroy ( g - > child ) ;
}
( * ( g - > baseCommitDestroy ) ) ( uiControl ( g ) ) ;
}
2015-05-29 18:48:27 -05:00
static uintptr_t groupHandle ( uiControl * c )
{
struct group * g = ( struct group * ) c ;
return ( uintptr_t ) ( g - > hwnd ) ;
}
2015-06-01 21:12:39 -05:00
// from https://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing
2015-06-01 17:45:37 -05:00
# define groupXMargin 6
# define groupYMarginTop 11 /* note this value /includes the groupbox label */
# define groupYMarginBottom 7
// unfortunately because the client area of a groupbox includes the frame and caption text, we have to apply some margins ourselves, even if we don't want "any"
// these were deduced by hand based on the standard DLU conversions; the X and Y top margins are the width and height, respectively, of one character cell
// they can be fine-tuned later
# define groupUnmarginedXMargin 4
# define groupUnmarginedYMarginTop 8
# define groupUnmarginedYMarginBottom 3
2015-05-16 19:31:56 -05:00
static void groupPreferredSize ( uiControl * c , uiSizing * d , intmax_t * width , intmax_t * height )
{
2015-06-01 17:45:37 -05:00
struct group * g = ( struct group * ) c ;
2015-05-18 14:00:12 -05:00
* width = 0 ;
* height = 0 ;
2015-06-01 17:45:37 -05:00
if ( g - > child ! = NULL )
uiControlPreferredSize ( g - > child , d , width , height ) ;
if ( g - > margined ) {
* width + = 2 * uiWindowsDlgUnitsToX ( groupXMargin , d - > Sys - > BaseX ) ;
* height + = uiWindowsDlgUnitsToY ( groupYMarginTop , d - > Sys - > BaseY ) + uiWindowsDlgUnitsToY ( groupYMarginBottom , d - > Sys - > BaseY ) ;
} else {
* width + = 2 * uiWindowsDlgUnitsToX ( groupUnmarginedXMargin , d - > Sys - > BaseX ) ;
* height + = uiWindowsDlgUnitsToY ( groupUnmarginedYMarginTop , d - > Sys - > BaseY ) + uiWindowsDlgUnitsToY ( groupUnmarginedYMarginBottom , d - > Sys - > BaseY ) ;
}
}
static void groupResize ( uiControl * c , intmax_t x , intmax_t y , intmax_t width , intmax_t height , uiSizing * d )
{
struct group * g = ( struct group * ) c ;
uiSizing * dchild ;
( * ( g - > baseResize ) ) ( uiControl ( g ) , x , y , width , height , d ) ;
if ( g - > child = = NULL )
return ;
if ( g - > margined ) {
x + = uiWindowsDlgUnitsToX ( groupXMargin , d - > Sys - > BaseX ) ;
y + = uiWindowsDlgUnitsToY ( groupYMarginTop , d - > Sys - > BaseY ) ;
width - = 2 * uiWindowsDlgUnitsToX ( groupXMargin , d - > Sys - > BaseX ) ;
height - = uiWindowsDlgUnitsToY ( groupYMarginTop , d - > Sys - > BaseY ) + uiWindowsDlgUnitsToY ( groupYMarginBottom , d - > Sys - > BaseY ) ;
} else {
x + = uiWindowsDlgUnitsToX ( groupUnmarginedXMargin , d - > Sys - > BaseX ) ;
y + = uiWindowsDlgUnitsToY ( groupUnmarginedYMarginTop , d - > Sys - > BaseY ) ;
width - = 2 * uiWindowsDlgUnitsToX ( groupUnmarginedXMargin , d - > Sys - > BaseX ) ;
height - = uiWindowsDlgUnitsToY ( groupUnmarginedYMarginTop , d - > Sys - > BaseY ) + uiWindowsDlgUnitsToY ( groupUnmarginedYMarginBottom , d - > Sys - > BaseY ) ;
}
dchild = uiControlSizing ( uiControl ( g ) ) ;
uiControlResize ( g - > child , x , y , width , height , dchild ) ;
uiFreeSizing ( dchild ) ;
2015-05-16 19:31:56 -05:00
}
2015-06-01 17:00:20 -05:00
static void groupContainerUpdateState ( uiControl * c )
2015-05-16 19:31:56 -05:00
{
2015-06-01 17:00:20 -05:00
struct group * g = ( struct group * ) c ;
if ( g - > child ! = NULL )
uiControlUpdateState ( g - > child ) ;
}
static void groupSetChild ( uiGroup * gg , uiControl * child )
{
struct group * g = ( struct group * ) gg ;
if ( g - > child ! = NULL )
uiControlSetParent ( g - > child , NULL ) ;
g - > child = child ;
if ( g - > child ! = NULL ) {
uiControlSetParent ( g - > child , uiControl ( g ) ) ;
uiControlQueueResize ( g - > child ) ;
}
2015-05-16 19:31:56 -05:00
}
uiGroup * uiNewGroup ( const char * text )
{
struct group * g ;
WCHAR * wtext ;
2015-05-29 17:03:24 -05:00
g = ( struct group * ) uiWindowsNewSingleHWNDControl ( uiTypeGroup ( ) ) ;
2015-05-16 19:31:56 -05:00
wtext = toUTF16 ( text ) ;
2015-05-29 19:53:12 -05:00
g - > hwnd = uiWindowsUtilCreateControlHWND ( WS_EX_CONTROLPARENT ,
2015-05-29 17:03:24 -05:00
L " button " , wtext ,
BS_GROUPBOX ,
hInstance , NULL ,
TRUE ) ;
2015-05-16 19:31:56 -05:00
uiFree ( wtext ) ;
2015-05-29 18:48:27 -05:00
uiControl ( g ) - > Handle = groupHandle ;
2015-05-16 19:31:56 -05:00
uiControl ( g ) - > PreferredSize = groupPreferredSize ;
2015-06-01 17:45:37 -05:00
g - > baseResize = uiControl ( g ) - > Resize ;
uiControl ( g ) - > Resize = groupResize ;
2015-06-01 17:00:20 -05:00
g - > baseCommitDestroy = uiControl ( g ) - > CommitDestroy ;
uiControl ( g ) - > CommitDestroy = groupCommitDestroy ;
uiControl ( g ) - > ContainerUpdateState = groupContainerUpdateState ;
2015-05-16 19:31:56 -05:00
uiGroup ( g ) - > SetChild = groupSetChild ;
return uiGroup ( g ) ;
}