/GUI/Win32/Canvases.py
Python | 306 lines | 185 code | 76 blank | 45 comment | 1 complexity | 66a5f0121d6403e4d65947a105628fe9 MD5 | raw file
1#--------------------------------------------------------------------
2#
3# PyGUI - Canvas - Win32
4#
5#--------------------------------------------------------------------
6
7from math import sin, cos, pi
8import win32con as wc, win32ui as ui, win32gui as gui
9from win32con import PS_SOLID, BS_SOLID, RGN_AND
10#from win32ui import CreatePen, CreateBrush
11#from win32gui import CloseFigure, PathToRegion, AngleArc
12import GDIPlus as gdip
13from StdColors import black, white
14from StdFonts import application_font
15from Components import win_null_brush
16from GCanvases import Canvas as GCanvas
17
18deg = pi / 180
19
20def ir(x, i = int, r = round):
21 return i(r(x))
22
23def irr(rect, ir = ir):
24 l, t, r, b = rect
25 return (ir(l), ir(t), ir(r), ir(b))
26
27#--------------------------------------------------------------------
28
29class GState(object):
30
31 pencolor = black
32 fillcolor = black
33 textcolor = black
34 backcolor = white
35 pensize = 1
36 font = application_font
37
38 win_pen = gdip.Pen(pencolor._win_argb, 1)
39 win_fill_brush = gdip.SolidBrush(fillcolor._win_argb)
40 win_text_brush = gdip.SolidBrush(textcolor._win_argb)
41 win_bg_brush = gdip.SolidBrush(backcolor._win_argb)
42
43 def __init__(self, clone = None):
44 if clone:
45 self.__dict__.update(clone.__dict__)
46
47#--------------------------------------------------------------------
48
49class Canvas(GCanvas):
50
51 _current_point = None
52
53# def __init__(self, win_graphics, dc = None):
54# if not dc:
55# print "Canvas.__init__: before get dc: clip bounds =", win_graphics.GetClipBounds() ###
56# dc = ui.CreateDCFromHandle(win_graphics.GetHDC())
57# print "Canvas.__init__: after get dc: clip bounds =", win_graphics.GetClipBounds() ###
58# dc.SetBkMode(wc.TRANSPARENT)
59# dc.SetTextAlign(wc.TA_LEFT | wc.TA_BASELINE | wc.TA_UPDATECP)
60# print "Canvas.__init__: clip bounds =", win_graphics.GetClipBounds() ###
61# self._win_graphics = win_graphics
62# self._win_dc = dc
63# self._win_hdc = dc.GetHandleOutput()
64# self._win_path = gdip.GraphicsPath()
65# self._state = GState()
66# self._stack = []
67
68 def __init__(self, win_graphics):
69 self._win_graphics = win_graphics
70 self._win_path = gdip.GraphicsPath()
71 self._state = GState()
72 self._stack = []
73
74 def _from_win_dc(cls, dc):
75 #self._win_dc = dc
76 hdc = dc.GetSafeHdc()
77 #self._win_hdc = hdc
78 win_graphics = gdip.Graphics.from_hdc(hdc)
79 return cls(win_graphics)
80
81 _from_win_dc = classmethod(_from_win_dc)
82
83 def _from_win_image(cls, win_image):
84 win_graphics = gdip.Graphics.from_image(win_image)
85 print "Canvas._from_win_image: win_graphics =", win_graphics ###
86 print "... clip bounds =", win_graphics.GetClipBounds() ###
87 return cls(win_graphics)
88
89 _from_win_image = classmethod(_from_win_image)
90
91 def get_pencolor(self):
92 return self._state.pencolor
93
94 def set_pencolor(self, c):
95 state = self._state
96 state.pencolor = c
97 state.win_pen = gdip.Pen(c._win_argb, state.pensize)
98
99 def get_fillcolor(self):
100 return self._state.fillcolor
101
102 def set_fillcolor(self, c):
103 state = self._state
104 state.fillcolor = c
105 state.win_fill_brush = gdip.SolidBrush(c._win_argb)
106
107 def get_textcolor(self):
108 return self._state.textcolor
109
110 def set_textcolor(self, c):
111 state = self._state
112 state.textcolor = c
113 state.win_text_brush = gdip.SolidBrush(c._win_argb)
114
115 def get_backcolor(self):
116 return self._state.backcolor
117
118 def set_backcolor(self, c):
119 state = self._state
120 state.backcolor = c
121 state.win_bg_brush = gdip.SolidBrush(c._win_argb)
122
123 def get_pensize(self):
124 return self._state.pensize
125
126 def set_pensize(self, x):
127 state = self._state
128 state.pensize = x
129 state.win_pen = gdip.Pen(state.pencolor._win_argb, x)
130
131 def get_current_point(self):
132 return self._current_point
133
134 def get_font(self):
135 return self._state.font
136
137 def set_font(self, f):
138 self._state.font = f
139
140 def newpath(self):
141 self._win_path.Reset()
142
143 def moveto(self, x, y):
144 p = (x, y)
145 self._current_point = p
146 self._win_path.StartFigure()
147
148 def lineto(self, x, y):
149 x0, y0 = self._current_point
150 self._win_path.AddLine_4f(x0, y0, x, y)
151 self._current_point = (x, y)
152
153 def curveto(self, p1, p2, p3):
154 p0 = self._current_point
155 self._win_path.AddBezier_4p(p0, p1, p2, p3)
156 self._current_point = p3
157
158 def arc(self, c, r, a0, a1):
159 g = self._win_path
160 g.AddArc_p3f(c, r, a0, a1)
161 self._current_point = g.GetLastPoint()
162
163 def closepath(self):
164 self._win_path.CloseFigure()
165 self._current_point = None
166
167 def fill(self):
168 self._win_graphics.FillPath(self._state.win_fill_brush, self._win_path)
169
170 def stroke(self):
171 self._win_graphics.DrawPath(self._state.win_pen, self._win_path)
172
173 def erase(self):
174 g = self._win_graphics
175 g.SetSourceCopyMode()
176 g.FillPath(self._state.win_bg_brush, self._win_path)
177 g.SetSourceOverMode()
178
179 def show_text(self, text):
180 font = self._state.font
181 gf = font._win_gdip_font
182 x, y = self._current_point
183 brush = self._state.win_text_brush
184 g = self._win_graphics
185 w = g.DrawAndMeasureStringWidth_2f(text, gf, x, y, brush)
186 self._current_point = x + w, y
187
188##
189## GDI+ screws up some fonts (e.g. Times) for some reason.
190## Using plain GDI to draw text for now.
191##
192# def show_text(self, text):
193# state = self._state
194# x, y = self._current_point
195# dc = self._win_dc
196# dc.SelectObject(state.font._win_font)
197# dc.SetTextColor(state.textcolor._win_color)
198# dc.MoveTo(ir(x), ir(y))
199# dc.TextOut(20, 20, text)
200# self._current_point = dc.GetCurrentPosition()
201
202 def clip(self):
203 self._win_graphics.SetClip_PI(self._win_path)
204
205 def rectclip(self, rect):
206 self._win_graphics.SetClip_rI(rect)
207
208 def gsave(self):
209 old_state = self._state
210 old_state.win_state = self._win_graphics.Save()
211 self._stack.append(old_state)
212 self._state = GState(old_state)
213
214 def grestore(self):
215 old_state = self._stack.pop()
216 self._win_graphics.Restore(old_state.win_state)
217 self._state = old_state
218
219 # Rectangles
220
221 def rect(self, rect):
222 self._win_path.AddRectangle_r(rect)
223 self._current_point = None
224
225 def fill_rect(self, rect):
226 self._win_graphics.FillRectangle_r(self._state.win_fill_brush, rect)
227
228 def stroke_rect(self, rect):
229 self._win_graphics.DrawRectangle_r(self._state.win_pen, rect)
230
231 def erase_rect(self, rect):
232 self._win_graphics.FillRectangle_r(self._state.win_bg_brush, rect)
233
234 # Ovals
235
236 def oval(self, rect):
237 self._win_path.AddEllipse_r(rect)
238 self._current_point = None
239
240 def fill_oval(self, rect):
241 self._win_graphics.FillEllipse_r(self._state.win_fill_brush, rect)
242
243 def stroke_oval(self, rect):
244 self._win_graphics.DrawEllipse_r(self._state.win_pen, rect)
245
246 def erase_oval(self, rect):
247 self._win_graphics.FillEllipse_r(self._state.win_bg_brush, rect)
248
249 # Arcs
250
251 def stroke_arc(self, c, r, a0, a1):
252 self._win_graphics.DrawArc_3pf(self._state.win_pen, c, r, a0, a1)
253
254 # Wedges
255
256 def wedge(self, c, r, a0, a1):
257 self._win_path.AddPie_p3f(c, r, a0, a1)
258 self._current_point = None
259
260 def stroke_wedge(self, c, r, a0, a1):
261 self._win_graphics.DrawPie_p3f(self._state.win_pen, c, r, a0, a1)
262
263 def fill_wedge(self, c, r, a0, a1):
264 self._win_graphics.FillPie_p3f(self._state.win_fill_brush, c, r, a0, a1)
265
266 def erase_wedge(self, c, r, a0, a1):
267 self._win_graphics.FillPie_p3f(self._state.win_bg_brush, c, r, a0, a1)
268
269 # Polylines
270
271 def lines(self, points):
272 self._win_path.AddLines_pv(points)
273 self._current_point = points[-1]
274
275 def linesto(self, points):
276 self.lines([self._current_point] + points)
277
278 def stroke_lines(self, points):
279 self._win_graphics.DrawLines_pv(self._state.win_pen, points)
280
281 # Polygons
282
283 def poly(self, points):
284 self._win_path.AddPolygon_pv(points)
285 self._current_point = None
286
287 def stroke_poly(self, points):
288 self._win_graphics.DrawPolygon_pv(self._state.win_pen, points)
289
290 def fill_poly(self, points):
291 self._win_graphics.FillPolygon_pv(self._state.win_fill_brush, points)
292
293 def erase_poly(self, points):
294 self._win_graphics.FillPolygon_pv(self._state.win_bg_brush, points)
295
296 # Polycurves
297
298 def curves(self, points):
299 self._win_path.AddBeziers_pv(points)
300 self._current_point = points[-1]
301
302 def curvesto(self, points):
303 self.curves([self._current_point] + points)
304
305 def stroke_curves(self, points):
306 self._win_graphics.DrawBeziers_pv(self._state.win_pen, points)