Salome HOME
Issue #1865: Model Widget for fields
authorvsv <vitaly.smetannikov@opencascade.com>
Wed, 16 Nov 2016 15:59:46 +0000 (18:59 +0300)
committervsv <vitaly.smetannikov@opencascade.com>
Wed, 16 Nov 2016 16:00:00 +0000 (19:00 +0300)
src/CollectionPlugin/CMakeLists.txt
src/CollectionPlugin/CollectionPlugin_Plugin.cpp
src/CollectionPlugin/CollectionPlugin_WidgetCreator.cpp [new file with mode: 0644]
src/CollectionPlugin/CollectionPlugin_WidgetCreator.h [new file with mode: 0644]
src/CollectionPlugin/CollectionPlugin_WidgetField.cpp [new file with mode: 0644]
src/CollectionPlugin/CollectionPlugin_WidgetField.h [new file with mode: 0644]
src/CollectionPlugin/icons/field.png [new file with mode: 0644]
src/CollectionPlugin/plugin-Collection.xml

index 081f5bc5eacb53ca8fd3f3f255a9985843f026d3..69df0403470b4d94093f2c06f51673885b683a52 100644 (file)
@@ -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)
index 6732c4c73ea00e8e76f1616ceb26c510e80306f8..6f0ca30e7b8d7c9b237637c39ec589845918b227 100644 (file)
@@ -6,6 +6,10 @@
 #include <CollectionPlugin_Field.h>
 #include <ModelAPI_Session.h>
 
+#include <ModuleBase_WidgetCreatorFactory.h>
+
+#include "CollectionPlugin_WidgetCreator.h"
+
 #include <string>
 #include <memory>
 
@@ -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<CollectionPlugin_WidgetCreator>(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 (file)
index 0000000..a075622
--- /dev/null
@@ -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<std::string>& 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 (file)
index 0000000..ce806ca
--- /dev/null
@@ -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 <ModuleBase_IWidgetCreator.h>
+
+#include <string>
+#include <set>
+
+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<std::string>& 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<std::string> 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 (file)
index 0000000..d050035
--- /dev/null
@@ -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 <QLayout>
+#include <QWidget>
+#include <QFormLayout>
+#include <QComboBox>
+#include <QSpinBox>
+#include <QLabel>
+#include <QSlider>
+#include <QTableWidget>
+#include <QPushButton>
+#include <QHeaderView>
+
+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<QWidget*> CollectionPlugin_WidgetField::getControls() const
+{
+  QList<QWidget*> 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<ModelAPI_AttributeInteger>(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<ModelAPI_AttributeInteger>(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 (file)
index 0000000..0098157
--- /dev/null
@@ -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 <ModuleBase_ModelWidget.h>
+
+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<QWidget*> 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 (file)
index 0000000..e9ed824
Binary files /dev/null and b/src/CollectionPlugin/icons/field.png differ
index 09bc12bebecfb7771dbd589e913e44d240f54075..33042ac490d29ec6b9657d5f470ff129da9adb80 100644 (file)
@@ -9,6 +9,13 @@
         icon="icons/Collection/shape_group.png">
         <source path="group_widget.xml"/>
       </feature>
+      
+      <feature id="Field"
+        title="Field"
+        tooltip="Create create fields for selected shapes"
+        icon="icons/Collection/field.png">
+        <field-panel/>
+      </feature>      
     </group>
   </workbench>
 </plugin>