diff --git a/src/Mod/Sketcher/Gui/DrawSketchHandlerPoint.h b/src/Mod/Sketcher/Gui/DrawSketchHandlerPoint.h index e061216b40..33aa5d304a 100644 --- a/src/Mod/Sketcher/Gui/DrawSketchHandlerPoint.h +++ b/src/Mod/Sketcher/Gui/DrawSketchHandlerPoint.h @@ -27,102 +27,238 @@ #include "GeometryCreationMode.h" +#include "DrawSketchDefaultWidgetController.h" +#include "DrawSketchControllableHandler.h" namespace SketcherGui { extern GeometryCreationMode geometryCreationMode; // defined in CommandCreateGeo.cpp -class DrawSketchHandlerPoint: public DrawSketchHandler +class DrawSketchHandlerPoint; + +using DSHPointController = DrawSketchController>; + +using DrawSketchHandlerPointBase = DrawSketchControllableHandler; + +class DrawSketchHandlerPoint: public DrawSketchHandlerPointBase { + // Allow specialisations of controllers access to private members + friend DSHPointController; + public: - DrawSketchHandlerPoint() - : selectionDone(false) - {} - ~DrawSketchHandlerPoint() override - {} - - void mouseMove(Base::Vector2d onSketchPos) override - { - setPositionText(onSketchPos); - if (seekAutoConstraint(sugConstr, onSketchPos, Base::Vector2d(0.f, 0.f))) { - renderSuggestConstraintsCursor(sugConstr); - return; - } - applyCursor(); - } - - bool pressButton(Base::Vector2d onSketchPos) override - { - EditPoint = onSketchPos; - selectionDone = true; - return true; - } - - bool releaseButton(Base::Vector2d onSketchPos) override - { - Q_UNUSED(onSketchPos); - if (selectionDone) { - unsetCursor(); - resetPositionText(); - - try { - Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Add sketch point")); - Gui::cmdAppObjectArgs(sketchgui->getObject(), - "addGeometry(Part.Point(App.Vector(%f,%f,0)))", - EditPoint.x, - EditPoint.y); - - Gui::Command::commitCommand(); - } - catch (const Base::Exception&) { - Gui::NotifyError(sketchgui, - QT_TRANSLATE_NOOP("Notifications", "Error"), - QT_TRANSLATE_NOOP("Notifications", "Failed to add point")); - - Gui::Command::abortCommand(); - } - - // add auto constraints for the line segment start - if (!sugConstr.empty()) { - createAutoConstraints(sugConstr, getHighestCurveIndex(), Sketcher::PointPos::start); - sugConstr.clear(); - } - - tryAutoRecomputeIfNotSolve( - static_cast(sketchgui->getObject())); - - ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath( - "User parameter:BaseApp/Preferences/Mod/Sketcher"); - bool continuousMode = hGrp->GetBool("ContinuousCreationMode", true); - if (continuousMode) { - // This code enables the continuous creation mode. - applyCursor(); - /* It is ok not to call to purgeHandler - * in continuous creation mode because the - * handler is destroyed by the quit() method on pressing the - * right button of the mouse */ - } - else { - sketchgui->purgeHandler(); // no code after this line, Handler get deleted in - // ViewProvider - } - } - return true; - } + DrawSketchHandlerPoint() = default; + ~DrawSketchHandlerPoint() override = default; private: + void updateDataAndDrawToPosition(Base::Vector2d onSketchPos) override + { + switch (state()) { + case SelectMode::SeekFirst: { + drawPositionAtCursor(onSketchPos); + + editPoint = onSketchPos; + + if (seekAutoConstraint(sugConstraints[0], onSketchPos, Base::Vector2d(0.f, 0.f))) { + renderSuggestConstraintsCursor(sugConstraints[0]); + return; + } + } break; + default: + break; + } + } + + void executeCommands() override + { + try { + Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Add sketch point")); + Gui::cmdAppObjectArgs(sketchgui->getObject(), + "addGeometry(Part.Point(App.Vector(%f,%f,0)))", + editPoint.x, + editPoint.y); + + Gui::Command::commitCommand(); + } + catch (const Base::Exception&) { + Gui::NotifyError(sketchgui, + QT_TRANSLATE_NOOP("Notifications", "Error"), + QT_TRANSLATE_NOOP("Notifications", "Failed to add point")); + + Gui::Command::abortCommand(); + } + } + + void createAutoConstraints() override + { + + if (!sugConstraints[0].empty()) { + DrawSketchHandler::createAutoConstraints(sugConstraints[0], + getHighestCurveIndex(), + Sketcher::PointPos::start); + sugConstraints[0].clear(); + } + } + + std::string getToolName() const override + { + return "DSH_Point"; + } + QString getCrosshairCursorSVGName() const override { return QString::fromLatin1("Sketcher_Pointer_Create_Point"); } -protected: - bool selectionDone; - Base::Vector2d EditPoint; - std::vector sugConstr; + std::unique_ptr createWidget() const override + { + return std::make_unique(); + } + +private: + Base::Vector2d editPoint; }; +template<> +auto DSHPointController::getState(int labelindex) const +{ + switch (labelindex) { + case OnViewParameter::First: + case OnViewParameter::Second: + return SelectMode::SeekFirst; + break; + default: + THROWM(Base::ValueError, "Parameter index without an associated machine state") + } +} + +template<> +void DSHPointController::configureOnViewParameters() +{ + onViewParameters[OnViewParameter::First]->setLabelType(Gui::SoDatumLabel::DISTANCEX); + onViewParameters[OnViewParameter::Second]->setLabelType(Gui::SoDatumLabel::DISTANCEY); +} + +template<> +void DSHPointController::adaptDrawingToOnViewParameterChange(int labelindex, double value) +{ + switch (labelindex) { + case OnViewParameter::First: + handler->editPoint.x = value; + break; + case OnViewParameter::Second: + handler->editPoint.y = value; + break; + } + onViewParameters[OnViewParameter::First]->setPoints( + Base::Vector3d(0., 0., 0.), + Base::Vector3d(handler->editPoint.x, handler->editPoint.y, 0.)); + onViewParameters[OnViewParameter::Second]->setPoints( + Base::Vector3d(0., 0., 0.), + Base::Vector3d(handler->editPoint.x, handler->editPoint.y, 0.)); +} + +template<> +void DSHPointController::doEnforceControlParameters(Base::Vector2d& onSketchPos) +{ + switch (handler->state()) { + case SelectMode::SeekFirst: { + if (onViewParameters[OnViewParameter::First]->isSet) { + onSketchPos.x = onViewParameters[OnViewParameter::First]->getValue(); + } + + if (onViewParameters[OnViewParameter::Second]->isSet) { + onSketchPos.y = onViewParameters[OnViewParameter::Second]->getValue(); + } + } break; + default: + break; + } +} + +template<> +void DSHPointController::adaptParameters(Base::Vector2d onSketchPos) +{ + switch (handler->state()) { + case SelectMode::SeekFirst: { + if (!onViewParameters[OnViewParameter::First]->isSet) { + onViewParameters[OnViewParameter::First]->setSpinboxValue(onSketchPos.x); + } + + if (!onViewParameters[OnViewParameter::Second]->isSet) { + onViewParameters[OnViewParameter::Second]->setSpinboxValue(onSketchPos.y); + } + + bool sameSign = onSketchPos.x * onSketchPos.y > 0.; + onViewParameters[OnViewParameter::First]->setLabelAutoDistanceReverse(!sameSign); + onViewParameters[OnViewParameter::Second]->setLabelAutoDistanceReverse(sameSign); + onViewParameters[OnViewParameter::First]->setPoints( + Base::Vector3d(0., 0., 0.), + Base::Vector3d(onSketchPos.x, onSketchPos.y, 0.)); + onViewParameters[OnViewParameter::Second]->setPoints( + Base::Vector3d(0., 0., 0.), + Base::Vector3d(onSketchPos.x, onSketchPos.y, 0.)); + } break; + default: + break; + } +} + +template<> +void DSHPointController::doChangeDrawSketchHandlerMode() +{ + switch (handler->state()) { + case SelectMode::SeekFirst: { + if (onViewParameters[OnViewParameter::First]->isSet + && onViewParameters[OnViewParameter::Second]->isSet) { + + handler->setState(SelectMode::End); + // handler->finish(); // Called by the change of mode + } + } break; + default: + break; + } +} + +template<> +void DSHPointController::addConstraints() +{ + int firstCurve = handler->getHighestCurveIndex(); + + auto x0 = onViewParameters[OnViewParameter::First]->getValue(); + auto y0 = onViewParameters[OnViewParameter::Second]->getValue(); + + auto x0set = onViewParameters[OnViewParameter::First]->isSet; + auto y0set = onViewParameters[OnViewParameter::Second]->isSet; + + using namespace Sketcher; + + if (x0set && y0set && x0 == 0. && y0 == 0.) { + ConstraintToAttachment(GeoElementId(firstCurve, PointPos::start), + GeoElementId::RtPnt, + x0, + handler->sketchgui->getObject()); + } + else { + if (x0set) { + ConstraintToAttachment(GeoElementId(firstCurve, PointPos::start), + GeoElementId::VAxis, + x0, + handler->sketchgui->getObject()); + } + + if (y0set) { + ConstraintToAttachment(GeoElementId(firstCurve, PointPos::start), + GeoElementId::HAxis, + y0, + handler->sketchgui->getObject()); + } + } +} } // namespace SketcherGui