定義塊
塊定義描述了塊的外觀和行爲,包括文本,顏色,形狀以及它可以連接的其他塊。
定義自定義塊後,每個平臺都會以不同的方式加載這些定義,詳細信息請參見 網絡和 Android特定配置指南。
JSON格式與JavaScript API
Blockly有兩種定義塊的方式:JSON對象和JavaScript函數。JSON格式是跨平臺的,因此可以使用相同的代碼在Web,Android和iOS上定義塊。此外,JSON格式旨在在開發具有不同單詞順序的語言時簡化本地化過程。JSON格式是定義塊的首選方法。
但是,JSON格式無法直接定義高級功能,例如變異器或驗證器。這些必須以平臺的本機代碼,JavaScript,Java或Swift編寫,通常作爲 擴展。
使用Blockly的原始JavaScript實現的應用程序也可以直接將塊定義寫入較低級別的Blockly API函數調用,如下面的各種JavaScript示例所示。
//javascript
Blockly.Blocks['string_length'] = {
init: function() {
this.appendValueInput('VALUE')
.setCheck('String')
.appendField('length of');
this.setOutput(true, 'Number');
this.setColour(160);
this.setTooltip('Returns number of letters in the provided text.');
this.setHelpUrl('http://www.w3schools.com/jsref/jsref_length_string.asp');
}
};
//json
{
"type": "string_length",
"message0": 'length of %1',
"args0": [
{
"type": "input_value",
"name": "VALUE",
"check": "String"
}
],
"output": "Number",
"colour": 160,
"tooltip": "Returns number of letters in the provided text.",
"helpUrl": "http://www.w3schools.com/jsref/jsref_length_string.asp"
}
兩個示例均加載相同的“ string_length”塊。
在Web上,使用initJson
函數加載JSON格式。這也允許將兩種格式混合在Blockly網頁中。最好在可能的情況下使用JSON定義您的塊,並且僅將JavaScript用於JSON不支持的部分塊定義。
以下是一個塊的示例,該塊主要使用JSON定義,但使用JavaScript API進行了擴展,以提供動態工具提示。
var mathChangeJson = {
"message0": "change %1 by %2",
"args0": [
{"type": "field_variable", "name": "VAR", "variable": "item", "variableTypes": [""]},
{"type": "input_value", "name": "DELTA", "check": "Number"}
],
"previousStatement": null,
"nextStatement": null,
"colour": 230
};
Blockly.Blocks['math_change'] = {
init: function() {
this.jsonInit(mathChangeJson);
// Assign 'this' to a variable for use in the tooltip closure below.
var thisBlock = this;
this.setTooltip(function() {
return 'Add a number to variable "%1".'.replace('%1',
thisBlock.getFieldValue('VAR'));
});
}
};
Block colour
塊的主顏色由JSON colour屬性block.setColour(..)函數定義,或者通過使用主題和定義塊樣式來定義。
//JSON
{
// ...,
"colour": 160,
}
//javascript
init: function() {
// ...
this.setColour(160);
}
有關詳細信息,請參閱塊顏色指南。
Statement Connections (塊連接)
用戶可以使用nextStatement和previousStatement連接器創建塊序列。在Blockly的標準佈局中,這些連接位於頂部和底部,塊垂直堆疊。
帶有前一個連接器的塊不能有輸出連接器,反之亦然。語句塊是指沒有值輸出的塊。語句塊通常同時具有前一個連接和下一個連接。
可以鍵入nextStatement和previousStatement連接,但標準塊不使用此功能。
Next Connection (向下連接)
在塊的底部創建一個點,以便其他語句可以堆疊在它的下面。具有下一個連接但沒有上一個連接的塊通常表示一個事件,並且可以配置爲使用hat呈現。
// JSON
Untyped:
{
...,
"nextStatement": null,
}
Typed (rare):
{
"nextStatement": "Action",
...
}
//javascript
Untyped:
this.setNextStatement(true); // false implies no next connector, the default
Typed (rare):
this.setNextStatement(true, 'Action');
Previous Connection (向上連接)
在塊的頂部創建槽口,以便它可以作爲語句堆棧連接。
具有先前連接的塊不能有輸出連接。
//JSON
Untyped:
{
...,
"previousStatement": null,
}
Typed (rare):
{
"previousStatement": "Action",
...
}
//javascript
Untyped:
this.setPreviousStatement(true); // false implies no previous connector, the default
Typed (rare):
this.setPreviousStatement(true, 'Action');
Block Output (塊輸出)
塊可以具有單個輸出,表示爲前緣上的公拼圖連接器。輸出連接到值輸入。具有輸出的塊通常稱爲值塊。
//JSON
Untyped:
{
// ...,
"output": null,
}
Typed:
{
// ...,
"output": "Number",
}
//javascript
Untyped:
init: function() {
// ...
this.setOutput(true);
}
Typed:
init: function() {
// ...
this.setOutput(true, 'Number');
}
帶有輸出連接器的塊也不能有前一個語句槽。
Block Inputs
一個塊有一個或多個輸入,其中每個輸入是可能以連接結束的標籤和字段序列。有三種輸入類型,與連接類型匹配:
Value input:連接到值塊的輸出連接。math_算術塊(加法、減法)是具有兩個值輸入的塊的示例。
Statement input:連接到語句塊的前一個連接。while循環的嵌套部分是語句輸入的一個示例。
Dummy input:沒有塊連接。當塊被配置爲使用外部值輸入時,其行爲類似於換行符。
JSON格式和JavaScript API使用稍微不同的模型來描述它們的輸入。
Inputs and Fields in JSON
JSON定義的塊被構造爲一個插值消息字符串序列(message0、message1,…),其中每個插值標記(%1、%2,…)是匹配的JSON argsN數組中的字段或輸入端(因此,在消息中輸入連接器呈現)。這種格式旨在使國際化變得容易。
{
"message0": "set %1 to %2",
"args0": [
{
"type": "field_variable",
"name": "VAR",
"variable": "item",
"variableTypes": [""]
},
{
"type": "input_value",
"name": "VALUE"
}
]
}
插值標記必須與args0數組完全匹配:無重複,無遺漏。標記可以以任何順序出現,這允許不同的語言更改塊的佈局。
插值標記兩邊的文本將被空格修剪。使用字符的文本(例如,當引用百分比時)應使用%%,這樣它就不會被解釋爲插值標記。
參數的順序和參數類型定義塊的形狀。更改其中一個字符串可以完全更改塊的佈局。這在語序與英語不同的語言中尤爲重要。假設有一種語言,其中“set%1 to%2”(如上面的例子中所使用的)需要顛倒過來,表示“put%2 in%1”。更改這一個字符串(並保持JSON的其餘部分不變)將導致以下塊:
塊自動改變字段的順序,創建一個虛擬輸入,並從外部輸入切換到內部輸入。
Args
每個消息字符串都與一個相同編號的args數組配對。例如,message0
與args0一起使用。插值標記(%1、%2,…)引用args數組的項。每個對象都有一個類型字符串。其餘參數因類型而異:
每個對象也可能有alt字段。如果Blockly無法識別對象的類型,則使用alt對象代替它。例如,如果將名爲field_time的新字段添加到Blockly,則使用此字段的塊可以使用alt爲Blockly的舊版本定義field_input fallback:
{
"message0": "sound alarm at %1",
"args0": [
{
"type": "field_time",
"name": "TEMPO",
"hour": 9,
"minutes": 0,
"alt":
{
"type": "field_input",
"name": "TEMPOTEXT",
"text": "9:00"
}
}
]
}
alt對象可能有自己的alt對象,因此允許鏈接。最後,如果Blockly無法在args0數組中創建對象(在嘗試任何alt對象之後),則只跳過該對象。
如果消息字符串以不包含在輸入中的文本或字段結尾,則將自動在塊的末尾添加一個僞輸入。因此,如果塊上的最後一個輸入是僞輸入,則可以從args數組中省略它,並且不需要在消息中插入。自動添加拖尾僞輸入允許轉換器更改消息,而無需修改JSON的其餘部分。請參閱本頁前面的“將%1設置爲%2”(無僞輸入)和“將%2放入%1”(添加了僞輸入)示例。
lastDummyAlign0
在極少數情況下,自動創建的尾部僞輸入需要與“右”或“中心”對齊。如果未指定,則默認值爲“左”。
在下面的示例中,message0
is "send email to %1 subject %2 secure %3"
,併爲第三行自動添加一個虛擬輸入。將lastDummyAlign0設置爲“RIGHT”將強制此行右對齊。
在爲RTL(阿拉伯語和希伯來語)設計塊時,左右顛倒。因此,“RIGHT”將字段與左邊對齊。
message1
, args1
, lastDummyAlign1
有些區塊自然分成兩個或多個獨立的部分。考慮這個重複塊,它有兩行:
如果用單個消息描述此塊,則message0屬性將爲“repeat %1次%2執行%3”。這個字符串對於翻譯來說很難理解,很難解釋%2替換意味着什麼。在某些語言中甚至可能不需要%2僞輸入。可能有多個塊希望共享第二行的文本。一種更好的方法是JSON使用多個消息和args屬性:
{
"type": "controls_repeat_ext",
"message0": "repeat %1 times",
"args0": [
{"type": "input_value", "name": "TIMES", "check": "Number"}
],
"message1": "do %1",
"args1": [
{"type": "input_statement", "name": "DO"}
],
"previousStatement": null,
"nextStatement": null,
"colour": 120
}
任何數量的消息、參數和lastDummyAlign屬性都可以用JSON格式定義,從0開始並按順序遞增。請注意,塊工廠不能將消息拆分爲多個部分,但手動執行此操作非常簡單。
Inputs and Fields in JavaScript
JavaScript API爲每個輸入類型都包含一個append方法:
this.appendDummyInput()
.appendField('for each')
.appendField('item')
.appendField(new Blockly.FieldVariable());
this.appendValueInput('LIST')
.setCheck('Array')
.setAlign(Blockly.ALIGN_RIGHT)
.appendField('in list');
this.appendStatementInput('DO')
.appendField('do');
每個方法都可以採用由代碼生成器使用的標識符字符串。虛擬輸入很少需要引用,標識符通常不設置。
如上所示,每個方法都通過方法鏈返回要配置的輸入對象。有三個功能用於配置輸入。
setCheck
input.setCheck('Number');
此可選功能用於連接輸入的類型檢查。如果給定的參數爲null(默認值),則此輸入可以連接到任何塊。有關詳細信息,請參見類型檢查。
setAlign
input.setAlign(Blockly.ALIGN_RIGHT);
此可選功能用於對齊字段(請參見下文)。有三個自描述性值可以作爲參數傳遞給此函數:Blockly.ALIGN_LEFT、Blockly.ALIGN_RIGHT和Blockly.ALIGN_CENTRE。注意“center”的英國拼寫。默認爲左對齊。
在爲RTL(阿拉伯語和希伯來語)設計塊時,左右顛倒。因此Blockly.ALIGN_RIGHT會將字段左對齊。
appendField
一旦創建了輸入並將其附加到帶有append input的塊中,就可以選擇將任意數量的字段附加到輸入中。這些字段通常用作描述每個輸入的用途的標籤。
input.appendField('hello');
最簡單的字段元素是文本。Blockly的慣例是使用所有小寫文本,但專有名稱除外(例如Google、SQL)。
輸入行可以包含任意數量的字段元素。可以將多個appendField調用鏈接在一起,以便有效地將多個字段添加到同一輸入行。
input.appendField('hello')
.appendField(new Blockly.FieldLabel('Neil', 'person'));
appendField('hello')調用實際上是使用顯式FieldLabel構造函數的快捷方式:appendField(new Blockly.FieldLabel('hello'))。只有在指定類名時才希望使用構造函數,以便可以使用CSS規則對文本進行樣式設置。
Inline vs. External
塊輸入可以呈現爲外部或內部。
塊定義可以指定可選的布爾值,以控制輸入是否內聯。如果爲false,則任何值輸入都將是外部的(例如左塊)。如果爲true,則任何值輸入都將內聯(如上面的右塊)。
//json
{
// ...,
"inputsInline": true
}
//javascript
init: function() {
// ...
this.setInputsInline(true);
}
如果沒有定義,那麼Blockly將使用一些啓發式方法來猜測哪種模式是最好的。假設Blockly做出了正確的選擇,最好不定義這個字段,因爲不同的語言翻譯可以自動具有不同的模式。請參閱本頁前面的JSON示例“將%1設置爲%2”(外部輸入)和“將%2放入%1”(內聯輸入)。
當塊可能有小的輸入(如數字)時,使用內聯輸入。如果啓用摺疊配置(如果工具箱具有類別,則默認爲true),則用戶可以通過上下文菜單切換此選項。
Fields
字段定義塊中的UI元素。其中包括字符串標籤、圖像和文本數據(如字符串和數字)的輸入。最簡單的例子是math_number塊,可以是field_input(web)或field_number(Android)來輸入數字。
Blockly提供了許多內置字段,包括文本輸入、顏色選擇器和圖像。也可以創建自己的字段。
有關 built-in fields.的更多信息。
有關creating custom fields.的詳細信息。
Tooltips
當用戶將鼠標懸停在塊上時,工具提示提供即時幫助。如果文本很長,它將自動換行。
//json
{
// ...,
"tooltip": "Tooltip text."
}
//javascript
init: function() {
this.setTooltip("Tooltip text.");
}
在JavaScript API中,工具提示也可以定義爲函數而不是靜態字符串。這允許動態幫助。有關工具提示的示例,請參見math_算術,該工具提示會根據選擇的下拉選項而更改。
Blockly.Blocks['math_arithmetic'] = {
init: function() {
// ...
// Assign 'this' to a variable for use in the tooltip closure below.
var thisBlock = this;
this.setTooltip(function() {
var mode = thisBlock.getFieldValue('OP');
var TOOLTIPS = {
'ADD': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_ADD,
'MINUS': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_MINUS,
'MULTIPLY': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_MULTIPLY,
'DIVIDE': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_DIVIDE,
'POWER': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_POWER
};
return TOOLTIPS[mode];
});
}
};
使用JavaScript API,塊可以指定一個函數,而不是返回工具提示字符串的靜態字符串。這允許動態工具提示。例如,參見數學。
Help URL
塊可以具有與其關聯的幫助頁。Blockly for Web的用戶可以通過右鍵單擊該塊並從上下文菜單中選擇“幫助”來使用它。如果此值爲空,則菜單將灰顯。
//JSON
{
// ...,
"helpUrl": "https://en.wikipedia.org/wiki/For_loop"
}
//javascript
init: function() {
// ...
this.setHelpUrl('https://en.wikipedia.org/wiki/For_loop');
}
使用JavaScript API,塊可以指定一個函數,而不是返回URL字符串的靜態字符串,從而允許動態幫助。
Change Listeners and Validators
塊可以具有對工作區的任何更改(包括與塊無關的更改)調用的更改偵聽器函數。它們主要用於設置塊的警告文本或工作區外的類似用戶通知。
通過使用函數調用setOnChange來添加該函數,如果計劃在所有平臺上使用它,則可以在init期間或通過JSON擴展來完成。
//JSON
{
// ...,
"extensions":["warning_on_change"],
}
Blockly.Extensions.register('warning_on_change', function() {
// Example validation upon block change:
this.setOnChange(function(changeEvent) {
if (this.getInput('NUM').connection.targetBlock()) {
this.setWarningText(null);
} else {
this.setWarningText('Must have an input block.');
}
});
});
//javascript
Blockly.Blocks['block_type'] = {
init: function() {
// Example validation upon block change:
this.setOnChange(function(changeEvent) {
if (this.getInput('NUM').connection.targetBlock()) {
this.setWarningText(null);
} else {
this.setWarningText('Must have an input block.');
}
});
}
}
系統調用函數,傳遞change事件。在函數內部,這指的是塊實例。
因爲函數是在任何更改時調用的,如果使用,開發人員應該確保監聽器快速運行。還應該注意對工作區的更改,這些更改可能會層疊或循環回偵聽器。
有關示例,請參閱controls_flow_statements、logic_compare和procedures_ifreturn塊。
請注意,可編輯字段有自己的事件偵聽器,用於輸入驗證併產生副作用。
Mutator
變異器允許高級塊更改形狀,特別是當用戶打開一個對話框來添加、刪除或重新排列組件時。可以使用mutator鍵通過JSON添加mutator。
{
// ...,
"mutator":"if_else_mutator"
}
Per-block configuration
塊實例具有許多屬性,可配置它們對用戶的行爲方式。它們可以用來約束工作區以反映域的某些屬性(例如,只有一個“開始”事件),或者集中用戶的精力(例如,教程)。
Deletable State
默認情況下,用戶可以刪除可編輯工作區(而不是隻讀)上的任何塊。有時,使某些塊成爲永久性固定裝置是有用的。例如,教程框架代碼。
block.setDeletable(false);
任何塊,包括那些標記爲不可刪除的塊,都可以通過編程方式刪除:
block.dispose();
Editable State
block.setEditable(false);
當設置爲false時,用戶將無法更改塊的字段(例如下拉列表和文本輸入)。塊在可編輯工作空間上默認爲可編輯。
Movable State
block.setMovable(false);
當設置爲false時,用戶將無法直接移動塊。作爲另一個塊的子塊的不可移動塊不能從該塊斷開,儘管如果父塊被移動,它將與其父塊一起移動。
塊默認爲在可編輯工作空間上可移動。
任何塊(甚至是不可移動的塊)一旦在工作區上,就可以通過編程方式移動。在JavaScript中,調用block.moveBy(dx,dy)。除非另有指定,否則工作區上塊的起始位置默認爲(0,0)。
Block data (web only)
this.data = '16dcb3a4-bd39-11e4-8dfc-aa07a5b093db'; // Web only
數據是附加到塊的可選任意字符串。當保存爲XML時,數據字符串存儲在一個<data></data>標記中,以便它可以往返返回到一個塊。使用數據字符串將塊與外部資源關聯或用於任何其他自定義目的。
請注意,如果塊被複制或複製/粘貼,則數據字符串也會被複制。無法複製或複製/粘貼不可刪除的塊。