فیلدهای کشویی

فیلد کشویی یک رشته را به عنوان مقدار و یک رشته را به عنوان متن خود ذخیره می کند. این مقدار یک کلید زبان خنثی است که برای دسترسی به متن استفاده می‌شود و وقتی Blockly بین زبان‌ها جابه‌جا می‌شود، ترجمه نمی‌شود. متن یک رشته قابل خواندن توسط انسان است که به کاربر نمایش داده می شود.

ایجاد

سازنده کشویی یک مولد منو و یک اعتبارسنجی اختیاری را می گیرد. مولد منو انعطاف‌پذیری زیادی دارد، اما اساساً آرایه‌ای از گزینه‌ها است که هر گزینه شامل یک بخش قابل خواندن توسط انسان و یک رشته بی‌طرف از زبان است.

کشویی متن ساده

کشویی را با دو گزینه متنی باز کنید

JSON

{
  "type": "example_dropdown",
  "message0": "drop down: %1",
  "args0": [
    {
      "type": "field_dropdown",
      "name": "FIELDNAME",
      "options": [
        [ "first item", "ITEM1" ],
        [ "second item", "ITEM2" ]
      ]
    }
  ]
}

جاوا اسکریپت

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]] تعریف کند. [['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"]
      ]
    }
  ]
}

جاوا اسکریپت

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 انجام می شود.

جاوا اسکریپت

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"]
      ]
    }
  ]
}

جاوا اسکریپت

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"]
      ]
    }
  ]
}

جاوا اسکریپت

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' را در نظر بگیرند، نه 'drive red' . فضای بدون شکست یونیکد '\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');
  }
}