printrun-src/printrun/excluder.py

changeset 15
0bbb006204fc
child 46
cce0af6351f0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/printrun-src/printrun/excluder.py	Fri Jun 03 09:16:07 2016 +0200
@@ -0,0 +1,128 @@
+# This file is part of the Printrun suite.
+#
+# Printrun is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Printrun is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Printrun.  If not, see <http://www.gnu.org/licenses/>.
+
+import wx
+from printrun import gviz
+
+from .utils import imagefile, install_locale
+install_locale('pronterface')
+
+class ExcluderWindow(gviz.GvizWindow):
+
+    def __init__(self, excluder, *args, **kwargs):
+        super(ExcluderWindow, self).__init__(*args, **kwargs)
+        self.SetTitle(_("Part excluder: draw rectangles where print instructions should be ignored"))
+        self.toolbar.AddLabelTool(128, " " + _("Reset selection"),
+                                  wx.Image(imagefile('reset.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(),
+                                  shortHelp = _("Reset selection"),
+                                  longHelp = "")
+        self.Bind(wx.EVT_TOOL, self.reset_selection, id = 128)
+        self.parent = excluder
+        self.p.paint_overlay = self.paint_selection
+        self.p.layerup()
+
+    def real_to_gcode(self, x, y):
+        return (x + self.p.build_dimensions[3],
+                self.p.build_dimensions[4] + self.p.build_dimensions[1] - y)
+
+    def gcode_to_real(self, x, y):
+        return (x - self.p.build_dimensions[3],
+                self.p.build_dimensions[1] - (y - self.p.build_dimensions[4]))
+
+    def mouse(self, event):
+        if event.ButtonUp(wx.MOUSE_BTN_LEFT) \
+           or event.ButtonUp(wx.MOUSE_BTN_RIGHT):
+            self.initpos = None
+        elif event.Dragging() and event.RightIsDown():
+            e = event.GetPositionTuple()
+            if not self.initpos or not hasattr(self, "basetrans"):
+                self.initpos = e
+                self.basetrans = self.p.translate
+            self.p.translate = [self.basetrans[0] + (e[0] - self.initpos[0]),
+                                self.basetrans[1] + (e[1] - self.initpos[1])]
+            self.p.dirty = 1
+            wx.CallAfter(self.p.Refresh)
+        elif event.Dragging() and event.LeftIsDown():
+            x, y = event.GetPositionTuple()
+            if not self.initpos:
+                self.basetrans = self.p.translate
+            x = (x - self.basetrans[0]) / self.p.scale[0]
+            y = (y - self.basetrans[1]) / self.p.scale[1]
+            x, y = self.real_to_gcode(x, y)
+            if not self.initpos:
+                self.initpos = (x, y)
+                self.parent.rectangles.append((0, 0, 0, 0))
+            else:
+                pos = (x, y)
+                x0 = min(self.initpos[0], pos[0])
+                y0 = min(self.initpos[1], pos[1])
+                x1 = max(self.initpos[0], pos[0])
+                y1 = max(self.initpos[1], pos[1])
+                self.parent.rectangles[-1] = (x0, y0, x1, y1)
+            wx.CallAfter(self.p.Refresh)
+        else:
+            event.Skip()
+
+    def _line_scaler(self, orig):
+        x0, y0 = self.gcode_to_real(orig[0], orig[1])
+        x0 = self.p.scale[0] * x0 + self.p.translate[0]
+        y0 = self.p.scale[1] * y0 + self.p.translate[1]
+        x1, y1 = self.gcode_to_real(orig[2], orig[3])
+        x1 = self.p.scale[0] * x1 + self.p.translate[0]
+        y1 = self.p.scale[1] * y1 + self.p.translate[1]
+        width = max(x0, x1) - min(x0, x1) + 1
+        height = max(y0, y1) - min(y0, y1) + 1
+        return (min(x0, x1), min(y0, y1), width, height,)
+
+    def paint_selection(self, dc):
+        dc = wx.GCDC(dc)
+        dc.SetPen(wx.TRANSPARENT_PEN)
+        dc.DrawRectangleList([self._line_scaler(rect)
+                              for rect in self.parent.rectangles],
+                             None, wx.Brush((200, 200, 200, 150)))
+
+    def reset_selection(self, event):
+        self.parent.rectangles = []
+        wx.CallAfter(self.p.Refresh)
+
+class Excluder(object):
+
+    def __init__(self):
+        self.rectangles = []
+        self.window = None
+
+    def pop_window(self, gcode, *args, **kwargs):
+        if not self.window:
+            self.window = ExcluderWindow(self, *args, **kwargs)
+            self.window.p.addfile(gcode, True)
+            self.window.Bind(wx.EVT_CLOSE, self.close_window)
+            self.window.Show()
+        else:
+            self.window.Show()
+            self.window.Raise()
+
+    def close_window(self, event = None):
+        if self.window:
+            self.window.Destroy()
+            self.window = None
+
+if __name__ == '__main__':
+    import sys
+    import gcoder
+    gcode = gcoder.GCode(open(sys.argv[1]))
+    app = wx.App(False)
+    ex = Excluder()
+    ex.pop_window(gcode)
+    app.MainLoop()

mercurial