dispatch method
Dispatches a message through interception, children, then self handlers.
Implementation
Cmd? dispatch(Msg msg) {
rebuild();
if (msg is BackgroundColorMsg) {
updateThemeFromBackground(msg.hex);
}
// --- 1. Interception Phase (Top-down) ---
// Widgets can override handleIntercept to catch messages before children.
Cmd? interceptCmd;
if (this is StatefulElement) {
interceptCmd = (this as StatefulElement).state.handleIntercept(msg);
} else {
final (newWidget, cmd) = widget.handleIntercept(msg);
if (!identical(newWidget, widget)) {
update(newWidget);
}
interceptCmd = cmd;
}
if (interceptCmd != null) return interceptCmd;
// --- 2. Children Phase ---
final cmds = <Cmd>[];
final children = msg is KeyMsg ? _children.reversed : _children;
for (final child in children) {
final cmd = child.dispatch(msg);
if (cmd != null) {
// Keyboard events use a "one-winner" policy with bubbling.
// If a child handled it, we stop propagation.
if (msg is KeyMsg) return cmd;
cmds.add(cmd);
}
}
// --- 3. Self Phase (Bottom-up) ---
Cmd? selfCmd;
if (this is StatefulElement) {
selfCmd = (this as StatefulElement).state.handleUpdate(msg);
} else {
final (newWidget, cmd) = widget.handleUpdate(msg);
if (!identical(newWidget, widget)) {
update(newWidget);
}
selfCmd = cmd;
}
if (selfCmd != null) {
if (msg is KeyMsg) return selfCmd;
cmds.add(selfCmd);
}
return _coalesceCommands(cmds);
}