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
use zaplib::*;
#[derive(Clone, Copy, Default)]
#[repr(C)]
struct BackgroundIns {
quad: QuadIns,
color: Vec4,
radius: f32,
}
static SHADER: Shader = Shader {
build_geom: Some(QuadIns::build_geom),
code_to_concatenate: &[
Cx::STD_SHADER,
QuadIns::SHADER,
code_fragment!(
r#"
instance color: vec4;
instance radius: float;
fn pixel() -> vec4 {
// TODO(JP): Giant hack! We should just be able to call df.box with radius=0
// and then df.fill, but df.box with radius=0 seems totally broken, and even
// using df.rect with df.fill seems to leave a gap around the border..
if radius < 0.001 {
return vec4(color.rgb*color.a, color.a);
}
let df = Df::viewport(pos * rect_size);
df.box(vec2(0.), rect_size, radius);
return df.fill(color);
}"#
),
],
..Shader::DEFAULT
};
#[derive(Default)]
pub struct Background {
area: Area,
radius: f32,
draw_depth: f32,
}
impl Background {
pub fn set_color(&mut self, cx: &mut Cx, color: Vec4) {
let bg = self.area.get_first_mut::<BackgroundIns>(cx);
bg.color = color;
}
#[must_use]
pub fn with_draw_depth(self, draw_depth: f32) -> Self {
Self { draw_depth, ..self }
}
#[must_use]
pub fn with_radius(self, radius: f32) -> Self {
Self { radius, ..self }
}
pub fn begin_draw(&mut self, cx: &mut Cx, width: Width, height: Height, color: Vec4) {
self.draw(cx, Rect::default(), color);
cx.begin_row(width, height);
}
pub fn end_draw(&mut self, cx: &mut Cx) {
let rect = cx.end_row();
let bg = self.area.get_first_mut::<BackgroundIns>(cx);
bg.quad.rect_pos = rect.pos;
bg.quad.rect_size = rect.size;
}
pub fn area(&self) -> Area {
self.area
}
pub fn set_area(&mut self, area: Area) {
self.area = area;
}
pub fn draw(&mut self, cx: &mut Cx, rect: Rect, color: Vec4) {
let data = BackgroundIns { quad: QuadIns::from_rect(rect).with_draw_depth(self.draw_depth), color, radius: self.radius };
self.area = cx.add_instances(&SHADER, &[data]);
}
pub fn draw_with_scroll_sticky(&mut self, cx: &mut Cx, rect: Rect, color: Vec4) {
let data = BackgroundIns { quad: QuadIns::from_rect(rect).with_draw_depth(self.draw_depth), color, radius: self.radius };
self.area = cx.add_instances_with_scroll_sticky(&SHADER, &[data], true, true);
}
}