Phím tắt

Blockly duy trì một sổ đăng ký các phím tắt liên kết các phím (hoặc tổ hợp phím như ctrl-C) với các thao tác. Sổ đăng ký được điền sẵn một số phím tắt, chẳng hạn như ctrl-Cmeta-C để sao chép. Bạn có thể thêm và xoá lối tắt khỏi sổ đăng ký.

Cách hoạt động của phím tắt

Sổ đăng ký phím tắt chứa các đối tượng mô hình hoá phím tắt. Khi người dùng nhấn một phím (hoặc tổ hợp phím), Blockly sẽ:

  1. Kiểm tra sổ đăng ký để xem có lối tắt nào áp dụng cho khoá hay không. Nếu có nhiều phím tắt sử dụng cùng một khoá, các phím tắt sẽ được thử theo thứ tự đăng ký ngược. Tức là lối tắt được đăng ký gần đây nhất sẽ được thử trước.

  2. Gọi hàm preconditionFn của lối tắt để xác định xem lối tắt có áp dụng cho tình huống hiện tại hay không. Ví dụ: phím tắt sao chép áp dụng cho các khối nhưng không áp dụng cho không gian làm việc. Nếu phím tắt không áp dụng được, Blockly sẽ thử phím tắt tiếp theo trong danh sách (nếu có).

  3. Gọi hàm callback của lối tắt. Hàm này thực thi thao tác của lối tắt. Ví dụ: phím tắt sao chép sẽ tạo bản sao của đối tượng hiện được đặt làm tiêu điểm, chẳng hạn như một khối. Nếu hàm này trả về true, quá trình xử lý sẽ dừng. Nếu giá trị trả về là false, Blockly sẽ thử phím tắt tiếp theo trong danh sách (nếu có).

Phạm vi

Đối tượng Scope xác định thành phần Blockly hiện có tiêu điểm. Các đối tượng phạm vi được truyền đến preconditionFncallback. Các đối tượng này sử dụng các đối tượng phạm vi để quyết định xem một lối tắt có áp dụng cho một thành phần cụ thể hay không và nếu có thì cách áp dụng là gì.

Để sử dụng đối tượng Scope, hãy dùng thuộc tính focusedNode. Đây là một đối tượng triển khai IFocusableNode. Tất cả các thành phần Blockly mà người dùng có thể tập trung vào đều triển khai giao diện này, bao gồm cả không gian làm việc, khối, trường, nhận xét và các thành phần tuỳ chỉnh của riêng bạn; để biết thêm thông tin, hãy xem Hệ thống tiêu điểm.

Ví dụ: preconditionFn có thể dùng focusedNode để đảm bảo rằng một lối tắt chỉ áp dụng cho các khối.

preconditionFn(workspace, scope) {
  return (scope.focusedNode instanceof Blockly.BlockSvg);
}

Giao diện KeyboardShortcut

Các đối tượng trong sổ đăng ký lối tắt triển khai giao diện KeyboardShortcut. Đối tượng này chứa các thuộc tính sau.

tên (bắt buộc)

Tên duy nhất cho lối tắt. Người dùng sẽ không thấy thông tin này và bạn không cần phải viết sao cho dễ đọc. Bạn không nên dịch nội dung này.

const logFieldsShortcut = {
  name: 'logFields',
  // ...
};

preconditionFn (không bắt buộc)

Blockly gọi hàm này để quyết định xem một phím tắt có áp dụng cho tình huống hiện tại hay không. Nếu phương thức này trả về true, Blockly sẽ gọi callback. Nếu phương thức này trả về false, Blockly sẽ bỏ qua lối tắt này. Ví dụ:

const logFieldsShortcut = {
  // ...
  preconditionFn(workspace, scope) {
    // This shortcut only applies to blocks.
    return (scope.focusedNode instanceof Blockly.BlockSvg);
  },
  // ...
};

