- added "switch" feature to button

- added possibility to change state and caption
This commit is contained in:
frese 2005-01-16 17:14:31 +00:00
parent 03c223193b
commit 0f7e0eb189
1 changed files with 83 additions and 26 deletions

View File

@ -4,14 +4,17 @@
(down-colors colors '("gray" "black" "white" "black"))
(font font "-*-helvetica-medium-r-normal-*-12-*-*-*-*-*-*-*")
(content sexp 'none) ;; string | 'kill | 'iconify | 'maximize
(type sexp 'standard) ;; 'standard | 'switch (remains pressed)
(initial-state sexp 'up) ;; 'up | 'down
)
(define-record-type button :button
(make-button dpy window options)
(make-button dpy window options in-channel)
button?
(dpy button:dpy)
(window button:window)
(options button:options))
(options button:options)
(in-channel button:in-channel))
(define-record-discloser :button
(lambda (b)
@ -20,44 +23,84 @@
(define (create-button dpy parent colormap rect out-channel message options)
(let* ((options (create-options dpy colormap button-options-spec
options))
(bgcolor (first (get-option-value options 'up-colors)))
(window (create-simple-window dpy parent
(rectangle:x rect)
(rectangle:y rect)
(rectangle:width rect)
(rectangle:height rect)
0 (black-pixel dpy)
(white-pixel dpy))) ;; from options
bgcolor))
(gc (create-gc dpy window '()))
(button (make-button dpy window options)))
(in-channel (make-channel))
(abutton (make-button dpy window options in-channel))
(type (get-option-value options 'type)))
(spawn*
(list 'button button)
(list 'button abutton)
(lambda (release)
(call-with-event-channel
dpy window (event-mask exposure structure-notify
button-press button-release)
(lambda (event-channel)
(release)
(let loop ((state 'up))
(let ((e (receive event-channel)))
(cond
((and (expose-event? e) (window-exists? dpy window))
(draw-button button gc state)
(loop state))
((destroy-window-event? e) 'destroyed)
((and (button-event? e) (window-exists? dpy window))
(if (eq? (event-type button-press)
(button-event-type e))
(begin
(draw-button button gc 'down)
(loop 'down))
(begin
(draw-button button gc 'up)
(send out-channel (list message (button-event-time e)))
(loop 'up))))
(else (loop state)))))
(call-with-current-continuation
(lambda (exit)
(let ((state (get-option-value options 'initial-state))
(content (get-option-value options 'content)))
(let loop ()
(select*
(wrap (receive-rv in-channel)
(lambda (msg)
(case (car msg)
((get-state)
(placeholder-set! (second msg) state))
((set-state!)
(let ((s (second msg)))
(if (not (eq? s state))
(draw-button abutton gc s content))
(set! state s)))
((set-content!)
(let ((c (second msg)))
(if (not (equal? c content))
(draw-button abutton gc state c))
(set! content c))))))
(wrap (receive-rv event-channel)
(lambda (e)
(cond
((and (expose-event? e) (window-exists? dpy window))
(draw-button abutton gc state content))
((destroy-window-event? e) (exit 'destroyed))
((and (button-event? e) (window-exists? dpy window)
(eq? (button-event-button e)
(button button1)))
(let ((new-state
(if (eq? (event-type button-press)
(button-event-type e))
(if (eq? type 'standard)
'down
(if (eq? state 'up)
'down
'up))
(if (eq? type 'standard)
'up
#f))))
(if new-state
(begin
(draw-button abutton gc new-state content)
(set! state new-state)))
(if (and (eq? type 'standard)
(eq? new-state 'up))
(send out-channel
(list message (button-event-time e)
'click)))
(if (and (eq? type 'switch) new-state)
(send out-channel
(list message (button-event-time e)
new-state)))))))))
(loop)))))
(free-gc dpy gc)
(free-options options #t)))))
button))
abutton))
(define (destroy-button button)
(destroy-window (button:dpy button) (button:window button)))
@ -71,7 +114,22 @@
(define (move-resize-button button r)
(move-resize-window* (button:dpy button) (button:window button) r))
(define (draw-button button gc state)
(define (button-get-state button)
(let ((ph (make-placeholder)))
(send (button:in-channel button)
(list 'get-state ph))
(placeholder-value ph)))
(define (button-set-state! button state)
(send (button:in-channel button)
(list 'set-state! state)))
(define (button-set-content! button content)
(send (button:in-channel button)
(list 'set-content! content)))
(define (draw-button button gc state content)
(let ((dpy (button:dpy button))
(window (button:window button))
(options (button:options button)))
@ -79,7 +137,6 @@
(if (eq? state 'up)
'up-colors
'down-colors)))
(content (get-option-value options 'content))
(font (get-option-value options 'font))
(r (clip-rectangle dpy window)))
(set-gc-foreground! dpy gc (first colors))