- In Excellon Editor, finished updating the Drill Plugin and Slot Plugin

- fixed a bug in the excellon export method, regarding the slots processing
This commit is contained in:
Marius Stanciu
2022-04-29 20:11:55 +03:00
committed by Marius
parent 4ac90d83f5
commit b4c300b2eb
6 changed files with 490 additions and 215 deletions

View File

@@ -7,6 +7,11 @@ CHANGELOG for FlatCAM Evo beta
================================================= =================================================
29.04.2022
- In Excellon Editor, finished updating the Drill Plugin and Slot Plugin
- fixed a bug in the excellon export method, regarding the slots processing
28.04.2022 28.04.2022
- in Isolation Plugin made sure that the last displayed message is the warning, in the case of using tool validation and the tool is not validated - in Isolation Plugin made sure that the last displayed message is the warning, in the case of using tool validation and the tool is not validated

View File

@@ -7,7 +7,8 @@
from camlib import distance, arc, AppRTreeStorage from camlib import distance, arc, AppRTreeStorage
from appEditors.exc_plugins.ExcGenPlugin import * from appEditors.exc_plugins.ExcDrillPlugin import *
from appEditors.exc_plugins.ExcSlotPlugin import ExcSlotEditorTool
from appGUI.GUIElements import FCEntry, FCTable, FCDoubleSpinner, RadioSet, FCSpinner, FCButton, FCLabel, GLay from appGUI.GUIElements import FCEntry, FCTable, FCDoubleSpinner, RadioSet, FCSpinner, FCButton, FCLabel, GLay
from appEditors.AppGeoEditor import FCShapeTool, DrawTool, DrawToolShape, DrawToolUtilityShape, AppGeoEditor from appEditors.AppGeoEditor import FCShapeTool, DrawTool, DrawToolShape, DrawToolUtilityShape, AppGeoEditor
@@ -58,7 +59,6 @@ class SelectEditorExc(FCShapeTool):
self.draw_app.ui.resize_frame.hide() self.draw_app.ui.resize_frame.hide()
self.draw_app.ui.array_frame.hide() self.draw_app.ui.array_frame.hide()
self.draw_app.ui.slot_frame.hide()
self.draw_app.ui.slot_array_frame.hide() self.draw_app.ui.slot_array_frame.hide()
# make sure that the cursor text from the DrillAdd is deleted # make sure that the cursor text from the DrillAdd is deleted
@@ -263,27 +263,27 @@ class DrillAdd(FCShapeTool):
self.cursor = QtGui.QCursor(QtGui.QPixmap(self.draw_app.app.resource_location + '/aero_drill.png')) self.cursor = QtGui.QCursor(QtGui.QPixmap(self.draw_app.app.resource_location + '/aero_drill.png'))
QtGui.QGuiApplication.setOverrideCursor(self.cursor) QtGui.QGuiApplication.setOverrideCursor(self.cursor)
# #############################################################################################################
# Plugin UI
# #############################################################################################################
self.drill_tool = ExcDrillEditorTool(self.app, self.draw_app, plugin_name=_("Drill"))
self.ui = self.drill_tool.ui
self.drill_tool.run()
geo = self.utility_geometry(data=(self.draw_app.snap_x, self.draw_app.snap_y)) geo = self.utility_geometry(data=(self.draw_app.snap_x, self.draw_app.snap_y))
if isinstance(geo, DrawToolShape) and geo.geo is not None: if isinstance(geo, DrawToolShape) and geo.geo is not None:
self.draw_app.draw_utility_geometry(geo=geo) self.draw_app.draw_utility_geometry(geo=geo)
self.draw_app.app.inform.emit(_("Click to place ..."))
if self.app.use_3d_engine: if self.app.use_3d_engine:
self.draw_app.app.plotcanvas.view.camera.zoom_callback = self.draw_cursor_data self.draw_app.app.plotcanvas.view.camera.zoom_callback = self.draw_cursor_data
self.draw_app.app.jump_signal.connect(lambda x: self.draw_app.update_utility_geometry(data=x)) self.draw_app.app.jump_signal.connect(lambda x: self.draw_app.update_utility_geometry(data=x))
self.drill_tool = ExcGenEditorTool(self.app, self.draw_app, plugin_name=_("Drill"))
self.drill_tool.run()
self.drill_tool.length = self.draw_app.last_length self.drill_tool.length = self.draw_app.last_length
if not self.draw_app.snap_x: if not self.draw_app.snap_x:
self.draw_app.snap_x = 0.0 self.draw_app.snap_x = 0.0
if not self.draw_app.snap_y: if not self.draw_app.snap_y:
self.draw_app.snap_y = 0.0 self.draw_app.snap_y = 0.0
self.drill_tool.ui.x_entry.set_value(float(self.draw_app.snap_x))
self.drill_tool.ui.y_entry.set_value(float(self.draw_app.snap_y))
self.app.ui.notebook.setTabText(2, _("Drill")) self.app.ui.notebook.setTabText(2, _("Drill"))
if self.app.ui.splitter.sizes()[0] == 0: if self.app.ui.splitter.sizes()[0] == 0:
@@ -293,8 +293,29 @@ class DrillAdd(FCShapeTool):
self.draw_app.clicked_pos and self.draw_app.clicked_pos[0] and self.draw_app.clicked_pos[1] else (0.0, 0.0) self.draw_app.clicked_pos and self.draw_app.clicked_pos[0] and self.draw_app.clicked_pos[1] else (0.0, 0.0)
self.drill_point = None self.drill_point = None
self.set_plugin_ui()
# Signals
try:
self.ui.add_btn.clicked.disconnect()
except (AttributeError, TypeError):
pass
self.ui.add_btn.clicked.connect(self.on_add_drill)
self.draw_app.app.inform.emit(_("Click to place ..."))
def set_plugin_ui(self):
curr_row = self.draw_app.ui.tools_table_exc.currentRow()
tool_dia = float(self.draw_app.ui.tools_table_exc.item(curr_row, 1).text())
self.ui.dia_entry.set_value(tool_dia)
self.ui.x_entry.set_value(float(self.draw_app.snap_x))
self.ui.y_entry.set_value(float(self.draw_app.snap_y))
def click(self, point): def click(self, point):
self.drill_point = point self.drill_point = point
self.draw_app.last_length = self.drill_tool.length
self.ui.x_entry.set_value(float(self.draw_app.snap_x))
self.ui.y_entry.set_value(float(self.draw_app.snap_y))
self.make() self.make()
return "Done." return "Done."
@@ -321,8 +342,8 @@ class DrillAdd(FCShapeTool):
def make(self): def make(self):
if self.drill_point is None: if self.drill_point is None:
self.drill_point = (self.draw_app.snap_x, self.draw_app.snap_y) self.drill_point = (self.draw_app.snap_x, self.draw_app.snap_y)
self.selected_dia = self.draw_app.tool2tooldia[self.draw_app.last_tool_selected] self.selected_dia = self.draw_app.tool2tooldia[self.draw_app.last_tool_selected]
try: try:
QtGui.QGuiApplication.restoreOverrideCursor() QtGui.QGuiApplication.restoreOverrideCursor()
except Exception: except Exception:
@@ -340,22 +361,16 @@ class DrillAdd(FCShapeTool):
self.draw_app.in_action = False self.draw_app.in_action = False
self.complete = True self.complete = True
self.draw_app.last_length = self.drill_tool.length
self.drill_tool.ui.x_entry.set_value(float(self.draw_app.snap_x))
self.drill_tool.ui.y_entry.set_value(float(self.draw_app.snap_y))
self.draw_app.app.inform.emit('[success] %s' % _("Done."))
try: try:
self.draw_app.app.jump_signal.disconnect() self.draw_app.app.jump_signal.disconnect()
except (TypeError, AttributeError): except (TypeError, AttributeError):
pass pass
self.draw_app.app.inform.emit('[success] %s' % _("Done."))
def draw_cursor_data(self, pos=None, delete=False): def draw_cursor_data(self, pos=None, delete=False):
if pos is None: if pos is None:
pos = 0, 0 pos = self.draw_app.snap_x, self.draw_app.snap_y
if not self.points:
self.points = self.draw_app.snap_x, self.draw_app.snap_y
if delete: if delete:
if self.draw_app.app.use_3d_engine: if self.draw_app.app.use_3d_engine:
@@ -363,6 +378,9 @@ class DrillAdd(FCShapeTool):
self.draw_app.app.plotcanvas.view.camera.zoom_callback = lambda *args: None self.draw_app.app.plotcanvas.view.camera.zoom_callback = lambda *args: None
return return
if not self.points:
self.points = self.draw_app.snap_x, self.draw_app.snap_y
# font size # font size
qsettings = QtCore.QSettings("Open Source", "FlatCAM") qsettings = QtCore.QSettings("Open Source", "FlatCAM")
if qsettings.contains("hud_font_size"): if qsettings.contains("hud_font_size"):
@@ -377,12 +395,11 @@ class DrillAdd(FCShapeTool):
except IndexError: except IndexError:
length = self.draw_app.app.dec_format(0.0, self.draw_app.app.decimals) length = self.draw_app.app.dec_format(0.0, self.draw_app.app.decimals)
units = self.draw_app.app.app_units.lower()
x_dec = str(self.draw_app.app.dec_format(x, self.draw_app.app.decimals)) if x else '0.0' x_dec = str(self.draw_app.app.dec_format(x, self.draw_app.app.decimals)) if x else '0.0'
y_dec = str(self.draw_app.app.dec_format(y, self.draw_app.app.decimals)) if y else '0.0' y_dec = str(self.draw_app.app.dec_format(y, self.draw_app.app.decimals)) if y else '0.0'
length_dec = str(self.draw_app.app.dec_format(length, self.draw_app.app.decimals)) if length else '0.0' length_dec = str(self.draw_app.app.dec_format(length, self.draw_app.app.decimals)) if length else '0.0'
units = self.draw_app.app.app_units.lower()
l1_txt = 'X: %s [%s]' % (x_dec, units) l1_txt = 'X: %s [%s]' % (x_dec, units)
l2_txt = 'Y: %s [%s]' % (y_dec, units) l2_txt = 'Y: %s [%s]' % (y_dec, units)
l3_txt = 'L: %s [%s]' % (length_dec, units) l3_txt = 'L: %s [%s]' % (length_dec, units)
@@ -420,7 +437,7 @@ class DrillAdd(FCShapeTool):
self.drill_tool.length = str(self.drill_tool.length) + str(key.name) self.drill_tool.length = str(self.drill_tool.length) + str(key.name)
except AttributeError: except AttributeError:
# Qt keys # Qt keys
if self.drill_tool.length == 0: if self.drill_tool.length == self.draw_app.last_length:
self.drill_tool.length = chr(key) self.drill_tool.length = chr(key)
else: else:
self.drill_tool.length = str(self.drill_tool.length) + chr(key) self.drill_tool.length = str(self.drill_tool.length) + chr(key)
@@ -432,7 +449,7 @@ class DrillAdd(FCShapeTool):
self.drill_tool.length = 0.0 self.drill_tool.length = 0.0
return _("Failed.") return _("Failed.")
first_pt = self.drill_tool.ui.x_entry.get_value(), self.drill_tool.ui.y_entry.get_value() first_pt = self.ui.x_entry.get_value(), self.ui.y_entry.get_value()
last_pt = self.draw_app.snap_x, self.draw_app.snap_y last_pt = self.draw_app.snap_x, self.draw_app.snap_y
seg_length = math.sqrt((last_pt[0] - first_pt[0])**2 + (last_pt[1] - first_pt[1])**2) seg_length = math.sqrt((last_pt[0] - first_pt[0])**2 + (last_pt[1] - first_pt[1])**2)
@@ -447,8 +464,24 @@ class DrillAdd(FCShapeTool):
if first_pt != (new_x, new_y): if first_pt != (new_x, new_y):
self.draw_app.app.on_jump_to(custom_location=(new_x, new_y), fit_center=False) self.draw_app.app.on_jump_to(custom_location=(new_x, new_y), fit_center=False)
self.make() self.add_drill(drill_pos=(new_x, new_y))
self.drill_point = (new_x, new_y)
def add_drill(self, drill_pos):
curr_pos = self.draw_app.app.geo_editor.snap(drill_pos[0], drill_pos[1])
self.draw_app.snap_x = curr_pos[0]
self.draw_app.snap_y = curr_pos[1]
self.draw_app.on_canvas_click_left_handler(curr_pos)
if self.draw_app.active_tool.complete:
self.draw_app.on_shape_complete()
self.drill_point = curr_pos
self.draw_app.clicked_pos = curr_pos
def on_add_drill(self):
x = self.ui.x_entry.get_value()
y = self.ui.y_entry.get_value()
self.add_drill(drill_pos=(x, y))
def clean_up(self): def clean_up(self):
self.draw_app.selected = [] self.draw_app.selected = []
@@ -795,8 +828,9 @@ class SlotAdd(FCShapeTool):
self.name = 'slot_add' self.name = 'slot_add'
self.draw_app = draw_app self.draw_app = draw_app
self.app = self.draw_app.app self.app = self.draw_app.app
self.steps_per_circ = self.draw_app.app.options["geometry_circle_steps"]
self.draw_app.ui.slot_frame.show() self.half_height = 0.0
self.half_width = 0.0
self.selected_dia = None self.selected_dia = None
try: try:
@@ -819,72 +853,81 @@ class SlotAdd(FCShapeTool):
self.cursor = QtGui.QCursor(QtGui.QPixmap(self.draw_app.app.resource_location + '/aero_slot.png')) self.cursor = QtGui.QCursor(QtGui.QPixmap(self.draw_app.app.resource_location + '/aero_slot.png'))
QtGui.QGuiApplication.setOverrideCursor(self.cursor) QtGui.QGuiApplication.setOverrideCursor(self.cursor)
self.steps_per_circ = self.draw_app.app.options["geometry_circle_steps"]
self.half_height = 0.0
self.half_width = 0.0
self.radius = float(self.selected_dia / 2.0) self.radius = float(self.selected_dia / 2.0)
# #############################################################################################################
# Plugin UI
# #############################################################################################################
self.slot_tool = ExcSlotEditorTool(self.app, self.draw_app, plugin_name=_("Slot"))
self.ui = self.slot_tool.ui
self.slot_tool.run()
geo = self.utility_geometry(data=(self.draw_app.snap_x, self.draw_app.snap_y)) geo = self.utility_geometry(data=(self.draw_app.snap_x, self.draw_app.snap_y))
if isinstance(geo, DrawToolShape) and geo.geo is not None: if isinstance(geo, DrawToolShape) and geo.geo is not None:
self.draw_app.draw_utility_geometry(geo=geo) self.draw_app.draw_utility_geometry(geo=geo)
self.draw_app.app.inform.emit(_("Click on target location ..."))
if self.app.use_3d_engine: if self.app.use_3d_engine:
self.draw_app.app.plotcanvas.view.camera.zoom_callback = self.draw_cursor_data self.draw_app.app.plotcanvas.view.camera.zoom_callback = self.draw_cursor_data
self.draw_app.app.jump_signal.connect(lambda x: self.draw_app.update_utility_geometry(data=x)) self.draw_app.app.jump_signal.connect(lambda x: self.draw_app.update_utility_geometry(data=x))
self.slot_tool = ExcGenEditorTool(self.app, self.draw_app, plugin_name=_("Slot")) self.slot_tool.length = self.draw_app.last_length
self.slot_tool.run() if not self.draw_app.snap_x:
self.draw_app.snap_x = 0.0
if not self.draw_app.snap_y:
self.draw_app.snap_y = 0.0
self.app.ui.notebook.setTabText(2, _("Slot")) self.app.ui.notebook.setTabText(2, _("Slot"))
if self.app.ui.splitter.sizes()[0] == 0: if self.app.ui.splitter.sizes()[0] == 0:
self.app.ui.splitter.setSizes([1, 1]) self.app.ui.splitter.setSizes([1, 1])
self.points = deepcopy(self.draw_app.clicked_pos) if \
self.draw_app.clicked_pos and self.draw_app.clicked_pos[0] and self.draw_app.clicked_pos[1] else (0.0, 0.0)
self.slot_point = None
self.set_plugin_ui()
# Signals
try:
self.ui.add_btn.clicked.disconnect()
except (AttributeError, TypeError):
pass
self.ui.add_btn.clicked.connect(self.on_add_slot)
self.draw_app.app.inform.emit(_("Click to place ..."))
def set_plugin_ui(self):
self.ui.slot_length_entry.set_value(float(self.app.options['excellon_editor_slot_length']))
self.ui.slot_axis_radio.set_value(self.app.options['excellon_editor_slot_direction'])
self.ui.on_slot_angle_radio()
self.ui.slot_angle_spinner.set_value(float(self.app.options['excellon_editor_slot_angle']))
curr_row = self.draw_app.ui.tools_table_exc.currentRow()
tool_dia = float(self.draw_app.ui.tools_table_exc.item(curr_row, 1).text())
self.ui.dia_entry.set_value(tool_dia)
self.ui.x_entry.set_value(float(self.draw_app.snap_x))
self.ui.y_entry.set_value(float(self.draw_app.snap_y))
def click(self, point): def click(self, point):
self.slot_point = point
self.draw_app.last_length = self.slot_tool.length
self.ui.x_entry.set_value(float(self.draw_app.snap_x))
self.ui.y_entry.set_value(float(self.draw_app.snap_y))
self.make() self.make()
return "Done." return "Done."
def utility_geometry(self, data=None): def utility_geometry(self, data=None):
self.points = data
geo_data = self.util_shape(data) geo_data = self.util_shape(data)
if geo_data: return DrawToolUtilityShape(geo_data) if geo_data else None
return DrawToolUtilityShape(geo_data)
else:
return None
def util_shape(self, point): def util_shape(self, point):
if point is None:
return
# updating values here allows us to change the aperture on the fly, after the Tool has been started # updating values here allows us to change the aperture on the fly, after the Tool has been started
self.selected_dia = self.draw_app.tool2tooldia[self.draw_app.last_tool_selected] self.selected_dia = self.draw_app.tool2tooldia[self.draw_app.last_tool_selected]
self.radius = float(self.selected_dia / 2.0) self.radius = float(self.selected_dia / 2.0)
self.steps_per_circ = self.draw_app.app.options["geometry_circle_steps"] self.steps_per_circ = self.draw_app.app.options["geometry_circle_steps"]
try: slot_length = float(self.ui.slot_length_entry.get_value())
slot_length = float(self.draw_app.ui.slot_length_entry.get_value()) slot_angle = float(self.ui.slot_angle_spinner.get_value())
except ValueError: if self.ui.slot_axis_radio.get_value() == 'X':
# try to convert comma to decimal point. if it's still not working error message and return
try:
slot_length = float(self.draw_app.ui.slot_length_entry.get_value().replace(',', '.'))
self.draw_app.ui.slot_length_entry.set_value(slot_length)
except ValueError:
self.draw_app.app.inform.emit('[WARNING_NOTCL] %s' %
_("Value is missing or wrong format. Add it and retry."))
return
try:
slot_angle = float(self.draw_app.ui.slot_angle_spinner.get_value())
except ValueError:
self.draw_app.app.inform.emit('[WARNING_NOTCL] %s' %
_("Value is missing or wrong format. Add it and retry."))
return
if self.draw_app.ui.slot_axis_radio.get_value() == 'X':
self.half_width = slot_length / 2.0 self.half_width = slot_length / 2.0
self.half_height = self.radius self.half_height = self.radius
else: else:
@@ -899,7 +942,6 @@ class SlotAdd(FCShapeTool):
point_y = point[1] point_y = point[1]
geo = [] geo = []
if self.half_height > self.half_width: if self.half_height > self.half_width:
p1 = (point_x - self.half_width, point_y - self.half_height + self.half_width) p1 = (point_x - self.half_width, point_y - self.half_height + self.half_width)
p2 = (point_x + self.half_width, point_y - self.half_height + self.half_width) p2 = (point_x + self.half_width, point_y - self.half_height + self.half_width)
@@ -925,7 +967,7 @@ class SlotAdd(FCShapeTool):
geo.append(pt) geo.append(pt)
geo.append(p4) geo.append(p4)
if self.draw_app.ui.slot_axis_radio.get_value() == 'A': if self.ui.slot_axis_radio.get_value() == 'A':
return rotate(geom=Polygon(geo), angle=-slot_angle) return rotate(geom=Polygon(geo), angle=-slot_angle)
else: else:
return Polygon(geo) return Polygon(geo)
@@ -957,31 +999,36 @@ class SlotAdd(FCShapeTool):
return Polygon(geo) return Polygon(geo)
def make(self): def make(self):
if self.slot_point is None:
self.slot_point = (self.draw_app.snap_x, self.draw_app.snap_y)
self.selected_dia = self.draw_app.tool2tooldia[self.draw_app.last_tool_selected]
try: try:
QtGui.QGuiApplication.restoreOverrideCursor() QtGui.QGuiApplication.restoreOverrideCursor()
except Exception: except Exception:
pass pass
try:
self.geometry = DrawToolShape(self.util_shape(self.points))
except Exception as e:
log.error("SlotAdd.make() --> %s" % str(e))
# add the point to drills/slots if the diameter is a key in the dict, if not, create it add the drill location # add the point to drills/slots if the diameter is a key in the dict, if not, create it add the drill location
# to the value, as a list of itself # to the value, as a list of itself
if self.selected_dia in self.draw_app.slot_points_edit: if self.selected_dia in self.draw_app.slot_points_edit:
self.draw_app.slot_points_edit[self.selected_dia].append(self.points) self.draw_app.slot_points_edit[self.selected_dia].append(self.slot_point)
else: else:
self.draw_app.slot_points_edit[self.selected_dia] = [self.points] self.draw_app.slot_points_edit[self.selected_dia] = [self.slot_point]
self.draw_app.current_storage = self.draw_app.storage_dict[self.selected_dia] self.draw_app.current_storage = self.draw_app.storage_dict[self.selected_dia]
try:
self.geometry = DrawToolShape(self.util_shape(self.slot_point))
except Exception as e:
log.error("SlotAdd.make() --> %s" % str(e))
self.draw_app.in_action = False self.draw_app.in_action = False
self.complete = True self.complete = True
try:
self.draw_app.app.jump_signal.disconnect()
except (TypeError, AttributeError):
pass
self.draw_app.app.inform.emit('[success] %s' % _("Done.")) self.draw_app.app.inform.emit('[success] %s' % _("Done."))
self.draw_app.ui.slot_frame.hide()
self.draw_app.app.jump_signal.disconnect()
def draw_cursor_data(self, pos=None, delete=False): def draw_cursor_data(self, pos=None, delete=False):
if pos is None: if pos is None:
@@ -993,6 +1040,9 @@ class SlotAdd(FCShapeTool):
self.draw_app.app.plotcanvas.view.camera.zoom_callback = lambda *args: None self.draw_app.app.plotcanvas.view.camera.zoom_callback = lambda *args: None
return return
if not self.points:
self.points = self.draw_app.snap_x, self.draw_app.snap_y
# font size # font size
qsettings = QtCore.QSettings("Open Source", "FlatCAM") qsettings = QtCore.QSettings("Open Source", "FlatCAM")
if qsettings.contains("hud_font_size"): if qsettings.contains("hud_font_size"):
@@ -1003,15 +1053,15 @@ class SlotAdd(FCShapeTool):
x = pos[0] x = pos[0]
y = pos[1] y = pos[1]
try: try:
length = abs(np.sqrt((pos[0] - self.points[-1][0]) ** 2 + (pos[1] - self.points[-1][1]) ** 2)) length = abs(np.sqrt((x - self.points[0]) ** 2 + (y - self.points[1]) ** 2))
except IndexError: except IndexError:
length = self.draw_app.app.dec_format(0.0, self.draw_app.app.decimals) length = self.draw_app.app.dec_format(0.0, self.draw_app.app.decimals)
units = self.draw_app.app.app_units.lower()
x_dec = str(self.draw_app.app.dec_format(x, self.draw_app.app.decimals)) if x else '0.0' x_dec = str(self.draw_app.app.dec_format(x, self.draw_app.app.decimals)) if x else '0.0'
y_dec = str(self.draw_app.app.dec_format(y, self.draw_app.app.decimals)) if y else '0.0' y_dec = str(self.draw_app.app.dec_format(y, self.draw_app.app.decimals)) if y else '0.0'
length_dec = str(self.draw_app.app.dec_format(length, self.draw_app.app.decimals)) if length else '0.0' length_dec = str(self.draw_app.app.dec_format(length, self.draw_app.app.decimals)) if length else '0.0'
units = self.draw_app.app.app_units.lower()
l1_txt = 'X: %s [%s]' % (x_dec, units) l1_txt = 'X: %s [%s]' % (x_dec, units)
l2_txt = 'Y: %s [%s]' % (y_dec, units) l2_txt = 'Y: %s [%s]' % (y_dec, units)
l3_txt = 'L: %s [%s]' % (length_dec, units) l3_txt = 'L: %s [%s]' % (length_dec, units)
@@ -1024,7 +1074,7 @@ class SlotAdd(FCShapeTool):
# text # text
self.draw_app.app.plotcanvas.text_cursor.font_size = fsize self.draw_app.app.plotcanvas.text_cursor.font_size = fsize
self.draw_app.app.plotcanvas.text_cursor.text = cursor_text self.draw_app.app.plotcanvas.text_cursor.text = cursor_text
self.draw_app.app.plotcanvas.text_cursor.clicked_pos = x, y self.draw_app.app.plotcanvas.text_cursor.pos = x, y
self.draw_app.app.plotcanvas.text_cursor.anchors = 'left', 'top' self.draw_app.app.plotcanvas.text_cursor.anchors = 'left', 'top'
if self.draw_app.app.plotcanvas.text_cursor.parent is None: if self.draw_app.app.plotcanvas.text_cursor.parent is None:
@@ -1037,12 +1087,13 @@ class SlotAdd(FCShapeTool):
# Toggle Pad Direction # Toggle Pad Direction
if key == QtCore.Qt.Key.Key_Space: if key == QtCore.Qt.Key.Key_Space:
if self.draw_app.ui.slot_axis_radio.get_value() == 'X': if self.ui.slot_axis_radio.get_value() == 'X':
self.draw_app.ui.slot_axis_radio.set_value('Y') self.ui.slot_axis_radio.set_value('Y')
elif self.draw_app.ui.slot_axis_radio.get_value() == 'Y': elif self.ui.slot_axis_radio.get_value() == 'Y':
self.draw_app.ui.slot_axis_radio.set_value('A') self.ui.slot_axis_radio.set_value('A')
elif self.draw_app.ui.slot_axis_radio.get_value() == 'A': elif self.ui.slot_axis_radio.get_value() == 'A':
self.draw_app.ui.slot_axis_radio.set_value('X') self.ui.slot_axis_radio.set_value('X')
# ## Utility geometry (animated) # ## Utility geometry (animated)
self.draw_app.update_utility_geometry(data=(self.draw_app.snap_x, self.draw_app.snap_y)) self.draw_app.update_utility_geometry(data=(self.draw_app.snap_x, self.draw_app.snap_y))
@@ -1054,13 +1105,13 @@ class SlotAdd(FCShapeTool):
QtCore.Qt.Key.Key_Slash, QtCore.Qt.Key.Key_Asterisk]: QtCore.Qt.Key.Key_Slash, QtCore.Qt.Key.Key_Asterisk]:
try: try:
# VisPy keys # VisPy keys
if self.slot_tool.length == 0: if self.slot_tool.length == self.draw_app.last_length:
self.slot_tool.length = str(key.name) self.slot_tool.length = str(key.name)
else: else:
self.slot_tool.length = str(self.slot_tool.length) + str(key.name) self.slot_tool.length = str(self.slot_tool.length) + str(key.name)
except AttributeError: except AttributeError:
# Qt keys # Qt keys
if self.slot_tool.length == 0: if self.slot_tool.length == self.draw_app.last_length:
self.slot_tool.length = chr(key) self.slot_tool.length = chr(key)
else: else:
self.slot_tool.length = str(self.slot_tool.length) + chr(key) self.slot_tool.length = str(self.slot_tool.length) + chr(key)
@@ -1072,8 +1123,8 @@ class SlotAdd(FCShapeTool):
self.slot_tool.length = 0.0 self.slot_tool.length = 0.0
return _("Failed.") return _("Failed.")
first_pt = self.points[-1] first_pt = self.ui.x_entry.get_value(), self.ui.y_entry.get_value()
last_pt = self.draw_app.app.mouse last_pt = self.draw_app.snap_x, self.draw_app.snap_y
seg_length = math.sqrt((last_pt[0] - first_pt[0])**2 + (last_pt[1] - first_pt[1])**2) seg_length = math.sqrt((last_pt[0] - first_pt[0])**2 + (last_pt[1] - first_pt[1])**2)
if seg_length == 0.0: if seg_length == 0.0:
@@ -1082,26 +1133,39 @@ class SlotAdd(FCShapeTool):
new_x = first_pt[0] + (last_pt[0] - first_pt[0]) / seg_length * target_length new_x = first_pt[0] + (last_pt[0] - first_pt[0]) / seg_length * target_length
new_y = first_pt[1] + (last_pt[1] - first_pt[1]) / seg_length * target_length new_y = first_pt[1] + (last_pt[1] - first_pt[1]) / seg_length * target_length
except ZeroDivisionError as err: except ZeroDivisionError as err:
self.points = []
self.clean_up() self.clean_up()
return '[ERROR_NOTCL] %s %s' % (_("Failed."), str(err).capitalize()) return '[ERROR_NOTCL] %s %s' % (_("Failed."), str(err).capitalize())
if self.points[-1] != (new_x, new_y): if first_pt != (new_x, new_y):
self.points.append((new_x, new_y))
self.draw_app.app.on_jump_to(custom_location=(new_x, new_y), fit_center=False) self.draw_app.app.on_jump_to(custom_location=(new_x, new_y), fit_center=False)
if len(self.points) > 0: self.add_slot(slot_pos=(new_x, new_y))
msg = '%s: %s. %s' % (
_("Projected"), str(self.slot_tool.length), def add_slot(self, slot_pos):
_("Click on next Point or click right mouse button to complete ...")) curr_pos = self.draw_app.app.geo_editor.snap(slot_pos[0], slot_pos[1])
self.draw_app.app.inform.emit(msg) self.draw_app.snap_x = curr_pos[0]
# self.interpolate_length = '' self.draw_app.snap_y = curr_pos[1]
# return "Click on next point or hit ENTER to complete ..."
self.draw_app.on_canvas_click_left_handler(curr_pos)
if self.draw_app.active_tool.complete:
self.draw_app.on_shape_complete()
self.slot_point = curr_pos
self.draw_app.clicked_pos = curr_pos
def on_add_slot(self):
x = self.ui.x_entry.get_value()
y = self.ui.y_entry.get_value()
self.add_slot(slot_pos=(x, y))
def clean_up(self): def clean_up(self):
self.draw_app.selected = [] self.draw_app.selected = []
self.draw_app.ui.tools_table_exc.clearSelection() self.draw_app.ui.tools_table_exc.clearSelection()
self.draw_app.plot_all() self.draw_app.plot_all()
if self.draw_app.app.use_3d_engine:
self.draw_app.app.plotcanvas.text_cursor.parent = None
self.draw_app.app.plotcanvas.view.camera.zoom_callback = lambda *args: None
try: try:
self.draw_app.app.jump_signal.disconnect() self.draw_app.app.jump_signal.disconnect()
except (TypeError, AttributeError): except (TypeError, AttributeError):
@@ -2150,7 +2214,6 @@ class AppExcEditor(QtCore.QObject):
self.ui.slot_array_type_radio.activated_custom.connect(self.on_slot_array_type_radio) self.ui.slot_array_type_radio.activated_custom.connect(self.on_slot_array_type_radio)
self.ui.drill_axis_radio.activated_custom.connect(self.on_linear_angle_radio) self.ui.drill_axis_radio.activated_custom.connect(self.on_linear_angle_radio)
self.ui.slot_axis_radio.activated_custom.connect(self.on_slot_angle_radio)
self.ui.slot_array_axis_radio.activated_custom.connect(self.on_slot_array_linear_angle_radio) self.ui.slot_array_axis_radio.activated_custom.connect(self.on_slot_array_linear_angle_radio)
@@ -2256,10 +2319,6 @@ class AppExcEditor(QtCore.QObject):
self.ui.drill_array_dir_radio.set_value(self.app.options['excellon_editor_circ_dir']) self.ui.drill_array_dir_radio.set_value(self.app.options['excellon_editor_circ_dir'])
self.ui.drill_angle_entry.set_value(float(self.app.options['excellon_editor_circ_angle'])) self.ui.drill_angle_entry.set_value(float(self.app.options['excellon_editor_circ_angle']))
self.ui.slot_length_entry.set_value(float(self.app.options['excellon_editor_slot_length']))
self.ui.slot_axis_radio.set_value(self.app.options['excellon_editor_slot_direction'])
self.ui.slot_angle_spinner.set_value(float(self.app.options['excellon_editor_slot_angle']))
self.ui.slot_array_size_entry.set_value(int(self.app.options['excellon_editor_slot_array_size'])) self.ui.slot_array_size_entry.set_value(int(self.app.options['excellon_editor_slot_array_size']))
self.ui.slot_array_axis_radio.set_value(self.app.options['excellon_editor_slot_lin_dir']) self.ui.slot_array_axis_radio.set_value(self.app.options['excellon_editor_slot_lin_dir'])
self.ui.slot_array_pitch_entry.set_value(float(self.app.options['excellon_editor_slot_lin_pitch'])) self.ui.slot_array_pitch_entry.set_value(float(self.app.options['excellon_editor_slot_lin_pitch']))
@@ -2267,10 +2326,6 @@ class AppExcEditor(QtCore.QObject):
self.ui.slot_array_direction_radio.set_value(self.app.options['excellon_editor_slot_circ_dir']) self.ui.slot_array_direction_radio.set_value(self.app.options['excellon_editor_slot_circ_dir'])
self.ui.slot_array_angle_entry.set_value(float(self.app.options['excellon_editor_slot_circ_angle'])) self.ui.slot_array_angle_entry.set_value(float(self.app.options['excellon_editor_slot_circ_angle']))
# make sure that th visibility of the various UI frame are updated
# according to the set Preferences already loaded
self.on_slot_angle_radio()
self.ui.array_type_radio.set_value('linear') self.ui.array_type_radio.set_value('linear')
self.on_array_type_radio(val=self.ui.array_type_radio.get_value()) self.on_array_type_radio(val=self.ui.array_type_radio.get_value())
self.ui.slot_array_type_radio.set_value('linear') self.ui.slot_array_type_radio.set_value('linear')
@@ -3642,7 +3697,7 @@ class AppExcEditor(QtCore.QObject):
""" """
Called on 'mouse_move' event. Called on 'mouse_move' event.
It updates the mouse cursor if the grid snapping is ON. It updates the mouse cursor if the grid snapping is ON.
It decide if we have a mouse drag and if it is done with the right mouse click. Then it passes this info to a It decides if we have a mouse drag and if it is done with the right mouse click. Then it passes this info to a
class object which is used in the "mouse_release" handler to decide if to pop-up the context menu or not. class object which is used in the "mouse_release" handler to decide if to pop-up the context menu or not.
It draws utility_geometry for the Editor tools. It draws utility_geometry for the Editor tools.
Update the position labels from status bar. Update the position labels from status bar.
@@ -3698,8 +3753,8 @@ class AppExcEditor(QtCore.QObject):
edge_width=self.app.options["global_cursor_width"], edge_width=self.app.options["global_cursor_width"],
size=self.app.options["global_cursor_size"]) size=self.app.options["global_cursor_size"])
self.snap_x = x self.snap_x = deepcopy(x)
self.snap_y = y self.snap_y = deepcopy(y)
if self.clicked_pos is None: if self.clicked_pos is None:
self.clicked_pos = (0, 0) self.clicked_pos = (0, 0)
@@ -4172,15 +4227,6 @@ class AppExcEditor(QtCore.QObject):
self.ui.slot_array_linear_angle_spinner.hide() self.ui.slot_array_linear_angle_spinner.hide()
self.ui.slot_array_linear_angle_label.hide() self.ui.slot_array_linear_angle_label.hide()
def on_slot_angle_radio(self):
val = self.ui.slot_axis_radio.get_value()
if val == 'A':
self.ui.slot_angle_spinner.show()
self.ui.slot_angle_label.show()
else:
self.ui.slot_angle_spinner.hide()
self.ui.slot_angle_label.hide()
def exc_add_drill(self): def exc_add_drill(self):
self.select_tool('drill_add') self.select_tool('drill_add')
return return
@@ -4599,81 +4645,6 @@ class AppExcEditorUI:
separator_line.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken) separator_line.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken)
self.array_grid.addWidget(separator_line, 10, 0, 1, 2) self.array_grid.addWidget(separator_line, 10, 0, 1, 2)
# #############################################################################################################
# ################################### ADDING SLOTS ############################################################
# #############################################################################################################
# add a frame and inside add a grid box layout. Inside this grid layout I add
# all the add slot widgets
# this way I can hide/show the frame
self.slot_frame = QtWidgets.QFrame()
self.slot_frame.setContentsMargins(0, 0, 0, 0)
self.ui_vertical_lay.addWidget(self.slot_frame)
self.slot_grid = GLay(v_spacing=5, h_spacing=3)
self.slot_grid.setContentsMargins(0, 0, 0, 0)
self.slot_frame.setLayout(self.slot_grid)
# Slot Tile Label
self.slot_label = FCLabel('%s' % _("Slot Parameters"), bold=True)
self.slot_label.setToolTip(
_("Parameters for adding a slot (hole with oval shape)\n"
"either single or as an part of an array.")
)
self.slot_grid.addWidget(self.slot_label, 0, 0, 1, 2)
# Slot length
self.slot_length_label = FCLabel('%s:' % _('Length'))
self.slot_length_label.setToolTip(
_("Length. The length of the slot.")
)
self.slot_length_entry = FCDoubleSpinner(policy=False)
self.slot_length_entry.set_precision(self.decimals)
self.slot_length_entry.setSingleStep(0.1)
self.slot_length_entry.setRange(0.0000, 10000.0000)
self.slot_grid.addWidget(self.slot_length_label, 2, 0)
self.slot_grid.addWidget(self.slot_length_entry, 2, 1)
# Slot direction
self.slot_axis_label = FCLabel('%s:' % _('Direction'))
self.slot_axis_label.setToolTip(
_("Direction on which the slot is oriented:\n"
"- 'X' - horizontal axis \n"
"- 'Y' - vertical axis or \n"
"- 'Angle' - a custom angle for the slot inclination")
)
self.slot_axis_radio = RadioSet([{'label': _('X'), 'value': 'X'},
{'label': _('Y'), 'value': 'Y'},
{'label': _('Angle'), 'value': 'A'}])
self.slot_grid.addWidget(self.slot_axis_label, 4, 0)
self.slot_grid.addWidget(self.slot_axis_radio, 4, 1)
# Slot custom angle
self.slot_angle_label = FCLabel('%s:' % _('Angle'))
self.slot_angle_label.setToolTip(
_("Angle at which the slot is placed.\n"
"The precision is of max 2 decimals.\n"
"Min value is: -360.00 degrees.\n"
"Max value is: 360.00 degrees.")
)
self.slot_angle_spinner = FCDoubleSpinner(policy=False)
self.slot_angle_spinner.set_precision(self.decimals)
self.slot_angle_spinner.setWrapping(True)
self.slot_angle_spinner.setRange(-360.00, 360.00)
self.slot_angle_spinner.setSingleStep(1.0)
self.slot_grid.addWidget(self.slot_angle_label, 6, 0)
self.slot_grid.addWidget(self.slot_angle_spinner, 6, 1)
separator_line = QtWidgets.QFrame()
separator_line.setFrameShape(QtWidgets.QFrame.Shape.HLine)
separator_line.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken)
self.slot_grid.addWidget(separator_line, 8, 0, 1, 2)
# ############################################################################################################# # #############################################################################################################
# ##################################### ADDING SLOT ARRAY #################################################### # ##################################### ADDING SLOT ARRAY ####################################################
# ############################################################################################################# # #############################################################################################################
@@ -4834,7 +4805,6 @@ class AppExcEditorUI:
self.array_circular_frame.hide() self.array_circular_frame.hide()
self.array_frame.hide() self.array_frame.hide()
self.slot_frame.hide()
self.slot_array_linear_angle_spinner.hide() self.slot_array_linear_angle_spinner.hide()
self.slot_array_linear_angle_label.hide() self.slot_array_linear_angle_label.hide()
self.slot_array_frame.hide() self.slot_array_frame.hide()

