You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1725 lines
54 KiB
1725 lines
54 KiB
//========= Copyright 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" ) ); |
|
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" ) ); |
|
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" ) ); |
|
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->SetDeleteSelfOnClose( 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->SetDeleteSelfOnClose( 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" ) ); |
|
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->SetDeleteSelfOnClose( 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 ); |
|
} |
|
|
|
|
|
|