printrun-src/printrun/excluder.py

changeset 15
0bbb006204fc
child 46
cce0af6351f0
equal deleted inserted replaced
14:51bf56ba3c10 15:0bbb006204fc
1 # This file is part of the Printrun suite.
2 #
3 # Printrun is free software: you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation, either version 3 of the License, or
6 # (at your option) any later version.
7 #
8 # Printrun is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
12 #
13 # You should have received a copy of the GNU General Public License
14 # along with Printrun. If not, see <http://www.gnu.org/licenses/>.
15
16 import wx
17 from printrun import gviz
18
19 from .utils import imagefile, install_locale
20 install_locale('pronterface')
21
22 class ExcluderWindow(gviz.GvizWindow):
23
24 def __init__(self, excluder, *args, **kwargs):
25 super(ExcluderWindow, self).__init__(*args, **kwargs)
26 self.SetTitle(_("Part excluder: draw rectangles where print instructions should be ignored"))
27 self.toolbar.AddLabelTool(128, " " + _("Reset selection"),
28 wx.Image(imagefile('reset.png'), wx.BITMAP_TYPE_PNG).ConvertToBitmap(),
29 shortHelp = _("Reset selection"),
30 longHelp = "")
31 self.Bind(wx.EVT_TOOL, self.reset_selection, id = 128)
32 self.parent = excluder
33 self.p.paint_overlay = self.paint_selection
34 self.p.layerup()
35
36 def real_to_gcode(self, x, y):
37 return (x + self.p.build_dimensions[3],
38 self.p.build_dimensions[4] + self.p.build_dimensions[1] - y)
39
40 def gcode_to_real(self, x, y):
41 return (x - self.p.build_dimensions[3],
42 self.p.build_dimensions[1] - (y - self.p.build_dimensions[4]))
43
44 def mouse(self, event):
45 if event.ButtonUp(wx.MOUSE_BTN_LEFT) \
46 or event.ButtonUp(wx.MOUSE_BTN_RIGHT):
47 self.initpos = None
48 elif event.Dragging() and event.RightIsDown():
49 e = event.GetPositionTuple()
50 if not self.initpos or not hasattr(self, "basetrans"):
51 self.initpos = e
52 self.basetrans = self.p.translate
53 self.p.translate = [self.basetrans[0] + (e[0] - self.initpos[0]),
54 self.basetrans[1] + (e[1] - self.initpos[1])]
55 self.p.dirty = 1
56 wx.CallAfter(self.p.Refresh)
57 elif event.Dragging() and event.LeftIsDown():
58 x, y = event.GetPositionTuple()
59 if not self.initpos:
60 self.basetrans = self.p.translate
61 x = (x - self.basetrans[0]) / self.p.scale[0]
62 y = (y - self.basetrans[1]) / self.p.scale[1]
63 x, y = self.real_to_gcode(x, y)
64 if not self.initpos:
65 self.initpos = (x, y)
66 self.parent.rectangles.append((0, 0, 0, 0))
67 else:
68 pos = (x, y)
69 x0 = min(self.initpos[0], pos[0])
70 y0 = min(self.initpos[1], pos[1])
71 x1 = max(self.initpos[0], pos[0])
72 y1 = max(self.initpos[1], pos[1])
73 self.parent.rectangles[-1] = (x0, y0, x1, y1)
74 wx.CallAfter(self.p.Refresh)
75 else:
76 event.Skip()
77
78 def _line_scaler(self, orig):
79 x0, y0 = self.gcode_to_real(orig[0], orig[1])
80 x0 = self.p.scale[0] * x0 + self.p.translate[0]
81 y0 = self.p.scale[1] * y0 + self.p.translate[1]
82 x1, y1 = self.gcode_to_real(orig[2], orig[3])
83 x1 = self.p.scale[0] * x1 + self.p.translate[0]
84 y1 = self.p.scale[1] * y1 + self.p.translate[1]
85 width = max(x0, x1) - min(x0, x1) + 1
86 height = max(y0, y1) - min(y0, y1) + 1
87 return (min(x0, x1), min(y0, y1), width, height,)
88
89 def paint_selection(self, dc):
90 dc = wx.GCDC(dc)
91 dc.SetPen(wx.TRANSPARENT_PEN)
92 dc.DrawRectangleList([self._line_scaler(rect)
93 for rect in self.parent.rectangles],
94 None, wx.Brush((200, 200, 200, 150)))
95
96 def reset_selection(self, event):
97 self.parent.rectangles = []
98 wx.CallAfter(self.p.Refresh)
99
100 class Excluder(object):
101
102 def __init__(self):
103 self.rectangles = []
104 self.window = None
105
106 def pop_window(self, gcode, *args, **kwargs):
107 if not self.window:
108 self.window = ExcluderWindow(self, *args, **kwargs)
109 self.window.p.addfile(gcode, True)
110 self.window.Bind(wx.EVT_CLOSE, self.close_window)
111 self.window.Show()
112 else:
113 self.window.Show()
114 self.window.Raise()
115
116 def close_window(self, event = None):
117 if self.window:
118 self.window.Destroy()
119 self.window = None
120
121 if __name__ == '__main__':
122 import sys
123 import gcoder
124 gcode = gcoder.GCode(open(sys.argv[1]))
125 app = wx.App(False)
126 ex = Excluder()
127 ex.pop_window(gcode)
128 app.MainLoop()

mercurial