Event System
SimpleKit separates raw browser input from toolkit events using a small windowing system abstraction. This allows the same UI logic to work in both canvas and imperative modes.
Fundamental Events
The windowing system (see windowing-system module) listens for DOM events and
creates FundamentalEvents. These represent low level actions such as
mousedown, mouseup, mousemove, keydown, keyup and resize. Each event
contains a timeStamp along with coordinates or key data. Fundamental events
are placed on a shared queue which the toolkit consumes each animation frame.
A helper coalesceEvents function merges multiple mouse move or resize events so
that only the latest of each type is processed.
SKEvent Hierarchy
The toolkit defines several classes which describe higher level events passed to widgets and global listeners.
SKEvent– Base class containing the event type, timestamp and optional source object.SKMouseEvent– ExtendsSKEventand includesxandycoordinates.SKKeyboardEvent– ExtendsSKEventand carries an optional key string.SKResizeEvent– Reports changes to the canvas size withwidthandheight.
All event objects are exported from the events module and are used throughout
SimpleKit.
Event Translators
Fundamental events are transformed into toolkit events by Event Translators.
Each translator implements an update(fe: FundamentalEvent) function that either
returns an SKEvent or undefined if no event should be generated.
Four translators are provided:
fundamentalTranslator– Converts fundamental events directly to the matchingSKEventsubclass. For example amousemovefundamental event becomes anSKMouseEvent.clickTranslator– Detects mouse down and up pairs within a short time and distance to emitclickevents.dblclickTranslator– Uses an internal click translator to detect two clicks occurring within a configurable time threshold, emitting adblclickevent.dragTranslator– Watches mouse movement after a press to generatedragstart,draganddragendevents once movement exceeds a threshold.
Applications can add their own translators using addSKEventTranslator() in
both runtime modes.
Writing a translator
An event translator is an object with an update(fundamentalEvent) method. The method is called for every fundamental event and may return a newly constructed SKEvent. Translators run in the order they are registered which makes it possible to chain behaviours or override defaults.
const wheelTranslator = {
update(fe) {
if (fe.type === 'wheel') {
return new SKEvent('wheel', fe.timeStamp, fe.deltaY);
}
}
};
addSKEventTranslator(wheelTranslator);
Dispatching Events
In canvas mode all translated events are delivered to the global event
listener via setSKEventListener. Applications typically switch on the event
type to perform custom logic.
In imperative mode events are first routed to the widget tree. The mouse and keyboard dispatchers manage focus and hit testing:
mouseDispatchdetermines the element route under the pointer, sendsmouseenter/mouseexittransitions and performs capture/bubble propagation.keyboardDispatchforwards keyboard events to the currently focused widget.
Widgets implement handleMouseEvent and handleKeyboardEvent to react to these
callbacks. Global listeners registered with setSKEventListener still receive
all events after widget dispatch is complete.
Requesting Focus
Imperative mode exposes requestMouseFocus and requestKeyboardFocus helpers in
the dispatch module. Widgets such as SKButton and SKTextfield call these
methods when appropriate so they receive subsequent events exclusively until the
operation is finished or focus is cleared.
Custom Events
Widgets may emit their own high level events. For example SKButton emits an
action event when clicked and SKTextfield emits textchanged whenever its
text content updates. These events flow through the same dispatch mechanism and
can be observed using addEventListener on the widget instance.