use crate::prelude::*; use std::marker::PhantomData; pub struct TextBuilder = ()> { pub content: String, pub attrs: TextAttrs, pub hint: H, pub output: O, state: PhantomData, } impl> TextBuilder { pub fn size(mut self, size: impl UiNum) -> Self { self.attrs.font_size = size.to_f32(); self.attrs.line_height = self.attrs.font_size * LINE_HEIGHT_MULT; self } pub fn color(mut self, color: UiColor) -> Self { self.attrs.color = color; self } pub fn family(mut self, family: Family) -> Self { self.attrs.family = family; self } pub fn line_height(mut self, height: f32) -> Self { self.attrs.line_height = height; self } pub fn text_align(mut self, align: impl Into) -> Self { self.attrs.align = align.into(); self } pub fn center_text(mut self) -> Self { self.attrs.align = Align::CENTER; self } pub fn wrap(mut self, wrap: bool) -> Self { self.attrs.wrap = wrap; self } pub fn editable(self, mode: EditMode) -> TextBuilder { TextBuilder { content: self.content, attrs: self.attrs, hint: self.hint, output: TextEditOutput { mode }, state: PhantomData, } } } impl TextBuilder { pub fn hint, Tag>( self, hint: W, ) -> TextBuilder> { TextBuilder { content: self.content, attrs: self.attrs, hint: move |rsc: &mut Rsc| Some(hint.add_strong(rsc).any()), output: self.output, state: PhantomData, } } } pub trait TextBuilderOutput: Sized { type Output; fn run>( state: &mut State, builder: TextBuilder, ) -> Self::Output; } pub struct TextOutput; impl TextBuilderOutput for TextOutput { type Output = Text; fn run>( state: &mut Rsc, builder: TextBuilder, ) -> Self::Output { let buf = TextBuffer::new(&builder.content); let hint = builder.hint.get(state); let mut text = Text { content: builder.content.into(), view: TextView::new(buf, builder.attrs, hint), }; text.content.changed = false; text } } pub struct TextEditOutput { mode: EditMode, } impl TextBuilderOutput for TextEditOutput { type Output = TextEdit; fn run>( state: &mut State, builder: TextBuilder, ) -> Self::Output { let buf = TextBuffer::new(&builder.content); TextEdit::new( TextView::new(buf, builder.attrs, builder.hint.get(state)), builder.output.mode, ) } } impl, H: WidgetOption> FnOnce<(&mut State,)> for TextBuilder { type Output = O::Output; extern "rust-call" fn call_once(self, args: (&mut State,)) -> Self::Output { O::run(args.0, self) } } pub fn wtext(content: impl Into) -> TextBuilder { TextBuilder { content: content.into(), attrs: TextAttrs::default(), hint: (), output: TextOutput, state: PhantomData, } }