mirror of
https://github.com/mathuo/dockview
synced 2025-05-09 13:08:31 +00:00
refactor: simplify dnd control
This commit is contained in:
parent
321f78ec0e
commit
3052857dfc
@ -3,9 +3,7 @@ import {
|
|||||||
calculateQuadrantAsPixels,
|
calculateQuadrantAsPixels,
|
||||||
directionToPosition,
|
directionToPosition,
|
||||||
Droptarget,
|
Droptarget,
|
||||||
DropTargetDirections,
|
|
||||||
Position,
|
Position,
|
||||||
Quadrant,
|
|
||||||
} from '../../dnd/droptarget';
|
} from '../../dnd/droptarget';
|
||||||
import { fireEvent } from '@testing-library/dom';
|
import { fireEvent } from '@testing-library/dom';
|
||||||
|
|
||||||
@ -36,11 +34,11 @@ describe('droptarget', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('directionToPosition', () => {
|
test('directionToPosition', () => {
|
||||||
expect(directionToPosition('above')).toBe(Position.Top);
|
expect(directionToPosition('above')).toBe('top');
|
||||||
expect(directionToPosition('below')).toBe(Position.Bottom);
|
expect(directionToPosition('below')).toBe('bottom');
|
||||||
expect(directionToPosition('left')).toBe(Position.Left);
|
expect(directionToPosition('left')).toBe('left');
|
||||||
expect(directionToPosition('right')).toBe(Position.Right);
|
expect(directionToPosition('right')).toBe('right');
|
||||||
expect(directionToPosition('within')).toBe(Position.Center);
|
expect(directionToPosition('within')).toBe('center');
|
||||||
expect(() => directionToPosition('bad_input' as any)).toThrow(
|
expect(() => directionToPosition('bad_input' as any)).toThrow(
|
||||||
"invalid direction 'bad_input'"
|
"invalid direction 'bad_input'"
|
||||||
);
|
);
|
||||||
@ -65,7 +63,7 @@ describe('droptarget', () => {
|
|||||||
'.drop-target-dropzone'
|
'.drop-target-dropzone'
|
||||||
) as HTMLElement;
|
) as HTMLElement;
|
||||||
fireEvent.drop(target);
|
fireEvent.drop(target);
|
||||||
expect(position).toBe(Position.Center);
|
expect(position).toBe('center');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('drop', () => {
|
test('drop', () => {
|
||||||
@ -100,7 +98,7 @@ describe('droptarget', () => {
|
|||||||
|
|
||||||
expect(position).toBeUndefined();
|
expect(position).toBeUndefined();
|
||||||
fireEvent.drop(target);
|
fireEvent.drop(target);
|
||||||
expect(position).toBe(Position.Left);
|
expect(position).toBe('left');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('default', () => {
|
test('default', () => {
|
||||||
@ -135,7 +133,7 @@ describe('droptarget', () => {
|
|||||||
'.drop-target > .drop-target-dropzone > .drop-target-selection'
|
'.drop-target > .drop-target-dropzone > .drop-target-selection'
|
||||||
);
|
);
|
||||||
expect(viewQuery.length).toBe(1);
|
expect(viewQuery.length).toBe(1);
|
||||||
expect(droptarget.state).toBe(Position.Left);
|
expect(droptarget.state).toBe('left');
|
||||||
expect(
|
expect(
|
||||||
(
|
(
|
||||||
element
|
element
|
||||||
@ -153,7 +151,7 @@ describe('droptarget', () => {
|
|||||||
'.drop-target > .drop-target-dropzone > .drop-target-selection'
|
'.drop-target > .drop-target-dropzone > .drop-target-selection'
|
||||||
);
|
);
|
||||||
expect(viewQuery.length).toBe(1);
|
expect(viewQuery.length).toBe(1);
|
||||||
expect(droptarget.state).toBe(Position.Top);
|
expect(droptarget.state).toBe('top');
|
||||||
expect(
|
expect(
|
||||||
(
|
(
|
||||||
element
|
element
|
||||||
@ -171,7 +169,7 @@ describe('droptarget', () => {
|
|||||||
'.drop-target > .drop-target-dropzone > .drop-target-selection'
|
'.drop-target > .drop-target-dropzone > .drop-target-selection'
|
||||||
);
|
);
|
||||||
expect(viewQuery.length).toBe(1);
|
expect(viewQuery.length).toBe(1);
|
||||||
expect(droptarget.state).toBe(Position.Bottom);
|
expect(droptarget.state).toBe('bottom');
|
||||||
expect(
|
expect(
|
||||||
(
|
(
|
||||||
element
|
element
|
||||||
@ -189,7 +187,7 @@ describe('droptarget', () => {
|
|||||||
'.drop-target > .drop-target-dropzone > .drop-target-selection'
|
'.drop-target > .drop-target-dropzone > .drop-target-selection'
|
||||||
);
|
);
|
||||||
expect(viewQuery.length).toBe(1);
|
expect(viewQuery.length).toBe(1);
|
||||||
expect(droptarget.state).toBe(Position.Right);
|
expect(droptarget.state).toBe('right');
|
||||||
expect(
|
expect(
|
||||||
(
|
(
|
||||||
element
|
element
|
||||||
@ -202,7 +200,7 @@ describe('droptarget', () => {
|
|||||||
target,
|
target,
|
||||||
createOffsetDragOverEvent({ clientX: 100, clientY: 50 })
|
createOffsetDragOverEvent({ clientX: 100, clientY: 50 })
|
||||||
);
|
);
|
||||||
expect(droptarget.state).toBe(Position.Center);
|
expect(droptarget.state).toBe('center');
|
||||||
expect(
|
expect(
|
||||||
(
|
(
|
||||||
element
|
element
|
||||||
@ -212,7 +210,7 @@ describe('droptarget', () => {
|
|||||||
).toBe('');
|
).toBe('');
|
||||||
|
|
||||||
fireEvent.dragLeave(target);
|
fireEvent.dragLeave(target);
|
||||||
expect(droptarget.state).toBe(Position.Center);
|
expect(droptarget.state).toBe('center');
|
||||||
viewQuery = element.querySelectorAll('.drop-target');
|
viewQuery = element.querySelectorAll('.drop-target');
|
||||||
expect(viewQuery.length).toBe(0);
|
expect(viewQuery.length).toBe(0);
|
||||||
});
|
});
|
||||||
@ -220,10 +218,10 @@ describe('droptarget', () => {
|
|||||||
describe('calculateQuadrantAsPercentage', () => {
|
describe('calculateQuadrantAsPercentage', () => {
|
||||||
test('variety of cases', () => {
|
test('variety of cases', () => {
|
||||||
const inputs: Array<{
|
const inputs: Array<{
|
||||||
directions: DropTargetDirections[];
|
directions: Position[];
|
||||||
x: number;
|
x: number;
|
||||||
y: number;
|
y: number;
|
||||||
result: Quadrant | null | undefined;
|
result: Position | null;
|
||||||
}> = [
|
}> = [
|
||||||
{ directions: ['left', 'right'], x: 19, y: 50, result: 'left' },
|
{ directions: ['left', 'right'], x: 19, y: 50, result: 'left' },
|
||||||
{
|
{
|
||||||
@ -248,13 +246,13 @@ describe('droptarget', () => {
|
|||||||
directions: ['left', 'right', 'top', 'bottom', 'center'],
|
directions: ['left', 'right', 'top', 'bottom', 'center'],
|
||||||
x: 50,
|
x: 50,
|
||||||
y: 50,
|
y: 50,
|
||||||
result: null,
|
result: 'center',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
directions: ['left', 'right', 'top', 'bottom'],
|
directions: ['left', 'right', 'top', 'bottom'],
|
||||||
x: 50,
|
x: 50,
|
||||||
y: 50,
|
y: 50,
|
||||||
result: undefined,
|
result: null,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -276,10 +274,10 @@ describe('droptarget', () => {
|
|||||||
describe('calculateQuadrantAsPixels', () => {
|
describe('calculateQuadrantAsPixels', () => {
|
||||||
test('variety of cases', () => {
|
test('variety of cases', () => {
|
||||||
const inputs: Array<{
|
const inputs: Array<{
|
||||||
directions: DropTargetDirections[];
|
directions: Position[];
|
||||||
x: number;
|
x: number;
|
||||||
y: number;
|
y: number;
|
||||||
result: Quadrant | null | undefined;
|
result: Position | null;
|
||||||
}> = [
|
}> = [
|
||||||
{ directions: ['left', 'right'], x: 19, y: 50, result: 'left' },
|
{ directions: ['left', 'right'], x: 19, y: 50, result: 'left' },
|
||||||
{
|
{
|
||||||
@ -304,13 +302,13 @@ describe('droptarget', () => {
|
|||||||
directions: ['left', 'right', 'top', 'bottom', 'center'],
|
directions: ['left', 'right', 'top', 'bottom', 'center'],
|
||||||
x: 50,
|
x: 50,
|
||||||
y: 50,
|
y: 50,
|
||||||
result: null,
|
result: 'center',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
directions: ['left', 'right', 'top', 'bottom'],
|
directions: ['left', 'right', 'top', 'bottom'],
|
||||||
x: 50,
|
x: 50,
|
||||||
y: 50,
|
y: 50,
|
||||||
result: undefined,
|
result: null,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -253,9 +253,9 @@ describe('dockviewComponent', () => {
|
|||||||
const panel4 = dockview.getGroupPanel('panel4');
|
const panel4 = dockview.getGroupPanel('panel4');
|
||||||
|
|
||||||
const group1 = panel1!.group;
|
const group1 = panel1!.group;
|
||||||
dockview.moveGroupOrPanel(group1, group1.id, 'panel1', Position.Right);
|
dockview.moveGroupOrPanel(group1, group1.id, 'panel1', 'right');
|
||||||
const group2 = panel1!.group;
|
const group2 = panel1!.group;
|
||||||
dockview.moveGroupOrPanel(group2, group1.id, 'panel3', Position.Center);
|
dockview.moveGroupOrPanel(group2, group1.id, 'panel3', 'center');
|
||||||
|
|
||||||
expect(dockview.activeGroup).toBe(group2);
|
expect(dockview.activeGroup).toBe(group2);
|
||||||
expect(dockview.activeGroup!.model.activePanel).toBe(panel3);
|
expect(dockview.activeGroup!.model.activePanel).toBe(panel3);
|
||||||
@ -305,9 +305,9 @@ describe('dockviewComponent', () => {
|
|||||||
const panel1 = dockview.getGroupPanel('panel1')!;
|
const panel1 = dockview.getGroupPanel('panel1')!;
|
||||||
const panel2 = dockview.getGroupPanel('panel2')!;
|
const panel2 = dockview.getGroupPanel('panel2')!;
|
||||||
const group1 = panel1.group;
|
const group1 = panel1.group;
|
||||||
dockview.moveGroupOrPanel(group1, group1.id, 'panel1', Position.Right);
|
dockview.moveGroupOrPanel(group1, group1.id, 'panel1', 'right');
|
||||||
const group2 = panel1.group;
|
const group2 = panel1.group;
|
||||||
dockview.moveGroupOrPanel(group2, group1.id, 'panel3', Position.Center);
|
dockview.moveGroupOrPanel(group2, group1.id, 'panel3', 'center');
|
||||||
|
|
||||||
expect(dockview.size).toBe(2);
|
expect(dockview.size).toBe(2);
|
||||||
expect(dockview.totalPanels).toBe(4);
|
expect(dockview.totalPanels).toBe(4);
|
||||||
@ -370,9 +370,9 @@ describe('dockviewComponent', () => {
|
|||||||
expect(panel4.api.isActive).toBeFalsy();
|
expect(panel4.api.isActive).toBeFalsy();
|
||||||
|
|
||||||
const group1 = panel1.group;
|
const group1 = panel1.group;
|
||||||
dockview.moveGroupOrPanel(group1, group1.id, 'panel1', Position.Right);
|
dockview.moveGroupOrPanel(group1, group1.id, 'panel1', 'right');
|
||||||
const group2 = panel1.group;
|
const group2 = panel1.group;
|
||||||
dockview.moveGroupOrPanel(group2, group1.id, 'panel3', Position.Center);
|
dockview.moveGroupOrPanel(group2, group1.id, 'panel3', 'center');
|
||||||
|
|
||||||
expect(dockview.size).toBe(2);
|
expect(dockview.size).toBe(2);
|
||||||
expect(panel1.group).toBe(panel3.group);
|
expect(panel1.group).toBe(panel3.group);
|
||||||
@ -439,7 +439,7 @@ describe('dockviewComponent', () => {
|
|||||||
expect(group.model.indexOf(panel1)).toBe(0);
|
expect(group.model.indexOf(panel1)).toBe(0);
|
||||||
expect(group.model.indexOf(panel2)).toBe(1);
|
expect(group.model.indexOf(panel2)).toBe(1);
|
||||||
|
|
||||||
dockview.moveGroupOrPanel(group, group.id, 'panel1', Position.Right);
|
dockview.moveGroupOrPanel(group, group.id, 'panel1', 'right');
|
||||||
|
|
||||||
expect(dockview.size).toBe(2);
|
expect(dockview.size).toBe(2);
|
||||||
expect(dockview.totalPanels).toBe(2);
|
expect(dockview.totalPanels).toBe(2);
|
||||||
@ -489,7 +489,7 @@ describe('dockviewComponent', () => {
|
|||||||
expect(viewQuery.length).toBe(1);
|
expect(viewQuery.length).toBe(1);
|
||||||
|
|
||||||
const group = dockview.getGroupPanel('panel1')!.group;
|
const group = dockview.getGroupPanel('panel1')!.group;
|
||||||
dockview.moveGroupOrPanel(group, group.id, 'panel1', Position.Right);
|
dockview.moveGroupOrPanel(group, group.id, 'panel1', 'right');
|
||||||
|
|
||||||
viewQuery = container.querySelectorAll(
|
viewQuery = container.querySelectorAll(
|
||||||
'.branch-node > .split-view-container > .view-container > .view'
|
'.branch-node > .split-view-container > .view-container > .view'
|
||||||
@ -974,7 +974,7 @@ describe('dockviewComponent', () => {
|
|||||||
panel2.group!,
|
panel2.group!,
|
||||||
panel5.group!.id,
|
panel5.group!.id,
|
||||||
panel5.id,
|
panel5.id,
|
||||||
Position.Center
|
'center'
|
||||||
);
|
);
|
||||||
expect(events).toEqual([
|
expect(events).toEqual([
|
||||||
{ type: 'REMOVE_PANEL', panel: panel5 },
|
{ type: 'REMOVE_PANEL', panel: panel5 },
|
||||||
@ -993,7 +993,7 @@ describe('dockviewComponent', () => {
|
|||||||
panel2.group!,
|
panel2.group!,
|
||||||
panel4.group!.id,
|
panel4.group!.id,
|
||||||
panel4.id,
|
panel4.id,
|
||||||
Position.Center
|
'center'
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(events).toEqual([
|
expect(events).toEqual([
|
||||||
@ -1313,7 +1313,7 @@ describe('dockviewComponent', () => {
|
|||||||
panel1.group,
|
panel1.group,
|
||||||
panel2.group.id,
|
panel2.group.id,
|
||||||
'panel2',
|
'panel2',
|
||||||
Position.Left
|
'left'
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(panel1Spy).not.toHaveBeenCalled();
|
expect(panel1Spy).not.toHaveBeenCalled();
|
||||||
@ -1354,7 +1354,7 @@ describe('dockviewComponent', () => {
|
|||||||
panel1.group,
|
panel1.group,
|
||||||
panel2.group.id,
|
panel2.group.id,
|
||||||
'panel2',
|
'panel2',
|
||||||
Position.Center
|
'center'
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(panel1Spy).not.toHaveBeenCalled();
|
expect(panel1Spy).not.toHaveBeenCalled();
|
||||||
@ -1393,7 +1393,7 @@ describe('dockviewComponent', () => {
|
|||||||
panel1.group,
|
panel1.group,
|
||||||
panel1.group.id,
|
panel1.group.id,
|
||||||
'panel1',
|
'panel1',
|
||||||
Position.Center,
|
'center',
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -1554,7 +1554,7 @@ describe('dockviewComponent', () => {
|
|||||||
panel3.group,
|
panel3.group,
|
||||||
panel1.group.id,
|
panel1.group.id,
|
||||||
undefined,
|
undefined,
|
||||||
Position.Center
|
'center'
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(dockview.groups.length).toBe(1);
|
expect(dockview.groups.length).toBe(1);
|
||||||
|
@ -730,7 +730,7 @@ describe('groupview', () => {
|
|||||||
).toBe(0);
|
).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('that should allow drop when not dropping on self for same component id', () => {
|
test('that should not allow drop when dropping on self for same component id', () => {
|
||||||
const accessorMock = jest.fn<Partial<DockviewComponent>, []>(() => {
|
const accessorMock = jest.fn<Partial<DockviewComponent>, []>(() => {
|
||||||
return {
|
return {
|
||||||
id: 'testcomponentid',
|
id: 'testcomponentid',
|
||||||
@ -792,7 +792,7 @@ describe('groupview', () => {
|
|||||||
|
|
||||||
expect(
|
expect(
|
||||||
element.getElementsByClassName('drop-target-dropzone').length
|
element.getElementsByClassName('drop-target-dropzone').length
|
||||||
).toBe(1);
|
).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('that should not allow drop when not dropping for different component id', () => {
|
test('that should not allow drop when not dropping for different component id', () => {
|
||||||
|
@ -9,44 +9,29 @@ function numberOrFallback(maybeNumber: any, fallback: number): number {
|
|||||||
return typeof maybeNumber === 'number' ? maybeNumber : fallback;
|
return typeof maybeNumber === 'number' ? maybeNumber : fallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum Position {
|
|
||||||
Top = 'Top',
|
|
||||||
Left = 'Left',
|
|
||||||
Bottom = 'Bottom',
|
|
||||||
Right = 'Right',
|
|
||||||
Center = 'Center',
|
|
||||||
}
|
|
||||||
|
|
||||||
export function directionToPosition(direction: Direction): Position {
|
export function directionToPosition(direction: Direction): Position {
|
||||||
switch (direction) {
|
switch (direction) {
|
||||||
case 'above':
|
case 'above':
|
||||||
return Position.Top;
|
return 'top';
|
||||||
case 'below':
|
case 'below':
|
||||||
return Position.Bottom;
|
return 'bottom';
|
||||||
case 'left':
|
case 'left':
|
||||||
return Position.Left;
|
return 'left';
|
||||||
case 'right':
|
case 'right':
|
||||||
return Position.Right;
|
return 'right';
|
||||||
case 'within':
|
case 'within':
|
||||||
return Position.Center;
|
return 'center';
|
||||||
default:
|
default:
|
||||||
throw new Error(`invalid direction '${direction}'`);
|
throw new Error(`invalid direction '${direction}'`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Quadrant = 'top' | 'bottom' | 'left' | 'right';
|
|
||||||
|
|
||||||
export interface DroptargetEvent {
|
export interface DroptargetEvent {
|
||||||
readonly position: Position;
|
readonly position: Position;
|
||||||
readonly nativeEvent: DragEvent;
|
readonly nativeEvent: DragEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type DropTargetDirections =
|
export type Position = 'top' | 'bottom' | 'left' | 'right' | 'center';
|
||||||
| 'top'
|
|
||||||
| 'bottom'
|
|
||||||
| 'left'
|
|
||||||
| 'right'
|
|
||||||
| 'center';
|
|
||||||
|
|
||||||
function isBooleanValue(
|
function isBooleanValue(
|
||||||
canDisplayOverlay: CanDisplayOverlay
|
canDisplayOverlay: CanDisplayOverlay
|
||||||
@ -56,7 +41,7 @@ function isBooleanValue(
|
|||||||
|
|
||||||
export type CanDisplayOverlay =
|
export type CanDisplayOverlay =
|
||||||
| boolean
|
| boolean
|
||||||
| ((dragEvent: DragEvent, state: Quadrant | null) => boolean);
|
| ((dragEvent: DragEvent, state: Position) => boolean);
|
||||||
|
|
||||||
export class Droptarget extends CompositeDisposable {
|
export class Droptarget extends CompositeDisposable {
|
||||||
private target: HTMLElement | undefined;
|
private target: HTMLElement | undefined;
|
||||||
@ -74,7 +59,7 @@ export class Droptarget extends CompositeDisposable {
|
|||||||
private readonly element: HTMLElement,
|
private readonly element: HTMLElement,
|
||||||
private readonly options: {
|
private readonly options: {
|
||||||
canDisplayOverlay: CanDisplayOverlay;
|
canDisplayOverlay: CanDisplayOverlay;
|
||||||
acceptedTargetZones: DropTargetDirections[];
|
acceptedTargetZones: Position[];
|
||||||
overlayModel?: {
|
overlayModel?: {
|
||||||
size?: { value: number; type: 'pixels' | 'percentage' };
|
size?: { value: number; type: 'pixels' | 'percentage' };
|
||||||
activationSize?: {
|
activationSize?: {
|
||||||
@ -117,7 +102,7 @@ export class Droptarget extends CompositeDisposable {
|
|||||||
height
|
height
|
||||||
);
|
);
|
||||||
|
|
||||||
if (quadrant === undefined) {
|
if (quadrant === null) {
|
||||||
this.removeDropTarget();
|
this.removeDropTarget();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -135,7 +120,7 @@ export class Droptarget extends CompositeDisposable {
|
|||||||
this.target.className = 'drop-target-dropzone';
|
this.target.className = 'drop-target-dropzone';
|
||||||
this.overlay = document.createElement('div');
|
this.overlay = document.createElement('div');
|
||||||
this.overlay.className = 'drop-target-selection';
|
this.overlay.className = 'drop-target-selection';
|
||||||
this._state = Position.Center;
|
this._state = 'center';
|
||||||
this.target.appendChild(this.overlay);
|
this.target.appendChild(this.overlay);
|
||||||
|
|
||||||
this.element.classList.add('drop-target');
|
this.element.classList.add('drop-target');
|
||||||
@ -181,7 +166,7 @@ export class Droptarget extends CompositeDisposable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private toggleClasses(
|
private toggleClasses(
|
||||||
quadrant: Quadrant | null,
|
quadrant: Position,
|
||||||
width: number,
|
width: number,
|
||||||
height: number
|
height: number
|
||||||
): void {
|
): void {
|
||||||
@ -246,33 +231,33 @@ export class Droptarget extends CompositeDisposable {
|
|||||||
toggleClass(this.overlay, 'small-bottom', isSmallY && isBottom);
|
toggleClass(this.overlay, 'small-bottom', isSmallY && isBottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
private setState(quadrant: Quadrant | null): void {
|
private setState(quadrant: Position): void {
|
||||||
switch (quadrant) {
|
switch (quadrant) {
|
||||||
case 'top':
|
case 'top':
|
||||||
this._state = Position.Top;
|
this._state = 'top';
|
||||||
break;
|
break;
|
||||||
case 'left':
|
case 'left':
|
||||||
this._state = Position.Left;
|
this._state = 'left';
|
||||||
break;
|
break;
|
||||||
case 'bottom':
|
case 'bottom':
|
||||||
this._state = Position.Bottom;
|
this._state = 'bottom';
|
||||||
break;
|
break;
|
||||||
case 'right':
|
case 'right':
|
||||||
this._state = Position.Right;
|
this._state = 'right';
|
||||||
break;
|
break;
|
||||||
default:
|
case 'center':
|
||||||
this._state = Position.Center;
|
this._state = 'center';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private calculateQuadrant(
|
private calculateQuadrant(
|
||||||
overlayType: Set<DropTargetDirections>,
|
overlayType: Set<Position>,
|
||||||
x: number,
|
x: number,
|
||||||
y: number,
|
y: number,
|
||||||
width: number,
|
width: number,
|
||||||
height: number
|
height: number
|
||||||
): Quadrant | null | undefined {
|
): Position | null {
|
||||||
const isPercentage =
|
const isPercentage =
|
||||||
this.options.overlayModel?.activationSize === undefined ||
|
this.options.overlayModel?.activationSize === undefined ||
|
||||||
this.options.overlayModel?.activationSize?.type === 'percentage';
|
this.options.overlayModel?.activationSize?.type === 'percentage';
|
||||||
@ -315,13 +300,13 @@ export class Droptarget extends CompositeDisposable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function calculateQuadrantAsPercentage(
|
export function calculateQuadrantAsPercentage(
|
||||||
overlayType: Set<DropTargetDirections>,
|
overlayType: Set<Position>,
|
||||||
x: number,
|
x: number,
|
||||||
y: number,
|
y: number,
|
||||||
width: number,
|
width: number,
|
||||||
height: number,
|
height: number,
|
||||||
threshold: number
|
threshold: number
|
||||||
): Quadrant | null | undefined {
|
): Position | null {
|
||||||
const xp = (100 * x) / width;
|
const xp = (100 * x) / width;
|
||||||
const yp = (100 * y) / height;
|
const yp = (100 * y) / height;
|
||||||
|
|
||||||
@ -339,20 +324,20 @@ export function calculateQuadrantAsPercentage(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!overlayType.has('center')) {
|
if (!overlayType.has('center')) {
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 'center';
|
||||||
|
}
|
||||||
|
|
||||||
export function calculateQuadrantAsPixels(
|
export function calculateQuadrantAsPixels(
|
||||||
overlayType: Set<DropTargetDirections>,
|
overlayType: Set<Position>,
|
||||||
x: number,
|
x: number,
|
||||||
y: number,
|
y: number,
|
||||||
width: number,
|
width: number,
|
||||||
height: number,
|
height: number,
|
||||||
threshold: number
|
threshold: number
|
||||||
): Quadrant | null | undefined {
|
): Position | null {
|
||||||
if (overlayType.has('left') && x < threshold) {
|
if (overlayType.has('left') && x < threshold) {
|
||||||
return 'left';
|
return 'left';
|
||||||
}
|
}
|
||||||
@ -367,8 +352,8 @@ export function calculateQuadrantAsPixels(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!overlayType.has('center')) {
|
if (!overlayType.has('center')) {
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 'center';
|
||||||
|
}
|
||||||
|
@ -46,6 +46,7 @@ import {
|
|||||||
import { GroupPanel, IGroupviewPanel } from '../groupview/groupviewPanel';
|
import { GroupPanel, IGroupviewPanel } from '../groupview/groupviewPanel';
|
||||||
import { DefaultGroupPanelView } from './defaultGroupPanelView';
|
import { DefaultGroupPanelView } from './defaultGroupPanelView';
|
||||||
import { getPanelData } from '../dnd/dataTransfer';
|
import { getPanelData } from '../dnd/dataTransfer';
|
||||||
|
import { DockviewDropTargets } from '../groupview/dnd';
|
||||||
|
|
||||||
export interface PanelReference {
|
export interface PanelReference {
|
||||||
update: (event: { params: { [key: string]: any } }) => void;
|
update: (event: { params: { [key: string]: any } }) => void;
|
||||||
@ -235,8 +236,26 @@ export class DockviewComponent
|
|||||||
}
|
}
|
||||||
|
|
||||||
const dropTarget = new Droptarget(this.element, {
|
const dropTarget = new Droptarget(this.element, {
|
||||||
canDisplayOverlay: () => {
|
canDisplayOverlay: (event, position) => {
|
||||||
|
const data = getPanelData();
|
||||||
|
|
||||||
|
if (data) {
|
||||||
|
if (data.viewId !== this.id) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.options.showDndOverlay) {
|
||||||
|
return this.options.showDndOverlay({
|
||||||
|
nativeEvent: event,
|
||||||
|
position: position,
|
||||||
|
target: DockviewDropTargets.Edge,
|
||||||
|
getData: getPanelData,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
},
|
},
|
||||||
acceptedTargetZones: ['top', 'bottom', 'left', 'right'],
|
acceptedTargetZones: ['top', 'bottom', 'left', 'right'],
|
||||||
overlayModel: {
|
overlayModel: {
|
||||||
@ -250,16 +269,14 @@ export class DockviewComponent
|
|||||||
dropTarget.onDrop((event) => {
|
dropTarget.onDrop((event) => {
|
||||||
const data = getPanelData();
|
const data = getPanelData();
|
||||||
|
|
||||||
if (!data) {
|
if (data) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.moveGroupOrPanel(
|
this.moveGroupOrPanel(
|
||||||
this.orthogonalize(event.position),
|
this.orthogonalize(event.position),
|
||||||
data.groupId,
|
data.groupId,
|
||||||
data.panelId || undefined,
|
data.panelId || undefined,
|
||||||
Position.Center
|
'center'
|
||||||
);
|
);
|
||||||
|
}
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -268,16 +285,16 @@ export class DockviewComponent
|
|||||||
|
|
||||||
private orthogonalize(position: Position): GroupPanel {
|
private orthogonalize(position: Position): GroupPanel {
|
||||||
switch (position) {
|
switch (position) {
|
||||||
case Position.Top:
|
case 'top':
|
||||||
case Position.Bottom:
|
case 'bottom':
|
||||||
if (this.gridview.orientation === Orientation.HORIZONTAL) {
|
if (this.gridview.orientation === Orientation.HORIZONTAL) {
|
||||||
// we need to add to a vertical splitview but the current root is a horizontal splitview.
|
// we need to add to a vertical splitview but the current root is a horizontal splitview.
|
||||||
// insert a vertical splitview at the root level and add the existing view as a child
|
// insert a vertical splitview at the root level and add the existing view as a child
|
||||||
this.gridview.insertOrthogonalSplitviewAtRoot();
|
this.gridview.insertOrthogonalSplitviewAtRoot();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Position.Left:
|
case 'left':
|
||||||
case Position.Right:
|
case 'right':
|
||||||
if (this.gridview.orientation === Orientation.VERTICAL) {
|
if (this.gridview.orientation === Orientation.VERTICAL) {
|
||||||
// we need to add to a horizontal splitview but the current root is a vertical splitview.
|
// we need to add to a horizontal splitview but the current root is a vertical splitview.
|
||||||
// insert a horiziontal splitview at the root level and add the existing view as a child
|
// insert a horiziontal splitview at the root level and add the existing view as a child
|
||||||
@ -289,11 +306,11 @@ export class DockviewComponent
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (position) {
|
switch (position) {
|
||||||
case Position.Top:
|
case 'top':
|
||||||
case Position.Left:
|
case 'left':
|
||||||
return this.createGroupAtLocation([0]); // insert into first position
|
return this.createGroupAtLocation([0]); // insert into first position
|
||||||
case Position.Bottom:
|
case 'bottom':
|
||||||
case Position.Right:
|
case 'right':
|
||||||
return this.createGroupAtLocation([this.gridview.length]); // insert into last position
|
return this.createGroupAtLocation([this.gridview.length]); // insert into last position
|
||||||
default:
|
default:
|
||||||
throw new Error(`unsupported position ${position}`);
|
throw new Error(`unsupported position ${position}`);
|
||||||
@ -543,7 +560,7 @@ export class DockviewComponent
|
|||||||
const target = toTarget(
|
const target = toTarget(
|
||||||
<Direction>options.position?.direction || 'within'
|
<Direction>options.position?.direction || 'within'
|
||||||
);
|
);
|
||||||
if (target === Position.Center) {
|
if (target === 'center') {
|
||||||
panel = this.createPanel(options, referenceGroup);
|
panel = this.createPanel(options, referenceGroup);
|
||||||
referenceGroup.model.openPanel(panel);
|
referenceGroup.model.openPanel(panel);
|
||||||
} else {
|
} else {
|
||||||
@ -703,7 +720,7 @@ export class DockviewComponent
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!target || target === Position.Center) {
|
if (!target || target === 'center') {
|
||||||
const groupItem: IDockviewPanel | undefined =
|
const groupItem: IDockviewPanel | undefined =
|
||||||
sourceGroup?.model.removePanel(itemId) ||
|
sourceGroup?.model.removePanel(itemId) ||
|
||||||
this.panels.find((panel) => panel.id === itemId);
|
this.panels.find((panel) => panel.id === itemId);
|
||||||
@ -782,7 +799,7 @@ export class DockviewComponent
|
|||||||
target: Position
|
target: Position
|
||||||
): void {
|
): void {
|
||||||
if (sourceGroup) {
|
if (sourceGroup) {
|
||||||
if (!target || target === Position.Center) {
|
if (!target || target === 'center') {
|
||||||
const activePanel = sourceGroup.activePanel;
|
const activePanel = sourceGroup.activePanel;
|
||||||
const panels = [...sourceGroup.panels].map((p) =>
|
const panels = [...sourceGroup.panels].map((p) =>
|
||||||
sourceGroup.model.removePanel(p.id)
|
sourceGroup.model.removePanel(p.id)
|
||||||
|
@ -14,6 +14,7 @@ import { FrameworkFactory } from '../types';
|
|||||||
import { DockviewDropTargets } from '../groupview/dnd';
|
import { DockviewDropTargets } from '../groupview/dnd';
|
||||||
import { PanelTransfer } from '../dnd/dataTransfer';
|
import { PanelTransfer } from '../dnd/dataTransfer';
|
||||||
import { IGroupControlRenderer } from '../react/dockview/groupControlsRenderer';
|
import { IGroupControlRenderer } from '../react/dockview/groupControlsRenderer';
|
||||||
|
import { Position } from '../dnd/droptarget';
|
||||||
|
|
||||||
export interface GroupPanelFrameworkComponentFactory {
|
export interface GroupPanelFrameworkComponentFactory {
|
||||||
content: FrameworkFactory<IContentRenderer>;
|
content: FrameworkFactory<IContentRenderer>;
|
||||||
@ -54,7 +55,8 @@ export interface ViewFactoryData {
|
|||||||
export interface DockviewDndOverlayEvent {
|
export interface DockviewDndOverlayEvent {
|
||||||
nativeEvent: DragEvent;
|
nativeEvent: DragEvent;
|
||||||
target: DockviewDropTargets;
|
target: DockviewDropTargets;
|
||||||
group: GroupPanel;
|
position: Position;
|
||||||
|
group?: GroupPanel;
|
||||||
getData: () => PanelTransfer | undefined;
|
getData: () => PanelTransfer | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,19 +15,19 @@ const nextLayoutId = sequentialNumberGenerator();
|
|||||||
|
|
||||||
export type Direction = 'left' | 'right' | 'above' | 'below' | 'within';
|
export type Direction = 'left' | 'right' | 'above' | 'below' | 'within';
|
||||||
|
|
||||||
export function toTarget(direction: Direction) {
|
export function toTarget(direction: Direction): Position {
|
||||||
switch (direction) {
|
switch (direction) {
|
||||||
case 'left':
|
case 'left':
|
||||||
return Position.Left;
|
return 'left';
|
||||||
case 'right':
|
case 'right':
|
||||||
return Position.Right;
|
return 'right';
|
||||||
case 'above':
|
case 'above':
|
||||||
return Position.Top;
|
return 'top';
|
||||||
case 'below':
|
case 'below':
|
||||||
return Position.Bottom;
|
return 'bottom';
|
||||||
case 'within':
|
case 'within':
|
||||||
default:
|
default:
|
||||||
return Position.Center;
|
return 'center';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,13 +9,13 @@ import {
|
|||||||
Orientation,
|
Orientation,
|
||||||
Sizing,
|
Sizing,
|
||||||
} from '../splitview/core/splitview';
|
} from '../splitview/core/splitview';
|
||||||
import { Position } from '../dnd/droptarget';
|
|
||||||
import { tail } from '../array';
|
import { tail } from '../array';
|
||||||
import { LeafNode } from './leafNode';
|
import { LeafNode } from './leafNode';
|
||||||
import { BranchNode } from './branchNode';
|
import { BranchNode } from './branchNode';
|
||||||
import { Node } from './types';
|
import { Node } from './types';
|
||||||
import { Emitter, Event } from '../events';
|
import { Emitter, Event } from '../events';
|
||||||
import { IDisposable, MutableDisposable } from '../lifecycle';
|
import { IDisposable, MutableDisposable } from '../lifecycle';
|
||||||
|
import { Position } from '../dnd/droptarget';
|
||||||
|
|
||||||
function findLeaf(candiateNode: Node, last: boolean): LeafNode {
|
function findLeaf(candiateNode: Node, last: boolean): LeafNode {
|
||||||
if (candiateNode instanceof LeafNode) {
|
if (candiateNode instanceof LeafNode) {
|
||||||
@ -132,22 +132,19 @@ export function getRelativeLocation(
|
|||||||
const [rest, _index] = tail(location);
|
const [rest, _index] = tail(location);
|
||||||
let index = _index;
|
let index = _index;
|
||||||
|
|
||||||
if (direction === Position.Right || direction === Position.Bottom) {
|
if (direction === 'right' || direction === 'bottom') {
|
||||||
index += 1;
|
index += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return [...rest, index];
|
return [...rest, index];
|
||||||
} else {
|
} else {
|
||||||
const index =
|
const index = direction === 'right' || direction === 'bottom' ? 1 : 0;
|
||||||
direction === Position.Right || direction === Position.Bottom
|
|
||||||
? 1
|
|
||||||
: 0;
|
|
||||||
return [...location, index];
|
return [...location, index];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getDirectionOrientation(direction: Position): Orientation {
|
export function getDirectionOrientation(direction: Position): Orientation {
|
||||||
return direction === Position.Top || direction === Position.Bottom
|
return direction === 'top' || direction === 'bottom'
|
||||||
? Orientation.VERTICAL
|
? Orientation.VERTICAL
|
||||||
: Orientation.HORIZONTAL;
|
: Orientation.HORIZONTAL;
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@ import {
|
|||||||
SerializedGridObject,
|
SerializedGridObject,
|
||||||
getGridLocation,
|
getGridLocation,
|
||||||
} from './gridview';
|
} from './gridview';
|
||||||
import { Position } from '../dnd/droptarget';
|
|
||||||
import { tail, sequenceEquals } from '../array';
|
import { tail, sequenceEquals } from '../array';
|
||||||
import { CompositeDisposable } from '../lifecycle';
|
import { CompositeDisposable } from '../lifecycle';
|
||||||
import { IPanelDeserializer } from '../dockview/deserializer';
|
import { IPanelDeserializer } from '../dockview/deserializer';
|
||||||
@ -25,6 +24,7 @@ import { BaseComponentOptions } from '../panel/types';
|
|||||||
import { Orientation, Sizing } from '../splitview/core/splitview';
|
import { Orientation, Sizing } from '../splitview/core/splitview';
|
||||||
import { createComponent } from '../panel/componentFactory';
|
import { createComponent } from '../panel/componentFactory';
|
||||||
import { Emitter, Event } from '../events';
|
import { Emitter, Event } from '../events';
|
||||||
|
import { Position } from '../dnd/droptarget';
|
||||||
|
|
||||||
export interface SerializedGridview {
|
export interface SerializedGridview {
|
||||||
grid: {
|
grid: {
|
||||||
@ -265,7 +265,7 @@ export class GridviewComponent
|
|||||||
}
|
}
|
||||||
|
|
||||||
const target = toTarget(options.direction);
|
const target = toTarget(options.direction);
|
||||||
if (target === Position.Center) {
|
if (target === 'center') {
|
||||||
throw new Error(`${target} not supported as an option`);
|
throw new Error(`${target} not supported as an option`);
|
||||||
} else {
|
} else {
|
||||||
const location = getGridLocation(referenceGroup.element);
|
const location = getGridLocation(referenceGroup.element);
|
||||||
@ -294,7 +294,7 @@ export class GridviewComponent
|
|||||||
}
|
}
|
||||||
|
|
||||||
const target = toTarget(options.position.direction);
|
const target = toTarget(options.position.direction);
|
||||||
if (target === Position.Center) {
|
if (target === 'center') {
|
||||||
throw new Error(`${target} not supported as an option`);
|
throw new Error(`${target} not supported as an option`);
|
||||||
} else {
|
} else {
|
||||||
const location = getGridLocation(referenceGroup.element);
|
const location = getGridLocation(referenceGroup.element);
|
||||||
|
@ -2,4 +2,5 @@ export enum DockviewDropTargets {
|
|||||||
Tab,
|
Tab,
|
||||||
Panel,
|
Panel,
|
||||||
TabContainer,
|
TabContainer,
|
||||||
|
Edge,
|
||||||
}
|
}
|
||||||
|
@ -110,7 +110,11 @@ export interface IGroupview extends IDisposable, IGridPanelView {
|
|||||||
panel?: IDockviewPanel;
|
panel?: IDockviewPanel;
|
||||||
suppressRoll?: boolean;
|
suppressRoll?: boolean;
|
||||||
}): void;
|
}): void;
|
||||||
canDisplayOverlay(event: DragEvent, target: DockviewDropTargets): boolean;
|
canDisplayOverlay(
|
||||||
|
event: DragEvent,
|
||||||
|
position: Position,
|
||||||
|
target: DockviewDropTargets
|
||||||
|
): boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Groupview extends CompositeDisposable implements IGroupview {
|
export class Groupview extends CompositeDisposable implements IGroupview {
|
||||||
@ -240,18 +244,24 @@ export class Groupview extends CompositeDisposable implements IGroupview {
|
|||||||
|
|
||||||
this.dropTarget = new Droptarget(this.contentContainer.element, {
|
this.dropTarget = new Droptarget(this.contentContainer.element, {
|
||||||
acceptedTargetZones: ['top', 'bottom', 'left', 'right', 'center'],
|
acceptedTargetZones: ['top', 'bottom', 'left', 'right', 'center'],
|
||||||
canDisplayOverlay: (event, quadrant) => {
|
canDisplayOverlay: (event, position) => {
|
||||||
if (this.locked && !quadrant) {
|
if (this.locked && position === 'center') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = getPanelData();
|
const data = getPanelData();
|
||||||
|
|
||||||
if (data && data.viewId === this.accessor.id) {
|
if (data && data.viewId === this.accessor.id) {
|
||||||
if (data.panelId === null && data.groupId === this.id) {
|
if (data.groupId === this.id) {
|
||||||
// don't allow group move to drop on self
|
if (position === 'center') {
|
||||||
|
// don't allow to drop on self for center position
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (data.panelId === null) {
|
||||||
|
// don't allow group move to drop anywhere on self
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const groupHasOnePanelAndIsActiveDragElement =
|
const groupHasOnePanelAndIsActiveDragElement =
|
||||||
this._panels.length === 1 && data.groupId === this.id;
|
this._panels.length === 1 && data.groupId === this.id;
|
||||||
@ -259,7 +269,11 @@ export class Groupview extends CompositeDisposable implements IGroupview {
|
|||||||
return !groupHasOnePanelAndIsActiveDragElement;
|
return !groupHasOnePanelAndIsActiveDragElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.canDisplayOverlay(event, DockviewDropTargets.Panel);
|
return this.canDisplayOverlay(
|
||||||
|
event,
|
||||||
|
position,
|
||||||
|
DockviewDropTargets.Panel
|
||||||
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -279,7 +293,7 @@ export class Groupview extends CompositeDisposable implements IGroupview {
|
|||||||
this._onDidRemovePanel,
|
this._onDidRemovePanel,
|
||||||
this._onDidActivePanelChange,
|
this._onDidActivePanelChange,
|
||||||
this.tabsContainer.onDrop((event) => {
|
this.tabsContainer.onDrop((event) => {
|
||||||
this.handleDropEvent(event.event, Position.Center, event.index);
|
this.handleDropEvent(event.event, 'center', event.index);
|
||||||
}),
|
}),
|
||||||
this.contentContainer.onDidFocus(() => {
|
this.contentContainer.onDidFocus(() => {
|
||||||
this.accessor.doSetGroupActive(this.groupPanel, true);
|
this.accessor.doSetGroupActive(this.groupPanel, true);
|
||||||
@ -673,13 +687,18 @@ export class Groupview extends CompositeDisposable implements IGroupview {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
canDisplayOverlay(event: DragEvent, target: DockviewDropTargets): boolean {
|
canDisplayOverlay(
|
||||||
|
event: DragEvent,
|
||||||
|
position: Position,
|
||||||
|
target: DockviewDropTargets
|
||||||
|
): boolean {
|
||||||
// custom overlay handler
|
// custom overlay handler
|
||||||
if (this.accessor.options.showDndOverlay) {
|
if (this.accessor.options.showDndOverlay) {
|
||||||
return this.accessor.options.showDndOverlay({
|
return this.accessor.options.showDndOverlay({
|
||||||
nativeEvent: event,
|
nativeEvent: event,
|
||||||
target,
|
target,
|
||||||
group: this.accessor.getPanel(this.id)!,
|
group: this.accessor.getPanel(this.id)!,
|
||||||
|
position,
|
||||||
getData: getPanelData,
|
getData: getPanelData,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ export class Tab extends CompositeDisposable implements ITab {
|
|||||||
|
|
||||||
this.droptarget = new Droptarget(this._element, {
|
this.droptarget = new Droptarget(this._element, {
|
||||||
acceptedTargetZones: ['center'],
|
acceptedTargetZones: ['center'],
|
||||||
canDisplayOverlay: (event) => {
|
canDisplayOverlay: (event, position) => {
|
||||||
if (this.group.locked) {
|
if (this.group.locked) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -119,6 +119,7 @@ export class Tab extends CompositeDisposable implements ITab {
|
|||||||
|
|
||||||
return this.group.model.canDisplayOverlay(
|
return this.group.model.canDisplayOverlay(
|
||||||
event,
|
event,
|
||||||
|
position,
|
||||||
DockviewDropTargets.Tab
|
DockviewDropTargets.Tab
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -42,7 +42,7 @@ export class VoidContainer extends CompositeDisposable {
|
|||||||
|
|
||||||
this.voidDropTarget = new Droptarget(this._element, {
|
this.voidDropTarget = new Droptarget(this._element, {
|
||||||
acceptedTargetZones: ['center'],
|
acceptedTargetZones: ['center'],
|
||||||
canDisplayOverlay: (event) => {
|
canDisplayOverlay: (event, position) => {
|
||||||
const data = getPanelData();
|
const data = getPanelData();
|
||||||
|
|
||||||
if (data && this.accessor.id === data.viewId) {
|
if (data && this.accessor.id === data.viewId) {
|
||||||
@ -60,6 +60,7 @@ export class VoidContainer extends CompositeDisposable {
|
|||||||
|
|
||||||
return group.model.canDisplayOverlay(
|
return group.model.canDisplayOverlay(
|
||||||
event,
|
event,
|
||||||
|
position,
|
||||||
DockviewDropTargets.Panel
|
DockviewDropTargets.Panel
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -27,7 +27,7 @@ export * from './react'; // TODO: should be conditional on whether user wants th
|
|||||||
|
|
||||||
export { Event } from './events';
|
export { Event } from './events';
|
||||||
export { IDisposable } from './lifecycle';
|
export { IDisposable } from './lifecycle';
|
||||||
export { Position } from './dnd/droptarget';
|
export { Position as DropTargetDirections } from './dnd/droptarget';
|
||||||
export {
|
export {
|
||||||
FocusEvent,
|
FocusEvent,
|
||||||
PanelDimensionChangeEvent,
|
PanelDimensionChangeEvent,
|
||||||
|
@ -4,7 +4,7 @@ import {
|
|||||||
LocalSelectionTransfer,
|
LocalSelectionTransfer,
|
||||||
PaneTransfer,
|
PaneTransfer,
|
||||||
} from '../dnd/dataTransfer';
|
} from '../dnd/dataTransfer';
|
||||||
import { Droptarget, DroptargetEvent, Position } from '../dnd/droptarget';
|
import { Droptarget, DroptargetEvent } from '../dnd/droptarget';
|
||||||
import { Emitter } 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';
|
||||||
@ -142,16 +142,10 @@ export abstract class DraggablePaneviewPanel extends PaneviewPanel {
|
|||||||
const fromIndex = allPanels.indexOf(existingPanel);
|
const fromIndex = allPanels.indexOf(existingPanel);
|
||||||
let toIndex = containerApi.panels.indexOf(this);
|
let toIndex = containerApi.panels.indexOf(this);
|
||||||
|
|
||||||
if (
|
if (event.position === 'left' || event.position === 'top') {
|
||||||
event.position === Position.Left ||
|
|
||||||
event.position === Position.Top
|
|
||||||
) {
|
|
||||||
toIndex = Math.max(0, toIndex - 1);
|
toIndex = Math.max(0, toIndex - 1);
|
||||||
}
|
}
|
||||||
if (
|
if (event.position === 'right' || event.position === 'bottom') {
|
||||||
event.position === Position.Right ||
|
|
||||||
event.position === Position.Bottom
|
|
||||||
) {
|
|
||||||
if (fromIndex > toIndex) {
|
if (fromIndex > toIndex) {
|
||||||
toIndex++;
|
toIndex++;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user