widget

Attribute Macro widget 

Source
#[widget]
Expand description

Attribute to implement the kas::Widget family of traits

This may only be used within the impl_self, impl_scope! and impl_anon! macros. It does not need to be imported (it is resolved by the afore-mentioned macros).

Assists implementation of the Widget, Events, Layout and Tile traits. Implementations of these traits are generated if missing or augmented with missing method implementations.

This macro may inject methods into existing Layout / Tile / Events / Widget implementations. (In the case of multiple implementations of the same trait, as used for specialization, only the first implementation of each trait is extended.)

See also the layout attribute which assists in implementing Layout.

§Fields

The struct must contain a field of type widget_core!() (usually named core). The macro widget_core!() is a placeholder, expanded by #[widget] and used to identify the field used (any name may be used). This type implements [Default] and [Clone], though the clone is not an exact clone (cloned widgets must still be configured).

Assuming the deriving type is a struct or tuple struct, fields support the following attributes:

  • #[widget]: marks the field as a Widget to be configured, enumerated by Widget::get_child and included by glob layouts
  • #[widget(expr)]: the same, but maps the data reference type; expr is an expression returning a reference to the child widget’s input data; available inputs are self, data (own input data) and index (of the child).
  • #[widget = expr]: an alternative way of writing the above
  • #[collection]: the field is a Collection of widgets

§Examples

A simple example is the Frame widget:

#[impl_self]
mod Frame {
    /// A frame around content
    #[derive(Clone, Default)]
    #[widget]
    #[layout(frame!(self.inner))]
    pub struct Frame<W: Widget> {
        core: widget_core!(),
        #[widget]
        pub inner: W,
    }

    impl Self {
        /// Construct a frame
        #[inline]
        pub fn new(inner: W) -> Self {
            Frame {
                core: Default::default(),
                inner,
            }
        }
    }
}

§Method modification

As a policy, this macro may inject code into user-defined methods of Widget and its super traits, such that:

  • The modification cannot have harmful side effects (other than reported errors).
  • All side effects observable outside of reported error cases must be documented in the widget method documentation.

As an example, status checks are injected into some Layout methods to enforce the expected call order of methods at runtime in debug builds.

§Debugging

To inspect the output of this macro, set the environment variable KAS_DEBUG_WIDGET to the name of the widget concerned, dump the output to a temporary file and format. For example:

KAS_DEBUG_WIDGET=Border cargo build > temp.rs
rustfmt temp.rs