Making a new variable's "set" block appear

80 views
Skip to first unread message

Tim Erickson

unread,
Feb 16, 2023, 3:24:35 PM2/16/23
to Blockly
Hello, BlocklyWorld!

I have successfully made new variables, partly thanks to all of your help. And I've tried to be a good citizen and look carefully in the reference. No joy.

Here's what I want to do: when a user makes a new variable, I want to make a suitable "set" block appear in the workspace. As far as I can tell, that means making a new block of the right type and then setting the appropriate fields. In this case, (looking at an existing block) it appear there's one such field, a "VAR" field that contains an object with the id of the variable in question. 

Here is my code, showing some other attempts; theName is the desired name of the variable.

const newVarResult = await this.workspace.createVariable(theName);
let newBlock = this.workspace.newBlock('variables_set');
//const idObject = {"id" : newVarResult.id_};

newBlock.moveBy(222,111);  // maybe I have to move it??

//  newBlock.setFieldValue(idObject, 'VAR');  //  doesn't lik e this...            
newBlock.setFieldValue(newVarResult.id_, 'VAR');

It runs. It makes an ID. The new variable name will appear in the menus on a set block if you pull it out of the toolbox. But nothing appears in the workspace as a result of this code. ("where" gives me 0, 0).

Any help is welcome, including to a demo or example that does something like this.  

Thanks,
Tim


Beka Westberg

unread,
Feb 21, 2023, 11:18:31 AM2/21/23
to Blockly
Hello!

Confusingly, newBlock() doesn't actually initialize and render your block :/ You would need to change your code to look like the following:

```
const newBlock = this.workspace.newBlock('variables_set');
newBlock.initSvg();
newBlock.render();

// All of your other field settings etc...
```

However, I recommend against doing this because it's error prone, and is difficult to read. Instead I recommend using the JSON serialization system to append a new block to the workspace.

```
const newBlock = Blockly.serialization.blocks.append({
  'type': 'variables_set',
  'x': 222,
  'y': 111,
  'fields': {
    'VAR': {
      // Note: Do not use properties with underscores! They're private and can change at any time
      'id': newVarResult.getId(),
    }
  }
});
```

This will automatically initialize and render your block. And it keeps all of your field + position settings in one place =)

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

Tim Erickson

unread,
Feb 21, 2023, 3:02:53 PM2/21/23
to Blockly
OMG Beka, fantastic, and thanks for the extra tips. That it should be related to serialization makes perfect sense, although I had not even considered that.

Note: Originally, it didn't work, throwing an error into `math.js`. 
I did finally find the documentation (serialization is under namespaces, had no idea) and saw that the append() function requires two arguments, the second being the workspace. So the code that works looks like this:
```
const newVarResult = await this.workspace.createVariable(theName);

// make a "set" block appear in the workspace
const blockSpec = {

    'type': 'variables_set',
    'x': 222, 'y': 111,
    'fields': {
        'VAR': {
            'id': newVarResult.getId(),
        }
    }
}

const newlyCreatedBlock = Blockly.serialization.blocks.append(blockSpec, this.workspace);
```

If it's easy, I'm wondering: I put in the location for the new block originally in case (0,0) was hiding it behind the toolbox. Is there a way to have it appear where it would appear if you had drawn it out of the toolbox, or in some other suitable place?

A zillion thanks!

Beka Westberg

unread,
Feb 23, 2023, 11:34:24 AM2/23/23
to blo...@googlegroups.com
Hello =)

You can try to calculate a better position based on the viewport metrics. You probably want something like:

```
// This returns the metrics of the visible portion of the workspace in workspace coordinates.
const viewMetrics = myWorkspace.getMetricsManager().getViewMetrics(true);
```

Then you can either put your block in the middle of that, the top left, etc.

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

--
You received this message because you are subscribed to the Google Groups "Blockly" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blockly+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/blockly/867613a0-faca-48e0-9834-92705e36cc57n%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages