mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-13 03:28:33 -05:00
Merge from vscode bd0efff9e3f36d6b3e1045cee9887003af8034d7
This commit is contained in:
@@ -487,7 +487,7 @@ export class ResetViewLocationsAction extends Action {
|
||||
}
|
||||
|
||||
async run(): Promise<void> {
|
||||
this.viewDescriptorService.getViewContainers().forEach(viewContainer => {
|
||||
this.viewDescriptorService.viewContainers.forEach(viewContainer => {
|
||||
const viewContainerModel = this.viewDescriptorService.getViewContainerModel(viewContainer);
|
||||
|
||||
viewContainerModel.allViewDescriptors.forEach(viewDescriptor => {
|
||||
@@ -596,7 +596,7 @@ export class MoveFocusedViewAction extends Action {
|
||||
});
|
||||
}
|
||||
|
||||
const pinnedViewlets = this.activityBarService.getPinnedViewletIds();
|
||||
const pinnedViewlets = this.activityBarService.getPinnedViewContainerIds();
|
||||
items.push(...pinnedViewlets
|
||||
.filter(viewletId => {
|
||||
if (viewletId === this.viewDescriptorService.getViewContainerByViewId(focusedViewId)!.id) {
|
||||
|
||||
@@ -7,7 +7,6 @@ import * as nls from 'vs/nls';
|
||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
import { IWorkspaceEditingService } from 'vs/workbench/services/workspaces/common/workspaceEditing';
|
||||
import * as resources from 'vs/base/common/resources';
|
||||
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { mnemonicButtonLabel } from 'vs/base/common/labels';
|
||||
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
|
||||
@@ -19,6 +18,7 @@ import { getIconClasses } from 'vs/editor/common/services/getIconClasses';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
import { IFileDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||
import { IViewDescriptorService, IViewsService, ViewContainerLocation } from 'vs/workbench/common/views';
|
||||
|
||||
export const ADD_ROOT_FOLDER_COMMAND_ID = 'addRootFolder';
|
||||
export const ADD_ROOT_FOLDER_LABEL = nls.localize('addFolderToWorkspace', "Add Folder to Workspace...");
|
||||
@@ -55,7 +55,8 @@ CommandsRegistry.registerCommand({
|
||||
CommandsRegistry.registerCommand({
|
||||
id: ADD_ROOT_FOLDER_COMMAND_ID,
|
||||
handler: async (accessor) => {
|
||||
const viewletService = accessor.get(IViewletService);
|
||||
const viewDescriptorService = accessor.get(IViewDescriptorService);
|
||||
const viewsService = accessor.get(IViewsService);
|
||||
const workspaceEditingService = accessor.get(IWorkspaceEditingService);
|
||||
const dialogsService = accessor.get(IFileDialogService);
|
||||
const folders = await dialogsService.showOpenDialog({
|
||||
@@ -71,7 +72,7 @@ CommandsRegistry.registerCommand({
|
||||
}
|
||||
|
||||
await workspaceEditingService.addFolders(folders.map(folder => ({ uri: resources.removeTrailingPathSeparator(folder) })));
|
||||
await viewletService.openViewlet(viewletService.getDefaultViewletId(), true);
|
||||
await viewsService.openViewContainer(viewDescriptorService.getDefaultViewContainer(ViewContainerLocation.Sidebar)!.id, true);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@ import { trackFocus, Dimension } from 'vs/base/browser/dom';
|
||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { assertIsDefined } from 'vs/base/common/types';
|
||||
import { find } from 'vs/base/common/arrays';
|
||||
|
||||
/**
|
||||
* Composites are layed out in the sidebar and panel part of the workbench. At a time only one composite
|
||||
@@ -256,7 +255,7 @@ export abstract class CompositeRegistry<T extends Composite> extends Disposable
|
||||
private readonly _onDidDeregister = this._register(new Emitter<CompositeDescriptor<T>>());
|
||||
readonly onDidDeregister = this._onDidDeregister.event;
|
||||
|
||||
private composites: CompositeDescriptor<T>[] = [];
|
||||
private readonly composites: CompositeDescriptor<T>[] = [];
|
||||
|
||||
protected registerComposite(descriptor: CompositeDescriptor<T>): void {
|
||||
if (this.compositeById(descriptor.id)) {
|
||||
@@ -286,6 +285,6 @@ export abstract class CompositeRegistry<T extends Composite> extends Disposable
|
||||
}
|
||||
|
||||
private compositeById(id: string): CompositeDescriptor<T> | undefined {
|
||||
return find(this.composites, composite => composite.id === id);
|
||||
return this.composites.find(composite => composite.id === id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor';
|
||||
import { IConstructorSignature0, IInstantiationService, BrandedService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { find, insert } from 'vs/base/common/arrays';
|
||||
import { insert } from 'vs/base/common/arrays';
|
||||
import { IDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
|
||||
export interface IEditorDescriptor {
|
||||
@@ -154,7 +154,7 @@ class EditorRegistry implements IEditorRegistry {
|
||||
}
|
||||
|
||||
getEditorById(editorId: string): EditorDescriptor | undefined {
|
||||
return find(this.editors, editor => editor.getId() === editorId);
|
||||
return this.editors.find(editor => editor.getId() === editorId);
|
||||
}
|
||||
|
||||
getEditors(): readonly EditorDescriptor[] {
|
||||
|
||||
@@ -43,6 +43,7 @@ import { WINDOW_ACTIVE_BORDER, WINDOW_INACTIVE_BORDER } from 'vs/workbench/commo
|
||||
import { LineNumbersType } from 'vs/editor/common/config/editorOptions';
|
||||
import { ActivitybarPart } from 'vs/workbench/browser/parts/activitybar/activitybarPart';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IViewDescriptorService, ViewContainerLocation } from 'vs/workbench/common/views';
|
||||
|
||||
export enum Settings {
|
||||
ACTIVITYBAR_VISIBLE = 'workbench.activityBar.visible',
|
||||
@@ -171,6 +172,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
private panelService!: IPanelService;
|
||||
private titleService!: ITitleService;
|
||||
private viewletService!: IViewletService;
|
||||
private viewDescriptorService!: IViewDescriptorService;
|
||||
private contextService!: IWorkspaceContextService;
|
||||
private backupFileService!: IBackupFileService;
|
||||
private notificationService!: INotificationService;
|
||||
@@ -255,6 +257,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
this.editorGroupService = accessor.get(IEditorGroupsService);
|
||||
this.panelService = accessor.get(IPanelService);
|
||||
this.viewletService = accessor.get(IViewletService);
|
||||
this.viewDescriptorService = accessor.get(IViewDescriptorService);
|
||||
this.titleService = accessor.get(ITitleService);
|
||||
this.notificationService = accessor.get(INotificationService);
|
||||
accessor.get(IStatusbarService); // not used, but called to ensure instantiated
|
||||
@@ -489,11 +492,11 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
if (!this.state.sideBar.hidden) {
|
||||
|
||||
// Only restore last viewlet if window was reloaded or we are in development mode
|
||||
let viewletToRestore: string;
|
||||
let viewletToRestore: string | undefined;
|
||||
if (!this.environmentService.isBuilt || lifecycleService.startupKind === StartupKind.ReloadedWindow || isWeb) {
|
||||
viewletToRestore = this.storageService.get(SidebarPart.activeViewletSettingsKey, StorageScope.WORKSPACE, this.viewletService.getDefaultViewletId());
|
||||
viewletToRestore = this.storageService.get(SidebarPart.activeViewletSettingsKey, StorageScope.WORKSPACE, this.viewDescriptorService.getDefaultViewContainer(ViewContainerLocation.Sidebar)?.id);
|
||||
} else {
|
||||
viewletToRestore = this.viewletService.getDefaultViewletId();
|
||||
viewletToRestore = this.viewDescriptorService.getDefaultViewContainer(ViewContainerLocation.Sidebar)?.id;
|
||||
}
|
||||
|
||||
if (viewletToRestore) {
|
||||
@@ -639,7 +642,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
}
|
||||
|
||||
if (sidebarState.length) {
|
||||
storageService.store(ActivitybarPart.PINNED_VIEWLETS, JSON.stringify(sidebarState), StorageScope.GLOBAL);
|
||||
storageService.store(ActivitybarPart.PINNED_VIEW_CONTAINERS, JSON.stringify(sidebarState), StorageScope.GLOBAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1344,7 +1347,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
|
||||
if (viewletToOpen) {
|
||||
const viewlet = this.viewletService.openViewlet(viewletToOpen, true);
|
||||
if (!viewlet) {
|
||||
this.viewletService.openViewlet(this.viewletService.getDefaultViewletId(), true);
|
||||
this.viewletService.openViewlet(this.viewDescriptorService.getDefaultViewContainer(ViewContainerLocation.Sidebar)?.id, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
backdrop-filter: brightness(97%) blur(2px);
|
||||
pointer-events: none;
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
transition: opacity .5s, visibility .5s;
|
||||
|
||||
@@ -11,7 +11,6 @@ import { EventType as TouchEventType, GestureEvent } from 'vs/base/browser/touch
|
||||
import { Action, IAction } from 'vs/base/common/actions';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { dispose } from 'vs/base/common/lifecycle';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { SyncActionDescriptor, IMenuService, MenuId } from 'vs/platform/actions/common/actions';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
@@ -19,7 +18,6 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { activeContrastBorder, focusBorder } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { ICssStyleCollector, IColorTheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
||||
import { ActivityAction, ActivityActionViewItem, ICompositeBar, ICompositeBarColors, ToggleCompositePinnedAction } from 'vs/workbench/browser/parts/compositeBarActions';
|
||||
import { ViewletDescriptor } from 'vs/workbench/browser/viewlet';
|
||||
import { Extensions as ActionExtensions, IWorkbenchActionRegistry } from 'vs/workbench/common/actions';
|
||||
import { IActivity } from 'vs/workbench/common/activity';
|
||||
import { ACTIVITY_BAR_FOREGROUND, ACTIVITY_BAR_ACTIVE_BORDER, ACTIVITY_BAR_ACTIVE_FOCUS_BORDER, ACTIVITY_BAR_ACTIVE_BACKGROUND, ACTIVITY_BAR_BACKGROUND } from 'vs/workbench/common/theme';
|
||||
@@ -30,9 +28,8 @@ import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { createAndFillInActionBarActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { Codicon } from 'vs/base/common/codicons';
|
||||
import { isString } from 'vs/base/common/types';
|
||||
|
||||
export class ViewletActivityAction extends ActivityAction {
|
||||
export class ViewContainerActivityAction extends ActivityAction {
|
||||
|
||||
private static readonly preventDoubleClickDelay = 300;
|
||||
|
||||
@@ -48,7 +45,6 @@ export class ViewletActivityAction extends ActivityAction {
|
||||
@IWorkbenchLayoutService layoutService: IWorkbenchLayoutService,
|
||||
@ITelemetryService telemetryService: ITelemetryService
|
||||
) {
|
||||
ViewletActivityAction.generateIconCSS(activity);
|
||||
super(activity);
|
||||
|
||||
this.lastRun = 0;
|
||||
@@ -57,23 +53,7 @@ export class ViewletActivityAction extends ActivityAction {
|
||||
this.telemetryService = telemetryService;
|
||||
}
|
||||
|
||||
private static generateIconCSS(activity: IActivity): void {
|
||||
if (activity.iconUrl) {
|
||||
activity.cssClass = activity.cssClass || `activity-${activity.id.replace(/\./g, '-')}`;
|
||||
const iconClass = `.monaco-workbench .activitybar .monaco-action-bar .action-label.${activity.cssClass}`;
|
||||
DOM.createCSSRule(iconClass, `
|
||||
mask: ${DOM.asCSSUrl(activity.iconUrl)} no-repeat 50% 50%;
|
||||
mask-size: 24px;
|
||||
-webkit-mask: ${DOM.asCSSUrl(activity.iconUrl)} no-repeat 50% 50%;
|
||||
-webkit-mask-size: 24px;
|
||||
`);
|
||||
}
|
||||
}
|
||||
|
||||
setActivity(activity: IActivity): void {
|
||||
if (activity.iconUrl && this.activity.cssClass !== activity.cssClass) {
|
||||
ViewletActivityAction.generateIconCSS(activity);
|
||||
}
|
||||
updateActivity(activity: IActivity): void {
|
||||
this.activity = activity;
|
||||
}
|
||||
|
||||
@@ -84,7 +64,7 @@ export class ViewletActivityAction extends ActivityAction {
|
||||
|
||||
// prevent accident trigger on a doubleclick (to help nervous people)
|
||||
const now = Date.now();
|
||||
if (now > this.lastRun /* https://github.com/Microsoft/vscode/issues/25830 */ && now - this.lastRun < ViewletActivityAction.preventDoubleClickDelay) {
|
||||
if (now > this.lastRun /* https://github.com/Microsoft/vscode/issues/25830 */ && now - this.lastRun < ViewContainerActivityAction.preventDoubleClickDelay) {
|
||||
return;
|
||||
}
|
||||
this.lastRun = now;
|
||||
@@ -113,30 +93,6 @@ export class ViewletActivityAction extends ActivityAction {
|
||||
}
|
||||
}
|
||||
|
||||
export class ToggleViewletAction extends Action {
|
||||
|
||||
constructor(
|
||||
private _viewlet: ViewletDescriptor,
|
||||
@IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService,
|
||||
@IViewletService private readonly viewletService: IViewletService
|
||||
) {
|
||||
super(_viewlet.id, _viewlet.name);
|
||||
}
|
||||
|
||||
async run(): Promise<void> {
|
||||
const sideBarVisible = this.layoutService.isVisible(Parts.SIDEBAR_PART);
|
||||
const activeViewlet = this.viewletService.getActiveViewlet();
|
||||
|
||||
// Hide sidebar if selected viewlet already visible
|
||||
if (sideBarVisible && activeViewlet?.getId() === this._viewlet.id) {
|
||||
this.layoutService.setSideBarHidden(true);
|
||||
return;
|
||||
}
|
||||
|
||||
await this.viewletService.openViewlet(this._viewlet.id, true);
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountsActionViewItem extends ActivityActionViewItem {
|
||||
constructor(
|
||||
action: ActivityAction,
|
||||
@@ -248,23 +204,7 @@ export class GlobalActivityActionViewItem extends ActivityActionViewItem {
|
||||
}
|
||||
}
|
||||
|
||||
export class PlaceHolderViewletActivityAction extends ViewletActivityAction {
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
icon: URI | string | undefined,
|
||||
@IViewletService viewletService: IViewletService,
|
||||
@IWorkbenchLayoutService layoutService: IWorkbenchLayoutService,
|
||||
@ITelemetryService telemetryService: ITelemetryService
|
||||
) {
|
||||
super({
|
||||
id,
|
||||
name: id,
|
||||
iconUrl: URI.isUri(icon) ? icon : undefined,
|
||||
cssClass: isString(icon) ? icon : undefined
|
||||
}, viewletService, layoutService, telemetryService);
|
||||
}
|
||||
}
|
||||
export class PlaceHolderViewContainerActivityAction extends ViewContainerActivityAction { }
|
||||
|
||||
export class PlaceHolderToggleCompositePinnedAction extends ToggleCompositePinnedAction {
|
||||
|
||||
@@ -289,16 +229,16 @@ class SwitchSideBarViewAction extends Action {
|
||||
}
|
||||
|
||||
async run(offset: number): Promise<void> {
|
||||
const pinnedViewletIds = this.activityBarService.getPinnedViewletIds();
|
||||
const visibleViewletIds = this.activityBarService.getVisibleViewContainerIds();
|
||||
|
||||
const activeViewlet = this.viewletService.getActiveViewlet();
|
||||
if (!activeViewlet) {
|
||||
return;
|
||||
}
|
||||
let targetViewletId: string | undefined;
|
||||
for (let i = 0; i < pinnedViewletIds.length; i++) {
|
||||
if (pinnedViewletIds[i] === activeViewlet.getId()) {
|
||||
targetViewletId = pinnedViewletIds[(i + pinnedViewletIds.length + offset) % pinnedViewletIds.length];
|
||||
for (let i = 0; i < visibleViewletIds.length; i++) {
|
||||
if (visibleViewletIds[i] === activeViewlet.getId()) {
|
||||
targetViewletId = visibleViewletIds[(i + visibleViewletIds.length + offset) % visibleViewletIds.length];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,8 +8,7 @@ import * as nls from 'vs/nls';
|
||||
import { ActionsOrientation, ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { GLOBAL_ACTIVITY_ID, IActivity } from 'vs/workbench/common/activity';
|
||||
import { Part } from 'vs/workbench/browser/part';
|
||||
import { GlobalActivityActionViewItem, ViewletActivityAction, ToggleViewletAction, PlaceHolderToggleCompositePinnedAction, PlaceHolderViewletActivityAction, AccountsActionViewItem, HomeAction } from 'vs/workbench/browser/parts/activitybar/activitybarActions';
|
||||
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
|
||||
import { GlobalActivityActionViewItem, ViewContainerActivityAction, PlaceHolderToggleCompositePinnedAction, PlaceHolderViewContainerActivityAction, AccountsActionViewItem, HomeAction } from 'vs/workbench/browser/parts/activitybar/activitybarActions';
|
||||
import { IBadge, NumberBadge } from 'vs/workbench/services/activity/common/activity';
|
||||
import { IWorkbenchLayoutService, Parts, Position as SideBarPosition } from 'vs/workbench/services/layout/browser/layoutService';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
@@ -19,15 +18,13 @@ import { IThemeService, IColorTheme } from 'vs/platform/theme/common/themeServic
|
||||
import { ACTIVITY_BAR_BACKGROUND, ACTIVITY_BAR_BORDER, ACTIVITY_BAR_FOREGROUND, ACTIVITY_BAR_ACTIVE_BORDER, ACTIVITY_BAR_BADGE_BACKGROUND, ACTIVITY_BAR_BADGE_FOREGROUND, ACTIVITY_BAR_DRAG_AND_DROP_BACKGROUND, ACTIVITY_BAR_INACTIVE_FOREGROUND, ACTIVITY_BAR_ACTIVE_BACKGROUND } from 'vs/workbench/common/theme';
|
||||
import { contrastBorder } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { CompositeBar, ICompositeBarItem, CompositeDragAndDrop } from 'vs/workbench/browser/parts/compositeBar';
|
||||
import { Dimension, addClass, removeNode } from 'vs/base/browser/dom';
|
||||
import { Dimension, addClass, removeNode, createCSSRule, asCSSUrl } 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, UriComponents } from 'vs/base/common/uri';
|
||||
import { ToggleCompositePinnedAction, ICompositeBarColors, ActivityAction, ICompositeActivity } from 'vs/workbench/browser/parts/compositeBarActions';
|
||||
import { ViewletDescriptor } from 'vs/workbench/browser/viewlet';
|
||||
import { IViewDescriptorService, ViewContainer, TEST_VIEW_CONTAINER_ID, IViewContainerModel, ViewContainerLocation } from 'vs/workbench/common/views';
|
||||
import { IViewDescriptorService, ViewContainer, TEST_VIEW_CONTAINER_ID, IViewContainerModel, ViewContainerLocation, IViewsService } from 'vs/workbench/common/views';
|
||||
import { IContextKeyService, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IViewlet } from 'vs/workbench/common/viewlet';
|
||||
import { isUndefinedOrNull, assertIsDefined, isString } from 'vs/base/common/types';
|
||||
import { IActivityBarService } from 'vs/workbench/services/activityBar/browser/activityBarService';
|
||||
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
@@ -42,8 +39,10 @@ import { getUserDataSyncStore } from 'vs/platform/userDataSync/common/userDataSy
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { Before2D } from 'vs/workbench/browser/dnd';
|
||||
import { Codicon, iconRegistry } from 'vs/base/common/codicons';
|
||||
import { Action } from 'vs/base/common/actions';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
|
||||
interface IPlaceholderViewlet {
|
||||
interface IPlaceholderViewContainer {
|
||||
id: string;
|
||||
name?: string;
|
||||
iconUrl?: UriComponents;
|
||||
@@ -51,14 +50,14 @@ interface IPlaceholderViewlet {
|
||||
views?: { when?: string }[];
|
||||
}
|
||||
|
||||
interface IPinnedViewlet {
|
||||
interface IPinnedViewContainer {
|
||||
id: string;
|
||||
pinned: boolean;
|
||||
order?: number;
|
||||
visible: boolean;
|
||||
}
|
||||
|
||||
interface ICachedViewlet {
|
||||
interface ICachedViewContainer {
|
||||
id: string;
|
||||
name?: string;
|
||||
icon?: URI | string;
|
||||
@@ -73,8 +72,8 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
_serviceBrand: undefined;
|
||||
|
||||
private static readonly ACTION_HEIGHT = 48;
|
||||
static readonly PINNED_VIEWLETS = 'workbench.activity.pinnedViewlets2';
|
||||
private static readonly PLACEHOLDER_VIEWLETS = 'workbench.activity.placeholderViewlets';
|
||||
static readonly PINNED_VIEW_CONTAINERS = 'workbench.activity.pinnedViewlets2';
|
||||
private static readonly PLACEHOLDER_VIEW_CONTAINERS = 'workbench.activity.placeholderViewlets';
|
||||
|
||||
//#region IView
|
||||
|
||||
@@ -99,18 +98,20 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
private globalActivityActionBar: ActionBar | undefined;
|
||||
private readonly globalActivity: ICompositeActivity[] = [];
|
||||
|
||||
private readonly cachedViewlets: ICachedViewlet[] = [];
|
||||
private readonly compositeActions = new Map<string, { activityAction: ViewletActivityAction, pinnedAction: ToggleCompositePinnedAction }>();
|
||||
private readonly viewletDisposables = new Map<string, IDisposable>();
|
||||
private readonly cachedViewContainers: ICachedViewContainer[] = [];
|
||||
private readonly compositeActions = new Map<string, { activityAction: ViewContainerActivityAction, pinnedAction: ToggleCompositePinnedAction }>();
|
||||
private readonly viewContainerDisposables = new Map<string, IDisposable>();
|
||||
|
||||
private readonly location = ViewContainerLocation.Sidebar;
|
||||
|
||||
constructor(
|
||||
@IViewletService private readonly viewletService: IViewletService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@IWorkbenchLayoutService layoutService: IWorkbenchLayoutService,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IStorageService private readonly storageService: IStorageService,
|
||||
@IExtensionService private readonly extensionService: IExtensionService,
|
||||
@IViewDescriptorService private readonly viewDescriptorService: IViewDescriptorService,
|
||||
@IViewsService private readonly viewsService: IViewsService,
|
||||
@IContextKeyService private readonly contextKeyService: IContextKeyService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService,
|
||||
@@ -119,27 +120,27 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
) {
|
||||
super(Parts.ACTIVITYBAR_PART, { hasTitle: false }, themeService, storageService, layoutService);
|
||||
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: ActivitybarPart.PINNED_VIEWLETS, version: 1 });
|
||||
this.migrateFromOldCachedViewletsValue();
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: ActivitybarPart.PINNED_VIEW_CONTAINERS, version: 1 });
|
||||
this.migrateFromOldCachedViewContainersValue();
|
||||
|
||||
this.cachedViewlets = this.getCachedViewlets();
|
||||
for (const cachedViewlet of this.cachedViewlets) {
|
||||
this.cachedViewContainers = this.getCachedViewContainers();
|
||||
for (const cachedViewContainer of this.cachedViewContainers) {
|
||||
if (environmentService.configuration.remoteAuthority // In remote window, hide activity bar entries until registered.
|
||||
|| this.shouldBeHidden(cachedViewlet.id, cachedViewlet)
|
||||
|| this.shouldBeHidden(cachedViewContainer.id, cachedViewContainer)
|
||||
) {
|
||||
cachedViewlet.visible = false;
|
||||
cachedViewContainer.visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
const cachedItems = this.cachedViewlets
|
||||
const cachedItems = this.cachedViewContainers
|
||||
.map(v => ({ id: v.id, name: v.name, visible: v.visible, order: v.order, pinned: v.pinned }));
|
||||
this.compositeBar = this._register(this.instantiationService.createInstance(CompositeBar, cachedItems, {
|
||||
icon: true,
|
||||
orientation: ActionsOrientation.VERTICAL,
|
||||
openComposite: (compositeId: string) => this.viewletService.openViewlet(compositeId, true),
|
||||
openComposite: (compositeId: string) => this.viewsService.openViewContainer(compositeId, true),
|
||||
getActivityAction: (compositeId: string) => this.getCompositeActions(compositeId).activityAction,
|
||||
getCompositePinnedAction: (compositeId: string) => this.getCompositeActions(compositeId).pinnedAction,
|
||||
getOnCompositeClickAction: (compositeId: string) => this.instantiationService.createInstance(ToggleViewletAction, assertIsDefined(this.viewletService.getViewlet(compositeId))),
|
||||
getOnCompositeClickAction: (compositeId: string) => new Action(compositeId, '', '', true, () => this.viewsService.isViewContainerVisible(compositeId) ? Promise.resolve(this.viewsService.closeViewContainer(compositeId)) : this.viewsService.openViewContainer(compositeId)),
|
||||
getContextMenuActions: () => {
|
||||
const menuBarVisibility = getMenuBarVisibility(this.configurationService, this.environmentService);
|
||||
const actions = [];
|
||||
@@ -152,10 +153,10 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
return actions;
|
||||
},
|
||||
getContextMenuActionsForComposite: () => [],
|
||||
getDefaultCompositeId: () => this.viewletService.getDefaultViewletId(),
|
||||
getDefaultCompositeId: () => this.viewDescriptorService.getDefaultViewContainer(this.location)!.id,
|
||||
hidePart: () => this.layoutService.setSideBarHidden(true),
|
||||
dndHandler: new CompositeDragAndDrop(this.viewDescriptorService, ViewContainerLocation.Sidebar,
|
||||
(id: string, focus?: boolean) => this.viewletService.openViewlet(id, focus),
|
||||
(id: string, focus?: boolean) => this.viewsService.openViewContainer(id, focus),
|
||||
(from: string, to: string, before?: Before2D) => this.compositeBar.move(from, to, before?.verticallyBefore)
|
||||
),
|
||||
compositeSize: 52,
|
||||
@@ -163,28 +164,25 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
overflowActionSize: ActivitybarPart.ACTION_HEIGHT
|
||||
}));
|
||||
|
||||
this.onDidRegisterViewContainers(this.getViewContainers());
|
||||
this.registerListeners();
|
||||
this.onDidRegisterViewlets(viewletService.getViewlets());
|
||||
}
|
||||
|
||||
private registerListeners(): void {
|
||||
|
||||
// Viewlet registration
|
||||
this._register(this.viewletService.onDidViewletRegister(viewlet => this.onDidRegisterViewlets([viewlet])));
|
||||
this._register(this.viewletService.onDidViewletDeregister(({ id }) => this.onDidDeregisterViewlet(id)));
|
||||
// View Container Changes
|
||||
this._register(this.viewDescriptorService.onDidChangeViewContainers(({ added, removed }) => this.onDidChangeViewContainers(added, removed)));
|
||||
this._register(this.viewDescriptorService.onDidChangeContainerLocation(({ viewContainer, from, to }) => this.onDidChangeViewContainerLocation(viewContainer, from, to)));
|
||||
|
||||
// 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())));
|
||||
// View Container Visibility Changes
|
||||
this._register(Event.filter(this.viewsService.onDidChangeViewContainerVisibility, e => e.location === this.location)(({ id, visible }) => this.onDidChangeViewContainerVisibility(id, visible)));
|
||||
|
||||
// Extension registration
|
||||
let disposables = this._register(new DisposableStore());
|
||||
this._register(this.extensionService.onDidRegisterExtensions(() => {
|
||||
disposables.clear();
|
||||
this.onDidRegisterExtensions();
|
||||
this.compositeBar.onDidChange(() => this.saveCachedViewlets(), this, disposables);
|
||||
this.compositeBar.onDidChange(() => this.saveCachedViewContainers(), this, disposables);
|
||||
this.storageService.onDidChangeStorage(e => this.onDidStorageChange(e), this, disposables);
|
||||
}));
|
||||
|
||||
@@ -200,39 +198,57 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
}));
|
||||
}
|
||||
|
||||
private onDidRegisterExtensions(): void {
|
||||
this.removeNotExistingComposites();
|
||||
this.saveCachedViewlets();
|
||||
private onDidChangeViewContainers(added: ReadonlyArray<{ container: ViewContainer, location: ViewContainerLocation }>, removed: ReadonlyArray<{ container: ViewContainer, location: ViewContainerLocation }>) {
|
||||
removed.filter(({ location }) => location === ViewContainerLocation.Sidebar).forEach(({ container }) => this.onDidDeregisterViewContainer(container));
|
||||
this.onDidRegisterViewContainers(added.filter(({ location }) => location === ViewContainerLocation.Sidebar).map(({ container }) => container));
|
||||
}
|
||||
|
||||
private onDidViewletOpen(viewlet: IViewlet): void {
|
||||
|
||||
// Update the composite bar by adding
|
||||
const foundViewlet = this.viewletService.getViewlet(viewlet.getId());
|
||||
if (foundViewlet) {
|
||||
this.compositeBar.addComposite(foundViewlet);
|
||||
private onDidChangeViewContainerLocation(container: ViewContainer, from: ViewContainerLocation, to: ViewContainerLocation) {
|
||||
if (from === this.location) {
|
||||
this.onDidDeregisterViewContainer(container);
|
||||
}
|
||||
if (to === this.location) {
|
||||
this.onDidRegisterViewContainers([container]);
|
||||
}
|
||||
}
|
||||
|
||||
this.compositeBar.activateComposite(viewlet.getId());
|
||||
private onDidChangeViewContainerVisibility(id: string, visible: boolean) {
|
||||
if (visible) {
|
||||
// Activate view container action on opening of a view container
|
||||
this.onDidViewContainerVisible(id);
|
||||
} else {
|
||||
// Deactivate view container action on close
|
||||
this.compositeBar.deactivateComposite(id);
|
||||
}
|
||||
}
|
||||
|
||||
const viewletDescriptor = this.viewletService.getViewlet(viewlet.getId());
|
||||
if (viewletDescriptor) {
|
||||
const viewContainer = this.getViewContainer(viewletDescriptor.id);
|
||||
if (viewContainer?.hideIfEmpty) {
|
||||
private onDidRegisterExtensions(): void {
|
||||
this.removeNotExistingComposites();
|
||||
this.saveCachedViewContainers();
|
||||
}
|
||||
|
||||
private onDidViewContainerVisible(id: string): void {
|
||||
const viewContainer = this.getViewContainer(id);
|
||||
if (viewContainer) {
|
||||
// Update the composite bar by adding
|
||||
this.compositeBar.addComposite(viewContainer);
|
||||
this.compositeBar.activateComposite(viewContainer.id);
|
||||
|
||||
if (viewContainer.hideIfEmpty) {
|
||||
const viewContainerModel = this.viewDescriptorService.getViewContainerModel(viewContainer);
|
||||
if (viewContainerModel.activeViewDescriptors.length === 0) {
|
||||
this.hideComposite(viewletDescriptor.id); // Update the composite bar by hiding
|
||||
this.hideComposite(viewContainer.id); // Update the composite bar by hiding
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
showActivity(viewletOrActionId: string, badge: IBadge, clazz?: string, priority?: number): IDisposable {
|
||||
if (this.viewletService.getViewlet(viewletOrActionId)) {
|
||||
return this.compositeBar.showActivity(viewletOrActionId, badge, clazz, priority);
|
||||
showActivity(viewContainerOrActionId: string, badge: IBadge, clazz?: string, priority?: number): IDisposable {
|
||||
if (this.getViewContainer(viewContainerOrActionId)) {
|
||||
return this.compositeBar.showActivity(viewContainerOrActionId, badge, clazz, priority);
|
||||
}
|
||||
|
||||
if (viewletOrActionId === GLOBAL_ACTIVITY_ID) {
|
||||
if (viewContainerOrActionId === GLOBAL_ACTIVITY_ID) {
|
||||
return this.showGlobalActivity(badge, clazz, priority);
|
||||
}
|
||||
|
||||
@@ -342,7 +358,7 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
this.installMenubar();
|
||||
}
|
||||
|
||||
// Viewlets action bar
|
||||
// View Containers action bar
|
||||
this.compositeBar.create(this.content);
|
||||
|
||||
// Global action bar
|
||||
@@ -444,19 +460,20 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
this.globalActivityActionBar.push(this.globalActivityAction);
|
||||
}
|
||||
|
||||
private getCompositeActions(compositeId: string): { activityAction: ViewletActivityAction, pinnedAction: ToggleCompositePinnedAction } {
|
||||
private getCompositeActions(compositeId: string): { activityAction: ViewContainerActivityAction, pinnedAction: ToggleCompositePinnedAction } {
|
||||
let compositeActions = this.compositeActions.get(compositeId);
|
||||
if (!compositeActions) {
|
||||
const viewlet = this.viewletService.getViewlet(compositeId);
|
||||
if (viewlet) {
|
||||
const viewContainer = this.getViewContainer(compositeId);
|
||||
if (viewContainer) {
|
||||
const viewContainerModel = this.viewDescriptorService.getViewContainerModel(viewContainer);
|
||||
compositeActions = {
|
||||
activityAction: this.instantiationService.createInstance(ViewletActivityAction, viewlet),
|
||||
pinnedAction: new ToggleCompositePinnedAction(viewlet, this.compositeBar)
|
||||
activityAction: this.instantiationService.createInstance(ViewContainerActivityAction, this.toActivity(viewContainer, viewContainerModel)),
|
||||
pinnedAction: new ToggleCompositePinnedAction(viewContainer, this.compositeBar)
|
||||
};
|
||||
} else {
|
||||
const cachedComposite = this.cachedViewlets.filter(c => c.id === compositeId)[0];
|
||||
const cachedComposite = this.cachedViewContainers.filter(c => c.id === compositeId)[0];
|
||||
compositeActions = {
|
||||
activityAction: this.instantiationService.createInstance(PlaceHolderViewletActivityAction, compositeId, cachedComposite?.icon),
|
||||
activityAction: this.instantiationService.createInstance(PlaceHolderViewContainerActivityAction, ActivitybarPart.toActivity(compositeId, compositeId, cachedComposite?.icon, undefined)),
|
||||
pinnedAction: new PlaceHolderToggleCompositePinnedAction(compositeId, this.compositeBar)
|
||||
};
|
||||
}
|
||||
@@ -467,28 +484,27 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
return compositeActions;
|
||||
}
|
||||
|
||||
private onDidRegisterViewlets(viewlets: ViewletDescriptor[]): void {
|
||||
for (const viewlet of viewlets) {
|
||||
const cachedViewlet = this.cachedViewlets.filter(({ id }) => id === viewlet.id)[0];
|
||||
const activeViewlet = this.viewletService.getActiveViewlet();
|
||||
const isActive = activeViewlet?.getId() === viewlet.id;
|
||||
private onDidRegisterViewContainers(viewContainers: ReadonlyArray<ViewContainer>): void {
|
||||
for (const viewContainer of viewContainers) {
|
||||
const cachedViewContainer = this.cachedViewContainers.filter(({ id }) => id === viewContainer.id)[0];
|
||||
const visibleViewContainer = this.viewsService.getVisibleViewContainer(this.location);
|
||||
const isActive = visibleViewContainer?.id === viewContainer.id;
|
||||
|
||||
if (isActive || !this.shouldBeHidden(viewlet.id, cachedViewlet)) {
|
||||
this.compositeBar.addComposite(viewlet);
|
||||
if (isActive || !this.shouldBeHidden(viewContainer.id, cachedViewContainer)) {
|
||||
this.compositeBar.addComposite(viewContainer);
|
||||
|
||||
// Pin it by default if it is new
|
||||
if (!cachedViewlet) {
|
||||
this.compositeBar.pin(viewlet.id);
|
||||
if (!cachedViewContainer) {
|
||||
this.compositeBar.pin(viewContainer.id);
|
||||
}
|
||||
|
||||
if (isActive) {
|
||||
this.compositeBar.activateComposite(viewlet.id);
|
||||
this.compositeBar.activateComposite(viewContainer.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const viewlet of viewlets) {
|
||||
const viewContainer = this.getViewContainer(viewlet.id)!;
|
||||
for (const viewContainer of viewContainers) {
|
||||
const viewContainerModel = this.viewDescriptorService.getViewContainerModel(viewContainer);
|
||||
this.updateActivity(viewContainer, viewContainerModel);
|
||||
this.onDidChangeActiveViews(viewContainer, viewContainerModel);
|
||||
@@ -497,38 +513,53 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
disposables.add(viewContainerModel.onDidChangeContainerInfo(() => this.updateActivity(viewContainer, viewContainerModel)));
|
||||
disposables.add(viewContainerModel.onDidChangeActiveViewDescriptors(() => this.onDidChangeActiveViews(viewContainer, viewContainerModel)));
|
||||
|
||||
this.viewletDisposables.set(viewlet.id, disposables);
|
||||
this.viewContainerDisposables.set(viewContainer.id, disposables);
|
||||
}
|
||||
}
|
||||
|
||||
private onDidDeregisterViewlet(viewletId: string): void {
|
||||
const disposable = this.viewletDisposables.get(viewletId);
|
||||
private onDidDeregisterViewContainer(viewContainer: ViewContainer): void {
|
||||
const disposable = this.viewContainerDisposables.get(viewContainer.id);
|
||||
if (disposable) {
|
||||
disposable.dispose();
|
||||
}
|
||||
|
||||
this.viewletDisposables.delete(viewletId);
|
||||
this.hideComposite(viewletId);
|
||||
this.viewContainerDisposables.delete(viewContainer.id);
|
||||
this.hideComposite(viewContainer.id);
|
||||
}
|
||||
|
||||
private updateActivity(viewContainer: ViewContainer, viewContainerModel: IViewContainerModel): void {
|
||||
|
||||
const activity: IActivity = {
|
||||
id: viewContainer.id,
|
||||
name: viewContainerModel.title,
|
||||
iconUrl: URI.isUri(viewContainerModel.icon) ? viewContainerModel.icon : undefined,
|
||||
cssClass: isString(viewContainerModel.icon) ? viewContainerModel.icon : undefined,
|
||||
keybindingId: viewContainer.focusCommand?.id || viewContainer.id
|
||||
};
|
||||
|
||||
const activity: IActivity = this.toActivity(viewContainer, viewContainerModel);
|
||||
const { activityAction, pinnedAction } = this.getCompositeActions(viewContainer.id);
|
||||
activityAction.setActivity(activity);
|
||||
activityAction.updateActivity(activity);
|
||||
|
||||
if (pinnedAction instanceof PlaceHolderToggleCompositePinnedAction) {
|
||||
pinnedAction.setActivity(activity);
|
||||
}
|
||||
|
||||
this.saveCachedViewlets();
|
||||
this.saveCachedViewContainers();
|
||||
}
|
||||
|
||||
private toActivity({ id, focusCommand }: ViewContainer, { icon, title: name }: IViewContainerModel): IActivity {
|
||||
return ActivitybarPart.toActivity(id, name, icon, focusCommand?.id || id);
|
||||
}
|
||||
|
||||
private static toActivity(id: string, name: string, icon: URI | string | undefined, keybindingId: string | undefined): IActivity {
|
||||
let cssClass: string | undefined = undefined;
|
||||
let iconUrl: URI | undefined = undefined;
|
||||
if (URI.isUri(icon)) {
|
||||
iconUrl = icon;
|
||||
cssClass = `activity-${id.replace(/\./g, '-')}`;
|
||||
const iconClass = `.monaco-workbench .activitybar .monaco-action-bar .action-label.${cssClass}`;
|
||||
createCSSRule(iconClass, `
|
||||
mask: ${asCSSUrl(icon)} no-repeat 50% 50%;
|
||||
mask-size: 24px;
|
||||
-webkit-mask: ${asCSSUrl(icon)} no-repeat 50% 50%;
|
||||
-webkit-mask-size: 24px;
|
||||
`);
|
||||
} else if (isString(icon)) {
|
||||
cssClass = icon;
|
||||
}
|
||||
return { id, name, cssClass, iconUrl, keybindingId };
|
||||
}
|
||||
|
||||
private onDidChangeActiveViews(viewContainer: ViewContainer, viewContainerModel: IViewContainerModel): void {
|
||||
@@ -539,21 +570,21 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
}
|
||||
}
|
||||
|
||||
private shouldBeHidden(viewletId: string, cachedViewlet?: ICachedViewlet): boolean {
|
||||
const viewContainer = this.getViewContainer(viewletId);
|
||||
private shouldBeHidden(viewContainerId: string, cachedViewContainer?: ICachedViewContainer): boolean {
|
||||
const viewContainer = this.getViewContainer(viewContainerId);
|
||||
if (!viewContainer || !viewContainer.hideIfEmpty) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return cachedViewlet?.views && cachedViewlet.views.length
|
||||
? cachedViewlet.views.every(({ when }) => !!when && !this.contextKeyService.contextMatchesRules(ContextKeyExpr.deserialize(when)))
|
||||
: viewletId === TEST_VIEW_CONTAINER_ID /* Hide Test viewlet for the first time or it had no views registered before */;
|
||||
return cachedViewContainer?.views && cachedViewContainer.views.length
|
||||
? cachedViewContainer.views.every(({ when }) => !!when && !this.contextKeyService.contextMatchesRules(ContextKeyExpr.deserialize(when)))
|
||||
: viewContainerId === TEST_VIEW_CONTAINER_ID /* Hide Test view container for the first time or it had no views registered before */;
|
||||
}
|
||||
|
||||
private removeNotExistingComposites(): void {
|
||||
const viewlets = this.viewletService.getViewlets();
|
||||
for (const { id } of this.cachedViewlets) {
|
||||
if (viewlets.every(viewlet => viewlet.id !== id)) {
|
||||
const viewContainers = this.getViewContainers();
|
||||
for (const { id } of this.cachedViewContainers) {
|
||||
if (viewContainers.every(viewContainer => viewContainer.id !== id)) {
|
||||
this.hideComposite(id);
|
||||
}
|
||||
}
|
||||
@@ -570,15 +601,20 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
}
|
||||
}
|
||||
|
||||
getPinnedViewletIds(): string[] {
|
||||
getPinnedViewContainerIds(): string[] {
|
||||
const pinnedCompositeIds = this.compositeBar.getPinnedComposites().map(v => v.id);
|
||||
|
||||
return this.viewletService.getViewlets()
|
||||
return this.getViewContainers()
|
||||
.filter(v => this.compositeBar.isPinned(v.id))
|
||||
.sort((v1, v2) => pinnedCompositeIds.indexOf(v1.id) - pinnedCompositeIds.indexOf(v2.id))
|
||||
.map(v => v.id);
|
||||
}
|
||||
|
||||
getVisibleViewContainerIds(): string[] {
|
||||
return this.compositeBar.getVisibleComposites()
|
||||
.filter(v => this.viewsService.getVisibleViewContainer(this.location)?.id === v.id || this.compositeBar.isPinned(v.id))
|
||||
.map(v => v.id);
|
||||
}
|
||||
|
||||
layout(width: number, height: number): void {
|
||||
if (!this.layoutService.isVisible(Parts.ACTIVITYBAR_PART)) {
|
||||
return;
|
||||
@@ -601,27 +637,32 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
this.compositeBar.layout(new Dimension(width, availableHeight));
|
||||
}
|
||||
|
||||
private getViewContainer(viewletId: string): ViewContainer | undefined {
|
||||
return this.viewDescriptorService.getViewContainerById(viewletId) || undefined;
|
||||
private getViewContainer(id: string): ViewContainer | undefined {
|
||||
const viewContainer = this.viewDescriptorService.getViewContainerById(id);
|
||||
return viewContainer && this.viewDescriptorService.getViewContainerLocation(viewContainer) === this.location ? viewContainer : undefined;
|
||||
}
|
||||
|
||||
private getViewContainers(): ReadonlyArray<ViewContainer> {
|
||||
return this.viewDescriptorService.getViewContainersByLocation(this.location);
|
||||
}
|
||||
|
||||
private onDidStorageChange(e: IWorkspaceStorageChangeEvent): void {
|
||||
if (e.key === ActivitybarPart.PINNED_VIEWLETS && e.scope === StorageScope.GLOBAL
|
||||
&& this.pinnedViewletsValue !== this.getStoredPinnedViewletsValue() /* This checks if current window changed the value or not */) {
|
||||
this._pinnedViewletsValue = undefined;
|
||||
if (e.key === ActivitybarPart.PINNED_VIEW_CONTAINERS && e.scope === StorageScope.GLOBAL
|
||||
&& this.pinnedViewContainersValue !== this.getStoredPinnedViewContainersValue() /* This checks if current window changed the value or not */) {
|
||||
this._pinnedViewContainersValue = undefined;
|
||||
const newCompositeItems: ICompositeBarItem[] = [];
|
||||
const compositeItems = this.compositeBar.getCompositeBarItems();
|
||||
const cachedViewlets = this.getCachedViewlets();
|
||||
const cachedViewContainers = this.getCachedViewContainers();
|
||||
|
||||
for (const cachedViewlet of cachedViewlets) {
|
||||
for (const cachedViewContainer of cachedViewContainers) {
|
||||
// Add and update existing items
|
||||
const existingItem = compositeItems.filter(({ id }) => id === cachedViewlet.id)[0];
|
||||
const existingItem = compositeItems.filter(({ id }) => id === cachedViewContainer.id)[0];
|
||||
if (existingItem) {
|
||||
newCompositeItems.push({
|
||||
id: existingItem.id,
|
||||
name: existingItem.name,
|
||||
order: existingItem.order,
|
||||
pinned: cachedViewlet.pinned,
|
||||
pinned: cachedViewContainer.pinned,
|
||||
visible: existingItem.visible
|
||||
});
|
||||
}
|
||||
@@ -638,8 +679,8 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
}
|
||||
}
|
||||
|
||||
private saveCachedViewlets(): void {
|
||||
const state: ICachedViewlet[] = [];
|
||||
private saveCachedViewContainers(): void {
|
||||
const state: ICachedViewContainer[] = [];
|
||||
|
||||
const compositeItems = this.compositeBar.getCompositeBarItems();
|
||||
for (const compositeItem of compositeItems) {
|
||||
@@ -665,32 +706,32 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
}
|
||||
}
|
||||
|
||||
this.storeCachedViewletsState(state);
|
||||
this.storeCachedViewContainersState(state);
|
||||
}
|
||||
|
||||
private getCachedViewlets(): ICachedViewlet[] {
|
||||
const cachedViewlets: ICachedViewlet[] = this.getPinnedViewlets();
|
||||
for (const placeholderViewlet of this.getPlaceholderViewlets()) {
|
||||
const cachedViewlet = cachedViewlets.filter(cached => cached.id === placeholderViewlet.id)[0];
|
||||
if (cachedViewlet) {
|
||||
cachedViewlet.name = placeholderViewlet.name;
|
||||
cachedViewlet.icon = placeholderViewlet.iconCSS ? placeholderViewlet.iconCSS :
|
||||
placeholderViewlet.iconUrl ? URI.revive(placeholderViewlet.iconUrl) : undefined;
|
||||
cachedViewlet.views = placeholderViewlet.views;
|
||||
private getCachedViewContainers(): ICachedViewContainer[] {
|
||||
const cachedViewContainers: ICachedViewContainer[] = this.getPinnedViewContainers();
|
||||
for (const placeholderViewContainer of this.getPlaceholderViewContainers()) {
|
||||
const cachedViewContainer = cachedViewContainers.filter(cached => cached.id === placeholderViewContainer.id)[0];
|
||||
if (cachedViewContainer) {
|
||||
cachedViewContainer.name = placeholderViewContainer.name;
|
||||
cachedViewContainer.icon = placeholderViewContainer.iconCSS ? placeholderViewContainer.iconCSS :
|
||||
placeholderViewContainer.iconUrl ? URI.revive(placeholderViewContainer.iconUrl) : undefined;
|
||||
cachedViewContainer.views = placeholderViewContainer.views;
|
||||
}
|
||||
}
|
||||
|
||||
return cachedViewlets;
|
||||
return cachedViewContainers;
|
||||
}
|
||||
|
||||
private storeCachedViewletsState(cachedViewlets: ICachedViewlet[]): void {
|
||||
this.setPinnedViewlets(cachedViewlets.map(({ id, pinned, visible, order }) => (<IPinnedViewlet>{
|
||||
private storeCachedViewContainersState(cachedViewContainers: ICachedViewContainer[]): void {
|
||||
this.setPinnedViewContainers(cachedViewContainers.map(({ id, pinned, visible, order }) => (<IPinnedViewContainer>{
|
||||
id,
|
||||
pinned,
|
||||
visible,
|
||||
order
|
||||
})));
|
||||
this.setPlaceholderViewlets(cachedViewlets.map(({ id, icon, name, views }) => (<IPlaceholderViewlet>{
|
||||
this.setPlaceholderViewContainers(cachedViewContainers.map(({ id, icon, name, views }) => (<IPlaceholderViewContainer>{
|
||||
id,
|
||||
iconUrl: URI.isUri(icon) ? icon : undefined,
|
||||
iconCSS: isString(icon) ? icon : undefined,
|
||||
@@ -699,80 +740,80 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
})));
|
||||
}
|
||||
|
||||
private getPinnedViewlets(): IPinnedViewlet[] {
|
||||
return JSON.parse(this.pinnedViewletsValue);
|
||||
private getPinnedViewContainers(): IPinnedViewContainer[] {
|
||||
return JSON.parse(this.pinnedViewContainersValue);
|
||||
}
|
||||
|
||||
private setPinnedViewlets(pinnedViewlets: IPinnedViewlet[]): void {
|
||||
this.pinnedViewletsValue = JSON.stringify(pinnedViewlets);
|
||||
private setPinnedViewContainers(pinnedViewContainers: IPinnedViewContainer[]): void {
|
||||
this.pinnedViewContainersValue = JSON.stringify(pinnedViewContainers);
|
||||
}
|
||||
|
||||
private _pinnedViewletsValue: string | undefined;
|
||||
private get pinnedViewletsValue(): string {
|
||||
if (!this._pinnedViewletsValue) {
|
||||
this._pinnedViewletsValue = this.getStoredPinnedViewletsValue();
|
||||
private _pinnedViewContainersValue: string | undefined;
|
||||
private get pinnedViewContainersValue(): string {
|
||||
if (!this._pinnedViewContainersValue) {
|
||||
this._pinnedViewContainersValue = this.getStoredPinnedViewContainersValue();
|
||||
}
|
||||
|
||||
return this._pinnedViewletsValue;
|
||||
return this._pinnedViewContainersValue;
|
||||
}
|
||||
|
||||
private set pinnedViewletsValue(pinnedViewletsValue: string) {
|
||||
if (this.pinnedViewletsValue !== pinnedViewletsValue) {
|
||||
this._pinnedViewletsValue = pinnedViewletsValue;
|
||||
this.setStoredPinnedViewletsValue(pinnedViewletsValue);
|
||||
private set pinnedViewContainersValue(pinnedViewContainersValue: string) {
|
||||
if (this.pinnedViewContainersValue !== pinnedViewContainersValue) {
|
||||
this._pinnedViewContainersValue = pinnedViewContainersValue;
|
||||
this.setStoredPinnedViewContainersValue(pinnedViewContainersValue);
|
||||
}
|
||||
}
|
||||
|
||||
private getStoredPinnedViewletsValue(): string {
|
||||
return this.storageService.get(ActivitybarPart.PINNED_VIEWLETS, StorageScope.GLOBAL, '[]');
|
||||
private getStoredPinnedViewContainersValue(): string {
|
||||
return this.storageService.get(ActivitybarPart.PINNED_VIEW_CONTAINERS, StorageScope.GLOBAL, '[]');
|
||||
}
|
||||
|
||||
private setStoredPinnedViewletsValue(value: string): void {
|
||||
this.storageService.store(ActivitybarPart.PINNED_VIEWLETS, value, StorageScope.GLOBAL);
|
||||
private setStoredPinnedViewContainersValue(value: string): void {
|
||||
this.storageService.store(ActivitybarPart.PINNED_VIEW_CONTAINERS, value, StorageScope.GLOBAL);
|
||||
}
|
||||
|
||||
private getPlaceholderViewlets(): IPlaceholderViewlet[] {
|
||||
return JSON.parse(this.placeholderViewletsValue);
|
||||
private getPlaceholderViewContainers(): IPlaceholderViewContainer[] {
|
||||
return JSON.parse(this.placeholderViewContainersValue);
|
||||
}
|
||||
|
||||
private setPlaceholderViewlets(placeholderViewlets: IPlaceholderViewlet[]): void {
|
||||
this.placeholderViewletsValue = JSON.stringify(placeholderViewlets);
|
||||
private setPlaceholderViewContainers(placeholderViewContainers: IPlaceholderViewContainer[]): void {
|
||||
this.placeholderViewContainersValue = JSON.stringify(placeholderViewContainers);
|
||||
}
|
||||
|
||||
private _placeholderViewletsValue: string | undefined;
|
||||
private get placeholderViewletsValue(): string {
|
||||
if (!this._placeholderViewletsValue) {
|
||||
this._placeholderViewletsValue = this.getStoredPlaceholderViewletsValue();
|
||||
private _placeholderViewContainersValue: string | undefined;
|
||||
private get placeholderViewContainersValue(): string {
|
||||
if (!this._placeholderViewContainersValue) {
|
||||
this._placeholderViewContainersValue = this.getStoredPlaceholderViewContainersValue();
|
||||
}
|
||||
|
||||
return this._placeholderViewletsValue;
|
||||
return this._placeholderViewContainersValue;
|
||||
}
|
||||
|
||||
private set placeholderViewletsValue(placeholderViewletsValue: string) {
|
||||
if (this.placeholderViewletsValue !== placeholderViewletsValue) {
|
||||
this._placeholderViewletsValue = placeholderViewletsValue;
|
||||
this.setStoredPlaceholderViewletsValue(placeholderViewletsValue);
|
||||
private set placeholderViewContainersValue(placeholderViewContainesValue: string) {
|
||||
if (this.placeholderViewContainersValue !== placeholderViewContainesValue) {
|
||||
this._placeholderViewContainersValue = placeholderViewContainesValue;
|
||||
this.setStoredPlaceholderViewContainersValue(placeholderViewContainesValue);
|
||||
}
|
||||
}
|
||||
|
||||
private getStoredPlaceholderViewletsValue(): string {
|
||||
return this.storageService.get(ActivitybarPart.PLACEHOLDER_VIEWLETS, StorageScope.GLOBAL, '[]');
|
||||
private getStoredPlaceholderViewContainersValue(): string {
|
||||
return this.storageService.get(ActivitybarPart.PLACEHOLDER_VIEW_CONTAINERS, StorageScope.GLOBAL, '[]');
|
||||
}
|
||||
|
||||
private setStoredPlaceholderViewletsValue(value: string): void {
|
||||
this.storageService.store(ActivitybarPart.PLACEHOLDER_VIEWLETS, value, StorageScope.GLOBAL);
|
||||
private setStoredPlaceholderViewContainersValue(value: string): void {
|
||||
this.storageService.store(ActivitybarPart.PLACEHOLDER_VIEW_CONTAINERS, value, StorageScope.GLOBAL);
|
||||
}
|
||||
|
||||
private migrateFromOldCachedViewletsValue(): void {
|
||||
private migrateFromOldCachedViewContainersValue(): void {
|
||||
const value = this.storageService.get('workbench.activity.pinnedViewlets', StorageScope.GLOBAL);
|
||||
if (value !== undefined) {
|
||||
const storedStates: Array<string | ICachedViewlet> = JSON.parse(value);
|
||||
const cachedViewlets = storedStates.map(c => {
|
||||
const serialized: ICachedViewlet = typeof c === 'string' /* migration from pinned states to composites states */ ? { id: c, pinned: true, order: undefined, visible: true, name: undefined, icon: undefined, views: undefined } : c;
|
||||
const storedStates: Array<string | ICachedViewContainer> = JSON.parse(value);
|
||||
const cachedViewContainers = storedStates.map(c => {
|
||||
const serialized: ICachedViewContainer = typeof c === 'string' /* migration from pinned states to composites states */ ? { id: c, pinned: true, order: undefined, visible: true, name: undefined, icon: undefined, views: undefined } : c;
|
||||
serialized.visible = isUndefinedOrNull(serialized.visible) ? true : serialized.visible;
|
||||
return serialized;
|
||||
});
|
||||
this.storeCachedViewletsState(cachedViewlets);
|
||||
this.storeCachedViewContainersState(cachedViewContainers);
|
||||
this.storageService.remove('workbench.activity.pinnedViewlets', StorageScope.GLOBAL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,11 +37,11 @@ export class CompositeDragAndDrop implements ICompositeDragAndDrop {
|
||||
constructor(
|
||||
private viewDescriptorService: IViewDescriptorService,
|
||||
private targetContainerLocation: ViewContainerLocation,
|
||||
private openComposite: (id: string, focus?: boolean) => Promise<IPaneComposite | undefined>,
|
||||
private openComposite: (id: string, focus?: boolean) => Promise<IPaneComposite | null>,
|
||||
private moveComposite: (from: string, to: string, before?: Before2D) => void,
|
||||
) { }
|
||||
|
||||
drop(data: CompositeDragAndDropData, targetCompositeId: string, originalEvent: DragEvent, before?: Before2D): void {
|
||||
drop(data: CompositeDragAndDropData, targetCompositeId: string | undefined, originalEvent: DragEvent, before?: Before2D): void {
|
||||
const dragData = data.getData();
|
||||
|
||||
if (dragData.type === 'composite') {
|
||||
@@ -50,7 +50,9 @@ export class CompositeDragAndDrop implements ICompositeDragAndDrop {
|
||||
|
||||
// ... on the same composite bar
|
||||
if (currentLocation === this.targetContainerLocation) {
|
||||
this.moveComposite(dragData.id, targetCompositeId, before);
|
||||
if (targetCompositeId) {
|
||||
this.moveComposite(dragData.id, targetCompositeId, before);
|
||||
}
|
||||
}
|
||||
// ... on a different composite bar
|
||||
else {
|
||||
@@ -60,7 +62,10 @@ export class CompositeDragAndDrop implements ICompositeDragAndDrop {
|
||||
}
|
||||
|
||||
this.viewDescriptorService.moveViewContainerToLocation(currentContainer, this.targetContainerLocation);
|
||||
this.moveComposite(currentContainer.id, targetCompositeId, before);
|
||||
|
||||
if (targetCompositeId) {
|
||||
this.moveComposite(currentContainer.id, targetCompositeId, before);
|
||||
}
|
||||
|
||||
this.openComposite(currentContainer.id, true);
|
||||
}
|
||||
@@ -74,7 +79,9 @@ export class CompositeDragAndDrop implements ICompositeDragAndDrop {
|
||||
|
||||
const newContainer = this.viewDescriptorService.getViewContainerByViewId(viewToMove.id)!;
|
||||
|
||||
this.moveComposite(newContainer.id, targetCompositeId, before);
|
||||
if (targetCompositeId) {
|
||||
this.moveComposite(newContainer.id, targetCompositeId, before);
|
||||
}
|
||||
|
||||
this.openComposite(newContainer.id, true).then(composite => {
|
||||
if (composite) {
|
||||
@@ -140,7 +147,7 @@ export interface ICompositeBarOptions {
|
||||
getOnCompositeClickAction: (compositeId: string) => Action;
|
||||
getContextMenuActions: () => Action[];
|
||||
getContextMenuActionsForComposite: (compositeId: string) => Action[];
|
||||
openComposite: (compositeId: string) => Promise<IComposite | undefined>;
|
||||
openComposite: (compositeId: string) => Promise<IComposite | null>;
|
||||
getDefaultCompositeId: () => string;
|
||||
hidePart: () => void;
|
||||
}
|
||||
@@ -188,6 +195,10 @@ export class CompositeBar extends Widget implements ICompositeBar {
|
||||
return this.model.pinnedItems;
|
||||
}
|
||||
|
||||
getVisibleComposites(): ICompositeBarItem[] {
|
||||
return this.model.visibleItems;
|
||||
}
|
||||
|
||||
create(parent: HTMLElement): HTMLElement {
|
||||
const actionBarDiv = parent.appendChild($('.composite-bar'));
|
||||
this.compositeSwitcherBar = this._register(new ActionBar(actionBarDiv, {
|
||||
@@ -264,7 +275,8 @@ export class CompositeBar extends Widget implements ICompositeBar {
|
||||
// Add to the model
|
||||
if (this.model.add(id, name, order)) {
|
||||
this.computeSizes([this.model.findItem(id)]);
|
||||
this.updateCompositeSwitcher();
|
||||
// Set timeout helps prevent flicker
|
||||
setTimeout(() => this.updateCompositeSwitcher(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -526,7 +538,7 @@ export class CompositeBar extends Widget implements ICompositeBar {
|
||||
});
|
||||
|
||||
// Add overflow action as needed
|
||||
if ((visibleCompositesChange && overflows) || compositeSwitcherBar.length() === 0) {
|
||||
if ((visibleCompositesChange && overflows)) {
|
||||
this.compositeOverflowAction = this.instantiationService.createInstance(CompositeOverflowActivityAction, () => {
|
||||
if (this.compositeOverflowActionViewItem) {
|
||||
this.compositeOverflowActionViewItem.showMenu();
|
||||
|
||||
@@ -91,7 +91,7 @@ class Item extends BreadcrumbsItem {
|
||||
fileKind: this.element.kind,
|
||||
fileDecorations: { colors: this.options.showDecorationColors, badges: false },
|
||||
});
|
||||
dom.addClass(container, FileKind[this.element.kind].toLowerCase());
|
||||
container.classList.add(FileKind[this.element.kind].toLowerCase());
|
||||
this._disposables.add(label);
|
||||
|
||||
} else if (this.element instanceof OutlineModel) {
|
||||
@@ -113,7 +113,7 @@ class Item extends BreadcrumbsItem {
|
||||
let icon = document.createElement('div');
|
||||
icon.className = SymbolKinds.toCssClassName(this.element.symbol.kind);
|
||||
container.appendChild(icon);
|
||||
dom.addClass(container, 'shows-symbol-icon');
|
||||
container.classList.add('shows-symbol-icon');
|
||||
}
|
||||
let label = new IconLabel(container);
|
||||
let title = this.element.symbol.name.replace(/\r|\n|\r\n/g, '\u23CE');
|
||||
@@ -183,7 +183,7 @@ export class BreadcrumbsControl {
|
||||
@IBreadcrumbsService breadcrumbsService: IBreadcrumbsService,
|
||||
) {
|
||||
this.domNode = document.createElement('div');
|
||||
dom.addClass(this.domNode, 'breadcrumbs-control');
|
||||
this.domNode.classList.add('breadcrumbs-control');
|
||||
dom.append(container, this.domNode);
|
||||
|
||||
this._cfUseQuickPick = BreadcrumbsConfig.UseQuickPick.bindTo(_configurationService);
|
||||
@@ -221,13 +221,13 @@ export class BreadcrumbsControl {
|
||||
}
|
||||
|
||||
isHidden(): boolean {
|
||||
return dom.hasClass(this.domNode, 'hidden');
|
||||
return this.domNode.classList.contains('hidden');
|
||||
}
|
||||
|
||||
hide(): void {
|
||||
this._breadcrumbsDisposables.clear();
|
||||
this._ckBreadcrumbsVisible.set(false);
|
||||
dom.toggleClass(this.domNode, 'hidden', true);
|
||||
this.domNode.classList.toggle('hidden', true);
|
||||
}
|
||||
|
||||
update(): boolean {
|
||||
@@ -251,7 +251,7 @@ export class BreadcrumbsControl {
|
||||
}
|
||||
}
|
||||
|
||||
dom.toggleClass(this.domNode, 'hidden', false);
|
||||
this.domNode.classList.toggle('hidden', false);
|
||||
this._ckBreadcrumbsVisible.set(true);
|
||||
this._ckBreadcrumbsPossible.set(true);
|
||||
|
||||
@@ -263,8 +263,8 @@ export class BreadcrumbsControl {
|
||||
this._textResourceConfigurationService,
|
||||
this._workspaceService
|
||||
);
|
||||
dom.toggleClass(this.domNode, 'relative-path', model.isRelative());
|
||||
dom.toggleClass(this.domNode, 'backslash-path', this._labelService.getSeparator(uri.scheme, uri.authority) === '\\');
|
||||
this.domNode.classList.toggle('relative-path', model.isRelative());
|
||||
this.domNode.classList.toggle('backslash-path', this._labelService.getSeparator(uri.scheme, uri.authority) === '\\');
|
||||
|
||||
const updateBreadcrumbs = () => {
|
||||
const showIcons = this._cfShowIcons.getValue();
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { compareFileNames } from 'vs/base/common/comparers';
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
@@ -375,11 +374,11 @@ export class BreadcrumbsFilePicker extends BreadcrumbsPicker {
|
||||
_createTree(container: HTMLElement) {
|
||||
|
||||
// tree icon theme specials
|
||||
dom.addClass(this._treeContainer, 'file-icon-themable-tree');
|
||||
dom.addClass(this._treeContainer, 'show-file-icons');
|
||||
this._treeContainer.classList.add('file-icon-themable-tree');
|
||||
this._treeContainer.classList.add('show-file-icons');
|
||||
const onFileIconThemeChange = (fileIconTheme: IFileIconTheme) => {
|
||||
dom.toggleClass(this._treeContainer, 'align-icons-and-twisties', fileIconTheme.hasFileIcons && !fileIconTheme.hasFolderIcons);
|
||||
dom.toggleClass(this._treeContainer, 'hide-arrows', fileIconTheme.hidesExplorerArrows === true);
|
||||
this._treeContainer.classList.toggle('align-icons-and-twisties', fileIconTheme.hasFileIcons && !fileIconTheme.hasFolderIcons);
|
||||
this._treeContainer.classList.toggle('hide-arrows', fileIconTheme.hidesExplorerArrows === true);
|
||||
};
|
||||
this._disposables.add(this._themeService.onDidFileIconThemeChange(onFileIconThemeChange));
|
||||
onFileIconThemeChange(this._themeService.getFileIconTheme());
|
||||
|
||||
@@ -123,7 +123,7 @@ export class EditorControl extends Disposable {
|
||||
private doInstantiateEditorPane(descriptor: IEditorDescriptor): BaseEditor {
|
||||
|
||||
// Return early if already instantiated
|
||||
const existingEditorPane = this.editorPanes.filter(editorPane => descriptor.describes(editorPane))[0];
|
||||
const existingEditorPane = this.editorPanes.find(editorPane => descriptor.describes(editorPane));
|
||||
if (existingEditorPane) {
|
||||
return existingEditorPane;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ import { GroupDirection, MergeGroupMode } from 'vs/workbench/services/editor/com
|
||||
import { toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { RunOnceScheduler } from 'vs/base/common/async';
|
||||
import { find } from 'vs/base/common/arrays';
|
||||
import { DataTransfers } from 'vs/base/browser/dnd';
|
||||
import { VSBuffer } from 'vs/base/common/buffer';
|
||||
import { IFileDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||
@@ -600,7 +599,7 @@ export class EditorDropTarget extends Themable {
|
||||
|
||||
private findTargetGroupView(child: HTMLElement): IEditorGroupView | undefined {
|
||||
const groups = this.accessor.groups;
|
||||
return find(groups, groupView => isAncestor(child, groupView.element) || this.delegate.groupContainsPredicate?.(groupView));
|
||||
return groups.find(groupView => isAncestor(child, groupView.element) || this.delegate.groupContainsPredicate?.(groupView));
|
||||
}
|
||||
|
||||
private updateContainer(isDraggedOver: boolean): void {
|
||||
|
||||
@@ -1604,7 +1604,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
|
||||
// Forward to controls
|
||||
this.layoutTitleAreaControl(width);
|
||||
this.editorControl.layout(new Dimension(this.dimension.width, this.dimension.height - this.titleAreaControl.getPreferredHeight()));
|
||||
this.editorControl.layout(new Dimension(this.dimension.width, Math.max(0, this.dimension.height - this.titleAreaControl.getPreferredHeight())));
|
||||
}
|
||||
|
||||
private layoutTitleAreaControl(width: number): void {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
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 { Dimension, isAncestor, toggleClass, addClass, $, EventHelper } from 'vs/base/browser/dom';
|
||||
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, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
@@ -830,19 +830,23 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
|
||||
addClass(overlay, 'drop-block-overlay');
|
||||
parent.appendChild(overlay);
|
||||
|
||||
CompositeDragAndDropObserver.INSTANCE.registerTarget(this.element, {
|
||||
onDragOver: e => {
|
||||
if (e.eventData.dataTransfer) {
|
||||
e.eventData.dataTransfer.dropEffect = 'none';
|
||||
}
|
||||
},
|
||||
this._register(CompositeDragAndDropObserver.INSTANCE.registerTarget(this.element, {
|
||||
onDragStart: e => {
|
||||
toggleClass(overlay, 'visible', true);
|
||||
},
|
||||
onDragEnd: e => {
|
||||
toggleClass(overlay, 'visible', false);
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
||||
this._register(CompositeDragAndDropObserver.INSTANCE.registerTarget(overlay, {
|
||||
onDragOver: e => {
|
||||
EventHelper.stop(e.eventData, true);
|
||||
if (e.eventData.dataTransfer) {
|
||||
e.eventData.dataTransfer.dropEffect = 'none';
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
return this.container;
|
||||
}
|
||||
|
||||
@@ -50,7 +50,6 @@ import { IAccessibilityService, AccessibilitySupport } from 'vs/platform/accessi
|
||||
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
|
||||
import { IStatusbarEntryAccessor, IStatusbarService, StatusbarAlignment, IStatusbarEntry } from 'vs/workbench/services/statusbar/common/statusbar';
|
||||
import { IMarker, IMarkerService, MarkerSeverity, IMarkerData } from 'vs/platform/markers/common/markers';
|
||||
import { find } from 'vs/base/common/arrays';
|
||||
import { STATUS_BAR_PROMINENT_ITEM_BACKGROUND, STATUS_BAR_PROMINENT_ITEM_FOREGROUND } from 'vs/workbench/common/theme';
|
||||
import { themeColorFromId } from 'vs/platform/theme/common/themeService';
|
||||
|
||||
@@ -972,7 +971,7 @@ class ShowCurrentMarkerInStatusbarContribution extends Disposable {
|
||||
if (!position) {
|
||||
return null;
|
||||
}
|
||||
return find(this.markers, marker => Range.containsPosition(marker, position)) || null;
|
||||
return this.markers.find(marker => Range.containsPosition(marker, position)) || null;
|
||||
}
|
||||
|
||||
private onMarkerChanged(changedResources: ReadonlyArray<URI>): void {
|
||||
|
||||
@@ -48,7 +48,7 @@ export class EditorsObserver extends Disposable {
|
||||
}
|
||||
|
||||
get editors(): IEditorIdentifier[] {
|
||||
return this.mostRecentEditorsMap.values();
|
||||
return [...this.mostRecentEditorsMap.values()];
|
||||
}
|
||||
|
||||
hasEditor(resource: URI): boolean {
|
||||
@@ -283,7 +283,7 @@ export class EditorsObserver extends Disposable {
|
||||
|
||||
// Across all editor groups
|
||||
else {
|
||||
await this.doEnsureOpenedEditorsLimit(limit, this.mostRecentEditorsMap.values(), exclude);
|
||||
await this.doEnsureOpenedEditorsLimit(limit, [...this.mostRecentEditorsMap.values()], exclude);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -342,7 +342,7 @@ export class EditorsObserver extends Disposable {
|
||||
private serialize(): ISerializedEditorsList {
|
||||
const registry = Registry.as<IEditorInputFactoryRegistry>(Extensions.EditorInputFactories);
|
||||
|
||||
const entries = this.mostRecentEditorsMap.values();
|
||||
const entries = [...this.mostRecentEditorsMap.values()];
|
||||
const mapGroupToSerializableEditorsOfGroup = new Map<IEditorGroup, IEditorInput[]>();
|
||||
|
||||
return {
|
||||
|
||||
@@ -62,6 +62,22 @@
|
||||
|
||||
}
|
||||
|
||||
.monaco-workbench .part.panel .empty-panel-message-area {
|
||||
position: absolute;
|
||||
display: none;
|
||||
top: 0px;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.monaco-workbench .part.panel .empty-panel-message-area.visible {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
align-content: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.monaco-workbench .part.panel > .composite.title > .composite-bar-excess {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
@@ -20,13 +20,13 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ClosePanelAction, PanelActivityAction, ToggleMaximizedPanelAction, TogglePanelAction, PlaceHolderPanelActivityAction, PlaceHolderToggleCompositePinnedAction, PositionPanelActionConfigs, SetPanelPositionAction } from 'vs/workbench/browser/parts/panel/panelActions';
|
||||
import { IThemeService, registerThemingParticipant, IColorTheme, 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, PANEL_INPUT_BORDER } from 'vs/workbench/common/theme';
|
||||
import { PANEL_BACKGROUND, PANEL_BORDER, PANEL_ACTIVE_TITLE_FOREGROUND, PANEL_INACTIVE_TITLE_FOREGROUND, PANEL_ACTIVE_TITLE_BORDER, PANEL_DRAG_AND_DROP_BACKGROUND, PANEL_INPUT_BORDER, EDITOR_DRAG_AND_DROP_BACKGROUND } from 'vs/workbench/common/theme';
|
||||
import { activeContrastBorder, focusBorder, contrastBorder, editorBackground, badgeBackground, badgeForeground } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { CompositeBar, ICompositeBarItem, CompositeDragAndDrop } 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';
|
||||
import { Dimension, trackFocus } from 'vs/base/browser/dom';
|
||||
import { Dimension, trackFocus, addClass, toggleClass, EventHelper } from 'vs/base/browser/dom';
|
||||
import { localize } from 'vs/nls';
|
||||
import { IDisposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { IContextKey, IContextKeyService, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
@@ -38,7 +38,7 @@ import { MenuId } from 'vs/platform/actions/common/actions';
|
||||
import { ViewMenuActions } from 'vs/workbench/browser/parts/views/viewMenuActions';
|
||||
import { IPaneComposite } from 'vs/workbench/common/panecomposite';
|
||||
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
|
||||
import { Before2D } from 'vs/workbench/browser/dnd';
|
||||
import { Before2D, CompositeDragAndDropObserver, ICompositeDragAndDrop } from 'vs/workbench/browser/dnd';
|
||||
import { IActivity } from 'vs/workbench/common/activity';
|
||||
|
||||
interface ICachedPanel {
|
||||
@@ -96,6 +96,8 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
|
||||
private panelRegistry: PanelRegistry;
|
||||
|
||||
private dndHandler: ICompositeDragAndDrop;
|
||||
|
||||
constructor(
|
||||
@INotificationService notificationService: INotificationService,
|
||||
@IStorageService storageService: IStorageService,
|
||||
@@ -132,10 +134,15 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
this.panelRegistry = Registry.as<PanelRegistry>(PanelExtensions.Panels);
|
||||
storageKeysSyncRegistryService.registerStorageKey({ key: PanelPart.PINNED_PANELS, version: 1 });
|
||||
|
||||
this.dndHandler = new CompositeDragAndDrop(this.viewDescriptorService, ViewContainerLocation.Panel,
|
||||
(id: string, focus?: boolean) => (<unknown>this.openPanel(id, focus) as Promise<IPaneComposite | undefined>).then(panel => panel || null),
|
||||
(from: string, to: string, before?: Before2D) => this.compositeBar.move(from, to, before?.horizontallyBefore)
|
||||
);
|
||||
|
||||
this.compositeBar = this._register(this.instantiationService.createInstance(CompositeBar, this.getCachedPanels(), {
|
||||
icon: false,
|
||||
orientation: ActionsOrientation.HORIZONTAL,
|
||||
openComposite: (compositeId: string) => this.openPanel(compositeId, true),
|
||||
openComposite: (compositeId: string) => this.openPanel(compositeId, true).then(panel => panel || null),
|
||||
getActivityAction: (compositeId: string) => this.getCompositeActions(compositeId).activityAction,
|
||||
getCompositePinnedAction: (compositeId: string) => this.getCompositeActions(compositeId).pinnedAction,
|
||||
getOnCompositeClickAction: (compositeId: string) => this.instantiationService.createInstance(PanelActivityAction, assertIsDefined(this.getPanel(compositeId))),
|
||||
@@ -149,10 +156,7 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
getContextMenuActionsForComposite: (compositeId: string) => this.getContextMenuActionsForComposite(compositeId) as Action[],
|
||||
getDefaultCompositeId: () => this.panelRegistry.getDefaultPanelId(),
|
||||
hidePart: () => this.layoutService.setPanelHidden(true),
|
||||
dndHandler: new CompositeDragAndDrop(this.viewDescriptorService, ViewContainerLocation.Panel,
|
||||
(id: string, focus?: boolean) => <unknown>this.openPanel(id, focus) as Promise<IPaneComposite | undefined>, // {{SQL CARBON EDIT}} strict-null-checks
|
||||
(from: string, to: string, before?: Before2D) => this.compositeBar.move(from, to, before?.horizontallyBefore)
|
||||
),
|
||||
dndHandler: this.dndHandler,
|
||||
compositeSize: 0,
|
||||
overflowActionSize: 44,
|
||||
colors: (theme: IColorTheme) => ({
|
||||
@@ -192,7 +196,7 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
for (const panel of panels) {
|
||||
const cachedPanel = this.getCachedPanels().filter(({ id }) => id === panel.id)[0];
|
||||
const activePanel = this.getActivePanel();
|
||||
const isActive = activePanel?.getId() === panel.id;
|
||||
const isActive = activePanel?.getId() === panel.id || (!activePanel && this.getLastActivePanelId() === panel.id);
|
||||
|
||||
if (isActive || !this.shouldBeHidden(panel.id, cachedPanel)) {
|
||||
this.compositeBar.addComposite(panel);
|
||||
@@ -203,6 +207,10 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
}
|
||||
|
||||
if (isActive) {
|
||||
if (!activePanel) {
|
||||
this.doOpenPanel(panel.id);
|
||||
}
|
||||
|
||||
this.compositeBar.activateComposite(panel.id);
|
||||
}
|
||||
}
|
||||
@@ -352,6 +360,7 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
}
|
||||
|
||||
this.layoutCompositeBar(); // Need to relayout composite bar since different panels have different action bar width
|
||||
this.layoutEmptyMessage();
|
||||
}
|
||||
|
||||
private onPanelClose(panel: IPanel): void {
|
||||
@@ -362,6 +371,7 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
}
|
||||
|
||||
this.compositeBar.deactivateComposite(panel.getId());
|
||||
this.layoutEmptyMessage();
|
||||
}
|
||||
|
||||
create(parent: HTMLElement): void {
|
||||
@@ -369,11 +379,51 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
|
||||
super.create(parent);
|
||||
|
||||
this.createEmptyPanelMessage();
|
||||
|
||||
const focusTracker = this._register(trackFocus(parent));
|
||||
this._register(focusTracker.onDidFocus(() => this.panelFocusContextKey.set(true)));
|
||||
this._register(focusTracker.onDidBlur(() => this.panelFocusContextKey.set(false)));
|
||||
}
|
||||
|
||||
private createEmptyPanelMessage(): void {
|
||||
this.emptyPanelMessageElement = document.createElement('div');
|
||||
addClass(this.emptyPanelMessageElement, 'empty-panel-message-area');
|
||||
|
||||
const messageElement = document.createElement('div');
|
||||
addClass(messageElement, 'empty-panel-message');
|
||||
messageElement.innerText = localize('panel.emptyMessage', "No panels to display. Drag a view into the panel.");
|
||||
|
||||
this.emptyPanelMessageElement.appendChild(messageElement);
|
||||
this.element.appendChild(this.emptyPanelMessageElement);
|
||||
|
||||
this._register(CompositeDragAndDropObserver.INSTANCE.registerTarget(this.emptyPanelMessageElement, {
|
||||
onDragOver: (e) => {
|
||||
EventHelper.stop(e.eventData, true);
|
||||
},
|
||||
onDragEnter: (e) => {
|
||||
EventHelper.stop(e.eventData, true);
|
||||
|
||||
const validDropTarget = this.dndHandler.onDragEnter(e.dragAndDropData, undefined, e.eventData);
|
||||
this.emptyPanelMessageElement!.style.backgroundColor = validDropTarget ? this.theme.getColor(EDITOR_DRAG_AND_DROP_BACKGROUND)?.toString() || '' : '';
|
||||
},
|
||||
onDragLeave: (e) => {
|
||||
EventHelper.stop(e.eventData, true);
|
||||
this.emptyPanelMessageElement!.style.backgroundColor = '';
|
||||
},
|
||||
onDragEnd: (e) => {
|
||||
EventHelper.stop(e.eventData, true);
|
||||
this.emptyPanelMessageElement!.style.backgroundColor = '';
|
||||
},
|
||||
onDrop: (e) => {
|
||||
EventHelper.stop(e.eventData, true);
|
||||
this.emptyPanelMessageElement!.style.backgroundColor = '';
|
||||
|
||||
this.dndHandler.drop(e.dragAndDropData, undefined, e.eventData);
|
||||
},
|
||||
}));
|
||||
}
|
||||
|
||||
updateStyles(): void {
|
||||
super.updateStyles();
|
||||
|
||||
@@ -508,6 +558,9 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
|
||||
// Layout composite bar
|
||||
this.layoutCompositeBar();
|
||||
|
||||
// Add empty panel message
|
||||
this.layoutEmptyMessage();
|
||||
}
|
||||
|
||||
private layoutCompositeBar(): void {
|
||||
@@ -521,6 +574,13 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
}
|
||||
}
|
||||
|
||||
private emptyPanelMessageElement: HTMLElement | undefined;
|
||||
private layoutEmptyMessage(): void {
|
||||
if (this.emptyPanelMessageElement) {
|
||||
toggleClass(this.emptyPanelMessageElement, 'visible', this.compositeBar.getVisibleComposites().length === 0);
|
||||
}
|
||||
}
|
||||
|
||||
private getCompositeActions(compositeId: string): { activityAction: PanelActivityAction, pinnedAction: ToggleCompositePinnedAction; } {
|
||||
let compositeActions = this.compositeActions.get(compositeId);
|
||||
if (!compositeActions) {
|
||||
|
||||
@@ -109,7 +109,7 @@ export class SidebarPart extends CompositePart<Viewlet> implements IViewletServi
|
||||
themeService,
|
||||
Registry.as<ViewletRegistry>(ViewletExtensions.Viewlets),
|
||||
SidebarPart.activeViewletSettingsKey,
|
||||
Registry.as<ViewletRegistry>(ViewletExtensions.Viewlets).getDefaultViewletId(),
|
||||
viewDescriptorService.getDefaultViewContainer(ViewContainerLocation.Sidebar)!.id,
|
||||
'sideBar',
|
||||
'viewlet',
|
||||
SIDE_BAR_TITLE_FOREGROUND,
|
||||
@@ -142,7 +142,7 @@ export class SidebarPart extends CompositePart<Viewlet> implements IViewletServi
|
||||
|
||||
if (activeContainers.length) {
|
||||
if (this.getActiveComposite()?.getId() === viewletDescriptor.id) {
|
||||
const defaultViewletId = this.getDefaultViewletId();
|
||||
const defaultViewletId = this.viewDescriptorService.getDefaultViewContainer(ViewContainerLocation.Sidebar)?.id;
|
||||
const containerToOpen = activeContainers.filter(c => c.id === defaultViewletId)[0] || activeContainers[0];
|
||||
await this.openViewlet(containerToOpen.id);
|
||||
}
|
||||
@@ -253,10 +253,6 @@ export class SidebarPart extends CompositePart<Viewlet> implements IViewletServi
|
||||
});
|
||||
}
|
||||
|
||||
getDefaultViewletId(): string {
|
||||
return this.viewletRegistry.getDefaultViewletId();
|
||||
}
|
||||
|
||||
getViewlet(id: string): ViewletDescriptor {
|
||||
return this.getViewlets().filter(viewlet => viewlet.id === id)[0];
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati
|
||||
import { IStorageService, StorageScope, IWorkspaceStorageChangeEvent } from 'vs/platform/storage/common/storage';
|
||||
import { Parts, IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
|
||||
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
import { coalesce, find } from 'vs/base/common/arrays';
|
||||
import { coalesce } from 'vs/base/common/arrays';
|
||||
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
|
||||
import { ToggleStatusbarVisibilityAction } from 'vs/workbench/browser/actions/layoutActions';
|
||||
import { Separator } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
@@ -181,7 +181,7 @@ class StatusbarViewModel extends Disposable {
|
||||
}
|
||||
|
||||
findEntry(container: HTMLElement): IStatusbarViewModelEntry | undefined {
|
||||
return find(this._entries, entry => entry.container === container);
|
||||
return this._entries.find(entry => entry.container === container);
|
||||
}
|
||||
|
||||
getEntries(alignment: StatusbarAlignment): IStatusbarViewModelEntry[] {
|
||||
|
||||
@@ -72,7 +72,7 @@ export class TitlebarPart extends Part implements ITitleService {
|
||||
|
||||
private isInactive: boolean = false;
|
||||
|
||||
private readonly properties: ITitleProperties = { isPure: true, isAdmin: false };
|
||||
private readonly properties: ITitleProperties = { isPure: true, isAdmin: false, prefix: undefined };
|
||||
private readonly activeEditorListeners = this._register(new DisposableStore());
|
||||
|
||||
private readonly titleUpdater = this._register(new RunOnceScheduler(() => this.doUpdateTitle(), 0));
|
||||
@@ -191,6 +191,10 @@ export class TitlebarPart extends Part implements ITitleService {
|
||||
private getWindowTitle(): string {
|
||||
let title = this.doGetWindowTitle();
|
||||
|
||||
if (this.properties.prefix) {
|
||||
title = `${this.properties.prefix} ${title || this.productService.nameLong}`;
|
||||
}
|
||||
|
||||
if (this.properties.isAdmin) {
|
||||
title = `${title || this.productService.nameLong} ${TitlebarPart.NLS_USER_IS_ADMIN}`;
|
||||
}
|
||||
@@ -212,10 +216,12 @@ export class TitlebarPart extends Part implements ITitleService {
|
||||
updateProperties(properties: ITitleProperties): void {
|
||||
const isAdmin = typeof properties.isAdmin === 'boolean' ? properties.isAdmin : this.properties.isAdmin;
|
||||
const isPure = typeof properties.isPure === 'boolean' ? properties.isPure : this.properties.isPure;
|
||||
const prefix = typeof properties.prefix === 'string' ? properties.prefix : this.properties.prefix;
|
||||
|
||||
if (isAdmin !== this.properties.isAdmin || isPure !== this.properties.isPure) {
|
||||
if (isAdmin !== this.properties.isAdmin || isPure !== this.properties.isPure || prefix !== this.properties.prefix) {
|
||||
this.properties.isAdmin = isAdmin;
|
||||
this.properties.isPure = isPure;
|
||||
this.properties.prefix = prefix;
|
||||
|
||||
this.titleUpdater.schedule();
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import 'vs/css!./media/views';
|
||||
import { Disposable, IDisposable, toDisposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { IViewDescriptorService, ViewContainer, IViewDescriptor, IViewContainersRegistry, Extensions as ViewExtensions, IView, ViewContainerLocation, IViewsService, IViewPaneContainer, getVisbileViewContextKey } from 'vs/workbench/common/views';
|
||||
import { IViewDescriptorService, ViewContainer, IViewDescriptor, IView, ViewContainerLocation, IViewsService, IViewPaneContainer, getVisbileViewContextKey } from 'vs/workbench/common/views';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
|
||||
@@ -15,7 +15,6 @@ import { isString } from 'vs/base/common/types';
|
||||
import { MenuId, registerAction2, Action2 } from 'vs/platform/actions/common/actions';
|
||||
import { localize } from 'vs/nls';
|
||||
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { toggleClass, addClass } from 'vs/base/browser/dom';
|
||||
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
import { IPaneComposite } from 'vs/workbench/common/panecomposite';
|
||||
import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
|
||||
@@ -23,7 +22,7 @@ import { ServicesAccessor, IInstantiationService } from 'vs/platform/instantiati
|
||||
import { ViewPaneContainer } from 'vs/workbench/browser/parts/views/viewPaneContainer';
|
||||
import { PaneCompositePanel, PanelRegistry, PanelDescriptor, Extensions as PanelExtensions } from 'vs/workbench/browser/panel';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IThemeService, IFileIconTheme } from 'vs/platform/theme/common/themeService';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
@@ -37,15 +36,16 @@ export class ViewsService extends Disposable implements IViewsService {
|
||||
|
||||
_serviceBrand: undefined;
|
||||
|
||||
private readonly viewContainersRegistry: IViewContainersRegistry;
|
||||
private readonly viewDisposable: Map<IViewDescriptor, IDisposable>;
|
||||
private readonly viewPaneContainers: Map<string, { viewPaneContainer: ViewPaneContainer, disposable: IDisposable }>;
|
||||
|
||||
private readonly _onDidChangeViewVisibility: Emitter<{ id: string, visible: boolean }> = this._register(new Emitter<{ id: string, visible: boolean }>());
|
||||
readonly onDidChangeViewVisibility: Event<{ id: string, visible: boolean }> = this._onDidChangeViewVisibility.event;
|
||||
|
||||
private readonly visibleViewContextKeys: Map<string, IContextKey<boolean>>;
|
||||
private readonly _onDidChangeViewContainerVisibility = this._register(new Emitter<{ id: string, visible: boolean, location: ViewContainerLocation }>());
|
||||
readonly onDidChangeViewContainerVisibility = this._onDidChangeViewContainerVisibility.event;
|
||||
|
||||
private readonly visibleViewContextKeys: Map<string, IContextKey<boolean>>;
|
||||
|
||||
constructor(
|
||||
@IViewDescriptorService private readonly viewDescriptorService: IViewDescriptorService,
|
||||
@@ -56,7 +56,6 @@ export class ViewsService extends Disposable implements IViewsService {
|
||||
) {
|
||||
super();
|
||||
|
||||
this.viewContainersRegistry = Registry.as<IViewContainersRegistry>(ViewExtensions.ViewContainersRegistry);
|
||||
this.viewDisposable = new Map<IViewDescriptor, IDisposable>();
|
||||
this.visibleViewContextKeys = new Map<string, IContextKey<boolean>>();
|
||||
this.viewPaneContainers = new Map<string, { viewPaneContainer: ViewPaneContainer, disposable: IDisposable }>();
|
||||
@@ -66,10 +65,16 @@ export class ViewsService extends Disposable implements IViewsService {
|
||||
this.viewDisposable.clear();
|
||||
}));
|
||||
|
||||
this.viewDescriptorService.getViewContainers().forEach(viewContainer => this.onDidRegisterViewContainer(viewContainer, this.viewDescriptorService.getViewContainerLocation(viewContainer)!));
|
||||
this._register(this.viewContainersRegistry.onDidRegister(({ viewContainer }) => this.onDidRegisterViewContainer(viewContainer, this.viewDescriptorService.getViewContainerLocation(viewContainer)!)));
|
||||
this._register(this.viewContainersRegistry.onDidDeregister(e => this.deregisterViewPaneContainer(e.viewContainer.id)));
|
||||
this.viewDescriptorService.viewContainers.forEach(viewContainer => this.onDidRegisterViewContainer(viewContainer, this.viewDescriptorService.getViewContainerLocation(viewContainer)!));
|
||||
this._register(this.viewDescriptorService.onDidChangeViewContainers(({ added, removed }) => this.onDidChangeContainers(added, removed)));
|
||||
this._register(this.viewDescriptorService.onDidChangeContainerLocation(({ viewContainer, from, to }) => this.onDidChangeContainerLocation(viewContainer, from, to)));
|
||||
|
||||
// View Container Visibility
|
||||
this._register(this.viewletService.onDidViewletOpen(viewlet => this._onDidChangeViewContainerVisibility.fire({ id: viewlet.getId(), visible: true, location: ViewContainerLocation.Sidebar })));
|
||||
this._register(this.panelService.onDidPanelOpen(e => this._onDidChangeViewContainerVisibility.fire({ id: e.panel.getId(), visible: true, location: ViewContainerLocation.Panel })));
|
||||
this._register(this.viewletService.onDidViewletClose(viewlet => this._onDidChangeViewContainerVisibility.fire({ id: viewlet.getId(), visible: false, location: ViewContainerLocation.Sidebar })));
|
||||
this._register(this.panelService.onDidPanelClose(panel => this._onDidChangeViewContainerVisibility.fire({ id: panel.getId(), visible: false, location: ViewContainerLocation.Panel })));
|
||||
|
||||
}
|
||||
|
||||
private registerViewPaneContainer(viewPaneContainer: ViewPaneContainer): void {
|
||||
@@ -117,6 +122,15 @@ export class ViewsService extends Disposable implements IViewsService {
|
||||
return contextKey;
|
||||
}
|
||||
|
||||
private onDidChangeContainers(added: ReadonlyArray<{ container: ViewContainer, location: ViewContainerLocation }>, removed: ReadonlyArray<{ container: ViewContainer, location: ViewContainerLocation }>): void {
|
||||
for (const { container, location } of removed) {
|
||||
this.deregisterViewletOrPanel(container, location);
|
||||
}
|
||||
for (const { container, location } of added) {
|
||||
this.registerViewletOrPanel(container, location);
|
||||
}
|
||||
}
|
||||
|
||||
private onDidChangeContainerLocation(viewContainer: ViewContainer, from: ViewContainerLocation, to: ViewContainerLocation): void {
|
||||
this.deregisterViewletOrPanel(viewContainer, from);
|
||||
this.registerViewletOrPanel(viewContainer, to);
|
||||
@@ -226,6 +240,62 @@ export class ViewsService extends Disposable implements IViewsService {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
isViewContainerVisible(id: string): boolean {
|
||||
const viewContainer = this.viewDescriptorService.getViewContainerById(id);
|
||||
if (viewContainer) {
|
||||
const viewContainerLocation = this.viewDescriptorService.getViewContainerLocation(viewContainer);
|
||||
switch (viewContainerLocation) {
|
||||
case ViewContainerLocation.Panel:
|
||||
return this.panelService.getActivePanel()?.getId() === id;
|
||||
case ViewContainerLocation.Sidebar:
|
||||
return this.viewletService.getActiveViewlet()?.getId() === id;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
getVisibleViewContainer(location: ViewContainerLocation): ViewContainer | null {
|
||||
let viewContainerId: string | undefined = undefined;
|
||||
switch (location) {
|
||||
case ViewContainerLocation.Panel:
|
||||
viewContainerId = this.panelService.getActivePanel()?.getId();
|
||||
break;
|
||||
case ViewContainerLocation.Sidebar:
|
||||
viewContainerId = this.viewletService.getActiveViewlet()?.getId();
|
||||
break;
|
||||
}
|
||||
return viewContainerId ? this.viewDescriptorService.getViewContainerById(viewContainerId) : null;
|
||||
}
|
||||
|
||||
async openViewContainer(id: string, focus?: boolean): Promise<IPaneComposite | null> {
|
||||
const viewContainer = this.viewDescriptorService.getViewContainerById(id);
|
||||
if (viewContainer) {
|
||||
const viewContainerLocation = this.viewDescriptorService.getViewContainerLocation(viewContainer);
|
||||
switch (viewContainerLocation) {
|
||||
case ViewContainerLocation.Panel:
|
||||
const panel = await this.panelService.openPanel(id, focus);
|
||||
return panel as IPaneComposite;
|
||||
case ViewContainerLocation.Sidebar:
|
||||
const viewlet = await this.viewletService.openViewlet(id, focus);
|
||||
return viewlet || null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
async closeViewContainer(id: string): Promise<void> {
|
||||
const viewContainer = this.viewDescriptorService.getViewContainerById(id);
|
||||
if (viewContainer) {
|
||||
const viewContainerLocation = this.viewDescriptorService.getViewContainerLocation(viewContainer);
|
||||
switch (viewContainerLocation) {
|
||||
case ViewContainerLocation.Panel:
|
||||
return this.panelService.getActivePanel()?.getId() === id ? this.panelService.hideActivePanel() : undefined;
|
||||
case ViewContainerLocation.Sidebar:
|
||||
return this.viewletService.getActiveViewlet()?.getId() === id ? this.viewletService.hideActiveViewlet() : undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
isViewVisible(id: string): boolean {
|
||||
const activeView = this.getActiveViewWithId(id);
|
||||
return activeView?.isBodyVisible() || false;
|
||||
@@ -306,13 +376,13 @@ export class ViewsService extends Disposable implements IViewsService {
|
||||
return null;
|
||||
}
|
||||
|
||||
getProgressIndicator(id: string): IProgressIndicator | undefined {
|
||||
const viewContainer = this.viewDescriptorService.getViewContainerByViewId(id);
|
||||
getViewProgressIndicator(viewId: string): IProgressIndicator | undefined {
|
||||
const viewContainer = this.viewDescriptorService.getViewContainerByViewId(viewId);
|
||||
if (viewContainer === null) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const view = this.viewPaneContainers.get(viewContainer.id)?.viewPaneContainer?.getView(id);
|
||||
const view = this.viewPaneContainers.get(viewContainer.id)?.viewPaneContainer?.getView(viewId);
|
||||
return view?.getProgressIndicator();
|
||||
}
|
||||
|
||||
@@ -411,17 +481,4 @@ export class ViewsService extends Disposable implements IViewsService {
|
||||
}
|
||||
}
|
||||
|
||||
export function createFileIconThemableTreeContainerScope(container: HTMLElement, themeService: IThemeService): 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);
|
||||
}
|
||||
|
||||
registerSingleton(IViewsService, ViewsService);
|
||||
@@ -20,7 +20,6 @@ import { URI } from 'vs/base/common/uri';
|
||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { AsyncDataTree } from 'vs/base/browser/ui/tree/asyncDataTree';
|
||||
import { AbstractTree } from 'vs/base/browser/ui/tree/abstractTree';
|
||||
import { assertIsDefined } from 'vs/base/common/types';
|
||||
import { ViewPaneContainer } from 'vs/workbench/browser/parts/views/viewPaneContainer';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
@@ -97,7 +96,6 @@ export const Extensions = {
|
||||
};
|
||||
|
||||
export class ViewletRegistry extends CompositeRegistry<Viewlet> {
|
||||
private defaultViewletId: string | undefined;
|
||||
|
||||
/**
|
||||
* Registers a viewlet to the platform.
|
||||
@@ -110,9 +108,6 @@ export class ViewletRegistry extends CompositeRegistry<Viewlet> {
|
||||
* Deregisters a viewlet to the platform.
|
||||
*/
|
||||
deregisterViewlet(id: string): void {
|
||||
if (id === this.defaultViewletId) {
|
||||
throw new Error('Cannot deregister default viewlet');
|
||||
}
|
||||
super.deregisterComposite(id);
|
||||
}
|
||||
|
||||
@@ -130,19 +125,6 @@ export class ViewletRegistry extends CompositeRegistry<Viewlet> {
|
||||
return this.getComposites() as ViewletDescriptor[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the id of the viewlet that should open on startup by default.
|
||||
*/
|
||||
setDefaultViewletId(id: string): void {
|
||||
this.defaultViewletId = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the id of the viewlet that should open on startup by default.
|
||||
*/
|
||||
getDefaultViewletId(): string {
|
||||
return assertIsDefined(this.defaultViewletId);
|
||||
}
|
||||
}
|
||||
|
||||
Registry.add(Extensions.Viewlets, new ViewletRegistry());
|
||||
|
||||
@@ -46,6 +46,7 @@ import { Layout } from 'vs/workbench/browser/layout';
|
||||
import { IHostService } from 'vs/workbench/services/host/browser/host';
|
||||
import { ILanguageAssociationRegistry, Extensions as LanguageExtensions } from 'sql/workbench/services/languageAssociation/common/languageAssociation';
|
||||
import { Extensions as PanelExtensions, PanelRegistry } from 'vs/workbench/browser/panel';
|
||||
import { IViewDescriptorService, ViewContainerLocation } from 'vs/workbench/common/views';
|
||||
|
||||
export class Workbench extends Layout {
|
||||
|
||||
@@ -164,7 +165,7 @@ export class Workbench extends Layout {
|
||||
|
||||
// Restore
|
||||
try {
|
||||
await this.restoreWorkbench(accessor.get(IEditorService), accessor.get(IEditorGroupsService), accessor.get(IViewletService), accessor.get(IPanelService), accessor.get(ILogService), lifecycleService);
|
||||
await this.restoreWorkbench(accessor.get(IEditorService), accessor.get(IEditorGroupsService), accessor.get(IViewDescriptorService), accessor.get(IViewletService), accessor.get(IPanelService), accessor.get(ILogService), lifecycleService);
|
||||
} catch (error) {
|
||||
onUnexpectedError(error);
|
||||
}
|
||||
@@ -402,6 +403,7 @@ export class Workbench extends Layout {
|
||||
private async restoreWorkbench(
|
||||
editorService: IEditorService,
|
||||
editorGroupService: IEditorGroupsService,
|
||||
viewDescriptorService: IViewDescriptorService,
|
||||
viewletService: IViewletService,
|
||||
panelService: IPanelService,
|
||||
logService: ILogService,
|
||||
@@ -438,7 +440,7 @@ export class Workbench extends Layout {
|
||||
|
||||
const viewlet = await viewletService.openViewlet(this.state.sideBar.viewletToRestore);
|
||||
if (!viewlet) {
|
||||
await viewletService.openViewlet(viewletService.getDefaultViewletId()); // fallback to default viewlet as needed
|
||||
await viewletService.openViewlet(viewDescriptorService.getDefaultViewContainer(ViewContainerLocation.Sidebar)?.id); // fallback to default viewlet as needed
|
||||
}
|
||||
|
||||
mark('didRestoreViewlet');
|
||||
|
||||
Reference in New Issue
Block a user