Function for connecting subblocks to a block

582 views
Skip to first unread message

Marco Antonio Iñarrea Santomé

unread,
Aug 30, 2017, 6:32:38 AM8/30/17
to Blockly
I have a block (main_block) with a statement input and a mutator. Thanks to the mutator I connect blocks to the statement input. Each time I call the compose () function of the mutator I would like to invoke the blockly function which is responsible for adding subblocks to a block. I would like to know where to find that function.


Victor Ng

unread,
Aug 30, 2017, 5:49:34 PM8/30/17
to Blockly

I'm not sure if I understand your question, but to connect two blocks, you need to connect their "Connection" objects together.

eg.
var block1 = workspace.newBlock('controls_repeat_ext');
var block2 = workspace.newBlock('controls_if');
var connection = block1.getInput('DO').connection;
connection.connect(block2.previousConnection);

You can also use the helper method "Mutator.reconnect(...)", which helps reconnect previous connections on a mutated block. See the "if" block "compose()" method for example usage.

Does this answer your question?

Marco Antonio Iñarrea Santomé

unread,
Aug 31, 2017, 5:59:57 AM8/31/17
to Blockly

My main object represents an instance c1 of a Condition Java class. Initially it is loaded with 2 attributes

that is mandatory to set. From the mutator I want to be able to add optional attributes of the class.

To do this, within the workspace of the mutator UI I make a copy of my class block.



As you can see in the second image, the attributes to be added can be instances

of other classes. When I add a "class sub-block" in the mutator,

main block creates a complex block with its own mutator.


In the third image you can see how I modify an instance of the Reference class,

by adding an instance of the CodeableConcept class.


In the fourth image you can see how the resulting block remains. Until that point

Everything works fine.


The real problem is when removing blocks. To paint the attributes of the mutator,

I run the childBlocks of the mutator container and connect them in order to the input statement

Of the main block. But before, I have to delete the previous blocks. The problem I have

Is that those previous blocks have been modified and if I disconnect them and I simply catch the

Mutator childBlocks, I lose blocks that have been modified.



The fifth image shows the problem, I reopened the mutator of the main block and added

an instance of an Identifier object. As you can see I have lost the changes I had made

In the subject object.



I do not know if blockly implements some function that helps in some similar problem. Or if someone has faced

before some style problem. I do not know how to approach the problem.







/**
 * Reconfigure this block based on the mutator dialog's components.
 * @param {!Blockly.Block} containerBlock Root block in mutator.
 * @this Blockly.Block
 */

compose
(containerBlock) {


 
var childBlock = containerBlock.getInputTargetBlock('attributes');
 
this.mutatorChildBlocks_ = [];
 
while (childBlock) {
   
this.mutatorChildBlocks_.push(childBlock);
    childBlock
= childBlock.nextConnection &&
      childBlock
.nextConnection.targetBlock();
 
}


 
this.updateShape_();
},
/**
 * Modify this block to have the correct child blocks.
 * @private
 * @this Blockly.Block
 */

updateShape_
() {


  let connection
= this.getInput('attributes').connection;


 
// First, dispose of all my children.
 
for (let child of this.getChildren()) {
    child
.dispose();
 
}


 
for (let mutatorChildBlock of this.mutatorChildBlocks_) {


    let childBlock
;


   
//...


    childBlock
.initSvg();
    childBlock
.render();
    connection
.connect(childBlock.previousConnection);
    connection
= childBlock.nextConnection;
 
}


}

Victor Ng

unread,
Sep 1, 2017, 8:16:48 PM9/1/17
to Blockly
This is not best use of mutators. From a UX perspective, it is a bit confusing. Mutators aren't really meant for creating additional sub-blocks, but rather for modifying a single block (eg. "if" block).

That said, it sounds like you have a data synchronization problem. I think what you want is possible, but you'll have to be diligent about tracking state between calls to compose() and decompose() (I don't see a decompose method -- is that what you're missing?). You may also need to attach an event on the workspace to detect if a child block has been removed from one of the mutated blocks, in order to synchronize the internal state of the mutator.
Reply all
Reply to author
Forward
0 new messages