pub struct LayoutForm<W>{ /* private fields */ }Expand description
Create layouts for input widgets.
This takes the constraints for FormLabel and FormWidget and creates a multi-column layout for them.
There are two branches of the layout:
-
paged: Fill a target area with the widgets and start a new page when the layout overflows. You can use Form to render a multipage and navigate between the pages.
-
endless: Just stack the widgets. You can use Clipper to render such a layout and scroll through it.
§Both variants
Can
- add Blocks for multiple widgets. Can stack them too.
- layout labels above or to the left of the widget.
- add manual column/page breaks.
- align widgets vertically.
- define line/column spacing.
- flex layout columns.
Can not
- forcibly shrink-fit the widgets to a layout size.
§Paged layout
Can
- create n columns of widgets.
- stretch some widgets vertically to fill a column.
§Endless layout
Can
- create n columns of widgets.
- to-do: optimally fill all columns
- add manual breaks for now.
- not usefully stretch the widgets vertically.
if state.layout.area_changed(area) {
let mut ll = LayoutForm::new()
.spacing(1)
.line_spacing(1)
.column_spacing(1)
.padding(Padding::new(2,2,0,0))
.flex(Flex::Start)
.min_label(10);
use rat_widget::layout::{FormLabel as L, FormWidget as W};
// single row
ll.widget(state.text1.id(), L::Str("Text 1"), W::Width(22));
// stretch to form width. preferred width 15. 1 row high.
ll.widget(state.text2.id(), L::Str("Text 2"), W::StretchX(15, 1));
// stretch to the form-width and fill vertically.
// preferred width is 15 3 rows high.
ll.widget(state.text3.id(), L::Str("Text 3"), W::StretchXY(15, 3));
// calculate the layout and place it.
state.layout = ll.build_paged(area.as_size());
}
let ll = &state.layout;
// This is not really the intended use, but it works.
// In reality, you would use Clipper or Form.
let lbl1 = ll.label_for(state.text1.id());
Span::from(ll.label_str_for(state.text1.id())).render(lbl1, buf);
let txt1 = ll.widget_for(state.text1.id());
TextInput::new()
.render(txt1, buf, &mut state.text1);
let lbl2 = ll.label_for(state.text2.id());
Span::from(ll.label_str_for(state.text2.id())).render(lbl2, buf);
let txt2 = ll.widget_for(state.text2.id());
TextInput::new()
.render(txt2, buf, &mut state.text2);
let lbl3 = ll.label_for(state.text3.id());
Span::from(ll.label_str_for(state.text3.id())).render(lbl3, buf);
let txt3 = ll.widget_for(state.text3.id());
TextInput::new()
.render(txt3, buf, &mut state.text3);
Implementations§
Source§impl<W> LayoutForm<W>
impl<W> LayoutForm<W>
pub fn new() -> Self
Sourcepub fn line_spacing(self, spacing: u16) -> Self
pub fn line_spacing(self, spacing: u16) -> Self
Empty lines between widgets.
Sourcepub fn column_spacing(self, spacing: u16) -> Self
pub fn column_spacing(self, spacing: u16) -> Self
Empty space between columns.
Sourcepub fn border(self, border: Padding) -> Self
👎Deprecated since 2.0.0: use padding. is clearer.
pub fn border(self, border: Padding) -> Self
Page border.
Sourcepub fn mirror_odd_border(self) -> Self
pub fn mirror_odd_border(self) -> Self
Mirror the border given to layout between even and odd pages. The layout starts with page 0 which is even.
Sourcepub fn min_widget(self, width: u16) -> Self
pub fn min_widget(self, width: u16) -> Self
Set a reference widget width
Sourcepub fn start(&mut self, block: Option<Block<'static>>) -> BlockTag
pub fn start(&mut self, block: Option<Block<'static>>) -> BlockTag
Start a group/block.
This will create a block that covers all widgets added
before calling end().
Groups/blocks can be stacked, but they cannot interleave. An inner group/block must be closed before an outer one.
Sourcepub fn end(&mut self, tag: BlockTag)
pub fn end(&mut self, tag: BlockTag)
Closes the group/block with the given tag.
Panic Groups must be closed in reverse start order, otherwise this function will panic. It will also panic if there is no open group for the given tag.
Sourcepub fn widgets(
&mut self,
list: impl IntoIterator<Item = (W, FormLabel, FormWidget)>,
)
pub fn widgets( &mut self, list: impl IntoIterator<Item = (W, FormLabel, FormWidget)>, )
Add a list of label + widget constraints.
Sourcepub fn widget(&mut self, key: W, label: FormLabel, widget: FormWidget)
pub fn widget(&mut self, key: W, label: FormLabel, widget: FormWidget)
Add label + widget constraint. Key must be a unique identifier.
Sourcepub fn page_break(&mut self)
pub fn page_break(&mut self)
Add a manual page break after the last widget.
This will panic if the widget list is empty.
Sourcepub fn column_break(&mut self)
pub fn column_break(&mut self)
Add a manual column break after the last widget. This is a synonym for [page_break].
This will panic if the widget list is empty.
Sourcepub fn build_endless(self, width: u16) -> GenericLayout<W>
pub fn build_endless(self, width: u16) -> GenericLayout<W>
Calculate a layout without page-breaks using the given layout-width and padding.
Sourcepub fn build_paged(self, page: Size) -> GenericLayout<W>
pub fn build_paged(self, page: Size) -> GenericLayout<W>
Calculate the layout for the given page size and padding.
Trait Implementations§
Source§impl<W> Debug for LayoutForm<W>
impl<W> Debug for LayoutForm<W>
Auto Trait Implementations§
impl<W> Freeze for LayoutForm<W>
impl<W> RefUnwindSafe for LayoutForm<W>where
W: RefUnwindSafe,
impl<W> Send for LayoutForm<W>where
W: Send,
impl<W> Sync for LayoutForm<W>where
W: Sync,
impl<W> Unpin for LayoutForm<W>where
W: Unpin,
impl<W> UnwindSafe for LayoutForm<W>where
W: UnwindSafe,
Blanket Implementations§
Source§impl<S, D, Swp, Dwp, T> AdaptInto<D, Swp, Dwp, T> for Swhere
T: Real + Zero + Arithmetics + Clone,
Swp: WhitePoint<T>,
Dwp: WhitePoint<T>,
D: AdaptFrom<S, Swp, Dwp, T>,
impl<S, D, Swp, Dwp, T> AdaptInto<D, Swp, Dwp, T> for Swhere
T: Real + Zero + Arithmetics + Clone,
Swp: WhitePoint<T>,
Dwp: WhitePoint<T>,
D: AdaptFrom<S, Swp, Dwp, T>,
Source§fn adapt_into_using<M>(self, method: M) -> Dwhere
M: TransformMatrix<T>,
fn adapt_into_using<M>(self, method: M) -> Dwhere
M: TransformMatrix<T>,
Source§fn adapt_into(self) -> D
fn adapt_into(self) -> D
Source§impl<T, C> ArraysFrom<C> for Twhere
C: IntoArrays<T>,
impl<T, C> ArraysFrom<C> for Twhere
C: IntoArrays<T>,
Source§fn arrays_from(colors: C) -> T
fn arrays_from(colors: C) -> T
Source§impl<T, C> ArraysInto<C> for Twhere
C: FromArrays<T>,
impl<T, C> ArraysInto<C> for Twhere
C: FromArrays<T>,
Source§fn arrays_into(self) -> C
fn arrays_into(self) -> C
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<WpParam, T, U> Cam16IntoUnclamped<WpParam, T> for Uwhere
T: FromCam16Unclamped<WpParam, U>,
impl<WpParam, T, U> Cam16IntoUnclamped<WpParam, T> for Uwhere
T: FromCam16Unclamped<WpParam, U>,
Source§type Scalar = <T as FromCam16Unclamped<WpParam, U>>::Scalar
type Scalar = <T as FromCam16Unclamped<WpParam, U>>::Scalar
parameters when converting.Source§fn cam16_into_unclamped(
self,
parameters: BakedParameters<WpParam, <U as Cam16IntoUnclamped<WpParam, T>>::Scalar>,
) -> T
fn cam16_into_unclamped( self, parameters: BakedParameters<WpParam, <U as Cam16IntoUnclamped<WpParam, T>>::Scalar>, ) -> T
self into C, using the provided parameters.Source§impl<T, C> ComponentsFrom<C> for Twhere
C: IntoComponents<T>,
impl<T, C> ComponentsFrom<C> for Twhere
C: IntoComponents<T>,
Source§fn components_from(colors: C) -> T
fn components_from(colors: C) -> T
Source§impl<T> FromAngle<T> for T
impl<T> FromAngle<T> for T
Source§fn from_angle(angle: T) -> T
fn from_angle(angle: T) -> T
angle.Source§impl<T, U> FromStimulus<U> for Twhere
U: IntoStimulus<T>,
impl<T, U> FromStimulus<U> for Twhere
U: IntoStimulus<T>,
Source§fn from_stimulus(other: U) -> T
fn from_stimulus(other: U) -> T
other into Self, while performing the appropriate scaling,
rounding and clamping.Source§impl<T, U> IntoAngle<U> for Twhere
U: FromAngle<T>,
impl<T, U> IntoAngle<U> for Twhere
U: FromAngle<T>,
Source§fn into_angle(self) -> U
fn into_angle(self) -> U
T.Source§impl<WpParam, T, U> IntoCam16Unclamped<WpParam, T> for Uwhere
T: Cam16FromUnclamped<WpParam, U>,
impl<WpParam, T, U> IntoCam16Unclamped<WpParam, T> for Uwhere
T: Cam16FromUnclamped<WpParam, U>,
Source§type Scalar = <T as Cam16FromUnclamped<WpParam, U>>::Scalar
type Scalar = <T as Cam16FromUnclamped<WpParam, U>>::Scalar
parameters when converting.Source§fn into_cam16_unclamped(
self,
parameters: BakedParameters<WpParam, <U as IntoCam16Unclamped<WpParam, T>>::Scalar>,
) -> T
fn into_cam16_unclamped( self, parameters: BakedParameters<WpParam, <U as IntoCam16Unclamped<WpParam, T>>::Scalar>, ) -> T
self into C, using the provided parameters.Source§impl<T, U> IntoColor<U> for Twhere
U: FromColor<T>,
impl<T, U> IntoColor<U> for Twhere
U: FromColor<T>,
Source§fn into_color(self) -> U
fn into_color(self) -> U
Source§impl<T, U> IntoColorUnclamped<U> for Twhere
U: FromColorUnclamped<T>,
impl<T, U> IntoColorUnclamped<U> for Twhere
U: FromColorUnclamped<T>,
Source§fn into_color_unclamped(self) -> U
fn into_color_unclamped(self) -> U
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> IntoStimulus<T> for T
impl<T> IntoStimulus<T> for T
Source§fn into_stimulus(self) -> T
fn into_stimulus(self) -> T
self into T, while performing the appropriate scaling,
rounding and clamping.Source§impl<T, C> TryComponentsInto<C> for Twhere
C: TryFromComponents<T>,
impl<T, C> TryComponentsInto<C> for Twhere
C: TryFromComponents<T>,
Source§type Error = <C as TryFromComponents<T>>::Error
type Error = <C as TryFromComponents<T>>::Error
try_into_colors fails to cast.Source§fn try_components_into(self) -> Result<C, <T as TryComponentsInto<C>>::Error>
fn try_components_into(self) -> Result<C, <T as TryComponentsInto<C>>::Error>
Source§impl<T, U> TryIntoColor<U> for Twhere
U: TryFromColor<T>,
impl<T, U> TryIntoColor<U> for Twhere
U: TryFromColor<T>,
Source§fn try_into_color(self) -> Result<U, OutOfBounds<U>>
fn try_into_color(self) -> Result<U, OutOfBounds<U>>
OutOfBounds error is returned which contains
the unclamped color. Read more