use std::marker::{PhantomData, Sized}; use crate::prelude::*; use cosmic_text::{Attrs, Family, Metrics, Shaping}; pub trait TextBuilderOutput: Sized { type Output; fn run(ui: &mut Ui, builder: TextBuilder) -> Self::Output; } pub struct TextBuilder { pub content: String, pub attrs: TextAttrs, _pd: 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 * 1.1; self } pub fn color(mut self, color: UiColor) -> Self { self.attrs.color = color; self } pub fn family(mut self, family: Family<'static>) -> 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: Align) -> Self { self.attrs.align = align; self } pub fn wrap(mut self, wrap: bool) -> Self { self.attrs.wrap = wrap; self } pub fn editable(self) -> TextBuilder { TextBuilder { content: self.content, attrs: self.attrs, _pd: PhantomData, } } } pub struct TextOutput; impl TextBuilderOutput for TextOutput { type Output = Text; fn run(ui: &mut Ui, builder: TextBuilder) -> Self::Output { let mut buf = TextBuffer::new_empty(Metrics::new( builder.attrs.font_size, builder.attrs.line_height, )); let font_system = &mut ui.data.text.font_system; buf.set_text( font_system, &builder.content, &Attrs::new(), Shaping::Advanced, ); let mut text = Text { content: builder.content.into(), view: TextView::new(buf, builder.attrs), }; text.content.changed = false; builder.attrs.apply(font_system, &mut text.view.buf, None); text } } pub struct TextEditOutput; impl TextBuilderOutput for TextEditOutput { type Output = TextEdit; fn run(ui: &mut Ui, builder: TextBuilder) -> Self::Output { let buf = TextBuffer::new_empty(Metrics::new( builder.attrs.font_size, builder.attrs.line_height, )); let mut text = TextEdit { view: TextView::new(buf, builder.attrs), cursor: None, }; let font_system = &mut ui.data.text.font_system; text.buf.set_text( font_system, &builder.content, &Attrs::new(), Shaping::Advanced, ); builder.attrs.apply(font_system, &mut text.buf, None); text } } impl FnOnce<(&mut Ui,)> for TextBuilder { type Output = O::Output; extern "rust-call" fn call_once(self, args: (&mut Ui,)) -> Self::Output { O::run(args.0, self) } } pub fn text(content: impl Into) -> TextBuilder { TextBuilder { content: content.into(), attrs: TextAttrs::default(), _pd: PhantomData, } }