Skip to content

Conversation

@rachel-fenichel
Copy link
Collaborator

@rachel-fenichel rachel-fenichel commented Apr 3, 2025

Fixes #364

This PR adds constrained movement by selectively extending and overriding parts of the drag strategy. In particular:

  • Adds a searchNode property, which is where a constrained search should start traversing the tree.
  • Overrides currCandidateIsBetter to always return false for a constrained drag. That is, the new candidate is always preferred.
  • Overrides getConnectionCandidate to call getConstrainedConnectionCandidate if the movement was constrained.

getConstrainedConnectionCandidate implements the following algorithm:

  • Start a traversal at the saved searchNode.
  • Choose traversal direction (next or previous) based on input direction.
  • In a loop, get the next (or previous) connection node in the tree.
  • If the connection is compatible with any of the connections on the dragging block/stack:
    • Create an appropriate candidate connection.
    • Update the search node.
    • Break out of the loop.
  • Otherwise, continue until no new nodes are found and return null.

Additional information

This does not position the dragging block near the connection (tracked in #370). I'm still figuring out how to do that without causing very weird jumps--I have to push information backwards through the dragging pipeline.

This does not loop from the last block in the workspace to the first, or vice versa (tracked in #369).

When you switch from unconstrained to constrained dragging, the traversal will always resume at the last valid connection that was tried. This may lead to unexpected jumps.

If you use the arrow keys to constrained move off the edge of the workspace, it will not scroll to keep it in view (tracked in #371). The drag will continue and end appropriately on an escape or enter.

I'm accessing a lot of private properties. Every @ts-expect-error is a sign of an API problem we need to sort out.

@rachel-fenichel rachel-fenichel requested a review from a team as a code owner April 3, 2025 19:09
@rachel-fenichel rachel-fenichel requested review from maribethb and removed request for a team April 3, 2025 19:09
/**
* Returns the next compatible connection in keyboard navigation order,
* based on the input direction.
* Always resumes the search at the last
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this comment is cut off

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

private getConstrainedConnectionCandidate(
draggingBlock: BlockSvg,
): ConnectionCandidate | null {
const cursor = draggingBlock.workspace.getCursor() as LineCursor;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

even when line cursor is the default in core, we'll still let people have other types right? can you leave a comment or something to remind us that we'll need to adjust this logic as well

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a todo and filed an issue.

localConns.forEach((conn: RenderedConnection) => {
const potentialLocation =
potential?.getLocation() as RenderedConnection;
if (connectionChecker.canConnect(conn, potentialLocation, true, 5000)) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is the 5000 here just a really big number? what about Infinity?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I forgot Infinity exists. Changed.

@rachel-fenichel rachel-fenichel merged commit c38e11d into RaspberryPiFoundation:main Apr 3, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Create a new KeyboardDragStrategy class

2 participants