Skip to content

Commit

Permalink
#400: Ensure snap follows mouse cursor on resize, fix cursor feedback
Browse files Browse the repository at this point in the history
- Don't let mouse cursor and feedback get out of sync
- Provide proper mouse cursor feedback based for move and resize
- Use 'Alt' for free resize instead of 'Shift' due to marquee conflict

Signed-off-by: Martin Fleck <mfleck@eclipsesource.com>
  • Loading branch information
martin-fleck-at committed Oct 8, 2021
1 parent ab9890a commit f6bfed9
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 10 deletions.
14 changes: 11 additions & 3 deletions packages/client/css/glsp-sprotty.css
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,16 @@
cursor: crosshair;
}

.resize-mode {
cursor: none;
.move-mode {
cursor: move;
}

.resize-nesw-mode {
cursor: nesw-resize;
}

.resize-nwse-mode {
cursor: nwse-resize;
}

.element-deletion-mode {
Expand All @@ -104,4 +112,4 @@

.marquee-mode {
cursor: crosshair;
}
}
9 changes: 9 additions & 0 deletions packages/client/src/features/change-bounds/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,15 @@ export class SResizeHandle extends SChildElement implements Hoverable {
hasFeature(feature: symbol): boolean {
return feature === hoverFeedbackFeature;
}

isNwSeResize(): boolean {
return this.location === ResizeHandleLocation.TopLeft || this.location === ResizeHandleLocation.BottomRight;
}

isNeSwResize(): boolean {
return this.location === ResizeHandleLocation.TopRight || this.location === ResizeHandleLocation.BottomLeft;
}

}

export function addResizeHandles(element: SParentElement): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ import {
SModelRoot,
TYPES
} from 'sprotty';

import { isNotUndefined } from '../../utils/smodel-util';
import { addResizeHandles, isResizable, removeResizeHandles, SResizeHandle } from '../change-bounds/model';
import { createMovementRestrictionFeedback, removeMovementRestrictionFeedback } from '../change-bounds/movement-restrictor';
import { CursorCSS, cursorFeedbackAction } from '../tool-feedback/css-feedback';
import { ChangeBoundsTool } from '../tools/change-bounds-tool';
import { FeedbackCommand } from './model';

Expand Down Expand Up @@ -120,6 +120,7 @@ export class FeedbackMoveMouseListener extends MouseListener {
const moveAction = this.getElementMoves(target, event, false);
if (moveAction) {
result.push(moveAction);
result.push(cursorFeedbackAction(CursorCSS.MOVE));
}
}
return result;
Expand Down Expand Up @@ -224,6 +225,7 @@ export class FeedbackMoveMouseListener extends MouseListener {
if (this.tool.movementRestrictor) {
this.tool.deregisterFeedback([removeMovementRestrictionFeedback(target, this.tool.movementRestrictor)], this);
}
result.push(cursorFeedbackAction(CursorCSS.DEFAULT));
}
this.hasDragged = false;
this.startDragPosition = undefined;
Expand Down
4 changes: 3 additions & 1 deletion packages/client/src/features/tool-feedback/css-feedback.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ export enum CursorCSS {
EDGE_RECONNECT = 'edge-reconnect-select-target-mode',
OPERATION_NOT_ALLOWED = 'edge-modification-not-allowed-mode',
ELEMENT_DELETION = 'element-deletion-mode',
RESIZE = 'resize-mode',
RESIZE_NESW = 'resize-nesw-mode',
RESIZE_NWSE = 'resize-nwse-mode',
MOVE = 'move-mode',
MARQUEE = 'marquee-mode'
}

Expand Down
10 changes: 5 additions & 5 deletions packages/client/src/features/tools/change-bounds-tool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ export class ChangeBoundsListener extends DragAwareMouseListener implements Sele
// rely on the FeedbackMoveMouseListener to update the element bounds of selected elements
// consider resize handles ourselves
const actions: Action[] = [
cursorFeedbackAction(CursorCSS.RESIZE),
cursorFeedbackAction(this.activeResizeHandle.isNwSeResize() ? CursorCSS.RESIZE_NWSE : CursorCSS.RESIZE_NESW),
applyCssClasses(this.activeResizeHandle, ChangeBoundsListener.CSS_CLASS_ACTIVE)
];
const positionUpdate = this.updatePosition(target, event);
Expand Down Expand Up @@ -309,14 +309,14 @@ export class ChangeBoundsListener extends DragAwareMouseListener implements Sele

// snap our delta and only send update if the position actually changes
// otherwise accumulate delta until we do snap to an update
const positionUpdate = this.snap(this.positionDelta, target, !event.shiftKey);
const positionUpdate = this.snap(this.positionDelta, target, !event.altKey);
if (positionUpdate.x === 0 && positionUpdate.y === 0) {
return undefined;
}

// we update our position so we need to reset our delta
this.positionDelta.x = 0;
this.positionDelta.y = 0;
// we update our position so we update our delta by the snapped position
this.positionDelta.x -= positionUpdate.x;
this.positionDelta.y -= positionUpdate.y;
return positionUpdate;
}
return undefined;
Expand Down

0 comments on commit f6bfed9

Please sign in to comment.