diff --git a/src/Mod/Part/Gui/ViewProviderGridExtension.cpp b/src/Mod/Part/Gui/ViewProviderGridExtension.cpp index 49e36e2e5a..5e1dd87285 100644 --- a/src/Mod/Part/Gui/ViewProviderGridExtension.cpp +++ b/src/Mod/Part/Gui/ViewProviderGridExtension.cpp @@ -34,6 +34,8 @@ # include # include # include + +# include #endif #include @@ -58,12 +60,6 @@ using namespace std; EXTENSION_PROPERTY_SOURCE(PartGui::ViewProviderGridExtension, Gui::ViewProviderExtension) -enum class GridStyle { - Dashed = 0, - Light = 1, -}; - -const char* ViewProviderGridExtension::GridStyleEnums[] = { "Dashed","Light",nullptr }; App::PropertyQuantityConstraint::Constraints ViewProviderGridExtension::GridSizeRange = { 0.001,DBL_MAX,1.0 }; namespace PartGui { @@ -80,6 +76,9 @@ public: SoSeparator * getGridRoot(); + void getClosestGridPoint(double &x, double &y) const; + double getGridSize() const; + // Configurable parameters (to be configured by specific VP) int GridSizePixelThreshold = 15; int GridNumberSubdivision = 10; @@ -97,9 +96,9 @@ public: void OnChange(Base::Subject &rCaller, const char * sReason) override; private: - double computeGridSize(const Gui::View3DInventorViewer* viewer); + void computeGridSize(const Gui::View3DInventorViewer* viewer); void createGrid(bool cameraUpdate = false); - void createGridPart(double Step, int numberSubdiv, bool divLines, bool subDivLines, int pattern, SoBaseColor* color, int lineWidth = 1); + void createGridPart(int numberSubdiv, bool divLines, bool subDivLines, int pattern, SoBaseColor* color, int lineWidth = 1); bool checkCameraZoomChange(const Gui::View3DInventorViewer* viewer); bool checkCameraTranslationChange(const Gui::View3DInventorViewer* viewer); @@ -113,6 +112,9 @@ private: ViewProviderGridExtension * vp; bool enabled = false; + double computedGridValue = 10; + + bool isTooManySegmentsNotified = false; // scenograph SoSeparator * GridRoot; @@ -147,6 +149,25 @@ GridExtensionP::~GridExtensionP() hGrp->Detach(this); } +double GridExtensionP::getGridSize() const +{ + return computedGridValue; +} + +void GridExtensionP::getClosestGridPoint(double &x, double &y) const +{ + auto closestdim = [](double &dim, double gridValue) { + dim = dim / gridValue; + dim = dim < 0.0 ? ceil(dim - 0.5) : floor(dim + 0.5); + dim *= gridValue; + }; + + closestdim(x, computedGridValue); + closestdim(y, computedGridValue); + + //Base::Console().Log("gridvalue=%f, (x,y)=(%f,%f)", computedGridValue, x, y); +} + bool GridExtensionP::checkCameraZoomChange(const Gui::View3DInventorViewer* viewer) { float newCamMaxDimension = viewer->getMaxDimension(); @@ -171,34 +192,46 @@ bool GridExtensionP::checkCameraTranslationChange(const Gui::View3DInventorViewe return false; } -double GridExtensionP::computeGridSize(const Gui::View3DInventorViewer* viewer) +void GridExtensionP::computeGridSize(const Gui::View3DInventorViewer* viewer) { + + auto capGridSize = [](auto & value){ + value = std::max(static_cast(value), std::numeric_limits::min()); + value = std::min(static_cast(value), std::numeric_limits::max()); + }; + + if (!vp->GridAuto.getValue()) { + computedGridValue = vp->GridSize.getValue(); + capGridSize(computedGridValue); + return; + } + short pixelWidth = -1; short pixelHeight = -1; viewer->getViewportRegion().getViewportSizePixels().getValue(pixelWidth, pixelHeight); - if (pixelWidth < 0 || pixelHeight < 0) - return vp->GridSize.getValue(); + if (pixelWidth < 0 || pixelHeight < 0) { + computedGridValue = vp->GridSize.getValue(); + return; + } int numberOfLines = static_cast(std::max(pixelWidth, pixelHeight)) / GridSizePixelThreshold; double unitMultiplier = (unitsUserSchema == 2 || unitsUserSchema == 3) ? 25.4 : (unitsUserSchema == 5 || unitsUserSchema == 7) ? 304.8 : 1; - double newGridSize = unitMultiplier * pow(GridNumberSubdivision, 1 + floor(log(camMaxDimension / unitMultiplier / numberOfLines) / log(GridNumberSubdivision))); + computedGridValue = vp->GridSize.getValue() * unitMultiplier * pow(GridNumberSubdivision, floor(log(camMaxDimension / unitMultiplier / numberOfLines) / log(GridNumberSubdivision))); //cap the grid size - newGridSize = std::max(newGridSize, 0.000001); - newGridSize = std::min(newGridSize, 10000000.0); - - if (newGridSize != vp->GridSize.getValue()) // avoid unnecessary property update - vp->GridSize.setValue(newGridSize); //grid size must be set for grid snap. But we need to block it from calling createGrid. - - return newGridSize; + capGridSize(computedGridValue); } void GridExtensionP::createGrid(bool cameraUpdate) { - Gui::MDIView* mdi = Gui::Application::Instance->editDocument()->getActiveView(); - Gui::View3DInventorViewer* viewer = static_cast(mdi)->getViewer(); + auto view = dynamic_cast(Gui::Application::Instance->editDocument()->getActiveView()); + + if(!view) + return; + + Gui::View3DInventorViewer* viewer = view->getViewer(); bool cameraDimensionsChanged = checkCameraZoomChange(viewer); @@ -211,11 +244,7 @@ void GridExtensionP::createGrid(bool cameraUpdate) Gui::coinRemoveAllChildren(GridRoot); - double step; - if (vp->GridAuto.getValue()) - step = computeGridSize(viewer); - else - step = vp->GridSize.getValue(); + computeGridSize(viewer); auto getColor = [](auto unpackedcolor) { SoBaseColor* lineColor = new SoBaseColor; @@ -227,18 +256,18 @@ void GridExtensionP::createGrid(bool cameraUpdate) }; //First we create the subdivision lines - createGridPart(step, GridNumberSubdivision, true, + createGridPart(GridNumberSubdivision, true, (GridNumberSubdivision == 1), GridLinePattern, getColor(GridLineColor), GridLineWidth); //Second we create the wider lines marking every nth lines if (GridNumberSubdivision > 1) { - createGridPart(step, GridNumberSubdivision, false, true, + createGridPart(GridNumberSubdivision, false, true, GridDivLinePattern, getColor(GridDivLineColor), GridDivLineWidth); } } -void GridExtensionP::createGridPart(double Step, int numberSubdiv, bool subDivLines, bool divLines, int pattern, SoBaseColor* color, int lineWidth) +void GridExtensionP::createGridPart(int numberSubdiv, bool subDivLines, bool divLines, int pattern, SoBaseColor* color, int lineWidth) { SoGroup* parent = new Gui::SoSkipBoundingGroup(); GridRoot->addChild(parent); @@ -246,17 +275,10 @@ void GridExtensionP::createGridPart(double Step, int numberSubdiv, bool subDivLi parent->addChild(color); - if (vp->GridStyle.getValue() == static_cast(GridStyle::Dashed)) { - SoDrawStyle* DefaultStyle = new SoDrawStyle; - DefaultStyle->lineWidth = lineWidth; - DefaultStyle->linePattern = pattern; - parent->addChild(DefaultStyle); - } - else { - SoMaterial* LightStyle = new SoMaterial; - LightStyle->transparency = 0.7f; - parent->addChild(LightStyle); - } + SoDrawStyle* DefaultStyle = new SoDrawStyle; + DefaultStyle->lineWidth = lineWidth; + DefaultStyle->linePattern = pattern; + parent->addChild(DefaultStyle); SoPickStyle* PickStyle = new SoPickStyle; PickStyle->style = SoPickStyle::UNPICKABLE; @@ -267,12 +289,21 @@ void GridExtensionP::createGridPart(double Step, int numberSubdiv, bool subDivLi grid->vertexProperty = vts; float gridDimension = 1.5 * camMaxDimension; - int vlines = static_cast(gridDimension / Step); // total number of vertical lines + int vlines = static_cast(gridDimension / computedGridValue); // total number of vertical lines int nlines = 2 * vlines; // total number of lines + if (nlines > 2000) { + if(!isTooManySegmentsNotified) { + Base::Console().Warning("The grid is too dense, so it is being disabled. Consider zooming in or changing the grid configuration\n"); + isTooManySegmentsNotified = true; + } + Gui::coinRemoveAllChildren(GridRoot); return; } + else { + isTooManySegmentsNotified = false; + } // set the grid indices grid->numVertices.setNum(nlines); @@ -293,12 +324,12 @@ void GridExtensionP::createGridPart(double Step, int numberSubdiv, bool subDivLi maxY = minY + gridDimension; // vertical lines - int i_offset_x = static_cast(minX / Step); + int i_offset_x = static_cast(minX / computedGridValue); for (int i = 0; i < vlines; i++) { int iStep = (i + i_offset_x); if (((iStep % numberSubdiv == 0) && divLines) || ((iStep % numberSubdiv != 0) && subDivLines)) { - vertex_coords[2 * i].setValue(iStep * Step, minY, 0); - vertex_coords[2 * i + 1].setValue(iStep * Step, maxY, 0); + vertex_coords[2 * i].setValue(iStep * computedGridValue, minY, 0); + vertex_coords[2 * i + 1].setValue(iStep * computedGridValue, maxY, 0); } else { /*the number of vertices is defined before. To know the number of vertices ahead it would require @@ -310,12 +341,12 @@ void GridExtensionP::createGridPart(double Step, int numberSubdiv, bool subDivLi } // horizontal lines - int i_offset_y = static_cast(minY / Step) - vlines; + int i_offset_y = static_cast(minY / computedGridValue) - vlines; for (int i = vlines; i < nlines; i++) { int iStep = (i + i_offset_y); if (((iStep % numberSubdiv == 0) && divLines) || ((iStep % numberSubdiv != 0) && subDivLines)) { - vertex_coords[2 * i].setValue(minX, iStep * Step, 0); - vertex_coords[2 * i + 1].setValue(maxX, iStep * Step, 0); + vertex_coords[2 * i].setValue(minX, iStep * computedGridValue, 0); + vertex_coords[2 * i + 1].setValue(maxX, iStep * computedGridValue, 0); } else { vertex_coords[2 * i].setValue(0, 0, 0); @@ -379,16 +410,15 @@ ViewProviderGridExtension::ViewProviderGridExtension() EXTENSION_ADD_PROPERTY_TYPE(ShowGrid, (false), "Grid", (App::PropertyType)(App::Prop_None), "Switch the grid on/off"); EXTENSION_ADD_PROPERTY_TYPE(GridSize, (10.0), "Grid", (App::PropertyType)(App::Prop_None), "Gap size of the grid"); - EXTENSION_ADD_PROPERTY_TYPE(GridStyle, (0L), "Grid", (App::PropertyType)(App::Prop_None), "Appearance style of the grid"); - EXTENSION_ADD_PROPERTY_TYPE(GridSnap, (false), "Grid", (App::PropertyType)(App::Prop_None), "Switch the grid snap on/off"); EXTENSION_ADD_PROPERTY_TYPE(GridAuto, (true), "Grid", (App::PropertyType)(App::Prop_None), "Change size of grid based on view area."); initExtensionType(ViewProviderGridExtension::getExtensionClassTypeId()); - GridStyle.setEnums(GridStyleEnums); GridSize.setConstraints(&GridSizeRange); pImpl = std::make_unique(this); + + } ViewProviderGridExtension::~ViewProviderGridExtension() @@ -409,6 +439,16 @@ SoSeparator* ViewProviderGridExtension::getGridNode() return pImpl->getGridRoot(); } +double ViewProviderGridExtension::getGridSize() const +{ + return pImpl->getGridSize(); +} + +void ViewProviderGridExtension::getClosestGridPoint(double &x, double &y) const +{ + return pImpl->getClosestGridPoint(x, y); +} + void ViewProviderGridExtension::extensionUpdateData(const App::Property* prop) { if(pImpl->getEnabled()) { @@ -422,8 +462,8 @@ void ViewProviderGridExtension::extensionOnChanged(const App::Property* prop) { if(pImpl->getEnabled()) { if (prop == &ShowGrid || - prop == &GridSize || - prop == &GridStyle) { + prop == &GridAuto || + prop == &GridSize ) { pImpl->drawGrid(); } } @@ -459,14 +499,14 @@ void ViewProviderGridExtension::setGridDivLineWidth(int width) pImpl->GridDivLineWidth = width; } -void ViewProviderGridExtension::setGridLineColor(unsigned int color) +void ViewProviderGridExtension::setGridLineColor(const App::Color & color) { - pImpl->GridLineColor = color; + pImpl->GridLineColor = color.getPackedValue(); } -void ViewProviderGridExtension::setGridDivLineColor(unsigned int color) +void ViewProviderGridExtension::setGridDivLineColor(const App::Color & color) { - pImpl->GridDivLineColor = color; + pImpl->GridDivLineColor = color.getPackedValue(); } bool ViewProviderGridExtension::extensionHandleChangedPropertyType(Base::XMLReader& reader, diff --git a/src/Mod/Part/Gui/ViewProviderGridExtension.h b/src/Mod/Part/Gui/ViewProviderGridExtension.h index fe30c556e1..258aacdad5 100644 --- a/src/Mod/Part/Gui/ViewProviderGridExtension.h +++ b/src/Mod/Part/Gui/ViewProviderGridExtension.h @@ -28,6 +28,7 @@ #include #include #include +#include namespace PartGui { @@ -40,8 +41,6 @@ class PartGuiExport ViewProviderGridExtension : public Gui::ViewProviderExtensio public: App::PropertyBool ShowGrid; App::PropertyLength GridSize; - App::PropertyEnumeration GridStyle; - App::PropertyBool GridSnap; App::PropertyBool GridAuto; /// constructor @@ -56,8 +55,14 @@ public: SoSeparator* getGridNode(); + /** Return the distance to the closest point in the grid. + * The point closer to the grid is returned by reference + */ + void getClosestGridPoint(double &x, double &y) const; + double getGridSize() const; + protected: - void extensionOnChanged(const App::Property* /*prop*/) override; + void extensionOnChanged(const App::Property*) override; // configuration parameters void setGridSizePixelThreshold(int value); @@ -66,13 +71,9 @@ protected: void setGridDivLinePattern(int pattern); void setGridLineWidth(int width); void setGridDivLineWidth(int width); - void setGridLineColor(unsigned int color); - void setGridDivLineColor(unsigned int color); + void setGridLineColor(const App::Color & color); + void setGridDivLineColor(const App::Color & color); - - //void extensionRestore(Base::XMLReader& reader) override; - //virtual void extHandleChangedPropertyName(Base::XMLReader &reader, const char* TypeName, const char* PropName) override; - //void handleChangedPropertyType(Base::XMLReader& reader, const char* TypeName, App::Property* prop) override; virtual bool extensionHandleChangedPropertyType(Base::XMLReader &reader, const char * TypeName, App::Property * prop) override; diff --git a/src/Mod/Sketcher/Gui/Command.cpp b/src/Mod/Sketcher/Gui/Command.cpp index 728697e7e1..943395033a 100644 --- a/src/Mod/Sketcher/Gui/Command.cpp +++ b/src/Mod/Sketcher/Gui/Command.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -970,6 +971,7 @@ class GridSpaceAction : public QWidgetAction { public: GridSpaceAction(QObject* parent) : QWidgetAction(parent) { + setEnabled(false); } void updateWidget() { @@ -978,18 +980,24 @@ public: if(sketchView) { - auto updateCheckBox = [](QCheckBox * checkbox, App::PropertyBool & property) { + auto updateCheckBox = [](QCheckBox * checkbox, bool value) { auto checked = checkbox->checkState() == Qt::Checked; - auto propvalue = property.getValue(); - if( propvalue != checked ) { + if( value != checked ) { const QSignalBlocker blocker(checkbox); - checkbox->setChecked(propvalue); + checkbox->setChecked(value); } }; - updateCheckBox(gridSnap, sketchView->GridSnap); - updateCheckBox(gridAutoSpacing, sketchView->GridAuto); + auto updateCheckBoxFromProperty = [updateCheckBox](QCheckBox * checkbox, App::PropertyBool & property) { + auto propvalue = property.getValue(); + + updateCheckBox(checkbox, propvalue); + }; + + updateCheckBox(gridSnap, sketchView->getSnapMode() == SnapMode::SnapToGrid); + + updateCheckBoxFromProperty(gridAutoSpacing, sketchView->GridAuto); auto autospacing = gridAutoSpacing->checkState() == Qt::Checked; @@ -1001,34 +1009,30 @@ public: void languageChange() { - gridSnap->setText(QApplication::translate("GridSpaceAction", "Grid Snap")); - gridSnap->setToolTip(QApplication::translate("GridSpaceAction", "New points will snap to the nearest grid line.\nPoints must be set closer than a fifth of the grid spacing to a grid line to snap.")); + gridSnap->setText(tr("Grid Snap")); + gridSnap->setToolTip(tr("New points will snap to the nearest grid line.\nPoints must be set closer than a fifth of the grid spacing to a grid line to snap.")); gridSnap->setStatusTip(gridSnap->toolTip()); - gridAutoSpacing->setText(QApplication::translate("GridSpaceAction", "Grid Auto Spacing")); - gridAutoSpacing->setToolTip(QApplication::translate("GridSpaceAction", "Resize grid automatically depending on zoom.")); + gridAutoSpacing->setText(tr("Grid Auto Spacing")); + gridAutoSpacing->setToolTip(tr("Resize grid automatically depending on zoom.")); gridAutoSpacing->setStatusTip(gridAutoSpacing->toolTip()); - sizeLabel->setText(QApplication::translate("GridSpaceAction", "Spacing")); - gridSizeBox->setToolTip(QApplication::translate("GridSpaceAction", "Distance between two subsequent grid lines")); + sizeLabel->setText(tr("Spacing")); + gridSizeBox->setToolTip(tr("Distance between two subsequent grid lines")); } protected: QWidget* createWidget(QWidget* parent) override { - gridSnap = new QCheckBox(QApplication::translate("GridSpaceAction", "Grid Snap")); - gridSnap->setToolTip(QApplication::translate("GridSpaceAction", "New points will snap to the nearest grid line.\nPoints must be set closer than a fifth of the grid spacing to a grid line to snap.")); - gridSnap->setStatusTip(gridSnap->toolTip()); + gridSnap = new QCheckBox(); - gridAutoSpacing = new QCheckBox(QApplication::translate("GridSpaceAction", "Grid Auto Spacing")); - gridAutoSpacing->setToolTip(QApplication::translate("GridSpaceAction", "Resize grid automatically depending on zoom.")); - gridAutoSpacing->setStatusTip(gridAutoSpacing->toolTip()); + gridAutoSpacing = new QCheckBox(); + + sizeLabel = new QLabel(); - sizeLabel = new QLabel(QApplication::translate("GridSpaceAction", "Spacing")); gridSizeBox = new Gui::QuantitySpinBox(); gridSizeBox->setProperty("unit", QVariant(QStringLiteral("mm"))); gridSizeBox->setObjectName(QStringLiteral("gridSize")); - gridSizeBox->setToolTip(QApplication::translate("GridSpaceAction", "Distance between two subsequent grid lines")); gridSizeBox->setMaximum(99999999.0); gridSizeBox->setMinimum(0.001); @@ -1039,14 +1043,23 @@ protected: layout->addWidget(sizeLabel, 2, 0); layout->addWidget(gridSizeBox, 2, 1); - QObject::connect(gridSnap,&QCheckBox::stateChanged, [this](int state) { + languageChange(); + + QObject::connect(gridSnap, &QCheckBox::stateChanged, [this](int state) { auto* sketchView = getView(); + if(sketchView) { - sketchView->GridSnap.setValue(state == Qt::Checked); + if(state == Qt::Checked) { + sketchView->setSnapMode(SnapMode::SnapToGrid); + } + else { + sketchView->setSnapMode(SnapMode::None); + } } }); - QObject::connect(gridAutoSpacing,&QCheckBox::stateChanged, [this](int state) { + + QObject::connect(gridAutoSpacing, &QCheckBox::stateChanged, [this](int state) { auto* sketchView = getView(); if(sketchView) { diff --git a/src/Mod/Sketcher/Gui/PreCompiled.h b/src/Mod/Sketcher/Gui/PreCompiled.h index 050c664bd6..01322f9cb4 100644 --- a/src/Mod/Sketcher/Gui/PreCompiled.h +++ b/src/Mod/Sketcher/Gui/PreCompiled.h @@ -73,6 +73,8 @@ # include #endif +#include + // all of Inventor #ifndef __InventorAll__ # include diff --git a/src/Mod/Sketcher/Gui/SketcherSettings.cpp b/src/Mod/Sketcher/Gui/SketcherSettings.cpp index 49c7329669..fcb982e4b2 100644 --- a/src/Mod/Sketcher/Gui/SketcherSettings.cpp +++ b/src/Mod/Sketcher/Gui/SketcherSettings.cpp @@ -149,7 +149,6 @@ void SketcherSettingsGrid::saveSettings() { ui->checkBoxShowGrid->onSave(); ui->gridSize->onSave(); - ui->checkBoxGridSnap->onSave(); ui->checkBoxGridAuto->onSave(); ui->gridSizePixelThreshold->onSave(); ui->gridLineColor->onSave(); @@ -172,7 +171,6 @@ void SketcherSettingsGrid::loadSettings() { ui->checkBoxShowGrid->onRestore(); ui->gridSize->onRestore(); - ui->checkBoxGridSnap->onRestore(); ui->checkBoxGridAuto->onRestore(); ui->gridSizePixelThreshold->onRestore(); ui->gridLineColor->onRestore(); diff --git a/src/Mod/Sketcher/Gui/SketcherSettingsGrid.ui b/src/Mod/Sketcher/Gui/SketcherSettingsGrid.ui index 26e2065ffd..99e311bca2 100644 --- a/src/Mod/Sketcher/Gui/SketcherSettingsGrid.ui +++ b/src/Mod/Sketcher/Gui/SketcherSettingsGrid.ui @@ -49,26 +49,6 @@ - - - true - - - New points will snap to the nearest grid line. -Points must be set closer than a fifth of the grid spacing to a grid line to snap. - - - Grid snap - - - GridSnap - - - Mod/Sketcher/General - - - - true @@ -87,7 +67,7 @@ Points must be set closer than a fifth of the grid spacing to a grid line to sna - + Grid spacing @@ -97,7 +77,7 @@ Points must be set closer than a fifth of the grid spacing to a grid line to sna - + Distance between two subsequent grid lines @@ -128,7 +108,7 @@ Points must be set closer than a fifth of the grid spacing to a grid line to sna - + Pixel size threshold @@ -138,7 +118,7 @@ Points must be set closer than a fifth of the grid spacing to a grid line to sna - + While using 'Grid Auto Spacing' this sets a threshold in pixel to the grid spacing. The grid spacing change if it becomes smaller than this number of pixel. diff --git a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp index 1c3cf6cb67..45db1d527c 100644 --- a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp +++ b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp @@ -220,14 +220,6 @@ void ViewProviderSketch::ParameterObserver::initParameters() {[this](const std::string & string, App::Property * property){ updateBoolProperty(string, property, true);}, &Client.Autoconstraints }}, {"AvoidRedundantAutoconstraints", {[this](const std::string & string, App::Property * property){ updateBoolProperty(string, property, true);}, &Client.AvoidRedundant }}, - {"ShowGrid", - {[this](const std::string & string, App::Property * property){ updateBoolProperty(string, property, false);}, &Client.ShowGrid }}, - {"GridSnap", - {[this](const std::string & string, App::Property * property){ updateBoolProperty(string, property, false);}, &Client.GridSnap }}, - {"GridAuto", - {[this](const std::string & string, App::Property * property){ updateBoolProperty(string, property, true); }, &Client.GridAuto }}, - {"GridSize", - {[this](const std::string & string, App::Property * property){ updateGridSize(string, property);}, &Client.GridSize }}, {"SketchEdgeColor", {[this](const std::string & string, App::Property * property){ updateColorProperty(string, property, 1.f, 1.f, 1.f);}, &Client.LineColor }}, {"SketchVertexColor", @@ -251,9 +243,15 @@ void ViewProviderSketch::ParameterObserver::initParameters() {"GridDivLineWidth", {[this](const std::string & string, [[maybe_unused]] App::Property * property){ auto v = getSketcherGeneralParameter(string, 2); Client.setGridDivLineWidth(v); }, nullptr }}, {"GridLineColor", - {[this, packedDefaultGridColor](const std::string & string, [[maybe_unused]] App::Property * property){ auto v = getSketcherGeneralParameter(string, packedDefaultGridColor); Client.setGridLineColor(v); }, nullptr }}, + {[this, packedDefaultGridColor](const std::string & string, [[maybe_unused]] App::Property * property){ + auto v = getSketcherGeneralParameter(string, packedDefaultGridColor); + auto color = App::Color(v); + Client.setGridLineColor(color);}, nullptr }}, {"GridDivLineColor", - {[this, packedDefaultGridColor](const std::string & string, [[maybe_unused]] App::Property * property){ auto v = getSketcherGeneralParameter(string, packedDefaultGridColor); Client.setGridDivLineColor(v); }, nullptr }}, + {[this, packedDefaultGridColor](const std::string & string, [[maybe_unused]] App::Property * property){ + auto v = getSketcherGeneralParameter(string, packedDefaultGridColor); + auto color = App::Color(v); + Client.setGridDivLineColor(color);}, nullptr }}, }; for( auto & val : parameterMap){ @@ -263,6 +261,11 @@ void ViewProviderSketch::ParameterObserver::initParameters() update(string, property); } + + // unsubscribed parameters which update a property on just once upon construction (and before restore if properties are being restored from a file) + updateBoolProperty("ShowGrid", &Client.ShowGrid, false); + updateBoolProperty("GridAuto", &Client.GridAuto, true); + updateGridSize("GridSize", &Client.GridSize); } void ViewProviderSketch::ParameterObserver::OnChange(Base::Subject &rCaller, const char * sReason) @@ -538,30 +541,35 @@ bool ViewProviderSketch::keyPressed(bool pressed, int key) return true; // handle all other key events } -void ViewProviderSketch::snapToGrid(double &x, double &y) +void ViewProviderSketch::setSnapMode(SnapMode mode) { - if (GridSnap.getValue() && ShowGrid.getValue()) { + snapMode = mode; // to be redirected to SnapManager +} + +SnapMode ViewProviderSketch::getSnapMode() const +{ + return snapMode; // to be redirected to SnapManager +} + +void ViewProviderSketch::snapToGrid(double &x, double &y) // Paddle, when resolving this conflict, make sure to use the function in ViewProviderGridExtension +{ + if (snapMode == SnapMode::SnapToGrid && ShowGrid.getValue()) { // Snap Tolerance in pixels - const double snapTol = GridSize.getValue() / 5; + const double snapTol = getGridSize() / 5; double tmpX = x, tmpY = y; - // Find Nearest Snap points - tmpX = tmpX / GridSize.getValue(); - tmpX = tmpX < 0.0 ? ceil(tmpX - 0.5) : floor(tmpX + 0.5); - tmpX *= GridSize.getValue(); - - tmpY = tmpY / GridSize.getValue(); - tmpY = tmpY < 0.0 ? ceil(tmpY - 0.5) : floor(tmpY + 0.5); - tmpY *= GridSize.getValue(); + getClosestGridPoint(tmpX, tmpY); // Check if x within snap tolerance - if (x < tmpX + snapTol && x > tmpX - snapTol) + if (x < tmpX + snapTol && x > tmpX - snapTol) { x = tmpX; // Snap X Mouse Position + } // Check if y within snap tolerance - if (y < tmpY + snapTol && y > tmpY - snapTol) + if (y < tmpY + snapTol && y > tmpY - snapTol) { y = tmpY; // Snap Y Mouse Position + } } } diff --git a/src/Mod/Sketcher/Gui/ViewProviderSketch.h b/src/Mod/Sketcher/Gui/ViewProviderSketch.h index e7b8de613e..f287ab070b 100644 --- a/src/Mod/Sketcher/Gui/ViewProviderSketch.h +++ b/src/Mod/Sketcher/Gui/ViewProviderSketch.h @@ -85,6 +85,13 @@ namespace SketcherGui { class EditModeCoinManager; class DrawSketchHandler; +enum class SnapMode { // to be moved to SnapManager + None, + SnapToObject, + SnapToAngle, + SnapToGrid, +}; + using GeoList = Sketcher::GeoList; using GeoListFacade = Sketcher::GeoListFacade; @@ -474,6 +481,9 @@ public: void onSelectionChanged(const Gui::SelectionChanges& msg) override; //@} + void setSnapMode(SnapMode mode); + SnapMode getSnapMode() const; + /** @name Access to Sketch and Solver objects */ //@{ /// get the pointer to the sketch document object @@ -779,6 +789,8 @@ private: SoNodeSensor cameraSensor; int viewOrientationFactor; // stores if sketch viewed from front or back + + SnapMode snapMode = SnapMode::None; // temporary - to be moved to SnapManager }; } // namespace PartGui