Event Dispatch

  • UI toolkits typically organize widgets into a tree
    • need container widgets for non-leaf nodes
    • child order dictates draw order (e.g. draw left-to-right)
  • Route construction and propagation only applied to positional dispatch
  • The process of figuring out where the event goes and delivering it is called dispatch.
  • Propagation
    • capture DOWN from root to target
    • bubble UP from target to root
  • mouse event: target is the widget at the location of the cursor
    • called Positional Dispatch
  • key event: target is the widget that has focus
    • called Focus Dispatch
  • touch events: target selection may be more complex
    • A continuous gesture (like pinch-to-zoom) might select the target at the center point of all touches at gesture start
    • A swipe (like swipe right) might select the target at the center of the entire path of all fingers
  • SimpleKit Binding uses a form of Inheritance Binding with Listener Objects
button.addEventListener("action", () => {
  console.log("Button was clicked!");
});
  • We stop propagation to prevent some events from bubbling up to “default events”
  • Capture phase is to give higher-level containers (parents) a chance to intercept or filter events before they reach the target widget.
  • When Focus Dispatch, maximum one keyboard focus and one mouse focus.
  • Focus Dispatch Needs Positional Dispatch
    • A mousedown event sets mouse and keyboard focus to a widget. Only text entry widgets should request keyboard focus. Any widget could request mouse focus
  • The Mouse Enter and Exit Events Approach:
    1. Get the Target Widget
      • Run buildTargetRoute(...) to find the widget under the mouse.
      • The last item in that route is the front-most / deepest widget currently under the cursor.
    2. Compare with Previous Hovered Element
      • If the mouse was previously over a different widget:
      • Send "mouseexit" to the old one
      • Send "mouseenter" to the new one
    3. Edge Case (Not in SimpleKit)
      • In some systems, a widget can refuse a mouseenter (e.g., it’s invisible, disabled, etc.)
      • Then the system tries the next-highest ancestor in the route
      • But in SimpleKit, the toolkit always just sends the events to the new end element (no fallback logic)