Skip to content

addon.tab.createBlockContextMenu API - #1754

Merged
WorldLanguages merged 65 commits into
ScratchAddons:masterfrom
TheColaber:contextMenu
Jul 30, 2021
Merged

addon.tab.createBlockContextMenu API#1754
WorldLanguages merged 65 commits into
ScratchAddons:masterfrom
TheColaber:contextMenu

Conversation

@TheColaber

@TheColaber TheColaber commented Mar 8, 2021

Copy link
Copy Markdown
Member

Resolves #1749
Resolves #1968

@TheColaber

TheColaber commented Mar 8, 2021

Copy link
Copy Markdown
Member Author

How to use

createBlockContextMenu(
    callback,
    { workspace = false, blocks = false, flyout = false } = {}
)

The first param is the callback... the callback gets the param with all the items currently in the list, as well as, the blockly block (if there was one) that was right-clicked. The function should return the array of items back. Then the second param is the options params. workspace decides if it should run the callback when the user right-clicks on the workspace. blocks will run the callback when the user right-clicks on any block. flyout if true will also run the callback when the user right-clicks on a block in the flyout.

Here is an example:

addon.tab.createBlockContextMenu((items, block) => {
  if (block.type == "data_variable" && block.category_ == "data") { // Only allow blocks on the reporter blocks and data catagory blocks
    items.push({
      callback: (event) => {
        console.log("Clicked!!", event);
      },
      enabled: true,
      text: "Custom Item",
      separator: true
    });
  }
  return items;
}, {
  workspace: false, // Not on the workspace
  blocks: true, // Allow blocks in workspace
  flyout: true // Allow blocks in the flyout
});

How it works

Each addon has a property called addon.tab._blockContextMenu. When they use addon.tab.createBlockContextMenu, it appends some info into that array. module.js takes care of all the Blockly logic. It pollutes Blockly.ContextMenu.show, in which scratch passes in 3 parameters. event, items, rtl. The only useful and used parameter here is items. We make sure to run scripts first, adding more items from the addons, before having scratch's original code run. Remember, this is the show function, so once the original code runs, the context menu will be visible. We get the items to add by looking at scratchAddons.eventTargets.tab which is an array of all running addons that have userscripts. In there, we look for all addons' _blockContextMenu and put all items in one array. module.js does some logic to determine weather the item should be added to array based on the options that it was given. Each addon gets a callback called with 2 parameters. items and block. They must return the items array again, but they may modify and add items. block is a Blockly.Block when the user right clicks on a block. It determines which block the user right clicked by looking at Blockly.mainWorkspace.currentGesture_.targetBlock_. After all this, we call the original function, and finally, we make sure to add styles to items that add that as one of there settings. Make sure to refer to the example above again, and it may make more sense.

@mxmou

mxmou commented Mar 8, 2021

Copy link
Copy Markdown
Member

// TODO: Create Separators somehow... help!

Separators are not a Scratch feature, you need to add them using CSS after the menu loads.

@TheColaber
TheColaber requested a review from apple502j as a code owner March 9, 2021 22:39
@WorldLanguages WorldLanguages added this to the v1.16.0 milestone May 15, 2021
@cobaltt7 cobaltt7 linked an issue May 24, 2021 that may be closed by this pull request
@apple502j apple502j modified the milestones: v1.16.0, Backlog Jun 12, 2021
Comment thread addons/block-switching/userscript.js Outdated
@WorldLanguages
WorldLanguages merged commit f8d98af into ScratchAddons:master Jul 30, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

scope: addon api Related to the addon.* JS APIs or other ways for addons to provide features scope: core Related to the core script/extension workings

Projects

None yet

6 participants