diff --git a/packages/engine-render/src/basics/i-events.ts b/packages/engine-render/src/basics/i-events.ts index bdfce9345b2e..af4c4c221c94 100644 --- a/packages/engine-render/src/basics/i-events.ts +++ b/packages/engine-render/src/basics/i-events.ts @@ -113,7 +113,7 @@ export interface IEvent extends Event { */ inputIndex: number; /** - * Previous state of given input + * Previous state of given input, for what???, nobody read this value. */ previousState: Nullable; /** diff --git a/packages/engine-render/src/components/component.ts b/packages/engine-render/src/components/component.ts index 6548b00113ea..9f3997667143 100644 --- a/packages/engine-render/src/components/component.ts +++ b/packages/engine-render/src/components/component.ts @@ -14,12 +14,12 @@ * limitations under the License. */ -import { DisposableCollection, sortRules, toDisposable } from '@univerjs/core'; import type { IDisposable } from '@univerjs/core'; -import { BaseObject } from '../base-object'; import type { IViewportInfo } from '../basics/vector2'; import type { UniverRenderingContext } from '../context'; import type { ComponentExtension } from './extension'; +import { DisposableCollection, sortRules, toDisposable } from '@univerjs/core'; +import { BaseObject } from '../base-object'; export class RenderComponent extends BaseObject { private _extensions = new Map>(); diff --git a/packages/engine-render/src/engine.ts b/packages/engine-render/src/engine.ts index e72a922ea151..1d4535d92fe9 100644 --- a/packages/engine-render/src/engine.ts +++ b/packages/engine-render/src/engine.ts @@ -123,7 +123,7 @@ export class Engine extends ThinEngine { private _remainCapture: number = -1; /** previous pointer position */ - private _pointer: { [deviceSlot: number]: number } = {}; + private _pointerPosRecord: { [deviceSlot: number]: number } = {}; private _mouseId = -1; @@ -468,8 +468,8 @@ export class Engine extends ThinEngine { const deviceEvent = evt as unknown as IKeyboardEvent; deviceEvent.deviceType = DeviceType.Keyboard; deviceEvent.inputIndex = evt.keyCode; - deviceEvent.previousState = 0; - deviceEvent.currentState = 1; + // deviceEvent.previousState = 0; + // deviceEvent.currentState = 1; this.onInputChanged$.emitEvent(deviceEvent); }; @@ -478,8 +478,8 @@ export class Engine extends ThinEngine { const deviceEvent = evt as unknown as IKeyboardEvent; deviceEvent.deviceType = DeviceType.Keyboard; deviceEvent.inputIndex = evt.keyCode; - deviceEvent.previousState = 1; - deviceEvent.currentState = 0; + // deviceEvent.previousState = 1; + // deviceEvent.currentState = 0; this.onInputChanged$.emitEvent(deviceEvent); }; @@ -501,51 +501,27 @@ export class Engine extends ThinEngine { // const previousVertical = this.pointer[PointerInput.Vertical]; // const previousDeltaHorizontal = this.pointer[PointerInput.DeltaHorizontal]; // const previousDeltaVertical = this.pointer[PointerInput.DeltaVertical]; - this._pointer[PointerInput.Horizontal] = evt.clientX; - this._pointer[PointerInput.Vertical] = evt.clientY; - this._pointer[PointerInput.DeltaHorizontal] = evt.movementX; - this._pointer[PointerInput.DeltaVertical] = evt.movementY; + this._pointerPosRecord[PointerInput.Horizontal] = evt.clientX; + this._pointerPosRecord[PointerInput.Vertical] = evt.clientY; + this._pointerPosRecord[PointerInput.DeltaHorizontal] = evt.movementX; + this._pointerPosRecord[PointerInput.DeltaVertical] = evt.movementY; const deviceEvent = evt as unknown as IPointerEvent; deviceEvent.deviceType = deviceType; deviceEvent.inputIndex = PointerInput.Horizontal;// horizon 0 vertical 1 this.onInputChanged$.emitEvent(deviceEvent); - // TODO @lumixraku - //if (previousHorizontal !== evt.clientX) { - // deviceEvent.inputIndex = PointerInput.Horizontal; - // deviceEvent.previousState = previousHorizontal; - // deviceEvent.currentState = this.pointer[PointerInput.Horizontal]; - - // this.onInputChanged$.emitEvent(deviceEvent); - //} - //if (previousVertical !== evt.clientY) { - // deviceEvent.inputIndex = PointerInput.Vertical; - // deviceEvent.previousState = previousVertical; - // deviceEvent.currentState = this.pointer[PointerInput.Vertical]; - - // this.onInputChanged$.emitEvent(deviceEvent); - //} - //if (this.pointer[PointerInput.DeltaHorizontal] !== 0) { - // deviceEvent.inputIndex = PointerInput.DeltaHorizontal; - // deviceEvent.previousState = previousDeltaHorizontal; - // deviceEvent.currentState = this.pointer[PointerInput.DeltaHorizontal]; - - // this.onInputChanged$.emitEvent(deviceEvent); - //} - //if (this.pointer[PointerInput.DeltaVertical] !== 0) { - // deviceEvent.inputIndex = PointerInput.DeltaVertical; - // deviceEvent.previousState = previousDeltaVertical; - // deviceEvent.currentState = this.pointer[PointerInput.DeltaVertical]; - - // this.onInputChanged$.emitEvent(deviceEvent); - //} - // Lets Propagate the event for move with same position. - if (!this._usingSafari && evt.button !== -1) { + // evt.button is readonly and value is 0 1 2 3 4, it never be -1. + //if (!this._usingSafari && evt.button !== -1) { + + if (!this._usingSafari) { deviceEvent.inputIndex = evt.button + 2; - deviceEvent.previousState = this._pointer[evt.button + 2]; - this._pointer[evt.button + 2] = this._pointer[evt.button + 2] ? 0 : 1; // Reverse state of button if evt.button has value - deviceEvent.currentState = this._pointer[evt.button + 2]; + // deviceEvent.previousState = this._pointerPosRecord[evt.button + 2]; + + // Reverse state of button if evt.button has value // WHY? + // this._pointerPosRecord[evt.button + 2] = this._pointerPosRecord[evt.button + 2] ? 0 : 1; + + // deviceEvent.currentState = this._pointerPosRecord[evt.button + 2]; this.onInputChanged$.emitEvent(deviceEvent); } }; @@ -555,9 +531,11 @@ export class Engine extends ThinEngine { // TODO: maybe we should wrap the native event to an CustomEvent const deviceType = this._getPointerType(evt); - const previousHorizontal = this._pointer[PointerInput.Horizontal]; - const previousVertical = this._pointer[PointerInput.Vertical]; - const previousButton = this._pointer[evt.button + 2]; + const previousHorizontal = this._pointerPosRecord[PointerInput.Horizontal]; + const previousVertical = this._pointerPosRecord[PointerInput.Vertical]; + + // why ??? + // const previousButton = this._pointerPosRecord[evt.button + 2]; if (deviceType === DeviceType.Mouse) { // Mouse; Among supported browsers, value is either 1 or 0 for mouse @@ -579,32 +557,33 @@ export class Engine extends ThinEngine { } } - this._pointer[PointerInput.Horizontal] = evt.clientX; - this._pointer[PointerInput.Vertical] = evt.clientY; - this._pointer[evt.button + 2] = 1; + this._pointerPosRecord[PointerInput.Horizontal] = evt.clientX; + this._pointerPosRecord[PointerInput.Vertical] = evt.clientY; + // why?? + // this._pointerPosRecord[evt.button + 2] = 1; const deviceEvent = evt as IPointerEvent; deviceEvent.deviceType = deviceType; if (previousHorizontal !== evt.clientX) { deviceEvent.inputIndex = PointerInput.Horizontal; - deviceEvent.previousState = previousHorizontal; - deviceEvent.currentState = this._pointer[PointerInput.Horizontal]; + // deviceEvent.previousState = previousHorizontal; + // deviceEvent.currentState = this._pointerPosRecord[PointerInput.Horizontal]; this.onInputChanged$.emitEvent(deviceEvent); } if (previousVertical !== evt.clientY) { deviceEvent.inputIndex = PointerInput.Vertical; - deviceEvent.previousState = previousVertical; - deviceEvent.currentState = this._pointer[PointerInput.Vertical]; + // deviceEvent.previousState = previousVertical; + // deviceEvent.currentState = this._pointerPosRecord[PointerInput.Vertical]; this.onInputChanged$.emitEvent(deviceEvent); } // evt.button + 2 ---> leftClick: 2, middleClick: 3, rightClick:4 deviceEvent.inputIndex = evt.button + 2; - deviceEvent.previousState = previousButton; - deviceEvent.currentState = this._pointer[evt.button + 2]; + // deviceEvent.previousState = previousButton; + // deviceEvent.currentState = this._pointerPosRecord[evt.button + 2]; this.onInputChanged$.emitEvent(deviceEvent); }; @@ -612,35 +591,39 @@ export class Engine extends ThinEngine { const evt = _evt as PointerEvent | MouseEvent; const deviceType = this._getPointerType(evt); - const previousHorizontal = this._pointer[PointerInput.Horizontal]; - const previousVertical = this._pointer[PointerInput.Vertical]; - const previousButton = this._pointer[evt.button + 2]; + const previousHorizontal = this._pointerPosRecord[PointerInput.Horizontal]; + const previousVertical = this._pointerPosRecord[PointerInput.Vertical]; + + // why? + // const previousButton = this._pointerPosRecord[evt.button + 2]; + + this._pointerPosRecord[PointerInput.Horizontal] = evt.clientX; + this._pointerPosRecord[PointerInput.Vertical] = evt.clientY; - this._pointer[PointerInput.Horizontal] = evt.clientX; - this._pointer[PointerInput.Vertical] = evt.clientY; - this._pointer[evt.button + 2] = 0; + // why?? + // this._pointerPosRecord[evt.button + 2] = 0; const deviceEvent = evt as IPointerEvent; deviceEvent.deviceType = deviceType; if (previousHorizontal !== evt.clientX) { deviceEvent.inputIndex = PointerInput.Horizontal; - deviceEvent.previousState = previousHorizontal; - deviceEvent.currentState = this._pointer[PointerInput.Horizontal]; + // deviceEvent.previousState = previousHorizontal; + // deviceEvent.currentState = this._pointerPosRecord[PointerInput.Horizontal]; this.onInputChanged$.emitEvent(deviceEvent); } if (previousVertical !== evt.clientY) { deviceEvent.inputIndex = PointerInput.Vertical; - deviceEvent.previousState = previousVertical; - deviceEvent.currentState = this._pointer[PointerInput.Vertical]; + // deviceEvent.previousState = previousVertical; + // deviceEvent.currentState = this._pointerPosRecord[PointerInput.Vertical]; this.onInputChanged$.emitEvent(deviceEvent); } deviceEvent.inputIndex = evt.button + 2; - deviceEvent.previousState = previousButton; - deviceEvent.currentState = this._pointer[evt.button + 2]; + // deviceEvent.previousState = previousButton; + // deviceEvent.currentState = this._pointerPosRecord[evt.button + 2]; const canvasEle = this.getCanvasElement(); if ( @@ -659,7 +642,7 @@ export class Engine extends ThinEngine { // We don't want to unregister the mouse because we may miss input data when a mouse is moving after a click if (deviceType !== DeviceType.Mouse) { - this._pointer = {}; + this._pointerPosRecord = {}; } }; @@ -669,7 +652,7 @@ export class Engine extends ThinEngine { const deviceEvent = evt as IPointerEvent; deviceEvent.deviceType = deviceType; - deviceEvent.currentState = 2; + // deviceEvent.currentState = 2; this.onInputChanged$.emitEvent(deviceEvent); }; @@ -680,7 +663,7 @@ export class Engine extends ThinEngine { const deviceEvent = evt as IPointerEvent; deviceEvent.deviceType = deviceType; - deviceEvent.currentState = 3; + // deviceEvent.currentState = 3; this.onInputChanged$.emitEvent(deviceEvent); }; @@ -690,7 +673,7 @@ export class Engine extends ThinEngine { // Store previous values for event const deviceEvent = evt as IPointerEvent; deviceEvent.deviceType = deviceType; - deviceEvent.currentState = 3; + // deviceEvent.currentState = 3; this.onInputChanged$.emitEvent(deviceEvent); }; @@ -701,7 +684,7 @@ export class Engine extends ThinEngine { const deviceEvent = evt as IPointerEvent; deviceEvent.deviceType = deviceType; - deviceEvent.currentState = 3; + // deviceEvent.currentState = 3; this.onInputChanged$.emitEvent(deviceEvent); }; @@ -715,41 +698,42 @@ export class Engine extends ThinEngine { // this._mouseId = -1; } - this._pointer = {}; + this._pointerPosRecord = {}; }; this._pointerWheelEvent = (evt: any) => { const deviceType = DeviceType.Mouse; // Store previous values for event - const previousWheelScrollX = this._pointer[PointerInput.MouseWheelX]; - const previousWheelScrollY = this._pointer[PointerInput.MouseWheelY]; - const previousWheelScrollZ = this._pointer[PointerInput.MouseWheelZ]; + // const previousWheelScrollX = this._pointerPosRecord[PointerInput.MouseWheelX]; + // const previousWheelScrollY = this._pointerPosRecord[PointerInput.MouseWheelY]; + // const previousWheelScrollZ = this._pointerPosRecord[PointerInput.MouseWheelZ]; - this._pointer[PointerInput.MouseWheelX] = evt.deltaX || 0; - this._pointer[PointerInput.MouseWheelY] = evt.deltaY || evt.wheelDelta || 0; - this._pointer[PointerInput.MouseWheelZ] = evt.deltaZ || 0; + this._pointerPosRecord[PointerInput.MouseWheelX] = evt.deltaX || 0; + this._pointerPosRecord[PointerInput.MouseWheelY] = evt.deltaY || evt.wheelDelta || 0; + this._pointerPosRecord[PointerInput.MouseWheelZ] = evt.deltaZ || 0; const deviceEvent = evt as IPointerEvent; deviceEvent.deviceType = deviceType; - if (this._pointer[PointerInput.MouseWheelX] !== 0) { - deviceEvent.inputIndex = PointerInput.MouseWheelX; - deviceEvent.previousState = previousWheelScrollX; - deviceEvent.currentState = this._pointer[PointerInput.MouseWheelX]; - this.onInputChanged$.emitEvent(deviceEvent); + if (this._pointerPosRecord[PointerInput.MouseWheelX] !== 0) { + // deviceEvent.inputIndex = PointerInput.MouseWheelX; + // deviceEvent.previousState = previousWheelScrollX; + deviceEvent.currentState = this._pointerPosRecord[PointerInput.MouseWheelX]; + // this.onInputChanged$.emitEvent(deviceEvent); } - if (this._pointer[PointerInput.MouseWheelY] !== 0) { - deviceEvent.inputIndex = PointerInput.MouseWheelY; - deviceEvent.previousState = previousWheelScrollY; - deviceEvent.currentState = this._pointer[PointerInput.MouseWheelY]; - this.onInputChanged$.emitEvent(deviceEvent); + if (this._pointerPosRecord[PointerInput.MouseWheelY] !== 0) { + // deviceEvent.inputIndex = PointerInput.MouseWheelY; + // deviceEvent.previousState = previousWheelScrollY; + deviceEvent.currentState = this._pointerPosRecord[PointerInput.MouseWheelY]; + // this.onInputChanged$.emitEvent(deviceEvent); } - if (this._pointer[PointerInput.MouseWheelZ] !== 0) { - deviceEvent.inputIndex = PointerInput.MouseWheelZ; - deviceEvent.previousState = previousWheelScrollZ; - deviceEvent.currentState = this._pointer[PointerInput.MouseWheelZ]; - this.onInputChanged$.emitEvent(deviceEvent); + if (this._pointerPosRecord[PointerInput.MouseWheelZ] !== 0) { + // deviceEvent.inputIndex = PointerInput.MouseWheelZ; + // deviceEvent.previousState = previousWheelScrollZ; + deviceEvent.currentState = this._pointerPosRecord[PointerInput.MouseWheelZ]; + // this.onInputChanged$.emitEvent(deviceEvent); } + this.onInputChanged$.emitEvent(deviceEvent); }; const canvasEle = this.getCanvasElement(); @@ -798,53 +782,58 @@ export class Engine extends ThinEngine { const deviceType = this._getPointerType(evt); // Store previous values for event - const previousHorizontal = this._pointer[PointerInput.Horizontal]; - const previousVertical = this._pointer[PointerInput.Vertical]; - const previousDeltaHorizontal = this._pointer[PointerInput.DeltaHorizontal]; - const previousDeltaVertical = this._pointer[PointerInput.DeltaVertical]; - - this._pointer[PointerInput.Horizontal] = evt.clientX; - this._pointer[PointerInput.Vertical] = evt.clientY; - this._pointer[PointerInput.DeltaHorizontal] = evt.movementX; - this._pointer[PointerInput.DeltaVertical] = evt.movementY; + const previousHorizontal = this._pointerPosRecord[PointerInput.Horizontal]; + const previousVertical = this._pointerPosRecord[PointerInput.Vertical]; + // const previousDeltaHorizontal = this._pointerPosRecord[PointerInput.DeltaHorizontal]; + // const previousDeltaVertical = this._pointerPosRecord[PointerInput.DeltaVertical]; + + this._pointerPosRecord[PointerInput.Horizontal] = evt.clientX; + this._pointerPosRecord[PointerInput.Vertical] = evt.clientY; + this._pointerPosRecord[PointerInput.DeltaHorizontal] = evt.movementX; + this._pointerPosRecord[PointerInput.DeltaVertical] = evt.movementY; const deviceEvent = evt as IPointerEvent; deviceEvent.deviceType = deviceType; if (previousHorizontal !== evt.clientX) { deviceEvent.inputIndex = PointerInput.Horizontal; - deviceEvent.previousState = previousHorizontal; - deviceEvent.currentState = this._pointer[PointerInput.Horizontal]; + // deviceEvent.previousState = previousHorizontal; + deviceEvent.currentState = this._pointerPosRecord[PointerInput.Horizontal]; this.onInputChanged$.emitEvent(deviceEvent); } if (previousVertical !== evt.clientY) { deviceEvent.inputIndex = PointerInput.Vertical; - deviceEvent.previousState = previousVertical; - deviceEvent.currentState = this._pointer[PointerInput.Vertical]; + // deviceEvent.previousState = previousVertical; + deviceEvent.currentState = this._pointerPosRecord[PointerInput.Vertical]; this.onInputChanged$.emitEvent(deviceEvent); } - if (this._pointer[PointerInput.DeltaHorizontal] !== 0) { + if (this._pointerPosRecord[PointerInput.DeltaHorizontal] !== 0) { deviceEvent.inputIndex = PointerInput.DeltaHorizontal; - deviceEvent.previousState = previousDeltaHorizontal; - deviceEvent.currentState = this._pointer[PointerInput.DeltaHorizontal]; + // deviceEvent.previousState = previousDeltaHorizontal; + deviceEvent.currentState = this._pointerPosRecord[PointerInput.DeltaHorizontal]; this.onInputChanged$.emitEvent(deviceEvent); } - if (this._pointer[PointerInput.DeltaVertical] !== 0) { + if (this._pointerPosRecord[PointerInput.DeltaVertical] !== 0) { deviceEvent.inputIndex = PointerInput.DeltaVertical; - deviceEvent.previousState = previousDeltaVertical; - deviceEvent.currentState = this._pointer[PointerInput.DeltaVertical]; + // deviceEvent.previousState = previousDeltaVertical; + deviceEvent.currentState = this._pointerPosRecord[PointerInput.DeltaVertical]; this.onInputChanged$.emitEvent(deviceEvent); } // Lets Propagate the event for move with same position. - if (!this._usingSafari && evt.button !== -1) { + // -1 ??? evt.button varies from 0 to 4 + // if (!this._usingSafari && evt.button !== -1) { + + if (!this._usingSafari) { deviceEvent.inputIndex = evt.button + 2; - deviceEvent.previousState = this._pointer[evt.button + 2]; - this._pointer[evt.button + 2] = this._pointer[evt.button + 2] ? 0 : 1; // Reverse state of button if evt.button has value - deviceEvent.currentState = this._pointer[evt.button + 2]; + // deviceEvent.previousState = this._pointerPosRecord[evt.button + 2]; + + // Reverse state of button if evt.button has value. // WHY ?? why reverse value? + // this._pointerPosRecord[evt.button + 2] = this._pointerPosRecord[evt.button + 2] ? 0 : 1; + deviceEvent.currentState = this._pointerPosRecord[evt.button + 2]; this.onInputChanged$.emitEvent(deviceEvent); } }; diff --git a/packages/engine-render/src/scene.input-manager.ts b/packages/engine-render/src/scene.input-manager.ts index 3e99f6c4d78a..1b5f1e5e17f8 100644 --- a/packages/engine-render/src/scene.input-manager.ts +++ b/packages/engine-render/src/scene.input-manager.ts @@ -14,17 +14,17 @@ * limitations under the License. */ -import { Disposable, type Nullable, toDisposable } from '@univerjs/core'; +import type { PointerEvent } from 'react'; import type { Subscription } from 'rxjs'; -import type { PointerEvent } from 'react'; import type { BaseObject } from './base-object'; -import { RENDER_CLASS_TYPE } from './basics/const'; import type { IDragEvent, IEvent, IKeyboardEvent, IMouseEvent, IPointerEvent, IWheelEvent } from './basics/i-events'; +import type { ISceneInputControlOptions, Scene } from './scene'; +import type { ThinScene } from './thin-scene'; +import { Disposable, type Nullable, toDisposable } from '@univerjs/core'; +import { RENDER_CLASS_TYPE } from './basics/const'; import { DeviceType, PointerInput } from './basics/i-events'; import { Vector2 } from './basics/vector2'; -import type { ThinScene } from './thin-scene'; -import type { Viewport } from './viewport'; export class InputManager extends Disposable { /** The distance in pixel that you have to move to prevent some events */ @@ -52,24 +52,24 @@ export class InputManager extends Disposable { private _onInput$: Nullable; // Pointers - private _onPointerMove!: (evt: IMouseEvent) => void; - private _onPointerDown!: (evt: IPointerEvent) => void; - private _onPointerUp!: (evt: IPointerEvent) => void; - private _onPointerOut!: (evt: IPointerEvent) => void; - private _onPointerCancel!: (evt: IPointerEvent) => void; - private _onPointerEnter!: (evt: IPointerEvent) => void; - private _onPointerLeave!: (evt: IPointerEvent) => void; - private _onMouseWheel!: (evt: IWheelEvent) => void; + // private _onPointerMove!: (evt: IMouseEvent) => void; + // private _onPointerDown!: (evt: IPointerEvent) => void; + // private _onPointerUp!: (evt: IPointerEvent) => void; + // private _onPointerOut!: (evt: IPointerEvent) => void; + // private _onPointerCancel!: (evt: IPointerEvent) => void; + // private _onPointerEnter!: (evt: IPointerEvent) => void; + // private _onPointerLeave!: (evt: IPointerEvent) => void; + // private _onMouseWheel!: (evt: IWheelEvent) => void; // Keyboard - private _onKeyDown!: (evt: IKeyboardEvent) => void; - private _onKeyUp!: (evt: IKeyboardEvent) => void; + // private _onKeyDown!: (evt: IKeyboardEvent) => void; + // private _onKeyUp!: (evt: IKeyboardEvent) => void; // Drag - private _onDragEnter!: (evt: IDragEvent) => void; - private _onDragLeave!: (evt: IDragEvent) => void; - private _onDragOver!: (evt: IDragEvent) => void; - private _onDrop!: (evt: IDragEvent) => void; + // private _onDragEnter!: (evt: IDragEvent) => void; + // private _onDragLeave!: (evt: IDragEvent) => void; + // private _onDragOver!: (evt: IDragEvent) => void; + // private _onDrop!: (evt: IDragEvent) => void; private _currentMouseEnterPicked: Nullable; private _startingPosition = new Vector2(Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY); @@ -127,7 +127,7 @@ export class InputManager extends Disposable { } // Handle events such as triggering dragleave and dragenter. - dragLeaveEnterHandler(evt: IMouseEvent) { + dragLeaveEnterHandler(evt: IDragEvent) { const o = this._currentObject; if (o === null || o === undefined) { this._currentMouseEnterPicked?.triggerDragLeave(evt); @@ -140,262 +140,251 @@ export class InputManager extends Disposable { } } - // eslint-disable-next-line max-lines-per-function - attachControl( - hasDown: boolean = true, - hasUp: boolean = true, - enableMove: boolean = true, - hasWheel: boolean = true, - hasEnter: boolean = true, - hasLeave: boolean = true - ) { - const engine = this._scene.getEngine(); - - if (!engine) { - return; + _onPointerEnter(evt: IPointerEvent) { + // preserve compatibility with Safari when pointerId is not present + if (evt.pointerId === undefined) { + evt.pointerId = 0; } - this._onPointerEnter = (evt: IPointerEvent) => { - // preserve compatibility with Safari when pointerId is not present - if (evt.pointerId === undefined) { - evt.pointerId = 0; - } + this._currentObject = this._getObjectAtPos(evt.offsetX, evt.offsetY); + const _isStop = this._currentObject?.triggerPointerMove(evt); - this._currentObject = this._getObjectAtPos(evt.offsetX, evt.offsetY); - const _isStop = this._currentObject?.triggerPointerMove(evt); + this.mouseLeaveEnterHandler(evt); - this.mouseLeaveEnterHandler(evt); + // if (this._checkDirectSceneEventTrigger(!isStop, this._currentObject)) { + // if (this._scene.onPointerMoveObserver.hasObservers()) { + // this._scene.onPointerMoveObserver.notifyObservers(evt); + // } + // } + } - // if (this._checkDirectSceneEventTrigger(!isStop, this._currentObject)) { - // if (this._scene.onPointerMoveObserver.hasObservers()) { - // this._scene.onPointerMoveObserver.notifyObservers(evt); - // } - // } - }; + _onPointerLeave(evt: IPointerEvent) { + // preserve compatibility with Safari when pointerId is not present + if (evt.pointerId === undefined) { + evt.pointerId = 0; + } - this._onPointerLeave = (evt: IPointerEvent) => { - // preserve compatibility with Safari when pointerId is not present - if (evt.pointerId === undefined) { - evt.pointerId = 0; - } + // this._currentObject = this._getCurrentObject(evt.offsetX, evt.offsetY); + // const isStop = this._currentObject?.triggerPointerMove(evt); - // this._currentObject = this._getCurrentObject(evt.offsetX, evt.offsetY); - // const isStop = this._currentObject?.triggerPointerMove(evt); + this._currentObject = null; - this._currentObject = null; + this.mouseLeaveEnterHandler(evt); - this.mouseLeaveEnterHandler(evt); + // if (this._checkDirectSceneEventTrigger(!isStop, this._currentObject)) { + // if (this._scene.onPointerMoveObserver.hasObservers()) { + // this._scene.onPointerMoveObserver.notifyObservers(evt); + // } + // } + } - // if (this._checkDirectSceneEventTrigger(!isStop, this._currentObject)) { - // if (this._scene.onPointerMoveObserver.hasObservers()) { - // this._scene.onPointerMoveObserver.notifyObservers(evt); - // } - // } - }; + _onPointerMove(evt: IMouseEvent) { + // preserve compatibility with Safari when pointerId is not present + if ((evt as IPointerEvent).pointerId === undefined) { + (evt as unknown as PointerEvent).pointerId = 0; + } + const currentObject = this._currentObject = this._getObjectAtPos(evt.offsetX, evt.offsetY); - this._onPointerMove = (evt: IMouseEvent) => { - // preserve compatibility with Safari when pointerId is not present - if ((evt as IPointerEvent).pointerId === undefined) { - (evt as unknown as PointerEvent).pointerId = 0; - } - const currentObject = this._currentObject = this._getObjectAtPos(evt.offsetX, evt.offsetY); - // Math.random() < 0.01 && console.log('!!!scene _onPointerMove', currentObject?.oKey); + const isStop = currentObject?.triggerPointerMove(evt); - const isStop = currentObject?.triggerPointerMove(evt); + this.mouseLeaveEnterHandler(evt); - this.mouseLeaveEnterHandler(evt); + if (this._checkDirectSceneEventTrigger(!isStop, this._currentObject)) { + this._scene.onPointerMove$.emitEvent(evt); + this._scene.getEngine()?.setRemainCapture(); + } + } - if (this._checkDirectSceneEventTrigger(!isStop, this._currentObject)) { - this._scene.onPointerMove$.emitEvent(evt); - this._scene.getEngine()?.setRemainCapture(); - } - }; - this._onPointerDown = (evt: IPointerEvent) => { - // preserve compatibility with Safari when pointerId is not present - if (evt.pointerId === undefined) { - (evt as unknown as PointerEvent).pointerId = 0; - } + _onPointerDown(evt: IPointerEvent) { + // preserve compatibility with Safari when pointerId is not present + if (evt.pointerId === undefined) { + (evt as unknown as PointerEvent).pointerId = 0; + } - const currentObject = this._getObjectAtPos(evt.offsetX, evt.offsetY); - const isStop = currentObject?.triggerPointerDown(evt); + const currentObject = this._getObjectAtPos(evt.offsetX, evt.offsetY); + const isStop = currentObject?.triggerPointerDown(evt); - if (this._checkDirectSceneEventTrigger(!isStop, currentObject)) { - this._scene.onPointerDown$.emitEvent(evt); - } - }; + if (this._checkDirectSceneEventTrigger(!isStop, currentObject)) { + this._scene.onPointerDown$.emitEvent(evt); + } + } - this._onPointerUp = (evt: IPointerEvent) => { - // preserve compatibility with Safari when pointerId is not present - if (evt.pointerId === undefined) { - evt.pointerId = 0; - } + _onPointerUp(evt: IPointerEvent) { + // preserve compatibility with Safari when pointerId is not present + if (evt.pointerId === undefined) { + evt.pointerId = 0; + } - const currentObject = this._getObjectAtPos(evt.offsetX, evt.offsetY); - const isStop = currentObject?.triggerPointerUp(evt); + const currentObject = this._getObjectAtPos(evt.offsetX, evt.offsetY); + const isStop = currentObject?.triggerPointerUp(evt); - if (this._checkDirectSceneEventTrigger(!isStop, currentObject)) { - this._scene.onPointerUp$.emitEvent(evt); - } + if (this._checkDirectSceneEventTrigger(!isStop, currentObject)) { + this._scene.onPointerUp$.emitEvent(evt); + } - this._prePointerDoubleOrTripleClick(evt); - }; + this._prePointerDoubleOrTripleClick(evt); + } - this._onPointerCancel = (evt: IPointerEvent) => { - this._scene.onPointerCancel$.emitEvent(evt); - }; + _onPointerCancel(evt: IPointerEvent) { + this._scene.onPointerCancel$.emitEvent(evt); + } - this._onPointerOut = (evt: IPointerEvent) => { - this._scene.onPointerOut$.emitEvent(evt); - }; + _onPointerOut(evt: IPointerEvent) { + this._scene.onPointerOut$.emitEvent(evt); + } - this._onMouseWheel = (evt: IWheelEvent) => { - const currentObject = this._getObjectAtPos(evt.offsetX, evt.offsetY); - const isStop = currentObject?.triggerMouseWheel(evt); + _onMouseWheel(evt: IWheelEvent) { + const currentObject = this._getObjectAtPos(evt.offsetX, evt.offsetY); + const isStop = currentObject?.triggerMouseWheel(evt); - this._scene.getViewports().forEach((vp: Viewport) => { - vp.onMouseWheel$.emitEvent(evt); - // if (vp.onMouseWheel$.hasObservers()) { - // } - }); + // for doc + const viewportMain = (this._scene as Scene).getMainViewport(); + viewportMain.onMouseWheel$.emitEvent(evt); - if (this._checkDirectSceneEventTrigger(!isStop, currentObject)) { - this._scene.onMouseWheel$.emitEvent(evt); - // if (this._scene.onMouseWheel$.hasObservers()) { - // } - } - }; + if (this._checkDirectSceneEventTrigger(!isStop, currentObject)) { + this._scene.onMouseWheel$.emitEvent(evt); + } + } - this._onKeyDown = (evt: IKeyboardEvent) => { - this._scene.onKeyDown$.emitEvent(evt); - }; + _onKeyDown(evt: IKeyboardEvent) { + this._scene.onKeyDown$.emitEvent(evt); + } - this._onKeyUp = (evt: IKeyboardEvent) => { - this._scene.onKeyUp$.emitEvent(evt); - }; + _onKeyUp(evt: IKeyboardEvent) { + this._scene.onKeyUp$.emitEvent(evt); + } - this._onDragEnter = (evt: IDragEvent) => { - this._currentObject = this._getObjectAtPos(evt.offsetX, evt.offsetY); - this._currentObject?.triggerDragOver(evt); + _onDragEnter(evt: IDragEvent) { + this._currentObject = this._getObjectAtPos(evt.offsetX, evt.offsetY); + this._currentObject?.triggerDragOver(evt); - this.dragLeaveEnterHandler(evt); - }; + this.dragLeaveEnterHandler(evt); + } - this._onDragLeave = (evt: IDragEvent) => { - this._currentObject = null; + _onDragLeave(evt: IDragEvent) { + this._currentObject = null; - this.dragLeaveEnterHandler(evt); - }; + this.dragLeaveEnterHandler(evt); + } - this._onDragOver = (evt: IDragEvent) => { - this._currentObject = this._getObjectAtPos(evt.offsetX, evt.offsetY); - const isStop = this._currentObject?.triggerDragOver(evt); + _onDragOver(evt: IDragEvent) { + this._currentObject = this._getObjectAtPos(evt.offsetX, evt.offsetY); + const isStop = this._currentObject?.triggerDragOver(evt); - this.dragLeaveEnterHandler(evt); + this.dragLeaveEnterHandler(evt); - if (this._checkDirectSceneEventTrigger(!isStop, this._currentObject)) { - this._scene.onDragOver$.emitEvent(evt); - this._scene.getEngine()?.setRemainCapture(); - } - }; + if (this._checkDirectSceneEventTrigger(!isStop, this._currentObject)) { + this._scene.onDragOver$.emitEvent(evt); + this._scene.getEngine()?.setRemainCapture(); + } + } - this._onDrop = (evt: IDragEvent) => { - const currentObject = this._getObjectAtPos(evt.offsetX, evt.offsetY); - const isStop = currentObject?.triggerDrop(evt); + _onDrop(evt: IDragEvent) { + const currentObject = this._getObjectAtPos(evt.offsetX, evt.offsetY); + const isStop = currentObject?.triggerDrop(evt); - if (this._checkDirectSceneEventTrigger(!isStop, currentObject)) { - this._scene.onDrop$.emitEvent(evt); - } - }; + if (this._checkDirectSceneEventTrigger(!isStop, currentObject)) { + this._scene.onDrop$.emitEvent(evt); + } + } + + // eslint-disable-next-line max-lines-per-function + attachControl(options?: ISceneInputControlOptions) { + const enableDown: boolean = options?.enableDown ?? true; + const enableUp: boolean = options?.enableUp ?? true; + const enableMove: boolean = options?.enableMove ?? true; + const enableWheel: boolean = options?.enableWheel ?? true; + const enableEnter: boolean = options?.enableEnter ?? true; + const enableLeave: boolean = options?.enableLeave ?? true; + const engine = this._scene.getEngine(); + if (!engine) return; // eslint-disable-next-line complexity, max-lines-per-function this._onInput$ = engine.onInputChanged$.subscribeEvent((eventData: IEvent) => { const evt: IEvent = eventData; - // Keyboard Events if (eventData.deviceType === DeviceType.Keyboard) { - if (eventData.currentState === 1) { - this._onKeyDown(evt as IKeyboardEvent); - } - - if (eventData.currentState === 0) { - this._onKeyUp(evt as IKeyboardEvent); - } - } - - // Drag Events - if ((eventData as IDragEvent).dataTransfer) { - if (enableMove && - (eventData.inputIndex === PointerInput.Horizontal || - eventData.inputIndex === PointerInput.Vertical || - eventData.inputIndex === PointerInput.DeltaHorizontal || - eventData.inputIndex === PointerInput.DeltaVertical)) { - this._onDragOver(evt as IDragEvent); - } else if (hasEnter && eventData.currentState === 4) { - this._onDragEnter(evt as IDragEvent); - } else if (hasLeave && eventData.currentState === 5) { - this._onDragLeave(evt as IDragEvent); - } else if (hasUp && eventData.currentState === 6) { - this._onDrop(evt as IDragEvent); + switch (eventData.type) { + case 'keydown': + this._onKeyDown(evt as IKeyboardEvent); + break; + case 'keyup': + this._onKeyUp(evt as IKeyboardEvent); + break; } - - return; } // Pointer Events if (eventData.deviceType === DeviceType.Mouse || eventData.deviceType === DeviceType.Touch) { - if ( - hasDown && - eventData.inputIndex >= PointerInput.LeftClick && - eventData.inputIndex <= PointerInput.RightClick && - eventData.currentState === 1 - ) { - this._onPointerDown(evt as IPointerEvent); - } - - if ( - hasUp && - eventData.inputIndex >= PointerInput.LeftClick && - eventData.inputIndex <= PointerInput.RightClick && - eventData.currentState === 0 - ) { - this._onPointerUp(evt as IPointerEvent); - } - - if ( - enableMove && eventData.type === 'pointermove' - ) { - this._onPointerMove(evt as IPointerEvent); - } else if ( - hasWheel && - (eventData.inputIndex === PointerInput.MouseWheelX || - eventData.inputIndex === PointerInput.MouseWheelY || - eventData.inputIndex === PointerInput.MouseWheelZ) - ) { - this._onMouseWheel(evt as IWheelEvent); - } else if (hasEnter && eventData.currentState === 2) { - // this._onPointerUp(evt as IPointerEvent); - this._onPointerEnter(evt as IPointerEvent); - } else if (hasLeave && eventData.currentState === 3) { - // this._onPointerUp(evt as IPointerEvent); - this._onPointerLeave(evt as IPointerEvent); - } - - switch (evt.type) { + switch (eventData.type) { + case 'wheel': + case 'DOMMouseScroll': + case 'mousewheel': + if (enableWheel) { + this._onMouseWheel(evt as IWheelEvent); + } + break; case 'pointerout': this._onPointerOut(evt as IPointerEvent); break; case 'pointercancel': this._onPointerCancel(evt as IPointerEvent); break; + case 'pointerleave': + this._onPointerLeave(evt as IPointerEvent); + break; + case 'pointermove': + if (enableMove) { + this._onPointerMove(evt as IPointerEvent); + } + break; + case 'pointerup': + if (enableUp && + eventData.inputIndex >= PointerInput.LeftClick && + eventData.inputIndex <= PointerInput.RightClick) { + this._onPointerUp(evt as IPointerEvent); + } + break; + case 'pointerdown': + if (enableDown && + eventData.inputIndex >= PointerInput.LeftClick && + eventData.inputIndex <= PointerInput.RightClick) { + this._onPointerDown(evt as IPointerEvent); + } + break; } } - }); - this.disposeWithMe( - toDisposable( - this._onInput$ - ) - ); + // Drag Events, For 3rd users. Univer itself doesn't use drag events. + if ((eventData as IDragEvent).dataTransfer) { + switch (eventData.type) { + case 'dragenter': + if (enableEnter) { + this._onDragEnter(evt as IDragEvent); + } + break; + case 'dragover': { + const validIndex = eventData.inputIndex === PointerInput.Horizontal || + eventData.inputIndex === PointerInput.Vertical || + eventData.inputIndex === PointerInput.DeltaHorizontal || + eventData.inputIndex === PointerInput.DeltaVertical; + if (enableMove && validIndex) { + this._onDragOver(evt as IDragEvent); + } + break; + } + case 'dragleave': + if (enableLeave) { + this._onDragLeave(evt as IDragEvent); + } + break; + case 'drop': + this._onDrop(evt as IDragEvent); + break; + } + } + }); + this.disposeWithMe(toDisposable(this._onInput$)); this._alreadyAttached = true; } diff --git a/packages/engine-render/src/scene.ts b/packages/engine-render/src/scene.ts index f241dfd2575c..2dc960949ce5 100644 --- a/packages/engine-render/src/scene.ts +++ b/packages/engine-render/src/scene.ts @@ -37,6 +37,16 @@ import { InputManager } from './scene.input-manager'; import { Transformer } from './scene.transformer'; import { ThinScene } from './thin-scene'; +export const MAIN_VIEW_PORT_KEY = 'viewMain'; + +export interface ISceneInputControlOptions { + enableDown: boolean; + enableUp: boolean ; + enableMove: boolean ; + enableWheel: boolean ; + enableEnter: boolean ; + enableLeave: boolean ; +} export class Scene extends ThinScene { private _layers: Layer[] = []; @@ -139,13 +149,14 @@ export class Scene extends ThinScene { this.setCursor(val); } - attachControl(hasDown: boolean = true, hasUp: boolean = true, hasMove: boolean = true, hasWheel: boolean = true) { + attachControl(options?: ISceneInputControlOptions) { + // const hasDown: boolean = true; const hasUp: boolean = true; const hasMove: boolean = true; const hasWheel: boolean = true; if (!(this._parent.classType === RENDER_CLASS_TYPE.ENGINE)) { // 只绑定直接与 engine 挂载的 scene 来统一管理事件 return; } - this._inputManager?.attachControl(hasDown, hasUp, hasMove, hasWheel); + this._inputManager?.attachControl(options); return this; } @@ -588,6 +599,10 @@ export class Scene extends ThinScene { return this._viewports; } + getMainViewport(): Viewport { + return this.getViewport(MAIN_VIEW_PORT_KEY)!; + } + getViewport(key: string): Viewport | undefined { for (const viewport of this._viewports) { if (viewport.viewportKey === key) { diff --git a/packages/engine-render/src/thin-scene.ts b/packages/engine-render/src/thin-scene.ts index 2953893b563c..bdc41b40159f 100644 --- a/packages/engine-render/src/thin-scene.ts +++ b/packages/engine-render/src/thin-scene.ts @@ -14,12 +14,9 @@ * limitations under the License. */ -import { Disposable, EventSubject } from '@univerjs/core'; import type { Nullable } from '@univerjs/core'; - -import { RENDER_CLASS_TYPE } from './basics/const'; -import { Transform } from './basics/transform'; import type { BaseObject } from './base-object'; + import type { CURSOR_TYPE } from './basics/const'; import type { IDragEvent, IKeyboardEvent, IMouseEvent, IPointerEvent, IWheelEvent } from './basics/i-events'; import type { ITransformChangeState } from './basics/interfaces'; @@ -27,6 +24,9 @@ import type { Vector2 } from './basics/vector2'; import type { UniverRenderingContext } from './context'; import type { Scene } from './scene'; import type { ThinEngine } from './thin-engine'; +import { Disposable, EventSubject } from '@univerjs/core'; +import { RENDER_CLASS_TYPE } from './basics/const'; +import { Transform } from './basics/transform'; export abstract class ThinScene extends Disposable { onTransformChange$ = new EventSubject(); diff --git a/packages/engine-render/src/viewport.ts b/packages/engine-render/src/viewport.ts index 33cd45a7ce52..0fd90717126e 100644 --- a/packages/engine-render/src/viewport.ts +++ b/packages/engine-render/src/viewport.ts @@ -24,7 +24,6 @@ import type { BaseScrollBar } from './shape/base-scroll-bar'; import type { ThinScene } from './thin-scene'; import { EventSubject, Tools } from '@univerjs/core'; import { RENDER_CLASS_TYPE } from './basics/const'; -import { PointerInput } from './basics/i-events'; import { fixLineWidthByScale, toPx } from './basics/tools'; import { Transform } from './basics/transform'; import { Vector2 } from './basics/vector2'; @@ -968,95 +967,45 @@ export class Viewport { /** * At f7140a7c11, only doc need this method. - * In sheet, wheel event is handled by scroll-manager.service@setScrollInfo + * In sheet, wheel event is handled by scroll.render-controller@scene.onMouseWheel$ * @param evt * @param state */ - // eslint-disable-next-line complexity, max-lines-per-function + onMouseWheel(evt: IWheelEvent, state: EventState) { if (!this._scrollBar || this.isActive === false) { return; } - let isLimitedStore; - if (evt.inputIndex === PointerInput.MouseWheelX) { - const deltaFactor = Math.abs(evt.deltaX); - const allWidth = this._scene.width; - const viewWidth = this.width || 1; - const scrollNum = (viewWidth / allWidth) * deltaFactor; - if (evt.deltaX > 0) { - isLimitedStore = this.scrollByBarDeltaValue({ - x: scrollNum, - }); - } else { - isLimitedStore = this.scrollByBarDeltaValue({ - x: -scrollNum, - }); - } + let offsetX = 0; + let offsetY = 0; + const allWidth = this._scene.width; + const viewWidth = this.width || 1; + offsetX = (viewWidth / allWidth) * evt.deltaX; + + const allHeight = this._scene.height; + const viewHeight = this.height || 1; + if (evt.shiftKey) { + offsetX = (viewHeight / allHeight) * evt.deltaY * MOUSE_WHEEL_SPEED_SMOOTHING_FACTOR; + } else { + offsetY = (viewHeight / allHeight) * evt.deltaY; + } - // 临界点时执行浏览器行为 + const isLimitedStore = this.scrollByBarDeltaValue({ + x: offsetX, + y: offsetY, + }); + + if (isLimitedStore && !isLimitedStore.isLimitedX && !isLimitedStore.isLimitedY) { + // if viewport still have space to scroll, prevent default event. (DO NOT move canvas element) + // if scrolling is reaching limit, let scrolling event do the default behavior. + evt.preventDefault(); if (this._scene.getParent().classType === RENDER_CLASS_TYPE.SCENE_VIEWER) { - if (!isLimitedStore?.isLimitedX) { - state.stopPropagation(); - } - } else if (this._isWheelPreventDefaultX) { - evt.preventDefault(); - } else if (!isLimitedStore?.isLimitedX) { - evt.preventDefault(); + state.stopPropagation(); } } - if (evt.inputIndex === PointerInput.MouseWheelY) { - const deltaFactor = Math.abs(evt.deltaY); - const allHeight = this._scene.height; - const viewHeight = this.height || 1; - // let magicNumber = deltaFactor < 40 ? 2 : deltaFactor < 80 ? 3 : 4; - let scrollNum = (viewHeight / allHeight) * deltaFactor; - if (evt.shiftKey) { - scrollNum *= MOUSE_WHEEL_SPEED_SMOOTHING_FACTOR; - if (evt.deltaY > 0) { - isLimitedStore = this.scrollByBarDeltaValue({ - x: scrollNum, - }); - } else { - isLimitedStore = this.scrollByBarDeltaValue({ - x: -scrollNum, - }); - } - - // 临界点时执行浏览器行为 - if (this._scene.getParent().classType === RENDER_CLASS_TYPE.SCENE_VIEWER) { - if (!isLimitedStore?.isLimitedX) { - state.stopPropagation(); - } - } else if (this._isWheelPreventDefaultX) { - evt.preventDefault(); - } else if (!isLimitedStore?.isLimitedX) { - evt.preventDefault(); - } - } else { - if (evt.deltaY > 0) { - isLimitedStore = this.scrollByBarDeltaValue({ - y: scrollNum, - }); - } else { - isLimitedStore = this.scrollByBarDeltaValue({ - y: -scrollNum, - }); - } - - // 临界点时执行浏览器行为 - if (this._scene.getParent().classType === RENDER_CLASS_TYPE.SCENE_VIEWER) { - if (!isLimitedStore?.isLimitedY) { - state.stopPropagation(); - } - } else if (this._isWheelPreventDefaultY) { - evt.preventDefault(); - } else if (!isLimitedStore?.isLimitedY) { - evt.preventDefault(); - } - } - } - if (evt.inputIndex === PointerInput.MouseWheelZ) { - // TODO + + if (this._isWheelPreventDefaultX && this._isWheelPreventDefaultY) { + evt.preventDefault(); } this._scene.makeDirty(true); diff --git a/packages/sheets-ui/src/controllers/render-controllers/scroll.render-controller.ts b/packages/sheets-ui/src/controllers/render-controllers/scroll.render-controller.ts index c8cef02f2446..6e67d0001b1f 100644 --- a/packages/sheets-ui/src/controllers/render-controllers/scroll.render-controller.ts +++ b/packages/sheets-ui/src/controllers/render-controllers/scroll.render-controller.ts @@ -30,7 +30,7 @@ import { Inject, Injector, RANGE_TYPE, toDisposable } from '@univerjs/core'; -import { IRenderManagerService, PointerInput, RENDER_CLASS_TYPE, SHEET_VIEWPORT_KEY } from '@univerjs/engine-render'; +import { IRenderManagerService, RENDER_CLASS_TYPE, SHEET_VIEWPORT_KEY } from '@univerjs/engine-render'; import { getSelectionsService, ScrollToCellOperation, SetSelectionsOperation } from '@univerjs/sheets'; import { ScrollCommand, SetScrollRelativeCommand } from '../../commands/commands/set-scroll.command'; import { ExpandSelectionCommand, MoveSelectionCommand, MoveSelectionEnterAndTabCommand } from '../../commands/commands/set-selection.command'; @@ -40,6 +40,7 @@ import { getSheetObject } from '../utils/component-tools'; const SHEET_NAVIGATION_COMMANDS = [MoveSelectionCommand.id, MoveSelectionEnterAndTabCommand.id]; +const MOUSE_WHEEL_SPEED_SMOOTHING_FACTOR = 3; /** * This controller handles scroll logic in sheet interaction. */ @@ -163,7 +164,6 @@ export class SheetsScrollRenderController extends Disposable implements IRenderM if (!viewMain) return; this.disposeWithMe( - // eslint-disable-next-line complexity scene.onMouseWheel$.subscribeEvent((evt: IWheelEvent, state) => { if (evt.ctrlKey || !this._contextService.getContextValue(FOCUSING_SHEET)) { return; @@ -171,62 +171,34 @@ export class SheetsScrollRenderController extends Disposable implements IRenderM let offsetX = 0; let offsetY = 0; - const isLimitedStore = viewMain.limitedScroll(); - if (evt.inputIndex === PointerInput.MouseWheelX) { - const deltaFactor = Math.abs(evt.deltaX); - const scrollNum = deltaFactor; - // show more content on the right,evt.deltaX > 0, more content on the left, evt.deltaX < 0 - offsetX = evt.deltaX > 0 ? scrollNum : -scrollNum; - this._commandService.executeCommand(SetScrollRelativeCommand.id, { offsetX }); + // what???? + // const scrollNum = Math.abs(evt.deltaX); + // offsetX = evt.deltaX > 0 ? scrollNum : -scrollNum; + offsetX = evt.deltaX; + + // with shift, scrollY will be scrollX + if (evt.shiftKey) { + offsetX = evt.deltaY * MOUSE_WHEEL_SPEED_SMOOTHING_FACTOR; + } else { + offsetY = evt.deltaY; + } + this._commandService.executeCommand(SetScrollRelativeCommand.id, { offsetX, offsetY }); + this._context.scene.makeDirty(true); + + // if viewport still have space to scroll, prevent default event. (DO NOT move canvas element) + // if scrolling is reaching limit, let scrolling event do the default behavior. + if (isLimitedStore && !isLimitedStore.isLimitedX && !isLimitedStore.isLimitedY) { + evt.preventDefault(); if (scene.getParent().classType === RENDER_CLASS_TYPE.SCENE_VIEWER) { - if (!isLimitedStore?.isLimitedX) { - state.stopPropagation(); - } - } else if (viewMain.isWheelPreventDefaultX) { - evt.preventDefault(); - } else if (!isLimitedStore?.isLimitedX) { - evt.preventDefault(); + state.stopPropagation(); } } - if (evt.inputIndex === PointerInput.MouseWheelY) { - const deltaFactor = Math.abs(evt.deltaY); - let scrollNum = deltaFactor; - if (evt.shiftKey) { - scrollNum *= 3; - if (evt.deltaY > 0) { - offsetX = scrollNum; - } else { - offsetX = -scrollNum; - } - this._commandService.executeCommand(SetScrollRelativeCommand.id, { offsetX }); - - if (scene.getParent().classType === RENDER_CLASS_TYPE.SCENE_VIEWER) { - if (!isLimitedStore?.isLimitedX) { - state.stopPropagation(); - } - } else if (viewMain.isWheelPreventDefaultX) { - evt.preventDefault(); - } else if (!isLimitedStore?.isLimitedX) { - evt.preventDefault(); - } - } else { - offsetY = evt.deltaY > 0 ? scrollNum : -scrollNum; - this._commandService.executeCommand(SetScrollRelativeCommand.id, { offsetY }); - - if (scene.getParent().classType === RENDER_CLASS_TYPE.SCENE_VIEWER) { - if (!isLimitedStore?.isLimitedY) { - state.stopPropagation(); - } - } else if (viewMain.isWheelPreventDefaultY) { - evt.preventDefault(); - } else if (!isLimitedStore?.isLimitedY) { - evt.preventDefault(); - } - } + + if (viewMain.isWheelPreventDefaultX && viewMain.isWheelPreventDefaultY) { + evt.preventDefault(); } - this._context.scene.makeDirty(true); }) ); } diff --git a/packages/sheets-ui/src/services/selection/base-selection-render.service.ts b/packages/sheets-ui/src/services/selection/base-selection-render.service.ts index 4d9e53b140df..f9770c357260 100644 --- a/packages/sheets-ui/src/services/selection/base-selection-render.service.ts +++ b/packages/sheets-ui/src/services/selection/base-selection-render.service.ts @@ -130,6 +130,10 @@ export class BaseSelectionRenderService extends Disposable implements ISheetSele private _cancelUpSubscription: Nullable; protected _skeleton!: SpreadsheetSkeleton; + + /** + * From renderContext. + */ protected _scene!: Scene; // The type of selector determines the type of data range and the highlighting style of the title bar, now it always true. In future, this could be configurable by user. @@ -657,6 +661,7 @@ export class BaseSelectionRenderService extends Disposable implements ISheetSele unitId, sheetId, }; + this._scene.getEngine()?.setRemainCapture(); const viewportMain = scene.getViewport(SHEET_VIEWPORT_KEY.VIEW_MAIN)!;