Skip to main content

ferrum_flow/plugins/
delete.rs

1use crate::{
2    Edge, GraphOp, Node,
3    canvas::Command,
4    plugin::{FlowEvent, Plugin},
5};
6
7pub struct DeletePlugin;
8
9impl DeletePlugin {
10    pub fn new() -> Self {
11        Self {}
12    }
13}
14
15pub(crate) fn delete_selection(ctx: &mut crate::plugin::PluginContext) {
16    ctx.execute_command(DeleteCommand::new(ctx));
17}
18
19impl Plugin for DeletePlugin {
20    fn name(&self) -> &'static str {
21        "delete"
22    }
23    fn setup(&mut self, _ctx: &mut crate::plugin::InitPluginContext) {}
24    fn on_event(
25        &mut self,
26        event: &FlowEvent,
27        ctx: &mut crate::plugin::PluginContext,
28    ) -> crate::plugin::EventResult {
29        if let FlowEvent::Input(crate::plugin::InputEvent::KeyDown(ev)) = event {
30            if ev.keystroke.key == "delete" || ev.keystroke.key == "backspace" {
31                ctx.execute_command(DeleteCommand::new(&ctx));
32                return crate::plugin::EventResult::Stop;
33            }
34        }
35        crate::plugin::EventResult::Continue
36    }
37}
38
39struct DeleteCommand {
40    selected_edge: Vec<Edge>,
41    selected_node: Vec<Node>,
42}
43
44impl DeleteCommand {
45    fn new(ctx: &crate::plugin::PluginContext) -> Self {
46        Self {
47            selected_edge: ctx
48                .graph
49                .selected_edge
50                .iter()
51                .filter_map(|id| ctx.graph.edges.get(id).cloned())
52                .collect(),
53            selected_node: ctx
54                .graph
55                .selected_node
56                .iter()
57                .filter_map(|id| ctx.get_node(id).cloned())
58                .collect(),
59        }
60    }
61}
62
63impl Command for DeleteCommand {
64    fn name(&self) -> &'static str {
65        "delete"
66    }
67    fn execute(&mut self, ctx: &mut crate::canvas::CommandContext) {
68        ctx.remove_selected_edge();
69        ctx.remove_selected_node();
70    }
71    fn undo(&mut self, ctx: &mut crate::canvas::CommandContext) {
72        for edge in &self.selected_edge {
73            ctx.add_edge(edge.clone());
74            ctx.add_selected_edge(edge.id, true);
75        }
76
77        for node in &self.selected_node {
78            ctx.add_node(node.clone());
79            ctx.add_selected_node(node.id, true);
80        }
81    }
82
83    fn to_ops(&self, ctx: &mut crate::CommandContext) -> Vec<crate::GraphOp> {
84        let mut list = vec![];
85        for node in &self.selected_node {
86            list.push(GraphOp::RemoveNode { id: node.id });
87            let mut port_ids = node.inputs.clone();
88            port_ids.extend(node.outputs.clone());
89
90            let index = ctx.graph.node_order().iter().position(|v| *v == node.id);
91            if let Some(index) = index {
92                list.push(GraphOp::NodeOrderRemove { index })
93            }
94
95            for port_id in port_ids.iter() {
96                let edge1 = ctx
97                    .graph
98                    .edges
99                    .iter()
100                    .find(|(_, edge)| edge.source_port == *port_id);
101                if let Some((&edge_id, _)) = edge1 {
102                    list.push(GraphOp::RemoveEdge(edge_id));
103                }
104
105                let edge2 = ctx
106                    .graph
107                    .edges
108                    .iter()
109                    .find(|(_, edge)| edge.target_port == *port_id);
110                if let Some((&edge_id, _)) = edge2 {
111                    list.push(GraphOp::RemoveEdge(edge_id));
112                }
113
114                list.push(GraphOp::RemovePort(*port_id));
115            }
116        }
117
118        for edge in &self.selected_edge {
119            list.push(GraphOp::RemoveEdge(edge.id));
120        }
121
122        list
123    }
124}