|
|
//====== Copyright � 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#include "dme_controls/AssetBuilder.h"
#include "dme_controls/DmePanel.h"
#include "dme_controls/dmecontrols_utils.h"
#include "tier1/keyvalues.h"
#include "vgui_controls/ListPanel.h"
#include "vgui_controls/MenuButton.h"
#include "vgui_controls/TextEntry.h"
#include "vgui_controls/MessageBox.h"
#include "vgui_controls/ComboBox.h"
#include "vgui_controls/FileOpenDialog.h"
#include "vgui_controls/Splitter.h"
#include "vgui_controls/FileOpenStateMachine.h"
#include "vgui_controls/PropertySheet.h"
#include "vgui_controls/PropertyPage.h"
#include "vgui/ischeme.h"
#include "vgui/ivgui.h"
#include "vgui/isurface.h"
#include "tier1/tier1.h"
#include "movieobjects/dmemakefile.h"
#include "matsys_controls/picker.h"
#include "tier2/fileutils.h"
#include "vgui/keycode.h"
#include "filesystem.h"
#include "movieobjects/idmemakefileutils.h"
#include "tier3/tier3.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
using namespace vgui;
#define ASSET_FILE_FORMAT "model"
//-----------------------------------------------------------------------------
// Compile status bar
//-----------------------------------------------------------------------------
class CCompileStatusBar : public vgui::EditablePanel { DECLARE_CLASS_SIMPLE( CCompileStatusBar, EditablePanel );
public: enum CompileStatus_t { NOT_COMPILING, CURRENTLY_COMPILING, COMPILATION_FAILED, COMPILATION_SUCCESSFUL };
CCompileStatusBar( vgui::Panel *pParent, const char *pPanelName ); virtual ~CCompileStatusBar();
virtual void PaintBackground();
void SetStatus( CompileStatus_t status, const char *pMessage );
private: vgui::Label *m_pStatus; CompileStatus_t m_Status; int m_CompilingId; };
//-----------------------------------------------------------------------------
// Constructor, destructor
//-----------------------------------------------------------------------------
CCompileStatusBar::CCompileStatusBar( vgui::Panel *pParent, const char *pPanelName ) : BaseClass( pParent, pPanelName ) { m_pStatus = new vgui::Label( this, "StatusLabel", "" ); m_pStatus->SetAutoResize( PIN_TOPLEFT, AUTORESIZE_DOWNANDRIGHT, 0, 0, 0, 0 ); m_pStatus->SetContentAlignment( vgui::Label::a_center ); m_pStatus->SetTextColorState( vgui::Label::CS_BRIGHT ); SetStatus( NOT_COMPILING, "" ); SetPaintBackgroundEnabled( true ); m_CompilingId = vgui::surface()->DrawGetTextureId( "vgui/progressbar" ); if ( m_CompilingId == -1 ) // we didn't find it, so create a new one
{ m_CompilingId = vgui::surface()->CreateNewTextureID(); } vgui::surface()->DrawSetTextureFile( m_CompilingId, "vgui/progressbar", true, false ); }
CCompileStatusBar::~CCompileStatusBar() { }
//-----------------------------------------------------------------------------
// Sets compile status
//-----------------------------------------------------------------------------
void CCompileStatusBar::SetStatus( CompileStatus_t status, const char *pMessage ) { m_Status = status; m_pStatus->SetText( pMessage ); }
void CCompileStatusBar::PaintBackground() { int w, h; GetSize( w, h );
switch( m_Status ) { case NOT_COMPILING: break;
case COMPILATION_FAILED: vgui::surface()->DrawSetColor( 255, 0, 0, 255 ); vgui::surface()->DrawFilledRect( 0, 0, w, h ); break;
case COMPILATION_SUCCESSFUL: vgui::surface()->DrawSetColor( 0, 255, 0, 255 ); vgui::surface()->DrawFilledRect( 0, 0, w, h ); break;
case CURRENTLY_COMPILING: { float du = Plat_FloatTime() / 5.0f; du -= (int)du; du = 1.0f - du;
Vertex_t verts[4]; verts[0].Init( Vector2D( 0.0f, 0.0f ), Vector2D( du, 0.0f ) ); verts[1].Init( Vector2D( w, 0.0f ), Vector2D( 1.0f + du, 0.0f ) ); verts[2].Init( Vector2D( w, h ), Vector2D( 1.0f + du, 1.0f ) ); verts[3].Init( Vector2D( 0.0f, h ), Vector2D( du, 1.0f ) );
vgui::surface()->DrawSetColor( 255, 255, 255, 255 ); vgui::surface()->DrawSetTexture( m_CompilingId ); vgui::surface()->DrawTexturedPolygon( 4, verts ); } break; } }
//-----------------------------------------------------------------------------
//
// Asset Builder
//
//-----------------------------------------------------------------------------
IMPLEMENT_DMEPANEL_FACTORY( CAssetBuilder, DmeMakefile, "DmeMakeFileDefault", "MakeFile Editor", true );
//-----------------------------------------------------------------------------
// Static data
//-----------------------------------------------------------------------------
static PickerList_t s_AssetTypes; static bool s_bAssetTypeListBuilt = false;
//-----------------------------------------------------------------------------
// Builds the list of asset types
//-----------------------------------------------------------------------------
void BuildAssetTypeList( ) { if ( s_bAssetTypeListBuilt ) return;
s_bAssetTypeListBuilt = true;
CDisableUndoScopeGuard guard;
int hFactory = g_pDataModel->GetFirstFactory(); while ( g_pDataModel->IsValidFactory( hFactory ) ) { // Add all DmeElements that inherit from DmeMakefile
const char *pFactoryName = g_pDataModel->GetFactoryName( hFactory ); CDmElement *pElement = GetElement< CDmElement >( g_pDataModel->CreateElement( pFactoryName, "temp", DMFILEID_INVALID ) ); CDmeMakefile *pMakeFile = CastElement<CDmeMakefile>( pElement ); if ( pMakeFile && pMakeFile->GetMakefileType() ) { int i = s_AssetTypes.AddToTail(); s_AssetTypes[i].m_pChoiceString = pMakeFile->GetMakefileType()->m_pHumanReadableName; s_AssetTypes[i].m_pChoiceValue = pFactoryName; } DestroyElement( pElement );
hFactory = g_pDataModel->GetNextFactory( hFactory ); } }
//-----------------------------------------------------------------------------
// Builds the list of asset types
//-----------------------------------------------------------------------------
static PickerList_t &BuildAssetSubTypeList( const char **ppSubTypes, PickerList_t &pickerList ) { if ( !ppSubTypes ) return s_AssetTypes;
pickerList.RemoveAll();
CDisableUndoScopeGuard guard;
int nCount = s_AssetTypes.Count(); for ( int i = 0; i < nCount; ++i ) { // Add all DmeElements that inherit from DmeMakefile
CDmElement *pElement = GetElement< CDmElement >( g_pDataModel->CreateElement( s_AssetTypes[i].m_pChoiceValue, "temp", DMFILEID_INVALID ) ); CDmeMakefile *pMakeFile = CastElement< CDmeMakefile >( pElement );
for ( int j = 0; ppSubTypes[j]; ++j ) { if ( !pElement->IsA( ppSubTypes[j] ) ) continue;
int k = pickerList.AddToTail(); pickerList[k].m_pChoiceString = pMakeFile->GetMakefileType()->m_pHumanReadableName; pickerList[k].m_pChoiceValue = s_AssetTypes[i].m_pChoiceValue; break; } DestroyElement( pElement ); }
return pickerList; }
//-----------------------------------------------------------------------------
// Shows the overwrite existing file dialog
//-----------------------------------------------------------------------------
static void OverwriteFileDialog( vgui::Panel *pActionTarget, const char *pFileName, KeyValues *pOkCommand ) { if ( !g_pFullFileSystem->FileExists( pFileName ) ) { pActionTarget->PostMessage( pActionTarget->GetVPanel(), pOkCommand ); return; }
char pBuf[1024]; Q_snprintf( pBuf, sizeof(pBuf), "File already exists. Overwrite it?\n\n\"%s\"\n", pFileName ); vgui::MessageBox *pMessageBox = new vgui::MessageBox( "Overwrite Existing File?", pBuf, pActionTarget ); pMessageBox->AddActionSignalTarget( pActionTarget ); pMessageBox->SetOKButtonVisible( true ); pMessageBox->SetOKButtonText( "Yes" ); pMessageBox->SetCancelButtonVisible( true ); pMessageBox->SetCancelButtonText( "No" ); pMessageBox->SetCloseButtonVisible( false ); pMessageBox->SetCommand( pOkCommand ); pMessageBox->DoModal(); }
//-----------------------------------------------------------------------------
// Utility to load a makefile
//-----------------------------------------------------------------------------
static CDmeMakefile *ReadMakefile( const char *pFileName, CDmElement **ppRoot = NULL ) { if ( ppRoot ) { *ppRoot = NULL; }
CDmElement *pRoot; DmFileId_t fileid = g_pDataModel->RestoreFromFile( pFileName, NULL, NULL, &pRoot, CR_DELETE_OLD ); if ( fileid == DMFILEID_INVALID || !pRoot ) { Warning( "Unable to read makefile \"%s\"!\n", pFileName ); return NULL; }
CDmeMakefile *pMakeFile = CastElement< CDmeMakefile >( pRoot ); if ( !pMakeFile ) { CDmElement *pElement = CastElement< CDmElement >( pRoot ); pMakeFile = pElement->GetValueElement< CDmeMakefile >( "makefile" ); if ( !pMakeFile ) { DmFileId_t fileId = pRoot->GetFileId(); DestroyElement( pRoot ); if ( fileId != DMFILEID_INVALID && g_pDataModel->GetFileName( fileId )[0] ) { g_pDataModel->RemoveFileId( fileId ); } return NULL; } }
if ( ppRoot ) { *ppRoot = CastElement< CDmElement >( pRoot ); } return pMakeFile; }
//-----------------------------------------------------------------------------
// Sort by MDL name
//-----------------------------------------------------------------------------
static int __cdecl TypeSortFunc( vgui::ListPanel *pPanel, const ListPanelItem &item1, const ListPanelItem &item2 ) { const char *string1 = item1.kv->GetString("type"); const char *string2 = item2.kv->GetString("type"); int nRetVal = Q_stricmp( string1, string2 ); if ( nRetVal != 0 ) return nRetVal;
string1 = item1.kv->GetString("file"); string2 = item2.kv->GetString("file"); nRetVal = Q_stricmp( string1, string2 ); if ( nRetVal != 0 ) return nRetVal;
int nIndex1 = item1.kv->GetInt( "index" ); int nIndex2 = item2.kv->GetInt( "index" ); return nIndex1 - nIndex2; }
static int __cdecl FileSortFunc( vgui::ListPanel *pPanel, const ListPanelItem &item1, const ListPanelItem &item2 ) { const char *string1 = item1.kv->GetString("file"); const char *string2 = item2.kv->GetString("file"); int nRetVal = Q_stricmp( string1, string2 ); if ( nRetVal != 0 ) return nRetVal;
string1 = item1.kv->GetString("type"); string2 = item2.kv->GetString("type"); nRetVal = Q_stricmp( string1, string2 ); if ( nRetVal != 0 ) return nRetVal;
int nIndex1 = item1.kv->GetInt( "index" ); int nIndex2 = item2.kv->GetInt( "index" ); return nIndex1 - nIndex2; }
//-----------------------------------------------------------------------------
// Purpose: Constructor, destructor
//-----------------------------------------------------------------------------
CAssetBuilder::CAssetBuilder( vgui::Panel *pParent, const char *pPanelName ) : BaseClass( pParent, pPanelName ) { m_hContextMenu = NULL; m_hRootMakefile = NULL; m_bIsCompiling = false; m_bDestroyMakefileOnClose = true;
m_pInputOutputSheet = new vgui::PropertySheet( this, "InputOutputSheet" ); m_pInputOutputSheet->AddActionSignalTarget( this );
m_pInputPage = new PropertyPage( m_pInputOutputSheet, "InputPage" ); m_pOutputPage = new PropertyPage( m_pInputOutputSheet, "OutputPage" ); m_pCompilePage = new PropertyPage( m_pInputOutputSheet, "CompilePage" ); m_pOutputPreviewPage = new PropertyPage( m_pInputOutputSheet, "OutputPreviewPage" );
m_pPropertiesSplitter = new vgui::Splitter( m_pInputPage, "PropertiesSplitter", SPLITTER_MODE_VERTICAL, 1 );
vgui::Panel *pSplitterLeftSide = m_pPropertiesSplitter->GetChild( 0 ); vgui::Panel *pSplitterRightSide = m_pPropertiesSplitter->GetChild( 1 ); m_pDmePanel = new CDmePanel( pSplitterRightSide, "CompileOptions" ); m_pDmePanel->AddActionSignalTarget( this );
m_pOututPreviewPanel = new CDmePanel( m_pOutputPreviewPage, "OutputPreview", false ); m_pOututPreviewPanel->AddActionSignalTarget( this );
m_pSourcesList = new vgui::ListPanel( pSplitterLeftSide, "SourcesList" ); m_pSourcesList->AddColumnHeader( 0, "type", "type", 100, 0 ); m_pSourcesList->AddColumnHeader( 1, "file", "file", 52, 0 ); m_pSourcesList->AddActionSignalTarget( this ); m_pSourcesList->SetSortFunc( 0, TypeSortFunc ); m_pSourcesList->SetSortFunc( 1, FileSortFunc ); m_pSourcesList->SetSortColumn( 0 ); // m_pSourcesList->SetSelectIndividualCells( true );
m_pSourcesList->SetEmptyListText("No sources"); // m_pSourcesList->SetDragEnabled( true );
m_pOutputList = new vgui::ListPanel( m_pOutputPage, "OutputList" ); m_pOutputList->AddColumnHeader( 0, "type", "type", 100, 0 ); m_pOutputList->AddColumnHeader( 1, "file", "file", 52, 0 ); m_pOutputList->AddActionSignalTarget( this ); m_pOutputList->SetSortFunc( 0, TypeSortFunc ); m_pOutputList->SetSortFunc( 1, FileSortFunc ); m_pOutputList->SetSortColumn( 0 ); m_pOutputList->SetEmptyListText("No outputs");
m_pCompileOutput = new vgui::TextEntry( m_pCompilePage, "CompileOutput" ); m_pCompileOutput->SetMultiline( true ); m_pCompileOutput->SetVerticalScrollbar( true ); m_pCompile = new vgui::Button( this, "CompileButton", "Compile", this, "OnCompile" ); m_pPublish = new vgui::Button( this, "PublishButton", "Publish", this, "OnPublish" ); m_pAbortCompile = new vgui::Button( this, "AbortCompileButton", "AbortCompile", this, "OnAbortCompile" ); m_pCompileStatusBar = new CCompileStatusBar( this, "CompileStatus" );
m_pInputPage->LoadControlSettingsAndUserConfig( "resource/assetbuilderinputpage.res" ); m_pOutputPage->LoadControlSettingsAndUserConfig( "resource/assetbuilderoutputpage.res" ); m_pCompilePage->LoadControlSettingsAndUserConfig( "resource/assetbuildercompilepage.res" ); m_pOutputPreviewPage->LoadControlSettingsAndUserConfig( "resource/assetbuilderoutputpreviewpage.res" );
// Load layout settings; has to happen before pinning occurs in code
LoadControlSettingsAndUserConfig( "resource/assetbuilder.res" );
// NOTE: Page adding happens *after* LoadControlSettingsAndUserConfig
// because the layout of the sheet is correct at this point.
m_pInputOutputSheet->AddPage( m_pInputPage, "Input" ); m_pInputOutputSheet->AddPage( m_pOutputPage, "Output" ); m_pInputOutputSheet->AddPage( m_pCompilePage, "Compile" ); m_pInputOutputSheet->AddPage( m_pOutputPreviewPage, "Preview" );
m_pCompile->SetEnabled( false ); m_pPublish->SetEnabled( false ); m_pAbortCompile->SetEnabled( false ); }
CAssetBuilder::~CAssetBuilder() { if ( m_bDestroyMakefileOnClose ) { CleanupMakefile(); } CleanupContextMenu(); SaveUserConfig(); }
//-----------------------------------------------------------------------------
// Default behavior is to destroy the makefile when we close
//-----------------------------------------------------------------------------
void CAssetBuilder::DestroyMakefileOnClose( bool bEnable ) { m_bDestroyMakefileOnClose = bEnable; }
//-----------------------------------------------------------------------------
// Builds a unique list of file IDs
//-----------------------------------------------------------------------------
void CAssetBuilder::BuildFileIDList( CDmeMakefile *pMakeFile, CUtlVector<DmFileId_t> &fileIds ) { if ( !pMakeFile ) return;
// NOTE: Not hugely efficient. If the CDmeDependencyMakefile starts
// getting large, we can optimize this
DmFileId_t id = pMakeFile->GetFileId(); int nCount = fileIds.Count(); int i; for ( i = 0; i < nCount; ++i ) { if ( fileIds[i] == id ) break; }
if ( i == nCount ) { fileIds.AddToTail( id ); }
int nSourceCount = pMakeFile->GetSourceCount(); for ( int i = 0; i < nSourceCount; ++i ) { CDmeSource *pSource = pMakeFile->GetSource(i); BuildFileIDList( pSource->GetDependentMakefile(), fileIds ); } }
//-----------------------------------------------------------------------------
// Removes a makefile from memory
//-----------------------------------------------------------------------------
void CAssetBuilder::CleanupMakefile() { m_hMakefileStack.Clear(); m_pDmePanel->SetDmeElement( NULL ); m_pOututPreviewPanel->SetDmeElement( NULL );
if ( !m_hRootMakefile.Get() ) return;
// First, build a list of unique file IDs
CUtlVector<DmFileId_t> fileIds; BuildFileIDList( m_hRootMakefile, fileIds );
CDisableUndoScopeGuard guard;
m_hRootMakefile = NULL;
int nCount = fileIds.Count(); for ( int i = 0; i < nCount; ++i ) { if ( fileIds[i] != DMFILEID_INVALID && g_pDataModel->GetFileName( fileIds[i] )[0] ) { g_pDataModel->RemoveFileId( fileIds[i] ); } } }
//-----------------------------------------------------------------------------
// Marks the file as dirty (or not)
//-----------------------------------------------------------------------------
void CAssetBuilder::SetDirty() { PostActionSignal( new KeyValues( "DmeElementChanged" ) ); }
//-----------------------------------------------------------------------------
// Returns the current makefile
//-----------------------------------------------------------------------------
CDmeMakefile *CAssetBuilder::GetMakeFile() { return m_hMakefile.Get(); }
CDmeMakefile *CAssetBuilder::GetRootMakeFile() { return m_hRootMakefile.Get(); }
//-----------------------------------------------------------------------------
// Resets the lists; called when file name changes
//-----------------------------------------------------------------------------
void CAssetBuilder::Refresh() { RefreshSourceList(); RefreshOutputList(); }
//-----------------------------------------------------------------------------
// Resets the root makefile
//-----------------------------------------------------------------------------
void CAssetBuilder::SetRootMakefile( CDmeMakefile *pMakeFile ) { CleanupMakefile();
if ( pMakeFile ) { m_hRootMakefile = pMakeFile; m_hMakefileStack.Push( m_hRootMakefile ); } SetCurrentMakefile( pMakeFile ); }
//-----------------------------------------------------------------------------
// Resets the current makefile
//-----------------------------------------------------------------------------
void CAssetBuilder::SetCurrentMakefile( CDmeMakefile *pMakeFile ) { m_hMakefile = pMakeFile; m_pDmePanel->SetDmeElement( NULL ); m_pOututPreviewPanel->SetDmeElement( pMakeFile, true, "DmeMakeFileOutputPreview" ); RefreshSourceList(); RefreshOutputList();
// Lets the asset builder update the title bar
PostActionSignal( new KeyValues( "UpdateFileName" ) ); } //-----------------------------------------------------------------------------
// Hook into the DME panel framework
//-----------------------------------------------------------------------------
void CAssetBuilder::SetDmeElement( CDmeMakefile *pMakeFile ) { SetRootMakefile( pMakeFile ); }
//-----------------------------------------------------------------------------
// Refresh the source list
//-----------------------------------------------------------------------------
void CAssetBuilder::RefreshSourceList( ) { m_pSourcesList->RemoveAll(); if ( !m_hMakefile.Get() ) return;
DmeMakefileType_t *pSourceTypes = m_hMakefile->GetSourceTypes(); for ( int i = 0; pSourceTypes[i].m_pTypeName; ++i ) { CUtlVector< CDmeHandle< CDmeSource > > sources; m_hMakefile->GetSources( pSourceTypes[i].m_pTypeName, sources ); int nCount = sources.Count(); for ( int j = 0; j < nCount; ++j ) { char pFullPath[MAX_PATH]; m_hMakefile->GetSourceFullPath( sources[j], pFullPath, sizeof(pFullPath) );
KeyValues *pItemKeys = new KeyValues( "node", "type", pSourceTypes[i].m_pHumanReadableName ); pItemKeys->SetString( "file", pFullPath ); pItemKeys->SetInt( "sourceTypeIndex", i ); pItemKeys->SetInt( "index", j ); // for sorting in the listpanel
SetElementKeyValue( pItemKeys, "dmeSource", sources[j] ); m_pSourcesList->AddItem( pItemKeys, 0, false, false ); } }
m_pSourcesList->SortList(); }
//-----------------------------------------------------------------------------
// Refreshes the output list
//-----------------------------------------------------------------------------
void CAssetBuilder::RefreshOutputList() { m_pOutputList->RemoveAll(); m_pCompile->SetEnabled( false ); m_pPublish->SetEnabled( false ); if ( !m_hMakefile.Get() ) return;
CUtlVector<CUtlString> outputs; m_hMakefile->GetOutputs( outputs ); int nCount = outputs.Count(); for ( int j = 0; j < nCount; ++j ) { KeyValues *pItemKeys = new KeyValues( "node", "type", "Output" ); pItemKeys->SetString( "file", outputs[j] ); pItemKeys->SetInt( "index", j ); m_pOutputList->AddItem( pItemKeys, 0, false, false ); }
bool bEnabled = ( nCount > 0 ) && ( g_pDmeMakefileUtils != NULL ); m_pCompile->SetEnabled( bEnabled ); m_pPublish->SetEnabled( bEnabled );
m_pOutputList->SortList(); }
//-----------------------------------------------------------------------------
// Selects a particular source
//-----------------------------------------------------------------------------
void CAssetBuilder::SelectSource( CDmeSource *pSource ) { int nItemID = m_pSourcesList->FirstItem(); for ( ; nItemID != m_pSourcesList->InvalidItemID(); nItemID = m_pSourcesList->NextItem( nItemID ) ) { KeyValues *kv = m_pSourcesList->GetItem( nItemID ); if ( GetElementKeyValue< CDmeSource >( kv, "dmeSource" ) != pSource ) continue;
m_pSourcesList->SetSingleSelectedItem( nItemID ); return; } }
//-----------------------------------------------------------------------------
// Called by the picker popped up in OnFileNew
//-----------------------------------------------------------------------------
void CAssetBuilder::OnPicked( KeyValues *kv ) { const char *pValue = kv->GetString( "choice" ); KeyValues *pContextKeys = kv->FindKey( "OnAddSource" ); if ( pContextKeys ) { OnSourceFileAdded( "", pValue ); return; }
CDisableUndoScopeGuard guard; CDmeMakefile *pMakeFile = GetElement< CDmeMakefile >( g_pDataModel->CreateElement( pValue, "unnamed", DMFILEID_INVALID ) ); if ( !pMakeFile ) return;
DmeMakefileType_t *pType = pMakeFile->GetMakefileType();
char pContext[MAX_PATH]; Q_snprintf( pContext, sizeof(pContext), "asset_builder_session_%s", pType->m_pTypeName );
char pStartingDir[MAX_PATH]; pMakeFile->GetDefaultDirectory( pType->m_pDefaultDirectoryID, pStartingDir, sizeof(pStartingDir) ); g_pFullFileSystem->CreateDirHierarchy( pStartingDir );
KeyValues *pDialogKeys = new KeyValues( "NewSourceFileSelected", "makefileType", pValue ); FileOpenDialog *pDialog = new FileOpenDialog( this, "Select Asset Builder File Name", false, pDialogKeys ); pDialog->SetStartDirectoryContext( pContext, pStartingDir ); pDialog->AddFilter( pType->m_pFileFilter, pType->m_pFileFilterString, true ); pDialog->AddActionSignalTarget( this ); pDialog->DoModal( false ); DestroyElement( pMakeFile ); }
//-----------------------------------------------------------------------------
// Creates a new source file, hooks it in
//-----------------------------------------------------------------------------
void CAssetBuilder::OnNewSourceFile( ) { KeyValues *pKeyValues = GetSelectedSourceKeyvalues(); CDmeSource *pSource = GetElementKeyValue< CDmeSource >( pKeyValues, "dmeSource" ); if ( !pSource ) return;
BuildAssetTypeList();
PickerList_t typePickerList; PickerList_t &pickerList = BuildAssetSubTypeList( pSource->GetSourceMakefileTypes(), typePickerList );
// Create a list indicating which type of asset to create
CPickerFrame *pPicker = new CPickerFrame( this, "Select Sub-Asset Type", "Asset Type", "assetType" ); pPicker->DoModal( pickerList ); }
//-----------------------------------------------------------------------------
// Called when the button to add a file is clicked
//-----------------------------------------------------------------------------
void CAssetBuilder::OnAddSource( ) { if ( !m_hMakefile.Get() ) return;
PickerList_t sourceType;
DmeMakefileType_t *pSourceTypes = m_hMakefile->GetSourceTypes(); for ( int i = 0; pSourceTypes[i].m_pTypeName; ++i ) { if ( pSourceTypes[i].m_bIsSingleton ) { if ( m_hMakefile->HasSourceOfType( pSourceTypes[i].m_pTypeName ) ) continue; }
int j = sourceType.AddToTail( ); sourceType[j].m_pChoiceString = pSourceTypes[i].m_pHumanReadableName; sourceType[j].m_pChoiceValue = pSourceTypes[i].m_pTypeName; }
if ( sourceType.Count() == 0 ) return;
KeyValues *pContextKeys = new KeyValues( "OnAddSource" ); CPickerFrame *pPicker = new CPickerFrame( this, "Select Source Type", "Source Type", "sourceType" ); pPicker->DoModal( sourceType, pContextKeys ); }
//-----------------------------------------------------------------------------
// Returns the curerntly selected row
//-----------------------------------------------------------------------------
int CAssetBuilder::GetSelectedRow( ) { int nItemID = m_pSourcesList->GetSelectedItem( 0 ); return ( nItemID != -1 ) ? m_pSourcesList->GetItemCurrentRow( nItemID ) : -1; }
//-----------------------------------------------------------------------------
// Selects a particular row of the source list
//-----------------------------------------------------------------------------
void CAssetBuilder::SelectSourceListRow( int nRow ) { int nVisibleRowCount = m_pSourcesList->GetItemCount(); if ( nVisibleRowCount == 0 || nRow < 0 ) return;
if ( nRow >= nVisibleRowCount ) { nRow = nVisibleRowCount - 1; }
int nNewItemID = m_pSourcesList->GetItemIDFromRow( nRow ); m_pSourcesList->SetSingleSelectedItem( nNewItemID ); }
//-----------------------------------------------------------------------------
// Called when the button to remove a file is clicked
//-----------------------------------------------------------------------------
void CAssetBuilder::OnRemoveSource( ) { int nCount = m_pSourcesList->GetSelectedItemsCount(); if ( nCount == 0 || !m_hMakefile.Get() ) return;
int nRow = GetSelectedRow(); Assert( nRow >= 0 );
// Update the selection to be reasonable after deletion
CDisableUndoScopeGuard guard; for ( int i = 0; i < nCount; ++i ) { int nItemID = m_pSourcesList->GetSelectedItem( i ); KeyValues *pKeyValues = m_pSourcesList->GetItem( nItemID ); CDmeSource *pSource = GetElementKeyValue< CDmeSource >( pKeyValues, "dmeSource" ); if ( pSource ) { m_hMakefile->RemoveSource( pSource ); DestroyElement( pSource ); SetDirty( ); } }
RefreshSourceList();
SelectSourceListRow( nRow ); }
//-----------------------------------------------------------------------------
// Called to make a particular source the currently selected source
//-----------------------------------------------------------------------------
void CAssetBuilder::OnZoomInSource() { // Called to zoom into the currently selected source
CDmeSource *pSource = GetSelectedSource( ); if ( !pSource ) return;
CDmeMakefile *pChild = m_hMakefile->FindDependentMakefile( pSource ); if ( pChild ) { CDmeHandle< CDmeMakefile > hChild; hChild = pChild; m_hMakefileStack.Push( hChild ); SetCurrentMakefile( pChild ); } }
//-----------------------------------------------------------------------------
// Called to zoom out of a particular source
//-----------------------------------------------------------------------------
void CAssetBuilder::OnZoomOutSource() { // Called to zoom into the currently selected source
if ( m_hMakefileStack.Count() <= 1 ) return;
CDmeMakefile *pOldParent = m_hMakefileStack.Top().Get(); m_hMakefileStack.Pop( ); CDmeMakefile *pParent = m_hMakefileStack.Top().Get(); if ( pParent ) { SetCurrentMakefile( pParent ); CDmeSource *pSource = pParent->FindAssociatedSource( pOldParent ); if ( pSource ) { SelectSource( pSource ); } } }
//-----------------------------------------------------------------------------
// Called when a key is typed
//-----------------------------------------------------------------------------
void CAssetBuilder::OnKeyCodeTyped( vgui::KeyCode code ) { if ( code == KEY_DELETE ) { OnRemoveSource(); return; }
if ( code == KEY_ENTER ) { OnZoomInSource(); return; }
BaseClass::OnKeyCodeTyped( code ); }
//-----------------------------------------------------------------------------
// Called when we're browsing for a source file and one was selected
//-----------------------------------------------------------------------------
void CAssetBuilder::OnSourceFileAdded( const char *pFileName, const char *pTypeName ) { CDmeSource *pSource = NULL; { CDisableUndoScopeGuard guard; pSource = m_hMakefile->AddSource( pTypeName, pFileName ); } SetDirty( ); RefreshSourceList( ); SelectSource( pSource ); }
//-----------------------------------------------------------------------------
// Called when the file open dialog for browsing source files selects something
//-----------------------------------------------------------------------------
void CAssetBuilder::OnNewSourceFileSelected( const char *pFileName, KeyValues *kv ) { int nCount = m_pSourcesList->GetSelectedItemsCount(); if ( nCount != 1 || !m_hMakefile.Get() ) return;
int nItemID = m_pSourcesList->GetSelectedItem( 0 ); KeyValues *pKeyValues = m_pSourcesList->GetItem( nItemID ); CDmeSource *pSource = GetElementKeyValue< CDmeSource >( pKeyValues, "dmeSource" ); if ( !pSource ) return;
const char *pMakeFileType = kv->GetString( "makefileType" );
{ CDisableUndoScopeGuard guard; m_hMakefile->SetSourceFullPath( pSource, pFileName );
DmFileId_t fileid = g_pDataModel->FindOrCreateFileId( pFileName ); CDmeMakefile *pSourceMakeFile = CreateElement< CDmeMakefile >( pMakeFileType, pFileName, fileid ); pSourceMakeFile->SetFileName( pFileName );
m_hMakefile->SetAssociation( pSource, pSourceMakeFile ); SetDirty( ); }
pKeyValues->SetString( "file", pFileName ); m_pSourcesList->ApplyItemChanges( nItemID ); m_pSourcesList->SortList(); }
//-----------------------------------------------------------------------------
// Called when the file open dialog for browsing source files selects something
//-----------------------------------------------------------------------------
void CAssetBuilder::OnFileSelected( KeyValues *kv ) { const char *pFileName = kv->GetString( "fullpath", NULL ); if ( !pFileName ) return;
KeyValues *pDialogKeys = kv->FindKey( "SelectSourceFile" ); if ( pDialogKeys ) { OnSourceFileNameChanged( pFileName ); return; }
pDialogKeys = kv->FindKey( "NewSourceFileSelected" ); if ( pDialogKeys ) { if ( !g_pFullFileSystem->FileExists( pFileName ) ) { OnNewSourceFileSelected( pFileName, pDialogKeys ); } else { OnSourceFileNameChanged( pFileName ); } return; } }
//-----------------------------------------------------------------------------
// Shows the source file browser
//-----------------------------------------------------------------------------
void CAssetBuilder::ShowSourceFileBrowser( const char *pTitle, DmeMakefileType_t *pSourceType, KeyValues *pDialogKeys ) { char pContext[MAX_PATH]; Q_snprintf( pContext, sizeof(pContext), "asset_builder_session_%s", pSourceType->m_pTypeName );
char pStartingDir[MAX_PATH]; m_hMakefile->GetDefaultDirectory( pSourceType->m_pDefaultDirectoryID, pStartingDir, sizeof(pStartingDir) ); g_pFullFileSystem->CreateDirHierarchy( pStartingDir );
FileOpenDialog *pDialog = new FileOpenDialog( this, pTitle, true, pDialogKeys ); pDialog->SetStartDirectoryContext( pContext, pStartingDir ); pDialog->AddFilter( pSourceType->m_pFileFilter, pSourceType->m_pFileFilterString, true ); pDialog->AddActionSignalTarget( this ); pDialog->DoModal( false ); }
//-----------------------------------------------------------------------------
// Called when the button to browse for a source file is clicked
//-----------------------------------------------------------------------------
void CAssetBuilder::OnBrowseSourceFile( ) { KeyValues *pKeyValues = GetSelectedSourceKeyvalues(); if ( !pKeyValues ) return;
int nSourceTypeIndex = pKeyValues->GetInt( "sourceTypeIndex", -1 );
KeyValues *pDialogKeys = new KeyValues( "SelectSourceFile" ); DmeMakefileType_t &sourceType = m_hMakefile->GetSourceTypes()[nSourceTypeIndex]; ShowSourceFileBrowser( "Select Source File", &sourceType, pDialogKeys ); }
//-----------------------------------------------------------------------------
// Command handler
//-----------------------------------------------------------------------------
void CAssetBuilder::OnCommand( const char *pCommand ) { if ( !Q_stricmp( pCommand, "OnCompile" ) ) { OnCompile(); return; }
if ( !Q_stricmp( pCommand, "OnAbortCompile" ) ) { OnAbortCompile(); return; }
if ( !Q_stricmp( pCommand, "OnPublish" ) ) { OnPublish(); return; }
BaseClass::OnCommand( pCommand ); }
//-----------------------------------------------------------------------------
// Cleans up the context menu
//-----------------------------------------------------------------------------
void CAssetBuilder::CleanupContextMenu() { if ( m_hContextMenu.Get() ) { m_hContextMenu->MarkForDeletion(); m_hContextMenu = NULL; } }
//-----------------------------------------------------------------------------
// Called to open a context-sensitive menu for a particular menu item
//-----------------------------------------------------------------------------
void CAssetBuilder::OnOpenContextMenu( KeyValues *kv ) { CleanupContextMenu(); if ( !m_hMakefile.Get() ) return;
Panel *pPanel = (Panel *)kv->GetPtr( "panel", NULL ); int nItemID = kv->GetInt( "itemID", -1 );
if ( pPanel != m_pSourcesList ) return;
m_hContextMenu = new Menu( this, "ActionMenu" ); m_hContextMenu->AddMenuItem( "Add...", new KeyValues( "AddSource" ), this ); int nCount = m_pSourcesList->GetSelectedItemsCount(); if ( nCount > 0 ) { m_hContextMenu->AddMenuItem( "Remove", new KeyValues( "RemoveSource" ), this ); }
bool bShowZoomIn = false; bool bShowZoomOut = m_hMakefileStack.Count() > 1; bool bShowLoadSourceFile = false; bool bHasValidSourceFile = false; if ( nCount == 1 && nItemID != -1 ) { KeyValues *kv = m_pSourcesList->GetItem( nItemID ); CDmeSource *pSource = GetElementKeyValue< CDmeSource >( kv, "dmeSource" ); if ( pSource ) { bHasValidSourceFile = pSource->GetRelativeFileName()[0] != 0; if ( m_hMakefile->FindDependentMakefile( pSource ) ) { bShowZoomIn = true; } else { bShowLoadSourceFile = bHasValidSourceFile; } } }
if ( bShowZoomIn || bShowZoomOut ) { m_hContextMenu->AddSeparator(); if ( bShowZoomIn ) { m_hContextMenu->AddMenuItem( "Zoom In", new KeyValues( "ZoomInSource" ), this ); } if ( bShowZoomOut ) { m_hContextMenu->AddMenuItem( "Zoom Out", new KeyValues( "ZoomOutSource" ), this ); } }
if ( nCount == 1 ) { m_hContextMenu->AddSeparator(); m_hContextMenu->AddMenuItem( "New Source File...", new KeyValues( "NewSourceFile" ), this ); m_hContextMenu->AddMenuItem( "Select Source File...", new KeyValues( "BrowseSourceFile" ), this ); if ( bShowLoadSourceFile ) { m_hContextMenu->AddMenuItem( "Load Source File", new KeyValues( "LoadSourceFile" ), this ); } if ( bHasValidSourceFile ) { m_hContextMenu->AddMenuItem( "Edit Source File", new KeyValues( "EditSourceFile" ), this ); } }
Menu::PlaceContextMenu( this, m_hContextMenu.Get() ); }
//-----------------------------------------------------------------------------
// Called when a list panel's selection changes
//-----------------------------------------------------------------------------
void CAssetBuilder::OnSourceItemSelectionChanged( ) { int nCount = m_pSourcesList->GetSelectedItemsCount(); if ( nCount != 1 ) { m_pDmePanel->SetDmeElement( NULL ); return; }
int nItemID = m_pSourcesList->GetSelectedItem( 0 ); KeyValues *pKeyValues = m_pSourcesList->GetItem( nItemID ); CDmeSource *pSource = GetElementKeyValue< CDmeSource >( pKeyValues, "dmeSource" ); m_pDmePanel->SetDmeElement( pSource ); }
//-----------------------------------------------------------------------------
// Called when a list panel's selection changes
//-----------------------------------------------------------------------------
void CAssetBuilder::OnItemSelected( KeyValues *kv ) { Panel *pPanel = (Panel *)kv->GetPtr( "panel", NULL ); if ( pPanel == m_pSourcesList ) { OnSourceItemSelectionChanged(); return; } }
//-----------------------------------------------------------------------------
// Called when a list panel's selection changes
//-----------------------------------------------------------------------------
void CAssetBuilder::OnItemDeselected( KeyValues *kv ) { Panel *pPanel = (Panel *)kv->GetPtr( "panel", NULL ); if ( pPanel == m_pSourcesList ) { OnSourceItemSelectionChanged(); return; } }
//-----------------------------------------------------------------------------
// Returns the selected source (if there's only 1 source selected)
//-----------------------------------------------------------------------------
CDmeSource *CAssetBuilder::GetSelectedSource( ) { int nCount = m_pSourcesList->GetSelectedItemsCount(); if ( nCount != 1 || !m_hMakefile.Get() ) return NULL;
int nItemID = m_pSourcesList->GetSelectedItem( 0 ); KeyValues *pKeyValues = m_pSourcesList->GetItem( nItemID ); return GetElementKeyValue< CDmeSource >( pKeyValues, "dmeSource" ); }
KeyValues *CAssetBuilder::GetSelectedSourceKeyvalues( ) { int nCount = m_pSourcesList->GetSelectedItemsCount(); if ( nCount != 1 || !m_hMakefile.Get() ) return NULL;
int nItemID = m_pSourcesList->GetSelectedItem( 0 ); return m_pSourcesList->GetItem( nItemID ); }
//-----------------------------------------------------------------------------
// Called when the source file name changes
//-----------------------------------------------------------------------------
void CAssetBuilder::OnSourceFileNameChanged( const char *pFileName ) { int nCount = m_pSourcesList->GetSelectedItemsCount(); if ( nCount != 1 || !m_hMakefile.Get() ) return;
int nItemID = m_pSourcesList->GetSelectedItem( 0 ); KeyValues *pKeyValues = m_pSourcesList->GetItem( nItemID ); CDmeSource *pSource = GetElementKeyValue< CDmeSource >( pKeyValues, "dmeSource" ); if ( !pSource ) return;
{ CDisableUndoScopeGuard guard; m_hMakefile->SetSourceFullPath( pSource, pFileName ); SetDirty( ); }
pKeyValues->SetString( "file", pFileName ); m_pSourcesList->ApplyItemChanges( nItemID ); m_pSourcesList->SortList(); }
//-----------------------------------------------------------------------------
// Called during compilation
//-----------------------------------------------------------------------------
void CAssetBuilder::OnLoadSourceFile() { CDmeSource *pSource = GetSelectedSource( ); if ( !pSource ) return;
char pFullPath[MAX_PATH]; m_hMakefile->GetSourceFullPath( pSource, pFullPath, sizeof(pFullPath) );
{ CDisableUndoScopeGuard guard;
CDmElement *pRoot; CDmeMakefile *pMakeFile = ReadMakefile( pFullPath, &pRoot ); if ( !pMakeFile ) return;
// Successfully loaded a makefile. Set up the association.
m_hMakefile->SetAssociation( pSource, pMakeFile );
// Refresh the dme panel... setting association could provoke changes
m_pDmePanel->SetDmeElement( pSource, true ); } }
//-----------------------------------------------------------------------------
// Called to open an external editor for this source file
//-----------------------------------------------------------------------------
void CAssetBuilder::OnEditSourceFile() { CDmeSource *pSource = GetSelectedSource( ); if ( pSource ) { pSource->OpenEditor(); } }
//-----------------------------------------------------------------------------
// Finishes compilation
//-----------------------------------------------------------------------------
void CAssetBuilder::FinishCompilation( CompilationState_t state ) { // NOTE: compilation can cause the makefile to be completely
// rebuilt if it's sitting in the output file. Therefore,
// Detach the source preview panel from the source and refresh the
// source list to get it to correctly reconnect to the new source elements
m_pDmePanel->SetDmeElement( NULL ); int nRow = GetSelectedRow();
m_pOututPreviewPanel->SetDmeElement( m_hMakefile, true, "DmeMakeFileOutputPreview" ); m_bIsCompiling = false;
// NOTE: Sort of side-effecty. These two things must be done after
// m_pOututPreviewPanel->SetDmeElement, since that's what reloads the output element,
// which is also what can cause a reload of the makefile
RefreshSourceList(); SelectSourceListRow( nRow );
// Lets the asset builder update the title bar
// (compilation could have changed the dirty state if the makefile is in the file)
PostActionSignal( new KeyValues( "UpdateFileName" ) );
if ( state == COMPILATION_FAILED ) { char pBuf[256]; Q_snprintf( pBuf, sizeof(pBuf), "Compilation Error (return code %d)", g_pDmeMakefileUtils->GetExitCode() ); m_pCompileStatusBar->SetStatus( CCompileStatusBar::COMPILATION_FAILED, pBuf ); } else { m_pCompileStatusBar->SetStatus( CCompileStatusBar::COMPILATION_SUCCESSFUL, "Compile Successful!" ); } }
//-----------------------------------------------------------------------------
// Called during compilation
//-----------------------------------------------------------------------------
void CAssetBuilder::OnTick() { BaseClass::OnTick();
if ( m_bIsCompiling ) { int nLen = g_pDmeMakefileUtils->GetCompileOutputSize( ); char *pBuf = (char*)_alloca( nLen+1 ); CompilationState_t state = g_pDmeMakefileUtils->UpdateCompilation( pBuf, nLen ); if ( nLen > 0 ) { m_pCompileOutput->InsertString( pBuf ); } Assert( m_hMakefile.Get() ); if ( state != COMPILATION_NOT_COMPLETE ) { FinishCompilation( state ); } }
if ( !m_bIsCompiling ) { m_pAbortCompile->SetEnabled( false ); vgui::ivgui()->RemoveTickSignal( GetVPanel() ); } }
//-----------------------------------------------------------------------------
// Abort compile asset
//-----------------------------------------------------------------------------
void CAssetBuilder::OnAbortCompile() { if ( m_bIsCompiling ) { g_pDmeMakefileUtils->AbortCurrentCompilation(); m_bIsCompiling = false; m_pAbortCompile->SetEnabled( false ); m_pCompileStatusBar->SetStatus( CCompileStatusBar::COMPILATION_FAILED, "Compile Aborted" ); } }
//-----------------------------------------------------------------------------
// Compile asset
//-----------------------------------------------------------------------------
void CAssetBuilder::OnCompile( ) { if ( !m_hMakefile.Get() ) return;
OnAbortCompile();
m_pCompileOutput->SetText( "" ); g_pDmeMakefileUtils->PerformCompile( m_hMakefile, false ); m_bIsCompiling = true; m_pAbortCompile->SetEnabled( true ); m_pCompileStatusBar->SetStatus( CCompileStatusBar::CURRENTLY_COMPILING, "Compiling..." );
vgui::ivgui()->AddTickSignal( GetVPanel(), 10 ); }
//-----------------------------------------------------------------------------
// Compile, then publish
//-----------------------------------------------------------------------------
void CAssetBuilder::OnPublish( ) { if ( !m_hMakefile.Get() ) return;
OnAbortCompile();
m_pCompileOutput->SetText( "" ); g_pDmeMakefileUtils->PerformCompile( m_hMakefile, false ); m_bIsCompiling = true; m_pAbortCompile->SetEnabled( true ); m_pCompileStatusBar->SetStatus( CCompileStatusBar::CURRENTLY_COMPILING, "Compiling..." ); vgui::ivgui()->AddTickSignal( GetVPanel(), 10 ); }
//-----------------------------------------------------------------------------
// Purpose: Constructor, destructor
//-----------------------------------------------------------------------------
CAssetBuilderFrame::CAssetBuilderFrame( vgui::Panel *pParent, const char *pTitle ) : BaseClass( pParent, "AssetBuilderFrame" ) { m_TitleString = pTitle;
SetMenuButtonVisible( true ); SetImages( "resource/downarrow" );
m_pAssetBuilder = new CAssetBuilder( this, "AssetBuilder" ); m_pAssetBuilder->AddActionSignalTarget( this );
vgui::Menu *pMenu = new vgui::Menu( NULL, "FileMenu" ); pMenu->AddMenuItem( "new", "#AssetBuilder_FileNew", new KeyValues( "FileNew" ), this ); pMenu->AddMenuItem( "open", "#AssetBuilder_FileOpen", new KeyValues( "FileOpen" ), this ); pMenu->AddMenuItem( "save", "#AssetBuilder_FileSave", new KeyValues( "FileSave" ), this ); pMenu->AddMenuItem( "saveas", "#AssetBuilder_FileSaveAs", new KeyValues( "FileSaveAs" ), this ); SetSysMenu( pMenu );
m_pFileOpenStateMachine = new vgui::FileOpenStateMachine( this, this ); m_pFileOpenStateMachine->AddActionSignalTarget( this );
// Load layout settings; has to happen before pinning occurs in code
LoadControlSettingsAndUserConfig( "resource/assetbuilderframe.res" );
UpdateFileName(); }
CAssetBuilderFrame::~CAssetBuilderFrame() { }
//-----------------------------------------------------------------------------
// Inherited from IFileOpenStateMachineClient
//-----------------------------------------------------------------------------
void CAssetBuilderFrame::SetupFileOpenDialog( vgui::FileOpenDialog *pDialog, bool bOpenFile, const char *pFileFormat, KeyValues *pContextKeyValues ) { // Compute starting directory
char pStartingDir[ MAX_PATH ]; GetModContentSubdirectory( "", pStartingDir, sizeof(pStartingDir) );
if ( bOpenFile ) { // Clear out the existing makefile if we're opening a file
m_pAssetBuilder->SetRootMakefile( NULL ); pDialog->SetTitle( "Open Asset MakeFile", true ); } else { pDialog->SetTitle( "Save Asset MakeFile As", true ); }
pDialog->SetStartDirectoryContext( "asset_browser_makefile", pStartingDir ); pDialog->AddFilter( "*.*", "All Files (*.*)", false ); pDialog->AddFilter( "*.dmx", "Asset MakeFiles (*.dmx)", true, "keyvalues2" ); }
bool CAssetBuilderFrame::OnReadFileFromDisk( const char *pFileName, const char *pFileFormat, KeyValues *pContextKeyValues ) { CDmElement *pRoot; CDmeMakefile *pMakeFile = ReadMakefile( pFileName, &pRoot ); if ( !pMakeFile ) return false;
Reset( pMakeFile ); return true; }
bool CAssetBuilderFrame::OnWriteFileToDisk( const char *pFileName, const char *pFileFormat, KeyValues *pContextKeyValues ) { // Recompute relative paths for each source now that we know the file name
// NOTE: This also updates the name of the fileID in the datamodel system
CDmeMakefile *pMakefile = m_pAssetBuilder->GetMakeFile(); bool bOk; { CDisableUndoScopeGuard guard; bOk = pMakefile->SetFileName( pFileName ); } if ( !bOk ) { vgui::MessageBox *pError = new vgui::MessageBox( "#AssetBuilder_CannotRenameSourceFiles", "#AssetBuilder_CannotRenameSourceFilesText", this ); pError->DoModal(); return false; }
CDmElement *pRoot = GetElement< CDmElement >( g_pDataModel->GetFileRoot( pMakefile->GetFileId() ) ); if ( !pRoot ) { pRoot = pMakefile; } bOk = g_pDataModel->SaveToFile( pFileName, NULL, g_pDataModel->GetDefaultEncoding( pFileFormat ), pFileFormat, pRoot ); m_pAssetBuilder->Refresh(); return bOk; }
//-----------------------------------------------------------------------------
// Updates the file name
//-----------------------------------------------------------------------------
void CAssetBuilderFrame::UpdateFileName( ) { CDmeMakefile *pMakeFile = m_pAssetBuilder->GetMakeFile(); if ( !pMakeFile ) { SetTitle( m_TitleString.Get(), true ); return; }
DmeMakefileType_t *pMakefileType = pMakeFile->GetMakefileType();
DmFileId_t fileId = pMakeFile->GetFileId(); const char *pFileName = ( fileId != DMFILEID_INVALID ) ? g_pDataModel->GetFileName( fileId ) : "<unnamed>"; if ( !pFileName || !pFileName[0] ) { pFileName = "<unnamed>"; }
char pBuf[2*MAX_PATH]; if ( m_TitleString.Get() ) { Q_snprintf( pBuf, sizeof(pBuf), "%s - %s - %s%s", m_TitleString.Get(), pMakefileType->m_pHumanReadableName, pFileName, pMakeFile->IsDirty() ? " *" : "" ); } else { Q_snprintf( pBuf, sizeof(pBuf), "%s - s%s", pMakefileType->m_pHumanReadableName, pFileName, pMakeFile->IsDirty() ? " *" : "" ); } SetTitle( pBuf, true ); }
//-----------------------------------------------------------------------------
// Marks the file as dirty (or not)
//-----------------------------------------------------------------------------
void CAssetBuilderFrame::SetDirty( bool bDirty ) { CDmeMakefile *pMakeFile = m_pAssetBuilder->GetMakeFile(); if ( pMakeFile && ( pMakeFile->IsDirty() != bDirty ) ) { pMakeFile->SetDirty( bDirty );
// Necessary because we draw a * if it's dirty before the name
UpdateFileName(); } }
//-----------------------------------------------------------------------------
// Called when the asset builder changes something
//-----------------------------------------------------------------------------
void CAssetBuilderFrame::OnDmeElementChanged() { SetDirty( true ); }
//-----------------------------------------------------------------------------
// Resets the state
//-----------------------------------------------------------------------------
void CAssetBuilderFrame::Reset( CDmeMakefile *pMakeFile ) { // NOTE: Don't need to call SetDirty because we call UpdateFileName below
m_pAssetBuilder->SetRootMakefile( pMakeFile ); UpdateFileName(); }
//-----------------------------------------------------------------------------
// Called when the file open dialog for selecting the new asset name is selected
//-----------------------------------------------------------------------------
void CAssetBuilderFrame::OnPerformFileNew( KeyValues *kv ) { const char *pMakefileType = kv->GetString( "makefileType" ); const char *pFileName = kv->GetString( "fileName" ); CDmeMakefile *pMakeFile; { DmFileId_t fileid = g_pDataModel->FindOrCreateFileId( pFileName ); CDisableUndoScopeGuard guard; pMakeFile = CreateElement< CDmeMakefile >( pMakefileType, pFileName, fileid ); } if ( !pMakeFile ) return;
pMakeFile->SetFileName( pFileName ); Reset( pMakeFile ); SetDirty( true ); }
//-----------------------------------------------------------------------------
// Called when the file open dialog for browsing source files selects something
//-----------------------------------------------------------------------------
void CAssetBuilderFrame::OnFileSelected( KeyValues *kv ) { const char *pFileName = kv->GetString( "fullpath", NULL ); if ( !pFileName ) return;
KeyValues *pDialogKeys = kv->FindKey( "OnFileNew" ); if ( pDialogKeys ) { KeyValues *pOkCommand = new KeyValues( "PerformFileNew", "makefileType", pDialogKeys->GetString( "makefileType" ) ); pOkCommand->SetString( "fileName", pFileName ); OverwriteFileDialog( this, pFileName, pOkCommand ); return; } }
//-----------------------------------------------------------------------------
// Called by the picker popped up in OnFileNew
//-----------------------------------------------------------------------------
void CAssetBuilderFrame::OnPicked( KeyValues *kv ) { const char *pValue = kv->GetString( "choice" );
CDisableUndoScopeGuard guard; CDmeMakefile *pMakeFile = GetElement< CDmeMakefile >( g_pDataModel->CreateElement( pValue, "unnamed", DMFILEID_INVALID ) ); if ( !pMakeFile ) return;
DmeMakefileType_t *pType = pMakeFile->GetMakefileType();
char pContext[MAX_PATH]; Q_snprintf( pContext, sizeof(pContext), "asset_builder_session_%s", pType->m_pTypeName );
char pStartingDir[MAX_PATH]; pMakeFile->GetDefaultDirectory( pType->m_pDefaultDirectoryID, pStartingDir, sizeof(pStartingDir) ); g_pFullFileSystem->CreateDirHierarchy( pStartingDir );
char pTitle[MAX_PATH]; Q_snprintf( pTitle, sizeof(pTitle), "Select %s File Name", pType->m_pHumanReadableName );
KeyValues *pDialogKeys = new KeyValues( "OnFileNew", "makefileType", pValue ); FileOpenDialog *pDialog = new FileOpenDialog( this, pTitle, false, pDialogKeys ); pDialog->SetStartDirectoryContext( pContext, pStartingDir ); pDialog->AddFilter( pType->m_pFileFilter, pType->m_pFileFilterString, true ); pDialog->AddActionSignalTarget( this ); pDialog->DoModal( false ); DestroyElement( pMakeFile ); }
//-----------------------------------------------------------------------------
// Called by the file open state machine when an operation has completed
//-----------------------------------------------------------------------------
void CAssetBuilderFrame::OnFileStateMachineFinished( KeyValues *pKeyValues ) { KeyValues *pNewFile = pKeyValues->FindKey( "FileNew" ); if ( pNewFile ) { if ( pKeyValues->GetInt( "wroteFile", 0 ) != 0 ) { SetDirty( false ); UpdateFileName(); } if ( pKeyValues->GetInt( "completionState", FileOpenStateMachine::IN_PROGRESS ) == FileOpenStateMachine::SUCCESSFUL ) { ShowNewAssetPicker(); } return; }
KeyValues *pSaveFile = pKeyValues->FindKey( "FileSave" ); if ( pSaveFile ) { if ( pKeyValues->GetInt( "wroteFile", 0 ) != 0 ) { SetDirty( false ); UpdateFileName(); } return; } }
//-----------------------------------------------------------------------------
// Shows a picker for creating a new asset
//-----------------------------------------------------------------------------
void CAssetBuilderFrame::ShowNewAssetPicker( ) { BuildAssetTypeList();
// Create a list indicating which type of asset to create
CPickerFrame *pPicker = new CPickerFrame( this, "Select Asset Type", "Asset Type", "assetType" ); pPicker->DoModal( s_AssetTypes ); }
//-----------------------------------------------------------------------------
// Creates a new file
//-----------------------------------------------------------------------------
void CAssetBuilderFrame::OnFileNew( ) { CDmeMakefile *pMakeFile = m_pAssetBuilder->GetMakeFile(); if ( pMakeFile && pMakeFile->IsDirty() ) { KeyValues *pContextKeyValues = new KeyValues( "FileNew" ); const char *pFileName = g_pDataModel->GetFileName( pMakeFile->GetFileId() ); m_pFileOpenStateMachine->SaveFile( pContextKeyValues, pFileName, ASSET_FILE_FORMAT, FOSM_SHOW_PERFORCE_DIALOGS | FOSM_SHOW_SAVE_QUERY ); return; }
ShowNewAssetPicker(); }
void CAssetBuilderFrame::OnFileOpen( ) { int nFlags = 0; const char *pFileName = NULL; CDmeMakefile *pMakeFile = m_pAssetBuilder->GetMakeFile(); if ( pMakeFile && pMakeFile->IsDirty() ) { nFlags = FOSM_SHOW_PERFORCE_DIALOGS | FOSM_SHOW_SAVE_QUERY; pFileName = g_pDataModel->GetFileName( pMakeFile->GetFileId() ); } KeyValues *pContextKeyValues = new KeyValues( "FileOpen" ); m_pFileOpenStateMachine->OpenFile( ASSET_FILE_FORMAT, pContextKeyValues, pFileName, NULL, nFlags ); }
void CAssetBuilderFrame::OnFileSave( ) { CDmeMakefile *pMakeFile = m_pAssetBuilder->GetMakeFile(); if ( !pMakeFile ) return;
KeyValues *pContextKeyValues = new KeyValues( "FileSave" ); const char *pFileName = g_pDataModel->GetFileName( pMakeFile->GetFileId() ); m_pFileOpenStateMachine->SaveFile( pContextKeyValues, pFileName, ASSET_FILE_FORMAT, FOSM_SHOW_PERFORCE_DIALOGS ); }
void CAssetBuilderFrame::OnFileSaveAs( ) { CDmeMakefile *pMakeFile = m_pAssetBuilder->GetMakeFile(); if ( !pMakeFile ) return;
KeyValues *pContextKeyValues = new KeyValues( "FileSave" ); m_pFileOpenStateMachine->SaveFile( pContextKeyValues, NULL, ASSET_FILE_FORMAT, FOSM_SHOW_PERFORCE_DIALOGS ); }
|