Bentuk koneksi

Ada beberapa cara untuk menyesuaikan tampilan koneksi, masing-masing dengan menambah kesulitan. Semuanya membutuhkan pembuatan perender kustom.

Dimensi dasar

koneksi dengan dimensi berbeda

Anda bisa menyesuaikan koneksi dengan mengubah lebar atau tingginya, sementara mempertahankan bentuk dasar yang sama. Untuk melakukan ini, Anda perlu membuat komponen konstanta kustom, dan mengganti beberapa konstanta.

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

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

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

Ini diperlukan karena karena panel samping menggambar garis luar blok ini, menggambar setiap jenis koneksi di kedua 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-kasus tersebut.

ke arah suatu blok akan ditarik

Anda dapat mengganti metode makeNotch untuk metode berikutnya dan sebelumnya koneksi, dan metode makePuzzleTab untuk input dan koneksi 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 MMD SVG untuk informasi tentang cara untuk menentukan {i>string<i} jalur. Namespace Blockly.utils.svgPaths disediakan sebagai pembungkus tipis di sekeliling {i>string<i} ini untuk membuatnya lebih mudah dibaca.

Bentuk untuk pemeriksaan koneksi

koneksi yang berbeda 
dengan bentuk yang berbeda

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

Ini memungkinkan Anda membuat bentuk yang berbeda untuk mewakili jenis data yang berbeda. Misalnya, {i>string<i} dapat direpresentasikan oleh koneksi segitiga, sedangkan boolean diwakili oleh koneksi bulat.

Guna menyediakan bentuk yang berbeda untuk pemeriksaan koneksi yang berbeda, Anda perlu 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. Ini hanya dilakukan jika Anda ingin beberapa koneksi terlihat berbeda dari yang lain, tetapi yang tidak Anda inginkan didasarkan pada pemeriksaan koneksi.

Misalnya, jika Anda ingin beberapa {i>input<i} nilai diindentasi seperti {i>input <i}pernyataan, Anda dapat membuat input kustom untuk mendukungnya.

Membuat class input kustom

Ikuti langkah-langkah untuk membuat input kustom.

Membuat metrik terukur

Anda perlu membuat terukur untuk mewakili input kustom Anda.

Input kustom terukur harus mewarisi dari Blockly.blockRendering.InputConnection Termasuk di dalamnya adalah data pengukuran tambahan apa pun yang Anda butuhkan untuk menggambar bentuk {i>input.<i}

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

    // Any extra measurement data...
  }
}

Buat instance terukur

Info render Anda perlu membuat instance kustom terukur. 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);
  }
}

(Opsional) Buat baris

Secara default, input tidak membuat baris baru. Jika Anda menginginkan masukan untuk memicu akhir baris, Anda perlu mengganti Metode shouldStartNewRow_ Anda info render.

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 Anda dalam konstanta, seperti kami lakukan untuk notch dan tab puzzle. Ini membuat kode Anda tetap terorganisir, dan membuat lebih mudah untuk diubah.

Menggambar input

Terakhir, Anda perlu memodifikasi panel samping untuk menggambar bentuk.

Input kustom dapat:

  • Memengaruhi garis luar blok Anda, seperti input pernyataan

    gambar input struktur

  • Atau memengaruhi bagian dalam blok Anda, seperti input nilai inline

    gambar input internal

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