[plt-scheme] event binding help

From: briand at aracnet.com (briand at aracnet.com)
Date: Sun Feb 29 14:55:37 EST 2004

>>>>> "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))


Posted on the users mailing list.