| |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| #include <QAction> |
| #include <QMenu> |
| #include <QMessageBox> |
| #include <QTimer> |
|
|
| #include <App/Document.h> |
| #include <Base/Tools.h> |
| #include <Gui/Application.h> |
| #include <Gui/BitmapFactory.h> |
| #include <Gui/CommandT.h> |
| #include <Gui/Control.h> |
| #include <Gui/Selection/SelectionObject.h> |
| #include <Gui/Tools.h> |
| #include <Gui/Widgets.h> |
| #include <Mod/Part/Gui/ViewProvider.h> |
| #include <Mod/Surface/App/Blending/FeatureBlendCurve.h> |
|
|
| #include "TaskBlendCurve.h" |
| #include "ui_TaskBlendCurve.h" |
| #include "ViewProviderBlendCurve.h" |
|
|
|
|
| using namespace SurfaceGui; |
|
|
| class BlendCurvePanel::EdgeSelection: public Gui::SelectionFilterGate |
| { |
| public: |
| explicit EdgeSelection(Surface::FeatureBlendCurve* editedObject) |
| : Gui::SelectionFilterGate(nullPointer()) |
| , editedObject(editedObject) |
| {} |
| ~EdgeSelection() override = default; |
|
|
| EdgeSelection(const EdgeSelection&) = delete; |
| EdgeSelection& operator=(const EdgeSelection&) = delete; |
| EdgeSelection(EdgeSelection&&) = delete; |
| EdgeSelection& operator=(EdgeSelection&&) = delete; |
| |
| |
| |
| bool allow(App::Document* doc, App::DocumentObject* pObj, const char* sSubName) override |
| { |
| (void)doc; |
|
|
| |
| if (pObj == editedObject) { |
| return false; |
| } |
| if (!pObj->isDerivedFrom<Part::Feature>()) { |
| return false; |
| } |
|
|
| if (Base::Tools::isNullOrEmpty(sSubName)) { |
| return false; |
| } |
|
|
| std::string element(sSubName); |
| return (element.substr(0, 4) == "Edge"); |
| } |
|
|
| private: |
| Surface::FeatureBlendCurve* editedObject; |
| }; |
|
|
| |
|
|
| BlendCurvePanel::BlendCurvePanel(ViewProviderBlendCurve* vp) |
| : ui(new Ui_BlendCurve()) |
| , vp(vp) |
| { |
| ui->setupUi(this); |
|
|
| initControls(); |
| setupConnections(); |
| bindProperties(); |
| } |
|
|
| BlendCurvePanel::~BlendCurvePanel() = default; |
|
|
| void BlendCurvePanel::setupConnections() |
| { |
| |
| connect(ui->buttonFirstEdge, |
| &QToolButton::toggled, |
| this, |
| &BlendCurvePanel::onFirstEdgeButton); |
| connect(ui->buttonSecondEdge, |
| &QToolButton::toggled, |
| this, |
| &BlendCurvePanel::onSecondEdgeButton); |
| connect(ui->contFirstEdge, |
| qOverload<int>(&QComboBox::currentIndexChanged), |
| this, |
| &BlendCurvePanel::onFirstEdgeContChanged); |
| connect(ui->contSecondEdge, |
| qOverload<int>(&QComboBox::currentIndexChanged), |
| this, |
| &BlendCurvePanel::onSecondEdgeContChanged); |
| connect(ui->paramFirstEdge, |
| qOverload<double>(&QDoubleSpinBox::valueChanged), |
| this, |
| &BlendCurvePanel::onFirstEdgeParameterChanged); |
| connect(ui->paramSecondEdge, |
| qOverload<double>(&QDoubleSpinBox::valueChanged), |
| this, |
| &BlendCurvePanel::onSecondEdgeParameterChanged); |
| connect(ui->sizeFirstEdge, |
| qOverload<double>(&QDoubleSpinBox::valueChanged), |
| this, |
| &BlendCurvePanel::onFirstEdgeSizeChanged); |
| connect(ui->sizeSecondEdge, |
| qOverload<double>(&QDoubleSpinBox::valueChanged), |
| this, |
| &BlendCurvePanel::onSecondEdgeSizeChanged); |
| |
| } |
|
|
| void BlendCurvePanel::initControls() |
| { |
| initSubLinks(); |
| initContinuity(); |
| initParameter(); |
| initSize(); |
| } |
|
|
| void BlendCurvePanel::initSubLinks() |
| { |
| auto fea = vp->getObject<Surface::FeatureBlendCurve>(); |
|
|
| ui->firstEdgeEdit->setText(linkToString(fea->StartEdge)); |
| ui->secondEdgeEdit->setText(linkToString(fea->EndEdge)); |
| } |
|
|
| void BlendCurvePanel::initContinuity() |
| { |
| auto fea = vp->getObject<Surface::FeatureBlendCurve>(); |
|
|
| constexpr long maxCont = 4; |
| |
| ui->contFirstEdge->setCurrentIndex(static_cast<int>(std::min(maxCont, fea->StartContinuity.getValue()))); |
| ui->contSecondEdge->setCurrentIndex(static_cast<int>(std::min(maxCont, fea->EndContinuity.getValue()))); |
| |
| } |
|
|
| void BlendCurvePanel::initParameter() |
| { |
| auto fea = vp->getObject<Surface::FeatureBlendCurve>(); |
|
|
| const double minPara = fea->StartParameter.getMinimum(); |
| const double maxPara = fea->StartParameter.getMaximum(); |
| const double stepsPara = fea->StartParameter.getStepSize(); |
| ui->paramFirstEdge->setRange(minPara, maxPara); |
| ui->paramFirstEdge->setSingleStep(stepsPara); |
| ui->paramSecondEdge->setRange(minPara, maxPara); |
| ui->paramSecondEdge->setSingleStep(stepsPara); |
| ui->paramFirstEdge->setValue(fea->StartParameter.getValue()); |
| ui->paramSecondEdge->setValue(fea->EndParameter.getValue()); |
| } |
|
|
| void BlendCurvePanel::initSize() |
| { |
| auto fea = vp->getObject<Surface::FeatureBlendCurve>(); |
|
|
| const double minSize = fea->StartSize.getMinimum(); |
| const double maxSize = fea->StartSize.getMaximum(); |
| const double stepsSize = fea->StartSize.getStepSize(); |
| ui->sizeFirstEdge->setRange(minSize, maxSize); |
| ui->sizeFirstEdge->setSingleStep(stepsSize); |
| ui->sizeSecondEdge->setRange(minSize, maxSize); |
| ui->sizeSecondEdge->setSingleStep(stepsSize); |
| ui->sizeFirstEdge->setValue(fea->StartSize.getValue()); |
| ui->sizeSecondEdge->setValue(fea->EndSize.getValue()); |
| } |
|
|
| void BlendCurvePanel::bindProperties() |
| { |
| auto fea = vp->getObject<Surface::FeatureBlendCurve>(); |
|
|
| ui->paramFirstEdge->bind(fea->StartParameter); |
| ui->sizeFirstEdge->bind(fea->StartSize); |
| ui->paramSecondEdge->bind(fea->EndParameter); |
| ui->sizeSecondEdge->bind(fea->EndSize); |
| } |
|
|
| void BlendCurvePanel::onFirstEdgeButton(bool checked) |
| { |
| if (checked) { |
| onStartSelection(); |
| selectionMode = StartEdge; |
| onUncheckSecondEdgeButton(); |
| } |
| else { |
| exitSelectionMode(); |
| } |
| } |
|
|
| void BlendCurvePanel::onSecondEdgeButton(bool checked) |
| { |
| if (checked) { |
| onStartSelection(); |
| selectionMode = EndEdge; |
| onUncheckFirstEdgeButton(); |
| } |
| else { |
| exitSelectionMode(); |
| } |
| } |
|
|
| void BlendCurvePanel::onUncheckFirstEdgeButton() |
| { |
| QSignalBlocker block(ui->buttonFirstEdge); |
| ui->buttonFirstEdge->setChecked(false); |
| } |
|
|
| void BlendCurvePanel::onUncheckSecondEdgeButton() |
| { |
| QSignalBlocker block(ui->buttonSecondEdge); |
| ui->buttonSecondEdge->setChecked(false); |
| } |
|
|
| void BlendCurvePanel::onFirstEdgeContChanged(int index) |
| { |
| if (vp.expired()) { |
| return; |
| } |
|
|
| auto fea = vp->getObject<Surface::FeatureBlendCurve>(); |
| fea->StartContinuity.setValue(index); |
| fea->recomputeFeature(); |
| } |
|
|
| void BlendCurvePanel::onSecondEdgeContChanged(int index) |
| { |
| if (vp.expired()) { |
| return; |
| } |
|
|
| auto fea = vp->getObject<Surface::FeatureBlendCurve>(); |
| fea->EndContinuity.setValue(index); |
| fea->recomputeFeature(); |
| } |
|
|
| void BlendCurvePanel::onFirstEdgeParameterChanged(double value) |
| { |
| if (vp.expired()) { |
| return; |
| } |
|
|
| auto fea = vp->getObject<Surface::FeatureBlendCurve>(); |
| fea->StartParameter.setValue(value); |
| fea->recomputeFeature(); |
| } |
|
|
| void BlendCurvePanel::onSecondEdgeParameterChanged(double value) |
| { |
| if (vp.expired()) { |
| return; |
| } |
|
|
| auto fea = vp->getObject<Surface::FeatureBlendCurve>(); |
| fea->EndParameter.setValue(value); |
| fea->recomputeFeature(); |
| } |
|
|
| void BlendCurvePanel::onFirstEdgeSizeChanged(double value) |
| { |
| if (vp.expired()) { |
| return; |
| } |
|
|
| auto fea = vp->getObject<Surface::FeatureBlendCurve>(); |
| fea->StartSize.setValue(value); |
| fea->recomputeFeature(); |
| } |
|
|
| void BlendCurvePanel::onSecondEdgeSizeChanged(double value) |
| { |
| if (vp.expired()) { |
| return; |
| } |
|
|
| auto fea = vp->getObject<Surface::FeatureBlendCurve>(); |
| fea->EndSize.setValue(value); |
| fea->recomputeFeature(); |
| } |
|
|
| void BlendCurvePanel::onStartSelection() |
| { |
| if (vp.expired()) { |
| return; |
| } |
|
|
| auto gate = new EdgeSelection(vp->getObject<Surface::FeatureBlendCurve>()); |
| Gui::Selection().addSelectionGate(gate); |
| } |
|
|
| void BlendCurvePanel::exitSelectionMode() |
| { |
| Gui::Selection().clearSelection(); |
| Gui::Selection().rmvSelectionGate(); |
| selectionMode = None; |
| } |
|
|
| void BlendCurvePanel::onSelectionChanged(const Gui::SelectionChanges& msg) |
| { |
| if (selectionMode == None) { |
| return; |
| } |
|
|
| if (msg.Type != Gui::SelectionChanges::AddSelection) { |
| return; |
| } |
|
|
| if (selectionMode == StartEdge) { |
| setStartEdge(msg.Object.getObject(), msg.Object.getSubName()); |
| onUncheckFirstEdgeButton(); |
| } |
| else if (selectionMode == EndEdge) { |
| setEndEdge(msg.Object.getObject(), msg.Object.getSubName()); |
| onUncheckSecondEdgeButton(); |
| } |
|
|
| QTimer::singleShot(50, this, &BlendCurvePanel::exitSelectionMode); |
| } |
|
|
| QString BlendCurvePanel::linkToString(const App::PropertyLinkSub& link) |
| { |
| auto obj = link.getValue(); |
| const auto& sub = link.getSubValues(); |
| std::string name = sub.empty() ? "" : sub.front(); |
|
|
| return QString::fromLatin1("%1 [%2]").arg( |
| QString::fromLatin1(obj->Label.getValue()), |
| QString::fromStdString(name) |
| ); |
| } |
|
|
| void BlendCurvePanel::setStartEdge(App::DocumentObject* obj, const std::string& subname) |
| { |
| if (vp.expired()) { |
| return; |
| } |
|
|
| auto fea = vp->getObject<Surface::FeatureBlendCurve>(); |
| fea->StartEdge.setValue(obj, {{subname}}); |
| fea->recomputeFeature(); |
| ui->firstEdgeEdit->setText(linkToString(fea->StartEdge)); |
| } |
|
|
| void BlendCurvePanel::setEndEdge(App::DocumentObject* obj, const std::string& subname) |
| { |
| if (vp.expired()) { |
| return; |
| } |
|
|
| auto fea = vp->getObject<Surface::FeatureBlendCurve>(); |
| fea->EndEdge.setValue(obj, {{subname}}); |
| fea->recomputeFeature(); |
| ui->secondEdgeEdit->setText(linkToString(fea->EndEdge)); |
| } |
|
|
| void BlendCurvePanel::changeEvent(QEvent* e) |
| { |
| if (e->type() == QEvent::LanguageChange) { |
| ui->retranslateUi(this); |
| } |
| else { |
| QWidget::changeEvent(e); |
| } |
| } |
|
|
| void BlendCurvePanel::open() |
| { |
| checkOpenCommand(); |
| clearSelection(); |
| } |
|
|
| void BlendCurvePanel::clearSelection() |
| { |
| Gui::Selection().clearSelection(); |
| } |
|
|
| void BlendCurvePanel::checkOpenCommand() |
| { |
| if (!Gui::Command::hasPendingCommand()) { |
| Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Edit blending curve")); |
| } |
| } |
|
|
| bool BlendCurvePanel::accept() |
| { |
| Gui::cmdGuiDocument(vp->getObject(), "resetEdit()"); |
| Gui::Command::commitCommand(); |
| Gui::Command::updateActive(); |
| return true; |
| } |
|
|
| bool BlendCurvePanel::reject() |
| { |
| Gui::Command::abortCommand(); |
| Gui::cmdGuiDocument(vp->getObject(), "resetEdit()"); |
| Gui::Command::updateActive(); |
| return true; |
| } |
|
|
| |
|
|
| TaskBlendCurve::TaskBlendCurve(ViewProviderBlendCurve* vp) |
| : widget {new BlendCurvePanel(vp)} |
| { |
| addTaskBox(Gui::BitmapFactory().pixmap("Surface_BlendCurve"), widget); |
| } |
|
|
| void TaskBlendCurve::open() |
| { |
| widget->open(); |
| } |
|
|
| bool TaskBlendCurve::accept() |
| { |
| return widget->accept(); |
| } |
|
|
| bool TaskBlendCurve::reject() |
| { |
| return widget->reject(); |
| } |
|
|