From be4d5a705b5e5f8ae3e7271e416668abed5160eb Mon Sep 17 00:00:00 2001 From: Christian Heinemann Date: Thu, 26 Sep 2024 17:36:15 +0200 Subject: [PATCH] + cursor for position selection and editing changed + tooltip for revert and position select button + setting 20 creatures per colony --- source/Gui/AlienImGui.cpp | 15 +++-- source/Gui/AlienImGui.h | 2 + source/Gui/MainWindow.cpp | 3 +- source/Gui/RadiationSourcesWindow.cpp | 62 ++++++++----------- source/Gui/RadiationSourcesWindow.h | 3 +- .../Gui/SimulationInteractionController.cpp | 59 +++++++++++++++--- source/Gui/SimulationParametersWindow.cpp | 14 +++-- source/Gui/SimulationParametersWindow.h | 4 -- source/Gui/StatisticsWindow.cpp | 2 +- 9 files changed, 99 insertions(+), 65 deletions(-) diff --git a/source/Gui/AlienImGui.cpp b/source/Gui/AlienImGui.cpp index 30dd01cd4..9a2ea79f2 100644 --- a/source/Gui/AlienImGui.cpp +++ b/source/Gui/AlienImGui.cpp @@ -21,11 +21,6 @@ namespace { - bool revertButton(std::string const& id) - { - return ImGui::Button((ICON_FA_UNDO "##" + id).c_str()); - } - auto constexpr HoveredTimer = 0.5f; } @@ -79,6 +74,7 @@ bool AlienImGui::SliderFloat2(SliderFloat2Parameters const& parameters, float& v if (AlienImGui::SelectableButton(AlienImGui::SelectableButtonParameters().name(ICON_FA_CROSSHAIRS), mousePickerEnabled)) { parameters._setMousePickerEnabledFunc.value()(mousePickerEnabled); } + AlienImGui::Tooltip("Select a position with the mouse"); if (parameters._getMousePickerEnabledFunc.value()()) { if (auto pos = parameters._getMousePickerPositionFunc.value()()) { valueX = pos->x; @@ -92,7 +88,7 @@ bool AlienImGui::SliderFloat2(SliderFloat2Parameters const& parameters, float& v ImGui::SameLine(); ImGui::BeginDisabled(valueX == parameters._defaultValue->x && valueY == parameters._defaultValue->y); - if (revertButton(parameters._name)) { + if (AlienImGui::revertButton(parameters._name)) { valueX = parameters._defaultValue->x; valueY = parameters._defaultValue->y; } @@ -2000,6 +1996,13 @@ ImVec2 AlienImGui::RotationCenter(ImDrawList* drawList) return ImVec2((l.x + u.x) / 2, (l.y + u.y) / 2); // or use _ClipRectStack? } +bool AlienImGui::revertButton(std::string const& id) +{ + auto result = ImGui::Button((ICON_FA_UNDO "##" + id).c_str()); + AlienImGui::Tooltip("Revert changes"); + return result; +} + namespace { ImVec2 operator-(const ImVec2& l, const ImVec2& r) diff --git a/source/Gui/AlienImGui.h b/source/Gui/AlienImGui.h index 531ceafc6..68cbf01f9 100644 --- a/source/Gui/AlienImGui.h +++ b/source/Gui/AlienImGui.h @@ -378,6 +378,8 @@ class AlienImGui static ImVec2 RotationCenter(ImDrawList* drawList); + static bool revertButton(std::string const& id); + static std::unordered_set _basicSilderExpanded; static int _rotationStartIndex; static std::unordered_map _neuronSelectedInput; diff --git a/source/Gui/MainWindow.cpp b/source/Gui/MainWindow.cpp index 9fb5e0fc5..53490c494 100644 --- a/source/Gui/MainWindow.cpp +++ b/source/Gui/MainWindow.cpp @@ -125,11 +125,10 @@ _MainWindow::_MainWindow(SimulationController const& simController, GuiLogger co std::make_shared<_EditorController>(_simController); _simulationView = std::make_shared<_SimulationView>(_simController); _simInteractionController = std::make_shared<_SimulationInteractionController>(_simController, _editorController, _simulationView); - simulationViewPtr = _simulationView.get(); _statisticsWindow = std::make_shared<_StatisticsWindow>(_simController); _temporalControlWindow = std::make_shared<_TemporalControlWindow>(_simController, _statisticsWindow); _spatialControlWindow = std::make_shared<_SpatialControlWindow>(_simController, _temporalControlWindow); - _radiationSourcesWindow = std::make_shared<_RadiationSourcesWindow>(_simController); + _radiationSourcesWindow = std::make_shared<_RadiationSourcesWindow>(_simController, _simInteractionController); _simulationParametersWindow = std::make_shared<_SimulationParametersWindow>(_simController, _radiationSourcesWindow, _simInteractionController); _gpuSettingsDialog = std::make_shared<_GpuSettingsDialog>(_simController); _startupController = std::make_shared<_StartupController>(_simController, _temporalControlWindow); diff --git a/source/Gui/RadiationSourcesWindow.cpp b/source/Gui/RadiationSourcesWindow.cpp index e3081dfdc..7889ffb82 100644 --- a/source/Gui/RadiationSourcesWindow.cpp +++ b/source/Gui/RadiationSourcesWindow.cpp @@ -6,15 +6,17 @@ #include "RadiationSourcesWindow.h" #include "StyleRepository.h" +#include "SimulationInteractionController.h" namespace { auto const RightColumnWidth = 120.0f; } -_RadiationSourcesWindow::_RadiationSourcesWindow(SimulationController const& simController) +_RadiationSourcesWindow::_RadiationSourcesWindow(SimulationController const& simController, SimulationInteractionController const& simInteractionController) : _AlienWindow("Radiation sources", "windows.radiation sources", false) , _simController(simController) + , _simInteractionController(simInteractionController) {} void _RadiationSourcesWindow::processIntern() @@ -80,42 +82,32 @@ bool _RadiationSourcesWindow::processTab(int index) } } - 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") + auto getMousePickerEnabledFunc = [&]() { return _simInteractionController->isPositionSelectionMode(); }; + auto setMousePickerEnabledFunc = [&](bool value) { _simInteractionController->setPositionSelectionMode(value); }; + auto getMousePickerPositionFunc = [&]() { return _simInteractionController->getPositionSelectionData(); }; + AlienImGui::SliderFloat2( + AlienImGui::SliderFloat2Parameters() + .name("Position") .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") + .min({0, 0}) + .max(toRealVector2D(worldSize)) + .defaultValue(RealVector2D{origSource.posX, origSource.posY}) + .format("%.2f") + .getMousePickerEnabledFunc(getMousePickerEnabledFunc) + .setMousePickerEnabledFunc(setMousePickerEnabledFunc) + .getMousePickerPositionFunc(getMousePickerPositionFunc), + source.posX, + source.posY); + AlienImGui::SliderFloat2( + AlienImGui::SliderFloat2Parameters() + .name("Velocity") .textWidth(RightColumnWidth) - .min(-4.0f) - .max(4.0f) - .format("%.3f") - .defaultValue(&origSource.velY), - &source.velY); + .min({-4.0f, -4.0f}) + .max({4.0f, 4.0f}) + .defaultValue(RealVector2D{origSource.velX, origSource.velY}) + .format("%.2f"), + source.velX, + source.velY); AlienImGui::SliderFloat( AlienImGui::SliderFloatParameters() .name("Angle") diff --git a/source/Gui/RadiationSourcesWindow.h b/source/Gui/RadiationSourcesWindow.h index 0f79f2d8a..eb1df8ed4 100644 --- a/source/Gui/RadiationSourcesWindow.h +++ b/source/Gui/RadiationSourcesWindow.h @@ -7,7 +7,7 @@ class _RadiationSourcesWindow : public _AlienWindow { public: - _RadiationSourcesWindow(SimulationController const& simController); + _RadiationSourcesWindow(SimulationController const& simController, SimulationInteractionController const& simInteractionController); private: void processIntern() override; @@ -21,4 +21,5 @@ class _RadiationSourcesWindow : public _AlienWindow void validationAndCorrection(RadiationSource& source) const; SimulationController _simController; + SimulationInteractionController _simInteractionController; }; \ No newline at end of file diff --git a/source/Gui/SimulationInteractionController.cpp b/source/Gui/SimulationInteractionController.cpp index 9ad38e508..f32cba473 100644 --- a/source/Gui/SimulationInteractionController.cpp +++ b/source/Gui/SimulationInteractionController.cpp @@ -344,21 +344,56 @@ void _SimulationInteractionController::drawCursor() ImGui::SetMouseCursor(ImGuiMouseCursor_None); } - if (_modes.positionSelectionMode || _modes.editMode) { + // position selection cursor + if (_modes.positionSelectionMode) { + auto cursorSize = scale(CursorRadius); + + // shadow + drawList->AddRectFilled( + {mousePos.x - scale(2.0f), mousePos.y - cursorSize}, {mousePos.x + scale(2.0f), mousePos.y - cursorSize / 2}, Const::CursorShadowColor); + drawList->AddRectFilled( + {mousePos.x - scale(2.0f), mousePos.y + cursorSize / 2}, {mousePos.x + scale(2.0f), mousePos.y + cursorSize}, Const::CursorShadowColor); + drawList->AddRectFilled( + {mousePos.x - cursorSize, mousePos.y - scale(2.0f)}, {mousePos.x - cursorSize / 2, mousePos.y + scale(2.0f)}, Const::CursorShadowColor); + drawList->AddRectFilled( + {mousePos.x + cursorSize / 2, mousePos.y - scale(2.0f)}, {mousePos.x + cursorSize, mousePos.y + scale(2.0f)}, Const::CursorShadowColor); + + // foreground + drawList->AddRectFilled( + {mousePos.x - scale(1.0f), mousePos.y - cursorSize}, {mousePos.x + scale(1.0f), mousePos.y - cursorSize / 2}, Const::CursorColor); + drawList->AddRectFilled( + {mousePos.x - scale(1.0f), mousePos.y + cursorSize / 2}, {mousePos.x + scale(1.0f), mousePos.y + cursorSize}, Const::CursorColor); + drawList->AddRectFilled( + {mousePos.x - cursorSize, mousePos.y - scale(1.0f)}, {mousePos.x - cursorSize / 2, mousePos.y + scale(1.0f)}, Const::CursorColor); + drawList->AddRectFilled( + {mousePos.x + cursorSize / 2, mousePos.y - scale(1.0f)}, {mousePos.x + cursorSize, mousePos.y + scale(1.0f)}, Const::CursorColor); + return; + } + + // editing cursors + if (_modes.editMode) { if (!_modes.drawMode || _simController->isSimulationRunning()) { auto cursorSize = scale(CursorRadius); - //shadow + // shadow + drawList->AddRectFilled( + {mousePos.x - scale(2.0f), mousePos.y - cursorSize}, {mousePos.x + scale(2.0f), mousePos.y - cursorSize / 2}, Const::CursorShadowColor); drawList->AddRectFilled( - {mousePos.x - scale(2.0f), mousePos.y - cursorSize}, {mousePos.x + scale(2.0f), mousePos.y + cursorSize}, Const::CursorShadowColor); + {mousePos.x - scale(2.0f), mousePos.y + cursorSize / 2}, {mousePos.x + scale(2.0f), mousePos.y + cursorSize}, Const::CursorShadowColor); drawList->AddRectFilled( - {mousePos.x - cursorSize, mousePos.y - scale(2.0f)}, {mousePos.x + cursorSize, mousePos.y + scale(2.0f)}, Const::CursorShadowColor); + {mousePos.x - cursorSize, mousePos.y - scale(2.0f)}, {mousePos.x - cursorSize / 2, mousePos.y + scale(2.0f)}, Const::CursorShadowColor); + drawList->AddRectFilled( + {mousePos.x + cursorSize / 2, mousePos.y - scale(2.0f)}, {mousePos.x + cursorSize, mousePos.y + scale(2.0f)}, Const::CursorShadowColor); - //foreground + // foreground + drawList->AddRectFilled( + {mousePos.x - scale(1.0f), mousePos.y - cursorSize}, {mousePos.x + scale(1.0f), mousePos.y - cursorSize / 2}, Const::CursorColor); drawList->AddRectFilled( - {mousePos.x - scale(1.0f), mousePos.y - cursorSize}, {mousePos.x + scale(1.0f), mousePos.y + cursorSize}, Const::CursorColor); + {mousePos.x - scale(1.0f), mousePos.y + cursorSize / 2}, {mousePos.x + scale(1.0f), mousePos.y + cursorSize}, Const::CursorColor); drawList->AddRectFilled( - {mousePos.x - cursorSize, mousePos.y - scale(1.0f)}, {mousePos.x + cursorSize, mousePos.y + scale(1.0f)}, Const::CursorColor); + {mousePos.x - cursorSize, mousePos.y - scale(1.0f)}, {mousePos.x - cursorSize / 2, mousePos.y + scale(1.0f)}, Const::CursorColor); + drawList->AddRectFilled( + {mousePos.x + cursorSize / 2, mousePos.y - scale(1.0f)}, {mousePos.x + cursorSize, mousePos.y + scale(1.0f)}, Const::CursorColor); } else { auto zoom = Viewport::getZoomFactor(); auto radius = editorModel->getPencilWidth() * zoom; @@ -367,10 +402,14 @@ void _SimulationInteractionController::drawCursor() AlienImGui::ConvertRGBtoHSV(color, h, s, v); drawList->AddCircleFilled(mousePos, radius, ImColor::HSV(h, s, v, 0.6f)); } - } else { + return; + } + + // navigation cursor + if (!_modes.editMode) { auto cursorSize = scale(CursorRadius); - //shadow + // shadow drawList->AddCircle(mousePos, cursorSize / 2, Const::CursorShadowColor, 0, scale(4.0f)); drawList->AddLine( {mousePos.x + sqrtf(2.0f) / 2.0f * cursorSize / 2, mousePos.y + sqrtf(2.0f) / 2.0f * cursorSize / 2}, @@ -378,7 +417,7 @@ void _SimulationInteractionController::drawCursor() Const::CursorShadowColor, scale(4.0f)); - //foreground + // foreground drawList->AddCircle(mousePos, cursorSize / 2, Const::CursorColor, 0, scale(2.0f)); drawList->AddLine( {mousePos.x + sqrtf(2.0f) / 2.0f * cursorSize / 2, mousePos.y + sqrtf(2.0f) / 2.0f * cursorSize / 2}, diff --git a/source/Gui/SimulationParametersWindow.cpp b/source/Gui/SimulationParametersWindow.cpp index 60c82a6ff..bd666d123 100644 --- a/source/Gui/SimulationParametersWindow.cpp +++ b/source/Gui/SimulationParametersWindow.cpp @@ -77,9 +77,6 @@ _SimulationParametersWindow::_SimulationParametersWindow( _cellFunctionStrings.emplace_back(Const::CellFunctionToStringMap.at(i)); } - _getMousePickerEnabledFunc = [&]() { return _simInteractionController->isPositionSelectionMode(); }; - _setMousePickerEnabledFunc = [&](bool value) { _simInteractionController->setPositionSelectionMode(value); }; - _getMousePickerPositionFunc = [&]() { return _simInteractionController->getPositionSelectionData(); }; } _SimulationParametersWindow::~_SimulationParametersWindow() @@ -1662,6 +1659,11 @@ bool _SimulationParametersWindow::processSpot(int index) spot.shapeType)) { createDefaultSpotData(spot); } + + auto getMousePickerEnabledFunc = [&]() { return _simInteractionController->isPositionSelectionMode(); }; + auto setMousePickerEnabledFunc = [&](bool value) { _simInteractionController->setPositionSelectionMode(value); }; + auto getMousePickerPositionFunc = [&]() { return _simInteractionController->getPositionSelectionData(); }; + AlienImGui::SliderFloat2( AlienImGui::SliderFloat2Parameters() .name("Position") @@ -1670,9 +1672,9 @@ bool _SimulationParametersWindow::processSpot(int index) .max(toRealVector2D(worldSize)) .defaultValue(RealVector2D{origSpot.posX, origSpot.posY}) .format("%.2f") - .getMousePickerEnabledFunc(_getMousePickerEnabledFunc) - .setMousePickerEnabledFunc(_setMousePickerEnabledFunc) - .getMousePickerPositionFunc(_getMousePickerPositionFunc), + .getMousePickerEnabledFunc(getMousePickerEnabledFunc) + .setMousePickerEnabledFunc(setMousePickerEnabledFunc) + .getMousePickerPositionFunc(getMousePickerPositionFunc), spot.posX, spot.posY); AlienImGui::SliderFloat2( diff --git a/source/Gui/SimulationParametersWindow.h b/source/Gui/SimulationParametersWindow.h index 63fc548a5..cf62cead4 100644 --- a/source/Gui/SimulationParametersWindow.h +++ b/source/Gui/SimulationParametersWindow.h @@ -51,8 +51,4 @@ class _SimulationParametersWindow : public _AlienWindow bool _featureListOpen = false; float _featureListHeight = 200.0f; - - std::function _getMousePickerEnabledFunc; - std::function _setMousePickerEnabledFunc; - std::function(void)> _getMousePickerPositionFunc; }; \ No newline at end of file diff --git a/source/Gui/StatisticsWindow.cpp b/source/Gui/StatisticsWindow.cpp index 7380b353a..d32a61ff1 100644 --- a/source/Gui/StatisticsWindow.cpp +++ b/source/Gui/StatisticsWindow.cpp @@ -320,7 +320,7 @@ void _StatisticsWindow::processTimelineStatistics() ImGui::TableSetColumnIndex(1); AlienImGui::Text("Diversity"); ImGui::SameLine(); - AlienImGui::HelpMarker("The number of colonies is displayed. A colony is a set of at least 40 same mutants."); + AlienImGui::HelpMarker("The number of colonies is displayed. A colony is a set of at least 20 same mutants."); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0);