pub trait Widget: Tile {
type Data: Sized;
// Provided methods
fn as_node<'a>(&'a mut self, data: &'a Self::Data) -> Node<'a> { ... }
fn child_node<'n>(
&'n mut self,
data: &'n Self::Data,
index: usize,
) -> Option<Node<'n>> { ... }
}Expand description
The Widget trait
The primary widget trait covers event handling over super trait Tile
which governs layout, drawing, child enumeration and identification.
Most methods of Widget are hidden and only for use within the Kas library.
Widget is dyn-safe given a type parameter, e.g. dyn Widget<Data = ()>.
Tile is dyn-safe without a type parameter. Node is a dyn-safe
abstraction over a &dyn Widget<Data = T> plus a &T data parameter.
§Widget lifecycle
- The widget is configured (
Events::configure) and immediately updated (Events::update). - The widget has its size-requirements checked by calling
Layout::size_rulesfor each axis. Layout::set_rectis called to position elements. This may use data cached bysize_rules.- The widget is updated again after any data change (see
ConfigCx::update). - The widget is ready for event-handling and drawing
(
Events::handle_event,Layout::try_probe,Layout::draw).
Widgets are responsible for ensuring that their children may observe this lifecycle. Usually this simply involves inclusion of the child in layout operations. Steps of the lifecycle may be postponed until a widget becomes visible.
§Implementing Widget
To implement a widget, use the #widget macro within an
impl_self, impl_scope! or
impl_anon! macro.
This is the only supported method of implementing Widget.
Explicit (partial) implementations of Widget, Layout, Tile and Events
are optional. The #widget macro completes implementations.
Synopsis:
#[impl_self]
mod MyWidget {
#[widget {
// macro properties (all optional)
Data = T;
}]
#[layout(self.foo)]
struct MyWidget {
core: widget_core!(),
#[widget] foo: impl Widget<Data = T> = make_foo(),
// ...
}
// Optional implementations:
impl Layout for Self { /* ... */ }
impl Events for Self { /* ... */ }
impl Self { /* ... */ }
}Details may be categorised as follows:
- Data: the type
Widget::Datamust be specified exactly once, but this type may be given in any of three locations: as a property of the#widgetmacro or asWidget::Data. - Core methods of
Tileare always implemented via the#widgetmacro, whether or not animpl Tile { ... }item is present. - Introspection methods
Tile::child_indices,Tile::get_childandWidget::child_nodeare implemented by the#widgetmacro in most cases: child widgets embedded within a layout descriptor or included as fields marked with#[widget]are enumerated. - Introspection methods
Tile::find_child_indexandEvents::make_child_idhave default implementations which usually suffice. - Layout is specified either via layout syntax
or via implementation of at least
Layout::size_rulesandLayout::draw(optionally alsoset_rect,nav_next,translationandTile::probe). - Event handling is optional, implemented through
Events.
For examples, check the source code of widgets in the widgets library or examples apps. (Check that the code uses the same Kas version since the widget traits are not yet stable.)
Required Associated Types§
Sourcetype Data: Sized
type Data: Sized
Input data type
Widget expects data of this type to be provided by reference when calling any event-handling operation on this widget.
Type Data should be specified either here (impl Widget { ... }) or
in impl Events { ... }. Alternatively, if the widget has no children
and no explicit impl Events or impl Widget, then Data = () is
assumed; or, if the prior conditions are met and #[collection] is used
on some field, then Data = <#field_ty as ::kas::Collection>::Data is
assumed.
Provided Methods§
Sourcefn as_node<'a>(&'a mut self, data: &'a Self::Data) -> Node<'a>
fn as_node<'a>(&'a mut self, data: &'a Self::Data) -> Node<'a>
Erase type
This method is implemented by the #[widget] macro.
Sourcefn child_node<'n>(
&'n mut self,
data: &'n Self::Data,
index: usize,
) -> Option<Node<'n>>
fn child_node<'n>( &'n mut self, data: &'n Self::Data, index: usize, ) -> Option<Node<'n>>
Access a child as a Node, if available
This method is the mut version of Tile::get_child but which also
pairs the returned widget with its input data. It is expected to
succeed where Tile::get_child succeeds.
Valid index values may be discovered by calling
Tile::child_indices, Tile::find_child_index or
Tile::nav_next. The index-to-child mapping is not
required to remain fixed; use an Id to track a widget over time.
This method must be implemented explicitly when Tile::get_child is.
It might also need to be implemented explicitly to map data, though
usually the #[widget] attribute on children specifies this mapping.