Hình dạng kết nối

Có một số cách để bạn có thể tuỳ chỉnh giao diện của kết nối, mỗi cách có độ khó tăng dần. Tất cả những trình kết xuất này đều cần bạn tạo một trình kết xuất tuỳ chỉnh.

Kích thước cơ bản

các kết nối với nhiều kích thước

Bạn có thể tuỳ chỉnh các kết nối bằng cách thay đổi chiều rộng hoặc chiều cao của các kết nối đó mà vẫn giữ nguyên hình dạng cơ bản. Để thực hiện việc này, bạn cần tạo một thành phần trình cung cấp hằng số tuỳ chỉnh và ghi đè một số hằng số.

Mỗi trình kết xuất đều xác định và sử dụng các hằng số riêng, vì vậy, hãy xem tài liệu tham khảo về lớp cấp cao của bạn:

Đối với trình kết xuất cơ sở, bạn có thể ghi đè NOTCH_WIDTHNOTCH_HEIGHT cho các kết nối tiếp theo và trước đó, cũng như TAB_WIDTHTAB_HEIGHT cho các kết nối đầu vào và đầu ra.

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

Hình dạng cơ bản

các kết nối có hình dạng khác nhau

Bạn có thể tuỳ chỉnh kết nối bằng cách ghi đè hình dạng cơ bản của kết nối. Hình cơ bản có chiều cao, chiều rộng và 2 đường dẫn.

Mỗi đường dẫn đều vẽ cùng một hình dạng, nhưng từ hai đầu đối diện!

một rãnh được vẽ từ cả hai hướng

Điều này là cần thiết vì khi vẽ đường viền của khối, ngăn sẽ vẽ từng loại kết nối theo cả hai hướng. Ví dụ: các kết nối trước đó được vẽ từ trái sang phải, nhưng các kết nối tiếp theo được vẽ từ phải sang trái. Vì vậy, bạn cần cung cấp đường dẫn cho cả hai trường hợp đó.

hướng vẽ một khối

Bạn có thể ghi đè phương thức makeNotch cho các kết nối tiếp theo và trước đó, cũng như phương thức makePuzzleTab cho các kết nối đầu vào và đầu ra.

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

Hãy xem tài liệu về đường dẫn MMDN SVG để biết thông tin về cách xác định các chuỗi đường dẫn. Không gian tên Blockly.utils.svgPaths được cung cấp dưới dạng một trình bao bọc mỏng xung quanh các chuỗi này để giúp các chuỗi dễ đọc hơn.

Các hình dạng để kiểm tra kết nối

các kết nối khác nhau với hình dạng khác nhau

Bạn có thể tuỳ chỉnh các kết nối bằng cách thay đổi hình dạng dựa trên quy trình kiểm tra kết nối của kết nối.

Điều này cho phép bạn tạo nhiều hình dạng để đại diện cho các loại dữ liệu khác nhau. Ví dụ: chuỗi có thể được biểu thị bằng kết nối hình tam giác, trong khi boolean được biểu thị bằng kết nối tròn.

Để cung cấp nhiều hình dạng cho nhiều lượt kiểm tra kết nối, bạn cần ghi đè phương thức shapeFor. Các hình dạng được trả về sẽ được khởi tạo trong init.

Hãy xem các hình dạng cơ bản để biết thông tin về những loại hình dạng được hỗ trợ.

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

Thông tin đầu vào tuỳ chỉnh

Bạn có thể tuỳ chỉnh hình dạng kết nối bằng cách tạo một đầu vào hoàn toàn tuỳ chỉnh. Việc này chỉ được thực hiện nếu bạn muốn một số kết nối hiển thị khác với các kết nối khác, nhưng không muốn kết nối đó dựa trên quá trình kiểm tra kết nối.

Ví dụ: nếu muốn một số giá trị đầu vào được thụt lề như đầu vào câu lệnh, bạn có thể tạo một giá trị nhập tuỳ chỉnh để hỗ trợ việc này.

Tạo một lớp dữ liệu đầu vào tuỳ chỉnh

Làm theo các bước để tạo dữ liệu đầu vào tuỳ chỉnh.

Tạo ra một quảng cáo có thể đo lường

Bạn cần tạo một giá trị có thể đo lường để biểu thị dữ liệu đầu vào tuỳ chỉnh của mình.

Dữ liệu đầu vào tuỳ chỉnh có thể đo lường phải kế thừa từ Blockly.blockRendering.InputConnection. Đối tượng này cũng có thể bao gồm mọi dữ liệu đo lường bổ sung mà bạn cần để vẽ hình dạng của đầu vào.

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

    // Any extra measurement data...
  }
}

Tạo thực thể có thể đo lường

Thông tin kết xuất của bạn cần tạo thực thể cho tuỳ chỉnh có thể đo lường. Để thực hiện việc này, bạn cần phải ghi đè phương thức 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);
  }
}

Tạo một hàng (không bắt buộc)

Theo mặc định, dữ liệu đầu vào không tạo hàng mới. Nếu muốn dữ liệu đầu vào kích hoạt ở cuối một hàng, bạn cần ghi đè phương thức shouldStartNewRow_ của thông tin kết xuất.

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

Tạo tuỳ ý hình dạng cho thông tin nhập vào của bạn

Tốt nhất là nên lưu trữ hình dạng của dữ liệu đầu vào một cách cố định, giống như cách chúng ta làm với các thẻ xếp hình và cắt xếp. Việc này giúp cho mã của bạn luôn gọn gàng và giúp bạn sửa đổi sau này dễ dàng hơn.

Vẽ giá trị đầu vào

Cuối cùng, bạn cần sửa đổi ngăn để vẽ hình dạng.

Thông tin đầu vào tuỳ chỉnh có thể:

  • Ảnh hưởng đến đường viền của khối, chẳng hạn như nhập câu lệnh

    hình ảnh phác thảo đầu vào

  • Hoặc ảnh hưởng đến bên trong khối, chẳng hạn như đầu vào giá trị cùng dòng

    ảnh đầu vào nội bộ

Nếu dữ liệu đầu vào ảnh hưởng đến đường viền của khối, hãy ghi đè drawOutline_, nếu không, hãy ghi đè 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);
        }
      }
    }
  }
}