zng/
container.rs

1//! Container widget.
2//!
3//! Base widget for all widgets that are designed around a single child widget or a primary child widget surrounded by secondary widgets.
4//!
5//! # Child Inserts
6//!
7//! The example below demonstrates a container with a primary child that fills the available space not taken by the other children.
8//! The top child is also separated from the primary child by 5dip.
9//!
10//! ```
11//! use zng::prelude::*;
12//!
13//! # let _scope = APP.defaults();
14//! # let _ =
15//! Container! {
16//!     child_top = {
17//!         node: Text!("secondary (top)"),
18//!         spacing: 5,
19//!     };
20//!     child = Text! { txt = "primary"; widget::background_color = colors::BLUE };
21//!     child_bottom = {
22//!         node: Text!("secondary (bottom)"),
23//!         spacing: 0,
24//!     };
25//! }
26//! # ;
27//! ```
28//!
29//! Note that `Window!` inherits from `Container!` to the example above could become the skeleton of a classic app window:
30//!
31//! ```
32//! # use zng::prelude::*;
33//! # let _scope = APP.defaults();
34//! # fn tools() -> impl UiNode { widget::node::NilUiNode }
35//! # fn content() -> impl UiNode { widget::node::NilUiNode }
36//! # fn status() -> impl UiNode { widget::node::NilUiNode }
37//! # let _ =
38//! Window! {
39//!     child_top = tools(), 0;
40//!     child = content();
41//!     child_bottom = status(), 0;
42//! }
43//! # ;
44//! ```
45//!
46//! Note that a similar layout could be achieved using widgets like [`Grid!`], but the child insert properties are a convenient
47//! way to define this kind of widget, also a container widget without child inserts does not pay any extra cost, the insertion
48//! layout implementation if fully contained to the insert properties.
49//!
50//! [`Grid!`]: struct@crate::grid::Grid
51//!
52//! # Child Nodes
53//!
54//! The child can by any [`UiNode`] type, not just widgets, you can use this to plug nodes directly on the UI.
55//!
56//! ```
57//! use zng::{prelude::*, prelude_wgt::*};
58//!
59//! # let _scope = APP.defaults();
60//! # let _ =
61//! Container! {
62//!     widget::background_color = colors::BLACK;
63//!     child_align = layout::Align::CENTER;
64//!     child = {
65//!         let size = Size::splat(40);
66//!         let mut render_size = PxSize::zero();
67//!         match_node_leaf(move |op| match op {
68//!             UiNodeOp::Measure { desired_size, .. } => *desired_size = size.layout(),
69//!             UiNodeOp::Layout { final_size, .. } => {
70//!                 render_size = Size::splat(40).layout();
71//!                 *final_size = render_size;
72//!             },
73//!             UiNodeOp::Render { frame } => frame.push_color(
74//!                 PxRect::from_size(render_size),
75//!                 FrameValue::Value(colors::GREEN.into())
76//!             ),
77//!             _ => {}
78//!         })
79//!     }
80//! }
81//! # ;
82//! ```
83//!
84//! [`UiNode`]: crate::widget::node::UiNode
85//!
86//! # Full API
87//!
88//! See [`zng_wgt_container`] for the full widget API.
89
90pub use zng_wgt_container::{
91    ChildInsert, Container, child, child_bottom, child_end, child_insert, child_left, child_out_bottom, child_out_end, child_out_insert,
92    child_out_left, child_out_right, child_out_start, child_out_top, child_over, child_right, child_start, child_top, child_under,
93};