未验证 提交 5963a8eb 编写于 作者: S Sandeep Somavarapu 提交者: GitHub

Enabled movable Custom Views (#89240)

Enabled movable Custom Views
......@@ -807,6 +807,11 @@ export class WorkbenchDataTree<TInput, T, TFilterData = void> extends DataTree<T
this.internals = new WorkbenchTreeInternals(this, treeOptions, getAutomaticKeyboardNavigation, options.overrideStyles, contextKeyService, listService, themeService, configurationService, accessibilityService);
this.disposables.add(this.internals);
}
updateOptions(options: IWorkbenchAsyncDataTreeOptions<T, TFilterData> = {}): void {
super.updateOptions(options);
this.internals.updateStyleOverrides(options.overrideStyles);
}
}
export interface IWorkbenchAsyncDataTreeOptions<T, TFilterData> extends IAsyncDataTreeOptions<T, TFilterData> {
......@@ -839,6 +844,11 @@ export class WorkbenchAsyncDataTree<TInput, T, TFilterData = void> extends Async
this.internals = new WorkbenchTreeInternals(this, treeOptions, getAutomaticKeyboardNavigation, options.overrideStyles, contextKeyService, listService, themeService, configurationService, accessibilityService);
this.disposables.add(this.internals);
}
updateOptions(options: IWorkbenchAsyncDataTreeOptions<T, TFilterData> = {}): void {
super.updateOptions(options);
this.internals.updateStyleOverrides(options.overrideStyles);
}
}
export interface IWorkbenchCompressibleAsyncDataTreeOptions<T, TFilterData> extends ICompressibleAsyncDataTreeOptions<T, TFilterData> {
......@@ -936,15 +946,16 @@ class WorkbenchTreeInternals<TInput, T, TFilterData> {
private hasMultiSelection: IContextKey<boolean>;
private _useAltAsMultipleSelectionModifier: boolean;
private disposables: IDisposable[] = [];
private styler!: IDisposable;
constructor(
tree: WorkbenchObjectTree<T, TFilterData> | CompressibleObjectTree<T, TFilterData> | WorkbenchDataTree<TInput, T, TFilterData> | WorkbenchAsyncDataTree<TInput, T, TFilterData> | WorkbenchCompressibleAsyncDataTree<TInput, T, TFilterData>,
private tree: WorkbenchObjectTree<T, TFilterData> | CompressibleObjectTree<T, TFilterData> | WorkbenchDataTree<TInput, T, TFilterData> | WorkbenchAsyncDataTree<TInput, T, TFilterData> | WorkbenchCompressibleAsyncDataTree<TInput, T, TFilterData>,
options: IAbstractTreeOptions<T, TFilterData> | IAsyncDataTreeOptions<T, TFilterData>,
getAutomaticKeyboardNavigation: () => boolean | undefined,
overrideStyles: IColorMapping | undefined,
@IContextKeyService contextKeyService: IContextKeyService,
@IListService listService: IListService,
@IThemeService themeService: IThemeService,
@IThemeService private themeService: IThemeService,
@IConfigurationService configurationService: IConfigurationService,
@IAccessibilityService accessibilityService: IAccessibilityService,
) {
......@@ -970,10 +981,11 @@ class WorkbenchTreeInternals<TInput, T, TFilterData> {
});
};
this.updateStyleOverrides(overrideStyles);
this.disposables.push(
this.contextKeyService,
(listService as ListService).register(tree),
overrideStyles ? attachListStyler(tree, themeService, overrideStyles) : Disposable.None,
tree.onDidChangeSelection(() => {
const selection = tree.getSelection();
const focus = tree.getFocus();
......@@ -1023,8 +1035,14 @@ class WorkbenchTreeInternals<TInput, T, TFilterData> {
return this._useAltAsMultipleSelectionModifier;
}
updateStyleOverrides(overrideStyles?: IColorMapping): void {
dispose(this.styler);
this.styler = overrideStyles ? attachListStyler(this.tree, this.themeService, overrideStyles) : Disposable.None;
}
dispose(): void {
this.disposables = dispose(this.disposables);
this.styler = dispose(this.styler);
}
}
......
......@@ -399,8 +399,9 @@ class ViewsExtensionHandler implements IWorkbenchContribution {
ctorDescriptor: new SyncDescriptor(CustomTreeViewPane),
when: ContextKeyExpr.deserialize(item.when),
canToggleVisibility: true,
canMoveView: true,
treeView: this.instantiationService.createInstance(CustomTreeView, item.id, item.name),
collapsed: this.showCollapsed(container),
treeView: this.instantiationService.createInstance(CustomTreeView, item.id, item.name, container),
order: order,
extensionId: extension.description.identifier,
originalContainerId: entry.key,
......
......@@ -13,7 +13,7 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView
import { IMenuService, MenuId, MenuItemAction } from 'vs/platform/actions/common/actions';
import { ContextAwareMenuEntryActionViewItem, createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { ITreeView, ITreeItem, TreeItemCollapsibleState, ITreeViewDataProvider, TreeViewItemHandleArg, ITreeViewDescriptor, IViewsRegistry, ViewContainer, ITreeItemLabel, Extensions, IViewDescriptorService } from 'vs/workbench/common/views';
import { ITreeView, ITreeItem, TreeItemCollapsibleState, ITreeViewDataProvider, TreeViewItemHandleArg, ITreeViewDescriptor, IViewsRegistry, ITreeItemLabel, Extensions, IViewDescriptorService, ViewContainer, ViewContainerLocation } from 'vs/workbench/common/views';
import { IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { INotificationService } from 'vs/platform/notification/common/notification';
......@@ -41,7 +41,7 @@ import { ITreeRenderer, ITreeNode, IAsyncDataSource, ITreeContextMenuEvent } fro
import { FuzzyScore, createMatches } from 'vs/base/common/filters';
import { CollapseAllAction } from 'vs/base/browser/ui/tree/treeDefaults';
import { isFalsyOrWhitespace } from 'vs/base/common/strings';
import { SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme';
import { SIDE_BAR_BACKGROUND, PANEL_BACKGROUND } from 'vs/workbench/common/theme';
export class CustomTreeViewPane extends ViewPane {
......@@ -154,7 +154,6 @@ export class CustomTreeView extends Disposable implements ITreeView {
constructor(
private id: string,
private _title: string,
private viewContainer: ViewContainer,
@IExtensionService private readonly extensionService: IExtensionService,
@IWorkbenchThemeService private readonly themeService: IWorkbenchThemeService,
@IInstantiationService private readonly instantiationService: IInstantiationService,
......@@ -163,7 +162,8 @@ export class CustomTreeView extends Disposable implements ITreeView {
@IProgressService private readonly progressService: IProgressService,
@IContextMenuService private readonly contextMenuService: IContextMenuService,
@IKeybindingService private readonly keybindingService: IKeybindingService,
@INotificationService private readonly notificationService: INotificationService
@INotificationService private readonly notificationService: INotificationService,
@IViewDescriptorService private readonly viewDescriptorService: IViewDescriptorService
) {
super();
this.root = new Root();
......@@ -174,14 +174,23 @@ export class CustomTreeView extends Disposable implements ITreeView {
this.doRefresh([this.root]); /** soft refresh **/
}
}));
this._register(Registry.as<IViewsRegistry>(Extensions.ViewsRegistry).onDidChangeContainer(({ views, from, to }) => {
if (from === this.viewContainer && views.some(v => v.id === this.id)) {
this.viewContainer = to;
this._register(this.viewDescriptorService.onDidChangeLocation(({ views, from, to }) => {
if (views.some(v => v.id === this.id)) {
this.tree?.updateOptions({ overrideStyles: { listBackground: this.viewLocation === ViewContainerLocation.Sidebar ? SIDE_BAR_BACKGROUND : PANEL_BACKGROUND } });
}
}));
this.create();
}
get viewContainer(): ViewContainer {
return this.viewDescriptorService.getViewContainer(this.id)!;
}
get viewLocation(): ViewContainerLocation {
return this.viewDescriptorService.getViewLocation(this.id)!;
}
private _dataProvider: ITreeViewDataProvider | undefined;
get dataProvider(): ITreeViewDataProvider | undefined {
return this._dataProvider;
......@@ -360,7 +369,7 @@ export class CustomTreeView extends Disposable implements ITreeView {
},
multipleSelectionSupport: this.canSelectMany,
overrideStyles: {
listBackground: SIDE_BAR_BACKGROUND
listBackground: this.viewLocation === ViewContainerLocation.Sidebar ? SIDE_BAR_BACKGROUND : PANEL_BACKGROUND
}
}) as WorkbenchAsyncDataTree<ITreeItem, ITreeItem, FuzzyScore>);
aligner.tree = this.tree;
......
......@@ -91,7 +91,7 @@ export abstract class ViewPane extends Pane implements IView {
@IContextMenuService protected contextMenuService: IContextMenuService,
@IConfigurationService protected readonly configurationService: IConfigurationService,
@IContextKeyService contextKeyService: IContextKeyService,
@IViewDescriptorService private viewDescriptorService: IViewDescriptorService,
@IViewDescriptorService protected viewDescriptorService: IViewDescriptorService,
@IInstantiationService protected instantiationService: IInstantiationService,
) {
super(options);
......
......@@ -349,10 +349,8 @@ export interface IViewsViewlet extends IViewlet {
}
export const IViewDescriptorService = createDecorator<IViewDescriptorService>('viewDescriptorService');
export const IViewsService = createDecorator<IViewsService>('viewsService');
export interface IViewsService {
_serviceBrand: undefined;
......@@ -361,11 +359,15 @@ export interface IViewsService {
openView(id: string, focus?: boolean): Promise<IView | null>;
}
export const IViewDescriptorService = createDecorator<IViewDescriptorService>('viewDescriptorService');
export interface IViewDescriptorService {
_serviceBrand: undefined;
readonly onDidChangeContainer: Event<{ views: IViewDescriptor[], from: ViewContainer, to: ViewContainer }>;
readonly onDidChangeLocation: Event<{ views: IViewDescriptor[], from: ViewContainerLocation, to: ViewContainerLocation }>;
moveViewToLocation(view: IViewDescriptor, location: ViewContainerLocation): void;
moveViewsToContainer(views: IViewDescriptor[], viewContainer: ViewContainer): void;
......@@ -443,9 +445,7 @@ export interface IRevealOptions {
}
export interface ITreeViewDescriptor extends IViewDescriptor {
readonly treeView: ITreeView;
treeView: ITreeView;
}
export type TreeViewItemHandleArg = {
......
......@@ -47,7 +47,6 @@ import { basename } from 'vs/base/common/resources';
import { IDataSource } from 'vs/base/browser/ui/tree/tree';
import { IMarkerDecorationsService } from 'vs/editor/common/services/markersDecorationService';
import { MarkerSeverity } from 'vs/platform/markers/common/markers';
import { SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme';
import { IViewDescriptorService } from 'vs/workbench/common/views';
class RequestState {
......@@ -335,13 +334,19 @@ export class OutlinePane extends ViewPane {
keyboardNavigationLabelProvider: new OutlineNavigationLabelProvider(),
hideTwistiesOfChildlessElements: true,
overrideStyles: {
listBackground: SIDE_BAR_BACKGROUND
listBackground: this.getBackgroundColor()
}
}
);
this._disposables.push(this._tree);
this._disposables.push(this._outlineViewState.onDidChange(this._onDidChangeUserState, this));
this._disposables.push(this.viewDescriptorService.onDidChangeLocation(({ views, from, to }) => {
if (views.some(v => v.id === this.id)) {
this._tree.updateOptions({ overrideStyles: { listBackground: this.getBackgroundColor() } });
}
}));
// override the globally defined behaviour
this._tree.updateOptions({
......
......@@ -181,6 +181,12 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor
private static readonly CACHED_VIEW_POSITIONS = 'views.cachedViewPositions';
private static readonly COMMON_CONTAINER_ID_PREFIX = 'workbench.views.service';
private readonly _onDidChangeContainer: Emitter<{ views: IViewDescriptor[], from: ViewContainer, to: ViewContainer }> = this._register(new Emitter<{ views: IViewDescriptor[], from: ViewContainer, to: ViewContainer }>());
readonly onDidChangeContainer: Event<{ views: IViewDescriptor[], from: ViewContainer, to: ViewContainer }> = this._onDidChangeContainer.event;
private readonly _onDidChangeLocation: Emitter<{ views: IViewDescriptor[], from: ViewContainerLocation, to: ViewContainerLocation }> = this._register(new Emitter<{ views: IViewDescriptor[], from: ViewContainerLocation, to: ViewContainerLocation }>());
readonly onDidChangeLocation: Event<{ views: IViewDescriptor[], from: ViewContainerLocation, to: ViewContainerLocation }> = this._onDidChangeLocation.event;
private readonly viewDescriptorCollections: Map<ViewContainer, { viewDescriptorCollection: ViewDescriptorCollection, disposable: IDisposable; }>;
private readonly activeViewContextKeys: Map<string, IContextKey<boolean>>;
private readonly movableViewContextKeys: Map<string, IContextKey<boolean>>;
......@@ -230,7 +236,7 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor
this._register(this.viewsRegistry.onViewsRegistered(({ views, viewContainer }) => this.onDidRegisterViews(views, viewContainer)));
this._register(this.viewsRegistry.onViewsDeregistered(({ views, viewContainer }) => this.onDidDeregisterViews(views, viewContainer)));
this._register(this.viewsRegistry.onDidChangeContainer(({ views, from, to }) => { this.removeViews(from, views); this.addViews(to, views); }));
this._register(this.viewsRegistry.onDidChangeContainer(({ views, from, to }) => { this.removeViews(from, views); this.addViews(to, views); this._onDidChangeContainer.fire({ views, from, to }); }));
this._register(this.viewContainersRegistry.onDidRegister(({ viewContainer }) => this.onDidRegisterViewContainer(viewContainer)));
this._register(this.viewContainersRegistry.onDidDeregister(({ viewContainer }) => this.onDidDeregisterViewContainer(viewContainer)));
......@@ -295,6 +301,11 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor
const viewDescriptor = this.getViewDescriptor(viewId);
if (viewContainer && viewDescriptor) {
this.addViews(viewContainer, [viewDescriptor]);
const newLocation = this.viewContainersRegistry.getViewContainerLocation(viewContainer)!;
if (containerInfo.location && containerInfo.location !== newLocation) {
this._onDidChangeLocation.fire({ views: [viewDescriptor], from: containerInfo.location, to: newLocation });
}
}
}
......@@ -357,6 +368,7 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor
getViewContainer(viewId: string): ViewContainer | null {
const containerId = this.cachedViewInfo.get(viewId)?.containerId;
return containerId ?
this.viewContainersRegistry.get(containerId) ?? null :
this.viewsRegistry.getViewContainer(viewId);
......@@ -395,6 +407,15 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor
if (from && to && from !== to) {
this.removeViews(from, views);
this.addViews(to, views);
const oldLocation = this.viewContainersRegistry.getViewContainerLocation(from)!;
const newLocation = this.viewContainersRegistry.getViewContainerLocation(to)!;
if (oldLocation !== newLocation) {
this._onDidChangeLocation.fire({ views, from: oldLocation, to: newLocation });
}
this._onDidChangeContainer.fire({ views, from, to });
this.saveViewPositionsToCache();
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册