Skip to main content

scratch_test_model/attrs/dropdowns/
instances_menu.rs

1use scratch_test_model_proc::Block;
2
3use crate::attrs::{
4    DirectDropdownOf, StringAtArrayPosZero,
5    dropdowns::{
6        direct_dropdown::FromDirectDropdownString, dropdown_menu_of::ExtraMenuDropdownParseStrat,
7    },
8};
9
10#[derive(Block)]
11pub enum SensingOfObjectMenu {
12    SensingOfObjectMenu {
13        #[block(location = fields)]
14        object: StringAtArrayPosZero,
15    },
16}
17
18#[derive(Block)]
19pub enum Text2SpeechVoicesMenu {
20    #[block(opcode = "text2speech_menu_voices")]
21    Text2SpeechVoicesMenu {
22        #[block(location = fields, json_name = "voices")]
23        voices: DirectDropdownOf<svalue::ARc<str>>, // TODO: specific
24    },
25}
26
27#[derive(Block)]
28pub enum Text2SpeechLanguagesMenu {
29    #[block(opcode = "text2speech_menu_languages")]
30    Text2SpeechLanguagesMenu {
31        #[block(location = fields, json_name = "languages")]
32        languages: DirectDropdownOf<svalue::ARc<str>>, // TODO: specific
33    },
34}
35
36#[derive(Block)]
37pub enum MotionPointtowardsMenu {
38    MotionPointtowardsMenu {
39        #[block(location = fields)]
40        towards: StringAtArrayPosZero,
41    },
42}
43
44#[derive(Block)]
45pub enum SensingDistancetoMenu {
46    #[block(opcode = "sensing_distancetomenu")]
47    SensingDistancetoMenu {
48        #[block(location = fields)]
49        distancetomenu: StringAtArrayPosZero,
50    },
51}
52#[derive(Block)]
53pub enum SensingKeyoptionsMenu {
54    #[block(opcode = "sensing_keyoptions")]
55    SensingKeyoptionsMenu {
56        #[block(location = fields)]
57        key_option: StringAtArrayPosZero,
58    },
59}
60
61#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, derive_more::Deref)]
62pub struct SoundSounds(svalue::ARc<str>);
63
64#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, derive_more::Deref)]
65pub struct LooksCostume(svalue::ARc<str>);
66
67#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, derive_more::Deref)]
68pub struct ChooseClone(svalue::ARc<str>);
69
70#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, derive_more::Deref)]
71pub struct SensingKeyoptions(svalue::ARc<str>);
72
73#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, derive_more::Deref)]
74pub struct Text2SpeechVoices(svalue::ARc<str>);
75
76#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, derive_more::Deref)]
77pub struct Text2SpeechLanguages(svalue::ARc<str>);
78
79#[derive(Block)]
80pub enum ControlCreateCloneOfMenu {
81    ControlCreateCloneOfMenu {
82        #[block(location = fields)]
83        clone_option: DirectDropdownOf<svalue::ARc<str>>,
84    },
85}
86
87#[derive(Block)]
88pub enum SoundSoundsMenu {
89    SoundSoundsMenu {
90        #[block(location = fields)]
91        sound_menu: DirectDropdownOf<svalue::ARc<str>>,
92    },
93}
94
95#[derive(Block)]
96pub enum LooksCostumeMenu {
97    #[block(opcode = "looks_costume")]
98    LooksCostumeMenu {
99        #[block(location = fields)]
100        costume: DirectDropdownOf<svalue::ARc<str>>,
101    },
102}
103
104#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, derive_more::Deref)]
105pub struct SensingOfObject(svalue::ARc<str>);
106
107#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
108pub enum MotionPointtowards {
109    Mouse,
110}
111
112#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
113pub enum SensingDistanceto {
114    Mouse,
115}
116
117#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
118pub enum SensingTouchingobject {
119    Mouse,
120    Edge,
121}
122
123#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
124pub enum LooksBackdrops {
125    Next,
126    Previous,
127    ByName(svalue::ARc<str>),
128}
129
130#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
131pub enum PenColorParam {
132    Color,
133    Brightness,
134    Saturation,
135    Transparency,
136}
137
138impl FromDirectDropdownString for PenColorParam {
139    const VALID_HINT: &'static str = "'color', ...";
140    fn from_direct_dropdown_string(val: &str) -> Option<Self> {
141        Some(match val {
142            "color" => Self::Color,
143            "brightness" => Self::Brightness,
144            "saturation" => Self::Saturation,
145            "transparency" => Self::Transparency,
146            _ => return None,
147        })
148    }
149}
150
151/// internal helper block that parses an external menu block of a motion_glideto dropdown
152#[derive(Block)]
153pub enum MotionGlidetoMenu {
154    MotionGlidetoMenu {
155        #[block(location = fields)]
156        to: StringAtArrayPosZero,
157    },
158}
159#[derive(Block)]
160pub enum MotionGotoMenu {
161    MotionGotoMenu {
162        #[block(location = fields)]
163        to: StringAtArrayPosZero,
164    },
165}
166
167#[derive(Block)]
168pub enum PenColorParamMenu {
169    #[block(opcode = "pen_menu_colorParam")]
170    PenColorParamMenu {
171        #[block(location = fields, json_name = "colorParam")]
172        color_param: DirectDropdownOf<PenColorParam>,
173    },
174}
175
176#[derive(Block)]
177pub enum LooksBackdropsMenu {
178    #[block(opcode = "looks_backdrops")]
179    LooksBackdropsMenu {
180        #[block(location = fields)]
181        backdrop: StringAtArrayPosZero,
182    },
183}
184
185#[derive(Block)]
186pub enum SensingTouchingobjectmenu {
187    SensingTouchingobjectmenu {
188        #[block(location = fields)]
189        touchingobjectmenu: StringAtArrayPosZero,
190    },
191}
192
193#[derive(Debug, PartialEq, Clone)]
194pub enum PossibleGoToPos {
195    Random,
196    Mouse,
197}
198#[derive(Debug, PartialEq, Clone)]
199pub enum PossibleGlideToPos {
200    Random,
201    Mouse,
202}
203impl ExtraMenuDropdownParseStrat<PossibleGlideToPos> for PossibleGlideToPos {
204    const VALID_HINT: &'static str = "either '_mouse_' or '_random_'";
205
206    type MenuBlock = MotionGlidetoMenu;
207
208    fn from_menu_block(block: Self::MenuBlock) -> Result<Self, String>
209    where
210        Self: Sized,
211    {
212        let MotionGlidetoMenu::MotionGlidetoMenu { to } = block;
213        match to.as_str() {
214            "_mouse_" => Ok(Self::Mouse),
215            "_random_" => Ok(Self::Random),
216            _ => Err(to.take()),
217        }
218    }
219}
220impl ExtraMenuDropdownParseStrat<PossibleGoToPos> for PossibleGoToPos {
221    const VALID_HINT: &'static str = "either '_mouse_' or '_random_'";
222
223    type MenuBlock = MotionGotoMenu;
224
225    fn from_menu_block(block: Self::MenuBlock) -> Result<Self, String>
226    where
227        Self: Sized,
228    {
229        let MotionGotoMenu::MotionGotoMenu { to } = block;
230        match to.as_str() {
231            "_mouse_" => Ok(Self::Mouse),
232            "_random_" => Ok(Self::Random),
233            _ => Err(to.take()),
234        }
235    }
236}
237impl ExtraMenuDropdownParseStrat<LooksBackdrops> for LooksBackdrops {
238    const VALID_HINT: &'static str = "'previous backdrop', 'next backdrop' or backdrop name";
239
240    type MenuBlock = LooksBackdropsMenu;
241
242    fn from_menu_block(block: Self::MenuBlock) -> Result<Self, String>
243    where
244        Self: Sized,
245    {
246        let LooksBackdropsMenu::LooksBackdropsMenu { backdrop } = block;
247        match backdrop.as_str() {
248            "next backdrop" => Ok(Self::Next),
249            "previous backdrop" => Ok(Self::Previous),
250            _ => Ok(Self::ByName(backdrop.take().into())),
251        }
252    }
253}
254
255impl ExtraMenuDropdownParseStrat<SensingOfObject> for SensingOfObject {
256    const VALID_HINT: &'static str = "unspecified value";
257
258    type MenuBlock = SensingOfObjectMenu;
259
260    fn from_menu_block(block: Self::MenuBlock) -> Result<Self, String>
261    where
262        Self: Sized,
263    {
264        let SensingOfObjectMenu::SensingOfObjectMenu { object } = block;
265        Ok(Self(object.take().into()))
266    }
267}
268
269impl ExtraMenuDropdownParseStrat<MotionPointtowards> for MotionPointtowards {
270    const VALID_HINT: &'static str = "'_mouse_'";
271
272    type MenuBlock = MotionPointtowardsMenu;
273
274    fn from_menu_block(block: Self::MenuBlock) -> Result<Self, String>
275    where
276        Self: Sized,
277    {
278        let MotionPointtowardsMenu::MotionPointtowardsMenu { towards } = block;
279        match towards.as_str() {
280            "_mouse_" => Ok(Self::Mouse),
281            _ => Err(towards.take()),
282        }
283    }
284}
285
286impl ExtraMenuDropdownParseStrat<SensingDistanceto> for SensingDistanceto {
287    const VALID_HINT: &'static str = "'_mouse_'";
288
289    type MenuBlock = SensingDistancetoMenu;
290
291    fn from_menu_block(block: Self::MenuBlock) -> Result<Self, String>
292    where
293        Self: Sized,
294    {
295        let SensingDistancetoMenu::SensingDistancetoMenu { distancetomenu } = block;
296        match distancetomenu.as_str() {
297            "_mouse_" => Ok(Self::Mouse),
298            _ => Err(distancetomenu.take()),
299        }
300    }
301}
302
303impl ExtraMenuDropdownParseStrat<SensingTouchingobject> for SensingTouchingobject {
304    const VALID_HINT: &'static str = "either '_mouse_' or '_edge_'";
305
306    type MenuBlock = SensingTouchingobjectmenu;
307
308    fn from_menu_block(block: Self::MenuBlock) -> Result<Self, String>
309    where
310        Self: Sized,
311    {
312        let SensingTouchingobjectmenu::SensingTouchingobjectmenu { touchingobjectmenu } = block;
313        let value = match touchingobjectmenu.as_str() {
314            "_mouse_" => Self::Mouse,
315            "_edge_" => Self::Edge,
316            _ => return Err(touchingobjectmenu.take()),
317        };
318        Ok(value)
319    }
320}
321
322impl ExtraMenuDropdownParseStrat<SoundSounds> for SoundSounds {
323    const VALID_HINT: &'static str = "name of sound";
324
325    type MenuBlock = SoundSoundsMenu;
326
327    fn from_menu_block(block: Self::MenuBlock) -> Result<Self, String>
328    where
329        Self: Sized,
330    {
331        let SoundSoundsMenu::SoundSoundsMenu { sound_menu } = block;
332
333        Ok(Self(sound_menu.0.0))
334    }
335}
336
337impl ExtraMenuDropdownParseStrat<LooksCostume> for LooksCostume {
338    const VALID_HINT: &'static str = "name of costume";
339
340    type MenuBlock = LooksCostumeMenu;
341
342    fn from_menu_block(block: Self::MenuBlock) -> Result<Self, String>
343    where
344        Self: Sized,
345    {
346        let LooksCostumeMenu::LooksCostumeMenu { costume } = block;
347
348        Ok(Self(costume.0.0))
349    }
350}
351
352// TODO: limit to not-string
353impl ExtraMenuDropdownParseStrat<ChooseClone> for ChooseClone {
354    const VALID_HINT: &'static str = "name of object or '_myself_'";
355
356    type MenuBlock = ControlCreateCloneOfMenu;
357
358    fn from_menu_block(block: Self::MenuBlock) -> Result<Self, String>
359    where
360        Self: Sized,
361    {
362        let ControlCreateCloneOfMenu::ControlCreateCloneOfMenu { clone_option } = block;
363        Ok(Self(clone_option.0.0))
364    }
365}
366
367impl ExtraMenuDropdownParseStrat<SensingKeyoptions> for SensingKeyoptions {
368    const VALID_HINT: &'static str = "";
369
370    type MenuBlock = SensingKeyoptionsMenu;
371
372    fn from_menu_block(block: Self::MenuBlock) -> Result<Self, String>
373    where
374        Self: Sized,
375    {
376        let SensingKeyoptionsMenu::SensingKeyoptionsMenu { key_option } = block;
377        Ok(Self(key_option.0.into()))
378    }
379}
380
381impl ExtraMenuDropdownParseStrat<PenColorParam> for PenColorParam {
382    const VALID_HINT: &'static str = "";
383
384    type MenuBlock = PenColorParamMenu;
385
386    fn from_menu_block(block: Self::MenuBlock) -> Result<Self, String>
387    where
388        Self: Sized,
389    {
390        let PenColorParamMenu::PenColorParamMenu { color_param } = block;
391        Ok(color_param.0.0)
392    }
393}
394
395impl ExtraMenuDropdownParseStrat<Text2SpeechVoices> for Text2SpeechVoices {
396    const VALID_HINT: &'static str = "";
397
398    type MenuBlock = Text2SpeechVoicesMenu;
399
400    fn from_menu_block(block: Self::MenuBlock) -> Result<Self, String>
401    where
402        Self: Sized,
403    {
404        let Text2SpeechVoicesMenu::Text2SpeechVoicesMenu { voices } = block;
405        Ok(Self(voices.0.0))
406    }
407}
408
409impl ExtraMenuDropdownParseStrat<Text2SpeechLanguages> for Text2SpeechLanguages {
410    const VALID_HINT: &'static str = "";
411
412    type MenuBlock = Text2SpeechLanguagesMenu;
413
414    fn from_menu_block(block: Self::MenuBlock) -> Result<Self, String>
415    where
416        Self: Sized,
417    {
418        let Text2SpeechLanguagesMenu::Text2SpeechLanguagesMenu { languages } = block;
419        Ok(Self(languages.0.0))
420    }
421}