mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-25 22:18:11 +08:00
New overlay system that reimplements how overlays are drawn (#418)
* New overlay system that reimplements how overlays are drawn * Fix overlay message declaration * Fix small mistake * WIP (broken) changes to plumb the overlay document * Fix confusion over messaging system architecture * Removed log * Overlay system working * (broken) WIP overlay association * Finish the overlay system (except test failure) * Change back IDs in test * Fixed test, but stilled fails due to revealed real problem with layer reordering selection * Disable broken test that has a bug in issue #444 Co-authored-by: Dennis <dennis@kobert.dev> Co-authored-by: otdavies <oliver@psyfer.io>
This commit is contained in:
co-authored by
Dennis
otdavies
parent
3de426b7cc
commit
3dea989a00
@@ -29,11 +29,13 @@ pub struct Select {
|
||||
#[impl_message(Message, ToolMessage, Select)]
|
||||
#[derive(PartialEq, Clone, Debug, Hash, Serialize, Deserialize)]
|
||||
pub enum SelectMessage {
|
||||
// Standard messages
|
||||
Abort,
|
||||
DocumentIsDirty,
|
||||
|
||||
DragStart { add_to_selection: Key },
|
||||
DragStop,
|
||||
MouseMove { snap_angle: Key },
|
||||
Abort,
|
||||
UpdateSelectionBoundingBox,
|
||||
|
||||
Align(AlignAxis, AlignAggregate),
|
||||
FlipHorizontal,
|
||||
@@ -83,8 +85,8 @@ struct SelectToolData {
|
||||
drag_start: ViewportPosition,
|
||||
drag_current: ViewportPosition,
|
||||
layers_dragging: Vec<Vec<LayerId>>, // Paths and offsets
|
||||
drag_box_id: Option<Vec<LayerId>>,
|
||||
bounding_box_path: Option<Vec<LayerId>>,
|
||||
drag_box_overlay_layer: Option<Vec<LayerId>>,
|
||||
bounding_box_overlay_layer: Option<Vec<LayerId>>,
|
||||
snap_handler: SnapHandler,
|
||||
}
|
||||
|
||||
@@ -106,14 +108,13 @@ impl SelectToolData {
|
||||
|
||||
fn add_bounding_box(responses: &mut Vec<Message>) -> Vec<LayerId> {
|
||||
let path = vec![generate_uuid()];
|
||||
responses.push(
|
||||
Operation::AddOverlayRect {
|
||||
path: path.clone(),
|
||||
transform: DAffine2::ZERO.to_cols_array(),
|
||||
style: style::PathStyle::new(Some(Stroke::new(COLOR_ACCENT, 1.0)), Some(Fill::none())),
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
|
||||
let operation = Operation::AddOverlayRect {
|
||||
path: path.clone(),
|
||||
transform: DAffine2::ZERO.to_cols_array(),
|
||||
style: style::PathStyle::new(Some(Stroke::new(COLOR_ACCENT, 1.0)), Some(Fill::none())),
|
||||
};
|
||||
responses.push(DocumentMessage::Overlay(operation.into()).into());
|
||||
|
||||
path
|
||||
}
|
||||
@@ -139,21 +140,20 @@ impl Fsm for SelectToolFsmState {
|
||||
|
||||
if let ToolMessage::Select(event) = event {
|
||||
match (self, event) {
|
||||
(_, UpdateSelectionBoundingBox) => {
|
||||
(_, DocumentIsDirty) => {
|
||||
let mut buffer = Vec::new();
|
||||
let response = match (document.selected_layers_bounding_box(), data.bounding_box_path.take()) {
|
||||
(None, Some(path)) => Operation::DeleteLayer { path }.into(),
|
||||
let response = match (document.selected_visible_layers_bounding_box(), data.bounding_box_overlay_layer.take()) {
|
||||
(None, Some(path)) => DocumentMessage::Overlay(Operation::DeleteLayer { path }.into()).into(),
|
||||
(Some([pos1, pos2]), path) => {
|
||||
let path = path.unwrap_or_else(|| add_bounding_box(&mut buffer));
|
||||
|
||||
data.bounding_box_path = Some(path.clone());
|
||||
data.bounding_box_overlay_layer = Some(path.clone());
|
||||
|
||||
let half_pixel_offset = DVec2::splat(0.5);
|
||||
let pos1 = pos1 + half_pixel_offset;
|
||||
let pos2 = pos2 - half_pixel_offset;
|
||||
let transform = transform_from_box(pos1, pos2);
|
||||
|
||||
Operation::SetLayerTransformInViewport { path, transform }.into()
|
||||
DocumentMessage::Overlay(Operation::SetLayerTransformInViewport { path, transform }.into()).into()
|
||||
}
|
||||
(_, _) => Message::NoOp,
|
||||
};
|
||||
@@ -165,7 +165,7 @@ impl Fsm for SelectToolFsmState {
|
||||
data.drag_start = input.mouse.position;
|
||||
data.drag_current = input.mouse.position;
|
||||
let mut buffer = Vec::new();
|
||||
let mut selected: Vec<_> = document.selected_layers().map(|path| path.to_vec()).collect();
|
||||
let mut selected: Vec<_> = document.selected_visible_layers().map(|path| path.to_vec()).collect();
|
||||
let quad = data.selection_quad();
|
||||
let mut intersection = document.graphene_document.intersects_quad_root(quad);
|
||||
// If the user clicks on a layer that is in their current selection, go into the dragging mode.
|
||||
@@ -188,13 +188,14 @@ impl Fsm for SelectToolFsmState {
|
||||
data.layers_dragging.append(&mut selected);
|
||||
Dragging
|
||||
} else {
|
||||
data.drag_box_id = Some(add_bounding_box(&mut buffer));
|
||||
data.drag_box_overlay_layer = Some(add_bounding_box(&mut buffer));
|
||||
DrawingBox
|
||||
}
|
||||
};
|
||||
buffer.into_iter().rev().for_each(|message| responses.push_front(message));
|
||||
|
||||
let ignore_layers = if let Some(bounding_box) = &data.bounding_box_path {
|
||||
// TODO: Probably delete this now that the overlay system has moved to a separate Graphene document? (@0hypercube)
|
||||
let ignore_layers = if let Some(bounding_box) = &data.bounding_box_overlay_layer {
|
||||
vec![bounding_box.clone()]
|
||||
} else {
|
||||
Vec::new()
|
||||
@@ -203,7 +204,8 @@ impl Fsm for SelectToolFsmState {
|
||||
state
|
||||
}
|
||||
(Dragging, MouseMove { snap_angle }) => {
|
||||
responses.push_front(SelectMessage::UpdateSelectionBoundingBox.into());
|
||||
// TODO: This is a cheat. Break out the relevant functionality from the handler above and call it from there and here.
|
||||
responses.push_front(SelectMessage::DocumentIsDirty.into());
|
||||
|
||||
let mouse_position = if input.keyboard.get(snap_angle as usize) {
|
||||
let mouse_position = input.mouse.position - data.drag_start;
|
||||
@@ -237,10 +239,13 @@ impl Fsm for SelectToolFsmState {
|
||||
let size = data.drag_current - start + half_pixel_offset;
|
||||
|
||||
responses.push_front(
|
||||
Operation::SetLayerTransformInViewport {
|
||||
path: data.drag_box_id.clone().unwrap(),
|
||||
transform: DAffine2::from_scale_angle_translation(size, 0., start).to_cols_array(),
|
||||
}
|
||||
DocumentMessage::Overlay(
|
||||
Operation::SetLayerTransformInViewport {
|
||||
path: data.drag_box_overlay_layer.clone().unwrap(),
|
||||
transform: DAffine2::from_scale_angle_translation(size, 0., start).to_cols_array(),
|
||||
}
|
||||
.into(),
|
||||
)
|
||||
.into(),
|
||||
);
|
||||
DrawingBox
|
||||
@@ -258,17 +263,20 @@ impl Fsm for SelectToolFsmState {
|
||||
let quad = data.selection_quad();
|
||||
responses.push_front(DocumentMessage::AddSelectedLayers(document.graphene_document.intersects_quad_root(quad)).into());
|
||||
responses.push_front(
|
||||
Operation::DeleteLayer {
|
||||
path: data.drag_box_id.take().unwrap(),
|
||||
}
|
||||
DocumentMessage::Overlay(
|
||||
Operation::DeleteLayer {
|
||||
path: data.drag_box_overlay_layer.take().unwrap(),
|
||||
}
|
||||
.into(),
|
||||
)
|
||||
.into(),
|
||||
);
|
||||
Ready
|
||||
}
|
||||
(_, Abort) => {
|
||||
let mut delete = |path: &mut Option<Vec<LayerId>>| path.take().map(|path| responses.push_front(Operation::DeleteLayer { path }.into()));
|
||||
delete(&mut data.drag_box_id);
|
||||
delete(&mut data.bounding_box_path);
|
||||
let mut delete = |path: &mut Option<Vec<LayerId>>| path.take().map(|path| responses.push_front(DocumentMessage::Overlay(Operation::DeleteLayer { path }.into()).into()));
|
||||
delete(&mut data.drag_box_overlay_layer);
|
||||
delete(&mut data.bounding_box_overlay_layer);
|
||||
Ready
|
||||
}
|
||||
(_, Align(axis, aggregate)) => {
|
||||
|
||||
Reference in New Issue
Block a user