mirror of
https://github.com/mathuo/dockview
synced 2025-01-22 17:35:57 +00:00
feat: events cleanup
This commit is contained in:
parent
89fe866ac5
commit
807ccf80de
@ -257,9 +257,17 @@ describe('dockviewComponent', () => {
|
||||
const panel4 = dockview.getGroupPanel('panel4');
|
||||
|
||||
const group1 = panel1!.group;
|
||||
dockview.moveGroupOrPanel(group1, group1.id, 'panel1', 'right');
|
||||
|
||||
dockview.moveGroupOrPanel({
|
||||
from: { groupId: group1.id, panelId: 'panel1' },
|
||||
to: { group: group1, position: 'right' },
|
||||
});
|
||||
const group2 = panel1!.group;
|
||||
dockview.moveGroupOrPanel(group2, group1.id, 'panel3', 'center');
|
||||
|
||||
dockview.moveGroupOrPanel({
|
||||
from: { groupId: group1.id, panelId: 'panel3' },
|
||||
to: { group: group2, position: 'center' },
|
||||
});
|
||||
|
||||
expect(dockview.activeGroup).toBe(group2);
|
||||
expect(dockview.activeGroup!.model.activePanel).toBe(panel3);
|
||||
@ -309,9 +317,16 @@ describe('dockviewComponent', () => {
|
||||
const panel1 = dockview.getGroupPanel('panel1')!;
|
||||
const panel2 = dockview.getGroupPanel('panel2')!;
|
||||
const group1 = panel1.group;
|
||||
dockview.moveGroupOrPanel(group1, group1.id, 'panel1', 'right');
|
||||
|
||||
dockview.moveGroupOrPanel({
|
||||
from: { groupId: group1.id, panelId: 'panel1' },
|
||||
to: { group: group1, position: 'right' },
|
||||
});
|
||||
const group2 = panel1.group;
|
||||
dockview.moveGroupOrPanel(group2, group1.id, 'panel3', 'center');
|
||||
dockview.moveGroupOrPanel({
|
||||
from: { groupId: group1.id, panelId: 'panel3' },
|
||||
to: { group: group2, position: 'center' },
|
||||
});
|
||||
|
||||
expect(dockview.size).toBe(2);
|
||||
expect(dockview.totalPanels).toBe(4);
|
||||
@ -374,9 +389,16 @@ describe('dockviewComponent', () => {
|
||||
expect(panel4.api.isActive).toBeFalsy();
|
||||
|
||||
const group1 = panel1.group;
|
||||
dockview.moveGroupOrPanel(group1, group1.id, 'panel1', 'right');
|
||||
|
||||
dockview.moveGroupOrPanel({
|
||||
from: { groupId: group1.id, panelId: 'panel1' },
|
||||
to: { group: group1, position: 'right' },
|
||||
});
|
||||
const group2 = panel1.group;
|
||||
dockview.moveGroupOrPanel(group2, group1.id, 'panel3', 'center');
|
||||
dockview.moveGroupOrPanel({
|
||||
from: { groupId: group1.id, panelId: 'panel3' },
|
||||
to: { group: group2, position: 'center' },
|
||||
});
|
||||
|
||||
expect(dockview.size).toBe(2);
|
||||
expect(panel1.group).toBe(panel3.group);
|
||||
@ -443,7 +465,10 @@ describe('dockviewComponent', () => {
|
||||
expect(group.model.indexOf(panel1)).toBe(0);
|
||||
expect(group.model.indexOf(panel2)).toBe(1);
|
||||
|
||||
dockview.moveGroupOrPanel(group, group.id, 'panel1', 'right');
|
||||
dockview.moveGroupOrPanel({
|
||||
from: { groupId: group.id, panelId: 'panel1' },
|
||||
to: { group, position: 'right' },
|
||||
});
|
||||
|
||||
expect(dockview.size).toBe(2);
|
||||
expect(dockview.totalPanels).toBe(2);
|
||||
@ -493,7 +518,10 @@ describe('dockviewComponent', () => {
|
||||
expect(viewQuery.length).toBe(1);
|
||||
|
||||
const group = dockview.getGroupPanel('panel1')!.group;
|
||||
dockview.moveGroupOrPanel(group, group.id, 'panel1', 'right');
|
||||
dockview.moveGroupOrPanel({
|
||||
from: { groupId: group.id, panelId: 'panel1' },
|
||||
to: { group, position: 'right' },
|
||||
});
|
||||
|
||||
viewQuery = container.querySelectorAll(
|
||||
'.branch-node > .split-view-container > .view-container > .view'
|
||||
@ -908,8 +936,8 @@ describe('dockviewComponent', () => {
|
||||
|
||||
expect(events).toEqual([
|
||||
{ type: 'ADD_GROUP', group: panel1.group },
|
||||
{ type: 'ACTIVE_GROUP', group: panel1.group },
|
||||
{ type: 'ADD_PANEL', panel: panel1 },
|
||||
{ type: 'ACTIVE_GROUP', group: panel1.group },
|
||||
{ type: 'ACTIVE_PANEL', panel: panel1 },
|
||||
]);
|
||||
|
||||
@ -956,8 +984,8 @@ describe('dockviewComponent', () => {
|
||||
|
||||
expect(events).toEqual([
|
||||
{ type: 'ADD_GROUP', group: panel4.group },
|
||||
{ type: 'ACTIVE_GROUP', group: panel4.group },
|
||||
{ type: 'ADD_PANEL', panel: panel4 },
|
||||
{ type: 'ACTIVE_GROUP', group: panel4.group },
|
||||
{ type: 'ACTIVE_PANEL', panel: panel4 },
|
||||
]);
|
||||
|
||||
@ -973,36 +1001,24 @@ describe('dockviewComponent', () => {
|
||||
]);
|
||||
|
||||
events = [];
|
||||
dockview.moveGroupOrPanel(
|
||||
panel2.group!,
|
||||
panel5.group!.id,
|
||||
panel5.id,
|
||||
'center'
|
||||
);
|
||||
dockview.moveGroupOrPanel({
|
||||
from: { groupId: panel5.group.id, panelId: panel5.id },
|
||||
to: { group: panel2.group, position: 'center' },
|
||||
});
|
||||
|
||||
expect(events).toEqual([
|
||||
{ type: 'REMOVE_PANEL', panel: panel5 },
|
||||
{ type: 'ACTIVE_PANEL', panel: panel4 },
|
||||
{ type: 'ADD_PANEL', panel: panel5 },
|
||||
{ type: 'ACTIVE_PANEL', panel: panel5 },
|
||||
{ type: 'ACTIVE_GROUP', group: panel2.group },
|
||||
]);
|
||||
expect(events).toEqual([{ type: 'ACTIVE_GROUP', group: panel2.group }]);
|
||||
|
||||
events = [];
|
||||
|
||||
const groupReferenceBeforeMove = panel4.group;
|
||||
|
||||
dockview.moveGroupOrPanel(
|
||||
panel2.group!,
|
||||
panel4.group!.id,
|
||||
panel4.id,
|
||||
'center'
|
||||
);
|
||||
dockview.moveGroupOrPanel({
|
||||
from: { groupId: panel4.group.id, panelId: panel4.id },
|
||||
to: { group: panel2.group, position: 'center' },
|
||||
});
|
||||
|
||||
expect(events).toEqual([
|
||||
{ type: 'REMOVE_PANEL', panel: panel4 },
|
||||
{ type: 'REMOVE_GROUP', group: groupReferenceBeforeMove },
|
||||
{ type: 'ADD_PANEL', panel: panel4 },
|
||||
{ type: 'ACTIVE_PANEL', panel: panel4 },
|
||||
]);
|
||||
|
||||
@ -1022,8 +1038,8 @@ describe('dockviewComponent', () => {
|
||||
expect(events).toEqual([
|
||||
{ type: 'ADD_GROUP', group: panel6.group },
|
||||
{ type: 'ADD_PANEL', panel: panel6 },
|
||||
{ type: 'ACTIVE_PANEL', panel: panel6 },
|
||||
{ type: 'ACTIVE_GROUP', group: panel6.group },
|
||||
{ type: 'ACTIVE_PANEL', panel: panel6 },
|
||||
]);
|
||||
|
||||
events = [];
|
||||
@ -1038,8 +1054,8 @@ describe('dockviewComponent', () => {
|
||||
expect(events).toEqual([
|
||||
{ type: 'ADD_GROUP', group: panel7.group },
|
||||
{ type: 'ADD_PANEL', panel: panel7 },
|
||||
{ type: 'ACTIVE_PANEL', panel: panel7 },
|
||||
{ type: 'ACTIVE_GROUP', group: panel7.group },
|
||||
{ type: 'ACTIVE_PANEL', panel: panel7 },
|
||||
]);
|
||||
|
||||
expect(dockview.activePanel === panel7).toBeTruthy();
|
||||
@ -1061,6 +1077,7 @@ describe('dockviewComponent', () => {
|
||||
{ type: 'REMOVE_PANEL', panel: panel6 },
|
||||
{ type: 'REMOVE_GROUP', group: panel6Group },
|
||||
{ type: 'ACTIVE_GROUP', group: undefined },
|
||||
{ type: 'ACTIVE_PANEL', group: undefined },
|
||||
]);
|
||||
|
||||
expect(dockview.size).toBe(0);
|
||||
@ -1317,12 +1334,10 @@ describe('dockviewComponent', () => {
|
||||
const panel1Spy = jest.spyOn(panel1, 'dispose');
|
||||
const panel2Spy = jest.spyOn(panel2, 'dispose');
|
||||
|
||||
dockview.moveGroupOrPanel(
|
||||
panel1.group,
|
||||
panel2.group.id,
|
||||
'panel2',
|
||||
'left'
|
||||
);
|
||||
dockview.moveGroupOrPanel({
|
||||
from: { groupId: panel2.group.id, panelId: 'panel2' },
|
||||
to: { group: panel1.group, position: 'left' },
|
||||
});
|
||||
|
||||
expect(panel1Spy).not.toHaveBeenCalled();
|
||||
expect(panel2Spy).not.toHaveBeenCalled();
|
||||
@ -1359,12 +1374,10 @@ describe('dockviewComponent', () => {
|
||||
const panel1Spy = jest.spyOn(panel1, 'dispose');
|
||||
const panel2Spy = jest.spyOn(panel2, 'dispose');
|
||||
|
||||
dockview.moveGroupOrPanel(
|
||||
panel1.group,
|
||||
panel2.group.id,
|
||||
'panel2',
|
||||
'center'
|
||||
);
|
||||
dockview.moveGroupOrPanel({
|
||||
from: { groupId: panel2.group.id, panelId: 'panel2' },
|
||||
to: { group: panel1.group, position: 'center' },
|
||||
});
|
||||
|
||||
expect(panel1Spy).not.toHaveBeenCalled();
|
||||
expect(panel2Spy).not.toHaveBeenCalled();
|
||||
@ -1399,13 +1412,10 @@ describe('dockviewComponent', () => {
|
||||
const panel1Spy = jest.spyOn(panel1, 'dispose');
|
||||
const panel2Spy = jest.spyOn(panel2, 'dispose');
|
||||
|
||||
dockview.moveGroupOrPanel(
|
||||
panel1.group,
|
||||
panel1.group.id,
|
||||
'panel1',
|
||||
'center',
|
||||
0
|
||||
);
|
||||
dockview.moveGroupOrPanel({
|
||||
from: { groupId: panel1.group.id, panelId: 'panel1' },
|
||||
to: { group: panel1.group, position: 'center', index: 0 },
|
||||
});
|
||||
|
||||
expect(panel1Spy).not.toHaveBeenCalled();
|
||||
expect(panel2Spy).not.toHaveBeenCalled();
|
||||
@ -1563,12 +1573,10 @@ describe('dockviewComponent', () => {
|
||||
|
||||
expect(dockview.groups.length).toBe(2);
|
||||
|
||||
dockview.moveGroupOrPanel(
|
||||
panel3.group,
|
||||
panel1.group.id,
|
||||
undefined,
|
||||
'center'
|
||||
);
|
||||
dockview.moveGroupOrPanel({
|
||||
from: { groupId: panel1.group.id },
|
||||
to: { group: panel3.group, position: 'center' },
|
||||
});
|
||||
|
||||
expect(dockview.groups.length).toBe(1);
|
||||
expect(panel1Spy).toBeCalledTimes(1);
|
||||
@ -1697,7 +1705,7 @@ describe('dockviewComponent', () => {
|
||||
expect(activeGroup.length).toBe(1);
|
||||
expect(addPanel.length).toBe(5);
|
||||
expect(removePanel.length).toBe(0);
|
||||
expect(activePanel.length).toBe(5);
|
||||
expect(activePanel.length).toBe(1);
|
||||
expect(layoutChange).toBe(1);
|
||||
expect(layoutChangeFromJson).toBe(1);
|
||||
|
||||
@ -2728,32 +2736,26 @@ describe('dockviewComponent', () => {
|
||||
|
||||
expect(dockview.element.querySelectorAll('.view').length).toBe(1);
|
||||
|
||||
dockview.moveGroupOrPanel(
|
||||
panel3.group,
|
||||
panel3.group.id,
|
||||
panel3.id,
|
||||
'right'
|
||||
);
|
||||
dockview.moveGroupOrPanel({
|
||||
from: { groupId: panel3.group.id, panelId: panel3.id },
|
||||
to: { group: panel3.group, position: 'right' },
|
||||
});
|
||||
|
||||
expect(dockview.groups.length).toBe(2);
|
||||
expect(dockview.element.querySelectorAll('.view').length).toBe(2);
|
||||
|
||||
dockview.moveGroupOrPanel(
|
||||
panel3.group,
|
||||
panel2.group.id,
|
||||
panel2.id,
|
||||
'bottom'
|
||||
);
|
||||
dockview.moveGroupOrPanel({
|
||||
from: { groupId: panel2.group.id, panelId: panel2.id },
|
||||
to: { group: panel3.group, position: 'bottom' },
|
||||
});
|
||||
|
||||
expect(dockview.groups.length).toBe(3);
|
||||
expect(dockview.element.querySelectorAll('.view').length).toBe(4);
|
||||
|
||||
dockview.moveGroupOrPanel(
|
||||
panel2.group,
|
||||
panel1.group.id,
|
||||
panel1.id,
|
||||
'center'
|
||||
);
|
||||
dockview.moveGroupOrPanel({
|
||||
from: { groupId: panel1.group.id, panelId: panel1.id },
|
||||
to: { group: panel2.group, position: 'center' },
|
||||
});
|
||||
|
||||
expect(dockview.groups.length).toBe(2);
|
||||
|
||||
@ -3463,12 +3465,10 @@ describe('dockviewComponent', () => {
|
||||
expect(dockview.groups.length).toBe(2);
|
||||
expect(dockview.panels.length).toBe(2);
|
||||
|
||||
dockview.moveGroupOrPanel(
|
||||
panel1.group,
|
||||
panel2.group.id,
|
||||
undefined,
|
||||
'right'
|
||||
);
|
||||
dockview.moveGroupOrPanel({
|
||||
from: { groupId: panel2.group.id },
|
||||
to: { group: panel1.group, position: 'right' },
|
||||
});
|
||||
|
||||
expect(panel1.group.api.location.type).toBe('grid');
|
||||
expect(panel2.group.api.location.type).toBe('grid');
|
||||
@ -3508,12 +3508,10 @@ describe('dockviewComponent', () => {
|
||||
expect(dockview.groups.length).toBe(2);
|
||||
expect(dockview.panels.length).toBe(2);
|
||||
|
||||
dockview.moveGroupOrPanel(
|
||||
panel1.group,
|
||||
panel2.group.id,
|
||||
undefined,
|
||||
'center'
|
||||
);
|
||||
dockview.moveGroupOrPanel({
|
||||
from: { groupId: panel2.group.id },
|
||||
to: { group: panel1.group, position: 'center' },
|
||||
});
|
||||
|
||||
expect(panel1.group.api.location.type).toBe('grid');
|
||||
expect(panel2.group.api.location.type).toBe('grid');
|
||||
@ -3560,12 +3558,10 @@ describe('dockviewComponent', () => {
|
||||
expect(dockview.groups.length).toBe(3);
|
||||
expect(dockview.panels.length).toBe(3);
|
||||
|
||||
dockview.moveGroupOrPanel(
|
||||
panel2.group,
|
||||
panel3.group.id,
|
||||
undefined,
|
||||
'center'
|
||||
);
|
||||
dockview.moveGroupOrPanel({
|
||||
from: { groupId: panel3.group.id },
|
||||
to: { group: panel2.group, position: 'center' },
|
||||
});
|
||||
|
||||
expect(panel1.group.api.location.type).toBe('grid');
|
||||
expect(panel2.group.api.location.type).toBe('floating');
|
||||
@ -3613,12 +3609,10 @@ describe('dockviewComponent', () => {
|
||||
expect(dockview.groups.length).toBe(2);
|
||||
expect(dockview.panels.length).toBe(3);
|
||||
|
||||
dockview.moveGroupOrPanel(
|
||||
panel1.group,
|
||||
panel2.group.id,
|
||||
undefined,
|
||||
'right'
|
||||
);
|
||||
dockview.moveGroupOrPanel({
|
||||
from: { groupId: panel2.group.id },
|
||||
to: { group: panel1.group, position: 'right' },
|
||||
});
|
||||
|
||||
expect(panel1.group.api.location.type).toBe('grid');
|
||||
expect(panel2.group.api.location.type).toBe('grid');
|
||||
@ -3666,12 +3660,10 @@ describe('dockviewComponent', () => {
|
||||
expect(dockview.groups.length).toBe(2);
|
||||
expect(dockview.panels.length).toBe(3);
|
||||
|
||||
dockview.moveGroupOrPanel(
|
||||
panel1.group,
|
||||
panel2.group.id,
|
||||
undefined,
|
||||
'center'
|
||||
);
|
||||
dockview.moveGroupOrPanel({
|
||||
from: { groupId: panel2.group.id },
|
||||
to: { group: panel1.group, position: 'center' },
|
||||
});
|
||||
|
||||
expect(panel1.group.api.location.type).toBe('grid');
|
||||
expect(panel2.group.api.location.type).toBe('grid');
|
||||
@ -3726,12 +3718,10 @@ describe('dockviewComponent', () => {
|
||||
expect(dockview.groups.length).toBe(3);
|
||||
expect(dockview.panels.length).toBe(4);
|
||||
|
||||
dockview.moveGroupOrPanel(
|
||||
panel4.group,
|
||||
panel2.group.id,
|
||||
undefined,
|
||||
'center'
|
||||
);
|
||||
dockview.moveGroupOrPanel({
|
||||
from: { groupId: panel2.group.id },
|
||||
to: { group: panel4.group, position: 'center' },
|
||||
});
|
||||
|
||||
expect(panel1.group.api.location.type).toBe('grid');
|
||||
expect(panel2.group.api.location.type).toBe('floating');
|
||||
@ -3773,12 +3763,10 @@ describe('dockviewComponent', () => {
|
||||
expect(dockview.groups.length).toBe(2);
|
||||
expect(dockview.panels.length).toBe(2);
|
||||
|
||||
dockview.moveGroupOrPanel(
|
||||
panel1.group,
|
||||
panel2.group.id,
|
||||
panel2.id,
|
||||
'right'
|
||||
);
|
||||
dockview.moveGroupOrPanel({
|
||||
from: { groupId: panel2.group.id, panelId: panel2.id },
|
||||
to: { group: panel1.group, position: 'right' },
|
||||
});
|
||||
|
||||
expect(panel1.group.api.location.type).toBe('grid');
|
||||
expect(panel2.group.api.location.type).toBe('grid');
|
||||
@ -3818,12 +3806,10 @@ describe('dockviewComponent', () => {
|
||||
expect(dockview.groups.length).toBe(2);
|
||||
expect(dockview.panels.length).toBe(2);
|
||||
|
||||
dockview.moveGroupOrPanel(
|
||||
panel1.group,
|
||||
panel2.group.id,
|
||||
panel2.id,
|
||||
'center'
|
||||
);
|
||||
dockview.moveGroupOrPanel({
|
||||
from: { groupId: panel2.group.id, panelId: panel2.id },
|
||||
to: { group: panel1.group, position: 'center' },
|
||||
});
|
||||
|
||||
expect(panel1.group.api.location.type).toBe('grid');
|
||||
expect(panel2.group.api.location.type).toBe('grid');
|
||||
@ -3870,12 +3856,10 @@ describe('dockviewComponent', () => {
|
||||
expect(dockview.groups.length).toBe(3);
|
||||
expect(dockview.panels.length).toBe(3);
|
||||
|
||||
dockview.moveGroupOrPanel(
|
||||
panel2.group,
|
||||
panel3.group.id,
|
||||
panel3.id,
|
||||
'center'
|
||||
);
|
||||
dockview.moveGroupOrPanel({
|
||||
from: { groupId: panel3.group.id, panelId: panel3.id },
|
||||
to: { group: panel2.group, position: 'center' },
|
||||
});
|
||||
|
||||
expect(panel1.group.api.location.type).toBe('grid');
|
||||
expect(panel2.group.api.location.type).toBe('floating');
|
||||
@ -3923,12 +3907,10 @@ describe('dockviewComponent', () => {
|
||||
expect(dockview.groups.length).toBe(2);
|
||||
expect(dockview.panels.length).toBe(3);
|
||||
|
||||
dockview.moveGroupOrPanel(
|
||||
panel1.group,
|
||||
panel2.group.id,
|
||||
panel2.id,
|
||||
'right'
|
||||
);
|
||||
dockview.moveGroupOrPanel({
|
||||
from: { groupId: panel2.group.id, panelId: panel2.id },
|
||||
to: { group: panel1.group, position: 'right' },
|
||||
});
|
||||
|
||||
expect(panel1.group.api.location.type).toBe('grid');
|
||||
expect(panel2.group.api.location.type).toBe('grid');
|
||||
@ -3976,12 +3958,10 @@ describe('dockviewComponent', () => {
|
||||
expect(dockview.groups.length).toBe(2);
|
||||
expect(dockview.panels.length).toBe(3);
|
||||
|
||||
dockview.moveGroupOrPanel(
|
||||
panel1.group,
|
||||
panel2.group.id,
|
||||
panel2.id,
|
||||
'center'
|
||||
);
|
||||
dockview.moveGroupOrPanel({
|
||||
from: { groupId: panel2.group.id, panelId: panel2.id },
|
||||
to: { group: panel1.group, position: 'center' },
|
||||
});
|
||||
|
||||
expect(panel1.group.api.location.type).toBe('grid');
|
||||
expect(panel2.group.api.location.type).toBe('grid');
|
||||
@ -4036,12 +4016,10 @@ describe('dockviewComponent', () => {
|
||||
expect(dockview.groups.length).toBe(3);
|
||||
expect(dockview.panels.length).toBe(4);
|
||||
|
||||
dockview.moveGroupOrPanel(
|
||||
panel4.group,
|
||||
panel2.group.id,
|
||||
panel2.id,
|
||||
'center'
|
||||
);
|
||||
dockview.moveGroupOrPanel({
|
||||
from: { groupId: panel2.group.id, panelId: panel2.id },
|
||||
to: { group: panel4.group, position: 'center' },
|
||||
});
|
||||
|
||||
expect(panel1.group.api.location.type).toBe('grid');
|
||||
expect(panel2.group.api.location.type).toBe('floating');
|
||||
@ -4090,12 +4068,10 @@ describe('dockviewComponent', () => {
|
||||
expect(dockview.groups.length).toBe(3);
|
||||
expect(dockview.panels.length).toBe(3);
|
||||
|
||||
dockview.moveGroupOrPanel(
|
||||
panel3.group,
|
||||
panel1.group.id,
|
||||
panel1.id,
|
||||
'center'
|
||||
);
|
||||
dockview.moveGroupOrPanel({
|
||||
from: { groupId: panel1.group.id, panelId: panel1.id },
|
||||
to: { group: panel3.group, position: 'center' },
|
||||
});
|
||||
|
||||
expect(panel1.group.api.location.type).toBe('floating');
|
||||
expect(panel2.group.api.location.type).toBe('grid');
|
||||
@ -4142,12 +4118,10 @@ describe('dockviewComponent', () => {
|
||||
expect(dockview.groups.length).toBe(2);
|
||||
expect(dockview.panels.length).toBe(3);
|
||||
|
||||
dockview.moveGroupOrPanel(
|
||||
panel3.group,
|
||||
panel1.group.id,
|
||||
panel1.id,
|
||||
'center'
|
||||
);
|
||||
dockview.moveGroupOrPanel({
|
||||
from: { groupId: panel1.group.id, panelId: panel1.id },
|
||||
to: { group: panel3.group, position: 'center' },
|
||||
});
|
||||
|
||||
expect(panel1.group.api.location.type).toBe('floating');
|
||||
expect(panel2.group.api.location.type).toBe('grid');
|
||||
@ -4195,12 +4169,10 @@ describe('dockviewComponent', () => {
|
||||
expect(dockview.groups.length).toBe(3);
|
||||
expect(dockview.panels.length).toBe(3);
|
||||
|
||||
dockview.moveGroupOrPanel(
|
||||
panel3.group,
|
||||
panel1.group.id,
|
||||
undefined,
|
||||
'center'
|
||||
);
|
||||
dockview.moveGroupOrPanel({
|
||||
from: { groupId: panel1.group.id },
|
||||
to: { group: panel3.group, position: 'center' },
|
||||
});
|
||||
|
||||
expect(panel1.group.api.location.type).toBe('floating');
|
||||
expect(panel2.group.api.location.type).toBe('grid');
|
||||
@ -4247,12 +4219,10 @@ describe('dockviewComponent', () => {
|
||||
expect(dockview.groups.length).toBe(2);
|
||||
expect(dockview.panels.length).toBe(3);
|
||||
|
||||
dockview.moveGroupOrPanel(
|
||||
panel3.group,
|
||||
panel1.group.id,
|
||||
undefined,
|
||||
'center'
|
||||
);
|
||||
dockview.moveGroupOrPanel({
|
||||
from: { groupId: panel1.group.id },
|
||||
to: { group: panel3.group, position: 'center' },
|
||||
});
|
||||
|
||||
expect(panel1.group.api.location.type).toBe('floating');
|
||||
expect(panel2.group.api.location.type).toBe('floating');
|
||||
@ -4427,6 +4397,7 @@ describe('dockviewComponent', () => {
|
||||
document: fromPartial<Document>({
|
||||
body: document.createElement('body'),
|
||||
}),
|
||||
focus: jest.fn(),
|
||||
addEventListener: jest
|
||||
.fn()
|
||||
.mockImplementation((name, cb) => {
|
||||
@ -4560,12 +4531,10 @@ describe('dockviewComponent', () => {
|
||||
expect(dockview.groups.length).toBe(3);
|
||||
expect(dockview.panels.length).toBe(3);
|
||||
|
||||
dockview.moveGroupOrPanel(
|
||||
panel3.api.group,
|
||||
panel2.api.group.id,
|
||||
panel2.api.id,
|
||||
'right'
|
||||
);
|
||||
dockview.moveGroupOrPanel({
|
||||
from: { groupId: panel2.group.id, panelId: panel2.id },
|
||||
to: { group: panel3.group, position: 'right' },
|
||||
});
|
||||
|
||||
expect(panel1.group.api.location.type).toBe('popout');
|
||||
expect(panel2.group.api.location.type).toBe('grid');
|
||||
@ -4573,12 +4542,10 @@ describe('dockviewComponent', () => {
|
||||
expect(dockview.groups.length).toBe(4);
|
||||
expect(dockview.panels.length).toBe(3);
|
||||
|
||||
dockview.moveGroupOrPanel(
|
||||
panel3.api.group,
|
||||
panel1.api.group.id,
|
||||
panel1.api.id,
|
||||
'center'
|
||||
);
|
||||
dockview.moveGroupOrPanel({
|
||||
from: { groupId: panel1.group.id, panelId: panel1.id },
|
||||
to: { group: panel3.group, position: 'center' },
|
||||
});
|
||||
|
||||
expect(panel1.group.api.location.type).toBe('grid');
|
||||
expect(panel2.group.api.location.type).toBe('grid');
|
||||
|
@ -196,7 +196,14 @@ export class TestPanel implements IDockviewPanel {
|
||||
this._params = params;
|
||||
}
|
||||
|
||||
updateParentGroup(group: DockviewGroupPanel, isGroupActive: boolean): void {
|
||||
updateParentGroup(
|
||||
group: DockviewGroupPanel,
|
||||
options: { isGroupActive: boolean }
|
||||
): void {
|
||||
//
|
||||
}
|
||||
|
||||
runEvents(): void {
|
||||
//
|
||||
}
|
||||
|
||||
@ -624,7 +631,7 @@ describe('dockviewGroupPanelModel', () => {
|
||||
renderer: 'onlyWhenVisibile',
|
||||
} as any);
|
||||
|
||||
cut.openPanel(panel3, { skipSetPanelActive: true });
|
||||
cut.openPanel(panel3, { skipRender: true });
|
||||
expect(contentContainer.length).toBe(1);
|
||||
expect(contentContainer.item(0)).toBe(panel2.view.content.element);
|
||||
|
||||
|
@ -18,8 +18,8 @@ describe('dockviewGroupPanel', () => {
|
||||
element: document.createElement('div'),
|
||||
dispose: jest.fn(),
|
||||
update: jest.fn(),
|
||||
onGroupChange: jest.fn(),
|
||||
onPanelVisibleChange: jest.fn(),
|
||||
// onGroupChange: jest.fn(),
|
||||
// onPanelVisibleChange: jest.fn(),
|
||||
};
|
||||
return partial as IContentRenderer;
|
||||
});
|
||||
@ -29,8 +29,8 @@ describe('dockviewGroupPanel', () => {
|
||||
element: document.createElement('div'),
|
||||
dispose: jest.fn(),
|
||||
update: jest.fn(),
|
||||
onGroupChange: jest.fn(),
|
||||
onPanelVisibleChange: jest.fn(),
|
||||
// onGroupChange: jest.fn(),
|
||||
// onPanelVisibleChange: jest.fn(),
|
||||
};
|
||||
return partial as IContentRenderer;
|
||||
});
|
||||
@ -82,51 +82,51 @@ describe('dockviewGroupPanel', () => {
|
||||
expect(cut.tab.update).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('that events are fired', () => {
|
||||
const cut = new DockviewPanelModel(
|
||||
<IDockviewComponent>new accessorMock(),
|
||||
'id',
|
||||
'contentComponent',
|
||||
'tabComponent'
|
||||
);
|
||||
// test('that events are fired', () => {
|
||||
// const cut = new DockviewPanelModel(
|
||||
// <IDockviewComponent>new accessorMock(),
|
||||
// 'id',
|
||||
// 'contentComponent',
|
||||
// 'tabComponent'
|
||||
// );
|
||||
|
||||
const group1 = jest.fn() as any;
|
||||
const group2 = jest.fn() as any;
|
||||
cut.updateParentGroup(group1, false);
|
||||
// const group1 = jest.fn() as any;
|
||||
// const group2 = jest.fn() as any;
|
||||
// cut.updateParentGroup(group1, false);
|
||||
|
||||
expect(cut.content.onGroupChange).toHaveBeenNthCalledWith(1, group1);
|
||||
expect(cut.tab.onGroupChange).toHaveBeenNthCalledWith(1, group1);
|
||||
expect(cut.content.onPanelVisibleChange).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
false
|
||||
);
|
||||
expect(cut.tab.onPanelVisibleChange).toHaveBeenNthCalledWith(1, false);
|
||||
expect(cut.content.onGroupChange).toHaveBeenCalledTimes(1);
|
||||
expect(cut.tab.onGroupChange).toHaveBeenCalledTimes(1);
|
||||
expect(cut.content.onPanelVisibleChange).toHaveBeenCalledTimes(1);
|
||||
expect(cut.tab.onPanelVisibleChange).toHaveBeenCalledTimes(1);
|
||||
// expect(cut.content.onGroupChange).toHaveBeenNthCalledWith(1, group1);
|
||||
// expect(cut.tab.onGroupChange).toHaveBeenNthCalledWith(1, group1);
|
||||
// expect(cut.content.onPanelVisibleChange).toHaveBeenNthCalledWith(
|
||||
// 1,
|
||||
// false
|
||||
// );
|
||||
// expect(cut.tab.onPanelVisibleChange).toHaveBeenNthCalledWith(1, false);
|
||||
// expect(cut.content.onGroupChange).toHaveBeenCalledTimes(1);
|
||||
// expect(cut.tab.onGroupChange).toHaveBeenCalledTimes(1);
|
||||
// expect(cut.content.onPanelVisibleChange).toHaveBeenCalledTimes(1);
|
||||
// expect(cut.tab.onPanelVisibleChange).toHaveBeenCalledTimes(1);
|
||||
|
||||
cut.updateParentGroup(group1, true);
|
||||
// cut.updateParentGroup(group1, true);
|
||||
|
||||
expect(cut.content.onPanelVisibleChange).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
true
|
||||
);
|
||||
expect(cut.tab.onPanelVisibleChange).toHaveBeenNthCalledWith(2, true);
|
||||
expect(cut.content.onGroupChange).toHaveBeenCalledTimes(1);
|
||||
expect(cut.tab.onGroupChange).toHaveBeenCalledTimes(1);
|
||||
expect(cut.content.onPanelVisibleChange).toHaveBeenCalledTimes(2);
|
||||
expect(cut.tab.onPanelVisibleChange).toHaveBeenCalledTimes(2);
|
||||
// expect(cut.content.onPanelVisibleChange).toHaveBeenNthCalledWith(
|
||||
// 2,
|
||||
// true
|
||||
// );
|
||||
// expect(cut.tab.onPanelVisibleChange).toHaveBeenNthCalledWith(2, true);
|
||||
// expect(cut.content.onGroupChange).toHaveBeenCalledTimes(1);
|
||||
// expect(cut.tab.onGroupChange).toHaveBeenCalledTimes(1);
|
||||
// expect(cut.content.onPanelVisibleChange).toHaveBeenCalledTimes(2);
|
||||
// expect(cut.tab.onPanelVisibleChange).toHaveBeenCalledTimes(2);
|
||||
|
||||
cut.updateParentGroup(group2, true);
|
||||
// cut.updateParentGroup(group2, true);
|
||||
|
||||
expect(cut.content.onGroupChange).toHaveBeenNthCalledWith(2, group2);
|
||||
expect(cut.tab.onGroupChange).toHaveBeenNthCalledWith(2, group2);
|
||||
expect(cut.content.onGroupChange).toHaveBeenCalledTimes(2);
|
||||
expect(cut.tab.onGroupChange).toHaveBeenCalledTimes(2);
|
||||
expect(cut.content.onPanelVisibleChange).toHaveBeenCalledTimes(2);
|
||||
expect(cut.tab.onPanelVisibleChange).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
// expect(cut.content.onGroupChange).toHaveBeenNthCalledWith(2, group2);
|
||||
// expect(cut.tab.onGroupChange).toHaveBeenNthCalledWith(2, group2);
|
||||
// expect(cut.content.onGroupChange).toHaveBeenCalledTimes(2);
|
||||
// expect(cut.tab.onGroupChange).toHaveBeenCalledTimes(2);
|
||||
// expect(cut.content.onPanelVisibleChange).toHaveBeenCalledTimes(2);
|
||||
// expect(cut.tab.onPanelVisibleChange).toHaveBeenCalledTimes(2);
|
||||
// });
|
||||
|
||||
test('that the default tab is created', () => {
|
||||
accessorMock = jest.fn<DockviewComponent, []>(() => {
|
||||
|
@ -114,17 +114,17 @@ describe('baseComponentGridview', () => {
|
||||
proportionalLayout: true,
|
||||
});
|
||||
|
||||
const events: (TestPanel | undefined)[] = [];
|
||||
const events: { type: string; panel: TestPanel | undefined }[] = [];
|
||||
|
||||
const disposable = new CompositeDisposable(
|
||||
cut.onDidAddGroup((event) => {
|
||||
events.push(event);
|
||||
cut.onDidAdd((event) => {
|
||||
events.push({ type: 'add', panel: event });
|
||||
}),
|
||||
cut.onDidRemoveGroup((event) => {
|
||||
events.push(event);
|
||||
cut.onDidRemove((event) => {
|
||||
events.push({ type: 'remove', panel: event });
|
||||
}),
|
||||
cut.onDidActiveGroupChange((event) => {
|
||||
events.push(event);
|
||||
cut.onDidActiveChange((event) => {
|
||||
events.push({ type: 'active', panel: event });
|
||||
})
|
||||
);
|
||||
|
||||
@ -141,9 +141,8 @@ describe('baseComponentGridview', () => {
|
||||
|
||||
cut.doAddGroup(panel1);
|
||||
|
||||
expect(events.length).toBe(2);
|
||||
expect(events[0]).toBe(panel1);
|
||||
expect(events[1]).toBe(panel1);
|
||||
expect(events.length).toBe(1);
|
||||
expect(events[0]).toEqual({ type: 'add', panel: panel1 });
|
||||
|
||||
const panel2 = new TestPanel(
|
||||
'id',
|
||||
@ -158,12 +157,12 @@ describe('baseComponentGridview', () => {
|
||||
|
||||
cut.doAddGroup(panel2);
|
||||
|
||||
expect(events.length).toBe(4);
|
||||
expect(events[2]).toBe(panel2);
|
||||
expect(events.length).toBe(2);
|
||||
expect(events[1]).toEqual({ type: 'add', panel: panel2 });
|
||||
|
||||
cut.doRemoveGroup(panel1);
|
||||
expect(events.length).toBe(5);
|
||||
expect(events[4]).toBe(panel1);
|
||||
expect(events.length).toBe(3);
|
||||
expect(events[2]).toEqual({ type: 'remove', panel: panel1 });
|
||||
|
||||
disposable.dispose();
|
||||
cut.dispose();
|
||||
|
@ -63,12 +63,15 @@ export class DockviewGroupPanelApiImpl extends GridviewPanelApiImpl {
|
||||
direction: positionToDirection(options.position ?? 'right'),
|
||||
});
|
||||
|
||||
this.accessor.moveGroupOrPanel(
|
||||
group,
|
||||
this._group.id,
|
||||
undefined,
|
||||
options.group ? options.position ?? 'center' : 'center'
|
||||
);
|
||||
this.accessor.moveGroupOrPanel({
|
||||
from: { groupId: this._group.id },
|
||||
to: {
|
||||
group,
|
||||
position: options.group
|
||||
? options.position ?? 'center'
|
||||
: 'center',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
maximize(): void {
|
||||
|
@ -14,7 +14,15 @@ export interface TitleEvent {
|
||||
}
|
||||
|
||||
export interface RendererChangedEvent {
|
||||
renderer: DockviewPanelRenderer;
|
||||
readonly renderer: DockviewPanelRenderer;
|
||||
}
|
||||
|
||||
export interface ActiveGroupEvent {
|
||||
readonly isActive: boolean;
|
||||
}
|
||||
|
||||
export interface GroupChangedEvent {
|
||||
// empty
|
||||
}
|
||||
|
||||
export interface DockviewPanelApi
|
||||
@ -27,8 +35,8 @@ export interface DockviewPanelApi
|
||||
readonly isGroupActive: boolean;
|
||||
readonly renderer: DockviewPanelRenderer;
|
||||
readonly title: string | undefined;
|
||||
readonly onDidActiveGroupChange: Event<void>;
|
||||
readonly onDidGroupChange: Event<void>;
|
||||
readonly onDidActiveGroupChange: Event<ActiveGroupEvent>;
|
||||
readonly onDidGroupChange: Event<GroupChangedEvent>;
|
||||
readonly onDidRendererChange: Event<RendererChangedEvent>;
|
||||
readonly location: DockviewGroupLocation;
|
||||
readonly onDidLocationChange: Event<DockviewGroupPanelFloatingChangeEvent>;
|
||||
@ -58,10 +66,10 @@ export class DockviewPanelApiImpl
|
||||
readonly _onDidTitleChange = new Emitter<TitleEvent>();
|
||||
readonly onDidTitleChange = this._onDidTitleChange.event;
|
||||
|
||||
private readonly _onDidActiveGroupChange = new Emitter<void>();
|
||||
private readonly _onDidActiveGroupChange = new Emitter<ActiveGroupEvent>();
|
||||
readonly onDidActiveGroupChange = this._onDidActiveGroupChange.event;
|
||||
|
||||
private readonly _onDidGroupChange = new Emitter<void>();
|
||||
private readonly _onDidGroupChange = new Emitter<GroupChangedEvent>();
|
||||
readonly onDidGroupChange = this._onDidGroupChange.event;
|
||||
|
||||
readonly _onDidRendererChange = new Emitter<RendererChangedEvent>();
|
||||
@ -93,23 +101,39 @@ export class DockviewPanelApiImpl
|
||||
set group(value: DockviewGroupPanel) {
|
||||
const isOldGroupActive = this.isGroupActive;
|
||||
|
||||
this._group = value;
|
||||
if (this._group !== value) {
|
||||
this._group = value;
|
||||
|
||||
this._onDidGroupChange.fire();
|
||||
this._onDidGroupChange.fire({});
|
||||
|
||||
let _trackGroupActive = isOldGroupActive; // prevent duplicate events with same state
|
||||
|
||||
if (this._group) {
|
||||
this.groupEventsDisposable.value = new CompositeDisposable(
|
||||
this.group.api.onDidLocationChange((event) => {
|
||||
if (this.group !== this.panel.group) {
|
||||
return;
|
||||
}
|
||||
this._onDidLocationChange.fire(event);
|
||||
}),
|
||||
this.group.api.onDidActiveChange(() => {
|
||||
this._onDidActiveGroupChange.fire();
|
||||
if (this.group !== this.panel.group) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_trackGroupActive !== this.isGroupActive) {
|
||||
_trackGroupActive = this.isGroupActive;
|
||||
this._onDidActiveGroupChange.fire({
|
||||
isActive: this.isGroupActive,
|
||||
});
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
if (this.isGroupActive !== isOldGroupActive) {
|
||||
this._onDidActiveGroupChange.fire();
|
||||
}
|
||||
// if (this.isGroupActive !== isOldGroupActive) {
|
||||
// this._onDidActiveGroupChange.fire({
|
||||
// isActive: this.isGroupActive,
|
||||
// });
|
||||
// }
|
||||
|
||||
this._onDidLocationChange.fire({
|
||||
location: this.group.api.location,
|
||||
@ -132,8 +156,6 @@ export class DockviewPanelApiImpl
|
||||
|
||||
this._group = group;
|
||||
|
||||
|
||||
|
||||
this.addDisposables(
|
||||
this.groupEventsDisposable,
|
||||
this._onDidRendererChange,
|
||||
@ -153,13 +175,14 @@ export class DockviewPanelApiImpl
|
||||
position?: Position;
|
||||
index?: number;
|
||||
}): void {
|
||||
this.accessor.moveGroupOrPanel(
|
||||
options.group,
|
||||
this._group.id,
|
||||
this.panel.id,
|
||||
options.position ?? 'center',
|
||||
options.index
|
||||
);
|
||||
this.accessor.moveGroupOrPanel({
|
||||
from: { groupId: this._group.id, panelId: this.panel.id },
|
||||
to: {
|
||||
group: options.group,
|
||||
position: options.position ?? 'center',
|
||||
index: options.index,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
setTitle(title: string): void {
|
||||
|
@ -390,17 +390,15 @@ export class TabsContainer
|
||||
return;
|
||||
}
|
||||
|
||||
const alreadyFocused =
|
||||
panel.id === this.group.model.activePanel?.id &&
|
||||
this.group.model.isContentFocused;
|
||||
|
||||
const isLeftClick = event.button === 0;
|
||||
|
||||
if (!isLeftClick || event.defaultPrevented) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.group.model.openPanel(panel);
|
||||
if (this.group.activePanel !== panel) {
|
||||
this.group.model.openPanel(panel);
|
||||
}
|
||||
}),
|
||||
tab.onDrop((event) => {
|
||||
this._onDrop.fire({
|
||||
|
@ -232,6 +232,23 @@ export type DockviewComponentUpdateOptions = Pick<
|
||||
| 'disableDnd'
|
||||
>;
|
||||
|
||||
type MoveGroupOptions = {
|
||||
from: { group: DockviewGroupPanel };
|
||||
to: { group: DockviewGroupPanel; position: Position };
|
||||
};
|
||||
|
||||
type MoveGroupOrPanelOptions = {
|
||||
from: {
|
||||
groupId: string;
|
||||
panelId?: string;
|
||||
};
|
||||
to: {
|
||||
group: DockviewGroupPanel;
|
||||
position: Position;
|
||||
index?: number;
|
||||
};
|
||||
};
|
||||
|
||||
export interface IDockviewComponent extends IBaseGrid<DockviewGroupPanel> {
|
||||
readonly activePanel: IDockviewPanel | undefined;
|
||||
readonly totalPanels: number;
|
||||
@ -241,13 +258,8 @@ export interface IDockviewComponent extends IBaseGrid<DockviewGroupPanel> {
|
||||
readonly onWillShowOverlay: Event<WillShowOverlayLocationEvent>;
|
||||
readonly orientation: Orientation;
|
||||
updateOptions(options: DockviewComponentUpdateOptions): void;
|
||||
moveGroupOrPanel(
|
||||
referenceGroup: DockviewGroupPanel,
|
||||
groupId: string,
|
||||
itemId: string,
|
||||
target: Position,
|
||||
index?: number
|
||||
): void;
|
||||
moveGroupOrPanel(options: MoveGroupOrPanelOptions): void;
|
||||
moveGroup(options: MoveGroupOptions): void;
|
||||
doSetGroupActive: (group: DockviewGroupPanel, skipFocus?: boolean) => void;
|
||||
removeGroup: (group: DockviewGroupPanel) => void;
|
||||
options: DockviewComponentOptions;
|
||||
@ -287,6 +299,9 @@ export interface IDockviewComponent extends IBaseGrid<DockviewGroupPanel> {
|
||||
onWillClose?: (event: { id: string; window: Window }) => void;
|
||||
}
|
||||
): Promise<void>;
|
||||
readonly onDidRemoveGroup: Event<DockviewGroupPanel>;
|
||||
readonly onDidAddGroup: Event<DockviewGroupPanel>;
|
||||
readonly onDidActiveGroupChange: Event<DockviewGroupPanel | undefined>;
|
||||
}
|
||||
|
||||
export class DockviewComponent
|
||||
@ -335,6 +350,10 @@ export class DockviewComponent
|
||||
readonly onDidActivePanelChange: Event<IDockviewPanel | undefined> =
|
||||
this._onDidActivePanelChange.event;
|
||||
|
||||
private readonly _onDidMovePanel = new Emitter<{
|
||||
panel: IDockviewPanel;
|
||||
}>();
|
||||
|
||||
private readonly _floatingGroups: DockviewFloatingGroupPanel[] = [];
|
||||
private readonly _popoutGroups: {
|
||||
window: PopoutWindow;
|
||||
@ -344,6 +363,22 @@ export class DockviewComponent
|
||||
}[] = [];
|
||||
private readonly _rootDropTarget: Droptarget;
|
||||
|
||||
private _ignoreEvents = 0;
|
||||
|
||||
private readonly _onDidRemoveGroup = new Emitter<DockviewGroupPanel>();
|
||||
readonly onDidRemoveGroup: Event<DockviewGroupPanel> =
|
||||
this._onDidRemoveGroup.event;
|
||||
|
||||
protected readonly _onDidAddGroup = new Emitter<DockviewGroupPanel>();
|
||||
readonly onDidAddGroup: Event<DockviewGroupPanel> =
|
||||
this._onDidAddGroup.event;
|
||||
|
||||
private readonly _onDidActiveGroupChange = new Emitter<
|
||||
DockviewGroupPanel | undefined
|
||||
>();
|
||||
readonly onDidActiveGroupChange: Event<DockviewGroupPanel | undefined> =
|
||||
this._onDidActiveGroupChange.event;
|
||||
|
||||
get orientation(): Orientation {
|
||||
return this.gridview.orientation;
|
||||
}
|
||||
@ -404,9 +439,28 @@ export class DockviewComponent
|
||||
this._onDidLayoutFromJSON,
|
||||
this._onDidDrop,
|
||||
this._onWillDrop,
|
||||
this._onDidMovePanel,
|
||||
this._onDidAddGroup,
|
||||
this._onDidRemoveGroup,
|
||||
this._onDidActiveGroupChange,
|
||||
this.onDidAdd((event) => {
|
||||
if (!this._moving) {
|
||||
this._onDidAddGroup.fire(event);
|
||||
}
|
||||
}),
|
||||
this.onDidRemove((event) => {
|
||||
if (!this._moving) {
|
||||
this._onDidRemoveGroup.fire(event);
|
||||
}
|
||||
}),
|
||||
this.onDidActiveChange((event) => {
|
||||
if (!this._moving) {
|
||||
this._onDidActiveGroupChange.fire(event);
|
||||
}
|
||||
}),
|
||||
Event.any(
|
||||
this.onDidAddGroup,
|
||||
this.onDidRemoveGroup
|
||||
this.onDidAdd,
|
||||
this.onDidRemove
|
||||
)(() => {
|
||||
this.updateWatermark();
|
||||
}),
|
||||
@ -515,12 +569,16 @@ export class DockviewComponent
|
||||
const data = getPanelData();
|
||||
|
||||
if (data) {
|
||||
this.moveGroupOrPanel(
|
||||
this.orthogonalize(event.position),
|
||||
data.groupId,
|
||||
data.panelId ?? undefined,
|
||||
'center'
|
||||
);
|
||||
this.moveGroupOrPanel({
|
||||
from: {
|
||||
groupId: data.groupId,
|
||||
panelId: data.panelId ?? undefined,
|
||||
},
|
||||
to: {
|
||||
group: this.orthogonalize(event.position),
|
||||
position: 'center',
|
||||
},
|
||||
});
|
||||
} else {
|
||||
this._onDidDrop.fire(
|
||||
new DockviewDidDropEvent({
|
||||
@ -574,7 +632,7 @@ export class DockviewComponent
|
||||
|
||||
panels.forEach((panel) => {
|
||||
options.to.model.openPanel(panel, {
|
||||
skipSetPanelActive: activePanel !== panel,
|
||||
skipRender: activePanel !== panel,
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -651,16 +709,27 @@ export class DockviewComponent
|
||||
this.createGroup({ id: groupId });
|
||||
group.model.renderContainer = overlayRenderContainer;
|
||||
|
||||
if (itemToPopout instanceof DockviewPanel) {
|
||||
const panel =
|
||||
referenceGroup.model.removePanel(itemToPopout);
|
||||
group.model.openPanel(panel);
|
||||
} else {
|
||||
moveGroupWithoutDestroying({
|
||||
from: referenceGroup,
|
||||
to: group,
|
||||
});
|
||||
referenceGroup.api.setHidden(true);
|
||||
if (!options?.overridePopoutGroup) {
|
||||
this._onDidAddGroup.fire(group);
|
||||
}
|
||||
|
||||
const isMoving = this._moving;
|
||||
|
||||
try {
|
||||
this._moving = true;
|
||||
if (itemToPopout instanceof DockviewPanel) {
|
||||
const panel =
|
||||
referenceGroup.model.removePanel(itemToPopout);
|
||||
group.model.openPanel(panel);
|
||||
} else {
|
||||
moveGroupWithoutDestroying({
|
||||
from: referenceGroup,
|
||||
to: group,
|
||||
});
|
||||
referenceGroup.api.setHidden(true);
|
||||
}
|
||||
} finally {
|
||||
this._moving = isMoving;
|
||||
}
|
||||
|
||||
popoutContainer.classList.add('dv-dockview');
|
||||
@ -674,6 +743,17 @@ export class DockviewComponent
|
||||
getWindow: () => _window.window!,
|
||||
};
|
||||
|
||||
popoutWindowDisposable.addDisposables(
|
||||
group.api.onDidActiveChange((event) => {
|
||||
if (event.isActive) {
|
||||
_window.window?.focus();
|
||||
}
|
||||
}),
|
||||
group.api.onWillFocus(() => {
|
||||
_window.window?.focus();
|
||||
})
|
||||
);
|
||||
|
||||
const value = {
|
||||
window: _window,
|
||||
popoutGroup: group,
|
||||
@ -697,10 +777,15 @@ export class DockviewComponent
|
||||
overlayRenderContainer,
|
||||
Disposable.from(() => {
|
||||
if (this.getPanel(referenceGroup.id)) {
|
||||
moveGroupWithoutDestroying({
|
||||
from: group,
|
||||
to: referenceGroup,
|
||||
});
|
||||
try {
|
||||
this._moving = true;
|
||||
moveGroupWithoutDestroying({
|
||||
from: group,
|
||||
to: referenceGroup,
|
||||
});
|
||||
} finally {
|
||||
this._moving = isMoving;
|
||||
}
|
||||
|
||||
if (referenceGroup.api.isHidden) {
|
||||
referenceGroup.api.setHidden(false);
|
||||
@ -718,6 +803,7 @@ export class DockviewComponent
|
||||
this.overlayRenderContainer;
|
||||
removedGroup.model.location = { type: 'grid' };
|
||||
this.doAddGroup(removedGroup, [0]);
|
||||
this.doSetGroupAndPanelActive(removedGroup);
|
||||
}
|
||||
})
|
||||
);
|
||||
@ -733,19 +819,27 @@ export class DockviewComponent
|
||||
addFloatingGroup(
|
||||
item: DockviewPanel | DockviewGroupPanel,
|
||||
coord?: { x?: number; y?: number; height?: number; width?: number },
|
||||
options?: { skipRemoveGroup?: boolean; inDragMode: boolean }
|
||||
options?: {
|
||||
skipRemoveGroup?: boolean;
|
||||
inDragMode: boolean;
|
||||
skipActiveGroup?: boolean;
|
||||
}
|
||||
): void {
|
||||
let group: DockviewGroupPanel;
|
||||
|
||||
if (item instanceof DockviewPanel) {
|
||||
group = this.createGroup();
|
||||
this._onDidAddGroup.fire(group);
|
||||
|
||||
this.removePanel(item, {
|
||||
removeEmptyGroup: true,
|
||||
skipDispose: true,
|
||||
});
|
||||
this.movingLock(() =>
|
||||
this.removePanel(item, {
|
||||
removeEmptyGroup: true,
|
||||
skipDispose: true,
|
||||
skipSetActiveGroup: true,
|
||||
})
|
||||
);
|
||||
|
||||
group.model.openPanel(item);
|
||||
group.model.openPanel(item, { skipSetGroupActive: true });
|
||||
} else {
|
||||
group = item;
|
||||
|
||||
@ -841,6 +935,11 @@ export class DockviewComponent
|
||||
);
|
||||
|
||||
this._floatingGroups.push(floatingGroupPanel);
|
||||
|
||||
if (!options?.skipActiveGroup) {
|
||||
this.doSetGroupAndPanelActive(group);
|
||||
}
|
||||
|
||||
this.updateWatermark();
|
||||
}
|
||||
|
||||
@ -952,8 +1051,8 @@ export class DockviewComponent
|
||||
}
|
||||
|
||||
setActivePanel(panel: IDockviewPanel): void {
|
||||
this.doSetGroupActive(panel.group);
|
||||
panel.group.model.openPanel(panel);
|
||||
this.doSetGroupAndPanelActive(panel.group);
|
||||
}
|
||||
|
||||
moveToNext(options: MovementOptions = {}): void {
|
||||
@ -1108,7 +1207,7 @@ export class DockviewComponent
|
||||
activeView === panel.id;
|
||||
|
||||
group.model.openPanel(panel, {
|
||||
skipSetPanelActive: !isActive,
|
||||
skipRender: !isActive,
|
||||
skipSetGroupActive: true,
|
||||
});
|
||||
}
|
||||
@ -1241,10 +1340,6 @@ export class DockviewComponent
|
||||
this.doSetGroupAndPanelActive(undefined);
|
||||
}
|
||||
|
||||
if (hasActivePanel) {
|
||||
this._onDidActivePanelChange.fire(undefined);
|
||||
}
|
||||
|
||||
this.gridview.clear();
|
||||
}
|
||||
|
||||
@ -1301,8 +1396,10 @@ export class DockviewComponent
|
||||
const group = this.orthogonalize(
|
||||
directionToPosition(<Direction>options.position.direction)
|
||||
);
|
||||
|
||||
const panel = this.createPanel(options, group);
|
||||
group.model.openPanel(panel);
|
||||
this.doSetGroupAndPanelActive(group);
|
||||
return panel;
|
||||
}
|
||||
} else {
|
||||
@ -1318,26 +1415,30 @@ export class DockviewComponent
|
||||
|
||||
if (options.floating) {
|
||||
const group = this.createGroup();
|
||||
this._onDidAddGroup.fire(group);
|
||||
|
||||
const o =
|
||||
typeof options.floating === 'object' &&
|
||||
options.floating !== null
|
||||
? options.floating
|
||||
: {};
|
||||
|
||||
this.addFloatingGroup(group, o, {
|
||||
inDragMode: false,
|
||||
skipRemoveGroup: true,
|
||||
skipActiveGroup: true,
|
||||
});
|
||||
|
||||
this._onDidAddGroup.fire(group);
|
||||
panel = this.createPanel(options, group);
|
||||
|
||||
group.model.openPanel(panel);
|
||||
this.doSetGroupAndPanelActive(group);
|
||||
} else if (
|
||||
referenceGroup.api.location.type === 'floating' ||
|
||||
target === 'center'
|
||||
) {
|
||||
panel = this.createPanel(options, referenceGroup);
|
||||
referenceGroup.model.openPanel(panel);
|
||||
this.doSetGroupAndPanelActive(referenceGroup);
|
||||
} else {
|
||||
const location = getGridLocation(referenceGroup.element);
|
||||
const relativeLocation = getRelativeLocation(
|
||||
@ -1348,30 +1449,31 @@ export class DockviewComponent
|
||||
const group = this.createGroupAtLocation(relativeLocation);
|
||||
panel = this.createPanel(options, group);
|
||||
group.model.openPanel(panel);
|
||||
this.doSetGroupAndPanelActive(group);
|
||||
}
|
||||
} else if (options.floating) {
|
||||
const group = this.createGroup();
|
||||
this._onDidAddGroup.fire(group);
|
||||
|
||||
const o =
|
||||
typeof options.floating === 'object' &&
|
||||
options.floating !== null
|
||||
? options.floating
|
||||
: {};
|
||||
|
||||
this.addFloatingGroup(group, o, {
|
||||
inDragMode: false,
|
||||
skipRemoveGroup: true,
|
||||
skipActiveGroup: true,
|
||||
});
|
||||
|
||||
this._onDidAddGroup.fire(group);
|
||||
|
||||
panel = this.createPanel(options, group);
|
||||
group.model.openPanel(panel);
|
||||
} else {
|
||||
const group = this.createGroupAtLocation();
|
||||
panel = this.createPanel(options, group);
|
||||
group.model.openPanel(panel);
|
||||
this.doSetGroupAndPanelActive(group);
|
||||
} else {
|
||||
const group = this.createGroupAtLocation();
|
||||
|
||||
panel = this.createPanel(options, group);
|
||||
|
||||
group.model.openPanel(panel);
|
||||
}
|
||||
|
||||
return panel;
|
||||
@ -1379,7 +1481,11 @@ export class DockviewComponent
|
||||
|
||||
removePanel(
|
||||
panel: IDockviewPanel,
|
||||
options: { removeEmptyGroup: boolean; skipDispose: boolean } = {
|
||||
options: {
|
||||
removeEmptyGroup: boolean;
|
||||
skipDispose: boolean;
|
||||
skipSetActiveGroup?: boolean;
|
||||
} = {
|
||||
removeEmptyGroup: true,
|
||||
skipDispose: false,
|
||||
}
|
||||
@ -1392,7 +1498,9 @@ export class DockviewComponent
|
||||
);
|
||||
}
|
||||
|
||||
group.model.removePanel(panel);
|
||||
group.model.removePanel(panel, {
|
||||
skipSetActiveGroup: options.skipSetActiveGroup,
|
||||
});
|
||||
|
||||
if (!options.skipDispose) {
|
||||
this.overlayRenderContainer.detatch(panel);
|
||||
@ -1400,7 +1508,7 @@ export class DockviewComponent
|
||||
}
|
||||
|
||||
if (group.size === 0 && options.removeEmptyGroup) {
|
||||
this.removeGroup(group);
|
||||
this.removeGroup(group, { skipActive: options.skipSetActiveGroup });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1486,6 +1594,7 @@ export class DockviewComponent
|
||||
const group = this.orthogonalize(
|
||||
directionToPosition(<Direction>options.direction)
|
||||
);
|
||||
this.doSetGroupAndPanelActive(group);
|
||||
return group;
|
||||
}
|
||||
|
||||
@ -1498,9 +1607,11 @@ export class DockviewComponent
|
||||
target
|
||||
);
|
||||
this.doAddGroup(group, relativeLocation);
|
||||
this.doSetGroupAndPanelActive(group);
|
||||
return group;
|
||||
} else {
|
||||
this.doAddGroup(group);
|
||||
this.doSetGroupAndPanelActive(group);
|
||||
return group;
|
||||
}
|
||||
}
|
||||
@ -1514,22 +1625,7 @@ export class DockviewComponent
|
||||
}
|
||||
| undefined
|
||||
): void {
|
||||
const panels = [...group.panels]; // reassign since group panels will mutate
|
||||
|
||||
for (const panel of panels) {
|
||||
this.removePanel(panel, {
|
||||
removeEmptyGroup: false,
|
||||
skipDispose: options?.skipDispose ?? false,
|
||||
});
|
||||
}
|
||||
|
||||
const activePanel = this.activePanel;
|
||||
|
||||
this.doRemoveGroup(group, options);
|
||||
|
||||
if (this.activePanel !== activePanel) {
|
||||
this._onDidActivePanelChange.fire(this.activePanel);
|
||||
}
|
||||
}
|
||||
|
||||
protected override doRemoveGroup(
|
||||
@ -1542,6 +1638,19 @@ export class DockviewComponent
|
||||
}
|
||||
| undefined
|
||||
): DockviewGroupPanel {
|
||||
const panels = [...group.panels]; // reassign since group panels will mutate
|
||||
|
||||
if (!options?.skipDispose) {
|
||||
for (const panel of panels) {
|
||||
this.removePanel(panel, {
|
||||
removeEmptyGroup: false,
|
||||
skipDispose: options?.skipDispose ?? false,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const activePanel = this.activePanel;
|
||||
|
||||
if (group.api.location.type === 'floating') {
|
||||
const floatingGroup = this._floatingGroups.find(
|
||||
(_) => _.group === group
|
||||
@ -1560,7 +1669,7 @@ export class DockviewComponent
|
||||
if (!options?.skipActive && this._activeGroup === group) {
|
||||
const groups = Array.from(this._groups.values());
|
||||
|
||||
this.doSetGroupActive(
|
||||
this.doSetGroupAndPanelActive(
|
||||
groups.length > 0 ? groups[0].value : undefined
|
||||
);
|
||||
}
|
||||
@ -1597,7 +1706,7 @@ export class DockviewComponent
|
||||
if (!options?.skipActive && this._activeGroup === group) {
|
||||
const groups = Array.from(this._groups.values());
|
||||
|
||||
this.doSetGroupActive(
|
||||
this.doSetGroupAndPanelActive(
|
||||
groups.length > 0 ? groups[0].value : undefined
|
||||
);
|
||||
}
|
||||
@ -1609,48 +1718,100 @@ export class DockviewComponent
|
||||
throw new Error('failed to find popout group');
|
||||
}
|
||||
|
||||
return super.doRemoveGroup(group, options);
|
||||
const re = super.doRemoveGroup(group, options);
|
||||
|
||||
if (!options?.skipActive) {
|
||||
if (this.activePanel !== activePanel) {
|
||||
this._onDidActivePanelChange.fire(this.activePanel);
|
||||
}
|
||||
}
|
||||
|
||||
return re;
|
||||
}
|
||||
|
||||
moveGroupOrPanel(
|
||||
destinationGroup: DockviewGroupPanel,
|
||||
sourceGroupId: string,
|
||||
sourceItemId: string | undefined,
|
||||
destinationTarget: Position,
|
||||
destinationIndex?: number
|
||||
): void {
|
||||
private _moving = false;
|
||||
|
||||
movingLock<T>(func: () => T): T {
|
||||
const isMoving = this._moving;
|
||||
|
||||
try {
|
||||
this._moving = true;
|
||||
return func();
|
||||
} finally {
|
||||
this._moving = isMoving;
|
||||
}
|
||||
}
|
||||
|
||||
moveGroupOrPanel(options: MoveGroupOrPanelOptions): void {
|
||||
const destinationGroup = options.to.group;
|
||||
const sourceGroupId = options.from.groupId;
|
||||
const sourceItemId = options.from.panelId;
|
||||
const destinationTarget = options.to.position;
|
||||
const destinationIndex = options.to.index;
|
||||
|
||||
const sourceGroup = sourceGroupId
|
||||
? this._groups.get(sourceGroupId)?.value
|
||||
: undefined;
|
||||
|
||||
if (!sourceGroup) {
|
||||
throw new Error(`Failed to find group id ${sourceGroupId}`);
|
||||
}
|
||||
|
||||
if (sourceItemId === undefined) {
|
||||
if (sourceGroup) {
|
||||
this.moveGroup(
|
||||
sourceGroup,
|
||||
destinationGroup,
|
||||
destinationTarget
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Moving an entire group into another group
|
||||
*/
|
||||
|
||||
this.moveGroup({
|
||||
from: { group: sourceGroup },
|
||||
to: {
|
||||
group: destinationGroup,
|
||||
position: destinationTarget,
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (!destinationTarget || destinationTarget === 'center') {
|
||||
const groupItem: IDockviewPanel | undefined =
|
||||
sourceGroup?.model.removePanel(sourceItemId) ??
|
||||
this.panels.find((panel) => panel.id === sourceItemId);
|
||||
/**
|
||||
* Dropping a panel within another group
|
||||
*/
|
||||
|
||||
if (!groupItem) {
|
||||
const removedPanel: IDockviewPanel | undefined = this.movingLock(
|
||||
() =>
|
||||
sourceGroup.model.removePanel(sourceItemId, {
|
||||
skipEvents: true,
|
||||
skipActive: true,
|
||||
skipSetActiveGroup: true,
|
||||
})
|
||||
);
|
||||
|
||||
if (!removedPanel) {
|
||||
throw new Error(`No panel with id ${sourceItemId}`);
|
||||
}
|
||||
|
||||
if (sourceGroup?.model.size === 0) {
|
||||
this.doRemoveGroup(sourceGroup);
|
||||
if (sourceGroup.model.size === 0) {
|
||||
// remove the group and do not set a new group as active
|
||||
this.doRemoveGroup(sourceGroup, { skipActive: true });
|
||||
}
|
||||
|
||||
destinationGroup.model.openPanel(groupItem, {
|
||||
index: destinationIndex,
|
||||
this.movingLock(() =>
|
||||
destinationGroup.model.openPanel(removedPanel, {
|
||||
index: destinationIndex,
|
||||
skipSetGroupActive: true,
|
||||
})
|
||||
);
|
||||
this.doSetGroupAndPanelActive(destinationGroup);
|
||||
|
||||
this._onDidMovePanel.fire({
|
||||
panel: removedPanel,
|
||||
});
|
||||
} else {
|
||||
/**
|
||||
* Dropping a panel to the extremities of a group which will place that panel
|
||||
* into an adjacent group
|
||||
*/
|
||||
|
||||
const referenceLocation = getGridLocation(destinationGroup.element);
|
||||
const targetLocation = getRelativeLocation(
|
||||
this.gridview.orientation,
|
||||
@ -1658,7 +1819,12 @@ export class DockviewComponent
|
||||
destinationTarget
|
||||
);
|
||||
|
||||
if (sourceGroup && sourceGroup.size < 2) {
|
||||
if (sourceGroup.size < 2) {
|
||||
/**
|
||||
* If we are moving from a group which only has one panel left we will consider
|
||||
* moving the group itself rather than moving the panel into a newly created group
|
||||
*/
|
||||
|
||||
const [targetParentLocation, to] = tail(targetLocation);
|
||||
|
||||
if (sourceGroup.api.location.type === 'grid') {
|
||||
@ -1675,31 +1841,45 @@ export class DockviewComponent
|
||||
// if a group has one tab - we are essentially moving the 'group'
|
||||
// which is equivalent to swapping two views in this case
|
||||
this.gridview.moveView(sourceParentLocation, from, to);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// source group will become empty so delete the group
|
||||
const targetGroup = this.doRemoveGroup(sourceGroup, {
|
||||
skipActive: true,
|
||||
skipDispose: true,
|
||||
});
|
||||
const targetGroup = this.movingLock(() =>
|
||||
this.doRemoveGroup(sourceGroup, {
|
||||
skipActive: true,
|
||||
skipDispose: true,
|
||||
})
|
||||
);
|
||||
|
||||
// after deleting the group we need to re-evaulate the ref location
|
||||
const updatedReferenceLocation = getGridLocation(
|
||||
destinationGroup.element
|
||||
);
|
||||
|
||||
const location = getRelativeLocation(
|
||||
this.gridview.orientation,
|
||||
updatedReferenceLocation,
|
||||
destinationTarget
|
||||
);
|
||||
this.doAddGroup(targetGroup, location);
|
||||
this.movingLock(() => this.doAddGroup(targetGroup, location));
|
||||
this.doSetGroupAndPanelActive(targetGroup);
|
||||
} else {
|
||||
const groupItem: IDockviewPanel | undefined =
|
||||
sourceGroup?.model.removePanel(sourceItemId) ??
|
||||
this.panels.find((panel) => panel.id === sourceItemId);
|
||||
/**
|
||||
* The group we are removing from has many panels, we need to remove the panels we are moving,
|
||||
* create a new group, add the panels to that new group and add the new group in an appropiate position
|
||||
*/
|
||||
const removedPanel: IDockviewPanel | undefined =
|
||||
this.movingLock(() =>
|
||||
sourceGroup.model.removePanel(sourceItemId, {
|
||||
skipEvents: true,
|
||||
skipActive: true,
|
||||
skipSetActiveGroup: true,
|
||||
})
|
||||
);
|
||||
|
||||
if (!groupItem) {
|
||||
if (!removedPanel) {
|
||||
throw new Error(`No panel with id ${sourceItemId}`);
|
||||
}
|
||||
|
||||
@ -1710,86 +1890,121 @@ export class DockviewComponent
|
||||
);
|
||||
|
||||
const group = this.createGroupAtLocation(dropLocation);
|
||||
group.model.openPanel(groupItem);
|
||||
this.movingLock(() =>
|
||||
group.model.openPanel(removedPanel, {
|
||||
skipEvents: true,
|
||||
skipSetGroupActive: true,
|
||||
})
|
||||
);
|
||||
this.doSetGroupAndPanelActive(group);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private moveGroup(
|
||||
sourceGroup: DockviewGroupPanel,
|
||||
referenceGroup: DockviewGroupPanel,
|
||||
target: Position
|
||||
): void {
|
||||
if (sourceGroup) {
|
||||
if (!target || target === 'center') {
|
||||
const activePanel = sourceGroup.activePanel;
|
||||
const panels = [...sourceGroup.panels].map((p) =>
|
||||
sourceGroup.model.removePanel(p.id)
|
||||
);
|
||||
moveGroup(options: MoveGroupOptions): void {
|
||||
const from = options.from.group;
|
||||
const to = options.to.group;
|
||||
const target = options.to.position;
|
||||
|
||||
if (sourceGroup?.model.size === 0) {
|
||||
this.doRemoveGroup(sourceGroup);
|
||||
}
|
||||
if (target === 'center') {
|
||||
const activePanel = from.activePanel;
|
||||
|
||||
const panels = this.movingLock(() =>
|
||||
[...from.panels].map((p) =>
|
||||
from.model.removePanel(p.id, {
|
||||
skipRender: true,
|
||||
skipEvents: true,
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
if (from?.model.size === 0) {
|
||||
this.doRemoveGroup(from, { skipActive: true });
|
||||
}
|
||||
|
||||
this.movingLock(() => {
|
||||
for (const panel of panels) {
|
||||
referenceGroup.model.openPanel(panel, {
|
||||
skipSetPanelActive: panel !== activePanel,
|
||||
to.model.openPanel(panel, {
|
||||
skipRender: panel !== activePanel,
|
||||
skipSetGroupActive: panel !== activePanel,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
switch (sourceGroup.api.location.type) {
|
||||
case 'grid':
|
||||
this.gridview.removeView(
|
||||
getGridLocation(sourceGroup.element)
|
||||
);
|
||||
break;
|
||||
case 'floating': {
|
||||
const selectedFloatingGroup = this._floatingGroups.find(
|
||||
(x) => x.group === sourceGroup
|
||||
);
|
||||
if (!selectedFloatingGroup) {
|
||||
throw new Error('failed to find floating group');
|
||||
}
|
||||
selectedFloatingGroup.dispose();
|
||||
break;
|
||||
}
|
||||
case 'popout': {
|
||||
const selectedPopoutGroup = this._popoutGroups.find(
|
||||
(x) => x.popoutGroup === sourceGroup
|
||||
);
|
||||
if (!selectedPopoutGroup) {
|
||||
throw new Error('failed to find popout group');
|
||||
}
|
||||
selectedPopoutGroup.disposable.dispose();
|
||||
});
|
||||
|
||||
panels.forEach((panel) => {
|
||||
this._onDidMovePanel.fire({ panel });
|
||||
});
|
||||
} else {
|
||||
switch (from.api.location.type) {
|
||||
case 'grid':
|
||||
this.gridview.removeView(getGridLocation(from.element));
|
||||
break;
|
||||
case 'floating': {
|
||||
const selectedFloatingGroup = this._floatingGroups.find(
|
||||
(x) => x.group === from
|
||||
);
|
||||
if (!selectedFloatingGroup) {
|
||||
throw new Error('failed to find floating group');
|
||||
}
|
||||
selectedFloatingGroup.dispose();
|
||||
break;
|
||||
}
|
||||
case 'popout': {
|
||||
const selectedPopoutGroup = this._popoutGroups.find(
|
||||
(x) => x.popoutGroup === from
|
||||
);
|
||||
if (!selectedPopoutGroup) {
|
||||
throw new Error('failed to find popout group');
|
||||
}
|
||||
selectedPopoutGroup.disposable.dispose();
|
||||
}
|
||||
|
||||
const referenceLocation = getGridLocation(
|
||||
referenceGroup.element
|
||||
);
|
||||
const dropLocation = getRelativeLocation(
|
||||
this.gridview.orientation,
|
||||
referenceLocation,
|
||||
target
|
||||
);
|
||||
|
||||
this.gridview.addView(
|
||||
sourceGroup,
|
||||
Sizing.Distribute,
|
||||
dropLocation
|
||||
);
|
||||
}
|
||||
|
||||
const referenceLocation = getGridLocation(to.element);
|
||||
const dropLocation = getRelativeLocation(
|
||||
this.gridview.orientation,
|
||||
referenceLocation,
|
||||
target
|
||||
);
|
||||
|
||||
this.gridview.addView(from, Sizing.Distribute, dropLocation);
|
||||
|
||||
from.panels.forEach((panel) => {
|
||||
this._onDidMovePanel.fire({ panel });
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
doSetGroupAndPanelActive(
|
||||
group: DockviewGroupPanel | undefined,
|
||||
): void {
|
||||
const activePanel = this.activePanel;
|
||||
override doSetGroupActive(group: DockviewGroupPanel | undefined): void {
|
||||
super.doSetGroupActive(group);
|
||||
|
||||
if (this._activeGroup?.activePanel !== activePanel) {
|
||||
this._onDidActivePanelChange.fire(this._activeGroup?.activePanel);
|
||||
const activePanel = this.activePanel;
|
||||
|
||||
if (
|
||||
!this._moving &&
|
||||
activePanel !== this._onDidActivePanelChange.value
|
||||
) {
|
||||
this._onDidActivePanelChange.fire(activePanel);
|
||||
}
|
||||
}
|
||||
|
||||
doSetGroupAndPanelActive(group: DockviewGroupPanel | undefined): void {
|
||||
// if (
|
||||
// this.activeGroup === group &&
|
||||
// this._onDidActiveGroupChange.value !== group
|
||||
// ) {
|
||||
// this._onDidActiveGroupChange.fire(group);
|
||||
// }
|
||||
|
||||
super.doSetGroupActive(group);
|
||||
|
||||
const activePanel = this.activePanel;
|
||||
|
||||
if (
|
||||
!this._moving &&
|
||||
activePanel !== this._onDidActivePanelChange.value
|
||||
) {
|
||||
this._onDidActivePanelChange.fire(activePanel);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1836,7 +2051,14 @@ export class DockviewComponent
|
||||
}),
|
||||
view.model.onMove((event) => {
|
||||
const { groupId, itemId, target, index } = event;
|
||||
this.moveGroupOrPanel(view, groupId, itemId, target, index);
|
||||
this.moveGroupOrPanel({
|
||||
from: { groupId: groupId, panelId: itemId },
|
||||
to: {
|
||||
group: view,
|
||||
position: target,
|
||||
index,
|
||||
},
|
||||
});
|
||||
}),
|
||||
view.model.onDidDrop((event) => {
|
||||
this._onDidDrop.fire(event);
|
||||
@ -1853,13 +2075,27 @@ export class DockviewComponent
|
||||
this._onWillShowOverlay.fire(event);
|
||||
}),
|
||||
view.model.onDidAddPanel((event) => {
|
||||
if (this._moving) {
|
||||
return;
|
||||
}
|
||||
this._onDidAddPanel.fire(event.panel);
|
||||
}),
|
||||
view.model.onDidRemovePanel((event) => {
|
||||
if (this._moving) {
|
||||
return;
|
||||
}
|
||||
this._onDidRemovePanel.fire(event.panel);
|
||||
}),
|
||||
view.model.onDidActivePanelChange((event) => {
|
||||
this._onDidActivePanelChange.fire(event.panel);
|
||||
if (this._moving) {
|
||||
return;
|
||||
}
|
||||
if (event.panel !== this.activePanel) {
|
||||
return;
|
||||
}
|
||||
if (this._onDidActivePanelChange.value !== event.panel) {
|
||||
this._onDidActivePanelChange.fire(event.panel);
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
|
@ -88,6 +88,13 @@ export class DockviewGroupPanel
|
||||
);
|
||||
}
|
||||
|
||||
override focus(): void {
|
||||
if (!this.api.isActive) {
|
||||
this.api.setActive();
|
||||
}
|
||||
super.focus();
|
||||
}
|
||||
|
||||
initialize(): void {
|
||||
this._model.initialize();
|
||||
}
|
||||
|
@ -460,7 +460,7 @@ export class DockviewGroupPanelModel
|
||||
|
||||
// must be run after the constructor otherwise this.parent may not be
|
||||
// correctly initialized
|
||||
this.setActive(this.isActive, true, true);
|
||||
this.setActive(this.isActive, true);
|
||||
this.updateContainer();
|
||||
|
||||
if (this.accessor.options.createRightHeaderActionsElement) {
|
||||
@ -604,17 +604,25 @@ export class DockviewGroupPanelModel
|
||||
}
|
||||
|
||||
focus(): void {
|
||||
this._activePanel?.focus?.();
|
||||
this._activePanel?.focus();
|
||||
}
|
||||
|
||||
public openPanel(
|
||||
panel: IDockviewPanel,
|
||||
options: {
|
||||
index?: number;
|
||||
skipSetPanelActive?: boolean;
|
||||
skipRender?: boolean;
|
||||
skipEvents?: boolean;
|
||||
skipSetGroupActive?: boolean;
|
||||
} = {}
|
||||
): void {
|
||||
/**
|
||||
* set the panel group
|
||||
* add the panel
|
||||
* check if group active
|
||||
* check if panel active
|
||||
*/
|
||||
|
||||
if (
|
||||
typeof options.index !== 'number' ||
|
||||
options.index > this.panels.length
|
||||
@ -622,34 +630,47 @@ export class DockviewGroupPanelModel
|
||||
options.index = this.panels.length;
|
||||
}
|
||||
|
||||
const skipSetPanelActive = !!options.skipSetPanelActive;
|
||||
const skipSetGroupActive = !!options.skipSetGroupActive;
|
||||
const skipRender = !!options.skipRender;
|
||||
|
||||
// ensure the group is updated before we fire any events
|
||||
panel.updateParentGroup(this.groupPanel, true);
|
||||
panel.updateParentGroup(this.groupPanel, { isGroupActive: true });
|
||||
|
||||
this.doAddPanel(panel, options.index, {
|
||||
skipRender,
|
||||
});
|
||||
|
||||
if (this._activePanel === panel) {
|
||||
if (!skipSetGroupActive) {
|
||||
this.accessor.doSetGroupActive(this.groupPanel);
|
||||
}
|
||||
this.contentContainer.renderPanel(panel, { asActive: true });
|
||||
return;
|
||||
}
|
||||
|
||||
this.doAddPanel(panel, options.index, skipSetPanelActive);
|
||||
|
||||
if (!skipSetPanelActive) {
|
||||
if (!skipRender) {
|
||||
this.doSetActivePanel(panel);
|
||||
}
|
||||
|
||||
if (!skipSetGroupActive) {
|
||||
if (!options.skipSetGroupActive) {
|
||||
this.accessor.doSetGroupActive(this.groupPanel);
|
||||
}
|
||||
|
||||
this.updateContainer();
|
||||
if (!options.skipEvents) {
|
||||
panel.runEvents();
|
||||
this.updateContainer();
|
||||
}
|
||||
}
|
||||
|
||||
public removePanel(groupItemOrId: IDockviewPanel | string): IDockviewPanel {
|
||||
public removePanel(
|
||||
groupItemOrId: IDockviewPanel | string,
|
||||
options: {
|
||||
skipRender?: boolean;
|
||||
skipEvents?: boolean;
|
||||
skipActive?: boolean;
|
||||
skipSetActiveGroup?: boolean;
|
||||
} = {
|
||||
skipRender: false,
|
||||
skipEvents: false,
|
||||
skipActive: false,
|
||||
}
|
||||
): IDockviewPanel {
|
||||
const id =
|
||||
typeof groupItemOrId === 'string'
|
||||
? groupItemOrId
|
||||
@ -661,7 +682,7 @@ export class DockviewGroupPanelModel
|
||||
throw new Error('invalid operation');
|
||||
}
|
||||
|
||||
return this._removePanel(panelToRemove);
|
||||
return this._removePanel(panelToRemove, options);
|
||||
}
|
||||
|
||||
public closeAllPanels(): void {
|
||||
@ -692,15 +713,8 @@ export class DockviewGroupPanelModel
|
||||
this.tabsContainer.setRightActionsElement(element);
|
||||
}
|
||||
|
||||
public setActive(
|
||||
isGroupActive: boolean,
|
||||
skipFocus = false,
|
||||
force = false
|
||||
): void {
|
||||
public setActive(isGroupActive: boolean, force = false): void {
|
||||
if (!force && this.isActive === isGroupActive) {
|
||||
if (!skipFocus) {
|
||||
this._activePanel?.focus?.();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -716,12 +730,6 @@ export class DockviewGroupPanelModel
|
||||
}
|
||||
|
||||
this.updateContainer();
|
||||
|
||||
if (isGroupActive) {
|
||||
if (!skipFocus) {
|
||||
this._activePanel?.focus?.();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public layout(width: number, height: number): void {
|
||||
@ -735,21 +743,35 @@ export class DockviewGroupPanelModel
|
||||
}
|
||||
}
|
||||
|
||||
private _removePanel(panel: IDockviewPanel): IDockviewPanel {
|
||||
private _removePanel(
|
||||
panel: IDockviewPanel,
|
||||
options: {
|
||||
skipRender?: boolean;
|
||||
skipEvents?: boolean;
|
||||
skipSetActiveGroup?: boolean;
|
||||
}
|
||||
): IDockviewPanel {
|
||||
const isActivePanel = this._activePanel === panel;
|
||||
|
||||
this.doRemovePanel(panel);
|
||||
|
||||
if (isActivePanel && this.panels.length > 0) {
|
||||
const nextPanel = this.mostRecentlyUsed[0];
|
||||
this.openPanel(nextPanel);
|
||||
this.openPanel(nextPanel, {
|
||||
skipRender: options.skipRender,
|
||||
skipEvents: options.skipEvents,
|
||||
skipSetGroupActive: options.skipSetActiveGroup,
|
||||
});
|
||||
}
|
||||
|
||||
if (this._activePanel && this.panels.length === 0) {
|
||||
this.doSetActivePanel(undefined);
|
||||
}
|
||||
|
||||
this.updateContainer();
|
||||
if (!options.skipEvents) {
|
||||
this.updateContainer();
|
||||
}
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
||||
@ -776,7 +798,9 @@ export class DockviewGroupPanelModel
|
||||
private doAddPanel(
|
||||
panel: IDockviewPanel,
|
||||
index: number = this.panels.length,
|
||||
skipSetActive = false
|
||||
options: {
|
||||
skipRender: boolean;
|
||||
} = { skipRender: false }
|
||||
): void {
|
||||
const existingPanel = this._panels.indexOf(panel);
|
||||
const hasExistingPanel = existingPanel > -1;
|
||||
@ -786,7 +810,7 @@ export class DockviewGroupPanelModel
|
||||
|
||||
this.tabsContainer.openPanel(panel, index);
|
||||
|
||||
if (!skipSetActive) {
|
||||
if (!options.skipRender) {
|
||||
this.contentContainer.openPanel(panel);
|
||||
}
|
||||
|
||||
@ -802,6 +826,10 @@ export class DockviewGroupPanelModel
|
||||
}
|
||||
|
||||
private doSetActivePanel(panel: IDockviewPanel | undefined): void {
|
||||
if (this._activePanel === panel) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._activePanel = panel;
|
||||
|
||||
if (panel) {
|
||||
@ -811,7 +839,9 @@ export class DockviewGroupPanelModel
|
||||
|
||||
this.updateMru(panel);
|
||||
|
||||
this._onDidActivePanelChange.fire({ panel });
|
||||
this._onDidActivePanelChange.fire({
|
||||
panel,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -829,7 +859,10 @@ export class DockviewGroupPanelModel
|
||||
toggleClass(this.container, 'empty', this.isEmpty);
|
||||
|
||||
this.panels.forEach((panel) =>
|
||||
panel.updateParentGroup(this.groupPanel, this.isActive)
|
||||
// panel.updateParentGroup(this.groupPanel, {
|
||||
// isGroupActive: this.isActive,
|
||||
// })
|
||||
panel.runEvents()
|
||||
);
|
||||
|
||||
if (this.isEmpty && !this.watermark) {
|
||||
|
@ -18,11 +18,15 @@ export interface IDockviewPanel extends IDisposable, IPanel {
|
||||
readonly api: DockviewPanelApi;
|
||||
readonly title: string | undefined;
|
||||
readonly params: Parameters | undefined;
|
||||
updateParentGroup(group: DockviewGroupPanel, isGroupActive: boolean): void;
|
||||
updateParentGroup(
|
||||
group: DockviewGroupPanel,
|
||||
options: { isGroupActive: boolean }
|
||||
): void;
|
||||
init(params: IGroupPanelInitParameters): void;
|
||||
toJSON(): GroupviewPanelState;
|
||||
setTitle(title: string): void;
|
||||
update(event: PanelUpdateEvent): void;
|
||||
runEvents(): void;
|
||||
}
|
||||
|
||||
export class DockviewPanel
|
||||
@ -94,16 +98,6 @@ export class DockviewPanel
|
||||
}
|
||||
|
||||
focus(): void {
|
||||
/**
|
||||
* This is a progmatic request of focus -
|
||||
* We need to tell the active panel that it can choose it's focus
|
||||
* If the panel doesn't choose the panels container for it
|
||||
*/
|
||||
|
||||
if (!this.api.isActive) {
|
||||
this.api.setActive();
|
||||
}
|
||||
|
||||
const event = new WillFocusEvent();
|
||||
this.api._onWillFocus.fire(event);
|
||||
|
||||
@ -111,7 +105,9 @@ export class DockviewPanel
|
||||
return;
|
||||
}
|
||||
|
||||
this.group.model.focusContent();
|
||||
if (!this.api.isActive) {
|
||||
this.api.setActive();
|
||||
}
|
||||
}
|
||||
|
||||
public toJSON(): GroupviewPanelState {
|
||||
@ -183,24 +179,49 @@ export class DockviewPanel
|
||||
|
||||
public updateParentGroup(
|
||||
group: DockviewGroupPanel,
|
||||
isGroupActive: boolean
|
||||
options: { isGroupActive: boolean }
|
||||
): void {
|
||||
this._group = group;
|
||||
this.api.group = group;
|
||||
|
||||
// const isPanelVisible = this._group.model.isPanelActive(this);
|
||||
|
||||
// const isActive = options.isGroupActive && isPanelVisible;
|
||||
|
||||
// if (this.api.isActive !== isActive) {
|
||||
// this.api._onDidActiveChange.fire({
|
||||
// isActive: options.isGroupActive && isPanelVisible,
|
||||
// });
|
||||
// }
|
||||
|
||||
// if (this.api.isVisible !== isPanelVisible) {
|
||||
// this.api._onDidVisibilityChange.fire({
|
||||
// isVisible: isPanelVisible,
|
||||
// });
|
||||
// }
|
||||
|
||||
// this.view.updateParentGroup(
|
||||
// this._group,
|
||||
// this._group.model.isPanelActive(this)
|
||||
// );
|
||||
}
|
||||
|
||||
runEvents(): void {
|
||||
this.api.group = this._group;
|
||||
const isPanelVisible = this._group.model.isPanelActive(this);
|
||||
|
||||
this.api._onDidActiveChange.fire({
|
||||
isActive: isGroupActive && isPanelVisible,
|
||||
});
|
||||
this.api._onDidVisibilityChange.fire({
|
||||
isVisible: isPanelVisible,
|
||||
});
|
||||
const isActive = this.group.api.isActive && isPanelVisible;
|
||||
|
||||
this.view.updateParentGroup(
|
||||
this._group,
|
||||
this._group.model.isPanelActive(this)
|
||||
);
|
||||
if (this.api.isActive !== isActive) {
|
||||
this.api._onDidActiveChange.fire({
|
||||
isActive: this.group.api.isActive && isPanelVisible,
|
||||
});
|
||||
}
|
||||
|
||||
if (this.api.isVisible !== isPanelVisible) {
|
||||
this.api._onDidVisibilityChange.fire({
|
||||
isVisible: isPanelVisible,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public layout(width: number, height: number): void {
|
||||
|
@ -25,9 +25,6 @@ export class DockviewPanelModel implements IDockviewPanelModel {
|
||||
private readonly _content: IContentRenderer;
|
||||
private readonly _tab: ITabRenderer;
|
||||
|
||||
private _group: DockviewGroupPanel | null = null;
|
||||
private _isPanelVisible: boolean | null = null;
|
||||
|
||||
get content(): IContentRenderer {
|
||||
return this._content;
|
||||
}
|
||||
@ -52,28 +49,10 @@ export class DockviewPanelModel implements IDockviewPanelModel {
|
||||
}
|
||||
|
||||
updateParentGroup(
|
||||
group: DockviewGroupPanel,
|
||||
isPanelVisible: boolean
|
||||
_group: DockviewGroupPanel,
|
||||
_isPanelVisible: boolean
|
||||
): void {
|
||||
if (group !== this._group) {
|
||||
this._group = group;
|
||||
if (this._content.onGroupChange) {
|
||||
this._content.onGroupChange(group);
|
||||
}
|
||||
if (this._tab.onGroupChange) {
|
||||
this._tab.onGroupChange(group);
|
||||
}
|
||||
}
|
||||
|
||||
if (isPanelVisible !== this._isPanelVisible) {
|
||||
this._isPanelVisible = isPanelVisible;
|
||||
if (this._content.onPanelVisibleChange) {
|
||||
this._content.onPanelVisibleChange(isPanelVisible);
|
||||
}
|
||||
if (this._tab.onPanelVisibleChange) {
|
||||
this._tab.onPanelVisibleChange(isPanelVisible);
|
||||
}
|
||||
}
|
||||
// noop
|
||||
}
|
||||
|
||||
layout(width: number, height: number): void {
|
||||
|
@ -47,8 +47,6 @@ export interface ITabRenderer
|
||||
> {
|
||||
readonly element: HTMLElement;
|
||||
init(parameters: GroupPanelPartInitParameters): void;
|
||||
onGroupChange?(group: DockviewGroupPanel): void;
|
||||
onPanelVisibleChange?(isPanelVisible: boolean): void;
|
||||
}
|
||||
|
||||
export interface IContentRenderer
|
||||
@ -60,8 +58,6 @@ export interface IContentRenderer
|
||||
readonly onDidFocus?: Event<void>;
|
||||
readonly onDidBlur?: Event<void>;
|
||||
init(parameters: GroupPanelContentPartInitParameters): void;
|
||||
onGroupChange?(group: DockviewGroupPanel): void;
|
||||
onPanelVisibleChange?(isPanelVisible: boolean): void;
|
||||
}
|
||||
|
||||
// watermark component
|
||||
|
@ -93,6 +93,10 @@ export class Emitter<T> implements IDisposable {
|
||||
Emitter.ENABLE_TRACKING = isEnabled;
|
||||
}
|
||||
|
||||
get value(): T | undefined {
|
||||
return this._last;
|
||||
}
|
||||
|
||||
constructor(private readonly options?: EmitterOptions) {}
|
||||
|
||||
get event(): Event<T> {
|
||||
|
@ -54,10 +54,6 @@ export interface IBaseGrid<T extends IGridPanelView> {
|
||||
readonly activeGroup: T | undefined;
|
||||
readonly size: number;
|
||||
readonly groups: T[];
|
||||
readonly onDidLayoutChange: Event<void>;
|
||||
readonly onDidRemoveGroup: Event<T>;
|
||||
readonly onDidAddGroup: Event<T>;
|
||||
readonly onDidActiveGroupChange: Event<T | undefined>;
|
||||
getPanel(id: string): T | undefined;
|
||||
toJSON(): object;
|
||||
fromJSON(data: any): void;
|
||||
@ -70,6 +66,7 @@ export interface IBaseGrid<T extends IGridPanelView> {
|
||||
exitMaximizedGroup(): void;
|
||||
hasMaximizedGroup(): boolean;
|
||||
readonly onDidMaxmizedGroupChange: Event<void>;
|
||||
readonly onDidLayoutChange: Event<void>;
|
||||
}
|
||||
|
||||
export abstract class BaseGrid<T extends IGridPanelView>
|
||||
@ -85,15 +82,15 @@ export abstract class BaseGrid<T extends IGridPanelView>
|
||||
private _onDidLayoutChange = new Emitter<void>();
|
||||
readonly onDidLayoutChange = this._onDidLayoutChange.event;
|
||||
|
||||
protected readonly _onDidRemoveGroup = new Emitter<T>();
|
||||
readonly onDidRemoveGroup: Event<T> = this._onDidRemoveGroup.event;
|
||||
private readonly _onDidRemove = new Emitter<T>();
|
||||
readonly onDidRemove: Event<T> = this._onDidRemove.event;
|
||||
|
||||
protected readonly _onDidAddGroup = new Emitter<T>();
|
||||
readonly onDidAddGroup: Event<T> = this._onDidAddGroup.event;
|
||||
private readonly _onDidAdd = new Emitter<T>();
|
||||
readonly onDidAdd: Event<T> = this._onDidAdd.event;
|
||||
|
||||
private readonly _onDidActiveGroupChange = new Emitter<T | undefined>();
|
||||
readonly onDidActiveGroupChange: Event<T | undefined> =
|
||||
this._onDidActiveGroupChange.event;
|
||||
private readonly _onDidActiveChange = new Emitter<T | undefined>();
|
||||
readonly onDidActiveChange: Event<T | undefined> =
|
||||
this._onDidActiveChange.event;
|
||||
|
||||
protected readonly _bufferOnDidLayoutChange = new TickDelayedEvent();
|
||||
|
||||
@ -167,9 +164,9 @@ export abstract class BaseGrid<T extends IGridPanelView>
|
||||
this._bufferOnDidLayoutChange.fire();
|
||||
}),
|
||||
Event.any(
|
||||
this.onDidAddGroup,
|
||||
this.onDidRemoveGroup,
|
||||
this.onDidActiveGroupChange
|
||||
this.onDidAdd,
|
||||
this.onDidRemove,
|
||||
this.onDidActiveChange
|
||||
)(() => {
|
||||
this._bufferOnDidLayoutChange.fire();
|
||||
}),
|
||||
@ -222,9 +219,9 @@ export abstract class BaseGrid<T extends IGridPanelView>
|
||||
): void {
|
||||
this.gridview.addView(group, size ?? Sizing.Distribute, location);
|
||||
|
||||
this._onDidAddGroup.fire(group);
|
||||
this._onDidAdd.fire(group);
|
||||
|
||||
this.doSetGroupActive(group);
|
||||
// this.doSetGroupActive(group);
|
||||
}
|
||||
|
||||
protected doRemoveGroup(
|
||||
@ -243,10 +240,9 @@ export abstract class BaseGrid<T extends IGridPanelView>
|
||||
item.disposable.dispose();
|
||||
item.value.dispose();
|
||||
this._groups.delete(group.id);
|
||||
this._onDidRemove.fire(group);
|
||||
}
|
||||
|
||||
this._onDidRemoveGroup.fire(group);
|
||||
|
||||
if (!options?.skipActive && this._activeGroup === group) {
|
||||
const groups = Array.from(this._groups.values());
|
||||
|
||||
@ -276,7 +272,7 @@ export abstract class BaseGrid<T extends IGridPanelView>
|
||||
|
||||
this._activeGroup = group;
|
||||
|
||||
this._onDidActiveGroupChange.fire(group);
|
||||
this._onDidActiveChange.fire(group);
|
||||
}
|
||||
|
||||
public removeGroup(group: T): void {
|
||||
@ -330,9 +326,9 @@ export abstract class BaseGrid<T extends IGridPanelView>
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this._onDidActiveGroupChange.dispose();
|
||||
this._onDidAddGroup.dispose();
|
||||
this._onDidRemoveGroup.dispose();
|
||||
this._onDidActiveChange.dispose();
|
||||
this._onDidAdd.dispose();
|
||||
this._onDidRemove.dispose();
|
||||
this._onDidLayoutChange.dispose();
|
||||
|
||||
for (const group of this.groups) {
|
||||
|
@ -71,6 +71,9 @@ export interface IGridviewComponent extends IBaseGrid<GridviewPanel> {
|
||||
): void;
|
||||
setVisible(panel: IGridviewPanel, visible: boolean): void;
|
||||
setActive(panel: IGridviewPanel): void;
|
||||
readonly onDidRemoveGroup: Event<GridviewPanel>;
|
||||
readonly onDidAddGroup: Event<GridviewPanel>;
|
||||
readonly onDidActiveGroupChange: Event<GridviewPanel | undefined>;
|
||||
}
|
||||
|
||||
export class GridviewComponent
|
||||
@ -83,6 +86,19 @@ export class GridviewComponent
|
||||
private readonly _onDidLayoutfromJSON = new Emitter<void>();
|
||||
readonly onDidLayoutFromJSON: Event<void> = this._onDidLayoutfromJSON.event;
|
||||
|
||||
private readonly _onDidRemoveGroup = new Emitter<GridviewPanel>();
|
||||
readonly onDidRemoveGroup: Event<GridviewPanel> =
|
||||
this._onDidRemoveGroup.event;
|
||||
|
||||
protected readonly _onDidAddGroup = new Emitter<GridviewPanel>();
|
||||
readonly onDidAddGroup: Event<GridviewPanel> = this._onDidAddGroup.event;
|
||||
|
||||
private readonly _onDidActiveGroupChange = new Emitter<
|
||||
GridviewPanel | undefined
|
||||
>();
|
||||
readonly onDidActiveGroupChange: Event<GridviewPanel | undefined> =
|
||||
this._onDidActiveGroupChange.event;
|
||||
|
||||
get orientation(): Orientation {
|
||||
return this.gridview.orientation;
|
||||
}
|
||||
@ -114,6 +130,21 @@ export class GridviewComponent
|
||||
|
||||
this._options = options;
|
||||
|
||||
this.addDisposables(
|
||||
this._onDidAddGroup,
|
||||
this._onDidRemoveGroup,
|
||||
this._onDidActiveGroupChange,
|
||||
this.onDidAdd((event) => {
|
||||
this._onDidAddGroup.fire(event);
|
||||
}),
|
||||
this.onDidRemove((event) => {
|
||||
this._onDidRemoveGroup.fire(event);
|
||||
}),
|
||||
this.onDidActiveChange((event) => {
|
||||
this._onDidActiveGroupChange.fire(event);
|
||||
})
|
||||
);
|
||||
|
||||
if (!this.options.components) {
|
||||
this.options.components = {};
|
||||
}
|
||||
@ -364,6 +395,7 @@ export class GridviewComponent
|
||||
this.registerPanel(view);
|
||||
|
||||
this.doAddGroup(view, relativeLocation, options.size);
|
||||
this.doSetGroupActive(view);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
@ -33,6 +33,8 @@ import DockviewMaximizeGroup from '@site/sandboxes/maximizegroup-dockview/src/ap
|
||||
import DockviewRenderMode from '@site/sandboxes/rendermode-dockview/src/app';
|
||||
import DockviewScrollbars from '@site/sandboxes/scrollbars-dockview/src/app';
|
||||
|
||||
import DockviewFocus from '@site/sandboxes/focus-dockview/src/app';
|
||||
|
||||
import { DocRef } from '@site/src/components/ui/reference/docRef';
|
||||
|
||||
import { attach as attachDockviewVanilla } from '@site/sandboxes/javascript/vanilla-dockview/src/app';
|
||||
@ -42,6 +44,11 @@ import { attach as attachNativeDockview } from '@site/sandboxes/javascript/fullw
|
||||
|
||||
# Dockview
|
||||
|
||||
<MultiFrameworkContainer
|
||||
sandboxId="focus-dockview"
|
||||
react={DockviewFocus}
|
||||
/>
|
||||
|
||||
## Introduction
|
||||
|
||||
Dockview is an abstraction built on top of [Gridviews](./gridview) where each view is a container of many tabbed panels.
|
||||
|
@ -5,14 +5,169 @@ import {
|
||||
IDockviewPanelHeaderProps,
|
||||
IDockviewPanelProps,
|
||||
IDockviewHeaderActionsProps,
|
||||
DockviewPanelApi,
|
||||
DockviewPanelRenderer,
|
||||
DockviewGroupLocation,
|
||||
DockviewApi,
|
||||
} from 'dockview';
|
||||
import * as React from 'react';
|
||||
import * as ReactDOM from 'react-dom';
|
||||
import { v4 } from 'uuid';
|
||||
import './app.scss';
|
||||
|
||||
interface PanelApiMetadata {
|
||||
isActive: {
|
||||
value: boolean;
|
||||
count: number;
|
||||
};
|
||||
isVisible: {
|
||||
value: boolean;
|
||||
count: number;
|
||||
};
|
||||
isHidden: {
|
||||
value: boolean;
|
||||
count: number;
|
||||
};
|
||||
renderer: {
|
||||
value: DockviewPanelRenderer;
|
||||
count: number;
|
||||
};
|
||||
isGroupActive: {
|
||||
value: boolean;
|
||||
count: number;
|
||||
};
|
||||
groupChanged: {
|
||||
count: number;
|
||||
};
|
||||
location: {
|
||||
value: DockviewGroupLocation;
|
||||
count: number;
|
||||
};
|
||||
didFocus: {
|
||||
count: number;
|
||||
};
|
||||
dimensions: {
|
||||
count: number;
|
||||
height: number;
|
||||
width: number;
|
||||
};
|
||||
}
|
||||
|
||||
function usePanelApiMetadata(api: DockviewPanelApi): PanelApiMetadata {
|
||||
const [state, setState] = React.useState<PanelApiMetadata>({
|
||||
isActive: { value: api.isActive, count: 0 },
|
||||
isVisible: { value: api.isVisible, count: 0 },
|
||||
isHidden: { value: api.isHidden, count: 0 },
|
||||
renderer: { value: api.renderer, count: 0 },
|
||||
isGroupActive: { value: api.isGroupActive, count: 0 },
|
||||
groupChanged: { count: 0 },
|
||||
location: { value: api.location, count: 0 },
|
||||
didFocus: { count: 0 },
|
||||
dimensions: { count: 0, height: api.height, width: api.width },
|
||||
});
|
||||
|
||||
React.useEffect(() => {
|
||||
const d1 = api.onDidActiveChange((event) => {
|
||||
setState((_) => ({
|
||||
..._,
|
||||
isActive: {
|
||||
value: event.isActive,
|
||||
count: _.isActive.count + 1,
|
||||
},
|
||||
}));
|
||||
});
|
||||
const d2 = api.onDidActiveGroupChange((event) => {
|
||||
setState((_) => ({
|
||||
..._,
|
||||
isGroupActive: {
|
||||
value: event.isActive,
|
||||
count: _.isGroupActive.count + 1,
|
||||
},
|
||||
}));
|
||||
});
|
||||
const d3 = api.onDidDimensionsChange((event) => {
|
||||
setState((_) => ({
|
||||
..._,
|
||||
dimensions: {
|
||||
count: _.dimensions.count + 1,
|
||||
height: event.height,
|
||||
width: event.width,
|
||||
},
|
||||
}));
|
||||
});
|
||||
const d4 = api.onDidFocusChange((event) => {
|
||||
setState((_) => ({
|
||||
..._,
|
||||
didFocus: {
|
||||
count: _.didFocus.count + 1,
|
||||
},
|
||||
}));
|
||||
});
|
||||
const d5 = api.onDidGroupChange((event) => {
|
||||
setState((_) => ({
|
||||
..._,
|
||||
groupChanged: {
|
||||
count: _.groupChanged.count + 1,
|
||||
},
|
||||
}));
|
||||
});
|
||||
const d6 = api.onDidHiddenChange((event) => {
|
||||
setState((_) => ({
|
||||
..._,
|
||||
isHidden: {
|
||||
value: event.isHidden,
|
||||
count: _.isHidden.count + 1,
|
||||
},
|
||||
}));
|
||||
});
|
||||
const d7 = api.onDidLocationChange((event) => {
|
||||
setState((_) => ({
|
||||
..._,
|
||||
location: {
|
||||
value: event.location,
|
||||
count: _.location.count + 1,
|
||||
},
|
||||
}));
|
||||
});
|
||||
const d8 = api.onDidRendererChange((event) => {
|
||||
setState((_) => ({
|
||||
..._,
|
||||
renderer: {
|
||||
value: event.renderer,
|
||||
count: _.renderer.count + 1,
|
||||
},
|
||||
}));
|
||||
});
|
||||
const d9 = api.onDidVisibilityChange((event) => {
|
||||
setState((_) => ({
|
||||
..._,
|
||||
isVisible: {
|
||||
value: event.isVisible,
|
||||
count: _.isVisible.count + 1,
|
||||
},
|
||||
}));
|
||||
});
|
||||
|
||||
return () => {
|
||||
d1.dispose();
|
||||
d2.dispose();
|
||||
d3.dispose();
|
||||
d4.dispose();
|
||||
d5.dispose();
|
||||
d6.dispose();
|
||||
d7.dispose();
|
||||
d8.dispose();
|
||||
d9.dispose();
|
||||
};
|
||||
}, [api]);
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
const components = {
|
||||
default: (props: IDockviewPanelProps<{ title: string }>) => {
|
||||
default: (props: IDockviewPanelProps) => {
|
||||
const metadata = usePanelApiMetadata(props.api);
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
@ -22,6 +177,9 @@ const components = {
|
||||
position: 'relative',
|
||||
}}
|
||||
>
|
||||
<pre style={{ fontSize: '11px' }}>
|
||||
{JSON.stringify(metadata, null, 4)}
|
||||
</pre>
|
||||
<span
|
||||
style={{
|
||||
position: 'absolute',
|
||||
@ -198,7 +356,62 @@ const PrefixHeaderControls = (props: IDockviewHeaderActionsProps) => {
|
||||
};
|
||||
|
||||
const DockviewDemo = (props: { theme?: string }) => {
|
||||
const [logLines, setLogLines] = React.useState<any[]>([]);
|
||||
|
||||
const [panels, setPanels] = React.useState<string[]>([]);
|
||||
const [groups, setGroups] = React.useState<string[]>([]);
|
||||
const [api, setApi] = React.useState<DockviewApi>();
|
||||
|
||||
const [activePanel, setActivePanel] = React.useState<string>();
|
||||
const [activeGroup, setActiveGroup] = React.useState<string>();
|
||||
|
||||
const onReady = (event: DockviewReadyEvent) => {
|
||||
setApi(event.api);
|
||||
|
||||
event.api.onDidAddPanel((event) => {
|
||||
setPanels((_) => [..._, event.id]);
|
||||
setLogLines((line) => [`Panel Added ${event.id}`, ...line]);
|
||||
});
|
||||
event.api.onDidActivePanelChange((event) => {
|
||||
setActivePanel(event?.id);
|
||||
setLogLines((line) => [`Panel Activated ${event?.id}`, ...line]);
|
||||
});
|
||||
event.api.onDidRemovePanel((event) => {
|
||||
setPanels((_) => {
|
||||
const next = [..._];
|
||||
next.splice(
|
||||
next.findIndex((x) => x === event.id),
|
||||
1
|
||||
);
|
||||
|
||||
return next;
|
||||
});
|
||||
setLogLines((line) => [`Panel Removed ${event.id}`, ...line]);
|
||||
});
|
||||
|
||||
event.api.onDidAddGroup((event) => {
|
||||
setGroups((_) => [..._, event.id]);
|
||||
setLogLines((line) => [`Group Added ${event.id}`, ...line]);
|
||||
});
|
||||
|
||||
event.api.onDidRemoveGroup((event) => {
|
||||
setGroups((_) => {
|
||||
const next = [..._];
|
||||
next.splice(
|
||||
next.findIndex((x) => x === event.id),
|
||||
1
|
||||
);
|
||||
|
||||
return next;
|
||||
});
|
||||
setLogLines((line) => [`Group Removed ${event.id}`, ...line]);
|
||||
});
|
||||
|
||||
event.api.onDidActiveGroupChange((event) => {
|
||||
setActiveGroup(event?.id);
|
||||
setLogLines((line) => [`Group Activated ${event?.id}`, ...line]);
|
||||
});
|
||||
|
||||
const panel1 = event.api.addPanel({
|
||||
id: 'panel_1',
|
||||
component: 'default',
|
||||
@ -257,16 +470,179 @@ const DockviewDemo = (props: { theme?: string }) => {
|
||||
panel1.api.setActive();
|
||||
};
|
||||
|
||||
const onAddPanel = () => {
|
||||
api?.addPanel({
|
||||
id: `id_${Date.now().toString()}`,
|
||||
component: 'default',
|
||||
title: `Tab ${counter++}`,
|
||||
});
|
||||
};
|
||||
|
||||
const onAddGroup = () => {
|
||||
api?.addGroup();
|
||||
};
|
||||
|
||||
return (
|
||||
<DockviewReact
|
||||
components={components}
|
||||
defaultTabComponent={headerComponents.default}
|
||||
rightHeaderActionsComponent={RightControls}
|
||||
leftHeaderActionsComponent={LeftControls}
|
||||
prefixHeaderActionsComponent={PrefixHeaderControls}
|
||||
onReady={onReady}
|
||||
className={props.theme || 'dockview-theme-abyss'}
|
||||
/>
|
||||
<div
|
||||
style={{ height: '100%', display: 'flex', flexDirection: 'column' }}
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
height: '25px',
|
||||
padding: '2px 0px',
|
||||
}}
|
||||
>
|
||||
<button onClick={onAddPanel}>Add Panel</button>
|
||||
<button onClick={onAddGroup}>Add Group</button>
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
height: '25px',
|
||||
padding: '2px 0px',
|
||||
}}
|
||||
>
|
||||
{panels.map((x) => {
|
||||
const onClick = () => {
|
||||
api?.getPanel(x)?.focus();
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<button
|
||||
onClick={onClick}
|
||||
style={{
|
||||
minWidth: '50px',
|
||||
border: 'none',
|
||||
margin: '0px 2px',
|
||||
padding: '0px 2px',
|
||||
backgroundColor:
|
||||
activePanel === x
|
||||
? 'blueviolet'
|
||||
: 'dodgerblue',
|
||||
borderRadius: '2px',
|
||||
}}
|
||||
>
|
||||
{x}
|
||||
</button>
|
||||
<button
|
||||
onClick={() => {
|
||||
const panel = api?.getPanel(x);
|
||||
if (panel) {
|
||||
api?.addFloatingGroup(panel);
|
||||
}
|
||||
}}
|
||||
>
|
||||
float
|
||||
</button>
|
||||
<button
|
||||
onClick={() => {
|
||||
const panel = api?.getPanel(x);
|
||||
if (panel) {
|
||||
api?.addPopoutGroup(panel);
|
||||
}
|
||||
}}
|
||||
>
|
||||
pop
|
||||
</button>
|
||||
</>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
height: '25px',
|
||||
padding: '2px 0px',
|
||||
}}
|
||||
>
|
||||
{groups.map((x) => {
|
||||
const onClick = () => {
|
||||
api?.getGroup(x)?.focus();
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<button
|
||||
onClick={onClick}
|
||||
style={{
|
||||
minWidth: '50px',
|
||||
border: 'none',
|
||||
margin: '0px 2px',
|
||||
padding: '0px 2px',
|
||||
backgroundColor:
|
||||
activeGroup === x
|
||||
? 'blueviolet'
|
||||
: 'dodgerblue',
|
||||
borderRadius: '2px',
|
||||
}}
|
||||
>
|
||||
{x}
|
||||
</button>
|
||||
<button
|
||||
onClick={() => {
|
||||
const panel = api?.getGroup(x);
|
||||
if (panel) {
|
||||
api?.addFloatingGroup(panel);
|
||||
}
|
||||
}}
|
||||
>
|
||||
float
|
||||
</button>
|
||||
<button
|
||||
onClick={() => {
|
||||
const panel = api?.getGroup(x);
|
||||
if (panel) {
|
||||
api?.addPopoutGroup(panel);
|
||||
}
|
||||
}}
|
||||
>
|
||||
pop
|
||||
</button>
|
||||
</>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ flexGrow: 1 }}>
|
||||
<DockviewReact
|
||||
components={components}
|
||||
defaultTabComponent={headerComponents.default}
|
||||
rightHeaderActionsComponent={RightControls}
|
||||
leftHeaderActionsComponent={LeftControls}
|
||||
prefixHeaderActionsComponent={PrefixHeaderControls}
|
||||
onReady={onReady}
|
||||
className={props.theme || 'dockview-theme-abyss'}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
height: '200px',
|
||||
backgroundColor: 'black',
|
||||
color: 'white',
|
||||
overflow: 'auto',
|
||||
}}
|
||||
>
|
||||
{logLines.map((line, i) => {
|
||||
return (
|
||||
<div key={i}>
|
||||
<span
|
||||
style={{
|
||||
display: 'inline-block',
|
||||
width: '30px',
|
||||
color: 'gray',
|
||||
borderRight: '1px solid gray',
|
||||
marginRight: '4px',
|
||||
}}
|
||||
>
|
||||
{logLines.length - i}
|
||||
</span>
|
||||
<span>{line}</span>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
32
packages/docs/sandboxes/focus-dockview/package.json
Normal file
32
packages/docs/sandboxes/focus-dockview/package.json
Normal file
@ -0,0 +1,32 @@
|
||||
{
|
||||
"name": "focus-dockview",
|
||||
"description": "",
|
||||
"keywords": [
|
||||
"dockview"
|
||||
],
|
||||
"version": "1.0.0",
|
||||
"main": "src/index.tsx",
|
||||
"dependencies": {
|
||||
"dockview": "*",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^18.0.28",
|
||||
"@types/react-dom": "^18.0.11",
|
||||
"typescript": "^4.9.5",
|
||||
"react-scripts": "*"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test --env=jsdom",
|
||||
"eject": "react-scripts eject"
|
||||
},
|
||||
"browserslist": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not ie <= 11",
|
||||
"not op_mini all"
|
||||
]
|
||||
}
|
44
packages/docs/sandboxes/focus-dockview/public/index.html
Normal file
44
packages/docs/sandboxes/focus-dockview/public/index.html
Normal file
@ -0,0 +1,44 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="theme-color" content="#000000">
|
||||
<!--
|
||||
manifest.json provides metadata used when your web app is added to the
|
||||
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
|
||||
-->
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
|
||||
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
|
||||
<!--
|
||||
Notice the use of %PUBLIC_URL% in the tags above.
|
||||
It will be replaced with the URL of the `public` folder during the build.
|
||||
Only files inside the `public` folder can be referenced from the HTML.
|
||||
|
||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
||||
work correctly both with client-side routing and a non-root public URL.
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
<title>React App</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<noscript>
|
||||
You need to enable JavaScript to run this app.
|
||||
</noscript>
|
||||
<div id="root"></div>
|
||||
<!--
|
||||
This HTML file is a template.
|
||||
If you open it directly in the browser, you will see an empty page.
|
||||
|
||||
You can add webfonts, meta tags, or analytics to this file.
|
||||
The build step will place the bundled scripts into the <body> tag.
|
||||
|
||||
To begin the development, run `npm start` or `yarn start`.
|
||||
To create a production bundle, use `npm run build` or `yarn build`.
|
||||
-->
|
||||
</body>
|
||||
|
||||
</html>
|
125
packages/docs/sandboxes/focus-dockview/src/app.tsx
Normal file
125
packages/docs/sandboxes/focus-dockview/src/app.tsx
Normal file
@ -0,0 +1,125 @@
|
||||
import {
|
||||
DockviewApi,
|
||||
DockviewReact,
|
||||
DockviewReadyEvent,
|
||||
IDockviewPanelProps,
|
||||
} from 'dockview';
|
||||
import * as React from 'react';
|
||||
|
||||
const components = {
|
||||
default: (props: IDockviewPanelProps) => {
|
||||
React.useEffect(() => {
|
||||
const d1 = props.api.onWillFocus((event) => {
|
||||
console.log('willFocus');
|
||||
});
|
||||
|
||||
const d2 = props.api.onDidActiveChange((event) => {
|
||||
console.log(props.api.title, event, 'active');
|
||||
});
|
||||
|
||||
const d3 = props.api.onDidActiveGroupChange((event) => {
|
||||
console.log(
|
||||
props.api.title,
|
||||
props.api.group.api.isActive,
|
||||
'active-group'
|
||||
);
|
||||
});
|
||||
|
||||
const d4 = props.api.onDidGroupChange((event) => {
|
||||
console.log(
|
||||
props.api.title,
|
||||
props.api.group.id,
|
||||
'group-change'
|
||||
);
|
||||
});
|
||||
|
||||
return () => {
|
||||
d1.dispose();
|
||||
d2.dispose();
|
||||
d3.dispose();
|
||||
};
|
||||
}, [props.api]);
|
||||
|
||||
return (
|
||||
<div style={{ padding: '20px', color: 'white' }}>
|
||||
{props.api.title}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
export const App: React.FC = (props: { theme?: string }) => {
|
||||
const [api, setApi] = React.useState<DockviewApi>();
|
||||
|
||||
const onReady = (event: DockviewReadyEvent) => {
|
||||
setApi(event.api);
|
||||
|
||||
event.api.addPanel({
|
||||
id: 'panel_1',
|
||||
title: 'Panel 1',
|
||||
component: 'default',
|
||||
});
|
||||
|
||||
event.api.addPanel({
|
||||
id: 'panel_2',
|
||||
title: 'Panel 2',
|
||||
component: 'default',
|
||||
});
|
||||
|
||||
// event.api.onDidAddPanel((event) => {
|
||||
// console.log('add panel', event);
|
||||
// });
|
||||
// event.api.onDidActivePanelChange((event) => {
|
||||
// console.log('active panel', event);
|
||||
// });
|
||||
// event.api.onDidRemovePanel((event) => {
|
||||
// console.log('remove panel', event);
|
||||
// });
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{ height: '100%', display: 'flex', flexDirection: 'column' }}
|
||||
>
|
||||
<div>
|
||||
<button
|
||||
onClick={() => {
|
||||
api?.getPanel('panel_1')?.focus();
|
||||
}}
|
||||
>
|
||||
{'Focus Panel 1'}
|
||||
</button>
|
||||
<button
|
||||
onClick={() => {
|
||||
api?.getPanel('panel_2')?.focus();
|
||||
}}
|
||||
>
|
||||
{'Focus Panel 2'}
|
||||
</button>
|
||||
<button
|
||||
onClick={() => {
|
||||
api?.getPanel('panel_1')?.api.setActive();
|
||||
}}
|
||||
>
|
||||
{'Active Panel 1'}
|
||||
</button>
|
||||
<button
|
||||
onClick={() => {
|
||||
api?.getPanel('panel_2')?.api.setActive();
|
||||
}}
|
||||
>
|
||||
{'Active Panel 2'}
|
||||
</button>
|
||||
</div>
|
||||
<div style={{ flexGrow: 1 }}>
|
||||
<DockviewReact
|
||||
components={components}
|
||||
onReady={onReady}
|
||||
className={props.theme || 'dockview-theme-abyss'}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
20
packages/docs/sandboxes/focus-dockview/src/index.tsx
Normal file
20
packages/docs/sandboxes/focus-dockview/src/index.tsx
Normal file
@ -0,0 +1,20 @@
|
||||
import { StrictMode } from 'react';
|
||||
import * as ReactDOMClient from 'react-dom/client';
|
||||
import './styles.css';
|
||||
import 'dockview/dist/styles/dockview.css';
|
||||
|
||||
import App from './app';
|
||||
|
||||
const rootElement = document.getElementById('root');
|
||||
|
||||
if (rootElement) {
|
||||
const root = ReactDOMClient.createRoot(rootElement);
|
||||
|
||||
root.render(
|
||||
<StrictMode>
|
||||
<div className="app">
|
||||
<App />
|
||||
</div>
|
||||
</StrictMode>
|
||||
);
|
||||
}
|
16
packages/docs/sandboxes/focus-dockview/src/styles.css
Normal file
16
packages/docs/sandboxes/focus-dockview/src/styles.css
Normal file
@ -0,0 +1,16 @@
|
||||
body {
|
||||
margin: 0px;
|
||||
color: white;
|
||||
font-family: sans-serif;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#root {
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
}
|
||||
|
||||
.app {
|
||||
height: 100%;
|
||||
|
||||
}
|
18
packages/docs/sandboxes/focus-dockview/tsconfig.json
Normal file
18
packages/docs/sandboxes/focus-dockview/tsconfig.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"outDir": "build/dist",
|
||||
"module": "esnext",
|
||||
"target": "es5",
|
||||
"lib": ["es6", "dom"],
|
||||
"sourceMap": true,
|
||||
"allowJs": true,
|
||||
"jsx": "react-jsx",
|
||||
"moduleResolution": "node",
|
||||
"rootDir": "src",
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noImplicitReturns": true,
|
||||
"noImplicitThis": true,
|
||||
"noImplicitAny": true,
|
||||
"strictNullChecks": true
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user