Trait kas::Layout[][src]

pub trait Layout: WidgetChildren {
    fn size_rules(
        &mut self,
        size_handle: &mut dyn SizeHandle,
        axis: AxisInfo
    ) -> SizeRules;
fn draw(
        &self,
        draw_handle: &mut dyn DrawHandle,
        mgr: &ManagerState,
        disabled: bool
    ); fn set_rect(&mut self, mgr: &mut Manager<'_>, rect: Rect, align: AlignHints) { ... }
fn translation(&self, _child_index: usize) -> Offset { ... }
fn spatial_nav(
        &mut self,
        mgr: &mut Manager<'_>,
        reverse: bool,
        from: Option<usize>
    ) -> Option<usize> { ... }
fn find_id(&self, coord: Coord) -> Option<WidgetId> { ... } }
Expand description

Positioning and drawing routines for widgets

This trait is part of the Widget family. It may be derived by derive(Widget), but is not by default.

This trait contains methods concerned with positioning of contents as well as low-level event handling.

For parent widgets, the implementation will often be derived (see kas::macros); otherwise, a layout engine may be used (see crate::layout). For leaf widgets, it is implemented directly.

For a description of the widget size model, see SizeRules.

Required methods

Get size rules for the given axis

This method takes &mut self to allow local caching of child widget configuration for future size_rules and set_rect calls. Fields written by set_rect should not be used for this cache since set_rect may be called multiple times without re-calling size_rules.

To allow automatic flow of content over new lines, the width is sized first, followed by the height; when sizing for height, AxisInfo contains the size of the other axis (i.e. the width).

For widgets with children, a crate::layout::RulesSolver engine may be useful to calculate requirements of complex layouts.

Draw a widget and its children

This method is invoked each frame to draw visible widgets. It should draw itself and recurse into all visible children.

The disabled argument is passed in from the parent; a widget should use let disabled = disabled || self.is_disabled(); to determine its own disabled state, then pass this value on to children.

WidgetCore::input_state may be used to obtain an InputState to determine active visual effects.

Provided methods

Apply a given rect to self

For widgets without children, the trivial default implementation of this method often suffices, though some widgets choose to align themselves within this space. Alignment may be applied in one of two ways:

  1. Shrinking to ideal area and aligning within available space (e.g. CheckBoxBare widget)
  2. Filling available space and applying alignment to contents (e.g. Label widget)

For widgets with children, a crate::layout::RulesSetter engine may be useful (used with a corresponding crate::layout::RulesSolver).

One may assume that size_rules has been called at least once for each axis with current size information before this method, however size_rules might not be re-called before calling set_rect again.

Get translation of a child

Children may live in a translated coordinate space relative to their parent. This method returns an offset which should be added to a coordinate to translate into the child’s coordinate space or subtracted to translate out.

In most cases, the translation will be zero. Widgets should return Offset::ZERO for non-existant children.

Navigation in spatial order

Returns the index of the “next” child in iteration order within the widget’s rect, if any. (Pop-up widgets should be excluded.)

If reverse is true, move in left/up direction, otherwise right/down. If from.is_some(), return its next sibling in iteration order, otherwise return the first or last child.

The default implementation often suffices: it will navigate through children in order.

Find a widget by coordinate

Used to find the widget responsible for handling events at this coord — usually the leaf-most widget containing the coordinate.

The default implementation suffices for widgets without children; otherwise this is usually implemented as follows:

  1. return None if !self.rect().contains(coord)
  2. for each child, check whether child.find_id(coord) returns Some(id), and if so return this result (parents with many children might use a faster search strategy here)
  3. otherwise, return Some(self.id())

Exceptionally, a widget may deviate from this behaviour, but only when the coord is within the widget’s own rect (example: CheckBox contains an embedded CheckBoxBare and always forwards this child’s id).

This must not be called before Layout::set_rect.

Implementations on Foreign Types

This implementation is unusual in that:

  1. size_rules always returns SizeRules::EMPTY
  2. set_rect sets the track within which this handle may move; the parent should call DragHandle::set_size_and_offset after set_rect (otherwise the handle’s offset will not be updated)
  3. draw does nothing: the parent is expected to do all drawing

Implementors