[plt-scheme] event binding help
>>>>> "Matthew" == Matthew Flatt <mflatt at cs.utah.edu> writes:
Matthew> If I understand the problem, then I agree that eventspaces
Matthew> don't help.
OK.
>> Unfortunately, after perusing the documentation, it's not obvious
>> to me how to do this without simply putting a brute force event
>> filter in on-subwindow-event and dispatching based on mode. And
>> that seems like a very kludgey way to do it.
Matthew> I don't quite understand this, though. How is that
Matthew> different from what Tk does (aside from the fact that Tk
Matthew> provides it built-in)? I'm also not sure why
Matthew> `on-subwindow-event' is the right place to put the filter,
Matthew> instead of `on-event', etc.
I use on-subwindow-event because I don't have a good grip on the mred
toolkit yet :-) on-event appears to be the right thing to use
(although I'm actually using an sgl canvas).
You're exactly right - in Tk the filtering is simply built-in. You're
code is very helpful and, with Matthias' suggestion, is basically very
close to what I want.
In fact, I noticed that in the (S)Tk program the bind method works
nicely except for one small problem. Let's say I've invoked the
line-proc and now the menu invokes a different tool. Well, the line
proc is the one which did the binding, so there is no way to undo the
bind's because nothing else knows what bind's took place. IOW, I
found a bug in my old program ! I also ended up passing state around
through globals.. Yuch. Note to self: don't do that.
Thank you to all for the help.
Brian
Matthew> More code below, but it's in the same spirit as Bruce's
Matthew> suggestion, so I'm not sure I'm on the right track.
Matthew> Matthew
Matthew> ----------------------------------------
Matthew> ;; Nicer event predicates for mouse/key mixtures
Matthew> (define (button-down? e)
Matthew> (and (e . is-a? . mouse-event%)
Matthew> (send e button-down?)))
Matthew> (define (button-up? e)
Matthew> (and (e . is-a? . mouse-event%)
Matthew> (send e button-up?)))
Matthew> (define (dragging? e)
Matthew> (and (e . is-a? . mouse-event%)
Matthew> (send e dragging?)))
Matthew> (define (key-press? e)
Matthew> (and (e . is-a? . key-event%)
Matthew> (not (eq? (send e get-key-code)
Matthew> 'release))))
Matthew> (define (key-release? e)
Matthew> (and (e . is-a? . key-event%)
Matthew> (eq? (send e get-key-code)
Matthew> 'release)))
Matthew> (define (event-mixin %)
Matthew> (class %
Matthew> (define/override (on-event e)
Matthew> (do-dispatch e))
Matthew> (define/override (on-char e)
Matthew> (do-dispatch e))
Matthew> (define current-target #f)
Matthew> (define/private (do-dispatch e)
Matthew> (if current-target
Matthew> (begin
Matthew> (current-target e)
Matthew> (when (or (button-up? e)
Matthew> (key-release? e))
Matthew> (set! current-target #f)))
Matthew> (begin
Matthew> (set! current-target (dispatch e))
Matthew> (when current-target
Matthew> (do-dispatch e)))))
Matthew> ;; dispatch : mouse-or-key-event -> #f or (mouse-or-key-event -> )
Matthew> ;; Selects an event handler based on an initial event.
Matthew> ;; This event handler keeps control until after a mouse up
Matthew> ;; or key up event
Matthew> (define/public (dispatch e)
Matthew> #f)
Matthew> (super-new)))
Matthew> ;; Example use
Matthew> (define f (make-object frame% "Hello"))
Matthew> (define c (make-object
Matthew> (class (event-mixin canvas%)
Matthew> (define/override (dispatch e)
Matthew> (cond
Matthew> [(button-down? e)
Matthew> ;; This handler gets everything from button down to button up
Matthew> (lambda (e)
Matthew> (printf "Button handler got ~e~n" e))]
Matthew> [(key-press? e)
Matthew> ;; This handler gets everything from key down to key up
Matthew> (lambda (e)
Matthew> (printf "Key handler got ~e~n" e))]
Matthew> [else #f]))
Matthew> (super-new))
Matthew> f))
Matthew> (send f show #t))