[Draft] Improved Snapper Toolbar Behaviour
Changed snap toolbar behaviour: - create a list of available snaps (Gui.Snapper.snaps) - make it consistent with Snap Gui Commands (in gui_snaps module) - create a list of active snaps (Gui.Snapper.active_snaps) - refactor the isEnabled() method to allow it to check if the given snap is in Gui.Snapper.active_snaps and not if the snap toolbar button isChecked() - updated and reordered the new list of gui snap commands in draftutils.init_tools and used it as a base to refactor the creation of draft toolbar - updated all the draft snap gui tools to make them control the toolbar buttons directly . . .
This commit is contained in:
committed by
Yorik van Havre
parent
add624353d
commit
55e537d79d
@@ -1893,8 +1893,7 @@ class DraftToolBar:
|
||||
return str(a)
|
||||
|
||||
def togglesnap(self):
|
||||
if hasattr(FreeCADGui,"Snapper"):
|
||||
FreeCADGui.Snapper.toggle()
|
||||
FreeCADGui.doCommand('FreeCADGui.runCommand("Draft_Snap_Lock")')
|
||||
|
||||
def togglenearsnap(self):
|
||||
if hasattr(FreeCADGui,"Snapper"):
|
||||
|
||||
@@ -39,19 +39,19 @@ import math
|
||||
from pivy import coin
|
||||
from PySide import QtCore, QtGui
|
||||
|
||||
import FreeCAD
|
||||
import FreeCADGui
|
||||
import FreeCAD as App
|
||||
import FreeCADGui as Gui
|
||||
import Draft
|
||||
import DraftVecUtils
|
||||
from FreeCAD import Vector
|
||||
import draftguitools.gui_trackers as trackers
|
||||
from draftutils.init_tools import get_draft_snap_commands
|
||||
from draftutils.messages import _msg, _wrn
|
||||
|
||||
__title__ = "FreeCAD Draft Snap tools"
|
||||
__author__ = "Yorik van Havre"
|
||||
__url__ = "https://www.freecadweb.org"
|
||||
|
||||
|
||||
class Snapper:
|
||||
"""Classes to manage snapping in Draft and Arch.
|
||||
|
||||
@@ -117,6 +117,27 @@ class Snapper:
|
||||
self.callbackMove = None
|
||||
self.snapObjectIndex = 0
|
||||
|
||||
# snap keys, it's important tha they are in this order for
|
||||
# saving in preferences and for properly restore the toolbar
|
||||
self.snaps = ['Lock', # 0
|
||||
'Near', # 1 former "passive" snap
|
||||
'Extension', # 2
|
||||
'Parallel', # 3
|
||||
'Grid', # 4
|
||||
"Endpoint", # 5
|
||||
'Midpoint', # 6
|
||||
'Perpendicular', # 7
|
||||
'Angle', # 8
|
||||
'Center', # 9
|
||||
'Ortho', # 10
|
||||
'Intersection', # 11
|
||||
'Special', # 12
|
||||
'Dimensions', # 13
|
||||
'WorkingPlane' # 14
|
||||
]
|
||||
|
||||
self.init_active_snaps()
|
||||
|
||||
# the snapmarker has "dot","circle" and "square" available styles
|
||||
if self.snapStyle:
|
||||
self.mk = coll.OrderedDict([('passive', 'empty'),
|
||||
@@ -159,6 +180,19 @@ class Snapper:
|
||||
('intersection', ':/icons/Snap_Intersection.svg'),
|
||||
('special', ':/icons/Snap_Special.svg')])
|
||||
|
||||
def init_active_snaps(self):
|
||||
"""
|
||||
set self.active_snaps according to user prefs
|
||||
"""
|
||||
self.active_snaps = []
|
||||
param = App.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft")
|
||||
snap_modes = param.GetString("snapModes")
|
||||
i = 0
|
||||
for snap in snap_modes:
|
||||
if bool(int(snap)):
|
||||
self.active_snaps.append(self.snaps[i])
|
||||
i += 1
|
||||
|
||||
def cstr(self, lastpoint, constrain, point):
|
||||
"""Return constraints if needed."""
|
||||
if constrain or self.mask:
|
||||
@@ -197,8 +231,8 @@ class Snapper:
|
||||
|
||||
if not hasattr(self, "toolbar"):
|
||||
self.makeSnapToolBar()
|
||||
mw = FreeCADGui.getMainWindow()
|
||||
bt = mw.findChild(QtGui.QToolBar, "Draft Snap")
|
||||
mw = Gui.getMainWindow()
|
||||
bt = mw.findChild(QtGui.QToolBar,"Draft Snap")
|
||||
if not bt:
|
||||
mw.addToolBar(self.toolbar)
|
||||
else:
|
||||
@@ -310,7 +344,7 @@ class Snapper:
|
||||
subname = self.snapInfo['SubName']
|
||||
obj = parent.getSubObject(subname, retType=1)
|
||||
else:
|
||||
obj = FreeCAD.ActiveDocument.getObject(self.snapInfo['Object'])
|
||||
obj = App.ActiveDocument.getObject(self.snapInfo['Object'])
|
||||
parent = obj
|
||||
subname = self.snapInfo['Component']
|
||||
if not obj:
|
||||
@@ -434,9 +468,9 @@ class Snapper:
|
||||
|
||||
# calculating the nearest snap point
|
||||
shortest = 1000000000000000000
|
||||
origin = Vector(self.snapInfo['x'],
|
||||
self.snapInfo['y'],
|
||||
self.snapInfo['z'])
|
||||
origin = App.Vector(self.snapInfo['x'],
|
||||
self.snapInfo['y'],
|
||||
self.snapInfo['z'])
|
||||
winner = None
|
||||
fp = point
|
||||
for snap in snaps:
|
||||
@@ -454,7 +488,7 @@ class Snapper:
|
||||
if self.radius:
|
||||
dv = point.sub(winner[2])
|
||||
if (dv.Length > self.radius):
|
||||
if (not oldActive) and self.isEnabled("passive"):
|
||||
if (not oldActive) and self.isEnabled("Near"):
|
||||
winner = self.snapToVertex(self.snapInfo)
|
||||
|
||||
# setting the cursors
|
||||
@@ -482,8 +516,8 @@ class Snapper:
|
||||
def toWP(self, point):
|
||||
"""Project the given point on the working plane, if needed."""
|
||||
if self.isEnabled("WorkingPlane"):
|
||||
if hasattr(FreeCAD, "DraftWorkingPlane"):
|
||||
return FreeCAD.DraftWorkingPlane.projectPoint(point)
|
||||
if hasattr(App, "DraftWorkingPlane"):
|
||||
return App.DraftWorkingPlane.projectPoint(point)
|
||||
return point
|
||||
|
||||
def getApparentPoint(self, x, y):
|
||||
@@ -491,14 +525,14 @@ class Snapper:
|
||||
view = Draft.get3DView()
|
||||
pt = view.getPoint(x, y)
|
||||
if self.mask != "z":
|
||||
if hasattr(FreeCAD, "DraftWorkingPlane"):
|
||||
if hasattr(App,"DraftWorkingPlane"):
|
||||
if view.getCameraType() == "Perspective":
|
||||
camera = view.getCameraNode()
|
||||
p = camera.getField("position").getValue()
|
||||
dv = pt.sub(Vector(p[0], p[1], p[2]))
|
||||
dv = pt.sub(App.Vector(p[0], p[1], p[2]))
|
||||
else:
|
||||
dv = view.getViewDirection()
|
||||
return FreeCAD.DraftWorkingPlane.projectPoint(pt, dv)
|
||||
return App.DraftWorkingPlane.projectPoint(pt, dv)
|
||||
return pt
|
||||
|
||||
def snapToDim(self, obj):
|
||||
@@ -526,7 +560,7 @@ class Snapper:
|
||||
self.extLine.on()
|
||||
self.setCursor(tsnap[1])
|
||||
return tsnap[2], eline
|
||||
if self.isEnabled("extension"):
|
||||
if self.isEnabled("Extension"):
|
||||
tsnap = self.snapToExtOrtho(last, constrain, eline)
|
||||
if tsnap:
|
||||
if (tsnap[0].sub(point)).Length < self.radius:
|
||||
@@ -553,10 +587,10 @@ class Snapper:
|
||||
self.setCursor(tsnap[1])
|
||||
return tsnap[2], eline
|
||||
|
||||
for o in (self.lastObj[1], self.lastObj[0]):
|
||||
if o and (self.isEnabled('extension')
|
||||
or self.isEnabled('parallel')):
|
||||
ob = FreeCAD.ActiveDocument.getObject(o)
|
||||
for o in [self.lastObj[1], self.lastObj[0]]:
|
||||
if o and (self.isEnabled('Extension')
|
||||
or self.isEnabled('Parallel')):
|
||||
ob = App.ActiveDocument.getObject(o)
|
||||
if ob:
|
||||
if ob.isDerivedFrom("Part::Feature"):
|
||||
edges = ob.Shape.Edges
|
||||
@@ -572,7 +606,7 @@ class Snapper:
|
||||
np = self.getPerpendicular(e,point)
|
||||
if not DraftGeomUtils.isPtOnEdge(np,e):
|
||||
if (np.sub(point)).Length < self.radius:
|
||||
if self.isEnabled('extension'):
|
||||
if self.isEnabled('Extension'):
|
||||
if np != e.Vertexes[0].Point:
|
||||
p0 = e.Vertexes[0].Point
|
||||
if self.tracker and not self.selectMode:
|
||||
@@ -603,7 +637,7 @@ class Snapper:
|
||||
self.lastExtensions[0] = ne
|
||||
return np,ne
|
||||
else:
|
||||
if self.isEnabled('parallel'):
|
||||
if self.isEnabled('Parallel'):
|
||||
if last:
|
||||
ve = DraftGeomUtils.vec(e)
|
||||
if not DraftVecUtils.isNull(ve):
|
||||
@@ -620,7 +654,7 @@ class Snapper:
|
||||
|
||||
def snapToCrossExtensions(self, point):
|
||||
"""Snap to the intersection of the last 2 extension lines."""
|
||||
if self.isEnabled('extension'):
|
||||
if self.isEnabled('Extension'):
|
||||
if len(self.lastExtensions) == 2:
|
||||
np = DraftGeomUtils.findIntersection(self.lastExtensions[0], self.lastExtensions[1], True, True)
|
||||
if np:
|
||||
@@ -648,19 +682,19 @@ class Snapper:
|
||||
return p
|
||||
return None
|
||||
|
||||
def snapToPolar(self, point, last):
|
||||
def snapToPolar(self,point,last):
|
||||
"""Snap to polar lines from the given point."""
|
||||
if self.isEnabled('ortho') and (not self.mask):
|
||||
if self.isEnabled('Ortho') and (not self.mask):
|
||||
if last:
|
||||
vecs = []
|
||||
if hasattr(FreeCAD, "DraftWorkingPlane"):
|
||||
ax = [FreeCAD.DraftWorkingPlane.u,
|
||||
FreeCAD.DraftWorkingPlane.v,
|
||||
FreeCAD.DraftWorkingPlane.axis]
|
||||
if hasattr(App,"DraftWorkingPlane"):
|
||||
ax = [App.DraftWorkingPlane.u,
|
||||
App.DraftWorkingPlane.v,
|
||||
App.DraftWorkingPlane.axis]
|
||||
else:
|
||||
ax = [FreeCAD.Vector(1, 0, 0),
|
||||
FreeCAD.Vector(0, 1, 0),
|
||||
FreeCAD.Vector(0, 0, 1)]
|
||||
ax = [App.Vector(1, 0, 0),
|
||||
App.Vector(0, 1, 0),
|
||||
App.Vector(0, 0, 1)]
|
||||
for a in self.polarAngles:
|
||||
if a == 90:
|
||||
vecs.extend([ax[0], ax[0].negative()])
|
||||
@@ -691,7 +725,7 @@ class Snapper:
|
||||
"""Return a grid snap point if available."""
|
||||
if self.grid:
|
||||
if self.grid.Visible:
|
||||
if self.isEnabled("grid"):
|
||||
if self.isEnabled("Grid"):
|
||||
np = self.grid.getClosestNode(point)
|
||||
if np:
|
||||
dv = point.sub(np)
|
||||
@@ -707,7 +741,7 @@ class Snapper:
|
||||
def snapToEndpoints(self, shape):
|
||||
"""Return a list of endpoints snap locations."""
|
||||
snaps = []
|
||||
if self.isEnabled("endpoint"):
|
||||
if self.isEnabled("Endpoint"):
|
||||
if hasattr(shape, "Vertexes"):
|
||||
for v in shape.Vertexes:
|
||||
snaps.append([v.Point, 'endpoint', self.toWP(v.Point)])
|
||||
@@ -725,7 +759,7 @@ class Snapper:
|
||||
def snapToMidpoint(self, shape):
|
||||
"""Return a list of midpoints snap locations."""
|
||||
snaps = []
|
||||
if self.isEnabled("midpoint"):
|
||||
if self.isEnabled("Midpoint"):
|
||||
if isinstance(shape, Part.Edge):
|
||||
mp = DraftGeomUtils.findMidpoint(shape)
|
||||
if mp:
|
||||
@@ -735,7 +769,7 @@ class Snapper:
|
||||
def snapToPerpendicular(self, shape, last):
|
||||
"""Return a list of perpendicular snap locations."""
|
||||
snaps = []
|
||||
if self.isEnabled("perpendicular"):
|
||||
if self.isEnabled("Perpendicular"):
|
||||
if last:
|
||||
if isinstance(shape, Part.Edge):
|
||||
if DraftGeomUtils.geomType(shape) == "Line":
|
||||
@@ -758,7 +792,7 @@ class Snapper:
|
||||
def snapToOrtho(self, shape, last, constrain):
|
||||
"""Return a list of ortho snap locations."""
|
||||
snaps = []
|
||||
if self.isEnabled("ortho"):
|
||||
if self.isEnabled("Ortho"):
|
||||
if constrain:
|
||||
if isinstance(shape, Part.Edge):
|
||||
if last:
|
||||
@@ -774,7 +808,7 @@ class Snapper:
|
||||
|
||||
def snapToExtOrtho(self, last, constrain, eline):
|
||||
"""Return an ortho X extension snap location."""
|
||||
if self.isEnabled("extension") and self.isEnabled("ortho"):
|
||||
if self.isEnabled("Extension") and self.isEnabled("Ortho"):
|
||||
if constrain and last and self.constraintAxis and self.extLine:
|
||||
tmpEdge1 = Part.LineSegment(last, last.add(self.constraintAxis)).toShape()
|
||||
tmpEdge2 = Part.LineSegment(self.extLine.p1(), self.extLine.p2()).toShape()
|
||||
@@ -800,15 +834,15 @@ class Snapper:
|
||||
"""
|
||||
if not self.holdPoints:
|
||||
return None
|
||||
if hasattr(FreeCAD, "DraftWorkingPlane"):
|
||||
u = FreeCAD.DraftWorkingPlane.u
|
||||
v = FreeCAD.DraftWorkingPlane.v
|
||||
if hasattr(App, "DraftWorkingPlane"):
|
||||
u = App.DraftWorkingPlane.u
|
||||
v = App.DraftWorkingPlane.v
|
||||
else:
|
||||
u = FreeCAD.Vector(1, 0, 0)
|
||||
v = FreeCAD.Vector(0, 1, 0)
|
||||
u = App.Vector(1, 0, 0)
|
||||
v = App.Vector(0, 1, 0)
|
||||
if len(self.holdPoints) > 1:
|
||||
# first try mid points
|
||||
if self.isEnabled("midpoint"):
|
||||
if self.isEnabled("Midpoint"):
|
||||
l = list(self.holdPoints)
|
||||
for p1, p2 in itertools.combinations(l, 2):
|
||||
p3 = p1.add((p2.sub(p1)).multiply(0.5))
|
||||
@@ -845,7 +879,7 @@ class Snapper:
|
||||
|
||||
def snapToExtPerpendicular(self, last):
|
||||
"""Return a perpendicular X extension snap location."""
|
||||
if self.isEnabled("extension") and self.isEnabled("perpendicular"):
|
||||
if self.isEnabled("Extension") and self.isEnabled("Perpendicular"):
|
||||
if last and self.extLine:
|
||||
if self.extLine.p1() != self.extLine.p2():
|
||||
tmpEdge = Part.LineSegment(self.extLine.p1(), self.extLine.p2()).toShape()
|
||||
@@ -856,7 +890,7 @@ class Snapper:
|
||||
def snapToElines(self, e1, e2):
|
||||
"""Return a snap at the infinite intersection of the given edges."""
|
||||
snaps = []
|
||||
if self.isEnabled("intersection") and self.isEnabled("extension"):
|
||||
if self.isEnabled("Intersection") and self.isEnabled("Extension"):
|
||||
if e1 and e2:
|
||||
# get the intersection points
|
||||
pts = DraftGeomUtils.findIntersection(e1, e2, True, True)
|
||||
@@ -868,7 +902,7 @@ class Snapper:
|
||||
def snapToAngles(self, shape):
|
||||
"""Return a list of angle snap locations."""
|
||||
snaps = []
|
||||
if self.isEnabled("angle"):
|
||||
if self.isEnabled("Angle"):
|
||||
rad = shape.Curve.Radius
|
||||
pos = shape.Curve.Center
|
||||
for i in (0, 30, 45, 60, 90,
|
||||
@@ -885,7 +919,7 @@ class Snapper:
|
||||
def snapToCenter(self, shape):
|
||||
"""Return a list of center snap locations."""
|
||||
snaps = []
|
||||
if self.isEnabled("center"):
|
||||
if self.isEnabled("Center"):
|
||||
pos = shape.Curve.Center
|
||||
c = self.toWP(pos)
|
||||
if hasattr(shape.Curve, "Radius"):
|
||||
@@ -906,7 +940,7 @@ class Snapper:
|
||||
def snapToFace(self, shape):
|
||||
"""Return a face center snap location."""
|
||||
snaps = []
|
||||
if self.isEnabled("center"):
|
||||
if self.isEnabled("Center"):
|
||||
pos = shape.CenterOfMass
|
||||
c = self.toWP(pos)
|
||||
snaps.append([pos, 'center', c])
|
||||
@@ -915,10 +949,10 @@ class Snapper:
|
||||
def snapToIntersection(self, shape):
|
||||
"""Return a list of intersection snap locations."""
|
||||
snaps = []
|
||||
if self.isEnabled("intersection"):
|
||||
if self.isEnabled("Intersection"):
|
||||
# get the stored objects to calculate intersections
|
||||
if self.lastObj[0]:
|
||||
obj = FreeCAD.ActiveDocument.getObject(self.lastObj[0])
|
||||
obj = App.ActiveDocument.getObject(self.lastObj[0])
|
||||
if obj:
|
||||
if obj.isDerivedFrom("Part::Feature") or (Draft.getType(obj) == "Axis"):
|
||||
if (not self.maxEdges) or (len(obj.Shape.Edges) <= self.maxEdges):
|
||||
@@ -947,7 +981,7 @@ class Snapper:
|
||||
def snapToPolygon(self, obj):
|
||||
"""Return a list of polygon center snap locations."""
|
||||
snaps = []
|
||||
if self.isEnabled("center"):
|
||||
if self.isEnabled("Center"):
|
||||
c = obj.Placement.Base
|
||||
for edge in obj.Shape.Edges:
|
||||
p1 = edge.Vertexes[0].Point
|
||||
@@ -958,29 +992,16 @@ class Snapper:
|
||||
snaps.append([v2, 'center', self.toWP(c)])
|
||||
return snaps
|
||||
|
||||
def snapToVertex(self, info, active=False):
|
||||
"""Return a vertex snap location."""
|
||||
p = Vector(info['x'], info['y'], info['z'])
|
||||
if active:
|
||||
if self.isEnabled("passive"):
|
||||
return [p, 'endpoint', self.toWP(p)]
|
||||
else:
|
||||
return []
|
||||
elif self.isEnabled("passive"):
|
||||
return [p, 'passive', p]
|
||||
else:
|
||||
return []
|
||||
|
||||
def snapToSpecials(self, obj, lastpoint=None, eline=None):
|
||||
"""Return special snap locations, if any."""
|
||||
snaps = []
|
||||
if self.isEnabled("special"):
|
||||
if self.isEnabled("Special"):
|
||||
|
||||
if (Draft.getType(obj) == "Wall"):
|
||||
# special snapping for wall: snap to its base shape if it is linear
|
||||
if obj.Base:
|
||||
if not obj.Base.Shape.Solids:
|
||||
for v in obj.Base.Shape.Vertexes:
|
||||
snaps.append([v.Point, 'special', self.toWP(v.Point)])
|
||||
|
||||
elif (Draft.getType(obj) == "Structure"):
|
||||
@@ -1040,13 +1061,13 @@ class Snapper:
|
||||
def setCursor(self, mode=None):
|
||||
"""Set or reset the cursor to the given mode or resets."""
|
||||
if self.selectMode:
|
||||
mw = FreeCADGui.getMainWindow()
|
||||
mw = Gui.getMainWindow()
|
||||
for w in mw.findChild(QtGui.QMdiArea).findChildren(QtGui.QWidget):
|
||||
if w.metaObject().className() == "SIM::Coin3D::Quarter::QuarterWidget":
|
||||
w.unsetCursor()
|
||||
self.cursorMode = None
|
||||
elif not mode:
|
||||
mw = FreeCADGui.getMainWindow()
|
||||
mw = Gui.getMainWindow()
|
||||
for w in mw.findChild(QtGui.QMdiArea).findChildren(QtGui.QWidget):
|
||||
if w.metaObject().className() == "SIM::Coin3D::Quarter::QuarterWidget":
|
||||
w.unsetCursor()
|
||||
@@ -1064,7 +1085,7 @@ class Snapper:
|
||||
qp.drawPixmap(QtCore.QPoint(16, 8), tp)
|
||||
qp.end()
|
||||
cur = QtGui.QCursor(newicon, 8, 8)
|
||||
mw = FreeCADGui.getMainWindow()
|
||||
mw = Gui.getMainWindow()
|
||||
for w in mw.findChild(QtGui.QMdiArea).findChildren(QtGui.QWidget):
|
||||
if w.metaObject().className() == "SIM::Coin3D::Quarter::QuarterWidget":
|
||||
w.setCursor(cur)
|
||||
@@ -1121,7 +1142,7 @@ class Snapper:
|
||||
"""Keep the current angle."""
|
||||
if delta:
|
||||
self.mask = delta
|
||||
elif isinstance(self.mask, FreeCAD.Vector):
|
||||
elif isinstance(self.mask, App.Vector):
|
||||
self.mask = None
|
||||
elif self.trackLine:
|
||||
if self.trackLine.Visible:
|
||||
@@ -1138,15 +1159,15 @@ class Snapper:
|
||||
used as basepoint.
|
||||
"""
|
||||
# without the Draft module fully loaded, no axes system!"
|
||||
if not hasattr(FreeCAD, "DraftWorkingPlane"):
|
||||
if not hasattr(App, "DraftWorkingPlane"):
|
||||
return point
|
||||
|
||||
point = Vector(point)
|
||||
point = App.Vector(point)
|
||||
|
||||
# setup trackers if needed
|
||||
if not self.constrainLine:
|
||||
if self.snapStyle:
|
||||
self.constrainLine = trackers.lineTracker(scolor=FreeCADGui.draftToolBar.getDefaultColor("snap"))
|
||||
self.constrainLine = trackers.lineTracker(scolor=Gui.draftToolBar.getDefaultColor("snap"))
|
||||
else:
|
||||
self.constrainLine = trackers.lineTracker(dotted=True)
|
||||
|
||||
@@ -1162,23 +1183,23 @@ class Snapper:
|
||||
if self.mask:
|
||||
self.affinity = self.mask
|
||||
if not self.affinity:
|
||||
self.affinity = FreeCAD.DraftWorkingPlane.getClosestAxis(delta)
|
||||
if isinstance(axis, FreeCAD.Vector):
|
||||
self.affinity = App.DraftWorkingPlane.getClosestAxis(delta)
|
||||
if isinstance(axis, App.Vector):
|
||||
self.constraintAxis = axis
|
||||
elif axis == "x":
|
||||
self.constraintAxis = FreeCAD.DraftWorkingPlane.u
|
||||
self.constraintAxis = App.DraftWorkingPlane.u
|
||||
elif axis == "y":
|
||||
self.constraintAxis = FreeCAD.DraftWorkingPlane.v
|
||||
self.constraintAxis = App.DraftWorkingPlane.v
|
||||
elif axis == "z":
|
||||
self.constraintAxis = FreeCAD.DraftWorkingPlane.axis
|
||||
self.constraintAxis = App.DraftWorkingPlane.axis
|
||||
else:
|
||||
if self.affinity == "x":
|
||||
self.constraintAxis = FreeCAD.DraftWorkingPlane.u
|
||||
self.constraintAxis = App.DraftWorkingPlane.u
|
||||
elif self.affinity == "y":
|
||||
self.constraintAxis = FreeCAD.DraftWorkingPlane.v
|
||||
self.constraintAxis = App.DraftWorkingPlane.v
|
||||
elif self.affinity == "z":
|
||||
self.constraintAxis = FreeCAD.DraftWorkingPlane.axis
|
||||
elif isinstance(self.affinity, FreeCAD.Vector):
|
||||
self.constraintAxis = App.DraftWorkingPlane.axis
|
||||
elif isinstance(self.affinity, App.Vector):
|
||||
self.constraintAxis = self.affinity
|
||||
else:
|
||||
self.constraintAxis = None
|
||||
@@ -1229,7 +1250,7 @@ class Snapper:
|
||||
if point:
|
||||
print "got a 3D point: ",point
|
||||
|
||||
FreeCADGui.Snapper.getPoint(callback=cb)
|
||||
Gui.Snapper.getPoint(callback=cb)
|
||||
|
||||
If the callback function accepts more than one argument,
|
||||
it will also receive the last snapped object. Finally, a qt widget
|
||||
@@ -1243,7 +1264,7 @@ class Snapper:
|
||||
self.pt = None
|
||||
self.lastSnappedObject = None
|
||||
self.holdPoints = []
|
||||
self.ui = FreeCADGui.draftToolBar
|
||||
self.ui = Gui.draftToolBar
|
||||
self.view = Draft.get3DView()
|
||||
|
||||
# remove any previous leftover callbacks
|
||||
@@ -1259,20 +1280,20 @@ class Snapper:
|
||||
mousepos = event.getPosition()
|
||||
ctrl = event.wasCtrlDown()
|
||||
shift = event.wasShiftDown()
|
||||
self.pt = FreeCADGui.Snapper.snap(mousepos, lastpoint=last,
|
||||
active=ctrl, constrain=shift)
|
||||
if hasattr(FreeCAD, "DraftWorkingPlane"):
|
||||
self.pt = Gui.Snapper.snap(mousepos, lastpoint=last,
|
||||
active=ctrl, constrain=shift)
|
||||
if hasattr(App, "DraftWorkingPlane"):
|
||||
self.ui.displayPoint(self.pt, last,
|
||||
plane=FreeCAD.DraftWorkingPlane,
|
||||
mask=FreeCADGui.Snapper.affinity)
|
||||
plane = App.DraftWorkingPlane,
|
||||
mask = App.Snapper.affinity)
|
||||
if movecallback:
|
||||
movecallback(self.pt, self.snapInfo)
|
||||
|
||||
def getcoords(point, relative=False):
|
||||
"""Get the global coordinates from a point."""
|
||||
self.pt = point
|
||||
if relative and last and hasattr(FreeCAD, "DraftWorkingPlane"):
|
||||
v = FreeCAD.DraftWorkingPlane.getGlobalCoords(point)
|
||||
if relative and last and hasattr(App, "DraftWorkingPlane"):
|
||||
v = App.DraftWorkingPlane.getGlobalCoords(point)
|
||||
self.pt = last.add(v)
|
||||
accept()
|
||||
|
||||
@@ -1289,8 +1310,8 @@ class Snapper:
|
||||
self.view.removeEventCallbackPivy(coin.SoLocation2Event.getClassTypeId(), self.callbackMove)
|
||||
self.callbackClick = None
|
||||
self.callbackMove = None
|
||||
obj = FreeCADGui.Snapper.lastSnappedObject
|
||||
FreeCADGui.Snapper.off()
|
||||
obj = Gui.Snapper.lastSnappedObject
|
||||
Gui.Snapper.off()
|
||||
self.ui.offUi()
|
||||
if callback:
|
||||
if len(inspect.getargspec(callback).args) > 1:
|
||||
@@ -1306,7 +1327,7 @@ class Snapper:
|
||||
self.view.removeEventCallbackPivy(coin.SoLocation2Event.getClassTypeId(), self.callbackMove)
|
||||
self.callbackClick = None
|
||||
self.callbackMove = None
|
||||
FreeCADGui.Snapper.off()
|
||||
Gui.Snapper.off()
|
||||
self.ui.offUi()
|
||||
if callback:
|
||||
if len(inspect.getargspec(callback).args) > 1:
|
||||
@@ -1332,121 +1353,90 @@ class Snapper:
|
||||
|
||||
def makeSnapToolBar(self):
|
||||
"""Build the Snap toolbar."""
|
||||
mw = FreeCADGui.getMainWindow()
|
||||
mw = Gui.getMainWindow()
|
||||
self.toolbar = QtGui.QToolBar(mw)
|
||||
mw.addToolBar(QtCore.Qt.TopToolBarArea, self.toolbar)
|
||||
self.toolbar.setObjectName("Draft Snap")
|
||||
self.toolbar.setWindowTitle(QtCore.QCoreApplication.translate("Workbench", "Draft Snap"))
|
||||
self.toolbarButtons = []
|
||||
|
||||
# grid button
|
||||
self.gridbutton = QtGui.QAction(mw)
|
||||
self.gridbutton.setIcon(QtGui.QIcon.fromTheme("Draft_Grid", QtGui.QIcon(":/icons/Draft_Grid.svg")))
|
||||
self.gridbutton.setText(QtCore.QCoreApplication.translate("Draft_ToggleGrid", "Grid"))
|
||||
self.gridbutton.setToolTip(QtCore.QCoreApplication.translate("Draft_ToggleGrid", "Toggles the Draft grid On/Off"))
|
||||
self.gridbutton.setObjectName("GridButton")
|
||||
self.gridbutton.setWhatsThis("Draft_ToggleGrid")
|
||||
QtCore.QObject.connect(self.gridbutton, QtCore.SIGNAL("triggered()"), self.toggleGrid)
|
||||
self.toolbar.addAction(self.gridbutton)
|
||||
snap_gui_commands = get_draft_snap_commands()
|
||||
self.init_draft_snap_buttons(snap_gui_commands, self.toolbar, "_Button")
|
||||
self.restore_snap_buttons_state(self.toolbar,"_Button")
|
||||
|
||||
# master button
|
||||
self.masterbutton = QtGui.QAction(mw)
|
||||
self.masterbutton.setIcon(QtGui.QIcon.fromTheme("Snap_Lock", QtGui.QIcon(":/icons/Snap_Lock.svg")))
|
||||
self.masterbutton.setText(QtCore.QCoreApplication.translate("Draft_Snap_Lock", "Lock"))
|
||||
self.masterbutton.setToolTip(QtCore.QCoreApplication.translate("Draft_Snap_Lock", "Toggle On/Off"))
|
||||
self.masterbutton.setObjectName("SnapButtonMain")
|
||||
self.masterbutton.setWhatsThis("Draft_ToggleSnap")
|
||||
self.masterbutton.setCheckable(True)
|
||||
self.masterbutton.setChecked(True)
|
||||
QtCore.QObject.connect(self.masterbutton,
|
||||
QtCore.SIGNAL("toggled(bool)"), self.toggle)
|
||||
self.toolbar.addAction(self.masterbutton)
|
||||
for c,i in self.cursors.items():
|
||||
if i:
|
||||
b = QtGui.QAction(mw)
|
||||
b.setIcon(QtGui.QIcon.fromTheme(i.replace(':/icons/', '').replace('.svg', ''), QtGui.QIcon(i)))
|
||||
if c == "passive":
|
||||
b.setText(QtCore.QCoreApplication.translate("Draft_Snap_Near", "Nearest"))
|
||||
b.setToolTip(QtCore.QCoreApplication.translate("Draft_Snap_Near", "Nearest"))
|
||||
else:
|
||||
b.setText(QtCore.QCoreApplication.translate("Draft_Snap_"+c.capitalize(), c.capitalize()))
|
||||
b.setToolTip(QtCore.QCoreApplication.translate("Draft_Snap_"+c.capitalize(), c.capitalize()))
|
||||
b.setObjectName("SnapButton" + c)
|
||||
b.setWhatsThis("Draft_" + c.capitalize())
|
||||
b.setCheckable(True)
|
||||
b.setChecked(True)
|
||||
self.toolbar.addAction(b)
|
||||
self.toolbarButtons.append(b)
|
||||
QtCore.QObject.connect(b, QtCore.SIGNAL("toggled(bool)"),
|
||||
self.saveSnapModes)
|
||||
if not Draft.getParam("showSnapBar",True):
|
||||
self.toolbar.hide()
|
||||
|
||||
# adding non-snap button
|
||||
for n in ("Dimensions", "WorkingPlane"):
|
||||
b = QtGui.QAction(mw)
|
||||
b.setIcon(QtGui.QIcon.fromTheme("Snap_" + n, QtGui.QIcon(":/icons/Snap_"+n+".svg")))
|
||||
b.setText(QtCore.QCoreApplication.translate("Draft_Snap_" + n,n))
|
||||
b.setToolTip(QtCore.QCoreApplication.translate("Draft_Snap_" + n,n))
|
||||
b.setObjectName("SnapButton" + n)
|
||||
b.setWhatsThis("Draft_" + n)
|
||||
def init_draft_snap_buttons(self, commands, context, button_suffix):
|
||||
"""
|
||||
Init Draft Snap toolbar buttons.
|
||||
|
||||
Parameters:
|
||||
commands Snap command list,
|
||||
use: get_draft_snap_commands():
|
||||
context The toolbar or action group the buttons have
|
||||
to be added to
|
||||
button_suffix The suffix that have to be applied to the command name
|
||||
to define the button name
|
||||
"""
|
||||
for gc in commands:
|
||||
# setup toolbar buttons
|
||||
command = 'Gui.runCommand("' + gc + '")'
|
||||
b = QtGui.QAction(context)
|
||||
b.setIcon(QtGui.QIcon(':/icons/' + gc[6:] + '.svg'))
|
||||
b.setText(QtCore.QCoreApplication.translate("Draft_Snap", "Snap " + gc[11:]))
|
||||
b.setToolTip(QtCore.QCoreApplication.translate("Draft_Snap", "Snap " + gc[11:]))
|
||||
b.setObjectName(gc + button_suffix)
|
||||
b.setWhatsThis("Draft_"+gc[11:].capitalize())
|
||||
b.setCheckable(True)
|
||||
b.setChecked(True)
|
||||
self.toolbar.addAction(b)
|
||||
QtCore.QObject.connect(b, QtCore.SIGNAL("toggled(bool)"),
|
||||
self.saveSnapModes)
|
||||
self.toolbarButtons.append(b)
|
||||
context.addAction(b)
|
||||
QtCore.QObject.connect(b,
|
||||
QtCore.SIGNAL("triggered()"),
|
||||
lambda f=Gui.doCommand,
|
||||
arg=command:f(arg))
|
||||
|
||||
# set status tip where needed
|
||||
for b in self.toolbar.actions():
|
||||
for b in context.actions():
|
||||
if len(b.statusTip()) == 0:
|
||||
b.setStatusTip(b.toolTip())
|
||||
|
||||
# restoring states
|
||||
t = Draft.getParam("snapModes", "111111111101111")
|
||||
if t:
|
||||
c = 0
|
||||
for b in [self.masterbutton] + self.toolbarButtons:
|
||||
if len(t) > c:
|
||||
state = bool(int(t[c]))
|
||||
b.setChecked(state)
|
||||
def restore_snap_buttons_state(self, toolbar, button_suffix):
|
||||
"""
|
||||
Restore toolbar button's checked state according to
|
||||
"snapModes" saved in preferences
|
||||
"""
|
||||
# set status tip where needed
|
||||
param = App.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft")
|
||||
snap_modes = param.GetString("snapModes")
|
||||
|
||||
for b in toolbar.actions():
|
||||
if len(b.statusTip()) == 0:
|
||||
b.setStatusTip(b.toolTip())
|
||||
|
||||
# restore toolbar buttons state
|
||||
if snap_modes:
|
||||
for a in toolbar.findChildren(QtGui.QAction):
|
||||
snap = a.objectName()[11:].replace(button_suffix,"")
|
||||
if snap in Gui.Snapper.snaps:
|
||||
i = Gui.Snapper.snaps.index(snap)
|
||||
state = bool(int(snap_modes[i]))
|
||||
a.setChecked(state)
|
||||
if state:
|
||||
b.setToolTip(b.toolTip() + " (ON)")
|
||||
a.setToolTip(a.toolTip()+" (ON)")
|
||||
else:
|
||||
b.setToolTip(b.toolTip() + " (OFF)")
|
||||
c += 1
|
||||
if not Draft.getParam("showSnapBar", True):
|
||||
self.toolbar.hide()
|
||||
a.setToolTip(a.toolTip()+" (OFF)")
|
||||
|
||||
def get_snap_toolbar(self):
|
||||
"""retuns snap toolbar object"""
|
||||
mw = Gui.getMainWindow()
|
||||
if mw:
|
||||
toolbar = mw.findChild(QtGui.QToolBar,"Draft Snap")
|
||||
if toolbar:
|
||||
return toolbar
|
||||
return None
|
||||
|
||||
def toggleGrid(self):
|
||||
"""Run Draft_ToggleGrid."""
|
||||
FreeCADGui.runCommand("Draft_ToggleGrid")
|
||||
|
||||
def saveSnapModes(self):
|
||||
"""Save the snap modes for next sessions."""
|
||||
t = ''
|
||||
for b in [self.masterbutton] + self.toolbarButtons:
|
||||
t += str(int(b.isChecked()))
|
||||
if b.isChecked():
|
||||
b.setToolTip(b.toolTip().replace("OFF", "ON"))
|
||||
else:
|
||||
b.setToolTip(b.toolTip().replace("ON", "OFF"))
|
||||
Draft.setParam("snapModes", t)
|
||||
|
||||
def toggle(self, checked=None):
|
||||
"""Toggle the snap mode."""
|
||||
if hasattr(self, "toolbarButtons"):
|
||||
if checked is None:
|
||||
self.masterbutton.toggle()
|
||||
elif checked:
|
||||
if hasattr(self, "savedButtonStates"):
|
||||
for i in range(len(self.toolbarButtons)):
|
||||
self.toolbarButtons[i].setEnabled(True)
|
||||
self.toolbarButtons[i].setChecked(self.savedButtonStates[i])
|
||||
else:
|
||||
self.savedButtonStates = []
|
||||
for i in range(len(self.toolbarButtons)):
|
||||
self.savedButtonStates.append(self.toolbarButtons[i].isChecked())
|
||||
self.toolbarButtons[i].setEnabled(False)
|
||||
self.saveSnapModes()
|
||||
"toggle FreeCAD Draft Grid"
|
||||
Gui.runCommand("Draft_ToggleGrid")
|
||||
|
||||
def showradius(self):
|
||||
"""Show the snap radius indicator."""
|
||||
@@ -1456,32 +1446,66 @@ class Snapper:
|
||||
self.radiusTracker.update(self.radius)
|
||||
self.radiusTracker.on()
|
||||
|
||||
def isEnabled(self, but):
|
||||
"""Return true if the given button is turned on."""
|
||||
for b in self.toolbarButtons:
|
||||
if str(b.objectName()) == "SnapButton" + but:
|
||||
return (b.isEnabled() and b.isChecked())
|
||||
return False
|
||||
def isEnabled(self, snap):
|
||||
"Returns true if the given snap is on"
|
||||
if "Lock" in self.active_snaps and snap in self.active_snaps:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def toggle_snap(self, snap, set_to = None):
|
||||
"Sets the given snap on/off according to the given parameter"
|
||||
if set_to: # set mode
|
||||
if set_to is True:
|
||||
if not snap in self.active_snaps:
|
||||
self.active_snaps.append(snap)
|
||||
status = True
|
||||
elif set_to is False:
|
||||
if snap in self.active_snaps:
|
||||
self.active_snaps.remove(snap)
|
||||
status = False
|
||||
else: # toggle mode, default
|
||||
if not snap in self.active_snaps:
|
||||
self.active_snaps.append(snap)
|
||||
status = True
|
||||
elif snap in self.active_snaps:
|
||||
self.active_snaps.remove(snap)
|
||||
status = False
|
||||
self.save_snap_state()
|
||||
return status
|
||||
|
||||
def save_snap_state(self):
|
||||
"""
|
||||
save snap state to user preferences to be restored in next session
|
||||
"""
|
||||
param = App.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft")
|
||||
snap_modes = ""
|
||||
for snap in self.snaps:
|
||||
if snap in self.active_snaps:
|
||||
snap_modes += "1"
|
||||
else:
|
||||
snap_modes += "0"
|
||||
param.SetString("snapModes",snap_modes)
|
||||
|
||||
def show(self):
|
||||
"""Show the toolbar and the grid."""
|
||||
if not hasattr(self, "toolbar"):
|
||||
self.makeSnapToolBar()
|
||||
mw = FreeCADGui.getMainWindow()
|
||||
bt = mw.findChild(QtGui.QToolBar, "Draft Snap")
|
||||
bt = self.get_snap_toolbar()
|
||||
if not bt:
|
||||
mw = FreeCADGui.getMainWindow()
|
||||
mw.addToolBar(self.toolbar)
|
||||
self.toolbar.setParent(mw)
|
||||
self.toolbar.show()
|
||||
self.toolbar.toggleViewAction().setVisible(True)
|
||||
if FreeCADGui.ActiveDocument:
|
||||
if Gui.ActiveDocument:
|
||||
self.setTrackers()
|
||||
if not FreeCAD.ActiveDocument.Objects:
|
||||
if FreeCADGui.ActiveDocument.ActiveView:
|
||||
if FreeCADGui.ActiveDocument.ActiveView.getCameraType() == 'Orthographic':
|
||||
c = FreeCADGui.ActiveDocument.ActiveView.getCameraNode()
|
||||
if not App.ActiveDocument.Objects:
|
||||
if Gui.ActiveDocument.ActiveView:
|
||||
if Gui.ActiveDocument.ActiveView.getCameraType() == 'Orthographic':
|
||||
c = Gui.ActiveDocument.ActiveView.getCameraNode()
|
||||
if c.orientation.getValue().getValue() == (0.0, 0.0, 0.0, 1.0):
|
||||
p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft")
|
||||
p = App.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft")
|
||||
h = p.GetInt("defaultCameraHeight",0)
|
||||
if h:
|
||||
c.height.setValue(h)
|
||||
@@ -1523,7 +1547,7 @@ class Snapper:
|
||||
self.tracker = trackers.snapTracker()
|
||||
self.trackLine = trackers.lineTracker()
|
||||
if self.snapStyle:
|
||||
c = FreeCADGui.draftToolBar.getDefaultColor("snap")
|
||||
c = Gui.draftToolBar.getDefaultColor("snap")
|
||||
self.extLine = trackers.lineTracker(scolor=c)
|
||||
self.extLine2 = trackers.lineTracker(scolor=c)
|
||||
else:
|
||||
|
||||
@@ -28,12 +28,23 @@
|
||||
# \brief Provide the Draft_Snap commands used by the snapping mechanism
|
||||
# in Draft.
|
||||
|
||||
from PySide.QtCore import QT_TRANSLATE_NOOP
|
||||
|
||||
import draftguitools.gui_base as gui_base
|
||||
import FreeCADGui as Gui
|
||||
import draftguitools.gui_base as gui_base
|
||||
from draftutils.translate import _tr
|
||||
|
||||
from PySide.QtCore import QT_TRANSLATE_NOOP
|
||||
from draftutils.translate import _tr
|
||||
|
||||
|
||||
class Draft_Snap_Lock(gui_base.GuiCommandSimplest):
|
||||
"""GuiCommand for the Draft_Snap_Lock tool.
|
||||
|
||||
Activate or deactivate all snap methods at once.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(name=_tr("Main toggle snap"))
|
||||
|
||||
class Draft_Snap_Lock(gui_base.GuiCommandSimplest):
|
||||
"""GuiCommand for the Draft_Snap_Lock tool.
|
||||
@@ -63,6 +74,11 @@ class Draft_Snap_Lock(gui_base.GuiCommandSimplest):
|
||||
if hasattr(Gui.Snapper, "masterbutton"):
|
||||
Gui.Snapper.masterbutton.toggle()
|
||||
|
||||
if hasattr(Gui, "Snapper"):
|
||||
if hasattr(Gui.Snapper, "masterbutton"):
|
||||
Gui.Snapper.masterbutton.toggle()
|
||||
|
||||
Gui.addCommand('Draft_Snap_Lock', Draft_Snap_Lock())
|
||||
|
||||
Gui.addCommand('Draft_Snap_Lock', Draft_Snap_Lock())
|
||||
|
||||
|
||||
@@ -115,15 +115,15 @@ def get_draft_utility_commands():
|
||||
|
||||
def get_draft_snap_commands():
|
||||
"""Return the snapping commands list."""
|
||||
return ['Draft_Snap_Lock', 'Draft_Snap_Midpoint',
|
||||
'Draft_Snap_Perpendicular',
|
||||
'Draft_Snap_Grid', 'Draft_Snap_Intersection',
|
||||
'Draft_Snap_Parallel',
|
||||
'Draft_Snap_Endpoint', 'Draft_Snap_Angle',
|
||||
'Draft_Snap_Center',
|
||||
'Draft_Snap_Extension', 'Draft_Snap_Near',
|
||||
'Draft_Snap_Ortho', 'Draft_Snap_Special',
|
||||
'Draft_Snap_Dimensions', 'Draft_Snap_WorkingPlane']
|
||||
return ['Draft_Snap_Lock',
|
||||
'Draft_Snap_Endpoint', 'Draft_Snap_Midpoint',
|
||||
'Draft_Snap_Center', 'Draft_Snap_Angle',
|
||||
'Draft_Snap_Intersection', 'Draft_Snap_Perpendicular',
|
||||
'Draft_Snap_Extension', 'Draft_Snap_Parallel',
|
||||
'Draft_Snap_Special', 'Draft_Snap_Near',
|
||||
'Draft_Snap_Ortho', 'Draft_Snap_Grid',
|
||||
'Draft_Snap_WorkingPlane', 'Draft_Snap_Dimensions',
|
||||
]
|
||||
|
||||
|
||||
def init_draft_toolbars(workbench):
|
||||
|
||||
Reference in New Issue
Block a user