View File

@@ -6,7 +6,7 @@ if '_' not in builtins.__dict__:
_ = gettext.gettext _ = gettext.gettext
class ExcGenEditorTool(AppTool): class ExcDrillEditorTool(AppTool):
""" """
Simple input for buffer distance. Simple input for buffer distance.
""" """
@@ -18,7 +18,7 @@ class ExcGenEditorTool(AppTool):
self.decimals = app.decimals self.decimals = app.decimals
self.plugin_name = plugin_name self.plugin_name = plugin_name
self.ui = ExcGenEditorUI(layout=self.layout, path_class=self, plugin_name=plugin_name) self.ui = ExcDrillEditorUI(layout=self.layout, path_class=self, plugin_name=plugin_name)
self.connect_signals_at_init() self.connect_signals_at_init()
self.set_tool_ui() self.set_tool_ui()
@@ -96,7 +96,7 @@ class ExcGenEditorTool(AppTool):
self.draw_app.select_tool("select") self.draw_app.select_tool("select")
class ExcGenEditorUI: class ExcDrillEditorUI:
def __init__(self, layout, path_class, plugin_name): def __init__(self, layout, path_class, plugin_name):
self.pluginName = plugin_name self.pluginName = plugin_name
@@ -123,6 +123,28 @@ class ExcGenEditorUI:
self.editor_vbox.setContentsMargins(0, 0, 0, 0) self.editor_vbox.setContentsMargins(0, 0, 0, 0)
self.path_tool_frame.setLayout(self.editor_vbox) self.path_tool_frame.setLayout(self.editor_vbox)
# Position
self.tool_lbl = FCLabel('%s' % _("Tool Diameter"), bold=True, color='blue')
self.editor_vbox.addWidget(self.tool_lbl)
# #############################################################################################################
# Diameter Frame
# #############################################################################################################
dia_frame = FCFrame()
self.editor_vbox.addWidget(dia_frame)
dia_grid = GLay(v_spacing=5, h_spacing=3, c_stretch=[0, 1, 0])
dia_frame.setLayout(dia_grid)
# Dia Value
self.dia_lbl = FCLabel('%s:' % _("Value"))
self.dia_entry = NumericalEvalEntry(border_color='#0069A9')
self.dia_entry.setDisabled(True)
self.dia_unit = FCLabel('%s' % 'mm')
dia_grid.addWidget(self.dia_lbl, 0, 0)
dia_grid.addWidget(self.dia_entry, 0, 1)
dia_grid.addWidget(self.dia_unit, 0, 2)
# Position # Position
self.pos_lbl = FCLabel('%s' % _("Position"), bold=True, color='red') self.pos_lbl = FCLabel('%s' % _("Position"), bold=True, color='red')
self.editor_vbox.addWidget(self.pos_lbl) self.editor_vbox.addWidget(self.pos_lbl)
@@ -177,5 +199,5 @@ class ExcGenEditorUI:
self.add_btn.setIcon(QtGui.QIcon(self.ed_class.app.resource_location + '/plus32.png')) self.add_btn.setIcon(QtGui.QIcon(self.ed_class.app.resource_location + '/plus32.png'))
self.editor_vbox.addWidget(self.add_btn) self.editor_vbox.addWidget(self.add_btn)
GLay.set_common_column_size([pos_grid, pro_grid], 0) GLay.set_common_column_size([dia_grid, pos_grid, pro_grid], 0)
self.layout.addStretch(1) self.layout.addStretch(1)

