-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
fix: Ensure immovable blocks are considered during workspace tidying #8550
fix: Ensure immovable blocks are considered during workspace tidying #8550
Conversation
At a high-level, this change ensures that cleaning up a workspace doesn't move blocks in a way that overlaps with immovable blocks. It also adds missing testing coverage for both Rect (used for bounding box calculations during workspace cleanup) and WorkspaceSvg (for verifying the updated clean up functionality). This also renames the clean up function to be 'tidyUp' since that better suits what's happening (as opposed to other clean-up routines which are actually deinitializing objects).
…ring-workspace-tidying
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.
Welcome! It looks like this is your first pull request in Blockly, so here are a couple of tips:
- You can find tips about contributing to Blockly and how to validate your changes on our developer site.
- All contributors must sign the Google Contributor License Agreement (CLA). If the google-cla bot leaves a comment on this PR, make sure you follow the instructions.
- We use conventional commits to make versioning the package easier. Make sure your commit message is in the proper format or learn how to fix it.
- If any of the other checks on this PR fail, you can click on them to learn why. It might be that your change caused a test failure, or that you need to double-check the style guide.
Thank you for opening this PR! A member of the Blockly team will review it soon.
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.
Self-reviewed changes.
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.
Self-reviewed test rename.
Looks like this is now ready for review. |
NB: Comments should be limited to 80 characters (ES lint doesn't catch this). |
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.
Self-reviewed changes renaming back to 'cleanUp'.
@gonfunko could you PTAL per latest changes and let me know if the PR still looks good to you? |
Thanks @gonfunko! |
Thanks so much for this! |
The basics
The details
Resolves
Fixes #6889
Proposed Changes
This PR introduces a fix for #6889 (
WorkspaceSvg.cleanUp
) when a workspace contains an immovable block. Previously, immovable blocks were ignored incleanUp
which could lead to situations where movable blocks were stacked on top of the immovable blocks. The updated algorithm addresses this.The old algorithm was essentially the following steps:
getTopBlocks
andWorkspace
's sorting logic).(0, 0)
.y
coordinate plus its height plus a minimum height spacing defined by the renderer'sMIN_BLOCK_HEIGHT
property. Also, left-align the block at anx
value of0
.The updated algorithm augments this by considering any immovable blocks that the new block's position might intersect with (by using
Rect
'sintersects
method), as so:Rect
(to be used later).(0, 0)
. If not, assume it to be(0, y)
wherey
is the previous block's position plus the previous block's height plus the minimum block spacing (as described above).y
in the same way as the previous step except use the conflicting immovable block's position and size, rather than the previous movable block.NOTE:
This PR is also renamingWorkspaceSvg.cleanUp
toWorkspaceSvg.tidyUp
since 'clean up' is an overloaded term in the codebase and generally means "deinitialize." This PR does not rename the context menu item since cleaning up the workspace has a different context for the user and probably makes equal sense to 'tidy' (so there wasn't an obvious reason to change it other than to keep the two aligned).This has been reverted after a discussion with the team--the preference is to avoid unnecessary code changes and this rename has few benefits.
Reason for Changes
Trying to tidy up the workspace without considering immovable blocks leads to undesirable results. See previous behavior:
Screen.recording.2024-08-21.1.42.28.PM.webm
With the changes, the new behavior is:
Screen.recording.2024-08-21.1.40.37.PM.webm
This is a much better user experience. Note that the above was demoed by importing the following JSON into a local Blockly playground:
Test Coverage
cleanUp
had no functional tests, so a bunch were added (including for verifying existing behaviors). All of this function's new tests passed without the algorithmic changes except for the test"multiple block types immovable blocks are not moved"
(which was verified to fail, as expected, without the algorithmic fixes).Separately,
Rect
had some additional functionality and documentation added, along with an entire new test suite meant to thoroughly test all aspects of the class (since it plays a pivotal role in the new functionality, plus a bunch of other existing functionality throughout Blockly core).Documentation
It doesn't seem any documentation changes are needed at this time since the fix was entirely infrastructural and implementation-specific. Since this is a public API function, it's certainly possible some documentation work will be needed.
Additional Information
The needs of
cleanUp
functional changes and its tests led to needing a bounding box class. This was added beforeRect
was discovered, and its intersection algorithm was independently derived.Rect
's own intersection code is actually replaced in this PR with the derived version (the same logic, just inverted) with some documentation to logically explain why it works to help any future readers who come across it.Separately, the workspace tests prefer to use JSON for block initialization vs. direct API access. This seems to be the recommended way to approach such test condition arrangement after discussions with other Blockly team members.