diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 10d1dc69972453011a5f40180e1e98141da49c57..dda02fa4d6d3dc569e73ee09a333602d42993078 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -10,7 +10,6 @@ mod window_input_handler; use crate::{ elements::{AnyElement, AnyRootElement, RootElement}, executor::{self, Task}, - fonts::TextStyle, json, keymap_matcher::{self, Binding, KeymapContext, KeymapMatcher, Keystroke, MatchResult}, platform::{ @@ -3345,10 +3344,6 @@ impl<'a, 'b, V: 'static> ViewContext<'a, 'b, V> { self.element_state::(element_id, T::default()) } - pub fn rem_pixels(&self) -> f32 { - 16. - } - pub fn default_element_state_dynamic( &mut self, tag: TypeTag, @@ -3447,17 +3442,6 @@ impl BorrowWindowContext for ViewContext<'_, '_, V> { } } -/// Methods shared by both LayoutContext and PaintContext -/// -/// It's that PaintContext should be implemented in terms of layout context and -/// deref to it, in which case we wouldn't need this. -pub trait RenderContext<'a, 'b, V> { - fn text_style(&self) -> TextStyle; - fn push_text_style(&mut self, style: TextStyle); - fn pop_text_style(&mut self); - fn as_view_context(&mut self) -> &mut ViewContext<'a, 'b, V>; -} - pub struct LayoutContext<'a, 'b, 'c, V> { // Nathan: Making this is public while I work on gpui2. pub view_context: &'c mut ViewContext<'a, 'b, V>, @@ -3520,38 +3504,6 @@ impl<'a, 'b, 'c, V> LayoutContext<'a, 'b, 'c, V> { .or_default() .push(self_view_id); } - - pub fn with_text_style(&mut self, style: TextStyle, f: F) -> T - where - F: FnOnce(&mut Self) -> T, - { - self.push_text_style(style); - let result = f(self); - self.pop_text_style(); - result - } -} - -impl<'a, 'b, 'c, V> RenderContext<'a, 'b, V> for LayoutContext<'a, 'b, 'c, V> { - fn text_style(&self) -> TextStyle { - self.window - .text_style_stack - .last() - .cloned() - .unwrap_or(TextStyle::default(&self.font_cache)) - } - - fn push_text_style(&mut self, style: TextStyle) { - self.window.text_style_stack.push(style); - } - - fn pop_text_style(&mut self) { - self.window.text_style_stack.pop(); - } - - fn as_view_context(&mut self) -> &mut ViewContext<'a, 'b, V> { - &mut self.view_context - } } impl<'a, 'b, 'c, V> Deref for LayoutContext<'a, 'b, 'c, V> { diff --git a/crates/gpui/src/app/window.rs b/crates/gpui/src/app/window.rs index 61a468d11b564af4181870ed735b7a86b25dffb8..18691934e5992d34f3ff80c1ef9e35f4f6235b88 100644 --- a/crates/gpui/src/app/window.rs +++ b/crates/gpui/src/app/window.rs @@ -1,6 +1,6 @@ use crate::{ elements::AnyRootElement, - fonts::TextStyle, + fonts::{TextStyle, TextStyleRefinement}, geometry::{rect::RectF, Size}, json::ToJson, keymap_matcher::{Binding, KeymapContext, Keystroke, MatchResult}, @@ -235,6 +235,10 @@ impl<'a> WindowContext<'a> { .push_back(Effect::RepaintWindow { window }); } + pub fn rem_size(&self) -> f32 { + 16. + } + pub fn layout_engine(&mut self) -> Option<&mut LayoutEngine> { self.window.layout_engines.last_mut() } @@ -1284,8 +1288,14 @@ impl<'a> WindowContext<'a> { .unwrap_or(TextStyle::default(&self.font_cache)) } - pub fn push_text_style(&mut self, style: TextStyle) { + pub fn push_text_style(&mut self, refinement: &TextStyleRefinement) -> Result<()> { + let mut style = self.text_style(); + style.refine(refinement, self.font_cache())?; + + dbg!(&style); + self.window.text_style_stack.push(style); + Ok(()) } pub fn pop_text_style(&mut self) { diff --git a/crates/gpui/src/fonts.rs b/crates/gpui/src/fonts.rs index 4b89dab6eacb2368bfbb8e5af67e2124563f6fba..4b46f8eb792c0efa6a0c1d1176d0f85607d031a2 100644 --- a/crates/gpui/src/fonts.rs +++ b/crates/gpui/src/fonts.rs @@ -60,7 +60,7 @@ pub struct Features { pub zero: Option, } -#[derive(Clone, Debug, JsonSchema, Refineable)] +#[derive(Clone, Debug, JsonSchema)] pub struct TextStyle { pub color: Color, pub font_family_name: Arc, @@ -80,19 +80,78 @@ impl TextStyle { ..Default::default() } } +} + +impl TextStyle { + pub fn refine( + &mut self, + refinement: &TextStyleRefinement, + font_cache: &FontCache, + ) -> Result<()> { + if let Some(font_size) = refinement.font_size { + self.font_size = font_size; + } + if let Some(color) = refinement.color { + self.color = color; + } + if let Some(underline) = refinement.underline { + self.underline = underline; + } + + let mut update_font_id = false; + if let Some(font_family) = refinement.font_family.clone() { + self.font_family_id = font_cache.load_family(&[&font_family], &Default::default())?; + self.font_family_name = font_family; + update_font_id = true; + } + if let Some(font_weight) = refinement.font_weight { + self.font_properties.weight = font_weight; + update_font_id = true; + } + if let Some(font_style) = refinement.font_style { + self.font_properties.style = font_style; + update_font_id = true; + } + + if update_font_id { + self.font_id = font_cache.select_font(self.font_family_id, &self.font_properties)?; + } - pub fn refine(self, refinement: TextStyleRefinement) -> TextStyle { - TextStyle { - color: refinement.color.unwrap_or(self.color), - font_family_name: refinement - .font_family_name - .unwrap_or_else(|| self.font_family_name.clone()), - font_family_id: refinement.font_family_id.unwrap_or(self.font_family_id), - font_id: refinement.font_id.unwrap_or(self.font_id), - font_size: refinement.font_size.unwrap_or(self.font_size), - font_properties: refinement.font_properties.unwrap_or(self.font_properties), - underline: refinement.underline.unwrap_or(self.underline), - soft_wrap: refinement.soft_wrap.unwrap_or(self.soft_wrap), + Ok(()) + } +} + +#[derive(Clone, Debug, Default)] +pub struct TextStyleRefinement { + pub color: Option, + pub font_family: Option>, + pub font_size: Option, + pub font_weight: Option, + pub font_style: Option