Use the new generic decl new/lookup dialog for materials and particles.

This commit is contained in:
Artyom Shalkhakov 2025-02-08 07:16:46 -07:00
parent ff85551c6f
commit a0bf643459
4 changed files with 300 additions and 329 deletions

View file

@ -79,225 +79,6 @@ bool RangeSlider::Draw( const char *label, float itemWidth, float sliderWidth )
return changed;
}
ParticleNew::ParticleNew()
: fileSelection(-1)
, prtFiles()
, fileName( "" )
, name( "" )
, errorText( "" )
, dp( NULL )
, state(DONE)
{
}
void ParticleNew::Start() {
prtFiles.Clear();
idFileList* files = fileSystem->ListFiles( "particles", ".prt", true, true );
for( int i = 0; i < files->GetNumFiles(); i++ )
{
idStr file = files->GetFile( i );
file.StripPath();
file.StripFileExtension();
prtFiles.Append( file );
}
fileSystem->FreeFileList( files );
fileSelection = -1;
fileName.Clear();
name.Clear();
errorText.Clear();
dp = NULL;
state = NAME;
ImGui::OpenPopup( "New Particle System" );
}
bool ParticleNew::Draw() {
if ( state == DONE ) {
return false;
}
bool accepted = false;
bool canceled = false;
if ( ImGui::BeginPopupModal( "New Particle System", nullptr, ImGuiWindowFlags_AlwaysAutoResize ) ) {
ImGui::TextColored( ImVec4( 1, 0, 0, 1 ), errorText );
if ( ImGui::InputTextStr( "File Name", &fileName ) ) {
// nop
}
if ( ImGui::BeginListBox( "Files##prtFileSelect" ) ) {
for( int i = 0; i < prtFiles.Num(); i++ )
{
if ( fileName.Length() && prtFiles[i].Find( fileName.c_str(), false ) == -1 ) {
continue;
}
bool selected = ( i == fileSelection );
ImGui::PushID( i );
if ( ImGui::Selectable( prtFiles[i].c_str(), selected ) ) {
fileSelection = i;
fileName = prtFiles[fileSelection];
}
if ( selected ) {
ImGui::SetItemDefaultFocus();
}
ImGui::PopID();
}
ImGui::EndListBox();
}
if ( ImGui::InputTextStr( "Name", &name ) ) {
// nop
}
if ( ImGui::Button( "OK" ) ) {
errorText.Clear();
if ( name.IsEmpty() ) {
errorText += "Please enter a name\n";
accepted = false;
}
idDeclParticle *newDecl = static_cast<idDeclParticle*>( const_cast<idDecl*>( declManager->FindType( DECL_PARTICLE, name.c_str(), false ) ) );
if( newDecl ) {
errorText += idStr::Format( "Particle System %s already exists in %s. Please select a different name\n", name.c_str(), newDecl->GetFileName() );
accepted = false;
}
if ( errorText.IsEmpty() ) {
idStr fullName;
fullName = "particles/";
fullName += fileName;
fullName += ".prt";
// create it
dp = static_cast<idDeclParticle*>( declManager->CreateNewDecl( DECL_PARTICLE, name.c_str(), fullName.c_str() ) );
state = DONE;
accepted = true;
ImGui::CloseCurrentPopup();
}
}
ImGui::SameLine();
if ( ImGui::Button( "Cancel" ) ) {
accepted = false;
state = DONE;
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
}
return accepted;
}
ParticleSelect::ParticleSelect()
: comboParticleSel(-1)
, comboParticle()
, name( "" )
, errorText( "" )
, dp( NULL )
, state(DONE)
{
}
void ParticleSelect::Start() {
comboParticle.Clear();
for ( int i = 0; i < declManager->GetNumDecls( DECL_PARTICLE ); i++ ) {
const idDecl *idp = declManager->DeclByIndex( DECL_PARTICLE, i );
comboParticle.Append( idp->GetName() );
}
comboParticleSel = 0;
name.Clear();
errorText.Clear();
dp = NULL;
state = NAME;
ImGui::OpenPopup( "Particle System Browser" );
}
bool ParticleSelect::Draw() {
if ( state == DONE ) {
return false;
}
bool accepted = false;
bool canceled = false;
if ( ImGui::BeginPopupModal( "Particle System Browser", nullptr, ImGuiWindowFlags_AlwaysAutoResize ) ) {
ImGui::TextColored( ImVec4( 1, 0, 0, 1 ), errorText );
if ( ImGui::InputTextStr( "Name", &name ) ) {
// nop
}
if ( ImGui::BeginListBox( "Particle Systems##prtSystemSelect" ) ) {
for( int i = 0; i < comboParticle.Num(); i++ )
{
if ( name.Length() && comboParticle[i].Find( name.c_str(), false ) == -1 ) {
continue;
}
bool selected = ( i == comboParticleSel );
ImGui::PushID( i );
if ( ImGui::Selectable( comboParticle[i].c_str(), selected ) ) {
comboParticleSel = i;
name = comboParticle[comboParticleSel];
}
if ( selected ) {
ImGui::SetItemDefaultFocus();
}
ImGui::PopID();
}
ImGui::EndListBox();
}
if ( ImGui::Button( "OK" ) ) {
errorText.Clear();
if ( name.IsEmpty() ) {
errorText += "Please enter a name or select a particle system from the list\n";
accepted = false;
}
idDeclParticle *decl = static_cast<idDeclParticle*>( const_cast<idDecl*>( declManager->FindType( DECL_PARTICLE, name.c_str(), false ) ) );
if( !decl ) {
errorText += idStr::Format( "Particle System %s does not exist. Please select a different particle system\n", name.c_str() );
accepted = false;
}
if ( errorText.IsEmpty() ) {
dp = decl;
state = DONE;
accepted = true;
ImGui::CloseCurrentPopup();
}
}
ImGui::SameLine();
if ( ImGui::Button( "Cancel" ) ) {
accepted = false;
state = DONE;
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
}
return accepted;
}
ParticleEditor& ParticleEditor::Instance()
{
static ParticleEditor instance;
@ -305,13 +86,13 @@ ParticleEditor& ParticleEditor::Instance()
}
ParticleEditor::ParticleEditor()
: particleNewDlg()
, particleSelectDlg()
: particleNewDlg( DECL_PARTICLE, "particles/", ".prt", "New Particle System" )
, particleSelectDlg( DECL_PARTICLE, "Select Particle System" )
, materialSelectDlg( DECL_MATERIAL, "Select Material" )
, colorDlg( "Color" )
, fadeColorDlg( "Fade Color" )
, entityColorDlg( "Entity Color" )
, particleDropDlg()
, materialDeclSelection(0)
{
isShown = false;
}
@ -361,17 +142,17 @@ void ParticleEditor::Draw()
}
if ( particleNewDlg.Draw() ) {
idDeclParticle *dp = particleNewDlg.GetParticle();
idDeclParticle *dp = static_cast<idDeclParticle*>( particleNewDlg.GetDecl() );
SetCurParticle( dp );
}
if ( clickedSelect) {
particleSelectDlg.Start();
if ( clickedSelect ) {
particleSelectDlg.Start( NULL );
}
if ( particleSelectDlg.Draw() ) {
idDeclParticle *dp = particleSelectDlg.GetParticle();
idDeclParticle *dp = static_cast<idDeclParticle*>( particleSelectDlg.GetDecl() );
SetCurParticle( dp );
}
@ -451,9 +232,16 @@ void ParticleEditor::Draw()
}
ImGui::SameLine();
if ( ImGui::Button( "...###BrowseMaterial" ) ) {
ImGui::OpenPopup("Select Material");
materialSelectDlg.Start( matName.c_str() );
}
if ( materialSelectDlg.Draw() ) {
idMaterial *material = static_cast<idMaterial *>( materialSelectDlg.GetDecl() );
if ( material ) {
matName = material->GetName();
DlgVarsToCurStage();
CurStageToDlgVars();
}
}
OnBnClickedButtonBrowsematerial();
ImGui::SetNextItemWidth(70);
if ( ImGui::InputInt( "Anim Frames", &animFrames, 0 ) ) {
DlgVarsToCurStage();
@ -951,58 +739,6 @@ void ParticleEditor::OnBnClickedButtonSaveParticles() {
buttonSaveParticleEntitiesEnabled = false;
}
void ParticleEditor::OnBnClickedButtonBrowsematerial() {
if( ImGui::BeginPopupModal( "Select Material" ) )
{
if( materialDecls.Num() == 0 )
{
int num = declManager->GetNumDecls( DECL_MATERIAL );
materialDecls.Clear();
materialDecls.Resize( num );
for( int i = 0; i < num; i++ )
{
materialDecls.Append( declManager->DeclByIndex( DECL_MATERIAL, i )->GetName() );
}
}
ImGui::BeginListBox( "##materialDeclSelect" );
for( int i = 0; i < materialDecls.Num(); i++ )
{
if( ImGui::ListBox( "Materials", &materialDeclSelection, StringListItemGetter, &materialDecls, materialDecls.Num() ) )
{
materialDeclName = materialDecls[materialDeclSelection];
}
}
ImGui::EndListBox();
/*
ImGui::SameLine();
ImGui::SmallButton( "New Material" );
*/
ImGui::InputTextStr( "Material Name", &materialDeclName );
if( ImGui::Button( "Select" ) )
{
matName = materialDeclName;
DlgVarsToCurStage();
CurStageToDlgVars();
ImGui::CloseCurrentPopup();
}
ImGui::SameLine();
if( ImGui::Button( "Close" ) )
{
materialDecls.Clear();
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
}
}
void ParticleEditor::ButtonColor() {
colorDlg.Button( color );
ImGui::SetItemTooltip( "Color that the material will be multiplied by" );

View file

@ -107,47 +107,6 @@ private:
state_t state;
};
class ParticleNew {
public:
ParticleNew();
void Start();
bool Draw();
ID_INLINE idDeclParticle* GetParticle() { return dp; }
private:
enum state_t { DONE = 0, NAME };
int fileSelection;
idList<idStr> prtFiles;
idStr fileName;
idStr name;
idStr errorText;
idDeclParticle * dp;
state_t state;
};
class ParticleSelect {
public:
ParticleSelect();
void Start();
bool Draw();
ID_INLINE idDeclParticle* GetParticle() { return dp; }
private:
enum state_t { DONE = 0, NAME };
int comboParticleSel;
idList<idStr> comboParticle;
idStr name;
idStr errorText;
idDeclParticle * dp;
state_t state;
};
class ParticleEditor {
public:
@ -172,10 +131,8 @@ public:
}
private:
void OnCbnSelchangeComboParticles();
void OnCbnSelchangeComboPath();
void OnLbnSelchangeListStages();
void OnBnClickedButtonBrowsematerial();
void ButtonColor();
void ButtonFadeColor();
void ButtonEntityColor();
@ -199,8 +156,9 @@ private:
private:
bool isShown;
ParticleNew particleNewDlg;
ParticleSelect particleSelectDlg;
DeclNew particleNewDlg;
DeclSelect particleSelectDlg;
DeclSelect materialSelectDlg;
idStr inFileText;
@ -211,10 +169,6 @@ private:
ColorPicker entityColorDlg;
ParticleDrop particleDropDlg;
int materialDeclSelection;
idList<idStr> materialDecls;
idStr materialDeclName;
idDeclParticle * curParticle;
// edit controls

View file

@ -36,6 +36,8 @@ If you have questions concerning this license or the applicable additional terms
#include "idlib/containers/StrList.h"
#include "ImGui_IdWidgets.h"
#include "framework/FileSystem.h"
#include "renderer/Material.h"
static const char* bodyContentsNames[5] =
@ -180,6 +182,236 @@ bool ColorPicker::Draw() {
return isAccepted;
}
DeclNew::DeclNew( declType_t _declType, const char *_directory, const char *_extension, const char *_label )
: declType(_declType)
, directory(_directory)
, extension(_extension)
, label(_label)
, fileSelection(-1)
, files()
, fileName( "" )
, name( "" )
, errorText( "" )
, dp( NULL )
, state(DONE)
{
}
void DeclNew::Start() {
files.Clear();
idFileList* names = fileSystem->ListFiles( directory, extension, true, true );
for( int i = 0; i < names->GetNumFiles(); i++ )
{
idStr file = names->GetFile( i );
file.StripPath();
file.StripFileExtension();
files.Append( file );
}
fileSystem->FreeFileList( names );
fileSelection = -1;
fileName.Clear();
name.Clear();
errorText.Clear();
dp = NULL;
state = NAME;
ImGui::OpenPopup( label );
}
bool DeclNew::Draw() {
if ( state == DONE ) {
return false;
}
bool accepted = false;
bool canceled = false;
if ( ImGui::BeginPopupModal( label, nullptr, ImGuiWindowFlags_AlwaysAutoResize ) ) {
ImGui::TextColored( ImVec4( 1, 0, 0, 1 ), errorText );
if ( ImGui::InputTextStr( "File Name", &fileName ) ) {
// nop
}
if ( ImGui::BeginListBox( "Files##prtFileSelect" ) ) {
for( int i = 0; i < files.Num(); i++ )
{
if ( fileName.Length() && files[i].Find( fileName.c_str(), false ) == -1 ) {
continue;
}
bool selected = ( i == fileSelection );
ImGui::PushID( i );
if ( ImGui::Selectable( files[i].c_str(), selected ) ) {
fileSelection = i;
fileName = files[fileSelection];
}
if ( selected ) {
ImGui::SetItemDefaultFocus();
}
ImGui::PopID();
}
ImGui::EndListBox();
}
if ( ImGui::InputTextStr( "Name", &name ) ) {
// nop
}
if ( ImGui::Button( "OK" ) ) {
errorText.Clear();
if ( name.IsEmpty() ) {
errorText += "Please enter a name\n";
accepted = false;
}
idDecl *newDecl = const_cast<idDecl*>( declManager->FindType( declType, name.c_str(), false ) );
if( newDecl ) {
errorText += idStr::Format( "Decl %s already exists in %s. Please select a different name\n", name.c_str(), newDecl->GetFileName() );
accepted = false;
}
if ( errorText.IsEmpty() ) {
idStr fullName;
fullName = directory;
fullName += fileName;
fullName += extension;
// create it
dp = declManager->CreateNewDecl( declType, name.c_str(), fullName.c_str() );
state = DONE;
accepted = true;
ImGui::CloseCurrentPopup();
}
}
ImGui::SameLine();
if ( ImGui::Button( "Cancel" ) ) {
accepted = false;
state = DONE;
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
}
return accepted;
}
DeclSelect::DeclSelect( declType_t _declType, const char *_label )
: declType(_declType)
, label(_label)
, listSel(-1)
, list()
, name( "" )
, errorText( "" )
, dp( NULL )
, state(DONE)
{
}
void DeclSelect::Start( const char *_name ) {
list.Clear();
for ( int i = 0; i < declManager->GetNumDecls( declType ); i++ ) {
const idDecl *idp = declManager->DeclByIndex( declType, i );
list.Append( idp->GetName() );
}
if ( _name ) {
name = _name;
listSel = list.FindIndex( name );
} else {
name.Clear();
listSel = -1;
}
errorText.Clear();
dp = NULL;
state = NAME;
ImGui::OpenPopup( label );
}
bool DeclSelect::Draw() {
if ( state == DONE ) {
return false;
}
bool accepted = false;
bool canceled = false;
if ( ImGui::BeginPopupModal( label, nullptr, ImGuiWindowFlags_AlwaysAutoResize ) ) {
ImGui::TextColored( ImVec4( 1, 0, 0, 1 ), errorText );
if ( ImGui::InputTextStr( "Name", &name ) ) {
// nop
}
if ( ImGui::BeginListBox( "Decls##prtSystemSelect" ) ) {
for( int i = 0; i < list.Num(); i++ )
{
if ( name.Length() && list[i].Find( name.c_str(), false ) == -1 ) {
continue;
}
bool selected = ( i == listSel );
ImGui::PushID( i );
if ( ImGui::Selectable( list[i].c_str(), selected ) ) {
listSel = i;
name = list[listSel];
}
if ( selected ) {
ImGui::SetItemDefaultFocus();
}
ImGui::PopID();
}
ImGui::EndListBox();
}
if ( ImGui::Button( "OK" ) ) {
errorText.Clear();
if ( name.IsEmpty() ) {
errorText += "Please enter a name or select a decl from the list\n";
accepted = false;
}
idDecl *decl = const_cast<idDecl*>( declManager->FindType( declType, name.c_str(), false ) );
if( !decl ) {
errorText += idStr::Format( "Decl %s does not exist. Please select a different decl\n", name.c_str() );
accepted = false;
}
if ( errorText.IsEmpty() ) {
dp = decl;
state = DONE;
accepted = true;
ImGui::CloseCurrentPopup();
}
}
ImGui::SameLine();
if ( ImGui::Button( "Cancel" ) ) {
accepted = false;
state = DONE;
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
}
return accepted;
}
} //namespace ImGuiTools

View file

@ -35,6 +35,8 @@ If you have questions concerning this license or the applicable additional terms
#include "idlib/containers/List.h"
#include "idlib/math/Vector.h"
#include "framework/Game.h"
namespace ImGuiTools
{
@ -85,6 +87,53 @@ private:
idVec4 oldColor;
};
class DeclNew {
public:
DeclNew( declType_t declType, const char *directory, const char *extension, const char *label );
void Start();
bool Draw();
ID_INLINE idDecl* GetDecl() { return dp; }
private:
enum state_t { DONE = 0, NAME };
declType_t declType;
const char * directory;
const char * extension;
const char * label;
int fileSelection;
idList<idStr> files;
idStr fileName;
idStr name;
idStr errorText;
idDecl * dp;
state_t state;
};
class DeclSelect {
public:
DeclSelect( declType_t declType, const char *label );
void Start( const char *name );
bool Draw();
ID_INLINE idDecl* GetDecl() { return dp; }
private:
enum state_t { DONE = 0, NAME };
declType_t declType;
const char * label;
int listSel;
idList<idStr> list;
idStr name;
idStr errorText;
idDecl * dp;
state_t state;
};
} //namespace ImGuiTools