- fixed the FCSpinner and FCDoubleSpinner GUI elements to select all on first click and deselect on second click in the Spinbox LineEdit

- for Gerber object in Selected Tab added ability to chose a V-Shape tool and therefore control the isolation better by adjusting the cut width of the isolation in function of the cut depth, tip width of the tool and the tip angle of the tool
This commit is contained in:
Marius Stanciu 2019-10-01 01:38:18 +03:00 committed by Marius
parent 225634aea2
commit e0e2aabf99
4 changed files with 234 additions and 98 deletions

View File

@ -616,10 +616,23 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
self.ui.obj_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
self.ui.obj_combo.setCurrentIndex(1)
self.ui.type_obj_combo.currentIndexChanged.connect(self.on_type_obj_index_changed)
self.ui.tool_type_radio.activated_custom.connect(self.on_tool_type_change)
self.ui.tool_type_radio.set_value('circular')
# Show/Hide Advanced Options
if self.app.defaults["global_app_level"] == 'b':
self.ui.level.setText('<span style="color:green;"><b>%s</b></span>' % _('Basic'))
self.ui.tool_type_label.hide()
self.ui.tool_type_radio.hide()
self.ui.tipdialabel.hide()
self.ui.tipdia_spinner.hide()
self.ui.tipanglelabel.hide()
self.ui.tipangle_spinner.hide()
self.ui.cutzlabel.hide()
self.ui.cutz_spinner.hide()
self.ui.apertures_table_label.hide()
self.ui.aperture_table_visibility_cb.hide()
self.ui.milling_type_label.hide()
@ -631,6 +644,9 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
self.ui.except_cb.hide()
else:
self.ui.level.setText('<span style="color:red;"><b>%s</b></span>' % _('Advanced'))
self.ui.tipdia_spinner.valueChanged.connect(self.on_calculate_tooldia)
self.ui.tipangle_spinner.valueChanged.connect(self.on_calculate_tooldia)
self.ui.cutz_spinner.valueChanged.connect(self.on_calculate_tooldia)
if self.app.defaults["gerber_buffering"] == 'no':
self.ui.create_buffer_button.show()
@ -647,11 +663,52 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
self.build_ui()
def on_calculate_tooldia(self):
try:
tdia = float(self.ui.tipdia_spinner.get_value())
except Exception as e:
return
try:
dang = float(self.ui.tipangle_spinner.get_value())
except Exception as e:
return
try:
cutz = float(self.ui.cutz_spinner.get_value())
except Exception as e:
return
cutz *= -1
if cutz < 0:
cutz *= -1
half_tip_angle = dang / 2
tool_diameter = tdia + (2 * cutz * math.tan(math.radians(half_tip_angle)))
self.ui.iso_tool_dia_entry.set_value(tool_diameter)
def on_type_obj_index_changed(self, index):
obj_type = self.ui.type_obj_combo.currentIndex()
self.ui.obj_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex()))
self.ui.obj_combo.setCurrentIndex(0)
def on_tool_type_change(self, state):
if state == 'circular':
self.ui.tipdialabel.hide()
self.ui.tipdia_spinner.hide()
self.ui.tipanglelabel.hide()
self.ui.tipangle_spinner.hide()
self.ui.cutzlabel.hide()
self.ui.cutz_spinner.hide()
self.ui.iso_tool_dia_entry.setDisabled(False)
else:
self.ui.tipdialabel.show()
self.ui.tipdia_spinner.show()
self.ui.tipanglelabel.show()
self.ui.tipangle_spinner.show()
self.ui.cutzlabel.show()
self.ui.cutz_spinner.show()
self.ui.iso_tool_dia_entry.setDisabled(True)
def build_ui(self):
FlatCAMObj.build_ui(self)

View File

@ -10,6 +10,11 @@ CAD program, and create G-Code for Isolation routing.
=================================================
1.10.2019
- fixed the FCSpinner and FCDoubleSpinner GUI elements to select all on first click and deselect on second click in the Spinbox LineEdit
- for Gerber object in Selected Tab added ability to chose a V-Shape tool and therefore control the isolation better by adjusting the cut width of the isolation in function of the cut depth, tip width of the tool and the tip angle of the tool
30.09.2019
- modified the Distance Tool such that the number of decimals all over the tool is set in one place by the self.decimals

View File

