Kotak alat adalah tempat di mana pengguna mendapatkan blok. Biasanya ditampilkan di satu sisi ruang kerja. Terkadang memiliki kategori, dan terkadang tidak.
Halaman ini berfokus terutama pada cara menentukan struktur toolbox (yaitu kategori yang dimilikinya dan blok yang terdapat di dalamnya). Jika Anda ingin mengetahui detail selengkapnya tentang cara mengubah UI toolbox, lihat Menyesuaikan codelab toolbox Blockly dan pembicaraan API Toolbox 2021.
Format
Dengan Blockly, Anda dapat menentukan struktur toolbox menggunakan beberapa format yang berbeda. Format baru yang direkomendasikan menggunakan JSON, dan format lama menggunakan XML.
Berikut berbagai cara untuk menentukan toolbox di atas:
JSON
Mulai Toolbox rilis September 2020 dapat ditentukan menggunakan JSON.
var toolbox = {
"kind": "flyoutToolbox",
"contents": [
{
"kind": "block",
"type": "controls_if"
},
{
"kind": "block",
"type": "controls_whileUntil"
}
]
};
var workspace = Blockly.inject('blocklyDiv', {toolbox: toolbox});
XML
<xml id="toolbox" style="display: none">
<block type="controls_if"></block>
<block type="controls_whileUntil"></block>
</xml>
<script>
var workspace = Blockly.inject('blocklyDiv',
{toolbox: document.getElementById('toolbox')});
</script>
String XML
var toolbox = '<xml>' +
'<block type="controls_if"></block>' +
'<block type="controls_whileUntil"></block>' +
'</xml>';
var workspace = Blockly.inject('blocklyDiv', {toolbox: toolbox});
Kategori
Blok di toolbox dapat diatur dalam kategori.
Berikut adalah cara untuk menentukan toolbox di atas, yang memiliki dua kategori ('Control' dan 'Logic'), yang masing-masing berisi blok:
JSON
{
"kind": "categoryToolbox",
"contents": [
{
"kind": "category",
"name": "Control",
"contents": [
{
"kind": "block",
"type": "controls_if"
},
]
},
{
"kind": "category",
"name": "Logic",
"contents": [
{
"kind": "block",
"type": "logic_compare"
},
{
"kind": "block",
"type": "logic_operation"
},
{
"kind": "block",
"type": "logic_boolean"
}
]
}
]
}
XML
<xml id="toolbox" style="display: none">
<category name="Control">
<block type="controls_if"></block>
<category name="Logic">
<block type="logic_compare"></block>
<block type="logic_operation"></block>
<block type="logic_boolean"></block>
</category>
</xml>
Kategori bertingkat
Kategori dapat disusun bertingkat dalam kategori lain. Berikut adalah dua kategori level teratas ('Core' dan 'Kustom'), yang kedua berisi dua sub-kategori, yang masing-masing berisi blok:
Perhatikan bahwa kategori dapat berisi sub-kategori dan blok. Pada contoh di atas, 'Kustom' memiliki dua subkategori ('Pindahkan' dan 'Putar'), serta bloknya sendiri ('mulai').
JSON
{
"kind": "categoryToolbox",
"contents": [
{
"kind": "category",
"name": "Core",
"contents": [
{
"kind": "block",
"type": "controls_if"
},
{
"kind": "block",
"type": "logic_compare"
},
]
},
{
"kind": "category",
"name": "Custom",
"contents": [
{
"kind": "block",
"type": "start"
},
{
"kind": "category",
"name": "Move",
"contents": [
{
"kind": "block",
"type": "move_forward"
}
]
},
{
"kind": "category",
"name": "Turn",
"contents": [
{
"kind": "block",
"type": "turn_left"
}
]
}
]
}
]
}
XML
<xml id="toolbox" style="display: none">
<category name="Core">
<block type="controls_if"></block>
<block type="logic_compare"></block>
</category>
<category name="Custom">
<block type="start"></block>
<category name="Move">
<block type="move_forward"></block>
</category>
<category name="Turn">
<block type="turn_left"></block>
</category>
</category>
</xml>
Kategori dinamis
Kategori dinamis adalah kategori yang diisi ulang secara dinamis berdasarkan sebuah fungsi setiap kali dibuka.
Blockly mendukung hal ini dengan memungkinkan Anda mengaitkan kategori dengan fungsi melalui kunci string yang terdaftar. Fungsi ini akan menampilkan definisi konten kategori (termasuk blok, tombol, label, dll.). Konten dapat ditetapkan sebagai JSON atau XML, meskipun JSON direkomendasikan.
Perhatikan juga bahwa fungsi ini menyediakan ruang kerja target sebagai parameter, sehingga blok dalam kategori dinamis Anda dapat didasarkan pada status ruang kerja.
JSON
Mulai rilis September 2021, Anda dapat menentukan status blok tanpa
menggunakan 'blockxml'
.
// Returns an array of objects.
var coloursFlyoutCallback = function(workspace) {
// Returns an array of hex colours, e.g. ['#4286f4', '#ef0447']
var colourList = getPalette();
var blockList = [];
for (var i = 0; i < colourList.length; i++) {
blockList.push({
'kind': 'block',
'type': 'colour_picker',
'fields': {
'COLOUR': colourList[i]
}
});
}
return blockList;
};
// Associates the function with the string 'COLOUR_PALETTE'
myWorkspace.registerToolboxCategoryCallback(
'COLOUR_PALETTE', coloursFlyoutCallback);
JSON lama
Sebelum rilis September 2021, Anda harus menggunakan properti 'blockxml'
untuk
menentukan status blok.
// Returns an array of objects.
var coloursFlyoutCallback = function(workspace) {
// Returns an array of hex colours, e.g. ['#4286f4', '#ef0447']
var colourList = getPalette();
var blockList = [];
for (var i = 0; i < colourList.length; i++) {
blockList.push({
'kind': 'block',
'type': 'colour_picker', // Type is optional if you provide blockxml
'blockxml': '<block type="colour_picker">' +
'<field name="COLOUR">' + colourList[i] + '</field>' +
'</block>'
});
}
return blockList;
};
// Associates the function with the string 'COLOUR_PALETTE'
myWorkspace.registerToolboxCategoryCallback(
'COLOUR_PALETTE', coloursFlyoutCallback);
XML
// Returns an arry of XML nodes.
var coloursFlyoutCallback = function(workspace) {
// Returns an array of hex colours, e.g. ['#4286f4', '#ef0447']
var colourList = getPalette();
var blockList = [];
for (var i = 0; i < colourList.length; i++) {
var block = document.createElement('block');
block.setAttribute('type', 'colour_picker');
var field = document.createElement('field');
field.setAttribute('name', 'COLOUR');
field.innerText = colourList[i];
block.appendChild(field);
blockList.push(block);
}
return blockList;
};
// Associates the function with the string 'COLOUR_PALETTE'
myWorkspace.registerToolboxCategoryCallback(
'COLOUR_PALETTE', coloursFlyoutCallback);
Setelah fungsi kategori dinamis dikaitkan dengan kunci string (alias
terdaftar), Anda dapat menetapkan kunci string ini ke properti custom
dari
definisi kategori Anda untuk membuat kategori tersebut dinamis.
JSON
{
"kind": "category",
"name": "Colours",
"custom": "COLOUR_PALETTE"
}
XML
<category name="Colours" custom="COLOUR_PALETTE"></category>
Kategori dinamis bawaan
Blockly menyediakan tiga kategori dinamis bawaan.
'VARIABLE'
membuat kategori untuk variabel untyped.'VARIABLE_DYNAMIC'
membuat kategori untuk variabel berjenis. Alat ini memiliki tombol untuk membuat {i>string<i}, angka, dan warna.'PROCEDURE'
membuat kategori untuk blok fungsi.
JSON
{
"kind": "category",
"name": "Variables",
"custom": "VARIABLE"
},
{
"kind": "category",
"name": "Variables",
"custom": "VARIABLE_DYNAMIC"
},
{
"kind": "category",
"name": "Functions",
"custom": "PROCEDURE"
}
XML
<category name="Variables" custom="VARIABLE"></category>
<category name="Variables" custom="VARIABLE_DYNAMIC"></category>
<category name="Functions" custom="PROCEDURE"></category>
Catatan: Kata 'prosedur' digunakan di seluruh codebase Blockly, tetapi kata 'fungsi' dianggap lebih mudah dipahami oleh siswa. Kami mohon maaf atas ketidakcocokan ini.
Menonaktifkan
Kategori yang dinonaktifkan tidak akan mengizinkan pengguna untuk membuka kategori dan akan dilewati selama navigasi keyboard.
var category = toolbox.getToolboxItems()[0];
category.setDisabled('true');
Jika kategori dinonaktifkan, properti 'disabled'
ditambahkan ke elemen DOM,
yang memungkinkan Anda mengontrol tampilan kategori yang dinonaktifkan.
.blocklyToolboxCategory[disabled="true"] {
opacity: .5;
}
Menyembunyikan
Kategori tersembunyi tidak akan ditampilkan sebagai bagian dari toolbox. Kategori tersembunyi nantinya dapat ditampilkan melalui JavaScript.
JSON
{
"kind": "category",
"name": "...",
"hidden": "true"
}
XML
<category name="..." hidden="true"></category>
JavaScript
var category = toolbox.getToolboxItems()[0];
category.hide();
// etc...
category.show();
Meluaskan
Hal ini hanya berlaku untuk kategori yang berisi kategori bertingkat lainnya.
Kategori yang diperluas akan menampilkan sub-kategorinya. Secara default, kategori bertingkat diciutkan, dan perlu diklik agar dapat diperluas.
JSON
{
"kind": "category",
"name": "...",
"expanded": "true"
}
XML
<category name="..." expanded="true"></sep>
Gaya visual
Blockly menyediakan UI kategori default, dan di dalamnya beberapa opsi dasar untuk gaya visual. Jika Anda menginginkan informasi tentang cara melakukan penataan gaya/konfigurasi lanjutan lebih lanjut untuk UI, lihat Menyesuaikan codelab toolbox Blockly dan pembicaraan Toolbox API 2021.
Tema
Tema memungkinkan Anda menentukan semua warna ruang kerja Anda sekaligus, termasuk warna kategori.
Untuk menggunakannya, Anda harus mengaitkan kategori Anda dengan gaya kategori tertentu:
JSON
{
"kind": "category",
"name": "Logic",
"categorystyle": "logic_category"
}
XML
<category name="Logic" categorystyle="logic_category"></category>
Warna
Anda juga dapat menentukan warna secara langsung, tetapi hal ini tidak disarankan. Warna adalah angka string (0-360) yang menentukan hue. Perhatikan ejaan Inggris.
JSON
{
"contents": [
{
"kind": "category",
"name": "Logic",
"colour": "210"
},
{
"kind": "category",
"name": "Loops",
"colour": "120"
}
]
}
XML
<xml id="toolbox" style="display: none">
<category name="Logic" colour="210">...</category>
<category name="Loops" colour="120">...</category>
<category name="Math" colour="230">...</category>
<category name="Colour" colour="20">...</category>
<category name="Variables" colour="330" custom="VARIABLE"></category>
<category name="Functions" colour="290" custom="PROCEDURE"></category>
</xml>
Perhatikan bahwa kami juga mendukung penggunaan referensi warna yang dapat dilokalkan.
Kategori CSS
Jika Anda ingin penyesuaian yang lebih andal, Blockly juga memungkinkan Anda menentukan class CSS untuk berbagai elemen UI default. Anda kemudian dapat menggunakan CSS untuk menata gayanya.
Jenis elemen berikut dapat menerapkan class CSS:
- container - Class untuk div induk untuk kategori.
blocklyToolboxCategory
default. - baris - Kelas untuk div yang berisi label dan ikon kategori.
blocklyTreeRow
default. - ikon - Kelas untuk ikon kategori.
blocklyTreeIcon
default. - label - Kelas untuk label kategori.
blocklyTreeLabel
default. - selected - Class yang akan ditambahkan ke kategori saat dipilih.
blocklyTreeSelected
default. - openicon - Class yang ditambahkan ke ikon saat kategori memiliki kategori bertingkat
dan terbuka.
blocklyTreeIconOpen
default. - closeicon - Class yang ditambahkan ke ikon saat kategori memiliki kategori bertingkat
dan ditutup.
blocklyTreeIconClosed
default.
Berikut ini cara menentukan class menggunakan salah satu format:
JSON
Tetapkan class CSS jenis elemen tertentu menggunakan properti cssConfig.
{
"kind": "category",
"name": "...",
"cssConfig": {
"container": "yourClassName"
}
}
XML
Menyetel class CSS jenis elemen tertentu dengan menambahkan awalan 'css-'.
<category name="..." css-container="yourClassName"></category>
Mengakses
Ada dua cara untuk mengakses kategori secara terprogram. Anda dapat mengaksesnya berdasarkan indeks (dengan 0 adalah kategori teratas):
var category = toolbox.getToolboxItems()[0];
Atau berdasarkan ID:
var category = toolbox.getToolboxItemById('categoryId');
Dengan ID yang ditentukan dalam definisi toolbox:
JSON
{
"kind": "category",
"name": "...",
"toolboxitemid": "categoryId"
}
XML
<category name="..." toolboxitemid="categoryId"></category>
Blok Preset
Definisi toolbox dapat berisi blok yang kolomnya ditetapkan ke nilai default, atau memiliki blok yang sudah terhubung bersama.
Berikut ini empat blok:
- Blok
logic_boolean
sederhana tanpa nilai preset:
- Blok
math_number
yang telah diubah untuk menampilkan angka 42, bukan default 0:
- Blok
controls_for
yang memiliki tiga blokmath_number
yang terhubung dengannya:
- Blok
math_arithmetic
yang memiliki dua blok bayanganmath_number
yang terhubung dengannya:
Berikut adalah definisi toolbox yang berisi empat blok tersebut:
JSON
Mulai rilis September 2021, Anda dapat menentukan status blok tanpa
menggunakan 'blockxml'
.
{
"kind": "flyoutToolbox",
"contents": [
{
"kind": "block",
"type": "logic_boolean"
},
{
"kind": "block",
"type": "math_number",
"fields": {
"NUM": 42
}
},
{
"kind": "block",
"type": "controls_for",
"inputs": {
"FROM": {
"block": {
"type": "math_number",
"fields": {
"NUM": 1
}
}
},
"TO": {
"block": {
"type": "math_number",
"fields": {
"NUM": 10
}
}
},
"BY": {
"block": {
"type": "math_number",
"fields": {
"NUM": 1
}
}
},
}
},
{
"kind": "block",
"type": "math_arithmetic",
"fields": {
"OP": "ADD"
},
"inputs": {
"A": {
"shadow": {
"type": "math_number",
"fields": {
"NUM": 1
}
}
},
"B": {
"shadow": {
"type": "math_number",
"fields": {
"NUM": 1
}
}
}
}
},
]
}
JSON lama
Sebelum rilis September 2021, Anda harus menggunakan properti 'blockxml'
untuk
menentukan status blok.
{
"kind": "flyoutToolbox",
"contents": [
{
"kind": "block",
"type": "logic_boolean"
},
{
"kind": "block",
"blockxml":
'<block type="math_number">' +
'<field name="NUM">42</field>' +
'</block>'
},
{
"kind": "block",
"blockxml":
'<block type="controls_for">' +
'<value name="FROM">' +
'<block type="math_number">' +
'<field name="NUM">1</field>' +
'</block>' +
'</value>' +
'<value name="TO">' +
'<block type="math_number">' +
'<field name="NUM">10</field>' +
'</block>' +
'</value>' +
'<value name="BY">' +
'<block type="math_number">' +
'<field name="NUM">1</field>' +
'</block>' +
'</value>' +
'</block>'
},
{
"kind": "block",
"blockxml":
'<block type="math_arithmetic">' +
'<field name="OP">ADD</field>' +
'<value name="A">' +
'<shadow type="math_number">' +
'<field name="NUM">1</field>' +
'</shadow>' +
'</value>' +
'<value name="B">' +
'<shadow type="math_number">' +
'<field name="NUM">1</field>' +
'</shadow>' +
'</value>' +
'</block>'
},
]
}
XML
<xml id="toolbox" style="display: none">
<block type="logic_boolean"></block>
<block type="math_number">
<field name="NUM">42</field>
</block>
<block type="controls_for">
<value name="FROM">
<block type="math_number">
<field name="NUM">1</field>
</block>
</value>
<value name="TO">
<block type="math_number">
<field name="NUM">10</field>
</block>
</value>
<value name="BY">
<block type="math_number">
<field name="NUM">1</field>
</block>
</value>
</block>
<block type="math_arithmetic">
<field name="OP">ADD</field>
<value name="A">
<shadow type="math_number">
<field name="NUM">1</field>
</shadow>
</value>
<value name="B">
<shadow type="math_number">
<field name="NUM">1</field>
</shadow>
</value>
</block>
</xml>
Menuliskan definisi ini secara manual bisa membuat... Sebagai gantinya, Anda dapat memuat blok Anda ke ruang kerja, lalu menjalankan kode berikut untuk mendapatkan definisinya. Panggilan ini berfungsi karena toolbox menggunakan format yang sama untuk blok dengan sistem serialisasi.
JSON
console.log(Blockly.serialization.workspaces.save(Blockly.getMainWorkspace()));
XML
console.log(Blockly.Xml.workspaceToDom(Blockly.getMainWorkspace()));
Anda juga dapat menghapus properti x
, y
, dan id
karena properti tersebut diabaikan
oleh toolbox.
Blok bayangan
Blok bayangan adalah blok placeholder yang melakukan beberapa fungsi:
- Kode tersebut menunjukkan nilai default untuk blok induknya.
- Keduanya memungkinkan pengguna untuk mengetik nilai secara langsung tanpa perlu mengambil blok angka atau string.
- Tidak seperti blok biasa, mereka akan diganti jika pengguna meletakkan blok di atasnya.
- Mereka menginformasikan pengguna tentang jenis nilai yang diharapkan.
Blok yang dinonaktifkan
Blok yang dinonaktifkan tidak dapat ditarik dari toolbox. Pemblokiran dapat dinonaktifkan
satu per satu menggunakan properti disabled
opsional.
JSON
{
"kind": "flyoutToolbox",
"contents": [
{
"kind": "block",
"type":"math_number"
},
{
"kind": "block",
"type": "math_arithmetic"
},
{
"kind": "block",
"type": "math_single",
"disabled": "true"
}
]
}
XML
<xml id="toolbox" style="display: none">
<block type="math_number"></block>
<block type="math_arithmetic"></block>
<block type="math_single" disabled="true"></block>
</xml>
Anda juga dapat menonaktifkan atau mengaktifkan pemblokiran secara terprogram menggunakan setEnabled
.
Kolom variabel
Kolom variabel mungkin perlu ditentukan secara berbeda saat berada di toolbox vs saat hanya diserialisasi.
Secara khusus, saat kolom variabel biasanya diserialisasi ke JSON, kolom tersebut hanya berisi ID variabel yang diwakilinya, karena nama dan jenis variabel diserialisasi secara terpisah. Namun, toolbox tidak berisi informasi tersebut, sehingga harus dimasukkan dalam bidang variabel secara langsung.
{
"kind": "flyoutToolbox",
"content": [
{
"type": "controls_for",
"fields": {
"VAR": {
"name": "index",
"type": "Number"
}
}
}
]
}
Pemisah
Menambahkan pemisah di antara dua kategori akan membuat garis dan ruang ekstra di antara dua kategori tersebut.
Anda dapat mengubah class untuk pemisah di definisi toolbox JSON atau XML.
JSON
{
"kind": "sep",
"cssConfig": {
"container": "yourClassName"
}
}
XML
<sep css-container="yourClassName"></sep>
Menambahkan pemisah di antara dua blok akan membuat jarak di antara blok. Secara default, setiap blok dipisahkan dari tetangganya yang lebih rendah sebesar 24 piksel. Pemisahan ini dapat diubah menggunakan atribut 'gap', yang akan menggantikan gap default.
Hal ini memungkinkan Anda membuat grup blok yang logis di toolbox.
JSON
{
"kind": "flyoutToolbox",
"contents": [
{
"kind": "block",
"type":"math_number"
},
{
"kind": "sep",
"gap": "32"
},
{
"kind": "block",
"blockxml": "<block type='math_arithmetic'><field name='OP'>ADD</field></block>"
},
{
"kind": "sep",
"gap": "8"
},
{
"kind": "block",
"blockxml": "<block type='math_arithmetic'><field name='OP'>MINUS</field></block>"
}
]
}
XML
<xml id="toolbox" style="display: none">
<block type="math_number"></block>
<sep gap="32"></sep>
<block type="math_arithmetic">
<field name="OP">ADD</field>
</block>
<sep gap="8"></sep>
<block type="math_arithmetic">
<field name="OP">MINUS</field>
</block>
</xml>
Tombol dan Label
Anda dapat meletakkan tombol atau label di mana pun Anda dapat menempatkan blok dalam toolbox.
JSON
{
"kind": "flyoutToolbox",
"contents": [
{
"kind": "block",
"type":"logic_operation"
},
{
"kind": "label",
"text": "A label",
"web-class": "myLabelStyle"
},
{
"kind": "label",
"text": "Another label"
},
{
"kind": "block",
"type": "logic_negate"
},
{
"kind": "button",
"text": "A button",
"callbackKey": "myFirstButtonPressed"
},
{
"kind": "block",
"type": "logic_boolean"
}
]
}
XML
<xml id="toolbox" style="display: none">
<block type="logic_operation"></block>
<label text="A label" web-class="myLabelStyle"></label>
<label text="Another label"></label>
<block type="logic_negate"></block>
<button text="A button" callbackKey="myFirstButtonPressed"></button>
<block type="logic_boolean"></block>
</xml>
<style>
.myLabelStyle>.blocklyFlyoutLabelText {
font-style: italic;
fill: green;
}
</style>
Anda dapat menentukan nama kelas CSS untuk diterapkan pada tombol atau label. Dalam contoh di atas, label pertama menggunakan gaya kustom, sedangkan label kedua menggunakan gaya default.
Tombol harus memiliki fungsi callback; label tidak boleh. Untuk menetapkan callback bagi klik tombol tertentu, gunakan
yourWorkspace.registerButtonCallback(yourCallbackKey, yourFunction).
Fungsi Anda akan menerima tombol yang diklik sebagai argumen. Tombol "Buat variabel..." dalam kategori variabel adalah contoh yang baik untuk tombol dengan callback.
Mengubah Toolbox
Aplikasi dapat mengubah blok yang tersedia di toolbox kapan saja dengan satu panggilan fungsi:
workspace.updateToolbox(newTree);
Seperti yang terjadi selama konfigurasi awal, newTree
dapat berupa hierarki node, representasi string, atau objek JSON. Satu-satunya batasan adalah
mode tidak dapat diubah; yaitu jika ada kategori di
toolbox yang pertama kali ditentukan, toolbox baru juga harus memiliki kategori
(meskipun kategorinya dapat berubah). Demikian pula, jika {i>toolbox<i} yang pertama ditentukan
tidak memiliki kategori apa pun, maka {i>toolbox<i} baru mungkin tidak memiliki kategori.
Konten dari satu kategori dapat diperbarui dengan:
var category = workspace.getToolbox().getToolboxItems()[0];
category.updateFlyoutContents(flyoutContents);
Dalam hal ini, flyoutContents dapat berupa daftar blok yang ditentukan menggunakan JSON, pohon node, atau representasi string.
Perlu diketahui bahwa saat ini mengupdate toolbox menyebabkan beberapa kali reset UI kecil:
- Dalam {i>toolbox<i} tanpa kategori, bidang apa pun yang diubah oleh pengguna (seperti {i>dropdown)<i} akan dikembalikan ke {i>default<i}.
Berikut adalah demo langsung hierarki dengan kategori dan grup blok.