یک منوی زمینه حاوی لیستی از اقداماتی است که کاربر می تواند روی یک مؤلفه مانند یک فضای کاری، بلوک یا نظر فضای کاری انجام دهد. منوی زمینه در پاسخ به کلیک راست یا فشار طولانی روی یک دستگاه لمسی نشان داده می شود. اگر از افزونه @blockly/keyboard-navigation
استفاده می کنید، همچنین با یک میانبر صفحه کلید نشان داده می شود که به طور پیش فرض Ctrl+Enter
در ویندوز یا Command+Enter
در مک است.
منوهای زمینه مکان خوبی برای افزودن اقداماتی هستند که کاربر به ندرت انجام می دهد، مانند دانلود یک اسکرین شات. اگر فکر میکنید از یک عمل بیشتر استفاده میشود، ممکن است بخواهید روشی قابل کشفتر برای فراخوانی آن ایجاد کنید.
منوهای زمینه توسط فضاهای کاری، بلوک ها، نظرات فضای کاری، حباب ها و اتصالات پشتیبانی می شوند. شما همچنین می توانید آنها را بر روی اجزای سفارشی خود پیاده سازی کنید . Blockly منوهای زمینه استانداردی را ارائه می دهد که می توانید آنها را سفارشی کنید. همچنین می توانید منوهای زمینه را در فضای کاری و بلوک ها را بر اساس هر فضای کاری یا هر بلوک سفارشی کنید.
منوهای زمینه چگونه کار می کنند
Blockly دارای یک رجیستری است که شامل الگوهایی برای تمام آیتم های منوی ممکن است. هر الگو نحوه ساخت یک آیتم واحد را در منوی زمینه توضیح می دهد. هنگامی که کاربر یک منوی زمینه را در یک جزء فراخوانی می کند، مؤلفه:
از رجیستری میخواهد آرایهای از آیتمهای منو را بسازد که بر روی کامپوننت اعمال میشود. رجیستری از هر الگو می پرسد که آیا برای کامپوننت اعمال می شود یا خیر و اگر چنین است، یک آیتم منوی مربوطه را به آرایه اضافه می کند.
اگر مؤلفه یک فضای کاری یا بلوک است، بررسی می کند که آیا فضای کاری یا بلوکی خاصی که منو در آن فراخوانی شده است ، عملکردی برای سفارشی کردن منوی زمینه دارد یا خیر. اگر چنین است، آرایه را به تابع میدهد که میتواند عناصر آرایه را اضافه، حذف یا تغییر دهد.
منوی زمینه را با استفاده از آرایه (احتمالاً اصلاح شده) آیتم های منوی زمینه نمایش می دهد.
Blockly مجموعه استانداردی از الگوها را برای منوهای زمینه برای فضاهای کاری، بلوک ها و نظرات فضای کاری تعریف می کند. این قالب ها را برای فضاهای کاری از قبل بارگذاری می کند و در رجیستری بلوک می کند. اگر میخواهید از الگوها برای نظرات فضای کاری استفاده کنید، باید خودتان آنها را در رجیستری بارگیری کنید .
برای اطلاعات در مورد نحوه افزودن، حذف و اصلاح الگوها در رجیستری، به سفارشی کردن رجیستری مراجعه کنید.
دامنه
منوهای زمینه توسط انواع مختلفی از مؤلفه ها، از جمله فضاهای کاری، نظرات فضای کاری، اتصالات، بلوک ها، حباب ها و مؤلفه های سفارشی خود پیاده سازی می شوند. منوهای زمینه برای هر یک از این انواع مؤلفه ممکن است شامل موارد مختلفی باشد و موارد ممکن است بر اساس نوع مؤلفه رفتار متفاوتی داشته باشند. بنابراین، سیستم منوی زمینه باید بداند که بر روی کدام مؤلفه فراخوانی شده است.
برای رفع این مشکل، رجیستری از یک شی Scope
استفاده می کند. مؤلفه ای که منوی زمینه در آن فراخوانی شده است در ویژگی focusedNode
به عنوان یک شی که IFocusableNode
را پیاده سازی می کند ذخیره می شود. ( IFocusableNode
توسط تمام مؤلفههایی که کاربران میتوانند روی آنها تمرکز کنند، اجرا میشود، از جمله آنهایی که منوهای زمینه را پیادهسازی میکنند. برای اطلاعات بیشتر، به سیستم فوکوس مراجعه کنید.)
شی Scope
به چندین تابع در یک الگو ارسال می شود. در هر تابعی که یک شی Scope
دریافت می کند، می توانید بر اساس نوع شیء موجود در ویژگی focusedNode
تصمیم بگیرید که چه کاری انجام دهید. به عنوان مثال، می توانید بررسی کنید که آیا جزء یک بلوک است با:
if (scope.focusedNode instanceof Blockly.BlockSvg) {
// do something with the block
}
شی Scope
دارای ویژگی های اختیاری دیگری است که دیگر برای استفاده توصیه نمی شوند، اما همچنان ممکن است تنظیم شوند:
-
block
فقط در صورتی تنظیم می شود که مؤلفه ای که منوی آن نشان داده شده یکBlockSvg
باشد. -
workspace
تنها در صورتی تنظیم میشود که مؤلفه یکWorkspaceSvg
باشد. -
comment
فقط در صورتی تنظیم می شود که مؤلفه یکRenderedWorkspaceComment
باشد.
این ویژگیها همه انواع مؤلفههایی را که ممکن است دارای منوی زمینه باشند را پوشش نمیدهند، بنابراین بهتر است از ویژگی focusedNode
استفاده کنید.
نوع RegistryItem
قالب ها دارای نوع ContextMenuRegistry.RegistryItem
هستند که دارای ویژگی های زیر است. توجه داشته باشید که ویژگیهای preconditionFn
، displayText
و callback
با خاصیت separator
متقابل هستند.
شناسه
ویژگی id
باید یک رشته منحصر به فرد باشد که نشان می دهد آیتم منوی زمینه شما چه کاری انجام می دهد.
const collapseTemplate = {
id: 'collapseBlock',
// ...
};
تابع پیش شرط
می توانید از preconditionFn
برای محدود کردن زمان و نحوه نمایش آیتم های منوی زمینه استفاده کنید.
باید یکی از مجموعهای از رشتهها را برگرداند: 'enabled'
، 'disabled'
یا 'hidden'
.
ارزش | توضیحات | تصویر |
---|---|---|
'enabled' | نشان می دهد که مورد فعال است. | ![]() |
'disabled' | نشان می دهد که مورد فعال نیست. | ![]() |
'hidden' | مورد را پنهان می کند. |
به preconditionFn
نیز یک Scope
ارسال می شود که می توانید از آن برای تعیین نوع مؤلفه ای که منو روی آن باز شده و وضعیت آن مؤلفه استفاده کنید.
به عنوان مثال، ممکن است بخواهید یک آیتم فقط برای بلوک ها ظاهر شود و فقط زمانی که آن بلوک ها در یک وضعیت خاص هستند:
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';
},
// ...
}
نمایش متن
displayText
چیزی است که باید به عنوان بخشی از آیتم منو به کاربر نشان داده شود. متن نمایشی می تواند یک رشته یا HTML یا تابعی باشد که یک رشته یا HTML را برمی گرداند.
const collapseTemplate = {
// ...
displayText: 'Collapse block',
// ...
};
اگر می خواهید ترجمه ای از Blockly.Msg
را نمایش دهید، باید از یک تابع استفاده کنید. اگر سعی کنید مقدار را مستقیماً اختصاص دهید، ممکن است پیام ها بارگیری نشوند و به جای آن مقدار undefined
دریافت خواهید کرد.
const collapseTemplate = {
// ...
displayText: () => Blockly.Msg['MY_COLLAPSE_BLOCK_TEXT'],
// ...
};
اگر از یک تابع استفاده می کنید، یک مقدار Scope
نیز به آن ارسال می شود. می توانید از این برای اضافه کردن اطلاعات مربوط به عنصر به متن نمایشگر خود استفاده کنید.
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 '';
},
// ...
}
وزن
weight
ترتیب نمایش آیتم های منوی زمینه را تعیین می کند. مقادیر مثبت بیشتر نسبت به مقادیر کمتر مثبت کمتر در لیست نمایش داده می شود. (شما می توانید تصور کنید که اقلام با وزن بالاتر "سنگین تر" هستند بنابراین به پایین فرو می روند.)
const collapseTemplate = {
// ...
weight: 10,
// ...
}
وزن آیتم های منوی زمینه داخلی به ترتیب افزایش می یابد که از 1 شروع می شود و به 1 افزایش می یابد.
عملکرد برگشت به تماس
ویژگی callback
تابعی است که عملکرد آیتم منوی زمینه شما را انجام می دهد. چندین پارامتر به آن منتقل می شود:
-
scope
: یک شیScope
که ارجاع به مؤلفه ای را ارائه می دهد که منوی آن باز شده است. -
menuOpenEvent
:Event
که باعث باز شدن منوی زمینه شد. این ممکن است یکPointerEvent
یاKeyboardEvent
باشد، بسته به اینکه کاربر چگونه منو را باز کرده است. -
menuSelectEvent
:Event
که این آیتم منوی زمینه خاص را از منو انتخاب کرده است. این ممکن است یکPointerEvent
یاKeyboardEvent
باشد، بسته به اینکه کاربر چگونه مورد را انتخاب کرده است. -
location
:Coordinate
پیکسل در جایی که منو باز شد. این به شما امکان می دهد، برای مثال، یک بلوک جدید در محل کلیک ایجاد کنید.
const collapseTemplate = {
// ...
callback: (scope, menuOpenEvent, menuSelectEvent, location) => {
if (scope.focusedNode instanceof Blockly.BlockSvg) {
scope.focusedNode.collapse();
}
},
}
میتوانید از scope
برای طراحی قالبهایی استفاده کنید که بسته به مؤلفهای که روی آن باز شدهاند، متفاوت عمل میکنند:
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);
}
}
}
جداکننده
ویژگی separator
یک خط در منوی زمینه ترسیم می کند.
الگوهای دارای ویژگی separator
نمیتوانند ویژگیهای preconditionFn
، displayText
یا callback
داشته باشند و فقط میتوانند با ویژگی scopeType
محدودهبندی شوند. محدودیت اخیر به این معنی است که آنها فقط می توانند در منوهای زمینه برای فضاهای کاری، بلوک ها و نظرات فضای کاری استفاده شوند.
const separatorAfterCollapseBlockTemplate = {
id: 'separatorAfterCollapseBlock',
scopeType: Blockly.ContextMenuRegistry.ScopeType.BLOCK,
weight: 11, // Between the weights of the two items you want to separate.
separator: true,
};
برای هر جداکننده در منوی زمینه خود به یک الگوی متفاوت نیاز دارید. از ویژگی weight
برای قرار دادن هر جداکننده استفاده کنید.
نوع محدوده
ویژگی scopeType
منسوخ شده است. قبلاً، برای تعیین اینکه آیا یک آیتم منو باید در یک منوی زمینه برای یک بلوک، یک نظر فضای کاری یا یک فضای کاری نشان داده شود، استفاده می شد. از آنجایی که منوهای زمینه را می توان روی سایر مؤلفه ها باز کرد، ویژگی scopeType
بسیار محدود است. در عوض، باید از preconditionFn
برای نمایش یا پنهان کردن گزینه خود برای اجزای مربوطه استفاده کنید.
اگر قالبهای منوی زمینه موجود دارید که scopeType
استفاده میکنند، Blockly همچنان مورد را فقط برای مؤلفه مناسب نشان میدهد.
const collapseTemplate = {
// ...
scopeType: Blockly.ContextMenuRegistry.ScopeType.BLOCK,
// ...
};
رجیستری را سفارشی کنید
می توانید قالب هایی را در رجیستری اضافه، حذف یا تغییر دهید. می توانید الگوهای پیش فرض را در contextmenu_items.ts
بیابید.
یک الگو اضافه کنید
می توانید با ثبت یک الگو به رجیستری اضافه کنید. شما باید این کار را یک بار در بارگذاری صفحه انجام دهید. ممکن است قبل یا بعد از تزریق محل کارتان اتفاق بیفتد.
const collapseTemplate = { /* properties from above */ };
Blockly.ContextMenuRegistry.registry.register(collapseTemplate);
یک الگو را حذف کنید
با لغو ثبت آن توسط ID می توانید یک الگو را از رجیستری حذف کنید.
Blockly.ContextMenuRegistry.registry.unregister('someID');
یک الگو را اصلاح کنید
می توانید با دریافت الگو از رجیستری و سپس اصلاح آن در محل، یک الگوی موجود را تغییر دهید.
const template = Blockly.ContextMenuRegistry.registry.getItem('someID');
template?.displayText = 'some other display text';
منوهای زمینه بلوک را غیرفعال کنید
بهطور پیشفرض، بلوکها دارای یک منوی زمینه هستند که به کاربران اجازه میدهد کارهایی مانند افزودن نظرات بلوک یا بلوکهای تکراری را انجام دهند.
با انجام زیر می توانید منوی زمینه یک بلوک را غیرفعال کنید:
block.contextMenu = false;
در تعریف JSON از نوع بلوک، از کلید enableContextMenu
استفاده کنید:
{
// ...,
"enableContextMenu": false,
}
منوهای زمینه را در هر نوع بلوک یا فضای کاری سفارشی کنید
پس از اینکه Blockly آرایه ای از آیتم های منوی زمینه را ایجاد کرد ، می توانید آن را برای بلوک ها یا فضاهای کاری جداگانه سفارشی کنید. برای انجام این کار، BlockSvg.customContextMenu
یا WorkspaceSvg.configureContextMenu
را روی تابعی تنظیم کنید که آرایه را در جای خود تغییر می دهد.
اشیاء موجود در آرایه ارسال شده به بلوک ها دارای نوع ContextMenuOption
یا پیاده سازی رابط LegacyContextMenuOption
هستند. اشیاء ارسال شده به فضاهای کاری دارای نوع ContextMenuOption
هستند. Blockly از ویژگی های زیر از این اشیا استفاده می کند:
-
text
: متن نمایش داده می شود. -
enabled
: اگرfalse
، مورد را با متن خاکستری نمایش دهید. -
callback
: تابعی که باید هنگام کلیک روی مورد فراخوانی شود. -
separator
: مورد یک جداکننده است. متقابل با سه ویژگی دیگر.
به اسناد مرجع برای انواع اموال و امضاهای عملکرد مراجعه کنید.
به عنوان مثال، در اینجا یک تابع است که یک Hello, World!
مورد در منوی زمینه یک فضای کاری:
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);
}
یک منوی زمینه را روی یک شی سفارشی نشان دهید
با دنبال کردن این مراحل میتوانید منوهای زمینه را برای اجزای سفارشی ظاهر کنید:
- پیاده سازی
IFocusableNode
یا گسترش کلاسی کهIFocusableNode
را پیاده سازی می کند. این رابط در سیستم منوی زمینه برای شناسایی جزء شما استفاده می شود. همچنین به کاربران اجازه می دهد تا با استفاده از افزونه پیمایش صفحه کلید به مؤلفه شما حرکت کنند. IContextMenu
که حاوی تابعshowContextMenu
است پیاده سازی کنید. این تابع آیتم های منوی زمینه را از رجیستری دریافت می کند، مکان نمایش منو را بر روی صفحه محاسبه می کند و در نهایت اگر مواردی برای نمایش وجود دارد، منو را نشان می دهد.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); } }
یک کنترل کننده رویداد اضافه کنید که وقتی کاربر روی مؤلفه شما راست کلیک می کند
showContextMenu
را فراخوانی می کند. توجه داشته باشید که پلاگین پیمایش صفحه کلید یک کنترل کننده رویداد ارائه می دهد که وقتی کاربرCtrl+Enter
(ویندوز) یاCommand+Enter
(Mac) را فشار می دهدshowContextMenu
را فراخوانی می کند.الگوهایی را برای آیتم های منوی زمینه خود به رجیستری اضافه کنید .