Unified · Split
| @@ -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]] | ||
| 3409 | name = "gpui3_macros" | ||
| 3410 | version = "0.1.0" | ||
| 3411 | dependencies = [ | ||
| 3412 | "proc-macro2", | ||
| 3413 | "quote", | ||
| 3414 | "syn 1.0.109", | ||
| 3415 | ] | ||
| 3416 | |||
| 3408 | [[package]] | 3417 | [[package]] |
| 3409 | name = "gpui_macros" | 3418 | name = "gpui_macros" |
| 3410 | version = "0.1.0" | 3419 | version = "0.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", |
| @@ -203,8 +203,8 @@ where · 202 unmodified lines | |||
| 203 | impl Size<DefiniteLength> { | 203 | impl 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 | |||
| 279 | impl Edges<DefiniteLength> { | 279 | impl 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 | |||
| 299 | impl Edges<AbsoluteLength> { | 299 | impl 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 | ||
| 439 | pub fn px<T: From<AbsoluteLength>>(pixels: f32) -> T { | ||
| 440 | AbsoluteLength::Pixels(pixels).into() | ||
| 441 | } | ||
| 442 | |||
| 439 | pub fn pixels<T: From<AbsoluteLength>>(pixels: f32) -> T { | 443 | pub fn pixels<T: From<AbsoluteLength>>(pixels: f32) -> T { |
| 440 | AbsoluteLength::Pixels(pixels).into() | 444 | AbsoluteLength::Pixels(pixels).into() |
| 441 | } | 445 | } |
| @@ -16,7 +16,7 @@ doctest = false · 15 unmodified lines | |||
| 16 | [dependencies] | 16 | [dependencies] |
| 17 | collections = { path = "../collections" } | 17 | collections = { path = "../collections" } |
| 18 | gpui_macros = { path = "../gpui_macros" } | 18 | gpui_macros = { path = "../gpui_macros" } |
| 19 | gpui2_macros = { path = "../gpui2_macros" } | 19 | gpui3_macros = { path = "../gpui3_macros" } |
| 20 | util = { path = "../util" } | 20 | util = { path = "../util" } |
| 21 | sum_tree = { path = "../sum_tree" } | 21 | sum_tree = { path = "../sum_tree" } |
| 22 | sqlez = { path = "../sqlez" } | 22 | sqlez = { path = "../sqlez" } |
| @@ -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 | self | 33 | 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 | ||
| 37 | trait ElementObject<S> { | 46 | trait ElementObject<S> { |
| @@ -1,6 +1,6 @@ | |||
| 1 | use crate::{ | 1 | use 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 | }; |
| 5 | use smallvec::SmallVec; | 5 | use smallvec::SmallVec; |
| 6 | use std::{cell::Cell, rc::Rc}; | 6 | use std::{cell::Cell, rc::Rc}; |
| @@ -257,6 +257,8 @@ impl<V> Styled for Div<V> { · 250 unmodified lines | |||
| 257 | } | 257 | } |
| 258 | } | 258 | } |
| 259 | 259 | ||
| 260 | impl<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.handlers | 264 | // &mut self.handlers |
| @@ -1,4 +1,4 @@ | |||
| 1 | use crate::{Element, Layout, LayoutId, Result, Style, Styled}; | 1 | use crate::{Element, Layout, LayoutId, Result, Style, StyleHelpers, Styled}; |
| 2 | use refineable::RefinementCascade; | 2 | use refineable::RefinementCascade; |
| 3 | use std::marker::PhantomData; | 3 | use std::marker::PhantomData; |
| 4 | use util::arc_cow::ArcCow; | 4 | use 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 | |||
| 102 | impl<S> StyleHelpers for Img<S> {} | ||
| @@ -1,4 +1,4 @@ | |||
| 1 | use crate::{Element, Layout, LayoutId, Result, Style, Styled}; | 1 | use crate::{Element, Layout, LayoutId, Result, Style, StyleHelpers, Styled}; |
| 2 | use refineable::RefinementCascade; | 2 | use refineable::RefinementCascade; |
| 3 | use std::{borrow::Cow, marker::PhantomData}; | 3 | use 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 | |||
| 81 | impl<S> StyleHelpers for Svg<S> {} | ||
| @@ -100,8 +100,8 @@ impl From<Size<Option<Pixels>>> for Size<Option<f32>> { · 99 unmodified lines | |||
| 100 | impl Size<Length> { | 100 | impl 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 | ||
| 413 | pub fn relative<T: From<DefiniteLength>>(fraction: f32) -> T { | 413 | pub fn relative(fraction: f32) -> DefiniteLength { |
| 414 | DefiniteLength::Fraction(fraction).into() | 414 | DefiniteLength::Fraction(fraction).into() |
| 415 | } | 415 | } |
| 416 | 416 | ||
| @@ -8,6 +8,7 @@ mod platform; · 7 unmodified lines | |||
| 8 | mod renderer; | 8 | mod renderer; |
| 9 | mod scene; | 9 | mod scene; |
| 10 | mod style; | 10 | mod style; |
| 11 | mod style_helpers; | ||
| 11 | mod styled; | 12 | mod styled; |
| 12 | mod taffy; | 13 | mod taffy; |
| 13 | mod text_system; | 14 | mod text_system; |
| @@ -30,6 +31,7 @@ pub use smallvec; · 16 unmodified lines | |||
| 30 | pub use smol::Timer; | 31 | pub use smol::Timer; |
| 31 | use std::ops::{Deref, DerefMut}; | 32 | use std::ops::{Deref, DerefMut}; |
| 32 | pub use style::*; | 33 | pub use style::*; |
| 34 | pub use style_helpers::*; | ||
| 33 | pub use styled::*; | 35 | pub use styled::*; |
| 34 | use taffy::TaffyLayoutEngine; | 36 | use taffy::TaffyLayoutEngine; |
| 35 | pub use taffy::{AvailableSpace, LayoutId}; | 37 | pub use taffy::{AvailableSpace, LayoutId}; |
| @@ -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)] |
| 291 | pub struct CornerRadii { | 291 | pub 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 | ||
| 298 | impl From<TextStyle> for HighlightStyle { | 298 | impl From<TextStyle> for HighlightStyle { |
| @@ -0,0 +1,288 @@ | |||
| 1 | use crate::{ | ||
| 2 | self as gpui2, relative, rems, AlignItems, Display, Fill, FlexDirection, Hsla, JustifyContent, | ||
| 3 | Length, Position, SharedString, Style, Styled, | ||
| 4 | }; | ||
| 5 | |||
| 6 | pub 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 | } | ||
| @@ -0,0 +1,14 @@ | |||
| 1 | [package] | ||
| 2 | name = "gpui3_macros" | ||
| 3 | version = "0.1.0" | ||
| 4 | edition = "2021" | ||
| 5 | publish = false | ||
| 6 | |||
| 7 | [lib] | ||
| 8 | path = "src/gpui3_macros.rs" | ||
| 9 | proc-macro = true | ||
| 10 | |||
| 11 | [dependencies] | ||
| 12 | syn = "1.0.72" | ||
| 13 | quote = "1.0.9" | ||
| 14 | proc-macro2 = "1.0.66" | ||
| @@ -0,0 +1,93 @@ | |||
| 1 | use proc_macro::TokenStream; | ||
| 2 | use proc_macro2::Ident; | ||
| 3 | use quote::quote; | ||
| 4 | use syn::{parse_macro_input, parse_quote, DeriveInput, GenericParam, Generics}; | ||
| 5 | |||
| 6 | use crate::derive_into_element::impl_into_element; | ||
| 7 | |||
| 8 | pub 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 | } | ||
| @@ -0,0 +1,69 @@ | |||
| 1 | use proc_macro::TokenStream; | ||
| 2 | use quote::quote; | ||
| 3 | use syn::{ | ||
| 4 | parse_macro_input, parse_quote, DeriveInput, GenericParam, Generics, Ident, WhereClause, | ||
| 5 | }; | ||
| 6 | |||
| 7 | pub 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 | |||
| 51 | pub 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 | } | ||
| @@ -0,0 +1,20 @@ | |||
| 1 | use proc_macro::TokenStream; | ||
| 2 | |||
| 3 | mod derive_element; | ||
| 4 | mod derive_into_element; | ||
| 5 | mod style_helpers; | ||
| 6 | |||
| 7 | #[proc_macro] | ||
| 8 | pub fn style_helpers(args: TokenStream) -> TokenStream { | ||
| 9 | style_helpers::style_helpers(args) | ||
| 10 | } | ||
| 11 | |||
| 12 | #[proc_macro_derive(Element, attributes(element_crate))] | ||
| 13 | pub fn derive_element(input: TokenStream) -> TokenStream { | ||
| 14 | derive_element::derive_element(input) | ||
| 15 | } | ||
| 16 | |||
| 17 | #[proc_macro_derive(IntoElement, attributes(element_crate))] | ||
| 18 | pub fn derive_into_element(input: TokenStream) -> TokenStream { | ||
| 19 | derive_into_element::derive_into_element(input) | ||
| 20 | } | ||
| @@ -0,0 +1,332 @@ | |||
| 1 | use proc_macro::TokenStream; | ||
| 2 | use proc_macro2::TokenStream as TokenStream2; | ||
| 3 | use quote::{format_ident, quote}; | ||
| 4 | use syn::{ | ||
| 5 | parse::{Parse, ParseStream, Result}, | ||
| 6 | parse_macro_input, | ||
| 7 | }; | ||
| 8 | |||
| 9 | struct StyleableMacroInput; | ||
| 10 | |||
| 11 | impl Parse for StyleableMacroInput { | ||
| 12 | fn parse(_input: ParseStream) -> Result<Self> { | ||
| 13 | Ok(StyleableMacroInput) | ||
| 14 | } | ||
| 15 | } | ||
| 16 | |||
| 17 | pub 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 | |||
| 32 | fn 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 | |||
| 61 | fn 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 | |||
| 93 | fn 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 | |||
| 168 | fn 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 | |||
| 220 | fn 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 | |||
| 266 | fn 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 | |||
| 279 | fn 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 | |||
| 311 | fn 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 | } | ||
| @@ -1,6 +1,7 @@ | |||
| 1 | use crate::theme::{theme, Theme}; | 1 | use crate::theme::{theme, Theme}; |
| 2 | use gpui3::{ | 2 | use 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 | }; |
| 5 | use std::marker::PhantomData; | 6 | use 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() |
| @@ -1,10 +1,9 @@ | |||
| 1 | #![allow(dead_code, unused_variables)] | 1 | #![allow(dead_code, unused_variables)] |
| 2 | 2 | ||
| 3 | use crate::theme::Theme; | 3 | use crate::theme::Theme; |
| 4 | use ::theme as legacy_theme; | ||
| 5 | use element_ext::ElementExt; | 4 | use element_ext::ElementExt; |
| 6 | use gpui3::{Element, ViewContext}; | 5 | use gpui3::{Element, ViewContext}; |
| 7 | use legacy_theme::ThemeSettings; | 6 | |
| 8 | use log::LevelFilter; | 7 | use log::LevelFilter; |
| 9 | use simplelog::SimpleLogger; | 8 | use simplelog::SimpleLogger; |
| 10 | 9 | ||
| @@ -22,7 +21,9 @@ mod workspace; · 11 unmodified lines | |||
| 22 | fn main() { | 21 | fn 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. |
| 58 | fn current_theme<V: 'static>(cx: &mut ViewContext<V>) -> Theme { | 59 | fn current_theme<V: 'static>(cx: &mut ViewContext<V>) -> Theme { |
| 59 | settings::get::<ThemeSettings>(cx) | 60 | todo!() |
| 60 | .theme | 61 | // settings::get::<ThemeSettings>(cx) |
| 61 | .deserialized_base_theme | 62 | // .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 | ||
| 74 | use rust_embed::RustEmbed; | 76 | use rust_embed::RustEmbed; |
| @@ -1,10 +1,6 @@ | |||
| 1 | use gpui3::{ | 1 | use gpui3::{Element, Hsla, Layout, LayoutId, ViewContext, WindowContext}; |
| 2 | serde_json, AppContext, Element, Hsla, IntoAnyElement, Layout, LayoutId, Vector2F, ViewContext, | ||
| 3 | WindowContext, | ||
| 4 | }; | ||
| 5 | use serde::{de::Visitor, Deserialize, Deserializer}; | 2 | use serde::{de::Visitor, Deserialize, Deserializer}; |
| 6 | use std::{collections::HashMap, fmt, marker::PhantomData}; | 3 | use std::{collections::HashMap, fmt}; |
| 7 | use theme::ThemeSettings; | ||
| 8 | 4 | ||
| 9 | #[derive(Deserialize, Clone, Default, Debug)] | 5 | #[derive(Deserialize, Clone, Default, Debug)] |
| 10 | pub struct Theme { | 6 | pub struct Theme { |
| @@ -137,6 +133,7 @@ pub struct Themed<E> { · 126 unmodified lines | |||
| 137 | } | 133 | } |
| 138 | 134 | ||
| 139 | impl<E: Element> Element for Themed<E> { | 135 | impl<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 | where | 144 | 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 | result | 150 | 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 | ) where | 159 | ) 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 | ||
| 171 | fn 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 | .theme | 171 | // .theme |
| 174 | .deserialized_base_theme | 172 | // .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 | ||
| 187 | pub fn theme<'a>(cx: &'a WindowContext) -> &'a Theme { | 185 | pub fn theme<'a>(cx: &'a WindowContext) -> &'a Theme { |
| 188 | cx.theme::<Theme>() | 186 | todo!() |
| 187 | // cx.theme::<Theme>() | ||
| 189 | } | 188 | } |
| @@ -1,5 +1,5 @@ | |||
| 1 | use crate::{collab_panel::collab_panel, theme::theme}; | 1 | use crate::{collab_panel::collab_panel, theme::theme}; |
| 2 | use gpui3::{div, img, svg, Element, ParentElement, ScrollState, Styled, ViewContext}; | 2 | use gpui3::{div, img, svg, Element, ParentElement, ScrollState, StyleHelpers, ViewContext}; |
| 3 | 3 | ||
| 4 | #[derive(Default)] | 4 | #[derive(Default)] |
| 5 | struct WorkspaceElement { | 5 | struct WorkspaceElement { |
| @@ -7,12 +7,16 @@ struct WorkspaceElement { · 1 unmodified line | |||
| 7 | right_scroll_state: ScrollState, | 7 | right_scroll_state: ScrollState, |
| 8 | } | 8 | } |
| 9 | 9 | ||
| 10 | pub fn workspace<V: 'static>() -> impl Element { | 10 | pub fn workspace() -> impl Element { |
| 11 | WorkspaceElement::default() | 11 | WorkspaceElement::default() |
| 12 | } | 12 | } |
| 13 | 13 | ||
| 14 | impl WorkspaceElement { | 14 | impl 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 | ||
| 44 | struct TitleBar; | 48 | struct TitleBar; |
| 45 | 49 | ||
| 46 | pub fn titlebar<V: 'static>() -> impl Element { | 50 | pub fn titlebar<V: 'static>() -> impl Element<State = V> { |
| 47 | TitleBar | 51 | TitleBar |
| 48 | } | 52 | } |
| 49 | 53 | ||
| 50 | impl TitleBar { | 54 | impl 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 | ||
| 266 | struct StatusBar; | 274 | struct StatusBar; |
| 267 | 275 | ||
| 268 | pub fn statusbar<V: 'static>() -> impl Element { | 276 | pub fn statusbar<V: 'static>() -> impl Element<State = V> { |
| 269 | StatusBar | 277 | StatusBar |
| 270 | } | 278 | } |
| 271 | 279 | ||
| 272 | impl StatusBar { | 280 | impl 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() |