Merge pull request #280 from mathuo/268-touch-support-for-resizing-panels-3

268 touch support for resizing panels
This commit is contained in:
mathuo 2023-06-13 19:41:43 +01:00 committed by GitHub
commit 782a468b7b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 124 additions and 8 deletions

View File

@ -84,6 +84,8 @@ describe('splitview', () => {
beforeEach(() => {
container = document.createElement('div');
container.className = 'container';
jest.clearAllMocks();
});
test('vertical splitview', () => {
@ -610,6 +612,12 @@ describe('splitview', () => {
splitview.addView(view1);
splitview.addView(view2);
const addEventListenerSpy = jest.spyOn(document, 'addEventListener');
const removeEventListenerSpy = jest.spyOn(
document,
'removeEventListener'
);
const sashElement = container
.getElementsByClassName('sash')
.item(0) as HTMLElement;
@ -623,6 +631,8 @@ describe('splitview', () => {
// start the drag event
fireEvent.mouseDown(sashElement, { clientX: 50, clientY: 100 });
expect(addEventListenerSpy).toBeCalledTimes(5);
// during a sash drag the views should have pointer-events disabled
expect(view1.element.parentElement!.style.pointerEvents).toBe('none');
expect(view2.element.parentElement!.style.pointerEvents).toBe('none');
@ -638,6 +648,8 @@ describe('splitview', () => {
// end the drag event
fireEvent.mouseUp(document);
expect(removeEventListenerSpy).toBeCalledTimes(5);
// expect pointer-eventes on views to be restored
expect(view1.element.parentElement!.style.pointerEvents).toBe('');
expect(view2.element.parentElement!.style.pointerEvents).toBe('');
@ -645,5 +657,79 @@ describe('splitview', () => {
fireEvent.mouseMove(document, { clientX: 100, clientY: 100 });
// expect no additional resizes
expect([view1.size, view2.size]).toEqual([225, 175]);
// expect no additional document listeners
expect(addEventListenerSpy).toBeCalledTimes(5);
expect(removeEventListenerSpy).toBeCalledTimes(5);
});
test('dnd: touch events to move sash', () => {
const splitview = new Splitview(container, {
orientation: Orientation.HORIZONTAL,
proportionalLayout: false,
});
splitview.layout(400, 500);
const view1 = new Testview(0, 1000);
const view2 = new Testview(0, 1000);
splitview.addView(view1);
splitview.addView(view2);
const addEventListenerSpy = jest.spyOn(document, 'addEventListener');
const removeEventListenerSpy = jest.spyOn(
document,
'removeEventListener'
);
const sashElement = container
.getElementsByClassName('sash')
.item(0) as HTMLElement;
// validate the expected state before drag
expect([view1.size, view2.size]).toEqual([200, 200]);
expect(sashElement).toBeTruthy();
expect(view1.element.parentElement!.style.pointerEvents).toBe('');
expect(view2.element.parentElement!.style.pointerEvents).toBe('');
// start the drag event
fireEvent.touchStart(sashElement, {
touches: [{ clientX: 50, clientY: 100 }],
});
expect(addEventListenerSpy).toBeCalledTimes(5);
// during a sash drag the views should have pointer-events disabled
expect(view1.element.parentElement!.style.pointerEvents).toBe('none');
expect(view2.element.parentElement!.style.pointerEvents).toBe('none');
// expect a delta move of 70 - 50 = 20
fireEvent.touchMove(document, {
touches: [{ clientX: 70, clientY: 110 }],
});
expect([view1.size, view2.size]).toEqual([220, 180]);
// expect a delta move of 75 - 70 = 5
fireEvent.touchMove(document, {
touches: [{ clientX: 75, clientY: 110 }],
});
expect([view1.size, view2.size]).toEqual([225, 175]);
// end the drag event
fireEvent.touchEnd(document);
expect(removeEventListenerSpy).toBeCalledTimes(5);
// expect pointer-eventes on views to be restored
expect(view1.element.parentElement!.style.pointerEvents).toBe('');
expect(view2.element.parentElement!.style.pointerEvents).toBe('');
fireEvent.touchMove(document, {
touches: [{ clientX: 100, clientY: 100 }],
});
// expect no additional resizes
expect([view1.size, view2.size]).toEqual([225, 175]);
// expect no additional document listeners
expect(addEventListenerSpy).toBeCalledTimes(5);
expect(removeEventListenerSpy).toBeCalledTimes(5);
});
});

View File

@ -393,7 +393,17 @@ export class Splitview {
const sash = document.createElement('div');
sash.className = 'sash';
const onStart = (event: MouseEvent) => {
const onTouchStart = (event: TouchEvent) => {
event.preventDefault();
const touch = event.touches[0];
onStart(touch);
};
const onMouseDown = (event: MouseEvent) => {
onStart(event);
};
const onStart = (event: { clientX: number; clientY: number }) => {
for (const item of this.viewItems) {
item.enabled = false;
}
@ -486,13 +496,25 @@ export class Splitview {
size: snappedViewItem.size,
};
}
//
const mousemove = (mousemoveEvent: MouseEvent) => {
const onMouseMove = (event: MouseEvent) => {
reposition(event);
};
const onTouchMove = (event: TouchEvent) => {
event.preventDefault();
const touch = event.touches[0];
reposition(touch);
};
const reposition = (event: {
clientX: number;
clientY: number;
}) => {
const current =
this._orientation === Orientation.HORIZONTAL
? mousemoveEvent.clientX
: mousemoveEvent.clientY;
? event.clientX
: event.clientY;
const delta = current - start;
this.resize(
@ -521,22 +543,30 @@ export class Splitview {
this.saveProportions();
document.removeEventListener('mousemove', mousemove);
document.removeEventListener('mousemove', onMouseMove);
document.removeEventListener('mouseup', end);
document.removeEventListener('touchmove', onTouchMove);
document.removeEventListener('touchend', end);
document.removeEventListener('touchcancel', end);
this._onDidSashEnd.fire(undefined);
};
document.addEventListener('mousemove', mousemove);
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('mouseup', end);
document.addEventListener('touchmove', onTouchMove);
document.addEventListener('touchend', end);
document.addEventListener('touchcancel', end);
};
sash.addEventListener('mousedown', onStart);
sash.addEventListener('mousedown', onMouseDown);
sash.addEventListener('touchstart', onTouchStart);
const sashItem: ISashItem = {
container: sash,
disposable: () => {
sash.removeEventListener('mousedown', onStart);
sash.removeEventListener('touchstart', onTouchStart);
this.sashContainer.removeChild(sash);
},
};