Thanks,<br><br>Thats exactly what I needed.<br><br>Stephen<br><br>PS Here is another version <br><br><span style="font-family:courier new,monospace">#lang racket/gui</span><br style="font-family:courier new,monospace"><br style="font-family:courier new,monospace">
<span style="font-family:courier new,monospace">;;;</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">;;; WORLD</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">;;;</span><br style="font-family:courier new,monospace">
<br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">(define-struct world (lines))</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">(define the-world </span><br style="font-family:courier new,monospace">
<span style="font-family:courier new,monospace"> (make-world '()))</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">; ((0 . 0) (0 . 300) (250 . 250)) ((150 . 176) (10 . 4) (280 . 10))</span><br style="font-family:courier new,monospace">
<span style="font-family:courier new,monospace">;;;</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">;;; USER LAND</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">;;;</span><br style="font-family:courier new,monospace">
<br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">(define (on-mouse-event world event)</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace"> (let ((x (send event get-x))</span><br style="font-family:courier new,monospace">
<span style="font-family:courier new,monospace"> (y (send event get-y)))</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace"> (cond</span><br style="font-family:courier new,monospace">
<span style="font-family:courier new,monospace"> [(and (send event get-left-down) (send event button-changed?)) </span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace"> (make-world (cons (cons (cons x y) '()) (world-lines world)))]</span><br style="font-family:courier new,monospace">
<span style="font-family:courier new,monospace"> [(and (send event get-left-down) (send event moving?) (not (send event button-changed?)))</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace"> (make-world (cons (cons (cons x y) (car (world-lines world))) (cdr (world-lines world))))]</span><br style="font-family:courier new,monospace">
<span style="font-family:courier new,monospace"> [else world])))</span><br style="font-family:courier new,monospace"><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">(define (on-paint world dc)</span><br style="font-family:courier new,monospace">
<span style="font-family:courier new,monospace"> (for-each (λ (lines) (send dc draw-lines lines))</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace"> (world-lines world)))</span><br style="font-family:courier new,monospace">
<br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">;;;</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">;;; SYSTEM</span><br style="font-family:courier new,monospace">
<span style="font-family:courier new,monospace">;;;</span><br style="font-family:courier new,monospace"><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">(define user:on-paint on-paint)</span><br style="font-family:courier new,monospace">
<br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">(define diagramframe (new frame% [label "paint"] </span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace"> [width 300] [height 300] </span><br style="font-family:courier new,monospace">
<span style="font-family:courier new,monospace"> [x 1000][y 300]))</span><br style="font-family:courier new,monospace"><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">(define paintcanvas%</span><br style="font-family:courier new,monospace">
<span style="font-family:courier new,monospace"> (class canvas%</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace"> (inherit get-dc refresh)</span><br style="font-family:courier new,monospace">
<span style="font-family:courier new,monospace"> (super-new)</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace"> (send (get-dc) set-pen "red" 10 'solid ) </span><br style="font-family:courier new,monospace">
<span style="font-family:courier new,monospace"> (define/override (on-paint)</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace"> (send (get-dc) suspend-flush)</span><br style="font-family:courier new,monospace">
<span style="font-family:courier new,monospace"> (user:on-paint the-world (get-dc))</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace"> (send (get-dc) resume-flush))</span><br style="font-family:courier new,monospace">
<span style="font-family:courier new,monospace"> </span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace"> (define/override (on-event mouse-event)</span><br style="font-family:courier new,monospace">
<span style="font-family:courier new,monospace"> (let* ([old-world the-world]</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace"> [new-world (on-mouse-event the-world mouse-event)])</span><br style="font-family:courier new,monospace">
<span style="font-family:courier new,monospace"> (if (eq? old-world new-world)</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace"> (super on-event mouse-event)</span><br style="font-family:courier new,monospace">
<span style="font-family:courier new,monospace"> (begin</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace"> (set! the-world new-world)</span><br style="font-family:courier new,monospace">
<span style="font-family:courier new,monospace"> (refresh)))))))</span><br style="font-family:courier new,monospace"><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">(define paintcanvas (new paintcanvas% [parent diagramframe]))</span><br style="font-family:courier new,monospace">
<span style="font-family:courier new,monospace">(send diagramframe show #t)</span><br><br style="font-family:courier new,monospace"><br><br><br><div class="gmail_quote">On Mon, Apr 9, 2012 at 12:12 PM, Jens Axel Søgaard <span dir="ltr"><<a href="mailto:jensaxel@soegaard.net">jensaxel@soegaard.net</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Stephen,<br>
<br>
Here is how I would do it.<br>
<br>
/Jens Axel<br>
<br>
#lang racket/gui<br>
<br>
;;;<br>
;;; WORLD<br>
;;;<br>
<br>
(define-struct world (lines))<br>
(define the-world (make-world '((0 . 0) (0 . 300) (250 . 250) (150 .<br>
176) (10 . 4) (280 . 10))))<br>
<br>
;;;<br>
;;; USER LAND<br>
;;;<br>
<br>
(define (on-mouse-event world event)<br>
(if (and (send event get-left-down)<br>
(send event moving?)<br>
#; (send event button-changed?))<br>
(let ((x (send event get-x))<br>
(y (send event get-y)))<br>
(make-world (cons (cons x y) (world-lines world))))<br>
world))<br>
<br>
(define (on-paint world dc)<br>
(send dc draw-lines<br>
(map pair->point (world-lines world))))<br>
<br>
(define (pair->point p)<br>
(make-object point% (car p) (cdr p)))<br>
<br>
<br>
;;;<br>
;;; SYSTEM<br>
;;;<br>
<br>
(define user:on-paint on-paint)<br>
<div class="im"><br>
(define diagramframe (new frame% [label "paint"] [width 300] [height<br>
300] [x 1000][y 300]))<br>
<br>
</div>(define paintcanvas%<br>
(class canvas%<br>
(inherit get-dc refresh)<br>
(super-new)<br>
<br>
(define/override (on-paint)<br>
(send (get-dc) suspend-flush)<br>
(user:on-paint the-world (get-dc))<br>
(send (get-dc) resume-flush))<br>
<br>
(define/override (on-event mouse-event)<br>
(let* ([old-world the-world]<br>
[new-world (on-mouse-event the-world mouse-event)])<br>
(if (eq? old-world new-world)<br>
(super on-event mouse-event)<br>
(begin<br>
(set! the-world new-world)<br>
(refresh)))))))<br>
<br>
(define paintcanvas (new paintcanvas% [parent diagramframe]))<br>
(send diagramframe show #t)<br>
<br>
<br>
<br>
2012/4/9 Stephen De Gabrielle <<a href="mailto:stephen.degabrielle@acm.org">stephen.degabrielle@acm.org</a>>:<br>
<div><div class="h5">> Hi,<br>
><br>
> I thought I'd try a simple GUI app using the world/universe mutation-free<br>
> approach, but trying to implement the 'world/universe' program design<br>
> myself.<br>
><br>
> I've got my little sketch below, but I quickly came to conclusion that while<br>
> I could use the teachpack, I don't know how to achieve the teachpack<br>
> functionality myself.<br>
><br>
> I'm guessing I should use continuations, but that doesn't seem to be the<br>
> approach in the universe.rkt source.<br>
><br>
> I could always just stuff the program into the canvas class, (as earlier<br>
> games like slidey and same seem to do), but I really want to get a handle<br>
> on how to implement the 'world/universe' style of program control.<br>
><br>
> Any suggestons would be appreciated.<br>
><br>
> Kind regards,<br>
><br>
> Stephen<br>
><br>
><br>
> ;;;;----<br>
> #lang racket/gui<br>
><br>
> ; simple drawing program<br>
> ; mousedown starts recording a list of points<br>
> ; mousechanged starts recording a new list<br>
> ; paint callback paints the list of lists as lines.<br>
><br>
> (define diagramframe (new frame% [label "paint"] [width 300] [height 300] [x<br>
> 1000][y 300]))<br>
><br>
> ;(define lines '(((0 . 0) (0 . 300) (250 . 250) (150 . 176))))<br>
> (define lines '(((0 . 0) (0 . 300) (250 . 250) (150 . 176))<br>
> ((10 . 4) (280 . 10))))<br>
><br>
> (define paintcanvas%<br>
> (class canvas%<br>
> (init-field mouse-event-callback)<br>
> (super-new)<br>
> (define dc (send this get-dc))<br>
> (define/override (on-event mouse-event)<br>
> (mouse-event-callback mouse-event))))<br>
><br>
> (define (paint-cb c dc)<br>
> (for-each (λ (line) (send dc draw-lines line)) lines))<br>
><br>
> (define (me-cb mouse-event)<br>
> (let ((x (send mouse-event get-x))<br>
> (y (send mouse-event get-y)))<br>
> (when (and (send mouse-event get-left-down)<br>
> (send mouse-event moving?))<br>
> (if (send mouse-event button-changed?)<br>
> ; if true append as new list<br>
> '()<br>
> ; if false append existing list<br>
> '())))<br>
> )<br>
><br>
> (define Paintcanvas (new paintcanvas%<br>
> [parent diagramframe]<br>
> [paint-callback paint-cb]<br>
> [mouse-event-callback me-cb]))<br>
><br>
> (define (main world)<br>
> (when world (main (??? world)))<br>
> (send diagramframe show #t))<br>
><br>
> (main lines)<br>
><br>
> (send diagramframe show #t)<br>
><br>
> ;;-----<br>
><br>
</div></div>> ____________________<br>
> Racket Users list:<br>
> <a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/users</a><br>
><br>
<br>
--<br>
Jens Axel Søgaard<br>
</blockquote></div><br><br clear="all"><br>-- <br><div> </div><div>--</div><div>Stephen De Gabrielle</div><div><a href="mailto:stephen.degabrielle@acm.org" target="_blank">stephen.degabrielle@acm.org</a></div><div>Telephone +44 (0)20 85670911</div>
<div>Mobile +44 (0)79 85189045</div><div><a href="http://www.degabrielle.name/stephen" target="_blank">http://www.degabrielle.name/stephen</a></div><div>----</div><div>Professor: Oh God! I clicked without reading! </div>
<div>Cubert: And I slightly modified something I own! </div><div>Professor: We're monsters!</div><br>