Skip to content
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

Plugin for Selecting & Dragging & Doing Actions on Multiple Blocks #1

Merged
merged 26 commits into from
Jul 28, 2022
Merged

Plugin for Selecting & Dragging & Doing Actions on Multiple Blocks #1

merged 26 commits into from
Jul 28, 2022

Conversation

HollowMan6
Copy link
Collaborator

@HollowMan6 HollowMan6 commented Jul 12, 2022

User behavior

  1. When some of the selected blocks are in one block stack, for example, some top blocks and some of their children blocks are in the selection simultaneously. If applicable, the plugin only disconnects the selected most top block in that stack with its parent block. Move along with all the children's blocks of that most top block as a whole.
  2. Blocks can be deselected by clicking on the workspace background.
  3. Additional blocks can be able to be selected/deselected by holding SHIFT key while clicking the new/already selected block.
  4. Clicking a new block without holding SHIFT key can clear the multiple selections and only select that block.
  5. Holding SHIFT key to drag a rectangle area to select can reverse their selection state for the blocks touched by the rectangle.
  6. Clicking on the button above the dustbin is equivalent to holding/releasing the SHIFT key for switching between the multiple selection mode and the normal mode. Icons are customizable.
  7. Bumping neighbours after dragging to avoid overlapping is disabled in this plugin by default. Enable with bumpNeighbours: true.
  8. Click on a block will bring that block to front. (In case Bumping neighbours is disabled)
  9. In multiple selection mode, workspace dragging as well as block dragging will all be disabled. You can only drag to draw a rectangle for selection.
  10. The Duplicate menu will duplicate the selected most top block in the block stack and all the children blocks of that most top block. The selection will be changed to all newly created duplicate blocks' most top blocks.
  11. The Add Comment / Remove Comment will instead read as Add Comment (X) / Remove Comment (X), and will add / remove comment buttons to all the selected blocks.
  12. The Inline Inputs / External Inputs will instead read as Inline Inputs (X) / External Inputs (X), and will convert the input format with all the selected blocks.
  13. The Collapse Block / Expand Block will instead read as Collapse Block (X) / Expand Block (X), and will only apply to the selected most top block in the block stack.
  14. The Disable Block / Enable Block will instead read as Disable Block (X) / Enable Block (X), and will only apply to the selected most top block in the block stack. All the children blocks of that most top block will also get disabled.
  15. For 11-14, X means the currently applicable number of selected blocks by the user, and (X) will only be shown when X is greater than 1.
  16. The text to show in 11-14 is determined by the state of the block that the user right-clicks, and the same status will be applied to all the blocks no matter their individual state.
  17. Delete [X] Blocks represents the count of the selected most top block in the block stack as well as all children of those selected most top block, and delete the blocks mentioned.
  18. The "Help" option displays just the helping information for which block the user just right-clicked.
  19. The workspace context menu has a item to Select all Blocks in that workspace.
  20. When you use Ctrl/Alt + A, you can select all the blocks in the current workspace. Ctrl/Alt + C to copy the selected blocks, Ctrl/Alt + X to cut the selected blocks to the clipboard, and Ctrl/Alt + V to paste all the blocks currently in the clipboard and get all the newly pasted blocks selected, these will only apply to the selected most top block in the block stack.
  21. (MIT App Inventor-only feature) Double click to collapse/expand currently selected blocks, enable with Blockly option useDoubleClick: true.

Note: This plugin is part of the achievement by Songlin Jiang(@HollowMan6) participating the Google Summer of Code 2022 at MIT App Inventor.

Copy link

@BeksOmega BeksOmega left a comment

Choose a reason for hiding this comment

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

This PR is quite large, so I'm going to have to review it in stages =) This is the first pass.

So far, looks really good! Thank you so much for your hard work on this :D

Copy link

@BeksOmega BeksOmega left a comment

Choose a reason for hiding this comment

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

Second Pass!

