diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/Shell.h b/GeneralsMD/Code/GameEngine/Include/GameClient/Shell.h index 0caf3ed653..656a1764f1 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameClient/Shell.h +++ b/GeneralsMD/Code/GameEngine/Include/GameClient/Shell.h @@ -125,6 +125,8 @@ class Shell : public SubsystemInterface virtual void update( void ); //=============================================================================================== + void recreateWindowLayouts( void ); + void showShellMap(Bool useShellMap ); ///< access function to turn on and off the shell map void hide( Bool hide ); ///< show/hide all shell layouts @@ -141,8 +143,6 @@ class Shell : public SubsystemInterface WindowLayout *findScreenByFilename( AsciiString filename ); ///< find screen inline Bool isShellActive( void ) { return m_isShellActive; } ///< Returns true if the shell is active - - inline Int getScreenCount(void) { return m_screenCount; } ///< Return the current number of screens void registerWithAnimateManager( GameWindow *win, AnimTypes animType, Bool needsToFinish, UnsignedInt delayMS = 0); Bool isAnimFinished( void ); @@ -152,6 +152,9 @@ class Shell : public SubsystemInterface void loadScheme( AsciiString name ); ShellMenuSchemeManager *getShellMenuSchemeManager( void ) { return m_schemeManager; } + Int getScreenCount( void ) const { return m_screenCount; } ///< Return the current number of screens + WindowLayout *getScreenLayout( Int index ) const; + WindowLayout *getSaveLoadMenuLayout( void ); ///< create if necessary and return layout for save load menu WindowLayout *getPopupReplayLayout( void ); ///< create if necessary and return layout for replay save menu WindowLayout *getOptionsLayout( Bool create ); ///< return layout for options menu, create if necessary and we are allowed to. @@ -159,6 +162,9 @@ class Shell : public SubsystemInterface protected: + void construct( void ); + void deconstruct( void ); + void linkScreen( WindowLayout *screen ); ///< link screen to list void unlinkScreen( WindowLayout *screen ); ///< remove screen from list diff --git a/GeneralsMD/Code/GameEngine/Include/GameClient/WindowLayout.h b/GeneralsMD/Code/GameEngine/Include/GameClient/WindowLayout.h index 719ab1e639..9770c3ce4e 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameClient/WindowLayout.h +++ b/GeneralsMD/Code/GameEngine/Include/GameClient/WindowLayout.h @@ -62,17 +62,17 @@ class WindowLayout : public MemoryPoolObject // ~WindowLayout( void ); ///< defined by memory pool glue // manipulating screen properties --------------------------------------------------------------- - AsciiString getFilename( void ); ///< return source window filename - Bool load( AsciiString filename ); ///< create windows and load from .wnd file - void hide( Bool hide ); ///< hide/unhide all windows on this screen - Bool isHidden( void ); ///< return visible state of screen + AsciiString getFilename( void ) const; ///< return source window filename + Bool load( AsciiString filename ); ///< create windows and load from .wnd file + void hide( Bool hide ); ///< hide/show all windows on this screen + Bool isHidden( void ) const; ///< return visible state of screen void bringForward( void ); ///< bring all windows in this screen forward // manipulating window lists -------------------------------------------------------------------- void addWindow( GameWindow *window ); ///< add window to screen void removeWindow( GameWindow *window ); ///< remove window from screen void destroyWindows( void ); ///< destroy all windows in this screen - GameWindow *getFirstWindow( void ); ///< get first window in list for screen + GameWindow *getFirstWindow( void ) const; ///< get first window in list for screen // accessing layout callbacks ------------------------------------------------------------------ void runInit( void *userData = NULL ); ///< run the init method if available @@ -110,9 +110,9 @@ class WindowLayout : public MemoryPoolObject }; // end class WindowLayout // INLINING /////////////////////////////////////////////////////////////////////////////////////// -inline AsciiString WindowLayout::getFilename( void ) { return m_filenameString; } -inline GameWindow *WindowLayout::getFirstWindow( void ) { return m_windowList; } -inline Bool WindowLayout::isHidden( void ) { return m_hidden; } +inline AsciiString WindowLayout::getFilename( void ) const { return m_filenameString; } +inline GameWindow *WindowLayout::getFirstWindow( void ) const { return m_windowList; } +inline Bool WindowLayout::isHidden( void ) const { return m_hidden; } inline void WindowLayout::runInit( void *userData ) { if( m_init ) m_init( this, userData ); } inline void WindowLayout::runUpdate( void *userData ) { if( m_update ) m_update( this, userData ); } diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/MainMenu.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/MainMenu.cpp index f507410f4d..7b6052efff 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/MainMenu.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/MainMenu.cpp @@ -761,18 +761,9 @@ void DeclineResolution() optionPref["Resolution"] = prefString; optionPref.write(); - // delete the shell - delete TheShell; - TheShell = NULL; - - // create the shell - TheShell = MSGNEW("GameClientSubsystem") Shell; - if( TheShell ) - TheShell->init(); - - TheInGameUI->recreateControlBar(); + TheShell->recreateWindowLayouts(); - TheShell->push( AsciiString("Menus/MainMenu.wnd") ); + TheInGameUI->recreateControlBar(); } } diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp index 29d0afddb7..e45ffb2f46 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp @@ -1301,18 +1301,9 @@ static void saveOptions( void ) prefString.format("%d %d", xres, yres ); (*pref)["Resolution"] = prefString; - // delete the shell - delete TheShell; - TheShell = NULL; - - // create the shell - TheShell = MSGNEW("GameClientSubsystem") Shell; - if( TheShell ) - TheShell->init(); - - TheInGameUI->recreateControlBar(); + TheShell->recreateWindowLayouts(); - TheShell->push( AsciiString("Menus/MainMenu.wnd") ); + TheInGameUI->recreateControlBar(); } } } diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/Shell/Shell.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/Shell/Shell.cpp index ea50ed4e8f..b10205578d 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/Shell/Shell.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/Shell/Shell.cpp @@ -57,6 +57,21 @@ Shell *TheShell = NULL; ///< the shell singleton definition //------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------- Shell::Shell( void ) +{ + construct(); + +} // end Shell + +//------------------------------------------------------------------------------------------------- +//------------------------------------------------------------------------------------------------- +Shell::~Shell( void ) +{ + deconstruct(); + +} // end ~Shell + +//------------------------------------------------------------------------------------------------- +void Shell::construct( void ) { Int i; @@ -80,12 +95,10 @@ Shell::Shell( void ) m_optionsLayout = NULL; m_screenCount = 0; // - -} // end Shell +} //------------------------------------------------------------------------------------------------- -//------------------------------------------------------------------------------------------------- -Shell::~Shell( void ) +void Shell::deconstruct( void ) { WindowLayout *newTop = top(); while(newTop) @@ -101,12 +114,10 @@ Shell::~Shell( void ) m_background = NULL; } - if(m_animateWindowManager) - delete m_animateWindowManager; + delete m_animateWindowManager; m_animateWindowManager = NULL; - if(m_schemeManager) - delete m_schemeManager; + delete m_schemeManager; m_schemeManager = NULL; // delete the save/load menu if present @@ -135,8 +146,7 @@ Shell::~Shell( void ) deleteInstance(m_optionsLayout); m_optionsLayout = NULL; } - -} // end ~Shell +} //------------------------------------------------------------------------------------------------- /** Initialize the shell system */ @@ -165,7 +175,7 @@ void Shell::reset( void ) // pop all screens while( m_screenCount ) - pop(); + popImmediate(); m_animateWindowManager->reset(); @@ -217,6 +227,53 @@ void Shell::update( void ) } // end update +//------------------------------------------------------------------------------------------------- +namespace +{ + struct ScreenInfo + { + ScreenInfo() : isHidden(false) {} + AsciiString filename; + bool isHidden; + }; +} + +//------------------------------------------------------------------------------------------------- +void Shell::recreateWindowLayouts( void ) +{ + // collect state of the current shell + const Int screenCount = getScreenCount(); + std::vector screenStackInfos; + + { + screenStackInfos.resize(screenCount); + Int screenIndex = 0; + for (; screenIndex < screenCount; ++screenIndex) + { + const WindowLayout* layout = getScreenLayout(screenIndex); + ScreenInfo& screenInfo = screenStackInfos[screenIndex]; + screenInfo.filename = layout->getFilename(); + screenInfo.isHidden = layout->isHidden(); + } + } + + // reconstruct the shell now + deconstruct(); + construct(); + init(); + + // restore the screen stack + Int screenIndex = 0; + for (; screenIndex < screenCount; ++screenIndex) + { + const ScreenInfo& screenInfo = screenStackInfos[screenIndex]; + push(screenInfo.filename); + + WindowLayout* layout = getScreenLayout(screenIndex); + layout->hide(screenInfo.isHidden); + } +} + //------------------------------------------------------------------------------------------------- /** Find a screen via the .wnd script filename loaded */ //------------------------------------------------------------------------------------------------- @@ -242,6 +299,15 @@ WindowLayout *Shell::findScreenByFilename( AsciiString filename ) } // end findScreenByFilename +//------------------------------------------------------------------------------------------------- +WindowLayout *Shell::getScreenLayout( Int index ) const +{ + if (index >= 0 && index < m_screenCount) + return m_screenStack[index]; + + return NULL; +} + //------------------------------------------------------------------------------------------------- /** Hide or unhide all window layouts loaded */ //------------------------------------------------------------------------------------------------- @@ -464,7 +530,7 @@ void Shell::showShell( Bool runInit ) Profile::StopRange("init"); #endif //else - TheShell->push( AsciiString("Menus/MainMenu.wnd") ); + push( AsciiString("Menus/MainMenu.wnd") ); } m_isShellActive = TRUE; } // end showShell