mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-30 20:08:12 +08:00
Fix Shape tool arc gizmo snap visualization and pointer cursor icon when hovering or dragging (#2957)
* fixed cursor,arc bugs * Update cursor icon * send pointer-move only when required * make it compile * Code review * remove repeated modifier key --------- Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
co-authored by
Keavon Chambers
parent
3cc9dd79fb
commit
7e0a274bd1
@@ -335,7 +335,7 @@ pub struct ShapeToolData {
|
||||
current_shape: ShapeType,
|
||||
|
||||
// Gizmos
|
||||
gizmo_manger: GizmoManager,
|
||||
gizmo_manager: GizmoManager,
|
||||
}
|
||||
|
||||
impl ShapeToolData {
|
||||
@@ -351,6 +351,23 @@ impl ShapeToolData {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn transform_cage_mouse_icon(&mut self, input: &InputPreprocessorMessageHandler) -> MouseCursorIcon {
|
||||
let dragging_bounds = self
|
||||
.bounding_box_manager
|
||||
.as_mut()
|
||||
.and_then(|bounding_box| bounding_box.check_selected_edges(input.mouse.position))
|
||||
.is_some();
|
||||
|
||||
self.bounding_box_manager.as_ref().map_or(MouseCursorIcon::Crosshair, |bounds| {
|
||||
let cursor_icon = bounds.get_cursor(input, true, dragging_bounds, Some(self.skew_edge));
|
||||
if cursor_icon == MouseCursorIcon::Default { MouseCursorIcon::Crosshair } else { cursor_icon }
|
||||
})
|
||||
}
|
||||
|
||||
fn shape_tool_modifier_keys() -> [Key; 3] {
|
||||
[Key::Alt, Key::Shift, Key::Control]
|
||||
}
|
||||
}
|
||||
|
||||
impl Fsm for ShapeToolFsmState {
|
||||
@@ -388,30 +405,34 @@ impl Fsm for ShapeToolFsmState {
|
||||
.indicator_pos()
|
||||
.map(|pos| document.metadata().document_to_viewport.transform_point2(pos))
|
||||
.unwrap_or(input.mouse.position);
|
||||
let is_resizing_or_rotating = matches!(self, ShapeToolFsmState::ResizingBounds | ShapeToolFsmState::SkewingBounds { .. } | ShapeToolFsmState::RotatingBounds);
|
||||
|
||||
if matches!(self, Self::Ready(_)) && !input.keyboard.key(Key::Control) {
|
||||
tool_data.gizmo_manger.handle_actions(mouse_position, document, responses);
|
||||
tool_data.gizmo_manger.overlays(document, input, shape_editor, mouse_position, &mut overlay_context);
|
||||
tool_data.gizmo_manager.handle_actions(mouse_position, document, responses);
|
||||
tool_data.gizmo_manager.overlays(document, input, shape_editor, mouse_position, &mut overlay_context);
|
||||
}
|
||||
|
||||
if matches!(self, ShapeToolFsmState::ModifyingGizmo) && !input.keyboard.key(Key::Control) {
|
||||
tool_data.gizmo_manger.dragging_overlays(document, input, shape_editor, mouse_position, &mut overlay_context);
|
||||
tool_data.gizmo_manager.dragging_overlays(document, input, shape_editor, mouse_position, &mut overlay_context);
|
||||
let cursor = tool_data.gizmo_manager.mouse_cursor_icon().unwrap_or(MouseCursorIcon::Crosshair);
|
||||
tool_data.cursor = cursor;
|
||||
responses.add(FrontendMessage::UpdateMouseCursor { cursor });
|
||||
}
|
||||
|
||||
let modifying_transform_cage = matches!(self, ShapeToolFsmState::ResizingBounds | ShapeToolFsmState::RotatingBounds | ShapeToolFsmState::SkewingBounds { .. });
|
||||
let hovering_over_gizmo = tool_data.gizmo_manger.hovering_over_gizmo();
|
||||
let hovering_over_gizmo = tool_data.gizmo_manager.hovering_over_gizmo();
|
||||
|
||||
if !is_resizing_or_rotating && !matches!(self, ShapeToolFsmState::ModifyingGizmo) && !modifying_transform_cage && !hovering_over_gizmo {
|
||||
if !matches!(self, ShapeToolFsmState::ModifyingGizmo) && !modifying_transform_cage && !hovering_over_gizmo {
|
||||
tool_data.data.snap_manager.draw_overlays(SnapData::new(document, input), &mut overlay_context);
|
||||
}
|
||||
|
||||
if modifying_transform_cage && !matches!(self, ShapeToolFsmState::ModifyingGizmo) {
|
||||
transform_cage_overlays(document, tool_data, &mut overlay_context);
|
||||
responses.add(FrontendMessage::UpdateMouseCursor { cursor: tool_data.cursor });
|
||||
}
|
||||
|
||||
if input.keyboard.key(Key::Control) && matches!(self, ShapeToolFsmState::Ready(_)) {
|
||||
anchor_overlays(document, &mut overlay_context);
|
||||
responses.add(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Crosshair });
|
||||
} else if matches!(self, ShapeToolFsmState::Ready(_)) {
|
||||
Line::overlays(document, tool_data, &mut overlay_context);
|
||||
|
||||
@@ -433,7 +454,7 @@ impl Fsm for ShapeToolFsmState {
|
||||
let edges = bounds.check_selected_edges(input.mouse.position);
|
||||
let is_skewing = matches!(self, ShapeToolFsmState::SkewingBounds { .. });
|
||||
let is_near_square = edges.is_some_and(|hover_edge| bounds.over_extended_edge_midpoint(input.mouse.position, hover_edge));
|
||||
if is_skewing || (dragging_bounds && is_near_square && !is_resizing_or_rotating && !hovering_over_gizmo) {
|
||||
if is_skewing || (dragging_bounds && is_near_square && !hovering_over_gizmo) {
|
||||
bounds.render_skew_gizmos(&mut overlay_context, tool_data.skew_edge);
|
||||
}
|
||||
if !is_skewing && dragging_bounds && !hovering_over_gizmo {
|
||||
@@ -442,6 +463,11 @@ impl Fsm for ShapeToolFsmState {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let cursor = tool_data.gizmo_manager.mouse_cursor_icon().unwrap_or_else(|| tool_data.transform_cage_mouse_icon(input));
|
||||
|
||||
tool_data.cursor = cursor;
|
||||
responses.add(FrontendMessage::UpdateMouseCursor { cursor });
|
||||
}
|
||||
|
||||
if matches!(self, ShapeToolFsmState::Drawing(_) | ShapeToolFsmState::DraggingLineEndpoints) {
|
||||
@@ -562,8 +588,16 @@ impl Fsm for ShapeToolFsmState {
|
||||
|
||||
tool_data.line_data.drag_current = mouse_pos;
|
||||
|
||||
if tool_data.gizmo_manger.handle_click() {
|
||||
if tool_data.gizmo_manager.handle_click() && !input.keyboard.key(Key::Accel) {
|
||||
tool_data.data.drag_start = document.metadata().document_to_viewport.inverse().transform_point2(mouse_pos);
|
||||
responses.add(DocumentMessage::StartTransaction);
|
||||
|
||||
let cursor = tool_data.gizmo_manager.mouse_cursor_icon().unwrap_or(MouseCursorIcon::Crosshair);
|
||||
tool_data.cursor = cursor;
|
||||
responses.add(FrontendMessage::UpdateMouseCursor { cursor });
|
||||
// Send a PointerMove message to refresh the cursor icon
|
||||
responses.add(ShapeToolMessage::PointerMove(ShapeToolData::shape_tool_modifier_keys()));
|
||||
|
||||
return ShapeToolFsmState::ModifyingGizmo;
|
||||
}
|
||||
|
||||
@@ -584,17 +618,31 @@ impl Fsm for ShapeToolFsmState {
|
||||
let (resize, rotate, skew) = transforming_transform_cage(document, &mut tool_data.bounding_box_manager, input, responses, &mut tool_data.layers_dragging, None);
|
||||
|
||||
if !input.keyboard.key(Key::Control) {
|
||||
// Helper function to update cursor and send pointer move message
|
||||
let update_cursor_and_pointer = |tool_data: &mut ShapeToolData, responses: &mut VecDeque<Message>| {
|
||||
let cursor = tool_data.transform_cage_mouse_icon(input);
|
||||
tool_data.cursor = cursor;
|
||||
responses.add(FrontendMessage::UpdateMouseCursor { cursor });
|
||||
responses.add(ShapeToolMessage::PointerMove(ShapeToolData::shape_tool_modifier_keys()));
|
||||
};
|
||||
|
||||
match (resize, rotate, skew) {
|
||||
(true, false, false) => {
|
||||
tool_data.get_snap_candidates(document, input);
|
||||
update_cursor_and_pointer(tool_data, responses);
|
||||
|
||||
return ShapeToolFsmState::ResizingBounds;
|
||||
}
|
||||
(false, true, false) => {
|
||||
tool_data.data.drag_start = mouse_pos;
|
||||
update_cursor_and_pointer(tool_data, responses);
|
||||
|
||||
return ShapeToolFsmState::RotatingBounds;
|
||||
}
|
||||
(false, false, true) => {
|
||||
tool_data.get_snap_candidates(document, input);
|
||||
update_cursor_and_pointer(tool_data, responses);
|
||||
|
||||
return ShapeToolFsmState::SkewingBounds { skew: Key::Control };
|
||||
}
|
||||
_ => {}
|
||||
@@ -686,8 +734,7 @@ impl Fsm for ShapeToolFsmState {
|
||||
self
|
||||
}
|
||||
(ShapeToolFsmState::ModifyingGizmo, ShapeToolMessage::PointerMove(..)) => {
|
||||
responses.add(DocumentMessage::StartTransaction);
|
||||
tool_data.gizmo_manger.handle_update(tool_data.data.drag_start, document, input, responses);
|
||||
tool_data.gizmo_manager.handle_update(tool_data.data.drag_start, document, input, responses);
|
||||
|
||||
responses.add(OverlaysMessage::Draw);
|
||||
|
||||
@@ -758,7 +805,7 @@ impl Fsm for ShapeToolFsmState {
|
||||
if cursor == MouseCursorIcon::Default { MouseCursorIcon::Crosshair } else { cursor }
|
||||
});
|
||||
|
||||
if tool_data.cursor != cursor && !input.keyboard.key(Key::Control) && !all_selected_layers_line {
|
||||
if tool_data.cursor != cursor {
|
||||
tool_data.cursor = cursor;
|
||||
responses.add(FrontendMessage::UpdateMouseCursor { cursor });
|
||||
}
|
||||
@@ -797,7 +844,7 @@ impl Fsm for ShapeToolFsmState {
|
||||
input.mouse.finish_transaction(tool_data.data.drag_start, responses);
|
||||
tool_data.data.cleanup(responses);
|
||||
|
||||
tool_data.gizmo_manger.handle_cleanup();
|
||||
tool_data.gizmo_manager.handle_cleanup();
|
||||
|
||||
if let Some(bounds) = &mut tool_data.bounding_box_manager {
|
||||
bounds.original_transforms.clear();
|
||||
@@ -822,12 +869,13 @@ impl Fsm for ShapeToolFsmState {
|
||||
tool_data.data.cleanup(responses);
|
||||
tool_data.line_data.dragging_endpoint = None;
|
||||
|
||||
tool_data.gizmo_manger.handle_cleanup();
|
||||
tool_data.gizmo_manager.handle_cleanup();
|
||||
|
||||
if let Some(bounds) = &mut tool_data.bounding_box_manager {
|
||||
bounds.original_transforms.clear();
|
||||
}
|
||||
|
||||
tool_data.cursor = MouseCursorIcon::Crosshair;
|
||||
responses.add(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Crosshair });
|
||||
|
||||
ShapeToolFsmState::Ready(tool_data.current_shape)
|
||||
|
||||
Reference in New Issue
Block a user