Для создания пользовательской иконки необходимо реализовать интерфейс 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 .
JavaScript
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);
}
Установить порядок
Значки в блоке имеют фиксированный порядок. Например, встроенные значки-мутаторы всегда отображаются перед значками комментариев, которые, в свою очередь, отображаются перед значками предупреждений.
Порядок отображения определяется значением, возвращаемым методом getWeight . Иконки с более положительными значениями веса отображаются после иконок с менее положительными значениями веса.
getWeight() {
return 10;
}
Реализуйте поведение при клике.
Многие значки интерактивны и выполняют какие-либо действия при нажатии. Например, все встроенные значки при нажатии отображают всплывающее окно . Для реализации этого можно использовать метод 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 .
updateCollapsed() {
// By default icons are hidden when the block is collapsed. We want it to
// be shown, so do nothing.
}
Удалите значок
При удалении иконок необходимо очищать все элементы DOM и внешние ссылки. По умолчанию уничтожается всё, что добавляется к this.svgRoot , но другие ссылки необходимо удалять вручную. Это следует делать внутри метода dispose .
dispose() {
// Always call super!
super.dispose();
this.myBubble?.dispose();
this.myOtherReference?.dispose();
}