diff --git a/DblSidedTool.py b/DblSidedTool.py
new file mode 100644
index 0000000..eb18f08
--- /dev/null
+++ b/DblSidedTool.py
@@ -0,0 +1,143 @@
+from PyQt4 import QtGui
+from GUIElements import RadioSet, EvalEntry, LengthEntry
+from FlatCAMTool import FlatCAMTool
+from FlatCAMObj import FlatCAMGerber, FlatCAMExcellon
+from shapely.geometry import Point
+from shapely import affinity
+
+
+class DblSidedTool(FlatCAMTool):
+
+ toolName = "Double-Sided PCB Tool"
+
+ def __init__(self, app):
+ FlatCAMTool.__init__(self, app)
+
+ ## Title
+ title_label = QtGui.QLabel("%s" % self.toolName)
+ self.layout.addWidget(title_label)
+
+ ## Form Layout
+ form_layout = QtGui.QFormLayout()
+ self.layout.addLayout(form_layout)
+
+ ## Layer to mirror
+ self.object_combo = QtGui.QComboBox()
+ self.object_combo.setModel(self.app.collection)
+ form_layout.addRow("Bottom Layer:", self.object_combo)
+
+ ## Axis
+ self.mirror_axis = RadioSet([{'label': 'X', 'value': 'X'},
+ {'label': 'Y', 'value': 'Y'}])
+ form_layout.addRow("Mirror Axis:", self.mirror_axis)
+
+ ## Axis Location
+ self.axis_location = RadioSet([{'label': 'Point', 'value': 'point'},
+ {'label': 'Box', 'value': 'box'}])
+ form_layout.addRow("Axis Location:", self.axis_location)
+
+ ## Point/Box
+ self.point_box_container = QtGui.QVBoxLayout()
+ form_layout.addRow("Point/Box:", self.point_box_container)
+ self.point = EvalEntry()
+ self.point_box_container.addWidget(self.point)
+ self.box_combo = QtGui.QComboBox()
+ self.box_combo.setModel(self.app.collection)
+ self.point_box_container.addWidget(self.box_combo)
+ self.box_combo.hide()
+
+ ## Alignment holes
+ self.alignment_holes = EvalEntry()
+ form_layout.addRow("Alignment Holes:", self.alignment_holes)
+
+ ## Drill diameter for alignment holes
+ self.drill_dia = LengthEntry()
+ form_layout.addRow("Drill diam.:", self.drill_dia)
+
+ ## Buttons
+ hlay = QtGui.QHBoxLayout()
+ self.layout.addLayout(hlay)
+ hlay.addStretch()
+ self.create_alignment_hole_button = QtGui.QPushButton("Create Alignment Drill")
+ self.mirror_object_button = QtGui.QPushButton("Mirror Object")
+ hlay.addWidget(self.create_alignment_hole_button)
+ hlay.addWidget(self.mirror_object_button)
+
+ self.layout.addStretch()
+
+ ## Signals
+ self.create_alignment_hole_button.clicked.connect(self.on_create_alignment_holes)
+ self.mirror_object_button.clicked.connect(self.on_mirror)
+
+ self.axis_location.group_toggle_fn = self.on_toggle_pointbox
+
+ ## Initialize form
+ self.mirror_axis.set_value('X')
+ self.axis_location.set_value('point')
+
+ def on_create_alignment_holes(self):
+ axis = self.mirror_axis.get_value()
+ mode = self.axis_location.get_value()
+
+ if mode == "point":
+ px, py = self.point.get_value()
+ else:
+ selection_index = self.box_combo.currentIndex()
+ bb_obj = self.app.collection.object_list[selection_index] # TODO: Direct access??
+ xmin, ymin, xmax, ymax = bb_obj.bounds()
+ px = 0.5*(xmin+xmax)
+ py = 0.5*(ymin+ymax)
+
+ xscale, yscale = {"X": (1.0, -1.0), "Y": (-1.0, 1.0)}[axis]
+
+ dia = self.drill_dia.get_value()
+ tools = {"1": {"C": dia}}
+
+ holes = self.alignment_holes.get_value()
+ drills = []
+
+ for hole in holes:
+ point = Point(hole)
+ point_mirror = affinity.scale(point, xscale, yscale, origin=(px, py))
+ drills.append({"point": point, "tool": "1"})
+ drills.append({"point": point_mirror, "tool": "1"})
+
+ def obj_init(obj_inst, app_inst):
+ obj_inst.tools = tools
+ obj_inst.drills = drills
+ obj_inst.create_geometry()
+
+ self.app.new_object("excellon", "Alignment Drills", obj_init)
+
+ def on_mirror(self):
+ selection_index = self.object_combo.currentIndex()
+ fcobj = self.app.collection.object_list[selection_index]
+
+ # For now, lets limit to Gerbers and Excellons.
+ # assert isinstance(gerb, FlatCAMGerber)
+ if not isinstance(fcobj, FlatCAMGerber) and not isinstance(fcobj, FlatCAMExcellon):
+ self.info("ERROR: Only Gerber and Excellon objects can be mirrored.")
+ return
+
+ axis = self.mirror_axis.get_value()
+ mode = self.axis_location.get_value()
+
+ if mode == "point":
+ px, py = self.point.get_value()
+ else:
+ selection_index = self.box_combo.currentIndex()
+ bb_obj = self.app.collection.object_list[selection_index] # TODO: Direct access??
+ xmin, ymin, xmax, ymax = bb_obj.bounds()
+ px = 0.5*(xmin+xmax)
+ py = 0.5*(ymin+ymax)
+
+ fcobj.mirror(axis, [px, py])
+ fcobj.plot()
+
+ def on_toggle_pointbox(self):
+ if self.axis_location.get_value() == "point":
+ self.point.show()
+ self.box_combo.hide()
+ else:
+ self.point.hide()
+ self.box_combo.show()
\ No newline at end of file
diff --git a/FlatCAMApp.py b/FlatCAMApp.py
index 66a5a1e..fdb59ea 100644
--- a/FlatCAMApp.py
+++ b/FlatCAMApp.py
@@ -20,10 +20,11 @@ from FlatCAMObj import *
from PlotCanvas import *
from FlatCAMGUI import *
from FlatCAMCommon import LoudDict
-from FlatCAMTool import *
from FlatCAMShell import FCShell
from FlatCAMDraw import FlatCAMDraw
from FlatCAMProcess import *
+from MeasurementTool import Measurement
+from DblSidedTool import DblSidedTool
########################################
diff --git a/FlatCAMTool.py b/FlatCAMTool.py
index b2d93c8..0aefa64 100644
--- a/FlatCAMTool.py
+++ b/FlatCAMTool.py
@@ -1,10 +1,4 @@
-from PyQt4 import QtGui, QtCore
-from shapely.geometry import Point
-from shapely import affinity
-from math import sqrt
-
-from GUIElements import *
-from FlatCAMObj import *
+from PyQt4 import QtGui
class FlatCAMTool(QtGui.QWidget):
@@ -45,213 +39,3 @@ class FlatCAMTool(QtGui.QWidget):
self.app.ui.notebook.setCurrentWidget(self.app.ui.tool_tab)
self.show()
-
-
-class DblSidedTool(FlatCAMTool):
-
- toolName = "Double-Sided PCB Tool"
-
- def __init__(self, app):
- FlatCAMTool.__init__(self, app)
-
- ## Title
- title_label = QtGui.QLabel("%s" % self.toolName)
- self.layout.addWidget(title_label)
-
- ## Form Layout
- form_layout = QtGui.QFormLayout()
- self.layout.addLayout(form_layout)
-
- ## Layer to mirror
- self.object_combo = QtGui.QComboBox()
- self.object_combo.setModel(self.app.collection)
- form_layout.addRow("Bottom Layer:", self.object_combo)
-
- ## Axis
- self.mirror_axis = RadioSet([{'label': 'X', 'value': 'X'},
- {'label': 'Y', 'value': 'Y'}])
- form_layout.addRow("Mirror Axis:", self.mirror_axis)
-
- ## Axis Location
- self.axis_location = RadioSet([{'label': 'Point', 'value': 'point'},
- {'label': 'Box', 'value': 'box'}])
- form_layout.addRow("Axis Location:", self.axis_location)
-
- ## Point/Box
- self.point_box_container = QtGui.QVBoxLayout()
- form_layout.addRow("Point/Box:", self.point_box_container)
- self.point = EvalEntry()
- self.point_box_container.addWidget(self.point)
- self.box_combo = QtGui.QComboBox()
- self.box_combo.setModel(self.app.collection)
- self.point_box_container.addWidget(self.box_combo)
- self.box_combo.hide()
-
- ## Alignment holes
- self.alignment_holes = EvalEntry()
- form_layout.addRow("Alignment Holes:", self.alignment_holes)
-
- ## Drill diameter for alignment holes
- self.drill_dia = LengthEntry()
- form_layout.addRow("Drill diam.:", self.drill_dia)
-
- ## Buttons
- hlay = QtGui.QHBoxLayout()
- self.layout.addLayout(hlay)
- hlay.addStretch()
- self.create_alignment_hole_button = QtGui.QPushButton("Create Alignment Drill")
- self.mirror_object_button = QtGui.QPushButton("Mirror Object")
- hlay.addWidget(self.create_alignment_hole_button)
- hlay.addWidget(self.mirror_object_button)
-
- self.layout.addStretch()
-
- ## Signals
- self.create_alignment_hole_button.clicked.connect(self.on_create_alignment_holes)
- self.mirror_object_button.clicked.connect(self.on_mirror)
-
- self.axis_location.group_toggle_fn = self.on_toggle_pointbox
-
- ## Initialize form
- self.mirror_axis.set_value('X')
- self.axis_location.set_value('point')
-
- def on_create_alignment_holes(self):
- axis = self.mirror_axis.get_value()
- mode = self.axis_location.get_value()
-
- if mode == "point":
- px, py = self.point.get_value()
- else:
- selection_index = self.box_combo.currentIndex()
- bb_obj = self.app.collection.object_list[selection_index] # TODO: Direct access??
- xmin, ymin, xmax, ymax = bb_obj.bounds()
- px = 0.5*(xmin+xmax)
- py = 0.5*(ymin+ymax)
-
- xscale, yscale = {"X": (1.0, -1.0), "Y": (-1.0, 1.0)}[axis]
-
- dia = self.drill_dia.get_value()
- tools = {"1": {"C": dia}}
-
- holes = self.alignment_holes.get_value()
- drills = []
-
- for hole in holes:
- point = Point(hole)
- point_mirror = affinity.scale(point, xscale, yscale, origin=(px, py))
- drills.append({"point": point, "tool": "1"})
- drills.append({"point": point_mirror, "tool": "1"})
-
- def obj_init(obj_inst, app_inst):
- obj_inst.tools = tools
- obj_inst.drills = drills
- obj_inst.create_geometry()
-
- self.app.new_object("excellon", "Alignment Drills", obj_init)
-
- def on_mirror(self):
- selection_index = self.object_combo.currentIndex()
- fcobj = self.app.collection.object_list[selection_index]
-
- # For now, lets limit to Gerbers and Excellons.
- # assert isinstance(gerb, FlatCAMGerber)
- if not isinstance(fcobj, FlatCAMGerber) and not isinstance(fcobj, FlatCAMExcellon):
- self.info("ERROR: Only Gerber and Excellon objects can be mirrored.")
- return
-
- axis = self.mirror_axis.get_value()
- mode = self.axis_location.get_value()
-
- if mode == "point":
- px, py = self.point.get_value()
- else:
- selection_index = self.box_combo.currentIndex()
- bb_obj = self.app.collection.object_list[selection_index] # TODO: Direct access??
- xmin, ymin, xmax, ymax = bb_obj.bounds()
- px = 0.5*(xmin+xmax)
- py = 0.5*(ymin+ymax)
-
- fcobj.mirror(axis, [px, py])
- fcobj.plot()
-
- def on_toggle_pointbox(self):
- if self.axis_location.get_value() == "point":
- self.point.show()
- self.box_combo.hide()
- else:
- self.point.hide()
- self.box_combo.show()
-
-
-class Measurement(FlatCAMTool):
-
- toolName = "Measurement Tool"
-
- def __init__(self, app):
- FlatCAMTool.__init__(self, app)
-
- # self.setContentsMargins(0, 0, 0, 0)
- self.layout.setMargin(0)
- self.layout.setContentsMargins(0, 0, 3, 0)
-
- self.setSizePolicy(QtGui.QSizePolicy.Ignored, QtGui.QSizePolicy.Maximum)
-
- self.point1 = None
- self.point2 = None
- self.label = QtGui.QLabel("Click on a reference point ...")
- self.label.setFrameStyle(QtGui.QFrame.StyledPanel | QtGui.QFrame.Plain)
- self.label.setMargin(3)
- self.layout.addWidget(self.label)
- # self.layout.setMargin(0)
- self.setVisible(False)
-
- self.click_subscription = None
- self.move_subscription = None
-
- def install(self):
- FlatCAMTool.install(self)
- self.app.ui.right_layout.addWidget(self)
- self.app.plotcanvas.mpl_connect('key_press_event', self.on_key_press)
-
- def run(self):
- self.toggle()
-
- def on_click(self, event):
- if self.point1 is None:
- self.point1 = (event.xdata, event.ydata)
- else:
- self.point2 = copy(self.point1)
- self.point1 = (event.xdata, event.ydata)
- self.on_move(event)
-
- def on_key_press(self, event):
- if event.key == 'r':
- self.toggle()
-
- def toggle(self):
- if self.isVisible():
- self.setVisible(False)
- self.app.plotcanvas.mpl_disconnect(self.move_subscription)
- self.app.plotcanvas.mpl_disconnect(self.click_subscription)
- else:
- self.setVisible(True)
- self.move_subscription = self.app.plotcanvas.mpl_connect('motion_notify_event', self.on_move)
- self.click_subscription = self.app.plotcanvas.mpl_connect('button_press_event', self.on_click)
-
- def on_move(self, event):
- if self.point1 is None:
- self.label.setText("Click on a reference point...")
- else:
- try:
- dx = event.xdata - self.point1[0]
- dy = event.ydata - self.point1[1]
- d = sqrt(dx**2 + dy**2)
- self.label.setText("D = %.4f D(x) = %.4f D(y) = %.4f" % (d, dx, dy))
- except TypeError:
- pass
- if self.update is not None:
- self.update()
-
-
-
diff --git a/MeasurementTool.py b/MeasurementTool.py
new file mode 100644
index 0000000..f8396d0
--- /dev/null
+++ b/MeasurementTool.py
@@ -0,0 +1,74 @@
+from PyQt4 import QtGui
+from FlatCAMTool import FlatCAMTool
+from copy import copy
+from math import sqrt
+
+
+class Measurement(FlatCAMTool):
+
+ toolName = "Measurement Tool"
+
+ def __init__(self, app):
+ FlatCAMTool.__init__(self, app)
+
+ # self.setContentsMargins(0, 0, 0, 0)
+ self.layout.setMargin(0)
+ self.layout.setContentsMargins(0, 0, 3, 0)
+
+ self.setSizePolicy(QtGui.QSizePolicy.Ignored, QtGui.QSizePolicy.Maximum)
+
+ self.point1 = None
+ self.point2 = None
+ self.label = QtGui.QLabel("Click on a reference point ...")
+ self.label.setFrameStyle(QtGui.QFrame.StyledPanel | QtGui.QFrame.Plain)
+ self.label.setMargin(3)
+ self.layout.addWidget(self.label)
+ # self.layout.setMargin(0)
+ self.setVisible(False)
+
+ self.click_subscription = None
+ self.move_subscription = None
+
+ def install(self):
+ FlatCAMTool.install(self)
+ self.app.ui.right_layout.addWidget(self)
+ self.app.plotcanvas.mpl_connect('key_press_event', self.on_key_press)
+
+ def run(self):
+ self.toggle()
+
+ def on_click(self, event):
+ if self.point1 is None:
+ self.point1 = (event.xdata, event.ydata)
+ else:
+ self.point2 = copy(self.point1)
+ self.point1 = (event.xdata, event.ydata)
+ self.on_move(event)
+
+ def on_key_press(self, event):
+ if event.key == 'r':
+ self.toggle()
+
+ def toggle(self):
+ if self.isVisible():
+ self.setVisible(False)
+ self.app.plotcanvas.mpl_disconnect(self.move_subscription)
+ self.app.plotcanvas.mpl_disconnect(self.click_subscription)
+ else:
+ self.setVisible(True)
+ self.move_subscription = self.app.plotcanvas.mpl_connect('motion_notify_event', self.on_move)
+ self.click_subscription = self.app.plotcanvas.mpl_connect('button_press_event', self.on_click)
+
+ def on_move(self, event):
+ if self.point1 is None:
+ self.label.setText("Click on a reference point...")
+ else:
+ try:
+ dx = event.xdata - self.point1[0]
+ dy = event.ydata - self.point1[1]
+ d = sqrt(dx**2 + dy**2)
+ self.label.setText("D = %.4f D(x) = %.4f D(y) = %.4f" % (d, dx, dy))
+ except TypeError:
+ pass
+ if self.update is not None:
+ self.update()