// SPDX-License-Identifier: LGPL-2.1-only // Copyright (C) 2026 Liberux Labs, S. L. //! Widgets — the interactive and decorative leaves of the [`Element`] tree. //! //! Each widget lives in its own submodule and is reached through the //! crate-root re-exports (`button`, `text`, `text_edit`, `slider`, …) plus //! the `img_widget` alias for [`image::Image`]. Construct one from its //! free constructor function, configure it through builder-style methods, //! and convert it into [`Element`] via `.into()` when pushing it //! into a layout. //! //! ```rust,no_run //! # use ltk::{ button, column, slider, text, Element }; //! # #[ derive( Clone ) ] enum Msg { SetVolume( f32 ), Mute } //! # struct App { volume: f32 } //! # impl App { fn _ex( &self ) -> Element { //! column() //! .push( text( "Volume" ) ) //! .push( slider( self.volume ).on_change( |v| Msg::SetVolume( v ) ) ) //! .push( button( "Mute" ).on_press( Msg::Mute ) ) //! .into() //! # }} //! ``` //! //! ## What lives here //! //! * **Buttons / activations**: [`button::Button`], //! [`pressable::Pressable`], [`window_button::WindowButton`], //! [`list_item::ListItem`]. //! * **Stateful binary controls**: [`toggle::Toggle`], //! [`checkbox::Checkbox`], [`radio::Radio`]. //! * **Continuous controls**: [`slider::Slider`], [`vslider::VSlider`], //! [`progress_bar::ProgressBar`]. //! * **Text**: [`text::Text`], [`text_edit::TextEdit`]. //! * **Images / decoration**: [`image::Image`], [`separator::Separator`], //! [`container::Container`]. //! * **Clipping wrappers**: [`scroll::Scroll`] (with gesture-driven //! scrolling), [`viewport::Viewport`] (passive clip / fade), and //! [`flex::Flex`] (treats a non-spacer child as a row filler). //! * **Overlays**: [`dialog::Dialog`] (modal / non-modal centered //! confirmation card with built-in scrim, ESC-to-cancel, and //! tap-outside-to-dismiss for the non-modal variant). //! //! Layouts ([`column`](crate::column), [`row`](crate::row), //! [`stack`](crate::stack), [`grid`](crate::grid), //! [`spacer`](crate::spacer)) live in [`crate::layout`]; they share the //! same [`Element`] tree but are kept separate to make the "what does //! this paint" / "how is this arranged" distinction explicit. //! //! ## Per-leaf handler snapshot //! //! [`WidgetHandlers`] is the snapshot the layout pass takes of every //! interactive widget so the input handlers can dispatch in O(1) without //! re-walking the [`Element`] tree. It is `pub( crate )` plumbing for the //! runtime; downstream apps usually never see it. The `test_support` //! module re-exports it for integration tests that want to assert on the //! handler shape. pub mod button; pub mod container; pub mod text_edit; pub mod image; pub mod text; pub mod scroll; pub mod viewport; pub mod slider; pub mod vslider; pub mod toggle; pub mod separator; pub mod progress_bar; pub mod checkbox; pub mod radio; pub mod list_item; pub mod window_button; pub mod pressable; pub mod flex; pub mod combo; pub mod anchored_overlay; pub mod spinner; pub mod tab_bar; pub mod toast; pub mod tooltip; pub mod notebook; pub mod date_picker; pub mod time_picker; pub mod color_picker; pub mod dialog; pub mod external; pub mod element; pub mod handlers; pub mod laid_out; pub mod factory; pub use element::Element; pub use handlers::WidgetHandlers; pub use laid_out::LaidOutWidget; pub use factory::{ button, icon_button, text_edit, image, text, container, external }; /// Type alias for the message-mapping closure shared across an /// [`Element::map`] walk. Stored as `Arc` so every per-widget /// `map_msg` can clone and re-share it without copying the closure body /// — the same closure is invoked once per emitted message, regardless /// of how many leaves the sub-tree has. pub( crate ) type MapFn = std::sync::Arc U>;