2024-09-24 12:54:57 +00:00
# include <precomp.h>
# include <bfc/wasabi_std.h>
# include <bfc/wasabi_std_wnd.h>
# include <api/wnd/wndevent.h>
# include <bfc/bfc_assert.h>
# include <api/wnd/wndclass/tooltip.h>
# include <api/wnd/cursor.h>
# include <api/wnd/accessible.h>
# include <api/service/svcs/svc_accessibility.h>
# include <api/wnd/paintsets.h>
# include <api/wnd/PaintCanvas.h>
# ifdef _WIN32
# include <shellapi.h> // for HDROP
# endif
# include <tataki/canvas/bltcanvas.h>
# define DESKTOPALPHA
# define REFRESH_RATE 25
# define DRAWTIMERID 125
# include <api/wnd/basewnd.h>
# include <api/wnd/usermsg.h>
# include <api/wnd/paintcb.h>
# include <tataki/canvas/canvas.h>
# include <bfc/file/filename.h>
# include <tataki/region/region.h>
# include <api/wnd/wndclass/guiobjwnd.h>
# include <api/script/scriptguid.h>
# include <api/wnd/notifmsg.h>
# include <api/metrics/metricscb.h>
# include <api/wndmgr/gc.h>
# include <api/wndmgr/layout.h>
namespace Agave
{
# include "../Agave/Config/api_config.h"
}
//#define TIP_TIMER_ID 1601
# define TIP_DESTROYTIMER_ID 1602
# define TIP_AWAY_ID 1603
# define TIP_AWAY_DELAY 100
# define TIP_TIMER_THRESHOLD 350
# define TIP_LENGTH 3000
# define VCHILD_TIMER_ID_MIN 2000
# define VCHILD_TIMER_ID_MAX 2100
# define BUFFEREDMSG_TIMER_ID 1604
# define DEFERREDCB_INVALIDATE 0x201 // move to .h
# define DEFERREDCB_FOCUSFIRST 0x202 // move to .h
# define DC_KILLGHOST 0x204
# ifdef _WIN32
# define WM_DEFER_CALLBACK (WM_USER+0x333)
# endif
class DragSet : public PtrList < void > , public NamedW { } ;
//CUT? static void register_wndClass(HINSTANCE);
//CUT? #define ROOTSTRING "RootWnd"
//CUT? #define BASEWNDCLASSNAME "BaseWindow_" ROOTSTRING
# ifndef WM_MOUSEWHEEL
# define WM_MOUSEWHEEL 0x20A
# endif
static ifc_window * stickyWnd ;
static RECT sticky ;
static UINT WINAMP_WM_DIRECT_MOUSE_WHEEL = WM_NULL ;
/*api_window *api_window::rootwndFromPoint(POINT &point, int level) {
api_window * wnd ;
wnd = WASABI_API_WND - > rootWndFromPoint ( & point ) ;
return api_window : : rootwndFromRootWnd ( wnd , level , & point ) ;
}
api_window * api_window : : rootwndFromRootWnd ( api_window * wnd , int level , POINT * point ) {
for ( ; ; ) {
if ( wnd = = NULL | | level < 0 ) return NULL ;
if ( point ) {
RECT r ;
wnd - > getWindowRect ( & r ) ;
if ( ! PtInRect ( & r , * point ) ) return NULL ; // PORT ME
}
if ( level = = 0 ) return wnd ;
wnd = wnd - > getRootWndParent ( ) ;
level - - ;
}
// should never get here
} */
static BOOL DisabledWindow_OnMouseClick ( HWND hwnd )
{
DWORD windowStyle = ( DWORD ) GetWindowLongPtrW ( hwnd , GWL_STYLE ) ;
if ( WS_DISABLED ! = ( ( WS_CHILD | WS_DISABLED ) & windowStyle ) )
return FALSE ;
HWND hActive = GetActiveWindow ( ) ;
HWND hPopup = GetWindow ( hwnd , GW_ENABLEDPOPUP ) ;
BOOL beepOk = ( hPopup = = hActive | | hwnd = = GetWindow ( hActive , GW_OWNER ) ) ;
if ( ! beepOk & & NULL = = hPopup )
{
for ( HWND hWalker = hwnd ; ; )
{
hWalker = GetWindow ( hWalker , GW_OWNER ) ;
if ( NULL = = hWalker | | ( 0 ! = ( WS_CHILD & GetWindowLongPtrW ( hWalker , GWL_STYLE ) ) ) )
break ;
if ( hActive = = GetWindow ( hWalker , GW_ENABLEDPOPUP ) )
{
beepOk = TRUE ;
break ;
}
}
}
if ( beepOk )
{
static const GUID accessibilityConfigGroupGUID =
{ 0xe2e7f4a , 0x7c51 , 0x478f , { 0x87 , 0x74 , 0xab , 0xbc , 0xf6 , 0xd5 , 0xa8 , 0x57 } } ;
# define GetBoolConfig(__group, __itemName, __default)\
( ( NULL ! = ( __group ) ) & & NULL ! = ( item = group - > GetItem ( __itemName ) ) ? item - > GetBool ( ) : ( __default ) )
waServiceFactory * serviceFactory = WASABI_API_SVC - > service_getServiceByGuid ( Agave : : AgaveConfigGUID ) ;
Agave : : api_config * config = ( NULL ! = serviceFactory ) ? ( Agave : : api_config * ) serviceFactory - > getInterface ( ) : NULL ;
Agave : : ifc_configgroup * group = ( NULL ! = config ) ? config - > GetGroup ( accessibilityConfigGroupGUID ) : NULL ;
Agave : : ifc_configitem * item ;
if ( GetBoolConfig ( group , L " modalflash " , true ) )
{
FLASHWINFO flashInfo ;
flashInfo . cbSize = sizeof ( FLASHWINFO ) ;
flashInfo . hwnd = hActive ;
flashInfo . dwFlags = FLASHW_CAPTION ;
flashInfo . uCount = 2 ;
flashInfo . dwTimeout = 100 ;
FlashWindowEx ( & flashInfo ) ;
}
if ( GetBoolConfig ( group , L " modalbeep " , false ) )
MessageBeep ( MB_OK ) ;
if ( NULL ! = config )
serviceFactory - > releaseInterface ( config ) ;
}
else
{
for ( HWND hWalker = hwnd ; NULL = = hPopup ; )
{
hWalker = GetWindow ( hWalker , GW_OWNER ) ;
if ( NULL = = hWalker | | ( 0 ! = ( WS_CHILD & GetWindowLongPtrW ( hWalker , GWL_STYLE ) ) ) )
break ;
hPopup = GetWindow ( hWalker , GW_ENABLEDPOPUP ) ;
}
SetWindowPos ( hwnd , HWND_TOP , 0 , 0 , 0 , 0 , SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE ) ;
if ( NULL ! = hPopup & & hPopup ! = hwnd )
{
BringWindowToTop ( hPopup ) ;
SetActiveWindow ( hPopup ) ;
}
}
return TRUE ;
}
int WndWatcher : : viewer_onItemDeleted ( ifc_dependent * item )
{
if ( item = = dep )
{
dep = NULL ;
watcher - > wndwatcher_onDeleteWindow ( watched ) ;
watched = NULL ;
}
return 1 ;
}
BaseWnd : : BaseWnd ( )
{
uiwaslocked = 0 ;
m_takenOver = 0 ;
rootfocus = NULL ;
rootfocuswatcher . setWatcher ( this ) ;
alwaysontop = 0 ;
customdefaultcursor = NULL ;
preventcancelcapture = 0 ;
ratiolinked = 1 ;
deleting = 0 ;
hinstance = NULL ;
hwnd = NULL ;
parentWnd = NULL ;
dragging = 0 ;
prevtarg = NULL ;
inputCaptured = 0 ;
btexture = NULL ;
postoninit = 0 ;
inited = 0 ;
skipnextfocus = 0 ;
ncb = FALSE ;
accessible = NULL ;
tooltip = NULL ;
tip_done = FALSE ;
tipshowtimer = FALSE ;
tipawaytimer = FALSE ;
tipdestroytimer = FALSE ;
start_hidden = 0 ;
notifyWindow = NULL ;
lastClick [ 0 ] = 0 ;
lastClick [ 1 ] = 0 ;
lastClickP [ 0 ] . x = 0 ;
lastClickP [ 0 ] . y = 0 ;
lastClickP [ 1 ] . x = 0 ;
lastClickP [ 1 ] . y = 0 ;
destroying = FALSE ;
curVirtualChildCaptured = NULL ;
curVirtualChildFocus = NULL ;
virtualCanvas = NULL ; virtualCanvasH = virtualCanvasW = 0 ;
deferedInvalidRgn = NULL ;
hasfocus = 0 ;
focus_on_click = 1 ;
lastnullregion = 0 ;
ratio = 1 ;
lastratio = 1 ;
rwidth = rheight = 0 ;
skin_id = - 1 ;
wndalpha = 255 ;
activealpha = 255 ;
inactivealpha = 255 ;
w2k_alpha = 0 ; //FUCKO
scalecanvas = NULL ;
clickthrough = 0 ;
mustquit = 0 ;
returnvalue = 0 ;
notifyid = 0 ;
cloaked = 0 ;
disable_tooltip_til_recapture = 0 ;
subtractorrgn = NULL ;
composedrgn = NULL ;
wndregioninvalid = 1 ;
regionop = REGIONOP_NONE ;
rectrgn = 1 ;
need_flush_cascaderepaint = 0 ;
deferedCascadeRepaintRgn = NULL ;
this_visible = 0 ;
this_enabled = 1 ;
renderbasetexture = 0 ;
oldCapture = NULL ;
my_guiobject = NULL ;
want_autoresize_after_init = 0 ;
resizecount = 0 ;
suggested_w = 320 ;
suggested_h = 200 ;
maximum_w = maximum_h = AUTOWH ;
minimum_w = minimum_h = AUTOWH ;
rx = 0 ;
ry = 0 ;
rwidth = 0 ;
rheight = 0 ;
allow_deactivate = 1 ;
minimized = 0 ;
inonresize = 0 ;
# ifndef WA3COMPATIBILITY
m_target = NULL ;
# endif
nodoubleclick = noleftclick = norightclick = nomousemove = nocontextmnu = 0 ;
focusEventsEnabled = 1 ;
maximized = 0 ;
MEMSET ( & restore_rect , 0 , sizeof ( RECT ) ) ;
ghostbust = 0 ;
lastActiveWnd = NULL ;
}
BaseWnd : : ~ BaseWnd ( )
{
//ASSERT(virtualChildren.getNumItems() == 0);
childtabs . deleteAll ( ) ;
if ( WASABI_API_WND & & WASABI_API_WND - > getModalWnd ( ) = = this ) WASABI_API_WND - > popModalWnd ( this ) ;
destroying = TRUE ;
curVirtualChildFocus = NULL ;
# ifdef _WIN32
if ( inputCaptured & & GetCapture ( ) = = getOsWindowHandle ( ) ) ReleaseCapture ( ) ;
# else
# warning port me
# endif
for ( int i = 0 ; i < ghosthwnd . getNumItems ( ) ; i + + )
Wasabi : : Std : : Wnd : : destroyWnd ( ghosthwnd . enumItem ( i ) ) ;
if ( hwnd ! = NULL & & ! m_takenOver )
{
# ifdef URLDROPS
if ( acceptExternalDrops ( ) ) Wasabi : : Std : : Wnd : : revokeDragNDrop ( hwnd /*, &m_target*/ ) ;
# else
# ifndef WA3COMPATIBILITY
if ( m_target ! = NULL )
{
Wasabi : : Std : : Wnd : : revokeDragNDrop ( hwnd ) ;
}
# endif
# endif
int popact = ! wantActivation ( ) ;
if ( popact ) WASABI_API_WND - > appdeactivation_push_disallow ( this ) ;
Wasabi : : Std : : Wnd : : destroyWnd ( hwnd ) ;
if ( popact ) WASABI_API_WND - > appdeactivation_pop_disallow ( this ) ;
}
deleteFrameBuffer ( virtualCanvas ) ;
virtualCanvas = NULL ;
delete scalecanvas ;
scalecanvas = NULL ;
resetDragSet ( ) ;
notifyParent ( ChildNotify : : DELETED ) ;
if ( tipdestroytimer )
killTimer ( TIP_DESTROYTIMER_ID ) ;
if ( tipshowtimer )
{
// TODO: on the mac, use CreateMouseTrackingRegion
TRACKMOUSEEVENT tracker ;
tracker . cbSize = sizeof ( tracker ) ;
tracker . dwFlags = TME_HOVER | TME_CANCEL ;
tracker . hwndTrack = this - > getOsWindowHandle ( ) ;
tracker . dwHoverTime = TIP_TIMER_THRESHOLD ;
TrackMouseEvent ( & tracker ) ;
}
if ( tipawaytimer )
killTimer ( TIP_AWAY_ID ) ;
destroyTip ( ) ;
delete tooltip ;
if ( uiwaslocked )
killTimer ( BUFFEREDMSG_TIMER_ID ) ;
if ( deferedInvalidRgn )
delete deferedInvalidRgn ;
delete composedrgn ;
delete subtractorrgn ;
delete deferedCascadeRepaintRgn ;
if ( parentWnd ! = NULL )
parentWnd - > unregisterRootWndChild ( this ) ;
if ( ! m_takenOver & & WASABI_API_WND ) WASABI_API_WND - > unregisterRootWnd ( this ) ;
hwnd = NULL ;
}
int BaseWnd : : init ( ifc_window * parWnd , int nochild )
{
if ( parWnd = = NULL )
return 0 ;
OSWINDOWHANDLE phwnd = parWnd - > getOsWindowHandle ( ) ;
ASSERT ( phwnd ! = NULL ) ;
parentWnd = parWnd ; // set default parent wnd
int ret = init ( parWnd - > getOsModuleHandle ( ) , phwnd , nochild ) ;
if ( ! ret )
parentWnd = NULL ; // abort
return ret ;
}
int BaseWnd : : init ( OSMODULEHANDLE moduleHandle , OSWINDOWHANDLE parent , int nochild )
{
RECT r ;
int w , h ;
ASSERTPR ( getOsWindowHandle ( ) = = NULL , " don't you double init you gaybag " ) ;
hinstance = moduleHandle ;
# ifdef _WIN32
ASSERT ( hinstance ! = NULL ) ;
# endif
//CUT register_wndClass(hinstance);
if ( parent ! = NULL )
{
Wasabi : : Std : : Wnd : : getClientRect ( parent , & r ) ;
}
else
{
Wasabi : : Std : : setRect ( & r , 0 , 0 , getPreferences ( SUGGESTED_W ) , getPreferences ( SUGGESTED_H ) ) ;
}
w = ( r . right - r . left ) ;
h = ( r . bottom - r . top ) ;
rwidth = w ;
rheight = h ;
rx = r . left ;
ry = r . top ;
int popact = ! wantActivation ( ) ;
if ( popact ) WASABI_API_WND - > appdeactivation_push_disallow ( this ) ;
//CUThwnd = createWindow(r.left, r.top, w, h, nochild, parent, hinstance);
hwnd = Wasabi : : Std : : Wnd : : createWnd ( & r , nochild , acceptExternalDrops ( ) , parent , hinstance , static_cast < ifc_window * > ( this ) ) ;
# ifdef __APPLE__
# warning remove me
Wasabi : : Std : : Wnd : : showWnd ( hwnd ) ;
# endif
if ( popact ) WASABI_API_WND - > appdeactivation_pop_disallow ( this ) ;
//ASSERT(hwnd != NULL); // lets fail nicely, this could happen for some win32 reason, we don't want to fail the whole app for it, so lets just fail the wnd
if ( hwnd = = NULL ) return 0 ;
if ( wantActivation ( ) ) bringToFront ( ) ;
//CUT nreal++;
//FUCKO
# ifdef _WIN32 // PORT ME
# ifdef URLDROPS
if ( acceptExternalDrops ( ) ) RegisterDragDrop ( hwnd , & m_target ) ;
# else
# ifndef WA3COMPATIBILITY
if ( ! m_target & & WASABI_API_WND ! = NULL )
m_target = WASABI_API_WND - > getDefaultDropTarget ( ) ;
if ( m_target ! = NULL )
{
RegisterDragDrop ( hwnd , ( IDropTarget * ) m_target ) ;
}
# endif
# endif
# endif
this_visible = 0 ;
onInit ( ) ;
this_visible = ! start_hidden ;
onPostOnInit ( ) ;
return 1 ;
}
# ifndef WA3COMPATIBILITY
void BaseWnd : : setDropTarget ( void * dt )
{
# ifdef _WIN32
if ( isVirtual ( ) ) return ;
if ( isInited ( ) & & m_target ! = NULL )
{
Wasabi : : Std : : Wnd : : revokeDragNDrop ( getOsWindowHandle ( ) ) ;
m_target = NULL ;
}
m_target = dt ;
if ( m_target ! = NULL & & isInited ( ) )
{
RegisterDragDrop ( gethWnd ( ) , ( IDropTarget * ) m_target ) ;
}
# else
# warning port me
# endif
}
void * BaseWnd : : getDropTarget ( )
{
return m_target ;
}
# endif
int BaseWnd : : onInit ( )
{
const wchar_t * s = getName ( ) ;
if ( s ! = NULL )
setOSWndName ( s ) ;
inited = 1 ;
if ( getParent ( ) )
getParent ( ) - > registerRootWndChild ( this ) ;
if ( WASABI_API_WND ! = NULL )
WASABI_API_WND - > registerRootWnd ( this ) ;
# ifdef _WIN32
if ( ! Wasabi : : Std : : Wnd : : isDesktopAlphaAvailable ( ) )
w2k_alpha = 0 ; //FUCKO
if ( w2k_alpha )
{
setLayeredWindow ( 1 ) ;
}
if ( WM_NULL = = WINAMP_WM_DIRECT_MOUSE_WHEEL )
WINAMP_WM_DIRECT_MOUSE_WHEEL = RegisterWindowMessageW ( L " WINAMP_WM_DIRECT_MOUSE_WHEEL " ) ;
# endif
return 0 ;
}
int BaseWnd : : onPostOnInit ( )
{
postoninit = 1 ; // from now on, isInited() returns 1;
if ( want_autoresize_after_init ) onResize ( ) ;
else invalidateWindowRegion ( ) ;
if ( isVisible ( ) ) onSetVisible ( 1 ) ;
if ( getTabOrder ( ) = = - 1 ) setAutoTabOrder ( ) ;
ifc_window * dp = getDesktopParent ( ) ;
if ( ( dp = = NULL | | dp = = this ) & & WASABI_API_TIMER ! = NULL )
postDeferredCallback ( DEFERREDCB_FOCUSFIRST , 0 , 500 ) ;
return 0 ;
}
void BaseWnd : : setLayeredWindow ( int i )
{
if ( ! Wasabi : : Std : : Wnd : : isValidWnd ( getOsWindowHandle ( ) ) ) return ;
if ( ! isInited ( ) ) return ;
Wasabi : : Std : : Wnd : : setLayeredWnd ( getOsWindowHandle ( ) , i ) ;
#if 0 //CUT
if ( i )
{
SetWindowLong ( getOsWindowHandle ( ) , GWL_EXSTYLE , GetWindowLong ( getOsWindowHandle ( ) , GWL_EXSTYLE ) & ~ WS_EX_LAYERED ) ;
SetWindowLong ( getOsWindowHandle ( ) , GWL_EXSTYLE , GetWindowLong ( getOsWindowHandle ( ) , GWL_EXSTYLE ) | WS_EX_LAYERED ) ;
}
else
{
SetWindowLong ( getOsWindowHandle ( ) , GWL_EXSTYLE , GetWindowLong ( getOsWindowHandle ( ) , GWL_EXSTYLE ) & ~ WS_EX_LAYERED ) ;
}
# endif
setTransparency ( - 1 ) ;
}
int BaseWnd : : getCursorType ( int x , int y )
{
if ( ! customdefaultcursor )
return BASEWND_CURSOR_POINTER ;
return BASEWND_CURSOR_USERSET ;
}
void BaseWnd : : onSetName ( )
{
if ( isInited ( ) & & ! isVirtual ( ) )
Wasabi : : Std : : Wnd : : setWndName ( getOsWindowHandle ( ) , getNameSafe ( ) ) ;
notifyParent ( ChildNotify : : NAMECHANGED ) ;
if ( accessible )
accessible - > onSetName ( getName ( ) ) ;
}
OSWINDOWHANDLE BaseWnd : : getOsWindowHandle ( )
{
OSWINDOWHANDLE handle ;
if ( isVirtual ( ) )
handle = getParent ( ) - > getOsWindowHandle ( ) ;
else
handle = hwnd ;
return handle ;
}
OSMODULEHANDLE BaseWnd : : getOsModuleHandle ( )
{
return hinstance ;
}
void BaseWnd : : onTip ( )
{
tipshowtimer = FALSE ;
tip_done = TRUE ;
POINT p ;
Wasabi : : Std : : getMousePos ( & p ) ;
if ( WASABI_API_WND - > rootWndFromPoint ( & p ) = = ( ifc_window * ) this )
{
createTip ( ) ;
setTimer ( TIP_DESTROYTIMER_ID , TIP_LENGTH ) ;
tipdestroytimer = TRUE ;
}
setTimer ( TIP_AWAY_ID , TIP_AWAY_DELAY ) ;
tipawaytimer = TRUE ;
}
void BaseWnd : : timerCallback ( int id )
{
switch ( id )
{
case BUFFEREDMSG_TIMER_ID :
checkLockedUI ( ) ;
break ;
// case TIP_TIMER_ID:
//onTip();
//break;
case TIP_DESTROYTIMER_ID :
killTimer ( TIP_DESTROYTIMER_ID ) ;
killTimer ( TIP_AWAY_ID ) ;
tipawaytimer = FALSE ;
tipdestroytimer = FALSE ;
destroyTip ( ) ;
break ;
case TIP_AWAY_ID :
onTipMouseMove ( ) ;
break ;
}
}
int BaseWnd : : isInited ( )
{
return inited ;
}
int BaseWnd : : isDestroying ( )
{
return destroying ;
}
int BaseWnd : : wantSiblingInvalidations ( )
{
return FALSE ;
}
void BaseWnd : : setRSize ( int x , int y , int w , int h )
{
rwidth = w ;
rheight = h ;
rx = x ;
ry = y ;
}
void BaseWnd : : resize ( int x , int y , int w , int h , int wantcb )
{
inonresize = 1 ;
if ( x = = AUTOWH ) x = NOCHANGE ;
if ( y = = AUTOWH ) y = NOCHANGE ;
if ( w = = AUTOWH ) w = NOCHANGE ;
if ( h = = AUTOWH ) h = NOCHANGE ;
if ( getNumMinMaxEnforcers ( ) > 0 )
{
int min_w = getPreferences ( MINIMUM_W ) ;
int min_h = getPreferences ( MINIMUM_H ) ;
int max_w = getPreferences ( MAXIMUM_W ) ;
int max_h = getPreferences ( MAXIMUM_H ) ;
if ( min_w ! = AUTOWH & & w ! = NOCHANGE & & w < min_w ) w = min_w ;
if ( max_w ! = AUTOWH & & w ! = NOCHANGE & & w > max_w ) w = max_w ;
if ( min_h ! = AUTOWH & & h ! = NOCHANGE & & h < min_h ) h = min_h ;
if ( max_h ! = AUTOWH & & h ! = NOCHANGE & & h > max_h ) h = max_h ;
}
int noresize = ( w = = NOCHANGE & & h = = NOCHANGE ) ;
int nomove = ( x = = NOCHANGE & & y = = NOCHANGE ) /* || (x == rx && y == ry)*/ ;
if ( x = = NOCHANGE ) x = rx ;
if ( y = = NOCHANGE ) y = ry ;
if ( w = = NOCHANGE ) w = rwidth ;
if ( h = = NOCHANGE ) h = rheight ;
# ifdef _DEBUG
ASSERT ( x < 0xFFF0 ) ;
ASSERT ( y < 0xFFF0 ) ;
ASSERT ( w < 0xFFF0 ) ;
ASSERT ( h < 0xFFF0 ) ;
# endif
double thisratio = getRenderRatio ( ) ;
int different_ratio = ( lastratio ! = thisratio ) ;
lastratio = thisratio ;
int noevent = ( resizecount > 1 & & w = = rwidth & & h = = rheight ) ;
//ifc_window *dp = getDesktopParent();
if ( different_ratio = = 1 & & noevent = = 1 )
{
if ( Wasabi : : Std : : Wnd : : getTopmostChild ( getOsWindowHandle ( ) ) ! = INVALIDOSWINDOWHANDLE )
noevent = 0 ;
invalidateWindowRegion ( ) ;
}
RECT oldsize , newsize = Wasabi : : Std : : makeRect ( x , y , w , h ) ;
if ( hwnd ! = NULL )
BaseWnd : : getNonClientRect ( & oldsize ) ;
else
oldsize = newsize ;
setRSize ( x , y , w , h ) ;
if ( handleRatio ( ) & & renderRatioActive ( ) )
{
multRatio ( & w , & h ) ;
if ( getParent ( ) ! = NULL )
{
multRatio ( & x , & y ) ;
}
}
if ( ! noevent )
{
if ( wantcb & & isPostOnInit ( ) )
{
resizecount = MIN ( 5 , + + resizecount ) ;
if ( ! isVirtual ( ) )
invalidateWindowRegion ( ) ;
onResize ( ) ;
if ( ensureWindowRegionValid ( ) )
updateWindowRegion ( ) ;
}
}
if ( getOsWindowHandle ( ) ! = NULL )
{
RECT oldsizescaled ;
getWindowRect ( & oldsizescaled ) ;
RECT newsizescaled = { x , y , x + w , y + h } ;
if ( MEMCMP ( & newsizescaled , & oldsizescaled , sizeof ( RECT ) ) )
{
//CUT SetWindowPos(getOsWindowHandle(), NULL, x, y, w, h,
//CUT SWP_NOZORDER |
//CUT SWP_NOACTIVATE |
//CUT (!wantRedrawOnResize() ? SWP_NOCOPYBITS: 0) |
//CUT (ncb ? SWP_NOCOPYBITS : 0) |
//CUT ( nomove ? SWP_NOMOVE : 0) |
//CUT ( noresize ? SWP_NOSIZE : 0) |
//CUT 0);
Wasabi : : Std : : Wnd : : setWndPos ( getOsWindowHandle ( ) , NULL , x , y , w , h , TRUE , TRUE , ! wantRedrawOnResize ( ) | | ncb , nomove , noresize ) ;
}
//else
//{
// DebugStringW(L"BaseWnd::resize optimized\n");
//}
onAfterResize ( ) ;
if ( ncb )
invalidate ( ) ;
else
{
RECT r ;
if ( hwnd ! = NULL )
{
if ( newsize . left = = oldsize . left & & newsize . top = = oldsize . top )
{
if ( newsize . right > oldsize . right )
{
// growing in width
r . left = oldsize . right ;
r . right = newsize . right ;
r . top = newsize . top ;
r . bottom = newsize . bottom ;
invalidateRect ( & r ) ;
if ( newsize . bottom > oldsize . bottom )
{
// growing in width & height
r . left = oldsize . left ;
r . right = newsize . right ;
r . top = oldsize . bottom ;
r . bottom = newsize . bottom ;
invalidateRect ( & r ) ;
}
}
else if ( newsize . bottom > oldsize . bottom )
{
if ( newsize . bottom > oldsize . bottom )
{
// growing in height
r . left = oldsize . left ;
r . right = newsize . right ;
r . top = oldsize . bottom ;
r . bottom = newsize . bottom ;
invalidateRect ( & r ) ;
}
}
}
}
}
}
inonresize = 0 ;
}
void BaseWnd : : forcedOnResizeChain ( ifc_window * w )
{
w - > triggerEvent ( TRIGGER_ONRESIZE ) ;
int n = w - > getNumRootWndChildren ( ) ;
for ( int i = 0 ; i < n ; i + + )
{
forcedOnResizeChain ( w - > enumRootWndChildren ( i ) ) ;
}
}
int BaseWnd : : forcedOnResize ( )
{
forcedOnResizeChain ( this ) ;
return 1 ;
}
int BaseWnd : : onResize ( )
{
if ( ! isVirtual ( ) | | ( getRegionOp ( ) ! = REGIONOP_NONE ) )
invalidateWindowRegion ( ) ;
// you are not supposed to call onResize until after onInit has returned. If what you wanted was to generate
// an onResize event to do some custom client coordinates recalculations (ie: to apply on your children)
// then you don't need to do anything since onResize is going to be called after onInit() is done. If you still want to
// trigger it because your code might be called by onInit and after onInit, use isPostOnInit() as a test.
// if what you wanted was to signal a object that you just resized it, then you don't need to do anything beside
// resize(...), it will generate the event on its own if the window is inited, and will defer to until after onInit
// if it is not.
// shortly put: do not call onResize before or inside onInit()
// if you have any valid reason for doing that, i'd like to know about it so i can make it possible. -FG
# ifdef _DEBUG
if ( ! isPostOnInit ( ) )
{
//__asm int 3;
ASSERTPR ( isPostOnInit ( ) , " do not call onResize before or inside onInit() " ) ;
}
# endif
return FALSE ;
}
void BaseWnd : : resizeToClient ( BaseWnd * wnd )
{
if ( wnd ! = NULL )
wnd - > resize ( & clientRect ( ) ) ;
}
int BaseWnd : : onPostedMove ( )
{
/*
if ( w2k_alpha & & Wasabi : : Std : : Wnd : : isDesktopAlphaAvailable ( ) & & ! cloaked )
{
RECT r ;
getWindowRect ( & r ) ;
Wasabi : : Std : : Wnd : : moveLayeredWnd ( hwnd , r . left , r . top ) ;
} */
return FALSE ;
}
void BaseWnd : : resize ( RECT * r , int wantcb )
{
resize ( r - > left , r - > top , r - > right - r - > left , r - > bottom - r - > top , wantcb ) ;
}
void BaseWnd : : move ( int x , int y )
{
//DebugStringW( L"BaseWnd::move( x = %d, y = %d )\n", x, y );
setRSize ( x , y , rwidth , rheight ) ;
Wasabi : : Std : : Wnd : : setWndPos ( getOsWindowHandle ( ) , NULL , x , y , 0 , 0 , TRUE , TRUE , ncb , FALSE , TRUE ) ;
//CUT if (!ncb)
//CUT SetWindowPos(getOsWindowHandle(), NULL, x, y, 0, 0, SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_DEFERERASE);
//CUT else
//CUT SetWindowPos(getOsWindowHandle(), NULL, x, y, 0, 0, SWP_NOSIZE|SWP_NOZORDER|SWP_NOCOPYBITS|SWP_NOACTIVATE|SWP_DEFERERASE);
}
# ifdef EXPERIMENTAL_INDEPENDENT_AOT
BOOL CALLBACK EnumOwnedTopMostWindows ( HWND hwnd , LPARAM lParam )
{
enumownedstruct * st = ( enumownedstruct * ) lParam ;
if ( hwnd ! = st - > hthis & & GetWindow ( hwnd , GW_OWNER ) = = st - > owner )
{
ifc_window * w = ( ifc_window * ) GetWindowLong ( hwnd , GWL_USERDATA ) ;
if ( w ! = NULL & & w - > getAlwaysOnTop ( ) )
st - > hlist - > addItem ( w ) ;
}
return TRUE ;
}
void BaseWnd : : saveTopMosts ( )
{
HWND owner = GetWindow ( getOsWindowHandle ( ) , GW_OWNER ) ;
enumownedstruct st ;
ontoplist . removeAll ( ) ;
if ( owner ! = NULL )
{
st . owner = owner ;
st . hlist = & ontoplist ;
st . hthis = getOsWindowHandle ( ) ;
EnumWindows ( EnumOwnedTopMostWindows , ( long ) & st ) ;
}
}
void BaseWnd : : restoreTopMosts ( )
{
HWND owner = GetWindow ( getOsWindowHandle ( ) , GW_OWNER ) ;
if ( owner ! = NULL )
{
for ( int i = 0 ; i < ontoplist . getNumItems ( ) ; i + + )
{
ontoplist . enumItem ( i ) - > setAlwaysOnTop ( 1 ) ;
}
}
}
# endif
void BaseWnd : : bringToFront ( )
{
// when we set a window to the top of the zorder (not topmost), win32 finds the owner and removes any topmost flag its children may
// have because it assumes we want this window over these, which we definitly don't. so we need to first go thru all the owner's children,
// make a list of the ones with a topmost flag, set this window on top, and set the topmost flags back. yay
ASSERT ( ! isVirtual ( ) ) ;
# ifdef EXPERIMENTAL_INDEPENDENT_AOT
saveTopMosts ( ) ;
# endif
//CUT SetWindowPos(getOsWindowHandle(), HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE|SWP_DEFERERASE|SWP_NOOWNERZORDER);
Wasabi : : Std : : Wnd : : bringToFront ( getOsWindowHandle ( ) ) ;
# ifdef EXPERIMENTAL_INDEPENDENT_AOT
restoreTopMosts ( ) ;
# endif
}
void BaseWnd : : bringToBack ( )
{
ASSERT ( ! isVirtual ( ) ) ;
# ifdef EXPERIMENTAL_INDEPENDENT_AOT
saveTopMosts ( ) ;
# endif
//CUT SetWindowPos(getOsWindowHandle(), HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE|SWP_DEFERERASE|SWP_NOOWNERZORDER);
Wasabi : : Std : : Wnd : : sendToBack ( getOsWindowHandle ( ) ) ;
# ifdef EXPERIMENTAL_INDEPENDENT_AOT
restoreTopMosts ( ) ;
# endif
}
void BaseWnd : : setVisible ( int show )
{
int visible = isVisible ( 1 ) ;
if ( ! ! visible = = ! ! show ) return ;
invalidate ( ) ;
this_visible = ! ! show ;
/*if (!getParent() || getParent() == WASABI_API_WND->main_getRootWnd() && IsWindow(getOsWindowHandle())) {
if ( ! show ) {
setLayeredWindow ( 0 ) ;
if ( setLayeredWindowAttributes )
setLayeredWindowAttributes ( hwnd , RGB ( 0 , 0 , 0 ) , 255 , LWA_ALPHA ) ;
} else {
setLayeredWindow ( w2k_alpha ) ;
}
} */
if ( ! getParent ( ) | | getParent ( ) = = WASABI_API_WND - > main_getRootWnd ( ) | | getParent ( ) - > isVisible ( ) )
{
onSetVisible ( show ) ;
}
}
void BaseWnd : : setCloaked ( int cloak )
{
if ( cloaked = = cloak ) return ;
cloaked = cloak ;
if ( isVirtual ( ) ) return ;
if ( cloaked )
{
//CUTif (IsWindowVisible(getOsWindowHandle()))
//CUT ShowWindow(getOsWindowHandle(), SW_HIDE);
if ( Wasabi : : Std : : Wnd : : isWndVisible ( getOsWindowHandle ( ) ) )
Wasabi : : Std : : Wnd : : hideWnd ( getOsWindowHandle ( ) ) ;
}
else
{
if ( isVisible ( 1 ) )
//CUTShowWindow(getOsWindowHandle(), SW_NORMAL);
Wasabi : : Std : : Wnd : : showWnd ( getOsWindowHandle ( ) ) ;
}
}
void BaseWnd : : onSetVisible ( int show )
{
/* for debug purposes - don't delete please
# include "../../../studio/container.h"
# include "../../../studio/layout.h"
if ( ! show & & getGuiObject ( ) & & STRCASEEQLSAFE ( getGuiObject ( ) - > guiobject_getId ( ) , " normal " ) ) {
Layout * l = ( Layout * ) getInterface ( layoutGuid ) ;
if ( l ) {
if ( l - > getParentContainer ( ) & & STRCASEEQLSAFE ( l - > getParentContainer ( ) - > getId ( ) , " main " ) ) {
DebugString ( " Hiding main player \n " ) ;
}
}
} */
if ( ! isVirtual ( ) )
if ( hwnd ! = NULL )
if ( ! cloaked )
{
//CUT // SetWindowPos(getOsWindowHandle(),NULL,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|SWP_NOZORDER|SWP_SHOWWINDOW);
//CUT ShowWindow(getOsWindowHandle(), show ? SW_SHOWNA : SW_HIDE);
if ( show )
Wasabi : : Std : : Wnd : : showWnd ( getOsWindowHandle ( ) , TRUE ) ;
else
Wasabi : : Std : : Wnd : : hideWnd ( getOsWindowHandle ( ) ) ;
}
/* if (!show)
postDeferredCallback ( 0x7849 ) ;
else { */
foreach ( rootwndchildren )
ifc_window * w = rootwndchildren . getfor ( ) ;
if ( w & & w - > isVisible ( 1 ) ) // check internal flag only
w - > onSetVisible ( show ) ;
endfor ;
dependent_sendEvent ( BaseWnd : : depend_getClassGuid ( ) , Event_SETVISIBLE , show ) ;
//}
/* if (getDesktopParent() == this) {
cascadeRepaint ( 0 ) ;
} */
/*#ifdef WIN32 // os-specific non virtual child wnd support
if ( ! isVirtual ( ) ) {
HWND w = GetWindow ( getOsWindowHandle ( ) , GW_CHILD ) ;
while ( w ! = NULL ) {
api_window * rootwnd = ( api_window * ) GetWindowLong ( w , GWL_USERDATA ) ;
if ( rootwnd & & rootwnd ! = this )
if ( rootwnd - > isInited ( ) )
rootwnd - > onSetVisible ( show ) ;
w = GetWindow ( w , GW_HWNDNEXT ) ;
}
}
# endif* /
if ( ! isVirtual ( ) )
{
if ( ! show )
{
deferedInvalidate ( ) ;
delete virtualCanvas ;
virtualCanvas = NULL ;
}
}
invalidateWindowRegion ( ) ;
}
void BaseWnd : : setEnabled ( int en )
{
int enabled = isEnabled ( 1 ) ;
if ( ! ! enabled = = ! ! en ) return ;
invalidate ( ) ;
this_enabled = ! ! en ;
if ( ! getParent ( ) | | getParent ( ) = = WASABI_API_WND - > main_getRootWnd ( ) | | getParent ( ) - > isEnabled ( ) )
{
onEnable ( en ) ;
}
}
int BaseWnd : : isEnabled ( int within )
{
if ( ! isVirtual ( ) & & ! getOsWindowHandle ( ) ) return 0 ;
if ( ! this_enabled ) return 0 ;
if ( within ) return this_enabled ; // whatever, local
if ( isVirtual ( ) ) // virtual, global
if ( getParent ( ) )
return getParent ( ) - > isEnabled ( ) ;
else
return 0 ;
// non virtual, global
//CUT if (GetWindowLong(getOsWindowHandle(), GWL_STYLE) & WS_POPUP) return this_enabled;
if ( Wasabi : : Std : : Wnd : : isPopup ( getOsWindowHandle ( ) ) ) return this_enabled ;
//CUT if (!Wasabi::Std::Wnd::isValidWnd(GetParent(gethWnd()))) return this_enabled;
if ( ! Wasabi : : Std : : Wnd : : isValidWnd ( Wasabi : : Std : : Wnd : : getParent ( getOsWindowHandle ( ) ) ) ) return this_enabled ;
if ( getParent ( ) ) return getParent ( ) - > isEnabled ( ) ; // not a popup, check its parent or fail
return this_enabled ;
}
int BaseWnd : : onEnable ( int en )
{
if ( ! isVirtual ( ) )
{
if ( hwnd ! = NULL )
//CUT EnableWindow(getOsWindowHandle(), en);
Wasabi : : Std : : Wnd : : setEnabled ( getOsWindowHandle ( ) , en ) ;
foreach ( rootwndchildren )
ifc_window * w = rootwndchildren . getfor ( ) ;
if ( w - > isEnabled ( 1 ) ) // check internal flag only
w - > onEnable ( en ) ;
endfor ;
}
return 1 ;
}
void BaseWnd : : setFocus ( )
{
if ( curVirtualChildFocus ! = NULL )
{
curVirtualChildFocus - > onKillFocus ( ) ;
curVirtualChildFocus = NULL ;
}
onSetRootFocus ( this ) ;
//CUT SetFocus(getOsWindowHandle());
Wasabi : : Std : : Wnd : : setFocus ( getOsWindowHandle ( ) ) ;
}
void BaseWnd : : setFocusOnClick ( int f )
{
focus_on_click = f ;
}
api_region * BaseWnd : : getDeferedInvalidRgn ( )
{
return deferedInvalidRgn ;
}
void BaseWnd : : deferedInvalidate ( )
{
if ( ! hasVirtualChildren ( ) | | ! isVisible ( 1 ) ) return ;
RECT r = Wasabi : : Std : : makeRect ( 0 , 0 , 0 , 0 ) ;
getNonClientRect ( & r ) ;
deferedInvalidateRect ( & r ) ;
}
void BaseWnd : : deferedInvalidateRect ( RECT * r )
{
if ( ! hasVirtualChildren ( ) ) return ;
RegionI h ( r ) ;
deferedInvalidateRgn ( & h ) ;
}
void BaseWnd : : deferedInvalidateRgn ( api_region * h )
{
if ( ! hasVirtualChildren ( ) ) return ;
if ( ! deferedInvalidRgn )
{
deferedInvalidRgn = new RegionI ( ) ;
}
deferedInvalidRgn - > addRegion ( h ) ;
}
void BaseWnd : : deferedValidate ( )
{
if ( ! hasVirtualChildren ( ) | | ! isVisible ( 1 ) ) return ;
RECT r = Wasabi : : Std : : makeRect ( 0 , 0 , 0 , 0 ) ;
getNonClientRect ( & r ) ;
deferedValidateRect ( & r ) ;
}
void BaseWnd : : deferedValidateRect ( RECT * r )
{
if ( ! hasVirtualChildren ( ) ) return ;
RegionI h ( r ) ;
deferedValidateRgn ( & h ) ;
}
void BaseWnd : : deferedValidateRgn ( api_region * h )
{
if ( ! hasVirtualChildren ( ) ) return ;
if ( ! deferedInvalidRgn ) return ;
deferedInvalidRgn - > subtractRgn ( h ) ;
}
int BaseWnd : : hasVirtualChildren ( )
{
return 1 ; //virtualChildren.getNumItems() > 0;
}
void BaseWnd : : invalidate ( )
{
invalidateFrom ( this ) ;
}
void BaseWnd : : invalidateFrom ( ifc_window * who )
{
if ( hasVirtualChildren ( ) ) deferedInvalidate ( ) ;
//CUT if (hwnd != NULL && isVisible(1)) InvalidateRect(getOsWindowHandle(), NULL, FALSE);
if ( hwnd ! = NULL & & isVisible ( 1 ) )
Wasabi : : Std : : Wnd : : invalidateRect ( getOsWindowHandle ( ) ) ;
}
void BaseWnd : : invalidateRectFrom ( RECT * r , ifc_window * who )
{
if ( hasVirtualChildren ( ) ) deferedInvalidateRect ( r ) ;
RegionI rg ( r ) ;
invalidateRgnFrom ( & rg , who ) ;
}
void BaseWnd : : invalidateRgn ( api_region * r )
{
invalidateRgnFrom ( r , this ) ;
}
void BaseWnd : : invalidateRect ( RECT * r )
{
invalidateRectFrom ( r , this ) ;
}
void BaseWnd : : invalidateRgnFrom ( api_region * r , ifc_window * who )
{
if ( parentWnd ) parentWnd - > onChildInvalidate ( r , who ) ;
PaintCallbackInfoI pc ( NULL , r ) ;
dependent_sendEvent ( BaseWnd : : depend_getClassGuid ( ) , Event_ONINVALIDATE , 0 , & pc ) ;
if ( hwnd ! = NULL & & isVisible ( 1 ) )
{
if ( hasVirtualChildren ( ) )
{
api_region * _r = r - > clone ( ) ;
int j = virtualChildren . searchItem ( who ) ;
for ( int i = 0 ; i < virtualChildren . getNumItems ( ) ; i + + )
{
ifc_window * w = virtualChildren [ i ] ;
if ( w ! = who & & w - > wantSiblingInvalidations ( ) )
w - > onSiblingInvalidateRgn ( _r , who , j , i ) ;
}
deferedInvalidateRgn ( _r ) ;
physicalInvalidateRgn ( _r ) ;
r - > disposeClone ( _r ) ;
}
else
{
deferedInvalidateRgn ( r ) ;
physicalInvalidateRgn ( r ) ;
}
}
}
void BaseWnd : : physicalInvalidateRgn ( api_region * r )
{
if ( hwnd ! = NULL & & isVisible ( 1 ) )
{
if ( renderRatioActive ( ) )
{
api_region * clone = r - > clone ( ) ;
clone - > scale ( getRenderRatio ( ) , getRenderRatio ( ) , TRUE ) ;
//CUT InvalidateRgn(getOsWindowHandle(), clone->getOSHandle(), FALSE);
Wasabi : : Std : : Wnd : : invalidateRegion ( getOsWindowHandle ( ) , clone - > getOSHandle ( ) ) ;
r - > disposeClone ( clone ) ;
}
else
//CUT InvalidateRgn(getOsWindowHandle(), r->getOSHandle(), FALSE);
Wasabi : : Std : : Wnd : : invalidateRegion ( getOsWindowHandle ( ) , r - > getOSHandle ( ) ) ;
}
}
void BaseWnd : : validate ( )
{
//CUT if (hwnd != NULL) ValidateRect(getOsWindowHandle(), NULL);
if ( hwnd ! = NULL )
Wasabi : : Std : : Wnd : : validateRect ( getOsWindowHandle ( ) ) ;
}
void BaseWnd : : validateRect ( RECT * r )
{
if ( hwnd ! = NULL )
{
if ( renderRatioActive ( ) )
{
RECT r2 = * r ;
Wasabi : : Std : : scaleRect ( & r2 , getRenderRatio ( ) ) ;
//CUT ValidateRect(getOsWindowHandle(), &r2);
Wasabi : : Std : : Wnd : : validateRect ( getOsWindowHandle ( ) , & r2 ) ;
}
else
//CUT ValidateRect(getOsWindowHandle(), r);
Wasabi : : Std : : Wnd : : validateRect ( getOsWindowHandle ( ) , r ) ;
}
}
void BaseWnd : : validateRgn ( api_region * reg )
{
if ( hwnd ! = NULL )
{
if ( renderRatioActive ( ) )
{
api_region * clone = reg - > clone ( ) ;
clone - > scale ( getRenderRatio ( ) , getRenderRatio ( ) , TRUE ) ;
//CUT ValidateRgn(getOsWindowHandle(), clone->getOSHandle());
Wasabi : : Std : : Wnd : : validateRegion ( getOsWindowHandle ( ) , clone - > getOSHandle ( ) ) ;
reg - > disposeClone ( clone ) ;
}
else
//CUT ValidateRgn(getOsWindowHandle(), reg->getOSHandle());
Wasabi : : Std : : Wnd : : validateRegion ( getOsWindowHandle ( ) , reg - > getOSHandle ( ) ) ;
}
}
void BaseWnd : : repaint ( )
{
/* if (hasVirtualChildren()) {
api_region * h = new api_region ( ) ;
int s = GetUpdateRgn ( getOsWindowHandle ( ) , h - > getHRGN ( ) , FALSE ) ;
if ( s ! = NULLREGION & & s ! = ERROR ) {
virtualDrawRgn ( h ) ;
}
delete h ;
} */
//CUTif (hwnd != NULL) UpdateWindow(getOsWindowHandle());
if ( hwnd ! = NULL )
Wasabi : : Std : : Wnd : : update ( getOsWindowHandle ( ) ) ;
}
void BaseWnd : : getClientRect ( RECT * rect )
{
/* rect->left = rx;
rect - > right = rx + rwidth ;
rect - > top = ry ;
rect - > bottom = ry + rheight ; */
//ASSERT(hwnd != NULL);
if ( ! Wasabi : : Std : : Wnd : : isValidWnd ( hwnd ) )
{
MEMSET ( rect , 0 , sizeof ( RECT ) ) ;
return ;
}
GetClientRect ( getOsWindowHandle ( ) , rect ) ;
////Wasabi::Std::Wnd::getClientRect(getOsWindowHandle(), rect);
rect - > right = rect - > left + rwidth ;
rect - > bottom = rect - > top + rheight ;
}
RECT BaseWnd : : clientRect ( )
{
RECT ret ;
getClientRect ( & ret ) ;
return ret ;
}
void BaseWnd : : getNonClientRect ( RECT * rect )
{
// ASSERT(hwnd != NULL);
if ( ! hwnd )
getClientRect ( rect ) ;
else
{
Wasabi : : Std : : Wnd : : getClientRect ( getOsWindowHandle ( ) , rect ) ;
if ( getRenderRatio ( ) ! = 1.0 )
{
rect - > right = rect - > left + rwidth ;
rect - > bottom = rect - > left + rheight ;
}
}
/* rect->left = rx;
rect - > right = rx + rwidth ;
rect - > top = ry ;
rect - > bottom = ry + rheight ; */
}
RECT BaseWnd : : nonClientRect ( )
{
RECT ret ;
getNonClientRect ( & ret ) ;
return ret ;
}
void BaseWnd : : getWindowRect ( RECT * rect )
{
//CUT#ifdef WIN32
//CUT ASSERT(hwnd != NULL);
//CUT GetWindowRect(getOsWindowHandle(), rect);
//CUT#else
//CUT#error port me
//CUT#endif
Wasabi : : Std : : Wnd : : getWindowRect ( getOsWindowHandle ( ) , rect ) ;
}
// get position relative to parent (same coordinate system for basewnd & virtualwnd)
void BaseWnd : : getPosition ( POINT * pt )
{
pt - > x = rx ;
pt - > y = ry ;
}
void * BaseWnd : : dependent_getInterface ( const GUID * classguid )
{
HANDLEGETINTERFACE ( ifc_window ) ;
//CUT HANDLEGETINTERFACE(api_window);
return NULL ;
}
RECT BaseWnd : : windowRect ( )
{
RECT ret ;
getWindowRect ( & ret ) ;
return ret ;
}
void BaseWnd : : clientToScreen ( int * x , int * y )
{
int _x = x ? * x : 0 ;
int _y = y ? * y : 0 ;
if ( renderRatioActive ( ) )
{
_x = ( int ) ( ( double ) _x * getRenderRatio ( ) ) ;
_y = ( int ) ( ( double ) _y * getRenderRatio ( ) ) ;
}
Wasabi : : Std : : Wnd : : clientToScreen ( getOsWindowHandle ( ) , & _x , & _y ) ;
if ( x ) * x = _x ;
if ( y ) * y = _y ;
}
void BaseWnd : : clientToScreen ( RECT * r )
{
clientToScreen ( ( int * ) & r - > left , ( int * ) & r - > top ) ;
clientToScreen ( ( int * ) & r - > right , ( int * ) & r - > bottom ) ;
}
void BaseWnd : : clientToScreen ( POINT * p )
{
clientToScreen ( ( int * ) & p - > x , ( int * ) & p - > y ) ;
}
void BaseWnd : : screenToClient ( int * x , int * y )
{
//CUT POINT p;
int _x = x ? * x : 0 ;
int _y = y ? * y : 0 ;
//CUT ScreenToClient(getOsWindowHandle(), &p);
Wasabi : : Std : : Wnd : : screenToClient ( getOsWindowHandle ( ) , & _x , & _y ) ;
if ( renderRatioActive ( ) )
{
_x = ( int ) ( ( double ) _x / getRenderRatio ( ) ) ;
_y = ( int ) ( ( double ) _y / getRenderRatio ( ) ) ;
}
if ( x ) * x = _x ;
if ( y ) * y = _y ;
}
void BaseWnd : : screenToClient ( RECT * r )
{
screenToClient ( ( int * ) & r - > left , ( int * ) & r - > top ) ;
screenToClient ( ( int * ) & r - > right , ( int * ) & r - > bottom ) ;
}
void BaseWnd : : screenToClient ( POINT * p )
{
screenToClient ( ( int * ) & p - > x , ( int * ) & p - > y ) ;
}
void BaseWnd : : setParent ( ifc_window * newparent )
{
ASSERTPR ( newparent ! = NULL , " quit being a weeny " ) ;
ASSERTPR ( parentWnd = = NULL | | newparent = = parentWnd , " can't reset parent " ) ;
parentWnd = newparent ;
if ( isInited ( ) )
{
OSWINDOWHANDLE w1 = getOsWindowHandle ( ) ;
OSWINDOWHANDLE w2 = newparent - > getOsWindowHandle ( ) ;
if ( w1 ! = w2 )
//CUT SetParent(w1, w2);
Wasabi : : Std : : Wnd : : setParent ( w1 , w2 ) ;
}
}
//FUCKO
int BaseWnd : : reparent ( ifc_window * newparent )
{
# ifdef _WIN32
if ( ! isVirtual ( ) )
{
if ( isInited ( ) )
{
ifc_window * old = getParent ( ) ;
if ( ! old & & newparent )
{
: : SetParent ( getOsWindowHandle ( ) , newparent - > getOsWindowHandle ( ) ) ;
SetWindowLong ( getOsWindowHandle ( ) , GWL_STYLE , GetWindowLong ( getOsWindowHandle ( ) , GWL_STYLE ) & ~ WS_POPUP ) ;
SetWindowLong ( getOsWindowHandle ( ) , GWL_STYLE , GetWindowLong ( getOsWindowHandle ( ) , GWL_STYLE ) | WS_CHILD ) ;
}
else if ( old & & ! newparent )
{
SetWindowLong ( getOsWindowHandle ( ) , GWL_STYLE , GetWindowLong ( getOsWindowHandle ( ) , GWL_STYLE ) & ~ WS_CHILD ) ;
SetWindowLong ( getOsWindowHandle ( ) , GWL_STYLE , GetWindowLong ( getOsWindowHandle ( ) , GWL_STYLE ) | WS_POPUP ) ;
: : SetParent ( getOsWindowHandle ( ) , NULL ) ;
}
else
{
: : SetParent ( getOsWindowHandle ( ) , newparent ? newparent - > getOsWindowHandle ( ) : NULL ) ;
}
}
}
parentWnd = newparent ;
onSetParent ( newparent ) ;
# ifdef WASABI_ON_REPARENT
WASABI_ON_REPARENT ( getOsWindowHandle ( ) ) ;
# endif
# else
# warning port me
# endif
return 1 ;
}
ifc_window * BaseWnd : : getParent ( )
{
return parentWnd ;
}
ifc_window * BaseWnd : : getRootParent ( )
{
return this ;
}
//PORTME
ifc_window * BaseWnd : : getDesktopParent ( )
{
# ifdef _WIN32
// NONPORTABLE
HWND w = getOsWindowHandle ( ) ;
HWND last = w ;
if ( ! w ) return NULL ;
HWND p = w ;
wchar_t cn [ 256 ] = { 0 } ;
while ( p & & ! ( GetWindowLong ( p , GWL_STYLE ) & WS_POPUP ) )
{
GetClassNameW ( p , cn , 255 ) ; cn [ 255 ] = 0 ;
if ( ! wcscmp ( cn , BASEWNDCLASSNAME ) )
last = p ;
p = GetParent ( p ) ;
}
if ( p )
{
GetClassNameW ( p , cn , 255 ) ; cn [ 255 ] = 0 ;
if ( ! wcscmp ( cn , BASEWNDCLASSNAME ) )
return ( ifc_window * ) GetWindowLongPtrW ( p , GWLP_USERDATA ) ;
else if ( last ! = NULL )
return ( ifc_window * ) GetWindowLongPtrW ( last , GWLP_USERDATA ) ;
}
# else
# warning port me
# endif
return NULL ;
}
int BaseWnd : : notifyParent ( int msg , int param1 , int param2 )
{
ifc_window * notifywnd = getNotifyWindow ( ) ;
if ( getParent ( ) = = NULL & & notifywnd = = NULL ) return 0 ;
if ( notifywnd = = NULL ) notifywnd = getParent ( ) ;
ASSERT ( notifywnd ! = NULL ) ;
return notifywnd - > childNotify ( this , msg , param1 , param2 ) ;
}
int BaseWnd : : passNotifyUp ( ifc_window * child , int msg , int param1 , int param2 )
{
// Same code as above to decide for whom we should notify.
ifc_window * notifywnd = getNotifyWindow ( ) ;
if ( getParent ( ) = = NULL & & notifywnd = = NULL ) return 0 ;
if ( notifywnd = = NULL ) notifywnd = getParent ( ) ;
ASSERT ( notifywnd ! = NULL ) ;
// And here we just change the api_window pointer.
return notifywnd - > childNotify ( child , msg , param1 , param2 ) ;
}
void BaseWnd : : setNotifyId ( int id )
{
notifyid = id ;
}
int BaseWnd : : getNotifyId ( )
{
return notifyid ;
}
DragInterface * BaseWnd : : getDragInterface ( )
{
return this ;
}
ifc_window * BaseWnd : : rootWndFromPoint ( POINT * pt )
{
// pt is in client coordinates
int x = ( int ) ( ( double ) pt - > x / getRenderRatio ( ) ) ;
int y = ( int ) ( ( double ) pt - > y / getRenderRatio ( ) ) ;
ifc_window * ret = findRootWndChild ( x , y ) ;
if ( ret = = NULL ) ret = this ;
return ret ;
}
int BaseWnd : : rootwnd_paintTree ( ifc_canvas * canvas , api_region * r )
{
BaseCloneCanvas c ( canvas ) ;
return paintTree ( & c , r ) ;
}
const wchar_t * BaseWnd : : getRootWndName ( )
{
return getName ( ) ;
}
const wchar_t * BaseWnd : : getId ( )
{
return NULL ;
}
void BaseWnd : : setSkinId ( int id )
{
skin_id = id ;
}
void BaseWnd : : setPreferences ( int what , int v )
{
switch ( what )
{
case MAXIMUM_W : maximum_w = v ; break ;
case MAXIMUM_H : maximum_h = v ; break ;
case MINIMUM_W : minimum_w = v ; break ;
case MINIMUM_H : minimum_h = v ; break ;
case SUGGESTED_W : suggested_w = v ; break ;
case SUGGESTED_H : suggested_h = v ; break ;
}
}
int BaseWnd : : getPreferences ( int what )
{
if ( getNumMinMaxEnforcers ( ) > 0 )
{
int min_x = minimum_w , min_y = minimum_h , max_x = maximum_w , max_y = maximum_h , sug_x = suggested_w , sug_y = suggested_h ;
for ( int i = 0 ; i < getNumMinMaxEnforcers ( ) ; i + + )
{
int tmin_x = MINIMUM_W , tmin_y = MINIMUM_H , tmax_x = MAXIMUM_W , tmax_y = MAXIMUM_H , tsug_x = SUGGESTED_W , tsug_y = SUGGESTED_H ;
ifc_window * w = enumMinMaxEnforcer ( i ) ;
if ( w )
{
tmin_x = w - > getPreferences ( MINIMUM_W ) ;
tmin_y = w - > getPreferences ( MINIMUM_H ) ;
tmax_x = w - > getPreferences ( MAXIMUM_W ) ;
tmax_y = w - > getPreferences ( MAXIMUM_H ) ;
tsug_x = w - > getPreferences ( SUGGESTED_W ) ;
tsug_y = w - > getPreferences ( SUGGESTED_H ) ;
if ( tmin_x = = - 1 ) tmin_x = AUTOWH ;
if ( tmin_y = = - 1 ) tmin_y = AUTOWH ;
if ( tmax_x = = - 1 ) tmax_x = AUTOWH ;
if ( tmax_y = = - 1 ) tmax_y = AUTOWH ;
if ( tsug_x = = - 1 ) tsug_x = AUTOWH ;
if ( tsug_y = = - 1 ) tsug_y = AUTOWH ;
# ifndef DISABLE_SYSFONTSCALE
TextInfoCanvas textInfoCanvas ( this ) ;
double fontScale = textInfoCanvas . getSystemFontScale ( ) ;
GuiObject * o = static_cast < GuiObject * > ( getInterface ( guiObjectGuid ) ) ;
if ( o ! = NULL )
{
if ( o - > guiobject_getAutoSysMetricsW ( ) )
{
if ( tmin_x ! = AUTOWH ) tmin_x = ( int ) ( ( float ) tmin_x * fontScale ) ;
if ( tmax_x ! = AUTOWH ) tmax_x = ( int ) ( ( float ) tmax_x * fontScale ) ;
if ( tsug_x ! = AUTOWH ) tsug_x = ( int ) ( ( float ) tsug_x * fontScale ) ;
}
if ( o - > guiobject_getAutoSysMetricsH ( ) )
{
if ( tmin_y ! = AUTOWH ) tmin_y = ( int ) ( ( float ) tmin_y * fontScale ) ;
if ( tmax_y ! = AUTOWH ) tmax_y = ( int ) ( ( float ) tmax_y * fontScale ) ;
if ( tsug_y ! = AUTOWH ) tsug_y = ( int ) ( ( float ) tsug_y * fontScale ) ;
}
}
# endif
RECT cor ;
w - > getNonClientRect ( & cor ) ;
RECT wr ;
getNonClientRect ( & wr ) ;
int xdif = ( wr . right - wr . left ) - ( cor . right - cor . left ) ;
int ydif = ( wr . bottom - wr . top ) - ( cor . bottom - cor . top ) ;
if ( tmin_x ! = AUTOWH ) tmin_x + = xdif ;
if ( tmin_y ! = AUTOWH ) tmin_y + = ydif ;
if ( tmax_x ! = AUTOWH ) tmax_x + = xdif ;
if ( tmax_y ! = AUTOWH ) tmax_y + = ydif ;
if ( tsug_x ! = AUTOWH ) tsug_x + = xdif ;
if ( tsug_y ! = AUTOWH ) tsug_y + = ydif ;
}
if ( min_x ! = AUTOWH ) min_x = ( tmin_x ! = AUTOWH ) ? MAX ( min_x , tmin_x ) : min_x ; else min_x = tmin_x ;
if ( max_x ! = AUTOWH ) max_x = ( tmax_x ! = AUTOWH ) ? MAX ( max_x , tmax_x ) : max_x ; else max_x = tmax_x ;
if ( min_y ! = AUTOWH ) min_y = ( tmin_y ! = AUTOWH ) ? MAX ( min_y , tmin_y ) : min_y ; else min_y = tmin_y ;
if ( max_y ! = AUTOWH ) max_y = ( tmax_y ! = AUTOWH ) ? MAX ( max_y , tmax_y ) : max_y ; else max_y = tmax_y ;
if ( sug_x ! = AUTOWH ) sug_x = ( tsug_x ! = AUTOWH ) ? MAX ( sug_x , tsug_x ) : sug_x ; else sug_x = tsug_x ;
if ( sug_y ! = AUTOWH ) sug_y = ( tsug_y ! = AUTOWH ) ? MAX ( sug_y , tsug_y ) : sug_y ; else sug_y = tsug_y ;
}
if ( min_x ! = AUTOWH & & min_x = = max_x ) sug_x = min_x ;
if ( min_y ! = AUTOWH & & min_y = = max_y ) sug_y = min_y ;
switch ( what )
{
case MINIMUM_W : return min_x ;
case MINIMUM_H : return min_y ;
case MAXIMUM_W : return max_x ;
case MAXIMUM_H : return max_y ;
case SUGGESTED_W : return sug_x ;
case SUGGESTED_H : return sug_y ;
}
}
switch ( what )
{
case SUGGESTED_W : return suggested_w ;
case SUGGESTED_H : return suggested_h ;
case MAXIMUM_W : return maximum_w ;
case MAXIMUM_H : return maximum_h ;
case MINIMUM_W : return minimum_w ;
case MINIMUM_H : return minimum_h ;
}
return AUTOWH ;
}
void BaseWnd : : setStartHidden ( int wtf )
{
start_hidden = wtf ;
}
//PORTME
# ifdef _WIN32
# define EQUAL_CLSNAME(__name1, __name2)\
( CSTR_EQUAL = = CompareStringW ( MAKELCID ( MAKELANGID ( LANG_ENGLISH , SUBLANG_ENGLISH_US ) , SORT_DEFAULT ) , \
NORM_IGNORECASE , ( __name1 ) , - 1 , ( __name2 ) , - 1 ) )
static BOOL BaseWnd_IsFrameWindow ( HWND hwnd )
{
WCHAR szClass [ 64 ] = { 0 } ;
if ( NULL = = hwnd | | ! GetClassNameW ( hwnd , szClass , ARRAYSIZE ( szClass ) ) )
return FALSE ;
return EQUAL_CLSNAME ( szClass , L " Winamp v1.x " ) | |
EQUAL_CLSNAME ( szClass , L " BaseWindow_RootWnd " ) ;
}
LRESULT BaseWnd : : wndProc ( HWND hWnd , UINT uMsg , WPARAM wParam , LPARAM lParam )
{
if ( ! isDestroying ( ) ) switch ( uMsg )
{
case WM_DEFER_CALLBACK :
timerclient_onDeferredCallback ( wParam , lParam ) ;
break ;
case WM_SYSCOMMAND :
{
if ( ( wParam & 0xfff0 ) = = SC_SCREENSAVE | | ( wParam & 0xfff0 ) = = SC_MONITORPOWER )
{
ifc_window * main = WASABI_API_WND - > main_getRootWnd ( ) ;
if ( main & & main ! = this )
return SendMessageW ( main - > gethWnd ( ) , uMsg , wParam , lParam ) ;
}
break ;
}
//CUT case WM_CREATE:
//CUT hwnd = hWnd;
//CUT break;
//CUT case WM_CLOSE:
//CUT return 0;
case WM_PAINT :
{
if ( inonresize & & ! wantRedrawOnResize ( ) ) return 1 ;
ASSERT ( hwnd ! = NULL ) ;
if ( ! isVisible ( 1 ) | | IsIconic ( hWnd ) ) break ;
RECT r ;
if ( GetUpdateRect ( hWnd , & r , FALSE ) )
{
if ( virtualOnPaint ( ) )
{
return 0 ;
}
}
}
break ;
case WM_PRINTCLIENT :
{
bool old_cloaked = ( ! ! cloaked ) ;
cloaked = true ;
DCCanvas dc ( ( HDC ) wParam , this ) ;
paint ( & dc , 0 ) ;
cloaked = old_cloaked ;
if ( lParam & PRF_CHILDREN )
{
RECT wnd_size ;
GetWindowRect ( hwnd , & wnd_size ) ;
HWND child = GetWindow ( hwnd , GW_CHILD ) ;
while ( child ! = NULL )
{
if ( GetWindowLongPtrW ( child , GWL_STYLE ) & WS_VISIBLE )
{
RECT child_size ;
GetWindowRect ( child , & child_size ) ;
if ( child_size . right & & child_size . bottom )
{
BltCanvas bitmap ( child_size . right , child_size . bottom , child ) ; ;
SendMessageW ( child , WM_PRINT , ( WPARAM ) bitmap . getHDC ( ) , PRF_CHILDREN | PRF_CLIENT | PRF_NONCLIENT /*| PRF_OWNED*/ ) ;
//bitmap->makeAlpha(255);
//set alpha to 255
int w , h ;
bitmap . getDim ( & w , & h , NULL ) ;
ARGB32 * m_pBits = ( ARGB32 * ) bitmap . getBits ( ) ;
int nwords = w * h ;
for ( ; nwords > 0 ; nwords - - , m_pBits + + )
{
unsigned char * pixel = ( unsigned char * ) m_pBits ;
pixel [ 3 ] = 255 ; // alpha
}
POINT offset ;
offset . x = child_size . left - wnd_size . left ;
offset . y = child_size . top - wnd_size . top ;
//BLENDFUNCTION blendFn;
//blendFn.BlendOp = AC_SRC_OVER;
//blendFn.BlendFlags = 0;
//blendFn.SourceConstantAlpha = 255;
//blendFn.AlphaFormat = 0;
//AlphaBlend((HDC)wParam, offset.x, offset.y, child_size.right-child_size.left, child_size.bottom-child_size.top,
// bitmap->getHDC(), 0, 0, child_size.right-child_size.left, child_size.bottom-child_size.top, blendFn);
StretchBlt ( ( HDC ) wParam , offset . x , offset . y , child_size . right - child_size . left , child_size . bottom - child_size . top ,
bitmap . getHDC ( ) , 0 , 0 , child_size . right - child_size . left , child_size . bottom - child_size . top , SRCCOPY ) ;
}
}
child = GetWindow ( child , GW_HWNDNEXT ) ;
}
}
}
return 0 ;
//CUT case WM_NCPAINT: return 0;
//CUT case WM_SYNCPAINT: return 0;
case WM_SETCURSOR :
if ( checkModal ( ) ) return TRUE ;
if ( hWnd = = ( HWND ) wParam )
{
DWORD windowStyle = ( DWORD ) GetWindowLongPtrW ( hWnd , GWL_STYLE ) ;
switch ( HIWORD ( lParam ) )
{
case WM_LBUTTONDOWN :
case WM_RBUTTONDOWN :
case WM_MBUTTONDOWN :
case 0x020B /*WM_XBUTTONDOWN*/ :
DisabledWindow_OnMouseClick ( hWnd ) ;
break ;
}
int ct = BASEWND_CURSOR_POINTER ;
int _x , _y ;
Wasabi : : Std : : getMousePos ( & _x , & _y ) ;
screenToClient ( & _x , & _y ) ;
OSCURSORHANDLE c = NULL ;
if ( 0 = = ( WS_DISABLED & windowStyle ) )
{
if ( ! handleVirtualChildMsg ( WM_SETCURSOR , _x , _y , & ct , & c ) )
{
ct = getCursorType ( _x , _y ) ;
}
}
wchar_t * wincursor = NULL ;
switch ( ct )
{
case BASEWND_CURSOR_USERSET :
if ( c = = NULL )
c = getCustomCursor ( _x , _y ) ;
if ( c ! = NULL )
{
SetCursor ( c ) ;
return TRUE ;
}
else wincursor = IDC_ARROW ; // Ensure to have at least a cursor
break ;
case BASEWND_CURSOR_POINTER :
wincursor = IDC_ARROW ;
break ;
case BASEWND_CURSOR_NORTHSOUTH :
wincursor = IDC_SIZENS ;
break ;
case BASEWND_CURSOR_EASTWEST :
wincursor = IDC_SIZEWE ;
break ;
case BASEWND_CURSOR_NORTHWEST_SOUTHEAST :
wincursor = IDC_SIZENWSE ;
break ;
case BASEWND_CURSOR_NORTHEAST_SOUTHWEST :
wincursor = IDC_SIZENESW ;
break ;
case BASEWND_CURSOR_4WAY :
wincursor = IDC_SIZEALL ;
break ;
case BASEWND_CURSOR_EDIT :
wincursor = IDC_IBEAM ;
break ;
default :
wincursor = IDC_ARROW ;
break ;
}
if ( wincursor ! = NULL )
{
SetCursor ( LoadCursor ( NULL , wincursor ) ) ;
return TRUE ;
}
}
return FALSE ;
case WM_TIMER :
timerCallback ( ( int ) wParam ) ;
return 0 ;
case WM_GETOBJECT :
if ( lParam = = OBJID_CLIENT )
{
Accessible * acc = getAccessibleObject ( ) ;
if ( acc ! = NULL )
{
LRESULT lAcc = acc - > getOSHandle ( ( int ) wParam ) ;
return lAcc ;
}
}
break ; // Fall through to DefWindowProc
case WM_SETFOCUS :
if ( ! focusEventsEnabled ) break ;
if ( isInited ( ) )
{
if ( rootfocus ! = NULL & & rootfocus ! = this )
{
if ( rootfocus ! = curVirtualChildFocus )
rootfocus - > setFocus ( ) ;
break ;
}
else
{
if ( wantFocus ( ) )
{
onGetFocus ( ) ;
break ;
}
else
{
ifc_window * w = getTab ( TAB_GETFIRST ) ;
if ( w ! = NULL )
{
w - > setFocus ( ) ;
}
}
}
}
break ;
case WM_KILLFOCUS :
{
ifc_window * rp = getRootParent ( ) ;
if ( ! WASABI_API_WND - > rootwndIsValid ( rp ) | | ! Wasabi : : Std : : Wnd : : isValidWnd ( rp - > getOsWindowHandle ( ) ) ) break ;
if ( ! focusEventsEnabled ) break ;
# ifdef WASABI_COMPILE_WND
if ( WASABI_API_WND ) WASABI_API_WND - > forwardOnKillFocus ( ) ; // resets the keyboard active keys buffer
# endif
if ( ! WASABI_API_WND - > rootwndIsValid ( curVirtualChildFocus ) ) curVirtualChildFocus = NULL ;
if ( curVirtualChildFocus )
{
curVirtualChildFocus - > onKillFocus ( ) ;
curVirtualChildFocus = NULL ;
}
else
if ( hasfocus ) onKillFocus ( ) ;
break ;
}
// dragging and dropping
case WM_LBUTTONDOWN :
{
if ( lParam = = 0xdeadc0de )
return 1 ;
if ( bufferizeLockedUIMsg ( uMsg , ( int ) wParam , ( int ) lParam ) )
return 0 ;
WASABI_API_WND - > popupexit_check ( this ) ;
if ( checkModal ( ) )
return 0 ;
abortTip ( ) ;
int xPos = ( signed short ) LOWORD ( lParam ) ;
int yPos = ( signed short ) HIWORD ( lParam ) ;
xPos = ( int ) ( ( float ) xPos / getRenderRatio ( ) ) ;
yPos = ( int ) ( ( float ) yPos / getRenderRatio ( ) ) ;
if ( ! getCapture ( ) & & hasVirtualChildren ( ) & & handleVirtualChildMsg ( WM_LBUTTONDOWN , xPos , yPos ) )
return 0 ;
if ( isEnabled ( ) & & ! dragging )
{
autoFocus ( this ) ;
int r = 0 ;
if ( wantLeftClicks ( ) )
r = onLeftButtonDown ( xPos , yPos ) ;
if ( checkDoubleClick ( uMsg , xPos , yPos ) & & wantDoubleClicks ( ) & & onLeftButtonDblClk ( xPos , yPos ) )
return 0 ;
return r ;
}
}
break ;
case WM_RBUTTONDOWN :
{
if ( lParam = = 0xdeadc0de ) return 1 ;
if ( bufferizeLockedUIMsg ( uMsg , ( int ) wParam , ( int ) lParam ) ) return 0 ;
WASABI_API_WND - > popupexit_check ( this ) ;
if ( checkModal ( ) ) return 0 ;
abortTip ( ) ;
int xPos = ( signed short ) LOWORD ( lParam ) ;
int yPos = ( signed short ) HIWORD ( lParam ) ;
xPos = ( int ) ( ( float ) xPos / getRenderRatio ( ) ) ;
yPos = ( int ) ( ( float ) yPos / getRenderRatio ( ) ) ;
if ( ! getCapture ( ) & & hasVirtualChildren ( ) )
if ( handleVirtualChildMsg ( WM_RBUTTONDOWN , xPos , yPos ) )
return 0 ;
if ( isEnabled ( ) & & ! dragging )
{
autoFocus ( this ) ;
int r = 0 ;
if ( wantRightClicks ( ) )
r = onRightButtonDown ( xPos , yPos ) ;
if ( checkDoubleClick ( uMsg , xPos , yPos ) & & wantDoubleClicks ( ) ) if ( onRightButtonDblClk ( xPos , yPos ) ) return 0 ;
return r ;
}
}
break ;
case WM_MOUSEHOVER :
if ( checkModal ( ) ) return 0 ;
if ( ! getCapture ( ) & & hasVirtualChildren ( ) )
if ( handleVirtualChildMsg ( WM_MOUSEHOVER , 0 , 0 ) )
return 0 ;
break ;
case WM_MOUSEMOVE :
{
/* static int mm=0;
DebugString ( " mousemove %d \n " , mm + + ) ; */
if ( checkModal ( ) ) return 0 ;
int xPos = ( signed short ) LOWORD ( lParam ) ;
int yPos = ( signed short ) HIWORD ( lParam ) ;
xPos = ( int ) ( ( float ) xPos / getRenderRatio ( ) ) ;
yPos = ( int ) ( ( float ) yPos / getRenderRatio ( ) ) ;
if ( dragging )
{
POINT pt = { xPos , yPos } ;
clientToScreen ( & pt ) ;
ifc_window * targ ;
int candrop = 0 ;
// find the window the mouse is over
targ = NULL ;
if ( stickyWnd )
{
RECT wr ;
GetWindowRect ( stickyWnd - > getOsWindowHandle ( ) , & wr ) ;
if ( pt . x > = wr . left - sticky . left & &
pt . x < = wr . right + sticky . right & &
pt . y > = wr . top - sticky . top & &
pt . y < = wr . bottom + sticky . bottom ) targ = stickyWnd ;
else stickyWnd = NULL ;
}
if ( targ = = NULL & & WASABI_API_WND ) targ = WASABI_API_WND - > rootWndFromPoint ( & pt ) ; // FG> not to self, check
DI prevtargdi ( prevtarg ) ;
DI targdi ( targ ) ;
if ( prevtarg ! = targ )
{
// window switch
if ( prevtarg ! = NULL ) prevtargdi . dragLeave ( this ) ;
if ( targ ! = NULL ) targdi . dragEnter ( this ) ;
}
if ( targ ! = NULL )
candrop = targdi . dragOver ( pt . x , pt . y , this ) ;
if ( targ = = NULL | | ! candrop )
SetCursor ( LoadCursor ( NULL , MAKEINTRESOURCE ( IDC_NO ) ) ) ;
else
SetCursor ( LoadCursor ( NULL , MAKEINTRESOURCE ( IDC_APPSTARTING ) ) ) ;
prevtarg = targ ;
}
else if ( isEnabled ( ) )
{
tipbeenchecked = FALSE ;
if ( ! getCapture ( ) & & hasVirtualChildren ( ) )
{
if ( handleVirtualChildMsg ( WM_MOUSEMOVE , xPos , yPos ) )
return 0 ;
}
if ( getCapture ( ) )
{
if ( wantMouseMoves ( ) )
if ( onMouseMove ( xPos , yPos ) )
return 0 ;
}
if ( ! tipbeenchecked ) onTipMouseMove ( ) ;
return 0 ;
}
}
break ;
case WM_LBUTTONUP :
{
if ( lParam = = 0xdeadc0de ) return 1 ;
if ( bufferizeLockedUIMsg ( uMsg , ( int ) wParam , ( int ) lParam ) ) return 0 ;
if ( checkModal ( ) ) return 0 ;
int xPos = ( signed short ) LOWORD ( lParam ) ;
int yPos = ( signed short ) HIWORD ( lParam ) ;
xPos = ( int ) ( ( float ) xPos / getRenderRatio ( ) ) ;
yPos = ( int ) ( ( float ) yPos / getRenderRatio ( ) ) ;
abortTip ( ) ;
if ( ! dragging & & ! getCapture ( ) & & hasVirtualChildren ( ) )
{
if ( handleVirtualChildMsg ( WM_LBUTTONUP , xPos , yPos ) )
return 0 ;
}
if ( dragging )
{
clientToScreen ( & xPos , & yPos ) ;
int res = 0 ;
if ( prevtarg ! = NULL )
{
res = DI ( prevtarg ) . dragDrop ( this , xPos , yPos ) ;
}
// inform source what happened
dragComplete ( res ) ;
resetDragSet ( ) ;
prevtarg = NULL ;
stickyWnd = NULL ;
suggestedTitle = NULL ;
SetCursor ( LoadCursor ( NULL , MAKEINTRESOURCE ( IDC_ARROW ) ) ) ;
Wasabi : : Std : : Wnd : : releaseCapture ( ) ;
dragging = 0 ;
}
else if ( isEnabled ( ) )
{
if ( wantLeftClicks ( ) )
if ( onLeftButtonUp ( xPos , yPos ) ) return 0 ;
}
}
break ;
case WM_RBUTTONUP :
{
if ( lParam = = 0xdeadc0de ) return 1 ;
if ( bufferizeLockedUIMsg ( uMsg , ( int ) wParam , ( int ) lParam ) ) return 0 ;
if ( checkModal ( ) ) return 0 ;
abortTip ( ) ;
int xPos = ( signed short ) LOWORD ( lParam ) ;
int yPos = ( signed short ) HIWORD ( lParam ) ;
xPos = ( int ) ( ( float ) xPos / getRenderRatio ( ) ) ;
yPos = ( int ) ( ( float ) yPos / getRenderRatio ( ) ) ;
if ( ! getCapture ( ) & & hasVirtualChildren ( ) )
{
if ( handleVirtualChildMsg ( WM_RBUTTONUP , xPos , yPos ) )
return 0 ;
}
if ( isEnabled ( ) & & ! dragging )
{
if ( wantRightClicks ( ) )
if ( onRightButtonUp ( xPos , yPos ) ) return 0 ;
}
}
break ;
case WM_CONTEXTMENU :
{
if ( bufferizeLockedUIMsg ( uMsg , ( int ) wParam , ( int ) lParam ) ) return 0 ;
if ( checkModal ( ) ) return 0 ;
ASSERT ( hWnd ! = NULL ) ;
int xPos = ( signed short ) LOWORD ( lParam ) ;
int yPos = ( signed short ) HIWORD ( lParam ) ;
if ( hWnd = = getOsWindowHandle ( ) )
{
if ( wantContextMenus ( ) )
if ( onContextMenu ( xPos , yPos ) ) return 0 ;
}
else if ( GetParent ( hWnd ) = = getOsWindowHandle ( ) )
{
if ( wantContextMenus ( ) )
if ( onChildContextMenu ( xPos , yPos ) ) return 0 ;
}
}
break ;
case WM_ERASEBKGND :
return ( onEraseBkgnd ( ( HDC ) wParam ) ) ;
case WM_MOUSEWHEEL :
{
abortTip ( ) ;
int l , a ;
l = ( short ) HIWORD ( wParam ) / 120 ;
a = ( short ) HIWORD ( wParam ) ;
if ( ! l )
if ( a > 0 ) l = 1 ;
else if ( a < 0 ) l = 0 ;
a = l > = 0 ? l : - l ;
if ( GetAsyncKeyState ( VK_MBUTTON ) & 0x8000 )
{
if ( l > = 0 ) l = 0 ; // Fast Forward 5s
else l = 1 ; // Rewind 5s
}
else
{
if ( l > = 0 ) l = 2 ; // Volume up
else l = 3 ; // Volume down
}
int r = 0 ;
if ( l & 1 )
r = onMouseWheelDown ( ! ( BOOL ) ( l & 2 ) , a ) ;
else
r = onMouseWheelUp ( ! ( BOOL ) ( l & 2 ) , a ) ;
if ( r = = 0 )
{
r = WASABI_API_WND - > forwardOnMouseWheel ( l , a ) ;
}
// if it wasn't handled by this wnd, nor by the api, send it to the main wnd, unless we're it
if ( r = = 0 )
{
if ( WASABI_API_WND - > main_getRootWnd ( ) ! = this )
r = ( int ) SendMessageW ( WASABI_API_WND - > main_getRootWnd ( ) - > gethWnd ( ) , uMsg , wParam , lParam ) ;
}
return r ;
}
case WM_WA_RELOAD :
{
if ( wParam = = 0 )
freeResources ( ) ;
else
reloadResources ( ) ;
return 0 ;
}
case WM_WA_GETFBSIZE :
{
SIZE * s = ( SIZE * ) wParam ;
s - > cx = rwidth ;
s - > cy = rheight ;
return 0 ;
}
case WM_USER + 8976 : // wheel in tip, delete tip
abortTip ( ) ;
return 0 ;
case WM_CHAR :
if ( bufferizeLockedUIMsg ( uMsg , ( int ) wParam , ( int ) lParam ) ) return 0 ;
if ( WASABI_API_WND - > interceptOnChar ( ( TCHAR ) wParam ) ) return 0 ;
if ( curVirtualChildFocus = = NULL )
{
if ( onChar ( ( ( TCHAR ) wParam ) ) ) return 0 ;
}
else
{
if ( curVirtualChildFocus - > onChar ( ( ( TCHAR ) wParam ) ) ) return 0 ;
}
if ( WASABI_API_WND & & WASABI_API_WND - > forwardOnChar ( this , ( TCHAR ) wParam , ( int ) lParam ) ) return 0 ;
break ;
case WM_KEYDOWN :
if ( bufferizeLockedUIMsg ( uMsg , ( int ) wParam , ( int ) lParam ) ) return 0 ;
if ( WASABI_API_WND - > interceptOnKeyDown ( ( int ) wParam ) ) return 0 ;
if ( curVirtualChildFocus = = NULL )
{
if ( onKeyDown ( ( int ) wParam ) ) return 0 ;
}
else
{
if ( curVirtualChildFocus - > onKeyDown ( ( int ) wParam ) ) return 0 ;
}
if ( WASABI_API_WND & & WASABI_API_WND - > forwardOnKeyDown ( this , ( int ) wParam , ( int ) lParam ) ) return 0 ;
break ;
case WM_KEYUP :
if ( bufferizeLockedUIMsg ( uMsg , ( int ) wParam , ( int ) lParam ) ) return 0 ;
if ( WASABI_API_WND - > interceptOnKeyUp ( ( int ) wParam ) ) return 0 ;
if ( curVirtualChildFocus = = NULL )
{
if ( onKeyUp ( ( int ) wParam ) ) return 0 ;
}
else
{
if ( curVirtualChildFocus - > onKeyUp ( ( int ) wParam ) ) return 0 ;
}
if ( WASABI_API_WND & & WASABI_API_WND - > forwardOnKeyUp ( this , ( int ) wParam , ( int ) lParam ) ) return 0 ;
break ;
case WM_SYSKEYDOWN :
if ( bufferizeLockedUIMsg ( uMsg , ( int ) wParam , ( int ) lParam ) ) return 0 ;
if ( WASABI_API_WND - > interceptOnSysKeyDown ( ( int ) wParam , ( int ) lParam ) ) return 0 ;
if ( curVirtualChildFocus = = NULL )
{
if ( onSysKeyDown ( ( int ) wParam , ( int ) lParam ) ) return 0 ;
}
else
{
if ( curVirtualChildFocus - > onSysKeyDown ( ( int ) wParam , ( int ) lParam ) ) return 0 ;
}
if ( WASABI_API_WND & & WASABI_API_WND - > forwardOnSysKeyDown ( this , ( int ) wParam , ( int ) lParam ) ) return 0 ;
break ;
case WM_SYSKEYUP :
if ( bufferizeLockedUIMsg ( uMsg , ( int ) wParam , ( int ) lParam ) ) return 0 ;
if ( WASABI_API_WND - > interceptOnSysKeyUp ( ( int ) wParam , ( int ) lParam ) ) return 0 ;
if ( curVirtualChildFocus = = NULL )
{
if ( onSysKeyUp ( ( int ) wParam , ( int ) lParam ) ) return 0 ;
}
else
{
if ( curVirtualChildFocus - > onSysKeyUp ( ( int ) wParam , ( int ) lParam ) ) return 0 ;
}
if ( WASABI_API_WND & & WASABI_API_WND - > forwardOnSysKeyUp ( this , ( int ) wParam , ( int ) lParam ) ) return 0 ;
break ;
case WM_MOUSEACTIVATE :
{
if ( checkModal ( ) | | ! wantActivation ( ) )
return MA_NOACTIVATE ;
//SetFocus(getOsWindowHandle());
return MA_ACTIVATE ;
}
case WM_ACTIVATEAPP :
if ( wParam = = FALSE )
{
if ( WASABI_API_WND ! = NULL )
{
WASABI_API_WND - > popupexit_signal ( ) ;
WASABI_API_SYSCB - > syscb_issueCallback ( SysCallback : : GC , GarbageCollectCallback : : GARBAGECOLLECT ) ;
WASABI_API_WND - > kbdReset ( ) ;
if ( ghosthwnd . getNumItems ( ) > 0 & & ghostbust )
{
ghostbust = 0 ; postDeferredCallback ( DC_KILLGHOST ) ;
}
return 0 ;
}
}
break ;
case WM_ACTIVATE :
switch ( LOWORD ( wParam ) )
{
case WA_ACTIVE :
case WA_CLICKACTIVE :
if ( WASABI_API_WND ! = NULL )
WASABI_API_WND - > popupexit_check ( this ) ;
onActivate ( ) ;
if ( WA_CLICKACTIVE = = LOWORD ( wParam ) )
{
POINT pt ;
DWORD pts = GetMessagePos ( ) ;
POINTSTOPOINT ( pt , pts ) ;
MapWindowPoints ( HWND_DESKTOP , hwnd , & pt , 1 ) ;
HWND hTarget = ChildWindowFromPointEx ( hwnd , pt , CWP_SKIPINVISIBLE | CWP_SKIPDISABLED | CWP_SKIPTRANSPARENT ) ;
if ( hTarget & & hTarget ! = hwnd ) lastActiveWnd = hTarget ;
}
if ( lastActiveWnd ! = hwnd & & NULL ! = lastActiveWnd & & IsWindow ( lastActiveWnd ) )
{
SendMessageW ( lastActiveWnd , uMsg , wParam , lParam ) ;
return 0 ;
}
break ;
default :
onDeactivate ( ) ;
lastActiveWnd = GetFocus ( ) ;
if ( NULL ! = lastActiveWnd & & ! IsChild ( hwnd , lastActiveWnd ) )
lastActiveWnd = NULL ;
{
# ifndef ARRAYSIZE
# define ARRAYSIZE(x) (sizeof(x) / sizeof(*x))
# endif
if ( NULL ! = lastActiveWnd & & ! BaseWnd_IsFrameWindow ( lastActiveWnd ) )
{
while ( lastActiveWnd )
{
if ( BaseWnd_IsFrameWindow ( GetWindow ( lastActiveWnd , GW_OWNER ) ) )
break ;
lastActiveWnd = GetAncestor ( lastActiveWnd , GA_PARENT ) ;
}
}
}
if ( lastActiveWnd ! = hwnd & & NULL ! = lastActiveWnd )
{
SendMessageW ( lastActiveWnd , uMsg , wParam , lParam ) ;
return 0 ;
}
break ;
}
break ;
case WM_NCACTIVATE :
if ( allowDeactivation ( ) )
return TRUE ;
return FALSE ;
case WM_WINDOWPOSCHANGING :
{
if ( ! isVirtual ( ) & & Wasabi : : Std : : Wnd : : isPopup ( hwnd ) )
{
WINDOWPOS * wp = ( WINDOWPOS * ) lParam ;
if ( wp - > x ! = rx | | wp - > y ! = ry ) wp - > flags | = SWP_NOMOVE ;
}
}
break ;
case WM_WINDOWPOSCHANGED :
{
WINDOWPOS * lpwp = ( WINDOWPOS * ) lParam ; // points to size and position data
if ( lpwp - > flags & SWP_HIDEWINDOW )
{
minimized = 1 ;
onMinimize ( ) ;
}
else if ( lpwp - > flags & SWP_SHOWWINDOW )
{
minimized = 0 ;
onRestore ( ) ;
}
if ( ! inonresize )
{
int w = rwidth ;
int h = rheight ;
multRatio ( & w , & h ) ;
if ( lpwp - > cx ! = w | | lpwp - > cy ! = h )
{
DebugStringW ( L " external onResize \n " ) ;
w = lpwp - > cx ;
h = lpwp - > cy ;
divRatio ( & w , & h ) ;
setRSize ( rx , ry , w , h ) ;
if ( isPostOnInit ( ) )
onResize ( ) ;
}
}
onPostedMove ( ) ;
return 0 ;
}
case WM_DROPFILES :
{
if ( checkModal ( ) ) break ;
WASABI_API_WND - > pushModalWnd ( ) ;
onExternalDropBegin ( ) ;
HDROP h = ( HDROP ) wParam ;
POINT dp = { 0 } ;
DragQueryPoint ( h , & dp ) ;
clientToScreen ( & dp ) ;
// build a file list
wchar_t buf [ WA_MAX_PATH ] = { 0 } ;
PtrList < FilenamePS > keep ;
SetCursor ( LoadCursor ( NULL , IDC_WAIT ) ) ;
//CUT #if UTF8
//CUT // doesn't really need UTF8, the "buf" is never written to.
//CUT // made to be NULL to enforce this concept.
int nfiles = DragQueryFile ( h , 0xffffffff , NULL , 0 ) ;
//CUT #else
//CUT int nfiles = DragQueryFile(h, 0xffffffff, buf, sizeof(buf));
//CUT #endif
// convert them all to PlayItem *'s
for ( int i = 0 ; i < nfiles ; i + + )
{
DragQueryFileW ( h , i , buf , WA_MAX_PATH ) ;
addDroppedFile ( buf , & keep ) ; // recursive
}
SetCursor ( LoadCursor ( NULL , IDC_ARROW ) ) ;
dragging = 1 ;
if ( dragEnter ( this ) )
{
if ( dragOver ( dp . x , dp . y , this ) ) dragDrop ( this , dp . x , dp . y ) ;
}
else
{
dragLeave ( this ) ;
# ifdef FORWARD_DRAGNDROP
HWND w = WASABI_API_WND - > main_getRootWnd ( ) - > gethWnd ( ) ;
SendMessageW ( w , WM_DROPFILES , wParam , lParam ) ;
# endif
}
dragging = 0 ;
// remove data
keep . deleteAll ( ) ;
resetDragSet ( ) ;
onExternalDropEnd ( ) ;
WASABI_API_WND - > popModalWnd ( ) ;
}
return 0 ; // dropfiles
case WM_CAPTURECHANGED :
/* static int cc=0;
DebugString ( " capture changed! %d \n " , cc + + ) ; */
if ( preventcancelcapture ) return 0 ;
inputCaptured = 0 ;
if ( curVirtualChildCaptured ! = NULL )
{
ifc_window * w = curVirtualChildCaptured ;
curVirtualChildCaptured = NULL ;
w - > onCancelCapture ( ) ;
}
else
{
onCancelCapture ( ) ;
}
return 0 ;
} //switch
if ( WINAMP_WM_DIRECT_MOUSE_WHEEL = = uMsg & &
WM_NULL ! = WINAMP_WM_DIRECT_MOUSE_WHEEL )
{
wndProc ( hWnd , WM_MOUSEWHEEL , wParam , lParam ) ;
return TRUE ;
}
if ( uMsg > = WM_USER )
{
int ret ;
if ( onUserMessage ( uMsg , ( int ) wParam , ( int ) lParam , & ret ) )
return ret ;
return 0 ;
}
return DefWindowProcW ( hWnd , uMsg , wParam , lParam ) ;
}
# endif
int BaseWnd : : onUserMessage ( int msg , int w , int l , int * r )
{
return 0 ;
}
int BaseWnd : : checkDoubleClick ( int b , int x , int y )
{
# ifdef _WIN32
uint32_t now = Wasabi : : Std : : getTickCount ( ) ;
switch ( b )
{
case WM_LBUTTONDOWN :
if ( lastClick [ 0 ] > now - Wasabi : : Std : : getDoubleClickDelay ( ) )
{
lastClick [ 0 ] = 0 ;
if ( ABS ( lastClickP [ 0 ] . x - x ) > Wasabi : : Std : : getDoubleClickX ( ) | | ABS ( lastClickP [ 0 ] . y - y ) > Wasabi : : Std : : getDoubleClickY ( ) ) return 0 ;
return 1 ;
}
lastClick [ 0 ] = now ;
lastClickP [ 0 ] . x = x ;
lastClickP [ 0 ] . y = y ;
break ;
case WM_RBUTTONDOWN :
if ( lastClick [ 1 ] > now - Wasabi : : Std : : getDoubleClickDelay ( ) )
{
lastClick [ 1 ] = 0 ;
if ( ABS ( lastClickP [ 1 ] . x - x ) > Wasabi : : Std : : getDoubleClickX ( ) | | ABS ( lastClickP [ 1 ] . y - y ) > Wasabi : : Std : : getDoubleClickY ( ) ) return 0 ;
return 1 ;
}
lastClick [ 1 ] = now ;
lastClickP [ 1 ] . x = x ;
lastClickP [ 1 ] . y = y ;
break ;
}
# else
# warning port me
# endif
return 0 ;
}
int BaseWnd : : onMouseWheelUp ( int click , int lines )
{
return 0 ;
}
int BaseWnd : : onMouseWheelDown ( int click , int lines )
{
return 0 ;
}
int BaseWnd : : onContextMenu ( int x , int y )
{
return 0 ;
}
int BaseWnd : : onChildContextMenu ( int x , int y )
{
return 0 ;
}
int BaseWnd : : onDeferredCallback ( intptr_t param1 , intptr_t param2 )
{
switch ( param1 )
{
case DEFERREDCB_FLUSHPAINT :
do_flushPaint ( ) ;
break ;
case DEFERREDCB_INVALIDATE :
if ( isPostOnInit ( ) )
invalidate ( ) ;
break ;
case DC_KILLGHOST :
if ( ghosthwnd . getNumItems ( ) > 0 )
{
preventcancelcapture = 1 ;
for ( int i = 0 ; i < ghosthwnd . getNumItems ( ) ; i + + )
Wasabi : : Std : : Wnd : : destroyWnd ( ghosthwnd . enumItem ( i ) ) ;
ghosthwnd . freeAll ( ) ;
preventcancelcapture = 0 ;
}
break ;
case DEFERREDCB_FOCUSFIRST :
assignRootFocus ( NULL ) ;
if ( Wasabi : : Std : : Wnd : : getFocus ( ) = = getOsWindowHandle ( ) )
{
focusNext ( ) ;
}
break ;
case 0x7849 /*DEFERREDCB_ONHIDE*/ :
{
foreach ( rootwndchildren )
ifc_window * w = rootwndchildren . getfor ( ) ;
if ( w - > isVisible ( 1 ) ) // check internal flag only
w - > onSetVisible ( 0 ) ;
endfor ;
dependent_sendEvent ( BaseWnd : : depend_getClassGuid ( ) , Event_SETVISIBLE , 0 ) ;
break ;
}
}
return 0 ;
}
int BaseWnd : : onPaint ( Canvas * canvas )
{
#if 0
// example:
PaintCanvas c ;
if ( ! c . beginPaint ( this ) ) return 0 ;
( do some painting )
c will self - destruct on return
# endif
if ( renderbasetexture )
{
PaintCanvas paintcanvas ;
if ( canvas = = NULL )
{
if ( ! paintcanvas . beginPaint ( this ) ) return 0 ;
canvas = & paintcanvas ;
}
RECT r ;
getNonClientRect ( & r ) ;
RenderBaseTexture ( canvas , r ) ;
}
return 0 ;
}
int BaseWnd : : onPaint ( Canvas * canvas , api_region * h )
{
if ( ! canvas ) return onPaint ( canvas ) ;
# ifdef _WIN32
int sdc = SaveDC ( canvas - > getHDC ( ) ) ;
# elif defined(__APPLE__)
CGContextSaveGState ( canvas - > getHDC ( ) ) ;
# endif
canvas - > selectClipRgn ( h ) ;
int rs = onPaint ( canvas ) ;
# ifdef _WIN32
RestoreDC ( canvas - > getHDC ( ) , sdc ) ;
# elif defined(__APPLE__)
CGContextRestoreGState ( canvas - > getHDC ( ) ) ;
# endif
return rs ;
}
int BaseWnd : : getTransparency ( )
{
return wndalpha ;
}
void BaseWnd : : setTransparency ( int amount )
{
//if (wndalpha == amount) return;
if ( amount = = 254 ) amount = 255 ;
if ( amount = = 1 ) amount = 0 ;
if ( amount ! = - 1 ) wndalpha = amount ; else amount = wndalpha ;
if ( ! Wasabi : : Std : : Wnd : : isDesktopAlphaAvailable ( ) )
{
wndalpha = 255 ;
return ;
}
if ( w2k_alpha )
{
invalidate ( ) ;
return ;
}
# ifdef WIN32
if ( ! isInited ( ) | | isVirtual ( ) ) return ;
if ( ! Wasabi : : Std : : Wnd : : isValidWnd ( getOsWindowHandle ( ) ) ) return ;
if ( amount < - 1 ) amount = 0 ;
else if ( amount > 255 ) amount = 255 ;
//CUT DWORD dwLong = GetWindowLong(hwnd, GWL_EXSTYLE);
if ( amount = = 255 & & ! forceTransparencyFlag ( ) )
{
Wasabi : : Std : : Wnd : : setLayeredWnd ( hwnd , FALSE ) ;
//CUT if (dwLong & WS_EX_LAYERED)
//CUT SetWindowLong(hwnd, GWL_EXSTYLE, dwLong & ~WS_EX_LAYERED);
has_alpha_flag = 0 ;
}
else
{
if ( ! Wasabi : : Std : : Wnd : : isLayeredWnd ( hwnd ) )
Wasabi : : Std : : Wnd : : setLayeredWnd ( hwnd , TRUE ) ;
//CUT if (!(dwLong & WS_EX_LAYERED))
//CUT SetWindowLong(hwnd, GWL_EXSTYLE, dwLong | WS_EX_LAYERED);
Wasabi : : Std : : Wnd : : setLayeredAlpha ( hwnd , amount ) ;
//CUT setLayeredWindowAttributes(hwnd, RGB(0,0,0), amount, LWA_ALPHA);
has_alpha_flag = 1 ;
}
# endif
}
int BaseWnd : : forceTransparencyFlag ( )
{
return 0 ;
}
int BaseWnd : : beginCapture ( )
{
if ( ! getCapture ( ) )
{
disable_tooltip_til_recapture = 0 ;
curVirtualChildCaptured = NULL ;
/* oldCapture = */ Wasabi : : Std : : Wnd : : setCapture ( getOsWindowHandle ( ) ) ;
/* if (oldCapture) {
DebugString ( " Stolen capture detected, this may be ok, but try to avoid it if possible. Saving old capture \n " ) ;
} */
inputCaptured = 1 ;
}
return 1 ;
}
int BaseWnd : : endCapture ( )
{
preventcancelcapture = 1 ;
if ( Wasabi : : Std : : Wnd : : getCapture ( ) = = getOsWindowHandle ( ) ) Wasabi : : Std : : Wnd : : releaseCapture ( ) ;
/* if (oldCapture) {
DebugString ( " Restoring old capture \n " ) ;
SetCapture ( oldCapture ) ;
oldCapture = NULL ;
} */
inputCaptured = 0 ;
preventcancelcapture = 0 ;
return 1 ;
}
int BaseWnd : : getCapture ( )
{
if ( inputCaptured & & Wasabi : : Std : : Wnd : : getCapture ( ) = = getOsWindowHandle ( ) & & curVirtualChildCaptured = = NULL ) return 1 ;
return 0 ;
}
void BaseWnd : : cancelCapture ( )
{
if ( curVirtualChildCaptured ! = NULL )
{
curVirtualChildCaptured - > cancelCapture ( ) ;
return ;
}
if ( getCapture ( ) ) endCapture ( ) ;
onCancelCapture ( ) ;
}
int BaseWnd : : onMouseMove ( int x , int y )
{
onTipMouseMove ( ) ;
return 0 ;
}
void BaseWnd : : onTipMouseMove ( )
{
POINT p ;
if ( dragging ) return ;
if ( disable_tooltip_til_recapture ) return ;
tipbeenchecked = TRUE ;
Wasabi : : Std : : getMousePos ( & p ) ;
if ( WASABI_API_WND - > rootWndFromPoint ( & p ) ! = ( ifc_window * ) this )
{
// leaving area
tip_done = FALSE ;
if ( tipawaytimer )
killTimer ( TIP_AWAY_ID ) ;
tipawaytimer = FALSE ;
if ( tipshowtimer )
{
// TODO: on the mac, use CreateMouseTrackingRegion
TRACKMOUSEEVENT tracker ;
tracker . cbSize = sizeof ( tracker ) ;
tracker . dwFlags = TME_HOVER | TME_CANCEL ;
tracker . hwndTrack = this - > getOsWindowHandle ( ) ;
tracker . dwHoverTime = TIP_TIMER_THRESHOLD ;
TrackMouseEvent ( & tracker ) ;
}
tipshowtimer = FALSE ;
destroyTip ( ) ;
}
else
{
// moving in area
const wchar_t * t = getTip ( ) ;
if ( ! disable_tooltip_til_recapture & & ! tipshowtimer & & ! tip_done & & t ! = NULL & & * t ! = 0 )
{
//entering area & need tip
// TODO: on the mac, use CreateMouseTrackingRegion
TRACKMOUSEEVENT tracker ;
tracker . cbSize = sizeof ( tracker ) ;
tracker . dwFlags = TME_HOVER ;
tracker . hwndTrack = this - > getOsWindowHandle ( ) ;
tracker . dwHoverTime = TIP_TIMER_THRESHOLD ;
TrackMouseEvent ( & tracker ) ;
tipshowtimer = TRUE ;
}
/*else if (tipshowtimer)
{
TRACKMOUSEEVENT tracker ;
tracker . cbSize = sizeof ( tracker ) ;
tracker . dwFlags = TME_HOVER ;
tracker . hwndTrack = this - > getOsWindowHandle ( ) ;
tracker . dwHoverTime = TIP_TIMER_THRESHOLD ;
TrackMouseEvent ( & tracker ) ;
} */
}
}
int BaseWnd : : onLeftButtonDblClk ( int x , int y )
{
return 0 ;
}
int BaseWnd : : onRightButtonDblClk ( int x , int y )
{
return 0 ;
}
int BaseWnd : : onGetFocus ( )
{
// return TRUE if you override this
hasfocus = 1 ;
notifyParent ( ChildNotify : : GOTFOCUS ) ;
getRootParent ( ) - > onSetRootFocus ( this ) ;
invalidate ( ) ;
Accessible * a = getAccessibleObject ( ) ;
if ( a ! = NULL )
a - > onGetFocus ( ) ;
return 1 ;
}
int BaseWnd : : onKillFocus ( )
{
// return TRUE if you override this
hasfocus = 0 ;
notifyParent ( ChildNotify : : KILLFOCUS ) ;
invalidate ( ) ;
return 1 ;
}
# if defined(_WIN64)
int BaseWnd : : childNotify ( ifc_window * child , int msg , int p1 , int p2 )
{
return 0 ;
}
# else
int BaseWnd : : childNotify ( ifc_window * child , int msg , intptr_t p1 , intptr_t p2 )
{
return 0 ;
}
# endif
int BaseWnd : : addDragItem ( const wchar_t * droptype , void * item )
{
ASSERT ( droptype ! = NULL ) ;
if ( item = = NULL ) return - 1 ;
DragSet * set ;
int pos = dragCheckData ( droptype ) ;
if ( pos = = - 1 )
{
set = new DragSet ( ) ;
set - > setName ( droptype ) ;
dragsets . addItem ( set ) ;
pos = dragsets . getNumItems ( ) - 1 ;
}
else set = dragsets [ pos ] ;
set - > addItem ( item ) ;
return pos ;
}
# ifdef _WIN32
int BaseWnd : : handleDrag ( )
{
abortTip ( ) ;
if ( dragsets . getNumItems ( ) = = 0 ) return 0 ;
Wasabi : : Std : : Wnd : : setCapture ( hwnd ) ;
SetCursor ( LoadCursor ( NULL , MAKEINTRESOURCE ( IDC_APPSTARTING ) ) ) ;
dragging = 1 ;
stickyWnd = NULL ;
return 1 ;
}
# endif
int BaseWnd : : resetDragSet ( )
{
dragsets . deleteAll ( ) ;
return 1 ;
}
int BaseWnd : : dragEnter ( ifc_window * sourceWnd )
{
ifc_window * rw = getParent ( ) ; //api_window::rootwndFromRootWnd(getParent()); //FG> note to self, check!
if ( rw ) return DI ( rw ) . dragEnter ( sourceWnd ) ;
return 0 ;
}
int BaseWnd : : dragSetSticky ( ifc_window * wnd , int left , int right , int up , int down )
{
ASSERT ( dragging ) ;
stickyWnd = wnd ;
if ( left < 0 ) left = 0 ;
if ( right < 0 ) right = 0 ;
if ( up < 0 ) up = 0 ;
if ( down < 0 ) down = 0 ;
Wasabi : : Std : : setRect ( & sticky , left , up , right , down ) ;
return 1 ;
}
void BaseWnd : : setSuggestedDropTitle ( const wchar_t * title )
{
ASSERT ( title ! = NULL ) ;
suggestedTitle = title ;
}
const wchar_t * BaseWnd : : dragGetSuggestedDropTitle ( )
{
return suggestedTitle ; // can be NULL
}
int BaseWnd : : dragCheckData ( const wchar_t * type , int * nitems )
{
for ( int i = 0 ; i < dragsets . getNumItems ( ) ; i + + )
{
if ( ! WCSICMP ( type , dragsets [ i ] - > getName ( ) ) )
{
if ( nitems ! = NULL ) * nitems = dragsets [ i ] - > getNumItems ( ) ;
return i ;
}
}
return - 1 ;
}
void * BaseWnd : : dragGetData ( int slot , int itemnum )
{
if ( slot < 0 | | slot > = dragsets . getNumItems ( ) ) return 0 ;
if ( itemnum < 0 | | itemnum > = dragsets [ slot ] - > getNumItems ( ) ) return 0 ;
return dragsets [ slot ] - > enumItem ( itemnum ) ;
}
void BaseWnd : : addDroppedFile ( const wchar_t * filename , PtrList < FilenamePS > * plist )
{
# ifdef RECURSE_SUBDIRS_ON_DROP
const char * slash = filename + STRLEN ( filename ) - 1 ;
for ( ; slash > filename ; slash - - ) if ( * slash = = ' / ' | | * slash = = ' \\ ' ) break ;
if ( STREQL ( slash + 1 , " . " ) | | STREQL ( slash + 1 , " .. " ) ) return ;
char buf [ WA_MAX_PATH ] = { 0 } ;
STRCPY ( buf , filename ) ;
// try to resolve shortcuts
char * ext = buf + STRLEN ( buf ) - 1 ;
for ( ; ext > buf ; ext - - ) if ( * ext = = ' . ' | | * ext = = ' \\ ' | | * ext = = ' / ' ) break ;
# ifdef WIN32
if ( ! STRICMP ( ext , " .lnk " ) )
{
char buf2 [ MAX_PATH ] = { 0 } ;
if ( StdFile : : resolveShortcut ( buf , buf2 ) ) STRCPY ( buf , buf2 ) ;
}
# endif
int isdir = 0 ;
// handle root dir specially?
WIN32_FIND_DATA data = { 0 } ;
HANDLE r = FindFirstFile ( buf , & data ) ;
if ( ! r ) return ;
FindClose ( r ) ;
if ( data . dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) isdir = 1 ;
if ( isdir )
{
onExternalDropDirScan ( buf ) ;
// enumerate that dir
char search [ WA_MAX_PATH ] = { 0 } ;
wsprintf ( search , " %s \\ *.* " , buf ) ;
HANDLE files = FindFirstFile ( search , & data ) ;
if ( files = = INVALID_HANDLE_VALUE ) return ; // nothin' in it
for ( ; ; )
{
wchar_t obuf [ WA_MAX_PATH ] = { 0 } ;
swprintf ( obuf , L " %s \\ %s " , buf , data . cFileName ) ;
addDroppedFile ( obuf , plist ) ;
if ( ! FindNextFile ( files , & data ) )
{
FindClose ( files ) ;
return ;
}
}
// should never get here
}
else
{
addDragItem ( DD_FILENAME , plist - > addItem ( new FilenamePS ( StringPrintfW ( L " file:%s " , buf ) ) ) ) ;
}
# else
addDragItem ( DD_FILENAME , plist - > addItem ( new FilenamePS ( StringPrintfW ( L " file:%s " , filename ) ) ) ) ;
# endif
}
bool BaseWnd : : getNoCopyBits ( void )
{
return ncb ;
}
void BaseWnd : : setNoCopyBits ( bool newncb )
{
ncb = newncb ;
}
int BaseWnd : : onEraseBkgnd ( HDC dc )
{
return 1 ;
}
void BaseWnd : : setIcon ( OSICONHANDLE icon , int _small )
{
Wasabi : : Std : : Wnd : : setIcon ( getOsWindowHandle ( ) , icon , ! _small ) ;
//CUT SendMessageW(getOsWindowHandle(), WM_SETICON, _small ? ICON_SMALL : ICON_BIG, (int)icon);
}
const wchar_t * BaseWnd : : getTip ( )
{
return tip ;
}
void BaseWnd : : setTip ( const wchar_t * _tooltip )
{
tip = _tooltip ;
abortTip ( ) ;
}
int BaseWnd : : getStartHidden ( )
{
return start_hidden ;
}
void BaseWnd : : abortTip ( )
{
if ( tipshowtimer )
{
// TODO: on the mac, use CreateMouseTrackingRegion
TRACKMOUSEEVENT tracker ;
tracker . cbSize = sizeof ( tracker ) ;
tracker . dwFlags = TME_HOVER | TME_CANCEL ;
tracker . hwndTrack = this - > getOsWindowHandle ( ) ;
tracker . dwHoverTime = TIP_TIMER_THRESHOLD ;
TrackMouseEvent ( & tracker ) ;
}
tipshowtimer = FALSE ;
if ( tipawaytimer )
killTimer ( TIP_AWAY_ID ) ;
tipawaytimer = FALSE ;
if ( tipdestroytimer )
killTimer ( TIP_DESTROYTIMER_ID ) ;
tipdestroytimer = FALSE ;
destroyTip ( ) ;
tip_done = FALSE ;
RECT r ;
if ( getOsWindowHandle ( ) & & Wasabi : : Std : : Wnd : : getUpdateRect ( getOsWindowHandle ( ) , & r ) ! = 0 ) // FG> avoids xoring over disapearing tip
repaint ( ) ;
}
int BaseWnd : : isVisible ( int within )
{
if ( ! isVirtual ( ) & & ! getOsWindowHandle ( ) ) return 0 ;
if ( ! this_visible ) return 0 ;
if ( within ) return this_visible ; // whatever, local
if ( isVirtual ( ) ) // virtual, global
if ( getParent ( ) )
return getParent ( ) - > isVisible ( ) ;
else
return 0 ;
// non virtual, global
if ( Wasabi : : Std : : Wnd : : isPopup ( getOsWindowHandle ( ) ) ) return this_visible ;
if ( ! Wasabi : : Std : : Wnd : : isValidWnd ( Wasabi : : Std : : Wnd : : getParent ( getOsWindowHandle ( ) ) ) ) return 0 ;
if ( getParent ( ) ) return getParent ( ) - > isVisible ( ) ; // not a popup, check its parent or fail
return this_visible ;
}
void BaseWnd : : registerRootWndChild ( ifc_window * child )
{
rootwndchildren . addItem ( child ) ;
if ( child - > isVirtual ( ) )
virtualChildren . addItem ( child ) ;
}
void BaseWnd : : unregisterRootWndChild ( ifc_window * child )
{
delTabOrderEntry ( child ) ;
rootwndchildren . removeItem ( child ) ;
if ( curVirtualChildCaptured = = child )
{
setVirtualChildCapture ( NULL ) ;
}
if ( curVirtualChildFocus = = child )
curVirtualChildFocus = NULL ;
virtualChildren . removeItem ( child ) ;
//WASABI_API_WND->timer_remove(this, -1);
if ( isPostOnInit ( ) & & isVisible ( ) )
postDeferredCallback ( DEFERREDCB_INVALIDATE , 0 ) ;
}
int BaseWnd : : isVirtual ( )
{
return 0 ;
}
//CUT?inline int isInRect(RECT *r,int x,int y) {
//CUT? if (x>=r->left&&x<=r->right&&y>=r->top&&y<=r->bottom) return 1;
//CUT? return 0;
//CUT?}
int BaseWnd : : ensureVirtualCanvasOk ( )
{
RECT ncr ;
if ( isVirtual ( ) & & getParent ( ) ) return 1 ;
int size_w = rwidth ;
int size_h = rheight ;
if ( ! size_w | | ! size_h ) return 0 ;
if ( ! virtualCanvas | | virtualCanvasH ! = size_h | | virtualCanvasW ! = size_w )
{
if ( virtualCanvas )
{
deleteFrameBuffer ( virtualCanvas ) ;
virtualCanvas = NULL ;
}
delete scalecanvas ;
scalecanvas = NULL ;
virtualCanvas = createFrameBuffer ( size_w , size_h ) ;
prepareFrameBuffer ( virtualCanvas , size_w , size_h ) ;
virtualCanvas - > setBaseWnd ( this ) ;
virtualCanvasH = size_h ; virtualCanvasW = size_w ;
BaseWnd : : getNonClientRect ( & ncr ) ;
deferedInvalidateRect ( & ncr ) ;
}
return 1 ;
}
Canvas * BaseWnd : : createFrameBuffer ( int w , int h )
{
return new BltCanvas ( w , h , getOsWindowHandle ( ) ) ;
}
void BaseWnd : : prepareFrameBuffer ( Canvas * canvas , int w , int h )
{
RECT r = { 0 , 0 , w , h } ;
RegionI reg ( & r ) ;
virtualBeforePaint ( & reg ) ;
# ifdef _WIN32
canvas - > selectClipRgn ( NULL ) ;
canvas - > fillRect ( & r , 0 ) ;
# elif defined(__APPLE__)
CGContextClearRect ( canvas - > getHDC ( ) , CGRectInfinite ) ; // TODO: make "clear" function in canvas
# endif
virtualAfterPaint ( & reg ) ;
}
void BaseWnd : : deleteFrameBuffer ( Canvas * canvas )
{
delete canvas ;
}
// paints the client content, followed by the virtual child tree. recursive
int BaseWnd : : paintTree ( Canvas * canvas , api_region * r )
{
onPaint ( canvas , r ) ;
# ifdef WASABI_DRAW_FOCUS_RECT
if ( gotFocus ( ) )
{
RECT ncr ;
getNonClientRect ( & ncr ) ;
// try to use skinned focus rect
if ( WASABI_API_WND - > paintset_present ( Paintset : : FOCUSRECT ) )
WASABI_API_WND - > paintset_render ( Paintset : : FOCUSRECT , canvas , & ncr , 128 ) ;
else // otherwise this looks kinda nice :P
canvas - > drawRect ( & ncr , 0 , 0xFFFFFF , 128 ) ;
}
# endif
if ( isVirtual ( ) & & ! hasVirtualChildren ( ) ) return 0 ;
api_region * hostrgn = NULL ;
api_region * update = r ;
if ( ! ( hwnd ! = NULL & & getParent ( ) = = NULL ) )
{
hostrgn = getRegion ( ) ;
update = r - > clone ( ) ;
if ( hostrgn & & ! isRectRgn ( ) )
{
RECT ncr = clientRect ( ) ;
api_region * hostclone = hostrgn - > clone ( ) ;
hostclone - > addRegion ( getComposedRegion ( ) ) ;
hostclone - > offset ( ncr . left , ncr . top ) ;
update - > andRegion ( hostclone ) ;
hostrgn - > disposeClone ( hostclone ) ;
}
}
RegionI client_update ;
for ( int i = 0 ; i < virtualChildren . getNumItems ( ) ; i + + )
{
if ( ! virtualChildren [ i ] - > isVisible ( 1 ) ) continue ;
RECT rChild ;
ifc_window * w = virtualChildren [ i ] ;
w - > getNonClientRect ( & rChild ) ;
if ( ( rChild . right ! = rChild . left ) & & ( rChild . bottom ! = rChild . top ) )
if ( update - > intersectRect ( & rChild , & client_update ) )
{
w - > paintTree ( canvas , & client_update ) ;
}
}
if ( update ! = r ) r - > disposeClone ( update ) ;
return 1 ;
}
void BaseWnd : : setVirtualCanvas ( Canvas * c )
{
virtualCanvas = c ;
}
int BaseWnd : : pointInWnd ( POINT * p )
{
RECT r ;
if ( ! isVisible ( 1 ) ) return 0 ;
getWindowRect ( & r ) ;
if ( ! Wasabi : : Std : : pointInRect ( r , * p ) )
return 0 ;
for ( int i = 0 ; i < getNumRootWndChildren ( ) ; i + + )
{
ifc_window * c = enumRootWndChildren ( i ) ;
if ( ! c - > isVisible ( 1 ) ) continue ;
RECT rChild ;
c - > getWindowRect ( & rChild ) ;
if ( Wasabi : : Std : : pointInRect ( rChild , * p ) )
return 0 ;
}
//NONPORTABLE
/* HWND child = GetWindow(getOsWindowHandle(), GW_CHILD);
while ( child ! = NULL ) {
if ( IsWindowVisible ( child ) ) {
RECT r2 ;
GetWindowRect ( child , & r2 ) ;
if ( Std : : pointInRect ( r2 , * p ) )
return 0 ;
}
child = GetWindow ( child , GW_HWNDNEXT ) ;
} */
return 1 ;
}
int BaseWnd : : paint ( Canvas * c , api_region * r )
{
if ( isVirtual ( ) )
{
RegionI d ;
RECT cr ;
getClientRect ( & cr ) ;
if ( r = = NULL )
{
d . addRect ( & cr ) ;
}
else
{
d . addRegion ( r ) ;
d . offset ( cr . left , cr . top ) ;
}
ifc_window * rp = getRootParent ( ) ;
deferedInvalidate ( ) ;
rp - > paint ( NULL , & d ) ;
BltCanvas * cc = static_cast < BltCanvas * > ( rp - > getFrameBuffer ( ) ) ;
if ( r ! = NULL ) c - > selectClipRgn ( r ) ;
cc - > blit ( cr . left , cr . top , c , 0 , 0 , cr . right - cr . left , cr . bottom - cr . top ) ;
return 1 ;
}
if ( ! ensureVirtualCanvasOk ( ) ) return 0 ;
RegionI * deleteme = NULL ;
if ( r = = NULL )
{
RECT cr ;
getNonClientRect ( & cr ) ;
deleteme = new RegionI ( & cr ) ;
r = deleteme ;
}
virtualBeforePaint ( r ) ;
RECT rcPaint ;
r - > getBox ( & rcPaint ) ;
double ra = getRenderRatio ( ) ;
if ( deferedInvalidRgn )
{
api_region * nr = NULL ;
if ( renderRatioActive ( ) )
{
nr = r - > clone ( ) ;
double d = 1.0 / ra ;
nr - > scale ( d , d , TRUE ) ;
}
if ( deferedInvalidRgn - > isEmpty ( ) = = 0 )
{
// some deferednvalidated regions needs to be repainted
// TODO: need a "clear region" function in canvas
api_region * i = deferedInvalidRgn - > clone ( ) ;
# ifdef _WIN32
FillRgn ( virtualCanvas - > getHDC ( ) , i - > getOSHandle ( ) , ( HBRUSH ) GetStockObject ( BLACK_BRUSH ) ) ;
# elif defined(__APPLE__)
CGContextSaveGState ( virtualCanvas - > getHDC ( ) ) ;
virtualCanvas - > selectClipRgn ( i ) ;
CGContextClearRect ( virtualCanvas - > getHDC ( ) , CGRectInfinite ) ;
// virtualCanvas->selectClipRgn(0);
CGContextRestoreGState ( virtualCanvas - > getHDC ( ) ) ;
# endif
paintTree ( virtualCanvas , i ) ;
deferedValidateRgn ( i ) ;
deferedInvalidRgn - > disposeClone ( i ) ;
}
if ( nr ) r - > disposeClone ( nr ) ;
}
virtualAfterPaint ( r ) ;
if ( c ! = NULL )
{
commitFrameBuffer ( c , & rcPaint , ra ) ; //TH WDP2-212
}
delete deleteme ;
return 1 ;
}
int BaseWnd : : virtualOnPaint ( )
{
# ifdef _WIN32
RECT cr ;
getNonClientRect ( & cr ) ;
if ( cr . left > = cr . right | | cr . top > = cr . bottom ) return 0 ;
if ( ! ensureVirtualCanvasOk ( ) ) return 0 ;
RegionI reg ;
//CUT GetUpdateRgn(getOsWindowHandle(), r->getOSHandle(), FALSE);
Wasabi : : Std : : Wnd : : getUpdateRegion ( getOsWindowHandle ( ) , reg . getOSHandle ( ) ) ;
PaintCanvas paintcanvas ;
if ( ! paintcanvas . beginPaint ( this ) )
{
virtualAfterPaint ( & reg ) ; return 0 ;
}
// DO NOT DELETE - This looks like it does nothing, but it actually makes the GDI call us again with WM_PAINT if some window
// moves over this one between BeginPaint and EndPaint. We still use GetUpdateRgn so we don't have to check for
// the version of Windows. See doc. If this function is not available (should be here in 95/98/NT/2K, but we never know)
// then we use the rcPaint rect... less precise, but still works.
//CUT if (getRandomRgn) {
if ( Wasabi : : Std : : Wnd : : haveGetRandomRegion ( ) )
{
RegionI zap ;
//CUT getRandomRgn(paintcanvas.getHDC(), zap.getOSHandle(), SYSRGN);
Wasabi : : Std : : Wnd : : getRandomRegion ( paintcanvas . getHDC ( ) , zap . getOSHandle ( ) ) ;
}
else
{
RECT z ;
paintcanvas . getRcPaint ( & z ) ;
reg . setRect ( & z ) ;
}
// -------------
/*// for debug
HDC dc = GetDC ( getOsWindowHandle ( ) ) ;
InvertRgn ( dc , r - > getHRGN ( ) ) ;
InvertRgn ( dc , r - > getHRGN ( ) ) ;
ReleaseDC ( getOsWindowHandle ( ) , dc ) ; */
paint ( & paintcanvas , & reg ) ;
# else
# warning port me or remove me
# endif
return 1 ;
}
ifc_window * BaseWnd : : enumVirtualChild ( int _enum )
{
return virtualChildren [ _enum ] ;
}
int BaseWnd : : getNumVirtuals ( )
{
return virtualChildren . getNumItems ( ) ;
}
ifc_window * BaseWnd : : enumRootWndChildren ( int n )
{
return rootwndchildren . enumItem ( n ) ;
}
int BaseWnd : : getNumRootWndChildren ( )
{
return rootwndchildren . getNumItems ( ) ;
}
ifc_window * BaseWnd : : findRootWndChild ( int x , int y , int only_virtuals )
{
for ( int i = getNumRootWndChildren ( ) - 1 ; i > - 1 ; i - - )
{
RECT r ;
ifc_window * child = enumRootWndChildren ( i ) ;
//DebugStringW(L"findRootWndChild = entering = %s\n", child->getId());
if ( only_virtuals & & ! child - > isVirtual ( ) ) continue ;
child - > getNonClientRect ( & r ) ;
int _x = x ;
int _y = y ;
if ( ! child - > isVirtual ( ) )
{
POINT pt ;
child - > getPosition ( & pt ) ;
_x - = pt . x ;
_y - = pt . y ;
}
int iv = child - > isVisible ( 1 ) ;
//int gpa = child->getPaintingAlpha();
POINT _p = Wasabi : : Std : : makePoint ( _x , _y ) ;
if ( iv /*&& gpa > 0*/ & & Wasabi : : Std : : pointInRect ( r , _p ) )
{
// GROUP
ifc_window * z = child - > findRootWndChild ( _x , _y ) ;
if ( z ) return z ;
}
/*gpa > 0 &&*/
/*if (iv && _x>=r.left&&_x<=r.right&&_y>=r.top&&_y<=r.bottom && !child->isClickThrough() && child->ptInRegion(_x, _y)) {
return child ;
} */
}
return ( ! isClickThrough ( ) & & ptInRegion ( x , y ) ) ? this : NULL ;
}
//PORTME
int BaseWnd : : handleVirtualChildMsg ( UINT uMsg , int x , int y , void * p , void * d )
{
# ifdef _WIN32
ifc_window * child = NULL ;
if ( curVirtualChildCaptured )
child = curVirtualChildCaptured ;
else
child = findRootWndChild ( x , y , 1 ) ; // warning, can return this which is not virtual
// ASSERT(child != NULL); // BU this came up and I don't know why, looks like it should never happen
// FG> actually it can happen when coming back from a popup menu when cpu usage is high, the window might be
// hidden (destroying) and ptInRegion returns false.
if ( ! child ) return 0 ;
//int isvirtual = child->isVirtual();
if ( child ) child = child - > getForwardWnd ( ) ;
if ( child & & child - > isEnabled ( ) )
{
switch ( uMsg )
{
case WM_LBUTTONDOWN :
/* if (isvirtual && child != curVirtualChildFocus)
focusVirtualChild ( child ) ; */
autoFocus ( child ) ;
if ( child - > wantLeftClicks ( ) )
child - > onLeftButtonDown ( x , y ) ;
if ( child - > checkDoubleClick ( uMsg , x , y ) & & child - > wantDoubleClicks ( ) )
child - > onLeftButtonDblClk ( x , y ) ;
return 1 ;
case WM_RBUTTONDOWN :
/* if (isvirtual && child != curVirtualChildFocus)
focusVirtualChild ( child ) ; */
autoFocus ( child ) ;
if ( child - > wantRightClicks ( ) )
child - > onRightButtonDown ( x , y ) ;
if ( child - > checkDoubleClick ( uMsg , x , y ) & & child - > wantDoubleClicks ( ) )
child - > onRightButtonDblClk ( x , y ) ;
return 1 ;
case WM_LBUTTONUP :
if ( child - > wantLeftClicks ( ) )
child - > onLeftButtonUp ( x , y ) ;
return 1 ;
case WM_RBUTTONUP :
if ( child - > wantRightClicks ( ) )
child - > onRightButtonUp ( x , y ) ;
return 1 ;
case WM_MOUSEMOVE :
{
if ( curVirtualChildCaptured = = child | | ( curVirtualChildCaptured = = NULL ) )
{
if ( child - > wantMouseMoves ( ) )
child - > onMouseMove ( x , y ) ;
return 1 ;
}
return 0 ;
}
case WM_MOUSEHOVER :
( ( BaseWnd * ) child ) - > onTip ( ) ;
break ;
case WM_SETCURSOR :
int a = child - > getCursorType ( x , y ) ;
if ( ! p ) return 0 ;
* ( int * ) p = a ;
if ( a = = BASEWND_CURSOR_USERSET )
{
OSCURSORHANDLE c = child - > getCustomCursor ( x , y ) ;
if ( ! d ) return 0 ;
* ( OSCURSORHANDLE * ) d = c ;
}
return 1 ;
}
}
# else
# warning port me or remove me
# endif
return 0 ;
}
int BaseWnd : : onLeftButtonDown ( int x , int y )
{
disable_tooltip_til_recapture = 1 ;
abortTip ( ) ;
return 0 ;
}
int BaseWnd : : onLeftButtonUp ( int x , int y )
{
disable_tooltip_til_recapture = 1 ;
abortTip ( ) ;
return 0 ;
}
void BaseWnd : : setVirtualChildCapture ( ifc_window * child )
{
if ( child )
{
if ( ! inputCaptured )
{
beginCapture ( ) ;
}
}
else
{
endCapture ( ) ;
}
curVirtualChildCaptured = child ;
}
ifc_window * BaseWnd : : getVirtualChildCapture ( )
{
if ( inputCaptured & & Wasabi : : Std : : Wnd : : getCapture ( ) = = getOsWindowHandle ( ) )
return curVirtualChildCaptured ;
else
if ( inputCaptured ) inputCaptured = 0 ;
return NULL ;
}
ifc_window * BaseWnd : : getBaseTextureWindow ( )
{
// return our base texture window if we have it
if ( btexture )
return btexture ;
// return our parent's if they have it
if ( getParent ( ) )
return getParent ( ) - > getBaseTextureWindow ( ) ;
else
return NULL ;
}
void BaseWnd : : renderBaseTexture ( ifc_canvas * c , const RECT & r , int alpha )
{
WASABI_API_WND - > skin_renderBaseTexture ( getBaseTextureWindow ( ) , c , r , this , alpha ) ;
}
void BaseWnd : : setBaseTextureWindow ( ifc_window * w )
{
btexture = w ;
}
void BaseWnd : : setNotifyWindow ( ifc_window * newnotify )
{
notifyWindow = newnotify ;
}
ifc_window * BaseWnd : : getNotifyWindow ( )
{
return destroying ? NULL : notifyWindow ;
}
int BaseWnd : : gotFocus ( )
{
return hasfocus & & curVirtualChildFocus = = NULL ;
}
int BaseWnd : : isActive ( )
{
OSWINDOWHANDLE h = hwnd ;
if ( h = = NULL )
{
ifc_window * par = getParent ( ) ;
if ( par = = NULL ) return 0 ;
h = par - > getOsWindowHandle ( ) ;
}
if ( h = = NULL ) return 0 ;
return ( Wasabi : : Std : : Wnd : : getActiveWindow ( ) = = h ) ;
}
int BaseWnd : : onChar ( unsigned int c )
{
switch ( c )
{
case 9 : // TAB
if ( Std : : keyModifier ( STDKEY_SHIFT ) )
focusPrevious ( ) ;
else
focusNext ( ) ;
return 1 ;
}
return 0 ;
}
/*int BaseWnd::focusVirtualChild(api_window *child) {
if ( ! gotFocus ( ) ) setFocus ( ) ;
if ( ! child - > wantFocus ( ) ) return 0 ;
setVirtualChildFocus ( child ) ;
return 1 ;
} */
int BaseWnd : : wantFocus ( )
{
return 0 ;
}
// Return 1 if there is a modal window that is not this
int BaseWnd : : checkModal ( )
{
if ( bypassModal ( ) ) return 0 ;
ifc_window * w = WASABI_API_WND - > getModalWnd ( ) ;
if ( w & & w ! = static_cast < ifc_window * > ( this ) & & w ! = getDesktopParent ( ) )
{
return 1 ;
}
return 0 ;
}
int BaseWnd : : cascadeRepaintFrom ( ifc_window * who , int pack )
{
RECT r ;
BaseWnd : : getNonClientRect ( & r ) ;
return BaseWnd : : cascadeRepaintRect ( & r , pack ) ;
}
int BaseWnd : : cascadeRepaint ( int pack )
{
return cascadeRepaintFrom ( this , pack ) ;
}
int BaseWnd : : cascadeRepaintRgn ( api_region * r , int pack )
{
return cascadeRepaintRgnFrom ( r , this , pack ) ;
}
int BaseWnd : : cascadeRepaintRect ( RECT * r , int pack )
{
return cascadeRepaintRectFrom ( r , this , pack ) ;
}
int BaseWnd : : cascadeRepaintRectFrom ( RECT * r , ifc_window * who , int pack )
{
RegionI reg ( r ) ;
int rt = cascadeRepaintRgnFrom ( & reg , who , pack ) ;
return rt ;
}
void BaseWnd : : _cascadeRepaintRgn ( api_region * rg )
{
if ( ! ensureVirtualCanvasOk ( ) ) return ;
WndCanvas paintcanvas ;
if ( paintcanvas . attachToClient ( this ) = = 0 )
return ;
virtualBeforePaint ( rg ) ;
deferedInvalidateRgn ( rg ) ;
paintTree ( virtualCanvas , rg ) ;
virtualAfterPaint ( rg ) ;
double ra = getRenderRatio ( ) ;
RECT rcPaint ;
rg - > getBox ( & rcPaint ) ;
RECT rc ;
getClientRect ( & rc ) ; //JF> this gets it in virtual (non-scaled) coordinates,
// so we need to do these comparisons before scaling.
rcPaint . bottom = MIN ( ( int ) rc . bottom , ( int ) rcPaint . bottom ) ;
rcPaint . right = MIN ( ( int ) rc . right , ( int ) rcPaint . right ) ;
if ( renderRatioActive ( ) ) // probably faster than scaling the clone
{
rcPaint . left = ( int ) ( ( rcPaint . left - 1 ) * ra ) ;
rcPaint . top = ( int ) ( ( rcPaint . top - 1 ) * ra ) ;
rcPaint . right = ( int ) ( rcPaint . right * ra + 0.999999 ) ;
rcPaint . bottom = ( int ) ( rcPaint . bottom * ra + 0.999999 ) ;
}
rcPaint . left = MAX ( 0 , ( int ) rcPaint . left ) ;
rcPaint . top = MAX ( 0 , ( int ) rcPaint . top ) ;
rcPaint . right = MIN ( ( int ) rcPaint . right , ( int ) ( rwidth * ra ) ) ;
rcPaint . bottom = MIN ( ( int ) rcPaint . bottom , ( int ) ( rheight * ra ) ) ;
commitFrameBuffer ( & paintcanvas , & rcPaint , ra ) ;
}
void BaseWnd : : packCascadeRepaintRgn ( api_region * rg )
{
if ( ! deferedCascadeRepaintRgn ) deferedCascadeRepaintRgn = new RegionI ;
deferedCascadeRepaintRgn - > addRegion ( rg ) ;
need_flush_cascaderepaint = 1 ;
}
int BaseWnd : : cascadeRepaintRgnFrom ( api_region * _rg , ifc_window * who , int pack )
{
api_region * rg = _rg - > clone ( ) ;
int j = virtualChildren . searchItem ( who ) ;
for ( int i = 0 ; i < virtualChildren . getNumItems ( ) ; i + + )
{
ifc_window * w = virtualChildren [ i ] ;
if ( w ! = who & & w - > wantSiblingInvalidations ( ) )
w - > onSiblingInvalidateRgn ( rg , who , j , i ) ;
}
if ( ! pack )
{
_cascadeRepaintRgn ( rg ) ;
}
else
{
packCascadeRepaintRgn ( rg ) ;
}
_rg - > disposeClone ( rg ) ;
return 1 ;
}
void BaseWnd : : setDesktopAlpha ( int a )
{
if ( a & & ! Wasabi : : Std : : Wnd : : isDesktopAlphaAvailable ( ) ) return ;
if ( a = = w2k_alpha ) return ;
w2k_alpha = a ;
if ( ! a & & scalecanvas )
{
delete scalecanvas ;
scalecanvas = NULL ;
}
setLayeredWindow ( w2k_alpha ) ;
onSetDesktopAlpha ( a ) ;
}
void BaseWnd : : onSetDesktopAlpha ( int a ) { }
void BaseWnd : : commitFrameBuffer ( Canvas * paintcanvas , RECT * r , double ra )
{
if ( w2k_alpha & & Wasabi : : Std : : Wnd : : isDesktopAlphaAvailable ( ) & & ! cloaked )
{
//CUT BLENDFUNCTION blend= {AC_SRC_OVER, 0, wndalpha, AC_SRC_ALPHA };
//CUT POINT pt={0,0};
RECT spr ;
getWindowRect ( & spr ) ;
//CUT POINT sp={spr.left,spr.top};
//CUT SIZE ss={spr.right-spr.left, spr.bottom-spr.top};
int sw = spr . right - spr . left , sh = spr . bottom - spr . top ;
//CUT SysCanvas c;
if ( handleRatio ( ) & & renderRatioActive ( ) )
{
// eek slow!
RECT r ;
getWindowRect ( & r ) ;
int w = r . right - r . left ;
int h = r . bottom - r . top ;
if ( ! scalecanvas ) scalecanvas = new BltCanvas ( w , h , getOsWindowHandle ( ) ) ;
virtualCanvas - > stretchblit ( 0 , 0 , ( int ) ( ( double ) virtualCanvasW * 65536.0 ) , ( int ) ( ( double ) virtualCanvasH * 65536.0 ) , scalecanvas , 0 , 0 , w , h ) ;
}
//CUT updateLayeredWindow(hwnd, c.getHDC(), &sp, &ss, (scalecanvas ? scalecanvas : virtualCanvas)->getHDC(), &pt, 0, &blend, ULW_ALPHA);
Wasabi : : Std : : Wnd : : updateLayeredWnd ( hwnd , spr . left , spr . top , sw , sh , ( scalecanvas ? scalecanvas : virtualCanvas ) - > getHDC ( ) , wndalpha ) ;
}
else
{
if ( ABS ( ra - 1.0 ) < = 0.01 )
{
virtualCanvas - > blit ( r - > left , r - > top , paintcanvas , r - > left , r - > top , r - > right - r - > left , r - > bottom - r - > top ) ;
}
else
{
RECT tr = * r ;
double invra = 65536.0 / ra ;
int lp = tr . left ;
int tp = tr . top ;
int w = tr . right - tr . left ;
int h = tr . bottom - tr . top ;
int sx = ( int ) ( ( double ) lp * invra ) ;
int sy = ( int ) ( ( double ) tp * invra ) ;
int sw = ( int ) ( ( double ) w * invra ) ;
int sh = ( int ) ( ( double ) h * invra ) ;
virtualCanvas - > stretchblit ( sx , sy , sw , sh , paintcanvas , lp , tp , w , h ) ;
}
}
}
void BaseWnd : : flushPaint ( )
{
postDeferredCallback ( DEFERREDCB_FLUSHPAINT , 0 ) ;
}
void BaseWnd : : do_flushPaint ( )
{
if ( ! deferedInvalidRgn | | deferedInvalidRgn - > isEmpty ( ) ) return ;
api_region * r = deferedInvalidRgn - > clone ( ) ;
cascadeRepaintRgn ( r ) ;
deferedInvalidRgn - > disposeClone ( r ) ;
deferedInvalidRgn - > empty ( ) ;
}
int BaseWnd : : isMouseOver ( int x , int y )
{
POINT pt = { x , y } ;
clientToScreen ( & pt ) ;
return ( WASABI_API_WND - > rootWndFromPoint ( & pt ) = = this ) ;
}
void BaseWnd : : freeResources ( )
{ }
void BaseWnd : : reloadResources ( )
{
invalidate ( ) ;
}
double BaseWnd : : getRenderRatio ( )
{
if ( ! handleRatio ( ) ) return 1.0 ;
if ( ! ratiolinked ) return ratio ;
return getParent ( ) ? getParent ( ) - > getRenderRatio ( ) : ratio ;
}
void BaseWnd : : setRenderRatio ( double r )
{
// "snap" to 1.0
if ( ABS ( r - 1.0 ) < = 0.02f ) r = 1.0 ;
if ( scalecanvas )
{
delete scalecanvas ;
scalecanvas = NULL ;
}
if ( isInited ( ) & & r ! = ratio & & ! isVirtual ( ) & & ( ! getParent ( ) | | ! ratiolinked ) )
{
// must scale size & region accordingly
RECT rc ;
BaseWnd : : getWindowRect ( & rc ) ;
rc . right = rc . left + rwidth ;
rc . bottom = rc . top + rheight ;
ratio = r ;
resize ( & rc ) ;
invalidate ( ) ;
if ( isPostOnInit ( ) )
onRatioChanged ( ) ;
}
}
void BaseWnd : : setRatioLinked ( int l )
{
ratiolinked = l ;
if ( isPostOnInit ( ) )
setRenderRatio ( ratio ) ;
}
int BaseWnd : : renderRatioActive ( )
{
return ABS ( getRenderRatio ( ) - 1.0 ) > 0.01f ;
}
void BaseWnd : : multRatio ( int * x , int * y )
{
double rr = getRenderRatio ( ) ;
if ( x ) * x = ( int ) ( ( double ) ( * x ) * rr ) ;
if ( y ) * y = ( int ) ( ( double ) ( * y ) * rr ) ;
}
void BaseWnd : : multRatio ( RECT * r )
{
Wasabi : : Std : : scaleRect ( r , getRenderRatio ( ) ) ;
}
void BaseWnd : : divRatio ( int * x , int * y )
{
double rr = getRenderRatio ( ) ;
if ( x ) * x = ( int ) ( ( double ) ( * x ) / rr + 0.5 ) ;
if ( y ) * y = ( int ) ( ( double ) ( * y ) / rr + 0.5 ) ;
}
void BaseWnd : : divRatio ( RECT * r )
{
double rr = getRenderRatio ( ) ;
Wasabi : : Std : : scaleRect ( r , 1. / rr ) ;
}
void BaseWnd : : bringVirtualToFront ( ifc_window * w )
{
changeChildZorder ( w , 0 ) ;
}
void BaseWnd : : bringVirtualToBack ( ifc_window * w )
{
changeChildZorder ( w , virtualChildren . getNumItems ( ) - 1 ) ;
}
void BaseWnd : : bringVirtualAbove ( ifc_window * w , ifc_window * b )
{
ASSERT ( b - > isVirtual ( ) ) ;
int p = virtualChildren . searchItem ( b ) ;
if ( p = = - 1 ) return ;
changeChildZorder ( w , p ) ;
}
void BaseWnd : : bringVirtualBelow ( ifc_window * w , ifc_window * b )
{
ASSERT ( b - > isVirtual ( ) ) ;
int p = virtualChildren . searchItem ( b ) ;
if ( p = = - 1 ) return ;
changeChildZorder ( w , p + 1 ) ;
}
void BaseWnd : : changeChildZorder ( ifc_window * w , int newpos )
{
int p = newpos ;
p = MAX ( p , ( int ) 0 ) ;
p = MIN ( p , virtualChildren . getNumItems ( ) - 1 ) ;
RECT cr ;
w - > getClientRect ( & cr ) ;
PtrList < ifc_window > l ;
int i ;
for ( i = 0 ; i < virtualChildren . getNumItems ( ) ; i + + )
if ( virtualChildren [ i ] ! = w )
l . addItem ( virtualChildren [ i ] ) ;
p = virtualChildren . getNumItems ( ) - newpos - 1 ;
virtualChildren . removeAll ( ) ;
int done = 0 ;
for ( i = 0 ; i < l . getNumItems ( ) ; i + + )
if ( i = = p & & ! done )
{
virtualChildren . addItem ( w ) ;
i - - ;
done + + ;
}
else
{
RECT dr , intersection ;
l . enumItem ( i ) - > getClientRect ( & dr ) ;
if ( Wasabi : : Std : : rectIntersect ( intersection , dr , & cr ) )
l [ i ] - > invalidateRect ( & intersection ) ;
virtualChildren . addItem ( l . enumItem ( i ) ) ;
}
if ( i = = p & & ! done )
virtualChildren . addItem ( w ) ;
w - > invalidate ( ) ;
}
int BaseWnd : : onActivate ( )
{
if ( hasVirtualChildren ( ) )
{
int l = getNumVirtuals ( ) ;
for ( int i = 0 ; i < l ; i + + )
{
ifc_window * r = enumVirtualChild ( i ) ;
r - > onActivate ( ) ;
}
}
return 0 ;
}
int BaseWnd : : onDeactivate ( )
{
if ( hasVirtualChildren ( ) )
{
int l = getNumVirtuals ( ) ;
for ( int i = 0 ; i < l ; i + + )
{
ifc_window * r = enumVirtualChild ( i ) ;
r - > onDeactivate ( ) ;
}
}
return 0 ;
}
int BaseWnd : : getDesktopAlpha ( )
{
return w2k_alpha ;
}
api_region * BaseWnd : : getRegion ( )
{
return NULL ;
}
//CUT int BaseWnd::isTransparencyAvailable() {
//CUT #ifdef WIN32
//CUT #else
//CUT #pragma warning port me!
//CUT #endif
//CUT return 0;
//CUT }
int BaseWnd : : handleTransparency ( )
{
2024-09-29 02:04:03 +00:00
return 1 ; // by default all arch handle transparency, only arch blitting directly on the SCREEN (if you blit directly on the DC it's still ok),
2024-09-24 12:54:57 +00:00
} // for instance, a vis or a video using overlay should return 0, this will let the layout auto manage its alpha as that window is shown/hiden
void BaseWnd : : setAlpha ( int active , int inactive )
{
if ( active = = 254 ) active = 255 ;
if ( active = = 1 ) active = 0 ;
if ( inactive = = 254 ) inactive = 255 ;
if ( inactive = = 1 ) inactive = 0 ;
int oldactivealpha = activealpha ;
active = MIN ( 255 , MAX ( 0 , active ) ) ;
if ( inactive ! = - 1 ) inactive = MIN ( 255 , MAX ( 0 , inactive ) ) ;
if ( active ! = activealpha )
{
activealpha = active ;
if ( isActive ( ) )
{
invalidate ( ) ;
if ( ( oldactivealpha = = 0 | | activealpha = = 0 ) & & ( oldactivealpha ! = 0 | | activealpha ! = 0 ) )
invalidateWindowRegion ( ) ;
}
}
if ( inactive = = - 1 ) inactive = active ;
if ( inactive ! = inactivealpha )
{
inactivealpha = inactive ;
if ( ! isActive ( ) )
{
invalidate ( ) ;
if ( ( oldactivealpha = = 0 | | activealpha = = 0 ) & & ( oldactivealpha ! = 0 | | activealpha ! = 0 ) )
invalidateWindowRegion ( ) ;
}
}
}
void BaseWnd : : getAlpha ( int * active , int * inactive )
{
if ( active ) * active = activealpha ;
if ( inactive ) * inactive = inactivealpha ;
}
int BaseWnd : : getPaintingAlpha ( void )
{
int a = isActive ( ) ? MIN ( 255 , MAX ( 0 , activealpha ) ) : MIN ( 255 , MAX ( 0 , inactivealpha ) ) ;
ASSERT ( a > = 0 & & a < = 255 ) ;
if ( getParent ( ) & & getParent ( ) - > isVirtual ( ) )
{
int b = getParent ( ) - > getPaintingAlpha ( ) ;
a = ( int ) ( ( double ) a / 255.0 * ( double ) b ) ;
}
if ( a = = 254 ) a = 255 ;
if ( a = = 1 ) a = 0 ;
if ( ! isEnabled ( ) ) a = ( int ) ( a * 0.6 ) ;
return a ;
}
void BaseWnd : : setClickThrough ( int ct )
{
clickthrough = ct ;
}
int BaseWnd : : isClickThrough ( )
{
return clickthrough ;
}
int BaseWnd : : handleRatio ( )
{
return 1 ;
}
# include <api/script/objects/c_script/c_rootobj.h>
int BaseWnd : : createTip ( )
{
destroyTip ( ) ;
tooltip = new Tooltip ( getTip ( ) ) ;
return - 1 ;
}
void BaseWnd : : destroyTip ( )
{
// this is to avoid pb if destroytip() is being called by a time while destroying tip
Tooltip * tt = tooltip ;
tooltip = NULL ;
delete tt ;
}
int BaseWnd : : runModal ( )
{
//PORTME
# ifdef _WIN32
ifc_window * dp = getDesktopParent ( ) ;
if ( dp & & dp ! = this )
return dp - > runModal ( ) ;
MSG msg ;
// SetCapture(NULL);
SetFocus ( getOsWindowHandle ( ) ) ;
WASABI_API_WND - > pushModalWnd ( this ) ;
returnvalue = 0 ;
mustquit = 0 ;
// Main message loop:
while ( ! mustquit )
{
mustquit = ! GetMessage ( & msg , NULL , 0 , 0 ) ;
if ( ! msg . hwnd | | ! TranslateAccelerator ( msg . hwnd , NULL , & msg ) )
{
TranslateMessage ( & msg ) ;
DispatchMessage ( & msg ) ;
}
}
WASABI_API_WND - > popModalWnd ( this ) ;
// SetCapture(NULL);
return returnvalue ;
# else
# warning port me
return 0 ;
# endif
}
void BaseWnd : : endModal ( int ret )
{
ifc_window * dp = getDesktopParent ( ) ;
if ( dp & & dp ! = this )
{
dp - > endModal ( ret ) ;
return ;
}
returnvalue = ret ;
mustquit = 1 ;
}
int BaseWnd : : wantAutoContextMenu ( )
{
return 1 ;
}
void BaseWnd : : onCancelCapture ( )
{ }
ifc_window * BaseWnd : : getNextVirtualFocus ( ifc_window * w )
{
if ( w = = NULL )
{
if ( childtabs . getNumItems ( ) > 0 )
return childtabs . getFirst ( ) - > wnd ;
}
int a = getTabOrderEntry ( w ) + 1 ;
if ( a < childtabs . getNumItems ( ) )
return childtabs . enumItem ( a ) - > wnd ;
return NULL ;
}
void BaseWnd : : setVirtualChildFocus ( ifc_window * w )
{
ASSERT ( w & & w - > isVirtual ( ) ) ;
if ( curVirtualChildFocus )
curVirtualChildFocus - > onKillFocus ( ) ;
curVirtualChildFocus = w ;
onSetRootFocus ( w ) ;
Wasabi : : Std : : Wnd : : setFocus ( getOsWindowHandle ( ) ) ;
if ( curVirtualChildFocus )
curVirtualChildFocus - > onGetFocus ( ) ;
}
int BaseWnd : : ptInRegion ( int x , int y )
{
RECT cr ;
getNonClientRect ( & cr ) ;
POINT pt = { x - cr . left , y - cr . top } ;
api_region * reg = getRegion ( ) ;
if ( isRectRgn ( ) )
return ( x > = cr . left & & x < = cr . right & & y > = cr . top & & y < = cr . bottom ) ;
return reg ? reg - > ptInRegion ( & pt ) : 0 ;
}
api_region * BaseWnd : : getComposedRegion ( )
{
ensureWindowRegionValid ( ) ;
return composedrgn ;
}
api_region * BaseWnd : : getSubtractorRegion ( )
{
ensureWindowRegionValid ( ) ;
return subtractorrgn ;
}
int BaseWnd : : ensureWindowRegionValid ( )
{
if ( ! isInited ( ) ) return 0 ;
if ( wndregioninvalid )
{
computeComposedRegion ( ) ;
return 1 ;
}
return 0 ;
}
void BaseWnd : : invalidateWindowRegion ( )
{
wndregioninvalid = 1 ;
if ( getParent ( ) ) getParent ( ) - > invalidateWindowRegion ( ) ;
}
void BaseWnd : : computeComposedRegion ( )
{
if ( ! isPostOnInit ( ) ) return ;
wndregioninvalid = 0 ;
RECT r ;
getNonClientRect ( & r ) ;
api_region * reg = getRegion ( ) ;
RegionI * _reg = NULL ;
if ( ! reg )
{
_reg = new RegionI ;
reg = _reg ;
if ( isRectRgn ( ) )
reg - > setRect ( & r ) ;
}
else
if ( isRectRgn ( ) )
reg - > setRect ( & r ) ;
api_region * wr = reg - > clone ( ) ;
if ( ! subtractorrgn ) subtractorrgn = new RegionI ( ) ;
subtractorrgn - > empty ( ) ;
if ( ! composedrgn ) composedrgn = new RegionI ;
composedrgn - > empty ( ) ;
RegionI * subme = NULL ;
RegionI * andme = NULL ;
RegionI * orme = NULL ;
// if subregion is now empty, we need to only use our region
RECT gr ;
getNonClientRect ( & gr ) ;
for ( int i = 0 ; i < virtualChildren . getNumItems ( ) ; i + + )
{
ifc_window * srw = virtualChildren . enumItem ( i ) ;
if ( ! srw - > isVisible ( 1 ) | | srw - > getPaintingAlpha ( ) = = 0 ) continue ;
if ( srw - > getRegionOp ( ) ! = REGIONOP_NONE )
{
api_region * sr = srw - > getComposedRegion ( ) ;
if ( sr )
{
api_region * osr = sr - > clone ( ) ;
RECT r ;
srw - > getNonClientRect ( & r ) ;
r . left - = gr . left ;
r . top - = gr . top ;
osr - > offset ( r . left , r . top ) ;
/* sr->debug();
osr - > debug ( ) ; */
if ( srw - > getRegionOp ( ) = = REGIONOP_OR )
{
if ( ! orme ) orme = new RegionI ;
orme - > addRegion ( osr ) ;
}
else if ( srw - > getRegionOp ( ) = = REGIONOP_AND )
{
if ( ! andme ) andme = new RegionI ;
andme - > addRegion ( osr ) ;
}
else if ( srw - > getRegionOp ( ) = = REGIONOP_SUB )
{
if ( ! subme ) subme = new RegionI ;
subme - > addRegion ( osr ) ;
}
else if ( srw - > getRegionOp ( ) = = REGIONOP_SUB2 )
{
if ( ! subme ) subme = new RegionI ;
subtractorrgn - > addRegion ( osr ) ;
}
sr - > disposeClone ( osr ) ;
}
}
api_region * sr = srw - > getSubtractorRegion ( ) ;
if ( sr ! = NULL & & ! sr - > isEmpty ( ) )
{
api_region * osr = sr - > clone ( ) ;
RECT r ;
srw - > getNonClientRect ( & r ) ;
r . left - = gr . left ;
r . top - = gr . top ;
osr - > offset ( r . left , r . top ) ;
subtractorrgn - > addRegion ( osr ) ;
sr - > disposeClone ( osr ) ;
}
}
if ( andme )
{
wr - > andRegion ( andme ) ;
delete andme ;
}
if ( orme )
{
wr - > addRegion ( orme ) ;
delete orme ;
}
if ( subme )
{
wr - > subtractRgn ( subme ) ;
delete subme ;
}
composedrgn - > addRegion ( wr ) ;
reg - > disposeClone ( wr ) ;
delete _reg ;
}
void BaseWnd : : updateWindowRegion ( )
{
if ( ! isPostOnInit ( ) | | isVirtual ( ) ) return ;
if ( getDesktopAlpha ( ) )
{
// if desktopalpha is on, we can't use regions (thanks MS), we have to rely on the framebuffer correctness
//CUT SetWindowRgn(getOsWindowHandle(), NULL, FALSE);
Wasabi : : Std : : Wnd : : setWndRegion ( getOsWindowHandle ( ) , NULL ) ;
return ;
}
api_region * _r = getComposedRegion ( ) ;
api_region * _s = getSubtractorRegion ( ) ;
ASSERT ( _r ! = NULL & & _s ! = NULL ) ;
api_region * z = _r - > clone ( ) ;
z - > subtractRgn ( _s ) ;
assignWindowRegion ( z ) ;
_r - > disposeClone ( z ) ;
}
// wr is NOT scaled!!!
void BaseWnd : : assignWindowRegion ( api_region * wr )
{
ASSERT ( wr ! = NULL ) ;
if ( ! isPostOnInit ( ) ) return ;
int isrect = wr - > isRect ( ) ;
RECT r ;
BaseWnd : : getWindowRect ( & r ) ;
//DebugStringW( L"\nBaseWnd::assignWindowRegion() r before - x = %d, y = %d, w = %d, h = %d \n", r.left, r.top, r.right - r.left, r.bottom - r.top );
r . right - = r . left ;
r . left = 0 ;
r . bottom - = r . top ;
r . top = 0 ;
//DebugStringW( L"BaseWnd::assignWindowRegion() r after - x = %d, y = %d, w = %d, h = %d \n", r.left, r.top, r.right - r.left, r.bottom - r.top );
RECT z ;
wr - > getBox ( & z ) ;
//DebugStringW( L"BaseWnd::assignWindowRegion() z before - x = %d, y = %d, w = %d, h = %d \n", z.left, z.top, z.right - z.left, z.bottom - z.top );
z . left = 0 ;
z . top = 0 ;
//DebugStringW( L"BaseWnd::assignWindowRegion() z after - x = %d, y = %d, w = %d, h = %d \n", z.left, z.top, z.right - z.left, z.bottom - z.top );
if ( renderRatioActive ( ) )
{
double i = getRenderRatio ( ) ;
wr - > scale ( i , i , FALSE ) ;
}
RECT sz ;
wr - > getBox ( & sz ) ;
//DebugStringW( L"BaseWnd::assignWindowRegion() sz before - x = %d, y = %d, w = %d, h = %d \n", sz.left, sz.top, sz.right - sz.left, sz.bottom - sz.top );
sz . right - = sz . left ;
sz . bottom - = sz . top ;
sz . left = 0 ;
sz . top = 0 ;
//DebugStringW( L"BaseWnd::assignWindowRegion() sz after - x = %d, y = %d, w = %d, h = %d \n", sz.left, sz.top, sz.right - sz.left, sz.bottom - sz.top );
if ( isrect & &
( ( z . right = = rwidth & & z . bottom = = rheight ) | |
( sz . left = = r . left & & sz . right = = r . right & & sz . top = = r . top & & sz . bottom = = r . bottom ) | |
( 0 )
)
)
{
//CUT SetWindowRgn(getOsWindowHandle(), NULL, TRUE);
if ( ! lastnullregion )
{
Wasabi : : Std : : Wnd : : setWndRegion ( getOsWindowHandle ( ) , NULL , TRUE ) ;
lastnullregion = 1 ;
}
}
else
{
//DebugStringW(L"setting region, rwidth = %d, rheight = %d, z.right = %d, z.bottom = %d\n", rwidth, rheight, z.right, z.bottom);
//CUT SetWindowRgn(getOsWindowHandle(), wr->makeWindowRegion(), TRUE);
Wasabi : : Std : : Wnd : : setWndRegion ( getOsWindowHandle ( ) , wr - > makeWindowRegion ( ) , TRUE ) ;
lastnullregion = 0 ;
}
}
void BaseWnd : : performBatchProcesses ( )
{
// recompute the window region if needed and apply it to the HWND
if ( wndregioninvalid & & ! isVirtual ( ) )
if ( ensureWindowRegionValid ( ) )
updateWindowRegion ( ) ;
if ( need_flush_cascaderepaint )
{
_cascadeRepaintRgn ( deferedCascadeRepaintRgn ) ;
deferedCascadeRepaintRgn - > empty ( ) ;
need_flush_cascaderepaint = 0 ;
}
}
int BaseWnd : : getRegionOp ( )
{
return regionop ;
}
void BaseWnd : : setRegionOp ( int op )
{
if ( regionop ! = op )
{
regionop = op ;
invalidateWindowRegion ( ) ;
}
}
int BaseWnd : : isRectRgn ( )
{
return rectrgn ;
}
void BaseWnd : : setRectRgn ( int i )
{
rectrgn = i ;
}
TimerClient * BaseWnd : : timerclient_getMasterClient ( )
{
if ( ! isVirtual ( ) ) return this ;
ifc_window * w = getParent ( ) ;
if ( w )
{
TimerClient * tc = w - > getTimerClient ( ) ;
if ( tc )
return tc - > timerclient_getMasterClient ( ) ;
}
return NULL ;
}
void BaseWnd : : timerclient_onMasterClientMultiplex ( )
{
performBatchProcesses ( ) ;
}
TimerClient * BaseWnd : : getTimerClient ( )
{
return this ;
}
ifc_dependent * BaseWnd : : rootwnd_getDependencyPtr ( )
{
return this ;
}
ifc_dependent * BaseWnd : : timerclient_getDependencyPtr ( )
{
return this ;
}
void BaseWnd : : addMinMaxEnforcer ( ifc_window * w )
{
minmaxEnforcers . addItem ( w ) ;
signalMinMaxEnforcerChanged ( ) ;
}
void BaseWnd : : removeMinMaxEnforcer ( ifc_window * w )
{
minmaxEnforcers . removeItem ( w ) ;
signalMinMaxEnforcerChanged ( ) ;
}
void BaseWnd : : signalMinMaxEnforcerChanged ( void )
{
ifc_window * w = getDesktopParent ( ) ;
if ( w = = NULL | | w = = this ) onMinMaxEnforcerChanged ( ) ;
else w - > signalMinMaxEnforcerChanged ( ) ;
}
int BaseWnd : : getNumMinMaxEnforcers ( )
{
return minmaxEnforcers . getNumItems ( ) ;
}
ifc_window * BaseWnd : : enumMinMaxEnforcer ( int n )
{
return minmaxEnforcers . enumItem ( n ) ;
}
int BaseWnd : : onAction ( const wchar_t * action , const wchar_t * param , int x , int y , intptr_t p1 , intptr_t p2 , void * data , size_t datalen , ifc_window * source )
{
return 1 ;
}
int BaseWnd : : sendAction ( ifc_window * target , const wchar_t * action , const wchar_t * param , int x , int y , intptr_t p1 , intptr_t p2 , void * data , size_t datalen )
{
ASSERT ( target ! = NULL ) ;
return target - > onAction ( action , param , x , y , p1 , p2 , data , datalen , this ) ;
}
int BaseWnd : : virtualBeforePaint ( api_region * r )
{
if ( ! virtualCanvas ) return 0 ;
PaintCallbackInfoI pc ( virtualCanvas , r ) ;
dependent_sendEvent ( BaseWnd : : depend_getClassGuid ( ) , Event_ONPAINT , PaintCallback : : BEFOREPAINT , & pc ) ;
return 1 ;
}
int BaseWnd : : virtualAfterPaint ( api_region * r )
{
if ( ! virtualCanvas ) return 0 ;
PaintCallbackInfoI pc ( virtualCanvas , r ) ;
dependent_sendEvent ( BaseWnd : : depend_getClassGuid ( ) , Event_ONPAINT , PaintCallback : : AFTERPAINT , & pc ) ;
return 1 ;
}
int BaseWnd : : timerclient_onDeferredCallback ( intptr_t p1 , intptr_t p2 )
{
TimerClientI : : timerclient_onDeferredCallback ( p1 , p2 ) ;
return onDeferredCallback ( p1 , p2 ) ;
}
void BaseWnd : : timerclient_timerCallback ( int id )
{
TimerClientI : : timerclient_timerCallback ( id ) ;
timerCallback ( id ) ;
}
int BaseWnd : : setTimer ( int id , int ms )
{
return timerclient_setTimer ( id , ms ) ;
}
int BaseWnd : : killTimer ( int id )
{
return timerclient_killTimer ( id ) ;
}
void BaseWnd : : postDeferredCallback ( intptr_t p1 , intptr_t p2 , int mindelay )
{
# ifdef _WIN32
// TODO: re-enable, but post to some other window (e.g. some singleton window), not this window
// because our message pump might be blocked
// maybe make a hidden window in api_timer for this purpose
//if (mindelay)
timerclient_postDeferredCallback ( p1 , p2 , mindelay ) ;
//else
//PostMessage(hwnd, WM_DEFER_CALLBACK, p1, p2);
# else
# warning "port me - I can be optimized - don't use timers for this, use mac os x equiv of PostMessage!"
timerclient_postDeferredCallback ( p1 , p2 , mindelay ) ;
# endif
}
int BaseWnd : : bypassModal ( )
{
return 0 ;
}
void BaseWnd : : setRenderBaseTexture ( int r )
{
renderbasetexture = r ;
if ( isInited ( ) ) invalidate ( ) ;
}
int BaseWnd : : getRenderBaseTexture ( )
{
return renderbasetexture ;
}
GuiObject * BaseWnd : : getGuiObject ( )
{
if ( my_guiobject = = NULL )
{
my_guiobject = static_cast < GuiObject * > ( getInterface ( guiObjectGuid ) ) ;
}
return my_guiobject ;
}
//CUT someday
int BaseWnd : : getFlag ( int flag )
{
/* switch (flag) {
} */
return 0 ;
}
int BaseWnd : : triggerEvent ( int event , intptr_t p1 , intptr_t p2 )
{
//PORTME
switch ( event )
{
case TRIGGER_ONRESIZE :
if ( isPostOnInit ( ) )
onResize ( ) ;
break ;
case TRIGGER_INVALIDATE :
if ( isPostOnInit ( ) )
invalidate ( ) ;
break ;
}
return 0 ;
}
void BaseWnd : : registerAcceleratorSection ( const wchar_t * name , int global )
{
# if defined(WASABI_COMPILE_LOCALES)
WASABI_API_LOCALE - > locales_registerAcceleratorSection ( name , this , global ) ;
# endif
}
int BaseWnd : : onAcceleratorEvent ( const wchar_t * name )
{
for ( int i = 0 ; i < getNumRootWndChildren ( ) ; i + + )
if ( enumRootWndChildren ( i ) - > onAcceleratorEvent ( name ) )
return 1 ;
return 0 ;
}
int BaseWnd : : allowDeactivation ( )
{
return allow_deactivate & ( ( WASABI_API_WND = = NULL ) | | WASABI_API_WND - > appdeactivation_isallowed ( this ) ) ;
}
void BaseWnd : : onMinimize ( )
{
if ( ! isVirtual ( ) )
{
dropVirtualCanvas ( ) ;
}
}
void BaseWnd : : dropVirtualCanvas ( )
{
deferedInvalidate ( ) ;
delete virtualCanvas ;
virtualCanvas = NULL ;
}
void BaseWnd : : onRestore ( )
{
if ( getDesktopParent ( ) = = this )
{
cascadeRepaint ( TRUE ) ;
}
}
ifc_window * BaseWnd : : findWindow ( const wchar_t * id )
{
RootWndFinder find_object ;
find_object . reset ( ) ;
find_object . setFindId ( id ) ;
ifc_window * ret = findWindowChain ( & find_object ) ;
# ifdef _DEBUG
if ( ret = = NULL )
DebugStringW ( L " findWindow : window not found by id ! %s \n " , id ) ;
# endif
return ret ;
}
ifc_window * BaseWnd : : findWindowByInterface ( GUID interface_guid )
{
RootWndFinder find_object ;
find_object . reset ( ) ;
find_object . setFindGuid ( interface_guid ) ;
ifc_window * ret = findWindowChain ( & find_object ) ;
# ifdef _DEBUG
char str [ 256 ] = { 0 } ;
nsGUID : : toChar ( interface_guid , str ) ;
if ( ret = = NULL )
DebugStringW ( L " findWindow : object not found by guid ! %s \n " , str ) ;
# endif
return ret ;
}
ifc_window * BaseWnd : : findWindowByCallback ( FindObjectCallback * cb )
{
ifc_window * ret = findWindowChain ( cb ) ;
# ifdef _DEBUG
if ( ret = = NULL )
DebugStringW ( L " findWindow : object not found by callback! \n " ) ;
# endif
return ret ;
}
ifc_window * BaseWnd : : findWindowChain ( FindObjectCallback * cb , ifc_window * wcaller )
{
if ( ! cb ) return NULL ;
if ( cb - > findobjectcb_matchObject ( this ) ) return this ;
// first lets not look in subdirectories
for ( int i = 0 ; i < getNumRootWndChildren ( ) ; i + + )
{
ifc_window * child = enumRootWndChildren ( i ) ;
if ( ! child | | child = = wcaller ) continue ;
if ( cb - > findobjectcb_matchObject ( child ) )
return child ;
}
// ok so it wasn't in our content, lets try to find it as a grandchildren
for ( int i = 0 ; i < getNumRootWndChildren ( ) ; i + + )
{
ifc_window * child = enumRootWndChildren ( i ) ;
if ( child - > getNumRootWndChildren ( ) > 0 )
{
ifc_window * ret = child - > findWindowChain ( cb , this ) ;
if ( ret ) return ret ;
}
}
// so it wasnt one of our children, we'll hop the tree up one level and ask our parent to find it
// for us. of course, our parents are smart, they won't ask us back when asking our sibblings
ifc_window * p = getParent ( ) ;
if ( p ! = NULL & & wcaller ! = p )
{
return p - > findWindowChain ( cb , this ) ;
}
return NULL ;
}
const wchar_t * BaseWnd : : timerclient_getName ( )
{
tcname = StringPrintfW ( L " name= \" %S \" , id= \" %s \" " , getRootWndName ( ) , getId ( ) ) ;
return tcname ;
}
void BaseWnd : : setTabOrder ( int a )
{
if ( getParent ( ) ! = NULL )
getParent ( ) - > setVirtualTabOrder ( this , a ) ;
}
int BaseWnd : : getTabOrder ( )
{
if ( getParent ( ) ! = NULL )
return getParent ( ) - > getVirtualTabOrder ( this ) ;
return - 1 ;
}
void BaseWnd : : recursive_setVirtualTabOrder ( ifc_window * w , float a , float lambda )
{
ASSERT ( w ! = NULL ) ;
childtabs . setAutoSort ( 0 ) ;
int i = getTabOrderEntry ( a ) ;
if ( i ! = - 1 )
{
TabOrderEntry * toe = childtabs . enumItem ( i ) ;
if ( toe - > wnd ! = w )
{
lambda + = TABORDER_K ;
if ( lambda ! = 1.0 )
recursive_setVirtualTabOrder ( toe - > wnd , a + lambda , lambda ) ;
}
else
{
return ;
}
}
i = getTabOrderEntry ( w ) ;
if ( i ! = - 1 )
{
delete childtabs . enumItem ( i ) ;
childtabs . removeByPos ( i ) ;
}
TabOrderEntry * toe = new TabOrderEntry ;
toe - > wnd = w ;
toe - > order = a ;
childtabs . addItem ( toe ) ;
}
void BaseWnd : : setVirtualTabOrder ( ifc_window * w , int a )
{
if ( a = = - 1 )
{
delTabOrderEntry ( w ) ;
return ;
}
recursive_setVirtualTabOrder ( w , ( float ) a ) ;
}
int BaseWnd : : getVirtualTabOrder ( ifc_window * w )
{
int a = ( int ) getTabOrderEntry ( w ) ;
if ( a = = - 1 ) return - 1 ;
return ( int ) childtabs . enumItem ( a ) ;
}
int BaseWnd : : getTabOrderEntry ( ifc_window * w )
{
foreach ( childtabs )
if ( childtabs . getfor ( ) - > wnd = = w )
return foreach_index ;
endfor ;
return - 1 ;
}
void BaseWnd : : delTabOrderEntry ( int i )
{
int a = getTabOrderEntry ( ( float ) i ) ;
if ( a = = - 1 ) return ;
childtabs . removeByPos ( a ) ;
}
void BaseWnd : : delTabOrderEntry ( ifc_window * w )
{
int a = getTabOrderEntry ( w ) ;
if ( a = = - 1 ) return ;
delete childtabs . enumItem ( a ) ;
childtabs . removeByPos ( a ) ;
}
int BaseWnd : : getTabOrderEntry ( float order )
{
foreach ( childtabs )
if ( childtabs . getfor ( ) - > order = = order )
return foreach_index ;
endfor ;
return - 1 ;
}
void BaseWnd : : setAutoTabOrder ( )
{
if ( ! getParent ( ) ) return ;
getParent ( ) - > setVirtualAutoTabOrder ( this ) ;
}
void BaseWnd : : setVirtualAutoTabOrder ( ifc_window * w )
{
delTabOrderEntry ( w ) ;
float o = 0 ;
for ( int i = 0 ; i < childtabs . getNumItems ( ) ; i + + )
{
o = MAX ( o , childtabs . enumItem ( i ) - > order ) ;
}
setVirtualTabOrder ( w , ( ( int ) o ) + 1 ) ;
}
void BaseWnd : : focusNext ( )
{
ifc_window * dp = getDesktopParent ( ) ;
if ( dp ! = this )
{
if ( dp ! = NULL )
dp - > focusNext ( ) ;
return ;
}
ifc_window * w = getTab ( TAB_GETNEXT ) ;
if ( w ! = NULL ) w - > setFocus ( ) ;
}
void BaseWnd : : focusPrevious ( )
{
ifc_window * dp = getDesktopParent ( ) ;
if ( dp ! = this )
{
if ( dp ! = NULL )
getDesktopParent ( ) - > focusPrevious ( ) ;
return ;
}
ifc_window * w = getTab ( TAB_GETPREVIOUS ) ;
if ( w ! = NULL ) w - > setFocus ( ) ;
}
void BaseWnd : : recursive_buildTabList ( ifc_window * from , PtrList < ifc_window > * list )
{
for ( int i = 0 ; i < from - > getNumTabs ( ) ; i + + )
{
ifc_window * r = from - > enumTab ( i ) ;
if ( r - > isVisible ( ) & & r - > getPaintingAlpha ( ) > 0 )
{
if ( r - > wantFocus ( ) )
list - > addItem ( r ) ;
recursive_buildTabList ( r , list ) ;
}
}
}
ifc_window * BaseWnd : : getTab ( int what )
{
PtrList < ifc_window > listnow ;
recursive_buildTabList ( this , & listnow ) ;
int p = listnow . searchItem ( rootfocus ) ;
if ( p = = - 1 )
for ( int i = 0 ; i < listnow . getNumItems ( ) ; i + + )
{
ifc_window * r = listnow . enumItem ( i ) ;
if ( r - > gotFocus ( ) )
{
//DebugString("desync of rootfocus, fixing\n");
p = i ;
assignRootFocus ( r ) ;
break ;
}
}
if ( what = = TAB_GETNEXT & & rootfocus ! = NULL )
{
p + + ;
if ( p > = listnow . getNumItems ( ) )
p = 0 ;
return listnow . enumItem ( p ) ;
}
else if ( what = = TAB_GETPREVIOUS & & rootfocus ! = NULL )
{
p - - ;
if ( p < 0 ) p = listnow . getNumItems ( ) - 1 ;
return listnow . enumItem ( p ) ;
}
else if ( what = = TAB_GETCURRENT )
{
return rootfocus ;
}
else if ( what = = TAB_GETFIRST | | ( what = = TAB_GETNEXT & & rootfocus = = NULL ) )
{
return listnow . getFirst ( ) ;
}
else if ( what = = TAB_GETLAST | | ( what = = TAB_GETPREVIOUS & & rootfocus = = NULL ) )
{
return listnow . getLast ( ) ;
}
return NULL ;
}
int BaseWnd : : getNumTabs ( )
{
return childtabs . getNumItems ( ) ;
}
ifc_window * BaseWnd : : enumTab ( int i )
{
childtabs . sort ( ) ;
return childtabs . enumItem ( i ) - > wnd ;
}
void BaseWnd : : onSetRootFocus ( ifc_window * w )
{
assignRootFocus ( w ) ;
ifc_window * dp = getDesktopParent ( ) ;
if ( dp & & dp ! = this ) dp - > onSetRootFocus ( w ) ;
}
void BaseWnd : : autoFocus ( ifc_window * w )
{
if ( w - > getFocusOnClick ( ) & & w - > wantFocus ( ) )
{
w - > setFocus ( ) ;
return ;
}
ifc_window * g = w ;
while ( 1 )
{
ifc_window * p = g - > getParent ( ) ;
if ( p = = NULL ) break ;
ifc_window * dp = p - > getDesktopParent ( ) ;
if ( dp & & dp ! = p )
{
if ( p - > wantFocus ( ) & & p - > getFocusOnClick ( ) )
{
p - > setFocus ( ) ;
return ;
}
g = p ;
}
else
break ;
}
}
void BaseWnd : : setNoLeftClicks ( int no )
{
noleftclick = no ;
}
void BaseWnd : : setNoRightClicks ( int no )
{
norightclick = no ;
}
void BaseWnd : : setNoDoubleClicks ( int no )
{
nodoubleclick = no ;
}
void BaseWnd : : setNoMouseMoves ( int no )
{
nomousemove = no ;
}
void BaseWnd : : setNoContextMenus ( int no )
{
nocontextmnu = no ;
}
void BaseWnd : : setDefaultCursor ( Cursor * c )
{
customdefaultcursor = c ;
}
OSCURSORHANDLE BaseWnd : : getCustomCursor ( int x , int y )
{
# ifdef _WIN32
return customdefaultcursor ? customdefaultcursor - > getOSHandle ( ) : NULL ;
# else
# warning port me
return 0 ;
# endif
}
Accessible * BaseWnd : : createNewAccObj ( )
{
waServiceFactory * f = WASABI_API_SVC - > service_enumService ( WaSvc : : ACCESSIBILITY , 0 ) ;
if ( f ! = NULL )
{
svc_accessibility * svc = castService < svc_accessibility > ( f ) ;
if ( svc ! = NULL )
{
Accessible * a = svc - > createAccessibleObject ( this ) ;
WASABI_API_SVC - > service_release ( svc ) ;
return a ;
}
}
return NULL ;
}
Accessible * BaseWnd : : getAccessibleObject ( int createifnotexist )
{
if ( ! createifnotexist ) return accessible ;
if ( ! accessible )
accessible = createNewAccObj ( ) ;
else
accessible - > addRef ( ) ;
return accessible ;
}
int BaseWnd : : accessibility_getState ( )
{
int state = 0 ;
if ( ! isVisible ( ) ) state | = STATE_SYSTEM_INVISIBLE ;
//if (isVirtual() && !wantFocus()) state |= STATE_SYSTEM_INVISIBLE;
if ( gotFocus ( ) ) state | = STATE_SYSTEM_FOCUSED ;
return state ;
}
void BaseWnd : : activate ( )
{
Wasabi : : Std : : Wnd : : setActiveWindow ( getRootParent ( ) - > getOsWindowHandle ( ) ) ;
}
void BaseWnd : : setOSWndName ( const wchar_t * name )
{
if ( isVirtual ( ) ) return ;
//#ifdef COMPILE_WASABI_SKIN // for some reason this isn't being correctly defined
if ( name )
{
Wasabi : : Std : : Wnd : : setWndName ( getOsWindowHandle ( ) , name ) ;
}
else
Wasabi : : Std : : Wnd : : setWndName ( getOsWindowHandle ( ) , L " " ) ;
}
const wchar_t * BaseWnd : : getOSWndName ( )
{
if ( isVirtual ( ) ) return NULL ;
wchar_t str [ 4096 ] = { 0 } ;
Wasabi : : Std : : Wnd : : getWndName ( getOsWindowHandle ( ) , str , 4095 ) ;
str [ 4095 ] = ' \0 ' ;
osname = str ;
return osname ;
}
# ifdef EXPERIMENTAL_INDEPENDENT_AOT
void BaseWnd : : setAlwaysOnTop ( int i )
{
// this function should not optimize itself
if ( getDesktopParent ( ) = = this )
{
if ( i )
{
//CUT SetWindowPos(getOsWindowHandle(), HWND_TOPMOST, 0,0,0,0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOOWNERZORDER);
Wasabi : : Std : : Wnd : : setTopmost ( getOsWindowHandle ( ) , TRUE ) ;
}
else
{
saveTopMosts ( ) ;
//CUT SetWindowPos(getOsWindowHandle(), HWND_NOTOPMOST, 0,0,0,0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOOWNERZORDER);
Wasabi : : Std : : Wnd : : setTopmost ( getOsWindowHandle ( ) , FALSE ) ;
restoreTopMosts ( ) ;
}
alwaysontop = i ;
return ;
}
ifc_window * p = getParent ( ) ;
if ( p ! = NULL )
p - > setAlwaysOnTop ( i ) ;
}
int BaseWnd : : getAlwaysOnTop ( )
{
if ( getDesktopParent ( ) = = this )
return alwaysontop ;
ifc_window * p = getParent ( ) ;
if ( ! p ) return 0 ;
return p - > getAlwaysOnTop ( ) ;
}
# endif
void BaseWnd : : wndwatcher_onDeleteWindow ( ifc_window * w )
{
if ( w = = rootfocus )
{
rootfocus = NULL ;
}
}
void BaseWnd : : assignRootFocus ( ifc_window * w )
{
rootfocuswatcher . watchWindow ( w ) ;
rootfocus = w ;
}
Canvas * BaseWnd : : getFrameBuffer ( )
{
return virtualCanvas ;
}
void BaseWnd : : setForeignWnd ( int i )
{
m_takenOver = i ;
}
int BaseWnd : : bufferizeLockedUIMsg ( int uMsg , int wParam , int lParam )
{
if ( WASABI_API_SKIN & & ! WASABI_API_SKIN - > skin_getLockUI ( ) ) return 0 ;
if ( ! uiwaslocked )
{
uiwaslocked = 1 ;
setTimer ( BUFFEREDMSG_TIMER_ID , 20 ) ;
}
bufferedMsgStruct msg ;
msg . msg = uMsg ;
msg . wparam = wParam ;
msg . lparam = lParam ;
bufferedmsgs . addItem ( msg ) ;
return 1 ;
}
void BaseWnd : : checkLockedUI ( )
{
//PORTME :(
# ifdef _WIN32
if ( WASABI_API_SKIN & & ! WASABI_API_SKIN - > skin_getLockUI ( ) )
{
uiwaslocked = 0 ;
killTimer ( BUFFEREDMSG_TIMER_ID ) ;
while ( bufferedmsgs . getNumItems ( ) > 0 )
{
bufferedMsgStruct msg = bufferedmsgs . enumItem ( 0 ) ;
bufferedmsgs . delByPos ( 0 ) ;
SendMessageW ( gethWnd ( ) , msg . msg , msg . wparam , msg . lparam ) ;
}
uiwaslocked = 0 ;
killTimer ( BUFFEREDMSG_TIMER_ID ) ;
}
# else
# warning port me
# endif
}
int BaseWnd : : isMinimized ( )
{
ifc_window * w = getDesktopParent ( ) ;
if ( w = = this | | w = = NULL ) return minimized ;
return w - > isMinimized ( ) ;
}
int BaseWnd : : reinit ( )
{
# ifdef _WIN32
int nochild = ( GetWindowLong ( gethWnd ( ) , GWL_STYLE ) & WS_POPUP ) ? 1 : 0 ;
int r = reinit ( parentWnd ? parentWnd : WASABI_API_WND - > main_getRootWnd ( ) , nochild ) ;
if ( w2k_alpha )
setLayeredWindow ( 1 ) ;
return r ;
# else
# warning port me!
# endif
}
int BaseWnd : : reinit ( ifc_window * parWnd , int nochild )
{
OSWINDOWHANDLE phwnd = parWnd - > getOsWindowHandle ( ) ;
ASSERT ( phwnd ! = NULL ) ;
int ret ;
if ( ! nochild ) parentWnd = parWnd ;
else parentWnd = NULL ;
ret = reinit ( parWnd - > getOsModuleHandle ( ) , phwnd , nochild ) ;
if ( ! ret ) parentWnd = NULL ; // abort
return ret ;
}
int BaseWnd : : reinit ( OSMODULEHANDLE moduleHandle , OSWINDOWHANDLE parent , int nochild )
{
RECT r ;
int w , h ;
onBeforeReinit ( ) ;
pushWindowRect ( ) ;
preventcancelcapture = 1 ;
int _isvisible = isVisible ( 1 ) ;
int hadcapture = inputCaptured ;
//DebugString("had capture = %d\n", hadcapture);
Wasabi : : Std : : Wnd : : releaseCapture ( ) ;
unparentHWNDChildren ( ) ;
BaseWnd : : getClientRect ( & r ) ;
hinstance = moduleHandle ;
ASSERT ( hinstance ! = NULL ) ;
w = ( r . right - r . left ) ;
h = ( r . bottom - r . top ) ;
rwidth = w ;
rheight = h ;
rx = r . left ;
ry = r . top ;
WASABI_API_WND - > appdeactivation_push_disallow ( this ) ;
// destroy old window
Wasabi : : Std : : Wnd : : hideWnd ( hwnd ) ; //Wasabi::Std::Wnd::destroyWnd(hwnd);
ghosthwnd . addItem ( hwnd ) ;
hwnd = Wasabi : : Std : : Wnd : : createWnd ( & r , nochild , acceptExternalDrops ( ) , parent , hinstance , static_cast < ifc_window * > ( this ) ) ;
# ifdef __APPLE__
# warning remove me
Wasabi : : Std : : Wnd : : showWnd ( hwnd ) ;
# endif
WASABI_API_WND - > appdeactivation_pop_disallow ( this ) ;
//ASSERT(hwnd != NULL); // lets fail nicely, this could happen for some win32 reason, we don't want to fail the whole app for it, so lets just fail the wnd
if ( hwnd = = NULL )
{
preventcancelcapture = 0 ;
return 0 ;
}
//CUT nreal++;
# ifdef _WIN32
//FUCKO
# ifdef URLDROPS
if ( acceptExternalDrops ( ) ) RegisterDragDrop ( hwnd , & m_target ) ;
# elif !defined(WA3COMPATIBILITY)
if ( ! m_target & & WASABI_API_WND ! = NULL )
m_target = WASABI_API_WND - > getDefaultDropTarget ( ) ;
if ( m_target ! = NULL )
{
RegisterDragDrop ( hwnd , ( IDropTarget * ) m_target ) ;
}
# endif
# else
# warning port me - register drag & drop
# endif
this_visible = _isvisible ;
//onInit();
//this_visible = !start_hidden;
reparentHWNDChildren ( ) ;
popWindowRect ( ) ;
invalidateWindowRegion ( ) ;
updateWindowRegion ( ) ;
if ( this_visible )
Wasabi : : Std : : Wnd : : showWnd ( hwnd , FALSE ) ;
if ( hadcapture )
{
Wasabi : : Std : : Wnd : : setCapture ( hwnd ) ;
}
preventcancelcapture = 0 ;
forcedOnResize ( ) ;
redrawHWNDChildren ( ) ;
//onPostOnInit();
onAfterReinit ( ) ;
# ifdef WASABI_ON_REPARENT
WASABI_ON_REINIT ( getOsWindowHandle ( ) ) ;
# endif
return 1 ;
}
ReparentWndEntry : : ReparentWndEntry ( OSWINDOWHANDLE _wnd , OSWINDOWHANDLE parentwnd )
{
wnd = _wnd ;
Wasabi : : Std : : Wnd : : getWindowRect ( wnd , & rect ) ;
Wasabi : : Std : : Wnd : : screenToClient ( wnd , ( int * ) & ( rect . left ) , ( int * ) & ( rect . top ) ) ;
Wasabi : : Std : : Wnd : : clientToScreen ( parentwnd , ( int * ) & ( rect . left ) , ( int * ) & ( rect . top ) ) ;
}
void ReparentWndEntry : : unparent ( )
{
Wasabi : : Std : : Wnd : : setWndPos ( wnd , NULL , rect . left , - 30000 , 0 , 0 , TRUE , TRUE , FALSE , FALSE , TRUE ) ;
Wasabi : : Std : : Wnd : : setParent ( wnd , NULL ) ;
}
void ReparentWndEntry : : reparent ( OSWINDOWHANDLE newparent )
{
Wasabi : : Std : : Wnd : : setParent ( wnd , newparent ) ;
Wasabi : : Std : : Wnd : : setWndPos ( wnd , NULL , rect . left , rect . top , 0 , 0 , TRUE , TRUE , FALSE , FALSE , TRUE ) ;
}
# ifdef _WIN32
void BaseWnd : : unparentHWNDChildren ( )
{
// just in case
reparentwnds . deleteAll ( ) ;
# ifndef WIN32
2024-09-29 02:04:03 +00:00
# error port me ! // make a list of all the children osarch and reparent them to the desktop somewhere we can't see
2024-09-24 12:54:57 +00:00
# endif
OSWINDOWHANDLE wnd = GetWindow ( getOsWindowHandle ( ) , GW_CHILD ) ;
while ( wnd )
{
reparentwnds . addItem ( new ReparentWndEntry ( wnd , getOsWindowHandle ( ) ) ) ;
wnd = GetWindow ( wnd , GW_HWNDNEXT ) ;
}
foreach ( reparentwnds )
reparentwnds . getfor ( ) - > unparent ( ) ;
endfor ;
}
# endif
void BaseWnd : : reparentHWNDChildren ( )
{
// reparent to the new oswindowhandle
foreach ( reparentwnds )
reparentwnds . getfor ( ) - > reparent ( getOsWindowHandle ( ) ) ;
endfor ;
}
void BaseWnd : : redrawHWNDChildren ( )
{
// reparent to the new oswindowhandle
foreach ( reparentwnds )
Wasabi : : Std : : Wnd : : update ( getOsWindowHandle ( ) ) ;
endfor ;
}
void BaseWnd : : maximize ( int axis )
{
//DebugString("maximize!\n");
// if already maximized, don't use current rect, use restore_rect
if ( ! maximized )
{
restore_rect . left = rx ;
restore_rect . top = ry ;
restore_rect . right = rx + rwidth ;
restore_rect . bottom = ry + rheight ;
}
RECT nr = restore_rect ;
RECT dr ;
Wasabi : : Std : : getViewport ( & dr , NULL , NULL , getOsWindowHandle ( ) , 0 ) ;
if ( axis & MAXIMIZE_WIDTH )
{
nr . left = dr . left ;
nr . right = dr . right ;
}
if ( axis & MAXIMIZE_HEIGHT )
{
nr . top = dr . top ;
nr . bottom = dr . bottom ;
}
maximized = 1 ;
if ( axis ! = 0 ) resize ( & nr ) ;
onMaximize ( ) ;
}
void BaseWnd : : restore ( int what )
{
if ( maximized )
{
//DebugString("restore!\n");
if ( what = = ( RESTORE_X | RESTORE_Y | RESTORE_WIDTH | RESTORE_HEIGHT ) )
resize ( & restore_rect ) ;
else
{
resize ( ( what & RESTORE_X ) ? restore_rect . left : NOCHANGE ,
( what & RESTORE_Y ) ? restore_rect . top : NOCHANGE ,
( what & RESTORE_WIDTH ) ? restore_rect . right - restore_rect . left : NOCHANGE ,
( what & RESTORE_HEIGHT ) ? restore_rect . bottom - restore_rect . top : NOCHANGE ) ;
}
maximized = 0 ;
onRestore ( ) ;
}
}
void BaseWnd : : pushWindowRect ( )
{
//DebugString("pushWindowRect\n");
RECT wr ;
getWindowRect ( & wr ) ;
wr . right = wr . left + rwidth ;
wr . bottom = wr . top + rheight ;
windowrectstack . push ( wr ) ;
}
int BaseWnd : : popWindowRect ( RECT * rc , int applyhow )
{
//DebugString("popWindowRect\n");
if ( windowrectstack . peek ( ) = = 0 ) return 0 ;
RECT _rc ;
windowrectstack . pop ( & _rc ) ;
RECT r ;
getWindowRect ( & r ) ;
divRatio ( & r ) ;
if ( applyhow )
{
if ( applyhow = = PWR_POSITION )
{
move ( _rc . left , _rc . top ) ;
if ( rc )
{
int w = r . right - r . left ;
int h = r . bottom - r . top ;
rc - > left = _rc . left ;
rc - > top = _rc . top ;
rc - > right = rc - > left + w ;
rc - > bottom = rc - > top + h ;
}
}
else
{
if ( applyhow & PWR_X ) r . left = _rc . left ;
if ( applyhow & PWR_Y ) r . top = _rc . top ;
if ( applyhow & PWR_WIDTH ) r . right = r . left + ( _rc . right - _rc . left ) ;
if ( applyhow & PWR_HEIGHT ) r . bottom = r . top + ( _rc . bottom - _rc . top ) ;
resizeToRect ( & r ) ;
if ( rc ) * rc = _rc ;
}
}
else if ( rc ) * rc = _rc ;
return 1 ;
}
void BaseWnd : : setRestoredRect ( RECT * r )
{
if ( ! r )
return ;
restore_rect = * r ;
maximized = 1 ;
}
int BaseWnd : : getRestoredRect ( RECT * r )
{
if ( ! r )
return 0 ;
if ( ! maximized )
return 0 ;
* r = restore_rect ;
return 1 ;
}
void BaseWnd : : notifyDeferredMove ( int x , int y )
{
rx = x ;
ry = y ;
}
void BaseWnd : : setWindowTitle ( const wchar_t * title )
{
Layout * l = static_cast < Layout * > ( getInterface ( layoutGuid ) ) ;
if ( l )
{
Container * c = l - > getParentContainer ( ) ;
if ( c )
{
c - > setName ( title ) ;
}
}
}
# ifdef __APPLE__
OSStatus BaseWnd : : eventHandler ( EventHandlerCallRef inHandlerCallRef , EventRef inEvent , void * inUserData )
{
return eventNotHandledErr ;
}
# endif