diff --git a/source/EngineInterface/AuxiliaryDataParserService.cpp b/source/EngineInterface/AuxiliaryDataParserService.cpp index 6a4948154d..88a6a0ecd2 100644 --- a/source/EngineInterface/AuxiliaryDataParserService.cpp +++ b/source/EngineInterface/AuxiliaryDataParserService.cpp @@ -1,3 +1,5 @@ +#include + #include "AuxiliaryDataParserService.h" #include "GeneralSettings.h" @@ -768,6 +770,16 @@ namespace std::string base = "simulation parameters.spots." + std::to_string(index) + "."; auto& spot = parameters.spots[index]; auto& defaultSpot = defaultParameters.spots[index]; + + std::string currentName(spot.name); + std::string defaultName(defaultSpot.name); + encodeDecodeProperty(tree, currentName, defaultName, base + "name", parserTask); + + if (parserTask == ParserTask::Decode){ + currentName = currentName.substr(0, SIM_PARAM_SPOT_NAME_LENGTH - 1); // Leave space for null byte + strncpy(spot.name, currentName.c_str(), SIM_PARAM_SPOT_NAME_LENGTH); + } + encodeDecodeProperty(tree, spot.color, defaultSpot.color, base + "color", parserTask); encodeDecodeProperty(tree, spot.posX, defaultSpot.posX, base + "pos.x", parserTask); encodeDecodeProperty(tree, spot.posY, defaultSpot.posY, base + "pos.y", parserTask); diff --git a/source/EngineInterface/SimulationParametersSpot.h b/source/EngineInterface/SimulationParametersSpot.h index e8907fd192..b217250888 100644 --- a/source/EngineInterface/SimulationParametersSpot.h +++ b/source/EngineInterface/SimulationParametersSpot.h @@ -1,7 +1,7 @@ #pragma once #include - +#include #include "SimulationParametersSpotActivatedValues.h" #include "SimulationParametersSpotValues.h" @@ -86,8 +86,11 @@ union SpotShapeData RectangularSpot rectangularSpot; }; +static constexpr size_t SIM_PARAM_SPOT_NAME_LENGTH = 32; + struct SimulationParametersSpot { + char name[SIM_PARAM_SPOT_NAME_LENGTH]{}; uint32_t color = 0; float posX = 0; float posY = 0; @@ -139,7 +142,7 @@ struct SimulationParametersSpot } } - return color == other.color && posX == other.posX && posY == other.posY && velX == other.velX && velY == other.velY + return (strcmp(name, other.name) == 0) && color == other.color && posX == other.posX && posY == other.posY && velX == other.velX && velY == other.velY && fadeoutRadius == other.fadeoutRadius && values == other.values && activatedValues == other.activatedValues && shapeType == other.shapeType; } bool operator!=(SimulationParametersSpot const& other) const { return !operator==(other); } diff --git a/source/Gui/SimulationParametersWindow.cpp b/source/Gui/SimulationParametersWindow.cpp index e2e5ce1690..59af5cfb36 100644 --- a/source/Gui/SimulationParametersWindow.cpp +++ b/source/Gui/SimulationParametersWindow.cpp @@ -1,5 +1,7 @@ #include "SimulationParametersWindow.h" +#include + #include #include #include @@ -72,6 +74,12 @@ _SimulationParametersWindow::_SimulationParametersWindow( for (int i = 0; i < CellFunction_Count; ++i) { _cellFunctionStrings.emplace_back(Const::CellFunctionToStringMap.at(i)); } + + _serialTabID = 0; + for (int i = 0; i < MAX_SPOTS; ++i) { + _spotNameStrings.emplace_back(""); + _spotTabIDs.emplace_back(std::to_string(0)); + } } _SimulationParametersWindow::~_SimulationParametersWindow() @@ -101,8 +109,12 @@ void _SimulationParametersWindow::processIntern() SimulationParametersSpot _SimulationParametersWindow::createSpot(SimulationParameters const& simParameters, int index) { - auto worldSize = _simController->getWorldSize(); SimulationParametersSpot spot; + + strncpy(spot.name, std::string("Zone " + std::to_string(index)).c_str(), SIM_PARAM_SPOT_NAME_LENGTH); + + auto worldSize = _simController->getWorldSize(); + spot.posX = toFloat(worldSize.x / 2); spot.posY = toFloat(worldSize.y / 2); @@ -148,6 +160,8 @@ void _SimulationParametersWindow::processToolbar() ImGui::SameLine(); if (AlienImGui::ToolbarButton(ICON_FA_COPY)) { _copiedParameters = _simController->getSimulationParameters(); + _copiedSpotNameStrings = _spotNameStrings; + _copiedSpotTabIDs = _spotTabIDs; printOverlayMessage("Simulation parameters copied"); } AlienImGui::Tooltip("Copy simulation parameters"); @@ -157,6 +171,8 @@ void _SimulationParametersWindow::processToolbar() if (AlienImGui::ToolbarButton(ICON_FA_PASTE)) { _simController->setSimulationParameters(*_copiedParameters); _simController->setOriginalSimulationParameters(*_copiedParameters); + _spotNameStrings = _copiedSpotNameStrings; + _spotTabIDs = _copiedSpotTabIDs; printOverlayMessage("Simulation parameters pasted"); } ImGui::EndDisabled(); @@ -171,10 +187,29 @@ void _SimulationParametersWindow::processTabWidget( SimulationParameters& origParameters) { auto currentSessionId = _simController->getSessionId(); + + bool sessionChanged = (!_sessionId.has_value() || (currentSessionId != *_sessionId)); + _focusBaseTab = sessionChanged; + + if (sessionChanged){ + for (int i = 0; i < parameters.numSpots; ++i) { + // Legacy support: version <= 4.9 do not have names for zones + if (strcmp(parameters.spots[i].name, "") == 0){ + _spotNameStrings[i] = std::string("Zone ") + std::to_string(i); + }else{ + _spotNameStrings[i] = parameters.spots[i].name; + } + _spotTabIDs[i] = std::to_string(_serialTabID); + ++_serialTabID; + } + } + + _sessionId= currentSessionId; + if (ImGui::BeginChild("##", ImVec2(0, 0), false)) { - if (ImGui::BeginTabBar("##Parameters", ImGuiTabBarFlags_AutoSelectNewTabs | ImGuiTabBarFlags_FittingPolicyResizeDown)) { + if (ImGui::BeginTabBar("##Parameters", ImGuiTabBarFlags_AutoSelectNewTabs | ImGuiTabBarFlags_FittingPolicyResizeDown | ImGuiTabBarFlags_Reorderable)) { //add spot if (parameters.numSpots < MAX_SPOTS) { @@ -184,30 +219,35 @@ void _SimulationParametersWindow::processTabWidget( origParameters.spots[index] = createSpot(parameters, index); ++parameters.numSpots; ++origParameters.numSpots; + + _spotNameStrings[index] = parameters.spots[index].name; + _spotTabIDs[index] = std::to_string(_serialTabID); + ++_serialTabID; + _simController->setSimulationParameters(parameters); _simController->setOriginalSimulationParameters(origParameters); } AlienImGui::Tooltip("Add parameter zone"); } - bool open = true; - if (ImGui::BeginTabItem("Base", &open, _focusBaseTab ? ImGuiTabItemFlags_SetSelected : ImGuiTabItemFlags_None)) { + if (ImGui::BeginTabItem("Base", nullptr, _focusBaseTab ? ImGuiTabItemFlags_SetSelected : ImGuiTabItemFlags_NoReorder)) { processBase(parameters, origParameters); ImGui::EndTabItem(); } - - for (int tab = 0; tab < parameters.numSpots; ++tab) { + for (int tab = 0; tab < parameters.numSpots;) { SimulationParametersSpot& spot = parameters.spots[tab]; SimulationParametersSpot const& origSpot = origParameters.spots[tab]; - std::string name = "Zone " + std::to_string(tab + 1); - if (ImGui::BeginTabItem(name.c_str(), &open, ImGuiTabItemFlags_None)) { - processSpot(spot, origSpot, parameters); + + bool open = true; + std::string label = std::string(_spotNameStrings[tab] + std::string("###") + _spotTabIDs[tab]); + if (ImGui::BeginTabItem(label.c_str(), &open, ImGuiTabItemFlags_None)) { + processSpot(tab,spot, origSpot, parameters); ImGui::EndTabItem(); } - - //delete spot if (!open) { for (int i = tab; i < parameters.numSpots - 1; ++i) { + _spotNameStrings[i] = _spotNameStrings[i + 1]; + _spotTabIDs[i] = _spotTabIDs[i+1]; parameters.spots[i] = parameters.spots[i + 1]; origParameters.spots[i] = origParameters.spots[i + 1]; } @@ -215,6 +255,8 @@ void _SimulationParametersWindow::processTabWidget( --origParameters.numSpots; _simController->setSimulationParameters(parameters); _simController->setOriginalSimulationParameters(origParameters); + }else{ + ++tab; } } @@ -222,9 +264,6 @@ void _SimulationParametersWindow::processTabWidget( } } ImGui::EndChild(); - - _focusBaseTab = !_sessionId.has_value() || currentSessionId != *_sessionId; - _sessionId= currentSessionId; } void _SimulationParametersWindow::processBase( @@ -1442,6 +1481,7 @@ void _SimulationParametersWindow::processBase( } void _SimulationParametersWindow::processSpot( + int tab, SimulationParametersSpot& spot, SimulationParametersSpot const& origSpot, SimulationParameters const& parameters) @@ -1449,6 +1489,14 @@ void _SimulationParametersWindow::processSpot( if (ImGui::BeginChild("##", ImVec2(0, 0), false, ImGuiWindowFlags_HorizontalScrollbar)) { auto worldSize = _simController->getWorldSize(); + if (AlienImGui::BeginTreeNode(AlienImGui::TreeNodeParameters().text("General"))) { + if(AlienImGui::InputText(AlienImGui::InputTextParameters().name("Name").textWidth(RightColumnWidth), _spotNameStrings[tab])){ + _spotNameStrings[tab] = _spotNameStrings[tab].substr(0, SIM_PARAM_SPOT_NAME_LENGTH - 1); // Leave space for null byte + strncpy(spot.name, _spotNameStrings[tab].c_str(), SIM_PARAM_SPOT_NAME_LENGTH); + } + AlienImGui::EndTreeNode(); + } + /** * Colors and location */ @@ -2151,6 +2199,11 @@ void _SimulationParametersWindow::onOpenParameters() if (!SerializerService::deserializeSimulationParametersFromFile(parameters, firstFilename.string())) { MessageDialog::getInstance().information("Open simulation parameters", "The selected file could not be opened."); } else { + for(int spot = 0; spot < parameters.numSpots; ++spot){ + _spotNameStrings[spot] = std::string(parameters.spots[spot].name); + _spotTabIDs[spot] = std::to_string(_serialTabID); + ++_serialTabID; + } _simController->setSimulationParameters(parameters); } }); diff --git a/source/Gui/SimulationParametersWindow.h b/source/Gui/SimulationParametersWindow.h index c27ba3f0a0..9941e2e7a3 100644 --- a/source/Gui/SimulationParametersWindow.h +++ b/source/Gui/SimulationParametersWindow.h @@ -21,7 +21,7 @@ class _SimulationParametersWindow : public _AlienWindow void processToolbar(); void processTabWidget(SimulationParameters& parameters, SimulationParameters const& lastParameters, SimulationParameters& origParameters); void processBase(SimulationParameters& parameters, SimulationParameters const& origParameters); - void processSpot(SimulationParametersSpot& spot, SimulationParametersSpot const& origSpot, SimulationParameters const& parameters); + void processSpot(int tab, SimulationParametersSpot& spot, SimulationParametersSpot const& origSpot, SimulationParameters const& parameters); void processAddonList(SimulationParameters& parameters, SimulationParameters const& lastParameters, SimulationParameters const& origParameters); void onOpenParameters(); @@ -41,7 +41,14 @@ class _SimulationParametersWindow : public _AlienWindow std::optional _sessionId; bool _focusBaseTab = false; std::vector _cellFunctionStrings; - + + std::vector _spotNameStrings; + std::vector _spotTabIDs; + std::vector _copiedSpotNameStrings; + std::vector _copiedSpotTabIDs; + + int _serialTabID; + bool _featureListOpen = false; float _featureListHeight = 200.0f; }; \ No newline at end of file