Définir des blocs

Les définitions de blocs décrivent l'apparence et le comportement d'un bloc, y compris le texte, la couleur, la forme et les autres blocs auxquels il peut se connecter.

Format JSON et API JavaScript

Blockly permet de définir des blocs de deux façons: les objets JSON et les fonctions JavaScript. Le format JSON est conçu pour simplifier le processus de localisation lors du développement pour des langues dont l'ordre des mots est différent. Le format JSON est la méthode privilégiée pour définir des blocs.

Toutefois, le format JSON n'est pas en mesure de définir directement des fonctionnalités avancées telles que les mutateurs ou les validateurs. Elles doivent être écrites en JavaScript, généralement sous la forme d'extensions.

Les applications qui utilisent l'implémentation JavaScript d'origine de Blockly peuvent également écrire des définitions de bloc directement dans les appels de fonction de l'API Blockly de niveau inférieur, comme illustré dans les différents exemples JavaScript ci-dessous.

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

La fonction init crée la forme du bloc. Dans le contexte de cette fonction, le mot clé this correspond au bloc en cours de création.

Ces deux exemples chargent le même bloc "string_length".

Sur le Web, le format JSON est chargé à l'aide de la fonction initJson. Cela permet également de combiner les deux formats dans les pages Web Blockly. Il est préférable de définir votre bloc avec JSON dans la mesure du possible et de n'utiliser JavaScript que pour les parties des définitions de bloc non compatibles avec JSON.

Vous trouverez ci-dessous un exemple de bloc principalement défini à l'aide de JSON, mais étendu à l'aide de l'API JavaScript pour afficher une info-bulle dynamique.

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

Couleur du bloc

La couleur primaire d'un bloc est définie par la propriété JSON colour, la fonction block.setColour(..), ou par l'utilisation de thèmes et la définition d'un style de bloc.

JSON

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

JavaScript

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

Pour en savoir plus, consultez le guide relatif aux couleurs des blocs.

Connexions aux instructions

Les utilisateurs peuvent créer des séquences de blocs à l'aide des connecteurs nextStatement et previousStatement. Dans la mise en page standard de Blockly, ces connexions se trouvent en haut et en bas, les blocs étant empilés verticalement.

Un bloc avec un connecteur précédent ne peut pas avoir de connecteur de sortie, et inversement. Le terme bloc d'instructions fait référence à un bloc sans valeur de sortie. Un bloc d'instruction aura généralement à la fois une connexion précédente et une connexion suivante.

Les connexions nextStatement et previousStatement peuvent être typées, mais cette fonctionnalité n'est pas utilisée par les blocs standards.

Connexion suivante

Crée un point en bas du bloc, de sorte que d'autres instructions puissent être empilées en dessous. Un bloc avec une connexion suivante, mais sans connexion précédente représente généralement un événement et peut être configuré pour s'afficher avec un chapeau.

JSON

Non saisi:

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

Saisie (rare):

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

JavaScript

Non saisi:

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

Dactylographié (rare):

this.setNextStatement(true, 'Action');

Connexion précédente

Crée une encoche en haut du bloc afin qu'elle puisse être connectée sous la forme d'une pile d'instructions.

Les blocs avec une connexion précédente ne peuvent pas avoir de connexion de sortie.

JSON

Non saisi:

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

Saisie (rare):

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

JavaScript

Non saisi:

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

Dactylographié (rare):

this.setPreviousStatement(true, 'Action');

Bloquer la sortie

Un bloc peut avoir une seule sortie, représentée par un connecteur puzzle mâle sur le bord gauche. Les sorties se connectent aux entrées de valeur. Les blocs avec une sortie sont généralement appelés blocs de valeur.

JSON

Non saisi:

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

Saisi:

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

JavaScript

Non saisi:

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

Saisi:

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

Les blocs dotés d'un connecteur de sortie ne peuvent pas avoir d'encoche d'instruction précédente.

Bloquer les entrées

