Avant de créer un type de champ, déterminez si l'un des autres méthodes pour personnaliser les champs selon vos besoins. Si votre application doit stocker un ou que vous souhaitez créer une interface utilisateur pour un type de valeur existant, vous vous devrez probablement créer un nouveau type de champ.
Pour créer un champ, procédez comme suit:
- Implémentez un constructeur.
- Enregistrez une clé JSON et implémentez
fromJson
. - Gérer l'initialisation de l'interface utilisateur et de l'événement dans le bloc des écouteurs.
- Gérer la suppression des écouteurs d'événements (la suppression de l'UI est gérée pour vous).
- Implémentez la gestion de la valeur.
- Ajoutez une représentation textuelle de la valeur de votre champ pour améliorer l'accessibilité.
- Ajoutez des fonctionnalités supplémentaires, par exemple: <ph type="x-smartling-placeholder">
- Configurez d'autres aspects de votre champ, par exemple: <ph type="x-smartling-placeholder">
Dans cette section, nous partons du principe que vous avez lu et que vous connaissez le contenu des Anatomie d'une Champ.
Pour voir un exemple de champ personnalisé, consultez la rubrique Champs personnalisés démo pour en savoir plus.
Implémenter un constructeur
Le constructeur du champ est chargé de configurer la valeur initiale du champ et éventuellement de configurer un réseau local programme de validation. L'attribut personnalisé constructeur du champ est appelé lors de l'initialisation du bloc source, indépendamment indiquant si le bloc source est défini en JSON ou en JavaScript. Ainsi, n'a pas accès au bloc source pendant la construction.
L'exemple de code suivant crée un champ personnalisé nommé GenericField
:
class GenericField extends Blockly.Field {
constructor(value, validator) {
super(value, validator);
this.SERIALIZABLE = true;
}
}
Signature de la méthode
Les constructeurs de champs utilisent généralement une valeur et un validateur local. La valeur est
est facultatif, et si vous ne transmettez pas de valeur (ou si vous transmettez une valeur qui échoue à la classe
validation), la valeur par défaut de la super-classe sera utilisée. Pour le
la classe Field
par défaut, cette valeur est null
. Si vous ne voulez pas que cette valeur par défaut
, assurez-vous de transmettre une valeur appropriée. Le paramètre de l'outil de validation
s'affichent dans les champs modifiables et sont généralement marqués comme facultatifs. En savoir plus
les validateurs dans la section Validators
d'assistance.
Structure
La logique de votre constructeur doit suivre ce flux:
- Appelez le super-constructeur hérité (tous les champs personnalisés doivent hériter de
Blockly.Field
ou l'une de ses sous-classes) pour initialiser correctement la valeur et définissez l'outil de validation local pour votre champ. - Si votre champ est sérialisable, définissez la propriété correspondante dans la d'un constructeur. Les champs modifiables doivent être sérialisables et les champs modifiables par défaut. Vous devriez donc probablement définir cette propriété sur "true", il ne devrait pas être sérialisable.
- Facultatif: personnalisez davantage votre campagne (par exemple, Champs de libellé). permettre la transmission d'une classe CSS, qui est ensuite appliquée au texte).
JSON et enregistrement
Dans un bloc JSON
définitions,
sont décrits par une chaîne (par exemple, field_number
, field_textinput
).
Il gère Blockly une correspondance entre ces chaînes et des objets de champ, et appelle
fromJson
sur l'objet approprié pendant la construction.
Appelez Blockly.fieldRegistry.register
pour ajouter votre type de champ à cette carte.
en transmettant la classe field comme deuxième argument:
Blockly.fieldRegistry.register('field_generic', GenericField);
Vous devez également définir votre fonction fromJson
. Votre implémentation doit
déréférencez d'abord une chaîne
tableau
des références à l'aide de
replaceMessageReferences,
puis transmettre les valeurs au constructeur.
GenericField.fromJson = function(options) {
const value = Blockly.utils.parsing.replaceMessageReferences(
options['value']);
return new CustomFields.GenericField(value);
};
Initialisation…
Lorsque votre champ est créé, il ne contient essentiellement qu'une valeur. L'initialisation est l'endroit où le DOM est créé, c'est-à-dire le modèle (si le champ possède un modèle), et les événements sont liés.
Écran On-Block
Lors de l'initialisation, vous êtes responsable de la création de tout ce dont vous aurez besoin pour l'affichage sur bloc du champ.
Valeurs par défaut, arrière-plan et texte
La fonction initView
par défaut crée un élément rect
de couleur claire et un élément
text
. Si vous voulez que votre domaine comprenne ces deux éléments, plus quelques
des goodies, appelez la fonction initView
de super-classe avant d'ajouter le reste de votre
éléments DOM. Si vous voulez que votre domaine en comporte un, mais pas les deux,
vous pouvez utiliser les fonctions createBorderRect_
ou createTextElement_
.
Personnaliser la construction du DOM
Si votre champ est un champ de texte générique (par exemple, Texte
d'entrée),
La construction du DOM sera traitée pour vous. Sinon, vous devrez remplacer
la fonction initView
pour créer les éléments DOM dont vous aurez besoin
le rendu futur de votre champ.
Par exemple, un champ déroulant peut contenir à la fois des images et du texte. En initView
,
crée un seul élément image et un seul élément de texte. Puis pendant render_
l'élément actif est affiché et l'autre est masqué, en fonction du type
sélectionnée.
Pour créer des éléments DOM, vous pouvez utiliser la méthode
Blockly.utils.dom.createSvgElement
, ou à l'aide de la création DOM traditionnelle
méthodes.
Les conditions requises pour l'affichage dans les blocs d'un champ sont les suivantes:
- Tous les éléments DOM doivent être des enfants de l'élément
fieldGroup_
du champ. Champ est créé automatiquement. - Tous les éléments DOM doivent rester dans les dimensions signalées du champ.
Consultez le Affichage pour en savoir plus sur la personnalisation et la mise à jour de votre affichage pour les blocs.
Ajouter des symboles textuels
Si vous souhaitez ajouter des symboles au texte d'un champ (comme
Angle
symbole degré du champ), vous pouvez ajouter l'élément de symbole (généralement contenu dans
<tspan>
) directement dans la textElement_
du champ.
Événements de saisie
Par défaut, les champs enregistrent les événements d'info-bulle et les événements de survol (à utiliser pour
affichage
éditeurs).
Si vous souhaitez écouter d'autres types d'événements (par exemple, si vous voulez gérer
(faire glisser sur un champ), vous devez remplacer la fonction bindEvents_
du champ.
bindEvents_() {
// Call the superclass function to preserve the default behavior as well.
super.bindEvents_();
// Then register your own additional event listeners.
this.mouseDownWrapper_ =
Blockly.browserEvents.conditionalBind(this.getClickTarget_(), 'mousedown', this,
function(event) {
this.originalMouseX_ = event.clientX;
this.isMouseDown_ = true;
this.originalValue_ = this.getValue();
event.stopPropagation();
}
);
this.mouseMoveWrapper_ =
Blockly.browserEvents.conditionalBind(document, 'mousemove', this,
function(event) {
if (!this.isMouseDown_) {
return;
}
var delta = event.clientX - this.originalMouseX_;
this.setValue(this.originalValue_ + delta);
}
);
this.mouseUpWrapper_ =
Blockly.browserEvents.conditionalBind(document, 'mouseup', this,
function(_event) {
this.isMouseDown_ = false;
}
);
}
Pour créer un lien avec un événement, vous devez généralement utiliser
Blockly.utils.browserEvents.conditionalBind
. Cette méthode de liaison d'événements filtre les touches secondaires pendant
fait glisser. Si vous souhaitez que votre gestionnaire s'exécute même pendant un déplacement en cours
vous pouvez utiliser
Blockly.browserEvents.bind
.
Mise au rebut
Si vous avez enregistré des écouteurs d'événements personnalisés dans l'bindEvents_
du champ
leur enregistrement dans la fonction dispose
doit être annulé.
Si vous avez correctement initialisé le
vue
de votre champ (en ajoutant tous les éléments DOM à fieldGroup_
), la fonction
le DOM du champ seront automatiquement supprimés.
Traitement de la valeur
→ Pour plus d'informations sur la valeur d'un champ et son texte, consultez la section Anatomie d'une .
Ordre de validation
Implémenter un validateur de classe
Les champs ne doivent accepter que certaines valeurs. Par exemple, les champs numériques ne doivent les nombres, les champs de couleur ne doivent accepter que les couleurs, etc. en classe et en local programmes de validation. La classe les programmes de validation suivent les mêmes règles que les validateurs locaux, à la différence qu'il est aussi exécuté dans constructeur et ne doit donc pas faire référence au bloc source.
Pour implémenter l'outil de validation des classes de votre champ, remplacez doClassValidation_
.
doClassValidation_(newValue) {
if (typeof newValue != 'string') {
return null;
}
return newValue;
};
Traiter les valeurs valides
Si la valeur transmise à un champ comportant setValue
est valide, vous recevez une
Rappel doValueUpdate_
. Par défaut, la fonction doValueUpdate_
:
- Définit la propriété
value_
surnewValue
. - Définit la
isDirty_
surtrue
.
Si vous avez simplement besoin de stocker la valeur et que vous ne voulez pas effectuer de traitement personnalisé,
vous n'avez pas besoin de remplacer doValueUpdate_
.
Vous pouvez également effectuer les opérations suivantes:
- Stockage personnalisé de
newValue
. - Modifiez d'autres propriétés en fonction de
newValue
. - Enregistrer si la valeur actuelle est valide ou non.
Vous devez ignorer doValueUpdate_
:
doValueUpdate_(newValue) {
super.doValueUpdate_(newValue);
this.displayValue_ = newValue;
this.isValueValid_ = true;
}
Traiter les valeurs non valides
Si la valeur transmise au champ avec setValue
n'est pas valide, vous recevez une
Rappel doValueInvalid_
. Par défaut, la fonction doValueInvalid_
effectue
rien. Cela signifie que, par défaut, les valeurs non valides ne seront pas affichées. Il y a aussi
signifie que le champ ne sera pas renvoyé, car
isDirty_
ne sera pas définie.
Si vous souhaitez afficher des valeurs non valides, vous devez remplacer doValueInvalid_
.
Dans la plupart des cas, vous devez définir une propriété displayValue_
sur
valeur incorrecte, définir
isDirty_
à true
, et remplacer
render_
pour que l'affichage en mode bloc se mette à jour en fonction de displayValue_
au lieu de la
value_
doValueInvalid_(newValue) {
this.displayValue_ = newValue;
this.isDirty_ = true;
this.isValueValid_ = false;
}
Valeurs en plusieurs parties
Lorsque votre champ contient une valeur en plusieurs parties (ex. : listes, vecteurs, objets), vous peuvent souhaiter que les parties soient traitées comme des valeurs individuelles.
doClassValidation_(newValue) {
if (FieldTurtle.PATTERNS.indexOf(newValue.pattern) == -1) {
newValue.pattern = null;
}
if (FieldTurtle.HATS.indexOf(newValue.hat) == -1) {
newValue.hat = null;
}
if (FieldTurtle.NAMES.indexOf(newValue.turtleName) == -1) {
newValue.turtleName = null;
}
if (!newValue.pattern || !newValue.hat || !newValue.turtleName) {
this.cachedValidatedValue_ = newValue;
return null;
}
return newValue;
}
Dans l'exemple ci-dessus, chaque propriété de newValue
est validée individuellement. Ensuite,
à la fin de la fonction doClassValidation_
, si une propriété individuelle est
non valide, la valeur est mise en cache dans la propriété cacheValidatedValue_
avant
retour de null
(non valide). Mettre en cache l'objet avec des données validées individuellement
permet au
doValueInvalid_
pour les gérer séparément, simplement en effectuant
!this.cacheValidatedValue_.property
, au lieu de les revalider
individuellement.
Ce modèle de validation des valeurs en plusieurs parties peut également être utilisé dans des localisations de validation, il n'existe actuellement aucun moyen d'appliquer ce modèle.
isDirty_
isDirty_
est un indicateur utilisé dans la
setValue
la fonction, ainsi que d'autres parties du champ, pour savoir si le champ doit être
à nouveau. Si la valeur d'affichage du champ a changé, isDirty_
doit généralement
doit être définie sur true
.
Texte
→ Pour en savoir plus sur l'utilisation et les différences du texte d'un champ de la valeur du champ, consultez la section Anatomie d'une .
Si le texte de votre champ est différent de la valeur de votre champ, vous devez
remplacer
Fonction getText
pour fournir le texte correct.
getText() {
let text = this.value_.turtleName + ' wearing a ' + this.value_.hat;
if (this.value_.hat == 'Stovepipe' || this.value_.hat == 'Propeller') {
text += ' hat';
}
return text;
}
Créer un éditeur
Si vous définissez la fonction showEditor_
, Blockly écoutera automatiquement
les clics et appeler showEditor_
au moment opportun. Vous pouvez afficher n'importe quel code HTML
dans votre éditeur en l'encapsulant avec l'un des deux div spéciaux, appelé "DropDownDiv",
et WidgetDiv, qui flottent au-dessus du reste de l'UI de Blockly.
DropDownDiv et WidgetDiv
Le DropDownDiv
permet de fournir des éditeurs qui se trouvent dans une boîte connectée.
à un champ. Il se positionne automatiquement pour être près du champ tout en restant
dans les limites visibles. Le sélecteur d'angle et le sélecteur de couleur sont de bons exemples
le DropDownDiv
.
Le WidgetDiv
permet de
en fournissant des éditeurs
qui ne se trouvent pas dans une boîte. Les champs numériques utilisent le paramètre
WidgetDiv pour couvrir le champ avec une zone de saisie de texte HTML. Alors que la classe DropDownDiv
gère automatiquement le positionnement, contrairement à WidgetDiv. Les éléments devront être
positionné manuellement. Le système de coordonnées est exprimé en coordonnées en pixels par rapport
en haut à gauche de la fenêtre. L'éditeur de saisie de texte est un bon exemple
WidgetDiv
Exemple de code DropDownDiv
showEditor_() {
// Create the widget HTML
this.editor_ = this.dropdownCreate_();
Blockly.DropDownDiv.getContentDiv().appendChild(this.editor_);
// Set the dropdown's background colour.
// This can be used to make it match the colour of the field.
Blockly.DropDownDiv.setColour('white', 'silver');
// Show it next to the field. Always pass a dispose function.
Blockly.DropDownDiv.showPositionedByField(
this, this.disposeWidget_.bind(this));
}
Exemple de code WidgetDiv
showEditor_() {
// Show the div. This automatically closes the dropdown if it is open.
// Always pass a dispose function.
Blockly.WidgetDiv.show(
this, this.sourceBlock_.RTL, this.widgetDispose_.bind(this));
// Create the widget HTML.
var widget = this.createWidget_();
Blockly.WidgetDiv.getDiv().appendChild(widget);
}
Nettoyer
Les éléments DropDownDiv et WidgetDiv détruits le code HTML du widget mais vous devez supprimer manuellement tous les écouteurs d'événements appliquée à ces éléments.
widgetDispose_() {
for (let i = this.editorListeners_.length, listener;
listener = this.editorListeners_[i]; i--) {
Blockly.browserEvents.unbind(listener);
this.editorListeners_.pop();
}
}
La fonction dispose
est appelée dans un contexte null
sur le DropDownDiv
. Activé
le WidgetDiv
, il est appelé dans le contexte de WidgetDiv
. Dans les deux cas
il est préférable d'utiliser
liaison
lors de la transmission d'une fonction "dispose", comme indiqué dans le DropDownDiv
ci-dessus.
et WidgetDiv
.
→ Pour en savoir plus sur la suppression et non sur celle des éditeurs, consultez Mise au rebut.
Mise à jour de l'écran de blocage...
La fonction render_
permet de mettre à jour l'affichage du champ dans le bloc afin qu'il corresponde
sa valeur interne.
Voici quelques exemples courants :
- Modifier le texte (menu déroulant)
- Modifier la couleur
Valeurs par défaut
La fonction render_
par défaut définit le texte à afficher sur le résultat de la
getDisplayText_
. La fonction getDisplayText_
renvoie la propriété value_
du champ.
en une chaîne, après avoir été tronquée pour respecter le nombre maximal de caractères
Si vous utilisez l'affichage par défaut des blocs d'annonces bloqués et le comportement par défaut du texte
fonctionne pour votre champ, il n'est pas nécessaire de remplacer render_
.
Si le comportement du texte par défaut fonctionne pour votre champ, mais que celui-ci est bloqué
contient des éléments statiques supplémentaires, vous pouvez appeler la méthode render_
par défaut
, mais vous devrez tout de même la remplacer pour mettre à jour le paramètre
taille.
Si le comportement par défaut du texte ne fonctionne pas pour votre champ ou si la fonction
l'écran de blocage comporte des éléments dynamiques supplémentaires, vous devez personnaliser
le render_
de commande.
Personnaliser le rendu
Si le comportement d'affichage par défaut ne fonctionne pas pour votre champ, vous devez définir le comportement d'affichage personnalisé. Il peut s'agir, par exemple, de définir des le texte d'affichage, les éléments d'une image, la mise à jour des couleurs d'arrière-plan...
Toutes les modifications d'attributs DOM sont autorisées. Les deux seules choses à retenir sont les suivantes:
- La création d'un DOM doit être gérée initialisation car il est plus efficace.
- Vous devez toujours mettre à jour le
size_
pour qu'elle corresponde à la taille de l'écran de bloc.
render_() {
switch(this.value_.hat) {
case 'Stovepipe':
this.stovepipe_.style.display = '';
break;
case 'Crown':
this.crown_.style.display = '';
break;
case 'Mask':
this.mask_.style.display = '';
break;
case 'Propeller':
this.propeller_.style.display = '';
break;
case 'Fedora':
this.fedora_.style.display = '';
break;
}
switch(this.value_.pattern) {
case 'Dots':
this.shellPattern_.setAttribute('fill', 'url(#polkadots)');
break;
case 'Stripes':
this.shellPattern_.setAttribute('fill', 'url(#stripes)');
break;
case 'Hexagons':
this.shellPattern_.setAttribute('fill', 'url(#hexagons)');
break;
}
this.textContent_.nodeValue = this.value_.turtleName;
this.updateSize_();
}
Mise à jour de la taille...
Il est très important de mettre à jour la propriété size_
d'un champ, car elle renseigne le
comment positionner le champ. La meilleure façon
de déterminer
exactement ce que devrait être size_
en expérimentant.
updateSize_() {
const bbox = this.movableGroup_.getBBox();
let width = bbox.width;
let height = bbox.height;
if (this.borderRect_) {
width += this.constants_.FIELD_BORDER_RECT_X_PADDING * 2;
height += this.constants_.FIELD_BORDER_RECT_X_PADDING * 2;
this.borderRect_.setAttribute('width', width);
this.borderRect_.setAttribute('height', height);
}
// Note how both the width and the height can be dynamic.
this.size_.width = width;
this.size_.height = height;
}
Couleurs de bloc assorties
Si vous souhaitez que les éléments de votre champ correspondent aux couleurs du bloc,
vous devez remplacer la méthode applyColour
. Vous devez
accéder à la couleur via la propriété de style du bloc.
applyColour() {
const sourceBlock = this.sourceBlock_;
if (sourceBlock.isShadow()) {
this.arrow_.style.fill = sourceBlock.style.colourSecondary;
} else {
this.arrow_.style.fill = sourceBlock.style.colourPrimary;
}
}
Mise à jour de la modification...
Vous pouvez utiliser la fonction updateEditable
pour modifier l'apparence d'un champ.
selon qu'il est modifiable ou non. La fonction par défaut permet
L'arrière-plan comporte ou n'affiche pas de réponse de survol (bordure) s'il est ou n'est pas modifiable.
La taille de l'écran ne doit pas changer en fonction de sa capacité de modification, mais
toutes les autres modifications sont autorisées.
updateEditable() {
if (!this.fieldGroup_) {
// Not initialized yet.
return;
}
super.updateEditable();
const group = this.getClickTarget_();
if (!this.isCurrentlyEditable()) {
group.style.cursor = 'not-allowed';
} else {
group.style.cursor = this.CURSOR;
}
}
Sérialisation
La sérialisation consiste à enregistrer l'état du champ pour pouvoir le recharger ultérieurement dans l'espace de travail.
L'état de votre espace de travail inclut toujours la valeur du champ, mais il peut également inclure d'autres états, tels que l'état de l'UI de votre champ. Par exemple, si votre était une carte sur laquelle l'utilisateur pouvait zoomer, permettant à l'utilisateur de sélectionner des pays, sérialise également le niveau de zoom.
Si votre champ est sérialisable, vous devez définir la propriété SERIALIZABLE
sur
true
Blockly fournit deux ensembles de hooks de sérialisation pour les champs. Une paire de crochets fonctionne avec le nouveau système de sérialisation JSON, tandis que l'autre paire fonctionne avec le de l'ancien système de sérialisation XML.
saveState
et loadState
saveState
et loadState
sont des hooks de sérialisation qui fonctionnent avec le nouveau fichier JSON
système de sérialisation.
Dans certains cas, vous n'avez pas besoin de les fournir, car
les implémentations fonctionneront. Si (1) votre champ est une sous-classe directe de la base
Blockly.Field
, (2) votre valeur est un sérialisable JSON.
type, et (3) il vous suffit de
sérialiser la valeur, l'implémentation par défaut fonctionnera parfaitement.
Sinon, votre fonction saveState
doit renvoyer une valeur JSON sérialisable
objet/valeur qui représente l'état du champ. Et votre loadState
doit accepter le même objet/la même valeur sérialisable JSON et l'appliquer à
sur le terrain.
saveState() {
return {
'country': this.getValue(), // Value state
'zoom': this.getZoomLevel(), // UI state
};
}
loadState(state) {
this.setValue(state['country']);
this.setZoomLevel(state['zoom']);
}
Sérialisation complète et données de sauvegarde
saveState
reçoit également un paramètre facultatif doFullSerialization
. C'est
utilisés par les champs qui font normalement référence à un état sérialisé par une autre
sérialiseur (comme les modèles de données de sauvegarde). Le paramètre indique que
l'état référencé n'est pas disponible lorsque le bloc est désérialisé. Par conséquent,
doit effectuer toute la sérialisation elle-même. Par exemple, c'est le cas lorsque
un bloc individuel est sérialisé ou lorsqu'un bloc est copié-collé.
Voici deux cas d'utilisation courants:
- Lorsqu'un bloc individuel est chargé dans un espace de travail où les données de sauvegarde n'existe pas, le champ contient suffisamment d'informations dans son propre état pour créer un modèle de données.
- Lorsqu'un bloc est copié-collé, le champ crée toujours un support au lieu de référencer un modèle existant.
L'un des champs qui l'utilise est le champ de variable intégrée. Normalement, il sérialise
L'ID de la variable à laquelle il fait référence, mais si la valeur de doFullSerialization
est "true"
il sérialise tous ses états.
saveState(doFullSerialization) {
const state = {'id': this.variable_.getId()};
if (doFullSerialization) {
state['name'] = this.variable_.name;
state['type'] = this.variable_.type;
}
return state;
}
loadState(state) {
const variable = Blockly.Variables.getOrCreateVariablePackage(
this.getSourceBlock().workspace,
state['id'],
state['name'], // May not exist.
state['type']); // May not exist.
this.setValue(variable.getId());
}
Le champ "variable" effectue cette opération pour garantir que, si le fichier est chargé dans un espace de travail, où sa variable n'existe pas, il peut créer une nouvelle variable à référencer.
toXml
et fromXml
toXml
et fromXml
sont des hooks de sérialisation qui fonctionnent avec l'ancien fichier XML.
système de sérialisation. N'utilisez ces hooks que si c'est nécessaire (par exemple, si vous travaillez
sur un ancien codebase qui n'a pas encore été migré), sinon utilisez saveState
et
loadState
Votre fonction toXml
doit renvoyer un nœud XML qui représente l'état de
sur le terrain. Votre fonction fromXml
doit accepter le même nœud XML et s'appliquer
sur le terrain.
toXml(fieldElement) {
fieldElement.textContent = this.getValue();
fieldElement.setAttribute('zoom', this.getZoomLevel());
return fieldElement;
}
fromXml(fieldElement) {
this.setValue(fieldElement.textContent);
this.setZoomLevel(fieldElement.getAttribute('zoom'));
}
Propriétés modifiables et sérialisables
La propriété EDITABLE
détermine si le champ doit comporter une UI pour indiquer que
avec lequel il est possible d'interagir. Sa valeur par défaut est true
.
La propriété SERIALIZABLE
détermine si le champ doit être sérialisé. Il
la valeur par défaut est false
. Si cette propriété est true
, vous devrez peut-être fournir
fonctions de sérialisation et de désérialisation (voir
sérialisation).
Personnaliser le curseur
La propriété CURSOR
détermine le curseur que les utilisateurs voient lorsqu'ils pointent sur
votre domaine. Il doit s'agir d'une chaîne de curseur CSS valide. La valeur par défaut est le curseur
défini par .blocklyDraggable
, qui correspond au curseur de sélection.