History

WIP - Next: implement Element derive macro

Nathan Sobo committed 3 years ago

Commit dfeb7021 parent 6d2b27621 files · +980 −119Browse files

Unified · Split

21 files
  1. Cargo.lock +10 −1
  2. Cargo.toml +1 −0
  3. crates/gpui/src/geometry.rs +18 −14
  4. crates/gpui3/Cargo.toml +1 −1
  5. crates/gpui3/src/element.rs +9 −0
  6. crates/gpui3/src/elements/div.rs +3 −1
  7. crates/gpui3/src/elements/img.rs +3 −1
  8. crates/gpui3/src/elements/svg.rs +3 −1
  9. crates/gpui3/src/geometry.rs +3 −3
  10. crates/gpui3/src/gpui3.rs +2 −0
  11. crates/gpui3/src/style.rs +4 −4
  12. crates/gpui3/src/style_helpers.rs +288 −0
  13. crates/gpui3_macros/Cargo.toml +14 −0
  14. crates/gpui3_macros/src/derive_element.rs +93 −0
  15. crates/gpui3_macros/src/derive_into_element.rs +69 −0
  16. crates/gpui3_macros/src/gpui3_macros.rs +20 −0
  17. crates/gpui3_macros/src/style_helpers.rs +332 −0
  18. crates/storybook2/src/collab_panel.rs +8 −7
  19. crates/storybook2/src/storybook2.rs +18 −16
  20. crates/storybook2/src/theme.rs +30 −31
  21. crates/storybook2/src/workspace.rs +51 −39
