use iced::widget::grid;
use iced::{Element, Theme};
use crate::PlushieRenderer;
use crate::iced_convert;
use crate::message::Message;
use crate::protocol::TreeNode;
use crate::registry::PlushieWidget;
use crate::render_ctx::RenderCtx;
use crate::widget::helpers::*;
use plushie_core::types::{Length, PlushieType};
struct GridProps {
num_columns: Option<u32>,
width: Option<f32>,
height: Option<f32>,
column_width: Option<Length>,
row_height: Option<Length>,
fluid: Option<f32>,
}
impl GridProps {
fn from_node(node: &TreeNode) -> Self {
let p = &node.props;
Self {
num_columns: u32::extract(p, "num_columns"),
width: f32::extract(p, "width"),
height: f32::extract(p, "height"),
column_width: Length::extract(p, "column_width"),
row_height: Length::extract(p, "row_height"),
fluid: f32::extract(p, "fluid"),
}
}
}
pub(crate) struct GridWidget;
impl<R: PlushieRenderer> PlushieWidget<R> for GridWidget {
fn type_names(&self) -> &[&str] {
&["grid"]
}
fn render<'a>(
&'a self,
node: &'a TreeNode,
ctx: &RenderCtx<'a, R>,
) -> Element<'a, Message, Theme, R> {
let gp = GridProps::from_node(node);
let spacing = prop_animated_f32(
&ctx.caches.interpolated_props,
&node.id,
&node.props,
"spacing",
);
let cols = gp.num_columns.unwrap_or(1) as usize;
let children = ctx.render_children(node);
let mut g = grid(children).columns(cols);
if let Some(s) = spacing {
g = g.spacing(s);
}
if let Some(w) = gp.width {
g = g.width(w);
}
if let Some(h) = gp.height {
g = g.height(h);
}
if let Some(ref cw) = gp.column_width
&& let Length::Fixed(px) = *cw
{
g = g.width(px);
}
if let Some(ref rh) = gp.row_height {
g = g.height(iced_convert::length(rh));
}
if let Some(max_w) = gp.fluid {
g = g.fluid(max_w);
}
g.into()
}
fn fresh_for_session(&self) -> Box<dyn PlushieWidget<R>> {
Box::new(GridWidget)
}
}