Verbindungsformen

Es gibt mehrere Möglichkeiten, das Aussehen von Verbindungen anzupassen, wobei der Schwierigkeitsgrad jeweils zunehmen wird. Für all diese Elemente muss ein benutzerdefinierter Renderer erstellt werden.

Grundlegende Dimensionen

Verbindungen mit verschiedenen Abmessungen

Sie können Verbindungen anpassen, indem Sie ihre Breite oder Höhe ändern, während die Grundform beibehalten wird. Dazu müssen Sie eine benutzerdefinierte Konstantenanbieter-Komponente erstellen und einige Konstanten überschreiben.

Unterschiedliche Renderer definieren und verwenden unterschiedliche Konstanten. Sehen Sie sich daher die Referenzdokumentation für Ihre Superklasse an:

Für den Basis-Renderer können Sie NOTCH_WIDTH und NOTCH_HEIGHT für nächste und vorherige Verbindungen sowie TAB_WIDTH und TAB_HEIGHT für Eingabe- und Ausgabeverbindungen überschreiben.

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

Grundformen

Verbindungen mit unterschiedlichen Formen

Sie können Verbindungen anpassen, indem Sie ihre Grundform überschreiben. Grundformen haben eine Höhe, eine Breite und zwei Pfade.

Jeder Pfad hat dieselbe Form, aber von entgegengesetzten Enden aus.

eine Einkerbung aus beiden Richtungen

Dies ist notwendig, da beim Zeichnen des Umrisses des Blocks jede Art von Verbindung in beide Richtungen gezeichnet wird. Vorherige Verbindungen werden beispielsweise von links nach rechts gezeichnet, während nächste Verbindungen von rechts nach links gezeichnet werden. Sie müssen also Pfade für beide Fälle angeben.

Richtung, in die ein Block gezeichnet wird

Sie können die Methode makeNotch für nächste und vorherige Verbindungen und die Methode makePuzzleTab für Eingabe- und Ausgabeverbindungen überschreiben.

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

Informationen zum Definieren von Pfadstrings finden Sie in der Dokumentation zu MDN-SVG-Pfaden. Der Blockly.utils.svgPaths-Namespace wird als schlanker Wrapper um diese Strings bereitgestellt, um sie lesbarer zu machen.

Formen für Verbindungsprüfungen

Verschiedene Verbindungen mit unterschiedlichen Formen

Sie können Verbindungen anpassen, indem Sie die Form basierend auf der Verbindungsprüfung der Verbindung ändern.

So können Sie verschiedene Formen erstellen, um verschiedene Datentypen darzustellen. Beispielsweise können Strings durch dreieckige Verbindungen und boolesche Verbindungen durch runde Verbindungen dargestellt werden.

Wenn Sie verschiedene Formen für verschiedene Verbindungsprüfungen bereitstellen möchten, müssen Sie die Methode shapeFor überschreiben. Die zurückgegebenen Formen sollten in init initialisiert werden.

Informationen zu den unterstützten Formen finden Sie unter Einfache Formen.

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

Benutzerdefinierte Eingaben

Sie können Verbindungsformen anpassen, indem Sie eine vollständig benutzerdefinierte Eingabe erstellen. Dies ist nur erforderlich, wenn Sie möchten, dass sich einige Verbindungen von anderen unterscheiden, dies jedoch nicht auf der Verbindungsprüfung basieren soll.

Wenn Sie beispielsweise möchten, dass einige Werteingaben wie Anweisungseingaben eingerückt werden, können Sie eine benutzerdefinierte Eingabe erstellen, um dies zu unterstützen.

Benutzerdefinierte Eingabeklasse erstellen

Folgen Sie der Anleitung zum Erstellen einer benutzerdefinierten Eingabe.

Einen messbaren

Sie müssen einen messbaren Wert erstellen, der Ihre benutzerdefinierte Eingabe darstellt.

Ihre benutzerdefinierte Eingabe, die messbar ist, sollte von Blockly.blockRendering.InputConnection übernommen werden. Sie können auch zusätzliche Messdaten enthalten, die Sie zum Zeichnen der Eingabeform benötigen.

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

    // Any extra measurement data...
  }
}

Instanziieren Sie Ihren messbaren

Deine Renderinginformationen müssen deinen benutzerdefinierten messbaren Wert instanziieren. Dazu müssen Sie die Methode addInput_ überschreiben.

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

Optional: eine Zeile erstellen

Standardmäßig werden durch Eingaben keine neuen Zeilen erstellt. Wenn Sie möchten, dass Ihre Eingabe das Ende einer Zeile auslöst, müssen Sie die Methode shouldStartNewRow_ der Renderinginformationen überschreiben.

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

Optional: Erstellen Sie eine Form für Ihre Eingabe

Es empfiehlt sich, die Form der Eingabe in einer Konstante zu speichern, genau wie bei Notches und Puzzle-Tabs. So bleibt der Code organisiert und kann später leichter geändert werden.

Eingabe zeichnen

Als Letztes müssen Sie Ihre Leiste bearbeiten, um die Form zu zeichnen.

Benutzerdefinierte Eingaben haben folgende Möglichkeiten:

  • Den Umriss des Blocks beeinflussen, z. B. Anweisungseingaben

    Bild von Umrisseingaben

  • oder die Interna des Blocks beeinflussen, z. B. Inline-Werteingaben

    Bild der internen Eingaben

Wenn sich die Eingabe auf den Umriss des Blocks auswirkt, überschreiben Sie drawOutline_. Andernfalls überschreiben Sie 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);
        }
      }
    }
  }
}