7 #include "uiMeasurementQt/editor/SLandmarks.hpp" 9 #include <fwCom/Signal.hpp> 10 #include <fwCom/Signal.hxx> 11 #include <fwCom/Slot.hpp> 12 #include <fwCom/Slot.hxx> 13 #include <fwCom/Slots.hpp> 14 #include <fwCom/Slots.hxx> 16 #include <fwData/Exception.hpp> 17 #include <fwData/Landmarks.hpp> 19 #include <fwGuiQt/container/QtContainer.hpp> 21 #include <fwServices/macros.hpp> 23 #include <fwTools/NumericRoundCast.hxx> 25 #include <QColorDialog> 27 #include <QMessageBox> 28 #include <QPushButton> 29 #include <QTreeWidgetItem> 30 #include <QVBoxLayout> 42 static const ::fwServices::IService::KeyType s_LANDMARKS_INOUT =
"landmarks";
43 static const char* s_GROUP_PROPERTY_NAME =
"group";
44 static const int s_GROUP_NAME_ROLE = ::Qt::UserRole + 1;
46 static const ::fwCom::Slots::SlotKeyType s_ADD_PICKED_POINT_SLOT =
"addPickedPoint";
47 static const ::fwCom::Slots::SlotKeyType s_ADD_POINT_SLOT =
"addPoint";
48 static const ::fwCom::Slots::SlotKeyType s_MODIFY_POINT_SLOT =
"modifyPoint";
49 static const ::fwCom::Slots::SlotKeyType s_SELECT_POINT_SLOT =
"selectPoint";
50 static const ::fwCom::Slots::SlotKeyType s_DESELECT_POINT_SLOT =
"deselectPoint";
51 static const ::fwCom::Slots::SlotKeyType s_REMOVE_POINT_SLOT =
"removePoint";
52 static const ::fwCom::Slots::SlotKeyType s_ADD_GROUP_SLOT =
"addGroup";
53 static const ::fwCom::Slots::SlotKeyType s_REMOVE_GROUP_SLOT =
"removeGroup";
54 static const ::fwCom::Slots::SlotKeyType s_MODIFY_GROUP_SLOT =
"modifyGroup";
55 static const ::fwCom::Slots::SlotKeyType s_RENAME_GROUP_SLOT =
"renameGroup";
62 newSlot(s_ADD_PICKED_POINT_SLOT, &SLandmarks::addPickedPoint,
this);
63 newSlot(s_ADD_POINT_SLOT, &SLandmarks::addPoint,
this);
64 newSlot(s_MODIFY_POINT_SLOT, &SLandmarks::modifyPoint,
this);
65 newSlot(s_SELECT_POINT_SLOT, &SLandmarks::selectPoint,
this);
66 newSlot(s_DESELECT_POINT_SLOT, &SLandmarks::deselectPoint,
this);
67 newSlot(s_ADD_GROUP_SLOT, &SLandmarks::addGroup,
this);
68 newSlot(s_REMOVE_POINT_SLOT, &SLandmarks::removePoint,
this);
69 newSlot(s_REMOVE_GROUP_SLOT, &SLandmarks::removeGroup,
this);
70 newSlot(s_MODIFY_GROUP_SLOT, &SLandmarks::modifyGroup,
this);
71 newSlot(s_RENAME_GROUP_SLOT, &SLandmarks::renameGroup,
this);
73 std::srand(::fwTools::numericRoundCast<unsigned int>(std::time(NULL)));
88 const ::fwServices::IService::ConfigType config = this->
getConfigTree();
90 m_defaultLandmarkSize = config.get_optional<
float>(
"size").get_value_or(10.0);
92 "'size' value must be a positive number greater than 0 (current value: " << m_defaultLandmarkSize <<
")",
93 m_defaultLandmarkSize <= 0.f);
95 m_defaultLandmarkOpacity = config.get_optional<
float>(
"opacity").get_value_or(1.0);
97 "'opacity' value must be a number between 0.0 and 1.0 (current value: " << m_defaultLandmarkOpacity <<
")",
98 m_defaultLandmarkOpacity < 0.f || m_defaultLandmarkOpacity > 1.f);
100 const std::string advancedMode = config.get_optional<std::string>(
"advanced").get_value_or(
"no");
101 SLM_FATAL_IF(
"'advanced' value must be 'yes' or 'no', here : '" + advancedMode +
"'.",
102 advancedMode !=
"yes" && advancedMode !=
"no");
104 m_advancedMode = (advancedMode ==
"yes");
113 ::fwGuiQt::container::QtContainer::sptr qtContainer = ::fwGuiQt::container::QtContainer::dynamicCast(
114 this->getContainer() );
116 QVBoxLayout* layout =
new QVBoxLayout();
117 QGridLayout* gridLayout =
new QGridLayout();
119 m_visibilityCheckbox =
new QCheckBox();
120 QLabel* visibilityLabel =
new QLabel(QString(
"Visibility"));
121 m_sizeSlider =
new QSlider(Qt::Horizontal);
122 m_sizeSlider->setMinimum(1);
123 m_sizeSlider->setMaximum(100);
124 QLabel* sizeLabel =
new QLabel(QString(
"Size"));
125 m_opacitySlider =
new QSlider(Qt::Horizontal);
126 QLabel* opacityLabel =
new QLabel(
"Opacity");
127 m_shapeSelector =
new QComboBox();
128 m_shapeSelector->addItem(QString(
"Cube"));
129 m_shapeSelector->addItem(QString(
"Sphere"));
130 QLabel* shapeLabel =
new QLabel(
"Shape");
132 m_newGroupButton = m_advancedMode ?
new QPushButton(
"New Group") :
nullptr;
134 m_removeButton =
new QPushButton(
"Delete");
135 m_removeButton->setShortcut(QKeySequence::Delete);
137 gridLayout->addWidget(visibilityLabel, 0, 0);
138 gridLayout->addWidget(m_visibilityCheckbox, 0, 1);
139 gridLayout->addWidget(sizeLabel, 1, 0);
140 gridLayout->addWidget(m_sizeSlider, 1, 1);
141 gridLayout->addWidget(opacityLabel, 2, 0);
142 gridLayout->addWidget(m_opacitySlider, 2, 1);
143 gridLayout->addWidget(shapeLabel, 3, 0);
144 gridLayout->addWidget(m_shapeSelector, 3, 1);
145 gridLayout->addWidget(m_removeButton, 4, 1);
147 m_groupEditorWidget =
new QWidget();
148 m_groupEditorWidget->setLayout(gridLayout);
150 m_treeWidget =
new QTreeWidget();
151 QLabel* helperTextLabel =
new QLabel(
"Use 'Ctrl+Left Click' to add new landmarks");
152 layout->addWidget(helperTextLabel);
156 layout->addWidget(m_newGroupButton);
159 layout->addWidget(m_treeWidget);
160 layout->addWidget(m_groupEditorWidget);
161 m_groupEditorWidget->hide();
164 headers <<
"Group" <<
"Color";
172 m_treeWidget->setHeaderLabels(headers);
174 qtContainer->setLayout( layout );
183 m_treeWidget->blockSignals(
true);
185 ::fwData::Landmarks::sptr landmarks = this->getInOut< ::fwData::Landmarks >(s_LANDMARKS_INOUT);
187 m_treeWidget->clear();
189 for (
const auto& name : landmarks->getGroupNames())
191 this->addGroup(name);
192 this->addPoint(name);
195 QObject::connect(m_treeWidget.data(), &QTreeWidget::itemChanged,
this, &SLandmarks::onGroupNameEdited);
196 QObject::connect(m_treeWidget.data(), &QTreeWidget::currentItemChanged,
this, &SLandmarks::onSelectionChanged);
197 QObject::connect(m_sizeSlider.data(), &QSlider::valueChanged,
this, &SLandmarks::onSizeChanged);
198 QObject::connect(m_opacitySlider.data(), &QSlider::valueChanged,
this, &SLandmarks::onOpacityChanged);
199 QObject::connect(m_visibilityCheckbox.data(), &QCheckBox::stateChanged,
this, &SLandmarks::onVisibilityChanged);
200 QObject::connect(m_shapeSelector.data(), &QComboBox::currentTextChanged,
this, &SLandmarks::onShapeChanged);
201 QObject::connect(m_removeButton.data(), &QPushButton::clicked,
this, &SLandmarks::onRemoveSelection);
202 QObject::connect(m_newGroupButton.data(), &QPushButton::clicked,
this, &SLandmarks::onAddNewGroup);
204 m_treeWidget->blockSignals(
false);
216 void SLandmarks::onColorButton()
218 QObject* sender = this->sender();
221 auto qtContainer = ::fwGuiQt::container::QtContainer::dynamicCast( this->getContainer() );
222 QWidget*
const container = qtContainer->getQtContainer();
223 SLM_ASSERT(
"container not instanced", container);
225 const QColor oldColor = sender->property(
"color").value<QColor>();
226 const QColor colorQt = QColorDialog::getColor(oldColor, container,
"Select Color", QColorDialog::ShowAlphaChannel);
227 if(colorQt.isValid())
229 QPushButton* colorButton =
dynamic_cast<QPushButton*
>(sender);
230 colorButton->setProperty(
"color", colorQt);
232 setColorButtonIcon(colorButton, colorQt);
234 const std::string groupName = colorButton->property(s_GROUP_PROPERTY_NAME).value<QString>().toStdString();
236 ::fwData::Landmarks::sptr landmarks = this->getInOut< ::fwData::Landmarks >(s_LANDMARKS_INOUT);
238 auto& group = landmarks->getGroup(groupName);
239 ::fwData::Landmarks::ColorType color = {{colorQt.red()/255.f, colorQt.green()/255.f, colorQt.blue()/255.f,
240 colorQt.alpha()/255.f}};
242 m_opacitySlider->setValue(static_cast<int>(color[3] * m_opacitySlider->maximum()));
244 group.m_color = color;
251 sig->asyncEmit(groupName);
258 void SLandmarks::onGroupNameEdited(QTreeWidgetItem* item,
int column)
260 OSLM_ERROR_IF(
"A column different from the group's name is being edited", column != 0);
261 m_treeWidget->blockSignals(
true);
265 ::fwData::Landmarks::sptr landmarks = this->getInOut< ::fwData::Landmarks >(s_LANDMARKS_INOUT);
267 QString oldGroupName = item->data(0, s_GROUP_NAME_ROLE).toString();
268 QString newGroupName = item->text(0);
270 if(newGroupName.isEmpty())
272 QString msg =
"The new group name for '" + oldGroupName +
273 "' is empty. Please enter a valid name and try again";
274 QMessageBox msgBox(QMessageBox::Warning,
"No group name", msg, QMessageBox::Ok);
277 item->setText(0, oldGroupName);
279 else if(oldGroupName != newGroupName)
283 landmarks->renameGroup(oldGroupName.toStdString(), newGroupName.toStdString());
290 sig->asyncEmit(oldGroupName.toStdString(), newGroupName.toStdString());
293 item->setData(0, s_GROUP_NAME_ROLE, newGroupName);
294 QWidget* widget = m_treeWidget->itemWidget(item, 1);
296 widget->setProperty(s_GROUP_PROPERTY_NAME, newGroupName);
300 QString msg =
"Can't rename '" + oldGroupName +
"' as '" + newGroupName +
".\n" +
302 QMessageBox msgBox(QMessageBox::Warning,
"Can't rename" + oldGroupName, msg, QMessageBox::Ok);
305 item->setText(0, oldGroupName);
309 m_treeWidget->blockSignals(
false);
314 void SLandmarks::onSelectionChanged(QTreeWidgetItem* current, QTreeWidgetItem* previous)
316 ::fwData::Landmarks::sptr landmarks = this->getInOut< ::fwData::Landmarks >(s_LANDMARKS_INOUT);
327 QTreeWidgetItem* previousParent = previous->parent();
329 if(previousParent !=
nullptr)
331 const std::string& groupName = previousParent->text(0).toStdString();
333 size_t index =
static_cast<size_t>(previousParent->indexOfChild(previous));
335 SLM_ASSERT(
"index must be inferior to the number of points in '" + groupName +
"'.",
336 index < landmarks->getNumberOfPoints(groupName));
338 deselectSig->asyncEmit(groupName, index);
343 const std::string& groupName = previous->text(0).toStdString();
345 deselectSig->asyncEmit(groupName, 0);
354 std::string groupName;
357 QTreeWidgetItem* currentParent = current->parent();
359 if(currentParent !=
nullptr)
361 groupName = currentParent->text(0).toStdString();
363 size_t index =
static_cast<size_t>(currentParent->indexOfChild(current));
365 SLM_ASSERT(
"index must be inferior to the number of points in '" + groupName +
"'.",
366 index < landmarks->getNumberOfPoints(groupName));
369 selectSig->asyncEmit(groupName, index);
373 groupName = current->text(0).toStdString();
378 groupName = current->text(0).toStdString();
381 selectSig->asyncEmit(groupName, 0);
384 const ::fwData::Landmarks::LandmarksGroup& group = landmarks->getGroup(groupName);
387 m_sizeSlider->setValue(static_cast<int>(group.m_size));
388 m_visibilityCheckbox->setChecked(group.m_visibility);
390 const QString shapeText = group.m_shape == ::fwData::Landmarks::Shape::CUBE ?
"Cube" :
"Sphere";
391 m_shapeSelector->setCurrentText(shapeText);
393 float opacity = group.m_color[3];
394 m_opacitySlider->setValue(static_cast<int>(opacity * m_opacitySlider->maximum()));
398 m_groupEditorWidget->setHidden(current ==
nullptr);
403 void SLandmarks::onSizeChanged(
int newSize)
405 ::fwData::Landmarks::sptr landmarks = this->getInOut< ::fwData::Landmarks >(s_LANDMARKS_INOUT);
407 const ::fwData::Landmarks::SizeType realSize =
static_cast< ::fwData::Landmarks::SizeType
>(newSize);
409 std::string groupName;
410 if(currentSelection(groupName))
412 landmarks->setGroupSize(groupName, realSize);
419 sig->asyncEmit(groupName);
425 void SLandmarks::onOpacityChanged(
int newOpacity)
427 ::fwData::Landmarks::sptr landmarks = this->getInOut< ::fwData::Landmarks >(s_LANDMARKS_INOUT);
429 const float sliderSize =
static_cast<float>( m_opacitySlider->maximum() - m_opacitySlider->minimum());
431 const float realOpacity =
static_cast<float>(newOpacity) / sliderSize;
433 std::string groupName;
434 if(currentSelection(groupName))
436 const auto groupColor = landmarks->getGroup(groupName).m_color;
438 ::fwData::Landmarks::ColorType newGroupColor
439 = {{groupColor[0], groupColor[1], groupColor[2], realOpacity}};
441 landmarks->setGroupColor(groupName, newGroupColor);
443 QTreeWidgetItem* item = getGroupItem(groupName);
444 QPushButton* colorButton =
dynamic_cast<QPushButton*
>(m_treeWidget->itemWidget(item, 1));
446 QColor currentColor = colorButton->property(
"color").value<QColor>();
447 currentColor.setAlphaF(realOpacity);
448 colorButton->setProperty(
"color", currentColor);
450 setColorButtonIcon(colorButton, currentColor);
457 sig->asyncEmit(groupName);
463 void SLandmarks::onVisibilityChanged(
int visibility)
465 ::fwData::Landmarks::sptr landmarks = this->getInOut< ::fwData::Landmarks >(s_LANDMARKS_INOUT);
467 std::string groupName;
468 if(currentSelection(groupName))
470 landmarks->setGroupVisibility(groupName, static_cast<bool>(visibility));
477 sig->asyncEmit(groupName);
483 void SLandmarks::onShapeChanged(
const QString& shape)
485 ::fwData::Landmarks::sptr landmarks = this->getInOut< ::fwData::Landmarks >(s_LANDMARKS_INOUT);
487 std::string groupName;
488 if(currentSelection(groupName))
490 SLM_ASSERT(
"Shape must be 'Cube' or 'Sphere'.", shape ==
"Cube" || shape ==
"Sphere");
491 const ::fwData::Landmarks::Shape s
492 = (shape ==
"Cube") ? ::fwData::Landmarks::Shape::CUBE : ::fwData::Landmarks::Shape::SPHERE;
494 landmarks->setGroupShape(groupName, s);
501 sig->asyncEmit(groupName);
507 void SLandmarks::onAddNewGroup()
509 ::fwData::Landmarks::sptr landmarks = this->getInOut< ::fwData::Landmarks >(s_LANDMARKS_INOUT);
511 const std::string groupName = this->generateNewGroupName();
512 landmarks->addGroup(groupName, this->generateNewColor(), m_defaultLandmarkSize);
514 this->addGroup(groupName);
521 sig->asyncEmit(groupName);
527 void SLandmarks::onRemoveSelection()
529 m_treeWidget->blockSignals(
true);
531 ::fwData::Landmarks::sptr landmarks = this->getInOut< ::fwData::Landmarks >(s_LANDMARKS_INOUT);
532 QTreeWidgetItem* item = m_treeWidget->currentItem();
536 const int topLevelIndex = m_treeWidget->indexOfTopLevelItem(item);
538 if(m_advancedMode && topLevelIndex == -1)
540 QTreeWidgetItem* itemParent = item->parent();
542 const size_t index =
static_cast<size_t>(itemParent->indexOfChild(item));
543 const std::string& groupName = itemParent->text(0).toStdString();
545 landmarks->removePoint(groupName, index);
546 itemParent->removeChild(item);
553 sig->asyncEmit(groupName, index);
558 const std::string& groupName = item->text(0).toStdString();
560 landmarks->removeGroup(groupName);
561 delete m_treeWidget->takeTopLevelItem(topLevelIndex);
568 sig->asyncEmit(groupName);
572 m_treeWidget->setCurrentItem(
nullptr);
573 m_groupEditorWidget->setHidden(
true);
576 m_treeWidget->blockSignals(
false);
583 if(pickingInfo.
m_eventId == ::fwDataTools::PickingInfo::Event::MOUSE_LEFT_UP &&
587 ::fwData::Landmarks::PointType newPoint = {{ pickedPos[0], pickedPos[1], pickedPos[2] }};
589 ::fwData::Landmarks::sptr landmarks = this->getInOut< ::fwData::Landmarks >(s_LANDMARKS_INOUT);
591 std::string groupName;
592 QTreeWidgetItem* item = m_treeWidget->currentItem();
594 if(item ==
nullptr || !m_advancedMode)
596 groupName = this->generateNewGroupName();
597 landmarks->addGroup(groupName, this->generateNewColor(), m_defaultLandmarkSize);
599 this->addGroup(groupName);
606 sig->asyncEmit(groupName);
611 const int topLevelIndex = m_treeWidget->indexOfTopLevelItem(item);
613 if(topLevelIndex == -1)
615 item = item->parent();
617 groupName = item->text(0).toStdString();
620 landmarks->addPoint(groupName, newPoint);
621 this->addPoint(groupName);
627 sig->asyncEmit(groupName);
633 void SLandmarks::addPoint(std::string groupName)
637 m_treeWidget->blockSignals(
true);
639 ::fwData::Landmarks::sptr landmarks = this->getInOut< ::fwData::Landmarks >(s_LANDMARKS_INOUT);
641 QTreeWidgetItem* item = getGroupItem(groupName);
643 const size_t nbChilds =
static_cast<size_t>(item->childCount());
644 const size_t nbPoints = landmarks->getNumberOfPoints(groupName);
645 for(
size_t idx = nbChilds; idx < nbPoints; ++idx)
647 const ::fwData::Landmarks::PointType& newPoint = landmarks->getPoint(groupName, idx);
649 QTreeWidgetItem* pt =
new QTreeWidgetItem();
650 for(
int i = 0; i < 3; ++i)
652 pt->setText(i, QString::fromStdString(std::to_string(newPoint[static_cast<size_t>(i)])));
657 m_treeWidget->blockSignals(
false);
663 void SLandmarks::addGroup(std::string name)
665 ::fwData::Landmarks::sptr landmarks = this->getInOut< ::fwData::Landmarks >(s_LANDMARKS_INOUT);
667 const auto& group = landmarks->getGroup(name);
669 QTreeWidgetItem* item =
new QTreeWidgetItem();
670 item->setFlags(item->flags() | Qt::ItemIsEditable);
671 item->setData(0, s_GROUP_NAME_ROLE, QString::fromStdString(name));
673 m_treeWidget->addTopLevelItem(item);
675 item->setText(0, QString::fromStdString(name));
676 QPushButton* button =
new QPushButton();
678 const QColor color = convertToQColor(group.m_color);
680 setColorButtonIcon(button, color);
681 button->setProperty(
"color", color);
682 button->setProperty(s_GROUP_PROPERTY_NAME, QString::fromStdString(name));
684 QObject::connect(button, &QPushButton::clicked,
this, &SLandmarks::onColorButton);
686 m_treeWidget->setItemWidget(item, 1, button);
691 void SLandmarks::removeGroup(std::string name)
693 QTreeWidgetItem* item = getGroupItem(name);
695 while(item->childCount() != 0)
697 item->removeChild(item->child(0));
699 const int index = m_treeWidget->indexOfTopLevelItem(item);
700 QTreeWidgetItem* topItem = m_treeWidget->takeTopLevelItem(index);
706 void SLandmarks::removePoint(std::string groupName,
size_t index)
708 m_treeWidget->blockSignals(
true);
710 QTreeWidgetItem* item = getGroupItem(groupName);
712 OSLM_ASSERT(
"Index must be less than " << item->childCount(),
static_cast<int>(index) < item->childCount());
714 QTreeWidgetItem* pointItem = item->child(static_cast<int>(index));
715 item->removeChild(pointItem);
716 m_treeWidget->blockSignals(
false);
721 void SLandmarks::renameGroup(std::string oldName, std::string newName)
723 m_treeWidget->blockSignals(
true);
725 const QString qtNewName = QString::fromStdString(newName);
726 QTreeWidgetItem* item = getGroupItem(oldName);
727 item->setData(0, s_GROUP_NAME_ROLE, qtNewName);
728 QWidget* widget = m_treeWidget->itemWidget(item, 1);
729 widget->setProperty(s_GROUP_PROPERTY_NAME, qtNewName);
731 item->setText(0, qtNewName);
732 m_treeWidget->blockSignals(
false);
737 void SLandmarks::modifyGroup(std::string name)
739 QTreeWidgetItem* item = getGroupItem(name);
741 item->setText(0, name.c_str());
743 ::fwData::Landmarks::sptr landmarks = this->getInOut< ::fwData::Landmarks >(s_LANDMARKS_INOUT);
745 const ::fwData::Landmarks::LandmarksGroup& group = landmarks->getGroup(name);
747 QPushButton* colorButton =
dynamic_cast< QPushButton*
>(m_treeWidget->itemWidget(item, 1));
749 const QColor color = convertToQColor(group.m_color);
751 setColorButtonIcon(colorButton, color);
753 bool groupSelected = item->isSelected();
757 for(
int i = 0; i < item->childCount() && !groupSelected; ++i)
759 groupSelected = item->child(i)->isSelected();
765 const ::fwData::Landmarks::LandmarksGroup& group = landmarks->getGroup(name);
768 m_sizeSlider->setValue(static_cast<int>(group.m_size));
769 m_visibilityCheckbox->setChecked(group.m_visibility);
771 const QString shapeText = group.m_shape == ::fwData::Landmarks::Shape::CUBE ?
"Cube" :
"Sphere";
772 m_shapeSelector->setCurrentText(shapeText);
774 const float opacity = group.m_color[3];
775 m_opacitySlider->setValue(static_cast<int>(opacity * m_opacitySlider->maximum()));
782 void SLandmarks::modifyPoint(std::string groupName,
size_t index)
786 ::fwData::Landmarks::sptr landmarks = this->getInOut< ::fwData::Landmarks >(s_LANDMARKS_INOUT);
788 auto itemList = m_treeWidget->findItems(QString::fromStdString(groupName), Qt::MatchExactly);
790 SLM_ASSERT(
"Only a single item can be named '" + groupName +
"'", itemList.size() == 1);
792 QTreeWidgetItem* item = itemList.at(0);
794 OSLM_ASSERT(
"Index must be less than " << item->childCount(),
static_cast<int>(index) < item->childCount());
796 QTreeWidgetItem* pointItem = item->child(static_cast<int>(index));
797 const ::fwData::Landmarks::PointType&
point = landmarks->getPoint(groupName, index);
799 m_treeWidget->blockSignals(
true);
800 for(
int i = 0; i < 3; ++i)
802 pointItem->setText(i, QString(
"%1").arg(point[static_cast<size_t>(i)]));
804 m_treeWidget->blockSignals(
false);
810 void SLandmarks::selectPoint(std::string groupName,
size_t index)
812 m_treeWidget->blockSignals(
true);
814 QTreeWidgetItem* currentItem = getGroupItem(groupName);
819 "Index must be less than " << currentItem->childCount(),
820 static_cast<int>(index) < currentItem->childCount());
822 currentItem = currentItem->child(static_cast<int>(index));
824 m_treeWidget->setCurrentItem(currentItem);
826 ::fwData::Landmarks::sptr landmarks = this->getInOut< ::fwData::Landmarks >(s_LANDMARKS_INOUT);
828 const ::fwData::Landmarks::LandmarksGroup& group = landmarks->getGroup(groupName);
831 m_sizeSlider->setValue(static_cast<int>(group.m_size));
832 m_visibilityCheckbox->setChecked(group.m_visibility);
834 const QString shapeText = group.m_shape == ::fwData::Landmarks::Shape::CUBE ?
"Cube" :
"Sphere";
835 m_shapeSelector->setCurrentText(shapeText);
837 const float opacity = group.m_color[3];
838 m_opacitySlider->setValue(static_cast<int>(opacity * m_opacitySlider->maximum()));
840 m_groupEditorWidget->show();
841 m_treeWidget->blockSignals(
false);
846 void SLandmarks::deselectPoint(std::string,
size_t)
848 m_treeWidget->blockSignals(
true);
849 m_treeWidget->setCurrentItem(
nullptr);
850 m_groupEditorWidget->hide();
851 m_treeWidget->blockSignals(
false);
856 std::string SLandmarks::generateNewGroupName()
const 858 static size_t groupCount = 0;
860 const ::fwData::Landmarks::sptr landmarks = this->getInOut< ::fwData::Landmarks >(s_LANDMARKS_INOUT);
862 const ::fwData::Landmarks::GroupNameContainer groupNames = landmarks->getGroupNames();
864 const std::string newGroupNamePrefix = m_advancedMode ?
"Group_" :
"Point_";
866 while(std::find(groupNames.begin(), groupNames.end(),
867 newGroupNamePrefix + std::to_string(groupCount)) != groupNames.end())
872 return newGroupNamePrefix + std::to_string(groupCount);
877 std::array<float, 4> SLandmarks::generateNewColor()
879 const std::array<float,
880 4> color = {{rand()%255/255.f, rand()%255/255.f, rand()%255/255.f, m_defaultLandmarkOpacity}};
886 bool SLandmarks::currentSelection(std::string& selection)
const 888 QTreeWidgetItem* item = m_treeWidget->currentItem();
890 const bool selectedGroup = (item !=
nullptr);
894 const int topLevelIndex = m_treeWidget->indexOfTopLevelItem(item);
896 if(m_advancedMode && topLevelIndex == -1)
898 item = item->parent();
901 selection = item->text(0).toStdString();
904 return selectedGroup;
909 QColor SLandmarks::convertToQColor(const ::fwData::Landmarks::ColorType& color)
912 static_cast<int>(color[0]*255),
913 static_cast<int>(color[1]*255),
914 static_cast<int>(color[2]*255),
915 static_cast<int>(color[3]*255)
921 void SLandmarks::setColorButtonIcon(QPushButton* button,
const QColor& color)
923 const int iconSize = button->style()->pixelMetric(QStyle::PM_LargeIconSize);
924 QPixmap pix(iconSize, iconSize);
927 button->setIcon(QIcon(pix));
932 QTreeWidgetItem* SLandmarks::getGroupItem(
const std::string& groupName)
const 934 const auto itemList = m_treeWidget->findItems(QString::fromStdString(groupName), Qt::MatchExactly);
936 SLM_ASSERT(
"Only a single item can be named '" + groupName +
"'", itemList.size() == 1);
938 return itemList.at(0);
This class is a helper to define the connections of a service and its data.
virtual UIMEASUREMENTQT_API ~SLandmarks() noexcept
Destructor. Do nothing.
virtual void configuring() override
Configure the service before starting. Apply the configuration to service.
#define OSLM_ASSERT(message, cond)
work like 'assert' from 'cassert', with in addition a message logged by spylog (with FATAL loglevel) ...
Class allowing to block a Connection.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_POINT_DESELECTED_SIG
Type of signal when a group is added.
Defines the service interface managing the editor service for object.
FWGUI_API void destroy()
Stops sub-views and toobar services. Destroys view, sub-views and toolbar containers.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_GROUP_ADDED_SIG
Type of signal when a group is added.
Implements data exception class.
virtual void starting() override
Install the layout.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_GROUP_REMOVED_SIG
Type of signal when a group is added.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_POINT_SELECTED_SIG
Type of signal when a group is added.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_POINT_ADDED_SIG
Type of signal when a group is added.
virtual void stopping() override
Destroy the layout.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_GROUP_RENAMED_SIG
Type of signal when a group is added.
#define SLM_ASSERT(message, cond)
work like 'assert' from 'cassert', with in addition a message logged by spylog (with FATAL loglevel) ...
FWGUI_API void create()
Creates view, sub-views and toolbar containers. Manages sub-views and toobar services.
#define SLM_FATAL_IF(message, cond)
virtual UIMEASUREMENTQT_API KeyConnectionsMap getAutoConnections() const override
Returns proposals to connect service slots to associated objects signals, this method is used for obj...
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_MODIFIED_SIG
Key in m_signals map of signal m_sigModified.
virtual void updating() override
Do nothing.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_POINT_MODIFIED_SIG
Type of signal when a group is added.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_GROUP_MODIFIED_SIG
Type of signal when a group is added.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_POINT_REMOVED_SIG
Type of signal when a group is added.
UIMEASUREMENTQT_API SLandmarks() noexcept
Constructor. Do nothing.
#define OSLM_FATAL_IF(message, cond)
static FWSERVICES_APIconst::fwCom::Slots::SlotKeyType s_UPDATE_SLOT
Slot to call start method.
#define OSLM_ERROR_IF(message, cond)
FWGUI_API void initialize()
Initialize managers.
This service defines a graphical editor to edit landmarks.
FWSERVICES_API ConfigType getConfigTree() const
Return the configuration, in an boost property tree.