mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Merge from vscode d06f0e877ceaf3a35a283f1bfdc50927ec8dfd1e (#8767)
This commit is contained in:
@@ -156,9 +156,4 @@ export interface EditorServiceImpl extends IEditorService {
|
||||
* Emitted when the list of most recently active editors change.
|
||||
*/
|
||||
readonly onDidMostRecentlyActiveEditorsChange: Event<void>;
|
||||
|
||||
/**
|
||||
* Access to the list of most recently active editors.
|
||||
*/
|
||||
readonly mostRecentlyActiveEditors: ReadonlyArray<IEditorIdentifier>;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import * as nls from 'vs/nls';
|
||||
import { Action } from 'vs/base/common/actions';
|
||||
import { mixin } from 'vs/base/common/objects';
|
||||
import { IEditorInput, EditorInput, IEditorIdentifier, IEditorCommandsContext, CloseDirection, SaveReason } from 'vs/workbench/common/editor';
|
||||
import { IEditorInput, EditorInput, IEditorIdentifier, IEditorCommandsContext, CloseDirection, SaveReason, EditorsOrder } from 'vs/workbench/common/editor';
|
||||
import { QuickOpenEntryGroup } from 'vs/base/parts/quickopen/browser/quickOpenModel';
|
||||
import { EditorQuickOpenEntry, EditorQuickOpenEntryGroup, IEditorQuickOpenEntry, QuickOpenAction } from 'vs/workbench/browser/quickopen';
|
||||
import { IQuickOpenService } from 'vs/platform/quickOpen/common/quickOpen';
|
||||
@@ -16,7 +16,7 @@ import { IHistoryService } from 'vs/workbench/services/history/common/history';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { CLOSE_EDITOR_COMMAND_ID, NAVIGATE_ALL_EDITORS_BY_APPEARANCE_PREFIX, MOVE_ACTIVE_EDITOR_COMMAND_ID, NAVIGATE_IN_ACTIVE_GROUP_BY_MOST_RECENTLY_USED_PREFIX, ActiveEditorMoveArguments, SPLIT_EDITOR_LEFT, SPLIT_EDITOR_RIGHT, SPLIT_EDITOR_UP, SPLIT_EDITOR_DOWN, splitEditor, LAYOUT_EDITOR_GROUPS_COMMAND_ID, mergeAllGroups, NAVIGATE_ALL_EDITORS_BY_MOST_RECENTLY_USED_PREFIX } from 'vs/workbench/browser/parts/editor/editorCommands';
|
||||
import { IEditorGroupsService, IEditorGroup, GroupsArrangement, EditorsOrder, GroupLocation, GroupDirection, preferredSideBySideGroupDirection, IFindGroupScope, GroupOrientation, EditorGroupLayout, GroupsOrder } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { IEditorGroupsService, IEditorGroup, GroupsArrangement, GroupLocation, GroupDirection, preferredSideBySideGroupDirection, IFindGroupScope, GroupOrientation, EditorGroupLayout, GroupsOrder } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { IEditorService, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import 'vs/css!./media/editorgroupview';
|
||||
|
||||
import { EditorGroup, IEditorOpenOptions, EditorCloseEvent, ISerializedEditorGroup, isSerializedEditorGroup } from 'vs/workbench/common/editor/editorGroup';
|
||||
import { EditorInput, EditorOptions, GroupIdentifier, SideBySideEditorInput, CloseDirection, IEditorCloseEvent, EditorGroupActiveEditorDirtyContext, IEditor, EditorGroupEditorsCountContext, toResource, SideBySideEditor, SaveReason, SaveContext, IEditorPartOptionsChangeEvent } from 'vs/workbench/common/editor';
|
||||
import { EditorInput, EditorOptions, GroupIdentifier, SideBySideEditorInput, CloseDirection, IEditorCloseEvent, EditorGroupActiveEditorDirtyContext, IEditor, EditorGroupEditorsCountContext, toResource, SideBySideEditor, SaveReason, SaveContext, IEditorPartOptionsChangeEvent, EditorsOrder } from 'vs/workbench/common/editor';
|
||||
import { Event, Emitter, Relay } from 'vs/base/common/event';
|
||||
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { addClass, addClasses, Dimension, trackFocus, toggleClass, removeClass, addDisposableListener, EventType, EventHelper, findParentWithClass, clearNode, isAncestor } from 'vs/base/browser/dom';
|
||||
@@ -17,7 +17,7 @@ import { attachProgressBarStyler } from 'vs/platform/theme/common/styler';
|
||||
import { IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
||||
import { editorBackground, contrastBorder } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { Themable, EDITOR_GROUP_HEADER_TABS_BORDER, EDITOR_GROUP_HEADER_TABS_BACKGROUND, EDITOR_GROUP_HEADER_NO_TABS_BACKGROUND, EDITOR_GROUP_EMPTY_BACKGROUND, EDITOR_GROUP_FOCUSED_EMPTY_BORDER } from 'vs/workbench/common/theme';
|
||||
import { IMoveEditorOptions, ICopyEditorOptions, ICloseEditorsFilter, IGroupChangeEvent, GroupChangeKind, EditorsOrder, GroupsOrder, ICloseEditorOptions } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { IMoveEditorOptions, ICopyEditorOptions, ICloseEditorsFilter, IGroupChangeEvent, GroupChangeKind, GroupsOrder, ICloseEditorOptions } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { TabsTitleControl } from 'vs/workbench/browser/parts/editor/tabsTitleControl';
|
||||
import { EditorControl } from 'vs/workbench/browser/parts/editor/editorControl';
|
||||
import { IEditorProgressService } from 'vs/platform/progress/common/progress';
|
||||
@@ -725,7 +725,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
}
|
||||
|
||||
get editors(): EditorInput[] {
|
||||
return this._group.getEditors();
|
||||
return this._group.getEditors(EditorsOrder.SEQUENTIAL);
|
||||
}
|
||||
|
||||
get count(): number {
|
||||
@@ -752,12 +752,8 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
return this._group.isActive(editor);
|
||||
}
|
||||
|
||||
getEditors(order?: EditorsOrder): EditorInput[] {
|
||||
if (order === EditorsOrder.MOST_RECENTLY_ACTIVE) {
|
||||
return this._group.getEditors(true);
|
||||
}
|
||||
|
||||
return this.editors;
|
||||
getEditors(order: EditorsOrder): EditorInput[] {
|
||||
return this._group.getEditors(order);
|
||||
}
|
||||
|
||||
getEditorByIndex(index: number): EditorInput | undefined {
|
||||
@@ -1021,7 +1017,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
|
||||
// Use the first editor as active editor
|
||||
const { editor, options } = editors.shift()!;
|
||||
let firstOpenedEditor = await this.openEditor(editor, options);
|
||||
await this.openEditor(editor, options);
|
||||
|
||||
// Open the other ones inactive
|
||||
const startingIndex = this.getIndexOfEditor(editor) + 1;
|
||||
@@ -1031,13 +1027,13 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
adjustedEditorOptions.pinned = true;
|
||||
adjustedEditorOptions.index = startingIndex + index;
|
||||
|
||||
const openedEditor = await this.openEditor(editor, adjustedEditorOptions);
|
||||
if (!firstOpenedEditor) {
|
||||
firstOpenedEditor = openedEditor; // only take if the first editor opening failed
|
||||
}
|
||||
await this.openEditor(editor, adjustedEditorOptions);
|
||||
}));
|
||||
|
||||
return firstOpenedEditor;
|
||||
// Opening many editors at once can put any editor to be
|
||||
// the active one depending on options. As such, we simply
|
||||
// return the active control after this operation.
|
||||
return this.editorControl.activeControl;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
@@ -1373,7 +1369,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
const filter = editors;
|
||||
const hasDirection = typeof filter.direction === 'number';
|
||||
|
||||
let editorsToClose = this._group.getEditors(!hasDirection /* in MRU order only if direction is not specified */);
|
||||
let editorsToClose = this._group.getEditors(hasDirection ? EditorsOrder.SEQUENTIAL : EditorsOrder.MOST_RECENTLY_ACTIVE); // in MRU order only if direction is not specified
|
||||
|
||||
// Filter: saved only
|
||||
if (filter.savedOnly) {
|
||||
@@ -1434,7 +1430,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
}
|
||||
|
||||
// Check for dirty and veto
|
||||
const editors = this._group.getEditors(true);
|
||||
const editors = this._group.getEditors(EditorsOrder.MOST_RECENTLY_ACTIVE);
|
||||
const veto = await this.handleDirtyClosing(editors.slice(0));
|
||||
if (veto) {
|
||||
return;
|
||||
@@ -1528,8 +1524,6 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
|
||||
//#endregion
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Themable
|
||||
|
||||
protected updateStyles(): void {
|
||||
|
||||
@@ -13,12 +13,11 @@ import { getIconClasses } from 'vs/editor/common/services/getIconClasses';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { QuickOpenHandler } from 'vs/workbench/browser/quickopen';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IEditorGroupsService, IEditorGroup, EditorsOrder, GroupsOrder } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { IEditorGroupsService, IEditorGroup, GroupsOrder } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { toResource, SideBySideEditor, IEditorInput } from 'vs/workbench/common/editor';
|
||||
import { toResource, SideBySideEditor, IEditorInput, EditorsOrder } from 'vs/workbench/common/editor';
|
||||
import { compareItemsByScore, scoreItem, ScorerCache, prepareQuery } from 'vs/base/parts/quickopen/common/quickOpenScorer';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { IHistoryService } from 'vs/workbench/services/history/common/history';
|
||||
|
||||
export class EditorPickerEntry extends QuickOpenEntryGroup {
|
||||
|
||||
@@ -209,14 +208,13 @@ export abstract class BaseAllEditorsPicker extends BaseEditorPicker {
|
||||
constructor(
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@IEditorService editorService: IEditorService,
|
||||
@IEditorGroupsService editorGroupService: IEditorGroupsService,
|
||||
@IHistoryService protected historyService: IHistoryService
|
||||
@IEditorGroupsService editorGroupService: IEditorGroupsService
|
||||
) {
|
||||
super(instantiationService, editorService, editorGroupService);
|
||||
}
|
||||
|
||||
protected count(): number {
|
||||
return this.historyService.getMostRecentlyUsedOpenEditors().length;
|
||||
return this.editorService.count;
|
||||
}
|
||||
|
||||
getEmptyLabel(searchString: string): string {
|
||||
@@ -262,7 +260,7 @@ export class AllEditorsByMostRecentlyUsedPicker extends BaseAllEditorsPicker {
|
||||
protected getEditorEntries(): EditorPickerEntry[] {
|
||||
const entries: EditorPickerEntry[] = [];
|
||||
|
||||
for (const { editor, groupId } of this.historyService.getMostRecentlyUsedOpenEditors()) {
|
||||
for (const { editor, groupId } of this.editorService.getEditors(EditorsOrder.MOST_RECENTLY_ACTIVE)) {
|
||||
entries.push(this.instantiationService.createInstance(EditorPickerEntry, editor, this.editorGroupService.getGroup(groupId)!));
|
||||
}
|
||||
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IEditorInput, IEditorInputFactoryRegistry, IEditorIdentifier, GroupIdentifier, Extensions, IEditorPartOptionsChangeEvent } from 'vs/workbench/common/editor';
|
||||
import { IEditorInput, IEditorInputFactoryRegistry, IEditorIdentifier, GroupIdentifier, Extensions, IEditorPartOptionsChangeEvent, EditorsOrder } from 'vs/workbench/common/editor';
|
||||
import { dispose, Disposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { IEditorGroupsService, IEditorGroup, EditorsOrder, GroupChangeKind, GroupsOrder } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { IEditorGroupsService, IEditorGroup, GroupChangeKind, GroupsOrder } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { coalesce } from 'vs/base/common/arrays';
|
||||
import { LinkedMap, Touch } from 'vs/base/common/map';
|
||||
import { equals } from 'vs/base/common/objects';
|
||||
@@ -41,6 +41,10 @@ export class EditorsObserver extends Disposable {
|
||||
private readonly _onDidChange = this._register(new Emitter<void>());
|
||||
readonly onDidChange = this._onDidChange.event;
|
||||
|
||||
get count(): number {
|
||||
return this.mostRecentEditorsMap.size;
|
||||
}
|
||||
|
||||
get editors(): IEditorIdentifier[] {
|
||||
return this.mostRecentEditorsMap.values();
|
||||
}
|
||||
@@ -231,7 +235,7 @@ export class EditorsObserver extends Disposable {
|
||||
if (typeof groupId === 'number') {
|
||||
const group = this.editorGroupsService.getGroup(groupId);
|
||||
if (group) {
|
||||
this.doEnsureOpenedEditorsLimit(limit, group.getEditors(EditorsOrder.MOST_RECENTLY_ACTIVE).map(editor => ({ editor, groupId })), exclude);
|
||||
await this.doEnsureOpenedEditorsLimit(limit, group.getEditors(EditorsOrder.MOST_RECENTLY_ACTIVE).map(editor => ({ editor, groupId })), exclude);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,7 +249,7 @@ export class EditorsObserver extends Disposable {
|
||||
|
||||
// Across all editor groups
|
||||
else {
|
||||
this.doEnsureOpenedEditorsLimit(limit, this.mostRecentEditorsMap.values(), exclude);
|
||||
await this.doEnsureOpenedEditorsLimit(limit, this.mostRecentEditorsMap.values(), exclude);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import { SyncActionDescriptor, MenuId, MenuRegistry } from 'vs/platform/actions/
|
||||
import { IWorkbenchActionRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/actions';
|
||||
import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
|
||||
import { IWorkbenchLayoutService, Parts, Position, positionToString } from 'vs/workbench/services/layout/browser/layoutService';
|
||||
import { ActivityAction } from 'vs/workbench/browser/parts/compositeBarActions';
|
||||
import { ActivityAction, ToggleCompositePinnedAction, ICompositeBar } from 'vs/workbench/browser/parts/compositeBarActions';
|
||||
import { IActivity } from 'vs/workbench/common/activity';
|
||||
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { ActivePanelContext, PanelPositionContext } from 'vs/workbench/common/panel';
|
||||
@@ -149,7 +149,7 @@ function createPositionPanelActionConfig(id: string, alias: string, label: strin
|
||||
};
|
||||
}
|
||||
|
||||
export const PositionPanelActionConfigs = [
|
||||
export const PositionPanelActionConfigs: PanelActionConfig<Position>[] = [
|
||||
createPositionPanelActionConfig(PositionPanelActionId.LEFT, 'View: Panel Position Left', nls.localize('positionPanelLeft', 'Move Panel Left'), Position.LEFT),
|
||||
createPositionPanelActionConfig(PositionPanelActionId.RIGHT, 'View: Panel Position Right', nls.localize('positionPanelRight', 'Move Panel Right'), Position.RIGHT),
|
||||
createPositionPanelActionConfig(PositionPanelActionId.BOTTOM, 'View: Panel Position Bottom', nls.localize('positionPanelBottom', 'Move Panel To Bottom'), Position.BOTTOM),
|
||||
@@ -187,8 +187,34 @@ export class PanelActivityAction extends ActivityAction {
|
||||
this.activate();
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
setActivity(activity: IActivity): void {
|
||||
this.activity = activity;
|
||||
}
|
||||
}
|
||||
|
||||
export class PlaceHolderPanelActivityAction extends PanelActivityAction {
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
@IPanelService panelService: IPanelService
|
||||
) {
|
||||
super({ id, name: id }, panelService);
|
||||
}
|
||||
}
|
||||
|
||||
export class PlaceHolderToggleCompositePinnedAction extends ToggleCompositePinnedAction {
|
||||
|
||||
constructor(id: string, compositeBar: ICompositeBar) {
|
||||
super({ id, name: id, cssClass: undefined }, compositeBar);
|
||||
}
|
||||
|
||||
setActivity(activity: IActivity): void {
|
||||
this.label = activity.name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export class SwitchPanelViewAction extends Action {
|
||||
|
||||
constructor(
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import 'vs/css!./media/panelpart';
|
||||
import { IAction } from 'vs/base/common/actions';
|
||||
import { IAction, Action } from 'vs/base/common/actions';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { ActionsOrientation } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
@@ -18,7 +18,7 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ClosePanelAction, PanelActivityAction, ToggleMaximizedPanelAction, TogglePanelAction, PositionPanelActionConfigs, SetPanelPositionAction } from 'vs/workbench/browser/parts/panel/panelActions';
|
||||
import { ClosePanelAction, PanelActivityAction, ToggleMaximizedPanelAction, TogglePanelAction, PlaceHolderPanelActivityAction, PlaceHolderToggleCompositePinnedAction, PositionPanelActionConfigs, SetPanelPositionAction } from 'vs/workbench/browser/parts/panel/panelActions';
|
||||
import { IThemeService, registerThemingParticipant, ITheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService';
|
||||
import { PANEL_BACKGROUND, PANEL_BORDER, PANEL_ACTIVE_TITLE_FOREGROUND, PANEL_INACTIVE_TITLE_FOREGROUND, PANEL_ACTIVE_TITLE_BORDER, PANEL_DRAG_AND_DROP_BACKGROUND, PANEL_INPUT_BORDER } from 'vs/workbench/common/theme';
|
||||
import { activeContrastBorder, focusBorder, contrastBorder, editorBackground, badgeBackground, badgeForeground } from 'vs/platform/theme/common/colorRegistry';
|
||||
@@ -28,17 +28,19 @@ 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 { localize } from 'vs/nls';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IDisposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { IContextKey, IContextKeyService, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { isUndefinedOrNull, assertIsDefined } from 'vs/base/common/types';
|
||||
import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
|
||||
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { ViewContainer, IViewContainersRegistry, Extensions as ViewContainerExtensions, IViewsService, IViewDescriptorCollection } from 'vs/workbench/common/views';
|
||||
|
||||
interface ICachedPanel {
|
||||
id: string;
|
||||
pinned: boolean;
|
||||
order?: number;
|
||||
visible: boolean;
|
||||
views?: { when?: string }[];
|
||||
}
|
||||
|
||||
export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
@@ -80,9 +82,13 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
private compositeBar: CompositeBar;
|
||||
private compositeActions: Map<string, { activityAction: PanelActivityAction, pinnedAction: ToggleCompositePinnedAction; }> = new Map();
|
||||
|
||||
private readonly panelDisposables: Map<string, IDisposable> = new Map<string, IDisposable>();
|
||||
|
||||
private blockOpeningPanel = false;
|
||||
private _contentDimension: Dimension | undefined;
|
||||
|
||||
private panelRegistry: PanelRegistry;
|
||||
|
||||
constructor(
|
||||
@INotificationService notificationService: INotificationService,
|
||||
@IStorageService storageService: IStorageService,
|
||||
@@ -92,8 +98,9 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
@IKeybindingService keybindingService: IKeybindingService,
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IContextKeyService contextKeyService: IContextKeyService,
|
||||
@ILifecycleService private readonly lifecycleService: ILifecycleService
|
||||
@IContextKeyService private readonly contextKeyService: IContextKeyService,
|
||||
@IExtensionService private readonly extensionService: IExtensionService,
|
||||
@IViewsService private readonly viewsService: IViewsService,
|
||||
) {
|
||||
super(
|
||||
notificationService,
|
||||
@@ -114,6 +121,8 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
{ hasTitle: true }
|
||||
);
|
||||
|
||||
this.panelRegistry = Registry.as<PanelRegistry>(PanelExtensions.Panels);
|
||||
|
||||
this.compositeBar = this._register(this.instantiationService.createInstance(CompositeBar, this.getCachedPanels(), {
|
||||
icon: false,
|
||||
orientation: ActionsOrientation.HORIZONTAL,
|
||||
@@ -127,8 +136,8 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
.filter(({ when }) => contextKeyService.contextMatchesRules(when))
|
||||
.map(({ id, label }) => this.instantiationService.createInstance(SetPanelPositionAction, id, label)),
|
||||
this.instantiationService.createInstance(TogglePanelAction, TogglePanelAction.ID, localize('hidePanel', "Hide Panel"))
|
||||
],
|
||||
getDefaultCompositeId: () => Registry.as<PanelRegistry>(PanelExtensions.Panels).getDefaultPanelId(),
|
||||
] as Action[],
|
||||
getDefaultCompositeId: () => this.panelRegistry.getDefaultPanelId(),
|
||||
hidePart: () => this.layoutService.setPanelHidden(true),
|
||||
compositeSize: 0,
|
||||
overflowActionSize: 44,
|
||||
@@ -144,47 +153,156 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
})
|
||||
}));
|
||||
|
||||
for (const panel of this.getPanels()) {
|
||||
this.compositeBar.addComposite(panel);
|
||||
}
|
||||
|
||||
this.activePanelContextKey = ActivePanelContext.bindTo(contextKeyService);
|
||||
this.panelFocusContextKey = PanelFocusContext.bindTo(contextKeyService);
|
||||
|
||||
this.registerListeners();
|
||||
this.onDidRegisterPanels([...this.getPanels()]);
|
||||
}
|
||||
|
||||
private onDidRegisterPanels(panels: PanelDescriptor[]): void {
|
||||
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;
|
||||
|
||||
if (isActive || !this.shouldBeHidden(panel.id, cachedPanel)) {
|
||||
this.compositeBar.addComposite(panel);
|
||||
|
||||
// Pin it by default if it is new
|
||||
if (!cachedPanel) {
|
||||
this.compositeBar.pin(panel.id);
|
||||
}
|
||||
|
||||
if (isActive) {
|
||||
this.compositeBar.activateComposite(panel.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const panel of panels) {
|
||||
this.enableCompositeActions(panel);
|
||||
const viewContainer = this.getViewContainer(panel.id);
|
||||
if (viewContainer?.hideIfEmpty) {
|
||||
const viewDescriptors = this.viewsService.getViewDescriptors(viewContainer);
|
||||
if (viewDescriptors) {
|
||||
this.onDidChangeActiveViews(panel, viewDescriptors);
|
||||
this.panelDisposables.set(panel.id, viewDescriptors.onDidChangeActiveViews(() => this.onDidChangeActiveViews(panel, viewDescriptors)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private onDidDeregisterPanel(panelId: string): void {
|
||||
const disposable = this.panelDisposables.get(panelId);
|
||||
if (disposable) {
|
||||
disposable.dispose();
|
||||
}
|
||||
|
||||
this.panelDisposables.delete(panelId);
|
||||
this.hideComposite(panelId);
|
||||
}
|
||||
|
||||
private enableCompositeActions(panel: PanelDescriptor): void {
|
||||
const { activityAction, pinnedAction } = this.getCompositeActions(panel.id);
|
||||
if (activityAction instanceof PlaceHolderPanelActivityAction) {
|
||||
activityAction.setActivity(panel);
|
||||
}
|
||||
|
||||
if (pinnedAction instanceof PlaceHolderToggleCompositePinnedAction) {
|
||||
pinnedAction.setActivity(panel);
|
||||
}
|
||||
}
|
||||
|
||||
private onDidChangeActiveViews(panel: PanelDescriptor, viewDescriptors: IViewDescriptorCollection): void {
|
||||
if (viewDescriptors.activeViewDescriptors.length) {
|
||||
this.compositeBar.addComposite(panel);
|
||||
} else {
|
||||
this.hideComposite(panel.id);
|
||||
}
|
||||
}
|
||||
|
||||
private shouldBeHidden(panelId: string, cachedPanel?: ICachedPanel): boolean {
|
||||
const viewContainer = this.getViewContainer(panelId);
|
||||
if (!viewContainer || !viewContainer.hideIfEmpty) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return cachedPanel?.views && cachedPanel.views.length
|
||||
? cachedPanel.views.every(({ when }) => !!when && !this.contextKeyService.contextMatchesRules(ContextKeyExpr.deserialize(when)))
|
||||
: false;
|
||||
}
|
||||
|
||||
private registerListeners(): void {
|
||||
// Panel registration
|
||||
this._register(this.registry.onDidRegister(panel => this.onDidRegisterPanels([panel])));
|
||||
this._register(this.registry.onDidDeregister(panel => this.onDidDeregisterPanel(panel.id)));
|
||||
|
||||
// Panel open/close
|
||||
// Activate on panel open
|
||||
this._register(this.onDidPanelOpen(({ panel }) => this.onPanelOpen(panel)));
|
||||
|
||||
// Deactivate on panel close
|
||||
this._register(this.onDidPanelClose(this.onPanelClose, this));
|
||||
|
||||
// Panel register/deregister
|
||||
this._register(this.registry.onDidRegister(panelDescriptor => this.compositeBar.addComposite(panelDescriptor)));
|
||||
this._register(this.registry.onDidDeregister(panelDescriptor => {
|
||||
this.compositeBar.hideComposite(panelDescriptor.id);
|
||||
this.removeComposite(panelDescriptor.id);
|
||||
// Extension registration
|
||||
let disposables = this._register(new DisposableStore());
|
||||
this._register(this.extensionService.onDidRegisterExtensions(() => {
|
||||
disposables.clear();
|
||||
this.onDidRegisterExtensions();
|
||||
this.compositeBar.onDidChange(() => this.saveCachedPanels(), this, disposables);
|
||||
this.storageService.onDidChangeStorage(e => this.onDidStorageChange(e), this, disposables);
|
||||
}));
|
||||
}
|
||||
|
||||
// Activate panel action on opening of a panel
|
||||
this._register(this.onDidPanelOpen(({ panel }) => {
|
||||
this.compositeBar.activateComposite(panel.getId());
|
||||
this.layoutCompositeBar(); // Need to relayout composite bar since different panels have different action bar width
|
||||
}));
|
||||
private onDidRegisterExtensions(): void {
|
||||
this.removeNotExistingComposites();
|
||||
|
||||
// Deactivate panel action on close
|
||||
this._register(this.onDidPanelClose(panel => this.compositeBar.deactivateComposite(panel.getId())));
|
||||
this.saveCachedPanels();
|
||||
}
|
||||
|
||||
// State
|
||||
this.lifecycleService.when(LifecyclePhase.Eventually).then(() => {
|
||||
this._register(this.compositeBar.onDidChange(() => this.saveCachedPanels()));
|
||||
this._register(this.storageService.onDidChangeStorage(e => this.onDidStorageChange(e)));
|
||||
});
|
||||
private removeNotExistingComposites(): void {
|
||||
const panels = this.getPanels();
|
||||
for (const { id } of this.getCachedPanels()) { // should this value match viewlet (load on ctor)
|
||||
if (panels.every(panel => panel.id !== id)) {
|
||||
this.hideComposite(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private hideComposite(compositeId: string): void {
|
||||
this.compositeBar.hideComposite(compositeId);
|
||||
|
||||
const compositeActions = this.compositeActions.get(compositeId);
|
||||
if (compositeActions) {
|
||||
compositeActions.activityAction.dispose();
|
||||
compositeActions.pinnedAction.dispose();
|
||||
this.compositeActions.delete(compositeId);
|
||||
}
|
||||
}
|
||||
|
||||
private onPanelOpen(panel: IPanel): void {
|
||||
this.activePanelContextKey.set(panel.getId());
|
||||
|
||||
const foundPanel = this.panelRegistry.getPanel(panel.getId());
|
||||
if (foundPanel) {
|
||||
this.compositeBar.addComposite(foundPanel);
|
||||
}
|
||||
|
||||
// Activate composite when opened
|
||||
this.compositeBar.activateComposite(panel.getId());
|
||||
|
||||
const panelDescriptor = this.panelRegistry.getPanel(panel.getId());
|
||||
if (panelDescriptor) {
|
||||
const viewContainer = this.getViewContainer(panelDescriptor.id);
|
||||
if (viewContainer?.hideIfEmpty) {
|
||||
const viewDescriptors = this.viewsService.getViewDescriptors(viewContainer);
|
||||
if (viewDescriptors?.activeViewDescriptors.length === 0) {
|
||||
this.hideComposite(panelDescriptor.id); // Update the composite bar by hiding
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.layoutCompositeBar(); // Need to relayout composite bar since different panels have different action bar width
|
||||
}
|
||||
|
||||
private onPanelClose(panel: IPanel): void {
|
||||
@@ -193,6 +311,8 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
if (this.activePanelContextKey.get() === id) {
|
||||
this.activePanelContextKey.reset();
|
||||
}
|
||||
|
||||
this.compositeBar.deactivateComposite(panel.getId());
|
||||
}
|
||||
|
||||
create(parent: HTMLElement): void {
|
||||
@@ -243,11 +363,11 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
}
|
||||
|
||||
getPanel(panelId: string): IPanelIdentifier | undefined {
|
||||
return Registry.as<PanelRegistry>(PanelExtensions.Panels).getPanel(panelId);
|
||||
return this.panelRegistry.getPanel(panelId);
|
||||
}
|
||||
|
||||
getPanels(): readonly PanelDescriptor[] {
|
||||
return Registry.as<PanelRegistry>(PanelExtensions.Panels).getPanels()
|
||||
return this.panelRegistry.getPanels()
|
||||
.sort((v1, v2) => typeof v1.order === 'number' && typeof v2.order === 'number' ? v1.order - v2.order : NaN);
|
||||
}
|
||||
|
||||
@@ -331,10 +451,18 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
private getCompositeActions(compositeId: string): { activityAction: PanelActivityAction, pinnedAction: ToggleCompositePinnedAction; } {
|
||||
let compositeActions = this.compositeActions.get(compositeId);
|
||||
if (!compositeActions) {
|
||||
compositeActions = {
|
||||
activityAction: this.instantiationService.createInstance(PanelActivityAction, assertIsDefined(this.getPanel(compositeId))),
|
||||
pinnedAction: new ToggleCompositePinnedAction(this.getPanel(compositeId), this.compositeBar)
|
||||
};
|
||||
const panel = this.getPanel(compositeId);
|
||||
if (panel) {
|
||||
compositeActions = {
|
||||
activityAction: new PanelActivityAction(assertIsDefined(this.getPanel(compositeId)), this),
|
||||
pinnedAction: new ToggleCompositePinnedAction(this.getPanel(compositeId), this.compositeBar)
|
||||
};
|
||||
} else {
|
||||
compositeActions = {
|
||||
activityAction: new PlaceHolderPanelActivityAction(compositeId, this),
|
||||
pinnedAction: new PlaceHolderToggleCompositePinnedAction(compositeId, this.compositeBar)
|
||||
};
|
||||
}
|
||||
|
||||
this.compositeActions.set(compositeId, compositeActions);
|
||||
}
|
||||
@@ -448,6 +576,11 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
this.storageService.store(PanelPart.PINNED_PANELS, value, StorageScope.GLOBAL);
|
||||
}
|
||||
|
||||
private getViewContainer(panelId: string): ViewContainer | undefined {
|
||||
const viewContainerRegistry = Registry.as<IViewContainersRegistry>(ViewContainerExtensions.ViewContainersRegistry);
|
||||
return viewContainerRegistry.get(panelId);
|
||||
}
|
||||
|
||||
toJSON(): object {
|
||||
return {
|
||||
type: Parts.PANEL_PART
|
||||
|
||||
@@ -495,14 +495,12 @@ export class CustomTreeView extends Disposable implements ITreeView {
|
||||
|
||||
private showMessage(message: string): void {
|
||||
DOM.removeClass(this.messageElement, 'hide');
|
||||
if (this._messageValue !== message) {
|
||||
this.resetMessageElement();
|
||||
this._messageValue = message;
|
||||
if (!isFalsyOrWhitespace(this._message)) {
|
||||
this.messageElement.textContent = this._messageValue;
|
||||
}
|
||||
this.layout(this._height, this._width);
|
||||
this.resetMessageElement();
|
||||
this._messageValue = message;
|
||||
if (!isFalsyOrWhitespace(this._message)) {
|
||||
this.messageElement.textContent = this._messageValue;
|
||||
}
|
||||
this.layout(this._height, this._width);
|
||||
}
|
||||
|
||||
private hideMessage(): void {
|
||||
|
||||
@@ -243,7 +243,7 @@ interface IViewPaneItem {
|
||||
|
||||
export class ViewPaneContainer extends Component implements IViewPaneContainer {
|
||||
|
||||
private readonly viewContainer: ViewContainer;
|
||||
readonly viewContainer: ViewContainer;
|
||||
private lastFocusedPane: ViewPane | undefined;
|
||||
private paneItems: IViewPaneItem[] = [];
|
||||
private paneview?: PaneView;
|
||||
|
||||
@@ -8,6 +8,21 @@ import * as nls from 'vs/nls';
|
||||
import { IConfigurationRegistry, Extensions as ConfigurationExtensions, ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { isMacintosh, isWindows, isLinux, isWeb, isNative } from 'vs/base/common/platform';
|
||||
import { workbenchConfigurationNodeBase } from 'vs/workbench/common/configuration';
|
||||
import { PanelRegistry, Extensions as PanelExtensions, PanelDescriptor, PaneCompositePanel } from 'vs/workbench/browser/panel';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { ViewContainer, IViewContainersRegistry, Extensions as ViewContainerExtensions, ViewContainerLocation } from 'vs/workbench/common/views';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
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';
|
||||
import { Viewlet, ViewletDescriptor, ViewletRegistry, Extensions as ViewletExtensions } from 'vs/workbench/browser/viewlet';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { isString } from 'vs/base/common/types';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
|
||||
// Configuration
|
||||
(function registerConfiguration(): void {
|
||||
@@ -373,3 +388,74 @@ import { workbenchConfigurationNodeBase } from 'vs/workbench/common/configuratio
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
// Viewlets & Panels
|
||||
(function registerViewletsAndPanels(): void {
|
||||
const registerPanel = (viewContainer: ViewContainer): void => {
|
||||
class PaneContainerPanel extends PaneCompositePanel {
|
||||
constructor(
|
||||
@ITelemetryService telemetryService: ITelemetryService,
|
||||
@IStorageService storageService: IStorageService,
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IContextMenuService contextMenuService: IContextMenuService,
|
||||
@IExtensionService extensionService: IExtensionService,
|
||||
@IWorkspaceContextService contextService: IWorkspaceContextService
|
||||
) {
|
||||
super(viewContainer.id, (instantiationService as any).createInstance(viewContainer.ctorDescriptor!.ctor, ...(viewContainer.ctorDescriptor!.arguments || [])), telemetryService, storageService, instantiationService, themeService, contextMenuService, extensionService, contextService);
|
||||
}
|
||||
}
|
||||
Registry.as<PanelRegistry>(PanelExtensions.Panels).registerPanel(PanelDescriptor.create(
|
||||
PaneContainerPanel,
|
||||
viewContainer.id,
|
||||
viewContainer.name,
|
||||
isString(viewContainer.icon) ? viewContainer.icon : undefined,
|
||||
viewContainer.order,
|
||||
viewContainer.focusCommand?.id,
|
||||
));
|
||||
};
|
||||
|
||||
const registerViewlet = (viewContainer: ViewContainer): void => {
|
||||
class PaneContainerViewlet extends Viewlet {
|
||||
constructor(
|
||||
@IConfigurationService configurationService: IConfigurationService,
|
||||
@IWorkbenchLayoutService layoutService: IWorkbenchLayoutService,
|
||||
@ITelemetryService telemetryService: ITelemetryService,
|
||||
@IWorkspaceContextService contextService: IWorkspaceContextService,
|
||||
@IStorageService storageService: IStorageService,
|
||||
@IEditorService editorService: IEditorService,
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IContextMenuService contextMenuService: IContextMenuService,
|
||||
@IExtensionService extensionService: IExtensionService
|
||||
) {
|
||||
super(viewContainer.id, (instantiationService as any).createInstance(viewContainer.ctorDescriptor!.ctor, ...(viewContainer.ctorDescriptor!.arguments || [])), telemetryService, storageService, instantiationService, themeService, contextMenuService, extensionService, contextService, layoutService, configurationService);
|
||||
}
|
||||
}
|
||||
const viewletDescriptor = ViewletDescriptor.create(
|
||||
PaneContainerViewlet,
|
||||
viewContainer.id,
|
||||
viewContainer.name,
|
||||
isString(viewContainer.icon) ? viewContainer.icon : undefined,
|
||||
viewContainer.order,
|
||||
viewContainer.icon instanceof URI ? viewContainer.icon : undefined
|
||||
);
|
||||
|
||||
Registry.as<ViewletRegistry>(ViewletExtensions.Viewlets).registerViewlet(viewletDescriptor);
|
||||
};
|
||||
|
||||
const viewContainerRegistry = Registry.as<IViewContainersRegistry>(ViewContainerExtensions.ViewContainersRegistry);
|
||||
viewContainerRegistry.getViewContainers(ViewContainerLocation.Panel).forEach(viewContainer => registerPanel(viewContainer));
|
||||
viewContainerRegistry.onDidRegister(({ viewContainer, viewContainerLocation }) => {
|
||||
switch (viewContainerLocation) {
|
||||
case ViewContainerLocation.Panel:
|
||||
registerPanel(viewContainer);
|
||||
return;
|
||||
case ViewContainerLocation.Sidebar:
|
||||
if (viewContainer.ctorDescriptor) {
|
||||
registerViewlet(viewContainer);
|
||||
}
|
||||
return;
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user