2015-05-14 08:43:25 -05:00
// 14 may 2015
# include "uipriv_windows.h"
2015-05-14 09:08:49 -05:00
static struct ptrArray * resizes ;
void initResizes ( void )
{
resizes = newPtrArray ( ) ;
}
void uninitResizes ( void )
{
while ( resizes - > len ! = 0 )
ptrArrayDelete ( resizes , 0 ) ;
ptrArrayDestroy ( resizes ) ;
}
2015-05-18 11:04:52 -05:00
static uiControl * findToplevel ( uiControl * c )
2015-05-14 09:08:49 -05:00
{
2015-05-17 20:15:39 -05:00
for ( ; ; ) {
if ( uiIsWindow ( c ) )
break ;
2015-05-18 11:04:52 -05:00
if ( uiControlParent ( c ) = = NULL ) // not in a window
return NULL ;
2015-05-17 20:15:39 -05:00
c = uiControlParent ( c ) ;
}
2015-05-18 11:04:52 -05:00
return c ;
}
void queueResize ( uiControl * c )
{
uintmax_t i ;
uiControl * d ;
// resizing a control requires us to reocmpute the sizes of everything in the top-level window
c = findToplevel ( c ) ;
if ( c = = NULL )
return ;
2015-05-16 19:06:03 -05:00
// make sure we're only queued once
for ( i = 0 ; i < resizes - > len ; i + + ) {
d = ptrArrayIndex ( resizes , uiControl * , i ) ;
if ( c = = d )
return ;
}
2015-05-14 09:08:49 -05:00
ptrArrayAppend ( resizes , c ) ;
}
2015-05-16 19:06:03 -05:00
// TODO dequeueResize
2015-05-14 09:08:49 -05:00
void doResizes ( void )
{
2015-05-17 20:15:39 -05:00
uiWindow * w ;
2015-05-16 00:55:34 -05:00
HWND hwnd ;
2015-05-14 09:08:49 -05:00
while ( resizes - > len ! = 0 ) {
2015-05-17 20:15:39 -05:00
w = ptrArrayIndex ( resizes , uiWindow * , 0 ) ;
2015-05-14 09:08:49 -05:00
ptrArrayDelete ( resizes , 0 ) ;
2015-05-17 20:15:39 -05:00
uiWindowResizeChild ( w ) ;
hwnd = ( HWND ) uiControlHandle ( uiControl ( w ) ) ;
2015-05-14 09:08:49 -05:00
// we used SWP_NOREDRAW; we need to queue a redraw ourselves
// TODO use RedrawWindow() to bypass WS_CLIPCHILDREN complications
if ( InvalidateRect ( hwnd , NULL , TRUE ) = = 0 )
logLastError ( " error redrawing controls after a resize in doResizes() " ) ;
}
}
# define swpflags (SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOREDRAW)
2015-05-18 11:04:52 -05:00
void moveWindow ( HWND hwnd , intmax_t x , intmax_t y , intmax_t width , intmax_t height , uiSizing * d )
2015-05-14 09:08:49 -05:00
{
2015-05-18 11:04:52 -05:00
RECT r ;
r . left = x ;
r . top = y ;
r . right = x + width ;
r . bottom = y + height ;
mapWindowRect ( d - > Sys - > CoordFrom , d - > Sys - > CoordTo , & r ) ;
if ( SetWindowPos ( hwnd , NULL , r . left , r . top , r . right - r . left , r . bottom - r . top , swpflags | SWP_NOZORDER ) = = 0 )
2015-05-14 09:08:49 -05:00
logLastError ( " error moving window in moveWindow() " ) ;
}
2015-05-30 02:40:59 -05:00
// TODO make sure we're not missing any flags
2015-05-30 02:40:14 -05:00
void setWindowInsertAfter ( HWND hwnd , HWND insertAfter )
2015-05-14 09:08:49 -05:00
{
2015-05-30 02:40:14 -05:00
if ( SetWindowPos ( hwnd , insertAfter , 0 , 0 , 0 , 0 , swpflags | SWP_NOMOVE | SWP_NOSIZE ) = = 0 )
logLastError ( " error reordering window in setWindowInsertAfter() " ) ;
2015-05-14 09:08:49 -05:00
}
2015-05-15 15:04:10 -05:00
// from https://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing and https://msdn.microsoft.com/en-us/library/windows/desktop/bb226818%28v=vs.85%29.aspx
// this X value is really only for buttons but I don't see a better one :/
# define winXPadding 4
# define winYPadding 4
2015-05-18 10:46:50 -05:00
uiSizing * uiWindowsSizing ( uiControl * c )
2015-05-15 15:04:10 -05:00
{
2015-05-18 10:46:50 -05:00
uiSizing * d ;
2015-05-15 15:04:10 -05:00
HWND hwnd ;
HDC dc ;
HFONT prevfont ;
TEXTMETRICW tm ;
SIZE size ;
2015-05-18 11:04:52 -05:00
uiControl * toplevel ;
2015-05-15 15:04:10 -05:00
2015-05-18 10:46:50 -05:00
d = uiNew ( uiSizing ) ;
d - > Sys = uiNew ( uiSizingSys ) ;
2015-05-15 15:04:10 -05:00
hwnd = ( HWND ) uiControlHandle ( c ) ;
2015-05-16 00:55:34 -05:00
dc = GetDC ( hwnd ) ;
2015-05-15 15:04:10 -05:00
if ( dc = = NULL )
2015-05-18 10:46:50 -05:00
logLastError ( " error getting DC in uiWindowsSizing() " ) ;
2015-05-15 15:04:10 -05:00
prevfont = ( HFONT ) SelectObject ( dc , hMessageFont ) ;
if ( prevfont = = NULL )
2015-05-18 10:46:50 -05:00
logLastError ( " error loading control font into device context in uiWindowsSizing() " ) ;
2015-05-15 15:04:10 -05:00
ZeroMemory ( & tm , sizeof ( TEXTMETRICW ) ) ;
if ( GetTextMetricsW ( dc , & tm ) = = 0 )
2015-05-18 10:46:50 -05:00
logLastError ( " error getting text metrics in uiWindowsSizing() " ) ;
2015-05-15 15:04:10 -05:00
if ( GetTextExtentPoint32W ( dc , L " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz " , 52 , & size ) = = 0 )
2015-05-18 10:46:50 -05:00
logLastError ( " error getting text extent point in uiWindowsSizing() " ) ;
2015-05-15 15:04:10 -05:00
d - > Sys - > BaseX = ( int ) ( ( size . cx / 26 + 1 ) / 2 ) ;
d - > Sys - > BaseY = ( int ) tm . tmHeight ;
d - > Sys - > InternalLeading = tm . tmInternalLeading ;
if ( SelectObject ( dc , prevfont ) ! = hMessageFont )
2015-05-18 10:46:50 -05:00
logLastError ( " error restoring previous font into device context in uiWindowsSizing() " ) ;
2015-05-16 00:55:34 -05:00
if ( ReleaseDC ( hwnd , dc ) = = 0 )
2015-05-18 10:46:50 -05:00
logLastError ( " error releasing DC in uiWindowsSizing() " ) ;
2015-05-15 15:04:10 -05:00
2015-05-16 00:55:34 -05:00
d - > XPadding = uiWindowsDlgUnitsToX ( winXPadding , d - > Sys - > BaseX ) ;
d - > YPadding = uiWindowsDlgUnitsToY ( winYPadding , d - > Sys - > BaseY ) ;
2015-05-18 11:04:52 -05:00
toplevel = findToplevel ( c ) ;
if ( toplevel ! = NULL )
d - > Sys - > CoordFrom = ( HWND ) uiControlHandle ( toplevel ) ;
d - > Sys - > CoordTo = hwnd ;
return d ;
2015-05-15 15:04:10 -05:00
}
2015-05-18 10:46:50 -05:00
void uiFreeSizing ( uiSizing * d )
{
uiFree ( d - > Sys ) ;
uiFree ( d ) ;
}