From 2054879244f3323c305222c79c57d2db6a487538 Mon Sep 17 00:00:00 2001 From: vsv Date: Wed, 16 Nov 2016 18:59:46 +0300 Subject: [PATCH] Issue #1865: Model Widget for fields --- src/CollectionPlugin/CMakeLists.txt | 7 + .../CollectionPlugin_Plugin.cpp | 8 + .../CollectionPlugin_WidgetCreator.cpp | 38 +++ .../CollectionPlugin_WidgetCreator.h | 52 ++++ .../CollectionPlugin_WidgetField.cpp | 224 ++++++++++++++++++ .../CollectionPlugin_WidgetField.h | 82 +++++++ src/CollectionPlugin/icons/field.png | Bin 0 -> 1086 bytes src/CollectionPlugin/plugin-Collection.xml | 7 + 8 files changed, 418 insertions(+) create mode 100644 src/CollectionPlugin/CollectionPlugin_WidgetCreator.cpp create mode 100644 src/CollectionPlugin/CollectionPlugin_WidgetCreator.h create mode 100644 src/CollectionPlugin/CollectionPlugin_WidgetField.cpp create mode 100644 src/CollectionPlugin/CollectionPlugin_WidgetField.h create mode 100644 src/CollectionPlugin/icons/field.png diff --git a/src/CollectionPlugin/CMakeLists.txt b/src/CollectionPlugin/CMakeLists.txt index 081f5bc5e..69df04034 100644 --- a/src/CollectionPlugin/CMakeLists.txt +++ b/src/CollectionPlugin/CMakeLists.txt @@ -2,18 +2,23 @@ INCLUDE(Common) INCLUDE(UnitTest) +SET(CMAKE_AUTOMOC ON) SET(PROJECT_HEADERS CollectionPlugin.h CollectionPlugin_Plugin.h CollectionPlugin_Group.h CollectionPlugin_Field.h + CollectionPlugin_WidgetCreator.h + CollectionPlugin_WidgetField.h ) SET(PROJECT_SOURCES CollectionPlugin_Plugin.cpp CollectionPlugin_Group.cpp CollectionPlugin_Field.cpp + CollectionPlugin_WidgetCreator.cpp + CollectionPlugin_WidgetField.cpp ) SET(XML_RESOURCES @@ -34,6 +39,7 @@ INCLUDE_DIRECTORIES( ../GeomAlgoAPI ../GeomValidators ../Events + ../ModuleBase ) SET(PROJECT_LIBRARIES @@ -42,6 +48,7 @@ SET(PROJECT_LIBRARIES GeomAPI GeomAlgoAPI GeomValidators + ModuleBase ) ADD_DEFINITIONS(-DCOLLECTIONPLUGIN_EXPORTS) diff --git a/src/CollectionPlugin/CollectionPlugin_Plugin.cpp b/src/CollectionPlugin/CollectionPlugin_Plugin.cpp index 6732c4c73..6f0ca30e7 100644 --- a/src/CollectionPlugin/CollectionPlugin_Plugin.cpp +++ b/src/CollectionPlugin/CollectionPlugin_Plugin.cpp @@ -6,6 +6,10 @@ #include #include +#include + +#include "CollectionPlugin_WidgetCreator.h" + #include #include @@ -14,6 +18,10 @@ static CollectionPlugin_Plugin* MY_COLLECTION_INSTANCE = new CollectionPlugin_Pl CollectionPlugin_Plugin::CollectionPlugin_Plugin() { + WidgetCreatorFactoryPtr aWidgetCreatorFactory = ModuleBase_WidgetCreatorFactory::get(); + aWidgetCreatorFactory->registerCreator( + std::shared_ptr(new CollectionPlugin_WidgetCreator())); + SessionPtr aMgr = ModelAPI_Session::get(); // register this plugin ModelAPI_Session::get()->registerPlugin(this); diff --git a/src/CollectionPlugin/CollectionPlugin_WidgetCreator.cpp b/src/CollectionPlugin/CollectionPlugin_WidgetCreator.cpp new file mode 100644 index 000000000..a07562235 --- /dev/null +++ b/src/CollectionPlugin/CollectionPlugin_WidgetCreator.cpp @@ -0,0 +1,38 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +// File: CollectionPlugin_WidgetCreator.cpp +// Created: 15 Nov 2016 +// Author: Vitaly SMETANNIKOV + +#include "CollectionPlugin_WidgetCreator.h" +#include "CollectionPlugin_WidgetField.h" + + +CollectionPlugin_WidgetCreator::CollectionPlugin_WidgetCreator() +: ModuleBase_IWidgetCreator() +{ + myPanelTypes.insert("field-panel"); +} + +void CollectionPlugin_WidgetCreator::widgetTypes(std::set& theTypes) +{ + theTypes = myPanelTypes; +} + + +ModuleBase_ModelWidget* CollectionPlugin_WidgetCreator::createWidgetByType( + const std::string& theType, + QWidget* theParent, + Config_WidgetAPI* theWidgetApi, + ModuleBase_IWorkshop* /*theWorkshop*/) +{ + ModuleBase_ModelWidget* aWidget = 0; + if (myPanelTypes.find(theType) == myPanelTypes.end()) + return aWidget; + + if (theType == "field-panel") { + aWidget = new CollectionPlugin_WidgetField(theParent, theWidgetApi); + } + + return aWidget; +} diff --git a/src/CollectionPlugin/CollectionPlugin_WidgetCreator.h b/src/CollectionPlugin/CollectionPlugin_WidgetCreator.h new file mode 100644 index 000000000..ce806ca19 --- /dev/null +++ b/src/CollectionPlugin/CollectionPlugin_WidgetCreator.h @@ -0,0 +1,52 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +// File: CollectionPlugin_WidgetCreator.h +// Created: 15 Nov 2016 +// Author: Vitaly SMETANNIKOV + + +#ifndef CollectionPlugin_WidgetCreator_H +#define CollectionPlugin_WidgetCreator_H + + +#include "CollectionPlugin.h" +#include + +#include +#include + +class QWidget; + +/** +* \ingroup GUI +* Interface to WidgetCreator which can create specific widgets by type +*/ +class CollectionPlugin_WidgetCreator : public ModuleBase_IWidgetCreator +{ +public: + /// Default constructor + CollectionPlugin_WidgetCreator(); + + /// Virtual destructor + ~CollectionPlugin_WidgetCreator() {} + + /// Returns a container of possible page types, which this creator can process + /// \param theTypes a list of type names + virtual void widgetTypes(std::set& theTypes); + + /// Create widget by its type + /// The default implementation is empty + /// \param theType a type + /// \param theParent a parent widget + /// \param theData a low-level API for reading xml definitions of widgets + /// \param theWorkshop a current workshop + /// \return a created model widget or null + virtual ModuleBase_ModelWidget* createWidgetByType(const std::string& theType, + QWidget* theParent, + Config_WidgetAPI* theWidgetApi, + ModuleBase_IWorkshop* /*theWorkshop*/); +private: + std::set myPanelTypes; ///< types of panels +}; + +#endif \ No newline at end of file diff --git a/src/CollectionPlugin/CollectionPlugin_WidgetField.cpp b/src/CollectionPlugin/CollectionPlugin_WidgetField.cpp new file mode 100644 index 000000000..d0500355e --- /dev/null +++ b/src/CollectionPlugin/CollectionPlugin_WidgetField.cpp @@ -0,0 +1,224 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +// File: CollectionPlugin_WidgetField.cpp +// Created: 16 Nov 2016 +// Author: Vitaly SMETANNIKOV + +#include "CollectionPlugin_WidgetField.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +CollectionPlugin_WidgetField:: + CollectionPlugin_WidgetField(QWidget* theParent, const Config_WidgetAPI* theData): +ModuleBase_ModelWidget(theParent, theData) +{ + QVBoxLayout* aMainLayout = new QVBoxLayout(this); + + // Types definition controls + QWidget* aTypesWgt = new QWidget(this); + QFormLayout* aTypesLayout = new QFormLayout(aTypesWgt); + aTypesLayout->setContentsMargins(0, 0, 0, 0); + aMainLayout->addWidget(aTypesWgt); + + // Type of shapes + myShapeTypeCombo = new QComboBox(aTypesWgt); + QStringList aShapeTypes; + aShapeTypes << tr("Vertices") << tr("Edges") << tr("Faces") + << tr("Solids") << tr("Results") << tr("Parts"); + myShapeTypeCombo->addItems(aShapeTypes); + aTypesLayout->addRow(tr("Type of shapes"), myShapeTypeCombo); + + // Type of field + myFieldTypeCombo = new QComboBox(aTypesWgt); + QStringList aFieldTypes; + aFieldTypes << tr("Double") << tr("Integer") << tr("Boolean") + << tr("String"); + myFieldTypeCombo->addItems(aFieldTypes); + aTypesLayout->addRow(tr("Type of field"), myFieldTypeCombo); + + // Number of components + myNbComponentsSpn = new QSpinBox(aTypesWgt); + myNbComponentsSpn->setMinimum(1); + aTypesLayout->addRow(tr("Nb. of components"), myNbComponentsSpn); + + // Steps controls + QFrame* aStepFrame = new QFrame(this); + aStepFrame->setFrameShape(QFrame::Box); + aStepFrame->setFrameStyle(QFrame::StyledPanel); + QGridLayout* aStepLayout = new QGridLayout(aStepFrame); + aMainLayout->addWidget(aStepFrame); + + // Current step label + aStepLayout->addWidget(new QLabel(tr("Current step"), aStepFrame), 0, 0); + myCurStepLbl = new QLabel("1", aStepFrame); + QFont aFont = myCurStepLbl->font(); + aFont.setBold(true); + myCurStepLbl->setFont(aFont); + aStepLayout->addWidget(myCurStepLbl, 0, 1); + + // Steps slider + QWidget* aSliderWidget = new QWidget(aStepFrame); + aStepLayout->addWidget(aSliderWidget, 1, 0, 1, 2); + QHBoxLayout* aSliderLayout = new QHBoxLayout(aSliderWidget); + aSliderLayout->setContentsMargins(0, 0, 0, 0); + + aSliderLayout->addWidget(new QLabel("1", aSliderWidget)); + + myStepSlider = new QSlider(Qt::Horizontal, aSliderWidget); + myStepSlider->setTickPosition(QSlider::TicksBelow); + myStepSlider->setRange(1, 1); + myStepSlider->setPageStep(myStepSlider->singleStep()); + aSliderLayout->addWidget(myStepSlider, 1); + + myMaxLbl = new QLabel("1", aSliderWidget); + aSliderLayout->addWidget(myMaxLbl); + + // Stamp value + aStepLayout->addWidget(new QLabel(tr("Stamp"), aStepFrame), 2, 0); + myStampSpn = new QSpinBox(aStepFrame); + aStepLayout->addWidget(myStampSpn, 2, 1); + + // Data table + myDataTbl = new QTableWidget(2, 2, aStepFrame); + myDataTbl->verticalHeader()->hide(); + myDataTbl->horizontalHeader()->hide(); + myDataTbl->setRowHeight(0, 25); + myDataTbl->setRowHeight(1, 25); + + QTableWidgetItem* aItem = new QTableWidgetItem("Shape"); + aItem->setBackgroundColor(Qt::lightGray); + aItem->setFlags(Qt::NoItemFlags | Qt::ItemIsEnabled); + myDataTbl->setItem(0, 0, aItem); + + aItem = new QTableWidgetItem("Comp 1"); + aItem->setBackgroundColor(Qt::lightGray); + myDataTbl->setItem(0, 1, aItem); + + aItem = new QTableWidgetItem("Default value"); + aItem->setBackgroundColor(Qt::lightGray); + aItem->setFlags(Qt::NoItemFlags | Qt::ItemIsEnabled); + myDataTbl->setItem(1, 0, aItem); + + aItem = new QTableWidgetItem("0"); + aItem->setBackgroundColor(Qt::lightGray); + myDataTbl->setItem(1, 1, aItem); + + aStepLayout->addWidget(myDataTbl, 3, 0, 1, 2); + + // Buttons below + QWidget* aBtnWgt = new QWidget(this); + aMainLayout->addWidget(aBtnWgt); + QHBoxLayout* aBtnLayout = new QHBoxLayout(aBtnWgt); + aBtnLayout->setContentsMargins(0, 0, 0, 0); + + QPushButton* aAddBtn = new QPushButton(tr("Add step"), aBtnWgt); + aBtnLayout->addWidget(aAddBtn); + + aBtnLayout->addStretch(1); + + QPushButton* aRemoveBtn = new QPushButton(tr("Remove step"), aBtnWgt); + aBtnLayout->addWidget(aRemoveBtn); + + connect(myNbComponentsSpn, SIGNAL(valueChanged(int)), SLOT(onNbCompChanged(int))); + connect(aAddBtn, SIGNAL(clicked(bool)), SLOT(onAddStep())); + connect(aRemoveBtn, SIGNAL(clicked(bool)), SLOT(onRemoveStep())); + connect(myStepSlider, SIGNAL(valueChanged(int)), SLOT(onStepMove(int))); +} + +QList CollectionPlugin_WidgetField::getControls() const +{ + QList aControls; + // this control will accept focus and will be highlighted in the Property Panel + //aControls.push_back(myComboBox); + return aControls; +} + +bool CollectionPlugin_WidgetField::storeValueCustom() +{ + //AttributePtr anAttribute = myFeature->attribute(SamplePanelPlugin_Feature::VALUE_ID()); + //AttributeIntegerPtr aValueAttribute = + // std::dynamic_pointer_cast(anAttribute); + //aValueAttribute->setValue(myComboBox->currentIndex()); + //updateObject(myFeature); + return true; +} + +bool CollectionPlugin_WidgetField::restoreValueCustom() +{ + //AttributePtr anAttribute = myFeature->attribute(SamplePanelPlugin_Feature::VALUE_ID()); + //AttributeIntegerPtr aValueAttribute = + // std::dynamic_pointer_cast(anAttribute); + + //bool isBlocked = myComboBox->blockSignals(true); + //myComboBox->setCurrentIndex(aValueAttribute->value()); + //myComboBox->blockSignals(isBlocked); + + return true; +} + +void CollectionPlugin_WidgetField::onNbCompChanged(int theVal) +{ + int aOldCol = myDataTbl->columnCount() - 1; + int aNbRows = myDataTbl->rowCount(); + myDataTbl->setColumnCount(theVal + 1); + int aDif = theVal - aOldCol; + QTableWidgetItem* aItem = 0; + for (int i = 0; i < aDif; i++) { + for (int j = 0; j < aNbRows; j++) { + aItem = new QTableWidgetItem(); + if (j == 0) + aItem->setText(QString("Comp %1").arg(i + aOldCol + 1)); + else + aItem->setText("0"); + if (j < 3) + aItem->setBackgroundColor(Qt::lightGray); + myDataTbl->setItem(j, i + aOldCol + 1, aItem); + } + } +} + +void CollectionPlugin_WidgetField::onAddStep() +{ + int aMax = myStepSlider->maximum(); + aMax++; + myStepSlider->setMaximum(aMax); + myMaxLbl->setText(QString::number(aMax)); + clearData(); + myStepSlider->setValue(aMax); +} + +void CollectionPlugin_WidgetField::onRemoveStep() +{ + int aMax = myStepSlider->maximum(); + aMax--; + myStepSlider->setMaximum(aMax); + myMaxLbl->setText(QString::number(aMax)); +} + +void CollectionPlugin_WidgetField::clearData() +{ + int aNbRows = myDataTbl->rowCount(); + int aNbCol = myDataTbl->columnCount(); + + QString aDefValue; + for (int i = 1; i < aNbCol; i++) { + aDefValue = myDataTbl->item(1, i)->text(); + for (int j = 2; j < aNbRows; j++) { + myDataTbl->item(j, i)->setText(aDefValue); + } + } +} + +void CollectionPlugin_WidgetField::onStepMove(int theStep) +{ + myCurStepLbl->setText(QString::number(theStep)); +} diff --git a/src/CollectionPlugin/CollectionPlugin_WidgetField.h b/src/CollectionPlugin/CollectionPlugin_WidgetField.h new file mode 100644 index 000000000..009815739 --- /dev/null +++ b/src/CollectionPlugin/CollectionPlugin_WidgetField.h @@ -0,0 +1,82 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +// File: CollectionPlugin_WidgetField.h +// Created: 16 Nov 2016 +// Author: Vitaly SMETANNIKOV + + +#ifndef CollectionPlugin_WidgetField_H +#define CollectionPlugin_WidgetField_H + + +#include "CollectionPlugin.h" + +#include + +class QWidget; +class QComboBox; +class QSpinBox; +class QLabel; +class QSlider; +class QTableWidget; + +/*! + * \ingroup GUI + * Represent a content of the property panel to show/modify parameters of a Field feature. + */ +class CollectionPlugin_WidgetField : public ModuleBase_ModelWidget +{ + Q_OBJECT +public: + CollectionPlugin_WidgetField(QWidget* theParent, const Config_WidgetAPI* theData); + + virtual ~CollectionPlugin_WidgetField() {} + + /// Returns list of widget controls + /// \return a control list + virtual QList getControls() const; + +protected: + /// Saves the internal parameters to the given feature + /// \return True in success + virtual bool storeValueCustom(); + + /// Restore value from attribute data to the widget's control + virtual bool restoreValueCustom(); + +private slots: + void onNbCompChanged(int theVal); + + void onAddStep(); + + void onRemoveStep(); + + void onStepMove(int theStep); + +private: + void clearData(); + + /// Types of shapes selection + QComboBox* myShapeTypeCombo; + + /// Types of field data + QComboBox* myFieldTypeCombo; + + /// Number of components + QSpinBox* myNbComponentsSpn; + + /// Label of current step + QLabel* myCurStepLbl; + + /// Slider for steps management + QSlider* myStepSlider; + + /// Stamp value + QSpinBox* myStampSpn; + + QTableWidget* myDataTbl; + + QLabel* myMaxLbl; +}; + +#endif \ No newline at end of file diff --git a/src/CollectionPlugin/icons/field.png b/src/CollectionPlugin/icons/field.png new file mode 100644 index 0000000000000000000000000000000000000000..e9ed8243e254165aa7511eae67937e4d62a61c38 GIT binary patch literal 1086 zcmV-E1i|}>P)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2i*z- z4+a=?8*1|a00X{BL_t(I%Z-%JYh6VY$3ORG@|yROkmS7-6Z_+($m)tldseKT@Lrjvqfh9mnyI_kOA z&f$GAp66~V%d!oZyQ&eh7g!%19i7hee9}2rZM9l=VgRMoLLA3WYpo9@Niy2+_lLDM z2aGWXoO46nZg;Go>SmgzbG=?~^3sh{#udeW0O#COzjj{fIOm#0Q4lRGEF7Mmp5DJ_ z&z^moo10fd2)9Henwom7D`LsAj4aC#vBWWmSgJ!qeDU2;qG%9^I5>RnSwMhO(XnI4 z9#=|D4Gavpix)5c2ypV`$#9`w2V+14$vweZutMkCMgDIzM^;{pFJHcVH%XFp5m^T~ zapFX{Fg^}iZvl;ADBYx*Y*5|Y;N7=lo@ji2CWfE{W`+L82Up?C#S$XGndiwp=#An>>y+(6n1ALL?pJ>BE}$MFvcR*V69+8kP@6_9^jCOFkA(fLkI!jPapwMV`F1WMNvFyMbJ9N zh+xGcCCKcYFl;w>;y5NrJi5PQbOA)|c6&+r!sDF7h+uS#SW|)wA{Mb0YoHLe^#Wk? zK4|mkTU1G!Tpt@4YlsNifHD7RCXyin!2lM#_W=KR@9A`)C?1B*&dy#}0N#6_rYSY; z5i5wXh~!u)z0(kS4>$Mwu)NG4z{gt^TQ^XHgM&+Xmdy}F7-KNTAl8%jOITKx>xY5M z%K&@?bb$MSU0YjQQbkeVoQp#UXq{tiAU7pI0JjB=;z#5>*Z$}0VBXKz*S&letteE5uyCo4g=2thjsy#GOhwY0qKs*-h1Ze=I#|m zLA%|48R!BZmiup%@sn-o%18WFnNI-e{QP_fA>h5|U%L!u$OqIRC;$Ke07*qoM6N<$ Eg1wII0{{R3 literal 0 HcmV?d00001 diff --git a/src/CollectionPlugin/plugin-Collection.xml b/src/CollectionPlugin/plugin-Collection.xml index 09bc12beb..33042ac49 100644 --- a/src/CollectionPlugin/plugin-Collection.xml +++ b/src/CollectionPlugin/plugin-Collection.xml @@ -9,6 +9,13 @@ icon="icons/Collection/shape_group.png"> + + + + -- 2.39.2