source-engine/hammer/ToolManager.cpp

306 lines
7.9 KiB
C++
Raw Permalink Normal View History

2020-04-22 16:56:21 +00:00
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// TODO: add an autoregistration system for tools a la LINK_ENTITY_TO_CLASS
//=============================================================================//
#include "stdafx.h"
#include "MapDoc.h"
#include "MainFrm.h"
#include "MapView2D.h" // FIXME: for MapView2D::updTool
#include "ToolAxisHandle.h"
#include "ToolDecal.h"
#include "ToolDisplace.h"
#include "ToolManager.h"
#include "ToolMagnify.h"
#include "ToolMaterial.h"
#include "ToolPickFace.h"
#include "ToolPickAngles.h"
#include "ToolPickEntity.h"
#include "ToolPointHandle.h"
#include "ToolSphere.h"
#include "ToolSweptHull.h"
#include "ToolBlock.h"
#include "ToolCamera.h"
#include "ToolClipper.h"
#include "ToolCordon.h"
#include "ToolEntity.h"
#include "ToolMorph.h"
#include "ToolOverlay.h"
#include "ToolSelection.h"
#include "ToolMagnify.h"
#include "ToolMaterial.h"
#include "ChunkFile.h"
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
static CToolManager s_DummyToolmanager;
CToolManager* ToolManager()
{
CMapDoc *pDoc = CMapDoc::GetActiveMapDoc();
if ( pDoc )
return pDoc->GetTools();
return &s_DummyToolmanager;
}
//-----------------------------------------------------------------------------
// Purpose: Prepares the tool manager for use.
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CToolManager::Init( CMapDoc *pDocument )
{
// add default tools
//
// Create the tools that are held by the tool manager and add them
// to the internal tools list.
//
RemoveAllTools();
m_pDocument = pDocument;
AddTool( new CToolDisplace );
AddTool( new CToolMagnify );
AddTool( new CToolDecal );
AddTool( new CToolMaterial );
AddTool( new CToolAxisHandle );
AddTool( new CToolPointHandle );
AddTool( new CToolSphere );
AddTool( new CToolPickAngles );
AddTool( new CToolPickEntity );
AddTool( new CToolPickFace );
AddTool( new CToolSweptPlayerHull );
AddTool( new Selection3D );
AddTool( new CToolBlock );
AddTool( new CToolEntity );
AddTool( new Camera3D );
AddTool( new Morph3D );
AddTool( new Clipper3D );
AddTool( new Cordon3D );
AddTool( new CToolOverlay );
return true;
}
//-----------------------------------------------------------------------------
// Purpose: Shuts down the tool manager - called on app exit.
//-----------------------------------------------------------------------------
void CToolManager::Shutdown()
{
m_pActiveTool = NULL;
m_pDocument = NULL;
RemoveAllTools();
}
//-----------------------------------------------------------------------------
// Purpose: Constructor. Allocates the tools.
//-----------------------------------------------------------------------------
CToolManager::CToolManager()
{
m_pActiveTool = NULL;
m_pDocument = NULL;
}
//-----------------------------------------------------------------------------
// Purpose: Destructor. Deletes the tools.
//-----------------------------------------------------------------------------
CToolManager::~CToolManager()
{
Shutdown();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CToolManager::AddTool(CBaseTool *pTool)
{
if ( GetToolForID( pTool->GetToolID() ) )
{
Assert( !pTool );
Msg("CToolManager::AddTool: Tool %i already registered.\n", pTool->GetToolID());
return;
}
pTool->Init( m_pDocument );
m_Tools.AddToTail(pTool);
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CBaseTool *CToolManager::GetActiveTool()
{
return m_pActiveTool;
}
//-----------------------------------------------------------------------------
// Purpose: Returns a tool pointer for a given tool ID, NULL if there is no
// corresponding tool.
//-----------------------------------------------------------------------------
CBaseTool *CToolManager::GetToolForID(ToolID_t eToolID)
{
int nToolCount = GetToolCount();
for (int i = 0; i < nToolCount; i++)
{
CBaseTool *pTool = GetTool(i);
if (pTool->GetToolID() == eToolID)
{
return pTool;
}
}
return NULL;
}
//-----------------------------------------------------------------------------
// Purpose: Returns the ID of the active tool.
//-----------------------------------------------------------------------------
ToolID_t CToolManager::GetActiveToolID()
{
if ( m_pActiveTool )
return m_pActiveTool->GetToolID();
else
return TOOL_NONE;
}
//-----------------------------------------------------------------------------
// Purpose: Pushes a new tool onto the tool stack and activates it. The active
// tool will be deactivated and reactivated when PopTool is called.
//-----------------------------------------------------------------------------
void CToolManager::PushTool(ToolID_t eToolID)
{
//
// Add the new tool to the top of the tool stack.
//
if (eToolID != GetActiveToolID())
{
m_ToolIDStack.AddToHead(GetActiveToolID());
}
SetTool(eToolID);
}
//-----------------------------------------------------------------------------
// Purpose: Restores the active tool to what it was when PushTool was called.
// If the stack is underflowed somehow, the pointer is restored.
//-----------------------------------------------------------------------------
void CToolManager::PopTool()
{
int nCount = m_ToolIDStack.Count();
if (nCount > 0)
{
ToolID_t eNewTool = m_ToolIDStack.Element(0);
m_ToolIDStack.Remove(0);
SetTool(eNewTool);
}
}
//-----------------------------------------------------------------------------
// Purpose: Sets the current active tool by ID.
// Input : iTool - ID of the tool to activate.
//-----------------------------------------------------------------------------
void CToolManager::SetTool(ToolID_t eNewTool)
{
CBaseTool *pNewTool = GetToolForID(eNewTool);
CBaseTool *pOldTool = m_pActiveTool;
// Check to see that we can deactive the current tool
if ( pOldTool && (pOldTool != pNewTool) )
{
// Deactivate the current tool unless we are just 'reactivating' it.
if( !pOldTool->CanDeactivate() )
return;
}
// set active tool to new tool already so old tool can peek whats coming next
m_pActiveTool = pNewTool;
// deactivate the old tool if different.
if ( pOldTool && (pOldTool != pNewTool) )
{
pOldTool->Deactivate();
}
// always activate the new tool
if ( pNewTool )
{
pNewTool->Activate();
}
// FIXME: When we start up, we end up here before the main window is created because
// CFaceEditDispPage::OnSetActive() calls SetTool(TOOL_FACEEDIT_DISP). This
// behavior is rather nonsensical during startup.
CMainFrame *pwndMain = GetMainWnd();
if (pwndMain != NULL)
{
pwndMain->m_ObjectBar.UpdateListForTool(eNewTool);
}
if ( m_pDocument )
m_pDocument->UpdateAllViews( MAPVIEW_UPDATE_TOOL );
}
ChunkFileResult_t CToolManager::SaveVMF(CChunkFile *pFile, CSaveInfo *pSaveInfo)
{
for (int i=0;i<m_Tools.Count(); i++)
{
if ( m_Tools[i]->GetVMFChunkName() != NULL )
{
m_Tools[i]->SaveVMF( pFile, pSaveInfo );
}
}
return ChunkFile_Ok;
}
ChunkFileResult_t CToolManager::LoadCallback(CChunkFile *pFile, CBaseTool *pTool)
{
return pTool->LoadVMF( pFile );
}
void CToolManager::AddToolHandlers( CChunkHandlerMap *pHandlersMap )
{
for (int i=0;i<m_Tools.Count(); i++)
{
if ( m_Tools[i]->GetVMFChunkName() != NULL )
{
pHandlersMap->AddHandler( m_Tools[i]->GetVMFChunkName(), (ChunkHandler_t)LoadCallback, m_Tools[i] );
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Removes all the document-created tools from the tools list.
//-----------------------------------------------------------------------------
void CToolManager::RemoveAllTools()
{
m_pActiveTool = NULL;
m_Tools.PurgeAndDeleteElements();
m_ToolIDStack.RemoveAll();
}