Custom icon example.

396 views
Skip to first unread message

Lynn Duke

unread,
Jul 16, 2023, 11:07:17 AM7/16/23
to Blockly
Hello! Just joined the group and glad to see so much activity. 

My goal:
To make a custom icon.

My blockly version:
10.0.1

I pieced the code example together from the docs (doesn't seem to be a full sample in the codebase).


Here's my custom WaitIcon class

class WaitIcon extends Blockly.icons.Icon {

getType() {
return new Blockly.icons.IconType('wait_icon');
}
getSize() {
return new Blockly.utils.Size(16, 16);
}
getWeight() {
return 10;
}
initView(pointerdownListener) {
if (this.svgRoot) return; // Already initialized.
// This adds the pointerdownListener to the svgRoot element.
// If you do not call `super` you must do this yourself.
super.initView(pointerdownListener);
Blockly.utils.dom.createSvgElement(
Blockly.utils.Svg.CIRCLE,
{
'class': 'my-css-class',
'r': '8',
'cx': '8',
'cy': '8',
},
this.svgRoot // Append to the svgRoot.
);
}
onClick() {
// Do something when clicked.
}
isShownWhenCollapsed() {
return true;
}
updateEditable() {
if (this.sourceBlock.isEditable()) {
// Do editable things.
} else {
// Do non-editable things.
}
}
updateCollapsed() {
// By default icons are hidden when the block is collapsed. We want it to
// be shown, so do nothing.
}

}
Blockly.icons.registry.register(
new Blockly.icons.IconType('wait_icon'), WaitIcon);


I haven't found a good example (the docs don't show either) on how I actually add the icon to a block. I'd like to do it in JSON, but managed to find the javascript method "addIcon".  It causes a crash. I've looked through Blockly repo for a couple of days on and off for examples but could use some help or guidance.

I have an 'image' block where you can see I call "addIcon"

This will result in an exception:
Uncaught TypeError: Cannot read properties of undefined (reading 'getSvgRoot') in line 49 of icon.ts in the Blockly code. "svgBlock" must be null I suppose. 

What am I missing when it comes to getting my icon to work? How can I do an icon in JSON block definition (if possible). Thank you!

Blockly.Blocks['image'] = {
init: function () {
this.appendDummyInput()
.appendField(
new Blockly.FieldDropdown(imageOptions, function (newVal) {
let imgField = this.sourceBlock_.getField('IMAGE')
if (imgField) {
imgField.setValue(newVal)
}
}),
'IMAGE_DROPDOWN'
)
.appendField(new Blockly.FieldImage('default_image.png', 75, 50, '*'), 'IMAGE')
this.setPreviousStatement(true, null)
this.setNextStatement(true, null)
this.setColour("#d25552")
this.setTooltip('')
this.addIcon(new WaitIcon())

},
}




Beka Westberg

unread,
Jul 16, 2023, 4:47:09 PM7/16/23
to blo...@googlegroups.com
Hello! I think the issue is probably that the default icon constructor requires you to pass the source block to the constructor so that the svg elements can be properly constructed!

So your `addIcon` call should look like: `this.addIcon(new WaitIcon(this));`. I've put in a correction to the docs that should go out sometime in the next few days =)

Wrt your question about adding icons via JSON, that is currently not supported! If it's important to you please feel welcome to file a feature request!

I hope that helps! If you have any further questions please reply! I'd also be super interested to learn what your custom "WaitIcon" is for if you're interested in sharing!

Best wishes,
--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/a140c8e3-0529-4aaa-9a57-5cbf312ba951n%40googlegroups.com.

Lynn Duke

unread,
Jul 16, 2023, 5:37:00 PM7/16/23
to Blockly
That worked! Thanks! Great response time. 

I am building a visual story telling engine. Each block can be awaited or not. For example, a block my perform an image transition for 2 seconds, and maybe I want to wait until the image is complete before doing something else. Or, maybe I DONT want to wait for image to complete and move on to the next block. 

I could have used another wait block to wrap statements but wanted to save on the nesting of blocks. I still might create a wait/nowait block to wrap several statement as an additional options. But wanted to get icons working. You helped me do that!

Max Stephen Russell

unread,
Mar 7, 2025, 10:54:39 AM3/7/25
to Blockly
This example looks very carefully done and pays close attention to the guide, apparently missing only the source block in the constructor call. And so far, it is the only true example I've seen. So I'd like to ask, is this a good example for me to emulate in my first attempt to create a custom icon and bubble for certain blocks, apart from comments?

-Steve

ewpa...@gmail.com

unread,
Mar 13, 2025, 3:57:53 PM3/13/25
to Blockly
Hi Steve,

We have an error icon class in App Inventor that also drove some of the work that went into the Icon class design. However, our build system is fairly old school so it may not be the best example for what you're trying to accomplish.

Cheers,
Evan

Max Stephen Russell

unread,
Mar 14, 2025, 11:11:01 AM3/14/25
to Blockly
Evan,

At the very least, it is instructional. I like stuff that is actually complete! So thank you very much, and I will be sure to study this file thoroughly.

-Steve

Reply all
Reply to author
Forward
0 new messages