드롭다운 필드는 문자열을 값으로 저장하고 문자열을 텍스트로 저장합니다. 이 값은 텍스트에 액세스하는 데 사용되는 언어 중립 키이며, Blockly가 언어 간에 전환될 때 번역되지 않습니다. 텍스트는 사람이 읽을 수 있는 문자열로, 사용자에게 표시됩니다.
드롭다운 필드
편집기가 열려 있는 드롭다운 필드
접힌 블록의 드롭다운 필드
제작
드롭다운 생성자는 메뉴 생성기와 선택적 validator를 사용합니다. 메뉴 생성기는 많은 유연성을 갖추고 있지만 기본적으로 옵션의 배열로, 각 옵션은 사람이 읽을 수 있는 부분과 언어 중립적 문자열을 포함합니다.
간단한 텍스트 드롭다운
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');
}
};
사람이 읽을 수 있는 정보를 언어 중립 키와 별도로 유지하면 드롭다운 메뉴의 설정을 언어 간에 유지할 수 있습니다. 예를 들어 영어 버전의 블록은 [['left', 'LEFT'], ['right',
'RIGHT]]
를 정의하지만 동일한 블록의 독일어 버전은 [['links',
'LEFT'], ['rechts', 'RIGHT]]
를 정의할 수 있습니다.
이미지 드롭다운
드롭다운 메뉴의 옵션은 텍스트가 아니라 이미지일 수도 있습니다. 이미지 객체는 src
, width
, height
, alt
속성으로 지정됩니다.
드롭다운에는 텍스트 옵션과 이미지 옵션이 혼합되어 있을 수 있지만, 개별 옵션에 현재 이미지와 텍스트를 모두 포함할 수는 없습니다.
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');
}
};
동적 드롭다운
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');
});
이 작업은 JSON 확장 프로그램을 사용하여 수행됩니다.
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;
}
};
정적 옵션 목록 대신 함수를 드롭다운에 제공하여
동적 옵션을 만들 수 있습니다. 이 함수는 정적 옵션과 동일한 [human-readable-value, language-neutral-key]
형식으로 옵션 배열을 반환해야 합니다. 드롭다운을 클릭할 때마다 함수가 실행되고 옵션이 다시 계산됩니다.
직렬화
JSON
드롭다운 필드의 JSON은 다음과 같습니다.
{
"fields": {
"FIELDNAME": "LANGUAGE-NEUTRAL-KEY"
}
}
여기서 FIELDNAME
는 드롭다운 필드를 참조하는 문자열이며 값은 필드에 적용할 값입니다. 값은 언어 중립 옵션 키여야 합니다.
XML
드롭다운 필드의 XML은 다음과 같습니다.
<field name="FIELDNAME">LANGUAGE-NEUTRAL-KEY</field>
여기서 필드의 name
속성은 드롭다운 필드를 참조하는 문자열을 포함하며 내부 텍스트는 필드에 적용할 값입니다. 내부 텍스트는 유효한 언어 중립 옵션 키여야 합니다.
맞춤설정
드롭다운 화살표
Blockly.FieldDropdown.ARROW_CHAR
속성을 사용하여 드롭다운 화살표를 나타내는 유니코드 문자를 변경할 수 있습니다.
ARROW_CHAR
속성의 기본값은 Android에서는 \u25BC
(▼)이고 그렇지 않은 경우 \u25BE
(▾)입니다.
전역 속성이므로 설정하면 모든 드롭다운 필드가 수정됩니다.
메뉴 높이
Blockly.FieldDropdown.MAX_MENU_HEIGHT_VH
속성을 사용하여 메뉴의 최대 높이를 변경할 수 있습니다. 이는 표시 영역 높이의 백분율로 정의되며 표시 영역이 창으로 정의됩니다.
MAX_MENU_HEIGHT_VH
속성의 기본값은 0.45입니다.
전역 속성이므로 설정하면 모든 드롭다운 필드가 수정됩니다.
접두사/접미사 일치
모든 드롭다운 메뉴 옵션에서 공통 접두사 또는 접미사 단어를 공유하는 경우 이러한 단어는 자동으로 제외되어 정적 텍스트로 삽입됩니다. 예를 들어 다음과 같은 두 가지 방법으로 동일한 블록을 만들 수 있습니다 (첫 번째 방법은 접미사 일치를 사용하지 않고, 두 번째 방법은 접미사 일치 사용).
서픽스 일치 제외:
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');
}
};
서픽스 일치:
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');
}
};
이 접근 방식의 한 가지 이점은 블록을 다른 언어로 번역하기가 더 쉽다는 것입니다. 이전 코드에는 문자열 'hello'
, 'world'
, 'computer'
가 있지만 수정된 코드에는 'hello world'
및 'hello computer'
문자열이 있습니다. 번역사는 단어를 개별 단어보다
훨씬 쉽게 번역할 수 있습니다
이 접근 방식의 또 다른 장점은 단어 순서가 언어 간에 자주 변경된다는 점입니다. 'world hello'
및 'computer hello'
를 사용한 언어를 생각해 보겠습니다.
서픽스 일치 알고리즘은 공통 'hello'
를 감지하여 드롭다운 다음에 표시합니다.
하지만 접두어/접미사 일치가 실패하는 경우도 있습니다. 두 단어가 항상 함께 있어야 하고 접두사를 제외해서는 안 되는 몇 가지 경우가 있습니다.
예를 들어 'drive red car'
및 'drive red truck'
은 'drive red'
가 아닌 'drive'
만 인수분해해야 합니다. 접두사/접미사 일치자를 억제하기 위해 정규 공백 대신 유니코드 비 줄바꿈 없는 공간 '\u00A0'
를 사용할 수 있습니다. 따라서 위 예는 'drive red\u00A0car'
및 'drive red\u00A0truck'
로 수정할 수 있습니다.
개별 단어를 공백으로 구분하지 않는 언어에서도 접두사/접미사 일치가 실패합니다. 중국어가 좋은 예입니다. '訪問中國'
문자열은 'visit China'
를 의미합니다. 단어 사이에 공백이 없다는 점에 유의하세요.
전체적으로 마지막 두 문자 ('中國'
)는 'China'
를 나타내는 단어이지만 분할할 경우 각각 'centre'
와 'country'
를 의미합니다. 중국어와 같은 언어에서 접두사/접미사 일치가 작동하도록 하려면 줄바꿈이 필요한 곳에 공백을 삽입하면 됩니다. 예를 들어 '訪問 中國'
및 '訪問 美國'
는 "visit [China/USA]"
가 되고 '訪問 中 國'
및 '訪問 美 國'
는 "visit [centre/beautiful] country"
가 됩니다.
드롭다운 검사기 만들기
드롭다운 필드의 값은 언어 중립적인 문자열이므로 모든 검사기는 문자열을 수락하고 사용 가능한 옵션, null
, undefined
문자열을 반환해야 합니다.
유효성 검사 도구에서 그 밖의 결과가 반환되면 Blockly의 동작이 정의되지 않으므로 프로그램이 다운될 수 있습니다.
예를 들어 다음과 같이 세 가지 옵션과 검사기가 있는 드롭다운 필드를 정의할 수 있습니다.
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
는 항상 전달된 값을 반환하지만 드롭다운 값에 따라 입력을 추가하거나 삭제하는 도우미 함수 updateConnection
를 호출합니다.
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');
}
}