/GUI/Cocoa/Canvases.py

https://bitbucket.org/alsh/pygui-mirror · Python · 243 lines · 180 code · 53 blank · 10 comment · 0 complexity · 7a7da51eb20d9de3fa4396a3da511fb6 MD5 · raw file

  1. #
  2. # Python GUI - Drawing - PyObjC
  3. #
  4. from Foundation import NSPoint, NSMakeRect, NSString
  5. from AppKit import NSGraphicsContext, NSBezierPath, NSEvenOddWindingRule, \
  6. NSFontAttributeName, NSForegroundColorAttributeName, \
  7. NSCompositeCopy, NSCompositeSourceOver
  8. from StdColors import black, white
  9. from GCanvases import Canvas as GCanvas
  10. class Canvas(GCanvas):
  11. def __init__(self):
  12. self._ns_path = NSBezierPath.bezierPath()
  13. self._ns_path.setWindingRule_(NSEvenOddWindingRule)
  14. self._stack = []
  15. ctx = NSGraphicsContext.currentContext()
  16. ctx.setCompositingOperation_(NSCompositeSourceOver)
  17. GCanvas.__init__(self)
  18. self.initgraphics()
  19. def get_pencolor(self):
  20. return self._pencolor
  21. def set_pencolor(self, c):
  22. self._pencolor = c
  23. def get_fillcolor(self):
  24. return self._fillcolor
  25. def set_fillcolor(self, c):
  26. self._fillcolor = c
  27. def get_textcolor(self):
  28. return self._textcolor
  29. def set_textcolor(self, c):
  30. self._textcolor = c
  31. def get_backcolor(self):
  32. return self._backcolor
  33. def set_backcolor(self, c):
  34. self._backcolor = c
  35. def get_pensize(self):
  36. return self._pensize
  37. def set_pensize(self, d):
  38. self._pensize = d
  39. self._ns_path.setLineWidth_(d)
  40. def get_font(self):
  41. return self._font
  42. def set_font(self, f):
  43. self._font = f
  44. def get_current_point(self):
  45. return self._ns_path.currentPoint()
  46. def newpath(self):
  47. self._ns_path.removeAllPoints()
  48. def moveto(self, x, y):
  49. self._ns_path.moveToPoint_((x, y))
  50. def rmoveto(self, dx, dy):
  51. self._ns_path.relativeMoveToPoint_((dx, dy))
  52. def lineto(self, x, y):
  53. self._ns_path.lineToPoint_((x, y))
  54. def rlineto(self, dx, dy):
  55. self._ns_path.relativeLineToPoint_((dx, dy))
  56. def curveto(self, cp1, cp2, ep):
  57. self._ns_path.curveToPoint_controlPoint1_controlPoint2_(
  58. ep, cp1, *cp2)
  59. def rcurveto(self, cp1, cp2, ep):
  60. self._ns_path.relativeCurveToPoint_controlPoint1_controlPoint2_(
  61. ep, cp1, cp2)
  62. def arc(self, c, r, a0, a1):
  63. self._ns_path.appendBezierPathWithArcWithCenter_radius_startAngle_endAngle_(
  64. c, r, a0, a1)
  65. def rect(self, rect):
  66. self._ns_path.appendBezierPathWithRect_(_ns_rect(rect))
  67. def oval(self, rect):
  68. self._ns_path.appendBezierPathWithOvalInRect(_ns_rect(rect))
  69. def lines(self, points):
  70. ns = self._ns_path
  71. ns.moveToPoint_(points[0])
  72. ns.appendBezierPathWithPoints_count_(points)
  73. def poly(self, points):
  74. ns = self._ns_path
  75. ns.moveToPoint_(points[0])
  76. ns.appendBezierPathWithPoints_count_(points)
  77. ns.closePath()
  78. def closepath(self):
  79. self._ns_path.closePath()
  80. def clip(self):
  81. ns = self._ns_path
  82. ns.addClip()
  83. def rectclip(self, (l, t, r, b)):
  84. ns_rect = NSMakeRect(l, t, r - l, b - t)
  85. NSBezierPath.clipRect_(ns_rect)
  86. def gsave(self):
  87. self._stack.append((
  88. self._pencolor, self._fillcolor, self._textcolor, self._backcolor,
  89. self._pensize, self._font))
  90. NSGraphicsContext.currentContext().saveGraphicsState()
  91. def grestore(self):
  92. (self._pencolor, self._fillcolor, self._textcolor, self._backcolor,
  93. self._pensize, self._font) = self._stack.pop()
  94. NSGraphicsContext.currentContext().restoreGraphicsState()
  95. def stroke(self):
  96. ns = self._ns_path
  97. self._pencolor._ns_color.set()
  98. ns.stroke()
  99. def fill(self):
  100. ns = self._ns_path
  101. self._fillcolor._ns_color.set()
  102. ns.fill()
  103. def erase(self):
  104. ns = self._ns_path
  105. self._backcolor._ns_color.set()
  106. ctx = NSGraphicsContext.currentContext()
  107. ctx.setCompositingOperation_(NSCompositeCopy)
  108. ns.fill()
  109. ctx.setCompositingOperation_(NSCompositeSourceOver)
  110. def fill_stroke(self):
  111. ns = self._ns_path
  112. self._pencolor._ns_color.set()
  113. ns.stroke()
  114. self._fillcolor._ns_color.set()
  115. ns.fill()
  116. def show_text(self, text):
  117. x, y = self._ns_path.currentPoint()
  118. font = self._font
  119. ns_font = font._ns_font
  120. ns_color = self._textcolor._ns_color
  121. ns_string = NSString.stringWithString_(text)
  122. ns_attrs = {
  123. NSFontAttributeName: ns_font,
  124. NSForegroundColorAttributeName: ns_color,
  125. }
  126. #print "Canvas.show_text:", repr(text) ###
  127. #print "size:", ns_font.pointSize() ###
  128. #print "ascender:", ns_font.ascender() ###
  129. #print "descender:", ns_font.descender() ###
  130. #print "capHeight:", ns_font.capHeight() ###
  131. #print "defaultLineHeightForFont:", ns_font.defaultLineHeightForFont() ###
  132. h = ns_font.defaultLineHeightForFont()
  133. d = -ns_font.descender()
  134. ns_point = NSPoint(x, y - h + d)
  135. #print "drawing at:", ns_point ###
  136. ns_string.drawAtPoint_withAttributes_(ns_point, ns_attrs)
  137. dx = ns_font.widthOfString_(ns_string)
  138. self._ns_path.relativeMoveToPoint_(NSPoint(x + dx, y))
  139. def _ns_frame_rect(self, (l, t, r, b)):
  140. p = self._pensize
  141. q = 0.5 * p
  142. return NSMakeRect(l + q, t + q, r - l - p, b - t - p)
  143. def stroke_rect(self, r):
  144. self._pencolor._ns_color.set()
  145. NSBezierPath.setDefaultLineWidth_(self._pensize)
  146. NSBezierPath.strokeRect_(_ns_rect(r))
  147. def frame_rect(self, r):
  148. self._pencolor._ns_color.set()
  149. NSBezierPath.setDefaultLineWidth_(self._pensize)
  150. NSBezierPath.strokeRect_(self._ns_frame_rect(r))
  151. def fill_rect(self, r):
  152. self._fillcolor._ns_color.set()
  153. NSBezierPath.fillRect_(_ns_rect(r))
  154. def erase_rect(self, r):
  155. self._backcolor._ns_color.set()
  156. NSBezierPath.fillRect_(_ns_rect(r))
  157. def _ns_oval_path(self, ns_rect):
  158. ns_path = NSBezierPath.bezierPathWithOvalInRect_(ns_rect)
  159. ns_path.setLineWidth_(self._pensize)
  160. return ns_path
  161. def stroke_oval(self, r):
  162. self._pencolor._ns_color.set()
  163. self._ns_oval_path(_ns_rect(r)).stroke()
  164. def frame_oval(self, r):
  165. self._pencolor._ns_color.set()
  166. self._ns_oval_path(self._ns_frame_rect(r)).stroke()
  167. def fill_oval(self, r):
  168. self._fillcolor._ns_color.set()
  169. self._ns_oval_path(_ns_rect(r)).fill()
  170. def erase_oval(self, r):
  171. self._backcolor._ns_color.set()
  172. self._ns_oval_path(_ns_rect(r)).fill()
  173. def _ns_arc_path(self, c, r, sa, ea):
  174. ns_path = NSBezierPath.bezierPath()
  175. ns_path.setLineWidth_(self._pensize)
  176. ns_path.\
  177. appendBezierPathWithArcWithCenter_radius_startAngle_endAngle_(
  178. c, r, sa, ea)
  179. return ns_path
  180. def stroke_arc(self, center, radius, start_angle, arc_angle):
  181. ns_path = self._ns_arc_path(center, radius, start_angle, arc_angle)
  182. self._pencolor._ns_color.set()
  183. ns_path.stroke()
  184. def frame_arc(self, center, radius, start_angle, arc_angle):
  185. r = radius - 0.5 * self._pensize
  186. ns_path = self._ns_arc_path(center, r, start_angle, arc_angle)
  187. self._pencolor._ns_color.set()
  188. ns_path.stroke()
  189. def _ns_rect((l, t, r, b)):
  190. return NSMakeRect(l, t, r - l, b - t)