Skip to main content

pax_designtime/orm/template/
node_builder_commands.rs

1use std::{collections::HashMap, path::PathBuf};
2
3use pax_manifest::{
4    pax_runtime_api::ToPaxValue, ComponentDefinition, ComponentTemplate,
5    ControlFlowRepeatPredicateDefinition, ExpressionInfo, NodeLocation, NodeType, PaxManifest,
6    SettingElement, SettingsBlockElement, TemplateNodeDefinition, TemplateNodeId,
7    TimelineDefinition, Token, TreeIndexPosition, TreeLocation, TypeId,
8    UniqueTemplateNodeIdentifier, ValueDefinition,
9};
10use serde_derive::{Deserialize, Serialize};
11
12use crate::orm::{
13    Command, MoveToComponentEntry, ReloadType, Request, Response, SubTrees, Undo, UndoRedoCommand,
14};
15
16#[derive(Serialize, Deserialize, Clone, Default, Debug)]
17pub struct NodeData {
18    pub unique_node_identifier: UniqueTemplateNodeIdentifier,
19    pub cached_node: TemplateNodeDefinition,
20}
21
22#[derive(Serialize, Deserialize, Clone, Debug, Default)]
23pub struct ControlFlowSettingsDefinitionUpdate {
24    pub repeat_predicate_definition: Option<Option<ControlFlowRepeatPredicateDefinition>>,
25    pub repeat_source_expression: Option<Option<ExpressionInfo>>,
26    pub conditional_expression: Option<Option<ExpressionInfo>>,
27    pub slot_index_expression: Option<Option<ExpressionInfo>>,
28}
29
30#[derive(Serialize, Deserialize, Clone, Debug)]
31pub struct AddTemplateNodeRequest {
32    containing_component_type_id: TypeId,
33    template_node_type_id: TypeId,
34    node_data: NodeType,
35    location: Option<NodeLocation>,
36
37    // Used for Undo/Redo
38    _cached_node_data: Option<NodeData>,
39}
40
41impl AddTemplateNodeRequest {
42    pub fn new(
43        containing_component_type_id: TypeId,
44        template_node_type_id: TypeId,
45        node_data: NodeType,
46        location: Option<NodeLocation>,
47    ) -> Self {
48        Self {
49            containing_component_type_id,
50            template_node_type_id,
51            node_data,
52            location,
53            _cached_node_data: None,
54        }
55    }
56}
57
58#[derive(Serialize, Deserialize, Clone)]
59pub struct AddTemplateNodeResponse {
60    pub command_id: Option<usize>,
61    pub uni: UniqueTemplateNodeIdentifier,
62}
63
64impl Request for AddTemplateNodeRequest {
65    type Response = AddTemplateNodeResponse;
66}
67
68impl Response for AddTemplateNodeResponse {
69    fn set_id(&mut self, id: usize) {
70        self.command_id = Some(id);
71    }
72    fn get_id(&self) -> usize {
73        self.command_id.unwrap()
74    }
75    fn get_reload_type(&self) -> Option<ReloadType> {
76        Some(ReloadType::Tree)
77    }
78}
79
80impl Command<AddTemplateNodeRequest> for AddTemplateNodeRequest {
81    fn execute(&mut self, manifest: &mut PaxManifest) -> Result<AddTemplateNodeResponse, String> {
82        let component = manifest
83            .components
84            .get_mut(&self.containing_component_type_id)
85            .ok_or_else(|| format!("Component {} not found", self.containing_component_type_id))?;
86        if component.is_primitive || component.is_struct_only_component {
87            return Err("Component doesn't accept template nodes.".to_string());
88        }
89
90        let mut template_node = TemplateNodeDefinition {
91            type_id: self.template_node_type_id.clone(),
92            ..Default::default()
93        };
94
95        match &self.node_data {
96            NodeType::Template(settings) => {
97                template_node.settings = Some(settings.clone());
98            }
99            NodeType::ControlFlow(control_flow_settings) => {
100                template_node.control_flow_settings = Some(*control_flow_settings.clone());
101            }
102            NodeType::Comment(raw_comment_string) => {
103                template_node.raw_comment_string = Some(raw_comment_string.clone());
104            }
105        }
106
107        let mut node_data = NodeData {
108            cached_node: template_node.clone(),
109            ..Default::default()
110        };
111
112        node_data.unique_node_identifier = if let Some(template) = &mut component.template {
113            if let Some(location) = &self.location {
114                template.add_at(template_node, location.clone())
115            } else {
116                template.add(template_node)
117            }
118        } else {
119            let mut template =
120                ComponentTemplate::new(self.containing_component_type_id.clone(), None);
121            let uni = if let Some(location) = &self.location {
122                template.add_at(template_node, location.clone())
123            } else {
124                template.add(template_node)
125            };
126            component.template = Some(template);
127            uni
128        };
129
130        self._cached_node_data = Some(node_data.clone());
131
132        Ok(AddTemplateNodeResponse {
133            command_id: None,
134            uni: node_data.unique_node_identifier.clone(),
135        })
136    }
137
138    fn as_undo_redo(&mut self) -> Option<UndoRedoCommand> {
139        Some(UndoRedoCommand::AddTemplateNodeRequest(Box::new(
140            self.clone(),
141        )))
142    }
143}
144
145impl Undo for AddTemplateNodeRequest {
146    fn undo(&mut self, manifest: &mut PaxManifest) -> Result<(), String> {
147        let component = manifest
148            .components
149            .get_mut(&self.containing_component_type_id)
150            .unwrap();
151
152        let cached_data = self._cached_node_data.clone().unwrap();
153        if let Some(template) = &mut component.template {
154            template.remove_node(cached_data.unique_node_identifier.get_template_node_id());
155            template.set_next_id(
156                cached_data
157                    .unique_node_identifier
158                    .get_template_node_id()
159                    .as_usize(),
160            );
161        }
162        Ok(())
163    }
164}
165
166#[derive(Serialize, Deserialize, Clone, Debug)]
167pub struct UpdateTemplateNodeRequest {
168    uni: UniqueTemplateNodeIdentifier,
169    updated_properties: HashMap<Token, Option<ValueDefinition>>,
170    updated_classes: HashMap<String, bool>,
171    new_type_id: Option<TypeId>,
172    new_location: Option<NodeLocation>,
173    control_flow_updates: ControlFlowSettingsDefinitionUpdate,
174    // Used for Undo/Redo
175    _cached_node_data: Option<NodeData>,
176    _cached_move: Option<MoveTemplateNodeRequest>,
177}
178
179impl UpdateTemplateNodeRequest {
180    pub fn new(
181        uni: UniqueTemplateNodeIdentifier,
182        new_type_id: Option<TypeId>,
183        updated_properties: HashMap<Token, Option<ValueDefinition>>,
184        updated_classes: HashMap<String, bool>,
185        new_location: Option<NodeLocation>,
186        control_flow_updates: ControlFlowSettingsDefinitionUpdate,
187    ) -> Self {
188        Self {
189            uni,
190            updated_properties,
191            updated_classes,
192            new_location,
193            new_type_id,
194            _cached_node_data: None,
195            _cached_move: None,
196            control_flow_updates,
197        }
198    }
199}
200
201pub struct UpdateTemplateNodeResponse {
202    pub command_id: Option<usize>,
203    _affected_component_type_id: TypeId,
204    _affected_unique_node_identifier: UniqueTemplateNodeIdentifier,
205    _reload_type: ReloadType,
206}
207
208impl Request for UpdateTemplateNodeRequest {
209    type Response = UpdateTemplateNodeResponse;
210}
211
212impl Response for UpdateTemplateNodeResponse {
213    fn set_id(&mut self, id: usize) {
214        self.command_id = Some(id);
215    }
216    fn get_id(&self) -> usize {
217        self.command_id.unwrap()
218    }
219    fn get_reload_type(&self) -> Option<ReloadType> {
220        Some(self._reload_type.clone())
221    }
222}
223
224impl Command<UpdateTemplateNodeRequest> for UpdateTemplateNodeRequest {
225    fn execute(
226        &mut self,
227        manifest: &mut PaxManifest,
228    ) -> Result<UpdateTemplateNodeResponse, String> {
229        let uni = self.uni.clone();
230        let containing_component = uni.get_containing_component_type_id().clone();
231        let component = manifest
232            .components
233            .get_mut(&containing_component)
234            .ok_or_else(|| {
235                format!(
236                    "Component {} not found",
237                    self.uni.get_containing_component_type_id()
238                )
239            })?;
240        if component.is_primitive || component.is_struct_only_component {
241            return Err("Component doesn't accept template nodes.".to_string());
242        }
243
244        if let Some(template) = &mut component.template {
245            template.update_node_properties(
246                &uni.get_template_node_id(),
247                self.updated_properties.clone(),
248            );
249            template.update_classes(&uni.get_template_node_id(), self.updated_classes.clone());
250            template.update_control_flow_properties(
251                &uni.get_template_node_id(),
252                self.control_flow_updates
253                    .repeat_predicate_definition
254                    .clone(),
255                self.control_flow_updates.repeat_source_expression.clone(),
256                self.control_flow_updates.conditional_expression.clone(),
257                self.control_flow_updates.slot_index_expression.clone(),
258            );
259            // HACK: don't store path elements - grows large very quickly since we
260            // save this entire state on each mouse move
261            self.updated_properties
262                .remove(&Token::new_without_location("elements".to_string()));
263            self._cached_node_data = Some(NodeData {
264                unique_node_identifier: uni.clone(),
265                cached_node: template
266                    .get_node(&uni.get_template_node_id())
267                    .ok_or_else(|| "Cannot update node that doesn't exist".to_string())?
268                    .clone(),
269            });
270
271            if let Some(new_type) = &self.new_type_id {
272                template.update_node_type_id(&uni.get_template_node_id(), new_type);
273            }
274
275            if let Some(location) = &self.new_location {
276                let mut move_request = MoveTemplateNodeRequest::new(uni.clone(), location.clone());
277                move_request.execute(manifest)?;
278                self._cached_move = Some(move_request.clone());
279            }
280        }
281
282        Ok(UpdateTemplateNodeResponse {
283            command_id: None,
284            _affected_component_type_id: uni.get_containing_component_type_id(),
285            _affected_unique_node_identifier: uni,
286            // At the moment class changes aren't reloaded by a partial update
287            _reload_type: if !self.updated_classes.is_empty() {
288                ReloadType::Tree
289            } else {
290                ReloadType::Node(self.uni.clone(), {
291                    let mut updated: Vec<_> = self
292                        .updated_properties
293                        .keys()
294                        .map(|t| t.token_value.clone())
295                        .collect();
296                    updated.sort_unstable();
297                    updated
298                })
299            },
300        })
301    }
302
303    fn as_undo_redo(&mut self) -> Option<UndoRedoCommand> {
304        Some(UndoRedoCommand::UpdateTemplateNodeRequest(Box::new(
305            self.clone(),
306        )))
307    }
308}
309
310impl Undo for UpdateTemplateNodeRequest {
311    fn undo(&mut self, manifest: &mut PaxManifest) -> Result<(), String> {
312        if let Some(move_request) = &mut self._cached_move {
313            move_request.undo(manifest).unwrap();
314        }
315
316        let component = manifest
317            .components
318            .get_mut(&self.uni.get_containing_component_type_id())
319            .unwrap();
320
321        if let Some(template) = &mut component.template {
322            if let Some(data) = &self._cached_node_data {
323                template.set_node(self.uni.get_template_node_id(), data.cached_node.clone());
324            }
325        }
326        Ok(())
327    }
328}
329
330#[derive(Serialize, Deserialize, Clone, Debug)]
331pub struct MoveTemplateNodeRequest {
332    uni: UniqueTemplateNodeIdentifier,
333    new_location: NodeLocation,
334    // Used for Undo/Redo
335    _cached_old_position: Option<NodeLocation>,
336}
337
338impl MoveTemplateNodeRequest {
339    pub fn new(uni: UniqueTemplateNodeIdentifier, new_location: NodeLocation) -> Self {
340        Self {
341            uni,
342            new_location,
343            _cached_old_position: None,
344        }
345    }
346}
347
348pub struct MoveTemplateNodeResponse {
349    command_id: Option<usize>,
350    _affected_component_type_id: TypeId,
351}
352
353impl Request for MoveTemplateNodeRequest {
354    type Response = MoveTemplateNodeResponse;
355}
356
357impl Response for MoveTemplateNodeResponse {
358    fn set_id(&mut self, id: usize) {
359        self.command_id = Some(id);
360    }
361    fn get_id(&self) -> usize {
362        self.command_id.unwrap()
363    }
364    fn get_reload_type(&self) -> Option<ReloadType> {
365        Some(ReloadType::Tree)
366    }
367}
368
369impl Command<MoveTemplateNodeRequest> for MoveTemplateNodeRequest {
370    fn execute(&mut self, manifest: &mut PaxManifest) -> Result<MoveTemplateNodeResponse, String> {
371        let uni = self.uni.clone();
372        let requested_component = self.new_location.get_type_id();
373
374        let current_component = manifest
375            .components
376            .get_mut(&uni.get_containing_component_type_id())
377            .ok_or_else(|| {
378                format!(
379                    "Component {} not found",
380                    self.uni.get_containing_component_type_id()
381                )
382            })?;
383        if current_component.is_primitive || current_component.is_struct_only_component {
384            return Err("Component doesn't accept template nodes.".to_string());
385        }
386        if current_component.template.is_none() {
387            return Err("Component doesn't have a template.".to_string());
388        }
389
390        let template = current_component.template.as_mut().unwrap();
391
392        if *requested_component != uni.get_containing_component_type_id() {
393            return Err("Cannot move node to a different component.".to_string());
394        }
395
396        self._cached_old_position = template.get_location(&self.uni.get_template_node_id());
397        template.move_node(&uni.get_template_node_id(), self.new_location.clone());
398
399        Ok(MoveTemplateNodeResponse {
400            command_id: None,
401            _affected_component_type_id: uni.get_containing_component_type_id(),
402        })
403    }
404
405    fn as_undo_redo(&mut self) -> Option<UndoRedoCommand> {
406        Some(UndoRedoCommand::MoveTemplateNodeRequest(Box::new(
407            self.clone(),
408        )))
409    }
410}
411
412impl Undo for MoveTemplateNodeRequest {
413    fn undo(&mut self, manifest: &mut PaxManifest) -> Result<(), String> {
414        let component = manifest
415            .components
416            .get_mut(&self.uni.get_containing_component_type_id())
417            .unwrap();
418
419        if let Some(template) = &mut component.template {
420            if let Some(location) = &self._cached_old_position {
421                template.move_node(&self.uni.get_template_node_id(), location.clone());
422            }
423        }
424        Ok(())
425    }
426}
427
428#[derive(Serialize, Deserialize, Clone, Debug)]
429pub struct PasteSubTreeRequest {
430    new_location: NodeLocation,
431    subtrees: SubTrees,
432    _cached_template: Option<ComponentTemplate>,
433}
434
435impl PasteSubTreeRequest {
436    pub fn new(new_location: NodeLocation, subtrees: SubTrees) -> Self {
437        Self {
438            new_location,
439            subtrees,
440            _cached_template: None,
441        }
442    }
443}
444
445pub struct PasteSubTreeResponse {
446    command_id: Option<usize>,
447    root_ids: Vec<TemplateNodeId>,
448    _affected_component_type_id: TypeId,
449}
450
451impl PasteSubTreeResponse {
452    pub fn get_created(&self) -> &[TemplateNodeId] {
453        &self.root_ids
454    }
455}
456
457impl Request for PasteSubTreeRequest {
458    type Response = PasteSubTreeResponse;
459}
460
461impl Response for PasteSubTreeResponse {
462    fn set_id(&mut self, id: usize) {
463        self.command_id = Some(id);
464    }
465    fn get_id(&self) -> usize {
466        self.command_id.unwrap()
467    }
468    fn get_reload_type(&self) -> Option<ReloadType> {
469        Some(ReloadType::Tree)
470    }
471}
472
473impl Command<PasteSubTreeRequest> for PasteSubTreeRequest {
474    fn execute(&mut self, manifest: &mut PaxManifest) -> Result<PasteSubTreeResponse, String> {
475        let type_id = self.new_location.get_type_id();
476        let component = manifest
477            .components
478            .get_mut(type_id)
479            .ok_or_else(|| format!("Component {} not found", type_id))?;
480        if component.is_primitive || component.is_struct_only_component {
481            return Err("Component doesn't accept template nodes.".to_string());
482        }
483        if component.template.is_none() {
484            return Err("Component doesn't have a template.".to_string());
485        }
486
487        let template = component.template.as_mut().unwrap();
488        self._cached_template = Some(template.clone());
489
490        let mut root_ids = vec![];
491        for r in self.subtrees.roots.iter().rev() {
492            let def = self
493                .subtrees
494                .nodes
495                .get(r)
496                .ok_or_else(|| "Node not found".to_string())?;
497            let id = template
498                .add_at(def.clone(), self.new_location.clone())
499                .get_template_node_id();
500            root_ids.push(id.clone());
501            let mut to_visit = vec![];
502            if let Some(children) = self.subtrees.children.get(r) {
503                to_visit.push((id, children.clone()));
504            }
505            while let Some((id, children)) = to_visit.pop() {
506                for c in children {
507                    let c_def = self
508                        .subtrees
509                        .nodes
510                        .get(&c)
511                        .ok_or_else(|| "Child node not found".to_string())?;
512                    let c_id = template
513                        .add_child_back(id.clone(), c_def.clone())
514                        .get_template_node_id();
515                    if let Some(c_children) = self.subtrees.children.get(&c) {
516                        to_visit.push((c_id, c_children.clone()));
517                    }
518                }
519            }
520        }
521
522        Ok(PasteSubTreeResponse {
523            command_id: None,
524            root_ids,
525            _affected_component_type_id: type_id.clone(),
526        })
527    }
528
529    fn as_undo_redo(&mut self) -> Option<UndoRedoCommand> {
530        Some(UndoRedoCommand::PasteSubTreeRequest(Box::new(self.clone())))
531    }
532}
533
534impl Undo for PasteSubTreeRequest {
535    fn undo(&mut self, manifest: &mut PaxManifest) -> Result<(), String> {
536        let component = manifest
537            .components
538            .get_mut(&self.new_location.type_id)
539            .unwrap();
540        component.template.clone_from(&self._cached_template);
541        Ok(())
542    }
543}
544
545#[derive(Serialize, Deserialize, Clone, Debug)]
546pub struct RemoveTemplateNodeRequest {
547    uni: UniqueTemplateNodeIdentifier,
548    // Used for Undo/Redo
549    _cached_template: Option<ComponentTemplate>,
550}
551
552impl RemoveTemplateNodeRequest {
553    pub fn new(uni: UniqueTemplateNodeIdentifier) -> Self {
554        RemoveTemplateNodeRequest {
555            uni,
556            _cached_template: None,
557        }
558    }
559}
560
561pub struct RemoveTemplateNodeResponse {
562    command_id: Option<usize>,
563    _affected_component_type_id: TypeId,
564}
565
566impl Request for RemoveTemplateNodeRequest {
567    type Response = RemoveTemplateNodeResponse;
568}
569
570impl Response for RemoveTemplateNodeResponse {
571    fn set_id(&mut self, id: usize) {
572        self.command_id = Some(id);
573    }
574    fn get_id(&self) -> usize {
575        self.command_id.unwrap()
576    }
577    fn get_reload_type(&self) -> Option<ReloadType> {
578        Some(ReloadType::Tree)
579    }
580}
581
582impl Command<RemoveTemplateNodeRequest> for RemoveTemplateNodeRequest {
583    fn execute(
584        &mut self,
585        manifest: &mut PaxManifest,
586    ) -> Result<RemoveTemplateNodeResponse, String> {
587        let component = manifest
588            .components
589            .get_mut(&self.uni.get_containing_component_type_id())
590            .ok_or_else(|| {
591                format!(
592                    "Component {} not found",
593                    self.uni.get_containing_component_type_id()
594                )
595            })?;
596        if component.is_primitive || component.is_struct_only_component {
597            unreachable!("Component doesn't accept template nodes.");
598        }
599
600        if let Some(template) = &mut component.template {
601            self._cached_template = Some(template.clone());
602            template.remove_node(self.uni.get_template_node_id());
603        };
604
605        Ok(RemoveTemplateNodeResponse {
606            command_id: None,
607            _affected_component_type_id: self.uni.get_containing_component_type_id(),
608        })
609    }
610
611    fn as_undo_redo(&mut self) -> Option<UndoRedoCommand> {
612        Some(UndoRedoCommand::RemoveTemplateNodeRequest(Box::new(
613            self.clone(),
614        )))
615    }
616}
617
618impl Undo for RemoveTemplateNodeRequest {
619    fn undo(&mut self, manifest: &mut PaxManifest) -> Result<(), String> {
620        let component = manifest
621            .components
622            .get_mut(&self.uni.get_containing_component_type_id())
623            .ok_or_else(|| {
624                format!(
625                    "Component {} not found",
626                    self.uni.get_containing_component_type_id()
627                )
628            })?;
629        component.template.clone_from(&self._cached_template);
630        Ok(())
631    }
632}
633
634pub struct GetTemplateNodeRequest {
635    pub uni: UniqueTemplateNodeIdentifier,
636}
637
638pub struct GetTemplateNodeResponse {
639    pub command_id: Option<usize>,
640    pub node: Option<TemplateNodeDefinition>,
641}
642
643impl Request for GetTemplateNodeRequest {
644    type Response = GetTemplateNodeResponse;
645}
646
647impl Response for GetTemplateNodeResponse {
648    fn set_id(&mut self, id: usize) {
649        self.command_id = Some(id);
650    }
651    fn get_id(&self) -> usize {
652        self.command_id.unwrap()
653    }
654}
655
656impl Command<GetTemplateNodeRequest> for GetTemplateNodeRequest {
657    fn execute(
658        &mut self,
659        manifest: &mut PaxManifest,
660    ) -> Result<<GetTemplateNodeRequest as Request>::Response, String> {
661        let component = manifest
662            .components
663            .get_mut(&self.uni.get_containing_component_type_id())
664            .ok_or_else(|| {
665                format!(
666                    "Component {} not found",
667                    self.uni.get_containing_component_type_id()
668                )
669            })?;
670
671        let mut node = None;
672        if let Some(template) = &component.template {
673            if let Some(n) = template.get_node(&self.uni.get_template_node_id()) {
674                node = Some(n.clone());
675            }
676        }
677
678        Ok(GetTemplateNodeResponse {
679            command_id: None,
680            node,
681        })
682    }
683}
684
685pub struct GetChildrenRequest {
686    pub uni: UniqueTemplateNodeIdentifier,
687}
688
689pub struct GetChildrenResponse {
690    command_id: Option<usize>,
691    #[allow(unused)]
692    pub children: Vec<UniqueTemplateNodeIdentifier>,
693}
694
695impl Request for GetChildrenRequest {
696    type Response = GetChildrenResponse;
697}
698
699impl Response for GetChildrenResponse {
700    fn set_id(&mut self, id: usize) {
701        self.command_id = Some(id);
702    }
703    fn get_id(&self) -> usize {
704        self.command_id.unwrap()
705    }
706}
707
708impl Command<GetChildrenRequest> for GetChildrenRequest {
709    fn execute(
710        &mut self,
711        manifest: &mut PaxManifest,
712    ) -> Result<<GetChildrenRequest as Request>::Response, String> {
713        let component = manifest
714            .components
715            .get_mut(&self.uni.get_containing_component_type_id())
716            .unwrap();
717
718        let mut children = vec![];
719        if let Some(template) = &component.template {
720            if let Some(n) = template.get_children(&self.uni.get_template_node_id()) {
721                children = n
722                    .iter()
723                    .map(|tnid| {
724                        UniqueTemplateNodeIdentifier::build(
725                            self.uni.get_containing_component_type_id(),
726                            tnid.clone(),
727                        )
728                    })
729                    .collect();
730            }
731        }
732
733        Ok(GetChildrenResponse {
734            command_id: None,
735            children,
736        })
737    }
738}
739
740pub struct GetAllTemplateNodeRequest {
741    component_type_id: TypeId,
742}
743
744pub struct GetAllTemplateNodeResponse {
745    command_id: Option<usize>,
746    #[allow(unused)]
747    nodes: Option<Vec<TemplateNodeDefinition>>,
748}
749
750impl Request for GetAllTemplateNodeRequest {
751    type Response = GetAllTemplateNodeResponse;
752}
753
754impl Response for GetAllTemplateNodeResponse {
755    fn set_id(&mut self, id: usize) {
756        self.command_id = Some(id);
757    }
758    fn get_id(&self) -> usize {
759        self.command_id.unwrap()
760    }
761}
762
763impl Command<GetAllTemplateNodeRequest> for GetAllTemplateNodeRequest {
764    fn execute(
765        &mut self,
766        manifest: &mut PaxManifest,
767    ) -> Result<<GetAllTemplateNodeRequest as Request>::Response, String> {
768        let component = manifest
769            .components
770            .get_mut(&self.component_type_id)
771            .unwrap();
772
773        let mut nodes = None;
774        if let Some(template) = &component.template {
775            nodes = Some(template.get_nodes_owned());
776        }
777
778        Ok(GetAllTemplateNodeResponse {
779            command_id: None,
780            nodes,
781        })
782    }
783}
784
785#[derive(Serialize, Deserialize, Clone)]
786pub struct ReplaceTemplateRequest {
787    component_type_id: TypeId,
788    new_template: ComponentTemplate,
789    settings_block: Vec<SettingsBlockElement>,
790    #[serde(default)]
791    timelines: Vec<TimelineDefinition>,
792    _cached_prev_template: Option<ComponentTemplate>,
793    _cached_prev_settings_block: Option<Vec<SettingsBlockElement>>,
794    #[serde(default)]
795    _cached_prev_timelines: Option<Vec<TimelineDefinition>>,
796}
797
798impl ReplaceTemplateRequest {
799    pub fn new(
800        component_type_id: TypeId,
801        new_template: ComponentTemplate,
802        settings_block: Vec<SettingsBlockElement>,
803        timelines: Vec<TimelineDefinition>,
804    ) -> Self {
805        Self {
806            component_type_id,
807            new_template,
808            settings_block,
809            timelines,
810            _cached_prev_template: None,
811            _cached_prev_settings_block: None,
812            _cached_prev_timelines: None,
813        }
814    }
815}
816
817pub struct ReplaceTemplateResponse {
818    command_id: Option<usize>,
819    _affected_component_type_id: TypeId,
820}
821
822impl Response for ReplaceTemplateResponse {
823    fn set_id(&mut self, id: usize) {
824        self.command_id = Some(id);
825    }
826    fn get_id(&self) -> usize {
827        self.command_id.unwrap()
828    }
829    fn get_reload_type(&self) -> Option<ReloadType> {
830        Some(ReloadType::Tree)
831    }
832}
833
834impl Request for ReplaceTemplateRequest {
835    type Response = ReplaceTemplateResponse;
836}
837
838impl Command<ReplaceTemplateRequest> for ReplaceTemplateRequest {
839    fn execute(&mut self, manifest: &mut PaxManifest) -> Result<ReplaceTemplateResponse, String> {
840        let component = manifest
841            .components
842            .get_mut(&self.component_type_id)
843            .unwrap();
844
845        self._cached_prev_template.clone_from(&component.template);
846        self._cached_prev_settings_block
847            .clone_from(&component.settings);
848        self._cached_prev_timelines = Some(component.timelines.clone());
849
850        component.template = Some(self.new_template.clone());
851        component.settings = Some(self.settings_block.clone());
852        component.timelines.clone_from(&self.timelines);
853
854        Ok(ReplaceTemplateResponse {
855            command_id: None,
856            _affected_component_type_id: self.component_type_id.clone(),
857        })
858    }
859
860    fn as_undo_redo(&mut self) -> Option<UndoRedoCommand> {
861        Some(UndoRedoCommand::ReplaceTemplateRequest(Box::new(
862            self.clone(),
863        )))
864    }
865}
866
867impl Undo for ReplaceTemplateRequest {
868    fn undo(&mut self, manifest: &mut PaxManifest) -> Result<(), String> {
869        let component = manifest
870            .components
871            .get_mut(&self.component_type_id)
872            .unwrap();
873        component.template.clone_from(&self._cached_prev_template);
874        component
875            .settings
876            .clone_from(&self._cached_prev_settings_block);
877        component.timelines = self._cached_prev_timelines.clone().unwrap_or_default();
878        Ok(())
879    }
880}
881
882#[derive(Serialize, Deserialize, Clone, Debug)]
883pub struct SerializedTemplateNodeSubtree {
884    pub node: TemplateNodeDefinition,
885    pub children: Vec<SerializedTemplateNodeSubtree>,
886}
887
888#[derive(Serialize, Deserialize, Clone)]
889pub struct ReplaceNodeSubtreeRequest {
890    uni: UniqueTemplateNodeIdentifier,
891    new_subtree: Option<SerializedTemplateNodeSubtree>,
892    reload_uni: Option<UniqueTemplateNodeIdentifier>,
893    _cached_template: Option<ComponentTemplate>,
894}
895
896impl ReplaceNodeSubtreeRequest {
897    pub fn new(
898        uni: UniqueTemplateNodeIdentifier,
899        new_subtree: Option<SerializedTemplateNodeSubtree>,
900        reload_uni: Option<UniqueTemplateNodeIdentifier>,
901    ) -> Self {
902        Self {
903            uni,
904            new_subtree,
905            reload_uni,
906            _cached_template: None,
907        }
908    }
909}
910
911pub struct ReplaceNodeSubtreeResponse {
912    command_id: Option<usize>,
913    _affected_component_type_id: TypeId,
914    reload_type: ReloadType,
915}
916
917impl Request for ReplaceNodeSubtreeRequest {
918    type Response = ReplaceNodeSubtreeResponse;
919}
920
921impl Response for ReplaceNodeSubtreeResponse {
922    fn set_id(&mut self, id: usize) {
923        self.command_id = Some(id);
924    }
925
926    fn get_id(&self) -> usize {
927        self.command_id.unwrap()
928    }
929
930    fn get_reload_type(&self) -> Option<ReloadType> {
931        Some(self.reload_type.clone())
932    }
933}
934
935impl Command<ReplaceNodeSubtreeRequest> for ReplaceNodeSubtreeRequest {
936    fn execute(
937        &mut self,
938        manifest: &mut PaxManifest,
939    ) -> Result<ReplaceNodeSubtreeResponse, String> {
940        let component = manifest
941            .components
942            .get_mut(&self.uni.get_containing_component_type_id())
943            .ok_or_else(|| {
944                format!(
945                    "Component {} not found",
946                    self.uni.get_containing_component_type_id()
947                )
948            })?;
949        if component.is_primitive || component.is_struct_only_component {
950            return Err("Component doesn't accept template nodes.".to_string());
951        }
952
953        let template = component
954            .template
955            .as_mut()
956            .ok_or_else(|| "Component has no template".to_string())?;
957        self._cached_template = Some(template.clone());
958
959        match &self.new_subtree {
960            Some(new_subtree) => {
961                replace_template_node_subtree(
962                    template,
963                    self.uni.get_template_node_id(),
964                    new_subtree,
965                )?;
966            }
967            None => {
968                template.remove_node(self.uni.get_template_node_id());
969            }
970        }
971
972        Ok(ReplaceNodeSubtreeResponse {
973            command_id: None,
974            _affected_component_type_id: self.uni.get_containing_component_type_id(),
975            reload_type: self
976                .reload_uni
977                .clone()
978                .map(ReloadType::Subtree)
979                .unwrap_or(ReloadType::Tree),
980        })
981    }
982
983    fn as_undo_redo(&mut self) -> Option<UndoRedoCommand> {
984        Some(UndoRedoCommand::ReplaceNodeSubtreeRequest(Box::new(
985            self.clone(),
986        )))
987    }
988}
989
990impl Undo for ReplaceNodeSubtreeRequest {
991    fn undo(&mut self, manifest: &mut PaxManifest) -> Result<(), String> {
992        let component = manifest
993            .components
994            .get_mut(&self.uni.get_containing_component_type_id())
995            .ok_or_else(|| {
996                format!(
997                    "Component {} not found",
998                    self.uni.get_containing_component_type_id()
999                )
1000            })?;
1001        let template = component
1002            .template
1003            .as_mut()
1004            .ok_or_else(|| "Component has no template".to_string())?;
1005        if let Some(cached_template) = &self._cached_template {
1006            *template = cached_template.clone();
1007        }
1008        Ok(())
1009    }
1010}
1011
1012fn replace_template_node_subtree(
1013    template: &mut ComponentTemplate,
1014    target_id: TemplateNodeId,
1015    new_subtree: &SerializedTemplateNodeSubtree,
1016) -> Result<(), String> {
1017    if template.get_node(&target_id).is_none() {
1018        return Err(format!("Template node {} does not exist", target_id));
1019    }
1020
1021    let existing_children = template.get_children(&target_id).unwrap_or_default();
1022    for child in existing_children {
1023        template.remove_node(child);
1024    }
1025
1026    template.set_node(target_id.clone(), new_subtree.node.clone());
1027    append_template_subtree_children(template, &target_id, &new_subtree.children);
1028    Ok(())
1029}
1030
1031fn append_template_subtree_children(
1032    template: &mut ComponentTemplate,
1033    parent_id: &TemplateNodeId,
1034    children: &[SerializedTemplateNodeSubtree],
1035) {
1036    for child in children {
1037        let child_uni = template.add_child_back(parent_id.clone(), child.node.clone());
1038        append_template_subtree_children(
1039            template,
1040            &child_uni.get_template_node_id(),
1041            &child.children,
1042        );
1043    }
1044}
1045
1046#[derive(Serialize, Deserialize, Clone, Debug)]
1047pub struct ConvertToComponentRequest {
1048    // These subtrees (roots) must be at the same TreeLocation
1049    subtrees_roots: Vec<MoveToComponentEntry>,
1050    new_component_number: usize,
1051    x: f64,
1052    y: f64,
1053    width: f64,
1054    height: f64,
1055
1056    // Used for Undo/Redo
1057    _cached_template: Option<ComponentTemplate>,
1058    _cached_add: Option<AddTemplateNodeRequest>,
1059    _cached_new_component_type_id: Option<TypeId>,
1060}
1061
1062impl ConvertToComponentRequest {
1063    pub fn new(
1064        subtrees_roots: Vec<MoveToComponentEntry>,
1065        new_component_number: usize,
1066        x: f64,
1067        y: f64,
1068        width: f64,
1069        height: f64,
1070    ) -> Self {
1071        Self {
1072            subtrees_roots,
1073            new_component_number,
1074            x,
1075            y,
1076            width,
1077            height,
1078            _cached_template: None,
1079            _cached_add: None,
1080            _cached_new_component_type_id: None,
1081        }
1082    }
1083}
1084
1085impl Request for ConvertToComponentRequest {
1086    type Response = ConvertToComponentResponse;
1087}
1088
1089#[derive(Serialize, Deserialize, Clone)]
1090pub struct ConvertToComponentResponse {
1091    command_id: Option<usize>,
1092    pub uni: UniqueTemplateNodeIdentifier,
1093    pub new_component_type_id: TypeId,
1094}
1095
1096impl Response for ConvertToComponentResponse {
1097    fn set_id(&mut self, id: usize) {
1098        self.command_id = Some(id);
1099    }
1100    fn get_id(&self) -> usize {
1101        self.command_id.unwrap()
1102    }
1103    fn get_reload_type(&self) -> Option<ReloadType> {
1104        Some(ReloadType::Tree)
1105    }
1106}
1107
1108impl Command<ConvertToComponentRequest> for ConvertToComponentRequest {
1109    fn execute(
1110        &mut self,
1111        manifest: &mut PaxManifest,
1112    ) -> Result<ConvertToComponentResponse, String> {
1113        if self.subtrees_roots.is_empty() {
1114            return Err("No subtrees provided".to_string());
1115        }
1116
1117        let new_component_identifier = format!("NewComponent{}", self.new_component_number);
1118        let new_component_file_name = format!("new_component_{}.pax", self.new_component_number);
1119        let new_component_type_id = TypeId::build_blank_component(&new_component_identifier);
1120
1121        let (module_path, ul_path) = {
1122            let ul_bind = manifest.components.get(&manifest.main_component_type_id);
1123            let ul = ul_bind.expect("Main component not found").clone();
1124            (
1125                ul.module_path.clone(),
1126                ul.template
1127                    .as_ref()
1128                    .expect("Main component template not found")
1129                    .get_file_path()
1130                    .expect("Main component file path not found")
1131                    .clone(),
1132            )
1133        };
1134
1135        let new_component_path = PathBuf::from(ul_path)
1136            .parent()
1137            .expect("Main component path has no parent")
1138            .join(new_component_file_name)
1139            .to_str()
1140            .map(|s| s.to_string());
1141
1142        let current_component_type_id = self.subtrees_roots[0]
1143            .id
1144            .get_containing_component_type_id()
1145            .clone();
1146        let binding = manifest.components.get_mut(&current_component_type_id);
1147        let current_component = binding.expect("Component not found");
1148        let current_component_template = current_component
1149            .template
1150            .as_mut()
1151            .expect("Component template not found");
1152
1153        self._cached_template = Some(current_component_template.clone());
1154
1155        let mut new_template =
1156            ComponentTemplate::new(new_component_type_id.clone(), new_component_path);
1157
1158        fn add_subtree_to_new_template(
1159            current_template: &ComponentTemplate,
1160            new_template: &mut ComponentTemplate,
1161            node_id: TemplateNodeId,
1162            node_location: NodeLocation,
1163            root_bounds: Vec<MoveToComponentEntry>,
1164        ) {
1165            let mut node = current_template
1166                .get_node(&node_id)
1167                .expect("Node not found")
1168                .clone();
1169
1170            let relevant_bounds = root_bounds
1171                .iter()
1172                .filter(|entry| entry.id.get_template_node_id() == node_id)
1173                .collect::<Vec<_>>();
1174
1175            if let Some(e) = relevant_bounds.first() {
1176                if let Some(settings) = &mut node.settings {
1177                    update_position_if_exists(e.x, e.y, settings);
1178                }
1179            }
1180
1181            let new_node_id = new_template.add_at(node, node_location.clone());
1182            for child in current_template.get_children(&node_id).unwrap_or_default() {
1183                let location = NodeLocation::new(
1184                    node_location.type_id.clone(),
1185                    TreeLocation::Parent(new_node_id.get_template_node_id().clone()),
1186                    TreeIndexPosition::Bottom,
1187                );
1188                add_subtree_to_new_template(
1189                    current_template,
1190                    new_template,
1191                    child,
1192                    location,
1193                    root_bounds.clone(),
1194                );
1195            }
1196        }
1197
1198        // sort ids by TreeIndexPosition
1199        let mut ids_with_location = self
1200            .subtrees_roots
1201            .iter()
1202            .map(|entry| {
1203                let template_node_id = entry.id.get_template_node_id();
1204                let location = current_component_template
1205                    .get_location(&template_node_id)
1206                    .expect("Location not found")
1207                    .clone();
1208                (template_node_id, location)
1209            })
1210            .collect::<Vec<_>>();
1211
1212        ids_with_location.sort_by(|a, b| a.1.cmp(&b.1));
1213
1214        let new_component_location = ids_with_location.first().unwrap().1.clone();
1215
1216        let mut processed_ids: Vec<TemplateNodeId> = vec![];
1217        let new_bounds = self
1218            .subtrees_roots
1219            .iter()
1220            .map(|e| {
1221                let mut new_entry = e.clone();
1222                new_entry.x -= self.x;
1223                new_entry.y -= self.y;
1224                new_entry
1225            })
1226            .collect::<Vec<_>>();
1227
1228        for (id, nl) in ids_with_location {
1229            let new_location = NodeLocation::new(
1230                new_component_type_id.clone(),
1231                nl.tree_location.clone(),
1232                TreeIndexPosition::Bottom,
1233            );
1234            add_subtree_to_new_template(
1235                current_component_template,
1236                &mut new_template,
1237                id.clone(),
1238                new_location,
1239                new_bounds.clone(),
1240            );
1241            current_component_template.remove_node(id.clone());
1242            processed_ids.push(id);
1243        }
1244
1245        let new_component = ComponentDefinition {
1246            type_id: new_component_type_id.clone(),
1247            is_main_component: false,
1248            is_primitive: false,
1249            is_struct_only_component: false,
1250            module_path,
1251            primitive_instance_import_path: None,
1252            template: Some(new_template),
1253            settings: None,
1254            timelines: vec![],
1255            route_branch: None,
1256        };
1257
1258        manifest
1259            .components
1260            .insert(new_component_type_id.clone(), new_component);
1261
1262        self._cached_new_component_type_id = Some(new_component_type_id.clone());
1263
1264        let settings = {
1265            let mut settings: Vec<SettingElement> = Vec::new();
1266            settings.push(SettingElement::Setting(
1267                Token::new_without_location("x".to_string()),
1268                ValueDefinition::LiteralValue(self.x.to_pax_value()),
1269            ));
1270            settings.push(SettingElement::Setting(
1271                Token::new_without_location("y".to_string()),
1272                ValueDefinition::LiteralValue(self.y.to_pax_value()),
1273            ));
1274            settings.push(SettingElement::Setting(
1275                Token::new_without_location("width".to_string()),
1276                ValueDefinition::LiteralValue(self.width.to_pax_value()),
1277            ));
1278            settings.push(SettingElement::Setting(
1279                Token::new_without_location("height".to_string()),
1280                ValueDefinition::LiteralValue(self.height.to_pax_value()),
1281            ));
1282            settings
1283        };
1284
1285        let mut add_request = AddTemplateNodeRequest::new(
1286            current_component_type_id.clone(),
1287            new_component_type_id.clone(),
1288            NodeType::Template(settings),
1289            Some(new_component_location),
1290        );
1291        let response = add_request.execute(manifest)?;
1292
1293        self._cached_add = Some(add_request);
1294
1295        Ok(ConvertToComponentResponse {
1296            command_id: None,
1297            uni: response.uni,
1298            new_component_type_id,
1299        })
1300    }
1301
1302    fn as_undo_redo(&mut self) -> Option<UndoRedoCommand> {
1303        Some(UndoRedoCommand::ConvertToComponentRequest(Box::new(
1304            self.clone(),
1305        )))
1306    }
1307}
1308
1309impl Undo for ConvertToComponentRequest {
1310    fn undo(&mut self, manifest: &mut PaxManifest) -> Result<(), String> {
1311        if let Some(add_request) = &mut self._cached_add {
1312            add_request.undo(manifest).unwrap();
1313        }
1314
1315        if let Some(new_component_type_id) = &self._cached_new_component_type_id {
1316            manifest.components.remove(new_component_type_id);
1317        }
1318
1319        if let Some(template) = &self._cached_template {
1320            let binding = manifest
1321                .components
1322                .get_mut(&self.subtrees_roots[0].id.get_containing_component_type_id());
1323            let current_component = binding.expect("Component not found");
1324            current_component.template = Some(template.clone());
1325        }
1326
1327        Ok(())
1328    }
1329}
1330
1331/// Swap main component with a new component
1332#[derive(Serialize, Deserialize, Clone)]
1333pub struct SwapMainComponentRequest {
1334    new_component: ComponentDefinition,
1335    _cached_main_component: Option<ComponentDefinition>,
1336}
1337
1338impl SwapMainComponentRequest {
1339    pub fn new(new_componnet: ComponentDefinition) -> Self {
1340        Self {
1341            new_component: new_componnet,
1342            _cached_main_component: None,
1343        }
1344    }
1345}
1346
1347pub struct SwapMainComponentResponse {
1348    command_id: Option<usize>,
1349}
1350
1351impl Request for SwapMainComponentRequest {
1352    type Response = SwapMainComponentResponse;
1353}
1354
1355impl Response for SwapMainComponentResponse {
1356    fn set_id(&mut self, id: usize) {
1357        self.command_id = Some(id);
1358    }
1359    fn get_id(&self) -> usize {
1360        self.command_id.unwrap()
1361    }
1362
1363    fn get_reload_type(&self) -> Option<ReloadType> {
1364        Some(ReloadType::Tree)
1365    }
1366}
1367
1368impl Command<SwapMainComponentRequest> for SwapMainComponentRequest {
1369    fn execute(&mut self, manifest: &mut PaxManifest) -> Result<SwapMainComponentResponse, String> {
1370        let main_component = manifest
1371            .components
1372            .get_mut(&manifest.main_component_type_id)
1373            .unwrap();
1374
1375        self._cached_main_component = Some(main_component.clone());
1376
1377        manifest.components.insert(
1378            self.new_component.type_id.clone(),
1379            self.new_component.clone(),
1380        );
1381        manifest.main_component_type_id = self.new_component.type_id.clone();
1382        Ok(SwapMainComponentResponse { command_id: None })
1383    }
1384}
1385
1386impl Undo for SwapMainComponentRequest {
1387    fn undo(&mut self, manifest: &mut PaxManifest) -> Result<(), String> {
1388        manifest.components.remove(&self.new_component.type_id);
1389        manifest.main_component_type_id = self
1390            ._cached_main_component
1391            .as_ref()
1392            .unwrap()
1393            .type_id
1394            .clone();
1395        manifest.components.insert(
1396            self._cached_main_component
1397                .as_ref()
1398                .unwrap()
1399                .type_id
1400                .clone(),
1401            self._cached_main_component.as_ref().unwrap().clone(),
1402        );
1403        Ok(())
1404    }
1405}
1406
1407#[derive(Serialize, Deserialize, Debug, Clone)]
1408pub enum NodeAction {
1409    Add(AddTemplateNodeRequest),
1410    Update(UpdateTemplateNodeRequest),
1411    Remove(RemoveTemplateNodeRequest),
1412    Move(PasteSubTreeRequest),
1413}
1414
1415pub fn update_position_if_exists(new_x: f64, new_y: f64, settings: &mut [SettingElement]) {
1416    for setting in settings.iter_mut() {
1417        if let SettingElement::Setting(key, value) = setting {
1418            if key.token_value == "x" {
1419                *value = ValueDefinition::LiteralValue(new_x.to_pax_value())
1420            }
1421            if key.token_value == "y" {
1422                *value = ValueDefinition::LiteralValue(new_y.to_pax_value())
1423            }
1424        }
1425    }
1426}