Kształty połączeń

Jest kilka sposobów na dostosowanie wyglądu połączeń, a każdy z nich ma rosnący poziom trudności. Wszystkie wymagają utworzenia niestandardowego mechanizmu renderowania.

Wymiary podstawowe

połączenia o różnych wymiarach

Połączenia możesz dostosowywać, zmieniając ich szerokość lub wysokość, zachowując ten sam podstawowy kształt. Aby to zrobić, musisz utworzyć niestandardowy komponent stałego dostawcy i zastąpić niektóre stałe.

Różne mechanizmy renderowania definiują i używają różnych stałych, więc zapoznaj się z dokumentacją superklasy:

W przypadku podstawowego mechanizmu renderowania możesz zastąpić wartości NOTCH_WIDTH i NOTCH_HEIGHT dla następnego i poprzedniego połączenia oraz TAB_WIDTH i TAB_HEIGHT dla połączeń wejściowych i wyjściowych.

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

Podstawowe kształty

połączenia o różnych kształtach

Możesz dostosować połączenia, zastępując ich podstawowy kształt. Kształty podstawowe mają wysokość, szerokość i dwie ścieżki.

Każda ścieżka rysuje ten sam kształt, ale z przeciwległych końcach!

otwór w obu kierunkach

Jest to konieczne, ponieważ szuflada rysuje kontur bryły, dlatego wszystkie rodzaje połączeń są rysowane w obu kierunkach. Na przykład poprzednie połączenia są rysowane od lewej do prawej, a następne – od prawej do lewej. Musisz więc podać ścieżki do obu tych przypadków.

kierunek, w którym narysowana jest bryła

Możesz zastąpić metodę makeNotch w przypadku następnego i poprzedniego połączenia oraz metodę makePuzzleTab w przypadku połączeń wejściowych i wyjściowych.

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

Informacje o definiowaniu ciągów ścieżek znajdziesz w dokumentacji ścieżki SVG w MDN. Przestrzeń nazw Blockly.utils.svgPaths jest stosowana dookoła tych ciągów cienkich, dzięki czemu są one bardziej czytelne.

Kształty do sprawdzania połączeń

połączenia o różnych kształtach

Możesz dostosować połączenia, zmieniając ich kształt zgodnie ze stanem sprawdzania połączenia.

Dzięki temu możesz tworzyć różne kształty reprezentujące różne typy danych. Na przykład ciągi tekstowe mogą być reprezentowane przez połączenia trójkątne, a wartości logiczne – połączenia okrągłe.

Aby podać różne kształty na potrzeby różnych testów połączeń, musisz zastąpić metodę shapeFor. Zwrócone kształty powinny być zainicjowane w init.

Sprawdź podstawowe kształty, aby dowiedzieć się, jakie typy kształtów są obsługiwane.

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

Niestandardowe dane wejściowe

Możesz dostosować kształty połączeń, tworząc całkowicie niestandardowe dane wejściowe. Można to zrobić tylko wtedy, gdy chcesz, aby niektóre połączenia wyglądały inaczej niż inne, ale nie chcesz, aby przeprowadzano sprawdzanie połączeń.

Jeśli na przykład chcesz, by niektóre dane wejściowe były wcięte, tak jak dane wejściowe instrukcji, możesz utworzyć niestandardowe dane wejściowe.

Utwórz niestandardową klasę danych wejściowych

Wykonaj instrukcje tworzenia niestandardowych danych wejściowych.

Tworzenie wymiernych

Musisz utworzyć wskaźnik mierzalny, który będzie reprezentował Twoje niestandardowe dane wejściowe.

Niestandardowe dane wejściowe, które można zmierzyć, powinny dziedziczyć z właściwości Blockly.blockRendering.InputConnection. Może też zawierać wszelkie dodatkowe dane pomiarowe potrzebne do narysowania kształtu wejściowego.

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

    // Any extra measurement data...
  }
}

Utwórz instancję pomiaru

Do utworzenia instancji wymiernej niestandardowej potrzebne są informacje o renderowaniu. Aby to zrobić, musisz zastąpić metodę 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);
  }
}

Opcjonalnie utwórz wiersz

Domyślnie dane wejściowe nie tworzą nowych wierszy. Jeśli chcesz, aby dane wejściowe wywoływały koniec wiersza, musisz zastąpić metodę shouldStartNewRow_ informacji o renderowaniu.

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

Opcjonalnie utwórz kształt na potrzeby wprowadzania danych

Dobrze jest zapisywać na bieżąco kształt wprowadzonych danych, tak jak w przypadku kart z nacięciami i łamigłówkami. Pozwala to utrzymać porządek w kodzie i ułatwia jego późniejsze modyfikowanie.

Narysuj dane wejściowe

Na koniec musisz zmodyfikować szufladę, aby narysować kształt.

Niestandardowe dane wejściowe mogą:

  • Wpływaj na kontur bloku, np. w polu wprowadzania instrukcji

    obraz danych wejściowych konturu

  • Możesz też wpłynąć na elementy wewnętrzne bloku, takie jak dane wejściowe wartości w tekście

    obraz wewnętrznych wejść

Jeśli dane wejściowe mają wpływ na kontur blokady, zastąp drawOutline_. W przeciwnym razie zastąp 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);
        }
      }
    }
  }
}