From f7fb11d1f3d639d9f20bf19629d4188023c438dc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20=C5=A0toura=C4=8D?= <525032@mail.muni.cz>
Date: Wed, 8 May 2024 16:04:12 +0200
Subject: [PATCH] improve module rotation ui

---
 src/edit/include/edit/editor.hpp |  1 +
 src/edit/src/editor.cpp          | 13 ++++----
 src/gui/include/gui/ui.hpp       |  2 ++
 src/gui/src/ui.cpp               | 52 ++++++++++++++++++++++++++------
 4 files changed, 51 insertions(+), 17 deletions(-)

diff --git a/src/edit/include/edit/editor.hpp b/src/edit/include/edit/editor.hpp
index 286b3bf..dafc865 100644
--- a/src/edit/include/edit/editor.hpp
+++ b/src/edit/include/edit/editor.hpp
@@ -55,6 +55,7 @@ public:
     int add_module_list_index = -1;
     float module_translation_step = 1.0f;
     float module_rotation_step = 1.0f;
+    int module_rotation_input = 0;
     float component_rotation_step = 1.0f;
     
     connector_ptr connector;
diff --git a/src/edit/src/editor.cpp b/src/edit/src/editor.cpp
index c00d33d..a0a6231 100644
--- a/src/edit/src/editor.cpp
+++ b/src/edit/src/editor.cpp
@@ -2072,7 +2072,6 @@ void Editor::doRotateComponentAction()
     updateSelectedComponent();
     updateRotationHint();
     rotateComponent();
-    // TO DO: This detects collision between 30 and 60 degrees when rotating shoes
     detectCollision(can_rotate_component, rofiworld);
 }
 
@@ -2167,8 +2166,8 @@ void Editor::controlConnectModule()
 void Editor::controlManipulateModule()
 {
     is_removing_module = keyboard.just_pressed().contains("Delete");
-    is_moving_module = mouse.down().contains("MouseLeft") /*&& 
-                        (keyboard.down().contains("LeftCtrl")) || keyboard.down().contains("LeftShift")) */
+    is_moving_module = (mouse.down().contains("MouseLeft") && 
+                        (keyboard.down().contains("LeftCtrl")) || keyboard.down().contains("LeftShift"))
                        || is_moving_module;
 }
 
@@ -2373,14 +2372,14 @@ void Editor::manipulateModule()
         removeModule(selected_module);
     else if (is_rotating_module)
         rotateModule(selected_module, module_rotation_angles);
-    else
+    else if (is_moving_module)
     {
         moveObject(selected_module->getNode());
-
         //ui move
-        if (is_moving_module)
-            selected_module->getNode()->translatePosVecWorld(module_position);
+        selected_module->getNode()->translatePosVecWorld(module_position);
     }
+    else
+        object_moving = false;
 }
 
 void Editor::selectModule()
diff --git a/src/gui/include/gui/ui.hpp b/src/gui/include/gui/ui.hpp
index 80a66c6..425282a 100644
--- a/src/gui/include/gui/ui.hpp
+++ b/src/gui/include/gui/ui.hpp
@@ -46,6 +46,8 @@ void module_selection_ui(const osi::Window &window, edit::UIData &data);
 void module_connection_ui(const osi::Window &window, edit::UIData &data);
 void module_movement_ui(const osi::Window &window, edit::UIData &data);
 void module_rotation_ui(const osi::Window &window, edit::UIData &data);
+void module_rotation_drag(edit::UIData &data, glm::vec3 &euler_angles);
+void module_rotation_manual(edit::UIData &data, glm::vec3 &euler_angles);
 void component_rotation_ui(const osi::Window &window, edit::UIData &data);
 void save_module_ui(const osi::Window &window, edit::UIData &data);
 void export_file_ui(const osi::Window &window, edit::UIData &data);
diff --git a/src/gui/src/ui.cpp b/src/gui/src/ui.cpp
index a353fea..6f07443 100644
--- a/src/gui/src/ui.cpp
+++ b/src/gui/src/ui.cpp
@@ -559,6 +559,10 @@ void module_connection_ui(const osi::Window &window, edit::UIData &data)
         ImGui::Text(orientation.c_str());
         ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.7f, 0.0f, 0.0f, 1.0f));
         data.is_connecting_modules = ImGui::Button("Disconnect");
+        
+        ImGui::SetTooltip("Disconnect (M)");
+        if (ImGui::IsItemHovered())
+            ImGui::SetTooltip("Disconnect (M)");
         ImGui::PopStyleColor();
     }
     else
