diff --git a/radiant/ui/ortho/OrthoContextMenu.cpp b/radiant/ui/ortho/OrthoContextMenu.cpp index 588f299fe0..a307166b9c 100644 --- a/radiant/ui/ortho/OrthoContextMenu.cpp +++ b/radiant/ui/ortho/OrthoContextMenu.cpp @@ -373,15 +373,15 @@ void OrthoContextMenu::callbackAddParticle() UndoableCommand command("addParticle"); // Display the particle selector and block waiting for a selection (may be empty) - auto selectedParticle = ParticleChooserDialog::ChooseParticle(); + auto result = ParticleChooserDialog::ChooseParticleAndEmitter(); - if (selectedParticle.empty()) return; + if (result.selectedParticle.empty()) return; try { - auto node = GlobalEntityModule().createEntityFromSelection(PARTICLE_EMITTER_CLASSNAME, _lastPoint); + auto node = GlobalEntityModule().createEntityFromSelection(result.selectedClassname, _lastPoint); - node->getEntity().setKeyValue("model", selectedParticle); + node->getEntity().setKeyValue("model", result.selectedParticle); } catch (cmd::ExecutionFailure& e) { diff --git a/radiant/ui/particles/ParticleChooserDialog.cpp b/radiant/ui/particles/ParticleChooserDialog.cpp index a91653913a..680147aed9 100644 --- a/radiant/ui/particles/ParticleChooserDialog.cpp +++ b/radiant/ui/particles/ParticleChooserDialog.cpp @@ -6,40 +6,92 @@ #include "wxutil/dataview/TreeViewItemStyle.h" #include +#include +#include namespace ui { -ParticleChooserDialog::ParticleChooserDialog() : +ParticleChooserDialog::ParticleChooserDialog(bool showClassnameSelector) : DialogBase(_("Choose Particle")), - _selector(new ParticleSelector(this)) + _selector(new ParticleSelector(this)), + _funcEmitter(nullptr), + _funcSmoke(nullptr) { SetSizer(new wxBoxSizer(wxVERTICAL)); GetSizer()->Add(_selector, 1, wxEXPAND | wxALL, 12); - GetSizer()->Add(CreateStdDialogButtonSizer(wxOK | wxCANCEL), 0, wxALIGN_RIGHT | wxBOTTOM | wxLEFT | wxRIGHT, 12); + + auto bottomHbox = new wxBoxSizer(wxHORIZONTAL); + + if (showClassnameSelector) + { + auto radioHbox = new wxBoxSizer(wxHORIZONTAL); + + auto classText = new wxStaticText(this, wxID_ANY, _("Entity Class to create:")); + + _funcEmitter = new wxRadioButton(this, wxID_ANY, "func_emitter", wxDefaultPosition, wxDefaultSize, wxRB_GROUP); + _funcSmoke = new wxRadioButton(this, wxID_ANY, "func_smoke"); + + _funcEmitter->SetValue(true); + + radioHbox->Add(classText, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, 0); + radioHbox->Add(_funcEmitter, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, 12); + radioHbox->Add(_funcSmoke, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, 6); + + bottomHbox->Add(radioHbox, 0, wxLEFT, 12); + } + + bottomHbox->Add(CreateStdDialogButtonSizer(wxOK | wxCANCEL), 1, wxALIGN_CENTER_VERTICAL); + + GetSizer()->Add(bottomHbox, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 12); FitToScreen(0.5f, 0.6f); _selector->Bind(wxEVT_DATAVIEW_ITEM_ACTIVATED, &ParticleChooserDialog::_onItemActivated, this); } +std::string ParticleChooserDialog::getSelectedClassname() +{ + if (_funcSmoke == nullptr || _funcEmitter == nullptr) return ""; + + return _funcEmitter->GetValue() ? "func_emitter" : "func_smoke"; +} + void ParticleChooserDialog::_onItemActivated(wxDataViewEvent& ev) { EndModal(wxID_OK); } -std::string ParticleChooserDialog::ChooseParticle(const std::string& current) +std::string ParticleChooserDialog::ChooseParticle(const std::string& currentParticle) { - auto* dialog = new ParticleChooserDialog(); - - dialog->_selector->setSelectedParticle(current); + return RunDialog(false, currentParticle).selectedParticle; +} + +ParticleChooserDialog::SelectionResult ParticleChooserDialog::ChooseParticleAndEmitter(const std::string& currentParticle) +{ + return RunDialog(true, currentParticle); +} + +ParticleChooserDialog::SelectionResult ParticleChooserDialog::RunDialog(bool showClassnameSelector, const std::string& currentParticle) +{ + auto* dialog = new ParticleChooserDialog(showClassnameSelector); + + dialog->_selector->setSelectedParticle(currentParticle); + + auto result = dialog->ShowModal(); + + SelectionResult selectionResult; - auto returnValue = dialog->ShowModal() == wxID_OK ? dialog->_selector->getSelectedParticle() : ""; + if (result == wxID_OK) + { + selectionResult.selectedParticle = result == wxID_OK ? dialog->_selector->getSelectedParticle() : ""; + selectionResult.selectedClassname = showClassnameSelector ? dialog->getSelectedClassname() : ""; + } dialog->Destroy(); - return returnValue; + return selectionResult; } } // namespace diff --git a/radiant/ui/particles/ParticleChooserDialog.h b/radiant/ui/particles/ParticleChooserDialog.h index dd1085be14..e8e8510249 100644 --- a/radiant/ui/particles/ParticleChooserDialog.h +++ b/radiant/ui/particles/ParticleChooserDialog.h @@ -4,12 +4,11 @@ #include "ParticleSelector.h" -#include "iparticles.h" #include -#include -#include #include +class wxRadioButton; + namespace ui { @@ -24,14 +23,25 @@ class ParticleChooserDialog : private: ParticleSelector* _selector; + wxRadioButton* _funcEmitter; + wxRadioButton* _funcSmoke; + private: // Constructor creates elements - ParticleChooserDialog(); + ParticleChooserDialog(bool showClassnameSelector); void _onItemActivated( wxDataViewEvent& ev ); + std::string getSelectedClassname(); + public: + struct SelectionResult + { + std::string selectedParticle; + std::string selectedClassname; + }; + /** * Display the dialog and return the name of the selected * particle system, or the empty string if none was selected. @@ -46,6 +56,24 @@ class ParticleChooserDialog : * choice was cancelled or invalid. */ static std::string ChooseParticle(const std::string& currentParticle = ""); + + /** + * Display the dialog and return the name of the selected + * particle system, or the empty string if none was selected. + * + * @param currentParticle + * The particle name which should be highlighted in the list when the dialog + * is first displayed. If this value is left at the default value of "", no + * particle will be selected. + * + * @returns + * The name of the particle selected by the user, or an empty string if the + * choice was cancelled or invalid. + */ + static SelectionResult ChooseParticleAndEmitter(const std::string& currentParticle = ""); + +private: + static SelectionResult RunDialog(bool showClassnameSelector, const std::string& currentParticle); }; }