Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: set pointer caputure when pointer out #4099

Merged
merged 3 commits into from
Nov 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/engine-render/src/basics/i-events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<number>;
/**
Expand Down
4 changes: 2 additions & 2 deletions packages/engine-render/src/components/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<T, U, V> extends BaseObject {
private _extensions = new Map<string, ComponentExtension<T, U, V>>();
Expand Down
223 changes: 106 additions & 117 deletions packages/engine-render/src/engine.ts

Large diffs are not rendered by default.

429 changes: 209 additions & 220 deletions packages/engine-render/src/scene.input-manager.ts

Large diffs are not rendered by default.

19 changes: 17 additions & 2 deletions packages/engine-render/src/scene.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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[] = [];

Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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) {
Expand Down
8 changes: 4 additions & 4 deletions packages/engine-render/src/thin-scene.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,19 @@
* 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';
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<ITransformChangeState>();
Expand Down
107 changes: 28 additions & 79 deletions packages/engine-render/src/viewport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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.
*/
Expand Down Expand Up @@ -163,70 +164,41 @@ 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;
}

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);
})
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,10 @@ export class BaseSelectionRenderService extends Disposable implements ISheetSele
private _cancelUpSubscription: Nullable<Subscription>;

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.
Expand Down Expand Up @@ -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)!;

Expand Down
Loading