@@ -572,6 +576,8 @@ void module_connection_ui(const osi::Window &window, edit::UIData &data)
         
         ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.0f, 0.0f, 0.7f, 1.0f));
         data.is_connecting_modules = ImGui::Button("Connect");
+        if (ImGui::IsItemHovered())
+            ImGui::SetTooltip("Connect (M)");
         ImGui::PopStyleColor();
     }
 
@@ -618,12 +624,12 @@ void module_rotation_ui(const osi::Window &window, edit::UIData &data)
 
     float size_x = static_cast<float>(window.size().x);
     float size_y = static_cast<float>(window.size().y);
-    ImGui::SetNextWindowPos(ImVec2(size_x, size_y - 40.0f), ImGuiCond_Always, ImVec2(1.0f, 1.0f));
+    ImGui::SetNextWindowPos(ImVec2(size_x, size_y - 40.0f), ImGuiCond_Appearing, ImVec2(1.0f, 1.0f));
 
     ImGui::Begin("Module Rotation##ModuleRotationMenu", NULL, ImGuiWindowFlags_NoMove 
                                                               | ImGuiWindowFlags_NoResize 
                                                               | ImGuiWindowFlags_NoCollapse 
-                                                              | ImGuiWindowFlags_AlwaysAutoResize);
+                                                              | ImGuiWindowFlags_NoScrollbar);
 
     ImGui::DragFloat("Step", &data.module_rotation_step, 0.25f, 0.0f, 90.0f, "%.3f", ImGuiSliderFlags_AlwaysClamp);
 
@@ -631,18 +637,40 @@ void module_rotation_ui(const osi::Window &window, edit::UIData &data)
     euler_angles = glm::degrees(euler_angles);
     glm::vec3 prev_euler_angles = euler_angles;
 
-    float min_limit = -360.0f;
-    float max_limit = 360.0f;
+
 
     ImGui::Text("Rotation Axes:");
     ImGui::RadioButton("Local", &data.coordinate_space_selection, 0); 
     ImGui::SameLine();
     ImGui::RadioButton("World", &data.coordinate_space_selection, 1);
 
+    ImGui::Text("Input:");
+    ImGui::RadioButton("Drag", &data.module_rotation_input, 0); 
+    ImGui::SameLine();
+    ImGui::RadioButton("Manual", &data.module_rotation_input, 1);
+
+    ImGui::Separator();
+
+    ImGui::Text("World Space Angles");
+    if (data.module_rotation_input == 0)
+        module_rotation_drag(data, euler_angles);
+    else
+        module_rotation_manual(data, euler_angles);
+
+    ImGui::End();
+
+    data.module_rotation_angles = euler_angles - prev_euler_angles;
+    data.is_rotating_module = data.module_rotation_angles != glm::vec3(0.0f, 0.0f, 0.0f);
+}
+
+void module_rotation_drag(edit::UIData &data, glm::vec3 &euler_angles)
+{
     const char *button_labels[6] = { "##Arrow-X", "##Arrow-Y", "##Arrow-Z", "##Arrow+X", "##Arrow+Y", "##Arrow+Z" };
     const char *drag_labels[3] = { "X##ModuleRotationDragX", "Y##ModuleRotationDragY", "Z##ModuleRotationDragZ" };
 
-    ImGui::Text("World Space Angles");
+    float min_limit = -360.0f;
+    float max_limit = 360.0f;
+
     for (int i = 0; i < 3; ++i)
     {
         if (ImGui::ArrowButton(button_labels[i], 0))
@@ -653,11 +681,15 @@ void module_rotation_ui(const osi::Window &window, edit::UIData &data)
         if (ImGui::ArrowButton(button_labels[i + 3], 1))
             euler_angles[i] = glm::clamp(euler_angles[i] + data.module_rotation_step, min_limit, max_limit);
     }
-
-    ImGui::End();
-
-    data.module_rotation_angles = euler_angles - prev_euler_angles;
-    data.is_rotating_module = data.module_rotation_angles != glm::vec3(0.0f, 0.0f, 0.0f);
+}
+void module_rotation_manual(edit::UIData &data, glm::vec3 &euler_angles)
+{
+    const char *input_labels[3] = { "X##ModuleRotationInputX", "Y##ModuleRotationInputY", "Z##ModuleRotationInputZ" };
+    for (int i = 0; i < 3; ++i)
+    {
+        ImGui::InputFloat(input_labels[i], &euler_angles[i], data.module_rotation_step, data.module_rotation_step, "%.3f°", 
+                          ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue);
+    }
 }
 
 void component_rotation_ui(const osi::Window &window, edit::UIData &data)
-- 
GitLab