View File

@@ -0,0 +1,279 @@
from appTool import *
fcTranslate.apply_language('strings')
if '_' not in builtins.__dict__:
_ = gettext.gettext
class ExcSlotEditorTool(AppTool):
"""
Simple input for buffer distance.
"""
def __init__(self, app, draw_app, plugin_name):
AppTool.__init__(self, app)
self.draw_app = draw_app
self.decimals = app.decimals
self.plugin_name = plugin_name
self.ui = ExcSlotEditorUI(layout=self.layout, path_class=self, plugin_name=plugin_name)
self.connect_signals_at_init()
self.set_tool_ui()
def connect_signals_at_init(self):
# Signals
self.ui.clear_btn.clicked.connect(self.on_clear)
def disconnect_signals(self):
# Signals
try:
self.ui.clear_btn.clicked.disconnect()
except (TypeError, AttributeError):
pass
def run(self):
self.app.defaults.report_usage("Geo Editor ToolPath()")
AppTool.run(self)
# if the splitter us hidden, display it
if self.app.ui.splitter.sizes()[0] == 0:
self.app.ui.splitter.setSizes([1, 1])
# if the Tool Tab is hidden display it, else hide it but only if the objectName is the same
found_idx = None
for idx in range(self.app.ui.notebook.count()):
if self.app.ui.notebook.widget(idx).objectName() == "plugin_tab":
found_idx = idx
break
# show the Tab
if not found_idx:
try:
self.app.ui.notebook.addTab(self.app.ui.plugin_tab, _("Plugin"))
except RuntimeError:
self.app.ui.plugin_tab = QtWidgets.QWidget()
self.app.ui.plugin_tab.setObjectName("plugin_tab")
self.app.ui.plugin_tab_layout = QtWidgets.QVBoxLayout(self.app.ui.plugin_tab)
self.app.ui.plugin_tab_layout.setContentsMargins(2, 2, 2, 2)
self.app.ui.plugin_scroll_area = VerticalScrollArea()
self.app.ui.plugin_tab_layout.addWidget(self.app.ui.plugin_scroll_area)
self.app.ui.notebook.addTab(self.app.ui.plugin_tab, _("Plugin"))
# focus on Tool Tab
self.app.ui.notebook.setCurrentWidget(self.app.ui.plugin_tab)
# self.app.ui.notebook.callback_on_close = self.on_tab_close
self.app.ui.notebook.setTabText(2, self.plugin_name)
def set_tool_ui(self):
# Init appGUI
self.length = 0.0
def on_tab_close(self):
self.disconnect_signals()
self.hide_tool()
# self.app.ui.notebook.callback_on_close = lambda: None
def on_clear(self):
self.set_tool_ui()
@property
def length(self):
return self.ui.project_line_entry.get_value()
@length.setter
def length(self, val):
self.ui.project_line_entry.set_value(val)
def hide_tool(self):
self.ui.path_tool_frame.hide()
self.app.ui.notebook.setCurrentWidget(self.app.ui.properties_tab)
if self.draw_app.active_tool.name != 'select':
self.draw_app.select_tool("select")
class ExcSlotEditorUI:
def __init__(self, layout, path_class, plugin_name):
self.pluginName = plugin_name
self.ed_class = path_class
self.decimals = self.ed_class.app.decimals
self.layout = layout
# Title
title_label = FCLabel("%s" % ('Editor ' + self.pluginName))
title_label.setStyleSheet("""
QLabel
{
font-size: 16px;
font-weight: bold;
}
""")
self.layout.addWidget(title_label)
# this way I can hide/show the frame
self.path_tool_frame = QtWidgets.QFrame()
self.path_tool_frame.setContentsMargins(0, 0, 0, 0)
self.layout.addWidget(self.path_tool_frame)
self.editor_vbox = QtWidgets.QVBoxLayout()
self.editor_vbox.setContentsMargins(0, 0, 0, 0)
self.path_tool_frame.setLayout(self.editor_vbox)
# Position
self.tool_lbl = FCLabel('%s' % _("Tool Diameter"), bold=True, color='blue')
self.editor_vbox.addWidget(self.tool_lbl)
# #############################################################################################################
# Diameter Frame
# #############################################################################################################
dia_frame = FCFrame()
self.editor_vbox.addWidget(dia_frame)
dia_grid = GLay(v_spacing=5, h_spacing=3, c_stretch=[0, 1, 0])
dia_frame.setLayout(dia_grid)
# Dia Value
self.dia_lbl = FCLabel('%s:' % _("Value"))
self.dia_entry = NumericalEvalEntry(border_color='#0069A9')
self.dia_entry.setDisabled(True)
self.dia_unit = FCLabel('%s' % 'mm')
dia_grid.addWidget(self.dia_lbl, 0, 0)
dia_grid.addWidget(self.dia_entry, 0, 1)
dia_grid.addWidget(self.dia_unit, 0, 2)
# Position
self.pos_lbl = FCLabel('%s' % _("Position"), bold=True, color='red')
self.editor_vbox.addWidget(self.pos_lbl)
# #############################################################################################################
# Position Frame
# #############################################################################################################
pos_frame = FCFrame()
self.editor_vbox.addWidget(pos_frame)
pos_grid = GLay(v_spacing=5, h_spacing=3)
pos_frame.setLayout(pos_grid)
# X Pos
self.x_lbl = FCLabel('%s:' % _("X"))
self.x_entry = FCDoubleSpinner()
self.x_entry.set_precision(self.decimals)
self.x_entry.set_range(-10000.0000, 10000.0000)
pos_grid.addWidget(self.x_lbl, 2, 0)
pos_grid.addWidget(self.x_entry, 2, 1)
# Y Pos
self.y_lbl = FCLabel('%s:' % _("Y"))
self.y_entry = FCDoubleSpinner()
self.y_entry.set_precision(self.decimals)
self.y_entry.set_range(-10000.0000, 10000.0000)
pos_grid.addWidget(self.y_lbl, 4, 0)
pos_grid.addWidget(self.y_entry, 4, 1)
# Parameters
self.slot_label = FCLabel('%s' % _("Parameters"), bold=True, color='purple')
self.slot_label.setToolTip(
_("Parameters for adding a slot (hole with oval shape)\n"
"either single or as an part of an array.")
)
self.editor_vbox.addWidget(self.slot_label)
# #############################################################################################################
# ################################### Parameter Frame #########################################################
# #############################################################################################################
self.par_frame = FCFrame()
self.editor_vbox.addWidget(self.par_frame)
par_grid = GLay(v_spacing=5, h_spacing=3)
self.par_frame.setLayout(par_grid)
# Slot length
self.slot_length_label = FCLabel('%s:' % _('Length'))
self.slot_length_label.setToolTip(
_("Length. The length of the slot.")
)
self.slot_length_entry = FCDoubleSpinner(policy=False)
self.slot_length_entry.set_precision(self.decimals)
self.slot_length_entry.setSingleStep(0.1)
self.slot_length_entry.setRange(0.0000, 10000.0000)
par_grid.addWidget(self.slot_length_label, 2, 0)
par_grid.addWidget(self.slot_length_entry, 2, 1)
# Slot direction
self.slot_axis_label = FCLabel('%s:' % _('Direction'))
self.slot_axis_label.setToolTip(
_("Direction on which the slot is oriented:\n"
"- 'X' - horizontal axis \n"
"- 'Y' - vertical axis or \n"
"- 'Angle' - a custom angle for the slot inclination")
)
self.slot_axis_radio = RadioSet([{'label': _('X'), 'value': 'X'},
{'label': _('Y'), 'value': 'Y'},
{'label': _('Angle'), 'value': 'A'}])
par_grid.addWidget(self.slot_axis_label, 4, 0)
par_grid.addWidget(self.slot_axis_radio, 4, 1)
# Slot custom angle
self.slot_angle_label = FCLabel('%s:' % _('Angle'))
self.slot_angle_label.setToolTip(
_("Angle at which the slot is placed.\n"
"The precision is of max 2 decimals.\n"
"Min value is: -360.00 degrees.\n"
"Max value is: 360.00 degrees.")
)
self.slot_angle_spinner = FCDoubleSpinner(policy=False)
self.slot_angle_spinner.set_precision(self.decimals)
self.slot_angle_spinner.setWrapping(True)
self.slot_angle_spinner.setRange(-360.00, 360.00)
self.slot_angle_spinner.setSingleStep(1.0)
par_grid.addWidget(self.slot_angle_label, 6, 0)
par_grid.addWidget(self.slot_angle_spinner, 6, 1)
# #############################################################################################################
# Projection Frame
# #############################################################################################################
pro_frame = FCFrame()
self.editor_vbox.addWidget(pro_frame)
pro_grid = GLay(v_spacing=5, h_spacing=3, c_stretch=[0, 1, 0])
pro_frame.setLayout(pro_grid)
# Project distance
self.project_line_lbl = FCLabel('%s:' % _("Projection"))
self.project_line_lbl.setToolTip(
_("Length of the current segment/move.")
)
self.project_line_entry = NumericalEvalEntry(border_color='#0069A9')
pro_grid.addWidget(self.project_line_lbl, 0, 0)
pro_grid.addWidget(self.project_line_entry, 0, 1)
self.clear_btn = QtWidgets.QToolButton()
self.clear_btn.setIcon(QtGui.QIcon(self.ed_class.app.resource_location + '/trash32.png'))
pro_grid.addWidget(self.clear_btn, 0, 2)
self.add_btn = FCButton(_("Add"))
self.add_btn.setIcon(QtGui.QIcon(self.ed_class.app.resource_location + '/plus32.png'))
self.editor_vbox.addWidget(self.add_btn)
GLay.set_common_column_size([dia_grid, par_grid, pos_grid, pro_grid], 0)
self.layout.addStretch(1)
# Signals
self.slot_axis_radio.activated_custom.connect(self.on_slot_angle_radio)
def on_slot_angle_radio(self):
val = self.slot_axis_radio.get_value()
if val == 'A':
self.slot_angle_spinner.setEnabled(True)
self.slot_angle_label.setEnabled(True)
else:
self.slot_angle_spinner.setEnabled(False)
self.slot_angle_label.setEnabled(False)

