From 8b71e4d04c14582c1e709107dec497cf24f33c0a Mon Sep 17 00:00:00 2001
From: Fabian Paus <fabian.paus@kit.edu>
Date: Tue, 4 Jan 2022 13:45:46 +0100
Subject: [PATCH] ArViz: Show interactive elements and currently selected
 element

---
 .../components/ArViz/Coin/Visualizer.cpp      | 10 +++++
 .../components/ArViz/Coin/Visualizer.h        |  2 +
 .../RobotAPI/gui-plugins/ArViz/ArVizWidget.ui |  2 +-
 .../ArViz/ArVizWidgetController.cpp           | 38 +++++++++++++++++++
 .../gui-plugins/ArViz/ArVizWidgetController.h |  2 +
 5 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/source/RobotAPI/components/ArViz/Coin/Visualizer.cpp b/source/RobotAPI/components/ArViz/Coin/Visualizer.cpp
index 01ed16c36..b71d5e48d 100644
--- a/source/RobotAPI/components/ArViz/Coin/Visualizer.cpp
+++ b/source/RobotAPI/components/ArViz/Coin/Visualizer.cpp
@@ -377,6 +377,7 @@ namespace coin
                 root->removeAllChildren();
                 interactionFeedbackBuffer.clear();
                 elementInteractions.clear();
+                selectedElement = nullptr;
                 layers.data.clear();
                 pulledUpdates.revision = 0;
                 pulledUpdates.updates.clear();
@@ -611,6 +612,15 @@ namespace coin
         //            << "Layer: " << id->layer.first << "/" << id->layer.second
         //            << ", element: " << id->element;
 
+        if (eventType == data::InteractionFeedbackType::SELECT)
+        {
+            selectedElement = id;
+        }
+        else
+        {
+            selectedElement = nullptr;
+        }
+
         viz::data::InteractionFeedback& feedback = interactionFeedbackBuffer.emplace_back();
         feedback.type = eventType;
         feedback.component = id->layer.first;
diff --git a/source/RobotAPI/components/ArViz/Coin/Visualizer.h b/source/RobotAPI/components/ArViz/Coin/Visualizer.h
index 885387a19..a3c9da6fa 100644
--- a/source/RobotAPI/components/ArViz/Coin/Visualizer.h
+++ b/source/RobotAPI/components/ArViz/Coin/Visualizer.h
@@ -242,6 +242,8 @@ namespace armarx::viz
         // Later, we can retrieve the element ID from this pointer, if it has been selected.
         std::vector<std::unique_ptr<ElementInteractionData>> elementInteractions;
         std::vector<viz::data::InteractionFeedback> interactionFeedbackBuffer;
+        // The currently selected element. Maybe nullptr if no element is selected.
+        ElementInteractionData* selectedElement = nullptr;
 
         void onUpdateSuccess(data::LayerUpdates const& updates);
         void onUpdateFailure(Ice::Exception const& ex);
diff --git a/source/RobotAPI/gui-plugins/ArViz/ArVizWidget.ui b/source/RobotAPI/gui-plugins/ArViz/ArVizWidget.ui
index b406c02e8..782e9d704 100644
--- a/source/RobotAPI/gui-plugins/ArViz/ArVizWidget.ui
+++ b/source/RobotAPI/gui-plugins/ArViz/ArVizWidget.ui
@@ -635,7 +635,7 @@
            </widget>
           </item>
           <item>
-           <widget class="QPushButton" name="buttonDeselect">
+           <widget class="QPushButton" name="deselectButton">
             <property name="text">
              <string>Deselect / Clear Selection</string>
             </property>
diff --git a/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.cpp b/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.cpp
index 5df52a995..cf6e7bfc7 100644
--- a/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.cpp
+++ b/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.cpp
@@ -89,6 +89,8 @@ namespace armarx
 
         connect(widget.exportToVRMLButton, &QPushButton::clicked, this, &This::exportToVRML);
 
+        connect(widget.deselectButton, &QPushButton::clicked, this, &This::onDeselectElement);
+
         connect(this, &This::connectGui, this, &This::onConnectGui, Qt::QueuedConnection);
         connect(this, &This::disconnectGui, this, &This::onDisconnectGui, Qt::QueuedConnection);
 
@@ -427,9 +429,45 @@ namespace armarx
         layerTreeChanged(nullptr, 0);
     }
 
+    void ArVizWidgetController::onDeselectElement()
+    {
+        // We just deselect all elements.
+        // Maybe we need to be more specific for strange use cases (?)
+        visualizer.selection->deselectAll();
+    }
+
+    static QString toQString(viz::ElementInteractionData const& inter)
+    {
+        std::string id = inter.layer.first + "/"
+                         + inter.layer.second + "/"
+                         + inter.element;
+        return QString::fromStdString(id);
+    }
+
     void ArVizWidgetController::onUpdate()
     {
         visualizer.update();
+
+        // Show the currently selected element
+        QString selectedElementName("<None>");
+        if (visualizer.selectedElement)
+        {
+            selectedElementName = toQString(*visualizer.selectedElement);
+        }
+        widget.labelSelectedElement->setText(selectedElementName);
+
+        // Show the interactive elements
+        int currentCount = widget.listInteractiveElements->count();
+        int newCount = (int)visualizer.elementInteractions.size();
+        if (newCount != currentCount)
+        {
+            widget.listInteractiveElements->clear();
+            for (auto& interaction : visualizer.elementInteractions)
+            {
+                QString elementID = toQString(*interaction);
+                widget.listInteractiveElements->addItem(elementID);
+            }
+        }
     }
 
     void ArVizWidgetController::onTimingObserverUpdate()
diff --git a/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.h b/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.h
index cd089f6c8..27b6cfd52 100644
--- a/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.h
+++ b/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.h
@@ -138,6 +138,8 @@ namespace armarx
         void showAllLayers(bool visible);
         void showFilteredLayers(bool visible);
 
+        void onDeselectElement();
+
         void onUpdate();
         void onTimingObserverUpdate();
 
-- 
GitLab