Skip to content

Commit d44b0dc

Browse files
Improve drag UI
1 parent 83ee510 commit d44b0dc

File tree

6 files changed

+64
-39
lines changed

6 files changed

+64
-39
lines changed

client/src/components/mindmap.rs

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use crate::components::DraggedNode;
21
use crate::components::LocationIndicator;
32
use crate::components::MiniMap;
43
use crate::components::Node;
@@ -29,13 +28,18 @@ pub fn Mindmap() -> Element {
2928
if let Some(parent_id) = node.parent_id {
3029
NodeLink { id: node.id, parent_id, store: store.clone() }
3130
}
31+
3232
Node { id: node.id, store: store.clone() }
3333
},
3434
));
3535
});
3636
nodes.sort_by_key(|(id, _)| {
3737
let root_id = graph.get_root(*id);
38-
(dragging_id != Some(root_id), root_id)
38+
(
39+
dragging_id == Some(*id),
40+
dragging_id != Some(root_id),
41+
root_id,
42+
)
3943
});
4044
rsx! {
4145
div {
@@ -140,7 +144,7 @@ pub fn Mindmap() -> Element {
140144
if let Some(dragging_node) = dragging_node {
141145
let target = graph.on_other(dragging_node.id, svg_coords);
142146
pane.update_drag(svg_coords, target);
143-
graph.move_node(dragging_node.id, dragging_node.coords);
147+
graph.move_root_node(dragging_node.id, dragging_node.coords);
144148
}
145149
if *pane.panning.read() {
146150
let (start_x, start_y) = *pane.pan_offset.read();
@@ -190,22 +194,14 @@ pub fn Mindmap() -> Element {
190194

191195
if let Some(dragging_node) = *pane.dragging_node.read() {
192196
if dragging_node.has_moved {
193-
if let Some(node) = graph.get_node(dragging_node.id) {
194-
if node.parent_id.is_some() {
195-
DraggedNode {
196-
id: node.id,
197-
coords: dragging_node.coords,
198-
}
199-
}
200-
if let Some((_, location)) = dragging_node.target {
201-
g {
202-
transform: format!(
203-
"translate({},{})",
204-
dragging_node.coords.0 + 8.0,
205-
dragging_node.coords.1 - 8.0,
206-
),
207-
LocationIndicator { location }
208-
}
197+
if let Some((_, location)) = dragging_node.target {
198+
g {
199+
transform: format!(
200+
"translate({},{})",
201+
dragging_node.coords.0 + 8.0,
202+
dragging_node.coords.1 - 8.0,
203+
),
204+
LocationIndicator { location }
209205
}
210206
}
211207
}

client/src/components/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
//! component and an Echo component for fullstack apps to be used in our app.
44
55
mod node;
6-
pub use node::DraggedNode;
76
pub use node::Node;
87

98
mod node_link;

client/src/components/node.rs

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,6 @@ use uuid::Uuid;
66

77
const SELECTED_PADDING: f32 = 5.0;
88

9-
#[component]
10-
pub fn DraggedNode(id: Uuid, coords: (f32, f32)) -> Element {
11-
rsx! {
12-
g { transform: format!("translate({}, {})", coords.0, coords.1),
13-
r#use { href: format!("#{id}") }
14-
}
15-
}
16-
}
17-
189
#[component]
1910
fn RawChildNode(width: f32, height: f32, color: String) -> Element {
2011
rsx! {
@@ -153,6 +144,7 @@ pub fn Node(id: Uuid, store: Store) -> Element {
153144
let height = node.height();
154145
let font_size = node.font_size();
155146
let is_editing = *store.pane.editing.read() == Some(id);
147+
let (node_x, node_y) = store.pane.coords(&node);
156148
let mut input_element: Signal<Option<Rc<MountedData>>> = use_signal(|| None);
157149
use_effect(move || {
158150
if let Some(input) = &*input_element.read() {
@@ -161,7 +153,7 @@ pub fn Node(id: Uuid, store: Store) -> Element {
161153
});
162154

163155
rsx! {
164-
g { transform: format!("translate({},{})", node.x, node.y),
156+
g { transform: format!("translate({},{})", node_x, node_y),
165157
g {
166158
onmousedown: move |evt| {
167159
if is_editing {

client/src/components/node_link.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,26 +36,31 @@ pub fn RedCross(x: f32, y: f32) -> Element {
3636
#[component]
3737
pub fn NodeLink(id: Uuid, parent_id: Uuid, store: Store) -> Element {
3838
let graph = store.graph;
39+
3940
let Some(child) = graph.get_node(id) else {
4041
return rsx! {};
4142
};
4243

44+
let (child_x, child_y) = store.pane.coords(&child);
45+
4346
let Some(parent) = graph.get_node(parent_id) else {
44-
let x = child.x - child.width() / 2.0;
45-
let y = child.y;
47+
let x = child_x - child.width() / 2.0;
48+
let y = child_y;
4649
return rsx! {
4750
RedCross { x, y }
4851
};
4952
};
5053

54+
let (parent_x, parent_y) = store.pane.coords(&parent);
55+
5156
let is_right = child.x > parent.x;
5257
let side_mult = if is_right { 1.0 } else { -1.0 };
5358

5459
// Parent/child edges
55-
let start_x = parent.x + side_mult * parent.width() / 2.0;
56-
let start_y = parent.y;
57-
let end_x = child.x - side_mult * child.width() / 2.0;
58-
let end_y = child.y;
60+
let start_x = parent_x + side_mult * parent.width() / 2.0;
61+
let start_y = parent_y;
62+
let end_x = child_x - side_mult * child.width() / 2.0;
63+
let end_y = child_y;
5964

6065
// Horizontal offsets
6166
let start_offset = 20.0 * side_mult;

client/src/data/graph.rs

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -225,16 +225,22 @@ impl Graph {
225225
}
226226
}
227227

228+
pub fn move_root_node(&mut self, id: Uuid, coords: (f32, f32)) {
229+
if let Some(node) = self.get_node(id) {
230+
if node.parent_id.is_none() {
231+
self.doc.write().update_node_coords(id, coords);
232+
}
233+
}
234+
}
235+
228236
pub fn move_node_into(
229237
&mut self,
230238
id: Uuid,
231239
coords: (f32, f32),
232240
target: Option<(Uuid, RelativeLocation)>,
233241
) {
234242
if let Some((target_id, location)) = target {
235-
if self.get_root(target_id) == id {
236-
self.move_node(id, coords);
237-
} else {
243+
if !self.ancestors(target_id).contains(&id) {
238244
let side = match location {
239245
RelativeLocation::Left => Side::Left,
240246
RelativeLocation::Right => Side::Right,
@@ -265,6 +271,22 @@ impl Graph {
265271
.unwrap_or(id)
266272
}
267273

274+
pub fn ancestors(&self, id: Uuid) -> Vec<Uuid> {
275+
let mut result = match self.get_node(id) {
276+
Some(node) => {
277+
if let Some(parent_id) = node.parent_id {
278+
self.ancestors(parent_id)
279+
} else {
280+
Vec::new()
281+
}
282+
}
283+
None => Vec::new(),
284+
};
285+
286+
result.push(id);
287+
result
288+
}
289+
268290
pub fn on(&self, coords: (f32, f32)) -> Option<(Uuid, RelativeLocation)> {
269291
let mut target = None;
270292
for node in self.nodes.read().values() {

client/src/data/pane.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::f32;
2+
13
use dioxus::prelude::*;
24
use uuid::Uuid;
35

@@ -55,6 +57,15 @@ impl Pane {
5557
(x - t.pan_x, y - t.pan_y)
5658
}
5759

60+
pub fn coords(&self, node: &RenderedNode) -> (f32, f32) {
61+
if let Some(dragging_node) = *self.dragging_node.read() {
62+
if dragging_node.id == node.id {
63+
return dragging_node.coords;
64+
}
65+
}
66+
(node.x, node.y)
67+
}
68+
5869
pub fn start_drag(&mut self, node: &RenderedNode, (x, y): (f32, f32)) {
5970
let ox = x - node.x;
6071
let oy = y - node.y;

0 commit comments

Comments
 (0)