diff --git a/source/Gui/RadiationSourcesWindow.cpp b/source/Gui/RadiationSourcesWindow.cpp index 6766bcb1b..f95af615f 100644 --- a/source/Gui/RadiationSourcesWindow.cpp +++ b/source/Gui/RadiationSourcesWindow.cpp @@ -19,12 +19,10 @@ _RadiationSourcesWindow::_RadiationSourcesWindow(SimulationController const& sim void _RadiationSourcesWindow::processIntern() { - auto parameters = _simController->getSimulationParameters(); - auto lastParameters = parameters; - auto origParameters = _simController->getOriginalSimulationParameters(); - auto worldSize = _simController->getWorldSize(); + std::optional scheduleAddTab; + std::optional scheduleDelTabAtIndex; if (ImGui::BeginTabBar("##ParticleSources", ImGuiTabBarFlags_AutoSelectNewTabs | ImGuiTabBarFlags_FittingPolicyResizeDown)) { @@ -32,143 +30,175 @@ void _RadiationSourcesWindow::processIntern() //add source if (ImGui::TabItemButton("+", ImGuiTabItemFlags_Trailing | ImGuiTabItemFlags_NoTooltip)) { - auto index = parameters.numRadiationSources; - parameters.radiationSources[index] = createParticleSource(); - origParameters.radiationSources[index] = createParticleSource(); - ++parameters.numRadiationSources; - ++origParameters.numRadiationSources; - _simController->setSimulationParameters(parameters); - _simController->setOriginalSimulationParameters(origParameters); + scheduleAddTab = true; } AlienImGui::Tooltip("Add source"); } for (int tab = 0; tab < parameters.numRadiationSources; ++tab) { - RadiationSource& source = parameters.radiationSources[tab]; - RadiationSource& origSource = origParameters.radiationSources[tab]; - bool open = true; - char name[18] = {}; - bool* openPtr = &open; - snprintf(name, IM_ARRAYSIZE(name), "Source %01d", tab + 1); - if (ImGui::BeginTabItem(name, openPtr, ImGuiTabItemFlags_None)) { - - if (AlienImGui::Combo( - AlienImGui::ComboParameters() - .name("Shape") - .values({"Circular", "Rectangular"}) - .textWidth(RightColumnWidth) - .defaultValue(origSource.shapeType), - source.shapeType)) { - if (source.shapeType == RadiationSourceShapeType_Circular) { - source.shapeData.circularRadiationSource.radius = 1; - } else { - source.shapeData.rectangularRadiationSource.width = 40; - source.shapeData.rectangularRadiationSource.height = 10; - } - } - - AlienImGui::SliderFloat( - AlienImGui::SliderFloatParameters() - .name("Position X") - .textWidth(RightColumnWidth) - .min(0) - .max(toFloat(worldSize.x)) - .format("%.0f") - .defaultValue(&origSource.posX), - &source.posX); - AlienImGui::SliderFloat( - AlienImGui::SliderFloatParameters() - .name("Position Y") - .textWidth(RightColumnWidth) - .min(0) - .max(toFloat(worldSize.y)) - .format("%.0f") - .defaultValue(&origSource.posY), - &source.posY); - AlienImGui::SliderFloat( - AlienImGui::SliderFloatParameters() - .name("Velocity X") - .textWidth(RightColumnWidth) - .min(-4.0f) - .max(4.0f) - .format("%.3f") - .defaultValue(&origSource.velX), - &source.velX); - AlienImGui::SliderFloat( - AlienImGui::SliderFloatParameters() - .name("Velocity Y") - .textWidth(RightColumnWidth) - .min(-4.0f) - .max(4.0f) - .format("%.3f") - .defaultValue(&origSource.velY), - &source.velY); - AlienImGui::SliderFloat( - AlienImGui::SliderFloatParameters() - .name("Angle") - .textWidth(RightColumnWidth) - .min(-180.0f) - .max(180.0f) - .defaultEnabledValue(&origSource.useAngle) - .defaultValue(&origSource.angle) - .disabledValue(&source.angle) - .format("%.1f"), - &source.angle, - &source.useAngle); - if (source.shapeType == RadiationSourceShapeType_Circular) { - auto maxRadius = toFloat(std::min(worldSize.x, worldSize.y)); - AlienImGui::SliderFloat( - AlienImGui::SliderFloatParameters() - .name("Radius") - .textWidth(RightColumnWidth) - .min(1) - .max(maxRadius) - .format("%.0f") - .defaultValue(&origSource.shapeData.circularRadiationSource.radius), - &source.shapeData.circularRadiationSource.radius); - } - if (source.shapeType == RadiationSourceShapeType_Rectangular) { - AlienImGui::SliderFloat( - AlienImGui::SliderFloatParameters() - .name("Width") - .textWidth(RightColumnWidth) - .min(1) - .max(toFloat(worldSize.x)) - .format("%.0f") - .defaultValue(&origSource.shapeData.rectangularRadiationSource.width), - &source.shapeData.rectangularRadiationSource.width); - AlienImGui::SliderFloat( - AlienImGui::SliderFloatParameters() - .name("Height") - .textWidth(RightColumnWidth) - .min(1) - .max(toFloat(worldSize.y)) - .format("%.0f") - .defaultValue(&origSource.shapeData.rectangularRadiationSource.height), - &source.shapeData.rectangularRadiationSource.height); - } - ImGui::EndTabItem(); - validationAndCorrection(source); + if (!processTab(tab)) { + scheduleDelTabAtIndex = tab; } + } + + ImGui::EndTabBar(); + } + + if (scheduleAddTab.has_value()) { + processAppendTab(); + } + if (scheduleDelTabAtIndex.has_value()) { + processDelTab(scheduleDelTabAtIndex.value()); + } +} + +bool _RadiationSourcesWindow::processTab(int index) +{ + auto parameters = _simController->getSimulationParameters(); + auto lastParameters = parameters; + auto origParameters = _simController->getOriginalSimulationParameters(); + + auto worldSize = _simController->getWorldSize(); + + RadiationSource& source = parameters.radiationSources[index]; + RadiationSource& origSource = origParameters.radiationSources[index]; + + bool isOpen = true; + char name[18] = {}; + + snprintf(name, IM_ARRAYSIZE(name), "Source %01d", index + 1); + if (ImGui::BeginTabItem(name, &isOpen, ImGuiTabItemFlags_None)) { - //del source - if (!open) { - for (int i = tab; i < parameters.numRadiationSources - 1; ++i) { - parameters.radiationSources[i] = parameters.radiationSources[i + 1]; - origParameters.radiationSources[i] = origParameters.radiationSources[i + 1]; - } - --parameters.numRadiationSources; - --origParameters.numRadiationSources; - _simController->setSimulationParameters(parameters); - _simController->setOriginalSimulationParameters(origParameters); + if (AlienImGui::Combo( + AlienImGui::ComboParameters().name("Shape").values({"Circular", "Rectangular"}).textWidth(RightColumnWidth).defaultValue(origSource.shapeType), + source.shapeType)) { + if (source.shapeType == RadiationSourceShapeType_Circular) { + source.shapeData.circularRadiationSource.radius = 1; + } else { + source.shapeData.rectangularRadiationSource.width = 40; + source.shapeData.rectangularRadiationSource.height = 10; } } - ImGui::EndTabBar(); + AlienImGui::SliderFloat( + AlienImGui::SliderFloatParameters() + .name("Position X") + .textWidth(RightColumnWidth) + .min(0) + .max(toFloat(worldSize.x)) + .format("%.0f") + .defaultValue(&origSource.posX), + &source.posX); + AlienImGui::SliderFloat( + AlienImGui::SliderFloatParameters() + .name("Position Y") + .textWidth(RightColumnWidth) + .min(0) + .max(toFloat(worldSize.y)) + .format("%.0f") + .defaultValue(&origSource.posY), + &source.posY); + AlienImGui::SliderFloat( + AlienImGui::SliderFloatParameters() + .name("Velocity X") + .textWidth(RightColumnWidth) + .min(-4.0f) + .max(4.0f) + .format("%.3f") + .defaultValue(&origSource.velX), + &source.velX); + AlienImGui::SliderFloat( + AlienImGui::SliderFloatParameters() + .name("Velocity Y") + .textWidth(RightColumnWidth) + .min(-4.0f) + .max(4.0f) + .format("%.3f") + .defaultValue(&origSource.velY), + &source.velY); + AlienImGui::SliderFloat( + AlienImGui::SliderFloatParameters() + .name("Angle") + .textWidth(RightColumnWidth) + .min(-180.0f) + .max(180.0f) + .defaultEnabledValue(&origSource.useAngle) + .defaultValue(&origSource.angle) + .disabledValue(&source.angle) + .format("%.1f"), + &source.angle, + &source.useAngle); + if (source.shapeType == RadiationSourceShapeType_Circular) { + auto maxRadius = toFloat(std::min(worldSize.x, worldSize.y)); + AlienImGui::SliderFloat( + AlienImGui::SliderFloatParameters() + .name("Radius") + .textWidth(RightColumnWidth) + .min(1) + .max(maxRadius) + .format("%.0f") + .defaultValue(&origSource.shapeData.circularRadiationSource.radius), + &source.shapeData.circularRadiationSource.radius); + } + if (source.shapeType == RadiationSourceShapeType_Rectangular) { + AlienImGui::SliderFloat( + AlienImGui::SliderFloatParameters() + .name("Width") + .textWidth(RightColumnWidth) + .min(1) + .max(toFloat(worldSize.x)) + .format("%.0f") + .defaultValue(&origSource.shapeData.rectangularRadiationSource.width), + &source.shapeData.rectangularRadiationSource.width); + AlienImGui::SliderFloat( + AlienImGui::SliderFloatParameters() + .name("Height") + .textWidth(RightColumnWidth) + .min(1) + .max(toFloat(worldSize.y)) + .format("%.0f") + .defaultValue(&origSource.shapeData.rectangularRadiationSource.height), + &source.shapeData.rectangularRadiationSource.height); + } + ImGui::EndTabItem(); + validationAndCorrection(source); } + if (parameters != lastParameters) { _simController->setSimulationParameters(parameters); } + + return isOpen; +} + +void _RadiationSourcesWindow::processAppendTab() +{ + auto parameters = _simController->getSimulationParameters(); + auto origParameters = _simController->getOriginalSimulationParameters(); + + auto index = parameters.numRadiationSources; + parameters.radiationSources[index] = createParticleSource(); + origParameters.radiationSources[index] = createParticleSource(); + ++parameters.numRadiationSources; + ++origParameters.numRadiationSources; + + _simController->setSimulationParameters(parameters); + _simController->setOriginalSimulationParameters(origParameters); +} + +void _RadiationSourcesWindow::processDelTab(int index) +{ + auto parameters = _simController->getSimulationParameters(); + auto origParameters = _simController->getOriginalSimulationParameters(); + + for (int i = index; i < parameters.numRadiationSources - 1; ++i) { + parameters.radiationSources[i] = parameters.radiationSources[i + 1]; + origParameters.radiationSources[i] = origParameters.radiationSources[i + 1]; + } + --parameters.numRadiationSources; + --origParameters.numRadiationSources; + _simController->setSimulationParameters(parameters); + _simController->setOriginalSimulationParameters(origParameters); } RadiationSource _RadiationSourcesWindow::createParticleSource() const diff --git a/source/Gui/RadiationSourcesWindow.h b/source/Gui/RadiationSourcesWindow.h index 7c09b2aad..19a926def 100644 --- a/source/Gui/RadiationSourcesWindow.h +++ b/source/Gui/RadiationSourcesWindow.h @@ -12,6 +12,10 @@ class _RadiationSourcesWindow : public _AlienWindow private: void processIntern() override; + bool processTab(int index); //return false if tab is closed + void processAppendTab(); + void processDelTab(int index); + RadiationSource createParticleSource() const; void validationAndCorrection(RadiationSource& source) const; diff --git a/source/Gui/SimulationParametersWindow.cpp b/source/Gui/SimulationParametersWindow.cpp index 50ffa4e95..310533b95 100644 --- a/source/Gui/SimulationParametersWindow.cpp +++ b/source/Gui/SimulationParametersWindow.cpp @@ -190,7 +190,7 @@ void _SimulationParametersWindow::processTabWidget( AlienImGui::Tooltip("Add parameter zone"); } - bool open = true; + bool open = true; if (ImGui::BeginTabItem("Base", &open, _focusBaseTab ? ImGuiTabItemFlags_SetSelected : ImGuiTabItemFlags_None)) { processBase(parameters, origParameters); ImGui::EndTabItem(); @@ -215,6 +215,7 @@ void _SimulationParametersWindow::processTabWidget( --origParameters.numSpots; _simController->setSimulationParameters(parameters); _simController->setOriginalSimulationParameters(origParameters); + break; } } diff --git a/source/Gui/TemporalControlWindow.cpp b/source/Gui/TemporalControlWindow.cpp index a912df45b..5afda65c7 100644 --- a/source/Gui/TemporalControlWindow.cpp +++ b/source/Gui/TemporalControlWindow.cpp @@ -181,7 +181,7 @@ void _TemporalControlWindow::processStepForwardButton() void _TemporalControlWindow::processCreateFlashbackButton() { auto result = AlienImGui::ToolbarButton(ICON_FA_CAMERA); - AlienImGui::Tooltip("Create flashback: It saves the content of the current world to the memory."); + AlienImGui::Tooltip("Creating flashback: It saves the content of the current world to the memory."); if (result) { delayedExecution([this] { onSnapshot(); }); @@ -193,7 +193,8 @@ void _TemporalControlWindow::processLoadFlashbackButton() { ImGui::BeginDisabled(!_snapshot); auto result = AlienImGui::ToolbarButton(ICON_FA_UNDO); - AlienImGui::Tooltip("Load flashback: It loads the saved world from the memory."); + AlienImGui::Tooltip("Loading flashback: It loads the saved world from the memory. Static simulation parameters will not be changed. Non-static parameters " + "(such as the position of moving zones) will be restored as well."); if (result) { delayedExecution([this] { applySnapshot(*_snapshot); }); _simController->removeSelection();