161 lines
5.2 KiB
Scheme
161 lines
5.2 KiB
Scheme
|
|
(module toolbar mzscheme
|
|
(require (prefix mred: mred)
|
|
mzlib/class
|
|
mzlib/file
|
|
mzlib/pretty
|
|
mzlib/etc
|
|
mzlib/list
|
|
"utils.ss")
|
|
|
|
;; These modules implement snips for the various
|
|
;; kinds of windows and controls.
|
|
(require "base.ss"
|
|
"panel.ss"
|
|
"simple-control.ss"
|
|
"text-field.ss"
|
|
"multiple-choice.ss"
|
|
"slider-guage.ss"
|
|
"canvas.ss")
|
|
|
|
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; Frame
|
|
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
(define-struct tool (icon callback active?))
|
|
|
|
(define lg-pen (send mred:the-pen-list find-or-create-pen
|
|
(make-object mred:color% 200 200 200) 0 'solid))
|
|
|
|
(define dg-pen (send mred:the-pen-list find-or-create-pen
|
|
(make-object mred:color% 140 140 140) 0 'solid))
|
|
|
|
(define icons (make-hash-table))
|
|
|
|
(define toolbar%
|
|
(class mred:canvas%
|
|
(inherit min-height stretchable-height get-dc)
|
|
(init [style '()])
|
|
(private-field
|
|
[margin 2]
|
|
[icon-size 16]
|
|
[tools null]
|
|
[active-tool #f])
|
|
(private*
|
|
[deactivate-tool
|
|
(lambda ()
|
|
(when active-tool
|
|
(set-tool-active?! active-tool #f)
|
|
(set! active-tool #f)
|
|
(on-paint)))]
|
|
[activate-tool
|
|
(lambda (mx my only)
|
|
(let ([y 0]
|
|
[h (+ icon-size (* 2 margin))]
|
|
[w (+ icon-size (* 2 margin))])
|
|
(let loop ([l tools][x 0])
|
|
(unless (null? l)
|
|
(if (and (<= x mx (+ x w)) (<= y my (+ y h))
|
|
(or (not only) (eq? (car l) only)))
|
|
(begin
|
|
(set! active-tool (car l))
|
|
(set-tool-active?! active-tool #t)
|
|
(on-paint))
|
|
(loop (cdr l) (+ x w)))))))])
|
|
(private-field
|
|
[can-drag #f])
|
|
(override*
|
|
[on-paint
|
|
(lambda ()
|
|
(let ([dc (get-dc)]
|
|
[y 0]
|
|
[h (+ icon-size (* 2 margin))]
|
|
[w (+ icon-size (* 2 margin))])
|
|
(let loop ([l tools][x 0])
|
|
(unless (null? l)
|
|
(let ([tool (car l)])
|
|
(let ([p (send dc get-pen)]
|
|
[on? (tool-active? tool)])
|
|
(send dc set-pen (if on? dg-pen lg-pen))
|
|
(send dc draw-line x y (+ x w -1) y)
|
|
(send dc draw-line x y x (+ y h -1))
|
|
(send dc draw-line x (add1 y) (+ x w -2) (add1 y))
|
|
(send dc draw-line (add1 x) y (add1 x) (+ y h -2))
|
|
(send dc set-pen (if on? lg-pen dg-pen))
|
|
(send dc draw-line (+ x 1) (+ y h -1) (+ x w -1) (+ y h -1))
|
|
(send dc draw-line (+ x w -1) (+ y 1) (+ x w -1) (+ y h -1))
|
|
(send dc draw-line (+ x 2) (+ y h -2) (+ x w -2) (+ y h -2))
|
|
(send dc draw-line (+ x w -2) (+ y 2) (+ x w -2) (+ y h -2))
|
|
(send dc set-pen p))
|
|
(if (tool-icon tool)
|
|
(send dc draw-bitmap (tool-icon tool) (+ x margin) margin)
|
|
(send dc draw-rectangle (+ x margin) margin icon-size icon-size)))
|
|
(loop (cdr l) (+ x w))))))]
|
|
[on-event
|
|
(lambda (e)
|
|
(cond
|
|
[(send e button-down?)
|
|
(deactivate-tool)
|
|
(activate-tool (send e get-x) (send e get-y) #f)
|
|
(set! can-drag active-tool)]
|
|
[(send e button-up?)
|
|
(set! can-drag #f)
|
|
(when active-tool
|
|
(let ([cb (tool-callback active-tool)])
|
|
(deactivate-tool)
|
|
(cb #f #f)))]
|
|
[(send e dragging?)
|
|
(when can-drag
|
|
(let ([old-active active-tool])
|
|
(set! active-tool #f)
|
|
(activate-tool (send e get-x) (send e get-y) can-drag)
|
|
(when (and (not active-tool) old-active)
|
|
(set-tool-active?! old-active #f)
|
|
(on-paint))))]
|
|
[else (set! can-drag #f)
|
|
(deactivate-tool)]))])
|
|
(public*
|
|
[append-tool
|
|
(lambda (icon-name cb)
|
|
(let* ([name (string->symbol icon-name)]
|
|
[icon
|
|
(hash-table-get
|
|
icons name
|
|
(lambda ()
|
|
(let* ([icon (make-object mred:bitmap%
|
|
(build-path (collection-path "guibuilder")
|
|
icon-name))])
|
|
(if (send icon ok?)
|
|
icon
|
|
#f))))])
|
|
(hash-table-put! icons name icon)
|
|
(set! tools (append tools (list (make-tool icon cb #f))))))])
|
|
(super-new [style (cons 'no-focus style)])
|
|
(min-height (+ icon-size (* margin 2)))
|
|
(stretchable-height #f)))
|
|
|
|
(define (add-tools toolbar emenu insert-element)
|
|
(let* ([append-element-type
|
|
(lambda (name icon c%)
|
|
(let ([maker (lambda (i e) (insert-element c%))])
|
|
(when toolbar
|
|
(send toolbar append-tool icon maker))
|
|
(when emenu
|
|
(make-object mred:menu-item% name emenu maker))))])
|
|
(append-element-type "New Vertical Panel" "vpanel.xpm" gb:vertical-panel-snip%)
|
|
(append-element-type "New Horizontal Panel" "hpanel.xpm" gb:horizontal-panel-snip%)
|
|
(append-element-type "New Message Label" "message.xpm" gb:message-snip%)
|
|
(append-element-type "New Button" "button.xpm" gb:button-snip%)
|
|
(append-element-type "New Checkbox" "checkbox.xpm" gb:check-box-snip%)
|
|
(append-element-type "New Text Field" "text.xpm" gb:text-snip%)
|
|
(append-element-type "New List" "list.xpm" gb:list-box-snip%)
|
|
(append-element-type "New Radiobox" "radiobox.xpm" gb:radio-box-snip%)
|
|
(append-element-type "New Choice" "choice.xpm" gb:choice-snip%)
|
|
(append-element-type "New Slider" "slider.xpm" gb:slider-snip%)
|
|
(append-element-type "New Gauge" "gauge.xpm" gb:gauge-snip%)
|
|
(append-element-type "New Canvas" "canvas.xpm" gb:canvas-snip%)
|
|
(append-element-type "New Editor Canvas" "mcanvas.xpm" gb:editor-canvas-snip%)))
|
|
|
|
(provide toolbar%
|
|
add-tools))
|