Definir bloqueios

As definições de bloco descrevem a aparência e o comportamento de um bloco, incluindo texto, cor, forma e a que outros blocos ele pode se conectar.

Formato JSON em comparação com a API JavaScript

O Blockly tem duas maneiras de definir blocos: objetos JSON e funções JavaScript. O formato JSON foi projetado para simplificar o processo de localização ao desenvolver para idiomas com diferentes ordens de palavras. O formato JSON é o método preferido para definir blocos.

No entanto, o formato JSON não pode definir diretamente recursos avançados, como mutadores ou validadores. Eles precisam ser escritos em JavaScript, geralmente como extensões.

Os apps que usam a implementação original do JavaScript do Blockly também podem gravar definições de bloco diretamente nas chamadas de função da API Blockly de nível inferior, mostradas nos vários exemplos de JavaScript abaixo.

JSON

Blockly.defineBlocksWithJsonArray([{
  "type": "string_length",
  "message0": 'length of %1',
  "args0": [
    {
      "type": "input_value",
      "name": "VALUE",
      "check": "String"
    }
  ],
  "output": "Number",
  "colour": 160,
  "tooltip": "Returns number of letters in the provided text.",
  "helpUrl": "http://www.w3schools.com/jsref/jsref_length_string.asp"
}]);

JavaScript

Blockly.Blocks['string_length'] = {
  init: function() {
    this.appendValueInput('VALUE')
        .setCheck('String')
        .appendField('length of');
    this.setOutput(true, 'Number');
    this.setColour(160);
    this.setTooltip('Returns number of letters in the provided text.');
    this.setHelpUrl('http://www.w3schools.com/jsref/jsref_length_string.asp');
  }
};

A função init cria a forma do bloco. No contexto dessa função, a palavra-chave this é o bloco que está sendo criado.

Os dois exemplos carregam o mesmo bloco "string_length".

Na Web, o formato JSON é carregado usando a função initJson. Isso também permite misturar os dois formatos nas páginas da Web do Blockly. É preferível definir o bloco com JSON sempre que possível e usar JavaScript somente para partes das definições de bloco que não são compatíveis com o JSON.

Veja abaixo o exemplo de um bloco predominantemente definido usando JSON, mas estendido usando a API JavaScript para apresentar uma dica dinâmica.

JavaScript

var mathChangeJson = {
  "message0": "change %1 by %2",
  "args0": [
    {"type": "field_variable", "name": "VAR", "variable": "item", "variableTypes": [""]},
    {"type": "input_value", "name": "DELTA", "check": "Number"}
  ],
  "previousStatement": null,
  "nextStatement": null,
  "colour": 230
};

Blockly.Blocks['math_change'] = {
  init: function() {
    this.jsonInit(mathChangeJson);
    // Assign 'this' to a variable for use in the tooltip closure below.
    var thisBlock = this;
    this.setTooltip(function() {
      return 'Add a number to variable "%1".'.replace('%1',
          thisBlock.getFieldValue('VAR'));
    });
  }
};

Cor do bloco

A cor principal de um bloco é definida pela propriedade JSON colour, pela função block.setColour(..) ou pelo uso de temas e da definição de um estilo de bloco.

JSON

{
  // ...,
  "colour": 160,
}

JavaScript

init: function() {
  // ...
  this.setColour(160);
}

Consulte o guia de cores de blocos para ver mais detalhes.

Conexões de instrução

Os usuários podem criar sequências de blocos usando os conectores nextStatement e previousStatement. No layout padrão do Blockly, essas conexões estão nas partes de cima e de baixo, com os blocos empilhados verticalmente.

Um bloco com um conector anterior não pode ter um conector de saída e vice-versa. O termo bloco de instrução se refere a um bloco sem saída de valor. Um bloco de instrução geralmente terá uma conexão anterior e uma próxima.

As conexões nextStatement e previousStatement podem ser digitadas, mas esse recurso não é usado por blocos padrão.

Próxima conexão

Cria um ponto na parte de baixo do bloco para que outras instruções possam ser empilhadas abaixo dele. Um bloco com uma próxima conexão, mas nenhuma conexão anterior, geralmente representa um evento e pode ser configurado para ser renderizado com um chapéu.

JSON

Sem tipo:

{
  ...,
  "nextStatement": null,
}

Tipo (raro):

{
  "nextStatement": "Action",
  ...
}

JavaScript

Sem tipo:

this.setNextStatement(true);  // false implies no next connector, the default

Tipo (raro):

this.setNextStatement(true, 'Action');

Conexão anterior

Cria um entalhe na parte de cima do bloco, para que ele possa ser conectado como uma pilha de instruções.

Blocos com uma conexão anterior não podem ter uma conexão de saída.

JSON

Sem tipo:

{
  ...,
  "previousStatement": null,
}

Tipo (raro):

{
  "previousStatement": "Action",
  ...
}

JavaScript

Sem tipo:

this.setPreviousStatement(true);  // false implies no previous connector, the default

Tipo (raro):

this.setPreviousStatement(true, 'Action');

Bloquear saída

Um bloco pode ter uma única saída, representada como um conector jigsaw macho na borda de cima. As saídas se conectam a entradas de valor. Os blocos com uma saída geralmente são chamados de blocos de valor.

JSON

Sem tipo:

{
  // ...,
  "output": null,
}

Digitada:

{
  // ...,
  "output": "Number",
}

JavaScript

Sem tipo:

init: function() {
  // ...
  this.setOutput(true);
}

Digitada:

init: function() {
  // ...
  this.setOutput(true, 'Number');
}

Blocos com um conector de saída não podem ter também um entalhe de instrução anterior.

Bloquear entradas

Um bloco tem uma ou mais entradas, em que cada entrada tem uma sequência de campos e pode terminar em uma conexão. Há vários tipos de entradas integradas.

  • Entrada de valor: conecta-se a uma conexão de saída de um bloco de valor. Um bloco math_arithmetic (adição, subtração) é um exemplo de um bloco com duas entradas de valor.
  • Entrada de instrução: conecta-se a uma conexão anterior de um bloco de instruções. A seção aninhada de uma repetição "while" é um exemplo de entrada de instrução.
  • Entrada fictícia: não tem uma conexão de bloco. Ele funciona como uma nova linha quando o bloco é configurado para usar entradas de valor externas.
  • Entrada de linha final: não tem uma conexão de bloco e sempre funciona como uma nova linha.

Também é possível criar uma entrada personalizada para oferecer suporte à renderização personalizada.

O formato JSON e a API JavaScript usam modelos um pouco diferentes para descrever as entradas.

Entradas e campos no JSON

Os blocos definidos por JSON são estruturados como uma sequência de strings de mensagem interpoladas ( message0, message1, ...), em que cada token de interpolação (%1, %2, ...) é um campo ou uma extremidade de entrada (onde o conector de entrada é renderizado dentro da mensagem) na matriz de argsN JSON correspondente. O objetivo desse formato é facilitar a internacionalização.

JSON

{
  "message0": "set %1 to %2",
  "args0": [
    {
      "type": "field_variable",
      "name": "VAR",
      "variable": "item",
      "variableTypes": [""]
    },
    {
      "type": "input_value",
      "name": "VALUE"
    }
  ]
}

Os tokens de interpolação precisam corresponder completamente à matriz args0: sem duplicatas, sem omissões. Os tokens podem estar presentes em qualquer ordem, o que permite que idiomas diferentes mudem o layout do bloco.

O texto nos dois lados de um token de interpolação é removido do espaço em branco. O texto que usa o caractere % (por exemplo, ao se referir a uma porcentagem) precisa usar %% para que não seja interpretado como um token de interpolação.

A ordem e os tipos dos argumentos definem a forma do bloco. Mudar uma dessas strings pode mudar completamente o layout do bloco. Isso é particularmente importante em idiomas que têm uma ordem de palavras diferente do inglês. Considere uma linguagem hipotética em que "set %1 to %2" (como usado no exemplo acima) precisa ser revertido para dizer "put %2 in %1". Mudar essa string (e deixar o restante do JSON inalterado) resulta neste bloco:

O Blockly alterou automaticamente a ordem dos campos, criou uma entrada fictícia e alternou de entradas externas para internas.

O Blockly também substitui automaticamente todos os caracteres de nova linha (\n) na string da mensagem por uma entrada de linha final.

JSON

{
  "message0": "set %1\nto %2",
  "args0": [
    {
      "type": "field_variable",
      "name": "VAR",
      "variable": "item",
      "variableTypes": [""]
    },
    {
      "type": "input_value",
      "name": "VALUE"
    }
  ]
}

args

Cada string de mensagem é pareada com uma matriz args do mesmo número. Por exemplo, message0 é usado com args0. Os tokens de interpolação (%1, %2, ...) se referem aos itens da matriz args. Todo objeto tem uma string type. O restante dos parâmetros varia de acordo com o tipo:

Também é possível definir seus próprios campos personalizados e entradas personalizadas e transmiti-las como argumentos.

Todo objeto também pode ter um campo alt. Caso o Blockly não reconheça o type do objeto, o objeto alt será usado no lugar dele. Por exemplo, se um novo campo chamado field_time for adicionado ao Blockly, os blocos que usam esse campo poderão usar alt para definir um substituto field_input para versões mais antigas do Blockly:

JSON

{
  "message0": "sound alarm at %1",
  "args0": [
    {
      "type": "field_time",
      "name": "TEMPO",
      "hour": 9,
      "minutes": 0,
      "alt":
        {
          "type": "field_input",
          "name": "TEMPOTEXT",
          "text": "9:00"
        }
    }
  ]
}

Um objeto alt pode ter o próprio objeto alt, permitindo o encadeamento. Por fim, se o Blockly não puder criar um objeto na matriz args0 (depois de tentar quaisquer objetos alt), esse objeto será simplesmente ignorado.

Uma entrada fictícia será adicionada automaticamente ao final do bloco se a string message terminar com texto ou campos que não estão contidos por uma entrada. Assim, se a última entrada em um bloco for uma entrada fictícia, ela poderá ser omitida da matriz args e não precisará de interpolação em message. A adição automática de uma entrada fictícia de cauda permite que os tradutores mudem message sem precisar modificar o restante do JSON. Consulte o exemplo de "set %1 to %2" (nenhuma entrada fictícia) e "put %2 in %1" (entrada fictícia adicionada) anteriormente nesta página.

implicitAlign0

Em casos raros, a entrada fictícia final criada automaticamente precisa estar alinhada a "RIGHT" ou "CENTRE". O padrão, se não for especificado, será "LEFT".

No exemplo abaixo, message0 é "send email to %1 subject %2 secure %3", e o Blockly adiciona automaticamente uma entrada fictícia à terceira linha. Definir implicitAlign0 como "RIGHT" força essa linha a ficar alinhada à direita. Esse alinhamento se aplica a todas as entradas que não estão explicitamente definidas na definição de bloco JSON, incluindo entradas da linha final que substituem caracteres de nova linha ('\n') na mensagem. Há também a propriedade descontinuada lastDummyAlign0 que tem o mesmo comportamento que implicitAlign0.

Ao criar blocos para RTL (árabe e hebraico), a esquerda e a direita são invertidas. Assim, "RIGHT" alinharia os campos à esquerda.

message1, args1, implicitAlign1

Alguns blocos são naturalmente divididos em duas ou mais partes separadas. Considere este bloco de repetição que tem duas linhas:

Se esse bloco fosse descrito com uma única mensagem, a propriedade message0 seria "repeat %1 times %2 do %3". Essa string é estranha para um tradutor, é difícil explicar o que a substituição %2 significa. A entrada fictícia %2 também pode não ser desejada em alguns idiomas. E pode haver vários blocos que queiram compartilhar o texto da segunda linha. Uma abordagem melhor é que o JSON use mais de uma propriedade de mensagem e args:

JSON

{
  "type": "controls_repeat_ext",
  "message0": "repeat %1 times",
  "args0": [
    {"type": "input_value", "name": "TIMES", "check": "Number"}
  ],
  "message1": "do %1",
  "args1": [
    {"type": "input_statement", "name": "DO"}
  ],
  "previousStatement": null,
  "nextStatement": null,
  "colour": 120
}

Qualquer número de propriedades message, args e implicitAlign pode ser definida no formato JSON, começando com 0 e incrementando sequencialmente. Observe que a Block Factory não é capaz de dividir mensagens em várias partes, mas fazer isso manualmente é simples.

Entradas e campos no JavaScript

A API JavaScript inclui um método append para cada tipo de entrada:

JavaScript

this.appendEndRowInput()
    .appendField('for each')
    .appendField('item')
    .appendField(new Blockly.FieldVariable());
this.appendValueInput('LIST')
    .setCheck('Array')
    .setAlign(Blockly.inputs.Align.RIGHT)
    .appendField('in list');
this.appendStatementInput('DO')
    .appendField('do');
this.appendDummyInput()
    .appendField('end');

Cada método de anexação pode receber uma string identificadora usada por geradores de código. Entradas fictícias e de linha final raramente precisam de referência, e o identificador geralmente não é definido.

A API JavaScript também inclui um método appendInput genérico para anexar entradas personalizadas. Nesse caso, o identificador precisa ser transmitido diretamente ao construtor da sua entrada personalizada.

JavaScript

this.appendInput(new MyCustomInput('INPUT_NAME'))
    .appendField('an example label')

Todos os métodos appendInput (genéricos e não genéricos) retornam o objeto de entrada para que possam ser mais configurados usando o encadeamento de métodos. Há três métodos integrados usados para configurar entradas.

setCheck

JavaScript

input.setCheck('Number');

Essa função opcional é usada para a verificação de tipo das entradas conectadas. Se receber um argumento nulo, o padrão, essa entrada poderá ser conectada a qualquer bloco. Consulte Verificações de tipo para mais detalhes.

setAlign

JavaScript

input.setAlign(Blockly.inputs.Align.RIGHT);

Essa função opcional é usada para alinhar os campos (veja abaixo). Há três valores autodescritivos que podem ser transmitidos como um argumento para essa função: Blockly.inputs.Align.LEFT, Blockly.inputs.Align.RIGHT e Blockly.inputs.Align.CENTER.

Ao criar blocos para RTL (árabe e hebraico), a esquerda e a direita são invertidas. Assim, Blockly.inputs.Align.RIGHT alinharia os campos à esquerda.

appendField

Depois que uma entrada é criada e anexada a um bloco com appendInput, é possível anexar qualquer número de campos a ela. Esses campos costumam ser usados como rótulos para descrever a finalidade de cada entrada.

JavaScript

input.appendField('hello');

O elemento de campo mais simples é o texto. A convenção de Blockly é usar todo texto em minúsculas, com exceção de nomes próprios (por exemplo, Google, SQL).

Uma linha de entrada pode conter qualquer número de elementos de campo. Várias chamadas appendField podem ser encadeadas para adicionar vários campos à mesma linha de entrada de maneira eficiente.

JavaScript

input.appendField('hello')
     .appendField(new Blockly.FieldLabel('Neil', 'person'));

Na verdade, a chamada appendField('hello') é um atalho para usar um construtor de FieldLabel explícito: appendField(new Blockly.FieldLabel('hello')). A única ocasião de usar o construtor é ao especificar um nome de classe para que o texto possa ser estilizado usando uma regra CSS.

In-line x Externo

As entradas de bloco podem ser renderizadas como externas ou internas.

A definição do bloco pode especificar um booleano opcional que controla se as entradas são inline ou não. Se for false, todas as entradas de valor serão externas (como o bloco esquerdo). Se for true, todas as entradas de valor estarão inline (como o bloco direito acima).

JSON

{
  // ...,
  "inputsInline": true
}

JavaScript

init: function() {
  // ...
  this.setInputsInline(true);
}

Se ela não for definida, o Blockly usará algumas heurísticas para adivinhar qual modo é melhor. Supondo que o Blockly faça a escolha certa, é preferível deixar esse campo indefinido, já que traduções de diferentes idiomas podem ter diferentes modos automaticamente. Consulte o exemplo de JSON de "set %1 to %2" (entradas externas) e "put %2 in %1" (entradas inline) anteriormente nesta página.

Use entradas inline quando um bloco tiver chances de ter entradas pequenas, como números. O usuário poderá alternar essa opção por meio do menu de contexto se a configuração collapse estiver ativada. O padrão será "true" se a caixa de ferramentas tiver categorias.

Campos

Os campos definem a maioria dos elementos de interface do usuário em um bloco. Isso inclui os rótulos de string, imagens e entradas para dados literais, como strings e números. O exemplo mais simples é o bloco math_number, que usa um field_input para permitir que o usuário digite um número.

Os campos são anexados ao bloco usando appendField.

O Blockly fornece vários campos integrados, incluindo entradas de texto, seletores de cores e imagens. Também é possível criar campos próprios.

→ Mais informações sobre campos integrados.

→ Mais informações sobre a criação de campos personalizados.

Ícones

Os ícones definem elementos da interface em um bloco que exibem informações "meta" sobre o bloco.

Os ícones são anexados ao bloco usando addIcon.

O Blockly fornece vários ícones integrados, incluindo ícones de comentários e ícones de aviso. Você também pode criar seus próprios ícones.

→ Mais informações sobre a criação de ícones personalizados.

Dicas

As dicas oferecem ajuda instantânea quando o usuário passa o mouse sobre o bloco. Se o texto for longo, ele vai ser ajustado automaticamente.

JSON

{
  // ...,
  "tooltip": "Tooltip text."
}

JavaScript

init: function() {
  this.setTooltip("Tooltip text.");
}

Na API JavaScript, as dicas também podem ser definidas como uma função em vez de uma string estática. Isso permite ajuda dinâmica. Consulte math_arithmetic para ver um exemplo de dica que muda dependendo de qual opção do menu suspenso foi escolhida.

JavaScript

Blockly.Blocks['math_arithmetic'] = {
  init: function() {
    // ...

    // Assign 'this' to a variable for use in the tooltip closure below.
    var thisBlock = this;
    this.setTooltip(function() {
      var mode = thisBlock.getFieldValue('OP');
      var TOOLTIPS = {
        'ADD': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_ADD,
        'MINUS': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_MINUS,
        'MULTIPLY': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_MULTIPLY,
        'DIVIDE': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_DIVIDE,
        'POWER': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_POWER
      };
      return TOOLTIPS[mode];
    });
  }
};

Com a API JavaScript, os blocos podem especificar uma função, em vez de uma string estática, que retorna uma string de dica. Isso permite dicas dinâmicas. Consulte math_arithmetic para ver um exemplo.

Personalização

Você também pode personalizar a aparência das dicas fornecendo uma função de renderização personalizada. Crie uma função que aceite dois parâmetros:

  • Primeiro, um elemento <div> em que você vai renderizar o conteúdo.
  • segundo, o elemento real que está passando o mouse e que você mostrará a dica para

No corpo da função, você pode renderizar o conteúdo que quiser no div. Para acessar a string de dica definida no bloco que está passando o mouse, você pode chamar Blockly.Tooltip.getTooltipOfObject(element);, em que element é o segundo parâmetro acima.

Por fim, registre essa função para que o Blockly possa chamá-la no momento apropriado:

Blockly.Tooltip.setCustomTooltip(yourFnHere);

Para ver um exemplo, consulte a demonstração de dicas personalizadas.

URL da ajuda

Os bloqueios podem ter uma página de ajuda associada a eles. Ela está disponível para os usuários do Blockly para Web clicando com o botão direito do mouse no bloco e selecionando "Help" no menu de contexto. Se esse valor for null, o menu ficará esmaecido.

JSON

{
  // ...,
  "helpUrl": "https://en.wikipedia.org/wiki/For_loop"
}

JavaScript

init: function() {
  // ...
  this.setHelpUrl('https://en.wikipedia.org/wiki/For_loop');
}

Com a API JavaScript, os blocos podem especificar uma função, em vez de uma string estática, que retorna uma string de URL, permitindo assim ajuda dinâmica.

Mudar listeners e validadores

Os blocos podem ter funções de listener de mudança que são chamadas em qualquer alteração no espaço de trabalho (inclusive aquelas não relacionadas ao bloco). Eles são usados principalmente para definir o texto de aviso do bloco ou notificações de usuário semelhantes fora do espaço de trabalho.

A função é adicionada chamando setOnChange com uma função e pode ser feita durante a inicialização ou por meio de uma extensão JSON caso você pretenda usá-la em todas as plataformas.

JSON

{
  // ...,
  "extensions":["warning_on_change"],
}

Blockly.Extensions.register('warning_on_change', function() {
  // Example validation upon block change:
  this.setOnChange(function(changeEvent) {
    if (this.getInput('NUM').connection.targetBlock()) {
      this.setWarningText(null);
    } else {
      this.setWarningText('Must have an input block.');
    }
  });
});

JavaScript

Blockly.Blocks['block_type'] = {
  init: function() {
    // Example validation upon block change:
    this.setOnChange(function(changeEvent) {
      if (this.getInput('NUM').connection.targetBlock()) {
        this.setWarningText(null);
      } else {
        this.setWarningText('Must have an input block.');
      }
    });
  }
}

O sistema chama a função, passando o evento de alteração. Dentro da função, this se refere à instância do bloco.

Como a função é chamada em qualquer mudança, se usada, os desenvolvedores precisam garantir que o listener seja executado rapidamente. Também é preciso desconfiar de alterações no espaço de trabalho que podem ser aplicadas em cascata ou voltar ao listener.

Consulte os blocos controls_flow_statements, logic_compare e procedures_ifreturn para ver exemplos.

Observe que os campos editáveis têm seus próprios listeners de eventos para validar a entrada e causar efeitos colaterais.

Mutador

Os mutadores permitem que blocos avançados mudem de forma, principalmente como resultado de os usuários abrindo uma caixa de diálogo para adicionar, remover ou reorganizar componentes. Os mutadores podem ser adicionados por JSON com a chave mutator.

JSON

{
  // ...,
  "mutator":"if_else_mutator"
}

Configuração por bloco

As instâncias em bloco têm várias propriedades que configuram como se comportam com o usuário. Eles podem ser usados para restringir o espaço de trabalho a refletir determinadas propriedades do domínio (por exemplo, se houver exatamente um evento "start") ou focar o esforço do usuário (por exemplo, um tutorial).

Estado deletável

block.setDeletable(false);

Se ela for definida como falsa, o usuário não poderá excluir o bloqueio. Por padrão, os bloqueios podem ser excluídos em um espaço de trabalho editável.

Qualquer bloco, até mesmo os que não podem ser excluídos, pode ser excluído de maneira programática:

block.dispose();

Estado editável

block.setEditable(false);

Quando ele é definido como "false", o usuário não pode mudar os campos do bloco (por exemplo, menus suspensos e entradas de texto). Por padrão, os blocos podem ser editados em um espaço de trabalho editável.

Estado móvel

block.setMovable(false);

Quando definido como falso, o usuário não poderá mover o bloco diretamente. Um bloco imóvel que é filho de outro não pode ser desconectado desse bloco, embora ele seja movido com o pai se o pai for movido. Por padrão, os blocos podem ser movidos em um espaço de trabalho editável.

Qualquer bloco (até mesmo os imóveis) pode ser movido de maneira programática quando está em um espaço de trabalho.

block.moveBy(dx, dy)

A posição inicial de um bloco em um espaço de trabalho é padronizada como (0, 0).

Bloquear dados

this.data = '16dcb3a4-bd39-11e4-8dfc-aa07a5b093db';

Data é uma string opcional e arbitrária anexada ao bloco. Quando o bloco é serializado, a string de dados é serializada com ele. Isso inclui quando o bloco está duplicado ou copiado/colado.

Geralmente, esse elemento é usado para associar um bloco a um recurso externo.

Quando serializados para JSON, os dados são armazenados como uma propriedade de nível superior no bloco:

{
  "type": "my_block",
  "data": "16dcb3a4-bd39-11e4-8dfc-aa07a5b093db",
  // etc..
}

Quando serializada para XML (o antigo sistema de serialização icebox), a string de dados é armazenada em uma tag <data></data> dentro do bloco:

<block type="my_block">
  <data>16dcb3a4-bd39-11e4-8dfc-aa07a5b093db</data>
  <!-- etc... -->
</block>

Destruição

Os blocos têm um hook destroy, que é chamado quando são excluídos do espaço de trabalho. Isso pode ser usado para destruir todos os modelos de dados de apoio/recursos externos associados ao bloco que não são mais necessários.

JSON

{
  // ...,
  "extensions":["destroy"],
}

Blockly.Extensions.registerMixin('destroy', {
  destroy: function() {
    this.myResource.dispose();
  }
});

JavaScript

Blockly.Blocks['block_type'] = {
  destroy: function() {
    this.myResource.dispose();
  }
}

O método destroy é chamado depois que o pai do bloco é descartado, mas antes que os filhos ou campos sejam descartados.

Menus de contexto

Por padrão, os blocos têm um menu de contexto acionado por um clique com o botão direito do mouse, que permite aos usuários realizar ações como adicionar comentários ou duplicar blocos.

Para desativar o menu de contexto de um bloco específico, faça o seguinte:

block.contextMenu = false;

Também é possível personalizar as opções mostradas no menu. Para personalizar o menu para todos os blocos, consulte a documentação dos menus de contexto. Para personalizar o menu para um bloco individual, implemente customContextMenu. Essa função aceita uma matriz de opções de menu e a modifica, o que significa que é possível adicionar e remover itens.

Cada opção de menu é um objeto com três propriedades:

  • text é o texto de exibição.
  • enabled é um booleano. Quando desativada, a opção é mostrada, mas com texto cinza.
  • callback é a função a ser chamada quando a opção é clicada.