1use gpui::{
15 AnyElement, App, Bounds, Corners, Element, GlobalElementId, InspectorElementId, IntoElement,
16 LayoutId, Pixels, Window, px,
17};
18
19use theme::Theme;
20
21pub const MENU_BLUR: f32 = 44.0;
25
26pub fn material(corner_radius: f32, blur_radius: f32, child: impl IntoElement) -> Material {
29 Material {
30 corner_radius,
31 blur_radius,
32 child: child.into_any_element(),
33 }
34}
35
36pub struct Material {
37 corner_radius: f32,
38 blur_radius: f32,
39 child: AnyElement,
40}
41
42impl Element for Material {
43 type RequestLayoutState = ();
44 type PrepaintState = ();
45
46 fn id(&self) -> Option<gpui::ElementId> {
47 None
48 }
49
50 fn source_location(&self) -> Option<&'static core::panic::Location<'static>> {
51 None
52 }
53
54 fn request_layout(
55 &mut self,
56 _id: Option<&GlobalElementId>,
57 _inspector_id: Option<&InspectorElementId>,
58 window: &mut Window,
59 cx: &mut App,
60 ) -> (LayoutId, ()) {
61 (self.child.request_layout(window, cx), ())
62 }
63
64 fn prepaint(
65 &mut self,
66 _id: Option<&GlobalElementId>,
67 _inspector_id: Option<&InspectorElementId>,
68 _bounds: Bounds<Pixels>,
69 _request_layout: &mut Self::RequestLayoutState,
70 window: &mut Window,
71 cx: &mut App,
72 ) {
73 self.child.prepaint(window, cx);
74 }
75
76 fn paint(
77 &mut self,
78 _id: Option<&GlobalElementId>,
79 _inspector_id: Option<&InspectorElementId>,
80 bounds: Bounds<Pixels>,
81 _request_layout: &mut Self::RequestLayoutState,
82 _prepaint: &mut Self::PrepaintState,
83 window: &mut Window,
84 cx: &mut App,
85 ) {
86 if Theme::of(cx).is_glass() {
87 window.paint_layer(bounds, |window| {
88 window.paint_backdrop_blur(
89 bounds,
90 Corners::all(px(self.corner_radius)),
91 px(self.blur_radius),
92 );
93 self.child.paint(window, cx);
94 });
95 } else {
96 self.child.paint(window, cx);
97 }
98 }
99}
100
101impl IntoElement for Material {
102 type Element = Self;
103
104 fn into_element(self) -> Self::Element {
105 self
106 }
107}
108
109pub fn layered(child: impl IntoElement) -> Layered {
118 Layered {
119 child: child.into_any_element(),
120 }
121}
122
123pub struct Layered {
124 child: AnyElement,
125}
126
127impl Element for Layered {
128 type RequestLayoutState = ();
129 type PrepaintState = ();
130
131 fn id(&self) -> Option<gpui::ElementId> {
132 None
133 }
134
135 fn source_location(&self) -> Option<&'static core::panic::Location<'static>> {
136 None
137 }
138
139 fn request_layout(
140 &mut self,
141 _id: Option<&GlobalElementId>,
142 _inspector_id: Option<&InspectorElementId>,
143 window: &mut Window,
144 cx: &mut App,
145 ) -> (LayoutId, ()) {
146 (self.child.request_layout(window, cx), ())
147 }
148
149 fn prepaint(
150 &mut self,
151 _id: Option<&GlobalElementId>,
152 _inspector_id: Option<&InspectorElementId>,
153 _bounds: Bounds<Pixels>,
154 _request_layout: &mut Self::RequestLayoutState,
155 window: &mut Window,
156 cx: &mut App,
157 ) {
158 self.child.prepaint(window, cx);
159 }
160
161 fn paint(
162 &mut self,
163 _id: Option<&GlobalElementId>,
164 _inspector_id: Option<&InspectorElementId>,
165 bounds: Bounds<Pixels>,
166 _request_layout: &mut Self::RequestLayoutState,
167 _prepaint: &mut Self::PrepaintState,
168 window: &mut Window,
169 cx: &mut App,
170 ) {
171 window.paint_layer(bounds, |window| self.child.paint(window, cx));
172 }
173}
174
175impl IntoElement for Layered {
176 type Element = Self;
177
178 fn into_element(self) -> Self::Element {
179 self
180 }
181}