NAME
Clay::UI::Role::Layout::HasLayout - layout attribute for Clay::UI widgets
SYNOPSIS
use v5.22;
use Object::Pad;
use Clay::XS qw(
sizing_grow sizing_fixed padding_all CLAY_TOP_TO_BOTTOM CLAY_ALIGN_X_CENTER
);
use Clay::UI::Role::Core::Container;
use Clay::UI::Role::Layout::HasLayout;
class My::Column :strict(params)
:does(Clay::UI::Role::Core::Container)
:does(Clay::UI::Role::Layout::HasLayout)
{}
my $column = My::Column->new(
layout => {
sizing => { width => sizing_grow(), height => sizing_fixed(300) },
padding => padding_all(10),
child_gap => 4,
child_alignment => { x => CLAY_ALIGN_X_CENTER },
layout_direction => CLAY_TOP_TO_BOTTOM,
},
);
my $layout = $column->layout; # a copy
$layout->{child_gap} = 8;
$column->layout($layout); # write it back
DESCRIPTION
Clay::UI::Role::Layout::HasLayout gives a widget the layout attribute: how the element is sized, how much padding it has and how it places its children. The widget adds it to its declaration (the hash of settings Clay receives for the element) as the layout part. Clay::UI::Box, Clay::UI::Grid, Clay::UI::Grid::Cell and Clay::UI::Grid::Row compose it.
ATTRIBUTES
layout
my $layout = $widget->layout; # read: a copy
$widget->layout({ child_gap => 8 }); # write: replaces the whole hash
$widget->layout({}); # back to Clay's defaults
A constructor parameter and a read/write accessor. The value is a hashref with any of these keys (snake_case, or Clay's camelCase; the reader returns snake_case):
sizing-
{ width => $axis, height => $axis }, each axis built withsizing_fit,sizing_grow,sizing_fixedorsizing_percentfrom Clay::XS. An axis left out is FIT. A maximum of 0 means "no maximum", sosizing_fixed(0)does not make an element 0 wide: it behaves like FIT. padding-
{ left, right, top, bottom }, integers 0 to 65535;padding_all($n)from Clay::XS builds one. A single number dies. child_gap-
The space between children along the layout direction, an integer 0 to 65535.
child_alignment-
{ x => CLAY_ALIGN_X_*, y => CLAY_ALIGN_Y_* }. layout_direction-
CLAY_LEFT_TO_RIGHT(the default),CLAY_TOP_TO_BOTTOM,CLAY_LEFT_TO_RIGHT_WRAP(children flow into lines) orCLAY_BACK_TO_FRONT(children stacked on top of each other). line_gap-
For
CLAY_LEFT_TO_RIGHT_WRAP: the space between lines, an integer 0 to 65535. line_sizing-
For
CLAY_LEFT_TO_RIGHT_WRAP:CLAY_LINE_SIZING_FITorCLAY_LINE_SIZING_GROW.
See "layout" in Clay::XS::Structs for what each field does in Clay.
Default {}: the declaration gets no layout part and Clay uses its defaults (FIT on both axes, no padding, no gap, CLAY_LEFT_TO_RIGHT, children at the left and top).
Reading returns a new deep copy; writing stores a deep copy of the value, so changing a hash after passing it in, or one a read returned, does not change the widget. A write replaces the whole hash (it does not merge with the old one), bumps the revision (Clay::UI::Revision), takes effect at the next render and returns a copy of the new value.
The value is checked when it is set, at construction or by the accessor, and a bad value dies naming the attribute and the path inside it, for example:
Clay::UI: 'layout' has unknown key 'paddin' (known keys: sizing, padding, ...)
Clay::UI: 'layout.padding.left' expected an integer in 0..65535, got '-5'
Clay::UI: 'layout.padding' expected a hash reference, got '5' (padding_all(N) builds one)
Clay::UI: 'layout' must be defined
A key given in both spellings (child_gap and childGap) dies as well.
METHODS
contribute_layout
Adds the layout part to the widget's declaration (see "EXTENDING THE DECLARATION" in Clay::UI::Role::Core::Element). It writes nothing while layout is empty. Otherwise it merges the widget's layout over a layout part another role already wrote, one top-level key at a time: Clay::UI::Grid supplies default keys that way, and every key the user set wins. The merge is shallow: a sizing you give replaces the whole default sizing.