Naming Render traits / methods

So I implemented a Focus trait crate:

There I just added a new trait that is both Widget + Focus:

trait FocusableWidget: WidgetRef + Focus {
    fn boxed(self) -> Box<dyn FocusableWidget>
    where
        Self: 'static + Sized,
    {
        Box::new(self)
    }
}

And defined a form which uses it:

#[derive(Focus, FocusContainer)]
pub(crate) struct Form {
    pub(crate) children: Vec<Box<dyn FocusableWidget>>,
}

Fill it with some widgets:

    let mut form = Form::from_iter([
        Label::new("Label 1:").boxed(),
        TextBox::new("Text 1").boxed(),
        Label::new("Label 2:").boxed(),
        TextBox::new("Text 2").boxed(),
        Label::new("Label 3:").boxed(),
        TextBox::new("Text 3").boxed(),
    ]);
    form.focus_first();

Which is then rendered:

impl WidgetRef for Form {
    fn render_ref(&self, area: Rect, buf: &mut Buffer) {
        let areas = Layout::vertical(vec![Constraint::Length(1); self.children.len()]).split(area);
        for (child, area) in zip(self.children.iter(), areas.iter()) {
            child.render_ref(*area, buf);
        }
    }
}

image

The ability to just slap form fields into a vec like this and be able to produce a rendered form is what I’m talking about when I suggest that WidgetRef is a useful abstaction. This wouldn’t be possible to build with the no Widget traits approach.

1 Like