home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Garbo
/
Garbo.cdr
/
mac
/
science
/
xlspstr1.sit
/
Examples
/
plotcontrols.lsp
< prev
next >
Wrap
Text File
|
1989-12-02
|
11KB
|
294 lines
(defmeth graph-proto :add-control (c) (send self :add-overlay c))
(defmeth graph-proto :delete-control (c) (send self :delete-overlay c))
(defproto graph-control-proto
'(action location title) nil graph-overlay-proto)
(defmeth graph-control-proto :location (&optional (new nil set))
(when set
(send self :erase)
(setf (slot-value 'location) new)
(send self :redraw))
(slot-value 'location))
(defmeth graph-control-proto :title (&optional (new nil set))
(when set
(send self :erase)
(setf (slot-value 'title) new)
(send self :redraw))
(slot-value 'title))
(defmeth graph-control-proto :erase ()
(let ((graph (send self :graph))
(loc (send self :location))
(sz (send self :size)))
(if graph (apply #'send graph :erase-rect (append loc sz)))))
(defmeth graph-control-proto :size ()
(let ((graph (send self :graph))
(title (send self :title)))
(if graph
(list (+ 10 5 (send graph :text-width title)) 20)
(list 10 10))))
(defmeth graph-control-proto :redraw ()
(let* ((graph (send self :graph))
(loc (send self :location))
(loc-x (first loc))
(loc-y (second loc))
(title (send self :title)))
(send self :erase)
(send graph :frame-rect loc-x (+ 5 loc-y) 10 10)
(send graph :draw-text title (+ 15 loc-x) (+ 15 loc-y) 0 0)))
(defmeth graph-control-proto :do-click (x y a b)
(let* ((graph (send self :graph))
(loc (send self :location))
(loc-x (first loc))
(loc-y (+ 5 (second loc))))
(when (and (< loc-x x (+ loc-x 10)) (< loc-y y (+ loc-y 10)))
(send graph :paint-rect (+ 1 loc-x) (+ 1 loc-y) 8 8)
(send self :do-action (list a b))
(send graph :while-button-down
#'(lambda (x y) (send self :do-action nil)) nil)
(send graph :erase-rect (+ 1 loc-x) (+ 1 loc-y) 8 8)
t)))
(defmeth graph-control-proto :do-action (x) (sysbeep))
;;; Rockers
(defproto rocker-control-proto () () graph-control-proto)
(defmeth rocker-control-proto :size ()
(let ((graph (send self :graph))
(title (send self :title)))
(if graph
(list (+ 10 5 10 5 (send graph :text-width title)) 20)
(list 10 10))))
(defmeth rocker-control-proto :redraw ()
(let* ((graph (send self :graph))
(loc (send self :location))
(loc-x (first loc))
(loc-y (second loc))
(title (send self :title)))
(send self :erase)
(send graph :frame-rect loc-x (+ 5 loc-y) 10 10)
(send graph :frame-rect (+ 15 loc-x) (+ 5 loc-y) 10 10)
(send graph :draw-text title (+ 30 loc-x) (+ 15 loc-y) 0 0)))
(defmeth rocker-control-proto :do-click (x y a b)
(let* ((graph (send self :graph))
(loc (send self :location))
(loc-x1 (first loc))
(loc-x2 (+ 15 loc-x1))
(loc-y (+ 5 (second loc))))
(if (< loc-y y (+ loc-y 10))
(let* ((arg (cond
((< loc-x1 x (+ loc-x1 10)) '-)
((< loc-x2 x (+ loc-x2 10)) '+)))
(loc-x (case arg (- loc-x1) (+ loc-x2))))
(when arg
(send graph :paint-rect (+ 1 loc-x) (+ 1 loc-y) 8 8)
(send self :do-action (list a b) arg)
(send graph :while-button-down
#'(lambda (x y) (send self :do-action nil arg)) nil)
(send graph :erase-rect (+ 1 loc-x) (+ 1 loc-y) 8 8)
t)))))
(defmeth rocker-control-proto :do-action (x arg) (sysbeep))
;;; Slider
(defproto slider-control-proto
'(index sequence display) () graph-control-proto)
(defmeth slider-control-proto :isnew (sequence &key
(title "Value")
(display sequence)
(location '(10 20))
(index 0)
graph)
(call-next-method :title title :location location)
(send self :sequence sequence :display display)
(send self :index index)
(if graph (send graph :add-control self)))
(defmeth slider-control-proto :size ()
(let ((graph (send self :graph))
(title (send self :title)))
(list 100 30)))
(defmeth slider-control-proto :redraw ()
(let* ((graph (send self :graph))
(loc (send self :location))
(loc-x (first loc))
(loc-y (second loc))
(w (first (send self :size))))
(when graph
(send graph :draw-text (send self :title) loc-x (+ loc-y 15) 0 0)
(send graph :frame-rect loc-x (+ loc-y 20) w 10)
(send self :draw-indicator))))
(defmeth slider-control-proto :draw-indicator (&optional index)
(let* ((graph (send self :graph))
(loc (send self :location))
(loc-x (first loc))
(loc-y (second loc))
(w (first (send self :size)))
(min (send self :min))
(max (send self :max))
(index (if index index (send self :index)))
(val (floor (* (- w 7) (/ (- index min) (- max min))))))
(when graph
(let ((tw (send graph :text-width (send self :title))))
(send graph :start-buffering)
(send graph :erase-rect (+ 1 tw loc-x) loc-y (- w tw) 20)
(send graph :draw-text
(format nil "~a" (elt (send self :display) index))
(+ loc-x w) (+ loc-y 15) 2 0)
(send graph :buffer-to-screen (+ 1 tw loc-x) loc-y (- w tw) 20))
(send graph :erase-rect (+ 1 loc-x) (+ 21 loc-y) (- w 2) 8)
(send graph :paint-rect (+ 1 loc-x val) (+ 21 loc-y) 5 8))))
(defmeth slider-control-proto :min () 0)
(defmeth slider-control-proto :max () (- (length (slot-value 'sequence)) 1))
(defmeth slider-control-proto :sequence (&optional (seq nil set) &key
(display seq))
(when set
(setf (slot-value 'sequence) (coerce seq 'vector))
(setf (slot-value 'display) (coerce display 'vector)))
(slot-value 'sequence))
(defmeth slider-control-proto :display () (slot-value 'display))
(defmeth slider-control-proto :index (&optional (new nil set))
(if set
(let* ((new (max (send self :min) (min new (send self :max)))))
(setf (slot-value 'index) new)
(send self :draw-indicator)
(send self :do-action (elt (send self :sequence) new))))
(slot-value 'index))
(defmeth slider-control-proto :do-click (x y a b)
(let* ((graph (send self :graph))
(loc (send self :location))
(loc-x (nth 0 loc))
(loc-y (nth 1 loc))
(w (first (send self :size))))
(when (and (< loc-x x (+ loc-x w)) (< (+ loc-y 20) y (+ loc-y 30)))
(let ((pos (+ (floor (* (- w 7) (/ (send self :index)
(send self :max))))
loc-x)))
(cond
((<= pos x (+ pos 5))
(let ((off (- x pos)))
(send graph :while-button-down
#'(lambda (x y)
(let ((val (max (+ loc-x 1)
(min (- x off)
(+ loc-x (- w 6))))))
(setf pos val)
(send self :draw-indicator
(floor (* (send self :max)
(/ (- pos loc-x) (- w 7)))))))))
(send self :index
(floor (* (send self :max)
(/ (- pos loc-x) (- w 7))))))
((< loc-x x pos)
(send graph :while-button-down
#'(lambda (x y)
(let ((pos (+ (floor (* w (/ (send self :index)
(send self :max))))
loc-x)))
(if (< x pos)
(send self :index (- (send self :index) 1)))))
nil))
((< pos x (+ loc-x w))
(send graph :while-button-down
#'(lambda (x y)
(let ((pos (+ (floor (* w (/ (send self :index)
(send self :max))))
loc-x)))
(if (> x pos)
(send self :index (+ (send self :index) 1)))))
nil))))
t)))
;;;;
;;;; Rotation example
;;;;
;;; Rotation around axes
(defproto spin-rotate-control-proto '(v) () rocker-control-proto)
(defmeth spin-rotate-control-proto :isnew (v)
(call-next-method :v v :location (list 10 (case v (0 10) (1 30) (2 50)))))
(defmeth spin-rotate-control-proto :title ()
(send (send self :graph) :variable-label (slot-value 'v)))
(defmeth spin-rotate-control-proto :do-action (first sign)
(let ((graph (send self :graph)))
(if first
(let* ((v (slot-value 'v))
(v1 (if (= v 0) 1 0))
(v2 (if (= v 2) 1 2))
(trans (send graph :transformation))
(cols (column-list
(if trans
trans
(identity-matrix (send graph :num-variables)))))
(angle (send graph :angle)))
(send graph :idle-on (car first))
(send graph :slot-value 'rotation-type
(make-rotation (nth v1 cols) (nth v2 cols)
(case sign (+ angle) (- (- angle)))))))
(send graph :rotate)))
;;; Plot Rocking Control
(defproto spin-rock-control-proto '(v) () graph-control-proto)
(defmeth spin-rock-control-proto :isnew ()
(call-next-method :location '(10 70) :title "Rock Plot"))
(defmeth spin-rock-control-proto :do-action (first)
(send (send self :graph) :rock-plot))
(defmeth spin-proto :rock-plot (&optional (k 2))
(let ((angle (send self :angle)))
(dotimes (i k) (send self :rotate-2 0 2 angle))
(dotimes (i (* 2 k)) (send self :rotate-2 0 2 (- angle)))
(dotimes (i k) (send self :rotate-2 0 2 angle))))
;;;; Speed Control
(defproto spin-speed-control-proto () () slider-control-proto)
(defmeth spin-speed-control-proto :isnew (&optional (points 21))
(call-next-method (rseq 0 .2 points) :location '(10 90) :title "Speed"))
(defmeth spin-speed-control-proto :do-action (v)
(let ((graph (send self :graph)))
(if graph (send graph :angle v))))
;;;; Installation method
(defmeth spin-proto :add-spin-controls ()
(send self :margin 110 0 0 20)
(apply #'send self :size (+ (send self :size) '(100 0)))
(send self :resize)
(send self :add-control (send spin-rotate-control-proto :new 0))
(send self :add-control (send spin-rotate-control-proto :new 1))
(send self :add-control (send spin-rotate-control-proto :new 2))
(send self :add-control (send spin-rock-control-proto :new))
(send self :add-control (send spin-speed-control-proto :new)))