View File

@@ -4047,8 +4047,7 @@ class MainGUI(QtWidgets.QMainWindow):
and self.app.exc_editor.active_tool.drill_array_tool.length != 0.0: and self.app.exc_editor.active_tool.drill_array_tool.length != 0.0:
pass pass
elif self.app.exc_editor.active_tool.name == 'slot_add' \ elif self.app.exc_editor.active_tool.name == 'slot_add' \
and self.app.exc_editor.active_tool.slot_tool.x != 0.0 \ and self.app.exc_editor.active_tool.slot_tool.length != 0.0 :
and self.app.exc_editor.active_tool.slot_tool.y != 0.0:
pass pass
elif self.app.exc_editor.active_tool.name == 'slot_array' \ elif self.app.exc_editor.active_tool.name == 'slot_array' \
and self.app.exc_editor.active_tool.slot_array_tool.length != 0.0 \ and self.app.exc_editor.active_tool.slot_array_tool.length != 0.0 \

View File

@@ -849,10 +849,10 @@ class ExcellonObject(FlatCAMObj, Excellon):
for slot in self.tools[tool]['slots']: for slot in self.tools[tool]['slots']:
if form == 'dec': if form == 'dec':
try: try:
start_slot_x = slot.x * factor start_slot_x = slot[0].x * factor
start_slot_y = slot.y * factor start_slot_y = slot[0].y * factor
stop_slot_x = slot.x * factor stop_slot_x = slot[1].x * factor
stop_slot_y = slot.y * factor stop_slot_y = slot[1].y * factor
if slot_type == 'routing': if slot_type == 'routing':
excellon_code += "G00X{:.{dec}f}Y{:.{dec}f}\nM15\n".format(start_slot_x, excellon_code += "G00X{:.{dec}f}Y{:.{dec}f}\nM15\n".format(start_slot_x,
start_slot_y, start_slot_y,
@@ -868,10 +868,10 @@ class ExcellonObject(FlatCAMObj, Excellon):
self.app.log.error('ExcellonObject.export_excellon() slots "dec" -> %s' % str(err)) self.app.log.error('ExcellonObject.export_excellon() slots "dec" -> %s' % str(err))
elif e_zeros == 'LZ': elif e_zeros == 'LZ':
try: try:
start_slot_x = slot.x * factor start_slot_x = slot[0].x * factor
start_slot_y = slot.y * factor start_slot_y = slot[0].y * factor
stop_slot_x = slot.x * factor stop_slot_x = slot[1].x * factor
stop_slot_y = slot.y * factor stop_slot_y = slot[1].y * factor
start_slot_x_formatted = "{:.{dec}f}".format(start_slot_x, dec=fract).replace('.', '') start_slot_x_formatted = "{:.{dec}f}".format(start_slot_x, dec=fract).replace('.', '')
start_slot_y_formatted = "{:.{dec}f}".format(start_slot_y, dec=fract).replace('.', '') start_slot_y_formatted = "{:.{dec}f}".format(start_slot_y, dec=fract).replace('.', '')
@@ -911,10 +911,10 @@ class ExcellonObject(FlatCAMObj, Excellon):
self.app.log.error('ExcellonObject.export_excellon() slots "LZ" -> %s' % str(err)) self.app.log.error('ExcellonObject.export_excellon() slots "LZ" -> %s' % str(err))
else: else:
try: try:
start_slot_x = slot.x * factor start_slot_x = slot[0].x * factor
start_slot_y = slot.y * factor start_slot_y = slot[0].y * factor
stop_slot_x = slot.x * factor stop_slot_x = slot[1].x * factor
stop_slot_y = slot.y * factor stop_slot_y = slot[1].y * factor
length = whole + fract length = whole + fract
start_slot_x_formatted = "{:.{dec}f}".format(start_slot_x, dec=fract).replace('.', '') start_slot_x_formatted = "{:.{dec}f}".format(start_slot_x, dec=fract).replace('.', '')