@ -507,6 +507,109 @@ class EvalEntry2(QtWidgets.QLineEdit):
return QtCore.QSize(EDIT_SIZE_HINT, default_hint_size.height())
class FCSpinner(QtWidgets.QSpinBox):
def __init__(self, parent=None):
super(FCSpinner, self).__init__(parent)
self.readyToEdit = True
self.editingFinished.connect(self.on_edit_finished)
self.lineEdit().installEventFilter(self)
def eventFilter(self, object, event):
if event.type() == QtCore.QEvent.MouseButtonPress:
if self.readyToEdit:
self.lineEdit().selectAll()
self.readyToEdit = False
else:
self.lineEdit().deselect()
return True
return False
def on_edit_finished(self):
self.clearFocus()
# def mousePressEvent(self, e, parent=None):
# super(FCSpinner, self).mousePressEvent(e) # required to deselect on 2e click
# if self.readyToEdit:
# self.lineEdit().selectAll()
# self.readyToEdit = False
def focusOutEvent(self, e):
# don't focus out if the user requests an popup menu
if e.reason() != QtCore.Qt.PopupFocusReason:
super(FCSpinner, self).focusOutEvent(e) # required to remove cursor on focusOut
self.lineEdit().deselect()
self.readyToEdit = True
def get_value(self):
return str(self.value())
def set_value(self, val):
try:
k = int(val)
except Exception as e:
log.debug(str(e))
return
self.setValue(k)
def set_range(self, min_val, max_val):
self.setRange(min_val, max_val)
# def sizeHint(self):
# default_hint_size = super(FCSpinner, self).sizeHint()
# return QtCore.QSize(EDIT_SIZE_HINT, default_hint_size.height())
class FCDoubleSpinner(QtWidgets.QDoubleSpinBox):
def __init__(self, parent=None):
super(FCDoubleSpinner, self).__init__(parent)
self.readyToEdit = True
self.editingFinished.connect(self.on_edit_finished)
self.lineEdit().installEventFilter(self)
def eventFilter(self, object, event):
if event.type() == QtCore.QEvent.MouseButtonPress:
if self.readyToEdit:
self.lineEdit().selectAll()
self.readyToEdit = False
else:
self.lineEdit().deselect()
return True
return False
def on_edit_finished(self):
self.clearFocus()
# def mousePressEvent(self, e, parent=None):
# super(FCDoubleSpinner, self).mousePressEvent(e) # required to deselect on 2e click
# if self.readyToEdit:
# self.lineEdit().selectAll()
# self.readyToEdit = False
def focusOutEvent(self, e):
# don't focus out if the user requests an popup menu
if e.reason() != QtCore.Qt.PopupFocusReason:
super(FCDoubleSpinner, self).focusOutEvent(e) # required to remove cursor on focusOut
self.lineEdit().deselect()
self.readyToEdit = True
def get_value(self):
return str(self.value())
def set_value(self, val):
try:
k = float(val)
except Exception as e:
log.debug(str(e))
return
self.setValue(k)
def set_precision(self, val):
self.setDecimals(val)
def set_range(self, min_val, max_val):
self.setRange(min_val, max_val)
class FCCheckBox(QtWidgets.QCheckBox):
def __init__(self, label='', parent=None):
super(FCCheckBox, self).__init__(str(label), parent)
@ -1652,87 +1755,6 @@ class SpinBoxDelegate(QtWidgets.QItemDelegate):
spinbox.setDecimals(digits)
class FCSpinner(QtWidgets.QSpinBox):
def __init__(self, parent=None):
super(FCSpinner, self).__init__(parent)
self.readyToEdit = True
self.editingFinished.connect(self.on_edit_finished)
def on_edit_finished(self):
self.clearFocus()
def mousePressEvent(self, e, parent=None):
super(FCSpinner, self).mousePressEvent(e) # required to deselect on 2e click
if self.readyToEdit:
self.lineEdit().selectAll()
self.readyToEdit = False
def focusOutEvent(self, e):
# don't focus out if the user requests an popup menu
if e.reason() != QtCore.Qt.PopupFocusReason:
super(FCSpinner, self).focusOutEvent(e) # required to remove cursor on focusOut
self.lineEdit().deselect()
self.readyToEdit = True
def get_value(self):
return str(self.value())
def set_value(self, val):
try:
k = int(val)
except Exception as e:
log.debug(str(e))
return
self.setValue(k)
def set_range(self, min_val, max_val):
self.setRange(min_val, max_val)
# def sizeHint(self):
# default_hint_size = super(FCSpinner, self).sizeHint()
# return QtCore.QSize(EDIT_SIZE_HINT, default_hint_size.height())
class FCDoubleSpinner(QtWidgets.QDoubleSpinBox):
def __init__(self, parent=None):
super(FCDoubleSpinner, self).__init__(parent)
self.readyToEdit = True
self.editingFinished.connect(self.on_edit_finished)
def on_edit_finished(self):
self.clearFocus()
def mousePressEvent(self, e, parent=None):
super(FCDoubleSpinner, self).mousePressEvent(e) # required to deselect on 2e click
if self.readyToEdit:
self.lineEdit().selectAll()
self.readyToEdit = False
def focusOutEvent(self, e):
# don't focus out if the user requests an popup menu
if e.reason() != QtCore.Qt.PopupFocusReason:
super(FCDoubleSpinner, self).focusOutEvent(e) # required to remove cursor on focusOut
self.lineEdit().deselect()
self.readyToEdit = True
def get_value(self):
return str(self.value())
def set_value(self, val):
try:
k = float(val)
except Exception as e:
log.debug(str(e))
return
self.setValue(k)
def set_precision(self, val):
self.setDecimals(val)
def set_range(self, min_val, max_val):
self.setRange(min_val, max_val)
class Dialog_box(QtWidgets.QWidget):
def __init__(self, title=None, label=None, icon=None, initial_text=None):
"""

View File

@ -261,6 +261,58 @@ class GerberObjectUI(ObjectUI):
grid1 = QtWidgets.QGridLayout()
self.custom_box.addLayout(grid1)
# Tool Type
self.tool_type_label = QtWidgets.QLabel('<b>%s</b>' % _('Tool Type'))
self.tool_type_label.setToolTip(
_("Choose what tool to use for Gerber isolation:\n"
"'Circular' or 'V-shape'.\n"
"When the 'V-shape' is selected then the tool\n"
"diameter will depend on the chosen cut depth.")
)
self.tool_type_radio = RadioSet([{'label': 'Circular', 'value': 'circular'},
{'label': 'V-Shape', 'value': 'v'}])
grid1.addWidget(self.tool_type_label, 0, 0)
grid1.addWidget(self.tool_type_radio, 0, 1, 1, 2)
# Tip Dia
self.tipdialabel = QtWidgets.QLabel('%s:' % _('V-Tip Dia'))
self.tipdialabel.setToolTip(
_("The tip diameter for V-Shape Tool")
)
self.tipdia_spinner = FCDoubleSpinner()
self.tipdia_spinner.set_range(-99.9999, 99.9999)
self.tipdia_spinner.setSingleStep(0.1)
self.tipdia_spinner.setWrapping(True)
grid1.addWidget(self.tipdialabel, 1, 0)
grid1.addWidget(self.tipdia_spinner, 1, 1, 1, 2)
# Tip Angle
self.tipanglelabel = QtWidgets.QLabel('%s:' % _('V-Tip Angle'))
self.tipanglelabel.setToolTip(
_("The tip angle for V-Shape Tool.\n"
"In degree.")
)
self.tipangle_spinner = FCSpinner()
self.tipangle_spinner.set_range(0, 180)
self.tipangle_spinner.setSingleStep(5)
self.tipangle_spinner.setWrapping(True)
grid1.addWidget(self.tipanglelabel, 2, 0)
grid1.addWidget(self.tipangle_spinner, 2, 1, 1, 2)
# Cut Z
self.cutzlabel = QtWidgets.QLabel('%s:' % _('Cut Z'))
self.cutzlabel.setToolTip(
_("Cutting depth (negative)\n"
"below the copper surface.")
)
self.cutz_spinner = FCDoubleSpinner()
self.cutz_spinner.set_range(-99.9999, -0.0001)
self.cutz_spinner.setSingleStep(0.1)
self.cutz_spinner.setWrapping(True)
grid1.addWidget(self.cutzlabel, 3, 0)
grid1.addWidget(self.cutz_spinner, 3, 1, 1, 2)
tdlabel = QtWidgets.QLabel('%s:' % _('Tool dia'))
tdlabel.setToolTip(
_("Diameter of the cutting tool.\n"
@ -271,8 +323,8 @@ class GerberObjectUI(ObjectUI):
)
tdlabel.setMinimumWidth(90)
self.iso_tool_dia_entry = LengthEntry()
grid1.addWidget(tdlabel, 0, 0)
grid1.addWidget(self.iso_tool_dia_entry, 0, 1, 1, 2)
grid1.addWidget(tdlabel, 4, 0)
grid1.addWidget(self.iso_tool_dia_entry, 4, 1, 1, 2)
passlabel = QtWidgets.QLabel('%s:' % _('# Passes'))
passlabel.setToolTip(
@ -282,8 +334,8 @@ class GerberObjectUI(ObjectUI):
passlabel.setMinimumWidth(90)
self.iso_width_entry = FCSpinner()
self.iso_width_entry.setRange(1, 999)
grid1.addWidget(passlabel, 1, 0)
grid1.addWidget(self.iso_width_entry, 1, 1, 1, 2)
grid1.addWidget(passlabel, 5, 0)
grid1.addWidget(self.iso_width_entry, 5, 1, 1, 2)
overlabel = QtWidgets.QLabel('%s:' % _('Pass overlap'))
overlabel.setToolTip(
@ -297,8 +349,8 @@ class GerberObjectUI(ObjectUI):
self.iso_overlap_entry.setWrapping(True)
self.iso_overlap_entry.setRange(0.000, 0.999)
self.iso_overlap_entry.setSingleStep(0.1)
grid1.addWidget(overlabel, 2, 0)
grid1.addWidget(self.iso_overlap_entry, 2, 1, 1, 2)
grid1.addWidget(overlabel, 6, 0)
grid1.addWidget(self.iso_overlap_entry, 6, 1, 1, 2)
# Milling Type Radio Button
self.milling_type_label = QtWidgets.QLabel('%s:' % _('Milling Type'))
@ -309,8 +361,8 @@ class GerberObjectUI(ObjectUI):
)
self.milling_type_radio = RadioSet([{'label': _('Climb'), 'value': 'cl'},
{'label': _('Conv.'), 'value': 'cv'}])
grid1.addWidget(self.milling_type_label, 3, 0)
grid1.addWidget(self.milling_type_radio, 3, 1, 1, 2)
grid1.addWidget(self.milling_type_label, 7, 0)
grid1.addWidget(self.milling_type_radio, 7, 1, 1, 2)
# combine all passes CB
self.combine_passes_cb = FCCheckBox(label=_('Combine Passes'))
@ -330,13 +382,13 @@ class GerberObjectUI(ObjectUI):
"by checking this, the area of the object bellow\n"
"will be subtracted from the isolation geometry."))
grid1.addWidget(self.combine_passes_cb, 4, 0)
grid1.addWidget(self.follow_cb, 4, 1)
grid1.addWidget(self.except_cb, 4, 2)
grid1.addWidget(self.combine_passes_cb, 8, 0)
grid1.addWidget(self.follow_cb, 8, 1)
grid1.addWidget(self.except_cb, 8, 2)
# ## Form Layout
form_layout = QtWidgets.QFormLayout()
grid1.addLayout(form_layout, 5, 0, 1, 3)
grid1.addLayout(form_layout, 9, 0, 1, 3)
# ################################################
# ##### Type of object to be excepted ############
@ -383,7 +435,7 @@ class GerberObjectUI(ObjectUI):
"inside the actual Gerber feature, use a negative tool\n"
"diameter above.")
)
grid1.addWidget(self.gen_iso_label, 6, 0, 1, 3)
grid1.addWidget(self.gen_iso_label, 10, 0, 1, 3)
self.create_buffer_button = QtWidgets.QPushButton(_('Buffer Solid Geometry'))
self.create_buffer_button.setToolTip(
@ -392,7 +444,7 @@ class GerberObjectUI(ObjectUI):
"Clicking this will create the buffered geometry\n"
"required for isolation.")
)
grid1.addWidget(self.create_buffer_button, 7, 0, 1, 3)
grid1.addWidget(self.create_buffer_button, 11, 0, 1, 3)
self.generate_iso_button = QtWidgets.QPushButton(_('FULL Geo'))
self.generate_iso_button.setToolTip(
@ -400,10 +452,10 @@ class GerberObjectUI(ObjectUI):
"for isolation routing. It contains both\n"
"the interiors and exteriors geometry.")
)
grid1.addWidget(self.generate_iso_button, 8, 0)
grid1.addWidget(self.generate_iso_button, 12, 0)
hlay_1 = QtWidgets.QHBoxLayout()
grid1.addLayout(hlay_1, 8, 1, 1, 2)
grid1.addLayout(hlay_1, 12, 1, 1, 2)
self.generate_ext_iso_button = QtWidgets.QPushButton(_('Ext Geo'))
self.generate_ext_iso_button.setToolTip(
@ -433,7 +485,7 @@ class GerberObjectUI(ObjectUI):
self.ois_iso = OptionalInputSection(self.follow_cb,
[self.generate_int_iso_button, self.generate_ext_iso_button], logic=False)
grid1.addWidget(QtWidgets.QLabel(''), 9, 0)
grid1.addWidget(QtWidgets.QLabel(''), 13, 0)
# ###########################################
# ########## NEW GRID #######################