zng/container.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 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
//! Container widget.
//!
//! Base widget for all widgets that are designed around a single child widget or a primary child widget surrounded by secondary widgets.
//!
//! # Child Inserts
//!
//! The example below demonstrates a container with a primary child that fills the available space not taken by the other children.
//! The top child is also separated from the primary child by 5dip.
//!
//! ```
//! use zng::prelude::*;
//!
//! # let _scope = APP.defaults();
//! # let _ =
//! Container! {
//! child_top = {
//! node: Text!("secondary (top)"),
//! spacing: 5,
//! };
//! child = Text! { txt = "primary"; widget::background_color = colors::BLUE };
//! child_bottom = {
//! node: Text!("secondary (bottom)"),
//! spacing: 0,
//! };
//! }
//! # ;
//! ```
//!
//! Note that `Window!` inherits from `Container!` to the example above could become the skeleton of a classic app window:
//!
//! ```
//! # use zng::prelude::*;
//! # let _scope = APP.defaults();
//! # fn tools() -> impl UiNode { widget::node::NilUiNode }
//! # fn content() -> impl UiNode { widget::node::NilUiNode }
//! # fn status() -> impl UiNode { widget::node::NilUiNode }
//! # let _ =
//! Window! {
//! child_top = tools(), 0;
//! child = content();
//! child_bottom = status(), 0;
//! }
//! # ;
//! ```
//!
//! Note that a similar layout could be achieved using widgets like [`Grid!`], but the child insert properties are a convenient
//! way to define this kind of widget, also a container widget without child inserts does not pay any extra cost, the insertion
//! layout implementation if fully contained to the insert properties.
//!
//! [`Grid!`]: struct@crate::grid::Grid
//!
//! # Child Nodes
//!
//! The child can by any [`UiNode`] type, not just widgets, you can use this to plug nodes directly on the UI.
//!
//! ```
//! use zng::{prelude::*, prelude_wgt::*};
//!
//! # let _scope = APP.defaults();
//! # let _ =
//! Container! {
//! widget::background_color = colors::BLACK;
//! child_align = layout::Align::CENTER;
//! child = {
//! let size = Size::splat(40);
//! let mut render_size = PxSize::zero();
//! match_node_leaf(move |op| match op {
//! UiNodeOp::Measure { desired_size, .. } => *desired_size = size.layout(),
//! UiNodeOp::Layout { final_size, .. } => {
//! render_size = Size::splat(40).layout();
//! *final_size = render_size;
//! },
//! UiNodeOp::Render { frame } => frame.push_color(
//! PxRect::from_size(render_size),
//! FrameValue::Value(colors::GREEN.into())
//! ),
//! _ => {}
//! })
//! }
//! }
//! # ;
//! ```
//!
//! [`UiNode`]: crate::widget::node::UiNode
//!
//! # Full API
//!
//! See [`zng_wgt_container`] for the full widget API.
pub use zng_wgt_container::{
child, child_bottom, child_end, child_insert, child_left, child_out_bottom, child_out_end, child_out_insert, child_out_left,
child_out_right, child_out_start, child_out_top, child_over, child_right, child_start, child_top, child_under, ChildInsert, Container,
};