From a0bf643459eedee0267197b29bd96dc707284bdf Mon Sep 17 00:00:00 2001 From: Artyom Shalkhakov Date: Sat, 8 Feb 2025 07:16:46 -0700 Subject: [PATCH] Use the new generic decl new/lookup dialog for materials and particles. --- .../imgui/particleeditor/ParticleEditor.cpp | 296 +----------------- .../imgui/particleeditor/ParticleEditor.h | 52 +-- neo/tools/imgui/util/ImGui_IdWidgets.cpp | 232 ++++++++++++++ neo/tools/imgui/util/ImGui_IdWidgets.h | 49 +++ 4 files changed, 300 insertions(+), 329 deletions(-) diff --git a/neo/tools/imgui/particleeditor/ParticleEditor.cpp b/neo/tools/imgui/particleeditor/ParticleEditor.cpp index e5f2d091..afc9f0ae 100644 --- a/neo/tools/imgui/particleeditor/ParticleEditor.cpp +++ b/neo/tools/imgui/particleeditor/ParticleEditor.cpp @@ -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( const_cast( 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( 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( const_cast( 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( particleNewDlg.GetDecl() ); SetCurParticle( dp ); } - if ( clickedSelect) { - particleSelectDlg.Start(); + if ( clickedSelect ) { + particleSelectDlg.Start( NULL ); } if ( particleSelectDlg.Draw() ) { - idDeclParticle *dp = particleSelectDlg.GetParticle(); + idDeclParticle *dp = static_cast( 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( 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" ); diff --git a/neo/tools/imgui/particleeditor/ParticleEditor.h b/neo/tools/imgui/particleeditor/ParticleEditor.h index 0b5d73d2..70262850 100644 --- a/neo/tools/imgui/particleeditor/ParticleEditor.h +++ b/neo/tools/imgui/particleeditor/ParticleEditor.h @@ -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 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 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 materialDecls; - idStr materialDeclName; - idDeclParticle * curParticle; // edit controls diff --git a/neo/tools/imgui/util/ImGui_IdWidgets.cpp b/neo/tools/imgui/util/ImGui_IdWidgets.cpp index 8b9bfd61..2a70d41b 100644 --- a/neo/tools/imgui/util/ImGui_IdWidgets.cpp +++ b/neo/tools/imgui/util/ImGui_IdWidgets.cpp @@ -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( 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( 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 diff --git a/neo/tools/imgui/util/ImGui_IdWidgets.h b/neo/tools/imgui/util/ImGui_IdWidgets.h index 8043e653..50b2157a 100644 --- a/neo/tools/imgui/util/ImGui_IdWidgets.h +++ b/neo/tools/imgui/util/ImGui_IdWidgets.h @@ -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 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 list; + idStr name; + idStr errorText; + idDecl * dp; + state_t state; +}; + } //namespace ImGuiTools