Il campo a discesa memorizza una stringa come valore e una stringa come testo. La è una chiave indipendente dalla lingua che verrà utilizzata per accedere al testo e non verranno tradotti quando Blockly viene cambiato da una lingua all'altra. Il testo è una stringa leggibile che verrà mostrata all'utente.
Campo a discesa
Campo a discesa con l'editor aperto
Campo a discesa nel blocco compresso
Creazione
Il costruttore del menu a discesa include un generatore di menu e un'opzione facoltativa strumento di convalida. Il generatore di menu offre molti flessibilità, ma si tratta essenzialmente di una serie di opzioni, ciascuna delle quali contiene una parte leggibile e una stringa indipendente dal linguaggio.
Menu a discesa di testo semplici
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');
}
};
Mantenere le informazioni leggibili separatamente dalla chiave indipendente dalla lingua.
consente di mantenere l'impostazione del menu a discesa tra le lingue. Per
Ad esempio, una versione inglese di un blocco può definire [['left', 'LEFT'], ['right',
'RIGHT]]
, mentre una versione tedesca dello stesso blocco può definire [['links',
'LEFT'], ['rechts', 'RIGHT]]
.
Menu a discesa di immagini
Le opzioni di un menu a discesa possono anche essere immagini anziché testo. Gli oggetti immagine vengono
specificato con le proprietà src
, width
, height
e alt
.
Tieni presente che, sebbene un menu a discesa possa contenere una combinazione di opzioni di testo e immagini, una singola opzione al momento non può contenere sia un'immagine che un testo.
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');
}
};
Menu a discesa dinamici
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');
});
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;
}
};
È anche possibile fornire un menu a discesa con una funzione anziché un elenco di
opzioni dinamiche, in modo che le opzioni siano dinamiche. La funzione deve restituire un
array di opzioni nello stesso [human-readable-value, language-neutral-key]
come opzioni statiche. Ogni volta che l'utente fa clic sul menu a discesa, la funzione viene
e le opzioni vengono ricalcolate.
Serializzazione
JSON
Il codice JSON di un campo a discesa è simile al seguente:
{
"fields": {
"FIELDNAME": "LANGUAGE-NEUTRAL-KEY"
}
}
dove FIELDNAME
è una stringa che fa riferimento a un campo a discesa e
il valore è il valore da applicare al campo. Il valore deve essere un
tasto di opzione indipendente dalla lingua.
XML
L'XML per un campo a discesa ha il seguente aspetto:
<field name="FIELDNAME">LANGUAGE-NEUTRAL-KEY</field>
In cui l'attributo name
del campo contiene una stringa che fa riferimento a un menu a discesa
e il testo interno è il valore da applicare al campo. La parte interna
deve essere una chiave di opzione valida e indipendente dalla lingua.
Personalizzazione
Freccia menu a discesa
La proprietà Blockly.FieldDropdown.ARROW_CHAR
può essere utilizzata per modificare
Carattere Unicode che rappresenta la freccia del menu a discesa.
Per impostazione predefinita, la proprietà ARROW_CHAR
è \u25BC
(▼) su Android e \u25BE
(▾)
negli altri casi.
Questa è una proprietà globale, quindi modifica tutti i campi del menu a discesa quando viene impostata.
Altezza del menu
La proprietà Blockly.FieldDropdown.MAX_MENU_HEIGHT_VH
può essere utilizzata per modificare
l'altezza massima del menu. Viene definita come percentuale dell'area visibile
in cui l'area visibile è la finestra.
Il valore predefinito della proprietà MAX_MENU_HEIGHT_VH
è 0,45.
Questa è una proprietà globale, quindi modifica tutti i campi del menu a discesa quando viene impostata.
Corrispondenza di prefisso/suffisso
Se tutte le opzioni del menu a discesa condividono un prefisso e/o un suffisso comuni queste parole vengono automaticamente escluse e inserite come testo statico. Ad esempio, ecco due modi per creare lo stesso blocco (il primo senza la corrispondenza dei suffissi e la seconda con):
Senza corrispondenza del suffisso:
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');
}
};
Con corrispondenza dei suffissi:
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');
}
};
Un vantaggio di questo approccio è che il blocco è più facile da tradurre in
in altre lingue. Il codice precedente ha le stringhe 'hello'
, 'world'
e
'computer'
, mentre il codice rivisto ha le stringhe 'hello world'
e
'hello computer'
. Per tradurre le frasi è molto più facile che i traduttori
le parole in isolamento.
Un altro vantaggio di questo approccio è che l'ordine delle parole spesso cambia
lingue diverse. Immagina una lingua che utilizza 'world hello'
e 'computer hello'
.
L'algoritmo di corrispondenza dei suffissi rileverà il valore 'hello'
comune e lo mostrerà
dopo il menu a discesa.
Tuttavia, a volte la corrispondenza del prefisso/suffisso non va a buon fine. Ci sono alcuni casi in cui
due parole devono sempre andare insieme e il prefisso non deve essere escluso.
Ad esempio, 'drive red car'
e 'drive red truck'
dovrebbero probabilmente solo
è stato escluso 'drive'
, non 'drive red'
. Il modello Unicode
lo spazio '\u00A0'
può essere usato al posto di uno spazio regolare per eliminare
per corrispondenze di prefisso/suffisso. Di conseguenza, l'esempio precedente può essere corretto con
'drive red\u00A0car'
e 'drive red\u00A0truck'
.
Un altro caso in cui la corrispondenza di prefisso/suffisso non riesce è nelle lingue che non
separa le singole parole con uno spazio. Il cinese ne è un buon esempio. La stringa
'訪問中國'
significa 'visit China'
. Nota l'assenza di spazi tra le parole.
Collettivamente, gli ultimi due caratteri ('中國'
) sono la parola per 'China'
,
ma se suddivisi significano rispettivamente 'centre'
e 'country'
. Per rendere
l'abbinamento di prefisso/suffisso funziona in lingue quali cinese,
basta inserire uno spazio nel punto in cui
dovrebbe essere l'interruzione. Ad esempio '訪問 中國'
e
'訪問 美國'
genererebbe "visit [China/USA]"
, mentre '訪問 中 國'
e
'訪問 美 國'
genererà "visit [centre/beautiful] country"
.
Creazione di uno strumento di convalida del menu a discesa
Il valore di un campo a discesa è una stringa indipendente dalla lingua, quindi tutti gli strumenti di convalida devono
accettare una stringa e restituire una stringa che è un'opzione disponibile, null
oppure
undefined
.
Se lo strumento di convalida restituisce qualcos'altro, il comportamento di Blockly è indefinito il programma potrebbe arrestarsi in modo anomalo.
Ad esempio, puoi definire un campo a discesa con tre opzioni e un di convalida come questo:
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
restituisce sempre il valore passato, ma chiama l'assistente
funzione updateConnection
che aggiunge o rimuove input in base al menu a discesa
valore:
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');
}
}