Sketcher: Snap: initial implementation: - creation of SnapManager class. - Move grid snap to this new class. - Add snap to object. - Add snap at angle.
This commit is contained in:
@@ -995,7 +995,7 @@ public:
|
||||
updateCheckBox(checkbox, propvalue);
|
||||
};
|
||||
|
||||
updateCheckBox(gridSnap, sketchView->getSnapMode() == SnapMode::SnapToGrid);
|
||||
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher/General");
|
||||
|
||||
updateCheckBoxFromProperty(gridAutoSpacing, sketchView->GridAuto);
|
||||
|
||||
@@ -1005,10 +1005,6 @@ public:
|
||||
|
||||
void languageChange()
|
||||
{
|
||||
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(tr("Grid Auto Spacing"));
|
||||
gridAutoSpacing->setToolTip(tr("Resize grid automatically depending on zoom."));
|
||||
gridAutoSpacing->setStatusTip(gridAutoSpacing->toolTip());
|
||||
@@ -1020,8 +1016,6 @@ public:
|
||||
protected:
|
||||
QWidget* createWidget(QWidget* parent) override
|
||||
{
|
||||
gridSnap = new QCheckBox();
|
||||
|
||||
gridAutoSpacing = new QCheckBox();
|
||||
|
||||
sizeLabel = new QLabel();
|
||||
@@ -1034,27 +1028,12 @@ protected:
|
||||
|
||||
QWidget* gridSizeW = new QWidget(parent);
|
||||
auto* layout = new QGridLayout(gridSizeW);
|
||||
layout->addWidget(gridSnap, 0, 0);
|
||||
layout->addWidget(gridAutoSpacing, 1, 0);
|
||||
layout->addWidget(sizeLabel, 2, 0);
|
||||
layout->addWidget(gridSizeBox, 2, 1);
|
||||
layout->addWidget(gridAutoSpacing, 0, 0, 1, 2);
|
||||
layout->addWidget(sizeLabel, 1, 0);
|
||||
layout->addWidget(gridSizeBox, 1, 1);
|
||||
|
||||
languageChange();
|
||||
|
||||
QObject::connect(gridSnap, &QCheckBox::stateChanged, [this](int state) {
|
||||
auto* sketchView = getView();
|
||||
|
||||
if(sketchView) {
|
||||
if(state == Qt::Checked) {
|
||||
sketchView->setSnapMode(SnapMode::SnapToGrid);
|
||||
}
|
||||
else {
|
||||
sketchView->setSnapMode(SnapMode::None);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
QObject::connect(gridAutoSpacing, &QCheckBox::stateChanged, [this](int state) {
|
||||
auto* sketchView = getView();
|
||||
|
||||
@@ -1086,7 +1065,6 @@ private:
|
||||
}
|
||||
|
||||
private:
|
||||
QCheckBox * gridSnap;
|
||||
QCheckBox * gridAutoSpacing;
|
||||
QLabel * sizeLabel;
|
||||
Gui::QuantitySpinBox * gridSizeBox;
|
||||
@@ -1213,6 +1191,250 @@ bool CmdSketcherGrid::isActive()
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Snap tool */
|
||||
class SnapSpaceAction : public QWidgetAction
|
||||
{
|
||||
public:
|
||||
SnapSpaceAction(QObject* parent) : QWidgetAction(parent) {
|
||||
setEnabled(false);
|
||||
}
|
||||
|
||||
void updateWidget() {
|
||||
|
||||
auto* sketchView = getView();
|
||||
|
||||
if (sketchView) {
|
||||
|
||||
auto updateCheckBox = [](QCheckBox* checkbox, bool value) {
|
||||
auto checked = checkbox->checkState() == Qt::Checked;
|
||||
|
||||
if (value != checked) {
|
||||
const QSignalBlocker blocker(checkbox);
|
||||
checkbox->setChecked(value);
|
||||
}
|
||||
};
|
||||
|
||||
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher/General");
|
||||
|
||||
updateCheckBox(snapToObjects, hGrp->GetBool("SnapToObjects", true));
|
||||
|
||||
updateCheckBox(snapToGrid, hGrp->GetBool("SnapToGrid", false));
|
||||
|
||||
snapAngle->setValue(hGrp->GetFloat("SnapAngle", 5.0));
|
||||
|
||||
bool snapActivated = hGrp->GetBool("Snap", true);
|
||||
snapToObjects->setEnabled(snapActivated);
|
||||
snapToGrid->setEnabled(snapActivated);
|
||||
angleLabel->setEnabled(snapActivated);
|
||||
snapAngle->setEnabled(snapActivated);
|
||||
}
|
||||
}
|
||||
|
||||
void languageChange()
|
||||
{
|
||||
|
||||
snapToObjects->setText(tr("Snap to objects"));
|
||||
snapToObjects->setToolTip(tr("New points will snap to the currently preselected object. It will also snap to the middle of lines and arcs."));
|
||||
snapToObjects->setStatusTip(snapToObjects->toolTip());
|
||||
|
||||
snapToGrid->setText(tr("Snap to Grid"));
|
||||
snapToGrid->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."));
|
||||
snapToGrid->setStatusTip(snapToGrid->toolTip());
|
||||
|
||||
angleLabel->setText(tr("Snap angle"));
|
||||
snapAngle->setToolTip(tr("Angular step for tools that use 'Snap at Angle' (line for instance). Hold CTRL to enable 'Snap at Angle'. The angle start from the East axis (horizontal right)"));
|
||||
}
|
||||
|
||||
protected:
|
||||
QWidget* createWidget(QWidget* parent) override
|
||||
{
|
||||
snapToObjects = new QCheckBox();
|
||||
|
||||
snapToGrid = new QCheckBox();
|
||||
|
||||
angleLabel = new QLabel();
|
||||
|
||||
snapAngle = new Gui::QuantitySpinBox();
|
||||
snapAngle->setProperty("unit", QVariant(QStringLiteral("deg")));
|
||||
snapAngle->setObjectName(QStringLiteral("snapAngle"));
|
||||
snapAngle->setMaximum(99999999.0);
|
||||
snapAngle->setMinimum(0);
|
||||
|
||||
QWidget* snapW = new QWidget(parent);
|
||||
auto* layout = new QGridLayout(snapW);
|
||||
layout->addWidget(snapToGrid, 0, 0, 1, 2);
|
||||
layout->addWidget(snapToObjects, 1, 0, 1, 2);
|
||||
layout->addWidget(angleLabel, 2, 0);
|
||||
layout->addWidget(snapAngle, 2, 1);
|
||||
|
||||
languageChange();
|
||||
|
||||
QObject::connect(snapToObjects, &QCheckBox::stateChanged, [this](int state) {
|
||||
auto* sketchView = getView();
|
||||
|
||||
if (sketchView) {
|
||||
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher/General");
|
||||
hGrp->SetBool("SnapToObjects", state == Qt::Checked);
|
||||
}
|
||||
});
|
||||
|
||||
QObject::connect(snapToGrid, &QCheckBox::stateChanged, [this](int state) {
|
||||
auto* sketchView = getView();
|
||||
if (sketchView) {
|
||||
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher/General");
|
||||
hGrp->SetBool("SnapToGrid", state == Qt::Checked);
|
||||
}
|
||||
});
|
||||
|
||||
QObject::connect(snapAngle, qOverload<double>(&Gui::QuantitySpinBox::valueChanged), [this](double val) {
|
||||
auto* sketchView = getView();
|
||||
|
||||
if (sketchView) {
|
||||
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher/General");
|
||||
hGrp->SetFloat("SnapAngle", val);
|
||||
}
|
||||
});
|
||||
|
||||
return snapW;
|
||||
}
|
||||
|
||||
private:
|
||||
ViewProviderSketch* getView() {
|
||||
Gui::Document* doc = Gui::Application::Instance->activeDocument();
|
||||
|
||||
if (doc) {
|
||||
return dynamic_cast<SketcherGui::ViewProviderSketch*>(doc->getInEdit());
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
QCheckBox* snapToObjects;
|
||||
QCheckBox* snapToGrid;
|
||||
QLabel* angleLabel;
|
||||
Gui::QuantitySpinBox* snapAngle;
|
||||
};
|
||||
|
||||
class CmdSketcherSnap : public Gui::Command
|
||||
{
|
||||
public:
|
||||
CmdSketcherSnap();
|
||||
virtual ~CmdSketcherSnap() {}
|
||||
virtual const char* className() const
|
||||
{
|
||||
return "CmdSketcherSnap";
|
||||
}
|
||||
virtual void languageChange();
|
||||
protected:
|
||||
virtual void activated(int iMsg);
|
||||
virtual bool isActive(void);
|
||||
virtual Gui::Action* createAction(void);
|
||||
private:
|
||||
void updateIcon(bool value);
|
||||
|
||||
CmdSketcherSnap(const CmdSketcherSnap&) = delete;
|
||||
CmdSketcherSnap(CmdSketcherSnap&&) = delete;
|
||||
CmdSketcherSnap& operator= (const CmdSketcherSnap&) = delete;
|
||||
CmdSketcherSnap& operator= (CmdSketcherSnap&&) = delete;
|
||||
};
|
||||
|
||||
CmdSketcherSnap::CmdSketcherSnap()
|
||||
: Command("Sketcher_Snap")
|
||||
{
|
||||
sAppModule = "Sketcher";
|
||||
sGroup = "Sketcher";
|
||||
sMenuText = QT_TR_NOOP("Toggle Snap");
|
||||
sToolTipText = QT_TR_NOOP("Toggle all snapping functionalities. In the menu you can toggle individually 'Snap to Grid', 'Snap to Objects' and further snap settings");
|
||||
sWhatsThis = "Sketcher_Snap";
|
||||
sStatusTip = sToolTipText;
|
||||
eType = 0;
|
||||
}
|
||||
|
||||
void CmdSketcherSnap::updateIcon(bool value)
|
||||
{
|
||||
static QIcon active = Gui::BitmapFactory().iconFromTheme("Sketcher_Snap");
|
||||
static QIcon inactive = Gui::BitmapFactory().iconFromTheme("Sketcher_Snap_Deactivated");
|
||||
|
||||
auto* pcAction = qobject_cast<Gui::ActionGroup*>(getAction());
|
||||
pcAction->setIcon(value ? active : inactive);
|
||||
}
|
||||
|
||||
void CmdSketcherSnap::activated(int iMsg)
|
||||
{
|
||||
Q_UNUSED(iMsg);
|
||||
|
||||
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher/General");
|
||||
bool value = !hGrp->GetBool("Snap", true);
|
||||
|
||||
hGrp->SetBool("Snap", value);
|
||||
|
||||
updateIcon(value);
|
||||
|
||||
//Update the widget :
|
||||
if (!_pcAction)
|
||||
return;
|
||||
|
||||
Gui::ActionGroup* pcAction = qobject_cast<Gui::ActionGroup*>(_pcAction);
|
||||
QList<QAction*> a = pcAction->actions();
|
||||
|
||||
auto* ssa = static_cast<SnapSpaceAction*>(a[0]);
|
||||
ssa->updateWidget();
|
||||
}
|
||||
|
||||
Gui::Action* CmdSketcherSnap::createAction()
|
||||
{
|
||||
auto* pcAction = new Gui::ActionGroup(this, Gui::getMainWindow());
|
||||
pcAction->setDropDownMenu(true);
|
||||
pcAction->setExclusive(false);
|
||||
applyCommandData(this->className(), pcAction);
|
||||
|
||||
SnapSpaceAction* ssa = new SnapSpaceAction(pcAction);
|
||||
pcAction->addAction(ssa);
|
||||
|
||||
_pcAction = pcAction;
|
||||
|
||||
QObject::connect(pcAction, &Gui::ActionGroup::aboutToShow, [ssa](QMenu* menu) {
|
||||
Q_UNUSED(menu)
|
||||
ssa->updateWidget();
|
||||
});
|
||||
|
||||
// set the right pixmap
|
||||
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher/General");
|
||||
updateIcon(hGrp->GetBool("Snap", true));
|
||||
|
||||
return pcAction;
|
||||
}
|
||||
|
||||
void CmdSketcherSnap::languageChange()
|
||||
{
|
||||
Command::languageChange();
|
||||
|
||||
if (!_pcAction)
|
||||
return;
|
||||
|
||||
Gui::ActionGroup* pcAction = qobject_cast<Gui::ActionGroup*>(_pcAction);
|
||||
QList<QAction*> a = pcAction->actions();
|
||||
|
||||
auto* ssa = static_cast<SnapSpaceAction*>(a[0]);
|
||||
ssa->languageChange();
|
||||
}
|
||||
|
||||
bool CmdSketcherSnap::isActive()
|
||||
{
|
||||
auto* vp = getInactiveHandlerEditModeSketchViewProvider();
|
||||
|
||||
if (vp) {
|
||||
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher/General");
|
||||
bool value = hGrp->GetBool("Snap", true);
|
||||
|
||||
updateIcon(value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CreateSketcherCommands()
|
||||
{
|
||||
@@ -1230,4 +1452,5 @@ void CreateSketcherCommands()
|
||||
rcCmdMgr.addCommand(new CmdSketcherMergeSketches());
|
||||
rcCmdMgr.addCommand(new CmdSketcherViewSection());
|
||||
rcCmdMgr.addCommand(new CmdSketcherGrid());
|
||||
rcCmdMgr.addCommand(new CmdSketcherSnap());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user