;; Load the libraries in (load "gui-lib.scm") (load "fractaltree2.scm") ;; Define another function to compose tree fractal growing behavior ;; make-multiGrow: list-of-list-of-posn --> (Line --> Branch) ;; factory that takes in a list of growing functgions and returns a ;; growing function that will take a Line and return a Branch formed ;; by successively applying growing with all the growing functions. (define (make-multiGrow loGrowFn) (lambda (line) (foldr (lambda (growFn rr) (tfExecute rr growTF2 growFn)) line loGrowFn))) ;; define some prototype branches (define branchRefs1 (list (make-posn .3 .5) (make-posn -.3 .5) )) (define branchRefs2 (list (make-posn .5 .4) (make-posn -.2 .3) (make-posn -.4 -.2))) (define branchRefs3 (list (make-posn .2 .5) (make-posn -.4 .1) (make-posn -.3 -.5))) ;; ------ Abstract placeholders, initialized to some concrete value -------- (define growFn (make-nextBranch branchRefs1)) ;; The growing function to be used. (define growFns empty) ;; a sequence (list) of growing functions. (define fracTreeInitial (make-Line (make-posn 0 0) (make-posn 0 100))) ;; The initial value for the fractal (define fracTree fracTreeInitial) ;; the fractal that is being grown or drawn ;; ---- Utility functions --------------------------------- ;; setGrowFn: RadioEntry --> void ;; sets the growFn placeholder to be the data held in the supplied RadioEntry structure. (define (setGrowFn re) (set! growFn (RadioEntry-data re))) ;; setGrowFns: RadioEntry --> void ;; set the growFn placeholder to be the grow function returned by make-multiGrow using the growFns list of grow ;; functions as input. (define (setGrowFns re) (set! growFn (make-multiGrow growFns))) ;; ---------------- Radio button data --------------------------------------- ;; a vector of RadioEntries that determines the number of radio buttons, the radio button's caption, ;; the radio button's listener, and any data that might be needed (here, the growing function to be used). (define myREVec (vector (make-RadioEntry "Branching #1" setGrowFn (make-nextBranch branchRefs1)) (make-RadioEntry "Branching #2" setGrowFn (make-nextBranch branchRefs2)) (make-RadioEntry "Branching #3" setGrowFn (make-nextBranch branchRefs3)) (make-RadioEntry "Branching #1+#2+#3" setGrowFn (make-multiNextBranch (list branchRefs3 branchRefs2 branchRefs1))) (make-RadioEntry "Branching sequence" setGrowFns null) )) ;; ----------------- Create the GUI ------------------------------------------------------------- (define width 600) ;; the width (and height) of the frame (define frame1 (makeFrame "Tree Fractal Frame" width width)) ;; create a frame (define growRBox (addRadioBox "Growing Function Selection" ;; create a panel with all the frame1 ;; radio button information in myREVec)) ;; a supplied vector. (define growBtn (addButton "Grow tree" ;; A button to grow fracTree using the given growing function. frame1 (lambda () ;; The listener that causes the fractal to grow one step at a time. (begin (set! fracTree (tfExecute fracTree growTF2 growFn)) ;; reset the old tree with the new one (refresher))))) ;; Also sends a request to repaint the canvas. (define resetTreeBtn (addButton "Reset tree" ;; A button to reset the tree back to its initial state. frame1 (lambda () ;; The listener for the button (begin (set! fracTree fracTreeInitial) (refresher))))) ;; Also sends a request to repaint the canvas. (define addSeqBtn (addButton "Add to Sequence" ;; This button adds the current growing function to the list of growing functions frame1 (lambda () ;; The listener for the button (set! growFns (cons growFn growFns))))) (define resetSeqBtn (addButton "Reset Sequence" ;; This button resets the sequence. frame1 (lambda () (set! growFns empty)))) (define canvas1 (addCanvas frame1 ;; adds a canvas to supplied frame. (lambda (a-canvas a-dc) ;; the paint event listener (tfExecute fracTree drawTF 'blue) ;; redraw the fractal. ))) ;; ---- Utility GUI functions ------------------------------------------------------- (define draw-solidline (make-draw-solid-line canvas1)) ;; makes a draw method that will draw on the canvas only. (define refresher (makeRefresh canvas1)) ;; makes a refresher that will refresh the canvas only.