From 19d75bfcc2bee4e95d03f6d9597552c273de79f4 Mon Sep 17 00:00:00 2001 From: Ryan McGrath Date: Sat, 25 May 2019 02:45:47 -0700 Subject: [PATCH] Fix to actually display the child text node, add support for more CSS styles, clean up a slew of warnings --- alchemy/src/components/text.rs | 39 ++++++++++++++++++++++++++------- alchemy/src/reconciler.rs | 9 ++++---- alchemy/src/theme/mod.rs | 1 - alchemy/src/theme/stylesheet.rs | 18 +++++++-------- cocoa/src/text.rs | 12 ++++------ styles/src/styles.rs | 23 +++++++++++++++++-- 6 files changed, 70 insertions(+), 32 deletions(-) diff --git a/alchemy/src/components/text.rs b/alchemy/src/components/text.rs index 1b6f86a..23f8a7c 100644 --- a/alchemy/src/components/text.rs +++ b/alchemy/src/components/text.rs @@ -22,11 +22,35 @@ use alchemy_cocoa::text::{Text as PlatformTextBridge}; /// ``` /// /// ``` -pub struct Text(Mutex); +pub struct Text { + text: String, + bridge: Mutex +} impl Default for Text { fn default() -> Text { - Text(Mutex::new(PlatformTextBridge::new())) + Text { + text: "".into(), + bridge: Mutex::new(PlatformTextBridge::new()) + } + } +} + +impl Text { + // This is very naive for now, but it's fine - we probably + // want to do some fun stuff here later with stylized text + // rendering anyway. + fn compare_and_update_text(&mut self, props: &Props) { + let text = props.children.iter().map(|child| match child { + RSX::VirtualText(s) => s.0.clone(), + _ => String::new() + }).collect::(); + + if self.text != text { + let mut bridge = self.bridge.lock().unwrap(); + bridge.set_text(&text); + self.text = text; + } } } @@ -34,25 +58,24 @@ impl Component for Text { fn has_native_backing_node(&self) -> bool { true } fn borrow_native_backing_node(&self) -> Option { - let bridge = self.0.lock().unwrap(); + let bridge = self.bridge.lock().unwrap(); Some(bridge.borrow_native_backing_node()) } // Shouldn't be allowed to have child elements... or, should it? // Panic might not be right here, but eh, should probably do something. - fn append_child_component(&self, component: &Component) {} + fn append_child_component(&self, _component: &Component) {} fn apply_styles(&self, layout: &Layout, style: &Style) { - let mut bridge = self.0.lock().unwrap(); + let mut bridge = self.bridge.lock().unwrap(); bridge.apply_styles(layout, style); } fn component_did_mount(&mut self, props: &Props) { - let mut bridge = self.0.lock().unwrap(); - bridge.set_text("LOL"); + self.compare_and_update_text(props); } - fn render(&self, props: &Props) -> Result { + fn render(&self, _props: &Props) -> Result { Ok(RSX::None) } } diff --git a/alchemy/src/reconciler.rs b/alchemy/src/reconciler.rs index 15a5c71..97e630f 100644 --- a/alchemy/src/reconciler.rs +++ b/alchemy/src/reconciler.rs @@ -7,7 +7,6 @@ use std::mem::{discriminant, swap}; use alchemy_styles::Stretch; use alchemy_styles::styles::Style; -use alchemy_lifecycle::traits::Component; use alchemy_lifecycle::rsx::{StylesList, RSX, VirtualNode}; /// Given two node trees, will compare, diff, and apply changes in a recursive fashion. @@ -199,9 +198,11 @@ fn find_and_link_layout_nodes(parent_node: &mut VirtualNode, child_tree: &mut Vi if let (Some(parent_instance), Some(child_instance)) = (&mut parent_node.instance, &mut child_tree.instance) { if let (Some(parent_layout_node), Some(child_layout_node)) = (&parent_node.layout_node, &child_tree.layout_node) { stretch.add_child(*parent_layout_node, *child_layout_node)?; - if let (parent_component, child_component) = (parent_instance.write().unwrap(), child_instance.read().unwrap()) { - parent_component.append_child_component(&*child_component); - } + + let parent_component = parent_instance.write().unwrap(); + let child_component = child_instance.read().unwrap(); + parent_component.append_child_component(&*child_component); + return Ok(()); } } diff --git a/alchemy/src/theme/mod.rs b/alchemy/src/theme/mod.rs index 38ead7f..8e98889 100644 --- a/alchemy/src/theme/mod.rs +++ b/alchemy/src/theme/mod.rs @@ -73,7 +73,6 @@ impl ThemeEngine { let mut themes = self.themes.write().unwrap(); if !themes.contains_key(key) { themes.insert(key.to_string(), stylesheet); - println!("REGISTERED STYLES"); return; } diff --git a/alchemy/src/theme/stylesheet.rs b/alchemy/src/theme/stylesheet.rs index 25993d5..589f497 100644 --- a/alchemy/src/theme/stylesheet.rs +++ b/alchemy/src/theme/stylesheet.rs @@ -97,9 +97,9 @@ fn reduce_styles_into_style(styles: &Vec, layout: &mut Style) { Styles::FontFamily(_val) => { }, Styles::FontLineHeight(_val) => { }, - Styles::FontSize(_val) => { }, - Styles::FontStyle(_val) => { }, - Styles::FontWeight(_val) => { }, + Styles::FontSize(val) => { layout.font_size = *val; }, + Styles::FontStyle(val) => { layout.font_style = *val; }, + Styles::FontWeight(val) => { layout.font_weight = *val; }, Styles::Height(val) => { layout.size = Size { @@ -201,8 +201,8 @@ fn reduce_styles_into_style(styles: &Vec, layout: &mut Style) { }; }, - Styles::Opacity(val) => { }, - Styles::Overflow(val) => { }, + Styles::Opacity(val) => { layout.opacity = *val; }, + Styles::Overflow(val) => { layout.overflow = *val; }, Styles::PaddingBottom(val) => { layout.padding = Rect { @@ -278,11 +278,11 @@ fn reduce_styles_into_style(styles: &Vec, layout: &mut Style) { }; }, - Styles::TextAlignment(val) => { }, + Styles::TextAlignment(val) => { layout.text_alignment = *val; }, Styles::TextColor(val) => { layout.text_color = *val; }, - Styles::TextDecorationColor(val) => { }, - Styles::TextShadowColor(val) => { }, - Styles::TintColor(val) => { }, + Styles::TextDecorationColor(val) => { layout.text_decoration_color = *val; }, + Styles::TextShadowColor(val) => { layout.text_shadow_color = *val; }, + Styles::TintColor(val) => { layout.tint_color = *val; }, Styles::Top(val) => { layout.position = Rect { diff --git a/cocoa/src/text.rs b/cocoa/src/text.rs index 76095d0..825dce7 100644 --- a/cocoa/src/text.rs +++ b/cocoa/src/text.rs @@ -30,7 +30,7 @@ pub struct Text { inner_share: ShareId, background_color: Id, text_color: Id, - text: Id + //text: Id } impl Text { @@ -38,7 +38,7 @@ impl Text { /// flipping occur (macOS still uses (0,0) as lower-left by default), and opting in to layer /// backed views for smoother scrolling. pub fn new() -> Text { - let (inner_mut, inner_share, s) = unsafe { + let (inner_mut, inner_share) = unsafe { let initial_string = NSString::alloc(nil).init_str("wut wut"); let view: id = msg_send![register_class(), labelWithString:initial_string]; msg_send![view, setSelectable:YES]; @@ -46,7 +46,7 @@ impl Text { msg_send![view, setWantsLayer:YES]; msg_send![view, setLayerContentsRedrawPolicy:1]; let x = view.clone(); - (Id::from_ptr(view), ShareId::from_ptr(x), Id::from_ptr(initial_string)) + (Id::from_ptr(view), ShareId::from_ptr(x)) //, Id::from_ptr(initial_string)) }; Text { @@ -54,7 +54,7 @@ impl Text { inner_share: inner_share, background_color: Color::transparent().into_nscolor(), text_color: Color::transparent().into_nscolor(), - text: s + // text: s } } @@ -117,10 +117,6 @@ fn register_class() -> *const Class { // Force NSText to render from the top-left, not bottom-left //decl.add_method(sel!(isFlipped), enforce_normalcy as extern fn(&Object, _) -> BOOL); - // Opt-in to AutoLayout - decl.add_method(sel!(isSelectable), enforce_normalcy as extern fn(&Object, _) -> BOOL); - decl.add_method(sel!(drawsBackground), enforce_normalcy as extern fn(&Object, _) -> BOOL); - // Request optimized backing layers //decl.add_method(sel!(updateLayer), update_layer as extern fn(&Object, _)); //decl.add_method(sel!(wantsUpdateLayer), enforce_normalcy as extern fn(&Object, _) -> BOOL); diff --git a/styles/src/styles.rs b/styles/src/styles.rs index e8b621d..cf7bb64 100644 --- a/styles/src/styles.rs +++ b/styles/src/styles.rs @@ -337,7 +337,15 @@ pub struct Style { // Appearance-based styles pub background_color: Color, - pub text_color: Color + pub font_size: f32, + pub font_style: FontStyle, + pub font_weight: FontWeight, + pub opacity: f32, + pub text_alignment: TextAlignment, + pub text_color: Color, + pub text_decoration_color: Color, + pub text_shadow_color: Color, + pub tint_color: Color } impl Default for Style { @@ -365,7 +373,18 @@ impl Default for Style { max_size: Default::default(), aspect_ratio: Default::default(), background_color: Color::transparent(), - text_color: Color::transparent() + + // @TODO: We can definitely judge a default value better here. + font_size: 14., + + font_style: FontStyle::default(), + font_weight: FontWeight::default(), + opacity: 1., + text_alignment: TextAlignment::default(), + text_color: Color::transparent(), + text_decoration_color: Color::transparent(), + text_shadow_color: Color::transparent(), + tint_color: Color::transparent() } } }