CAM: Refactor LeadInOut task panel to use QuantitySpinBox and improve migration/visibility logic
- Replace QDoubleSpinBox widgets with Gui::QuantitySpinBox in DressUpLeadInOutEdit.ui for all lead-in/out numeric fields, enabling unit/expressions support. - Register QuantitySpinBox as a custom widget in the .ui file. - Refactor TaskDressupLeadInOut panel setup: - Add setupSpinBoxes, setupGroupBoxes, setupDynamicVisibility for cleaner UI initialization. - Use PathGuiUtil.QuantitySpinBox for all numeric fields and ensure updateWidget() is called for each. - Centralize signal registration and field updates using getSignalsForUpdate and pageGetFields. - Move group box signal handler to a class method. - Share hideModes dictionary for field visibility logic. - Add dynamic label switching for "Radius"/"Length" with translation placeholders. - Remove the Include layers Check Box - Improve ObjectDressup migration: - Use shared hideModes from TaskDressupLeadInOut. - Set default angles to 90 instead of 45. - Preserve previous style values when migrating StyleOn/StyleOff. - Ensure field visibility is updated after migration. - Add Perpendicular and Tangent to lead_styles in correct order.
This commit is contained in:
committed by
Chris Hennes
parent
d92c8fbfa3
commit
b1437fe189
@@ -62,20 +62,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QDoubleSpinBox" name="dspRadiusIn">
|
||||
<property name="toolTip">
|
||||
<string>Length of the Lead-in</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>0.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>999999.000000000000000</double>
|
||||
</property>
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="Gui::QuantitySpinBox" name="dspRadiusIn"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_1">
|
||||
@@ -85,20 +72,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QDoubleSpinBox" name="dspAngleIn">
|
||||
<property name="toolTip">
|
||||
<string>Angular extent of the lead in arc (degrees)</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>180.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>10.000000000000000</double>
|
||||
</property>
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="Gui::QuantitySpinBox" name="dspAngleIn"/>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
@@ -108,17 +82,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QDoubleSpinBox" name="dspOffsetIn">
|
||||
<property name="minimum">
|
||||
<double>-999999.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>999999.000000000000000</double>
|
||||
</property>
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="Gui::QuantitySpinBox" name="dspOffsetIn"/>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QCheckBox" name="chkInvertDirectionIn">
|
||||
@@ -174,20 +138,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QDoubleSpinBox" name="dspRadiusOut">
|
||||
<property name="toolTip">
|
||||
<string>Length of the Lead-out</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>0.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>999999.000000000000000</double>
|
||||
</property>
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="Gui::QuantitySpinBox" name="dspRadiusOut"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_11">
|
||||
@@ -197,20 +148,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QDoubleSpinBox" name="dspAngleOut">
|
||||
<property name="toolTip">
|
||||
<string>Angular extent of the lead out arc (degrees)</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>180.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>10.000000000000000</double>
|
||||
</property>
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="Gui::QuantitySpinBox" name="dspAngleOut"/>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_17">
|
||||
@@ -220,17 +158,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QDoubleSpinBox" name="dspOffsetOut">
|
||||
<property name="minimum">
|
||||
<double>-999999.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>999999.000000000000000</double>
|
||||
</property>
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="Gui::QuantitySpinBox" name="dspOffsetOut"/>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QCheckBox" name="chkInvertDirectionOut">
|
||||
@@ -262,16 +190,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="chkLayers">
|
||||
<property name="toolTip">
|
||||
<string>Apply lead-in/out on all layers</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Include layers</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
@@ -280,10 +198,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QDoubleSpinBox" name="dspRetractThreshold">
|
||||
<property name="maximum">
|
||||
<double>999999.000000000000000</double>
|
||||
</property>
|
||||
<widget class="Gui::QuantitySpinBox" name="dspRetractThreshold">
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
@@ -308,4 +223,11 @@
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>Gui::QuantitySpinBox</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>Gui/QuantitySpinBox.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
</ui>
|
||||
|
||||
@@ -27,6 +27,7 @@ import Path
|
||||
import Path.Base.Language as PathLanguage
|
||||
import Path.Dressup.Utils as PathDressup
|
||||
import PathScripts.PathUtils as PathUtils
|
||||
import Path.Base.Gui.Util as PathGuiUtil
|
||||
from Path.Base.Util import toolControllerForOp
|
||||
import copy
|
||||
import math
|
||||
@@ -49,6 +50,8 @@ lead_styles = (
|
||||
# common options first
|
||||
QT_TRANSLATE_NOOP("CAM_DressupLeadInOut", "Arc"),
|
||||
QT_TRANSLATE_NOOP("CAM_DressupLeadInOut", "Line"),
|
||||
QT_TRANSLATE_NOOP("CAM_DressupLeadInOut", "Perpendicular"),
|
||||
QT_TRANSLATE_NOOP("CAM_DressupLeadInOut", "Tangent"),
|
||||
# additional options, alphabetical order
|
||||
QT_TRANSLATE_NOOP("CAM_DressupLeadInOut", "Arc3d"),
|
||||
QT_TRANSLATE_NOOP("CAM_DressupLeadInOut", "ArcZ"),
|
||||
@@ -56,8 +59,6 @@ lead_styles = (
|
||||
QT_TRANSLATE_NOOP("CAM_DressupLeadInOut", "Line3d"),
|
||||
QT_TRANSLATE_NOOP("CAM_DressupLeadInOut", "LineZ"),
|
||||
QT_TRANSLATE_NOOP("CAM_DressupLeadInOut", "No Retract"),
|
||||
QT_TRANSLATE_NOOP("CAM_DressupLeadInOut", "Perpendicular"),
|
||||
QT_TRANSLATE_NOOP("CAM_DressupLeadInOut", "Tangent"),
|
||||
QT_TRANSLATE_NOOP("CAM_DressupLeadInOut", "Vertical"),
|
||||
)
|
||||
|
||||
@@ -170,8 +171,8 @@ class ObjectDressup:
|
||||
def setup(self, obj):
|
||||
obj.LeadIn = True
|
||||
obj.LeadOut = True
|
||||
obj.AngleIn = 45
|
||||
obj.AngleOut = 45
|
||||
obj.AngleIn = 90
|
||||
obj.AngleOut = 90
|
||||
obj.InvertIn = False
|
||||
obj.InvertOut = False
|
||||
obj.RapidPlunge = False
|
||||
@@ -227,13 +228,8 @@ class ObjectDressup:
|
||||
if obj.AngleOut < limit_angle_out:
|
||||
obj.AngleOut = limit_angle_out
|
||||
|
||||
hideModes = {
|
||||
"Angle": ("No Retract", "Perpendicular", "Tangent", "Vertical"),
|
||||
"Invert": ("No Retract", "ArcZ", "LineZ", "Vertical"),
|
||||
"Offset": ("No Retract"),
|
||||
"Radius": ("No Retract", "Vertical"),
|
||||
}
|
||||
for k, v in hideModes.items():
|
||||
# Use shared hideModes from TaskDressupLeadInOut
|
||||
for k, v in TaskDressupLeadInOut.hideModes.items():
|
||||
obj.setEditorMode(k + "In", 2 if obj.StyleIn in v else 0)
|
||||
obj.setEditorMode(k + "Out", 2 if obj.StyleOut in v else 0)
|
||||
|
||||
@@ -268,7 +264,12 @@ class ObjectDressup:
|
||||
)
|
||||
obj.StyleIn = lead_styles
|
||||
obj.removeProperty("StyleOn")
|
||||
obj.StyleIn = "Arc"
|
||||
# Set previous value if possible
|
||||
if styleOn in lead_styles:
|
||||
obj.StyleIn = styleOn
|
||||
elif styleOn == "Arc":
|
||||
obj.StyleIn = "Arc"
|
||||
obj.AngleIn = 90
|
||||
if hasattr(obj, "StyleOff"):
|
||||
# Replace StyleOff by StyleOut
|
||||
styleOff = obj.StyleOff
|
||||
@@ -280,7 +281,12 @@ class ObjectDressup:
|
||||
)
|
||||
obj.StyleOut = lead_styles
|
||||
obj.removeProperty("StyleOff")
|
||||
obj.StyleOut = "Arc"
|
||||
# Set previous value if possible
|
||||
if styleOff in lead_styles:
|
||||
obj.StyleOut = styleOff
|
||||
elif styleOff == "Arc":
|
||||
obj.StyleOut = "Arc"
|
||||
obj.AngleOut = 90
|
||||
|
||||
if not hasattr(obj, "AngleIn"):
|
||||
obj.addProperty(
|
||||
@@ -289,7 +295,7 @@ class ObjectDressup:
|
||||
"Path Lead-in",
|
||||
QT_TRANSLATE_NOOP("App::Property", "Angle of the Lead-In (1..90)"),
|
||||
)
|
||||
obj.AngleIn = 45
|
||||
obj.AngleIn = 90
|
||||
if not hasattr(obj, "AngleOut"):
|
||||
obj.addProperty(
|
||||
"App::PropertyAngle",
|
||||
@@ -297,7 +303,7 @@ class ObjectDressup:
|
||||
"Path Lead-out",
|
||||
QT_TRANSLATE_NOOP("App::Property", "Angle of the Lead-Out (1..90)"),
|
||||
)
|
||||
obj.AngleOut = 45
|
||||
obj.AngleOut = 90
|
||||
|
||||
if styleOn:
|
||||
if styleOn == "Arc":
|
||||
@@ -402,6 +408,11 @@ class ObjectDressup:
|
||||
obj.RetractThreshold = 999999
|
||||
obj.removeProperty("KeepToolDown")
|
||||
|
||||
# Ensure correct initial visibility of fields after defaults are set
|
||||
for k, v in TaskDressupLeadInOut.hideModes.items():
|
||||
obj.setEditorMode(k + "In", 2 if obj.StyleIn in v else 0)
|
||||
obj.setEditorMode(k + "Out", 2 if obj.StyleOut in v else 0)
|
||||
|
||||
# Get direction for lead-in/lead-out in XY plane
|
||||
def getLeadDir(self, obj, invert=False):
|
||||
output = math.pi / 2
|
||||
@@ -587,7 +598,6 @@ class ObjectDressup:
|
||||
return commands
|
||||
|
||||
def getLeadStart(self, obj, move, first, inInstrPrev, outInstrPrev):
|
||||
|
||||
# tangent begin move
|
||||
# <----_-----x-------------------x
|
||||
# / |
|
||||
@@ -734,7 +744,6 @@ class ObjectDressup:
|
||||
return lead
|
||||
|
||||
def getLeadEnd(self, obj, move, last, outInstrPrev):
|
||||
|
||||
# move end tangent
|
||||
# x-------------------x-----_---->
|
||||
# | \
|
||||
@@ -1052,7 +1061,6 @@ class ObjectDressup:
|
||||
|
||||
# Process all instructions
|
||||
for i, instr in enumerate(source):
|
||||
|
||||
# Process not mill instruction
|
||||
if not self.isCuttingMove(instr):
|
||||
if not instr.isMove():
|
||||
@@ -1165,28 +1173,123 @@ class TaskDressupLeadInOut(SimpleEditPanel):
|
||||
_ui_file = ":/panels/DressUpLeadInOutEdit.ui"
|
||||
|
||||
def setupUi(self):
|
||||
self.setupSpinBoxes()
|
||||
self.setupGroupBoxes()
|
||||
self.setupDynamicVisibility()
|
||||
self.setFields()
|
||||
self.pageRegisterSignalHandlers()
|
||||
|
||||
def setupSpinBoxes(self):
|
||||
self.connectWidget("InvertIn", self.form.chkInvertDirectionIn)
|
||||
self.connectWidget("InvertOut", self.form.chkInvertDirectionOut)
|
||||
self.connectWidget("RadiusIn", self.form.dspRadiusIn)
|
||||
self.connectWidget("RadiusOut", self.form.dspRadiusOut)
|
||||
self.connectWidget("StyleIn", self.form.cboStyleIn)
|
||||
self.connectWidget("StyleOut", self.form.cboStyleOut)
|
||||
self.connectWidget("AngleIn", self.form.dspAngleIn)
|
||||
self.connectWidget("AngleOut", self.form.dspAngleOut)
|
||||
self.connectWidget("OffsetIn", self.form.dspOffsetIn)
|
||||
self.connectWidget("OffsetOut", self.form.dspOffsetOut)
|
||||
self.radiusIn = PathGuiUtil.QuantitySpinBox(self.form.dspRadiusIn, self.obj, "RadiusIn")
|
||||
self.radiusOut = PathGuiUtil.QuantitySpinBox(self.form.dspRadiusOut, self.obj, "RadiusOut")
|
||||
self.angleIn = PathGuiUtil.QuantitySpinBox(self.form.dspAngleIn, self.obj, "AngleIn")
|
||||
self.angleOut = PathGuiUtil.QuantitySpinBox(self.form.dspAngleOut, self.obj, "AngleOut")
|
||||
self.offsetIn = PathGuiUtil.QuantitySpinBox(self.form.dspOffsetIn, self.obj, "OffsetIn")
|
||||
self.offsetOut = PathGuiUtil.QuantitySpinBox(self.form.dspOffsetOut, self.obj, "OffsetOut")
|
||||
self.connectWidget("RapidPlunge", self.form.chkRapidPlunge)
|
||||
self.connectWidget("RetractThreshold", self.form.dspRetractThreshold)
|
||||
self.setFields()
|
||||
self.retractThreshold = PathGuiUtil.QuantitySpinBox(
|
||||
self.form.dspRetractThreshold, self.obj, "RetractThreshold"
|
||||
)
|
||||
|
||||
def handleGroupBoxCheck():
|
||||
self.obj.LeadIn = self.form.groupBoxIn.isChecked()
|
||||
self.obj.LeadOut = self.form.groupBoxOut.isChecked()
|
||||
self.radiusIn.updateWidget()
|
||||
self.radiusOut.updateWidget()
|
||||
self.angleIn.updateWidget()
|
||||
self.angleOut.updateWidget()
|
||||
self.offsetIn.updateWidget()
|
||||
self.offsetOut.updateWidget()
|
||||
self.retractThreshold.updateWidget()
|
||||
|
||||
def setupGroupBoxes(self):
|
||||
self.form.groupBoxIn.setChecked(self.obj.LeadIn)
|
||||
self.form.groupBoxOut.setChecked(self.obj.LeadOut)
|
||||
self.form.groupBoxIn.clicked.connect(handleGroupBoxCheck)
|
||||
self.form.groupBoxOut.clicked.connect(handleGroupBoxCheck)
|
||||
self.form.groupBoxIn.clicked.connect(self.handleGroupBoxCheck)
|
||||
self.form.groupBoxOut.clicked.connect(self.handleGroupBoxCheck)
|
||||
|
||||
def handleGroupBoxCheck(self):
|
||||
self.obj.LeadIn = self.form.groupBoxIn.isChecked()
|
||||
self.obj.LeadOut = self.form.groupBoxOut.isChecked()
|
||||
|
||||
def setupDynamicVisibility(self):
|
||||
self.form.cboStyleIn.currentIndexChanged.connect(self.updateLeadInVisibility)
|
||||
self.form.cboStyleOut.currentIndexChanged.connect(self.updateLeadOutVisibility)
|
||||
self.updateLeadInVisibility()
|
||||
self.updateLeadOutVisibility()
|
||||
|
||||
def getSignalsForUpdate(self):
|
||||
signals = []
|
||||
signals.append(self.form.dspRadiusIn.editingFinished)
|
||||
signals.append(self.form.dspRadiusOut.editingFinished)
|
||||
signals.append(self.form.dspAngleIn.editingFinished)
|
||||
signals.append(self.form.dspAngleOut.editingFinished)
|
||||
signals.append(self.form.dspOffsetIn.editingFinished)
|
||||
signals.append(self.form.dspOffsetOut.editingFinished)
|
||||
signals.append(self.form.dspRetractThreshold.editingFinished)
|
||||
return signals
|
||||
|
||||
def pageGetFields(self):
|
||||
PathGuiUtil.updateInputField(self.obj, "RadiusIn", self.form.dspRadiusIn)
|
||||
PathGuiUtil.updateInputField(self.obj, "RadiusOut", self.form.dspRadiusOut)
|
||||
PathGuiUtil.updateInputField(self.obj, "AngleIn", self.form.dspAngleIn)
|
||||
PathGuiUtil.updateInputField(self.obj, "AngleOut", self.form.dspAngleOut)
|
||||
PathGuiUtil.updateInputField(self.obj, "OffsetIn", self.form.dspOffsetIn)
|
||||
PathGuiUtil.updateInputField(self.obj, "OffsetOut", self.form.dspOffsetOut)
|
||||
PathGuiUtil.updateInputField(self.obj, "RetractThreshold", self.form.dspRetractThreshold)
|
||||
|
||||
def pageRegisterSignalHandlers(self):
|
||||
for signal in self.getSignalsForUpdate():
|
||||
signal.connect(self.pageGetFields)
|
||||
|
||||
# Shared hideModes for both LeadIn and LeadOut
|
||||
hideModes = {
|
||||
"Angle": ("No Retract", "Perpendicular", "Tangent", "Vertical"),
|
||||
"Invert": ("No Retract", "ArcZ", "LineZ", "Vertical", "Perpendicular", "Tangent"),
|
||||
"Offset": ("No Retract"),
|
||||
"Radius": ("No Retract", "Vertical"),
|
||||
}
|
||||
|
||||
def updateLeadVisibility(self, style, angleWidget, invertWidget, angleLabel, radiusLabel=None):
|
||||
# Dynamic label for Radius/Length
|
||||
arc_styles = ("Arc", "Arc3d", "ArcZ", "Helix")
|
||||
if radiusLabel and hasattr(self.form, radiusLabel):
|
||||
if style in arc_styles:
|
||||
getattr(self.form, radiusLabel).setText("Radius")
|
||||
# Will do translation later
|
||||
# getattr(self.form, radiusLabel).setText(translate("CAM_DressupLeadInOut", "Radius"))
|
||||
else:
|
||||
getattr(self.form, radiusLabel).setText("Length")
|
||||
# Will do translation later
|
||||
# getattr(self.form, radiusLabel).setText(translate("CAM_DressupLeadInOut", "Length"))
|
||||
|
||||
# Angle
|
||||
if style in self.hideModes["Angle"]:
|
||||
angleWidget.hide()
|
||||
if hasattr(self.form, angleLabel):
|
||||
getattr(self.form, angleLabel).hide()
|
||||
else:
|
||||
angleWidget.show()
|
||||
if hasattr(self.form, angleLabel):
|
||||
getattr(self.form, angleLabel).show()
|
||||
# Invert Direction
|
||||
if style in self.hideModes["Invert"]:
|
||||
invertWidget.hide()
|
||||
else:
|
||||
invertWidget.show()
|
||||
|
||||
def updateLeadInVisibility(self):
|
||||
style = self.form.cboStyleIn.currentText()
|
||||
self.updateLeadVisibility(
|
||||
style, self.form.dspAngleIn, self.form.chkInvertDirectionIn, "label_1", "label_5"
|
||||
)
|
||||
|
||||
def updateLeadOutVisibility(self):
|
||||
style = self.form.cboStyleOut.currentText()
|
||||
self.updateLeadVisibility(
|
||||
style, self.form.dspAngleOut, self.form.chkInvertDirectionOut, "label_11", "label_15"
|
||||
)
|
||||
|
||||
|
||||
class ViewProviderDressup:
|
||||
|
||||
Reference in New Issue
Block a user