zng/style.rs
1//! Style mix-in and other types.
2//!
3//! A [`Style!`](struct@Style) is an special widget that represents a set of properties that are dynamically loaded onto
4//! another styleable widget. Styleable widgets inherit from [`StyleMix<P>`](struct@StyleMix) and provide a contextual
5//! `style_fn` property that sets the widget style.
6//!
7//! Styles extend the contextual style by default, only replacing the intersection of properties.
8//! The special [`replace`](struct@Style#method.replace) property can be set on a style to fully replace the contextual style.
9//!
10//! The example below demonstrates multiple contexts setting style for buttons.
11//!
12//! ```
13//! use zng::prelude::*;
14//! # let _app = APP.defaults();
15//!
16//! # let _ =
17//! Stack! {
18//! direction = StackDirection::top_to_bottom();
19//! spacing = 5;
20//!
21//! zng::button::style_fn = Style! {
22//! // override the default background_color for all buttons in the Stack.
23//! // note that this does not override the hovered/pressed background.
24//! widget::background_color = colors::BLUE;
25//! };
26//!
27//! children = ui_vec![
28//! // these buttons have the default style with blue background.
29//! Button! { child = Text!("Default+BLUE") },
30//! Button! { child = Text!("Default+BLUE") },
31//!
32//! Stack! {
33//! direction = StackDirection::top_to_bottom();
34//! spacing = 5;
35//!
36//! zng::button::style_fn = Style! {
37//! // override the default border for all buttons in the Stack.
38//! widget::border = 2, colors::GREEN;
39//! };
40//!
41//! children = ui_vec![
42//! // these buttons have the default style, with blue background and green border.
43//! Button! { child = Text!("Default+BLUE+GREEN") },
44//! Button! { child = Text!("Default+BLUE+GREEN") },
45//!
46//! Stack! {
47//! direction = StackDirection::top_to_bottom();
48//! spacing = 5;
49//!
50//!
51//! zng::button::style_fn = Style! {
52//! // override the context style background_color in the Stack.
53//! widget::background_color = colors::RED;
54//! };
55//!
56//! children = ui_vec![
57//! // these buttons have the default style, with green border and red background.
58//! Button! { child = Text!("Default+GREEN+RED") },
59//! Button! { child = Text!("Default+GREEN+RED") },
60//! // this button ignores the contextual style by setting the `style_fn` to a style
61//! // that is `replace=true`.
62//! Button! {
63//! child = Text!("Default");
64//! style_fn = zng::button::DefaultStyle!();
65//! },
66//! ]
67//! },
68//! ]
69//! },
70//! Stack! {
71//! direction = StackDirection::top_to_bottom();
72//! spacing = 5;
73//!
74//! zng::button::style_fn = Style! {
75//! // replace the default style with this one.
76//! replace = true;
77//! widget::background_color = colors::RED;
78//! };
79//!
80//! // these buttons only have the red background.
81//! children = ui_vec![
82//! Button! { child = Text!("RED") },
83//! Button! { child = Text!("RED") },
84//! ]
85//! }
86//! ]
87//! }
88//! # ;
89//! ```
90//!
91//! # Shared Styles
92//!
93//! Style instances can be set directly on `style_fn` properties, but if the style is used by more then one widget property values
94//! that can't be cloned will only appear on the last widget to use the style. The [`style_fn!`] macro can be used to declare a
95//! closure that instantiates the style for each usage. The property values that can't be cloned are `impl UiNode` and `impl UiNodeList`.
96//!
97//! The example below demonstrates this issue:
98//!
99//! ```
100//! use zng::prelude::*;
101//! # let _scope = APP.defaults();
102//!
103//! # let _ =
104//! Stack!(
105//! top_to_bottom,
106//! 20,
107//! ui_vec![
108//! Stack! {
109//! direction = StackDirection::top_to_bottom();
110//! spacing = 5;
111//! widget::parallel = false; // init buttons sequentially
112//!
113//! zng::button::style_fn = Style! {
114//! // background is `impl UiNode` that can't be cloned. Nodes
115//! // are moved to the last place that requests it.
116//! widget::background = zng::color::flood(colors::AZURE);
117//! };
118//! children = ui_vec![
119//! Button! { child = Text!("Default") },
120//! // the last button to init takes the background node.
121//! Button! { child = Text!("Default+AZURE") },
122//! ]
123//! },
124//! Stack! {
125//! direction = StackDirection::top_to_bottom();
126//! spacing = 5;
127//!
128//! // Sets the style to a closure that will be called for each button.
129//! zng::button::style_fn = style_fn!(|_| Style! {
130//! widget::background = zng::color::flood(colors::AZURE);
131//! });
132//! children = ui_vec![
133//! // each button gets its own background node.
134//! Button! { child = Text!("Default+AZURE") },
135//! Button! { child = Text!("Default+AZURE") },
136//! ]
137//! }
138//! ]
139//! )
140//! # ;
141//! ```
142
143pub use zng_wgt_style::{Style, StyleArgs, StyleBuilder, StyleFn, StyleMix, impl_style_fn, style_fn};