#include "stdafx.h" #include "CWindowManager.h" CWindowManager::CWindowManager() { FocusedWindow = NULL; CapturedWindow = NULL; LastMouseMove = NULL; FocusChangeCount = 0; Root.PrivateSetPosition( 0, 0 ); Root.PrivateSetSize( 1, 1 ); return; } CWindowManager::~CWindowManager() { return; } bool CWindowManager::SetWidth( float NewWidth ) { return Root.PrivateSetWidth( NewWidth ); } float CWindowManager::GetWidth() { return Root.GetWidth(); } bool CWindowManager::SetHeight( float NewHeight ) { return Root.PrivateSetHeight( NewHeight ); } float CWindowManager::GetHeight() { return Root.GetHeight(); } bool CWindowManager::SetSize( float NewWidth, float NewHeight ) { return Root.PrivateSetSize( NewWidth, NewHeight ); } bool CWindowManager::AddWindow( IWindow &Window ) { return Root.PrivateAddChild( Window ); } bool CWindowManager::RemoveWindow( IWindow &Window ) { return Root.PrivateRemoveChild( Window ); } IWindow *CWindowManager::SetFocusedWindow( IWindow * Window ) { bool FoundWindow = false; bool MustResetFocusChangeCount = false; IWindow *TempWindow = NULL; IWindow *OldFocusedWindow = FocusedWindow; unsigned long MyFocusID = 0; std::list< IWindow * >::iterator I; //IF THIS IS THE FIRST CALL TO SETFOCUSEDWINDOW IN A NESTED SET OF CALLS //THIS CALL MUST ALSO RESET THE FOCUSCHANGECOUNT TO 0 if( FocusChangeCount == 0 ) { MustResetFocusChangeCount = true; } //INCREMENT THE FOCUSCHANGECOUNT AND STORE THE LOCAL FOCUSID FocusChangeCount = FocusChangeCount + 1; MyFocusID = FocusChangeCount; //VERIFY THAT THE WINDOW THAT'S GOING TO RECEIVE FOCUS IS VALID //IE A NULL WINDOW OR ONE THAT'S IN THE WINDOW LIST if( Window != NULL ) { TempWindow = Window; while( TempWindow->GetParent() != NULL ) { TempWindow = TempWindow->GetParent(); } FoundWindow = false; if( TempWindow == &Root ) { FoundWindow = true; } if( FoundWindow == false ) { if( MustResetFocusChangeCount == true ) { FocusChangeCount = 0; } //RETURN UNSUCCESSFULLY return FocusedWindow; } } //UPDATE FOCUSEDWINDOW -- THE FOCUSEDWINDOW IS NULL DURING THE LOST AND GOTFOCUS EVENTS FocusedWindow = NULL; //IF THERE IS A CURRENT WINDOW WITH FOCUS CALL ITS ONLOSTFOCUS EVENT AND RETURN AN ERROR IF THE FOCUS DOES NOT END UP AS EXPECTED if( OldFocusedWindow != NULL ) { OldFocusedWindow->FireLostFocus( Window ); if( MyFocusID != FocusChangeCount ) { if( MustResetFocusChangeCount == true ) { FocusChangeCount = 0; } //RETURN UNSUCCESSFULLY return FocusedWindow; } } //IF THERE IS A NEW WINDOW TO RECEIVE FOCUS CALL ITS ONGOTFOCUS EVENT AND RETURN AN ERROR IF THE FOCUS DOES NOT END UP AS EXPECTED if( FocusedWindow != NULL ) { FocusedWindow->FireGotFocus( OldFocusedWindow ); if( MyFocusID != FocusChangeCount ) { if( MustResetFocusChangeCount == true ) { FocusChangeCount = 0; } //RETURN UNSUCCESSFULLY return FocusedWindow; } } //JUMP THE WINDOW AND ALL IT'S ANCESTORS TO THE TOP OF THE Z ORDER FOR VISUAL FOCUS FocusedWindow = Window; TempWindow = FocusedWindow; while( TempWindow != NULL ) { TempWindow->JumpToFront(); TempWindow = TempWindow->GetParent(); } //RESET THE FOCUSCHANGECOUNT IF NECESSARY if( MustResetFocusChangeCount == true ) { FocusChangeCount = 0; } //RETURN SUCCESSFULLY return FocusedWindow; } IWindow *CWindowManager::GetFocusedWindow() { return FocusedWindow; } IWindow *CWindowManager::GetWindowFromXY( float X, float Y ) { std::list< IWindow * >::const_reverse_iterator I; IWindow *Window = NULL; for( I = Root.GetChildren().rbegin(); I != Root.GetChildren().rend(); I++ ) { if( (*I)->GetVisible() == true ) { Window = GetChildFromXY( *I, X, Y ); if( Window != NULL ) { return Window; } } } return NULL; } void CWindowManager::OnRender( double TimeSlice ) { std::list< IWindow * >::const_iterator I; for( I = Root.GetChildren().begin(); I != Root.GetChildren().end(); I++ ) { if( (*I)->GetVisible() == true ) { RenderWindow( *I, TimeSlice ); } } return; } void CWindowManager::OnClick( float X, float Y, unsigned long Button ) { IWindow *TempWindow; TempWindow = GetWindowFromXY( X, Y ); if( TempWindow != NULL ) { TempWindow->FireClick( X - TempWindow->GetAbsoluteLeft() , Y - TempWindow->GetAbsoluteTop() , Button ); } return; } void CWindowManager::OnDoubleClick( float X, float Y, unsigned long Button ) { IWindow *TempWindow; TempWindow = GetWindowFromXY( X, Y ); if( TempWindow != NULL ) { TempWindow->FireDoubleClick( X - TempWindow->GetAbsoluteLeft() , Y - TempWindow->GetAbsoluteTop() , Button ); } return; } void CWindowManager::OnMouseDown( float X, float Y, unsigned long Button ) { IWindow *TempWindow; TempWindow = GetWindowFromXY( X, Y ); CapturedWindow = TempWindow; SetFocusedWindow( TempWindow ); if( TempWindow != NULL ) { TempWindow->FireMouseDown( X - TempWindow->GetAbsoluteLeft() , Y - TempWindow->GetAbsoluteTop() , Button ); } return; } void CWindowManager::OnMouseWheel( float X, float Y, unsigned long Button ) { IWindow *TempWindow; TempWindow = GetWindowFromXY( X, Y ); if( TempWindow != NULL ) { TempWindow->FireMouseWheel( X - TempWindow->GetAbsoluteLeft() , Y - TempWindow->GetAbsoluteTop() , Button ); } return; } void CWindowManager::OnMouseUp( float X, float Y, unsigned long Button ) { IWindow *TempWindow; if( CapturedWindow == NULL ) { TempWindow = GetWindowFromXY( X, Y ); } else { TempWindow = CapturedWindow; } if( TempWindow != NULL ) { TempWindow->FireMouseUp( X - TempWindow->GetAbsoluteLeft() , Y - TempWindow->GetAbsoluteTop() , Button ); if( CapturedWindow == GetWindowFromXY( X, Y ) ) { TempWindow->FireClick( X - TempWindow->GetAbsoluteLeft() , Y - TempWindow->GetAbsoluteTop() , Button ); } } CapturedWindow = NULL; if( LastMouseMove != TempWindow ) { if( LastMouseMove != NULL ) { LastMouseMove->FireMouseExit( X, Y, Button ); } if( TempWindow != NULL ) { TempWindow->FireMouseEnter( X, Y, Button ); } } LastMouseMove = TempWindow; return; } void CWindowManager::OnMouseMove( float X, float Y, unsigned long Button ) { IWindow *TempWindow; if( CapturedWindow == NULL ) { TempWindow = GetWindowFromXY( X, Y ); if( LastMouseMove != TempWindow ) { if( LastMouseMove != NULL ) { LastMouseMove->FireMouseExit( X, Y, Button ); } if( TempWindow != NULL ) { TempWindow->FireMouseEnter( X, Y, Button ); } } LastMouseMove = TempWindow; } else { TempWindow = CapturedWindow; } if( TempWindow != NULL ) { TempWindow->FireMouseMove( X - TempWindow->GetAbsoluteLeft() , Y - TempWindow->GetAbsoluteTop() , Button ); } return; } void CWindowManager::OnMouseEnter( float X, float Y, unsigned long Button ) { return; } void CWindowManager::OnMouseExit( float X, float Y, unsigned long Button ) { return; } void CWindowManager::OnKeyPress( unsigned long KeyCode ) { std::list< IWindow * >::const_iterator I; std::list< IWindow * >::const_iterator NextI; if( FocusedWindow == NULL ) { return; } //DEAL WITH FOCUS SWITCHING if( KeyCode == 9 ) { if( FocusedWindow->GetParent() != NULL ) { for( I = FocusedWindow->GetParent()->GetChildren().begin(); I != FocusedWindow->GetParent()->GetChildren().end(); I++ ) { if( FocusedWindow == *I ) { NextI = I++; if( NextI != FocusedWindow->GetParent()->GetChildren().end() ) { FocusedWindow = *NextI; } else { FocusedWindow = *(FocusedWindow->GetParent()->GetChildren().begin() ); } break; } } } } FocusedWindow->FireKeyPress( KeyCode ); return; } void CWindowManager::OnKeyDown( unsigned long KeyCode ) { if( FocusedWindow == NULL ) { return; } FocusedWindow->FireKeyDown( KeyCode ); return; } void CWindowManager::OnKeyUp( unsigned long KeyCode ) { if( FocusedWindow == NULL ) { return; } FocusedWindow->FireKeyUp( KeyCode ); return; } void CWindowManager::RenderWindow( IWindow * Window, double TimeSlice ) { std::list< IWindow * >::const_iterator I; Window->FireRender( TimeSlice ); for( I = Window->GetChildren().begin(); I != Window->GetChildren().end(); I++ ) { if( (*I)->GetVisible() == true ) { RenderWindow( *I, TimeSlice ); } } return; } IWindow *CWindowManager::GetChildFromXY( IWindow * Window, float X, float Y ) { IWindow *TempWindow = NULL; std::list< IWindow * >::const_reverse_iterator I; for( I = Window->GetChildren().rbegin(); I != Window->GetChildren().rend(); I++ ) { if( (*I)->GetVisible() == true ) { TempWindow = GetChildFromXY( *I, X, Y ); if( TempWindow != NULL ) { return TempWindow; } } } if( X >= Window->GetAbsoluteLeft() && X <= ( Window->GetAbsoluteLeft() + Window->GetWidth() ) && Y >= Window->GetAbsoluteTop() && Y <= ( Window->GetAbsoluteTop() + Window->GetHeight() ) ) { return Window; } return NULL; }