Arrastrable

Un elemento arrastrable es un objeto renderizado que existe en el lugar de trabajo y se puede arrastrar y soltar. Implementan la interfaz IDraggable.

Hay muy pocas circunstancias en las que querrás agregar un nuevo elemento arrastrable a Blockly (p.ej., el complemento de selección múltiple o cambiar la forma en que un objeto existente controla los arrastres) porque no puedes agregar nuevos objetos renderizados a Blockly. Los únicos objetos renderizados que pueden existir dentro de un lugar de trabajo son los bloques, las burbujas y los comentarios del lugar de trabajo.

Responsabilidades

Los elementos arrastrables tienen varias responsabilidades cuando se ejecutan arrastres:

  • Movimiento de elementos de SVG a la capa de arrastre
  • Traducir elementos de SVG.
  • Se activan eventos de movimiento.

Implementación

Para crear un nuevo elemento arrastrable, debes implementar las interfaces IRenderedElement y IDraggable. Esto le indica a Blockly que tu objeto es visible y que puedes arrastrarlo.

class MyDraggable extends IRenderedElement, IDraggable {}

Muestra el elemento de SVG raíz

El método getRootSvg muestra el elemento de SVG raíz (por lo general, un grupo) que contiene todos los demás elementos que conforman la vista del elemento arrastrable.

getSvgRoot() {
  return this.rootSvg;
}

Movilidad de devoluciones

El método isMovable muestra si el elemento arrastrable se puede mover actualmente (ya que es posible que desees inhabilitar temporalmente el arrastre de un objeto). Si isMovable muestra false, el lugar de trabajo se arrastra en su lugar.

isMovable() {
  return true;
}

Posición de regreso

El método getRelativeToSurfaceXY muestra un Coordinate que especifica la ubicación de la esquina superior de inicio del elemento arrastrable en las coordenadas del lugar de trabajo.

Las coordenadas del lugar de trabajo tienen un origen en la izquierda y la parte superior absolutas del lugar de trabajo. Y no cambian cuando se escala o se mueve el lugar de trabajo.

getRelativeToSurfaceXY() {
  return this.loc;
}

Iniciar arrastres

El método startDrag inicializa un arrastre en el elemento arrastrable. Este método no mueve el elemento arrastrable. Sin embargo, debes almacenar los datos o construir los objetos que necesites para completar el arrastre. Esto incluye los datos que necesitarías para revertir el arrastre si se llama a revertDrag.

También se deben cambiar los elementos de SVG para que estén en la capa de arrastre del lugar de trabajo, de modo que se encuentren encima de cualquier otro elemento.

También toma un evento, que puedes usar para verificar las teclas presionadas. Esto te permite, por ejemplo, tratar un arrastre mientras se desplaza de manera diferente a un arrastre normal.

startDrag(e) {
  // Save the original location so we can revert the drag.
  this.startLoc = this.getRelativeToSurfaceXY();

  // Disable resizing the workspace for performance.
  this.workspace.setResizesEnabled(false);

  // Put the element on the drag layer.
  this.workspace.getLayerManager()?.moveToDragLayer(this);

  // Fire a drag event...

  // etc...
}

Arrastrar

En realidad, el método drag mueve el objeto arrastrable. newLoc está en las coordenadas del lugar de trabajo y también se pasó un evento que puedes usar para verificar las teclas presionadas.

drag(newLoc, e) {
  this.moveTo(newLoc);
}

Revertir arrastres

El método revertDrag muestra el elemento arrastrable a la posición en la que se encontraba al comienzo del arrastre. Esto sucede, por ejemplo, si el elemento arrastrable se suelta en un objetivo de arrastre que impide el movimiento.

revertDrag() {
  // Move back to the position that was stored in `startDrag`.
  this.moveTo(this.startLoc);
}

Finalizar arrastres

El método endDrag limpia un arrastre, libera los objetos o datos almacenados, y devuelve el elemento arrastrable a su capa original.

Siempre se llama a endDrag después de revertDrag si se llama a revertDrag.

endDrag() {
  // Put the element back on its original layer (in this case BLOCK).
  this.workspace
    .getLayerManager()
    ?.moveOffDragLayer(this, Blockly.layers.BLOCK);

  // Allow the workspace to start resizing again.
  this.workspace.setResizesEnabled(true);
}

Selección

El elemento que se selecciona determina el elemento que se arrastra cuando se detecta un arrastre.

ISelectable

Para que se seleccione un elemento arrastrable, debe implementar la interfaz ISelectable.

class MyDraggable implements ISelectable {
  constructor(workspace) {
    this.id = Blockly.utils.idGenerator.genUid();
    this.workspace = workspace;
  }

  select() {
    // Visually indicate this draggable is selected.
  }

  unselect() {
    // Visually indicate this draggable is not selected.
  }
}

Establece la selección

El elemento seleccionado se puede configurar llamando a Blockly.common.setSelected(). por lo general, querrás hacerlo en respuesta a un evento pointerdown del usuario.

  constructor() {
    this.initSvg();

    Blockly.browserEvents.conditionalBind(
      this.getSvgRoot(),
      'pointerdown',
      this,
      () => Blockly.common.setSelected(this));
  }

Compatibilidad

El elemento arrastrable puede implementar interfaces adicionales para que pueda interactuar con otros sistemas en Blockly.

Se puede borrar

Puedes implementar la interfaz IDeleteable para permitir que se deseche el elemento arrastrable en la papelera o en otros destinos de eliminación.

class MyDraggable implements IDeletable {
  isDeletable() {
    return true;
  }

  dispose() {
    // Dispose of any references to data or SVG elements.
  }

  setDeleteStyle() {
    // Visually indicate that the draggable is about to be deleted.
  }
}

Se puede copiar

Puedes implementar la interfaz ICopyable para permitir que se copie el elemento arrastrable y definir un IPaster para permitir que se pegue.

Para obtener más información sobre cómo copiar y pegar, consulta Cómo copiar y pegar.