Un bloc comporte une ou plusieurs entrées, chacune étant associée à une séquence de champs et pouvant se terminer par une connexion. Il existe plusieurs types d'entrées intégrées.

  • Entrée de valeur: se connecte à une connexion de sortie d'un bloc de valeur. Un bloc math_arithmetic (addition, soustraction) est un exemple de bloc avec deux entrées de valeur.
  • Statement input (Entrée d'instruction) : se connecte à une connexion précédente d'un bloc d'instructions. La section imbriquée d'une boucle "while" est un exemple d'entrée d'instruction.
  • Entrée factice: aucune connexion en mode bloc n'est définie. Agit comme un retour à la ligne lorsque le bloc est configuré pour utiliser des entrées de valeurs externes.
  • Entrée de fin de ligne: n'a pas de connexion en bloc et agit toujours comme un retour à la ligne.

Vous pouvez également créer une entrée personnalisée pour prendre en charge le rendu personnalisé.

Le format JSON et l'API JavaScript utilisent des modèles légèrement différents pour décrire leurs entrées.

Entrées et champs au format JSON

Les blocs définis par JSON sont structurés comme une séquence de chaînes de messages interpolées ( message0, message1, ...), où chaque jeton d'interpolation (%1, %2, ...) est un champ ou une extrémité d'entrée (où le connecteur d'entrée affiche donc, dans le message) dans le tableau JSON argsN correspondant. Ce format est destiné à faciliter l'internationalisation.

JSON

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

Les jetons d'interpolation doivent correspondre exactement au tableau args0: pas de doublons, ni d'omissions. Les jetons peuvent être présents dans n'importe quel ordre, ce qui permet à différentes langues de modifier la mise en page du bloc.

Le texte de chaque côté d'un jeton d'interpolation est tronqué à l'aide d'espaces. Le texte utilisant le caractère % (par exemple, lorsqu'il fait référence à un pourcentage) doit utiliser %% pour qu'il ne soit pas interprété comme un jeton d'interpolation.

L'ordre des arguments et des types d'arguments définit la forme du bloc. La modification de l'une de ces chaînes peut complètement modifier la mise en page du bloc. Cela est particulièrement important dans les langues dont l'ordre des mots est différent de l'anglais. Prenons l'exemple d'un langage hypothétique dans lequel "set %1 to %2" (tel qu'utilisé dans l'exemple ci-dessus) doit être inversé pour indiquer "put %2 in %1". Si vous modifiez cette chaîne (et laissez le reste des données JSON intactes), le bloc suivant est généré:

Blockly a automatiquement modifié l'ordre des champs, créé une entrée factice et basculé d'entrées externes vers des entrées internes.

Blockly remplace également automatiquement tout caractère de retour à la ligne (\n) de la chaîne de message par une entrée de fin de ligne.

JSON

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

Args

Chaque chaîne de message est associée à un tableau args du même nombre. Par exemple, message0 va avec args0. Les jetons d'interpolation (%1, %2, ...) font référence aux éléments du tableau args. Chaque objet possède une chaîne type. Les autres paramètres varient en fonction du type:

Vous pouvez également définir vos propres champs personnalisés et entrées personnalisées, et les transmettre en tant qu'arguments.

Chaque objet peut également comporter un champ alt. Si Blockly ne reconnaît pas le type de l'objet, l'objet alt est utilisé à sa place. Par exemple, si un nouveau champ nommé field_time est ajouté à Blockly, les blocs utilisant ce champ peuvent utiliser alt pour définir un remplacement field_input pour les anciennes versions de 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"
        }
    }
  ]
}

Un objet alt peut avoir son propre objet alt, ce qui permet le chaînage. En fin de compte, si Blockly ne peut pas créer d'objet dans le tableau args0 (après avoir tenté d'utiliser des objets alt), cet objet est simplement ignoré.

Une entrée factice est automatiquement ajoutée à la fin du bloc si la chaîne message se termine par du texte ou des champs qui ne sont pas contenus dans une entrée. Ainsi, si la dernière entrée d'un bloc est une entrée factice, elle peut être omise du tableau args et n'a pas besoin d'être interpolée dans message. L'ajout automatique d'une entrée factice de fin de ligne permet aux traducteurs de modifier message sans avoir à modifier le reste du fichier JSON. Consultez l'exemple "set %1 to %2" (aucune entrée factice) et "put %2 in %1" (entrée factice ajoutée) plus tôt sur cette page.

implicitAlign0

Dans de rares cas, l'entrée factice de fin créée automatiquement doit être alignée sur "RIGHT" ou "CENTRE". Si aucune valeur n'est spécifiée, la valeur par défaut est "LEFT".

Dans l'exemple ci-dessous, message0 correspond à "send email to %1 subject %2 secure %3", et Blockly ajoute automatiquement une entrée factice pour la troisième ligne. Si vous définissez implicitAlign0 sur "RIGHT", cette ligne est alignée à droite. Cet alignement s'applique à toutes les entrées qui ne sont pas explicitement définies dans la définition du bloc JSON, y compris les entrées de fin de ligne qui remplacent les caractères de retour à la ligne ('\n') dans le message. Il existe également la propriété obsolète lastDummyAlign0 qui a le même comportement que implicitAlign0.

