LayoutForm

Struct LayoutForm 

Source
pub struct LayoutForm<W>
where W: Eq + Hash + Clone + Debug,
{ /* 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>
where W: Eq + Hash + Clone + Debug,

Source

pub fn new() -> Self

Source

pub fn spacing(self, spacing: u16) -> Self

Spacing between label and widget.

Source

pub fn line_spacing(self, spacing: u16) -> Self

Empty lines between widgets.

Source

pub fn column_spacing(self, spacing: u16) -> Self

Empty space between columns.

Source

pub fn padding(self, border: Padding) -> Self

Page border.

Source

pub fn border(self, border: Padding) -> Self

👎Deprecated since 2.0.0: use padding. is clearer.

Page border.

Source

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.

Source

pub fn columns(self, columns: u8) -> Self

Layout as multiple columns.

Source

pub fn flex(self, flex: Flex) -> Self

Flex.

Source

pub fn min_label(self, width: u16) -> Self

Set a reference label width

Source

pub fn min_widget(self, width: u16) -> Self

Set a reference widget width

Source

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.

Source

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.

Source

pub fn end_all(&mut self)

Closes all open groups/blocks.

Source

pub fn widgets( &mut self, list: impl IntoIterator<Item = (W, FormLabel, FormWidget)>, )

Add a list of label + widget constraints.

Source

pub fn widget(&mut self, key: W, label: FormLabel, widget: FormWidget)

Add label + widget constraint. Key must be a unique identifier.

Source

pub fn page_break(&mut self)

Add a manual page break after the last widget.

This will panic if the widget list is empty.

Source

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.

Source

pub fn build_endless(self, width: u16) -> GenericLayout<W>

Calculate a layout without page-breaks using the given layout-width and padding.

Source

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>
where W: Eq + Hash + Clone + Debug + Debug,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<W> Default for LayoutForm<W>
where W: Eq + Clone + Hash + Debug,

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

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<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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 more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.