feat: render mode

This commit is contained in:
mathuo 2024-01-10 22:34:37 +00:00
parent ccef43cb82
commit 718e3344ca
No known key found for this signature in database
GPG Key ID: C6EEDEFD6CA07281
7 changed files with 67 additions and 48 deletions

View File

@ -10,6 +10,7 @@ import { PanelUpdateEvent } from '../../../../panel/types';
import { IDockviewPanel } from '../../../../dockview/dockviewPanel';
import { IDockviewPanelModel } from '../../../../dockview/dockviewPanelModel';
import { DockviewComponent } from '../../../../dockview/dockviewComponent';
import { OverlayRenderContainer } from '../../../../overlayRenderContainer';
class TestContentRenderer
extends CompositeDisposable
@ -61,6 +62,9 @@ describe('contentContainer', () => {
const dockviewComponent = jest.fn<DockviewComponent, []>(() => {
return {
renderer: 'onlyWhenVisibile',
overlayRenderContainer: new OverlayRenderContainer(
document.createElement('div')
),
} as DockviewComponent;
});

View File

@ -21,6 +21,7 @@ import { IDockviewPanelModel } from '../../dockview/dockviewPanelModel';
import { DockviewGroupPanel } from '../../dockview/dockviewGroupPanel';
import { WatermarkRendererInitParameters } from '../../dockview/types';
import { createOffsetDragOverEvent } from '../__test_utils__/utils';
import { OverlayRenderContainer } from '../../overlayRenderContainer';
enum GroupChangeKind2 {
ADD_PANEL,
@ -227,7 +228,7 @@ export class TestPanel implements IDockviewPanel {
}
}
describe('groupview', () => {
describe('dockviewGroupPanelModel', () => {
let groupview: DockviewGroupPanel;
let dockview: DockviewComponent;
let options: GroupOptions;
@ -250,6 +251,9 @@ describe('groupview', () => {
removeGroup: removeGroupMock,
onDidAddPanel: () => ({ dispose: jest.fn() }),
onDidRemovePanel: () => ({ dispose: jest.fn() }),
overlayRenderContainer: new OverlayRenderContainer(
document.createElement('div')
),
}) as DockviewComponent;
groupview = new DockviewGroupPanel(dockview, 'groupview-1', options);
@ -791,6 +795,9 @@ describe('groupview', () => {
doSetGroupActive: jest.fn(),
onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(),
overlayRenderContainer: new OverlayRenderContainer(
document.createElement('div')
),
};
});
const accessor = new accessorMock() as DockviewComponent;
@ -861,6 +868,9 @@ describe('groupview', () => {
doSetGroupActive: jest.fn(),
onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(),
overlayRenderContainer: new OverlayRenderContainer(
document.createElement('div')
),
};
});
const accessor = new accessorMock() as DockviewComponent;
@ -936,6 +946,9 @@ describe('groupview', () => {
doSetGroupActive: jest.fn(),
onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(),
overlayRenderContainer: new OverlayRenderContainer(
document.createElement('div')
),
};
});
const accessor = new accessorMock() as DockviewComponent;

View File

@ -100,10 +100,7 @@ describe('overlayRenderContainer', () => {
})
);
const container = cut.setReferenceContentContainer(
panel,
referenceContainer
);
const container = cut.attach({ panel, referenceContainer });
await exhaustMicrotaskQueue();

View File

@ -22,7 +22,7 @@ export interface IContentContainer extends IDisposable {
closePanel: () => void;
show(): void;
hide(): void;
renderPanel(panel: IDockviewPanel): void;
renderPanel(panel: IDockviewPanel, options: { asActive: boolean }): void;
}
export class ContentContainer
@ -114,16 +114,33 @@ export class ContentContainer
this.element.style.display = 'none';
}
renderPanel(panel: IDockviewPanel): void {
const isActive = panel === this.group.activePanel;
renderPanel(
panel: IDockviewPanel,
options: { asActive: boolean } = { asActive: true }
): void {
const doRender =
options.asActive ||
(this.panel && this.group.isPanelActive(this.panel));
if (
this.panel &&
this.panel.view.content.element.parentElement === this._element
) {
/**
* If the currently attached panel is mounted directly to the content then remove it
*/
this._element.removeChild(this.panel.view.content.element);
}
this.panel = panel;
let container: HTMLElement;
switch (panel.api.renderer) {
case 'onlyWhenVisibile':
this.accessor.overlayRenderContainer.remove(panel);
if (isActive) {
if (this.panel) {
this.accessor.overlayRenderContainer.detatch(panel);
if (this.panel) {
if (doRender) {
this._element.appendChild(
this.panel.view.content.element
);
@ -137,15 +154,14 @@ export class ContentContainer
) {
this._element.removeChild(panel.view.content.element);
}
container =
this.accessor.overlayRenderContainer.setReferenceContentContainer(
panel,
this
);
container = this.accessor.overlayRenderContainer.attach({
panel,
referenceContainer: this,
});
break;
}
if (isActive) {
if (doRender) {
const _onDidFocus = panel.view.content.onDidFocus;
const _onDidBlur = panel.view.content.onDidBlur;

View File

@ -1215,7 +1215,7 @@ export class DockviewComponent
group.model.removePanel(panel);
if (!options.skipDispose) {
this.overlayRenderContainer.remove(panel);
this.overlayRenderContainer.detatch(panel);
panel.dispose();
}

View File

@ -404,7 +404,7 @@ export class DockviewGroupPanelModel
}
rerender(panel: IDockviewPanel): void {
this.contentContainer.renderPanel(panel);
this.contentContainer.renderPanel(panel, { asActive: false });
}
public indexOf(panel: IDockviewPanel): number {

View File

@ -1,12 +1,7 @@
import { DragAndDropObserver } from './dnd/dnd';
import { Droptarget } from './dnd/droptarget';
import { getDomNodePagePosition, toggleClass } from './dom';
import {
CompositeDisposable,
Disposable,
IDisposable,
MutableDisposable,
} from './lifecycle';
import { CompositeDisposable, Disposable, IDisposable } from './lifecycle';
import { IDockviewPanel } from './dockview/dockviewPanel';
export type DockviewPanelRenderer = 'onlyWhenVisibile' | 'always';
@ -33,10 +28,6 @@ export class OverlayRenderContainer extends CompositeDisposable {
}
> = {};
get allIds(): string[] {
return Object.keys(this.map);
}
constructor(private readonly element: HTMLElement) {
super();
@ -50,7 +41,7 @@ export class OverlayRenderContainer extends CompositeDisposable {
);
}
remove(panel: IDockviewPanel): boolean {
detatch(panel: IDockviewPanel): boolean {
if (this.map[panel.api.id]) {
this.map[panel.api.id].disposable.dispose();
delete this.map[panel.api.id];
@ -59,10 +50,12 @@ export class OverlayRenderContainer extends CompositeDisposable {
return false;
}
setReferenceContentContainer(
panel: IDockviewPanel,
referenceContainer: IRenderable
): HTMLElement {
attach(options: {
panel: IDockviewPanel;
referenceContainer: IRenderable;
}): HTMLElement {
const { panel, referenceContainer } = options;
if (!this.map[panel.api.id]) {
const element = createFocusableElement();
element.className = 'dv-render-overlay';
@ -110,17 +103,14 @@ export class OverlayRenderContainer extends CompositeDisposable {
focusContainer.style.display = panel.api.isVisible ? '' : 'none';
};
const whenVisible = <T>(func: (event: T) => void) => {
return (event: T) => {
if (!panel.api.isVisible) {
return;
}
func(event);
};
};
const disposable = new CompositeDisposable(
/**
* since container is positioned absoutely we must explicitly forward
* the dnd events for the expect behaviours to continue to occur in terms of dnd
*
* the dnd observer does not need to be conditional on whether the panel is visible since
* non-visible panels are 'display: none' and in such case the dnd observer will not fire.
*/
new DragAndDropObserver(focusContainer, {
onDragEnd: (e) => {
referenceContainer.dropTarget.dnd.onDragEnd(e);
@ -138,10 +128,7 @@ export class OverlayRenderContainer extends CompositeDisposable {
referenceContainer.dropTarget.dnd.onDragOver(e);
},
}),
/**
* since container is positioned absoutely we must explicitly forward
* the dnd events for the expect behaviours to continue to occur in terms of dnd
*/
panel.api.onDidVisibilityChange((event) => {
/**
* Control the visibility of the content, however even when not visible (display: none)
@ -177,7 +164,9 @@ export class OverlayRenderContainer extends CompositeDisposable {
visibilityChanged();
});
// dispose of logic asoccciated with previous reference-container
this.map[panel.api.id].disposable.dispose();
// and reset the disposable to the active reference-container
this.map[panel.api.id].disposable = disposable;
return focusContainer;