From b823dff7bde4a972b27b6c6d9abc7447b7bc8bcb Mon Sep 17 00:00:00 2001 From: Meixner <andre.meixner@kit.edu> Date: Wed, 27 Nov 2024 11:49:30 +0100 Subject: [PATCH] Updated ArvizProfileManager --- .../ArViz/ArVizWidgetController.cpp | 19 +- .../gui-plugins/ArViz/ArVizWidgetController.h | 4 +- .../ArViz/ArvizProfileManagerWidget.cpp | 288 ++++++++++++++++++ .../ArViz/ArvizProfileManagerWidget.h | 138 +++++++++ .../RobotAPI/gui-plugins/ArViz/CMakeLists.txt | 4 +- .../ArViz/HiddenCoinLayerManagerWidget.cpp | 153 ---------- .../ArViz/HiddenCoinLayerManagerWidget.h | 92 ------ 7 files changed, 440 insertions(+), 258 deletions(-) create mode 100644 source/RobotAPI/gui-plugins/ArViz/ArvizProfileManagerWidget.cpp create mode 100644 source/RobotAPI/gui-plugins/ArViz/ArvizProfileManagerWidget.h delete mode 100644 source/RobotAPI/gui-plugins/ArViz/HiddenCoinLayerManagerWidget.cpp delete mode 100644 source/RobotAPI/gui-plugins/ArViz/HiddenCoinLayerManagerWidget.h diff --git a/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.cpp b/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.cpp index 1633da37a..d7d1680c5 100644 --- a/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.cpp +++ b/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.cpp @@ -23,6 +23,7 @@ #include "ArVizWidgetController.h" #include <ArmarXCore/observers/variant/Variant.h> +#include "RobotAPI/gui-plugins/ArViz/ArvizProfileManagerWidget.h" #include <SimoxUtility/algorithm/string/string_tools.h> @@ -93,9 +94,9 @@ namespace armarx connect(this, &This::connectGui, this, &This::onConnectGui, Qt::QueuedConnection); connect(this, &This::disconnectGui, this, &This::onDisconnectGui, Qt::QueuedConnection); - hiddenCoinLayerWidget = new HiddenCoinLayerManagerWidget(); - widget.verticalLayout->addWidget(hiddenCoinLayerWidget); - connect(hiddenCoinLayerWidget, &HiddenCoinLayerManagerWidget::hiddenLayersReset, this, &This::updateHiddenLayers); + arvizeProfileLayerWidget = new ArvizProfileManagerWidget(); + widget.verticalLayout->addWidget(arvizeProfileLayerWidget); + connect(arvizeProfileLayerWidget, &ArvizProfileManagerWidget::layersReset, this, &This::updateHiddenLayers); // Layer info tree. @@ -187,7 +188,7 @@ namespace armarx QTreeWidgetItem* layerItem = componentItem->child(layerIndex); const std::string layer = layerItem->text(0).toStdString(); const viz::CoinLayerID layerID(component, layer); - const bool visible = not hiddenCoinLayerWidget->isHidden(layerID); + const bool visible = not arvizeProfileLayerWidget->isHidden(layerID); layerItem->setCheckState(0, visible ? Qt::CheckState::Checked : Qt::CheckState::Unchecked); parentChecked &= visible; visualizer.showLayer(layerID, visible); @@ -235,7 +236,7 @@ namespace armarx { layerItem->setCheckState(0, componentCheck); } - hiddenCoinLayerWidget->update(component, componentCheck == Qt::Checked); + arvizeProfileLayerWidget->update(component, componentCheck == Qt::Checked); } return; } @@ -249,7 +250,7 @@ namespace armarx viz::CoinLayerID layerID(component, layer); - hiddenCoinLayerWidget->update(layerID, layerVisible); + arvizeProfileLayerWidget->update(layerID, layerVisible); visualizer.showLayer(layerID, layerVisible); } @@ -297,7 +298,7 @@ namespace armarx // Create a new item currentItem = new QTreeWidgetItem(tree); currentItem->setText(0, QString::fromStdString(component)); - currentItem->setCheckState(0, hiddenCoinLayerWidget->isHidden(entry) ? Qt::Unchecked : Qt::Checked); + currentItem->setCheckState(0, arvizeProfileLayerWidget->isHidden(entry) ? Qt::Unchecked : Qt::Checked); componentWasNew = true; } @@ -319,7 +320,7 @@ namespace armarx std::string const& layer = entry.second; QTreeWidgetItem* layerItem = new QTreeWidgetItem; layerItem->setText(0, QString::fromStdString(layer)); - layerItem->setCheckState(0, hiddenCoinLayerWidget->isHidden(entry) ? Qt::Unchecked : Qt::Checked); + layerItem->setCheckState(0, arvizeProfileLayerWidget->isHidden(entry) ? Qt::Unchecked : Qt::Checked); if (currentItem) { @@ -341,7 +342,7 @@ namespace armarx else { // Item exists already ==> make sure that it is not shown if necessary - if (hiddenCoinLayerWidget->isHidden(iter->first) or iter->second->checkState(0) == Qt::Unchecked) + if (arvizeProfileLayerWidget->isHidden(iter->first) or iter->second->checkState(0) == Qt::Unchecked) { visualizer.showLayer(iter->first, false); } diff --git a/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.h b/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.h index d81dc69bc..783ff4bcd 100644 --- a/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.h +++ b/source/RobotAPI/gui-plugins/ArViz/ArVizWidgetController.h @@ -36,7 +36,7 @@ #include <ArmarXCore/core/system/ImportExportComponent.h> #include "LayerInfoTree.h" -#include "HiddenCoinLayerManagerWidget.h" +#include "ArvizProfileManagerWidget.h" namespace armarx @@ -228,7 +228,7 @@ namespace armarx std::vector<double> timings; - HiddenCoinLayerManagerWidget* hiddenCoinLayerWidget; + ArvizProfileManagerWidget* arvizeProfileLayerWidget; public: static QIcon GetWidgetIcon() diff --git a/source/RobotAPI/gui-plugins/ArViz/ArvizProfileManagerWidget.cpp b/source/RobotAPI/gui-plugins/ArViz/ArvizProfileManagerWidget.cpp new file mode 100644 index 000000000..e060e715c --- /dev/null +++ b/source/RobotAPI/gui-plugins/ArViz/ArvizProfileManagerWidget.cpp @@ -0,0 +1,288 @@ +#include "ArvizProfileManagerWidget.h" +#include <string> + + +#include <QVBoxLayout> +#include <QMessageBox> +#include <QBoxLayout> +#include <QLabel> +#include <QFormLayout> +#include <QDialogButtonBox> +#include <QPushButton> +#include <qboxlayout.h> +#include <qchar.h> +#include <qradiobutton.h> + +#include <ArmarXCore/core/system/ArmarXDataPath.h> +#include <ArmarXCore/core/logging/Logging.h> + +namespace armarx +{ + +ProfileDialog::ProfileDialog(QWidget *parent, const QString &name, bool additive, bool addDialog) + : QDialog(parent) +{ + setWindowTitle(addDialog ? "Add Profile" : "Edit Profile"); + + // Set up UI components + nameInput = new QLineEdit(this); + nameInput->setText(name); + + additiveRadioButton = new QRadioButton("Save added layers", this); + additiveRadioButton->setChecked(additive); + substractiveRadioButton = new QRadioButton("Save removed layers", this); + substractiveRadioButton->setChecked(not additive); + + // Save/Cancel buttons + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Save | QDialogButtonBox::Cancel, this); + connect(buttonBox, &QDialogButtonBox::accepted, this, &ProfileDialog::accept); + connect(buttonBox, &QDialogButtonBox::rejected, this, &ProfileDialog::reject); + + // Delete button + deleteButton = new QPushButton("Delete", this); + connect(deleteButton, &QPushButton::clicked, this, &ProfileDialog::deleteProfile); + + // Layouts + QFormLayout *formLayout = new QFormLayout; + formLayout->addRow("Profile Name:", nameInput); + formLayout->addRow(additiveRadioButton); + formLayout->addRow(substractiveRadioButton); + + QHBoxLayout *mainLayout = new QHBoxLayout; + mainLayout->addLayout(formLayout); + mainLayout->addWidget(buttonBox); + mainLayout->addWidget(deleteButton); + + setLayout(mainLayout); +} + +ProfileDialog::~ProfileDialog() +{ +} + +QString ProfileDialog::getName() const +{ + return nameInput->text(); +} + +bool ProfileDialog::isAdditive() const +{ + return additiveRadioButton->isChecked(); +} + +void ProfileDialog::deleteProfile() +{ + // Handle the profile deletion + emit deleteProfileSignal(); + reject(); // Close the dialog after deletion +} + + + +ArvizProfileManagerWidget::ArvizProfileManagerWidget(QWidget* parent) : + QWidget(parent), + settings(QString((armarx::ArmarXDataPath::GetDefaultUserConfigPath() + "/ArvizProfileManager.conf").c_str()), + QSettings::NativeFormat), + currentProfile(Profile()) +{ + QHBoxLayout* layout = new QHBoxLayout(this); + + // Setup UI elements + layersComboBox = new QComboBox(this); + connect(layersComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), + this, &ArvizProfileManagerWidget::onLayersSelected); + + addButton = new QPushButton("Add", this); + editButton = new QPushButton("Edit", this); + saveButton = new QPushButton("Save", this); + + layout->addWidget(new QLabel("Arviz Profile: ")); + layout->addWidget(layersComboBox); + layout->addWidget(addButton); + layout->addWidget(editButton); + layout->addWidget(saveButton); + + setLayout(layout); + + connect(addButton, &QPushButton::clicked, this, &ArvizProfileManagerWidget::addProfile); + connect(editButton, &QPushButton::clicked, this, &ArvizProfileManagerWidget::editProfile); + connect(saveButton, &QPushButton::clicked, this, &ArvizProfileManagerWidget::saveCurrentLayers); + + loadLayerNames(); +} + +void ArvizProfileManagerWidget::onLayersSelected(int index) +{ + const QString name = layersComboBox->currentText(); + + loadProfile(name); + emit layersReset(); +} + +void ArvizProfileManagerWidget::saveCurrentLayers() +{ + const QString name = layersComboBox->currentText(); + if (name.isEmpty()) + { + QMessageBox::warning(this, "Warning", "Please enter a valid name."); + return; + } + + if (saveProfile(name, currentProfile)) + { + if (layersComboBox->findText(name) == -1) + { + layersComboBox->addItem(name); + } + layersComboBox->setCurrentText(name); + } +} + +void ArvizProfileManagerWidget::deleteCurrentLayersSave() +{ + const QString name = layersComboBox->currentText(); + settings.remove(name); + + const int index = layersComboBox->currentIndex(); + layersComboBox->removeItem(index); + settings.remove(name); + + if (layersComboBox->count() == 0) + { + editButton->setDisabled(true); + saveButton->setDisabled(true); + } + + emit layersReset(); +} + +void ArvizProfileManagerWidget::addProfile() +{ + if (dialog == nullptr || !dialog->isVisible()) + { + const QString defaultName = "Profile"; + const bool defaultAdditive = false; + QString name = defaultName; + unsigned int counter = 2; + while (layersComboBox->count() > 0 and layersComboBox->findText(name) >= 0) + { + name = defaultName + QString::fromStdString(std::to_string(counter++)); + } + dialog = new ProfileDialog(this, name, defaultAdditive, true); + const int result = dialog->exec(); + + if (result == QDialog::Accepted) + { + if (layersComboBox->findText(dialog->getName()) >= 0) + { + ARMARX_WARNING << "Profile with name " << dialog->getName().toStdString() << " already exists!"; + return; + } + currentProfile.layers = {}; + currentProfile.additive = dialog->isAdditive(); + saveProfile(dialog->getName(), currentProfile); + loadLayerNames(); + + layersComboBox->setCurrentText(dialog->getName()); + onLayersSelected(0); + } + else + { + // do nothing + } + } + else + { + QMessageBox::information(this, "Dialog Already Open", "The dialog is already open."); + } +} + +void ArvizProfileManagerWidget::editProfile() +{ + if (layersComboBox->count() > 0) + { + if (dialog == nullptr || !dialog->isVisible()) + { + dialog = new ProfileDialog(this, layersComboBox->currentText(), currentProfile.additive, false); + connect(dialog, &ProfileDialog::deleteProfileSignal, this, &ArvizProfileManagerWidget::deleteCurrentLayersSave); + const int result = dialog->exec(); + + if (result == QDialog::Accepted) + { + currentProfile.additive = dialog->isAdditive(); + settings.remove(layersComboBox->currentText()); + saveProfile(dialog->getName(), currentProfile); + loadLayerNames(); + layersComboBox->setCurrentText(dialog->getName()); + emit layersReset(); + } + else + { + // do nothing + } + } + else + { + QMessageBox::information(this, "Dialog Already Open", "The dialog is already open."); + } + } +} + +void ArvizProfileManagerWidget::loadLayerNames() +{ + layersComboBox->clear(); + for (const QString& groups : settings.childGroups()) + { + layersComboBox->addItem(groups); + } + if (layersComboBox->count() == 0) + { + editButton->setDisabled(true); + saveButton->setDisabled(true); + } + else + { + editButton->setEnabled(true); + saveButton->setEnabled(true); + } +} + +void ArvizProfileManagerWidget::loadProfile(const QString& name) +{ + std::scoped_lock lock(mtx); + currentProfile.layers.clear(); + + settings.beginGroup(name); + currentProfile.additive = settings.value("additive").toBool(); + const int size = settings.beginReadArray("layers"); + for (int i = 0; i < size; ++i) + { + settings.setArrayIndex(i); + QString first = settings.value("component").toString(); + QString second = settings.value("layer").toString(); + currentProfile.layers.insert({first.toStdString(), second.toStdString()}); + } + settings.endArray(); + settings.endGroup(); + editButton->setEnabled(true); +} + +bool ArvizProfileManagerWidget::saveProfile(const QString& name, const Profile& profile) +{ + settings.beginGroup(name); + settings.setValue("additive", profile.additive); + settings.remove("layers"); + settings.beginWriteArray("layers", profile.layers.size()); + int i = 0; + for (const auto& pair : profile.layers) + { + settings.setArrayIndex(i++); + settings.setValue("component", QString::fromStdString(pair.first)); + settings.setValue("layer", QString::fromStdString(pair.second)); + } + settings.endArray(); + settings.endGroup(); + return true; +} + +} \ No newline at end of file diff --git a/source/RobotAPI/gui-plugins/ArViz/ArvizProfileManagerWidget.h b/source/RobotAPI/gui-plugins/ArViz/ArvizProfileManagerWidget.h new file mode 100644 index 000000000..b7924a97a --- /dev/null +++ b/source/RobotAPI/gui-plugins/ArViz/ArvizProfileManagerWidget.h @@ -0,0 +1,138 @@ +#pragma once + +#include <QWidget> +#include <QDialog> +#include <QComboBox> +#include <QPushButton> +#include <QLineEdit> +#include <QSettings> +#include <QString> +#include <QCheckBox> +#include <qradiobutton.h> + +#include <mutex> +#include <unordered_set> +#include <string> +#include <utility> + +#include <RobotAPI/components/ArViz/Coin/Visualizer.h> + +namespace armarx +{ + struct pair_hash + { + template <typename T1, typename T2> + std::size_t operator ()(const std::pair<T1, T2>& p) const + { + auto h1 = std::hash<T1>{}(p.first); + auto h2 = std::hash<T2>{}(p.second); + return h1 ^ (h2 << 1); + } + }; + + using Layers = std::unordered_set<viz::CoinLayerID, pair_hash>; + + struct Profile + { + Layers layers; + bool additive = false; + }; + + + class ProfileDialog : public QDialog + { + Q_OBJECT + + public: + explicit ProfileDialog(QWidget *parent = nullptr, const QString &name = "", bool additive = false, bool addDialog = true); + ~ProfileDialog(); + + QString getName() const; + bool isAdditive() const; + + signals: + void deleteProfileSignal(); + + private slots: + void deleteProfile(); + + private: + QLineEdit *nameInput; + QRadioButton *additiveRadioButton; + QRadioButton *substractiveRadioButton; + QPushButton *deleteButton; + }; + + + class ArvizProfileManagerWidget : public QWidget + { + Q_OBJECT + + public: + explicit ArvizProfileManagerWidget(QWidget* parent = nullptr); + + inline void update(const viz::CoinLayerID& layerID, bool visible) + { + std::scoped_lock lock(mtx); + + if (visible and currentProfile.layers.count(layerID) > 0) + { + currentProfile.layers.erase(layerID); + currentProfile.layers.erase({layerID.first, "*"}); + } + else if (not visible) + { + currentProfile.layers.insert(layerID); + } + } + + inline void update(const std::string& componentName, bool visible) + { + update({componentName, "*"}, visible); + } + + inline bool isHidden(const viz::CoinLayerID& layerID) const + { + std::scoped_lock lock(mtx); + + const bool result = currentProfile.layers.count(layerID) > 0 or currentProfile.layers.count({layerID.first, "*"}) > 0; + + if (currentProfile.additive) + { + return not result; + } + else + { + return result; + } + } + + signals: + // Signal emitted when the saveLayer is reset (reselected) + void layersReset(); + + private slots: + void onLayersSelected(int index); + void saveCurrentLayers(); + void deleteCurrentLayersSave(); + + void addProfile(); + void editProfile(); + + private: + void loadLayerNames(); + void loadProfile(const QString& name); + bool saveProfile(const QString& name, const Profile& profile); + + ProfileDialog* dialog = nullptr; + QComboBox* layersComboBox; + QPushButton* addButton; + QPushButton* editButton; + QPushButton* saveButton; + QSettings settings; + mutable std::mutex mtx; + + Profile currentProfile; + }; + +} \ No newline at end of file diff --git a/source/RobotAPI/gui-plugins/ArViz/CMakeLists.txt b/source/RobotAPI/gui-plugins/ArViz/CMakeLists.txt index 318b4d9bd..94928007f 100644 --- a/source/RobotAPI/gui-plugins/ArViz/CMakeLists.txt +++ b/source/RobotAPI/gui-plugins/ArViz/CMakeLists.txt @@ -10,7 +10,7 @@ armarx_build_if(ArmarXGui_FOUND "ArmarXGui not available") set(SOURCES ArVizGuiPlugin.cpp ArVizWidgetController.cpp - HiddenCoinLayerManagerWidget.cpp + ArvizProfileManagerWidget.cpp LayerInfoTree.cpp ) @@ -19,7 +19,7 @@ set(SOURCES set(HEADERS ArVizGuiPlugin.h ArVizWidgetController.h - HiddenCoinLayerManagerWidget.h + ArvizProfileManagerWidget.h LayerInfoTree.h ) diff --git a/source/RobotAPI/gui-plugins/ArViz/HiddenCoinLayerManagerWidget.cpp b/source/RobotAPI/gui-plugins/ArViz/HiddenCoinLayerManagerWidget.cpp deleted file mode 100644 index 95ca8de3d..000000000 --- a/source/RobotAPI/gui-plugins/ArViz/HiddenCoinLayerManagerWidget.cpp +++ /dev/null @@ -1,153 +0,0 @@ -#include "HiddenCoinLayerManagerWidget.h" - -#include <ArmarXCore/core/logging/Logging.h> -#include <QVBoxLayout> -#include <QMessageBox> - -#include <ArmarXCore/core/system/ArmarXDataPath.h> -#include <qboxlayout.h> -#include <qlabel.h> - -namespace armarx -{ - -HiddenCoinLayerManagerWidget::HiddenCoinLayerManagerWidget(QWidget* parent) : - QWidget(parent), - settings(QString((armarx::ArmarXDataPath::GetDefaultUserConfigPath() + "/ArvizHiddenCoinLayerManager.conf").c_str()), - QSettings::NativeFormat), - hiddenLayers(HiddenLayers{}) -{ - QHBoxLayout* layout = new QHBoxLayout(this); - - // Setup UI elements - hiddenLayersComboBox = new QComboBox(this); - hiddenLayersComboBox->addItem("default"); - connect(hiddenLayersComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), - this, &HiddenCoinLayerManagerWidget::onHiddenLayersSelected); - - nameEdit = new QLineEdit(this); - saveButton = new QPushButton("Save", this); - deleteButton = new QPushButton("Delete", this); - - layout->addWidget(new QLabel("Arviz Layer Saves: ")); - layout->addWidget(hiddenLayersComboBox); - layout->addWidget(nameEdit); - layout->addWidget(saveButton); - layout->addWidget(deleteButton); - setLayout(layout); - - connect(saveButton, &QPushButton::clicked, this, &HiddenCoinLayerManagerWidget::saveCurrentHiddenLayers); - connect(deleteButton, &QPushButton::clicked, this, &HiddenCoinLayerManagerWidget::deleteCurrentHiddenLayersSave); - - loadHiddenLayerNames(); - loadDefaultHiddenLayer(); -} - -void HiddenCoinLayerManagerWidget::onHiddenLayersSelected(int index) -{ - const QString name = hiddenLayersComboBox->currentText(); - - loadHiddenLayers(name); - emit hiddenLayersReset(); -} - -void HiddenCoinLayerManagerWidget::saveCurrentHiddenLayers() -{ - const QString name = nameEdit->text(); - if (name.isEmpty() or name == "default") - { - QMessageBox::warning(this, "Warning", "Please enter a valid name."); - return; - } - - if (saveHiddenLayers(name, hiddenLayers)) - { - if (hiddenLayersComboBox->findText(name) == -1) - { - hiddenLayersComboBox->addItem(name); - } - hiddenLayersComboBox->setCurrentText(name); - } -} - -void HiddenCoinLayerManagerWidget::deleteCurrentHiddenLayersSave() -{ - const QString name = hiddenLayersComboBox->currentText(); - if (name == "default") - { - QMessageBox::warning(this, "Warning", "Cannot delete the default."); - return; - } - - settings.remove(name); - - int index = hiddenLayersComboBox->currentIndex(); - hiddenLayersComboBox->removeItem(index); - loadDefaultHiddenLayer(); - emit hiddenLayersReset(); -} - -void HiddenCoinLayerManagerWidget::loadHiddenLayerNames() -{ - for (const QString& groups : settings.childGroups()) - { - hiddenLayersComboBox->addItem(groups); - } -} - -void HiddenCoinLayerManagerWidget::loadDefaultHiddenLayer() -{ - hiddenLayersComboBox->setCurrentText("default"); - hiddenLayers.clear(); -} - -void HiddenCoinLayerManagerWidget::loadHiddenLayers(const QString& name) -{ - std::scoped_lock lock(mtx); - hiddenLayers.clear(); - - if (name != "default") - { - settings.beginGroup(name); - const int size = settings.beginReadArray("layers"); - for (int i = 0; i < size; ++i) - { - settings.setArrayIndex(i); - QString first = settings.value("component").toString(); - QString second = settings.value("layer").toString(); - hiddenLayers.insert({first.toStdString(), second.toStdString()}); - } - settings.endArray(); - settings.endGroup(); - - nameEdit->setText(name); - deleteButton->setEnabled(true); - } - else - { - deleteButton->setEnabled(false); - } -} - -bool HiddenCoinLayerManagerWidget::saveHiddenLayers(const QString& name, const HiddenLayers& hiddenLayers) -{ - if (name != "default") - { - settings.beginGroup(name); - settings.remove("layers"); - settings.beginWriteArray("layers", hiddenLayers.size()); - int i = 0; - for (const auto& pair : hiddenLayers) - { - settings.setArrayIndex(i++); - settings.setValue("component", QString::fromStdString(pair.first)); - settings.setValue("layer", QString::fromStdString(pair.second)); - } - settings.endArray(); - settings.endGroup(); - return true; - } - return false; -} - -} \ No newline at end of file diff --git a/source/RobotAPI/gui-plugins/ArViz/HiddenCoinLayerManagerWidget.h b/source/RobotAPI/gui-plugins/ArViz/HiddenCoinLayerManagerWidget.h deleted file mode 100644 index f10140d09..000000000 --- a/source/RobotAPI/gui-plugins/ArViz/HiddenCoinLayerManagerWidget.h +++ /dev/null @@ -1,92 +0,0 @@ -#pragma once - -#include <QWidget> -#include <QComboBox> -#include <QPushButton> -#include <QLineEdit> -#include <QSettings> -#include <QString> - -#include <mutex> -#include <qobjectdefs.h> -#include <shared_mutex> -#include <unordered_set> -#include <string> -#include <utility> - -#include <RobotAPI/components/ArViz/Coin/Visualizer.h> - -namespace armarx -{ - struct pair_hash - { - template <typename T1, typename T2> - std::size_t operator ()(const std::pair<T1, T2>& p) const - { - auto h1 = std::hash<T1>{}(p.first); - auto h2 = std::hash<T2>{}(p.second); - return h1 ^ (h2 << 1); - } - }; - - using HiddenLayers = std::unordered_set<viz::CoinLayerID, pair_hash>; - - class HiddenCoinLayerManagerWidget : public QWidget - { - Q_OBJECT - - public: - explicit HiddenCoinLayerManagerWidget(QWidget* parent = nullptr); - - inline void update(const viz::CoinLayerID& layerID, bool visible) - { - std::scoped_lock lock(mtx); - - if (visible and hiddenLayers.count(layerID) > 0) - { - hiddenLayers.erase(layerID); - hiddenLayers.erase({layerID.first, "*"}); - } - else if (not visible) - { - hiddenLayers.insert(layerID); - } - } - - inline void update(const std::string& componentName, bool visible) - { - update({componentName, "*"}, visible); - } - - inline bool isHidden(const viz::CoinLayerID& layerID) const - { - std::scoped_lock lock(mtx); - - return hiddenLayers.count(layerID) > 0 or hiddenLayers.count({layerID.first, "*"}) > 0; - } - - signals: - // Signal emitted when the saveHiddenLayer is reset (reselected) - void hiddenLayersReset(); - - private slots: - void onHiddenLayersSelected(int index); - void saveCurrentHiddenLayers(); - void deleteCurrentHiddenLayersSave(); - - private: - void loadHiddenLayerNames(); - void loadDefaultHiddenLayer(); - void loadHiddenLayers(const QString& name); - bool saveHiddenLayers(const QString& name, const HiddenLayers& hiddenLayers); - - QComboBox* hiddenLayersComboBox; - QLineEdit* nameEdit; - QPushButton* saveButton; - QPushButton* deleteButton; - QSettings settings; - mutable std::mutex mtx; - HiddenLayers hiddenLayers; - }; - -} \ No newline at end of file -- GitLab