Bağlam menüsünde, kullanıcının bir bileşende (ör. çalışma alanı, blok veya çalışma alanı yorumu) gerçekleştirebileceği işlemlerin listesi yer alır. İçerik menüsü, sağ tıklama veya dokunmatik cihazda uzun basma işlemine yanıt olarak gösterilir. @blockly/keyboard-navigation
eklentisini kullanıyorsanız bu eklenti de klavye kısayoluyla gösterilir. Bu kısayol, Windows'da varsayılan olarak Ctrl+Enter
, Mac'te ise Command+Enter
olarak ayarlanır.
Bağlam menüleri, kullanıcının nadiren gerçekleştirdiği işlemleri (ör. ekran görüntüsü indirme) eklemek için iyi bir yerdir. Bir işlemin daha yaygın olarak kullanılacağını düşünüyorsanız bu işlemi çağırmak için daha kolay bulunabilir bir yöntem oluşturabilirsiniz.
İçerik menüleri çalışma alanları, bloklar, çalışma alanı yorumları, balonlar ve bağlantılar tarafından desteklenir. Ayrıca kendi özel bileşenlerinizde de uygulayabilirsiniz. Blockly, özelleştirebileceğiniz standart bağlam menüleri sağlar. Ayrıca, çalışma alanlarındaki ve bloklardaki bağlam menülerini çalışma alanı veya blok bazında özelleştirebilirsiniz.
İçerik menülerinin işleyiş şekli
Blockly'de, olası tüm menü öğelerinin şablonlarını içeren bir kayıt defteri bulunur. Her şablon, bağlam menüsünde tek bir öğenin nasıl oluşturulacağını açıklar. Kullanıcı bir bileşende içerik menüsünü çağırdığında bileşen:
Kayıt defterinden, bileşen için geçerli olan bir menü öğeleri dizisi oluşturmasını ister. Kayıt defteri, her şablona bileşen için geçerli olup olmadığını sorar ve geçerliyse diziye ilgili menü öğesini ekler.
Bileşen bir çalışma alanı veya bloksa menünün çağrıldığı çalışma alanında ya da blokta bağlam menüsünü özelleştirme işlevi olup olmadığını kontrol eder. Bu durumda, diziyi işlevine iletir. İşlev, dizinin öğelerini ekleyebilir, silebilir veya değiştirebilir.
İçerik menüsü öğelerinin (muhtemelen değiştirilmiş) dizisini kullanarak içerik menüsünü görüntüler.
Blockly, çalışma alanları, bloklar ve çalışma alanı yorumları için bağlam menülerine yönelik standart bir şablon grubu tanımlar. Çalışma alanları ve bloklarla ilgili şablonları kayıt defterine önceden yükler. Çalışma alanı yorumları için şablonları kullanmak istiyorsanız şablonları kayıt defterine kendiniz yüklemeniz gerekir.
Kayıt defterine şablon ekleme, şablon silme ve şablon değiştirme hakkında bilgi edinmek için Kayıt defterini özelleştirme başlıklı makaleyi inceleyin.
Kapsam
İçerik menüleri; çalışma alanları, çalışma alanı yorumları, bağlantılar, bloklar, balonlar ve kendi özel bileşenleriniz dahil olmak üzere farklı bileşen türleri tarafından uygulanır. Bu bileşen türlerinin her birine ait içerik menüleri farklı öğeler içerebilir ve öğeler, bileşen türüne bağlı olarak farklı şekilde davranabilir. Bu nedenle, içerik menüsü sisteminin hangi bileşende çağrıldığını bilmesi gerekir.
Bu sorunu çözmek için kayıt defteri Scope
nesnesini kullanır. Bağlam menüsünün çağrıldığı bileşen, focusedNode
özelliğinde IFocusableNode
uygulayan bir nesne olarak depolanır. (IFocusableNode
, bağlam menülerini uygulayanlar da dahil olmak üzere kullanıcıların odaklanabileceği tüm bileşenler tarafından uygulanır. Daha fazla bilgi için Odaklanma
sistemi başlıklı makaleyi inceleyin.)
Scope
nesnesi, şablondaki işlevlerin birçoğuna iletilir. Scope
nesnesi alan herhangi bir işlevde, focusedNode
özelliğindeki nesnenin türüne göre ne yapacağınıza karar verebilirsiniz. Örneğin, bileşenin aşağıdakileri içeren bir blok olup olmadığını kontrol edebilirsiniz:
if (scope.focusedNode instanceof Blockly.BlockSvg) {
// do something with the block
}
Scope
nesnesinin, artık kullanılması önerilmeyen ancak yine de ayarlanabilen başka isteğe bağlı özellikleri vardır:
block
yalnızca menüsü gösterilen bileşen birBlockSvg
ise ayarlanır.workspace
yalnızca bileşen birWorkspaceSvg
ise ayarlanır.comment
yalnızca bileşen birRenderedWorkspaceComment
ise ayarlanır.
Bu özellikler, bağlam menüsü olabilecek tüm bileşen türlerini kapsamaz. Bu nedenle focusedNode
özelliğini kullanmanız önerilir.
RegistryItem türü
Şablonlar, aşağıdaki özellikleri içeren ContextMenuRegistry.RegistryItem
türündedir. preconditionFn
, displayText
ve callback
özelliklerinin separator
özelliğiyle aynı anda kullanılamadığını unutmayın.
Kimlik
id
özelliği, bağlam menüsü öğenizin ne yaptığını gösteren benzersiz bir dize olmalıdır.
const collapseTemplate = {
id: 'collapseBlock',
// ...
};
Ön koşul işlevi
Bir içerik menüsü öğesinin ne zaman ve nasıl gösterileceğini kısıtlamak için preconditionFn
öğesini kullanabilirsiniz.
'enabled'
, 'disabled'
veya 'hidden'
gibi bir dizi dizeden birini döndürmelidir.
Değer | Açıklama | Resim |
---|---|---|
'enabled'
|
Öğenin etkin olduğunu gösterir. | ![]() |
'disabled'
|
Öğenin etkin olmadığını gösterir. | ![]() |
'hidden' |
Öğeyi gizler. |
preconditionFn
işlevine, menünün hangi tür bileşende açıldığını ve bu bileşenin durumunu belirlemek için kullanabileceğiniz bir Scope
de iletilir.
Örneğin, bir öğenin yalnızca bloklar için ve yalnızca bu bloklar belirli bir durumdayken görünmesini isteyebilirsiniz:
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';
},
// ...
}
Görünen metin
displayText
, menü öğesinin bir parçası olarak kullanıcıya gösterilmesi gereken öğedir.
Görünen metin bir dize, HTML veya dize ya da HTML döndüren bir işlev olabilir.
const collapseTemplate = {
// ...
displayText: 'Collapse block',
// ...
};
Blockly.Msg
kaynağından çeviri göstermek istiyorsanız bir işlev kullanmanız gerekir. Değeri doğrudan atamaya çalışırsanız mesajlar yüklenmeyebilir ve bunun yerine undefined
değeri gösterilir.
const collapseTemplate = {
// ...
displayText: () => Blockly.Msg['MY_COLLAPSE_BLOCK_TEXT'],
// ...
};
Bir işlev kullanırsanız bu işlev de Scope
değerini alır. Bunu, öğe hakkında bilgileri görünen metninize eklemek için kullanabilirsiniz.
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 '';
},
// ...
}
Ağırlık
weight
, içerik menüsü öğelerinin gösterilme sırasını belirler.
Daha pozitif değerler, listede daha az pozitif değerlerden daha aşağıda gösterilir.
(Daha yüksek ağırlığa sahip öğelerin "daha ağır" olduğunu ve bu nedenle en alta battığını düşünebilirsiniz.)
const collapseTemplate = {
// ...
weight: 10,
// ...
}
Yerleşik içerik menüsü öğelerinin ağırlıkları 1'den başlayarak 1'er artan sırada verilir.
Geri çağırma işlevi
callback
özelliği, bağlam menüsü öğenizin işlemini gerçekleştiren bir işlevdir. Birkaç parametre iletilir:
scope
: Menüsü açılan bileşene referans sağlayan birScope
nesnesi.menuOpenEvent
: İçerik menüsünün açılmasını tetikleyenEvent
. Bu, kullanıcının menüyü nasıl açtığına bağlı olarakPointerEvent
veyaKeyboardEvent
olabilir.menuSelectEvent
: Menüden bu bağlam menüsü öğesini seçenEvent
. Bu, kullanıcının öğeyi nasıl seçtiğine bağlı olarakPointerEvent
veyaKeyboardEvent
olabilir.location
: Menünün açıldığı piksel koordinatlarındaCoordinate
. Bu sayede, örneğin tıklama konumunda yeni bir blok oluşturabilirsiniz.
const collapseTemplate = {
// ...
callback: (scope, menuOpenEvent, menuSelectEvent, location) => {
if (scope.focusedNode instanceof Blockly.BlockSvg) {
scope.focusedNode.collapse();
}
},
}
scope
kullanarak, açıldıkları bileşene bağlı olarak farklı şekilde çalışan şablonlar tasarlayabilirsiniz:
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);
}
}
}
Ayırıcı
separator
özelliği, içerik menüsünde bir çizgi çizer.
separator
özelliği içeren şablonlarda preconditionFn
, displayText
veya callback
özellikleri bulunamaz ve yalnızca scopeType
özelliğiyle kapsamlandırılabilir. Bu kısıtlama, bu emojilerin yalnızca çalışma alanları, bloklar ve çalışma alanı yorumları için bağlam menülerinde kullanılabileceği anlamına gelir.
const separatorAfterCollapseBlockTemplate = {
id: 'separatorAfterCollapseBlock',
scopeType: Blockly.ContextMenuRegistry.ScopeType.BLOCK,
weight: 11, // Between the weights of the two items you want to separate.
separator: true,
};
Bağlam menünüzdeki her ayırıcı için farklı bir şablona ihtiyacınız vardır. Her ayırıcıyı konumlandırmak için weight
özelliğini kullanın.
Kapsam türü
scopeType
özelliğinin desteği sonlandırıldı. Daha önce, bir menü öğesinin blok, çalışma alanı yorumu veya çalışma alanı için içerik menüsünde gösterilip gösterilmeyeceğini belirlemek için kullanılıyordu. Bağlam menüleri diğer bileşenlerde açılabildiğinden scopeType
özelliği çok kısıtlayıcıdır. Bunun yerine, ilgili bileşenler için seçeneğinizi göstermek veya gizlemek üzere preconditionFn
kullanmanız gerekir.
scopeType
kullanan mevcut içerik menüsü şablonlarınız varsa Blockly, öğeyi yalnızca uygun bileşen için göstermeye devam eder.
const collapseTemplate = {
// ...
scopeType: Blockly.ContextMenuRegistry.ScopeType.BLOCK,
// ...
};
Kayıt defterini özelleştirme
Kayıt defterine şablon ekleyebilir, şablonları silebilir veya değiştirebilirsiniz. Varsayılan şablonları contextmenu_items.ts
bölümünde bulabilirsiniz.
Şablon ekleme
Bir şablonu kaydederek kayıt defterine ekleyebilirsiniz. Bu işlemi sayfa yüklendiğinde bir kez yapmanız gerekir. Bu durum, çalışma alanınızı eklemeden önce veya ekledikten sonra gerçekleşebilir.
const collapseTemplate = { /* properties from above */ };
Blockly.ContextMenuRegistry.registry.register(collapseTemplate);
Şablon silme
Bir şablonu kimliğine göre kaydını silerek kayıt defterinden kaldırabilirsiniz.
Blockly.ContextMenuRegistry.registry.unregister('someID');
Şablonu değiştirme
Kayıt defterinden alıp yerinde değiştirerek mevcut bir şablonu değiştirebilirsiniz.
const template = Blockly.ContextMenuRegistry.registry.getItem('someID');
template?.displayText = 'some other display text';
İçerik menülerinin engellenmesini devre dışı bırakma
Varsayılan olarak bloklarda, kullanıcıların blok yorumları ekleme veya blokları çoğaltma gibi işlemler yapmasına olanak tanıyan bir bağlam menüsü bulunur.
Aşağıdaki yöntemlerle tek bir bloğun bağlam menüsünü devre dışı bırakabilirsiniz:
block.contextMenu = false;
Bir blok türünün JSON tanımında enableContextMenu
anahtarını kullanın:
{
// ...,
"enableContextMenu": false,
}
İçerik menülerini blok türüne veya çalışma alanına göre özelleştirme
Blockly bir bağlam menüsü öğeleri dizisi oluşturduktan sonra bunu tek tek bloklar veya çalışma alanları için özelleştirebilirsiniz. Bunu yapmak için BlockSvg.customContextMenu
veya WorkspaceSvg.configureContextMenu
işlevini, diziyi yerinde değiştiren bir işlev olarak ayarlayın.
Bloklara iletilen dizideki nesneler ContextMenuOption
türündedir veya LegacyContextMenuOption
arayüzünü uygular. Çalışma alanlarına aktarılan nesneler ContextMenuOption
türündedir. Blockly, bu nesnelerden aşağıdaki özellikleri kullanır:
text
: Görünen metin.enabled
:false
ise öğeyi gri metinle gösterin.callback
: Öğe tıklandığında çağrılacak işlev.separator
: Öğe bir ayraçtır. Diğer üç özellik ile karşılıklı olarak dışlayıcıdır.
Mülk türleri ve işlev imzalarıyla ilgili referans belgelerine bakın.
Örneğin, bir çalışma alanının içerik menüsüne Hello, World!
öğesi ekleyen bir işlevi aşağıda bulabilirsiniz:
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);
}
Özel bir nesnede içerik menüsü gösterme
Aşağıdaki adımları uygulayarak özel bileşenler için bağlam menülerinin görünmesini sağlayabilirsiniz:
IFocusableNode
uygulayan veyaIFocusableNode
uygulayan bir sınıfı genişleten bir sınıf uygulayın. Bu arayüz, bağlam menüsü sisteminde bileşeninizi tanımlamak için kullanılır. Ayrıca, kullanıcıların klavye gezinme eklentisini kullanarak bileşeninizde gezinmesine de olanak tanır.IContextMenu
işlevini içerenshowContextMenu
işlevini uygulayın. Bu işlev, içerik menüsü öğelerini kayıt defterinden alır, menünün ekranda gösterileceği konumu hesaplar ve son olarak gösterilecek öğeler varsa menüyü gösterir.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); } }
Kullanıcı bileşeninizi sağ tıkladığında
showContextMenu
işlevini çağıran bir etkinlik işleyici ekleyin. Klavye ile gezinme eklentisinin, kullanıcıCtrl+Enter
(Windows) veyaCommand+Enter
(Mac) tuşuna bastığındashowContextMenu
işlevini çağıran bir etkinlik işleyici sağladığını unutmayın.Bağlam menüsü öğeleriniz için kayıt defterine şablon ekleyin.