gui/gui-lib/mrlib/click-forwarding-editor.rkt
2014-12-02 02:33:07 -05:00

58 lines
2.1 KiB
Racket

(module click-forwarding-editor mzscheme
(require
mzlib/class
mzlib/contract
mzlib/etc
mred)
(provide/contract
(click-forwarding-editor-mixin mixin-contract))
;; mixin to forward clicks to children snips within the editor
(define (click-forwarding-editor-mixin super%)
(class super%
(inherit get-snip-location global-to-local local-to-global
find-snip get-dc set-caret-owner)
;; on-event ((is-a?/c mouse-event%) . -> . void?)
;; overridden to give focus to child snips when clicked
(define/override (on-event event)
(if (memq (send event get-event-type)
'(left-down left-up middle-down middle-up right-down right-up))
(let ([snip (find-snip/global (send event get-x) (send event get-y))])
(if (is-a? snip snip%)
(forward-event snip event)
(super on-event event)))
(super on-event event)))
;; forward-event ((is-a?/c snip%) (is-a?/c mouse-event%) . -> . void?)
;; send the event to the snip
(define/private (forward-event snip event)
(let ([editorx (box 0)]
[editory (box 0)])
(get-snip-location snip editorx editory false)
(let ([x (box (unbox editorx))]
[y (box (unbox editory))])
(local-to-global x y)
(send snip on-event (get-dc) (unbox x) (unbox y)
(unbox editorx) (unbox editory) event)
(set-caret-owner snip 'display))))
;; find-snip/global (number? number? . -> . (union (is-a?/c snip%) false?))
;; finds the snip in the pasteboard that is at x y in the global display
(define/private (find-snip/global x y)
(let ([new-x (box x)]
[new-y (box y)])
(global-to-local new-x new-y)
(cond
[(is-a? this text%)
(let ([pos (send this find-position (unbox new-x) (unbox new-y))])
(find-snip pos 'after-or-none))]
[(is-a? this pasteboard%)
(find-snip (unbox new-x) (unbox new-y))])))
(super-instantiate ())
))
)