Draggable

Um elemento arrastável é um objeto renderizado que existe no espaço de trabalho e pode ser arrastado e solto. Eles implementam a interface IDraggable.

Existem pouquíssimas circunstâncias em que você quer adicionar um novo elemento arrastável ao Blockly (por exemplo, o plug-in de seleção múltipla ou a mudança de como um objeto existente processa as ações de arrastar), porque não é possível adicionar novos objetos renderizados ao Blockly. Os únicos objetos renderizados que podem existir em um espaço de trabalho são blocos, balões e comentários do espaço de trabalho.

Responsabilidades

Os elementos arrastáveis têm várias responsabilidades ao executar esse recurso:

Implementação

Para criar um novo elemento arrastável, implemente as interfaces IRenderedElement e IDraggable. Isso permite que o Blockly saiba que seu objeto está visível e pode ser arrastado.

class MyDraggable extends IRenderedElement, IDraggable {}

Retornar o elemento SVG raiz

O método getRootSvg retorna o elemento svg raiz (geralmente um grupo) que contém todos os outros elementos que compõem a visualização do arrastável.

getSvgRoot() {
  return this.rootSvg;
}

Mobilidade da devolução

O método isMovable retorna se o elemento arrastável pode ser movido no momento, já que é recomendável desativar temporariamente o recurso de arrastar um objeto. Se isMovable retornar false, o espaço de trabalho será arrastado.

isMovable() {
  return true;
}

Posição de retorno

O método getRelativeToSurfaceXY retorna um Coordinate que especifica o local do canto inicial do elemento arrastável nas coordenadas do espaço de trabalho.

As coordenadas do espaço de trabalho têm uma origem no lado esquerdo e no topo absoluto do espaço de trabalho. E não mudam quando o espaço de trabalho é dimensionado ou movido.

getRelativeToSurfaceXY() {
  return this.loc;
}

Começar a arrastar

O método startDrag inicializa uma ação de arrastar no arrastável. Esse método não move o elemento arrastável. No entanto, é necessário armazenar os dados ou construir os objetos necessários para concluir a ação de arrastar. Isso inclui todos os dados necessários para reverter o arrastar se revertDrag for chamado.

Ele também precisa alterar os elementos svg para que estejam na camada de arrastar do espaço de trabalho, para que eles apareçam acima de todos os outros elementos.

Ele também aceita um evento, que pode ser usado para verificar as teclas pressionadas. Isso permite, por exemplo, tratar uma ação de arrastar ao deslocar de maneira diferente de uma arrastação 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...
}

Arrasto

O método drag move o objeto arrastável. O newLoc está em coordenadas do espaço de trabalho, e há também um evento transmitido que pode ser usado para conferir se há teclas pressionadas.

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

Reverter arrastos

O método revertDrag retorna o elemento arrastável para a posição em que estava no início da ação. Isso vai acontecer se, por exemplo, o elemento arrastável for solto em um destino de arrastar que impede o movimento.

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

Finalizar arrastar

O método endDrag limpa uma ação de arrastar, liberando todos os dados ou objetos armazenados e retornando o elemento arrastável à camada original.

O endDrag sempre será chamado depois do revertDrag se revertDrag for chamado.

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

Seleção

O elemento que é arrastado é determinado pelo selecionado quando uma ação de arrastar é detectada.

ISelectable

Para ser selecionado, um elemento arrastável precisa implementar a interface 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.
  }
}

Definir seleção

O elemento selecionado pode ser definido chamando Blockly.common.setSelected(). Geralmente, convém fazer isso em resposta a um evento pointerdown do usuário.

  constructor() {
    this.initSvg();

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

Compatibilidade

O elemento arrastável pode implementar outras interfaces para interagir com outros sistemas no Blockly.

Excluíveis

Você pode implementar a interface IDeleteable para permitir que o elemento arrastável seja descartado pela lixeira ou por outros destinos de exclusão.

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.
  }
}

Copiar

Você pode implementar a interface ICopyable para permitir que o elemento arrastável seja copiado e definir um IPaster para permitir que ele seja colado.

Saiba como copiar e colar em Copiar e colar.