Define custom block with default shadowed value input

1,501 views
Skip to first unread message

Александр Чи

unread,
Feb 4, 2019, 6:45:52 AM2/4/19
to Blockly
I am defining custom block and I want it to have default shadowed value input.

Now I have the following code:

this.name = name;
this.setColour(0);
this.appendArgs_(name);
this.setPreviousStatement(true);
this.setNextStatement(true);
this.appendValueInput('ARG')
.setCheck("Number");

This produces the following block:


I think, I should somehow modify last line of code to get desired result, but the function appendValueInput accepts only one argument (I can't pass something like content to it). Maybe I should use another function?

The desired result is something like this:

Amber B

unread,
Feb 4, 2019, 8:44:14 AM2/4/19
to Blockly
It's generally easier and more customary to define shadow blocks in the toolbox. See the shadow blocks section of this page: https://developers.google.com/blockly/guides/configure/web/toolbox

Александр Чи

unread,
Feb 4, 2019, 7:16:47 PM2/4/19
to Blockly
Well, whole my toolbox is already defined in this manner:
Blocks['math_number'] = $.inherit(SimpleBlock, {
originType: 'math_number',

init: function() {
this.__base();
},

getValue: function() {
return Number(this.getFieldValue('NUM'));
}
});

So, it would be a lot of work to rewrite everything in xml style. May be I can at least insert default value there? I mean, not shadowed. It would be good too

понедельник, 4 февраля 2019 г., 23:44:14 UTC+10 пользователь Amber B написал:

Amber B

unread,
Feb 5, 2019, 8:58:09 AM2/5/19
to Blockly
Hrm. Well, it is possible to do shadow blocks with other toolbox setups (we actually use JSON, for example), but none that wouldn't require rewriting your function as it stands. If you're really determined to do it in the block code itself, I suppose you could do the following in your Block's init method:

  1. Use workspace.newBlock(prototypeName) to create a new shadow block of the desired type
  2. Use Block.setShadow(true) on the newly created block in order to make it a shadow block.
  3. Set the input to which you want to attach the shadow input to a variable (e.g. var inputOne = this.appendValueInput('ARG').setCheck('Number');)
  4. Connect the block's connection to the input connection. This code is a bit annoying to do, but assuming your new block is named newBlock, I believe it would look something like inputOne.connection.connect(newBlock.outputConnection).
I haven't tested this, but as I recall, we did something more or less like this when attempting to create a shadow block for an input which was created via mutator at one point.

Александр Чи

unread,
Feb 6, 2019, 2:49:29 AM2/6/19
to Blockly
Thank you very much, it works perfect! Almost..

It creates a block, but it moves separately. When you click and hold parent block, it gets a bit transparent (as a reaction to click) and also child block gets same transparency (it "understands", that parent was clicked). But if you move parent block, child will stay on it's place. Maybe, I am missed something about connections?

Here is my code now:
var defaultArgument = Blockly.Block.obtain(Blockly.mainWorkspace, 'math_number');
defaultArgument.initSvg();
defaultArgument.render();

this.appendValueInput('ARG' + i)
.setCheck("Number")
.connection
.connect(defaultArgument.outputConnection);

If I don't call defaultArgument.render() child block moves together with parent, but (obviously) doesn't get rendered. Also, in my version of Blockly workspace doesn't have newBlock(prototypeName)
method, so I use Blockly.Block.obtain().

вторник, 5 февраля 2019 г., 23:58:09 UTC+10 пользователь Amber B написал:

Amber B

unread,
Feb 6, 2019, 8:59:16 AM2/6/19
to Blockly
Um... huh. That's a new one by me. It definitely seems like something is a bit broken there, but it's hard to tell if it's a bug in Blockly itself or a bug in the way you're calling it. I don't see `Blockly.Block.obtain` in the API documentation for Blockly anywhere... are you using an outdated version, or perhaps a custom fork? I might be able to help if I know more about which version of Blockly you're using, but without that it's a bit tough.

Amber B

unread,
Feb 6, 2019, 9:00:54 AM2/6/19
to Blockly
Also, are there any errors in your console when you run this?

Александр Чи

unread,
Feb 7, 2019, 1:42:24 AM2/7/19
to Blockly
I think, it's probably bug the way I call it :)

Here is the method obtain.

And also - yes, I am using very outdated version - probably, I should update it, but I don't know, how to do it safely and properly. About version.. How to find out, which version am I using? I have two files - blockly_compressed.js and blockly_uncompressed.js, and there is no comment with version tag. I know, that files were committed in May 2014 =)

I can share a link to repositiory, if neccessary


About errors in console - yes, I have some. When I trying to spawn block from the toolbox, it firstly looks like this:

When I drag it to the main workspace, an exception appears. It says "Source connection already connected (value).". After it, block doesn't get rendered. When I drag it somewhere, it renders. When I drag it again, it moves separately from child block. Totaly mess 😟
среда, 6 февраля 2019 г., 23:59:16 UTC+10 пользователь Amber B написал:

kushal bhattacharya

unread,
Feb 7, 2019, 2:06:35 AM2/7/19
to Blockly
thats a much older file, you need to update to latest version in order to get a proper working code

Amber B

unread,
Feb 7, 2019, 8:40:47 AM2/7/19
to Blockly
Unfortunately this sounds like it may be a bug in the Blockly version you are using itself. I had to do an update from an older version of Blockly some time ago, and it mostly went fairly smoothly, but I did have to update some of our custom blocks and fields, particularly custom blocks which used variable dropdowns in them. How much in the way of custom configuration have you added to your Blockly project? It might at this point be better to try to guide you through an upgrade to the newest version.

Александр Чи

unread,
Feb 11, 2019, 2:27:48 AM2/11/19
to Blockly
Well, we added pretty much. For example, conversion from Python code to blocks or some other features.

But I think, the best solution would be to upgrade the library. I'll be very grateful, if you'd help me to do it 🙏🏻

Now I did the following steps:
  • Replaced blockly_compressed.js, blockly_uncompressed.js, blocks_compressed.js and python_compressed.js with their newer versions
And when in my code I call new Blockly.Flyout(), I get the error "this.getMetrics_ is undefined".

четверг, 7 февраля 2019 г., 23:40:47 UTC+10 пользователь Amber B написал:

Amber B

unread,
Feb 11, 2019, 9:00:01 AM2/11/19
to Blockly
My first suggestion would be to checkout a new branch of your local Blockly project and try doing a merge from the current master into your branch, then report back with the Merge Conflicts you get. Some may be easier to fix; some may not be.

That's an interesting issue, though. I definitely see a getMetrics_ option in the core Blockly code within flyout_base.js... it looks like that code should be defined within blockly_compressed.js. It may be better to get the new version merged in and then do your own build, though, since then you know it should match the rest of your code.
Reply all
Reply to author
Forward
0 new messages