Pole menu zawiera ciąg znaków jako jego wartość, a ciąg znaków jako tekst. to klucz neutralny dla języka, który zostanie użyty do uzyskania dostępu do tekstu nie zostanie przetłumaczona po przełączeniu się między językami Blockly. Tekst to zrozumiały dla człowieka ciąg tekstowy, który zostanie wyświetlony użytkownikowi.
Pole rozwijane
Pole z otwartym edytorem
Pole rozwijane w zwiniętym bloku
na podstawie trendów
Konstruktor menu pobiera generator menu i opcjonalny element walidatorem. W generatorze menu jest wiele opcji jest elastyczność, ale zasadniczo jest to szeroki wachlarz opcji, a każda z nich w części zrozumiałej dla człowieka i ciągu neutralnego dla języka.
Proste menu tekstowe
JSON
{
"type": "example_dropdown",
"message0": "drop down: %1",
"args0": [
{
"type": "field_dropdown",
"name": "FIELDNAME",
"options": [
[ "first item", "ITEM1" ],
[ "second item", "ITEM2" ]
]
}
]
}
JavaScript
Blockly.Blocks['example_dropdown'] = {
init: function() {
this.appendDummyInput()
.appendField('drop down:')
.appendField(new Blockly.FieldDropdown([
['first item', 'ITEM1'],
['second item', 'ITEM2']
]), 'FIELDNAME');
}
};
Oddzielenie informacji zrozumiałych dla człowieka od kluczy neutralnych dla języka
umożliwia zachowywanie ustawień menu pomiędzy językami. Dla:
np. angielska wersja bloku może definiować [['left', 'LEFT'], ['right',
'RIGHT]]
, podczas gdy wersja niemiecka tego samego bloku zdefiniuje [['links',
'LEFT'], ['rechts', 'RIGHT]]
.
Menu obrazów
Opcje w menu mogą też być obrazami zamiast tekstu. Obiekty graficzne są
z właściwościami src
, width
, height
i alt
.
Pamiętaj, że chociaż w menu mogą znajdować się zarówno opcje tekstowe, jak i graficzne, jedna opcja nie może obecnie zawierać jednocześnie obrazu i tekstu.
JSON
{
"type": "image_dropdown",
"message0": "flag %1",
"args0": [
{
"type": "field_dropdown",
"name": "FLAG",
"options": [
["none", "NONE"],
[{"src": "canada.png", "width": 50, "height": 25, "alt": "Canada"}, "CANADA"],
[{"src": "usa.png", "width": 50, "height": 25, "alt": "USA"}, "USA"],
[{"src": "mexico.png", "width": 50, "height": 25, "alt": "Mexico"}, "MEXICO"]
]
}
]
}
JavaScript
Blockly.Blocks['image_dropdown'] = {
init: function() {
var input = this.appendDummyInput()
.appendField('flag');
var options = [
['none', 'NONE'],
[{'src': 'canada.png', 'width': 50, 'height': 25, 'alt': 'Canada'}, 'CANADA'],
[{'src': 'usa.png', 'width': 50, 'height': 25, 'alt': 'USA'}, 'USA'],
[{'src': 'mexico.png', 'width': 50, 'height': 25, 'alt': 'Mexico'}, 'MEXICO']
];
input.appendField(new Blockly.FieldDropdown(options), 'FLAG');
}
};
Dynamiczne menu
JSON
{
"type": "dynamic_dropdown",
"message0": "day %1",
"args0": [
{
"type": "input_dummy",
"name": "INPUT"
}
],
"extensions": ["dynamic_menu_extension"]
}
Blockly.Extensions.register('dynamic_menu_extension',
function() {
this.getInput('INPUT')
.appendField(new Blockly.FieldDropdown(
function() {
var options = [];
var now = Date.now();
for(var i = 0; i < 7; i++) {
var dateString = String(new Date(now)).substring(0, 3);
options.push([dateString, dateString.toUpperCase()]);
now += 24 * 60 * 60 * 1000;
}
return options;
}), 'DAY');
});
Użyjesz do tego formatu JSON rozszerzenie.
JavaScript
Blockly.Blocks['dynamic_dropdown'] = {
init: function() {
var input = this.appendDummyInput()
.appendField('day')
.appendField(new Blockly.FieldDropdown(
this.generateOptions), 'DAY');
},
generateOptions: function() {
var options = [];
var now = Date.now();
for(var i = 0; i < 7; i++) {
var dateString = String(new Date(now)).substring(0, 3);
options.push([dateString, dateString.toUpperCase()]);
now += 24 * 60 * 60 * 1000;
}
return options;
}
};
Zamiast listy statycznej można też podać menu
dzięki czemu opcje mogą być dynamiczne. Funkcja powinna zwrócić
tablica opcji w tym samym [human-readable-value, language-neutral-key]
jako opcji statycznych. Po każdym kliknięciu menu funkcja
i opcje zostaną obliczone ponownie.
Serializacja
JSON
Kod JSON pola menu wygląda tak:
{
"fields": {
"FIELDNAME": "LANGUAGE-NEUTRAL-KEY"
}
}
Gdzie FIELDNAME
jest ciągiem znaków odwołującym się do pola menu,
Argument wartość to wartość, która ma zostać zastosowana do pola. Wartość powinna być ciągiem znaków
klawisz opcji neutralnej dla języka.
XML
Kod XML pola menu wygląda tak:
<field name="FIELDNAME">LANGUAGE-NEUTRAL-KEY</field>
Gdzie atrybut name
pola zawiera ciąg znaków odnoszący się do menu
, a tekst wewnętrzny to wartość do zastosowania. Wewnątrz
tekst powinien być prawidłowym kluczem opcji neutralnym dla języka.
Dostosowywanie
Strzałka w dół
Właściwość Blockly.FieldDropdown.ARROW_CHAR
może służyć do zmiany
znak Unicode reprezentujący strzałkę w dół.
Domyślnie usługa ARROW_CHAR
ma wartość \u25BC
(▼) na Androidzie i \u25BE
(▾)
w przeciwnym razie.
Jest to usługa globalna, więc gdy zostanie ustawiona, zmodyfikuje wszystkie pola menu.
Wysokość menu
Za pomocą właściwości Blockly.FieldDropdown.MAX_MENU_HEIGHT_VH
można zmieniać
maksymalnej wysokości menu. Jest ona określana jako procent widocznego obszaru.
wysokość, a widocznym obszarem jest okno.
Wartość domyślna właściwości MAX_MENU_HEIGHT_VH
to 0,45.
Jest to usługa globalna, więc gdy zostanie ustawiona, zmodyfikuje wszystkie pola menu.
Dopasowywanie prefiksów i sufiksów
Jeśli wszystkie opcje w menu mają wspólny prefiks lub sufiks są automatycznie pomijane i wstawiane jako tekst statyczny. Oto 2 sposoby utworzenia tego samego bloku (ten pierwszy bez dopasowania sufiksu, a drugi z):
Bez dopasowania sufiksu:
JSON
{
"type": "dropdown_no_matching",
"message0": "hello %1",
"args0": [
{
"type": "field_dropdown",
"name": "MODE",
"options": [
["world", "WORLD"],
["computer", "CPU"]
]
}
]
}
JavaScript
Blockly.Blocks['dropdown_no_matching'] = {
init: function() {
var options = [
['world', 'WORLD'],
['computer', 'CPU']
];
this.appendDummyInput()
.appendField('hello')
.appendField(new Blockly.FieldDropdown(options), 'MODE');
}
};
Z dopasowywaniem sufiksów:
JSON
{
"type": "dropdown_with_matching",
"message0": "%1",
"args0": [
{
"type": "field_dropdown",
"name": "MODE",
"options": [
["hello world", "WORLD"],
["hello computer", "CPU"]
]
}
]
}
JavaScript
Blockly.Blocks['dropdown_with_matching'] = {
init: function() {
var options = [
['hello world', 'WORLD'],
['hello computer', 'CPU']
];
this.appendDummyInput()
.appendField(new Blockly.FieldDropdown(options), 'MODE');
}
};
Jedną z zalet tego podejścia jest to, że bloki można łatwiej przenieść
w innych językach. Wcześniejszy kod zawiera ciągi znaków 'hello'
, 'world'
oraz
'computer'
, podczas gdy poprawiony kod zawiera ciągi znaków 'hello world'
oraz
'hello computer'
. Tłumacze łatwiej tłumaczą wyrażenia niż
z osobna.
Kolejną zaletą tego podejścia jest to, że kolejność słów często zmienia się
języki. Wyobraź sobie język, w którym są 'world hello'
i 'computer hello'
.
Algorytm dopasowania sufiksu wykryje typ 'hello'
i wyświetli go
za menu.
Czasami jednak dopasowanie prefiksu/sufiksu nie działa. Istnieją sytuacje, w których
dwa słowa zawsze powinny być razem i prefiks nie powinien być pomijany.
Na przykład 'drive red car'
i 'drive red truck'
powinny zawierać przypuszczalnie tylko
uwzględniono 'drive'
, a nie 'drive red'
. Niełamiący kod Unicode
spacja '\u00A0'
może być używana zamiast zwykłej spacji do pomijania
dopasowania prefiksu/sufiksu. Powyższy przykład można poprawić za pomocą
'drive red\u00A0car'
i 'drive red\u00A0truck'
.
Dopasowanie przedrostka i sufiksu nie działa też w językach, w których
oddziel poszczególne słowa spacjami. Dobrym przykładem jest chiński. Ciąg
'訪問中國'
oznacza 'visit China'
. Zwróć uwagę na brak spacji między słowami.
Ostatnie 2 znaki ('中國'
) to słowo oznaczające wyrażenie 'China'
,
ale przy podziale będą one oznaczać odpowiednio 'centre'
i 'country'
. Aby zrobić
dopasowania przedrostka i sufiksu w językach takich jak chiński,
po prostu wstaw spację w miejscu, gdzie ma znajdować się przerwa. Na przykład '訪問 中國'
i
'訪問 美國'
daje wynik "visit [China/USA]"
, podczas gdy '訪問 中 國'
i
'訪問 美 國'
daje "visit [centre/beautiful] country"
wynik.
Tworzenie walidatora menu
Wartość pola menu jest ciągiem niezależnym od języka, więc wszyscy walidatorzy
zaakceptować ciąg znaków i zwrócić ciąg dostępny dla opcji, null
lub
undefined
Jeśli walidator zwraca cokolwiek innego, zachowanie Blockly jest niezdefiniowane i program może ulec awarii.
Możesz na przykład zdefiniować pole menu z 3 opcjami i taki:
validate: function(newValue) {
this.getSourceBlock().updateConnections(newValue);
return newValue;
},
init: function() {
var options = [
['has neither', 'NEITHER'],
['has statement', 'STATEMENT'],
['has value', 'VALUE'],
];
this.appendDummyInput()
// Pass the field constructor the options list, the validator, and the name.
.appendField(new Blockly.FieldDropdown(options, this.validate), 'MODE');
}
validate
zawsze zwraca przekazaną wartość, ale wywołuje funkcję pomocniczą.
funkcja updateConnection
, która dodaje lub usuwa dane wejściowe na podstawie menu
wartość:
updateConnections: function(newValue) {
this.removeInput('STATEMENT', /* no error */ true);
this.removeInput('VALUE', /* no error */ true);
if (newValue == 'STATEMENT') {
this.appendStatementInput('STATEMENT');
} else if (newValue == 'VALUE') {
this.appendValueInput('VALUE');
}
}