Phím tắt có thể bỏ qua hàm này nếu phím tắt luôn được áp dụng (không phổ biến). Các lối tắt không được bỏ qua hàm này rồi thực hiện hành động có điều kiện trong callback. Việc này sẽ ngăn Blockly thực hiện những việc như tạo trình đơn trợ giúp theo bối cảnh cho thấy các phím tắt có thể áp dụng.

callback (không bắt buộc)

Hàm này thực thi thao tác liên kết với lối tắt. Phương thức này chỉ được gọi nếu preconditionFn trả về true hoặc không tồn tại. Các tham số của hàm này là:

  • workspace: WorkspaceSvg hiện tại.
  • e: Event đã khởi tạo lối tắt.
  • shortcut: Chính KeyboardShortcut.
  • scope: Scope mà lối tắt áp dụng.

Hàm này trả về true nếu thành công và false nếu không thành công.

Ví dụ:

const logFieldsShortcut = {
  // ...
  callback(workspace, event, shortcut, scope) {
    // preconditionFn required focusedNode to be a BlockSvg.
    for (input of scope.focusedNode.inputList) {
      // Log the values of all named fields. (Label fields usually don't have names.)
      for (field of input.fieldRow) {
        if (field.name) {
          console.log(field.name + ': ' + field.getText());
        }
      }
    }
    return true;
  },
  // ...
};

Mặc dù callback là không bắt buộc, nhưng thường không có lý do gì để không triển khai nó.

keyCodes (không bắt buộc)

Một mảng các khoá (hoặc tổ hợp khoá) kích hoạt phím tắt này. Để xác định các khoá, hãy sử dụng mã khoá trong Blockly.utils.KeyCodes. Ví dụ:

const logFieldsShortcut = {
  // ...
  keyCodes: [Blockly.utils.KeyCodes.L],
  // ...
};

Nếu muốn ánh xạ các phím bổ sung vào một phím tắt hiện có (ví dụ: bạn muốn thêm các phím vào một phím tắt mặc định), bạn có thể gọi Blockly.ShortcutRegistry.registry.addKeyMapping. Điều này không phổ biến.

Tổ hợp phím

Nếu phím tắt của bạn được kích hoạt bằng một tổ hợp phím, chẳng hạn như nhấn giữ đồng thời ControlC, hãy tạo một mã khoá được chuyển đổi tuần tự bằng cách gọi Blockly.ShortcutRegistry.registry.createSerializedKey:

const ctrlC = Blockly.ShortcutRegistry.registry.createSerializedKey(
  Blockly.utils.KeyCodes.C,       // Keycode of main key
  [Blockly.utils.KeyCodes.CTRL],  // Array of modifier keys
);

const copyShortcut = {
  // ...
  keyCodes: [ctrlC], // Use the serialized keycode
  // ...
};

Điều khiển và Meta

Trên Windows, nhiều phím tắt được kích hoạt bằng phím Control. Trên máy Mac, các phím tắt này sử dụng phím Command thay cho phím META. Để hỗ trợ cả hai hệ điều hành, hãy đăng ký các phím tắt bằng cả mã khoá CTRL và mã khoá META.

const ctrlC = Blockly.ShortcutRegistry.registry.createSerializedKey(
  Blockly.utils.KeyCodes.C,
  [Blockly.utils.KeyCodes.CTRL],
);
const metaC = Blockly.ShortcutRegistry.registry.createSerializedKey(
  Blockly.utils.KeyCodes.C,
  [Blockly.utils.KeyCodes.META],
);

const copyShortcut = {
  // ...
  keyCodes: [ctrlC, metaC],
  // ...
};

Lưu ý khi triển khai

Trình xử lý sự kiện bàn phím của Blockly sử dụng thuộc tính keycode của KeyboardEvent mặc dù thuộc tính này không được dùng nữa.

allowCollision (không bắt buộc)

