jellyflow_runtime/runtime/selection/
types.rs1use serde::{Deserialize, Serialize};
2
3use jellyflow_core::core::{CanvasPoint, CanvasRect, CanvasSize, EdgeId, GroupId, NodeId};
4
5#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
7#[serde(rename_all = "snake_case")]
8pub enum SelectionModifier {
9 #[default]
10 Replace,
11 Additive,
12}
13
14impl SelectionModifier {
15 pub fn additive(self) -> bool {
16 matches!(self, Self::Additive)
17 }
18}
19
20#[derive(Debug, Clone, Copy, Default, PartialEq, Serialize, Deserialize)]
22pub struct SelectionBoxOptions {
23 #[serde(default)]
25 pub modifier: SelectionModifier,
26 #[serde(default, skip_serializing_if = "Option::is_none")]
28 pub fallback_size: Option<CanvasSize>,
29}
30
31#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
33pub struct SelectionBoxInput {
34 pub rect: CanvasRect,
35 #[serde(default)]
36 pub options: SelectionBoxOptions,
37}
38
39impl SelectionBoxInput {
40 pub fn new(rect: CanvasRect, options: SelectionBoxOptions) -> Self {
41 Self { rect, options }
42 }
43
44 pub fn from_drag(
45 start: CanvasPoint,
46 current: CanvasPoint,
47 options: SelectionBoxOptions,
48 ) -> Self {
49 Self::new(normalized_drag_rect(start, current), options)
50 }
51
52 pub fn replace(rect: CanvasRect) -> Self {
53 Self::new(rect, SelectionBoxOptions::default())
54 }
55
56 pub fn replace_from_drag(start: CanvasPoint, current: CanvasPoint) -> Self {
57 Self::from_drag(start, current, SelectionBoxOptions::default())
58 }
59
60 pub fn additive(rect: CanvasRect) -> Self {
61 Self::new(
62 rect,
63 SelectionBoxOptions {
64 modifier: SelectionModifier::Additive,
65 ..SelectionBoxOptions::default()
66 },
67 )
68 }
69
70 pub fn additive_from_drag(start: CanvasPoint, current: CanvasPoint) -> Self {
71 Self::from_drag(
72 start,
73 current,
74 SelectionBoxOptions {
75 modifier: SelectionModifier::Additive,
76 ..SelectionBoxOptions::default()
77 },
78 )
79 }
80}
81
82fn normalized_drag_rect(start: CanvasPoint, current: CanvasPoint) -> CanvasRect {
83 let min_x = start.x.min(current.x);
84 let min_y = start.y.min(current.y);
85 CanvasRect {
86 origin: CanvasPoint { x: min_x, y: min_y },
87 size: CanvasSize {
88 width: (start.x - current.x).abs(),
89 height: (start.y - current.y).abs(),
90 },
91 }
92}
93
94#[derive(Debug, Clone, Default, PartialEq, Eq)]
96pub struct SelectionBoxResult {
97 pub nodes: Vec<NodeId>,
98 pub edges: Vec<EdgeId>,
99 pub groups: Vec<GroupId>,
100}
101
102impl SelectionBoxResult {
103 pub fn is_empty(&self) -> bool {
104 self.nodes.is_empty() && self.edges.is_empty() && self.groups.is_empty()
105 }
106}
107
108#[derive(Debug, Clone, Default, PartialEq, Eq)]
110pub struct SelectionBoxDecision {
111 result: SelectionBoxResult,
112}
113
114impl SelectionBoxDecision {
115 pub fn new(result: SelectionBoxResult) -> Self {
116 Self { result }
117 }
118
119 pub fn result(&self) -> &SelectionBoxResult {
120 &self.result
121 }
122
123 pub fn into_result(self) -> SelectionBoxResult {
124 self.result
125 }
126}