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
#![allow(missing_docs)]
use crate::graphics::{Color, DrawContext, Graphic};
use crate::widget::WidgetGraphic;
use super::super::OpenGlRenderPlatform;
pub trait Effect {
fn push(&mut self, ctx: &mut DrawContext<OpenGlRenderPlatform>);
fn pop(&mut self, ctx: &mut DrawContext<OpenGlRenderPlatform>);
}
#[derive(Default)]
pub struct BaseEffect<T: ?Sized> {
backup_params: Option<super::super::DrawParams>,
pub effect: T,
}
pub struct BaseEffectPush<'a, T: Effect + ?Sized> {
inner: &'a mut BaseEffect<T>,
}
impl<'a, T> Graphic<OpenGlRenderPlatform> for BaseEffectPush<'a, T>
where
T: Effect + ?Sized,
{
fn draw(&mut self, ctx: &mut DrawContext<OpenGlRenderPlatform>) {
self.inner.backup_params = Some(ctx.manually_push());
self.inner.effect.push(ctx);
}
}
pub struct BaseEffectPop<'a, T: Effect + ?Sized> {
inner: &'a mut BaseEffect<T>,
}
impl<'a, T> Graphic<OpenGlRenderPlatform> for BaseEffectPop<'a, T>
where
T: Effect + ?Sized,
{
fn draw(&mut self, ctx: &mut DrawContext<OpenGlRenderPlatform>) {
self.inner.effect.pop(ctx);
if let Some(params) = self.inner.backup_params.take() {
ctx.manually_pop(params);
}
}
}
impl<'a, 'b, T> WidgetGraphic<'a, 'b, OpenGlRenderPlatform> for BaseEffect<T>
where
T: 'a + 'b + Effect + ?Sized,
{
type Before = BaseEffectPush<'b, T>;
type After = BaseEffectPop<'a, T>;
fn before_children(&'b mut self) -> Self::Before {
BaseEffectPush { inner: self }
}
fn after_children(&'a mut self) -> Self::After {
BaseEffectPop { inner: self }
}
}
pub struct TintEffect {
color: Color,
}
impl Default for TintEffect {
fn default() -> Self {
TintEffect {
color: Color::WHITE,
}
}
}
impl Effect for TintEffect {
fn push(&mut self, ctx: &mut DrawContext<OpenGlRenderPlatform>) {
ctx.params().tint(self.color);
}
fn pop(&mut self, _ctx: &mut DrawContext<OpenGlRenderPlatform>) {}
}
#[derive(Default)]
pub struct Tint {
inner: BaseEffect<TintEffect>,
}
impl Tint {
pub fn set_tint_color(&mut self, color: Color) {
self.inner.effect.color = color;
}
pub fn current_tint_color(&self) -> Color {
self.inner.effect.color
}
}
impl<'a, 'b> WidgetGraphic<'a, 'b, OpenGlRenderPlatform> for Tint {
type Before = BaseEffectPush<'b, TintEffect>;
type After = BaseEffectPop<'a, TintEffect>;
fn before_children(&'b mut self) -> Self::Before {
self.inner.before_children()
}
fn after_children(&'a mut self) -> Self::After {
self.inner.after_children()
}
}