mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-03-24 13:50:29 -04:00
Merge VS Code 1.31.1 (#4283)
This commit is contained in:
@@ -36,14 +36,14 @@ export class ViewletActivityAction extends ActivityAction {
|
||||
|
||||
constructor(
|
||||
activity: IActivity,
|
||||
@IViewletService private viewletService: IViewletService,
|
||||
@IPartService private partService: IPartService,
|
||||
@ITelemetryService private telemetryService: ITelemetryService
|
||||
@IViewletService private readonly viewletService: IViewletService,
|
||||
@IPartService private readonly partService: IPartService,
|
||||
@ITelemetryService private readonly telemetryService: ITelemetryService
|
||||
) {
|
||||
super(activity);
|
||||
}
|
||||
|
||||
run(event: any): Thenable<any> {
|
||||
run(event: any): Promise<any> {
|
||||
if (event instanceof MouseEvent && event.button === 2) {
|
||||
return Promise.resolve(false); // do not run on right click
|
||||
}
|
||||
@@ -84,13 +84,13 @@ export class ToggleViewletAction extends Action {
|
||||
|
||||
constructor(
|
||||
private _viewlet: ViewletDescriptor,
|
||||
@IPartService private partService: IPartService,
|
||||
@IViewletService private viewletService: IViewletService
|
||||
@IPartService private readonly partService: IPartService,
|
||||
@IViewletService private readonly viewletService: IViewletService
|
||||
) {
|
||||
super(_viewlet.id, _viewlet.name);
|
||||
}
|
||||
|
||||
run(): Thenable<any> {
|
||||
run(): Promise<any> {
|
||||
const sideBarVisible = this.partService.isVisible(Parts.SIDEBAR_PART);
|
||||
const activeViewlet = this.viewletService.getActiveViewlet();
|
||||
|
||||
@@ -175,7 +175,7 @@ export class PlaceHolderViewletActivityAction extends ViewletActivityAction {
|
||||
) {
|
||||
super({ id, name: id, cssClass: `extensionViewlet-placeholder-${id.replace(/\./g, '-')}` }, viewletService, partService, telemetryService);
|
||||
|
||||
const iconClass = `.monaco-workbench > .activitybar .monaco-action-bar .action-label.${this.class}`; // Generate Placeholder CSS to show the icon in the activity bar
|
||||
const iconClass = `.monaco-workbench .activitybar .monaco-action-bar .action-label.${this.class}`; // Generate Placeholder CSS to show the icon in the activity bar
|
||||
DOM.createCSSRule(iconClass, `-webkit-mask: url('${iconUrl || ''}') no-repeat 50% 50%`);
|
||||
}
|
||||
|
||||
@@ -187,7 +187,7 @@ export class PlaceHolderViewletActivityAction extends ViewletActivityAction {
|
||||
export class PlaceHolderToggleCompositePinnedAction extends ToggleCompositePinnedAction {
|
||||
|
||||
constructor(id: string, compositeBar: ICompositeBar) {
|
||||
super({ id, name: id, cssClass: void 0 }, compositeBar);
|
||||
super({ id, name: id, cssClass: undefined }, compositeBar);
|
||||
}
|
||||
|
||||
setActivity(activity: IActivity): void {
|
||||
@@ -200,13 +200,13 @@ class SwitchSideBarViewAction extends Action {
|
||||
constructor(
|
||||
id: string,
|
||||
name: string,
|
||||
@IViewletService private viewletService: IViewletService,
|
||||
@IActivityService private activityService: IActivityService
|
||||
@IViewletService private readonly viewletService: IViewletService,
|
||||
@IActivityService private readonly activityService: IActivityService
|
||||
) {
|
||||
super(id, name);
|
||||
}
|
||||
|
||||
run(offset: number): Thenable<any> {
|
||||
run(offset: number): Promise<any> {
|
||||
const pinnedViewletIds = this.activityService.getPinnedViewletIds();
|
||||
|
||||
const activeViewlet = this.viewletService.getActiveViewlet();
|
||||
@@ -238,7 +238,7 @@ export class PreviousSideBarViewAction extends SwitchSideBarViewAction {
|
||||
super(id, name, viewletService, activityService);
|
||||
}
|
||||
|
||||
run(): Thenable<any> {
|
||||
run(): Promise<any> {
|
||||
return super.run(-1);
|
||||
}
|
||||
}
|
||||
@@ -257,7 +257,7 @@ export class NextSideBarViewAction extends SwitchSideBarViewAction {
|
||||
super(id, name, viewletService, activityService);
|
||||
}
|
||||
|
||||
run(): Thenable<any> {
|
||||
run(): Promise<any> {
|
||||
return super.run(1);
|
||||
}
|
||||
}
|
||||
@@ -271,9 +271,9 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
|
||||
const activeForegroundColor = theme.getColor(ACTIVITY_BAR_FOREGROUND);
|
||||
if (activeForegroundColor) {
|
||||
collector.addRule(`
|
||||
.monaco-workbench > .activitybar > .content .monaco-action-bar .action-item.active .action-label,
|
||||
.monaco-workbench > .activitybar > .content .monaco-action-bar .action-item:focus .action-label,
|
||||
.monaco-workbench > .activitybar > .content .monaco-action-bar .action-item:hover .action-label {
|
||||
.monaco-workbench .activitybar > .content .monaco-action-bar .action-item.active .action-label,
|
||||
.monaco-workbench .activitybar > .content .monaco-action-bar .action-item:focus .action-label,
|
||||
.monaco-workbench .activitybar > .content .monaco-action-bar .action-item:hover .action-label {
|
||||
background-color: ${activeForegroundColor} !important;
|
||||
}
|
||||
`);
|
||||
@@ -283,7 +283,7 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
|
||||
const outline = theme.getColor(activeContrastBorder);
|
||||
if (outline) {
|
||||
collector.addRule(`
|
||||
.monaco-workbench > .activitybar > .content .monaco-action-bar .action-item:before {
|
||||
.monaco-workbench .activitybar > .content .monaco-action-bar .action-item:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 9px;
|
||||
@@ -292,26 +292,26 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
|
||||
width: 32px;
|
||||
}
|
||||
|
||||
.monaco-workbench > .activitybar > .content .monaco-action-bar .action-item.active:before,
|
||||
.monaco-workbench > .activitybar > .content .monaco-action-bar .action-item.active:hover:before,
|
||||
.monaco-workbench > .activitybar > .content .monaco-action-bar .action-item.checked:before,
|
||||
.monaco-workbench > .activitybar > .content .monaco-action-bar .action-item.checked:hover:before {
|
||||
.monaco-workbench .activitybar > .content .monaco-action-bar .action-item.active:before,
|
||||
.monaco-workbench .activitybar > .content .monaco-action-bar .action-item.active:hover:before,
|
||||
.monaco-workbench .activitybar > .content .monaco-action-bar .action-item.checked:before,
|
||||
.monaco-workbench .activitybar > .content .monaco-action-bar .action-item.checked:hover:before {
|
||||
outline: 1px solid;
|
||||
}
|
||||
|
||||
.monaco-workbench > .activitybar > .content .monaco-action-bar .action-item:hover:before {
|
||||
.monaco-workbench .activitybar > .content .monaco-action-bar .action-item:hover:before {
|
||||
outline: 1px dashed;
|
||||
}
|
||||
|
||||
.monaco-workbench > .activitybar > .content .monaco-action-bar .action-item:focus:before {
|
||||
.monaco-workbench .activitybar > .content .monaco-action-bar .action-item:focus:before {
|
||||
border-left-color: ${outline};
|
||||
}
|
||||
|
||||
.monaco-workbench > .activitybar > .content .monaco-action-bar .action-item.active:before,
|
||||
.monaco-workbench > .activitybar > .content .monaco-action-bar .action-item.active:hover:before,
|
||||
.monaco-workbench > .activitybar > .content .monaco-action-bar .action-item.checked:before,
|
||||
.monaco-workbench > .activitybar > .content .monaco-action-bar .action-item.checked:hover:before,
|
||||
.monaco-workbench > .activitybar > .content .monaco-action-bar .action-item:hover:before {
|
||||
.monaco-workbench .activitybar > .content .monaco-action-bar .action-item.active:before,
|
||||
.monaco-workbench .activitybar > .content .monaco-action-bar .action-item.active:hover:before,
|
||||
.monaco-workbench .activitybar > .content .monaco-action-bar .action-item.checked:before,
|
||||
.monaco-workbench .activitybar > .content .monaco-action-bar .action-item.checked:hover:before,
|
||||
.monaco-workbench .activitybar > .content .monaco-action-bar .action-item:hover:before {
|
||||
outline-color: ${outline};
|
||||
}
|
||||
`);
|
||||
@@ -322,7 +322,7 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
|
||||
const focusBorderColor = theme.getColor(focusBorder);
|
||||
if (focusBorderColor) {
|
||||
collector.addRule(`
|
||||
.monaco-workbench > .activitybar > .content .monaco-action-bar .action-item:focus:before {
|
||||
.monaco-workbench .activitybar > .content .monaco-action-bar .action-item:focus:before {
|
||||
border-left-color: ${focusBorderColor};
|
||||
}
|
||||
`);
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
import 'vs/css!./media/activitybarpart';
|
||||
import * as nls from 'vs/nls';
|
||||
import { illegalArgument } from 'vs/base/common/errors';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
import { ActionsOrientation, ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { GlobalActivityExtensions, IGlobalActivityRegistry } from 'vs/workbench/common/activity';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
@@ -15,38 +16,39 @@ import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
|
||||
import { IBadge } from 'vs/workbench/services/activity/common/activity';
|
||||
import { IPartService, Parts, Position as SideBarPosition } from 'vs/workbench/services/part/common/partService';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { ToggleActivityBarVisibilityAction } from 'vs/workbench/browser/actions/toggleActivityBarVisibility';
|
||||
import { IThemeService, registerThemingParticipant, ITheme } from 'vs/platform/theme/common/themeService';
|
||||
import { IDisposable, toDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { ToggleActivityBarVisibilityAction } from 'vs/workbench/browser/actions/layoutActions';
|
||||
import { IThemeService, ITheme } from 'vs/platform/theme/common/themeService';
|
||||
import { ACTIVITY_BAR_BACKGROUND, ACTIVITY_BAR_BORDER, ACTIVITY_BAR_FOREGROUND, ACTIVITY_BAR_BADGE_BACKGROUND, ACTIVITY_BAR_BADGE_FOREGROUND, ACTIVITY_BAR_DRAG_AND_DROP_BACKGROUND, ACTIVITY_BAR_INACTIVE_FOREGROUND } from 'vs/workbench/common/theme';
|
||||
import { contrastBorder } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { CompositeBar } from 'vs/workbench/browser/parts/compositeBar';
|
||||
import { isMacintosh } from 'vs/base/common/platform';
|
||||
import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
|
||||
import { scheduleAtNextAnimationFrame, Dimension, addClass } from 'vs/base/browser/dom';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { CompositeBar, ICompositeBarItem } from 'vs/workbench/browser/parts/compositeBar';
|
||||
import { Dimension, addClass } from 'vs/base/browser/dom';
|
||||
import { IStorageService, StorageScope, IWorkspaceStorageChangeEvent } from 'vs/platform/storage/common/storage';
|
||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import { ToggleCompositePinnedAction, ICompositeBarColors } from 'vs/workbench/browser/parts/compositeBarActions';
|
||||
import { ViewletDescriptor } from 'vs/workbench/browser/viewlet';
|
||||
import { IViewsService, IViewContainersRegistry, Extensions as ViewContainerExtensions, ViewContainer, TEST_VIEW_CONTAINER_ID, IViewDescriptorCollection } from 'vs/workbench/common/views';
|
||||
import { IContextKeyService, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IViewlet } from 'vs/workbench/common/viewlet';
|
||||
import { isUndefinedOrNull } from 'vs/base/common/types';
|
||||
import { ISerializableView } from 'vs/base/browser/ui/grid/grid';
|
||||
|
||||
const SCM_VIEWLET_ID = 'workbench.view.scm';
|
||||
|
||||
interface ICachedViewlet {
|
||||
id: string;
|
||||
iconUrl: URI;
|
||||
iconUrl: UriComponents;
|
||||
pinned: boolean;
|
||||
order: number;
|
||||
visible: boolean;
|
||||
views?: { when: string }[];
|
||||
}
|
||||
|
||||
export class ActivitybarPart extends Part {
|
||||
export class ActivitybarPart extends Part implements ISerializableView {
|
||||
|
||||
private static readonly ACTION_HEIGHT = 50;
|
||||
private static readonly PINNED_VIEWLETS = 'workbench.activity.pinnedViewlets';
|
||||
private static readonly CACHED_VIEWLETS = 'workbench.activity.placeholderViewlets';
|
||||
|
||||
private dimension: Dimension;
|
||||
|
||||
@@ -57,23 +59,37 @@ export class ActivitybarPart extends Part {
|
||||
private compositeBar: CompositeBar;
|
||||
private compositeActions: { [compositeId: string]: { activityAction: ViewletActivityAction, pinnedAction: ToggleCompositePinnedAction } } = Object.create(null);
|
||||
|
||||
element: HTMLElement;
|
||||
minimumWidth: number = 50;
|
||||
maximumWidth: number = 50;
|
||||
minimumHeight: number = 0;
|
||||
maximumHeight: number = Number.POSITIVE_INFINITY;
|
||||
|
||||
private _onDidChange = new Emitter<{ width: number; height: number; }>();
|
||||
readonly onDidChange = this._onDidChange.event;
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
@IViewletService private viewletService: IViewletService,
|
||||
@IInstantiationService private instantiationService: IInstantiationService,
|
||||
@IPartService private partService: IPartService,
|
||||
@IViewletService private readonly viewletService: IViewletService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@IPartService private readonly partService: IPartService,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@ILifecycleService private lifecycleService: ILifecycleService,
|
||||
@IStorageService private storageService: IStorageService,
|
||||
@IExtensionService private extensionService: IExtensionService,
|
||||
@IViewsService private viewsService: IViewsService,
|
||||
@IContextKeyService private contextKeyService: IContextKeyService
|
||||
@IStorageService private readonly storageService: IStorageService,
|
||||
@IExtensionService private readonly extensionService: IExtensionService,
|
||||
@IViewsService private readonly viewsService: IViewsService,
|
||||
@IContextKeyService private readonly contextKeyService: IContextKeyService
|
||||
) {
|
||||
super(id, { hasTitle: false }, themeService, storageService);
|
||||
|
||||
this.compositeBar = this._register(this.instantiationService.createInstance(CompositeBar, {
|
||||
this.cachedViewlets = this.getCachedViewlets();
|
||||
for (const cachedViewlet of this.cachedViewlets) {
|
||||
if (this.shouldBeHidden(cachedViewlet.id, cachedViewlet)) {
|
||||
cachedViewlet.visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
this.compositeBar = this._register(this.instantiationService.createInstance(CompositeBar, this.cachedViewlets.map(v => (<ICompositeBarItem>{ id: v.id, name: undefined, visible: v.visible, order: v.order, pinned: v.pinned })), {
|
||||
icon: true,
|
||||
storageId: ActivitybarPart.PINNED_VIEWLETS,
|
||||
orientation: ActionsOrientation.VERTICAL,
|
||||
openComposite: (compositeId: string) => this.viewletService.openViewlet(compositeId, true),
|
||||
getActivityAction: (compositeId: string) => this.getCompositeActions(compositeId).activityAction,
|
||||
@@ -87,16 +103,8 @@ export class ActivitybarPart extends Part {
|
||||
overflowActionSize: ActivitybarPart.ACTION_HEIGHT
|
||||
}));
|
||||
|
||||
const previousState = this.storageService.get(ActivitybarPart.CACHED_VIEWLETS, StorageScope.GLOBAL, '[]');
|
||||
this.cachedViewlets = (<ICachedViewlet[]>JSON.parse(previousState)).map(({ id, iconUrl, views }) => ({ id, views, iconUrl: typeof iconUrl === 'object' ? URI.revive(iconUrl) : void 0 }));
|
||||
for (const cachedViewlet of this.cachedViewlets) {
|
||||
if (this.shouldBeHidden(cachedViewlet.id, cachedViewlet)) {
|
||||
this.compositeBar.hideComposite(cachedViewlet.id);
|
||||
}
|
||||
}
|
||||
|
||||
this.registerListeners();
|
||||
this.onDidRegisterViewlets(viewletService.getAllViewlets());
|
||||
this.onDidRegisterViewlets(viewletService.getViewlets());
|
||||
}
|
||||
|
||||
// {{SQL CARBON EDIT}}
|
||||
@@ -112,35 +120,40 @@ export class ActivitybarPart extends Part {
|
||||
}
|
||||
|
||||
private registerListeners(): void {
|
||||
|
||||
this._register(this.viewletService.onDidViewletRegister(viewlet => this.onDidRegisterViewlets([viewlet])));
|
||||
this._register(this.viewletService.onDidViewletDeregister(({ id }) => this.removeComposite(id, true)));
|
||||
|
||||
// Activate viewlet action on opening of a viewlet
|
||||
this._register(this.viewletService.onDidViewletOpen(viewlet => this.onDidViewletOpen(viewlet)));
|
||||
|
||||
// Deactivate viewlet action on close
|
||||
this._register(this.viewletService.onDidViewletClose(viewlet => this.compositeBar.deactivateComposite(viewlet.getId())));
|
||||
this._register(this.viewletService.onDidViewletEnablementChange(({ id, enabled }) => {
|
||||
if (enabled) {
|
||||
this.compositeBar.addComposite(this.viewletService.getViewlet(id));
|
||||
} else {
|
||||
this.removeComposite(id, true);
|
||||
}
|
||||
}));
|
||||
|
||||
this._register(this.extensionService.onDidRegisterExtensions(() => this.onDidRegisterExtensions()));
|
||||
let disposables: IDisposable[] = [];
|
||||
this._register(this.extensionService.onDidRegisterExtensions(() => {
|
||||
disposables = dispose(disposables);
|
||||
this.onDidRegisterExtensions();
|
||||
this.compositeBar.onDidChange(() => this.saveCachedViewlets(), this, disposables);
|
||||
this.storageService.onDidChangeStorage(e => this.onDidStorageChange(e), this, disposables);
|
||||
}));
|
||||
this._register(toDisposable(() => dispose(disposables)));
|
||||
}
|
||||
|
||||
private onDidRegisterExtensions(): void {
|
||||
this.removeNotExistingComposites();
|
||||
for (const viewlet of this.viewletService.getAllViewlets()) {
|
||||
for (const viewlet of this.viewletService.getViewlets()) {
|
||||
this.enableCompositeActions(viewlet);
|
||||
const viewContainer = this.getViewContainer(viewlet.id);
|
||||
if (viewContainer) {
|
||||
const viewDescriptors = this.viewsService.getViewDescriptors(viewContainer);
|
||||
this.onDidChangeActiveViews(viewlet, viewDescriptors);
|
||||
viewDescriptors.onDidChangeActiveViews(() => this.onDidChangeActiveViews(viewlet, viewDescriptors));
|
||||
if (viewDescriptors) {
|
||||
this.onDidChangeActiveViews(viewlet, viewDescriptors);
|
||||
viewDescriptors.onDidChangeActiveViews(() => this.onDidChangeActiveViews(viewlet, viewDescriptors));
|
||||
}
|
||||
}
|
||||
}
|
||||
this.saveCachedViewlets();
|
||||
}
|
||||
|
||||
private onDidChangeActiveViews(viewlet: ViewletDescriptor, viewDescriptors: IViewDescriptorCollection): void {
|
||||
@@ -157,9 +170,12 @@ export class ActivitybarPart extends Part {
|
||||
this.compositeBar.activateComposite(viewlet.getId());
|
||||
const viewletDescriptor = this.viewletService.getViewlet(viewlet.getId());
|
||||
const viewContainer = this.getViewContainer(viewletDescriptor.id);
|
||||
if (viewContainer && this.viewsService.getViewDescriptors(viewContainer).activeViewDescriptors.length === 0) {
|
||||
// Update the composite bar by hiding
|
||||
this.removeComposite(viewletDescriptor.id, true);
|
||||
if (viewContainer) {
|
||||
const viewDescriptors = this.viewsService.getViewDescriptors(viewContainer);
|
||||
if (viewDescriptors && viewDescriptors.activeViewDescriptors.length === 0) {
|
||||
// Update the composite bar by hiding
|
||||
this.removeComposite(viewletDescriptor.id, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,6 +203,7 @@ export class ActivitybarPart extends Part {
|
||||
}
|
||||
|
||||
createContentArea(parent: HTMLElement): HTMLElement {
|
||||
this.element = parent;
|
||||
const content = document.createElement('div');
|
||||
addClass(content, 'content');
|
||||
parent.appendChild(content);
|
||||
@@ -201,27 +218,6 @@ export class ActivitybarPart extends Part {
|
||||
|
||||
this.createGlobalActivityActionBar(globalActivities);
|
||||
|
||||
// TODO@Ben: workaround for https://github.com/Microsoft/vscode/issues/45700
|
||||
// It looks like there are rendering glitches on macOS with Chrome 61 when
|
||||
// using --webkit-mask with a background color that is different from the image
|
||||
// The workaround is to promote the element onto its own drawing layer. We do
|
||||
// this only after the workbench has loaded because otherwise there is ugly flicker.
|
||||
if (isMacintosh) {
|
||||
this.lifecycleService.when(LifecyclePhase.Restored).then(() => {
|
||||
scheduleAtNextAnimationFrame(() => { // another delay...
|
||||
scheduleAtNextAnimationFrame(() => { // ...to prevent more flickering on startup
|
||||
registerThemingParticipant((theme, collector) => {
|
||||
const activityBarForeground = theme.getColor(ACTIVITY_BAR_FOREGROUND);
|
||||
if (activityBarForeground && !activityBarForeground.equals(Color.white)) {
|
||||
// only apply this workaround if the color is different from the image one (white)
|
||||
collector.addRule('.monaco-workbench .activitybar > .content .monaco-action-bar .action-label { will-change: transform; }');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
@@ -287,7 +283,7 @@ export class ActivitybarPart extends Part {
|
||||
} else {
|
||||
const cachedComposite = this.cachedViewlets.filter(c => c.id === compositeId)[0];
|
||||
compositeActions = {
|
||||
activityAction: this.instantiationService.createInstance(PlaceHolderViewletActivityAction, compositeId, cachedComposite && cachedComposite.iconUrl),
|
||||
activityAction: this.instantiationService.createInstance(PlaceHolderViewletActivityAction, compositeId, cachedComposite ? URI.revive(cachedComposite.iconUrl) : undefined),
|
||||
pinnedAction: new PlaceHolderToggleCompositePinnedAction(compositeId, this.compositeBar)
|
||||
};
|
||||
}
|
||||
@@ -326,8 +322,8 @@ export class ActivitybarPart extends Part {
|
||||
}
|
||||
|
||||
private removeNotExistingComposites(): void {
|
||||
const viewlets = this.viewletService.getAllViewlets();
|
||||
for (const { id } of this.compositeBar.getComposites()) {
|
||||
const viewlets = this.viewletService.getViewlets();
|
||||
for (const { id } of this.cachedViewlets) {
|
||||
if (viewlets.every(viewlet => viewlet.id !== id)) {
|
||||
this.removeComposite(id, false);
|
||||
}
|
||||
@@ -366,13 +362,19 @@ export class ActivitybarPart extends Part {
|
||||
.map(v => v.id);
|
||||
}
|
||||
|
||||
layout(dimension: Dimension): Dimension[] {
|
||||
layout(dimension: Dimension): Dimension[];
|
||||
layout(width: number, height: number): void;
|
||||
layout(dim1: Dimension | number, dim2?: number): Dimension[] | void {
|
||||
if (!this.partService.isVisible(Parts.ACTIVITYBAR_PART)) {
|
||||
return [dimension];
|
||||
if (dim1 instanceof Dimension) {
|
||||
return [dim1];
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Pass to super
|
||||
const sizes = super.layout(dimension);
|
||||
const sizes = super.layout(dim1 instanceof Dimension ? dim1 : new Dimension(dim1, dim2));
|
||||
|
||||
this.dimension = sizes[1];
|
||||
|
||||
@@ -381,26 +383,114 @@ export class ActivitybarPart extends Part {
|
||||
// adjust height for global actions showing
|
||||
availableHeight -= (this.globalActionBar.items.length * ActivitybarPart.ACTION_HEIGHT);
|
||||
}
|
||||
this.compositeBar.layout(new Dimension(dimension.width, availableHeight));
|
||||
this.compositeBar.layout(new Dimension(dim1 instanceof Dimension ? dim1.width : dim1, availableHeight));
|
||||
|
||||
return sizes;
|
||||
if (dim1 instanceof Dimension) {
|
||||
return sizes;
|
||||
}
|
||||
}
|
||||
|
||||
protected saveState(): void {
|
||||
const state: ICachedViewlet[] = [];
|
||||
for (const { id, iconUrl } of this.viewletService.getAllViewlets()) {
|
||||
const viewContainer = this.getViewContainer(id);
|
||||
const views: { when: string }[] = [];
|
||||
if (viewContainer) {
|
||||
for (const { when } of this.viewsService.getViewDescriptors(viewContainer).allViewDescriptors) {
|
||||
views.push({ when: when ? when.serialize() : void 0 });
|
||||
private onDidStorageChange(e: IWorkspaceStorageChangeEvent): void {
|
||||
if (e.key === ActivitybarPart.PINNED_VIEWLETS && e.scope === StorageScope.GLOBAL
|
||||
&& this.cachedViewletsValue !== this.getStoredCachedViewletsValue() /* This checks if current window changed the value or not */) {
|
||||
this._cachedViewletsValue = null;
|
||||
const newCompositeItems: ICompositeBarItem[] = [];
|
||||
const compositeItems = this.compositeBar.getCompositeBarItems();
|
||||
const cachedViewlets = this.getCachedViewlets();
|
||||
|
||||
for (const cachedViewlet of cachedViewlets) {
|
||||
// Add and update existing items
|
||||
const existingItem = compositeItems.filter(({ id }) => id === cachedViewlet.id)[0];
|
||||
if (existingItem) {
|
||||
newCompositeItems.push({
|
||||
id: existingItem.id,
|
||||
name: existingItem.name,
|
||||
order: existingItem.order,
|
||||
pinned: cachedViewlet.pinned,
|
||||
visible: existingItem.visible
|
||||
});
|
||||
}
|
||||
}
|
||||
state.push({ id, iconUrl, views });
|
||||
}
|
||||
this.storageService.store(ActivitybarPart.CACHED_VIEWLETS, JSON.stringify(state), StorageScope.GLOBAL);
|
||||
|
||||
super.saveState();
|
||||
for (let index = 0; index < compositeItems.length; index++) {
|
||||
// Add items currently exists but does not exist in new.
|
||||
if (!newCompositeItems.some(({ id }) => id === compositeItems[index].id)) {
|
||||
newCompositeItems.splice(index, 0, compositeItems[index]);
|
||||
}
|
||||
}
|
||||
|
||||
this.compositeBar.setCompositeBarItems(newCompositeItems);
|
||||
}
|
||||
}
|
||||
|
||||
private saveCachedViewlets(): void {
|
||||
const state: ICachedViewlet[] = [];
|
||||
const compositeItems = this.compositeBar.getCompositeBarItems();
|
||||
const allViewlets = this.viewletService.getViewlets();
|
||||
for (const compositeItem of compositeItems) {
|
||||
const viewContainer = this.getViewContainer(compositeItem.id);
|
||||
const viewlet = allViewlets.filter(({ id }) => id === compositeItem.id)[0];
|
||||
if (viewlet) {
|
||||
const views: { when: string }[] = [];
|
||||
if (viewContainer) {
|
||||
const viewDescriptors = this.viewsService.getViewDescriptors(viewContainer);
|
||||
if (viewDescriptors) {
|
||||
for (const { when } of viewDescriptors.allViewDescriptors) {
|
||||
views.push({ when: when ? when.serialize() : undefined });
|
||||
}
|
||||
}
|
||||
}
|
||||
state.push({ id: compositeItem.id, iconUrl: viewlet.iconUrl, views, pinned: compositeItem && compositeItem.pinned, order: compositeItem ? compositeItem.order : undefined, visible: compositeItem && compositeItem.visible });
|
||||
}
|
||||
}
|
||||
this.cachedViewletsValue = JSON.stringify(state);
|
||||
}
|
||||
|
||||
private getCachedViewlets(): ICachedViewlet[] {
|
||||
const storedStates = <Array<string | ICachedViewlet>>JSON.parse(this.cachedViewletsValue);
|
||||
const cachedViewlets = <ICachedViewlet[]>storedStates.map(c => {
|
||||
const serialized: ICachedViewlet = typeof c === 'string' /* migration from pinned states to composites states */ ? <ICachedViewlet>{ id: c, pinned: true, order: undefined, visible: true, iconUrl: undefined, views: undefined } : c;
|
||||
serialized.visible = isUndefinedOrNull(serialized.visible) ? true : serialized.visible;
|
||||
return serialized;
|
||||
});
|
||||
for (const old of this.loadOldCachedViewlets()) {
|
||||
const cachedViewlet = cachedViewlets.filter(cached => cached.id === old.id)[0];
|
||||
if (cachedViewlet) {
|
||||
cachedViewlet.iconUrl = old.iconUrl;
|
||||
cachedViewlet.views = old.views;
|
||||
}
|
||||
}
|
||||
return cachedViewlets;
|
||||
}
|
||||
|
||||
private loadOldCachedViewlets(): ICachedViewlet[] {
|
||||
const previousState = this.storageService.get('workbench.activity.placeholderViewlets', StorageScope.GLOBAL, '[]');
|
||||
const result = (<ICachedViewlet[]>JSON.parse(previousState));
|
||||
this.storageService.remove('workbench.activity.placeholderViewlets', StorageScope.GLOBAL);
|
||||
return result;
|
||||
}
|
||||
|
||||
private _cachedViewletsValue: string;
|
||||
private get cachedViewletsValue(): string {
|
||||
if (!this._cachedViewletsValue) {
|
||||
this._cachedViewletsValue = this.getStoredCachedViewletsValue();
|
||||
}
|
||||
return this._cachedViewletsValue;
|
||||
}
|
||||
|
||||
private set cachedViewletsValue(cachedViewletsValue: string) {
|
||||
if (this.cachedViewletsValue !== cachedViewletsValue) {
|
||||
this._cachedViewletsValue = cachedViewletsValue;
|
||||
this.setStoredCachedViewletsValue(cachedViewletsValue);
|
||||
}
|
||||
}
|
||||
|
||||
private getStoredCachedViewletsValue(): string {
|
||||
return this.storageService.get(ActivitybarPart.PINNED_VIEWLETS, StorageScope.GLOBAL, '[]');
|
||||
}
|
||||
|
||||
private setStoredCachedViewletsValue(value: string): void {
|
||||
this.storageService.store(ActivitybarPart.PINNED_VIEWLETS, value, StorageScope.GLOBAL);
|
||||
}
|
||||
|
||||
private getViewContainer(viewletId: string): ViewContainer | undefined {
|
||||
@@ -411,4 +501,10 @@ export class ActivitybarPart extends Part {
|
||||
const viewContainerRegistry = Registry.as<IViewContainersRegistry>(ViewContainerExtensions.ViewContainersRegistry);
|
||||
return viewContainerRegistry.get(viewletId);
|
||||
}
|
||||
|
||||
toJSON(): object {
|
||||
return {
|
||||
type: Parts.ACTIVITYBAR_PART
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
.monaco-workbench > .activitybar > .content .monaco-action-bar .action-item {
|
||||
.monaco-workbench .activitybar > .content .monaco-action-bar .action-item {
|
||||
display: block;
|
||||
position: relative;
|
||||
padding: 5px 0;
|
||||
}
|
||||
|
||||
.monaco-workbench > .activitybar > .content .monaco-action-bar .action-label {
|
||||
.monaco-workbench .activitybar > .content .monaco-action-bar .action-label {
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
height: 40px;
|
||||
@@ -20,7 +20,7 @@
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.monaco-workbench > .activitybar > .content .monaco-action-bar .action-item:focus:before {
|
||||
.monaco-workbench .activitybar > .content .monaco-action-bar .action-item:focus:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 9px;
|
||||
@@ -29,19 +29,19 @@
|
||||
border-left: 2px solid;
|
||||
}
|
||||
|
||||
.monaco-workbench > .activitybar > .content .monaco-action-bar .action-item.clicked:focus:before {
|
||||
.monaco-workbench .activitybar > .content .monaco-action-bar .action-item.clicked:focus:before {
|
||||
border-left: none !important; /* no focus feedback when using mouse */
|
||||
}
|
||||
|
||||
.monaco-workbench > .activitybar.left > .content .monaco-action-bar .action-item:focus:before {
|
||||
.monaco-workbench .activitybar.left > .content .monaco-action-bar .action-item:focus:before {
|
||||
left: 1px;
|
||||
}
|
||||
|
||||
.monaco-workbench > .activitybar.right > .content .monaco-action-bar .action-item:focus:before {
|
||||
.monaco-workbench .activitybar.right > .content .monaco-action-bar .action-item:focus:before {
|
||||
right: 1px;
|
||||
}
|
||||
|
||||
.monaco-workbench > .activitybar > .content .monaco-action-bar .badge {
|
||||
.monaco-workbench .activitybar > .content .monaco-action-bar .badge {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
left: 0;
|
||||
@@ -50,7 +50,7 @@
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.monaco-workbench > .activitybar > .content .monaco-action-bar .badge .badge-content {
|
||||
.monaco-workbench .activitybar > .content .monaco-action-bar .badge .badge-content {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
right: 8px;
|
||||
@@ -65,13 +65,13 @@
|
||||
|
||||
/* Right aligned */
|
||||
|
||||
.monaco-workbench > .activitybar.right > .content .monaco-action-bar .action-label {
|
||||
.monaco-workbench .activitybar.right > .content .monaco-action-bar .action-label {
|
||||
margin-left: 0;
|
||||
padding: 0 50px 0 0;
|
||||
background-position: calc(100% - 9px) center;
|
||||
}
|
||||
|
||||
.monaco-workbench > .activitybar.right > .content .monaco-action-bar .badge {
|
||||
.monaco-workbench .activitybar.right > .content .monaco-action-bar .badge {
|
||||
left: auto;
|
||||
right: 0;
|
||||
}
|
||||
@@ -3,23 +3,23 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
.monaco-workbench > .part.activitybar {
|
||||
.monaco-workbench .part.activitybar {
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.monaco-workbench > .activitybar > .content {
|
||||
.monaco-workbench .activitybar > .content {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.monaco-workbench > .activitybar > .content .monaco-action-bar {
|
||||
.monaco-workbench .activitybar > .content .monaco-action-bar {
|
||||
text-align: left;
|
||||
background-color: inherit;
|
||||
}
|
||||
|
||||
.monaco-workbench > .activitybar .action-item:focus {
|
||||
.monaco-workbench .activitybar .action-item:focus {
|
||||
outline: 0 !important; /* activity bar indicates focus custom */
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ import { illegalArgument } from 'vs/base/common/errors';
|
||||
import * as arrays from 'vs/base/common/arrays';
|
||||
import { IDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IBadge } from 'vs/workbench/services/activity/common/activity';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ActionBar, ActionsOrientation, Separator } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { CompositeActionItem, CompositeOverflowActivityAction, ICompositeActivity, CompositeOverflowActivityActionItem, ActivityAction, ICompositeBar, ICompositeBarColors, DraggedCompositeIdentifier } from 'vs/workbench/browser/parts/compositeBarActions';
|
||||
@@ -20,10 +19,18 @@ import { Widget } from 'vs/base/browser/ui/widget';
|
||||
import { isUndefinedOrNull } from 'vs/base/common/types';
|
||||
import { LocalSelectionTransfer } from 'vs/workbench/browser/dnd';
|
||||
import { ITheme } from 'vs/platform/theme/common/themeService';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
|
||||
export interface ICompositeBarItem {
|
||||
id: string;
|
||||
name: string;
|
||||
pinned: boolean;
|
||||
order: number;
|
||||
visible: boolean;
|
||||
}
|
||||
|
||||
export interface ICompositeBarOptions {
|
||||
icon: boolean;
|
||||
storageId: string;
|
||||
orientation: ActionsOrientation;
|
||||
colors: (theme: ITheme) => ICompositeBarColors;
|
||||
compositeSize: number;
|
||||
@@ -32,7 +39,7 @@ export interface ICompositeBarOptions {
|
||||
getCompositePinnedAction: (compositeId: string) => Action;
|
||||
getOnCompositeClickAction: (compositeId: string) => Action;
|
||||
getContextMenuActions: () => Action[];
|
||||
openComposite: (compositeId: string) => Thenable<any>;
|
||||
openComposite: (compositeId: string) => Promise<any>;
|
||||
getDefaultCompositeId: () => string;
|
||||
hidePart: () => void;
|
||||
}
|
||||
@@ -51,24 +58,33 @@ export class CompositeBar extends Widget implements ICompositeBar {
|
||||
|
||||
private compositeTransfer: LocalSelectionTransfer<DraggedCompositeIdentifier>;
|
||||
|
||||
private readonly _onDidChange: Emitter<void> = this._register(new Emitter<void>());
|
||||
readonly onDidChange: Event<void> = this._onDidChange.event;
|
||||
|
||||
constructor(
|
||||
items: ICompositeBarItem[],
|
||||
private options: ICompositeBarOptions,
|
||||
@IInstantiationService private instantiationService: IInstantiationService,
|
||||
@IStorageService storageService: IStorageService,
|
||||
@IContextMenuService private contextMenuService: IContextMenuService
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@IContextMenuService private readonly contextMenuService: IContextMenuService
|
||||
) {
|
||||
super();
|
||||
|
||||
this.model = new CompositeBarModel(options, storageService);
|
||||
this.model = new CompositeBarModel(items, options);
|
||||
this.visibleComposites = [];
|
||||
this.compositeSizeInBar = new Map<string, number>();
|
||||
this.compositeTransfer = LocalSelectionTransfer.getInstance<DraggedCompositeIdentifier>();
|
||||
}
|
||||
|
||||
getComposites(): ICompositeBarItem[] {
|
||||
getCompositeBarItems(): ICompositeBarItem[] {
|
||||
return [...this.model.items];
|
||||
}
|
||||
|
||||
setCompositeBarItems(items: ICompositeBarItem[]): void {
|
||||
if (this.model.setItems(items)) {
|
||||
this.updateCompositeSwitcher();
|
||||
}
|
||||
}
|
||||
|
||||
getPinnedComposites(): ICompositeBarItem[] {
|
||||
return this.model.pinnedItems;
|
||||
}
|
||||
@@ -125,7 +141,7 @@ export class CompositeBar extends Widget implements ICompositeBar {
|
||||
this.updateCompositeSwitcher();
|
||||
}
|
||||
|
||||
addComposite({ id, name, order }: { id: string; name: string, order: number }): void {
|
||||
addComposite({ id, name, order }: { id: string; name: string, order?: number }): void {
|
||||
// Add to the model
|
||||
if (this.model.add(id, name, order)) {
|
||||
this.computeSizes([this.model.findItem(id)]);
|
||||
@@ -254,7 +270,7 @@ export class CompositeBar extends Widget implements ICompositeBar {
|
||||
return item && item.activityAction;
|
||||
}
|
||||
|
||||
private computeSizes(items: ICompositeBarItem[]): void {
|
||||
private computeSizes(items: ICompositeBarModelItem[]): void {
|
||||
const size = this.options.compositeSize;
|
||||
if (size) {
|
||||
items.forEach(composite => this.compositeSizeInBar.set(composite.id, size));
|
||||
@@ -367,7 +383,7 @@ export class CompositeBar extends Widget implements ICompositeBar {
|
||||
CompositeOverflowActivityActionItem,
|
||||
this.compositeOverflowAction,
|
||||
() => this.getOverflowingComposites(),
|
||||
() => this.model.activeItem ? this.model.activeItem.id : void 0,
|
||||
() => this.model.activeItem ? this.model.activeItem.id : undefined,
|
||||
(compositeId: string) => {
|
||||
const item = this.model.findItem(compositeId);
|
||||
return item && item.activity[0] && item.activity[0].badge;
|
||||
@@ -379,8 +395,7 @@ export class CompositeBar extends Widget implements ICompositeBar {
|
||||
this.compositeSwitcherBar.push(this.compositeOverflowAction, { label: false, icon: true });
|
||||
}
|
||||
|
||||
// Persist
|
||||
this.model.saveState();
|
||||
this._onDidChange.fire();
|
||||
}
|
||||
|
||||
private getOverflowingComposites(): { id: string, name: string }[] {
|
||||
@@ -428,15 +443,7 @@ export class CompositeBar extends Widget implements ICompositeBar {
|
||||
}
|
||||
}
|
||||
|
||||
interface ISerializedCompositeBarItem {
|
||||
id: string;
|
||||
pinned: boolean;
|
||||
order: number;
|
||||
visible: boolean;
|
||||
}
|
||||
|
||||
interface ICompositeBarItem extends ISerializedCompositeBarItem {
|
||||
name: string;
|
||||
interface ICompositeBarModelItem extends ICompositeBarItem {
|
||||
activityAction: ActivityAction;
|
||||
pinnedAction: Action;
|
||||
activity: ICompositeActivity[];
|
||||
@@ -444,28 +451,63 @@ interface ICompositeBarItem extends ISerializedCompositeBarItem {
|
||||
|
||||
class CompositeBarModel {
|
||||
|
||||
private _items: ICompositeBarModelItem[];
|
||||
private readonly options: ICompositeBarOptions;
|
||||
readonly items: ICompositeBarItem[];
|
||||
|
||||
activeItem: ICompositeBarItem;
|
||||
activeItem: ICompositeBarModelItem;
|
||||
|
||||
constructor(
|
||||
options: ICompositeBarOptions,
|
||||
private storageService: IStorageService,
|
||||
items: ICompositeBarItem[],
|
||||
options: ICompositeBarOptions
|
||||
) {
|
||||
this.options = options;
|
||||
this.items = this.loadItemStates();
|
||||
this.setItems(items);
|
||||
}
|
||||
|
||||
get visibleItems(): ICompositeBarItem[] {
|
||||
get items(): ICompositeBarModelItem[] {
|
||||
return this._items;
|
||||
}
|
||||
|
||||
setItems(items: ICompositeBarItem[]): boolean {
|
||||
const result: ICompositeBarModelItem[] = [];
|
||||
let hasChanges: boolean = false;
|
||||
if (!this.items || this.items.length === 0) {
|
||||
this._items = items.map(i => this.createCompositeBarItem(i.id, i.name, i.order, i.pinned, i.visible));
|
||||
hasChanges = true;
|
||||
} else {
|
||||
const existingItems = this.items;
|
||||
for (let index = 0; index < items.length; index++) {
|
||||
const newItem = items[index];
|
||||
const existingItem = existingItems.filter(({ id }) => id === newItem.id)[0];
|
||||
if (existingItem) {
|
||||
if (
|
||||
existingItem.pinned !== newItem.pinned ||
|
||||
index !== existingItems.indexOf(existingItem)
|
||||
) {
|
||||
existingItem.pinned = newItem.pinned;
|
||||
result.push(existingItem);
|
||||
hasChanges = true;
|
||||
} else {
|
||||
result.push(existingItem);
|
||||
}
|
||||
} else {
|
||||
result.push(this.createCompositeBarItem(newItem.id, newItem.name, newItem.order, newItem.pinned, newItem.visible));
|
||||
hasChanges = true;
|
||||
}
|
||||
}
|
||||
this._items = result;
|
||||
}
|
||||
return hasChanges;
|
||||
}
|
||||
|
||||
get visibleItems(): ICompositeBarModelItem[] {
|
||||
return this.items.filter(item => item.visible);
|
||||
}
|
||||
|
||||
get pinnedItems(): ICompositeBarItem[] {
|
||||
get pinnedItems(): ICompositeBarModelItem[] {
|
||||
return this.items.filter(item => item.visible && item.pinned);
|
||||
}
|
||||
|
||||
private createCompositeBarItem(id: string, name: string, order: number, pinned: boolean, visible: boolean): ICompositeBarItem {
|
||||
private createCompositeBarItem(id: string, name: string, order: number, pinned: boolean, visible: boolean): ICompositeBarModelItem {
|
||||
const options = this.options;
|
||||
return {
|
||||
id, name, pinned, order, visible,
|
||||
@@ -551,8 +593,7 @@ class CompositeBarModel {
|
||||
}
|
||||
|
||||
setPinned(id: string, pinned: boolean): boolean {
|
||||
for (let index = 0; index < this.items.length; index++) {
|
||||
const item = this.items[index];
|
||||
for (const item of this.items) {
|
||||
if (item.id === id) {
|
||||
if (item.pinned !== pinned) {
|
||||
item.pinned = pinned;
|
||||
@@ -614,8 +655,7 @@ class CompositeBarModel {
|
||||
if (this.activeItem) {
|
||||
this.deactivate();
|
||||
}
|
||||
for (let index = 0; index < this.items.length; index++) {
|
||||
const item = this.items[index];
|
||||
for (const item of this.items) {
|
||||
if (item.id === id) {
|
||||
this.activeItem = item;
|
||||
this.activeItem.activityAction.activate();
|
||||
@@ -629,13 +669,13 @@ class CompositeBarModel {
|
||||
deactivate(): boolean {
|
||||
if (this.activeItem) {
|
||||
this.activeItem.activityAction.deactivate();
|
||||
this.activeItem = void 0;
|
||||
this.activeItem = undefined;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
findItem(id: string): ICompositeBarItem {
|
||||
findItem(id: string): ICompositeBarModelItem {
|
||||
return this.items.filter(item => item.id === id)[0];
|
||||
}
|
||||
|
||||
@@ -647,17 +687,4 @@ class CompositeBarModel {
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private loadItemStates(): ICompositeBarItem[] {
|
||||
const storedStates = <Array<string | ISerializedCompositeBarItem>>JSON.parse(this.storageService.get(this.options.storageId, StorageScope.GLOBAL, '[]'));
|
||||
return <ICompositeBarItem[]>storedStates.map(c => {
|
||||
const serialized: ISerializedCompositeBarItem = typeof c === 'string' /* migration from pinned states to composites states */ ? { id: c, pinned: true, order: void 0, visible: true } : c;
|
||||
return this.createCompositeBarItem(serialized.id, void 0, serialized.order, serialized.pinned, isUndefinedOrNull(serialized.visible) ? true : serialized.visible);
|
||||
});
|
||||
}
|
||||
|
||||
saveState(): void {
|
||||
const serialized = this.items.map(({ id, pinned, order, visible }) => ({ id, pinned, order, visible }));
|
||||
this.storageService.store(this.options.storageId, JSON.stringify(serialized), StorageScope.GLOBAL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,7 +207,7 @@ export class ActivityActionItem extends BaseActionItem {
|
||||
}));
|
||||
|
||||
// Label
|
||||
this.label = dom.append(this.element, dom.$('a.action-label'));
|
||||
this.label = dom.append(this.element, dom.$('a'));
|
||||
|
||||
// Badge
|
||||
this.badge = dom.append(this.element, dom.$('.badge'));
|
||||
@@ -301,8 +301,9 @@ export class ActivityActionItem extends BaseActionItem {
|
||||
}
|
||||
|
||||
protected updateLabel(): void {
|
||||
this.label.className = 'action-label';
|
||||
if (this.activity.cssClass) {
|
||||
dom.addClasses(this.label, this.activity.cssClass);
|
||||
dom.addClass(this.label, this.activity.cssClass);
|
||||
}
|
||||
if (!this.options.icon) {
|
||||
this.label.textContent = this.getAction().label;
|
||||
@@ -358,7 +359,7 @@ export class CompositeOverflowActivityActionItem extends ActivityActionItem {
|
||||
private getBadge: (compositeId: string) => IBadge,
|
||||
private getCompositeOpenAction: (compositeId: string) => Action,
|
||||
colors: (theme: ITheme) => ICompositeBarColors,
|
||||
@IContextMenuService private contextMenuService: IContextMenuService,
|
||||
@IContextMenuService private readonly contextMenuService: IContextMenuService,
|
||||
@IThemeService themeService: IThemeService
|
||||
) {
|
||||
super(action, { icon: true, colors }, themeService);
|
||||
@@ -411,7 +412,7 @@ export class CompositeOverflowActivityActionItem extends ActivityActionItem {
|
||||
class ManageExtensionAction extends Action {
|
||||
|
||||
constructor(
|
||||
@ICommandService private commandService: ICommandService
|
||||
@ICommandService private readonly commandService: ICommandService
|
||||
) {
|
||||
super('activitybar.manage.extension', nls.localize('manageExtension', "Manage Extension"));
|
||||
}
|
||||
@@ -434,7 +435,6 @@ export class CompositeActionItem extends ActivityActionItem {
|
||||
private static manageExtensionAction: ManageExtensionAction;
|
||||
|
||||
private compositeActivity: IActivity;
|
||||
private cssClass: string;
|
||||
private compositeTransfer: LocalSelectionTransfer<DraggedCompositeIdentifier>;
|
||||
|
||||
constructor(
|
||||
@@ -444,14 +444,13 @@ export class CompositeActionItem extends ActivityActionItem {
|
||||
colors: (theme: ITheme) => ICompositeBarColors,
|
||||
icon: boolean,
|
||||
private compositeBar: ICompositeBar,
|
||||
@IContextMenuService private contextMenuService: IContextMenuService,
|
||||
@IKeybindingService private keybindingService: IKeybindingService,
|
||||
@IContextMenuService private readonly contextMenuService: IContextMenuService,
|
||||
@IKeybindingService private readonly keybindingService: IKeybindingService,
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@IThemeService themeService: IThemeService
|
||||
) {
|
||||
super(compositeActivityAction, { draggable: true, colors, icon }, themeService);
|
||||
|
||||
this.cssClass = compositeActivityAction.class;
|
||||
this.compositeTransfer = LocalSelectionTransfer.getInstance<DraggedCompositeIdentifier>();
|
||||
|
||||
if (!CompositeActionItem.manageExtensionAction) {
|
||||
@@ -473,7 +472,7 @@ export class CompositeActionItem extends ActivityActionItem {
|
||||
|
||||
this.compositeActivity = {
|
||||
id: this.compositeActivityAction.activity.id,
|
||||
cssClass: this.cssClass,
|
||||
cssClass: this.compositeActivityAction.activity.cssClass,
|
||||
name: activityName
|
||||
};
|
||||
}
|
||||
@@ -606,17 +605,6 @@ export class CompositeActionItem extends ActivityActionItem {
|
||||
this.container.focus();
|
||||
}
|
||||
|
||||
protected updateClass(): void {
|
||||
if (this.cssClass) {
|
||||
dom.removeClasses(this.label, this.cssClass);
|
||||
}
|
||||
|
||||
this.cssClass = this.getAction().class;
|
||||
if (this.cssClass) {
|
||||
dom.addClasses(this.label, this.cssClass);
|
||||
}
|
||||
}
|
||||
|
||||
protected updateChecked(): void {
|
||||
if (this.getAction().checked) {
|
||||
dom.addClass(this.container, 'checked');
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import 'vs/css!./media/compositepart';
|
||||
import * as nls from 'vs/nls';
|
||||
import { defaultGenerator } from 'vs/base/common/idGenerator';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import * as strings from 'vs/base/common/strings';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
import * as errors from 'vs/base/common/errors';
|
||||
@@ -46,6 +46,12 @@ export interface ICompositeTitleLabel {
|
||||
updateStyles(): void;
|
||||
}
|
||||
|
||||
interface CompositeItem {
|
||||
composite: Composite;
|
||||
disposable: IDisposable;
|
||||
progressService: IProgressService;
|
||||
}
|
||||
|
||||
export abstract class CompositePart<T extends Composite> extends Part {
|
||||
|
||||
protected _onDidCompositeOpen = this._register(new Emitter<{ composite: IComposite, focus: boolean }>());
|
||||
@@ -53,22 +59,20 @@ export abstract class CompositePart<T extends Composite> extends Part {
|
||||
|
||||
protected toolBar: ToolBar;
|
||||
|
||||
private instantiatedCompositeListeners: IDisposable[];
|
||||
private mapCompositeToCompositeContainer: { [compositeId: string]: HTMLElement; };
|
||||
private mapActionsBindingToComposite: { [compositeId: string]: () => void; };
|
||||
private mapProgressServiceToComposite: { [compositeId: string]: IProgressService; };
|
||||
private activeComposite: Composite;
|
||||
private activeComposite: Composite | null;
|
||||
private lastActiveCompositeId: string;
|
||||
private instantiatedComposites: Composite[];
|
||||
private instantiatedCompositeItems: Map<string, CompositeItem>;
|
||||
private titleLabel: ICompositeTitleLabel;
|
||||
private progressBar: ProgressBar;
|
||||
private contentAreaSize: Dimension;
|
||||
private telemetryActionsListener: IDisposable;
|
||||
private telemetryActionsListener: IDisposable | null;
|
||||
private currentCompositeOpenToken: string;
|
||||
|
||||
constructor(
|
||||
private notificationService: INotificationService,
|
||||
private storageService: IStorageService,
|
||||
protected storageService: IStorageService,
|
||||
private telemetryService: ITelemetryService,
|
||||
protected contextMenuService: IContextMenuService,
|
||||
protected partService: IPartService,
|
||||
@@ -86,16 +90,14 @@ export abstract class CompositePart<T extends Composite> extends Part {
|
||||
) {
|
||||
super(id, options, themeService, storageService);
|
||||
|
||||
this.instantiatedCompositeListeners = [];
|
||||
this.mapCompositeToCompositeContainer = {};
|
||||
this.mapActionsBindingToComposite = {};
|
||||
this.mapProgressServiceToComposite = {};
|
||||
this.activeComposite = null;
|
||||
this.instantiatedComposites = [];
|
||||
this.instantiatedCompositeItems = new Map<string, CompositeItem>();
|
||||
this.lastActiveCompositeId = storageService.get(activeCompositeSettingsKey, StorageScope.WORKSPACE, this.defaultCompositeId);
|
||||
}
|
||||
|
||||
protected openComposite(id: string, focus?: boolean): Composite {
|
||||
protected openComposite(id: string, focus?: boolean): Composite | undefined {
|
||||
// Check if composite already visible and just focus in that case
|
||||
if (this.activeComposite && this.activeComposite.getId() === id) {
|
||||
if (focus) {
|
||||
@@ -110,7 +112,7 @@ export abstract class CompositePart<T extends Composite> extends Part {
|
||||
return this.doOpenComposite(id, focus);
|
||||
}
|
||||
|
||||
private doOpenComposite(id: string, focus?: boolean): Composite {
|
||||
private doOpenComposite(id: string, focus: boolean = false): Composite | undefined {
|
||||
|
||||
// Use a generated token to avoid race conditions from long running promises
|
||||
const currentCompositeOpenToken = defaultGenerator.nextId();
|
||||
@@ -159,10 +161,9 @@ export abstract class CompositePart<T extends Composite> extends Part {
|
||||
protected createComposite(id: string, isActive?: boolean): Composite {
|
||||
|
||||
// Check if composite is already created
|
||||
for (let i = 0; i < this.instantiatedComposites.length; i++) {
|
||||
if (this.instantiatedComposites[i].getId() === id) {
|
||||
return this.instantiatedComposites[i];
|
||||
}
|
||||
const compositeItem = this.instantiatedCompositeItems.get(id);
|
||||
if (compositeItem) {
|
||||
return compositeItem.composite;
|
||||
}
|
||||
|
||||
// Instantiate composite from registry otherwise
|
||||
@@ -172,18 +173,18 @@ export abstract class CompositePart<T extends Composite> extends Part {
|
||||
const compositeInstantiationService = this.instantiationService.createChild(new ServiceCollection([IProgressService, progressService]));
|
||||
|
||||
const composite = compositeDescriptor.instantiate(compositeInstantiationService);
|
||||
this.mapProgressServiceToComposite[composite.getId()] = progressService;
|
||||
const disposables: IDisposable[] = [];
|
||||
|
||||
// Remember as Instantiated
|
||||
this.instantiatedComposites.push(composite);
|
||||
this.instantiatedCompositeItems.set(id, { composite, disposable: toDisposable(() => dispose(disposables)), progressService });
|
||||
|
||||
// Register to title area update events from the composite
|
||||
this.instantiatedCompositeListeners.push(composite.onTitleAreaUpdate(() => this.onTitleAreaUpdate(composite.getId())));
|
||||
composite.onTitleAreaUpdate(() => this.onTitleAreaUpdate(composite.getId()), this, disposables);
|
||||
|
||||
return composite;
|
||||
}
|
||||
|
||||
throw new Error(strings.format('Unable to find composite with id {0}', id));
|
||||
throw new Error(`Unable to find composite with id ${id}`);
|
||||
}
|
||||
|
||||
protected showComposite(composite: Composite): void {
|
||||
@@ -219,19 +220,22 @@ export abstract class CompositePart<T extends Composite> extends Part {
|
||||
}
|
||||
|
||||
// Report progress for slow loading composites (but only if we did not create the composites before already)
|
||||
const progressService = this.mapProgressServiceToComposite[composite.getId()];
|
||||
if (progressService && !compositeContainer) {
|
||||
this.mapProgressServiceToComposite[composite.getId()].showWhile(Promise.resolve(), this.partService.isRestored() ? 800 : 3200 /* less ugly initial startup */);
|
||||
const compositeItem = this.instantiatedCompositeItems.get(composite.getId());
|
||||
if (compositeItem && !compositeContainer) {
|
||||
compositeItem.progressService.showWhile(Promise.resolve(), this.partService.isRestored() ? 800 : 3200 /* less ugly initial startup */);
|
||||
}
|
||||
|
||||
// Fill Content and Actions
|
||||
// Make sure that the user meanwhile did not open another composite or closed the part containing the composite
|
||||
if (!this.activeComposite || composite.getId() !== this.activeComposite.getId()) {
|
||||
return void 0;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Take Composite on-DOM and show
|
||||
this.getContentArea().appendChild(compositeContainer);
|
||||
const contentArea = this.getContentArea();
|
||||
if (contentArea) {
|
||||
contentArea.appendChild(compositeContainer);
|
||||
}
|
||||
show(compositeContainer);
|
||||
|
||||
// Setup action runner
|
||||
@@ -240,7 +244,7 @@ export abstract class CompositePart<T extends Composite> extends Part {
|
||||
// Update title with composite title if it differs from descriptor
|
||||
const descriptor = this.registry.getComposite(composite.getId());
|
||||
if (descriptor && descriptor.name !== composite.getTitle()) {
|
||||
this.updateTitle(composite.getId(), composite.getTitle());
|
||||
this.updateTitle(composite.getId(), composite.getTitle() || undefined);
|
||||
}
|
||||
|
||||
// Handle Composite Actions
|
||||
@@ -296,7 +300,7 @@ export abstract class CompositePart<T extends Composite> extends Part {
|
||||
if (this.activeComposite && this.activeComposite.getId() === compositeId) {
|
||||
|
||||
// Title
|
||||
this.updateTitle(this.activeComposite.getId(), this.activeComposite.getTitle());
|
||||
this.updateTitle(this.activeComposite.getId(), this.activeComposite.getTitle() || undefined);
|
||||
|
||||
// Actions
|
||||
const actionsBinding = this.collectCompositeActions(this.activeComposite);
|
||||
@@ -322,7 +326,7 @@ export abstract class CompositePart<T extends Composite> extends Part {
|
||||
|
||||
const keybinding = this.keybindingService.lookupKeybinding(compositeId);
|
||||
|
||||
this.titleLabel.updateTitle(compositeId, compositeTitle, keybinding ? keybinding.getLabel() : undefined);
|
||||
this.titleLabel.updateTitle(compositeId, compositeTitle, (keybinding && keybinding.getLabel()) || undefined);
|
||||
|
||||
this.toolBar.setAriaLabel(nls.localize('ariaCompositeToolbarLabel', "{0} actions", compositeTitle));
|
||||
}
|
||||
@@ -341,7 +345,7 @@ export abstract class CompositePart<T extends Composite> extends Part {
|
||||
return this.toolBar.setActions(prepareActions(primaryActions), prepareActions(secondaryActions));
|
||||
}
|
||||
|
||||
protected getActiveComposite(): IComposite {
|
||||
protected getActiveComposite(): IComposite | null {
|
||||
return this.activeComposite;
|
||||
}
|
||||
|
||||
@@ -349,7 +353,7 @@ export abstract class CompositePart<T extends Composite> extends Part {
|
||||
return this.lastActiveCompositeId;
|
||||
}
|
||||
|
||||
protected hideActiveComposite(): Composite {
|
||||
protected hideActiveComposite(): Composite | undefined {
|
||||
if (!this.activeComposite) {
|
||||
return undefined; // Nothing to do
|
||||
}
|
||||
@@ -423,14 +427,14 @@ export abstract class CompositePart<T extends Composite> extends Part {
|
||||
this.titleLabel.updateStyles();
|
||||
}
|
||||
|
||||
protected actionItemProvider(action: Action): IActionItem {
|
||||
protected actionItemProvider(action: Action): IActionItem | null {
|
||||
|
||||
// Check Active Composite
|
||||
if (this.activeComposite) {
|
||||
return this.activeComposite.getActionItem(action);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
return null;
|
||||
}
|
||||
|
||||
createContentArea(parent: HTMLElement): HTMLElement {
|
||||
@@ -443,8 +447,9 @@ export abstract class CompositePart<T extends Composite> extends Part {
|
||||
return contentContainer;
|
||||
}
|
||||
|
||||
getProgressIndicator(id: string): IProgressService {
|
||||
return this.mapProgressServiceToComposite[id];
|
||||
getProgressIndicator(id: string): IProgressService | null {
|
||||
const compositeItem = this.instantiatedCompositeItems.get(id);
|
||||
return compositeItem ? compositeItem.progressService : null;
|
||||
}
|
||||
|
||||
protected getActions(): IAction[] {
|
||||
@@ -459,10 +464,11 @@ export abstract class CompositePart<T extends Composite> extends Part {
|
||||
return AnchorAlignment.RIGHT;
|
||||
}
|
||||
|
||||
layout(dimension: Dimension): Dimension[] {
|
||||
|
||||
layout(dimension: Dimension): Dimension[];
|
||||
layout(width: number, height: number): void;
|
||||
layout(dim1: Dimension | number, dim2?: number): Dimension[] | void {
|
||||
// Pass to super
|
||||
const sizes = super.layout(dimension);
|
||||
const sizes = super.layout(dim1 instanceof Dimension ? dim1 : new Dimension(dim1, dim2!));
|
||||
|
||||
// Pass Contentsize to composite
|
||||
this.contentAreaSize = sizes[1];
|
||||
@@ -470,20 +476,38 @@ export abstract class CompositePart<T extends Composite> extends Part {
|
||||
this.activeComposite.layout(this.contentAreaSize);
|
||||
}
|
||||
|
||||
return sizes;
|
||||
if (dim1 instanceof Dimension) {
|
||||
return sizes;
|
||||
}
|
||||
}
|
||||
|
||||
protected removeComposite(compositeId: string): boolean {
|
||||
if (this.activeComposite && this.activeComposite.getId() === compositeId) {
|
||||
// do not remove active compoiste
|
||||
return false;
|
||||
}
|
||||
|
||||
delete this.mapCompositeToCompositeContainer[compositeId];
|
||||
delete this.mapActionsBindingToComposite[compositeId];
|
||||
const compositeItem = this.instantiatedCompositeItems.get(compositeId);
|
||||
if (compositeItem) {
|
||||
compositeItem.composite.dispose();
|
||||
dispose(compositeItem.disposable);
|
||||
this.instantiatedCompositeItems.delete(compositeId);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this.mapCompositeToCompositeContainer = null;
|
||||
this.mapProgressServiceToComposite = null;
|
||||
this.mapActionsBindingToComposite = null;
|
||||
this.mapCompositeToCompositeContainer = null!; // StrictNullOverride: nulling out ok in dispose
|
||||
this.mapActionsBindingToComposite = null!; // StrictNullOverride: nulling out ok in dispose
|
||||
|
||||
for (let i = 0; i < this.instantiatedComposites.length; i++) {
|
||||
this.instantiatedComposites[i].dispose();
|
||||
}
|
||||
this.instantiatedCompositeItems.forEach(compositeItem => {
|
||||
compositeItem.composite.dispose();
|
||||
dispose(compositeItem.disposable);
|
||||
});
|
||||
|
||||
this.instantiatedComposites = [];
|
||||
this.instantiatedCompositeListeners = dispose(this.instantiatedCompositeListeners);
|
||||
this.instantiatedCompositeItems.clear();
|
||||
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import { IEditorGroup, IEditorGroupsService } from 'vs/workbench/services/group/
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { LRUCache } from 'vs/base/common/map';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { once, Event } from 'vs/base/common/event';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { isEmptyObject } from 'vs/base/common/types';
|
||||
import { DEFAULT_EDITOR_MIN_DIMENSIONS, DEFAULT_EDITOR_MAX_DIMENSIONS } from 'vs/workbench/browser/parts/editor/editor';
|
||||
|
||||
@@ -38,12 +38,12 @@ export abstract class BaseEditor extends Panel implements IEditor {
|
||||
readonly minimumHeight = DEFAULT_EDITOR_MIN_DIMENSIONS.height;
|
||||
readonly maximumHeight = DEFAULT_EDITOR_MAX_DIMENSIONS.height;
|
||||
|
||||
readonly onDidSizeConstraintsChange: Event<{ width: number; height: number; }> = Event.None;
|
||||
readonly onDidSizeConstraintsChange: Event<{ width: number; height: number; } | undefined> = Event.None;
|
||||
|
||||
protected _input: EditorInput;
|
||||
protected _options: EditorOptions;
|
||||
protected _input: EditorInput | null;
|
||||
protected _options: EditorOptions | null;
|
||||
|
||||
private _group: IEditorGroup;
|
||||
private _group?: IEditorGroup;
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
@@ -54,15 +54,15 @@ export abstract class BaseEditor extends Panel implements IEditor {
|
||||
super(id, telemetryService, themeService, storageService);
|
||||
}
|
||||
|
||||
get input(): EditorInput {
|
||||
get input(): EditorInput | null {
|
||||
return this._input;
|
||||
}
|
||||
|
||||
get options(): EditorOptions {
|
||||
get options(): EditorOptions | null {
|
||||
return this._options;
|
||||
}
|
||||
|
||||
get group(): IEditorGroup {
|
||||
get group(): IEditorGroup | undefined {
|
||||
return this._group;
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ export abstract class BaseEditor extends Panel implements IEditor {
|
||||
* The provided cancellation token should be used to test if the operation
|
||||
* was cancelled.
|
||||
*/
|
||||
setInput(input: EditorInput, options: EditorOptions, token: CancellationToken): Thenable<void> {
|
||||
setInput(input: EditorInput, options: EditorOptions | null, token: CancellationToken): Promise<void> {
|
||||
this._input = input;
|
||||
this._options = options;
|
||||
|
||||
@@ -100,7 +100,7 @@ export abstract class BaseEditor extends Panel implements IEditor {
|
||||
* Sets the given options to the editor. Clients should apply the options
|
||||
* to the current input.
|
||||
*/
|
||||
setOptions(options: EditorOptions): void {
|
||||
setOptions(options: EditorOptions | null): void {
|
||||
this._options = options;
|
||||
}
|
||||
|
||||
@@ -118,6 +118,7 @@ export abstract class BaseEditor extends Panel implements IEditor {
|
||||
|
||||
setVisible(visible: boolean, group?: IEditorGroup): void {
|
||||
super.setVisible(visible);
|
||||
|
||||
// Propagate to Editor
|
||||
this.setEditorVisible(visible, group);
|
||||
}
|
||||
@@ -129,7 +130,7 @@ export abstract class BaseEditor extends Panel implements IEditor {
|
||||
* @param visible the state of visibility of this editor
|
||||
* @param group the editor group this editor is in.
|
||||
*/
|
||||
protected setEditorVisible(visible: boolean, group: IEditorGroup): void {
|
||||
protected setEditorVisible(visible: boolean, group: IEditorGroup | undefined): void {
|
||||
this._group = group;
|
||||
}
|
||||
|
||||
@@ -205,18 +206,18 @@ export class EditorMemento<T> implements IEditorMemento<T> {
|
||||
|
||||
// Automatically clear when editor input gets disposed if any
|
||||
if (resourceOrEditor instanceof EditorInput) {
|
||||
once(resourceOrEditor.onDispose)(() => {
|
||||
Event.once(resourceOrEditor.onDispose)(() => {
|
||||
this.clearEditorState(resource);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
loadEditorState(group: IEditorGroup, resource: URI): T;
|
||||
loadEditorState(group: IEditorGroup, editor: EditorInput): T;
|
||||
loadEditorState(group: IEditorGroup, resourceOrEditor: URI | EditorInput): T {
|
||||
loadEditorState(group: IEditorGroup, resource: URI): T | undefined;
|
||||
loadEditorState(group: IEditorGroup, editor: EditorInput): T | undefined;
|
||||
loadEditorState(group: IEditorGroup, resourceOrEditor: URI | EditorInput): T | undefined {
|
||||
const resource = this.doGetResource(resourceOrEditor);
|
||||
if (!resource || !group) {
|
||||
return void 0; // we are not in a good state to load any state for a resource
|
||||
return undefined; // we are not in a good state to load any state for a resource
|
||||
}
|
||||
|
||||
const cache = this.doLoad();
|
||||
@@ -226,7 +227,7 @@ export class EditorMemento<T> implements IEditorMemento<T> {
|
||||
return mementoForResource[group.id];
|
||||
}
|
||||
|
||||
return void 0;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
clearEditorState(resource: URI, group?: IEditorGroup): void;
|
||||
@@ -247,7 +248,7 @@ export class EditorMemento<T> implements IEditorMemento<T> {
|
||||
}
|
||||
}
|
||||
|
||||
private doGetResource(resourceOrEditor: URI | EditorInput): URI {
|
||||
private doGetResource(resourceOrEditor: URI | EditorInput): URI | null {
|
||||
if (resourceOrEditor instanceof EditorInput) {
|
||||
return resourceOrEditor.getResource();
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ export class BinaryResourceDiffEditor extends SideBySideEditor {
|
||||
super(telemetryService, instantiationService, themeService, storageService);
|
||||
}
|
||||
|
||||
getMetadata(): string {
|
||||
getMetadata(): string | null {
|
||||
const master = this.masterEditor;
|
||||
const details = this.detailsEditor;
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ import { dispose } from 'vs/base/common/lifecycle';
|
||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
|
||||
export interface IOpenCallbacks {
|
||||
openInternal: (input: EditorInput, options: EditorOptions) => Thenable<void>;
|
||||
openInternal: (input: EditorInput, options: EditorOptions) => Promise<void>;
|
||||
openExternal: (uri: URI) => void;
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ export abstract class BaseBinaryResourceEditor extends BaseEditor {
|
||||
get onDidOpenInPlace(): Event<void> { return this._onDidOpenInPlace.event; }
|
||||
|
||||
private callbacks: IOpenCallbacks;
|
||||
private metadata: string;
|
||||
private metadata: string | null;
|
||||
private binaryContainer: HTMLElement;
|
||||
private scrollbar: DomScrollableElement;
|
||||
private resourceViewerContext: ResourceViewerContext;
|
||||
@@ -55,7 +55,7 @@ export abstract class BaseBinaryResourceEditor extends BaseEditor {
|
||||
this.callbacks = callbacks;
|
||||
}
|
||||
|
||||
getTitle(): string {
|
||||
getTitle() {
|
||||
return this.input ? this.input.getName() : nls.localize('binaryEditor', "Binary Viewer");
|
||||
}
|
||||
|
||||
@@ -72,13 +72,13 @@ export abstract class BaseBinaryResourceEditor extends BaseEditor {
|
||||
parent.appendChild(this.scrollbar.getDomNode());
|
||||
}
|
||||
|
||||
setInput(input: EditorInput, options: EditorOptions, token: CancellationToken): Thenable<void> {
|
||||
setInput(input: EditorInput, options: EditorOptions, token: CancellationToken): Promise<void> {
|
||||
return super.setInput(input, options, token).then(() => {
|
||||
return input.resolve().then(model => {
|
||||
|
||||
// Check for cancellation
|
||||
if (token.isCancellationRequested) {
|
||||
return void 0;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Assert Model instance
|
||||
@@ -97,7 +97,7 @@ export abstract class BaseBinaryResourceEditor extends BaseEditor {
|
||||
meta => this.handleMetadataChanged(meta)
|
||||
);
|
||||
|
||||
return void 0;
|
||||
return undefined;
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -110,13 +110,13 @@ export abstract class BaseBinaryResourceEditor extends BaseEditor {
|
||||
});
|
||||
}
|
||||
|
||||
private handleMetadataChanged(meta: string): void {
|
||||
private handleMetadataChanged(meta: string | null): void {
|
||||
this.metadata = meta;
|
||||
|
||||
this._onMetadataChanged.fire();
|
||||
}
|
||||
|
||||
getMetadata(): string {
|
||||
getMetadata() {
|
||||
return this.metadata;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ export interface IBreadcrumbsService {
|
||||
|
||||
register(group: GroupIdentifier, widget: BreadcrumbsWidget): IDisposable;
|
||||
|
||||
getWidget(group: GroupIdentifier): BreadcrumbsWidget;
|
||||
getWidget(group: GroupIdentifier): BreadcrumbsWidget | undefined;
|
||||
}
|
||||
|
||||
|
||||
@@ -43,12 +43,12 @@ export class BreadcrumbsService implements IBreadcrumbsService {
|
||||
};
|
||||
}
|
||||
|
||||
getWidget(group: number): BreadcrumbsWidget {
|
||||
getWidget(group: number): BreadcrumbsWidget | undefined {
|
||||
return this._map.get(group);
|
||||
}
|
||||
}
|
||||
|
||||
registerSingleton(IBreadcrumbsService, BreadcrumbsService);
|
||||
registerSingleton(IBreadcrumbsService, BreadcrumbsService, true);
|
||||
|
||||
|
||||
//#region config
|
||||
@@ -59,7 +59,7 @@ export abstract class BreadcrumbsConfig<T> {
|
||||
onDidChange: Event<void>;
|
||||
|
||||
abstract getValue(overrides?: IConfigurationOverrides): T;
|
||||
abstract updateValue(value: T, overrides?: IConfigurationOverrides): Thenable<void>;
|
||||
abstract updateValue(value: T, overrides?: IConfigurationOverrides): Promise<void>;
|
||||
abstract dispose(): void;
|
||||
|
||||
private constructor() {
|
||||
@@ -90,10 +90,18 @@ export abstract class BreadcrumbsConfig<T> {
|
||||
readonly name = name;
|
||||
readonly onDidChange = onDidChange.event;
|
||||
getValue(overrides?: IConfigurationOverrides): T {
|
||||
return service.getValue(name, overrides);
|
||||
if (overrides) {
|
||||
return service.getValue(name, overrides);
|
||||
} else {
|
||||
return service.getValue(name);
|
||||
}
|
||||
}
|
||||
updateValue(newValue: T, overrides?: IConfigurationOverrides): Thenable<void> {
|
||||
return service.updateValue(name, newValue, overrides);
|
||||
updateValue(newValue: T, overrides?: IConfigurationOverrides): Promise<void> {
|
||||
if (overrides) {
|
||||
return service.updateValue(name, newValue, overrides);
|
||||
} else {
|
||||
return service.updateValue(name, newValue);
|
||||
}
|
||||
}
|
||||
dispose(): void {
|
||||
listener.dispose();
|
||||
@@ -112,7 +120,7 @@ Registry.as<IConfigurationRegistry>(Extensions.Configuration).registerConfigurat
|
||||
type: 'object',
|
||||
properties: {
|
||||
'breadcrumbs.enabled': {
|
||||
description: localize('enabled', "Enable/disable navigation breadcrumbs"),
|
||||
description: localize('enabled', "Enable/disable navigation breadcrumbs."),
|
||||
type: 'boolean',
|
||||
default: false
|
||||
},
|
||||
|
||||
@@ -35,7 +35,7 @@ import { ColorIdentifier, ColorFunction } from 'vs/platform/theme/common/colorRe
|
||||
import { attachBreadcrumbsStyler } from 'vs/platform/theme/common/styler';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
import { FileLabel } from 'vs/workbench/browser/labels';
|
||||
import { ResourceLabel } from 'vs/workbench/browser/labels';
|
||||
import { BreadcrumbsConfig, IBreadcrumbsService } from 'vs/workbench/browser/parts/editor/breadcrumbs';
|
||||
import { BreadcrumbElement, EditorBreadcrumbsModel, FileElement } from 'vs/workbench/browser/parts/editor/breadcrumbsModel';
|
||||
import { BreadcrumbsPicker, createBreadcrumbsPicker } from 'vs/workbench/browser/parts/editor/breadcrumbsPicker';
|
||||
@@ -78,8 +78,8 @@ class Item extends BreadcrumbsItem {
|
||||
render(container: HTMLElement): void {
|
||||
if (this.element instanceof FileElement) {
|
||||
// file/folder
|
||||
let label = this._instantiationService.createInstance(FileLabel, container, {});
|
||||
label.setFile(this.element.uri, {
|
||||
let label = this._instantiationService.createInstance(ResourceLabel, container, {});
|
||||
label.element.setFile(this.element.uri, {
|
||||
hidePath: true,
|
||||
hideIcon: this.element.kind === FileKind.FOLDER || !this.options.showFileIcons,
|
||||
fileKind: this.element.kind,
|
||||
@@ -98,7 +98,7 @@ class Item extends BreadcrumbsItem {
|
||||
} else if (this.element instanceof OutlineGroup) {
|
||||
// provider
|
||||
let label = new IconLabel(container);
|
||||
label.setValue(this.element.provider.displayName);
|
||||
label.setLabel(this.element.provider.displayName);
|
||||
this._disposables.push(label);
|
||||
|
||||
} else if (this.element instanceof OutlineElement) {
|
||||
@@ -111,7 +111,7 @@ class Item extends BreadcrumbsItem {
|
||||
}
|
||||
let label = new IconLabel(container);
|
||||
let title = this.element.symbol.name.replace(/\r|\n|\r\n/g, '\u23CE');
|
||||
label.setValue(title);
|
||||
label.setLabel(title);
|
||||
this._disposables.push(label);
|
||||
}
|
||||
}
|
||||
@@ -356,7 +356,7 @@ export class BreadcrumbsControl {
|
||||
},
|
||||
getAnchor: () => {
|
||||
let maxInnerWidth = window.innerWidth - 8 /*a little less the full widget*/;
|
||||
let maxHeight = Math.min(window.innerHeight * .7, 300);
|
||||
let maxHeight = Math.min(window.innerHeight * 0.7, 300);
|
||||
|
||||
let pickerWidth = Math.min(maxInnerWidth, Math.max(240, maxInnerWidth / 4.17));
|
||||
let pickerArrowSize = 8;
|
||||
@@ -379,7 +379,7 @@ export class BreadcrumbsControl {
|
||||
pickerArrowOffset = maxPickerArrowOffset;
|
||||
}
|
||||
} else {
|
||||
pickerArrowOffset = (data.left + (data.width * .3)) - x;
|
||||
pickerArrowOffset = (data.left + (data.width * 0.3)) - x;
|
||||
}
|
||||
picker.setInput(element, maxHeight, pickerWidth, pickerArrowSize, Math.max(0, pickerArrowOffset));
|
||||
return { x, y };
|
||||
@@ -453,15 +453,17 @@ MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
|
||||
category: localize('cmd.category', "View")
|
||||
}
|
||||
});
|
||||
MenuRegistry.appendMenuItem(MenuId.MenubarViewMenu, {
|
||||
group: '5_editor',
|
||||
order: 99,
|
||||
command: {
|
||||
id: 'breadcrumbs.toggle',
|
||||
title: localize('miToggleBreadcrumbs', "Toggle &&Breadcrumbs"),
|
||||
toggled: ContextKeyExpr.equals('config.breadcrumbs.enabled', true)
|
||||
}
|
||||
});
|
||||
// {{SQL CARBON EDIT}} - Disable unused menu item
|
||||
// MenuRegistry.appendMenuItem(MenuId.MenubarViewMenu, {
|
||||
// group: '5_editor',
|
||||
// order: 99,
|
||||
// command: {
|
||||
// id: 'breadcrumbs.toggle',
|
||||
// title: localize('miToggleBreadcrumbs', "Toggle &&Breadcrumbs"),
|
||||
// toggled: ContextKeyExpr.equals('config.breadcrumbs.enabled', true)
|
||||
// }
|
||||
// });
|
||||
// {{SQL CARBON EDIT}} - End
|
||||
CommandsRegistry.registerCommand('breadcrumbs.toggle', accessor => {
|
||||
let config = accessor.get(IConfigurationService);
|
||||
let value = BreadcrumbsConfig.IsEnabled.bindTo(config).getValue();
|
||||
|
||||
@@ -8,7 +8,7 @@ import { TimeoutTimer } from 'vs/base/common/async';
|
||||
import { CancellationTokenSource } from 'vs/base/common/cancellation';
|
||||
import { size } from 'vs/base/common/collections';
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { debounceEvent, Emitter, Event } from 'vs/base/common/event';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { isEqual, dirname } from 'vs/base/common/resources';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
@@ -31,7 +31,7 @@ export class FileElement {
|
||||
|
||||
export type BreadcrumbElement = FileElement | OutlineModel | OutlineGroup | OutlineElement;
|
||||
|
||||
type FileInfo = { path: FileElement[], folder: IWorkspaceFolder };
|
||||
type FileInfo = { path: FileElement[], folder?: IWorkspaceFolder };
|
||||
|
||||
export class EditorBreadcrumbsModel {
|
||||
|
||||
@@ -41,7 +41,7 @@ export class EditorBreadcrumbsModel {
|
||||
private readonly _cfgFilePath: BreadcrumbsConfig<'on' | 'off' | 'last'>;
|
||||
private readonly _cfgSymbolPath: BreadcrumbsConfig<'on' | 'off' | 'last'>;
|
||||
|
||||
private _outlineElements: (OutlineModel | OutlineGroup | OutlineElement)[] = [];
|
||||
private _outlineElements: Array<OutlineModel | OutlineGroup | OutlineElement> = [];
|
||||
private _outlineDisposables: IDisposable[] = [];
|
||||
|
||||
private _onDidUpdate = new Emitter<this>();
|
||||
@@ -105,16 +105,21 @@ export class EditorBreadcrumbsModel {
|
||||
}
|
||||
|
||||
let info: FileInfo = {
|
||||
folder: workspaceService.getWorkspaceFolder(uri),
|
||||
folder: workspaceService.getWorkspaceFolder(uri) || undefined,
|
||||
path: []
|
||||
};
|
||||
|
||||
while (uri.path !== '/') {
|
||||
if (info.folder && isEqual(info.folder.uri, uri)) {
|
||||
let uriPrefix: URI | null = uri;
|
||||
while (uriPrefix && uriPrefix.path !== '/') {
|
||||
if (info.folder && isEqual(info.folder.uri, uriPrefix)) {
|
||||
break;
|
||||
}
|
||||
info.path.unshift(new FileElement(uriPrefix, info.path.length === 0 ? FileKind.FILE : FileKind.FOLDER));
|
||||
let prevPathLength = uriPrefix.path.length;
|
||||
uriPrefix = dirname(uriPrefix);
|
||||
if (!uriPrefix || uriPrefix.path.length === prevPathLength) {
|
||||
break;
|
||||
}
|
||||
info.path.unshift(new FileElement(uri, info.path.length === 0 ? FileKind.FILE : FileKind.FOLDER));
|
||||
uri = dirname(uri);
|
||||
}
|
||||
|
||||
if (info.folder && workspaceService.getWorkbenchState() === WorkbenchState.WORKSPACE) {
|
||||
@@ -131,7 +136,7 @@ export class EditorBreadcrumbsModel {
|
||||
this._disposables.push(DocumentSymbolProviderRegistry.onDidChange(_ => this._updateOutline()));
|
||||
this._disposables.push(this._editor.onDidChangeModel(_ => this._updateOutline()));
|
||||
this._disposables.push(this._editor.onDidChangeModelLanguage(_ => this._updateOutline()));
|
||||
this._disposables.push(debounceEvent(this._editor.onDidChangeModelContent, _ => _, 350)(_ => this._updateOutline(true)));
|
||||
this._disposables.push(Event.debounce(this._editor.onDidChangeModelContent, _ => _, 350)(_ => this._updateOutline(true)));
|
||||
this._updateOutline();
|
||||
|
||||
// stop when editor dies
|
||||
@@ -145,7 +150,9 @@ export class EditorBreadcrumbsModel {
|
||||
this._updateOutlineElements([]);
|
||||
}
|
||||
|
||||
const buffer = this._editor.getModel();
|
||||
const editor = this._editor!;
|
||||
|
||||
const buffer = editor.getModel();
|
||||
if (!buffer || !DocumentSymbolProviderRegistry.has(buffer) || !isEqual(buffer.uri, this._uri)) {
|
||||
return;
|
||||
}
|
||||
@@ -171,11 +178,11 @@ export class EditorBreadcrumbsModel {
|
||||
// copy the model
|
||||
model = model.adopt();
|
||||
|
||||
this._updateOutlineElements(this._getOutlineElements(model, this._editor.getPosition()));
|
||||
this._outlineDisposables.push(this._editor.onDidChangeCursorPosition(_ => {
|
||||
this._updateOutlineElements(this._getOutlineElements(model, editor.getPosition()));
|
||||
this._outlineDisposables.push(editor.onDidChangeCursorPosition(_ => {
|
||||
timeout.cancelAndSet(() => {
|
||||
if (!buffer.isDisposed() && versionIdThen === buffer.getVersionId() && this._editor.getModel()) {
|
||||
this._updateOutlineElements(this._getOutlineElements(model, this._editor.getPosition()));
|
||||
if (!buffer.isDisposed() && versionIdThen === buffer.getVersionId() && editor.getModel()) {
|
||||
this._updateOutlineElements(this._getOutlineElements(model, editor.getPosition()));
|
||||
}
|
||||
}, 150);
|
||||
}));
|
||||
@@ -186,22 +193,22 @@ export class EditorBreadcrumbsModel {
|
||||
});
|
||||
}
|
||||
|
||||
private _getOutlineElements(model: OutlineModel, position: IPosition): (OutlineModel | OutlineGroup | OutlineElement)[] {
|
||||
if (!model) {
|
||||
private _getOutlineElements(model: OutlineModel, position: IPosition | null): Array<OutlineModel | OutlineGroup | OutlineElement> {
|
||||
if (!model || !position) {
|
||||
return [];
|
||||
}
|
||||
let item: OutlineGroup | OutlineElement = model.getItemEnclosingPosition(position);
|
||||
let item: OutlineGroup | OutlineElement | undefined = model.getItemEnclosingPosition(position);
|
||||
if (!item) {
|
||||
return [model];
|
||||
}
|
||||
let chain: (OutlineGroup | OutlineElement)[] = [];
|
||||
let chain: Array<OutlineGroup | OutlineElement> = [];
|
||||
while (item) {
|
||||
chain.push(item);
|
||||
let parent = item.parent;
|
||||
if (parent instanceof OutlineModel) {
|
||||
break;
|
||||
}
|
||||
if (parent instanceof OutlineGroup && size(parent.parent.children) === 1) {
|
||||
if (parent instanceof OutlineGroup && parent.parent && size(parent.parent.children) === 1) {
|
||||
break;
|
||||
}
|
||||
item = parent;
|
||||
@@ -209,7 +216,7 @@ export class EditorBreadcrumbsModel {
|
||||
return chain.reverse();
|
||||
}
|
||||
|
||||
private _updateOutlineElements(elements: (OutlineModel | OutlineGroup | OutlineElement)[]): void {
|
||||
private _updateOutlineElements(elements: Array<OutlineModel | OutlineGroup | OutlineElement>): void {
|
||||
if (!equals(elements, this._outlineElements, EditorBreadcrumbsModel._outlineElementEquals)) {
|
||||
this._outlineElements = elements;
|
||||
this._onDidUpdate.fire(this);
|
||||
|
||||
@@ -14,7 +14,6 @@ import { dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { join } from 'vs/base/common/paths';
|
||||
import { basename, dirname, isEqual } from 'vs/base/common/resources';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { IDataSource, IFilter, IRenderer, ISorter, ITree } from 'vs/base/parts/tree/browser/tree';
|
||||
import 'vs/css!./media/breadcrumbscontrol';
|
||||
import { OutlineElement, OutlineModel, TreeElement } from 'vs/editor/contrib/documentSymbols/outlineModel';
|
||||
@@ -26,7 +25,7 @@ import { IConstructorSignature1, IInstantiationService } from 'vs/platform/insta
|
||||
import { HighlightingWorkbenchTree, IHighlighter, IHighlightingTreeConfiguration, IHighlightingTreeOptions } from 'vs/platform/list/browser/listService';
|
||||
import { breadcrumbsPickerBackground, widgetShadow } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { IWorkspace, IWorkspaceContextService, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
|
||||
import { FileLabel } from 'vs/workbench/browser/labels';
|
||||
import { ResourceLabels, IResourceLabel, DEFAULT_LABELS_CONTAINER } from 'vs/workbench/browser/labels';
|
||||
import { BreadcrumbsConfig } from 'vs/workbench/browser/parts/editor/breadcrumbs';
|
||||
import { BreadcrumbElement, FileElement } from 'vs/workbench/browser/parts/editor/breadcrumbsModel';
|
||||
import { IFileIconTheme, IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
|
||||
@@ -160,7 +159,7 @@ export abstract class BreadcrumbsPicker {
|
||||
// use proper selection, reveal
|
||||
let selection = this._getInitialSelection(this._tree, input);
|
||||
if (selection) {
|
||||
return this._tree.reveal(selection, .5).then(() => {
|
||||
return this._tree.reveal(selection, 0.5).then(() => {
|
||||
this._tree.setSelection([selection], this._tree);
|
||||
this._tree.setFocus(selection);
|
||||
this._tree.domFocus();
|
||||
@@ -228,7 +227,7 @@ export class FileDataSource implements IDataSource {
|
||||
return URI.isUri(element) || IWorkspace.isIWorkspace(element) || IWorkspaceFolder.isIWorkspaceFolder(element) || element.isDirectory;
|
||||
}
|
||||
|
||||
getChildren(tree: ITree, element: IWorkspace | IWorkspaceFolder | IFileStat | URI): TPromise<IWorkspaceFolder[] | IFileStat[]> {
|
||||
getChildren(tree: ITree, element: IWorkspace | IWorkspaceFolder | IFileStat | URI): Promise<IWorkspaceFolder[] | IFileStat[]> {
|
||||
if (IWorkspace.isIWorkspace(element)) {
|
||||
return Promise.resolve(element.folders).then(folders => {
|
||||
for (let child of folders) {
|
||||
@@ -253,7 +252,7 @@ export class FileDataSource implements IDataSource {
|
||||
});
|
||||
}
|
||||
|
||||
getParent(tree: ITree, element: IWorkspace | URI | IWorkspaceFolder | IFileStat): TPromise<IWorkspaceFolder | IFileStat> {
|
||||
getParent(tree: ITree, element: IWorkspace | URI | IWorkspaceFolder | IFileStat): Promise<IWorkspaceFolder | IFileStat> {
|
||||
return Promise.resolve(this._parents.get(element));
|
||||
}
|
||||
}
|
||||
@@ -330,7 +329,7 @@ export class FileHighlighter implements IHighlighter {
|
||||
export class FileRenderer implements IRenderer {
|
||||
|
||||
constructor(
|
||||
@IInstantiationService private readonly _instantiationService: IInstantiationService,
|
||||
private readonly _labels: ResourceLabels,
|
||||
@IConfigurationService private readonly _configService: IConfigurationService,
|
||||
) { }
|
||||
|
||||
@@ -343,10 +342,10 @@ export class FileRenderer implements IRenderer {
|
||||
}
|
||||
|
||||
renderTemplate(tree: ITree, templateId: string, container: HTMLElement) {
|
||||
return this._instantiationService.createInstance(FileLabel, container, { supportHighlights: true });
|
||||
return this._labels.create(container, { supportHighlights: true });
|
||||
}
|
||||
|
||||
renderElement(tree: ITree, element: IFileStat | IWorkspaceFolder, templateId: string, templateData: FileLabel): void {
|
||||
renderElement(tree: ITree, element: IFileStat | IWorkspaceFolder, templateId: string, templateData: IResourceLabel): void {
|
||||
let fileDecorations = this._configService.getValue<{ colors: boolean, badges: boolean }>('explorer.decorations');
|
||||
let resource: URI;
|
||||
let fileKind: FileKind;
|
||||
@@ -366,7 +365,7 @@ export class FileRenderer implements IRenderer {
|
||||
});
|
||||
}
|
||||
|
||||
disposeTemplate(tree: ITree, templateId: string, templateData: FileLabel): void {
|
||||
disposeTemplate(tree: ITree, templateId: string, templateData: IResourceLabel): void {
|
||||
templateData.dispose();
|
||||
}
|
||||
}
|
||||
@@ -428,7 +427,9 @@ export class BreadcrumbsFilePicker extends BreadcrumbsPicker {
|
||||
this._disposables.push(filter);
|
||||
|
||||
config.dataSource = this._instantiationService.createInstance(FileDataSource);
|
||||
config.renderer = this._instantiationService.createInstance(FileRenderer);
|
||||
const labels = this._instantiationService.createInstance(ResourceLabels, DEFAULT_LABELS_CONTAINER /* TODO@Jo visibility propagation */);
|
||||
this._disposables.push(labels);
|
||||
config.renderer = this._instantiationService.createInstance(FileRenderer, labels);
|
||||
config.sorter = new FileSorter();
|
||||
config.highlighter = new FileHighlighter();
|
||||
config.filter = filter;
|
||||
|
||||
@@ -50,6 +50,7 @@ import { AllEditorsPicker, ActiveEditorGroupPicker } from 'vs/workbench/browser/
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { registerEditorContribution } from 'vs/editor/browser/editorExtensions';
|
||||
import { OpenWorkspaceButtonContribution } from 'vs/workbench/browser/parts/editor/editorWidgets';
|
||||
import { ZoomStatusbarItem } from 'vs/workbench/browser/parts/editor/resourceViewer';
|
||||
|
||||
// Register String Editor
|
||||
Registry.as<IEditorRegistry>(EditorExtensions.Editors).registerEditor(
|
||||
@@ -110,7 +111,7 @@ interface ISerializedUntitledEditorInput {
|
||||
class UntitledEditorInputFactory implements IEditorInputFactory {
|
||||
|
||||
constructor(
|
||||
@ITextFileService private textFileService: ITextFileService
|
||||
@ITextFileService private readonly textFileService: ITextFileService
|
||||
) { }
|
||||
|
||||
serialize(editorInput: EditorInput): string {
|
||||
@@ -144,7 +145,7 @@ class UntitledEditorInputFactory implements IEditorInputFactory {
|
||||
return instantiationService.invokeFunction<UntitledEditorInput>(accessor => {
|
||||
const deserialized: ISerializedUntitledEditorInput = JSON.parse(serializedEditorInput);
|
||||
const resource = !!deserialized.resourceJSON ? URI.revive(deserialized.resourceJSON) : URI.parse(deserialized.resource);
|
||||
const filePath = resource.scheme === Schemas.file ? resource.fsPath : void 0;
|
||||
const filePath = resource.scheme === Schemas.file ? resource.fsPath : undefined;
|
||||
const language = deserialized.modeId;
|
||||
const encoding = deserialized.encoding;
|
||||
|
||||
@@ -226,6 +227,9 @@ registerEditorContribution(OpenWorkspaceButtonContribution);
|
||||
const statusBar = Registry.as<IStatusbarRegistry>(StatusExtensions.Statusbar);
|
||||
statusBar.registerStatusbarItem(new StatusbarItemDescriptor(EditorStatus, 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) */));
|
||||
|
||||
// Register Status Actions
|
||||
const registry = Registry.as<IWorkbenchActionRegistry>(ActionExtensions.WorkbenchActions);
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(ChangeModeAction, ChangeModeAction.ID, ChangeModeAction.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.KEY_M) }), 'Change Language Mode');
|
||||
@@ -235,7 +239,7 @@ registry.registerWorkbenchAction(new SyncActionDescriptor(ChangeEncodingAction,
|
||||
export class QuickOpenActionContributor extends ActionBarContributor {
|
||||
private openToSideActionInstance: OpenToSideFromQuickOpenAction;
|
||||
|
||||
constructor(@IInstantiationService private instantiationService: IInstantiationService) {
|
||||
constructor(@IInstantiationService private readonly instantiationService: IInstantiationService) {
|
||||
super();
|
||||
}
|
||||
|
||||
@@ -745,7 +749,7 @@ MenuRegistry.appendMenuItem(MenuId.MenubarLayoutMenu, {
|
||||
|
||||
// Forward/Back
|
||||
MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, {
|
||||
group: '1_fwd_back',
|
||||
group: '1_history_nav',
|
||||
command: {
|
||||
id: 'workbench.action.navigateBack',
|
||||
title: nls.localize({ key: 'miBack', comment: ['&& denotes a mnemonic'] }, "&&Back"),
|
||||
@@ -755,7 +759,7 @@ MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, {
|
||||
});
|
||||
|
||||
MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, {
|
||||
group: '1_fwd_back',
|
||||
group: '1_history_nav',
|
||||
command: {
|
||||
id: 'workbench.action.navigateForward',
|
||||
title: nls.localize({ key: 'miForward', comment: ['&& denotes a mnemonic'] }, "&&Forward"),
|
||||
@@ -764,6 +768,16 @@ MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, {
|
||||
order: 2
|
||||
});
|
||||
|
||||
MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, {
|
||||
group: '1_history_nav',
|
||||
command: {
|
||||
id: 'workbench.action.navigateToLastEditLocation',
|
||||
title: nls.localize({ key: 'miLastEditLocation', comment: ['&& denotes a mnemonic'] }, "&&Last Edit Location"),
|
||||
precondition: ContextKeyExpr.has('canNavigateToLastEditLocation')
|
||||
},
|
||||
order: 3
|
||||
});
|
||||
|
||||
// Switch Editor
|
||||
MenuRegistry.appendMenuItem(MenuId.MenubarSwitchEditorMenu, {
|
||||
group: '1_any',
|
||||
@@ -802,7 +816,7 @@ MenuRegistry.appendMenuItem(MenuId.MenubarSwitchEditorMenu, {
|
||||
});
|
||||
|
||||
MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, {
|
||||
group: '2_switch',
|
||||
group: '2_editor_nav',
|
||||
title: nls.localize({ key: 'miSwitchEditor', comment: ['&& denotes a mnemonic'] }, "Switch &&Editor"),
|
||||
submenu: MenuId.MenubarSwitchEditorMenu,
|
||||
order: 1
|
||||
@@ -909,7 +923,7 @@ MenuRegistry.appendMenuItem(MenuId.MenubarSwitchGroupMenu, {
|
||||
});
|
||||
|
||||
MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, {
|
||||
group: '2_switch',
|
||||
group: '2_editor_nav',
|
||||
title: nls.localize({ key: 'miSwitchGroup', comment: ['&& denotes a mnemonic'] }, "Switch &&Group"),
|
||||
submenu: MenuId.MenubarSwitchGroupMenu,
|
||||
order: 2
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { GroupIdentifier, IWorkbenchEditorConfiguration, IWorkbenchEditorPartConfiguration, EditorOptions, TextEditorOptions, IEditorInput, IEditorIdentifier, IEditorCloseEvent } from 'vs/workbench/common/editor';
|
||||
import { GroupIdentifier, IWorkbenchEditorConfiguration, IWorkbenchEditorPartConfiguration, EditorOptions, TextEditorOptions, IEditorInput, IEditorIdentifier, IEditorCloseEvent, IEditor } from 'vs/workbench/common/editor';
|
||||
import { EditorGroup } from 'vs/workbench/common/editor/editorGroup';
|
||||
import { IEditorGroup, GroupDirection, IAddGroupOptions, IMergeGroupOptions, GroupsOrder, IEditorGroupsService } from 'vs/workbench/services/group/common/editorGroupsService';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
@@ -30,6 +30,7 @@ export const DEFAULT_EDITOR_PART_OPTIONS: IEditorPartOptions = {
|
||||
highlightModifiedTabs: false,
|
||||
tabCloseButton: 'right',
|
||||
tabSizing: 'fit',
|
||||
focusRecentEditorAfterClose: true,
|
||||
showIcons: true,
|
||||
enablePreview: true,
|
||||
openPositioning: 'right',
|
||||
@@ -74,9 +75,9 @@ export interface IEditorOpeningEvent extends IEditorIdentifier {
|
||||
* that will be executed instead. By returning another editor promise
|
||||
* it is possible to override the opening with another editor. It is ok
|
||||
* to return a promise that resolves to NULL to prevent the opening
|
||||
* altogether.
|
||||
* alltogether.
|
||||
*/
|
||||
prevent(callback: () => Thenable<any>): void;
|
||||
prevent(callback: () => Promise<IEditor>): void;
|
||||
}
|
||||
|
||||
export interface IEditorGroupsAccessor {
|
||||
@@ -102,7 +103,7 @@ export interface IEditorGroupsAccessor {
|
||||
|
||||
export interface IEditorGroupView extends IDisposable, ISerializableView, IEditorGroup {
|
||||
readonly group: EditorGroup;
|
||||
readonly whenRestored: Thenable<void>;
|
||||
readonly whenRestored: Promise<void>;
|
||||
readonly disposed: boolean;
|
||||
|
||||
readonly onDidFocus: Event<void>;
|
||||
@@ -119,7 +120,7 @@ export interface IEditorGroupView extends IDisposable, ISerializableView, IEdito
|
||||
}
|
||||
|
||||
export function getActiveTextEditorOptions(group: IEditorGroup, expectedActiveEditor?: IEditorInput, presetOptions?: EditorOptions): EditorOptions {
|
||||
const activeGroupCodeEditor = group.activeControl ? getCodeEditor(group.activeControl.getControl()) : void 0;
|
||||
const activeGroupCodeEditor = group.activeControl ? getCodeEditor(group.activeControl.getControl()) : undefined;
|
||||
if (activeGroupCodeEditor) {
|
||||
if (!expectedActiveEditor || expectedActiveEditor.matches(group.activeEditor)) {
|
||||
return TextEditorOptions.fromEditor(activeGroupCodeEditor, presetOptions);
|
||||
@@ -155,5 +156,5 @@ export interface EditorGroupsServiceImpl extends IEditorGroupsService {
|
||||
/**
|
||||
* A promise that resolves when groups have been restored.
|
||||
*/
|
||||
readonly whenRestored: Thenable<void>;
|
||||
readonly whenRestored: Promise<void>;
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ export class ExecuteCommandAction extends Action {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
run(): Thenable<any> {
|
||||
run(): Promise<any> {
|
||||
return this.commandService.executeCommand(this.commandId, this.commandArgs);
|
||||
}
|
||||
}
|
||||
@@ -182,7 +182,7 @@ export class JoinTwoGroupsAction extends Action {
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IEditorGroupsService private editorGroupService: IEditorGroupsService
|
||||
@IEditorGroupsService private readonly editorGroupService: IEditorGroupsService
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
@@ -196,8 +196,8 @@ export class JoinTwoGroupsAction extends Action {
|
||||
}
|
||||
|
||||
const targetGroupDirections = [GroupDirection.RIGHT, GroupDirection.DOWN, GroupDirection.LEFT, GroupDirection.UP];
|
||||
for (let i = 0; i < targetGroupDirections.length; i++) {
|
||||
const targetGroup = this.editorGroupService.findGroup({ direction: targetGroupDirections[i] }, sourceGroup);
|
||||
for (const targetGroupDirection of targetGroupDirections) {
|
||||
const targetGroup = this.editorGroupService.findGroup({ direction: targetGroupDirection }, sourceGroup);
|
||||
if (targetGroup && sourceGroup !== targetGroup) {
|
||||
this.editorGroupService.mergeGroup(sourceGroup, targetGroup);
|
||||
|
||||
@@ -217,7 +217,7 @@ export class JoinAllGroupsAction extends Action {
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IEditorGroupsService private editorGroupService: IEditorGroupsService
|
||||
@IEditorGroupsService private readonly editorGroupService: IEditorGroupsService
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
@@ -237,12 +237,12 @@ export class NavigateBetweenGroupsAction extends Action {
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IEditorGroupsService private editorGroupService: IEditorGroupsService
|
||||
@IEditorGroupsService private readonly editorGroupService: IEditorGroupsService
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
run(): Thenable<any> {
|
||||
run(): Promise<any> {
|
||||
const nextGroup = this.editorGroupService.findGroup({ location: GroupLocation.NEXT }, this.editorGroupService.activeGroup, true);
|
||||
nextGroup.focus();
|
||||
|
||||
@@ -258,12 +258,12 @@ export class FocusActiveGroupAction extends Action {
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IEditorGroupsService private editorGroupService: IEditorGroupsService
|
||||
@IEditorGroupsService private readonly editorGroupService: IEditorGroupsService
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
run(): Thenable<any> {
|
||||
run(): Promise<any> {
|
||||
this.editorGroupService.activeGroup.focus();
|
||||
|
||||
return Promise.resolve(true);
|
||||
@@ -276,12 +276,12 @@ export abstract class BaseFocusGroupAction extends Action {
|
||||
id: string,
|
||||
label: string,
|
||||
private scope: IFindGroupScope,
|
||||
@IEditorGroupsService private editorGroupService: IEditorGroupsService
|
||||
@IEditorGroupsService private readonly editorGroupService: IEditorGroupsService
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
run(): Thenable<any> {
|
||||
run(): Promise<any> {
|
||||
const group = this.editorGroupService.findGroup(this.scope, this.editorGroupService.activeGroup, true);
|
||||
if (group) {
|
||||
group.focus();
|
||||
@@ -409,8 +409,8 @@ export class OpenToSideFromQuickOpenAction extends Action {
|
||||
static readonly OPEN_TO_SIDE_LABEL = nls.localize('openToSide', "Open to the Side");
|
||||
|
||||
constructor(
|
||||
@IEditorService private editorService: IEditorService,
|
||||
@IConfigurationService private configurationService: IConfigurationService
|
||||
@IEditorService private readonly editorService: IEditorService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService
|
||||
) {
|
||||
super(OpenToSideFromQuickOpenAction.OPEN_TO_SIDE_ID, OpenToSideFromQuickOpenAction.OPEN_TO_SIDE_LABEL);
|
||||
|
||||
@@ -423,7 +423,7 @@ export class OpenToSideFromQuickOpenAction extends Action {
|
||||
this.class = (preferredDirection === GroupDirection.RIGHT) ? 'quick-open-sidebyside-vertical' : 'quick-open-sidebyside-horizontal';
|
||||
}
|
||||
|
||||
run(context: any): Thenable<any> {
|
||||
run(context: any): Promise<any> {
|
||||
const entry = toEditorQuickOpenEntry(context);
|
||||
if (entry) {
|
||||
const input = entry.getInput();
|
||||
@@ -467,13 +467,13 @@ export class CloseEditorAction extends Action {
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@ICommandService private commandService: ICommandService
|
||||
@ICommandService private readonly commandService: ICommandService
|
||||
) {
|
||||
super(id, label, 'close-editor-action');
|
||||
}
|
||||
|
||||
run(context?: IEditorCommandsContext): Promise<any> {
|
||||
return this.commandService.executeCommand(CLOSE_EDITOR_COMMAND_ID, void 0, context);
|
||||
return this.commandService.executeCommand(CLOSE_EDITOR_COMMAND_ID, undefined, context);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -485,12 +485,12 @@ export class CloseOneEditorAction extends Action {
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IEditorGroupsService private editorGroupService: IEditorGroupsService
|
||||
@IEditorGroupsService private readonly editorGroupService: IEditorGroupsService
|
||||
) {
|
||||
super(id, label, 'close-editor-action');
|
||||
}
|
||||
|
||||
run(context?: IEditorCommandsContext): Thenable<any> {
|
||||
run(context?: IEditorCommandsContext): Promise<any> {
|
||||
let group: IEditorGroup;
|
||||
let editorIndex: number;
|
||||
if (context) {
|
||||
@@ -530,12 +530,12 @@ export class RevertAndCloseEditorAction extends Action {
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IEditorService private editorService: IEditorService
|
||||
@IEditorService private readonly editorService: IEditorService
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
run(): Thenable<any> {
|
||||
run(): Promise<any> {
|
||||
const activeControl = this.editorService.activeControl;
|
||||
if (activeControl) {
|
||||
const editor = activeControl.input;
|
||||
@@ -563,13 +563,13 @@ export class CloseLeftEditorsInGroupAction extends Action {
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IEditorService private editorService: IEditorService,
|
||||
@IEditorGroupsService private editorGroupService: IEditorGroupsService
|
||||
@IEditorService private readonly editorService: IEditorService,
|
||||
@IEditorGroupsService private readonly editorGroupService: IEditorGroupsService
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
run(context?: IEditorIdentifier): Thenable<any> {
|
||||
run(context?: IEditorIdentifier): Promise<any> {
|
||||
const { group, editor } = getTarget(this.editorService, this.editorGroupService, context);
|
||||
if (group && editor) {
|
||||
return group.closeEditors({ direction: CloseDirection.LEFT, except: editor });
|
||||
@@ -614,7 +614,7 @@ export abstract class BaseCloseAllAction extends Action {
|
||||
return groupsToClose;
|
||||
}
|
||||
|
||||
run(): Thenable<any> {
|
||||
run(): Promise<any> {
|
||||
|
||||
// Just close all if there are no or one dirty editor
|
||||
if (this.textFileService.getDirty().length < 2) {
|
||||
@@ -624,10 +624,10 @@ export abstract class BaseCloseAllAction extends Action {
|
||||
// Otherwise ask for combined confirmation
|
||||
return this.textFileService.confirmSave().then(confirm => {
|
||||
if (confirm === ConfirmResult.CANCEL) {
|
||||
return void 0;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let saveOrRevertPromise: Thenable<boolean>;
|
||||
let saveOrRevertPromise: Promise<boolean>;
|
||||
if (confirm === ConfirmResult.DONT_SAVE) {
|
||||
saveOrRevertPromise = this.textFileService.revertAll(null, { soft: true }).then(() => true);
|
||||
} else {
|
||||
@@ -639,12 +639,12 @@ export abstract class BaseCloseAllAction extends Action {
|
||||
return this.doCloseAll();
|
||||
}
|
||||
|
||||
return void 0;
|
||||
return undefined;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
protected abstract doCloseAll(): Thenable<any>;
|
||||
protected abstract doCloseAll(): Promise<any>;
|
||||
}
|
||||
|
||||
export class CloseAllEditorsAction extends BaseCloseAllAction {
|
||||
@@ -677,7 +677,7 @@ export class CloseAllEditorGroupsAction extends BaseCloseAllAction {
|
||||
@ITextFileService textFileService: ITextFileService,
|
||||
@IEditorGroupsService editorGroupService: IEditorGroupsService
|
||||
) {
|
||||
super(id, label, void 0, textFileService, editorGroupService);
|
||||
super(id, label, undefined, textFileService, editorGroupService);
|
||||
}
|
||||
|
||||
protected doCloseAll(): Promise<any> {
|
||||
@@ -695,12 +695,12 @@ export class CloseEditorsInOtherGroupsAction extends Action {
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IEditorGroupsService private editorGroupService: IEditorGroupsService,
|
||||
@IEditorGroupsService private readonly editorGroupService: IEditorGroupsService,
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
run(context?: IEditorIdentifier): Thenable<any> {
|
||||
run(context?: IEditorIdentifier): Promise<any> {
|
||||
const groupToSkip = context ? this.editorGroupService.getGroup(context.groupId) : this.editorGroupService.activeGroup;
|
||||
return Promise.all(this.editorGroupService.getGroups(GroupsOrder.MOST_RECENTLY_ACTIVE).map(g => {
|
||||
if (g.id === groupToSkip.id) {
|
||||
@@ -720,13 +720,13 @@ export class CloseEditorInAllGroupsAction extends Action {
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IEditorGroupsService private editorGroupService: IEditorGroupsService,
|
||||
@IEditorService private editorService: IEditorService
|
||||
@IEditorGroupsService private readonly editorGroupService: IEditorGroupsService,
|
||||
@IEditorService private readonly editorService: IEditorService
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
run(): Thenable<any> {
|
||||
run(): Promise<any> {
|
||||
const activeEditor = this.editorService.activeEditor;
|
||||
if (activeEditor) {
|
||||
return Promise.all(this.editorGroupService.getGroups(GroupsOrder.MOST_RECENTLY_ACTIVE).map(g => g.closeEditor(activeEditor)));
|
||||
@@ -780,14 +780,14 @@ export class BaseMoveGroupAction extends Action {
|
||||
break;
|
||||
}
|
||||
|
||||
for (let i = 0; i < targetNeighbours.length; i++) {
|
||||
const targetNeighbour = this.editorGroupService.findGroup({ direction: targetNeighbours[i] }, sourceGroup);
|
||||
if (targetNeighbour) {
|
||||
return targetNeighbour;
|
||||
for (const targetNeighbour of targetNeighbours) {
|
||||
const targetNeighbourGroup = this.editorGroupService.findGroup({ direction: targetNeighbour }, sourceGroup);
|
||||
if (targetNeighbourGroup) {
|
||||
return targetNeighbourGroup;
|
||||
}
|
||||
}
|
||||
|
||||
return void 0;
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -852,11 +852,11 @@ export class MinimizeOtherGroupsAction extends Action {
|
||||
static readonly ID = 'workbench.action.minimizeOtherEditors';
|
||||
static readonly LABEL = nls.localize('minimizeOtherEditorGroups', "Maximize Editor Group");
|
||||
|
||||
constructor(id: string, label: string, @IEditorGroupsService private editorGroupService: IEditorGroupsService) {
|
||||
constructor(id: string, label: string, @IEditorGroupsService private readonly editorGroupService: IEditorGroupsService) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
run(): Thenable<any> {
|
||||
run(): Promise<any> {
|
||||
this.editorGroupService.arrangeGroups(GroupsArrangement.MINIMIZE_OTHERS);
|
||||
|
||||
return Promise.resolve(false);
|
||||
@@ -868,11 +868,11 @@ export class ResetGroupSizesAction extends Action {
|
||||
static readonly ID = 'workbench.action.evenEditorWidths';
|
||||
static readonly LABEL = nls.localize('evenEditorGroups', "Reset Editor Group Sizes");
|
||||
|
||||
constructor(id: string, label: string, @IEditorGroupsService private editorGroupService: IEditorGroupsService) {
|
||||
constructor(id: string, label: string, @IEditorGroupsService private readonly editorGroupService: IEditorGroupsService) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
run(): Thenable<any> {
|
||||
run(): Promise<any> {
|
||||
this.editorGroupService.arrangeGroups(GroupsArrangement.EVEN);
|
||||
|
||||
return Promise.resolve(false);
|
||||
@@ -887,14 +887,14 @@ export class MaximizeGroupAction extends Action {
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IEditorService private editorService: IEditorService,
|
||||
@IEditorGroupsService private editorGroupService: IEditorGroupsService,
|
||||
@IPartService private partService: IPartService
|
||||
@IEditorService private readonly editorService: IEditorService,
|
||||
@IEditorGroupsService private readonly editorGroupService: IEditorGroupsService,
|
||||
@IPartService private readonly partService: IPartService
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
run(): Thenable<any> {
|
||||
run(): Promise<any> {
|
||||
if (this.editorService.activeEditor) {
|
||||
this.editorGroupService.arrangeGroups(GroupsArrangement.MINIMIZE_OTHERS);
|
||||
this.partService.setSideBarHidden(true);
|
||||
@@ -915,7 +915,7 @@ export abstract class BaseNavigateEditorAction extends Action {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
run(): Thenable<any> {
|
||||
run(): Promise<any> {
|
||||
const result = this.navigate();
|
||||
if (!result) {
|
||||
return Promise.resolve(false);
|
||||
@@ -964,7 +964,7 @@ export class OpenNextEditor extends BaseNavigateEditorAction {
|
||||
return { editor: previousGroupEditors[0], groupId: nextGroup.id };
|
||||
}
|
||||
|
||||
return void 0;
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -999,7 +999,7 @@ export class OpenPreviousEditor extends BaseNavigateEditorAction {
|
||||
return { editor: previousGroupEditors[previousGroupEditors.length - 1], groupId: previousGroup.id };
|
||||
}
|
||||
|
||||
return void 0;
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1098,11 +1098,11 @@ export class NavigateForwardAction extends Action {
|
||||
static readonly ID = 'workbench.action.navigateForward';
|
||||
static readonly LABEL = nls.localize('navigateNext', "Go Forward");
|
||||
|
||||
constructor(id: string, label: string, @IHistoryService private historyService: IHistoryService) {
|
||||
constructor(id: string, label: string, @IHistoryService private readonly historyService: IHistoryService) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
run(): Thenable<any> {
|
||||
run(): Promise<any> {
|
||||
this.historyService.forward();
|
||||
|
||||
return Promise.resolve(null);
|
||||
@@ -1114,11 +1114,11 @@ export class NavigateBackwardsAction extends Action {
|
||||
static readonly ID = 'workbench.action.navigateBack';
|
||||
static readonly LABEL = nls.localize('navigatePrevious', "Go Back");
|
||||
|
||||
constructor(id: string, label: string, @IHistoryService private historyService: IHistoryService) {
|
||||
constructor(id: string, label: string, @IHistoryService private readonly historyService: IHistoryService) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
run(): Thenable<any> {
|
||||
run(): Promise<any> {
|
||||
this.historyService.back();
|
||||
|
||||
return Promise.resolve(null);
|
||||
@@ -1130,11 +1130,11 @@ export class NavigateToLastEditLocationAction extends Action {
|
||||
static readonly ID = 'workbench.action.navigateToLastEditLocation';
|
||||
static readonly LABEL = nls.localize('navigateToLastEditLocation', "Go to Last Edit Location");
|
||||
|
||||
constructor(id: string, label: string, @IHistoryService private historyService: IHistoryService) {
|
||||
constructor(id: string, label: string, @IHistoryService private readonly historyService: IHistoryService) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
run(): Thenable<any> {
|
||||
run(): Promise<any> {
|
||||
this.historyService.openLastEditLocation();
|
||||
|
||||
return Promise.resolve(null);
|
||||
@@ -1146,11 +1146,11 @@ export class NavigateLastAction extends Action {
|
||||
static readonly ID = 'workbench.action.navigateLast';
|
||||
static readonly LABEL = nls.localize('navigateLast', "Go Last");
|
||||
|
||||
constructor(id: string, label: string, @IHistoryService private historyService: IHistoryService) {
|
||||
constructor(id: string, label: string, @IHistoryService private readonly historyService: IHistoryService) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
run(): Thenable<any> {
|
||||
run(): Promise<any> {
|
||||
this.historyService.last();
|
||||
|
||||
return Promise.resolve(null);
|
||||
@@ -1165,12 +1165,12 @@ export class ReopenClosedEditorAction extends Action {
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IHistoryService private historyService: IHistoryService
|
||||
@IHistoryService private readonly historyService: IHistoryService
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
run(): Thenable<any> {
|
||||
run(): Promise<any> {
|
||||
this.historyService.reopenLastClosedEditor();
|
||||
|
||||
return Promise.resolve(false);
|
||||
@@ -1185,13 +1185,13 @@ export class ClearRecentFilesAction extends Action {
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IWindowsService private windowsService: IWindowsService,
|
||||
@IHistoryService private historyService: IHistoryService
|
||||
@IWindowsService private readonly windowsService: IWindowsService,
|
||||
@IHistoryService private readonly historyService: IHistoryService
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
run(): Thenable<any> {
|
||||
run(): Promise<any> {
|
||||
|
||||
// Clear global recently opened
|
||||
this.windowsService.clearRecentlyOpened();
|
||||
@@ -1232,13 +1232,13 @@ export class BaseQuickOpenEditorInGroupAction extends Action {
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IQuickOpenService private quickOpenService: IQuickOpenService,
|
||||
@IKeybindingService private keybindingService: IKeybindingService
|
||||
@IQuickOpenService private readonly quickOpenService: IQuickOpenService,
|
||||
@IKeybindingService private readonly keybindingService: IKeybindingService
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
run(): Thenable<any> {
|
||||
run(): Promise<any> {
|
||||
const keys = this.keybindingService.lookupKeybindings(this.id);
|
||||
|
||||
|
||||
@@ -1287,13 +1287,13 @@ export class OpenPreviousEditorFromHistoryAction extends Action {
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IQuickOpenService private quickOpenService: IQuickOpenService,
|
||||
@IKeybindingService private keybindingService: IKeybindingService
|
||||
@IQuickOpenService private readonly quickOpenService: IQuickOpenService,
|
||||
@IKeybindingService private readonly keybindingService: IKeybindingService
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
run(): Thenable<any> {
|
||||
run(): Promise<any> {
|
||||
const keys = this.keybindingService.lookupKeybindings(this.id);
|
||||
|
||||
this.quickOpenService.show(null, { quickNavigateConfiguration: { keybindings: keys } });
|
||||
@@ -1307,11 +1307,11 @@ export class OpenNextRecentlyUsedEditorAction extends Action {
|
||||
static readonly ID = 'workbench.action.openNextRecentlyUsedEditor';
|
||||
static readonly LABEL = nls.localize('openNextRecentlyUsedEditor', "Open Next Recently Used Editor");
|
||||
|
||||
constructor(id: string, label: string, @IHistoryService private historyService: IHistoryService) {
|
||||
constructor(id: string, label: string, @IHistoryService private readonly historyService: IHistoryService) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
run(): Thenable<any> {
|
||||
run(): Promise<any> {
|
||||
this.historyService.forward(true);
|
||||
|
||||
return Promise.resolve(null);
|
||||
@@ -1323,11 +1323,11 @@ export class OpenPreviousRecentlyUsedEditorAction extends Action {
|
||||
static readonly ID = 'workbench.action.openPreviousRecentlyUsedEditor';
|
||||
static readonly LABEL = nls.localize('openPreviousRecentlyUsedEditor', "Open Previous Recently Used Editor");
|
||||
|
||||
constructor(id: string, label: string, @IHistoryService private historyService: IHistoryService) {
|
||||
constructor(id: string, label: string, @IHistoryService private readonly historyService: IHistoryService) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
run(): Thenable<any> {
|
||||
run(): Promise<any> {
|
||||
this.historyService.back(true);
|
||||
|
||||
return Promise.resolve(null);
|
||||
@@ -1342,12 +1342,12 @@ export class ClearEditorHistoryAction extends Action {
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IHistoryService private historyService: IHistoryService
|
||||
@IHistoryService private readonly historyService: IHistoryService
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
run(): Thenable<any> {
|
||||
run(): Promise<any> {
|
||||
|
||||
// Editor history
|
||||
this.historyService.clear();
|
||||
@@ -1619,7 +1619,7 @@ export class BaseCreateEditorGroupAction extends Action {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
run(): Thenable<any> {
|
||||
run(): Promise<any> {
|
||||
this.editorGroupService.addGroup(this.editorGroupService.activeGroup, this.direction, { activate: true });
|
||||
|
||||
return Promise.resolve(true);
|
||||
|
||||
@@ -267,8 +267,8 @@ function registerDiffEditorCommands(): void {
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: TOGGLE_DIFF_SIDE_BY_SIDE,
|
||||
weight: KeybindingWeight.WorkbenchContrib,
|
||||
when: void 0,
|
||||
primary: void 0,
|
||||
when: undefined,
|
||||
primary: undefined,
|
||||
handler: accessor => toggleDiffSideBySide(accessor)
|
||||
});
|
||||
|
||||
@@ -287,8 +287,8 @@ function registerDiffEditorCommands(): void {
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: TOGGLE_DIFF_IGNORE_TRIM_WHITESPACE,
|
||||
weight: KeybindingWeight.WorkbenchContrib,
|
||||
when: void 0,
|
||||
primary: void 0,
|
||||
when: undefined,
|
||||
primary: undefined,
|
||||
handler: accessor => toggleDiffIgnoreTrimWhitespace(accessor)
|
||||
});
|
||||
}
|
||||
@@ -319,7 +319,7 @@ function registerOpenEditorAtIndexCommands(): void {
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: OPEN_EDITOR_AT_INDEX_COMMAND_ID + visibleIndex,
|
||||
weight: KeybindingWeight.WorkbenchContrib,
|
||||
when: void 0,
|
||||
when: undefined,
|
||||
primary: KeyMod.Alt | toKeyCode(visibleIndex),
|
||||
mac: { primary: KeyMod.WinCtrl | toKeyCode(visibleIndex) },
|
||||
handler: accessor => openEditorAtIndex(accessor, editorIndex)
|
||||
@@ -340,7 +340,7 @@ function registerOpenEditorAtIndexCommands(): void {
|
||||
case 9: return KeyCode.KEY_9;
|
||||
}
|
||||
|
||||
return void 0;
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -351,7 +351,7 @@ function registerFocusEditorGroupAtIndexCommands(): void {
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: toCommandId(groupIndex),
|
||||
weight: KeybindingWeight.WorkbenchContrib,
|
||||
when: void 0,
|
||||
when: undefined,
|
||||
primary: KeyMod.CtrlCmd | toKeyCode(groupIndex),
|
||||
handler: accessor => {
|
||||
const editorGroupService = accessor.get(IEditorGroupsService);
|
||||
@@ -392,7 +392,7 @@ function registerFocusEditorGroupAtIndexCommands(): void {
|
||||
case 7: return 'workbench.action.focusEighthEditorGroup';
|
||||
}
|
||||
|
||||
return void 0;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function toKeyCode(index: number): KeyCode {
|
||||
@@ -406,7 +406,7 @@ function registerFocusEditorGroupAtIndexCommands(): void {
|
||||
case 7: return KeyCode.KEY_8;
|
||||
}
|
||||
|
||||
return void 0;
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -455,7 +455,7 @@ function registerCloseEditorCommands() {
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: CLOSE_SAVED_EDITORS_COMMAND_ID,
|
||||
weight: KeybindingWeight.WorkbenchContrib,
|
||||
when: void 0,
|
||||
when: undefined,
|
||||
primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.KEY_U),
|
||||
handler: (accessor, resourceOrContext: URI | IEditorCommandsContext, context?: IEditorCommandsContext) => {
|
||||
const editorGroupService = accessor.get(IEditorGroupsService);
|
||||
@@ -475,7 +475,7 @@ function registerCloseEditorCommands() {
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: CLOSE_EDITORS_IN_GROUP_COMMAND_ID,
|
||||
weight: KeybindingWeight.WorkbenchContrib,
|
||||
when: void 0,
|
||||
when: undefined,
|
||||
primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.KEY_W),
|
||||
handler: (accessor, resourceOrContext: URI | IEditorCommandsContext, context?: IEditorCommandsContext) => {
|
||||
const editorGroupService = accessor.get(IEditorGroupsService);
|
||||
@@ -495,7 +495,7 @@ function registerCloseEditorCommands() {
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: CLOSE_EDITOR_COMMAND_ID,
|
||||
weight: KeybindingWeight.WorkbenchContrib,
|
||||
when: void 0,
|
||||
when: undefined,
|
||||
primary: KeyMod.CtrlCmd | KeyCode.KEY_W,
|
||||
win: { primary: KeyMod.CtrlCmd | KeyCode.F4, secondary: [KeyMod.CtrlCmd | KeyCode.KEY_W] },
|
||||
handler: (accessor, resourceOrContext: URI | IEditorCommandsContext, context?: IEditorCommandsContext) => {
|
||||
@@ -544,8 +544,8 @@ function registerCloseEditorCommands() {
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: CLOSE_OTHER_EDITORS_IN_GROUP_COMMAND_ID,
|
||||
weight: KeybindingWeight.WorkbenchContrib,
|
||||
when: void 0,
|
||||
primary: void 0,
|
||||
when: undefined,
|
||||
primary: undefined,
|
||||
mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_T },
|
||||
handler: (accessor, resourceOrContext: URI | IEditorCommandsContext, context?: IEditorCommandsContext) => {
|
||||
const editorGroupService = accessor.get(IEditorGroupsService);
|
||||
@@ -573,8 +573,8 @@ function registerCloseEditorCommands() {
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: CLOSE_EDITORS_TO_THE_RIGHT_COMMAND_ID,
|
||||
weight: KeybindingWeight.WorkbenchContrib,
|
||||
when: void 0,
|
||||
primary: void 0,
|
||||
when: undefined,
|
||||
primary: undefined,
|
||||
handler: (accessor, resourceOrContext: URI | IEditorCommandsContext, context?: IEditorCommandsContext) => {
|
||||
const editorGroupService = accessor.get(IEditorGroupsService);
|
||||
|
||||
@@ -590,7 +590,7 @@ function registerCloseEditorCommands() {
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: KEEP_EDITOR_COMMAND_ID,
|
||||
weight: KeybindingWeight.WorkbenchContrib,
|
||||
when: void 0,
|
||||
when: undefined,
|
||||
primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.Enter),
|
||||
handler: (accessor, resourceOrContext: URI | IEditorCommandsContext, context?: IEditorCommandsContext) => {
|
||||
const editorGroupService = accessor.get(IEditorGroupsService);
|
||||
@@ -607,8 +607,8 @@ function registerCloseEditorCommands() {
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: SHOW_EDITORS_IN_GROUP,
|
||||
weight: KeybindingWeight.WorkbenchContrib,
|
||||
when: void 0,
|
||||
primary: void 0,
|
||||
when: undefined,
|
||||
primary: undefined,
|
||||
handler: (accessor, resourceOrContext: URI | IEditorCommandsContext, context?: IEditorCommandsContext) => {
|
||||
const editorGroupService = accessor.get(IEditorGroupsService);
|
||||
const quickOpenService = accessor.get(IQuickOpenService);
|
||||
@@ -638,7 +638,7 @@ function registerCloseEditorCommands() {
|
||||
});
|
||||
}
|
||||
|
||||
return void 0;
|
||||
return undefined;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -655,7 +655,7 @@ function getCommandsContext(resourceOrContext: URI | IEditorCommandsContext, con
|
||||
return context;
|
||||
}
|
||||
|
||||
return void 0;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function resolveCommandsContext(editorGroupService: IEditorGroupsService, context?: IEditorCommandsContext): { group: IEditorGroup, editor: IEditorInput, control: IEditor } {
|
||||
@@ -682,7 +682,7 @@ export function getMultiSelectedEditorContexts(editorContext: IEditorCommandsCon
|
||||
if (list instanceof List && list.getHTMLElement() === document.activeElement) {
|
||||
const elementToContext = (element: IEditorIdentifier | IEditorGroup) => {
|
||||
if (isEditorGroup(element)) {
|
||||
return { groupId: element.id, editorIndex: void 0 };
|
||||
return { groupId: element.id, editorIndex: undefined };
|
||||
}
|
||||
|
||||
return { groupId: element.groupId, editorIndex: editorGroupService.getGroup(element.groupId).getIndexOfEditor(element.editor) };
|
||||
@@ -690,11 +690,11 @@ export function getMultiSelectedEditorContexts(editorContext: IEditorCommandsCon
|
||||
|
||||
const onlyEditorGroupAndEditor = (e: IEditorIdentifier | IEditorGroup) => isEditorGroup(e) || isEditorIdentifier(e);
|
||||
|
||||
const focusedElements: (IEditorIdentifier | IEditorGroup)[] = list.getFocusedElements().filter(onlyEditorGroupAndEditor);
|
||||
const focus = editorContext ? editorContext : focusedElements.length ? focusedElements.map(elementToContext)[0] : void 0; // need to take into account when editor context is { group: group }
|
||||
const focusedElements: Array<IEditorIdentifier | IEditorGroup> = list.getFocusedElements().filter(onlyEditorGroupAndEditor);
|
||||
const focus = editorContext ? editorContext : focusedElements.length ? focusedElements.map(elementToContext)[0] : undefined; // need to take into account when editor context is { group: group }
|
||||
|
||||
if (focus) {
|
||||
const selection: (IEditorIdentifier | IEditorGroup)[] = list.getSelectedElements().filter(onlyEditorGroupAndEditor);
|
||||
const selection: Array<IEditorIdentifier | IEditorGroup> = list.getSelectedElements().filter(onlyEditorGroupAndEditor);
|
||||
|
||||
// Only respect selection if it contains focused element
|
||||
if (selection && selection.some(s => isEditorGroup(s) ? s.id === focus.groupId : s.groupId === focus.groupId && editorGroupService.getGroup(s.groupId).getIndexOfEditor(s.editor) === focus.editorIndex)) {
|
||||
|
||||
@@ -8,7 +8,6 @@ import { EditorInput, EditorOptions } from 'vs/workbench/common/editor';
|
||||
import { Dimension, show, hide, addClass } from 'vs/base/browser/dom';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { IEditorRegistry, Extensions as EditorExtensions, IEditorDescriptor } from 'vs/workbench/browser/editor';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { IPartService } from 'vs/workbench/services/part/common/partService';
|
||||
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
@@ -31,10 +30,10 @@ export class EditorControl extends Disposable {
|
||||
private _onDidFocus: Emitter<void> = this._register(new Emitter<void>());
|
||||
get onDidFocus(): Event<void> { return this._onDidFocus.event; }
|
||||
|
||||
private _onDidSizeConstraintsChange = this._register(new Emitter<{ width: number; height: number; }>());
|
||||
get onDidSizeConstraintsChange(): Event<{ width: number; height: number; }> { return this._onDidSizeConstraintsChange.event; }
|
||||
private _onDidSizeConstraintsChange = this._register(new Emitter<{ width: number; height: number; } | undefined>());
|
||||
get onDidSizeConstraintsChange(): Event<{ width: number; height: number; } | undefined> { return this._onDidSizeConstraintsChange.event; }
|
||||
|
||||
private _activeControl: BaseEditor;
|
||||
private _activeControl: BaseEditor | null;
|
||||
private controls: BaseEditor[] = [];
|
||||
|
||||
private activeControlDisposeables: IDisposable[] = [];
|
||||
@@ -44,8 +43,8 @@ export class EditorControl extends Disposable {
|
||||
constructor(
|
||||
private parent: HTMLElement,
|
||||
private groupView: IEditorGroupView,
|
||||
@IPartService private partService: IPartService,
|
||||
@IInstantiationService private instantiationService: IInstantiationService,
|
||||
@IPartService private readonly partService: IPartService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@IProgressService progressService: IProgressService
|
||||
) {
|
||||
super();
|
||||
@@ -53,21 +52,24 @@ export class EditorControl extends Disposable {
|
||||
this.editorOperation = this._register(new LongRunningOperation(progressService));
|
||||
}
|
||||
|
||||
get activeControl(): BaseEditor {
|
||||
get activeControl() {
|
||||
return this._activeControl;
|
||||
}
|
||||
|
||||
openEditor(editor: EditorInput, options?: EditorOptions): TPromise<IOpenEditorResult> {
|
||||
openEditor(editor: EditorInput, options?: EditorOptions): Promise<IOpenEditorResult> {
|
||||
|
||||
// Editor control
|
||||
const descriptor = Registry.as<IEditorRegistry>(EditorExtensions.Editors).getEditor(editor);
|
||||
const control = this.doShowEditorControl(descriptor, options);
|
||||
if (!descriptor) {
|
||||
throw new Error('No editor descriptor found');
|
||||
}
|
||||
const control = this.doShowEditorControl(descriptor);
|
||||
|
||||
// Set input
|
||||
return this.doSetInput(control, editor, options).then((editorChanged => (({ control, editorChanged } as IOpenEditorResult))));
|
||||
return this.doSetInput(control, editor, options || null).then((editorChanged => (({ control, editorChanged } as IOpenEditorResult))));
|
||||
}
|
||||
|
||||
private doShowEditorControl(descriptor: IEditorDescriptor, options: EditorOptions): BaseEditor {
|
||||
private doShowEditorControl(descriptor: IEditorDescriptor): BaseEditor {
|
||||
|
||||
// Return early if the currently active editor control can handle the input
|
||||
if (this._activeControl && descriptor.describes(this._activeControl)) {
|
||||
@@ -130,7 +132,7 @@ export class EditorControl extends Disposable {
|
||||
return control;
|
||||
}
|
||||
|
||||
private doSetActiveControl(control: BaseEditor) {
|
||||
private doSetActiveControl(control: BaseEditor | null) {
|
||||
this._activeControl = control;
|
||||
|
||||
// Clear out previous active control listeners
|
||||
@@ -143,10 +145,10 @@ export class EditorControl extends Disposable {
|
||||
}
|
||||
|
||||
// Indicate that size constraints could have changed due to new editor
|
||||
this._onDidSizeConstraintsChange.fire();
|
||||
this._onDidSizeConstraintsChange.fire(undefined);
|
||||
}
|
||||
|
||||
private doSetInput(control: BaseEditor, editor: EditorInput, options: EditorOptions): TPromise<boolean> {
|
||||
private doSetInput(control: BaseEditor, editor: EditorInput, options: EditorOptions | null): Promise<boolean> {
|
||||
|
||||
// If the input did not change, return early and only apply the options
|
||||
// unless the options instruct us to force open it even if it is the same
|
||||
@@ -163,7 +165,7 @@ export class EditorControl extends Disposable {
|
||||
control.focus();
|
||||
}
|
||||
|
||||
return TPromise.as(false);
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
|
||||
// Show progress while setting input after a certain timeout. If the workbench is opening
|
||||
@@ -172,7 +174,7 @@ export class EditorControl extends Disposable {
|
||||
|
||||
// Call into editor control
|
||||
const editorWillChange = !inputMatches;
|
||||
return TPromise.wrap(control.setInput(editor, options, operation.token)).then(() => {
|
||||
return control.setInput(editor, options, operation.token).then(() => {
|
||||
|
||||
// Focus (unless prevented or another operation is running)
|
||||
if (operation.isCurrent()) {
|
||||
@@ -191,7 +193,7 @@ export class EditorControl extends Disposable {
|
||||
// Operation done
|
||||
operation.stop();
|
||||
|
||||
return TPromise.wrapError(e);
|
||||
return Promise.reject(e);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -96,7 +96,7 @@ class DropOverlay extends Themable {
|
||||
|
||||
private registerListeners(): void {
|
||||
this._register(new DragAndDropObserver(this.container, {
|
||||
onDragEnter: e => void 0,
|
||||
onDragEnter: e => undefined,
|
||||
onDragOver: e => {
|
||||
const isDraggingGroup = this.groupTransfer.hasData(DraggedEditorGroupIdentifier.prototype);
|
||||
const isDraggingEditor = this.editorTransfer.hasData(DraggedEditorIdentifier.prototype);
|
||||
@@ -170,7 +170,7 @@ class DropOverlay extends Themable {
|
||||
return this.accessor.getGroup(this.editorTransfer.getData(DraggedEditorIdentifier.prototype)[0].identifier.groupId);
|
||||
}
|
||||
|
||||
return void 0;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private handleDrop(event: DragEvent, splitDirection?: GroupDirection): void {
|
||||
@@ -303,7 +303,7 @@ class DropOverlay extends Themable {
|
||||
mousePosX > edgeWidthThreshold && mousePosX < editorControlWidth - edgeWidthThreshold &&
|
||||
mousePosY > edgeHeightThreshold && mousePosY < editorControlHeight - edgeHeightThreshold
|
||||
) {
|
||||
splitDirection = void 0;
|
||||
splitDirection = undefined;
|
||||
}
|
||||
|
||||
// Offer to split otherwise
|
||||
@@ -413,7 +413,7 @@ class DropOverlay extends Themable {
|
||||
removeClass(this.overlay, 'overlay-move-transition');
|
||||
|
||||
// Reset current operation
|
||||
this.currentDropOperation = void 0;
|
||||
this.currentDropOperation = undefined;
|
||||
}
|
||||
|
||||
contains(element: HTMLElement): boolean {
|
||||
@@ -440,7 +440,7 @@ export class EditorDropTarget extends Themable {
|
||||
private accessor: IEditorGroupsAccessor,
|
||||
private container: HTMLElement,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IInstantiationService private instantiationService: IInstantiationService
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService
|
||||
) {
|
||||
super(themeService);
|
||||
|
||||
@@ -452,7 +452,7 @@ export class EditorDropTarget extends Themable {
|
||||
return this._overlay;
|
||||
}
|
||||
|
||||
return void 0;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private registerListeners(): void {
|
||||
@@ -512,15 +512,13 @@ export class EditorDropTarget extends Themable {
|
||||
|
||||
private findTargetGroupView(child: HTMLElement): IEditorGroupView {
|
||||
const groups = this.accessor.groups;
|
||||
for (let i = 0; i < groups.length; i++) {
|
||||
const groupView = groups[i];
|
||||
|
||||
for (const groupView of groups) {
|
||||
if (isAncestor(child, groupView.element)) {
|
||||
return groupView;
|
||||
}
|
||||
}
|
||||
|
||||
return void 0;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private updateContainer(isDraggedOver: boolean): void {
|
||||
@@ -536,7 +534,7 @@ export class EditorDropTarget extends Themable {
|
||||
private disposeOverlay(): void {
|
||||
if (this.overlay) {
|
||||
this.overlay.dispose();
|
||||
this._overlay = void 0;
|
||||
this._overlay = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,10 +4,9 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import 'vs/css!./media/editorgroupview';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { EditorGroup, IEditorOpenOptions, EditorCloseEvent, ISerializedEditorGroup, isSerializedEditorGroup } from 'vs/workbench/common/editor/editorGroup';
|
||||
import { EditorInput, EditorOptions, GroupIdentifier, ConfirmResult, SideBySideEditorInput, CloseDirection, IEditorCloseEvent, EditorGroupActiveEditorDirtyContext } from 'vs/workbench/common/editor';
|
||||
import { Event, Emitter, once, Relay } from 'vs/base/common/event';
|
||||
import { EditorInput, EditorOptions, GroupIdentifier, ConfirmResult, SideBySideEditorInput, CloseDirection, IEditorCloseEvent, EditorGroupActiveEditorDirtyContext, IEditor } from 'vs/workbench/common/editor';
|
||||
import { Event, Emitter, Relay } from 'vs/base/common/event';
|
||||
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { addClass, addClasses, Dimension, trackFocus, toggleClass, removeClass, addDisposableListener, EventType, EventHelper, findParentWithClass, clearNode, isAncestor } from 'vs/base/browser/dom';
|
||||
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
|
||||
@@ -100,7 +99,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
private active: boolean;
|
||||
private dimension: Dimension;
|
||||
|
||||
private _whenRestored: Thenable<void>;
|
||||
private _whenRestored: Promise<void>;
|
||||
private isRestored: boolean;
|
||||
|
||||
private scopedInstantiationService: IInstantiationService;
|
||||
@@ -116,21 +115,21 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
private ignoreOpenEditorErrors: boolean;
|
||||
private disposedEditorsWorker: RunOnceWorker<EditorInput>;
|
||||
|
||||
private mapEditorToPendingConfirmation: Map<EditorInput, TPromise<boolean>> = new Map<EditorInput, TPromise<boolean>>();
|
||||
private mapEditorToPendingConfirmation: Map<EditorInput, Promise<boolean>> = new Map<EditorInput, Promise<boolean>>();
|
||||
|
||||
constructor(
|
||||
private accessor: IEditorGroupsAccessor,
|
||||
from: IEditorGroupView | ISerializedEditorGroup,
|
||||
private _label: string,
|
||||
@IInstantiationService private instantiationService: IInstantiationService,
|
||||
@IContextKeyService private contextKeyService: IContextKeyService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@IContextKeyService private readonly contextKeyService: IContextKeyService,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@INotificationService private notificationService: INotificationService,
|
||||
@ITelemetryService private telemetryService: ITelemetryService,
|
||||
@IUntitledEditorService private untitledEditorService: IUntitledEditorService,
|
||||
@IKeybindingService private keybindingService: IKeybindingService,
|
||||
@IMenuService private menuService: IMenuService,
|
||||
@IContextMenuService private contextMenuService: IContextMenuService,
|
||||
@INotificationService private readonly notificationService: INotificationService,
|
||||
@ITelemetryService private readonly telemetryService: ITelemetryService,
|
||||
@IUntitledEditorService private readonly untitledEditorService: IUntitledEditorService,
|
||||
@IKeybindingService private readonly keybindingService: IKeybindingService,
|
||||
@IMenuService private readonly menuService: IMenuService,
|
||||
@IContextMenuService private readonly contextMenuService: IContextMenuService,
|
||||
// {{SQL CARBON EDIT}}
|
||||
@ICommandService private commandService: ICommandService
|
||||
) {
|
||||
@@ -141,7 +140,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
} else if (isSerializedEditorGroup(from)) {
|
||||
this._group = this._register(instantiationService.createInstance(EditorGroup, from));
|
||||
} else {
|
||||
this._group = this._register(instantiationService.createInstance(EditorGroup, void 0));
|
||||
this._group = this._register(instantiationService.createInstance(EditorGroup, undefined));
|
||||
}
|
||||
|
||||
this.disposedEditorsWorker = this._register(new RunOnceWorker(editors => this.handleDisposedEditors(editors), 0));
|
||||
@@ -283,9 +282,9 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
});
|
||||
|
||||
// Toolbar actions
|
||||
const removeGroupAction = this._register(new Action(CLOSE_EDITOR_GROUP_COMMAND_ID, localize('closeGroupAction', "Close"), 'close-editor-group', true, () => { this.accessor.removeGroup(this); return TPromise.as(true); }));
|
||||
const removeGroupAction = this._register(new Action(CLOSE_EDITOR_GROUP_COMMAND_ID, localize('closeGroupAction', "Close"), 'close-editor-group', true, () => { this.accessor.removeGroup(this); return Promise.resolve(true); }));
|
||||
const keybinding = this.keybindingService.lookupKeybinding(removeGroupAction.id);
|
||||
containerToolbar.push(removeGroupAction, { icon: true, label: false, keybinding: keybinding ? keybinding.getLabel() : void 0 });
|
||||
containerToolbar.push(removeGroupAction, { icon: true, label: false, keybinding: keybinding ? keybinding.getLabel() : undefined });
|
||||
}
|
||||
|
||||
private createContainerContextMenu(): void {
|
||||
@@ -309,7 +308,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
|
||||
// Fill in contributed actions
|
||||
const actions: IAction[] = [];
|
||||
fillInContextMenuActions(menu, void 0, actions, this.contextMenuService);
|
||||
fillInContextMenuActions(menu, undefined, actions, this.contextMenuService);
|
||||
|
||||
// Show it
|
||||
this.contextMenuService.showContextMenu({
|
||||
@@ -334,7 +333,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
let target: HTMLElement;
|
||||
if (e instanceof MouseEvent) {
|
||||
if (e.button !== 0) {
|
||||
return void 0; // only for left mouse click
|
||||
return undefined; // only for left mouse click
|
||||
}
|
||||
|
||||
target = e.target as HTMLElement;
|
||||
@@ -404,9 +403,9 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
}
|
||||
}
|
||||
|
||||
private restoreEditors(from: IEditorGroupView | ISerializedEditorGroup): Thenable<void> {
|
||||
private restoreEditors(from: IEditorGroupView | ISerializedEditorGroup): Promise<void> {
|
||||
if (this._group.count === 0) {
|
||||
return Promise.resolve(void 0); // nothing to show
|
||||
return Promise.resolve(); // nothing to show
|
||||
}
|
||||
|
||||
// Determine editor options
|
||||
@@ -491,7 +490,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
|
||||
// Close the editor when it is no longer open in any group including diff editors
|
||||
editorsToClose.forEach(editorToClose => {
|
||||
const resource = editorToClose ? editorToClose.getResource() : void 0; // prefer resource to not close right-hand side editors of a diff editor
|
||||
const resource = editorToClose ? editorToClose.getResource() : undefined; // prefer resource to not close right-hand side editors of a diff editor
|
||||
if (!this.accessor.groups.some(groupView => groupView.group.contains(resource || editorToClose))) {
|
||||
editorToClose.close();
|
||||
}
|
||||
@@ -609,7 +608,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
return this._disposed;
|
||||
}
|
||||
|
||||
get whenRestored(): Thenable<void> {
|
||||
get whenRestored(): Promise<void> {
|
||||
return this._whenRestored;
|
||||
}
|
||||
|
||||
@@ -660,7 +659,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
}
|
||||
|
||||
get activeControl(): BaseEditor {
|
||||
return this.editorControl ? this.editorControl.activeControl : void 0;
|
||||
return this.editorControl ? this.editorControl.activeControl : undefined;
|
||||
}
|
||||
|
||||
get activeEditor(): EditorInput {
|
||||
@@ -731,11 +730,11 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
|
||||
//#region openEditor()
|
||||
|
||||
openEditor(editor: EditorInput, options?: EditorOptions): TPromise<void> {
|
||||
openEditor(editor: EditorInput, options?: EditorOptions): Promise<IEditor | null> {
|
||||
|
||||
// Guard against invalid inputs
|
||||
if (!editor) {
|
||||
return TPromise.as(void 0);
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
|
||||
// Editor opening event allows for prevention
|
||||
@@ -750,11 +749,11 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
return this.doOpenEditor(editor, options);
|
||||
}
|
||||
|
||||
private doOpenEditor(editor: EditorInput, options?: EditorOptions): TPromise<void> {
|
||||
private doOpenEditor(editor: EditorInput, options?: EditorOptions): Promise<IEditor> {
|
||||
|
||||
// Determine options
|
||||
const openEditorOptions: IEditorOpenOptions = {
|
||||
index: options ? options.index : void 0,
|
||||
index: options ? options.index : undefined,
|
||||
pinned: !this.accessor.partOptions.enablePreview || editor.isDirty() || (options && options.pinned) || (options && typeof options.index === 'number'),
|
||||
active: this._group.count === 0 || !options || !options.inactive
|
||||
};
|
||||
@@ -791,10 +790,10 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
return this.doShowEditor(editor, openEditorOptions.active, options);
|
||||
}
|
||||
|
||||
private doShowEditor(editor: EditorInput, active: boolean, options?: EditorOptions): TPromise<void> {
|
||||
private doShowEditor(editor: EditorInput, active: boolean, options?: EditorOptions): Promise<IEditor> {
|
||||
|
||||
// Show in editor control if the active editor changed
|
||||
let openEditorPromise: TPromise<void>;
|
||||
let openEditorPromise: Promise<IEditor>;
|
||||
if (active) {
|
||||
openEditorPromise = this.editorControl.openEditor(editor, options).then(result => {
|
||||
|
||||
@@ -802,13 +801,17 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
if (result.editorChanged) {
|
||||
this._onDidGroupChange.fire({ kind: GroupChangeKind.EDITOR_ACTIVE, editor });
|
||||
}
|
||||
|
||||
return result.control;
|
||||
}, error => {
|
||||
|
||||
// Handle errors but do not bubble them up
|
||||
this.doHandleOpenEditorError(error, editor, options);
|
||||
|
||||
return null; // error: return NULL as result to signal this
|
||||
});
|
||||
} else {
|
||||
openEditorPromise = TPromise.as(void 0);
|
||||
openEditorPromise = Promise.resolve(null); // inactive: return NULL as result to signal this
|
||||
}
|
||||
|
||||
// Show in title control after editor control because some actions depend on it
|
||||
@@ -833,7 +836,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
actions
|
||||
});
|
||||
|
||||
once(handle.onDidClose)(() => dispose(actions.primary));
|
||||
Event.once(handle.onDidClose)(() => dispose(actions.primary));
|
||||
}
|
||||
|
||||
// Event
|
||||
@@ -850,17 +853,21 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
|
||||
//#region openEditors()
|
||||
|
||||
openEditors(editors: { editor: EditorInput, options?: EditorOptions }[]): TPromise<void> {
|
||||
openEditors(editors: { editor: EditorInput, options?: EditorOptions }[]): Promise<IEditor | null> {
|
||||
if (!editors.length) {
|
||||
return TPromise.as(void 0);
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
|
||||
// Do not modify original array
|
||||
editors = editors.slice(0);
|
||||
|
||||
let result: IEditor;
|
||||
|
||||
// Use the first editor as active editor
|
||||
const { editor, options } = editors.shift();
|
||||
return this.openEditor(editor, options).then(() => {
|
||||
return this.openEditor(editor, options).then(activeEditor => {
|
||||
result = activeEditor; // this can be NULL if the opening failed
|
||||
|
||||
const startingIndex = this.getIndexOfEditor(editor) + 1;
|
||||
|
||||
// Open the other ones inactive
|
||||
@@ -870,8 +877,12 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
adjustedEditorOptions.pinned = true;
|
||||
adjustedEditorOptions.index = startingIndex + index;
|
||||
|
||||
return this.openEditor(editor, adjustedEditorOptions);
|
||||
})).then(() => void 0);
|
||||
return this.openEditor(editor, adjustedEditorOptions).then(activeEditor => {
|
||||
if (!result) {
|
||||
result = activeEditor; // only take if the first editor opening failed
|
||||
}
|
||||
});
|
||||
})).then(() => result);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -893,7 +904,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
}
|
||||
|
||||
private doMoveEditorInsideGroup(editor: EditorInput, moveOptions?: IMoveEditorOptions): void {
|
||||
const moveToIndex = moveOptions ? moveOptions.index : void 0;
|
||||
const moveToIndex = moveOptions ? moveOptions.index : undefined;
|
||||
if (typeof moveToIndex !== 'number') {
|
||||
return; // do nothing if we move into same group without index
|
||||
}
|
||||
@@ -953,9 +964,9 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
|
||||
//#region closeEditor()
|
||||
|
||||
closeEditor(editor: EditorInput = this.activeEditor): TPromise<void> {
|
||||
closeEditor(editor: EditorInput = this.activeEditor): Promise<void> {
|
||||
if (!editor) {
|
||||
return TPromise.as(void 0);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
// Check for dirty and veto
|
||||
@@ -1025,7 +1036,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
this.ignoreOpenEditorErrors = true;
|
||||
}
|
||||
|
||||
const options = !focusNext ? EditorOptions.create({ preserveFocus: true }) : void 0;
|
||||
const options = !focusNext ? EditorOptions.create({ preserveFocus: true }) : undefined;
|
||||
this.openEditor(nextActiveEditor, options).then(() => {
|
||||
this.ignoreOpenEditorErrors = false;
|
||||
});
|
||||
@@ -1069,9 +1080,9 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
this._group.closeEditor(editor);
|
||||
}
|
||||
|
||||
private handleDirty(editors: EditorInput[]): TPromise<boolean /* veto */> {
|
||||
private handleDirty(editors: EditorInput[]): Promise<boolean /* veto */> {
|
||||
if (!editors.length) {
|
||||
return TPromise.as(false); // no veto
|
||||
return Promise.resolve(false); // no veto
|
||||
}
|
||||
|
||||
const editor = editors.shift();
|
||||
@@ -1099,13 +1110,13 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
});
|
||||
}
|
||||
|
||||
private doHandleDirty(editor: EditorInput): TPromise<boolean /* veto */> {
|
||||
private doHandleDirty(editor: EditorInput): Promise<boolean /* veto */> {
|
||||
if (
|
||||
!editor.isDirty() || // editor must be dirty
|
||||
this.accessor.groups.some(groupView => groupView !== this && groupView.group.contains(editor, true /* support side by side */)) || // editor is opened in other group
|
||||
editor instanceof SideBySideEditorInput && this.isOpened(editor.master) // side by side editor master is still opened
|
||||
) {
|
||||
return TPromise.as(false);
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
|
||||
// Switch to editor that we want to handle and confirm to save/revert
|
||||
@@ -1146,9 +1157,9 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
|
||||
//#region closeEditors()
|
||||
|
||||
closeEditors(args: EditorInput[] | ICloseEditorsFilter): TPromise<void> {
|
||||
closeEditors(args: EditorInput[] | ICloseEditorsFilter): Promise<void> {
|
||||
if (this.isEmpty()) {
|
||||
return TPromise.as(void 0);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
const editors = this.getEditorsToClose(args);
|
||||
@@ -1219,7 +1230,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
|
||||
//#region closeAllEditors()
|
||||
|
||||
closeAllEditors(): TPromise<void> {
|
||||
closeAllEditors(): Promise<void> {
|
||||
if (this.isEmpty()) {
|
||||
|
||||
// If the group is empty and the request is to close all editors, we still close
|
||||
@@ -1229,7 +1240,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
this.accessor.removeGroup(this);
|
||||
}
|
||||
|
||||
return TPromise.as(void 0);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
// Check for dirty and veto
|
||||
@@ -1264,7 +1275,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
|
||||
//#region replaceEditors()
|
||||
|
||||
replaceEditors(editors: EditorReplacement[]): TPromise<void> {
|
||||
replaceEditors(editors: EditorReplacement[]): Promise<void> {
|
||||
|
||||
// Extract active vs. inactive replacements
|
||||
let activeReplacement: EditorReplacement;
|
||||
@@ -1322,10 +1333,10 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
// Forward to title control
|
||||
this.titleAreaControl.closeEditor(activeReplacement.editor);
|
||||
|
||||
return openEditorResult;
|
||||
return openEditorResult.then(() => undefined);
|
||||
}
|
||||
|
||||
return TPromise.as(void 0);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
//#endregion
|
||||
@@ -1379,6 +1390,10 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
layout(width: number, height: number): void {
|
||||
this.dimension = new Dimension(width, height);
|
||||
|
||||
// Ensure editor container gets height as CSS depending
|
||||
// on the preferred height of the title control
|
||||
this.editorContainer.style.height = `calc(100% - ${this.titleAreaControl.getPreferredHeight()}px)`;
|
||||
|
||||
// Forward to controls
|
||||
this.titleAreaControl.layout(new Dimension(this.dimension.width, this.titleAreaControl.getPreferredHeight()));
|
||||
this.editorControl.layout(new Dimension(this.dimension.width, this.dimension.height - this.titleAreaControl.getPreferredHeight()));
|
||||
@@ -1410,7 +1425,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
}
|
||||
|
||||
class EditorOpeningEvent implements IEditorOpeningEvent {
|
||||
private override: () => TPromise<any>;
|
||||
private override: () => Promise<IEditor>;
|
||||
|
||||
constructor(
|
||||
private _group: GroupIdentifier,
|
||||
@@ -1431,11 +1446,11 @@ class EditorOpeningEvent implements IEditorOpeningEvent {
|
||||
return this._options;
|
||||
}
|
||||
|
||||
prevent(callback: () => TPromise<any>): void {
|
||||
prevent(callback: () => Promise<IEditor>): void {
|
||||
this.override = callback;
|
||||
}
|
||||
|
||||
isPrevented(): () => TPromise<any> {
|
||||
isPrevented(): () => Promise<IEditor> {
|
||||
return this.override;
|
||||
}
|
||||
}
|
||||
@@ -1451,7 +1466,7 @@ registerThemingParticipant((theme, collector, environment) => {
|
||||
// Letterpress
|
||||
const letterpress = `resources/letterpress${theme.type === 'dark' ? '-dark' : theme.type === 'hc' ? '-hc' : ''}.svg`;
|
||||
collector.addRule(`
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container.empty .editor-group-letterpress {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container.empty .editor-group-letterpress {
|
||||
background-image: url('${URI.file(join(environment.appRoot, letterpress)).toString()}')
|
||||
}
|
||||
`);
|
||||
@@ -1460,20 +1475,20 @@ registerThemingParticipant((theme, collector, environment) => {
|
||||
const focusedEmptyGroupBorder = theme.getColor(EDITOR_GROUP_FOCUSED_EMPTY_BORDER);
|
||||
if (focusedEmptyGroupBorder) {
|
||||
collector.addRule(`
|
||||
.monaco-workbench > .part.editor > .content:not(.empty) .editor-group-container.empty.active:focus {
|
||||
.monaco-workbench .part.editor > .content:not(.empty) .editor-group-container.empty.active:focus {
|
||||
outline-width: 1px;
|
||||
outline-color: ${focusedEmptyGroupBorder};
|
||||
outline-offset: -2px;
|
||||
outline-style: solid;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content.empty .editor-group-container.empty.active:focus {
|
||||
.monaco-workbench .part.editor > .content.empty .editor-group-container.empty.active:focus {
|
||||
outline: none; /* never show outline for empty group if it is the last */
|
||||
}
|
||||
`);
|
||||
} else {
|
||||
collector.addRule(`
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container.empty.active:focus {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container.empty.active:focus {
|
||||
outline: none; /* disable focus outline unless active empty group border is defined */
|
||||
}
|
||||
`);
|
||||
|
||||
@@ -7,11 +7,11 @@ import 'vs/workbench/browser/parts/editor/editor.contribution';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { Part } from 'vs/workbench/browser/part';
|
||||
import { Dimension, isAncestor, toggleClass, addClass, $ } from 'vs/base/browser/dom';
|
||||
import { Event, Emitter, once, Relay, anyEvent } from 'vs/base/common/event';
|
||||
import { Event, Emitter, Relay } from 'vs/base/common/event';
|
||||
import { contrastBorder, editorBackground } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { GroupDirection, IAddGroupOptions, GroupsArrangement, GroupOrientation, IMergeGroupOptions, MergeGroupMode, ICopyEditorOptions, GroupsOrder, GroupChangeKind, GroupLocation, IFindGroupScope, EditorGroupLayout, GroupLayoutArgument } from 'vs/workbench/services/group/common/editorGroupsService';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { Direction, SerializableGrid, Sizing, ISerializedGrid, Orientation, GridBranchNode, isGridBranchNode, GridNode, createSerializedGrid, Grid } from 'vs/base/browser/ui/grid/grid';
|
||||
import { Direction, SerializableGrid, Sizing, ISerializedGrid, Orientation, GridBranchNode, isGridBranchNode, GridNode, createSerializedGrid, Grid, ISerializableView } from 'vs/base/browser/ui/grid/grid';
|
||||
import { GroupIdentifier, IWorkbenchEditorConfiguration } from 'vs/workbench/common/editor';
|
||||
import { values } from 'vs/base/common/map';
|
||||
import { EDITOR_GROUP_BORDER, EDITOR_PANE_BACKGROUND } from 'vs/workbench/common/theme';
|
||||
@@ -23,13 +23,13 @@ import { IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { assign } from 'vs/base/common/objects';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { ISerializedEditorGroup, isSerializedEditorGroup } from 'vs/workbench/common/editor/editorGroup';
|
||||
import { always } from 'vs/base/common/async';
|
||||
import { EditorDropTarget } from 'vs/workbench/browser/parts/editor/editorDropTarget';
|
||||
import { localize } from 'vs/nls';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { CenteredViewLayout } from 'vs/base/browser/ui/centered/centeredViewLayout';
|
||||
import { IView, orthogonal } from 'vs/base/browser/ui/grid/gridview';
|
||||
import { IView, orthogonal, LayoutPriority } from 'vs/base/browser/ui/grid/gridview';
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { Parts } from 'vs/workbench/services/part/common/partService';
|
||||
|
||||
// {{SQL CARBON EDIT}}
|
||||
import { convertEditorInput } from 'sql/parts/common/customInputConverter';
|
||||
@@ -83,7 +83,7 @@ class GridWidgetView<T extends IView> implements IView {
|
||||
}
|
||||
}
|
||||
|
||||
export class EditorPart extends Part implements EditorGroupsServiceImpl, IEditorGroupsAccessor {
|
||||
export class EditorPart extends Part implements EditorGroupsServiceImpl, IEditorGroupsAccessor, ISerializableView {
|
||||
|
||||
_serviceBrand: any;
|
||||
|
||||
@@ -109,11 +109,14 @@ export class EditorPart extends Part implements EditorGroupsServiceImpl, IEditor
|
||||
|
||||
private onDidSetGridWidget = this._register(new Emitter<{ width: number; height: number; }>());
|
||||
private _onDidSizeConstraintsChange = this._register(new Relay<{ width: number; height: number; }>());
|
||||
get onDidSizeConstraintsChange(): Event<{ width: number; height: number; }> { return anyEvent(this.onDidSetGridWidget.event, this._onDidSizeConstraintsChange.event); }
|
||||
get onDidSizeConstraintsChange(): Event<{ width: number; height: number; }> { return Event.any(this.onDidSetGridWidget.event, this._onDidSizeConstraintsChange.event); }
|
||||
|
||||
private _onDidPreferredSizeChange: Emitter<void> = this._register(new Emitter<void>());
|
||||
get onDidPreferredSizeChange(): Event<void> { return this._onDidPreferredSizeChange.event; }
|
||||
|
||||
private _onDidActivateGroup: Emitter<IEditorGroupView> = this._register(new Emitter<IEditorGroupView>());
|
||||
get onDidActivateGroup(): Event<IEditorGroupView> { return this._onDidActivateGroup.event; }
|
||||
|
||||
//#endregion
|
||||
|
||||
private dimension: Dimension;
|
||||
@@ -133,15 +136,22 @@ export class EditorPart extends Part implements EditorGroupsServiceImpl, IEditor
|
||||
private gridWidget: SerializableGrid<IEditorGroupView>;
|
||||
private gridWidgetView: GridWidgetView<IEditorGroupView>;
|
||||
|
||||
private _whenRestored: Thenable<void>;
|
||||
private _whenRestored: Promise<void>;
|
||||
private whenRestoredResolve: () => void;
|
||||
|
||||
element: HTMLElement;
|
||||
|
||||
private _onDidChange = new Emitter<{ width: number; height: number; }>();
|
||||
readonly onDidChange = this._onDidChange.event;
|
||||
|
||||
priority: LayoutPriority = LayoutPriority.High;
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
private restorePreviousState: boolean,
|
||||
@IInstantiationService private instantiationService: IInstantiationService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IConfigurationService private configurationService: IConfigurationService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@IStorageService storageService: IStorageService
|
||||
) {
|
||||
super(id, { hasTitle: false }, themeService, storageService);
|
||||
@@ -220,13 +230,13 @@ export class EditorPart extends Part implements EditorGroupsServiceImpl, IEditor
|
||||
|
||||
get orientation(): GroupOrientation {
|
||||
if (!this.gridWidget) {
|
||||
return void 0; // we have not been created yet
|
||||
return undefined; // we have not been created yet
|
||||
}
|
||||
|
||||
return this.gridWidget.orientation === Orientation.VERTICAL ? GroupOrientation.VERTICAL : GroupOrientation.HORIZONTAL;
|
||||
}
|
||||
|
||||
get whenRestored(): Thenable<void> {
|
||||
get whenRestored(): Promise<void> {
|
||||
return this._whenRestored;
|
||||
}
|
||||
|
||||
@@ -316,6 +326,7 @@ export class EditorPart extends Part implements EditorGroupsServiceImpl, IEditor
|
||||
const groupView = this.assertGroupView(group);
|
||||
this.doSetGroupActive(groupView);
|
||||
|
||||
this._onDidActivateGroup.fire(groupView);
|
||||
return groupView;
|
||||
}
|
||||
|
||||
@@ -527,7 +538,7 @@ export class EditorPart extends Part implements EditorGroupsServiceImpl, IEditor
|
||||
}));
|
||||
|
||||
// Track dispose
|
||||
once(groupView.onWillDispose)(() => {
|
||||
Event.once(groupView.onWillDispose)(() => {
|
||||
groupDisposables = dispose(groupDisposables);
|
||||
this.groupViews.delete(groupView.id);
|
||||
this.doUpdateMostRecentActive(groupView);
|
||||
@@ -762,7 +773,7 @@ export class EditorPart extends Part implements EditorGroupsServiceImpl, IEditor
|
||||
private resetPreferredSize(): void {
|
||||
|
||||
// Reset (will be computed upon next access)
|
||||
this._preferredSize = void 0;
|
||||
this._preferredSize = undefined;
|
||||
|
||||
// Event
|
||||
this._onDidPreferredSizeChange.fire();
|
||||
@@ -783,6 +794,7 @@ export class EditorPart extends Part implements EditorGroupsServiceImpl, IEditor
|
||||
createContentArea(parent: HTMLElement): HTMLElement {
|
||||
|
||||
// Container
|
||||
this.element = parent;
|
||||
this.container = document.createElement('div');
|
||||
addClass(this.container, 'content');
|
||||
parent.appendChild(this.container);
|
||||
@@ -824,7 +836,7 @@ export class EditorPart extends Part implements EditorGroupsServiceImpl, IEditor
|
||||
}
|
||||
|
||||
// Signal restored
|
||||
always(Promise.all(this.groups.map(group => group.whenRestored)), () => this.whenRestoredResolve());
|
||||
Promise.all(this.groups.map(group => group.whenRestored)).finally(() => this.whenRestoredResolve());
|
||||
|
||||
// Update container
|
||||
this.updateContainer();
|
||||
@@ -861,7 +873,7 @@ export class EditorPart extends Part implements EditorGroupsServiceImpl, IEditor
|
||||
|
||||
this.groupViews.forEach(group => group.dispose());
|
||||
this.groupViews.clear();
|
||||
this._activeGroup = void 0;
|
||||
this._activeGroup = undefined;
|
||||
this.mostRecentActiveGroups = [];
|
||||
}
|
||||
|
||||
@@ -924,7 +936,7 @@ export class EditorPart extends Part implements EditorGroupsServiceImpl, IEditor
|
||||
this._onDidSizeConstraintsChange.input = gridWidget.onDidChange;
|
||||
}
|
||||
|
||||
this.onDidSetGridWidget.fire();
|
||||
this.onDidSetGridWidget.fire(undefined);
|
||||
}
|
||||
|
||||
private updateContainer(): void {
|
||||
@@ -950,12 +962,16 @@ export class EditorPart extends Part implements EditorGroupsServiceImpl, IEditor
|
||||
return this.groupViews.size === 1 && this._activeGroup.isEmpty();
|
||||
}
|
||||
|
||||
layout(dimension: Dimension): Dimension[] {
|
||||
const sizes = super.layout(dimension);
|
||||
layout(dimension: Dimension): Dimension[];
|
||||
layout(width: number, height: number): void;
|
||||
layout(dim1: Dimension | number, dim2?: number): Dimension[] | void {
|
||||
const sizes = super.layout(dim1 instanceof Dimension ? dim1 : new Dimension(dim1, dim2));
|
||||
|
||||
this.doLayout(sizes[1]);
|
||||
|
||||
return sizes;
|
||||
if (dim1 instanceof Dimension) {
|
||||
return sizes;
|
||||
}
|
||||
}
|
||||
|
||||
private doLayout(dimension: Dimension): void {
|
||||
@@ -1016,4 +1032,10 @@ export class EditorPart extends Part implements EditorGroupsServiceImpl, IEditor
|
||||
}
|
||||
|
||||
//#endregion
|
||||
}
|
||||
|
||||
toJSON(): object {
|
||||
return {
|
||||
type: Parts.EDITOR_PART
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,8 +25,8 @@ export class EditorPickerEntry extends QuickOpenEntryGroup {
|
||||
constructor(
|
||||
private editor: EditorInput,
|
||||
private _group: IEditorGroup,
|
||||
@IModeService private modeService: IModeService,
|
||||
@IModelService private modelService: IModelService
|
||||
@IModeService private readonly modeService: IModeService,
|
||||
@IModelService private readonly modelService: IModelService
|
||||
) {
|
||||
super();
|
||||
}
|
||||
@@ -90,7 +90,7 @@ export abstract class BaseEditorPicker extends QuickOpenHandler {
|
||||
this.scorerCache = Object.create(null);
|
||||
}
|
||||
|
||||
getResults(searchValue: string, token: CancellationToken): Thenable<QuickOpenModel> {
|
||||
getResults(searchValue: string, token: CancellationToken): Promise<QuickOpenModel | null> {
|
||||
const editorEntries = this.getEditorEntries();
|
||||
if (!editorEntries.length) {
|
||||
return Promise.resolve(null);
|
||||
|
||||
@@ -50,7 +50,7 @@ import { IQuickInputService, IQuickPickItem, QuickPickInput } from 'vs/platform/
|
||||
import { getIconClasses } from 'vs/editor/common/services/getIconClasses';
|
||||
import { timeout } from 'vs/base/common/async';
|
||||
import { INotificationHandle, INotificationService, Severity } from 'vs/platform/notification/common/notification';
|
||||
import { once } from 'vs/base/common/event';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
|
||||
class SideBySideEditorEncodingSupport implements IEncodingSupport {
|
||||
constructor(private master: IEncodingSupport, private details: IEncodingSupport) { }
|
||||
@@ -290,12 +290,12 @@ export class EditorStatus implements IStatusbarItem {
|
||||
private screenReaderNotification: INotificationHandle;
|
||||
|
||||
constructor(
|
||||
@IEditorService private editorService: IEditorService,
|
||||
@IQuickOpenService private quickOpenService: IQuickOpenService,
|
||||
@IInstantiationService private instantiationService: IInstantiationService,
|
||||
@IUntitledEditorService private untitledEditorService: IUntitledEditorService,
|
||||
@IModeService private modeService: IModeService,
|
||||
@ITextFileService private textFileService: ITextFileService,
|
||||
@IEditorService private readonly editorService: IEditorService,
|
||||
@IQuickOpenService private readonly quickOpenService: IQuickOpenService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@IUntitledEditorService private readonly untitledEditorService: IUntitledEditorService,
|
||||
@IModeService private readonly modeService: IModeService,
|
||||
@ITextFileService private readonly textFileService: ITextFileService,
|
||||
@IWorkspaceConfigurationService private readonly configurationService: IWorkspaceConfigurationService,
|
||||
@INotificationService private readonly notificationService: INotificationService
|
||||
) {
|
||||
@@ -518,7 +518,7 @@ export class EditorStatus implements IStatusbarItem {
|
||||
{ sticky: true }
|
||||
);
|
||||
|
||||
once(this.screenReaderNotification.onDidClose)(() => {
|
||||
Event.once(this.screenReaderNotification.onDidClose)(() => {
|
||||
this.screenReaderNotification = null;
|
||||
});
|
||||
}
|
||||
@@ -548,7 +548,7 @@ export class EditorStatus implements IStatusbarItem {
|
||||
|
||||
private updateStatusBar(): void {
|
||||
const activeControl = this.editorService.activeControl;
|
||||
const activeCodeEditor = activeControl ? getCodeEditor(activeControl.getControl()) : void 0;
|
||||
const activeCodeEditor = activeControl ? getCodeEditor(activeControl.getControl()) : undefined;
|
||||
|
||||
// Update all states
|
||||
this.onScreenReaderModeChange(activeCodeEditor);
|
||||
@@ -587,8 +587,8 @@ export class EditorStatus implements IStatusbarItem {
|
||||
this.onEOLChange(activeCodeEditor);
|
||||
|
||||
let selections = activeCodeEditor.getSelections();
|
||||
for (let i = 0; i < e.changes.length; i++) {
|
||||
if (selections.some(selection => Range.areIntersecting(selection, e.changes[i].range))) {
|
||||
for (const change of e.changes) {
|
||||
if (selections.some(selection => Range.areIntersecting(selection, change.range))) {
|
||||
this.onSelectionChange(activeCodeEditor);
|
||||
break;
|
||||
}
|
||||
@@ -820,7 +820,7 @@ export class ShowLanguageExtensionsAction extends Action {
|
||||
|
||||
constructor(
|
||||
private fileExtension: string,
|
||||
@ICommandService private commandService: ICommandService,
|
||||
@ICommandService private readonly commandService: ICommandService,
|
||||
@IExtensionGalleryService galleryService: IExtensionGalleryService
|
||||
) {
|
||||
super(ShowLanguageExtensionsAction.ID, nls.localize('showLanguageExtensions', "Search Marketplace Extensions for '{0}'...", fileExtension));
|
||||
@@ -828,8 +828,8 @@ export class ShowLanguageExtensionsAction extends Action {
|
||||
this.enabled = galleryService.isEnabled();
|
||||
}
|
||||
|
||||
run(): Thenable<void> {
|
||||
return this.commandService.executeCommand('workbench.extensions.action.showExtensionsForLanguage', this.fileExtension).then(() => void 0);
|
||||
run(): Promise<void> {
|
||||
return this.commandService.executeCommand('workbench.extensions.action.showExtensionsForLanguage', this.fileExtension).then(() => undefined);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -841,19 +841,19 @@ export class ChangeModeAction extends Action {
|
||||
constructor(
|
||||
actionId: string,
|
||||
actionLabel: string,
|
||||
@IModeService private modeService: IModeService,
|
||||
@IModelService private modelService: IModelService,
|
||||
@IEditorService private editorService: IEditorService,
|
||||
@IWorkspaceConfigurationService private configurationService: IWorkspaceConfigurationService,
|
||||
@IQuickInputService private quickInputService: IQuickInputService,
|
||||
@IPreferencesService private preferencesService: IPreferencesService,
|
||||
@IInstantiationService private instantiationService: IInstantiationService,
|
||||
@IUntitledEditorService private untitledEditorService: IUntitledEditorService
|
||||
@IModeService private readonly modeService: IModeService,
|
||||
@IModelService private readonly modelService: IModelService,
|
||||
@IEditorService private readonly editorService: IEditorService,
|
||||
@IWorkspaceConfigurationService private readonly configurationService: IWorkspaceConfigurationService,
|
||||
@IQuickInputService private readonly quickInputService: IQuickInputService,
|
||||
@IPreferencesService private readonly preferencesService: IPreferencesService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@IUntitledEditorService private readonly untitledEditorService: IUntitledEditorService
|
||||
) {
|
||||
super(actionId, actionLabel);
|
||||
}
|
||||
|
||||
run(): Thenable<any> {
|
||||
run(): Promise<any> {
|
||||
const activeTextEditorWidget = getCodeEditor(this.editorService.activeTextEditorWidget);
|
||||
if (!activeTextEditorWidget) {
|
||||
return this.quickInputService.pick([{ label: nls.localize('noEditor', "No text editor active at this time") }]);
|
||||
@@ -958,6 +958,7 @@ export class ChangeModeAction extends Action {
|
||||
}
|
||||
|
||||
// Change mode for active editor
|
||||
// {{SQL CARBON EDIT}} - Get activeControl instead of activeEditor
|
||||
const activeEditor = this.editorService.activeControl;
|
||||
const activeTextEditorWidget = this.editorService.activeTextEditorWidget;
|
||||
const models: ITextModel[] = [];
|
||||
@@ -1012,7 +1013,7 @@ export class ChangeModeAction extends Action {
|
||||
return <IQuickPickItem>{
|
||||
id,
|
||||
label: lang,
|
||||
description: (id === currentAssociation) ? nls.localize('currentAssociation', "Current Association") : void 0
|
||||
description: (id === currentAssociation) ? nls.localize('currentAssociation', "Current Association") : undefined
|
||||
};
|
||||
});
|
||||
|
||||
@@ -1061,13 +1062,13 @@ class ChangeIndentationAction extends Action {
|
||||
constructor(
|
||||
actionId: string,
|
||||
actionLabel: string,
|
||||
@IEditorService private editorService: IEditorService,
|
||||
@IQuickInputService private quickInputService: IQuickInputService
|
||||
@IEditorService private readonly editorService: IEditorService,
|
||||
@IQuickInputService private readonly quickInputService: IQuickInputService
|
||||
) {
|
||||
super(actionId, actionLabel);
|
||||
}
|
||||
|
||||
run(): Thenable<any> {
|
||||
run(): Promise<any> {
|
||||
const activeTextEditorWidget = getCodeEditor(this.editorService.activeTextEditorWidget);
|
||||
if (!activeTextEditorWidget) {
|
||||
return this.quickInputService.pick([{ label: nls.localize('noEditor', "No text editor active at this time") }]);
|
||||
@@ -1111,13 +1112,13 @@ export class ChangeEOLAction extends Action {
|
||||
constructor(
|
||||
actionId: string,
|
||||
actionLabel: string,
|
||||
@IEditorService private editorService: IEditorService,
|
||||
@IQuickInputService private quickInputService: IQuickInputService
|
||||
@IEditorService private readonly editorService: IEditorService,
|
||||
@IQuickInputService private readonly quickInputService: IQuickInputService
|
||||
) {
|
||||
super(actionId, actionLabel);
|
||||
}
|
||||
|
||||
run(): Thenable<any> {
|
||||
run(): Promise<any> {
|
||||
const activeTextEditorWidget = getCodeEditor(this.editorService.activeTextEditorWidget);
|
||||
if (!activeTextEditorWidget) {
|
||||
return this.quickInputService.pick([{ label: nls.localize('noEditor', "No text editor active at this time") }]);
|
||||
@@ -1156,15 +1157,15 @@ export class ChangeEncodingAction extends Action {
|
||||
constructor(
|
||||
actionId: string,
|
||||
actionLabel: string,
|
||||
@IEditorService private editorService: IEditorService,
|
||||
@IQuickInputService private quickInputService: IQuickInputService,
|
||||
@ITextResourceConfigurationService private textResourceConfigurationService: ITextResourceConfigurationService,
|
||||
@IFileService private fileService: IFileService
|
||||
@IEditorService private readonly editorService: IEditorService,
|
||||
@IQuickInputService private readonly quickInputService: IQuickInputService,
|
||||
@ITextResourceConfigurationService private readonly textResourceConfigurationService: ITextResourceConfigurationService,
|
||||
@IFileService private readonly fileService: IFileService
|
||||
) {
|
||||
super(actionId, actionLabel);
|
||||
}
|
||||
|
||||
run(): Thenable<any> {
|
||||
run(): Promise<any> {
|
||||
if (!getCodeEditor(this.editorService.activeTextEditorWidget)) {
|
||||
return this.quickInputService.pick([{ label: nls.localize('noEditor', "No text editor active at this time") }]);
|
||||
}
|
||||
@@ -1196,7 +1197,7 @@ export class ChangeEncodingAction extends Action {
|
||||
|
||||
return pickActionPromise.then(action => {
|
||||
if (!action) {
|
||||
return void 0;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const resource = toResource(activeControl.input, { supportSideBySide: true });
|
||||
|
||||
@@ -34,7 +34,7 @@ export class FloatingClickWidget extends Widget implements IOverlayWidget {
|
||||
private label: string,
|
||||
keyBindingAction: string,
|
||||
@IKeybindingService keybindingService: IKeybindingService,
|
||||
@IThemeService private themeService: IThemeService
|
||||
@IThemeService private readonly themeService: IThemeService
|
||||
) {
|
||||
super();
|
||||
|
||||
@@ -106,9 +106,9 @@ export class OpenWorkspaceButtonContribution extends Disposable implements IEdit
|
||||
|
||||
constructor(
|
||||
private editor: ICodeEditor,
|
||||
@IInstantiationService private instantiationService: IInstantiationService,
|
||||
@IWindowService private windowService: IWindowService,
|
||||
@IWorkspaceContextService private contextService: IWorkspaceContextService
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@IWindowService private readonly windowService: IWindowService,
|
||||
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService
|
||||
) {
|
||||
super();
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 381 B After Width: | Height: | Size: 266 B |
@@ -3,17 +3,17 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
.monaco-workbench>.part.editor>.content .editor-group-container .breadcrumbs-control.hidden {
|
||||
.monaco-workbench .part.editor>.content .editor-group-container .breadcrumbs-control.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.monaco-workbench>.part.editor>.content .editor-group-container .breadcrumbs-control .monaco-breadcrumb-item.selected .monaco-icon-label,
|
||||
.monaco-workbench>.part.editor>.content .editor-group-container .breadcrumbs-control .monaco-breadcrumb-item.focused .monaco-icon-label {
|
||||
.monaco-workbench .part.editor>.content .editor-group-container .breadcrumbs-control .monaco-breadcrumb-item.selected .monaco-icon-label,
|
||||
.monaco-workbench .part.editor>.content .editor-group-container .breadcrumbs-control .monaco-breadcrumb-item.focused .monaco-icon-label {
|
||||
text-decoration-line: underline;
|
||||
}
|
||||
|
||||
.monaco-workbench>.part.editor>.content .editor-group-container .breadcrumbs-control .monaco-breadcrumb-item.selected .hint-more,
|
||||
.monaco-workbench>.part.editor>.content .editor-group-container .breadcrumbs-control .monaco-breadcrumb-item.focused .hint-more {
|
||||
.monaco-workbench .part.editor>.content .editor-group-container .breadcrumbs-control .monaco-breadcrumb-item.selected .hint-more,
|
||||
.monaco-workbench .part.editor>.content .editor-group-container .breadcrumbs-control .monaco-breadcrumb-item.focused .hint-more {
|
||||
text-decoration-line: underline;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,26 +5,26 @@
|
||||
|
||||
/* Container */
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container.empty {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container.empty {
|
||||
opacity: 0.5; /* dimmed to indicate inactive state */
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container.empty.active,
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container.empty.dragged-over {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container.empty.active,
|
||||
.monaco-workbench .part.editor > .content .editor-group-container.empty.dragged-over {
|
||||
opacity: 1; /* indicate active/dragged-over group through undimmed state */
|
||||
}
|
||||
|
||||
/* Letterpress */
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .editor-group-letterpress {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .editor-group-letterpress {
|
||||
display: none; /* only visible when empty */
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container.empty > .editor-group-letterpress {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container.empty > .editor-group-letterpress {
|
||||
display: block;
|
||||
margin: auto;
|
||||
width: 100%;
|
||||
@@ -35,25 +35,25 @@
|
||||
background-size: 70% 70%;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content.empty .editor-group-container.empty > .editor-group-letterpress {
|
||||
.monaco-workbench .part.editor > .content.empty .editor-group-container.empty > .editor-group-letterpress {
|
||||
background-size: 100% 100%; /* larger for empty editor part */
|
||||
height: 100%; /* no toolbar in this case */
|
||||
}
|
||||
|
||||
/* Title */
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title {
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title:not(.tabs) {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title:not(.tabs) {
|
||||
display: flex; /* when tabs are not shown, use flex layout */
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title.title-border-bottom::after {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title.title-border-bottom::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
@@ -65,21 +65,21 @@
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container.empty > .title {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container.empty > .title {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Toolbar */
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .editor-group-container-toolbar {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .editor-group-container-toolbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content:not(.empty) .editor-group-container.empty > .editor-group-container-toolbar {
|
||||
.monaco-workbench .part.editor > .content:not(.empty) .editor-group-container.empty > .editor-group-container-toolbar {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .editor-group-container-toolbar .action-label {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .editor-group-container-toolbar .action-label {
|
||||
display: block;
|
||||
height: 35px;
|
||||
line-height: 35px;
|
||||
@@ -89,30 +89,26 @@
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.vs .monaco-workbench > .part.editor > .content .editor-group-container > .editor-group-container-toolbar .close-editor-group {
|
||||
.vs .monaco-workbench .part.editor > .content .editor-group-container > .editor-group-container-toolbar .close-editor-group {
|
||||
background-image: url('close-big.svg');
|
||||
}
|
||||
|
||||
.vs-dark .monaco-workbench > .part.editor > .content .editor-group-container > .editor-group-container-toolbar .close-editor-group,
|
||||
.hc-black .monaco-workbench > .part.editor > .content .editor-group-container > .editor-group-container-toolbar .close-editor-group {
|
||||
.vs-dark .monaco-workbench .part.editor > .content .editor-group-container > .editor-group-container-toolbar .close-editor-group,
|
||||
.hc-black .monaco-workbench .part.editor > .content .editor-group-container > .editor-group-container-toolbar .close-editor-group {
|
||||
background-image: url('close-big-inverse.svg');
|
||||
}
|
||||
|
||||
/* Editor */
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .editor-container {
|
||||
height: calc(100% - 35px); /* below title control */
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container.empty > .editor-container {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container.empty > .editor-container {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .editor-container > .editor-instance {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .editor-container > .editor-instance {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .grid-view-container {
|
||||
.monaco-workbench .part.editor > .content .grid-view-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
cursor: default !important;
|
||||
}
|
||||
|
||||
.monaco-shell .screen-reader-detected-explanation {
|
||||
.monaco-workbench .screen-reader-detected-explanation {
|
||||
width: 420px;
|
||||
top: 30px;
|
||||
right: 6px;
|
||||
@@ -30,7 +30,7 @@
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.monaco-shell .screen-reader-detected-explanation .cancel {
|
||||
.monaco-workbench .screen-reader-detected-explanation .cancel {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
@@ -41,27 +41,27 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.monaco-shell .screen-reader-detected-explanation h2 {
|
||||
.monaco-workbench .screen-reader-detected-explanation h2 {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-weight: 400;
|
||||
font-size: 1.8em;
|
||||
}
|
||||
|
||||
.monaco-shell .screen-reader-detected-explanation p {
|
||||
.monaco-workbench .screen-reader-detected-explanation p {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
.monaco-shell .screen-reader-detected-explanation hr {
|
||||
.monaco-workbench .screen-reader-detected-explanation hr {
|
||||
border: 0;
|
||||
height: 2px;
|
||||
}
|
||||
|
||||
.monaco-shell .screen-reader-detected-explanation .buttons {
|
||||
.monaco-workbench .screen-reader-detected-explanation .buttons {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.monaco-shell .screen-reader-detected-explanation .buttons a {
|
||||
.monaco-workbench .screen-reader-detected-explanation .buttons a {
|
||||
font-size: 13px;
|
||||
padding-left: 12px;
|
||||
padding-right: 12px;
|
||||
@@ -69,11 +69,11 @@
|
||||
max-width: fit-content;
|
||||
}
|
||||
|
||||
.monaco-shell.vs .screen-reader-detected-explanation .cancel {
|
||||
.vs .monaco-workbench .screen-reader-detected-explanation .cancel {
|
||||
background: url('close-statusview.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
.monaco-shell.vs-dark .screen-reader-detected-explanation .cancel,
|
||||
.monaco-shell.hc-black .screen-reader-detected-explanation .cancel {
|
||||
.vs-dark .monaco-workbench .screen-reader-detected-explanation .cancel,
|
||||
.hc-black .monaco-workbench .screen-reader-detected-explanation .cancel {
|
||||
background: url('close-statusview-inverse.svg') center center no-repeat;
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 381 B After Width: | Height: | Size: 258 B |
@@ -5,7 +5,8 @@
|
||||
|
||||
/* Title Label */
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title > .label-container {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title > .label-container {
|
||||
height: 35px;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
@@ -13,7 +14,7 @@
|
||||
flex: auto;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .title-label {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .title-label {
|
||||
line-height: 35px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
@@ -21,31 +22,31 @@
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title.breadcrumbs .no-tabs.title-label {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title.breadcrumbs .no-tabs.title-label {
|
||||
flex: none;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .monaco-icon-label::before {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .monaco-icon-label::before {
|
||||
height: 35px; /* tweak the icon size of the editor labels when icons are enabled */
|
||||
}
|
||||
|
||||
/* Breadcrumbs */
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title.breadcrumbs .breadcrumbs-control {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title.breadcrumbs .breadcrumbs-control {
|
||||
flex: 1 50%;
|
||||
overflow: hidden;
|
||||
margin-left: .45em;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title.breadcrumbs .breadcrumbs-control .monaco-breadcrumb-item {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title.breadcrumbs .breadcrumbs-control .monaco-breadcrumb-item {
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title.breadcrumbs .breadcrumbs-control.preview .monaco-breadcrumb-item {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title.breadcrumbs .breadcrumbs-control.preview .monaco-breadcrumb-item {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title.breadcrumbs .breadcrumbs-control .monaco-breadcrumb-item::before {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title.breadcrumbs .breadcrumbs-control .monaco-breadcrumb-item::before {
|
||||
content: '/';
|
||||
opacity: 1;
|
||||
height: inherit;
|
||||
@@ -54,35 +55,36 @@
|
||||
}
|
||||
|
||||
/* {{SQL CARBON EDIT}} */
|
||||
.monaco-workbench.windows > .part.editor > .content .editor-group-container > .title.breadcrumbs .breadcrumbs-control .monaco-breadcrumb-item::before {
|
||||
.windows > .monaco-workbench .part.editor > .content .editor-group-container > .title.breadcrumbs .breadcrumbs-control .monaco-breadcrumb-item::before {
|
||||
content: '/';
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title.breadcrumbs .breadcrumbs-control .monaco-breadcrumb-item.root_folder::before,
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title.breadcrumbs .breadcrumbs-control .monaco-breadcrumb-item.root_folder + .monaco-breadcrumb-item::before,
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title.breadcrumbs .breadcrumbs-control.relative-path .monaco-breadcrumb-item:nth-child(2)::before {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title.breadcrumbs .breadcrumbs-control .monaco-breadcrumb-item.root_folder::before,
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title.breadcrumbs .breadcrumbs-control .monaco-breadcrumb-item.root_folder + .monaco-breadcrumb-item::before,
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title.breadcrumbs .breadcrumbs-control.relative-path .monaco-breadcrumb-item:nth-child(2)::before,
|
||||
.windows > .monaco-workbench .part.editor > .content .editor-group-container > .title.breadcrumbs .breadcrumbs-control .monaco-breadcrumb-item:nth-child(2)::before {
|
||||
/* workspace folder, item following workspace folder, or relative path -> hide first seperator */
|
||||
display: none;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title.breadcrumbs .breadcrumbs-control .monaco-breadcrumb-item.root_folder::after {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title.breadcrumbs .breadcrumbs-control .monaco-breadcrumb-item.root_folder::after {
|
||||
/* use dot separator for workspace folder */
|
||||
content: '\00a0•\00a0';
|
||||
padding: 0px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title.breadcrumbs .breadcrumbs-control .monaco-breadcrumb-item:last-child {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title.breadcrumbs .breadcrumbs-control .monaco-breadcrumb-item:last-child {
|
||||
padding-right: 4px; /* does not have trailing separator*/
|
||||
}
|
||||
|
||||
/* Title Actions */
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .title-actions {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .title-actions {
|
||||
display: flex;
|
||||
flex: initial;
|
||||
opacity: 0.5;
|
||||
height: 35px;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container.active > .title .title-actions {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container.active > .title .title-actions {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
@@ -5,37 +5,37 @@
|
||||
|
||||
/* Title Container */
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title.tabs > .tabs-and-actions-container {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title.tabs > .tabs-and-actions-container {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title.tabs > .tabs-and-actions-container > .monaco-scrollable-element {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title.tabs > .tabs-and-actions-container > .monaco-scrollable-element {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title.tabs > .tabs-and-actions-container > .monaco-scrollable-element .scrollbar {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title.tabs > .tabs-and-actions-container > .monaco-scrollable-element .scrollbar {
|
||||
z-index: 3; /* on top of tabs */
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/* Tabs Container */
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container {
|
||||
display: flex;
|
||||
height: 35px;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container.scroll {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container.scroll {
|
||||
overflow: scroll !important;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container::-webkit-scrollbar {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Tab */
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab {
|
||||
position: relative;
|
||||
display: flex;
|
||||
white-space: nowrap;
|
||||
@@ -45,45 +45,45 @@
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sizing-shrink.has-icon-theme.close-button-right,
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sizing-shrink.has-icon-theme.close-button-off {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sizing-shrink.has-icon-theme.close-button-right,
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sizing-shrink.has-icon-theme.close-button-off {
|
||||
padding-left: 5px; /* reduce padding when we show icons and are in shrinking mode and tab close button is not left */
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sizing-fit {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sizing-fit {
|
||||
width: 120px;
|
||||
min-width: fit-content;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sizing-shrink {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sizing-shrink {
|
||||
min-width: 60px;
|
||||
flex-basis: 0; /* all tabs are even */
|
||||
flex-grow: 1; /* all tabs grow even */
|
||||
max-width: fit-content;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sizing-shrink.close-button-left::after,
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sizing-shrink.close-button-off::after {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sizing-shrink.close-button-left::after,
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sizing-shrink.close-button-off::after {
|
||||
content: '';
|
||||
display: flex;
|
||||
flex: 0;
|
||||
width: 5px; /* Reserve space to hide tab fade when close button is left or off (fixes https://github.com/Microsoft/vscode/issues/45728) */
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sizing-shrink.close-button-left {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sizing-shrink.close-button-left {
|
||||
min-width: 80px; /* make more room for close button when it shows to the left */
|
||||
padding-right: 5px; /* we need less room when sizing is shrink */
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.dragged {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.dragged {
|
||||
will-change: transform; /* forces tab to be drawn on a separate layer (fixes https://github.com/Microsoft/vscode/issues/18733) */
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.dragged-over div {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.dragged-over div {
|
||||
pointer-events: none; /* prevents cursor flickering (fixes https://github.com/Microsoft/vscode/issues/38753) */
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.close-button-left {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.close-button-left {
|
||||
flex-direction: row-reverse;
|
||||
padding-left: 0;
|
||||
padding-right: 10px;
|
||||
@@ -91,14 +91,14 @@
|
||||
|
||||
/* Tab border top/bottom */
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab > .tab-border-top-container,
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab > .tab-border-bottom-container {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab > .tab-border-top-container,
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab > .tab-border-bottom-container {
|
||||
display: none; /* hidden by default until a color is provided (see below) */
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.active.tab-border-top > .tab-border-top-container,
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.active.tab-border-bottom > .tab-border-bottom-container,
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.dirty-border-top > .tab-border-top-container {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.active.tab-border-top > .tab-border-top-container,
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.active.tab-border-bottom > .tab-border-bottom-container,
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.dirty-border-top > .tab-border-top-container {
|
||||
display: block;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
@@ -107,19 +107,19 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.active.tab-border-top > .tab-border-top-container {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.active.tab-border-top > .tab-border-top-container {
|
||||
top: 0;
|
||||
height: 1px;
|
||||
background-color: var(--tab-border-top-color);
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.active.tab-border-bottom > .tab-border-bottom-container {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.active.tab-border-bottom > .tab-border-bottom-container {
|
||||
bottom: 0;
|
||||
height: 1px;
|
||||
background-color: var(--tab-border-bottom-color);
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.dirty-border-top > .tab-border-top-container {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.dirty-border-top > .tab-border-top-container {
|
||||
top: 0;
|
||||
height: 2px;
|
||||
background-color: var(--tab-dirty-border-top-color);
|
||||
@@ -127,16 +127,16 @@
|
||||
|
||||
/* Tab Label */
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab .tab-label {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab .tab-label {
|
||||
margin-top: auto;
|
||||
margin-bottom: auto;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sizing-shrink .tab-label {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sizing-shrink .tab-label {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sizing-shrink > .tab-label::after {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sizing-shrink > .tab-label::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
right: 0;
|
||||
@@ -146,66 +146,66 @@
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sizing-shrink:focus > .tab-label::after {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sizing-shrink:focus > .tab-label::after {
|
||||
opacity: 0; /* when tab has the focus this shade breaks the tab border (fixes https://github.com/Microsoft/vscode/issues/57819) */
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sizing-fit .monaco-icon-label,
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sizing-fit .monaco-icon-label > .monaco-icon-label-description-container {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sizing-fit .monaco-icon-label,
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sizing-fit .monaco-icon-label > .monaco-icon-label-description-container {
|
||||
overflow: visible; /* fixes https://github.com/Microsoft/vscode/issues/20182 */
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sizing-shrink > .monaco-icon-label > .monaco-icon-label-description-container {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sizing-shrink > .monaco-icon-label > .monaco-icon-label-description-container {
|
||||
text-overflow: clip;
|
||||
}
|
||||
|
||||
.hc-black .monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sizing-shrink > .monaco-icon-label > .monaco-icon-label-description-container {
|
||||
.hc-black .monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sizing-shrink > .monaco-icon-label > .monaco-icon-label-description-container {
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab .monaco-icon-label::before {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab .monaco-icon-label::before {
|
||||
height: 16px; /* tweak the icon size of the editor labels when icons are enabled */
|
||||
}
|
||||
|
||||
/* Tab Close */
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab > .tab-close {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab > .tab-close {
|
||||
margin-top: auto;
|
||||
margin-bottom: auto;
|
||||
width: 28px;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.close-button-right.sizing-shrink > .tab-close {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.close-button-right.sizing-shrink > .tab-close {
|
||||
flex: 0;
|
||||
overflow: hidden; /* let the close button be pushed out of view when sizing is set to shrink to make more room... */
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.dirty.close-button-right.sizing-shrink > .tab-close,
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.close-button-right.sizing-shrink:hover > .tab-close,
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.close-button-right.sizing-shrink > .tab-close:focus-within {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.dirty.close-button-right.sizing-shrink > .tab-close,
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.close-button-right.sizing-shrink:hover > .tab-close,
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.close-button-right.sizing-shrink > .tab-close:focus-within {
|
||||
overflow: visible; /* ...but still show the close button on hover, focus and when dirty */
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.close-button-off > .tab-close {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.close-button-off > .tab-close {
|
||||
display: none; /* hide the close action bar when we are configured to hide it */
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container.active > .title .tabs-container > .tab.active > .tab-close .action-label, /* always show it for active tab */
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container.active > .title .tabs-container > .tab > .tab-close .action-label:focus, /* always show it on focus */
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container.active > .title .tabs-container > .tab:hover > .tab-close .action-label, /* always show it on hover */
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container.active > .title .tabs-container > .tab.active:hover > .tab-close .action-label, /* always show it on hover */
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container.active > .title .tabs-container > .tab.dirty > .tab-close .action-label { /* always show it for dirty tabs */
|
||||
.monaco-workbench .part.editor > .content .editor-group-container.active > .title .tabs-container > .tab.active > .tab-close .action-label, /* always show it for active tab */
|
||||
.monaco-workbench .part.editor > .content .editor-group-container.active > .title .tabs-container > .tab > .tab-close .action-label:focus, /* always show it on focus */
|
||||
.monaco-workbench .part.editor > .content .editor-group-container.active > .title .tabs-container > .tab:hover > .tab-close .action-label, /* always show it on hover */
|
||||
.monaco-workbench .part.editor > .content .editor-group-container.active > .title .tabs-container > .tab.active:hover > .tab-close .action-label, /* always show it on hover */
|
||||
.monaco-workbench .part.editor > .content .editor-group-container.active > .title .tabs-container > .tab.dirty > .tab-close .action-label { /* always show it for dirty tabs */
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.active > .tab-close .action-label, /* show dimmed for inactive group */
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.active:hover > .tab-close .action-label, /* show dimmed for inactive group */
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.dirty > .tab-close .action-label, /* show dimmed for inactive group */
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab:hover > .tab-close .action-label { /* show dimmed for inactive group */
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.active > .tab-close .action-label, /* show dimmed for inactive group */
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.active:hover > .tab-close .action-label, /* show dimmed for inactive group */
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.dirty > .tab-close .action-label, /* show dimmed for inactive group */
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab:hover > .tab-close .action-label { /* show dimmed for inactive group */
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab > .tab-close .action-label {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab > .tab-close .action-label {
|
||||
opacity: 0;
|
||||
display: block;
|
||||
height: 16px;
|
||||
@@ -216,53 +216,53 @@
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
|
||||
.vs .monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.dirty .close-editor-action {
|
||||
.vs .monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.dirty .close-editor-action {
|
||||
background: url('close-dirty.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
.vs-dark .monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.dirty .close-editor-action,
|
||||
.hc-black .monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.dirty .close-editor-action {
|
||||
.vs-dark .monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.dirty .close-editor-action,
|
||||
.hc-black .monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.dirty .close-editor-action {
|
||||
background: url('close-dirty-inverse.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
.vs .monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.dirty .close-editor-action:hover {
|
||||
.vs .monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.dirty .close-editor-action:hover {
|
||||
background: url('close.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
.vs-dark .monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.dirty .close-editor-action:hover,
|
||||
.hc-black .monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.dirty .close-editor-action:hover {
|
||||
.vs-dark .monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.dirty .close-editor-action:hover,
|
||||
.hc-black .monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.dirty .close-editor-action:hover {
|
||||
background: url('close-inverse.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
/* No Tab Close Button */
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.close-button-off {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.close-button-off {
|
||||
padding-right: 10px; /* give a little bit more room if close button is off */
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sizing-shrink.close-button-off {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sizing-shrink.close-button-off {
|
||||
padding-right: 5px; /* we need less room when sizing is shrink */
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.close-button-off.dirty {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.close-button-off.dirty:not(.dirty-border-top) {
|
||||
background-repeat: no-repeat;
|
||||
background-position-y: center;
|
||||
background-position-x: calc(100% - 6px); /* to the right of the tab label */
|
||||
padding-right: 28px; /* make room for dirty indication when we are running without close button */
|
||||
}
|
||||
|
||||
.vs .monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.close-button-off.dirty {
|
||||
.vs .monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.close-button-off.dirty:not(.dirty-border-top) {
|
||||
background-image: url('close-dirty.svg');
|
||||
}
|
||||
|
||||
.vs-dark .monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.close-button-off.dirty,
|
||||
.hc-black .monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.close-button-off.dirty {
|
||||
.vs-dark .monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.close-button-off.dirty:not(.dirty-border-top),
|
||||
.hc-black .monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.close-button-off.dirty {
|
||||
background-image: url('close-dirty-inverse.svg');
|
||||
}
|
||||
|
||||
/* Editor Actions */
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .editor-actions {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .editor-actions {
|
||||
cursor: default;
|
||||
flex: initial;
|
||||
padding-left: 4px;
|
||||
@@ -271,30 +271,30 @@
|
||||
|
||||
/* Breadcrumbs */
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-breadcrumbs .breadcrumbs-control {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-breadcrumbs .breadcrumbs-control {
|
||||
flex: 1 100%;
|
||||
height: 22px;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-breadcrumbs .breadcrumbs-control .monaco-icon-label {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-breadcrumbs .breadcrumbs-control .monaco-icon-label {
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-breadcrumbs .breadcrumbs-control .monaco-icon-label::before {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-breadcrumbs .breadcrumbs-control .monaco-icon-label::before {
|
||||
height: 22px; /* tweak the icon size of the editor labels when icons are enabled */
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-breadcrumbs .breadcrumbs-control .monaco-breadcrumb-item {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-breadcrumbs .breadcrumbs-control .monaco-breadcrumb-item {
|
||||
max-width: 80%;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-breadcrumbs .breadcrumbs-control .monaco-breadcrumb-item::before {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-breadcrumbs .breadcrumbs-control .monaco-breadcrumb-item::before {
|
||||
min-width: 16px;
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-breadcrumbs .breadcrumbs-control .monaco-breadcrumb-item:last-child {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-breadcrumbs .breadcrumbs-control .monaco-breadcrumb-item:last-child {
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
@@ -5,31 +5,31 @@
|
||||
|
||||
/* Editor Label */
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .title-label,
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab .tab-label {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .title-label,
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab .tab-label {
|
||||
white-space: nowrap;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .title-label a,
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab .tab-label a {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .title-label a,
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab .tab-label a {
|
||||
text-decoration: none;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .monaco-icon-label::before,
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab .monaco-icon-label::before,
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .title-label a,
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab .tab-label a,
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .title-label h2,
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab .tab-label span {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .monaco-icon-label::before,
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab .monaco-icon-label::before,
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .title-label a,
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab .tab-label a,
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .title-label h2,
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab .tab-label span {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Title Actions */
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .title-actions .action-label,
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .editor-actions .action-label {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .title-actions .action-label,
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .editor-actions .action-label {
|
||||
display: block;
|
||||
height: 35px;
|
||||
line-height: 35px;
|
||||
@@ -39,29 +39,29 @@
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.hc-black .monaco-workbench > .part.editor > .content .editor-group-container > .title .title-actions .action-label,
|
||||
.hc-black .monaco-workbench > .part.editor > .content .editor-group-container > .title .editor-actions .action-label {
|
||||
.hc-black .monaco-workbench .part.editor > .content .editor-group-container > .title .title-actions .action-label,
|
||||
.hc-black .monaco-workbench .part.editor > .content .editor-group-container > .title .editor-actions .action-label {
|
||||
line-height: initial;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .editor-actions .action-label .label,
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .title-actions .action-label .label {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .editor-actions .action-label .label,
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .title-actions .action-label .label {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Drag Cursor */
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title {
|
||||
cursor: -webkit-grab;
|
||||
}
|
||||
|
||||
/* Actions */
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .close-editor-action {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .close-editor-action {
|
||||
background: url('close.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
.vs-dark .monaco-workbench > .part.editor > .content .editor-group-container > .title .close-editor-action,
|
||||
.hc-black .monaco-workbench > .part.editor > .content .editor-group-container > .title .close-editor-action {
|
||||
.vs-dark .monaco-workbench .part.editor > .content .editor-group-container > .title .close-editor-action,
|
||||
.hc-black .monaco-workbench .part.editor > .content .editor-group-container > .title .close-editor-action {
|
||||
background: url('close-inverse.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import 'vs/css!./media/notabstitlecontrol';
|
||||
import { toResource, Verbosity, IEditorInput } from 'vs/workbench/common/editor';
|
||||
import { TitleControl, IToolbarActions } from 'vs/workbench/browser/parts/editor/titleControl';
|
||||
import { ResourceLabel } from 'vs/workbench/browser/labels';
|
||||
import { ResourceLabel, IResourceLabel } from 'vs/workbench/browser/labels';
|
||||
import { TAB_ACTIVE_FOREGROUND, TAB_UNFOCUSED_ACTIVE_FOREGROUND } from 'vs/workbench/common/theme';
|
||||
import { EventType as TouchEventType, GestureEvent, Gesture } from 'vs/base/browser/touch';
|
||||
import { addDisposableListener, EventType, addClass, EventHelper, removeClass, toggleClass } from 'vs/base/browser/dom';
|
||||
@@ -22,7 +22,7 @@ interface IRenderedEditorLabel {
|
||||
|
||||
export class NoTabsTitleControl extends TitleControl {
|
||||
private titleContainer: HTMLElement;
|
||||
private editorLabel: ResourceLabel;
|
||||
private editorLabel: IResourceLabel;
|
||||
private activeLabel: IRenderedEditorLabel = Object.create(null);
|
||||
|
||||
protected create(parent: HTMLElement): void {
|
||||
@@ -40,8 +40,8 @@ export class NoTabsTitleControl extends TitleControl {
|
||||
this.titleContainer.appendChild(labelContainer);
|
||||
|
||||
// Editor Label
|
||||
this.editorLabel = this._register(this.instantiationService.createInstance(ResourceLabel, labelContainer, void 0));
|
||||
this._register(this.editorLabel.onClick(e => this.onTitleLabelClick(e)));
|
||||
this.editorLabel = this._register(this.instantiationService.createInstance(ResourceLabel, labelContainer, undefined)).element;
|
||||
this._register(addDisposableListener(this.editorLabel.element, EventType.CLICK, e => this.onTitleLabelClick(e)));
|
||||
|
||||
// Breadcrumbs
|
||||
this.createBreadcrumbsControl(labelContainer, { showFileIcons: false, showSymbolIcons: true, showDecorationColors: false, breadcrumbsBackground: () => Color.transparent });
|
||||
@@ -244,7 +244,7 @@ export class NoTabsTitleControl extends TitleControl {
|
||||
title = ''; // dont repeat what is already shown
|
||||
}
|
||||
|
||||
this.editorLabel.setLabel({ name, description, resource }, { title, italic: !isEditorPinned, extraClasses: ['no-tabs', 'title-label'] });
|
||||
this.editorLabel.setResource({ name, description, resource }, { title, italic: !isEditorPinned, extraClasses: ['no-tabs', 'title-label'] });
|
||||
if (isGroupActive) {
|
||||
this.editorLabel.element.style.color = this.getColor(TAB_ACTIVE_FOREGROUND);
|
||||
} else {
|
||||
|
||||
@@ -28,7 +28,7 @@ export class RangeHighlightDecorations extends Disposable {
|
||||
private readonly _onHighlightRemoved: Emitter<void> = this._register(new Emitter<void>());
|
||||
get onHighlghtRemoved(): Event<void> { return this._onHighlightRemoved.event; }
|
||||
|
||||
constructor(@IEditorService private editorService: IEditorService) {
|
||||
constructor(@IEditorService private readonly editorService: IEditorService) {
|
||||
super();
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ export class RangeHighlightDecorations extends Disposable {
|
||||
this.setEditor(editor);
|
||||
}
|
||||
|
||||
private getEditor(resourceRange: IRangeHighlightDecoration): ICodeEditor {
|
||||
private getEditor(resourceRange: IRangeHighlightDecoration): ICodeEditor | undefined {
|
||||
const activeEditor = this.editorService.activeEditor;
|
||||
const resource = activeEditor && activeEditor.getResource();
|
||||
if (resource) {
|
||||
@@ -67,7 +67,7 @@ export class RangeHighlightDecorations extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private setEditor(editor: ICodeEditor) {
|
||||
|
||||
@@ -13,12 +13,10 @@ import { LRUCache } from 'vs/base/common/map';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { clamp } from 'vs/base/common/numbers';
|
||||
import { Themable } from 'vs/workbench/common/theme';
|
||||
import { IStatusbarItem, StatusbarItemDescriptor, IStatusbarRegistry, Extensions } from 'vs/workbench/browser/parts/statusbar/statusbar';
|
||||
import { StatusbarAlignment } from 'vs/platform/statusbar/common/statusbar';
|
||||
import { IStatusbarItem } from 'vs/workbench/browser/parts/statusbar/statusbar';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { IDisposable, Disposable, combinedDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { Action } from 'vs/base/common/actions';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { memoize } from 'vs/base/common/decorators';
|
||||
@@ -234,7 +232,7 @@ class FileSeemsBinaryFileView {
|
||||
|
||||
type Scale = number | 'fit';
|
||||
|
||||
class ZoomStatusbarItem extends Themable implements IStatusbarItem {
|
||||
export class ZoomStatusbarItem extends Themable implements IStatusbarItem {
|
||||
|
||||
static instance: ZoomStatusbarItem;
|
||||
|
||||
@@ -244,7 +242,7 @@ class ZoomStatusbarItem extends Themable implements IStatusbarItem {
|
||||
private onSelectScale?: (scale: Scale) => void;
|
||||
|
||||
constructor(
|
||||
@IContextMenuService private contextMenuService: IContextMenuService,
|
||||
@IContextMenuService private readonly contextMenuService: IContextMenuService,
|
||||
@IEditorService editorService: IEditorService,
|
||||
@IThemeService themeService: IThemeService
|
||||
) {
|
||||
@@ -257,7 +255,7 @@ class ZoomStatusbarItem extends Themable implements IStatusbarItem {
|
||||
|
||||
private onActiveEditorChanged(): void {
|
||||
this.hide();
|
||||
this.onSelectScale = void 0;
|
||||
this.onSelectScale = undefined;
|
||||
}
|
||||
|
||||
show(scale: Scale, onSelectScale: (scale: number) => void) {
|
||||
@@ -298,12 +296,12 @@ class ZoomStatusbarItem extends Themable implements IStatusbarItem {
|
||||
private get zoomActions(): Action[] {
|
||||
const scales: Scale[] = [10, 5, 2, 1, 0.5, 0.2, 'fit'];
|
||||
return scales.map(scale =>
|
||||
new Action(`zoom.${scale}`, ZoomStatusbarItem.zoomLabel(scale), void 0, void 0, () => {
|
||||
new Action(`zoom.${scale}`, ZoomStatusbarItem.zoomLabel(scale), undefined, undefined, () => {
|
||||
if (this.onSelectScale) {
|
||||
this.onSelectScale(scale);
|
||||
}
|
||||
|
||||
return void 0;
|
||||
return Promise.resolve(undefined);
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -314,10 +312,6 @@ class ZoomStatusbarItem extends Themable implements IStatusbarItem {
|
||||
}
|
||||
}
|
||||
|
||||
Registry.as<IStatusbarRegistry>(Extensions.Statusbar).registerStatusbarItem(
|
||||
new StatusbarItemDescriptor(ZoomStatusbarItem, StatusbarAlignment.RIGHT, 101 /* to the left of editor status (100) */)
|
||||
);
|
||||
|
||||
interface ImageState {
|
||||
scale: Scale;
|
||||
offsetX: number;
|
||||
@@ -394,7 +388,7 @@ class InlineImageView {
|
||||
DOM.removeClass(image, 'pixelated');
|
||||
image.style.minWidth = 'auto';
|
||||
image.style.width = 'auto';
|
||||
InlineImageView.imageStateCache.set(cacheKey, null);
|
||||
InlineImageView.imageStateCache.delete(cacheKey);
|
||||
} else {
|
||||
const oldWidth = image.width;
|
||||
const oldHeight = image.height;
|
||||
@@ -432,6 +426,10 @@ class InlineImageView {
|
||||
}
|
||||
|
||||
function firstZoom() {
|
||||
if (!image) {
|
||||
return;
|
||||
}
|
||||
|
||||
scale = image.clientWidth / image.naturalWidth;
|
||||
updateScale(scale);
|
||||
}
|
||||
@@ -537,10 +535,13 @@ class InlineImageView {
|
||||
DOM.clearNode(container);
|
||||
DOM.addClasses(container, 'image', 'zoom-in');
|
||||
|
||||
image = DOM.append(container, DOM.$('img.scale-to-fit'));
|
||||
image = DOM.append(container, DOM.$<HTMLImageElement>('img.scale-to-fit'));
|
||||
image.style.visibility = 'hidden';
|
||||
|
||||
disposables.push(DOM.addDisposableListener(image, DOM.EventType.LOAD, e => {
|
||||
if (!image) {
|
||||
return;
|
||||
}
|
||||
if (typeof descriptor.size === 'number') {
|
||||
metadataClb(nls.localize('imgMeta', '{0}x{1} {2}', image.naturalWidth, image.naturalHeight, BinarySize.formatSize(descriptor.size)));
|
||||
} else {
|
||||
@@ -568,7 +569,7 @@ class InlineImageView {
|
||||
return context;
|
||||
}
|
||||
|
||||
private static imageSrc(descriptor: IResourceDescriptor, fileService: IFileService): Thenable<string> {
|
||||
private static imageSrc(descriptor: IResourceDescriptor, fileService: IFileService): Promise<string> {
|
||||
if (descriptor.resource.scheme === Schemas.data) {
|
||||
return Promise.resolve(descriptor.resource.toString(true /* skip encoding */));
|
||||
}
|
||||
@@ -582,7 +583,7 @@ class InlineImageView {
|
||||
}
|
||||
|
||||
function getMime(descriptor: IResourceDescriptor) {
|
||||
let mime = descriptor.mime;
|
||||
let mime: string | undefined = descriptor.mime;
|
||||
if (!mime && descriptor.resource.scheme !== Schemas.data) {
|
||||
mime = mimes.getMediaMime(descriptor.resource.path);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ import { IEditorRegistry, Extensions as EditorExtensions } from 'vs/workbench/br
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { IEditorGroup } from 'vs/workbench/services/group/common/editorGroupsService';
|
||||
import { SplitView, Sizing, Orientation } from 'vs/base/browser/ui/splitview/splitview';
|
||||
import { Event, Relay, anyEvent, mapEvent, Emitter } from 'vs/base/common/event';
|
||||
import { Event, Relay, Emitter } from 'vs/base/common/event';
|
||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
|
||||
export class SideBySideEditor extends BaseEditor {
|
||||
@@ -43,8 +43,8 @@ export class SideBySideEditor extends BaseEditor {
|
||||
get minimumHeight() { return this.minimumMasterHeight + this.minimumDetailsHeight; }
|
||||
get maximumHeight() { return this.maximumMasterHeight + this.maximumDetailsHeight; }
|
||||
|
||||
protected masterEditor: BaseEditor;
|
||||
protected detailsEditor: BaseEditor;
|
||||
protected masterEditor?: BaseEditor;
|
||||
protected detailsEditor?: BaseEditor;
|
||||
|
||||
private masterEditorContainer: HTMLElement;
|
||||
private detailsEditorContainer: HTMLElement;
|
||||
@@ -52,13 +52,13 @@ export class SideBySideEditor extends BaseEditor {
|
||||
private splitview: SplitView;
|
||||
private dimension: DOM.Dimension = new DOM.Dimension(0, 0);
|
||||
|
||||
private onDidCreateEditors = this._register(new Emitter<{ width: number; height: number; }>());
|
||||
private _onDidSizeConstraintsChange = this._register(new Relay<{ width: number; height: number; }>());
|
||||
readonly onDidSizeConstraintsChange: Event<{ width: number; height: number; }> = anyEvent(this.onDidCreateEditors.event, this._onDidSizeConstraintsChange.event);
|
||||
private onDidCreateEditors = this._register(new Emitter<{ width: number; height: number; } | undefined>());
|
||||
private _onDidSizeConstraintsChange = this._register(new Relay<{ width: number; height: number; } | undefined>());
|
||||
readonly onDidSizeConstraintsChange: Event<{ width: number; height: number; } | undefined> = Event.any(this.onDidCreateEditors.event, this._onDidSizeConstraintsChange.event);
|
||||
|
||||
constructor(
|
||||
@ITelemetryService telemetryService: ITelemetryService,
|
||||
@IInstantiationService private instantiationService: IInstantiationService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IStorageService storageService: IStorageService
|
||||
) {
|
||||
@@ -92,7 +92,7 @@ export class SideBySideEditor extends BaseEditor {
|
||||
this.updateStyles();
|
||||
}
|
||||
|
||||
setInput(newInput: SideBySideEditorInput, options: EditorOptions, token: CancellationToken): Thenable<void> {
|
||||
setInput(newInput: SideBySideEditorInput, options: EditorOptions, token: CancellationToken): Promise<void> {
|
||||
const oldInput = <SideBySideEditorInput>this.input;
|
||||
return super.setInput(newInput, options, token)
|
||||
.then(() => this.updateInput(oldInput, newInput, options, token));
|
||||
@@ -141,7 +141,7 @@ export class SideBySideEditor extends BaseEditor {
|
||||
this.splitview.layout(dimension.width);
|
||||
}
|
||||
|
||||
getControl(): IEditorControl {
|
||||
getControl(): IEditorControl | null {
|
||||
if (this.masterEditor) {
|
||||
return this.masterEditor.getControl();
|
||||
}
|
||||
@@ -149,15 +149,15 @@ export class SideBySideEditor extends BaseEditor {
|
||||
return null;
|
||||
}
|
||||
|
||||
getMasterEditor(): IEditor {
|
||||
getMasterEditor(): IEditor | undefined {
|
||||
return this.masterEditor;
|
||||
}
|
||||
|
||||
getDetailsEditor(): IEditor {
|
||||
getDetailsEditor(): IEditor | undefined {
|
||||
return this.detailsEditor;
|
||||
}
|
||||
|
||||
private updateInput(oldInput: SideBySideEditorInput, newInput: SideBySideEditorInput, options: EditorOptions, token: CancellationToken): Thenable<void> {
|
||||
private updateInput(oldInput: SideBySideEditorInput, newInput: SideBySideEditorInput, options: EditorOptions, token: CancellationToken): Promise<void> {
|
||||
if (!newInput.matches(oldInput)) {
|
||||
if (oldInput) {
|
||||
this.disposeEditors();
|
||||
@@ -165,22 +165,28 @@ export class SideBySideEditor extends BaseEditor {
|
||||
|
||||
return this.setNewInput(newInput, options, token);
|
||||
}
|
||||
if (!this.detailsEditor || !this.masterEditor) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
return Promise.all([
|
||||
this.detailsEditor.setInput(newInput.details, null, token),
|
||||
this.masterEditor.setInput(newInput.master, options, token)]
|
||||
).then(() => void 0);
|
||||
).then(() => undefined);
|
||||
}
|
||||
|
||||
private setNewInput(newInput: SideBySideEditorInput, options: EditorOptions, token: CancellationToken): Thenable<void> {
|
||||
const detailsEditor = this._createEditor(<EditorInput>newInput.details, this.detailsEditorContainer);
|
||||
const masterEditor = this._createEditor(<EditorInput>newInput.master, this.masterEditorContainer);
|
||||
private setNewInput(newInput: SideBySideEditorInput, options: EditorOptions, token: CancellationToken): Promise<void> {
|
||||
const detailsEditor = this.doCreateEditor(<EditorInput>newInput.details, this.detailsEditorContainer);
|
||||
const masterEditor = this.doCreateEditor(<EditorInput>newInput.master, this.masterEditorContainer);
|
||||
|
||||
return this.onEditorsCreated(detailsEditor, masterEditor, newInput.details, newInput.master, options, token);
|
||||
}
|
||||
|
||||
private _createEditor(editorInput: EditorInput, container: HTMLElement): BaseEditor {
|
||||
private doCreateEditor(editorInput: EditorInput, container: HTMLElement): BaseEditor {
|
||||
const descriptor = Registry.as<IEditorRegistry>(EditorExtensions.Editors).getEditor(editorInput);
|
||||
if (!descriptor) {
|
||||
throw new Error('No descriptor for editor found');
|
||||
}
|
||||
|
||||
const editor = descriptor.instantiate(this.instantiationService);
|
||||
editor.create(container);
|
||||
@@ -193,12 +199,12 @@ export class SideBySideEditor extends BaseEditor {
|
||||
this.detailsEditor = details;
|
||||
this.masterEditor = master;
|
||||
|
||||
this._onDidSizeConstraintsChange.input = anyEvent(
|
||||
mapEvent(details.onDidSizeConstraintsChange, () => undefined),
|
||||
mapEvent(master.onDidSizeConstraintsChange, () => undefined)
|
||||
this._onDidSizeConstraintsChange.input = Event.any(
|
||||
Event.map(details.onDidSizeConstraintsChange, () => undefined),
|
||||
Event.map(master.onDidSizeConstraintsChange, () => undefined)
|
||||
);
|
||||
|
||||
this.onDidCreateEditors.fire();
|
||||
this.onDidCreateEditors.fire(undefined);
|
||||
|
||||
return Promise.all([this.detailsEditor.setInput(detailsInput, null, token), this.masterEditor.setInput(masterInput, options, token)]).then(() => this.focus());
|
||||
}
|
||||
@@ -214,12 +220,12 @@ export class SideBySideEditor extends BaseEditor {
|
||||
private disposeEditors(): void {
|
||||
if (this.detailsEditor) {
|
||||
this.detailsEditor.dispose();
|
||||
this.detailsEditor = null;
|
||||
this.detailsEditor = undefined;
|
||||
}
|
||||
|
||||
if (this.masterEditor) {
|
||||
this.masterEditor.dispose();
|
||||
this.masterEditor = null;
|
||||
this.masterEditor = undefined;
|
||||
}
|
||||
|
||||
this.detailsEditorContainer.innerHTML = '';
|
||||
|
||||
@@ -10,7 +10,7 @@ import { toResource, GroupIdentifier, IEditorInput, Verbosity, EditorCommandsCon
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { EventType as TouchEventType, GestureEvent, Gesture } from 'vs/base/browser/touch';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { ResourceLabel } from 'vs/workbench/browser/labels';
|
||||
import { ResourceLabels, IResourceLabel, DEFAULT_LABELS_CONTAINER } from 'vs/workbench/browser/labels';
|
||||
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
@@ -69,7 +69,7 @@ export class TabsTitleControl extends TitleControl {
|
||||
private tabsScrollbar: ScrollableElement;
|
||||
private closeOneEditorAction: CloseOneEditorAction;
|
||||
|
||||
private tabLabelWidgets: ResourceLabel[] = [];
|
||||
private tabResourceLabels: ResourceLabels;
|
||||
private tabLabels: IEditorInputLabel[] = [];
|
||||
private tabDisposeables: IDisposable[] = [];
|
||||
|
||||
@@ -83,7 +83,7 @@ export class TabsTitleControl extends TitleControl {
|
||||
group: IEditorGroupView,
|
||||
@IContextMenuService contextMenuService: IContextMenuService,
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@IUntitledEditorService private untitledEditorService: IUntitledEditorService,
|
||||
@IUntitledEditorService private readonly untitledEditorService: IUntitledEditorService,
|
||||
@IContextKeyService contextKeyService: IContextKeyService,
|
||||
@IKeybindingService keybindingService: IKeybindingService,
|
||||
@ITelemetryService telemetryService: ITelemetryService,
|
||||
@@ -142,6 +142,9 @@ export class TabsTitleControl extends TitleControl {
|
||||
addClass(breadcrumbsContainer, 'tabs-breadcrumbs');
|
||||
this.titleContainer.appendChild(breadcrumbsContainer);
|
||||
this.createBreadcrumbsControl(breadcrumbsContainer, { showFileIcons: true, showSymbolIcons: true, showDecorationColors: false, breadcrumbsBackground: breadcrumbsBackground });
|
||||
|
||||
// Tab Labels
|
||||
this.tabResourceLabels = this._register(this.instantiationService.createInstance(ResourceLabels, DEFAULT_LABELS_CONTAINER));
|
||||
}
|
||||
|
||||
private createTabsScrollbar(scrollable: HTMLElement): ScrollableElement {
|
||||
@@ -314,7 +317,6 @@ export class TabsTitleControl extends TitleControl {
|
||||
(this.tabsContainer.lastChild as HTMLElement).remove();
|
||||
|
||||
// Remove associated tab label and widget
|
||||
this.tabLabelWidgets.pop();
|
||||
this.tabDisposeables.pop().dispose();
|
||||
}
|
||||
|
||||
@@ -330,7 +332,7 @@ export class TabsTitleControl extends TitleControl {
|
||||
clearNode(this.tabsContainer);
|
||||
|
||||
this.tabDisposeables = dispose(this.tabDisposeables);
|
||||
this.tabLabelWidgets = [];
|
||||
this.tabResourceLabels.clear();
|
||||
this.tabLabels = [];
|
||||
|
||||
this.clearEditorActionsToolbar();
|
||||
@@ -414,12 +416,12 @@ export class TabsTitleControl extends TitleControl {
|
||||
this.redraw();
|
||||
}
|
||||
|
||||
private withTab(editor: IEditorInput, fn: (tabContainer: HTMLElement, tabLabelWidget: ResourceLabel, tabLabel: IEditorInputLabel) => void): void {
|
||||
private withTab(editor: IEditorInput, fn: (tabContainer: HTMLElement, tabLabelWidget: IResourceLabel, tabLabel: IEditorInputLabel) => void): void {
|
||||
const editorIndex = this.group.getIndexOfEditor(editor);
|
||||
|
||||
const tabContainer = this.tabsContainer.children[editorIndex] as HTMLElement;
|
||||
if (tabContainer) {
|
||||
fn(tabContainer, this.tabLabelWidgets[editorIndex], this.tabLabels[editorIndex]);
|
||||
fn(tabContainer, this.tabResourceLabels.get(editorIndex), this.tabLabels[editorIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -441,8 +443,7 @@ export class TabsTitleControl extends TitleControl {
|
||||
tabContainer.appendChild(tabBorderTopContainer);
|
||||
|
||||
// Tab Editor Label
|
||||
const editorLabel = this.instantiationService.createInstance(ResourceLabel, tabContainer, void 0);
|
||||
this.tabLabelWidgets.push(editorLabel);
|
||||
const editorLabel = this.tabResourceLabels.create(tabContainer);
|
||||
|
||||
// Tab Close Button
|
||||
const tabCloseContainer = document.createElement('div');
|
||||
@@ -479,7 +480,7 @@ export class TabsTitleControl extends TitleControl {
|
||||
e.preventDefault(); // required to prevent auto-scrolling (https://github.com/Microsoft/vscode/issues/16690)
|
||||
}
|
||||
|
||||
return void 0; // only for left mouse click
|
||||
return undefined; // only for left mouse click
|
||||
}
|
||||
|
||||
if (this.originatesFromTabActionBar(e)) {
|
||||
@@ -489,7 +490,7 @@ export class TabsTitleControl extends TitleControl {
|
||||
// Open tabs editor
|
||||
this.group.openEditor(this.group.getEditor(index));
|
||||
|
||||
return void 0;
|
||||
return undefined;
|
||||
};
|
||||
|
||||
const showContextMenu = (e: Event) => {
|
||||
@@ -836,16 +837,16 @@ export class TabsTitleControl extends TitleControl {
|
||||
this.layout(this.dimension);
|
||||
}
|
||||
|
||||
private forEachTab(fn: (editor: IEditorInput, index: number, tabContainer: HTMLElement, tabLabelWidget: ResourceLabel, tabLabel: IEditorInputLabel) => void): void {
|
||||
private forEachTab(fn: (editor: IEditorInput, index: number, tabContainer: HTMLElement, tabLabelWidget: IResourceLabel, tabLabel: IEditorInputLabel) => void): void {
|
||||
this.group.editors.forEach((editor, index) => {
|
||||
const tabContainer = this.tabsContainer.children[index] as HTMLElement;
|
||||
if (tabContainer) {
|
||||
fn(editor, index, tabContainer, this.tabLabelWidgets[index], this.tabLabels[index]);
|
||||
fn(editor, index, tabContainer, this.tabResourceLabels.get(index), this.tabLabels[index]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private redrawTab(editor: IEditorInput, index: number, tabContainer: HTMLElement, tabLabelWidget: ResourceLabel, tabLabel: IEditorInputLabel): void {
|
||||
private redrawTab(editor: IEditorInput, index: number, tabContainer: HTMLElement, tabLabelWidget: IResourceLabel, tabLabel: IEditorInputLabel): void {
|
||||
|
||||
// Label
|
||||
this.redrawLabel(editor, tabContainer, tabLabelWidget, tabLabel);
|
||||
@@ -880,7 +881,7 @@ export class TabsTitleControl extends TitleControl {
|
||||
this.setEditorTabColor(editor, tabContainer, this.group.isActive(editor));
|
||||
}
|
||||
|
||||
private redrawLabel(editor: IEditorInput, tabContainer: HTMLElement, tabLabelWidget: ResourceLabel, tabLabel: IEditorInputLabel): void {
|
||||
private redrawLabel(editor: IEditorInput, tabContainer: HTMLElement, tabLabelWidget: IResourceLabel, tabLabel: IEditorInputLabel): void {
|
||||
const name = tabLabel.name;
|
||||
const description = tabLabel.description || '';
|
||||
const title = tabLabel.title || '';
|
||||
@@ -890,14 +891,14 @@ export class TabsTitleControl extends TitleControl {
|
||||
tabContainer.title = title;
|
||||
|
||||
// Label
|
||||
tabLabelWidget.setLabel({ name, description, resource: toResource(editor, { supportSideBySide: true }) }, { title, extraClasses: ['tab-label'], italic: !this.group.isPinned(editor) });
|
||||
tabLabelWidget.setResource({ name, description, resource: toResource(editor, { supportSideBySide: true }) }, { title, extraClasses: ['tab-label'], italic: !this.group.isPinned(editor) });
|
||||
|
||||
// {{SQL CARBON EDIT}} -- Display the editor's tab color
|
||||
const isTabActive = this.group.isActive(editor);
|
||||
this.setEditorTabColor(editor, tabContainer, isTabActive);
|
||||
}
|
||||
|
||||
private redrawEditorActiveAndDirty(isGroupActive: boolean, editor: IEditorInput, tabContainer: HTMLElement, tabLabelWidget: ResourceLabel): void {
|
||||
private redrawEditorActiveAndDirty(isGroupActive: boolean, editor: IEditorInput, tabContainer: HTMLElement, tabLabelWidget: IResourceLabel): void {
|
||||
const isTabActive = this.group.isActive(editor);
|
||||
|
||||
const hasModifiedBorderTop = this.doRedrawEditorDirty(isGroupActive, isTabActive, editor, tabContainer);
|
||||
@@ -905,7 +906,7 @@ export class TabsTitleControl extends TitleControl {
|
||||
this.doRedrawEditorActive(isGroupActive, !hasModifiedBorderTop, editor, tabContainer, tabLabelWidget);
|
||||
}
|
||||
|
||||
private doRedrawEditorActive(isGroupActive: boolean, allowBorderTop: boolean, editor: IEditorInput, tabContainer: HTMLElement, tabLabelWidget: ResourceLabel): void {
|
||||
private doRedrawEditorActive(isGroupActive: boolean, allowBorderTop: boolean, editor: IEditorInput, tabContainer: HTMLElement, tabLabelWidget: IResourceLabel): void {
|
||||
|
||||
// Tab is active
|
||||
if (this.group.isActive(editor)) {
|
||||
@@ -924,7 +925,7 @@ export class TabsTitleControl extends TitleControl {
|
||||
tabContainer.style.removeProperty('--tab-border-bottom-color');
|
||||
}
|
||||
|
||||
const activeTabBorderColorTop = allowBorderTop ? this.getColor(isGroupActive ? TAB_ACTIVE_BORDER_TOP : TAB_UNFOCUSED_ACTIVE_BORDER_TOP) : void 0;
|
||||
const activeTabBorderColorTop = allowBorderTop ? this.getColor(isGroupActive ? TAB_ACTIVE_BORDER_TOP : TAB_UNFOCUSED_ACTIVE_BORDER_TOP) : undefined;
|
||||
if (activeTabBorderColorTop) {
|
||||
addClass(tabContainer, 'tab-border-top');
|
||||
tabContainer.style.setProperty('--tab-border-top-color', activeTabBorderColorTop.toString());
|
||||
@@ -1008,7 +1009,7 @@ export class TabsTitleControl extends TitleControl {
|
||||
if (!this.layoutScheduled) {
|
||||
this.layoutScheduled = scheduleAtNextAnimationFrame(() => {
|
||||
this.doLayout(this.dimension);
|
||||
this.layoutScheduled = void 0;
|
||||
this.layoutScheduled = undefined;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1073,7 +1074,7 @@ export class TabsTitleControl extends TitleControl {
|
||||
return this.tabsContainer.children[editorIndex] as HTMLElement;
|
||||
}
|
||||
|
||||
return void 0;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private blockRevealActiveTabOnce(): void {
|
||||
@@ -1094,7 +1095,7 @@ export class TabsTitleControl extends TitleControl {
|
||||
element = (e as GestureEvent).initialTarget as HTMLElement;
|
||||
}
|
||||
|
||||
return !!findParentWithClass(element, 'monaco-action-bar', 'tab');
|
||||
return !!findParentWithClass(element, 'action-item', 'tab');
|
||||
}
|
||||
|
||||
private onDrop(e: DragEvent, targetIndex: number): void {
|
||||
@@ -1185,21 +1186,21 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
|
||||
const activeContrastBorderColor = theme.getColor(activeContrastBorder);
|
||||
if (activeContrastBorderColor) {
|
||||
collector.addRule(`
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.active,
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.active:hover {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.active,
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.active:hover {
|
||||
outline: 1px solid;
|
||||
outline-offset: -5px;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab:hover {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab:hover {
|
||||
outline: 1px dashed;
|
||||
outline-offset: -5px;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.active > .tab-close .action-label,
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.active:hover > .tab-close .action-label,
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab.dirty > .tab-close .action-label,
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab:hover > .tab-close .action-label {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.active > .tab-close .action-label,
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.active:hover > .tab-close .action-label,
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.dirty > .tab-close .action-label,
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab:hover > .tab-close .action-label {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
`);
|
||||
@@ -1209,7 +1210,7 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
|
||||
const tabHoverBackground = theme.getColor(TAB_HOVER_BACKGROUND);
|
||||
if (tabHoverBackground) {
|
||||
collector.addRule(`
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container.active > .title .tabs-container > .tab:hover {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container.active > .title .tabs-container > .tab:hover {
|
||||
background-color: ${tabHoverBackground} !important;
|
||||
}
|
||||
`);
|
||||
@@ -1218,7 +1219,7 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
|
||||
const tabUnfocusedHoverBackground = theme.getColor(TAB_UNFOCUSED_HOVER_BACKGROUND);
|
||||
if (tabUnfocusedHoverBackground) {
|
||||
collector.addRule(`
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab:hover {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab:hover {
|
||||
background-color: ${tabUnfocusedHoverBackground} !important;
|
||||
}
|
||||
`);
|
||||
@@ -1228,7 +1229,7 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
|
||||
const tabHoverBorder = theme.getColor(TAB_HOVER_BORDER);
|
||||
if (tabHoverBorder) {
|
||||
collector.addRule(`
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container.active > .title .tabs-container > .tab:hover {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container.active > .title .tabs-container > .tab:hover {
|
||||
box-shadow: ${tabHoverBorder} 0 -1px inset !important;
|
||||
}
|
||||
`);
|
||||
@@ -1237,7 +1238,7 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
|
||||
const tabUnfocusedHoverBorder = theme.getColor(TAB_UNFOCUSED_HOVER_BORDER);
|
||||
if (tabUnfocusedHoverBorder) {
|
||||
collector.addRule(`
|
||||
.monaco-workbench > .part.editor > .content .editor-group-container > .title .tabs-container > .tab:hover {
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab:hover {
|
||||
box-shadow: ${tabUnfocusedHoverBorder} 0 -1px inset !important;
|
||||
}
|
||||
`);
|
||||
@@ -1265,12 +1266,12 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
|
||||
const adjustedColor = tabHoverBackground.flatten(adjustedTabBackground);
|
||||
const adjustedColorDrag = tabHoverBackground.flatten(adjustedTabDragBackground);
|
||||
collector.addRule(`
|
||||
.monaco-workbench > .part.editor > .content:not(.dragged-over) .editor-group-container.active > .title .tabs-container > .tab.sizing-shrink:not(.dragged):hover > .tab-label::after {
|
||||
.monaco-workbench .part.editor > .content:not(.dragged-over) .editor-group-container.active > .title .tabs-container > .tab.sizing-shrink:not(.dragged):hover > .tab-label::after {
|
||||
background: linear-gradient(to left, ${adjustedColor}, transparent) !important;
|
||||
}
|
||||
|
||||
|
||||
.monaco-workbench > .part.editor > .content.dragged-over .editor-group-container.active > .title .tabs-container > .tab.sizing-shrink:not(.dragged):hover > .tab-label::after {
|
||||
.monaco-workbench .part.editor > .content.dragged-over .editor-group-container.active > .title .tabs-container > .tab.sizing-shrink:not(.dragged):hover > .tab-label::after {
|
||||
background: linear-gradient(to left, ${adjustedColorDrag}, transparent) !important;
|
||||
}
|
||||
`);
|
||||
@@ -1281,11 +1282,11 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
|
||||
const adjustedColor = tabUnfocusedHoverBackground.flatten(adjustedTabBackground);
|
||||
const adjustedColorDrag = tabUnfocusedHoverBackground.flatten(adjustedTabDragBackground);
|
||||
collector.addRule(`
|
||||
.monaco-workbench > .part.editor > .content:not(.dragged-over) .editor-group-container > .title .tabs-container > .tab.sizing-shrink:not(.dragged):hover > .tab-label::after {
|
||||
.monaco-workbench .part.editor > .content:not(.dragged-over) .editor-group-container > .title .tabs-container > .tab.sizing-shrink:not(.dragged):hover > .tab-label::after {
|
||||
background: linear-gradient(to left, ${adjustedColor}, transparent) !important;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content.dragged-over .editor-group-container > .title .tabs-container > .tab.sizing-shrink:not(.dragged):hover > .tab-label::after {
|
||||
.monaco-workbench .part.editor > .content.dragged-over .editor-group-container > .title .tabs-container > .tab.sizing-shrink:not(.dragged):hover > .tab-label::after {
|
||||
background: linear-gradient(to left, ${adjustedColorDrag}, transparent) !important;
|
||||
}
|
||||
`);
|
||||
@@ -1295,8 +1296,8 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
|
||||
if (editorDragAndDropBackground && adjustedTabDragBackground) {
|
||||
const adjustedColorDrag = editorDragAndDropBackground.flatten(adjustedTabDragBackground);
|
||||
collector.addRule(`
|
||||
.monaco-workbench > .part.editor > .content.dragged-over .editor-group-container.active > .title .tabs-container > .tab.sizing-shrink.dragged-over:not(.active):not(.dragged) > .tab-label::after,
|
||||
.monaco-workbench > .part.editor > .content.dragged-over .editor-group-container:not(.active) > .title .tabs-container > .tab.sizing-shrink.dragged-over:not(.dragged) > .tab-label::after {
|
||||
.monaco-workbench .part.editor > .content.dragged-over .editor-group-container.active > .title .tabs-container > .tab.sizing-shrink.dragged-over:not(.active):not(.dragged) > .tab-label::after,
|
||||
.monaco-workbench .part.editor > .content.dragged-over .editor-group-container:not(.active) > .title .tabs-container > .tab.sizing-shrink.dragged-over:not(.dragged) > .tab-label::after {
|
||||
background: linear-gradient(to left, ${adjustedColorDrag}, transparent) !important;
|
||||
}
|
||||
`);
|
||||
@@ -1308,11 +1309,11 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
|
||||
const adjustedColor = tabActiveBackground.flatten(adjustedTabBackground);
|
||||
const adjustedColorDrag = tabActiveBackground.flatten(adjustedTabDragBackground);
|
||||
collector.addRule(`
|
||||
.monaco-workbench > .part.editor > .content:not(.dragged-over) .editor-group-container > .title .tabs-container > .tab.sizing-shrink.active:not(.dragged) > .tab-label::after {
|
||||
.monaco-workbench .part.editor > .content:not(.dragged-over) .editor-group-container > .title .tabs-container > .tab.sizing-shrink.active:not(.dragged) > .tab-label::after {
|
||||
background: linear-gradient(to left, ${adjustedColor}, transparent);
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content.dragged-over .editor-group-container > .title .tabs-container > .tab.sizing-shrink.active:not(.dragged) > .tab-label::after {
|
||||
.monaco-workbench .part.editor > .content.dragged-over .editor-group-container > .title .tabs-container > .tab.sizing-shrink.active:not(.dragged) > .tab-label::after {
|
||||
background: linear-gradient(to left, ${adjustedColorDrag}, transparent);
|
||||
}
|
||||
`);
|
||||
@@ -1324,11 +1325,11 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
|
||||
const adjustedColor = tabInactiveBackground.flatten(adjustedTabBackground);
|
||||
const adjustedColorDrag = tabInactiveBackground.flatten(adjustedTabDragBackground);
|
||||
collector.addRule(`
|
||||
.monaco-workbench > .part.editor > .content:not(.dragged-over) .editor-group-container > .title .tabs-container > .tab.sizing-shrink:not(.dragged) > .tab-label::after {
|
||||
.monaco-workbench .part.editor > .content:not(.dragged-over) .editor-group-container > .title .tabs-container > .tab.sizing-shrink:not(.dragged) > .tab-label::after {
|
||||
background: linear-gradient(to left, ${adjustedColor}, transparent);
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content.dragged-over .editor-group-container > .title .tabs-container > .tab.sizing-shrink:not(.dragged) > .tab-label::after {
|
||||
.monaco-workbench .part.editor > .content.dragged-over .editor-group-container > .title .tabs-container > .tab.sizing-shrink:not(.dragged) > .tab-label::after {
|
||||
background: linear-gradient(to left, ${adjustedColorDrag}, transparent);
|
||||
}
|
||||
`);
|
||||
|
||||
@@ -26,7 +26,7 @@ import { ScrollType, IDiffEditorViewState, IDiffEditorModel } from 'vs/editor/co
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { once } from 'vs/base/common/event';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorGroupsService';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
@@ -73,7 +73,7 @@ export class TextDiffEditor extends BaseTextEditor implements ITextDiffEditor {
|
||||
return this.instantiationService.createInstance(DiffEditorWidget, parent, configuration);
|
||||
}
|
||||
|
||||
setInput(input: EditorInput, options: EditorOptions, token: CancellationToken): Thenable<void> {
|
||||
setInput(input: EditorInput, options: EditorOptions, token: CancellationToken): Promise<void> {
|
||||
|
||||
// Dispose previous diff navigator
|
||||
this.diffNavigatorDisposables = dispose(this.diffNavigatorDisposables);
|
||||
@@ -87,12 +87,12 @@ export class TextDiffEditor extends BaseTextEditor implements ITextDiffEditor {
|
||||
|
||||
// Check for cancellation
|
||||
if (token.isCancellationRequested) {
|
||||
return void 0;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Assert Model Instance
|
||||
if (!(resolvedModel instanceof TextDiffEditorModel) && this.openAsBinary(input, options)) {
|
||||
return void 0;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Set Editor Model
|
||||
@@ -282,7 +282,7 @@ export class TextDiffEditor extends BaseTextEditor implements ITextDiffEditor {
|
||||
super.saveTextEditorViewState(resource);
|
||||
|
||||
// Make sure to clean up when the input gets disposed
|
||||
once(input.onDispose)(() => {
|
||||
Event.once(input.onDispose)(() => {
|
||||
super.clearTextEditorViewState([resource]);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ export abstract class BaseTextEditor extends BaseEditor implements ITextEditor {
|
||||
private editorControl: IEditor;
|
||||
private _editorContainer: HTMLElement;
|
||||
private hasPendingConfigurationChange: boolean;
|
||||
private lastAppliedEditorOptions: IEditorOptions;
|
||||
private lastAppliedEditorOptions?: IEditorOptions;
|
||||
private editorMemento: IEditorMemento<IEditorViewState>;
|
||||
|
||||
constructor(
|
||||
@@ -53,13 +53,17 @@ export abstract class BaseTextEditor extends BaseEditor implements ITextEditor {
|
||||
@ITextFileService private readonly _textFileService: ITextFileService,
|
||||
@IEditorService protected editorService: IEditorService,
|
||||
@IEditorGroupsService protected editorGroupService: IEditorGroupsService,
|
||||
@IWindowService private windowService: IWindowService
|
||||
@IWindowService private readonly windowService: IWindowService
|
||||
) {
|
||||
super(id, telemetryService, themeService, storageService);
|
||||
|
||||
this.editorMemento = this.getEditorMemento<IEditorViewState>(editorGroupService, TEXT_EDITOR_VIEW_STATE_PREFERENCE_KEY, 100);
|
||||
|
||||
this._register(this.configurationService.onDidChangeConfiguration(e => this.handleConfigurationChangeEvent(this.configurationService.getValue<IEditorConfiguration>(this.getResource()))));
|
||||
this._register(this.configurationService.onDidChangeConfiguration(e => {
|
||||
const resource = this.getResource();
|
||||
const value = resource ? this.configurationService.getValue<IEditorConfiguration>(resource) : undefined;
|
||||
return this.handleConfigurationChangeEvent(value);
|
||||
}));
|
||||
}
|
||||
|
||||
protected get instantiationService(): IInstantiationService {
|
||||
@@ -129,7 +133,7 @@ export abstract class BaseTextEditor extends BaseEditor implements ITextEditor {
|
||||
|
||||
// Editor for Text
|
||||
this._editorContainer = parent;
|
||||
this.editorControl = this._register(this.createEditorControl(parent, this.computeConfiguration(this.configurationService.getValue<IEditorConfiguration>(this.getResource()))));
|
||||
this.editorControl = this._register(this.createEditorControl(parent, this.computeConfiguration(this.configurationService.getValue<IEditorConfiguration>(this.getResource()!))));
|
||||
|
||||
// Model & Language changes
|
||||
const codeEditor = getCodeEditor(this.editorControl);
|
||||
@@ -170,7 +174,7 @@ export abstract class BaseTextEditor extends BaseEditor implements ITextEditor {
|
||||
(reason === SaveReason.FOCUS_CHANGE && mode === AutoSaveMode.ON_FOCUS_CHANGE)
|
||||
) {
|
||||
if (this.textFileService.isDirty()) {
|
||||
this.textFileService.saveAll(void 0, { reason });
|
||||
this.textFileService.saveAll(undefined, { reason });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -187,7 +191,7 @@ export abstract class BaseTextEditor extends BaseEditor implements ITextEditor {
|
||||
return this.instantiationService.createInstance(CodeEditorWidget, parent, configuration, {});
|
||||
}
|
||||
|
||||
setInput(input: EditorInput, options: EditorOptions, token: CancellationToken): Thenable<void> {
|
||||
setInput(input: EditorInput, options: EditorOptions, token: CancellationToken): Promise<void> {
|
||||
return super.setInput(input, options, token).then(() => {
|
||||
|
||||
// Update editor options after having set the input. We do this because there can be
|
||||
@@ -229,14 +233,14 @@ export abstract class BaseTextEditor extends BaseEditor implements ITextEditor {
|
||||
*/
|
||||
protected saveTextEditorViewState(resource: URI): void {
|
||||
const editorViewState = this.retrieveTextEditorViewState(resource);
|
||||
if (!editorViewState) {
|
||||
if (!editorViewState || !this.group) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.editorMemento.saveEditorState(this.group, resource, editorViewState);
|
||||
}
|
||||
|
||||
protected retrieveTextEditorViewState(resource: URI): IEditorViewState {
|
||||
protected retrieveTextEditorViewState(resource: URI): IEditorViewState | null {
|
||||
const control = this.getControl() as ICodeEditor;
|
||||
const model = control.getModel();
|
||||
if (!model) {
|
||||
@@ -267,12 +271,18 @@ export abstract class BaseTextEditor extends BaseEditor implements ITextEditor {
|
||||
/**
|
||||
* Loads the text editor view state for the given resource and returns it.
|
||||
*/
|
||||
protected loadTextEditorViewState(resource: URI): IEditorViewState {
|
||||
return this.editorMemento.loadEditorState(this.group, resource);
|
||||
protected loadTextEditorViewState(resource: URI): IEditorViewState | undefined {
|
||||
return this.group ? this.editorMemento.loadEditorState(this.group, resource) : undefined;
|
||||
}
|
||||
|
||||
private updateEditorConfiguration(configuration = this.configurationService.getValue<IEditorConfiguration>(this.getResource())): void {
|
||||
if (!this.editorControl) {
|
||||
private updateEditorConfiguration(configuration?: IEditorConfiguration): void {
|
||||
if (!configuration) {
|
||||
const resource = this.getResource();
|
||||
if (resource) {
|
||||
configuration = this.configurationService.getValue<IEditorConfiguration>(resource);
|
||||
}
|
||||
}
|
||||
if (!this.editorControl || !configuration) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -292,7 +302,7 @@ export abstract class BaseTextEditor extends BaseEditor implements ITextEditor {
|
||||
}
|
||||
}
|
||||
|
||||
protected getResource(): URI {
|
||||
protected getResource(): URI | null {
|
||||
const codeEditor = getCodeEditor(this.editorControl);
|
||||
if (codeEditor) {
|
||||
const model = codeEditor.getModel();
|
||||
@@ -311,7 +321,7 @@ export abstract class BaseTextEditor extends BaseEditor implements ITextEditor {
|
||||
protected abstract getAriaLabel(): string;
|
||||
|
||||
dispose(): void {
|
||||
this.lastAppliedEditorOptions = void 0;
|
||||
this.lastAppliedEditorOptions = undefined;
|
||||
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ import { ITextResourceConfigurationService } from 'vs/editor/common/services/res
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { once } from 'vs/base/common/event';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { ScrollType } from 'vs/editor/common/editorCommon';
|
||||
import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorGroupsService';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
@@ -54,7 +54,7 @@ export class AbstractTextResourceEditor extends BaseTextEditor {
|
||||
return nls.localize('textEditor', "Text Editor");
|
||||
}
|
||||
|
||||
setInput(input: EditorInput, options: EditorOptions, token: CancellationToken): Thenable<void> {
|
||||
setInput(input: EditorInput, options: EditorOptions, token: CancellationToken): Promise<void> {
|
||||
|
||||
// Remember view settings if input changes
|
||||
this.saveTextResourceEditorViewState(this.input);
|
||||
@@ -65,7 +65,7 @@ export class AbstractTextResourceEditor extends BaseTextEditor {
|
||||
|
||||
// Check for cancellation
|
||||
if (token.isCancellationRequested) {
|
||||
return void 0;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Assert Model instance
|
||||
@@ -90,7 +90,7 @@ export class AbstractTextResourceEditor extends BaseTextEditor {
|
||||
this.restoreTextResourceEditorViewState(input);
|
||||
}
|
||||
|
||||
return void 0;
|
||||
return undefined;
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -136,19 +136,14 @@ export class AbstractTextResourceEditor extends BaseTextEditor {
|
||||
|
||||
/**
|
||||
* Reveals the last line of this editor if it has a model set.
|
||||
* When smart is true only scroll if the cursor is currently on the last line of the output panel.
|
||||
* This allows users to click on the output panel to stop scrolling when they see something of interest.
|
||||
* To resume, they should scroll to the end of the output panel again.
|
||||
*/
|
||||
revealLastLine(smart: boolean): void {
|
||||
revealLastLine(): void {
|
||||
const codeEditor = <ICodeEditor>this.getControl();
|
||||
const model = codeEditor.getModel();
|
||||
|
||||
if (model) {
|
||||
const lastLine = model.getLineCount();
|
||||
if (!smart || codeEditor.getPosition().lineNumber === lastLine) {
|
||||
codeEditor.revealPosition({ lineNumber: lastLine, column: model.getLineMaxColumn(lastLine) }, ScrollType.Smooth);
|
||||
}
|
||||
codeEditor.revealPosition({ lineNumber: lastLine, column: model.getLineMaxColumn(lastLine) }, ScrollType.Smooth);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,7 +185,7 @@ export class AbstractTextResourceEditor extends BaseTextEditor {
|
||||
super.saveTextEditorViewState(resource);
|
||||
|
||||
// Make sure to clean up when the input gets disposed
|
||||
once(input.onDispose)(() => {
|
||||
Event.once(input.onDispose)(() => {
|
||||
super.clearTextEditorViewState([resource]);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -65,17 +65,17 @@ export abstract class TitleControl extends Themable {
|
||||
parent: HTMLElement,
|
||||
protected accessor: IEditorGroupsAccessor,
|
||||
protected group: IEditorGroupView,
|
||||
@IContextMenuService private contextMenuService: IContextMenuService,
|
||||
@IContextMenuService private readonly contextMenuService: IContextMenuService,
|
||||
@IInstantiationService protected instantiationService: IInstantiationService,
|
||||
@IContextKeyService private contextKeyService: IContextKeyService,
|
||||
@IKeybindingService private keybindingService: IKeybindingService,
|
||||
@ITelemetryService private telemetryService: ITelemetryService,
|
||||
@IContextKeyService private readonly contextKeyService: IContextKeyService,
|
||||
@IKeybindingService private readonly keybindingService: IKeybindingService,
|
||||
@ITelemetryService private readonly telemetryService: ITelemetryService,
|
||||
// {{SQL CARBON EDIT}} -- need to make the notification service protected
|
||||
@INotificationService protected notificationService: INotificationService,
|
||||
@IMenuService private menuService: IMenuService,
|
||||
@INotificationService protected readonly notificationService: INotificationService,
|
||||
@IMenuService private readonly menuService: IMenuService,
|
||||
@IQuickOpenService protected quickOpenService: IQuickOpenService,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IExtensionService private extensionService: IExtensionService,
|
||||
@IExtensionService private readonly extensionService: IExtensionService,
|
||||
@IConfigurationService protected configurationService: IConfigurationService,
|
||||
@IFileService private readonly fileService: IFileService,
|
||||
) {
|
||||
@@ -320,11 +320,9 @@ export abstract class TitleControl extends Themable {
|
||||
protected getKeybindingLabel(action: IAction): string {
|
||||
const keybinding = this.getKeybinding(action);
|
||||
|
||||
return keybinding ? keybinding.getLabel() : void 0;
|
||||
return keybinding ? keybinding.getLabel() : undefined;
|
||||
}
|
||||
|
||||
//#region ITitleAreaControl
|
||||
|
||||
abstract openEditor(editor: IEditorInput): void;
|
||||
|
||||
abstract closeEditor(editor: IEditorInput): void;
|
||||
@@ -348,8 +346,6 @@ export abstract class TitleControl extends Themable {
|
||||
abstract updateStyles(): void;
|
||||
|
||||
layout(dimension: Dimension): void {
|
||||
// Optionally implemented in subclasses
|
||||
|
||||
if (this.breadcrumbsControl) {
|
||||
this.breadcrumbsControl.layout(undefined);
|
||||
}
|
||||
@@ -365,8 +361,6 @@ export abstract class TitleControl extends Themable {
|
||||
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
//#endregion
|
||||
}
|
||||
|
||||
registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
|
||||
|
||||
@@ -3,15 +3,15 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
.monaco-workbench > .part > .content > .composite {
|
||||
.monaco-workbench .part > .content > .composite {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part > .composite.title {
|
||||
.monaco-workbench .part > .composite.title {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part > .composite.title > .title-actions {
|
||||
.monaco-workbench .part > .composite.title > .title-actions {
|
||||
flex: 1;
|
||||
padding-left: 5px;
|
||||
}
|
||||
@@ -21,7 +21,7 @@ export class ClearNotificationAction extends Action {
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@ICommandService private commandService: ICommandService
|
||||
@ICommandService private readonly commandService: ICommandService
|
||||
) {
|
||||
super(id, label, 'clear-notification-action');
|
||||
}
|
||||
@@ -29,7 +29,7 @@ export class ClearNotificationAction extends Action {
|
||||
run(notification: INotificationViewItem): Promise<any> {
|
||||
this.commandService.executeCommand(CLEAR_NOTIFICATION, notification);
|
||||
|
||||
return Promise.resolve(void 0);
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ export class ClearAllNotificationsAction extends Action {
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@ICommandService private commandService: ICommandService
|
||||
@ICommandService private readonly commandService: ICommandService
|
||||
) {
|
||||
super(id, label, 'clear-all-notifications-action');
|
||||
}
|
||||
@@ -49,7 +49,7 @@ export class ClearAllNotificationsAction extends Action {
|
||||
run(notification: INotificationViewItem): Promise<any> {
|
||||
this.commandService.executeCommand(CLEAR_ALL_NOTIFICATIONS);
|
||||
|
||||
return Promise.resolve(void 0);
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ export class HideNotificationsCenterAction extends Action {
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@ICommandService private commandService: ICommandService
|
||||
@ICommandService private readonly commandService: ICommandService
|
||||
) {
|
||||
super(id, label, 'hide-all-notifications-action');
|
||||
}
|
||||
@@ -69,7 +69,7 @@ export class HideNotificationsCenterAction extends Action {
|
||||
run(notification: INotificationViewItem): Promise<any> {
|
||||
this.commandService.executeCommand(HIDE_NOTIFICATIONS_CENTER);
|
||||
|
||||
return Promise.resolve(void 0);
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ export class ExpandNotificationAction extends Action {
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@ICommandService private commandService: ICommandService
|
||||
@ICommandService private readonly commandService: ICommandService
|
||||
) {
|
||||
super(id, label, 'expand-notification-action');
|
||||
}
|
||||
@@ -89,7 +89,7 @@ export class ExpandNotificationAction extends Action {
|
||||
run(notification: INotificationViewItem): Promise<any> {
|
||||
this.commandService.executeCommand(EXPAND_NOTIFICATION, notification);
|
||||
|
||||
return Promise.resolve(void 0);
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ export class CollapseNotificationAction extends Action {
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@ICommandService private commandService: ICommandService
|
||||
@ICommandService private readonly commandService: ICommandService
|
||||
) {
|
||||
super(id, label, 'collapse-notification-action');
|
||||
}
|
||||
@@ -109,7 +109,7 @@ export class CollapseNotificationAction extends Action {
|
||||
run(notification: INotificationViewItem): Promise<any> {
|
||||
this.commandService.executeCommand(COLLAPSE_NOTIFICATION, notification);
|
||||
|
||||
return Promise.resolve(void 0);
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@ export class CopyNotificationMessageAction extends Action {
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IClipboardService private clipboardService: IClipboardService
|
||||
@IClipboardService private readonly clipboardService: IClipboardService
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
@@ -147,15 +147,15 @@ export class CopyNotificationMessageAction extends Action {
|
||||
run(notification: INotificationViewItem): Promise<any> {
|
||||
this.clipboardService.writeText(notification.message.raw);
|
||||
|
||||
return Promise.resolve(void 0);
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
export class NotificationActionRunner extends ActionRunner {
|
||||
|
||||
constructor(
|
||||
@ITelemetryService private telemetryService: ITelemetryService,
|
||||
@INotificationService private notificationService: INotificationService
|
||||
@ITelemetryService private readonly telemetryService: ITelemetryService,
|
||||
@INotificationService private readonly notificationService: INotificationService
|
||||
) {
|
||||
super();
|
||||
}
|
||||
@@ -171,8 +171,8 @@ export class NotificationActionRunner extends ActionRunner {
|
||||
this.telemetryService.publicLog('workbenchActionExecuted', { id: action.id, from: 'message' });
|
||||
|
||||
// Run and make sure to notify on any error again
|
||||
super.runAction(action, context).then(null, error => this.notificationService.error(error));
|
||||
super.runAction(action, context).then(undefined, error => this.notificationService.error(error));
|
||||
|
||||
return Promise.resolve(void 0);
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import { INotificationViewItem, INotificationsModel, NotificationChangeType, INo
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { toErrorMessage } from 'vs/base/common/errorMessage';
|
||||
import { Severity } from 'vs/platform/notification/common/notification';
|
||||
import { once } from 'vs/base/common/event';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
|
||||
export class NotificationsAlerts extends Disposable {
|
||||
|
||||
@@ -52,7 +52,7 @@ export class NotificationsAlerts extends Disposable {
|
||||
}
|
||||
});
|
||||
|
||||
once(notifiation.onDidClose)(() => listener.dispose());
|
||||
Event.once(notifiation.onDidClose)(() => listener.dispose());
|
||||
|
||||
this.doTriggerAriaAlert(notifiation);
|
||||
}
|
||||
|
||||
@@ -42,11 +42,11 @@ export class NotificationsCenter extends Themable {
|
||||
private container: HTMLElement,
|
||||
private model: INotificationsModel,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IInstantiationService private instantiationService: IInstantiationService,
|
||||
@IPartService private partService: IPartService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@IPartService private readonly partService: IPartService,
|
||||
@IContextKeyService contextKeyService: IContextKeyService,
|
||||
@IEditorGroupsService private editorGroupService: IEditorGroupsService,
|
||||
@IKeybindingService private keybindingService: IKeybindingService
|
||||
@IEditorGroupsService private readonly editorGroupService: IEditorGroupsService,
|
||||
@IKeybindingService private readonly keybindingService: IKeybindingService
|
||||
) {
|
||||
super(themeService);
|
||||
|
||||
@@ -152,10 +152,10 @@ export class NotificationsCenter extends Themable {
|
||||
this.container.appendChild(this.notificationsCenterContainer);
|
||||
}
|
||||
|
||||
private getKeybindingLabel(action: IAction): string {
|
||||
private getKeybindingLabel(action: IAction): string | null {
|
||||
const keybinding = this.keybindingService.lookupKeybinding(action.id);
|
||||
|
||||
return keybinding ? keybinding.getLabel() : void 0;
|
||||
return keybinding ? keybinding.getLabel() : null;
|
||||
}
|
||||
|
||||
private onDidNotificationChange(e: INotificationChangeEvent): void {
|
||||
|
||||
@@ -62,7 +62,7 @@ export interface INotificationsToastController {
|
||||
|
||||
export function registerNotificationCommands(center: INotificationsCenterController, toasts: INotificationsToastController): void {
|
||||
|
||||
function getNotificationFromContext(listService: IListService, context?: any): INotificationViewItem {
|
||||
function getNotificationFromContext(listService: IListService, context?: any): INotificationViewItem | undefined {
|
||||
if (isNotificationViewItem(context)) {
|
||||
return context;
|
||||
}
|
||||
@@ -75,7 +75,7 @@ export function registerNotificationCommands(center: INotificationsCenterControl
|
||||
}
|
||||
}
|
||||
|
||||
return void 0;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Show Notifications Cneter
|
||||
|
||||
@@ -26,9 +26,9 @@ export class NotificationsList extends Themable {
|
||||
constructor(
|
||||
private container: HTMLElement,
|
||||
private options: IListOptions<INotificationViewItem>,
|
||||
@IInstantiationService private instantiationService: IInstantiationService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IContextMenuService private contextMenuService: IContextMenuService
|
||||
@IContextMenuService private readonly contextMenuService: IContextMenuService
|
||||
) {
|
||||
super(themeService);
|
||||
|
||||
@@ -77,7 +77,8 @@ export class NotificationsList extends Themable {
|
||||
[renderer],
|
||||
{
|
||||
...this.options,
|
||||
setRowLineHeight: false
|
||||
setRowLineHeight: false,
|
||||
horizontalScrolling: false
|
||||
}
|
||||
));
|
||||
|
||||
@@ -89,7 +90,7 @@ export class NotificationsList extends Themable {
|
||||
}
|
||||
|
||||
this.contextMenuService.showContextMenu({
|
||||
getAnchor: () => e.anchor,
|
||||
getAnchor: () => e.anchor!,
|
||||
getActions: () => [copyAction],
|
||||
getActionsContext: () => e.element,
|
||||
actionRunner
|
||||
@@ -133,7 +134,7 @@ export class NotificationsList extends Themable {
|
||||
const focusedIndex = this.list.getFocus()[0];
|
||||
const focusedItem = this.viewModel[focusedIndex];
|
||||
|
||||
let focusRelativeTop: number;
|
||||
let focusRelativeTop: number | null = null;
|
||||
if (typeof focusedIndex === 'number') {
|
||||
focusRelativeTop = this.list.getRelativeTop(focusedIndex);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ export class NotificationsStatus extends Disposable {
|
||||
|
||||
constructor(
|
||||
private model: INotificationsModel,
|
||||
@IStatusbarService private statusbarService: IStatusbarService
|
||||
@IStatusbarService private readonly statusbarService: IStatusbarService
|
||||
) {
|
||||
super();
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import { IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { addClass, removeClass, isAncestor, addDisposableListener, EventType, Dimension } from 'vs/base/browser/dom';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { NotificationsList } from 'vs/workbench/browser/parts/notifications/notificationsList';
|
||||
import { once } from 'vs/base/common/event';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { IPartService, Parts } from 'vs/workbench/services/part/common/partService';
|
||||
import { Themable, NOTIFICATIONS_TOAST_BORDER } from 'vs/workbench/common/theme';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
@@ -22,6 +22,7 @@ import { Severity } from 'vs/platform/notification/common/notification';
|
||||
import { ScrollbarVisibility } from 'vs/base/common/scrollable';
|
||||
import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
|
||||
import { IWindowService } from 'vs/platform/windows/common/windows';
|
||||
import { timeout } from 'vs/base/common/async';
|
||||
|
||||
interface INotificationToast {
|
||||
item: INotificationViewItem;
|
||||
@@ -53,7 +54,6 @@ export class NotificationsToasts extends Themable {
|
||||
|
||||
private notificationsToastsContainer: HTMLElement;
|
||||
private workbenchDimensions: Dimension;
|
||||
private windowHasFocus: boolean;
|
||||
private isNotificationsCenterVisible: boolean;
|
||||
private mapNotificationToToast: Map<INotificationViewItem, INotificationToast>;
|
||||
private notificationsToastsVisibleContextKey: IContextKey<boolean>;
|
||||
@@ -61,28 +61,26 @@ export class NotificationsToasts extends Themable {
|
||||
constructor(
|
||||
private container: HTMLElement,
|
||||
private model: INotificationsModel,
|
||||
@IInstantiationService private instantiationService: IInstantiationService,
|
||||
@IPartService private partService: IPartService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@IPartService private readonly partService: IPartService,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IEditorGroupsService private editorGroupService: IEditorGroupsService,
|
||||
@IEditorGroupsService private readonly editorGroupService: IEditorGroupsService,
|
||||
@IContextKeyService contextKeyService: IContextKeyService,
|
||||
@ILifecycleService private lifecycleService: ILifecycleService,
|
||||
@IWindowService private windowService: IWindowService
|
||||
@ILifecycleService private readonly lifecycleService: ILifecycleService,
|
||||
@IWindowService private readonly windowService: IWindowService
|
||||
) {
|
||||
super(themeService);
|
||||
|
||||
this.mapNotificationToToast = new Map<INotificationViewItem, INotificationToast>();
|
||||
this.notificationsToastsVisibleContextKey = NotificationsToastsVisibleContext.bindTo(contextKeyService);
|
||||
|
||||
this.windowService.isFocused().then(isFocused => this.windowHasFocus = isFocused);
|
||||
|
||||
this.registerListeners();
|
||||
}
|
||||
|
||||
private registerListeners(): void {
|
||||
|
||||
// Wait for the running phase to ensure we can draw notifications properly
|
||||
this.lifecycleService.when(LifecyclePhase.Ready).then(() => {
|
||||
// Delay some tasks until after we can show notifications
|
||||
this.onCanShowNotifications().then(() => {
|
||||
|
||||
// Show toast for initial notifications if any
|
||||
this.model.notifications.forEach(notification => this.addToast(notification));
|
||||
@@ -90,9 +88,20 @@ export class NotificationsToasts extends Themable {
|
||||
// Update toasts on notification changes
|
||||
this._register(this.model.onDidNotificationChange(e => this.onDidNotificationChange(e)));
|
||||
});
|
||||
}
|
||||
|
||||
// Track window focus
|
||||
this.windowService.onDidChangeFocus(hasFocus => this.windowHasFocus = hasFocus);
|
||||
private onCanShowNotifications(): Promise<void> {
|
||||
|
||||
// Wait for the running phase to ensure we can draw notifications properly
|
||||
return this.lifecycleService.when(LifecyclePhase.Ready).then(() => {
|
||||
|
||||
// Push notificiations out until either workbench is restored
|
||||
// or some time has ellapsed to reduce pressure on the startup
|
||||
return Promise.race([
|
||||
this.lifecycleService.when(LifecyclePhase.Restored),
|
||||
timeout(2000)
|
||||
]);
|
||||
});
|
||||
}
|
||||
|
||||
private onDidNotificationChange(e: INotificationChangeEvent): void {
|
||||
@@ -185,7 +194,7 @@ export class NotificationsToasts extends Themable {
|
||||
}));
|
||||
|
||||
// Remove when item gets closed
|
||||
once(item.onDidClose)(() => {
|
||||
Event.once(item.onDidClose)(() => {
|
||||
this.removeToast(item);
|
||||
});
|
||||
|
||||
@@ -226,7 +235,7 @@ export class NotificationsToasts extends Themable {
|
||||
// the timeout again. This prevents an issue where focussing the window
|
||||
// could immediately hide the notification because the timeout was triggered
|
||||
// again.
|
||||
if ((item.sticky || item.hasPrompt()) && !this.windowHasFocus) {
|
||||
if ((item.sticky || item.hasPrompt()) && !this.windowService.hasFocus) {
|
||||
if (!listener) {
|
||||
listener = this.windowService.onDidChangeFocus(focus => {
|
||||
if (focus) {
|
||||
@@ -447,7 +456,7 @@ export class NotificationsToasts extends Themable {
|
||||
let maxWidth = NotificationsToasts.MAX_WIDTH;
|
||||
|
||||
let availableWidth = maxWidth;
|
||||
let availableHeight: number;
|
||||
let availableHeight: number | undefined;
|
||||
|
||||
if (this.workbenchDimensions) {
|
||||
|
||||
@@ -468,7 +477,9 @@ export class NotificationsToasts extends Themable {
|
||||
availableHeight -= (2 * 12); // adjust for paddings top and bottom
|
||||
}
|
||||
|
||||
availableHeight = Math.round(availableHeight * 0.618); // try to not cover the full height for stacked toasts
|
||||
availableHeight = typeof availableHeight === 'number'
|
||||
? Math.round(availableHeight * 0.618) // try to not cover the full height for stacked toasts
|
||||
: 0;
|
||||
|
||||
return new Dimension(Math.min(maxWidth, availableWidth), availableHeight);
|
||||
}
|
||||
|
||||
@@ -16,12 +16,13 @@ import { IAction, IActionRunner } from 'vs/base/common/actions';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { DropdownMenuActionItem } from 'vs/base/browser/ui/dropdown/dropdown';
|
||||
import { DropdownMenuActionItem, IContextMenuProvider } from 'vs/base/browser/ui/dropdown/dropdown';
|
||||
import { INotificationViewItem, NotificationViewItem, NotificationViewItemLabelKind, INotificationMessage, ChoiceAction } from 'vs/workbench/common/notifications';
|
||||
import { ClearNotificationAction, ExpandNotificationAction, CollapseNotificationAction, ConfigureNotificationAction } from 'vs/workbench/browser/parts/notifications/notificationsActions';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { ProgressBar } from 'vs/base/browser/ui/progressbar/progressbar';
|
||||
import { Severity } from 'vs/platform/notification/common/notification';
|
||||
import { isNonEmptyArray } from 'vs/base/common/arrays';
|
||||
|
||||
export class NotificationsListDelegate implements IListVirtualDelegate<INotificationViewItem> {
|
||||
|
||||
@@ -61,7 +62,7 @@ export class NotificationsListDelegate implements IListVirtualDelegate<INotifica
|
||||
}
|
||||
|
||||
// Last row: source and buttons if we have any
|
||||
if (notification.source || notification.actions.primary.length > 0) {
|
||||
if (notification.source || isNonEmptyArray(notification.actions.primary)) {
|
||||
expandedHeight += NotificationsListDelegate.ROW_HEIGHT;
|
||||
}
|
||||
|
||||
@@ -81,7 +82,7 @@ export class NotificationsListDelegate implements IListVirtualDelegate<INotifica
|
||||
if (notification.canCollapse) {
|
||||
actions++; // expand/collapse
|
||||
}
|
||||
if (notification.actions.secondary.length > 0) {
|
||||
if (isNonEmptyArray(notification.actions.secondary)) {
|
||||
actions++; // secondary actions
|
||||
}
|
||||
this.offsetHelper.style.width = `calc(100% - ${10 /* padding */ + 24 /* severity icon */ + (actions * 24) /* 24px per action */}px)`;
|
||||
@@ -104,7 +105,7 @@ export class NotificationsListDelegate implements IListVirtualDelegate<INotifica
|
||||
return NotificationRenderer.TEMPLATE_ID;
|
||||
}
|
||||
|
||||
return void 0;
|
||||
throw new Error('unknown element type: ' + element);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,8 +144,7 @@ class NotificationMessageRenderer {
|
||||
// Message has links
|
||||
else {
|
||||
let index = 0;
|
||||
for (let i = 0; i < message.links.length; i++) {
|
||||
const link = message.links[i];
|
||||
for (const link of message.links) {
|
||||
|
||||
const textBefore = message.value.substring(index, link.offset);
|
||||
if (textBefore) {
|
||||
@@ -182,9 +182,9 @@ export class NotificationRenderer implements IListRenderer<INotificationViewItem
|
||||
|
||||
constructor(
|
||||
private actionRunner: IActionRunner,
|
||||
@IThemeService private themeService: IThemeService,
|
||||
@IContextMenuService private contextMenuService: IContextMenuService,
|
||||
@IInstantiationService private instantiationService: IInstantiationService
|
||||
@IThemeService private readonly themeService: IThemeService,
|
||||
@IContextMenuService private readonly contextMenuService: IContextMenuService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -220,8 +220,8 @@ export class NotificationRenderer implements IListRenderer<INotificationViewItem
|
||||
{
|
||||
ariaLabel: localize('notificationActions', "Notification Actions"),
|
||||
actionItemProvider: action => {
|
||||
if (action instanceof ConfigureNotificationAction) {
|
||||
const item = new DropdownMenuActionItem(action, action.configurationActions, this.contextMenuService, null, this.actionRunner, null, action.class);
|
||||
if (action && action instanceof ConfigureNotificationAction) {
|
||||
const item = new DropdownMenuActionItem(action, action.configurationActions, this.contextMenuService as IContextMenuProvider, undefined, this.actionRunner, undefined, action.class as string);
|
||||
data.toDispose.push(item);
|
||||
|
||||
return item;
|
||||
@@ -275,10 +275,6 @@ export class NotificationRenderer implements IListRenderer<INotificationViewItem
|
||||
data.renderer.setInput(notification);
|
||||
}
|
||||
|
||||
disposeElement(): void {
|
||||
// noop
|
||||
}
|
||||
|
||||
disposeTemplate(templateData: INotificationTemplateData): void {
|
||||
templateData.toDispose = dispose(templateData.toDispose);
|
||||
}
|
||||
@@ -290,17 +286,17 @@ export class NotificationTemplateRenderer {
|
||||
private static expandNotificationAction: ExpandNotificationAction;
|
||||
private static collapseNotificationAction: CollapseNotificationAction;
|
||||
|
||||
private static readonly SEVERITIES: ('info' | 'warning' | 'error')[] = ['info', 'warning', 'error'];
|
||||
private static readonly SEVERITIES: Array<'info' | 'warning' | 'error'> = ['info', 'warning', 'error'];
|
||||
|
||||
private inputDisposeables: IDisposable[] = [];
|
||||
|
||||
constructor(
|
||||
private template: INotificationTemplateData,
|
||||
private actionRunner: IActionRunner,
|
||||
@IOpenerService private openerService: IOpenerService,
|
||||
@IInstantiationService private instantiationService: IInstantiationService,
|
||||
@IThemeService private themeService: IThemeService,
|
||||
@IKeybindingService private keybindingService: IKeybindingService
|
||||
@IOpenerService private readonly openerService: IOpenerService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@IThemeService private readonly themeService: IThemeService,
|
||||
@IKeybindingService private readonly keybindingService: IKeybindingService
|
||||
) {
|
||||
if (!NotificationTemplateRenderer.closeNotificationAction) {
|
||||
NotificationTemplateRenderer.closeNotificationAction = instantiationService.createInstance(ClearNotificationAction, ClearNotificationAction.ID, ClearNotificationAction.LABEL);
|
||||
@@ -374,7 +370,7 @@ export class NotificationTemplateRenderer {
|
||||
|
||||
const messageOverflows = notification.canCollapse && !notification.expanded && this.template.message.scrollWidth > this.template.message.clientWidth;
|
||||
if (messageOverflows) {
|
||||
this.template.message.title = this.template.message.textContent;
|
||||
this.template.message.title = this.template.message.textContent + '';
|
||||
} else {
|
||||
this.template.message.removeAttribute('title');
|
||||
}
|
||||
@@ -391,7 +387,7 @@ export class NotificationTemplateRenderer {
|
||||
const actions: IAction[] = [];
|
||||
|
||||
// Secondary Actions
|
||||
if (notification.actions.secondary.length > 0) {
|
||||
if (isNonEmptyArray(notification.actions.secondary)) {
|
||||
const configureNotificationAction = this.instantiationService.createInstance(ConfigureNotificationAction, ConfigureNotificationAction.ID, ConfigureNotificationAction.LABEL, notification.actions.secondary);
|
||||
actions.push(configureNotificationAction);
|
||||
this.inputDisposeables.push(configureNotificationAction);
|
||||
@@ -434,10 +430,10 @@ export class NotificationTemplateRenderer {
|
||||
private renderButtons(notification: INotificationViewItem): void {
|
||||
clearNode(this.template.buttonsContainer);
|
||||
|
||||
if (notification.expanded) {
|
||||
if (notification.expanded && notification.actions.primary) {
|
||||
const buttonGroup = new ButtonGroup(this.template.buttonsContainer, notification.actions.primary.length, { title: true /* assign titles to buttons in case they overflow */ });
|
||||
buttonGroup.buttons.forEach((button, index) => {
|
||||
const action = notification.actions.primary[index];
|
||||
const action = notification.actions.primary![index];
|
||||
button.label = action.label;
|
||||
|
||||
this.inputDisposeables.push(button.onDidClick(e => {
|
||||
@@ -502,10 +498,10 @@ export class NotificationTemplateRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
private getKeybindingLabel(action: IAction): string {
|
||||
private getKeybindingLabel(action: IAction): string | null {
|
||||
const keybinding = this.keybindingService.lookupKeybinding(action.id);
|
||||
|
||||
return keybinding ? keybinding.getLabel() : void 0;
|
||||
return keybinding ? keybinding.getLabel() : null;
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
.monaco-workbench.nopanel > .part.panel {
|
||||
.monaco-workbench.nopanel .part.panel {
|
||||
display: none !important;
|
||||
visibility: hidden !important;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.panel {
|
||||
.monaco-workbench .part.panel {
|
||||
z-index: initial;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.panel .title {
|
||||
.monaco-workbench .part.panel .title {
|
||||
padding-right: 0px;
|
||||
height: 35px;
|
||||
display: flex;
|
||||
@@ -20,23 +20,23 @@
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.panel.bottom .title {
|
||||
.monaco-workbench .part.panel.bottom .title {
|
||||
border-top-width: 1px;
|
||||
border-top-style: solid;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.panel.right {
|
||||
.monaco-workbench .part.panel.right {
|
||||
border-left-width: 1px;
|
||||
border-left-style: solid;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.panel > .title > .title-actions .monaco-action-bar .action-item .action-label {
|
||||
.monaco-workbench .part.panel > .title > .title-actions .monaco-action-bar .action-item .action-label {
|
||||
outline-offset: -2px;
|
||||
}
|
||||
|
||||
/** Panel Switcher */
|
||||
|
||||
.monaco-workbench > .part.panel > .title > .panel-switcher-container.composite-bar > .monaco-action-bar .action-label.toggle-more {
|
||||
.monaco-workbench .part.panel > .title > .panel-switcher-container.composite-bar > .monaco-action-bar .action-label.toggle-more {
|
||||
background-image: url('ellipsis.svg');
|
||||
display: block;
|
||||
height: 28px;
|
||||
@@ -48,16 +48,16 @@
|
||||
background-position: center center;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.panel > .title > .panel-switcher-container > .monaco-action-bar {
|
||||
.monaco-workbench .part.panel > .title > .panel-switcher-container > .monaco-action-bar {
|
||||
line-height: 27px; /* matches panel titles in settings */
|
||||
height: 35px;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.panel > .title > .panel-switcher-container > .monaco-action-bar .action-item:first-child {
|
||||
.monaco-workbench .part.panel > .title > .panel-switcher-container > .monaco-action-bar .action-item:first-child {
|
||||
padding-left: 12px;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.panel > .title > .panel-switcher-container > .monaco-action-bar .action-item {
|
||||
.monaco-workbench .part.panel > .title > .panel-switcher-container > .monaco-action-bar .action-item {
|
||||
text-transform: uppercase;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
@@ -67,24 +67,24 @@
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.panel > .title > .panel-switcher-container > .monaco-action-bar .action-item .action-label{
|
||||
.monaco-workbench .part.panel > .title > .panel-switcher-container > .monaco-action-bar .action-item .action-label{
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.panel > .title > .panel-switcher-container > .monaco-action-bar .action-item:last-child {
|
||||
.monaco-workbench .part.panel > .title > .panel-switcher-container > .monaco-action-bar .action-item:last-child {
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.panel > .title > .panel-switcher-container > .monaco-action-bar .action-item.checked .action-label {
|
||||
.monaco-workbench .part.panel > .title > .panel-switcher-container > .monaco-action-bar .action-item.checked .action-label {
|
||||
border-bottom: 1px solid;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.panel > .title > .panel-switcher-container > .monaco-action-bar .badge {
|
||||
.monaco-workbench .part.panel > .title > .panel-switcher-container > .monaco-action-bar .badge {
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.panel > .title > .panel-switcher-container > .monaco-action-bar .badge .badge-content {
|
||||
.monaco-workbench .part.panel > .title > .panel-switcher-container > .monaco-action-bar .badge .badge-content {
|
||||
padding: 0.3em 0.5em;
|
||||
border-radius: 1em;
|
||||
font-weight: normal;
|
||||
@@ -152,7 +152,7 @@
|
||||
background: url('close-inverse.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
.vs-dark .monaco-workbench > .part.panel > .title > .panel-switcher-container.composite-bar > .monaco-action-bar .action-label.toggle-more,
|
||||
.hc-black .monaco-workbench > .part.panel > .title > .panel-switcher-container.composite-bar > .monaco-action-bar .action-label.toggle-more {
|
||||
.vs-dark .monaco-workbench .part.panel > .title > .panel-switcher-container.composite-bar > .monaco-action-bar .action-label.toggle-more,
|
||||
.hc-black .monaco-workbench .part.panel > .title > .panel-switcher-container.composite-bar > .monaco-action-bar .action-label.toggle-more {
|
||||
background-image: url('ellipsis-inverse.svg');
|
||||
}
|
||||
|
||||
@@ -24,12 +24,12 @@ export class ClosePanelAction extends Action {
|
||||
constructor(
|
||||
id: string,
|
||||
name: string,
|
||||
@IPartService private partService: IPartService
|
||||
@IPartService private readonly partService: IPartService
|
||||
) {
|
||||
super(id, name, 'hide-panel-action');
|
||||
}
|
||||
|
||||
run(): Thenable<any> {
|
||||
run(): Promise<any> {
|
||||
this.partService.setPanelHidden(true);
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
@@ -43,12 +43,12 @@ export class TogglePanelAction extends Action {
|
||||
constructor(
|
||||
id: string,
|
||||
name: string,
|
||||
@IPartService private partService: IPartService
|
||||
@IPartService private readonly partService: IPartService
|
||||
) {
|
||||
super(id, name, partService.isVisible(Parts.PANEL_PART) ? 'panel expanded' : 'panel');
|
||||
}
|
||||
|
||||
run(): Thenable<any> {
|
||||
run(): Promise<any> {
|
||||
this.partService.setPanelHidden(this.partService.isVisible(Parts.PANEL_PART));
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
@@ -62,13 +62,13 @@ class FocusPanelAction extends Action {
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IPanelService private panelService: IPanelService,
|
||||
@IPartService private partService: IPartService
|
||||
@IPanelService private readonly panelService: IPanelService,
|
||||
@IPartService private readonly partService: IPartService
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
run(): Thenable<any> {
|
||||
run(): Promise<any> {
|
||||
|
||||
// Show panel
|
||||
if (!this.partService.isVisible(Parts.PANEL_PART)) {
|
||||
@@ -99,7 +99,7 @@ export class TogglePanelPositionAction extends Action {
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IPartService private partService: IPartService,
|
||||
@IPartService private readonly partService: IPartService,
|
||||
) {
|
||||
super(id, label, partService.getPanelPosition() === Position.RIGHT ? 'move-panel-to-bottom' : 'move-panel-to-right');
|
||||
|
||||
@@ -116,7 +116,7 @@ export class TogglePanelPositionAction extends Action {
|
||||
setClassAndLabel();
|
||||
}
|
||||
|
||||
run(): Thenable<any> {
|
||||
run(): Promise<any> {
|
||||
const position = this.partService.getPanelPosition();
|
||||
|
||||
this.partService.setPanelPosition(position === Position.BOTTOM ? Position.RIGHT : Position.BOTTOM);
|
||||
@@ -143,7 +143,7 @@ export class ToggleMaximizedPanelAction extends Action {
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IPartService private partService: IPartService
|
||||
@IPartService private readonly partService: IPartService
|
||||
) {
|
||||
super(id, label, partService.isPanelMaximized() ? 'minimize-panel-action' : 'maximize-panel-action');
|
||||
|
||||
@@ -156,7 +156,7 @@ export class ToggleMaximizedPanelAction extends Action {
|
||||
}));
|
||||
}
|
||||
|
||||
run(): Thenable<any> {
|
||||
run(): Promise<any> {
|
||||
if (!this.partService.isVisible(Parts.PANEL_PART)) {
|
||||
this.partService.setPanelHidden(false);
|
||||
}
|
||||
@@ -176,12 +176,12 @@ export class PanelActivityAction extends ActivityAction {
|
||||
|
||||
constructor(
|
||||
activity: IActivity,
|
||||
@IPanelService private panelService: IPanelService
|
||||
@IPanelService private readonly panelService: IPanelService
|
||||
) {
|
||||
super(activity);
|
||||
}
|
||||
|
||||
run(event: any): Thenable<any> {
|
||||
run(event: any): Promise<any> {
|
||||
this.panelService.openPanel(this.activity.id, true);
|
||||
this.activate();
|
||||
return Promise.resolve(null);
|
||||
@@ -193,12 +193,12 @@ export class SwitchPanelViewAction extends Action {
|
||||
constructor(
|
||||
id: string,
|
||||
name: string,
|
||||
@IPanelService private panelService: IPanelService
|
||||
@IPanelService private readonly panelService: IPanelService
|
||||
) {
|
||||
super(id, name);
|
||||
}
|
||||
|
||||
run(offset: number): Thenable<any> {
|
||||
run(offset: number): Promise<any> {
|
||||
const pinnedPanels = this.panelService.getPinnedPanels();
|
||||
const activePanel = this.panelService.getActivePanel();
|
||||
if (!activePanel) {
|
||||
@@ -229,7 +229,7 @@ export class PreviousPanelViewAction extends SwitchPanelViewAction {
|
||||
super(id, name, panelService);
|
||||
}
|
||||
|
||||
run(): Thenable<any> {
|
||||
run(): Promise<any> {
|
||||
return super.run(-1);
|
||||
}
|
||||
}
|
||||
@@ -247,7 +247,7 @@ export class NextPanelViewAction extends SwitchPanelViewAction {
|
||||
super(id, name, panelService);
|
||||
}
|
||||
|
||||
public run(): Thenable<any> {
|
||||
public run(): Promise<any> {
|
||||
return super.run(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import 'vs/css!./media/panelpart';
|
||||
import { IAction } from 'vs/base/common/actions';
|
||||
import { Event, mapEvent } from 'vs/base/common/event';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { ActionsOrientation } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { IPanel } from 'vs/workbench/common/panel';
|
||||
@@ -13,7 +13,7 @@ import { CompositePart, ICompositeTitleLabel } from 'vs/workbench/browser/parts/
|
||||
import { Panel, PanelRegistry, Extensions as PanelExtensions, PanelDescriptor } from 'vs/workbench/browser/panel';
|
||||
import { IPanelService, IPanelIdentifier } from 'vs/workbench/services/panel/common/panelService';
|
||||
import { IPartService, Parts, Position } from 'vs/workbench/services/part/common/partService';
|
||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageService, StorageScope, IWorkspaceStorageChangeEvent } from 'vs/platform/storage/common/storage';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
@@ -22,7 +22,7 @@ import { ClosePanelAction, TogglePanelPositionAction, PanelActivityAction, Toggl
|
||||
import { IThemeService, registerThemingParticipant, ITheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService';
|
||||
import { PANEL_BACKGROUND, PANEL_BORDER, PANEL_ACTIVE_TITLE_FOREGROUND, PANEL_INACTIVE_TITLE_FOREGROUND, PANEL_ACTIVE_TITLE_BORDER, PANEL_DRAG_AND_DROP_BACKGROUND } from 'vs/workbench/common/theme';
|
||||
import { activeContrastBorder, focusBorder, contrastBorder, editorBackground, badgeBackground, badgeForeground } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { CompositeBar } from 'vs/workbench/browser/parts/compositeBar';
|
||||
import { CompositeBar, ICompositeBarItem } from 'vs/workbench/browser/parts/compositeBar';
|
||||
import { ToggleCompositePinnedAction } from 'vs/workbench/browser/parts/compositeBarActions';
|
||||
import { IBadge } from 'vs/workbench/services/activity/common/activity';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
@@ -30,11 +30,22 @@ import { Dimension, trackFocus } from 'vs/base/browser/dom';
|
||||
import { localize } from 'vs/nls';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { RawContextKey, IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { isUndefinedOrNull } from 'vs/base/common/types';
|
||||
import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
|
||||
import { ISerializableView } from 'vs/base/browser/ui/grid/grid';
|
||||
import { LayoutPriority } from 'vs/base/browser/ui/grid/gridview';
|
||||
|
||||
export const ActivePanelContext = new RawContextKey<string>('activePanel', '');
|
||||
export const PanelFocusContext = new RawContextKey<boolean>('panelFocus', false);
|
||||
|
||||
export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
interface ICachedPanel {
|
||||
id: string;
|
||||
pinned: boolean;
|
||||
order: number;
|
||||
visible: boolean;
|
||||
}
|
||||
|
||||
export class PanelPart extends CompositePart<Panel> implements IPanelService, ISerializableView {
|
||||
|
||||
static readonly activePanelSettingsKey = 'workbench.panelpart.activepanelid';
|
||||
|
||||
@@ -50,6 +61,17 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
private compositeActions: { [compositeId: string]: { activityAction: PanelActivityAction, pinnedAction: ToggleCompositePinnedAction } } = Object.create(null);
|
||||
private dimension: Dimension;
|
||||
|
||||
element: HTMLElement;
|
||||
minimumWidth: number = 300;
|
||||
maximumWidth: number = Number.POSITIVE_INFINITY;
|
||||
minimumHeight: number = 77;
|
||||
maximumHeight: number = Number.POSITIVE_INFINITY;
|
||||
snapSize: number = 50;
|
||||
priority: LayoutPriority = LayoutPriority.Low;
|
||||
|
||||
private _onDidChange = new Emitter<{ width: number; height: number; }>();
|
||||
readonly onDidChange = this._onDidChange.event;
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
@INotificationService notificationService: INotificationService,
|
||||
@@ -61,6 +83,7 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IContextKeyService contextKeyService: IContextKeyService,
|
||||
@ILifecycleService private readonly lifecycleService: ILifecycleService
|
||||
) {
|
||||
super(
|
||||
notificationService,
|
||||
@@ -81,9 +104,8 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
{ hasTitle: true }
|
||||
);
|
||||
|
||||
this.compositeBar = this._register(this.instantiationService.createInstance(CompositeBar, {
|
||||
this.compositeBar = this._register(this.instantiationService.createInstance(CompositeBar, this.getCachedPanels(), {
|
||||
icon: false,
|
||||
storageId: PanelPart.PINNED_PANELS,
|
||||
orientation: ActionsOrientation.HORIZONTAL,
|
||||
openComposite: (compositeId: string) => Promise.resolve(this.openPanel(compositeId, true)),
|
||||
getActivityAction: (compositeId: string) => this.getCompositeActions(compositeId).activityAction,
|
||||
@@ -120,6 +142,8 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
}
|
||||
|
||||
create(parent: HTMLElement): void {
|
||||
this.element = parent;
|
||||
|
||||
super.create(parent);
|
||||
|
||||
const focusTracker = trackFocus(parent);
|
||||
@@ -137,6 +161,10 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
this._register(this.onDidPanelClose(this._onDidPanelClose, this));
|
||||
|
||||
this._register(this.registry.onDidRegister(panelDescriptor => this.compositeBar.addComposite(panelDescriptor)));
|
||||
this._register(this.registry.onDidDeregister(panelDescriptor => {
|
||||
this.compositeBar.hideComposite(panelDescriptor.id);
|
||||
this.removeComposite(panelDescriptor.id);
|
||||
}));
|
||||
|
||||
// Activate panel action on opening of a panel
|
||||
this._register(this.onDidPanelOpen(({ panel }) => {
|
||||
@@ -146,6 +174,11 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
|
||||
// Deactivate panel action on close
|
||||
this._register(this.onDidPanelClose(panel => this.compositeBar.deactivateComposite(panel.getId())));
|
||||
|
||||
this.lifecycleService.when(LifecyclePhase.Eventually).then(() => {
|
||||
this._register(this.compositeBar.onDidChange(() => this.saveCachedPanels()));
|
||||
this._register(this.storageService.onDidChangeStorage(e => this.onDidStorageChange(e)));
|
||||
});
|
||||
}
|
||||
|
||||
private _onDidPanelOpen(panel: IPanel): void {
|
||||
@@ -161,7 +194,7 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
}
|
||||
|
||||
get onDidPanelOpen(): Event<{ panel: IPanel, focus: boolean }> {
|
||||
return mapEvent(this._onDidCompositeOpen.event, compositeOpen => ({ panel: compositeOpen.composite, focus: compositeOpen.focus }));
|
||||
return Event.map(this._onDidCompositeOpen.event, compositeOpen => ({ panel: compositeOpen.composite, focus: compositeOpen.focus }));
|
||||
}
|
||||
|
||||
get onDidPanelClose(): Event<IPanel> {
|
||||
@@ -207,7 +240,6 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
|
||||
getPanels(): PanelDescriptor[] {
|
||||
return Registry.as<PanelRegistry>(PanelExtensions.Panels).getPanels()
|
||||
.filter(p => p.enabled)
|
||||
.sort((v1, v2) => v1.order - v2.order);
|
||||
}
|
||||
|
||||
@@ -218,18 +250,6 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
.sort((p1, p2) => pinnedCompositeIds.indexOf(p1.id) - pinnedCompositeIds.indexOf(p2.id));
|
||||
}
|
||||
|
||||
setPanelEnablement(id: string, enabled: boolean): void {
|
||||
const descriptor = Registry.as<PanelRegistry>(PanelExtensions.Panels).getPanels().filter(p => p.id === id).pop();
|
||||
if (descriptor && descriptor.enabled !== enabled) {
|
||||
descriptor.enabled = enabled;
|
||||
if (enabled) {
|
||||
this.compositeBar.addComposite(descriptor);
|
||||
} else {
|
||||
this.removeComposite(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected getActions(): IAction[] {
|
||||
return [
|
||||
this.instantiationService.createInstance(ToggleMaximizedPanelAction, ToggleMaximizedPanelAction.ID, ToggleMaximizedPanelAction.LABEL),
|
||||
@@ -266,21 +286,32 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
};
|
||||
}
|
||||
|
||||
layout(dimension: Dimension): Dimension[] {
|
||||
layout(dimension: Dimension): Dimension[];
|
||||
layout(width: number, height: number): void;
|
||||
layout(dim1: Dimension | number, dim2?: number): Dimension[] | void {
|
||||
if (!this.partService.isVisible(Parts.PANEL_PART)) {
|
||||
return [dimension];
|
||||
if (dim1 instanceof Dimension) {
|
||||
return [dim1];
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const { width, height } = dim1 instanceof Dimension ? dim1 : { width: dim1, height: dim2 };
|
||||
|
||||
if (this.partService.getPanelPosition() === Position.RIGHT) {
|
||||
// Take into account the 1px border when layouting
|
||||
this.dimension = new Dimension(dimension.width - 1, dimension.height);
|
||||
this.dimension = new Dimension(width - 1, height);
|
||||
} else {
|
||||
this.dimension = dimension;
|
||||
this.dimension = new Dimension(width, height);
|
||||
}
|
||||
const sizes = super.layout(this.dimension);
|
||||
|
||||
const sizes = super.layout(this.dimension.width, this.dimension.height);
|
||||
this.layoutCompositeBar();
|
||||
|
||||
return sizes;
|
||||
if (dim1 instanceof Dimension) {
|
||||
return sizes;
|
||||
}
|
||||
}
|
||||
|
||||
private layoutCompositeBar(): void {
|
||||
@@ -306,14 +337,17 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
return compositeActions;
|
||||
}
|
||||
|
||||
private removeComposite(compositeId: string): void {
|
||||
this.compositeBar.hideComposite(compositeId);
|
||||
const compositeActions = this.compositeActions[compositeId];
|
||||
if (compositeActions) {
|
||||
compositeActions.activityAction.dispose();
|
||||
compositeActions.pinnedAction.dispose();
|
||||
delete this.compositeActions[compositeId];
|
||||
protected removeComposite(compositeId: string): boolean {
|
||||
if (super.removeComposite(compositeId)) {
|
||||
const compositeActions = this.compositeActions[compositeId];
|
||||
if (compositeActions) {
|
||||
compositeActions.activityAction.dispose();
|
||||
compositeActions.pinnedAction.dispose();
|
||||
delete this.compositeActions[compositeId];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private getToolbarWidth(): number {
|
||||
@@ -323,6 +357,89 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
}
|
||||
return this.toolBar.getItemsWidth();
|
||||
}
|
||||
|
||||
private onDidStorageChange(e: IWorkspaceStorageChangeEvent): void {
|
||||
if (e.key === PanelPart.PINNED_PANELS && e.scope === StorageScope.GLOBAL
|
||||
&& this.cachedPanelsValue !== this.getStoredCachedPanelsValue() /* This checks if current window changed the value or not */) {
|
||||
this._cachedPanelsValue = null;
|
||||
const newCompositeItems: ICompositeBarItem[] = [];
|
||||
const compositeItems = this.compositeBar.getCompositeBarItems();
|
||||
const cachedPanels = this.getCachedPanels();
|
||||
|
||||
for (const cachedPanel of cachedPanels) {
|
||||
// Add and update existing items
|
||||
const existingItem = compositeItems.filter(({ id }) => id === cachedPanel.id)[0];
|
||||
if (existingItem) {
|
||||
newCompositeItems.push({
|
||||
id: existingItem.id,
|
||||
name: existingItem.name,
|
||||
order: existingItem.order,
|
||||
pinned: cachedPanel.pinned,
|
||||
visible: existingItem.visible
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
for (let index = 0; index < compositeItems.length; index++) {
|
||||
// Add items currently exists but does not exist in new.
|
||||
if (!newCompositeItems.some(({ id }) => id === compositeItems[index].id)) {
|
||||
newCompositeItems.splice(index, 0, compositeItems[index]);
|
||||
}
|
||||
}
|
||||
|
||||
this.compositeBar.setCompositeBarItems(newCompositeItems);
|
||||
}
|
||||
}
|
||||
|
||||
private saveCachedPanels(): void {
|
||||
const state: ICachedPanel[] = [];
|
||||
const compositeItems = this.compositeBar.getCompositeBarItems();
|
||||
for (const compositeItem of compositeItems) {
|
||||
state.push({ id: compositeItem.id, pinned: compositeItem.pinned, order: compositeItem.order, visible: compositeItem.visible });
|
||||
}
|
||||
this.cachedPanelsValue = JSON.stringify(state);
|
||||
}
|
||||
|
||||
private getCachedPanels(): ICachedPanel[] {
|
||||
const storedStates = <Array<string | ICachedPanel>>JSON.parse(this.cachedPanelsValue);
|
||||
const registeredPanels = this.getPanels();
|
||||
const cachedPanels = <ICachedPanel[]>storedStates.map(c => {
|
||||
const serialized: ICachedPanel = typeof c === 'string' /* migration from pinned states to composites states */ ? <ICachedPanel>{ id: c, pinned: true, order: undefined, visible: true } : c;
|
||||
const registered = registeredPanels.some(p => p.id === serialized.id);
|
||||
serialized.visible = registered ? isUndefinedOrNull(serialized.visible) ? true : serialized.visible : false;
|
||||
return serialized;
|
||||
});
|
||||
return cachedPanels;
|
||||
}
|
||||
|
||||
private _cachedPanelsValue: string;
|
||||
private get cachedPanelsValue(): string {
|
||||
if (!this._cachedPanelsValue) {
|
||||
this._cachedPanelsValue = this.getStoredCachedPanelsValue();
|
||||
}
|
||||
return this._cachedPanelsValue;
|
||||
}
|
||||
|
||||
private set cachedPanelsValue(cachedViewletsValue: string) {
|
||||
if (this.cachedPanelsValue !== cachedViewletsValue) {
|
||||
this._cachedPanelsValue = cachedViewletsValue;
|
||||
this.setStoredCachedViewletsValue(cachedViewletsValue);
|
||||
}
|
||||
}
|
||||
|
||||
private getStoredCachedPanelsValue(): string {
|
||||
return this.storageService.get(PanelPart.PINNED_PANELS, StorageScope.GLOBAL, '[]');
|
||||
}
|
||||
|
||||
private setStoredCachedViewletsValue(value: string): void {
|
||||
this.storageService.store(PanelPart.PINNED_PANELS, value, StorageScope.GLOBAL);
|
||||
}
|
||||
|
||||
toJSON(): object {
|
||||
return {
|
||||
type: Parts.PANEL_PART
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
|
||||
@@ -333,9 +450,9 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
|
||||
const panelBackground = theme.getColor(PANEL_BACKGROUND);
|
||||
if (panelBackground && panelBackground !== theme.getColor(editorBackground)) {
|
||||
collector.addRule(`
|
||||
.monaco-workbench > .part.panel > .content .monaco-editor,
|
||||
.monaco-workbench > .part.panel > .content .monaco-editor .margin,
|
||||
.monaco-workbench > .part.panel > .content .monaco-editor .monaco-editor-background {
|
||||
.monaco-workbench .part.panel > .content .monaco-editor,
|
||||
.monaco-workbench .part.panel > .content .monaco-editor .margin,
|
||||
.monaco-workbench .part.panel > .content .monaco-editor .monaco-editor-background {
|
||||
background-color: ${panelBackground};
|
||||
}
|
||||
`);
|
||||
@@ -346,7 +463,7 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
|
||||
const titleActiveBorder = theme.getColor(PANEL_ACTIVE_TITLE_BORDER);
|
||||
if (titleActive || titleActiveBorder) {
|
||||
collector.addRule(`
|
||||
.monaco-workbench > .part.panel > .title > .panel-switcher-container > .monaco-action-bar .action-item:hover .action-label {
|
||||
.monaco-workbench .part.panel > .title > .panel-switcher-container > .monaco-action-bar .action-item:hover .action-label {
|
||||
color: ${titleActive} !important;
|
||||
border-bottom-color: ${titleActiveBorder} !important;
|
||||
}
|
||||
@@ -357,14 +474,14 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
|
||||
const focusBorderColor = theme.getColor(focusBorder);
|
||||
if (focusBorderColor) {
|
||||
collector.addRule(`
|
||||
.monaco-workbench > .part.panel > .title > .panel-switcher-container > .monaco-action-bar .action-item:focus .action-label {
|
||||
.monaco-workbench .part.panel > .title > .panel-switcher-container > .monaco-action-bar .action-item:focus .action-label {
|
||||
color: ${titleActive} !important;
|
||||
border-bottom-color: ${focusBorderColor} !important;
|
||||
border-bottom: 1px solid;
|
||||
}
|
||||
`);
|
||||
collector.addRule(`
|
||||
.monaco-workbench > .part.panel > .title > .panel-switcher-container > .monaco-action-bar .action-item:focus {
|
||||
.monaco-workbench .part.panel > .title > .panel-switcher-container > .monaco-action-bar .action-item:focus {
|
||||
outline: none;
|
||||
}
|
||||
`);
|
||||
@@ -376,8 +493,8 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
|
||||
const outline = theme.getColor(activeContrastBorder);
|
||||
|
||||
collector.addRule(`
|
||||
.monaco-workbench > .part.panel > .title > .panel-switcher-container > .monaco-action-bar .action-item.checked .action-label,
|
||||
.monaco-workbench > .part.panel > .title > .panel-switcher-container > .monaco-action-bar .action-item .action-label:hover {
|
||||
.monaco-workbench .part.panel > .title > .panel-switcher-container > .monaco-action-bar .action-item.checked .action-label,
|
||||
.monaco-workbench .part.panel > .title > .panel-switcher-container > .monaco-action-bar .action-item .action-label:hover {
|
||||
outline-color: ${outline};
|
||||
outline-width: 1px;
|
||||
outline-style: solid;
|
||||
@@ -386,7 +503,7 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
|
||||
outline-offset: 1px;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.panel > .title > .panel-switcher-container > .monaco-action-bar .action-item:not(.checked) .action-label:hover {
|
||||
.monaco-workbench .part.panel > .title > .panel-switcher-container > .monaco-action-bar .action-item:not(.checked) .action-label:hover {
|
||||
outline-style: dashed;
|
||||
}
|
||||
`);
|
||||
|
||||
@@ -25,7 +25,7 @@ import { CountBadge } from 'vs/base/browser/ui/countBadge/countBadge';
|
||||
import { attachBadgeStyler, attachProgressBarStyler, attachButtonStyler } from 'vs/platform/theme/common/styler';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { ProgressBar } from 'vs/base/browser/ui/progressbar/progressbar';
|
||||
import { debounceEvent, Emitter, Event } from 'vs/base/common/event';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { Button } from 'vs/base/browser/ui/button/button';
|
||||
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import Severity from 'vs/base/common/severity';
|
||||
@@ -252,14 +252,20 @@ class QuickInput implements IQuickInput {
|
||||
this.ui.leftActionBar.clear();
|
||||
const leftButtons = this.buttons.filter(button => button === backButton);
|
||||
this.ui.leftActionBar.push(leftButtons.map((button, index) => {
|
||||
const action = new Action(`id-${index}`, '', button.iconClass || getIconClass(button.iconPath), true, () => this.onDidTriggerButtonEmitter.fire(button));
|
||||
const action = new Action(`id-${index}`, '', button.iconClass || getIconClass(button.iconPath), true, () => {
|
||||
this.onDidTriggerButtonEmitter.fire(button);
|
||||
return Promise.resolve(null);
|
||||
});
|
||||
action.tooltip = button.tooltip;
|
||||
return action;
|
||||
}), { icon: true, label: false });
|
||||
this.ui.rightActionBar.clear();
|
||||
const rightButtons = this.buttons.filter(button => button !== backButton);
|
||||
this.ui.rightActionBar.push(rightButtons.map((button, index) => {
|
||||
const action = new Action(`id-${index}`, '', button.iconClass || getIconClass(button.iconPath), true, () => this.onDidTriggerButtonEmitter.fire(button));
|
||||
const action = new Action(`id-${index}`, '', button.iconClass || getIconClass(button.iconPath), true, () => {
|
||||
this.onDidTriggerButtonEmitter.fire(button);
|
||||
return Promise.resolve(null);
|
||||
});
|
||||
action.tooltip = button.tooltip;
|
||||
return action;
|
||||
}), { icon: true, label: false });
|
||||
@@ -306,7 +312,7 @@ class QuickPick<T extends IQuickPickItem> extends QuickInput implements IQuickPi
|
||||
private _placeholder;
|
||||
private onDidChangeValueEmitter = new Emitter<string>();
|
||||
private onDidAcceptEmitter = new Emitter<string>();
|
||||
private _items: (T | IQuickPickSeparator)[] = [];
|
||||
private _items: Array<T | IQuickPickSeparator> = [];
|
||||
private itemsUpdated = false;
|
||||
private _canSelectMany = false;
|
||||
private _matchOnDescription = false;
|
||||
@@ -360,7 +366,7 @@ class QuickPick<T extends IQuickPickItem> extends QuickInput implements IQuickPi
|
||||
return this._items;
|
||||
}
|
||||
|
||||
set items(items: (T | IQuickPickSeparator)[]) {
|
||||
set items(items: Array<T | IQuickPickSeparator>) {
|
||||
this._items = items;
|
||||
this.itemsUpdated = true;
|
||||
this.update();
|
||||
@@ -482,7 +488,7 @@ class QuickPick<T extends IQuickPickItem> extends QuickInput implements IQuickPi
|
||||
this._selectedItems = [this.activeItems[0]];
|
||||
this.onDidChangeSelectionEmitter.fire(this.selectedItems);
|
||||
}
|
||||
this.onDidAcceptEmitter.fire();
|
||||
this.onDidAcceptEmitter.fire(undefined);
|
||||
}),
|
||||
this.ui.list.onDidChangeFocus(focusedItems => {
|
||||
if (this.activeItemsUpdated) {
|
||||
@@ -507,7 +513,7 @@ class QuickPick<T extends IQuickPickItem> extends QuickInput implements IQuickPi
|
||||
this._selectedItems = selectedItems as T[];
|
||||
this.onDidChangeSelectionEmitter.fire(selectedItems as T[]);
|
||||
if (selectedItems.length) {
|
||||
this.onDidAcceptEmitter.fire();
|
||||
this.onDidAcceptEmitter.fire(undefined);
|
||||
}
|
||||
}),
|
||||
this.ui.list.onChangedCheckedElements(checkedItems => {
|
||||
@@ -570,7 +576,7 @@ class QuickPick<T extends IQuickPickItem> extends QuickInput implements IQuickPi
|
||||
if (wasTriggerKeyPressed && this.activeItems[0]) {
|
||||
this._selectedItems = [this.activeItems[0]];
|
||||
this.onDidChangeSelectionEmitter.fire(this.selectedItems);
|
||||
this.onDidAcceptEmitter.fire();
|
||||
this.onDidAcceptEmitter.fire(undefined);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -723,7 +729,7 @@ class InputBox extends QuickInput implements IInputBox {
|
||||
this._value = value;
|
||||
this.onDidValueChangeEmitter.fire(value);
|
||||
}),
|
||||
this.ui.onDidAccept(() => this.onDidAcceptEmitter.fire()),
|
||||
this.ui.onDidAccept(() => this.onDidAcceptEmitter.fire(undefined)),
|
||||
);
|
||||
this.valueSelectionUpdated = true;
|
||||
}
|
||||
@@ -788,14 +794,14 @@ export class QuickInputService extends Component implements IQuickInputService {
|
||||
private controller: QuickInput;
|
||||
|
||||
constructor(
|
||||
@IEnvironmentService private environmentService: IEnvironmentService,
|
||||
@IConfigurationService private configurationService: IConfigurationService,
|
||||
@IInstantiationService private instantiationService: IInstantiationService,
|
||||
@IPartService private partService: IPartService,
|
||||
@IQuickOpenService private quickOpenService: IQuickOpenService,
|
||||
@IEditorGroupsService private editorGroupService: IEditorGroupsService,
|
||||
@IKeybindingService private keybindingService: IKeybindingService,
|
||||
@IContextKeyService private contextKeyService: IContextKeyService,
|
||||
@IEnvironmentService private readonly environmentService: IEnvironmentService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@IPartService private readonly partService: IPartService,
|
||||
@IQuickOpenService private readonly quickOpenService: IQuickOpenService,
|
||||
@IEditorGroupsService private readonly editorGroupService: IEditorGroupsService,
|
||||
@IKeybindingService private readonly keybindingService: IKeybindingService,
|
||||
@IContextKeyService private readonly contextKeyService: IContextKeyService,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IStorageService storageService: IStorageService
|
||||
) {
|
||||
@@ -1129,7 +1135,7 @@ export class QuickInputService extends Component implements IQuickInputService {
|
||||
}
|
||||
});
|
||||
input.show();
|
||||
Promise.resolve(picks).then(null, err => {
|
||||
Promise.resolve(picks).then(undefined, err => {
|
||||
reject(err);
|
||||
input.hide();
|
||||
});
|
||||
@@ -1143,8 +1149,8 @@ export class QuickInputService extends Component implements IQuickInputService {
|
||||
return;
|
||||
}
|
||||
const input = this.createInputBox();
|
||||
const validateInput = options.validateInput || (() => <Thenable<undefined>>Promise.resolve(undefined));
|
||||
const onDidValueChange = debounceEvent(input.onDidChangeValue, (last, cur) => cur, 100);
|
||||
const validateInput = options.validateInput || (() => <Promise<undefined>>Promise.resolve(undefined));
|
||||
const onDidValueChange = Event.debounce(input.onDidChangeValue, (last, cur) => cur, 100);
|
||||
let validationValue = options.value || '';
|
||||
let validation = Promise.resolve(validateInput(validationValue));
|
||||
const disposables = [
|
||||
@@ -1406,7 +1412,7 @@ export class BackAction extends Action {
|
||||
public static readonly ID = 'workbench.action.quickInputBack';
|
||||
public static readonly LABEL = localize('back', "Back");
|
||||
|
||||
constructor(id: string, label: string, @IQuickInputService private quickInputService: IQuickInputService) {
|
||||
constructor(id: string, label: string, @IQuickInputService private readonly quickInputService: IQuickInputService) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ export class QuickInputBox {
|
||||
private parent: HTMLElement
|
||||
) {
|
||||
this.container = dom.append(this.parent, $('.quick-input-box'));
|
||||
this.inputBox = new InputBox(this.container, null);
|
||||
this.inputBox = new InputBox(this.container, undefined);
|
||||
this.disposables.push(this.inputBox);
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ export class QuickInputBox {
|
||||
}
|
||||
|
||||
get placeholder() {
|
||||
return this.inputBox.inputElement.getAttribute('placeholder');
|
||||
return this.inputBox.inputElement.getAttribute('placeholder') || '';
|
||||
}
|
||||
|
||||
set placeholder(placeholder: string) {
|
||||
|
||||
@@ -13,7 +13,7 @@ import { IQuickPickItem, IQuickPickItemButtonEvent, IQuickPickSeparator } from '
|
||||
import { IMatch } from 'vs/base/common/filters';
|
||||
import { matchesFuzzyOcticonAware, parseOcticons } from 'vs/base/common/octicon';
|
||||
import { compareAnything } from 'vs/base/common/comparers';
|
||||
import { Emitter, Event, mapEvent } from 'vs/base/common/event';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { assign } from 'vs/base/common/objects';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
@@ -32,14 +32,14 @@ import { IListOptions } from 'vs/base/browser/ui/list/listWidget';
|
||||
const $ = dom.$;
|
||||
|
||||
interface IListElement {
|
||||
index: number;
|
||||
item: IQuickPickItem;
|
||||
saneLabel: string;
|
||||
saneDescription?: string;
|
||||
saneDetail?: string;
|
||||
checked: boolean;
|
||||
separator: IQuickPickSeparator;
|
||||
fireButtonTriggered: (event: IQuickPickItemButtonEvent<IQuickPickItem>) => void;
|
||||
readonly index: number;
|
||||
readonly item: IQuickPickItem;
|
||||
readonly saneLabel: string;
|
||||
readonly saneDescription?: string;
|
||||
readonly saneDetail?: string;
|
||||
readonly checked: boolean;
|
||||
readonly separator?: IQuickPickSeparator;
|
||||
readonly fireButtonTriggered: (event: IQuickPickItemButtonEvent<IQuickPickItem>) => void;
|
||||
}
|
||||
|
||||
class ListElement implements IListElement {
|
||||
@@ -53,7 +53,7 @@ class ListElement implements IListElement {
|
||||
onChecked = this._onChecked.event;
|
||||
_checked?: boolean;
|
||||
get checked() {
|
||||
return this._checked;
|
||||
return !!this._checked;
|
||||
}
|
||||
set checked(value: boolean) {
|
||||
if (value !== this._checked) {
|
||||
@@ -61,7 +61,7 @@ class ListElement implements IListElement {
|
||||
this._onChecked.fire(value);
|
||||
}
|
||||
}
|
||||
separator: IQuickPickSeparator;
|
||||
separator?: IQuickPickSeparator;
|
||||
labelHighlights?: IMatch[];
|
||||
descriptionHighlights?: IMatch[];
|
||||
detailHighlights?: IMatch[];
|
||||
@@ -144,7 +144,7 @@ class ListElementRenderer implements IListRenderer<ListElement, IListElementTemp
|
||||
options.descriptionTitle = element.saneDescription;
|
||||
options.descriptionMatches = descriptionHighlights || [];
|
||||
options.extraClasses = element.item.iconClasses;
|
||||
data.label.setValue(element.saneLabel, element.saneDescription, options);
|
||||
data.label.setLabel(element.saneLabel, element.saneDescription, options);
|
||||
|
||||
// Meta
|
||||
data.detail.set(element.saneDetail, detailHighlights);
|
||||
@@ -173,14 +173,14 @@ class ListElementRenderer implements IListRenderer<ListElement, IListElementTemp
|
||||
const buttons = element.item.buttons;
|
||||
if (buttons && buttons.length) {
|
||||
data.actionBar.push(buttons.map((button, index) => {
|
||||
const action = new Action(`id-${index}`, '', button.iconClass || getIconClass(button.iconPath), true, () => {
|
||||
const action = new Action(`id-${index}`, '', button.iconClass || (button.iconPath ? getIconClass(button.iconPath) : undefined), true, () => {
|
||||
element.fireButtonTriggered({
|
||||
button,
|
||||
item: element.item
|
||||
});
|
||||
return null;
|
||||
return Promise.resolve();
|
||||
});
|
||||
action.tooltip = button.tooltip;
|
||||
action.tooltip = button.tooltip || '';
|
||||
return action;
|
||||
}), { icon: true, label: false });
|
||||
dom.addClass(data.entry, 'has-actions');
|
||||
@@ -215,7 +215,7 @@ export class QuickInputList {
|
||||
readonly id: string;
|
||||
private container: HTMLElement;
|
||||
private list: WorkbenchList<ListElement>;
|
||||
private inputElements: (IQuickPickItem | IQuickPickSeparator)[];
|
||||
private inputElements: Array<IQuickPickItem | IQuickPickSeparator>;
|
||||
private elements: ListElement[] = [];
|
||||
private elementsToIndexes = new Map<IQuickPickItem, number>();
|
||||
matchOnDescription = false;
|
||||
@@ -239,7 +239,7 @@ export class QuickInputList {
|
||||
constructor(
|
||||
private parent: HTMLElement,
|
||||
id: string,
|
||||
@IInstantiationService private instantiationService: IInstantiationService
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService
|
||||
) {
|
||||
this.id = id;
|
||||
this.container = dom.append(this.parent, $('.quick-input-list'));
|
||||
@@ -248,7 +248,8 @@ export class QuickInputList {
|
||||
identityProvider: { getId: element => element.saneLabel },
|
||||
openController: { shouldOpen: () => false }, // Workaround #58124
|
||||
setRowLineHeight: false,
|
||||
multipleSelectionSupport: false
|
||||
multipleSelectionSupport: false,
|
||||
horizontalScrolling: false
|
||||
} as IListOptions<ListElement>) as WorkbenchList<ListElement>;
|
||||
this.list.getHTMLElement().id = id;
|
||||
this.disposables.push(this.list);
|
||||
@@ -294,12 +295,12 @@ export class QuickInputList {
|
||||
|
||||
@memoize
|
||||
get onDidChangeFocus() {
|
||||
return mapEvent(this.list.onFocusChange, e => e.elements.map(e => e.item));
|
||||
return Event.map(this.list.onFocusChange, e => e.elements.map(e => e.item));
|
||||
}
|
||||
|
||||
@memoize
|
||||
get onDidChangeSelection() {
|
||||
return mapEvent(this.list.onSelectionChange, e => e.elements.map(e => e.item));
|
||||
return Event.map(this.list.onSelectionChange, e => e.elements.map(e => e.item));
|
||||
}
|
||||
|
||||
getAllVisibleChecked() {
|
||||
@@ -356,7 +357,7 @@ export class QuickInputList {
|
||||
}
|
||||
}
|
||||
|
||||
setElements(inputElements: (IQuickPickItem | IQuickPickSeparator)[]): void {
|
||||
setElements(inputElements: Array<IQuickPickItem | IQuickPickSeparator>): void {
|
||||
this.elementDisposables = dispose(this.elementDisposables);
|
||||
const fireButtonTriggered = (event: IQuickPickItemButtonEvent<IQuickPickItem>) => this.fireButtonTriggered(event);
|
||||
this.inputElements = inputElements;
|
||||
@@ -395,7 +396,7 @@ export class QuickInputList {
|
||||
setFocusedElements(items: IQuickPickItem[]) {
|
||||
this.list.setFocus(items
|
||||
.filter(item => this.elementsToIndexes.has(item))
|
||||
.map(item => this.elementsToIndexes.get(item)));
|
||||
.map(item => this.elementsToIndexes.get(item)!));
|
||||
}
|
||||
|
||||
getActiveDescendant() {
|
||||
@@ -410,7 +411,7 @@ export class QuickInputList {
|
||||
setSelectedElements(items: IQuickPickItem[]) {
|
||||
this.list.setSelection(items
|
||||
.filter(item => this.elementsToIndexes.has(item))
|
||||
.map(item => this.elementsToIndexes.get(item)));
|
||||
.map(item => this.elementsToIndexes.get(item)!));
|
||||
}
|
||||
|
||||
getCheckedElements() {
|
||||
@@ -484,9 +485,9 @@ export class QuickInputList {
|
||||
// Filter by value (since we support octicons, use octicon aware fuzzy matching)
|
||||
else {
|
||||
this.elements.forEach(element => {
|
||||
const labelHighlights = matchesFuzzyOcticonAware(query, parseOcticons(element.saneLabel));
|
||||
const descriptionHighlights = this.matchOnDescription ? matchesFuzzyOcticonAware(query, parseOcticons(element.saneDescription || '')) : undefined;
|
||||
const detailHighlights = this.matchOnDetail ? matchesFuzzyOcticonAware(query, parseOcticons(element.saneDetail || '')) : undefined;
|
||||
const labelHighlights = matchesFuzzyOcticonAware(query, parseOcticons(element.saneLabel)) || undefined;
|
||||
const descriptionHighlights = this.matchOnDescription ? matchesFuzzyOcticonAware(query, parseOcticons(element.saneDescription || '')) || undefined : undefined;
|
||||
const detailHighlights = this.matchOnDetail ? matchesFuzzyOcticonAware(query, parseOcticons(element.saneDetail || '')) || undefined : undefined;
|
||||
|
||||
if (labelHighlights || descriptionHighlights || detailHighlights) {
|
||||
element.labelHighlights = labelHighlights;
|
||||
|
||||
@@ -53,7 +53,7 @@ import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
|
||||
const HELP_PREFIX = '?';
|
||||
|
||||
type ValueCallback<T = any> = (value: T | Thenable<T>) => void;
|
||||
type ValueCallback<T = any> = (value: T | Promise<T>) => void;
|
||||
|
||||
export class QuickOpenController extends Component implements IQuickOpenService {
|
||||
|
||||
@@ -86,13 +86,13 @@ export class QuickOpenController extends Component implements IQuickOpenService
|
||||
private pendingGetResultsInvocation: CancellationTokenSource;
|
||||
|
||||
constructor(
|
||||
@IEditorGroupsService private editorGroupService: IEditorGroupsService,
|
||||
@INotificationService private notificationService: INotificationService,
|
||||
@IContextKeyService private contextKeyService: IContextKeyService,
|
||||
@IConfigurationService private configurationService: IConfigurationService,
|
||||
@IInstantiationService private instantiationService: IInstantiationService,
|
||||
@IPartService private partService: IPartService,
|
||||
@IEnvironmentService private environmentService: IEnvironmentService,
|
||||
@IEditorGroupsService private readonly editorGroupService: IEditorGroupsService,
|
||||
@INotificationService private readonly notificationService: INotificationService,
|
||||
@IContextKeyService private readonly contextKeyService: IContextKeyService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@IPartService private readonly partService: IPartService,
|
||||
@IEnvironmentService private readonly environmentService: IEnvironmentService,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IStorageService storageService: IStorageService
|
||||
) {
|
||||
@@ -155,9 +155,9 @@ export class QuickOpenController extends Component implements IQuickOpenService
|
||||
}
|
||||
|
||||
show(prefix?: string, options?: IShowOptions): Promise<void> {
|
||||
let quickNavigateConfiguration = options ? options.quickNavigateConfiguration : void 0;
|
||||
let inputSelection = options ? options.inputSelection : void 0;
|
||||
let autoFocus = options ? options.autoFocus : void 0;
|
||||
let quickNavigateConfiguration = options ? options.quickNavigateConfiguration : undefined;
|
||||
let inputSelection = options ? options.inputSelection : undefined;
|
||||
let autoFocus = options ? options.autoFocus : undefined;
|
||||
|
||||
const promiseCompletedOnHide = new Promise<void>(c => {
|
||||
this.promisesToCompleteOnHide.push(c);
|
||||
@@ -452,11 +452,11 @@ export class QuickOpenController extends Component implements IQuickOpenService
|
||||
const previousInput = this.quickOpenWidget.getInput();
|
||||
const wasShowingHistory = previousInput && previousInput.entries && previousInput.entries.some(e => e instanceof EditorHistoryEntry || e instanceof EditorHistoryEntryGroup);
|
||||
if (wasShowingHistory || matchingHistoryEntries.length > 0) {
|
||||
let responseDelay: Thenable<void>;
|
||||
let responseDelay: Promise<void>;
|
||||
if (resolvedHandler.hasShortResponseTime()) {
|
||||
responseDelay = timeout(QuickOpenController.MAX_SHORT_RESPONSE_TIME);
|
||||
} else {
|
||||
responseDelay = Promise.resolve(void 0);
|
||||
responseDelay = Promise.resolve();
|
||||
}
|
||||
|
||||
responseDelay.then(() => {
|
||||
@@ -490,8 +490,7 @@ export class QuickOpenController extends Component implements IQuickOpenService
|
||||
// Remove results already showing by checking for a "resource" property
|
||||
const mapEntryToResource = this.mapEntriesToResource(quickOpenModel);
|
||||
const additionalHandlerResults: QuickOpenEntry[] = [];
|
||||
for (let i = 0; i < handlerResults.length; i++) {
|
||||
const result = handlerResults[i];
|
||||
for (const result of handlerResults) {
|
||||
const resource = result.getResource();
|
||||
|
||||
if (!result.mergeWithEditorHistory() || !resource || !mapEntryToResource[resource.toString()]) {
|
||||
@@ -529,7 +528,7 @@ export class QuickOpenController extends Component implements IQuickOpenService
|
||||
const model = new QuickOpenModel([new PlaceholderQuickOpenEntry(placeHolderLabel)], this.actionProvider);
|
||||
this.showModel(model, resolvedHandler.getAutoFocus(value, { model, quickNavigateConfiguration: this.quickOpenWidget.getQuickNavigateConfiguration() }), resolvedHandler.getAriaLabel());
|
||||
|
||||
return Promise.resolve(null);
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
// Support extra class from handler
|
||||
@@ -646,9 +645,9 @@ class EditorHistoryHandler {
|
||||
private scorerCache: ScorerCache;
|
||||
|
||||
constructor(
|
||||
@IHistoryService private historyService: IHistoryService,
|
||||
@IInstantiationService private instantiationService: IInstantiationService,
|
||||
@IFileService private fileService: IFileService
|
||||
@IHistoryService private readonly historyService: IHistoryService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@IFileService private readonly fileService: IFileService
|
||||
) {
|
||||
this.scorerCache = Object.create(null);
|
||||
}
|
||||
@@ -709,7 +708,7 @@ class EditorHistoryItemAccessorClass extends QuickOpenItemAccessorClass {
|
||||
}
|
||||
|
||||
getItemDescription(entry: QuickOpenEntry): string {
|
||||
return this.allowMatchOnDescription ? entry.getDescription() : void 0;
|
||||
return this.allowMatchOnDescription ? entry.getDescription() : undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -730,10 +729,10 @@ export class EditorHistoryEntry extends EditorQuickOpenEntry {
|
||||
constructor(
|
||||
input: IEditorInput | IResourceInput,
|
||||
@IEditorService editorService: IEditorService,
|
||||
@IModeService private modeService: IModeService,
|
||||
@IModelService private modelService: IModelService,
|
||||
@ITextFileService private textFileService: ITextFileService,
|
||||
@IConfigurationService private configurationService: IConfigurationService,
|
||||
@IModeService private readonly modeService: IModeService,
|
||||
@IModelService private readonly modelService: IModelService,
|
||||
@ITextFileService private readonly textFileService: ITextFileService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@ILabelService labelService: ILabelService,
|
||||
@IFileService fileService: IFileService
|
||||
) {
|
||||
@@ -808,7 +807,7 @@ export class EditorHistoryEntry extends EditorQuickOpenEntry {
|
||||
}
|
||||
|
||||
function resourceForEditorHistory(input: EditorInput, fileService: IFileService): URI {
|
||||
const resource = input ? input.getResource() : void 0;
|
||||
const resource = input ? input.getResource() : undefined;
|
||||
|
||||
// For the editor history we only prefer resources that are either untitled or
|
||||
// can be handled by the file service which indicates they are editable resources.
|
||||
@@ -816,7 +815,7 @@ function resourceForEditorHistory(input: EditorInput, fileService: IFileService)
|
||||
return resource;
|
||||
}
|
||||
|
||||
return void 0;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export class RemoveFromEditorHistoryAction extends Action {
|
||||
@@ -827,16 +826,16 @@ export class RemoveFromEditorHistoryAction extends Action {
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IQuickInputService private quickInputService: IQuickInputService,
|
||||
@IModelService private modelService: IModelService,
|
||||
@IModeService private modeService: IModeService,
|
||||
@IInstantiationService private instantiationService: IInstantiationService,
|
||||
@IHistoryService private historyService: IHistoryService
|
||||
@IQuickInputService private readonly quickInputService: IQuickInputService,
|
||||
@IModelService private readonly modelService: IModelService,
|
||||
@IModeService private readonly modeService: IModeService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@IHistoryService private readonly historyService: IHistoryService
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
run(): Thenable<any> {
|
||||
run(): Promise<any> {
|
||||
interface IHistoryPickEntry extends IQuickPickItem {
|
||||
input: IEditorInput | IResourceInput;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ CommandsRegistry.registerCommand(QUICKOPEN_ACTION_ID, function (accessor: Servic
|
||||
const quickOpenService = accessor.get(IQuickOpenService);
|
||||
|
||||
return quickOpenService.show(typeof prefix === 'string' ? prefix : undefined).then(() => {
|
||||
return void 0;
|
||||
return undefined;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -32,7 +32,7 @@ CommandsRegistry.registerCommand(QUICKOPEN_FOCUS_SECONDARY_ACTION_ID, function (
|
||||
const quickOpenService = accessor.get(IQuickOpenService);
|
||||
|
||||
return quickOpenService.show(undefined, { autoFocus: { autoFocusSecondEntry: true } }).then(() => {
|
||||
return void 0;
|
||||
return undefined;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -43,16 +43,16 @@ export class BaseQuickOpenNavigateAction extends Action {
|
||||
label: string,
|
||||
private next: boolean,
|
||||
private quickNavigate: boolean,
|
||||
@IQuickOpenService private quickOpenService: IQuickOpenService,
|
||||
@IQuickInputService private quickInputService: IQuickInputService,
|
||||
@IKeybindingService private keybindingService: IKeybindingService
|
||||
@IQuickOpenService private readonly quickOpenService: IQuickOpenService,
|
||||
@IQuickInputService private readonly quickInputService: IQuickInputService,
|
||||
@IKeybindingService private readonly keybindingService: IKeybindingService
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
run(event?: any): Thenable<any> {
|
||||
run(event?: any): Promise<any> {
|
||||
const keys = this.keybindingService.lookupKeybindings(this.id);
|
||||
const quickNavigate = this.quickNavigate ? { keybindings: keys } : void 0;
|
||||
const quickNavigate = this.quickNavigate ? { keybindings: keys } : undefined;
|
||||
|
||||
this.quickOpenService.navigate(this.next, quickNavigate);
|
||||
this.quickInputService.navigate(this.next, quickNavigate);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
.monaco-workbench > .sidebar > .content {
|
||||
.monaco-workbench .sidebar > .content {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
visibility: hidden !important;
|
||||
}
|
||||
|
||||
.monaco-workbench > .sidebar > .title > .title-label h2 {
|
||||
.monaco-workbench .sidebar > .title > .title-label h2 {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import * as nls from 'vs/nls';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { Action } from 'vs/base/common/actions';
|
||||
import { CompositePart } from 'vs/workbench/browser/parts/compositePart';
|
||||
import { Viewlet, ViewletRegistry, Extensions as ViewletExtensions } from 'vs/workbench/browser/viewlet';
|
||||
import { Viewlet, ViewletRegistry, Extensions as ViewletExtensions, ViewletDescriptor } from 'vs/workbench/browser/viewlet';
|
||||
import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actions';
|
||||
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
|
||||
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
|
||||
@@ -20,25 +20,43 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { KeyMod, KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { Event, mapEvent } from 'vs/base/common/event';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { contrastBorder } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { SIDE_BAR_TITLE_FOREGROUND, SIDE_BAR_BACKGROUND, SIDE_BAR_FOREGROUND, SIDE_BAR_BORDER } from 'vs/workbench/common/theme';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { Dimension, EventType, addDisposableListener, trackFocus } from 'vs/base/browser/dom';
|
||||
import { EventType, addDisposableListener, trackFocus, Dimension } from 'vs/base/browser/dom';
|
||||
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
|
||||
import { RawContextKey, IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { AnchorAlignment } from 'vs/base/browser/ui/contextview/contextview';
|
||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { ISerializableView } from 'vs/base/browser/ui/grid/grid';
|
||||
import { LayoutPriority } from 'vs/base/browser/ui/grid/gridview';
|
||||
|
||||
const SideBarFocusContextId = 'sideBarFocus';
|
||||
export const SidebarFocusContext = new RawContextKey<boolean>(SideBarFocusContextId, false);
|
||||
export const SidebarFocusContext = new RawContextKey<boolean>('sideBarFocus', false);
|
||||
export const ActiveViewletContext = new RawContextKey<string>('activeViewlet', '');
|
||||
|
||||
export class SidebarPart extends CompositePart<Viewlet> {
|
||||
export class SidebarPart extends CompositePart<Viewlet> implements ISerializableView, IViewletService {
|
||||
_serviceBrand: any;
|
||||
|
||||
static readonly activeViewletSettingsKey = 'workbench.sidebar.activeviewletid';
|
||||
|
||||
private viewletRegistry: ViewletRegistry;
|
||||
private sideBarFocusContextKey: IContextKey<boolean>;
|
||||
private activeViewletContextKey: IContextKey<string>;
|
||||
private blockOpeningViewlet: boolean;
|
||||
private _onDidViewletDeregister = this._register(new Emitter<ViewletDescriptor>());
|
||||
|
||||
element: HTMLElement;
|
||||
minimumWidth: number = 170;
|
||||
maximumWidth: number = Number.POSITIVE_INFINITY;
|
||||
minimumHeight: number = 0;
|
||||
maximumHeight: number = Number.POSITIVE_INFINITY;
|
||||
snapSize: number = 50;
|
||||
priority: LayoutPriority = LayoutPriority.Low;
|
||||
|
||||
private _onDidChange = new Emitter<{ width: number; height: number; }>();
|
||||
readonly onDidChange = this._onDidChange.event;
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
@@ -51,6 +69,7 @@ export class SidebarPart extends CompositePart<Viewlet> {
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IContextKeyService contextKeyService: IContextKeyService,
|
||||
@IExtensionService private readonly extensionService: IExtensionService
|
||||
) {
|
||||
super(
|
||||
notificationService,
|
||||
@@ -72,10 +91,32 @@ export class SidebarPart extends CompositePart<Viewlet> {
|
||||
);
|
||||
|
||||
this.sideBarFocusContextKey = SidebarFocusContext.bindTo(contextKeyService);
|
||||
this.viewletRegistry = Registry.as<ViewletRegistry>(ViewletExtensions.Viewlets);
|
||||
|
||||
this.activeViewletContextKey = ActiveViewletContext.bindTo(contextKeyService);
|
||||
|
||||
this._register(this.onDidViewletOpen(viewlet => {
|
||||
this.activeViewletContextKey.set(viewlet.getId());
|
||||
}));
|
||||
this._register(this.onDidViewletClose(viewlet => {
|
||||
if (this.activeViewletContextKey.get() === viewlet.getId()) {
|
||||
this.activeViewletContextKey.reset();
|
||||
}
|
||||
}));
|
||||
this._register(this.registry.onDidDeregister(async (viewletDescriptor: ViewletDescriptor) => {
|
||||
if (this.getActiveViewlet().getId() === viewletDescriptor.id) {
|
||||
await this.openViewlet(this.getDefaultViewletId());
|
||||
}
|
||||
this.removeComposite(viewletDescriptor.id);
|
||||
this._onDidViewletDeregister.fire(viewletDescriptor);
|
||||
}));
|
||||
}
|
||||
|
||||
get onDidViewletRegister(): Event<ViewletDescriptor> { return <Event<ViewletDescriptor>>this.viewletRegistry.onDidRegister; }
|
||||
get onDidViewletDeregister(): Event<ViewletDescriptor> { return this._onDidViewletDeregister.event; }
|
||||
|
||||
get onDidViewletOpen(): Event<IViewlet> {
|
||||
return mapEvent(this._onDidCompositeOpen.event, compositeEvent => <IViewlet>compositeEvent.composite);
|
||||
return Event.map(this._onDidCompositeOpen.event, compositeEvent => <IViewlet>compositeEvent.composite);
|
||||
}
|
||||
|
||||
get onDidViewletClose(): Event<IViewlet> {
|
||||
@@ -83,6 +124,8 @@ export class SidebarPart extends CompositePart<Viewlet> {
|
||||
}
|
||||
|
||||
create(parent: HTMLElement): void {
|
||||
this.element = parent;
|
||||
|
||||
super.create(parent);
|
||||
|
||||
const focusTracker = trackFocus(parent);
|
||||
@@ -124,7 +167,65 @@ export class SidebarPart extends CompositePart<Viewlet> {
|
||||
container.style.borderLeftColor = !isPositionLeft ? borderColor : null;
|
||||
}
|
||||
|
||||
openViewlet(id: string, focus?: boolean): Viewlet {
|
||||
layout(dimension: Dimension): Dimension[];
|
||||
layout(width: number, height: number): void;
|
||||
layout(dim1: Dimension | number, dim2?: number): Dimension[] | void {
|
||||
if (!this.partService.isVisible(Parts.SIDEBAR_PART)) {
|
||||
if (dim1 instanceof Dimension) {
|
||||
return [dim1];
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (dim1 instanceof Dimension) {
|
||||
return super.layout(dim1);
|
||||
}
|
||||
|
||||
super.layout(dim1, dim2!);
|
||||
}
|
||||
|
||||
// Viewlet service
|
||||
|
||||
getActiveViewlet(): IViewlet {
|
||||
return <IViewlet>this.getActiveComposite();
|
||||
}
|
||||
|
||||
getLastActiveViewletId(): string {
|
||||
return this.getLastActiveCompositetId();
|
||||
}
|
||||
|
||||
hideActiveViewlet(): void {
|
||||
this.hideActiveComposite();
|
||||
}
|
||||
|
||||
openViewlet(id: string, focus?: boolean): Promise<IViewlet | null> {
|
||||
if (this.getViewlet(id)) {
|
||||
return Promise.resolve(this.doOpenViewlet(id, focus));
|
||||
}
|
||||
return this.extensionService.whenInstalledExtensionsRegistered()
|
||||
.then(() => {
|
||||
if (this.getViewlet(id)) {
|
||||
return this.doOpenViewlet(id, focus);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
getViewlets(): ViewletDescriptor[] {
|
||||
return this.viewletRegistry.getViewlets()
|
||||
.sort((v1, v2) => v1.order! - v2.order!);
|
||||
}
|
||||
|
||||
getDefaultViewletId(): string {
|
||||
return this.viewletRegistry.getDefaultViewletId();
|
||||
}
|
||||
|
||||
getViewlet(id: string): ViewletDescriptor {
|
||||
return this.getViewlets().filter(viewlet => viewlet.id === id)[0];
|
||||
}
|
||||
|
||||
private doOpenViewlet(id: string, focus?: boolean): Viewlet | null {
|
||||
if (this.blockOpeningViewlet) {
|
||||
return null; // Workaround against a potential race condition
|
||||
}
|
||||
@@ -142,26 +243,6 @@ export class SidebarPart extends CompositePart<Viewlet> {
|
||||
return this.openComposite(id, focus) as Viewlet;
|
||||
}
|
||||
|
||||
getActiveViewlet(): IViewlet {
|
||||
return <IViewlet>this.getActiveComposite();
|
||||
}
|
||||
|
||||
getLastActiveViewletId(): string {
|
||||
return this.getLastActiveCompositetId();
|
||||
}
|
||||
|
||||
hideActiveViewlet(): void {
|
||||
this.hideActiveComposite();
|
||||
}
|
||||
|
||||
layout(dimension: Dimension): Dimension[] {
|
||||
if (!this.partService.isVisible(Parts.SIDEBAR_PART)) {
|
||||
return [dimension];
|
||||
}
|
||||
|
||||
return super.layout(dimension);
|
||||
}
|
||||
|
||||
protected getTitleAreaDropDownAnchorAlignment(): AnchorAlignment {
|
||||
return this.partService.getSideBarPosition() === SideBarPosition.LEFT ? AnchorAlignment.LEFT : AnchorAlignment.RIGHT;
|
||||
}
|
||||
@@ -181,6 +262,12 @@ export class SidebarPart extends CompositePart<Viewlet> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
toJSON(): object {
|
||||
return {
|
||||
type: Parts.SIDEBAR_PART
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class FocusSideBarAction extends Action {
|
||||
@@ -191,13 +278,13 @@ class FocusSideBarAction extends Action {
|
||||
constructor(
|
||||
id: string,
|
||||
label: string,
|
||||
@IViewletService private viewletService: IViewletService,
|
||||
@IPartService private partService: IPartService
|
||||
@IViewletService private readonly viewletService: IViewletService,
|
||||
@IPartService private readonly partService: IPartService
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
run(): Thenable<any> {
|
||||
run(): Promise<any> {
|
||||
|
||||
// Show side bar
|
||||
if (!this.partService.isVisible(Parts.SIDEBAR_PART)) {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
.monaco-workbench > .part.statusbar {
|
||||
.monaco-workbench .part.statusbar {
|
||||
box-sizing: border-box;
|
||||
cursor: default;
|
||||
width: 100%;
|
||||
@@ -11,18 +11,18 @@
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.statusbar > .statusbar-item {
|
||||
.monaco-workbench .part.statusbar > .statusbar-item {
|
||||
display: inline-block;
|
||||
line-height: 22px;
|
||||
height: 100%;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.statusbar > .statusbar-item.has-beak {
|
||||
.monaco-workbench .part.statusbar > .statusbar-item.has-beak {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.statusbar > .statusbar-item.has-beak:before {
|
||||
.monaco-workbench .part.statusbar > .statusbar-item.has-beak:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 11px;
|
||||
@@ -33,48 +33,48 @@
|
||||
border-right: 5px solid transparent;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.statusbar > .statusbar-item.left > :first-child {
|
||||
.monaco-workbench .part.statusbar > .statusbar-item.left > :first-child {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.statusbar > .statusbar-item.right {
|
||||
.monaco-workbench .part.statusbar > .statusbar-item.right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.statusbar > .statusbar-item.right > :first-child {
|
||||
.monaco-workbench .part.statusbar > .statusbar-item.right > :first-child {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
/* adding padding to the most left status bar item */
|
||||
.monaco-workbench > .part.statusbar > .statusbar-item.left:first-child, .monaco-workbench > .part.statusbar > .statusbar-item.right + .statusbar-item.left {
|
||||
.monaco-workbench .part.statusbar > .statusbar-item.left:first-child, .monaco-workbench .part.statusbar > .statusbar-item.right + .statusbar-item.left {
|
||||
padding-left: 10px;
|
||||
}
|
||||
/* adding padding to the most right status bar item */
|
||||
.monaco-workbench > .part.statusbar > .statusbar-item.right:first-child {
|
||||
.monaco-workbench .part.statusbar > .statusbar-item.right:first-child {
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.statusbar > .statusbar-item a {
|
||||
.monaco-workbench .part.statusbar > .statusbar-item a {
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.statusbar > .statusbar-entry > span {
|
||||
.monaco-workbench .part.statusbar > .statusbar-entry > span {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.statusbar > .statusbar-entry > span,
|
||||
.monaco-workbench > .part.statusbar > .statusbar-entry > a {
|
||||
.monaco-workbench .part.statusbar > .statusbar-entry > span,
|
||||
.monaco-workbench .part.statusbar > .statusbar-entry > a {
|
||||
padding: 0 5px 0 5px;
|
||||
white-space: pre; /* gives some degree of styling */
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.statusbar > .statusbar-entry span.octicon {
|
||||
.monaco-workbench .part.statusbar > .statusbar-entry span.octicon {
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.statusbar > .statusbar-item a:hover {
|
||||
.monaco-workbench .part.statusbar > .statusbar-item a:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
@@ -24,27 +24,39 @@ import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/
|
||||
import { contrastBorder } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { isThemeColor } from 'vs/editor/common/editorCommon';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { addClass, EventHelper, createStyleSheet, addDisposableListener } from 'vs/base/browser/dom';
|
||||
import { addClass, EventHelper, createStyleSheet, addDisposableListener, Dimension } from 'vs/base/browser/dom';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
import { ISerializableView } from 'vs/base/browser/ui/grid/grid';
|
||||
import { Parts } from 'vs/workbench/services/part/common/partService';
|
||||
|
||||
export class StatusbarPart extends Part implements IStatusbarService {
|
||||
|
||||
export class StatusbarPart extends Part implements IStatusbarService, ISerializableView {
|
||||
_serviceBrand: any;
|
||||
|
||||
private static readonly PRIORITY_PROP = 'statusbar-entry-priority';
|
||||
private static readonly ALIGNMENT_PROP = 'statusbar-entry-alignment';
|
||||
|
||||
private statusItemsContainer: HTMLElement;
|
||||
element: HTMLElement;
|
||||
private statusMsgDispose: IDisposable;
|
||||
|
||||
|
||||
minimumWidth: number = 0;
|
||||
maximumWidth: number = Number.POSITIVE_INFINITY;
|
||||
minimumHeight: number = 22;
|
||||
maximumHeight: number = 22;
|
||||
|
||||
private _onDidChange = new Emitter<{ width: number; height: number; }>();
|
||||
readonly onDidChange = this._onDidChange.event;
|
||||
|
||||
private styleElement: HTMLStyleElement;
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
@IInstantiationService private instantiationService: IInstantiationService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IWorkspaceContextService private contextService: IWorkspaceContextService,
|
||||
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
|
||||
@IStorageService storageService: IStorageService
|
||||
) {
|
||||
super(id, { hasTitle: false }, themeService, storageService);
|
||||
@@ -59,16 +71,15 @@ export class StatusbarPart extends Part implements IStatusbarService {
|
||||
addEntry(entry: IStatusbarEntry, alignment: StatusbarAlignment, priority: number = 0): IDisposable {
|
||||
|
||||
// Render entry in status bar
|
||||
const el = this.doCreateStatusItem(alignment, priority, entry.showBeak ? 'has-beak' : void 0);
|
||||
const el = this.doCreateStatusItem(alignment, priority, entry.showBeak ? 'has-beak' : undefined);
|
||||
const item = this.instantiationService.createInstance(StatusBarEntryItem, entry);
|
||||
const toDispose = item.render(el);
|
||||
|
||||
// Insert according to priority
|
||||
const container = this.statusItemsContainer;
|
||||
const container = this.element;
|
||||
const neighbours = this.getEntries(alignment);
|
||||
let inserted = false;
|
||||
for (let i = 0; i < neighbours.length; i++) {
|
||||
const neighbour = neighbours[i];
|
||||
for (const neighbour of neighbours) {
|
||||
const nPriority = Number(neighbour.getAttribute(StatusbarPart.PRIORITY_PROP));
|
||||
if (
|
||||
alignment === StatusbarAlignment.LEFT && nPriority < priority ||
|
||||
@@ -96,7 +107,7 @@ export class StatusbarPart extends Part implements IStatusbarService {
|
||||
private getEntries(alignment: StatusbarAlignment): HTMLElement[] {
|
||||
const entries: HTMLElement[] = [];
|
||||
|
||||
const container = this.statusItemsContainer;
|
||||
const container = this.element;
|
||||
const children = container.children;
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
const childElement = <HTMLElement>children.item(i);
|
||||
@@ -109,7 +120,7 @@ export class StatusbarPart extends Part implements IStatusbarService {
|
||||
}
|
||||
|
||||
createContentArea(parent: HTMLElement): HTMLElement {
|
||||
this.statusItemsContainer = parent;
|
||||
this.element = parent;
|
||||
|
||||
// Fill in initial items that were contributed from the registry
|
||||
const registry = Registry.as<IStatusbarRegistry>(Extensions.Statusbar);
|
||||
@@ -135,10 +146,10 @@ export class StatusbarPart extends Part implements IStatusbarService {
|
||||
const el = this.doCreateStatusItem(descriptor.alignment, descriptor.priority);
|
||||
|
||||
this._register(item.render(el));
|
||||
this.statusItemsContainer.appendChild(el);
|
||||
this.element.appendChild(el);
|
||||
}
|
||||
|
||||
return this.statusItemsContainer;
|
||||
return this.element;
|
||||
}
|
||||
|
||||
protected updateStyles(): void {
|
||||
@@ -162,7 +173,7 @@ export class StatusbarPart extends Part implements IStatusbarService {
|
||||
this.styleElement = createStyleSheet(container);
|
||||
}
|
||||
|
||||
this.styleElement.innerHTML = `.monaco-workbench > .part.statusbar > .statusbar-item.has-beak:before { border-bottom-color: ${backgroundColor}; }`;
|
||||
this.styleElement.innerHTML = `.monaco-workbench .part.statusbar > .statusbar-item.has-beak:before { border-bottom-color: ${backgroundColor}; }`;
|
||||
}
|
||||
|
||||
private doCreateStatusItem(alignment: StatusbarAlignment, priority: number = 0, extraClass?: string): HTMLElement {
|
||||
@@ -191,7 +202,7 @@ export class StatusbarPart extends Part implements IStatusbarService {
|
||||
|
||||
// Create new
|
||||
let statusDispose: IDisposable;
|
||||
let showHandle = setTimeout(() => {
|
||||
let showHandle: any = setTimeout(() => {
|
||||
statusDispose = this.addEntry({ text: message }, StatusbarAlignment.LEFT, -Number.MAX_VALUE /* far right on left hand side */);
|
||||
showHandle = null;
|
||||
}, delayBy);
|
||||
@@ -221,6 +232,22 @@ export class StatusbarPart extends Part implements IStatusbarService {
|
||||
|
||||
return dispose;
|
||||
}
|
||||
|
||||
layout(dimension: Dimension): Dimension[];
|
||||
layout(width: number, height: number): void;
|
||||
layout(dim1: Dimension | number, dim2?: number): Dimension[] | void {
|
||||
if (dim1 instanceof Dimension) {
|
||||
return super.layout(dim1);
|
||||
} else {
|
||||
super.layout(new Dimension(dim1, dim2!));
|
||||
}
|
||||
}
|
||||
|
||||
toJSON(): object {
|
||||
return {
|
||||
type: Parts.STATUSBAR_PART
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
let manageExtensionAction: ManageExtensionAction;
|
||||
@@ -228,13 +255,13 @@ class StatusBarEntryItem implements IStatusbarItem {
|
||||
|
||||
constructor(
|
||||
private entry: IStatusbarEntry,
|
||||
@ICommandService private commandService: ICommandService,
|
||||
@IInstantiationService private instantiationService: IInstantiationService,
|
||||
@INotificationService private notificationService: INotificationService,
|
||||
@ITelemetryService private telemetryService: ITelemetryService,
|
||||
@IContextMenuService private contextMenuService: IContextMenuService,
|
||||
@IEditorService private editorService: IEditorService,
|
||||
@IThemeService private themeService: IThemeService
|
||||
@ICommandService private readonly commandService: ICommandService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@INotificationService private readonly notificationService: INotificationService,
|
||||
@ITelemetryService private readonly telemetryService: ITelemetryService,
|
||||
@IContextMenuService private readonly contextMenuService: IContextMenuService,
|
||||
@IEditorService private readonly editorService: IEditorService,
|
||||
@IThemeService private readonly themeService: IThemeService
|
||||
) {
|
||||
this.entry = entry;
|
||||
|
||||
@@ -252,7 +279,7 @@ class StatusBarEntryItem implements IStatusbarItem {
|
||||
if (this.entry.command) {
|
||||
textContainer = document.createElement('a');
|
||||
|
||||
toDispose.push(addDisposableListener(textContainer, 'click', () => this.executeCommand(this.entry.command, this.entry.arguments)));
|
||||
toDispose.push(addDisposableListener(textContainer, 'click', () => this.executeCommand(this.entry.command!, this.entry.arguments)));
|
||||
} else {
|
||||
textContainer = document.createElement('span');
|
||||
}
|
||||
@@ -286,7 +313,7 @@ class StatusBarEntryItem implements IStatusbarItem {
|
||||
|
||||
this.contextMenuService.showContextMenu({
|
||||
getAnchor: () => el,
|
||||
getActionsContext: () => this.entry.extensionId,
|
||||
getActionsContext: () => this.entry.extensionId!.value,
|
||||
getActions: () => [manageExtensionAction]
|
||||
});
|
||||
}));
|
||||
@@ -324,12 +351,12 @@ class StatusBarEntryItem implements IStatusbarItem {
|
||||
class ManageExtensionAction extends Action {
|
||||
|
||||
constructor(
|
||||
@ICommandService private commandService: ICommandService
|
||||
@ICommandService private readonly commandService: ICommandService
|
||||
) {
|
||||
super('statusbar.manage.extension', nls.localize('manageExtension', "Manage Extension"));
|
||||
}
|
||||
|
||||
run(extensionId: string): Thenable<any> {
|
||||
run(extensionId: string): Promise<any> {
|
||||
return this.commandService.executeCommand('_extensions.manage', extensionId);
|
||||
}
|
||||
}
|
||||
@@ -337,21 +364,21 @@ class ManageExtensionAction extends Action {
|
||||
registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
|
||||
const statusBarItemHoverBackground = theme.getColor(STATUS_BAR_ITEM_HOVER_BACKGROUND);
|
||||
if (statusBarItemHoverBackground) {
|
||||
collector.addRule(`.monaco-workbench > .part.statusbar > .statusbar-item a:hover { background-color: ${statusBarItemHoverBackground}; }`);
|
||||
collector.addRule(`.monaco-workbench .part.statusbar > .statusbar-item a:hover { background-color: ${statusBarItemHoverBackground}; }`);
|
||||
}
|
||||
|
||||
const statusBarItemActiveBackground = theme.getColor(STATUS_BAR_ITEM_ACTIVE_BACKGROUND);
|
||||
if (statusBarItemActiveBackground) {
|
||||
collector.addRule(`.monaco-workbench > .part.statusbar > .statusbar-item a:active { background-color: ${statusBarItemActiveBackground}; }`);
|
||||
collector.addRule(`.monaco-workbench .part.statusbar > .statusbar-item a:active { background-color: ${statusBarItemActiveBackground}; }`);
|
||||
}
|
||||
|
||||
const statusBarProminentItemBackground = theme.getColor(STATUS_BAR_PROMINENT_ITEM_BACKGROUND);
|
||||
if (statusBarProminentItemBackground) {
|
||||
collector.addRule(`.monaco-workbench > .part.statusbar > .statusbar-item .status-bar-info { background-color: ${statusBarProminentItemBackground}; }`);
|
||||
collector.addRule(`.monaco-workbench .part.statusbar > .statusbar-item .status-bar-info { background-color: ${statusBarProminentItemBackground}; }`);
|
||||
}
|
||||
|
||||
const statusBarProminentItemHoverBackground = theme.getColor(STATUS_BAR_PROMINENT_ITEM_HOVER_BACKGROUND);
|
||||
if (statusBarProminentItemHoverBackground) {
|
||||
collector.addRule(`.monaco-workbench > .part.statusbar > .statusbar-item a.status-bar-info:hover { background-color: ${statusBarProminentItemHoverBackground}; }`);
|
||||
collector.addRule(`.monaco-workbench .part.statusbar > .statusbar-item a.status-bar-info:hover { background-color: ${statusBarProminentItemHoverBackground}; }`);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
.monaco-workbench > .part.titlebar {
|
||||
.monaco-workbench .part.titlebar {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
padding: 0 70px;
|
||||
@@ -18,7 +18,7 @@
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.titlebar > .titlebar-drag-region {
|
||||
.monaco-workbench .part.titlebar > .titlebar-drag-region {
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: block;
|
||||
@@ -29,7 +29,7 @@
|
||||
-webkit-app-region: drag;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.titlebar > .window-title {
|
||||
.monaco-workbench .part.titlebar > .window-title {
|
||||
flex: 0 1 auto;
|
||||
font-size: 12px;
|
||||
overflow: hidden;
|
||||
@@ -42,8 +42,8 @@
|
||||
|
||||
/* Windows/Linux: Rules for custom title (icon, window controls) */
|
||||
|
||||
.monaco-workbench.windows > .part.titlebar,
|
||||
.monaco-workbench.linux > .part.titlebar {
|
||||
.windows > .monaco-workbench .part.titlebar,
|
||||
.linux > .monaco-workbench .part.titlebar {
|
||||
padding: 0;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
@@ -51,17 +51,17 @@
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.monaco-workbench.windows > .part.titlebar > .window-title,
|
||||
.monaco-workbench.linux > .part.titlebar > .window-title {
|
||||
.windows > .monaco-workbench .part.titlebar > .window-title,
|
||||
.linux > .monaco-workbench .part.titlebar > .window-title {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.monaco-workbench.linux > .part.titlebar > .window-title {
|
||||
.linux > .monaco-workbench .part.titlebar > .window-title {
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
.monaco-workbench.windows > .part.titlebar > .resizer,
|
||||
.monaco-workbench.linux > .part.titlebar > .resizer {
|
||||
.windows > .monaco-workbench .part.titlebar > .resizer,
|
||||
.linux > .monaco-workbench .part.titlebar > .resizer {
|
||||
-webkit-app-region: no-drag;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
@@ -69,13 +69,13 @@
|
||||
height: 20%;
|
||||
}
|
||||
|
||||
.monaco-workbench.windows.fullscreen > .part.titlebar > .resizer,
|
||||
.monaco-workbench.linux.fullscreen > .part.titlebar > .resizer {
|
||||
.windows > .monaco-workbench.fullscreen .part.titlebar > .resizer,
|
||||
.linux > .monaco-workbench.fullscreen .part.titlebar > .resizer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
.monaco-workbench > .part.titlebar > .window-appicon {
|
||||
.monaco-workbench .part.titlebar > .window-appicon {
|
||||
width: 35px;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
@@ -87,11 +87,11 @@
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.monaco-workbench.fullscreen > .part.titlebar > .window-appicon {
|
||||
.monaco-workbench.fullscreen .part.titlebar > .window-appicon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.titlebar > .window-controls-container {
|
||||
.monaco-workbench .part.titlebar > .window-controls-container {
|
||||
display: flex;
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
@@ -104,56 +104,56 @@
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.monaco-workbench.fullscreen > .part.titlebar > .window-controls-container {
|
||||
.monaco-workbench.fullscreen .part.titlebar > .window-controls-container {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.titlebar > .window-controls-container > .window-icon-bg {
|
||||
.monaco-workbench .part.titlebar > .window-controls-container > .window-icon-bg {
|
||||
display: inline-block;
|
||||
-webkit-app-region: no-drag;
|
||||
height: 100%;
|
||||
width: 33.34%;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.titlebar > .window-controls-container .window-icon svg {
|
||||
.monaco-workbench .part.titlebar > .window-controls-container .window-icon svg {
|
||||
shape-rendering: crispEdges;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.titlebar.titlebar > .window-controls-container .window-close {
|
||||
.monaco-workbench .part.titlebar.titlebar > .window-controls-container .window-close {
|
||||
-webkit-mask: url('chrome-close.svg') no-repeat 50% 50%;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.titlebar.titlebar > .window-controls-container .window-unmaximize {
|
||||
.monaco-workbench .part.titlebar.titlebar > .window-controls-container .window-unmaximize {
|
||||
-webkit-mask: url('chrome-restore.svg') no-repeat 50% 50%;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.titlebar > .window-controls-container .window-maximize {
|
||||
.monaco-workbench .part.titlebar > .window-controls-container .window-maximize {
|
||||
-webkit-mask: url('chrome-maximize.svg') no-repeat 50% 50%;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.titlebar > .window-controls-container .window-minimize {
|
||||
.monaco-workbench .part.titlebar > .window-controls-container .window-minimize {
|
||||
-webkit-mask: url('chrome-minimize.svg') no-repeat 50% 50%;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.titlebar > .window-controls-container > .window-icon-bg > .window-icon {
|
||||
.monaco-workbench .part.titlebar > .window-controls-container > .window-icon-bg > .window-icon {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
-webkit-mask-size: 23.1%;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.titlebar > .window-controls-container > .window-icon-bg:hover {
|
||||
.monaco-workbench .part.titlebar > .window-controls-container > .window-icon-bg:hover {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.titlebar.light > .window-controls-container > .window-icon-bg:hover {
|
||||
.monaco-workbench .part.titlebar.light > .window-controls-container > .window-icon-bg:hover {
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.titlebar > .window-controls-container > .window-icon-bg.window-close-bg:hover {
|
||||
.monaco-workbench .part.titlebar > .window-controls-container > .window-icon-bg.window-close-bg:hover {
|
||||
background-color: rgba(232, 17, 35, 0.9);
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.titlebar > .window-controls-container .window-icon.window-close:hover {
|
||||
.monaco-workbench .part.titlebar > .window-controls-container .window-icon.window-close:hover {
|
||||
background-color: white;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as nls from 'vs/nls';
|
||||
import { IMenubarMenu, IMenubarMenuItemAction, IMenubarMenuItemSubmenu, IMenubarKeybinding, IMenubarService, IMenubarData } from 'vs/platform/menubar/common/menubar';
|
||||
import { IMenubarMenu, IMenubarMenuItemAction, IMenubarMenuItemSubmenu, IMenubarKeybinding, IMenubarService, IMenubarData, MenubarMenuItem } from 'vs/platform/menubar/common/menubar';
|
||||
import { IMenuService, MenuId, IMenu, SubmenuItemAction } from 'vs/platform/actions/common/actions';
|
||||
import { registerThemingParticipant, ITheme, ICssStyleCollector, IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { IWindowService, MenuBarVisibility, IWindowsService, getTitleBarStyle } from 'vs/platform/windows/common/windows';
|
||||
@@ -31,6 +31,7 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment'
|
||||
import { MenuBar } from 'vs/base/browser/ui/menu/menubar';
|
||||
import { SubmenuAction } from 'vs/base/browser/ui/menu/menu';
|
||||
import { attachMenuStyler } from 'vs/platform/theme/common/styler';
|
||||
import { assign } from 'vs/base/common/objects';
|
||||
|
||||
export class MenubarControl extends Disposable {
|
||||
|
||||
@@ -45,27 +46,29 @@ export class MenubarControl extends Disposable {
|
||||
'window.nativeTabs'
|
||||
];
|
||||
|
||||
// {{SQL CARBON EDIT}} - Disable unusued menus
|
||||
private topLevelMenus: {
|
||||
'File': IMenu;
|
||||
'Edit': IMenu;
|
||||
'Selection': IMenu;
|
||||
// 'Selection': IMenu;
|
||||
'View': IMenu;
|
||||
'Go': IMenu;
|
||||
'Debug': IMenu;
|
||||
'Terminal': IMenu;
|
||||
// 'Go': IMenu;
|
||||
// 'Debug': IMenu;
|
||||
// 'Terminal': IMenu;
|
||||
'Window'?: IMenu;
|
||||
'Help': IMenu;
|
||||
[index: string]: IMenu;
|
||||
// [index: string]: IMenu;
|
||||
};
|
||||
|
||||
// {{SQL CARBON EDIT}} - Disable unused menus
|
||||
private topLevelTitles = {
|
||||
'File': nls.localize({ key: 'mFile', comment: ['&& denotes a mnemonic'] }, "&&File"),
|
||||
'Edit': nls.localize({ key: 'mEdit', comment: ['&& denotes a mnemonic'] }, "&&Edit"),
|
||||
'Selection': nls.localize({ key: 'mSelection', comment: ['&& denotes a mnemonic'] }, "&&Selection"),
|
||||
// 'Selection': nls.localize({ key: 'mSelection', comment: ['&& denotes a mnemonic'] }, "&&Selection"),
|
||||
'View': nls.localize({ key: 'mView', comment: ['&& denotes a mnemonic'] }, "&&View"),
|
||||
'Go': nls.localize({ key: 'mGoto', comment: ['&& denotes a mnemonic'] }, "&&Go"),
|
||||
'Debug': nls.localize({ key: 'mDebug', comment: ['&& denotes a mnemonic'] }, "&&Debug"),
|
||||
'Terminal': nls.localize({ key: 'mTerminal', comment: ['&& denotes a mnemonic'] }, "&&Terminal"),
|
||||
// 'Go': nls.localize({ key: 'mGoto', comment: ['&& denotes a mnemonic'] }, "&&Go"),
|
||||
// 'Debug': nls.localize({ key: 'mDebug', comment: ['&& denotes a mnemonic'] }, "&&Debug"),
|
||||
// 'Terminal': nls.localize({ key: 'mTerminal', comment: ['&& denotes a mnemonic'] }, "&&Terminal"),
|
||||
'Help': nls.localize({ key: 'mHelp', comment: ['&& denotes a mnemonic'] }, "&&Help")
|
||||
};
|
||||
|
||||
@@ -80,32 +83,33 @@ export class MenubarControl extends Disposable {
|
||||
private static MAX_MENU_RECENT_ENTRIES = 10;
|
||||
|
||||
constructor(
|
||||
@IThemeService private themeService: IThemeService,
|
||||
@IMenubarService private menubarService: IMenubarService,
|
||||
@IMenuService private menuService: IMenuService,
|
||||
@IWindowService private windowService: IWindowService,
|
||||
@IWindowsService private windowsService: IWindowsService,
|
||||
@IContextKeyService private contextKeyService: IContextKeyService,
|
||||
@IKeybindingService private keybindingService: IKeybindingService,
|
||||
@IConfigurationService private configurationService: IConfigurationService,
|
||||
@ILabelService private labelService: ILabelService,
|
||||
@IUpdateService private updateService: IUpdateService,
|
||||
@IStorageService private storageService: IStorageService,
|
||||
@INotificationService private notificationService: INotificationService,
|
||||
@IPreferencesService private preferencesService: IPreferencesService,
|
||||
@IEnvironmentService private environmentService: IEnvironmentService
|
||||
@IThemeService private readonly themeService: IThemeService,
|
||||
@IMenubarService private readonly menubarService: IMenubarService,
|
||||
@IMenuService private readonly menuService: IMenuService,
|
||||
@IWindowService private readonly windowService: IWindowService,
|
||||
@IWindowsService private readonly windowsService: IWindowsService,
|
||||
@IContextKeyService private readonly contextKeyService: IContextKeyService,
|
||||
@IKeybindingService private readonly keybindingService: IKeybindingService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@ILabelService private readonly labelService: ILabelService,
|
||||
@IUpdateService private readonly updateService: IUpdateService,
|
||||
@IStorageService private readonly storageService: IStorageService,
|
||||
@INotificationService private readonly notificationService: INotificationService,
|
||||
@IPreferencesService private readonly preferencesService: IPreferencesService,
|
||||
@IEnvironmentService private readonly environmentService: IEnvironmentService
|
||||
) {
|
||||
|
||||
super();
|
||||
|
||||
// {{SQL CARBON EDIT}} - Disable unused menus
|
||||
this.topLevelMenus = {
|
||||
'File': this._register(this.menuService.createMenu(MenuId.MenubarFileMenu, this.contextKeyService)),
|
||||
'Edit': this._register(this.menuService.createMenu(MenuId.MenubarEditMenu, this.contextKeyService)),
|
||||
'Selection': this._register(this.menuService.createMenu(MenuId.MenubarSelectionMenu, this.contextKeyService)),
|
||||
// 'Selection': this._register(this.menuService.createMenu(MenuId.MenubarSelectionMenu, this.contextKeyService)),
|
||||
'View': this._register(this.menuService.createMenu(MenuId.MenubarViewMenu, this.contextKeyService)),
|
||||
'Go': this._register(this.menuService.createMenu(MenuId.MenubarGoMenu, this.contextKeyService)),
|
||||
'Debug': this._register(this.menuService.createMenu(MenuId.MenubarDebugMenu, this.contextKeyService)),
|
||||
'Terminal': this._register(this.menuService.createMenu(MenuId.MenubarTerminalMenu, this.contextKeyService)),
|
||||
// 'Go': this._register(this.menuService.createMenu(MenuId.MenubarGoMenu, this.contextKeyService)),
|
||||
// 'Debug': this._register(this.menuService.createMenu(MenuId.MenubarDebugMenu, this.contextKeyService)),
|
||||
// 'Terminal': this._register(this.menuService.createMenu(MenuId.MenubarTerminalMenu, this.contextKeyService)),
|
||||
'Help': this._register(this.menuService.createMenu(MenuId.MenubarHelpMenu, this.contextKeyService))
|
||||
};
|
||||
|
||||
@@ -263,6 +267,9 @@ export class MenubarControl extends Disposable {
|
||||
this.menubar.blur();
|
||||
}));
|
||||
}
|
||||
|
||||
// Update recent menu items on formatter registration
|
||||
this._register(this.labelService.onDidChangeFormatters(() => { this.onRecentlyOpenedChange(); }));
|
||||
}
|
||||
|
||||
private doUpdateMenubar(firstTime: boolean): void {
|
||||
@@ -315,7 +322,7 @@ export class MenubarControl extends Disposable {
|
||||
return label;
|
||||
}
|
||||
|
||||
private createOpenRecentMenuAction(workspace: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | URI, commandId: string, isFile: boolean): IAction {
|
||||
private createOpenRecentMenuAction(workspace: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | URI, commandId: string, isFile: boolean): IAction & { uri: URI } {
|
||||
|
||||
let label: string;
|
||||
let uri: URI;
|
||||
@@ -331,7 +338,7 @@ export class MenubarControl extends Disposable {
|
||||
label = this.labelService.getUriLabel(uri);
|
||||
}
|
||||
|
||||
return new Action(commandId, label, undefined, undefined, (event) => {
|
||||
const ret: IAction = new Action(commandId, label, undefined, undefined, (event) => {
|
||||
const openInNewWindow = event && ((!isMacintosh && (event.ctrlKey || event.shiftKey)) || (isMacintosh && (event.metaKey || event.altKey)));
|
||||
|
||||
return this.windowService.openWindow([uri], {
|
||||
@@ -339,8 +346,11 @@ export class MenubarControl extends Disposable {
|
||||
forceOpenWorkspaceAsFile: isFile
|
||||
});
|
||||
});
|
||||
|
||||
return assign(ret, { uri: uri });
|
||||
}
|
||||
|
||||
/* Custom Menu takes actions */
|
||||
private getOpenRecentActions(): IAction[] {
|
||||
if (!this.recentlyOpened) {
|
||||
return [];
|
||||
@@ -369,6 +379,19 @@ export class MenubarControl extends Disposable {
|
||||
return result;
|
||||
}
|
||||
|
||||
private transformOpenRecentAction(action: Separator | (IAction & { uri: URI })): MenubarMenuItem {
|
||||
if (action instanceof Separator) {
|
||||
return { id: 'vscode.menubar.separator' };
|
||||
}
|
||||
|
||||
return {
|
||||
id: action.id,
|
||||
uri: action.uri,
|
||||
enabled: action.enabled,
|
||||
label: action.label
|
||||
};
|
||||
}
|
||||
|
||||
private getUpdateAction(): IAction | null {
|
||||
const state = this.updateService.state;
|
||||
|
||||
@@ -501,13 +524,13 @@ export class MenubarControl extends Disposable {
|
||||
// first try to resolve a native accelerator
|
||||
const electronAccelerator = binding.getElectronAccelerator();
|
||||
if (electronAccelerator) {
|
||||
return { label: electronAccelerator };
|
||||
return { label: electronAccelerator, userSettingsLabel: binding.getUserSettingsLabel() };
|
||||
}
|
||||
|
||||
// we need this fallback to support keybindings that cannot show in electron menus (e.g. chords)
|
||||
const acceleratorLabel = binding.getLabel();
|
||||
if (acceleratorLabel) {
|
||||
return { label: acceleratorLabel, isNative: false };
|
||||
return { label: acceleratorLabel, isNative: false, userSettingsLabel: binding.getUserSettingsLabel() };
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -534,6 +557,11 @@ export class MenubarControl extends Disposable {
|
||||
menuToPopulate.items.push(menubarSubmenuItem);
|
||||
menuToDispose.dispose();
|
||||
} else {
|
||||
if (menuItem.id === 'workbench.action.openRecent') {
|
||||
const actions = this.getOpenRecentActions().map(this.transformOpenRecentAction);
|
||||
menuToPopulate.items.push(...actions);
|
||||
}
|
||||
|
||||
let menubarMenuItem: IMenubarMenuItemAction = {
|
||||
id: menuItem.id,
|
||||
label: menuItem.label
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
import 'vs/css!./media/titlebarpart';
|
||||
import * as paths from 'vs/base/common/paths';
|
||||
import * as resources from 'vs/base/common/resources';
|
||||
import { Part } from 'vs/workbench/browser/part';
|
||||
import { ITitleService, ITitleProperties } from 'vs/workbench/services/title/common/titleService';
|
||||
import { getZoomFactor } from 'vs/base/browser/browser';
|
||||
@@ -25,15 +26,17 @@ import { isMacintosh, isWindows, isLinux } from 'vs/base/common/platform';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { trim } from 'vs/base/common/strings';
|
||||
import { EventType, EventHelper, Dimension, isAncestor, hide, show, removeClass, addClass, append, $, addDisposableListener } from 'vs/base/browser/dom';
|
||||
import { EventType, EventHelper, Dimension, isAncestor, hide, show, removeClass, addClass, append, $, addDisposableListener, runAtThisOrScheduleAtNextAnimationFrame } from 'vs/base/browser/dom';
|
||||
import { MenubarControl } from 'vs/workbench/browser/parts/titlebar/menubarControl';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { template, getBaseLabel } from 'vs/base/common/labels';
|
||||
import { ILabelService } from 'vs/platform/label/common/label';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { ISerializableView } from 'vs/base/browser/ui/grid/grid';
|
||||
import { Parts } from 'vs/workbench/services/part/common/partService';
|
||||
|
||||
export class TitlebarPart extends Part implements ITitleService {
|
||||
export class TitlebarPart extends Part implements ITitleService, ISerializableView {
|
||||
|
||||
_serviceBrand: any;
|
||||
|
||||
@@ -43,7 +46,7 @@ export class TitlebarPart extends Part implements ITitleService {
|
||||
private static readonly TITLE_DIRTY = '\u25cf ';
|
||||
private static readonly TITLE_SEPARATOR = isMacintosh ? ' — ' : ' - '; // macOS uses special - separator
|
||||
|
||||
private titleContainer: HTMLElement;
|
||||
element: HTMLElement;
|
||||
private title: HTMLElement;
|
||||
private dragRegion: HTMLElement;
|
||||
private windowControls: HTMLElement;
|
||||
@@ -61,18 +64,26 @@ export class TitlebarPart extends Part implements ITitleService {
|
||||
private properties: ITitleProperties;
|
||||
private activeEditorListeners: IDisposable[];
|
||||
|
||||
minimumWidth: number = 0;
|
||||
maximumWidth: number = Number.POSITIVE_INFINITY;
|
||||
get minimumHeight(): number { return isMacintosh ? 22 / getZoomFactor() : (30 / (this.configurationService.getValue<MenuBarVisibility>('window.menuBarVisibility') === 'hidden' ? getZoomFactor() : 1)); }
|
||||
get maximumHeight(): number { return isMacintosh ? 22 / getZoomFactor() : (30 / (this.configurationService.getValue<MenuBarVisibility>('window.menuBarVisibility') === 'hidden' ? getZoomFactor() : 1)); }
|
||||
|
||||
private _onDidChange = new Emitter<{ width: number; height: number; }>();
|
||||
readonly onDidChange = this._onDidChange.event;
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
@IContextMenuService private contextMenuService: IContextMenuService,
|
||||
@IWindowService private windowService: IWindowService,
|
||||
@IConfigurationService private configurationService: IConfigurationService,
|
||||
@IWindowsService private windowsService: IWindowsService,
|
||||
@IEditorService private editorService: IEditorService,
|
||||
@IEnvironmentService private environmentService: IEnvironmentService,
|
||||
@IWorkspaceContextService private contextService: IWorkspaceContextService,
|
||||
@IInstantiationService private instantiationService: IInstantiationService,
|
||||
@IContextMenuService private readonly contextMenuService: IContextMenuService,
|
||||
@IWindowService private readonly windowService: IWindowService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@IWindowsService private readonly windowsService: IWindowsService,
|
||||
@IEditorService private readonly editorService: IEditorService,
|
||||
@IEnvironmentService private readonly environmentService: IEnvironmentService,
|
||||
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@ILabelService private labelService: ILabelService,
|
||||
@ILabelService private readonly labelService: ILabelService,
|
||||
@IStorageService storageService: IStorageService
|
||||
) {
|
||||
super(id, { hasTitle: false }, themeService, storageService);
|
||||
@@ -90,7 +101,7 @@ export class TitlebarPart extends Part implements ITitleService {
|
||||
this._register(this.contextService.onDidChangeWorkspaceFolders(() => this.doUpdateTitle()));
|
||||
this._register(this.contextService.onDidChangeWorkbenchState(() => this.doUpdateTitle()));
|
||||
this._register(this.contextService.onDidChangeWorkspaceName(() => this.doUpdateTitle()));
|
||||
this._register(this.labelService.onDidRegisterFormatter(() => this.doUpdateTitle()));
|
||||
this._register(this.labelService.onDidChangeFormatters(() => this.doUpdateTitle()));
|
||||
}
|
||||
|
||||
private onBlur(): void {
|
||||
@@ -107,6 +118,12 @@ export class TitlebarPart extends Part implements ITitleService {
|
||||
if (event.affectsConfiguration('window.title')) {
|
||||
this.doUpdateTitle();
|
||||
}
|
||||
|
||||
if (event.affectsConfiguration('window.doubleClickIconToClose')) {
|
||||
if (this.appIcon) {
|
||||
this.onUpdateAppIconDragBehavior();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private onMenubarVisibilityChanged(visible: boolean) {
|
||||
@@ -184,7 +201,7 @@ export class TitlebarPart extends Part implements ITitleService {
|
||||
this.pendingTitle = title;
|
||||
}
|
||||
|
||||
if (isWindows || isLinux) {
|
||||
if ((isWindows || isLinux) && this.title) {
|
||||
this.adjustTitleMarginToCenter();
|
||||
}
|
||||
}
|
||||
@@ -222,21 +239,25 @@ export class TitlebarPart extends Part implements ITitleService {
|
||||
/**
|
||||
* Possible template values:
|
||||
*
|
||||
* {activeEditorLong}: e.g. /Users/Development/myProject/myFolder/myFile.txt
|
||||
* {activeEditorMedium}: e.g. myFolder/myFile.txt
|
||||
* {activeEditorLong}: e.g. /Users/Development/myFolder/myFileFolder/myFile.txt
|
||||
* {activeEditorMedium}: e.g. myFolder/myFileFolder/myFile.txt
|
||||
* {activeEditorShort}: e.g. myFile.txt
|
||||
* {activeFolderLong}: e.g. /Users/Development/myFolder/myFileFolder
|
||||
* {activeFolderMedium}: e.g. myFolder/myFileFolder
|
||||
* {activeFolderShort}: e.g. myFileFolder
|
||||
* {rootName}: e.g. myFolder1, myFolder2, myFolder3
|
||||
* {rootPath}: e.g. /Users/Development/myProject
|
||||
* {rootPath}: e.g. /Users/Development
|
||||
* {folderName}: e.g. myFolder
|
||||
* {folderPath}: e.g. /Users/Development/myFolder
|
||||
* {appName}: e.g. VS Code
|
||||
* {dirty}: indiactor
|
||||
* {dirty}: indicator
|
||||
* {separator}: conditional separator
|
||||
*/
|
||||
private doGetWindowTitle(): string {
|
||||
const editor = this.editorService.activeEditor;
|
||||
const workspace = this.contextService.getWorkspace();
|
||||
|
||||
// Compute root
|
||||
let root: URI;
|
||||
if (workspace.configuration) {
|
||||
root = workspace.configuration;
|
||||
@@ -244,15 +265,25 @@ export class TitlebarPart extends Part implements ITitleService {
|
||||
root = workspace.folders[0].uri;
|
||||
}
|
||||
|
||||
// Compute active editor folder
|
||||
const editorResource = editor ? toResource(editor) : undefined;
|
||||
let editorFolderResource = editorResource ? resources.dirname(editorResource) : undefined;
|
||||
if (editorFolderResource && editorFolderResource.path === '.') {
|
||||
editorFolderResource = undefined;
|
||||
}
|
||||
|
||||
// Compute folder resource
|
||||
// Single Root Workspace: always the root single workspace in this case
|
||||
// Otherwise: root folder of the currently active file if any
|
||||
let folder = this.contextService.getWorkbenchState() === WorkbenchState.FOLDER ? workspace.folders[0] : this.contextService.getWorkspaceFolder(toResource(editor, { supportSideBySide: true }));
|
||||
const folder = this.contextService.getWorkbenchState() === WorkbenchState.FOLDER ? workspace.folders[0] : this.contextService.getWorkspaceFolder(toResource(editor, { supportSideBySide: true }));
|
||||
|
||||
// Variables
|
||||
const activeEditorShort = editor ? editor.getTitle(Verbosity.SHORT) : '';
|
||||
const activeEditorMedium = editor ? editor.getTitle(Verbosity.MEDIUM) : activeEditorShort;
|
||||
const activeEditorLong = editor ? editor.getTitle(Verbosity.LONG) : activeEditorMedium;
|
||||
const activeFolderShort = editorFolderResource ? resources.basename(editorFolderResource) : '';
|
||||
const activeFolderMedium = editorFolderResource ? this.labelService.getUriLabel(editorFolderResource, { relative: true }) : '';
|
||||
const activeFolderLong = editorFolderResource ? this.labelService.getUriLabel(editorFolderResource) : '';
|
||||
const rootName = this.labelService.getWorkspaceLabel(workspace);
|
||||
const rootPath = root ? this.labelService.getUriLabel(root) : '';
|
||||
const folderName = folder ? folder.name : '';
|
||||
@@ -266,6 +297,9 @@ export class TitlebarPart extends Part implements ITitleService {
|
||||
activeEditorShort,
|
||||
activeEditorLong,
|
||||
activeEditorMedium,
|
||||
activeFolderShort,
|
||||
activeFolderMedium,
|
||||
activeFolderLong,
|
||||
rootName,
|
||||
rootPath,
|
||||
folderName,
|
||||
@@ -277,19 +311,24 @@ export class TitlebarPart extends Part implements ITitleService {
|
||||
}
|
||||
|
||||
createContentArea(parent: HTMLElement): HTMLElement {
|
||||
this.titleContainer = parent;
|
||||
this.element = parent;
|
||||
|
||||
// Draggable region that we can manipulate for #52522
|
||||
this.dragRegion = append(this.titleContainer, $('div.titlebar-drag-region'));
|
||||
this.dragRegion = append(this.element, $('div.titlebar-drag-region'));
|
||||
|
||||
// App Icon (Windows/Linux)
|
||||
if (!isMacintosh) {
|
||||
this.appIcon = append(this.titleContainer, $('div.window-appicon'));
|
||||
this.appIcon = append(this.element, $('div.window-appicon'));
|
||||
this.onUpdateAppIconDragBehavior();
|
||||
|
||||
this._register(addDisposableListener(this.appIcon, EventType.DBLCLICK, (e => {
|
||||
this.windowService.closeWindow();
|
||||
})));
|
||||
}
|
||||
|
||||
// Menubar: the menubar part which is responsible for populating both the custom and native menubars
|
||||
this.menubarPart = this.instantiationService.createInstance(MenubarControl);
|
||||
this.menubar = append(this.titleContainer, $('div.menubar'));
|
||||
this.menubar = append(this.element, $('div.menubar'));
|
||||
this.menubar.setAttribute('role', 'menubar');
|
||||
|
||||
this.menubarPart.create(this.menubar);
|
||||
@@ -300,7 +339,7 @@ export class TitlebarPart extends Part implements ITitleService {
|
||||
}
|
||||
|
||||
// Title
|
||||
this.title = append(this.titleContainer, $('div.window-title'));
|
||||
this.title = append(this.element, $('div.window-title'));
|
||||
if (this.pendingTitle) {
|
||||
this.title.innerText = this.pendingTitle;
|
||||
} else {
|
||||
@@ -309,7 +348,7 @@ export class TitlebarPart extends Part implements ITitleService {
|
||||
|
||||
// Maximize/Restore on doubleclick
|
||||
if (isMacintosh) {
|
||||
this._register(addDisposableListener(this.titleContainer, EventType.DBLCLICK, e => {
|
||||
this._register(addDisposableListener(this.element, EventType.DBLCLICK, e => {
|
||||
EventHelper.stop(e);
|
||||
|
||||
this.onTitleDoubleclick();
|
||||
@@ -329,7 +368,7 @@ export class TitlebarPart extends Part implements ITitleService {
|
||||
|
||||
// Window Controls (Windows/Linux)
|
||||
if (!isMacintosh) {
|
||||
this.windowControls = append(this.titleContainer, $('div.window-controls-container'));
|
||||
this.windowControls = append(this.element, $('div.window-controls-container'));
|
||||
|
||||
|
||||
// Minimize
|
||||
@@ -364,7 +403,7 @@ export class TitlebarPart extends Part implements ITitleService {
|
||||
}));
|
||||
|
||||
// Resizer
|
||||
this.resizer = append(this.titleContainer, $('div.resizer'));
|
||||
this.resizer = append(this.element, $('div.resizer'));
|
||||
|
||||
const isMaximized = this.windowService.getConfiguration().maximized ? true : false;
|
||||
this.onDidChangeMaximized(isMaximized);
|
||||
@@ -373,7 +412,7 @@ export class TitlebarPart extends Part implements ITitleService {
|
||||
|
||||
// Since the title area is used to drag the window, we do not want to steal focus from the
|
||||
// currently active element. So we restore focus after a timeout back to where it was.
|
||||
this._register(addDisposableListener(this.titleContainer, EventType.MOUSE_DOWN, e => {
|
||||
this._register(addDisposableListener(this.element, EventType.MOUSE_DOWN, e => {
|
||||
if (e.target && isAncestor(e.target as HTMLElement, this.menubar)) {
|
||||
return;
|
||||
}
|
||||
@@ -388,7 +427,7 @@ export class TitlebarPart extends Part implements ITitleService {
|
||||
|
||||
this.updateStyles();
|
||||
|
||||
return this.titleContainer;
|
||||
return this.element;
|
||||
}
|
||||
|
||||
private onDidChangeMaximized(maximized: boolean) {
|
||||
@@ -417,26 +456,26 @@ export class TitlebarPart extends Part implements ITitleService {
|
||||
super.updateStyles();
|
||||
|
||||
// Part container
|
||||
if (this.titleContainer) {
|
||||
if (this.element) {
|
||||
if (this.isInactive) {
|
||||
addClass(this.titleContainer, 'inactive');
|
||||
addClass(this.element, 'inactive');
|
||||
} else {
|
||||
removeClass(this.titleContainer, 'inactive');
|
||||
removeClass(this.element, 'inactive');
|
||||
}
|
||||
|
||||
const titleBackground = this.getColor(this.isInactive ? TITLE_BAR_INACTIVE_BACKGROUND : TITLE_BAR_ACTIVE_BACKGROUND);
|
||||
this.titleContainer.style.backgroundColor = titleBackground;
|
||||
this.element.style.backgroundColor = titleBackground;
|
||||
if (Color.fromHex(titleBackground).isLighter()) {
|
||||
addClass(this.titleContainer, 'light');
|
||||
addClass(this.element, 'light');
|
||||
} else {
|
||||
removeClass(this.titleContainer, 'light');
|
||||
removeClass(this.element, 'light');
|
||||
}
|
||||
|
||||
const titleForeground = this.getColor(this.isInactive ? TITLE_BAR_INACTIVE_FOREGROUND : TITLE_BAR_ACTIVE_FOREGROUND);
|
||||
this.titleContainer.style.color = titleForeground;
|
||||
this.element.style.color = titleForeground;
|
||||
|
||||
const titleBorder = this.getColor(TITLE_BAR_BORDER);
|
||||
this.titleContainer.style.borderBottom = titleBorder ? `1px solid ${titleBorder}` : null;
|
||||
this.element.style.borderBottom = titleBorder ? `1px solid ${titleBorder}` : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -444,6 +483,16 @@ export class TitlebarPart extends Part implements ITitleService {
|
||||
this.windowService.onWindowTitleDoubleClick();
|
||||
}
|
||||
|
||||
private onUpdateAppIconDragBehavior() {
|
||||
const setting = this.configurationService.getValue('window.doubleClickIconToClose');
|
||||
if (setting) {
|
||||
this.appIcon.style['-webkit-app-region'] = 'no-drag';
|
||||
}
|
||||
else {
|
||||
this.appIcon.style['-webkit-app-region'] = 'drag';
|
||||
}
|
||||
}
|
||||
|
||||
private onContextMenu(e: MouseEvent): void {
|
||||
|
||||
// Find target anchor
|
||||
@@ -491,30 +540,27 @@ export class TitlebarPart extends Part implements ITitleService {
|
||||
}
|
||||
|
||||
private adjustTitleMarginToCenter(): void {
|
||||
setTimeout(() => {
|
||||
// Cannot center
|
||||
if (!isMacintosh &&
|
||||
(this.appIcon.clientWidth + this.menubar.clientWidth + 10 > (this.titleContainer.clientWidth - this.title.clientWidth) / 2 ||
|
||||
this.titleContainer.clientWidth - this.windowControls.clientWidth - 10 < (this.titleContainer.clientWidth + this.title.clientWidth) / 2)) {
|
||||
this.title.style.position = null;
|
||||
this.title.style.left = null;
|
||||
this.title.style.transform = null;
|
||||
} else {
|
||||
this.title.style.position = 'absolute';
|
||||
this.title.style.left = '50%';
|
||||
this.title.style.transform = 'translate(-50%, 0)';
|
||||
}
|
||||
}, 0); // delay so that we can get accurate information about widths
|
||||
if (!isMacintosh &&
|
||||
(this.appIcon.clientWidth + this.menubar.clientWidth + 10 > (this.element.clientWidth - this.title.clientWidth) / 2 ||
|
||||
this.element.clientWidth - this.windowControls.clientWidth - 10 < (this.element.clientWidth + this.title.clientWidth) / 2)) {
|
||||
this.title.style.position = null;
|
||||
this.title.style.left = null;
|
||||
this.title.style.transform = null;
|
||||
} else {
|
||||
this.title.style.position = 'absolute';
|
||||
this.title.style.left = '50%';
|
||||
this.title.style.transform = 'translate(-50%, 0)';
|
||||
}
|
||||
}
|
||||
|
||||
layout(dimension: Dimension): Dimension[] {
|
||||
updateLayout(dimension: Dimension): void {
|
||||
if (getTitleBarStyle(this.configurationService, this.environmentService) === 'custom') {
|
||||
// Only prevent zooming behavior on macOS or when the menubar is not visible
|
||||
if (isMacintosh || this.configurationService.getValue<MenuBarVisibility>('window.menuBarVisibility') === 'hidden') {
|
||||
this.title.style.zoom = `${1.0 / getZoomFactor()}`;
|
||||
this.title.style.zoom = `${1 / getZoomFactor()}`;
|
||||
if (isWindows || isLinux) {
|
||||
this.appIcon.style.zoom = `${1.0 / getZoomFactor()}`;
|
||||
this.windowControls.style.zoom = `${1.0 / getZoomFactor()}`;
|
||||
this.appIcon.style.zoom = `${1 / getZoomFactor()}`;
|
||||
this.windowControls.style.zoom = `${1 / getZoomFactor()}`;
|
||||
}
|
||||
} else {
|
||||
this.title.style.zoom = null;
|
||||
@@ -524,15 +570,34 @@ export class TitlebarPart extends Part implements ITitleService {
|
||||
}
|
||||
}
|
||||
|
||||
this.adjustTitleMarginToCenter();
|
||||
runAtThisOrScheduleAtNextAnimationFrame(() => this.adjustTitleMarginToCenter());
|
||||
|
||||
if (this.menubarPart) {
|
||||
const menubarDimension = new Dimension(undefined, dimension.height);
|
||||
this.menubarPart.layout(menubarDimension);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return super.layout(dimension);
|
||||
layout(dimension: Dimension): Dimension[];
|
||||
layout(width: number, height: number): void;
|
||||
layout(dim1: Dimension | number, dim2?: number): Dimension[] | void {
|
||||
if (dim1 instanceof Dimension) {
|
||||
this.updateLayout(dim1);
|
||||
|
||||
return super.layout(dim1);
|
||||
}
|
||||
|
||||
const dimensions = new Dimension(dim1, dim2);
|
||||
this.updateLayout(dimensions);
|
||||
|
||||
super.layout(dimensions);
|
||||
}
|
||||
|
||||
toJSON(): object {
|
||||
return {
|
||||
type: Parts.TITLEBAR_PART
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -542,7 +607,7 @@ class ShowItemInFolderAction extends Action {
|
||||
super('showItemInFolder.action.id', label);
|
||||
}
|
||||
|
||||
run(): Thenable<void> {
|
||||
run(): Promise<void> {
|
||||
return this.windowsService.showItemInFolder(this.path);
|
||||
}
|
||||
}
|
||||
@@ -551,7 +616,7 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
|
||||
const titlebarActiveFg = theme.getColor(TITLE_BAR_ACTIVE_FOREGROUND);
|
||||
if (titlebarActiveFg) {
|
||||
collector.addRule(`
|
||||
.monaco-workbench > .part.titlebar > .window-controls-container .window-icon {
|
||||
.monaco-workbench .part.titlebar > .window-controls-container .window-icon {
|
||||
background-color: ${titlebarActiveFg};
|
||||
}
|
||||
`);
|
||||
@@ -560,7 +625,7 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
|
||||
const titlebarInactiveFg = theme.getColor(TITLE_BAR_INACTIVE_FOREGROUND);
|
||||
if (titlebarInactiveFg) {
|
||||
collector.addRule(`
|
||||
.monaco-workbench > .part.titlebar.inactive > .window-controls-container .window-icon {
|
||||
.monaco-workbench .part.titlebar.inactive > .window-controls-container .window-icon {
|
||||
background-color: ${titlebarInactiveFg};
|
||||
}
|
||||
`);
|
||||
|
||||
@@ -13,7 +13,7 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView
|
||||
import { IMenuService, MenuId, MenuItemAction } from 'vs/platform/actions/common/actions';
|
||||
import { ContextAwareMenuItemActionItem, fillInActionBarActions, fillInContextMenuActions } from 'vs/platform/actions/browser/menuItemActionItem';
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IViewsService, ITreeView, ITreeItem, TreeItemCollapsibleState, ITreeViewDataProvider, TreeViewItemHandleArg, ICustomViewDescriptor, ViewsRegistry, ViewContainer, ITreeItemLabel } from 'vs/workbench/common/views';
|
||||
import { IViewsService, ITreeView, ITreeItem, TreeItemCollapsibleState, ITreeViewDataProvider, TreeViewItemHandleArg, ITreeViewDescriptor, ViewsRegistry, ViewContainer, ITreeItemLabel } from 'vs/workbench/common/views';
|
||||
import { IViewletViewOptions, FileIconThemableWorkbenchTree } from 'vs/workbench/browser/parts/views/viewsViewlet';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
@@ -23,7 +23,7 @@ import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/work
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import { IDataSource, ITree, IRenderer, ContextMenuEvent } from 'vs/base/parts/tree/browser/tree';
|
||||
import { ResourceLabel } from 'vs/workbench/browser/labels';
|
||||
import { ResourceLabels, IResourceLabel } from 'vs/workbench/browser/labels';
|
||||
import { ActionBar, IActionItemProvider, ActionItem } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { basename } from 'vs/base/common/paths';
|
||||
@@ -51,22 +51,18 @@ export class CustomTreeViewPanel extends ViewletPanel {
|
||||
|
||||
constructor(
|
||||
options: IViewletViewOptions,
|
||||
@INotificationService private notificationService: INotificationService,
|
||||
@INotificationService private readonly notificationService: INotificationService,
|
||||
@IKeybindingService keybindingService: IKeybindingService,
|
||||
@IContextMenuService contextMenuService: IContextMenuService,
|
||||
@IConfigurationService configurationService: IConfigurationService,
|
||||
@IViewsService viewsService: IViewsService,
|
||||
) {
|
||||
super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: options.title }, keybindingService, contextMenuService, configurationService);
|
||||
const { treeView } = (<ICustomViewDescriptor>ViewsRegistry.getView(options.id));
|
||||
const { treeView } = (<ITreeViewDescriptor>ViewsRegistry.getView(options.id));
|
||||
this.treeView = treeView;
|
||||
this.treeView.onDidChangeActions(() => this.updateActions(), this, this.disposables);
|
||||
this.disposables.push(toDisposable(() => this.treeView.setVisibility(false)));
|
||||
this.updateTreeVisibility();
|
||||
}
|
||||
|
||||
setVisible(visible: boolean): void {
|
||||
super.setVisible(visible);
|
||||
this.disposables.push(this.onDidChangeBodyVisibility(() => this.updateTreeVisibility()));
|
||||
this.updateTreeVisibility();
|
||||
}
|
||||
|
||||
@@ -79,11 +75,6 @@ export class CustomTreeViewPanel extends ViewletPanel {
|
||||
this.treeView.show(container);
|
||||
}
|
||||
|
||||
setExpanded(expanded: boolean): void {
|
||||
this.treeView.setVisibility(this.isVisible() && expanded);
|
||||
super.setExpanded(expanded);
|
||||
}
|
||||
|
||||
layoutBody(size: number): void {
|
||||
this.treeView.layout(size);
|
||||
}
|
||||
@@ -105,7 +96,7 @@ export class CustomTreeViewPanel extends ViewletPanel {
|
||||
}
|
||||
|
||||
private updateTreeVisibility(): void {
|
||||
this.treeView.setVisibility(this.isVisible() && this.isExpanded());
|
||||
this.treeView.setVisibility(this.isBodyVisible());
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
@@ -126,8 +117,8 @@ class TitleMenus implements IDisposable {
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
@IContextKeyService private contextKeyService: IContextKeyService,
|
||||
@IMenuService private menuService: IMenuService,
|
||||
@IContextKeyService private readonly contextKeyService: IContextKeyService,
|
||||
@IMenuService private readonly menuService: IMenuService,
|
||||
) {
|
||||
if (this.titleDisposable) {
|
||||
this.titleDisposable.dispose();
|
||||
@@ -175,7 +166,7 @@ class Root implements ITreeItem {
|
||||
handle = '0';
|
||||
parentHandle = null;
|
||||
collapsibleState = TreeItemCollapsibleState.Expanded;
|
||||
children = void 0;
|
||||
children = undefined;
|
||||
}
|
||||
|
||||
const noDataProviderMessage = localize('no-dataprovider', "There is no data provider registered that can provide view data.");
|
||||
@@ -194,6 +185,7 @@ export class CustomTreeView extends Disposable implements ITreeView {
|
||||
private _messageValue: string | IMarkdownString | undefined;
|
||||
private messageElement: HTMLDivElement;
|
||||
private tree: FileIconThemableWorkbenchTree;
|
||||
private treeLabels: ResourceLabels;
|
||||
private root: ITreeItem;
|
||||
private elementsToRefresh: ITreeItem[] = [];
|
||||
private menus: TitleMenus;
|
||||
@@ -218,13 +210,13 @@ export class CustomTreeView extends Disposable implements ITreeView {
|
||||
|
||||
constructor(
|
||||
private id: string,
|
||||
private container: ViewContainer,
|
||||
@IExtensionService private extensionService: IExtensionService,
|
||||
@IWorkbenchThemeService private themeService: IWorkbenchThemeService,
|
||||
@IInstantiationService private instantiationService: IInstantiationService,
|
||||
@ICommandService private commandService: ICommandService,
|
||||
@IConfigurationService private configurationService: IConfigurationService,
|
||||
@IProgressService2 private progressService: IProgressService2
|
||||
private viewContainer: ViewContainer,
|
||||
@IExtensionService private readonly extensionService: IExtensionService,
|
||||
@IWorkbenchThemeService private readonly themeService: IWorkbenchThemeService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@ICommandService private readonly commandService: ICommandService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@IProgressService2 private readonly progressService: IProgressService2
|
||||
) {
|
||||
super();
|
||||
this.root = new Root();
|
||||
@@ -243,6 +235,11 @@ export class CustomTreeView extends Disposable implements ITreeView {
|
||||
this.markdownResult.dispose();
|
||||
}
|
||||
}));
|
||||
this._register(ViewsRegistry.onDidChangeContainer(({ views, from, to }) => {
|
||||
if (from === this.viewContainer && views.some(v => v.id === this.id)) {
|
||||
this.viewContainer = to;
|
||||
}
|
||||
}));
|
||||
this.create();
|
||||
}
|
||||
|
||||
@@ -382,13 +379,13 @@ export class CustomTreeView extends Disposable implements ITreeView {
|
||||
|
||||
private createTree() {
|
||||
const actionItemProvider = (action: IAction) => action instanceof MenuItemAction ? this.instantiationService.createInstance(ContextAwareMenuItemActionItem, action) : undefined;
|
||||
const menus = this.instantiationService.createInstance(TreeMenus, this.id);
|
||||
const dataSource = this.instantiationService.createInstance(TreeDataSource, this, this.container);
|
||||
const renderer = this.instantiationService.createInstance(TreeRenderer, this.id, menus, actionItemProvider);
|
||||
const menus = this._register(this.instantiationService.createInstance(TreeMenus, this.id));
|
||||
this.treeLabels = this._register(this.instantiationService.createInstance(ResourceLabels, this));
|
||||
const dataSource = this.instantiationService.createInstance(TreeDataSource, this, <T>(task: Promise<T>) => this.progressService.withProgress({ location: this.viewContainer.id }, () => task));
|
||||
const renderer = this.instantiationService.createInstance(TreeRenderer, this.id, menus, this.treeLabels, actionItemProvider);
|
||||
const controller = this.instantiationService.createInstance(TreeController, this.id, menus);
|
||||
this.tree = this.instantiationService.createInstance(FileIconThemableWorkbenchTree, this.treeContainer, { dataSource, renderer, controller }, {});
|
||||
this.tree = this._register(this.instantiationService.createInstance(FileIconThemableWorkbenchTree, this.treeContainer, { dataSource, renderer, controller }, {}));
|
||||
this.tree.contextKeyService.createKey<boolean>(this.id, true);
|
||||
this._register(this.tree);
|
||||
this._register(this.tree.onDidChangeSelection(e => this.onSelection(e)));
|
||||
this._register(this.tree.onDidExpandItem(e => this._onDidExpandItem.fire(e.item.getElement())));
|
||||
this._register(this.tree.onDidCollapseItem(e => this._onDidCollapseItem.fire(e.item.getElement())));
|
||||
@@ -451,7 +448,7 @@ export class CustomTreeView extends Disposable implements ITreeView {
|
||||
getOptimalWidth(): number {
|
||||
if (this.tree) {
|
||||
const parentNode = this.tree.getHTMLElement();
|
||||
const childNodes = ([] as Element[]).slice.call(parentNode.querySelectorAll('.outline-item-label > a'));
|
||||
const childNodes = ([] as HTMLElement[]).slice.call(parentNode.querySelectorAll('.outline-item-label > a'));
|
||||
return DOM.getLargestChildWidth(parentNode, childNodes);
|
||||
}
|
||||
return 0;
|
||||
@@ -459,25 +456,39 @@ export class CustomTreeView extends Disposable implements ITreeView {
|
||||
|
||||
refresh(elements?: ITreeItem[]): Promise<void> {
|
||||
if (this.dataProvider && this.tree) {
|
||||
elements = elements || [this.root];
|
||||
if (!elements) {
|
||||
elements = [this.root];
|
||||
// remove all waiting elements to refresh if root is asked to refresh
|
||||
this.elementsToRefresh = [];
|
||||
}
|
||||
for (const element of elements) {
|
||||
element.children = null; // reset children
|
||||
}
|
||||
if (this.isVisible) {
|
||||
return this.doRefresh(elements);
|
||||
} else {
|
||||
this.elementsToRefresh.push(...elements);
|
||||
if (this.elementsToRefresh.length) {
|
||||
const seen: Set<string> = new Set<string>();
|
||||
this.elementsToRefresh.forEach(element => seen.add(element.handle));
|
||||
for (const element of elements) {
|
||||
if (!seen.has(element.handle)) {
|
||||
this.elementsToRefresh.push(element);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.elementsToRefresh.push(...elements);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Promise.resolve(null);
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
expand(itemOrItems: ITreeItem | ITreeItem[]): Thenable<void> {
|
||||
expand(itemOrItems: ITreeItem | ITreeItem[]): Promise<void> {
|
||||
if (this.tree) {
|
||||
itemOrItems = Array.isArray(itemOrItems) ? itemOrItems : [itemOrItems];
|
||||
return this.tree.expandAll(itemOrItems);
|
||||
}
|
||||
return Promise.arguments(null);
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
setSelection(items: ITreeItem[]): void {
|
||||
@@ -493,17 +504,17 @@ export class CustomTreeView extends Disposable implements ITreeView {
|
||||
}
|
||||
}
|
||||
|
||||
reveal(item: ITreeItem): Thenable<void> {
|
||||
reveal(item: ITreeItem): Promise<void> {
|
||||
if (this.tree) {
|
||||
return this.tree.reveal(item);
|
||||
}
|
||||
return Promise.arguments(null);
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
|
||||
private activate() {
|
||||
if (!this.activated) {
|
||||
this.createTree();
|
||||
this.progressService.withProgress({ location: this.container.id }, () => this.extensionService.activateByEvent(`onView:${this.id}`))
|
||||
this.progressService.withProgress({ location: this.viewContainer.id }, () => this.extensionService.activateByEvent(`onView:${this.id}`))
|
||||
.then(() => timeout(2000))
|
||||
.then(() => {
|
||||
this.updateMessage();
|
||||
@@ -525,7 +536,7 @@ export class CustomTreeView extends Disposable implements ITreeView {
|
||||
}
|
||||
});
|
||||
}
|
||||
return Promise.resolve(null);
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
private updateContentAreas(): void {
|
||||
@@ -563,8 +574,7 @@ class TreeDataSource implements IDataSource {
|
||||
|
||||
constructor(
|
||||
private treeView: ITreeView,
|
||||
private container: ViewContainer,
|
||||
@IProgressService2 private progressService: IProgressService2
|
||||
private withProgress: <T>(task: Promise<T>) => Promise<T>
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -578,7 +588,7 @@ class TreeDataSource implements IDataSource {
|
||||
|
||||
getChildren(tree: ITree, node: ITreeItem): Promise<any[]> {
|
||||
if (this.treeView.dataProvider) {
|
||||
return this.progressService.withProgress({ location: this.container.id }, () => this.treeView.dataProvider.getChildren(node));
|
||||
return this.withProgress(this.treeView.dataProvider.getChildren(node));
|
||||
}
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
@@ -593,7 +603,7 @@ class TreeDataSource implements IDataSource {
|
||||
}
|
||||
|
||||
interface ITreeExplorerTemplateData {
|
||||
resourceLabel: ResourceLabel;
|
||||
resourceLabel: IResourceLabel;
|
||||
icon: HTMLElement;
|
||||
actionBar: ActionBar;
|
||||
aligner: Aligner;
|
||||
@@ -605,10 +615,12 @@ registerThemingParticipant((theme, collector) => {
|
||||
const findMatchHighlightColor = theme.getColor(editorFindMatchHighlight);
|
||||
if (findMatchHighlightColor) {
|
||||
collector.addRule(`.file-icon-themable-tree .monaco-tree-row .content .monaco-highlighted-label .highlight { color: unset !important; background-color: ${findMatchHighlightColor}; }`);
|
||||
collector.addRule(`.monaco-tl-contents .monaco-highlighted-label .highlight { color: unset !important; background-color: ${findMatchHighlightColor}; }`);
|
||||
}
|
||||
const findMatchHighlightColorBorder = theme.getColor(editorFindMatchHighlightBorder);
|
||||
if (findMatchHighlightColorBorder) {
|
||||
collector.addRule(`.file-icon-themable-tree .monaco-tree-row .content .monaco-highlighted-label .highlight { color: unset !important; border: 1px dotted ${findMatchHighlightColorBorder}; box-sizing: border-box; }`);
|
||||
collector.addRule(`.monaco-tl-contents .monaco-highlighted-label .highlight { color: unset !important; border: 1px dotted ${findMatchHighlightColorBorder}; box-sizing: border-box; }`);
|
||||
}
|
||||
const link = theme.getColor(textLinkForeground);
|
||||
if (link) {
|
||||
@@ -632,11 +644,11 @@ class TreeRenderer implements IRenderer {
|
||||
constructor(
|
||||
private treeViewId: string,
|
||||
private menus: TreeMenus,
|
||||
private labels: ResourceLabels,
|
||||
private actionItemProvider: IActionItemProvider,
|
||||
@IInstantiationService private instantiationService: IInstantiationService,
|
||||
@IWorkbenchThemeService private themeService: IWorkbenchThemeService,
|
||||
@IConfigurationService private configurationService: IConfigurationService,
|
||||
@ILabelService private labelService: ILabelService
|
||||
@IWorkbenchThemeService private readonly themeService: IWorkbenchThemeService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@ILabelService private readonly labelService: ILabelService
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -652,7 +664,7 @@ class TreeRenderer implements IRenderer {
|
||||
DOM.addClass(container, 'custom-view-tree-node-item');
|
||||
|
||||
const icon = DOM.append(container, DOM.$('.custom-view-tree-node-item-icon'));
|
||||
const resourceLabel = this.instantiationService.createInstance(ResourceLabel, container, { supportHighlights: true, donotSupportOcticons: true });
|
||||
const resourceLabel = this.labels.create(container, { supportHighlights: true, donotSupportOcticons: true });
|
||||
DOM.addClass(resourceLabel.element, 'custom-view-tree-node-item-resourceLabel');
|
||||
const actionsContainer = DOM.append(resourceLabel.element, DOM.$('.actions'));
|
||||
const actionBar = new ActionBar(actionsContainer, {
|
||||
@@ -665,23 +677,22 @@ class TreeRenderer implements IRenderer {
|
||||
|
||||
renderElement(tree: ITree, node: ITreeItem, templateId: string, templateData: ITreeExplorerTemplateData): void {
|
||||
const resource = node.resourceUri ? URI.revive(node.resourceUri) : null;
|
||||
const treeItemLabel: ITreeItemLabel = node.label ? node.label : resource ? { label: basename(resource.path) } : void 0;
|
||||
const description = isString(node.description) ? node.description : resource && node.description === true ? this.labelService.getUriLabel(dirname(resource), { relative: true }) : void 0;
|
||||
const label = treeItemLabel ? treeItemLabel.label : void 0;
|
||||
const matches = treeItemLabel && treeItemLabel.highlights ? treeItemLabel.highlights.map(([start, end]) => ({ start, end })) : void 0;
|
||||
const treeItemLabel: ITreeItemLabel = node.label ? node.label : resource ? { label: basename(resource.path) } : undefined;
|
||||
const description = isString(node.description) ? node.description : resource && node.description === true ? this.labelService.getUriLabel(dirname(resource), { relative: true }) : undefined;
|
||||
const label = treeItemLabel ? treeItemLabel.label : undefined;
|
||||
const matches = treeItemLabel && treeItemLabel.highlights ? treeItemLabel.highlights.map(([start, end]) => ({ start, end })) : undefined;
|
||||
const icon = this.themeService.getTheme().type === LIGHT ? node.icon : node.iconDark;
|
||||
const iconUrl = icon ? URI.revive(icon) : null;
|
||||
const title = node.tooltip ? node.tooltip : resource ? void 0 : label;
|
||||
const title = node.tooltip ? node.tooltip : resource ? undefined : label;
|
||||
|
||||
// reset
|
||||
templateData.resourceLabel.clear();
|
||||
templateData.actionBar.clear();
|
||||
|
||||
if (resource || node.themeIcon) {
|
||||
const fileDecorations = this.configurationService.getValue<{ colors: boolean, badges: boolean }>('explorer.decorations');
|
||||
templateData.resourceLabel.setLabel({ name: label, description, resource: resource ? resource : URI.parse('missing:_icon_resource') }, { fileKind: this.getFileKind(node), title, hideIcon: !!iconUrl, fileDecorations, extraClasses: ['custom-view-tree-node-item-resourceLabel'], matches });
|
||||
templateData.resourceLabel.setResource({ name: label, description, resource: resource ? resource : URI.parse('missing:_icon_resource') }, { fileKind: this.getFileKind(node), title, hideIcon: !!iconUrl, fileDecorations, extraClasses: ['custom-view-tree-node-item-resourceLabel'], matches });
|
||||
} else {
|
||||
templateData.resourceLabel.setLabel({ name: label, description }, { title, hideIcon: true, extraClasses: ['custom-view-tree-node-item-resourceLabel'], matches });
|
||||
templateData.resourceLabel.setResource({ name: label, description }, { title, hideIcon: true, extraClasses: ['custom-view-tree-node-item-resourceLabel'], matches });
|
||||
}
|
||||
|
||||
templateData.icon.style.backgroundImage = iconUrl ? `url('${iconUrl.toString(true)}')` : '';
|
||||
@@ -772,7 +783,7 @@ class TreeController extends WorkbenchTreeController {
|
||||
constructor(
|
||||
private treeViewId: string,
|
||||
private menus: TreeMenus,
|
||||
@IContextMenuService private contextMenuService: IContextMenuService,
|
||||
@IContextMenuService private readonly contextMenuService: IContextMenuService,
|
||||
@IKeybindingService private readonly _keybindingService: IKeybindingService,
|
||||
@IConfigurationService configurationService: IConfigurationService
|
||||
) {
|
||||
@@ -827,7 +838,7 @@ class MultipleSelectionActionRunner extends ActionRunner {
|
||||
super();
|
||||
}
|
||||
|
||||
runAction(action: IAction, context: any): Thenable<any> {
|
||||
runAction(action: IAction, context: any): Promise<any> {
|
||||
if (action instanceof MenuItemAction) {
|
||||
const selection = this.getSelectedResources();
|
||||
const filteredSelection = selection.filter(s => s !== context);
|
||||
@@ -847,9 +858,9 @@ class TreeMenus extends Disposable implements IDisposable {
|
||||
|
||||
constructor(
|
||||
private id: string,
|
||||
@IContextKeyService private contextKeyService: IContextKeyService,
|
||||
@IMenuService private menuService: IMenuService,
|
||||
@IContextMenuService private contextMenuService: IContextMenuService
|
||||
@IContextKeyService private readonly contextKeyService: IContextKeyService,
|
||||
@IMenuService private readonly menuService: IMenuService,
|
||||
@IContextMenuService private readonly contextMenuService: IContextMenuService
|
||||
) {
|
||||
super();
|
||||
}
|
||||
@@ -914,4 +925,4 @@ class MarkdownRenderer {
|
||||
dispose: () => dispose(disposeables)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
/* File icon themeable tree style */
|
||||
/* File icon themeable OLD tree style */
|
||||
.file-icon-themable-tree .monaco-tree-row .content {
|
||||
display: flex;
|
||||
}
|
||||
@@ -50,6 +50,17 @@
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* File icons in trees */
|
||||
|
||||
.file-icon-themable-tree.align-icons-and-twisties .monaco-tl-twistie:not(.collapsible),
|
||||
.file-icon-themable-tree.hide-arrows .monaco-tl-twistie {
|
||||
background-image: none !important;
|
||||
width: 0 !important;
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
|
||||
/* Misc */
|
||||
|
||||
.monaco-workbench .tree-explorer-viewlet-tree-view {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import 'vs/css!./media/panelviewlet';
|
||||
import * as nls from 'vs/nls';
|
||||
import { Event, Emitter, filterEvent } from 'vs/base/common/event';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { ColorIdentifier } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { attachStyler, IColorMapping } from 'vs/platform/theme/common/styler';
|
||||
import { SIDE_BAR_DRAG_AND_DROP_BACKGROUND, SIDE_BAR_SECTION_HEADER_FOREGROUND, SIDE_BAR_SECTION_HEADER_BACKGROUND, SIDE_BAR_SECTION_HEADER_BORDER } from 'vs/workbench/common/theme';
|
||||
@@ -52,14 +52,17 @@ export abstract class ViewletPanel extends Panel implements IView {
|
||||
private _onDidBlur = new Emitter<void>();
|
||||
readonly onDidBlur: Event<void> = this._onDidBlur.event;
|
||||
|
||||
private _onDidChangeBodyVisibility = new Emitter<boolean>();
|
||||
readonly onDidChangeBodyVisibility: Event<boolean> = this._onDidChangeBodyVisibility.event;
|
||||
|
||||
protected _onDidChangeTitleArea = new Emitter<void>();
|
||||
readonly onDidChangeTitleArea: Event<void> = this._onDidChangeTitleArea.event;
|
||||
|
||||
private _isVisible: boolean = true;
|
||||
private _isVisible: boolean = false;
|
||||
readonly id: string;
|
||||
readonly title: string;
|
||||
|
||||
protected actionRunner: IActionRunner;
|
||||
protected actionRunner?: IActionRunner;
|
||||
protected toolbar: ToolBar;
|
||||
private headerContainer: HTMLElement;
|
||||
|
||||
@@ -74,11 +77,17 @@ export abstract class ViewletPanel extends Panel implements IView {
|
||||
this.id = options.id;
|
||||
this.title = options.title;
|
||||
this.actionRunner = options.actionRunner;
|
||||
|
||||
this.disposables.push(this._onDidFocus, this._onDidBlur, this._onDidChangeBodyVisibility, this._onDidChangeTitleArea);
|
||||
}
|
||||
|
||||
setVisible(visible: boolean): void {
|
||||
if (this._isVisible !== visible) {
|
||||
this._isVisible = visible;
|
||||
|
||||
if (this.isExpanded()) {
|
||||
this._onDidChangeBodyVisibility.fire(visible);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,6 +95,19 @@ export abstract class ViewletPanel extends Panel implements IView {
|
||||
return this._isVisible;
|
||||
}
|
||||
|
||||
isBodyVisible(): boolean {
|
||||
return this._isVisible && this.isExpanded();
|
||||
}
|
||||
|
||||
setExpanded(expanded: boolean): boolean {
|
||||
const changed = super.setExpanded(expanded);
|
||||
if (changed) {
|
||||
this._onDidChangeBodyVisibility.fire(expanded);
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
render(): void {
|
||||
super.render();
|
||||
|
||||
@@ -105,20 +127,20 @@ export abstract class ViewletPanel extends Panel implements IView {
|
||||
orientation: ActionsOrientation.HORIZONTAL,
|
||||
actionItemProvider: action => this.getActionItem(action),
|
||||
ariaLabel: nls.localize('viewToolbarAriaLabel', "{0} actions", this.title),
|
||||
getKeyBinding: action => this.keybindingService.lookupKeybinding(action.id),
|
||||
getKeyBinding: action => this.keybindingService.lookupKeybinding(action.id) || undefined,
|
||||
actionRunner: this.actionRunner
|
||||
});
|
||||
|
||||
this.disposables.push(this.toolbar);
|
||||
this.setActions();
|
||||
|
||||
const onDidRelevantConfigurationChange = filterEvent(this.configurationService.onDidChangeConfiguration, e => e.affectsConfiguration(ViewletPanel.AlwaysShowActionsConfig));
|
||||
const onDidRelevantConfigurationChange = Event.filter(this.configurationService.onDidChangeConfiguration, e => e.affectsConfiguration(ViewletPanel.AlwaysShowActionsConfig));
|
||||
onDidRelevantConfigurationChange(this.updateActionsVisibility, this, this.disposables);
|
||||
this.updateActionsVisibility();
|
||||
}
|
||||
|
||||
protected renderHeaderTitle(container: HTMLElement, title: string): void {
|
||||
append(container, $('h3.title', null, title));
|
||||
append(container, $('h3.title', undefined, title));
|
||||
}
|
||||
|
||||
focus(): void {
|
||||
@@ -151,7 +173,7 @@ export abstract class ViewletPanel extends Panel implements IView {
|
||||
return [];
|
||||
}
|
||||
|
||||
getActionItem(action: IAction): IActionItem {
|
||||
getActionItem(action: IAction): IActionItem | null {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -237,7 +259,7 @@ export class PanelViewlet extends Viewlet {
|
||||
let title = Registry.as<ViewletRegistry>(Extensions.Viewlets).getViewlet(this.getId()).name;
|
||||
|
||||
if (this.isSingleView()) {
|
||||
title += ': ' + this.panelItems[0].panel.title;
|
||||
title = `${title}: ${this.panelItems[0].panel.title}`;
|
||||
}
|
||||
|
||||
return title;
|
||||
@@ -259,7 +281,7 @@ export class PanelViewlet extends Viewlet {
|
||||
return [];
|
||||
}
|
||||
|
||||
getActionItem(action: IAction): IActionItem {
|
||||
getActionItem(action: IAction): IActionItem | null {
|
||||
if (this.isSingleView()) {
|
||||
return this.panelItems[0].panel.getActionItem(action);
|
||||
}
|
||||
@@ -283,7 +305,7 @@ export class PanelViewlet extends Viewlet {
|
||||
}
|
||||
|
||||
layout(dimension: Dimension): void {
|
||||
this.panelview.layout(dimension.height);
|
||||
this.panelview.layout(dimension.height, dimension.width);
|
||||
}
|
||||
|
||||
getOptimalWidth(): number {
|
||||
|
||||
@@ -4,14 +4,14 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import 'vs/css!./media/views';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { Disposable, IDisposable, toDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { IViewsService, ViewsRegistry, IViewsViewlet, ViewContainer, IViewDescriptor, IViewContainersRegistry, Extensions as ViewContainerExtensions, IView, IViewDescriptorCollection } from 'vs/workbench/common/views';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
|
||||
import { IContextKeyService, IContextKeyChangeEvent, IReadableSet, IContextKey, RawContextKey, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { Event, chain, filterEvent, Emitter } from 'vs/base/common/event';
|
||||
import { sortedDiff, firstIndex, move } from 'vs/base/common/arrays';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { sortedDiff, firstIndex, move, isNonEmptyArray } from 'vs/base/common/arrays';
|
||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
import { isUndefinedOrNull } from 'vs/base/common/types';
|
||||
import { MenuId, MenuRegistry, ICommandAction } from 'vs/platform/actions/common/actions';
|
||||
@@ -19,14 +19,23 @@ import { CommandsRegistry } from 'vs/platform/commands/common/commands';
|
||||
import { localize } from 'vs/nls';
|
||||
import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { values } from 'vs/base/common/map';
|
||||
import { IFileIconTheme, IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
|
||||
import { toggleClass, addClass } from 'vs/base/browser/dom';
|
||||
|
||||
function filterViewEvent(container: ViewContainer, event: Event<IViewDescriptor[]>): Event<IViewDescriptor[]> {
|
||||
return chain(event)
|
||||
.map(views => views.filter(view => view.container === container))
|
||||
function filterViewRegisterEvent(container: ViewContainer, event: Event<{ viewContainer: ViewContainer, views: IViewDescriptor[] }>): Event<IViewDescriptor[]> {
|
||||
return Event.chain(event)
|
||||
.map(({ views, viewContainer }) => viewContainer === container ? views : [])
|
||||
.filter(views => views.length > 0)
|
||||
.event;
|
||||
}
|
||||
|
||||
function filterViewMoveEvent(container: ViewContainer, event: Event<{ from: ViewContainer, to: ViewContainer, views: IViewDescriptor[] }>): Event<{ added?: IViewDescriptor[], removed?: IViewDescriptor[] }> {
|
||||
return Event.chain(event)
|
||||
.map(({ views, from, to }) => from === container ? { removed: views } : to === container ? { added: views } : {})
|
||||
.filter(({ added, removed }) => isNonEmptyArray(added) || isNonEmptyArray(removed))
|
||||
.event;
|
||||
}
|
||||
|
||||
class CounterSet<T> implements IReadableSet<T> {
|
||||
|
||||
private map = new Map<T, number>();
|
||||
@@ -84,16 +93,26 @@ class ViewDescriptorCollection extends Disposable implements IViewDescriptorColl
|
||||
|
||||
constructor(
|
||||
container: ViewContainer,
|
||||
@IContextKeyService private contextKeyService: IContextKeyService
|
||||
@IContextKeyService private readonly contextKeyService: IContextKeyService
|
||||
) {
|
||||
super();
|
||||
const onRelevantViewsRegistered = filterViewEvent(container, ViewsRegistry.onViewsRegistered);
|
||||
const onRelevantViewsRegistered = filterViewRegisterEvent(container, ViewsRegistry.onViewsRegistered);
|
||||
this._register(onRelevantViewsRegistered(this.onViewsRegistered, this));
|
||||
|
||||
const onRelevantViewsDeregistered = filterViewEvent(container, ViewsRegistry.onViewsDeregistered);
|
||||
const onRelevantViewsMoved = filterViewMoveEvent(container, ViewsRegistry.onDidChangeContainer);
|
||||
this._register(onRelevantViewsMoved(({ added, removed }) => {
|
||||
if (isNonEmptyArray(added)) {
|
||||
this.onViewsRegistered(added);
|
||||
}
|
||||
if (isNonEmptyArray(removed)) {
|
||||
this.onViewsDeregistered(removed);
|
||||
}
|
||||
}));
|
||||
|
||||
const onRelevantViewsDeregistered = filterViewRegisterEvent(container, ViewsRegistry.onViewsDeregistered);
|
||||
this._register(onRelevantViewsDeregistered(this.onViewsDeregistered, this));
|
||||
|
||||
const onRelevantContextChange = filterEvent(contextKeyService.onDidChangeContext, e => e.affectsSome(this.contextKeys));
|
||||
const onRelevantContextChange = Event.filter(contextKeyService.onDidChangeContext, e => e.affectsSome(this.contextKeys));
|
||||
this._register(onRelevantContextChange(this.onContextChanged, this));
|
||||
|
||||
this.onViewsRegistered(ViewsRegistry.getViews(container));
|
||||
@@ -204,7 +223,7 @@ export class ContributableViewsModel extends Disposable {
|
||||
|
||||
readonly viewDescriptors: IViewDescriptor[] = [];
|
||||
get visibleViewDescriptors(): IViewDescriptor[] {
|
||||
return this.viewDescriptors.filter(v => this.viewStates.get(v.id).visible);
|
||||
return this.viewDescriptors.filter(v => this.viewStates.get(v.id)!.visible);
|
||||
}
|
||||
|
||||
private _onDidAdd = this._register(new Emitter<IAddedViewDescriptorRef[]>());
|
||||
@@ -224,8 +243,10 @@ export class ContributableViewsModel extends Disposable {
|
||||
super();
|
||||
const viewDescriptorCollection = viewsService.getViewDescriptors(container);
|
||||
|
||||
this._register(viewDescriptorCollection.onDidChangeActiveViews(() => this.onDidChangeViewDescriptors(viewDescriptorCollection.activeViewDescriptors)));
|
||||
this.onDidChangeViewDescriptors(viewDescriptorCollection.activeViewDescriptors);
|
||||
if (viewDescriptorCollection) {
|
||||
this._register(viewDescriptorCollection.onDidChangeActiveViews(() => this.onDidChangeViewDescriptors(viewDescriptorCollection.activeViewDescriptors)));
|
||||
this.onDidChangeViewDescriptors(viewDescriptorCollection.activeViewDescriptors);
|
||||
}
|
||||
}
|
||||
|
||||
isVisible(id: string): boolean {
|
||||
@@ -298,7 +319,7 @@ export class ContributableViewsModel extends Disposable {
|
||||
move(this.viewDescriptors, fromIndex, toIndex);
|
||||
|
||||
for (let index = 0; index < this.viewDescriptors.length; index++) {
|
||||
const state = this.viewStates.get(this.viewDescriptors[index].id);
|
||||
const state = this.viewStates.get(this.viewDescriptors[index].id)!;
|
||||
state.order = index;
|
||||
}
|
||||
|
||||
@@ -312,6 +333,9 @@ export class ContributableViewsModel extends Disposable {
|
||||
for (let i = 0, visibleIndex = 0; i < this.viewDescriptors.length; i++) {
|
||||
const viewDescriptor = this.viewDescriptors[i];
|
||||
const state = this.viewStates.get(viewDescriptor.id);
|
||||
if (!state) {
|
||||
throw new Error(`View state for ${id} not found`);
|
||||
}
|
||||
|
||||
if (viewDescriptor.id === id) {
|
||||
return { index: i, visibleIndex, viewDescriptor, state };
|
||||
@@ -357,7 +381,7 @@ export class ContributableViewsModel extends Disposable {
|
||||
} else {
|
||||
this.viewStates.set(viewDescriptor.id, {
|
||||
visible: !viewDescriptor.hideByDefault,
|
||||
collapsed: viewDescriptor.collapsed
|
||||
collapsed: !!viewDescriptor.collapsed
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -369,7 +393,7 @@ export class ContributableViewsModel extends Disposable {
|
||||
).reverse();
|
||||
|
||||
const toRemove: { index: number, viewDescriptor: IViewDescriptor }[] = [];
|
||||
const toAdd: { index: number, viewDescriptor: IViewDescriptor, size: number, collapsed: boolean }[] = [];
|
||||
const toAdd: { index: number, viewDescriptor: IViewDescriptor, size?: number, collapsed: boolean }[] = [];
|
||||
|
||||
for (const splice of splices) {
|
||||
const startViewDescriptor = this.viewDescriptors[splice.start];
|
||||
@@ -384,9 +408,8 @@ export class ContributableViewsModel extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < splice.toInsert.length; i++) {
|
||||
const viewDescriptor = splice.toInsert[i];
|
||||
const state = this.viewStates.get(viewDescriptor.id);
|
||||
for (const viewDescriptor of splice.toInsert) {
|
||||
const state = this.viewStates.get(viewDescriptor.id)!;
|
||||
|
||||
if (state.visible) {
|
||||
toAdd.push({ index: startIndex++, viewDescriptor, size: state.size, collapsed: state.collapsed });
|
||||
@@ -437,7 +460,7 @@ export class PersistentContributableViewsModel extends ContributableViewsModel {
|
||||
}
|
||||
|
||||
private saveViewsStates(): void {
|
||||
const storedViewsStates: { [id: string]: { collapsed: boolean, size: number, order: number } } = {};
|
||||
const storedViewsStates: { [id: string]: { collapsed: boolean, size?: number, order?: number } } = {};
|
||||
|
||||
let hasState = false;
|
||||
for (const viewDescriptor of this.viewDescriptors) {
|
||||
@@ -460,7 +483,7 @@ export class PersistentContributableViewsModel extends ContributableViewsModel {
|
||||
for (const viewDescriptor of viewDescriptors) {
|
||||
if (viewDescriptor.canToggleVisibility) {
|
||||
const viewState = this.viewStates.get(viewDescriptor.id);
|
||||
storedViewsVisibilityStates.set(viewDescriptor.id, { id: viewDescriptor.id, isHidden: viewState ? !viewState.visible : void 0 });
|
||||
storedViewsVisibilityStates.set(viewDescriptor.id, { id: viewDescriptor.id, isHidden: viewState ? !viewState.visible : false });
|
||||
}
|
||||
}
|
||||
this.storageService.store(this.hiddenViewsStorageId, JSON.stringify(values(storedViewsVisibilityStates)), StorageScope.GLOBAL);
|
||||
@@ -513,34 +536,49 @@ export class ViewsService extends Disposable implements IViewsService {
|
||||
|
||||
_serviceBrand: any;
|
||||
|
||||
private readonly viewDescriptorCollections: Map<ViewContainer, IViewDescriptorCollection>;
|
||||
private readonly viewDescriptorCollections: Map<ViewContainer, { viewDescriptorCollection: IViewDescriptorCollection, disposable: IDisposable }>;
|
||||
private readonly viewDisposable: Map<IViewDescriptor, IDisposable>;
|
||||
private readonly activeViewContextKeys: Map<string, IContextKey<boolean>>;
|
||||
|
||||
constructor(
|
||||
@IViewletService private viewletService: IViewletService,
|
||||
@IContextKeyService private contextKeyService: IContextKeyService
|
||||
@IViewletService private readonly viewletService: IViewletService,
|
||||
@IContextKeyService private readonly contextKeyService: IContextKeyService
|
||||
) {
|
||||
super();
|
||||
|
||||
this.viewDescriptorCollections = new Map<ViewContainer, IViewDescriptorCollection>();
|
||||
this.viewDescriptorCollections = new Map<ViewContainer, { viewDescriptorCollection: IViewDescriptorCollection, disposable: IDisposable }>();
|
||||
this.viewDisposable = new Map<IViewDescriptor, IDisposable>();
|
||||
this.activeViewContextKeys = new Map<string, IContextKey<boolean>>();
|
||||
|
||||
this.onDidRegisterViews(ViewsRegistry.getAllViews());
|
||||
this._register(ViewsRegistry.onViewsRegistered(views => this.onDidRegisterViews(views)));
|
||||
|
||||
const viewContainersRegistry = Registry.as<IViewContainersRegistry>(ViewContainerExtensions.ViewContainersRegistry);
|
||||
viewContainersRegistry.all.forEach(viewContainer => this.onDidRegisterViewContainer(viewContainer));
|
||||
viewContainersRegistry.all.forEach(viewContainer => {
|
||||
this.onDidRegisterViews(viewContainer, ViewsRegistry.getViews(viewContainer));
|
||||
this.onDidRegisterViewContainer(viewContainer);
|
||||
});
|
||||
this._register(ViewsRegistry.onViewsRegistered(({ views, viewContainer }) => this.onDidRegisterViews(viewContainer, views)));
|
||||
this._register(ViewsRegistry.onViewsDeregistered(({ views }) => this.onDidDeregisterViews(views)));
|
||||
this._register(ViewsRegistry.onDidChangeContainer(({ views, to }) => { this.onDidDeregisterViews(views); this.onDidRegisterViews(to, views); }));
|
||||
this._register(toDisposable(() => {
|
||||
this.viewDisposable.forEach(disposable => disposable.dispose());
|
||||
this.viewDisposable.clear();
|
||||
}));
|
||||
this._register(viewContainersRegistry.onDidRegister(viewContainer => this.onDidRegisterViewContainer(viewContainer)));
|
||||
this._register(viewContainersRegistry.onDidDeregister(viewContainer => this.onDidDeregisterViewContainer(viewContainer)));
|
||||
this._register(toDisposable(() => {
|
||||
this.viewDescriptorCollections.forEach(({ disposable }) => disposable.dispose());
|
||||
this.viewDescriptorCollections.clear();
|
||||
}));
|
||||
}
|
||||
|
||||
getViewDescriptors(container: ViewContainer): IViewDescriptorCollection {
|
||||
return this.viewDescriptorCollections.get(container);
|
||||
getViewDescriptors(container: ViewContainer): IViewDescriptorCollection | null {
|
||||
const viewDescriptorCollectionItem = this.viewDescriptorCollections.get(container);
|
||||
return viewDescriptorCollectionItem ? viewDescriptorCollectionItem.viewDescriptorCollection : null;
|
||||
}
|
||||
|
||||
openView(id: string, focus: boolean): Thenable<IView> {
|
||||
const viewDescriptor = ViewsRegistry.getView(id);
|
||||
if (viewDescriptor) {
|
||||
const viewletDescriptor = this.viewletService.getViewlet(viewDescriptor.container.id);
|
||||
openView(id: string, focus: boolean): Promise<IView | null> {
|
||||
const viewContainer = ViewsRegistry.getViewContainer(id);
|
||||
if (viewContainer) {
|
||||
const viewletDescriptor = this.viewletService.getViewlet(viewContainer.id);
|
||||
if (viewletDescriptor) {
|
||||
return this.viewletService.openViewlet(viewletDescriptor.id, focus)
|
||||
.then((viewlet: IViewsViewlet) => {
|
||||
@@ -555,12 +593,21 @@ export class ViewsService extends Disposable implements IViewsService {
|
||||
}
|
||||
|
||||
private onDidRegisterViewContainer(viewContainer: ViewContainer): void {
|
||||
const viewDescriptorCollection = this._register(new ViewDescriptorCollection(viewContainer, this.contextKeyService));
|
||||
const viewDescriptorCollection = new ViewDescriptorCollection(viewContainer, this.contextKeyService);
|
||||
const disposables: IDisposable[] = [viewDescriptorCollection];
|
||||
|
||||
this.onDidChangeActiveViews({ added: viewDescriptorCollection.activeViewDescriptors, removed: [] });
|
||||
this._register(viewDescriptorCollection.onDidChangeActiveViews(changed => this.onDidChangeActiveViews(changed)));
|
||||
viewDescriptorCollection.onDidChangeActiveViews(changed => this.onDidChangeActiveViews(changed), this, disposables);
|
||||
|
||||
this.viewDescriptorCollections.set(viewContainer, viewDescriptorCollection);
|
||||
this.viewDescriptorCollections.set(viewContainer, { viewDescriptorCollection, disposable: toDisposable(() => dispose(disposables)) });
|
||||
}
|
||||
|
||||
private onDidDeregisterViewContainer(viewContainer: ViewContainer): void {
|
||||
const viewDescriptorCollectionItem = this.viewDescriptorCollections.get(viewContainer);
|
||||
if (viewDescriptorCollectionItem) {
|
||||
viewDescriptorCollectionItem.disposable.dispose();
|
||||
this.viewDescriptorCollections.delete(viewContainer);
|
||||
}
|
||||
}
|
||||
|
||||
private onDidChangeActiveViews({ added, removed }: { added: IViewDescriptor[], removed: IViewDescriptor[] }): void {
|
||||
@@ -568,9 +615,10 @@ export class ViewsService extends Disposable implements IViewsService {
|
||||
removed.forEach(viewDescriptor => this.getOrCreateActiveViewContextKey(viewDescriptor).set(false));
|
||||
}
|
||||
|
||||
private onDidRegisterViews(viewDescriptors: IViewDescriptor[]): void {
|
||||
for (const viewDescriptor of viewDescriptors) {
|
||||
const viewlet = this.viewletService.getViewlet(viewDescriptor.container.id);
|
||||
private onDidRegisterViews(container: ViewContainer, views: IViewDescriptor[]): void {
|
||||
const viewlet = this.viewletService.getViewlet(container.id);
|
||||
for (const viewDescriptor of views) {
|
||||
const disposables: IDisposable[] = [];
|
||||
const command: ICommandAction = {
|
||||
id: viewDescriptor.focusCommand ? viewDescriptor.focusCommand.id : `${viewDescriptor.id}.focus`,
|
||||
title: { original: `Focus on ${viewDescriptor.name} View`, value: localize('focus view', "Focus on {0} View", viewDescriptor.name) },
|
||||
@@ -578,12 +626,12 @@ export class ViewsService extends Disposable implements IViewsService {
|
||||
};
|
||||
const when = ContextKeyExpr.has(`${viewDescriptor.id}.active`);
|
||||
|
||||
CommandsRegistry.registerCommand(command.id, () => this.openView(viewDescriptor.id, true).then(() => null));
|
||||
disposables.push(CommandsRegistry.registerCommand(command.id, () => this.openView(viewDescriptor.id, true).then(() => null)));
|
||||
|
||||
MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
|
||||
disposables.push(MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
|
||||
command,
|
||||
when
|
||||
});
|
||||
}));
|
||||
|
||||
if (viewDescriptor.focusCommand && viewDescriptor.focusCommand.keybindings) {
|
||||
KeybindingsRegistry.registerKeybindingRule({
|
||||
@@ -597,6 +645,18 @@ export class ViewsService extends Disposable implements IViewsService {
|
||||
win: viewDescriptor.focusCommand.keybindings.win
|
||||
});
|
||||
}
|
||||
|
||||
this.viewDisposable.set(viewDescriptor, toDisposable(() => dispose(disposables)));
|
||||
}
|
||||
}
|
||||
|
||||
private onDidDeregisterViews(views: IViewDescriptor[]): void {
|
||||
for (const view of views) {
|
||||
const disposable = this.viewDisposable.get(view);
|
||||
if (disposable) {
|
||||
disposable.dispose();
|
||||
this.viewDisposable.delete(view);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -610,3 +670,16 @@ export class ViewsService extends Disposable implements IViewsService {
|
||||
return contextKey;
|
||||
}
|
||||
}
|
||||
|
||||
export function createFileIconThemableTreeContainerScope(container: HTMLElement, themeService: IWorkbenchThemeService): IDisposable {
|
||||
addClass(container, 'file-icon-themable-tree');
|
||||
addClass(container, 'show-file-icons');
|
||||
|
||||
const onDidChangeFileIconTheme = (theme: IFileIconTheme) => {
|
||||
toggleClass(container, 'align-icons-and-twisties', theme.hasFileIcons && !theme.hasFolderIcons);
|
||||
toggleClass(container, 'hide-arrows', theme.hidesExplorerArrows === true);
|
||||
};
|
||||
|
||||
onDidChangeFileIconTheme(themeService.getFileIconTheme());
|
||||
return themeService.onDidFileIconThemeChange(onDidChangeFileIconTheme);
|
||||
}
|
||||
@@ -23,83 +23,13 @@ import { DefaultPanelDndController } from 'vs/base/browser/ui/splitview/panelvie
|
||||
import { WorkbenchTree, IListService } from 'vs/platform/list/browser/listService';
|
||||
import { IWorkbenchThemeService, IFileIconTheme } from 'vs/workbench/services/themes/common/workbenchThemeService';
|
||||
import { ITreeConfiguration, ITreeOptions } from 'vs/base/parts/tree/browser/tree';
|
||||
import { latch, mapEvent } from 'vs/base/common/event';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IPartService } from 'vs/workbench/services/part/common/partService';
|
||||
import { localize } from 'vs/nls';
|
||||
import { IAddedViewDescriptorRef, IViewDescriptorRef, PersistentContributableViewsModel } from 'vs/workbench/browser/parts/views/views';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
|
||||
export abstract class TreeViewsViewletPanel extends ViewletPanel {
|
||||
|
||||
protected tree: WorkbenchTree;
|
||||
|
||||
setExpanded(expanded: boolean): void {
|
||||
if (this.isExpanded() !== expanded) {
|
||||
this.updateTreeVisibility(this.tree, expanded);
|
||||
super.setExpanded(expanded);
|
||||
}
|
||||
}
|
||||
|
||||
setVisible(visible: boolean): void {
|
||||
if (this.isVisible() !== visible) {
|
||||
super.setVisible(visible);
|
||||
this.updateTreeVisibility(this.tree, visible && this.isExpanded());
|
||||
}
|
||||
}
|
||||
|
||||
focus(): void {
|
||||
super.focus();
|
||||
this.focusTree();
|
||||
}
|
||||
|
||||
layoutBody(size: number): void {
|
||||
if (this.tree) {
|
||||
this.tree.layout(size);
|
||||
}
|
||||
}
|
||||
|
||||
protected updateTreeVisibility(tree: WorkbenchTree, isVisible: boolean): void {
|
||||
if (!tree) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isVisible) {
|
||||
DOM.show(tree.getHTMLElement());
|
||||
} else {
|
||||
DOM.hide(tree.getHTMLElement()); // make sure the tree goes out of the tabindex world by hiding it
|
||||
}
|
||||
|
||||
if (isVisible) {
|
||||
tree.onVisible();
|
||||
} else {
|
||||
tree.onHidden();
|
||||
}
|
||||
}
|
||||
|
||||
private focusTree(): void {
|
||||
if (!this.tree) {
|
||||
return; // return early if viewlet has not yet been created
|
||||
}
|
||||
|
||||
// Make sure the current selected element is revealed
|
||||
const selectedElement = this.tree.getSelection()[0];
|
||||
if (selectedElement) {
|
||||
this.tree.reveal(selectedElement);
|
||||
}
|
||||
|
||||
// Pass Focus to Viewer
|
||||
this.tree.domFocus();
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
if (this.tree) {
|
||||
this.tree.dispose();
|
||||
}
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
export interface IViewletViewOptions extends IViewletPanelOptions {
|
||||
viewletState: object;
|
||||
}
|
||||
@@ -274,7 +204,7 @@ export abstract class ViewContainerViewlet extends PanelViewlet implements IView
|
||||
this.onContextMenu(new StandardMouseEvent(e), viewDescriptor);
|
||||
});
|
||||
|
||||
const collapseDisposable = latch(mapEvent(panel.onDidChange, () => !panel.isExpanded()))(collapsed => {
|
||||
const collapseDisposable = Event.latch(Event.map(panel.onDidChange, () => !panel.isExpanded()))(collapsed => {
|
||||
this.viewsModel.setCollapsed(viewDescriptor.id, collapsed);
|
||||
});
|
||||
|
||||
@@ -284,7 +214,13 @@ export abstract class ViewContainerViewlet extends PanelViewlet implements IView
|
||||
|
||||
this.addPanels(panelsToAdd);
|
||||
this.restoreViewSizes();
|
||||
return panelsToAdd.map(({ panel }) => panel);
|
||||
|
||||
const panels: ViewletPanel[] = [];
|
||||
for (const { panel } of panelsToAdd) {
|
||||
panel.setVisible(this.isVisible());
|
||||
panels.push(panel);
|
||||
}
|
||||
return panels;
|
||||
}
|
||||
|
||||
private onDidRemoveViews(removed: IViewDescriptorRef[]): void {
|
||||
|
||||
Reference in New Issue
Block a user