提交 943b7823 编写于 作者: B Benjamin Pasero

paper cut - offer a menu to control visibility of status bar entries

上级 bd39f3d7
......@@ -11,7 +11,13 @@ import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
export const IStatusbarService = createDecorator<IStatusbarService>('statusbarService');
export const enum StatusbarAlignment {
LEFT, RIGHT
LEFT,
RIGHT
}
export interface IStatusbarEntryCategory {
id: string;
label: string;
}
/**
......@@ -19,6 +25,11 @@ export const enum StatusbarAlignment {
*/
export interface IStatusbarEntry {
/**
* The category of the entry is needed to allow users to hide entries via settings.
*/
readonly category: IStatusbarEntryCategory;
/**
* The text to show for the entry. You can embed icons in the text by leveraging the syntax:
*
......
......@@ -3,12 +3,13 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IStatusbarService, StatusbarAlignment as MainThreadStatusBarAlignment, IStatusbarEntryAccessor } from 'vs/platform/statusbar/common/statusbar';
import { IStatusbarService, StatusbarAlignment as MainThreadStatusBarAlignment, IStatusbarEntryAccessor, IStatusbarEntry } from 'vs/platform/statusbar/common/statusbar';
import { MainThreadStatusBarShape, MainContext, IExtHostContext } from '../common/extHost.protocol';
import { ThemeColor } from 'vs/platform/theme/common/themeService';
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { dispose } from 'vs/base/common/lifecycle';
import { localize } from 'vs/nls';
@extHostNamedCustomer(MainContext.MainThreadStatusBar)
export class MainThreadStatusBar implements MainThreadStatusBarShape {
......@@ -25,8 +26,18 @@ export class MainThreadStatusBar implements MainThreadStatusBarShape {
this.entries.clear();
}
$setEntry(id: number, extensionId: ExtensionIdentifier, text: string, tooltip: string, command: string, color: string | ThemeColor, alignment: MainThreadStatusBarAlignment, priority: number): void {
const entry = { text, tooltip, command, color, extensionId };
$setEntry(id: number, extension: IExtensionDescription, text: string, tooltip: string, command: string, color: string | ThemeColor, alignment: MainThreadStatusBarAlignment, priority: number): void {
const entry: IStatusbarEntry = {
category: {
id: extension.identifier.value,
label: localize('extensionLabel', "{0} (Extension)", extension.displayName || extension.name)
},
text,
tooltip,
command,
color,
extensionId: extension.identifier
};
// Reset existing entry if alignment or priority changed
let existingEntry = this.entries.get(id);
......
......@@ -495,7 +495,7 @@ export interface MainThreadQuickOpenShape extends IDisposable {
}
export interface MainThreadStatusBarShape extends IDisposable {
$setEntry(id: number, extensionId: ExtensionIdentifier | undefined, text: string, tooltip: string, command: string, color: string | ThemeColor, alignment: statusbar.StatusbarAlignment, priority: number | undefined): void;
$setEntry(id: number, extension: IExtensionDescription | undefined, text: string, tooltip: string, command: string, color: string | ThemeColor, alignment: statusbar.StatusbarAlignment, priority: number | undefined): void;
$dispose(id: number): void;
}
......
......@@ -7,7 +7,7 @@ import { StatusbarAlignment as MainThreadStatusBarAlignment } from 'vs/platform/
import { StatusBarAlignment as ExtHostStatusBarAlignment, Disposable, ThemeColor } from './extHostTypes';
import { StatusBarItem, StatusBarAlignment } from 'vscode';
import { MainContext, MainThreadStatusBarShape, IMainContext } from './extHost.protocol';
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
export class ExtHostStatusBarEntry implements StatusBarItem {
private static ID_GEN = 0;
......@@ -26,14 +26,14 @@ export class ExtHostStatusBarEntry implements StatusBarItem {
private _timeoutHandle: any;
private _proxy: MainThreadStatusBarShape;
private _extensionId?: ExtensionIdentifier;
private _extension?: IExtensionDescription;
constructor(proxy: MainThreadStatusBarShape, extensionId: ExtensionIdentifier | undefined, alignment: ExtHostStatusBarAlignment = ExtHostStatusBarAlignment.Left, priority?: number) {
constructor(proxy: MainThreadStatusBarShape, extension: IExtensionDescription | undefined, alignment: ExtHostStatusBarAlignment = ExtHostStatusBarAlignment.Left, priority?: number) {
this._id = ExtHostStatusBarEntry.ID_GEN++;
this._proxy = proxy;
this._alignment = alignment;
this._priority = priority;
this._extensionId = extensionId;
this._extension = extension;
}
public get id(): number {
......@@ -107,7 +107,7 @@ export class ExtHostStatusBarEntry implements StatusBarItem {
this._timeoutHandle = undefined;
// Set to status bar
this._proxy.$setEntry(this.id, this._extensionId, this.text, this.tooltip, this.command, this.color,
this._proxy.$setEntry(this.id, this._extension, this.text, this.tooltip, this.command, this.color,
this._alignment === ExtHostStatusBarAlignment.Left ? MainThreadStatusBarAlignment.LEFT : MainThreadStatusBarAlignment.RIGHT,
this._priority);
}, 0);
......@@ -167,8 +167,8 @@ export class ExtHostStatusBar {
this._statusMessage = new StatusBarMessage(this);
}
createStatusBarEntry(extensionId: ExtensionIdentifier | undefined, alignment?: ExtHostStatusBarAlignment, priority?: number): StatusBarItem {
return new ExtHostStatusBarEntry(this._proxy, extensionId, alignment, priority);
createStatusBarEntry(extension: IExtensionDescription | undefined, alignment?: ExtHostStatusBarAlignment, priority?: number): StatusBarItem {
return new ExtHostStatusBarEntry(this._proxy, extension, alignment, priority);
}
setStatusBarMessage(text: string, timeoutOrThenable?: number | Thenable<any>): Disposable {
......
......@@ -466,7 +466,7 @@ export function createApiFactory(
return extHostDialogs.showSaveDialog(options);
},
createStatusBarItem(position?: vscode.StatusBarAlignment, priority?: number): vscode.StatusBarItem {
return extHostStatusBar.createStatusBarEntry(extension.identifier, <number>position, priority);
return extHostStatusBar.createStatusBarEntry(extension, <number>position, priority);
},
setStatusBarMessage(text: string, timeoutOrThenable?: number | Thenable<any>): vscode.Disposable {
return extHostStatusBar.setStatusBarMessage(text, timeoutOrThenable);
......
......@@ -221,10 +221,20 @@ registerEditorContribution(OpenWorkspaceButtonContribution);
// Register Editor Status
const statusBar = Registry.as<IStatusbarRegistry>(StatusExtensions.Statusbar);
statusBar.registerStatusbarItem(new StatusbarItemDescriptor(EditorStatus, StatusbarAlignment.RIGHT, 100 /* towards the left of the right hand side */));
statusBar.registerStatusbarItem(new StatusbarItemDescriptor(
EditorStatus,
{ id: 'status.editor', label: nls.localize('status.editor', "Editor Status") },
StatusbarAlignment.RIGHT,
100 /* towards the left of the right hand side */
));
// Register Zoom Status
statusBar.registerStatusbarItem(new StatusbarItemDescriptor(ZoomStatusbarItem, StatusbarAlignment.RIGHT, 101 /* to the left of editor status (100) */));
statusBar.registerStatusbarItem(new StatusbarItemDescriptor(
ZoomStatusbarItem,
{ id: 'status.imageZoom', label: nls.localize('status.imageZoom', "Image Zoom") },
StatusbarAlignment.RIGHT,
101 /* to the left of editor status (100) */)
);
// Register Status Actions
const registry = Registry.as<IWorkbenchActionRegistry>(ActionExtensions.WorkbenchActions);
......
......@@ -58,6 +58,7 @@ export class NotificationsStatus extends Disposable {
private updateNotificationsCenterStatusItem(): void {
const statusProperties: IStatusbarEntry = {
category: { id: 'status.notifications', label: localize('status.notifications', "Notifictions") },
text: this.currentNotifications.size === 0 ? '$(bell)' : `$(bell) ${this.currentNotifications.size}`,
command: this.isNotificationsCenterVisible ? HIDE_NOTIFICATIONS_CENTER : SHOW_NOTIFICATIONS_CENTER,
tooltip: this.getTooltip(),
......@@ -137,7 +138,10 @@ export class NotificationsStatus extends Disposable {
// Create new
let statusMessageEntry: IStatusbarEntryAccessor;
let showHandle: any = setTimeout(() => {
statusMessageEntry = this.statusbarService.addEntry({ text: message }, StatusbarAlignment.LEFT, -Number.MAX_VALUE /* far right on left hand side */);
statusMessageEntry = this.statusbarService.addEntry({
category: { id: 'status.message', label: localize('status.message', "Status Message") },
text: message
}, StatusbarAlignment.LEFT, -Number.MAX_VALUE /* far right on left hand side */);
showHandle = null;
}, showAfter);
......
......@@ -5,7 +5,7 @@
import { Registry } from 'vs/platform/registry/common/platform';
import { IDisposable } from 'vs/base/common/lifecycle';
import { StatusbarAlignment } from 'vs/platform/statusbar/common/statusbar';
import { StatusbarAlignment, IStatusbarEntryCategory } from 'vs/platform/statusbar/common/statusbar';
import { SyncDescriptor0, createSyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { IConstructorSignature0 } from 'vs/platform/instantiation/common/instantiation';
......@@ -14,11 +14,18 @@ export interface IStatusbarItem {
}
export class StatusbarItemDescriptor {
syncDescriptor: SyncDescriptor0<IStatusbarItem>;
alignment: StatusbarAlignment;
priority: number;
constructor(ctor: IConstructorSignature0<IStatusbarItem>, alignment?: StatusbarAlignment, priority?: number) {
readonly syncDescriptor: SyncDescriptor0<IStatusbarItem>;
readonly category: IStatusbarEntryCategory;
readonly alignment: StatusbarAlignment;
readonly priority: number;
constructor(
ctor: IConstructorSignature0<IStatusbarItem>,
category: IStatusbarEntryCategory,
alignment?: StatusbarAlignment,
priority?: number
) {
this.category = category;
this.syncDescriptor = createSyncDescriptor(ctor);
this.alignment = alignment || StatusbarAlignment.LEFT;
this.priority = priority || 0;
......@@ -26,21 +33,16 @@ export class StatusbarItemDescriptor {
}
export interface IStatusbarRegistry {
readonly items: StatusbarItemDescriptor[];
registerStatusbarItem(descriptor: StatusbarItemDescriptor): void;
items: StatusbarItemDescriptor[];
}
class StatusbarRegistry implements IStatusbarRegistry {
private _items: StatusbarItemDescriptor[];
constructor() {
this._items = [];
}
get items(): StatusbarItemDescriptor[] {
return this._items;
}
private readonly _items: StatusbarItemDescriptor[] = [];
get items(): StatusbarItemDescriptor[] { return this._items; }
registerStatusbarItem(descriptor: StatusbarItemDescriptor): void {
this._items.push(descriptor);
......
......@@ -65,6 +65,7 @@ export class DebugStatusContribution implements IWorkbenchContribution {
private get entry(): IStatusbarEntry {
return {
category: { id: 'status.debug', label: nls.localize('status.debug', "Debug Configuration") },
text: this.getText(),
tooltip: nls.localize('selectAndStartDebug', "Select and start debug configuration"),
command: 'workbench.action.debug.selectandstart'
......
......@@ -84,6 +84,7 @@ export class ExtensionHostProfileService extends Disposable implements IExtensio
if (visible) {
const indicator: IStatusbarEntry = {
category: { id: 'status.profiler', label: nls.localize('status.profiler', "Extension Profiler") },
text: nls.localize('profilingExtensionHost', "$(sync~spin) Profiling Extension Host"),
tooltip: nls.localize('selectAndStartDebug', "Click to stop profiling."),
command: 'workbench.action.extensionHostProfilder.stop'
......
......@@ -13,6 +13,7 @@ import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from 'v
// Register Statusbar item
Registry.as<IStatusbarRegistry>(Extensions.Statusbar).registerStatusbarItem(new StatusbarItemDescriptor(
FeedbackStatusbarItem,
{ id: 'status.feedback', label: localize('status.feedback', "Send Feedback") },
StatusbarAlignment.RIGHT,
-100 /* towards the end of the right hand side */
));
......
......@@ -6,7 +6,7 @@
import { IDisposable, dispose, Disposable } from 'vs/base/common/lifecycle';
import { IStatusbarItem } from 'vs/workbench/browser/parts/statusbar/statusbar';
import { FeedbackDropdown, IFeedback, IFeedbackDelegate, FEEDBACK_VISIBLE_CONFIG } from 'vs/workbench/contrib/feedback/electron-browser/feedback';
import { IContextViewService, IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import product from 'vs/platform/product/node/product';
import { Themable, STATUS_BAR_ITEM_HOVER_BACKGROUND } from 'vs/workbench/common/theme';
......@@ -14,8 +14,6 @@ import { IThemeService, registerThemingParticipant, ITheme, ICssStyleCollector }
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { IConfigurationChangeEvent, IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { clearNode, EventHelper, addClass, removeClass, addDisposableListener } from 'vs/base/browser/dom';
import { localize } from 'vs/nls';
import { Action } from 'vs/base/common/actions';
class TwitterFeedbackService implements IFeedbackDelegate {
......@@ -54,13 +52,11 @@ export class FeedbackStatusbarItem extends Themable implements IStatusbarItem {
private dropdown: FeedbackDropdown | undefined;
private enabled: boolean;
private container: HTMLElement;
private hideAction: HideAction;
constructor(
@IInstantiationService private readonly instantiationService: IInstantiationService,
@IContextViewService private readonly contextViewService: IContextViewService,
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
@IContextMenuService private readonly contextMenuService: IContextMenuService,
@IConfigurationService private readonly configurationService: IConfigurationService,
@IThemeService themeService: IThemeService
) {
......@@ -68,8 +64,6 @@ export class FeedbackStatusbarItem extends Themable implements IStatusbarItem {
this.enabled = this.configurationService.getValue(FEEDBACK_VISIBLE_CONFIG);
this.hideAction = this._register(this.instantiationService.createInstance(HideAction));
this.registerListeners();
}
......@@ -95,16 +89,6 @@ export class FeedbackStatusbarItem extends Themable implements IStatusbarItem {
}
}, true));
// Offer context menu to hide status bar entry
this._register(addDisposableListener(this.container, 'contextmenu', e => {
EventHelper.stop(e, true);
this.contextMenuService.showContextMenu({
getAnchor: () => this.container,
getActions: () => [this.hideAction]
});
}));
return this.update();
}
......@@ -143,19 +127,6 @@ export class FeedbackStatusbarItem extends Themable implements IStatusbarItem {
}
}
class HideAction extends Action {
constructor(
@IConfigurationService private readonly configurationService: IConfigurationService
) {
super('feedback.hide', localize('hide', "Hide"));
}
run(extensionId: string): Promise<any> {
return this.configurationService.updateValue(FEEDBACK_VISIBLE_CONFIG, false);
}
}
registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
const statusBarItemHoverBackground = theme.getColor(STATUS_BAR_ITEM_HOVER_BACKGROUND);
if (statusBarItemHoverBackground) {
......
......@@ -286,6 +286,7 @@ class MarkersStatusBarContributions extends Disposable implements IWorkbenchCont
private getMarkersItem(): IStatusbarEntry {
const markersStatistics = this.markerService.getStatistics();
return {
category: { id: 'status.problems', label: localize('status.problems', "Problems") },
text: this.getMarkersText(markersStatistics),
tooltip: this.getMarkersTooltip(markersStatistics),
command: 'workbench.actions.view.toggleProblems'
......
......@@ -138,6 +138,7 @@ export class RemoteWindowActiveIndicator extends Disposable implements IWorkbenc
private renderWindowIndicator(text: string, tooltip?: string, command?: string): void {
const properties: IStatusbarEntry = {
category: { id: 'status.host', label: nls.localize('status.host', "Remote Host") },
backgroundColor: themeColorFromId(STATUS_BAR_HOST_NAME_BACKGROUND), color: themeColorFromId(STATUS_BAR_HOST_NAME_FOREGROUND), text, tooltip, command
};
if (this.windowIndicatorEntry) {
......
......@@ -190,6 +190,7 @@ export class StatusBarController implements IWorkbenchContribution {
const disposables = new DisposableStore();
for (const c of commands) {
disposables.add(this.statusbarService.addEntry({
category: { id: 'status.scm', label: localize('status.scm', "Source Control") },
text: c.title,
tooltip: `${label} - ${c.tooltip}`,
command: c.id,
......
......@@ -182,6 +182,7 @@ export class TaskStatusBarContributions extends Disposable implements IWorkbench
}
} else {
const itemProps: IStatusbarEntry = {
category: { id: 'status.runningTasks', label: nls.localize('status.runningTasks', "Running Tasks") },
text: `$(tools) ${tasks.length}`,
tooltip: nls.localize('runningTasks', "Show Running Tasks"),
command: 'workbench.action.tasks.showTasks',
......
......@@ -129,6 +129,7 @@ export class ProgressService implements IProgressService {
}
this._globalStatusEntry = this._statusbarService.addEntry({
category: { id: 'status.progress', label: localize('status.progress', "Progress Message") },
text: `$(sync~spin) ${text}`,
tooltip: title
}, StatusbarAlignment.LEFT);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册