;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;

;; DRAG GRAPHICS EXAMPLE

;;

;; Demonstrates direct manipulation of graphics.

;;

;; Drag two squares around a graphics window

;; using X and Y to control pitch and velocity.

;; Each square controls a different instrument.

;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; make sure that no audio units are already connected

(au:clear-graph)

;; Setup AudioGraph

; In this example two audio units are used. Their outputs

; are combined using an audio unit mixer, Apple's stereo mixer.

(define marimba (au:make-node "aumu" "dls " "appl"))

(define guitar (au:make-node "aumu" "dls " "appl"))

(define mixer (au:make-node "aumx" "smxr" "appl"))

(au:connect-node mixer 0 *au:output-node* 0)

(au:connect-node marimba 0 mixer 0)

(au:connect-node guitar 0 mixer 1)

(au:update-graph)

;; Set program changes

(au:midi-out (now) marimba *io:midi-pc* 0 12 0)

(au:midi-out (now) guitar *io:midi-pc* 0 25 0)

;; Set up graphics window and register

;; this process to receive mouse events

(define *canvas* (gfx:make-canvas))

(io:register-mouse-events *canvas*)

;; Setup Some Globals used to store the mouse position

(define *x* 0)

(define *y* 0)

; list containing (instrument path fill stroke)

; The "list" function constructs a list from the elements

; that follow it. In this case there are nested lists.

(define *marimba*

(list marimba (gfx:make-rectangle 300 200 50 100)

(list 1.0 0.0 0.0 1.0)

(list (random) (random) (random) 0.6)))

; list containing (instrument path fill stroke)

(define *guitar*

(list guitar (gfx:make-oval 100 100 50 100)

(list 1.0 0.0 0.0 1.0)

(list (random) (random) (random) 0.6)

(list 1.0 0.0 0.0 1.0)))

; Create a variable to hold the shape currently being dragged

(define *current* '())

;; Clear (fill) the screen, draw both squares

;; Set *current* to be the shape the

;; mouse is currently inside (or set to null)

(define (io:mouse-down x y)

(set! *x* x)

(set! *y* y)

(gfx:clear-canvas (now) *canvas* '(0.2 0.0 0.0 1.0))

(gfx:draw-path (now) *canvas*

1.0

*gfx:whole-path*)

(gfx:draw-path (now) *canvas*

1.0

*gfx:whole-path*)

(cond ((gfx:point-in-path? (cadr *marimba*) x y)

(set! *current* *marimba*))

(set! *current* *guitar*))

(else (set! *current* '()))))

;; set *current* to null when mouse button released

(define (io:mouse-up x y)

(set! *current* '()))

;; 1) play note on *current* instrument

;; 2) wipe old square (keeping the stroke)

;; 3) move square

;; 4) draw square

; The function cadr gets the second element of a list

; caddr gets the third element of a list

; cadddr gets the fourth element of a list, etc...

(define io:mouse-drag

(lambda (x y)

(if (not (null? *current*))

(begin (play-note (+ (now) 1)

(car *current*)

(+ 10 (/ y 4)) (+ 0 (/ x 4)) 5000)

(gfx:draw-path (+ (now) 2) *canvas*

'(0.2 0.0 0.0 1.0)

'(0.2 0.0 0.0 1.0))

(gfx:move-path (+ (now) 3) (cadr *current*) (- x *x*) (- y *y*))

(gfx:draw-path (+ (now) 4) *canvas*

(set! *x* x)

(set! *y* y)))))

;; Initialize

(define (start time)

(gfx:clear-canvas time

*canvas*

'(0.2 0.0 0.0 1.0))

(gfx:draw-path (+ time 1) *canvas*