ferrum_flow/plugins/
delete.rs1use 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}