1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
use std::any::Any;
use std::borrow::Cow;
use std::ops::{Deref, DerefMut};
use super::{Theme, Window};
use kas::draw::{color, DrawIface, DrawSharedImpl, SharedState};
use kas::event::EventState;
use kas::theme::{ThemeControl, ThemeDraw, ThemeSize};
use kas::TkAction;
pub enum MaybeBoxed<'a, B: 'a + ?Sized> {
Borrowed(&'a B),
Boxed(Box<B>),
}
impl<T: ?Sized> AsRef<T> for MaybeBoxed<'_, T> {
fn as_ref(&self) -> &T {
match self {
MaybeBoxed::Borrowed(r) => r,
MaybeBoxed::Boxed(b) => b.as_ref(),
}
}
}
pub trait ThemeDst<DS: DrawSharedImpl>: ThemeControl {
fn config(&self) -> MaybeBoxed<dyn Any>;
fn apply_config(&mut self, config: &dyn Any) -> TkAction;
fn init(&mut self, shared: &mut SharedState<DS>);
fn new_window(&self, dpi_factor: f32) -> Box<dyn Window>;
fn update_window(&self, window: &mut dyn Window, dpi_factor: f32);
fn draw<'a>(
&'a self,
draw: DrawIface<'a, DS>,
ev: &'a mut EventState,
window: &'a mut dyn Window,
) -> Box<dyn ThemeDraw + 'a>;
fn clear_color(&self) -> color::Rgba;
}
impl<DS: DrawSharedImpl, T: Theme<DS>> ThemeDst<DS> for T {
fn config(&self) -> MaybeBoxed<dyn Any> {
match self.config() {
Cow::Borrowed(config) => MaybeBoxed::Borrowed(config),
Cow::Owned(config) => MaybeBoxed::Boxed(Box::new(config)),
}
}
fn apply_config(&mut self, config: &dyn Any) -> TkAction {
self.apply_config(config.downcast_ref().unwrap())
}
fn init(&mut self, shared: &mut SharedState<DS>) {
self.init(shared);
}
fn new_window(&self, dpi_factor: f32) -> Box<dyn Window> {
let window = <T as Theme<DS>>::new_window(self, dpi_factor);
Box::new(window)
}
fn update_window(&self, window: &mut dyn Window, dpi_factor: f32) {
let window = window.as_any_mut().downcast_mut().unwrap();
self.update_window(window, dpi_factor);
}
fn draw<'b>(
&'b self,
draw: DrawIface<'b, DS>,
ev: &'b mut EventState,
window: &'b mut dyn Window,
) -> Box<dyn ThemeDraw + 'b> {
let window = window.as_any_mut().downcast_mut().unwrap();
Box::new(<T as Theme<DS>>::draw(self, draw, ev, window))
}
fn clear_color(&self) -> color::Rgba {
self.clear_color()
}
}
impl Window for Box<dyn Window> {
fn size(&self) -> &dyn ThemeSize {
self.deref().size()
}
fn as_any_mut(&mut self) -> &mut dyn Any {
self.deref_mut().as_any_mut()
}
}