UI event handling refactoring
- A+ is now the command key, and M+ is the option key, on mac - new send-gesture, propagate-gesture words clean up gesture sending - always send user-input after key-down, without checking if a gadget handled the key-down firstdb4
parent
b141b732ab
commit
e65368a137
|
@ -18,8 +18,8 @@ IN: ui.cocoa.views
|
||||||
{
|
{
|
||||||
{ S+ HEX: 20000 }
|
{ S+ HEX: 20000 }
|
||||||
{ C+ HEX: 40000 }
|
{ C+ HEX: 40000 }
|
||||||
{ A+ HEX: 80000 }
|
{ A+ HEX: 100000 }
|
||||||
{ M+ HEX: 100000 }
|
{ M+ HEX: 80000 }
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
: key-codes
|
: key-codes
|
||||||
|
@ -59,9 +59,8 @@ IN: ui.cocoa.views
|
||||||
: key-event>gesture ( event -- modifiers keycode action? )
|
: key-event>gesture ( event -- modifiers keycode action? )
|
||||||
dup event-modifiers swap key-code ;
|
dup event-modifiers swap key-code ;
|
||||||
|
|
||||||
: send-key-event ( view event quot -- ? )
|
: send-key-event ( view gesture -- )
|
||||||
>r key-event>gesture r> call swap window-focus
|
swap window-focus propagate-gesture ;
|
||||||
send-gesture ; inline
|
|
||||||
|
|
||||||
: send-user-input ( view string -- )
|
: send-user-input ( view string -- )
|
||||||
CF>string swap window-focus user-input ;
|
CF>string swap window-focus user-input ;
|
||||||
|
@ -70,18 +69,19 @@ IN: ui.cocoa.views
|
||||||
NSArray swap -> arrayWithObject: -> interpretKeyEvents: ;
|
NSArray swap -> arrayWithObject: -> interpretKeyEvents: ;
|
||||||
|
|
||||||
: send-key-down-event ( view event -- )
|
: send-key-down-event ( view event -- )
|
||||||
2dup [ <key-down> ] send-key-event
|
[ key-event>gesture <key-down> send-key-event ]
|
||||||
[ interpret-key-event ] [ 2drop ] if ;
|
[ interpret-key-event ]
|
||||||
|
2bi ;
|
||||||
|
|
||||||
: send-key-up-event ( view event -- )
|
: send-key-up-event ( view event -- )
|
||||||
[ <key-up> ] send-key-event drop ;
|
key-event>gesture <key-up> send-key-event ;
|
||||||
|
|
||||||
: mouse-event>gesture ( event -- modifiers button )
|
: mouse-event>gesture ( event -- modifiers button )
|
||||||
dup event-modifiers swap button ;
|
dup event-modifiers swap button ;
|
||||||
|
|
||||||
: send-button-down$ ( view event -- )
|
: send-button-down$ ( view event -- )
|
||||||
[ mouse-event>gesture <button-down> ] 2keep
|
[ mouse-event>gesture <button-down> ]
|
||||||
mouse-location rot window send-button-down ;
|
[ mouse-location rot window send-button-down ] 2bi ;
|
||||||
|
|
||||||
: send-button-up$ ( view event -- )
|
: send-button-up$ ( view event -- )
|
||||||
[ mouse-event>gesture <button-up> ] 2keep
|
[ mouse-event>gesture <button-up> ] 2keep
|
||||||
|
|
|
@ -26,10 +26,10 @@ TUPLE: slot-editor < track ref text ;
|
||||||
GENERIC: finish-editing ( slot-editor ref -- )
|
GENERIC: finish-editing ( slot-editor ref -- )
|
||||||
|
|
||||||
M: key-ref finish-editing
|
M: key-ref finish-editing
|
||||||
drop T{ update-object } swap send-gesture drop ;
|
drop T{ update-object } swap propagate-gesture ;
|
||||||
|
|
||||||
M: value-ref finish-editing
|
M: value-ref finish-editing
|
||||||
drop T{ update-slot } swap send-gesture drop ;
|
drop T{ update-slot } swap propagate-gesture ;
|
||||||
|
|
||||||
: slot-editor-value ( slot-editor -- object )
|
: slot-editor-value ( slot-editor -- object )
|
||||||
text>> control-value parse-fresh ;
|
text>> control-value parse-fresh ;
|
||||||
|
@ -55,14 +55,14 @@ M: value-ref finish-editing
|
||||||
|
|
||||||
: delete ( slot-editor -- )
|
: delete ( slot-editor -- )
|
||||||
dup ref>> delete-ref
|
dup ref>> delete-ref
|
||||||
T{ update-object } swap send-gesture drop ;
|
T{ update-object } swap propagate-gesture ;
|
||||||
|
|
||||||
\ delete H{
|
\ delete H{
|
||||||
{ +description+ "Delete the slot and close the slot editor." }
|
{ +description+ "Delete the slot and close the slot editor." }
|
||||||
} define-command
|
} define-command
|
||||||
|
|
||||||
: close ( slot-editor -- )
|
: close ( slot-editor -- )
|
||||||
T{ update-slot } swap send-gesture drop ;
|
T{ update-slot } swap propagate-gesture ;
|
||||||
|
|
||||||
\ close H{
|
\ close H{
|
||||||
{ +description+ "Close the slot editor without saving changes." }
|
{ +description+ "Close the slot editor without saving changes." }
|
||||||
|
@ -92,7 +92,7 @@ TUPLE: editable-slot < track printer ref ;
|
||||||
|
|
||||||
: <edit-button> ( -- gadget )
|
: <edit-button> ( -- gadget )
|
||||||
"..."
|
"..."
|
||||||
[ T{ edit-slot } swap send-gesture drop ]
|
[ T{ edit-slot } swap propagate-gesture ]
|
||||||
<roll-button> ;
|
<roll-button> ;
|
||||||
|
|
||||||
: display-slot ( gadget editable-slot -- )
|
: display-slot ( gadget editable-slot -- )
|
||||||
|
|
|
@ -107,6 +107,20 @@ world H{
|
||||||
{ T{ button-up f { A+ } 1 } [ drop T{ button-up f f 2 } button-gesture ] }
|
{ T{ button-up f { A+ } 1 } [ drop T{ button-up f f 2 } button-gesture ] }
|
||||||
} set-gestures
|
} set-gestures
|
||||||
|
|
||||||
|
PREDICATE: specific-button-up < button-up #>> ;
|
||||||
|
|
||||||
|
PREDICATE: specific-button-down < button-down #>> ;
|
||||||
|
|
||||||
|
: generalize-gesture ( gesture -- )
|
||||||
|
clone f >># button-gesture ;
|
||||||
|
|
||||||
|
M: world handle-gesture ( gesture gadget -- ? )
|
||||||
|
{
|
||||||
|
{ [ over specific-button-up? ] [ drop generalize-gesture t ] }
|
||||||
|
{ [ over specific-button-down? ] [ drop generalize-gesture t ] }
|
||||||
|
[ call-next-method ]
|
||||||
|
} cond ;
|
||||||
|
|
||||||
: close-global ( world global -- )
|
: close-global ( world global -- )
|
||||||
dup get-global find-world rot eq?
|
dup get-global find-world rot eq?
|
||||||
[ f swap set-global ] [ drop ] if ;
|
[ f swap set-global ] [ drop ] if ;
|
||||||
|
|
|
@ -15,11 +15,11 @@ $nl
|
||||||
"The default implementation looks at the " { $snippet "\"gestures\"" } " word property of each superclass of the gadget's class." }
|
"The default implementation looks at the " { $snippet "\"gestures\"" } " word property of each superclass of the gadget's class." }
|
||||||
{ $notes "Methods should be defined on this word if you desire to handle an arbitrary set of gestures. To define handlers for a fixed set, it is easier to use " { $link set-gestures } "." } ;
|
{ $notes "Methods should be defined on this word if you desire to handle an arbitrary set of gestures. To define handlers for a fixed set, it is easier to use " { $link set-gestures } "." } ;
|
||||||
|
|
||||||
{ send-gesture handle-gesture set-gestures } related-words
|
{ propagate-gesture handle-gesture set-gestures } related-words
|
||||||
|
|
||||||
HELP: send-gesture
|
HELP: propagate-gesture
|
||||||
{ $values { "gesture" "a gesture" } { "gadget" gadget } { "?" "a boolean" } }
|
{ $values { "gesture" "a gesture" } { "gadget" gadget } { "?" "a boolean" } }
|
||||||
{ $description "Calls " { $link send-gesture } " on every parent of " { $snippet "gadget" } ". Outputs " { $link f } " if some parent handled the gesture, else outputs " { $link t } "." } ;
|
{ $description "Calls " { $link handle-gesture } " on every parent of " { $snippet "gadget" } ". Outputs " { $link f } " if some parent handled the gesture, else outputs " { $link t } "." } ;
|
||||||
|
|
||||||
HELP: user-input
|
HELP: user-input
|
||||||
{ $values { "str" string } { "gadget" gadget } }
|
{ $values { "str" string } { "gadget" gadget } }
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: accessors arrays assocs kernel math models namespaces
|
USING: accessors arrays assocs kernel math models namespaces
|
||||||
make sequences words strings system hashtables math.parser
|
make sequences words strings system hashtables math.parser
|
||||||
math.vectors classes.tuple classes ui.gadgets boxes calendar
|
math.vectors classes.tuple classes boxes calendar
|
||||||
alarms symbols combinators sets columns ;
|
alarms symbols combinators sets columns fry ui.gadgets ;
|
||||||
IN: ui.gestures
|
IN: ui.gestures
|
||||||
|
|
||||||
: set-gestures ( class hash -- ) "gestures" set-word-prop ;
|
: set-gestures ( class hash -- ) "gestures" set-word-prop ;
|
||||||
|
@ -15,13 +15,17 @@ M: object handle-gesture
|
||||||
[ "gestures" word-prop ] map
|
[ "gestures" word-prop ] map
|
||||||
assoc-stack dup [ call f ] [ 2drop t ] if ;
|
assoc-stack dup [ call f ] [ 2drop t ] if ;
|
||||||
|
|
||||||
: send-gesture ( gesture gadget -- ? )
|
: send-gesture ( gesture gadget -- )
|
||||||
[ dupd handle-gesture ] each-parent nip ;
|
handle-gesture drop ;
|
||||||
|
|
||||||
|
: each-gesture ( gesture seq -- )
|
||||||
|
[ send-gesture ] with each ;
|
||||||
|
|
||||||
|
: propagate-gesture ( gesture gadget -- )
|
||||||
|
[ handle-gesture ] with each-parent drop ;
|
||||||
|
|
||||||
: user-input ( str gadget -- )
|
: user-input ( str gadget -- )
|
||||||
over empty?
|
'[ _ [ user-input* ] with each-parent drop ] unless-empty ;
|
||||||
[ [ dupd user-input* ] each-parent ] unless
|
|
||||||
2drop ;
|
|
||||||
|
|
||||||
! Gesture objects
|
! Gesture objects
|
||||||
TUPLE: motion ; C: <motion> motion
|
TUPLE: motion ; C: <motion> motion
|
||||||
|
@ -46,11 +50,8 @@ TUPLE: right-action ; C: <right-action> right-action
|
||||||
TUPLE: up-action ; C: <up-action> up-action
|
TUPLE: up-action ; C: <up-action> up-action
|
||||||
TUPLE: down-action ; C: <down-action> down-action
|
TUPLE: down-action ; C: <down-action> down-action
|
||||||
|
|
||||||
TUPLE: zoom-in-action ; C: <zoom-in-action> zoom-in-action
|
TUPLE: zoom-in-action ; C: <zoom-in-action> zoom-in-action
|
||||||
TUPLE: zoom-out-action ; C: <zoom-out-action> zoom-out-action
|
TUPLE: zoom-out-action ; C: <zoom-out-action> zoom-out-action
|
||||||
|
|
||||||
: generalize-gesture ( gesture -- newgesture )
|
|
||||||
clone f >># ;
|
|
||||||
|
|
||||||
! Modifiers
|
! Modifiers
|
||||||
SYMBOLS: C+ A+ M+ S+ ;
|
SYMBOLS: C+ A+ M+ S+ ;
|
||||||
|
@ -58,7 +59,7 @@ SYMBOLS: C+ A+ M+ S+ ;
|
||||||
TUPLE: key-down mods sym ;
|
TUPLE: key-down mods sym ;
|
||||||
|
|
||||||
: <key-gesture> ( mods sym action? class -- mods' sym' )
|
: <key-gesture> ( mods sym action? class -- mods' sym' )
|
||||||
>r [ S+ rot remove swap ] unless r> boa ; inline
|
[ [ S+ rot remove swap ] unless ] dip boa ; inline
|
||||||
|
|
||||||
: <key-down> ( mods sym action? -- key-down )
|
: <key-down> ( mods sym action? -- key-down )
|
||||||
key-down <key-gesture> ;
|
key-down <key-gesture> ;
|
||||||
|
@ -100,11 +101,7 @@ SYMBOL: double-click-timeout
|
||||||
hand-loc get hand-click-loc get = not ;
|
hand-loc get hand-click-loc get = not ;
|
||||||
|
|
||||||
: button-gesture ( gesture -- )
|
: button-gesture ( gesture -- )
|
||||||
hand-clicked get-global 2dup send-gesture [
|
hand-clicked get-global propagate-gesture ;
|
||||||
>r generalize-gesture r> send-gesture drop
|
|
||||||
] [
|
|
||||||
2drop
|
|
||||||
] if ;
|
|
||||||
|
|
||||||
: drag-gesture ( -- )
|
: drag-gesture ( -- )
|
||||||
hand-buttons get-global
|
hand-buttons get-global
|
||||||
|
@ -130,14 +127,11 @@ SYMBOL: drag-timer
|
||||||
|
|
||||||
: fire-motion ( -- )
|
: fire-motion ( -- )
|
||||||
hand-buttons get-global empty? [
|
hand-buttons get-global empty? [
|
||||||
T{ motion } hand-gadget get-global send-gesture drop
|
T{ motion } hand-gadget get-global propagate-gesture
|
||||||
] [
|
] [
|
||||||
drag-gesture
|
drag-gesture
|
||||||
] if ;
|
] if ;
|
||||||
|
|
||||||
: each-gesture ( gesture seq -- )
|
|
||||||
[ handle-gesture drop ] with each ;
|
|
||||||
|
|
||||||
: hand-gestures ( new old -- )
|
: hand-gestures ( new old -- )
|
||||||
drop-prefix <reversed>
|
drop-prefix <reversed>
|
||||||
T{ mouse-leave } swap each-gesture
|
T{ mouse-leave } swap each-gesture
|
||||||
|
@ -145,15 +139,15 @@ SYMBOL: drag-timer
|
||||||
|
|
||||||
: forget-rollover ( -- )
|
: forget-rollover ( -- )
|
||||||
f hand-world set-global
|
f hand-world set-global
|
||||||
hand-gadget get-global >r
|
hand-gadget get-global
|
||||||
f hand-gadget set-global
|
[ f hand-gadget set-global f ] dip
|
||||||
f r> parents hand-gestures ;
|
parents hand-gestures ;
|
||||||
|
|
||||||
: send-lose-focus ( gadget -- )
|
: send-lose-focus ( gadget -- )
|
||||||
T{ lose-focus } swap handle-gesture drop ;
|
T{ lose-focus } swap send-gesture ;
|
||||||
|
|
||||||
: send-gain-focus ( gadget -- )
|
: send-gain-focus ( gadget -- )
|
||||||
T{ gain-focus } swap handle-gesture drop ;
|
T{ gain-focus } swap send-gesture ;
|
||||||
|
|
||||||
: focus-child ( child gadget ? -- )
|
: focus-child ( child gadget ? -- )
|
||||||
[
|
[
|
||||||
|
@ -219,9 +213,11 @@ SYMBOL: drag-timer
|
||||||
|
|
||||||
: move-hand ( loc world -- )
|
: move-hand ( loc world -- )
|
||||||
dup hand-world set-global
|
dup hand-world set-global
|
||||||
under-hand >r over hand-loc set-global
|
under-hand [
|
||||||
pick-up hand-gadget set-global
|
over hand-loc set-global
|
||||||
under-hand r> hand-gestures ;
|
pick-up hand-gadget set-global
|
||||||
|
under-hand
|
||||||
|
] dip hand-gestures ;
|
||||||
|
|
||||||
: send-button-down ( gesture loc world -- )
|
: send-button-down ( gesture loc world -- )
|
||||||
move-hand
|
move-hand
|
||||||
|
@ -240,14 +236,13 @@ SYMBOL: drag-timer
|
||||||
: send-wheel ( direction loc world -- )
|
: send-wheel ( direction loc world -- )
|
||||||
move-hand
|
move-hand
|
||||||
scroll-direction set-global
|
scroll-direction set-global
|
||||||
T{ mouse-scroll } hand-gadget get-global send-gesture
|
T{ mouse-scroll } hand-gadget get-global propagate-gesture ;
|
||||||
drop ;
|
|
||||||
|
|
||||||
: world-focus ( world -- gadget )
|
: world-focus ( world -- gadget )
|
||||||
dup focus>> [ world-focus ] [ ] ?if ;
|
dup focus>> [ world-focus ] [ ] ?if ;
|
||||||
|
|
||||||
: send-action ( world gesture -- )
|
: send-action ( world gesture -- )
|
||||||
swap world-focus send-gesture drop ;
|
swap world-focus propagate-gesture ;
|
||||||
|
|
||||||
GENERIC: gesture>string ( gesture -- string/f )
|
GENERIC: gesture>string ( gesture -- string/f )
|
||||||
|
|
||||||
|
|
|
@ -67,10 +67,10 @@ M: browser-gadget definitions-changed ( assoc browser -- )
|
||||||
\ browser-help H{ { +nullary+ t } } define-command
|
\ browser-help H{ { +nullary+ t } } define-command
|
||||||
|
|
||||||
browser-gadget "toolbar" f {
|
browser-gadget "toolbar" f {
|
||||||
{ T{ key-down f { A+ } "b" } com-back }
|
{ T{ key-down f { A+ } "LEFT" } com-back }
|
||||||
{ T{ key-down f { A+ } "f" } com-forward }
|
{ T{ key-down f { A+ } "RIGHT" } com-forward }
|
||||||
{ T{ key-down f { A+ } "h" } com-documentation }
|
{ f com-documentation }
|
||||||
{ T{ key-down f { A+ } "v" } com-vocabularies }
|
{ f com-vocabularies }
|
||||||
{ T{ key-down f f "F1" } browser-help }
|
{ T{ key-down f f "F1" } browser-help }
|
||||||
} define-command-map
|
} define-command-map
|
||||||
|
|
||||||
|
|
|
@ -194,7 +194,7 @@ SYMBOLS: msg-obj class-name-ptr mouse-captured ;
|
||||||
:: handle-wm-keydown ( hWnd uMsg wParam lParam -- )
|
:: handle-wm-keydown ( hWnd uMsg wParam lParam -- )
|
||||||
wParam exclude-key-wm-keydown? [
|
wParam exclude-key-wm-keydown? [
|
||||||
wParam keystroke>gesture <key-down>
|
wParam keystroke>gesture <key-down>
|
||||||
hWnd window-focus send-gesture drop
|
hWnd window-focus propagate-gesture
|
||||||
] unless ;
|
] unless ;
|
||||||
|
|
||||||
:: handle-wm-char ( hWnd uMsg wParam lParam -- )
|
:: handle-wm-char ( hWnd uMsg wParam lParam -- )
|
||||||
|
@ -205,7 +205,7 @@ SYMBOLS: msg-obj class-name-ptr mouse-captured ;
|
||||||
|
|
||||||
:: handle-wm-keyup ( hWnd uMsg wParam lParam -- )
|
:: handle-wm-keyup ( hWnd uMsg wParam lParam -- )
|
||||||
wParam keystroke>gesture <key-up>
|
wParam keystroke>gesture <key-up>
|
||||||
hWnd window-focus send-gesture drop ;
|
hWnd window-focus propagate-gesture ;
|
||||||
|
|
||||||
:: set-window-active ( hwnd uMsg wParam lParam ? -- n )
|
:: set-window-active ( hwnd uMsg wParam lParam ? -- n )
|
||||||
? hwnd window (>>active?)
|
? hwnd window (>>active?)
|
||||||
|
|
|
@ -72,15 +72,19 @@ M: world configure-event
|
||||||
handle>> xic>> lookup-string
|
handle>> xic>> lookup-string
|
||||||
>r swap event-modifiers r> key-code <key-down> ;
|
>r swap event-modifiers r> key-code <key-down> ;
|
||||||
|
|
||||||
|
: valid-input? ( string -- ? )
|
||||||
|
[ f ] [ [ [ 127 = not ] [ CHAR: \s >= ] bi and ] all? ] if-empty ;
|
||||||
|
|
||||||
M: world key-down-event
|
M: world key-down-event
|
||||||
[ key-down-event>gesture ] keep world-focus
|
[ key-down-event>gesture ] keep
|
||||||
[ send-gesture ] keep swap [ user-input ] [ 2drop ] if ;
|
world-focus [ propagate-gesture ] keep
|
||||||
|
over valid-input? [ user-input ] [ 2drop ] if ;
|
||||||
|
|
||||||
: key-up-event>gesture ( event -- gesture )
|
: key-up-event>gesture ( event -- gesture )
|
||||||
dup event-modifiers swap 0 XLookupKeysym key-code <key-up> ;
|
dup event-modifiers swap 0 XLookupKeysym key-code <key-up> ;
|
||||||
|
|
||||||
M: world key-up-event
|
M: world key-up-event
|
||||||
>r key-up-event>gesture r> world-focus send-gesture drop ;
|
>r key-up-event>gesture r> world-focus propagate-gesture ;
|
||||||
|
|
||||||
: mouse-event>gesture ( event -- modifiers button loc )
|
: mouse-event>gesture ( event -- modifiers button loc )
|
||||||
dup event-modifiers over XButtonEvent-button
|
dup event-modifiers over XButtonEvent-button
|
||||||
|
|
Loading…
Reference in New Issue