Ada beberapa cara untuk menyesuaikan tampilan koneksi, masing-masing dengan tingkat kesulitan yang semakin meningkat. Semuanya memerlukan pembuatan perender kustom.
Dimensi dasar
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
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!
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.
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
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
Atau memengaruhi internal blok Anda, seperti input nilai inline
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);
}
}
}
}
}