Menu konteks berisi daftar tindakan yang dapat dilakukan pengguna pada komponen
seperti ruang kerja, blok, atau komentar ruang kerja. Menu konteks ditampilkan sebagai
respons terhadap klik kanan atau tekan lama pada perangkat sentuh. Jika Anda menggunakan
plugin @blockly/keyboard-navigation
, plugin tersebut juga
ditampilkan dengan pintasan keyboard, yang secara default adalah Ctrl+Enter
di Windows atau
Command+Enter
di Mac.
Menu konteks adalah tempat yang tepat untuk menambahkan tindakan yang jarang dilakukan pengguna, seperti mendownload screenshot. Jika Anda merasa suatu tindakan akan lebih sering digunakan, Anda mungkin ingin membuat cara yang lebih mudah ditemukan untuk memanggilnya.
Menu konteks didukung oleh ruang kerja, blok, komentar ruang kerja, balon, dan koneksi. Anda juga dapat menerapkannya pada komponen kustom Anda sendiri. Blockly menyediakan menu konteks standar yang dapat Anda sesuaikan. Anda juga dapat menyesuaikan menu konteks di ruang kerja dan blok berdasarkan per ruang kerja atau per blok.
Cara kerja menu konteks
Blockly memiliki registri yang berisi template untuk semua kemungkinan item menu. Setiap template menjelaskan cara membuat satu item dalam menu konteks. Saat pengguna memanggil menu konteks pada komponen, komponen:
Meminta konstruksi registry membuat array item menu yang berlaku untuk komponen. Registry akan menanyakan kepada setiap template apakah template tersebut berlaku untuk komponen dan, jika ya, akan menambahkan item menu yang sesuai ke array.
Jika komponen adalah ruang kerja atau blok, periksa apakah ruang kerja atau blok tertentu tempat menu dipanggil memiliki fungsi untuk menyesuaikan menu konteks. Jika demikian, array akan diteruskan ke fungsi, yang dapat menambahkan, menghapus, atau mengubah elemen array.
Menampilkan menu konteks menggunakan array item menu konteks (yang mungkin telah diubah).
Blockly menentukan serangkaian template standar untuk menu konteks bagi ruang kerja, blok, dan komentar ruang kerja. Plugin ini memuat sebelumnya template untuk ruang kerja dan blok ke dalam registry. Jika ingin menggunakan template untuk komentar ruang kerja, Anda harus memuatnya ke dalam registri sendiri.
Untuk mengetahui informasi tentang cara menambahkan, menghapus, dan mengubah template di registry, lihat Menyesuaikan registry.
Cakupan
Menu konteks diimplementasikan oleh berbagai jenis komponen, termasuk ruang kerja, komentar ruang kerja, koneksi, blok, balon, dan komponen kustom Anda sendiri. Menu konteks untuk setiap jenis komponen ini dapat berisi item yang berbeda, dan item dapat berperilaku berbeda berdasarkan jenis komponen. Oleh karena itu, sistem menu konteks perlu mengetahui komponen mana yang memanggilnya.
Untuk mengatasi hal ini, registri menggunakan objek Scope
. Komponen tempat
menu konteks dipanggil disimpan dalam properti focusedNode
sebagai objek
yang mengimplementasikan IFocusableNode
. (IFocusableNode
diterapkan oleh semua komponen yang dapat difokuskan pengguna, termasuk yang menerapkan menu konteks. Untuk mengetahui informasi selengkapnya, lihat Sistem
fokus.)
Objek Scope
diteruskan ke beberapa fungsi dalam template. Dalam fungsi apa pun yang mendapatkan objek Scope
, Anda dapat memutuskan tindakan yang akan dilakukan berdasarkan jenis objek dalam properti focusedNode
. Misalnya, Anda dapat memeriksa apakah
komponen adalah blok dengan:
if (scope.focusedNode instanceof Blockly.BlockSvg) {
// do something with the block
}
Objek Scope
memiliki properti opsional lain yang tidak lagi direkomendasikan untuk digunakan, tetapi masih dapat ditetapkan:
block
hanya disetel jika komponen yang menunya ditampilkan adalahBlockSvg
.workspace
hanya ditetapkan jika komponennya adalahWorkspaceSvg
.comment
hanya ditetapkan jika komponennya adalahRenderedWorkspaceComment
.
Properti ini tidak mencakup semua jenis komponen yang mungkin memiliki menu
konteks, jadi sebaiknya gunakan properti focusedNode
.
Jenis RegistryItem
Template memiliki jenis ContextMenuRegistry.RegistryItem
,
yang berisi properti berikut. Perhatikan bahwa properti preconditionFn
,
displayText
, dan callback
tidak dapat terjadi bersamaan dengan
properti separator
.
ID
Properti id
harus berupa string unik yang menunjukkan fungsi item menu
konteks Anda.
const collapseTemplate = {
id: 'collapseBlock',
// ...
};
Fungsi prasyarat
Anda dapat menggunakan preconditionFn
untuk membatasi kapan dan bagaimana item menu konteks
harus ditampilkan.
Metode ini harus menampilkan salah satu dari serangkaian string: 'enabled'
, 'disabled'
, atau
'hidden'
.
Nilai | Deskripsi | Gambar |
---|---|---|
'enabled'
|
Menunjukkan bahwa item aktif. | ![]() |
'disabled'
|
Menunjukkan bahwa item tidak aktif. | ![]() |
'hidden' |
Menyembunyikan item. |
preconditionFn
juga meneruskan Scope
yang dapat Anda gunakan untuk
menentukan jenis komponen tempat menu dibuka dan status
komponen tersebut.
Misalnya, Anda mungkin ingin item hanya muncul untuk blok, dan hanya saat blok tersebut dalam status tertentu:
const collapseTemplate = {
// ...
preconditionFn: (scope) => {
if (scope.focusedNode instanceof Blockly.BlockSvg) {
if (!scope.focusedNode.isCollapsed()) {
// The component is a block and it is not already collapsed
return 'enabled';
} else {
// The block is already collapsed
return 'disabled';
}
}
// The component is not a block
return 'hidden';
},
// ...
}
Teks tampilan
displayText
adalah yang harus ditampilkan kepada pengguna sebagai bagian dari item menu.
Teks tampilan dapat berupa string, atau HTML, atau fungsi yang menampilkan string atau HTML.
const collapseTemplate = {
// ...
displayText: 'Collapse block',
// ...
};
Jika Anda ingin menampilkan terjemahan dari Blockly.Msg
, Anda harus menggunakan
fungsi. Jika Anda mencoba menetapkan nilai secara langsung, pesan mungkin tidak dimuat dan Anda akan mendapatkan nilai undefined
.
const collapseTemplate = {
// ...
displayText: () => Blockly.Msg['MY_COLLAPSE_BLOCK_TEXT'],
// ...
};
Jika Anda menggunakan fungsi, fungsi tersebut juga akan meneruskan nilai Scope
. Anda dapat menggunakan
ini untuk menambahkan informasi tentang elemen ke teks tampilan.
const collapseTemplate = {
// ...
displayText: (scope) => {
if (scope.focusedNode instanceof Blockly.Block) {
return `Collapse ${scope.focusedNode.type} block`;
}
// Shouldn't be possible, as our preconditionFn only shows this item for blocks
return '';
},
// ...
}
Berat
weight
menentukan urutan item menu konteks ditampilkan.
Nilai yang lebih positif ditampilkan lebih rendah dalam daftar daripada nilai yang kurang positif.
(Anda dapat membayangkan bahwa item dengan bobot yang lebih tinggi "lebih berat" sehingga tenggelam ke
bagian bawah.)
const collapseTemplate = {
// ...
weight: 10,
// ...
}
Bobot untuk item menu konteks bawaan diurutkan dalam urutan menaik, dimulai dari 1 dan bertambah 1.
Fungsi callback
Properti callback
adalah fungsi yang melakukan tindakan item menu
konteks Anda. Fungsi ini meneruskan beberapa parameter:
scope
: ObjekScope
yang memberikan referensi ke komponen yang menunya dibuka.menuOpenEvent
:Event
yang memicu pembukaan menu konteks. Ini dapat berupaPointerEvent
atauKeyboardEvent
, bergantung pada cara pengguna membuka menu.menuSelectEvent
:Event
yang memilih item menu konteks tertentu ini dari menu. Ini dapat berupaPointerEvent
atauKeyboardEvent
, bergantung pada cara pengguna memilih item.location
:Coordinate
dalam koordinat piksel tempat menu dibuka. Dengan demikian, Anda dapat, misalnya, membuat blok baru di lokasi klik.
const collapseTemplate = {
// ...
callback: (scope, menuOpenEvent, menuSelectEvent, location) => {
if (scope.focusedNode instanceof Blockly.BlockSvg) {
scope.focusedNode.collapse();
}
},
}
Anda dapat menggunakan scope
untuk mendesain template yang berfungsi secara berbeda, bergantung pada
komponen tempat template tersebut dibuka:
const collapseTemplate = {
// ...
callback: (scope) => {
if (scope.focusedNode instance of Blockly.BlockSvg) {
// On a block, collapse just the block.
const block = scope.focusedNode;
block.collapse();
} else if (scope.focusedNode instanceof Blockly.WorkspaceSvg) {
// On a workspace, collapse all the blocks.
let workspace = scope.focusedNode;
collapseAllBlocks(workspace);
}
}
}
Pemisah
Properti separator
menggambar garis di menu konteks.
Template dengan properti separator
tidak boleh memiliki properti preconditionFn
,
displayText
, atau callback
dan hanya dapat dicakup dengan
properti scopeType
. Pembatasan terakhir berarti mereka hanya dapat digunakan di menu konteks untuk ruang kerja, blok, dan komentar ruang kerja.
const separatorAfterCollapseBlockTemplate = {
id: 'separatorAfterCollapseBlock',
scopeType: Blockly.ContextMenuRegistry.ScopeType.BLOCK,
weight: 11, // Between the weights of the two items you want to separate.
separator: true,
};
Anda memerlukan template yang berbeda untuk setiap pemisah di menu konteks. Gunakan properti
weight
untuk memosisikan setiap pemisah.
Jenis cakupan
Properti scopeType
tidak digunakan lagi. Sebelumnya, opsi ini digunakan untuk menentukan apakah item menu harus ditampilkan di menu konteks untuk blok, komentar ruang kerja, atau ruang kerja. Karena menu konteks dapat dibuka di komponen lain, properti
scopeType
terlalu membatasi. Sebagai gantinya, Anda harus menggunakan
preconditionFn
untuk menampilkan atau menyembunyikan opsi untuk komponen yang sesuai.
Jika Anda memiliki template menu konteks yang sudah ada dan menggunakan scopeType
, Blockly akan
terus menampilkan item hanya untuk komponen yang sesuai.
const collapseTemplate = {
// ...
scopeType: Blockly.ContextMenuRegistry.ScopeType.BLOCK,
// ...
};
Menyesuaikan registri
Anda dapat menambahkan, menghapus, atau mengubah template di registri. Anda dapat menemukan
template default di contextmenu_items.ts
.
Menambahkan template
Anda dapat menambahkan template ke registry dengan mendaftarkannya. Anda harus melakukannya sekali saat pemuatan halaman. Hal ini dapat terjadi sebelum atau setelah Anda menyuntikkan ruang kerja.
const collapseTemplate = { /* properties from above */ };
Blockly.ContextMenuRegistry.registry.register(collapseTemplate);
Menghapus template
Anda dapat menghapus template dari registri dengan membatalkan pendaftarannya menurut ID.
Blockly.ContextMenuRegistry.registry.unregister('someID');
Mengubah template
Anda dapat mengubah template yang ada dengan mengambil template dari registry lalu mengubahnya di tempat.
const template = Blockly.ContextMenuRegistry.registry.getItem('someID');
template?.displayText = 'some other display text';
Nonaktifkan menu konteks pemblokiran
Secara default, blok memiliki menu konteks yang memungkinkan pengguna melakukan hal-hal seperti menambahkan komentar blok atau menduplikasi blok.
Anda dapat menonaktifkan menu konteks setiap blok dengan melakukan:
block.contextMenu = false;
Dalam definisi JSON jenis blok, gunakan kunci enableContextMenu
:
{
// ...,
"enableContextMenu": false,
}
Menyesuaikan menu konteks per jenis blok atau ruang kerja
Setelah Blockly membuat array item menu konteks, Anda dapat menyesuaikannya untuk setiap blok atau ruang kerja. Untuk melakukannya, tetapkan BlockSvg.customContextMenu
atau
WorkspaceSvg.configureContextMenu
ke fungsi yang
mengubah array di tempat.
Objek dalam array yang diteruskan ke blok memiliki jenis
ContextMenuOption
atau mengimplementasikan antarmuka
LegacyContextMenuOption
. Objek yang diteruskan ke
ruang kerja memiliki jenis ContextMenuOption
. Blockly menggunakan properti berikut dari objek ini:
text
: Teks tampilan.enabled
: Jikafalse
, tampilkan item dengan teks berwarna abu-abu.callback
: Fungsi yang akan dipanggil saat item diklik.separator
: Item adalah pemisah. Tidak dapat muncul bersamaan dengan tiga properti lainnya.
Lihat dokumentasi referensi untuk jenis properti dan tanda tangan fungsi.
Misalnya, berikut adalah fungsi yang menambahkan item Hello, World!
ke menu konteks ruang kerja:
workspace.configureContextMenu = function (menuOptions, e) {
const item = {
text: 'Hello, World!',
enabled: true,
callback: function () {
alert('Hello, World!');
},
};
// Add the item to the end of the context menu.
menuOptions.push(item);
}
Menampilkan menu konteks pada objek kustom
Anda dapat membuat menu konteks muncul untuk komponen kustom dengan mengikuti langkah-langkah berikut:
- Terapkan
IFocusableNode
atau perluas class yang menerapkanIFocusableNode
. Antarmuka ini digunakan dalam sistem menu konteks untuk mengidentifikasi komponen Anda. Hal ini juga memungkinkan pengguna menavigasi ke komponen Anda menggunakan plugin navigasi keyboard. Implementasikan
IContextMenu
, yang berisi fungsishowContextMenu
. Fungsi ini mendapatkan item menu konteks dari registri, menghitung lokasi di layar tempat menu akan ditampilkan, dan akhirnya menampilkan menu jika ada item yang akan ditampilkan.const MyBubble implements IFocusableNode, IContextMenu { ... showContextMenu(menuOpenEvent) { // Get the items from the context menu registry const scope = {focusedNode: this}; const items = Blockly.ContextMenuRegistry.registry.getContextMenuOptions(scope, menuOpenEvent); // Return early if there are no items available if (!items.length) return; // Show the menu at the same location on screen as this component // The location is in pixel coordinates, so translate from workspace coordinates const location = Blockly.utils.svgMath.wsToScreenCoordinates(new Coordinate(this.x, this.y)); // Show the context menu Blockly.ContextMenu.show(menuOpenEvent, items, this.workspace.RTL, this.workspace, location); } }
Tambahkan pengendali peristiwa yang memanggil
showContextMenu
saat pengguna mengklik kanan komponen Anda. Perhatikan bahwa plugin navigasi keyboard menyediakan pengendali peristiwa yang memanggilshowContextMenu
saat pengguna menekanCtrl+Enter
(Windows) atauCommand+Enter
(Mac).Tambahkan template ke registry untuk item menu konteks Anda.