use iced::{
advanced::graphics::core::Element,
font::{Stretch, Weight},
widget::{column, component, scrollable, text, Column, Component, Row},
Font, Renderer,
};
use itertools::Itertools;
use crate::{theme::Image, widgets::image_card, ActivePage};
pub struct Omni<M> {
open_page: fn(ActivePage) -> M,
}
impl<M> Omni<M> {
pub fn new(open_page: fn(ActivePage) -> M) -> Self {
Self { open_page }
}
}
impl<M: Clone> Component<M, Renderer> for Omni<M> {
type State = State;
type Event = Event;
fn update(&mut self, _state: &mut Self::State, event: Self::Event) -> Option<M> {
match event {
Event::OpenRoom(room) => Some((self.open_page)(ActivePage::Room(room))),
}
}
fn view(&self, _state: &Self::State) -> Element<'_, Self::Event, Renderer> {
let header = |v| {
text(v).size(60).font(Font {
weight: Weight::Bold,
stretch: Stretch::Condensed,
..Font::with_name("Helvetica Neue")
})
};
let room = |room, image| {
image_card::image_card(image, room).on_press(Event::OpenRoom(room))
};
let rooms = [
room("Living Room", Image::LivingRoom),
room("Kitchen", Image::Kitchen),
room("Bathroom", Image::Bathroom),
room("Bedroom", Image::Bedroom),
room("Dining Room", Image::DiningRoom),
]
.into_iter()
.chunks(2)
.into_iter()
.map(|children| children.into_iter().fold(Row::new().spacing(10), Row::push))
.fold(Column::new().spacing(10), Column::push);
scrollable(
column![header("Cameras"), header("Rooms"), rooms,]
.spacing(20)
.padding(40),
)
.into()
}
}
#[derive(Default, Hash)]
pub struct State {}
#[derive(Clone)]
pub enum Event {
OpenRoom(&'static str),
}
impl<'a, M> From<Omni<M>> for Element<'a, M, Renderer>
where
M: 'a + Clone,
{
fn from(card: Omni<M>) -> Self {
component(card)
}
}