Hi everyone, my name is Abby Schmiedt and I'm a software developer on the Blockly team.
In this presentation I'm going to be talking about the Blockly toolbox and some of our newer APIs.
So I'm going to go over a little background information on the
toolbox so you're aware of what features came out in what release.
Then I'm going to talk about how you can define a toolbox and the rest of the presentation is
really going to focus on how you can customize your toolbox to work for your application.
So in July 2019 we removed the closure UI library from Blockly. The toolbox still
used some of the components from that library so we ended up just copying those components
directly into Blockly Core. This is one of the reasons we decided to rewrite the toolbox.
In quarter two of 2020 we started rewriting the toolbox and in quarter three we released
the rewritten toolbox and support for defining the toolbox in JSON.
Most of the talk - most of this talk is going to be focused on the APIs that came out in that
September 2020 release of Blockly. And finally in November 2020 we released the continuous toolbox
in Blockly Samples which relies on the new toolbox that came out in the September 2020 release.
So now that we know when everything came out we're going to talk about the different
ways you can define a toolbox ,and we are specifically going into more information
on defining a toolbox using JSON. So there are two different kinds of toolboxes in Blockly.
There's the flyout toolbox and the category to box. The flyout toolbox can hold blocks,
buttons, and labels, and it's really great if you only have a small set of blocks.
The category toolbox allows you to break up a long list of blocks into different categories
You can find both of these toolboxes using XML. This is how toolboxes have always been defined
in the past so I'm going to gloss over this a bit. If you want more information on this
you can find it on our developer guide on the toolbox page and I'll add a link to that at
the end of this presentation. As of September 2020 you can also define a toolbox using JSON.
So for both the flyout and category toolbox you have a JSON object with a contents array.
In the case of flyout toolbox the contents array is filled with blocks, buttons,
and labels. In the case of a category toolbox the contents array is filled with categories,
and inside each category is another contents array which is filled with blocks, buttons, and labels.
So an important note for defining your toolbox using JSON - if you want to
define a more complex block with something like shadow blocks, you will need to use "blockxml"
key and give it an XML string of the block you are trying to define. So due to time
constraints when developing this we did not add the ability to build a block directly from JSON.
So what happens when you define "blockxml" is that we take that string, convert it to XML,
and then use that XML to create a block. It's this extra step of converting the string to XML that
causes a performance hit when you open a category with approximately 100 blocks defined this way.
So now you understand how to define the toolbox, we're going to go into more detail about how you
can customize your toolbox. So there are three main ways we expect someone to customize their
toolbox. The first is by using CSS; second is by overriding different methods on either the
toolbox class or either of the toolbox category classes; or by using a custom toolbox item.
So when we're doing the toolbox one of the main pain points people brought up
was that there was not a great way for them to add a custom CSS class
to their category. Users mainly wanted to be able to add different icons for each category
and this was often much more difficult than it should have been. So to remedy this we added
support for user to add their own CSS class to the category. In XML this can be done by
defining a "css--container" attribute. In JSON this can be done by creating a cssConfig object
with a container key and with the value of whatever class name that you want to add to your
category. More information on this can be found on our toolbox documentation page under category CSS.
The second way we expect someone to customize their toolbox is by creating their own toolbox
or toolbox category class and then overriding any specific methods. Instead of going through
every method on the toolbox into box category class I'm going to go over
different methods that we overrode when writing the continuous toolbox and what that resulted in.
So for those of you not familiar with the continuous toolbox, the continuous toolbox
is a custom toolbox with a single flyout that is always open. the user can click on the
category to scroll to a section of blocks or they can simply scroll through all the
blocks that are in the flyout. This can be found in our Blockly Samples as a plugin.
So the first method we're going to look at is setSelected on the toolbox category class.
So this method sets what the category looks like when it is selected.
In the case of our default toolbox we set the background color to the color of the category.
In the case of the continuous toolbox we set the background color to a darker shade of gray.
The next method we're going to look at is addColorBorder on the toolbox category class.
In the case of the default toolbox this creates the border you see
on the left hand side of the category. In the case of the continuous toolbox we actually
didn't want that border so we override - overrode addColorBorder to be nothing in this method.
So the final method we're going to look at is the getClientRect method on the toolbox.
In the previous two slides we were looking at different methods on the toolbox category class,
but here we are looking at a method that is actually on the toolbox class.
This method calculates the delete area for the toolbox and in the case of the continuous
toolbox we override this method and return the area of the toolbox plus the flyout. So this
allows blocks to be deleted - to be deleted when dragged over the flyout as well as the toolbox.
In the next section we'll be talking about adding custom toolbox items
so to start we're going to do a very quick demo showing how to add a simple label to the toolbox.
If you like to follow along there's a link to a starter project on this slide.
All right, so in this demo we're going to be creating a customToolboxItem that adds a label
to our toolbox. So there's two main files here that are important. The first one is index.js
and in this file we're just doing all the setup for the Blockly workspace. And the most important
part of this file is this toolbox definition here. So we're going to be modifying that later on.
So now if you go over to customToolboxItem, in here we're going to create our custom toolbox item
and so we're just going to create a class; ... I'm going to name it "customLabel"
and it's going to extend the Blockly.ToolboxItem.
All right, so now we're going to need to override the getDiv method and in this method we're just
going to return a label element that we want to get added to the toolbox. So I'm going to
create a label document.createElement label and then I'm going to set the text on it.
We're just gonna set it to "test1" and then I'm gonna return that label.
All right and so that's really all we're gonna do, um, with that class.
The next thing we're gonna do is we're gonna register this toolbox item.
So we're gonna call "Blockly.registry.register" and the first parameter we're going to give it
is the type that we're going to register. So it's going to be a toolbox item type. So
"Blockly.registry.Type.TOOLBOX_ITEM". All right so the next thing we're going to give it is the name.
So I'm just going to name this customLabel and we're going to be using that later on
when we add this uh toolbox item to our toolbox definition.
So the next thing we're going to give it is this class so customLabel
and the last value is TRUE. So all TRUE does is allow us to register another item with
the name customLabel and this is just for demo purposes um code sandbox the way it refreshes
the page this needs to be set to TRUE, but in your own project that might not be necessary.
So now we're going to go to index.js and in here I'm just going to add that toolbox item
that we just created, and so the kind I'm going to set to be category or sorry, "customLabel"
so now you see on the right hand side of the screen "test1" showed up
in our toolbox which is what we wanted. So now though if we want to create
another custom label with a different name we don't really have a great way to do that,
so what we're gonna do is we're gonna add a label here, and we're gonna give it a name "Test1"and
now in customToolboxItem we're going to use that value that I just set
through the toolbox item definition. So I'm going to call "this.toolboxItemDef_.label"
and so if you can see on the right hand side that got updated to test one but with a capital "T".
So if you go back to index.js we're going to create multiple labels and
then we're going to change that label value
that's gonna be "Test2" and so now we have different labels with different names.
So that was just really basic how to create a custom toolbox item
so hopefully now you have a better understanding of how to create a toolbox item. There are a few
different types of toolbox items that are supported. For items that don't need to be
interacted with, you can simply extend the toolbox item class like we did in the demo.
The best example of this in core is the toolbox separator. This is the
line between the color and variable category that I have highlighted in red on this slide.
The second kind of toolbox item is a selectable toolbox item. These are items that a user needs
to be able to interact with. The toolbox will render these items, select them when a user is
using the keyboard to navigate the toolbox, and call the onClick method on the item when
the item has been clicked. You can create a selectable toolbox item by implementing the
ISelectable toolbox item interface and returning true from the isSelectable method. If you want an
example of a selectable toolbox item you can look in the toolbox category class in core.
The third kind of toolbox item is a collapsible toolbox item.
These are items that hold other toolbox items. They do everything that a selectable toolbox
item does but will also collapse or expand when a user clicks on them
or uses the left and right arrows. You can create a collapsible toolbox item by implementing the
ICollapsible toolbox item interface and returning true from the isCollapsible
method. For an example of this in core you can look at the collapsible toolbox category.
For more information on customizing the toolbox please visit the Blockly Toolbox Codelab.
For more information on defining a toolbox please visit the developer guides. So thank
you - hopefully this helped you understand a little bit more about the newer toolbox APIs.