mirror of
https://github.com/microsoft/vscode.git
synced 2026-07-09 20:37:13 -05:00
Implement #30120
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
'use strict';
|
||||
|
||||
import 'vs/css!./media/explorerviewlet';
|
||||
import { localize } from 'vs/nls';
|
||||
import { IActionRunner } from 'vs/base/common/actions';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
@@ -93,7 +94,8 @@ export class ExplorerViewlet extends ComposedViewsViewlet {
|
||||
location: ViewLocation.Explorer,
|
||||
ctor: OpenEditorsView,
|
||||
order: 0,
|
||||
when: OpenEditorsVisibleCondition
|
||||
when: OpenEditorsVisibleCondition,
|
||||
canToggleVisibility: true
|
||||
};
|
||||
}
|
||||
|
||||
@@ -103,17 +105,19 @@ export class ExplorerViewlet extends ComposedViewsViewlet {
|
||||
name: EmptyView.NAME,
|
||||
location: ViewLocation.Explorer,
|
||||
ctor: EmptyView,
|
||||
order: 1
|
||||
order: 1,
|
||||
canToggleVisibility: true
|
||||
};
|
||||
}
|
||||
|
||||
private createExplorerViewDescriptor(): IViewDescriptor {
|
||||
return {
|
||||
id: ExplorerView.ID,
|
||||
name: this.contextService.getWorkspace().name,
|
||||
name: localize('folders', "Folders"),
|
||||
location: ViewLocation.Explorer,
|
||||
ctor: ExplorerView,
|
||||
order: 1
|
||||
order: 1,
|
||||
canToggleVisibility: true
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -314,6 +314,9 @@ class TreeController extends DefaultController {
|
||||
}
|
||||
|
||||
public onContextMenu(tree: ITree, node: ITreeItem, event: ContextMenuEvent): boolean {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
tree.setFocus(node);
|
||||
const actions = this.menus.getResourceContextActions(node);
|
||||
if (!actions.length) {
|
||||
|
||||
@@ -12,7 +12,7 @@ import { $, Dimension, Builder } from 'vs/base/browser/builder';
|
||||
import { Scope } from 'vs/workbench/common/memento';
|
||||
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IAction, IActionRunner } from 'vs/base/common/actions';
|
||||
import { IActionItem, ActionsOrientation, Separator } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { IActionItem, ActionsOrientation } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { prepareActions } from 'vs/workbench/browser/actions';
|
||||
import { Viewlet, ViewletRegistry, Extensions } from 'vs/workbench/browser/viewlet';
|
||||
@@ -58,6 +58,8 @@ export interface IView extends IBaseView, IThemable {
|
||||
|
||||
name: string;
|
||||
|
||||
getHeaderElement(): HTMLElement;
|
||||
|
||||
create(): TPromise<void>;
|
||||
|
||||
setVisible(visible: boolean): TPromise<void>;
|
||||
@@ -141,6 +143,10 @@ export abstract class CollapsibleView extends AbstractCollapsibleView implements
|
||||
return TPromise.as(null);
|
||||
}
|
||||
|
||||
getHeaderElement(): HTMLElement {
|
||||
return this.header;
|
||||
}
|
||||
|
||||
public renderHeader(container: HTMLElement): void {
|
||||
|
||||
// Tool bar
|
||||
@@ -306,6 +312,7 @@ export class ComposedViewsViewlet extends Viewlet {
|
||||
|
||||
private splitView: SplitView;
|
||||
protected views: IView[];
|
||||
private viewHeaderContextMenuListeners: IDisposable[] = [];
|
||||
private dimension: Dimension;
|
||||
private viewletSettings: object;
|
||||
|
||||
@@ -348,7 +355,6 @@ export class ComposedViewsViewlet extends Viewlet {
|
||||
this.viewletContainer = DOM.append(parent.getHTMLElement(), DOM.$(''));
|
||||
this.splitView = this._register(new SplitView(this.viewletContainer));
|
||||
this._register(this.splitView.onFocus((view: IView) => this.lastFocusedView = view));
|
||||
this._register(DOM.addDisposableListener(this.viewletContainer, 'contextmenu', e => this.onContextMenu(new StandardMouseEvent(e))));
|
||||
|
||||
return this.onViewDescriptorsChanged()
|
||||
.then(() => {
|
||||
@@ -373,18 +379,20 @@ export class ComposedViewsViewlet extends Viewlet {
|
||||
}
|
||||
|
||||
public getSecondaryActions(): IAction[] {
|
||||
let actions = [];
|
||||
if (this.hasSingleView() && this.views[0]) {
|
||||
actions = this.views[0].getSecondaryActions();
|
||||
return this.views[0].getSecondaryActions();
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
if (actions.length) {
|
||||
actions.push(new Separator());
|
||||
}
|
||||
|
||||
actions.push(...this.getToggleVisibilityActions(this.getViewDescriptorsFromRegistry()));
|
||||
|
||||
return actions;
|
||||
public getContextMenuActions(): IAction[] {
|
||||
return this.getVisibilityManageableViewDescriptors().map(viewDescriptor => (<IAction>{
|
||||
id: `${viewDescriptor.id}.toggleVisibility`,
|
||||
label: viewDescriptor.name,
|
||||
checked: this.isCurrentlyVisible(viewDescriptor),
|
||||
enabled: this.contextKeyService.contextMatchesRules(viewDescriptor.when),
|
||||
run: () => this.toggleViewVisibility(viewDescriptor.id)
|
||||
}));
|
||||
}
|
||||
|
||||
public setVisible(visible: boolean): TPromise<void> {
|
||||
@@ -428,28 +436,9 @@ export class ComposedViewsViewlet extends Viewlet {
|
||||
}
|
||||
}
|
||||
|
||||
private onContextMenu(event: StandardMouseEvent): void {
|
||||
let anchor: { x: number, y: number } = { x: event.posx, y: event.posy };
|
||||
this.contextMenuService.showContextMenu({
|
||||
getAnchor: () => anchor,
|
||||
getActions: () => TPromise.as(this.getSecondaryActions()),
|
||||
});
|
||||
}
|
||||
|
||||
private getToggleVisibilityActions(viewDescriptors: IViewDescriptor[]): IAction[] {
|
||||
// return viewDescriptors.map(viewDescriptor => (<IAction>{
|
||||
// id: `${viewDescriptor.id}.toggleVisibility`,
|
||||
// label: viewDescriptor.name,
|
||||
// checked: this.isCurrentlyVisible(viewDescriptor),
|
||||
// enabled: this.contextKeyService.contextMatchesRules(viewDescriptor.when),
|
||||
// run: () => this.toggleViewVisibility(viewDescriptor)
|
||||
// }));
|
||||
return [];
|
||||
}
|
||||
|
||||
protected toggleViewVisibility(viewDescriptor: IViewDescriptor): void {
|
||||
const view = this.getView(viewDescriptor.id);
|
||||
let viewState = this.viewsStates.get(viewDescriptor.id);
|
||||
private toggleViewVisibility(id: string): void {
|
||||
const view = this.getView(id);
|
||||
let viewState = this.viewsStates.get(id);
|
||||
if (view) {
|
||||
viewState = viewState || this.createViewState(view);
|
||||
viewState.isHidden = true;
|
||||
@@ -457,7 +446,7 @@ export class ComposedViewsViewlet extends Viewlet {
|
||||
viewState = viewState || { collapsed: true, size: void 0, isHidden: false };
|
||||
viewState.isHidden = false;
|
||||
}
|
||||
this.viewsStates.set(viewDescriptor.id, viewState);
|
||||
this.viewsStates.set(id, viewState);
|
||||
this.updateViews();
|
||||
}
|
||||
|
||||
@@ -602,6 +591,14 @@ export class ComposedViewsViewlet extends Viewlet {
|
||||
// Update title area since the title actions have changed.
|
||||
this.updateTitleArea();
|
||||
|
||||
this.viewHeaderContextMenuListeners = dispose(this.viewHeaderContextMenuListeners);
|
||||
for (const viewDescriptor of this.getVisibilityManageableViewDescriptors()) {
|
||||
const view = this.getView(viewDescriptor.id);
|
||||
if (view) {
|
||||
this.viewHeaderContextMenuListeners.push(DOM.addDisposableListener(view.getHeaderElement(), DOM.EventType.CONTEXT_MENU, (e) => this.onContextMenu(new StandardMouseEvent(e), view)));
|
||||
}
|
||||
}
|
||||
|
||||
if (this.dimension) {
|
||||
this.layoutViews();
|
||||
}
|
||||
@@ -609,6 +606,22 @@ export class ComposedViewsViewlet extends Viewlet {
|
||||
return this.setVisible(this.isVisible());
|
||||
}
|
||||
|
||||
private onContextMenu(event: StandardMouseEvent, view: IView): void {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
let anchor: { x: number, y: number } = { x: event.posx, y: event.posy };
|
||||
this.contextMenuService.showContextMenu({
|
||||
getAnchor: () => anchor,
|
||||
getActions: () => TPromise.as([{
|
||||
id: `${view.id}.removeView`,
|
||||
label: nls.localize('removeView', "Remove from {0}", this.getTitle()),
|
||||
enabled: true,
|
||||
run: () => this.toggleViewVisibility(view.id)
|
||||
}]),
|
||||
});
|
||||
}
|
||||
|
||||
private hasSingleView(): boolean {
|
||||
if (this.views.length > 1) {
|
||||
return false;
|
||||
@@ -620,6 +633,10 @@ export class ComposedViewsViewlet extends Viewlet {
|
||||
return true;
|
||||
}
|
||||
|
||||
private getVisibilityManageableViewDescriptors(): IViewDescriptor[] {
|
||||
return this.getViewDescriptorsFromRegistry().filter(viewDescriptor => viewDescriptor.canToggleVisibility);
|
||||
}
|
||||
|
||||
private getViewDescriptorsFromRegistry(): IViewDescriptor[] {
|
||||
return ViewsRegistry.getViews(this.location)
|
||||
.sort((a, b) => {
|
||||
|
||||
@@ -8,7 +8,7 @@ import { localize } from 'vs/nls';
|
||||
import { forEach } from 'vs/base/common/collections';
|
||||
import { IJSONSchema } from 'vs/base/common/jsonSchema';
|
||||
import { ExtensionMessageCollector, ExtensionsRegistry } from 'vs/platform/extensions/common/extensionsRegistry';
|
||||
import { ViewLocation, ViewsRegistry } from 'vs/workbench/parts/views/browser/viewsRegistry';
|
||||
import { ViewLocation, ViewsRegistry, IViewDescriptor } from 'vs/workbench/parts/views/browser/viewsRegistry';
|
||||
import { TreeView } from 'vs/workbench/parts/views/browser/treeView';
|
||||
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
|
||||
@@ -92,12 +92,13 @@ ExtensionsRegistry.registerExtensionPoint<{ [loc: string]: schema.IUserFriendlyV
|
||||
return;
|
||||
}
|
||||
|
||||
const viewDescriptors = entry.value.map(item => ({
|
||||
const viewDescriptors = entry.value.map(item => (<IViewDescriptor>{
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
ctor: TreeView,
|
||||
location,
|
||||
when: ContextKeyExpr.deserialize(item.when)
|
||||
when: ContextKeyExpr.deserialize(item.when),
|
||||
canToggleVisibility: true
|
||||
}));
|
||||
ViewsRegistry.registerViews(viewDescriptors);
|
||||
});
|
||||
|
||||
@@ -44,6 +44,8 @@ export interface IViewDescriptor {
|
||||
readonly order?: number;
|
||||
|
||||
readonly size?: number;
|
||||
|
||||
readonly canToggleVisibility?: boolean;
|
||||
}
|
||||
|
||||
export interface IViewsRegistry {
|
||||
|
||||
Reference in New Issue
Block a user