support contextual title via containerTitle
This commit is contained in:
parent
b01489a20e
commit
56b8c19205
5 changed files with 84 additions and 8 deletions
|
@ -412,6 +412,7 @@ class ViewsExtensionHandler implements IWorkbenchContribution {
|
||||||
ctorDescriptor: new SyncDescriptor(TreeViewPane),
|
ctorDescriptor: new SyncDescriptor(TreeViewPane),
|
||||||
when: ContextKeyExpr.deserialize(item.when),
|
when: ContextKeyExpr.deserialize(item.when),
|
||||||
containerIcon: viewContainer?.icon,
|
containerIcon: viewContainer?.icon,
|
||||||
|
containerTitle: viewContainer?.name,
|
||||||
canToggleVisibility: true,
|
canToggleVisibility: true,
|
||||||
canMoveView: true,
|
canMoveView: true,
|
||||||
treeView: this.instantiationService.createInstance(CustomTreeView, item.id, item.name),
|
treeView: this.instantiationService.createInstance(CustomTreeView, item.id, item.name),
|
||||||
|
|
|
@ -50,11 +50,17 @@ interface ICachedPanel {
|
||||||
views?: { when?: string }[];
|
views?: { when?: string }[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface IPlaceholderViewContainer {
|
||||||
|
id: string;
|
||||||
|
name?: string;
|
||||||
|
}
|
||||||
|
|
||||||
export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||||
|
|
||||||
static readonly activePanelSettingsKey = 'workbench.panelpart.activepanelid';
|
static readonly activePanelSettingsKey = 'workbench.panelpart.activepanelid';
|
||||||
|
|
||||||
static readonly PINNED_PANELS = 'workbench.panel.pinnedPanels';
|
static readonly PINNED_PANELS = 'workbench.panel.pinnedPanels';
|
||||||
|
static readonly PLACEHOLDER_VIEW_CONTAINERS = 'workbench.panel.placeholderPanels';
|
||||||
private static readonly MIN_COMPOSITE_BAR_WIDTH = 50;
|
private static readonly MIN_COMPOSITE_BAR_WIDTH = 50;
|
||||||
|
|
||||||
_serviceBrand: undefined;
|
_serviceBrand: undefined;
|
||||||
|
@ -94,6 +100,8 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||||
private blockOpeningPanel = false;
|
private blockOpeningPanel = false;
|
||||||
private contentDimension: Dimension | undefined;
|
private contentDimension: Dimension | undefined;
|
||||||
|
|
||||||
|
private extensionsRegistered = false;
|
||||||
|
|
||||||
private panelRegistry: PanelRegistry;
|
private panelRegistry: PanelRegistry;
|
||||||
|
|
||||||
private dndHandler: ICompositeDragAndDrop;
|
private dndHandler: ICompositeDragAndDrop;
|
||||||
|
@ -255,9 +263,11 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateActivity(viewContainer: ViewContainer, viewContainerModel: IViewContainerModel): void {
|
private updateActivity(viewContainer: ViewContainer, viewContainerModel: IViewContainerModel): void {
|
||||||
|
const cachedTitle = this.getPlaceholderViewContainers().filter(panel => panel.id === viewContainer.id)[0]?.name;
|
||||||
|
|
||||||
const activity: IActivity = {
|
const activity: IActivity = {
|
||||||
id: viewContainer.id,
|
id: viewContainer.id,
|
||||||
name: viewContainerModel.title,
|
name: this.extensionsRegistered || cachedTitle === undefined ? viewContainerModel.title : cachedTitle,
|
||||||
keybindingId: viewContainer.focusCommand?.id
|
keybindingId: viewContainer.focusCommand?.id
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -268,7 +278,10 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||||
pinnedAction.setActivity(activity);
|
pinnedAction.setActivity(activity);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.saveCachedPanels();
|
// only update our cached panel info after extensions are done registering
|
||||||
|
if (this.extensionsRegistered) {
|
||||||
|
this.saveCachedPanels();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private onDidChangeActiveViews(viewContainer: ViewContainer, viewContainerModel: IViewContainerModel): void {
|
private onDidChangeActiveViews(viewContainer: ViewContainer, viewContainerModel: IViewContainerModel): void {
|
||||||
|
@ -313,6 +326,7 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private onDidRegisterExtensions(): void {
|
private onDidRegisterExtensions(): void {
|
||||||
|
this.extensionsRegistered = true;
|
||||||
this.removeNotExistingComposites();
|
this.removeNotExistingComposites();
|
||||||
|
|
||||||
this.saveCachedPanels();
|
this.saveCachedPanels();
|
||||||
|
@ -670,6 +684,7 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||||
|
|
||||||
private saveCachedPanels(): void {
|
private saveCachedPanels(): void {
|
||||||
const state: ICachedPanel[] = [];
|
const state: ICachedPanel[] = [];
|
||||||
|
const placeholders: IPlaceholderViewContainer[] = [];
|
||||||
|
|
||||||
const compositeItems = this.compositeBar.getCompositeBarItems();
|
const compositeItems = this.compositeBar.getCompositeBarItems();
|
||||||
for (const compositeItem of compositeItems) {
|
for (const compositeItem of compositeItems) {
|
||||||
|
@ -677,10 +692,12 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||||
if (viewContainer) {
|
if (viewContainer) {
|
||||||
const viewContainerModel = this.viewDescriptorService.getViewContainerModel(viewContainer);
|
const viewContainerModel = this.viewDescriptorService.getViewContainerModel(viewContainer);
|
||||||
state.push({ id: compositeItem.id, name: viewContainerModel.title, pinned: compositeItem.pinned, order: compositeItem.order, visible: compositeItem.visible });
|
state.push({ id: compositeItem.id, name: viewContainerModel.title, pinned: compositeItem.pinned, order: compositeItem.order, visible: compositeItem.visible });
|
||||||
|
placeholders.push({ id: compositeItem.id, name: this.getCompositeActions(compositeItem.id).activityAction.label });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.cachedPanelsValue = JSON.stringify(state);
|
this.cachedPanelsValue = JSON.stringify(state);
|
||||||
|
this.setPlaceholderViewContainers(placeholders);
|
||||||
}
|
}
|
||||||
|
|
||||||
private getCachedPanels(): ICachedPanel[] {
|
private getCachedPanels(): ICachedPanel[] {
|
||||||
|
@ -694,6 +711,13 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||||
return serialized;
|
return serialized;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
for (const placeholderViewContainer of this.getPlaceholderViewContainers()) {
|
||||||
|
const cachedViewContainer = cachedPanels.filter(cached => cached.id === placeholderViewContainer.id)[0];
|
||||||
|
if (cachedViewContainer) {
|
||||||
|
cachedViewContainer.name = placeholderViewContainer.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return cachedPanels;
|
return cachedPanels;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -721,6 +745,38 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||||
this.storageService.store(PanelPart.PINNED_PANELS, value, StorageScope.GLOBAL);
|
this.storageService.store(PanelPart.PINNED_PANELS, value, StorageScope.GLOBAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getPlaceholderViewContainers(): IPlaceholderViewContainer[] {
|
||||||
|
return JSON.parse(this.placeholderViewContainersValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private setPlaceholderViewContainers(placeholderViewContainers: IPlaceholderViewContainer[]): void {
|
||||||
|
this.placeholderViewContainersValue = JSON.stringify(placeholderViewContainers);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _placeholderViewContainersValue: string | undefined;
|
||||||
|
private get placeholderViewContainersValue(): string {
|
||||||
|
if (!this._placeholderViewContainersValue) {
|
||||||
|
this._placeholderViewContainersValue = this.getStoredPlaceholderViewContainersValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._placeholderViewContainersValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private set placeholderViewContainersValue(placeholderViewContainesValue: string) {
|
||||||
|
if (this.placeholderViewContainersValue !== placeholderViewContainesValue) {
|
||||||
|
this._placeholderViewContainersValue = placeholderViewContainesValue;
|
||||||
|
this.setStoredPlaceholderViewContainersValue(placeholderViewContainesValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private getStoredPlaceholderViewContainersValue(): string {
|
||||||
|
return this.storageService.get(PanelPart.PLACEHOLDER_VIEW_CONTAINERS, StorageScope.WORKSPACE, '[]');
|
||||||
|
}
|
||||||
|
|
||||||
|
private setStoredPlaceholderViewContainersValue(value: string): void {
|
||||||
|
this.storageService.store(PanelPart.PLACEHOLDER_VIEW_CONTAINERS, value, StorageScope.WORKSPACE);
|
||||||
|
}
|
||||||
|
|
||||||
private getViewContainer(panelId: string): ViewContainer | undefined {
|
private getViewContainer(panelId: string): ViewContainer | undefined {
|
||||||
return this.viewDescriptorService.getViewContainerById(panelId) || undefined;
|
return this.viewDescriptorService.getViewContainerById(panelId) || undefined;
|
||||||
}
|
}
|
||||||
|
|
|
@ -290,6 +290,10 @@ export abstract class ViewPane extends Pane implements IView {
|
||||||
this._register(this.toolbar);
|
this._register(this.toolbar);
|
||||||
this.setActions();
|
this.setActions();
|
||||||
|
|
||||||
|
this._register(this.viewDescriptorService.getViewContainerModel(this.viewDescriptorService.getViewContainerByViewId(this.id)!)!.onDidChangeContainerInfo(({ title }) => {
|
||||||
|
this.updateTitle(this.title);
|
||||||
|
}));
|
||||||
|
|
||||||
const onDidRelevantConfigurationChange = Event.filter(this.configurationService.onDidChangeConfiguration, e => e.affectsConfiguration(ViewPane.AlwaysShowActionsConfig));
|
const onDidRelevantConfigurationChange = Event.filter(this.configurationService.onDidChangeConfiguration, e => e.affectsConfiguration(ViewPane.AlwaysShowActionsConfig));
|
||||||
this._register(onDidRelevantConfigurationChange(this.updateActionsVisibility, this));
|
this._register(onDidRelevantConfigurationChange(this.updateActionsVisibility, this));
|
||||||
this.updateActionsVisibility();
|
this.updateActionsVisibility();
|
||||||
|
@ -300,17 +304,30 @@ export abstract class ViewPane extends Pane implements IView {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected renderHeaderTitle(container: HTMLElement, title: string): void {
|
protected renderHeaderTitle(container: HTMLElement, title: string): void {
|
||||||
this.titleContainer = append(container, $('h3.title', undefined, title));
|
this.titleContainer = append(container, $('h3.title', undefined, this.calculateTitle(title)));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected updateTitle(title: string): void {
|
updateTitle(title: string): void {
|
||||||
if (this.titleContainer) {
|
if (this.titleContainer) {
|
||||||
this.titleContainer.textContent = title;
|
this.titleContainer.textContent = this.calculateTitle(title);
|
||||||
}
|
}
|
||||||
this.title = title;
|
this.title = title;
|
||||||
this._onDidChangeTitleArea.fire();
|
this._onDidChangeTitleArea.fire();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private calculateTitle(title: string): string {
|
||||||
|
const viewContainer = this.viewDescriptorService.getViewContainerByViewId(this.id)!;
|
||||||
|
const model = this.viewDescriptorService.getViewContainerModel(viewContainer);
|
||||||
|
const viewDescriptor = this.viewDescriptorService.getViewDescriptorById(this.id)!;
|
||||||
|
const isDefault = this.viewDescriptorService.getDefaultContainerById(this.id) === viewContainer;
|
||||||
|
|
||||||
|
if (!isDefault && viewDescriptor.containerTitle && model.title !== viewDescriptor.containerTitle) {
|
||||||
|
return `${viewDescriptor.containerTitle}: ${title}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
private scrollableElement!: DomScrollableElement;
|
private scrollableElement!: DomScrollableElement;
|
||||||
|
|
||||||
protected renderBody(container: HTMLElement): void {
|
protected renderBody(container: HTMLElement): void {
|
||||||
|
@ -510,7 +527,6 @@ export abstract class ViewPane extends Pane implements IView {
|
||||||
|
|
||||||
export interface IViewPaneContainerOptions extends IPaneViewOptions {
|
export interface IViewPaneContainerOptions extends IPaneViewOptions {
|
||||||
mergeViewWithContainerWhenSingleView: boolean;
|
mergeViewWithContainerWhenSingleView: boolean;
|
||||||
donotShowContainerTitleWhenMergedWithContainer?: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IViewPaneItem {
|
interface IViewPaneItem {
|
||||||
|
@ -904,7 +920,7 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer {
|
||||||
|
|
||||||
if (this.isViewMergedWithContainer()) {
|
if (this.isViewMergedWithContainer()) {
|
||||||
const paneItemTitle = this.paneItems[0].pane.title;
|
const paneItemTitle = this.paneItems[0].pane.title;
|
||||||
if (this.options.donotShowContainerTitleWhenMergedWithContainer || containerTitle === paneItemTitle) {
|
if (containerTitle === paneItemTitle) {
|
||||||
return this.paneItems[0].pane.title;
|
return this.paneItems[0].pane.title;
|
||||||
}
|
}
|
||||||
return paneItemTitle ? `${containerTitle}: ${paneItemTitle}` : containerTitle;
|
return paneItemTitle ? `${containerTitle}: ${paneItemTitle}` : containerTitle;
|
||||||
|
@ -1227,6 +1243,7 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer {
|
||||||
this.updateTitleArea();
|
this.updateTitleArea();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const onDidChangeVisibility = pane.onDidChangeBodyVisibility(() => this._onDidChangeViewVisibility.fire(pane));
|
const onDidChangeVisibility = pane.onDidChangeBodyVisibility(() => this._onDidChangeViewVisibility.fire(pane));
|
||||||
const onDidChange = pane.onDidChange(() => {
|
const onDidChange = pane.onDidChange(() => {
|
||||||
if (pane === this.lastFocusedPane && !pane.isExpanded()) {
|
if (pane === this.lastFocusedPane && !pane.isExpanded()) {
|
||||||
|
|
|
@ -211,6 +211,8 @@ export interface IViewDescriptor {
|
||||||
|
|
||||||
readonly containerIcon?: string | URI;
|
readonly containerIcon?: string | URI;
|
||||||
|
|
||||||
|
readonly containerTitle?: string;
|
||||||
|
|
||||||
// Applies only to newly created views
|
// Applies only to newly created views
|
||||||
readonly hideByDefault?: boolean;
|
readonly hideByDefault?: boolean;
|
||||||
|
|
||||||
|
|
|
@ -342,7 +342,7 @@ export class ViewContainerModel extends Disposable implements IViewContainerMode
|
||||||
private updateContainerInfo(): void {
|
private updateContainerInfo(): void {
|
||||||
/* Use default container info if one of the visible view descriptors belongs to the current container by default */
|
/* Use default container info if one of the visible view descriptors belongs to the current container by default */
|
||||||
const useDefaultContainerInfo = this.container.alwaysUseContainerInfo || this.visibleViewDescriptors.length === 0 || this.visibleViewDescriptors.some(v => Registry.as<IViewsRegistry>(ViewExtensions.ViewsRegistry).getViewContainer(v.id) === this.container);
|
const useDefaultContainerInfo = this.container.alwaysUseContainerInfo || this.visibleViewDescriptors.length === 0 || this.visibleViewDescriptors.some(v => Registry.as<IViewsRegistry>(ViewExtensions.ViewsRegistry).getViewContainer(v.id) === this.container);
|
||||||
const title = useDefaultContainerInfo ? this.container.name : this.visibleViewDescriptors[0]?.name || '';
|
const title = useDefaultContainerInfo ? this.container.name : this.visibleViewDescriptors[0]?.containerTitle || this.visibleViewDescriptors[0]?.name || '';
|
||||||
let titleChanged: boolean = false;
|
let titleChanged: boolean = false;
|
||||||
if (this._title !== title) {
|
if (this._title !== title) {
|
||||||
this._title = title;
|
this._title = title;
|
||||||
|
|
Loading…
Reference in a new issue