Added buttons to use Z level of current selection for start or final depth.

This commit is contained in:
Markus Lampert
2017-09-09 20:08:04 -07:00
committed by wmayer
parent 756ed3381e
commit ce61fac68b
3 changed files with 174 additions and 61 deletions

View File

@@ -6,70 +6,105 @@
<rect>
<x>0</x>
<y>0</y>
<width>394</width>
<height>219</height>
<width>270</width>
<height>235</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QFormLayout" name="formLayout">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="Gui::InputField" name="startDepth">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Start Depth of the operation. The highest point in Z-axis the operation needs to process.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="startDepthLabel">
<property name="text">
<string>Start Depth</string>
</property>
</widget>
</item>
<item row="1" column="0">
<item row="1" column="1">
<widget class="Gui::InputField" name="finalDepth">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The depth of the operation which corresponds to the lowest value in Z-axis the operation needs to process.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="finalDepthLabel">
<property name="text">
<string>Final Depth</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="Gui::InputField" name="stepDown">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The depth in Z-axis the operation moves downwards between layers.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This value depends on the tool being used, the material to be cut, available cooling and many other factors. Please consult the tool manufacturers data sheets for the proper value.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="stepDownLabel">
<property name="text">
<string>Step Down</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="Gui::InputField" name="finishDepth">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Depth of the final cut of the operation. Can be used to produce a cleaner finish.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="finishDepthLabel">
<property name="text">
<string>Finish Depth</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="Gui::InputField" name="finishDepth">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Depth of the final cut of the operation. Can be used to produce a cleaner finish.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<item row="3" column="0">
<widget class="QLabel" name="stepDownLabel">
<property name="text">
<string>Step Down</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="finalDepthLabel">
<property name="text">
<string>Final Depth</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="Gui::InputField" name="stepDown">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The depth in Z-axis the operation moves downwards between layers.&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;This value depends on the tool being used, the material to be cut, available cooling and many other factors. Please consult the tool manufacturers data sheets for the proper value.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="Gui::InputField" name="startDepth">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Start Depth of the operation. The highest point in Z-axis the operation needs to process.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QToolButton" name="startDepthSet">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../../../../Gui/Icons/resource.qrc">
<normaloff>:/icons/button_left.svg</normaloff>:/icons/button_left.svg</iconset>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QToolButton" name="finalDepthSet">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../../../../Gui/Icons/resource.qrc">
<normaloff>:/icons/button_left.svg</normaloff>:/icons/button_left.svg</iconset>
</property>
</widget>
</item>
<item row="4" column="0" colspan="3">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<customwidgets>
@@ -85,6 +120,8 @@
<tabstop>finishDepth</tabstop>
<tabstop>stepDown</tabstop>
</tabstops>
<resources/>
<resources>
<include location="../../../../../Gui/Icons/resource.qrc"/>
</resources>
<connections/>
</ui>

View File

@@ -6,22 +6,29 @@
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>447</height>
<width>282</width>
<height>242</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QFormLayout" name="formLayout_4">
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="1">
<widget class="Gui::InputField" name="clearanceHeight">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The height where lateral movement of the toolbit is not obstructed by any fixtures or the part / stock material itself.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="Gui::InputField" name="safeHeight">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The height above which it is safe to move the tool bit with rapid movements. Below this height all lateral and downward movements are performed with feed rate speeds.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item row="0" column="1">
<item row="0" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Safe Height</string>
@@ -29,19 +36,25 @@
</widget>
</item>
<item row="1" column="0">
<widget class="Gui::InputField" name="clearanceHeight">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The height where lateral movement of the toolbit is not obstructed by any fixtures or the part / stock material itself.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Clearance Height</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<customwidgets>

View File

