Event sinking and filtering
Pointer and Key events "sink" from ancestors down to their target. The "sink" portion is the first phase of event handling; and it runs before the "bubbling" phase. The root ancestor and all descendants toward the target
View
are notified of the event before the target is during this phase.
This phase can also be considered the filter phase, because it lets ancestors decide which events their children get to handle, since they can "veto" an event before it reaches the intended target.
Listeners can take part in this phase of event handling as well. You do this by registering the following types via their respective properties within View
.
PointerListener
viapointerFilter
PointerMotionListener
viapointerMotionFilter
KeyListener
viakeyFilter
package pointerinput
import io.nacular.doodle.core.View
import io.nacular.doodle.event.KeyListener.Companion.pressed
import io.nacular.doodle.event.PointerListener.Companion.clicked
import io.nacular.doodle.event.PointerMotionListener.Companion.moved
fun filter(view: View) {
//sampleStart
view.pointerFilter += clicked { event ->
// called whenever a pointer is pressed on this
// View or its children, before the target
// is notified
}
view.pointerMotionFilter += moved { event ->
// called whenever a pointer is pressed on this
// View or its children, before the target
// is notified
}
view.keyFilter += pressed { event ->
// called whenever a key is pressed while this
// View or one of its children has focus,
// before the target is notified
}
//sampleEnd
}
Calling consume
during filter will prevent descendants (and the target) from receiving the event
Event bubbling
Event "bubbling" is the second and final phase of event handling. This phase notifies the target View
and then "bubbles" the event up to ancestors of that View
as long as the event remains unconsumed. This means you can listen to all events that happen to the descendants of a View
during this phase as well. And similar to the filter phase, you will only receive events that were not consumed before-hand, which in this case means down the hierarchy.
Bubbling is canceled if any listener calls consume
.
Pointer events for ancestors
Pointer events sent to an ancestors and descendants are slightly different from those sent to the View
. These events continue to have the same target
(View
where the event fired), but their source
changes to the recipient ancestor as they bubble or sink.