hadrone_core/
interaction.rs1use crate::{CollisionStrategy, CompactionType, LayoutItem, ResizeHandle, layout_engine};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
5pub enum InteractionType {
6 Drag,
8 Resize,
10}
11
12#[derive(Debug, Clone, PartialEq)]
16pub struct InteractionSession {
17 pub id: String,
19 pub interaction_type: InteractionType,
21 pub start_mouse: (f32, f32),
23 pub start_rect: (i32, i32, i32, i32),
25 pub handle: ResizeHandle,
27 pub col_width_px: f32,
29 pub row_height_px: f32,
31 pub margin: (i32, i32),
33 pub container_padding: (i32, i32),
36 pub compaction: CompactionType,
38 pub collision: CollisionStrategy,
40}
41
42impl InteractionSession {
43 pub fn get_smooth_offset(&self, current_mouse: (f32, f32)) -> (f32, f32) {
45 (
46 current_mouse.0 - self.start_mouse.0,
47 current_mouse.1 - self.start_mouse.1,
48 )
49 }
50
51 pub fn update(&self, current_mouse: (f32, f32), layout: &mut Vec<LayoutItem>, cols: i32) {
54 let (dx, dy) = self.get_smooth_offset(current_mouse);
55
56 let grid_dx = (dx / self.col_width_px).round() as i32;
57 let grid_dy = (dy / (self.row_height_px + self.margin.1 as f32)).round() as i32;
58
59 let engine = layout_engine(self.compaction, self.collision, cols);
60
61 match self.interaction_type {
62 InteractionType::Drag => {
63 engine.move_element(
64 layout,
65 &self.id,
66 self.start_rect.0 + grid_dx,
67 self.start_rect.1 + grid_dy,
68 );
69 }
70 InteractionType::Resize => {
71 let (mut nx, mut ny, mut nw, mut nh) = self.start_rect;
72
73 match self.handle {
74 ResizeHandle::East => {
75 nw += grid_dx;
76 }
77 ResizeHandle::West => {
78 nx += grid_dx;
79 nw -= grid_dx;
80 }
81 ResizeHandle::South => {
82 nh += grid_dy;
83 }
84 ResizeHandle::North => {
85 ny += grid_dy;
86 nh -= grid_dy;
87 }
88 ResizeHandle::SouthEast => {
89 nw += grid_dx;
90 nh += grid_dy;
91 }
92 ResizeHandle::SouthWest => {
93 nx += grid_dx;
94 nw -= grid_dx;
95 nh += grid_dy;
96 }
97 ResizeHandle::NorthEast => {
98 ny += grid_dy;
99 nh -= grid_dy;
100 nw += grid_dx;
101 }
102 ResizeHandle::NorthWest => {
103 nx += grid_dx;
104 nw -= grid_dx;
105 ny += grid_dy;
106 nh -= grid_dy;
107 }
108 }
109
110 engine.resize_element(layout, &self.id, nx, ny, nw, nh, Some(self.handle));
111 }
112 }
113 }
114
115 pub fn get_visual_rect(&self, current_mouse: (f32, f32)) -> (f32, f32, f32, f32) {
118 let (dx, dy) = self.get_smooth_offset(current_mouse);
119 let (pad_x, pad_y) = (
120 self.container_padding.0 as f32,
121 self.container_padding.1 as f32,
122 );
123
124 let mut x = self.start_rect.0 as f32 * self.col_width_px + pad_x;
126 let mut y = self.start_rect.1 as f32 * (self.row_height_px + self.margin.1 as f32) + pad_y;
127 let mut w = (self.start_rect.2 as f32 * self.col_width_px) - self.margin.0 as f32;
128 let mut h = self.start_rect.3 as f32 * self.row_height_px
129 + (self.start_rect.3 as f32 - 1.0) * self.margin.1 as f32;
130
131 match self.interaction_type {
132 InteractionType::Drag => {
133 x += dx;
134 y += dy;
135 }
136 InteractionType::Resize => match self.handle {
137 ResizeHandle::East => {
138 w += dx;
139 }
140 ResizeHandle::West => {
141 x += dx;
142 w -= dx;
143 }
144 ResizeHandle::South => {
145 h += dy;
146 }
147 ResizeHandle::North => {
148 y += dy;
149 h -= dy;
150 }
151 ResizeHandle::SouthEast => {
152 w += dx;
153 h += dy;
154 }
155 ResizeHandle::SouthWest => {
156 x += dx;
157 w -= dx;
158 h += dy;
159 }
160 ResizeHandle::NorthEast => {
161 y += dy;
162 h -= dy;
163 w += dx;
164 }
165 ResizeHandle::NorthWest => {
166 x += dx;
167 w -= dx;
168 y += dy;
169 h -= dy;
170 }
171 },
172 }
173
174 (x, y, w, h)
175 }
176
177 pub fn get_visual_delta(&self, current_mouse: (f32, f32)) -> (f32, f32, f32, f32) {
180 let (dx, dy) = self.get_smooth_offset(current_mouse);
181 let mut out_dx = 0.0;
182 let mut out_dy = 0.0;
183 let mut out_dw = 0.0;
184 let mut out_dh = 0.0;
185
186 match self.interaction_type {
187 InteractionType::Drag => {
188 out_dx = dx;
189 out_dy = dy;
190 }
191 InteractionType::Resize => match self.handle {
192 ResizeHandle::East => {
193 out_dw = dx;
194 }
195 ResizeHandle::West => {
196 out_dx = dx;
197 out_dw = -dx;
198 }
199 ResizeHandle::South => {
200 out_dh = dy;
201 }
202 ResizeHandle::North => {
203 out_dy = dy;
204 out_dh = -dy;
205 }
206 ResizeHandle::SouthEast => {
207 out_dw = dx;
208 out_dh = dy;
209 }
210 ResizeHandle::SouthWest => {
211 out_dx = dx;
212 out_dw = -dx;
213 out_dh = dy;
214 }
215 ResizeHandle::NorthEast => {
216 out_dy = dy;
217 out_dh = -dy;
218 out_dw = dx;
219 }
220 ResizeHandle::NorthWest => {
221 out_dx = dx;
222 out_dw = -dx;
223 out_dy = dy;
224 out_dh = -dy;
225 }
226 },
227 }
228 (out_dx, out_dy, out_dw, out_dh)
229 }
230}