use kas::draw::{color, DrawIface, DrawSharedImpl, SharedState};
use kas::event::EventState;
use kas::theme::{ThemeControl, ThemeDraw, ThemeSize};
use kas::{autoimpl, TkAction};
use std::any::Any;
use std::ops::{Deref, DerefMut};
#[cfg(not(feature = "config"))]
pub trait ThemeConfig: Clone + std::fmt::Debug + 'static {
fn apply_startup(&self);
fn raster(&self) -> &crate::RasterConfig;
}
#[cfg(feature = "config")]
pub trait ThemeConfig:
Clone + std::fmt::Debug + 'static + for<'a> serde::Deserialize<'a> + serde::Serialize
{
fn is_dirty(&self) -> bool;
fn apply_startup(&self);
fn raster(&self) -> &crate::RasterConfig;
}
pub trait Theme<DS: DrawSharedImpl>: ThemeControl {
type Config: ThemeConfig;
type Window: Window;
type Draw<'a>: ThemeDraw
where
DS: 'a,
Self: 'a;
fn config(&self) -> std::borrow::Cow<Self::Config>;
fn apply_config(&mut self, config: &Self::Config) -> TkAction;
fn init(&mut self, shared: &mut SharedState<DS>);
fn new_window(&self, dpi_factor: f32) -> Self::Window;
fn update_window(&self, window: &mut Self::Window, dpi_factor: f32);
fn draw<'a>(
&'a self,
draw: DrawIface<'a, DS>,
ev: &'a mut EventState,
window: &'a mut Self::Window,
) -> Self::Draw<'a>;
fn clear_color(&self) -> color::Rgba;
}
#[autoimpl(for<T: trait> Box<T>)]
pub trait Window: 'static {
fn size(&self) -> &dyn ThemeSize;
fn as_any_mut(&mut self) -> &mut dyn Any;
}
impl<T: Theme<DS>, DS: DrawSharedImpl> Theme<DS> for Box<T> {
type Window = <T as Theme<DS>>::Window;
type Config = <T as Theme<DS>>::Config;
type Draw<'a> = <T as Theme<DS>>::Draw<'a>
where
T: 'a;
fn config(&self) -> std::borrow::Cow<Self::Config> {
self.deref().config()
}
fn apply_config(&mut self, config: &Self::Config) -> TkAction {
self.deref_mut().apply_config(config)
}
fn init(&mut self, shared: &mut SharedState<DS>) {
self.deref_mut().init(shared);
}
fn new_window(&self, dpi_factor: f32) -> Self::Window {
self.deref().new_window(dpi_factor)
}
fn update_window(&self, window: &mut Self::Window, dpi_factor: f32) {
self.deref().update_window(window, dpi_factor);
}
fn draw<'a>(
&'a self,
draw: DrawIface<'a, DS>,
ev: &'a mut EventState,
window: &'a mut Self::Window,
) -> Self::Draw<'a> {
self.deref().draw(draw, ev, window)
}
fn clear_color(&self) -> color::Rgba {
self.deref().clear_color()
}
}