Skip to main content

azul_layout/widgets/
mod.rs

1//! Built-in widgets for the Azul GUI system
2
3/// Implements `Display, Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Hash`
4/// for a Callback with a `.cb` field.
5///
6/// This is necessary to work around for <https://github.com/rust-lang/rust/issues/54508>
7///
8/// # Host-invoker plumbing for managed-FFI bindings
9///
10/// Widget callbacks have varying shapes — some are
11/// `(RefAny, CallbackInfo) -> Update` (Button), others add a state
12/// struct (CheckBox/Tab/etc.), a few have two extras (`ListView`). The
13/// macro therefore does **not** auto-emit an `impl_managed_callback!`
14/// invocation; per-widget files apply it themselves with the right
15/// extras list. The base invocation still produces the standard
16/// `Display`/`Debug`/`Clone`/`From<CallbackType>`/`From<Callback>` impls
17/// that all widget callbacks share.
18#[macro_export]
19macro_rules! impl_widget_callback {
20    (
21        $callback_wrapper:ident,
22        $option_callback_wrapper:ident,
23        $callback_value:ident,
24        $callback_ty:ident
25    ) => {
26        #[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
27        #[repr(C)]
28        pub struct $callback_wrapper {
29            pub refany: RefAny,
30            pub callback: $callback_value,
31        }
32
33        #[repr(C)]
34        pub struct $callback_value {
35            pub cb: $callback_ty,
36            /// For FFI: stores the foreign callable (e.g., `PyFunction`)
37            /// Native Rust code sets this to None
38            pub ctx: azul_core::refany::OptionRefAny,
39        }
40
41        azul_css::impl_option!(
42            $callback_wrapper,
43            $option_callback_wrapper,
44            copy = false,
45            [Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash]
46        );
47
48        impl $callback_value {
49            /// Create a new callback with just a function pointer (for native Rust code)
50            pub fn create<I: Into<$callback_value>>(cb: I) -> $callback_value {
51                cb.into()
52            }
53        }
54
55        impl ::core::fmt::Display for $callback_value {
56            fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
57                write!(f, "{:?}", self)
58            }
59        }
60
61        impl ::core::fmt::Debug for $callback_value {
62            fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
63                let callback = stringify!($callback_value);
64                write!(f, "{} @ 0x{:x}", callback, self.cb as *const () as usize)
65            }
66        }
67
68        impl Clone for $callback_value {
69            fn clone(&self) -> Self {
70                $callback_value {
71                    cb: self.cb.clone(),
72                    ctx: self.ctx.clone(),
73                }
74            }
75        }
76
77        impl core::hash::Hash for $callback_value {
78            fn hash<H>(&self, state: &mut H)
79            where
80                H: ::core::hash::Hasher,
81            {
82                state.write_usize(self.cb as *const () as usize);
83            }
84        }
85
86        impl PartialEq for $callback_value {
87            fn eq(&self, rhs: &Self) -> bool {
88                self.cb as *const () as usize == rhs.cb as usize
89            }
90        }
91
92        impl PartialOrd for $callback_value {
93            fn partial_cmp(&self, other: &Self) -> Option<::core::cmp::Ordering> {
94                Some((self.cb as *const () as usize).cmp(&(other.cb as usize)))
95            }
96        }
97
98        impl Ord for $callback_value {
99            fn cmp(&self, other: &Self) -> ::core::cmp::Ordering {
100                (self.cb as *const () as usize).cmp(&(other.cb as usize))
101            }
102        }
103
104        impl Eq for $callback_value {}
105
106        /// Allow creating callback from a raw function pointer
107        /// Sets callable to None (for native Rust/C usage)
108        impl From<$callback_ty> for $callback_value {
109            fn from(cb: $callback_ty) -> $callback_value {
110                $callback_value {
111                    cb,
112                    ctx: azul_core::refany::OptionRefAny::None,
113                }
114            }
115        }
116
117        /// Allow creating widget callback from a generic Callback
118        /// This enables Python/FFI code to pass generic callbacks to widget methods
119        impl From<$crate::callbacks::Callback> for $callback_value {
120            // transmute target ($callback_value's cb fn-ptr type) varies per macro
121            // instantiation, so an explicit annotation can't be written generically here.
122            #[allow(clippy::missing_transmute_annotations, clippy::useless_transmute)]
123            fn from(cb: $crate::callbacks::Callback) -> $callback_value {
124                $callback_value {
125                    cb: unsafe { core::mem::transmute(cb.cb) },
126                    ctx: cb.ctx,
127                }
128            }
129        }
130    };
131}
132
133/// Button widget
134pub mod button;
135/// Checkbox widget
136pub mod check_box;
137/// Box displaying a color with a callback for value changes
138pub mod color_input;
139/// File input widget
140pub mod file_input;
141/// Label widget (centered text)
142pub mod label;
143/// Drop-down select widget
144pub mod drop_down;
145/// Frame container widget
146pub mod frame;
147/// List view widget
148pub mod list_view;
149/// Shared core for the video-ish widgets (camera/screencap/video): the
150/// `VideoFrame` type + the GL-texture `present_frame` writeback.
151///
152/// See
153/// `capture_common.rs`.
154pub mod capture_common;
155/// Camera-preview widget (P6) — a "dumb widget" owning a background capture
156/// thread + a GL-texture ImageRef; no camera logic in core.
157///
158/// Same RefAny-
159/// dataset + merge-callback design as the map widget. See `camera.rs`.
160pub mod camera;
161/// Screen-capture widget (P6) — identical "dumb widget" architecture to the
162/// camera widget, capturing a display/window instead.
163///
164/// See `screencap.rs`.
165pub mod screencap;
166/// Video-playback widget (P6) — same "dumb widget" architecture, decoding a
167/// video source (vk-video) into a GL texture.
168///
169/// See `video.rs`.
170pub mod video;
171/// Microphone-capture widget (P7) — same "dumb widget" architecture as the
172/// capture widgets, audio instead of video (no GL): a background thread feeds
173/// each `AudioFrame` to the user's `on_frame` hook.
174///
175/// See `microphone.rs`.
176pub mod microphone;
177/// Map widget — MVT tile + MapCSS → SVG → DOM (AzulMaps goal app, P3).
178///
179/// Cache lives in a dataset RefAny owned by a merge callback so it
180/// survives relayout. See `layout/src/widgets/map.rs` for the design.
181pub mod map;
182/// Software menu-bar widget (Linux fallback when there is no native global menu).
183///
184/// Renders a window's `Menu` as a horizontal bar; items open dropdowns via the
185/// unified `WindowPosition::RelativeToParentWindow` popup path.
186pub mod menubar;
187/// Node graph widget
188pub mod node_graph;
189/// Same as text input, but only allows numeric input
190pub mod number_input;
191/// Progress bar widget
192pub mod progressbar;
193/// Ribbon widget
194pub mod ribbon;
195/// Tab container widgets
196pub mod tabs;
197/// Single line text input widget
198pub mod text_input;
199/// Titlebar widget for custom window chrome
200pub mod titlebar;
201/// Tree view widget
202pub mod tree_view;
203/// Switch / toggle widget.
204///
205/// Boolean on/off with a sliding knob; see `switch.rs`.
206pub mod switch;
207/// Divider / separator rule widget (horizontal or vertical).
208///
209/// See `divider.rs`.
210pub mod divider;
211/// Card container widget.
212///
213/// Elevated/bordered content box (no title); see `card.rs`.
214pub mod card;
215/// Badge widget.
216///
217/// A small rounded count/status pill (stateless); see `badge.rs`.
218pub mod badge;
219/// Slider / range widget.
220///
221/// Draggable thumb on a track → numeric value; see `slider.rs`.
222pub mod slider;
223/// Segmented control widget.
224///
225/// Joined row of mutually-exclusive buttons; see `segmented.rs`.
226pub mod segmented;
227/// Radio-group widget.
228///
229/// Vertical/horizontal group of mutually-exclusive options (exactly one selected) with a circular indicator; see `radio_group.rs`.
230pub mod radio_group;
231/// Tooltip widget.
232///
233/// Shows a small text popup near an anchor on hover; see `tooltip.rs`.
234pub mod tooltip;
235/// Multi-line text input (text area) widget.
236///
237/// See `text_area.rs`.
238pub mod text_area;
239/// Alert / banner widget.
240///
241/// A coloured inline message box with an optional dismissible close button; see `alert.rs`.
242pub mod alert;
243/// Accordion / expander widget.
244///
245/// One or more collapsible titled sections; see `accordion.rs`.
246pub mod accordion;
247/// Avatar widget.
248///
249/// A circular image/initials badge (stateless); see `avatar.rs`.
250pub mod avatar;
251/// Chip / tag widget.
252///
253/// A compact rounded pill with a label + optional removable "x" (stateful when removable, mirrors alert's dismiss); see `chip.rs`.
254pub mod chip;
255/// Spinner / activity widget.
256///
257/// A static indeterminate busy ring (stateless; no animation — see the file's PARTIAL/TODO2 note); see `spinner.rs`.
258pub mod spinner;
259/// Popover widget.
260///
261/// A click-triggered floating panel holding arbitrary content, anchored to a `Dom` (the click-toggled sibling of tooltip); see `popover.rs`.
262pub mod popover;
263/// Combobox widget.
264///
265/// An editable text field with a click-toggled drop-down list of options (drop_down's select + text_input's editable field); see `combobox.rs`.
266pub mod combobox;
267/// Modal / dialog widget.
268///
269/// An in-app overlay dialog (backdrop + centred panel + arbitrary content), shown/hidden via state toggle; see `modal.rs`.
270pub mod modal;
271/// Toast / snackbar widget.
272///
273/// A transient floating notification banner pinned to a corner, manually dismissed via "x" (auto-timeout needs a host timer — see the file's TODO2); a near-clone of `alert.rs` positioned as an overlay; see `toast.rs`.
274pub mod toast;
275/// Breadcrumb widget.
276///
277/// A horizontal trail of clickable crumb links separated by "/", ending in the current (non-clickable) page; see `breadcrumb.rs`.
278pub mod breadcrumb;
279/// Pagination widget.
280///
281/// A `Prev` / page-numbers / `Next` page navigator with an active-page restyle (segmented-style); see `pagination.rs`.
282pub mod pagination;
283/// Stepper / wizard widget.
284///
285/// A horizontal numbered-step progress indicator with connector lines and an accent/muted restyle on step change (segmented-style + progressbar-style filled connector); see `stepper.rs`.
286pub mod stepper;
287/// Split-pane / splitter widget.
288///
289/// A two-pane (horizontal/vertical) container with a draggable divider that live-resizes the panes via `set_css_property` (the frame two-box layout + the map/slider pointer-drag state machine); see `split_pane.rs`.
290pub mod split_pane;
291/// Time picker widget.
292///
293/// Two clamped numeric up/down spinners (hour + minute) side by side with an optional AM/PM toggle for 12-hour mode (the number_input clamp/retext path + segmented's clickable-cell navigation); see `time_picker.rs`.
294pub mod time_picker;
295/// Calendar date picker widget.
296///
297/// A month header (‹ / `Month YYYY` / ›) above a weekday-labelled 7-column day grid computed from real calendar math; clicking a day selects + restyles it (segmented-style), and the per-cell day number is carried drop_down-style. Month nav fires on_change but cannot rebuild the grid in-widget (prominent module TODO2); see `date_picker.rs`.
298pub mod date_picker;
299// /// Spreadsheet (virtualized view) widget
300// pub mod spreadsheet;