From 8780450bbd2992e479b5f539c20dd523738fdca9 Mon Sep 17 00:00:00 2001 From: Philipp Mildenberger Date: Thu, 9 Nov 2023 20:17:30 +0100 Subject: [PATCH] Add more String views (`&'static str`, `Cow<'static, str>`) --- examples/hello.rs | 2 +- src/view/text.rs | 79 ++++++++++++++++++++++++++++++++++++++++++++++ src/widget/text.rs | 7 ++-- 3 files changed, 84 insertions(+), 4 deletions(-) diff --git a/examples/hello.rs b/examples/hello.rs index 747018586..464501d1c 100644 --- a/examples/hello.rs +++ b/examples/hello.rs @@ -16,7 +16,7 @@ fn app_logic(data: &mut i32) -> impl View { *data += 1; }), h_stack(( - String::from("Buttons: "), + "Buttons: ", button("decrease", |data| { println!("clicked decrease"); *data -= 1; diff --git a/src/view/text.rs b/src/view/text.rs index 7576058b1..1f911027b 100644 --- a/src/view/text.rs +++ b/src/view/text.rs @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +use std::borrow::Cow; + use crate::view::{Id, ViewMarker}; use crate::widget::ChangeFlags; @@ -24,6 +26,83 @@ impl View for String { type Element = crate::widget::TextWidget; + fn build(&self, cx: &mut Cx) -> (crate::view::Id, Self::State, Self::Element) { + let (id, element) = + cx.with_new_id(|_| crate::widget::TextWidget::new(Cow::from(self.clone()))); + (id, (), element) + } + + fn rebuild( + &self, + _cx: &mut Cx, + prev: &Self, + _id: &mut Id, + _state: &mut Self::State, + element: &mut Self::Element, + ) -> ChangeFlags { + if prev != self { + element.set_text(Cow::from(self.clone())) + } else { + ChangeFlags::empty() + } + } + + fn message( + &self, + _id_path: &[xilem_core::Id], + _state: &mut Self::State, + _message: Box, + _app_state: &mut T, + ) -> xilem_core::MessageResult { + xilem_core::MessageResult::Nop + } +} + +impl ViewMarker for &'static str {} + +impl View for &'static str { + type State = (); + + type Element = crate::widget::TextWidget; + + fn build(&self, cx: &mut Cx) -> (crate::view::Id, Self::State, Self::Element) { + let (id, element) = cx.with_new_id(|_| crate::widget::TextWidget::new(Cow::from(*self))); + (id, (), element) + } + + fn rebuild( + &self, + _cx: &mut Cx, + prev: &Self, + _id: &mut Id, + _state: &mut Self::State, + element: &mut Self::Element, + ) -> ChangeFlags { + if prev != self { + element.set_text(Cow::from(*self)) + } else { + ChangeFlags::empty() + } + } + + fn message( + &self, + _id_path: &[xilem_core::Id], + _state: &mut Self::State, + _message: Box, + _app_state: &mut T, + ) -> xilem_core::MessageResult { + xilem_core::MessageResult::Nop + } +} + +impl ViewMarker for Cow<'static, str> {} + +impl View for Cow<'static, str> { + type State = (); + + type Element = crate::widget::TextWidget; + fn build(&self, cx: &mut Cx) -> (crate::view::Id, Self::State, Self::Element) { let (id, element) = cx.with_new_id(|_| crate::widget::TextWidget::new(self.clone())); (id, (), element) diff --git a/src/widget/text.rs b/src/widget/text.rs index 40e33d0cd..4da022d6d 100644 --- a/src/widget/text.rs +++ b/src/widget/text.rs @@ -13,6 +13,7 @@ // limitations under the License. use parley::{FontContext, Layout}; +use std::borrow::Cow; use vello::{ kurbo::{Affine, Size}, peniko::{Brush, Color}, @@ -27,16 +28,16 @@ use super::{ }; pub struct TextWidget { - text: String, + text: Cow<'static, str>, layout: Option>, } impl TextWidget { - pub fn new(text: String) -> TextWidget { + pub fn new(text: Cow<'static, str>) -> TextWidget { TextWidget { text, layout: None } } - pub fn set_text(&mut self, text: String) -> ChangeFlags { + pub fn set_text(&mut self, text: Cow<'static, str>) -> ChangeFlags { self.text = text; ChangeFlags::LAYOUT | ChangeFlags::PAINT }