cotis_defaults/element_configs/
text_config.rs1use crate::colors::Color;
6#[cfg(feature = "complex_colored_text")]
7use crate::colors::ColorLayer;
8use cotis::utils::OwnedOrRef;
9use cotis::utils::OwnedOrRef::Ref;
10#[cfg(feature = "serde")]
11use serde::{Deserialize, Serialize};
12use std::ops::Range;
13
14#[derive(Debug, Clone, Copy)]
15#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
16pub struct TextConfig {
17 pub font_id: u16,
21 pub font_size: f32,
23 pub letter_spacing: f32,
25 pub line_height: f32,
29 pub wrap_mode: TextElementConfigWrapMode,
31 pub alignment: TextAlignment,
33}
34
35#[derive(Debug, Clone)]
36#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
37#[cfg_attr(not(feature = "complex_colored_text"), derive(Copy))]
38pub struct TextStyle {
39 #[cfg(not(feature = "complex_colored_text"))]
41 pub color: Color,
42 #[cfg(feature = "complex_colored_text")]
43 pub color: ColorLayer,
44}
45
46impl Default for TextConfig {
47 fn default() -> Self {
49 Self {
50 font_id: 0,
51 font_size: 0.,
52 letter_spacing: 0.,
53 line_height: 0.,
54 wrap_mode: TextElementConfigWrapMode::Words,
55 alignment: TextAlignment::Left,
56 }
57 }
58}
59
60impl Default for TextStyle {
61 fn default() -> Self {
63 Self {
64 #[cfg(not(feature = "complex_colored_text"))]
65 color: Color::rgb(0.0, 0.0, 0.0),
66 #[cfg(feature = "complex_colored_text")]
67 color: ColorLayer::Solid(Color::rgb(0.0, 0.0, 0.0)),
68 }
69 }
70}
71
72#[derive(Debug, Clone, Copy)]
73#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
74pub enum TextElementConfigWrapMode {
75 Words,
77 Newline,
79 None,
81}
82
83#[derive(Debug, Clone, Copy)]
84#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
85pub enum TextAlignment {
86 Left,
88 Center,
90 Right,
92}
93
94#[derive(Debug, Clone)]
96#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
97pub struct TextElementConfig<'a> {
98 pub text: OwnedOrRef<'a, str>,
100 pub config: TextConfig,
102 pub style: TextStyle,
104}
105
106#[derive(Debug, Clone)]
108#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
109#[cfg_attr(not(feature = "complex_colored_text"), derive(Copy, Default))]
110pub struct TextConfigStylePair {
111 pub config: TextConfig,
113 pub style: TextStyle,
115}
116
117impl<'a> Default for TextElementConfig<'a> {
118 fn default() -> Self {
119 Self {
120 text: Ref(""),
121 config: TextConfig::default(),
122 style: Default::default(),
123 }
124 }
125}
126
127#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
132pub struct RichTextElementConfig<'a> {
133 pub text: OwnedOrRef<'a, str>,
135 pub default_config: TextConfigStylePair,
137 pub configs: Vec<TextConfigStylePair>,
139 pub config_ranges: Vec<(Range<usize>, usize)>,
141}
142
143pub struct RichTextElementBuilder<'a> {
145 text: OwnedOrRef<'a, str>,
146 default_config: TextConfigStylePair,
147 configs: Vec<TextConfigStylePair>,
148 config_ranges: Vec<(Range<usize>, usize)>,
149}
150
151impl<'a> RichTextElementBuilder<'a> {
152 pub fn new(text: OwnedOrRef<'a, str>, default_config: TextConfigStylePair) -> Self {
154 Self {
155 text,
156 default_config,
157 configs: vec![],
158 config_ranges: vec![],
159 }
160 }
161
162 pub fn add_config(&mut self, config: TextConfigStylePair) -> usize {
164 self.configs.push(config);
165 self.config_ranges.len() - 1
166 }
167
168 pub fn configure_range(&mut self, range: Range<usize>, config_index: usize) {
175 assert!(range.end < self.text.as_ref().len());
176 assert!(config_index <= self.config_ranges.len());
177 self.config_ranges.push((range, config_index));
178 }
179
180 pub fn into_config(self) -> RichTextElementConfig<'a> {
182 RichTextElementConfig {
183 text: self.text,
184 default_config: self.default_config,
185 configs: self.configs,
186 config_ranges: self.config_ranges,
187 }
188 }
189}