Get a 50% colored box rendering

Co-Authored-By: Mikayla Maki <mikayla@zed.dev>
This commit is contained in:
Nathan Sobo 2023-08-14 14:46:09 -06:00
parent 740b105330
commit f9858445b8
8 changed files with 130 additions and 49 deletions

View file

@ -1,5 +1,5 @@
use crate::element::{LayoutContext, PaintContext}; use crate::element::{LayoutContext, PaintContext};
use gpui::geometry::rect::RectF; use gpui::{geometry::rect::RectF, LayoutEngine};
use util::ResultExt; use util::ResultExt;
use crate::element::AnyElement; use crate::element::AnyElement;
@ -8,7 +8,7 @@ use crate::element::AnyElement;
pub struct Adapter<V>(pub(crate) AnyElement<V>); pub struct Adapter<V>(pub(crate) AnyElement<V>);
impl<V: 'static> gpui::Element<V> for Adapter<V> { impl<V: 'static> gpui::Element<V> for Adapter<V> {
type LayoutState = (); type LayoutState = Option<LayoutEngine>;
type PaintState = (); type PaintState = ();
fn layout( fn layout(
@ -17,7 +17,7 @@ impl<V: 'static> gpui::Element<V> for Adapter<V> {
view: &mut V, view: &mut V,
legacy_cx: &mut gpui::LayoutContext<V>, legacy_cx: &mut gpui::LayoutContext<V>,
) -> (gpui::geometry::vector::Vector2F, Self::LayoutState) { ) -> (gpui::geometry::vector::Vector2F, Self::LayoutState) {
legacy_cx.push_layout_engine(); legacy_cx.push_layout_engine(LayoutEngine::new());
let node = self let node = self
.0 .0
.layout(view, &mut LayoutContext { legacy_cx }) .layout(view, &mut LayoutContext { legacy_cx })
@ -27,9 +27,9 @@ impl<V: 'static> gpui::Element<V> for Adapter<V> {
let layout_engine = legacy_cx.layout_engine().unwrap(); let layout_engine = legacy_cx.layout_engine().unwrap();
layout_engine.compute_layout(node, constraint.max).log_err(); layout_engine.compute_layout(node, constraint.max).log_err();
} }
legacy_cx.pop_layout_engine(); let layout_engine = legacy_cx.pop_layout_engine();
debug_assert!(layout_engine.is_some());
(constraint.max, ()) (constraint.max, layout_engine)
} }
fn paint( fn paint(
@ -37,12 +37,15 @@ impl<V: 'static> gpui::Element<V> for Adapter<V> {
scene: &mut gpui::SceneBuilder, scene: &mut gpui::SceneBuilder,
bounds: RectF, bounds: RectF,
visible_bounds: RectF, visible_bounds: RectF,
layout: &mut (), layout_engine: &mut Option<LayoutEngine>,
view: &mut V, view: &mut V,
legacy_cx: &mut gpui::PaintContext<V>, legacy_cx: &mut gpui::PaintContext<V>,
) -> Self::PaintState { ) -> Self::PaintState {
legacy_cx.push_layout_engine(layout_engine.take().unwrap());
let mut cx = PaintContext { legacy_cx, scene }; let mut cx = PaintContext { legacy_cx, scene };
self.0.paint(view, &mut cx).log_err(); self.0.paint(view, &mut cx).log_err();
*layout_engine = legacy_cx.pop_layout_engine();
debug_assert!(layout_engine.is_some());
} }
fn rect_for_text_range( fn rect_for_text_range(

View file

@ -1,6 +1,6 @@
use crate::{ use crate::{
adapter::Adapter, adapter::Adapter,
style::{DefinedLength, Display, Fill, Overflow, Position, Style}, style::{DefinedLength, Display, Fill, Length, Overflow, Position, Style},
}; };
use anyhow::Result; use anyhow::Result;
use derive_more::{Deref, DerefMut}; use derive_more::{Deref, DerefMut};
@ -168,7 +168,7 @@ pub trait Element<V: 'static>: 'static + Clone {
} }
#[tailwind_lengths] #[tailwind_lengths]
fn inset(mut self, length: DefinedLength) -> Self fn inset_(mut self, length: DefinedLength) -> Self
where where
Self: Sized, Self: Sized,
{ {
@ -179,8 +179,24 @@ pub trait Element<V: 'static>: 'static + Clone {
self self
} }
fn w(mut self, width: impl Into<Length>) -> Self
where
Self: Sized,
{
self.style_mut().size.width = width.into();
self
}
fn w_auto(mut self) -> Self
where
Self: Sized,
{
self.style_mut().size.width = Length::Auto;
self
}
#[tailwind_lengths] #[tailwind_lengths]
fn w(mut self, length: DefinedLength) -> Self fn w_(mut self, length: DefinedLength) -> Self
where where
Self: Sized, Self: Sized,
{ {
@ -189,7 +205,7 @@ pub trait Element<V: 'static>: 'static + Clone {
} }
#[tailwind_lengths] #[tailwind_lengths]
fn min_w(mut self, length: DefinedLength) -> Self fn min_w_(mut self, length: DefinedLength) -> Self
where where
Self: Sized, Self: Sized,
{ {
@ -197,17 +213,33 @@ pub trait Element<V: 'static>: 'static + Clone {
self self
} }
#[tailwind_lengths] fn h(mut self, height: impl Into<Length>) -> Self
fn h(mut self, length: DefinedLength) -> Self
where where
Self: Sized, Self: Sized,
{ {
self.style_mut().size.height = length; self.style_mut().size.height = height.into();
self
}
fn h_auto(mut self) -> Self
where
Self: Sized,
{
self.style_mut().size.height = Length::Auto;
self self
} }
#[tailwind_lengths] #[tailwind_lengths]
fn min_h(mut self, length: DefinedLength) -> Self fn h_(mut self, height: DefinedLength) -> Self
where
Self: Sized,
{
self.style_mut().size.height = height;
self
}
#[tailwind_lengths]
fn min_h_(mut self, length: DefinedLength) -> Self
where where
Self: Sized, Self: Sized,
{ {

View file

@ -37,6 +37,13 @@ impl<V: 'static> Element<V> for Frame<V> {
} }
fn paint(&mut self, layout: Layout, view: &mut V, cx: &mut PaintContext<V>) -> Result<()> { fn paint(&mut self, layout: Layout, view: &mut V, cx: &mut PaintContext<V>) -> Result<()> {
cx.scene.push_quad(gpui::scene::Quad {
bounds: layout.bounds,
background: self.style.fill.color().map(Into::into),
border: Default::default(),
corner_radii: Default::default(),
});
for child in &mut self.children { for child in &mut self.children {
child.paint(view, cx)?; child.paint(view, cx)?;
} }

View file

@ -1,20 +1,14 @@
#![allow(dead_code, unused_variables)] #![allow(dead_code, unused_variables)]
use element::{AnyElement, Element}; use element::Element;
use frame::frame; use frame::frame;
use gpui::{
geometry::{rect::RectF, vector::vec2f},
platform::WindowOptions,
};
use log::LevelFilter; use log::LevelFilter;
use simplelog::SimpleLogger; use simplelog::SimpleLogger;
fn main() { use style::percent;
SimpleLogger::init(LevelFilter::Info, Default::default()).expect("could not initialize logger");
gpui::App::new(()).unwrap().run(|cx| {
cx.add_window(Default::default(), |_| {
view(|_| workspace(&rose_pine::moon()))
});
cx.platform().activate(true);
});
}
use themes::{rose_pine, ThemeColors}; use themes::{rose_pine, ThemeColors};
use view::view; use view::view;
@ -26,16 +20,28 @@ mod style;
mod themes; mod themes;
mod view; mod view;
pub struct Playground<V: 'static>(AnyElement<V>); fn main() {
SimpleLogger::init(LevelFilter::Info, Default::default()).expect("could not initialize logger");
impl<V> Playground<V> { gpui::App::new(()).unwrap().run(|cx| {
pub fn new() -> Self { cx.add_window(
Self(workspace(&rose_pine::moon()).into_any()) WindowOptions {
} bounds: gpui::platform::WindowBounds::Fixed(RectF::new(
vec2f(0., 0.),
vec2f(400., 300.),
)),
center: true,
..Default::default()
},
|_| view(|_| workspace(&rose_pine::moon())),
);
cx.platform().activate(true);
});
} }
fn workspace<V: 'static>(theme: &ThemeColors) -> impl Element<V> { fn workspace<V: 'static>(theme: &ThemeColors) -> impl Element<V> {
frame() // frame().w_full().h_half().fill(theme.success(0.5))
frame().h_full().w(percent(50.)).fill(theme.success(0.5))
} }
// todo!() // todo!()
// // column() // // column()

View file

@ -239,10 +239,10 @@ impl Edges<Length> {
pub const fn zero() -> Self { pub const fn zero() -> Self {
Self { Self {
top: Length::Length(DefinedLength::Pixels(0.0)), top: Length::Defined(DefinedLength::Pixels(0.0)),
right: Length::Length(DefinedLength::Pixels(0.0)), right: Length::Defined(DefinedLength::Pixels(0.0)),
bottom: Length::Length(DefinedLength::Pixels(0.0)), bottom: Length::Defined(DefinedLength::Pixels(0.0)),
left: Length::Length(DefinedLength::Pixels(0.0)), left: Length::Defined(DefinedLength::Pixels(0.0)),
} }
} }
@ -272,7 +272,9 @@ impl DefinedLength {
match self { match self {
DefinedLength::Pixels(pixels) => taffy::style::LengthPercentage::Length(*pixels), DefinedLength::Pixels(pixels) => taffy::style::LengthPercentage::Length(*pixels),
DefinedLength::Rems(rems) => taffy::style::LengthPercentage::Length(rems * rem_size), DefinedLength::Rems(rems) => taffy::style::LengthPercentage::Length(rems * rem_size),
DefinedLength::Percent(percent) => taffy::style::LengthPercentage::Percent(*percent), DefinedLength::Percent(percent) => {
taffy::style::LengthPercentage::Percent(*percent / 100.)
}
} }
} }
} }
@ -280,14 +282,30 @@ impl DefinedLength {
/// A length that can be defined in pixels, rems, percent of parent, or auto. /// A length that can be defined in pixels, rems, percent of parent, or auto.
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub enum Length { pub enum Length {
Length(DefinedLength), Defined(DefinedLength),
Auto, Auto,
} }
pub fn auto() -> Length {
Length::Auto
}
pub fn percent(percent: f32) -> DefinedLength {
DefinedLength::Percent(percent)
}
pub fn rems(rems: f32) -> DefinedLength {
DefinedLength::Rems(rems)
}
pub fn pixels(pixels: f32) -> DefinedLength {
DefinedLength::Pixels(pixels)
}
impl Length { impl Length {
fn to_taffy(&self, rem_size: f32) -> taffy::prelude::LengthPercentageAuto { fn to_taffy(&self, rem_size: f32) -> taffy::prelude::LengthPercentageAuto {
match self { match self {
Length::Length(length) => length.to_taffy(rem_size).into(), Length::Defined(length) => length.to_taffy(rem_size).into(),
Length::Auto => taffy::prelude::LengthPercentageAuto::Auto, Length::Auto => taffy::prelude::LengthPercentageAuto::Auto,
} }
} }
@ -295,7 +313,7 @@ impl Length {
impl From<DefinedLength> for Length { impl From<DefinedLength> for Length {
fn from(value: DefinedLength) -> Self { fn from(value: DefinedLength) -> Self {
Length::Length(value) Length::Defined(value)
} }
} }
@ -304,8 +322,22 @@ pub enum Fill {
Color(Hsla), Color(Hsla),
} }
impl Fill {
pub fn color(&self) -> Option<Hsla> {
match self {
Fill::Color(color) => Some(*color),
}
}
}
impl Default for Fill { impl Default for Fill {
fn default() -> Self { fn default() -> Self {
Self::Color(Hsla::default()) Self::Color(Hsla::default())
} }
} }
impl From<Hsla> for Fill {
fn from(color: Hsla) -> Self {
Self::Color(color)
}
}

View file

@ -20,7 +20,7 @@ pub fn tailwind_lengths(_attr: TokenStream, item: TokenStream) -> TokenStream {
let mut output_functions = TokenStream2::new(); let mut output_functions = TokenStream2::new();
for (length, value) in fixed_lengths() { for (length, value) in fixed_lengths() {
let function_name = format_ident!("{}_{}", function_signature.ident, length); let function_name = format_ident!("{}{}", function_signature.ident, length);
output_functions.extend(quote! { output_functions.extend(quote! {
#visibility fn #function_name(mut self) -> Self #where_clause { #visibility fn #function_name(mut self) -> Self #where_clause {
let #argument_name = #value.into(); let #argument_name = #value.into();

View file

@ -214,12 +214,12 @@ impl<'a> WindowContext<'a> {
self.window.layout_engines.last_mut() self.window.layout_engines.last_mut()
} }
pub fn push_layout_engine(&mut self) { pub fn push_layout_engine(&mut self, engine: LayoutEngine) {
self.window.layout_engines.push(LayoutEngine::new()); self.window.layout_engines.push(engine);
} }
pub fn pop_layout_engine(&mut self) { pub fn pop_layout_engine(&mut self) -> Option<LayoutEngine> {
self.window.layout_engines.pop(); self.window.layout_engines.pop()
} }
pub fn remove_window(&mut self) { pub fn remove_window(&mut self) {
@ -1235,12 +1235,13 @@ impl<'a> WindowContext<'a> {
} }
} }
#[derive(Default)]
pub struct LayoutEngine(Taffy); pub struct LayoutEngine(Taffy);
pub use taffy::style::Style as LayoutStyle; pub use taffy::style::Style as LayoutStyle;
impl LayoutEngine { impl LayoutEngine {
fn new() -> Self { pub fn new() -> Self {
Self(Taffy::new()) Default::default()
} }
pub fn add_node<C>(&mut self, style: LayoutStyle, children: C) -> Result<LayoutNodeId> pub fn add_node<C>(&mut self, style: LayoutStyle, children: C) -> Result<LayoutNodeId>

View file

@ -28,7 +28,7 @@ pub mod keymap_matcher;
pub mod platform; pub mod platform;
pub use gpui_macros::{test, Element}; pub use gpui_macros::{test, Element};
pub use window::{ pub use window::{
Axis, Layout, LayoutNodeId, RectFExt, SizeConstraint, Vector2FExt, WindowContext, Axis, Layout, LayoutEngine, LayoutNodeId, RectFExt, SizeConstraint, Vector2FExt, WindowContext,
}; };
pub use anyhow; pub use anyhow;