- Tool Punch Gerber - updated the UI
- Tool Panelize - updated the UI - Tool Extract Drills - updated the UI - Tool QRcode - updated the UI - Tool SolderPaste - updated the UI - Tool DblSided - updated the UI
This commit is contained in:
@@ -35,266 +35,22 @@ class Panelize(AppTool):
|
||||
toolName = _("Panelize PCB")
|
||||
|
||||
def __init__(self, app):
|
||||
self.decimals = app.decimals
|
||||
|
||||
AppTool.__init__(self, app)
|
||||
self.decimals = app.decimals
|
||||
self.app = app
|
||||
|
||||
# ## Title
|
||||
title_label = QtWidgets.QLabel("%s" % self.toolName)
|
||||
title_label.setStyleSheet("""
|
||||
QLabel
|
||||
{
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
""")
|
||||
self.layout.addWidget(title_label)
|
||||
|
||||
self.object_label = QtWidgets.QLabel('<b>%s:</b>' % _("Source Object"))
|
||||
self.object_label.setToolTip(
|
||||
_("Specify the type of object to be panelized\n"
|
||||
"It can be of type: Gerber, Excellon or Geometry.\n"
|
||||
"The selection here decide the type of objects that will be\n"
|
||||
"in the Object combobox.")
|
||||
)
|
||||
|
||||
self.layout.addWidget(self.object_label)
|
||||
|
||||
# Form Layout
|
||||
form_layout_0 = QtWidgets.QFormLayout()
|
||||
self.layout.addLayout(form_layout_0)
|
||||
|
||||
# Type of object to be panelized
|
||||
self.type_obj_combo = FCComboBox()
|
||||
self.type_obj_combo.addItem("Gerber")
|
||||
self.type_obj_combo.addItem("Excellon")
|
||||
self.type_obj_combo.addItem("Geometry")
|
||||
|
||||
self.type_obj_combo.setItemIcon(0, QtGui.QIcon(self.app.resource_location + "/flatcam_icon16.png"))
|
||||
self.type_obj_combo.setItemIcon(1, QtGui.QIcon(self.app.resource_location + "/drill16.png"))
|
||||
self.type_obj_combo.setItemIcon(2, QtGui.QIcon(self.app.resource_location + "/geometry16.png"))
|
||||
|
||||
self.type_object_label = QtWidgets.QLabel('%s:' % _("Object Type"))
|
||||
|
||||
form_layout_0.addRow(self.type_object_label, self.type_obj_combo)
|
||||
|
||||
# Object to be panelized
|
||||
self.object_combo = FCComboBox()
|
||||
self.object_combo.setModel(self.app.collection)
|
||||
self.object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
|
||||
self.object_combo.is_last = True
|
||||
|
||||
self.object_combo.setToolTip(
|
||||
_("Object to be panelized. This means that it will\n"
|
||||
"be duplicated in an array of rows and columns.")
|
||||
)
|
||||
form_layout_0.addRow(self.object_combo)
|
||||
|
||||
# Form Layout
|
||||
form_layout = QtWidgets.QFormLayout()
|
||||
self.layout.addLayout(form_layout)
|
||||
|
||||
# Type of box Panel object
|
||||
self.reference_radio = RadioSet([{'label': _('Object'), 'value': 'object'},
|
||||
{'label': _('Bounding Box'), 'value': 'bbox'}])
|
||||
self.box_label = QtWidgets.QLabel("<b>%s:</b>" % _("Penelization Reference"))
|
||||
self.box_label.setToolTip(
|
||||
_("Choose the reference for panelization:\n"
|
||||
"- Object = the bounding box of a different object\n"
|
||||
"- Bounding Box = the bounding box of the object to be panelized\n"
|
||||
"\n"
|
||||
"The reference is useful when doing panelization for more than one\n"
|
||||
"object. The spacings (really offsets) will be applied in reference\n"
|
||||
"to this reference object therefore maintaining the panelized\n"
|
||||
"objects in sync.")
|
||||
)
|
||||
form_layout.addRow(self.box_label)
|
||||
form_layout.addRow(self.reference_radio)
|
||||
|
||||
# Type of Box Object to be used as an envelope for panelization
|
||||
self.type_box_combo = FCComboBox()
|
||||
self.type_box_combo.addItems([_("Gerber"), _("Geometry")])
|
||||
|
||||
# we get rid of item1 ("Excellon") as it is not suitable for use as a "box" for panelizing
|
||||
# self.type_box_combo.view().setRowHidden(1, True)
|
||||
self.type_box_combo.setItemIcon(0, QtGui.QIcon(self.app.resource_location + "/flatcam_icon16.png"))
|
||||
self.type_box_combo.setItemIcon(1, QtGui.QIcon(self.app.resource_location + "/geometry16.png"))
|
||||
|
||||
self.type_box_combo_label = QtWidgets.QLabel('%s:' % _("Box Type"))
|
||||
self.type_box_combo_label.setToolTip(
|
||||
_("Specify the type of object to be used as an container for\n"
|
||||
"panelization. It can be: Gerber or Geometry type.\n"
|
||||
"The selection here decide the type of objects that will be\n"
|
||||
"in the Box Object combobox.")
|
||||
)
|
||||
form_layout.addRow(self.type_box_combo_label, self.type_box_combo)
|
||||
|
||||
# Box
|
||||
self.box_combo = FCComboBox()
|
||||
self.box_combo.setModel(self.app.collection)
|
||||
self.box_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
|
||||
self.box_combo.is_last = True
|
||||
|
||||
self.box_combo.setToolTip(
|
||||
_("The actual object that is used as container for the\n "
|
||||
"selected object that is to be panelized.")
|
||||
)
|
||||
form_layout.addRow(self.box_combo)
|
||||
|
||||
separator_line = QtWidgets.QFrame()
|
||||
separator_line.setFrameShape(QtWidgets.QFrame.HLine)
|
||||
separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
|
||||
form_layout.addRow(separator_line)
|
||||
|
||||
panel_data_label = QtWidgets.QLabel("<b>%s:</b>" % _("Panel Data"))
|
||||
panel_data_label.setToolTip(
|
||||
_("This informations will shape the resulting panel.\n"
|
||||
"The number of rows and columns will set how many\n"
|
||||
"duplicates of the original geometry will be generated.\n"
|
||||
"\n"
|
||||
"The spacings will set the distance between any two\n"
|
||||
"elements of the panel array.")
|
||||
)
|
||||
form_layout.addRow(panel_data_label)
|
||||
|
||||
# Spacing Columns
|
||||
self.spacing_columns = FCDoubleSpinner(callback=self.confirmation_message)
|
||||
self.spacing_columns.set_range(0, 9999)
|
||||
self.spacing_columns.set_precision(4)
|
||||
|
||||
self.spacing_columns_label = QtWidgets.QLabel('%s:' % _("Spacing cols"))
|
||||
self.spacing_columns_label.setToolTip(
|
||||
_("Spacing between columns of the desired panel.\n"
|
||||
"In current units.")
|
||||
)
|
||||
form_layout.addRow(self.spacing_columns_label, self.spacing_columns)
|
||||
|
||||
# Spacing Rows
|
||||
self.spacing_rows = FCDoubleSpinner(callback=self.confirmation_message)
|
||||
self.spacing_rows.set_range(0, 9999)
|
||||
self.spacing_rows.set_precision(4)
|
||||
|
||||
self.spacing_rows_label = QtWidgets.QLabel('%s:' % _("Spacing rows"))
|
||||
self.spacing_rows_label.setToolTip(
|
||||
_("Spacing between rows of the desired panel.\n"
|
||||
"In current units.")
|
||||
)
|
||||
form_layout.addRow(self.spacing_rows_label, self.spacing_rows)
|
||||
|
||||
# Columns
|
||||
self.columns = FCSpinner(callback=self.confirmation_message_int)
|
||||
self.columns.set_range(0, 9999)
|
||||
|
||||
self.columns_label = QtWidgets.QLabel('%s:' % _("Columns"))
|
||||
self.columns_label.setToolTip(
|
||||
_("Number of columns of the desired panel")
|
||||
)
|
||||
form_layout.addRow(self.columns_label, self.columns)
|
||||
|
||||
# Rows
|
||||
self.rows = FCSpinner(callback=self.confirmation_message_int)
|
||||
self.rows.set_range(0, 9999)
|
||||
|
||||
self.rows_label = QtWidgets.QLabel('%s:' % _("Rows"))
|
||||
self.rows_label.setToolTip(
|
||||
_("Number of rows of the desired panel")
|
||||
)
|
||||
form_layout.addRow(self.rows_label, self.rows)
|
||||
|
||||
separator_line = QtWidgets.QFrame()
|
||||
separator_line.setFrameShape(QtWidgets.QFrame.HLine)
|
||||
separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
|
||||
form_layout.addRow(separator_line)
|
||||
|
||||
# Type of resulting Panel object
|
||||
self.panel_type_radio = RadioSet([{'label': _('Gerber'), 'value': 'gerber'},
|
||||
{'label': _('Geo'), 'value': 'geometry'}])
|
||||
self.panel_type_label = QtWidgets.QLabel("<b>%s:</b>" % _("Panel Type"))
|
||||
self.panel_type_label.setToolTip(
|
||||
_("Choose the type of object for the panel object:\n"
|
||||
"- Geometry\n"
|
||||
"- Gerber")
|
||||
)
|
||||
form_layout.addRow(self.panel_type_label)
|
||||
form_layout.addRow(self.panel_type_radio)
|
||||
|
||||
# Constrains
|
||||
self.constrain_cb = FCCheckBox('%s:' % _("Constrain panel within"))
|
||||
self.constrain_cb.setToolTip(
|
||||
_("Area define by DX and DY within to constrain the panel.\n"
|
||||
"DX and DY values are in current units.\n"
|
||||
"Regardless of how many columns and rows are desired,\n"
|
||||
"the final panel will have as many columns and rows as\n"
|
||||
"they fit completely within selected area.")
|
||||
)
|
||||
form_layout.addRow(self.constrain_cb)
|
||||
|
||||
self.x_width_entry = FCDoubleSpinner(callback=self.confirmation_message)
|
||||
self.x_width_entry.set_precision(4)
|
||||
self.x_width_entry.set_range(0, 9999)
|
||||
|
||||
self.x_width_lbl = QtWidgets.QLabel('%s:' % _("Width (DX)"))
|
||||
self.x_width_lbl.setToolTip(
|
||||
_("The width (DX) within which the panel must fit.\n"
|
||||
"In current units.")
|
||||
)
|
||||
form_layout.addRow(self.x_width_lbl, self.x_width_entry)
|
||||
|
||||
self.y_height_entry = FCDoubleSpinner(callback=self.confirmation_message)
|
||||
self.y_height_entry.set_range(0, 9999)
|
||||
self.y_height_entry.set_precision(4)
|
||||
|
||||
self.y_height_lbl = QtWidgets.QLabel('%s:' % _("Height (DY)"))
|
||||
self.y_height_lbl.setToolTip(
|
||||
_("The height (DY)within which the panel must fit.\n"
|
||||
"In current units.")
|
||||
)
|
||||
form_layout.addRow(self.y_height_lbl, self.y_height_entry)
|
||||
|
||||
self.constrain_sel = OptionalInputSection(
|
||||
self.constrain_cb, [self.x_width_lbl, self.x_width_entry, self.y_height_lbl, self.y_height_entry])
|
||||
|
||||
separator_line = QtWidgets.QFrame()
|
||||
separator_line.setFrameShape(QtWidgets.QFrame.HLine)
|
||||
separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
|
||||
form_layout.addRow(separator_line)
|
||||
|
||||
# Buttons
|
||||
self.panelize_object_button = QtWidgets.QPushButton(_("Panelize Object"))
|
||||
self.panelize_object_button.setToolTip(
|
||||
_("Panelize the specified object around the specified box.\n"
|
||||
"In other words it creates multiple copies of the source object,\n"
|
||||
"arranged in a 2D array of rows and columns.")
|
||||
)
|
||||
self.panelize_object_button.setStyleSheet("""
|
||||
QPushButton
|
||||
{
|
||||
font-weight: bold;
|
||||
}
|
||||
""")
|
||||
self.layout.addWidget(self.panelize_object_button)
|
||||
|
||||
self.layout.addStretch()
|
||||
|
||||
# ## Reset Tool
|
||||
self.reset_button = QtWidgets.QPushButton(_("Reset Tool"))
|
||||
self.reset_button.setToolTip(
|
||||
_("Will reset the tool parameters.")
|
||||
)
|
||||
self.reset_button.setStyleSheet("""
|
||||
QPushButton
|
||||
{
|
||||
font-weight: bold;
|
||||
}
|
||||
""")
|
||||
self.layout.addWidget(self.reset_button)
|
||||
# #############################################################################
|
||||
# ######################### Tool GUI ##########################################
|
||||
# #############################################################################
|
||||
self.ui = PanelizeUI(layout=self.layout, app=self.app)
|
||||
self.toolName = self.ui.toolName
|
||||
|
||||
# Signals
|
||||
self.reference_radio.activated_custom.connect(self.on_reference_radio_changed)
|
||||
self.panelize_object_button.clicked.connect(self.on_panelize)
|
||||
self.type_obj_combo.currentIndexChanged.connect(self.on_type_obj_index_changed)
|
||||
self.type_box_combo.currentIndexChanged.connect(self.on_type_box_index_changed)
|
||||
self.reset_button.clicked.connect(self.set_tool_ui)
|
||||
self.ui.reference_radio.activated_custom.connect(self.on_reference_radio_changed)
|
||||
self.ui.panelize_object_button.clicked.connect(self.on_panelize)
|
||||
self.ui.type_obj_combo.currentIndexChanged.connect(self.on_type_obj_index_changed)
|
||||
self.ui.type_box_combo.currentIndexChanged.connect(self.on_type_box_index_changed)
|
||||
self.ui.reset_button.clicked.connect(self.set_tool_ui)
|
||||
|
||||
# list to hold the temporary objects
|
||||
self.objs = []
|
||||
@@ -342,35 +98,35 @@ class Panelize(AppTool):
|
||||
|
||||
sp_c = self.app.defaults["tools_panelize_spacing_columns"] if \
|
||||
self.app.defaults["tools_panelize_spacing_columns"] else 0.0
|
||||
self.spacing_columns.set_value(float(sp_c))
|
||||
self.ui.spacing_columns.set_value(float(sp_c))
|
||||
|
||||
sp_r = self.app.defaults["tools_panelize_spacing_rows"] if \
|
||||
self.app.defaults["tools_panelize_spacing_rows"] else 0.0
|
||||
self.spacing_rows.set_value(float(sp_r))
|
||||
self.ui.spacing_rows.set_value(float(sp_r))
|
||||
|
||||
rr = self.app.defaults["tools_panelize_rows"] if \
|
||||
self.app.defaults["tools_panelize_rows"] else 0.0
|
||||
self.rows.set_value(int(rr))
|
||||
self.ui.rows.set_value(int(rr))
|
||||
|
||||
cc = self.app.defaults["tools_panelize_columns"] if \
|
||||
self.app.defaults["tools_panelize_columns"] else 0.0
|
||||
self.columns.set_value(int(cc))
|
||||
self.ui.columns.set_value(int(cc))
|
||||
|
||||
c_cb = self.app.defaults["tools_panelize_constrain"] if \
|
||||
self.app.defaults["tools_panelize_constrain"] else False
|
||||
self.constrain_cb.set_value(c_cb)
|
||||
self.ui.constrain_cb.set_value(c_cb)
|
||||
|
||||
x_w = self.app.defaults["tools_panelize_constrainx"] if \
|
||||
self.app.defaults["tools_panelize_constrainx"] else 0.0
|
||||
self.x_width_entry.set_value(float(x_w))
|
||||
self.ui.x_width_entry.set_value(float(x_w))
|
||||
|
||||
y_w = self.app.defaults["tools_panelize_constrainy"] if \
|
||||
self.app.defaults["tools_panelize_constrainy"] else 0.0
|
||||
self.y_height_entry.set_value(float(y_w))
|
||||
self.ui.y_height_entry.set_value(float(y_w))
|
||||
|
||||
panel_type = self.app.defaults["tools_panelize_panel_type"] if \
|
||||
self.app.defaults["tools_panelize_panel_type"] else 'gerber'
|
||||
self.panel_type_radio.set_value(panel_type)
|
||||
self.ui.panel_type_radio.set_value(panel_type)
|
||||
|
||||
# run once the following so the obj_type attribute is updated in the FCComboBoxes
|
||||
# such that the last loaded object is populated in the combo boxes
|
||||
@@ -378,43 +134,43 @@ class Panelize(AppTool):
|
||||
self.on_type_box_index_changed()
|
||||
|
||||
def on_type_obj_index_changed(self):
|
||||
obj_type = self.type_obj_combo.currentIndex()
|
||||
self.object_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex()))
|
||||
self.object_combo.setCurrentIndex(0)
|
||||
self.object_combo.obj_type = {
|
||||
obj_type = self.ui.type_obj_combo.currentIndex()
|
||||
self.ui.object_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex()))
|
||||
self.ui.object_combo.setCurrentIndex(0)
|
||||
self.ui.object_combo.obj_type = {
|
||||
_("Gerber"): "Gerber", _("Excellon"): "Excellon", _("Geometry"): "Geometry"
|
||||
}[self.type_obj_combo.get_value()]
|
||||
}[self.ui.type_obj_combo.get_value()]
|
||||
|
||||
# hide the panel type for Excellons, the panel can be only of type Geometry
|
||||
if self.type_obj_combo.currentText() != 'Excellon':
|
||||
self.panel_type_label.setDisabled(False)
|
||||
self.panel_type_radio.setDisabled(False)
|
||||
if self.ui.type_obj_combo.currentText() != 'Excellon':
|
||||
self.ui.panel_type_label.setDisabled(False)
|
||||
self.ui.panel_type_radio.setDisabled(False)
|
||||
else:
|
||||
self.panel_type_label.setDisabled(True)
|
||||
self.panel_type_radio.setDisabled(True)
|
||||
self.panel_type_radio.set_value('geometry')
|
||||
self.ui.panel_type_label.setDisabled(True)
|
||||
self.ui.panel_type_radio.setDisabled(True)
|
||||
self.ui.panel_type_radio.set_value('geometry')
|
||||
|
||||
def on_type_box_index_changed(self):
|
||||
obj_type = self.type_box_combo.currentIndex()
|
||||
obj_type = self.ui.type_box_combo.currentIndex()
|
||||
obj_type = 2 if obj_type == 1 else obj_type
|
||||
self.box_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex()))
|
||||
self.box_combo.setCurrentIndex(0)
|
||||
self.box_combo.obj_type = {
|
||||
self.ui.box_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex()))
|
||||
self.ui.box_combo.setCurrentIndex(0)
|
||||
self.ui.box_combo.obj_type = {
|
||||
_("Gerber"): "Gerber", _("Geometry"): "Geometry"
|
||||
}[self.type_box_combo.get_value()]
|
||||
}[self.ui.type_box_combo.get_value()]
|
||||
|
||||
def on_reference_radio_changed(self, current_val):
|
||||
if current_val == 'object':
|
||||
self.type_box_combo.setDisabled(False)
|
||||
self.type_box_combo_label.setDisabled(False)
|
||||
self.box_combo.setDisabled(False)
|
||||
self.ui.type_box_combo.setDisabled(False)
|
||||
self.ui.type_box_combo_label.setDisabled(False)
|
||||
self.ui.box_combo.setDisabled(False)
|
||||
else:
|
||||
self.type_box_combo.setDisabled(True)
|
||||
self.type_box_combo_label.setDisabled(True)
|
||||
self.box_combo.setDisabled(True)
|
||||
self.ui.type_box_combo.setDisabled(True)
|
||||
self.ui.type_box_combo_label.setDisabled(True)
|
||||
self.ui.box_combo.setDisabled(True)
|
||||
|
||||
def on_panelize(self):
|
||||
name = self.object_combo.currentText()
|
||||
name = self.ui.object_combo.currentText()
|
||||
|
||||
# Get source object to be panelized.
|
||||
try:
|
||||
@@ -429,7 +185,7 @@ class Panelize(AppTool):
|
||||
(_("Object not found"), panel_source_obj))
|
||||
return
|
||||
|
||||
boxname = self.box_combo.currentText()
|
||||
boxname = self.ui.box_combo.currentText()
|
||||
|
||||
try:
|
||||
box = self.app.collection.get_by_name(boxname)
|
||||
@@ -440,29 +196,29 @@ class Panelize(AppTool):
|
||||
|
||||
if box is None:
|
||||
self.app.inform.emit('[WARNING_NOTCL] %s: %s' % (_("No object Box. Using instead"), panel_source_obj))
|
||||
self.reference_radio.set_value('bbox')
|
||||
self.ui.reference_radio.set_value('bbox')
|
||||
|
||||
if self.reference_radio.get_value() == 'bbox':
|
||||
if self.ui.reference_radio.get_value() == 'bbox':
|
||||
box = panel_source_obj
|
||||
|
||||
self.outname = name + '_panelized'
|
||||
|
||||
spacing_columns = float(self.spacing_columns.get_value())
|
||||
spacing_columns = float(self.ui.spacing_columns.get_value())
|
||||
spacing_columns = spacing_columns if spacing_columns is not None else 0
|
||||
|
||||
spacing_rows = float(self.spacing_rows.get_value())
|
||||
spacing_rows = float(self.ui.spacing_rows.get_value())
|
||||
spacing_rows = spacing_rows if spacing_rows is not None else 0
|
||||
|
||||
rows = int(self.rows.get_value())
|
||||
rows = int(self.ui.rows.get_value())
|
||||
rows = rows if rows is not None else 1
|
||||
|
||||
columns = int(self.columns.get_value())
|
||||
columns = int(self.ui.columns.get_value())
|
||||
columns = columns if columns is not None else 1
|
||||
|
||||
constrain_dx = float(self.x_width_entry.get_value())
|
||||
constrain_dy = float(self.y_height_entry.get_value())
|
||||
constrain_dx = float(self.ui.x_width_entry.get_value())
|
||||
constrain_dy = float(self.ui.y_height_entry.get_value())
|
||||
|
||||
panel_type = str(self.panel_type_radio.get_value())
|
||||
panel_type = str(self.ui.panel_type_radio.get_value())
|
||||
|
||||
if 0 in {columns, rows}:
|
||||
self.app.inform.emit('[ERROR_NOTCL] %s' %
|
||||
@@ -474,7 +230,7 @@ class Panelize(AppTool):
|
||||
lenghty = ymax - ymin + spacing_rows
|
||||
|
||||
# check if constrain within an area is desired
|
||||
if self.constrain_cb.isChecked():
|
||||
if self.ui.constrain_cb.isChecked():
|
||||
panel_lengthx = ((xmax - xmin) * columns) + (spacing_columns * (columns - 1))
|
||||
panel_lengthy = ((ymax - ymin) * rows) + (spacing_rows * (rows - 1))
|
||||
|
||||
@@ -820,3 +576,283 @@ class Panelize(AppTool):
|
||||
def reset_fields(self):
|
||||
self.object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
|
||||
self.box_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
|
||||
|
||||
|
||||
class PanelizeUI:
|
||||
|
||||
toolName = _("Panelize PCB")
|
||||
|
||||
def __init__(self, layout, app):
|
||||
self.app = app
|
||||
self.decimals = self.app.decimals
|
||||
self.layout = layout
|
||||
|
||||
# ## Title
|
||||
title_label = QtWidgets.QLabel("%s" % self.toolName)
|
||||
title_label.setStyleSheet("""
|
||||
QLabel
|
||||
{
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
""")
|
||||
self.layout.addWidget(title_label)
|
||||
|
||||
self.object_label = QtWidgets.QLabel('<b>%s:</b>' % _("Source Object"))
|
||||
self.object_label.setToolTip(
|
||||
_("Specify the type of object to be panelized\n"
|
||||
"It can be of type: Gerber, Excellon or Geometry.\n"
|
||||
"The selection here decide the type of objects that will be\n"
|
||||
"in the Object combobox.")
|
||||
)
|
||||
|
||||
self.layout.addWidget(self.object_label)
|
||||
|
||||
# Form Layout
|
||||
form_layout_0 = QtWidgets.QFormLayout()
|
||||
self.layout.addLayout(form_layout_0)
|
||||
|
||||
# Type of object to be panelized
|
||||
self.type_obj_combo = FCComboBox()
|
||||
self.type_obj_combo.addItem("Gerber")
|
||||
self.type_obj_combo.addItem("Excellon")
|
||||
self.type_obj_combo.addItem("Geometry")
|
||||
|
||||
self.type_obj_combo.setItemIcon(0, QtGui.QIcon(self.app.resource_location + "/flatcam_icon16.png"))
|
||||
self.type_obj_combo.setItemIcon(1, QtGui.QIcon(self.app.resource_location + "/drill16.png"))
|
||||
self.type_obj_combo.setItemIcon(2, QtGui.QIcon(self.app.resource_location + "/geometry16.png"))
|
||||
|
||||
self.type_object_label = QtWidgets.QLabel('%s:' % _("Object Type"))
|
||||
|
||||
form_layout_0.addRow(self.type_object_label, self.type_obj_combo)
|
||||
|
||||
# Object to be panelized
|
||||
self.object_combo = FCComboBox()
|
||||
self.object_combo.setModel(self.app.collection)
|
||||
self.object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
|
||||
self.object_combo.is_last = True
|
||||
|
||||
self.object_combo.setToolTip(
|
||||
_("Object to be panelized. This means that it will\n"
|
||||
"be duplicated in an array of rows and columns.")
|
||||
)
|
||||
form_layout_0.addRow(self.object_combo)
|
||||
|
||||
# Form Layout
|
||||
form_layout = QtWidgets.QFormLayout()
|
||||
self.layout.addLayout(form_layout)
|
||||
|
||||
# Type of box Panel object
|
||||
self.reference_radio = RadioSet([{'label': _('Object'), 'value': 'object'},
|
||||
{'label': _('Bounding Box'), 'value': 'bbox'}])
|
||||
self.box_label = QtWidgets.QLabel("<b>%s:</b>" % _("Penelization Reference"))
|
||||
self.box_label.setToolTip(
|
||||
_("Choose the reference for panelization:\n"
|
||||
"- Object = the bounding box of a different object\n"
|
||||
"- Bounding Box = the bounding box of the object to be panelized\n"
|
||||
"\n"
|
||||
"The reference is useful when doing panelization for more than one\n"
|
||||
"object. The spacings (really offsets) will be applied in reference\n"
|
||||
"to this reference object therefore maintaining the panelized\n"
|
||||
"objects in sync.")
|
||||
)
|
||||
form_layout.addRow(self.box_label)
|
||||
form_layout.addRow(self.reference_radio)
|
||||
|
||||
# Type of Box Object to be used as an envelope for panelization
|
||||
self.type_box_combo = FCComboBox()
|
||||
self.type_box_combo.addItems([_("Gerber"), _("Geometry")])
|
||||
|
||||
# we get rid of item1 ("Excellon") as it is not suitable for use as a "box" for panelizing
|
||||
# self.type_box_combo.view().setRowHidden(1, True)
|
||||
self.type_box_combo.setItemIcon(0, QtGui.QIcon(self.app.resource_location + "/flatcam_icon16.png"))
|
||||
self.type_box_combo.setItemIcon(1, QtGui.QIcon(self.app.resource_location + "/geometry16.png"))
|
||||
|
||||
self.type_box_combo_label = QtWidgets.QLabel('%s:' % _("Box Type"))
|
||||
self.type_box_combo_label.setToolTip(
|
||||
_("Specify the type of object to be used as an container for\n"
|
||||
"panelization. It can be: Gerber or Geometry type.\n"
|
||||
"The selection here decide the type of objects that will be\n"
|
||||
"in the Box Object combobox.")
|
||||
)
|
||||
form_layout.addRow(self.type_box_combo_label, self.type_box_combo)
|
||||
|
||||
# Box
|
||||
self.box_combo = FCComboBox()
|
||||
self.box_combo.setModel(self.app.collection)
|
||||
self.box_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
|
||||
self.box_combo.is_last = True
|
||||
|
||||
self.box_combo.setToolTip(
|
||||
_("The actual object that is used as container for the\n "
|
||||
"selected object that is to be panelized.")
|
||||
)
|
||||
form_layout.addRow(self.box_combo)
|
||||
|
||||
separator_line = QtWidgets.QFrame()
|
||||
separator_line.setFrameShape(QtWidgets.QFrame.HLine)
|
||||
separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
|
||||
form_layout.addRow(separator_line)
|
||||
|
||||
panel_data_label = QtWidgets.QLabel("<b>%s:</b>" % _("Panel Data"))
|
||||
panel_data_label.setToolTip(
|
||||
_("This informations will shape the resulting panel.\n"
|
||||
"The number of rows and columns will set how many\n"
|
||||
"duplicates of the original geometry will be generated.\n"
|
||||
"\n"
|
||||
"The spacings will set the distance between any two\n"
|
||||
"elements of the panel array.")
|
||||
)
|
||||
form_layout.addRow(panel_data_label)
|
||||
|
||||
# Spacing Columns
|
||||
self.spacing_columns = FCDoubleSpinner(callback=self.confirmation_message)
|
||||
self.spacing_columns.set_range(0, 9999)
|
||||
self.spacing_columns.set_precision(4)
|
||||
|
||||
self.spacing_columns_label = QtWidgets.QLabel('%s:' % _("Spacing cols"))
|
||||
self.spacing_columns_label.setToolTip(
|
||||
_("Spacing between columns of the desired panel.\n"
|
||||
"In current units.")
|
||||
)
|
||||
form_layout.addRow(self.spacing_columns_label, self.spacing_columns)
|
||||
|
||||
# Spacing Rows
|
||||
self.spacing_rows = FCDoubleSpinner(callback=self.confirmation_message)
|
||||
self.spacing_rows.set_range(0, 9999)
|
||||
self.spacing_rows.set_precision(4)
|
||||
|
||||
self.spacing_rows_label = QtWidgets.QLabel('%s:' % _("Spacing rows"))
|
||||
self.spacing_rows_label.setToolTip(
|
||||
_("Spacing between rows of the desired panel.\n"
|
||||
"In current units.")
|
||||
)
|
||||
form_layout.addRow(self.spacing_rows_label, self.spacing_rows)
|
||||
|
||||
# Columns
|
||||
self.columns = FCSpinner(callback=self.confirmation_message_int)
|
||||
self.columns.set_range(0, 9999)
|
||||
|
||||
self.columns_label = QtWidgets.QLabel('%s:' % _("Columns"))
|
||||
self.columns_label.setToolTip(
|
||||
_("Number of columns of the desired panel")
|
||||
)
|
||||
form_layout.addRow(self.columns_label, self.columns)
|
||||
|
||||
# Rows
|
||||
self.rows = FCSpinner(callback=self.confirmation_message_int)
|
||||
self.rows.set_range(0, 9999)
|
||||
|
||||
self.rows_label = QtWidgets.QLabel('%s:' % _("Rows"))
|
||||
self.rows_label.setToolTip(
|
||||
_("Number of rows of the desired panel")
|
||||
)
|
||||
form_layout.addRow(self.rows_label, self.rows)
|
||||
|
||||
separator_line = QtWidgets.QFrame()
|
||||
separator_line.setFrameShape(QtWidgets.QFrame.HLine)
|
||||
separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
|
||||
form_layout.addRow(separator_line)
|
||||
|
||||
# Type of resulting Panel object
|
||||
self.panel_type_radio = RadioSet([{'label': _('Gerber'), 'value': 'gerber'},
|
||||
{'label': _('Geo'), 'value': 'geometry'}])
|
||||
self.panel_type_label = QtWidgets.QLabel("<b>%s:</b>" % _("Panel Type"))
|
||||
self.panel_type_label.setToolTip(
|
||||
_("Choose the type of object for the panel object:\n"
|
||||
"- Geometry\n"
|
||||
"- Gerber")
|
||||
)
|
||||
form_layout.addRow(self.panel_type_label)
|
||||
form_layout.addRow(self.panel_type_radio)
|
||||
|
||||
# Constrains
|
||||
self.constrain_cb = FCCheckBox('%s:' % _("Constrain panel within"))
|
||||
self.constrain_cb.setToolTip(
|
||||
_("Area define by DX and DY within to constrain the panel.\n"
|
||||
"DX and DY values are in current units.\n"
|
||||
"Regardless of how many columns and rows are desired,\n"
|
||||
"the final panel will have as many columns and rows as\n"
|
||||
"they fit completely within selected area.")
|
||||
)
|
||||
form_layout.addRow(self.constrain_cb)
|
||||
|
||||
self.x_width_entry = FCDoubleSpinner(callback=self.confirmation_message)
|
||||
self.x_width_entry.set_precision(4)
|
||||
self.x_width_entry.set_range(0, 9999)
|
||||
|
||||
self.x_width_lbl = QtWidgets.QLabel('%s:' % _("Width (DX)"))
|
||||
self.x_width_lbl.setToolTip(
|
||||
_("The width (DX) within which the panel must fit.\n"
|
||||
"In current units.")
|
||||
)
|
||||
form_layout.addRow(self.x_width_lbl, self.x_width_entry)
|
||||
|
||||
self.y_height_entry = FCDoubleSpinner(callback=self.confirmation_message)
|
||||
self.y_height_entry.set_range(0, 9999)
|
||||
self.y_height_entry.set_precision(4)
|
||||
|
||||
self.y_height_lbl = QtWidgets.QLabel('%s:' % _("Height (DY)"))
|
||||
self.y_height_lbl.setToolTip(
|
||||
_("The height (DY)within which the panel must fit.\n"
|
||||
"In current units.")
|
||||
)
|
||||
form_layout.addRow(self.y_height_lbl, self.y_height_entry)
|
||||
|
||||
self.constrain_sel = OptionalInputSection(
|
||||
self.constrain_cb, [self.x_width_lbl, self.x_width_entry, self.y_height_lbl, self.y_height_entry])
|
||||
|
||||
separator_line = QtWidgets.QFrame()
|
||||
separator_line.setFrameShape(QtWidgets.QFrame.HLine)
|
||||
separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
|
||||
form_layout.addRow(separator_line)
|
||||
|
||||
# Buttons
|
||||
self.panelize_object_button = QtWidgets.QPushButton(_("Panelize Object"))
|
||||
self.panelize_object_button.setToolTip(
|
||||
_("Panelize the specified object around the specified box.\n"
|
||||
"In other words it creates multiple copies of the source object,\n"
|
||||
"arranged in a 2D array of rows and columns.")
|
||||
)
|
||||
self.panelize_object_button.setStyleSheet("""
|
||||
QPushButton
|
||||
{
|
||||
font-weight: bold;
|
||||
}
|
||||
""")
|
||||
self.layout.addWidget(self.panelize_object_button)
|
||||
|
||||
self.layout.addStretch()
|
||||
|
||||
# ## Reset Tool
|
||||
self.reset_button = QtWidgets.QPushButton(_("Reset Tool"))
|
||||
self.reset_button.setToolTip(
|
||||
_("Will reset the tool parameters.")
|
||||
)
|
||||
self.reset_button.setStyleSheet("""
|
||||
QPushButton
|
||||
{
|
||||
font-weight: bold;
|
||||
}
|
||||
""")
|
||||
self.layout.addWidget(self.reset_button)
|
||||
|
||||
# #################################### FINSIHED GUI ###########################
|
||||
# #############################################################################
|
||||
|
||||
def confirmation_message(self, accepted, minval, maxval):
|
||||
if accepted is False:
|
||||
self.app.inform[str, bool].emit('[WARNING_NOTCL] %s: [%.*f, %.*f]' % (_("Edited value is out of range"),
|
||||
self.decimals,
|
||||
minval,
|
||||
self.decimals,
|
||||
maxval), False)
|
||||
else:
|
||||
self.app.inform[str, bool].emit('[success] %s' % _("Edited value is within limits."), False)
|
||||
|
||||
def confirmation_message_int(self, accepted, minval, maxval):
|
||||
if accepted is False:
|
||||
self.app.inform[str, bool].emit('[WARNING_NOTCL] %s: [%d, %d]' %
|
||||
(_("Edited value is out of range"), minval, maxval), False)
|
||||
else:
|
||||
self.app.inform[str, bool].emit('[success] %s' % _("Edited value is within limits."), False)
|
||||
|
||||
Reference in New Issue
Block a user