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

View file

@ -1,6 +1,6 @@
use crate::{
adapter::Adapter,
style::{DefinedLength, Display, Fill, Overflow, Position, Style},
style::{DefinedLength, Display, Fill, Length, Overflow, Position, Style},
};
use anyhow::Result;
use derive_more::{Deref, DerefMut};
@ -168,7 +168,7 @@ pub trait Element<V: 'static>: 'static + Clone {
}
#[tailwind_lengths]
fn inset(mut self, length: DefinedLength) -> Self
fn inset_(mut self, length: DefinedLength) -> Self
where
Self: Sized,
{
@ -179,8 +179,24 @@ pub trait Element<V: 'static>: 'static + Clone {
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]
fn w(mut self, length: DefinedLength) -> Self
fn w_(mut self, length: DefinedLength) -> Self
where
Self: Sized,
{
@ -189,7 +205,7 @@ pub trait Element<V: 'static>: 'static + Clone {
}
#[tailwind_lengths]
fn min_w(mut self, length: DefinedLength) -> Self
fn min_w_(mut self, length: DefinedLength) -> Self
where
Self: Sized,
{
@ -197,17 +213,33 @@ pub trait Element<V: 'static>: 'static + Clone {
self
}
#[tailwind_lengths]
fn h(mut self, length: DefinedLength) -> Self
fn h(mut self, height: impl Into<Length>) -> Self
where
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
}
#[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
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<()> {
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 {
child.paint(view, cx)?;
}

View file

@ -1,20 +1,14 @@
#![allow(dead_code, unused_variables)]
use element::{AnyElement, Element};
use element::Element;
use frame::frame;
use gpui::{
geometry::{rect::RectF, vector::vec2f},
platform::WindowOptions,
};
use log::LevelFilter;
use simplelog::SimpleLogger;
fn main() {
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 style::percent;
use themes::{rose_pine, ThemeColors};
use view::view;
@ -26,16 +20,28 @@ mod style;
mod themes;
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> {
pub fn new() -> Self {
Self(workspace(&rose_pine::moon()).into_any())
}
gpui::App::new(()).unwrap().run(|cx| {
cx.add_window(
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> {
frame()
// frame().w_full().h_half().fill(theme.success(0.5))
frame().h_full().w(percent(50.)).fill(theme.success(0.5))
}
// todo!()
// // column()

View file

@ -239,10 +239,10 @@ impl Edges<Length> {
pub const fn zero() -> Self {
Self {
top: Length::Length(DefinedLength::Pixels(0.0)),
right: Length::Length(DefinedLength::Pixels(0.0)),
bottom: Length::Length(DefinedLength::Pixels(0.0)),
left: Length::Length(DefinedLength::Pixels(0.0)),
top: Length::Defined(DefinedLength::Pixels(0.0)),
right: Length::Defined(DefinedLength::Pixels(0.0)),
bottom: Length::Defined(DefinedLength::Pixels(0.0)),
left: Length::Defined(DefinedLength::Pixels(0.0)),
}
}
@ -272,7 +272,9 @@ impl DefinedLength {
match self {
DefinedLength::Pixels(pixels) => taffy::style::LengthPercentage::Length(*pixels),
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.
#[derive(Clone, Copy)]
pub enum Length {
Length(DefinedLength),
Defined(DefinedLength),
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 {
fn to_taffy(&self, rem_size: f32) -> taffy::prelude::LengthPercentageAuto {
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,
}
}
@ -295,7 +313,7 @@ impl Length {
impl From<DefinedLength> for Length {
fn from(value: DefinedLength) -> Self {
Length::Length(value)
Length::Defined(value)
}
}
@ -304,8 +322,22 @@ pub enum Fill {
Color(Hsla),
}
impl Fill {
pub fn color(&self) -> Option<Hsla> {
match self {
Fill::Color(color) => Some(*color),
}
}
}
impl Default for Fill {
fn default() -> Self {
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();
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! {
#visibility fn #function_name(mut self) -> Self #where_clause {
let #argument_name = #value.into();

View file

@ -214,12 +214,12 @@ impl<'a> WindowContext<'a> {
self.window.layout_engines.last_mut()
}
pub fn push_layout_engine(&mut self) {
self.window.layout_engines.push(LayoutEngine::new());
pub fn push_layout_engine(&mut self, engine: LayoutEngine) {
self.window.layout_engines.push(engine);
}
pub fn pop_layout_engine(&mut self) {
self.window.layout_engines.pop();
pub fn pop_layout_engine(&mut self) -> Option<LayoutEngine> {
self.window.layout_engines.pop()
}
pub fn remove_window(&mut self) {
@ -1235,12 +1235,13 @@ impl<'a> WindowContext<'a> {
}
}
#[derive(Default)]
pub struct LayoutEngine(Taffy);
pub use taffy::style::Style as LayoutStyle;
impl LayoutEngine {
fn new() -> Self {
Self(Taffy::new())
pub fn new() -> Self {
Default::default()
}
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 use gpui_macros::{test, Element};
pub use window::{
Axis, Layout, LayoutNodeId, RectFExt, SizeConstraint, Vector2FExt, WindowContext,
Axis, Layout, LayoutEngine, LayoutNodeId, RectFExt, SizeConstraint, Vector2FExt, WindowContext,
};
pub use anyhow;