From 06f6491472ad13c95e2809d19003f26bbd519085 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Sat, 7 Nov 2020 05:39:37 +0200 Subject: [PATCH] - In Gerber Editor upgraded the UI - in Gerber Editor made sure that trying to add a Circular Pad array with null radius will fail - in Gerber Editor when the radius is zero the utility geometry is deleted - in Excellon Editor made sure that trying to add a Circular Drill/Slot array with null radius will fail - in Excellon Editor when the radius is zero the utility geometry is deleted --- CHANGELOG.md | 5 + appEditors/AppExcEditor.py | 107 ++++++++----- appEditors/AppGerberEditor.py | 277 +++++++++++++++++++++------------- 3 files changed, 248 insertions(+), 141 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0243929f..2dd4b338 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,11 @@ CHANGELOG for FlatCAM beta 7.11.2020 - fixed a small issue in Excellon Editor that reset the delta coordinates on right mouse button click too, which was incorrect. Only left mouse button click should reset the delta coordinates. +- In Gerber Editor upgraded the UI +- in Gerber Editor made sure that trying to add a Circular Pad array with null radius will fail +- in Gerber Editor when the radius is zero the utility geometry is deleted +- in Excellon Editor made sure that trying to add a Circular Drill/Slot array with null radius will fail +- in Excellon Editor when the radius is zero the utility geometry is deleted 6.11.2020 diff --git a/appEditors/AppExcEditor.py b/appEditors/AppExcEditor.py index 5ef96de3..381bc6f5 100644 --- a/appEditors/AppExcEditor.py +++ b/appEditors/AppExcEditor.py @@ -330,7 +330,7 @@ class DrillArray(FCShapeTool): self.selected_dia = None self.drill_axis = 'X' - self.drill_array = 0 # 'linear' + self.drill_array = 'linear' # 'linear' self.drill_array_size = None self.drill_pitch = None self.drill_linear_angle = None @@ -382,7 +382,7 @@ class DrillArray(FCShapeTool): def click(self, point): - if self.drill_array == 0: # 'Linear' + if self.drill_array == 'linear': # 'Linear' self.make() return else: @@ -405,7 +405,7 @@ class DrillArray(FCShapeTool): def utility_geometry(self, data=None, static=None): self.drill_axis = self.draw_app.ui.drill_axis_radio.get_value() self.drill_direction = self.draw_app.ui.drill_array_dir_radio.get_value() - self.drill_array = self.draw_app.ui.array_type_combo.get_value() + self.drill_array = self.draw_app.ui.array_type_radio.get_value() try: self.drill_array_size = int(self.draw_app.ui.drill_array_size_entry.get_value()) try: @@ -421,7 +421,7 @@ class DrillArray(FCShapeTool): (_("The value is mistyped. Check the value"), str(e))) return - if self.drill_array == 0: # 'Linear' + if self.drill_array == 'linear': # 'Linear' if data[0] is None and data[1] is None: dx = self.draw_app.x dy = self.draw_app.y @@ -454,7 +454,7 @@ class DrillArray(FCShapeTool): self.last_dx = dx self.last_dy = dy return DrawToolUtilityShape(geo_list) - elif self.drill_array == 1: # 'Circular' + elif self.drill_array == 'circular': # 'Circular' if data[0] is None and data[1] is None: cdx = self.draw_app.x cdy = self.draw_app.y @@ -469,6 +469,9 @@ class DrillArray(FCShapeTool): except Exception: radius = 0 + if radius == 0: + self.draw_app.delete_utility_geometry() + if len(self.pt) >= 1 and radius > 0: try: if cdx < self.origin[0]: @@ -553,7 +556,7 @@ class DrillArray(FCShapeTool): self.draw_app.current_storage = self.draw_app.storage_dict[self.selected_dia] - if self.drill_array == 0: # 'Linear' + if self.drill_array == 'linear': # 'Linear' for item in range(self.drill_array_size): if self.drill_axis == 'X': geo = self.util_shape(((self.points[0] + (self.drill_pitch * item)), self.points[1])) @@ -575,6 +578,12 @@ class DrillArray(FCShapeTool): return radius = distance(self.destination, self.origin) + if radius == 0: + self.draw_app.app.inform.emit('[ERROR_NOTCL] %s' % _("Failed.")) + self.draw_app.delete_utility_geometry() + self.draw_app.select_tool('drill_select') + return + if self.destination[0] < self.origin[0]: radius = -radius initial_angle = math.asin((self.destination[1] - self.origin[1]) / radius) @@ -879,7 +888,7 @@ class SlotArray(FCShapeTool): self.radius = float(self.selected_dia / 2.0) self.slot_axis = 'X' - self.slot_array = 0 # 'linear' + self.slot_array = 'linear' # 'linear' self.slot_array_size = None self.slot_pitch = None self.slot_linear_angle = None @@ -910,7 +919,7 @@ class SlotArray(FCShapeTool): def click(self, point): - if self.slot_array == 0: # 'Linear' + if self.slot_array == 'linear': # 'Linear' self.make() return else: # 'Circular' @@ -933,7 +942,7 @@ class SlotArray(FCShapeTool): def utility_geometry(self, data=None, static=None): self.slot_axis = self.draw_app.ui.slot_array_axis_radio.get_value() self.slot_direction = self.draw_app.ui.slot_array_direction_radio.get_value() - self.slot_array = self.draw_app.ui.slot_array_type_combo.get_value() + self.slot_array = self.draw_app.ui.slot_array_type_radio.get_value() try: self.slot_array_size = int(self.draw_app.ui.slot_array_size_entry.get_value()) try: @@ -948,7 +957,7 @@ class SlotArray(FCShapeTool): self.draw_app.app.inform.emit('[ERROR_NOTCL] %s' % _("The value is mistyped. Check the value.")) return - if self.slot_array == 0: # 'Linear' + if self.slot_array == 'linear': # 'Linear' if data[0] is None and data[1] is None: dx = self.draw_app.x dy = self.draw_app.y @@ -999,6 +1008,9 @@ class SlotArray(FCShapeTool): except Exception: radius = 0 + if radius == 0: + self.draw_app.delete_utility_geometry() + if len(self.pt) >= 1 and radius > 0: try: if cdx < self.origin[0]: @@ -1166,7 +1178,7 @@ class SlotArray(FCShapeTool): self.draw_app.current_storage = self.draw_app.storage_dict[self.selected_dia] - if self.slot_array == 0: # 'Linear' + if self.slot_array == 'linear': # 'Linear' for item in range(self.slot_array_size): if self.slot_axis == 'X': geo = self.util_shape(((self.points[0] + (self.slot_pitch * item)), self.points[1])) @@ -1207,6 +1219,12 @@ class SlotArray(FCShapeTool): # self.geometry.append(DrawToolShape(geo)) radius = distance(self.destination, self.origin) + if radius == 0: + self.draw_app.app.inform.emit('[ERROR_NOTCL] %s' % _("Failed.")) + self.draw_app.delete_utility_geometry() + self.draw_app.select_tool('drill_select') + return + if self.destination[0] < self.origin[0]: radius = -radius initial_angle = math.asin((self.destination[1] - self.origin[1]) / radius) @@ -1862,8 +1880,8 @@ class AppExcEditor(QtCore.QObject): # self.ui.tools_table_exc.selectionModel().currentChanged.connect(self.on_row_selected) self.ui.tools_table_exc.cellPressed.connect(self.on_row_selected) - self.ui.array_type_combo.currentIndexChanged.connect(self.on_array_type_combo) - self.ui.slot_array_type_combo.currentIndexChanged.connect(self.on_slot_array_type_combo) + self.ui.array_type_radio.activated_custom.connect(self.on_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.slot_axis_radio.activated_custom.connect(self.on_slot_angle_radio) @@ -1976,8 +1994,10 @@ class AppExcEditor(QtCore.QObject): # according to the set Preferences already loaded self.on_slot_angle_radio() - self.on_array_type_combo() - self.on_slot_array_type_combo() + self.ui.array_type_radio.set_value('linear') + self.on_array_type_radio(val=self.ui.array_type_radio.get_value()) + self.ui.slot_array_type_radio.set_value('linear') + self.on_slot_array_type_radio(val=self.ui.slot_array_type_radio.get_value()) self.on_linear_angle_radio() self.on_slot_array_linear_angle_radio() @@ -3160,7 +3180,7 @@ class AppExcEditor(QtCore.QObject): self.pos = self.app.geo_editor.snap(self.pos[0], self.pos[1]) else: self.pos = (self.pos[0], self.pos[1]) - + self.app.ui.rel_position_label.setText("Dx: %.4f   Dy: " "%.4f    " % (0, 0)) @@ -3755,8 +3775,8 @@ class AppExcEditor(QtCore.QObject): if unsel_shape in self.selected: self.selected.remove(unsel_shape) - def on_array_type_combo(self): - if self.ui.array_type_combo.currentIndex() == 0: + def on_array_type_radio(self, val): + if val == 'linear': self.ui.array_circular_frame.hide() self.ui.array_linear_frame.show() else: @@ -3765,8 +3785,8 @@ class AppExcEditor(QtCore.QObject): self.ui.array_linear_frame.hide() self.app.inform.emit(_("Click on the circular array Center position")) - def on_slot_array_type_combo(self): - if self.ui.slot_array_type_combo.currentIndex() == 0: + def on_slot_array_type_radio(self, val): + if val == 'linear': self.ui.slot_array_circular_frame.hide() self.ui.slot_array_linear_frame.show() else: @@ -3897,11 +3917,11 @@ class AppExcEditorUI: self.ui_vertical_lay.setContentsMargins(0, 0, 0, 0) self.drills_frame.setLayout(self.ui_vertical_lay) - # ## Page Title box (spacing between children) + # Page Title box (spacing between children) self.title_box = QtWidgets.QHBoxLayout() self.ui_vertical_lay.addLayout(self.title_box) - # ## Page Title + # Page Title pixmap = QtGui.QPixmap(self.app.resource_location + '/flatcam_icon32.png') self.icon = FCLabel() self.icon.setPixmap(pixmap) @@ -3912,17 +3932,18 @@ class AppExcEditorUI: self.title_box.addWidget(self.icon, stretch=0) self.title_box.addWidget(self.title_label, stretch=1) - # ## Object name + # Object name box self.name_box = QtWidgets.QHBoxLayout() self.ui_vertical_lay.addLayout(self.name_box) + # Object Name name_label = FCLabel(_("Name:")) self.name_entry = FCEntry() self.name_box.addWidget(name_label) self.name_box.addWidget(self.name_entry) - # ### Tools Drills ## ## + # Tools Drills Table Title self.tools_table_label = FCLabel("%s" % _('Tools Table')) self.tools_table_label.setToolTip( _("Tools in this Excellon object\n" @@ -3930,7 +3951,9 @@ class AppExcEditorUI: ) self.ui_vertical_lay.addWidget(self.tools_table_label) - # Drills TABLE + # ############################################################################################################# + # ########################################## Drills TABLE ##################################################### + # ############################################################################################################# self.tools_table_exc = FCTable() self.tools_table_exc.setColumnCount(4) self.tools_table_exc.setHorizontalHeaderLabels(['#', _('Diameter'), 'D', 'S']) @@ -3957,7 +3980,7 @@ class AppExcEditorUI: separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) self.ui_vertical_lay.addWidget(separator_line) - # ### Add a new Tool ## ## + # Add a new Tool self.addtool_label = FCLabel('%s' % _('Add/Delete Tool')) self.addtool_label.setToolTip( _("Add/Delete a tool to the tool list\n" @@ -4089,16 +4112,20 @@ class AppExcEditorUI: _("Add an array of drills (linear or circular array)") ) - # Special Combo - it works by indexes as opposed to the items Text - self.array_type_combo = FCComboBox2() - self.array_type_combo.setToolTip( + self.array_grid.addWidget(self.drill_array_label, 0, 0, 1, 2) + + # Array Type + array_type_lbl = FCLabel('%s:' % _("Type")) + array_type_lbl.setToolTip( _("Select the type of drills array to create.\n" "It can be Linear X(Y) or Circular") ) - self.array_type_combo.addItems([_("Linear"), _("Circular")]) - self.array_grid.addWidget(self.drill_array_label, 0, 0, 1, 2) - self.array_grid.addWidget(self.array_type_combo, 2, 0, 1, 2) + self.array_type_radio = RadioSet([{'label': _('Linear'), 'value': 'linear'}, + {'label': _('Circular'), 'value': 'circular'}]) + + self.array_grid.addWidget(array_type_lbl, 2, 0) + self.array_grid.addWidget(self.array_type_radio, 2, 1) # Set the number of drill holes in the drill array self.drill_array_size_label = FCLabel('%s:' % _('Number')) @@ -4289,9 +4316,6 @@ class AppExcEditorUI: # ############################################################################################################# # ##################################### ADDING SLOT ARRAY #################################################### # ############################################################################################################# - # add a frame and inside add a vertical box layout. Inside this vbox layout I add - # all the add slot widgets - # this way I can hide/show the frame self.slot_array_frame = QtWidgets.QFrame() self.slot_array_frame.setContentsMargins(0, 0, 0, 0) self.ui_vertical_lay.addWidget(self.slot_array_frame) @@ -4310,15 +4334,18 @@ class AppExcEditorUI: self.slot_array_grid.addWidget(self.slot_array_label, 0, 0, 1, 2) - # Special type of Combobox that get_value() by indexes and not by items text - self.slot_array_type_combo = FCComboBox2() - self.slot_array_type_combo.setToolTip( + # Array Type + array_type_lbl = FCLabel('%s:' % _("Type")) + array_type_lbl.setToolTip( _("Select the type of slot array to create.\n" "It can be Linear X(Y) or Circular") ) - self.slot_array_type_combo.addItems([_("Linear"), _("Circular")]) - self.slot_array_grid.addWidget(self.slot_array_type_combo, 2, 0, 1, 2) + self.slot_array_type_radio = RadioSet([{'label': _('Linear'), 'value': 'linear'}, + {'label': _('Circular'), 'value': 'circular'}]) + + self.slot_array_grid.addWidget(array_type_lbl, 2, 0) + self.slot_array_grid.addWidget(self.slot_array_type_radio, 2, 1) # Set the number of slot holes in the slot array self.slot_array_size_label = FCLabel('%s:' % _('Number')) diff --git a/appEditors/AppGerberEditor.py b/appEditors/AppGerberEditor.py index 909c2260..418197cc 100644 --- a/appEditors/AppGerberEditor.py +++ b/appEditors/AppGerberEditor.py @@ -455,7 +455,7 @@ class PadArrayEditorGrb(ShapeToolEditorGrb): self.selected_size = None self.pad_axis = 'X' - self.pad_array = 0 # 'linear' + self.pad_array = 'linear' # 'linear' self.pad_array_size = None self.pad_pitch = None self.pad_linear_angle = None @@ -487,7 +487,7 @@ class PadArrayEditorGrb(ShapeToolEditorGrb): def click(self, point): - if self.draw_app.ui.array_type_combo.get_value() == 0: # 'Linear' + if self.draw_app.ui.array_type_radio.get_value() == 0: # 'Linear' self.make() return else: @@ -522,7 +522,7 @@ class PadArrayEditorGrb(ShapeToolEditorGrb): self.pad_axis = self.draw_app.ui.pad_axis_radio.get_value() self.pad_direction = self.draw_app.ui.pad_direction_radio.get_value() - self.pad_array = self.draw_app.ui.array_type_combo.get_value() + self.pad_array = self.draw_app.ui.array_type_radio.get_value() try: self.pad_array_size = int(self.draw_app.ui.pad_array_size_entry.get_value()) @@ -538,7 +538,7 @@ class PadArrayEditorGrb(ShapeToolEditorGrb): self.draw_app.app.inform.emit('[ERROR_NOTCL] %s' % _("The value is mistyped. Check the value.")) return - if self.pad_array == 0: # 'Linear' + if self.pad_array == 'linear': # 'Linear' if data[0] is None and data[1] is None: dx = self.draw_app.x dy = self.draw_app.y @@ -582,7 +582,7 @@ class PadArrayEditorGrb(ShapeToolEditorGrb): self.last_dx = dx self.last_dy = dy return DrawToolUtilityShape(geo_el_list) - elif self.pad_array == 1: # 'Circular' + elif self.pad_array == 'circular': # 'Circular' if data[0] is None and data[1] is None: cdx = self.draw_app.x cdy = self.draw_app.y @@ -597,6 +597,9 @@ class PadArrayEditorGrb(ShapeToolEditorGrb): except Exception: radius = 0 + if radius == 0: + self.draw_app.delete_utility_geometry() + if len(self.pt) >= 1 and radius > 0: try: if cdx < self.origin[0]: @@ -773,7 +776,7 @@ class PadArrayEditorGrb(ShapeToolEditorGrb): self.draw_app.current_storage = self.storage_obj - if self.pad_array == 0: # 'Linear' + if self.pad_array == 'linear': # 'Linear' for item in range(self.pad_array_size): if self.pad_axis == 'X': geo = self.util_shape(((self.points[0] + (self.pad_pitch * item)), self.points[1])) @@ -794,6 +797,12 @@ class PadArrayEditorGrb(ShapeToolEditorGrb): return radius = distance(self.destination, self.origin) + if radius == 0: + self.draw_app.app.inform.emit('[ERROR_NOTCL] %s' % _("Failed.")) + self.draw_app.delete_utility_geometry() + self.draw_app.select_tool('select') + return + if self.destination[0] < self.origin[0]: radius = -radius initial_angle = math.asin((self.destination[1] - self.origin[1]) / radius) @@ -2101,7 +2110,7 @@ class MarkEditorGrb(ShapeToolEditorGrb): self.draw_app.ui.ma_tool_frame.show() # clear previous marking - self.draw_app.ui.ma_annotation.clear(update=True) + self.draw_app.ma_annotation.clear(update=True) try: self.draw_app.ui.ma_threshold_button.clicked.disconnect() @@ -2911,7 +2920,7 @@ class AppGerberEditor(QtCore.QObject): self.ui.delaperture_btn.clicked.connect(self.on_aperture_delete) self.ui.apertures_table.cellPressed.connect(self.on_row_selected) - self.ui.array_type_combo.currentIndexChanged.connect(self.on_array_type_combo) + self.ui.array_type_radio.activated_custom.connect(self.on_array_type_radio) self.ui.pad_axis_radio.activated_custom.connect(self.on_linear_angle_radio) self.ui.exit_editor_button.clicked.connect(lambda: self.app.editor2object()) @@ -2993,12 +3002,20 @@ class AppGerberEditor(QtCore.QObject): self.ui.aptype_cb.set_value(self.app.defaults["gerber_editor_newtype"]) self.ui.apdim_entry.set_value(self.app.defaults["gerber_editor_newdim"]) + # PAD Array + self.ui.array_type_radio.set_value('linear') # Linear + self.on_array_type_radio(val=self.ui.array_type_radio.get_value()) self.ui.pad_array_size_entry.set_value(int(self.app.defaults["gerber_editor_array_size"])) + # linear array + self.ui.pad_axis_radio.set_value('X') + self.on_linear_angle_radio(val=self.ui.pad_axis_radio.get_value()) self.ui.pad_axis_radio.set_value(self.app.defaults["gerber_editor_lin_axis"]) self.ui.pad_pitch_entry.set_value(float(self.app.defaults["gerber_editor_lin_pitch"])) self.ui.linear_angle_spinner.set_value(self.app.defaults["gerber_editor_lin_angle"]) + # circular array + self.ui.pad_direction_radio.set_value('CW') self.ui.pad_direction_radio.set_value(self.app.defaults["gerber_editor_circ_dir"]) self.ui.pad_angle_entry.set_value(float(self.app.defaults["gerber_editor_circ_angle"])) @@ -4882,18 +4899,41 @@ class AppGerberEditor(QtCore.QObject): if geo_el in self.selected: self.selected.remove(geo_el) - def on_array_type_combo(self): - if self.ui.array_type_combo.currentIndex() == 0: - self.ui.array_circular_frame.hide() - self.ui.array_linear_frame.show() + def on_array_type_radio(self, val): + if val == 'linear': + self.ui.pad_axis_label.show() + self.ui.pad_axis_radio.show() + self.ui.pad_pitch_label.show() + self.ui.pad_pitch_entry.show() + self.ui.linear_angle_label.show() + self.ui.linear_angle_spinner.show() + self.ui.lin_separator_line.show() + + self.ui.pad_direction_label.hide() + self.ui.pad_direction_radio.hide() + self.ui.pad_angle_label.hide() + self.ui.pad_angle_entry.hide() + self.ui.circ_separator_line.hide() else: self.delete_utility_geometry() - self.ui.array_circular_frame.show() - self.ui.array_linear_frame.hide() + + self.ui.pad_axis_label.hide() + self.ui.pad_axis_radio.hide() + self.ui.pad_pitch_label.hide() + self.ui.pad_pitch_entry.hide() + self.ui.linear_angle_label.hide() + self.ui.linear_angle_spinner.hide() + self.ui.lin_separator_line.hide() + + self.ui.pad_direction_label.show() + self.ui.pad_direction_radio.show() + self.ui.pad_angle_label.show() + self.ui.pad_angle_entry.show() + self.ui.circ_separator_line.show() + self.app.inform.emit(_("Click on the circular array Center position")) - def on_linear_angle_radio(self): - val = self.ui.pad_axis_radio.get_value() + def on_linear_angle_radio(self, val): if val == 'A': self.ui.linear_angle_spinner.show() self.ui.linear_angle_label.show() @@ -5169,9 +5209,9 @@ class AppGerberEditorUI: self.custom_box = QtWidgets.QVBoxLayout() layout.addLayout(self.custom_box) - # ######################### - # ### Gerber Apertures #### - # ######################### + # ############################################################################################################# + # #################################### Gerber Apertures Table ################################################# + # ############################################################################################################# self.apertures_table_label = FCLabel('%s:' % _('Apertures')) self.apertures_table_label.setToolTip( _("Apertures Table for the Gerber Object.") @@ -5202,8 +5242,10 @@ class AppGerberEditorUI: " - (width, height) for R, O type.\n" " - (dia, nVertices) for P type")) - self.empty_label = FCLabel('') - self.custom_box.addWidget(self.empty_label) + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + self.custom_box.addWidget(separator_line) # add a frame and inside add a vertical box layout. Inside this vbox layout I add all the Apertures widgets # this way I can hide/show the frame @@ -5214,23 +5256,33 @@ class AppGerberEditorUI: self.apertures_box.setContentsMargins(0, 0, 0, 0) self.apertures_frame.setLayout(self.apertures_box) - # # ## Add/Delete an new Aperture ## ## - + # ############################################################################################################# + # ############################ Add/Delete an new Aperture ##################################################### + # ############################################################################################################# grid1 = QtWidgets.QGridLayout() self.apertures_box.addLayout(grid1) grid1.setColumnStretch(0, 0) grid1.setColumnStretch(1, 1) + # Title + apadd_del_lbl = FCLabel('%s:' % _('Add/Delete Aperture')) + apadd_del_lbl.setToolTip( + _("Add/Delete an aperture in the aperture table") + ) + grid1.addWidget(apadd_del_lbl, 0, 0, 1, 2) + + # Aperture Code apcode_lbl = FCLabel('%s:' % _('Aperture Code')) apcode_lbl.setToolTip(_("Code for the new aperture")) - grid1.addWidget(apcode_lbl, 1, 0) self.apcode_entry = FCSpinner() - self.apcode_entry.set_range(0, 999) + self.apcode_entry.set_range(0, 1000) self.apcode_entry.setWrapping(True) + grid1.addWidget(apcode_lbl, 1, 0) grid1.addWidget(self.apcode_entry, 1, 1) + # Aperture Size apsize_lbl = FCLabel('%s' % _('Aperture Size:')) apsize_lbl.setToolTip( _("Size for the new aperture.\n" @@ -5239,14 +5291,15 @@ class AppGerberEditorUI: "calculated as:\n" "sqrt(width**2 + height**2)") ) - grid1.addWidget(apsize_lbl, 2, 0) self.apsize_entry = FCDoubleSpinner() self.apsize_entry.set_precision(self.decimals) - self.apsize_entry.set_range(0.0, 9999) + self.apsize_entry.set_range(0.0, 10000.0000) + grid1.addWidget(apsize_lbl, 2, 0) grid1.addWidget(self.apsize_entry, 2, 1) + # Aperture Type aptype_lbl = FCLabel('%s:' % _('Aperture Type')) aptype_lbl.setToolTip( _("Select the type of new aperture. Can be:\n" @@ -5254,31 +5307,34 @@ class AppGerberEditorUI: "R = rectangular\n" "O = oblong") ) - grid1.addWidget(aptype_lbl, 3, 0) self.aptype_cb = FCComboBox() self.aptype_cb.addItems(['C', 'R', 'O']) + + grid1.addWidget(aptype_lbl, 3, 0) grid1.addWidget(self.aptype_cb, 3, 1) + # Aperture Dimensions self.apdim_lbl = FCLabel('%s:' % _('Aperture Dim')) self.apdim_lbl.setToolTip( _("Dimensions for the new aperture.\n" "Active only for rectangular apertures (type R).\n" "The format is (width, height)") ) - grid1.addWidget(self.apdim_lbl, 4, 0) self.apdim_entry = EvalEntry2() + + grid1.addWidget(self.apdim_lbl, 4, 0) grid1.addWidget(self.apdim_entry, 4, 1) - apadd_del_lbl = FCLabel('%s:' % _('Add/Delete Aperture')) - apadd_del_lbl.setToolTip( - _("Add/Delete an aperture in the aperture table") - ) - self.apertures_box.addWidget(apadd_del_lbl) + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + grid1.addWidget(separator_line, 6, 0, 1, 2) + # Aperture Buttons hlay_ad = QtWidgets.QHBoxLayout() - self.apertures_box.addLayout(hlay_ad) + grid1.addLayout(hlay_ad, 8, 0, 1, 2) self.addaperture_btn = FCButton(_('Add')) self.addaperture_btn.setIcon(QtGui.QIcon(self.app.resource_location + '/plus16.png')) @@ -5294,9 +5350,9 @@ class AppGerberEditorUI: hlay_ad.addWidget(self.addaperture_btn) hlay_ad.addWidget(self.delaperture_btn) - # ################### - # ### BUFFER TOOL ### - # ################### + # ############################################################################################################# + # ############################################ BUFFER TOOL #################################################### + # ############################################################################################################# self.buffer_tool_frame = QtWidgets.QFrame() self.buffer_tool_frame.setContentsMargins(0, 0, 0, 0) self.custom_box.addWidget(self.buffer_tool_frame) @@ -5322,6 +5378,8 @@ class AppGerberEditorUI: self.buffer_distance_entry.set_range(-10000.0000, 10000.0000) buf_form_layout.addRow('%s:' % _("Buffer distance"), self.buffer_distance_entry) + + # Buffer Corner self.buffer_corner_lbl = FCLabel('%s:' % _("Buffer corner")) self.buffer_corner_lbl.setToolTip( _("There are 3 types of corners:\n" @@ -5335,6 +5393,11 @@ class AppGerberEditorUI: self.buffer_corner_cb.addItem(_("Beveled")) buf_form_layout.addRow(self.buffer_corner_lbl, self.buffer_corner_cb) + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + buf_form_layout.addRow(separator_line) + # Buttons hlay_buf = QtWidgets.QHBoxLayout() self.buffer_tools_box.addLayout(hlay_buf) @@ -5343,9 +5406,9 @@ class AppGerberEditorUI: self.buffer_button.setIcon(QtGui.QIcon(self.app.resource_location + '/buffer16-2.png')) hlay_buf.addWidget(self.buffer_button) - # ################## - # ### SCALE TOOL ### - # ################## + # ############################################################################################################# + # ########################################### SCALE TOOL ###################################################### + # ############################################################################################################# self.scale_tool_frame = QtWidgets.QFrame() self.scale_tool_frame.setContentsMargins(0, 0, 0, 0) self.custom_box.addWidget(self.scale_tool_frame) @@ -5376,6 +5439,11 @@ class AppGerberEditorUI: scale_form_layout.addRow(self.scale_factor_lbl, self.scale_factor_entry) + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + scale_form_layout.addRow(separator_line) + # Buttons hlay_scale = QtWidgets.QHBoxLayout() self.scale_tools_box.addLayout(hlay_scale) @@ -5384,9 +5452,9 @@ class AppGerberEditorUI: self.scale_button.setIcon(QtGui.QIcon(self.app.resource_location + '/clean32.png')) hlay_scale.addWidget(self.scale_button) - # ###################### - # ### Mark Area TOOL ### - # ###################### + # ############################################################################################################# + # ######################################### Mark Area TOOL #################################################### + # ############################################################################################################# self.ma_tool_frame = QtWidgets.QFrame() self.ma_tool_frame.setContentsMargins(0, 0, 0, 0) self.custom_box.addWidget(self.ma_tool_frame) @@ -5395,6 +5463,11 @@ class AppGerberEditorUI: self.ma_tool_frame.setLayout(self.ma_tools_box) self.ma_tool_frame.hide() + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + self.ma_tools_box.addWidget(separator_line) + # Title ma_title_lbl = FCLabel('%s:' % _('Mark polygons')) ma_title_lbl.setToolTip( @@ -5452,12 +5525,9 @@ class AppGerberEditorUI: ) hlay_ma.addWidget(self.ma_clear_button) - # ###################### - # ### Add Pad Array #### - # ###################### - # add a frame and inside add a vertical box layout. Inside this vbox layout I add - # all the add Pad array widgets - # this way I can hide/show the frame + # ############################################################################################################# + # ######################################### Add Pad Array ##################################################### + # ############################################################################################################# self.array_frame = QtWidgets.QFrame() self.array_frame.setContentsMargins(0, 0, 0, 0) self.custom_box.addWidget(self.array_frame) @@ -5465,48 +5535,57 @@ class AppGerberEditorUI: self.array_box.setContentsMargins(0, 0, 0, 0) self.array_frame.setLayout(self.array_box) - self.emptyarray_label = FCLabel('') - self.array_box.addWidget(self.emptyarray_label) + separator_line = QtWidgets.QFrame() + separator_line.setFrameShape(QtWidgets.QFrame.HLine) + separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + self.array_box.addWidget(separator_line) + array_grid = QtWidgets.QGridLayout() + array_grid.setColumnStretch(0, 0) + array_grid.setColumnStretch(1, 1) + self.array_box.addLayout(array_grid) + + # Title self.padarray_label = FCLabel('%s' % _("Add Pad Array")) self.padarray_label.setToolTip( _("Add an array of pads (linear or circular array)") ) - self.array_box.addWidget(self.padarray_label) + array_grid.addWidget(self.padarray_label, 0, 0, 1, 2) - self.array_type_combo = FCComboBox2() - self.array_type_combo.setToolTip( + # Array Type + array_type_lbl = FCLabel('%s:' % _("Type")) + array_type_lbl.setToolTip( _("Select the type of pads array to create.\n" "It can be Linear X(Y) or Circular") ) - self.array_type_combo.addItems([_("Linear"), _("Circular")]) - self.array_box.addWidget(self.array_type_combo) + self.array_type_radio = RadioSet([{'label': _('Linear'), 'value': 'linear'}, + {'label': _('Circular'), 'value': 'circular'}]) - self.array_form = QtWidgets.QFormLayout() - self.array_box.addLayout(self.array_form) + array_grid.addWidget(array_type_lbl, 2, 0) + array_grid.addWidget(self.array_type_radio, 2, 1) - self.pad_array_size_label = FCLabel('%s:' % _('Nr of pads')) - self.pad_array_size_label.setToolTip( + # Number of Pads in Array + pad_array_size_label = FCLabel('%s:' % _('Nr of pads')) + pad_array_size_label.setToolTip( _("Specify how many pads to be in the array.") ) - self.pad_array_size_label.setMinimumWidth(100) self.pad_array_size_entry = FCSpinner() - self.pad_array_size_entry.set_range(1, 9999) + self.pad_array_size_entry.set_range(1, 10000) - self.array_form.addRow(self.pad_array_size_label, self.pad_array_size_entry) + array_grid.addWidget(pad_array_size_label, 4, 0) + array_grid.addWidget(self.pad_array_size_entry, 4, 1) - self.array_linear_frame = QtWidgets.QFrame() - self.array_linear_frame.setContentsMargins(0, 0, 0, 0) - self.array_box.addWidget(self.array_linear_frame) - self.linear_box = QtWidgets.QVBoxLayout() - self.linear_box.setContentsMargins(0, 0, 0, 0) - self.array_linear_frame.setLayout(self.linear_box) - - self.linear_form = QtWidgets.QFormLayout() - self.linear_box.addLayout(self.linear_form) + # ############################################################################################################# + # ############################ Linear Pad Array ############################################################### + # ############################################################################################################# + self.lin_separator_line = QtWidgets.QFrame() + self.lin_separator_line.setFrameShape(QtWidgets.QFrame.HLine) + self.lin_separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + array_grid.addWidget(self.lin_separator_line, 6, 0, 1, 2) + # Linear Direction self.pad_axis_label = FCLabel('%s:' % _('Direction')) self.pad_axis_label.setToolTip( _("Direction on which the linear array is oriented:\n" @@ -5514,27 +5593,29 @@ class AppGerberEditorUI: "- 'Y' - vertical axis or \n" "- 'Angle' - a custom angle for the array inclination") ) - self.pad_axis_label.setMinimumWidth(100) self.pad_axis_radio = RadioSet([{'label': _('X'), 'value': 'X'}, {'label': _('Y'), 'value': 'Y'}, {'label': _('Angle'), 'value': 'A'}]) - self.pad_axis_radio.set_value('X') - self.linear_form.addRow(self.pad_axis_label, self.pad_axis_radio) + array_grid.addWidget(self.pad_axis_label, 8, 0) + array_grid.addWidget(self.pad_axis_radio, 8, 1) + + # Linear Pitch self.pad_pitch_label = FCLabel('%s:' % _('Pitch')) self.pad_pitch_label.setToolTip( _("Pitch = Distance between elements of the array.") ) - self.pad_pitch_label.setMinimumWidth(100) self.pad_pitch_entry = FCDoubleSpinner() self.pad_pitch_entry.set_precision(self.decimals) self.pad_pitch_entry.set_range(0.0000, 10000.0000) self.pad_pitch_entry.setSingleStep(0.1) - self.linear_form.addRow(self.pad_pitch_label, self.pad_pitch_entry) + array_grid.addWidget(self.pad_pitch_label, 10, 0) + array_grid.addWidget(self.pad_pitch_entry, 10, 1) + # Linear Angle self.linear_angle_label = FCLabel('%s:' % _('Angle')) self.linear_angle_label.setToolTip( _("Angle at which the linear array is placed.\n" @@ -5542,56 +5623,50 @@ class AppGerberEditorUI: "Min value is: -360.00 degrees.\n" "Max value is: 360.00 degrees.") ) - self.linear_angle_label.setMinimumWidth(100) self.linear_angle_spinner = FCDoubleSpinner() self.linear_angle_spinner.set_precision(self.decimals) self.linear_angle_spinner.setRange(-360.00, 360.00) - self.linear_form.addRow(self.linear_angle_label, self.linear_angle_spinner) - self.array_circular_frame = QtWidgets.QFrame() - self.array_circular_frame.setContentsMargins(0, 0, 0, 0) - self.array_box.addWidget(self.array_circular_frame) - self.circular_box = QtWidgets.QVBoxLayout() - self.circular_box.setContentsMargins(0, 0, 0, 0) - self.array_circular_frame.setLayout(self.circular_box) + array_grid.addWidget(self.linear_angle_label, 12, 0) + array_grid.addWidget(self.linear_angle_spinner, 12, 1) + # ############################################################################################################# + # ################################### Circular Pad Array ###################################################### + # ############################################################################################################# + self.circ_separator_line = QtWidgets.QFrame() + self.circ_separator_line.setFrameShape(QtWidgets.QFrame.HLine) + self.circ_separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) + array_grid.addWidget(self.circ_separator_line, 14, 0, 1, 2) + + # Circular Direction self.pad_direction_label = FCLabel('%s:' % _('Direction')) self.pad_direction_label.setToolTip( _("Direction for circular array.\n" "Can be CW = clockwise or CCW = counter clockwise.") ) - self.pad_direction_label.setMinimumWidth(100) - - self.circular_form = QtWidgets.QFormLayout() - self.circular_box.addLayout(self.circular_form) self.pad_direction_radio = RadioSet([{'label': _('CW'), 'value': 'CW'}, {'label': _('CCW'), 'value': 'CCW'}]) - self.pad_direction_radio.set_value('CW') - self.circular_form.addRow(self.pad_direction_label, self.pad_direction_radio) + array_grid.addWidget(self.pad_direction_label, 16, 0) + array_grid.addWidget(self.pad_direction_radio, 16, 1) + + # Circular Angle self.pad_angle_label = FCLabel('%s:' % _('Angle')) self.pad_angle_label.setToolTip( _("Angle at which each element in circular array is placed.") ) - self.pad_angle_label.setMinimumWidth(100) self.pad_angle_entry = FCDoubleSpinner() self.pad_angle_entry.set_precision(self.decimals) self.pad_angle_entry.set_range(-360.00, 360.00) self.pad_angle_entry.setSingleStep(0.1) - self.circular_form.addRow(self.pad_angle_label, self.pad_angle_entry) + array_grid.addWidget(self.pad_angle_label, 18, 0) + array_grid.addWidget(self.pad_angle_entry, 18, 1) - self.array_circular_frame.hide() - - self.linear_angle_spinner.hide() - self.linear_angle_label.hide() - - self.array_frame.hide() self.custom_box.addStretch() - layout.addStretch() # Editor