// SPDX-License-Identifier: LGPL-2.1-only // Copyright (C) 2026 Liberux Labs, S. L. use crate::types::{ Rect, WidgetId }; use super::handlers::WidgetHandlers; /// Result of laying out one *interactive* widget — i.e. a widget that should /// receive pointer / touch hit-testing. Captures both the *hit rect* (where /// input lands) and the *paint rect* (the bounding box of everything the /// widget actually paints, including hover circles, focus rings, shadows…). /// The paint rect is used by the partial-redraw path to know how much of the /// canvas must be invalidated when a widget transitions in/out of a given /// state — it is always `>= rect`. /// /// `handlers` carries the snapshot of the widget's callbacks/values at layout /// time so input dispatch is O(1) instead of re-walking the [`super::Element`] tree. /// /// `keyboard_focusable` snapshots whether the widget should participate in the /// Tab / Shift+Tab cycle. Most interactive widgets are also keyboard-focusable /// (`Button`, `TextEdit`, `Slider`, …) but window-decoration chrome /// (`WindowButton`) is interactive without taking keyboard focus by default — /// matching the convention of macOS / GNOME / Windows title bars. pub struct LaidOutWidget { pub rect: Rect, pub flat_idx: usize, pub id: Option, pub paint_rect: Rect, pub handlers: WidgetHandlers, pub keyboard_focusable: bool, /// Cursor shape this widget wants to show on hover. Snapshotted /// from [`super::Element::cursor_shape`] at layout time so the input /// dispatch can pick the right shape without re-walking the /// element tree. pub cursor: crate::types::CursorShape, pub tooltip: Option, /// Visible text of the widget, captured for the accessibility /// tree. `None` for non-textual widgets (icons, dividers). pub accessible_label: Option, pub is_live_region: bool, } impl Clone for LaidOutWidget { fn clone( &self ) -> Self { Self { rect: self.rect, flat_idx: self.flat_idx, id: self.id, paint_rect: self.paint_rect, handlers: self.handlers.clone(), keyboard_focusable: self.keyboard_focusable, cursor: self.cursor, tooltip: self.tooltip.clone(), accessible_label: self.accessible_label.clone(), is_live_region: self.is_live_region, } } }