mirror of
https://github.com/mathuo/dockview
synced 2025-11-27 18:02:28 +00:00
refactor: cleaner code
This commit is contained in:
parent
374d59f2cb
commit
88d6026335
@ -89,28 +89,28 @@ describe('dockviewComponent', () => {
|
|||||||
dockview.moveGroupOrPanel(group2, group1.id, 'panel3', Position.Center);
|
dockview.moveGroupOrPanel(group2, group1.id, 'panel3', Position.Center);
|
||||||
|
|
||||||
expect(dockview.activeGroup).toBe(group2);
|
expect(dockview.activeGroup).toBe(group2);
|
||||||
expect(dockview.activeGroup.group.activePanel).toBe(panel3);
|
expect(dockview.activeGroup.model.activePanel).toBe(panel3);
|
||||||
expect(dockview.activeGroup.group.indexOf(panel3)).toBe(1);
|
expect(dockview.activeGroup.model.indexOf(panel3)).toBe(1);
|
||||||
|
|
||||||
dockview.moveToPrevious({ includePanel: true });
|
dockview.moveToPrevious({ includePanel: true });
|
||||||
expect(dockview.activeGroup).toBe(group2);
|
expect(dockview.activeGroup).toBe(group2);
|
||||||
expect(dockview.activeGroup.group.activePanel).toBe(panel1);
|
expect(dockview.activeGroup.model.activePanel).toBe(panel1);
|
||||||
|
|
||||||
dockview.moveToNext({ includePanel: true });
|
dockview.moveToNext({ includePanel: true });
|
||||||
expect(dockview.activeGroup).toBe(group2);
|
expect(dockview.activeGroup).toBe(group2);
|
||||||
expect(dockview.activeGroup.group.activePanel).toBe(panel3);
|
expect(dockview.activeGroup.model.activePanel).toBe(panel3);
|
||||||
|
|
||||||
dockview.moveToPrevious({ includePanel: false });
|
dockview.moveToPrevious({ includePanel: false });
|
||||||
expect(dockview.activeGroup).toBe(group1);
|
expect(dockview.activeGroup).toBe(group1);
|
||||||
expect(dockview.activeGroup.group.activePanel).toBe(panel4);
|
expect(dockview.activeGroup.model.activePanel).toBe(panel4);
|
||||||
|
|
||||||
dockview.moveToPrevious({ includePanel: true });
|
dockview.moveToPrevious({ includePanel: true });
|
||||||
expect(dockview.activeGroup).toBe(group1);
|
expect(dockview.activeGroup).toBe(group1);
|
||||||
expect(dockview.activeGroup.group.activePanel).toBe(panel2);
|
expect(dockview.activeGroup.model.activePanel).toBe(panel2);
|
||||||
|
|
||||||
dockview.moveToNext({ includePanel: false });
|
dockview.moveToNext({ includePanel: false });
|
||||||
expect(dockview.activeGroup).toBe(group2);
|
expect(dockview.activeGroup).toBe(group2);
|
||||||
expect(dockview.activeGroup.group.activePanel).toBe(panel3);
|
expect(dockview.activeGroup.model.activePanel).toBe(panel3);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('remove group', () => {
|
test('remove group', () => {
|
||||||
@ -142,8 +142,8 @@ describe('dockviewComponent', () => {
|
|||||||
|
|
||||||
expect(dockview.size).toBe(2);
|
expect(dockview.size).toBe(2);
|
||||||
expect(dockview.totalPanels).toBe(4);
|
expect(dockview.totalPanels).toBe(4);
|
||||||
expect(panel1.group.group.size).toBe(2);
|
expect(panel1.group.model.size).toBe(2);
|
||||||
expect(panel2.group.group.size).toBe(2);
|
expect(panel2.group.model.size).toBe(2);
|
||||||
|
|
||||||
dockview.removeGroup(panel1.group);
|
dockview.removeGroup(panel1.group);
|
||||||
|
|
||||||
@ -263,13 +263,13 @@ describe('dockviewComponent', () => {
|
|||||||
|
|
||||||
const group = panel1.group;
|
const group = panel1.group;
|
||||||
|
|
||||||
expect(group.group.size).toBe(2);
|
expect(group.model.size).toBe(2);
|
||||||
expect(group.group.containsPanel(panel1)).toBeTruthy();
|
expect(group.model.containsPanel(panel1)).toBeTruthy();
|
||||||
expect(group.group.containsPanel(panel2)).toBeTruthy();
|
expect(group.model.containsPanel(panel2)).toBeTruthy();
|
||||||
expect(group.group.activePanel).toBe(panel2);
|
expect(group.model.activePanel).toBe(panel2);
|
||||||
|
|
||||||
expect(group.group.indexOf(panel1)).toBe(0);
|
expect(group.model.indexOf(panel1)).toBe(0);
|
||||||
expect(group.group.indexOf(panel2)).toBe(1);
|
expect(group.model.indexOf(panel2)).toBe(1);
|
||||||
|
|
||||||
dockview.moveGroupOrPanel(group, group.id, 'panel1', Position.Right);
|
dockview.moveGroupOrPanel(group, group.id, 'panel1', Position.Right);
|
||||||
|
|
||||||
@ -277,12 +277,12 @@ describe('dockviewComponent', () => {
|
|||||||
expect(dockview.totalPanels).toBe(2);
|
expect(dockview.totalPanels).toBe(2);
|
||||||
|
|
||||||
expect(panel1.group).not.toBe(panel2.group);
|
expect(panel1.group).not.toBe(panel2.group);
|
||||||
expect(panel1.group.group.size).toBe(1);
|
expect(panel1.group.model.size).toBe(1);
|
||||||
expect(panel2.group.group.size).toBe(1);
|
expect(panel2.group.model.size).toBe(1);
|
||||||
expect(panel1.group.group.containsPanel(panel1)).toBeTruthy();
|
expect(panel1.group.model.containsPanel(panel1)).toBeTruthy();
|
||||||
expect(panel2.group.group.containsPanel(panel2)).toBeTruthy();
|
expect(panel2.group.model.containsPanel(panel2)).toBeTruthy();
|
||||||
expect(panel1.group.group.activePanel).toBe(panel1);
|
expect(panel1.group.model.activePanel).toBe(panel1);
|
||||||
expect(panel2.group.group.activePanel).toBe(panel2);
|
expect(panel2.group.model.activePanel).toBe(panel2);
|
||||||
|
|
||||||
await panel1.api.close();
|
await panel1.api.close();
|
||||||
|
|
||||||
|
|||||||
@ -235,7 +235,7 @@ describe('groupview', () => {
|
|||||||
activePanel: panel2,
|
activePanel: panel2,
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(groupview2.group.activePanel).toBe(panel2);
|
expect(groupview2.model.activePanel).toBe(panel2);
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
groupview2.element.querySelector('.content-part-panel1')
|
groupview2.element.querySelector('.content-part-panel1')
|
||||||
@ -253,33 +253,33 @@ describe('groupview', () => {
|
|||||||
const panel2 = new TestPanel('panel2', jest.fn() as any);
|
const panel2 = new TestPanel('panel2', jest.fn() as any);
|
||||||
const panel3 = new TestPanel('panel3', jest.fn() as any);
|
const panel3 = new TestPanel('panel3', jest.fn() as any);
|
||||||
|
|
||||||
groupview.group.openPanel(panel1);
|
groupview.model.openPanel(panel1);
|
||||||
groupview.group.openPanel(panel2);
|
groupview.model.openPanel(panel2);
|
||||||
groupview.group.openPanel(panel3);
|
groupview.model.openPanel(panel3);
|
||||||
|
|
||||||
groupview.group.openPanel(panel2); // set active
|
groupview.model.openPanel(panel2); // set active
|
||||||
|
|
||||||
groupview.group.moveToPrevious();
|
groupview.model.moveToPrevious();
|
||||||
expect(groupview.group.activePanel).toBe(panel1);
|
expect(groupview.model.activePanel).toBe(panel1);
|
||||||
|
|
||||||
groupview.group.moveToPrevious({ suppressRoll: true });
|
groupview.model.moveToPrevious({ suppressRoll: true });
|
||||||
expect(groupview.group.activePanel).toBe(panel1);
|
expect(groupview.model.activePanel).toBe(panel1);
|
||||||
|
|
||||||
groupview.group.moveToPrevious();
|
groupview.model.moveToPrevious();
|
||||||
expect(groupview.group.activePanel).toBe(panel3);
|
expect(groupview.model.activePanel).toBe(panel3);
|
||||||
|
|
||||||
groupview.group.moveToNext({ suppressRoll: true });
|
groupview.model.moveToNext({ suppressRoll: true });
|
||||||
expect(groupview.group.activePanel).toBe(panel3);
|
expect(groupview.model.activePanel).toBe(panel3);
|
||||||
|
|
||||||
groupview.group.moveToNext({ suppressRoll: false });
|
groupview.model.moveToNext({ suppressRoll: false });
|
||||||
expect(groupview.group.activePanel).toBe(panel1);
|
expect(groupview.model.activePanel).toBe(panel1);
|
||||||
|
|
||||||
groupview.group.moveToPrevious({ suppressRoll: false });
|
groupview.model.moveToPrevious({ suppressRoll: false });
|
||||||
expect(groupview.group.activePanel).toBe(panel3);
|
expect(groupview.model.activePanel).toBe(panel3);
|
||||||
|
|
||||||
groupview.group.moveToNext();
|
groupview.model.moveToNext();
|
||||||
groupview.group.moveToNext();
|
groupview.model.moveToNext();
|
||||||
expect(groupview.group.activePanel).toBe(panel2);
|
expect(groupview.model.activePanel).toBe(panel2);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('default', () => {
|
test('default', () => {
|
||||||
@ -298,12 +298,12 @@ describe('groupview', () => {
|
|||||||
const panel1 = new TestPanel('panel1', jest.fn() as any);
|
const panel1 = new TestPanel('panel1', jest.fn() as any);
|
||||||
const panel2 = new TestPanel('panel2', jest.fn() as any);
|
const panel2 = new TestPanel('panel2', jest.fn() as any);
|
||||||
|
|
||||||
groupview.group.openPanel(panel1);
|
groupview.model.openPanel(panel1);
|
||||||
groupview.group.openPanel(panel2);
|
groupview.model.openPanel(panel2);
|
||||||
|
|
||||||
const events: GroupDropEvent[] = [];
|
const events: GroupDropEvent[] = [];
|
||||||
|
|
||||||
groupview.group.onDrop((event) => {
|
groupview.model.onDrop((event) => {
|
||||||
events.push(event);
|
events.push(event);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -98,7 +98,7 @@ export class DockviewPanelApiImpl
|
|||||||
if (!this.group) {
|
if (!this.group) {
|
||||||
throw new Error(`panel ${this.id} has no 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>) {
|
public interceptOnCloseAction(interceptor: () => Promise<boolean>) {
|
||||||
|
|||||||
@ -135,7 +135,8 @@ export interface LayoutDropEvent {
|
|||||||
|
|
||||||
export class DockviewComponent
|
export class DockviewComponent
|
||||||
extends BaseGrid<GroupviewPanel>
|
extends BaseGrid<GroupviewPanel>
|
||||||
implements IDockviewComponent {
|
implements IDockviewComponent
|
||||||
|
{
|
||||||
private readonly panels = new Map<string, IValueDisposable<IGroupPanel>>();
|
private readonly panels = new Map<string, IValueDisposable<IGroupPanel>>();
|
||||||
private readonly dirtyPanels = new Set<IGroupPanel>();
|
private readonly dirtyPanels = new Set<IGroupPanel>();
|
||||||
private readonly debouncedDeque = debounce(
|
private readonly debouncedDeque = debounce(
|
||||||
@ -144,11 +145,11 @@ export class DockviewComponent
|
|||||||
);
|
);
|
||||||
// events
|
// events
|
||||||
private readonly _onTabInteractionEvent = new Emitter<LayoutMouseEvent>();
|
private readonly _onTabInteractionEvent = new Emitter<LayoutMouseEvent>();
|
||||||
readonly onTabInteractionEvent: Event<LayoutMouseEvent> = this
|
readonly onTabInteractionEvent: Event<LayoutMouseEvent> =
|
||||||
._onTabInteractionEvent.event;
|
this._onTabInteractionEvent.event;
|
||||||
private readonly _onTabContextMenu = new Emitter<TabContextMenuEvent>();
|
private readonly _onTabContextMenu = new Emitter<TabContextMenuEvent>();
|
||||||
readonly onTabContextMenu: Event<TabContextMenuEvent> = this
|
readonly onTabContextMenu: Event<TabContextMenuEvent> =
|
||||||
._onTabContextMenu.event;
|
this._onTabContextMenu.event;
|
||||||
// everything else
|
// everything else
|
||||||
private drag = new MutableDisposable();
|
private drag = new MutableDisposable();
|
||||||
private _deserializer: IPanelDeserializer | undefined;
|
private _deserializer: IPanelDeserializer | undefined;
|
||||||
@ -270,7 +271,7 @@ export class DockviewComponent
|
|||||||
|
|
||||||
const panel = this.panels.get(panelOptions.id)?.value;
|
const panel = this.panels.get(panelOptions.id)?.value;
|
||||||
if (panel) {
|
if (panel) {
|
||||||
this.drag.value = panel.group!.group.startActiveDrag(panel);
|
this.drag.value = panel.group!.model.startActiveDrag(panel);
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = JSON.stringify({
|
const data = JSON.stringify({
|
||||||
@ -309,7 +310,7 @@ export class DockviewComponent
|
|||||||
throw new Error(`Panel ${panel.id} has no associated group`);
|
throw new Error(`Panel ${panel.id} has no associated group`);
|
||||||
}
|
}
|
||||||
this.doSetGroupActive(panel.group);
|
this.doSetGroupActive(panel.group);
|
||||||
panel.group.group.openPanel(panel);
|
panel.group.model.openPanel(panel);
|
||||||
}
|
}
|
||||||
|
|
||||||
public moveToNext(options: MovementOptions = {}): void {
|
public moveToNext(options: MovementOptions = {}): void {
|
||||||
@ -322,12 +323,12 @@ export class DockviewComponent
|
|||||||
|
|
||||||
if (options.includePanel && options.group) {
|
if (options.includePanel && options.group) {
|
||||||
if (
|
if (
|
||||||
options.group.group.activePanel !==
|
options.group.model.activePanel !==
|
||||||
options.group.group.panels[
|
options.group.model.panels[
|
||||||
options.group.group.panels.length - 1
|
options.group.model.panels.length - 1
|
||||||
]
|
]
|
||||||
) {
|
) {
|
||||||
options.group.group.moveToNext({ suppressRoll: true });
|
options.group.model.moveToNext({ suppressRoll: true });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -347,10 +348,10 @@ export class DockviewComponent
|
|||||||
|
|
||||||
if (options.includePanel && options.group) {
|
if (options.includePanel && options.group) {
|
||||||
if (
|
if (
|
||||||
options.group.group.activePanel !==
|
options.group.model.activePanel !==
|
||||||
options.group.group.panels[0]
|
options.group.model.panels[0]
|
||||||
) {
|
) {
|
||||||
options.group.group.moveToPrevious({ suppressRoll: true });
|
options.group.model.moveToPrevious({ suppressRoll: true });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -511,7 +512,7 @@ export class DockviewComponent
|
|||||||
for (const entry of this.groups.entries()) {
|
for (const entry of this.groups.entries()) {
|
||||||
const [_, group] = entry;
|
const [_, group] = entry;
|
||||||
|
|
||||||
const didCloseAll = await group.value.group.closeAllPanels();
|
const didCloseAll = await group.value.model.closeAllPanels();
|
||||||
if (!didCloseAll) {
|
if (!didCloseAll) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -523,7 +524,7 @@ export class DockviewComponent
|
|||||||
public setTabHeight(height: number | undefined): void {
|
public setTabHeight(height: number | undefined): void {
|
||||||
this.options.tabHeight = height;
|
this.options.tabHeight = height;
|
||||||
this.groups.forEach((value) => {
|
this.groups.forEach((value) => {
|
||||||
value.value.group.tabHeight = height;
|
value.value.model.tabHeight = height;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -569,7 +570,7 @@ export class DockviewComponent
|
|||||||
if (referenceGroup) {
|
if (referenceGroup) {
|
||||||
const target = toTarget(options.position?.direction || 'within');
|
const target = toTarget(options.position?.direction || 'within');
|
||||||
if (target === Position.Center) {
|
if (target === Position.Center) {
|
||||||
referenceGroup.group.openPanel(panel);
|
referenceGroup.model.openPanel(panel);
|
||||||
} else {
|
} else {
|
||||||
const location = getGridLocation(referenceGroup.element);
|
const location = getGridLocation(referenceGroup.element);
|
||||||
const relativeLocation = getRelativeLocation(
|
const relativeLocation = getRelativeLocation(
|
||||||
@ -652,8 +653,9 @@ export class DockviewComponent
|
|||||||
const group = this.createGroup();
|
const group = this.createGroup();
|
||||||
|
|
||||||
if (options) {
|
if (options) {
|
||||||
const referencePanel = this.panels.get(options.referencePanel)
|
const referencePanel = this.panels.get(
|
||||||
?.value;
|
options.referencePanel
|
||||||
|
)?.value;
|
||||||
|
|
||||||
if (!referencePanel) {
|
if (!referencePanel) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
@ -684,9 +686,9 @@ export class DockviewComponent
|
|||||||
}
|
}
|
||||||
|
|
||||||
public removeGroup(group: GroupviewPanel): void {
|
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) => {
|
panels.forEach((panel) => {
|
||||||
group.group.removePanel(panel);
|
group.model.removePanel(panel);
|
||||||
this.unregisterPanel(panel);
|
this.unregisterPanel(panel);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -707,7 +709,7 @@ export class DockviewComponent
|
|||||||
group! = this.createGroup();
|
group! = this.createGroup();
|
||||||
this.doAddGroup(group, location);
|
this.doAddGroup(group, location);
|
||||||
|
|
||||||
group.group.openPanel(panel);
|
group.model.openPanel(panel);
|
||||||
}
|
}
|
||||||
|
|
||||||
public moveGroupOrPanel(
|
public moveGroupOrPanel(
|
||||||
@ -723,18 +725,18 @@ export class DockviewComponent
|
|||||||
|
|
||||||
if (!target || target === Position.Center) {
|
if (!target || target === Position.Center) {
|
||||||
const groupItem: IGroupPanel | undefined =
|
const groupItem: IGroupPanel | undefined =
|
||||||
sourceGroup?.group.removePanel(itemId) ||
|
sourceGroup?.model.removePanel(itemId) ||
|
||||||
this.panels.get(itemId)?.value;
|
this.panels.get(itemId)?.value;
|
||||||
|
|
||||||
if (!groupItem) {
|
if (!groupItem) {
|
||||||
throw new Error(`No panel with id ${itemId}`);
|
throw new Error(`No panel with id ${itemId}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sourceGroup?.group.size === 0) {
|
if (sourceGroup?.model.size === 0) {
|
||||||
this.doRemoveGroup(sourceGroup);
|
this.doRemoveGroup(sourceGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
referenceGroup.group.openPanel(groupItem, { index });
|
referenceGroup.model.openPanel(groupItem, { index });
|
||||||
} else {
|
} else {
|
||||||
const referenceLocation = getGridLocation(referenceGroup.element);
|
const referenceLocation = getGridLocation(referenceGroup.element);
|
||||||
const targetLocation = getRelativeLocation(
|
const targetLocation = getRelativeLocation(
|
||||||
@ -743,7 +745,7 @@ export class DockviewComponent
|
|||||||
target
|
target
|
||||||
);
|
);
|
||||||
|
|
||||||
if (sourceGroup && sourceGroup.group.size < 2) {
|
if (sourceGroup && sourceGroup.model.size < 2) {
|
||||||
const [targetParentLocation, to] = tail(targetLocation);
|
const [targetParentLocation, to] = tail(targetLocation);
|
||||||
const sourceLocation = getGridLocation(sourceGroup.element);
|
const sourceLocation = getGridLocation(sourceGroup.element);
|
||||||
const [sourceParentLocation, from] = tail(sourceLocation);
|
const [sourceParentLocation, from] = tail(sourceLocation);
|
||||||
@ -775,7 +777,7 @@ export class DockviewComponent
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const groupItem: IGroupPanel | undefined =
|
const groupItem: IGroupPanel | undefined =
|
||||||
sourceGroup?.group.removePanel(itemId) ||
|
sourceGroup?.model.removePanel(itemId) ||
|
||||||
this.panels.get(itemId)?.value;
|
this.panels.get(itemId)?.value;
|
||||||
|
|
||||||
if (!groupItem) {
|
if (!groupItem) {
|
||||||
@ -820,19 +822,19 @@ export class DockviewComponent
|
|||||||
const view = new GroupviewPanel(this, id, options);
|
const view = new GroupviewPanel(this, id, options);
|
||||||
|
|
||||||
if (typeof this.options.tabHeight === 'number') {
|
if (typeof this.options.tabHeight === 'number') {
|
||||||
view.group.tabHeight = this.options.tabHeight;
|
view.model.tabHeight = this.options.tabHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.groups.has(view.id)) {
|
if (!this.groups.has(view.id)) {
|
||||||
const disposable = new CompositeDisposable(
|
const disposable = new CompositeDisposable(
|
||||||
view.group.onMove((event) => {
|
view.model.onMove((event) => {
|
||||||
const { groupId, itemId, target, index } = event;
|
const { groupId, itemId, target, index } = event;
|
||||||
this.moveGroupOrPanel(view, groupId, itemId, target, index);
|
this.moveGroupOrPanel(view, groupId, itemId, target, index);
|
||||||
}),
|
}),
|
||||||
view.group.onDidGroupChange((event) => {
|
view.model.onDidGroupChange((event) => {
|
||||||
this._onGridEvent.fire(event);
|
this._onGridEvent.fire(event);
|
||||||
}),
|
}),
|
||||||
view.group.onDrop((event) => {
|
view.model.onDrop((event) => {
|
||||||
const dragEvent = event.event;
|
const dragEvent = event.event;
|
||||||
const dataTransfer = dragEvent.dataTransfer;
|
const dataTransfer = dragEvent.dataTransfer;
|
||||||
|
|
||||||
@ -883,7 +885,7 @@ export class DockviewComponent
|
|||||||
|
|
||||||
private findGroup(panel: IGroupPanel): GroupviewPanel | undefined {
|
private findGroup(panel: IGroupPanel): GroupviewPanel | undefined {
|
||||||
return Array.from(this.groups.values()).find((group) =>
|
return Array.from(this.groups.values()).find((group) =>
|
||||||
group.value.group.containsPanel(panel)
|
group.value.model.containsPanel(panel)
|
||||||
)?.value;
|
)?.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -157,10 +157,10 @@ export class DockviewGroupPanel
|
|||||||
this._group = group;
|
this._group = group;
|
||||||
this.api.group = group;
|
this.api.group = group;
|
||||||
|
|
||||||
this.mutableDisposable.value = this._group.group.onDidGroupChange(
|
this.mutableDisposable.value = this._group.model.onDidGroupChange(
|
||||||
(ev) => {
|
(ev) => {
|
||||||
if (ev.kind === GroupChangeKind.GROUP_ACTIVE) {
|
if (ev.kind === GroupChangeKind.GROUP_ACTIVE) {
|
||||||
const isVisible = !!this._group?.group.isPanelActive(this);
|
const isVisible = !!this._group?.model.isPanelActive(this);
|
||||||
this.api._onDidActiveChange.fire({
|
this.api._onDidActiveChange.fire({
|
||||||
isActive: isGroupActive && isVisible,
|
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({
|
this.api._onDidActiveChange.fire({
|
||||||
isActive: isGroupActive && isPanelVisible,
|
isActive: isGroupActive && isPanelVisible,
|
||||||
@ -182,7 +182,7 @@ export class DockviewGroupPanel
|
|||||||
|
|
||||||
this.view?.updateParentGroup(
|
this.view?.updateParentGroup(
|
||||||
this._group,
|
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
|
// the obtain the correct dimensions of the content panel we must deduct the tab height
|
||||||
this.api._onDidPanelDimensionChange.fire({
|
this.api._onDidPanelDimensionChange.fire({
|
||||||
width,
|
width,
|
||||||
height: height - (this.group?.group.tabHeight || 0),
|
height: height - (this.group?.model.tabHeight || 0),
|
||||||
});
|
});
|
||||||
|
|
||||||
this.view?.layout(width, height);
|
this.view?.layout(width, height);
|
||||||
|
|||||||
@ -27,7 +27,8 @@ export interface BasePanelViewExported<T extends PanelApiImpl> {
|
|||||||
|
|
||||||
export abstract class BasePanelView<T extends PanelApiImpl>
|
export abstract class BasePanelView<T extends PanelApiImpl>
|
||||||
extends CompositeDisposable
|
extends CompositeDisposable
|
||||||
implements IPanel, BasePanelViewExported<T> {
|
implements IPanel, BasePanelViewExported<T>
|
||||||
|
{
|
||||||
private _height = 0;
|
private _height = 0;
|
||||||
private _width = 0;
|
private _width = 0;
|
||||||
private _element: HTMLElement;
|
private _element: HTMLElement;
|
||||||
@ -87,8 +88,10 @@ export abstract class BasePanelView<T extends PanelApiImpl>
|
|||||||
this._height = height;
|
this._height = height;
|
||||||
this.api._onDidPanelDimensionChange.fire({ width, height });
|
this.api._onDidPanelDimensionChange.fire({ width, height });
|
||||||
|
|
||||||
if (this.part && this.params) {
|
if (this.part) {
|
||||||
this.part.update(this.params.params);
|
if (this.params) {
|
||||||
|
this.part.update(this.params.params);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -35,7 +35,8 @@ export interface IGridviewPanel
|
|||||||
|
|
||||||
export abstract class GridviewPanel
|
export abstract class GridviewPanel
|
||||||
extends BasePanelView<GridviewPanelApiImpl>
|
extends BasePanelView<GridviewPanelApiImpl>
|
||||||
implements IGridPanelComponentView, IGridviewPanel {
|
implements IGridPanelComponentView, IGridviewPanel
|
||||||
|
{
|
||||||
private _evaluatedMinimumWidth = 0;
|
private _evaluatedMinimumWidth = 0;
|
||||||
private _evaluatedMaximumWidth = Number.MAX_SAFE_INTEGER;
|
private _evaluatedMaximumWidth = Number.MAX_SAFE_INTEGER;
|
||||||
private _evaluatedMinimumHeight = 0;
|
private _evaluatedMinimumHeight = 0;
|
||||||
@ -49,8 +50,8 @@ export abstract class GridviewPanel
|
|||||||
private _snap = false;
|
private _snap = false;
|
||||||
|
|
||||||
private readonly _onDidChange = new Emitter<IViewSize | undefined>();
|
private readonly _onDidChange = new Emitter<IViewSize | undefined>();
|
||||||
readonly onDidChange: Event<IViewSize | undefined> = this._onDidChange
|
readonly onDidChange: Event<IViewSize | undefined> =
|
||||||
.event;
|
this._onDidChange.event;
|
||||||
|
|
||||||
get priority(): LayoutPriority | undefined {
|
get priority(): LayoutPriority | undefined {
|
||||||
return this._priority;
|
return this._priority;
|
||||||
|
|||||||
@ -16,12 +16,18 @@ import { addDisposableListener, Emitter, Event } from '../events';
|
|||||||
import { IGridPanelView } from '../gridview/baseComponentGridview';
|
import { IGridPanelView } from '../gridview/baseComponentGridview';
|
||||||
import { IViewSize } from '../gridview/gridview';
|
import { IViewSize } from '../gridview/gridview';
|
||||||
import { CompositeDisposable, Disposable, IDisposable } from '../lifecycle';
|
import { CompositeDisposable, Disposable, IDisposable } from '../lifecycle';
|
||||||
import { PanelInitParameters, PanelUpdateEvent } from '../panel/types';
|
import {
|
||||||
|
IFrameworkPart,
|
||||||
|
PanelInitParameters,
|
||||||
|
PanelUpdateEvent,
|
||||||
|
} from '../panel/types';
|
||||||
import { IGroupPanel } from './groupPanel';
|
import { IGroupPanel } from './groupPanel';
|
||||||
import { ContentContainer, IContentContainer } from './panel/content';
|
import { ContentContainer, IContentContainer } from './panel/content';
|
||||||
import { ITabsContainer, TabsContainer } from './titlebar/tabsContainer';
|
import { ITabsContainer, TabsContainer } from './titlebar/tabsContainer';
|
||||||
import { IWatermarkRenderer } from './types';
|
import { IWatermarkRenderer } from './types';
|
||||||
import { GroupviewPanel } from './groupviewPanel';
|
import { GroupviewPanel } from './groupviewPanel';
|
||||||
|
import { focusedElement } from '../focusedElement';
|
||||||
|
import { BasePanelView } from '../gridview/basePanelView';
|
||||||
|
|
||||||
export enum GroupChangeKind {
|
export enum GroupChangeKind {
|
||||||
GROUP_ACTIVE = 'GROUP_ACTIVE',
|
GROUP_ACTIVE = 'GROUP_ACTIVE',
|
||||||
@ -80,7 +86,7 @@ export interface IGroupview extends IDisposable, IGridPanelView {
|
|||||||
readonly isActive: boolean;
|
readonly isActive: boolean;
|
||||||
readonly size: number;
|
readonly size: number;
|
||||||
readonly panels: IGroupPanel[];
|
readonly panels: IGroupPanel[];
|
||||||
tabHeight: number | undefined;
|
readonly tabHeight: number | undefined;
|
||||||
// state
|
// state
|
||||||
isPanelActive: (panel: IGroupPanel) => boolean;
|
isPanelActive: (panel: IGroupPanel) => boolean;
|
||||||
activePanel: IGroupPanel | undefined;
|
activePanel: IGroupPanel | undefined;
|
||||||
@ -105,7 +111,7 @@ export interface IGroupview extends IDisposable, IGridPanelView {
|
|||||||
panel?: IGroupPanel;
|
panel?: IGroupPanel;
|
||||||
suppressRoll?: boolean;
|
suppressRoll?: boolean;
|
||||||
}): void;
|
}): void;
|
||||||
isAncestor(element: Element): boolean;
|
isContentFocused(): boolean;
|
||||||
updateActions(): void;
|
updateActions(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,8 +132,8 @@ export class Groupview extends CompositeDisposable implements IGroupview {
|
|||||||
private mostRecentlyUsed: IGroupPanel[] = [];
|
private mostRecentlyUsed: IGroupPanel[] = [];
|
||||||
|
|
||||||
private readonly _onDidChange = new Emitter<IViewSize | undefined>();
|
private readonly _onDidChange = new Emitter<IViewSize | undefined>();
|
||||||
readonly onDidChange: Event<IViewSize | undefined> = this._onDidChange
|
readonly onDidChange: Event<IViewSize | undefined> =
|
||||||
.event;
|
this._onDidChange.event;
|
||||||
|
|
||||||
private _width = 0;
|
private _width = 0;
|
||||||
private _height = 0;
|
private _height = 0;
|
||||||
@ -141,8 +147,8 @@ export class Groupview extends CompositeDisposable implements IGroupview {
|
|||||||
readonly onDrop: Event<GroupDropEvent> = this._onDrop.event;
|
readonly onDrop: Event<GroupDropEvent> = this._onDrop.event;
|
||||||
|
|
||||||
private readonly _onDidGroupChange = new Emitter<GroupChangeEvent>();
|
private readonly _onDidGroupChange = new Emitter<GroupChangeEvent>();
|
||||||
readonly onDidGroupChange: Event<{ kind: GroupChangeKind }> = this
|
readonly onDidGroupChange: Event<{ kind: GroupChangeKind }> =
|
||||||
._onDidGroupChange.event;
|
this._onDidGroupChange.event;
|
||||||
|
|
||||||
get element(): HTMLElement {
|
get element(): HTMLElement {
|
||||||
throw new Error('not supported');
|
throw new Error('not supported');
|
||||||
@ -193,10 +199,92 @@ export class Groupview extends CompositeDisposable implements IGroupview {
|
|||||||
return Number.MAX_SAFE_INTEGER;
|
return Number.MAX_SAFE_INTEGER;
|
||||||
}
|
}
|
||||||
|
|
||||||
isAncestor(element: Element): boolean {
|
constructor(
|
||||||
return (
|
private readonly container: HTMLElement,
|
||||||
element === this.contentContainer.element ||
|
private accessor: IDockviewComponent,
|
||||||
isAncestor(element, this.contentContainer.element)
|
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);
|
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) {
|
init(params: PanelInitParameters) {
|
||||||
//noop
|
//noop
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,47 +1,30 @@
|
|||||||
import { IFrameworkPart } from '../panel/types';
|
import { IFrameworkPart } from '../panel/types';
|
||||||
import { IDockviewComponent } from '../dockview/dockviewComponent';
|
import { IDockviewComponent } from '../dockview/dockviewComponent';
|
||||||
import {
|
import { GridviewPanelApiImpl } from '../api/gridviewPanelApi';
|
||||||
GridviewPanelApiImpl,
|
|
||||||
GridviewPanelApi,
|
|
||||||
} from '../api/gridviewPanelApi';
|
|
||||||
import { Groupview, GroupOptions } from './groupview';
|
import { Groupview, GroupOptions } from './groupview';
|
||||||
import { GridviewPanel } from '../gridview/gridviewPanel';
|
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 {
|
export class GroupviewPanel extends GridviewPanel {
|
||||||
private readonly _group: Groupview;
|
private readonly _model: Groupview;
|
||||||
|
|
||||||
get group(): Groupview {
|
get model(): Groupview {
|
||||||
return this._group;
|
return this._model;
|
||||||
}
|
}
|
||||||
|
|
||||||
get minimumHeight() {
|
get minimumHeight() {
|
||||||
return this._group.minimumHeight;
|
return this._model.minimumHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
get maximumHeight() {
|
get maximumHeight() {
|
||||||
return this._group.maximumHeight;
|
return this._model.maximumHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
get minimumWidth() {
|
get minimumWidth() {
|
||||||
return this._group.minimumWidth;
|
return this._model.minimumWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
get maximumWidth() {
|
get maximumWidth() {
|
||||||
return this._group.maximumWidth;
|
return this._model.maximumWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@ -49,29 +32,27 @@ export class GroupviewPanel extends GridviewPanel {
|
|||||||
id: string,
|
id: string,
|
||||||
options: GroupOptions
|
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._model = new Groupview(this.element, accessor, id, options, this);
|
||||||
|
this.model.initialize();
|
||||||
(this.api as GroupApi).group = this._group;
|
|
||||||
this.group.bootstrap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setActive(isActive: boolean): void {
|
setActive(isActive: boolean): void {
|
||||||
super.setActive(isActive);
|
super.setActive(isActive);
|
||||||
this.group.setActive(isActive);
|
this.model.setActive(isActive);
|
||||||
}
|
}
|
||||||
|
|
||||||
layout(width: number, height: number) {
|
layout(width: number, height: number) {
|
||||||
super.layout(width, height);
|
super.layout(width, height);
|
||||||
this.group.layout(width, height);
|
this.model.layout(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
getComponent(): IFrameworkPart {
|
getComponent(): IFrameworkPart {
|
||||||
return this._group;
|
return this._model;
|
||||||
}
|
}
|
||||||
|
|
||||||
toJSON(): any {
|
toJSON(): any {
|
||||||
return this.group.toJSON();
|
return this.model.toJSON();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,13 +7,6 @@ import { Emitter, Event } from '../../events';
|
|||||||
import { trackFocus } from '../../dom';
|
import { trackFocus } from '../../dom';
|
||||||
import { IGroupPanel } from '../groupPanel';
|
import { IGroupPanel } from '../groupPanel';
|
||||||
|
|
||||||
export interface IRenderable {
|
|
||||||
id: string;
|
|
||||||
element: HTMLElement;
|
|
||||||
onDidFocus?: Event<void>;
|
|
||||||
onDidBlur?: Event<void>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IContentContainer extends IDisposable {
|
export interface IContentContainer extends IDisposable {
|
||||||
onDidFocus: Event<void>;
|
onDidFocus: Event<void>;
|
||||||
onDidBlur: Event<void>;
|
onDidBlur: Event<void>;
|
||||||
@ -25,76 +18,10 @@ export interface IContentContainer extends IDisposable {
|
|||||||
hide(): void;
|
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
|
export class ContentContainer
|
||||||
extends CompositeDisposable
|
extends CompositeDisposable
|
||||||
implements IContentContainer {
|
implements IContentContainer
|
||||||
|
{
|
||||||
private _element: HTMLElement;
|
private _element: HTMLElement;
|
||||||
private panel: IGroupPanel | undefined;
|
private panel: IGroupPanel | undefined;
|
||||||
private disposable = new MutableDisposable();
|
private disposable = new MutableDisposable();
|
||||||
@ -145,8 +72,8 @@ export class ContentContainer
|
|||||||
const disposable = new CompositeDisposable();
|
const disposable = new CompositeDisposable();
|
||||||
|
|
||||||
if (this.panel.view) {
|
if (this.panel.view) {
|
||||||
const _onDidFocus: Event<void> = this.panel.view.content
|
const _onDidFocus: Event<void> =
|
||||||
.onDidFocus!;
|
this.panel.view.content.onDidFocus!;
|
||||||
const _onDidBlur: Event<void> = this.panel.view.content.onDidBlur!;
|
const _onDidBlur: Event<void> = this.panel.view.content.onDidBlur!;
|
||||||
|
|
||||||
const { onDidFocus, onDidBlur } = trackFocus(this._element);
|
const { onDidFocus, onDidBlur } = trackFocus(this._element);
|
||||||
|
|||||||
71
packages/dockview/src/groupview/panel/hostedPanel.ts
Normal file
71
packages/dockview/src/groupview/panel/hostedPanel.ts
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -8,7 +8,6 @@ import { ITab, MouseEventKind, Tab } from '../tab';
|
|||||||
import { removeClasses, addClasses } from '../../dom';
|
import { removeClasses, addClasses } from '../../dom';
|
||||||
import { DroptargetEvent, Position } from '../../dnd/droptarget';
|
import { DroptargetEvent, Position } from '../../dnd/droptarget';
|
||||||
import { last } from '../../array';
|
import { last } from '../../array';
|
||||||
import { focusedElement } from '../../focusedElement';
|
|
||||||
import { IGroupPanel } from '../groupPanel';
|
import { IGroupPanel } from '../groupPanel';
|
||||||
import { IDockviewComponent } from '../../dockview/dockviewComponent';
|
import { IDockviewComponent } from '../../dockview/dockviewComponent';
|
||||||
import { LocalSelectionTransfer } from '../../dnd/dataTransfer';
|
import { LocalSelectionTransfer } from '../../dnd/dataTransfer';
|
||||||
@ -40,7 +39,8 @@ export interface ITabsContainer extends IDisposable {
|
|||||||
|
|
||||||
export class TabsContainer
|
export class TabsContainer
|
||||||
extends CompositeDisposable
|
extends CompositeDisposable
|
||||||
implements ITabsContainer {
|
implements ITabsContainer
|
||||||
|
{
|
||||||
private readonly _element: HTMLElement;
|
private readonly _element: HTMLElement;
|
||||||
private readonly tabContainer: HTMLElement;
|
private readonly tabContainer: HTMLElement;
|
||||||
private readonly actionContainer: HTMLElement;
|
private readonly actionContainer: HTMLElement;
|
||||||
@ -281,8 +281,8 @@ export class TabsContainer
|
|||||||
const disposable = CompositeDisposable.from(
|
const disposable = CompositeDisposable.from(
|
||||||
tabToAdd.onChanged((event) => {
|
tabToAdd.onChanged((event) => {
|
||||||
const alreadyFocused =
|
const alreadyFocused =
|
||||||
panel.id === this.group.group.activePanel?.id &&
|
panel.id === this.group.model.activePanel?.id &&
|
||||||
this.group.group.isAncestor(focusedElement.element!);
|
this.group.model.isContentFocused();
|
||||||
this.accessor.fireMouseEvent({ ...event, panel, tab: true });
|
this.accessor.fireMouseEvent({ ...event, panel, tab: true });
|
||||||
|
|
||||||
const isLeftClick = event.event.button === 0;
|
const isLeftClick = event.event.button === 0;
|
||||||
@ -293,7 +293,7 @@ export class TabsContainer
|
|||||||
|
|
||||||
switch (event.kind) {
|
switch (event.kind) {
|
||||||
case MouseEventKind.CLICK:
|
case MouseEventKind.CLICK:
|
||||||
this.group.group.openPanel(panel, {
|
this.group.model.openPanel(panel, {
|
||||||
skipFocus: alreadyFocused,
|
skipFocus: alreadyFocused,
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -7,6 +7,13 @@ import { GroupviewPanel } from './groupviewPanel';
|
|||||||
import { Event } from '../events';
|
import { Event } from '../events';
|
||||||
import { WrappedTab } from '../dockview/components/tab/defaultTab';
|
import { WrappedTab } from '../dockview/components/tab/defaultTab';
|
||||||
|
|
||||||
|
export interface IRenderable {
|
||||||
|
id: string;
|
||||||
|
element: HTMLElement;
|
||||||
|
onDidFocus?: Event<void>;
|
||||||
|
onDidBlur?: Event<void>;
|
||||||
|
}
|
||||||
|
|
||||||
export interface HeaderPartInitParameters {
|
export interface HeaderPartInitParameters {
|
||||||
title: string;
|
title: string;
|
||||||
suppressClosable?: boolean;
|
suppressClosable?: boolean;
|
||||||
|
|||||||
@ -15,10 +15,6 @@ import { PanelCollection, PanelParameters } from '../types';
|
|||||||
import { watchElementResize } from '../../dom';
|
import { watchElementResize } from '../../dom';
|
||||||
import { IContentRenderer, ITabRenderer } from '../../groupview/types';
|
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>>
|
export interface IGroupPanelBaseProps<T extends {} = Record<string, any>>
|
||||||
extends PanelParameters<T> {
|
extends PanelParameters<T> {
|
||||||
api: DockviewPanelApi;
|
api: DockviewPanelApi;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user