Block specific context menu

491 views
Skip to first unread message

Antoine Lever

unread,
Mar 13, 2019, 9:14:00 AM3/13/19
to Blockly
I want certain block types to have an additional context menu option but, having read everything I can find on the subject, I just can't make it work. FYI, I managed to customise a global context menu to which works on the workspace, but nothing that works on a block. PLEASE HELP ME! Here is my block:

let block = {};
block['colour'] = colour;
block['message0'] = `${rule['value']}`;
block['args0'] = [];
block['tooltip'] = template['uuid'];
block['type'] = template['uuid'];
block['enableContextMenu'] = true;

if (!template['rootRule']) block['previousStatement'] = true;

if (rule['value'].includes('When')) { // I only want this type of rule to have the extra context menu option
block['customContextMenu'] = function(options) {
var option = {
enabled: true,
text: 'Custom option',
callback: function(e) {
console.log('custom context menu called\n', e);
},
};
options.push(option);
};
}

Blockly.Blocks[template['uuid']] = {
init: function() {
this.jsonInit(block);
},
};
Enter code here...Enter code here...

All I need is one example of this working. I can't find any online.
Thanks in advance for anything you can do for me



Beka Westberg

unread,
Mar 13, 2019, 10:16:43 AM3/13/19
to Blockly
Hello,

Well your custom context menu code all looks correct so that's good! I think the problem may be that you're trying to define the block with JSON ( if I'm reading this correctly ), and json doesn't let you define functions.

If you want to define a custom context menu you're probably going to have to do it with javascript, e.g:

Blockly.Blocks['test_block'] = {
  init
: function() {
   
this.appendDummyInput()
     
.appendField("testBlock");
   
this.setColour(230);
   
this.setTooltip("");
   
this.setHelpUrl("");
 
},


  customContextMenu
: function(options) {

   
var option = {
      enabled
: true,
      text
: 'Custom option',
      callback
: function(e) {
        console
.log('custom context menu called\n', e);
     
},
   
};
    options
.push(option);
 
}
};

The Json/Javascript thing may not be the problem though, that was just my first instinct.

I hope that helps! If you have any further questions please reply!
Beka

Antoine Lever

unread,
Mar 13, 2019, 10:29:41 AM3/13/19
to Blockly
I don't know if you've heard of my "favourite person of the day" award but it's rather prestigious and you've just won it. Thank you!!  I simply changed the following:

        Blockly.Blocks[template['uuid']] = {
           init: function() {
               this.jsonInit(block);
           },
           customContextMenu: function(options) {
               var option = {
                   enabled: true,
                   text: 'Custom option',
                   callback: function(e) {
                       console.log('custom context menu called\n', e);
                   },
               };
               options.push(option);
           },
       };



fpw2377

unread,
Aug 12, 2020, 7:07:42 AM8/12/20
to Blockly
Is the callback function suppose to pass an "e" argument?  When I tried this e was always undefined.  The only way I was able to get the context of which block was calling this menu was with this code:
 
customContextMenu: function (options) {
      var block = this
      var option = {
        enabled: true,
        text: 'Save as template',
        callback: function () {
          // fire event for template save
          Blockly.Events.fire(new TemplateSystemEvent(block, 'save'))
        }
      }
      options.push(option)
    }

I had to save "this" of the createContextMenu to a local var then access it from within the callback function of the option.  Is this the correct way to accomplish this? 
Reply all
Reply to author
Forward
0 new messages