Skip to main content

makepad_gen_plugin/builtin/widget/basic/view/
prop.rs

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// ------------ wait to implement ------------------------------------
14// pub scroll_bars: Option<LivePtr>,
15// pub draw_view: DrawGView,
16// pub animator: Animator,
17// -------------------------------------------------------------------
18#[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    // MinWidth(f32),
38    // MinHeight(f32),
39    // MaxWidth(f32),
40    // MaxHeight(f32),
41    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            // "min_width" => Ok(Props::MinWidth(&value.1.try_into()?)),
114            // "min_height" => Ok(Props::MinHeight(&value.1.try_into()?)),
115            // "max_width" => Ok(Props::MaxWidth(&value.1.try_into()?)),
116            // "max_height" => Ok(Props::MaxHeight(&value.1.try_into()?)),
117            "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            // "min_width" => Ok(Props::MinWidth(value.1.as_f32()?)),
187            // "min_height" => Ok(Props::MinHeight(value.1.as_f32()?)),
188            // "max_width" => Ok(Props::MaxWidth(value.1.as_f32()?)),
189            // "max_height" => Ok(Props::MaxHeight(value.1.as_f32()?)),
190            // "walk" => Ok(Props::Walk(Walk::try_from(&value.1)?)),
191            // "layout" => Ok(Props::Layout(Layout::try_from(&value.1)?)),
192            "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}