Get a 50% colored box rendering
Co-Authored-By: Mikayla Maki <mikayla@zed.dev>
This commit is contained in:
parent
740b105330
commit
f9858445b8
8 changed files with 130 additions and 49 deletions
|
@ -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(
|
||||||
|
|
|
@ -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,
|
||||||
{
|
{
|
||||||
|
|
|
@ -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)?;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue