Criar um novo tipo de ícone

Para criar um ícone personalizado, você precisa implementar a interface IIcon. Isso informa ao Blockly como o ícone deve ser renderizado e o que fazer se receber um clique etc.

Recomendamos criar subclasses da classe abstrata Icon, porque ela já fornece implementações padrão de vários métodos na IIcon interface gráfica do usuário.

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

Especificar o tipo de ícone

O método getType retorna um valor que representa o tipo da ícone. Ele é usado para registrar o ícone para serialização e o ícone 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');
  }

Criar a visualização do ícone

A visualização do ícone refere-se aos elementos SVG que residem no bloco.

Inicializar a visualização

O método initView é onde você cria os elementos SVG do seu ícone que reside no bloco. Os novos elementos devem ser filhos do this.svgRoot elemento para que sejam limpos automaticamente quando o ícone será destruída.

O módulo Blockly.utils.dom oferece uma interface limpa para instanciar SVGs.

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

Retornar o tamanho

O método getSize retorna o tamanho do ícone, de modo que o renderizador pode aumentar a largura do bloco o suficiente.

O tamanho é em "unidades de espaço de trabalho" arbitrárias. (que não mudam conforme o espaço de trabalho muda de escala).

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

Definir a ordem

Os ícones têm uma ordem estática dentro do bloco. Por exemplo, o mutador integrado ícones são sempre mostrados na frente dos ícones de comentários, que são mostrados na frente dos ícones de aviso.

A ordem é controlada pelo valor retornado por getWeight. . Ícones com pesos mais positivos são renderizados depois de ícones com menos pesos positivos.

getWeight() {
  return 10;
}

Implementar o comportamento "onclick"

Muitos ícones são interativos e fazem algo quando são clicados. Por exemplo: Todos os ícones integrados mostram um balão quando são clicados. Você pode use o método onClick para implementar isso.

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

Responder a alterações de bloqueio

Alguns ícones também querem responder a alterações no bloco, em particular alterações capacidade de edição e fechamento.

Editabilidade

Se o ícone deve se comportar de forma diferente dependendo se o bloco é editável ou não (por exemplo, não ser clicável quando o bloco não editável), implemente o método updateEditable. Esse método é chamado automaticamente quando o status editável do bloco é alterado.

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

Recolhimento

Alguns ícones são mostrados quando o bloco é recolhido, mas, por padrão, são não. Se você quiser que seu ícone seja mostrado, substitua o isShownWhenCollapsed para retornar true.

isShownWhenCollapsed() {
  return true;
}

Em seguida, substitua o método updateCollapsed.

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

Elimine o ícone

Os ícones devem limpar todos os elementos do DOM ou referências externas quando estiverem descartados. Por padrão, tudo o que for anexado a this.svgRoot será destruídos, mas outras referências precisam ser limpas manualmente. Ela deve ser feita no método dispose.

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

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