1312 lines
33 KiB
C++
1312 lines
33 KiB
C++
//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======
|
|
//
|
|
// Purpose:
|
|
//
|
|
//=============================================================================
|
|
|
|
#include "matsys_controls/particlepicker.h"
|
|
#include "tier1/keyvalues.h"
|
|
#include "tier1/utldict.h"
|
|
#include "filesystem.h"
|
|
#include "studio.h"
|
|
#include "matsys_controls/matsyscontrols.h"
|
|
#include "matsys_controls/mdlpanel.h"
|
|
#include "vgui_controls/Splitter.h"
|
|
#include "vgui_controls/ComboBox.h"
|
|
#include "vgui_controls/Button.h"
|
|
#include "vgui_controls/PropertySheet.h"
|
|
#include "vgui_controls/MessageBox.h"
|
|
#include "vgui_controls/MenuItem.h"
|
|
#include "vgui_controls/MenuButton.h"
|
|
#include "vgui_controls/PropertyPage.h"
|
|
#include "vgui_controls/CheckButton.h"
|
|
#include "vgui_controls/ScrollableEditablePanel.h"
|
|
#include "vgui_controls/ScrollBar.h"
|
|
#include "vgui_controls/Tooltip.h"
|
|
#include "vgui/IVGui.h"
|
|
#include "vgui/IInput.h"
|
|
#include "vgui/ISurface.h"
|
|
#include "vgui/Cursor.h"
|
|
#include "matsys_controls/assetpicker.h"
|
|
#include "dmxloader/dmxloader.h"
|
|
#include "particles/particles.h"
|
|
|
|
#include "vstdlib/jobthread.h"
|
|
|
|
#include "dme_controls/particlesystempanel.h"
|
|
|
|
// memdbgon must be the last include file in a .cpp file!!!
|
|
#include "tier0/memdbgon.h"
|
|
|
|
using namespace vgui;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
struct CachedParticleInfo_t
|
|
{
|
|
CachedAssetInfo_t m_AssetInfo;
|
|
CUtlString m_FileName;
|
|
};
|
|
|
|
struct PCFToLoad_t
|
|
{
|
|
CUtlString m_FileName;
|
|
int m_ModId;
|
|
};
|
|
|
|
static CUtlVector<PCFToLoad_t> sCacheUnloadedPCFs;
|
|
static CUtlVector<CachedParticleInfo_t> sCacheParticleList;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
class CParticleSnapshotPanel: public vgui::EditablePanel
|
|
{
|
|
DECLARE_CLASS_SIMPLE( CParticleSnapshotPanel, vgui::EditablePanel );
|
|
|
|
public:
|
|
CParticleSnapshotPanel( vgui::Panel *pParent, const char *pName );
|
|
virtual ~CParticleSnapshotPanel( );
|
|
MESSAGE_FUNC( OnSetFocus, "SetFocus" );
|
|
MESSAGE_FUNC_CHARPTR( OnParticleSystemSelected, "ParticleSystemSelected", SystemName );
|
|
|
|
virtual void OnMousePressed(MouseCode code);
|
|
virtual void OnMouseDoublePressed(MouseCode code);
|
|
|
|
virtual void ApplySchemeSettings(IScheme *pScheme);
|
|
|
|
virtual void Paint();
|
|
|
|
void SetParticleSystem( const char *szSystemName, int nId );
|
|
void Simulate();
|
|
void SetSelected( bool bSelected );
|
|
const char *GetSystemName() const;
|
|
bool IsSelected();
|
|
CParticleCollection* GetSystem();
|
|
int GetId();
|
|
|
|
void SetPreviewEnabled( bool bEnabled );
|
|
|
|
void UpdateRelatives( IImage *pIcon, CUtlVector<CParticleSnapshotGrid::PSysRelativeInfo_t>& sysParents, CUtlVector<CParticleSnapshotGrid::PSysRelativeInfo_t>& sysChildren );
|
|
|
|
protected:
|
|
CParticleSystemPanel *m_pParticlePanel;
|
|
MenuButton *m_pParentsButton;
|
|
MenuButton *m_pChildrenButton;
|
|
vgui::Label *m_pLabel;
|
|
int m_nSystemIndex;
|
|
CUtlString m_SystemName;
|
|
bool m_bSelected;
|
|
int m_nSystemId;
|
|
bool m_bPreviewEnabled;
|
|
|
|
Color m_SelectedBgColor;
|
|
Color m_SelectedTextColor;
|
|
};
|
|
|
|
CParticleSnapshotPanel::CParticleSnapshotPanel( vgui::Panel *pParent, const char *pName ):
|
|
BaseClass(pParent,pName)
|
|
{
|
|
m_bSelected = false;
|
|
m_bPreviewEnabled = true;
|
|
|
|
m_pParticlePanel = new CParticleSystemPanel( this, pName );
|
|
m_pParticlePanel->SetSelfSimulation(false);
|
|
m_pParticlePanel->SetGridColor( 128, 128, 128 );
|
|
m_pParticlePanel->RenderGrid(true);
|
|
m_pParticlePanel->SetParentMouseNotify(true);
|
|
m_pParticlePanel->EnableAutoViewing(true);
|
|
|
|
m_pLabel = new Label( this, "SystemLabel", "Unnamed" );
|
|
m_pLabel->SetContentAlignment( Label::a_center );
|
|
m_pLabel->SetPaintBackgroundEnabled( false );
|
|
m_pLabel->SetMouseInputEnabled( false );
|
|
|
|
CBoxSizer *pSizer = new CBoxSizer(ESLD_VERTICAL);
|
|
pSizer->AddPanel( m_pParticlePanel, SizerAddArgs_t().Expand( 1.0f ).Padding( 5 ) );
|
|
|
|
{
|
|
CBoxSizer *pRow = new CBoxSizer(ESLD_HORIZONTAL);
|
|
|
|
m_pParentsButton = new MenuButton( this, "ParentsButton", "P" );
|
|
pRow->AddPanel( m_pParentsButton, SizerAddArgs_t().Expand( 0.0f ).Padding( 0 ) );
|
|
|
|
m_pChildrenButton = new MenuButton( this, "ChildrenButton", "C" );
|
|
pRow->AddPanel( m_pChildrenButton, SizerAddArgs_t().Expand( 0.0f ).Padding( 0 ) );
|
|
|
|
pRow->AddPanel( m_pLabel, SizerAddArgs_t().Expand( 0.0f ).Padding( 2 ) );
|
|
|
|
pSizer->AddSizer( pRow, SizerAddArgs_t().Expand( 0.0f ).Padding( 5 ) );
|
|
}
|
|
|
|
pSizer->AddSpacer( SizerAddArgs_t().Padding( 5 ) );
|
|
SetSizer( pSizer );
|
|
InvalidateLayout(true);
|
|
|
|
m_pParticlePanel->ResetView();
|
|
m_pParticlePanel->LookAt( 50.f );
|
|
}
|
|
|
|
void CParticleSnapshotPanel::SetPreviewEnabled( bool bEnabled )
|
|
{
|
|
m_bPreviewEnabled = bEnabled;
|
|
m_pParticlePanel->SetVisible(m_bPreviewEnabled);
|
|
InvalidateLayout();
|
|
}
|
|
|
|
CParticleSnapshotPanel::~CParticleSnapshotPanel( )
|
|
{
|
|
|
|
}
|
|
|
|
void CParticleSnapshotPanel::OnParticleSystemSelected( const char *SystemName )
|
|
{
|
|
// hand the signal up
|
|
PostActionSignal( new KeyValues( "ParticleSystemSelected", "SystemName", SystemName ) );
|
|
}
|
|
|
|
int CParticleSnapshotPanel::GetId()
|
|
{
|
|
return m_nSystemId;
|
|
}
|
|
|
|
CParticleCollection* CParticleSnapshotPanel::GetSystem()
|
|
{
|
|
return m_pParticlePanel->GetParticleSystem();
|
|
}
|
|
|
|
void CParticleSnapshotPanel::OnSetFocus()
|
|
{
|
|
BaseClass::OnSetFocus();
|
|
}
|
|
|
|
void CParticleSnapshotPanel::UpdateRelatives( IImage *pIcon, CUtlVector<CParticleSnapshotGrid::PSysRelativeInfo_t>& sysParents, CUtlVector<CParticleSnapshotGrid::PSysRelativeInfo_t>& sysChildren )
|
|
{
|
|
char countBuf[8];
|
|
|
|
// parents
|
|
if ( sysParents.Count() )
|
|
{
|
|
Menu *pParentsMenu = new Menu(GetParent()->GetParent(), "ParentsMenu");
|
|
|
|
for ( int i = 0; i < sysParents.Count(); ++i )
|
|
{
|
|
int nItemIdx = pParentsMenu->AddMenuItem( sysParents[i].relName, new KeyValues( "ParticleSystemSelected", "SystemName", sysParents[i].relName ), this );
|
|
pParentsMenu->GetMenuItem(nItemIdx)->SetEnabled( sysParents[i].bVisibleInCurrentView );
|
|
}
|
|
|
|
m_pParentsButton->SetEnabled( true );
|
|
|
|
V_snprintf( countBuf, sizeof(countBuf), "%d", sysParents.Count() );
|
|
m_pParentsButton->SetText( countBuf );
|
|
|
|
m_pParentsButton->SetMenu( pParentsMenu );
|
|
}
|
|
else
|
|
{
|
|
m_pParentsButton->SetEnabled( false );
|
|
m_pParentsButton->SetText( "P" );
|
|
m_pParentsButton->SetMenu( NULL );
|
|
}
|
|
|
|
// children
|
|
if ( sysChildren.Count() )
|
|
{
|
|
Menu *pChildrenMenu = new Menu(GetParent()->GetParent(), "ChildrenMenu");
|
|
|
|
for ( int i = 0; i < sysChildren.Count(); ++i )
|
|
{
|
|
int nItemIdx = pChildrenMenu->AddMenuItem( sysChildren[i].relName, new KeyValues( "ParticleSystemSelected", "SystemName", sysChildren[i].relName ), this );
|
|
pChildrenMenu->GetMenuItem(nItemIdx)->SetEnabled( sysChildren[i].bVisibleInCurrentView );
|
|
}
|
|
|
|
m_pChildrenButton->SetEnabled( true );
|
|
|
|
V_snprintf( countBuf, sizeof(countBuf), "%d", sysChildren.Count() );
|
|
m_pChildrenButton->SetText( countBuf );
|
|
|
|
m_pChildrenButton->SetMenu( pChildrenMenu );
|
|
}
|
|
else
|
|
{
|
|
m_pChildrenButton->SetEnabled( false );
|
|
m_pChildrenButton->SetText( "C" );
|
|
m_pChildrenButton->SetMenu( NULL );
|
|
}
|
|
}
|
|
|
|
void CParticleSnapshotPanel::OnMousePressed( MouseCode code )
|
|
{
|
|
BaseClass::OnMousePressed( code );
|
|
if ( code == MOUSE_LEFT )
|
|
{
|
|
if ( input()->IsKeyDown(KEY_LSHIFT) || input()->IsKeyDown(KEY_RSHIFT) )
|
|
{
|
|
PostActionSignal( new KeyValues( "ParticleSystemShiftSelected", "SystemName", m_SystemName ) );
|
|
}
|
|
else if ( input()->IsKeyDown(KEY_LCONTROL) || input()->IsKeyDown(KEY_RCONTROL) )
|
|
{
|
|
PostActionSignal( new KeyValues( "ParticleSystemCtrlSelected", "SystemName", m_SystemName ) );
|
|
}
|
|
else
|
|
{
|
|
PostActionSignal( new KeyValues( "ParticleSystemSelected", "SystemName", m_SystemName ) );
|
|
}
|
|
}
|
|
}
|
|
|
|
void CParticleSnapshotPanel::OnMouseDoublePressed( MouseCode code )
|
|
{
|
|
BaseClass::OnMouseDoublePressed( code );
|
|
|
|
if ( code == MOUSE_LEFT )
|
|
{
|
|
PostActionSignal( new KeyValues( "ParticleSystemPicked", "SystemName", m_SystemName ) );
|
|
}
|
|
}
|
|
|
|
void CParticleSnapshotPanel::SetParticleSystem( const char *szSystemName, int nId )
|
|
{
|
|
bool bSameSystem = !V_strcmp( m_SystemName, szSystemName );
|
|
|
|
m_SystemName = szSystemName;
|
|
m_nSystemId = nId;
|
|
|
|
if ( !bSameSystem || m_pParticlePanel->GetParticleSystem() == NULL )
|
|
{
|
|
m_pParticlePanel->SetParticleSystem(szSystemName);
|
|
m_pParticlePanel->SetControlPointValue( 0, Vector(0.f,0.f,0.f) );
|
|
m_pParticlePanel->SetControlPointValue( 1, Vector(100.f,0.f,0.f) );
|
|
m_pParticlePanel->LookAt( 50.f );
|
|
|
|
m_pLabel->SetText( m_SystemName );
|
|
|
|
m_pParticlePanel->ResetView();
|
|
}
|
|
|
|
if ( !m_pParticlePanel->GetParticleSystem() )
|
|
{
|
|
CUtlString errStr = "ERROR: ";
|
|
errStr += m_SystemName;
|
|
m_pLabel->SetText( errStr );
|
|
m_pParticlePanel->SetBackgroundColor( 64,0,0 );
|
|
}
|
|
else
|
|
{
|
|
m_pParticlePanel->SetBackgroundColor( 32, 32, 32 );
|
|
}
|
|
|
|
InvalidateLayout();
|
|
}
|
|
|
|
void CParticleSnapshotPanel::ApplySchemeSettings(IScheme *pScheme)
|
|
{
|
|
BaseClass::ApplySchemeSettings(pScheme);
|
|
|
|
m_SelectedBgColor = pScheme->GetColor( "ListPanel.SelectedBgColor", Color(255, 255, 255, 0) );
|
|
m_SelectedTextColor = pScheme->GetColor( "ListPanel.SelectedTextColor", Color(255, 255, 255, 0) );
|
|
|
|
// override the colors because alpha = 0 is bad
|
|
Color btnFgColor = pScheme->GetColor("Button.TextColor", Color(255, 255, 255, 255) );
|
|
Color btnBgColor = pScheme->GetColor("ListPanel.BgColor", Color(128, 128, 128, 255) );
|
|
|
|
m_pChildrenButton->SetDefaultColor( btnFgColor, btnBgColor );
|
|
m_pChildrenButton->SetArmedColor( btnFgColor, btnBgColor );
|
|
m_pChildrenButton->SetDepressedColor( btnFgColor, btnBgColor );
|
|
|
|
m_pParentsButton->SetDefaultColor( btnFgColor, btnBgColor );
|
|
m_pParentsButton->SetArmedColor( btnFgColor, btnBgColor );
|
|
m_pParentsButton->SetDepressedColor( btnFgColor, btnBgColor );
|
|
}
|
|
|
|
void CParticleSnapshotPanel::Simulate()
|
|
{
|
|
if( !m_bPreviewEnabled )
|
|
{
|
|
return;
|
|
}
|
|
|
|
Panel* pParent = GetParent();
|
|
|
|
int x0,y0,x1, y1;
|
|
GetClipRect( x0, y0, x1, y1 );
|
|
|
|
int nPX0, nPY0, nPX1, nPY1;
|
|
pParent->GetClipRect( nPX0, nPY0, nPX1, nPY1 );
|
|
|
|
if( x1 < nPX0 || x0 > nPX1 ||
|
|
y1 < nPY0 || y0 > nPY1 )
|
|
{
|
|
// out of bounds
|
|
return;
|
|
}
|
|
|
|
m_pParticlePanel->Simulate();
|
|
}
|
|
|
|
void CParticleSnapshotPanel::Paint()
|
|
{
|
|
BaseClass::Paint();
|
|
|
|
if( m_bSelected )
|
|
{
|
|
DrawBox( 1, 1, GetWide()-2, GetTall()-2, m_SelectedBgColor, 1.0f );
|
|
}
|
|
|
|
if( m_bPreviewEnabled )
|
|
{
|
|
// black border around the preview
|
|
int x, y, w, t;
|
|
m_pParticlePanel->GetBounds( x, y, w, t );
|
|
surface()->DrawSetColor( Color(0,0,0,255) );
|
|
surface()->DrawOutlinedRect( x-1, y-1, x+w+1, y+t+1 );
|
|
}
|
|
}
|
|
|
|
const char *CParticleSnapshotPanel::GetSystemName() const
|
|
{
|
|
return m_SystemName;
|
|
}
|
|
|
|
void CParticleSnapshotPanel::SetSelected( bool bSelected )
|
|
{
|
|
m_bSelected = bSelected;
|
|
}
|
|
|
|
bool CParticleSnapshotPanel::IsSelected( )
|
|
{
|
|
return m_bSelected;
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Particle Snapshot Grid
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
const int MIN_PANEL_SIZE = 200;
|
|
const int MAX_PANEL_SIZE = 250;
|
|
const int MIN_NUM_COLS = 1;
|
|
const int OFFSET = 4;
|
|
const int TOOLBAR_HEIGHT = 30;
|
|
|
|
CParticleSnapshotGrid::CParticleSnapshotGrid( vgui::Panel *pParent, const char *pName ):
|
|
BaseClass(pParent,pName)
|
|
{
|
|
m_pRelativesImgNeither = scheme()->GetImage( "tools/particles/icon_particles_rel_neither", false );
|
|
m_pRelativesImgPOnly = scheme()->GetImage( "tools/particles/icon_particles_rel_ponly", false );
|
|
m_pRelativesImgCOnly = scheme()->GetImage( "tools/particles/icon_particles_rel_conly", false );
|
|
m_pRelativesImgBoth = scheme()->GetImage( "tools/particles/icon_particles_rel_both", false );
|
|
|
|
m_pScrollBar = new ScrollBar( this, "ScrollBar", true );
|
|
m_pScrollBar->SetWide( 16 );
|
|
m_pScrollBar->SetAutoResize( PIN_TOPRIGHT, AUTORESIZE_DOWN, 0, TOOLBAR_HEIGHT, -16, 0 );
|
|
m_pScrollBar->AddActionSignalTarget( this );
|
|
|
|
m_pScrollPanel = new Panel( this, "ScrollPanel" );
|
|
m_pScrollPanel->SetAutoResize( PIN_TOPLEFT, AUTORESIZE_DOWNANDRIGHT, 0, TOOLBAR_HEIGHT, -16, 0 );
|
|
m_pScrollPanel->DisableMouseInputForThisPanel(true);
|
|
|
|
m_pToolPanel = new Panel( this, "ToolPanel" );
|
|
m_pToolPanel->SetTall(TOOLBAR_HEIGHT);
|
|
m_pToolPanel->SetAutoResize( PIN_TOPLEFT, AUTORESIZE_RIGHT, 0, 0, -16, 0 );
|
|
|
|
m_pToolPanel->SetSizer( new CBoxSizer(ESLD_HORIZONTAL) );
|
|
m_pPreviewCheckbox = new CheckButton( m_pToolPanel, "PreviewCheckbox", "Show Previews" );
|
|
m_pPreviewCheckbox->SetSelected(true);
|
|
m_pPreviewCheckbox->AddActionSignalTarget( this );
|
|
m_pToolPanel->GetSizer()->AddPanel( m_pPreviewCheckbox, SizerAddArgs_t() );
|
|
|
|
m_pNoSystemsLabel = new Label( m_pScrollPanel, "NoSystemsLabel", "<No Systems>" );
|
|
|
|
m_nCurrentColCount = MIN_NUM_COLS;
|
|
m_nMostRecentSelectedIndex = -1;
|
|
|
|
vgui::ivgui()->AddTickSignal( GetVPanel(), 0 );
|
|
|
|
SetKeyBoardInputEnabled(true);
|
|
}
|
|
|
|
void CParticleSnapshotGrid::MapSystemRelatives( )
|
|
{
|
|
// somewhat slow, but doesn't get called frequently or with large enough data sets to optimize
|
|
|
|
m_ParentsMap.RemoveAll();
|
|
m_ParentsMap.AddMultipleToTail( m_Panels.Count() );
|
|
m_ChildrenMap.RemoveAll();
|
|
m_ChildrenMap.AddMultipleToTail( m_Panels.Count() );
|
|
|
|
for ( int i = 0; i < g_pParticleSystemMgr->GetParticleSystemCount(); i++ )
|
|
{
|
|
const char *pPotentialParentName = g_pParticleSystemMgr->GetParticleSystemNameFromIndex(i);
|
|
CParticleSystemDefinition *pPotentialParent = g_pParticleSystemMgr->FindParticleSystem( pPotentialParentName );
|
|
|
|
//////////////////////
|
|
// see if this system is visible
|
|
int nParentVisibileIndex = -1;
|
|
for ( int p = 0; p < m_Panels.Count(); ++p )
|
|
{
|
|
CParticleCollection *pVisible = m_Panels[p]->GetSystem();
|
|
|
|
if( pVisible == NULL )
|
|
continue;
|
|
|
|
if ( pVisible->m_pDef == pPotentialParent )
|
|
{
|
|
nParentVisibileIndex = p;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//////////////////////
|
|
// see if this system is a parent of any visible system; check all its children
|
|
for ( int c = 0; c < pPotentialParent->m_Children.Count(); ++c )
|
|
{
|
|
CParticleSystemDefinition *pChild = NULL;
|
|
|
|
if ( pPotentialParent->m_Children[c].m_bUseNameBasedLookup )
|
|
{
|
|
pChild = g_pParticleSystemMgr->FindParticleSystem( pPotentialParent->m_Children[c].m_Name );
|
|
}
|
|
else
|
|
{
|
|
pChild = g_pParticleSystemMgr->FindParticleSystem( pPotentialParent->m_Children[c].m_Id );
|
|
}
|
|
|
|
if ( pChild == NULL )
|
|
continue;
|
|
|
|
//////////////////////
|
|
// is the child visible?
|
|
int nChildVisibleIndex = -1;
|
|
|
|
for ( int p = 0; p < m_Panels.Count(); ++p )
|
|
{
|
|
CParticleCollection *pVisible = m_Panels[p]->GetSystem();
|
|
|
|
if( pVisible == NULL )
|
|
continue;
|
|
|
|
if ( pVisible->m_pDef == pChild )
|
|
{
|
|
// this child is visible; add entry, and mark parent if visible
|
|
PSysRelativeInfo_t parentInfo;
|
|
parentInfo.relName = pPotentialParent->GetName();
|
|
parentInfo.bVisibleInCurrentView = ( nParentVisibileIndex != -1 );
|
|
m_ParentsMap[p].AddToTail( parentInfo );
|
|
|
|
nChildVisibleIndex = p;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( nParentVisibileIndex != -1 )
|
|
{
|
|
// this parent is visible; add entry, and mark child if visible
|
|
PSysRelativeInfo_t childInfo;
|
|
childInfo.relName = pChild->GetName();
|
|
childInfo.bVisibleInCurrentView = ( nChildVisibleIndex != -1 );
|
|
m_ChildrenMap[nParentVisibileIndex].AddToTail( childInfo );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void CParticleSnapshotGrid::UpdatePanelRelatives( int nIndex )
|
|
{
|
|
CParticleSnapshotPanel* pPanel = m_Panels[nIndex];
|
|
CUtlVector<PSysRelativeInfo_t>& sysParents = m_ParentsMap[nIndex];
|
|
CUtlVector<PSysRelativeInfo_t>& sysChildren = m_ChildrenMap[nIndex];
|
|
|
|
IImage *pImg = m_pRelativesImgNeither;
|
|
|
|
if ( sysParents.Count() && sysChildren.Count() )
|
|
{
|
|
pImg = m_pRelativesImgBoth;
|
|
}
|
|
else if ( sysParents.Count() )
|
|
{
|
|
pImg = m_pRelativesImgPOnly;
|
|
}
|
|
else if ( sysChildren.Count() )
|
|
{
|
|
pImg = m_pRelativesImgCOnly;
|
|
}
|
|
|
|
pPanel->UpdateRelatives( pImg, sysParents, sysChildren );
|
|
}
|
|
|
|
void CParticleSnapshotGrid::OnScrollBarSliderMoved()
|
|
{
|
|
LayoutScrolled();
|
|
}
|
|
|
|
void CParticleSnapshotGrid::OnCheckButtonChecked( KeyValues *kv )
|
|
{
|
|
SetAllPreviewEnabled( m_pPreviewCheckbox->IsSelected() );
|
|
}
|
|
|
|
void CParticleSnapshotGrid::ApplySchemeSettings(IScheme *pScheme)
|
|
{
|
|
BaseClass::ApplySchemeSettings(pScheme);
|
|
}
|
|
|
|
void CParticleSnapshotGrid::UpdateAllRelatives()
|
|
{
|
|
MapSystemRelatives();
|
|
|
|
for ( int i = 0; i < m_Panels.Count(); ++i )
|
|
{
|
|
UpdatePanelRelatives( i );
|
|
}
|
|
}
|
|
|
|
void CParticleSnapshotGrid::OnMousePressed(MouseCode code)
|
|
{
|
|
BaseClass::OnMousePressed( code );
|
|
|
|
SelectSystem("",false,false);
|
|
PostActionSignal( new KeyValues( "ParticleSystemSelectionChanged" ) );
|
|
}
|
|
|
|
static int PanelSortHelperI( CParticleSnapshotPanel *const *a, CParticleSnapshotPanel * const *b )
|
|
{
|
|
return V_stricmp((*a)->GetSystemName(),(*b)->GetSystemName());
|
|
}
|
|
|
|
void CParticleSnapshotGrid::SetParticleList( const CUtlVector<const char *>& ParticleNames )
|
|
{
|
|
bool bPreviewEnabled = m_pPreviewCheckbox->IsSelected();
|
|
|
|
// might have too many panels
|
|
while ( m_Panels.Count() > ParticleNames.Count() )
|
|
{
|
|
delete m_Panels.Tail();
|
|
m_Panels.RemoveMultipleFromTail(1);
|
|
}
|
|
|
|
// might have too few panels
|
|
while ( m_Panels.Count() < ParticleNames.Count() )
|
|
{
|
|
char szPanelName[32];
|
|
V_snprintf( szPanelName, sizeof(szPanelName), "ParticlePanel%d", m_Panels.Count() );
|
|
CParticleSnapshotPanel *pPanel = new CParticleSnapshotPanel( m_pScrollPanel, szPanelName );
|
|
pPanel->SetPreviewEnabled(bPreviewEnabled);
|
|
pPanel->AddActionSignalTarget(this);
|
|
|
|
m_Panels.AddToTail( pPanel );
|
|
}
|
|
|
|
// reinit them all, with the new system names
|
|
for ( int i = 0; i < m_Panels.Count(); ++i )
|
|
{
|
|
if( i < ParticleNames.Count() )
|
|
{
|
|
m_Panels[i]->SetParticleSystem( ParticleNames[i], i );
|
|
}
|
|
else
|
|
{
|
|
m_Panels[i]->SetParticleSystem( "", i );
|
|
}
|
|
|
|
m_Panels[i]->SetSelected(false);
|
|
}
|
|
|
|
// now sort the panels however we want
|
|
m_Panels.Sort( PanelSortHelperI );
|
|
|
|
UpdateAllRelatives();
|
|
|
|
m_nMostRecentSelectedIndex = -1;
|
|
|
|
InvalidateLayout();
|
|
}
|
|
|
|
int CParticleSnapshotGrid::GetPanelWide()
|
|
{
|
|
int nWide = GetWide() - OFFSET*2 - m_pScrollBar->GetWide();
|
|
return MIN(MAX_PANEL_SIZE,nWide/m_nCurrentColCount);
|
|
}
|
|
|
|
int CParticleSnapshotGrid::GetPanelTall()
|
|
{
|
|
if ( m_pPreviewCheckbox->IsSelected() )
|
|
{
|
|
return GetPanelWide();
|
|
}
|
|
else
|
|
{
|
|
return 30; // TODO: This shouldn't be hard-coded :|
|
|
}
|
|
}
|
|
|
|
void CParticleSnapshotGrid::PerformLayout()
|
|
{
|
|
BaseClass::PerformLayout();
|
|
|
|
int nWide = GetWide() - OFFSET*2 - m_pScrollBar->GetWide();
|
|
m_nCurrentColCount = MAX(MIN_NUM_COLS,nWide/MIN_PANEL_SIZE);
|
|
|
|
LayoutScrolled();
|
|
}
|
|
|
|
void CParticleSnapshotGrid::SetAllPreviewEnabled( bool bEnabled )
|
|
{
|
|
for ( int i = 0; i < m_Panels.Count(); ++i )
|
|
{
|
|
m_Panels[i]->SetPreviewEnabled(bEnabled);
|
|
}
|
|
|
|
InvalidateLayout(true);
|
|
LayoutScrolled();
|
|
}
|
|
|
|
void CParticleSnapshotGrid::LayoutScrolled()
|
|
{
|
|
// int nWide = GetWide() - m_pScrollBar->GetWide();
|
|
int nPanels = m_Panels.Count();
|
|
int nRows = (nPanels+m_nCurrentColCount-1)/m_nCurrentColCount; // panels/cols rounded up
|
|
// int nRemainder = (nWide - m_nCurrentColCount*m_nCurrentPanelSize - OFFSET*2);
|
|
int nScrollPos = m_pScrollBar->GetValue();
|
|
|
|
int nPanelW = GetPanelWide();
|
|
int nPanelT = GetPanelTall();
|
|
|
|
m_pScrollBar->SetRange( 0, nRows*nPanelT+OFFSET*2 );
|
|
m_pScrollBar->SetRangeWindow( m_pScrollPanel->GetTall() );
|
|
|
|
for( int r = 0; r < nRows; ++r )
|
|
{
|
|
for( int c = 0; c < m_nCurrentColCount; ++c )
|
|
{
|
|
int i = c + r*m_nCurrentColCount;
|
|
if( i >= nPanels ) continue;
|
|
|
|
if( IsSystemVisible( i ) )
|
|
{
|
|
m_Panels[i]->SetSize(nPanelW,nPanelT);
|
|
m_Panels[i]->SetPos(OFFSET+c*nPanelW,OFFSET-nScrollPos+r*nPanelT);
|
|
m_Panels[i]->SetVisible(true);
|
|
}
|
|
else
|
|
{
|
|
m_Panels[i]->SetSize(1,1);
|
|
m_Panels[i]->SetPos(-10,-10);
|
|
m_Panels[i]->SetVisible(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( nPanels == 0 )
|
|
{
|
|
m_pNoSystemsLabel->SetVisible( true );
|
|
|
|
int w,t;
|
|
m_pNoSystemsLabel->GetContentSize(w,t);
|
|
|
|
w *= 2;
|
|
m_pNoSystemsLabel->SetWide( w );
|
|
m_pNoSystemsLabel->SetPos( (m_pScrollPanel->GetWide()-w)/2, (m_pScrollPanel->GetTall()-t)/2 );
|
|
}
|
|
else
|
|
{
|
|
m_pNoSystemsLabel->SetVisible( false );
|
|
}
|
|
}
|
|
|
|
void CParticleSnapshotGrid::OnMouseWheeled(int delta)
|
|
{
|
|
int val = m_pScrollBar->GetValue();
|
|
val -= (delta * 30);
|
|
m_pScrollBar->SetValue(val);
|
|
RequestFocus();
|
|
}
|
|
|
|
bool CParticleSnapshotGrid::IsSystemVisible( int nIndex )
|
|
{
|
|
int nViewTall = m_pScrollPanel->GetTall();
|
|
int nRow = (nIndex / m_nCurrentColCount);
|
|
int nTopOfPanel = nRow * GetPanelTall();
|
|
int nBottomOfPanel = nTopOfPanel + GetPanelTall();
|
|
int nCurrentScrollValue = m_pScrollBar->GetValue();
|
|
|
|
return ( nTopOfPanel < nCurrentScrollValue+nViewTall &&
|
|
nBottomOfPanel > nCurrentScrollValue );
|
|
}
|
|
|
|
void CParticleSnapshotGrid::SelectIndex( int nIndex, bool bAddToSelection, bool bToggle )
|
|
{
|
|
// not the most efficient, but easy
|
|
SelectSystem( m_Panels[nIndex]->GetSystemName(), bAddToSelection, bToggle );
|
|
}
|
|
|
|
void CParticleSnapshotGrid::SelectId( int nId, bool bAddToSelection, bool bToggle )
|
|
{
|
|
// not the most efficient, but easy
|
|
SelectSystem( GetSystemName(nId), bAddToSelection, bToggle );
|
|
}
|
|
|
|
void CParticleSnapshotGrid::DeselectAll()
|
|
{
|
|
for ( int i = 0; i < m_Panels.Count(); ++i )
|
|
{
|
|
m_Panels[i]->SetSelected(false);
|
|
}
|
|
|
|
m_nMostRecentSelectedIndex = -1;
|
|
}
|
|
|
|
int CParticleSnapshotGrid::GetSelectedSystemCount()
|
|
{
|
|
int nSelected = 0;
|
|
|
|
for ( int i = 0; i < m_Panels.Count(); ++i )
|
|
{
|
|
if( m_Panels[i]->IsSelected() )
|
|
{
|
|
nSelected++;
|
|
}
|
|
}
|
|
|
|
return nSelected;
|
|
}
|
|
|
|
const char *CParticleSnapshotGrid::GetSystemName( int nSystemId )
|
|
{
|
|
int nInternalIndex = IdToIndex( nSystemId );
|
|
|
|
if ( nInternalIndex < 0 || nInternalIndex >= m_Panels.Count() )
|
|
{
|
|
return "";
|
|
}
|
|
else
|
|
{
|
|
return m_Panels[nInternalIndex]->GetSystemName();
|
|
}
|
|
}
|
|
|
|
int CParticleSnapshotGrid::GetSelectedSystemId( int nSelectionIndex )
|
|
{
|
|
for ( int i = 0; i < m_Panels.Count(); ++i )
|
|
{
|
|
if( m_Panels[i]->IsSelected() )
|
|
{
|
|
nSelectionIndex--;
|
|
|
|
if( nSelectionIndex < 0 )
|
|
{
|
|
return m_Panels[i]->GetId();
|
|
}
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
void CParticleSnapshotGrid::SelectSystem( const char *pSystemName, bool bAddToSelection, bool bToggle )
|
|
{
|
|
int nSelectedIndex = -1;
|
|
|
|
for ( int i = 0; i < m_Panels.Count(); ++i )
|
|
{
|
|
if ( !V_strcmp(m_Panels[i]->GetSystemName(),pSystemName) )
|
|
{
|
|
if ( m_Panels[i]->IsSelected() )
|
|
{
|
|
if ( bAddToSelection && bToggle )
|
|
{
|
|
m_Panels[i]->SetSelected( false );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
nSelectedIndex = i;
|
|
m_Panels[i]->SetSelected( true );
|
|
m_Panels[i]->RequestFocus();
|
|
}
|
|
|
|
m_nMostRecentSelectedIndex = i;
|
|
}
|
|
else if( !bAddToSelection )
|
|
{
|
|
m_Panels[i]->SetSelected(false);
|
|
}
|
|
}
|
|
|
|
if ( nSelectedIndex != -1 )
|
|
{
|
|
int nViewTall = m_pScrollPanel->GetTall();
|
|
int nRow = (nSelectedIndex / m_nCurrentColCount);
|
|
int nTopOfPanel = nRow * GetPanelTall() + OFFSET;
|
|
int nBottomOfPanel = nTopOfPanel + GetPanelTall() + OFFSET;
|
|
int nCurrentScrollValue = m_pScrollBar->GetValue();
|
|
|
|
if( nTopOfPanel < nCurrentScrollValue )
|
|
{
|
|
m_pScrollBar->SetValue(nTopOfPanel);
|
|
}
|
|
else if( nBottomOfPanel > nCurrentScrollValue+nViewTall )
|
|
{
|
|
m_pScrollBar->SetValue(nBottomOfPanel-nViewTall);
|
|
}
|
|
}
|
|
|
|
Repaint();
|
|
}
|
|
/*
|
|
static void ProcessPSystem( CParticleSnapshotPanel *&pPanel )
|
|
{
|
|
pPanel->Simulate();
|
|
}
|
|
*/
|
|
void CParticleSnapshotGrid::OnTick()
|
|
{
|
|
// ParallelProcess( m_Panels.Base(), m_Panels.Count(), ProcessPSystem );
|
|
|
|
for ( int i = 0; i < m_Panels.Count(); ++i )
|
|
{
|
|
m_Panels[i]->Simulate();
|
|
}
|
|
}
|
|
|
|
void CParticleSnapshotGrid::OnParticleSystemSelected( const char *SystemName )
|
|
{
|
|
SelectSystem( SystemName, false, false );
|
|
PostActionSignal( new KeyValues( "ParticleSystemSelectionChanged" ) );
|
|
}
|
|
|
|
void CParticleSnapshotGrid::OnParticleSystemCtrlSelected( const char *SystemName )
|
|
{
|
|
SelectSystem( SystemName, true, true );
|
|
PostActionSignal( new KeyValues( "ParticleSystemSelectionChanged" ) );
|
|
}
|
|
|
|
void CParticleSnapshotGrid::OnParticleSystemShiftSelected( const char *SystemName )
|
|
{
|
|
int nIdx = InternalFindSystemIndexByName( SystemName );
|
|
|
|
if ( nIdx != -1 && m_nMostRecentSelectedIndex != -1 )
|
|
{
|
|
int nFrom = MIN( nIdx, m_nMostRecentSelectedIndex );
|
|
int nTo = MAX( nIdx, m_nMostRecentSelectedIndex );
|
|
|
|
for ( int i = nFrom; i <= nTo; ++i )
|
|
{
|
|
SelectIndex( i, true, false );
|
|
}
|
|
|
|
PostActionSignal( new KeyValues( "ParticleSystemSelectionChanged" ) );
|
|
}
|
|
}
|
|
|
|
int CParticleSnapshotGrid::InternalFindSystemIndexByName( const char *pSystemName )
|
|
{
|
|
for ( int i = 0; i < m_Panels.Count(); ++i )
|
|
{
|
|
if ( !V_strcmp(m_Panels[i]->GetSystemName(),pSystemName) )
|
|
{
|
|
return i;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
void CParticleSnapshotGrid::OnParticleSystemPicked( const char *SystemName )
|
|
{
|
|
PostActionSignal( new KeyValues( "ParticleSystemPicked", "SystemName", SystemName ) );
|
|
}
|
|
|
|
int CParticleSnapshotGrid::IdToIndex( int nId )
|
|
{
|
|
for ( int i = 0; i < m_Panels.Count(); ++i )
|
|
{
|
|
if ( m_Panels[i]->GetId() == nId )
|
|
{
|
|
return i;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
void CParticleSnapshotGrid::OnKeyCodeTyped( vgui::KeyCode code )
|
|
{
|
|
if ( code == KEY_UP ||
|
|
code == KEY_DOWN ||
|
|
code == KEY_LEFT ||
|
|
code == KEY_RIGHT )
|
|
{
|
|
if ( m_nMostRecentSelectedIndex != -1 )
|
|
{
|
|
int nNextIndex = m_nMostRecentSelectedIndex;
|
|
|
|
if ( code == KEY_UP )
|
|
{
|
|
nNextIndex -= m_nCurrentColCount;
|
|
}
|
|
else if ( code == KEY_DOWN )
|
|
{
|
|
nNextIndex += m_nCurrentColCount;
|
|
}
|
|
else if ( code == KEY_LEFT )
|
|
{
|
|
nNextIndex--;
|
|
}
|
|
else if ( code == KEY_RIGHT )
|
|
{
|
|
nNextIndex++;
|
|
}
|
|
|
|
int nPanels = m_Panels.Count();
|
|
int nCurrentRowCount = (nPanels+m_nCurrentColCount-1)/m_nCurrentColCount;
|
|
|
|
if ( nNextIndex/m_nCurrentColCount >= nCurrentRowCount-1 &&
|
|
nNextIndex >= nPanels )
|
|
{
|
|
// if you're not on the last row and hit down,
|
|
// but nothing is below you, still pop to the last
|
|
// item in the list
|
|
nNextIndex = nPanels-1;
|
|
}
|
|
|
|
if( nNextIndex >= 0 && nNextIndex < nPanels )
|
|
{
|
|
SelectIndex( nNextIndex, false, false );
|
|
PostActionSignal( new KeyValues( "ParticleSystemSelectionChanged" ) );
|
|
RequestFocus();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
BaseClass::OnKeyCodeTyped( code );
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Particle Picker
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
static int StringSortHelperI( const char * const *a, const char * const *b )
|
|
{
|
|
return V_stricmp(*a,*b);
|
|
}
|
|
|
|
void CParticlePicker::OnAssetListChanged( )
|
|
{
|
|
CUtlVector<const char*> assetNames;
|
|
|
|
int nCount = GetAssetCount();
|
|
for ( int i = 0; i < nCount; ++i )
|
|
{
|
|
if ( IsAssetVisible( i ) )
|
|
{
|
|
assetNames.AddToTail( GetAssetName(i) );
|
|
}
|
|
}
|
|
|
|
assetNames.Sort( StringSortHelperI );
|
|
|
|
m_pSnapshotGrid->SetParticleList( assetNames );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Constructor
|
|
//-----------------------------------------------------------------------------
|
|
CParticlePicker::CParticlePicker( vgui::Panel *pParent ) :
|
|
BaseClass( pParent, "Particle Systems", "pcf", "particles", "pcfName" )
|
|
{
|
|
m_pFileBrowserSplitter = new Splitter( this, "FileBrowserSplitter", SPLITTER_MODE_VERTICAL, 1 );
|
|
|
|
float flFractions[] = { 0.33f, 0.67f };
|
|
|
|
m_pFileBrowserSplitter->RespaceSplitters( flFractions );
|
|
|
|
vgui::Panel *pSplitterLeftSide = m_pFileBrowserSplitter->GetChild( 0 );
|
|
vgui::Panel *pSplitterRightSide = m_pFileBrowserSplitter->GetChild( 1 );
|
|
|
|
pSplitterLeftSide->RequestFocus();
|
|
CreateStandardControls( pSplitterLeftSide, false );
|
|
AutoLayoutStandardControls();
|
|
|
|
m_pSnapshotGrid = new CParticleSnapshotGrid( pSplitterRightSide, "ParticleSystemPanel" );
|
|
m_pSnapshotGrid->SetAutoResize( PIN_TOPLEFT, AUTORESIZE_DOWNANDRIGHT, 0, 0, 0, 0 );
|
|
m_pSnapshotGrid->AddActionSignalTarget(this);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Destructor
|
|
//-----------------------------------------------------------------------------
|
|
CParticlePicker::~CParticlePicker()
|
|
{
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Performs layout
|
|
//-----------------------------------------------------------------------------
|
|
void CParticlePicker::PerformLayout()
|
|
{
|
|
// NOTE: This call should cause auto-resize to occur
|
|
// which should fix up the width of the panels
|
|
BaseClass::PerformLayout();
|
|
|
|
int w, h;
|
|
GetSize( w, h );
|
|
|
|
// Layout the mdl splitter
|
|
m_pFileBrowserSplitter->SetBounds( 0, 0, w, h );
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Buttons on various pages
|
|
//-----------------------------------------------------------------------------
|
|
void CParticlePicker::OnAssetSelected( KeyValues *pParams )
|
|
{
|
|
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// A particle system was selected
|
|
//-----------------------------------------------------------------------------
|
|
void CParticlePicker::OnSelectedAssetPicked( const char *pParticleSysName )
|
|
{
|
|
SelectParticleSys( pParticleSysName );
|
|
|
|
m_pSnapshotGrid->SelectSystem( pParticleSysName, false, false );
|
|
}
|
|
|
|
|
|
void CParticlePicker::OnMousePressed(MouseCode code)
|
|
{
|
|
SelectParticleSys( "" );
|
|
m_pSnapshotGrid->SelectSystem( "", false, false );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Allows external apps to select a particle system
|
|
//-----------------------------------------------------------------------------
|
|
void CParticlePicker::SelectParticleSys( const char *pRelativePath )
|
|
{
|
|
PostActionSignal( new KeyValues( "SelectedParticleSysChanged", "particle", pRelativePath ? pRelativePath : "" ) );
|
|
}
|
|
|
|
void CParticlePicker::GetSelectedParticleSysName( char *pBuffer, int nMaxLen )
|
|
{
|
|
Assert( nMaxLen > 0 );
|
|
|
|
if ( GetSelectedAssetCount() > 0 )
|
|
{
|
|
Q_snprintf( pBuffer, nMaxLen, "%s", GetSelectedAsset() );
|
|
}
|
|
else
|
|
{
|
|
pBuffer[0] = 0;
|
|
}
|
|
}
|
|
|
|
void CParticlePicker::OnParticleSystemSelectionChanged()
|
|
{
|
|
const char *SystemName = m_pSnapshotGrid->GetSystemName( m_pSnapshotGrid->GetSelectedSystemId(0) );
|
|
SetSelection( SystemName );
|
|
}
|
|
|
|
void CParticlePicker::OnParticleSystemPicked( const char *SystemName )
|
|
{
|
|
OnKeyCodeTyped(KEY_ENTER);
|
|
}
|
|
|
|
int CParticlePicker::GetAssetCount()
|
|
{
|
|
return sCacheParticleList.Count();
|
|
}
|
|
|
|
const char *CParticlePicker::GetAssetName( int nAssetIndex )
|
|
{
|
|
return sCacheParticleList[nAssetIndex].m_AssetInfo.m_AssetName;
|
|
}
|
|
|
|
const CachedAssetInfo_t& CParticlePicker::GetCachedAsset( int nAssetIndex )
|
|
{
|
|
return sCacheParticleList[nAssetIndex].m_AssetInfo;
|
|
}
|
|
|
|
int CParticlePicker::GetCachedAssetCount()
|
|
{
|
|
return sCacheParticleList.Count();
|
|
}
|
|
|
|
void CParticlePicker::CachePCFInfo( int nModIndex, const char *pFileName )
|
|
{
|
|
const CacheModInfo_t& modInfo = ModInfo(nModIndex);
|
|
|
|
if ( pFileName[0] == '!' )
|
|
{
|
|
++pFileName;
|
|
}
|
|
|
|
CUtlBuffer buf;
|
|
|
|
CUtlString pcfPath = modInfo.m_Path;
|
|
pcfPath += "/";
|
|
pcfPath += pFileName;
|
|
|
|
// cache the particles into the manager
|
|
g_pParticleSystemMgr->ReadParticleConfigFile( pcfPath, true );
|
|
|
|
// and read it ourselves to see what came out
|
|
if ( !g_pFullFileSystem->ReadFile( pcfPath, modInfo.m_Path, buf ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
DECLARE_DMX_CONTEXT_DECOMMIT( true );
|
|
|
|
CDmxElement *pRoot;
|
|
if ( !UnserializeDMX( buf, &pRoot, pFileName ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ( !Q_stricmp( pRoot->GetTypeString(), "DmeParticleSystemDefinition" ) )
|
|
{
|
|
CachedParticleInfo_t &info = sCacheParticleList[sCacheParticleList.AddToTail()];
|
|
info.m_AssetInfo.m_AssetName = pRoot->GetName();
|
|
info.m_AssetInfo.m_nModIndex = nModIndex;
|
|
info.m_FileName = pFileName;
|
|
|
|
return;
|
|
}
|
|
|
|
const CDmxAttribute *pDefinitions = pRoot->GetAttribute( "particleSystemDefinitions" );
|
|
if ( !pDefinitions || pDefinitions->GetType() != AT_ELEMENT_ARRAY )
|
|
{
|
|
CleanupDMX( pRoot );
|
|
return;
|
|
}
|
|
|
|
const CUtlVector< CDmxElement* >& definitions = pDefinitions->GetArray<CDmxElement*>( );
|
|
int nCount = definitions.Count();
|
|
for ( int i = 0; i < nCount; ++i )
|
|
{
|
|
CachedParticleInfo_t &info = sCacheParticleList[sCacheParticleList.AddToTail()];
|
|
info.m_AssetInfo.m_AssetName = definitions[i]->GetName();
|
|
info.m_AssetInfo.m_nModIndex = nModIndex;
|
|
info.m_FileName = pFileName;
|
|
}
|
|
|
|
CleanupDMX( pRoot );
|
|
}
|
|
|
|
void CParticlePicker::HandleModParticles( int nModIndex )
|
|
{
|
|
const CacheModInfo_t &modInfo = ModInfo(nModIndex);
|
|
|
|
CUtlString manifestPath = modInfo.m_Path;
|
|
manifestPath += "/particles/particles_manifest.txt" ;
|
|
|
|
CUtlVector<CUtlString> pcfList;
|
|
GetParticleManifest( pcfList, manifestPath );
|
|
|
|
int nCount = pcfList.Count();
|
|
for ( int i = 0; i < nCount; ++i )
|
|
{
|
|
PCFToLoad_t &p = sCacheUnloadedPCFs[sCacheUnloadedPCFs.AddToTail()];
|
|
p.m_FileName = pcfList[i];
|
|
p.m_ModId = nModIndex;
|
|
}
|
|
}
|
|
|
|
bool CParticlePicker::BeginCacheAssets( bool bForceRecache )
|
|
{
|
|
if ( bForceRecache )
|
|
{
|
|
sCacheParticleList.RemoveAll();
|
|
sCacheUnloadedPCFs.RemoveAll();
|
|
}
|
|
|
|
if ( sCacheParticleList.Count() )
|
|
{
|
|
return true;
|
|
}
|
|
|
|
int nCount = ModCount();
|
|
for ( int i = 0; i < nCount; ++i )
|
|
{
|
|
HandleModParticles( i );
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
bool CParticlePicker::IncrementalCacheAssets( float flTimeAllowed )
|
|
{
|
|
float flStartTime = Plat_FloatTime();
|
|
|
|
while ( sCacheUnloadedPCFs.Count() )
|
|
{
|
|
PCFToLoad_t &p = sCacheUnloadedPCFs.Tail();
|
|
|
|
CachePCFInfo( p.m_ModId, p.m_FileName );
|
|
|
|
sCacheUnloadedPCFs.RemoveMultipleFromTail(1);
|
|
|
|
// might have run out of time
|
|
if ( Plat_FloatTime() - flStartTime >= flTimeAllowed )
|
|
break;
|
|
}
|
|
|
|
return (sCacheUnloadedPCFs.Count() == 0);
|
|
}
|
|
|
|
CUtlString CParticlePicker::GetSelectedAssetFullPath( int nSelectionIndex )
|
|
{
|
|
int nAssetIndex = GetSelectedAssetIndex( nSelectionIndex );
|
|
|
|
if( nAssetIndex < 0 || nAssetIndex >= sCacheParticleList.Count() )
|
|
{
|
|
return CUtlString("ERROR");
|
|
}
|
|
|
|
CachedParticleInfo_t &p = sCacheParticleList[nAssetIndex];
|
|
const CacheModInfo_t &m = ModInfo( p.m_AssetInfo.m_nModIndex );
|
|
|
|
char pBuf[MAX_PATH+128];
|
|
Q_snprintf( pBuf, sizeof(pBuf), "%s\\%s::%s",
|
|
m.m_Path.Get(), p.m_FileName.Get(), p.m_AssetInfo.m_AssetName.Get() );
|
|
Q_FixSlashes( pBuf );
|
|
|
|
return CUtlString(pBuf);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Purpose: Modal picker frame
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
CParticlePickerFrame::CParticlePickerFrame( vgui::Panel *pParent, const char *pTitle ) :
|
|
BaseClass( pParent )
|
|
{
|
|
SetAssetPicker( new CParticlePicker( this ) );
|
|
LoadControlSettingsAndUserConfig( "resource/mdlpickerframe.res" );
|
|
SetTitle( pTitle, false );
|
|
}
|
|
|
|
CParticlePickerFrame::~CParticlePickerFrame()
|
|
{
|
|
}
|
|
|
|
void CParticlePickerFrame::SelectParticleSys( const char *pRelativePath )
|
|
{
|
|
static_cast<CParticlePicker*>( GetAssetPicker() )->SelectParticleSys( pRelativePath );
|
|
}
|