2012-04-09 3 views
3

Ich dachte, ich würde eine einfache GUI-App mit dem Ansatz "Welt/Universum ohne Mutation" versuchen, aber versuchen, das Programm "Welt/Universum" selbst zu implementieren.Über die Welt/das Universum hinausgehen

Ich habe meine kleine Skizze unten, aber ich kam schnell zu dem Schluss, dass, während ich das Teachpack verwenden konnte, ich nicht weiß, wie ich die Teachpack-Funktionalität selbst erreichen kann.

Ich vermute, ich sollte Fortsetzungen verwenden, aber das scheint nicht der Ansatz in der Quelle universum.rkt zu sein.

Ich könnte immer nur das Programm in die Canvas-Klasse stopfen, (wie früher Spiele wie Slidey und dergleichen scheinen), aber ich möchte wirklich einen Griff bekommen, wie man den 'Welt/Universum'-Stil des Programms implementiert Steuerung.

;;;;---- 
#lang racket/gui 

; simple drawing program 
; mousedown starts recording a list of points 
; mousechanged starts recording a new list 
; paint callback paints the list of lists as lines. 

(define diagramframe (new frame% [label "paint"] [width 300] 
           [height 300] [x 1000][y 300])) 

;(define lines '(((0 . 0) (0 . 300) (250 . 250) (150 . 176)))) 
(define lines '(((0 . 0) (0 . 300) (250 . 250) (150 . 176)) 
                ((10 . 4) (280 . 10)))) 

(define paintcanvas% 
  (class canvas% 
    (init-field mouse-event-callback) 
    (super-new) 
    (define dc (send this get-dc)) 
    (define/override (on-event mouse-event) 
      (mouse-event-callback mouse-event)))) 

(define (paint-cb c dc)  
  (for-each (λ (line) (send dc draw-lines line)) lines)) 

(define (me-cb mouse-event) 
    (let ((x (send mouse-event get-x)) 
        (y (send mouse-event get-y))) 
    (when (and (send mouse-event get-left-down) 
               (send mouse-event moving?)) 
      (if (send mouse-event button-changed?) 
          ; if true append as new list 
          '()  
          ; if false append existing list 
          '())))) 

(define Paintcanvas (new paintcanvas% 
                         [parent diagramframe] 
         [paint-callback paint-cb] 
         [mouse-event-callback me-cb])) 

(define (main world) 
 (when world (main (??? world))) 
  (send diagramframe show #t)) 
  
(main lines) 

(send diagramframe show #t) 

;;----- 

Antwort

5

Hier ist, wie ich es tun würde.

Beachten Sie, dass die GUI-Ereignisschleife das Programmhaupt fungiert. Verwenden Sie ein Timer-Ereignis, um ein Häkchen zu setzen.

#lang racket/gui 

;;; 
;;; WORLD 
;;; 

(define-struct world (lines)) 
(define the-world (make-world '((0 . 0) (0 . 300) (250 . 250) (150 . 176) (10 . 4) (280 . 10)))) 

;;; 
;;; USER LAND 
;;; 

(define (on-mouse-event world event) 
    (if (and (send event get-left-down) 
      (send event moving?) 
      #; (send event button-changed?)) 
     (let ((x (send event get-x)) 
      (y (send event get-y))) 
     (make-world (cons (cons x y) (world-lines world)))) 
     world)) 

(define (on-paint world dc) 
    (send dc draw-lines 
     (map pair->point (world-lines world)))) 

(define (pair->point p) 
    (make-object point% (car p) (cdr p))) 


;;; 
;;; SYSTEM 
;;; 

(define user:on-paint on-paint) 

(define diagramframe (new frame% [label "paint"] [width 300] [height 300] [x 1000][y 300])) 

(define paintcanvas% 
    (class canvas% 
    (inherit get-dc refresh) 
    (super-new) 

    (define/override (on-paint) 
     (send (get-dc) suspend-flush) 
     (user:on-paint the-world (get-dc)) 
     (send (get-dc) resume-flush)) 

    (define/override (on-event mouse-event) 
     (let* ([old-world the-world] 
      [new-world (on-mouse-event the-world mouse-event)]) 
     (if (eq? old-world new-world) 
      (super on-event mouse-event) 
      (begin 
       (set! the-world new-world) 
       (refresh))))))) 

(define paintcanvas (new paintcanvas% [parent diagramframe])) 
(send diagramframe show #t) 
+0

danke - große Antwort. – Stephen

Verwandte Themen