| |
use tuirealm::command::{Cmd, CmdResult};
|
| |
use tuirealm::props::{
|
| - |
AttrValue, Attribute, BorderSides, BorderType, Color, PropPayload, PropValue, Props, Style,
|
| - |
TextModifiers,
|
| + |
AttrValue, Attribute, BorderSides, BorderType, Color, Props, Style, TextModifiers,
|
| |
};
|
| |
use tuirealm::tui::layout::{Constraint, Direction, Layout, Rect};
|
| - |
use tuirealm::tui::widgets::{Block, Cell, Row};
|
| + |
use tuirealm::tui::widgets::{Block, Row};
|
| |
use tuirealm::{Frame, MockComponent, State, StateValue};
|
| |
|
| |
use crate::ui::ext::HeaderBlock;
|
| |
use crate::ui::layout;
|
| |
use crate::ui::state::TabState;
|
| + |
use crate::ui::theme::Theme;
|
| |
use crate::ui::widget::{Widget, WidgetComponent};
|
| |
|
| |
use super::label::Label;
|
| + |
use super::list::{Table, TableItem, TableModel};
|
| |
|
| |
/// Some user events need to be handled globally (e.g. user presses key `q` to quit
|
| |
/// the application). This component can be used in conjunction with SubEventClause
|
| |
}
|
| |
|
| |
/// A labeled container header.
|
| - |
#[derive(Default)]
|
| - |
pub struct Header;
|
| - |
|
| - |
impl Header {
|
| - |
fn content<'a>(spans: Vec<PropValue>) -> Row<'a> {
|
| - |
Row::new(
|
| - |
spans
|
| - |
.iter()
|
| - |
.map(|span| Cell::from(span.clone().unwrap_text_span().content))
|
| - |
.collect::<Vec<_>>(),
|
| - |
)
|
| - |
}
|
| + |
pub struct Header<V, const W: usize>
|
| + |
where
|
| + |
V: TableItem<W>,
|
| + |
{
|
| + |
model: TableModel<V, W>,
|
| + |
theme: Theme,
|
| + |
}
|
| |
|
| - |
fn widths(widths: Vec<PropValue>) -> Vec<Constraint> {
|
| - |
widths
|
| - |
.iter()
|
| - |
.map(|prop| Constraint::Percentage(prop.clone().unwrap_u16()))
|
| - |
.collect()
|
| + |
impl<V, const W: usize> Header<V, W>
|
| + |
where
|
| + |
V: TableItem<W>,
|
| + |
{
|
| + |
pub fn new(model: TableModel<V, W>, theme: Theme) -> Self {
|
| + |
Self { model, theme }
|
| |
}
|
| |
}
|
| |
|
| - |
impl WidgetComponent for Header {
|
| + |
impl<V, const W: usize> WidgetComponent for Header<V, W>
|
| + |
where
|
| + |
V: TableItem<W> + Clone,
|
| + |
{
|
| |
fn view(&mut self, properties: &Props, frame: &mut Frame, area: Rect) {
|
| |
let display = properties
|
| |
.get_or(Attribute::Display, AttrValue::Flag(true))
|
| |
.unwrap_flag();
|
| - |
let content = properties
|
| - |
.get_or(
|
| - |
Attribute::Content,
|
| - |
AttrValue::Payload(PropPayload::Vec(vec![])),
|
| - |
)
|
| - |
.unwrap_payload()
|
| - |
.unwrap_vec();
|
| - |
let widths = properties
|
| - |
.get_or(
|
| - |
Attribute::Custom("widths"),
|
| - |
AttrValue::Payload(PropPayload::Vec(vec![])),
|
| - |
)
|
| - |
.unwrap_payload()
|
| - |
.unwrap_vec();
|
| - |
|
| |
if display {
|
| |
let block = HeaderBlock::default()
|
| |
.borders(BorderSides::all())
|
| |
.horizontal_margin(1)
|
| |
.split(area);
|
| |
|
| - |
let header = Self::content(content);
|
| - |
let widths = Self::widths(widths);
|
| + |
let widths =
|
| + |
Table::<V, W>::widths(area, self.model.widths(), self.theme.tables.spacing);
|
| + |
let header: Row<'_> = Row::new(self.model.header(&self.theme));
|
| |
|
| |
let table = tuirealm::tui::widgets::Table::new(vec![])
|
| - |
.column_spacing(3u16)
|
| + |
.column_spacing(self.theme.tables.spacing)
|
| |
.header(header)
|
| |
.widths(&widths);
|
| |
frame.render_widget(table, layout[0]);
|
| |
}
|
| |
|
| |
pub struct LabeledContainer {
|
| - |
header: Widget<Header>,
|
| + |
header: Widget<Header<(), 1>>,
|
| |
component: Box<dyn MockComponent>,
|
| |
}
|
| |
|
| |
impl LabeledContainer {
|
| - |
pub fn new(header: Widget<Header>, component: Box<dyn MockComponent>) -> Self {
|
| + |
pub fn new(header: Widget<Header<(), 1>>, component: Box<dyn MockComponent>) -> Self {
|
| |
Self { header, component }
|
| |
}
|
| |
}
|