src/dragger.js Outdated
});
if (this.blockDraggers_.size > 1) {
// Restore the highlighting around connection for multiple blocks.
Blockly.RenderedConnection.prototype.highlight = origHighlight;

Choose a reason for hiding this comment

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

I'd like to find a way around this that doesn't involve monkey patching the prototype, but I'll have to think on it haha. @BeksOmega for later.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

If we can luckily fix the bug, then that monkey patch is no longer needed.

The bug is that, when you finished connecting multiple blocks at the same time, only one of the highlighted connection path that appear during the multiple drag can get deleted and others will still remain:


So the patch here is just a work around, it disables showing the highlight in a multiple drag.
image

Currently I have no idea on how to fix that, may be some upstream patches will be necessary I guess.

Choose a reason for hiding this comment

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

I agree that that is an upstream bug that needs to be fixed. Will file.

Choose a reason for hiding this comment

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

Choose a reason for hiding this comment

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

Ok, I don't see a way around these monkey patches without fixes in core. @cpcallen , will module sealing break these patches? or will they be fine and we can leave them for now?

@HollowMan6
Copy link
Collaborator Author

HollowMan6 commented Jul 13, 2022

Hi @BeksOmega ! Thanks so much for reviewing, I have committed all the resolved code changes for the Pass 1 & 2 in a85fc79

In addition, I just disabled bumping neighbours and fixed a Bug 92234e7

The reason for disabling bumping is that, I noticed that sometimes, for multiple selection, bumping neighbours will lead some selected blocks' surrounding highlight disappear (while still selected) after moving, and I also dislike bumping neighbours in multiple selection mode as those unpredictable movements can make the workspace really messy.

The fixed random bug is that, when you drag the selected children blocks from their unselected parent, the children blocks of the selected ones can be out of the position while still connected after the disconnection (the selected blocks' children do should remain connected, but they shouldn't be out of the position).

GIF 13-07-2022 15-43-27

Copy link

@BeksOmega BeksOmega left a comment

Choose a reason for hiding this comment

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

Pass 3! And good catch on that bumping bug =) Haven't had time to investigate ways around all of the prototype assignments yet.

src/index.js Outdated
this.justDeletedBlock_.pathObject.updateSelected(false);
this.justDeletedBlock_ = null;
}
// Update the selection highlight.

Choose a reason for hiding this comment

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

Why do you need to update the selection highlight in bulk if you're updating individual blocks individual blocks as they're selected/unselected?

Copy link
Collaborator Author

@HollowMan6 HollowMan6 Jul 15, 2022

Choose a reason for hiding this comment

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

We may still want to do this here, otherwise such as in the multiple selection shortcut copy and paste, it's not easy to keep all those selected. Maybe it can be optimized later, but currently we just keep the original as it's an easy way to avoid bugs and it seems like that it won't impact the performance.

Copy link

@BeksOmega BeksOmega left a comment

Choose a reason for hiding this comment

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

Pass 4!

src/dragger.js Outdated
});
if (this.blockDraggers_.size > 1) {
// Restore the highlighting around connection for multiple blocks.
Blockly.RenderedConnection.prototype.highlight = origHighlight;

Choose a reason for hiding this comment

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

I agree that that is an upstream bug that needs to be fixed. Will file.

@ewpatton
Copy link
Member

ewpatton commented Jul 15, 2022 via email

@HollowMan6
Copy link
Collaborator Author

@ewpatton

We should verify this. App Inventor uses a different rendering algorithm than base Blockly. We haven't tested whether the new render pipeline performs similarly without the optimizations we've added.

Okay, then will add a TODO to verify that in App Inventor when ready.

@BeksOmega
Copy link

General JavaScript style note: Usually if a file only contains a single class, the name of the class and the name of the file are the same.

E.g. if a file exports a single class FooBar the file will be named foo_bar.js.

Signed-off-by: Hollow Man <[email protected]>
@HollowMan6
Copy link
Collaborator Author

General JavaScript style note: Usually if a file only contains a single class, the name of the class and the name of the file are the same.

E.g. if a file exports a single class FooBar the file will be named foo_bar.js.

Okay, just reorganized the code accordingly.

Signed-off-by: Hollow Man <[email protected]>
Copy link

@BeksOmega BeksOmega left a comment

Choose a reason for hiding this comment

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

Ok, I think with this I've been about as helpful as I can be =)

The monkey patches included will definitely require maintenance (the core team does not guarantee they will continue to work). But aside from that, I think this is about as stable as one can make it.

@ewpatton you might want to have someone on your team take a look as well before merging.

@HollowMan6
Copy link
Collaborator Author

Ok, I think with this I've been about as helpful as I can be =)

The monkey patches included will definitely require maintenance (the core team does not guarantee they will continue to work). But aside from that, I think this is about as stable as one can make it.

Thanks so much for helping me review my code all the way around!

@BeksOmega
Copy link

Ok, I think with this I've been about as helpful as I can be =)
The monkey patches included will definitely require maintenance (the core team does not guarantee they will continue to work). But aside from that, I think this is about as stable as one can make it.

Thanks so much for helping me review my code all the way around!

Absolutely! Reviewing PRs is one of my favorite things =) I can't wait to see this go up on NPM!

Copy link
Member

@ewpatton ewpatton left a comment

Choose a reason for hiding this comment

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

This is looking pretty good @HollowMan6. I've left some comments for you to think about.

@HollowMan6 HollowMan6 requested a review from ewpatton July 28, 2022 01:34
Copy link
Member

@ewpatton ewpatton left a comment

Choose a reason for hiding this comment

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

@HollowMan6 I think this is good for a first pass. We're going to merge this and deploy this first version to npm so people can start trying it out. @ellelili2025 will coordinate next steps for integration into the latest version of App Inventor with Blockly 8.

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.

3 participants