mirror of
				https://github.com/mathuo/dockview
				synced 2025-11-04 14:10:32 +00:00 
			
		
		
		
	Merge branch 'master' of https://github.com/mathuo/dockview into master
This commit is contained in:
		
						commit
						317957c26f
					
				@ -17,6 +17,7 @@
 | 
				
			|||||||
          "ES2016.Array.Include",
 | 
					          "ES2016.Array.Include",
 | 
				
			||||||
          "ES2017.String",
 | 
					          "ES2017.String",
 | 
				
			||||||
          "ES2018.Promise",
 | 
					          "ES2018.Promise",
 | 
				
			||||||
 | 
					          "ES2019",
 | 
				
			||||||
          "DOM",
 | 
					          "DOM",
 | 
				
			||||||
		  ]
 | 
							  ]
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -17,6 +17,7 @@
 | 
				
			|||||||
          "ES2016.Array.Include",
 | 
					          "ES2016.Array.Include",
 | 
				
			||||||
          "ES2017.String",
 | 
					          "ES2017.String",
 | 
				
			||||||
          "ES2018.Promise",
 | 
					          "ES2018.Promise",
 | 
				
			||||||
 | 
					          "ES2019",
 | 
				
			||||||
          "DOM",
 | 
					          "DOM",
 | 
				
			||||||
		  ]
 | 
							  ]
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										78
									
								
								packages/dockview/src/__tests__/api/groupPanelApi.spec.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								packages/dockview/src/__tests__/api/groupPanelApi.spec.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,78 @@
 | 
				
			|||||||
 | 
					import { IDockviewComponent, IGroupPanel } from '../..';
 | 
				
			||||||
 | 
					import { DockviewPanelApiImpl, TitleEvent } from '../../api/groupPanelApi';
 | 
				
			||||||
 | 
					import { GroupviewPanel } from '../../groupview/groupviewPanel';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					describe('groupPanelApi', () => {
 | 
				
			||||||
 | 
					    test('title', () => {
 | 
				
			||||||
 | 
					        const groupPanel: Partial<IGroupPanel> = {
 | 
				
			||||||
 | 
					            id: 'test_id',
 | 
				
			||||||
 | 
					            title: 'test_title',
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const accessor: Partial<IDockviewComponent> = {};
 | 
				
			||||||
 | 
					        const groupViewPanel = new GroupviewPanel(
 | 
				
			||||||
 | 
					            <IDockviewComponent>accessor,
 | 
				
			||||||
 | 
					            '',
 | 
				
			||||||
 | 
					            {}
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const cut = new DockviewPanelApiImpl(
 | 
				
			||||||
 | 
					            <IGroupPanel>groupPanel,
 | 
				
			||||||
 | 
					            <GroupviewPanel>groupViewPanel
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let events: TitleEvent[] = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const disposable = cut.onDidTitleChange((event) => {
 | 
				
			||||||
 | 
					            events.push(event);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        expect(events.length).toBe(0);
 | 
				
			||||||
 | 
					        expect(cut.title).toBe('test_title');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        cut.setTitle('test_title_2');
 | 
				
			||||||
 | 
					        expect(events.length).toBe(1);
 | 
				
			||||||
 | 
					        expect(events[0]).toEqual({ title: 'test_title_2' });
 | 
				
			||||||
 | 
					        expect(cut.title).toBe('test_title'); // title should remain unchanged
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        disposable.dispose();
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    test('onDidGroupChange', () => {
 | 
				
			||||||
 | 
					        const groupPanel: Partial<IGroupPanel> = {
 | 
				
			||||||
 | 
					            id: 'test_id',
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const accessor: Partial<IDockviewComponent> = {};
 | 
				
			||||||
 | 
					        const groupViewPanel = new GroupviewPanel(
 | 
				
			||||||
 | 
					            <IDockviewComponent>accessor,
 | 
				
			||||||
 | 
					            '',
 | 
				
			||||||
 | 
					            {}
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const cut = new DockviewPanelApiImpl(
 | 
				
			||||||
 | 
					            <IGroupPanel>groupPanel,
 | 
				
			||||||
 | 
					            <GroupviewPanel>groupViewPanel
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let events = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const disposable = cut.onDidGroupChange(() => {
 | 
				
			||||||
 | 
					            events++;
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        expect(events).toBe(0);
 | 
				
			||||||
 | 
					        expect(cut.group).toBe(groupViewPanel);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const groupViewPanel2 = new GroupviewPanel(
 | 
				
			||||||
 | 
					            <IDockviewComponent>accessor,
 | 
				
			||||||
 | 
					            '',
 | 
				
			||||||
 | 
					            {}
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        cut.group = groupViewPanel2;
 | 
				
			||||||
 | 
					        expect(events).toBe(1);
 | 
				
			||||||
 | 
					        expect(cut.group).toBe(groupViewPanel2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        disposable.dispose();
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
@ -811,4 +811,31 @@ describe('dockviewComponent', () => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        disposable.dispose();
 | 
					        disposable.dispose();
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    test('that removing a panel from a group reflects in the dockviewcomponent when searching for a panel', () => {
 | 
				
			||||||
 | 
					        dockview.layout(500, 500);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const panel1 = dockview.addPanel({
 | 
				
			||||||
 | 
					            id: 'panel1',
 | 
				
			||||||
 | 
					            component: 'default',
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const panel2 = dockview.addPanel({
 | 
				
			||||||
 | 
					            id: 'panel2',
 | 
				
			||||||
 | 
					            component: 'default',
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        expect(dockview.getGroupPanel('panel1')).toEqual(panel1);
 | 
				
			||||||
 | 
					        expect(dockview.getGroupPanel('panel2')).toEqual(panel2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        panel1.group.model.removePanel(panel1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        expect(dockview.getGroupPanel('panel1')).toBeUndefined();
 | 
				
			||||||
 | 
					        expect(dockview.getGroupPanel('panel2')).toEqual(panel2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        dockview.removePanel(panel2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        expect(dockview.getGroupPanel('panel1')).toBeUndefined();
 | 
				
			||||||
 | 
					        expect(dockview.getGroupPanel('panel2')).toBeUndefined();
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
				
			|||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -444,4 +444,19 @@ describe('groupview', () => {
 | 
				
			|||||||
        groupview.model.closeAllPanels();
 | 
					        groupview.model.closeAllPanels();
 | 
				
			||||||
        expect(removeGroupMock).toBeCalledWith(groupview);
 | 
					        expect(removeGroupMock).toBeCalledWith(groupview);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    test('that group is set on panel during onDidAddPanel event', () => {
 | 
				
			||||||
 | 
					        const cut = new DockviewComponent(document.createElement('div'), {
 | 
				
			||||||
 | 
					            components: {
 | 
				
			||||||
 | 
					                component: TestContentPart,
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const disposable = cut.onDidAddPanel((panel) => {
 | 
				
			||||||
 | 
					            expect(panel.group).toBeTruthy();
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const panel = cut.addPanel({ id: 'id', component: 'component' });
 | 
				
			||||||
 | 
					        disposable.dispose();
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
				
			|||||||
@ -11,6 +11,8 @@ export enum Position {
 | 
				
			|||||||
    Center = 'Center',
 | 
					    Center = 'Center',
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Quadrant = 'top' | 'bottom' | 'left' | 'right';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface DroptargetEvent {
 | 
					export interface DroptargetEvent {
 | 
				
			||||||
    position: Position;
 | 
					    position: Position;
 | 
				
			||||||
    nativeEvent: DragEvent;
 | 
					    nativeEvent: DragEvent;
 | 
				
			||||||
@ -100,60 +102,18 @@ export class Droptarget extends CompositeDisposable {
 | 
				
			|||||||
                    const xp = (100 * x) / width;
 | 
					                    const xp = (100 * x) / width;
 | 
				
			||||||
                    const yp = (100 * y) / height;
 | 
					                    const yp = (100 * y) / height;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    let isRight = false;
 | 
					                    const quadrant = this.calculateQuadrant(
 | 
				
			||||||
                    let isLeft = false;
 | 
					                        this.options.validOverlays,
 | 
				
			||||||
                    let isTop = false;
 | 
					                        xp,
 | 
				
			||||||
                    let isBottom = false;
 | 
					                        yp
 | 
				
			||||||
 | 
					                    );
 | 
				
			||||||
                    switch (this.options.validOverlays) {
 | 
					 | 
				
			||||||
                        case 'all':
 | 
					 | 
				
			||||||
                            isRight = xp > 80;
 | 
					 | 
				
			||||||
                            isLeft = xp < 20;
 | 
					 | 
				
			||||||
                            isTop = !isRight && !isLeft && yp < 20;
 | 
					 | 
				
			||||||
                            isBottom = !isRight && !isLeft && yp > 80;
 | 
					 | 
				
			||||||
                            break;
 | 
					 | 
				
			||||||
                        case 'vertical':
 | 
					 | 
				
			||||||
                            isTop = yp < 50;
 | 
					 | 
				
			||||||
                            isBottom = yp >= 50;
 | 
					 | 
				
			||||||
                            break;
 | 
					 | 
				
			||||||
                        case 'horizontal':
 | 
					 | 
				
			||||||
                            isLeft = xp < 50;
 | 
					 | 
				
			||||||
                            isRight = xp >= 50;
 | 
					 | 
				
			||||||
                            break;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    const isSmallX = width < 100;
 | 
					                    const isSmallX = width < 100;
 | 
				
			||||||
                    const isSmallY = height < 100;
 | 
					                    const isSmallY = height < 100;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    toggleClass(this.overlay, 'right', !isSmallX && isRight);
 | 
					                    this.toggleClasses(quadrant, isSmallX, isSmallY);
 | 
				
			||||||
                    toggleClass(this.overlay, 'left', !isSmallX && isLeft);
 | 
					 | 
				
			||||||
                    toggleClass(this.overlay, 'top', !isSmallY && isTop);
 | 
					 | 
				
			||||||
                    toggleClass(this.overlay, 'bottom', !isSmallY && isBottom);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    toggleClass(
 | 
					                    this.setState(quadrant);
 | 
				
			||||||
                        this.overlay,
 | 
					 | 
				
			||||||
                        'small-right',
 | 
					 | 
				
			||||||
                        isSmallX && isRight
 | 
					 | 
				
			||||||
                    );
 | 
					 | 
				
			||||||
                    toggleClass(this.overlay, 'small-left', isSmallX && isLeft);
 | 
					 | 
				
			||||||
                    toggleClass(this.overlay, 'small-top', isSmallY && isTop);
 | 
					 | 
				
			||||||
                    toggleClass(
 | 
					 | 
				
			||||||
                        this.overlay,
 | 
					 | 
				
			||||||
                        'small-bottom',
 | 
					 | 
				
			||||||
                        isSmallY && isBottom
 | 
					 | 
				
			||||||
                    );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    if (isRight) {
 | 
					 | 
				
			||||||
                        this._state = Position.Right;
 | 
					 | 
				
			||||||
                    } else if (isLeft) {
 | 
					 | 
				
			||||||
                        this._state = Position.Left;
 | 
					 | 
				
			||||||
                    } else if (isTop) {
 | 
					 | 
				
			||||||
                        this._state = Position.Top;
 | 
					 | 
				
			||||||
                    } else if (isBottom) {
 | 
					 | 
				
			||||||
                        this._state = Position.Bottom;
 | 
					 | 
				
			||||||
                    } else {
 | 
					 | 
				
			||||||
                        this._state = Position.Center;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
                onDragLeave: (e) => {
 | 
					                onDragLeave: (e) => {
 | 
				
			||||||
                    this.removeDropTarget();
 | 
					                    this.removeDropTarget();
 | 
				
			||||||
@ -181,6 +141,87 @@ export class Droptarget extends CompositeDisposable {
 | 
				
			|||||||
        this.removeDropTarget();
 | 
					        this.removeDropTarget();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private toggleClasses(
 | 
				
			||||||
 | 
					        quadrant: Quadrant | null,
 | 
				
			||||||
 | 
					        isSmallX: boolean,
 | 
				
			||||||
 | 
					        isSmallY: boolean
 | 
				
			||||||
 | 
					    ) {
 | 
				
			||||||
 | 
					        if (!this.overlay) {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const isLeft = quadrant === 'left';
 | 
				
			||||||
 | 
					        const isRight = quadrant === 'right';
 | 
				
			||||||
 | 
					        const isTop = quadrant === 'top';
 | 
				
			||||||
 | 
					        const isBottom = quadrant === 'bottom';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        toggleClass(this.overlay, 'right', !isSmallX && isRight);
 | 
				
			||||||
 | 
					        toggleClass(this.overlay, 'left', !isSmallX && isLeft);
 | 
				
			||||||
 | 
					        toggleClass(this.overlay, 'top', !isSmallY && isTop);
 | 
				
			||||||
 | 
					        toggleClass(this.overlay, 'bottom', !isSmallY && isBottom);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        toggleClass(this.overlay, 'small-right', isSmallX && isRight);
 | 
				
			||||||
 | 
					        toggleClass(this.overlay, 'small-left', isSmallX && isLeft);
 | 
				
			||||||
 | 
					        toggleClass(this.overlay, 'small-top', isSmallY && isTop);
 | 
				
			||||||
 | 
					        toggleClass(this.overlay, 'small-bottom', isSmallY && isBottom);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private setState(quadrant: Quadrant | null) {
 | 
				
			||||||
 | 
					        switch (quadrant) {
 | 
				
			||||||
 | 
					            case 'top':
 | 
				
			||||||
 | 
					                this._state = Position.Top;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case 'left':
 | 
				
			||||||
 | 
					                this._state = Position.Left;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case 'bottom':
 | 
				
			||||||
 | 
					                this._state = Position.Bottom;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case 'right':
 | 
				
			||||||
 | 
					                this._state = Position.Right;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            default:
 | 
				
			||||||
 | 
					                this._state = Position.Center;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private calculateQuadrant(
 | 
				
			||||||
 | 
					        overlayType: DropTargetDirections,
 | 
				
			||||||
 | 
					        xp: number,
 | 
				
			||||||
 | 
					        yp: number
 | 
				
			||||||
 | 
					    ): Quadrant | null {
 | 
				
			||||||
 | 
					        switch (overlayType) {
 | 
				
			||||||
 | 
					            case 'all':
 | 
				
			||||||
 | 
					                if (xp < 20) {
 | 
				
			||||||
 | 
					                    return 'left';
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                if (xp > 80) {
 | 
				
			||||||
 | 
					                    return 'right';
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                if (yp < 20) {
 | 
				
			||||||
 | 
					                    return 'top';
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                if (yp > 80) {
 | 
				
			||||||
 | 
					                    return 'bottom';
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case 'vertical':
 | 
				
			||||||
 | 
					                if (yp < 50) {
 | 
				
			||||||
 | 
					                    return 'top';
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                return 'bottom';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            case 'horizontal':
 | 
				
			||||||
 | 
					                if (xp < 50) {
 | 
				
			||||||
 | 
					                    return 'left';
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                return 'right';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private removeDropTarget() {
 | 
					    private removeDropTarget() {
 | 
				
			||||||
        if (this.target) {
 | 
					        if (this.target) {
 | 
				
			||||||
            this._state = undefined;
 | 
					            this._state = undefined;
 | 
				
			||||||
 | 
				
			|||||||
@ -7,7 +7,7 @@ import { Position } from '../dnd/droptarget';
 | 
				
			|||||||
import { tail, sequenceEquals } from '../array';
 | 
					import { tail, sequenceEquals } from '../array';
 | 
				
			||||||
import { GroupviewPanelState, IGroupPanel } from '../groupview/groupPanel';
 | 
					import { GroupviewPanelState, IGroupPanel } from '../groupview/groupPanel';
 | 
				
			||||||
import { DockviewGroupPanel } from './dockviewGroupPanel';
 | 
					import { DockviewGroupPanel } from './dockviewGroupPanel';
 | 
				
			||||||
import { CompositeDisposable, IValueDisposable } from '../lifecycle';
 | 
					import { CompositeDisposable } from '../lifecycle';
 | 
				
			||||||
import { Event, Emitter } from '../events';
 | 
					import { Event, Emitter } from '../events';
 | 
				
			||||||
import { Watermark } from './components/watermark/watermark';
 | 
					import { Watermark } from './components/watermark/watermark';
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
@ -100,7 +100,6 @@ export interface IDockviewComponent extends IBaseGrid<GroupviewPanel> {
 | 
				
			|||||||
    getGroupPanel: (id: string) => IGroupPanel | undefined;
 | 
					    getGroupPanel: (id: string) => IGroupPanel | undefined;
 | 
				
			||||||
    fireMouseEvent(event: LayoutMouseEvent): void;
 | 
					    fireMouseEvent(event: LayoutMouseEvent): void;
 | 
				
			||||||
    createWatermarkComponent(): IWatermarkRenderer;
 | 
					    createWatermarkComponent(): IWatermarkRenderer;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    // lifecycle
 | 
					    // lifecycle
 | 
				
			||||||
    addEmptyGroup(options?: AddGroupOptions): void;
 | 
					    addEmptyGroup(options?: AddGroupOptions): void;
 | 
				
			||||||
    closeAllGroups(): void;
 | 
					    closeAllGroups(): void;
 | 
				
			||||||
@ -113,13 +112,17 @@ export interface IDockviewComponent extends IBaseGrid<GroupviewPanel> {
 | 
				
			|||||||
    focus(): void;
 | 
					    focus(): void;
 | 
				
			||||||
    toJSON(): SerializedDockview;
 | 
					    toJSON(): SerializedDockview;
 | 
				
			||||||
    fromJSON(data: SerializedDockview): void;
 | 
					    fromJSON(data: SerializedDockview): void;
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
 | 
					    readonly onDidRemovePanel: Event<IGroupPanel>;
 | 
				
			||||||
 | 
					    readonly onDidAddPanel: Event<IGroupPanel>;
 | 
				
			||||||
 | 
					    readonly onDidActivePanelChange: Event<IGroupPanel | undefined>;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class DockviewComponent
 | 
					export class DockviewComponent
 | 
				
			||||||
    extends BaseGrid<GroupviewPanel>
 | 
					    extends BaseGrid<GroupviewPanel>
 | 
				
			||||||
    implements IDockviewComponent
 | 
					    implements IDockviewComponent
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    private readonly _panels = new Map<string, IValueDisposable<IGroupPanel>>();
 | 
					    // private readonly _panels = new Map<string, IValueDisposable<IGroupPanel>>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // events
 | 
					    // events
 | 
				
			||||||
    private readonly _onTabInteractionEvent = new Emitter<LayoutMouseEvent>();
 | 
					    private readonly _onTabInteractionEvent = new Emitter<LayoutMouseEvent>();
 | 
				
			||||||
@ -133,17 +136,30 @@ export class DockviewComponent
 | 
				
			|||||||
    private readonly _onDidDrop = new Emitter<DockviewDropEvent>();
 | 
					    private readonly _onDidDrop = new Emitter<DockviewDropEvent>();
 | 
				
			||||||
    readonly onDidDrop: Event<DockviewDropEvent> = this._onDidDrop.event;
 | 
					    readonly onDidDrop: Event<DockviewDropEvent> = this._onDidDrop.event;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private readonly _onDidRemovePanel = new Emitter<IGroupPanel>();
 | 
				
			||||||
 | 
					    readonly onDidRemovePanel: Event<IGroupPanel> =
 | 
				
			||||||
 | 
					        this._onDidRemovePanel.event;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private readonly _onDidAddPanel = new Emitter<IGroupPanel>();
 | 
				
			||||||
 | 
					    readonly onDidAddPanel: Event<IGroupPanel> = this._onDidAddPanel.event;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private readonly _onDidActivePanelChange = new Emitter<
 | 
				
			||||||
 | 
					        IGroupPanel | undefined
 | 
				
			||||||
 | 
					    >();
 | 
				
			||||||
 | 
					    readonly onDidActivePanelChange: Event<IGroupPanel | undefined> =
 | 
				
			||||||
 | 
					        this._onDidActivePanelChange.event;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // everything else
 | 
					    // everything else
 | 
				
			||||||
    private _deserializer: IPanelDeserializer | undefined;
 | 
					    private _deserializer: IPanelDeserializer | undefined;
 | 
				
			||||||
    private _api: DockviewApi;
 | 
					    private _api: DockviewApi;
 | 
				
			||||||
    private _options: DockviewComponentOptions;
 | 
					    private _options: DockviewComponentOptions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    get totalPanels(): number {
 | 
					    get totalPanels(): number {
 | 
				
			||||||
        return this._panels.size;
 | 
					        return this.panels.length;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    get panels(): IGroupPanel[] {
 | 
					    get panels(): IGroupPanel[] {
 | 
				
			||||||
        return Array.from(this._panels.values()).map((_) => _.value);
 | 
					        return this.groups.flatMap((group) => group.model.panels);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    get deserializer(): IPanelDeserializer | undefined {
 | 
					    get deserializer(): IPanelDeserializer | undefined {
 | 
				
			||||||
@ -235,7 +251,7 @@ export class DockviewComponent
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    getGroupPanel(id: string): IGroupPanel | undefined {
 | 
					    getGroupPanel(id: string): IGroupPanel | undefined {
 | 
				
			||||||
        return this._panels.get(id)?.value;
 | 
					        return this.panels.find((panel) => panel.id === id);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    setActivePanel(panel: IGroupPanel): void {
 | 
					    setActivePanel(panel: IGroupPanel): void {
 | 
				
			||||||
@ -296,35 +312,6 @@ export class DockviewComponent
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private registerPanel(panel: IGroupPanel): void {
 | 
					 | 
				
			||||||
        if (this._panels.has(panel.id)) {
 | 
					 | 
				
			||||||
            throw new Error(`panel ${panel.id} already exists`);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        this._panels.set(panel.id, {
 | 
					 | 
				
			||||||
            value: panel,
 | 
					 | 
				
			||||||
            disposable: {
 | 
					 | 
				
			||||||
                dispose: () => {
 | 
					 | 
				
			||||||
                    /** noop */
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private unregisterPanel(panel: IGroupPanel): void {
 | 
					 | 
				
			||||||
        if (!this._panels.has(panel.id)) {
 | 
					 | 
				
			||||||
            throw new Error(`panel ${panel.id} doesn't exist`);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        const item = this._panels.get(panel.id);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (item) {
 | 
					 | 
				
			||||||
            item.disposable.dispose();
 | 
					 | 
				
			||||||
            item.value.dispose();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        this._panels.delete(panel.id);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Serialize the current state of the layout
 | 
					     * Serialize the current state of the layout
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
@ -333,13 +320,10 @@ export class DockviewComponent
 | 
				
			|||||||
    toJSON(): SerializedDockview {
 | 
					    toJSON(): SerializedDockview {
 | 
				
			||||||
        const data = this.gridview.serialize();
 | 
					        const data = this.gridview.serialize();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const panels = Array.from(this._panels.values()).reduce(
 | 
					        const panels = this.panels.reduce((collection, panel) => {
 | 
				
			||||||
            (collection, panel) => {
 | 
					            collection[panel.id] = panel.toJSON();
 | 
				
			||||||
                collection[panel.value.id] = panel.value.toJSON();
 | 
					 | 
				
			||||||
            return collection;
 | 
					            return collection;
 | 
				
			||||||
            },
 | 
					        }, {} as { [key: string]: GroupviewPanelState });
 | 
				
			||||||
            {} as { [key: string]: GroupviewPanelState }
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return {
 | 
					        return {
 | 
				
			||||||
            grid: data,
 | 
					            grid: data,
 | 
				
			||||||
@ -351,11 +335,9 @@ export class DockviewComponent
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    fromJSON(data: SerializedDockview): void {
 | 
					    fromJSON(data: SerializedDockview): void {
 | 
				
			||||||
        this.gridview.clear();
 | 
					        this.gridview.clear();
 | 
				
			||||||
        this._panels.forEach((panel) => {
 | 
					        this.panels.forEach((panel) => {
 | 
				
			||||||
            panel.disposable.dispose();
 | 
					            panel.dispose();
 | 
				
			||||||
            panel.value.dispose();
 | 
					 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        this._panels.clear();
 | 
					 | 
				
			||||||
        this._groups.clear();
 | 
					        this._groups.clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!this.deserializer) {
 | 
					        if (!this.deserializer) {
 | 
				
			||||||
@ -376,9 +358,7 @@ export class DockviewComponent
 | 
				
			|||||||
            new DefaultDeserializer(this, {
 | 
					            new DefaultDeserializer(this, {
 | 
				
			||||||
                createPanel: (id) => {
 | 
					                createPanel: (id) => {
 | 
				
			||||||
                    const panelData = panels[id];
 | 
					                    const panelData = panels[id];
 | 
				
			||||||
                    const panel = this.deserializer!.fromJSON(panelData);
 | 
					                    return this.deserializer!.fromJSON(panelData);
 | 
				
			||||||
                    this.registerPanel(panel);
 | 
					 | 
				
			||||||
                    return panel;
 | 
					 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
            })
 | 
					            })
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
@ -457,7 +437,6 @@ export class DockviewComponent
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    removePanel(panel: IGroupPanel): void {
 | 
					    removePanel(panel: IGroupPanel): void {
 | 
				
			||||||
        this.unregisterPanel(panel);
 | 
					 | 
				
			||||||
        const group = panel.group;
 | 
					        const group = panel.group;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!group) {
 | 
					        if (!group) {
 | 
				
			||||||
@ -491,9 +470,9 @@ export class DockviewComponent
 | 
				
			|||||||
        const group = this.createGroup();
 | 
					        const group = this.createGroup();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (options) {
 | 
					        if (options) {
 | 
				
			||||||
            const referencePanel = this._panels.get(
 | 
					            const referencePanel = this.panels.find(
 | 
				
			||||||
                options.referencePanel
 | 
					                (panel) => panel.id === options.referencePanel
 | 
				
			||||||
            )?.value;
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (!referencePanel) {
 | 
					            if (!referencePanel) {
 | 
				
			||||||
                throw new Error(
 | 
					                throw new Error(
 | 
				
			||||||
@ -551,7 +530,7 @@ export class DockviewComponent
 | 
				
			|||||||
        if (!target || target === Position.Center) {
 | 
					        if (!target || target === Position.Center) {
 | 
				
			||||||
            const groupItem: IGroupPanel | undefined =
 | 
					            const groupItem: IGroupPanel | undefined =
 | 
				
			||||||
                sourceGroup?.model.removePanel(itemId) ||
 | 
					                sourceGroup?.model.removePanel(itemId) ||
 | 
				
			||||||
                this._panels.get(itemId)?.value;
 | 
					                this.panels.find((panel) => panel.id === itemId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (!groupItem) {
 | 
					            if (!groupItem) {
 | 
				
			||||||
                throw new Error(`No panel with id ${itemId}`);
 | 
					                throw new Error(`No panel with id ${itemId}`);
 | 
				
			||||||
@ -603,7 +582,7 @@ export class DockviewComponent
 | 
				
			|||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                const groupItem: IGroupPanel | undefined =
 | 
					                const groupItem: IGroupPanel | undefined =
 | 
				
			||||||
                    sourceGroup?.model.removePanel(itemId) ||
 | 
					                    sourceGroup?.model.removePanel(itemId) ||
 | 
				
			||||||
                    this._panels.get(itemId)?.value;
 | 
					                    this.panels.find((panel) => panel.id === itemId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (!groupItem) {
 | 
					                if (!groupItem) {
 | 
				
			||||||
                    throw new Error(`No panel with id ${itemId}`);
 | 
					                    throw new Error(`No panel with id ${itemId}`);
 | 
				
			||||||
@ -632,6 +611,9 @@ export class DockviewComponent
 | 
				
			|||||||
                kind: GroupChangeKind.PANEL_ACTIVE,
 | 
					                kind: GroupChangeKind.PANEL_ACTIVE,
 | 
				
			||||||
                panel: this._activeGroup?.model.activePanel,
 | 
					                panel: this._activeGroup?.model.activePanel,
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
 | 
					            this._onDidActivePanelChange.fire(
 | 
				
			||||||
 | 
					                this._activeGroup?.model.activePanel
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -677,24 +659,25 @@ export class DockviewComponent
 | 
				
			|||||||
                                kind: GroupChangeKind.ADD_PANEL,
 | 
					                                kind: GroupChangeKind.ADD_PANEL,
 | 
				
			||||||
                                panel: event.panel,
 | 
					                                panel: event.panel,
 | 
				
			||||||
                            });
 | 
					                            });
 | 
				
			||||||
                            break;
 | 
					                            if (event.panel) {
 | 
				
			||||||
                        case GroupChangeKind2.GROUP_ACTIVE:
 | 
					                                this._onDidAddPanel.fire(event.panel);
 | 
				
			||||||
                            this._onGridEvent.fire({
 | 
					                            }
 | 
				
			||||||
                                kind: GroupChangeKind.GROUP_ACTIVE,
 | 
					 | 
				
			||||||
                                panel: event.panel,
 | 
					 | 
				
			||||||
                            });
 | 
					 | 
				
			||||||
                            break;
 | 
					                            break;
 | 
				
			||||||
                        case GroupChangeKind2.REMOVE_PANEL:
 | 
					                        case GroupChangeKind2.REMOVE_PANEL:
 | 
				
			||||||
                            this._onGridEvent.fire({
 | 
					                            this._onGridEvent.fire({
 | 
				
			||||||
                                kind: GroupChangeKind.REMOVE_PANEL,
 | 
					                                kind: GroupChangeKind.REMOVE_PANEL,
 | 
				
			||||||
                                panel: event.panel,
 | 
					                                panel: event.panel,
 | 
				
			||||||
                            });
 | 
					                            });
 | 
				
			||||||
 | 
					                            if (event.panel) {
 | 
				
			||||||
 | 
					                                this._onDidRemovePanel.fire(event.panel);
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
                            break;
 | 
					                            break;
 | 
				
			||||||
                        case GroupChangeKind2.PANEL_ACTIVE:
 | 
					                        case GroupChangeKind2.PANEL_ACTIVE:
 | 
				
			||||||
                            this._onGridEvent.fire({
 | 
					                            this._onGridEvent.fire({
 | 
				
			||||||
                                kind: GroupChangeKind.PANEL_ACTIVE,
 | 
					                                kind: GroupChangeKind.PANEL_ACTIVE,
 | 
				
			||||||
                                panel: event.panel,
 | 
					                                panel: event.panel,
 | 
				
			||||||
                            });
 | 
					                            });
 | 
				
			||||||
 | 
					                            this._onDidActivePanelChange.fire(event.panel);
 | 
				
			||||||
                            break;
 | 
					                            break;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                })
 | 
					                })
 | 
				
			||||||
@ -732,7 +715,6 @@ export class DockviewComponent
 | 
				
			|||||||
            params: options?.params || {},
 | 
					            params: options?.params || {},
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.registerPanel(panel);
 | 
					 | 
				
			||||||
        return panel;
 | 
					        return panel;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -778,4 +760,12 @@ export class DockviewComponent
 | 
				
			|||||||
            group.value.model.containsPanel(panel)
 | 
					            group.value.model.containsPanel(panel)
 | 
				
			||||||
        )?.value;
 | 
					        )?.value;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public dispose(): void {
 | 
				
			||||||
 | 
					        super.dispose();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this._onDidActivePanelChange.dispose();
 | 
				
			||||||
 | 
					        this._onDidAddPanel.dispose();
 | 
				
			||||||
 | 
					        this._onDidRemovePanel.dispose();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,3 @@
 | 
				
			|||||||
import { GroupChangeKind2 } from '../groupview/groupview';
 | 
					 | 
				
			||||||
import { DockviewApi } from '../api/component.api';
 | 
					import { DockviewApi } from '../api/component.api';
 | 
				
			||||||
import { DockviewPanelApiImpl } from '../api/groupPanelApi';
 | 
					import { DockviewPanelApiImpl } from '../api/groupPanelApi';
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
@ -147,20 +146,6 @@ export class DockviewGroupPanel
 | 
				
			|||||||
        this._group = group;
 | 
					        this._group = group;
 | 
				
			||||||
        this.api.group = group;
 | 
					        this.api.group = group;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.mutableDisposable.value = this._group.model.onDidGroupChange(
 | 
					 | 
				
			||||||
            (ev) => {
 | 
					 | 
				
			||||||
                if (ev.kind === GroupChangeKind2.GROUP_ACTIVE) {
 | 
					 | 
				
			||||||
                    const isVisible = !!this._group?.model.isPanelActive(this);
 | 
					 | 
				
			||||||
                    this.api._onDidActiveChange.fire({
 | 
					 | 
				
			||||||
                        isActive: isGroupActive && isVisible,
 | 
					 | 
				
			||||||
                    });
 | 
					 | 
				
			||||||
                    this.api._onDidVisibilityChange.fire({
 | 
					 | 
				
			||||||
                        isVisible,
 | 
					 | 
				
			||||||
                    });
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        const isPanelVisible = this._group.model.isPanelActive(this);
 | 
					        const isPanelVisible = this._group.model.isPanelActive(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.api._onDidActiveChange.fire({
 | 
					        this.api._onDidActiveChange.fire({
 | 
				
			||||||
 | 
				
			|||||||
@ -74,6 +74,9 @@ export interface IBaseGrid<T extends IGridPanelView> {
 | 
				
			|||||||
    readonly groups: T[];
 | 
					    readonly groups: T[];
 | 
				
			||||||
    readonly onGridEvent: Event<GroupChangeEvent>;
 | 
					    readonly onGridEvent: Event<GroupChangeEvent>;
 | 
				
			||||||
    readonly onDidLayoutChange: Event<void>;
 | 
					    readonly onDidLayoutChange: Event<void>;
 | 
				
			||||||
 | 
					    readonly onDidRemoveGroup: Event<T>;
 | 
				
			||||||
 | 
					    readonly onDidAddGroup: Event<T>;
 | 
				
			||||||
 | 
					    readonly onDidActiveGroupChange: Event<T | undefined>;
 | 
				
			||||||
    getPanel(id: string): T | undefined;
 | 
					    getPanel(id: string): T | undefined;
 | 
				
			||||||
    toJSON(): object;
 | 
					    toJSON(): object;
 | 
				
			||||||
    fromJSON(data: any): void;
 | 
					    fromJSON(data: any): void;
 | 
				
			||||||
@ -99,6 +102,16 @@ export abstract class BaseGrid<T extends IGridPanelView>
 | 
				
			|||||||
    private _onDidLayoutChange = new Emitter<void>();
 | 
					    private _onDidLayoutChange = new Emitter<void>();
 | 
				
			||||||
    readonly onDidLayoutChange = this._onDidLayoutChange.event;
 | 
					    readonly onDidLayoutChange = this._onDidLayoutChange.event;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private readonly _onDidRemoveGroup = new Emitter<T>();
 | 
				
			||||||
 | 
					    readonly onDidRemoveGroup: Event<T> = this._onDidRemoveGroup.event;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private readonly _onDidAddGroup = new Emitter<T>();
 | 
				
			||||||
 | 
					    readonly onDidAddGroup: Event<T> = this._onDidAddGroup.event;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private readonly _onDidActiveGroupChange = new Emitter<T | undefined>();
 | 
				
			||||||
 | 
					    readonly onDidActiveGroupChange: Event<T | undefined> =
 | 
				
			||||||
 | 
					        this._onDidActiveGroupChange.event;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    get id() {
 | 
					    get id() {
 | 
				
			||||||
        return this._id;
 | 
					        return this._id;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -154,8 +167,7 @@ export abstract class BaseGrid<T extends IGridPanelView>
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        this.element.appendChild(this.gridview.element);
 | 
					        this.element.appendChild(this.gridview.element);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // TODO for some reason this is required before anything will layout correctly
 | 
					        this.layout(0, 0, true); // set some elements height/widths
 | 
				
			||||||
        this.layout(0, 0, true);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.addDisposables(
 | 
					        this.addDisposables(
 | 
				
			||||||
            this.gridview.onDidChange(() => {
 | 
					            this.gridview.onDidChange(() => {
 | 
				
			||||||
@ -209,6 +221,7 @@ export abstract class BaseGrid<T extends IGridPanelView>
 | 
				
			|||||||
        this.gridview.addView(group, size ?? Sizing.Distribute, location);
 | 
					        this.gridview.addView(group, size ?? Sizing.Distribute, location);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this._onGridEvent.fire({ kind: GroupChangeKind.ADD_GROUP });
 | 
					        this._onGridEvent.fire({ kind: GroupChangeKind.ADD_GROUP });
 | 
				
			||||||
 | 
					        this._onDidAddGroup.fire(group);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.doSetGroupActive(group);
 | 
					        this.doSetGroupActive(group);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -231,6 +244,7 @@ export abstract class BaseGrid<T extends IGridPanelView>
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this._onGridEvent.fire({ kind: GroupChangeKind.REMOVE_GROUP });
 | 
					        this._onGridEvent.fire({ kind: GroupChangeKind.REMOVE_GROUP });
 | 
				
			||||||
 | 
					        this._onDidRemoveGroup.fire(group);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!options?.skipActive && this._activeGroup === group) {
 | 
					        if (!options?.skipActive && this._activeGroup === group) {
 | 
				
			||||||
            const groups = Array.from(this._groups.values());
 | 
					            const groups = Array.from(this._groups.values());
 | 
				
			||||||
@ -270,6 +284,7 @@ export abstract class BaseGrid<T extends IGridPanelView>
 | 
				
			|||||||
        this._onGridEvent.fire({
 | 
					        this._onGridEvent.fire({
 | 
				
			||||||
            kind: GroupChangeKind.GROUP_ACTIVE,
 | 
					            kind: GroupChangeKind.GROUP_ACTIVE,
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					        this._onDidActiveGroupChange.fire(group);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public removeGroup(group: T) {
 | 
					    public removeGroup(group: T) {
 | 
				
			||||||
@ -338,6 +353,11 @@ export abstract class BaseGrid<T extends IGridPanelView>
 | 
				
			|||||||
        super.dispose();
 | 
					        super.dispose();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this._onGridEvent.dispose();
 | 
					        this._onGridEvent.dispose();
 | 
				
			||||||
 | 
					        this._onDidActiveGroupChange.dispose();
 | 
				
			||||||
 | 
					        this._onDidAddGroup.dispose();
 | 
				
			||||||
 | 
					        this._onDidRemoveGroup.dispose();
 | 
				
			||||||
 | 
					        this._onDidLayoutChange.dispose();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.gridview.dispose();
 | 
					        this.gridview.dispose();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -17,6 +17,19 @@ import { Node } from './types';
 | 
				
			|||||||
import { Emitter, Event } from '../events';
 | 
					import { Emitter, Event } from '../events';
 | 
				
			||||||
import { IDisposable, MutableDisposable } from '../lifecycle';
 | 
					import { IDisposable, MutableDisposable } from '../lifecycle';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function findLeaf(candiateNode: Node, last: boolean): LeafNode {
 | 
				
			||||||
 | 
					    if (candiateNode instanceof LeafNode) {
 | 
				
			||||||
 | 
					        return candiateNode;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (candiateNode instanceof BranchNode) {
 | 
				
			||||||
 | 
					        return findLeaf(
 | 
				
			||||||
 | 
					            candiateNode.children[last ? candiateNode.children.length - 1 : 0],
 | 
				
			||||||
 | 
					            last
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    throw new Error('invalid node');
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function flipNode<T extends Node>(
 | 
					function flipNode<T extends Node>(
 | 
				
			||||||
    node: T,
 | 
					    node: T,
 | 
				
			||||||
    size: number,
 | 
					    size: number,
 | 
				
			||||||
@ -289,7 +302,8 @@ export class Gridview implements IDisposable {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public deserialize(json: any, deserializer: IViewDeserializer) {
 | 
					    public deserialize(json: any, deserializer: IViewDeserializer) {
 | 
				
			||||||
        const orientation = json.orientation;
 | 
					        const orientation = json.orientation;
 | 
				
			||||||
        const height = json.height;
 | 
					        const height =
 | 
				
			||||||
 | 
					            orientation === Orientation.VERTICAL ? json.height : json.width;
 | 
				
			||||||
        this._deserialize(
 | 
					        this._deserialize(
 | 
				
			||||||
            json.root as ISerializedBranchNode,
 | 
					            json.root as ISerializedBranchNode,
 | 
				
			||||||
            orientation,
 | 
					            orientation,
 | 
				
			||||||
@ -308,7 +322,8 @@ export class Gridview implements IDisposable {
 | 
				
			|||||||
            root,
 | 
					            root,
 | 
				
			||||||
            orientation,
 | 
					            orientation,
 | 
				
			||||||
            deserializer,
 | 
					            deserializer,
 | 
				
			||||||
            orthogonalSize
 | 
					            orthogonalSize,
 | 
				
			||||||
 | 
					            true
 | 
				
			||||||
        ) as BranchNode;
 | 
					        ) as BranchNode;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -316,7 +331,8 @@ export class Gridview implements IDisposable {
 | 
				
			|||||||
        node: ISerializedNode,
 | 
					        node: ISerializedNode,
 | 
				
			||||||
        orientation: Orientation,
 | 
					        orientation: Orientation,
 | 
				
			||||||
        deserializer: IViewDeserializer,
 | 
					        deserializer: IViewDeserializer,
 | 
				
			||||||
        orthogonalSize: number
 | 
					        orthogonalSize: number,
 | 
				
			||||||
 | 
					        isRoot = false
 | 
				
			||||||
    ): Node {
 | 
					    ): Node {
 | 
				
			||||||
        let result: Node;
 | 
					        let result: Node;
 | 
				
			||||||
        if (node.type === 'branch') {
 | 
					        if (node.type === 'branch') {
 | 
				
			||||||
@ -333,12 +349,14 @@ export class Gridview implements IDisposable {
 | 
				
			|||||||
                } as INodeDescriptor;
 | 
					                } as INodeDescriptor;
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // HORIZONTAL => height=orthogonalsize width=size
 | 
				
			||||||
 | 
					            // VERTICAL => height=size width=orthogonalsize
 | 
				
			||||||
            result = new BranchNode(
 | 
					            result = new BranchNode(
 | 
				
			||||||
                orientation,
 | 
					                orientation,
 | 
				
			||||||
                this.proportionalLayout,
 | 
					                this.proportionalLayout,
 | 
				
			||||||
                this.styles,
 | 
					                this.styles,
 | 
				
			||||||
                node.size,
 | 
					                isRoot ? orthogonalSize : node.size,
 | 
				
			||||||
                orthogonalSize,
 | 
					                isRoot ? node.size : orthogonalSize,
 | 
				
			||||||
                children
 | 
					                children
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
@ -437,21 +455,6 @@ export class Gridview implements IDisposable {
 | 
				
			|||||||
            throw new Error('invalid location');
 | 
					            throw new Error('invalid location');
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const findLeaf = (candiateNode: Node, last: boolean): LeafNode => {
 | 
					 | 
				
			||||||
            if (candiateNode instanceof LeafNode) {
 | 
					 | 
				
			||||||
                return candiateNode;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            if (candiateNode instanceof BranchNode) {
 | 
					 | 
				
			||||||
                return findLeaf(
 | 
					 | 
				
			||||||
                    candiateNode.children[
 | 
					 | 
				
			||||||
                        last ? candiateNode.children.length - 1 : 0
 | 
					 | 
				
			||||||
                    ],
 | 
					 | 
				
			||||||
                    last
 | 
					 | 
				
			||||||
                );
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            throw new Error('invalid node');
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        for (let i = path.length - 1; i > -1; i--) {
 | 
					        for (let i = path.length - 1; i > -1; i--) {
 | 
				
			||||||
            const n = path[i];
 | 
					            const n = path[i];
 | 
				
			||||||
            const l = location[i] || 0;
 | 
					            const l = location[i] || 0;
 | 
				
			||||||
 | 
				
			|||||||
@ -19,7 +19,6 @@ export enum GroupChangeKind2 {
 | 
				
			|||||||
    ADD_PANEL = 'ADD_PANEL',
 | 
					    ADD_PANEL = 'ADD_PANEL',
 | 
				
			||||||
    REMOVE_PANEL = 'REMOVE_PANEL',
 | 
					    REMOVE_PANEL = 'REMOVE_PANEL',
 | 
				
			||||||
    PANEL_ACTIVE = 'PANEL_ACTIVE',
 | 
					    PANEL_ACTIVE = 'PANEL_ACTIVE',
 | 
				
			||||||
    GROUP_ACTIVE = 'GROUP_ACTIVE',
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface DndService {
 | 
					export interface DndService {
 | 
				
			||||||
@ -365,6 +364,10 @@ export class Groupview extends CompositeDisposable implements IGroupview {
 | 
				
			|||||||
        ) {
 | 
					        ) {
 | 
				
			||||||
            options.index = this.panels.length;
 | 
					            options.index = this.panels.length;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // ensure the group is updated before we fire any events
 | 
				
			||||||
 | 
					        panel.updateParentGroup(this.parent, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (this._activePanel === panel) {
 | 
					        if (this._activePanel === panel) {
 | 
				
			||||||
            this.accessor.doSetGroupActive(this.parent);
 | 
					            this.accessor.doSetGroupActive(this.parent);
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
 | 
				
			|||||||
@ -5,7 +5,7 @@ import {
 | 
				
			|||||||
    PaneTransfer,
 | 
					    PaneTransfer,
 | 
				
			||||||
} from '../dnd/dataTransfer';
 | 
					} from '../dnd/dataTransfer';
 | 
				
			||||||
import { Droptarget, DroptargetEvent, Position } from '../dnd/droptarget';
 | 
					import { Droptarget, DroptargetEvent, Position } from '../dnd/droptarget';
 | 
				
			||||||
import { Emitter, Event } from '../events';
 | 
					import { Emitter } from '../events';
 | 
				
			||||||
import { IDisposable } from '../lifecycle';
 | 
					import { IDisposable } from '../lifecycle';
 | 
				
			||||||
import { Orientation } from '../splitview/core/splitview';
 | 
					import { Orientation } from '../splitview/core/splitview';
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
@ -14,23 +14,6 @@ import {
 | 
				
			|||||||
    PaneviewPanel,
 | 
					    PaneviewPanel,
 | 
				
			||||||
} from './paneviewPanel';
 | 
					} from './paneviewPanel';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface ViewContainer {
 | 
					 | 
				
			||||||
    readonly title: string;
 | 
					 | 
				
			||||||
    readonly icon: string;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
interface ViewContainerModel {
 | 
					 | 
				
			||||||
    readonly title: string;
 | 
					 | 
				
			||||||
    readonly icon: string;
 | 
					 | 
				
			||||||
    readonly onDidAdd: Event<void>;
 | 
					 | 
				
			||||||
    readonly onDidRemove: Event<void>;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
interface IViewContainerService {
 | 
					 | 
				
			||||||
    getViewContainerById(id: string): ViewContainer;
 | 
					 | 
				
			||||||
    getViewContainerModel(container: ViewContainer): ViewContainerModel;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export interface PaneviewDropEvent2 extends DroptargetEvent {
 | 
					export interface PaneviewDropEvent2 extends DroptargetEvent {
 | 
				
			||||||
    panel: IPaneviewPanel;
 | 
					    panel: IPaneviewPanel;
 | 
				
			||||||
    getData: () => PaneTransfer | undefined;
 | 
					    getData: () => PaneTransfer | undefined;
 | 
				
			||||||
@ -101,6 +84,12 @@ export abstract class DraggablePaneviewPanel extends PaneviewPanel {
 | 
				
			|||||||
            this.handler,
 | 
					            this.handler,
 | 
				
			||||||
            this.target,
 | 
					            this.target,
 | 
				
			||||||
            this.target.onDrop((event) => {
 | 
					            this.target.onDrop((event) => {
 | 
				
			||||||
 | 
					                this.onDrop(event);
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private onDrop(event: DroptargetEvent) {
 | 
				
			||||||
        const data = getPaneData();
 | 
					        const data = getPaneData();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!data) {
 | 
					        if (!data) {
 | 
				
			||||||
@ -148,7 +137,5 @@ export abstract class DraggablePaneviewPanel extends PaneviewPanel {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        containerApi.movePanel(fromIndex, toIndex);
 | 
					        containerApi.movePanel(fromIndex, toIndex);
 | 
				
			||||||
            })
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user