Canvas · Graphs and boards: node graph, flow chart, mind map, whiteboard
NodeGraph joins Nodes by wires between typed Ports: a title drags a node, a drag out of an output lands on an input of the same kind, an input takes one wire, and a press on a wired input lifts its wire. Links join shapes on the plane and follow them, straight or at right angles, with an arrow and words; the Connector tool draws them and the Note tool drops a sticky note. A double press with Select writes on a shape. FlowChart draws Steps as ellipses, boxes and diamonds with their words. MindMap lays topics out from a root, half to each side, and asks the owner to add, remove and rename by key. Whiteboard keeps its own tool, view and selection over a board it hands back after each change. Painting moves to canvas::paint; a press on the tool layer goes through canvas::press, and the layer focuses itself and asks to delete. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
5d58ee4577
commit
f3822a8d98
28 files changed
+3068
-240
No files matched your search
+25
-2
@@ -3,7 +3,7 @@ use std::rc::Rc;
|
||||
use gpui::{App, Bounds, Entity, Pixels, SharedString, Window};
|
||||
|
||||
use super::{
|
||||
edit::{Handle, drawn, inside, resized, snapped},
|
||||
edit::{Handle, drawn, hit, inside, resized, snapped},
|
||||
shape::{Shape, ShapeKind},
|
||||
view::{Frame, Viewport},
|
||||
};
|
||||
@@ -12,6 +12,8 @@ pub(super) type OnKeys = Rc<dyn Fn(&[SharedString], &mut Window, &mut App)>;
|
||||
pub(super) type OnDraw = Rc<dyn Fn(ShapeKind, Frame, &mut Window, &mut App)>;
|
||||
pub(super) type OnMove = Rc<dyn Fn(&[SharedString], (f32, f32), &mut Window, &mut App)>;
|
||||
pub(super) type OnResize = Rc<dyn Fn(&SharedString, Frame, &mut Window, &mut App)>;
|
||||
/// A handler for two keys, or a key and its words.
|
||||
pub(crate) type OnPair = Rc<dyn Fn(&SharedString, &SharedString, &mut Window, &mut App)>;
|
||||
|
||||
/// A brush's width in canvas units and its hue among the chart colors.
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
@@ -47,15 +49,20 @@ pub(super) enum Gesture {
|
||||
Stroke {
|
||||
points: Vec<(f32, f32)>,
|
||||
},
|
||||
Linking {
|
||||
from: SharedString,
|
||||
to: (f32, f32),
|
||||
},
|
||||
}
|
||||
|
||||
/// The layer's own state: the gesture under way, whether Shift is held, the box it covers, and the pen's points so far.
|
||||
/// The layer's own state: the gesture under way, whether Shift is held, the box it covers, the pen's points so far, and the shape being written on.
|
||||
#[derive(Default)]
|
||||
pub(super) struct Hand {
|
||||
pub(super) gesture: Gesture,
|
||||
pub(super) square: bool,
|
||||
pub(super) bounds: Bounds<Pixels>,
|
||||
pub(super) pen: Vec<(f32, f32)>,
|
||||
pub(super) writing: Option<SharedString>,
|
||||
}
|
||||
|
||||
/// Shapes a small nudge still counts as a click by, in view pixels.
|
||||
@@ -109,6 +116,8 @@ pub(super) struct Handlers {
|
||||
pub(super) on_draw: Option<OnDraw>,
|
||||
pub(super) on_move: Option<OnMove>,
|
||||
pub(super) on_resize: Option<OnResize>,
|
||||
pub(super) on_link: Option<OnPair>,
|
||||
pub(super) on_text: Option<OnPair>,
|
||||
}
|
||||
|
||||
/// What a gesture ends against: the shapes, the selection, the frames to snap to, and the view.
|
||||
@@ -181,6 +190,20 @@ pub(super) fn commit(
|
||||
on_draw(kind, frame, window, cx);
|
||||
}
|
||||
}
|
||||
Gesture::Linking { from, to } => {
|
||||
let Some(ix) = hit(&scene.shapes, to, REACH / scene.view.zoom) else {
|
||||
log::info!("tool layer: the link from {from} lands on nothing");
|
||||
return;
|
||||
};
|
||||
let target = &scene.shapes[ix].key;
|
||||
if *target == from {
|
||||
return;
|
||||
}
|
||||
log::info!("tool layer: link {from} to {target}");
|
||||
if let Some(on_link) = &handlers.on_link {
|
||||
on_link(&from, target, window, cx);
|
||||
}
|
||||
}
|
||||
Gesture::Stroke { points } if points.len() > 1 => {
|
||||
let (kind, frame) = path(&points, brush.size);
|
||||
log::info!("tool layer: a stroke of {} points", points.len());
|
||||
|
||||
Reference in new issue
Block a user