refactor: cleaner code

This commit is contained in:
mathuo 2021-06-08 22:29:44 +01:00
parent 374d59f2cb
commit 88d6026335
14 changed files with 295 additions and 297 deletions

View File

@ -89,28 +89,28 @@ describe('dockviewComponent', () => {
dockview.moveGroupOrPanel(group2, group1.id, 'panel3', Position.Center);
expect(dockview.activeGroup).toBe(group2);
expect(dockview.activeGroup.group.activePanel).toBe(panel3);
expect(dockview.activeGroup.group.indexOf(panel3)).toBe(1);
expect(dockview.activeGroup.model.activePanel).toBe(panel3);
expect(dockview.activeGroup.model.indexOf(panel3)).toBe(1);
dockview.moveToPrevious({ includePanel: true });
expect(dockview.activeGroup).toBe(group2);
expect(dockview.activeGroup.group.activePanel).toBe(panel1);
expect(dockview.activeGroup.model.activePanel).toBe(panel1);
dockview.moveToNext({ includePanel: true });
expect(dockview.activeGroup).toBe(group2);
expect(dockview.activeGroup.group.activePanel).toBe(panel3);
expect(dockview.activeGroup.model.activePanel).toBe(panel3);
dockview.moveToPrevious({ includePanel: false });
expect(dockview.activeGroup).toBe(group1);
expect(dockview.activeGroup.group.activePanel).toBe(panel4);
expect(dockview.activeGroup.model.activePanel).toBe(panel4);
dockview.moveToPrevious({ includePanel: true });
expect(dockview.activeGroup).toBe(group1);
expect(dockview.activeGroup.group.activePanel).toBe(panel2);
expect(dockview.activeGroup.model.activePanel).toBe(panel2);
dockview.moveToNext({ includePanel: false });
expect(dockview.activeGroup).toBe(group2);
expect(dockview.activeGroup.group.activePanel).toBe(panel3);
expect(dockview.activeGroup.model.activePanel).toBe(panel3);
});
test('remove group', () => {
@ -142,8 +142,8 @@ describe('dockviewComponent', () => {
expect(dockview.size).toBe(2);
expect(dockview.totalPanels).toBe(4);
expect(panel1.group.group.size).toBe(2);
expect(panel2.group.group.size).toBe(2);
expect(panel1.group.model.size).toBe(2);
expect(panel2.group.model.size).toBe(2);
dockview.removeGroup(panel1.group);
@ -263,13 +263,13 @@ describe('dockviewComponent', () => {
const group = panel1.group;
expect(group.group.size).toBe(2);
expect(group.group.containsPanel(panel1)).toBeTruthy();
expect(group.group.containsPanel(panel2)).toBeTruthy();
expect(group.group.activePanel).toBe(panel2);
expect(group.model.size).toBe(2);
expect(group.model.containsPanel(panel1)).toBeTruthy();
expect(group.model.containsPanel(panel2)).toBeTruthy();
expect(group.model.activePanel).toBe(panel2);
expect(group.group.indexOf(panel1)).toBe(0);
expect(group.group.indexOf(panel2)).toBe(1);
expect(group.model.indexOf(panel1)).toBe(0);
expect(group.model.indexOf(panel2)).toBe(1);
dockview.moveGroupOrPanel(group, group.id, 'panel1', Position.Right);
@ -277,12 +277,12 @@ describe('dockviewComponent', () => {
expect(dockview.totalPanels).toBe(2);
expect(panel1.group).not.toBe(panel2.group);
expect(panel1.group.group.size).toBe(1);
expect(panel2.group.group.size).toBe(1);
expect(panel1.group.group.containsPanel(panel1)).toBeTruthy();
expect(panel2.group.group.containsPanel(panel2)).toBeTruthy();
expect(panel1.group.group.activePanel).toBe(panel1);
expect(panel2.group.group.activePanel).toBe(panel2);
expect(panel1.group.model.size).toBe(1);
expect(panel2.group.model.size).toBe(1);
expect(panel1.group.model.containsPanel(panel1)).toBeTruthy();
expect(panel2.group.model.containsPanel(panel2)).toBeTruthy();
expect(panel1.group.model.activePanel).toBe(panel1);
expect(panel2.group.model.activePanel).toBe(panel2);
await panel1.api.close();

View File

@ -235,7 +235,7 @@ describe('groupview', () => {
activePanel: panel2,
});
expect(groupview2.group.activePanel).toBe(panel2);
expect(groupview2.model.activePanel).toBe(panel2);
expect(
groupview2.element.querySelector('.content-part-panel1')
@ -253,33 +253,33 @@ describe('groupview', () => {
const panel2 = new TestPanel('panel2', jest.fn() as any);
const panel3 = new TestPanel('panel3', jest.fn() as any);
groupview.group.openPanel(panel1);
groupview.group.openPanel(panel2);
groupview.group.openPanel(panel3);
groupview.model.openPanel(panel1);
groupview.model.openPanel(panel2);
groupview.model.openPanel(panel3);
groupview.group.openPanel(panel2); // set active
groupview.model.openPanel(panel2); // set active
groupview.group.moveToPrevious();
expect(groupview.group.activePanel).toBe(panel1);
groupview.model.moveToPrevious();
expect(groupview.model.activePanel).toBe(panel1);
groupview.group.moveToPrevious({ suppressRoll: true });
expect(groupview.group.activePanel).toBe(panel1);
groupview.model.moveToPrevious({ suppressRoll: true });
expect(groupview.model.activePanel).toBe(panel1);
groupview.group.moveToPrevious();
expect(groupview.group.activePanel).toBe(panel3);
groupview.model.moveToPrevious();
expect(groupview.model.activePanel).toBe(panel3);
groupview.group.moveToNext({ suppressRoll: true });
expect(groupview.group.activePanel).toBe(panel3);
groupview.model.moveToNext({ suppressRoll: true });
expect(groupview.model.activePanel).toBe(panel3);
groupview.group.moveToNext({ suppressRoll: false });
expect(groupview.group.activePanel).toBe(panel1);
groupview.model.moveToNext({ suppressRoll: false });
expect(groupview.model.activePanel).toBe(panel1);
groupview.group.moveToPrevious({ suppressRoll: false });
expect(groupview.group.activePanel).toBe(panel3);
groupview.model.moveToPrevious({ suppressRoll: false });
expect(groupview.model.activePanel).toBe(panel3);
groupview.group.moveToNext();
groupview.group.moveToNext();
expect(groupview.group.activePanel).toBe(panel2);
groupview.model.moveToNext();
groupview.model.moveToNext();
expect(groupview.model.activePanel).toBe(panel2);
});
test('default', () => {
@ -298,12 +298,12 @@ describe('groupview', () => {
const panel1 = new TestPanel('panel1', jest.fn() as any);
const panel2 = new TestPanel('panel2', jest.fn() as any);
groupview.group.openPanel(panel1);
groupview.group.openPanel(panel2);
groupview.model.openPanel(panel1);
groupview.model.openPanel(panel2);
const events: GroupDropEvent[] = [];
groupview.group.onDrop((event) => {
groupview.model.onDrop((event) => {
events.push(event);
});

View File

@ -98,7 +98,7 @@ export class DockviewPanelApiImpl
if (!this.group) {
throw new Error(`panel ${this.id} has no group`);
}
return this.group.group.closePanel(this.panel);
return this.group.model.closePanel(this.panel);
}
public interceptOnCloseAction(interceptor: () => Promise<boolean>) {

View File

@ -135,7 +135,8 @@ export interface LayoutDropEvent {
export class DockviewComponent
extends BaseGrid<GroupviewPanel>
implements IDockviewComponent {
implements IDockviewComponent
{
private readonly panels = new Map<string, IValueDisposable<IGroupPanel>>();
private readonly dirtyPanels = new Set<IGroupPanel>();
private readonly debouncedDeque = debounce(
@ -144,11 +145,11 @@ export class DockviewComponent
);
// events
private readonly _onTabInteractionEvent = new Emitter<LayoutMouseEvent>();
readonly onTabInteractionEvent: Event<LayoutMouseEvent> = this
._onTabInteractionEvent.event;
readonly onTabInteractionEvent: Event<LayoutMouseEvent> =
this._onTabInteractionEvent.event;
private readonly _onTabContextMenu = new Emitter<TabContextMenuEvent>();
readonly onTabContextMenu: Event<TabContextMenuEvent> = this
._onTabContextMenu.event;
readonly onTabContextMenu: Event<TabContextMenuEvent> =
this._onTabContextMenu.event;
// everything else
private drag = new MutableDisposable();
private _deserializer: IPanelDeserializer | undefined;
@ -270,7 +271,7 @@ export class DockviewComponent
const panel = this.panels.get(panelOptions.id)?.value;
if (panel) {
this.drag.value = panel.group!.group.startActiveDrag(panel);
this.drag.value = panel.group!.model.startActiveDrag(panel);
}
const data = JSON.stringify({
@ -309,7 +310,7 @@ export class DockviewComponent
throw new Error(`Panel ${panel.id} has no associated group`);
}
this.doSetGroupActive(panel.group);
panel.group.group.openPanel(panel);
panel.group.model.openPanel(panel);
}
public moveToNext(options: MovementOptions = {}): void {
@ -322,12 +323,12 @@ export class DockviewComponent
if (options.includePanel && options.group) {
if (
options.group.group.activePanel !==
options.group.group.panels[
options.group.group.panels.length - 1
options.group.model.activePanel !==
options.group.model.panels[
options.group.model.panels.length - 1
]
) {
options.group.group.moveToNext({ suppressRoll: true });
options.group.model.moveToNext({ suppressRoll: true });
return;
}
}
@ -347,10 +348,10 @@ export class DockviewComponent
if (options.includePanel && options.group) {
if (
options.group.group.activePanel !==
options.group.group.panels[0]
options.group.model.activePanel !==
options.group.model.panels[0]
) {
options.group.group.moveToPrevious({ suppressRoll: true });
options.group.model.moveToPrevious({ suppressRoll: true });
return;
}
}
@ -511,7 +512,7 @@ export class DockviewComponent
for (const entry of this.groups.entries()) {
const [_, group] = entry;
const didCloseAll = await group.value.group.closeAllPanels();
const didCloseAll = await group.value.model.closeAllPanels();
if (!didCloseAll) {
return false;
}
@ -523,7 +524,7 @@ export class DockviewComponent
public setTabHeight(height: number | undefined): void {
this.options.tabHeight = height;
this.groups.forEach((value) => {
value.value.group.tabHeight = height;
value.value.model.tabHeight = height;
});
}
@ -569,7 +570,7 @@ export class DockviewComponent
if (referenceGroup) {
const target = toTarget(options.position?.direction || 'within');
if (target === Position.Center) {
referenceGroup.group.openPanel(panel);
referenceGroup.model.openPanel(panel);
} else {
const location = getGridLocation(referenceGroup.element);
const relativeLocation = getRelativeLocation(
@ -652,8 +653,9 @@ export class DockviewComponent
const group = this.createGroup();
if (options) {
const referencePanel = this.panels.get(options.referencePanel)
?.value;
const referencePanel = this.panels.get(
options.referencePanel
)?.value;
if (!referencePanel) {
throw new Error(
@ -684,9 +686,9 @@ export class DockviewComponent
}
public removeGroup(group: GroupviewPanel): void {
const panels = [...group.group.panels]; // reassign since group panels will mutate
const panels = [...group.model.panels]; // reassign since group panels will mutate
panels.forEach((panel) => {
group.group.removePanel(panel);
group.model.removePanel(panel);
this.unregisterPanel(panel);
});
@ -707,7 +709,7 @@ export class DockviewComponent
group! = this.createGroup();
this.doAddGroup(group, location);
group.group.openPanel(panel);
group.model.openPanel(panel);
}
public moveGroupOrPanel(
@ -723,18 +725,18 @@ export class DockviewComponent
if (!target || target === Position.Center) {
const groupItem: IGroupPanel | undefined =
sourceGroup?.group.removePanel(itemId) ||
sourceGroup?.model.removePanel(itemId) ||
this.panels.get(itemId)?.value;
if (!groupItem) {
throw new Error(`No panel with id ${itemId}`);
}
if (sourceGroup?.group.size === 0) {
if (sourceGroup?.model.size === 0) {
this.doRemoveGroup(sourceGroup);
}
referenceGroup.group.openPanel(groupItem, { index });
referenceGroup.model.openPanel(groupItem, { index });
} else {
const referenceLocation = getGridLocation(referenceGroup.element);
const targetLocation = getRelativeLocation(
@ -743,7 +745,7 @@ export class DockviewComponent
target
);
if (sourceGroup && sourceGroup.group.size < 2) {
if (sourceGroup && sourceGroup.model.size < 2) {
const [targetParentLocation, to] = tail(targetLocation);
const sourceLocation = getGridLocation(sourceGroup.element);
const [sourceParentLocation, from] = tail(sourceLocation);
@ -775,7 +777,7 @@ export class DockviewComponent
}
} else {
const groupItem: IGroupPanel | undefined =
sourceGroup?.group.removePanel(itemId) ||
sourceGroup?.model.removePanel(itemId) ||
this.panels.get(itemId)?.value;
if (!groupItem) {
@ -820,19 +822,19 @@ export class DockviewComponent
const view = new GroupviewPanel(this, id, options);
if (typeof this.options.tabHeight === 'number') {
view.group.tabHeight = this.options.tabHeight;
view.model.tabHeight = this.options.tabHeight;
}
if (!this.groups.has(view.id)) {
const disposable = new CompositeDisposable(
view.group.onMove((event) => {
view.model.onMove((event) => {
const { groupId, itemId, target, index } = event;
this.moveGroupOrPanel(view, groupId, itemId, target, index);
}),
view.group.onDidGroupChange((event) => {
view.model.onDidGroupChange((event) => {
this._onGridEvent.fire(event);
}),
view.group.onDrop((event) => {
view.model.onDrop((event) => {
const dragEvent = event.event;
const dataTransfer = dragEvent.dataTransfer;
@ -883,7 +885,7 @@ export class DockviewComponent
private findGroup(panel: IGroupPanel): GroupviewPanel | undefined {
return Array.from(this.groups.values()).find((group) =>
group.value.group.containsPanel(panel)
group.value.model.containsPanel(panel)
)?.value;
}

View File

@ -157,10 +157,10 @@ export class DockviewGroupPanel
this._group = group;
this.api.group = group;
this.mutableDisposable.value = this._group.group.onDidGroupChange(
this.mutableDisposable.value = this._group.model.onDidGroupChange(
(ev) => {
if (ev.kind === GroupChangeKind.GROUP_ACTIVE) {
const isVisible = !!this._group?.group.isPanelActive(this);
const isVisible = !!this._group?.model.isPanelActive(this);
this.api._onDidActiveChange.fire({
isActive: isGroupActive && isVisible,
});
@ -171,7 +171,7 @@ export class DockviewGroupPanel
}
);
const isPanelVisible = this._group.group.isPanelActive(this);
const isPanelVisible = this._group.model.isPanelActive(this);
this.api._onDidActiveChange.fire({
isActive: isGroupActive && isPanelVisible,
@ -182,7 +182,7 @@ export class DockviewGroupPanel
this.view?.updateParentGroup(
this._group,
this._group.group.isPanelActive(this)
this._group.model.isPanelActive(this)
);
}
@ -190,7 +190,7 @@ export class DockviewGroupPanel
// the obtain the correct dimensions of the content panel we must deduct the tab height
this.api._onDidPanelDimensionChange.fire({
width,
height: height - (this.group?.group.tabHeight || 0),
height: height - (this.group?.model.tabHeight || 0),
});
this.view?.layout(width, height);

View File

@ -27,7 +27,8 @@ export interface BasePanelViewExported<T extends PanelApiImpl> {
export abstract class BasePanelView<T extends PanelApiImpl>
extends CompositeDisposable
implements IPanel, BasePanelViewExported<T> {
implements IPanel, BasePanelViewExported<T>
{
private _height = 0;
private _width = 0;
private _element: HTMLElement;
@ -87,8 +88,10 @@ export abstract class BasePanelView<T extends PanelApiImpl>
this._height = height;
this.api._onDidPanelDimensionChange.fire({ width, height });
if (this.part && this.params) {
this.part.update(this.params.params);
if (this.part) {
if (this.params) {
this.part.update(this.params.params);
}
}
}

View File

@ -35,7 +35,8 @@ export interface IGridviewPanel
export abstract class GridviewPanel
extends BasePanelView<GridviewPanelApiImpl>
implements IGridPanelComponentView, IGridviewPanel {
implements IGridPanelComponentView, IGridviewPanel
{
private _evaluatedMinimumWidth = 0;
private _evaluatedMaximumWidth = Number.MAX_SAFE_INTEGER;
private _evaluatedMinimumHeight = 0;
@ -49,8 +50,8 @@ export abstract class GridviewPanel
private _snap = false;
private readonly _onDidChange = new Emitter<IViewSize | undefined>();
readonly onDidChange: Event<IViewSize | undefined> = this._onDidChange
.event;
readonly onDidChange: Event<IViewSize | undefined> =
this._onDidChange.event;
get priority(): LayoutPriority | undefined {
return this._priority;

View File

@ -16,12 +16,18 @@ import { addDisposableListener, Emitter, Event } from '../events';
import { IGridPanelView } from '../gridview/baseComponentGridview';
import { IViewSize } from '../gridview/gridview';
import { CompositeDisposable, Disposable, IDisposable } from '../lifecycle';
import { PanelInitParameters, PanelUpdateEvent } from '../panel/types';
import {
IFrameworkPart,
PanelInitParameters,
PanelUpdateEvent,
} from '../panel/types';
import { IGroupPanel } from './groupPanel';
import { ContentContainer, IContentContainer } from './panel/content';
import { ITabsContainer, TabsContainer } from './titlebar/tabsContainer';
import { IWatermarkRenderer } from './types';
import { GroupviewPanel } from './groupviewPanel';
import { focusedElement } from '../focusedElement';
import { BasePanelView } from '../gridview/basePanelView';
export enum GroupChangeKind {
GROUP_ACTIVE = 'GROUP_ACTIVE',
@ -80,7 +86,7 @@ export interface IGroupview extends IDisposable, IGridPanelView {
readonly isActive: boolean;
readonly size: number;
readonly panels: IGroupPanel[];
tabHeight: number | undefined;
readonly tabHeight: number | undefined;
// state
isPanelActive: (panel: IGroupPanel) => boolean;
activePanel: IGroupPanel | undefined;
@ -105,7 +111,7 @@ export interface IGroupview extends IDisposable, IGridPanelView {
panel?: IGroupPanel;
suppressRoll?: boolean;
}): void;
isAncestor(element: Element): boolean;
isContentFocused(): boolean;
updateActions(): void;
}
@ -126,8 +132,8 @@ export class Groupview extends CompositeDisposable implements IGroupview {
private mostRecentlyUsed: IGroupPanel[] = [];
private readonly _onDidChange = new Emitter<IViewSize | undefined>();
readonly onDidChange: Event<IViewSize | undefined> = this._onDidChange
.event;
readonly onDidChange: Event<IViewSize | undefined> =
this._onDidChange.event;
private _width = 0;
private _height = 0;
@ -141,8 +147,8 @@ export class Groupview extends CompositeDisposable implements IGroupview {
readonly onDrop: Event<GroupDropEvent> = this._onDrop.event;
private readonly _onDidGroupChange = new Emitter<GroupChangeEvent>();
readonly onDidGroupChange: Event<{ kind: GroupChangeKind }> = this
._onDidGroupChange.event;
readonly onDidGroupChange: Event<{ kind: GroupChangeKind }> =
this._onDidGroupChange.event;
get element(): HTMLElement {
throw new Error('not supported');
@ -193,10 +199,92 @@ export class Groupview extends CompositeDisposable implements IGroupview {
return Number.MAX_SAFE_INTEGER;
}
isAncestor(element: Element): boolean {
return (
element === this.contentContainer.element ||
isAncestor(element, this.contentContainer.element)
constructor(
private readonly container: HTMLElement,
private accessor: IDockviewComponent,
public id: string,
private readonly options: GroupOptions,
private readonly parent: GroupviewPanel
) {
super();
this.container.classList.add('groupview');
this.addDisposables(this._onMove, this._onDidGroupChange, this._onDrop);
this.tabsContainer = new TabsContainer(this.accessor, this.parent, {
tabHeight: options.tabHeight,
});
this.contentContainer = new ContentContainer();
this.dropTarget = new Droptarget(this.contentContainer.element, {
isDirectional: true,
id: this.accessor.id,
isDisabled: () => {
// disable the drop target if we only have one tab, and that is also the tab we are moving
return (
this._panels.length === 1 &&
this.tabsContainer.hasActiveDragEvent
);
},
enableExternalDragEvents:
this.accessor.options.enableExternalDragEvents,
});
container.append(
this.tabsContainer.element,
this.contentContainer.element
);
this.addDisposables(
this._onMove,
this._onDidGroupChange,
this.tabsContainer.onDropEvent((event) =>
this.handleDropEvent(event.event, event.index)
),
this.contentContainer.onDidFocus(() => {
this.accessor.doSetGroupActive(this.parent, true);
}),
this.contentContainer.onDidBlur(() => {
// this._activePanel?.api._ondid
}),
this.dropTarget.onDidChange((event) => {
// if we've center dropped on ourself then ignore
if (
event.position === Position.Center &&
this.tabsContainer.hasActiveDragEvent
) {
return;
}
this.handleDropEvent(event);
})
);
if (this.options?.panels) {
this.options.panels.forEach((panel) => {
this.doAddPanel(panel);
});
}
if (this.options?.activePanel) {
this.openPanel(this.options.activePanel);
}
}
initialize() {
// must be run after the constructor otherwise this.parent may not be
// correctly initialized
this.setActive(this.isActive, true, true);
this.updateContainer();
}
isContentFocused() {
if (!focusedElement.element) {
return false;
}
return isAncestor(
focusedElement.element,
this.contentContainer.element
);
}
@ -286,84 +374,6 @@ export class Groupview extends CompositeDisposable implements IGroupview {
return this.panels.includes(panel);
}
constructor(
private readonly container: HTMLElement,
private accessor: IDockviewComponent,
public id: string,
private readonly options: GroupOptions,
private readonly parent: GroupviewPanel
) {
super();
this.container.classList.add('groupview');
this.addDisposables(this._onMove, this._onDidGroupChange, this._onDrop);
this.tabsContainer = new TabsContainer(this.accessor, this.parent, {
tabHeight: options.tabHeight,
});
this.contentContainer = new ContentContainer();
this.dropTarget = new Droptarget(this.contentContainer.element, {
isDirectional: true,
id: this.accessor.id,
isDisabled: () => {
// disable the drop target if we only have one tab, and that is also the tab we are moving
return (
this._panels.length === 1 &&
this.tabsContainer.hasActiveDragEvent
);
},
enableExternalDragEvents: this.accessor.options
.enableExternalDragEvents,
});
container.append(
this.tabsContainer.element,
this.contentContainer.element
);
this.addDisposables(
this._onMove,
this._onDidGroupChange,
this.tabsContainer.onDropEvent((event) =>
this.handleDropEvent(event.event, event.index)
),
this.contentContainer.onDidFocus(() => {
this.accessor.doSetGroupActive(this.parent, true);
}),
this.contentContainer.onDidBlur(() => {
// this._activePanel?.api._ondid
}),
this.dropTarget.onDidChange((event) => {
// if we've center dropped on ourself then ignore
if (
event.position === Position.Center &&
this.tabsContainer.hasActiveDragEvent
) {
return;
}
this.handleDropEvent(event);
})
);
}
bootstrap() {
if (this.options?.panels) {
this.options.panels.forEach((panel) => {
this.doAddPanel(panel);
});
}
if (this.options?.activePanel) {
this.openPanel(this.options.activePanel);
}
this.setActive(this.isActive, true, true);
this.updateContainer();
}
init(params: PanelInitParameters) {
//noop
}

View File

@ -1,47 +1,30 @@
import { IFrameworkPart } from '../panel/types';
import { IDockviewComponent } from '../dockview/dockviewComponent';
import {
GridviewPanelApiImpl,
GridviewPanelApi,
} from '../api/gridviewPanelApi';
import { GridviewPanelApiImpl } from '../api/gridviewPanelApi';
import { Groupview, GroupOptions } from './groupview';
import { GridviewPanel } from '../gridview/gridviewPanel';
interface IGroupApi extends GridviewPanelApi {}
class GroupApi extends GridviewPanelApiImpl implements IGroupApi {
private _value?: Groupview;
set group(value: Groupview) {
this._value = value;
}
constructor(id: string) {
super(id);
}
}
export class GroupviewPanel extends GridviewPanel {
private readonly _group: Groupview;
private readonly _model: Groupview;
get group(): Groupview {
return this._group;
get model(): Groupview {
return this._model;
}
get minimumHeight() {
return this._group.minimumHeight;
return this._model.minimumHeight;
}
get maximumHeight() {
return this._group.maximumHeight;
return this._model.maximumHeight;
}
get minimumWidth() {
return this._group.minimumWidth;
return this._model.minimumWidth;
}
get maximumWidth() {
return this._group.maximumWidth;
return this._model.maximumWidth;
}
constructor(
@ -49,29 +32,27 @@ export class GroupviewPanel extends GridviewPanel {
id: string,
options: GroupOptions
) {
super(id, 'groupview_default', new GroupApi(id));
super(id, 'groupview_default', new GridviewPanelApiImpl(id));
this._group = new Groupview(this.element, accessor, id, options, this);
(this.api as GroupApi).group = this._group;
this.group.bootstrap();
this._model = new Groupview(this.element, accessor, id, options, this);
this.model.initialize();
}
setActive(isActive: boolean): void {
super.setActive(isActive);
this.group.setActive(isActive);
this.model.setActive(isActive);
}
layout(width: number, height: number) {
super.layout(width, height);
this.group.layout(width, height);
this.model.layout(width, height);
}
getComponent(): IFrameworkPart {
return this._group;
return this._model;
}
toJSON(): any {
return this.group.toJSON();
return this.model.toJSON();
}
}

View File

@ -7,13 +7,6 @@ import { Emitter, Event } from '../../events';
import { trackFocus } from '../../dom';
import { IGroupPanel } from '../groupPanel';
export interface IRenderable {
id: string;
element: HTMLElement;
onDidFocus?: Event<void>;
onDidBlur?: Event<void>;
}
export interface IContentContainer extends IDisposable {
onDidFocus: Event<void>;
onDidBlur: Event<void>;
@ -25,76 +18,10 @@ export interface IContentContainer extends IDisposable {
hide(): void;
}
export interface HostedPanelOptions {
id: string;
parent?: HTMLElement;
}
export class HostedPanel implements IRenderable, IDisposable {
private readonly _element: HTMLElement;
get element() {
return this._element;
}
get id() {
return this.panel.id;
}
constructor(
private readonly panel: IGroupPanel,
private readonly options: HostedPanelOptions
) {
if (!options.parent) {
options.parent = document.getElementById('app') as HTMLElement;
options.parent.style.position = 'relative';
}
this._element = document.createElement('div');
this._element.style.visibility = 'hidden';
this._element.style.overflow = 'hidden';
// this._element.style.pointerEvents = 'none';
this._element.id = `webivew-${options.id}`;
options.parent.appendChild(this._element);
}
hide() {
this._element.style.visibility = 'hidden';
}
show() {
this._element.style.visibility = 'visible';
}
layout(
element: HTMLElement,
dimension?: { width: number; height: number }
) {
if (!this.element || !this.element.parentElement) {
return;
}
const frameRect = element.getBoundingClientRect();
const containerRect = this.element.parentElement.getBoundingClientRect();
this.element.style.position = 'absolute';
this.element.style.top = `${frameRect.top - containerRect.top}px`;
this.element.style.left = `${frameRect.left - containerRect.left}px`;
this.element.style.width = `${
dimension ? dimension.width : frameRect.width
}px`;
this.element.style.height = `${
dimension ? dimension.height : frameRect.height
}px`;
}
dispose() {
this._element.remove();
}
}
export class ContentContainer
extends CompositeDisposable
implements IContentContainer {
implements IContentContainer
{
private _element: HTMLElement;
private panel: IGroupPanel | undefined;
private disposable = new MutableDisposable();
@ -145,8 +72,8 @@ export class ContentContainer
const disposable = new CompositeDisposable();
if (this.panel.view) {
const _onDidFocus: Event<void> = this.panel.view.content
.onDidFocus!;
const _onDidFocus: Event<void> =
this.panel.view.content.onDidFocus!;
const _onDidBlur: Event<void> = this.panel.view.content.onDidBlur!;
const { onDidFocus, onDidBlur } = trackFocus(this._element);

View File

@ -0,0 +1,71 @@
import { IDisposable } from '../../lifecycle';
import { IGroupPanel } from '../groupPanel';
import { IRenderable } from '../types';
export interface HostedPanelOptions {
id: string;
parent?: HTMLElement;
}
export class HostedPanel implements IRenderable, IDisposable {
private readonly _element: HTMLElement;
get element() {
return this._element;
}
get id() {
return this.panel.id;
}
constructor(
private readonly panel: IGroupPanel,
private readonly options: HostedPanelOptions
) {
if (!options.parent) {
options.parent = document.getElementById('app') as HTMLElement;
options.parent.style.position = 'relative';
}
this._element = document.createElement('div');
this._element.style.visibility = 'hidden';
this._element.style.overflow = 'hidden';
// this._element.style.pointerEvents = 'none';
this._element.id = `webivew-${options.id}`;
options.parent.appendChild(this._element);
}
hide() {
this._element.style.visibility = 'hidden';
}
show() {
this._element.style.visibility = 'visible';
}
layout(
element: HTMLElement,
dimension?: { width: number; height: number }
) {
if (!this.element || !this.element.parentElement) {
return;
}
const frameRect = element.getBoundingClientRect();
const containerRect =
this.element.parentElement.getBoundingClientRect();
this.element.style.position = 'absolute';
this.element.style.top = `${frameRect.top - containerRect.top}px`;
this.element.style.left = `${frameRect.left - containerRect.left}px`;
this.element.style.width = `${
dimension ? dimension.width : frameRect.width
}px`;
this.element.style.height = `${
dimension ? dimension.height : frameRect.height
}px`;
}
dispose() {
this._element.remove();
}
}

View File

@ -8,7 +8,6 @@ import { ITab, MouseEventKind, Tab } from '../tab';
import { removeClasses, addClasses } from '../../dom';
import { DroptargetEvent, Position } from '../../dnd/droptarget';
import { last } from '../../array';
import { focusedElement } from '../../focusedElement';
import { IGroupPanel } from '../groupPanel';
import { IDockviewComponent } from '../../dockview/dockviewComponent';
import { LocalSelectionTransfer } from '../../dnd/dataTransfer';
@ -40,7 +39,8 @@ export interface ITabsContainer extends IDisposable {
export class TabsContainer
extends CompositeDisposable
implements ITabsContainer {
implements ITabsContainer
{
private readonly _element: HTMLElement;
private readonly tabContainer: HTMLElement;
private readonly actionContainer: HTMLElement;
@ -281,8 +281,8 @@ export class TabsContainer
const disposable = CompositeDisposable.from(
tabToAdd.onChanged((event) => {
const alreadyFocused =
panel.id === this.group.group.activePanel?.id &&
this.group.group.isAncestor(focusedElement.element!);
panel.id === this.group.model.activePanel?.id &&
this.group.model.isContentFocused();
this.accessor.fireMouseEvent({ ...event, panel, tab: true });
const isLeftClick = event.event.button === 0;
@ -293,7 +293,7 @@ export class TabsContainer
switch (event.kind) {
case MouseEventKind.CLICK:
this.group.group.openPanel(panel, {
this.group.model.openPanel(panel, {
skipFocus: alreadyFocused,
});
break;

View File

@ -7,6 +7,13 @@ import { GroupviewPanel } from './groupviewPanel';
import { Event } from '../events';
import { WrappedTab } from '../dockview/components/tab/defaultTab';
export interface IRenderable {
id: string;
element: HTMLElement;
onDidFocus?: Event<void>;
onDidBlur?: Event<void>;
}
export interface HeaderPartInitParameters {
title: string;
suppressClosable?: boolean;

View File

@ -15,10 +15,6 @@ import { PanelCollection, PanelParameters } from '../types';
import { watchElementResize } from '../../dom';
import { IContentRenderer, ITabRenderer } from '../../groupview/types';
export interface PanelCollection1<T extends IDockviewPanelProps> {
[name: string]: React.FunctionComponent<T>;
}
export interface IGroupPanelBaseProps<T extends {} = Record<string, any>>
extends PanelParameters<T> {
api: DockviewPanelApi;