Dragster

Un outil de glisser-déposer est un objet de contrôleur qui coordonne le glissement des éléments déplaçables en réponse aux interactions de l'utilisateur.

Il est très rare que vous souhaitiez implémenter un outil de glisser-déposer personnalisé, car il n'y a pas grand-chose que vous puissiez personnaliser concernant la coordination d'un glisser-déposer. Le plug-in de défilement d'options implémente un glisser-déposer personnalisé, car il souhaitait ajouter un défilement au bord de l'espace de travail, ce qui modifie la façon dont les coordonnées en pixels sont converties en coordonnées de l'espace de travail.

Responsabilités

Le dragger a plusieurs responsabilités lors de l'exécution des glissers:

  • Appel des méthodes de glisser-déposer sur l'élément déplaçable.
  • Calcul de la position à laquelle l'élément déplaçable doit se déplacer en coordonnées d'espace de travail.
  • Appel des méthodes de cible de glissement sur les cibles de glissement sur lesquelles la souris est pointée.

Implémentation

Pour créer un outil de glisser-déposer personnalisé, vous devez implémenter l'interface IDragger.

class MyDragger implements IDragger {
  // Takes in the draggable being dragged and the workspace the drag
  // is occurring in.
  constructor(draggable, workspace);
}

Vous pouvez également sous-classer Blockly.dragging.Dragger intégré, qui gère déjà les responsabilités de base.

Lancer le déplacement

La méthode onDragStart initialise un glissement. Il doit stocker toutes les données nécessaires à l'exécution du glisser-déposer. Il doit également appeler startDrag sur l'élément déplaçable en cours de déplacement.

onDragStart(e) {
  this.startLoc = this.draggable.getRelativeToSurfaceXY();

  this.draggable.startDrag(e);
}

Traînée

La méthode onDrag exécute un glisser-déposer. Il doit calculer la nouvelle position de l'espace de travail pour l'élément déplaçable en fonction de totalDelta, qui est indiqué en coordonnées de pixel.

Il doit également mettre à jour les cibles de glisser-déposer sur lesquelles vous pointez.

  • wouldDelete doit toujours être appelé avant d'appeler d'autres hooks sur la cible de glisser-déposer.
  • onDragExit doit toujours être appelé sur l'ancienne cible de glisser-déposer avant d'appeler onDragEnter sur la nouvelle cible de glisser-déposer.
  • onDragOver doit être appelé après onDragEnter la première fois que la cible de glissement est pointée, et à chaque appel supplémentaire de onDrag lorsque la cible de glissement est toujours pointée.
onDrag(e, totalDelta) {
  // Update the draggable location.
  const delta = this.pixelsToWorkspaceUnits(totalDelta);
  const newLoc = Coordinate.sum(this.startLoc, delta);
  this.draggable.drag(newLoc, e);

  // Call wouldDeleteDraggable.
  if (isDeletable(this.draggable)) {
    this.draggable.setDeleteStyle(
      // Checks that the drag target is an `IDeleteArea` and calls `wouldDelete`
      // on it.
      this.wouldDeleteDraggable(e, this.draggable),
    );
  }

  const newDragTarget = this.workspace.getDragTarget(e);
  if (this.dragTarget !== newDragTarget) {
    // Call `onDragExit` then `onDragEnter`.
    this.dragTarget?.onDragExit(this.draggable);
    newDragTarget?.onDragEnter(this.draggable);
  }
  // Always call `onDragOver`
  newDragTarget?.onDragOver(this.draggable);
  this.dragTarget = newDragTarget;
}

Arrêter les glissements

La méthode onEndDrag met fin à un glissement. Il doit informer l'élément draggable que le glissement est terminé et toute cible de glissement survolée que l'élément draggable a été déposé. Il doit également supprimer l'élément déplaçable si la cible de glissement est une zone de suppression.

  • onDrop doit toujours être appelé avant les autres méthodes.
  • revertDrag doit être appelé si la cible de glisser-déposer empêche les glissements.
  • endDrag doit être appelé après l'annulation du glissement, mais avant la suppression.
  • dispose doit être appelé si la cible de glisser-déposer est une zone de suppression.
onDragEnd(e) {
  // Call `onDrop` first.
  const dragTarget = this.workspace.getDragTarget(e);
  if (dragTarget) {
    this.dragTarget?.onDrop(this.draggable);
  }

  // Then revert the drag (if applicable).
  if (this.shouldReturnToStart(e, this.draggable)) {
    this.draggable.revertDrag();
  }

  // Then end the drag.
  this.draggable.endDrag(e);

  // Then delete the draggable (if applicable).
  if (
    isDeletable(this.draggable) &&
    this.wouldDeleteDraggable(e, this.draggable)
  ) {
    this.draggable.dispose();
  }
}

Inscription

Votre classe de dragger doit être enregistrée pour pouvoir être créée lorsque des glisser-déposer sont détectés.

// Note that the type is BLOCK_DRAGGER even though draggers drag more than
// blocks. The name is for backwards compatibility.
Blockly.registry.register(registry.Type.BLOCK_DRAGGER, 'MY_DRAGGER', MyDragger);

Utilisation

Une fois que vous avez implémenté votre outil de glisser-déposer personnalisé, vous pouvez l'utiliser en le transmettant à votre struct de configuration d'injection.

const myWorkspace = Blockly.inject('blocklyDiv', {
  plugins: {
    // Note that we pass this to blockDragger even though draggers drag more
    // than blocks. The name is for backwards compatibility.
    blockDragger: MyDragger,
  },
});