Merge branch 'master' into Draft_addgroup
This commit is contained in:
@@ -139,7 +139,7 @@ class Arc_3Points(gui_base.GuiCommandSimplest):
|
||||
Parameters
|
||||
----------
|
||||
point: Base::Vector
|
||||
The dynamic point pased by the callback
|
||||
The dynamic point passed by the callback
|
||||
as we move the pointer in the 3D view.
|
||||
|
||||
info: str
|
||||
|
||||
@@ -33,99 +33,6 @@ import draftutils.todo as todo
|
||||
from draftutils.messages import _msg, _log
|
||||
|
||||
|
||||
class GuiCommandSimplest:
|
||||
"""Simplest base class for GuiCommands.
|
||||
|
||||
This class only sets up the command name and the document object
|
||||
to use for the command.
|
||||
When it is executed, it logs the command name to the log file,
|
||||
and prints the command name to the console.
|
||||
|
||||
It implements the `IsActive` method, which must return `True`
|
||||
when the command should be available.
|
||||
It should return `True` when there is an active document,
|
||||
otherwise the command (button or menu) should be disabled.
|
||||
|
||||
This class is meant to be inherited by other GuiCommand classes
|
||||
to quickly log the command name, and set the correct document object.
|
||||
|
||||
Parameter
|
||||
---------
|
||||
name: str, optional
|
||||
It defaults to `'None'`.
|
||||
The name of the action that is being run,
|
||||
for example, `'Heal'`, `'Flip dimensions'`,
|
||||
`'Line'`, `'Circle'`, etc.
|
||||
|
||||
doc: App::Document, optional
|
||||
It defaults to the value of `App.activeDocument()`.
|
||||
The document object itself, which indicates where the actions
|
||||
of the command will be executed.
|
||||
|
||||
Attributes
|
||||
----------
|
||||
command_name: str
|
||||
This is the command name, which is assigned by `name`.
|
||||
|
||||
doc: App::Document
|
||||
This is the document object itself, which is assigned by `doc`.
|
||||
|
||||
This attribute should be used by functions to make sure
|
||||
that the operations are performed in the correct document
|
||||
and not in other documents.
|
||||
To set the active document we can use
|
||||
|
||||
>>> App.setActiveDocument(self.doc.Name)
|
||||
"""
|
||||
|
||||
def __init__(self, name="None", doc=App.activeDocument()):
|
||||
self.command_name = name
|
||||
self.doc = doc
|
||||
|
||||
def IsActive(self):
|
||||
"""Return True when this command should be available.
|
||||
|
||||
It is `True` when there is a document.
|
||||
"""
|
||||
if App.activeDocument():
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def Activated(self):
|
||||
"""Execute when the command is called.
|
||||
|
||||
Log the command name to the log file and console.
|
||||
Also update the `doc` attribute.
|
||||
"""
|
||||
self.doc = App.activeDocument()
|
||||
_log("Document: {}".format(self.doc.Label))
|
||||
_log("GuiCommand: {}".format(self.command_name))
|
||||
_msg("{}".format(16*"-"))
|
||||
_msg("GuiCommand: {}".format(self.command_name))
|
||||
|
||||
|
||||
class GuiCommandNeedsSelection(GuiCommandSimplest):
|
||||
"""Base class for GuiCommands that need a selection to be available.
|
||||
|
||||
It re-implements the `IsActive` method to return `True`
|
||||
when there is both an active document and an active selection.
|
||||
|
||||
It inherits `GuiCommandSimplest` to set up the document
|
||||
and other behavior. See this class for more information.
|
||||
"""
|
||||
|
||||
def IsActive(self):
|
||||
"""Return True when this command should be available.
|
||||
|
||||
It is `True` when there is a selection.
|
||||
"""
|
||||
if App.activeDocument() and Gui.Selection.getSelection():
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
class GuiCommandSimplest:
|
||||
"""Simplest base class for GuiCommands.
|
||||
|
||||
|
||||
302
src/Mod/Draft/draftguitools/gui_base_original.py
Normal file
302
src/Mod/Draft/draftguitools/gui_base_original.py
Normal file
@@ -0,0 +1,302 @@
|
||||
# ***************************************************************************
|
||||
# * (c) 2009 Yorik van Havre <yorik@uncreated.net> *
|
||||
# * (c) 2010 Ken Cline <cline@frii.com> *
|
||||
# * (c) 2020 Eliud Cabrera Castillo <e.cabrera-castillo@tum.de> *
|
||||
# * *
|
||||
# * This file is part of the FreeCAD CAx development system. *
|
||||
# * *
|
||||
# * This program is free software; you can redistribute it and/or modify *
|
||||
# * it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
# * as published by the Free Software Foundation; either version 2 of *
|
||||
# * the License, or (at your option) any later version. *
|
||||
# * for detail see the LICENCE text file. *
|
||||
# * *
|
||||
# * FreeCAD 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 FreeCAD; if not, write to the Free Software *
|
||||
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
"""Provides the Base object for most old Draft Gui Commands.
|
||||
|
||||
This class is used by Gui Commands to set up some properties
|
||||
of the DraftToolBar, the Snapper, and the working plane.
|
||||
"""
|
||||
## @package gui_base_original
|
||||
# \ingroup DRAFT
|
||||
# \brief Provides the Base object for most old Draft Gui Commands.
|
||||
|
||||
import FreeCAD as App
|
||||
import FreeCADGui as Gui
|
||||
import DraftVecUtils
|
||||
import draftutils.utils as utils
|
||||
import draftutils.gui_utils as gui_utils
|
||||
import draftutils.todo as todo
|
||||
import draftguitools.gui_trackers as trackers
|
||||
import draftguitools.gui_tool_utils as gui_tool_utils
|
||||
from draftutils.messages import _msg, _log
|
||||
|
||||
|
||||
class DraftTool:
|
||||
"""The base class of all Draft Tools.
|
||||
|
||||
This is the original class that was defined in `DraftTools.py`
|
||||
before any re-organization of the code.
|
||||
It must be preserved exactly like this to keep the original tools
|
||||
running without problems.
|
||||
|
||||
This class is subclassed by `Creator` and `Modifier`
|
||||
to set up a few additional properties of these two types.
|
||||
|
||||
This class connects with the `draftToolBar` and `Snapper` classes
|
||||
that are installed in the `FreeCADGui` namespace in order to set up some
|
||||
properties of the running tools such as the task panel, the snapping
|
||||
functions, and the grid trackers.
|
||||
|
||||
It also connects with the `DraftWorkingPlane` class
|
||||
that is installed in the `FreeCAD` namespace in order to set up
|
||||
the working plane if it doesn't exist.
|
||||
|
||||
This class is intended to be replaced by newer classes inside the
|
||||
`gui_base` module, in particular, `GuiCommandBase`.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.commitList = []
|
||||
|
||||
def IsActive(self):
|
||||
"""Return True when this command should be available.
|
||||
|
||||
It is `True` when there is a document.
|
||||
"""
|
||||
if Gui.ActiveDocument:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def Activated(self, name="None", noplanesetup=False, is_subtool=False):
|
||||
"""Execute when the command is called.
|
||||
|
||||
If an active Gui Command exists, it will call the `finish` method
|
||||
of it to terminate it.
|
||||
|
||||
If no active Gui Command exists, it will proceed with configuration
|
||||
of the tool. The child class that subclasses this class
|
||||
then should continue with its own Activated method.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
name: str, optional
|
||||
It defaults to `'None'`.
|
||||
It is the `featureName` of the object, to know what is being run.
|
||||
|
||||
noplanesetup: bool, optional
|
||||
It defaults to `False`.
|
||||
If it is `False` it will set up the working plane
|
||||
by running `App.DraftWorkingPlane.setup()`.
|
||||
|
||||
is_subtool: bool, optional
|
||||
It defaults to `False`.
|
||||
This is set to `True` when we want to modify an object
|
||||
by using the mechanism of a `subtool`, introduced
|
||||
through the `Draft_SubelementHighlight` command.
|
||||
That is, first we run `Draft_SubelementHighlight`
|
||||
then we can use `Draft_Move` while setting `is_subtool` to `True`.
|
||||
"""
|
||||
if App.activeDraftCommand and not is_subtool:
|
||||
App.activeDraftCommand.finish()
|
||||
|
||||
# The Part module is first initialized when using any Gui Command
|
||||
# for the first time.
|
||||
global Part, DraftGeomUtils
|
||||
import Part
|
||||
import DraftGeomUtils
|
||||
|
||||
self.ui = None
|
||||
self.call = None
|
||||
self.support = None
|
||||
self.point = None
|
||||
self.commitList = []
|
||||
self.doc = App.ActiveDocument
|
||||
if not self.doc:
|
||||
self.finish()
|
||||
return
|
||||
|
||||
App.activeDraftCommand = self
|
||||
self.view = gui_utils.get_3d_view()
|
||||
self.ui = Gui.draftToolBar
|
||||
self.featureName = name
|
||||
self.ui.sourceCmd = self
|
||||
self.ui.setTitle(name)
|
||||
self.ui.show()
|
||||
if not noplanesetup:
|
||||
App.DraftWorkingPlane.setup()
|
||||
self.node = []
|
||||
self.pos = []
|
||||
self.constrain = None
|
||||
self.obj = None
|
||||
self.extendedCopy = False
|
||||
self.ui.setTitle(name)
|
||||
self.planetrack = None
|
||||
if utils.get_param("showPlaneTracker", False):
|
||||
self.planetrack = trackers.PlaneTracker()
|
||||
if hasattr(Gui, "Snapper"):
|
||||
Gui.Snapper.setTrackers()
|
||||
|
||||
_log("GuiCommand: {}".format(self.featureName))
|
||||
_msg("{}".format(16*"-"))
|
||||
_msg("GuiCommand: {}".format(self.featureName))
|
||||
|
||||
def finish(self, close=False):
|
||||
"""Finish the current command.
|
||||
|
||||
These are general cleaning tasks that are performed
|
||||
when terminating all commands.
|
||||
|
||||
These include setting the node list to empty,
|
||||
setting to `None` the active command,
|
||||
turning off the graphical interface (task panel),
|
||||
finishing the plane tracker, restoring the working plane,
|
||||
turning off the snapper.
|
||||
|
||||
If a callback is installed in the 3D view, the callback is removed,
|
||||
and set to `None`.
|
||||
|
||||
If the commit list is non-empty it will commit the instructions on
|
||||
the list with `draftutils.todo.ToDo.delayCommit`,
|
||||
and the list will be set to empty.
|
||||
"""
|
||||
self.node = []
|
||||
App.activeDraftCommand = None
|
||||
if self.ui:
|
||||
self.ui.offUi()
|
||||
self.ui.sourceCmd = None
|
||||
if self.planetrack:
|
||||
self.planetrack.finalize()
|
||||
App.DraftWorkingPlane.restore()
|
||||
if hasattr(Gui, "Snapper"):
|
||||
Gui.Snapper.off()
|
||||
if self.call:
|
||||
try:
|
||||
self.view.removeEventCallback("SoEvent", self.call)
|
||||
except RuntimeError:
|
||||
# the view has been deleted already
|
||||
pass
|
||||
self.call = None
|
||||
if self.commitList:
|
||||
todo.ToDo.delayCommit(self.commitList)
|
||||
self.commitList = []
|
||||
|
||||
def commit(self, name, func):
|
||||
"""Store actions in the commit list to be run later.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
name: str
|
||||
An arbitraty string that indicates the name of the operation
|
||||
to run.
|
||||
|
||||
func: list of str
|
||||
Each element of the list is a string that will be run by
|
||||
`Gui.doCommand`.
|
||||
|
||||
See the complete information in the `draftutils.todo.ToDo` class.
|
||||
"""
|
||||
self.commitList.append((name, func))
|
||||
|
||||
def getStrings(self, addrot=None):
|
||||
"""Return useful strings that will be used to build commands.
|
||||
|
||||
Returns
|
||||
-------
|
||||
str, str, str, str
|
||||
A tuple of four strings that represent useful information.
|
||||
|
||||
* the current working plane rotation quaternion as a string
|
||||
* the support object if available as a string
|
||||
* the list of nodes inside the `node` attribute as a string
|
||||
* the string `'True'` or `'False'` depending on the fill mode
|
||||
of the current tool
|
||||
"""
|
||||
# Current plane rotation as a string
|
||||
p = App.DraftWorkingPlane.getRotation()
|
||||
qr = p.Rotation.Q
|
||||
qr = "({0}, {1}, {2}, {3})".format(qr[0], qr[1], qr[2], qr[3])
|
||||
|
||||
# Support object
|
||||
_params = "User parameter:BaseApp/Preferences/Mod/Draft"
|
||||
_params_group = App.ParamGet(_params)
|
||||
if self.support and _params_group.GetBool("useSupport", False):
|
||||
sup = 'FreeCAD.ActiveDocument.getObject'
|
||||
sup += '("{}")'.format(self.support.Name)
|
||||
else:
|
||||
sup = 'None'
|
||||
|
||||
# Contents of self.node
|
||||
points = '['
|
||||
for n in self.node:
|
||||
if len(points) > 1:
|
||||
points += ', '
|
||||
points += DraftVecUtils.toString(n)
|
||||
points += ']'
|
||||
|
||||
# Fill mode
|
||||
if self.ui:
|
||||
fil = str(bool(self.ui.fillmode))
|
||||
else:
|
||||
fil = "True"
|
||||
|
||||
return qr, sup, points, fil
|
||||
|
||||
|
||||
class Creator(DraftTool):
|
||||
"""A generic Creator tool, used by creation tools such as line or arc.
|
||||
|
||||
It runs the Activated method from the parent class.
|
||||
If `noplanesetup` is `False`, it sets the appropriate `support` attribute
|
||||
and sets the working plane with `gui_tool_utils.get_support`.
|
||||
|
||||
It inherits `DraftTool`, which sets up the majority of the behavior
|
||||
of this class.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def Activated(self, name="None", noplanesetup=False):
|
||||
"""Execute when the command is called.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
name: str, optional
|
||||
It defaults to `'None'`.
|
||||
It is the `featureName` of the object, to know what is being run.
|
||||
|
||||
noplanesetup: bool, optional
|
||||
It defaults to `False`.
|
||||
If it is `False` it will set up the working plane
|
||||
by running `App.DraftWorkingPlane.setup()`.
|
||||
"""
|
||||
super().Activated(name, noplanesetup)
|
||||
if not noplanesetup:
|
||||
self.support = gui_tool_utils.get_support()
|
||||
|
||||
|
||||
class Modifier(DraftTool):
|
||||
"""A generic Modifier tool, used by modification tools such as move.
|
||||
|
||||
After initializing the parent class, it sets the `copymode` attribute
|
||||
to `False`.
|
||||
|
||||
It inherits `DraftTool`, which sets up the majority of the behavior
|
||||
of this class.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.copymode = False
|
||||
@@ -53,7 +53,7 @@ class AddToGroup(gui_base.GuiCommandNeedsSelection):
|
||||
|
||||
It adds selected objects to a group, or removes them from any group.
|
||||
|
||||
It inherits `GuiCommandNeedsSelection` to only be availbale
|
||||
It inherits `GuiCommandNeedsSelection` to only be available
|
||||
when there is a document and a selection.
|
||||
See this class for more information.
|
||||
"""
|
||||
@@ -169,7 +169,7 @@ class SelectGroup(gui_base.GuiCommandNeedsSelection):
|
||||
in this case it works in an intuitive manner, selecting
|
||||
only the objects under the group.
|
||||
|
||||
It inherits `GuiCommandNeedsSelection` to only be availbale
|
||||
It inherits `GuiCommandNeedsSelection` to only be available
|
||||
when there is a document and a selection.
|
||||
See this class for more information.
|
||||
"""
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -28,13 +28,74 @@
|
||||
# \brief Provide the Draft_Snap commands used by the snapping mechanism
|
||||
# in Draft.
|
||||
|
||||
from PySide import QtGui
|
||||
from PySide.QtCore import QT_TRANSLATE_NOOP
|
||||
|
||||
import FreeCADGui as Gui
|
||||
|
||||
import draftguitools.gui_base as gui_base
|
||||
from draftutils.translate import _tr
|
||||
|
||||
|
||||
# UTILITIES -----------------------------------------------------------------
|
||||
|
||||
|
||||
def get_snap_statusbar_widget():
|
||||
"""Return snap statusbar button."""
|
||||
mw = Gui.getMainWindow()
|
||||
if mw:
|
||||
sb = mw.statusBar()
|
||||
if sb:
|
||||
return sb.findChild(QtGui.QToolBar,"draft_snap_widget")
|
||||
return None
|
||||
|
||||
|
||||
def sync_snap_toolbar_button(button, status):
|
||||
"""Set snap toolbar button to given state."""
|
||||
snap_toolbar = Gui.Snapper.get_snap_toolbar()
|
||||
if not snap_toolbar:
|
||||
return
|
||||
for a in snap_toolbar.actions():
|
||||
if a.objectName() == button:
|
||||
if button == "Draft_Snap_Lock_Button":
|
||||
# for lock button
|
||||
snap_toolbar.actions()[0].setChecked(status)
|
||||
for a in snap_toolbar.actions()[1:]:
|
||||
a.setEnabled(status)
|
||||
else:
|
||||
# for every other button
|
||||
a.setChecked(status)
|
||||
if a.isChecked():
|
||||
a.setToolTip(a.toolTip().replace("OFF","ON"))
|
||||
else:
|
||||
a.setToolTip(a.toolTip().replace("ON","OFF"))
|
||||
|
||||
|
||||
def sync_snap_statusbar_button(button, status):
|
||||
"""Set snap statusbar button to given state."""
|
||||
ssw = get_snap_statusbar_widget()
|
||||
if not ssw:
|
||||
return
|
||||
for child in ssw.children():
|
||||
if child.objectName() == "Snap_Statusbutton":
|
||||
ssb = child
|
||||
actions = []
|
||||
for a in ssb.menu().actions() + ssw.children()[-6:]:
|
||||
actions.append(a)
|
||||
|
||||
if button == "Draft_Snap_Lock_Statusbutton":
|
||||
ssb.setChecked(status)
|
||||
for a in actions[1:]:
|
||||
a.setEnabled(status)
|
||||
else:
|
||||
for a in actions:
|
||||
if a.objectName() == button:
|
||||
a.setChecked(status)
|
||||
|
||||
|
||||
# SNAP GUI TOOLS ------------------------------------------------------------
|
||||
|
||||
|
||||
class Draft_Snap_Lock(gui_base.GuiCommandSimplest):
|
||||
"""GuiCommand for the Draft_Snap_Lock tool.
|
||||
|
||||
@@ -42,7 +103,7 @@ class Draft_Snap_Lock(gui_base.GuiCommandSimplest):
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(name=_tr("Main toggle snap"))
|
||||
super(Draft_Snap_Lock, self).__init__(name=_tr("Main toggle snap"))
|
||||
|
||||
def GetResources(self):
|
||||
"""Set icon, menu and tooltip."""
|
||||
@@ -57,11 +118,13 @@ class Draft_Snap_Lock(gui_base.GuiCommandSimplest):
|
||||
|
||||
def Activated(self):
|
||||
"""Execute when the command is called."""
|
||||
super().Activated()
|
||||
|
||||
super(Draft_Snap_Lock, self).Activated()
|
||||
|
||||
if hasattr(Gui, "Snapper"):
|
||||
if hasattr(Gui.Snapper, "masterbutton"):
|
||||
Gui.Snapper.masterbutton.toggle()
|
||||
status = Gui.Snapper.toggle_snap('Lock')
|
||||
# change interface consistently
|
||||
sync_snap_toolbar_button("Draft_Snap_Lock"+"_Button", status)
|
||||
sync_snap_statusbar_button("Draft_Snap_Lock"+"_Statusbutton", status)
|
||||
|
||||
|
||||
Gui.addCommand('Draft_Snap_Lock', Draft_Snap_Lock())
|
||||
@@ -74,7 +137,7 @@ class Draft_Snap_Midpoint(gui_base.GuiCommandSimplest):
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(name=_tr("Midpoint snap"))
|
||||
super(Draft_Snap_Midpoint, self).__init__(name=_tr("Midpoint snap"))
|
||||
|
||||
def GetResources(self):
|
||||
"""Set icon, menu and tooltip."""
|
||||
@@ -87,13 +150,13 @@ class Draft_Snap_Midpoint(gui_base.GuiCommandSimplest):
|
||||
|
||||
def Activated(self):
|
||||
"""Execute when the command is called."""
|
||||
super().Activated()
|
||||
super(Draft_Snap_Midpoint, self).Activated()
|
||||
|
||||
if hasattr(Gui, "Snapper"):
|
||||
if hasattr(Gui.Snapper, "toolbarButtons"):
|
||||
for b in Gui.Snapper.toolbarButtons:
|
||||
if b.objectName() == "SnapButtonmidpoint":
|
||||
b.toggle()
|
||||
status = Gui.Snapper.toggle_snap('Midpoint')
|
||||
# change interface consistently
|
||||
sync_snap_toolbar_button("Draft_Snap_Midpoint"+"_Button", status)
|
||||
sync_snap_statusbar_button("Draft_Snap_Midpoint_Statusbutton", status)
|
||||
|
||||
|
||||
Gui.addCommand('Draft_Snap_Midpoint', Draft_Snap_Midpoint())
|
||||
@@ -106,7 +169,7 @@ class Draft_Snap_Perpendicular(gui_base.GuiCommandSimplest):
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(name=_tr("Perpendicular snap"))
|
||||
super(Draft_Snap_Perpendicular, self).__init__(name=_tr("Perpendicular snap"))
|
||||
|
||||
def GetResources(self):
|
||||
"""Set icon, menu and tooltip."""
|
||||
@@ -121,13 +184,13 @@ class Draft_Snap_Perpendicular(gui_base.GuiCommandSimplest):
|
||||
|
||||
def Activated(self):
|
||||
"""Execute when the command is called."""
|
||||
super().Activated()
|
||||
super(Draft_Snap_Perpendicular, self).Activated()
|
||||
|
||||
if hasattr(Gui, "Snapper"):
|
||||
if hasattr(Gui.Snapper, "toolbarButtons"):
|
||||
for b in Gui.Snapper.toolbarButtons:
|
||||
if b.objectName() == "SnapButtonperpendicular":
|
||||
b.toggle()
|
||||
status = Gui.Snapper.toggle_snap('Perpendicular')
|
||||
# change interface consistently
|
||||
sync_snap_toolbar_button("Draft_Snap_Perpendicular"+"_Button", status)
|
||||
sync_snap_statusbar_button("Draft_Snap_Perpendicular_Statusbutton", status)
|
||||
|
||||
|
||||
Gui.addCommand('Draft_Snap_Perpendicular', Draft_Snap_Perpendicular())
|
||||
@@ -140,7 +203,7 @@ class Draft_Snap_Grid(gui_base.GuiCommandSimplest):
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(name=_tr("Grid snap"))
|
||||
super(Draft_Snap_Grid, self).__init__(name=_tr("Grid snap"))
|
||||
|
||||
def GetResources(self):
|
||||
"""Set icon, menu and tooltip."""
|
||||
@@ -152,13 +215,13 @@ class Draft_Snap_Grid(gui_base.GuiCommandSimplest):
|
||||
|
||||
def Activated(self):
|
||||
"""Execute when the command is called."""
|
||||
super().Activated()
|
||||
super(Draft_Snap_Grid, self).Activated()
|
||||
|
||||
if hasattr(Gui, "Snapper"):
|
||||
if hasattr(Gui.Snapper, "toolbarButtons"):
|
||||
for b in Gui.Snapper.toolbarButtons:
|
||||
if b.objectName() == "SnapButtongrid":
|
||||
b.toggle()
|
||||
status = Gui.Snapper.toggle_snap('Grid')
|
||||
# change interface consistently
|
||||
sync_snap_toolbar_button("Draft_Snap_Grid"+"_Button", status)
|
||||
sync_snap_statusbar_button("Draft_Snap_Grid_Statusbutton", status)
|
||||
|
||||
|
||||
Gui.addCommand('Draft_Snap_Grid', Draft_Snap_Grid())
|
||||
@@ -171,7 +234,7 @@ class Draft_Snap_Intersection(gui_base.GuiCommandSimplest):
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(name=_tr("Intersection snap"))
|
||||
super(Draft_Snap_Intersection, self).__init__(name=_tr("Intersection snap"))
|
||||
|
||||
def GetResources(self):
|
||||
"""Set icon, menu and tooltip."""
|
||||
@@ -186,13 +249,13 @@ class Draft_Snap_Intersection(gui_base.GuiCommandSimplest):
|
||||
|
||||
def Activated(self):
|
||||
"""Execute when the command is called."""
|
||||
super().Activated()
|
||||
super(Draft_Snap_Intersection, self).Activated()
|
||||
|
||||
if hasattr(Gui, "Snapper"):
|
||||
if hasattr(Gui.Snapper, "toolbarButtons"):
|
||||
for b in Gui.Snapper.toolbarButtons:
|
||||
if b.objectName() == "SnapButtonintersection":
|
||||
b.toggle()
|
||||
status = Gui.Snapper.toggle_snap('Intersection')
|
||||
# change interface consistently
|
||||
sync_snap_toolbar_button("Draft_Snap_Intersection"+"_Button", status)
|
||||
sync_snap_statusbar_button("Draft_Snap_Intersection_Statusbutton", status)
|
||||
|
||||
|
||||
Gui.addCommand('Draft_Snap_Intersection', Draft_Snap_Intersection())
|
||||
@@ -205,7 +268,7 @@ class Draft_Snap_Parallel(gui_base.GuiCommandSimplest):
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(name=_tr("Parallel snap"))
|
||||
super(Draft_Snap_Parallel, self).__init__(name=_tr("Parallel snap"))
|
||||
|
||||
def GetResources(self):
|
||||
"""Set icon, menu and tooltip."""
|
||||
@@ -218,13 +281,13 @@ class Draft_Snap_Parallel(gui_base.GuiCommandSimplest):
|
||||
|
||||
def Activated(self):
|
||||
"""Execute when the command is called."""
|
||||
super().Activated()
|
||||
super(Draft_Snap_Parallel, self).Activated()
|
||||
|
||||
if hasattr(Gui, "Snapper"):
|
||||
if hasattr(Gui.Snapper, "toolbarButtons"):
|
||||
for b in Gui.Snapper.toolbarButtons:
|
||||
if b.objectName() == "SnapButtonparallel":
|
||||
b.toggle()
|
||||
status = Gui.Snapper.toggle_snap('Parallel')
|
||||
# change interface consistently
|
||||
sync_snap_toolbar_button("Draft_Snap_Parallel"+"_Button", status)
|
||||
sync_snap_statusbar_button("Draft_Snap_Parallel_Statusbutton", status)
|
||||
|
||||
|
||||
Gui.addCommand('Draft_Snap_Parallel', Draft_Snap_Parallel())
|
||||
@@ -237,7 +300,7 @@ class Draft_Snap_Endpoint(gui_base.GuiCommandSimplest):
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(name=_tr("Endpoint snap"))
|
||||
super(Draft_Snap_Endpoint, self).__init__(name=_tr("Endpoint snap"))
|
||||
|
||||
def GetResources(self):
|
||||
"""Set icon, menu and tooltip."""
|
||||
@@ -250,13 +313,13 @@ class Draft_Snap_Endpoint(gui_base.GuiCommandSimplest):
|
||||
|
||||
def Activated(self):
|
||||
"""Execute when the command is called."""
|
||||
super().Activated()
|
||||
super(Draft_Snap_Endpoint, self).Activated()
|
||||
|
||||
if hasattr(Gui, "Snapper"):
|
||||
if hasattr(Gui.Snapper, "toolbarButtons"):
|
||||
for b in Gui.Snapper.toolbarButtons:
|
||||
if b.objectName() == "SnapButtonendpoint":
|
||||
b.toggle()
|
||||
status = Gui.Snapper.toggle_snap('Endpoint')
|
||||
# change interface consistently
|
||||
sync_snap_toolbar_button("Draft_Snap_Endpoint"+"_Button", status)
|
||||
sync_snap_statusbar_button("Draft_Snap_Endpoint_Statusbutton", status)
|
||||
|
||||
|
||||
Gui.addCommand('Draft_Snap_Endpoint', Draft_Snap_Endpoint())
|
||||
@@ -270,7 +333,7 @@ class Draft_Snap_Angle(gui_base.GuiCommandSimplest):
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(name=_tr("Angle snap (30 and 45 degrees)"))
|
||||
super(Draft_Snap_Angle, self).__init__(name=_tr("Angle snap (30 and 45 degrees)"))
|
||||
|
||||
def GetResources(self):
|
||||
"""Set icon, menu and tooltip."""
|
||||
@@ -284,13 +347,13 @@ class Draft_Snap_Angle(gui_base.GuiCommandSimplest):
|
||||
|
||||
def Activated(self):
|
||||
"""Execute when the command is called."""
|
||||
super().Activated()
|
||||
super(Draft_Snap_Angle, self).Activated()
|
||||
|
||||
if hasattr(Gui, "Snapper"):
|
||||
if hasattr(Gui.Snapper, "toolbarButtons"):
|
||||
for b in Gui.Snapper.toolbarButtons:
|
||||
if b.objectName() == "SnapButtonangle":
|
||||
b.toggle()
|
||||
status = Gui.Snapper.toggle_snap('Angle')
|
||||
# change interface consistently
|
||||
sync_snap_toolbar_button("Draft_Snap_Angle"+"_Button", status)
|
||||
sync_snap_statusbar_button("Draft_Snap_Angle_Statusbutton", status)
|
||||
|
||||
|
||||
Gui.addCommand('Draft_Snap_Angle', Draft_Snap_Angle())
|
||||
@@ -303,7 +366,7 @@ class Draft_Snap_Center(gui_base.GuiCommandSimplest):
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(name=_tr("Arc center snap"))
|
||||
super(Draft_Snap_Center, self).__init__(name=_tr("Arc center snap"))
|
||||
|
||||
def GetResources(self):
|
||||
"""Set icon, menu and tooltip."""
|
||||
@@ -315,13 +378,13 @@ class Draft_Snap_Center(gui_base.GuiCommandSimplest):
|
||||
|
||||
def Activated(self):
|
||||
"""Execute when the command is called."""
|
||||
super().Activated()
|
||||
super(Draft_Snap_Center, self).Activated()
|
||||
|
||||
if hasattr(Gui, "Snapper"):
|
||||
if hasattr(Gui.Snapper, "toolbarButtons"):
|
||||
for b in Gui.Snapper.toolbarButtons:
|
||||
if b.objectName() == "SnapButtoncenter":
|
||||
b.toggle()
|
||||
status = Gui.Snapper.toggle_snap('Center')
|
||||
# change interface consistently
|
||||
sync_snap_toolbar_button("Draft_Snap_Center"+"_Button", status)
|
||||
sync_snap_statusbar_button("Draft_Snap_Center_Statusbutton", status)
|
||||
|
||||
|
||||
Gui.addCommand('Draft_Snap_Center', Draft_Snap_Center())
|
||||
@@ -334,7 +397,7 @@ class Draft_Snap_Extension(gui_base.GuiCommandSimplest):
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(name=_tr("Edge extension snap"))
|
||||
super(Draft_Snap_Extension, self).__init__(name=_tr("Edge extension snap"))
|
||||
|
||||
def GetResources(self):
|
||||
"""Set icon, menu and tooltip."""
|
||||
@@ -347,13 +410,13 @@ class Draft_Snap_Extension(gui_base.GuiCommandSimplest):
|
||||
|
||||
def Activated(self):
|
||||
"""Execute when the command is called."""
|
||||
super().Activated()
|
||||
super(Draft_Snap_Extension, self).Activated()
|
||||
|
||||
if hasattr(Gui, "Snapper"):
|
||||
if hasattr(Gui.Snapper, "toolbarButtons"):
|
||||
for b in Gui.Snapper.toolbarButtons:
|
||||
if b.objectName() == "SnapButtonextension":
|
||||
b.toggle()
|
||||
status = Gui.Snapper.toggle_snap('Extension')
|
||||
# change interface consistently
|
||||
sync_snap_toolbar_button("Draft_Snap_Extension"+"_Button", status)
|
||||
sync_snap_statusbar_button("Draft_Snap_Extension_Statusbutton", status)
|
||||
|
||||
|
||||
Gui.addCommand('Draft_Snap_Extension', Draft_Snap_Extension())
|
||||
@@ -366,7 +429,7 @@ class Draft_Snap_Near(gui_base.GuiCommandSimplest):
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(name=_tr("Near snap"))
|
||||
super(Draft_Snap_Near, self).__init__(name=_tr("Near snap"))
|
||||
|
||||
def GetResources(self):
|
||||
"""Set icon, menu and tooltip."""
|
||||
@@ -378,13 +441,13 @@ class Draft_Snap_Near(gui_base.GuiCommandSimplest):
|
||||
|
||||
def Activated(self):
|
||||
"""Execute when the command is called."""
|
||||
super().Activated()
|
||||
super(Draft_Snap_Near, self).Activated()
|
||||
|
||||
if hasattr(Gui, "Snapper"):
|
||||
if hasattr(Gui.Snapper, "toolbarButtons"):
|
||||
for b in Gui.Snapper.toolbarButtons:
|
||||
if b.objectName() == "SnapButtonpassive":
|
||||
b.toggle()
|
||||
status = Gui.Snapper.toggle_snap('Near')
|
||||
# change interface consistently
|
||||
sync_snap_toolbar_button("Draft_Snap_Near"+"_Button", status)
|
||||
sync_snap_statusbar_button("Draft_Snap_Near_Statusbutton", status)
|
||||
|
||||
|
||||
Gui.addCommand('Draft_Snap_Near', Draft_Snap_Near())
|
||||
@@ -398,7 +461,7 @@ class Draft_Snap_Ortho(gui_base.GuiCommandSimplest):
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(name=_tr("Orthogonal snap"))
|
||||
super(Draft_Snap_Ortho, self).__init__(name=_tr("Orthogonal snap"))
|
||||
|
||||
def GetResources(self):
|
||||
"""Set icon, menu and tooltip."""
|
||||
@@ -412,13 +475,13 @@ class Draft_Snap_Ortho(gui_base.GuiCommandSimplest):
|
||||
|
||||
def Activated(self):
|
||||
"""Execute when the command is called."""
|
||||
super().Activated()
|
||||
super(Draft_Snap_Ortho, self).Activated()
|
||||
|
||||
if hasattr(Gui, "Snapper"):
|
||||
if hasattr(Gui.Snapper, "toolbarButtons"):
|
||||
for b in Gui.Snapper.toolbarButtons:
|
||||
if b.objectName() == "SnapButtonortho":
|
||||
b.toggle()
|
||||
status = Gui.Snapper.toggle_snap('Ortho')
|
||||
# change interface consistently
|
||||
sync_snap_toolbar_button("Draft_Snap_Ortho"+"_Button", status)
|
||||
sync_snap_statusbar_button("Draft_Snap_Ortho"+"_Statusbutton", status)
|
||||
|
||||
|
||||
Gui.addCommand('Draft_Snap_Ortho', Draft_Snap_Ortho())
|
||||
@@ -431,7 +494,7 @@ class Draft_Snap_Special(gui_base.GuiCommandSimplest):
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(name=_tr("Special point snap"))
|
||||
super(Draft_Snap_Special, self).__init__(name=_tr("Special point snap"))
|
||||
|
||||
def GetResources(self):
|
||||
"""Set icon, menu and tooltip."""
|
||||
@@ -444,13 +507,13 @@ class Draft_Snap_Special(gui_base.GuiCommandSimplest):
|
||||
|
||||
def Activated(self):
|
||||
"""Execute when the command is called."""
|
||||
super().Activated()
|
||||
super(Draft_Snap_Special, self).Activated()
|
||||
|
||||
if hasattr(Gui, "Snapper"):
|
||||
if hasattr(Gui.Snapper, "toolbarButtons"):
|
||||
for b in Gui.Snapper.toolbarButtons:
|
||||
if b.objectName() == "SnapButtonspecial":
|
||||
b.toggle()
|
||||
status = Gui.Snapper.toggle_snap('Special')
|
||||
# change interface consistently
|
||||
sync_snap_toolbar_button("Draft_Snap_Special"+"_Button", status)
|
||||
sync_snap_statusbar_button("Draft_Snap_Special_Statusbutton", status)
|
||||
|
||||
|
||||
Gui.addCommand('Draft_Snap_Special', Draft_Snap_Special())
|
||||
@@ -464,7 +527,7 @@ class Draft_Snap_Dimensions(gui_base.GuiCommandSimplest):
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(name=_tr("Dimension display"))
|
||||
super(Draft_Snap_Dimensions, self).__init__(name=_tr("Dimension display"))
|
||||
|
||||
def GetResources(self):
|
||||
"""Set icon, menu and tooltip."""
|
||||
@@ -478,13 +541,13 @@ class Draft_Snap_Dimensions(gui_base.GuiCommandSimplest):
|
||||
|
||||
def Activated(self):
|
||||
"""Execute when the command is called."""
|
||||
super().Activated()
|
||||
super(Draft_Snap_Dimensions, self).Activated()
|
||||
|
||||
if hasattr(Gui, "Snapper"):
|
||||
if hasattr(Gui.Snapper, "toolbarButtons"):
|
||||
for b in Gui.Snapper.toolbarButtons:
|
||||
if b.objectName() == "SnapButtonDimensions":
|
||||
b.toggle()
|
||||
status = Gui.Snapper.toggle_snap('Dimensions')
|
||||
# change interface consistently
|
||||
sync_snap_toolbar_button("Draft_Snap_Dimensions"+"_Button", status)
|
||||
sync_snap_statusbar_button("Draft_Snap_Dimensions"+"_Statusbutton", status)
|
||||
|
||||
|
||||
Gui.addCommand('Draft_Snap_Dimensions', Draft_Snap_Dimensions())
|
||||
@@ -500,7 +563,7 @@ class Draft_Snap_WorkingPlane(gui_base.GuiCommandSimplest):
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(name=_tr("Working plane snap"))
|
||||
super(Draft_Snap_WorkingPlane, self).__init__(name=_tr("Working plane snap"))
|
||||
|
||||
def GetResources(self):
|
||||
"""Set icon, menu and tooltip."""
|
||||
@@ -520,13 +583,13 @@ class Draft_Snap_WorkingPlane(gui_base.GuiCommandSimplest):
|
||||
|
||||
def Activated(self):
|
||||
"""Execute when the command is called."""
|
||||
super().Activated()
|
||||
super(Draft_Snap_WorkingPlane, self).Activated()
|
||||
|
||||
if hasattr(Gui, "Snapper"):
|
||||
if hasattr(Gui.Snapper, "toolbarButtons"):
|
||||
for b in Gui.Snapper.toolbarButtons:
|
||||
if b.objectName() == "SnapButtonWorkingPlane":
|
||||
b.toggle()
|
||||
status = Gui.Snapper.toggle_snap('WorkingPlane')
|
||||
# change interface consistently
|
||||
sync_snap_toolbar_button("Draft_Snap_WorkingPlane"+"_Button", status)
|
||||
sync_snap_statusbar_button("Draft_Snap_WorkingPlane_Statusbutton", status)
|
||||
|
||||
|
||||
Gui.addCommand('Draft_Snap_WorkingPlane', Draft_Snap_WorkingPlane())
|
||||
@@ -539,7 +602,7 @@ class ShowSnapBar(gui_base.GuiCommandSimplest):
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(name=_tr("Show snap toolbar"))
|
||||
super(ShowSnapBar, self).__init__(name=_tr("Show snap toolbar"))
|
||||
|
||||
def GetResources(self):
|
||||
"""Set icon, menu and tooltip."""
|
||||
@@ -553,7 +616,7 @@ class ShowSnapBar(gui_base.GuiCommandSimplest):
|
||||
|
||||
def Activated(self):
|
||||
"""Execute when the command is called."""
|
||||
super().Activated()
|
||||
super(ShowSnapBar, self).Activated()
|
||||
|
||||
if hasattr(Gui, "Snapper"):
|
||||
Gui.Snapper.show()
|
||||
|
||||
@@ -160,7 +160,7 @@ class ToggleDisplayMode(gui_base.GuiCommandNeedsSelection):
|
||||
Switches the display mode of selected objects from flatlines
|
||||
to wireframe and back.
|
||||
|
||||
It inherits `GuiCommandNeedsSelection` to only be availbale
|
||||
It inherits `GuiCommandNeedsSelection` to only be available
|
||||
when there is a document and a selection.
|
||||
See this class for more information.
|
||||
"""
|
||||
|
||||
389
src/Mod/Draft/draftguitools/gui_tool_utils.py
Normal file
389
src/Mod/Draft/draftguitools/gui_tool_utils.py
Normal file
@@ -0,0 +1,389 @@
|
||||
# ***************************************************************************
|
||||
# * (c) 2009 Yorik van Havre <yorik@uncreated.net> *
|
||||
# * (c) 2010 Ken Cline <cline@frii.com> *
|
||||
# * (c) 2020 Eliud Cabrera Castillo <e.cabrera-castillo@tum.de> *
|
||||
# * *
|
||||
# * This file is part of the FreeCAD CAx development system. *
|
||||
# * *
|
||||
# * This program is free software; you can redistribute it and/or modify *
|
||||
# * it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
# * as published by the Free Software Foundation; either version 2 of *
|
||||
# * the License, or (at your option) any later version. *
|
||||
# * for detail see the LICENCE text file. *
|
||||
# * *
|
||||
# * FreeCAD 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 FreeCAD; if not, write to the Free Software *
|
||||
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
"""Provides the utility functions for Draft Gui Commands.
|
||||
|
||||
These functions are used by different command classes in the `DraftTools`
|
||||
module. We assume that the graphical interface was already loaded
|
||||
as they operate on selections and graphical properties.
|
||||
"""
|
||||
## @package gui_tool_utils
|
||||
# \ingroup DRAFT
|
||||
# \brief Provides the utility functions for Draft Gui Commands.
|
||||
|
||||
import FreeCAD as App
|
||||
import FreeCADGui as Gui
|
||||
import draftutils.gui_utils as gui_utils
|
||||
import draftutils.utils as utils
|
||||
from draftutils.messages import _wrn
|
||||
|
||||
# Set modifier keys from the parameter database
|
||||
MODS = ["shift", "ctrl", "alt"]
|
||||
MODCONSTRAIN = MODS[utils.get_param("modconstrain", 0)]
|
||||
MODSNAP = MODS[utils.get_param("modsnap", 1)]
|
||||
MODALT = MODS[utils.get_param("modalt", 2)]
|
||||
|
||||
|
||||
def format_unit(exp, unit="mm"):
|
||||
"""Return a formatting string to set a number to the correct unit."""
|
||||
return App.Units.Quantity(exp, App.Units.Length).UserString
|
||||
|
||||
|
||||
formatUnit = format_unit
|
||||
|
||||
|
||||
def select_object(arg):
|
||||
"""Handle the selection of objects depending on buttons pressed.
|
||||
|
||||
This is a scene event handler, to be called from the Draft tools
|
||||
when they need to select an object.
|
||||
::
|
||||
self.call = self.view.addEventCallback("SoEvent", select_object)
|
||||
|
||||
Parameters
|
||||
----------
|
||||
arg: Coin event
|
||||
The Coin event received from the 3D view.
|
||||
|
||||
If it is of type Keyboard and the `ESCAPE` key, it runs the `finish`
|
||||
method of the active command.
|
||||
|
||||
If it is of type Mouse button and `BUTTON1` press,
|
||||
it captures the position of the cursor (x, y)
|
||||
and the object below that cursor to add it to the active selection;
|
||||
then it runs the `proceed` method of the active command
|
||||
to continue with the command's logic.
|
||||
"""
|
||||
if arg["Type"] == "SoKeyboardEvent":
|
||||
if arg["Key"] == "ESCAPE":
|
||||
App.activeDraftCommand.finish()
|
||||
# TODO: this part raises a coin3D warning about scene traversal.
|
||||
# It needs to be fixed.
|
||||
elif arg["Type"] == "SoMouseButtonEvent":
|
||||
if arg["State"] == "DOWN" and arg["Button"] == "BUTTON1":
|
||||
cursor = arg["Position"]
|
||||
snapped = gui_utils.get_3d_view().getObjectInfo((cursor[0],
|
||||
cursor[1]))
|
||||
if snapped:
|
||||
obj = App.ActiveDocument.getObject(snapped['Object'])
|
||||
Gui.Selection.addSelection(obj)
|
||||
App.activeDraftCommand.component = snapped['Component']
|
||||
App.activeDraftCommand.proceed()
|
||||
|
||||
|
||||
selectObject = select_object
|
||||
|
||||
|
||||
def has_mod(args, mod):
|
||||
"""Check if args has a specific modifier.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
args: Coin event
|
||||
The Coin event received from the 3D view.
|
||||
|
||||
mod: str
|
||||
A string indicating the modifier, either `'shift'`, `'ctrl'`,
|
||||
or `'alt'`.
|
||||
|
||||
Returns
|
||||
-------
|
||||
bool
|
||||
It returns `args["ShiftDown"]`, `args["CtrlDown"]`,
|
||||
or `args["AltDown"]`, depending on the passed value of `mod`.
|
||||
"""
|
||||
if mod == "shift":
|
||||
return args["ShiftDown"]
|
||||
elif mod == "ctrl":
|
||||
return args["CtrlDown"]
|
||||
elif mod == "alt":
|
||||
return args["AltDown"]
|
||||
|
||||
|
||||
hasMod = has_mod
|
||||
|
||||
|
||||
def set_mod(args, mod, state):
|
||||
"""Set a specific modifier state in args.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
args: Coin event
|
||||
The Coin event received from the 3D view.
|
||||
|
||||
mod: str
|
||||
A string indicating the modifier, either `'shift'`, `'ctrl'`,
|
||||
or `'alt'`.
|
||||
|
||||
state: bool
|
||||
The boolean value of `state` is assigned to `args["ShiftDown"]`,
|
||||
`args["CtrlDown"]`, or `args["AltDown"]`
|
||||
depending on `mod`.
|
||||
"""
|
||||
if mod == "shift":
|
||||
args["ShiftDown"] = state
|
||||
elif mod == "ctrl":
|
||||
args["CtrlDown"] = state
|
||||
elif mod == "alt":
|
||||
args["AltDown"] = state
|
||||
|
||||
|
||||
setMod = set_mod
|
||||
|
||||
|
||||
def get_point(target, args,
|
||||
mobile=False, sym=False, workingplane=True, noTracker=False):
|
||||
"""Return a constrained 3D point and its original point.
|
||||
|
||||
It is used by the Draft tools.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
target: object (class)
|
||||
The target object with a `node` attribute. If this is present,
|
||||
return the last node, otherwise return `None`.
|
||||
|
||||
In the Draft tools, `target` is essentially the same class
|
||||
of the Gui command, that is, `self`. Therefore, this method
|
||||
probably makes more sense as a class method.
|
||||
|
||||
args: Coin event
|
||||
The Coin event received from the 3D view.
|
||||
|
||||
mobile: bool, optional
|
||||
It defaults to `False`.
|
||||
If it is `True` the constraining occurs from the location of
|
||||
the mouse cursor when `Shift` is pressed; otherwise from the last
|
||||
entered point.
|
||||
|
||||
sym: bool, optional
|
||||
It defaults to `False`.
|
||||
If it is `True`, the x and y values always stay equal.
|
||||
|
||||
workingplane: bool, optional
|
||||
It defaults to `True`.
|
||||
If it is `False`, the point won't be projected on the currently
|
||||
active working plane.
|
||||
|
||||
noTracker: bool, optional
|
||||
It defaults to `False`.
|
||||
If it is `True`, the tracking line will not be displayed.
|
||||
|
||||
Returns
|
||||
-------
|
||||
CoinPoint, Base::Vector3, str
|
||||
It returns a tuple with some information.
|
||||
|
||||
The first is the Coin point returned by `Snapper.snap`
|
||||
or by the `ActiveView`; the second is that same point
|
||||
turned into an `App.Vector`,
|
||||
and the third is some information of the point
|
||||
returned by the `Snapper` or by the `ActiveView`.
|
||||
"""
|
||||
ui = Gui.draftToolBar
|
||||
|
||||
if target.node:
|
||||
last = target.node[-1]
|
||||
else:
|
||||
last = None
|
||||
|
||||
amod = hasMod(args, MODSNAP)
|
||||
cmod = hasMod(args, MODCONSTRAIN)
|
||||
point = None
|
||||
|
||||
if hasattr(Gui, "Snapper"):
|
||||
point = Gui.Snapper.snap(args["Position"],
|
||||
lastpoint=last,
|
||||
active=amod,
|
||||
constrain=cmod,
|
||||
noTracker=noTracker)
|
||||
info = Gui.Snapper.snapInfo
|
||||
mask = Gui.Snapper.affinity
|
||||
if not point:
|
||||
p = Gui.ActiveDocument.ActiveView.getCursorPos()
|
||||
point = Gui.ActiveDocument.ActiveView.getPoint(p)
|
||||
info = Gui.ActiveDocument.ActiveView.getObjectInfo(p)
|
||||
mask = None
|
||||
|
||||
ctrlPoint = App.Vector(point)
|
||||
if target.node:
|
||||
if target.featureName == "Rectangle":
|
||||
ui.displayPoint(point, target.node[0],
|
||||
plane=App.DraftWorkingPlane, mask=mask)
|
||||
else:
|
||||
ui.displayPoint(point, target.node[-1],
|
||||
plane=App.DraftWorkingPlane, mask=mask)
|
||||
else:
|
||||
ui.displayPoint(point, plane=App.DraftWorkingPlane, mask=mask)
|
||||
return point, ctrlPoint, info
|
||||
|
||||
|
||||
getPoint = get_point
|
||||
|
||||
|
||||
def set_working_plane_to_object_under_cursor(mouseEvent):
|
||||
"""Set the working plane to the object under the cursor.
|
||||
|
||||
It tests for an object under the cursor.
|
||||
If it is found, it checks whether a `'face'` or `'curve'` component
|
||||
is selected in the object's `Shape`.
|
||||
Then it tries to align the working plane to that face or curve.
|
||||
|
||||
The working plane is only aligned to the face if
|
||||
the working plane is not `'weak'`.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
mouseEvent: Coin event
|
||||
Coin event with the mouse, that is, a click.
|
||||
|
||||
Returns
|
||||
-------
|
||||
None
|
||||
If no object was found in the 3D view under the cursor.
|
||||
Or if the working plane is not `weak`.
|
||||
Or if there was an exception with aligning the working plane
|
||||
to the component under the cursor.
|
||||
|
||||
Coin info
|
||||
The `getObjectInfo` of the object under the cursor.
|
||||
"""
|
||||
objectUnderCursor = gui_utils.get_3d_view().getObjectInfo((
|
||||
mouseEvent["Position"][0],
|
||||
mouseEvent["Position"][1]))
|
||||
|
||||
if not objectUnderCursor:
|
||||
return None
|
||||
|
||||
try:
|
||||
# Get the component "face" or "curve" under the "Shape"
|
||||
# of the selected object
|
||||
componentUnderCursor = getattr(
|
||||
App.ActiveDocument.getObject(objectUnderCursor['Object']).Shape,
|
||||
objectUnderCursor["Component"])
|
||||
|
||||
if not App.DraftWorkingPlane.weak:
|
||||
return None
|
||||
|
||||
if "Face" in objectUnderCursor["Component"]:
|
||||
App.DraftWorkingPlane.alignToFace(componentUnderCursor)
|
||||
else:
|
||||
App.DraftWorkingPlane.alignToCurve(componentUnderCursor)
|
||||
App.DraftWorkingPlane.weak = True
|
||||
return objectUnderCursor
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return None
|
||||
|
||||
|
||||
setWorkingPlaneToObjectUnderCursor = set_working_plane_to_object_under_cursor
|
||||
|
||||
|
||||
def set_working_plane_to_selected_object():
|
||||
"""Set the working plane to the selected object's face.
|
||||
|
||||
The working plane is only aligned to the face if
|
||||
the working plane is `'weak'`.
|
||||
|
||||
Returns
|
||||
-------
|
||||
None
|
||||
If more than one object was selected.
|
||||
Or if the selected object has many subelements.
|
||||
Or if the single subelement is not a `'Face'`.
|
||||
|
||||
App::DocumentObject
|
||||
The single object that contains a single selected face.
|
||||
"""
|
||||
sel = Gui.Selection.getSelectionEx()
|
||||
if len(sel) != 1:
|
||||
return None
|
||||
sel = sel[0]
|
||||
if (sel.HasSubObjects
|
||||
and len(sel.SubElementNames) == 1
|
||||
and "Face" in sel.SubElementNames[0]):
|
||||
if App.DraftWorkingPlane.weak:
|
||||
App.DraftWorkingPlane.alignToFace(sel.SubObjects[0])
|
||||
App.DraftWorkingPlane.weak = True
|
||||
return sel.Object
|
||||
return None
|
||||
|
||||
|
||||
setWorkingPlaneToSelectedObject = set_working_plane_to_selected_object
|
||||
|
||||
|
||||
def get_support(mouseEvent=None):
|
||||
"""Return the supporting object and set the working plane.
|
||||
|
||||
It saves the current working plane, then sets it to the selected object.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
mouseEvent: Coin event, optional
|
||||
It defaults to `None`.
|
||||
Coin event with the mouse, that is, a click.
|
||||
|
||||
If there is a mouse event it calls
|
||||
`set_working_plane_to_object_under_cursor`.
|
||||
Otherwise, it calls `set_working_plane_to_selected_object`.
|
||||
|
||||
Returns
|
||||
-------
|
||||
None
|
||||
If there was a mouse event, but there was nothing under the cursor.
|
||||
Or if the working plane is not `weak`.
|
||||
Or if there was an exception with aligning the working plane
|
||||
to the component under the cursor.
|
||||
Or if more than one object was selected.
|
||||
Or if the selected object has many subelements.
|
||||
Or if the single subelement is not a `'Face'`.
|
||||
|
||||
Coin info
|
||||
If there was a mouse event, the `getObjectInfo`
|
||||
of the object under the cursor.
|
||||
|
||||
App::DocumentObject
|
||||
If there was no mouse event, the single selected object
|
||||
that contains the single selected face that was used
|
||||
to align the working plane.
|
||||
"""
|
||||
App.DraftWorkingPlane.save()
|
||||
if mouseEvent:
|
||||
return setWorkingPlaneToObjectUnderCursor(mouseEvent)
|
||||
return setWorkingPlaneToSelectedObject()
|
||||
|
||||
|
||||
getSupport = get_support
|
||||
|
||||
|
||||
def redraw_3d_view():
|
||||
"""Force a redraw of 3D view or do nothing if it fails."""
|
||||
try:
|
||||
Gui.ActiveDocument.ActiveView.redraw()
|
||||
except AttributeError as err:
|
||||
_wrn(err)
|
||||
|
||||
|
||||
redraw3DView = redraw_3d_view
|
||||
Reference in New Issue
Block a user