1 // Copyright (C) 2019-2020 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include <PartSet_BSplineWidget.h>
22 #include <SketchPlugin_BSpline.h>
24 #include <ModuleBase_Tools.h>
26 #include <ModelAPI_AttributeDoubleArray.h>
28 #include <GeomDataAPI_Point2DArray.h>
30 #include <GeomAPI_Pnt2d.h>
32 #include <QFormLayout>
35 #include <QVBoxLayout>
36 #include <QScrollArea>
39 PartSet_BSplineWidget::PartSet_BSplineWidget(
41 const Config_WidgetAPI* theData)
42 : ModuleBase_ModelWidget(theParent, theData)
44 QVBoxLayout* aMainLayout = new QVBoxLayout(this);
45 aMainLayout->setContentsMargins(0, 0, 0, 0);
47 // GroupBox to keep widgets for B-spline poles and weights
48 myPolesGroupBox = new QGroupBox(tr("Poles and weights"), this);
49 aMainLayout->addWidget(myPolesGroupBox);
51 QVBoxLayout* aLayout = new QVBoxLayout(myPolesGroupBox);
52 ModuleBase_Tools::adjustMargins(aLayout);
54 myScrollArea = new QScrollArea(myPolesGroupBox);
55 myScrollArea->setWidgetResizable(true);
56 myScrollArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
57 myScrollArea->setFrameStyle(QFrame::NoFrame);
58 aLayout->addWidget(myScrollArea);
60 QWidget* aContainer = new QWidget(myScrollArea);
61 QVBoxLayout* aBoxLay = new QVBoxLayout(aContainer);
62 aBoxLay->setContentsMargins(0, 0, 0, 0);
65 myPolesWgt = new QWidget(aContainer);
66 QGridLayout* aGroupLayout = new QGridLayout(myPolesWgt);
67 aGroupLayout->setSpacing(4);
68 aGroupLayout->setColumnStretch(1, 1);
69 ModuleBase_Tools::adjustMargins(aGroupLayout);
72 aBoxLay->addWidget(myPolesWgt);
73 aBoxLay->addStretch(1);
74 myScrollArea->setWidget(aContainer);
77 void PartSet_BSplineWidget::setFeature(const FeaturePtr& theFeature,
78 const bool theToStoreValue,
79 const bool isUpdateFlushed)
81 ModuleBase_ModelWidget::setFeature(theFeature, theToStoreValue, isUpdateFlushed);
85 void PartSet_BSplineWidget::deactivate()
87 ModuleBase_ModelWidget::deactivate();
92 QList<QWidget*> PartSet_BSplineWidget::getControls() const
94 QList<QWidget*> aControls;
95 aControls.append(myScrollArea);
99 void PartSet_BSplineWidget::storePolesAndWeights() const
101 std::shared_ptr<ModelAPI_Data> aData = myFeature->data();
102 AttributeDoubleArrayPtr aWeightsArray = aData->realArray(SketchPlugin_BSpline::WEIGHTS_ID());
104 std::list<BSplinePoleWidgets>::const_iterator anIt = myPoles.begin();
105 for (int anIndex = 0; anIt != myPoles.end(); ++anIndex, ++anIt) {
106 aWeightsArray->setValue(anIndex, anIt->myWeight->value());
110 bool PartSet_BSplineWidget::storeValueCustom()
112 std::shared_ptr<ModelAPI_Data> aData = myFeature->data();
113 if (!aData || !aData->isValid()) // can be on abort of sketcher element
116 AttributeDoubleArrayPtr aWeights = aData->realArray(SketchPlugin_BSpline::WEIGHTS_ID());
118 bool isBlocked = blockSignals(true);
119 storePolesAndWeights();
120 ModuleBase_Tools::flushUpdated(myFeature);
121 blockSignals(isBlocked);
123 updateObject(myFeature);
127 bool PartSet_BSplineWidget::restoreValueCustom()
132 DataPtr aData = myFeature->data();
134 AttributePoint2DArrayPtr aPoles = std::dynamic_pointer_cast<GeomDataAPI_Point2DArray>(
135 aData->attribute(SketchPlugin_BSpline::POLES_ID()));
136 AttributeDoubleArrayPtr aWeights = aData->realArray(SketchPlugin_BSpline::WEIGHTS_ID());
138 while (myPoles.size() < aPoles->size())
141 std::list<BSplinePoleWidgets>::iterator anIt = myPoles.begin();
142 for (int anIndex = 0; anIt != myPoles.end(); ++anIt, ++anIndex) {
143 GeomPnt2dPtr aPoint = aPoles->pnt(anIndex);
144 anIt->myX->setValue(aPoint->x());
145 anIt->myY->setValue(aPoint->y());
146 bool isBlocked = anIt->myWeight->blockSignals(true);
147 anIt->myWeight->setValue(aWeights->value(anIndex));
148 anIt->myWeight->blockSignals(isBlocked);
154 void PartSet_BSplineWidget::addPoleWidget()
156 QGridLayout* aGroupLay = dynamic_cast<QGridLayout*>(myPolesWgt->layout());
157 ModuleBase_Tools::adjustMargins(aGroupLay);
159 int aNbPoles = (int)myPoles.size();
161 QString aPoleStr = tr("Pole %1");
162 aPoleStr = aPoleStr.arg(aNbPoles + 1);
164 QGroupBox* aPoleGroupBox = new QGroupBox(aPoleStr, myPolesWgt);
165 QFormLayout* aPoleLay = new QFormLayout(aPoleGroupBox);
166 ModuleBase_Tools::adjustMargins(aPoleLay);
167 aPoleLay->setSpacing(2);
169 myPoles.push_back(BSplinePoleWidgets());
170 BSplinePoleWidgets& aPoleWidgets = myPoles.back();
172 aPoleWidgets.myX = new ModuleBase_LabelValue(aPoleGroupBox, tr("X"));
173 aPoleLay->addRow(aPoleWidgets.myX);
174 aPoleWidgets.myY = new ModuleBase_LabelValue(aPoleGroupBox, tr("Y"));
175 aPoleLay->addRow(aPoleWidgets.myY);
176 aPoleWidgets.myWeight = new ModuleBase_ParamSpinBox(aPoleGroupBox);
177 aPoleWidgets.myWeight->setMinimum(0.0);
178 aPoleLay->addRow(tr("Weight") + " : ", aPoleWidgets.myWeight);
180 aGroupLay->addWidget(aPoleGroupBox, aNbPoles, 1);
182 // we should listen textChanged signal as valueChanged do not send when text is modified
183 connect(aPoleWidgets.myWeight, SIGNAL(textChanged(const QString&)),
184 this, SIGNAL(valuesChanged()));