Lors de la conception de blocs pour les langues qui se lisent de droite à gauche (arabe et hébreu), les côtés gauche et droit sont inversés. Ainsi, "RIGHT" aligne les champs à gauche.

message1, args1 et implicitAlign1

Certains blocs sont naturellement divisés en deux ou plusieurs parties distinctes. Prenons l'exemple de ce bloc de répétition qui comporte deux lignes:

Si ce bloc était décrit dans un seul message, la propriété message0 serait "repeat %1 times %2 do %3". Cette chaîne pose problème pour un traducteur. Il est difficile d'expliquer ce que signifie la substitution %2. L'entrée factice %2 peut également ne pas être souhaitée dans certaines langues. Plusieurs blocs peuvent également souhaiter partager le texte de la deuxième ligne. Il est préférable que JSON utilise plusieurs propriétés de message et d'arguments:

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
}

Vous pouvez définir n'importe quel nombre de propriétés message, args et implicitAlign au format JSON, en commençant par 0 et en les incrémentant de manière séquentielle. Notez que la fabrique de blocs n'est pas capable de diviser les messages en plusieurs parties, mais une opération manuelle est simple.

Entrées et champs dans JavaScript

L'API JavaScript inclut une méthode append pour chaque type d'entrée:

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

Chaque méthode d'ajout peut accepter une chaîne d'identifiant, utilisée par les générateurs de code. Les entrées factices et de fin de ligne ont rarement besoin d'être référencées, et l'identifiant n'est généralement pas défini.

L'API JavaScript inclut également une méthode appendInput générique pour ajouter des entrées personnalisées. Notez que dans ce cas, l'identifiant doit être transmis directement au constructeur de votre entrée personnalisée.

JavaScript

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

Toutes les méthodes appendInput (génériques et non génériques) renvoient l'objet d'entrée afin qu'elles puissent être configurées à l'aide du chaînage de méthodes. Trois méthodes intégrées permettent de configurer les entrées.

setCheck

JavaScript

input.setCheck('Number');

Cette fonction facultative est utilisée pour vérifier le type des entrées connectées. Si l'argument est "null", la valeur par défaut est "null", cette entrée peut être connectée à n'importe quel bloc. Pour en savoir plus, consultez la section Vérifications du type.

setAlign

JavaScript

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

Cette fonction facultative permet d'aligner les champs (voir ci-dessous). Trois valeurs autodescriptives peuvent être transmises en tant qu'argument à cette fonction : Blockly.inputs.Align.LEFT, Blockly.inputs.Align.RIGHT et Blockly.inputs.Align.CENTER.

Lors de la conception de blocs pour les langues qui se lisent de droite à gauche (arabe et hébreu), les côtés gauche et droit sont inversés. Ainsi, Blockly.inputs.Align.RIGHT aligne les champs à gauche.

appendField

Une fois qu'une entrée a été créée et ajoutée à un bloc avec appendInput, il est possible d'ajouter un nombre illimité de champs à l'entrée. Ces champs sont souvent utilisés comme étiquettes pour décrire à quoi sert chaque entrée.

JavaScript

input.appendField('hello');

L'élément de champ le plus simple est le texte. La convention de Blockly consiste à utiliser du texte en minuscules, à l'exception des noms propres (par exemple, Google ou SQL).

Une ligne d'entrée peut contenir un nombre illimité d'éléments de champ. Plusieurs appels appendField peuvent être enchaînés pour ajouter efficacement plusieurs champs à la même ligne d'entrée.

JavaScript

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

L'appel appendField('hello') est en réalité un raccourci permettant d'utiliser un constructeur FieldLabel explicite: appendField(new Blockly.FieldLabel('hello')). Le seul cas d'utilisation du constructeur est lorsque vous spécifiez un nom de classe pour que le texte puisse être stylisé à l'aide d'une règle CSS.

Intégrée ou externe

Les entrées de bloc peuvent être affichées en tant qu'entrées externes ou internes.

La définition du bloc peut spécifier une valeur booléenne facultative qui contrôle si les entrées sont intégrées ou non. Si la valeur est false, toutes les entrées de valeur seront externes (comme le bloc de gauche). Si la valeur est true, toutes les entrées de valeur seront intégrées (comme le bloc de droite ci-dessus).

JSON

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

JavaScript

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

S'il n'est pas défini, Blockly utilise une méthode heuristique pour déterminer le mode le plus adapté. Si Blockly fait le bon choix, il est préférable de ne pas définir ce champ, car différentes traductions peuvent avoir automatiquement différents modes. Consultez l'exemple JSON "set %1 to %2" (entrées externes) et "put %2 in %1" (entrées intégrées) plus tôt sur cette page.

Utilisez des entrées intégrées lorsqu'un bloc est susceptible de comporter de petites entrées, telles que des nombres. L'utilisateur peut activer/désactiver cette option via le menu contextuel si la configuration collapse est activée (la valeur par défaut est "true" si la boîte à outils comporte des catégories).

Champs

Les champs définissent la majorité des éléments d'interface utilisateur au sein d'un bloc. Ceux-ci incluent les étiquettes de chaîne, les images et les entrées pour les données littérales telles que les chaînes et les nombres. L'exemple le plus simple est le bloc math_number, qui utilise un field_input pour permettre à l'utilisateur de saisir un nombre.

Les champs sont ajoutés au bloc à l'aide de appendField.

Blockly fournit un certain nombre de champs intégrés, y compris des entrées de texte, des sélecteurs de couleur et des images. Vous pouvez également créer vos propres champs.

→ En savoir plus sur les champs intégrés

→ En savoir plus sur la création de champs personnalisés

Icônes

Les icônes définissent des éléments d'interface utilisateur sur un bloc, qui affichent des informations "meta" concernant le bloc.

Les icônes sont ajoutées au bloc à l'aide de la commande addIcon.

Blockly fournit un certain nombre d'icônes intégrées, y compris des icônes de commentaire et d'avertissement. Vous pouvez également créer vos propres icônes.

→ En savoir plus sur la création d'icônes personnalisées

Info-bulles

Les info-bulles offrent une aide instantanée lorsque l'utilisateur pointe sa souris sur le bloc. Si le texte est long, il est automatiquement renvoyé à la ligne.

JSON

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

JavaScript

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

Dans l'API JavaScript, les info-bulles peuvent également être définies comme une fonction et non comme une chaîne statique. Cela permet une aide dynamique. Consultez math_arithmetic pour obtenir un exemple d'info-bulle qui change en fonction de l'option choisie dans le menu déroulant.

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

À l'aide de l'API JavaScript, les blocs peuvent spécifier une fonction au lieu d'une chaîne statique, qui renvoie une chaîne d'info-bulle. Cela permet d'afficher des info-bulles dynamiques. Consultez math_arithmetic pour obtenir un exemple.

Personnalisation

Vous pouvez également personnaliser l'apparence de vos info-bulles en fournissant une fonction d'affichage personnalisé. Créez une fonction qui accepte deux paramètres:

  • d'abord, un élément <div> dans lequel vous afficherez le contenu
  • l'élément sur lequel l'utilisateur passe la souris et sur lequel l'info-bulle s'affiche.

Dans le corps de la fonction, vous pouvez afficher le contenu de votre choix dans l'élément div. Pour obtenir la chaîne d'info-bulles définie sur le bloc passé avec la souris, vous pouvez appeler Blockly.Tooltip.getTooltipOfObject(element);, où element est le deuxième paramètre ci-dessus.

Enfin, enregistrez cette fonction afin que Blockly puisse l'appeler au moment approprié:

Blockly.Tooltip.setCustomTooltip(yourFnHere);

Pour obtenir un exemple, consultez la démonstration Info-bulles personnalisées.

URL de l'aide

Les blocs peuvent être associés à une page d'aide. Cette option est disponible pour les utilisateurs de Blockly pour le Web en effectuant un clic droit sur le bloc, puis en sélectionnant "Aide" dans le menu contextuel. Si cette valeur est null, le menu est grisé.

JSON

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

JavaScript

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

Avec l'API JavaScript, les blocs peuvent spécifier une fonction au lieu d'une chaîne statique, qui renvoie une chaîne d'URL, ce qui permet une aide dynamique.

Écouteurs et programmes de validation de modifications

Les blocs peuvent comporter des fonctions d'écouteur de modification qui sont appelées lors de toute modification apportée à l'espace de travail (y compris celles qui ne sont pas liées au bloc). Ils sont principalement utilisés pour définir le texte d'avertissement du bloc ou une notification utilisateur similaire en dehors de l'espace de travail.

Cette fonction est ajoutée en appelant setOnChange avec une fonction et peut être effectuée lors d'init ou via une extension JSON si vous prévoyez de l'utiliser sur toutes les plates-formes.

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

Le système appelle la fonction, en transmettant l'événement de modification. Dans la fonction, this fait référence à l'instance de bloc.