@@ -24,13 +24,15 @@
import FreeCAD
import FreeCADGui
import PathScripts.PathGeom as PathGeom
import PathScripts.PathGetPoint as PathGetPoint
import PathScripts.PathLog as PathLog
import PathScripts.PathSelection as PathSelection
import PathScripts.PathOp as PathOp
import PathScripts.PathUtils as PathUtils
import importlib
from PathScripts import PathUtils
from PathScripts.PathGeom import PathGeom
from PySide import QtCore, QtGui
__title__ = "Path Operation UI base classes"
@@ -106,6 +108,10 @@ class ViewProvider(object):
'''clearTaskPanel() ... internal callback function when editing has finished.'''
self.panel = None
def unsetEdit(self, arg1, arg2):
if self.panel:
self.panel.reject(False)
def __getstate__(self):
'''__getstate__() ... callback before receiver is saved to a file.
Returns a dictionary with the receiver's resources as strings.'''
@@ -244,6 +250,10 @@ class TaskPanelPage(object):
In such a scenario the first property assignment will cause all changes in the UI of the other fields to be overwritten by setFields(obj).
You have been warned.'''
pass
def updateSelection(self, obj, sel):
'''updateSelection(obj, sel) ... overwrite to customize UI depending on current selection.
Can safely be overwritten by subclasses.'''
pass
# helpers
def selectInComboBox(self, name, combo):
@@ -557,6 +567,7 @@ class TaskPanelDepthsPage(TaskPanelPage):
self.form.stepDown.setText(FreeCAD.Units.Quantity(obj.StepDown.Value, FreeCAD.Units.Length).UserString)
if PathOp.FeatureFinishDepth & self.features:
self.form.finishDepth.setText(FreeCAD.Units.Quantity(obj.FinishDepth.Value, FreeCAD.Units.Length).UserString)
self.updateSelection(obj, FreeCADGui.Selection.getSelectionEx())
def getSignalsForUpdate(self, obj):
signals = []
signals.append(self.form.startDepth.editingFinished)
@@ -566,10 +577,40 @@ class TaskPanelDepthsPage(TaskPanelPage):
if PathOp.FeatureFinishDepth & self.features:
signals.append(self.form.finishDepth.editingFinished)
return signals
def registerSignalHandlers(self, obj):
self.form.startDepthSet.clicked.connect(lambda: self.depthSet(obj, self.form.startDepth))
self.form.finalDepthSet.clicked.connect(lambda: self.depthSet(obj, self.form.finalDepth))
def pageUpdateData(self, obj, prop):
if prop in ['StartDepth', 'FinalDepth', 'StepDown', 'FinishDepth']:
self.setFields(obj)
def depthSet(self, obj, widget):
z = self.selectionZLevel(FreeCADGui.Selection.getSelectionEx())
if z is not None:
PathLog.info("depthSet(%.2f)" % z)
widget.setText(FreeCAD.Units.Quantity(z, FreeCAD.Units.Length).UserString)
self.getFields(obj)
else:
PathLog.info("depthSet(-)")
def selectionZLevel(self, sel):
if len(sel) == 1 and len(sel[0].SubObjects) == 1:
sub = sel[0].SubObjects[0]
if 'Vertex' == sub.ShapeType:
return sub.Z
if 'Edge' == sub.ShapeType and PathGeom.isRoughly(sub.Vertexes[0].Z, sub.Vertexes[1].Z):
return sub.Vertexes[0].Z
if 'Face' == sub.ShapeType and PathGeom.isRoughly(sub.BoundBox.ZLength, 0):
return sub.BoundBox.ZMax
return None
def updateSelection(self, obj, sel):
if self.selectionZLevel(sel) is not None:
self.form.startDepthSet.setEnabled(True)
self.form.finalDepthSet.setEnabled(True)
else:
self.form.startDepthSet.setEnabled(False)
self.form.finalDepthSet.setEnabled(False)
class TaskPanel(object):
'''
Generic TaskPanel implementation handling the standard Path operation layout.
@@ -658,30 +699,36 @@ class TaskPanel(object):
for page in self.featurePages:
page.setClean()
def accept(self):
def accept(self, resetEdit=True):
'''accept() ... callback invoked when user presses the task panel OK button.'''
FreeCAD.ActiveDocument.commitTransaction()
self.cleanup()
self.preCleanup()
if self.isDirty:
self.panelGetFields()
FreeCAD.ActiveDocument.recompute()
FreeCAD.ActiveDocument.commitTransaction()
self.cleanup(resetEdit)
def reject(self):
def reject(self, resetEdit=True):
'''reject() ... callback invoked when user presses the task panel Cancel button.'''
self.preCleanup()
FreeCAD.ActiveDocument.abortTransaction()
self.cleanup()
if self.deleteOnReject:
FreeCAD.ActiveDocument.openTransaction(translate("Path", "Uncreate AreaOp Operation"))
FreeCAD.ActiveDocument.removeObject(self.obj.Name)
FreeCAD.ActiveDocument.commitTransaction()
FreeCAD.ActiveDocument.recompute()
self.cleanup(resetEdit)
return True
def cleanup(self):
def preCleanup(self):
FreeCADGui.Selection.removeObserver(self)
FreeCADGui.Selection.removeObserver(self.s)
def cleanup(self, resetEdit):
'''cleanup() ... implements common cleanup tasks.'''
self.obj.ViewObject.Proxy.clearTaskPanel()
FreeCADGui.Control.closeDialog()
FreeCADGui.ActiveDocument.resetEdit()
FreeCADGui.Selection.removeObserver(self.s)
if resetEdit:
FreeCADGui.ActiveDocument.resetEdit()
FreeCAD.ActiveDocument.recompute()
def clicked(self, button):
'''clicked(button) ... callback invoked when the user presses any of the task panel buttons.'''
@@ -710,8 +757,8 @@ class TaskPanel(object):
def open(self):
'''open() ... callback invoked when the task panel is opened.'''
self.s = SelObserver(self.selectionFactory)
# install the function mode resident
FreeCADGui.Selection.addObserver(self.s)
FreeCADGui.Selection.addObserver(self)
def getStandardButtons(self):
'''getStandardButtons() ... returns the Buttons for the task panel.'''
@@ -741,6 +788,22 @@ class TaskPanel(object):
def needsFullSpace(self):
return True
def updateSelection(self):
sel = FreeCADGui.Selection.getSelectionEx()
for page in self.featurePages:
page.updateSelection(self.obj, sel)
# SelectionObserver interface
def addSelection(self, doc, obj, sub, pnt):
self.updateSelection()
def removeSelection(self, doc, obj, sub):
self.updateSelection()
def setSelection(self, doc):
self.updateSelection()
def clearSelection(self, doc):
self.updateSelection()
class SelObserver:
'''Implementation of the selection observer used by the task panel.
Its specific behaviour is determined by the factory function.'''