Formas de conexão

Há várias maneiras de personalizar a aparência das conexões, cada uma com dificuldade crescente. Todos eles exigem a criação de um renderizador personalizado.

Dimensões básicas

conexões com diferentes dimensões

Você pode personalizar as conexões alterando a largura ou a altura delas mantendo a mesma forma básica. Para fazer isso, você precisa criar um componente personalizado de provedor de constantes e modificar algumas constantes.

Diferentes renderizadores definem e usam constantes diferentes, portanto, confira a documentação de referência para sua superclasse:

.

Para o renderizador base, você pode substituir NOTCH_WIDTH e NOTCH_HEIGHT para as conexões anteriores e a próxima e TAB_WIDTH e TAB_HEIGHT para entrada e saída conexões de rede.

class CustomConstantProvider extends Blockly.blockRendering.ConstantProvider {
  constructor() {
    super();
    this.NOTCH_WIDTH = 20;
    this.NOTCH_HEIGHT = 10;
    this.TAB_HEIGHT = 8;
  }
}

Formas básicas

conexões com diferentes formas

É possível personalizar as conexões substituindo a forma básica delas. Formas básicas ter uma altura, uma largura e dois caminhos.

Cada caminho desenha a mesma forma, mas em extremidades opostas.

um entalhe nas duas direções

Isso é necessário porque, como a gaveta desenha o contorno da de um bloco, ela desenha cada tipo de conexão em ambas as direções. Por exemplo: As conexões anteriores são desenhadas da esquerda para a direita, mas as próximas conexões são desenhada da direita para a esquerda. Portanto, você precisa fornecer caminhos para nesses casos.

a direção em que um bloco é desenhado

Você pode substituir o método makeNotch para o próximo e o anterior e o método makePuzzleTab para entrada e saída conexões de saída.

class CustomConstantProvider extends Blockly.blockRendering.ConstantProvider {
  makePuzzleTab() {
    const width = this.TAB_WIDTH;
    const height = this.TAB_HEIGHT;
    return {
      type: this.SHAPES.PUZZLE,
      width,
      height,
      pathUp: Blockly.utils.svgPaths.line([
          Blockly.utils.svgPaths.point(-width, -height / 2),
          Blockly.utils.svgPaths.point(width, -height / 2)]),
      pathDown: Blockly.utils.svgPaths.line([
          Blockly.utils.svgPaths.point(-width, height / 2),
          Blockly.utils.svgPaths.point(width, height / 2)]),
    };
  }
}

Confira a documentação do caminho do MDN SVG para informações sobre como para definir strings de caminho. O namespace Blockly.utils.svgPaths é fornecido como um wrapper fino em torno dessas strings para torná-las mais legíveis.

Formas para verificações de conexão

diferentes conexões com diferentes formas

Você pode personalizar as conexões alterando a forma com base no verificação de conexão.

Isso permite criar diferentes formas para representar diferentes tipos de dados. Por exemplo, strings podem ser representadas por conexões triangulares, enquanto booleanos são representados por conexões redondas.

Para fornecer formas diferentes para verificações de conexão diferentes, é necessário substituir o método shapeFor. As formas retornadas devem ser inicializadas em init.

Consulte formas básicas para mais informações sobre os tipos de formas são suportados.

export class ConstantProvider extends Blockly.blockRendering.BaseConstantProvider {
  shapeFor(connection) {
    let check = connection.getCheck();
    // For connections with no check, match any child block.
    if (!check && connection.targetConnection) {
      check = connection.targetConnection.getCheck();
    }

    if (check && check.includes('String')) return this.TRIANGULAR_TAB;
    if (check && check.includes('Boolean')) return this.ROUND_TAB;

    return super.shapeFor(connection);
  }
}

Entradas personalizadas

Você pode personalizar as formas de conexão criando uma entrada totalmente personalizada. Isso só é feita se você quiser que algumas conexões pareçam diferentes de outras, mas se não quiser que ela seja baseada na verificação de conexão.

Por exemplo, se você quiser que algumas entradas de valor sejam recuadas, como entradas de instrução, crie uma entrada personalizada para que isso aconteça.

Criar uma classe de entrada personalizada

Siga as etapas para criar uma entrada personalizada.

Crie uma métrica

Você precisa criar um elemento mensurável para representar sua entrada personalizada.

A entrada personalizada mensurável deve herdar de Blockly.blockRendering.InputConnection Também pode incluir os dados de medição extras necessários para desenhar a forma da entrada.

export class CustomInputMeasurable extends Blockly.blockRendering.InputConnection {
  constructor(constants, input) {
    super(constants, input);

    // Any extra measurement data...
  }
}

Instancie seu conteúdo mensurável

Suas informações de renderização precisam instanciar sua personalização e mensuráveis. Para fazer isso, substitua o método addInput_.

export class RenderInfo extends Blockly.blockRendering.RenderInfo {
  addInput_(input, activeRow) {
    if (input instanceof CustomInput) {
      activeRow.elements.push(new CustomInputMeasurable(this.constants_, input));
    }
    super.addInput_(input, activeRow);
  }
}

Como opção, crie uma linha

Por padrão, as entradas não criam novas linhas. Se você quiser que sua entrada para acionar o fim de uma linha, você precisa substituir o método shouldStartNewRow_ da sua renderizar informações.

export class RenderInfo extends Blockly.blockRendering.RenderInfo {
  shouldStartNewRow_(currInput, prevInput) {
    if (prevInput instanceof CustomInput) return true;
    return super.shouldStartNewRow_(currInput, prevInput);
  }
}

Como opção, crie uma forma para a entrada

É uma boa ideia armazenar a forma de sua entrada em uma constante, assim como para entalhes e abas de quebra-cabeças. Isso mantém seu código organizado e facilita mais fácil de modificar posteriormente.

Desenhar a entrada

Por fim, você precisa modificar a gaveta para desenhar a forma.

As entradas personalizadas podem:

  • Afetam o contorno do bloco, como entradas de instrução

    imagem de entradas Outline

  • Ou afetam os componentes internos do seu bloco, como entradas de valor inline

    imagem de entradas internas

Se a entrada afetar o contorno do bloco, substitua drawOutline_; caso contrário, substitua drawInternals_

export class Drawer extends Blockly.blockRendering.Drawer {
  drawOutline_() {
    this.drawTop_();
    for (let r = 1; r < this.info_.rows.length - 1; r++) {
      const row = this.info_.rows[r];

      // Insert checks for your input here!
      if (row.getLastInput() instanceof CustomInputMeasurable) {
        this.drawCustomInput(row);
      } else if (row.hasJaggedEdge) {
        this.drawJaggedEdge_(row);
      } else if (row.hasStatement) {
        this.drawStatementInput_(row);
      } else if (row.hasExternalInput) {
        this.drawValueInput_(row);
      } else {
        this.drawRightSideRow_(row);
      }
    }
    this.drawBottom_();
    this.drawLeft_();
  }

  protected drawInternals_() {
    for (const row of rows) {
      for (const elem of row) {

        // Insert checks for your input here!
        if (elem instanceof CustomInputMeasurable) {
          this.drawCustomInput(elem);
        }

        if (Types.isInlineInput(elem)) {
          this.drawInlineInput_(elem as InlineInput);
        } else if (Types.isIcon(elem) || Types.isField(elem)) {
          this.layoutField_(elem as Field | Icon);
        }
      }
    }
  }
}