onUpdate method
Override to react during the update phase each frame.
Called after all registered listenOnUpdate listeners.
Implementation
@override
@mustCallSuper
void onUpdate(double dt) => on2<CTransform<T>, CRectCollider<T>>((t, c) {
t.position = worldPosition;
// collider covers only the trigger; dropdown is handled manually
c.size = _interactiveSize.copy();
final mouse = backend.mouse;
final origin = t.position;
final RectangleD triggerRect = .rect(origin.x, origin.y, controlWidth, controlHeight);
final hoveredTrigger = backend.collision.pointRectangle(
mouse.position, triggerRect,
);
_IsWidgetClickable_updateState(
hovered: hoveredTrigger,
usePendingSingleClickMethod: false,
dt: dt,
);
// toggle open on trigger click
if (hoveredTrigger && mouse.btnLeft.pressed) {
_isOpen = !_isOpen;
_hoveredItemIndex = -1;
}
if (_isOpen) {
final RectangleD dropdownRect = .rect(
origin.x, origin.y + controlHeight,
controlWidth, _dropdownHeight,
);
final hoveredDropdown = backend.collision.pointRectangle(
mouse.position, dropdownRect,
);
// track which item the mouse is over
if (hoveredDropdown) {
final relY = mouse.position.y - (origin.y + controlHeight);
_hoveredItemIndex = (relY / itemHeight).floor().clamp(0, options.length - 1);
} else {
_hoveredItemIndex = -1;
}
// click an item
if (hoveredDropdown && mouse.btnLeft.pressed) {
selectedIndex = _hoveredItemIndex;
onChangeFn?.call(this, selectedIndex, selectedLabel);
_isOpen = false;
_hoveredItemIndex = -1;
}
// click outside the entire widget → close
final hoveredFull = backend.collision.pointRectangle(
mouse.position, _fullRect(origin),
);
if (!hoveredFull && mouse.btnLeft.pressed) {
_isOpen = false;
_hoveredItemIndex = -1;
}
// keyboard navigation
if (backend.input.isKeyPressed(.KEY_ESCAPE)) {
_isOpen = false;
_hoveredItemIndex = -1;
}
if (backend.input.isKeyPressed(.KEY_DOWN)) {
_hoveredItemIndex = (_hoveredItemIndex + 1).clamp(0, options.length - 1);
}
if (backend.input.isKeyPressed(.KEY_UP)) {
_hoveredItemIndex = (_hoveredItemIndex - 1).clamp(0, options.length - 1);
}
if (backend.input.isKeyPressed(.KEY_ENTER) || backend.input.isKeyPressed(.KEY_KP_ENTER)) {
if (_hoveredItemIndex >= 0) {
selectedIndex = _hoveredItemIndex;
onChangeFn?.call(this, selectedIndex, selectedLabel);
}
_isOpen = false;
_hoveredItemIndex = -1;
}
}
});