38 if (_focusables.empty()) {
42 if (_focused ==
nullptr) {
43 set_focus(ctx, _focusables.front());
46 auto it = std::ranges::find(_focusables, _focused);
47 if (it == _focusables.end()) {
48 set_focus(ctx, _focusables.front());
52 if (it == _focusables.end()) {
53 it = _focusables.begin();
60 if (_focusables.empty()) {
64 if (_focused ==
nullptr) {
65 set_focus(ctx, _focusables.front());
69 auto it = std::ranges::find(_focusables, _focused);
70 if (it == _focusables.end()) {
71 set_focus(ctx, _focusables.front());
75 if (it == _focusables.begin()) {
76 it = _focusables.end();
84 if (_focusables.empty()) {
88 if (_focused ==
nullptr) {
89 set_focus(ctx, _focusables.front());
93 const auto& from = _focused->transform;
94 const float fx = from.get_center().x;
95 const float fy = from.get_center().y;
98 float bestScore = 1e30f;
100 for (
Widget* w : _focusables) {
104 const auto& to = w->transform;
105 const float tx = to.get_center().x;
106 const float ty = to.get_center().y;
107 const float vx = tx - fx;
108 const float vy = ty - fy;
111 if (dx != 0 && (vx * dx) <= 0.0f) {
114 if (dy != 0 && (vy * dy) <= 0.0f) {
120 const float primary = (dx != 0) ? std::abs(vx) : std::abs(vy);
121 const float ortho = (dx != 0) ? std::abs(vy) : std::abs(vx);
124 const float dist2 = (vx * vx) + (vy * vy);
126 const float score = (primary * 1.0f) + (ortho * 2.0f) + (dist2 * 0.001f);
127 if (score < bestScore) {
133 if (best !=
nullptr) {
134 set_focus(ctx, best);
Shared state for the UI system.
UI context and focus management for the ASW UI module.