335 lines
9.0 KiB
C++
335 lines
9.0 KiB
C++
|
//========= 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();
|
||
|
}
|