-
Notifications
You must be signed in to change notification settings - Fork 13
feat: Introduce Mover actions + experimental DragMover implementation
#317
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Introduce the Mover class, with shortcuts that will put a workspace into (and exit from) moving mode. While in moving mode, cursor navigation via the cursor keys is disabled.
Create an experimental implementation of unconstrained dragging using the existing Dragger class. Implement this on a new Mover subclass DragMover, to keep this experimental code (that will probably be thrown away) separate from the main Mover implementation. Known bugs: * Blocks lurch around somewhat wildly while being moved. * Moving top-level blocks works reasonably well, but attempting to move a non-top-level block will result in it being deleted unless the move is aborted.
|
Deployed here so I could play with it easily (won't automatically update for subsequent pushes) |
|
Just to note that Alt+left arrow takes me back to the previous page in Chrome on Windows 11. (we get away with Alt+right arrow for testing as there isn't usually a subsequent page, though of course there could be) |
I had originally proposed using |
Alt+arrows causes browser navigation on Windows. :-(
|
Now provides a context menu item (on blocks) for the move action, and supports |
There was a bug that would often cause blocks to be deleted. This was because the dragger thought the block was on the toolbox, which is a delete area. Fix this by giving the dragger much better fake PointerEvents, so that it knows where the block actually is - good enough that you can move the block to the trash can and it will be deleted!
|
Fixed issue with blocks being deleted when the move finished. The fix was to provide better fake The blocks still lurch around a bit, and the implementation is kind of janky (don't look at what happens when you abort a move!), but it is absolutley good enough to be useful now, so I'm marking this PR as ready for review. |
|
I notice that if you move a block such that an insertion marker appears, and abort the move at that point, you get the following stack trace: And wind up with an orphaned insertion marker in some cases. |
| hasNavigationFocus: boolean = false; | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this was inadvertently introduced resolving a merge conflict?
| ShortcutRegistry.registry.unregister(shortcut.name); | ||
| } | ||
|
|
||
| this.mover.install(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
uninstall()?
|
|
||
| constructor( | ||
| protected navigation: Navigation, | ||
| canEdit: (ws: WorkspaceSvg) => boolean, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
canEdit could also just be declared protected here for consistency
| * given workspace. | ||
| * | ||
| * @param workspace The workspace to move on. | ||
| * @returns True iff we can beign a move. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: begin
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
beignet
| if (!block) { | ||
| const cursor = workspace?.getCursor(); | ||
| const curNode = cursor?.getCurNode(); | ||
| block = curNode?.getSourceBlock() ?? undefined; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be worth factoring this out into a getCurrentBlock() since startMove also appears to need it
| cursor.setCurNode(ASTNode.createBlockNode(block)!); | ||
|
|
||
| // Additional implementation goes here. | ||
| console.log('startMove'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove? Applies throughout, assuming this was just debugging logging.
| * @returns True iff move successfully finished. | ||
| */ | ||
| finishMove(workspace: WorkspaceSvg) { | ||
| if (!workspace) return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make the workspace arg to this function nullable or remove this null check, same for abortMove. Or perhaps unify them since they're currently identical?
| * @returns True iff move successfully finished. | ||
| */ | ||
| override finishMove(workspace: WorkspaceSvg) { | ||
| if (!workspace) return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As in the base class, either remove the null check or make the arg nullable here and in abortMove
…tion (#352) * feat: Introduce Mover class, moving mode Introduce the Mover class, with shortcuts that will put a workspace into (and exit from) moving mode. While in moving mode, cursor navigation via the cursor keys is disabled. * feat: Save block starting location and connections * feat: Experiment: unconstrained movement using Dragger Create an experimental implementation of unconstrained dragging using the existing Dragger class. Implement this on a new Mover subclass DragMover, to keep this experimental code (that will probably be thrown away) separate from the main Mover implementation. Known bugs: * Blocks lurch around somewhat wildly while being moved. * Moving top-level blocks works reasonably well, but attempting to move a non-top-level block will result in it being deleted unless the move is aborted. * feat: Add Move Block (M) context menu item * fix: Allow ctrl+arrows to also perform unconstrained moves Alt+arrows causes browser navigation on Windows. :-( * fix: Use better fake PointerEvents to prevent random deletions There was a bug that would often cause blocks to be deleted. This was because the dragger thought the block was on the toolbox, which is a delete area. Fix this by giving the dragger much better fake PointerEvents, so that it knows where the block actually is - good enough that you can move the block to the trash can and it will be deleted! * chore: address feedback from #317 * chore: lint and format * fix: remove allowCollision for m * fix: #356 by hiding the connection preview before reverting a drag * fix: spelling --------- Co-authored-by: Christopher Allen <cpcallen+git@google.com>
|
Closed in favor of #352 |
…tion (RaspberryPiFoundation#352) * feat: Introduce Mover class, moving mode Introduce the Mover class, with shortcuts that will put a workspace into (and exit from) moving mode. While in moving mode, cursor navigation via the cursor keys is disabled. * feat: Save block starting location and connections * feat: Experiment: unconstrained movement using Dragger Create an experimental implementation of unconstrained dragging using the existing Dragger class. Implement this on a new Mover subclass DragMover, to keep this experimental code (that will probably be thrown away) separate from the main Mover implementation. Known bugs: * Blocks lurch around somewhat wildly while being moved. * Moving top-level blocks works reasonably well, but attempting to move a non-top-level block will result in it being deleted unless the move is aborted. * feat: Add Move Block (M) context menu item * fix: Allow ctrl+arrows to also perform unconstrained moves Alt+arrows causes browser navigation on Windows. :-( * fix: Use better fake PointerEvents to prevent random deletions There was a bug that would often cause blocks to be deleted. This was because the dragger thought the block was on the toolbox, which is a delete area. Fix this by giving the dragger much better fake PointerEvents, so that it knows where the block actually is - good enough that you can move the block to the trash can and it will be deleted! * chore: address feedback from RaspberryPiFoundation#317 * chore: lint and format * fix: remove allowCollision for m * fix: RaspberryPiFoundation#356 by hiding the connection preview before reverting a drag * fix: spelling --------- Co-authored-by: Christopher Allen <cpcallen+git@google.com> feat: heuristic insert (RaspberryPiFoundation#355) * chore: simplify tryToConnectNodes We only insert blocks so remove other cases. * feat: heurstic insertion logic - use first statement or value input - in statement inputs move to the last next connection in the chain - use next connections over previous connections chore: convert webdriverio tests to TypeScript (RaspberryPiFoundation#353) * chore: convert webdriverio tests to TypeScript * chore: comment typo fix feat: allow for toolbox with multiple tab stops (RaspberryPiFoundation#358) - Switch to focusin/out for toolbox (maybe in future elsewhere) - Drop the tab index fiddling as it's not practical to get it right in the face of more than one tab stop in the toolbox, especially if that toolbox has a DOM structure not known to the plugin. Given that we're reinstating the ability to shift-tab flyout->toolbox it makes sense to allow tab to the flyout. Shift-tab to the flyout remains not possible in the auto-hide case but that's not unreasonable. This version can be made to work with MakeCode without further modifications. feat: use ts and factor out helper functions
Introduces a
Moverclass which:(for now only keyboard shortcuts)to start a move, move in cursor-key directions, and end or abort a move.Mover-internal state. When in moving mode, the arrow keys are hooked to trigger block moving actions rather than their normal cursor moving actions.Additionally, introduces a
DragMoversubclass that provides an experimental implementation of unconstrained block movement usingDragger.To try this out, move the cursor to a movable block, press
m, then usealt+arrows to move the block. Pressenterto finish the move, orescto abort it.Moving using the dragger sort of works, with a few known issues:
Moving top-level blocks works reasonably well, but attempting to move a non-top-level block will result in it being deleted unless the move is aborted.FIXED!The purpose of separating this experimental implementation into a separate subclass is that it is anticipated that it may well be thrown away, both because of the above noted issues and because this approach may be fundamentally incompatible with constrained movement. Specifically: constrained movement should first concern itself with where the moving block(s) might be connected, and only then decide where to position them on screen (e.g. so that they are very near but not obscuring an insertion marker)—whereas dragging begins with the position of the block and from that decides where the block might connect.
Part of #106.