Avant de créer un type de champ, déterminez si l'une des autres méthodes de personnalisation des champs répond à vos besoins. Si votre application doit stocker un nouveau type de valeur ou si vous souhaitez créer une interface utilisateur pour un type de valeur existant, vous devrez probablement créer un type de champ.
Pour créer un champ :
- Implémenter un constructeur
- Enregistrez une clé JSON et implémentez
fromJson
. - Gérez l'initialisation de l'UI et des écouteurs d'événements sur le bloc.
- Gérez la suppression des écouteurs d'événements (la suppression de l'UI est gérée pour vous).
- Implémentez la gestion des valeurs.
- Ajoutez une représentation textuelle de la valeur de votre champ pour l'accessibilité.
- Ajoutez des fonctionnalités supplémentaires, telles que :
- Configurez d'autres aspects de votre champ, tels que :
Dans cette section, nous partons du principe que vous avez lu et que vous connaissez le contenu de la section Anatomie d'un champ.
Pour obtenir un exemple de champ personnalisé, consultez la démonstration des champs personnalisés.
Implémenter un constructeur
Le constructeur du champ est responsable de la configuration de la valeur initiale du champ et, éventuellement, de la configuration d'un validateur local. Le constructeur du champ personnalisé est appelé lors de l'initialisation du bloc source, que le bloc source soit défini en JSON ou en JavaScript. Le champ personnalisé n'a donc pas accès au bloc source lors de 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 acceptent généralement une valeur et un validateur local. La valeur est facultative. Si vous n'en transmettez pas (ou si vous transmettez une valeur qui ne valide pas la classe), la valeur par défaut de la superclasse sera utilisée. Pour la classe Field
par défaut, cette valeur est null
. Si vous ne souhaitez pas utiliser cette valeur par défaut, veillez à transmettre une valeur appropriée. Le paramètre de validation n'est présent que pour les champs modifiables et est généralement marqué comme facultatif. Pour en savoir plus sur les validateurs, consultez la documentation sur les validateurs.
Structure
La logique à l'intérieur 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 de l'une de ses sous-classes) pour initialiser correctement la valeur et définir le validateur local pour votre champ. - Si votre champ est sérialisable, définissez la propriété correspondante dans le constructeur. Les champs modifiables doivent être sérialisables. Les champs sont modifiables par défaut. Vous devez donc probablement définir cette propriété sur "true", sauf si vous savez qu'elle ne doit pas être sérialisable.
- Facultatif : Appliquez une personnalisation supplémentaire (par exemple, les champs de libellé permettent de transmettre une classe CSS, qui est ensuite appliquée au texte).
JSON et enregistrement
Dans les définitions de blocs JSON, les champs sont décrits par une chaîne (par exemple, field_number
, field_textinput
). Blockly conserve une carte de ces chaînes vers les objets de champ et appelle fromJson
sur l'objet approprié lors de la construction.
Appelez Blockly.fieldRegistry.register
pour ajouter votre type de champ à cette carte, en transmettant la classe de champ comme deuxième argument :
Blockly.fieldRegistry.register('field_generic', GenericField);
Vous devez également définir votre fonction fromJson
. Votre implémentation doit d'abord déréférencer toutes les références aux jetons de localisation à 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 construit, il ne contient qu'une valeur. L'initialisation est l'étape où le DOM est créé, le modèle est créé (si le champ possède un modèle) et les événements sont liés.
Affichage sur le bloc
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 souhaitez que votre champ comporte ces deux éléments, ainsi que d'autres, appelez la fonction initView
de la superclasse avant d'ajouter le reste de vos éléments DOM. Si vous souhaitez que votre champ comporte l'un de ces éléments, 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, Text Input), la construction du DOM sera gérée pour vous. Sinon, vous devrez remplacer la fonction initView
pour créer les éléments DOM dont vous aurez besoin lors du futur rendu de votre champ.
Par exemple, un champ de menu déroulant peut contenir à la fois des images et du texte. Dans initView
, il crée un seul élément image et un seul élément de texte. Ensuite, pendant render_
, il affiche l'élément actif et masque l'autre, en fonction du type d'option sélectionnée.
Vous pouvez créer des éléments DOM à l'aide de la méthode Blockly.utils.dom.createSvgElement
ou des méthodes de création DOM traditionnelles.
Voici les exigences concernant l'affichage sur le bloc d'un champ :
- Tous les éléments DOM doivent être des enfants de l'élément
fieldGroup_
du champ. Le groupe de champs est créé automatiquement. - Tous les éléments DOM doivent rester dans les dimensions signalées du champ.
Pour en savoir plus sur la personnalisation et la mise à jour de l'affichage sur le bloc, consultez la section Rendu.
Ajouter des symboles de texte
Si vous souhaitez ajouter des symboles au texte d'un champ (comme le symbole de degré du champ Angle), vous pouvez ajouter l'élément de symbole (généralement contenu dans un <tspan>
) directement au textElement_
du champ.
Événements de saisie
Par défaut, les champs enregistrent les événements d'info-bulle et les événements mousedown (à utiliser pour afficher les éditeurs).
Si vous souhaitez écouter d'autres types d'événements (par exemple, si vous souhaitez gérer le déplacement d'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 associer un événement, vous devez généralement utiliser la fonction Blockly.utils.browserEvents.conditionalBind
. Cette méthode de liaison des événements filtre les contacts secondaires lors des déplacements. Si vous souhaitez que votre gestionnaire s'exécute même au milieu d'un déplacement en cours, vous pouvez utiliser la fonction Blockly.browserEvents.bind
.
Élimination
Si vous avez enregistré des écouteurs d'événements personnalisés dans la fonction bindEvents_
du champ, vous devrez les désenregistrer dans la fonction dispose
.
Si vous avez correctement initialisé la vue de votre champ (en ajoutant tous les éléments DOM à fieldGroup_
), le DOM du champ sera supprimé automatiquement.
Gestion des valeurs
→ Pour en savoir plus sur la valeur d'un champ par rapport à son texte, consultez Anatomie d'un champ.
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 accepter que des nombres, les champs de couleur ne doivent accepter que des couleurs, etc. Cela est garanti par les validateurs de classe et locaux. Le validateur de classe suit les mêmes règles que les validateurs locaux, sauf qu'il est également exécuté dans le constructeur et, à ce titre, il ne doit pas faire référence au bloc source.
Pour implémenter le validateur de classe de votre champ, remplacez la fonction doClassValidation_
.
doClassValidation_(newValue) {
if (typeof newValue != 'string') {
return null;
}
return newValue;
};
Gérer les valeurs valides
Si la valeur transmise à un champ avec setValue
est valide, vous recevrez un rappel doValueUpdate_
. Par défaut, la fonction doValueUpdate_
:
- La propriété
value_
est définie surnewValue
. - Définit la propriété
isDirty_
surtrue
.
Si vous avez simplement besoin de stocker la valeur et que vous ne souhaitez pas effectuer de traitement personnalisé, vous n'avez pas besoin de remplacer doValueUpdate_
.
Sinon, si vous souhaitez effectuer des actions telles que :
- Espace de stockage personnalisé de
newValue
. - Modifiez d'autres propriétés en fonction de
newValue
. - Enregistrez si la valeur actuelle est valide ou non.
Vous devrez remplacer doValueUpdate_
:
doValueUpdate_(newValue) {
super.doValueUpdate_(newValue);
this.displayValue_ = newValue;
this.isValueValid_ = true;
}
Gérer les valeurs non valides
Si la valeur transmise au champ avec setValue
n'est pas valide, vous recevrez un rappel doValueInvalid_
. Par défaut, la fonction doValueInvalid_
ne fait rien. Cela signifie que les valeurs non valides ne s'affichent pas par défaut. Cela signifie également que le champ ne sera pas réaffiché, car la propriété 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 la valeur non valide, définir isDirty_
sur true
et override
render_ pour que l'affichage sur le bloc soit mis à jour en fonction de displayValue_
au lieu de 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 (par exemple, des listes, des vecteurs ou des objets), vous pouvez 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 n'est pas valide, la valeur est mise en cache dans la propriété cacheValidatedValue_
avant de renvoyer null
(non valide). La mise en cache de l'objet avec des propriétés validées individuellement permet à la fonction doValueInvalid_
de les gérer séparément, simplement en effectuant une vérification !this.cacheValidatedValue_.property
, au lieu de revalider chaque propriété individuellement.
Ce modèle de validation des valeurs en plusieurs parties peut également être utilisé dans les validateurs locaux, mais il n'existe actuellement aucun moyen de l'appliquer.
isDirty_
isDirty_
est un indicateur utilisé dans la fonction setValue
, ainsi que dans d'autres parties du champ, pour indiquer si le champ doit être rendu à nouveau. Si la valeur affichée du champ a changé, isDirty_
doit généralement être défini sur true
.
Texte
→ Pour savoir où le texte d'un champ est utilisé et en quoi il diffère de la valeur du champ, consultez Anatomie d'un champ.
Si le texte de votre champ est différent de sa valeur, vous devez remplacer la 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 appellera showEditor_
au moment opportun. Vous pouvez afficher n'importe quel code HTML dans votre éditeur en l'encapsulant dans l'une des deux divs spéciales, appelées DropDownDiv et WidgetDiv, qui flottent au-dessus du reste de l'UI de Blockly.
DropDownDiv et WidgetDiv
DropDownDiv
est utilisé pour fournir des éditeurs qui se trouvent dans une boîte connectée à un champ. Il se positionne automatiquement à proximité du champ tout en restant dans les limites visibles. Le sélecteur d'angle et le sélecteur de couleur sont de bons exemples de DropDownDiv
.
WidgetDiv
est utilisé pour fournir des éditeurs qui ne se trouvent pas dans une boîte. Les champs numériques utilisent WidgetDiv pour couvrir le champ avec une zone de saisie de texte HTML. Bien que DropDownDiv gère le positionnement pour vous, WidgetDiv ne le fait pas. Les éléments devront être positionnés manuellement. Le système de coordonnées est exprimé en coordonnées de pixels par rapport au coin supérieur gauche de la fenêtre. L'éditeur de saisie de texte est un bon exemple de 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 gèrent la destruction des éléments HTML du widget, mais vous devez supprimer manuellement tous les écouteurs d'événements que vous avez appliqués à 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 DropDownDiv
. Sur WidgetDiv
, il est appelé dans le contexte de WidgetDiv
. Dans les deux cas, il est préférable d'utiliser la fonction bind lorsque vous transmettez une fonction de suppression, comme illustré dans les exemples DropDownDiv
et WidgetDiv
ci-dessus.
→ Pour en savoir plus sur la suppression d'éléments qui ne sont pas spécifiques à la suppression d'éditeurs, consultez Suppression.
Mettre à jour l'affichage sur le bloc
La fonction render_
est utilisée pour mettre à jour l'affichage sur le bloc du champ afin qu'il corresponde à sa valeur interne.
Voici quelques exemples courants :
- Modifier le texte (menu déroulant)
- Modifier la couleur (color)
Valeurs par défaut
La fonction render_
par défaut définit le texte à afficher sur le résultat de la fonction getDisplayText_
. La fonction getDisplayText_
renvoie la propriété value_
du champ convertie en chaîne, après avoir été tronquée pour respecter la longueur maximale du texte.
Si vous utilisez l'affichage par défaut sur le bloc et que le comportement de texte par défaut fonctionne pour votre champ, vous n'avez pas besoin de remplacer render_
.
Si le comportement de texte par défaut fonctionne pour votre champ, mais que l'affichage sur bloc de votre champ comporte des éléments statiques supplémentaires, vous pouvez appeler la fonction render_
par défaut, mais vous devrez toujours la remplacer pour mettre à jour la taille du champ.
Si le comportement de texte par défaut ne fonctionne pas pour votre champ ou si l'affichage sur le bloc de votre champ comporte des éléments dynamiques supplémentaires, vous devrez personnaliser la fonction render_
.
Personnaliser l'affichage
Si le comportement de rendu par défaut ne fonctionne pas pour votre champ, vous devrez définir un comportement de rendu personnalisé. Cela peut impliquer de définir un texte à afficher personnalisé, de modifier des éléments d'image ou de mettre à jour les couleurs d'arrière-plan.
Toutes les modifications apportées aux attributs DOM sont légales. Les deux seules choses à retenir sont les suivantes :
- La création du DOM doit être gérée lors de l'initialisation, car c'est plus efficace.
- Vous devez toujours mettre à jour la propriété
size_
pour qu'elle corresponde à la taille de l'annonce display sur 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 indique au code de rendu du bloc comment positionner le champ. La meilleure façon de déterminer exactement ce que doit être size_
est d'expérimenter.
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;
}
Assortir les couleurs des blocs
Si vous souhaitez que les éléments de votre champ correspondent aux couleurs du bloc auquel ils sont associés, vous devez remplacer la méthode applyColour
. Vous devrez 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;
}
}
Mettre à jour la possibilité de modification
La fonction updateEditable
peut être utilisée pour modifier l'apparence de votre champ selon qu'il est modifiable ou non. La fonction par défaut permet au fond d'avoir ou non une réponse au survol (bordure) s'il est modifiable ou non.
La taille de l'affichage dans le bloc 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 de votre champ afin qu'il puisse être rechargé 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 champ était une carte zoomable permettant à l'utilisateur de sélectionner des pays, vous pourriez également sérialiser 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 hooks fonctionne avec le nouveau système de sérialisation JSON, et l'autre paire fonctionne avec 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 système de sérialisation JSON.
Dans certains cas, vous n'avez pas besoin de les fournir, car les implémentations par défaut fonctionneront. Si (1) votre champ est une sous-classe directe de la classe de base Blockly.Field
, (2) votre valeur est un type sérialisable JSON et (3) vous n'avez besoin que de sérialiser la valeur, l'implémentation par défaut fonctionnera parfaitement.
Sinon, votre fonction saveState
doit renvoyer un objet/une valeur sérialisable JSON qui représente l'état du champ. Votre fonction loadState
doit accepter le même objet/valeur sérialisable JSON et l'appliquer au champ.
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
. Cette option est utilisée par les champs qui font normalement référence à un état sérialisé par un sérialiseur différent (comme les modèles de données de sauvegarde). Le paramètre indique que l'état référencé ne sera pas disponible lorsque le bloc sera désérialisé. Le champ doit donc effectuer lui-même toute la sérialisation. Par exemple, cela est vrai lorsqu'un bloc individuel est sérialisé ou lorsqu'un bloc est copié et collé.
Voici deux cas d'utilisation courants :
- Lorsqu'un bloc individuel est chargé dans un espace de travail où le modèle de données sous-jacent n'existe pas, le champ dispose de suffisamment d'informations dans son propre état pour créer un modèle de données.
- Lorsqu'un bloc est copié et collé, le champ crée toujours un nouveau modèle de données sous-jacent au lieu de faire référence à un modèle existant.
Le champ de variable intégré en est un exemple. Normalement, il sérialise l'ID de la variable à laquelle il fait référence, mais si doFullSerialization
est défini sur "true", il sérialise tout son état.
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 de variable permet de s'assurer que, s'il 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 système de sérialisation XML. N'utilisez ces hooks que si vous y êtes obligé (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 du champ. Votre fonction fromXml
doit accepter le même nœud XML et l'appliquer au champ.
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 disposer d'une interface utilisateur pour indiquer qu'il peut être utilisé. Sa valeur par défaut est true
.
La propriété SERIALIZABLE
détermine si le champ doit être sérialisé. La valeur par défaut est false
. Si cette propriété est true
, vous devrez peut-être fournir des fonctions de sérialisation et de désérialisation (voir Sérialisation).
Personnaliser avec CSS
Vous pouvez personnaliser votre champ avec CSS. Dans la méthode initView
, ajoutez une classe personnalisée au fieldGroup_
de votre champ, puis référencez cette classe dans votre CSS.
Par exemple, pour utiliser un autre curseur :
initView() {
...
// Add a custom CSS class.
if (this.fieldGroup_) {
Blockly.utils.dom.addClass(this.fieldGroup_, 'myCustomField');
}
}
.myCustomField {
cursor: cell;
}
Personnaliser le curseur
Par défaut, les classes qui étendent FieldInput
utilisent un curseur text
lorsqu'un utilisateur pointe sur le champ, les champs en cours de déplacement utilisent un curseur grabbing
et tous les autres champs utilisent un curseur default
. Si vous souhaitez utiliser un autre curseur, définissez-le à l'aide du CSS.