Merge from master

This commit is contained in:
Raj Musuku
2019-02-21 17:56:04 -08:00
parent 5a146e34fa
commit 666ae11639
11482 changed files with 119352 additions and 255574 deletions

View 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';

View File

@@ -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;
}

View 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;
}