Étant donné que la fonction est appelée lors de toute modification, si elle est utilisée, les développeurs doivent s'assurer que l'écouteur s'exécute rapidement. Vous devez également vous méfier des modifications apportées à l'espace de travail qui pourraient être appliquées en cascade ou en retour à l'écouteur.

Consultez les blocs controls_flow_statements, logic_compare et procedures_ifreturn pour obtenir des exemples.

Notez que les champs modifiables possèdent leurs propres écouteurs d'événements pour valider les entrées et entraîner des effets secondaires.

Mutateur

Les mutations permettent de modifier la forme des blocs avancés, notamment à la suite de l'ouverture d'une boîte de dialogue permettant aux utilisateurs d'ajouter, de supprimer ou de réorganiser des composants. Les mutateurs peuvent être ajoutés via JSON à l'aide de la clé mutator.

JSON

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

Configuration par bloc

Les instances de bloc possèdent un certain nombre de propriétés qui configurent leur comportement vis-à-vis de l'utilisateur. Ils permettent de contraindre l'espace de travail à refléter certaines propriétés du domaine (par exemple, il y a exactement un événement de démarrage) ou à concentrer les efforts de l'utilisateur (par exemple, un tutoriel).

État pouvant être supprimé

block.setDeletable(false);

Si cette règle est définie sur "false", l'utilisateur ne peut pas supprimer le bloc. Par défaut, les blocages peuvent être supprimés sur un espace de travail modifiable.

Tous les blocages, même ceux qui ne peuvent pas être supprimés, peuvent être supprimés par programmation:

block.dispose();

État modifiable

block.setEditable(false);

Si cette règle est définie sur "false", l'utilisateur ne peut pas modifier les champs du bloc (par exemple, les menus déroulants et les entrées de texte). Par défaut, les blocages sont modifiables sur un espace de travail modifiable.

État mobile

block.setMovable(false);

Lorsque cette règle est définie sur "false", l'utilisateur ne peut pas déplacer le bloc directement. Un bloc fixe qui est l'enfant d'un autre bloc ne peut pas être déconnecté de ce bloc, bien qu'il soit déplacé avec son parent si celui-ci est déplacé. Bloque par défaut pour être déplaçables dans un espace de travail modifiable.

N'importe quel bloc (même celles qui ne peuvent pas être déplacées) peut être déplacé par programmation une fois qu'il se trouve sur un espace de travail.

block.moveBy(dx, dy)

La position de départ d'un bloc dans un espace de travail est définie par défaut (0, 0).

Bloquer les données

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

"data" correspond à une chaîne facultative et arbitraire associée au bloc. Lorsque le bloc est sérialisé, la chaîne de données est sérialisée avec lui. Cela inclut les cas de duplication ou de copier-coller du bloc.

Elle est souvent utilisée pour associer un bloc à une ressource externe.

Lorsqu'elles sont sérialisées en JSON, les données sont stockées en tant que propriété de premier niveau dans le bloc:

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

Lorsqu'elle est sérialisée en XML (l'ancien système de sérialisation glacé), la chaîne de données est stockée dans une balise <data></data> à l'intérieur du bloc:

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

Destruction

Les blocs comportent un hook destroy, appelé lorsqu'ils sont supprimés de l'espace de travail. Cela permet de détruire les modèles de données de sauvegarde/ressources externes associés au bloc dont vous n'avez plus besoin.

JSON

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

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

JavaScript

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

La méthode destroy est appelée après la suppression du parent du bloc, mais avant la suppression de ses enfants ou de ses champs.

Menus contextuels

Par défaut, les blocs disposent d'un menu contextuel (accessible par clic droit) qui permet aux utilisateurs d'effectuer des actions telles que l'ajout de commentaires ou la duplication de blocages.

Vous pouvez désactiver le menu contextuel d'un blocage spécifique en procédant comme suit:

block.contextMenu = false;

Vous pouvez également personnaliser les options affichées dans le menu. Pour personnaliser le menu pour tous les blocs, consultez la documentation sur les menus contextuels. Pour personnaliser le menu d'un bloc individuel, vous pouvez implémenter customContextMenu. Cette fonction utilise un tableau d'options de menu et la modifie en place, ce qui signifie que vous pouvez à la fois ajouter et supprimer des éléments.

Chaque option de menu est un objet possédant trois propriétés:

  • text correspond au texte à afficher.
  • enabled est une valeur booléenne. Lorsqu'elle est désactivée, l'option est affichée en gris.
  • callback est la fonction à appeler lorsque l'utilisateur clique sur l'option.