Cómo crear un nuevo tipo de ícono

Para crear un ícono personalizado, debes implementar la interfaz IIcon. Esto le indica a Blockly cómo quieres que se renderice tu ícono, hacer si alguien hace clic, etc.

Recomendamos subclasificar la clase abstracta Icon porque ya proporciona implementaciones predeterminadas de muchos métodos en IIcon interfaz de usuario.

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

Especifica el tipo del ícono

El método getType muestra un valor que representa el tipo de ícono. Se usa a fin de registrar el ícono para la serialización. recuperando el ícono de getIcon

JavaScript

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

TypeScript

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

Cómo crear la vista del ícono

La vista del icono hace referencia a los elementos SVG que se alojan en el bloque.

Inicializa la vista

El método initView es donde creas los elementos SVG de tu que se alojan en el bloque. Los elementos nuevos deben ser secundarios de this.svgRoot para que se limpien automáticamente cuando aparezca el ícono se destruye.

El módulo Blockly.utils.dom proporciona una interfaz limpia para crear instancias de 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.
  );
}

Muestra el tamaño

El método getSize muestra el tamaño del ícono para que la renderer puede hacer que el bloque sea lo suficientemente ancho.

El tamaño está en “unidades de espacio de trabajo” arbitrarias. (que no cambian como espacio de trabajo cambia la escala).

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

Establecer el orden

Los iconos tienen un orden estático dentro del bloque. Por ejemplo, el mutador integrado Los íconos siempre se muestran delante de los íconos de comentarios, que aparecen delante de íconos de advertencia.

El valor que muestra getWeight controla el pedido . Los íconos con mayor peso positivo se renderizan después de los íconos con menos con pesos positivos.

getWeight() {
  return 10;
}

Implementa el comportamiento de clic

Muchos iconos son interactivos y hacen algo cuando se hace clic en ellos. Por ejemplo: todos los íconos integrados muestran una burbuja cuando se hace clic en ellos. Puedes Usa el método onClick para implementarlo.

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

Cómo responder a los cambios de bloqueo

Algunos íconos también quieren responder a los cambios del bloque, en particular a los cambios hasta la capacidad de edición y la capacidad contraída.

Editabilidad

Si tu icono debe comportarse de manera diferente según si el bloque está editable o no (por ejemplo, no se puede hacer clic cuando el bloque no está editable), implementa el método updateEditable. Este método se llama automáticamente cuando cambia el estado editable del bloque.

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

Contraído

Algunos iconos se muestran cuando se contrae el bloque, pero, de forma predeterminada, son no. Si deseas que se muestre tu ícono, anula el isShownWhenCollapsed para mostrar true.

isShownWhenCollapsed() {
  return true;
}

Luego, anula el método updateCollapsed.

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

Eliminación del ícono

Los iconos deben limpiar los elementos del dominio o las referencias externas cuando están desechar. De forma predeterminada, todo lo que se agregue a this.svgRoot se obtiene y destruir, pero otras referencias deben limpiarse manualmente. Debe ser dentro del método dispose.

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

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