From cbcbb9de51b6e832d966b25d1981d58c8e82813a Mon Sep 17 00:00:00 2001 From: Abdullah Tahiri Date: Sun, 20 Jun 2021 07:07:22 +0200 Subject: [PATCH] Sketcher: Reorder rounded rectangle code next to normal rectangle code --- src/Mod/Sketcher/Gui/CommandCreateGeo.cpp | 849 +++++++++++----------- 1 file changed, 423 insertions(+), 426 deletions(-) diff --git a/src/Mod/Sketcher/Gui/CommandCreateGeo.cpp b/src/Mod/Sketcher/Gui/CommandCreateGeo.cpp index d856b888b8..d1b89441a2 100644 --- a/src/Mod/Sketcher/Gui/CommandCreateGeo.cpp +++ b/src/Mod/Sketcher/Gui/CommandCreateGeo.cpp @@ -615,6 +615,429 @@ bool CmdSketcherCreateRectangle::isActive(void) return isCreateGeoActive(getActiveGuiDocument()); } +/* Create rounded oblong =======================================================*/ + +class DrawSketchHandlerOblong : public DrawSketchHandler +{ +public: + DrawSketchHandlerOblong() + : Mode(STATUS_SEEK_First) + , lengthX(0), lengthY(0), radius(0), signX(1), signY(1) + , EditCurve(37) + { + } + virtual ~DrawSketchHandlerOblong() {} + /// mode table + enum BoxMode { + STATUS_SEEK_First, /**< enum value ----. */ + STATUS_SEEK_Second, /**< enum value ----. */ + STATUS_End + }; + + virtual void activated(ViewProviderSketch*) + { + setCrosshairCursor("Sketcher_Pointer_Oblong"); + } + + virtual void mouseMove(Base::Vector2d onSketchPos) + { + + if (Mode == STATUS_SEEK_First) { + setPositionText(onSketchPos); + if (seekAutoConstraint(sugConstr1, onSketchPos, Base::Vector2d(0.f, 0.f))) { + renderSuggestConstraintsCursor(sugConstr1); + return; + } + } + else if (Mode == STATUS_SEEK_Second) { + float distanceX = onSketchPos.x - StartPos.x; + float distanceY = onSketchPos.y - StartPos.y; + + lengthX = distanceX; lengthY = distanceY; + signX = Base::sgn(distanceX); + signY = Base::sgn(distanceY); + if (fabs(distanceX) > fabs(distanceY)) { + radius = fabs(distanceY) / 4; // we use a fourth of the smaller distance as default radius + } + else { + radius = fabs(distanceX) / 4; + } + + // we draw the lines with 36 segments, 8 for each arc and 4 lines + // draw the arcs + for (int i = 0; i < 8; i++) { + // calculate the x,y positions forming the the arc + double angle = i * M_PI / 16.0; + double x_i = -radius * sin(angle); + double y_i = -radius * cos(angle); + // we are drawing clockwise starting with the arc that is besides StartPos + if (signX == signY) { + EditCurve[i] = Base::Vector2d(StartPos.x + signX * (radius + x_i), StartPos.y + signY * (radius + y_i)); + EditCurve[9 + i] = Base::Vector2d(StartPos.x + signY * (radius + y_i), StartPos.y + lengthY - signX * (radius + x_i)); + EditCurve[18 + i] = Base::Vector2d(StartPos.x + lengthX - signX * (radius + x_i), StartPos.y + lengthY - signY * (radius + y_i)); + EditCurve[27 + i] = Base::Vector2d(StartPos.x + lengthX - signY * (radius + y_i), StartPos.y + signX * (radius + x_i)); + } + else { + EditCurve[i] = Base::Vector2d(StartPos.x - signY * (radius + y_i), StartPos.y - signX * (radius + x_i)); + EditCurve[9 + i] = Base::Vector2d(StartPos.x + lengthX - signX * (radius + x_i), StartPos.y + signY * (radius + y_i)); + EditCurve[18 + i] = Base::Vector2d(StartPos.x + lengthX + signY * (radius + y_i), StartPos.y + lengthY + signX * (radius + x_i)); + EditCurve[27 + i] = Base::Vector2d(StartPos.x + signX * (radius + x_i), StartPos.y + lengthY - signY * (radius + y_i)); + } + } + // draw the lines + if (signX == signY) { + EditCurve[8] = Base::Vector2d(StartPos.x, StartPos.y + (signY * radius)); + EditCurve[17] = Base::Vector2d(StartPos.x + (signX * radius), StartPos.y + lengthY); + EditCurve[26] = Base::Vector2d(StartPos.x + lengthX, StartPos.y + lengthY - (signY * radius)); + EditCurve[35] = Base::Vector2d(StartPos.x + lengthX - (signX * radius), StartPos.y); + } + else { + EditCurve[8] = Base::Vector2d(StartPos.x + (signX * radius), StartPos.y); + EditCurve[17] = Base::Vector2d(StartPos.x + lengthX, StartPos.y + (signY * radius)); + EditCurve[26] = Base::Vector2d(StartPos.x + lengthX - (signX * radius), StartPos.y + lengthY); + EditCurve[35] = Base::Vector2d(StartPos.x, StartPos.y + lengthY - (signY * radius)); + } + // close the curve + EditCurve[36] = EditCurve[0]; + + SbString text; + text.sprintf(" (%.1fR %.1fX %.1fY)", radius, lengthX, lengthY); + setPositionText(onSketchPos, text); + + sketchgui->drawEdit(EditCurve); + if (seekAutoConstraint(sugConstr2, onSketchPos, Base::Vector2d(0.f, 0.f))) { + renderSuggestConstraintsCursor(sugConstr2); + return; + } + } + applyCursor(); + } + + virtual bool pressButton(Base::Vector2d onSketchPos) + { + if (Mode == STATUS_SEEK_First) { + StartPos = onSketchPos; + Mode = STATUS_SEEK_Second; + } + else { + EndPos = onSketchPos; + Mode = STATUS_End; + } + return true; + } + + virtual bool releaseButton(Base::Vector2d onSketchPos) + { + Q_UNUSED(onSketchPos); + if (Mode == STATUS_End) { + unsetCursor(); + resetPositionText(); + + int firstCurve = getHighestCurveIndex() + 1; + // add the geometry to the sketch + // first determine the angles for the first arc + double start = 0; + double end = M_PI / 2; + if (signX > 0 && signY > 0) { + start = -2 * end; + end = -1 * end; + } + else if (signX > 0 && signY < 0) { + start = end; + end = 2 * end; + } + else if (signX < 0 && signY > 0) { + start = -1 * end; + end = 0; + } + + try { + Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Add rounded rectangle")); + Gui::Command::doCommand(Gui::Command::Doc, + // syntax for arcs: Part.ArcOfCircle(Part.Circle(center, axis, radius), startangle, endangle) + "geoList = []\n" + "geoList.append(Part.ArcOfCircle(Part.Circle(App.Vector(%f, %f, 0), App.Vector(0, 0, 1), %f), %f, %f))\n" + "geoList.append(Part.LineSegment(App.Vector(%f, %f, 0), App.Vector(%f, %f, 0)))\n" + "geoList.append(Part.ArcOfCircle(Part.Circle(App.Vector(%f, %f, 0), App.Vector(0, 0, 1), %f), %f, %f))\n" + "geoList.append(Part.LineSegment(App.Vector(%f, %f, 0), App.Vector(%f, %f, 0)))\n" + "geoList.append(Part.ArcOfCircle(Part.Circle(App.Vector(%f, %f, 0), App.Vector(0, 0, 1), %f), %f, %f))\n" + "geoList.append(Part.LineSegment(App.Vector(%f, %f, 0), App.Vector(%f, %f, 0)))\n" + "geoList.append(Part.ArcOfCircle(Part.Circle(App.Vector(%f, %f, 0), App.Vector(0, 0, 1), %f), %f, %f))\n" + "geoList.append(Part.LineSegment(App.Vector(%f, %f, 0), App.Vector(%f, %f, 0)))\n" + "%s.addGeometry(geoList, %s)\n" + "conList = []\n" + "conList.append(Sketcher.Constraint('Tangent', %i, 1, %i, 1))\n" + "conList.append(Sketcher.Constraint('Tangent', %i, 2, %i, 2))\n" + "conList.append(Sketcher.Constraint('Tangent', %i, 1, %i, 1))\n" + "conList.append(Sketcher.Constraint('Tangent', %i, 2, %i, 2))\n" + "conList.append(Sketcher.Constraint('Tangent', %i, 1, %i, 1))\n" + "conList.append(Sketcher.Constraint('Tangent', %i, 2, %i, 2))\n" + "conList.append(Sketcher.Constraint('Tangent', %i, 1, %i, 1))\n" + "conList.append(Sketcher.Constraint('Tangent', %i, 2, %i, 2))\n" + "conList.append(Sketcher.Constraint('Horizontal', %i))\n" + "conList.append(Sketcher.Constraint('Horizontal', %i))\n" + "conList.append(Sketcher.Constraint('Vertical', %i))\n" + "conList.append(Sketcher.Constraint('Vertical', %i))\n" + "conList.append(Sketcher.Constraint('Equal', %i, %i))\n" + "conList.append(Sketcher.Constraint('Equal', %i, %i))\n" + "conList.append(Sketcher.Constraint('Equal', %i, %i))\n" + "%s.addConstraint(conList)\n", + StartPos.x + (signX * radius), StartPos.y + (signY * radius), // center of the arc 1 + radius, + start, end, // start and end angle of arc1 + EditCurve[8].x, EditCurve[8].y, EditCurve[9].x, EditCurve[9].y, // line 1 + signX == signY ? StartPos.x + (signX * radius) : StartPos.x + lengthX - (signX * radius), // center of the arc 2 + signX == signY ? StartPos.y + lengthY - (signY * radius) : StartPos.y + (signY * radius), + radius, + // start and end angle of arc 2 + // the logic is that end is start + M_PI / 2 and start is the previous end - M_PI + end - M_PI, + end - 0.5 * M_PI, + EditCurve[17].x, EditCurve[17].y, EditCurve[18].x, EditCurve[18].y, // line 2 + StartPos.x + lengthX - (signX * radius), StartPos.y + lengthY - (signY * radius), // center of the arc 3 + radius, + end - 1.5 * M_PI, + end - M_PI, + EditCurve[26].x, EditCurve[26].y, EditCurve[27].x, EditCurve[27].y, // line 3 + signX == signY ? StartPos.x + lengthX - (signX * radius) : StartPos.x + (signX * radius), // center of the arc 4 + signX == signY ? StartPos.y + (signY * radius) : StartPos.y + lengthY - (signY * radius), + radius, + end - 2 * M_PI, + end - 1.5 * M_PI, + EditCurve[35].x, EditCurve[35].y, EditCurve[36].x, EditCurve[36].y, // line 4 + Gui::Command::getObjectCmd(sketchgui->getObject()).c_str(), // the sketch + geometryCreationMode == Construction ? "True" : "False", // geometry as construction or not + firstCurve, firstCurve + 1, // tangent 1 + firstCurve + 1, firstCurve + 2, // tangent 2 + firstCurve + 2, firstCurve + 3, // tangent 3 + firstCurve + 3, firstCurve + 4, // tangent 4 + firstCurve + 4, firstCurve + 5, // tangent 5 + firstCurve + 5, firstCurve + 6, // tangent 6 + firstCurve + 6, firstCurve + 7, // tangent 7 + firstCurve + 7, firstCurve, // tangent 8 + signX == signY ? firstCurve + 3 : firstCurve + 1, // horizontal constraint + signX == signY ? firstCurve + 7 : firstCurve + 5, // horizontal constraint + signX == signY ? firstCurve + 1 : firstCurve + 3, // vertical constraint + signX == signY ? firstCurve + 5 : firstCurve + 7, // vertical constraint + firstCurve, firstCurve + 2, // equal 1 + firstCurve + 2, firstCurve + 4, // equal 2 + firstCurve + 4, firstCurve + 6, // equal 3 + Gui::Command::getObjectCmd(sketchgui->getObject()).c_str()); // the sketch + + // now add contruction geometry - two points used to take suggested constraints + Gui::Command::doCommand(Gui::Command::Doc, + "geoList = []\n" + "geoList.append(Part.Point(App.Vector(%f, %f, 0)))\n" + "geoList.append(Part.Point(App.Vector(%f, %f, 0)))\n" + "%s.addGeometry(geoList, True)\n" // geometry as construction + "conList = []\n" + "conList.append(Sketcher.Constraint('PointOnObject', %i, 1, %i, ))\n" + "conList.append(Sketcher.Constraint('PointOnObject', %i, 1, %i, ))\n" + "conList.append(Sketcher.Constraint('PointOnObject', %i, 1, %i, ))\n" + "conList.append(Sketcher.Constraint('PointOnObject', %i, 1, %i, ))\n" + "%s.addConstraint(conList)\n", + StartPos.x, StartPos.y, // point at StartPos + EndPos.x, EndPos.y, // point at EndPos + Gui::Command::getObjectCmd(sketchgui->getObject()).c_str(), // the sketch + firstCurve + 8, firstCurve + 1, // point on object constraint + firstCurve + 8, firstCurve + 7, // point on object constraint + firstCurve + 9, firstCurve + 3, // point on object constraint + firstCurve + 9, firstCurve + 5, // point on object constraint + Gui::Command::getObjectCmd(sketchgui->getObject()).c_str()); // the sketch + + Gui::Command::commitCommand(); + + // add auto constraints at the StartPos auxiliar point + if (sugConstr1.size() > 0) { + createAutoConstraints(sugConstr1, getHighestCurveIndex() - 1, Sketcher::start); + sugConstr1.clear(); + } + + // add auto constraints at the EndPos auxiliar point + if (sugConstr2.size() > 0) { + createAutoConstraints(sugConstr2, getHighestCurveIndex(), Sketcher::start); + sugConstr2.clear(); + } + + tryAutoRecomputeIfNotSolve(static_cast(sketchgui->getObject())); + } + catch (const Base::Exception& e) { + Base::Console().Error("Failed to add rounded rectangle: %s\n", e.what()); + Gui::Command::abortCommand(); + + tryAutoRecompute(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. + Mode = STATUS_SEEK_First; + EditCurve.clear(); + sketchgui->drawEdit(EditCurve); + EditCurve.resize(37); + applyCursor(); + /* this 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; + } +protected: + BoxMode Mode; + Base::Vector2d StartPos, EndPos; + double lengthX, lengthY, radius; + float signX, signY; + std::vector EditCurve; + std::vector sugConstr1, sugConstr2; +}; + +DEF_STD_CMD_AU(CmdSketcherCreateOblong) + +CmdSketcherCreateOblong::CmdSketcherCreateOblong() + : Command("Sketcher_CreateOblong") +{ + sAppModule = "Sketcher"; + sGroup = QT_TR_NOOP("Sketcher"); + sMenuText = QT_TR_NOOP("Create rounded rectangle"); + sToolTipText = QT_TR_NOOP("Create a rounded rectangle in the sketch"); + sWhatsThis = "Sketcher_CreateOblong"; + sStatusTip = sToolTipText; + sPixmap = "Sketcher_CreateOblong"; + sAccel = ""; + eType = ForEdit; +} + +void CmdSketcherCreateOblong::activated(int iMsg) +{ + Q_UNUSED(iMsg); + ActivateHandler(getActiveGuiDocument(), new DrawSketchHandlerOblong()); +} + +void CmdSketcherCreateOblong::updateAction(int mode) +{ + switch (mode) { + case Normal: + if (getAction()) + getAction()->setIcon(Gui::BitmapFactory().iconFromTheme("Sketcher_CreateOblong")); + break; + case Construction: + if (getAction()) + getAction()->setIcon(Gui::BitmapFactory().iconFromTheme("Sketcher_CreateOblong_Constr")); + break; + } +} + +bool CmdSketcherCreateOblong::isActive(void) +{ + return isCreateGeoActive(getActiveGuiDocument()); +} + +/* Rectangles Comp command =========================================*/ + +DEF_STD_CMD_ACLU(CmdSketcherCompCreateRectangles) + +CmdSketcherCompCreateRectangles::CmdSketcherCompCreateRectangles() + : Command("Sketcher_CompCreateRectangles") +{ + sAppModule = "Sketcher"; + sGroup = QT_TR_NOOP("Sketcher"); + sMenuText = QT_TR_NOOP("Create rectangles"); + sToolTipText = QT_TR_NOOP("Creates a rectangle in the sketch"); + sWhatsThis = "Sketcher_CompCreateRectangles"; + sStatusTip = sToolTipText; + eType = ForEdit; +} + +void CmdSketcherCompCreateRectangles::activated(int iMsg) +{ + if (iMsg == 0) + ActivateHandler(getActiveGuiDocument(), new DrawSketchHandlerBox()); + else if (iMsg == 1) + ActivateHandler(getActiveGuiDocument(), new DrawSketchHandlerOblong()); + else + return; + + // Since the default icon is reset when enabling/disabling the command we have + // to explicitly set the icon of the used command. + Gui::ActionGroup* pcAction = qobject_cast(_pcAction); + QList a = pcAction->actions(); + + assert(iMsg < a.size()); + pcAction->setIcon(a[iMsg]->icon()); +} + +Gui::Action* CmdSketcherCompCreateRectangles::createAction(void) +{ + Gui::ActionGroup* pcAction = new Gui::ActionGroup(this, Gui::getMainWindow()); + pcAction->setDropDownMenu(true); + applyCommandData(this->className(), pcAction); + + QAction* arc1 = pcAction->addAction(QString()); + arc1->setIcon(Gui::BitmapFactory().iconFromTheme("Sketcher_CreateRectangle")); + QAction* arc2 = pcAction->addAction(QString()); + arc2->setIcon(Gui::BitmapFactory().iconFromTheme("Sketcher_CreateOblong")); + + _pcAction = pcAction; + languageChange(); + + pcAction->setIcon(arc1->icon()); + int defaultId = 0; + pcAction->setProperty("defaultAction", QVariant(defaultId)); + + return pcAction; +} + +void CmdSketcherCompCreateRectangles::updateAction(int mode) +{ + Gui::ActionGroup* pcAction = qobject_cast(getAction()); + if (!pcAction) + return; + + QList a = pcAction->actions(); + int index = pcAction->property("defaultAction").toInt(); + switch (mode) { + case Normal: + a[0]->setIcon(Gui::BitmapFactory().iconFromTheme("Sketcher_CreateRectangle")); + a[1]->setIcon(Gui::BitmapFactory().iconFromTheme("Sketcher_CreateOblong")); + getAction()->setIcon(a[index]->icon()); + break; + case Construction: + a[0]->setIcon(Gui::BitmapFactory().iconFromTheme("Sketcher_CreateRectangle_Constr")); + a[1]->setIcon(Gui::BitmapFactory().iconFromTheme("Sketcher_CreateOblong_Constr")); + getAction()->setIcon(a[index]->icon()); + break; + } +} + +void CmdSketcherCompCreateRectangles::languageChange() +{ + Command::languageChange(); + + if (!_pcAction) + return; + Gui::ActionGroup* pcAction = qobject_cast(_pcAction); + QList a = pcAction->actions(); + + QAction* rectangle1 = a[0]; + rectangle1->setText(QApplication::translate("CmdSketcherCompCreateRectangles", "Rectangle")); + rectangle1->setToolTip(QApplication::translate("Sketcher_CreateRectangle", "Create a rectangle")); + rectangle1->setStatusTip(rectangle1->toolTip()); + QAction* rectangle2 = a[1]; + rectangle2->setText(QApplication::translate("CmdSketcherCompCreateRectangles", "Rounded rectangle")); + rectangle2->setToolTip(QApplication::translate("Sketcher_CreateOblong", "Create a rounded rectangle")); + rectangle2->setStatusTip(rectangle2->toolTip()); +} + +bool CmdSketcherCompCreateRectangles::isActive(void) +{ + return isCreateGeoActive(getActiveGuiDocument()); +} // ====================================================================================== @@ -6637,432 +7060,6 @@ bool CmdSketcherCreateSlot::isActive(void) return isCreateGeoActive(getActiveGuiDocument()); } - -/** - * Create rounded oblong - */ -class DrawSketchHandlerOblong : public DrawSketchHandler -{ -public: - DrawSketchHandlerOblong() - : Mode(STATUS_SEEK_First) - , lengthX(0), lengthY(0), radius(0), signX(1), signY(1) - , EditCurve(37) - { - } - virtual ~DrawSketchHandlerOblong() {} - /// mode table - enum BoxMode { - STATUS_SEEK_First, /**< enum value ----. */ - STATUS_SEEK_Second, /**< enum value ----. */ - STATUS_End - }; - - virtual void activated(ViewProviderSketch*) - { - setCrosshairCursor("Sketcher_Pointer_Oblong"); - } - - virtual void mouseMove(Base::Vector2d onSketchPos) - { - - if (Mode == STATUS_SEEK_First) { - setPositionText(onSketchPos); - if (seekAutoConstraint(sugConstr1, onSketchPos, Base::Vector2d(0.f, 0.f))) { - renderSuggestConstraintsCursor(sugConstr1); - return; - } - } - else if (Mode == STATUS_SEEK_Second) { - float distanceX = onSketchPos.x - StartPos.x; - float distanceY = onSketchPos.y - StartPos.y; - - lengthX = distanceX; lengthY = distanceY; - signX = Base::sgn(distanceX); - signY = Base::sgn(distanceY); - if (fabs(distanceX) > fabs(distanceY)) { - radius = fabs(distanceY) / 4; // we use a fourth of the smaller distance as default radius - } - else { - radius = fabs(distanceX) / 4; - } - - // we draw the lines with 36 segments, 8 for each arc and 4 lines - // draw the arcs - for (int i = 0; i < 8; i++) { - // calculate the x,y positions forming the the arc - double angle = i * M_PI / 16.0; - double x_i = -radius * sin(angle); - double y_i = -radius * cos(angle); - // we are drawing clockwise starting with the arc that is besides StartPos - if (signX == signY) { - EditCurve[i] = Base::Vector2d(StartPos.x + signX * (radius + x_i), StartPos.y + signY * (radius + y_i)); - EditCurve[9 + i] = Base::Vector2d(StartPos.x + signY * (radius + y_i), StartPos.y + lengthY - signX * (radius + x_i)); - EditCurve[18 + i] = Base::Vector2d(StartPos.x + lengthX - signX * (radius + x_i), StartPos.y + lengthY - signY * (radius + y_i)); - EditCurve[27 + i] = Base::Vector2d(StartPos.x + lengthX - signY * (radius + y_i), StartPos.y + signX * (radius + x_i)); - } - else { - EditCurve[i] = Base::Vector2d(StartPos.x - signY * (radius + y_i), StartPos.y - signX * (radius + x_i)); - EditCurve[9 + i] = Base::Vector2d(StartPos.x + lengthX - signX * (radius + x_i), StartPos.y + signY * (radius + y_i)); - EditCurve[18 + i] = Base::Vector2d(StartPos.x + lengthX + signY * (radius + y_i), StartPos.y + lengthY + signX * (radius + x_i)); - EditCurve[27 + i] = Base::Vector2d(StartPos.x + signX * (radius + x_i), StartPos.y + lengthY - signY * (radius + y_i)); - } - } - // draw the lines - if (signX == signY) { - EditCurve[8] = Base::Vector2d(StartPos.x, StartPos.y + (signY * radius)); - EditCurve[17] = Base::Vector2d(StartPos.x + (signX * radius), StartPos.y + lengthY); - EditCurve[26] = Base::Vector2d(StartPos.x + lengthX, StartPos.y + lengthY - (signY * radius)); - EditCurve[35] = Base::Vector2d(StartPos.x + lengthX - (signX * radius), StartPos.y); - } - else { - EditCurve[8] = Base::Vector2d(StartPos.x + (signX * radius), StartPos.y); - EditCurve[17] = Base::Vector2d(StartPos.x + lengthX, StartPos.y + (signY * radius)); - EditCurve[26] = Base::Vector2d(StartPos.x + lengthX - (signX * radius), StartPos.y + lengthY); - EditCurve[35] = Base::Vector2d(StartPos.x, StartPos.y + lengthY - (signY * radius)); - } - // close the curve - EditCurve[36] = EditCurve[0]; - - SbString text; - text.sprintf(" (%.1fR %.1fX %.1fY)", radius, lengthX, lengthY); - setPositionText(onSketchPos, text); - - sketchgui->drawEdit(EditCurve); - if (seekAutoConstraint(sugConstr2, onSketchPos, Base::Vector2d(0.f, 0.f))) { - renderSuggestConstraintsCursor(sugConstr2); - return; - } - } - applyCursor(); - } - - virtual bool pressButton(Base::Vector2d onSketchPos) - { - if (Mode == STATUS_SEEK_First) { - StartPos = onSketchPos; - Mode = STATUS_SEEK_Second; - } - else { - EndPos = onSketchPos; - Mode = STATUS_End; - } - return true; - } - - virtual bool releaseButton(Base::Vector2d onSketchPos) - { - Q_UNUSED(onSketchPos); - if (Mode == STATUS_End) { - unsetCursor(); - resetPositionText(); - - int firstCurve = getHighestCurveIndex() + 1; - // add the geometry to the sketch - // first determine the angles for the first arc - double start = 0; - double end = M_PI / 2; - if (signX > 0 && signY > 0) { - start = -2 * end; - end = -1 * end; - } - else if (signX > 0 && signY < 0) { - start = end; - end = 2 * end; - } - else if (signX < 0 && signY > 0) { - start = -1 * end; - end = 0; - } - - try { - Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Add rounded rectangle")); - Gui::Command::doCommand(Gui::Command::Doc, - // syntax for arcs: Part.ArcOfCircle(Part.Circle(center, axis, radius), startangle, endangle) - "geoList = []\n" - "geoList.append(Part.ArcOfCircle(Part.Circle(App.Vector(%f, %f, 0), App.Vector(0, 0, 1), %f), %f, %f))\n" - "geoList.append(Part.LineSegment(App.Vector(%f, %f, 0), App.Vector(%f, %f, 0)))\n" - "geoList.append(Part.ArcOfCircle(Part.Circle(App.Vector(%f, %f, 0), App.Vector(0, 0, 1), %f), %f, %f))\n" - "geoList.append(Part.LineSegment(App.Vector(%f, %f, 0), App.Vector(%f, %f, 0)))\n" - "geoList.append(Part.ArcOfCircle(Part.Circle(App.Vector(%f, %f, 0), App.Vector(0, 0, 1), %f), %f, %f))\n" - "geoList.append(Part.LineSegment(App.Vector(%f, %f, 0), App.Vector(%f, %f, 0)))\n" - "geoList.append(Part.ArcOfCircle(Part.Circle(App.Vector(%f, %f, 0), App.Vector(0, 0, 1), %f), %f, %f))\n" - "geoList.append(Part.LineSegment(App.Vector(%f, %f, 0), App.Vector(%f, %f, 0)))\n" - "%s.addGeometry(geoList, %s)\n" - "conList = []\n" - "conList.append(Sketcher.Constraint('Tangent', %i, 1, %i, 1))\n" - "conList.append(Sketcher.Constraint('Tangent', %i, 2, %i, 2))\n" - "conList.append(Sketcher.Constraint('Tangent', %i, 1, %i, 1))\n" - "conList.append(Sketcher.Constraint('Tangent', %i, 2, %i, 2))\n" - "conList.append(Sketcher.Constraint('Tangent', %i, 1, %i, 1))\n" - "conList.append(Sketcher.Constraint('Tangent', %i, 2, %i, 2))\n" - "conList.append(Sketcher.Constraint('Tangent', %i, 1, %i, 1))\n" - "conList.append(Sketcher.Constraint('Tangent', %i, 2, %i, 2))\n" - "conList.append(Sketcher.Constraint('Horizontal', %i))\n" - "conList.append(Sketcher.Constraint('Horizontal', %i))\n" - "conList.append(Sketcher.Constraint('Vertical', %i))\n" - "conList.append(Sketcher.Constraint('Vertical', %i))\n" - "conList.append(Sketcher.Constraint('Equal', %i, %i))\n" - "conList.append(Sketcher.Constraint('Equal', %i, %i))\n" - "conList.append(Sketcher.Constraint('Equal', %i, %i))\n" - "%s.addConstraint(conList)\n", - StartPos.x + (signX * radius), StartPos.y + (signY * radius), // center of the arc 1 - radius, - start, end, // start and end angle of arc1 - EditCurve[8].x, EditCurve[8].y, EditCurve[9].x, EditCurve[9].y, // line 1 - signX == signY ? StartPos.x + (signX * radius) : StartPos.x + lengthX - (signX * radius), // center of the arc 2 - signX == signY ? StartPos.y + lengthY - (signY * radius) : StartPos.y + (signY * radius), - radius, - // start and end angle of arc 2 - // the logic is that end is start + M_PI / 2 and start is the previous end - M_PI - end - M_PI, - end - 0.5 * M_PI, - EditCurve[17].x, EditCurve[17].y, EditCurve[18].x, EditCurve[18].y, // line 2 - StartPos.x + lengthX - (signX * radius), StartPos.y + lengthY - (signY * radius), // center of the arc 3 - radius, - end - 1.5 * M_PI, - end - M_PI, - EditCurve[26].x, EditCurve[26].y, EditCurve[27].x, EditCurve[27].y, // line 3 - signX == signY ? StartPos.x + lengthX - (signX * radius) : StartPos.x + (signX * radius), // center of the arc 4 - signX == signY ? StartPos.y + (signY * radius) : StartPos.y + lengthY - (signY * radius), - radius, - end - 2 * M_PI, - end - 1.5 * M_PI, - EditCurve[35].x, EditCurve[35].y, EditCurve[36].x, EditCurve[36].y, // line 4 - Gui::Command::getObjectCmd(sketchgui->getObject()).c_str(), // the sketch - geometryCreationMode == Construction ? "True" : "False", // geometry as construction or not - firstCurve, firstCurve + 1, // tangent 1 - firstCurve + 1, firstCurve + 2, // tangent 2 - firstCurve + 2, firstCurve + 3, // tangent 3 - firstCurve + 3, firstCurve + 4, // tangent 4 - firstCurve + 4, firstCurve + 5, // tangent 5 - firstCurve + 5, firstCurve + 6, // tangent 6 - firstCurve + 6, firstCurve + 7, // tangent 7 - firstCurve + 7, firstCurve, // tangent 8 - signX == signY ? firstCurve + 3 : firstCurve + 1, // horizontal constraint - signX == signY ? firstCurve + 7 : firstCurve + 5, // horizontal constraint - signX == signY ? firstCurve + 1 : firstCurve + 3, // vertical constraint - signX == signY ? firstCurve + 5 : firstCurve + 7, // vertical constraint - firstCurve, firstCurve + 2, // equal 1 - firstCurve + 2, firstCurve + 4, // equal 2 - firstCurve + 4, firstCurve + 6, // equal 3 - Gui::Command::getObjectCmd(sketchgui->getObject()).c_str()); // the sketch - - // now add contruction geometry - two points used to take suggested constraints - Gui::Command::doCommand(Gui::Command::Doc, - "geoList = []\n" - "geoList.append(Part.Point(App.Vector(%f, %f, 0)))\n" - "geoList.append(Part.Point(App.Vector(%f, %f, 0)))\n" - "%s.addGeometry(geoList, True)\n" // geometry as construction - "conList = []\n" - "conList.append(Sketcher.Constraint('PointOnObject', %i, 1, %i, ))\n" - "conList.append(Sketcher.Constraint('PointOnObject', %i, 1, %i, ))\n" - "conList.append(Sketcher.Constraint('PointOnObject', %i, 1, %i, ))\n" - "conList.append(Sketcher.Constraint('PointOnObject', %i, 1, %i, ))\n" - "%s.addConstraint(conList)\n", - StartPos.x, StartPos.y, // point at StartPos - EndPos.x, EndPos.y, // point at EndPos - Gui::Command::getObjectCmd(sketchgui->getObject()).c_str(), // the sketch - firstCurve + 8, firstCurve + 1, // point on object constraint - firstCurve + 8, firstCurve + 7, // point on object constraint - firstCurve + 9, firstCurve + 3, // point on object constraint - firstCurve + 9, firstCurve + 5, // point on object constraint - Gui::Command::getObjectCmd(sketchgui->getObject()).c_str()); // the sketch - - Gui::Command::commitCommand(); - - // add auto constraints at the StartPos auxiliar point - if (sugConstr1.size() > 0) { - createAutoConstraints(sugConstr1, getHighestCurveIndex() - 1, Sketcher::start); - sugConstr1.clear(); - } - - // add auto constraints at the EndPos auxiliar point - if (sugConstr2.size() > 0) { - createAutoConstraints(sugConstr2, getHighestCurveIndex(), Sketcher::start); - sugConstr2.clear(); - } - - tryAutoRecomputeIfNotSolve(static_cast(sketchgui->getObject())); - } - catch (const Base::Exception& e) { - Base::Console().Error("Failed to add rounded rectangle: %s\n", e.what()); - Gui::Command::abortCommand(); - - tryAutoRecompute(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. - Mode = STATUS_SEEK_First; - EditCurve.clear(); - sketchgui->drawEdit(EditCurve); - EditCurve.resize(37); - applyCursor(); - /* this 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; - } -protected: - BoxMode Mode; - Base::Vector2d StartPos, EndPos; - double lengthX, lengthY, radius; - float signX, signY; - std::vector EditCurve; - std::vector sugConstr1, sugConstr2; -}; - -DEF_STD_CMD_AU(CmdSketcherCreateOblong) - -CmdSketcherCreateOblong::CmdSketcherCreateOblong() - : Command("Sketcher_CreateOblong") -{ - sAppModule = "Sketcher"; - sGroup = QT_TR_NOOP("Sketcher"); - sMenuText = QT_TR_NOOP("Create rounded rectangle"); - sToolTipText = QT_TR_NOOP("Create a rounded rectangle in the sketch"); - sWhatsThis = "Sketcher_CreateOblong"; - sStatusTip = sToolTipText; - sPixmap = "Sketcher_CreateOblong"; - sAccel = ""; - eType = ForEdit; -} - -void CmdSketcherCreateOblong::activated(int iMsg) -{ - Q_UNUSED(iMsg); - ActivateHandler(getActiveGuiDocument(), new DrawSketchHandlerOblong()); -} - -void CmdSketcherCreateOblong::updateAction(int mode) -{ - switch (mode) { - case Normal: - if (getAction()) - getAction()->setIcon(Gui::BitmapFactory().iconFromTheme("Sketcher_CreateOblong")); - break; - case Construction: - if (getAction()) - getAction()->setIcon(Gui::BitmapFactory().iconFromTheme("Sketcher_CreateOblong_Constr")); - break; - } -} - -bool CmdSketcherCreateOblong::isActive(void) -{ - return isCreateGeoActive(getActiveGuiDocument()); -} - - -DEF_STD_CMD_ACLU(CmdSketcherCompCreateRectangles) - -CmdSketcherCompCreateRectangles::CmdSketcherCompCreateRectangles() - : Command("Sketcher_CompCreateRectangles") -{ - sAppModule = "Sketcher"; - sGroup = QT_TR_NOOP("Sketcher"); - sMenuText = QT_TR_NOOP("Create rectangles"); - sToolTipText = QT_TR_NOOP("Creates a rectangle in the sketch"); - sWhatsThis = "Sketcher_CompCreateRectangles"; - sStatusTip = sToolTipText; - eType = ForEdit; -} - -void CmdSketcherCompCreateRectangles::activated(int iMsg) -{ - if (iMsg == 0) - ActivateHandler(getActiveGuiDocument(), new DrawSketchHandlerBox()); - else if (iMsg == 1) - ActivateHandler(getActiveGuiDocument(), new DrawSketchHandlerOblong()); - else - return; - - // Since the default icon is reset when enabling/disabling the command we have - // to explicitly set the icon of the used command. - Gui::ActionGroup* pcAction = qobject_cast(_pcAction); - QList a = pcAction->actions(); - - assert(iMsg < a.size()); - pcAction->setIcon(a[iMsg]->icon()); -} - -Gui::Action* CmdSketcherCompCreateRectangles::createAction(void) -{ - Gui::ActionGroup* pcAction = new Gui::ActionGroup(this, Gui::getMainWindow()); - pcAction->setDropDownMenu(true); - applyCommandData(this->className(), pcAction); - - QAction* arc1 = pcAction->addAction(QString()); - arc1->setIcon(Gui::BitmapFactory().iconFromTheme("Sketcher_CreateRectangle")); - QAction* arc2 = pcAction->addAction(QString()); - arc2->setIcon(Gui::BitmapFactory().iconFromTheme("Sketcher_CreateOblong")); - - _pcAction = pcAction; - languageChange(); - - pcAction->setIcon(arc1->icon()); - int defaultId = 0; - pcAction->setProperty("defaultAction", QVariant(defaultId)); - - return pcAction; -} - -void CmdSketcherCompCreateRectangles::updateAction(int mode) -{ - Gui::ActionGroup* pcAction = qobject_cast(getAction()); - if (!pcAction) - return; - - QList a = pcAction->actions(); - int index = pcAction->property("defaultAction").toInt(); - switch (mode) { - case Normal: - a[0]->setIcon(Gui::BitmapFactory().iconFromTheme("Sketcher_CreateRectangle")); - a[1]->setIcon(Gui::BitmapFactory().iconFromTheme("Sketcher_CreateOblong")); - getAction()->setIcon(a[index]->icon()); - break; - case Construction: - a[0]->setIcon(Gui::BitmapFactory().iconFromTheme("Sketcher_CreateRectangle_Constr")); - a[1]->setIcon(Gui::BitmapFactory().iconFromTheme("Sketcher_CreateOblong_Constr")); - getAction()->setIcon(a[index]->icon()); - break; - } -} - -void CmdSketcherCompCreateRectangles::languageChange() -{ - Command::languageChange(); - - if (!_pcAction) - return; - Gui::ActionGroup* pcAction = qobject_cast(_pcAction); - QList a = pcAction->actions(); - - QAction* rectangle1 = a[0]; - rectangle1->setText(QApplication::translate("CmdSketcherCompCreateRectangles", "Rectangle")); - rectangle1->setToolTip(QApplication::translate("Sketcher_CreateRectangle", "Create a rectangle")); - rectangle1->setStatusTip(rectangle1->toolTip()); - QAction* rectangle2 = a[1]; - rectangle2->setText(QApplication::translate("CmdSketcherCompCreateRectangles", "Rounded rectangle")); - rectangle2->setToolTip(QApplication::translate("Sketcher_CreateOblong", "Create a rounded rectangle")); - rectangle2->setStatusTip(rectangle2->toolTip()); -} - -bool CmdSketcherCompCreateRectangles::isActive(void) -{ - return isCreateGeoActive(getActiveGuiDocument()); -} - - /* Create Regular Polygon ==============================================*/ class DrawSketchHandlerRegularPolygon: public DrawSketchHandler