/GUI/Win32/Canvases.py

https://bitbucket.org/alsh/pygui-mirror · Python · 306 lines · 185 code · 76 blank · 45 comment · 1 complexity · 66a5f0121d6403e4d65947a105628fe9 MD5 · raw file

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