mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-03-26 23:00:29 -04:00
Merge from master
This commit is contained in:
43
src/vs/base/parts/contextmenu/common/contextmenu.ts
Normal file
43
src/vs/base/parts/contextmenu/common/contextmenu.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
export interface ICommonContextMenuItem {
|
||||
label?: string;
|
||||
|
||||
type?: 'normal' | 'separator' | 'submenu' | 'checkbox' | 'radio';
|
||||
|
||||
accelerator?: string;
|
||||
|
||||
enabled?: boolean;
|
||||
visible?: boolean;
|
||||
checked?: boolean;
|
||||
}
|
||||
|
||||
export interface ISerializableContextMenuItem extends ICommonContextMenuItem {
|
||||
id: number;
|
||||
submenu?: ISerializableContextMenuItem[];
|
||||
}
|
||||
|
||||
export interface IContextMenuItem extends ICommonContextMenuItem {
|
||||
click?: (event: IContextMenuEvent) => void;
|
||||
submenu?: IContextMenuItem[];
|
||||
}
|
||||
|
||||
export interface IContextMenuEvent {
|
||||
shiftKey?: boolean;
|
||||
ctrlKey?: boolean;
|
||||
altKey?: boolean;
|
||||
metaKey?: boolean;
|
||||
}
|
||||
|
||||
export interface IPopupOptions {
|
||||
x?: number;
|
||||
y?: number;
|
||||
positioningItem?: number;
|
||||
onHide?: () => void;
|
||||
}
|
||||
|
||||
export const CONTEXT_MENU_CHANNEL = 'vscode:contextmenu';
|
||||
export const CONTEXT_MENU_CLOSE_CHANNEL = 'vscode:onCloseContextMenu';
|
||||
@@ -0,0 +1,58 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ipcRenderer, Event } from 'electron';
|
||||
import { IContextMenuItem, ISerializableContextMenuItem, CONTEXT_MENU_CLOSE_CHANNEL, CONTEXT_MENU_CHANNEL, IPopupOptions, IContextMenuEvent } from 'vs/base/parts/contextmenu/common/contextmenu';
|
||||
|
||||
let contextMenuIdPool = 0;
|
||||
|
||||
export function popup(items: IContextMenuItem[], options?: IPopupOptions): void {
|
||||
const processedItems: IContextMenuItem[] = [];
|
||||
|
||||
const contextMenuId = contextMenuIdPool++;
|
||||
const onClickChannel = `vscode:onContextMenu${contextMenuId}`;
|
||||
const onClickChannelHandler = (_event: Event, itemId: number, context: IContextMenuEvent) => {
|
||||
const item = processedItems[itemId];
|
||||
if (item.click) {
|
||||
item.click(context);
|
||||
}
|
||||
};
|
||||
|
||||
ipcRenderer.once(onClickChannel, onClickChannelHandler);
|
||||
ipcRenderer.once(CONTEXT_MENU_CLOSE_CHANNEL, (_event: Event, closedContextMenuId: number) => {
|
||||
if (closedContextMenuId !== contextMenuId) {
|
||||
return;
|
||||
}
|
||||
|
||||
ipcRenderer.removeListener(onClickChannel, onClickChannelHandler);
|
||||
|
||||
if (options && options.onHide) {
|
||||
options.onHide();
|
||||
}
|
||||
});
|
||||
|
||||
ipcRenderer.send(CONTEXT_MENU_CHANNEL, contextMenuId, items.map(item => createItem(item, processedItems)), onClickChannel, options);
|
||||
}
|
||||
|
||||
function createItem(item: IContextMenuItem, processedItems: IContextMenuItem[]): ISerializableContextMenuItem {
|
||||
const serializableItem = {
|
||||
id: processedItems.length,
|
||||
label: item.label,
|
||||
type: item.type,
|
||||
accelerator: item.accelerator,
|
||||
checked: item.checked,
|
||||
enabled: typeof item.enabled === 'boolean' ? item.enabled : true,
|
||||
visible: typeof item.visible === 'boolean' ? item.visible : true
|
||||
} as ISerializableContextMenuItem;
|
||||
|
||||
processedItems.push(item);
|
||||
|
||||
// Submenu
|
||||
if (Array.isArray(item.submenu)) {
|
||||
serializableItem.submenu = item.submenu.map(submenuItem => createItem(submenuItem, processedItems));
|
||||
}
|
||||
|
||||
return serializableItem;
|
||||
}
|
||||
63
src/vs/base/parts/contextmenu/electron-main/contextmenu.ts
Normal file
63
src/vs/base/parts/contextmenu/electron-main/contextmenu.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Menu, MenuItem, BrowserWindow, Event, ipcMain } from 'electron';
|
||||
import { ISerializableContextMenuItem, CONTEXT_MENU_CLOSE_CHANNEL, CONTEXT_MENU_CHANNEL, IPopupOptions } from 'vs/base/parts/contextmenu/common/contextmenu';
|
||||
|
||||
export function registerContextMenuListener(): void {
|
||||
ipcMain.on(CONTEXT_MENU_CHANNEL, (event: Event, contextMenuId: number, items: ISerializableContextMenuItem[], onClickChannel: string, options?: IPopupOptions) => {
|
||||
const menu = createMenu(event, onClickChannel, items);
|
||||
|
||||
menu.popup({
|
||||
window: BrowserWindow.fromWebContents(event.sender),
|
||||
x: options ? options.x : void 0,
|
||||
y: options ? options.y : void 0,
|
||||
positioningItem: options ? options.positioningItem : void 0,
|
||||
callback: () => {
|
||||
event.sender.send(CONTEXT_MENU_CLOSE_CHANNEL, contextMenuId);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function createMenu(event: Event, onClickChannel: string, items: ISerializableContextMenuItem[]): Menu {
|
||||
const menu = new Menu();
|
||||
|
||||
items.forEach(item => {
|
||||
let menuitem: MenuItem;
|
||||
|
||||
// Separator
|
||||
if (item.type === 'separator') {
|
||||
menuitem = new MenuItem({
|
||||
type: item.type,
|
||||
});
|
||||
}
|
||||
|
||||
// Sub Menu
|
||||
else if (Array.isArray(item.submenu)) {
|
||||
menuitem = new MenuItem({
|
||||
submenu: createMenu(event, onClickChannel, item.submenu),
|
||||
label: item.label
|
||||
});
|
||||
}
|
||||
|
||||
// Normal Menu Item
|
||||
else {
|
||||
menuitem = new MenuItem({
|
||||
label: item.label,
|
||||
type: item.type,
|
||||
accelerator: item.accelerator,
|
||||
checked: item.checked,
|
||||
enabled: item.enabled,
|
||||
visible: item.visible,
|
||||
click: (menuItem, win, contextmenuEvent) => event.sender.send(onClickChannel, item.id, contextmenuEvent)
|
||||
});
|
||||
}
|
||||
|
||||
menu.append(menuitem);
|
||||
});
|
||||
|
||||
return menu;
|
||||
}
|
||||
Reference in New Issue
Block a user