mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-01 06:58:11 +08:00
Migrate the Select tool to the document graph (#1433)
* function for accessing document metadata * Better select tool * Fix render * Fix transforms * Fix loading saved documents * Populate graph UI when loading autosave * Multiple transform nodes * Fix deep select * Graph tooltips * Fix flip axis icon * Show disabled widgets * Stop select tool from selecting artboards * Disable (not hide) the pivot widget; remove Deep/Shallow select for now * Code review changes * Fix pivot position with select tool * Fix incorrectly selected layers when shift clicking --------- Co-authored-by: Dennis Kobert <dennis@kobert.dev> Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
committed by
Keavon Chambers
co-authored by
Dennis Kobert
Keavon Chambers
parent
e1cdb2242d
commit
5827e989dc
@@ -103,14 +103,14 @@ struct ArtboardToolData {
|
||||
|
||||
impl ArtboardToolData {
|
||||
fn refresh_overlays(&mut self, document: &DocumentMessageHandler, responses: &mut VecDeque<Message>) {
|
||||
let current_artboard = self.selected_artboard.and_then(|layer| document.document_legacy.metadata.bounding_box_document(layer));
|
||||
let current_artboard = self.selected_artboard.and_then(|layer| document.metadata().bounding_box_document(layer));
|
||||
match (current_artboard, self.bounding_box_overlays.take()) {
|
||||
(None, Some(bounding_box_overlays)) => bounding_box_overlays.delete(responses),
|
||||
(Some(bounds), paths) => {
|
||||
let mut bounding_box_overlays = paths.unwrap_or_else(|| BoundingBoxOverlays::new(responses));
|
||||
|
||||
bounding_box_overlays.bounds = bounds;
|
||||
bounding_box_overlays.transform = document.document_legacy.metadata.document_to_viewport;
|
||||
bounding_box_overlays.transform = document.metadata().document_to_viewport;
|
||||
|
||||
bounding_box_overlays.transform(responses);
|
||||
|
||||
@@ -265,7 +265,7 @@ impl Fsm for ArtboardToolFsmState {
|
||||
let mouse_position = input.mouse.position;
|
||||
let snapped_mouse_position = tool_data.snap_manager.snap_position(responses, document, mouse_position);
|
||||
|
||||
let root_transform = document.document_legacy.metadata.document_to_viewport.inverse();
|
||||
let root_transform = document.metadata().document_to_viewport.inverse();
|
||||
|
||||
let mut start = tool_data.drag_start;
|
||||
let mut size = snapped_mouse_position - start;
|
||||
|
||||
@@ -341,7 +341,7 @@ impl Fsm for BrushToolFsmState {
|
||||
document, global_tool_data, input, ..
|
||||
} = tool_action_data;
|
||||
|
||||
let document_position = document.document_legacy.metadata.document_to_viewport.inverse().transform_point2(input.mouse.position);
|
||||
let document_position = document.metadata().document_to_viewport.inverse().transform_point2(input.mouse.position);
|
||||
let layer_position = tool_data.transform.inverse().transform_point2(document_position);
|
||||
|
||||
let ToolMessage::Brush(event) = event else {
|
||||
|
||||
@@ -68,7 +68,7 @@ impl Fsm for FillToolFsmState {
|
||||
let ToolMessage::Fill(event) = event else {
|
||||
return self;
|
||||
};
|
||||
let Some(layer_identifier) = document.document_legacy.metadata.click(input.mouse.position) else {
|
||||
let Some(layer_identifier) = document.metadata().click(input.mouse.position, &document.document_legacy.document_network) else {
|
||||
return self;
|
||||
};
|
||||
let layer = layer_identifier.to_path();
|
||||
|
||||
@@ -110,7 +110,7 @@ impl Fsm for NodeGraphToolFsmState {
|
||||
match (self, event) {
|
||||
(_, FrameToolMessage::DocumentIsDirty | FrameToolMessage::SelectionChanged) => {
|
||||
tool_data.path_outlines.clear_selected(responses);
|
||||
tool_data.path_outlines.update_selected(document.selected_visible_layers(), document, responses, render_data);
|
||||
//tool_data.path_outlines.update_selected(document.selected_visible_layers(), document, responses, render_data);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
@@ -191,7 +191,7 @@ impl Fsm for FreehandToolFsmState {
|
||||
document, global_tool_data, input, ..
|
||||
} = tool_action_data;
|
||||
|
||||
let transform = document.document_legacy.metadata.document_to_viewport;
|
||||
let transform = document.metadata().document_to_viewport;
|
||||
|
||||
let ToolMessage::Freehand(event) = event else {
|
||||
return self;
|
||||
|
||||
@@ -116,10 +116,10 @@ enum GradientToolFsmState {
|
||||
|
||||
/// Computes the transform from gradient space to viewport space (where gradient space is 0..1)
|
||||
fn gradient_space_transform(layer: LayerNodeIdentifier, document: &DocumentMessageHandler) -> DAffine2 {
|
||||
let bounds = document.document_legacy.metadata.bounding_box_with_transform(layer, DAffine2::IDENTITY).unwrap();
|
||||
let bounds = document.metadata().nonzero_bounding_box(layer);
|
||||
let bound_transform = DAffine2::from_scale_angle_translation(bounds[1] - bounds[0], 0., bounds[0]);
|
||||
|
||||
let multiplied = document.document_legacy.metadata.transform_from_viewport(layer);
|
||||
let multiplied = document.metadata().transform_to_viewport(layer);
|
||||
|
||||
multiplied * bound_transform
|
||||
}
|
||||
@@ -252,7 +252,7 @@ impl SelectedGradient {
|
||||
};
|
||||
|
||||
// Clear the gradient if layer deleted
|
||||
if !inner_gradient.layer.exists(&document.document_legacy.metadata) {
|
||||
if !inner_gradient.layer.exists(&document.metadata()) {
|
||||
responses.add(ToolMessage::RefreshToolOptions);
|
||||
*gradient = None;
|
||||
return;
|
||||
@@ -391,7 +391,7 @@ impl Fsm for GradientToolFsmState {
|
||||
SelectedGradient::update(&mut tool_data.selected_gradient, document, responses);
|
||||
}
|
||||
|
||||
for layer in document.document_legacy.metadata.selected_visible_layers() {
|
||||
for layer in document.metadata().selected_visible_layers() {
|
||||
if let Some(gradient) = get_gradient(layer, &document.document_legacy) {
|
||||
let dragging = tool_data
|
||||
.selected_gradient
|
||||
@@ -526,7 +526,7 @@ impl Fsm for GradientToolFsmState {
|
||||
document.backup_nonmut(responses);
|
||||
GradientToolFsmState::Drawing
|
||||
} else {
|
||||
let selected_layer = document.document_legacy.metadata.click(input.mouse.position);
|
||||
let selected_layer = document.metadata().click(input.mouse.position, &document.document_legacy.document_network);
|
||||
|
||||
// Apply the gradient to the selected layer
|
||||
if let Some(layer) = selected_layer {
|
||||
@@ -540,7 +540,7 @@ impl Fsm for GradientToolFsmState {
|
||||
// return self;
|
||||
// }
|
||||
|
||||
if !document.document_legacy.metadata.selected_layers_contains(layer) {
|
||||
if !document.metadata().selected_layers_contains(layer) {
|
||||
let replacement_selected_layers = vec![layer.to_path()];
|
||||
|
||||
responses.add(DocumentMessage::SetSelectedLayers { replacement_selected_layers });
|
||||
|
||||
@@ -118,7 +118,7 @@ impl Fsm for ImaginateToolFsmState {
|
||||
match (self, event) {
|
||||
(_, ImaginateToolMessage::DocumentIsDirty | ImaginateToolMessage::SelectionChanged) => {
|
||||
tool_data.path_outlines.clear_selected(responses);
|
||||
tool_data.path_outlines.update_selected(document.selected_visible_layers(), document, responses, render_data);
|
||||
//tool_data.path_outlines.update_selected(document.selected_visible_layers(), document, responses, render_data);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
@@ -181,7 +181,7 @@ impl Fsm for LineToolFsmState {
|
||||
tool_data.snap_manager.add_all_document_handles(document, input, &[], &[], &[]);
|
||||
|
||||
let viewport_start = tool_data.snap_manager.snap_position(responses, document, input.mouse.position);
|
||||
tool_data.drag_start = document.document_legacy.metadata.document_to_viewport.inverse().transform_point2(viewport_start);
|
||||
tool_data.drag_start = document.metadata().document_to_viewport.inverse().transform_point2(viewport_start);
|
||||
|
||||
let subpath = bezier_rs::Subpath::new_line(DVec2::ZERO, DVec2::X);
|
||||
|
||||
@@ -202,7 +202,7 @@ impl Fsm for LineToolFsmState {
|
||||
tool_data.drag_current = tool_data.snap_manager.snap_position(responses, document, input.mouse.position);
|
||||
|
||||
let keyboard = &input.keyboard;
|
||||
let transform = document.document_legacy.metadata.document_to_viewport;
|
||||
let transform = document.metadata().document_to_viewport;
|
||||
responses.add(generate_transform(tool_data, transform, keyboard.key(lock_angle), keyboard.key(snap_angle), keyboard.key(center)));
|
||||
|
||||
LineToolFsmState::Drawing
|
||||
|
||||
@@ -210,7 +210,7 @@ struct PathToolData {
|
||||
impl PathToolData {
|
||||
fn refresh_overlays(&mut self, document: &DocumentMessageHandler, shape_editor: &mut ShapeState, shape_overlay: &mut OverlayRenderer, responses: &mut VecDeque<Message>) {
|
||||
// Set the previously selected layers to invisible
|
||||
for layer in document.document_legacy.metadata.all_layers() {
|
||||
for layer in document.metadata().all_layers() {
|
||||
shape_overlay.layer_overlay_visibility(&document.document_legacy, layer, false, responses);
|
||||
}
|
||||
|
||||
@@ -242,15 +242,11 @@ impl PathToolData {
|
||||
PathToolFsmState::Dragging
|
||||
}
|
||||
// We didn't find a point nearby, so consider selecting the nearest shape instead
|
||||
else if let Some(layer) = document.document_legacy.metadata.click(input.mouse.position) {
|
||||
// TODO: Actual selection
|
||||
let layer_list = vec![layer.to_path()];
|
||||
else if let Some(layer) = document.metadata().click(input.mouse.position, &document.document_legacy.document_network) {
|
||||
if shift {
|
||||
responses.add(DocumentMessage::AddSelectedLayers { additional_layers: layer_list });
|
||||
responses.add(NodeGraphMessage::AddSelectNodes { nodes: vec![layer.to_node()] });
|
||||
} else {
|
||||
responses.add(DocumentMessage::SetSelectedLayers {
|
||||
replacement_selected_layers: layer_list,
|
||||
});
|
||||
responses.add(NodeGraphMessage::SetSelectNodes { nodes: vec![layer.to_node()] });
|
||||
}
|
||||
self.drag_start_pos = input.mouse.position;
|
||||
self.previous_mouse_position = input.mouse.position;
|
||||
@@ -342,7 +338,7 @@ impl Fsm for PathToolFsmState {
|
||||
match (self, event) {
|
||||
(_, PathToolMessage::SelectionChanged) => {
|
||||
// Set the newly targeted layers to visible
|
||||
let target_layers = document.document_legacy.metadata.selected_layers().collect();
|
||||
let target_layers = document.metadata().selected_layers().collect();
|
||||
shape_editor.set_selected_layers(target_layers);
|
||||
|
||||
tool_data.refresh_overlays(document, shape_editor, shape_overlay, responses);
|
||||
@@ -354,7 +350,7 @@ impl Fsm for PathToolFsmState {
|
||||
(_, PathToolMessage::DocumentIsDirty) => {
|
||||
// When the document has moved / needs to be redraw, re-render the overlays
|
||||
// TODO the overlay system should probably receive this message instead of the tool
|
||||
for layer in document.document_legacy.metadata.selected_layers() {
|
||||
for layer in document.metadata().selected_layers() {
|
||||
shape_overlay.render_subpath_overlays(&shape_editor.selected_shape_state, &document.document_legacy, layer, responses);
|
||||
}
|
||||
|
||||
@@ -386,7 +382,7 @@ impl Fsm for PathToolFsmState {
|
||||
let shift_pressed = input.keyboard.get(add_to_selection as usize);
|
||||
|
||||
if tool_data.drag_start_pos == tool_data.previous_mouse_position {
|
||||
responses.add(DocumentMessage::DeselectAllLayers);
|
||||
responses.add(NodeGraphMessage::SetSelectNodes { nodes: vec![] });
|
||||
} else {
|
||||
shape_editor.select_all_in_quad(&document.document_legacy, [tool_data.drag_start_pos, tool_data.previous_mouse_position], !shift_pressed);
|
||||
tool_data.refresh_overlays(document, shape_editor, shape_overlay, responses);
|
||||
@@ -401,7 +397,7 @@ impl Fsm for PathToolFsmState {
|
||||
let shift_pressed = input.keyboard.get(shift_mirror_distance as usize);
|
||||
|
||||
if tool_data.drag_start_pos == tool_data.previous_mouse_position {
|
||||
responses.add(DocumentMessage::DeselectAllLayers);
|
||||
responses.add(NodeGraphMessage::SetSelectNodes { nodes: vec![] });
|
||||
} else {
|
||||
shape_editor.select_all_in_quad(&document.document_legacy, [tool_data.drag_start_pos, tool_data.previous_mouse_position], !shift_pressed);
|
||||
tool_data.refresh_overlays(document, shape_editor, shape_overlay, responses);
|
||||
|
||||
@@ -247,7 +247,7 @@ impl PenToolData {
|
||||
let layer_path = document.get_path_for_new_layer();
|
||||
|
||||
// Get the position and set properties
|
||||
let transform = document.document_legacy.metadata.document_to_viewport * document.document_legacy.multiply_transforms(&layer_path[..layer_path.len() - 1]).unwrap_or_default();
|
||||
let transform = document.metadata().document_to_viewport * document.document_legacy.multiply_transforms(&layer_path[..layer_path.len() - 1]).unwrap_or_default();
|
||||
let snapped_position = self.snap_manager.snap_position(responses, document, input.mouse.position);
|
||||
let start_position = transform.inverse().transform_point2(snapped_position);
|
||||
self.weight = line_weight;
|
||||
@@ -566,7 +566,7 @@ impl Fsm for PenToolFsmState {
|
||||
transform = DAffine2::IDENTITY;
|
||||
}
|
||||
|
||||
transform = document.document_legacy.metadata.document_to_viewport * transform;
|
||||
transform = document.metadata().document_to_viewport * transform;
|
||||
|
||||
let ToolMessage::Pen(event) = event else {
|
||||
return self;
|
||||
@@ -579,19 +579,19 @@ impl Fsm for PenToolFsmState {
|
||||
(_, PenToolMessage::DocumentIsDirty) => {
|
||||
// When the document has moved / needs to be redraw, re-render the overlays
|
||||
// TODO the overlay system should probably receive this message instead of the tool
|
||||
for layer in document.document_legacy.metadata.selected_layers() {
|
||||
for layer in document.metadata().selected_layers() {
|
||||
shape_overlay.render_subpath_overlays(&shape_editor.selected_shape_state, &document.document_legacy, layer, responses);
|
||||
}
|
||||
self
|
||||
}
|
||||
(_, PenToolMessage::SelectionChanged) => {
|
||||
// Set the previously selected layers to invisible
|
||||
for layer in document.document_legacy.metadata.all_layers() {
|
||||
for layer in document.metadata().all_layers() {
|
||||
shape_overlay.layer_overlay_visibility(&document.document_legacy, layer, false, responses);
|
||||
}
|
||||
|
||||
// Redraw the overlays of the newly selected layers
|
||||
for layer in document.document_legacy.metadata.selected_layers() {
|
||||
for layer in document.metadata().selected_layers() {
|
||||
shape_overlay.render_subpath_overlays(&shape_editor.selected_shape_state, &document.document_legacy, layer, responses);
|
||||
}
|
||||
self
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -202,7 +202,7 @@ impl Fsm for SplineToolFsmState {
|
||||
..
|
||||
} = tool_action_data;
|
||||
|
||||
let transform = document.document_legacy.metadata.document_to_viewport;
|
||||
let transform = document.metadata().document_to_viewport;
|
||||
|
||||
let ToolMessage::Spline(event) = event else {
|
||||
return self;
|
||||
|
||||
Reference in New Issue
Block a user