Files
create/src/Mod/Sketcher/Gui/DrawSketchHandlerRectangle.h
Syres916 36bd6709bc [Sketcher] Allow experienced users to not have...
...the extra points created on rounded rectangles, it started to become a real pain when box selecting large amounts of geometry and having to keep changing the two points back to construction. New and existing users are completely unaffected.
2023-04-22 21:04:23 +02:00

614 lines
31 KiB
C++

/***************************************************************************
* Copyright (c) 2022 Abdullah Tahiri <abdullah.tahiri.yo@gmail.com> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef SKETCHERGUI_DrawSketchHandlerRectangle_H
#define SKETCHERGUI_DrawSketchHandlerRectangle_H
#include "GeometryCreationMode.h"
namespace SketcherGui {
extern GeometryCreationMode geometryCreationMode; // defined in CommandCreateGeo.cpp
class DrawSketchHandlerBox: public DrawSketchHandler
{
public:
enum ConstructionMethod {
Diagonal,
CenterAndCorner
};
explicit DrawSketchHandlerBox(ConstructionMethod constrMethod = Diagonal): Mode(STATUS_SEEK_First),
EditCurve(5),
constructionMethod(constrMethod){}
virtual ~DrawSketchHandlerBox(){}
/// mode table
enum BoxMode {
STATUS_SEEK_First, /**< enum value ----. */
STATUS_SEEK_Second, /**< enum value ----. */
STATUS_End
};
public:
void mouseMove(Base::Vector2d onSketchPos) override
{
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) {
if(constructionMethod == Diagonal) {
float dx = onSketchPos.x - EditCurve[0].x;
float dy = onSketchPos.y - EditCurve[0].y;
if (showCursorCoords()) {
SbString text;
std::string dxString = lengthToDisplayFormat(dx, 1);
std::string dyString = lengthToDisplayFormat(dy, 1);
text.sprintf(" (%s x %s)", dxString.c_str(), dyString.c_str());
setPositionText(onSketchPos, text);
}
EditCurve[2] = onSketchPos;
EditCurve[1] = Base::Vector2d(onSketchPos.x ,EditCurve[0].y);
EditCurve[3] = Base::Vector2d(EditCurve[0].x,onSketchPos.y);
}
else if (constructionMethod == CenterAndCorner) {
float dx = onSketchPos.x - center.x;
float dy = onSketchPos.y - center.y;
if (showCursorCoords()) {
SbString text;
std::string dxString = lengthToDisplayFormat(dx, 1);
std::string dyString = lengthToDisplayFormat(dy, 1);
text.sprintf(" (%s x %s)", dxString.c_str(), dyString.c_str());
setPositionText(onSketchPos, text);
}
EditCurve[0] = center - (onSketchPos - center);
EditCurve[1] = Base::Vector2d(EditCurve[0].x,onSketchPos.y);
EditCurve[2] = onSketchPos;
EditCurve[3] = Base::Vector2d(onSketchPos.x,EditCurve[0].y);
EditCurve[4] = EditCurve[0];
}
drawEdit(EditCurve);
if (seekAutoConstraint(sugConstr2, onSketchPos, Base::Vector2d(0.0,0.0))) {
renderSuggestConstraintsCursor(sugConstr2);
return;
}
}
applyCursor();
}
bool pressButton(Base::Vector2d onSketchPos) override
{
if (Mode==STATUS_SEEK_First){
if(constructionMethod == Diagonal) {
EditCurve[0] = onSketchPos;
EditCurve[4] = onSketchPos;
}
else if (constructionMethod == CenterAndCorner) {
center = onSketchPos;
}
Mode = STATUS_SEEK_Second;
}
else {
if(constructionMethod == Diagonal) {
EditCurve[2] = onSketchPos;
EditCurve[1] = Base::Vector2d(onSketchPos.x ,EditCurve[0].y);
EditCurve[3] = Base::Vector2d(EditCurve[0].x,onSketchPos.y);
drawEdit(EditCurve);
Mode = STATUS_End;
}
else if (constructionMethod == CenterAndCorner) {
EditCurve[0] = center - (onSketchPos - center);
EditCurve[1] = Base::Vector2d(EditCurve[0].x,onSketchPos.y);
EditCurve[2] = onSketchPos;
EditCurve[3] = Base::Vector2d(onSketchPos.x,EditCurve[0].y);
EditCurve[4] = EditCurve[0];
drawEdit(EditCurve);
Mode = STATUS_End;
}
}
return true;
}
bool releaseButton(Base::Vector2d onSketchPos) override
{
Q_UNUSED(onSketchPos);
if (Mode==STATUS_End){
unsetCursor();
resetPositionText();
int firstCurve = getHighestCurveIndex() + 1;
try {
if(constructionMethod == Diagonal) {
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Add sketch box"));
Gui::Command::doCommand(Gui::Command::Doc,
"geoList = []\n"
"geoList.append(Part.LineSegment(App.Vector(%f,%f,0),App.Vector(%f,%f,0)))\n"
"geoList.append(Part.LineSegment(App.Vector(%f,%f,0),App.Vector(%f,%f,0)))\n"
"geoList.append(Part.LineSegment(App.Vector(%f,%f,0),App.Vector(%f,%f,0)))\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('Coincident',%i,2,%i,1))\n"
"conList.append(Sketcher.Constraint('Coincident',%i,2,%i,1))\n"
"conList.append(Sketcher.Constraint('Coincident',%i,2,%i,1))\n"
"conList.append(Sketcher.Constraint('Coincident',%i,2,%i,1))\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"
"%s.addConstraint(conList)\n"
"del geoList, conList\n",
EditCurve[0].x,EditCurve[0].y,EditCurve[1].x,EditCurve[1].y, // line 1
EditCurve[1].x,EditCurve[1].y,EditCurve[2].x,EditCurve[2].y, // line 2
EditCurve[2].x,EditCurve[2].y,EditCurve[3].x,EditCurve[3].y, // line 3
EditCurve[3].x,EditCurve[3].y,EditCurve[0].x,EditCurve[0].y, // line 4
Gui::Command::getObjectCmd(sketchgui->getObject()).c_str(), // the sketch
geometryCreationMode==Construction?"True":"False", // geometry as construction or not
firstCurve,firstCurve+1, // coincident1
firstCurve+1,firstCurve+2, // coincident2
firstCurve+2,firstCurve+3, // coincident3
firstCurve+3,firstCurve, // coincident4
firstCurve, // horizontal1
firstCurve+2, // horizontal2
firstCurve+1, // vertical1
firstCurve+3, // vertical2
Gui::Command::getObjectCmd(sketchgui->getObject()).c_str()); // the sketch
Gui::Command::commitCommand();
}
else if (constructionMethod == CenterAndCorner) {
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Add centered sketch box"));
Gui::Command::doCommand(Gui::Command::Doc,
"geoList = []\n"
"geoList.append(Part.LineSegment(App.Vector(%f,%f,0),App.Vector(%f,%f,0)))\n"
"geoList.append(Part.LineSegment(App.Vector(%f,%f,0),App.Vector(%f,%f,0)))\n"
"geoList.append(Part.LineSegment(App.Vector(%f,%f,0),App.Vector(%f,%f,0)))\n"
"geoList.append(Part.LineSegment(App.Vector(%f,%f,0),App.Vector(%f,%f,0)))\n"
"geoList.append(Part.Point(App.Vector(%f,%f,0)))\n"
"%s.addGeometry(geoList,%s)\n"
"conList = []\n"
"conList.append(Sketcher.Constraint('Coincident',%i,2,%i,1))\n"
"conList.append(Sketcher.Constraint('Coincident',%i,2,%i,1))\n"
"conList.append(Sketcher.Constraint('Coincident',%i,2,%i,1))\n"
"conList.append(Sketcher.Constraint('Coincident',%i,2,%i,1))\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('Symmetric',%i,2,%i,1,%i,1))\n"
"%s.addConstraint(conList)\n"
"del geoList, conList\n",
EditCurve[0].x,EditCurve[0].y,EditCurve[1].x,EditCurve[1].y, // line 1
EditCurve[1].x,EditCurve[1].y,EditCurve[2].x,EditCurve[2].y, // line 2
EditCurve[2].x,EditCurve[2].y,EditCurve[3].x,EditCurve[3].y, // line 3
EditCurve[3].x,EditCurve[3].y,EditCurve[0].x,EditCurve[0].y, // line 4
center.x,center.y, // center point
Gui::Command::getObjectCmd(sketchgui->getObject()).c_str(), // the sketch
geometryCreationMode==Construction?"True":"False", // geometry as construction or not
firstCurve,firstCurve+1, // coincident1
firstCurve+1,firstCurve+2, // coincident2
firstCurve+2,firstCurve+3, // coincident3
firstCurve+3,firstCurve, // coincident4
firstCurve+1, // horizontal1
firstCurve+3, // horizontal2
firstCurve, // vertical1
firstCurve+2, // vertical2
firstCurve+1, firstCurve, firstCurve + 4, // Symmetric
Gui::Command::getObjectCmd(sketchgui->getObject()).c_str()); // the sketch
Gui::Command::commitCommand();
}
}
catch (const Base::Exception& e) {
Base::Console().Error("Failed to add box: %s\n", e.what());
Gui::Command::abortCommand();
}
if(constructionMethod == Diagonal) {
// add auto constraints at the start of the first side
if (!sugConstr1.empty()) {
createAutoConstraints(sugConstr1, getHighestCurveIndex() - 3 , Sketcher::PointPos::start);
sugConstr1.clear();
}
// add auto constraints at the end of the second side
if (!sugConstr2.empty()) {
createAutoConstraints(sugConstr2, getHighestCurveIndex() - 2, Sketcher::PointPos::end);
sugConstr2.clear();
}
}
else if (constructionMethod == CenterAndCorner) {
// add auto constraints at the start of the first side
if (!sugConstr1.empty()) {
createAutoConstraints(sugConstr1, getHighestCurveIndex(), Sketcher::PointPos::start);
sugConstr1.clear();
}
// add auto constraints at the end of the second side
if (!sugConstr2.empty()) {
createAutoConstraints(sugConstr2, getHighestCurveIndex() - 3, Sketcher::PointPos::end);
sugConstr2.clear();
}
}
tryAutoRecomputeIfNotSolve(static_cast<Sketcher::SketchObject *>(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();
drawEdit(EditCurve);
EditCurve.resize(5);
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;
}
private:
QString getCrosshairCursorSVGName() const override
{
return QString::fromLatin1("Sketcher_Pointer_Create_Box");
}
protected:
BoxMode Mode;
std::vector<Base::Vector2d> EditCurve;
std::vector<AutoConstraint> sugConstr1, sugConstr2;
ConstructionMethod constructionMethod;
Base::Vector2d center;
};
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
};
void mouseMove(Base::Vector2d onSketchPos) override
{
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 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];
if (showCursorCoords()) {
SbString text;
std::string radiusString = lengthToDisplayFormat(radius, 1);
std::string xString = lengthToDisplayFormat(lengthX, 1);
std::string yString = lengthToDisplayFormat(lengthY, 1);
text.sprintf(" (R%s X%s Y%s)", radiusString.c_str(), xString.c_str(), yString.c_str());
setPositionText(onSketchPos, text);
}
drawEdit(EditCurve);
if (seekAutoConstraint(sugConstr2, onSketchPos, Base::Vector2d(0.f, 0.f))) {
renderSuggestConstraintsCursor(sugConstr2);
return;
}
}
applyCursor();
}
bool pressButton(Base::Vector2d onSketchPos) override
{
if (Mode == STATUS_SEEK_First) {
StartPos = onSketchPos;
Mode = STATUS_SEEK_Second;
}
else {
EndPos = onSketchPos;
Mode = STATUS_End;
}
return true;
}
bool releaseButton(Base::Vector2d onSketchPos) override
{
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"
"del geoList, 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
// not all users want these extra points, some power users find them unnecessary
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher");
auto showExtraPoints = hGrp->GetBool("RoundRectangleSuggConstraints", true);
if (showExtraPoints) {
// now add construction 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"
"del geoList, 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 auxiliary point
if (!sugConstr1.empty()) {
createAutoConstraints(sugConstr1, getHighestCurveIndex() - 1, Sketcher::PointPos::start);
sugConstr1.clear();
}
// add auto constraints at the EndPos auxiliary point
if (!sugConstr2.empty()) {
createAutoConstraints(sugConstr2, getHighestCurveIndex(), Sketcher::PointPos::start);
sugConstr2.clear();
}
tryAutoRecomputeIfNotSolve(static_cast<Sketcher::SketchObject*>(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<Sketcher::SketchObject*>(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();
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;
}
private:
QString getCrosshairCursorSVGName() const override
{
return QString::fromLatin1("Sketcher_Pointer_Oblong");
}
protected:
BoxMode Mode;
Base::Vector2d StartPos, EndPos;
double lengthX, lengthY, radius;
float signX, signY;
std::vector<Base::Vector2d> EditCurve;
std::vector<AutoConstraint> sugConstr1, sugConstr2;
};
} // namespace SketcherGui
#endif // SKETCHERGUI_DrawSketchHandlerRectangle_H