Blockly开发3 -- 创建工具栏ToolBox

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中加入文字和按键

labelbutton标签可以给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);

 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值