Macro conrod::widget_style
[−]
[src]
macro_rules! widget_style { ( $(#[$Style_attr:meta])* style $Style:ident { $($fields:tt)* } ) => { ... }; }
A macro for vastly simplifying the definition and implementation of a widget's associated
Style
type.
For more information on the purpose of this Style
type, see the associated type Style
docs
in the Widget
trait documentation.
Using the macro looks like this:
widget_style!{ // Doc comment or attr for the generated `Style` struct can go here. style Style { // Fields and their type T (which get converted to `Option<T>` in the struct definition) // along with their default expression go here. // You can also write doc comments or attr above each field. - color: conrod::Color { theme.shape_color } - label_color: conrod::Color { conrod::color::BLUE } // .. more fields. } }
An invocation of the macro expands into two things:
- A struct definition with the given name following the
style
token. An
impl Style
block with anew
constructor as well as a style retrieval method for each given field. These retrieval methods do the following:- Attempt to use the value at the field.
- If the field is
None
, attempts to retreive a default from thewidget_styling
map in theUi
's currentTheme
. - If no defaults were found, evaluates the given default expression (or
theme.field
).
Examples
The following is a typical usage example for the widget_style!
macro.
#[macro_use] extern crate conrod; struct MyWidget { style: Style, // Other necessary fields... } widget_style!{ /// Unique, awesome styling for a `MyWidget`. style Style { /// The totally amazing color to use for the `MyWidget`. /// /// If the `color` is unspecified and there is no default given via the `Theme`, the /// `Theme`'s standard `shape_color` field will be used as a fallback. - color: conrod::Color { theme.shape_color } /// The extremely pretty color to use for the `MyWidget`'s label. /// /// If the `label_color` is unspecified and there is no default given via the `Theme`, /// the label will fallback to `conrod::color::PURPLE`. - label_color: conrod::Color { conrod::color::PURPLE } } } // We can now retrieve the `color` or `label_color` for a `MyWidget` like so: // let color = my_widget.style.color(&theme); // let label_color = my_widget.style.label_color(&theme);
And here is what it expands into:
#[macro_use] extern crate conrod; struct MyWidget { style: Style, // Other necessary fields... } /// Unique, awesome styling for a `MyWidget`. #[derive(Copy, Clone, Debug, PartialEq)] pub struct Style { /// The totally amazing color to use for the `MyWidget`. /// /// If the `color` is unspecified and there is no default given via the `Theme`, the /// `Theme`'s standard `shape_color` field will be used as a fallback. color: Option<conrod::Color>, /// The extremely pretty color to use for the `MyWidget`'s label. /// /// If the `label_color` is unspecified and there is no default given via the `Theme`, /// the label will fallback to `conrod::color::PURPLE`. label_color: Option<conrod::Color>, } impl Style { /// Construct the default `Style`, initialising all fields to `None`. pub fn new() -> Self { Style { color: None, label_color: None, } } /// Retrieves the value from the `Style`. /// /// If the `Style`'s field is `None`, falls back to default specified within the `Theme`. pub fn color(&self, theme: &conrod::Theme) -> conrod::Color { self.color .or_else(|| theme.widget_style::<Self>().and_then(|default| { default.style.color })) .unwrap_or_else(|| theme.shape_color) } /// Retrieves the value from the `Style`. /// /// If the `Style`'s field is `None`, falls back to default specified within the `Theme`. pub fn label_color(&self, theme: &conrod::Theme) -> conrod::Color { self.label_color .or_else(|| theme.widget_style::<Self>().and_then(|default| { default.style.label_color })) .unwrap_or_else(|| conrod::color::PURPLE) } } // We can now retrieve the `color` or `label_color` for a `MyWidget` like so: // let color = my_widget.style.color(&theme); // let label_color = my_widget.style.label_color(&theme);