summaryrefslogtreecommitdiff
path: root/tools/toolutils
diff options
context:
space:
mode:
Diffstat (limited to 'tools/toolutils')
-rw-r--r--tools/toolutils/BaseToolSystem.cpp1156
-rw-r--r--tools/toolutils/ConsolePage.cpp45
-rw-r--r--tools/toolutils/ToolFileMenuButton.cpp251
-rw-r--r--tools/toolutils/ToolHelpMenuButton.cpp60
-rw-r--r--tools/toolutils/ToolMenuButton.cpp185
-rw-r--r--tools/toolutils/ToolSwitchMenuButton.cpp72
-rw-r--r--tools/toolutils/ToolUI.cpp118
-rw-r--r--tools/toolutils/ToolUI.h66
-rw-r--r--tools/toolutils/attributeelementchoicelist.cpp137
-rw-r--r--tools/toolutils/basepropertiescontainer.cpp47
-rw-r--r--tools/toolutils/basestatusbar.cpp151
-rw-r--r--tools/toolutils/miniviewport.cpp457
-rw-r--r--tools/toolutils/recentfilelist.cpp157
-rw-r--r--tools/toolutils/savewindowpositions.cpp286
-rw-r--r--tools/toolutils/tool_main.cpp233
-rw-r--r--tools/toolutils/tooleditmenubutton.cpp131
-rw-r--r--tools/toolutils/toolmenubar.cpp132
-rw-r--r--tools/toolutils/toolutils.vpc54
-rw-r--r--tools/toolutils/vgui_tools.cpp67
19 files changed, 3805 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 );
+ }
+ }
+}
diff --git a/tools/toolutils/ConsolePage.cpp b/tools/toolutils/ConsolePage.cpp
new file mode 100644
index 0000000..b2ff4d5
--- /dev/null
+++ b/tools/toolutils/ConsolePage.cpp
@@ -0,0 +1,45 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//===========================================================================//
+
+#include "toolutils/ConsolePage.h"
+#include "toolutils/enginetools_int.h"
+#include "toolframework/ienginetool.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+using namespace vgui;
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Constructor
+//-----------------------------------------------------------------------------
+CConsolePage::CConsolePage( Panel *parent, bool bStatusVersion ) : BaseClass( parent, "ToolsConsole", bStatusVersion )
+{
+ AddActionSignalTarget( this );
+}
+
+
+//-----------------------------------------------------------------------------
+// Submits a command
+//-----------------------------------------------------------------------------
+void CConsolePage::OnCommandSubmitted( const char *pCommand )
+{
+ enginetools->Command( pCommand );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: sets up colors
+//-----------------------------------------------------------------------------
+void CConsolePage::ApplySchemeSettings(IScheme *pScheme)
+{
+ BaseClass::ApplySchemeSettings(pScheme);
+
+ m_PrintColor = GetSchemeColor("IFMConsole.TextColor", pScheme);
+ m_DPrintColor = GetSchemeColor("IFMConsole.DevTextColor", pScheme);
+}
diff --git a/tools/toolutils/ToolFileMenuButton.cpp b/tools/toolutils/ToolFileMenuButton.cpp
new file mode 100644
index 0000000..36070fb
--- /dev/null
+++ b/tools/toolutils/ToolFileMenuButton.cpp
@@ -0,0 +1,251 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Standard file menu
+//
+//=============================================================================
+
+#include "toolutils/toolfilemenubutton.h"
+#include "toolutils/toolmenubutton.h"
+#include "tier1/KeyValues.h"
+#include "tier1/utlstring.h"
+#include "vgui_controls/menu.h"
+#include "vgui_controls/frame.h"
+#include "vgui_controls/button.h"
+#include "vgui_controls/listpanel.h"
+#include "toolutils/enginetools_int.h"
+#include "p4lib/ip4.h"
+#include "vgui_controls/perforcefilelistframe.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+
+//-----------------------------------------------------------------------------
+// Global function to create the file menu
+//-----------------------------------------------------------------------------
+CToolMenuButton* CreateToolFileMenuButton( vgui::Panel *parent, const char *panelName,
+ const char *text, vgui::Panel *pActionTarget, IFileMenuCallbacks *pCallbacks )
+{
+ return new CToolFileMenuButton( parent, panelName, text, pActionTarget, pCallbacks );
+}
+
+
+//-----------------------------------------------------------------------------
+// Constructor
+//-----------------------------------------------------------------------------
+CToolFileMenuButton::CToolFileMenuButton( vgui::Panel *pParent, const char *panelName, const char *text, vgui::Panel *pActionSignalTarget, IFileMenuCallbacks *pFileMenuCallback ) :
+ BaseClass( pParent, panelName, text, pActionSignalTarget ), m_pFileMenuCallback( pFileMenuCallback )
+{
+ Assert( pFileMenuCallback );
+
+ AddMenuItem( "new", "#ToolFileNew", new KeyValues( "OnNew" ), pActionSignalTarget, NULL, "file_new" );
+ AddMenuItem( "open", "#ToolFileOpen", new KeyValues( "OnOpen" ), pActionSignalTarget, NULL, "file_open" );
+ AddMenuItem( "save", "#ToolFileSave", new KeyValues( "OnSave" ), pActionSignalTarget, NULL, "file_save" );
+ AddMenuItem( "saveas", "#ToolFileSaveAs", new KeyValues( "OnSaveAs" ), pActionSignalTarget );
+ AddMenuItem( "close", "#ToolFileClose", new KeyValues( "OnClose" ), pActionSignalTarget );
+ AddSeparator();
+
+ // Add the Perforce menu options only if there is a valid P4 interface (SDK users won't have this)
+ if ( p4 )
+ {
+ m_pPerforce = new vgui::Menu( this, "Perforce" );
+ m_pMenu->AddCascadingMenuItem( "#ToolPerforce", this, m_pPerforce );
+ m_nPerforceAdd = m_pPerforce->AddMenuItem( "perforce_add", "#ToolPerforceAdd", new KeyValues( "OnPerforceAdd" ), this );
+ m_nPerforceOpen = m_pPerforce->AddMenuItem( "perforce_open", "#ToolPerforceOpen", new KeyValues( "OnPerforceOpen" ), this );
+ m_nPerforceRevert = m_pPerforce->AddMenuItem( "perforce_revert", "#ToolPerforceRevert", new KeyValues( "OnPerforceRevert" ), this );
+ m_nPerforceSubmit = m_pPerforce->AddMenuItem( "perforce_submit", "#ToolPerforceSubmit", new KeyValues( "OnPerforceSubmit" ), this );
+ m_pPerforce->AddSeparator();
+ m_nPerforceP4Win = m_pPerforce->AddMenuItem( "perforce_p4win", "#ToolPerforceP4Win", new KeyValues( "OnPerforceP4Win" ), this );
+ m_nPerforceListOpenFiles = m_pPerforce->AddMenuItem( "perforce_listopenfiles", "#ToolPerforceListOpenFiles", new KeyValues( "OnPerforceListOpenFiles" ), this );
+ }
+
+ m_pRecentFiles = new vgui::Menu( this, "RecentFiles" );
+ m_nRecentFiles = m_pMenu->AddCascadingMenuItem( "#ToolFileRecent", pActionSignalTarget, m_pRecentFiles );
+
+ AddMenuItem( "clearrecent", "#ToolFileClearRecent", new KeyValues ( "OnClearRecent" ), pActionSignalTarget );
+ AddSeparator();
+ AddMenuItem( "exit", "#ToolFileExit", new KeyValues ( "OnExit" ), pActionSignalTarget );
+
+ SetMenu( m_pMenu );
+}
+
+
+//-----------------------------------------------------------------------------
+// Gets called when the menu is shown
+//-----------------------------------------------------------------------------
+void CToolFileMenuButton::OnShowMenu( vgui::Menu *menu )
+{
+ BaseClass::OnShowMenu( menu );
+
+ // Update the menu
+ int nEnableMask = m_pFileMenuCallback->GetFileMenuItemsEnabled();
+
+ int id = m_Items.Find( "new" );
+ SetItemEnabled( id, (nEnableMask & IFileMenuCallbacks::FILE_NEW) != 0 );
+ id = m_Items.Find( "open" );
+ SetItemEnabled( id, (nEnableMask & IFileMenuCallbacks::FILE_OPEN) != 0 );
+ id = m_Items.Find( "save" );
+ SetItemEnabled( id, (nEnableMask & IFileMenuCallbacks::FILE_SAVE) != 0 );
+ id = m_Items.Find( "saveas" );
+ SetItemEnabled( id, (nEnableMask & IFileMenuCallbacks::FILE_SAVEAS) != 0 );
+ id = m_Items.Find( "close" );
+ SetItemEnabled( id, (nEnableMask & IFileMenuCallbacks::FILE_CLOSE) != 0 );
+ id = m_Items.Find( "clearrecent" );
+ SetItemEnabled( id, (nEnableMask & IFileMenuCallbacks::FILE_CLEAR_RECENT) != 0 );
+
+ m_pRecentFiles->DeleteAllItems();
+
+ if ( (nEnableMask & IFileMenuCallbacks::FILE_RECENT) == 0 )
+ {
+ m_pMenu->SetItemEnabled( m_nRecentFiles, false );
+ }
+ else
+ {
+ m_pMenu->SetItemEnabled( m_nRecentFiles, true );
+ m_pFileMenuCallback->AddRecentFilesToMenu( m_pRecentFiles );
+ }
+
+ // We only have the Perforce menu items if we have valid p4 interface
+ if ( p4 )
+ {
+ bool bP4Connected = p4->IsConnectedToServer();
+ char pPerforceFile[MAX_PATH];
+ if ( bP4Connected && m_pFileMenuCallback->GetPerforceFileName( pPerforceFile, sizeof(pPerforceFile) ) )
+ {
+ bool bIsUnnamed = !Q_IsAbsolutePath( pPerforceFile );
+ bool bOpenedForEdit = p4->GetFileState( pPerforceFile ) != P4FILE_UNOPENED;
+ bool bFileInPerforce = p4->IsFileInPerforce( pPerforceFile );
+
+ m_pPerforce->SetItemEnabled( m_nPerforceAdd, !bIsUnnamed && !bFileInPerforce && !bOpenedForEdit );
+ m_pPerforce->SetItemEnabled( m_nPerforceOpen, !bIsUnnamed && bFileInPerforce && !bOpenedForEdit );
+ m_pPerforce->SetItemEnabled( m_nPerforceRevert, !bIsUnnamed && bOpenedForEdit );
+ m_pPerforce->SetItemEnabled( m_nPerforceSubmit, !bIsUnnamed && bOpenedForEdit );
+ m_pPerforce->SetItemEnabled( m_nPerforceP4Win, !bIsUnnamed && bFileInPerforce || bOpenedForEdit );
+ m_pPerforce->SetItemEnabled( m_nPerforceListOpenFiles, true );
+ }
+ else
+ {
+ m_pPerforce->SetItemEnabled( m_nPerforceAdd, false );
+ m_pPerforce->SetItemEnabled( m_nPerforceOpen, false );
+ m_pPerforce->SetItemEnabled( m_nPerforceRevert, false );
+ m_pPerforce->SetItemEnabled( m_nPerforceSubmit, false );
+ m_pPerforce->SetItemEnabled( m_nPerforceP4Win, false );
+ m_pPerforce->SetItemEnabled( m_nPerforceListOpenFiles, bP4Connected );
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Perforce functions
+//-----------------------------------------------------------------------------
+void CToolFileMenuButton::OnPerforceAdd( )
+{
+ char pPerforceFile[MAX_PATH];
+ if ( m_pFileMenuCallback->GetPerforceFileName( pPerforceFile, sizeof(pPerforceFile) ) )
+ {
+ CPerforceFileListFrame *pPerforceFrame = new CPerforceFileListFrame( m_pFileMenuCallback->GetRootPanel(), "Add Movie File to Perforce?", "Movie File", PERFORCE_ACTION_FILE_ADD );
+ pPerforceFrame->AddFile( pPerforceFile );
+ pPerforceFrame->DoModal( );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Check out a file
+//-----------------------------------------------------------------------------
+void CToolFileMenuButton::OnPerforceOpen( )
+{
+ char pPerforceFile[MAX_PATH];
+ if ( m_pFileMenuCallback->GetPerforceFileName( pPerforceFile, sizeof(pPerforceFile) ) )
+ {
+ CPerforceFileListFrame *pPerforceFrame = new CPerforceFileListFrame( m_pFileMenuCallback->GetRootPanel(), "Check Out Movie File from Perforce?", "Movie File", PERFORCE_ACTION_FILE_EDIT );
+ pPerforceFrame->AddFile( pPerforceFile );
+ pPerforceFrame->DoModal( );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Revert a file
+//-----------------------------------------------------------------------------
+void CToolFileMenuButton::OnPerforceRevert( )
+{
+ char pPerforceFile[MAX_PATH];
+ if ( m_pFileMenuCallback->GetPerforceFileName( pPerforceFile, sizeof(pPerforceFile) ) )
+ {
+ CPerforceFileListFrame *pPerforceFrame = new CPerforceFileListFrame( m_pFileMenuCallback->GetRootPanel(), "Revert Movie File Changes from Perforce?", "Movie File", PERFORCE_ACTION_FILE_REVERT );
+ pPerforceFrame->AddFile( pPerforceFile );
+ pPerforceFrame->DoModal( );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Submit a file
+//-----------------------------------------------------------------------------
+void CToolFileMenuButton::OnPerforceSubmit( )
+{
+ char pPerforceFile[MAX_PATH];
+ if ( m_pFileMenuCallback->GetPerforceFileName( pPerforceFile, sizeof(pPerforceFile) ) )
+ {
+ CPerforceFileListFrame *pPerforceFrame = new CPerforceFileListFrame( m_pFileMenuCallback->GetRootPanel(), "Submit Movie File Changes to Perforce?", "Movie File", PERFORCE_ACTION_FILE_SUBMIT );
+ pPerforceFrame->AddFile( pPerforceFile );
+ pPerforceFrame->DoModal( );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Open a file in p4win
+//-----------------------------------------------------------------------------
+void CToolFileMenuButton::OnPerforceP4Win( )
+{
+ char pPerforceFile[MAX_PATH];
+ if ( m_pFileMenuCallback->GetPerforceFileName( pPerforceFile, sizeof(pPerforceFile) ) )
+ {
+ if ( p4->IsFileInPerforce( pPerforceFile ) )
+ {
+ p4->OpenFileInP4Win( pPerforceFile );
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Show a file in p4win
+//-----------------------------------------------------------------------------
+void CToolFileMenuButton::OnPerforceListOpenFiles( )
+{
+ CUtlVector<P4File_t> openedFiles;
+ p4->GetOpenedFileListInPath( "GAME", openedFiles );
+ COperationFileListFrame *pOpenedFiles = new COperationFileListFrame( m_pFileMenuCallback->GetRootPanel(), "Opened Files In Perforce", "File Name", false, true );
+
+ int nCount = openedFiles.Count();
+ for ( int i = 0; i < nCount; ++i )
+ {
+ const char *pOpenType = NULL;
+ switch( openedFiles[i].m_eOpenState )
+ {
+ case P4FILE_OPENED_FOR_ADD:
+ pOpenType = "Add";
+ break;
+ case P4FILE_OPENED_FOR_EDIT:
+ pOpenType = "Edit";
+ break;
+ case P4FILE_OPENED_FOR_DELETE:
+ pOpenType = "Delete";
+ break;
+ case P4FILE_OPENED_FOR_INTEGRATE:
+ pOpenType = "Integrate";
+ break;
+ }
+
+ if ( pOpenType )
+ {
+ pOpenedFiles->AddOperation( pOpenType, p4->String( openedFiles[i].m_sLocalFile ) );
+ }
+ }
+
+ pOpenedFiles->DoModal( );
+}
diff --git a/tools/toolutils/ToolHelpMenuButton.cpp b/tools/toolutils/ToolHelpMenuButton.cpp
new file mode 100644
index 0000000..6ee6567
--- /dev/null
+++ b/tools/toolutils/ToolHelpMenuButton.cpp
@@ -0,0 +1,60 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Core Movie Maker UI API
+//
+//=============================================================================
+
+#include "toolutils/toolswitchmenubutton.h"
+#include "vgui_controls/panel.h"
+#include "toolutils/toolmenubutton.h"
+#include "toolutils/enginetools_int.h"
+#include "tier1/KeyValues.h"
+#include "vgui_controls/menu.h"
+#include "vgui/ILocalize.h"
+#include "toolframework/ienginetool.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+
+//-----------------------------------------------------------------------------
+// Menu to switch between tools
+//-----------------------------------------------------------------------------
+class CToolHelpMenuButton : public CToolMenuButton
+{
+ DECLARE_CLASS_SIMPLE( CToolHelpMenuButton, CToolMenuButton );
+
+public:
+ CToolHelpMenuButton( char const *toolName, char const *helpBinding, vgui::Panel *parent, const char *panelName, const char *text, vgui::Panel *pActionTarget );
+};
+
+
+//-----------------------------------------------------------------------------
+// Global function to create the help menu
+//-----------------------------------------------------------------------------
+CToolMenuButton* CreateToolHelpMenuButton( char const *toolName, char const *helpBinding, vgui::Panel *parent, const char *panelName, const char *text, vgui::Panel *pActionTarget )
+{
+ return new CToolHelpMenuButton( toolName, helpBinding, parent, panelName, text, pActionTarget );
+}
+
+
+//-----------------------------------------------------------------------------
+// Constructor
+//-----------------------------------------------------------------------------
+CToolHelpMenuButton::CToolHelpMenuButton( char const *toolName, char const *helpBinding, vgui::Panel *parent, const char *panelName, const char *text, vgui::Panel *pActionTarget ) :
+ BaseClass( parent, panelName, text, pActionTarget )
+{
+ wchar_t *fmt = g_pVGuiLocalize->Find( "ToolHelpShowHelp" );
+ if ( fmt )
+ {
+ wchar_t desc[ 256 ];
+ g_pVGuiLocalize->ConvertANSIToUnicode( toolName, desc, sizeof( desc ) );
+
+ wchar_t buf[ 512 ];
+ g_pVGuiLocalize->ConstructString( buf, sizeof( buf ), fmt, 1, desc );
+
+ AddMenuItem( "help", buf, new KeyValues( "OnHelp" ), pActionTarget, NULL, helpBinding );
+ }
+
+ SetMenu(m_pMenu);
+}
diff --git a/tools/toolutils/ToolMenuButton.cpp b/tools/toolutils/ToolMenuButton.cpp
new file mode 100644
index 0000000..86ecaec
--- /dev/null
+++ b/tools/toolutils/ToolMenuButton.cpp
@@ -0,0 +1,185 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Core Movie Maker UI API
+//
+//=============================================================================
+
+#include "toolutils/toolmenubutton.h"
+#include "toolutils/toolmenubar.h"
+#include "toolutils/basetoolsystem.h"
+#include "vgui_controls/menu.h"
+#include "vgui_controls/KeyBindingMap.h"
+#include "vgui/ILocalize.h"
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+using namespace vgui;
+
+//-----------------------------------------------------------------------------
+// Constructor
+//-----------------------------------------------------------------------------
+CToolMenuButton::CToolMenuButton( Panel *parent, const char *panelName, const char *text, Panel *actionTarget ) :
+ BaseClass( parent, panelName, text ),
+ m_pActionTarget( actionTarget )
+{
+ m_pMenu = new Menu( this, "Menu" );
+}
+
+void CToolMenuButton::Reset()
+{
+ m_Items.RemoveAll();
+ m_pMenu->DeleteAllItems();
+}
+
+int CToolMenuButton::AddMenuItem( char const *itemName, const char *itemText, KeyValues *message, Panel *target, const KeyValues *userData /*= NULL*/, char const *kbcommandname /*= NULL*/ )
+{
+ int id = m_pMenu->AddMenuItem(itemText, message, target, userData);
+ MenuItem_t item;
+ item.m_ItemID = id;
+ if ( kbcommandname )
+ {
+ item.m_KeyBinding = kbcommandname;
+ }
+ m_Items.Insert( itemName, item );
+ return id;
+}
+
+int CToolMenuButton::AddCheckableMenuItem( char const *itemName, const char *itemText, KeyValues *message, Panel *target, const KeyValues *userData /*= NULL*/, char const *kbcommandname /*= NULL*/ )
+{
+ int id = m_pMenu->AddCheckableMenuItem(itemText, message, target, userData);
+ MenuItem_t item;
+ item.m_ItemID = id;
+ if ( kbcommandname )
+ {
+ item.m_KeyBinding = kbcommandname;
+ }
+ m_Items.Insert( itemName, item );
+ return id;
+}
+
+int CToolMenuButton::AddMenuItem( char const *itemName, const wchar_t *itemText, KeyValues *message, Panel *target, const KeyValues *userData /*= NULL*/, char const *kbcommandname /*= NULL*/ )
+{
+ int id = m_pMenu->AddMenuItem(itemName, itemText, message, target, userData);
+ MenuItem_t item;
+ item.m_ItemID = id;
+ if ( kbcommandname )
+ {
+ item.m_KeyBinding = kbcommandname;
+ }
+ m_Items.Insert( itemName, item );
+ return id;
+}
+
+int CToolMenuButton::AddCheckableMenuItem( char const *itemName, const wchar_t *itemText, KeyValues *message, Panel *target, const KeyValues *userData /*= NULL*/, char const *kbcommandname /*= NULL*/ )
+{
+ int id = m_pMenu->AddCheckableMenuItem(itemName, itemText, message, target, userData);
+ MenuItem_t item;
+ item.m_ItemID = id;
+ if ( kbcommandname )
+ {
+ item.m_KeyBinding = kbcommandname;
+ }
+ m_Items.Insert( itemName, item );
+ return id;
+}
+
+void CToolMenuButton::AddSeparator()
+{
+ m_pMenu->AddSeparator();
+}
+
+void CToolMenuButton::SetItemEnabled( int itemID, bool state )
+{
+ m_pMenu->SetItemEnabled( m_Items[ itemID ].m_ItemID, state );
+}
+
+int CToolMenuButton::FindMenuItem( char const *itemName )
+{
+ int id = m_Items.Find( itemName );
+ if ( id == m_Items.InvalidIndex() )
+ return -1;
+ return m_Items[ id ].m_ItemID;
+}
+
+void CToolMenuButton::AddSeparatorAfterItem( char const *itemName )
+{
+ int id = FindMenuItem( itemName );
+ if ( id != -1 )
+ {
+ m_pMenu->AddSeparatorAfterItem( id );
+ }
+}
+
+void CToolMenuButton::MoveMenuItem( int itemID, int moveBeforeThisItemID )
+{
+ m_pMenu->MoveMenuItem( itemID, moveBeforeThisItemID );
+}
+
+void CToolMenuButton::SetCurrentKeyBindingLabel( char const *itemName, char const *binding )
+{
+ int id = FindMenuItem( itemName );
+ if ( id != -1 )
+ {
+ m_pMenu->SetCurrentKeyBinding( id, binding );
+ }
+}
+
+
+
+void CToolMenuButton::UpdateMenuItemKeyBindings()
+{
+ if ( !m_pActionTarget )
+ return;
+
+ int c = m_Items.Count();
+ for ( int i = 0; i < c; ++i )
+ {
+ if ( !m_Items[ i ].m_KeyBinding.IsValid() )
+ continue;
+
+ char const *bindingName = m_Items[ i ].m_KeyBinding.String();
+
+ CUtlVector< BoundKey_t * > list;
+ m_pActionTarget->LookupBoundKeys( bindingName, list );
+ if ( list.Count() <= 0 )
+ continue;
+
+ BoundKey_t *kb = list[ 0 ];
+ Assert( kb );
+
+ // Found it, now convert to binding string
+ // First do modifiers
+ wchar_t sz[ 256 ];
+ wcsncpy( sz, Panel::KeyCodeModifiersToDisplayString( (KeyCode)kb->keycode, kb->modifiers ), 256 );
+ sz[ 255 ] = L'\0';
+
+ char ansi[ 512 ];
+ g_pVGuiLocalize->ConvertUnicodeToANSI( sz, ansi, sizeof( ansi ) );
+ m_pMenu->SetCurrentKeyBinding( m_Items[ i ].m_ItemID, ansi );
+
+ }
+}
+
+void CToolMenuButton::OnShowMenu( Menu *menu )
+{
+ CToolMenuBar *bar = dynamic_cast< CToolMenuBar * >( GetParent() );
+ if ( bar )
+ {
+ CBaseToolSystem *sys = bar->GetToolSystem();
+ if ( sys )
+ {
+ sys->UpdateMenu( menu );
+ }
+ }
+
+ UpdateMenuItemKeyBindings();
+
+ m_pMenu->ForceCalculateWidth();
+}
+
+vgui::Menu *CToolMenuButton::GetMenu()
+{
+ return m_pMenu;
+}
+
+
diff --git a/tools/toolutils/ToolSwitchMenuButton.cpp b/tools/toolutils/ToolSwitchMenuButton.cpp
new file mode 100644
index 0000000..46f0c7c
--- /dev/null
+++ b/tools/toolutils/ToolSwitchMenuButton.cpp
@@ -0,0 +1,72 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Core Movie Maker UI API
+//
+//=============================================================================
+
+#include "toolutils/toolswitchmenubutton.h"
+#include "vgui_controls/panel.h"
+#include "toolutils/toolmenubutton.h"
+#include "toolutils/enginetools_int.h"
+#include "tier1/KeyValues.h"
+#include "vgui_controls/menu.h"
+#include "toolframework/ienginetool.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+
+//-----------------------------------------------------------------------------
+// Menu to switch between tools
+//-----------------------------------------------------------------------------
+class CToolSwitchMenuButton : public CToolMenuButton
+{
+ DECLARE_CLASS_SIMPLE( CToolSwitchMenuButton, CToolMenuButton );
+
+public:
+ CToolSwitchMenuButton( vgui::Panel *parent, const char *panelName, const char *text, vgui::Panel *pActionTarget );
+ virtual void OnShowMenu(vgui::Menu *menu);
+};
+
+
+//-----------------------------------------------------------------------------
+// Global function to create the switch menu
+//-----------------------------------------------------------------------------
+CToolMenuButton* CreateToolSwitchMenuButton( vgui::Panel *parent, const char *panelName, const char *text, vgui::Panel *pActionTarget )
+{
+ return new CToolSwitchMenuButton( parent, panelName, text, pActionTarget );
+}
+
+
+//-----------------------------------------------------------------------------
+// Constructor
+//-----------------------------------------------------------------------------
+CToolSwitchMenuButton::CToolSwitchMenuButton( vgui::Panel *parent, const char *panelName, const char *text, vgui::Panel *pActionTarget ) :
+ BaseClass( parent, panelName, text, pActionTarget )
+{
+ SetMenu(m_pMenu);
+}
+
+
+//-----------------------------------------------------------------------------
+// Is called when the menu is made visible
+//-----------------------------------------------------------------------------
+void CToolSwitchMenuButton::OnShowMenu(vgui::Menu *menu)
+{
+ BaseClass::OnShowMenu( menu );
+
+ Reset();
+
+ int c = enginetools->GetToolCount();
+ for ( int i = 0 ; i < c; ++i )
+ {
+ char const *toolname = enginetools->GetToolName( i );
+
+ char toolcmd[ 32 ];
+ Q_snprintf( toolcmd, sizeof( toolcmd ), "OnTool%i", i );
+
+ int id = AddCheckableMenuItem( toolname, toolname, new KeyValues ( "Command", "command", toolcmd ), m_pActionTarget );
+ m_pMenu->SetItemEnabled( id, true );
+ m_pMenu->SetMenuItemChecked( id, enginetools->IsTopmostTool( enginetools->GetToolSystem( i ) ) );
+ }
+}
diff --git a/tools/toolutils/ToolUI.cpp b/tools/toolutils/ToolUI.cpp
new file mode 100644
index 0000000..012811c
--- /dev/null
+++ b/tools/toolutils/ToolUI.cpp
@@ -0,0 +1,118 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// The tool UI has 4 purposes:
+// 1) Create the menu bar and client area (lies under the menu bar)
+// 2) Forward all mouse messages to the tool workspace so action menus work
+// 3) Forward all commands to the tool system so all smarts can reside there
+// 4) Control the size of the menu bar + the working area
+//=============================================================================
+
+#include "ToolUI.h"
+#include "toolutils/toolmenubar.h"
+#include "toolutils/basetoolsystem.h"
+#include "vgui/Cursor.h"
+#include "vgui/ISurface.h"
+#include "tier1/KeyValues.h"
+#include "toolutils/toolmenubar.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+
+#define MENU_HEIGHT 28
+// Height of the status bar, if the tool installs one
+#define STATUS_HEIGHT 24
+//-----------------------------------------------------------------------------
+// Constructor
+//-----------------------------------------------------------------------------
+CToolUI::CToolUI( vgui::Panel *pParent, const char *panelName, CBaseToolSystem *pBaseToolSystem ) :
+ BaseClass( pParent, panelName ), m_pClientArea( 0 ), m_pBaseToolSystem( pBaseToolSystem )
+{
+ SetPaintEnabled(false);
+ SetPaintBackgroundEnabled(false);
+ SetPaintBorderEnabled(false);
+
+ int w, h;
+ pParent->GetSize( w, h );
+ SetBounds( 0, 0, w, h );
+
+ m_pMenuBar = m_pBaseToolSystem->CreateMenuBar( m_pBaseToolSystem );
+ m_pMenuBar->SetParent( this );
+ m_pMenuBar->SetSize( w, MENU_HEIGHT );
+ // This can be NULL if no status bar should be included
+ m_pStatusBar = m_pBaseToolSystem->CreateStatusBar( this );
+ m_pStatusBar->SetParent( this );
+
+ m_pClientArea = new vgui::Panel( this, "ClientArea" );
+ m_pClientArea->SetMouseInputEnabled( false );
+ m_pClientArea->SetCursor( vgui::dc_none );
+ m_pClientArea->SetBounds( 0, MENU_HEIGHT, w, h - MENU_HEIGHT );
+}
+
+vgui::Panel *CToolUI::GetClientArea()
+{
+ return m_pClientArea;
+}
+
+
+//-----------------------------------------------------------------------------
+// The tool UI panel should always fill the space...
+//-----------------------------------------------------------------------------
+void CToolUI::PerformLayout()
+{
+ BaseClass::PerformLayout();
+
+ // Make the editor panel fill the space
+ int iWidth, iHeight;
+ vgui::VPANEL parent = GetParent() ? GetParent()->GetVPanel() : vgui::surface()->GetEmbeddedPanel();
+ vgui::ipanel()->GetSize( parent, iWidth, iHeight );
+ SetSize( iWidth, iHeight );
+ int insettop = MENU_HEIGHT;
+ int insetbottom = 0;
+ m_pMenuBar->SetSize( iWidth, insettop );
+ if ( m_pStatusBar )
+ {
+ insetbottom = STATUS_HEIGHT;
+ m_pStatusBar->SetBounds( 0, iHeight - insetbottom, iWidth, insetbottom );
+ }
+ m_pClientArea->SetBounds( 0, insettop, iWidth, iHeight - insettop - insetbottom );
+}
+
+
+//-----------------------------------------------------------------------------
+// Returns the menu bar
+//-----------------------------------------------------------------------------
+vgui::MenuBar *CToolUI::GetMenuBar()
+{
+ return m_pMenuBar;
+}
+
+vgui::Panel *CToolUI::GetStatusBar()
+{
+ return m_pStatusBar;
+}
+
+//-----------------------------------------------------------------------------
+// Forward commands to systems that have more smarts than I do!
+//-----------------------------------------------------------------------------
+void CToolUI::OnMousePressed( vgui::MouseCode code )
+{
+ // Chain mouse pressed calls to the parent tool workspace
+ CallParentFunction( new KeyValues( "MousePressed", "code", code ) );
+}
+
+void CToolUI::OnCommand( const char *cmd )
+{
+ m_pBaseToolSystem->OnCommand( cmd );
+}
+
+void CToolUI::UpdateMenuBarTitle()
+{
+ CToolFileMenuBar *mb = dynamic_cast< CToolFileMenuBar * >( GetMenuBar() );
+ if ( mb )
+ {
+ char title[ 64 ];
+ m_pBaseToolSystem->ComputeMenuBarTitle( title, sizeof( title ) );
+ mb->SetInfo( title );
+ }
+}
diff --git a/tools/toolutils/ToolUI.h b/tools/toolutils/ToolUI.h
new file mode 100644
index 0000000..8a7a710
--- /dev/null
+++ b/tools/toolutils/ToolUI.h
@@ -0,0 +1,66 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// The tool UI has 4 purposes:
+// 1) Create the menu bar and client area (lies under the menu bar)
+// 2) Forward all mouse messages to the tool workspace so action menus work
+// 3) Forward all commands to the tool system so all smarts can reside there
+// 4) Control the size of the menu bar + the working area
+//=============================================================================
+
+#ifndef TOOLUI_H
+#define TOOLUI_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "vgui_controls/panel.h"
+#include "vgui/mousecode.h"
+
+
+//-----------------------------------------------------------------------------
+// Forward declarations
+//-----------------------------------------------------------------------------
+class CBaseToolSystem;
+
+namespace vgui
+{
+ class MenuBar;
+}
+
+//-----------------------------------------------------------------------------
+// The tool UI has 4 purposes:
+// 1) Create the menu bar and client area (lies under the menu bar)
+// 2) Forward all mouse messages to the tool workspace so action menus work
+// 3) Forward all commands to the tool system so all smarts can reside there
+// 4) Control the size of the menu bar + the working area
+//-----------------------------------------------------------------------------
+class CToolUI : public vgui::Panel
+{
+ DECLARE_CLASS_SIMPLE( CToolUI, vgui::Panel );
+
+public:
+ // Constructor
+ CToolUI( vgui::Panel *pParent, const char *pPanelName, CBaseToolSystem *pBaseToolSystem );
+
+ // Overrides of panel methods
+ virtual void PerformLayout();
+ virtual void OnCommand( const char *cmd );
+ virtual void OnMousePressed( vgui::MouseCode code );
+
+ virtual void UpdateMenuBarTitle();
+
+ // Other public methods
+ vgui::MenuBar *GetMenuBar();
+ vgui::Panel *GetClientArea();
+ vgui::Panel *GetStatusBar();
+
+private:
+ vgui::MenuBar *m_pMenuBar;
+ vgui::Panel *m_pStatusBar;
+ vgui::Panel *m_pClientArea;
+ CBaseToolSystem *m_pBaseToolSystem;
+};
+
+
+#endif // TOOLUI_H
diff --git a/tools/toolutils/attributeelementchoicelist.cpp b/tools/toolutils/attributeelementchoicelist.cpp
new file mode 100644
index 0000000..974ac21
--- /dev/null
+++ b/tools/toolutils/attributeelementchoicelist.cpp
@@ -0,0 +1,137 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+
+#include "toolutils/attributeelementchoicelist.h"
+#include "datamodel/dmelement.h"
+
+
+typedef CUtlRBTree< CDmElement *, int > ElementDict_t;
+
+
+//-----------------------------------------------------------------------------
+// returns the choice string that AddElementsRecursively would have returned
+//-----------------------------------------------------------------------------
+const char *GetChoiceString( CDmElement *pElement )
+{
+ return pElement->GetName();
+}
+
+//-----------------------------------------------------------------------------
+// Recursively adds all elements referred to this element into the list of elements
+//-----------------------------------------------------------------------------
+void AddElementsRecursively_R( CDmElement *pElement, ElementChoiceList_t &list, ElementDict_t &dict, const char *pElementType )
+{
+ if ( !pElement )
+ return;
+
+ if ( dict.Find( pElement ) != dict.InvalidIndex() )
+ return;
+
+ dict.Insert( pElement );
+
+ if ( pElement->IsA( pElementType ) )
+ {
+ int nIndex = list.AddToTail( );
+ ElementChoice_t &entry = list[nIndex];
+ entry.m_pValue = pElement;
+ entry.m_pChoiceString = GetChoiceString( pElement );
+ }
+
+ for ( CDmAttribute *pAttribute = pElement->FirstAttribute(); pAttribute; pAttribute = pAttribute->NextAttribute() )
+ {
+ char const *attributeName = pAttribute->GetName( );
+ DmAttributeType_t attrType = pAttribute->GetType( );
+ if ( attrType == AT_ELEMENT )
+ {
+ CDmElement *pChild = pElement->GetValueElement< CDmElement >( attributeName );
+ AddElementsRecursively_R( pChild, list, dict, pElementType );
+ }
+ else if ( attrType == AT_ELEMENT_ARRAY )
+ {
+ const CDmrElementArray<CDmElement> children( pElement, attributeName );
+ uint n = children.Count();
+ for ( uint i = 0; i < n; ++i )
+ {
+ CDmElement *pChild = children[ i ];
+ AddElementsRecursively_R( pChild, list, dict, pElementType );
+ }
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Recursively adds all elements referred to this element into the list of elements
+//-----------------------------------------------------------------------------
+void AddElementsRecursively_R( CDmElement *pElement, DmeHandleVec_t &list, ElementDict_t &dict, const char *pElementType )
+{
+ if ( !pElement )
+ return;
+
+ if ( dict.Find( pElement ) != dict.InvalidIndex() )
+ return;
+
+ dict.Insert( pElement );
+
+ if ( pElement->IsA( pElementType ) )
+ {
+ int nIndex = list.AddToTail( );
+ list[nIndex] = pElement;
+ }
+
+ for ( CDmAttribute *pAttribute = pElement->FirstAttribute(); pAttribute; pAttribute = pAttribute->NextAttribute() )
+ {
+ char const *attributeName = pAttribute->GetName( );
+ DmAttributeType_t attrType = pAttribute->GetType( );
+ if ( attrType == AT_ELEMENT )
+ {
+ CDmElement *pChild = pElement->GetValueElement< CDmElement >( attributeName );
+ AddElementsRecursively_R( pChild, list, dict, pElementType );
+ }
+ else if ( attrType == AT_ELEMENT_ARRAY )
+ {
+ const CDmrElementArray<CDmElement> children( pElement, attributeName );
+ uint n = children.Count();
+ for ( uint i = 0; i < n; ++i )
+ {
+ CDmElement *pChild = children[ i ];
+ AddElementsRecursively_R( pChild, list, dict, pElementType );
+ }
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Recursively adds all elements referred to this element into the list of elements
+//-----------------------------------------------------------------------------
+void AddElementsRecursively( CDmElement *obj, ElementChoiceList_t &list, const char *pElementType )
+{
+ if ( !pElementType )
+ {
+ pElementType = g_pDataModel->GetString( CDmElement::GetStaticTypeSymbol() );
+ }
+
+ ElementDict_t dict( 0, 0, DefLessFunc( CDmElement * ) );
+ AddElementsRecursively_R( obj, list, dict, pElementType );
+}
+
+
+//-----------------------------------------------------------------------------
+// Recursively adds all elements of the specified type under pElement into the vector
+//-----------------------------------------------------------------------------
+void AddElementsRecursively( CDmElement *pElement, DmeHandleVec_t &list, const char *pElementType )
+{
+ if ( !pElementType )
+ {
+ pElementType = g_pDataModel->GetString( CDmElement::GetStaticTypeSymbol() );
+ }
+
+ ElementDict_t dict( 0, 0, DefLessFunc( CDmElement * ) );
+ AddElementsRecursively_R( pElement, list, dict, pElementType );
+}
diff --git a/tools/toolutils/basepropertiescontainer.cpp b/tools/toolutils/basepropertiescontainer.cpp
new file mode 100644
index 0000000..50891a9
--- /dev/null
+++ b/tools/toolutils/basepropertiescontainer.cpp
@@ -0,0 +1,47 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================
+
+#include "toolutils/basepropertiescontainer.h"
+#include "tier1/KeyValues.h"
+
+CBasePropertiesContainer::CBasePropertiesContainer( vgui::Panel *parent, IDmNotify *pNotify, CDmeEditorTypeDictionary *pDict /*=NULL*/ )
+ : BaseClass( parent, pNotify, NULL, true, pDict )
+{
+ SetDropEnabled( true );
+}
+
+bool CBasePropertiesContainer::IsDroppable( CUtlVector< KeyValues * >& msglist )
+{
+ if ( msglist.Count() != 1 )
+ return false;
+
+ KeyValues *data = msglist[ 0 ];
+ CDmElement *ptr = reinterpret_cast< CDmElement * >( g_pDataModel->GetElement( DmElementHandle_t( data->GetInt( "dmeelement", DMELEMENT_HANDLE_INVALID ) ) ) );
+ if ( !ptr )
+ return false;
+
+ if ( ptr == GetObject() )
+ return false;
+
+ return true;
+}
+
+void CBasePropertiesContainer::OnPanelDropped( CUtlVector< KeyValues * >& msglist )
+{
+ if ( msglist.Count() != 1 )
+ return;
+
+ KeyValues *data = msglist[ 0 ];
+ CDmElement *ptr = reinterpret_cast< CDmElement * >( g_pDataModel->GetElement( DmElementHandle_t( data->GetInt( "dmeelement", DMELEMENT_HANDLE_INVALID ) ) ) );
+ if ( !ptr )
+ return;
+
+ // Already browsing
+ if ( ptr == GetObject() )
+ return;
+
+ SetObject( ptr );
+} \ No newline at end of file
diff --git a/tools/toolutils/basestatusbar.cpp b/tools/toolutils/basestatusbar.cpp
new file mode 100644
index 0000000..1fe8add
--- /dev/null
+++ b/tools/toolutils/basestatusbar.cpp
@@ -0,0 +1,151 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================
+
+#include "toolutils/basestatusbar.h"
+#include "toolutils/ConsolePage.h"
+#include "vgui_controls/Label.h"
+#include "movieobjects/dmeclip.h"
+#include "tier1/KeyValues.h"
+#include "vgui/IVGui.h"
+#include "toolutils/enginetools_int.h"
+#include "toolframework/ienginetool.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+using namespace vgui;
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CBaseStatusBar::CBaseStatusBar( vgui::Panel *parent, char const *panelName )
+ : BaseClass( parent, panelName ),
+ m_flLastFPSSnapShot( -1.0f )
+{
+ SetVisible( true );
+ m_pConsole = new CConsolePage( this, true );
+ m_pLabel = new Label( this, "Console", "#BxConsole" );
+ m_pMemory = new Label( this, "Memory", "" );
+ m_pFPS = new Label( this, "FPS", "" );
+ m_pGameTime = new Label( this, "GameTime", "" );
+
+ MakePopup( false );
+
+ UpdateMemoryUsage( 9.999 );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Forces console to take up full area except right edge
+// Input : -
+//-----------------------------------------------------------------------------
+void CBaseStatusBar::PerformLayout()
+{
+ BaseClass::PerformLayout();
+
+ int w, h;
+ GetSize( w, h );
+
+ int oldw = w;
+
+ w *= 0.45f;
+
+ int x = 8;
+
+ int cw, ch;
+ m_pLabel->GetContentSize( cw, ch );
+ m_pLabel->SetBounds( x, 4, cw, h - 8 );
+
+ x += cw + 4;
+
+ int consoleWide = w - x - 8;
+
+ m_pConsole->SetBounds( x, 2, consoleWide, h - 4 );
+
+ x += consoleWide + 4;
+
+ int infoW = 85;
+
+ int rightx = oldw - infoW - 10;
+ m_pFPS->SetBounds( rightx, 2, infoW - 2 - 10, h - 8 );
+ rightx -= infoW;
+ m_pGameTime->SetBounds( rightx, 2, infoW - 2, h - 8 );
+ rightx -= infoW;
+ m_pMemory->SetBounds( rightx, 2, infoW - 2, h - 8 );
+}
+
+void CBaseStatusBar::UpdateMemoryUsage( float mbUsed )
+{
+ char mem[ 256 ];
+ Q_snprintf( mem, sizeof( mem ), "[mem: %.2f Mb]", mbUsed );
+ m_pMemory->SetText( mem );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Message map
+//-----------------------------------------------------------------------------
+void CBaseStatusBar::ApplySchemeSettings(IScheme *pScheme)
+{
+ BaseClass::ApplySchemeSettings(pScheme);
+
+ // get the borders we need
+ SetBorder(pScheme->GetBorder("ButtonBorder"));
+
+ // get the background color
+ SetBgColor(pScheme->GetColor( "StatusBar.BgColor", GetBgColor() ));
+
+ m_pLabel->SetFont( pScheme->GetFont( "DefaultVerySmall" ) );
+ m_pMemory->SetFont( pScheme->GetFont( "DefaultVerySmall" ) );
+ m_pFPS->SetFont( pScheme->GetFont( "DefaultVerySmall" ) );
+ m_pGameTime->SetFont( pScheme->GetFont( "DefaultVerySmall" ) );
+}
+
+static float GetMemoryUsage();
+
+void CBaseStatusBar::OnThink()
+{
+ BaseClass::OnThink();
+
+ float curtime = enginetools->GetRealTime();
+
+ char gt[ 32 ];
+ Q_snprintf( gt, sizeof( gt ), "[game: %.3f]", enginetools->ServerTime() );
+ m_pGameTime->SetText( gt );
+
+ float elapsed = curtime - m_flLastFPSSnapShot;
+ if ( elapsed < 0.4f )
+ return;
+
+ m_flLastFPSSnapShot = curtime;
+
+ float ft = enginetools->GetRealFrameTime();
+ if ( ft <= 0.0f )
+ {
+ m_pFPS->SetText( "[fps: ??]" );
+ }
+ else
+ {
+ char fps[ 32 ];
+ Q_snprintf( fps, sizeof( fps ), "[fps: %.1f]", 1.0f / ft );
+ m_pFPS->SetText( fps );
+ }
+
+ UpdateMemoryUsage( GetMemoryUsage() );
+}
+
+#include <windows.h>
+#include <psapi.h>
+static float GetMemoryUsage()
+{
+ PROCESS_MEMORY_COUNTERS counters;
+ counters.cb = sizeof( counters );
+
+ if ( GetProcessMemoryInfo( GetCurrentProcess(), &counters, sizeof( counters ) ) )
+ {
+ return (float)counters.WorkingSetSize / ( 1024.0f * 1024.0f );
+ }
+
+ return 0;
+} \ No newline at end of file
diff --git a/tools/toolutils/miniviewport.cpp b/tools/toolutils/miniviewport.cpp
new file mode 100644
index 0000000..2b74c35
--- /dev/null
+++ b/tools/toolutils/miniviewport.cpp
@@ -0,0 +1,457 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================
+
+#include "toolutils/miniviewport.h"
+#include "tier1/utlstring.h"
+#include "vgui/ISurface.h"
+#include "materialsystem/imaterialsystemhardwareconfig.h"
+#include "materialsystem/imaterialsystem.h"
+#include "materialsystem/MaterialSystemUtil.h"
+#include "materialsystem/imesh.h"
+#include "materialsystem/imaterial.h"
+#include "materialsystem/itexture.h"
+#include "tier1/KeyValues.h"
+#include "toolframework/ienginetool.h"
+#include "toolutils/enginetools_int.h"
+#include "VGuiMatSurface/IMatSystemSurface.h"
+#include "view_shared.h"
+#include "texture_group_names.h"
+#include "vgui_controls/PropertySheet.h"
+#include "tier2/tier2.h"
+#include <windows.h> // for MultiByteToWideChar
+#include "cdll_int.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+class CMiniViewportEngineRenderArea;
+
+using namespace vgui;
+
+extern IMatSystemSurface *g_pMatSystemSurface;
+
+#define DEFAULT_PREVIEW_WIDTH 1280
+
+//-----------------------------------------------------------------------------
+// Purpose: This is a "frame" which is used to position the engine
+//-----------------------------------------------------------------------------
+class CMiniViewportPropertyPage : public vgui::EditablePanel
+{
+ DECLARE_CLASS_SIMPLE( CMiniViewportPropertyPage, vgui::EditablePanel );
+
+public:
+ CMiniViewportPropertyPage( Panel *parent, const char *panelName );
+
+ virtual Color GetBgColor();
+
+ void GetEngineBounds( int& x, int& y, int& w, int& h );
+
+ void RenderFrameBegin();
+
+ CMiniViewportEngineRenderArea *GetViewportArea() { return m_pViewportArea; }
+
+private:
+ virtual void PerformLayout();
+
+ Color m_bgColor;
+
+ CMiniViewportEngineRenderArea *m_pViewportArea;
+};
+
+//-----------------------------------------------------------------------------
+//
+// the actual renderable area
+//
+//-----------------------------------------------------------------------------
+class CMiniViewportEngineRenderArea : public vgui::EditablePanel
+{
+ DECLARE_CLASS_SIMPLE( CMiniViewportEngineRenderArea, vgui::EditablePanel );
+
+public:
+ CMiniViewportEngineRenderArea( Panel *parent, const char *panelName );
+ ~CMiniViewportEngineRenderArea();
+
+ virtual void PaintBackground();
+ virtual void GetEngineBounds( int& x, int& y, int& w, int& h );
+ virtual void ApplySchemeSettings( IScheme *pScheme );
+
+ void RenderFrameBegin();
+ void SetOverlayText( const char *pText );
+
+ // Called when the layoff texture needs to be released
+ void ReleaseLayoffTexture();
+
+protected:
+ void InitSceneMaterials();
+ void ShutdownSceneMaterials();
+
+ // Paints the black borders around the engine window
+ void PaintEngineBorders( int x, int y, int w, int h );
+
+ // Paints the engine window itself
+ void PaintEngineWindow( int x, int y, int w, int h );
+
+ // Paints the overlay text
+ void PaintOverlayText( );
+
+ int m_nEngineOutputTexture;
+ vgui::HFont m_OverlayTextFont;
+ CUtlString m_OverlayText;
+
+ CTextureReference m_ScreenBuffer;
+ CMaterialReference m_ScreenMaterial;
+};
+
+
+CMiniViewportEngineRenderArea::CMiniViewportEngineRenderArea( Panel *parent, const char *panelName )
+ : BaseClass( parent, panelName )
+{
+ SetPaintEnabled( false );
+ SetPaintBorderEnabled( false );
+ SetPaintBackgroundEnabled( true );
+
+ m_nEngineOutputTexture = vgui::surface()->CreateNewTextureID();
+}
+
+CMiniViewportEngineRenderArea::~CMiniViewportEngineRenderArea()
+{
+ ShutdownSceneMaterials();
+}
+
+void CMiniViewportEngineRenderArea::RenderFrameBegin()
+{
+ if ( !enginetools->IsInGame() )
+ return;
+
+ InitSceneMaterials();
+
+ CViewSetup playerViewSetup;
+ int x, y, w, h;
+ GetEngineBounds( x, y, w, h );
+ enginetools->GetPlayerView( playerViewSetup, 0, 0, w, h );
+
+ // NOTE: This is a workaround to a nasty problem. Vgui uses stencil
+ // to determing if the panels should occlude each other. The engine
+ // has now started to use stencil for various random effects.
+ // To prevent these different stencil uses from clashing, we will
+ // render the engine prior to vgui painting + cache the result off in
+ //
+ // Make the engine draw the scene
+ CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
+ pRenderContext->PushRenderTargetAndViewport( m_ScreenBuffer, 0, 0, w, h );
+
+ // Tell the engine to tell the client to render the view (sans viewmodel)
+ enginetools->SetMainView( playerViewSetup.origin, playerViewSetup.angles );
+ enginetools->RenderView( playerViewSetup, VIEW_CLEAR_COLOR | VIEW_CLEAR_DEPTH, RENDERVIEW_DRAWHUD | RENDERVIEW_DRAWVIEWMODEL );
+
+ // Pop the target
+ pRenderContext->PopRenderTargetAndViewport();
+}
+
+void CMiniViewportEngineRenderArea::InitSceneMaterials()
+{
+ if ( m_ScreenBuffer )
+ return;
+
+ if ( g_pMaterialSystem->IsTextureLoaded( "_rt_LayoffResult" ) )
+ {
+ ITexture *pTexture = g_pMaterialSystem->FindTexture( "_rt_LayoffResult", TEXTURE_GROUP_RENDER_TARGET );
+ m_ScreenBuffer.Init( pTexture );
+ }
+ else
+ {
+ // For now, layoff dimensions match aspect of back buffer
+ int nBackBufferWidth, nBackBufferHeight;
+ g_pMaterialSystem->GetBackBufferDimensions( nBackBufferWidth, nBackBufferHeight );
+ float flAspect = nBackBufferWidth / (float)nBackBufferHeight;
+ int nPreviewWidth = min( DEFAULT_PREVIEW_WIDTH, nBackBufferWidth );
+ int nPreviewHeight = ( int )( nPreviewWidth / flAspect + 0.5f );
+
+ g_pMaterialSystem->BeginRenderTargetAllocation(); // Begin allocating RTs which IFM can scribble into
+
+ // LDR final result of either HDR or LDR rendering
+ m_ScreenBuffer.Init( g_pMaterialSystem->CreateNamedRenderTargetTextureEx2(
+ "_rt_LayoffResult", nPreviewWidth, nPreviewHeight, RT_SIZE_OFFSCREEN,
+ g_pMaterialSystem->GetBackBufferFormat(), MATERIAL_RT_DEPTH_SHARED, TEXTUREFLAGS_BORDER ) );
+
+ g_pMaterialSystem->EndRenderTargetAllocation(); // End allocating RTs which IFM can scribble into
+ }
+
+ KeyValues *pVMTKeyValues = NULL;
+ pVMTKeyValues= new KeyValues( "UnlitGeneric" );
+ pVMTKeyValues->SetString( "$basetexture", m_ScreenBuffer->GetName() );
+ pVMTKeyValues->SetInt( "$nofog", 1 );
+ m_ScreenMaterial.Init( "MiniViewportEngineRenderAreaSceneMaterial", pVMTKeyValues );
+ m_ScreenMaterial->Refresh();
+}
+
+
+//-----------------------------------------------------------------------------
+// Called when the layoff texture needs to be released
+//-----------------------------------------------------------------------------
+void CMiniViewportEngineRenderArea::ReleaseLayoffTexture()
+{
+ m_ScreenBuffer.Shutdown();
+ m_ScreenMaterial.Shutdown();
+}
+
+
+//-----------------------------------------------------------------------------
+// Apply scheme settings
+//-----------------------------------------------------------------------------
+void CMiniViewportEngineRenderArea::ApplySchemeSettings( IScheme *pScheme )
+{
+ BaseClass::ApplySchemeSettings( pScheme );
+ m_OverlayTextFont = pScheme->GetFont( "DefaultLargeOutline" );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CMiniViewportEngineRenderArea::ShutdownSceneMaterials()
+{
+ m_ScreenBuffer.Shutdown();
+ m_ScreenMaterial.Shutdown();
+}
+
+
+//-----------------------------------------------------------------------------
+// Sets text to draw over the window
+//-----------------------------------------------------------------------------
+void CMiniViewportEngineRenderArea::SetOverlayText( const char *pText )
+{
+ m_OverlayText = pText;
+}
+
+
+//-----------------------------------------------------------------------------
+// Paints the black borders around the engine window
+//-----------------------------------------------------------------------------
+void CMiniViewportEngineRenderArea::PaintEngineBorders( int x, int y, int w, int h )
+{
+ // Draws black borders around the engine window
+ surface()->DrawSetColor( Color( 0, 0, 0, 255 ) );
+ if ( x != 0 )
+ {
+ surface()->DrawFilledRect( 0, 0, x, h );
+ surface()->DrawFilledRect( x + w, 0, w + 2 * x, h );
+ }
+ else if ( y != 0 )
+ {
+ surface()->DrawFilledRect( 0, 0, w, y );
+ surface()->DrawFilledRect( 0, y + h, w, h + 2 * y );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Paints the overlay text
+//-----------------------------------------------------------------------------
+void CMiniViewportEngineRenderArea::PaintOverlayText( )
+{
+ if ( !m_OverlayText.Length() )
+ return;
+
+ int cw, ch;
+ GetSize( cw, ch );
+
+ int nTextWidth, nTextHeight;
+ int nBufLen = m_OverlayText.Length()+1;
+ wchar_t *pTemp = (wchar_t*)_alloca( nBufLen * sizeof(wchar_t) );
+ ::MultiByteToWideChar( CP_UTF8, 0, m_OverlayText.Get(), -1, pTemp, nBufLen );
+
+ g_pMatSystemSurface->GetTextSize( m_OverlayTextFont, pTemp, nTextWidth, nTextHeight );
+ int lx = (cw - nTextWidth) / 2;
+ if ( lx < 10 )
+ {
+ lx = 10;
+ }
+ int ly = ch - 10 - nTextHeight;
+ g_pMatSystemSurface->DrawColoredTextRect( m_OverlayTextFont,
+ lx, ly, cw - lx, ch - ly,
+ 255, 255, 255, 255, "%s", m_OverlayText.Get() );
+}
+
+
+//-----------------------------------------------------------------------------
+// Paints the engine window itself
+//-----------------------------------------------------------------------------
+void CMiniViewportEngineRenderArea::PaintEngineWindow( int x, int y, int w, int h )
+{
+ if ( !enginetools->IsInGame() )
+ {
+ surface()->DrawSetColor( Color( 127, 127, 200, 63 ) );
+ surface()->DrawFilledRect( x, y, x + w, y + h );
+ }
+ else
+ {
+ CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
+
+ g_pMatSystemSurface->DrawSetTextureMaterial( m_nEngineOutputTexture, m_ScreenMaterial );
+ surface()->DrawSetColor( Color( 0, 0, 0, 255 ) );
+
+ int nTexWidth = m_ScreenBuffer->GetActualWidth();
+ int nTexHeight = m_ScreenBuffer->GetActualHeight();
+ float flOOWidth = 1.0f / nTexWidth;
+ float flOOHeight = 1.0f / nTexHeight;
+
+ float s0, s1, t0, t1;
+
+ s0 = ( 0.5f ) * flOOWidth;
+ t0 = ( 0.5f ) * flOOHeight;
+ s1 = ( (float)w - 0.5f ) * flOOWidth;
+ t1 = ( (float)h - 0.5f ) * flOOHeight;
+
+ vgui::surface()->DrawTexturedSubRect( x, y, x+w, y+h, s0, t0, s1, t1 );
+
+ PaintOverlayText();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Paints the background
+//-----------------------------------------------------------------------------
+void CMiniViewportEngineRenderArea::PaintBackground()
+{
+ int x, y, w, h;
+ GetEngineBounds( x, y, w, h );
+ PaintEngineBorders( x, y, w, h );
+ PaintEngineWindow( x, y, w, h );
+}
+
+void CMiniViewportEngineRenderArea::GetEngineBounds( int& x, int& y, int& w, int& h )
+{
+ x = 0;
+ y = 0;
+ GetSize( w, h );
+
+ // Check aspect ratio
+ int sx, sy;
+ surface()->GetScreenSize( sx, sy );
+
+ if ( sy > 0 &&
+ h > 0 )
+ {
+ float screenaspect = (float)sx / (float)sy;
+ float aspect = (float)w / (float)h;
+
+ float ratio = screenaspect / aspect;
+
+ // Screen is wider, need bars at top and bottom
+ if ( ratio > 1.0f )
+ {
+ int usetall = (float)w / screenaspect;
+ y = ( h - usetall ) / 2;
+ h = usetall;
+ }
+ // Screen is narrower, need bars at left/right
+ else
+ {
+ int usewide = (float)h * screenaspect;
+ x = ( w - usewide ) / 2;
+ w = usewide;
+ }
+ }
+}
+
+CMiniViewportPropertyPage::CMiniViewportPropertyPage(Panel *parent, const char *panelName ) :
+ BaseClass( parent, panelName )
+{
+ m_bgColor = Color( 0, 0, 0, 0 );
+
+ m_pViewportArea = new CMiniViewportEngineRenderArea( this, "Engine" );
+}
+
+void CMiniViewportPropertyPage::PerformLayout()
+{
+ BaseClass::PerformLayout();
+
+ int w, h;
+ GetSize( w, h );
+ m_pViewportArea->SetBounds( 0, 0, w, h );
+}
+
+Color CMiniViewportPropertyPage::GetBgColor()
+{
+ return m_bgColor;
+}
+
+
+void CMiniViewportPropertyPage::GetEngineBounds( int& x, int& y, int& w, int& h )
+{
+ m_pViewportArea->GetEngineBounds( x, y, w, h );
+ m_pViewportArea->LocalToScreen( x, y );
+}
+
+void CMiniViewportPropertyPage::RenderFrameBegin()
+{
+ m_pViewportArea->RenderFrameBegin();
+}
+
+CMiniViewport::CMiniViewport( vgui::Panel *parent, bool contextLabel, vgui::IToolWindowFactory *factory /*= 0*/,
+ vgui::Panel *page /*= NULL*/, char const *title /*= NULL*/, bool contextMenu /*= false*/ ) :
+ BaseClass( parent, contextLabel, factory, page, title, contextMenu, false )
+{
+ SetCloseButtonVisible( false );
+
+ GetPropertySheet()->SetDraggableTabs( false );
+
+ // Add the viewport panel
+ m_hPage = new CMiniViewportPropertyPage( this, "ViewportPage" );
+
+ AddPage( m_hPage.Get(), "#ToolMiniViewport", false );
+}
+
+void CMiniViewport::GetViewport( bool& enabled, int& x, int& y, int& w, int& h )
+{
+ enabled = false;
+ x = y = w = h = 0;
+
+ int screenw, screenh;
+ surface()->GetScreenSize( screenw, screenh );
+
+ m_hPage->GetEngineBounds( x, y, w, h );
+
+ y = screenh - ( y + h );
+}
+
+void CMiniViewport::GetEngineBounds( int& x, int& y, int& w, int& h )
+{
+ m_hPage->GetEngineBounds( x, y, w, h );
+}
+
+
+//-----------------------------------------------------------------------------
+// Called when the layoff texture needs to be released
+//-----------------------------------------------------------------------------
+void CMiniViewport::ReleaseLayoffTexture()
+{
+ if ( m_hPage.Get() )
+ {
+ m_hPage->GetViewportArea()->ReleaseLayoffTexture();
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Sets text to draw over the window
+//-----------------------------------------------------------------------------
+void CMiniViewport::SetOverlayText( const char *pText )
+{
+ if ( m_hPage.Get() )
+ {
+ m_hPage->GetViewportArea()->SetOverlayText( pText );
+ }
+}
+
+void CMiniViewport::RenderFrameBegin()
+{
+ if ( m_hPage.Get() )
+ {
+ m_hPage->RenderFrameBegin();
+ }
+}
diff --git a/tools/toolutils/recentfilelist.cpp b/tools/toolutils/recentfilelist.cpp
new file mode 100644
index 0000000..d8a436c
--- /dev/null
+++ b/tools/toolutils/recentfilelist.cpp
@@ -0,0 +1,157 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Core Movie Maker UI API
+//
+//=============================================================================
+
+#include "toolutils/recentfilelist.h"
+#include "vgui_controls/menu.h"
+#include "iregistry.h"
+#include "tier1/KeyValues.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+
+
+//-----------------------------------------------------------------------------
+// Adds a file to the list of recent files
+//-----------------------------------------------------------------------------
+void CRecentFileList::Add( const char *pFileName, const char *pFileFormat )
+{
+ RecentFileInfo_t info;
+ info.m_pFileName = pFileName;
+ int idx = m_RecentFiles.Find( info );
+ if ( idx != m_RecentFiles.InvalidIndex() )
+ {
+ // Remove from current slot so it gets added to head (most recent) below...
+ m_RecentFiles.Remove( idx );
+ }
+
+ while ( m_RecentFiles.Count() >= MAX_RECENT_FILES )
+ {
+ // Oldest is at last slot
+ m_RecentFiles.Remove( m_RecentFiles.Count() - 1 );
+ }
+
+ int i = m_RecentFiles.AddToHead( );
+ m_RecentFiles[i].m_pFileName = pFileName;
+ m_RecentFiles[i].m_pFileFormat = pFileFormat;
+}
+
+
+//-----------------------------------------------------------------------------
+// Removes all files from the list
+//-----------------------------------------------------------------------------
+void CRecentFileList::Clear()
+{
+ m_RecentFiles.RemoveAll();
+}
+
+
+//-----------------------------------------------------------------------------
+// Returns true if there's no files in the file list
+//-----------------------------------------------------------------------------
+bool CRecentFileList::IsEmpty() const
+{
+ return m_RecentFiles.Count() == 0;
+}
+
+
+//-----------------------------------------------------------------------------
+// Gets the file in a particular slot
+//-----------------------------------------------------------------------------
+const char *CRecentFileList::GetFile( int slot ) const
+{
+ if ( slot < 0 || slot >= m_RecentFiles.Count() )
+ return NULL;
+
+ return m_RecentFiles[slot].m_pFileName;
+}
+
+
+//-----------------------------------------------------------------------------
+// Gets the file in a particular slot
+//-----------------------------------------------------------------------------
+const char *CRecentFileList::GetFileFormat( int slot ) const
+{
+ if ( slot < 0 || slot >= m_RecentFiles.Count() )
+ return NULL;
+
+ return m_RecentFiles[slot].m_pFileFormat;
+}
+
+
+//-----------------------------------------------------------------------------
+// Loads the file list from the registry
+//-----------------------------------------------------------------------------
+void CRecentFileList::LoadFromRegistry( const char *pToolKeyName )
+{
+ Clear();
+
+ // Iterate in reverse order so most recent files goes to top
+ for ( int i = MAX_RECENT_FILES; i >= 0; --i )
+ {
+ char sz[ 128 ];
+ char szType[ 128 ];
+ Q_snprintf( sz, sizeof( sz ), "%s\\history%02i", pToolKeyName, i );
+ Q_snprintf( szType, sizeof( szType ), "%s\\history_fileformat%02i", pToolKeyName, i );
+
+ // NOTE: Can't call registry->ReadString twice in a row!
+ char pFileName[MAX_PATH];
+ Q_strncpy( pFileName, registry->ReadString( sz, "" ), sizeof(pFileName) );
+ if ( pFileName && pFileName[ 0 ] )
+ {
+ const char *valType = registry->ReadString( szType, "" );
+ const char *pFormat = (valType && valType[0]) ? valType : "dmx";
+ Add( pFileName, pFormat );
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Saves file list into the registry
+//-----------------------------------------------------------------------------
+void CRecentFileList::SaveToRegistry( const char *pToolKeyName ) const
+{
+ char sz[ 128 ];
+
+ int i, c;
+ c = m_RecentFiles.Count();
+ for ( i = 0 ; i < c; ++i )
+ {
+ Q_snprintf( sz, sizeof( sz ), "%s\\history%02i", pToolKeyName, i );
+ registry->WriteString( sz, m_RecentFiles[i].m_pFileName );
+
+ Q_snprintf( sz, sizeof( sz ), "%s\\history_fileformat%02i", pToolKeyName, i );
+ registry->WriteString( sz, m_RecentFiles[i].m_pFileFormat );
+ }
+
+ // Clear out all other registry settings
+ for ( ; i < MAX_RECENT_FILES; ++i )
+ {
+ Q_snprintf( sz, sizeof( sz ), "%s\\history%02i", pToolKeyName, i );
+ registry->WriteString( sz, "" );
+
+ Q_snprintf( sz, sizeof( sz ), "%s\\history_fileformat%02i", pToolKeyName, i );
+ registry->WriteString( sz, "" );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Adds the list of files to a particular menu
+//-----------------------------------------------------------------------------
+void CRecentFileList::AddToMenu( vgui::Menu *menu, vgui::Panel *pActionTarget, const char *pCommandName ) const
+{
+ int i, c;
+ c = m_RecentFiles.Count();
+ for ( i = 0 ; i < c; ++i )
+ {
+ char sz[ 32 ];
+ Q_snprintf( sz, sizeof( sz ), "%s%02i", pCommandName, i );
+ char const *fn = m_RecentFiles[i].m_pFileName;
+ menu->AddMenuItem( fn, new KeyValues( "Command", "command", sz ), pActionTarget );
+ }
+}
diff --git a/tools/toolutils/savewindowpositions.cpp b/tools/toolutils/savewindowpositions.cpp
new file mode 100644
index 0000000..8447bf0
--- /dev/null
+++ b/tools/toolutils/savewindowpositions.cpp
@@ -0,0 +1,286 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================
+
+#include "toolutils/savewindowpositions.h"
+#include "iregistry.h"
+#include "vgui_controls/Panel.h"
+#include "vgui_controls/PHandle.h"
+#include "vgui_controls/ToolWindow.h"
+#include "vgui/ISurface.h"
+#include "vgui_controls/PropertySheet.h"
+#include "tier1/utlsymbol.h"
+#include "tier1/utlbuffer.h"
+#include "tier1/KeyValues.h"
+#include "filesystem.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+using namespace vgui;
+
+//-----------------------------------------------------------------------------
+// Purpose: This will save the bounds and the visibility state of UI elements registered during startup
+// FIXME: Preserve Z order?
+//-----------------------------------------------------------------------------
+class CWindowPositionMgr : public IWindowPositionMgr
+{
+public:
+ // Inherited from IWindowPositionMgr
+ virtual void SavePositions( char const *filename, char const *key );
+ virtual bool LoadPositions( char const *filename, Panel *parent, vgui::IToolWindowFactory *factory, char const *key, bool force = false );
+ virtual void RegisterPanel( char const *saveName, Panel *panel, bool contextMenu );
+ virtual void UnregisterPanel( vgui::Panel *panel );
+
+private:
+ struct LoadInfo_t
+ {
+ CUtlSymbol m_Name;
+ PHandle m_hPanel;
+ bool m_bLoaded;
+ bool m_bContextMenu;
+ };
+
+ LoadInfo_t *Find( Panel *panel );
+ LoadInfo_t *Find( char const *panelName );
+
+ CUtlVector< LoadInfo_t > m_Panels;
+};
+
+
+//-----------------------------------------------------------------------------
+// Singleton instance
+//-----------------------------------------------------------------------------
+static CWindowPositionMgr g_WindowPositionMgr;
+IWindowPositionMgr *windowposmgr = &g_WindowPositionMgr;
+
+CWindowPositionMgr::LoadInfo_t *CWindowPositionMgr::Find( Panel *panel )
+{
+ if ( !panel )
+ return NULL;
+
+ int c = m_Panels.Count();
+ for ( int i = 0; i < c; ++i )
+ {
+ LoadInfo_t *info = &m_Panels[ i ];
+ if ( info->m_hPanel.Get() == panel )
+ return info;
+ }
+ return NULL;
+}
+
+CWindowPositionMgr::LoadInfo_t *CWindowPositionMgr::Find( char const *panelName )
+{
+ if ( !panelName )
+ return NULL;
+
+ int c = m_Panels.Count();
+ for ( int i = 0; i < c; ++i )
+ {
+ LoadInfo_t *info = &m_Panels[ i ];
+ if ( !Q_stricmp( info->m_Name.String(), panelName ) )
+ return info;
+ }
+ return NULL;
+}
+
+static void BufPrint( CUtlBuffer& buf, int level, char const *fmt, ... )
+{
+ char string[ 2048 ];
+ va_list argptr;
+ va_start( argptr, fmt );
+ _vsnprintf( string, sizeof( string ) - 1, fmt, argptr );
+ va_end( argptr );
+ string[ sizeof( string ) - 1 ] = 0;
+
+ while ( --level >= 0 )
+ {
+ buf.Printf( " " );
+ }
+ buf.Printf( "%s", string );
+}
+
+void CWindowPositionMgr::SavePositions( char const *filename, char const *key )
+{
+ CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER );
+ buf.Printf( "%s\n", key );
+ buf.Printf( "{\n" );
+
+ int sw, sh;
+ vgui::surface()->GetScreenSize( sw, sh );
+ float flOOW = (sw != 0.0f) ? 1.0f / (float)sw : 1.0f;
+ float flOOH = (sh != 0.0f) ? 1.0f / (float)sh : 1.0f;
+
+ int c = ToolWindow::GetToolWindowCount();
+
+ for ( int i = 0 ; i < c; ++i )
+ {
+ ToolWindow *tw = ToolWindow::GetToolWindow( i );
+ Assert( tw );
+ if ( !tw )
+ continue;
+
+ BufPrint( buf, 1, "toolwindow\n" );
+ BufPrint( buf, 1, "{\n" );
+
+ // Get panel bounds
+ int x, y, w, h;
+ tw->GetBounds( x, y, w, h );
+
+ float fx = (float)x * flOOW;
+ float fy = (float)y * flOOH;
+ float fw = (float)w * flOOW;
+ float fh = (float)h * flOOH;
+ BufPrint( buf, 2, "bounds \"%.10f %.10f %.10f %.10f\"\n", fx, fy, fw, fh );
+
+ // Now iterate the actual contained panels
+ PropertySheet *sheet = tw->GetPropertySheet();
+ Assert( sheet );
+ if ( sheet )
+ {
+ int subCount = sheet->GetNumPages();
+ Assert( subCount > 0 );
+ if ( subCount > 0 )
+ {
+ BufPrint( buf, 2, "windows\n" );
+ BufPrint( buf, 2, "{\n" );
+
+ for ( int s = 0 ; s < subCount; ++s )
+ {
+ Panel *subPanel = sheet->GetPage( s );
+ if ( !subPanel )
+ continue;
+
+ LoadInfo_t *info = Find( subPanel );
+ if ( !info )
+ continue;
+
+ BufPrint( buf, 3, "panel \"%s\"\n", info->m_Name.String() );
+ }
+
+ BufPrint( buf, 2, "}\n" );
+ }
+ }
+
+ BufPrint( buf, 1, "}\n" );
+ }
+
+ buf.Printf( "}\n" );
+
+ if ( g_pFullFileSystem->FileExists( filename, "DEFAULT_WRITE_PATH" ) &&
+ !g_pFullFileSystem->IsFileWritable( filename, "DEFAULT_WRITE_PATH" ) )
+ {
+ Warning( "IFM window layout file '%s' is read-only!!!\n", filename );
+ }
+
+ FileHandle_t h = g_pFullFileSystem->Open( filename, "wb", "DEFAULT_WRITE_PATH" );
+ if ( FILESYSTEM_INVALID_HANDLE != h )
+ {
+ g_pFullFileSystem->Write( buf.Base(), buf.TellPut(), h );
+ g_pFullFileSystem->Close( h );
+ }
+}
+
+bool CWindowPositionMgr::LoadPositions( char const *filename, vgui::Panel *parent, vgui::IToolWindowFactory *factory, char const *key, bool force /*=false*/ )
+{
+ bool success = false;
+
+ int sw, sh;
+ vgui::surface()->GetScreenSize( sw, sh );
+
+ KeyValues *kv = new KeyValues( key );
+ if ( kv->LoadFromFile( g_pFullFileSystem, filename, "GAME" ) )
+ {
+ // Walk through tools
+ for ( KeyValues *tw = kv->GetFirstSubKey(); tw != NULL; tw = tw->GetNextKey() )
+ {
+ if ( Q_stricmp( tw->GetName(), "toolwindow" ) )
+ continue;
+
+ // read bounds
+ float fx, fy, fw, fh;
+ int x, y, w, h;
+ char const *bounds = tw->GetString( "bounds", "" );
+ if ( !bounds || !bounds[ 0 ] )
+ continue;
+
+ if ( 4 != sscanf( bounds, "%f %f %f %f", &fx, &fy, &fw, &fh ) )
+ continue;
+
+ x = (int)( sw * fx + 0.5f );
+ y = (int)( sh * fy + 0.5f );
+ w = (int)( sw * fw + 0.5f );
+ h = (int)( sh * fh + 0.5f );
+
+ w = clamp( w, 0, sw );
+ h = clamp( h, 0, sh );
+
+ // Now load pages
+ KeyValues *pages = tw->FindKey( "windows", false );
+ if ( !pages )
+ continue;
+
+ ToolWindow *newTool = factory->InstanceToolWindow( parent, true, NULL, NULL, false );
+ newTool->SetBounds( x, y, w, h );
+
+ for ( KeyValues *page = pages->GetFirstSubKey(); page != NULL; page = page->GetNextKey() )
+ {
+ if ( Q_stricmp( page->GetName(), "panel" ) )
+ continue;
+
+ char const *pageName = page->GetString();
+ if ( !pageName || !pageName[ 0 ] )
+ continue;
+
+ LoadInfo_t *info = Find( pageName );
+ if ( !info )
+ continue;
+
+ newTool->AddPage( info->m_hPanel.Get(), info->m_Name.String(), info->m_bContextMenu );
+ success = true;
+ }
+
+ // If we didn't successfully create something, delete the tool
+ if ( !success )
+ {
+ delete newTool;
+ }
+ }
+ }
+ kv->deleteThis();
+
+ return success;
+}
+
+void CWindowPositionMgr::RegisterPanel( char const *saveName, Panel *panel, bool contextMenu )
+{
+ char const *panelName = panel->GetName();
+ if ( !panelName || !panelName[ 0 ] )
+ {
+ Warning( "CWindowPositionMgr::RegisterPanel: Panel has NULL or blank name!!!\n" );
+ return;
+ }
+
+ LoadInfo_t info;
+ info.m_hPanel = panel;
+ info.m_Name = saveName;
+ info.m_bLoaded = false;
+ info.m_bContextMenu = contextMenu;
+
+ m_Panels.AddToTail( info );
+}
+
+void CWindowPositionMgr::UnregisterPanel( vgui::Panel *panel )
+{
+ int c = m_Panels.Count();
+ for ( int i = c - 1; i >= 0; --i )
+ {
+ if ( m_Panels[ i ].m_hPanel.Get() != panel )
+ continue;
+
+ m_Panels.Remove( i );
+ break;
+ }
+}
diff --git a/tools/toolutils/tool_main.cpp b/tools/toolutils/tool_main.cpp
new file mode 100644
index 0000000..3895f22
--- /dev/null
+++ b/tools/toolutils/tool_main.cpp
@@ -0,0 +1,233 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================
+
+#include "tier1/utlvector.h"
+#include "tier1/convar.h"
+#include "icvar.h"
+#include "toolframework/itoolsystem.h"
+#include "toolframework/itooldictionary.h"
+#include "toolframework/ienginetool.h"
+#include "toolutils/enginetools_int.h"
+#include "ienginevgui.h"
+#include "icvar.h"
+#include "toolutils/vgui_tools.h"
+#include "mathlib/mathlib.h"
+#include "iregistry.h"
+#include "datamodel/idatamodel.h"
+#include "filesystem.h"
+#include "p4lib/ip4.h"
+#include "engine/ivdebugoverlay.h"
+#include "tier3/tier3dm.h"
+#include "datamodel/dmelementfactoryhelper.h"
+#include "dmserializers/idmserializers.h"
+
+//-----------------------------------------------------------------------------
+// Singleton interfaces
+//-----------------------------------------------------------------------------
+IEngineTool *enginetools = NULL;
+IEngineVGui *enginevgui = NULL;
+IFileSystem *g_pFileSystem = NULL;
+IVDebugOverlay *debugoverlay = NULL;
+
+
+//-----------------------------------------------------------------------------
+// Assumed to be implemented within the specific tool DLL
+//-----------------------------------------------------------------------------
+bool ConnectTools( CreateInterfaceFn factory );
+void CreateTools( );
+void DisconnectTools( );
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void VGUI_CreateToolRootPanel( void )
+{
+ // Just using PANEL_GAMEDLL in HL2 right now
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void VGUI_DestroyToolRootPanel( void )
+{
+}
+
+
+//-----------------------------------------------------------------------------
+// Global accessors for root tool panels
+//-----------------------------------------------------------------------------
+vgui::VPANEL VGui_GetToolRootPanel( void )
+{
+ vgui::VPANEL root = enginevgui->GetPanel( PANEL_GAMEDLL );
+ return root;
+}
+
+vgui::VPANEL VGui_GetRootPanel( void )
+{
+ vgui::VPANEL root = enginevgui->GetPanel( PANEL_ROOT );
+ return root;
+}
+
+
+//-----------------------------------------------------------------------------
+// Implementation of IToolDictionary
+//-----------------------------------------------------------------------------
+class CToolDictionary : public CTier3DmAppSystem< IToolDictionary >
+{
+ typedef CTier3DmAppSystem< IToolDictionary > BaseClass;
+
+public:
+ CToolDictionary();
+
+ // Inherited from IAppSystem
+ virtual bool Connect( CreateInterfaceFn factory );
+ virtual void Disconnect();
+ virtual void *QueryInterface( const char *pInterfaceName );
+ virtual InitReturnVal_t Init();
+ virtual void Shutdown();
+
+ // Inherited from IToolDictionary
+ virtual void CreateTools();
+ virtual int GetToolCount() const;
+ virtual IToolSystem *GetTool( int index );
+
+public:
+ void RegisterTool( IToolSystem *tool );
+
+private:
+ CUtlVector< IToolSystem * > m_Tools;
+};
+
+
+//-----------------------------------------------------------------------------
+// Singleton interface for tools
+//-----------------------------------------------------------------------------
+static CToolDictionary g_ToolDictionary;
+EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CToolDictionary, IToolDictionary, VTOOLDICTIONARY_INTERFACE_VERSION, g_ToolDictionary );
+
+
+//-----------------------------------------------------------------------------
+// Constructor
+//-----------------------------------------------------------------------------
+CToolDictionary::CToolDictionary()
+{
+}
+
+
+//-----------------------------------------------------------------------------
+// Inherited from IAppSystem
+//-----------------------------------------------------------------------------
+bool CToolDictionary::Connect( CreateInterfaceFn factory )
+{
+ if ( !BaseClass::Connect( factory ) )
+ return false;
+
+ // FIXME: This interface pointer is taken care of in tier2 + tier1
+ g_pFileSystem = g_pFullFileSystem;
+
+ enginevgui = ( IEngineVGui * )factory( VENGINE_VGUI_VERSION, NULL );
+ enginetools = ( IEngineTool * )factory( VENGINETOOL_INTERFACE_VERSION, NULL );
+ debugoverlay = ( IVDebugOverlay * )factory( VDEBUG_OVERLAY_INTERFACE_VERSION, NULL );
+
+ if ( !enginevgui || !debugoverlay || !g_pCVar || !enginetools || !g_pFileSystem )
+ return false;
+
+ if ( !VGui_Startup( factory ) )
+ return false;
+
+ return ConnectTools( factory );
+}
+
+void CToolDictionary::Disconnect()
+{
+ DisconnectTools();
+ enginevgui = NULL;
+ enginetools = NULL;
+ debugoverlay = NULL;
+ g_pFileSystem = NULL;
+
+ BaseClass::Disconnect( );
+}
+
+void *CToolDictionary::QueryInterface( const char *pInterfaceName )
+{
+ if ( !V_strcmp( pInterfaceName, VTOOLDICTIONARY_INTERFACE_VERSION ) )
+ return (IToolDictionary*)this;
+
+ return NULL;
+}
+
+InitReturnVal_t CToolDictionary::Init()
+{
+ InitReturnVal_t nRetVal = BaseClass::Init();
+ if ( nRetVal != INIT_OK )
+ return nRetVal;
+
+ MathLib_Init( 2.2f, 2.2f, 0.0f, 2.0f );
+
+ // Init registry
+ if ( !registry->Init( "Source\\Tools" ) )
+ {
+ Warning( "registry->Init failed\n" );
+ return INIT_FAILED;
+ }
+
+ // Re-enable this and VGui_Shutdown if we create root tool panels
+// VGui_PostInit();
+
+ return INIT_OK;
+}
+
+void CToolDictionary::Shutdown()
+{
+ // Re-enable this and VGui_PostInit if we create root tool panels
+ VGui_Shutdown();
+
+ registry->Shutdown();
+
+ BaseClass::Shutdown();
+}
+
+
+//-----------------------------------------------------------------------------
+// Implementation of IToolDictionary methods
+//-----------------------------------------------------------------------------
+void CToolDictionary::CreateTools()
+{
+ ::CreateTools( );
+}
+
+int CToolDictionary::GetToolCount() const
+{
+ return m_Tools.Count();
+}
+
+IToolSystem *CToolDictionary::GetTool( int index )
+{
+ if ( index < 0 || index >= m_Tools.Count() )
+ {
+ return NULL;
+ }
+ return m_Tools[ index ];
+}
+
+void CToolDictionary::RegisterTool( IToolSystem *tool )
+{
+ m_Tools.AddToTail( tool );
+}
+
+
+//-----------------------------------------------------------------------------
+// Allows tools to install themselves into the dictionary
+//-----------------------------------------------------------------------------
+void RegisterTool( IToolSystem *tool )
+{
+ g_ToolDictionary.RegisterTool( tool );
+}
+
+
diff --git a/tools/toolutils/tooleditmenubutton.cpp b/tools/toolutils/tooleditmenubutton.cpp
new file mode 100644
index 0000000..99e64a3
--- /dev/null
+++ b/tools/toolutils/tooleditmenubutton.cpp
@@ -0,0 +1,131 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Standard edit menu for tools
+//
+//=============================================================================
+
+#include "toolutils/tooleditmenubutton.h"
+#include "toolutils/toolmenubutton.h"
+#include "tier1/KeyValues.h"
+#include "toolutils/enginetools_int.h"
+#include "datamodel/idatamodel.h"
+#include "vgui_controls/menu.h"
+#include "vgui/ilocalize.h"
+#include "tier2/tier2.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+
+//-----------------------------------------------------------------------------
+//
+// The Edit menu
+//
+//-----------------------------------------------------------------------------
+class CToolEditMenuButton : public CToolMenuButton
+{
+ DECLARE_CLASS_SIMPLE( CToolEditMenuButton, CToolMenuButton );
+public:
+ CToolEditMenuButton( vgui::Panel *parent, const char *panelName, const char *text, vgui::Panel *pActionSignalTarget );
+ virtual void OnShowMenu( vgui::Menu *menu );
+};
+
+
+//-----------------------------------------------------------------------------
+// Global function to create the file menu
+//-----------------------------------------------------------------------------
+CToolMenuButton* CreateToolEditMenuButton( vgui::Panel *parent, const char *panelName, const char *text, vgui::Panel *pActionTarget )
+{
+ return new CToolEditMenuButton( parent, panelName, text, pActionTarget );
+}
+
+
+//-----------------------------------------------------------------------------
+// Constructor
+//-----------------------------------------------------------------------------
+CToolEditMenuButton::CToolEditMenuButton( vgui::Panel *parent, const char *panelName, const char *text, vgui::Panel *pActionSignalTarget )
+ : BaseClass( parent, panelName, text, pActionSignalTarget )
+{
+ AddMenuItem( "undo", "#ToolEditUndo", new KeyValues ( "Command", "command", "OnUndo" ), pActionSignalTarget, NULL, "undo" );
+ AddMenuItem( "redo", "#ToolEditRedo", new KeyValues ( "Command", "command", "OnRedo" ), pActionSignalTarget, NULL, "redo" );
+ AddSeparator();
+ AddMenuItem( "describe", "#ToolEditDescribeUndo", new KeyValues ( "Command", "command", "OnDescribeUndo" ), pActionSignalTarget);
+ AddMenuItem( "wipeundo", "#ToolEditWipeUndo", new KeyValues ( "Command", "command", "OnWipeUndo" ), pActionSignalTarget);
+ AddSeparator();
+ AddMenuItem( "editkeybindings", "#BxEditKeyBindings", new KeyValues( "OnEditKeyBindings" ), pActionSignalTarget, NULL, "editkeybindings" );
+
+ SetMenu(m_pMenu);
+}
+
+void CToolEditMenuButton::OnShowMenu( vgui::Menu *menu )
+{
+ BaseClass::OnShowMenu( menu );
+
+ // Update the menu
+ char sz[ 512 ];
+
+ int id;
+ id = m_Items.Find( "undo" );
+ if ( g_pDataModel->CanUndo() )
+ {
+ m_pMenu->SetItemEnabled( id, true );
+
+ wchar_t *fmt = g_pVGuiLocalize->Find( "ToolEditUndoStr" );
+ if ( fmt )
+ {
+ wchar_t desc[ 256 ];
+ g_pVGuiLocalize->ConvertANSIToUnicode( g_pDataModel->GetUndoDesc(), desc, sizeof( desc ) );
+
+ wchar_t buf[ 512 ];
+ g_pVGuiLocalize->ConstructString( buf, sizeof( buf ), fmt, 1, desc );
+
+ m_pMenu->UpdateMenuItem( id, buf, new KeyValues( "Command", "command", "OnUndo" ) );
+ }
+ else
+ {
+ m_pMenu->UpdateMenuItem( id, "#ToolEditUndo", new KeyValues( "Command", "command", "OnUndo" ) );
+ }
+ }
+ else
+ {
+ m_pMenu->SetItemEnabled( id, false );
+ m_pMenu->UpdateMenuItem( id, "#ToolEditUndo", new KeyValues( "Command", "command", "OnUndo" ) );
+ }
+
+ id = m_Items.Find( "redo" );
+ if ( g_pDataModel->CanRedo() )
+ {
+ m_pMenu->SetItemEnabled( id, true );
+
+ wchar_t *fmt = g_pVGuiLocalize->Find( "ToolEditRedoStr" );
+ if ( fmt )
+ {
+ wchar_t desc[ 256 ];
+ g_pVGuiLocalize->ConvertANSIToUnicode( g_pDataModel->GetRedoDesc(), desc, sizeof( desc ) );
+
+ wchar_t buf[ 512 ];
+ g_pVGuiLocalize->ConstructString( buf, sizeof( buf ), fmt, 1, desc );
+
+ m_pMenu->UpdateMenuItem( id, buf, new KeyValues( "Command", "command", "OnRedo" ) );
+ }
+ else
+ {
+ m_pMenu->UpdateMenuItem( id, sz, new KeyValues( "Command", "command", "OnRedo" ) );
+ }
+ }
+ else
+ {
+ m_pMenu->SetItemEnabled( id, false );
+ m_pMenu->UpdateMenuItem( id, "#ToolEditRedo", new KeyValues( "Command", "command", "OnRedo" ) );
+ }
+
+ id = m_Items.Find( "describe" );
+ if ( g_pDataModel->CanUndo() )
+ {
+ m_pMenu->SetItemEnabled( id, true );
+ }
+ else
+ {
+ m_pMenu->SetItemEnabled( id, false );
+ }
+}
diff --git a/tools/toolutils/toolmenubar.cpp b/tools/toolutils/toolmenubar.cpp
new file mode 100644
index 0000000..fb02a35
--- /dev/null
+++ b/tools/toolutils/toolmenubar.cpp
@@ -0,0 +1,132 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Core Movie Maker UI API
+//
+//=============================================================================
+
+#include "toolutils/toolmenubar.h"
+#include "vgui_controls/Label.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+
+using namespace vgui;
+
+
+//-----------------------------------------------------------------------------
+//
+// Version that only has tool name and info
+//
+//-----------------------------------------------------------------------------
+
+
+//-----------------------------------------------------------------------------
+// Constructor
+//-----------------------------------------------------------------------------
+CToolMenuBar::CToolMenuBar( CBaseToolSystem *pParent, const char *pPanelName ) :
+ BaseClass( (Panel *)pParent, pPanelName ),
+ m_pToolSystem( pParent )
+{
+ m_pInfo = new Label( this, "Info", "" );
+ m_pToolName = new Label( this, "ToolName", "" );
+}
+
+CBaseToolSystem *CToolMenuBar::GetToolSystem()
+{
+ return m_pToolSystem;
+}
+
+//-----------------------------------------------------------------------------
+// Sets the tool bar's name
+//-----------------------------------------------------------------------------
+void CToolMenuBar::SetToolName( const char *pName )
+{
+ m_pToolName->SetText( pName );
+ InvalidateLayout();
+}
+
+
+//-----------------------------------------------------------------------------
+// Sets the tool bar info
+//-----------------------------------------------------------------------------
+void CToolMenuBar::SetInfo( const char *pInfo )
+{
+ m_pInfo->SetText( pInfo );
+ InvalidateLayout();
+}
+
+
+//-----------------------------------------------------------------------------
+// Lays out the menu bar
+//-----------------------------------------------------------------------------
+void CToolMenuBar::PerformLayout()
+{
+ BaseClass::PerformLayout();
+
+ int w, h;
+ GetSize( w, h );
+
+ int cw, ch;
+ m_pInfo->GetContentSize( cw, ch );
+
+ int right = w - cw - 20;
+ m_pInfo->SetBounds( right, 0, cw, h );
+
+ m_pToolName->GetContentSize( cw, ch );
+ m_pToolName->SetBounds( right - cw - 5, 0, cw, h );
+}
+
+
+//-----------------------------------------------------------------------------
+//
+// Version that only has tool name, info, and file name
+//
+//-----------------------------------------------------------------------------
+
+
+//-----------------------------------------------------------------------------
+// Constructor
+//-----------------------------------------------------------------------------
+CToolFileMenuBar::CToolFileMenuBar( CBaseToolSystem *parent, const char *panelName ) :
+ BaseClass( parent, panelName )
+{
+ m_pFileName = new Label( this, "FileName", "" );
+}
+
+
+void CToolFileMenuBar::SetFileName( char const *name )
+{
+ m_pFileName->SetText( name );
+ InvalidateLayout();
+}
+
+
+//-----------------------------------------------------------------------------
+// Performs layout
+//-----------------------------------------------------------------------------
+void CToolFileMenuBar::PerformLayout()
+{
+ BaseClass::PerformLayout();
+
+ int w, h;
+ GetSize( w, h );
+
+ int cw, ch;
+ m_pInfo->GetContentSize( cw, ch );
+
+ int right = w - cw - 20;
+
+ m_pToolName->GetContentSize( cw, ch );
+
+ int barx, bary;
+ GetContentSize( barx, bary );
+
+ int faredge = right - cw - 5- 2;
+ int nearedge = barx + 2;
+
+ int mid = ( nearedge + faredge ) * 0.5f;
+
+ m_pFileName->GetContentSize( cw, ch );
+ m_pFileName->SetBounds( mid - cw * 0.5f, 0, cw, h );
+}
diff --git a/tools/toolutils/toolutils.vpc b/tools/toolutils/toolutils.vpc
new file mode 100644
index 0000000..6d692cb
--- /dev/null
+++ b/tools/toolutils/toolutils.vpc
@@ -0,0 +1,54 @@
+//-----------------------------------------------------------------------------
+// TOOLUTILS.VPC
+//
+// Project Script
+//-----------------------------------------------------------------------------
+
+$Macro SRCDIR "..\.."
+$Include "$SRCDIR\vpc_scripts\source_lib_base.vpc"
+
+$Project "Toolutils"
+{
+ $Folder "Source Files"
+ {
+ $File "attributeelementchoicelist.cpp"
+ $File "basepropertiescontainer.cpp"
+ $File "basestatusbar.cpp"
+ $File "BaseToolSystem.cpp"
+ $File "ConsolePage.cpp"
+ $File "miniviewport.cpp"
+ $File "recentfilelist.cpp"
+ $File "savewindowpositions.cpp"
+ $File "tool_main.cpp"
+ $File "tooleditmenubutton.cpp"
+ $File "ToolFileMenuButton.cpp"
+ $File "ToolHelpMenuButton.cpp"
+ $File "toolmenubar.cpp"
+ $File "ToolMenuButton.cpp"
+ $File "ToolSwitchMenuButton.cpp"
+ $File "ToolUI.cpp"
+ $File "vgui_tools.cpp"
+ }
+
+ $Folder "Header Files"
+ {
+ $File "$SRCDIR\public\toolutils\AttributeElementChoiceList.h"
+ $File "$SRCDIR\public\toolutils\basepropertiescontainer.h"
+ $File "$SRCDIR\public\toolutils\basestatusbar.h"
+ $File "$SRCDIR\public\toolutils\BaseToolSystem.h"
+ $File "$SRCDIR\public\toolutils\DmeMdlRenderable.h"
+ $File "$SRCDIR\public\toolutils\DmeRenderable.h"
+ $File "$SRCDIR\public\toolutils\enginetools_int.h"
+ $File "$SRCDIR\public\toolutils\miniviewport.h"
+ $File "$SRCDIR\public\toolutils\recentfilelist.h"
+ $File "$SRCDIR\public\toolutils\savewindowpositions.h"
+ $File "$SRCDIR\public\toolutils\ToolEditMenuButton.h"
+ $File "$SRCDIR\public\toolutils\ToolFileMenuButton.h"
+ $File "$SRCDIR\public\toolutils\ToolHelpMenuButton.h"
+ $File "$SRCDIR\public\toolutils\toolmenubar.h"
+ $File "$SRCDIR\public\toolutils\ToolMenuButton.h"
+ $File "$SRCDIR\public\toolutils\ToolSwitchMenuButton.h"
+ $File "ToolUI.h"
+ $File "$SRCDIR\public\toolutils\vgui_tools.h"
+ }
+}
diff --git a/tools/toolutils/vgui_tools.cpp b/tools/toolutils/vgui_tools.cpp
new file mode 100644
index 0000000..f60c1e5
--- /dev/null
+++ b/tools/toolutils/vgui_tools.cpp
@@ -0,0 +1,67 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================
+
+#include "toolutils/vgui_tools.h"
+#include "ienginevgui.h"
+#include <vgui/ISurface.h>
+#include <vgui/IVGui.h>
+#include <vgui/IInput.h>
+#include "tier0/vprof.h"
+#include <vgui_controls/Panel.h>
+#include <KeyValues.h>
+#include <dme_controls/dmeControls.h>
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+using namespace vgui;
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : appSystemFactory -
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool VGui_Startup( CreateInterfaceFn appSystemFactory )
+{
+ // All of the various tools .dlls expose GetVGuiControlsModuleName() to us to make sure we don't have communication across .dlls
+ if ( !vgui::VGui_InitDmeInterfacesList( GetVGuiControlsModuleName(), &appSystemFactory, 1 ) )
+ return false;
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool VGui_PostInit()
+{
+ // Create any root panels for .dll
+ VGUI_CreateToolRootPanel();
+
+ // Make sure we have a panel
+ VPANEL root = VGui_GetToolRootPanel();
+ if ( !root )
+ {
+ return false;
+ }
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+//-----------------------------------------------------------------------------
+void VGui_Shutdown()
+{
+ VGUI_DestroyToolRootPanel();
+
+ // Make sure anything "marked for deletion"
+ // actually gets deleted before this dll goes away
+ vgui::ivgui()->RunFrame();
+}