ltk/widget/laid_out.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
// SPDX-License-Identifier: LGPL-2.1-only
// Copyright (C) 2026 Liberux Labs, S. L. <info@liberux.net>
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<Msg: Clone>
{
pub rect: Rect,
pub flat_idx: usize,
pub id: Option<WidgetId>,
pub paint_rect: Rect,
pub handlers: WidgetHandlers<Msg>,
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<String>,
/// Visible text of the widget, captured for the accessibility
/// tree. `None` for non-textual widgets (icons, dividers).
pub accessible_label: Option<String>,
pub is_live_region: bool,
}
impl<Msg: Clone> Clone for LaidOutWidget<Msg>
{
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,
}
}
}