Pola menu

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.

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

Otwórz menu z 2 opcjami tekstowymi

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.

Pole zawierające obrazy i tekst

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

Pole rozwijane z dniami tygodnia

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

Właściwość Blockly.FieldDropdown.ARROW_CHAR może służyć do zmiany znak Unicode reprezentujący strzałkę w dół.

Pole ze strzałką niestandardową

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.

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');
  }
};

Menu z

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');
  }
}