1. 创建ToolBox
要创建一个ToolBox非常简单,只需要在定义workspace的时候进行设置即可。
var workspace = Blockly.inject(blocklyDiv, {
media: 'blockly/media/',
toolbox: document.getElementById('toolbox'), // 定义ToolBox
});
但在此之前,需要先定义ToolBox。ToolBox由<xml></xml>
标签定义。下面的代码展示了如何定义一个toolbox,其中id
属性用于查找该xml元素。
// 定义toolbox
<xml id="toolbox" style="display: none;">
<block type="controls_if"></block>
</xml>
2. 嵌套目录
<category>
标签可以进行嵌套实现多级目录。
<xml id="toolbox" style="display: none;">
<category name="一级目录1">
<block type="controls_if"></block>
</category>
<category name="一级目录2">
<category name="二级目录1">
<block type="controls_if"></block>
</category>
<category name="二级目录2">
<block type="controls_if"></block>
</category>
</category>
</xml>
多级目录的ToolBox
要注意,在根目录中,不能同时存在<category>
标签和<block>
标签。
// 以下是错误的ToolBox定义
<xml id="toolbox" style="display: none;">
<block type="controls_if"></block>
<category name="一级目录1">
<block type="controls_if"></block>
</category>
</xml>
3.分割线
用<sep></sep>
标签对可以在ToolBox目录之间加入分割线,效果如下:
<xml id="toolbox" style="display: none;">
<category name="一级目录1">
<block type="controls_if"></block>
</category>
<sep></sep>
<category name="一级目录2">
<category name="二级目录1">
<block type="controls_if"></block>
</category>
<category name="二级目录2">
<block type="controls_if"></block>
</category>
</category>
</xml>
分割线
如果将<sep></sep>
放在<block>
标签之间,则可以通过gap属性定义两个block之间的间隔,单位为px,默认情况下这个值为24,下面的代码将间隔分别改为40和5。
<xml id="toolbox" style="display: none;">
<category name="一级目录1">
<block type="controls_if"></block>
<sep gap="40"></sep>
<block type="controls_if"></block>
<sep gap="5"></sep>
<block type="controls_if"></block>
</category>
</xml>
改变模块间隔
4.在ToolBox中加入模块组
在ToolBox定义中,可以通过<field>
和<value>
在模块中嵌入其他模块,形成模块组,用这个功能可以将经常组合使用的模块直接放在ToolBox中。至于在下面的代码中,什么时候用value标签,什么时候用field标签,为什么name叫"IF0","A","B",这与模块的定义有关,我会在后面关于模块定义的部分讲解。
<xml id="toolbox" style="display: none;">
<block type="controls_if">
<value name="IF0">
<block type="logic_operation">
<value name="A">
<block type="logic_boolean">
<field name="BOOL">TRUE</field>
</block>
</value>
<value name="B">
<block type="logic_boolean">
<field name="BOOL">FALSE</field>
</block>
</value>
</block>
</value>
</block>
</xml>
模块组
5. 在ToolBox中加入文字和按键
用label
和button
标签可以给ToolBox添加文字和按键,通过text属性,可以设置他们显示的文字内容,通过web-class属性,你还可以自定义他们的样式。下面代码展示了如何使用它们:
<xml id="toolbox" style="display: none;">
<label text="a label" web-class="labelStyle"></label>
<button text="a button" web-class="buttonStyle"></button>
</xml>
<style>
.labelStyle>.blocklyFlyoutLabelText {
font-style: italic;
fill: blue;
}
.buttonStyle {
font-style: italic;
fill: red;
}
</style>
自定义文字和按键
另外,按键需要指定一个回调函数。button
标签的callbackKey属性可以定义点击按键时的回调函数。同时,需要用registerButtonCallback函数将callbackKey和回调函数关联起来。
<xml id="toolbox" style="display: none;">
<button text="a button" callbackKey="buttonKey"></button>
</xml>
<script>
//生成模块列表区域
var blocklyDiv = document.getElementById('blocklyDiv');
var workspace = Blockly.inject(blocklyDiv, {
media: 'blockly/media/',
toolbox: document.getElementById('toolbox'),
});
//调整工作区域大小
var onresize = function (e) {
Blockly.svgResize(workspace);
};
//注册resize处理函数
window.addEventListener('resize', onresize, false);
Blockly.svgResize(workspace);
// 注册回调函数
workspace.registerButtonCallback("buttonKey", callback);
// 定义回调函数
function callback() {
console.log("a button pressed");
}
</script>
点击button时,将调用callback函数。
6. 改变ToolBox
workspace的ToolBox属性可以通过workspace.updateToolbox()
函数动态改变。它接受一个参数,可以是节点树或者合法的定义字符串。
当更新ToolBox时,有一个限制必须要注意。我们之前说过,在第一级中,目录和模块是不能共存的。如果旧的ToolBox第一级是目录,那么新的ToolBox也必须是目录,反之亦然。
7. 动态目录
之前我们定义的目录都是静态的,每个目录下面的元素,在最开始就已经确定了。为了使ToolBox更加灵活,Blockly提供了动态改变目录的功能,最典型的比如变量和函数这两个目录,里面的模块数量和类型会根据当前已经定义的变量和函数动态变化。
<!-- 变量与函数目录 -->
<category name="Variables" custom="VARIABLE"></category>
<category name="Functions" custom="PROCEDURE"></category>
要定义一个动态的目录只需要3步:
a. 在ToolBox中定义一个目录,并用custom属性设置一个名字。
<category name="myCategory" custom="MY_CATEGORY"></category>
b. 定义一个函数用于动态生成目录下的内容。这个函数在每次目录被点击展开时调用,它必须接收一个workspace参数,并且返回一个模块/目录节点树列表,Blockly会将列表中的模块/目录按照顺序放在目录下。
myCategoryFlyoutCallback = function(workspace) {
// 通过workspace,你可以访问到当前工作空间下的所有数据,你也可以修改workspace。
var xmlList = [];
// 根据workspace中的数据,生成模块/目录节点并填充xmlList
return xmlList; // 返回xmlList
};
c. 注册目录生成函数,将前两步中定义的内容关联起来。
workspace.registerToolboxCategoryCallback('MY_CATEGORY', myCategoryFlyoutCallback);
来源:CSDN
作者:wolf131721
链接:https://blog.csdn.net/wolf131721/article/details/103896546