use masonry::properties::types::Length;
use std::marker::PhantomData;
use masonry::widgets;
use crate::core::{MessageContext, Mut, View, ViewMarker};
use crate::{Pod, ViewCtx, WidgetView};
pub fn sized_box<State, Action, V>(inner: V) -> SizedBox<V, State, Action>
where
V: WidgetView<State, Action>,
{
SizedBox {
inner,
height: None,
width: None,
phantom: PhantomData,
}
}
#[must_use = "View values do nothing unless provided to Xilem."]
pub struct SizedBox<V, State, Action = ()> {
inner: V,
width: Option<f64>,
height: Option<f64>,
phantom: PhantomData<fn() -> (State, Action)>,
}
impl<V, State, Action> SizedBox<V, State, Action> {
pub fn width(mut self, width: Length) -> Self {
self.width = Some(width.get());
self
}
pub fn height(mut self, height: Length) -> Self {
self.height = Some(height.get());
self
}
pub fn expand(mut self) -> Self {
self.width = Some(f64::INFINITY);
self.height = Some(f64::INFINITY);
self
}
pub fn expand_width(mut self) -> Self {
self.width = Some(f64::INFINITY);
self
}
pub fn expand_height(mut self) -> Self {
self.height = Some(f64::INFINITY);
self
}
}
impl<V, State, Action> ViewMarker for SizedBox<V, State, Action> {}
impl<V, State, Action> View<State, Action, ViewCtx> for SizedBox<V, State, Action>
where
State: 'static,
Action: 'static,
V: WidgetView<State, Action>,
{
type Element = Pod<widgets::SizedBox>;
type ViewState = V::ViewState;
fn build(&self, ctx: &mut ViewCtx, app_state: &mut State) -> (Self::Element, Self::ViewState) {
let (child, child_state) = self.inner.build(ctx, app_state);
let widget = widgets::SizedBox::new(child.new_widget)
.raw_width(self.width)
.raw_height(self.height);
(ctx.create_pod(widget), child_state)
}
fn rebuild(
&self,
prev: &Self,
view_state: &mut Self::ViewState,
ctx: &mut ViewCtx,
mut element: Mut<'_, Self::Element>,
app_state: &mut State,
) {
if self.width != prev.width {
widgets::SizedBox::set_raw_width(&mut element, self.width);
}
if self.height != prev.height {
widgets::SizedBox::set_raw_height(&mut element, self.height);
}
{
let mut child = widgets::SizedBox::child_mut(&mut element)
.expect("We only create SizedBox with a child");
self.inner
.rebuild(&prev.inner, view_state, ctx, child.downcast(), app_state);
}
}
fn teardown(
&self,
view_state: &mut Self::ViewState,
ctx: &mut ViewCtx,
mut element: Mut<'_, Self::Element>,
) {
let mut child = widgets::SizedBox::child_mut(&mut element)
.expect("We only create SizedBox with a child");
self.inner.teardown(view_state, ctx, child.downcast());
}
fn message(
&self,
view_state: &mut Self::ViewState,
message: &mut MessageContext,
mut element: Mut<'_, Self::Element>,
app_state: &mut State,
) -> crate::MessageResult<Action> {
let mut child = widgets::SizedBox::child_mut(&mut element)
.expect("We only create SizedBox with a child");
self.inner
.message(view_state, message, child.downcast(), app_state)
}
}