forked from emilk/egui
/
frame.rs
132 lines (114 loc) · 3.4 KB
/
frame.rs
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
125
126
127
128
129
130
131
132
//! Frame container
use crate::{layers::PaintCmdIdx, paint::*, *};
/// Adds a rectangular frame and background to some `Ui`.
#[derive(Clone, Debug)]
pub struct Frame {
// On each side
pub margin: Vec2,
pub corner_radius: f32,
pub fill: Srgba,
pub stroke: Stroke,
}
impl Frame {
pub fn none() -> Self {
Self {
margin: Vec2::zero(),
corner_radius: 0.0,
fill: Default::default(),
stroke: Stroke::none(),
}
}
pub fn window(style: &Style) -> Self {
Self {
margin: style.spacing.window_padding,
corner_radius: style.visuals.window_corner_radius,
fill: style.visuals.widgets.noninteractive.bg_fill,
stroke: style.visuals.widgets.inactive.bg_stroke, // because we can resize windows
}
}
pub fn menu_bar(style: &Style) -> Self {
Self {
margin: Vec2::splat(1.0),
corner_radius: 0.0,
fill: style.visuals.widgets.noninteractive.bg_fill,
stroke: style.visuals.widgets.noninteractive.bg_stroke,
}
}
pub fn menu(style: &Style) -> Self {
Self {
margin: Vec2::splat(1.0),
corner_radius: 2.0,
fill: style.visuals.widgets.noninteractive.bg_fill,
stroke: style.visuals.widgets.noninteractive.bg_stroke,
}
}
pub fn popup(style: &Style) -> Self {
Self {
margin: style.spacing.window_padding,
corner_radius: 5.0,
fill: style.visuals.widgets.noninteractive.bg_fill,
stroke: style.visuals.widgets.noninteractive.bg_stroke,
}
}
pub fn fill(mut self, fill: Srgba) -> Self {
self.fill = fill;
self
}
pub fn stroke(mut self, stroke: Stroke) -> Self {
self.stroke = stroke;
self
}
}
pub struct Prepared {
pub frame: Frame,
outer_rect_bounds: Rect,
where_to_put_background: PaintCmdIdx,
pub content_ui: Ui,
}
impl Frame {
pub fn begin(self, ui: &mut Ui) -> Prepared {
let outer_rect_bounds = ui.available();
let inner_rect = outer_rect_bounds.shrink2(self.margin);
let where_to_put_background = ui.painter().add(PaintCmd::Noop);
let content_ui = ui.child_ui(inner_rect);
Prepared {
frame: self,
outer_rect_bounds,
where_to_put_background,
content_ui,
}
}
pub fn show<R>(self, ui: &mut Ui, add_contents: impl FnOnce(&mut Ui) -> R) -> R {
let mut prepared = self.begin(ui);
let ret = add_contents(&mut prepared.content_ui);
prepared.end(ui);
ret
}
}
impl Prepared {
pub fn outer_rect(&self) -> Rect {
Rect::from_min_max(
self.outer_rect_bounds.min,
self.content_ui.child_bounds().max + self.frame.margin,
)
}
pub fn end(self, ui: &mut Ui) -> Rect {
let outer_rect = self.outer_rect();
let Prepared {
frame,
where_to_put_background,
..
} = self;
ui.painter().set(
where_to_put_background,
PaintCmd::Rect {
corner_radius: frame.corner_radius,
fill: frame.fill,
stroke: frame.stroke,
rect: outer_rect,
},
);
ui.allocate_space(outer_rect.size());
outer_rect
}
}