258 lines
11 KiB

;;;; STk adaptation of the Tk widget demo.
;;;; This demonstration script creates a canvas that displays the
;;;; canvas item types.
(define (demo-items)
;; Functions used by this demo
(let* ((w (make-demo-toplevel "items"
"Canvas Item Demonstration"
"This window contains a canvas widget with examples of the various kinds of items supported by canvases. The following operations are supported:\n Button-1 drag:\tmoves item under pointer.\n Button-2 drag:\trepositions view.\n Button-3 drag:\tstrokes out area.\n Ctrl+f:\t\tprints items under area."))
(c (make <Scroll-Canvas>
:parent w
:scroll-region (list 0 0 '30c '24c)
:width "15c"
:height "10c"
:relief "groove"
:border-width 3
:h-scroll-side "bottom"))
(font1 "-Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*")
(font2 "-Adobe-Helvetica-Bold-R-Normal--*-240-*-*-*-*-*-*")
(mono (= (winfo 'depth c) 1))
(blue (if mono "black" "DeepSkyBlue3"))
(red (if mono "black" "red"))
(bisque (if mono "black" "bisque3"))
(green (if mono "black" "SeaGreen3")))
(pack c :expand #t :fill "both")
;; Display a 3x3 rectangular grid.
(make <Rectangle> :parent c :coords '(0c 0c 30c 24c) :width 2)
(make <Line> :parent c :coords '(0c 8c 30c 8c) :width 2)
(make <Line> :parent c :coords '(0c 16c 30c 16c) :width 2)
(make <Line> :parent c :coords '(10c 0c 10c 24c) :width 2)
(make <Line> :parent c :coords '(20c 0c 20c 24c) :width 2)
;; Set up demos within each of the areas of the grid.
;; Lines
(make <Text-item> :parent c :coords '(5c .2c) :text "Lines" :anchor "n")
(make <Line> :parent c :coords '(1c 1c 3c 1c 1c 4c 3c 4c) :width "2m"
:fill blue :cap "butt" :join "miter" :tags "item")
(make <Line> :parent c :coords '(4.67c 1c 4.67c 4c) :arrow "last"
:tags "item")
(make <Line> :parent c :coords '(6.33c 1c 6.33c 4c) :arrow "both"
:tags "item")
(make <Line> :parent c
:coords '(5c 6c 9c 6c 9c 1c 8c 1c 8c 4.8c 8.8c 4.8c 8.8c 1.2c 8.2c 1.2c 8.2c 4.6c 8.6c 4.6c 8.6c 1.4c 8.4c 1.4c 8.4c 4.4c)
:width 3 :fill red :tags "item")
(make <Line> :parent c :coords '(1c 5c 7c 5c 7c 7c 9c 7c) :width '.5c
:stipple (string-append "@" *STk-images* "grey.25")
:arrow "both" :arrow-shape (list 15 15 7) :tags "item")
(make <Line> :parent c
:coords '(1c 7c 1.75c 5.8c 2.5c 7c 3.25c 5.8c 4c 7c) :width '.5c
:cap-style "round" :join-style "round" :tags "item")
;; Smoothed lines
(make <Text-item> :parent c :coords '(15c .2c)
:text "Curves (smoothed lines)" :anchor "n")
(make <Line> :parent c :coords '(11c 4c 11.5c 1c 13.5c 1c 14c 4c)
:smooth #t :fill blue :tags "item")
(make <Line> :parent c :coords '(15.5c 1c 19.5c 1.5c 15.5c 4.5c 19.5c 4c)
:smooth #t :arrow "both" :width 3 :tags "item")
(make <Line> :parent c
:coords '(12c 6c 13.5c 4.5c 16.5c 7.5c 18c 6c 16.5c 4.5c 13.5c 7.5c 12c 6c)
:smooth #t :width '3m :cap-style "round"
:stipple (string-append "@" *STk-images* "grey.25")
:fill red :tags "item")
;; Polygons
(make <Text-item> :parent c :coords '(25c .2c) :text "Polygons"
:anchor "n")
(make <Polygon> :parent c
:coords '(21c 1.0c 22.5c 1.75c 24c 1.0c 23.25c 2.5c 24c 4.0c 22.5c 3.25c 21c 4.0c 21.75c 2.5c)
:fill green :outline "black" :width 4 :tags "item")
(make <Polygon> :parent c
:coords '(25c 4c 25c 4c 25c 1c 26c 1c 27c 4c 28c 1c 29c 1c 29c 4c 29c 4c)
:fill red :smooth #t :tags "item")
(make <Polygon> :parent c
:coords '(22c 4.5c 25c 4.5c 25c 6.75c 28c 6.75c 28c 5.25c 24c 5.25c 24c 6.0c 26c 6c 26c 7.5c 22c 7.5c)
:stipple (string-append "@" *STk-images* "grey.25")
:outline "black" :tags "item")
;; Rectangles
(make <Text-item> :parent c :coords '(5c 8.2c) :text "Rectangles"
:anchor "n")
(make <Rectangle> :parent c :coords '(1c 9.5c 4c 12.5c)
:outline red :width '3m :tags "item")
(make <Rectangle> :parent c :coords '(0.5c 13.5c 4.5c 15.5c)
:fill green :tags "item")
(make <Rectangle> :parent c :coords '(6c 10c 9c 15c)
:stipple (string-append "@" *STk-images* "grey.25")
:outline "" :fill blue :tags "item")
;; Ovals
(make <Text-item> :parent c :coords '(15c 8.2c) :text "Ovals" :anchor "n")
(make <Oval> :parent c :coords '(11c 9.5c 14c 12.5c)
:outline red :width '3m :tags "item")
(make <Oval> :parent c :coords '(10.5c 13.5c 14.5c 15.5c)
:fill green :tags "item")
(make <Oval> :parent c :coords '(16c 10c 19c 15c)
:stipple (string-append "@" *STk-images* "grey.25")
:outline "" :fill blue :tags "item")
;; Texts
(make <Text-item> :parent c :coords '(25c 8.2c) :text "Text" :anchor "n")
(make <Rectangle> :parent c :coords '(22.4c 8.9c 22.6c 9.1c))
(make <Text-item> :parent c :coords '(22.5c 9c) :anchor "n"
:font font1 :width '4c
:text "A short string of text, word-wrapped, justified left, and anchored north (at the top). The rectangles show the anchor points for each piece of text."
:tags "item")
(make <Rectangle> :parent c :coords '(25.4c 10.9c 25.6c 11.1c))
(make <Text-item> :parent c :coords '(25.5c 11c) :anchor "w"
:font font1 :fill blue
:text "Several lines,\n each centered\nindividually,\nand all anchored\nat the left edge."
:justify "center" :tags "item")
(make <Rectangle> :parent c :coords '(24.9c 13.9c 25.1c 14.1c))
(make <Text-item> :parent c :coords '(25c 14c)
:font font2 :anchor "c" :fill red
:stipple (string-append "@" *STk-images* "grey.5")
:text "Stippled characters" :tags "item")
;; Arcs
(make <Text-item> :parent c :coords '(5c 16.2c) :text "Arcs" :anchor "n")
(make <Arc> :parent c :coords '(0.5c 17c 7c 20c) :fill green
:outline "black" :start 45 :extent 270 :style "pieslice" :tags "item")
(make <Arc> :parent c :coords '(6.5c 17c 9.5c 20c) :width '4m :style "arc"
:outline blue :start -135 :extent 270
:outline-stipple (string-append "@" *STk-images* "grey.25")
:tags "item")
(make <Arc> :parent c :coords '(0.5c 20c 9.5c 24c) :width '4m
:style "pieslice" :fill "" :outline red :start 225 :extent -90
:tags "item")
(make <Arc> :parent c :coords '(5.5c 20.5c 9.5c 23.5c) :width '4m
:style "chord" :fill blue :outline "" :start 45 :extent 270
:tags "item")
;; Bitmaps
(make <Text-item> :parent c :coords '(15c 16.2c) :text "Bitmaps" :anchor "n")
(make <Bitmap-item> :parent c :coords '(13c 20c)
:bitmap-name (string-append "@" *STk-images* "face")
:tags "item")
(make <Bitmap-item> :parent c :coords '(17c 18.5c)
:bitmap-name (string-append "@" *STk-images* "noletters")
:tags "item")
(make <Bitmap-item> :parent c :coords '(17c 21.5c)
:bitmap-name (string-append "@" *STk-images* "letters")
:tags "item")
;; Windows
(make <Text-item> :parent c :coords '(25c 16.2c) :text "Windows" :anchor "n")
(make <Canvas-window> :parent c :coords '(21c 18c) :anchor "nw"
:window (make <Button> :text "Press Me" :parent c
:command (lambda ()
(let ((i (make <Text-item> :parent c
:coords '(25c 18.1c)
:anchor "n"
:text "Ouch!!"
:fill "Red")))
(after 500 (lambda ()
(destroy i))))))
:tags "item")
(make <Canvas-window> :parent c :coords '(21c 21c) :anchor "nw"
:window (make <Entry> :parent c :width 20 :relief "sunken"
:value "Edit thid text")
:tags "item")
(make <Canvas-window> :parent c :coords '(28.5c 17.5c) :anchor "n"
:window (make <Scale> :parent c :from 0 :to 100 :length '6c
:slider-length '.4c :width '.5c :tick-interval 0)
:tags "item")
(make <Text-item> :parent c :coords '(21c 17.9c) :text "Button" :anchor "sw")
(make <Text-item> :parent c :coords '(21c 20.9c) :text "Entry" :anchor "sw")
(make <Text-item> :parent c :coords '(28.5c 17.4c) :text "Scale" :anchor "s")
;; Set up event bindings for canvas:
(let ((action #f)
(x0 0) (y0 0)
(x1 0) (y1 0)
(x2 0) (y2 0))
(define (item-enter c)
(let ((item (car (find-items c 'with "current"))))
((= (winfo 'depth c) 1)
(set! action #f))
((is-a? item <Canvas-window>)
(set! action #f))
((is-a? item <Bitmap-item>)
(let ((bg (slot-ref item 'background)))
(set! action `(slot-set! ,item 'background ,bg))
(slot-set! item 'background "SteelBlue2")))
((and (or (is-a? item <Rectangle>)
(is-a? item <Oval>)
(is-a? item <Arc>))
(equal? (slot-ref item 'fill) ""))
(let ((outline (slot-ref item 'outline)))
(set! action `(slot-set! ,item 'outline ,outline))
(slot-set! item 'outline "SteelBlue2")))
(ELSE (let ((fill (slot-ref item 'fill)))
(set! action `(slot-set! ,item 'fill ,fill))
(slot-set! item 'fill "SteelBlue2"))))))
;; Utility procedures for stroking out a rectangle and printing what's
;; underneath the rectangle's area.
(define (item-mark c x y)
(set! x1 (canvas-x c x))
(set! y1 (canvas-y c y))
(canvas-delete c "area"))
(define (item-stroke c x y)
(let ((x (canvas-x c x))
(y (canvas-y c y)))
(unless (and (= x x1) (= y y1))
(canvas-delete c "area")
(make <Rectangle> :parent c :coords (list x1 y1 x y) :tags "area")
(set! x2 x)
(set! y2 y))))
(define (items-under-area c)
(format #t "Items enclosed by area: ~S\n"
(find-items c 'enclosed x1 y1 x2 y2))
(format #t "Items overlapping area: ~S\n"
(cdr (reverse (find-items c 'overlapping x1 y1 x2 y2)))))
;; Utility procedures to support dragging of items.
(define (item-start-drag c x y)
(set! x0 (canvas-x c x))
(set! y0 (canvas-x c y)))
(define (item-drag c x y)
(let ((x (canvas-x c x))
(y (canvas-x c y)))
(move c "current" (- x x0) (- y y0))
(set! x0 x)
(set! y0 y)))
(bind c "item" "<Any-Enter>" (lambda () (item-enter c)))
(bind c "item" "<Any-Leave>" (lambda () (eval action)))
(bind c "<1>" (lambda (x y) (item-start-drag c x y)))
(bind c "<B1-Motion>" (lambda (x y) (item-drag c x y)))
(bind c "<2>" (lambda (x y) (scan c 'mark x y)))
(bind c "<B2-Motion>" (lambda (x y) (scan c 'dragto x y)))
(bind c "<3>" (lambda (x y) (item-mark c x y)))
(bind c "<B3-Motion>" (lambda (x y) (item-stroke c x y)))
(bind c "<Control-f>" (lambda () (items-under-area c))))
(focus c)