Cargo.lock+10−1
@@ -3363,7 +3363,7 @@ dependencies = [ · 3362 unmodified lines
3363 "font-kit",3363 "font-kit",
3364 "foreign-types 0.3.2",3364 "foreign-types 0.3.2",
3365 "futures 0.3.28",3365 "futures 0.3.28",
3366 "gpui2_macros",3366 "gpui3_macros",
3367 "gpui_macros",3367 "gpui_macros",
3368 "image",3368 "image",
3369 "itertools",3369 "itertools",
@@ -3405,6 +3405,15 @@ dependencies = [ · 35 unmodified lines
3405 "wgpu",3405 "wgpu",
3406]3406]
3407 3407
3408[[package]]
3409name = "gpui3_macros"
3410version = "0.1.0"
3411dependencies = [
3412 "proc-macro2",
3413 "quote",
3414 "syn 1.0.109",
3415]
3416
3408[[package]]3417[[package]]
3409name = "gpui_macros"3418name = "gpui_macros"
3410version = "0.1.0"3419version = "0.1.0"
Cargo.toml+1−0
@@ -36,6 +36,7 @@ members = [ · 35 unmodified lines
36 "crates/gpui2",36 "crates/gpui2",
37 "crates/gpui2_macros",37 "crates/gpui2_macros",
38 "crates/gpui3",38 "crates/gpui3",
39 "crates/gpui3_macros",
39 "crates/install_cli",40 "crates/install_cli",
40 "crates/journal",41 "crates/journal",
41 "crates/language",42 "crates/language",
crates/gpui/src/geometry.rs+18−14
@@ -203,8 +203,8 @@ where · 202 unmodified lines
203impl Size<DefiniteLength> {203impl Size<DefiniteLength> {
204 pub fn zero() -> Self {204 pub fn zero() -> Self {
205 Self {205 Self {
206 width: pixels(0.),206 width: px(0.),
207 height: pixels(0.),207 height: px(0.),
208 }208 }
209 }209 }
210 210
@@ -256,10 +256,10 @@ impl Edges<Length> { · 45 unmodified lines
256 256
257 pub fn zero() -> Self {257 pub fn zero() -> Self {
258 Self {258 Self {
259 top: pixels(0.),259 top: px(0.),
260 right: pixels(0.),260 right: px(0.),
261 bottom: pixels(0.),261 bottom: px(0.),
262 left: pixels(0.),262 left: px(0.),
263 }263 }
264 }264 }
265 265
@@ -279,10 +279,10 @@ impl Edges<Length> { · 13 unmodified lines
279impl Edges<DefiniteLength> {279impl Edges<DefiniteLength> {
280 pub fn zero() -> Self {280 pub fn zero() -> Self {
281 Self {281 Self {
282 top: pixels(0.),282 top: px(0.),
283 right: pixels(0.),283 right: px(0.),
284 bottom: pixels(0.),284 bottom: px(0.),
285 left: pixels(0.),285 left: px(0.),
286 }286 }
287 }287 }
288 288
@@ -299,10 +299,10 @@ impl Edges<DefiniteLength> { · 10 unmodified lines
299impl Edges<AbsoluteLength> {299impl Edges<AbsoluteLength> {
300 pub fn zero() -> Self {300 pub fn zero() -> Self {
301 Self {301 Self {
302 top: pixels(0.),302 top: px(0.),
303 right: pixels(0.),303 right: px(0.),
304 bottom: pixels(0.),304 bottom: px(0.),
305 left: pixels(0.),305 left: px(0.),
306 }306 }
307 }307 }
308 308
@@ -436,6 +436,10 @@ pub fn rems<T: From<AbsoluteLength>>(rems: f32) -> T { · 127 unmodified lines
436 AbsoluteLength::Rems(rems).into()436 AbsoluteLength::Rems(rems).into()
437}437}
438 438
439pub fn px<T: From<AbsoluteLength>>(pixels: f32) -> T {
440 AbsoluteLength::Pixels(pixels).into()
441}
442
439pub fn pixels<T: From<AbsoluteLength>>(pixels: f32) -> T {443pub fn pixels<T: From<AbsoluteLength>>(pixels: f32) -> T {
440 AbsoluteLength::Pixels(pixels).into()444 AbsoluteLength::Pixels(pixels).into()
441}445}
crates/gpui3/Cargo.toml+1−1
@@ -16,7 +16,7 @@ doctest = false · 15 unmodified lines
16[dependencies]16[dependencies]
17collections = { path = "../collections" }17collections = { path = "../collections" }
18gpui_macros = { path = "../gpui_macros" }18gpui_macros = { path = "../gpui_macros" }
19gpui2_macros = { path = "../gpui2_macros" }19gpui3_macros = { path = "../gpui3_macros" }
20util = { path = "../util" }20util = { path = "../util" }
21sum_tree = { path = "../sum_tree" }21sum_tree = { path = "../sum_tree" }
22sqlez = { path = "../sqlez" }22sqlez = { path = "../sqlez" }
crates/gpui3/src/element.rs+9−0
@@ -32,6 +32,15 @@ pub trait ParentElement<S> { · 31 unmodified lines
32 self.children_mut().push(child.into_any());32 self.children_mut().push(child.into_any());
33 self33 self
34 }34 }
35
36 fn children(mut self, iter: impl IntoIterator<Item = impl IntoAnyElement<S>>) -> Self
37 where
38 Self: Sized,
39 {
40 self.children_mut()
41 .extend(iter.into_iter().map(|item| item.into_any()));
42 self
43 }
35}44}
36 45
37trait ElementObject<S> {46trait ElementObject<S> {
crates/gpui3/src/elements/div.rs+3−1
@@ -1,6 +1,6 @@
1use crate::{1use crate::{
2 AnyElement, Bounds, Element, Layout, LayoutId, Overflow, ParentElement, Pixels, Point,2 AnyElement, Bounds, Element, Layout, LayoutId, Overflow, ParentElement, Pixels, Point,
3 Refineable, RefinementCascade, Result, Style, Styled, ViewContext,3 Refineable, RefinementCascade, Result, Style, StyleHelpers, Styled, ViewContext,
4};4};
5use smallvec::SmallVec;5use smallvec::SmallVec;
6use std::{cell::Cell, rc::Rc};6use std::{cell::Cell, rc::Rc};
@@ -257,6 +257,8 @@ impl<V> Styled for Div<V> { · 250 unmodified lines
257 }257 }
258}258}
259 259
260impl<V> StyleHelpers for Div<V> {}
261
260// impl<V> Interactive<V> for Div<V> {262// impl<V> Interactive<V> for Div<V> {
261// fn interaction_handlers(&mut self) -> &mut InteractionHandlers<V> {263// fn interaction_handlers(&mut self) -> &mut InteractionHandlers<V> {
262// &mut self.handlers264// &mut self.handlers
crates/gpui3/src/elements/img.rs+3−1
@@ -1,4 +1,4 @@
1use crate::{Element, Layout, LayoutId, Result, Style, Styled};1use crate::{Element, Layout, LayoutId, Result, Style, StyleHelpers, Styled};
2use refineable::RefinementCascade;2use refineable::RefinementCascade;
3use std::marker::PhantomData;3use std::marker::PhantomData;
4use util::arc_cow::ArcCow;4use util::arc_cow::ArcCow;
@@ -98,3 +98,5 @@ impl<S> Styled for Img<S> { · 93 unmodified lines
98 self.style.base()98 self.style.base()
99 }99 }
100}100}
101
102impl<S> StyleHelpers for Img<S> {}
crates/gpui3/src/elements/svg.rs+3−1
@@ -1,4 +1,4 @@
1use crate::{Element, Layout, LayoutId, Result, Style, Styled};1use crate::{Element, Layout, LayoutId, Result, Style, StyleHelpers, Styled};
2use refineable::RefinementCascade;2use refineable::RefinementCascade;
3use std::{borrow::Cow, marker::PhantomData};3use std::{borrow::Cow, marker::PhantomData};
4 4
@@ -77,3 +77,5 @@ impl<S> Styled for Svg<S> { · 72 unmodified lines
77 self.style.base()77 self.style.base()
78 }78 }
79}79}
80
81impl<S> StyleHelpers for Svg<S> {}
crates/gpui3/src/geometry.rs+3−3
@@ -100,8 +100,8 @@ impl From<Size<Option<Pixels>>> for Size<Option<f32>> { · 99 unmodified lines
100impl Size<Length> {100impl Size<Length> {
101 pub fn full() -> Self {101 pub fn full() -> Self {
102 Self {102 Self {
103 width: relative(1.),103 width: relative(1.).into(),
104 height: relative(1.),104 height: relative(1.).into(),
105 }105 }
106 }106 }
107}107}
@@ -410,7 +410,7 @@ impl Debug for Length { · 302 unmodified lines
410 }410 }
411}411}
412 412
413pub fn relative<T: From<DefiniteLength>>(fraction: f32) -> T {413pub fn relative(fraction: f32) -> DefiniteLength {
414 DefiniteLength::Fraction(fraction).into()414 DefiniteLength::Fraction(fraction).into()
415}415}
416 416
crates/gpui3/src/gpui3.rs+2−0
@@ -8,6 +8,7 @@ mod platform; · 7 unmodified lines
8mod renderer;8mod renderer;
9mod scene;9mod scene;
10mod style;10mod style;
11mod style_helpers;
11mod styled;12mod styled;
12mod taffy;13mod taffy;
13mod text_system;14mod text_system;
@@ -30,6 +31,7 @@ pub use smallvec; · 16 unmodified lines
30pub use smol::Timer;31pub use smol::Timer;
31use std::ops::{Deref, DerefMut};32use std::ops::{Deref, DerefMut};
32pub use style::*;33pub use style::*;
34pub use style_helpers::*;
33pub use styled::*;35pub use styled::*;
34use taffy::TaffyLayoutEngine;36use taffy::TaffyLayoutEngine;
35pub use taffy::{AvailableSpace, LayoutId};37pub use taffy::{AvailableSpace, LayoutId};
crates/gpui3/src/style.rs+4−4
@@ -289,10 +289,10 @@ impl From<Hsla> for Fill { · 288 unmodified lines
289#[derive(Clone, Refineable, Default, Debug)]289#[derive(Clone, Refineable, Default, Debug)]
290#[refineable(debug)]290#[refineable(debug)]
291pub struct CornerRadii {291pub struct CornerRadii {
292 top_left: AbsoluteLength,292 pub top_left: AbsoluteLength,
293 top_right: AbsoluteLength,293 pub top_right: AbsoluteLength,
294 bottom_left: AbsoluteLength,294 pub bottom_left: AbsoluteLength,
295 bottom_right: AbsoluteLength,295 pub bottom_right: AbsoluteLength,
296}296}
297 297
298impl From<TextStyle> for HighlightStyle {298impl From<TextStyle> for HighlightStyle {
crates/gpui3/src/style_helpers.rs+288−0
@@ -0,0 +1,288 @@
1use crate::{
2 self as gpui2, relative, rems, AlignItems, Display, Fill, FlexDirection, Hsla, JustifyContent,
3 Length, Position, SharedString, Style, Styled,
4};
5
6pub trait StyleHelpers: Styled<Style = Style> {
7 gpui3_macros::style_helpers!();
8
9 fn h(mut self, height: Length) -> Self
10 where
11 Self: Sized,
12 {
13 self.declared_style().size.height = Some(height);
14 self
15 }
16
17 /// size_{n}: Sets width & height to {n}
18 ///
19 /// Example:
20 /// size_1: Sets width & height to 1
21 fn size(mut self, size: Length) -> Self
22 where
23 Self: Sized,
24 {
25 self.declared_style().size.height = Some(size);
26 self.declared_style().size.width = Some(size);
27 self
28 }
29
30 fn full(mut self) -> Self
31 where
32 Self: Sized,
33 {
34 self.declared_style().size.width = Some(relative(1.).into());
35 self.declared_style().size.height = Some(relative(1.).into());
36 self
37 }
38
39 fn relative(mut self) -> Self
40 where
41 Self: Sized,
42 {
43 self.declared_style().position = Some(Position::Relative);
44 self
45 }
46
47 fn absolute(mut self) -> Self
48 where
49 Self: Sized,
50 {
51 self.declared_style().position = Some(Position::Absolute);
52 self
53 }
54
55 fn block(mut self) -> Self
56 where
57 Self: Sized,
58 {
59 self.declared_style().display = Some(Display::Block);
60 self
61 }
62
63 fn flex(mut self) -> Self
64 where
65 Self: Sized,
66 {
67 self.declared_style().display = Some(Display::Flex);
68 self
69 }
70
71 fn flex_col(mut self) -> Self
72 where
73 Self: Sized,
74 {
75 self.declared_style().flex_direction = Some(FlexDirection::Column);
76 self
77 }
78
79 fn flex_row(mut self) -> Self
80 where
81 Self: Sized,
82 {
83 self.declared_style().flex_direction = Some(FlexDirection::Row);
84 self
85 }
86
87 fn flex_1(mut self) -> Self
88 where
89 Self: Sized,
90 {
91 self.declared_style().flex_grow = Some(1.);
92 self.declared_style().flex_shrink = Some(1.);
93 self.declared_style().flex_basis = Some(relative(0.).into());
94 self
95 }
96
97 fn flex_auto(mut self) -> Self
98 where
99 Self: Sized,
100 {
101 self.declared_style().flex_grow = Some(1.);
102 self.declared_style().flex_shrink = Some(1.);
103 self.declared_style().flex_basis = Some(Length::Auto);
104 self
105 }
106
107 fn flex_initial(mut self) -> Self
108 where
109 Self: Sized,
110 {
111 self.declared_style().flex_grow = Some(0.);
112 self.declared_style().flex_shrink = Some(1.);
113 self.declared_style().flex_basis = Some(Length::Auto);
114 self
115 }
116
117 fn flex_none(mut self) -> Self
118 where
119 Self: Sized,
120 {
121 self.declared_style().flex_grow = Some(0.);
122 self.declared_style().flex_shrink = Some(0.);
123 self
124 }
125
126 fn grow(mut self) -> Self
127 where
128 Self: Sized,
129 {
130 self.declared_style().flex_grow = Some(1.);
131 self
132 }
133
134 fn items_start(mut self) -> Self
135 where
136 Self: Sized,
137 {
138 self.declared_style().align_items = Some(AlignItems::FlexStart);
139 self
140 }
141
142 fn items_end(mut self) -> Self
143 where
144 Self: Sized,
145 {
146 self.declared_style().align_items = Some(AlignItems::FlexEnd);
147 self
148 }
149
150 fn items_center(mut self) -> Self
151 where
152 Self: Sized,
153 {
154 self.declared_style().align_items = Some(AlignItems::Center);
155 self
156 }
157
158 fn justify_between(mut self) -> Self
159 where
160 Self: Sized,
161 {
162 self.declared_style().justify_content = Some(JustifyContent::SpaceBetween);
163 self
164 }
165
166 fn justify_center(mut self) -> Self
167 where
168 Self: Sized,
169 {
170 self.declared_style().justify_content = Some(JustifyContent::Center);
171 self
172 }
173
174 fn justify_start(mut self) -> Self
175 where
176 Self: Sized,
177 {
178 self.declared_style().justify_content = Some(JustifyContent::Start);
179 self
180 }
181
182 fn justify_end(mut self) -> Self
183 where
184 Self: Sized,
185 {
186 self.declared_style().justify_content = Some(JustifyContent::End);
187 self
188 }
189
190 fn justify_around(mut self) -> Self
191 where
192 Self: Sized,
193 {
194 self.declared_style().justify_content = Some(JustifyContent::SpaceAround);
195 self
196 }
197
198 fn fill<F>(mut self, fill: F) -> Self
199 where
200 F: Into<Fill>,
201 Self: Sized,
202 {
203 self.declared_style().fill = Some(fill.into());
204 self
205 }
206
207 fn border_color<C>(mut self, border_color: C) -> Self
208 where
209 C: Into<Hsla>,
210 Self: Sized,
211 {
212 self.declared_style().border_color = Some(border_color.into());
213 self
214 }
215
216 fn text_color<C>(mut self, color: C) -> Self
217 where
218 C: Into<Hsla>,
219 Self: Sized,
220 {
221 self.declared_style().text_color = Some(color.into());
222 self
223 }
224
225 fn text_xs(mut self) -> Self
226 where
227 Self: Sized,
228 {
229 self.declared_style().font_size = Some(rems(0.75));
230 self
231 }
232
233 fn text_sm(mut self) -> Self
234 where
235 Self: Sized,
236 {
237 self.declared_style().font_size = Some(rems(0.875));
238 self
239 }
240
241 fn text_base(mut self) -> Self
242 where
243 Self: Sized,
244 {
245 self.declared_style().font_size = Some(rems(1.0));
246 self
247 }
248
249 fn text_lg(mut self) -> Self
250 where
251 Self: Sized,
252 {
253 self.declared_style().font_size = Some(rems(1.125));
254 self
255 }
256
257 fn text_xl(mut self) -> Self
258 where
259 Self: Sized,
260 {
261 self.declared_style().font_size = Some(rems(1.25));
262 self
263 }
264
265 fn text_2xl(mut self) -> Self
266 where
267 Self: Sized,
268 {
269 self.declared_style().font_size = Some(rems(1.5));
270 self
271 }
272
273 fn text_3xl(mut self) -> Self
274 where
275 Self: Sized,
276 {
277 self.declared_style().font_size = Some(rems(1.875));
278 self
279 }
280
281 fn font(mut self, family_name: impl Into<SharedString>) -> Self
282 where
283 Self: Sized,
284 {
285 self.declared_style().font_family = Some(family_name.into());
286 self
287 }
288}
crates/gpui3_macros/Cargo.toml+14−0
@@ -0,0 +1,14 @@
1[package]
2name = "gpui3_macros"
3version = "0.1.0"
4edition = "2021"
5publish = false
6
7[lib]
8path = "src/gpui3_macros.rs"
9proc-macro = true
10
11[dependencies]
12syn = "1.0.72"
13quote = "1.0.9"
14proc-macro2 = "1.0.66"
crates/gpui3_macros/src/derive_element.rs+93−0
@@ -0,0 +1,93 @@
1use proc_macro::TokenStream;
2use proc_macro2::Ident;
3use quote::quote;
4use syn::{parse_macro_input, parse_quote, DeriveInput, GenericParam, Generics};
5
6use crate::derive_into_element::impl_into_element;
7
8pub fn derive_element(input: TokenStream) -> TokenStream {
9 let ast = parse_macro_input!(input as DeriveInput);
10 let type_name = ast.ident;
11 let placeholder_view_generics: Generics = parse_quote! { <V: 'static> };
12
13 let (impl_generics, type_generics, where_clause, view_type_name, lifetimes) =
14 if let Some(first_type_param) = ast.generics.params.iter().find_map(|param| {
15 if let GenericParam::Type(type_param) = param {
16 Some(type_param.ident.clone())
17 } else {
18 None
19 }
20 }) {
21 let mut lifetimes = vec![];
22 for param in ast.generics.params.iter() {
23 if let GenericParam::Lifetime(lifetime_def) = param {
24 lifetimes.push(lifetime_def.lifetime.clone());
25 }
26 }
27 let generics = ast.generics.split_for_impl();
28 (
29 generics.0,
30 Some(generics.1),
31 generics.2,
32 first_type_param,
33 lifetimes,
34 )
35 } else {
36 let generics = placeholder_view_generics.split_for_impl();
37 let placeholder_view_type_name: Ident = parse_quote! { V };
38 (
39 generics.0,
40 None,
41 generics.2,
42 placeholder_view_type_name,
43 vec![],
44 )
45 };
46
47 let lifetimes = if !lifetimes.is_empty() {
48 quote! { <#(#lifetimes),*> }
49 } else {
50 quote! {}
51 };
52
53 let impl_into_element = impl_into_element(
54 &impl_generics,
55 &view_type_name,
56 &type_name,
57 &type_generics,
58 &where_clause,
59 );
60
61 let gen = quote! {
62 impl #impl_generics gpui2::element::Element<#view_type_name> for #type_name #type_generics
63 #where_clause
64 {
65 type PaintState = gpui2::element::AnyElement<#view_type_name #lifetimes>;
66
67 fn layout(
68 &mut self,
69 view: &mut V,
70 cx: &mut gpui2::ViewContext<V>,
71 ) -> anyhow::Result<(gpui2::element::LayoutId, Self::PaintState)> {
72 let mut rendered_element = self.render(view, cx).into_element().into_any();
73 let layout_id = rendered_element.layout(view, cx)?;
74 Ok((layout_id, rendered_element))
75 }
76
77 fn paint(
78 &mut self,
79 view: &mut V,
80 parent_origin: gpui2::Vector2F,
81 _: &gpui2::element::Layout,
82 rendered_element: &mut Self::PaintState,
83 cx: &mut gpui2::ViewContext<V>,
84 ) {
85 rendered_element.paint(view, parent_origin, cx);
86 }
87 }
88
89 #impl_into_element
90 };
91
92 gen.into()
93}
crates/gpui3_macros/src/derive_into_element.rs+69−0
@@ -0,0 +1,69 @@
1use proc_macro::TokenStream;
2use quote::quote;
3use syn::{
4 parse_macro_input, parse_quote, DeriveInput, GenericParam, Generics, Ident, WhereClause,
5};
6
7pub fn derive_into_element(input: TokenStream) -> TokenStream {
8 let ast = parse_macro_input!(input as DeriveInput);
9 let type_name = ast.ident;
10
11 let placeholder_view_generics: Generics = parse_quote! { <V: 'static> };
12 let placeholder_view_type_name: Ident = parse_quote! { V };
13 let view_type_name: Ident;
14 let impl_generics: syn::ImplGenerics<'_>;
15 let type_generics: Option<syn::TypeGenerics<'_>>;
16 let where_clause: Option<&'_ WhereClause>;
17
18 match ast.generics.params.iter().find_map(|param| {
19 if let GenericParam::Type(type_param) = param {
20 Some(type_param.ident.clone())
21 } else {
22 None
23 }
24 }) {
25 Some(type_name) => {
26 view_type_name = type_name;
27 let generics = ast.generics.split_for_impl();
28 impl_generics = generics.0;
29 type_generics = Some(generics.1);
30 where_clause = generics.2;
31 }
32 _ => {
33 view_type_name = placeholder_view_type_name;
34 let generics = placeholder_view_generics.split_for_impl();
35 impl_generics = generics.0;
36 type_generics = None;
37 where_clause = generics.2;
38 }
39 }
40
41 impl_into_element(
42 &impl_generics,
43 &view_type_name,
44 &type_name,
45 &type_generics,
46 &where_clause,
47 )
48 .into()
49}
50
51pub fn impl_into_element(
52 impl_generics: &syn::ImplGenerics<'_>,
53 view_type_name: &Ident,
54 type_name: &Ident,
55 type_generics: &Option<syn::TypeGenerics<'_>>,
56 where_clause: &Option<&WhereClause>,
57) -> proc_macro2::TokenStream {
58 quote! {
59 impl #impl_generics gpui2::element::IntoElement<#view_type_name> for #type_name #type_generics
60 #where_clause
61 {
62 type Element = Self;
63
64 fn into_element(self) -> Self {
65 self
66 }
67 }
68 }
69}
crates/gpui3_macros/src/gpui3_macros.rs+20−0
@@ -0,0 +1,20 @@
1use proc_macro::TokenStream;
2
3mod derive_element;
4mod derive_into_element;
5mod style_helpers;
6
7#[proc_macro]
8pub fn style_helpers(args: TokenStream) -> TokenStream {
9 style_helpers::style_helpers(args)
10}
11
12#[proc_macro_derive(Element, attributes(element_crate))]
13pub fn derive_element(input: TokenStream) -> TokenStream {
14 derive_element::derive_element(input)
15}
16
17#[proc_macro_derive(IntoElement, attributes(element_crate))]
18pub fn derive_into_element(input: TokenStream) -> TokenStream {
19 derive_into_element::derive_into_element(input)
20}
crates/gpui3_macros/src/style_helpers.rs+332−0
@@ -0,0 +1,332 @@
1use proc_macro::TokenStream;
2use proc_macro2::TokenStream as TokenStream2;
3use quote::{format_ident, quote};
4use syn::{
5 parse::{Parse, ParseStream, Result},
6 parse_macro_input,
7};
8
9struct StyleableMacroInput;
10
11impl Parse for StyleableMacroInput {
12 fn parse(_input: ParseStream) -> Result<Self> {
13 Ok(StyleableMacroInput)
14 }
15}
16
17pub fn style_helpers(input: TokenStream) -> TokenStream {
18 let _ = parse_macro_input!(input as StyleableMacroInput);
19 let methods = generate_methods();
20
21 for method in &methods {
22 println!("method: {}", method);
23 }
24
25 let output = quote! {
26 #(#methods)*
27 };
28
29 output.into()
30}
31
32fn generate_methods() -> Vec<TokenStream2> {
33 let mut methods = Vec::new();
34
35 for (prefix, auto_allowed, fields) in box_prefixes() {
36 for (suffix, length_tokens) in box_suffixes() {
37 if auto_allowed || suffix != "auto" {
38 let method = generate_method(prefix, suffix, &fields, length_tokens);
39 methods.push(method);
40 }
41 }
42 }
43
44 for (prefix, fields) in corner_prefixes() {
45 for (suffix, radius_tokens) in corner_suffixes() {
46 let method = generate_method(prefix, suffix, &fields, radius_tokens);
47 methods.push(method);
48 }
49 }
50
51 for (prefix, fields) in border_prefixes() {
52 for (suffix, width_tokens) in border_suffixes() {
53 let method = generate_method(prefix, suffix, &fields, width_tokens);
54 methods.push(method);
55 }
56 }
57
58 methods
59}
60
61fn generate_method(
62 prefix: &'static str,
63 suffix: &'static str,
64 fields: &Vec<TokenStream2>,
65 length_tokens: TokenStream2,
66) -> TokenStream2 {
67 let method_name = if suffix.is_empty() {
68 format_ident!("{}", prefix)
69 } else {
70 format_ident!("{}_{}", prefix, suffix)
71 };
72
73 let field_assignments = fields
74 .iter()
75 .map(|field_tokens| {
76 quote! {
77 style.#field_tokens = Some(gpui2::#length_tokens.into());
78 }
79 })
80 .collect::<Vec<_>>();
81
82 let method = quote! {
83 fn #method_name(mut self) -> Self where Self: std::marker::Sized {
84 let style = self.declared_style();
85 #(#field_assignments)*
86 self
87 }
88 };
89
90 method
91}
92
93fn box_prefixes() -> Vec<(&'static str, bool, Vec<TokenStream2>)> {
94 vec![
95 ("w", true, vec![quote! { size.width }]),
96 ("h", true, vec![quote! { size.height }]),
97 (
98 "size",
99 true,
100 vec![quote! {size.width}, quote! {size.height}],
101 ),
102 ("min_w", false, vec![quote! { min_size.width }]),
103 ("min_h", false, vec![quote! { min_size.height }]),
104 ("max_w", false, vec![quote! { max_size.width }]),
105 ("max_h", false, vec![quote! { max_size.height }]),
106 (
107 "m",
108 true,
109 vec![
110 quote! { margin.top },
111 quote! { margin.bottom },
112 quote! { margin.left },
113 quote! { margin.right },
114 ],
115 ),
116 ("mt", true, vec![quote! { margin.top }]),
117 ("mb", true, vec![quote! { margin.bottom }]),
118 (
119 "my",
120 true,
121 vec![quote! { margin.top }, quote! { margin.bottom }],
122 ),
123 (
124 "mx",
125 true,
126 vec![quote! { margin.left }, quote! { margin.right }],
127 ),
128 ("ml", true, vec![quote! { margin.left }]),
129 ("mr", true, vec![quote! { margin.right }]),
130 (
131 "p",
132 false,
133 vec![
134 quote! { padding.top },
135 quote! { padding.bottom },
136 quote! { padding.left },
137 quote! { padding.right },
138 ],
139 ),
140 ("pt", false, vec![quote! { padding.top }]),
141 ("pb", false, vec![quote! { padding.bottom }]),
142 (
143 "px",
144 false,
145 vec![quote! { padding.left }, quote! { padding.right }],
146 ),
147 (
148 "py",
149 false,
150 vec![quote! { padding.top }, quote! { padding.bottom }],
151 ),
152 ("pl", false, vec![quote! { padding.left }]),
153 ("pr", false, vec![quote! { padding.right }]),
154 ("top", true, vec![quote! { inset.top }]),
155 ("bottom", true, vec![quote! { inset.bottom }]),
156 ("left", true, vec![quote! { inset.left }]),
157 ("right", true, vec![quote! { inset.right }]),
158 (
159 "gap",
160 false,
161 vec![quote! { gap.width }, quote! { gap.height }],
162 ),
163 ("gap_x", false, vec![quote! { gap.width }]),
164 ("gap_y", false, vec![quote! { gap.height }]),
165 ]
166}
167
168fn box_suffixes() -> Vec<(&'static str, TokenStream2)> {
169 vec![
170 ("0", quote! { px(0.) }),
171 ("0p5", quote! { rems(0.125) }),
172 ("1", quote! { rems(0.25) }),
173 ("1p5", quote! { rems(0.375) }),
174 ("2", quote! { rems(0.5) }),
175 ("2p5", quote! { rems(0.625) }),
176 ("3", quote! { rems(0.75) }),
177 ("3p5", quote! { rems(0.875) }),
178 ("4", quote! { rems(1.) }),
179 ("5", quote! { rems(1.25) }),
180 ("6", quote! { rems(1.5) }),
181 ("7", quote! { rems(1.75) }),
182 ("8", quote! { rems(2.0) }),
183 ("9", quote! { rems(2.25) }),
184 ("10", quote! { rems(2.5) }),
185 ("11", quote! { rems(2.75) }),
186 ("12", quote! { rems(3.) }),
187 ("16", quote! { rems(4.) }),
188 ("20", quote! { rems(5.) }),
189 ("24", quote! { rems(6.) }),
190 ("32", quote! { rems(8.) }),
191 ("40", quote! { rems(10.) }),
192 ("48", quote! { rems(12.) }),
193 ("56", quote! { rems(14.) }),
194 ("64", quote! { rems(16.) }),
195 ("72", quote! { rems(18.) }),
196 ("80", quote! { rems(20.) }),
197 ("96", quote! { rems(24.) }),
198 ("auto", quote! { auto() }),
199 ("px", quote! { px(1.) }),
200 ("full", quote! { relative(1.) }),
201 ("1_2", quote! { relative(0.5) }),
202 ("1_3", quote! { relative(1./3.) }),
203 ("2_3", quote! { relative(2./3.) }),
204 ("1_4", quote! { relative(0.25) }),
205 ("2_4", quote! { relative(0.5) }),
206 ("3_4", quote! { relative(0.75) }),
207 ("1_5", quote! { relative(0.2) }),
208 ("2_5", quote! { relative(0.4) }),
209 ("3_5", quote! { relative(0.6) }),
210 ("4_5", quote! { relative(0.8) }),
211 ("1_6", quote! { relative(1./6.) }),
212 ("5_6", quote! { relative(5./6.) }),
213 ("1_12", quote! { relative(1./12.) }),
214 // ("screen_50", quote! { DefiniteLength::Vh(50.0) }),
215 // ("screen_75", quote! { DefiniteLength::Vh(75.0) }),
216 // ("screen", quote! { DefiniteLength::Vh(100.0) }),
217 ]
218}
219
220fn corner_prefixes() -> Vec<(&'static str, Vec<TokenStream2>)> {
221 vec![
222 (
223 "rounded",
224 vec![
225 quote! { corner_radii.top_left },
226 quote! { corner_radii.top_right },
227 quote! { corner_radii.bottom_right },
228 quote! { corner_radii.bottom_left },
229 ],
230 ),
231 (
232 "rounded_t",
233 vec![
234 quote! { corner_radii.top_left },
235 quote! { corner_radii.top_right },
236 ],
237 ),
238 (
239 "rounded_b",
240 vec![
241 quote! { corner_radii.bottom_left },
242 quote! { corner_radii.bottom_right },
243 ],
244 ),
245 (
246 "rounded_r",
247 vec![
248 quote! { corner_radii.top_right },
249 quote! { corner_radii.bottom_right },
250 ],
251 ),
252 (
253 "rounded_l",
254 vec![
255 quote! { corner_radii.top_left },
256 quote! { corner_radii.bottom_left },
257 ],
258 ),
259 ("rounded_tl", vec![quote! { corner_radii.top_left }]),
260 ("rounded_tr", vec![quote! { corner_radii.top_right }]),
261 ("rounded_bl", vec![quote! { corner_radii.bottom_left }]),
262 ("rounded_br", vec![quote! { corner_radii.bottom_right }]),
263 ]
264}
265
266fn corner_suffixes() -> Vec<(&'static str, TokenStream2)> {
267 vec![
268 ("none", quote! { px(0.) }),
269 ("sm", quote! { rems(0.125) }),
270 ("md", quote! { rems(0.25) }),
271 ("lg", quote! { rems(0.5) }),
272 ("xl", quote! { rems(0.75) }),
273 ("2xl", quote! { rems(1.) }),
274 ("3xl", quote! { rems(1.5) }),
275 ("full", quote! { px(9999.) }),
276 ]
277}
278
279fn border_prefixes() -> Vec<(&'static str, Vec<TokenStream2>)> {
280 vec![
281 (
282 "border",
283 vec![
284 quote! { border_widths.top },
285 quote! { border_widths.right },
286 quote! { border_widths.bottom },
287 quote! { border_widths.left },
288 ],
289 ),
290 ("border_t", vec![quote! { border_widths.top }]),
291 ("border_b", vec![quote! { border_widths.bottom }]),
292 ("border_r", vec![quote! { border_widths.right }]),
293 ("border_l", vec![quote! { border_widths.left }]),
294 (
295 "border_x",
296 vec![
297 quote! { border_widths.left },
298 quote! { border_widths.right },
299 ],
300 ),
301 (
302 "border_y",
303 vec![
304 quote! { border_widths.top },
305 quote! { border_widths.bottom },
306 ],
307 ),
308 ]
309}
310
311fn border_suffixes() -> Vec<(&'static str, TokenStream2)> {
312 vec![
313 ("", quote! { px(1.) }),
314 ("0", quote! { px(0.) }),
315 ("1", quote! { px(1.) }),
316 ("2", quote! { px(2.) }),
317 ("3", quote! { px(3.) }),
318 ("4", quote! { px(4.) }),
319 ("5", quote! { px(5.) }),
320 ("6", quote! { px(6.) }),
321 ("7", quote! { px(7.) }),
322 ("8", quote! { px(8.) }),
323 ("9", quote! { px(9.) }),
324 ("10", quote! { px(10.) }),
325 ("11", quote! { px(11.) }),
326 ("12", quote! { px(12.) }),
327 ("16", quote! { px(16.) }),
328 ("20", quote! { px(20.) }),
329 ("24", quote! { px(24.) }),
330 ("32", quote! { px(32.) }),
331 ]
332}
crates/storybook2/src/collab_panel.rs+8−7
@@ -1,6 +1,7 @@
1use crate::theme::{theme, Theme};1use crate::theme::{theme, Theme};
2use gpui3::{2use gpui3::{
3 div, img, svg, ArcCow, Element, IntoAnyElement, ParentElement, ScrollState, Styled, ViewContext,3 div, img, svg, ArcCow, Element, IntoAnyElement, ParentElement, ScrollState, StyleHelpers,
4 ViewContext,
4};5};
5use std::marker::PhantomData;6use std::marker::PhantomData;
6 7
@@ -117,7 +118,7 @@ impl<V: 'static> CollabPanelElement<V> { · 110 unmodified lines
117 label: impl IntoAnyElement<V>,118 label: impl IntoAnyElement<V>,
118 expanded: bool,119 expanded: bool,
119 theme: &Theme,120 theme: &Theme,
120 ) -> impl Element {121 ) -> impl Element<State = V> {
121 div()122 div()
122 .h_7()123 .h_7()
123 .px_2()124 .px_2()
@@ -145,16 +146,16 @@ impl<V: 'static> CollabPanelElement<V> { · 21 unmodified lines
145 avatar_uri: impl Into<ArcCow<'static, str>>,146 avatar_uri: impl Into<ArcCow<'static, str>>,
146 label: impl IntoAnyElement<V>,147 label: impl IntoAnyElement<V>,
147 theme: &Theme,148 theme: &Theme,
148 ) -> impl Element {149 ) -> impl Element<State = V> {
149 div()150 div()
150 .h_7()151 .h_7()
151 .px_2()152 .px_2()
152 .flex()153 .flex()
153 .items_center()154 .items_center()
154 .hover()155 // .hover()
155 .fill(theme.lowest.variant.hovered.background)156 // .fill(theme.lowest.variant.hovered.background)
156 .active()157 // .active()
157 .fill(theme.lowest.variant.pressed.background)158 // .fill(theme.lowest.variant.pressed.background)
158 .child(159 .child(
159 div()160 div()
160 .flex()161 .flex()
crates/storybook2/src/storybook2.rs+18−16
@@ -1,10 +1,9 @@
1#![allow(dead_code, unused_variables)]1#![allow(dead_code, unused_variables)]
2 2
3use crate::theme::Theme;3use crate::theme::Theme;
4use ::theme as legacy_theme;
5use element_ext::ElementExt;4use element_ext::ElementExt;
6use gpui3::{Element, ViewContext};5use gpui3::{Element, ViewContext};
7use legacy_theme::ThemeSettings;6
8use log::LevelFilter;7use log::LevelFilter;
9use simplelog::SimpleLogger;8use simplelog::SimpleLogger;
10 9
@@ -22,7 +21,9 @@ mod workspace; · 11 unmodified lines
22fn main() {21fn main() {
23 SimpleLogger::init(LevelFilter::Info, Default::default()).expect("could not initialize logger");22 SimpleLogger::init(LevelFilter::Info, Default::default()).expect("could not initialize logger");
24 23
25 gpui3::App::new().run(|cx| cx.open_window(Default::default(), |cx| todo!()));24 gpui3::App::new().run(|cx| {
25 let window: gpui3::WindowHandle<()> = cx.open_window(Default::default(), |cx| todo!());
26 });
26 27
27 // gpui3::App::new(Assets).unwrap().run(|cx| {28 // gpui3::App::new(Assets).unwrap().run(|cx| {
28 // let mut store = SettingsStore::default();29 // let mut store = SettingsStore::default();
@@ -56,19 +57,20 @@ fn storybook<V: 'static>(cx: &mut ViewContext<V>) -> impl Element { · 27 unmodified lines
56 57
57// Nathan: During the transition to gpui2, we will include the base theme on the legacy Theme struct.58// Nathan: During the transition to gpui2, we will include the base theme on the legacy Theme struct.
58fn current_theme<V: 'static>(cx: &mut ViewContext<V>) -> Theme {59fn current_theme<V: 'static>(cx: &mut ViewContext<V>) -> Theme {
59 settings::get::<ThemeSettings>(cx)60 todo!()
60 .theme61 // settings::get::<ThemeSettings>(cx)
61 .deserialized_base_theme62 // .theme
62 .lock()63 // .deserialized_base_theme
63 .get_or_insert_with(|| {64 // .lock()
64 let theme: Theme =65 // .get_or_insert_with(|| {
65 serde_json::from_value(settings::get::<ThemeSettings>(cx).theme.base_theme.clone())66 // let theme: Theme =
66 .unwrap();67 // serde_json::from_value(settings::get::<ThemeSettings>(cx).theme.base_theme.clone())
67 Box::new(theme)68 // .unwrap();
68 })69 // Box::new(theme)
69 .downcast_ref::<Theme>()70 // })
70 .unwrap()71 // .downcast_ref::<Theme>()
71 .clone()72 // .unwrap()
73 // .clone()
72}74}
73 75
74use rust_embed::RustEmbed;76use rust_embed::RustEmbed;
crates/storybook2/src/theme.rs+30−31
@@ -1,10 +1,6 @@
1use gpui3::{1use gpui3::{Element, Hsla, Layout, LayoutId, ViewContext, WindowContext};
2 serde_json, AppContext, Element, Hsla, IntoAnyElement, Layout, LayoutId, Vector2F, ViewContext,
3 WindowContext,
4};
5use serde::{de::Visitor, Deserialize, Deserializer};2use serde::{de::Visitor, Deserialize, Deserializer};
6use std::{collections::HashMap, fmt, marker::PhantomData};3use std::{collections::HashMap, fmt};
7use theme::ThemeSettings;
8 4
9#[derive(Deserialize, Clone, Default, Debug)]5#[derive(Deserialize, Clone, Default, Debug)]
10pub struct Theme {6pub struct Theme {
@@ -137,6 +133,7 @@ pub struct Themed<E> { · 126 unmodified lines
137}133}
138 134
139impl<E: Element> Element for Themed<E> {135impl<E: Element> Element for Themed<E> {
136 type State = E::State;
140 type FrameState = E::FrameState;137 type FrameState = E::FrameState;
141 138
142 fn layout(139 fn layout(
@@ -147,43 +144,45 @@ impl<E: Element> Element for Themed<E> { · 4 unmodified lines
147 where144 where
148 Self: Sized,145 Self: Sized,
149 {146 {
150 cx.push_theme(self.theme.clone());147 // cx.push_theme(self.theme.clone());
151 let result = self.child.layout(state, cx);148 let result = self.child.layout(state, cx);
152 cx.pop_theme();149 // cx.pop_theme();
153 result150 result
154 }151 }
155 152
156 fn paint(153 fn paint(
157 &mut self,154 &mut self,
158 view: &mut V,155 layout: Layout,
159 layout: &Layout,156 state: &mut Self::State,
160 state: &mut Self::FrameState,157 frame_state: &mut Self::FrameState,
161 cx: &mut ViewContext<V>,158 cx: &mut ViewContext<Self::State>,
162 ) where159 ) where
163 Self: Sized,160 Self: Sized,
164 {161 {
165 cx.push_theme(self.theme.clone());162 // todo!
166 self.child.paint(view, layout, state, cx);163 // cx.push_theme(self.theme.clone());
167 cx.pop_theme();164 self.child.paint(layout, state, frame_state, cx);
165 // cx.pop_theme();
168 }166 }
169}167}
170 168
171fn preferred_theme<V: 'static>(cx: &AppContext) -> Theme {169// fn preferred_theme<V: 'static>(cx: &AppContext) -> Theme {
172 settings::get::<ThemeSettings>(cx)170// settings::get::<ThemeSettings>(cx)
173 .theme171// .theme
174 .deserialized_base_theme172// .deserialized_base_theme
175 .lock()173// .lock()
176 .get_or_insert_with(|| {174// .get_or_insert_with(|| {
177 let theme: Theme =175// let theme: Theme =
178 serde_json::from_value(settings::get::<ThemeSettings>(cx).theme.base_theme.clone())176// serde_json::from_value(settings::get::<ThemeSettings>(cx).theme.base_theme.clone())
179 .unwrap();177// .unwrap();
180 Box::new(theme)178// Box::new(theme)
181 })179// })
182 .downcast_ref::<Theme>()180// .downcast_ref::<Theme>()
183 .unwrap()181// .unwrap()
184 .clone()182// .clone()
185}183// }
186 184
187pub fn theme<'a>(cx: &'a WindowContext) -> &'a Theme {185pub fn theme<'a>(cx: &'a WindowContext) -> &'a Theme {
188 cx.theme::<Theme>()186 todo!()
187 // cx.theme::<Theme>()
189}188}
crates/storybook2/src/workspace.rs+51−39
@@ -1,5 +1,5 @@
1use crate::{collab_panel::collab_panel, theme::theme};1use crate::{collab_panel::collab_panel, theme::theme};
2use gpui3::{div, img, svg, Element, ParentElement, ScrollState, Styled, ViewContext};2use gpui3::{div, img, svg, Element, ParentElement, ScrollState, StyleHelpers, ViewContext};
3 3
4#[derive(Default)]4#[derive(Default)]
5struct WorkspaceElement {5struct WorkspaceElement {
@@ -7,12 +7,16 @@ struct WorkspaceElement { · 1 unmodified line
7 right_scroll_state: ScrollState,7 right_scroll_state: ScrollState,
8}8}
9 9
10pub fn workspace<V: 'static>() -> impl Element {10pub fn workspace() -> impl Element {
11 WorkspaceElement::default()11 WorkspaceElement::default()
12}12}
13 13
14impl WorkspaceElement {14impl WorkspaceElement {
15 fn render<V: 'static>(&mut self, _: &mut V, cx: &mut ViewContext<V>) -> impl Element {15 fn render<V: 'static>(
16 &mut self,
17 _: &mut V,
18 cx: &mut ViewContext<V>,
19 ) -> impl Element<State = V> {
16 let theme = theme(cx);20 let theme = theme(cx);
17 21
18 div()22 div()
@@ -43,12 +47,16 @@ impl WorkspaceElement { · 24 unmodified lines
43 47
44struct TitleBar;48struct TitleBar;
45 49
46pub fn titlebar<V: 'static>() -> impl Element {50pub fn titlebar<V: 'static>() -> impl Element<State = V> {
47 TitleBar51 TitleBar
48}52}
49 53
50impl TitleBar {54impl TitleBar {
51 fn render<V: 'static>(&mut self, _: &mut V, cx: &mut ViewContext<V>) -> impl Element {55 fn render<V: 'static>(
56 &mut self,
57 _: &mut V,
58 cx: &mut ViewContext<V>,
59 ) -> impl Element<State = V> {
52 let theme = theme(cx);60 let theme = theme(cx);
53 div()61 div()
54 .flex()62 .flex()
@@ -61,7 +69,7 @@ impl TitleBar { · 6 unmodified lines
61 .child(self.right_group(cx))69 .child(self.right_group(cx))
62 }70 }
63 71
64 fn left_group<V: 'static>(&mut self, cx: &mut ViewContext<V>) -> impl Element {72 fn left_group<V: 'static>(&mut self, cx: &mut ViewContext<V>) -> impl Element<State = V> {
65 let theme = theme(cx);73 let theme = theme(cx);
66 div()74 div()
67 .flex()75 .flex()
@@ -111,10 +119,10 @@ impl TitleBar { · 43 unmodified lines
111 .justify_center()119 .justify_center()
112 .px_2()120 .px_2()
113 .rounded_md()121 .rounded_md()
114 .hover()122 // .hover()
115 .fill(theme.lowest.base.hovered.background)123 // .fill(theme.lowest.base.hovered.background)
116 .active()124 // .active()
117 .fill(theme.lowest.base.pressed.background)125 // .fill(theme.lowest.base.pressed.background)
118 .child(div().text_sm().child("project")),126 .child(div().text_sm().child("project")),
119 )127 )
120 .child(128 .child(
@@ -126,16 +134,16 @@ impl TitleBar { · 5 unmodified lines
126 .px_2()134 .px_2()
127 .rounded_md()135 .rounded_md()
128 .text_color(theme.lowest.variant.default.foreground)136 .text_color(theme.lowest.variant.default.foreground)
129 .hover()137 // .hover()
130 .fill(theme.lowest.base.hovered.background)138 // .fill(theme.lowest.base.hovered.background)
131 .active()139 // .active()
132 .fill(theme.lowest.base.pressed.background)140 // .fill(theme.lowest.base.pressed.background)
133 .child(div().text_sm().child("branch")),141 .child(div().text_sm().child("branch")),
134 ),142 ),
135 )143 )
136 }144 }
137 145
138 fn right_group<V: 'static>(&mut self, cx: &mut ViewContext<V>) -> impl Element {146 fn right_group<V: 'static>(&mut self, cx: &mut ViewContext<V>) -> impl Element<State = V> {
139 let theme = theme(cx);147 let theme = theme(cx);
140 div()148 div()
141 .flex()149 .flex()
@@ -173,10 +181,10 @@ impl TitleBar { · 31 unmodified lines
173 .flex()181 .flex()
174 .items_center()182 .items_center()
175 .justify_center()183 .justify_center()
176 .hover()184 // .hover()
177 .fill(theme.lowest.base.hovered.background)185 // .fill(theme.lowest.base.hovered.background)
178 .active()186 // .active()
179 .fill(theme.lowest.base.pressed.background)187 // .fill(theme.lowest.base.pressed.background)
180 .child(188 .child(
181 svg()189 svg()
182 .path("icons/microphone.svg")190 .path("icons/microphone.svg")
@@ -193,10 +201,10 @@ impl TitleBar { · 10 unmodified lines
193 .flex()201 .flex()
194 .items_center()202 .items_center()
195 .justify_center()203 .justify_center()
196 .hover()204 // .hover()
197 .fill(theme.lowest.base.hovered.background)205 // .fill(theme.lowest.base.hovered.background)
198 .active()206 // .active()
199 .fill(theme.lowest.base.pressed.background)207 // .fill(theme.lowest.base.pressed.background)
200 .child(208 .child(
201 svg()209 svg()
202 .path("icons/radix/speaker-loud.svg")210 .path("icons/radix/speaker-loud.svg")
@@ -213,10 +221,10 @@ impl TitleBar { · 10 unmodified lines
213 .flex()221 .flex()
214 .items_center()222 .items_center()
215 .justify_center()223 .justify_center()
216 .hover()224 // .hover()
217 .fill(theme.lowest.base.hovered.background)225 // .fill(theme.lowest.base.hovered.background)
218 .active()226 // .active()
219 .fill(theme.lowest.base.pressed.background)227 // .fill(theme.lowest.base.pressed.background)
220 .child(228 .child(
221 svg()229 svg()
222 .path("icons/radix/desktop.svg")230 .path("icons/radix/desktop.svg")
@@ -238,10 +246,10 @@ impl TitleBar { · 15 unmodified lines
238 .justify_center()246 .justify_center()
239 .rounded_md()247 .rounded_md()
240 .gap_0p5()248 .gap_0p5()
241 .hover()249 // .hover()
242 .fill(theme.lowest.base.hovered.background)250 // .fill(theme.lowest.base.hovered.background)
243 .active()251 // .active()
244 .fill(theme.lowest.base.pressed.background)252 // .fill(theme.lowest.base.pressed.background)
245 .child(253 .child(
246 img()254 img()
247 .uri("https://avatars.githubusercontent.com/u/1714999?v=4")255 .uri("https://avatars.githubusercontent.com/u/1714999?v=4")
@@ -265,12 +273,16 @@ impl TitleBar { · 17 unmodified lines
265 273
266struct StatusBar;274struct StatusBar;
267 275
268pub fn statusbar<V: 'static>() -> impl Element {276pub fn statusbar<V: 'static>() -> impl Element<State = V> {
269 StatusBar277 StatusBar
270}278}
271 279
272impl StatusBar {280impl StatusBar {
273 fn render<V: 'static>(&mut self, _: &mut V, cx: &mut ViewContext<V>) -> impl Element {281 fn render<V: 'static>(
282 &mut self,
283 _: &mut V,
284 cx: &mut ViewContext<V>,
285 ) -> impl Element<State = V> {
274 let theme = theme(cx);286 let theme = theme(cx);
275 div()287 div()
276 .flex()288 .flex()
@@ -283,7 +295,7 @@ impl StatusBar { · 6 unmodified lines
283 .child(self.right_group(cx))295 .child(self.right_group(cx))
284 }296 }
285 297
286 fn left_group<V: 'static>(&mut self, cx: &mut ViewContext<V>) -> impl Element {298 fn left_group<V: 'static>(&mut self, cx: &mut ViewContext<V>) -> impl Element<State = V> {
287 let theme = theme(cx);299 let theme = theme(cx);
288 div()300 div()
289 .flex()301 .flex()
@@ -358,10 +370,10 @@ impl StatusBar { · 68 unmodified lines
358 .gap_0p5()370 .gap_0p5()
359 .px_1()371 .px_1()
360 .text_color(theme.lowest.variant.default.foreground)372 .text_color(theme.lowest.variant.default.foreground)
361 .hover()373 // .hover()
362 .fill(theme.lowest.base.hovered.background)374 // .fill(theme.lowest.base.hovered.background)
363 .active()375 // .active()
364 .fill(theme.lowest.base.pressed.background)376 // .fill(theme.lowest.base.pressed.background)
365 .child(377 .child(
366 svg()378 svg()
367 .path("icons/error.svg")379 .path("icons/error.svg")
@@ -380,7 +392,7 @@ impl StatusBar { · 12 unmodified lines
380 )392 )
381 }393 }
382 394
383 fn right_group<V: 'static>(&mut self, cx: &mut ViewContext<V>) -> impl Element {395 fn right_group<V: 'static>(&mut self, cx: &mut ViewContext<V>) -> impl Element<State = V> {
384 let theme = theme(cx);396 let theme = theme(cx);
385 div()397 div()
386 .flex()398 .flex()

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t