use std::sync::Arc;
use crate::builder::Grid;
use crate::error::{PaneError, TreeError};
use crate::layout::Layout;
use crate::strategy::{CardSpan, GridColumnMode};
pub struct Dashboard {
cards: Arc<[(Arc<str>, CardSpan)]>,
columns: GridColumnMode,
gap: f32,
auto_rows: bool,
}
impl Dashboard {
pub(crate) fn new(
cards: impl IntoIterator<Item = (impl Into<Arc<str>>, impl Into<CardSpan>)>,
) -> Self {
Self {
cards: cards
.into_iter()
.map(|(k, span)| (k.into(), span.into()))
.collect(),
columns: GridColumnMode::Fixed(4),
gap: 0.0,
auto_rows: false,
}
}
crate::macros::builder_mapped_setters!(
columns(columns: usize) -> columns = GridColumnMode::Fixed(columns);
auto_fill(min_width: f32) -> columns = GridColumnMode::AutoFill { min_width };
auto_fit(min_width: f32) -> columns = GridColumnMode::AutoFit { min_width }
);
crate::macros::builder_setters!(
gap(gap: f32)
);
crate::macros::builder_flag_setters!(
auto_rows -> auto_rows = true
);
fn to_grid(&self) -> Grid {
Grid::from_column_mode(self.columns)
.gap(self.gap)
.apply_auto_rows(self.auto_rows)
}
pub fn build(&self) -> Result<Layout, PaneError> {
match self.cards.is_empty() {
true => return Err(PaneError::InvalidTree(TreeError::DashboardNoCards)),
false => {}
}
let cards = Arc::clone(&self.cards);
Layout::build_grid(self.to_grid(), |g| {
for (kind, span) in cards.iter() {
g.panel_span(Arc::clone(kind), *span);
}
})
}
}
impl Dashboard {
pub fn into_runtime(self) -> Result<crate::runtime::LayoutRuntime, PaneError> {
let spans: Arc<[CardSpan]> = self.cards.iter().map(|(_, s)| *s).collect();
let kinds: Box<[Arc<str>]> = self.cards.iter().map(|(k, _)| Arc::clone(k)).collect();
let strategy = self
.columns
.to_dashboard_strategy(self.gap, spans, self.auto_rows);
crate::runtime::LayoutRuntime::from_strategy(strategy, &kinds)
}
}
super::impl_preset!(Dashboard);