zng/
lib.rs

1#![expect(clippy::needless_doctest_main)]
2#![doc(html_favicon_url = "https://zng-ui.github.io/res/zng-logo-icon.png")]
3#![doc(html_logo_url = "https://zng-ui.github.io/res/zng-logo.png")]
4
5//! Zng is a cross-platform GUI framework, it provides ready made highly customizable widgets, responsive layout,
6//! live data binding, easy localization, automatic focus navigation and accessibility, async and multi-threaded tasks, robust
7//! multi-process architecture and more.
8//!
9//! Zng is pronounced "zing", or as an initialism: ZNG (Z Nesting Graphics).
10//!
11//! Every component of the framework can be extended, you can create new widgets or add properties to existing ones,
12//! at a lower level you can introduce new events and services, seamless integrating custom hardware.
13//!
14//! # Usage
15//!
16//! First add this to your `Cargo.toml`:
17//!
18//! ```toml
19//! [dependencies]
20//! zng = { version = "0.19.2", features = ["view_prebuilt"] }
21//! ```
22//!
23//! Then create your first app:
24//!
25//! ```no_run
26//! use zng::prelude::*;
27//!
28//! fn main() {
29//!     zng::env::init!();
30//!     app();
31//! }
32//!
33//! fn app() {
34//!     APP.defaults().run_window(async {
35//!         Window! {
36//!             child_align = Align::CENTER;
37//!             child = {
38//!                 let size = var(28i32);
39//!                 Button! {
40//!                     child = Text! {
41//!                         txt = "Hello World!";
42//!
43//!                         #[easing(200.ms())]
44//!                         font_size = size.map_into();
45//!                     };
46//!                     on_click = hn!(|_| {
47//!                         let next = size.get() + 10;
48//!                         size.set(if next > 80 { 28 } else { next });
49//!                     });
50//!                 }
51//!             };
52//!         }
53//!     })
54//! }
55//! ```
56//!
57//! You can also use a [prebuild view](app#prebuild) and run in the [same process](app#same-process), see [`app`] for more details.
58//!
59//! # Widgets & Properties
60//!
61//! The high-level building blocks of UI.
62//!
63//! ```
64//! use zng::prelude::*;
65//!
66//! # fn example() {
67//! # let _ =
68//! Button! {
69//!     child = Text!("Green?");
70//!     widget::background_color = colors::GREEN;
71//!     on_click = hn!(|_| println!("SUPER GREEN!"));
72//! }
73//! # ; }
74//! ```
75//!
76//! In the example above [`Button!`] and [`Text!`] are widgets and `child`, [`background_color`] and [`on_click`] are properties.
77//! Widgets are mostly an aggregation of properties that define an specific function and presentation, most properties are standalone
78//! implementations of an specific behavior or appearance, in the example only `child` is implemented by the button widget, the
79//! other two properties can be set in any widget.
80//!
81//! Each widget is a dual macro and `struct` of the same name, in the documentation only the `struct` is visible, when
82//! an struct represents a widget it is tagged with <strong><code>W</code></strong>. Each properties is declared as a function,
83//! in the documentation property functions are tagged with <strong><code>P</code></strong>.
84//!
85//! Widget instances can be of any type, usually they are an opaque [`UiNode`] or a type that is [`IntoUiNode`],
86//! some special widgets have non node instance type, the [`Window!`] widget for example has the instance type [`WindowRoot`].
87//! Property instances are always of type [`UiNode`], each property function takes an `impl IntoUiNode` input plus one or more value
88//! inputs and returns an `UiNode` output that wraps the input node adding the property behavior, the widgets take care of this
89//! node chaining nesting each property instance in the proper order, internally every widget instance is a tree of nested node instances.
90//!
91//! Widgets and properties are very versatile and extendable, widget docs will promote properties that are explicitly associated
92//! with the widget type, but that is only a starting point, many other standalone properties can be set in any widget.
93//!
94//! ```
95//! use zng::prelude::*;
96//!
97//! # let _app = APP.minimal();
98//! # let _ =
99//! Wgt! {
100//!     layout::align = layout::Align::CENTER;
101//!     layout::size = 50;
102//!
103//!     #[easing(200.ms())]
104//!     widget::background_color = colors::RED;
105//!
106//!     when *#gesture::is_hovered {
107//!         widget::background_color = colors::GREEN;
108//!     }
109//! }
110//! # ;
111//! ```
112//!
113//! In the example above an [`Wgt!`] is completely defined by stand-alone properties, [`align`] and [`size`] define
114//! the layout bounds of the widget, [`background_color`] fills the bounds with color and [`is_hovered`] reacts to pointer interaction.
115//!
116//! The example also introduces [`when`] blocks, [state properties] and the [`easing`] property attribute. State properties
117//! compute an state from the widget, this state can be used to change the value of other properties. When blocks are a powerful
118//! feature of widgets, they declare conditional property values. The easing attribute can be set in any property with transitionable
119//! values to smoothly animate between changes.
120//!
121//! The [`widget`](mod@widget) module documentation provides an in-depth explanation of how widgets and properties work.
122//!
123//! [`Button!`]: struct@button::Button
124//! [`Window!`]: struct@window::Window
125//! [`Text!`]: struct@text::Text
126//! [`Wgt!`]: struct@widget::Wgt
127//! [`background_color`]: fn@widget::background_color
128//! [`on_click`]: fn@gesture::on_click
129//! [`is_hovered`]: fn@gesture::is_hovered
130//! [`align`]: fn@layout::align
131//! [`size`]: fn@layout::size
132//! [`when`]: widget#when
133//! [state properties]: widget#state-properties
134//! [`easing`]: widget::easing
135//! [`UiNode`]: widget::node::UiNode
136//! [`IntoUiNode`]: widget::node::IntoUiNode
137//! [`WindowRoot`]: window::WindowRoot
138//!
139//! # Variables
140//!
141//! Observable values that glue most of the UI together.
142//!
143//! ```
144//! use zng::prelude::*;
145//!
146//! # let _app = APP.minimal();
147//! let btn_pressed = var(false);
148//!
149//! # let _ =
150//! Stack! {
151//!     direction = StackDirection::top_to_bottom();
152//!     spacing = 10;
153//!     children = ui_vec![
154//!         Button! {
155//!             child = Text! {
156//!                 txt = "Press Me!";
157//!             };
158//!             gesture::is_pressed = btn_pressed.clone();
159//!         },
160//!         Text! {
161//!             txt = btn_pressed.map(|&b| if b { "Button is pressed!" } else { "Button is not pressed." }.into());
162//!         }
163//!     ];
164//! }
165//! # ;
166//! ```
167//!
168//! The example above binds the pressed state of a widget with the text content of another using a [`var`]. Variables
169//! are the most common property input kind, in the example `direction`, `spacing`, `is_pressed` and `txt` all accept
170//! an [`IntoVar<T>`] input that gets converted into a [`Var<T>`] when the property is instantiated.
171//!
172//! There are multiple variable kinds, they can be a simple constant value, a shared observable and modifiable value or a
173//! contextual value. Variables can also depend on other variables automatically updating when input variables update.
174//!
175//! ```
176//! use zng::prelude::*;
177//!
178//! # let _app = APP.minimal();
179//! fn ui(txt: impl IntoVar<Txt>) -> UiNode {
180//!     Text!(txt)
181//! }
182//!
183//! ui("const value");
184//!
185//! let txt = var(Txt::from("dynamic value"));
186//! ui(txt.clone());
187//! txt.set("change applied next update");
188//!
189//! let show_txt = var(true);
190//! ui(expr_var!(if *#{show_txt} { #{txt}.clone() } else { Txt::from("") }));
191//!
192//! ui(text::FONT_COLOR_VAR.map(|s| formatx!("font color is {s}")));
193//! ```
194//!
195//! In the example a [`var`] clone is shared with the UI and a new value is scheduled for the next app update. Variable
196//! updates are batched, during each app update pass every property can observe the current value and schedule modifications to
197//! the value, the modifications are only applied after, potentially causing a new update pass if any value actually changed, see
198//! [var updates] in the [var module] documentation for more details.
199//!
200//! The example also demonstrates the [`expr_var!`], a read-only observable variable that interpolates other variables, the
201//! value of this variable automatically update when any of the interpolated variables update.
202//!
203//! And finally the example demonstrates a context var, `FONT_COLOR_VAR`. Context variables get their value from the
204//! *environment* where they are used, the UI in the example can show a different text depending on where it is placed.
205//! Context variables are usually encapsulated by properties strongly associated with a widget, most of [`Text!`] properties just
206//! set a context var that affects all text instances in the widget they are placed and descendant widgets.
207//!
208//! There are other useful variable kinds, see the [var module] module documentation for more details.
209//!
210//! [`var`]: var::var
211//! [`expr_var!`]: var::expr_var
212//! [var module]: crate::var
213//! [`IntoVar<T>`]: var::IntoVar
214//! [`Var<T>`]: var::Var
215//!
216//! # Context
217//!
218//! Context or *ambient* values set on parent widgets affecting descendant widgets.
219//!
220//! ```
221//! use zng::prelude::*;
222//!
223//! # let _app = APP.minimal();
224//! # let _ =
225//! Stack! {
226//!     direction = StackDirection::top_to_bottom();
227//!     spacing = 10;
228//!
229//!     text::font_color = colors::RED;
230//!
231//!     children = ui_vec![
232//!         Button! {
233//!             child = Text!("Text 1");
234//!         },
235//!         Button! {
236//!             child = Text!("Text 2");
237//!         },
238//!         Button! {
239//!             child = Text!("Text 3");
240//!             text::font_color = colors::GREEN;
241//!         },
242//!     ];
243//! }
244//! # ;
245//! ```
246//!
247//! In the example above "Text 1" and "Text 2" are rendered in red and "Text 3" is rendered in green. The context
248//! of a widget is important, `text::font_color` sets text color in the `Stack!` widget and all descendant widgets,
249//! the color is overridden in the third `Button!` for the context of that button and descendants, the `Text!`
250//! widget has a different appearance just by being in a different context.
251//!
252//! Note that the text widget can also set the color directly, in the following example the "Text 4" is blue, this
253//! value is still contextual, but texts are usually leaf widgets so only the text is affected.
254//!
255//! ```
256//! # use zng::prelude::*;
257//! # let _app = APP.minimal();
258//! # let _ =
259//! Text! {
260//!     txt = "Text 4";
261//!     font_color = colors::BLUE;
262//! }
263//! # ;
264//! ```
265//!
266//! In the example above a context variable defines the text color, but not just variables are contextual, layout
267//! units and widget services are also contextual, widget implementers may declare custom contextual values too,
268//! see [context local] in the app module documentation for more details.
269//!
270//! [context local]: app#context-local
271//!  
272//! # Services
273//!
274//! App or contextual value and function providers.
275//!
276//! ```
277//! use zng::clipboard::CLIPBOARD;
278//! use zng::prelude::*;
279//!
280//! # let _app = APP.minimal();
281//! # let _ =
282//! Stack! {
283//!     direction = StackDirection::top_to_bottom();
284//!     spacing = 10;
285//!
286//!     children = {
287//!         let txt = var(Txt::from(""));
288//!         let txt_is_err = var(false);
289//!         ui_vec![
290//!             Button! {
291//!                 child = Text!("Paste");
292//!                 on_click = hn!(txt, txt_is_err, |_| {
293//!                     match CLIPBOARD.text() {
294//!                         Ok(p) => {
295//!                             if let Some(t) = p {
296//!                                 txt.set(t);
297//!                                 txt_is_err.set(false);
298//!                             }
299//!                         }
300//!                         Err(e) => {
301//!                             let t = WIDGET.trace_path();
302//!                             txt.set(formatx!("error in {t}: {e}"));
303//!                             txt_is_err.set(true);
304//!                         }
305//!                     }
306//!                 });
307//!             },
308//!             Text! {
309//!                 txt;
310//!                 when *#{txt_is_err} {
311//!                     font_color = colors::RED;
312//!                 }
313//!             }
314//!         ]
315//!     };
316//! }
317//! # ;
318//! ```
319//!
320//! The example above uses two services, `CLIPBOARD` and `WIDGET`. Services are represented
321//! by an unit struct named like a static item, service functionality is available as methods on
322//! this unit struct. Services are contextual, `CLIPBOARD` exists on the app context, it can only operate
323//! in app threads, `WIDGET` represents the current widget and can only be used inside a widget.
324//!
325//! The default app provides multiple services, some common ones are [`APP`], [`WINDOWS`], [`WINDOW`], [`WIDGET`],
326//! [`FOCUS`], [`POPUP`], [`DATA`] and more. Services all follow the same pattern, they are a unit struct named like a static
327//! item, if you see such a type it is a service.
328//!
329//! Most services are synchronized with the update cycle. If the service provides a value that value does not change mid-update, all
330//! widgets read the same value in the same update. If the service run some operation it takes requests to run the operation, the
331//! requests are only applied after the current UI update. This is even true for the [`INSTANT`] service that provides the current
332//! time.
333//!
334//! [`WINDOWS`]: window::WINDOWS
335//! [`WINDOW`]: window::WINDOW
336//! [`WIDGET`]: widget::WIDGET
337//! [`FOCUS`]: focus::FOCUS
338//! [`POPUP`]: popup::POPUP
339//! [`DATA`]: data_context::DATA
340//! [`INSTANT`]: app::INSTANT
341//!
342//! # Events & Commands
343//!
344//! Targeted messages send from the system to widgets or from one widget to another.
345//!
346//! ```no_run
347//! use zng::{
348//!     clipboard::{CLIPBOARD, PASTE_CMD, on_paste},
349//!     prelude::*,
350//! };
351//!
352//! APP.defaults().run_window(async {
353//!     let cmd = PASTE_CMD.scoped(WINDOW.id());
354//!     let paste_btn = Button! {
355//!         child = Text!(cmd.name());
356//!         widget::enabled = cmd.is_enabled();
357//!         widget::visibility = cmd.has_handlers().map_into();
358//!         tooltip = Tip!(Text!(cmd.name_with_shortcut()));
359//!         on_click = hn!(|args: &gesture::ClickArgs| {
360//!             args.propagation().stop();
361//!             cmd.notify();
362//!         });
363//!     };
364//!
365//!     let pasted_txt = var(Txt::from(""));
366//!
367//!     Window! {
368//!         on_paste = hn!(pasted_txt, |_| {
369//!             if let Some(t) = CLIPBOARD.text().ok().flatten() {
370//!                 pasted_txt.set(t);
371//!             }
372//!         });
373//!
374//!         child = Stack! {
375//!             children_align = Align::CENTER;
376//!             direction = StackDirection::top_to_bottom();
377//!             spacing = 20;
378//!             children = ui_vec![paste_btn, Text!(pasted_txt)];
379//!         };
380//!     }
381//! });
382//! ```
383//!
384//! The example above uses events and command events. Events are represented by a static instance
385//! of [`Event<A>`] with name suffix `_EVENT`. Events are usually abstracted by
386//! one or more event property, event properties are named with prefix `on_` and accept one input of
387//! [`Handler<A>`]. Commands are specialized events represented by a static instance of [`Command`]
388//! with name suffix `_CMD`. Every command is also an `Event<CommandArgs>`, unlike other events it is common
389//! for the command instance to be used directly.
390//!
391//! The `on_click` property handles the `CLICK_EVENT` when the click was done with the primary button and targets
392//! the widget or a descendant of the widget. The [`hn!`] is a widget handler that synchronously handles the event.
393//! See the [`event`] module documentation for details about event propagation, targeting and route. And see
394//! [`handler`] module for other handler types, including [`async_hn!`] that enables async `.await` in any event property.
395//!
396//! The example above defines a button for the `PASTE_CMD` command scoped on the window. Scoped commands are different
397//! instances of [`Command`], the command scope can be a window or widget ID, the scope is the target of the command and
398//! the context of the command metadata. In the example the button is only visible if the command scope (window) has
399//! a paste handler, the button is only enabled it at least one paste handler on the scope is enabled, the button also
400//! displays the command name and shortcut metadata, and finally on click the button notifies a command event that is
401//! received in `on_click`.
402//!
403//! Commands enable separation of concerns, the button in the example does not need to know what the window will do on paste,
404//! in fact the button does not even need to know what command it is requesting. Widgets can also be controlled using commands,
405//! the `Scroll!` widget for example can be controlled from anywhere else in the app using the [`scroll::cmd`] commands. See
406//! the [commands](event#commands) section in the event module documentation for more details.
407//!
408//! [`Event<A>`]: event::Event
409//! [`Command`]: event::Command
410//! [`Handler<A>`]: handler::Handler
411//! [`hn!`]: handler::hn!
412//! [`async_hn!`]: handler::async_hn!
413//!
414//! # Layout
415//!
416//! Contextual properties and constraints that affect how a widget is sized and placed on the screen.
417//!
418//! ```
419//! use zng::prelude::*;
420//! # let _app = APP.minimal();
421//!
422//! # let _ =
423//! Container! {
424//!     layout::size = (400, 350);
425//!     widget::background_color = colors::BLUE.darken(70.pct());
426//!
427//!     child = Button! {
428//!         child = Text!("Text");
429//!
430//!         layout::align = layout::Align::CENTER;
431//!         layout::size = (60.pct(), 70.pct());
432//!     };
433//! }
434//! # ;
435//! ```
436//!
437//! In the example above the container widget sets an exact size using `layout::size` with exact units, the
438//! button widget sets a relative size using percentage units and positions itself in the container using `layout::align`.
439//! All the layout properties are stand-alone, in the example only the text widget implements layout directly. Layout
440//! properties modify the layout context by setting constraints and defining units, this context is available for all
441//! properties that need it during layout, see the [`layout`] module documentation for more details.
442//!
443//! # Error Handling
444//!
445//! Recoverable errors handled internally are logged using [`tracing`], in debug builds tracing events (info, warn and error)
446//! are printed using [`app::print_tracing`] by default if no tracing subscriber is set before the app starts building.
447//!
448//! Components always attempt to recover from errors when possible, or at least attempt to contain errors and turn then into
449//! a displayable message. The general idea is to at least give the end user a chance to workaround the issue.
450//!
451//! Components do not generally attempt to recover from panics, with some notable exceptions. The view-process will attempt to respawn
452//! if it crashes, because all state is safe in the app-process all windows and frames can be recreated, this lets the app survive
453//! some catastrophic video driver errors, like a forced disconnect caused by a driver update. The [`task::spawn`] and related
454//! fire-and-forget task runners will also just log the panic as an error.
455//!
456//! The [`zng::app::crash_handler`] is enabled by default, it collect panic backtraces, crash minidumps, show a crash dialog to the user
457//! and restart the app. During development a debug crash dialog is provided, it shows the stdout/stderr, panics stacktrace and
458//! minidumps collected if any non-panic fatal error happens. Note that the crash handler **stops debuggers from working**, see the
459//! [Debugger section] of the crash-handler docs on how to automatically disable the crash handler for debugger runs.
460//!
461//! [`tracing`]: https://docs.rs/tracing
462//! [Debugger section]: zng::app::crash_handler#debugger
463//!
464//! # In-Depth Documentation
465//!
466//! This crate level documentation only gives an overview required to start making apps using existing widgets and properties.
467//! All top-level modules in this crate contains in-depth documentation about their subject, of particular importance the
468//! [`app`], [`widget`](mod@widget), [`layout`] and [`render`] modules should give you a solid understanding of how everything works.
469//!
470//! ## Cargo Features
471//!
472//! See the [Cargo Features] section in the crate README for Cargo features documentation.
473//!
474//! [Cargo Features]: https://github.com/zng-ui/zng/tree/main/crates/zng#cargo-features
475
476#![warn(unused_extern_crates)]
477#![warn(missing_docs)]
478
479// manually expanded enable_widget_macros to avoid error running doc tests:
480// macro-expanded `extern crate` items cannot shadow names passed with `--extern`
481#[doc(hidden)]
482#[allow(unused_extern_crates)]
483extern crate self as zng;
484#[doc(hidden)]
485pub use zng_app::__proc_macro_util;
486
487pub use zng_clone_move::{async_clmv, async_clmv_fn, async_clmv_fn_once, clmv};
488
489pub mod access;
490pub mod ansi_text;
491pub mod app;
492pub mod button;
493pub mod checkerboard;
494pub mod clipboard;
495pub mod color;
496pub mod config;
497pub mod container;
498pub mod data_context;
499pub mod data_view;
500pub mod dialog;
501pub mod drag_drop;
502pub mod env;
503pub mod event;
504pub mod focus;
505pub mod font;
506pub mod fs_watcher;
507pub mod gesture;
508pub mod grid;
509pub mod handler;
510pub mod hot_reload;
511pub mod icon;
512pub mod image;
513pub mod keyboard;
514pub mod l10n;
515pub mod label;
516pub mod layer;
517pub mod layout;
518pub mod markdown;
519pub mod menu;
520pub mod mouse;
521pub mod panel;
522pub mod pointer_capture;
523pub mod popup;
524pub mod progress;
525pub mod render;
526pub mod rule_line;
527pub mod scroll;
528pub mod selectable;
529pub mod shortcut_text;
530pub mod slider;
531pub mod stack;
532pub mod state_map;
533pub mod style;
534pub mod task;
535pub mod text;
536pub mod text_input;
537pub mod third_party;
538pub mod timer;
539pub mod tip;
540pub mod toggle;
541pub mod touch;
542pub mod undo;
543pub mod update;
544pub mod var;
545pub mod view_process;
546pub mod widget;
547pub mod window;
548pub mod wrap;
549
550/// Start and manage an app process.
551pub struct APP;
552impl std::ops::Deref for APP {
553    type Target = zng_app::APP;
554
555    fn deref(&self) -> &Self::Target {
556        &zng_app::APP
557    }
558}
559
560/// Types for general app development.
561///
562/// See also [`prelude_wgt`] for declaring new widgets and properties.
563pub mod prelude {
564    #[doc(no_inline)]
565    pub use crate::__prelude::*;
566}
567mod __prelude {
568    pub use crate::APP;
569    pub use crate::{color, gesture, keyboard, layout, mouse, task, timer, touch, widget};
570
571    pub use zng_task::rayon::prelude::{
572        FromParallelIterator as _, IndexedParallelIterator as _, IntoParallelIterator as _, IntoParallelRefIterator as _,
573        IntoParallelRefMutIterator as _, ParallelBridge as _, ParallelDrainFull as _, ParallelDrainRange as _, ParallelExtend as _,
574        ParallelIterator as _, ParallelSlice as _, ParallelSliceMut as _, ParallelString as _,
575    };
576
577    pub use zng_task::io::{
578        AsyncBufRead as _, AsyncRead as _, AsyncReadExt as _, AsyncSeek as _, AsyncSeekExt as _, AsyncWrite as _, AsyncWriteExt as _,
579    };
580
581    pub use zng_app::{
582        INSTANT,
583        event::{AnyEventArgs as _, CommandInfoExt as _, CommandNameExt as _, CommandParam, EventArgs as _},
584        handler::{HandlerExt as _, async_hn, async_hn_once, hn, hn_once},
585        shortcut::{CommandShortcutExt as _, shortcut},
586        widget::{
587            AnyVarSubscribe as _, VarLayout as _, VarSubscribe as _, WIDGET, WidgetId, easing,
588            node::{IntoUiNode, UiNode, UiVec, ui_vec},
589        },
590        window::{WINDOW, WindowId},
591    };
592
593    pub use zng_app::widget::inspector::WidgetInfoInspectorExt as _;
594
595    pub use zng_var::{
596        IntoValue, IntoVar, Var, VarValue, const_var, context_var, expr_var, flat_expr_var, merge_var, var, var_from, var_getter,
597        var_state, when_var,
598    };
599
600    pub use crate::var::animation::easing;
601
602    pub use zng_layout::unit::{
603        Align, AngleUnits as _, ByteUnits as _, DipToPx as _, FactorUnits as _, Layout1d as _, Layout2d as _, Length, LengthUnits as _,
604        LineFromTuplesBuilder as _, PxDensityUnits as _, PxToDip as _, RectFromTuplesBuilder as _, TimeUnits as _,
605    };
606
607    pub use zng_txt::{ToTxt as _, Txt, formatx};
608
609    pub use zng_clone_move::{async_clmv, async_clmv_fn, async_clmv_fn_once, clmv};
610
611    pub use zng_color::{LightDarkVarExt as _, MixAdjust as _, colors, hex, hsl, hsla, hsv, hsva, light_dark, rgb, rgba, web_colors};
612
613    #[cfg(feature = "clipboard")]
614    pub use zng_ext_clipboard::CLIPBOARD;
615
616    #[cfg(feature = "config")]
617    pub use zng_ext_config::CONFIG;
618
619    pub use zng_ext_font::{FontStretch, FontStyle, FontWeight};
620
621    #[cfg(feature = "image")]
622    pub use zng_ext_image::ImageSource;
623
624    #[cfg(feature = "image")]
625    pub use zng_wgt_image::Image;
626
627    pub use zng_ext_input::{
628        focus::{FOCUS, WidgetInfoFocusExt as _, cmd::CommandFocusExt as _, iter::IterFocusableExt as _},
629        gesture::{CommandShortcutMatchesExt as _, HeadlessAppGestureExt as _},
630        keyboard::HeadlessAppKeyboardExt as _,
631        mouse::WidgetInfoMouseExt as _,
632    };
633
634    pub use zng_ext_l10n::{L10N, l10n, lang};
635
636    pub use zng_wgt_text::lang;
637
638    #[cfg(feature = "undo")]
639    pub use zng_ext_undo::{CommandUndoExt as _, REDO_CMD, UNDO, UNDO_CMD};
640
641    #[cfg(feature = "window")]
642    pub use zng_ext_window::{
643        AppRunWindowExt as _, HeadlessAppWindowExt as _, WINDOW_Ext as _, WINDOWS, WidgetInfoImeArea as _, WindowCloseRequestedArgs,
644        WindowIcon,
645    };
646    #[cfg(feature = "window")]
647    pub use zng_wgt_window::WINDOWS_Ext as _;
648
649    pub use zng_wgt::{CommandIconExt as _, ICONS, Wgt};
650
651    pub use crate::text;
652    pub use zng_wgt_text::Text;
653
654    #[cfg(feature = "text_input")]
655    pub use zng_wgt_text_input::{TextInput, selectable::SelectableText};
656
657    #[cfg(feature = "window")]
658    pub use crate::window;
659    #[cfg(feature = "window")]
660    pub use zng_wgt_window::Window;
661
662    pub use zng_wgt_container::Container;
663
664    #[cfg(feature = "button")]
665    pub use zng_wgt_button::Button;
666
667    #[cfg(feature = "data_context")]
668    pub use zng_wgt_data::{DATA, data};
669
670    #[cfg(feature = "grid")]
671    pub use crate::grid;
672    #[cfg(feature = "grid")]
673    pub use zng_wgt_grid::Grid;
674
675    pub use crate::layer;
676    pub use zng_wgt_layer::{AnchorMode, LAYERS, LayerIndex};
677
678    pub use crate::popup;
679    pub use zng_wgt_layer::popup::POPUP;
680
681    #[cfg(feature = "menu")]
682    pub use crate::menu;
683    #[cfg(feature = "menu")]
684    pub use zng_wgt_menu::{
685        Menu,
686        context::{ContextMenu, context_menu, context_menu_fn},
687        sub::SubMenu,
688    };
689
690    #[cfg(feature = "rule_line")]
691    pub use zng_wgt_rule_line::{hr::Hr, vr::Vr};
692
693    #[cfg(feature = "scroll")]
694    pub use zng_wgt_scroll::{SCROLL, Scroll};
695
696    #[cfg(feature = "toggle")]
697    pub use crate::toggle;
698    #[cfg(feature = "toggle")]
699    pub use zng_wgt_toggle::Toggle;
700
701    #[cfg(feature = "tooltip")]
702    pub use crate::tip;
703    #[cfg(feature = "tooltip")]
704    pub use zng_wgt_tooltip::{Tip, tooltip, tooltip_fn};
705
706    pub use zng_wgt::{
707        WidgetFn,
708        node::{VarPresent as _, VarPresentData as _, VarPresentList as _, VarPresentListFromIter as _, VarPresentOpt as _},
709        wgt_fn,
710    };
711
712    pub use zng_wgt_style::{Style, style_fn};
713
714    #[cfg(feature = "stack")]
715    pub use zng_wgt_stack::{Stack, StackDirection};
716
717    #[cfg(feature = "wrap")]
718    pub use zng_wgt_wrap::Wrap;
719
720    #[cfg(feature = "data_view")]
721    pub use zng_wgt_data_view::{DataView, DataViewArgs};
722
723    #[cfg(feature = "settings_editor")]
724    pub use zng_wgt_settings::SettingBuilderEditorExt as _;
725
726    #[cfg(feature = "dialog")]
727    pub use crate::dialog;
728    #[cfg(feature = "dialog")]
729    pub use zng_wgt_dialog::DIALOG;
730
731    #[cfg(all(feature = "fs_watcher", feature = "image"))]
732    pub use crate::fs_watcher::IMAGES_Ext as _;
733}
734
735/// Prelude for declaring new properties and widgets.
736///
737/// This prelude can be imported over [`prelude`].
738///
739/// # Examples
740///
741/// ```
742/// # fn main() { }
743/// use zng::{prelude::*, prelude_wgt::*};
744///
745/// /// A button with only text child.
746/// #[widget($crate::TextButton)]
747/// pub struct TextButton(Button);
748///
749/// /// Button text.
750/// #[property(CHILD, widget_impl(TextButton))]
751/// pub fn txt(wgt: &mut WidgetBuilding, txt: impl IntoVar<Txt>) {
752///     let _ = txt;
753///     wgt.expect_property_capture();
754/// }
755///
756/// impl TextButton {
757///     fn widget_intrinsic(&mut self) {
758///         self.widget_builder().push_build_action(|b| {
759///             let txt = b
760///                 .capture_var::<Txt>(property_id!(Self::txt))
761///                 .unwrap_or_else(|| const_var(Txt::from("")));
762///             b.set_child(Text!(txt));
763///         });
764///     }
765/// }
766/// ```
767pub mod prelude_wgt {
768    #[doc(no_inline)]
769    pub use crate::__prelude_wgt::*;
770}
771mod __prelude_wgt {
772    pub use zng_app::{
773        DInstant, Deadline, INSTANT,
774        event::{
775            AnyEventArgs as _, Command, CommandHandle, CommandInfoExt as _, CommandNameExt as _, CommandParam, Event, EventArgs as _,
776            EventHandle, EventHandles, EventPropagationHandle, command, event, event_args,
777        },
778        handler::{Handler, HandlerExt as _, async_hn, async_hn_once, hn, hn_once},
779        render::{FrameBuilder, FrameUpdate, FrameValue, FrameValueKey, FrameValueUpdate, SpatialFrameId, TransformStyle},
780        shortcut::{CommandShortcutExt as _, Shortcut, ShortcutFilter, Shortcuts, shortcut},
781        timer::{DeadlineHandle, DeadlineVar, TIMERS, TimerHandle, TimerVar},
782        update::{EventUpdate, UPDATES, UpdateDeliveryList, UpdateOp, WidgetUpdates},
783        widget::{
784            AnyVarSubscribe as _, VarLayout as _, VarSubscribe as _, WIDGET, WidgetId, WidgetUpdateMode,
785            base::{WidgetBase, WidgetImpl},
786            border::{BORDER, BorderSides, BorderStyle, CornerRadius, CornerRadiusFit, LineOrientation, LineStyle},
787            builder::{NestGroup, WidgetBuilder, WidgetBuilding, property_id},
788            easing,
789            info::{
790                InteractionPath, Interactivity, Visibility, WidgetBorderInfo, WidgetBoundsInfo, WidgetInfo, WidgetInfoBuilder,
791                WidgetLayout, WidgetMeasure, WidgetPath,
792            },
793            node::{
794                ArcNode, ChainList, EditableUiVec, EditableUiVecRef, FillUiNode, IntoUiNode, PanelList, SORTING_LIST, SortingList, UiNode,
795                UiNodeImpl, UiNodeListObserver, UiNodeOp, UiVec, ZIndex, match_node, match_node_leaf, match_widget, ui_vec,
796            },
797            property, widget, widget_impl, widget_mixin, widget_set,
798        },
799        window::{MonitorId, WINDOW, WindowId},
800    };
801
802    pub use zng_var::{
803        ContextVar, IntoValue, IntoVar, ResponderVar, ResponseVar, Var, VarCapability, VarHandle, VarHandles, VarValue, const_var,
804        context_var, expr_var, flat_expr_var, impl_from_and_into_var, merge_var, response_done_var, response_var, var, var_getter,
805        var_state, when_var,
806    };
807
808    pub use zng_layout::{
809        context::{DIRECTION_VAR, LAYOUT, LayoutDirection, LayoutMetrics},
810        unit::{
811            Align, AngleDegree, AngleGradian, AngleRadian, AngleUnits as _, ByteUnits as _, Dip, DipBox, DipPoint, DipRect, DipSideOffsets,
812            DipSize, DipToPx as _, DipVector, Factor, Factor2d, FactorPercent, FactorSideOffsets, FactorUnits as _, Layout1d as _,
813            Layout2d as _, LayoutAxis, Length, LengthUnits as _, Line, LineFromTuplesBuilder as _, Point, Px, PxBox, PxConstraints,
814            PxConstraints2d, PxCornerRadius, PxDensityUnits as _, PxLine, PxPoint, PxRect, PxSideOffsets, PxSize, PxToDip as _,
815            PxTransform, PxVector, Rect, RectFromTuplesBuilder as _, SideOffsets, Size, TimeUnits as _, Transform, Vector,
816        },
817    };
818
819    pub use zng_txt::{ToTxt as _, Txt, formatx};
820
821    pub use zng_clone_move::{async_clmv, async_clmv_fn, async_clmv_fn_once, clmv};
822
823    pub use crate::task;
824
825    pub use zng_app_context::{CaptureFilter, ContextLocal, ContextValueSet, LocalContext, RunOnDrop, app_local, context_local};
826
827    pub use crate::state_map;
828    pub use zng_state_map::{OwnedStateMap, StateId, StateMapMut, StateMapRef, static_id};
829
830    pub use zng_wgt::prelude::{IdEntry, IdMap, IdSet};
831
832    pub use zng_wgt::{WidgetFn, wgt_fn};
833
834    pub use zng_color::{
835        ColorScheme, Hsla, Hsva, LightDark, MixAdjust as _, MixBlendMode, Rgba, colors, gradient, hex, hsl, hsla, hsv, hsva, light_dark,
836        rgb, rgba, web_colors,
837    };
838
839    pub use zng_wgt::node::{
840        VarPresent as _, VarPresentData as _, VarPresentList as _, VarPresentListFromIter, VarPresentOpt as _, bind_state, bind_state_init,
841        border_node, command_property, event_property, event_state, event_state2, event_state3, event_state4, fill_node, list_presenter,
842        list_presenter_from_iter, presenter, presenter_opt, widget_state_get_state, widget_state_is_state, with_context_blend,
843        with_context_local, with_context_local_init, with_context_var, with_context_var_init, with_widget_state, with_widget_state_modify,
844    };
845
846    #[cfg(feature = "window")]
847    pub use zng_ext_window::WidgetInfoBuilderImeArea as _;
848
849    #[cfg(hot_reload)]
850    pub use crate::hot_reload::hot_node;
851
852    #[cfg(all(feature = "fs_watcher", feature = "image"))]
853    pub use crate::fs_watcher::IMAGES_Ext as _;
854}
855
856mod defaults {
857    use zng_app::{AppExtended, AppExtension};
858    #[cfg(feature = "clipboard")]
859    use zng_ext_clipboard::ClipboardManager;
860    #[cfg(feature = "config")]
861    use zng_ext_config::ConfigManager;
862    use zng_ext_font::FontManager;
863    #[cfg(feature = "fs_watcher")]
864    use zng_ext_fs_watcher::FsWatcherManager;
865    #[cfg(feature = "image")]
866    use zng_ext_image::ImageManager;
867    use zng_ext_input::{
868        focus::FocusManager, gesture::GestureManager, keyboard::KeyboardManager, mouse::MouseManager,
869        pointer_capture::PointerCaptureManager, touch::TouchManager,
870    };
871
872    #[cfg(feature = "drag_drop")]
873    use zng_ext_input::drag_drop::DragDropManager;
874
875    use zng_ext_l10n::L10nManager;
876    #[cfg(feature = "undo")]
877    use zng_ext_undo::UndoManager;
878
879    #[cfg(feature = "window")]
880    use zng_ext_window::WindowManager;
881
882    use crate::default_editors;
883
884    #[cfg(feature = "dyn_app_extension")]
885    macro_rules! DefaultsAppExtended {
886        () => {
887            AppExtended<Vec<Box<dyn zng_app::AppExtensionBoxed>>>
888        }
889    }
890    #[cfg(not(feature = "dyn_app_extension"))]
891    macro_rules! DefaultsAppExtended {
892        () => {
893            AppExtended<impl AppExtension>
894        }
895    }
896
897    impl super::APP {
898        /// App with default extensions.
899        ///     
900        /// # Extensions
901        ///
902        /// Extensions included.
903        ///
904        /// * [`FsWatcherManager`] if the `"fs_watcher"` feature is enabled.
905        /// * [`ConfigManager`] if the `"config"` feature is enabled.
906        /// * [`L10nManager`]
907        /// * [`PointerCaptureManager`]
908        /// * [`MouseManager`]
909        /// * [`TouchManager`]
910        /// * [`KeyboardManager`]
911        /// * [`GestureManager`]
912        /// * [`WindowManager`] if the `"window"` feature is enabled.
913        /// * [`FontManager`]
914        /// * [`FocusManager`]
915        /// * [`DragDropManager`] if the `"drag_drop"` feature is enabled.
916        /// * [`ImageManager`] if the `"image"` feature is enabled.
917        /// * [`ClipboardManager`] if the `"clipboard"` feature is enabled.
918        /// * [`UndoManager`]
919        /// * [`SingleInstanceManager`] if the `"single_instance"` feature is enabled.
920        /// * [`HotReloadManager`] if the `"hot_reload"` feature is enabled.
921        /// * [`MaterialIconsManager`] if any `"material_icons*"` feature is enabled.
922        /// * [`SvgManager`] if the `"svg"` feature is enabled.
923        ///
924        /// [`MaterialIconsManager`]: zng_wgt_material_icons::MaterialIconsManager
925        /// [`SingleInstanceManager`]: zng_ext_single_instance::SingleInstanceManager
926        /// [`HotReloadManager`]: zng_ext_hot_reload::HotReloadManager
927        /// [`ConfigManager`]: zng_ext_config::ConfigManager
928        /// [`L10nManager`]: zng_ext_l10n::L10nManager
929        /// [`FontManager`]: zng_ext_font::FontManager
930        /// [`SvgManager`]: zng_ext_svg::SvgManager
931        pub fn defaults(&self) -> DefaultsAppExtended![] {
932            let r = self.minimal();
933
934            #[cfg(feature = "fs_watcher")]
935            let r = r.extend(FsWatcherManager::default());
936
937            #[cfg(feature = "config")]
938            let r = r.extend(ConfigManager::default());
939
940            let r = r.extend(L10nManager::default());
941
942            let r = r.extend(PointerCaptureManager::default());
943
944            let r = r.extend(MouseManager::default());
945
946            let r = r.extend(TouchManager::default());
947
948            let r = r.extend(KeyboardManager::default());
949
950            let r = r.extend(GestureManager::default());
951
952            #[cfg(feature = "window")]
953            let r = r.extend(WindowManager::default());
954
955            let r = r.extend(FontManager::default());
956
957            let r = r.extend(FocusManager::default());
958
959            #[cfg(feature = "drag_drop")]
960            let r = r.extend(DragDropManager::default());
961
962            #[cfg(feature = "image")]
963            let r = r.extend(ImageManager::default());
964
965            #[cfg(feature = "clipboard")]
966            let r = r.extend(ClipboardManager::default());
967
968            #[cfg(feature = "undo")]
969            let r = r.extend(UndoManager::default());
970
971            #[cfg(all(view, view_prebuilt))]
972            tracing::debug!(r#"both "view" and "view_prebuilt" enabled, will use only one, indeterminate witch"#);
973
974            #[cfg(single_instance)]
975            let r = r.extend(zng_ext_single_instance::SingleInstanceManager::default());
976
977            #[cfg(hot_reload)]
978            let r = r.extend(zng_ext_hot_reload::HotReloadManager::default());
979
980            #[cfg(any(
981                feature = "material_icons_outlined",
982                feature = "material_icons_filled",
983                feature = "material_icons_rounded",
984                feature = "material_icons_sharp",
985            ))]
986            let r = r.extend(zng_wgt_material_icons::MaterialIconsManager::default());
987
988            #[cfg(feature = "svg")]
989            let r = r.extend(zng_ext_svg::SvgManager::default());
990
991            r.extend(DefaultsInit {})
992        }
993    }
994
995    struct DefaultsInit {}
996    impl AppExtension for DefaultsInit {
997        fn init(&mut self) {
998            // Common editors.
999            zng_wgt::EDITORS.register_fallback(zng_wgt::WidgetFn::new(default_editors::handler));
1000            tracing::debug!("defaults init, EDITORS set");
1001
1002            // injected in all windows
1003            #[cfg(feature = "window")]
1004            {
1005                zng_ext_window::WINDOWS.register_root_extender(|a| {
1006                    let child = a.root;
1007
1008                    #[cfg(feature = "inspector")]
1009                    let child = zng_wgt_inspector::inspector(child, zng_wgt_inspector::live_inspector(true));
1010
1011                    #[cfg(feature = "menu")]
1012                    let child = zng_wgt_menu::style_fn(child, crate::style::style_fn!(|_| crate::menu::DefaultStyle!()));
1013
1014                    child
1015                });
1016                tracing::debug!("defaults init, root_extender set");
1017            }
1018            #[cfg(any(target_os = "android", target_os = "ios"))]
1019            {
1020                zng_ext_window::WINDOWS.register_open_nested_handler(crate::window::default_mobile_nested_open_handler);
1021                tracing::debug!("defaults init, open_nested_handler set");
1022            }
1023
1024            // setup OPEN_LICENSES_CMD handler
1025            #[cfg(all(feature = "third_party_default", feature = "third_party"))]
1026            {
1027                crate::third_party::setup_default_view();
1028                tracing::debug!("defaults init, third_party set");
1029            }
1030
1031            // setup SETTINGS_CMD handler
1032            #[cfg(feature = "settings_editor")]
1033            {
1034                zng_wgt_settings::handle_settings_cmd();
1035                tracing::debug!("defaults init, settings set");
1036            }
1037
1038            #[cfg(all(single_instance, feature = "window"))]
1039            {
1040                crate::app::APP_INSTANCE_EVENT
1041                    .on_pre_event(crate::handler::hn!(|args| {
1042                        use crate::window::*;
1043
1044                        // focus a window if none are focused.
1045                        if !args.is_current() && WINDOWS.focused_window_id().is_none() {
1046                            for w in WINDOWS.widget_trees() {
1047                                if w.is_rendered()
1048                                    && WINDOWS.mode(w.window_id()) == Ok(WindowMode::Headed)
1049                                    && WINDOWS.focus(w.window_id()).is_ok()
1050                                {
1051                                    break;
1052                                }
1053                            }
1054                        }
1055                    }))
1056                    .perm();
1057                tracing::debug!("defaults init, single_instance set");
1058            }
1059        }
1060
1061        fn deinit(&mut self) {
1062            // ensure zng_view_prebuilt is linked, macOS system linker can "optimize" the entire
1063            // crate away because it is only referenced by `linkme` in `on_process_start!`
1064            #[cfg(all(view_prebuilt, any(target_os = "macos", target_os = "ios")))]
1065            if std::env::var("=").is_ok() {
1066                crate::view_process::prebuilt::run_same_process(|| unreachable!());
1067            }
1068        }
1069    }
1070}
1071
1072#[doc = include_str!("../../README.md")]
1073#[cfg(doctest)]
1074pub mod read_me_test {}
1075
1076mod default_editors {
1077    use zng::widget::{EditorRequestArgs, node::UiNode};
1078
1079    pub fn handler(args: EditorRequestArgs) -> UiNode {
1080        #[cfg(feature = "text_input")]
1081        if let Some(txt) = args.value::<zng::text::Txt>() {
1082            return zng::text_input::TextInput! {
1083                txt;
1084            };
1085        }
1086        #[cfg(feature = "text_input")]
1087        if let Some(s) = args.value::<String>() {
1088            return zng::text_input::TextInput! {
1089                txt = s.map_bidi(|s| zng::text::Txt::from_str(s), |t: &zng::text::Txt| t.to_string());
1090            };
1091        }
1092        #[cfg(feature = "text_input")]
1093        if let Some(c) = args.value::<char>() {
1094            return zng::text_input::TextInput! {
1095                txt_parse::<char> = c;
1096                style_fn = crate::text_input::FieldStyle!();
1097            };
1098        }
1099
1100        #[cfg(feature = "toggle")]
1101        if let Some(checked) = args.value::<bool>() {
1102            return zng::toggle::Toggle! {
1103                style_fn = zng::toggle::CheckStyle!();
1104                checked;
1105            };
1106        }
1107
1108        macro_rules! parse {
1109            ($($ty:ty),+ $(,)?) => {
1110                $(
1111                    #[cfg(feature = "text_input")]
1112                    if let Some(n) = args.value::<$ty>() {
1113                        return zng::text_input::TextInput! {
1114                            txt_parse::<$ty> = n;
1115                            style_fn = crate::text_input::FieldStyle!();
1116                        };
1117                    }
1118
1119                )+
1120            }
1121        }
1122        parse! { u8, i8, u16, i16, u32, i32, u64, i64, u128, i128, f32, f64 }
1123
1124        let _ = args;
1125        UiNode::nil()
1126    }
1127}