Merge pull request #13525 from Ondsel-Development/td_dimension
TechDraw: Smart dimension tool
This commit is contained in:
@@ -1217,6 +1217,7 @@ SET(FreeCADGui_CPP_SRCS
|
||||
ManualAlignment.cpp
|
||||
StartupProcess.cpp
|
||||
TransactionObject.cpp
|
||||
ToolHandler.cpp
|
||||
)
|
||||
SET(FreeCADGui_SRCS
|
||||
Application.h
|
||||
@@ -1254,6 +1255,7 @@ SET(FreeCADGui_SRCS
|
||||
ManualAlignment.h
|
||||
StartupProcess.h
|
||||
TransactionObject.h
|
||||
ToolHandler.h
|
||||
${FreeCADGui_SDK_MOC_HDRS}
|
||||
)
|
||||
|
||||
|
||||
288
src/Gui/ToolHandler.cpp
Normal file
288
src/Gui/ToolHandler.cpp
Normal file
@@ -0,0 +1,288 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Pierre-Louis Boyer <development@ondsel.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 *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
#include <cmath>
|
||||
|
||||
#include <QGuiApplication>
|
||||
#include <QPainter>
|
||||
|
||||
#include <Inventor/events/SoKeyboardEvent.h>
|
||||
#endif // #ifndef _PreComp_
|
||||
|
||||
#include <Base/Console.h>
|
||||
#include <Base/Exception.h>
|
||||
|
||||
#include "Application.h"
|
||||
#include "BitmapFactory.h"
|
||||
#include "CommandT.h"
|
||||
#include "MainWindow.h"
|
||||
#include "View3DInventor.h"
|
||||
#include "View3DInventorViewer.h"
|
||||
|
||||
#include "ToolHandler.h"
|
||||
|
||||
using namespace Gui;
|
||||
|
||||
/**************************** ToolHandler *******************************************/
|
||||
|
||||
QString ToolHandler::getCrosshairCursorSVGName() const
|
||||
{
|
||||
return QString::fromLatin1("None");
|
||||
}
|
||||
|
||||
bool ToolHandler::activate()
|
||||
{
|
||||
// save the cursor at the time the DSH is activated
|
||||
QWidget* cw = getCursorWidget();
|
||||
if (cw) {
|
||||
oldCursor = cw->cursor();
|
||||
|
||||
updateCursor();
|
||||
|
||||
this->preActivated();
|
||||
this->activated();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ToolHandler::deactivate()
|
||||
{
|
||||
this->deactivated();
|
||||
this->postDeactivated();
|
||||
|
||||
unsetCursor();
|
||||
}
|
||||
|
||||
//**************************************************************************
|
||||
// Helpers
|
||||
|
||||
unsigned long ToolHandler::getCrosshairColor()
|
||||
{
|
||||
unsigned long color = 0xFFFFFFFF; // white
|
||||
ParameterGrp::handle hGrp =
|
||||
App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
|
||||
color = hGrp->GetUnsigned("CursorCrosshairColor", color);
|
||||
// from rgba to rgb
|
||||
color = (color >> 8) & 0xFFFFFF;
|
||||
return color;
|
||||
}
|
||||
|
||||
void ToolHandler::setCrosshairCursor(const QString& svgName)
|
||||
{
|
||||
const unsigned long defaultCrosshairColor = 0xFFFFFF;
|
||||
unsigned long color = getCrosshairColor();
|
||||
auto colorMapping = std::map<unsigned long, unsigned long>();
|
||||
colorMapping[defaultCrosshairColor] = color;
|
||||
// hot spot of all SVG icons should be 8,8 for 32x32 size (16x16 for 64x64)
|
||||
int hotX = 8;
|
||||
int hotY = 8;
|
||||
setSvgCursor(svgName, hotX, hotY, colorMapping);
|
||||
}
|
||||
|
||||
void ToolHandler::setCrosshairCursor(const char* svgName)
|
||||
{
|
||||
QString cursorName = QString::fromLatin1(svgName);
|
||||
setCrosshairCursor(cursorName);
|
||||
}
|
||||
|
||||
void ToolHandler::setSvgCursor(const QString& cursorName,
|
||||
int x,
|
||||
int y,
|
||||
const std::map<unsigned long, unsigned long>& colorMapping)
|
||||
{
|
||||
// The TechDraw_Pointer_*.svg icons have a default size of 64x64. When directly creating
|
||||
// them with a size of 32x32 they look very bad.
|
||||
// As a workaround the icons are created with 64x64 and afterwards the pixmap is scaled to
|
||||
// 32x32. This workaround is only needed if pRatio is equal to 1.0
|
||||
//
|
||||
qreal pRatio = devicePixelRatio();
|
||||
bool isRatioOne = (pRatio == 1.0);
|
||||
qreal defaultCursorSize = isRatioOne ? 64 : 32;
|
||||
qreal hotX = x;
|
||||
qreal hotY = y;
|
||||
#if !defined(Q_OS_WIN32) && !defined(Q_OS_MAC)
|
||||
if (qGuiApp->platformName() == QLatin1String("xcb")) {
|
||||
hotX *= pRatio;
|
||||
hotY *= pRatio;
|
||||
}
|
||||
#endif
|
||||
qreal cursorSize = defaultCursorSize * pRatio;
|
||||
|
||||
QPixmap pointer = Gui::BitmapFactory().pixmapFromSvg(cursorName.toStdString().c_str(),
|
||||
QSizeF(cursorSize, cursorSize),
|
||||
colorMapping);
|
||||
if (isRatioOne) {
|
||||
pointer = pointer.scaled(32, 32);
|
||||
}
|
||||
pointer.setDevicePixelRatio(pRatio);
|
||||
setCursor(pointer, hotX, hotY, false);
|
||||
}
|
||||
|
||||
void ToolHandler::setCursor(const QPixmap& p, int x, int y, bool autoScale)
|
||||
{
|
||||
|
||||
QWidget* cw = getCursorWidget();
|
||||
if (cw) {
|
||||
QCursor cursor;
|
||||
QPixmap p1(p);
|
||||
// TODO remove autoScale after all cursors are SVG-based
|
||||
if (autoScale) {
|
||||
qreal pRatio = devicePixelRatio();
|
||||
int newWidth = p.width() * pRatio;
|
||||
int newHeight = p.height() * pRatio;
|
||||
p1 = p1.scaled(newWidth, newHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
p1.setDevicePixelRatio(pRatio);
|
||||
qreal hotX = x;
|
||||
qreal hotY = y;
|
||||
#if !defined(Q_OS_WIN32) && !defined(Q_OS_MAC)
|
||||
if (qGuiApp->platformName() == QLatin1String("xcb")) {
|
||||
hotX *= pRatio;
|
||||
hotY *= pRatio;
|
||||
}
|
||||
#endif
|
||||
cursor = QCursor(p1, hotX, hotY);
|
||||
}
|
||||
else {
|
||||
// already scaled
|
||||
cursor = QCursor(p1, x, y);
|
||||
}
|
||||
|
||||
actCursor = cursor;
|
||||
actCursorPixmap = p1;
|
||||
|
||||
setWidgetCursor(cursor);
|
||||
}
|
||||
}
|
||||
|
||||
void ToolHandler::addCursorTail(std::vector<QPixmap>& pixmaps)
|
||||
{
|
||||
// Create a pixmap that will contain icon and each autoconstraint icon
|
||||
QPixmap baseIcon = QPixmap(actCursorPixmap);
|
||||
baseIcon.setDevicePixelRatio(actCursorPixmap.devicePixelRatio());
|
||||
qreal pixelRatio = baseIcon.devicePixelRatio();
|
||||
// cursor size in device independent pixels
|
||||
qreal baseCursorWidth = baseIcon.width();
|
||||
qreal baseCursorHeight = baseIcon.height();
|
||||
|
||||
int tailWidth = 0;
|
||||
for (auto const& p : pixmaps) {
|
||||
tailWidth += p.width();
|
||||
}
|
||||
|
||||
int newIconWidth = baseCursorWidth + tailWidth;
|
||||
int newIconHeight = baseCursorHeight;
|
||||
|
||||
QPixmap newIcon(newIconWidth, newIconHeight);
|
||||
newIcon.fill(Qt::transparent);
|
||||
|
||||
QPainter qp;
|
||||
qp.begin(&newIcon);
|
||||
|
||||
qp.drawPixmap(QPointF(0, 0),
|
||||
baseIcon.scaled(baseCursorWidth * pixelRatio,
|
||||
baseCursorHeight * pixelRatio,
|
||||
Qt::KeepAspectRatio,
|
||||
Qt::SmoothTransformation));
|
||||
|
||||
// Iterate through pixmaps and them to the cursor pixmap
|
||||
qreal currentIconX = baseCursorWidth;
|
||||
qreal currentIconY;
|
||||
|
||||
for (auto& icon : pixmaps) {
|
||||
currentIconY = baseCursorHeight - icon.height();
|
||||
qp.drawPixmap(QPointF(currentIconX, currentIconY), icon);
|
||||
currentIconX += icon.width();
|
||||
}
|
||||
|
||||
qp.end(); // Finish painting
|
||||
|
||||
// Create the new cursor with the icon.
|
||||
QPoint p = actCursor.hotSpot();
|
||||
newIcon.setDevicePixelRatio(pixelRatio);
|
||||
QCursor newCursor(newIcon, p.x(), p.y());
|
||||
applyCursor(newCursor);
|
||||
}
|
||||
|
||||
void ToolHandler::updateCursor()
|
||||
{
|
||||
auto cursorstring = getCrosshairCursorSVGName();
|
||||
|
||||
if (cursorstring != QString::fromLatin1("None")) {
|
||||
setCrosshairCursor(cursorstring);
|
||||
}
|
||||
}
|
||||
|
||||
void ToolHandler::applyCursor()
|
||||
{
|
||||
applyCursor(actCursor);
|
||||
}
|
||||
|
||||
void ToolHandler::applyCursor(QCursor& newCursor)
|
||||
{
|
||||
setWidgetCursor(newCursor);
|
||||
}
|
||||
|
||||
void ToolHandler::unsetCursor()
|
||||
{
|
||||
setWidgetCursor(oldCursor);
|
||||
}
|
||||
|
||||
qreal ToolHandler::devicePixelRatio()
|
||||
{
|
||||
qreal pixelRatio = 1;
|
||||
|
||||
QWidget* cw = getCursorWidget();
|
||||
if (cw) {
|
||||
pixelRatio = cw->devicePixelRatio();
|
||||
}
|
||||
return pixelRatio;
|
||||
}
|
||||
|
||||
QWidget* ToolHandler::getCursorWidget()
|
||||
{
|
||||
Gui::View3DInventorViewer* viewer = getViewer();
|
||||
if (viewer) {
|
||||
return viewer->getWidget();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ToolHandler::setWidgetCursor(QCursor cursor)
|
||||
{
|
||||
QWidget* cw = getCursorWidget();
|
||||
if (cw) {
|
||||
cw->setCursor(cursor);
|
||||
}
|
||||
}
|
||||
|
||||
Gui::View3DInventorViewer* ToolHandler::getViewer()
|
||||
{
|
||||
Gui::MDIView* view = Gui::getMainWindow()->activeWindow();
|
||||
if (view && view->isDerivedFrom(Gui::View3DInventor::getClassTypeId())) {
|
||||
return static_cast<Gui::View3DInventor*>(view)->getViewer();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
127
src/Gui/ToolHandler.h
Normal file
127
src/Gui/ToolHandler.h
Normal file
@@ -0,0 +1,127 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Pierre-Louis Boyer <development@ondsel.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 GUI_ToolHandler_H
|
||||
#define GUI_ToolHandler_H
|
||||
|
||||
#include <QCursor>
|
||||
#include <QPixmap>
|
||||
|
||||
#include <Base/Parameter.h>
|
||||
#include <Base/Tools2D.h>
|
||||
|
||||
#include "Selection.h"
|
||||
|
||||
|
||||
namespace Gui
|
||||
{
|
||||
class View3DInventorViewer;
|
||||
|
||||
|
||||
class GuiExport ToolHandler
|
||||
{
|
||||
public:
|
||||
ToolHandler() = default;
|
||||
virtual ~ToolHandler() = default;
|
||||
|
||||
bool activate();
|
||||
virtual void deactivate();
|
||||
|
||||
virtual void quit()
|
||||
{}
|
||||
|
||||
/// updates the actCursor with the icon by calling getCrosshairCursorSVGName(),
|
||||
/// enabling to set data member dependent icons (i.e. for different construction methods)
|
||||
void updateCursor();
|
||||
|
||||
private: // NVI
|
||||
virtual void preActivated()
|
||||
{}
|
||||
virtual void activated()
|
||||
{}
|
||||
virtual void deactivated()
|
||||
{}
|
||||
virtual void postDeactivated()
|
||||
{}
|
||||
|
||||
protected: // NVI requiring base implementation
|
||||
virtual QString getCrosshairCursorSVGName() const;
|
||||
|
||||
|
||||
protected:
|
||||
// helpers
|
||||
/**
|
||||
* Sets a cursor for 3D inventor view.
|
||||
* pixmap as a cursor image in device independent pixels.
|
||||
*
|
||||
* \param autoScale - set this to false if pixmap already scaled for HiDPI
|
||||
**/
|
||||
|
||||
/** @name Icon helpers */
|
||||
//@{
|
||||
void setCursor(const QPixmap& pixmap, int x, int y, bool autoScale = true);
|
||||
|
||||
|
||||
void unsetCursor();
|
||||
|
||||
/// restitutes the DSH cached cursor (without any tail due to autoconstraints, ...)
|
||||
void applyCursor();
|
||||
|
||||
void addCursorTail(std::vector<QPixmap>& pixmaps);
|
||||
|
||||
/// returns the color to be used for the crosshair (configurable as a parameter)
|
||||
unsigned long getCrosshairColor();
|
||||
|
||||
/// functions to set the cursor to a given svgName (to be migrated to NVI style)
|
||||
|
||||
qreal devicePixelRatio();
|
||||
//@}
|
||||
|
||||
View3DInventorViewer* getViewer();
|
||||
|
||||
virtual QWidget* getCursorWidget();
|
||||
|
||||
virtual void setWidgetCursor(QCursor cursor);
|
||||
|
||||
private:
|
||||
void setSvgCursor(const QString& svgName, int x, int y,
|
||||
const std::map<unsigned long, unsigned long>& colorMapping =
|
||||
std::map<unsigned long, unsigned long>());
|
||||
|
||||
|
||||
void applyCursor(QCursor& newCursor);
|
||||
|
||||
void setCrosshairCursor(const QString& svgName);
|
||||
void setCrosshairCursor(const char* svgName);
|
||||
|
||||
protected:
|
||||
|
||||
QCursor oldCursor;
|
||||
QCursor actCursor;
|
||||
QPixmap actCursorPixmap;
|
||||
};
|
||||
|
||||
|
||||
} // namespace Gui
|
||||
|
||||
|
||||
#endif // GUI_ToolHandler_H
|
||||
@@ -1376,6 +1376,7 @@ public:
|
||||
, selLine({})
|
||||
, selCircleArc({})
|
||||
, selEllipseAndCo({})
|
||||
, selSplineAndCo({})
|
||||
, initialSelection(std::move(SubNames))
|
||||
, numberOfConstraintsCreated(0)
|
||||
{
|
||||
@@ -1616,6 +1617,15 @@ protected:
|
||||
|
||||
Sketcher::SketchObject* Obj;
|
||||
|
||||
void clearRefVectors()
|
||||
{
|
||||
selPoints.clear();
|
||||
selLine.clear();
|
||||
selCircleArc.clear();
|
||||
selEllipseAndCo.clear();
|
||||
selSplineAndCo.clear();
|
||||
}
|
||||
|
||||
void handleInitialSelection()
|
||||
{
|
||||
if (initialSelection.size() == 0) {
|
||||
@@ -1648,11 +1658,7 @@ protected:
|
||||
bool selAllowed = makeAppropriateConstraint(Base::Vector2d(0.,0.));
|
||||
|
||||
if (!selAllowed) {
|
||||
selPoints.clear();
|
||||
selLine.clear();
|
||||
selCircleArc.clear();
|
||||
selEllipseAndCo.clear();
|
||||
selSplineAndCo.clear();
|
||||
clearRefVectors();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1686,10 +1692,7 @@ protected:
|
||||
numberOfConstraintsCreated = 0;
|
||||
specialConstraint = SpecialConstraint::None;
|
||||
previousOnSketchPos = Base::Vector2d(0.f, 0.f);
|
||||
selPoints.clear();
|
||||
selLine.clear();
|
||||
selCircleArc.clear();
|
||||
selEllipseAndCo.clear();
|
||||
clearRefVectors();
|
||||
}
|
||||
else {
|
||||
sketchgui->purgeHandler(); // no code after this line, Handler get deleted in ViewProvider
|
||||
|
||||
@@ -270,7 +270,8 @@ void CurveConverter::OnChange(Base::Subject<const char*>& rCaller, const char* s
|
||||
// Construction/Destruction
|
||||
|
||||
DrawSketchHandler::DrawSketchHandler()
|
||||
: sketchgui(nullptr)
|
||||
: Gui::ToolHandler()
|
||||
, sketchgui(nullptr)
|
||||
{}
|
||||
|
||||
DrawSketchHandler::~DrawSketchHandler()
|
||||
@@ -281,11 +282,6 @@ std::string DrawSketchHandler::getToolName() const
|
||||
return "DSH_None";
|
||||
}
|
||||
|
||||
QString DrawSketchHandler::getCrosshairCursorSVGName() const
|
||||
{
|
||||
return QString::fromLatin1("None");
|
||||
}
|
||||
|
||||
std::unique_ptr<QWidget> DrawSketchHandler::createWidget() const
|
||||
{
|
||||
return nullptr;
|
||||
@@ -311,36 +307,20 @@ void DrawSketchHandler::activate(ViewProviderSketch* vp)
|
||||
{
|
||||
sketchgui = vp;
|
||||
|
||||
// save the cursor at the time the DSH is activated
|
||||
auto* view = dynamic_cast<Gui::View3DInventor*>(Gui::getMainWindow()->activeWindow());
|
||||
|
||||
if (view) {
|
||||
Gui::View3DInventorViewer* viewer = dynamic_cast<Gui::View3DInventor*>(view)->getViewer();
|
||||
oldCursor = viewer->getWidget()->cursor();
|
||||
|
||||
updateCursor();
|
||||
|
||||
this->signalToolChanged();
|
||||
|
||||
this->preActivated();
|
||||
this->activated();
|
||||
}
|
||||
else {
|
||||
if (!Gui::ToolHandler::activate()) {
|
||||
sketchgui->purgeHandler();
|
||||
}
|
||||
}
|
||||
|
||||
void DrawSketchHandler::deactivate()
|
||||
{
|
||||
this->deactivated();
|
||||
this->postDeactivated();
|
||||
Gui::ToolHandler::deactivate();
|
||||
ViewProviderSketchDrawSketchHandlerAttorney::setConstraintSelectability(*sketchgui, true);
|
||||
|
||||
// clear temporary Curve and Markers from the scenograph
|
||||
clearEdit();
|
||||
clearEditMarkers();
|
||||
resetPositionText();
|
||||
unsetCursor();
|
||||
setAngleSnapping(false);
|
||||
|
||||
ViewProviderSketchDrawSketchHandlerAttorney::signalToolChanged(*sketchgui, "DSH_None");
|
||||
@@ -348,25 +328,10 @@ void DrawSketchHandler::deactivate()
|
||||
|
||||
void DrawSketchHandler::preActivated()
|
||||
{
|
||||
this->signalToolChanged();
|
||||
ViewProviderSketchDrawSketchHandlerAttorney::setConstraintSelectability(*sketchgui, false);
|
||||
}
|
||||
|
||||
void DrawSketchHandler::quit()
|
||||
{
|
||||
assert(sketchgui);
|
||||
|
||||
Gui::Selection().rmvSelectionGate();
|
||||
Gui::Selection().rmvPreselect();
|
||||
|
||||
sketchgui->purgeHandler();
|
||||
}
|
||||
|
||||
void DrawSketchHandler::toolWidgetChanged(QWidget* newwidget)
|
||||
{
|
||||
toolwidget = newwidget;
|
||||
onWidgetChanged();
|
||||
}
|
||||
|
||||
void DrawSketchHandler::registerPressedKey(bool pressed, int key)
|
||||
{
|
||||
// the default behaviour is to quit - specific handler categories may
|
||||
@@ -383,6 +348,23 @@ void DrawSketchHandler::pressRightButton(Base::Vector2d /*onSketchPos*/)
|
||||
quit();
|
||||
}
|
||||
|
||||
|
||||
void DrawSketchHandler::quit()
|
||||
{
|
||||
assert(sketchgui);
|
||||
|
||||
Gui::Selection().rmvSelectionGate();
|
||||
Gui::Selection().rmvPreselect();
|
||||
|
||||
sketchgui->purgeHandler();
|
||||
}
|
||||
|
||||
void DrawSketchHandler::toolWidgetChanged(QWidget* newwidget)
|
||||
{
|
||||
toolwidget = newwidget;
|
||||
onWidgetChanged();
|
||||
}
|
||||
|
||||
//**************************************************************************
|
||||
// Helpers
|
||||
|
||||
@@ -396,198 +378,6 @@ int DrawSketchHandler::getHighestCurveIndex()
|
||||
return sketchgui->getSketchObject()->getHighestCurveIndex();
|
||||
}
|
||||
|
||||
unsigned long DrawSketchHandler::getCrosshairColor()
|
||||
{
|
||||
unsigned long color = 0xFFFFFFFF; // white
|
||||
ParameterGrp::handle hGrp =
|
||||
App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
|
||||
color = hGrp->GetUnsigned("CursorCrosshairColor", color);
|
||||
// from rgba to rgb
|
||||
color = (color >> 8) & 0xFFFFFF;
|
||||
return color;
|
||||
}
|
||||
|
||||
void DrawSketchHandler::setCrosshairCursor(const QString& svgName)
|
||||
{
|
||||
const unsigned long defaultCrosshairColor = 0xFFFFFF;
|
||||
unsigned long color = getCrosshairColor();
|
||||
auto colorMapping = std::map<unsigned long, unsigned long>();
|
||||
colorMapping[defaultCrosshairColor] = color;
|
||||
// hot spot of all SVG icons should be 8,8 for 32x32 size (16x16 for 64x64)
|
||||
int hotX = 8;
|
||||
int hotY = 8;
|
||||
setSvgCursor(svgName, hotX, hotY, colorMapping);
|
||||
}
|
||||
|
||||
void DrawSketchHandler::setCrosshairCursor(const char* svgName)
|
||||
{
|
||||
QString cursorName = QString::fromLatin1(svgName);
|
||||
setCrosshairCursor(cursorName);
|
||||
}
|
||||
|
||||
void DrawSketchHandler::setSvgCursor(const QString& cursorName,
|
||||
int x,
|
||||
int y,
|
||||
const std::map<unsigned long, unsigned long>& colorMapping)
|
||||
{
|
||||
// The Sketcher_Pointer_*.svg icons have a default size of 64x64. When directly creating
|
||||
// them with a size of 32x32 they look very bad.
|
||||
// As a workaround the icons are created with 64x64 and afterwards the pixmap is scaled to
|
||||
// 32x32. This workaround is only needed if pRatio is equal to 1.0
|
||||
//
|
||||
qreal pRatio = devicePixelRatio();
|
||||
bool isRatioOne = (pRatio == 1.0);
|
||||
qreal defaultCursorSize = isRatioOne ? 64 : 32;
|
||||
qreal hotX = x;
|
||||
qreal hotY = y;
|
||||
#if !defined(Q_OS_WIN32) && !defined(Q_OS_MAC)
|
||||
if (qGuiApp->platformName() == QLatin1String("xcb")) {
|
||||
hotX *= pRatio;
|
||||
hotY *= pRatio;
|
||||
}
|
||||
#endif
|
||||
qreal cursorSize = defaultCursorSize * pRatio;
|
||||
|
||||
QPixmap pointer = Gui::BitmapFactory().pixmapFromSvg(cursorName.toStdString().c_str(),
|
||||
QSizeF(cursorSize, cursorSize),
|
||||
colorMapping);
|
||||
if (isRatioOne) {
|
||||
pointer = pointer.scaled(32, 32);
|
||||
}
|
||||
pointer.setDevicePixelRatio(pRatio);
|
||||
setCursor(pointer, hotX, hotY, false);
|
||||
}
|
||||
|
||||
void DrawSketchHandler::setCursor(const QPixmap& p, int x, int y, bool autoScale)
|
||||
{
|
||||
Gui::View3DInventorViewer* viewer = getViewer();
|
||||
if (viewer) {
|
||||
QCursor cursor;
|
||||
QPixmap p1(p);
|
||||
// TODO remove autoScale after all cursors are SVG-based
|
||||
if (autoScale) {
|
||||
qreal pRatio = viewer->devicePixelRatio();
|
||||
int newWidth = p.width() * pRatio;
|
||||
int newHeight = p.height() * pRatio;
|
||||
p1 = p1.scaled(newWidth, newHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
p1.setDevicePixelRatio(pRatio);
|
||||
qreal hotX = x;
|
||||
qreal hotY = y;
|
||||
#if !defined(Q_OS_WIN32) && !defined(Q_OS_MAC)
|
||||
if (qGuiApp->platformName() == QLatin1String("xcb")) {
|
||||
hotX *= pRatio;
|
||||
hotY *= pRatio;
|
||||
}
|
||||
#endif
|
||||
cursor = QCursor(p1, hotX, hotY);
|
||||
}
|
||||
else {
|
||||
// already scaled
|
||||
cursor = QCursor(p1, x, y);
|
||||
}
|
||||
|
||||
actCursor = cursor;
|
||||
actCursorPixmap = p1;
|
||||
|
||||
viewer->getWidget()->setCursor(cursor);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawSketchHandler::addCursorTail(std::vector<QPixmap>& pixmaps)
|
||||
{
|
||||
// Create a pixmap that will contain icon and each autoconstraint icon
|
||||
Gui::MDIView* view = Gui::getMainWindow()->activeWindow();
|
||||
if (view && view->isDerivedFrom(Gui::View3DInventor::getClassTypeId())) {
|
||||
QPixmap baseIcon = QPixmap(actCursorPixmap);
|
||||
baseIcon.setDevicePixelRatio(actCursorPixmap.devicePixelRatio());
|
||||
qreal pixelRatio = baseIcon.devicePixelRatio();
|
||||
// cursor size in device independent pixels
|
||||
qreal baseCursorWidth = baseIcon.width();
|
||||
qreal baseCursorHeight = baseIcon.height();
|
||||
|
||||
int tailWidth = 0;
|
||||
for (auto const& p : pixmaps) {
|
||||
tailWidth += p.width();
|
||||
}
|
||||
|
||||
int newIconWidth = baseCursorWidth + tailWidth;
|
||||
int newIconHeight = baseCursorHeight;
|
||||
|
||||
QPixmap newIcon(newIconWidth, newIconHeight);
|
||||
newIcon.fill(Qt::transparent);
|
||||
|
||||
QPainter qp;
|
||||
qp.begin(&newIcon);
|
||||
|
||||
qp.drawPixmap(QPointF(0, 0),
|
||||
baseIcon.scaled(baseCursorWidth * pixelRatio,
|
||||
baseCursorHeight * pixelRatio,
|
||||
Qt::KeepAspectRatio,
|
||||
Qt::SmoothTransformation));
|
||||
|
||||
// Iterate through pixmaps and them to the cursor pixmap
|
||||
std::vector<QPixmap>::iterator pit = pixmaps.begin();
|
||||
int i = 0;
|
||||
qreal currentIconX = baseCursorWidth;
|
||||
qreal currentIconY;
|
||||
|
||||
for (; pit != pixmaps.end(); ++pit, i++) {
|
||||
QPixmap icon = *pit;
|
||||
currentIconY = baseCursorHeight - icon.height();
|
||||
qp.drawPixmap(QPointF(currentIconX, currentIconY), icon);
|
||||
currentIconX += icon.width();
|
||||
}
|
||||
|
||||
qp.end(); // Finish painting
|
||||
|
||||
// Create the new cursor with the icon.
|
||||
QPoint p = actCursor.hotSpot();
|
||||
newIcon.setDevicePixelRatio(pixelRatio);
|
||||
QCursor newCursor(newIcon, p.x(), p.y());
|
||||
applyCursor(newCursor);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawSketchHandler::updateCursor()
|
||||
{
|
||||
auto cursorstring = getCrosshairCursorSVGName();
|
||||
|
||||
if (cursorstring != QString::fromLatin1("None")) {
|
||||
setCrosshairCursor(cursorstring);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawSketchHandler::applyCursor()
|
||||
{
|
||||
applyCursor(actCursor);
|
||||
}
|
||||
|
||||
void DrawSketchHandler::applyCursor(QCursor& newCursor)
|
||||
{
|
||||
Gui::View3DInventorViewer* viewer = getViewer();
|
||||
if (viewer) {
|
||||
viewer->getWidget()->setCursor(newCursor);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawSketchHandler::unsetCursor()
|
||||
{
|
||||
Gui::View3DInventorViewer* viewer = getViewer();
|
||||
if (viewer) {
|
||||
viewer->getWidget()->setCursor(oldCursor);
|
||||
}
|
||||
}
|
||||
|
||||
qreal DrawSketchHandler::devicePixelRatio()
|
||||
{
|
||||
qreal pixelRatio = 1;
|
||||
Gui::View3DInventorViewer* viewer = getViewer();
|
||||
if (viewer) {
|
||||
pixelRatio = viewer->devicePixelRatio();
|
||||
}
|
||||
return pixelRatio;
|
||||
}
|
||||
|
||||
std::vector<QPixmap>
|
||||
DrawSketchHandler::suggestedConstraintsPixmaps(std::vector<AutoConstraint>& suggestedConstraints)
|
||||
{
|
||||
@@ -1284,12 +1074,3 @@ void DrawSketchHandler::signalToolChanged() const
|
||||
{
|
||||
ViewProviderSketchDrawSketchHandlerAttorney::signalToolChanged(*sketchgui, this->getToolName());
|
||||
}
|
||||
|
||||
Gui::View3DInventorViewer* DrawSketchHandler::getViewer()
|
||||
{
|
||||
Gui::MDIView* view = Gui::getMainWindow()->activeWindow();
|
||||
if (view && view->isDerivedFrom(Gui::View3DInventor::getClassTypeId())) {
|
||||
return static_cast<Gui::View3DInventor*>(view)->getViewer();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <Base/Parameter.h>
|
||||
#include <Base/Tools2D.h>
|
||||
#include <Gui/Selection.h>
|
||||
#include <Gui/ToolHandler.h>
|
||||
#include <Mod/Part/App/Geometry.h>
|
||||
#include <Mod/Sketcher/App/Constraint.h>
|
||||
|
||||
@@ -137,26 +138,28 @@ private:
|
||||
* implemented in DrawSketchHandler and used from its derived classes by virtue of the inheritance.
|
||||
* This promotes a concentrating the coupling in a single point (and code reuse).
|
||||
*/
|
||||
class SketcherGuiExport DrawSketchHandler
|
||||
class SketcherGuiExport DrawSketchHandler: public Gui::ToolHandler
|
||||
{
|
||||
public:
|
||||
DrawSketchHandler();
|
||||
virtual ~DrawSketchHandler();
|
||||
|
||||
void activate(ViewProviderSketch*);
|
||||
void deactivate();
|
||||
void deactivate() override;
|
||||
|
||||
virtual void mouseMove(Base::Vector2d pos) = 0;
|
||||
virtual bool pressButton(Base::Vector2d pos) = 0;
|
||||
virtual bool releaseButton(Base::Vector2d pos) = 0;
|
||||
|
||||
virtual void registerPressedKey(bool pressed, int key);
|
||||
virtual void pressRightButton(Base::Vector2d pos);
|
||||
|
||||
virtual void mouseMove(Base::Vector2d onSketchPos) = 0;
|
||||
virtual bool pressButton(Base::Vector2d onSketchPos) = 0;
|
||||
virtual bool releaseButton(Base::Vector2d onSketchPos) = 0;
|
||||
virtual bool onSelectionChanged(const Gui::SelectionChanges&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual void registerPressedKey(bool pressed, int key);
|
||||
virtual void pressRightButton(Base::Vector2d onSketchPos);
|
||||
|
||||
virtual void quit();
|
||||
void quit() override;
|
||||
|
||||
friend class ViewProviderSketch;
|
||||
|
||||
@@ -215,19 +218,12 @@ public:
|
||||
//@}
|
||||
|
||||
private: // NVI
|
||||
virtual void preActivated();
|
||||
virtual void activated()
|
||||
{}
|
||||
virtual void deactivated()
|
||||
{}
|
||||
virtual void postDeactivated()
|
||||
{}
|
||||
void preActivated() override;
|
||||
virtual void onWidgetChanged()
|
||||
{}
|
||||
|
||||
protected: // NVI requiring base implementation
|
||||
virtual std::string getToolName() const;
|
||||
virtual QString getCrosshairCursorSVGName() const;
|
||||
|
||||
virtual std::unique_ptr<QWidget> createWidget() const;
|
||||
virtual bool isWidgetVisible() const;
|
||||
@@ -235,37 +231,6 @@ protected: // NVI requiring base implementation
|
||||
virtual QString getToolWidgetText() const;
|
||||
|
||||
protected:
|
||||
// helpers
|
||||
/**
|
||||
* Sets a cursor for 3D inventor view.
|
||||
* pixmap as a cursor image in device independent pixels.
|
||||
*
|
||||
* \param autoScale - set this to false if pixmap already scaled for HiDPI
|
||||
**/
|
||||
|
||||
/** @name Icon helpers */
|
||||
//@{
|
||||
void setCursor(const QPixmap& pixmap, int x, int y, bool autoScale = true);
|
||||
|
||||
/// updates the actCursor with the icon by calling getCrosshairCursorSVGName(),
|
||||
/// enabling to set data member dependent icons (i.e. for different construction methods)
|
||||
void updateCursor();
|
||||
|
||||
/// restitutes the cursor that was in use at the moment of starting the DrawSketchHandler (i.e.
|
||||
/// oldCursor)
|
||||
void unsetCursor();
|
||||
|
||||
/// restitutes the DSH cached cursor (e.g. without any tail due to autoconstraints, ...)
|
||||
void applyCursor();
|
||||
|
||||
/// returns the color to be used for the crosshair (configurable as a parameter)
|
||||
unsigned long getCrosshairColor();
|
||||
|
||||
/// functions to set the cursor to a given svgName (to be migrated to NVI style)
|
||||
|
||||
qreal devicePixelRatio();
|
||||
//@}
|
||||
|
||||
void drawEdit(const std::vector<Base::Vector2d>& EditCurve) const;
|
||||
void drawEdit(const std::list<std::vector<Base::Vector2d>>& list) const;
|
||||
void drawEdit(const std::vector<Part::Geometry*>& geometries) const;
|
||||
@@ -300,22 +265,6 @@ protected:
|
||||
|
||||
void signalToolChanged() const;
|
||||
|
||||
Gui::View3DInventorViewer* getViewer();
|
||||
|
||||
private:
|
||||
void setSvgCursor(const QString& svgName,
|
||||
int x,
|
||||
int y,
|
||||
const std::map<unsigned long, unsigned long>& colorMapping =
|
||||
std::map<unsigned long, unsigned long>());
|
||||
|
||||
void addCursorTail(std::vector<QPixmap>& pixmaps);
|
||||
|
||||
void applyCursor(QCursor& newCursor);
|
||||
|
||||
void setCrosshairCursor(const QString& svgName);
|
||||
void setCrosshairCursor(const char* svgName);
|
||||
|
||||
|
||||
protected:
|
||||
/**
|
||||
@@ -325,9 +274,6 @@ protected:
|
||||
suggestedConstraintsPixmaps(std::vector<AutoConstraint>& suggestedConstraints);
|
||||
|
||||
ViewProviderSketch* sketchgui;
|
||||
QCursor oldCursor;
|
||||
QCursor actCursor;
|
||||
QPixmap actCursorPixmap;
|
||||
|
||||
QWidget* toolwidget;
|
||||
};
|
||||
|
||||
@@ -63,16 +63,19 @@ std::string DimensionFormatter::formatValue(const qreal value,
|
||||
{
|
||||
// Base::Console().Message("DF::formatValue() - %s isRestoring: %d\n",
|
||||
// m_dimension->getNameInDocument(), m_dimension->isRestoring());
|
||||
bool angularMeasure = false;
|
||||
bool angularMeasure = m_dimension->Type.isValue("Angle") || m_dimension->Type.isValue("Angle3Pt");
|
||||
bool areaMeasure = m_dimension->Type.isValue("Area");
|
||||
QLocale loc;
|
||||
|
||||
Base::Quantity asQuantity;
|
||||
asQuantity.setValue(value);
|
||||
if ( (m_dimension->Type.isValue("Angle")) ||
|
||||
(m_dimension->Type.isValue("Angle3Pt")) ) {
|
||||
angularMeasure = true;
|
||||
if (angularMeasure) {
|
||||
asQuantity.setUnit(Base::Unit::Angle);
|
||||
} else {
|
||||
}
|
||||
else if (areaMeasure) {
|
||||
asQuantity.setUnit(Base::Unit::Area);
|
||||
}
|
||||
else {
|
||||
asQuantity.setUnit(Base::Unit::Length);
|
||||
}
|
||||
|
||||
@@ -128,9 +131,14 @@ std::string DimensionFormatter::formatValue(const qreal value,
|
||||
if (angularMeasure) {
|
||||
userVal = asQuantity.getValue();
|
||||
qBasicUnit = QString::fromUtf8("°");
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
double convertValue = Base::Quantity::parse(QString::fromLatin1("1") + qBasicUnit).getValue();
|
||||
userVal = asQuantity.getValue() / convertValue;
|
||||
if (areaMeasure) {
|
||||
userVal = userVal / convertValue; // divide again as area is length²
|
||||
qBasicUnit = qBasicUnit + QString::fromUtf8("²");
|
||||
}
|
||||
}
|
||||
|
||||
if (isTooSmall(userVal, formatSpecifier)) {
|
||||
@@ -153,37 +161,44 @@ std::string DimensionFormatter::formatValue(const qreal value,
|
||||
return Base::Tools::toStdString(formatPrefix) +
|
||||
Base::Tools::toStdString(qUserString) +
|
||||
Base::Tools::toStdString(formatSuffix);
|
||||
} else if (partial == 1) { // prefix number[unit] suffix
|
||||
}
|
||||
else if (partial == 1) { // prefix number[unit] suffix
|
||||
if (angularMeasure) {
|
||||
//always insert unit after value
|
||||
return Base::Tools::toStdString(formatPrefix) +
|
||||
formattedValueString + "°" +
|
||||
Base::Tools::toStdString(formatSuffix);
|
||||
} else if (m_dimension->showUnits()){
|
||||
}
|
||||
else if (m_dimension->showUnits() || areaMeasure){
|
||||
if (isDim && m_dimension->haveTolerance()) {
|
||||
//unit will be included in tolerance so don't repeat it here
|
||||
return Base::Tools::toStdString(formatPrefix) +
|
||||
formattedValueString +
|
||||
Base::Tools::toStdString(formatSuffix);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
//no tolerance, so we need to include unit
|
||||
return Base::Tools::toStdString(formatPrefix) +
|
||||
formattedValueString + " " +
|
||||
Base::Tools::toStdString(qBasicUnit) +
|
||||
Base::Tools::toStdString(formatSuffix);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
//showUnits is false
|
||||
return Base::Tools::toStdString(formatPrefix) +
|
||||
formattedValueString +
|
||||
Base::Tools::toStdString(formatSuffix);
|
||||
}
|
||||
} else if (partial == 2) { // just the unit
|
||||
}
|
||||
else if (partial == 2) { // just the unit
|
||||
if (angularMeasure) {
|
||||
return Base::Tools::toStdString(qBasicUnit);
|
||||
} else if (m_dimension->showUnits()) {
|
||||
}
|
||||
else if (m_dimension->showUnits() || areaMeasure) {
|
||||
return Base::Tools::toStdString(qBasicUnit);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -361,3 +361,35 @@ void arcPoints::dump(const std::string& text) const
|
||||
DrawUtil::formatVector(arcEnds.second()).c_str());
|
||||
Base::Console().Message("arcPoints - midArc: %s\n", DrawUtil::formatVector(midArc).c_str());
|
||||
}
|
||||
|
||||
|
||||
areaPoint::areaPoint() :
|
||||
area(0.0),
|
||||
center(Base::Vector3d())
|
||||
{
|
||||
}
|
||||
|
||||
areaPoint& areaPoint::operator=(const areaPoint& ap)
|
||||
{
|
||||
area = ap.area;
|
||||
center = ap.center;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void areaPoint::move(const Base::Vector3d& offset)
|
||||
{
|
||||
center = center - offset;
|
||||
}
|
||||
|
||||
void areaPoint::project(const DrawViewPart* dvp)
|
||||
{
|
||||
area = area * dvp->getScale();
|
||||
center = dvp->projectPoint(center) * dvp->getScale();
|
||||
}
|
||||
|
||||
void areaPoint::dump(const std::string& text) const
|
||||
{
|
||||
Base::Console().Message("areaPoint - %s\n", text.c_str());
|
||||
Base::Console().Message("areaPoint - area: %.3f center: %s\n", area,
|
||||
DrawUtil::formatVector(center).c_str());
|
||||
}
|
||||
|
||||
@@ -156,6 +156,24 @@ public:
|
||||
bool arcCW;
|
||||
};
|
||||
|
||||
//a convenient container for area dimension
|
||||
class TechDrawExport areaPoint
|
||||
{
|
||||
public:
|
||||
areaPoint();
|
||||
areaPoint(const areaPoint& ap) = default;
|
||||
|
||||
areaPoint& operator= (const areaPoint& ap);
|
||||
|
||||
void move(const Base::Vector3d& offset);
|
||||
void project(const DrawViewPart* dvp);
|
||||
void dump(const std::string& text) const;
|
||||
|
||||
//TODO: setters and getters
|
||||
double area;
|
||||
Base::Vector3d center;
|
||||
};
|
||||
|
||||
} //end namespace TechDraw
|
||||
|
||||
#endif
|
||||
|
||||
@@ -86,6 +86,12 @@ ReferenceEntry& ReferenceEntry::operator=(const ReferenceEntry& otherRef)
|
||||
}
|
||||
|
||||
|
||||
bool ReferenceEntry::operator==(const ReferenceEntry& otherRef) const
|
||||
{
|
||||
return getObjectName() == otherRef.getObjectName() && getSubName() == otherRef.getSubName();
|
||||
}
|
||||
|
||||
|
||||
TopoDS_Shape ReferenceEntry::getGeometry() const
|
||||
{
|
||||
// Base::Console().Message("RE::getGeometry() - objectName: %s sub: **%s**\n",
|
||||
@@ -206,6 +212,10 @@ Part::TopoShape ReferenceEntry::asTopoShape() const
|
||||
TopoDS_Edge edge = TopoDS::Edge(geom);
|
||||
return asTopoShapeEdge(edge);
|
||||
}
|
||||
if (geom.ShapeType() == TopAbs_FACE) {
|
||||
TopoDS_Face face = TopoDS::Face(geom);
|
||||
return asTopoShapeFace(face);
|
||||
}
|
||||
throw Base::RuntimeError("Dimension Reference has unsupported geometry");
|
||||
}
|
||||
|
||||
@@ -253,12 +263,30 @@ Part::TopoShape ReferenceEntry::asTopoShapeEdge(const TopoDS_Edge &edge)
|
||||
return { edge };
|
||||
}
|
||||
|
||||
Part::TopoShape ReferenceEntry::asTopoShapeFace(const TopoDS_Face &face)
|
||||
{
|
||||
return { face };
|
||||
}
|
||||
|
||||
std::string ReferenceEntry::geomType() const
|
||||
{
|
||||
// Base::Console().Message("RE::geomType() - subName: **%s**\n", getSubName().c_str());
|
||||
return DrawUtil::getGeomTypeFromName(getSubName());
|
||||
}
|
||||
|
||||
GeomType ReferenceEntry::geomEdgeType() const
|
||||
{
|
||||
int geoId = TechDraw::DrawUtil::getIndexFromName(getSubName());
|
||||
auto dvp = static_cast<TechDraw::DrawViewPart*>(getObject());
|
||||
BaseGeomPtr geom = dvp->getGeomByIndex(geoId);
|
||||
|
||||
if (geomType() == "Edge" && geom) {
|
||||
return geom->getGeomType();
|
||||
}
|
||||
|
||||
return GeomType::NOTDEF;
|
||||
}
|
||||
|
||||
bool ReferenceEntry::isWholeObject() const
|
||||
{
|
||||
return getSubName().empty();
|
||||
@@ -314,12 +342,19 @@ bool ReferenceEntry::hasGeometry2d() const
|
||||
if (vert) {
|
||||
return true;
|
||||
}
|
||||
} else if (gType == "Edge") {
|
||||
}
|
||||
else if (gType == "Edge") {
|
||||
auto edge = dvp->getGeomByIndex(geomNumber);
|
||||
if (edge) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (gType == "Face") {
|
||||
auto face = dvp->getFace(getSubName());
|
||||
if (face) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
|
||||
#include <Mod/Part/App/TopoShape.h>
|
||||
#include <Mod/TechDraw/App/Geometry.h>
|
||||
|
||||
namespace App
|
||||
{
|
||||
@@ -59,6 +60,7 @@ public:
|
||||
~ReferenceEntry() = default;
|
||||
|
||||
ReferenceEntry& operator= (const ReferenceEntry& otherRef);
|
||||
bool operator== (const ReferenceEntry& otherRef) const;
|
||||
|
||||
App::DocumentObject* getObject() const;
|
||||
void setObject(App::DocumentObject* docObj) { m_object = docObj; }
|
||||
@@ -71,6 +73,8 @@ public:
|
||||
|
||||
TopoDS_Shape getGeometry() const;
|
||||
std::string geomType() const;
|
||||
GeomType geomEdgeType() const;
|
||||
|
||||
bool isWholeObject() const;
|
||||
|
||||
Part::TopoShape asTopoShape() const;
|
||||
@@ -86,6 +90,7 @@ private:
|
||||
|
||||
static Part::TopoShape asTopoShapeVertex(const TopoDS_Vertex &vert);
|
||||
static Part::TopoShape asTopoShapeEdge(const TopoDS_Edge& edge);
|
||||
static Part::TopoShape asTopoShapeFace(const TopoDS_Face& edge);
|
||||
|
||||
App::DocumentObject* m_object{nullptr};
|
||||
std::string m_subName;
|
||||
|
||||
@@ -59,13 +59,31 @@
|
||||
|
||||
using namespace TechDraw;
|
||||
|
||||
void DrawDimHelper::makeExtentDim(DrawViewPart* dvp, std::vector<std::string> edgeNames,
|
||||
DrawViewDimension* DrawDimHelper::makeExtentDim(DrawViewPart* dvp,
|
||||
const std::string& dimType, ReferenceVector references2d)
|
||||
{
|
||||
std::vector<std::string> edgeNames;
|
||||
for (auto& ref : references2d) {
|
||||
if (ref.getSubName().empty()) {
|
||||
continue;
|
||||
}
|
||||
std::string geomType = DrawUtil::getGeomTypeFromName(ref.getSubName());
|
||||
if (geomType == "Edge") {
|
||||
edgeNames.push_back(ref.getSubName());
|
||||
}
|
||||
}
|
||||
int direction = dimType == "DistanceX" ? 0 : dimType == "DistanceY" ? 1 : 2;
|
||||
|
||||
return makeExtentDim(dvp, edgeNames, direction);
|
||||
}
|
||||
|
||||
DrawViewDimension* DrawDimHelper::makeExtentDim(DrawViewPart* dvp, std::vector<std::string> edgeNames,
|
||||
int direction)
|
||||
{
|
||||
// Base::Console().Message("DDH::makeExtentDim() - dvp: %s edgeNames: %d\n",
|
||||
// dvp->Label.getValue(), edgeNames.size());
|
||||
if (!dvp) {
|
||||
return;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::string dimType = "DistanceX";
|
||||
@@ -74,8 +92,12 @@ void DrawDimHelper::makeExtentDim(DrawViewPart* dvp, std::vector<std::string> ed
|
||||
dimType = "DistanceY";
|
||||
dimNum = 1;
|
||||
}
|
||||
else if (direction == LENGTH) {
|
||||
dimType = "Distance";
|
||||
dimNum = 2;
|
||||
}
|
||||
|
||||
TechDraw::DrawPage* page = dvp->findParentPage();
|
||||
DrawPage* page = dvp->findParentPage();
|
||||
std::string pageName = page->getNameInDocument();
|
||||
|
||||
App::Document* doc = dvp->getDocument();
|
||||
@@ -89,8 +111,7 @@ void DrawDimHelper::makeExtentDim(DrawViewPart* dvp, std::vector<std::string> ed
|
||||
Base::Interpreter().runStringArg(
|
||||
"App.activeDocument().%s.DirExtent = %d", dimName.c_str(), dimNum);
|
||||
|
||||
TechDraw::DrawViewDimExtent* dimExt =
|
||||
dynamic_cast<TechDraw::DrawViewDimExtent*>(doc->getObject(dimName.c_str()));
|
||||
auto* dimExt = dynamic_cast<DrawViewDimExtent*>(doc->getObject(dimName.c_str()));
|
||||
if (!dimExt) {
|
||||
throw Base::TypeError("Dim extent not found");
|
||||
}
|
||||
@@ -113,6 +134,14 @@ void DrawDimHelper::makeExtentDim(DrawViewPart* dvp, std::vector<std::string> ed
|
||||
dimName.c_str());
|
||||
|
||||
dimExt->recomputeFeature();
|
||||
|
||||
return dimExt;
|
||||
}
|
||||
|
||||
void DrawDimHelper::makeExtentDim3d(DrawViewPart* dvp, const std::string& dimType, ReferenceVector references3d)
|
||||
{
|
||||
int direction = dimType == "DistanceX" ? 0 : dimType == "DistanceY" ? 1 : 2;
|
||||
return makeExtentDim3d(dvp, references3d, direction);
|
||||
}
|
||||
|
||||
void DrawDimHelper::makeExtentDim3d(DrawViewPart* dvp, ReferenceVector references, int direction)
|
||||
@@ -130,7 +159,7 @@ void DrawDimHelper::makeExtentDim3d(DrawViewPart* dvp, ReferenceVector reference
|
||||
dimNum = 1;
|
||||
}
|
||||
|
||||
TechDraw::DrawPage* page = dvp->findParentPage();
|
||||
DrawPage* page = dvp->findParentPage();
|
||||
std::string pageName = page->getNameInDocument();
|
||||
|
||||
App::Document* doc = dvp->getDocument();
|
||||
@@ -144,8 +173,7 @@ void DrawDimHelper::makeExtentDim3d(DrawViewPart* dvp, ReferenceVector reference
|
||||
Base::Interpreter().runStringArg(
|
||||
"App.activeDocument().%s.DirExtent = %d", dimName.c_str(), dimNum);
|
||||
|
||||
TechDraw::DrawViewDimExtent* dimExt =
|
||||
dynamic_cast<TechDraw::DrawViewDimExtent*>(doc->getObject(dimName.c_str()));
|
||||
auto* dimExt = dynamic_cast<DrawViewDimExtent*>(doc->getObject(dimName.c_str()));
|
||||
if (!dimExt) {
|
||||
throw Base::TypeError("Dim extent not found");
|
||||
}
|
||||
|
||||
@@ -44,9 +44,18 @@ class DrawViewDimension;
|
||||
/// Additional functions for working with Dimensions
|
||||
class TechDrawExport DrawDimHelper {
|
||||
public:
|
||||
static void makeExtentDim(DrawViewPart* dvp,
|
||||
|
||||
static DrawViewDimension* makeExtentDim(DrawViewPart* dvp,
|
||||
const std::string& dimType,
|
||||
ReferenceVector references2d);
|
||||
|
||||
static DrawViewDimension* makeExtentDim(DrawViewPart* dvp,
|
||||
std::vector<std::string> edgeNames,
|
||||
int direction);
|
||||
|
||||
static void makeExtentDim3d(DrawViewPart* dvp,
|
||||
const std::string& dimType,
|
||||
ReferenceVector references2d);
|
||||
static void makeExtentDim3d(DrawViewPart* dvp,
|
||||
ReferenceVector references,
|
||||
int direction);
|
||||
@@ -55,7 +64,7 @@ class TechDrawExport DrawDimHelper {
|
||||
TopoDS_Edge& boundary);
|
||||
|
||||
|
||||
static TechDraw::DrawViewDimension* makeDistDim(DrawViewPart* dvp,
|
||||
static DrawViewDimension* makeDistDim(DrawViewPart* dvp,
|
||||
std::string dimType,
|
||||
Base::Vector3d refMin,
|
||||
Base::Vector3d refMax,
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
||||
#include <BRepGProp.hxx>
|
||||
#include <GProp_GProps.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <BRepAdaptor_Curve.hxx>
|
||||
#include <BRepBuilderAPI_MakeEdge.hxx>
|
||||
@@ -93,6 +95,7 @@ const char* DrawViewDimension::TypeEnums[] = {"Distance",
|
||||
"Diameter",
|
||||
"Angle",
|
||||
"Angle3Pt",
|
||||
"Area",
|
||||
nullptr};
|
||||
|
||||
const char* DrawViewDimension::MeasureTypeEnums[] = {"True", "Projected", nullptr};
|
||||
@@ -267,6 +270,12 @@ void DrawViewDimension::resetArc()
|
||||
m_arcPoints.arcCW = false;
|
||||
}
|
||||
|
||||
void DrawViewDimension::resetArea()
|
||||
{
|
||||
m_areaPoint.center = Base::Vector3d(0, 0, 0);
|
||||
m_areaPoint.area = 0.0;
|
||||
}
|
||||
|
||||
void DrawViewDimension::onChanged(const App::Property* prop)
|
||||
{
|
||||
if (prop == &References3D) {
|
||||
@@ -461,6 +470,7 @@ App::DocumentObjectExecReturn* DrawViewDimension::execute()
|
||||
resetLinear();
|
||||
resetAngular();
|
||||
resetArc();
|
||||
resetArea();
|
||||
|
||||
// we have either or both valid References3D and References2D
|
||||
ReferenceVector references = getEffectiveReferences();
|
||||
@@ -499,6 +509,13 @@ App::DocumentObjectExecReturn* DrawViewDimension::execute()
|
||||
m_anglePoints = getAnglePointsThreeVerts(references);
|
||||
m_hasGeometry = true;
|
||||
}
|
||||
else if (Type.isValue("Area")) {
|
||||
if (getRefType() != oneFace) {
|
||||
throw Base::RuntimeError("area dimension has non-face references");
|
||||
}
|
||||
m_areaPoint = getAreaParameters(references);
|
||||
m_hasGeometry = true;
|
||||
}
|
||||
|
||||
overrideKeepUpdated(false);
|
||||
return DrawView::execute();
|
||||
@@ -679,6 +696,9 @@ double DrawViewDimension::getTrueDimValue() const
|
||||
else if (Type.isValue("Angle") || Type.isValue("Angle3Pt")) {
|
||||
result = measurement->angle();
|
||||
}
|
||||
else if (Type.isValue("Area")) {
|
||||
result = measurement->area();
|
||||
}
|
||||
else { // tarfu
|
||||
throw Base::ValueError("getDimValue() - Unknown Dimension Type (3)");
|
||||
}
|
||||
@@ -721,9 +741,8 @@ double DrawViewDimension::getProjectedDimValue() const
|
||||
}
|
||||
}
|
||||
else if (Type.isValue("Radius")) {
|
||||
arcPoints pts = m_arcPoints;
|
||||
result =
|
||||
pts.radius / getViewPart()->getScale(); // Projected BaseGeom is scaled for drawing
|
||||
// Projected BaseGeom is scaled for drawing
|
||||
result = m_arcPoints.radius / getViewPart()->getScale();
|
||||
}
|
||||
else if (Type.isValue("Diameter")) {
|
||||
arcPoints pts = m_arcPoints;
|
||||
@@ -738,6 +757,9 @@ double DrawViewDimension::getProjectedDimValue() const
|
||||
double legAngle = Base::toDegrees(leg0.GetAngle(leg1));
|
||||
result = legAngle;
|
||||
}
|
||||
else if (Type.isValue("Area")) {
|
||||
result = m_areaPoint.area / getViewPart()->getScale();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -927,7 +949,7 @@ arcPoints DrawViewDimension::getArcParameters(ReferenceVector references)
|
||||
ssMessage << getNameInDocument() << " can not find geometry for 2d reference (4)";
|
||||
throw Base::RuntimeError(ssMessage.str());
|
||||
}
|
||||
return arcPointsFromBaseGeom(getViewPart()->getGeomByIndex(iSubelement));
|
||||
return arcPointsFromBaseGeom(geom);
|
||||
}
|
||||
|
||||
// this is a 3d reference
|
||||
@@ -1324,6 +1346,40 @@ anglePoints DrawViewDimension::getAnglePointsThreeVerts(ReferenceVector referenc
|
||||
return pts;
|
||||
}
|
||||
|
||||
areaPoint DrawViewDimension::getAreaParameters(ReferenceVector references)
|
||||
{
|
||||
areaPoint pts;
|
||||
|
||||
App::DocumentObject* refObject = references.front().getObject();
|
||||
if (refObject->isDerivedFrom<DrawViewPart>() && !references[0].getSubName().empty()) {
|
||||
// this is a 2d object (a DVP + subelements)
|
||||
TechDraw::FacePtr face = getViewPart()->getFace(references[0].getSubName());
|
||||
if (!face) {
|
||||
std::stringstream ssMessage;
|
||||
ssMessage << getNameInDocument() << " can not find geometry for 2d reference (4)";
|
||||
throw Base::RuntimeError(ssMessage.str());
|
||||
}
|
||||
|
||||
pts.area = face->getArea();
|
||||
pts.center = face->getCenter();
|
||||
}
|
||||
else {
|
||||
// this is a 3d reference
|
||||
TopoDS_Shape geometry = references[0].getGeometry();
|
||||
if (geometry.IsNull() || geometry.ShapeType() != TopAbs_FACE) {
|
||||
throw Base::RuntimeError("Geometry for dimension reference is null.");
|
||||
}
|
||||
const TopoDS_Face& face = TopoDS::Face(geometry);
|
||||
|
||||
GProp_GProps props;
|
||||
BRepGProp::SurfaceProperties(face, props);
|
||||
pts.area = props.Mass();
|
||||
pts.center = DrawUtil::toVector3d(props.CentreOfMass());
|
||||
}
|
||||
|
||||
return pts;
|
||||
}
|
||||
|
||||
DrawViewPart* DrawViewDimension::getViewPart() const
|
||||
{
|
||||
if (References2D.getValues().empty()) {
|
||||
@@ -1411,6 +1467,7 @@ int DrawViewDimension::getRefTypeSubElements(const std::vector<std::string>& sub
|
||||
int refType = invalidRef;
|
||||
int refEdges{0};
|
||||
int refVertices{0};
|
||||
int refFaces{0};
|
||||
|
||||
for (const auto& se : subElements) {
|
||||
if (DrawUtil::getGeomTypeFromName(se) == "Vertex") {
|
||||
@@ -1419,23 +1476,29 @@ int DrawViewDimension::getRefTypeSubElements(const std::vector<std::string>& sub
|
||||
if (DrawUtil::getGeomTypeFromName(se) == "Edge") {
|
||||
refEdges++;
|
||||
}
|
||||
if (DrawUtil::getGeomTypeFromName(se) == "Face") {
|
||||
refFaces++;
|
||||
}
|
||||
}
|
||||
|
||||
if (refEdges == 0 && refVertices == 2) {
|
||||
if (refEdges == 0 && refVertices == 2 && refFaces == 0) {
|
||||
refType = twoVertex;
|
||||
}
|
||||
if (refEdges == 0 && refVertices == 3) {
|
||||
if (refEdges == 0 && refVertices == 3 && refFaces == 0) {
|
||||
refType = threeVertex;
|
||||
}
|
||||
if (refEdges == 1 && refVertices == 0) {
|
||||
if (refEdges == 1 && refVertices == 0 && refFaces == 0) {
|
||||
refType = oneEdge;
|
||||
}
|
||||
if (refEdges == 1 && refVertices == 1) {
|
||||
if (refEdges == 1 && refVertices == 1 && refFaces == 0) {
|
||||
refType = vertexEdge;
|
||||
}
|
||||
if (refEdges == 2 && refVertices == 0) {
|
||||
if (refEdges == 2 && refVertices == 0 && refFaces == 0) {
|
||||
refType = twoEdge;
|
||||
}
|
||||
if (refEdges == 0 && refVertices == 0 && refFaces == 1) {
|
||||
refType = oneFace;
|
||||
}
|
||||
|
||||
return refType;
|
||||
}
|
||||
@@ -1749,6 +1812,17 @@ bool DrawViewDimension::validateReferenceForm() const
|
||||
return (subGeom0 == "Vertex" && subGeom1 == "Vertex" && subGeom2 == "Vertex");
|
||||
}
|
||||
|
||||
if (Type.isValue("Area")) {
|
||||
if (references.size() != 1) {
|
||||
return false;
|
||||
}
|
||||
std::string subGeom = DrawUtil::getGeomTypeFromName(references.front().getSubName());
|
||||
if (subGeom != "Face") {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -101,6 +101,7 @@ public:
|
||||
twoVertex,
|
||||
vertexEdge,
|
||||
threeVertex,
|
||||
oneFace,
|
||||
extent
|
||||
};
|
||||
|
||||
@@ -178,6 +179,10 @@ public:
|
||||
{
|
||||
return m_anglePoints;
|
||||
}
|
||||
areaPoint getAreaPoint()
|
||||
{
|
||||
return m_areaPoint;
|
||||
}
|
||||
|
||||
bool leaderIntersectsArc(Base::Vector3d s, Base::Vector3d pointOnCircle);
|
||||
|
||||
@@ -228,6 +233,8 @@ protected:
|
||||
virtual anglePoints getAnglePointsTwoEdges(ReferenceVector references);
|
||||
virtual anglePoints getAnglePointsThreeVerts(ReferenceVector references);
|
||||
|
||||
virtual areaPoint getAreaParameters(ReferenceVector references);
|
||||
|
||||
Measure::Measurement* measurement;
|
||||
double
|
||||
dist2Segs(Base::Vector3d s1, Base::Vector3d e1, Base::Vector3d s2, Base::Vector3d e2) const;
|
||||
@@ -236,6 +243,7 @@ protected:
|
||||
void resetLinear();
|
||||
void resetAngular();
|
||||
void resetArc();
|
||||
void resetArea();
|
||||
|
||||
bool okToProceed();
|
||||
void updateSavedGeometry();
|
||||
@@ -252,6 +260,7 @@ private:
|
||||
pointPair m_arrowPositions;
|
||||
arcPoints m_arcPoints;
|
||||
anglePoints m_anglePoints;
|
||||
areaPoint m_areaPoint;
|
||||
bool m_hasGeometry;
|
||||
|
||||
friend class DimensionFormatter;
|
||||
|
||||
@@ -168,6 +168,13 @@ Base::Vector3d Face::getCenter() const {
|
||||
return DrawUtil::toVector3d(faceProps.CentreOfMass());
|
||||
}
|
||||
|
||||
double Face::getArea() const {
|
||||
GProp_GProps faceProps;
|
||||
BRepGProp::SurfaceProperties(toOccFace(), faceProps);
|
||||
|
||||
return faceProps.Mass();
|
||||
}
|
||||
|
||||
Face::~Face()
|
||||
{
|
||||
for(auto it : wires) {
|
||||
|
||||
@@ -348,6 +348,7 @@ class TechDrawExport Face
|
||||
TopoDS_Face toOccFace() const;
|
||||
std::vector<Wire *> wires;
|
||||
|
||||
double getArea() const;
|
||||
Base::Vector3d getCenter() const;
|
||||
};
|
||||
using FacePtr = std::shared_ptr<Face>;
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
#include <BRepGProp.hxx>
|
||||
#include <GProp_GProps.hxx>
|
||||
#endif
|
||||
|
||||
#include <BRepAdaptor_Curve.hxx>
|
||||
@@ -75,9 +77,13 @@ bool GeometryMatcher::compareGeometry(const Part::TopoShape &shape1, const Part:
|
||||
if (geom1.ShapeType() == TopAbs_EDGE) {
|
||||
return compareEdges(geom1, geom2);
|
||||
}
|
||||
if (geom1.ShapeType() == TopAbs_FACE) {
|
||||
return compareFaces(geom1, geom2);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool GeometryMatcher::comparePoints(const TopoDS_Shape& shape1, const TopoDS_Shape& shape2)
|
||||
{
|
||||
// Base::Console().Message("GM::comparePoints()\n");
|
||||
@@ -92,6 +98,27 @@ bool GeometryMatcher::comparePoints(const TopoDS_Shape& shape1, const TopoDS_Sha
|
||||
return point1.IsEqual(point2, EWTOLERANCE);
|
||||
}
|
||||
|
||||
bool GeometryMatcher::compareFaces(const TopoDS_Shape& shape1, const TopoDS_Shape& shape2)
|
||||
{
|
||||
// Base::Console().Message("GM::compareFaces()\n");
|
||||
|
||||
if (shape1.ShapeType() != TopAbs_FACE || shape2.ShapeType() != TopAbs_FACE) {
|
||||
// can not compare these shapes
|
||||
return false;
|
||||
}
|
||||
TopoDS_Face face1 = TopoDS::Face(shape1);
|
||||
TopoDS_Face face2 = TopoDS::Face(shape2);
|
||||
|
||||
//Note: face1.IsSame(face2) and face1.IsEqual(face2) do not work.
|
||||
|
||||
GProp_GProps props1, props2;
|
||||
BRepGProp::SurfaceProperties(face1, props1);
|
||||
BRepGProp::SurfaceProperties(face2, props2);
|
||||
|
||||
// Check if areas are approximately equal
|
||||
return fabs(props1.Mass() - props2.Mass()) < 1e-5;
|
||||
}
|
||||
|
||||
bool GeometryMatcher::compareEdges(const TopoDS_Shape& shape1, const TopoDS_Shape& shape2)
|
||||
{
|
||||
// Base::Console().Message("GM::compareEdges()\n");
|
||||
|
||||
@@ -58,6 +58,7 @@ public:
|
||||
private:
|
||||
static bool comparePoints(const TopoDS_Shape& shape1, const TopoDS_Shape& shape2);
|
||||
static bool compareEdges(const TopoDS_Shape& shape1, const TopoDS_Shape& shape2);
|
||||
static bool compareFaces(const TopoDS_Shape& shape1, const TopoDS_Shape& shape2);
|
||||
|
||||
static bool compareLines(const TopoDS_Edge& edge1, const TopoDS_Edge& edge2);
|
||||
static bool compareCircles(const TopoDS_Edge& edge1, const TopoDS_Edge& edge2);
|
||||
|
||||
@@ -125,11 +125,11 @@ PyMOD_INIT_FUNC(TechDrawGui)
|
||||
|
||||
// instantiating the commands
|
||||
CreateTechDrawCommands();
|
||||
CreateTechDrawCommandsDims();
|
||||
CreateTechDrawCommandsDecorate();
|
||||
CreateTechDrawCommandsAnnotate();
|
||||
CreateTechDrawCommandsExtensionDims();
|
||||
CreateTechDrawCommandsExtensions();
|
||||
CreateTechDrawCommandsDims();
|
||||
CreateTechDrawCommandsStack();
|
||||
|
||||
TechDrawGui::Workbench::init();
|
||||
|
||||
@@ -102,6 +102,7 @@ SET(TechDrawGui_SRCS
|
||||
CommandDecorate.cpp
|
||||
CommandAnnotate.cpp
|
||||
CommandExtensionDims.cpp
|
||||
CommandExtensionDims.h
|
||||
CommandExtensionPack.cpp
|
||||
CommandStack.cpp
|
||||
DimensionValidators.cpp
|
||||
@@ -223,6 +224,8 @@ SET(TechDrawGui_SRCS
|
||||
TaskCosmeticCircle.cpp
|
||||
TaskCosmeticCircle.h
|
||||
TaskCosmeticCircle.ui
|
||||
TechDrawHandler.cpp
|
||||
TechDrawHandler.h
|
||||
Widgets/CompassDialWidget.cpp
|
||||
Widgets/CompassDialWidget.h
|
||||
Widgets/CompassWidget.cpp
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -25,6 +25,8 @@
|
||||
# include <QApplication>
|
||||
# include <QMessageBox>
|
||||
# include <sstream>
|
||||
# include <BRepGProp.hxx>
|
||||
# include <GProp_GProps.hxx>
|
||||
#endif
|
||||
|
||||
# include <App/Document.h>
|
||||
@@ -52,6 +54,7 @@
|
||||
#include "DrawGuiUtil.h"
|
||||
#include "TaskCustomizeFormat.h"
|
||||
#include "TaskSelectLineAttributes.h"
|
||||
#include "CommandExtensionDims.h"
|
||||
|
||||
|
||||
using namespace TechDrawGui;
|
||||
@@ -78,7 +81,7 @@ namespace TechDrawGui {
|
||||
std::vector<TechDraw::DrawViewDimension*>_getDimensions(std::vector<Gui::SelectionObject> selection, std::string needDimType);
|
||||
std::vector<dimVertex> _getVertexInfo(TechDraw::DrawViewPart* objFeat,
|
||||
std::vector<std::string> subNames);
|
||||
TechDraw::DrawViewDimension* _createLinDimension(Gui::Command* cmd,
|
||||
TechDraw::DrawViewDimension* _createLinDimension(
|
||||
TechDraw::DrawViewPart* objFeat,
|
||||
std::string startVertex,
|
||||
std::string endVertex,
|
||||
@@ -1280,7 +1283,7 @@ void execCreateHorizChainDimension(Gui::Command* cmd) {
|
||||
float yMaster = 0.0;
|
||||
for (long unsigned int n = 0; n < allVertexes.size() - 1; n++) {
|
||||
TechDraw::DrawViewDimension* dim;
|
||||
dim = _createLinDimension(cmd, objFeat, allVertexes[n].name, allVertexes[n + 1].name, "DistanceX");
|
||||
dim = _createLinDimension(objFeat, allVertexes[n].name, allVertexes[n + 1].name, "DistanceX");
|
||||
TechDraw::pointPair pp = dim->getLinearPoints();
|
||||
Base::Vector3d mid = (pp.first() + pp.second()) / 2.0;
|
||||
dim->X.setValue(mid.x);
|
||||
@@ -1347,7 +1350,7 @@ void execCreateVertChainDimension(Gui::Command* cmd) {
|
||||
double fontSize = Preferences::dimFontSizeMM();
|
||||
for (long unsigned int n = 0; n < allVertexes.size() - 1; n++) {
|
||||
TechDraw::DrawViewDimension* dim;
|
||||
dim = _createLinDimension(cmd, objFeat, allVertexes[n].name, allVertexes[n + 1].name, "DistanceY");
|
||||
dim = _createLinDimension(objFeat, allVertexes[n].name, allVertexes[n + 1].name, "DistanceY");
|
||||
TechDraw::pointPair pp = dim->getLinearPoints();
|
||||
Base::Vector3d mid = (pp.first() + pp.second()) / 2.0;
|
||||
if (n == 0)
|
||||
@@ -1404,7 +1407,37 @@ void execCreateObliqueChainDimension(Gui::Command* cmd) {
|
||||
}
|
||||
|
||||
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Create Oblique Chain Dim"));
|
||||
const std::vector<std::string> subNames = selection[0].getSubNames();
|
||||
|
||||
std::vector<TechDraw::ReferenceEntry> refs;
|
||||
for (auto& subName : selection[0].getSubNames()) {
|
||||
refs.push_back(ReferenceEntry(objFeat, subName));
|
||||
}
|
||||
|
||||
auto dims = makeObliqueChainDimension(refs);
|
||||
if(dims.empty()){
|
||||
Gui::Command::abortCommand();
|
||||
}
|
||||
else {
|
||||
objFeat->refreshCEGeoms();
|
||||
objFeat->requestPaint();
|
||||
cmd->getSelection().clearSelection();
|
||||
Gui::Command::commitCommand();
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<DrawViewDimension*> TechDrawGui::makeObliqueChainDimension(std::vector<TechDraw::ReferenceEntry> refs)
|
||||
{
|
||||
if (refs.empty()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<std::string> subNames;
|
||||
auto* objFeat = static_cast<DrawViewPart*>(refs[0].getObject());
|
||||
for (auto& ref : refs) {
|
||||
subNames.push_back(ref.getSubName());
|
||||
}
|
||||
std::vector<DrawViewDimension*> dims;
|
||||
|
||||
std::vector<dimVertex> allVertexes, carrierVertexes;
|
||||
allVertexes = _getVertexInfo(objFeat, subNames);
|
||||
if (!allVertexes.empty() && allVertexes.size() > 1) {
|
||||
@@ -1443,17 +1476,16 @@ void execCreateObliqueChainDimension(Gui::Command* cmd) {
|
||||
double fontSize = Preferences::dimFontSizeMM();
|
||||
for (long unsigned int n = 0; n < allVertexes.size() - 1; n++) {
|
||||
TechDraw::DrawViewDimension* dim;
|
||||
dim = _createLinDimension(cmd, objFeat, carrierVertexes[n].name, carrierVertexes[n + 1].name, "Distance");
|
||||
dim = _createLinDimension(objFeat, carrierVertexes[n].name, carrierVertexes[n + 1].name, "Distance");
|
||||
TechDraw::pointPair pp = dim->getLinearPoints();
|
||||
Base::Vector3d mid = (pp.first() + pp.second()) / 2.0 + delta;
|
||||
dim->X.setValue(mid.x);
|
||||
dim->Y.setValue(-mid.y + 0.5 * fontSize);
|
||||
dims.push_back(dim);
|
||||
}
|
||||
objFeat->refreshCEGeoms();
|
||||
objFeat->requestPaint();
|
||||
cmd->getSelection().clearSelection();
|
||||
Gui::Command::commitCommand();
|
||||
}
|
||||
|
||||
return dims;
|
||||
}
|
||||
|
||||
DEF_STD_CMD_A(CmdTechDrawExtensionCreateObliqueChainDimension)
|
||||
@@ -1630,7 +1662,7 @@ void execCreateHorizCoordDimension(Gui::Command* cmd) {
|
||||
dimDistance = -dimDistance;
|
||||
for (long unsigned int n = 0; n < allVertexes.size() - 1; n++) {
|
||||
TechDraw::DrawViewDimension* dim;
|
||||
dim = _createLinDimension(cmd, objFeat, allVertexes[0].name, allVertexes[n + 1].name, "DistanceX");
|
||||
dim = _createLinDimension(objFeat, allVertexes[0].name, allVertexes[n + 1].name, "DistanceX");
|
||||
TechDraw::pointPair pp = dim->getLinearPoints();
|
||||
Base::Vector3d mid = (pp.first() + pp.second()) / 2.0;
|
||||
dim->X.setValue(mid.x);
|
||||
@@ -1703,7 +1735,7 @@ void execCreateVertCoordDimension(Gui::Command* cmd) {
|
||||
double fontSize = Preferences::dimFontSizeMM();
|
||||
for (long unsigned int n = 0; n < allVertexes.size() - 1; n++) {
|
||||
TechDraw::DrawViewDimension* dim;
|
||||
dim = _createLinDimension(cmd, objFeat, allVertexes[0].name, allVertexes[n + 1].name, "DistanceY");
|
||||
dim = _createLinDimension(objFeat, allVertexes[0].name, allVertexes[n + 1].name, "DistanceY");
|
||||
TechDraw::pointPair pp = dim->getLinearPoints();
|
||||
Base::Vector3d mid = (pp.first() + pp.second()) / 2.0;
|
||||
dim->X.setValue(xMaster + dimDistance * n);
|
||||
@@ -1760,7 +1792,37 @@ void execCreateObliqueCoordDimension(Gui::Command* cmd) {
|
||||
}
|
||||
|
||||
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Create Oblique Coord Dim"));
|
||||
const std::vector<std::string> subNames = selection[0].getSubNames();
|
||||
|
||||
std::vector<TechDraw::ReferenceEntry> refs;
|
||||
for (auto& subName : selection[0].getSubNames()) {
|
||||
refs.push_back(ReferenceEntry(objFeat, subName));
|
||||
}
|
||||
|
||||
auto dims = makeObliqueCoordDimension(refs);
|
||||
if (dims.empty()) {
|
||||
Gui::Command::abortCommand();
|
||||
}
|
||||
else {
|
||||
objFeat->refreshCEGeoms();
|
||||
objFeat->requestPaint();
|
||||
cmd->getSelection().clearSelection();
|
||||
Gui::Command::commitCommand();
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<DrawViewDimension*> TechDrawGui::makeObliqueCoordDimension(std::vector<TechDraw::ReferenceEntry> refs)
|
||||
{
|
||||
if (refs.empty()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<std::string> subNames;
|
||||
auto* objFeat = static_cast<DrawViewPart*>(refs[0].getObject());
|
||||
for (auto& ref : refs) {
|
||||
subNames.push_back(ref.getSubName());
|
||||
}
|
||||
std::vector<DrawViewDimension*> dims;
|
||||
|
||||
std::vector<dimVertex> allVertexes, carrierVertexes;
|
||||
allVertexes = _getVertexInfo(objFeat, subNames);
|
||||
if (!allVertexes.empty() && allVertexes.size() > 1) {
|
||||
@@ -1804,17 +1866,16 @@ void execCreateObliqueCoordDimension(Gui::Command* cmd) {
|
||||
double fontSize = Preferences::dimFontSizeMM();
|
||||
for (long unsigned int n = 0; n < allVertexes.size() - 1; n++) {
|
||||
TechDraw::DrawViewDimension* dim;
|
||||
dim = _createLinDimension(cmd, objFeat, carrierVertexes[0].name, carrierVertexes[n + 1].name, "Distance");
|
||||
dim = _createLinDimension(objFeat, carrierVertexes[0].name, carrierVertexes[n + 1].name, "Distance");
|
||||
TechDraw::pointPair pp = dim->getLinearPoints();
|
||||
Base::Vector3d mid = (pp.first() + pp.second()) / 2.0 + delta * (n + 1);
|
||||
dim->X.setValue(mid.x);
|
||||
dim->Y.setValue(-mid.y + 0.5 * fontSize);
|
||||
dims.push_back(dim);
|
||||
}
|
||||
}
|
||||
objFeat->refreshCEGeoms();
|
||||
objFeat->requestPaint();
|
||||
cmd->getSelection().clearSelection();
|
||||
Gui::Command::commitCommand();
|
||||
|
||||
return dims;
|
||||
}
|
||||
|
||||
DEF_STD_CMD_A(CmdTechDrawExtensionCreateObliqueCoordDimension)
|
||||
@@ -1991,7 +2052,7 @@ void execCreateHorizChamferDimension(Gui::Command* cmd) {
|
||||
if (!allVertexes.empty() && allVertexes.size() > 1) {
|
||||
const auto Pi180 = 180.0 / M_PI;
|
||||
TechDraw::DrawViewDimension* dim;
|
||||
dim = _createLinDimension(cmd, objFeat, allVertexes[0].name, allVertexes[1].name, "DistanceX");
|
||||
dim = _createLinDimension(objFeat, allVertexes[0].name, allVertexes[1].name, "DistanceX");
|
||||
float yMax = std::max(abs(allVertexes[0].point.y), abs(allVertexes[1].point.y)) + 7.0;
|
||||
if (std::signbit(allVertexes[0].point.y))
|
||||
yMax = -yMax;
|
||||
@@ -2060,7 +2121,7 @@ void execCreateVertChamferDimension(Gui::Command* cmd) {
|
||||
if (!allVertexes.empty() && allVertexes.size() > 1) {
|
||||
const auto Pi180 = 180.0 / M_PI;
|
||||
TechDraw::DrawViewDimension* dim;
|
||||
dim = _createLinDimension(cmd, objFeat, allVertexes[0].name, allVertexes[1].name, "DistanceY");
|
||||
dim = _createLinDimension(objFeat, allVertexes[0].name, allVertexes[1].name, "DistanceY");
|
||||
float xMax = std::max(abs(allVertexes[0].point.x), abs(allVertexes[1].point.x)) + 7.0;
|
||||
if (std::signbit(allVertexes[0].point.x))
|
||||
xMax = -xMax;
|
||||
@@ -2240,47 +2301,19 @@ void CmdTechDrawExtensionCreateLengthArc::activated(int iMsg) {
|
||||
}
|
||||
|
||||
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Create Arc Length Dim"));
|
||||
const std::vector<std::string> subNames = selection[0].getSubNames();
|
||||
int geoId = TechDraw::DrawUtil::getIndexFromName(subNames[0]);
|
||||
TechDraw::BaseGeomPtr geom = objFeat->getGeomByIndex(geoId);
|
||||
std::string geoType = TechDraw::DrawUtil::getGeomTypeFromName(subNames[0]);
|
||||
if (geoType == "Edge" && geom->getGeomType() == TechDraw::ARCOFCIRCLE) {
|
||||
TechDraw::AOCPtr arcTag = std::static_pointer_cast<TechDraw::AOC>(geom);
|
||||
float radius = arcTag->radius;
|
||||
Base::Vector3d centerPt = arcTag->center;
|
||||
centerPt.y = -centerPt.y;
|
||||
Base::Vector3d startPt = arcTag->startPnt;
|
||||
startPt.y = -startPt.y;
|
||||
Base::Vector3d endPt = arcTag->endPnt;
|
||||
endPt.y = -endPt.y;
|
||||
std::stringstream startName, endName, formatSpec;
|
||||
double scale = objFeat->getScale();
|
||||
Base::Vector3d cvPoint = CosmeticVertex::makeCanonicalPoint(objFeat, startPt);
|
||||
std::string startVertTag = objFeat->addCosmeticVertex(cvPoint);
|
||||
int startVertNumber = objFeat->add1CVToGV(startVertTag);
|
||||
startName << "Vertex" << startVertNumber;
|
||||
cvPoint = CosmeticVertex::makeCanonicalPoint(objFeat, endPt);
|
||||
std::string endVertTag = objFeat->addCosmeticVertex(cvPoint);
|
||||
int endVertNumber = objFeat->add1CVToGV(endVertTag);
|
||||
endName << "Vertex" << endVertNumber;
|
||||
TechDraw::DrawViewDimension* dim;
|
||||
dim = _createLinDimension(this, objFeat, startName.str(), endName.str(), "Distance");
|
||||
TechDraw::pointPair pp = dim->getLinearPoints();
|
||||
Base::Vector3d mid = (pp.first() + pp.second()) / 2.0;
|
||||
dim->X.setValue(mid.x);
|
||||
dim->Y.setValue(-mid.y);
|
||||
Base::Vector3d radVec1 = startPt - centerPt;
|
||||
Base::Vector3d radVec2 = endPt - centerPt;
|
||||
float alpha = acos((radVec1 * radVec2) / (radVec1.Length() * radVec2.Length()));
|
||||
float arcLength = alpha * radius / scale;
|
||||
dim->Arbitrary.setValue(true);
|
||||
formatSpec << "◠ " << arcLength;
|
||||
dim->FormatSpec.setValue(formatSpec.str());
|
||||
|
||||
ReferenceEntry ref(objFeat, selection[0].getSubNames()[0]);
|
||||
|
||||
TechDraw::DrawViewDimension* dim = makeArcLengthDimension(ref);
|
||||
|
||||
if (dim) {
|
||||
objFeat->refreshCEGeoms();
|
||||
objFeat->requestPaint();
|
||||
getSelection().clearSelection();
|
||||
Gui::Command::commitCommand();
|
||||
}
|
||||
else {
|
||||
Gui::Command::abortCommand();
|
||||
}
|
||||
Gui::Command::commitCommand();
|
||||
}
|
||||
|
||||
bool CmdTechDrawExtensionCreateLengthArc::isActive()
|
||||
@@ -2329,6 +2362,51 @@ bool CmdTechDrawExtensionCustomizeFormat::isActive()
|
||||
return (havePage && haveView);
|
||||
}
|
||||
|
||||
DrawViewDimension* TechDrawGui::makeArcLengthDimension(const ReferenceEntry& ref)
|
||||
{
|
||||
DrawViewDimension* dim = nullptr;
|
||||
auto* dvp = static_cast<DrawViewPart*>(ref.getObject());
|
||||
|
||||
int geoId = DrawUtil::getIndexFromName(ref.getSubName());
|
||||
BaseGeomPtr geom = dvp->getGeomByIndex(geoId);
|
||||
|
||||
// Find the edge length.
|
||||
TechDraw::BaseGeomPtr edge = dvp->getEdge(ref.getSubName());
|
||||
if (!edge) {
|
||||
return nullptr;
|
||||
}
|
||||
GProp_GProps edgeProps;
|
||||
BRepGProp::LinearProperties(edge->getOCCEdge(), edgeProps);
|
||||
double length = edgeProps.Mass() / dvp->getScale();
|
||||
|
||||
Base::Vector3d startPt = edge->getStartPoint();
|
||||
Base::Vector3d endPt = edge->getEndPoint();
|
||||
startPt.y = -startPt.y;
|
||||
endPt.y = -endPt.y;
|
||||
|
||||
std::stringstream startName, endName, formatSpec;
|
||||
Base::Vector3d cvPoint = CosmeticVertex::makeCanonicalPoint(dvp, startPt);
|
||||
std::string startVertTag = dvp->addCosmeticVertex(cvPoint);
|
||||
int startVertNumber = dvp->add1CVToGV(startVertTag);
|
||||
startName << "Vertex" << startVertNumber;
|
||||
cvPoint = CosmeticVertex::makeCanonicalPoint(dvp, endPt);
|
||||
std::string endVertTag = dvp->addCosmeticVertex(cvPoint);
|
||||
int endVertNumber = dvp->add1CVToGV(endVertTag);
|
||||
endName << "Vertex" << endVertNumber;
|
||||
|
||||
dim = _createLinDimension(dvp, startName.str(), endName.str(), "Distance");
|
||||
TechDraw::pointPair pp = dim->getLinearPoints();
|
||||
Base::Vector3d mid = (pp.first() + pp.second()) / 2.0;
|
||||
dim->X.setValue(mid.x);
|
||||
dim->Y.setValue(-mid.y);
|
||||
|
||||
dim->Arbitrary.setValue(true);
|
||||
formatSpec << "◠ " << length;
|
||||
dim->FormatSpec.setValue(formatSpec.str());
|
||||
|
||||
return dim;
|
||||
}
|
||||
|
||||
namespace TechDrawGui {
|
||||
//===========================================================================
|
||||
// internal helper routines
|
||||
@@ -2387,7 +2465,8 @@ namespace TechDrawGui {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
TechDraw::DrawViewDimension* _createLinDimension(Gui::Command* cmd,
|
||||
|
||||
TechDraw::DrawViewDimension* _createLinDimension(
|
||||
TechDraw::DrawViewPart* objFeat,
|
||||
std::string startVertex,
|
||||
std::string endVertex,
|
||||
@@ -2396,21 +2475,21 @@ namespace TechDrawGui {
|
||||
{
|
||||
TechDraw::DrawPage* page = objFeat->findParentPage();
|
||||
std::string PageName = page->getNameInDocument();
|
||||
TechDraw::DrawViewDimension* dim = nullptr;
|
||||
std::string FeatName = cmd->getUniqueObjectName("Dimension");
|
||||
std::string FeatName = objFeat->getDocument()->getUniqueObjectName("Dimension");
|
||||
std::vector<App::DocumentObject*> objs;
|
||||
std::vector<std::string> subs;
|
||||
objs.push_back(objFeat);
|
||||
objs.push_back(objFeat);
|
||||
subs.push_back(startVertex);
|
||||
subs.push_back(endVertex);
|
||||
cmd->doCommand(cmd->Doc, "App.activeDocument().addObject('TechDraw::DrawViewDimension', '%s')", FeatName.c_str());
|
||||
cmd->doCommand(cmd->Doc, "App.activeDocument().%s.Type = '%s'", FeatName.c_str(), dimType.c_str());
|
||||
dim = dynamic_cast<TechDraw::DrawViewDimension*>(cmd->getDocument()->getObject(FeatName.c_str()));
|
||||
if (!dim)
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "App.activeDocument().addObject('TechDraw::DrawViewDimension', '%s')", FeatName.c_str());
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "App.activeDocument().%s.Type = '%s'", FeatName.c_str(), dimType.c_str());
|
||||
auto dim = dynamic_cast<TechDraw::DrawViewDimension*>(objFeat->getDocument()->getObject(FeatName.c_str()));
|
||||
if (!dim){
|
||||
throw Base::TypeError("CmdTechDrawExtensionCreateLinDimension - dim not found\n");
|
||||
}
|
||||
dim->References2D.setValues(objs, subs);
|
||||
cmd->doCommand(cmd->Doc, "App.activeDocument().%s.addView(App.activeDocument().%s)", PageName.c_str(), FeatName.c_str());
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "App.activeDocument().%s.addView(App.activeDocument().%s)", PageName.c_str(), FeatName.c_str());
|
||||
|
||||
// Touch the parent feature so the dimension in tree view appears as a child
|
||||
objFeat->touch();
|
||||
|
||||
41
src/Mod/TechDraw/Gui/CommandExtensionDims.h
Normal file
41
src/Mod/TechDraw/Gui/CommandExtensionDims.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2021 edi *
|
||||
* *
|
||||
* 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 TECHDRAWGUI_CommandExtensionDims_H
|
||||
#define TECHDRAWGUI_CommandExtensionDims_H
|
||||
|
||||
#include <Mod/TechDraw/TechDrawGlobal.h>
|
||||
|
||||
namespace TechDraw
|
||||
{
|
||||
class ReferenceEntry;
|
||||
class DrawViewDimension;
|
||||
}
|
||||
|
||||
namespace TechDrawGui {
|
||||
TechDraw::DrawViewDimension* makeArcLengthDimension(const TechDraw::ReferenceEntry& ref);
|
||||
|
||||
std::vector<TechDraw::DrawViewDimension*> makeObliqueChainDimension(std::vector<TechDraw::ReferenceEntry> refs);
|
||||
std::vector<TechDraw::DrawViewDimension*> makeObliqueCoordDimension(std::vector<TechDraw::ReferenceEntry> refs);
|
||||
}
|
||||
|
||||
#endif // TECHDRAWGUI_CommandExtensionDims_H
|
||||
@@ -116,7 +116,7 @@ DimensionGeometryType TechDraw::validateDimSelection(
|
||||
StringVector subNames;
|
||||
TechDraw::DrawViewPart* dvpSave(nullptr);
|
||||
for (auto& ref : references) {
|
||||
TechDraw::DrawViewPart* dvp = dynamic_cast<TechDraw::DrawViewPart*>(ref.getObject());
|
||||
auto* dvp = dynamic_cast<TechDraw::DrawViewPart*>(ref.getObject());
|
||||
if (dvp) {
|
||||
dvpSave = dvp;
|
||||
if (!ref.getSubName().empty()) {
|
||||
@@ -295,6 +295,10 @@ DimensionGeometryType TechDraw::getGeometryConfiguration(ReferenceVector valid2d
|
||||
if (config > isInvalid) {
|
||||
return config;
|
||||
}
|
||||
config = isValidSingleFace(valid2dReferences.front());
|
||||
if (config > isInvalid) {
|
||||
return config;
|
||||
}
|
||||
|
||||
// no valid configuration found
|
||||
return isInvalid;
|
||||
@@ -336,6 +340,10 @@ DimensionGeometryType TechDraw::getGeometryConfiguration3d(DrawViewPart* dvp,
|
||||
if (config > isInvalid) {
|
||||
return config;
|
||||
}
|
||||
config = isValidSingleFace3d(dvp, valid3dReferences.front());
|
||||
if (config > isInvalid) {
|
||||
return config;
|
||||
}
|
||||
config = isValidHybrid3d(dvp, valid3dReferences);
|
||||
if (config > isInvalid) {
|
||||
return config;
|
||||
@@ -461,6 +469,47 @@ DimensionGeometryType TechDraw::isValidSingleEdge3d(DrawViewPart* dvp, Reference
|
||||
return isInvalid;
|
||||
}
|
||||
|
||||
//! verify that Selection contains a valid Geometry for a single Edge Dimension
|
||||
DimensionGeometryType TechDraw::isValidSingleFace(ReferenceEntry ref)
|
||||
{
|
||||
auto objFeat(dynamic_cast<TechDraw::DrawViewPart*>(ref.getObject()));
|
||||
if (!objFeat) {
|
||||
return isInvalid;
|
||||
}
|
||||
|
||||
//the Name starts with "Edge"
|
||||
std::string geomName = DrawUtil::getGeomTypeFromName(ref.getSubName());
|
||||
if (geomName != "Face") {
|
||||
return isInvalid;
|
||||
}
|
||||
|
||||
auto geom = objFeat->getFace(ref.getSubName());
|
||||
if (!geom) {
|
||||
return isInvalid;
|
||||
}
|
||||
|
||||
return isFace;
|
||||
}
|
||||
|
||||
//! verify that Selection contains a valid Geometry for a single Edge Dimension
|
||||
DimensionGeometryType TechDraw::isValidSingleFace3d(DrawViewPart* dvp, ReferenceEntry ref)
|
||||
{
|
||||
(void)dvp;
|
||||
//the Name starts with "Edge"
|
||||
std::string geomName = DrawUtil::getGeomTypeFromName(ref.getSubName());
|
||||
if (geomName != "Face") {
|
||||
return isInvalid;
|
||||
}
|
||||
|
||||
TopoDS_Shape refShape = ref.getGeometry();
|
||||
if (refShape.IsNull() || refShape.ShapeType() != TopAbs_FACE) {
|
||||
Base::Console().Warning("Geometry for reference is not a face.\n");
|
||||
return isInvalid;
|
||||
}
|
||||
|
||||
return isFace;
|
||||
}
|
||||
|
||||
//! verify that the edge references can make a dimension. Currently only extent
|
||||
//! dimensions support more than 2 edges
|
||||
DimensionGeometryType TechDraw::isValidMultiEdge(ReferenceVector refs)
|
||||
|
||||
@@ -60,6 +60,7 @@ enum DimensionGeometryEnum {
|
||||
isMultiEdge,
|
||||
isZLimited,
|
||||
isHybrid,
|
||||
isFace,
|
||||
isViewReference //never needs to be specified in the acceptable list
|
||||
};
|
||||
|
||||
@@ -89,11 +90,13 @@ bool checkGeometryOccurrences(StringVector subNames, GeomCountMap keyedMinimumCo
|
||||
DimensionGeometryType isValidVertexes(ReferenceVector refs);
|
||||
DimensionGeometryType isValidMultiEdge(ReferenceVector refs);
|
||||
DimensionGeometryType isValidSingleEdge(ReferenceEntry ref);
|
||||
DimensionGeometryType isValidSingleFace(ReferenceEntry ref);
|
||||
DimensionGeometryType isValidHybrid(ReferenceVector refs);
|
||||
|
||||
DimensionGeometryType isValidVertexes3d(DrawViewPart* dvp, ReferenceVector refs);
|
||||
DimensionGeometryType isValidMultiEdge3d(DrawViewPart* dvp, ReferenceVector refs);
|
||||
DimensionGeometryType isValidSingleEdge3d(DrawViewPart* dvp, ReferenceEntry ref);
|
||||
DimensionGeometryType isValidSingleFace3d(DrawViewPart* dvp, ReferenceEntry ref);
|
||||
DimensionGeometryType isValidHybrid3d(DrawViewPart* dvp, ReferenceVector refs);
|
||||
|
||||
long int mapGeometryTypeToDimType(long int dimType, DimensionGeometryType geometry2d,
|
||||
|
||||
@@ -524,9 +524,9 @@ Multiplier of 'Font Size'</string>
|
||||
<item row="9" column="2">
|
||||
<widget class="Gui::PrefDoubleSpinBox" name="pdsbGapISO">
|
||||
<property name="toolTip">
|
||||
<string>Controls the size of gap between dimension point and start of extension line for ISO dimensions.
|
||||
Value * linewidth is the gap.
|
||||
Normally, no gap is used. If using a gap, the recommended value 8.</string>
|
||||
<string>Controls the size of gap between dimension point and start of extension line for ISO dimensions.
|
||||
Value * linewidth is the gap.
|
||||
Normally, no gap is used. If using a gap, the recommended value 8.</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
@@ -545,8 +545,8 @@ Normally, no gap is used. If using a gap, the recommended value 8.</string>
|
||||
<item row="10" column="2">
|
||||
<widget class="Gui::PrefDoubleSpinBox" name="pdsbGapASME">
|
||||
<property name="toolTip">
|
||||
<string>Controls the size of gap between dimension point and start of extension line for ASME dimensions. Value * linewidth is the gap.
|
||||
Normally, no gap is used. If a gap is used, the recommended value is 6.</string>
|
||||
<string>Controls the size of gap between dimension point and start of extension line for ASME dimensions. Value * linewidth is the gap.
|
||||
Normally, no gap is used. If a gap is used, the recommended value is 6.</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
@@ -618,6 +618,56 @@ Normally, no gap is used. If a gap is used, the recommended value is 6.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_6">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Tools</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_general">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="dimensioningLabel">
|
||||
<property name="text">
|
||||
<string>Dimensioning tools:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="dimensioningMode">
|
||||
<property name="toolTip">
|
||||
<string>Select the type of dimensioning tools for your toolbar:
|
||||
'Single tool': A single tool for all dimensioning in the toolbar: Distance, Distance X / Y, Angle, Radius. (Others in dropdown)
|
||||
'Separated tools': Individual tools for each dimensioning tool.
|
||||
'Both': You will have both the 'Dimension' tool and the separated tools.
|
||||
This setting is only for the toolbar. Whichever you choose, all tools are always available in the menu and through shortcuts.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="radiusDiameterLabel">
|
||||
<property name="text">
|
||||
<string>Dimension tool diameter/radius mode:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="radiusDiameterMode">
|
||||
<property name="toolTip">
|
||||
<string>While using the Dimension tool you may choose how to handle circles and arcs:
|
||||
'Auto': The tool will apply radius to arcs and diameter to circles.
|
||||
'Diameter': The tool will apply diameter to all.
|
||||
'Radius': The tool will apply radius to all.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#include <Base/Tools.h>
|
||||
#include <App/Application.h>
|
||||
|
||||
#include "DlgPrefsTechDrawDimensionsImp.h"
|
||||
#include "ui_DlgPrefsTechDrawDimensions.h"
|
||||
@@ -67,6 +68,61 @@ void DlgPrefsTechDrawDimensionsImp::saveSettings()
|
||||
ui->pdsbGapISO->onSave();
|
||||
ui->pdsbGapASME->onSave();
|
||||
ui->pdsbLineSpacingFactorISO->onSave();
|
||||
|
||||
enum
|
||||
{
|
||||
DimensionSingleTool,
|
||||
DimensionSeparateTools,
|
||||
DimensionBoth
|
||||
};
|
||||
|
||||
// Dimensioning constraints mode
|
||||
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
|
||||
"User parameter:BaseApp/Preferences/Mod/TechDraw/dimensioning");
|
||||
bool singleTool = true;
|
||||
bool SeparatedTools = false;
|
||||
int index = ui->dimensioningMode->currentIndex();
|
||||
switch (index) {
|
||||
case DimensionSeparateTools:
|
||||
singleTool = false;
|
||||
SeparatedTools = true;
|
||||
break;
|
||||
case DimensionBoth:
|
||||
singleTool = true;
|
||||
SeparatedTools = true;
|
||||
break;
|
||||
}
|
||||
hGrp->SetBool("SingleDimensioningTool", singleTool);
|
||||
hGrp->SetBool("SeparatedDimensioningTools", SeparatedTools);
|
||||
|
||||
ui->radiusDiameterMode->setEnabled(index != 1);
|
||||
|
||||
enum
|
||||
{
|
||||
DimensionAutoRadiusDiam,
|
||||
DimensionDiameter,
|
||||
DimensionRadius
|
||||
};
|
||||
|
||||
bool Diameter = true;
|
||||
bool Radius = true;
|
||||
index = ui->radiusDiameterMode->currentIndex();
|
||||
switch (index) {
|
||||
case DimensionDiameter:
|
||||
Diameter = true;
|
||||
Radius = false;
|
||||
break;
|
||||
case DimensionRadius:
|
||||
Diameter = false;
|
||||
Radius = true;
|
||||
break;
|
||||
}
|
||||
hGrp->SetBool("DimensioningDiameter", Diameter);
|
||||
hGrp->SetBool("DimensioningRadius", Radius);
|
||||
|
||||
if (property("dimensioningMode").toInt() != ui->dimensioningMode->currentIndex()) {
|
||||
requireRestart();
|
||||
}
|
||||
}
|
||||
|
||||
void DlgPrefsTechDrawDimensionsImp::loadSettings()
|
||||
@@ -101,6 +157,42 @@ void DlgPrefsTechDrawDimensionsImp::loadSettings()
|
||||
ui->pdsbGapASME->onRestore();
|
||||
ui->pdsbLineSpacingFactorISO->onRestore();
|
||||
|
||||
|
||||
// Dimensioning constraints mode
|
||||
ui->dimensioningMode->clear();
|
||||
ui->dimensioningMode->addItem(tr("Single tool"));
|
||||
ui->dimensioningMode->addItem(tr("Separated tools"));
|
||||
ui->dimensioningMode->addItem(tr("Both"));
|
||||
|
||||
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
|
||||
"User parameter:BaseApp/Preferences/Mod/TechDraw/dimensioning");
|
||||
bool singleTool = hGrp->GetBool("SingleDimensioningTool", true);
|
||||
bool SeparatedTools = hGrp->GetBool("SeparatedDimensioningTools", true);
|
||||
int index = SeparatedTools ? (singleTool ? 2 : 1) : 0;
|
||||
ui->dimensioningMode->setCurrentIndex(index);
|
||||
setProperty("dimensioningMode", index);
|
||||
connect(ui->dimensioningMode,
|
||||
QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||
this,
|
||||
&DlgPrefsTechDrawDimensionsImp::dimensioningModeChanged);
|
||||
|
||||
ui->radiusDiameterMode->setEnabled(index != 1);
|
||||
|
||||
// Dimensioning constraints mode
|
||||
ui->radiusDiameterMode->clear();
|
||||
ui->radiusDiameterMode->addItem(tr("Auto"));
|
||||
ui->radiusDiameterMode->addItem(tr("Diameter"));
|
||||
ui->radiusDiameterMode->addItem(tr("Radius"));
|
||||
|
||||
bool Diameter = hGrp->GetBool("DimensioningDiameter", true);
|
||||
bool Radius = hGrp->GetBool("DimensioningRadius", true);
|
||||
index = Diameter ? (Radius ? 0 : 1) : 2;
|
||||
ui->radiusDiameterMode->setCurrentIndex(index);
|
||||
}
|
||||
|
||||
void DlgPrefsTechDrawDimensionsImp::dimensioningModeChanged(int index)
|
||||
{
|
||||
ui->radiusDiameterMode->setEnabled(index != 1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -45,6 +45,7 @@ protected:
|
||||
void saveSettings() override;
|
||||
void loadSettings() override;
|
||||
void changeEvent(QEvent *e) override;
|
||||
void dimensioningModeChanged(int index);
|
||||
|
||||
int prefArrowStyle() const;
|
||||
|
||||
|
||||
@@ -110,6 +110,7 @@ MDIViewPage::MDIViewPage(ViewProviderPage* pageVp, Gui::Document* doc, QWidget*
|
||||
connect(m_printAllAction, &QAction::triggered, this, qOverload<>(&MDIViewPage::printAllPages));
|
||||
|
||||
isSelectionBlocked = false;
|
||||
isContextualMenuEnabled = true;
|
||||
|
||||
QString tabText = QString::fromUtf8(pageVp->getDrawPage()->getNameInDocument());
|
||||
tabText += QString::fromUtf8("[*]");
|
||||
@@ -461,14 +462,16 @@ PyObject* MDIViewPage::getPyObject()
|
||||
void MDIViewPage::contextMenuEvent(QContextMenuEvent* event)
|
||||
{
|
||||
// Base::Console().Message("MDIVP::contextMenuEvent() - reason: %d\n", event->reason());
|
||||
QMenu menu;
|
||||
menu.addAction(m_toggleFrameAction);
|
||||
menu.addAction(m_toggleKeepUpdatedAction);
|
||||
menu.addAction(m_exportSVGAction);
|
||||
menu.addAction(m_exportDXFAction);
|
||||
menu.addAction(m_exportPDFAction);
|
||||
menu.addAction(m_printAllAction);
|
||||
menu.exec(event->globalPos());
|
||||
if (isContextualMenuEnabled) {
|
||||
QMenu menu;
|
||||
menu.addAction(m_toggleFrameAction);
|
||||
menu.addAction(m_toggleKeepUpdatedAction);
|
||||
menu.addAction(m_exportSVGAction);
|
||||
menu.addAction(m_exportDXFAction);
|
||||
menu.addAction(m_exportPDFAction);
|
||||
menu.addAction(m_printAllAction);
|
||||
menu.exec(event->globalPos());
|
||||
}
|
||||
}
|
||||
|
||||
void MDIViewPage::toggleFrame() { m_vpPage->toggleFrameState(); }
|
||||
@@ -755,13 +758,27 @@ void MDIViewPage::sceneSelectionChanged()
|
||||
std::vector<Gui::SelectionObject> treeSel = Gui::Selection().getSelectionEx();
|
||||
QList<QGraphicsItem*> sceneSel = m_qgSceneSelected;
|
||||
|
||||
//check if really need to change selection
|
||||
bool sameSel = compareSelections(treeSel, sceneSel);
|
||||
if (sameSel) {
|
||||
return;
|
||||
|
||||
bool saveBlock = blockSelection(true);// block selectionChanged signal from Tree/Observer
|
||||
blockSceneSelection(true);
|
||||
|
||||
if (sceneSel.empty()) {
|
||||
if (!treeSel.empty()) {
|
||||
Gui::Selection().clearSelection();
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (auto& sel : treeSel) {
|
||||
removeSelFromTreeSel(sceneSel, sel);
|
||||
}
|
||||
|
||||
for (auto* scene : sceneSel) {
|
||||
addSceneToTreeSel(scene, treeSel);
|
||||
}
|
||||
}
|
||||
|
||||
setTreeToSceneSelect();
|
||||
blockSceneSelection(false);
|
||||
blockSelection(saveBlock);
|
||||
}
|
||||
|
||||
//Note: Qt says: "no guarantee of selection order"!!!
|
||||
@@ -771,149 +788,48 @@ void MDIViewPage::setTreeToSceneSelect()
|
||||
bool saveBlock = blockSelection(true);// block selectionChanged signal from Tree/Observer
|
||||
blockSceneSelection(true);
|
||||
Gui::Selection().clearSelection();
|
||||
QList<QGraphicsItem*> sceneSel = m_qgSceneSelected;
|
||||
for (QList<QGraphicsItem*>::iterator it = sceneSel.begin(); it != sceneSel.end(); ++it) {
|
||||
QGIView* itemView = dynamic_cast<QGIView*>(*it);
|
||||
|
||||
for (auto* scene : m_qgSceneSelected) {
|
||||
auto* itemView = dynamic_cast<QGIView*>(scene);
|
||||
if (!itemView) {
|
||||
QGIEdge* edge = dynamic_cast<QGIEdge*>(*it);
|
||||
if (edge) {
|
||||
QGraphicsItem* parent = edge->parentItem();
|
||||
if (!parent) {
|
||||
continue;
|
||||
}
|
||||
|
||||
QGIView* viewItem = dynamic_cast<QGIView*>(parent);
|
||||
if (!viewItem) {
|
||||
continue;
|
||||
}
|
||||
|
||||
TechDraw::DrawView* viewObj = viewItem->getViewObject();
|
||||
|
||||
std::stringstream ss;
|
||||
ss << "Edge" << edge->getProjIndex();
|
||||
//bool accepted =
|
||||
static_cast<void>(Gui::Selection().addSelection(viewObj->getDocument()->getName(),
|
||||
viewObj->getNameInDocument(),
|
||||
ss.str().c_str()));
|
||||
showStatusMsg(viewObj->getDocument()->getName(), viewObj->getNameInDocument(),
|
||||
ss.str().c_str());
|
||||
auto* parent = dynamic_cast<QGIView*>(scene->parentItem());
|
||||
if (!parent) {
|
||||
return;
|
||||
}
|
||||
TechDraw::DrawView* viewObj = parent->getViewObject();
|
||||
if (!viewObj) {
|
||||
continue;
|
||||
}
|
||||
const char* doc_name = viewObj->getDocument()->getName();
|
||||
const char* obj_name = viewObj->getNameInDocument();
|
||||
|
||||
QGIVertex* vert = dynamic_cast<QGIVertex*>(*it);
|
||||
if (vert) {
|
||||
QGraphicsItem* parent = vert->parentItem();
|
||||
if (!parent) {
|
||||
continue;
|
||||
}
|
||||
auto* edge = dynamic_cast<QGIEdge*>(scene);
|
||||
auto* vert = dynamic_cast<QGIVertex*>(scene);
|
||||
auto* face = dynamic_cast<QGIFace*>(scene);
|
||||
if (edge || vert || face) {
|
||||
const char* ssn = getSceneSubName(scene).c_str();
|
||||
|
||||
QGIView* viewItem = dynamic_cast<QGIView*>(parent);
|
||||
if (!viewItem) {
|
||||
continue;
|
||||
}
|
||||
|
||||
TechDraw::DrawView* viewObj = viewItem->getViewObject();
|
||||
|
||||
std::stringstream ss;
|
||||
ss << "Vertex" << vert->getProjIndex();
|
||||
//bool accepted =
|
||||
static_cast<void>(Gui::Selection().addSelection(viewObj->getDocument()->getName(),
|
||||
viewObj->getNameInDocument(),
|
||||
ss.str().c_str()));
|
||||
showStatusMsg(viewObj->getDocument()->getName(), viewObj->getNameInDocument(),
|
||||
ss.str().c_str());
|
||||
continue;
|
||||
Gui::Selection().addSelection(doc_name, obj_name, ssn);
|
||||
showStatusMsg(doc_name, obj_name, ssn);
|
||||
return;
|
||||
}
|
||||
|
||||
QGIFace* face = dynamic_cast<QGIFace*>(*it);
|
||||
if (face) {
|
||||
QGraphicsItem* parent = face->parentItem();
|
||||
if (!parent) {
|
||||
continue;
|
||||
}
|
||||
|
||||
QGIView* viewItem = dynamic_cast<QGIView*>(parent);
|
||||
if (!viewItem) {
|
||||
continue;
|
||||
}
|
||||
|
||||
TechDraw::DrawView* viewObj = viewItem->getViewObject();
|
||||
|
||||
std::stringstream ss;
|
||||
ss << "Face" << face->getProjIndex();
|
||||
//bool accepted =
|
||||
static_cast<void>(Gui::Selection().addSelection(viewObj->getDocument()->getName(),
|
||||
viewObj->getNameInDocument(),
|
||||
ss.str().c_str()));
|
||||
showStatusMsg(viewObj->getDocument()->getName(), viewObj->getNameInDocument(),
|
||||
ss.str().c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
QGIDatumLabel* dimLabel = dynamic_cast<QGIDatumLabel*>(*it);
|
||||
if (dimLabel) {
|
||||
QGraphicsItem* dimParent = dimLabel->QGraphicsItem::parentItem();
|
||||
if (!dimParent) {
|
||||
continue;
|
||||
}
|
||||
|
||||
QGIView* dimItem = dynamic_cast<QGIView*>(dimParent);
|
||||
|
||||
if (!dimItem) {
|
||||
continue;
|
||||
}
|
||||
|
||||
TechDraw::DrawView* dimObj = dimItem->getViewObject();
|
||||
if (!dimObj) {
|
||||
continue;
|
||||
}
|
||||
const char* name = dimObj->getNameInDocument();
|
||||
if (!name) {//can happen during undo/redo if Dim is selected???
|
||||
else if (dynamic_cast<QGIDatumLabel*>(scene) || dynamic_cast<QGMText*>(scene)) {
|
||||
if (!obj_name) {//can happen during undo/redo if Dim is selected???
|
||||
//Base::Console().Log("INFO - MDIVP::sceneSelectionChanged - dimObj name is null!\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
//bool accepted =
|
||||
static_cast<void>(Gui::Selection().addSelection(dimObj->getDocument()->getName(),
|
||||
dimObj->getNameInDocument()));
|
||||
}
|
||||
|
||||
QGMText* mText = dynamic_cast<QGMText*>(*it);
|
||||
if (mText) {
|
||||
QGraphicsItem* textParent = mText->QGraphicsItem::parentItem();
|
||||
if (!textParent) {
|
||||
continue;
|
||||
}
|
||||
|
||||
QGIView* parent = dynamic_cast<QGIView*>(textParent);
|
||||
|
||||
if (!parent) {
|
||||
continue;
|
||||
}
|
||||
|
||||
TechDraw::DrawView* parentFeat = parent->getViewObject();
|
||||
if (!parentFeat) {
|
||||
continue;
|
||||
}
|
||||
const char* name = parentFeat->getNameInDocument();
|
||||
if (!name) {//can happen during undo/redo if Dim is selected???
|
||||
continue;
|
||||
}
|
||||
|
||||
//bool accepted =
|
||||
static_cast<void>(Gui::Selection().addSelection(
|
||||
parentFeat->getDocument()->getName(), parentFeat->getNameInDocument()));
|
||||
Gui::Selection().addSelection(doc_name, obj_name);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
TechDraw::DrawView* viewObj = itemView->getViewObject();
|
||||
if (viewObj && !viewObj->isRemoving()) {
|
||||
std::string doc_name = viewObj->getDocument()->getName();
|
||||
std::string obj_name = viewObj->getNameInDocument();
|
||||
const char* doc_name = viewObj->getDocument()->getName();
|
||||
const char* obj_name = viewObj->getNameInDocument();
|
||||
|
||||
Gui::Selection().addSelection(doc_name.c_str(), obj_name.c_str());
|
||||
showStatusMsg(doc_name.c_str(), obj_name.c_str(), "");
|
||||
Gui::Selection().addSelection(doc_name, obj_name);
|
||||
showStatusMsg(doc_name, obj_name, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -922,6 +838,138 @@ void MDIViewPage::setTreeToSceneSelect()
|
||||
blockSelection(saveBlock);
|
||||
}
|
||||
|
||||
std::string MDIViewPage::getSceneSubName(QGraphicsItem* scene)
|
||||
{
|
||||
auto* edge = dynamic_cast<QGIEdge*>(scene);
|
||||
auto* vert = dynamic_cast<QGIVertex*>(scene);
|
||||
auto* face = dynamic_cast<QGIFace*>(scene);
|
||||
if (edge || vert || face) {
|
||||
auto* viewItem = dynamic_cast<QGIView*>(scene->parentItem());
|
||||
if (viewItem) {
|
||||
TechDraw::DrawView* viewObj = viewItem->getViewObject();
|
||||
|
||||
std::stringstream ss;
|
||||
if (edge) { ss << "Edge" << edge->getProjIndex(); }
|
||||
else if (vert) { ss << "Vertex" << vert->getProjIndex(); }
|
||||
else { ss << "Face" << face->getProjIndex(); }
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// adds scene to core selection if it's not in already.
|
||||
void MDIViewPage::addSceneToTreeSel(QGraphicsItem* sn, std::vector<Gui::SelectionObject> treeSel)
|
||||
{
|
||||
auto* itemView = dynamic_cast<QGIView*>(sn);
|
||||
if (!itemView) {
|
||||
auto* parent = dynamic_cast<QGIView*>(sn->parentItem());
|
||||
if (!parent) {
|
||||
return;
|
||||
}
|
||||
TechDraw::DrawView* viewObj = parent->getViewObject();
|
||||
if (!viewObj) {
|
||||
return;
|
||||
}
|
||||
|
||||
const char* doc_name = viewObj->getDocument()->getName();
|
||||
const char* obj_name = viewObj->getNameInDocument();
|
||||
std::string sub_name;
|
||||
|
||||
if (dynamic_cast<QGIEdge*>(sn) || dynamic_cast<QGIVertex*>(sn) || dynamic_cast<QGIFace*>(sn)) {
|
||||
sub_name = getSceneSubName(sn);
|
||||
}
|
||||
|
||||
else if (dynamic_cast<QGIDatumLabel*>(sn) || dynamic_cast<QGMText*>(sn)) {
|
||||
if (!obj_name) {//can happen during undo/redo if Dim is selected???
|
||||
return;
|
||||
}
|
||||
}
|
||||
else { // are there other cases?
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Gui::Selection().isSelected(viewObj, sub_name.c_str())) {
|
||||
Gui::Selection().addSelection(doc_name, obj_name, sub_name.c_str());
|
||||
showStatusMsg(doc_name, obj_name, sub_name.c_str());
|
||||
}
|
||||
}
|
||||
else {
|
||||
TechDraw::DrawView* viewObj = itemView->getViewObject();
|
||||
if (viewObj && !viewObj->isRemoving()) {
|
||||
const char* doc_name = viewObj->getDocument()->getName();
|
||||
const char* obj_name = viewObj->getNameInDocument();
|
||||
|
||||
if (!Gui::Selection().isSelected(viewObj)) {
|
||||
Gui::Selection().addSelection(doc_name, obj_name);
|
||||
showStatusMsg(doc_name, obj_name, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove core selection if scene is not selected anymore
|
||||
void MDIViewPage::removeSelFromTreeSel(QList<QGraphicsItem*> sceneSel, Gui::SelectionObject& sel)
|
||||
{
|
||||
std::string selDocName = sel.getDocName();
|
||||
App::DocumentObject* selObj = sel.getObject();
|
||||
|
||||
for (auto& sub : sel.getSubNames()) {
|
||||
bool found = false;
|
||||
for (auto& sn : sceneSel) {
|
||||
auto* itemView = dynamic_cast<QGIView*>(sn);
|
||||
if (!itemView) {
|
||||
auto* parent = dynamic_cast<QGIView*>(sn->parentItem());
|
||||
if (!parent) {
|
||||
continue;
|
||||
}
|
||||
TechDraw::DrawView* viewObj = parent->getViewObject();
|
||||
if (!viewObj) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const char* doc_name = viewObj->getDocument()->getName();
|
||||
const char* obj_name = viewObj->getNameInDocument();
|
||||
std::string sub_name;
|
||||
|
||||
if (dynamic_cast<QGIEdge*>(sn) || dynamic_cast<QGIVertex*>(sn) || dynamic_cast<QGIFace*>(sn)) {
|
||||
sub_name = getSceneSubName(sn);
|
||||
}
|
||||
|
||||
else if (dynamic_cast<QGIDatumLabel*>(sn) || dynamic_cast<QGMText*>(sn)) {
|
||||
if (!obj_name) {//can happen during undo/redo if Dim is selected???
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else { // are there other cases?
|
||||
continue;
|
||||
}
|
||||
|
||||
if (selDocName == doc_name && selObj == viewObj && sub == sub_name) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
TechDraw::DrawView* viewObj = itemView->getViewObject();
|
||||
if (viewObj && !viewObj->isRemoving()) {
|
||||
const char* doc_name = viewObj->getDocument()->getName();
|
||||
const char* obj_name = viewObj->getNameInDocument();
|
||||
|
||||
if (selDocName == doc_name && selObj == viewObj) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
Gui::Selection().rmvSelection(sel.getDocName(), sel.getObject()->getNameInDocument(), sub.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool MDIViewPage::compareSelections(std::vector<Gui::SelectionObject> treeSel,
|
||||
QList<QGraphicsItem*> sceneSel)
|
||||
{
|
||||
@@ -1020,6 +1068,17 @@ void MDIViewPage::showStatusMsg(const char* string1, const char* string2, const
|
||||
}
|
||||
}
|
||||
|
||||
void MDIViewPage::setDimensionsSelectability(bool val)
|
||||
{
|
||||
for (auto scene : m_scene->items()) {
|
||||
auto* dl = dynamic_cast<QGIDatumLabel*>(scene);
|
||||
if (dl) {
|
||||
dl->setSelectability(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void MDIViewPagePy::init_type()
|
||||
|
||||
@@ -109,6 +109,9 @@ public:
|
||||
void setScene(QGSPage* scene, QGVPage* view);
|
||||
void fixSceneDependencies();
|
||||
|
||||
void setDimensionsSelectability(bool val);
|
||||
void enableContextualMenu(bool val) { isContextualMenuEnabled = val; }
|
||||
|
||||
public Q_SLOTS:
|
||||
void viewAll() override;
|
||||
void saveSVG();
|
||||
@@ -127,6 +130,9 @@ protected:
|
||||
void onDeleteObject(const App::DocumentObject& obj);
|
||||
|
||||
bool compareSelections(std::vector<Gui::SelectionObject> treeSel, QList<QGraphicsItem*> sceneSel);
|
||||
void addSceneToTreeSel(QGraphicsItem* scene, std::vector<Gui::SelectionObject> treeSel);
|
||||
void removeSelFromTreeSel(QList<QGraphicsItem*> sceneSel, Gui::SelectionObject& sel);
|
||||
std::string getSceneSubName(QGraphicsItem* scene);
|
||||
void setTreeToSceneSelect();
|
||||
void sceneSelectionManager();
|
||||
|
||||
@@ -144,6 +150,7 @@ private:
|
||||
std::string m_objectName;
|
||||
std::string m_documentName;
|
||||
bool isSelectionBlocked;
|
||||
bool isContextualMenuEnabled;
|
||||
QPointer<QGSPage> m_scene;
|
||||
|
||||
QString m_currentPath;
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <App/Material.h>
|
||||
#include <Base/Console.h>
|
||||
#include <Base/Parameter.h>
|
||||
#include <Gui/Selection.h>
|
||||
#include <Mod/TechDraw/App/Preferences.h>
|
||||
#include <Mod/TechDraw/App/LineGenerator.h>
|
||||
|
||||
@@ -214,7 +215,8 @@ bool PreferencesGui::showGrid()
|
||||
|
||||
bool PreferencesGui::multiSelection()
|
||||
{
|
||||
return Preferences::getPreferenceGroup("General")->GetBool("multiSelection", false);
|
||||
bool greedy = Gui::Selection().getSelectionStyle() == Gui::SelectionSingleton::SelectionStyle::GreedySelection;
|
||||
return greedy || Preferences::getPreferenceGroup("General")->GetBool("multiSelection", false);
|
||||
}
|
||||
|
||||
App::Color PreferencesGui::pageColor()
|
||||
|
||||
@@ -93,8 +93,7 @@ QGIDatumLabel::QGIDatumLabel() : m_dragState(NoDrag)
|
||||
setCacheMode(QGraphicsItem::NoCache);
|
||||
setFlag(ItemSendsGeometryChanges, true);
|
||||
setFlag(ItemIsMovable, true);
|
||||
setFlag(ItemIsSelectable, true);
|
||||
setAcceptHoverEvents(true);
|
||||
setSelectability(true);
|
||||
setFiltersChildEvents(true);
|
||||
|
||||
m_dimText = new QGCustomText();
|
||||
@@ -445,6 +444,13 @@ void QGIDatumLabel::setColor(QColor color)
|
||||
m_unitText->setColor(m_colNormal);
|
||||
}
|
||||
|
||||
void QGIDatumLabel::setSelectability(bool val)
|
||||
{
|
||||
setFlag(ItemIsSelectable, val);
|
||||
setAcceptHoverEvents(val);
|
||||
setAcceptedMouseButtons(val ? Qt::AllButtons : Qt::NoButton);
|
||||
}
|
||||
|
||||
//**************************************************************
|
||||
QGIViewDimension::QGIViewDimension() : dvDimension(nullptr), hasHover(false), m_lineWidth(0.0)
|
||||
{
|
||||
@@ -717,9 +723,9 @@ void QGIViewDimension::draw()
|
||||
return;
|
||||
}
|
||||
|
||||
TechDraw::DrawViewDimension* dim = dynamic_cast<TechDraw::DrawViewDimension*>(getViewObject());
|
||||
auto* dim = dynamic_cast<TechDraw::DrawViewDimension*>(getViewObject());
|
||||
if (!dim ||//nothing to draw, don't try
|
||||
!dim->isDerivedFrom(TechDraw::DrawViewDimension::getClassTypeId())
|
||||
!dim->isDerivedFrom<TechDraw::DrawViewDimension>()
|
||||
|| !dim->has2DReferences()) {
|
||||
datumLabel->hide();
|
||||
hide();
|
||||
@@ -767,6 +773,9 @@ void QGIViewDimension::draw()
|
||||
else if (strcmp(dimType, "Angle") == 0 || strcmp(dimType, "Angle3Pt") == 0) {
|
||||
drawAngle(dim, vp);
|
||||
}
|
||||
else if (strcmp(dimType, "Area") == 0) {
|
||||
drawArea(dim, vp);
|
||||
}
|
||||
else {
|
||||
Base::Console().Error("QGIVD::draw - this DimensionType is unknown: %s\n", dimType);
|
||||
}
|
||||
@@ -1255,7 +1264,7 @@ void QGIViewDimension::resetArrows() const
|
||||
}
|
||||
|
||||
void QGIViewDimension::drawArrows(int count, const Base::Vector2d positions[], double angles[],
|
||||
bool flipped) const
|
||||
bool flipped, bool forcePoint) const
|
||||
{
|
||||
const int arrowCount = 2;
|
||||
QGIArrow* arrows[arrowCount] = {aHead1, aHead2};
|
||||
@@ -1275,7 +1284,8 @@ void QGIViewDimension::drawArrows(int count, const Base::Vector2d positions[], d
|
||||
continue;
|
||||
}
|
||||
|
||||
arrow->setStyle(QGIArrow::getPrefArrowStyle());
|
||||
// some dimensions must use point ends (area). The point style is 3.
|
||||
arrow->setStyle(forcePoint ? 3 : QGIArrow::getPrefArrowStyle());
|
||||
auto vp = static_cast<ViewProviderDimension*>(getViewProvider(getViewObject()));
|
||||
auto arrowSize = vp->Arrowsize.getValue();
|
||||
arrow->setSize(arrowSize);
|
||||
@@ -1403,7 +1413,7 @@ void QGIViewDimension::drawDimensionLine(QPainterPath& painterPath,
|
||||
const Base::Vector2d& targetPoint, double lineAngle,
|
||||
double startPosition, double jointPosition,
|
||||
const Base::BoundBox2d& labelRectangle, int arrowCount,
|
||||
int standardStyle, bool flipArrows) const
|
||||
int standardStyle, bool flipArrows, bool forcePointStyle) const
|
||||
{
|
||||
// Keep the convention start position <= 0
|
||||
jointPosition *= normalizeStartPosition(startPosition, lineAngle);
|
||||
@@ -1423,7 +1433,7 @@ void QGIViewDimension::drawDimensionLine(QPainterPath& painterPath,
|
||||
arrowAngles[0] = lineAngle;
|
||||
arrowAngles[1] = lineAngle + M_PI;
|
||||
|
||||
drawArrows(arrowCount, arrowPositions, arrowAngles, flipArrows);
|
||||
drawArrows(arrowCount, arrowPositions, arrowAngles, flipArrows, forcePointStyle);
|
||||
}
|
||||
|
||||
void QGIViewDimension::drawDimensionArc(QPainterPath& painterPath, const Base::Vector2d& arcCenter,
|
||||
@@ -2085,6 +2095,75 @@ void QGIViewDimension::drawRadiusExecutive(const Base::Vector2d& centerPoint,
|
||||
dimLines->setPath(radiusPath);
|
||||
}
|
||||
|
||||
void QGIViewDimension::drawAreaExecutive(const Base::Vector2d& centerPoint, double area,
|
||||
const Base::BoundBox2d& labelRectangle,
|
||||
double centerOverhang, int standardStyle,
|
||||
int renderExtent, bool flipArrow) const
|
||||
{
|
||||
QPainterPath areaPath;
|
||||
|
||||
Base::Vector2d labelCenter(labelRectangle.GetCenter());
|
||||
double labelAngle = 0.0;
|
||||
bool forcePointStyle = true;
|
||||
|
||||
if (standardStyle == ViewProviderDimension::STD_STYLE_ISO_REFERENCING
|
||||
|| standardStyle == ViewProviderDimension::STD_STYLE_ASME_REFERENCING) {
|
||||
// The dimensional value text must stay horizontal
|
||||
|
||||
bool left = labelCenter.x < centerPoint.x;
|
||||
|
||||
Base::Vector2d jointDirection;
|
||||
if (standardStyle == ViewProviderDimension::STD_STYLE_ISO_REFERENCING) {
|
||||
jointDirection = getIsoRefJointPoint(labelRectangle, left) - centerPoint;
|
||||
}
|
||||
else {
|
||||
jointDirection = getAsmeRefJointPoint(labelRectangle, left) - centerPoint;
|
||||
}
|
||||
|
||||
double lineAngle = jointDirection.Angle();
|
||||
double jointPositions = jointDirection.Length();
|
||||
|
||||
drawDimensionLine(areaPath, centerPoint, lineAngle, 0.0, jointPositions, labelRectangle, 1, standardStyle, flipArrow, forcePointStyle);
|
||||
|
||||
Base::Vector2d outsetPoint(standardStyle == ViewProviderDimension::STD_STYLE_ISO_REFERENCING
|
||||
? getIsoRefOutsetPoint(labelRectangle, left)
|
||||
: getAsmeRefOutsetPoint(labelRectangle, left));
|
||||
|
||||
areaPath.moveTo(toQtGui(outsetPoint));
|
||||
areaPath.lineTo(toQtGui(centerPoint + jointDirection));
|
||||
}
|
||||
else if (standardStyle == ViewProviderDimension::STD_STYLE_ISO_ORIENTED) {
|
||||
// We may rotate the label so no reference line is needed
|
||||
double lineAngle;
|
||||
double devAngle = computeLineAndLabelAngles(centerPoint, labelCenter,
|
||||
labelRectangle.Height() * 0.5 + getIsoDimensionLineSpacing(),
|
||||
lineAngle, labelAngle);
|
||||
|
||||
lineAngle = lineAngle - M_PI;
|
||||
double labelPosition = -cos(devAngle) * ((labelCenter - centerPoint).Length());
|
||||
|
||||
drawDimensionLine(areaPath, centerPoint, lineAngle, 0.0, labelPosition, labelRectangle, 1, standardStyle, flipArrow, forcePointStyle);
|
||||
}
|
||||
else if (standardStyle == ViewProviderDimension::STD_STYLE_ASME_INLINED) {
|
||||
// Text must remain horizontal, but it may split the leader line
|
||||
Base::Vector2d labelDirection(labelCenter - centerPoint);
|
||||
double lineAngle = labelDirection.Angle();
|
||||
double labelPosition = labelDirection.Length();
|
||||
|
||||
drawDimensionLine(areaPath, centerPoint, lineAngle, 0.0, labelPosition, labelRectangle, 1, standardStyle, flipArrow, forcePointStyle);
|
||||
}
|
||||
else {
|
||||
Base::Console().Error(
|
||||
"QGIVD::drawRadiusExecutive - this Standard&Style is not supported: %d\n",
|
||||
standardStyle);
|
||||
}
|
||||
|
||||
datumLabel->setTransformOriginPoint(datumLabel->boundingRect().center());
|
||||
datumLabel->setRotation(toQtDeg(labelAngle));
|
||||
|
||||
dimLines->setPath(areaPath);
|
||||
}
|
||||
|
||||
void QGIViewDimension::drawDistance(TechDraw::DrawViewDimension* dimension,
|
||||
ViewProviderDimension* viewProvider) const
|
||||
{
|
||||
@@ -2510,6 +2589,21 @@ void QGIViewDimension::drawAngle(TechDraw::DrawViewDimension* dimension,
|
||||
dimLines->setPath(anglePath);
|
||||
}
|
||||
|
||||
void QGIViewDimension::drawArea(TechDraw::DrawViewDimension* dimension,
|
||||
ViewProviderDimension* viewProvider) const
|
||||
{
|
||||
Base::BoundBox2d labelRectangle(
|
||||
fromQtGui(mapRectFromItem(datumLabel, datumLabel->boundingRect())));
|
||||
areaPoint areaPoint = dimension->getAreaPoint();
|
||||
|
||||
double endAngle;
|
||||
double startRotation;
|
||||
|
||||
drawAreaExecutive(
|
||||
fromQtApp(areaPoint.center), areaPoint.area, labelRectangle, 0.0, viewProvider->StandardAndStyle.getValue(),
|
||||
viewProvider->RenderingExtent.getValue(), viewProvider->FlipArrowheads.getValue());
|
||||
}
|
||||
|
||||
QColor QGIViewDimension::prefNormalColor()
|
||||
{
|
||||
setNormalColor(PreferencesGui::getAccessibleQColor(PreferencesGui::dimQColor()));
|
||||
|
||||
@@ -87,6 +87,7 @@ public:
|
||||
void setPrettyPre();
|
||||
void setPrettyNormal();
|
||||
void setColor(QColor color);
|
||||
void setSelectability(bool val);
|
||||
|
||||
QGCustomText* getDimText() { return m_dimText; }
|
||||
void setDimText(QGCustomText* newText) { m_dimText = newText; }
|
||||
@@ -232,7 +233,7 @@ protected:
|
||||
void draw() override;
|
||||
|
||||
void resetArrows() const;
|
||||
void drawArrows(int count, const Base::Vector2d positions[], double angles[], bool flipped) const;
|
||||
void drawArrows(int count, const Base::Vector2d positions[], double angles[], bool flipped, bool forcePoint = false) const;
|
||||
|
||||
void drawSingleLine(QPainterPath &painterPath, const Base::Vector2d &lineOrigin, double lineAngle,
|
||||
double startPosition, double endPosition) const;
|
||||
@@ -245,7 +246,7 @@ protected:
|
||||
|
||||
void drawDimensionLine(QPainterPath &painterPath, const Base::Vector2d &targetPoint, double lineAngle,
|
||||
double startPosition, double jointPosition, const Base::BoundBox2d &labelRectangle,
|
||||
int arrowCount, int standardStyle, bool flipArrows) const;
|
||||
int arrowCount, int standardStyle, bool flipArrows, bool forcePointStyle = false) const;
|
||||
void drawDimensionArc(QPainterPath &painterPath, const Base::Vector2d &arcCenter, double arcRadius,
|
||||
double endAngle, double startRotation, double jointAngle,
|
||||
const Base::BoundBox2d &labelRectangle, int arrowCount,
|
||||
@@ -261,10 +262,14 @@ protected:
|
||||
double endAngle, double startRotation, const Base::BoundBox2d &labelRectangle,
|
||||
double centerOverhang, int standardStyle, int renderExtent, bool flipArrow) const;
|
||||
|
||||
void drawAreaExecutive(const Base::Vector2d ¢erPoint, double area, const Base::BoundBox2d &labelRectangle,
|
||||
double centerOverhang, int standardStyle, int renderExtent, bool flipArrow) const;
|
||||
|
||||
void drawDistance(TechDraw::DrawViewDimension *dimension, ViewProviderDimension *viewProvider) const;
|
||||
void drawRadius(TechDraw::DrawViewDimension *dimension, ViewProviderDimension *viewProvider) const;
|
||||
void drawDiameter(TechDraw::DrawViewDimension *dimension, ViewProviderDimension *viewProvider) const;
|
||||
void drawAngle(TechDraw::DrawViewDimension *dimension, ViewProviderDimension *viewProvider) const;
|
||||
void drawArea(TechDraw::DrawViewDimension *dimension, ViewProviderDimension *viewProvider) const;
|
||||
|
||||
QVariant itemChange( GraphicsItemChange change,
|
||||
const QVariant &value ) override;
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
#include "QGVNavStyleTouchpad.h"
|
||||
#include "QGVPage.h"
|
||||
#include "Rez.h"
|
||||
#include "TechDrawHandler.h"
|
||||
#include "ViewProviderPage.h"
|
||||
|
||||
|
||||
@@ -167,7 +168,7 @@ public:
|
||||
QGVPage::QGVPage(ViewProviderPage* vpPage, QGSPage* scenePage, QWidget* parent)
|
||||
: QGraphicsView(parent), m_renderer(Native), drawBkg(true), m_vpPage(nullptr),
|
||||
m_scene(scenePage), balloonPlacing(false), m_showGrid(false),
|
||||
m_navStyle(nullptr), d(new Private(this))
|
||||
m_navStyle(nullptr), d(new Private(this)), toolHandler(nullptr)
|
||||
{
|
||||
assert(vpPage);
|
||||
m_vpPage = vpPage;
|
||||
@@ -281,6 +282,31 @@ void QGVPage::setNavigationStyle(std::string navParm)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void QGVPage::activateHandler(TechDrawHandler* newHandler)
|
||||
{
|
||||
if (toolHandler) {
|
||||
toolHandler->deactivate();
|
||||
}
|
||||
|
||||
toolHandler = std::unique_ptr<TechDrawHandler>(newHandler);
|
||||
toolHandler->activate(this);
|
||||
|
||||
// make sure receiver has focus so immediately pressing Escape will be handled by
|
||||
// ViewProviderSketch::keyPressed() and dismiss the active handler, and not the entire
|
||||
// sketcher editor
|
||||
//Gui::MDIView* mdi = Gui::Application::Instance->activeDocument()->getActiveView();
|
||||
//mdi->setFocus();
|
||||
}
|
||||
|
||||
void QGVPage::deactivateHandler()
|
||||
{
|
||||
if (toolHandler) {
|
||||
toolHandler->deactivate();
|
||||
toolHandler = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void QGVPage::startBalloonPlacing(DrawView* parent)
|
||||
{
|
||||
// Base::Console().Message("QGVP::startBalloonPlacing(%s)\n", parent->getNameInDocument());
|
||||
@@ -421,7 +447,12 @@ void QGVPage::wheelEvent(QWheelEvent* event)
|
||||
|
||||
void QGVPage::keyPressEvent(QKeyEvent* event)
|
||||
{
|
||||
m_navStyle->handleKeyPressEvent(event);
|
||||
if (toolHandler) {
|
||||
toolHandler->keyPressEvent(event);
|
||||
}
|
||||
else {
|
||||
m_navStyle->handleKeyPressEvent(event);
|
||||
}
|
||||
if (!event->isAccepted()) {
|
||||
QGraphicsView::keyPressEvent(event);
|
||||
}
|
||||
@@ -429,7 +460,12 @@ void QGVPage::keyPressEvent(QKeyEvent* event)
|
||||
|
||||
void QGVPage::keyReleaseEvent(QKeyEvent* event)
|
||||
{
|
||||
m_navStyle->handleKeyReleaseEvent(event);
|
||||
if (toolHandler) {
|
||||
toolHandler->keyReleaseEvent(event);
|
||||
}
|
||||
else {
|
||||
m_navStyle->handleKeyReleaseEvent(event);
|
||||
}
|
||||
if (!event->isAccepted()) {
|
||||
QGraphicsView::keyReleaseEvent(event);
|
||||
}
|
||||
@@ -465,6 +501,11 @@ void QGVPage::enterEvent(QEvent* event)
|
||||
void QGVPage::enterEvent(QEnterEvent* event)
|
||||
#endif
|
||||
{
|
||||
if (toolHandler) {
|
||||
// if the user interacted with another widget than the mdi, the cursor got unset.
|
||||
// So we reapply it.
|
||||
toolHandler->updateCursor();
|
||||
}
|
||||
QGraphicsView::enterEvent(event);
|
||||
m_navStyle->handleEnterEvent(event);
|
||||
QGraphicsView::enterEvent(event);
|
||||
@@ -478,21 +519,37 @@ void QGVPage::leaveEvent(QEvent* event)
|
||||
|
||||
void QGVPage::mousePressEvent(QMouseEvent* event)
|
||||
{
|
||||
m_navStyle->handleMousePressEvent(event);
|
||||
if (toolHandler && (event->button() != Qt::MiddleButton)) {
|
||||
toolHandler->mousePressEvent(event);
|
||||
}
|
||||
else {
|
||||
m_navStyle->handleMousePressEvent(event);
|
||||
}
|
||||
QGraphicsView::mousePressEvent(event);
|
||||
}
|
||||
|
||||
void QGVPage::mouseMoveEvent(QMouseEvent* event)
|
||||
{
|
||||
m_navStyle->handleMouseMoveEvent(event);
|
||||
if (toolHandler) {
|
||||
toolHandler->mouseMoveEvent(event);
|
||||
}
|
||||
else {
|
||||
m_navStyle->handleMouseMoveEvent(event);
|
||||
}
|
||||
QGraphicsView::mouseMoveEvent(event);
|
||||
}
|
||||
|
||||
void QGVPage::mouseReleaseEvent(QMouseEvent* event)
|
||||
{
|
||||
m_navStyle->handleMouseReleaseEvent(event);
|
||||
QGraphicsView::mouseReleaseEvent(event);
|
||||
resetCursor();
|
||||
if (toolHandler && (event->button() != Qt::MiddleButton)) {
|
||||
QGraphicsView::mouseReleaseEvent(event);
|
||||
toolHandler->mouseReleaseEvent(event);
|
||||
}
|
||||
else {
|
||||
m_navStyle->handleMouseReleaseEvent(event);
|
||||
QGraphicsView::mouseReleaseEvent(event);
|
||||
resetCursor();
|
||||
}
|
||||
}
|
||||
|
||||
TechDraw::DrawPage* QGVPage::getDrawPage() { return m_vpPage->getDrawPage(); }
|
||||
@@ -553,8 +610,7 @@ void QGVPage::activateCursor(QCursor cursor)
|
||||
|
||||
void QGVPage::resetCursor()
|
||||
{
|
||||
this->setCursor(Qt::ArrowCursor);
|
||||
viewport()->setCursor(Qt::ArrowCursor);
|
||||
activateCursor(Qt::ArrowCursor);
|
||||
}
|
||||
|
||||
void QGVPage::setPanCursor() { activateCursor(panCursor); }
|
||||
|
||||
@@ -71,6 +71,7 @@ class QGILeaderLine;
|
||||
class QGIRichAnno;
|
||||
class QGITile;
|
||||
class QGVNavStyle;
|
||||
class TechDrawHandler;
|
||||
|
||||
class TechDrawGuiExport QGVPage: public QGraphicsView
|
||||
{
|
||||
@@ -101,6 +102,10 @@ public:
|
||||
void showGrid(bool state) { m_showGrid = state; }
|
||||
void updateViewport() { viewport()->repaint(); }
|
||||
|
||||
void activateHandler(TechDrawHandler* newHandler);
|
||||
void deactivateHandler();
|
||||
bool isHandlerActive() { return toolHandler != nullptr; }
|
||||
|
||||
bool isBalloonPlacing() const { return balloonPlacing; }
|
||||
void setBalloonPlacing(bool isPlacing) { balloonPlacing = isPlacing; }
|
||||
|
||||
@@ -196,6 +201,8 @@ private:
|
||||
|
||||
MDIViewPage* m_parentMDI;
|
||||
QContextMenuEvent* m_saveContextEvent;
|
||||
|
||||
std::unique_ptr<TechDrawHandler> toolHandler;
|
||||
};
|
||||
|
||||
}// namespace TechDrawGui
|
||||
|
||||
@@ -86,10 +86,12 @@
|
||||
<file>icons/square.svg</file>
|
||||
<file>icons/TechDraw_3PtAngleDimension.svg</file>
|
||||
<file>icons/TechDraw_AngleDimension.svg</file>
|
||||
<file>icons/TechDraw_AreaDimension.svg</file>
|
||||
<file>icons/TechDraw_Balloon.svg</file>
|
||||
<file>icons/TechDraw_CameraOrientation.svg</file>
|
||||
<file>icons/TechDraw_DiameterDimension.svg</file>
|
||||
<file>icons/TechDraw_Dimension.svg</file>
|
||||
<file>icons/TechDraw_Dimension_Pointer.svg</file>
|
||||
<file>icons/TechDraw_DimensionRepair.svg</file>
|
||||
<file>icons/TechDraw_ExtensionAreaAnnotation.svg</file>
|
||||
<file>icons/TechDraw_ExtensionArcLengthAnnotation.svg</file>
|
||||
|
||||
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 5.5 KiB |
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 11 KiB |
@@ -0,0 +1,146 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
version="1.1"
|
||||
height="64"
|
||||
width="64"
|
||||
id="svg12"
|
||||
sodipodi:docname="TechDraw_Dimension_Pointer.svg"
|
||||
inkscape:version="1.1-beta1 (77e7b44db3, 2021-03-28)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview1"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:zoom="14.59375"
|
||||
inkscape:cx="29.910064"
|
||||
inkscape:cy="29.498929"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="1571"
|
||||
inkscape:window-x="-9"
|
||||
inkscape:window-y="-9"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg12"
|
||||
objecttolerance="10.0"
|
||||
gridtolerance="10.0"
|
||||
guidetolerance="10.0"
|
||||
inkscape:pageshadow="0"
|
||||
showgrid="false" />
|
||||
<defs
|
||||
id="defs16">
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3026"
|
||||
id="linearGradient927"
|
||||
x1="16.969255"
|
||||
y1="39.85923"
|
||||
x2="58.005249"
|
||||
y2="39.85923"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
id="linearGradient3026"
|
||||
inkscape:collect="always">
|
||||
<stop
|
||||
id="stop3028"
|
||||
offset="0"
|
||||
style="stop-color:#c4a000;stop-opacity:1" />
|
||||
<stop
|
||||
id="stop3030"
|
||||
offset="1"
|
||||
style="stop-color:#fce94f;stop-opacity:1" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g
|
||||
id="crosshair"
|
||||
style="stroke:#ffffff;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:miter"
|
||||
transform="translate(-0.4111349)">
|
||||
<path
|
||||
d="m 16,3 v 9 m 0,8 v 9 M 3,16 h 9 m 8,0 h 9"
|
||||
id="path9" />
|
||||
</g>
|
||||
<g
|
||||
id="g1123"
|
||||
transform="matrix(0.92503381,0,0,0.92503381,6.1433162,7.4809763)">
|
||||
<path
|
||||
style="fill:none;stroke:#302b00;stroke-width:4;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:100;stroke-dasharray:none;stroke-dashoffset:8.71;stroke-opacity:1"
|
||||
id="path3"
|
||||
sodipodi:type="arc"
|
||||
sodipodi:cx="42.62447"
|
||||
sodipodi:cy="32.611259"
|
||||
sodipodi:rx="16.283468"
|
||||
sodipodi:ry="16.283468"
|
||||
sodipodi:start="5.3462224"
|
||||
sodipodi:end="0.51990659"
|
||||
sodipodi:arc-type="arc"
|
||||
sodipodi:open="true"
|
||||
transform="rotate(12.779233)"
|
||||
d="m 52.268157,19.490641 a 16.283468,16.283468 0 0 1 4.488175,21.21023" />
|
||||
<path
|
||||
style="fill:none;stroke:#302b00;stroke-width:8;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:100;stroke-dasharray:none;stroke-dashoffset:8.71;stroke-opacity:1"
|
||||
d="M 54.090138,23.080858 18.968981,44.576119 56.005249,56.637604"
|
||||
id="path1" />
|
||||
<path
|
||||
style="fill:none;stroke:#fce94f;stroke-width:2;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:100;stroke-dasharray:none;stroke-dashoffset:8.71;stroke-opacity:1"
|
||||
id="path3-6"
|
||||
sodipodi:type="arc"
|
||||
sodipodi:cx="42.62447"
|
||||
sodipodi:cy="32.658588"
|
||||
sodipodi:rx="16.283468"
|
||||
sodipodi:ry="16.283468"
|
||||
sodipodi:start="5.2511532"
|
||||
sodipodi:end="0.51990659"
|
||||
sodipodi:arc-type="arc"
|
||||
sodipodi:open="true"
|
||||
transform="rotate(12.779233)"
|
||||
d="M 50.979121,18.681781 A 16.283468,16.283468 0 0 1 56.756332,40.7482" />
|
||||
<path
|
||||
style="fill:none;stroke:url(#linearGradient927);stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:100;stroke-dasharray:none;stroke-dashoffset:8.71;stroke-opacity:1"
|
||||
d="M 54.090138,23.080858 18.968981,44.576119 56.005249,56.637604"
|
||||
id="path1-3" />
|
||||
<path
|
||||
style="fill:none;stroke:#fce94f;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:100;stroke-dasharray:none;stroke-dashoffset:8.71;stroke-opacity:1"
|
||||
d="M 54.03712,22.151886 18.920565,43.727975 55.94574,55.594886"
|
||||
id="path2"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<path
|
||||
style="fill:none;stroke:#302b00;stroke-width:4;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:100;stroke-dasharray:none;stroke-dashoffset:8.71;stroke-opacity:1"
|
||||
d="M 59.334145,21.127535 49.123924,6.3035436"
|
||||
id="path4" />
|
||||
<path
|
||||
style="fill:none;stroke:#fce94f;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:100;stroke-dasharray:none;stroke-dashoffset:8.71;stroke-opacity:1"
|
||||
d="M 59.334145,21.127535 49.123924,6.3035439"
|
||||
id="path4-7" />
|
||||
<path
|
||||
style="fill:none;stroke:#302b00;stroke-width:4;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:100;stroke-dasharray:none;stroke-dashoffset:8.71;stroke-opacity:1"
|
||||
d="M 14.780546,48.06322 4.5703249,33.239228"
|
||||
id="path4-2" />
|
||||
<path
|
||||
style="fill:none;stroke:#fce94f;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:100;stroke-dasharray:none;stroke-dashoffset:8.71;stroke-opacity:1"
|
||||
d="M 14.780546,48.06322 4.5703248,33.239228"
|
||||
id="path4-7-9" />
|
||||
<path
|
||||
style="fill:none;stroke:#302b00;stroke-width:4;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:100;stroke-dasharray:none;stroke-dashoffset:8.71;stroke-opacity:1"
|
||||
d="M 39.969325,13.041079 15.273234,28.142693"
|
||||
id="path6" />
|
||||
<path
|
||||
style="fill:#fce94f;fill-opacity:1;stroke:#302b00;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:100;stroke-dasharray:none;stroke-dashoffset:8.71;stroke-opacity:1"
|
||||
d="m 38.468308,8.9727464 c 9.40717,-0.9537682 9.40717,-0.9537682 9.40717,-0.9537682 l -4.952425,8.2021028 z"
|
||||
id="path5" />
|
||||
<path
|
||||
style="fill:#fce94f;fill-opacity:1;stroke:#302b00;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:100;stroke-dasharray:none;stroke-dashoffset:8.71;stroke-opacity:1"
|
||||
d="M 16.774251,32.211025 C 7.3670811,33.164794 7.3670811,33.164794 7.3670811,33.164794 L 12.319506,24.96269 Z"
|
||||
id="path5-1" />
|
||||
<path
|
||||
style="fill:none;stroke:#fce94f;stroke-width:2.00001;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:100;stroke-dasharray:none;stroke-dashoffset:8.71;stroke-opacity:1"
|
||||
d="M 40.879356,12.483498 14.021683,28.964296"
|
||||
id="path6-2" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.4 KiB |
131
src/Mod/TechDraw/Gui/TechDrawHandler.cpp
Normal file
131
src/Mod/TechDraw/Gui/TechDrawHandler.cpp
Normal file
@@ -0,0 +1,131 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Pierre-Louis Boyer <development@ondsel.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 *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
#include <cmath>
|
||||
|
||||
#include <QGuiApplication>
|
||||
#include <QPainter>
|
||||
#include <QKeyEvent>
|
||||
#include <QMouseEvent>
|
||||
#include <QTimer>
|
||||
|
||||
#include <Inventor/events/SoKeyboardEvent.h>
|
||||
#endif // #ifndef _PreComp_
|
||||
|
||||
#include <Base/Console.h>
|
||||
#include <Base/Exception.h>
|
||||
#include <Gui/Application.h>
|
||||
#include <Gui/CommandT.h>
|
||||
#include <Gui/MainWindow.h>
|
||||
#include <Gui/View3DInventor.h>
|
||||
#include <Gui/View3DInventorViewer.h>
|
||||
|
||||
#include "MDIViewPage.h"
|
||||
#include "QGVPage.h"
|
||||
#include "TechDrawHandler.h"
|
||||
|
||||
|
||||
using namespace TechDrawGui;
|
||||
|
||||
/**************************** TechDrawHandler *******************************************/
|
||||
|
||||
TechDrawHandler::TechDrawHandler() : Gui::ToolHandler(), viewPage(nullptr)
|
||||
{}
|
||||
|
||||
TechDrawHandler::~TechDrawHandler()
|
||||
{}
|
||||
|
||||
void TechDrawHandler::activate(QGVPage* vp)
|
||||
{
|
||||
auto* mdi = dynamic_cast<MDIViewPage*>(Gui::getMainWindow()->activeWindow());
|
||||
if (!mdi) {
|
||||
return;
|
||||
}
|
||||
mdi->enableContextualMenu(false);
|
||||
|
||||
viewPage = vp;
|
||||
|
||||
if (!Gui::ToolHandler::activate()) {
|
||||
viewPage->deactivateHandler();
|
||||
}
|
||||
}
|
||||
|
||||
void TechDrawHandler::deactivate()
|
||||
{
|
||||
Gui::ToolHandler::deactivate();
|
||||
|
||||
// The context menu event of MDIViewPage comes after the tool is deactivated.
|
||||
// So to prevent the menu from appearing when the tool is cleared by right mouse click
|
||||
// we set a small timer.
|
||||
QTimer::singleShot(100, [this]() { // 100 milliseconds delay
|
||||
auto* mdi = dynamic_cast<MDIViewPage*>(Gui::getMainWindow()->activeWindow());
|
||||
if (!mdi) {
|
||||
return;
|
||||
}
|
||||
mdi->enableContextualMenu(true);
|
||||
});
|
||||
}
|
||||
|
||||
void TechDrawHandler::keyReleaseEvent(QKeyEvent* event)
|
||||
{
|
||||
// the default behaviour is to quit - specific handler categories may
|
||||
// override this behaviour, for example to implement a continuous mode
|
||||
if (event->key() == Qt::Key_Escape) {
|
||||
quit();
|
||||
event->accept();
|
||||
}
|
||||
}
|
||||
|
||||
void TechDrawHandler::mouseReleaseEvent(QMouseEvent* event)
|
||||
{
|
||||
// the default behaviour is to quit - specific handler categories may
|
||||
// override this behaviour, for example to implement a continuous mode
|
||||
if (event->button() == Qt::RightButton) {
|
||||
quit();
|
||||
event->accept();
|
||||
}
|
||||
}
|
||||
|
||||
void TechDrawHandler::quit()
|
||||
{
|
||||
viewPage->deactivateHandler();
|
||||
}
|
||||
|
||||
QWidget* TechDrawHandler::getCursorWidget()
|
||||
{
|
||||
return viewPage;
|
||||
}
|
||||
|
||||
void TechDrawHandler::setWidgetCursor(QCursor cursor)
|
||||
{
|
||||
if (viewPage) {
|
||||
viewPage->setCursor(cursor);
|
||||
viewPage->viewport()->setCursor(cursor);
|
||||
}
|
||||
}
|
||||
|
||||
TechDraw::DrawPage* TechDrawHandler::getPage()
|
||||
{
|
||||
return viewPage->getDrawPage();
|
||||
}
|
||||
67
src/Mod/TechDraw/Gui/TechDrawHandler.h
Normal file
67
src/Mod/TechDraw/Gui/TechDrawHandler.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2024 Pierre-Louis Boyer <development@ondsel.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 TechDrawGUI_TechDrawHandler_H
|
||||
#define TechDrawGUI_TechDrawHandler_H
|
||||
|
||||
#include <Gui/ToolHandler.h>
|
||||
|
||||
#include <Mod/TechDraw/TechDrawGlobal.h>
|
||||
|
||||
namespace TechDrawGui
|
||||
{
|
||||
class QGVPage;
|
||||
|
||||
class TechDrawGuiExport TechDrawHandler : public Gui::ToolHandler
|
||||
{
|
||||
public:
|
||||
|
||||
TechDrawHandler();
|
||||
virtual ~TechDrawHandler();
|
||||
|
||||
void activate(QGVPage* vPage);
|
||||
void deactivate() override;
|
||||
|
||||
void quit() override;
|
||||
|
||||
virtual void mouseMoveEvent(QMouseEvent* event) = 0;
|
||||
virtual void mousePressEvent(QMouseEvent* event) { Q_UNUSED(event) };
|
||||
virtual void mouseReleaseEvent(QMouseEvent* event);
|
||||
|
||||
virtual void keyPressEvent(QKeyEvent* event) = 0;
|
||||
virtual void keyReleaseEvent(QKeyEvent* event);
|
||||
|
||||
TechDraw::DrawPage* getPage();
|
||||
|
||||
|
||||
protected:
|
||||
QWidget* getCursorWidget() override;
|
||||
void setWidgetCursor(QCursor cursor) override;
|
||||
|
||||
QGVPage* viewPage;
|
||||
};
|
||||
|
||||
|
||||
} // namespace TechDrawGui
|
||||
|
||||
|
||||
#endif // TechDrawGUI_TechDrawHandler_H
|
||||
@@ -196,6 +196,8 @@ void ViewProviderDimension::setPixmapForType()
|
||||
sPixmap = "TechDraw_AngleDimension";
|
||||
} else if (getViewObject()->Type.isValue("Angle3Pt")) {
|
||||
sPixmap = "TechDraw_3PtAngleDimension";
|
||||
} else if (getViewObject()->Type.isValue("Area")) {
|
||||
sPixmap = "TechDraw_ExtensionAreaAnnotation";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#endif
|
||||
|
||||
#include "Workbench.h"
|
||||
#include <App/Application.h>
|
||||
#include <Gui/MenuManager.h>
|
||||
#include <Gui/ToolBarManager.h>
|
||||
|
||||
@@ -82,6 +83,7 @@ Gui::MenuItem* Workbench::setupMenuBar() const
|
||||
// dimensions
|
||||
Gui::MenuItem* dimensions = new Gui::MenuItem;
|
||||
dimensions->setCommand("Dimensions");
|
||||
*dimensions << "TechDraw_Dimension";
|
||||
*dimensions << "TechDraw_LengthDimension";
|
||||
*dimensions << "TechDraw_HorizontalDimension";
|
||||
*dimensions << "TechDraw_VerticalDimension";
|
||||
@@ -89,6 +91,7 @@ Gui::MenuItem* Workbench::setupMenuBar() const
|
||||
*dimensions << "TechDraw_DiameterDimension";
|
||||
*dimensions << "TechDraw_AngleDimension";
|
||||
*dimensions << "TechDraw_3PtAngleDimension";
|
||||
*dimensions << "TechDraw_AreaDimension";
|
||||
*dimensions << "TechDraw_HorizontalExtentDimension";
|
||||
*dimensions << "TechDraw_VerticalExtentDimension";
|
||||
// TechDraw_LinkDimension is DEPRECATED. Use TechDraw_DimensionRepair instead.
|
||||
@@ -305,14 +308,30 @@ Gui::ToolBarItem* Workbench::setupToolBars() const
|
||||
|
||||
Gui::ToolBarItem* dims = new Gui::ToolBarItem(root);
|
||||
dims->setCommand("TechDraw Dimensions");
|
||||
*dims << "TechDraw_LengthDimension";
|
||||
*dims << "TechDraw_HorizontalDimension";
|
||||
*dims << "TechDraw_VerticalDimension";
|
||||
*dims << "TechDraw_RadiusDimension";
|
||||
*dims << "TechDraw_DiameterDimension";
|
||||
*dims << "TechDraw_AngleDimension";
|
||||
*dims << "TechDraw_3PtAngleDimension";
|
||||
*dims << "TechDraw_ExtentGroup";
|
||||
|
||||
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
|
||||
"User parameter:BaseApp/Preferences/Mod/TechDraw/dimensioning");
|
||||
bool separatedTools = hGrp->GetBool("SeparatedDimensioningTools", true);
|
||||
if (hGrp->GetBool("SingleDimensioningTool", true)) {
|
||||
if (separatedTools) {
|
||||
*dims << "TechDraw_Dimension";
|
||||
}
|
||||
else {
|
||||
*dims << "TechDraw_CompDimensionTools";
|
||||
}
|
||||
}
|
||||
if (separatedTools) {
|
||||
*dims << "TechDraw_LengthDimension";
|
||||
*dims << "TechDraw_HorizontalDimension";
|
||||
*dims << "TechDraw_VerticalDimension";
|
||||
*dims << "TechDraw_RadiusDimension";
|
||||
*dims << "TechDraw_DiameterDimension";
|
||||
*dims << "TechDraw_AngleDimension";
|
||||
*dims << "TechDraw_3PtAngleDimension";
|
||||
*dims << "TechDraw_AreaDimension";
|
||||
*dims << "TechDraw_ExtentGroup";
|
||||
}
|
||||
|
||||
// TechDraw_LinkDimension is DEPRECATED. Use TechDraw_DimensionRepair instead.
|
||||
// *dims << "TechDraw_LinkDimension";
|
||||
*dims << "TechDraw_Balloon";
|
||||
@@ -329,8 +348,10 @@ Gui::ToolBarItem* Workbench::setupToolBars() const
|
||||
*extattribs << "TechDraw_ExtensionPositionSectionView";
|
||||
*extattribs << "TechDraw_ExtensionPosChainDimensionGroup";
|
||||
*extattribs << "TechDraw_ExtensionCascadeDimensionGroup";
|
||||
*extattribs << "TechDraw_ExtensionAreaAnnotation";
|
||||
*extattribs << "TechDraw_ExtensionArcLengthAnnotation";
|
||||
if (separatedTools) {
|
||||
*extattribs << "TechDraw_ExtensionAreaAnnotation";
|
||||
*extattribs << "TechDraw_ExtensionArcLengthAnnotation";
|
||||
}
|
||||
*extattribs << "TechDraw_ExtensionCustomizeFormat";
|
||||
|
||||
Gui::ToolBarItem* extcenter = new Gui::ToolBarItem(root);
|
||||
@@ -344,10 +365,12 @@ Gui::ToolBarItem* Workbench::setupToolBars() const
|
||||
|
||||
Gui::ToolBarItem* extdimensions = new Gui::ToolBarItem(root);
|
||||
extdimensions->setCommand("TechDraw Extend Dimensions");
|
||||
*extdimensions << "TechDraw_ExtensionCreateChainDimensionGroup";
|
||||
*extdimensions << "TechDraw_ExtensionCreateCoordDimensionGroup";
|
||||
*extdimensions << "TechDraw_ExtensionChamferDimensionGroup";
|
||||
*extdimensions << "TechDraw_ExtensionCreateLengthArc";
|
||||
if (separatedTools) {
|
||||
*extdimensions << "TechDraw_ExtensionCreateChainDimensionGroup";
|
||||
*extdimensions << "TechDraw_ExtensionCreateCoordDimensionGroup";
|
||||
*extdimensions << "TechDraw_ExtensionChamferDimensionGroup";
|
||||
*extdimensions << "TechDraw_ExtensionCreateLengthArc";
|
||||
}
|
||||
*extdimensions << "TechDraw_ExtensionInsertPrefixGroup";
|
||||
*extdimensions << "TechDraw_ExtensionIncreaseDecreaseGroup";
|
||||
|
||||
@@ -406,6 +429,7 @@ Gui::ToolBarItem* Workbench::setupCommandBars() const
|
||||
|
||||
Gui::ToolBarItem* dims = new Gui::ToolBarItem(root);
|
||||
dims->setCommand("TechDraw Dimensions");
|
||||
*dims << "TechDraw_Dimension";
|
||||
*dims << "TechDraw_LengthDimension";
|
||||
*dims << "TechDraw_HorizontalDimension";
|
||||
*dims << "TechDraw_VerticalDimension";
|
||||
|
||||
Reference in New Issue
Block a user