From c76852f5d47d542bee22f4e57459916a8c9ff091 Mon Sep 17 00:00:00 2001 From: codereader Date: Sun, 3 Apr 2022 08:42:16 +0200 Subject: [PATCH] #5787: Add "Create Particle" option to ortho context menu. --- radiant/ui/ortho/OrthoContextMenu.cpp | 91 ++++++++++++++++----------- radiant/ui/ortho/OrthoContextMenu.h | 3 +- 2 files changed, 57 insertions(+), 37 deletions(-) diff --git a/radiant/ui/ortho/OrthoContextMenu.cpp b/radiant/ui/ortho/OrthoContextMenu.cpp index db1af77c25..25ed4f606c 100644 --- a/radiant/ui/ortho/OrthoContextMenu.cpp +++ b/radiant/ui/ortho/OrthoContextMenu.cpp @@ -2,12 +2,10 @@ #include "i18n.h" #include "selectionlib.h" -#include "ibrush.h" #include "isound.h" #include "ui/iresourcechooser.h" #include "ui/idialogmanager.h" #include "entitylib.h" // EntityFindByClassnameWalker -#include "selectionlib.h" #include "ientity.h" // Node_getEntity() #include "iregistry.h" #include "ui/imainframe.h" @@ -19,6 +17,7 @@ #include "ui/modelselector/ModelSelector.h" #include "ui/prefabselector/PrefabSelector.h" +#include "ui/particles/ParticlesChooser.h" #include "string/convert.h" #include "scene/GroupNodeChecker.h" @@ -41,6 +40,7 @@ namespace { const char* LIGHT_CLASSNAME = "light"; const char* MODEL_CLASSNAME_ANIMATED = "func_animate"; const char* MODEL_CLASSNAME_STATIC = "func_static"; + const char* PARTICLE_EMITTER_CLASSNAME = "func_emitter"; const char* PLAYERSTART_CLASSNAME = "info_player_start"; const char* ADD_ENTITY_TEXT = N_("Create Entity..."); @@ -50,6 +50,8 @@ namespace { const char* PLACE_PLAYERSTART_ICON = "player_start16.png"; const char* ADD_MODEL_TEXT = N_("Create Model..."); const char* ADD_MODEL_ICON = "cmenu_add_model.png"; + const char* ADD_PARTICLE_TEXT = N_("Create Particle..."); + const char* ADD_PARTICLE_ICON = "particle16.png"; const char* ADD_MONSTERCLIP_TEXT = N_("Surround with Monsterclip"); const char* ADD_MONSTERCLIP_ICON = "monsterclip16.png"; const char* ADD_LIGHT_TEXT = N_("Create Light..."); @@ -190,7 +192,7 @@ bool OrthoContextMenu::checkAddEntity() return !_selectionInfo.anythingSelected || _selectionInfo.onlyPrimitivesSelected; } -bool OrthoContextMenu::checkAddModel() +bool OrthoContextMenu::checkAddModelOrParticle() { return !_selectionInfo.anythingSelected; } @@ -331,50 +333,59 @@ void OrthoContextMenu::callbackAddModel() { UndoableCommand command("addModel"); - const SelectionInfo& info = GlobalSelectionSystem().getSelectionInfo(); + // Display the model selector and block waiting for a selection (may be empty) + ModelSelectorResult ms = ModelSelector::chooseModel("", true, true); + + // If a model was selected, create the entity and set its model key + if (ms.model.empty()) + { + return; + } - // To create a model selection must be empty - if (info.totalCount == 0) + try { - // Display the model selector and block waiting for a selection (may be empty) - ModelSelectorResult ms = ui::ModelSelector::chooseModel("", true, true); + auto modelDef = GlobalEntityClassManager().findModel(ms.model); + + auto className = modelDef ? MODEL_CLASSNAME_ANIMATED : MODEL_CLASSNAME_STATIC; - // If a model was selected, create the entity and set its model key - if (ms.model.empty()) + auto modelNode = GlobalEntityModule().createEntityFromSelection( + className, _lastPoint + ); + + //Node_getTraversable(GlobalSceneGraph().root())->insert(modelNode); + modelNode->getEntity().setKeyValue("model", ms.model); + modelNode->getEntity().setKeyValue("skin", ms.skin); + + // If 'createClip' is ticked, create a clip brush + if (ms.createClip) { - return; + GlobalCommandSystem().execute("SurroundWithMonsterclip"); } + } + catch (cmd::ExecutionFailure& e) + { + wxutil::Messagebox::ShowError(fmt::format(_("Unable to create model: {0}"), e.what())); + } +} - try - { - auto modelDef = GlobalEntityClassManager().findModel(ms.model); +void OrthoContextMenu::callbackAddParticle() +{ + UndoableCommand command("addParticle"); - auto className = modelDef ? MODEL_CLASSNAME_ANIMATED : MODEL_CLASSNAME_STATIC; + // Display the particle selector and block waiting for a selection (may be empty) + auto selectedParticle = ParticlesChooser::ChooseParticle(); - auto modelNode = GlobalEntityModule().createEntityFromSelection( - className, _lastPoint - ); + if (selectedParticle.empty()) return; - //Node_getTraversable(GlobalSceneGraph().root())->insert(modelNode); - modelNode->getEntity().setKeyValue("model", ms.model); - modelNode->getEntity().setKeyValue("skin", ms.skin); + try + { + auto node = GlobalEntityModule().createEntityFromSelection(PARTICLE_EMITTER_CLASSNAME, _lastPoint); - // If 'createClip' is ticked, create a clip brush - if (ms.createClip) - { - GlobalCommandSystem().execute("SurroundWithMonsterclip"); - } - } - catch (cmd::ExecutionFailure& e) - { - wxutil::Messagebox::ShowError(fmt::format(_("Unable to create model: {0}"), e.what())); - } + node->getEntity().setKeyValue("model", selectedParticle); } - else + catch (cmd::ExecutionFailure& e) { - wxutil::Messagebox::ShowError( - _("Nothing must be selected for model creation") - ); + wxutil::Messagebox::ShowError(fmt::format(_("Unable to create particle entity: {0}"), e.what())); } } @@ -410,7 +421,14 @@ void OrthoContextMenu::registerDefaultItems() new wxutil::MenuItem( new wxutil::IconTextMenuItem(_(ADD_MODEL_TEXT), ADD_MODEL_ICON), std::bind(&OrthoContextMenu::callbackAddModel, this), - std::bind(&OrthoContextMenu::checkAddModel, this)) + std::bind(&OrthoContextMenu::checkAddModelOrParticle, this)) + ); + + wxutil::MenuItemPtr addParticle( + new wxutil::MenuItem( + new wxutil::IconTextMenuItem(_(ADD_PARTICLE_TEXT), ADD_PARTICLE_ICON), + std::bind(&OrthoContextMenu::callbackAddParticle, this), + std::bind(&OrthoContextMenu::checkAddModelOrParticle, this)) ); wxutil::CommandMenuItemPtr surroundWithMonsterClip( @@ -474,6 +492,7 @@ void OrthoContextMenu::registerDefaultItems() // Register all constructed items addItem(_createEntityItem, SECTION_CREATE); addItem(addModel, SECTION_CREATE); + addItem(addParticle, SECTION_CREATE); addItem(addLight, SECTION_CREATE); addItem(addSpeaker, SECTION_CREATE); addItem(addPrefab, SECTION_CREATE); diff --git a/radiant/ui/ortho/OrthoContextMenu.h b/radiant/ui/ortho/OrthoContextMenu.h index a2ced02bf1..45a9cc71e8 100644 --- a/radiant/ui/ortho/OrthoContextMenu.h +++ b/radiant/ui/ortho/OrthoContextMenu.h @@ -102,11 +102,12 @@ class OrthoContextMenu : bool checkMakeVisportal(); bool checkAddMonsterclip(); bool checkAddEntity(); - bool checkAddModel(); + bool checkAddModelOrParticle(); void addEntity(); void placePlayerStart(); void callbackAddModel(); + void callbackAddParticle(); void callbackAddLight(); void callbackAddPrefab(); void callbackAddSpeaker();