Closed BenHenning closed 2 months ago
Looks like this is now ready for review.
NB: Comments should be limited to 80 characters (ES lint doesn't catch this).
@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 renaming
WorkspaceSvg.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.