Skip to content
Snippets Groups Projects
Commit fc29bde8 authored by Fabian Paus's avatar Fabian Paus
Browse files

Implement tree view to select layers to show

parent f815ca39
No related branches found
No related tags found
No related merge requests found
......@@ -179,8 +179,8 @@ void ArVizStorage::compressHistory()
updateHistory.push_back(std::move(layer));
}
ARMARX_INFO << "Compressed history from " << currentHistorySize
<< " to " << newHistorySize;
ARMARX_VERBOSE << "Compressed history from " << currentHistorySize
<< " to " << newHistorySize;
long updateCounterAfterCompression = updateCounterBase + newHistorySize;
......
......@@ -101,9 +101,7 @@ namespace armarx
coinNode->ref();
root->addChild(coinNode);
CoinLayer newLayer;
newLayer.node = coinNode;
layerIt = layers.emplace(layerID, std::move(newLayer)).first;
layerIt = layers.emplace(layerID, CoinLayer(coinNode)).first;
}
CoinLayer& layer = layerIt->second;
......@@ -232,12 +230,20 @@ namespace armarx
// We never block the GUI thread with Ice calls: Only get result when call is completed
if (pullUpdateResult->isCompleted())
{
auto layerIDsBefore = getLayerIDs();
LayerUpdates pulledUpdates = storage->end_pullUpdatesSince(pullUpdateResult);
for (LayerUpdate const& update : pulledUpdates.updates)
{
apply(update);
}
updateCounter = pulledUpdates.updateCounter;
auto layerIDsAfter = getLayerIDs();
if (layerIDsAfter != layerIDsBefore)
{
emitLayersChanged(layerIDsAfter);
}
}
else
{
......@@ -258,5 +264,51 @@ namespace armarx
}
}
void CoinVisualizer::showLayer(CoinLayerID const& id, bool visible)
{
auto iter = layers.find(id);
if (iter == layers.end())
{
return;
}
viz::CoinLayer& layer = iter->second;
int childIndex = root->findChild(layer.node);
if (childIndex < 0)
{
// Layer is currently not visible
if (visible)
{
root->addChild(layer.node);
}
}
else
{
// Layer is currently visible
if (!visible)
{
root->removeChild(childIndex);
}
}
}
std::vector<CoinLayerID> CoinVisualizer::getLayerIDs()
{
std::vector<CoinLayerID> result;
for (auto& entry : layers)
{
result.push_back(entry.first);
}
return result;
}
void CoinVisualizer::emitLayersChanged(std::vector<CoinLayerID> const& layerIDs)
{
if (layersChangedCallback)
{
layersChangedCallback(layerIDs);
}
}
}
}
......@@ -18,6 +18,37 @@ namespace armarx::viz
struct CoinLayer
{
CoinLayer(SoSeparator* node)
: node(node)
{
// Increase ref-count, so we can add/remove this node without it being deleted
// This is needed for showing/hiding layers
node->ref();
}
CoinLayer(CoinLayer&& other)
: node(other.node)
{
other.node = nullptr;
}
~CoinLayer()
{
if (node)
{
node->unref();
}
}
CoinLayer(CoinLayer const&) = delete;
void operator= (CoinLayer const&) = delete;
void operator= (CoinLayer&& other)
{
node = other.node;
other.node = nullptr;
}
SoSeparator* node = nullptr;
std::map<std::string, std::unique_ptr<coin::ElementVisualization>> elements;
};
......@@ -56,6 +87,11 @@ namespace armarx::viz
elementVisualizers.emplace_back(typeid(ElementT), std::make_unique<VisualizerT>());
}
void showLayer(CoinLayerID const& id, bool visible);
std::vector<CoinLayerID> getLayerIDs();
void emitLayersChanged(std::vector<CoinLayerID> const& layerIDs);
std::mutex storageMutex;
viz::StorageInterfacePrx storage;
Ice::AsyncResultPtr pullUpdateResult;
......@@ -72,5 +108,7 @@ namespace armarx::viz
std::atomic<CoinVisualizerState> state{CoinVisualizerState::STOPPED};
viz::StorageInterfacePrx stateStorage;
std::function<void(std::vector<CoinLayerID> const&)> layersChangedCallback;
};
}
......@@ -6,13 +6,31 @@
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
<width>576</width>
<height>400</height>
</rect>
</property>
<property name="windowTitle">
<string>ArVizWidget</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QTreeWidget" name="layerTree">
<column>
<property name="text">
<string>Layer</string>
</property>
</column>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Layer Information</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
......
......@@ -31,6 +31,15 @@ using namespace armarx;
ArVizWidgetController::ArVizWidgetController()
{
widget.setupUi(getWidget());
connect(widget.layerTree, &QTreeWidget::itemChanged, this, &ArVizWidgetController::layerTreeChanged);
// We need a callback from the visualizer, when the layers have changed
// So we can update the tree accordingly
visualizer.layersChangedCallback = [this](std::vector<viz::CoinLayerID> const & layers)
{
layersChanged(layers);
};
}
ArVizWidgetController::~ArVizWidgetController()
......@@ -44,6 +53,7 @@ void ArVizWidgetController::onInitComponent()
{
usingProxy(storageName);
}
ARMARX_IMPORTANT << "OnInit: " << storageName;
}
void armarx::ArVizWidgetController::onExitComponent()
......@@ -54,11 +64,87 @@ void ArVizWidgetController::onConnectComponent()
{
getProxy(storage, storageName);
visualizer.startAsync(storage);
ARMARX_IMPORTANT << "OnConnect: " << storageName;
}
void armarx::ArVizWidgetController::onDisconnectComponent()
{
visualizer.stop();
ARMARX_IMPORTANT << "OnDisconnect: " << storageName;
}
void ArVizWidgetController::layerTreeChanged(QTreeWidgetItem* item, int /*column*/)
{
// Iterate over all items and activate/deactivate layers accordingly
for (QTreeWidgetItemIterator compIter(widget.layerTree); *compIter; ++compIter)
{
QTreeWidgetItem* componentItem = *compIter;
std::string component = componentItem->text(0).toStdString();
Qt::CheckState componentCheck = componentItem->checkState(0);
if (componentItem == item)
{
// The parent was selected or deselected, so all children should be set accordingly
for (QTreeWidgetItemIterator layerIter(componentItem); *layerIter; ++layerIter)
{
QTreeWidgetItem* layerItem = *layerIter;
if (layerItem->checkState(0) != componentCheck)
{
layerItem->setCheckState(0, componentCheck);
}
}
return;
}
for (QTreeWidgetItemIterator layerIter(componentItem); *layerIter; ++layerIter)
{
QTreeWidgetItem* layerItem = *layerIter;
std::string layer = layerItem->text(0).toStdString();
bool layerVisible = (layerItem->checkState(0) == Qt::Checked);
bool visible = layerVisible;
viz::CoinLayerID layerID(component, layer);
visualizer.showLayer(layerID, visible);
}
}
}
void ArVizWidgetController::layersChanged(std::vector<viz::CoinLayerID> const& layers)
{
QTreeWidget* tree = widget.layerTree;
QTreeWidgetItem* currentItem = nullptr;
// TODO: We need to keep the state of the old tree items
// HACK: Just remove all the children before adding them again
tree->clear();
std::string currentComponent;
for (auto& entry : layers)
{
std::string const& component = entry.first;
if (component != currentComponent)
{
// Create a new item
currentItem = new QTreeWidgetItem(tree);
currentItem->setText(0, QString::fromStdString(component));
// A new item is visible by default
currentItem->setCheckState(0, Qt::Checked);
currentComponent = component;
}
std::string const& layer = entry.second;
QTreeWidgetItem* layerItem = new QTreeWidgetItem;
layerItem->setText(0, QString::fromStdString(layer));
// A new item is visible by default
// TODO: Take into account the old state!
layerItem->setCheckState(0, Qt::Checked);
currentItem->addChild(layerItem);
}
}
SoNode* ArVizWidgetController::getScene()
......
......@@ -100,10 +100,14 @@ namespace armarx
public slots:
/* QT slot declarations */
void layerTreeChanged(QTreeWidgetItem* item, int column);
signals:
/* QT signal declarations */
private:
void layersChanged(std::vector<viz::CoinLayerID> const& layers);
private:
Ui::ArVizWidget widget;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment