1use crate::{
2 PrefabValue, Scalar,
3 props::Props,
4 widget::{
5 WidgetId,
6 node::WidgetNode,
7 unit::WidgetUnitData,
8 utils::{Color, Transform},
9 },
10};
11use serde::{Deserialize, Serialize};
12use std::convert::TryFrom;
13
14#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
15pub enum TextBoxHorizontalAlign {
16 #[default]
17 Left,
18 Center,
19 Right,
20}
21
22#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
23pub enum TextBoxVerticalAlign {
24 #[default]
25 Top,
26 Middle,
27 Bottom,
28}
29
30#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
31pub enum TextBoxDirection {
32 #[default]
33 HorizontalLeftToRight,
34 HorizontalRightToLeft,
35 VerticalTopToBottom,
36 VerticalBottomToTop,
37}
38
39impl TextBoxDirection {
40 pub fn is_horizontal(&self) -> bool {
41 *self == Self::HorizontalLeftToRight || *self == Self::HorizontalRightToLeft
42 }
43
44 pub fn is_vertical(&self) -> bool {
45 *self == Self::VerticalTopToBottom || *self == Self::VerticalBottomToTop
46 }
47
48 pub fn is_order_ascending(&self) -> bool {
49 *self == Self::HorizontalLeftToRight || *self == Self::VerticalTopToBottom
50 }
51
52 pub fn is_order_descending(&self) -> bool {
53 *self == Self::HorizontalRightToLeft || *self == Self::VerticalBottomToTop
54 }
55}
56
57#[derive(Debug, Default, Clone, Serialize, Deserialize)]
58pub struct TextBoxFont {
59 #[serde(default)]
60 pub name: String,
61 #[serde(default)]
62 pub size: Scalar,
63}
64
65#[derive(Debug, Default, Copy, Clone, Serialize, Deserialize)]
66pub enum TextBoxSizeValue {
67 Content,
68 #[default]
69 Fill,
70 Exact(Scalar),
71}
72
73#[derive(Debug, Default, Clone, Serialize, Deserialize)]
74pub struct TextBox {
75 #[serde(default)]
76 pub id: WidgetId,
77 #[serde(default)]
78 pub text: String,
79 #[serde(default)]
80 pub width: TextBoxSizeValue,
81 #[serde(default)]
82 pub height: TextBoxSizeValue,
83 #[serde(default)]
84 pub horizontal_align: TextBoxHorizontalAlign,
85 #[serde(default)]
86 pub vertical_align: TextBoxVerticalAlign,
87 #[serde(default)]
88 pub direction: TextBoxDirection,
89 #[serde(default)]
90 pub font: TextBoxFont,
91 #[serde(default)]
92 pub color: Color,
93 #[serde(default)]
94 pub transform: Transform,
95}
96
97impl WidgetUnitData for TextBox {
98 fn id(&self) -> &WidgetId {
99 &self.id
100 }
101}
102
103impl TryFrom<TextBoxNode> for TextBox {
104 type Error = ();
105
106 fn try_from(node: TextBoxNode) -> Result<Self, Self::Error> {
107 let TextBoxNode {
108 id,
109 text,
110 width,
111 height,
112 horizontal_align,
113 vertical_align,
114 direction,
115 font,
116 color,
117 transform,
118 ..
119 } = node;
120 Ok(Self {
121 id,
122 text,
123 width,
124 height,
125 horizontal_align,
126 vertical_align,
127 direction,
128 font,
129 color,
130 transform,
131 })
132 }
133}
134
135#[derive(Debug, Default, Clone)]
136pub struct TextBoxNode {
137 pub id: WidgetId,
138 pub props: Props,
139 pub text: String,
140 pub width: TextBoxSizeValue,
141 pub height: TextBoxSizeValue,
142 pub horizontal_align: TextBoxHorizontalAlign,
143 pub vertical_align: TextBoxVerticalAlign,
144 pub direction: TextBoxDirection,
145 pub font: TextBoxFont,
146 pub color: Color,
147 pub transform: Transform,
148}
149
150impl TextBoxNode {
151 pub fn remap_props<F>(&mut self, mut f: F)
152 where
153 F: FnMut(Props) -> Props,
154 {
155 let props = std::mem::take(&mut self.props);
156 self.props = (f)(props);
157 }
158}
159
160impl From<TextBoxNode> for WidgetNode {
161 fn from(data: TextBoxNode) -> Self {
162 Self::Unit(data.into())
163 }
164}
165
166#[derive(Debug, Default, Clone, Serialize, Deserialize)]
167pub(crate) struct TextBoxNodePrefab {
168 #[serde(default)]
169 pub id: WidgetId,
170 #[serde(default)]
171 pub props: PrefabValue,
172 #[serde(default)]
173 pub text: String,
174 #[serde(default)]
175 pub width: TextBoxSizeValue,
176 #[serde(default)]
177 pub height: TextBoxSizeValue,
178 #[serde(default)]
179 pub horizontal_align: TextBoxHorizontalAlign,
180 #[serde(default)]
181 pub vertical_align: TextBoxVerticalAlign,
182 #[serde(default)]
183 pub direction: TextBoxDirection,
184 #[serde(default)]
185 pub font: TextBoxFont,
186 #[serde(default)]
187 pub color: Color,
188 #[serde(default)]
189 pub transform: Transform,
190}