1use gen_analyzer::{value::Value, PropKey};
2use gen_utils::{err_from_to, error::Error};
3
4use crate::{
5 builtin::prop::{
6 value_bool, EventOrder, FromGenProps, Layout, MouseCursor, Prop, Themes, Vec2,
7 ViewOptimize, Walk, F32, F64,
8 },
9 from_gen::MakepadColor,
10 props_to_tokens,
11};
12
13#[derive(Debug, Clone)]
19pub enum Props {
20 Theme(Themes),
21 BackgroundColor(MakepadColor),
22 HoverColor(MakepadColor),
23 FocusColor(MakepadColor),
24 BorderColor(MakepadColor),
25 BorderWidth(F32),
26 BorderRadius(F32),
27 Visible(bool),
28 BackgroundVisible(bool),
29 ShadowColor(MakepadColor),
30 SpreadRadius(F32),
31 BlurRadius(F32),
32 ShadowOffset(Vec2),
33 Cursor(MouseCursor),
34 AnimationKey(bool),
35 GrabKeyFocus(bool),
36 BlockSignalEvent(bool),
37 Walk(Walk),
42 Layout(Layout),
43 EventOrder(EventOrder),
44 DpiFactor(F64),
45 Optimize(ViewOptimize),
46 CaptureOverload(bool),
47 EventKey(bool),
48 BlockChildEvents(bool),
49}
50
51impl Props {
52 pub fn to_toml_item_kv(&self) -> (String, toml_edit::Value) {
53 match self {
54 Props::Theme(themes) => ("theme".to_string(), themes.into()),
55 Props::BackgroundColor(makepad_color) => {
56 ("background_color".to_string(), makepad_color.into())
57 }
58 Props::HoverColor(makepad_color) => ("hover_color".to_string(), makepad_color.into()),
59 Props::FocusColor(makepad_color) => ("focus_color".to_string(), makepad_color.into()),
60 Props::BorderColor(makepad_color) => ("border_color".to_string(), makepad_color.into()),
61 Props::BorderWidth(f) => ("border_width".to_string(), f.into()),
62 Props::BorderRadius(f) => ("border_radius".to_string(), f.into()),
63 Props::Visible(vis) => ("visible".to_string(), (*vis).into()),
64 Props::BackgroundVisible(vis) => ("background_visible".to_string(), (*vis).into()),
65 Props::ShadowColor(makepad_color) => ("shadow_color".to_string(), makepad_color.into()),
66 Props::SpreadRadius(f) => ("spread_radius".to_string(), f.into()),
67 Props::BlurRadius(f) => ("blur_radius".to_string(), f.into()),
68 Props::ShadowOffset(vec2) => ("shadow_offset".to_string(), vec2.into()),
69 Props::Cursor(mouse_cursor) => ("cursor".to_string(), mouse_cursor.into()),
70 Props::AnimationKey(key) => ("animation_key".to_string(), (*key).into()),
71 Props::GrabKeyFocus(focus) => ("grab_key_focus".to_string(), (*focus).into()),
72 Props::BlockSignalEvent(e) => ("block_signal_event".to_string(), (*e).into()),
73 Props::Walk(walk) => {
74 let (key, value) = walk.to_toml_item_kv();
75 (key, value)
76 }
77 Props::Layout(layout) => {
78 let (key, value) = layout.to_toml_item_kv();
79 (key, value)
80 }
81 Props::EventOrder(event_order) => ("event_order".to_string(), event_order.into()),
82 Props::DpiFactor(f) => ("dpi_factor".to_string(), f.into()),
83 Props::Optimize(view_optimize) => ("optimize".to_string(), view_optimize.into()),
84 Props::CaptureOverload(o) => ("capture_overload".to_string(), (*o).into()),
85 Props::EventKey(key) => ("event_key".to_string(), (*key).into()),
86 Props::BlockChildEvents(e) => ("block_child_events".to_string(), (*e).into()),
87 }
88 }
89}
90
91impl TryFrom<(&str, &toml_edit::Value)> for Props {
92 type Error = Error;
93
94 fn try_from(value: (&str, &toml_edit::Value)) -> Result<Self, Self::Error> {
95 match value.0 {
96 "theme" => Ok(Props::Theme(value.1.try_into()?)),
97 "background_color" => Ok(Props::BackgroundColor(value.1.try_into()?)),
98 "hover_color" => Ok(Props::HoverColor(value.1.try_into()?)),
99 "focus_color" => Ok(Props::FocusColor(value.1.try_into()?)),
100 "border_color" => Ok(Props::BorderColor(value.1.try_into()?)),
101 "border_width" => Ok(Props::BorderWidth(value.1.try_into()?)),
102 "border_radius" => Ok(Props::BorderRadius(value.1.try_into()?)),
103 "visible" => Ok(Props::Visible(value_bool(value.1)?)),
104 "background_visible" => Ok(Props::BackgroundVisible(value_bool(value.1)?)),
105 "shadow_color" => Ok(Props::ShadowColor(value.1.try_into()?)),
106 "spread_radius" => Ok(Props::SpreadRadius(value.1.try_into()?)),
107 "blur_radius" => Ok(Props::BlurRadius(value.1.try_into()?)),
108 "shadow_offset" => Ok(Props::ShadowOffset(value.1.try_into()?)),
109 "cursor" => Ok(Props::Cursor(value.1.try_into()?)),
110 "animation_key" => Ok(Props::AnimationKey(value_bool(value.1)?)),
111 "grab_key_focus" => Ok(Props::GrabKeyFocus(value_bool(value.1)?)),
112 "block_signal_event" => Ok(Props::BlockSignalEvent(value_bool(value.1)?)),
113 "event_order" => Ok(Props::EventOrder(value.1.try_into()?)),
118 "dpi_factor" => Ok(Props::DpiFactor(value.1.try_into()?)),
119 "optimize" => Ok(Props::Optimize(value.1.try_into()?)),
120 "capture_overload" => Ok(Props::CaptureOverload(value_bool(value.1)?)),
121 "event_key" => Ok(Props::EventKey(value_bool(value.1)?)),
122 "block_child_events" => Ok(Props::BlockChildEvents(value_bool(value.1)?)),
123 _ => {
124 if let Ok(prop) = Walk::try_from(value) {
125 return Ok(Props::Walk(prop));
126 } else if let Ok(prop) = Layout::try_from(value) {
127 return Ok(Props::Layout(prop));
128 } else {
129 return Err(err_from_to!(
130 "GenUI Props" => &format!("Makepad GView Prop, Invalid Prop: {}", value.0)
131 ).to_runtime("Makepad Compiler"));
132 }
133 }
134 }
135 }
136}
137
138impl FromGenProps for Prop<Props> {
139 type Output = Prop<Props>;
140
141 fn from_prop(
142 prop: Option<gen_analyzer::Props>,
143 ) -> Result<Option<Self::Output>, gen_utils::error::Error> {
144 if let Some(props) = prop {
145 let mut res = Prop::default();
146 for (prop, value) in props {
147 if prop.is_normal() {
148 res.push((prop, value).try_into()?);
149 }
150 }
151 Ok(Some(res))
152 } else {
153 Ok(None)
154 }
155 }
156}
157
158impl TryFrom<(PropKey, Value)> for Props {
159 type Error = gen_utils::error::Error;
160
161 fn try_from(value: (PropKey, Value)) -> Result<Self, Self::Error> {
162 match value.0.name.as_str() {
163 "theme" => Ok(Props::Theme(Themes::try_from(&value.1)?)),
164 "background_color" => Ok(Props::BackgroundColor(MakepadColor::try_from((
165 &value.1, None,
166 ))?)),
167 "hover_color" => Ok(Props::HoverColor(MakepadColor::try_from((&value.1, None))?)),
168 "focus_color" => Ok(Props::FocusColor(MakepadColor::try_from((&value.1, None))?)),
169 "border_color" => Ok(Props::BorderColor(MakepadColor::try_from((
170 &value.1, None,
171 ))?)),
172 "border_width" => Ok(Props::BorderWidth(value.1.as_f32()?.into())),
173 "border_radius" => Ok(Props::BorderRadius(value.1.as_f32()?.into())),
174 "visible" => Ok(Props::Visible(value.1.as_bool()?)),
175 "background_visible" => Ok(Props::BackgroundVisible(value.1.as_bool()?)),
176 "shadow_color" => Ok(Props::ShadowColor(MakepadColor::try_from((
177 &value.1, None,
178 ))?)),
179 "spread_radius" => Ok(Props::SpreadRadius(value.1.as_f32()?.into())),
180 "blur_radius" => Ok(Props::BlurRadius(value.1.as_f32()?.into())),
181 "shadow_offset" => Ok(Props::ShadowOffset(Vec2::try_from(&value.1)?)),
182 "cursor" => Ok(Props::Cursor(MouseCursor::try_from(&value.1)?)),
183 "animation_key" => Ok(Props::AnimationKey(value.1.as_bool()?)),
184 "grab_key_focus" => Ok(Props::GrabKeyFocus(value.1.as_bool()?)),
185 "block_signal_event" => Ok(Props::BlockSignalEvent(value.1.as_bool()?)),
186 "event_order" => Ok(Props::EventOrder(EventOrder::try_from(&value.1)?)),
193 "dpi_factor" => Ok(Props::DpiFactor(value.1.as_f64()?.into())),
194 "optimize" => Ok(Props::Optimize(ViewOptimize::try_from(&value.1)?)),
195 "capture_overload" => Ok(Props::CaptureOverload(value.1.as_bool()?)),
196 "event_key" => Ok(Props::EventKey(value.1.as_bool()?)),
197 "block_child_events" => Ok(Props::BlockChildEvents(value.1.as_bool()?)),
198 _ => {
199 if let Ok(prop) = Walk::try_from(&value) {
200 return Ok(Props::Walk(prop));
201 } else if let Ok(prop) = Layout::try_from(&value) {
202 return Ok(Props::Layout(prop));
203 } else {
204 return Err(err_from_to!(
205 "GenUI Props" => &format!("Makepad GView Prop, Invalid Prop: {}", &value.0.name)
206 ));
207 }
208 }
209 }
210 }
211}
212
213props_to_tokens! {
214 Props,
215 Props::Theme => theme, false,
216 Props::BackgroundColor => background_color, false,
217 Props::HoverColor => hover_color, false,
218 Props::FocusColor => focus_color, false,
219 Props::BorderColor => border_color, false,
220 Props::BorderWidth => border_width, false,
221 Props::BorderRadius => border_radius, false,
222 Props::Visible => visible, false,
223 Props::BackgroundVisible => background_visible, false,
224 Props::ShadowColor => shadow_color, false,
225 Props::SpreadRadius => spread_radius, false,
226 Props::BlurRadius => blur_radius, false,
227 Props::ShadowOffset => shadow_offset, false,
228 Props::Cursor => cursor, false,
229 Props::AnimationKey => animation_key, false,
230 Props::GrabKeyFocus => grab_key_focus, false,
231 Props::BlockSignalEvent => block_signal_event, false,
232 Props::Walk => walk, true,
233 Props::Layout => layout, true,
234 Props::EventOrder => event_order, false,
235 Props::DpiFactor => dpi_factor, false,
236 Props::Optimize => optimize, false,
237 Props::CaptureOverload => capture_overload, false,
238 Props::EventKey => event_key, false,
239 Props::BlockChildEvents => block_child_events, false
240}