From 29ec536dd944d02f2e87819b6d6424ab5ffbbe20 Mon Sep 17 00:00:00 2001 From: Fabian Peller <fabian.peller-konrad@kit.edu> Date: Wed, 25 Oct 2023 17:06:29 +0200 Subject: [PATCH] allow optionals in skill manager gui --- .../SkillProviderExample/HelloWorld.cpp | 1 + .../aron/HelloWorldAcceptedType.xml | 3 + .../visitors/AronTreeWidgetConverter.cpp | 164 ++++++++++++++++-- .../visitors/AronTreeWidgetCreator.cpp | 25 +++ .../visitors/AronTreeWidgetSetter.cpp | 81 ++++++--- 5 files changed, 244 insertions(+), 30 deletions(-) diff --git a/source/RobotAPI/components/skills/SkillProviderExample/HelloWorld.cpp b/source/RobotAPI/components/skills/SkillProviderExample/HelloWorld.cpp index d57f66c3a..edf918402 100644 --- a/source/RobotAPI/components/skills/SkillProviderExample/HelloWorld.cpp +++ b/source/RobotAPI/components/skills/SkillProviderExample/HelloWorld.cpp @@ -20,6 +20,7 @@ namespace armarx::skills::provider root_profile_params.some_float = 5; root_profile_params.some_int = 42; root_profile_params.some_text = "YOLO"; + root_profile_params.some_optional_text = "OPTIONAL"; root_profile_params.some_list_of_matrices.push_back(Eigen::Matrix3f::Zero()); root_profile_params.some_matrix = Eigen::Matrix3f::Zero(); diff --git a/source/RobotAPI/components/skills/SkillProviderExample/aron/HelloWorldAcceptedType.xml b/source/RobotAPI/components/skills/SkillProviderExample/aron/HelloWorldAcceptedType.xml index e90781ca6..10c81ab54 100644 --- a/source/RobotAPI/components/skills/SkillProviderExample/aron/HelloWorldAcceptedType.xml +++ b/source/RobotAPI/components/skills/SkillProviderExample/aron/HelloWorldAcceptedType.xml @@ -22,6 +22,9 @@ <ObjectChild key='some_text'> <String /> </ObjectChild> + <ObjectChild key='some_optional_text'> + <String optional="True" /> + </ObjectChild> <ObjectChild key='some_list_of_matrices'> <List> diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetConverter.cpp b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetConverter.cpp index 2e52ed4cf..5c3db21fb 100644 --- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetConverter.cpp +++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetConverter.cpp @@ -90,6 +90,16 @@ namespace armarx createdAron = createdAronDict; QTreeWidgetItem* el = parentItem->child(index); + if (i->getMaybe() != armarx::aron::type::Maybe::NONE) + { + // its a maybetype. We have to check the state + if (el->checkState(1) == Qt::CheckState::Unchecked) + { + createdAron = nullptr; + return; + } + } + unsigned int x = 0; for (const auto& [key, value] : i->getMemberTypes()) { @@ -113,6 +123,16 @@ namespace armarx createdAron = createdAronDict; QTreeWidgetItem* el = parentItem->child(index); + if (i->getMaybe() != armarx::aron::type::Maybe::NONE) + { + // its a maybetype. We have to check the state + if (el->checkState(1) == Qt::CheckState::Unchecked) + { + createdAron = nullptr; + return; + } + } + for (int x = 0; x < el->childCount(); ++x) { auto it = el->child(x); @@ -134,12 +154,23 @@ namespace armarx ARMARX_TRACE; auto createdAronList = std::make_shared<aron::data::List>(i->getPath()); createdAron = createdAronList; - auto* elem = parentItem->child(index); + auto* el = parentItem->child(index); + + if (i->getMaybe() != armarx::aron::type::Maybe::NONE) + { + // its a maybetype. We have to check the state + if (el->checkState(1) == Qt::CheckState::Unchecked) + { + createdAron = nullptr; + return; + } + } + auto childrenTypes = i->getChildren(); ARMARX_CHECK(childrenTypes.size() == 1); - for (int j = 0; j < elem->childCount(); ++j) + for (int j = 0; j < el->childCount(); ++j) { - AronTreeWidgetConverterVisitor convVisitor(elem, j); + AronTreeWidgetConverterVisitor convVisitor(el, j); aron::type::visit(convVisitor, childrenTypes[0]); handleErrors(convVisitor); @@ -156,11 +187,21 @@ namespace armarx ARMARX_TRACE; auto createdAronPair = std::make_shared<aron::data::List>(i->getPath()); createdAron = createdAronPair; - auto* elem = parentItem->child(index); + auto* el = parentItem->child(index); + + if (i->getMaybe() != armarx::aron::type::Maybe::NONE) + { + // its a maybetype. We have to check the state + if (el->checkState(1) == Qt::CheckState::Unchecked) + { + createdAron = nullptr; + return; + } + } for (int j = 0; j < 2; ++j) { - AronTreeWidgetConverterVisitor convVisitor(elem, j); + AronTreeWidgetConverterVisitor convVisitor(el, j); handleErrors(convVisitor); if (convVisitor.createdAron && convVisitor.isConversionSuccessful()) { @@ -177,6 +218,16 @@ namespace armarx createdAron = createdAronList; QTreeWidgetItem* el = parentItem->child(index); + if (i->getMaybe() != armarx::aron::type::Maybe::NONE) + { + // its a maybetype. We have to check the state + if (el->checkState(1) == Qt::CheckState::Unchecked) + { + createdAron = nullptr; + return; + } + } + for (int x = 0; x < el->childCount(); ++x) { auto* it = el->child(x); @@ -242,11 +293,22 @@ namespace armarx createdMatrix->setShape({i->getRows(), i->getCols(), dataSize}); int totalByteSize = i->getRows() * i->getCols() * dataSize; createdAron = createdMatrix; + auto* el = parentItem->child(index); + + if (i->getMaybe() != armarx::aron::type::Maybe::NONE) + { + // its a maybetype. We have to check the state + if (el->checkState(1) == Qt::CheckState::Unchecked) + { + createdAron = nullptr; + return; + } + } - auto* currElem = parentItem->child(index); - auto* rootWidget = currElem->treeWidget(); + + auto* rootWidget = el->treeWidget(); ARMARX_CHECK(rootWidget); - auto* widget = rootWidget->itemWidget(currElem, 1); + auto* widget = rootWidget->itemWidget(el, 1); auto* matrixWidget = EditMatrixWidget::DynamicCastAndCheck(widget); handleErrors(matrixWidget->hasParseErrors()); @@ -280,8 +342,19 @@ namespace armarx int dataSize = i->getElementType() == aron::type::quaternion::ElementType::FLOAT32 ? 4 : 8; createdQuat->setShape({1, 4, dataSize}); createdQuat->setType(i->getFullName()); - auto* currTreeElem = parentItem->child(index); - auto* itemWidget = currTreeElem->treeWidget()->itemWidget(currTreeElem, 1); + auto* el = parentItem->child(index); + + if (i->getMaybe() != armarx::aron::type::Maybe::NONE) + { + // its a maybetype. We have to check the state + if (el->checkState(1) == Qt::CheckState::Unchecked) + { + createdAron = nullptr; + return; + } + } + + auto* itemWidget = el->treeWidget()->itemWidget(el, 1); auto* quatWidget = QuaternionWidget::DynamicCastAndCheck(itemWidget); // error handling @@ -320,6 +393,17 @@ namespace armarx { ARMARX_TRACE; QTreeWidgetItem* el = parentItem->child(index); + + if (i->getMaybe() != armarx::aron::type::Maybe::NONE) + { + // its a maybetype. We have to check the state + if (el->checkState(1) == Qt::CheckState::Unchecked) + { + createdAron = nullptr; + return; + } + } + auto* genericWidget = el->treeWidget()->itemWidget(el, 1); auto* intEnumWidget = IntEnumWidget::DynamicCastAndCheck(genericWidget); if (!intEnumWidget) @@ -341,6 +425,16 @@ namespace armarx createdAron = createdAronInt; QTreeWidgetItem* el = parentItem->child(index); + if (i->getMaybe() != armarx::aron::type::Maybe::NONE) + { + // its a maybetype. We have to check the state + if (el->checkState(1) == Qt::CheckState::Unchecked) + { + createdAron = nullptr; + return; + } + } + std::string str = el->text(1).toStdString(); if (str.empty()) { @@ -370,6 +464,16 @@ namespace armarx createdAron = createdAronLong; QTreeWidgetItem* el = parentItem->child(index); + if (i->getMaybe() != armarx::aron::type::Maybe::NONE) + { + // its a maybetype. We have to check the state + if (el->checkState(1) == Qt::CheckState::Unchecked) + { + createdAron = nullptr; + return; + } + } + std::string str = el->text(1).toStdString(); if (str.empty()) { @@ -398,6 +502,16 @@ namespace armarx createdAron = createdAronFloat; QTreeWidgetItem* el = parentItem->child(index); + if (i->getMaybe() != armarx::aron::type::Maybe::NONE) + { + // its a maybetype. We have to check the state + if (el->checkState(1) == Qt::CheckState::Unchecked) + { + createdAron = nullptr; + return; + } + } + std::string str = el->text(1).toStdString(); if (str.empty()) { @@ -425,6 +539,16 @@ namespace armarx createdAron = createdAronDouble; QTreeWidgetItem* el = parentItem->child(index); + if (i->getMaybe() != armarx::aron::type::Maybe::NONE) + { + // its a maybetype. We have to check the state + if (el->checkState(1) == Qt::CheckState::Unchecked) + { + createdAron = nullptr; + return; + } + } + std::string str = el->text(1).toStdString(); if (str.empty()) { @@ -452,6 +576,16 @@ namespace armarx createdAron = createdAronBool; QTreeWidgetItem* el = parentItem->child(index); + if (i->getMaybe() != armarx::aron::type::Maybe::NONE) + { + // its a maybetype. We have to check the state + if (el->checkState(1) == Qt::CheckState::Unchecked) + { + createdAron = nullptr; + return; + } + } + std::string str = el->text(1).toStdString(); if (str.empty()) { @@ -479,6 +613,16 @@ namespace armarx createdAron = createdAronString; QTreeWidgetItem* el = parentItem->child(index); + if (i->getMaybe() != armarx::aron::type::Maybe::NONE) + { + // its a maybetype. We have to check the state + if (el->checkState(1) == Qt::CheckState::Unchecked) + { + createdAron = nullptr; + return; + } + } + std::string str = el->text(1).toStdString(); createdAronString->setValue(str); } diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetCreator.cpp b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetCreator.cpp index 84cb58585..5bc5a40bb 100644 --- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetCreator.cpp +++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetCreator.cpp @@ -101,6 +101,11 @@ namespace armarx createdQWidgetItem = new AronTreeWidgetItem(isDictChild, editableValue, QString::fromStdString(key), i); + + if (i->getMaybe() != armarx::aron::type::Maybe::NONE) + { + createdQWidgetItem->setCheckState(1, Qt::CheckState::Unchecked); + } createdQWidgetItem->setText(1, QString::fromStdString(defaul)); createdQWidgetItem->setText(2, QString::fromStdString(i->getShortName())); createdQWidgetItem->setText( @@ -129,6 +134,12 @@ namespace armarx createdQWidgetItem = new AronTreeWidgetItem(editableValue, false, QString::fromStdString(key), i); + + if (i->getMaybe() != armarx::aron::type::Maybe::NONE) + { + createdQWidgetItem->setCheckState(1, Qt::CheckState::Unchecked); + } + parentOfCreatedObj->addChild(createdQWidgetItem); for (const auto& [key, value] : i->getMemberTypes()) @@ -149,6 +160,7 @@ namespace armarx // The DictType has only one member, its key-type. This also must be present ARMARX_CHECK_EQUAL(i->getChildren().size(), 1); } + void AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::PairPtr& pair) { @@ -167,6 +179,7 @@ namespace armarx } } } + void AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::TuplePtr& tuple) { @@ -185,6 +198,7 @@ namespace armarx } } } + void AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::ListPtr& i) { @@ -192,6 +206,7 @@ namespace armarx auto txt = misc::generateNumElementsText(0); createdQWidgetItem->setText(1, txt); } + void AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::NDArrayPtr& i) { @@ -233,6 +248,7 @@ namespace armarx i->getRows(), i->getCols(), i->getElementType(), createdQWidgetItem); toplevelWidget->setItemWidget(createdQWidgetItem, 1, matWidget); } + void AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::QuaternionPtr& i) { @@ -257,16 +273,19 @@ namespace armarx new QuaternionWidget(i->getElementType(), createdQWidgetItem); toplevelWidget->setItemWidget(createdQWidgetItem, 1, quatWidget); } + void AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::ImagePtr& i) { insertNewTreeViewWidget(i, ""); } + void AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::PointCloudPtr& i) { insertNewTreeViewWidget(i, ""); } + void AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::IntEnumPtr& i) { @@ -278,36 +297,42 @@ namespace armarx IntEnumWidget* widget = new IntEnumWidget(i, createdQWidgetItem); createdQWidgetItem->treeWidget()->setItemWidget(createdQWidgetItem, 1, widget); } + void AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::IntPtr& i) { editableValue = true; insertNewTreeViewWidget(i, "0"); } + void AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::LongPtr& i) { editableValue = true; insertNewTreeViewWidget(i, "0"); } + void AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::FloatPtr& i) { editableValue = true; insertNewTreeViewWidget(i, "0.0"); } + void AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::DoublePtr& i) { editableValue = true; insertNewTreeViewWidget(i, "0.0"); } + void AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::BoolPtr& i) { editableValue = true; insertNewTreeViewWidget(i, "false"); } + void AronTreeWidgetCreatorVisitor::visitAronVariant(const aron::type::StringPtr& i) { diff --git a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetSetter.cpp b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetSetter.cpp index cf719f8a2..cafc9b499 100644 --- a/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetSetter.cpp +++ b/source/RobotAPI/gui-plugins/SkillManagerPlugin/aronTreeWidget/visitors/AronTreeWidgetSetter.cpp @@ -31,7 +31,6 @@ #include "AronTreeWidgetContextMenu.h" #include "AronTreeWidgetCreator.h" - template <typename T> std::string usString(T number, size_t precision = 3) @@ -44,7 +43,6 @@ usString(T number, size_t precision = 3) return ss.str(); } - //visitors namespace armarx { @@ -101,7 +99,6 @@ namespace armarx } } - void AronTreeWidgetSetterVisitor::visitAronVariant(const aron::data::DictPtr& i) { @@ -109,7 +106,7 @@ namespace armarx if (i->getPath().size() == 0 || checkTreeWidgetItemForSimilarName(i->getPath().getLastElement())) { - QTreeWidgetItem* el = parentItem->child(index); + AronTreeWidgetItem* el = AronTreeWidgetItem::DynamicCast(parentItem->child(index)); auto* aronTreeWidget = AronTreeWidgetItem::DynamicCastAndCheck(el); // allocate enough child items adjustNumberOfChildren(aronTreeWidget, i->childrenSize()); @@ -123,7 +120,11 @@ namespace armarx AronTreeWidgetSetterVisitor v(el, x++); aron::data::visit(v, value); } - return; + + if (el->aronType && el->aronType->getMaybe() != armarx::aron::type::Maybe::NONE) + { + el->setCheckState(1, Qt::CheckState::Checked); + } } } @@ -132,7 +133,7 @@ namespace armarx { if (checkTreeWidgetItemForSimilarName(i->getPath().getLastElement())) { - QTreeWidgetItem* el = parentItem->child(index); + AronTreeWidgetItem* el = AronTreeWidgetItem::DynamicCast(parentItem->child(index)); auto* aronTreeWidget = AronTreeWidgetItem::DynamicCastAndCheck(el); adjustNumberOfChildren(aronTreeWidget, i->childrenSize()); @@ -154,10 +155,14 @@ namespace armarx auto currFont = aronTreeWidget->font(1); currFont.setItalic(true); aronTreeWidget->setFont(1, currFont); + + if (el->aronType && el->aronType->getMaybe() != armarx::aron::type::Maybe::NONE) + { + el->setCheckState(1, Qt::CheckState::Checked); + } } } - void visitMatrix(EditMatrixWidget* matrixWidget, const std::shared_ptr<armarx::aron::type::Matrix>& matrixType, @@ -215,6 +220,7 @@ namespace armarx } } } + void visitQuaternion(QuaternionWidget* quatWidget, std::shared_ptr<armarx::aron::type::Quaternion>& quatType, @@ -256,16 +262,16 @@ namespace armarx AronTreeWidgetSetterVisitor::visitAronVariant(const aron::data::NDArrayPtr& arr) { // Matrices are handled as NDArray. Raw ndarrays cannot be created currently - auto* castedEl = AronTreeWidgetItem::DynamicCast(parentItem->child(index)); - ARMARX_CHECK(castedEl); + auto* el = AronTreeWidgetItem::DynamicCast(parentItem->child(index)); + ARMARX_CHECK(el); - auto matrixCast = aron::type::Matrix::DynamicCast(castedEl->aronType); - auto quaternionCast = aron::type::Quaternion::DynamicCast(castedEl->aronType); + auto matrixCast = aron::type::Matrix::DynamicCast(el->aronType); + auto quaternionCast = aron::type::Quaternion::DynamicCast(el->aronType); - auto* rootWidget = castedEl->treeWidget(); + auto* rootWidget = el->treeWidget(); ARMARX_CHECK(rootWidget); - auto* matrixWidget = EditMatrixWidget::DynamicCast(rootWidget->itemWidget(castedEl, 1)); - auto* quaternionWidget = QuaternionWidget::DynamicCast(rootWidget->itemWidget(castedEl, 1)); + auto* matrixWidget = EditMatrixWidget::DynamicCast(rootWidget->itemWidget(el, 1)); + auto* quaternionWidget = QuaternionWidget::DynamicCast(rootWidget->itemWidget(el, 1)); if (matrixCast && matrixWidget) { @@ -280,6 +286,11 @@ namespace armarx ARMARX_ERROR << "we do not support raw NDArrays. Ask Fabian Peller for more information."; } + + if (el->aronType && el->aronType->getMaybe() != armarx::aron::type::Maybe::NONE) + { + el->setCheckState(1, Qt::CheckState::Checked); + } } void @@ -287,7 +298,7 @@ namespace armarx { if (checkTreeWidgetItemForSimilarName(i->getPath().getLastElement())) { - QTreeWidgetItem* el = parentItem->child(index); + AronTreeWidgetItem* el = AronTreeWidgetItem::DynamicCast(parentItem->child(index)); auto* enumWidget = IntEnumWidget::DynamicCast(el->treeWidget()->itemWidget(el, 1)); auto newText = QString::fromStdString(usString<int>(i->getValue())); if (enumWidget) @@ -300,6 +311,11 @@ namespace armarx // Its just an int. -> do the QTreeWidgetItem call el->setText(1, newText); } + + if (el->aronType && el->aronType->getMaybe() != armarx::aron::type::Maybe::NONE) + { + el->setCheckState(1, Qt::CheckState::Checked); + } } } @@ -308,8 +324,13 @@ namespace armarx { if (checkTreeWidgetItemForSimilarName(i->getPath().getLastElement())) { - QTreeWidgetItem* el = parentItem->child(index); + AronTreeWidgetItem* el = AronTreeWidgetItem::DynamicCast(parentItem->child(index)); el->setText(1, QString::fromStdString(usString<long>(i->getValue()))); + + if (el->aronType && el->aronType->getMaybe() != armarx::aron::type::Maybe::NONE) + { + el->setCheckState(1, Qt::CheckState::Checked); + } } } @@ -318,8 +339,13 @@ namespace armarx { if (checkTreeWidgetItemForSimilarName(i->getPath().getLastElement())) { - QTreeWidgetItem* el = parentItem->child(index); + AronTreeWidgetItem* el = AronTreeWidgetItem::DynamicCast(parentItem->child(index)); el->setText(1, QString::fromStdString(usString<float>(i->getValue()))); + + if (el->aronType && el->aronType->getMaybe() != armarx::aron::type::Maybe::NONE) + { + el->setCheckState(1, Qt::CheckState::Checked); + } } } @@ -328,8 +354,13 @@ namespace armarx { if (checkTreeWidgetItemForSimilarName(i->getPath().getLastElement())) { - QTreeWidgetItem* el = parentItem->child(index); + AronTreeWidgetItem* el = AronTreeWidgetItem::DynamicCast(parentItem->child(index)); el->setText(1, QString::fromStdString(usString<double>(i->getValue()))); + + if (el->aronType && el->aronType->getMaybe() != armarx::aron::type::Maybe::NONE) + { + el->setCheckState(1, Qt::CheckState::Checked); + } } } @@ -338,8 +369,13 @@ namespace armarx { if (checkTreeWidgetItemForSimilarName(i->getPath().getLastElement())) { - QTreeWidgetItem* el = parentItem->child(index); + AronTreeWidgetItem* el = AronTreeWidgetItem::DynamicCast(parentItem->child(index)); el->setText(1, QString::fromStdString(usString<bool>(i->getValue()))); + + if (el->aronType && el->aronType->getMaybe() != armarx::aron::type::Maybe::NONE) + { + el->setCheckState(1, Qt::CheckState::Checked); + } } } @@ -348,8 +384,13 @@ namespace armarx { if (checkTreeWidgetItemForSimilarName(i->getPath().getLastElement())) { - QTreeWidgetItem* el = parentItem->child(index); + AronTreeWidgetItem* el = AronTreeWidgetItem::DynamicCast(parentItem->child(index)); el->setText(1, QString::fromStdString(i->getValue())); + + if (el->aronType && el->aronType->getMaybe() != armarx::aron::type::Maybe::NONE) + { + el->setCheckState(1, Qt::CheckState::Checked); + } } } -- GitLab