آیکون های سفارشی ایجاد کنید

برای ایجاد یک آیکون سفارشی، باید رابط IIcon را پیاده‌سازی کنید. این رابط به Blockly می‌گوید که می‌خواهید آیکون شما چگونه رندر شود، اگر روی آن کلیک شود چه کاری انجام دهد و غیره.

ما توصیه می‌کنیم از کلاس انتزاعی Icon ، زیرکلاس ایجاد کنید، زیرا این کلاس از قبل پیاده‌سازی‌های پیش‌فرض بسیاری از متدها را در رابط IIcon ارائه می‌دهد.

class MyIcon extends Blockly.icons.Icon {
  // The constructor should always take in the source block so that svg elements
  // can be properly created.
  constructor(sourceBlock) {
    super(sourceBlock);
  }
}

نوع آیکون را مشخص کنید

متد getType مقداری را برمی‌گرداند که نشان‌دهنده نوع آیکون است. این متد برای ثبت آیکون جهت سریال‌سازی و بازیابی آیکون از getIcon استفاده می‌شود.

جاوا اسکریپت

getType() {
  return new Blockly.icons.IconType('my_icon');
}

تایپ اسکریپت

getType(): Blockly.icons.IconType<MyIcon> {
  return new Blockly.icons.IconType<MyIcon>('my_icon');
}

نمای آیکون را ایجاد کنید

نمای آیکون به عناصر SVG که در بلوک قرار دارند اشاره دارد.

مقداردهی اولیه نما

متد initView جایی است که شما عناصر SVG آیکون خود را که در بلوک قرار دارند، ایجاد می‌کنید. عناصر جدید باید فرزندان عنصر this.svgRoot باشند تا هنگام از بین رفتن آیکون، به طور خودکار پاک شوند.

ماژول Blockly.utils.dom یک رابط کاربری تمیز برای نمونه‌سازی SVGها ارائه می‌دهد.

initView(pointerdownListener) {
  if (this.svgRoot) return;  // Already initialized.

  // This adds the pointerdownListener to the svgRoot element.
  // If you do not call `super` you must do this yourself.
  super.initView(pointerdownListener);

  Blockly.utils.dom.createSvgElement(
    Blockly.utils.Svg.CIRCLE,
    {
      'class': 'my-css-class',
      'r': '8',
      'cx': '8',
      'cy': '8',
    },
    this.svgRoot  // Append to the svgRoot.
  );
}

اندازه را برگردانید

متد getSize اندازه آیکون را برمی‌گرداند، به طوری که رندرکننده بتواند بلوک را به اندازه کافی عریض کند.

اندازه بر اساس «واحدهای فضای کاری» دلخواه است (که با تغییر مقیاس فضای کاری تغییر نمی‌کنند).

getSize() {
  return new Blockly.utils.Size(16, 16);
}

ترتیب را تنظیم کنید

آیکون‌ها در داخل بلوک ترتیب ثابتی دارند. برای مثال، آیکون‌های mutator داخلی همیشه قبل از آیکون‌های comment نمایش داده می‌شوند که خود آنها هم قبل از آیکون‌های warning نمایش داده می‌شوند.

ترتیب نمایش آیکون‌ها توسط مقداری که توسط متد getWeight برگردانده می‌شود، کنترل می‌شود. آیکون‌هایی که وزن مثبت بیشتری دارند، بعد از آیکون‌هایی با وزن مثبت کمتر نمایش داده می‌شوند.

getWeight() {
  return 10;
}

پیاده‌سازی رفتار کلیک (onclick)

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

onClick() {
  // Do something when clicked.
}

پاسخ به تغییرات بلوک

برخی از آیکون‌ها همچنین می‌خواهند به تغییرات در بلوک، به ویژه تغییرات در قابلیت ویرایش و حالت جمع‌شونده، پاسخ دهند.

قابلیت ویرایش

اگر آیکون شما باید بسته به قابل ویرایش بودن یا نبودن بلوک، رفتار متفاوتی داشته باشد (برای مثال، وقتی بلوک قابل ویرایش نیست، قابل کلیک نباشد)، متد updateEditable را پیاده‌سازی کنید. این متد به طور خودکار زمانی که وضعیت قابل ویرایش بلوک تغییر می‌کند، فراخوانی می‌شود.

updateEditable() {
  if (this.sourceBlock.isEditable()) {
    // Do editable things.
  } else {
    // Do non-editable things.
  }
}

فروپاشی

برخی از آیکون‌ها هنگام بسته شدن بلوک نمایش داده می‌شوند، اما به طور پیش‌فرض این‌طور نیستند. اگر می‌خواهید آیکون شما نمایش داده شود، متد isShownWhenCollapsed را برای برگرداندن true بازنویسی کنید.

isShownWhenCollapsed() {
  return true;
}

و سپس متد updateCollapsed بازنویسی (override) کنید.

updateCollapsed() {
  // By default icons are hidden when the block is collapsed. We want it to
  // be shown, so do nothing.
}

آیکون را حذف کنید

آیکون‌ها باید هنگام دفع، هرگونه عنصر دامنه یا ارجاعات خارجی را پاک کنند. به طور پیش‌فرض، هر چیزی که به this.svgRoot اضافه شود، از بین می‌رود، اما سایر ارجاعات باید به صورت دستی پاک شوند. این کار باید در داخل متد dispose انجام شود.

dispose() {
  // Always call super!
  super.dispose();

  this.myBubble?.dispose();
  this.myOtherReference?.dispose();
}