|
70 | 70 | (unless (even? (length args)) |
71 | 71 | (error 'method-spec "expected a list of types and argument names, but found ~a arguments" |
72 | 72 | (length args))) |
73 | | - (let ([first-line |
74 | | - (hbl-append |
75 | | - (type-spec range) |
76 | | - (normal-font " ") |
77 | | - (var-font name) |
78 | | - (cond |
79 | | - [(null? args) |
80 | | - (normal-font "()")] |
81 | | - [else |
82 | | - (hbl-append |
83 | | - (normal-font "(") |
84 | | - (let loop ([args args]) |
85 | | - (let* ([type (car args)] |
86 | | - [param (cadr args)] |
87 | | - [single-arg |
88 | | - (if param |
89 | | - (hbl-append (type-spec type) |
90 | | - (normal-font " ") |
91 | | - (var-font param)) |
92 | | - (type-spec type))]) |
93 | | - |
94 | | - (cond |
95 | | - [(null? (cddr args)) |
96 | | - (hbl-append single-arg (normal-font ")"))] |
97 | | - [else |
98 | | - (hbl-append single-arg |
99 | | - (normal-font ", ") |
100 | | - (loop (cddr args)))]))))]) |
101 | | - (if body |
102 | | - (hbl-append (normal-font " {")) |
103 | | - (blank)))]) |
104 | | - (if body |
105 | | - (vl-append first-line |
106 | | - (hbl-append (blank 8 0) body (normal-font "}"))) |
107 | | - first-line))) |
| 73 | + (define first-line |
| 74 | + (hbl-append |
| 75 | + (type-spec range) |
| 76 | + (normal-font " ") |
| 77 | + (var-font name) |
| 78 | + (cond |
| 79 | + [(null? args) (normal-font "()")] |
| 80 | + [else |
| 81 | + (hbl-append |
| 82 | + (normal-font "(") |
| 83 | + (let loop ([args args]) |
| 84 | + (let* ([type (car args)] |
| 85 | + [param (cadr args)] |
| 86 | + [single-arg (if param |
| 87 | + (hbl-append (type-spec type) (normal-font " ") (var-font param)) |
| 88 | + (type-spec type))]) |
| 89 | + |
| 90 | + (cond |
| 91 | + [(null? (cddr args)) (hbl-append single-arg (normal-font ")"))] |
| 92 | + [else (hbl-append single-arg (normal-font ", ") (loop (cddr args)))]))))]) |
| 93 | + (if body |
| 94 | + (hbl-append (normal-font " {")) |
| 95 | + (blank)))) |
| 96 | + (if body |
| 97 | + (vl-append first-line (hbl-append (blank 8 0) body (normal-font "}"))) |
| 98 | + first-line)) |
108 | 99 |
|
109 | 100 | (define (type-spec str) |
110 | 101 | (cond |
|
126 | 117 |
|
127 | 118 | ;; class-box : pict (or/c #f (listof pict)) (or/c #f (listof pict)) -> pict |
128 | 119 | (define (class-box name fields methods) |
129 | | - (let* ([mk-blank (λ () (blank 0 (+ class-box-margin class-box-margin)))]) |
130 | | - (cond |
131 | | - [(and methods fields) |
132 | | - (let* ([top-spacer (mk-blank)] |
133 | | - [bottom-spacer (mk-blank)] |
134 | | - [main (vl-append name |
135 | | - top-spacer |
136 | | - (if (null? fields) |
137 | | - (blank 0 4) |
138 | | - (apply vl-append fields)) |
139 | | - bottom-spacer |
140 | | - (if (null? methods) |
141 | | - (blank 0 4) |
142 | | - (apply vl-append methods)))]) |
143 | | - (add-hline |
144 | | - (add-hline (frame (inset main class-box-margin)) |
145 | | - top-spacer) |
146 | | - bottom-spacer))] |
147 | | - [fields |
148 | | - (let* ([top-spacer (mk-blank)] |
149 | | - [main (vl-append name |
150 | | - top-spacer |
151 | | - (if (null? fields) |
152 | | - (blank) |
153 | | - (apply vl-append fields)))]) |
154 | | - (add-hline (frame (inset main class-box-margin)) |
155 | | - top-spacer))] |
156 | | - [methods (class-box name methods fields)] |
157 | | - [else (frame (inset name class-box-margin))]))) |
| 120 | + (define (mk-blank) |
| 121 | + (blank 0 (+ class-box-margin class-box-margin))) |
| 122 | + (cond |
| 123 | + [(and methods fields) |
| 124 | + (let* ([top-spacer (mk-blank)] |
| 125 | + [bottom-spacer (mk-blank)] |
| 126 | + [main (vl-append name |
| 127 | + top-spacer |
| 128 | + (if (null? fields) |
| 129 | + (blank 0 4) |
| 130 | + (apply vl-append fields)) |
| 131 | + bottom-spacer |
| 132 | + (if (null? methods) |
| 133 | + (blank 0 4) |
| 134 | + (apply vl-append methods)))]) |
| 135 | + (add-hline (add-hline (frame (inset main class-box-margin)) top-spacer) bottom-spacer))] |
| 136 | + [fields |
| 137 | + (let* ([top-spacer (mk-blank)] |
| 138 | + [main (vl-append name |
| 139 | + top-spacer |
| 140 | + (if (null? fields) |
| 141 | + (blank) |
| 142 | + (apply vl-append fields)))]) |
| 143 | + (add-hline (frame (inset main class-box-margin)) top-spacer))] |
| 144 | + [methods (class-box name methods fields)] |
| 145 | + [else (frame (inset name class-box-margin))])) |
158 | 146 |
|
159 | 147 | (define (add-hline main sub) |
160 | | - (let-values ([(x y) (cc-find main sub)]) |
161 | | - (pin-line main |
162 | | - sub (λ (p1 p2) (values 0 y)) |
163 | | - sub (λ (p1 p2) (values (pict-width main) y))))) |
| 148 | + (define-values (x y) (cc-find main sub)) |
| 149 | + (pin-line main sub (λ (p1 p2) (values 0 y)) sub (λ (p1 p2) (values (pict-width main) y)))) |
164 | 150 |
|
165 | 151 | ;; hierarchy : pict (cons pict (listof pict)) (cons pict (listof pict)) -> pict |
166 | 152 | (define (hierarchy main supers subs) |
167 | | - (let ([supers-bottoms (apply max (map (λ (x) (let-values ([(x y) (cb-find main x)]) y)) supers))] |
168 | | - [subs-tops (apply min (map (λ (x) (let-values ([(x y) (ct-find main x)]) y)) subs))] |
169 | | - [sorted-subs (sort subs (λ (x y) (< (left-edge-x main x) (left-edge-x main y))))]) |
170 | | - (unless (< supers-bottoms subs-tops) |
171 | | - (error 'hierarchy "expected supers to be on top of subs, supers bottom is at ~a, and subs tops is at ~a" |
172 | | - supers-bottoms |
173 | | - subs-tops)) |
174 | | - (let* ([main-line-y (max (- subs-tops 20) (/ (+ supers-bottoms subs-tops) 2))] |
175 | | - [main-line-start-x (center-x main (car sorted-subs))] |
176 | | - [main-line-end-x (center-x main (last sorted-subs))] |
177 | | - [w/main-line |
178 | | - (pin-line main |
179 | | - main (λ (_1 _2) (values main-line-start-x main-line-y)) |
180 | | - main (λ (_1 _2) (values main-line-end-x main-line-y)) |
181 | | - #:color hierarchy-color)] |
182 | | - [super-lines |
183 | | - (map (λ (super) |
184 | | - (let-values ([(x y) (cb-find main super)]) |
185 | | - (pin-over |
186 | | - (pin-line (ghost main) |
187 | | - super cb-find |
188 | | - main (λ (_1 _2) (values x main-line-y))) |
189 | | - (- x (/ (pict-width triangle) 2)) |
190 | | - (- (/ (+ y main-line-y) 2) |
191 | | - (/ (pict-height triangle) 2)) |
192 | | - triangle))) |
193 | | - supers)] |
194 | | - [sub-lines |
195 | | - (map (λ (sub) |
196 | | - (let-values ([(x y) (ct-find main sub)]) |
197 | | - (pin-line (ghost main) |
198 | | - sub ct-find |
199 | | - main (λ (_1 _2) (values x main-line-y)) |
200 | | - #:color hierarchy-color))) |
201 | | - subs)]) |
202 | | - (apply cc-superimpose |
203 | | - w/main-line |
204 | | - (append sub-lines |
205 | | - super-lines))))) |
| 153 | + (define supers-bottoms |
| 154 | + (apply max |
| 155 | + (map (λ (x) |
| 156 | + (let-values ([(x y) (cb-find main x)]) |
| 157 | + y)) |
| 158 | + supers))) |
| 159 | + (define subs-tops |
| 160 | + (apply min |
| 161 | + (map (λ (x) |
| 162 | + (let-values ([(x y) (ct-find main x)]) |
| 163 | + y)) |
| 164 | + subs))) |
| 165 | + (define sorted-subs (sort subs (λ (x y) (< (left-edge-x main x) (left-edge-x main y))))) |
| 166 | + (unless (< supers-bottoms subs-tops) |
| 167 | + (error 'hierarchy |
| 168 | + "expected supers to be on top of subs, supers bottom is at ~a, and subs tops is at ~a" |
| 169 | + supers-bottoms |
| 170 | + subs-tops)) |
| 171 | + (define main-line-y (max (- subs-tops 20) (/ (+ supers-bottoms subs-tops) 2))) |
| 172 | + (define main-line-start-x (center-x main (car sorted-subs))) |
| 173 | + (define main-line-end-x (center-x main (last sorted-subs))) |
| 174 | + (define w/main-line |
| 175 | + (pin-line main |
| 176 | + main |
| 177 | + (λ (_1 _2) (values main-line-start-x main-line-y)) |
| 178 | + main |
| 179 | + (λ (_1 _2) (values main-line-end-x main-line-y)) |
| 180 | + #:color hierarchy-color)) |
| 181 | + (define super-lines |
| 182 | + (map (λ (super) |
| 183 | + (let-values ([(x y) (cb-find main super)]) |
| 184 | + (pin-over (pin-line (ghost main) super cb-find main (λ (_1 _2) (values x main-line-y))) |
| 185 | + (- x (/ (pict-width triangle) 2)) |
| 186 | + (- (/ (+ y main-line-y) 2) (/ (pict-height triangle) 2)) |
| 187 | + triangle))) |
| 188 | + supers)) |
| 189 | + (define sub-lines |
| 190 | + (map (λ (sub) |
| 191 | + (let-values ([(x y) (ct-find main sub)]) |
| 192 | + (pin-line (ghost main) |
| 193 | + sub |
| 194 | + ct-find |
| 195 | + main |
| 196 | + (λ (_1 _2) (values x main-line-y)) |
| 197 | + #:color hierarchy-color))) |
| 198 | + subs)) |
| 199 | + (apply cc-superimpose w/main-line (append sub-lines super-lines))) |
206 | 200 |
|
207 | 201 | (define triangle-width 12) |
208 | 202 | (define triangle-height 12) |
|
212 | 206 | (make-object point% triangle-width triangle-height))]) |
213 | 207 | (colorize |
214 | 208 | (dc (λ (dc dx dy) |
215 | | - (let ([brush (send dc get-brush)]) |
216 | | - (send dc set-brush (send brush get-color) 'solid) |
217 | | - (send dc draw-polygon points dx dy) |
218 | | - (send dc set-brush brush))) |
| 209 | + (define brush (send dc get-brush)) |
| 210 | + (send dc set-brush (send brush get-color) 'solid) |
| 211 | + (send dc draw-polygon points dx dy) |
| 212 | + (send dc set-brush brush)) |
219 | 213 | triangle-width |
220 | 214 | triangle-height) |
221 | 215 | hierarchy-color))) |
222 | 216 |
|
223 | 217 | (define (center-x main pict) |
224 | | - (let-values ([(x y) (cc-find main pict)]) |
225 | | - x)) |
| 218 | + (define-values (x y) (cc-find main pict)) |
| 219 | + x) |
226 | 220 |
|
227 | 221 | (define (left-edge-x main pict) |
228 | | - (let-values ([(x y) (lc-find main pict)]) |
229 | | - x)) |
| 222 | + (define-values (x y) (lc-find main pict)) |
| 223 | + x) |
230 | 224 |
|
231 | 225 |
|
232 | 226 | (define (add-dot-right main class field) (add-dot-left-right/offset main class field 0 rc-find)) |
233 | | -(define add-dot-right/space |
234 | | - (λ (main class field [count 1]) |
235 | | - (add-dot-right/offset main class field (* count dot-edge-spacing)))) |
| 227 | +(define (add-dot-right/space main class field [count 1]) |
| 228 | + (add-dot-right/offset main class field (* count dot-edge-spacing))) |
236 | 229 | (define (add-dot-right/offset main class field offset) |
237 | 230 | (add-dot-left-right/offset main class field offset rc-find)) |
238 | 231 |
|
239 | 232 | (define (add-dot-left main class field) (add-dot-left-right/offset main class field 0 lc-find)) |
240 | | -(define add-dot-left/space |
241 | | - (λ (main class field [count 1]) |
242 | | - (add-dot-left/offset main class field (* count (- dot-edge-spacing))))) |
| 233 | +(define (add-dot-left/space main class field [count 1]) |
| 234 | + (add-dot-left/offset main class field (* count (- dot-edge-spacing)))) |
243 | 235 | (define (add-dot-left/offset main class field offset) |
244 | 236 | (add-dot-left-right/offset main class field offset lc-find)) |
245 | 237 |
|
246 | 238 | (define (add-dot-left-right/offset main class field offset finder) |
247 | | - (let-values ([(_1 y) (cc-find main field)] |
248 | | - [(x-edge _2) (finder main class)]) |
249 | | - (add-dot main (+ x-edge offset) y))) |
| 239 | + (define-values (_1 y) (cc-find main field)) |
| 240 | + (define-values (x-edge _2) (finder main class)) |
| 241 | + (add-dot main (+ x-edge offset) y)) |
250 | 242 |
|
251 | 243 | (define add-dot-junction |
252 | 244 | (case-lambda |
253 | 245 | [(main x-pict y-pict) (add-dot-junction main x-pict cc-find y-pict cc-find)] |
254 | 246 | [(main x-pict x-find y-pict y-find) |
255 | | - (let-values ([(x _1) (x-find main x-pict)] |
256 | | - [(_2 y) (y-find main y-pict)]) |
257 | | - (add-dot main x y))])) |
| 247 | + (define-values (x _1) (x-find main x-pict)) |
| 248 | + (define-values (_2 y) (y-find main y-pict)) |
| 249 | + (add-dot main x y)])) |
258 | 250 |
|
259 | 251 | (define (add-dot-offset pict dot dx dy) |
260 | | - (let-values ([(x y) (cc-find pict dot)]) |
261 | | - (add-dot pict (+ x dx) (+ y dy)))) |
| 252 | + (define-values (x y) (cc-find pict dot)) |
| 253 | + (add-dot pict (+ x dx) (+ y dy))) |
262 | 254 |
|
263 | 255 | (define dot-δx (make-parameter 0)) |
264 | 256 | (define dot-δy (make-parameter 0)) |
265 | 257 |
|
266 | 258 | (define (add-dot pict dx dy) |
267 | | - (let ([dot (blank)]) |
268 | | - (values (pin-over pict |
269 | | - (+ dx (dot-δx)) |
270 | | - (+ dy (dot-δy)) |
271 | | - dot) |
272 | | - dot))) |
| 259 | + (define dot (blank)) |
| 260 | + (values (pin-over pict (+ dx (dot-δx)) (+ dy (dot-δy)) dot) dot)) |
273 | 261 |
|
274 | 262 | (define (connect-dots show-arrowhead? main dot1 . dots) |
275 | 263 | (let loop ([prev-dot dot1] |
|
327 | 315 | [count 1] |
328 | 316 | #:connect-dots [connect-dots connect-dots] |
329 | 317 | #:dot-delta [dot-delta 0]) |
330 | | - (let ([going-down? (let-values ([(_1 start-y) (find-cc main0 start-field)] |
331 | | - [(_2 finish-y) (find-cc main0 finish-name)]) |
332 | | - (< start-y finish-y))]) |
333 | | - (define-values (main1 dot1) (add-dot-delta (λ () (add-dot-right main0 start-class start-field)) |
334 | | - 0 |
335 | | - (if going-down? |
336 | | - dot-delta |
337 | | - (- dot-delta)))) |
338 | | - (define-values (main2 dot2) (add-dot-delta (λ () (add-dot-right/space main1 start-class start-field count)) |
339 | | - dot-delta |
340 | | - (if going-down? |
341 | | - dot-delta |
342 | | - (- dot-delta)))) |
343 | | - (define-values (main3 dot3) (add-dot-delta (λ () (add-dot-right main2 finish-class finish-name)) |
344 | | - 0 |
345 | | - (if going-down? |
346 | | - (- dot-delta) |
347 | | - dot-delta))) |
348 | | - (define-values (main4 dot4) (add-dot-delta (λ () (add-dot-junction main3 dot2 dot3)) |
349 | | - 0 |
350 | | - 0)) |
351 | | - |
352 | | - ;; these last two dots are just there for the delta-less arrowhead |
353 | | - (define-values (main5 dot5) (add-dot-right main4 finish-class finish-name)) |
354 | | - (define-values (main6 dot6) (add-dot-delta (λ () (add-dot-right main5 finish-class finish-name)) |
355 | | - 1 ;; just enough to get the arrowhead going the right direction; not enough to see the line |
356 | | - 0)) |
357 | | - |
358 | | - (connect-dots |
359 | | - #t |
360 | | - (connect-dots #f main6 dot1 dot2 dot4 dot3) |
361 | | - dot6 |
362 | | - dot5))) |
| 318 | + (define going-down? |
| 319 | + (let-values ([(_1 start-y) (find-cc main0 start-field)] |
| 320 | + [(_2 finish-y) (find-cc main0 finish-name)]) |
| 321 | + (< start-y finish-y))) |
| 322 | + (define-values (main1 dot1) |
| 323 | + (add-dot-delta (λ () (add-dot-right main0 start-class start-field)) |
| 324 | + 0 |
| 325 | + (if going-down? |
| 326 | + dot-delta |
| 327 | + (- dot-delta)))) |
| 328 | + (define-values (main2 dot2) |
| 329 | + (add-dot-delta (λ () (add-dot-right/space main1 start-class start-field count)) |
| 330 | + dot-delta |
| 331 | + (if going-down? |
| 332 | + dot-delta |
| 333 | + (- dot-delta)))) |
| 334 | + (define-values (main3 dot3) |
| 335 | + (add-dot-delta (λ () (add-dot-right main2 finish-class finish-name)) |
| 336 | + 0 |
| 337 | + (if going-down? |
| 338 | + (- dot-delta) |
| 339 | + dot-delta))) |
| 340 | + (define-values (main4 dot4) (add-dot-delta (λ () (add-dot-junction main3 dot2 dot3)) 0 0)) |
| 341 | + |
| 342 | + ;; these last two dots are just there for the delta-less arrowhead |
| 343 | + (define-values (main5 dot5) (add-dot-right main4 finish-class finish-name)) |
| 344 | + (define-values (main6 dot6) |
| 345 | + (add-dot-delta |
| 346 | + (λ () (add-dot-right main5 finish-class finish-name)) |
| 347 | + 1 ;; just enough to get the arrowhead going the right direction; not enough to see the line |
| 348 | + 0)) |
| 349 | + |
| 350 | + (connect-dots #t (connect-dots #f main6 dot1 dot2 dot4 dot3) dot6 dot5)) |
363 | 351 |
|
364 | 352 | (define left-left-reference |
365 | 353 | (λ (main0 start-class start-field finish-class finish-name [count 1] |
|
0 commit comments