source-engine/hammer/faceeditsheet.cpp

335 lines
9.0 KiB
C++
Raw Permalink Normal View History

2020-04-23 00:56:21 +08:00
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: A page in a tabbed dialog that allows the editing of face properties.
//
//=============================================================================//
#include <stdafx.h>
#include "hammer.h"
#include "MainFrm.h"
#include "GlobalFunctions.h"
#include "FaceEditSheet.h"
#include "MapSolid.h"
#include "MapFace.h"
#include "MapDisp.h"
#include "ToolManager.h"
#include "mapdoc.h"
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
IMPLEMENT_DYNAMIC( CFaceEditSheet, CPropertySheet )
BEGIN_MESSAGE_MAP( CFaceEditSheet, CPropertySheet )
//{{AFX_MSG_MAP( CFaceEdtiSheet )
ON_WM_CLOSE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
CFaceEditSheet::CFaceEditSheet( LPCTSTR pszCaption, CWnd *pParentWnd, UINT iSelectPage ) :
CPropertySheet( pszCaption, pParentWnd, iSelectPage )
{
m_ClickMode = -1;
m_bEnableUpdate = true;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
CFaceEditSheet::~CFaceEditSheet()
{
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void CFaceEditSheet::SetupPages( void )
{
//
// add pages to sheet
//
AddPage( &m_MaterialPage );
AddPage( &m_DispPage );
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void CFaceEditSheet::Setup( void )
{
SetupPages();
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
BOOL CFaceEditSheet::Create( CWnd *pParentWnd )
{
if( !CPropertySheet::Create( pParentWnd ) )
return FALSE;
//
// touch all pages so they create the hWnd for each
//
SetActivePage( &m_DispPage );
SetActivePage( &m_MaterialPage );
//
// initialize the pages
//
m_MaterialPage.Init();
// m_DispPage.Init();
return TRUE;
}
//-----------------------------------------------------------------------------
// Purpose: Disables window updates when adding a large number of faces to the
// dialog at once. When updates are re-enabled, the window is updated.
// Input : bEnable - true to enable updates, false to disable them.
//-----------------------------------------------------------------------------
void CFaceEditSheet::EnableUpdate( bool bEnable )
{
bool bOld = m_bEnableUpdate;
m_bEnableUpdate = bEnable;
if( ( bEnable ) && ( !bOld ) )
{
m_MaterialPage.UpdateDialogData();
}
}
//-----------------------------------------------------------------------------
// Purpose: Called when a new material is detected.
//-----------------------------------------------------------------------------
void CFaceEditSheet::NotifyNewMaterial( IEditorTexture *pTex )
{
m_MaterialPage.NotifyNewMaterial( pTex );
}
//-----------------------------------------------------------------------------
// Purpose: Clear the face list.
//-----------------------------------------------------------------------------
void CFaceEditSheet::ClearFaceList( void )
{
//
// reset selection state of all faces currently in the list
//
for( int i = 0; i < m_Faces.Count(); i++ )
{
m_Faces[i].pMapFace->SetSelectionState( SELECT_NONE );
EditDispHandle_t handle = m_Faces[i].pMapFace->GetDisp();
CMapDisp *pDisp = EditDispMgr()->GetDisp( handle );
if( pDisp )
{
pDisp->ResetTexelHitIndex();
}
}
//
// reset the list
//
m_Faces.Purge();
CMapDoc *pDoc = CMapDoc::GetActiveMapDoc();
if ( pDoc )
pDoc->UpdateAllViews( MAPVIEW_UPDATE_ONLY_3D );
}
void CFaceEditSheet::ClearFaceListByMapDoc( CMapDoc *pDoc )
{
// Remove any faces from our list that came from this CMapDoc.
for( int i = 0; i < m_Faces.Count(); i++ )
{
if ( m_Faces[i].pMapDoc == pDoc )
{
m_Faces.Remove( i );
--i;
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Search for the given face in the face selection list. If found,
// return the index of the face in the list. Otherwise, return -1.
//-----------------------------------------------------------------------------
int CFaceEditSheet::FindFaceInList( CMapFace *pFace )
{
for( int i = 0; i < m_Faces.Count(); i++ )
{
if( m_Faces[i].pMapFace == pFace )
return i;
}
return -1;
}
//-----------------------------------------------------------------------------
// It is really lame that I have to have material/displacement specific code
// here! It is unfortunately necessary - see CMapDoc (SelectFace). ClickFace
// not only specifies face selection (which it should do only!!!), but also
// specifies the "mode" (material specific) of the click -- LAME!!!! This will
// be a problem spot if/when we make face selection general. cab
//-----------------------------------------------------------------------------
void CFaceEditSheet::ClickFace( CMapSolid *pSolid, int faceIndex, int cmd, int clickMode )
{
//
// set the click mode (either to new mode or previously used)
//
if( clickMode == -1 )
{
clickMode = m_ClickMode;
}
//
// clear the face list?
//
if( cmd & cfClear )
{
ClearFaceList();
}
cmd &= ~cfClear;
//
// check for valid solid
//
if( !pSolid )
return;
//
// check for face in list, -1 from FindFaceInList indicates face not found
//
CMapFace *pFace = pSolid->GetFace( faceIndex );
int selectIndex = FindFaceInList( pFace );
bool bFoundInList = ( selectIndex != -1 );
//
// handle the face list selection
//
if( ( clickMode == ModeSelect ) || ( clickMode == ModeLiftSelect ) )
{
// toggle selection if necessary
if( cmd == cfToggle )
{
cmd = bFoundInList ? cfUnselect : cfSelect;
}
CMapDoc *pDoc = CMapDoc::GetActiveMapDoc();
if( ( cmd == cfSelect ) && !bFoundInList )
{
// add face to list
StoredFace_t sf;
sf.pMapDoc = pDoc;
sf.pMapFace = pFace;
sf.pMapSolid = pSolid;
m_Faces.AddToTail( sf );
pFace->SetSelectionState( SELECT_NORMAL );
}
else if( ( cmd == cfUnselect ) && bFoundInList )
{
// remove from list
m_Faces.Remove( selectIndex );
pFace->SetSelectionState( SELECT_NONE );
EditDispHandle_t handle = pFace->GetDisp();
CMapDisp *pDisp = EditDispMgr()->GetDisp( handle );
if( pDisp )
{
pDisp->ResetTexelHitIndex();
}
}
if ( pDoc )
pDoc->UpdateAllViews( MAPVIEW_UPDATE_ONLY_3D );
}
//
// pass to children (pages)
//
m_MaterialPage.ClickFace( pSolid, faceIndex, cmd, clickMode );
m_DispPage.ClickFace( pSolid, faceIndex, cmd, clickMode );
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void CFaceEditSheet::SetVisibility( bool bVisible )
{
if( bVisible )
{
ShowWindow( SW_SHOW );
SetActivePage( &m_DispPage ); // gross hack to active the default button!!!!
SetActivePage( &m_MaterialPage );
m_MaterialPage.UpdateDialogData();
m_DispPage.UpdateDialogData();
}
else
{
ShowWindow( SW_HIDE );
}
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
BOOL CFaceEditSheet::PreTranslateMessage( MSG *pMsg )
{
HACCEL hAccel = GetMainWnd()->GetAccelTable();
if( !(hAccel && ::TranslateAccelerator( GetMainWnd()->m_hWnd, hAccel, pMsg ) ) )
{
if (IsDialogMessage(pMsg))
{
return(TRUE);
}
return CWnd::PreTranslateMessage( pMsg );
}
return TRUE;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void CFaceEditSheet::OnClose( void )
{
// make sure all dialogs are closed upon exit!!
m_DispPage.CloseAllDialogs();
m_DispPage.ResetForceShows();
// toggle the face edit sheet and texture bar!
GetMainWnd()->ShowFaceEditSheetOrTextureBar( false );
// Force the material page to the original tool. This will clear out all
// dialogs
m_MaterialPage.SetMaterialPageTool( CFaceEditMaterialPage::MATERIALPAGETOOL_MATERIAL );
// set the tool pointer as default tool
ToolManager()->SetTool(TOOL_POINTER);
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void CFaceEditSheet::CloseAllPageDialogs( void )
{
// Make sure all dialogs are closed upon exit!
m_DispPage.CloseAllDialogs();
m_DispPage.ResetForceShows();
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void CFaceEditSheet::UpdateControls( void )
{
// Currently this is only needed for the material page.
m_MaterialPage.UpdateDialogData();
}