//====== Copyright © 1996-2005, 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 ); } //----------------------------------------------------------------------------- // Derived classes can implement this to get a new scheme to be applied to this tool //----------------------------------------------------------------------------- vgui::HScheme CBaseToolSystem::GetToolScheme() { return vgui::scheme()->LoadSchemeFromFile( "Resource/BoxRocket.res", GetToolName() ); } //----------------------------------------------------------------------------- // 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(); } // Delete ourselves MarkForDeletion(); // Make sure anything "marked for deletion" // actually gets deleted before this dll goes away vgui::ivgui()->RunFrame(); } //----------------------------------------------------------------------------- // Can the tool quit? //----------------------------------------------------------------------------- bool CBaseToolSystem::CanQuit( const char* /*pExitMsg*/ ) { 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::PostToolMessage( HTOOLHANDLE hEntity, KeyValues *message ) { return; } void CBaseToolSystem::ServerFrameUpdatePostEntityThink() { } void CBaseToolSystem::ServerPreClientUpdate() { } void CBaseToolSystem::ServerPreSetupVisibility() { } const char* CBaseToolSystem::GetEntityData( const char *pActualEntityData ) { return pActualEntityData; } void* CBaseToolSystem::QueryInterface( const char *pInterfaceName ) { return NULL; } //----------------------------------------------------------------------------- // 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 // This is a bit of a hack to work around the mouse capture bugs we seem to keep getting... if ( !IsGameInputEnabled() && key == KEY_ESCAPE ) { vgui::input()->SetMouseCapture( NULL ); } // 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" ); // If switching from tool to game mode, release the mouse capture so that the // tool knows that it is going to miss mouse events that are handed to the game. if ( bGameInputEnabled == true ) { input()->SetMouseCapture( NULL ); } // 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 ); } enginetools->OnModeChanged( 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; } //----------------------------------------------------------------------------- // Destroys all tool windows containers //----------------------------------------------------------------------------- void CBaseToolSystem::DestroyToolContainers() { int c = ToolWindow::GetToolWindowCount(); for ( int i = c - 1; i >= 0 ; --i ) { ToolWindow *kill = ToolWindow::GetToolWindow( i ); delete kill; } } 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( enginetools->GetToolSystem( i ) ); pToolSystem->PostToolMessage( 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 Panel *pPage = p->GetParent(); if ( !pPage ) continue; bool hasFocus = p->HasFocus(); bool bFocusOnTab = false; bool focusOnChild = false; if ( !hasFocus ) { PropertySheet *pSheet = dynamic_cast< PropertySheet * >( pPage ); if ( pSheet ) { Panel *pActiveTab = pSheet->GetActiveTab(); if ( pActiveTab ) { bFocusOnTab = ( ( focus == pActiveTab->GetVPanel() ) || // Tab itself has focus ipanel()->HasParent( focus, pActiveTab->GetVPanel() ) ); // Tab is parent of panel that has focus (in case we add subpanels to tabs) } } focusOnChild = focus && ipanel()->HasParent(focus, p->GetVPanel()); } if ( !hasFocus && !focusOnChild && !bFocusOnTab ) continue; if ( m_MostRecentlyFocused != p ) { 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::ShouldGamePlaySounds() { return true; } 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 defined( TOOLFRAMEWORK_VGUI_REFACTOR ) vgui::VPANEL gameuiBackground = enginevgui->GetPanel( PANEL_GAMEUIBACKGROUND ); #endif if ( gameui != 0 ) { bool wantsToBeSeen = IsGameInputEnabled() && (enginetools->IsGamePaused() || !enginetools->IsInGame() || enginetools->IsConsoleVisible()); vgui::ipanel()->SetVisible(gameui, wantsToBeSeen); #if defined( TOOLFRAMEWORK_VGUI_REFACTOR ) vgui::ipanel()->SetVisible(gameuiBackground, wantsToBeSeen); #endif } // 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(); } //----------------------------------------------------------------------------- // Returns the menu bar //----------------------------------------------------------------------------- vgui::MenuBar* CBaseToolSystem::GetMenuBar() { return m_pToolUI->GetMenuBar(); } //----------------------------------------------------------------------------- // Returns the status bar //----------------------------------------------------------------------------- vgui::Panel* CBaseToolSystem::GetStatusBar() { return m_pToolUI->GetStatusBar(); } //----------------------------------------------------------------------------- // 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 ); } } }