This commit is contained in:
Benjamin Pasero
2018-09-17 18:48:50 +02:00
parent 99217cbf12
commit 3bc654bf13
11 changed files with 60 additions and 61 deletions
+2 -2
View File
@@ -246,8 +246,8 @@ export class DropdownMenu extends BaseDropdown {
getAnchor: () => this.element,
getActions: () => TPromise.as(this.actions),
getActionsContext: () => this.menuOptions ? this.menuOptions.context : null,
getActionItem: (action) => this.menuOptions && this.menuOptions.actionItemProvider ? this.menuOptions.actionItemProvider(action) : null,
getKeyBinding: (action: IAction) => this.menuOptions && this.menuOptions.getKeyBinding ? this.menuOptions.getKeyBinding(action) : null,
getActionItem: action => this.menuOptions && this.menuOptions.actionItemProvider ? this.menuOptions.actionItemProvider(action) : null,
getKeyBinding: action => this.menuOptions && this.menuOptions.getKeyBinding ? this.menuOptions.getKeyBinding(action) : null,
getMenuClassName: () => this.menuClassName,
onHide: () => this.onHide(),
actionRunner: this.menuOptions ? this.menuOptions.actionRunner : null
@@ -184,11 +184,11 @@ export class DynamicStandaloneServices extends Disposable {
let commandService = ensure(ICommandService, () => new StandaloneCommandService(this._instantiationService));
ensure(IKeybindingService, () => this._register(new StandaloneKeybindingService(contextKeyService, commandService, telemetryService, notificationService, domElement)));
let keybindingService = ensure(IKeybindingService, () => this._register(new StandaloneKeybindingService(contextKeyService, commandService, telemetryService, notificationService, domElement)));
let contextViewService = ensure(IContextViewService, () => this._register(new ContextViewService(domElement, telemetryService, new NullLogService())));
ensure(IContextMenuService, () => this._register(new ContextMenuService(domElement, telemetryService, notificationService, contextViewService)));
ensure(IContextMenuService, () => this._register(new ContextMenuService(domElement, telemetryService, notificationService, contextViewService, keybindingService)));
ensure(IMenuService, () => new SimpleMenuService(commandService));
@@ -6,6 +6,7 @@
'use strict';
import 'vs/css!./contextMenuHandler';
import { combinedDisposable, IDisposable, dispose } from 'vs/base/common/lifecycle';
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
import { ActionRunner, IAction, IRunEvent } from 'vs/base/common/actions';
@@ -15,41 +16,38 @@ import { IContextViewService } from 'vs/platform/contextview/browser/contextView
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { IContextMenuDelegate } from 'vs/base/browser/contextmenu';
import { addDisposableListener } from 'vs/base/browser/dom';
import { addDisposableListener, EventType } from 'vs/base/browser/dom';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
export class ContextMenuHandler {
private contextViewService: IContextViewService;
private notificationService: INotificationService;
private telemetryService: ITelemetryService;
private element: HTMLElement;
private elementDisposable: IDisposable;
private menuContainerElement: HTMLElement;
private focusToReturn: HTMLElement;
constructor(element: HTMLElement, contextViewService: IContextViewService, telemetryService: ITelemetryService, notificationService: INotificationService) {
constructor(
element: HTMLElement,
private contextViewService: IContextViewService,
private telemetryService: ITelemetryService,
private notificationService: INotificationService,
private keybindingService: IKeybindingService
) {
this.setContainer(element);
this.contextViewService = contextViewService;
this.telemetryService = telemetryService;
this.notificationService = notificationService;
this.menuContainerElement = null;
}
public setContainer(container: HTMLElement): void {
setContainer(container: HTMLElement): void {
if (this.element) {
this.elementDisposable = dispose(this.elementDisposable);
this.element = null;
}
if (container) {
this.element = container;
this.elementDisposable = addDisposableListener(this.element, 'mousedown', (e) => this.onMouseDown(e as MouseEvent));
this.elementDisposable = addDisposableListener(this.element, EventType.MOUSE_DOWN, (e) => this.onMouseDown(e as MouseEvent));
}
}
public showContextMenu(delegate: IContextMenuDelegate): void {
showContextMenu(delegate: IContextMenuDelegate): void {
delegate.getActions().then((actions: IAction[]) => {
if (!actions.length) {
return; // Don't render an empty context menu
@@ -80,7 +78,7 @@ export class ContextMenuHandler {
actionItemProvider: delegate.getActionItem,
context: delegate.getActionsContext ? delegate.getActionsContext() : null,
actionRunner,
getKeyBinding: delegate.getKeyBinding
getKeyBinding: delegate.getKeyBinding ? delegate.getKeyBinding : action => this.keybindingService.lookupKeybinding(action.id)
});
menu.onDidCancel(() => this.contextViewService.hideContextView(true), null, menuDisposables);
@@ -146,7 +144,7 @@ export class ContextMenuHandler {
this.contextViewService.hideContextView();
}
public dispose(): void {
dispose(): void {
this.setContainer(null);
}
}
@@ -10,34 +10,41 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { Event, Emitter } from 'vs/base/common/event';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { IContextMenuDelegate } from 'vs/base/browser/contextmenu';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { Disposable } from 'vs/base/common/lifecycle';
export class ContextMenuService extends Disposable implements IContextMenuService {
_serviceBrand: any;
export class ContextMenuService implements IContextMenuService {
public _serviceBrand: any;
private _onDidContextMenu = this._register(new Emitter<void>());
get onDidContextMenu(): Event<void> { return this._onDidContextMenu.event; }
private contextMenuHandler: ContextMenuHandler;
private _onDidContextMenu = new Emitter<void>();
constructor(container: HTMLElement, telemetryService: ITelemetryService, notificationService: INotificationService, contextViewService: IContextViewService) {
this.contextMenuHandler = new ContextMenuHandler(container, contextViewService, telemetryService, notificationService);
constructor(
container: HTMLElement,
@ITelemetryService telemetryService: ITelemetryService,
@INotificationService notificationService: INotificationService,
@IContextViewService contextViewService: IContextViewService,
@IKeybindingService keybindingService: IKeybindingService
) {
super();
this.contextMenuHandler = this._register(new ContextMenuHandler(container, contextViewService, telemetryService, notificationService, keybindingService));
}
public dispose(): void {
dispose(): void {
this.contextMenuHandler.dispose();
}
public setContainer(container: HTMLElement): void {
setContainer(container: HTMLElement): void {
this.contextMenuHandler.setContainer(container);
}
// ContextMenu
public showContextMenu(delegate: IContextMenuDelegate): void {
showContextMenu(delegate: IContextMenuDelegate): void {
this.contextMenuHandler.showContextMenu(delegate);
this._onDidContextMenu.fire();
}
public get onDidContextMenu(): Event<void> {
return this._onDidContextMenu.event;
}
}
@@ -12,16 +12,20 @@ import { IContextMenuDelegate } from 'vs/base/browser/contextmenu';
export const IContextViewService = createDecorator<IContextViewService>('contextViewService');
export interface IContextViewService {
_serviceBrand: any;
showContextView(delegate: IContextViewDelegate): void;
hideContextView(data?: any): void;
layout(): void;
}
export interface IContextViewDelegate {
canRelayout?: boolean; // Default: true
getAnchor(): HTMLElement | { x: number; y: number; };
render(container: HTMLElement): IDisposable;
canRelayout?: boolean; // Default: true
onDOMEvent?(e: any, activeElement: HTMLElement): void;
onHide?(data?: any): void;
}
@@ -29,8 +33,9 @@ export interface IContextViewDelegate {
export const IContextMenuService = createDecorator<IContextMenuService>('contextMenuService');
export interface IContextMenuService {
_serviceBrand: any;
showContextMenu(delegate: IContextMenuDelegate): void;
// TODO@isidor these event should be removed once we get async context menus
onDidContextMenu: Event<void>;
onDidContextMenu: Event<void>; // TODO@isidor these event should be removed once we get async context menus
}
@@ -8,9 +8,10 @@ import { IContextViewService, IContextViewDelegate } from './contextView';
import { ContextView } from 'vs/base/browser/ui/contextview/contextview';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { ILogService } from 'vs/platform/log/common/log';
import { Disposable } from 'vs/base/common/lifecycle';
export class ContextViewService implements IContextViewService {
public _serviceBrand: any;
export class ContextViewService extends Disposable implements IContextViewService {
_serviceBrand: any;
private contextView: ContextView;
@@ -19,30 +20,28 @@ export class ContextViewService implements IContextViewService {
@ITelemetryService telemetryService: ITelemetryService,
@ILogService private logService: ILogService
) {
this.contextView = new ContextView(container);
}
super();
public dispose(): void {
this.contextView.dispose();
this.contextView = this._register(new ContextView(container));
}
// ContextView
public setContainer(container: HTMLElement): void {
setContainer(container: HTMLElement): void {
this.logService.trace('ContextViewService#setContainer');
this.contextView.setContainer(container);
}
public showContextView(delegate: IContextViewDelegate): void {
showContextView(delegate: IContextViewDelegate): void {
this.logService.trace('ContextViewService#showContextView');
this.contextView.show(delegate);
}
public layout(): void {
layout(): void {
this.contextView.layout();
}
public hideContextView(data?: any): void {
hideContextView(data?: any): void {
this.logService.trace('ContextViewService#hideContextView');
this.contextView.hide(data);
}
@@ -309,7 +309,6 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
this.contextMenuService.showContextMenu({
getAnchor: () => anchor,
getActions: () => TPromise.as(actions),
getKeyBinding: action => this.keybindingService.lookupKeybinding(action.id),
onHide: () => this.focus()
});
}
@@ -318,7 +318,7 @@ export abstract class TitleControl extends Themable {
});
}
protected getKeybinding(action: IAction): ResolvedKeybinding {
private getKeybinding(action: IAction): ResolvedKeybinding {
return this.keybindingService.lookupKeybinding(action.id);
}
@@ -152,8 +152,7 @@ export class SidebarPart extends CompositePart<Viewlet> {
getAnchor: () => anchor,
getActions: () => TPromise.as(contextMenuActions),
getActionItem: action => this.actionItemProvider(action as Action),
actionRunner: activeViewlet.getActionRunner(),
getKeyBinding: action => this.keybindingService.lookupKeybinding(action.id)
actionRunner: activeViewlet.getActionRunner()
});
}
}
@@ -112,8 +112,6 @@ import { IEditorGroupsService, GroupDirection, preferredSideBySideGroupDirection
import { EditorService } from 'vs/workbench/services/editor/browser/editorService';
import { IExtensionUrlHandler, ExtensionUrlHandler } from 'vs/workbench/services/extensions/electron-browser/inactiveExtensionUrlHandler';
import { ContextViewService } from 'vs/platform/contextview/browser/contextViewService';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { TelemetryService } from 'vs/platform/telemetry/common/telemetryService';
import { WorkbenchThemeService } from 'vs/workbench/services/themes/electron-browser/workbenchThemeService';
import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
import { LabelService, ILabelService } from 'vs/platform/label/common/label';
@@ -246,8 +244,7 @@ export class Workbench extends Disposable implements IPartService {
@IWorkbenchThemeService private themeService: WorkbenchThemeService,
@IEnvironmentService private environmentService: IEnvironmentService,
@IWindowService private windowService: IWindowService,
@INotificationService private notificationService: NotificationService,
@ITelemetryService private telemetryService: TelemetryService
@INotificationService private notificationService: NotificationService
) {
super();
@@ -364,7 +361,7 @@ export class Workbench extends Disposable implements IPartService {
// Use themable context menus when custom titlebar is enabled to match custom menubar
if (!isMacintosh && this.getCustomTitleBarStyle() === 'custom') {
serviceCollection.set(IContextMenuService, new SyncDescriptor(HTMLContextMenuService, null, this.telemetryService, this.notificationService, this.contextViewService));
serviceCollection.set(IContextMenuService, new SyncDescriptor(HTMLContextMenuService));
} else {
serviceCollection.set(IContextMenuService, new SyncDescriptor(NativeContextMenuService));
}
@@ -56,7 +56,6 @@ import { IDialogService, IConfirmationResult, IConfirmation, getConfirmMessage }
import { INotificationService } from 'vs/platform/notification/common/notification';
import { IEditorService, SIDE_GROUP, ACTIVE_GROUP } from 'vs/workbench/services/editor/common/editorService';
import { fillInContextMenuActions } from 'vs/platform/actions/browser/menuItemActionItem';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
export class FileDataSource implements IDataSource {
constructor(
@@ -408,7 +407,6 @@ export class FileController extends WorkbenchTreeController implements IDisposab
@IMenuService private menuService: IMenuService,
@IContextKeyService contextKeyService: IContextKeyService,
@IClipboardService private clipboardService: IClipboardService,
@IKeybindingService private keybindingService: IKeybindingService,
@IConfigurationService configurationService: IConfigurationService
) {
super({ clickBehavior: ClickBehavior.ON_MOUSE_UP /* do not change to not break DND */ }, configurationService);
@@ -541,9 +539,6 @@ export class FileController extends WorkbenchTreeController implements IDisposab
tree.domFocus();
}
},
getKeyBinding: (action) => {
return this.keybindingService.lookupKeybinding(action.id);
},
getActionsContext: () => selection && selection.indexOf(stat) >= 0
? selection.map((fs: ExplorerItem) => fs.resource)
: stat instanceof ExplorerItem ? [stat.resource] : []