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