Bentuk koneksi

Ada beberapa cara untuk menyesuaikan tampilan koneksi, masing-masing dengan tingkat kesulitan yang semakin meningkat. Semuanya memerlukan pembuatan perender kustom.

Dimensi dasar

hubungan dengan berbagai dimensi

Anda dapat menyesuaikan koneksi dengan mengubah lebar atau tingginya, dengan tetap mempertahankan bentuk dasar yang sama. Untuk melakukannya, Anda harus membuat komponen penyedia konstanta kustom, dan mengganti beberapa konstanta.

Perender yang berbeda menentukan dan menggunakan konstanta yang berbeda, jadi lihat dokumentasi referensi untuk class super Anda:

Untuk perender dasar, Anda dapat mengganti NOTCH_WIDTH dan NOTCH_HEIGHT untuk koneksi berikutnya dan sebelumnya, serta TAB_WIDTH dan TAB_HEIGHT untuk koneksi input dan output.

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

Bentuk dasar

koneksi dengan berbagai bentuk

Anda dapat menyesuaikan koneksi dengan mengganti bentuk dasarnya. Bentuk dasar memiliki tinggi, lebar, dan dua jalur.

Setiap jalur menggambar bentuk yang sama, tetapi dari ujung yang berlawanan!

lekukan yang digambar dari kedua arah

Hal ini diperlukan karena saat panel samping menggambar garis luar blok, panel ini menggambar setiap jenis koneksi secara dua arah. Misalnya, koneksi sebelumnya digambar dari kiri ke kanan, tetapi koneksi berikutnya digambar dari kanan ke kiri. Jadi, Anda perlu menyediakan jalur untuk kedua kasus tersebut.

ke arah mana sebuah blok ditarik

Anda dapat mengganti metode makeNotch untuk koneksi berikutnya dan sebelumnya, serta metode makePuzzleTab untuk koneksi input dan output.

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

Lihat Dokumentasi jalur SVG MDN untuk informasi tentang cara menentukan string jalur. Namespace Blockly.utils.svgPaths disediakan sebagai wrapper tipis di sekitar string ini agar lebih mudah dibaca.

Bentuk untuk pemeriksaan koneksi

koneksi yang berbeda dengan bentuk yang berbeda

Anda dapat menyesuaikan koneksi dengan mengubah bentuk berdasarkan pemeriksaan koneksi koneksi.

Hal ini memungkinkan Anda membuat bentuk yang berbeda untuk merepresentasikan jenis data yang berbeda. Misalnya, string dapat direpresentasikan oleh koneksi segitiga, sedangkan boolean diwakili oleh koneksi bulat.

Guna menyediakan bentuk yang berbeda untuk pemeriksaan koneksi yang berbeda, Anda harus mengganti metode shapeFor. Bentuk yang ditampilkan harus diinisialisasi di init.

Lihat bentuk dasar untuk informasi tentang jenis bentuk yang didukung.

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

Input kustom

Anda dapat menyesuaikan bentuk koneksi dengan membuat input yang sepenuhnya kustom. Hal ini hanya dilakukan jika Anda ingin beberapa koneksi terlihat berbeda dari yang lain, tetapi Anda tidak ingin koneksi tersebut didasarkan pada pemeriksaan koneksi.

Misalnya, jika Anda ingin beberapa input nilai diindentasi seperti input pernyataan, Anda dapat membuat input kustom untuk mendukung hal ini.

Membuat class input kustom

Ikuti langkah-langkah untuk membuat input kustom.

Membuat metrik yang dapat diukur

Anda perlu membuat terukur untuk mewakili input kustom Anda.

Input terukur kustom Anda harus mewarisi dari Blockly.blockRendering.InputConnection. Elemen ini juga dapat mencakup data pengukuran tambahan yang Anda perlukan untuk menggambar bentuk input.

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

    // Any extra measurement data...
  }
}

Buat instance yang dapat diukur

Info render Anda perlu membuat instance pengukuran kustom. Untuk melakukannya, Anda perlu mengganti metode 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);
  }
}

Jika ingin, membuat baris

Secara default, input tidak membuat baris baru. Jika ingin input Anda memicu akhir baris, Anda harus mengganti metode shouldStartNewRow_ dari info render Anda.

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

Jika ingin, buat bentuk untuk input Anda

Sebaiknya simpan bentuk input dalam konstanta, seperti yang kita lakukan untuk tab {i>puzzle<i} dan notch. Cara ini akan membuat kode Anda tetap teratur, dan memudahkan perubahan pada lain waktu.

Menggambar input

Terakhir, Anda perlu memodifikasi panel samping untuk menggambar bentuk.

Input kustom dapat:

  • Memengaruhi garis batas blok Anda, seperti input pernyataan

    gambar input outline

  • Atau memengaruhi internal blok Anda, seperti input nilai inline

    gambar input internal

Jika input memengaruhi garis batas blok Anda, ganti drawOutline_. Jika tidak, ganti 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);
        }
      }
    }
  }
}