diff --git a/Cargo.lock b/Cargo.lock index bf64781781dc36c860339714513625e51618dfa1..15956dd5a026157a779d05dcb5803873f1d32385 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5291,6 +5291,7 @@ checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" name = "playground" version = "0.1.0" dependencies = [ + "anyhow", "derive_more", "gpui", "log", @@ -5298,6 +5299,7 @@ dependencies = [ "serde", "simplelog", "smallvec", + "util", ] [[package]] diff --git a/crates/gpui/playground/Cargo.toml b/crates/gpui/playground/Cargo.toml index a9d9e226f45138493bc711a60c0be6db9649851b..db60eda1bb8104106c88553b76f7eb772cb67ea5 100644 --- a/crates/gpui/playground/Cargo.toml +++ b/crates/gpui/playground/Cargo.toml @@ -8,6 +8,7 @@ version = "0.1.0" edition = "2021" [dependencies] +anyhow.workspace = true derive_more.workspace = true gpui = { path = ".." } log.workspace = true @@ -15,6 +16,7 @@ optional_struct = "0.3.1" serde.workspace = true simplelog = "0.9" smallvec.workspace = true +util = { path = "../../util" } [dev-dependencies] gpui = { path = "..", features = ["test-support"] } diff --git a/crates/gpui/playground/src/color.rs b/crates/gpui/playground/src/color.rs index 2742c4a48314cc95c9be61bfa22294c3189e93df..afbe8e06dbbce69f34410fc191ab2cf9fe849905 100644 --- a/crates/gpui/playground/src/color.rs +++ b/crates/gpui/playground/src/color.rs @@ -37,7 +37,12 @@ impl Lerp for Range { impl From for Rgba { fn from(value: gpui::color::Color) -> Self { - todo!() + Self { + r: value.0.r as f32 / 255.0, + g: value.0.g as f32 / 255.0, + b: value.0.b as f32 / 255.0, + a: value.0.a as f32 / 255.0, + } } } @@ -199,6 +204,12 @@ impl From for Hsla { } } +impl Into for Hsla { + fn into(self) -> gpui::color::Color { + Rgba::from(self).into() + } +} + pub struct ColorScale { colors: SmallVec<[Hsla; 2]>, positions: SmallVec<[f32; 2]>, diff --git a/crates/gpui/playground/src/frame.rs b/crates/gpui/playground/src/frame.rs index 5f059a67cc5bede306868b9152c4161b7568c6c9..968d356b87e5dcb44b9d08fd8b81c32fd91f2705 100644 --- a/crates/gpui/playground/src/frame.rs +++ b/crates/gpui/playground/src/frame.rs @@ -4,7 +4,7 @@ use derive_more::{Add, Deref, DerefMut}; use gpui::{ color::Color, elements::layout_highlighted_chunks, - fonts::HighlightStyle, + fonts::{HighlightStyle, Underline}, geometry::{ rect::RectF, vector::{vec2f, Vector2F}, @@ -20,6 +20,7 @@ use length::{Length, Rems}; use log::warn; use optional_struct::*; use std::{any::Any, borrow::Cow, f32, ops::Range, sync::Arc}; +use util::ResultExt; use crate::color::{Hsla, Rgba}; @@ -77,17 +78,26 @@ impl Element for Frame { view: &mut V, cx: &mut LayoutContext, ) -> (Vector2F, Self::LayoutState) { + let mut pushed_text_style = false; if self.style.text.is_some() { let mut style = TextStyle::from_legacy(&cx.text_style(), cx); self.style.text.clone().apply_to(&mut style); - cx.push_text_style(style.to_legacy()); + if let Some(legacy_style) = style.to_legacy(cx).log_err() { + cx.push_text_style(legacy_style); + pushed_text_style = true; + } } let layout = if let Some(axis) = self.style.axis.to_2d() { self.layout_xy(axis, constraint, cx.rem_pixels(), view, cx) } else { - todo!() + unimplemented!() }; + + if pushed_text_style { + cx.pop_text_style(); + } + (layout.size.max(constraint.min), layout) } @@ -183,7 +193,7 @@ impl Element for Frame { child_origin.set(axis, child_origin.get(axis) + child.size().get(axis)); } } else { - todo!(); + unimplemented!(); } } } @@ -623,6 +633,8 @@ struct TextStyle { weight: FontWeight, style: FontStyle, color: Hsla, + soft_wrap: bool, + underline: Underline, } impl TextStyle { @@ -633,10 +645,12 @@ impl TextStyle { weight: text_style.font_properties.weight.into(), style: text_style.font_properties.style.into(), color: text_style.color.into(), + soft_wrap: text_style.soft_wrap, + underline: text_style.underline, } } - fn to_legacy(&self, cx: &WindowContext) -> Result { + fn to_legacy(&self, cx: &WindowContext) -> anyhow::Result { let font_family_id = cx.font_cache().load_family( &[self.font_family.as_ref()], &gpui::fonts::Features::default(), @@ -648,17 +662,17 @@ impl TextStyle { }; let font_id = cx .font_cache() - .select_font(font_family_id, &font_properties); + .select_font(font_family_id, &font_properties)?; Ok(gpui::fonts::TextStyle { color: self.color.into(), font_family_name: self.font_family.clone(), font_family_id, font_id, - font_size: todo!(), + font_size: self.size.to_pixels(16.), // TODO: Get this from the context! font_properties, - underline: todo!(), - soft_wrap: true, + underline: self.underline, + soft_wrap: self.soft_wrap, }) } } @@ -666,10 +680,10 @@ impl TextStyle { impl OptionalTextStyle { pub fn is_some(&self) -> bool { self.size.is_some() - && self.font_family.is_some() - && self.weight.is_some() - && self.style.is_some() - && self.color.is_some() + || self.font_family.is_some() + || self.weight.is_some() + || self.style.is_some() + || self.color.is_some() } } @@ -1211,6 +1225,18 @@ impl From for FontStyle { } } +impl Into for FontStyle { + fn into(self) -> gpui::fonts::Style { + use gpui::fonts::Style; + + match self { + FontStyle::Normal => Style::Normal, + FontStyle::Italic => Style::Italic, + FontStyle::Oblique => Style::Oblique, + } + } +} + #[derive(Clone, Copy, Default, Debug, PartialEq, Eq)] enum FontWeight { Thin, @@ -1229,16 +1255,44 @@ impl From for FontWeight { fn from(value: gpui::fonts::Weight) -> Self { use gpui::fonts::Weight; - match value { - Weight::THIN => FontWeight::Thin, - Weight::EXTRA_LIGHT => FontWeight::ExtraLight, - Weight::LIGHT => FontWeight::Light, - Weight::NORMAL => FontWeight::Normal, - Weight::MEDIUM => FontWeight::Medium, - Weight::SEMIBOLD => FontWeight::Semibold, - Weight::BOLD => FontWeight::Bold, - Weight::EXTRA_BOLD => FontWeight::ExtraBold, - Weight::BLACK => FontWeight::Black, + if value == Weight::THIN { + FontWeight::Thin + } else if value == Weight::EXTRA_LIGHT { + FontWeight::ExtraLight + } else if value == Weight::LIGHT { + FontWeight::Light + } else if value == Weight::NORMAL { + FontWeight::Normal + } else if value == Weight::MEDIUM { + FontWeight::Medium + } else if value == Weight::SEMIBOLD { + FontWeight::Semibold + } else if value == Weight::BOLD { + FontWeight::Bold + } else if value == Weight::EXTRA_BOLD { + FontWeight::ExtraBold + } else if value == Weight::BLACK { + FontWeight::Black + } else { + panic!("unknown font weight: {:?}", value); + } + } +} + +impl Into for FontWeight { + fn into(self) -> gpui::fonts::Weight { + use gpui::fonts::Weight; + + match self { + FontWeight::Thin => Weight::THIN, + FontWeight::ExtraLight => Weight::EXTRA_LIGHT, + FontWeight::Light => Weight::LIGHT, + FontWeight::Normal => Weight::NORMAL, + FontWeight::Medium => Weight::MEDIUM, + FontWeight::Semibold => Weight::SEMIBOLD, + FontWeight::Bold => Weight::BOLD, + FontWeight::ExtraBold => Weight::EXTRA_BOLD, + FontWeight::Black => Weight::BLACK, } } } @@ -1333,7 +1387,7 @@ impl Element for Text { let mut wrap_boundaries = Vec::new(); let mut wrapper = cx.font_cache.line_wrapper(font_id, style.font_size); for (line, shaped_line) in self.text.split('\n').zip(&shaped_lines) { - if style.soft_wrap { + if style.soft_wrap && constraint.max.x() > 0. { let boundaries = wrapper .wrap_shaped_line(line, shaped_line, constraint.max.x()) .collect::>(); @@ -1346,13 +1400,8 @@ impl Element for Text { } let line_height = cx.font_cache.line_height(style.font_size); - let size = vec2f( - max_line_width - .ceil() - .max(constraint.min.x()) - .min(constraint.max.x()), - (line_height * line_count as f32).ceil(), - ); + let size = vec2f(max_line_width, (line_height * line_count as f32).ceil()); + ( size, TextLayout {