提交 43e00376 编写于 作者: S Sandeep Somavarapu

#14379 ExtensionsView: Move secondary actions to context menu

上级 bdd1a312
......@@ -11,7 +11,7 @@ import * as DOM from 'vs/base/browser/dom';
import severity from 'vs/base/common/severity';
import paths = require('vs/base/common/paths');
import Event from 'vs/base/common/event';
import { ActionItem, IActionItem } from 'vs/base/browser/ui/actionbar/actionbar';
import { ActionItem, IActionItem, Separator } from 'vs/base/browser/ui/actionbar/actionbar';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { ReloadWindowAction } from 'vs/workbench/electron-browser/actions';
......@@ -282,7 +282,7 @@ export class DropDownMenuActionItem extends ActionItem {
private disposables: IDisposable[] = [];
private _extension: IExtension;
constructor(action: IAction, private menuActions: IExtensionAction[], private contextMenuService: IContextMenuService) {
constructor(action: IAction, private menuActions: IAction[], private contextMenuService: IContextMenuService) {
super(null, action, { icon: true, label: true });
this.disposables = [...menuActions];
}
......@@ -292,16 +292,19 @@ export class DropDownMenuActionItem extends ActionItem {
set extension(extension: IExtension) {
this._extension = extension;
for (const menuAction of this.menuActions) {
menuAction.extension = extension;
if (!(menuAction instanceof Separator)) {
(<IExtensionAction>menuAction).extension = extension;
}
}
}
public showMenu(): void {
const actions = this.menuActions.filter(a => a instanceof Separator || a.enabled);
let elementPosition = DOM.getDomNodePagePosition(this.builder.getHTMLElement());
const anchor = { x: elementPosition.left, y: elementPosition.top + elementPosition.height + 10 };
this.contextMenuService.showContextMenu({
getAnchor: () => anchor,
getActions: () => TPromise.wrap(this.menuActions),
getActions: () => TPromise.wrap(actions)
});
}
......@@ -311,45 +314,130 @@ export class DropDownMenuActionItem extends ActionItem {
}
}
export class ManageExtensionActionItem extends DropDownMenuActionItem {
constructor(
action: IAction,
@IInstantiationService instantiationService: IInstantiationService,
@IContextMenuService contextMenuService: IContextMenuService) {
super(action, [instantiationService.createInstance(EnableForWorkspaceAction, localize('enableForWorkspaceAction.label', "Enable (Workspace)")), instantiationService.createInstance(EnableGloballyAction, localize('enableAlwaysAction.label', "Enable")),
instantiationService.createInstance(DisableForWorkspaceAction, localize('disableForWorkspaceAction.label', "Disable (Workspace)")), instantiationService.createInstance(DisableGloballyAction, localize('disableAlwaysAction.label', "Disable")), new Separator(), instantiationService.createInstance(UninstallAction)], contextMenuService);
}
}
export class ManageExtensionAction extends Action {
static ID = 'extensions.manage';
private static Class = 'extension-action manage';
private static NoExtensionClass = `${ManageExtensionAction.Class} no-extension`;
private _actionItem: EnableActionItem;
get actionItem(): IActionItem { return this._actionItem; }
private disposables: IDisposable[] = [];
private _extension: IExtension;
get extension(): IExtension { return this._extension; }
set extension(extension: IExtension) { this._extension = extension; this._actionItem.extension = extension; this.update(); }
constructor(
@IWorkspaceContextService private workspaceContextService: IWorkspaceContextService,
@IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService,
@IExtensionsRuntimeService private extensionRuntimeService: IExtensionsRuntimeService,
@IInstantiationService private instantiationService: IInstantiationService
) {
super(ManageExtensionAction.ID);
this._actionItem = this.instantiationService.createInstance(ManageExtensionActionItem, this);
this.disposables.push(this._actionItem);
this.disposables.push(this.extensionsWorkbenchService.onChange(() => this.update()));
this.update();
}
private update(): void {
this.class = ManageExtensionAction.NoExtensionClass;
this.enabled = false;
if (this.extension) {
this.class = ManageExtensionAction.Class;
this.enabled = ExtensionState.Uninstalled !== this.extension.state;
}
}
public run(): TPromise<any> {
this._actionItem.showMenu();
return TPromise.wrap(null);
}
dispose(): void {
super.dispose();
this.disposables = dispose(this.disposables);
}
}
export class EnableForWorkspaceAction extends Action {
static ID = 'extensions.enableForWorkspace';
static LABEL = localize('enableForWorkspaceAction', "Workspace");
private disposables: IDisposable[] = [];
private _extension: IExtension;
get extension(): IExtension { return this._extension; }
set extension(extension: IExtension) { this._extension = extension; this.update(); }
constructor(
constructor(label: string,
@IWorkspaceContextService private workspaceContextService: IWorkspaceContextService,
@IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService,
@IExtensionsRuntimeService private extensionsRuntimeService: IExtensionsRuntimeService
@IExtensionsRuntimeService private extensionsRuntimeService: IExtensionsRuntimeService,
@IInstantiationService private instantiationService: IInstantiationService
) {
super('extensions.enableForWorkspace', localize('enableForWorkspaceAction', "Workspace"), '', !!workspaceContextService.getWorkspace());
super(EnableForWorkspaceAction.ID, label);
this.disposables.push(this.extensionsWorkbenchService.onChange(() => this.update()));
this.update();
}
private update(): void {
this.enabled = false;
if (this.extension && this.workspaceContextService.getWorkspace()) {
this.enabled = !this.extensionsRuntimeService.isDisabledAlways(this.extension.identifier);
this.enabled = ExtensionState.Disabled === this.extension.state && !this.extensionsRuntimeService.isDisabledAlways(this.extension.identifier);
}
}
run(): TPromise<any> {
return this.extensionsWorkbenchService.setEnablement(this.extension, true, true);
}
dispose(): void {
super.dispose();
this.disposables = dispose(this.disposables);
}
}
export class EnableGloballyAction extends Action {
static ID = 'extensions.enableGlobally';
static LABEL = localize('enableGloballyAction', "Always");
private disposables: IDisposable[] = [];
private _extension: IExtension;
get extension(): IExtension { return this._extension; }
set extension(extension: IExtension) { this._extension = extension; this.update(); }
constructor(
constructor(label: string,
@IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService,
@IExtensionsRuntimeService private extensionsRuntimeService: IExtensionsRuntimeService
@IExtensionsRuntimeService private extensionsRuntimeService: IExtensionsRuntimeService,
@IInstantiationService private instantiationService: IInstantiationService
) {
super('extensions.enableGlobally', localize('enableGloballyAction', "Always"), '', false);
super(EnableGloballyAction.ID, label);
this.disposables.push(this.extensionsWorkbenchService.onChange(() => this.update()));
this.update();
}
private update(): void {
this.enabled = false;
if (this.extension) {
this.enabled = this.extensionsRuntimeService.isDisabledAlways(this.extension.identifier);
}
......@@ -358,6 +446,11 @@ export class EnableGloballyAction extends Action {
run(): TPromise<any> {
return this.extensionsWorkbenchService.setEnablement(this.extension, true, false);
}
dispose(): void {
super.dispose();
this.disposables = dispose(this.disposables);
}
}
export class EnableAction extends Action {
......@@ -415,37 +508,79 @@ export class EnableAction extends Action {
export class DisableForWorkspaceAction extends Action {
static ID = 'extensions.disableForWorkspace';
static LABEL = localize('disableForWorkspaceAction', "Workspace");
private disposables: IDisposable[] = [];
private _extension: IExtension;
get extension(): IExtension { return this._extension; }
set extension(extension: IExtension) { this._extension = extension; }
set extension(extension: IExtension) { this._extension = extension; this.update(); }
constructor(
constructor(label: string,
@IWorkspaceContextService private workspaceContextService: IWorkspaceContextService,
@IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService
@IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService,
@IInstantiationService private instantiationService: IInstantiationService
) {
super('extensions.disableForWorkspace', localize('disableForWorkspaceAction', "Workspace"), '', !!workspaceContextService.getWorkspace());
super(DisableForWorkspaceAction.ID, label);
this.disposables.push(this.extensionsWorkbenchService.onChange(() => this.update()));
this.update();
}
private update(): void {
this.enabled = false;
if (this.extension && this.workspaceContextService.getWorkspace()) {
this.enabled = ExtensionState.Enabled === this.extension.state;
}
}
run(): TPromise<any> {
return this.extensionsWorkbenchService.setEnablement(this.extension, false, true);
}
dispose(): void {
super.dispose();
this.disposables = dispose(this.disposables);
}
}
export class DisableGloballyAction extends Action {
static ID = 'extensions.disableGlobally';
static LABEL = localize('disableGloballyAction', "Always");
private disposables: IDisposable[] = [];
private _extension: IExtension;
get extension(): IExtension { return this._extension; }
set extension(extension: IExtension) { this._extension = extension; }
set extension(extension: IExtension) { this._extension = extension; this.update(); }
constructor(
@IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService
constructor(label: string,
@IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService,
@IInstantiationService private instantiationService: IInstantiationService
) {
super('extensions.disableGlobally', localize('disableGloballyAction', "Always"), '', true);
super(DisableGloballyAction.ID, label);
this.disposables.push(this.extensionsWorkbenchService.onChange(() => this.update()));
this.update();
}
private update(): void {
this.enabled = false;
if (this.extension) {
this.enabled = ExtensionState.Enabled === this.extension.state;
}
}
run(): TPromise<any> {
return this.extensionsWorkbenchService.setEnablement(this.extension, false, false);
}
dispose(): void {
super.dispose();
this.disposables = dispose(this.disposables);
}
}
export class DisableAction extends Action {
......@@ -503,7 +638,7 @@ export class EnableActionItem extends DropDownMenuActionItem {
action: IAction,
@IInstantiationService instantiationService: IInstantiationService,
@IContextMenuService contextMenuService: IContextMenuService) {
super(action, [instantiationService.createInstance(EnableForWorkspaceAction), instantiationService.createInstance(EnableGloballyAction)], contextMenuService);
super(action, [instantiationService.createInstance(EnableForWorkspaceAction, EnableForWorkspaceAction.LABEL), instantiationService.createInstance(EnableGloballyAction, EnableGloballyAction.LABEL)], contextMenuService);
}
}
......@@ -512,7 +647,7 @@ export class DisableActionItem extends DropDownMenuActionItem {
action: IAction,
@IInstantiationService instantiationService: IInstantiationService,
@IContextMenuService contextMenuService: IContextMenuService) {
super(action, [instantiationService.createInstance(DisableForWorkspaceAction), instantiationService.createInstance(DisableGloballyAction)], contextMenuService);
super(action, [instantiationService.createInstance(DisableForWorkspaceAction, DisableForWorkspaceAction.LABEL), instantiationService.createInstance(DisableGloballyAction, DisableGloballyAction.LABEL)], contextMenuService);
}
}
......@@ -1118,4 +1253,4 @@ export class EnableAllWorkpsaceAction extends Action {
super.dispose();
this.disposables = dispose(this.disposables);
}
}
}
\ No newline at end of file
......@@ -16,9 +16,10 @@ import { IPagedRenderer } from 'vs/base/browser/ui/list/listPaging';
import { once } from 'vs/base/common/event';
import { domEvent } from 'vs/base/browser/event';
import { IExtension, ExtensionState } from '../common/extensions';
import { CombinedInstallAction, UpdateAction, EnableAction, DisableAction, BuiltinStatusLabelAction, ReloadAction } from './extensionsActions';
import { InstallAction, UpdateAction, BuiltinStatusLabelAction, ReloadAction, ManageExtensionAction } from './extensionsActions';
import { Label, RatingsWidget, InstallWidget } from './extensionsWidgets';
import { EventType } from 'vs/base/common/events';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
export interface ITemplateData {
element: HTMLElement;
......@@ -44,6 +45,7 @@ export class Renderer implements IPagedRenderer<IExtension, ITemplateData> {
constructor(
@IInstantiationService private instantiationService: IInstantiationService,
@IContextMenuService private contextMenuService: IContextMenuService,
@IMessageService private messageService: IMessageService
) { }
......@@ -65,16 +67,12 @@ export class Renderer implements IPagedRenderer<IExtension, ITemplateData> {
const actionbar = new ActionBar(footer, {
animated: false,
actionItemProvider: (action: Action) => {
if (action.id === EnableAction.ID) {
return (<EnableAction>action).actionItem;
}
if (action.id === DisableAction.ID) {
return (<DisableAction>action).actionItem;
if (action.id === ManageExtensionAction.ID) {
return (<ManageExtensionAction>action).actionItem;
}
return null;
}
});
actionbar.addListener2(EventType.RUN, ({ error }) => error && this.messageService.show(Severity.Error, error));
const versionWidget = this.instantiationService.createInstance(Label, version, e => e.version);
......@@ -82,14 +80,13 @@ export class Renderer implements IPagedRenderer<IExtension, ITemplateData> {
const ratingsWidget = this.instantiationService.createInstance(RatingsWidget, ratings, { small: true });
const builtinStatusAction = this.instantiationService.createInstance(BuiltinStatusLabelAction);
const combinedInstallAction = this.instantiationService.createInstance(CombinedInstallAction);
const installAction = this.instantiationService.createInstance(InstallAction);
const updateAction = this.instantiationService.createInstance(UpdateAction);
const enableAction = this.instantiationService.createInstance(EnableAction);
const disableAction = this.instantiationService.createInstance(DisableAction);
const reloadAction = this.instantiationService.createInstance(ReloadAction);
const manageAction = this.instantiationService.createInstance(ManageExtensionAction);
actionbar.push([enableAction, updateAction, disableAction, reloadAction, combinedInstallAction, builtinStatusAction], actionOptions);
const disposables = [versionWidget, installCountWidget, ratingsWidget, combinedInstallAction, builtinStatusAction, updateAction, enableAction, disableAction, reloadAction, actionbar];
actionbar.push([updateAction, reloadAction, installAction, builtinStatusAction, manageAction], actionOptions);
const disposables = [versionWidget, installCountWidget, ratingsWidget, builtinStatusAction, updateAction, reloadAction, manageAction, actionbar];
return {
element, icon, name, installCount, ratings, author, description, disposables,
......@@ -99,11 +96,10 @@ export class Renderer implements IPagedRenderer<IExtension, ITemplateData> {
installCountWidget.extension = extension;
ratingsWidget.extension = extension;
builtinStatusAction.extension = extension;
combinedInstallAction.extension = extension;
installAction.extension = extension;
updateAction.extension = extension;
enableAction.extension = extension;
disableAction.extension = extension;
reloadAction.extension = extension;
manageAction.extension = extension;
}
};
}
......
......@@ -104,4 +104,19 @@
.extension-editor > .header > .details > .actions > .monaco-action-bar .action-item .action-label.extension-action.built-in-status {
font-weight: normal;
}
.extensions-viewlet > .extensions .extension > .details > .footer > .monaco-action-bar .action-item .action-label.extension-action.manage.no-extension {
display: none;
}
.extensions-viewlet > .extensions .extension > .details > .footer > .monaco-action-bar .action-item .action-label.extension-action.manage {
height: 18px;
width: 10px;
border: none;
background: url('manage.svg') center center no-repeat;
}
.vs-dark .extensions-viewlet > .extensions .extension > .details > .footer > .monaco-action-bar .action-item .action-label.extension-action.manage {
background: url('manage-inverse.svg') center center no-repeat;
}
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><g fill="#C5C5C5"><path d="M12.714 9.603c-.07.207-.15.407-.246.601l1.017 2.139c-.335.424-.718.807-1.142 1.143l-2.14-1.018c-.193.097-.394.176-.601.247l-.795 2.235c-.265.03-.534.05-.807.05-.272 0-.541-.02-.806-.05l-.795-2.235c-.207-.071-.408-.15-.602-.247l-2.14 1.017c-.424-.336-.807-.719-1.143-1.143l1.017-2.139c-.094-.193-.175-.393-.245-.6l-2.236-.796c-.03-.265-.05-.534-.05-.807s.02-.542.05-.807l2.236-.795c.07-.207.15-.407.246-.601l-1.016-2.139c.336-.423.719-.807 1.143-1.142l2.14 1.017c.193-.096.394-.176.602-.247l.793-2.236c.265-.03.534-.05.806-.05.273 0 .542.02.808.05l.795 2.236c.207.07.407.15.601.246l2.14-1.017c.424.335.807.719 1.142 1.142l-1.017 2.139c.096.194.176.394.246.601l2.236.795c.029.266.049.535.049.808s-.02.542-.05.807l-2.236.796zm-4.714-4.603c-1.657 0-3 1.343-3 3s1.343 3 3 3 3-1.343 3-3-1.343-3-3-3z"/><circle cx="8" cy="8" r="1.5"/></g></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><g fill="#424242"><path d="M12.714 9.603c-.07.207-.15.407-.246.601l1.017 2.139c-.335.424-.718.807-1.142 1.143l-2.14-1.018c-.193.097-.394.176-.601.247l-.795 2.235c-.265.03-.534.05-.807.05-.272 0-.541-.02-.806-.05l-.795-2.235c-.207-.071-.408-.15-.602-.247l-2.14 1.017c-.424-.336-.807-.719-1.143-1.143l1.017-2.139c-.094-.193-.175-.393-.245-.6l-2.236-.796c-.03-.265-.05-.534-.05-.807s.02-.542.05-.807l2.236-.795c.07-.207.15-.407.246-.601l-1.016-2.139c.336-.423.719-.807 1.143-1.142l2.14 1.017c.193-.096.394-.176.602-.247l.793-2.236c.265-.03.534-.05.806-.05.273 0 .542.02.808.05l.795 2.236c.207.07.407.15.601.246l2.14-1.017c.424.335.807.719 1.142 1.142l-1.017 2.139c.096.194.176.394.246.601l2.236.795c.029.266.049.535.049.808s-.02.542-.05.807l-2.236.796zm-4.714-4.603c-1.657 0-3 1.343-3 3s1.343 3 3 3 3-1.343 3-3-1.343-3-3-3z"/><circle cx="8" cy="8" r="1.5"/></g></svg>
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册