Theo mặc định, bạn chỉ có thể đăng ký một phím tắt cho một khoá hoặc tổ hợp khoá nhất định. Việc đặt thuộc tính này thành true cho phép bạn đăng ký một phím (hoặc tổ hợp phím) ngay cả khi một phím tắt có cùng phím (hoặc tổ hợp phím) đã được đăng ký.

Xin lưu ý rằng thuộc tính này chỉ áp dụng khi bạn cố gắng đăng ký phím tắt này. Chế độ này không ngăn các phím tắt khác sử dụng cùng một phím (hoặc tổ hợp phím). Việc có thể đăng ký hay không phụ thuộc vào giá trị của thuộc tính allowCollision.

Bất kể có bao nhiêu phím tắt được đăng ký cho một phím hoặc tổ hợp phím nhất định, tối đa một phím tắt sẽ được thực thi thành công. Các lối tắt được thử theo thứ tự ngược lại của quá trình đăng ký (từ lối tắt được đăng ký sau cùng đến lối tắt được đăng ký đầu tiên). Sau khi một trong các lối tắt đó trả về true từ lệnh gọi lại của chúng, không có lối tắt nào khác được thử.

siêu dữ liệu (không bắt buộc)

Đây là một đối tượng tuỳ ý chứa thông tin bổ sung. Tham số này có sẵn cho callback thông qua tham số shortcut.

Thêm, xoá và sửa đổi lối tắt

Để thêm một phím tắt mới, hãy gọi Blockly.ShortcutRegistry.registry.register:

Blockly.ShortcutRegistry.registry.register(logFieldsShortcut);

Hàm này có tham số thứ hai (allowOverrides) cho phép bạn thay thế một phím tắt hiện có bằng phím tắt có cùng tên. Xin lưu ý rằng thao tác này khác với KeyboardShortcut.allowCollision. Thao tác này cho phép bạn thêm một phím tắt có tên khác nhưng sử dụng cùng một phím hoặc tổ hợp phím với một phím tắt hiện có.

Để xoá một phím tắt, hãy gọi Blockly.ShortcutRegistry.registry.unregister và truyền tên của phím tắt:

Blockly.ShortcutRegistry.registry.unregister('logFields');

Bạn không thể sửa đổi phím tắt tại chỗ. Thay vào đó, bạn cần xoá phím tắt hiện có và thêm một phím tắt mới. Ví dụ:

// Get the existing shortcut. getRegistry returns an object keyed by shortcut name.
const allShortcuts = Blockly.ShortcutRegistry.registry.getRegistry();
const modLogFieldsShortcut = allShortcuts[logFieldsShortcut.name];
// Apply the shortcut only to math blocks,
modLogFieldsShortcut.preconditionFn = function (workspace, scope) {
  return (scope.focusedNode instanceof Blockly.BlockSvg &&
          scope.focusedNode.type.startsWith('math_'));
}
// Delete the existing shortcut and add the modified shortcut.
Blockly.ShortcutRegistry.registry.unregister(logFieldsShortcut.name);
Blockly.ShortcutRegistry.registry.register(modLogFieldsShortcut);

Phím tắt mặc định

Sổ đăng ký phím tắt được điền sẵn một số phím tắt. Bạn có thể tìm thấy các mục này trong https://github.com/google/blockly/blob/master/core/shortcut_items.ts. Các lối tắt được xác định trong các hàm registerXxxx.

Phím tắt điều hướng

Trình bổ trợ điều hướng bằng bàn phím chứa các lối tắt cho phép người dùng điều hướng Blockly bằng bàn phím, chẳng hạn như bằng cách sử dụng các phím mũi tên. Thao tác bằng bàn phím là điều cần thiết đối với những người dùng không thể sử dụng chuột, chẳng hạn như người bị suy giảm vận động hoặc thị lực. Tính năng này cũng hữu ích cho những người dùng thành thạo có thể muốn sử dụng phím tắt để làm việc hiệu quả.