diff options
Diffstat (limited to 'tools/toolutils/BaseToolSystem.cpp')
| -rw-r--r-- | tools/toolutils/BaseToolSystem.cpp | 1156 |
1 files changed, 1156 insertions, 0 deletions
diff --git a/tools/toolutils/BaseToolSystem.cpp b/tools/toolutils/BaseToolSystem.cpp new file mode 100644 index 0000000..816385d --- /dev/null +++ b/tools/toolutils/BaseToolSystem.cpp @@ -0,0 +1,1156 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Core Movie Maker UI API +// +//============================================================================= + +#include "toolutils/basetoolsystem.h" +#include "toolframework/ienginetool.h" +#include "vgui/IPanel.h" +#include "vgui_controls/Controls.h" +#include "vgui_controls/Menu.h" +#include "vgui/ISurface.h" +#include "vgui_controls/Panel.h" +#include "vgui_controls/FileOpenDialog.h" +#include "vgui_controls/MessageBox.h" +#include "vgui/Cursor.h" +#include "vgui/iinput.h" +#include "vgui/ivgui.h" +#include "vgui_controls/AnimationController.h" +#include "ienginevgui.h" +#include "toolui.h" +#include "toolutils/toolmenubar.h" +#include "vgui/ilocalize.h" +#include "toolutils/enginetools_int.h" +#include "toolutils/vgui_tools.h" +#include "icvar.h" +#include "tier1/convar.h" +#include "datamodel/dmelementfactoryhelper.h" +#include "filesystem.h" +#include "vgui_controls/savedocumentquery.h" +#include "vgui_controls/perforcefilelistframe.h" +#include "toolutils/miniviewport.h" +#include "materialsystem/imaterialsystem.h" +#include "materialsystem/imaterial.h" +#include "materialsystem/imesh.h" +#include "toolutils/BaseStatusBar.h" +#include "movieobjects/movieobjects.h" +#include "vgui_controls/KeyBoardEditorDialog.h" +#include "vgui_controls/KeyBindingHelpDialog.h" +#include "dmserializers/idmserializers.h" +#include "tier2/renderutils.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + +using namespace vgui; + +extern IMaterialSystem *MaterialSystem(); + +class CGlobalFlexController : public IGlobalFlexController +{ +public: + virtual int FindGlobalFlexController( const char *name ) + { + return clienttools->FindGlobalFlexcontroller( name ); + } + + virtual const char *GetGlobalFlexControllerName( int idx ) + { + return clienttools->GetGlobalFlexControllerName( idx ); + } +}; + +static CGlobalFlexController g_GlobalFlexController; + +extern IGlobalFlexController *g_pGlobalFlexController; + +//----------------------------------------------------------------------------- +// Singleton interfaces +//----------------------------------------------------------------------------- +IServerTools *servertools = NULL; +IClientTools *clienttools = NULL; + + +//----------------------------------------------------------------------------- +// External functions +//----------------------------------------------------------------------------- +void RegisterTool( IToolSystem *tool ); + + +//----------------------------------------------------------------------------- +// Base tool system constructor +//----------------------------------------------------------------------------- +CBaseToolSystem::CBaseToolSystem( const char *pToolName /*="CBaseToolSystem"*/ ) : + BaseClass( NULL, pToolName ), + m_pBackground( 0 ), + m_pLogo( 0 ) +{ + RegisterTool( this ); + SetAutoDelete( false ); + m_bGameInputEnabled = false; + m_bFullscreenMode = false; + m_bIsActive = false; + m_bFullscreenToolModeEnabled = false; + m_MostRecentlyFocused = NULL; + SetKeyBoardInputEnabled( true ); + input()->RegisterKeyCodeUnhandledListener( GetVPanel() ); + + m_pFileOpenStateMachine = new vgui::FileOpenStateMachine( this, this ); + m_pFileOpenStateMachine->AddActionSignalTarget( this ); +} + + +void CBaseToolSystem::ApplySchemeSettings(IScheme *pScheme) +{ + BaseClass::ApplySchemeSettings(pScheme); + SetKeyBoardInputEnabled( true ); +} + +//----------------------------------------------------------------------------- +// Called at the end of engine startup (after client .dll and server .dll have been loaded) +//----------------------------------------------------------------------------- +bool CBaseToolSystem::Init( ) +{ + // Read shared localization info + g_pVGuiLocalize->AddFile( "resource/dmecontrols_%language%.txt" ); + g_pVGuiLocalize->AddFile( "resource/toolshared_%language%.txt" ); + g_pVGuiLocalize->AddFile( "Resource/vgui_%language%.txt" ); + g_pVGuiLocalize->AddFile( "Resource/platform_%language%.txt" ); + g_pVGuiLocalize->AddFile( "resource/boxrocket_%language%.txt" ); + + // Create the tool workspace + SetParent( VGui_GetToolRootPanel() ); + + // Deal with scheme + vgui::HScheme hToolScheme = GetToolScheme(); + if ( hToolScheme != 0 ) + { + SetScheme( hToolScheme ); + } + + m_KeyBindingsHandle = Panel::CreateKeyBindingsContext( GetBindingsContextFile(), "GAME" ); + SetKeyBindingsContext( m_KeyBindingsHandle ); + LoadKeyBindings(); + + const char *pszBackground = GetBackgroundTextureName(); + if ( pszBackground ) + { + m_pBackground = materials->FindMaterial( GetBackgroundTextureName() , TEXTURE_GROUP_VGUI ); + m_pBackground->IncrementReferenceCount(); + } + const char *pszLogo = GetLogoTextureName(); + if ( pszLogo ) + { + m_pLogo = materials->FindMaterial( GetLogoTextureName(), TEXTURE_GROUP_VGUI ); + m_pLogo->IncrementReferenceCount(); + } + + // Make the tool workspace the size of the screen + int w, h; + surface()->GetScreenSize( w, h ); + SetBounds( 0, 0, w, h ); + SetPaintBackgroundEnabled( true ); + SetPaintBorderEnabled( false ); + SetPaintEnabled( false ); + SetCursor( vgui::dc_none ); + SetVisible( false ); + + // Create the tool UI + m_pToolUI = new CToolUI( this, "ToolUI", this ); + + // Create the mini viewport + m_hMiniViewport = CreateMiniViewport( GetClientArea() ); + Assert( m_hMiniViewport.Get() ); + + return true; +} + +void CBaseToolSystem::ShowMiniViewport( bool state ) +{ + if ( !m_hMiniViewport.Get() ) + return; + + m_hMiniViewport->SetVisible( state ); +} + + +void CBaseToolSystem::SetMiniViewportBounds( int x, int y, int width, int height ) +{ + if ( m_hMiniViewport ) + { + m_hMiniViewport->SetBounds( x, y, width, height ); + } +} + +void CBaseToolSystem::SetMiniViewportText( const char *pText ) +{ + if ( m_hMiniViewport ) + { + m_hMiniViewport->SetOverlayText( pText ); + } +} + +void CBaseToolSystem::GetMiniViewportEngineBounds( int &x, int &y, int &width, int &height ) +{ + if ( m_hMiniViewport ) + { + m_hMiniViewport->GetEngineBounds( x, y, width, height ); + } +} + +vgui::Panel *CBaseToolSystem::GetMiniViewport( void ) +{ + return m_hMiniViewport; +} + +//----------------------------------------------------------------------------- +// Shut down +//----------------------------------------------------------------------------- +void CBaseToolSystem::Shutdown() +{ + if ( m_pBackground ) + { + m_pBackground->DecrementReferenceCount(); + } + if ( m_pLogo ) + { + m_pLogo->DecrementReferenceCount(); + } + + if ( m_hMiniViewport.Get() ) + { + delete m_hMiniViewport.Get(); + } + + // Make sure anything "marked for deletion" + // actually gets deleted before this dll goes away + vgui::ivgui()->RunFrame(); +} + + +//----------------------------------------------------------------------------- +// Can the tool quit? +//----------------------------------------------------------------------------- +bool CBaseToolSystem::CanQuit() +{ + return true; +} + + +//----------------------------------------------------------------------------- +// Client, server init + shutdown +//----------------------------------------------------------------------------- +bool CBaseToolSystem::ServerInit( CreateInterfaceFn serverFactory ) +{ + servertools = ( IServerTools * )serverFactory( VSERVERTOOLS_INTERFACE_VERSION, NULL ); + if ( !servertools ) + { + Error( "CBaseToolSystem::PostInit: Unable to get '%s' interface from game .dll\n", VSERVERTOOLS_INTERFACE_VERSION ); + } + + return true; +} + +bool CBaseToolSystem::ClientInit( CreateInterfaceFn clientFactory ) +{ + clienttools = ( IClientTools * )clientFactory( VCLIENTTOOLS_INTERFACE_VERSION, NULL ); + if ( !clienttools ) + { + Error( "CBaseToolSystem::PostInit: Unable to get '%s' interface from client .dll\n", VCLIENTTOOLS_INTERFACE_VERSION ); + } + else + { + g_pGlobalFlexController = &g_GlobalFlexController; // don't set this until clienttools is connected + } + + return true; +} + +void CBaseToolSystem::ServerShutdown() +{ + servertools = NULL; +} + +void CBaseToolSystem::ClientShutdown() +{ + clienttools = NULL; +} + + +//----------------------------------------------------------------------------- +// Level init, shutdown for server +//----------------------------------------------------------------------------- +void CBaseToolSystem::ServerLevelInitPreEntity() +{ +} + +void CBaseToolSystem::ServerLevelInitPostEntity() +{ +} + +void CBaseToolSystem::ServerLevelShutdownPreEntity() +{ +} + +void CBaseToolSystem::ServerLevelShutdownPostEntity() +{ +} + + +//----------------------------------------------------------------------------- +// Think methods +//----------------------------------------------------------------------------- +void CBaseToolSystem::ServerFrameUpdatePreEntityThink() +{ +} + +void CBaseToolSystem::Think( bool finalTick ) +{ + // run vgui animations + vgui::GetAnimationController()->UpdateAnimations( enginetools->Time() ); +} + +void CBaseToolSystem::PostMessage( HTOOLHANDLE hEntity, KeyValues *message ) +{ + if ( !Q_stricmp( message->GetName(), "ReleaseLayoffTexture" ) ) + { + if ( m_hMiniViewport.Get() ) + { + m_hMiniViewport->ReleaseLayoffTexture(); + } + return; + } +} + +void CBaseToolSystem::ServerFrameUpdatePostEntityThink() +{ +} + +void CBaseToolSystem::ServerPreClientUpdate() +{ +} + +void CBaseToolSystem::ServerPreSetupVisibility() +{ +} + +const char* CBaseToolSystem::GetEntityData( const char *pActualEntityData ) +{ + return pActualEntityData; +} + +//----------------------------------------------------------------------------- +// Level init, shutdown for client +//----------------------------------------------------------------------------- +void CBaseToolSystem::ClientLevelInitPreEntity() +{ +} + +void CBaseToolSystem::ClientLevelInitPostEntity() +{ +} + +void CBaseToolSystem::ClientLevelShutdownPreEntity() +{ +} + +void CBaseToolSystem::ClientLevelShutdownPostEntity() +{ +} + +void CBaseToolSystem::ClientPreRender() +{ +} + +void CBaseToolSystem::ClientPostRender() +{ +} + + +//----------------------------------------------------------------------------- +// Tool activation/deactivation +//----------------------------------------------------------------------------- +void CBaseToolSystem::OnToolActivate() +{ + m_bIsActive = true; + UpdateUIVisibility( ); + + // FIXME: Note that this is necessary because IsGameInputEnabled depends on m_bIsActive at the moment + OnModeChanged(); + + input()->SetModalSubTree( VGui_GetToolRootPanel(), GetVPanel(), IsGameInputEnabled() ); + input()->SetModalSubTreeReceiveMessages( !IsGameInputEnabled() ); + + m_pToolUI->UpdateMenuBarTitle(); +} + +void CBaseToolSystem::OnToolDeactivate() +{ + m_bIsActive = false; + UpdateUIVisibility( ); + + // FIXME: Note that this is necessary because IsGameInputEnabled depends on m_bIsActive at the moment + OnModeChanged(); + + input()->ReleaseModalSubTree(); +} + +//----------------------------------------------------------------------------- +// Let tool override key events (ie ESC and ~) +//----------------------------------------------------------------------------- +bool CBaseToolSystem::TrapKey( ButtonCode_t key, bool down ) +{ + // Don't hook keyboard if not topmost + if ( !m_bIsActive ) + return false; // didn't trap, continue processing + + // If in fullscreen toolMode, don't let ECSAPE bring up the game menu + if ( !m_bGameInputEnabled && m_bFullscreenMode && ( key == KEY_ESCAPE ) ) + return true; // trapping this key, stop processing + + if ( down ) + { + if ( key == TOGGLE_WINDOWED_KEY_CODE ) + { + SetMode( m_bGameInputEnabled, !m_bFullscreenMode ); + return true; // trapping this key, stop processing + } + + if ( key == TOGGLE_INPUT_KEY_CODE ) + { + if ( input()->IsKeyDown( KEY_LCONTROL ) || input()->IsKeyDown( KEY_RCONTROL ) ) + { + ToggleForceToolCamera(); + } + else + { + SetMode( !m_bGameInputEnabled, m_bFullscreenMode ); + } + return true; // trapping this key, stop processing + } + + // If in IFM mode, let ~ switch to gameMode and toggle console + if ( !IsGameInputEnabled() && ( key == '~' || key == '`' ) ) + { + SetMode( true, m_bFullscreenMode ); + return false; // didn't trap, continue processing + } + } + + return false; // didn't trap, continue processing +} + + +//----------------------------------------------------------------------------- +// Shows, hides the tool ui (menu, client area, status bar) +//----------------------------------------------------------------------------- +void CBaseToolSystem::SetToolUIVisible( bool bVisible ) +{ + if ( bVisible != m_pToolUI->IsVisible() ) + { + m_pToolUI->SetVisible( bVisible ); + m_pToolUI->InvalidateLayout(); + } +} + + +//----------------------------------------------------------------------------- +// Computes whether vgui is visible or not +//----------------------------------------------------------------------------- +void CBaseToolSystem::UpdateUIVisibility() +{ + bool bIsVisible = m_bIsActive && ( !IsGameInputEnabled() || !m_bFullscreenMode ); + ShowUI( bIsVisible ); +} + + +//----------------------------------------------------------------------------- +// Changes game input + fullscreen modes +//----------------------------------------------------------------------------- +void CBaseToolSystem::EnableFullscreenToolMode( bool bEnable ) +{ + m_bFullscreenToolModeEnabled = bEnable; +} + + +//----------------------------------------------------------------------------- +// Changed whether camera is forced to be tool camera +//----------------------------------------------------------------------------- +void CBaseToolSystem::ToggleForceToolCamera() +{ +} + + +//----------------------------------------------------------------------------- +// Changes game input + fullscreen modes +//----------------------------------------------------------------------------- +void CBaseToolSystem::SetMode( bool bGameInputEnabled, bool bFullscreen ) +{ + Assert( m_bIsActive ); + + if ( !m_bFullscreenToolModeEnabled ) + { + if ( !bGameInputEnabled ) + { + bFullscreen = false; + } + } + + if ( ( m_bFullscreenMode == bFullscreen ) && ( m_bGameInputEnabled == bGameInputEnabled ) ) + return; + + bool bOldGameInputEnabled = m_bGameInputEnabled; + + m_bFullscreenMode = bFullscreen; + m_bGameInputEnabled = bGameInputEnabled; + UpdateUIVisibility(); + + if ( bOldGameInputEnabled != m_bGameInputEnabled ) + { + Warning( "Input is now being sent to the %s\n", m_bGameInputEnabled ? "Game" : "Tools" ); + + // The subtree starts at the tool system root panel. If game input is enabled then + // the subtree should not receive or process input messages, otherwise it should + Assert( input()->GetModalSubTree() ); + if ( input()->GetModalSubTree() ) + { + input()->SetModalSubTreeReceiveMessages( !m_bGameInputEnabled ); + } + } + + if ( m_pToolUI ) + { + m_pToolUI->UpdateMenuBarTitle(); + } + + OnModeChanged( ); +} + + +//----------------------------------------------------------------------------- +// Keybinding +//----------------------------------------------------------------------------- +void CBaseToolSystem::LoadKeyBindings() +{ + ReloadKeyBindings( m_KeyBindingsHandle ); +} + +void CBaseToolSystem::ShowKeyBindingsEditor( Panel *panel, KeyBindingContextHandle_t handle ) +{ + if ( !m_hKeyBindingsEditor.Get() ) + { + // Show the editor + m_hKeyBindingsEditor = new CKeyBoardEditorDialog( GetClientArea(), panel, handle ); + m_hKeyBindingsEditor->DoModal(); + } +} + +void CBaseToolSystem::ShowKeyBindingsHelp( Panel *panel, KeyBindingContextHandle_t handle, vgui::KeyCode boundKey, int modifiers ) +{ + if ( m_hKeyBindingsHelp.Get() ) + { + m_hKeyBindingsHelp->HelpKeyPressed(); + return; + } + + m_hKeyBindingsHelp = new CKeyBindingHelpDialog( GetClientArea(), panel, handle, boundKey, modifiers ); +} + +vgui::KeyBindingContextHandle_t CBaseToolSystem::GetKeyBindingsHandle() +{ + return m_KeyBindingsHandle; +} + +void CBaseToolSystem::OnEditKeyBindings() +{ + Panel *tool = GetMostRecentlyFocusedTool(); + if ( tool ) + { + ShowKeyBindingsEditor( tool, tool->GetKeyBindingsContext() ); + } +} + +void CBaseToolSystem::OnKeyBindingHelp() +{ + Panel *tool = GetMostRecentlyFocusedTool(); + if ( tool ) + { + CUtlVector< BoundKey_t * > list; + LookupBoundKeys( "keybindinghelp", list ); + if ( list.Count() > 0 ) + { + ShowKeyBindingsHelp( tool, tool->GetKeyBindingsContext(), (KeyCode)list[ 0 ]->keycode, list[ 0 ]->modifiers ); + } + } +} + + +//----------------------------------------------------------------------------- +// Registers tool window +//----------------------------------------------------------------------------- +void CBaseToolSystem::RegisterToolWindow( vgui::PHandle hPanel ) +{ + int i = m_Tools.AddToTail( hPanel ); + m_Tools[i]->SetKeyBindingsContext( m_KeyBindingsHandle ); +} + +void CBaseToolSystem::UnregisterAllToolWindows() +{ + m_Tools.RemoveAll(); + m_MostRecentlyFocused = NULL; +} + +Panel *CBaseToolSystem::GetMostRecentlyFocusedTool() +{ + VPANEL focus = input()->GetFocus(); + int c = m_Tools.Count(); + for ( int i = 0; i < c; ++i ) + { + Panel *p = m_Tools[ i ].Get(); + if ( !p ) + continue; + + // Not a visible tool + if ( !p->GetParent() ) + continue; + + bool hasFocus = p->HasFocus(); + bool focusOnChild = focus && ipanel()->HasParent(focus, p->GetVPanel()); + + if ( !hasFocus && !focusOnChild ) + { + continue; + } + + return p; + } + + return m_MostRecentlyFocused.Get(); +} + +void CBaseToolSystem::PostMessageToActiveTool( KeyValues *pKeyValues, float flDelay ) +{ + Panel *pMostRecent = GetMostRecentlyFocusedTool(); + if ( pMostRecent ) + { + Panel::PostMessage( pMostRecent->GetVPanel(), pKeyValues, flDelay ); + } +} + +void CBaseToolSystem::PostMessageToActiveTool( const char *msg, float flDelay ) +{ + Panel *pMostRecent = GetMostRecentlyFocusedTool(); + if ( pMostRecent ) + { + Panel::PostMessage( pMostRecent->GetVPanel(), new KeyValues( msg ), flDelay ); + } +} + +void CBaseToolSystem::PostMessageToAllTools( KeyValues *message ) +{ + int nCount = enginetools->GetToolCount(); + for ( int i = 0; i < nCount; ++i ) + { + IToolSystem *pToolSystem = const_cast<IToolSystem*>( enginetools->GetToolSystem( i ) ); + pToolSystem->PostMessage( HTOOLHANDLE_INVALID, message ); + } +} + +void CBaseToolSystem::OnThink() +{ + BaseClass::OnThink(); + + VPANEL focus = input()->GetFocus(); + int c = m_Tools.Count(); + for ( int i = 0; i < c; ++i ) + { + Panel *p = m_Tools[ i ].Get(); + if ( !p ) + continue; + + // Not a visible tool + if ( !p->GetParent() ) + continue; + + bool hasFocus = p->HasFocus(); + bool focusOnChild = focus && ipanel()->HasParent(focus, p->GetVPanel()); + + if ( !hasFocus && !focusOnChild ) + continue; + + m_MostRecentlyFocused = p; + break; + } +} + + +//----------------------------------------------------------------------------- +// Let tool override viewport for engine +//----------------------------------------------------------------------------- +void CBaseToolSystem::AdjustEngineViewport( int& x, int& y, int& width, int& height ) +{ + if ( !m_hMiniViewport.Get() ) + return; + + bool enabled; + int vpx, vpy, vpw, vph; + + m_hMiniViewport->GetViewport( enabled, vpx, vpy, vpw, vph ); + + if ( !enabled ) + return; + + x = vpx; + y = vpy; + width = vpw; + height = vph; +} + +//----------------------------------------------------------------------------- +// Let tool override view/camera +//----------------------------------------------------------------------------- +bool CBaseToolSystem::SetupEngineView( Vector &origin, QAngle &angles, float &fov ) +{ + return false; +} + +//----------------------------------------------------------------------------- +// Let tool override microphone +//----------------------------------------------------------------------------- +bool CBaseToolSystem::SetupAudioState( AudioState_t &audioState ) +{ + return false; +} + +//----------------------------------------------------------------------------- +// Should the game be allowed to render the view? +//----------------------------------------------------------------------------- +bool CBaseToolSystem::ShouldGameRenderView() +{ + // Render through mini viewport unless in fullscreen mode + if ( !IsVisible() ) + { + return true; + } + + if ( !m_hMiniViewport.Get() ) + return true; + + if ( !m_hMiniViewport->IsVisible() ) + { + return true; + } + + // Route through mini viewport + return false; +} + +bool CBaseToolSystem::IsThirdPersonCamera() +{ + return false; +} + +bool CBaseToolSystem::IsToolRecording() +{ + return false; +} + +IMaterialProxy *CBaseToolSystem::LookupProxy( const char *proxyName ) +{ + return NULL; +} + + +bool CBaseToolSystem::GetSoundSpatialization( int iUserData, int guid, SpatializationInfo_t& info ) +{ + // Always hearable (no changes) + return true; +} + +void CBaseToolSystem::HostRunFrameBegin() +{ +} + +void CBaseToolSystem::HostRunFrameEnd() +{ +} + +void CBaseToolSystem::RenderFrameBegin() +{ + // If we can't see the engine window, do nothing + if ( !IsVisible() || !IsActiveTool() ) + return; + + if ( !m_hMiniViewport.Get() || !m_hMiniViewport->IsVisible() ) + return; + + m_hMiniViewport->RenderFrameBegin(); +} + +void CBaseToolSystem::RenderFrameEnd() +{ +} + +void CBaseToolSystem::VGui_PreRender( int paintMode ) +{ +} + +void CBaseToolSystem::VGui_PostRender( int paintMode ) +{ +} + +void CBaseToolSystem::VGui_PreSimulate() +{ + if ( !m_bIsActive ) + return; + + // only show the gameUI when in gameMode + vgui::VPANEL gameui = enginevgui->GetPanel( PANEL_GAMEUIDLL ); + if ( gameui != 0 ) + { + bool wantsToBeSeen = IsGameInputEnabled() && (enginetools->IsGamePaused() || !enginetools->IsInGame() || enginetools->IsConsoleVisible()); + vgui::ipanel()->SetVisible(gameui, wantsToBeSeen); + } + + // if there's no map loaded and we're in fullscreen toolMode, switch to gameMode + // otherwise there's nothing to see or do... + if ( !IsGameInputEnabled() && !IsVisible() && !enginetools->IsInGame() ) + { + SetMode( true, m_bFullscreenMode ); + } +} + +void CBaseToolSystem::VGui_PostSimulate() +{ +} + +const char *CBaseToolSystem::MapName() const +{ + return enginetools->GetCurrentMap(); +} + + +//----------------------------------------------------------------------------- +// Shows or hides the UI +//----------------------------------------------------------------------------- +bool CBaseToolSystem::ShowUI( bool bVisible ) +{ + bool bPrevVisible = IsVisible(); + if ( bPrevVisible == bVisible ) + return bPrevVisible; + + SetMouseInputEnabled( bVisible ); + SetVisible( bVisible ); + + // Hide loading image if using bx movie UI + // A bit of a hack because it more or less tunnels through to the client .dll, but the moviemaker assumes + // single player anyway... + if ( bVisible ) + { + ConVar *pCv = ( ConVar * )cvar->FindVar( "cl_showpausedimage" ); + if ( pCv ) + { + pCv->SetValue( 0 ); + } + } + + return bPrevVisible; +} + + +//----------------------------------------------------------------------------- +// Gets the action target to sent to panels so that the tool system's OnCommand is called +//----------------------------------------------------------------------------- +vgui::Panel *CBaseToolSystem::GetActionTarget() +{ + return this; +} + + +//----------------------------------------------------------------------------- +// Derived classes implement this to create a custom menubar +//----------------------------------------------------------------------------- +vgui::MenuBar *CBaseToolSystem::CreateMenuBar(CBaseToolSystem *pParent ) +{ + return new vgui::MenuBar( pParent, "ToolMenuBar" ); +} + +//----------------------------------------------------------------------------- +// Purpose: Derived classes implement this to create a custom status bar, or return NULL for no status bar +//----------------------------------------------------------------------------- +vgui::Panel *CBaseToolSystem::CreateStatusBar( vgui::Panel *pParent ) +{ + return new CBaseStatusBar( this, "Status Bar" ); +} + +//----------------------------------------------------------------------------- +// Gets at the action menu +//----------------------------------------------------------------------------- +vgui::Menu *CBaseToolSystem::GetActionMenu() +{ + return m_hActionMenu; +} + + +//----------------------------------------------------------------------------- +// Returns the client area +//----------------------------------------------------------------------------- +vgui::Panel* CBaseToolSystem::GetClientArea() +{ + return m_pToolUI->GetClientArea(); +} + + +//----------------------------------------------------------------------------- +// Pops up the action menu +//----------------------------------------------------------------------------- +void CBaseToolSystem::OnMousePressed( vgui::MouseCode code ) +{ + if ( code == MOUSE_RIGHT ) + { + InitActionMenu(); + } + else + { + BaseClass::OnMousePressed( code ); + } +} + + +//----------------------------------------------------------------------------- +// Creates the action menu +//----------------------------------------------------------------------------- +void CBaseToolSystem::InitActionMenu() +{ + ShutdownActionMenu(); + + // Let the tool system create the action menu + m_hActionMenu = CreateActionMenu( this ); + + if ( m_hActionMenu.Get() ) + { + m_hActionMenu->SetVisible(true); + PositionActionMenu(); + m_hActionMenu->RequestFocus(); + } +} + + +//----------------------------------------------------------------------------- +// Destroy action menu +//----------------------------------------------------------------------------- +void CBaseToolSystem::ShutdownActionMenu() +{ + if ( m_hActionMenu.Get() ) + { + m_hActionMenu->MarkForDeletion(); + m_hActionMenu = NULL; + } +} + +void CBaseToolSystem::UpdateMenu( vgui::Menu *menu ) +{ + // Nothing +} + +//----------------------------------------------------------------------------- +// Positions the action menu when it's time to pop it up +//----------------------------------------------------------------------------- +void CBaseToolSystem::PositionActionMenu() +{ + // get cursor position, this is local to this text edit window + int cursorX, cursorY; + input()->GetCursorPos(cursorX, cursorY); + + // relayout the menu immediately so that we know it's size + m_hActionMenu->InvalidateLayout(true); + + // Get the menu size + int menuWide, menuTall; + m_hActionMenu->GetSize( menuWide, menuTall ); + + // work out where the cursor is and therefore the best place to put the menu + int wide, tall; + GetSize( wide, tall ); + + if (wide - menuWide > cursorX) + { + // menu hanging right + if (tall - menuTall > cursorY) + { + // menu hanging down + m_hActionMenu->SetPos(cursorX, cursorY); + } + else + { + // menu hanging up + m_hActionMenu->SetPos(cursorX, cursorY - menuTall); + } + } + else + { + // menu hanging left + if (tall - menuTall > cursorY) + { + // menu hanging down + m_hActionMenu->SetPos(cursorX - menuWide, cursorY); + } + else + { + // menu hanging up + m_hActionMenu->SetPos(cursorX - menuWide, cursorY - menuTall); + } + } +} + + +//----------------------------------------------------------------------------- +// Handles the clear recent files message +//----------------------------------------------------------------------------- +void CBaseToolSystem::OnClearRecent() +{ + m_RecentFiles.Clear(); + m_RecentFiles.SaveToRegistry( GetRegistryName() ); +} + + +//----------------------------------------------------------------------------- +// Called by the file open state machine +//----------------------------------------------------------------------------- +void CBaseToolSystem::OnFileStateMachineFinished( KeyValues *pKeyValues ) +{ + KeyValues *pContext = pKeyValues->GetFirstTrueSubKey(); + bool bWroteFile = pKeyValues->GetInt( "wroteFile", 0 ) != 0; + vgui::FileOpenStateMachine::CompletionState_t state = (vgui::FileOpenStateMachine::CompletionState_t)pKeyValues->GetInt( "completionState", vgui::FileOpenStateMachine::IN_PROGRESS ); + const char *pFileType = pKeyValues->GetString( "fileType" ); + OnFileOperationCompleted( pFileType, bWroteFile, state, pContext ); +} + + +//----------------------------------------------------------------------------- +// Show the File browser dialog +//----------------------------------------------------------------------------- +void CBaseToolSystem::OpenFile( const char *pOpenFileType, const char *pSaveFileName, const char *pSaveFileType, int nFlags, KeyValues *pContextKeyValues ) +{ + m_pFileOpenStateMachine->OpenFile( pOpenFileType, pContextKeyValues, pSaveFileName, pSaveFileType, nFlags ); +} + +void CBaseToolSystem::OpenFile( const char *pOpenFileName, const char *pOpenFileType, const char *pSaveFileName, const char *pSaveFileType, int nFlags, KeyValues *pContextKeyValues ) +{ + m_pFileOpenStateMachine->OpenFile( pOpenFileName, pOpenFileType, pContextKeyValues, pSaveFileName, pSaveFileType, nFlags ); +} + + +//----------------------------------------------------------------------------- +// Used to save a specified file, and deal with all the lovely dialogs +//----------------------------------------------------------------------------- +void CBaseToolSystem::SaveFile( const char *pFileName, const char *pFileType, int nFlags, KeyValues *pContextKeyValues ) +{ + m_pFileOpenStateMachine->SaveFile( pContextKeyValues, pFileName, pFileType, nFlags ); +} + + +//----------------------------------------------------------------------------- +// Paints the background +//----------------------------------------------------------------------------- +void CBaseToolSystem::PaintBackground() +{ + int w, h; + GetSize( w, h ); + + int x, y; + GetPos( x, y ); + LocalToScreen( x, y ); + + CMatRenderContextPtr pRenderContext( materials ); + if ( m_pBackground ) + { + int texWide = m_pBackground->GetMappingWidth(); + int texTall = m_pBackground->GetMappingHeight(); + + float maxu = (float)w / (float)texWide; + float maxv = (float)h / (float)texTall; + + RenderQuad( m_pBackground, x, y, w, h, surface()->GetZPos(), 0.0f, 0.0f, maxu, maxv, Color( 255, 255, 255, 255 ) ); + } + + bool hasDoc = HasDocument(); + if ( m_pLogo ) + { + int texWide = m_pLogo->GetMappingWidth(); + float logoAspectRatio = 0.442; + + if ( hasDoc ) + { + int logoW = texWide / 2; + int logoH = logoW * logoAspectRatio; + + x = w - logoW - 15; + y = h - logoH - 30; + + w = logoW; + h = logoH; + } + else + { + int logoW = texWide; + int logoH = logoW * logoAspectRatio; + + x = ( w - logoW ) / 2; + y = ( h - logoH ) / 2; + + w = logoW; + h = logoH; + } + + int alpha = hasDoc ? 0 : 255; + + RenderQuad( m_pLogo, x, y, w, h, surface()->GetZPos(), 0.0f, 0.0f, 1.0f, 1.0f, Color( 255, 255, 255, alpha ) ); + } +} + +const char *CBaseToolSystem::GetBackgroundTextureName() +{ + return "vgui/tools/ifm/ifm_background"; +} + +bool CBaseToolSystem::HasDocument() +{ + return false; +} + +CMiniViewport *CBaseToolSystem::CreateMiniViewport( vgui::Panel *parent ) +{ + int w, h; + surface()->GetScreenSize( w, h ); + + CMiniViewport *vp = new CMiniViewport( parent, "MiniViewport" ); + Assert( vp ); + vp->SetVisible( true ); + int menuBarHeight = 28; + int titleBarHeight = 22; + int offset = 4; + vp->SetBounds( ( 2 * w / 3 ) - offset, menuBarHeight + offset, w / 3, h / 3 + titleBarHeight); + return vp; +} + +void CBaseToolSystem::ComputeMenuBarTitle( char *buf, size_t buflen ) +{ + Q_snprintf( buf, buflen, ": %s [ %s - Switch Mode ] [ %s - Full Screen ]", IsGameInputEnabled() ? "Game Mode" : "Tool Mode", TOGGLE_INPUT_KEY_NAME, TOGGLE_WINDOWED_KEY_NAME ); +} + +void CBaseToolSystem::OnUnhandledMouseClick( int code ) +{ + if ( (MouseCode)code == MOUSE_LEFT ) + { + // If tool ui is visible and we're running game in a window + // and they click on the ifm it'll be unhandled, but in this case + // we'll switch back to the IFM mode + if ( !IsFullscreen() && IsGameInputEnabled() ) + { + SetMode( false, m_bFullscreenMode ); + } + } +} |