Draft/BIM: Change Continue behavior and caching among commands (#20748)
* Draft: Cache ContinueMode setting for every tool separately Currently ContinueMode is done to be held globally, so this patch changes this to cache it inside `user.cfg` for every cmd separately. * Draft: Add Chained Mode option for Dimension Added new option under Dimension, although this is simply porting the existing logic of "Continue" under "Chained Mode", whereas allowing existing "Continue" mode to retrigger the command instead of placing Dimensions in a chain.
This commit is contained in:
@@ -156,6 +156,7 @@ class DraftToolBar:
|
||||
self.paramconstr = utils.rgba_to_argb(params.get_param("constructioncolor"))
|
||||
self.constrMode = False
|
||||
self.continueMode = False
|
||||
self.chainedMode = False
|
||||
self.relativeMode = True
|
||||
self.globalMode = False
|
||||
self.state = None
|
||||
@@ -390,7 +391,11 @@ class DraftToolBar:
|
||||
self.relativeMode = params.get_param("RelativeMode")
|
||||
self.globalMode = params.get_param("GlobalMode")
|
||||
self.makeFaceMode = params.get_param("MakeFaceMode")
|
||||
self.continueMode = params.get_param("ContinueMode")
|
||||
|
||||
feature_name = getattr(FreeCAD.activeDraftCommand, "featureName", None)
|
||||
self.continueMode = params.get_param(feature_name, "Mod/Draft/ContinueMode", silent=True)
|
||||
|
||||
self.chainedMode = params.get_param("ChainedMode")
|
||||
|
||||
# Note: The order of the calls to self._checkbox() below controls
|
||||
# the position of the checkboxes in the task panel.
|
||||
@@ -399,7 +404,11 @@ class DraftToolBar:
|
||||
self.isRelative = self._checkbox("isRelative", self.layout, checked=self.relativeMode)
|
||||
self.isGlobal = self._checkbox("isGlobal", self.layout, checked=self.globalMode)
|
||||
self.makeFace = self._checkbox("makeFace", self.layout, checked=self.makeFaceMode)
|
||||
self.continueCmd = self._checkbox("continueCmd", self.layout, checked=self.continueMode)
|
||||
self.continueCmd = self._checkbox("continueCmd", self.layout, checked=bool(self.continueMode))
|
||||
self.chainedModeCmd = self._checkbox("chainedModeCmd", self.layout, checked=self.chainedMode)
|
||||
|
||||
self.chainedModeCmd.setEnabled(not (hasattr(self.sourceCmd, "contMode") and self.continueMode))
|
||||
self.continueCmd.setEnabled(not (hasattr(self.sourceCmd, "chain") and self.chainedMode))
|
||||
|
||||
# update checkboxes without parameters and without internal modes:
|
||||
self.occOffset = self._checkbox("occOffset", self.layout, checked=False)
|
||||
@@ -449,6 +458,7 @@ class DraftToolBar:
|
||||
QtCore.QObject.connect(self.undoButton,QtCore.SIGNAL("pressed()"),self.undoSegment)
|
||||
QtCore.QObject.connect(self.selectButton,QtCore.SIGNAL("pressed()"),self.selectEdge)
|
||||
QtCore.QObject.connect(self.continueCmd,QtCore.SIGNAL("stateChanged(int)"),self.setContinue)
|
||||
QtCore.QObject.connect(self.chainedModeCmd,QtCore.SIGNAL("stateChanged(int)"),self.setChainedMode)
|
||||
|
||||
QtCore.QObject.connect(self.isCopy,QtCore.SIGNAL("stateChanged(int)"),self.setCopymode)
|
||||
QtCore.QObject.connect(self.isSubelementMode, QtCore.SIGNAL("stateChanged(int)"), self.setSubelementMode)
|
||||
@@ -549,6 +559,9 @@ class DraftToolBar:
|
||||
+ "the command button again"))
|
||||
self.continueCmd.setText(translate(
|
||||
"draft", "Continue") + " (" + _get_incmd_shortcut("Continue") + ")")
|
||||
self.chainedModeCmd.setText(translate("draft", "Chained Mode"))
|
||||
self.chainedModeCmd.setToolTip(translate("draft", "If checked, next Dimension will be placed in a chain" \
|
||||
" with the previously placed Dimension"))
|
||||
self.occOffset.setToolTip(translate(
|
||||
"draft", "If checked, an OCC-style offset will be performed"
|
||||
+ " instead of the classic offset"))
|
||||
@@ -920,8 +933,14 @@ class DraftToolBar:
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
def setContinue(self, val):
|
||||
params.set_param("ContinueMode", bool(val))
|
||||
params.set_param(FreeCAD.activeDraftCommand.featureName, bool(val), "Mod/Draft/ContinueMode")
|
||||
self.continueMode = bool(val)
|
||||
self.chainedModeCmd.setEnabled(not val)
|
||||
|
||||
def setChainedMode(self, val):
|
||||
params.set_param("ChainedMode", bool(val))
|
||||
self.chainedMode = bool(val)
|
||||
self.continueCmd.setEnabled(not val)
|
||||
|
||||
# val=-1 is used to temporarily switch to relativeMode and disable the checkbox.
|
||||
# val=-2 is used to switch back.
|
||||
|
||||
@@ -74,8 +74,10 @@ class Dimension(gui_base_original.Creator):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.max = 2
|
||||
self.cont = None
|
||||
self.chain = None
|
||||
self.contMode = None
|
||||
self.dir = None
|
||||
self.featureName = "Dimension"
|
||||
|
||||
def GetResources(self):
|
||||
"""Set icon, menu and tooltip."""
|
||||
@@ -87,13 +89,14 @@ class Dimension(gui_base_original.Creator):
|
||||
|
||||
def Activated(self):
|
||||
"""Execute when the command is called."""
|
||||
if self.cont:
|
||||
if self.chain and not self.contMode:
|
||||
self.finish()
|
||||
else:
|
||||
super().Activated(name="Dimension")
|
||||
super().Activated(name=self.featureName)
|
||||
if self.ui:
|
||||
self.ui.pointUi(title=translate("draft", "Dimension"), icon="Draft_Dimension")
|
||||
self.ui.pointUi(title=translate("draft", self.featureName), icon="Draft_Dimension")
|
||||
self.ui.continueCmd.show()
|
||||
self.ui.chainedModeCmd.show()
|
||||
self.ui.selectButton.show()
|
||||
self.altdown = False
|
||||
self.call = self.view.addEventCallback("SoEvent", self.action)
|
||||
@@ -159,7 +162,8 @@ class Dimension(gui_base_original.Creator):
|
||||
def finish(self, cont=False):
|
||||
"""Terminate the operation."""
|
||||
self.end_callbacks(self.call)
|
||||
self.cont = None
|
||||
self.chain = None
|
||||
self.contMode = None
|
||||
self.dir = None
|
||||
if self.ui:
|
||||
self.dimtrack.finalize()
|
||||
@@ -283,8 +287,9 @@ class Dimension(gui_base_original.Creator):
|
||||
# Linear dimension, not linked to any edge
|
||||
self.create_linear_dimension()
|
||||
|
||||
if self.ui.continueMode:
|
||||
self.cont = self.node[2]
|
||||
if self.ui.chainedMode or self.ui.continueMode:
|
||||
if self.ui.chainedMode:
|
||||
self.chain = self.node[2]
|
||||
if not self.dir:
|
||||
if self.link:
|
||||
v1 = self.link[0].Shape.Vertexes[self.link[1]].Point
|
||||
@@ -339,7 +344,7 @@ class Dimension(gui_base_original.Creator):
|
||||
ed = ob.Shape.Edges[num]
|
||||
v1 = ed.Vertexes[0].Point
|
||||
v2 = ed.Vertexes[-1].Point
|
||||
self.dimtrack.update([v1, v2, self.cont])
|
||||
self.dimtrack.update([v1, v2, self.chain])
|
||||
else:
|
||||
if self.node and (len(self.edges) < 2):
|
||||
self.dimtrack.on()
|
||||
@@ -413,7 +418,7 @@ class Dimension(gui_base_original.Creator):
|
||||
# update the dimline
|
||||
if self.node and not self.arcmode:
|
||||
self.dimtrack.update(self.node
|
||||
+ [self.point] + [self.cont])
|
||||
+ [self.point] + [self.chain])
|
||||
gui_tool_utils.redraw3DView()
|
||||
elif arg["Type"] == "SoMouseButtonEvent":
|
||||
if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"):
|
||||
@@ -493,10 +498,10 @@ class Dimension(gui_base_original.Creator):
|
||||
self.dimtrack.on()
|
||||
if self.planetrack:
|
||||
self.planetrack.set(self.node[0])
|
||||
elif len(self.node) == 2 and self.cont:
|
||||
self.node.append(self.cont)
|
||||
elif len(self.node) == 2 and self.chain:
|
||||
self.node.append(self.chain)
|
||||
self.createObject()
|
||||
if not self.cont:
|
||||
if not self.chain:
|
||||
self.finish()
|
||||
elif len(self.node) == 3:
|
||||
# for unlinked arc mode:
|
||||
@@ -506,7 +511,10 @@ class Dimension(gui_base_original.Creator):
|
||||
# cen = self.node[0].add(v)
|
||||
# self.node = [self.node[0], self.node[1], cen]
|
||||
self.createObject()
|
||||
if not self.cont:
|
||||
if self.ui.continueMode:
|
||||
self.contMode = True
|
||||
self.Activated()
|
||||
elif not self.chain:
|
||||
self.finish()
|
||||
elif self.angledata:
|
||||
self.node.append(self.point)
|
||||
@@ -526,7 +534,7 @@ class Dimension(gui_base_original.Creator):
|
||||
self.dimtrack.on()
|
||||
elif len(self.node) == 3:
|
||||
self.createObject()
|
||||
if not self.cont:
|
||||
if not self.chain:
|
||||
self.finish()
|
||||
|
||||
def set_constraint_node(self):
|
||||
|
||||
@@ -404,8 +404,8 @@ def _get_param_dictionary():
|
||||
param_dict["Mod/Draft"] = {
|
||||
"AnnotationStyleEditorHeight": ("int", 450),
|
||||
"AnnotationStyleEditorWidth": ("int", 450),
|
||||
"ChainedMode": ("bool", False),
|
||||
"CenterPlaneOnView": ("bool", False),
|
||||
"ContinueMode": ("bool", False),
|
||||
"CopyMode": ("bool", False),
|
||||
"DefaultAnnoDisplayMode": ("int", 0),
|
||||
"DefaultDisplayMode": ("int", 0),
|
||||
@@ -443,6 +443,35 @@ def _get_param_dictionary():
|
||||
"useSupport": ("bool", False),
|
||||
}
|
||||
|
||||
param_dict["Mod/Draft/ContinueMode"] = {
|
||||
# Draft
|
||||
"Line": ("bool", False),
|
||||
"Polyline": ("bool", False),
|
||||
"Arc": ("bool", False),
|
||||
"Arc_3Points": ("bool", False),
|
||||
"Circle": ("bool", False),
|
||||
"Ellipse": ("bool", False),
|
||||
"Rectangle": ("bool", False),
|
||||
"Polygon": ("bool", False),
|
||||
"Bspline": ("bool", False),
|
||||
"CubicBezCurve": ("bool", False),
|
||||
"BezCurve": ("bool", False),
|
||||
"Point": ("bool", False),
|
||||
"Text": ("bool", False),
|
||||
"Dimension": ("bool", False),
|
||||
|
||||
# Standard operations (Draft)
|
||||
"Move": ("bool", False),
|
||||
"Copy": ("bool", False),
|
||||
"Rotate": ("bool", False),
|
||||
|
||||
# Arch/BIM
|
||||
"Wall": ("bool", False),
|
||||
"Column": ("bool", False),
|
||||
"Beam": ("bool", False),
|
||||
"Panel": ("bool", False),
|
||||
}
|
||||
|
||||
# Arch parameters that are not in the preferences:
|
||||
param_dict["Mod/Arch"] = {
|
||||
"applyConstructionStyle": ("bool", True),
|
||||
@@ -634,7 +663,7 @@ def _get_param_dictionary():
|
||||
PARAM_DICT = _get_param_dictionary()
|
||||
|
||||
|
||||
def get_param(entry, path="Mod/Draft", ret_default=False):
|
||||
def get_param(entry, path="Mod/Draft", ret_default=False, silent=False):
|
||||
"""Return a stored parameter value or its default.
|
||||
|
||||
Parameters
|
||||
@@ -648,13 +677,17 @@ def get_param(entry, path="Mod/Draft", ret_default=False):
|
||||
ret_default: bool, optional
|
||||
Defaults to `False`.
|
||||
If `True`, always return the default value even if a stored value is available.
|
||||
silent: bool, optional
|
||||
Defaults to `False`.
|
||||
If `True`, do not log anything if entry wasn't found.
|
||||
|
||||
Returns
|
||||
-------
|
||||
bool, float, int or str (if successful) or `None`.
|
||||
"""
|
||||
if path not in PARAM_DICT or entry not in PARAM_DICT[path]:
|
||||
print(f"draftutils.params.get_param: Unable to find '{entry}' in '{path}'")
|
||||
if not silent:
|
||||
print(f"draftutils.params.get_param: Unable to find '{entry}' in '{path}'")
|
||||
return None
|
||||
param_grp = App.ParamGet("User parameter:BaseApp/Preferences/" + path)
|
||||
typ, default = PARAM_DICT[path][entry]
|
||||
|
||||
Reference in New Issue
Block a user