forked from LuKuangChen/stacker-on-racket
-
Notifications
You must be signed in to change notification settings - Fork 0
/
pict-loop.rkt
93 lines (89 loc) · 2.8 KB
/
pict-loop.rkt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#lang racket
(provide pict-loop)
(require pict)
(require racket/gui)
(define-values (forward!
backward!
what-is-now
add-future
has-past?
has-future?)
(let ([past '()]
[future '()]
[now #f])
(values
(lambda ()
(if (and now (pair? future))
(begin
(set! past (cons now past))
(set! now (car future))
(set! future (cdr future)))
(error 'forward-into-nowhere)))
(lambda ()
(if (and now (pair? past))
(begin
(set! future (cons now future))
(set! now (car past))
(set! past (cdr past)))
(error 'backward-into-nowhere)))
(lambda () now)
(lambda (item)
(cond
[(not now)
(set! now item)
now]
[(empty? future)
(set! future (cons item future))
(forward!)]
[else
(error 'pict-manager)]))
(lambda ()
(pair? past))
(lambda ()
(pair? future)))))
(define (pict-loop state terminate? forward pict-of-state)
(define the-frame (new frame% [label "Stacker"]))
(send the-frame create-status-line)
(define button-panel
(new horizontal-panel%
[parent the-frame]
[stretchable-height #f]))
(define the-canvas
(new canvas%
[parent the-frame]
[paint-callback
(lambda (canvas dc)
(let ([current-pict (what-is-now)])
(when current-pict
(send dc clear)
(send canvas min-width (add1 (inexact->exact (ceiling (pict-width current-pict)))))
(send canvas min-height (add1 (inexact->exact (ceiling (pict-height current-pict)))))
(send the-prev-button enable (has-past?))
(send the-next-button enable (or (has-future?) (not (terminate? state))))
(send the-frame set-status-text (if (terminate? state) "terminated" "still running"))
;;; (send the-frame resize 10 10)
(draw-pict current-pict dc 1 1))))]))
(define the-prev-button
(new button%
[label "Previous"]
[parent button-panel]
[callback
(lambda (_button _event)
(let ([item (backward!)])
(send the-frame refresh)))]))
(define the-next-button
(new button%
[label "Next"]
[parent button-panel]
[callback
(lambda (_button _event)
(if (has-future?)
(forward!)
(unless (terminate? state)
(step!)))
(send the-frame refresh))]))
(define (step!)
(set! state (forward state))
(add-future (pict-of-state state)))
(add-future (pict-of-state state))
(send the-frame show #t))