diff --git a/packages/engine-render/src/basics/scroll-xy.ts b/packages/engine-render/src/basics/scroll-xy.ts index 84cada083f81..98e6cc1fe7d8 100644 --- a/packages/engine-render/src/basics/scroll-xy.ts +++ b/packages/engine-render/src/basics/scroll-xy.ts @@ -14,9 +14,11 @@ * limitations under the License. */ +import type { Viewport } from '../viewport'; + export function getCurrentScrollXY(scrollTimer: any) { const scene = scrollTimer.getScene(); - const viewport = scrollTimer.getViewportByCoord(scene); + const viewport = scrollTimer.getViewportByCoord(scene) as Viewport; const scrollX = 0; const scrollY = 0; if (!viewport) { @@ -25,7 +27,7 @@ export function getCurrentScrollXY(scrollTimer: any) { scrollY, }; } - const actualScroll = viewport.getActualScroll(viewport.scrollX, viewport.scrollY); + const actualScroll = viewport.transScroll2ViewportScrollValue(viewport.scrollX, viewport.scrollY); return { scrollX: actualScroll.x, scrollY: actualScroll.y, diff --git a/packages/engine-render/src/viewport.ts b/packages/engine-render/src/viewport.ts index a276427d7b1d..f65f33e14b6c 100644 --- a/packages/engine-render/src/viewport.ts +++ b/packages/engine-render/src/viewport.ts @@ -68,8 +68,8 @@ export interface IScrollObserverParam { /** * scrollX for viewport */ - actualScrollX?: number; - actualScrollY?: number; + viewportScrollX?: number; + viewportScrollY?: number; limitX?: number; limitY?: number; isTrigger?: boolean; @@ -94,19 +94,19 @@ export class Viewport { */ scrollX: number = 0; scrollY: number = 0; - _preScrollX: number = 0; - _preScrollY: number = 0; + private _preScrollX: number = 0; + private _preScrollY: number = 0; /** - * The actual scroll offset equals the distance from the content area position to the top, and there is a conversion relationship with scrollX and scrollY - * use getActualScroll to get scrolling value for spreadsheet. + * The viewport scroll offset equals the distance from the content area position to the top, and there is a conversion relationship with scrollX and scrollY + * use transScroll2ViewportScrollValue to get scrolling value for spreadsheet. */ - viewportScrollX: number = 0; - viewportScrollY: number = 0; - preViewportScrollX: number = 0; - preViewportScrollY: number = 0; - _deltaViewportScrollX: number = 0; - _deltaViewportScrollY: number = 0; + private _viewportScrollX: number = 0; + private _viewportScrollY: number = 0; + private _preViewportScrollX: number = 0; + private _preViewportScrollY: number = 0; + private _deltaViewportScrollX: number = 0; + private _deltaViewportScrollY: number = 0; onMouseWheelObserver = new Observable(); @@ -252,9 +252,6 @@ export class Viewport { this._mainCanvasResizeHandler(); }); this._mainCanvasResizeHandler(); - if (this.viewportKey === 'viewMain') { - console.log('viewMain init'); - } } initCacheCanvas(props?: IViewProps) { @@ -377,6 +374,22 @@ export class Viewport { return this._active; } + set viewportScrollX(val: number) { + this._viewportScrollX = val; + } + + get viewportScrollX() { + return this._viewportScrollX; + } + + set viewportScrollY(val: number) { + this._viewportScrollY = val; + } + + get viewportScrollY() { + return this._viewportScrollY; + } + private set top(num: number) { this._topOrigin = num; this._top = toPx(num, this._scene?.getParent()?.height); @@ -488,30 +501,27 @@ export class Viewport { } /** - * scroll to scrollbar position, absolute, - * only viewMain would call scrollTo, other views did not call scroll - * see scroll.render-controller + * set scrollXY and viewportScrollXY, and update scrollInfo without notify listeners of scrollInfo$ + * mainly call by scroll.render-controller and viewport.resize ... + * only viewMain would call scrollTo, other views did not call scroll, see scroll.render-controller + * @param pos + * + * when scrolling: + * * scroll.render-controller@_scrollManagerService.scrollInfo$.subscribe --> scrollTo * - * mainly call by scroll.render-controller and viewport.resize ... + * when change skelenton: + * _currentSkeletonBefore$ ---> scroll.render-controller@_updateSceneSize --> setSearchParam --> scene@_setTransForm ---> viewport.resetCanvasSizeAndUpdateScrollBar ---> scrollTo ---> _scroll + * --> onScrollAfterObserver.notifyObservers --> scroll.render-controller@onScrollAfterObserver ---> setScrollInfoToCurrSheetWithoutNotify ---> sms._setScrollInfo * - * after change skelenton - * exec sequence - * _currentSkeleton$ ---> selection.render-controller ---> formula@_autoScroll ---> viewport.resize + * _currentSkeleton$ ---> selection.render-controller ---> formula@_autoScroll ---> viewport.resize ---> get scrollXY by viewportScrollXY ---> scrollTo * _currentSkeleton$ ---> selection.render-controller ---> setCurrentSelection ---> formula@_autoScroll ---> scrollTo - * _currentSkeleton$ ---> freeze.render-controller@_refreshFreeze --> viewport.resize ---> scrollTo ---> _scroll (XXXX) - * _currentSkeleton$ ---> scroll.render-controller@updateSceneSize --> setSearchParam --> _setTransForm ---> viewport.resetCanvasSizeAndScrollbar ---> scrollTo ---> _scroll - * --> onScrollAfterObserver.notifyObservers --> scroll.render-controller@observer ---> setScrollInfoWithoutNotify - * - * render-controller@addOrReplaceNoRefresh ---> _setScrollInfo - * _currentSkeleton$ ---> scrollManagerService@setCurrentScroll --> scrollTo - * _currentSkeleton$ ---> scroll.render-controller@updateSceneSize --> viewport.resetCanvasSizeAndScrollbar ---> scrollTo + * _currentSkeleton$ ---> freeze.render-controller@_refreshFreeze --> viewport.resize ---> scrollTo ---> _scroll * Debug * window.scene.getViewports()[0].scrollTo({x: 14.2, y: 1.8}, true) - * @param pos */ - scrollTo(pos: IScrollBarPosition, isTrigger = true) { - return this._scrollToScrollbarPos(SCROLL_TYPE.scrollTo, pos, isTrigger); + scrollTo(pos: IScrollBarPosition) { + return this._scrollToScrollbarPos(SCROLL_TYPE.scrollTo, pos); } /** @@ -532,8 +542,8 @@ export class Viewport { scrollY: this.scrollY, x, y, - actualScrollX: this.viewportScrollX, - actualScrollY: this.viewportScrollY, + viewportScrollX: this.viewportScrollX, + viewportScrollY: this.viewportScrollY, limitX: this._scrollBar?.limitX, limitY: this._scrollBar?.limitY, isTrigger, @@ -655,7 +665,7 @@ export class Viewport { // this._deltaScrollY = this.scrollY - this._preScrollY; this._preScrollX = this.scrollX; this._preScrollY = this.scrollY; - const { scrollX, scrollY, actualScrollX, actualScrollY } = current; + const { scrollX, scrollY, viewportScrollX, viewportScrollY } = current; if (scrollX !== undefined) { this.scrollX = scrollX; } @@ -664,16 +674,16 @@ export class Viewport { this.scrollY = scrollY; } - if (actualScrollX !== undefined) { - this.preViewportScrollX = this.viewportScrollX; - this.viewportScrollX = actualScrollX; - this._deltaViewportScrollX = actualScrollX - this.preViewportScrollX; + if (viewportScrollX !== undefined) { + this._preViewportScrollX = this.viewportScrollX; + this.viewportScrollX = viewportScrollX; + this._deltaViewportScrollX = viewportScrollX - this._preViewportScrollX; } - if (actualScrollY !== undefined) { - this.preViewportScrollY = this.viewportScrollY; - this.viewportScrollY = actualScrollY; - this._deltaViewportScrollY = actualScrollY - this.preViewportScrollY; + if (viewportScrollY !== undefined) { + this._preViewportScrollY = this.viewportScrollY; + this.viewportScrollY = viewportScrollY; + this._deltaViewportScrollY = viewportScrollY - this._preViewportScrollY; } return this; } @@ -1133,8 +1143,6 @@ export class Viewport { * resize canvas & use viewportScrollXY to scrollTo */ private _resizeCacheCanvas() { - const viewportScrollX = this.viewportScrollX; - const viewportScrollY = this.viewportScrollY; const { width, height } = this._getViewPortSize(); const scaleX = this.scene.scaleX; @@ -1145,21 +1153,6 @@ export class Viewport { this.cacheBound = this._viewBound; this.preCacheBound = null; - // const contentWidth = (this._scene.width - this._paddingEndX) * this._scene.scaleX; - // const contentHeight = (this._scene.height - this._paddingEndY) * this._scene.scaleY; - // // @ts-expect-error - // if (this.viewportKey === 'sheetViewMain') { - // console.log('cotnentHeight', contentHeight, window.sms?._searchParamForScroll); - // } - - // if (this._scrollBar) { - // this._scrollBar.resize(width, height, contentWidth, contentHeight); - // const { x, y } = this.transViewportScroll2ScrollValue(viewportScrollX, viewportScrollY); - // this.scrollTo({ - // x, - // y, - // }); - // } this.markForceDirty(true); } @@ -1169,10 +1162,6 @@ export class Viewport { const { width, height } = this._getViewPortSize(); const contentWidth = (this._scene.width - this._paddingEndX) * this._scene.scaleX; const contentHeight = (this._scene.height - this._paddingEndY) * this._scene.scaleY; - // @ts-expect-error - if (this.viewportKey === 'sheetViewMain') { - console.log('cotnentHeight', contentHeight, window.sms?._searchParamForScroll); - } if (this._scrollBar) { this._scrollBar.resize(width, height, contentWidth, contentHeight); @@ -1256,8 +1245,7 @@ export class Viewport { y: number; }, x?: number, - y?: number, - isTrigger = true + y?: number ) { clearTimeout(this._scrollStopNum); this._scrollStopNum = setTimeout(() => { @@ -1267,11 +1255,10 @@ export class Viewport { scrollY: this.scrollY, x, y, - actualScrollX: scroll.x, - actualScrollY: scroll.y, + viewportScrollX: scroll.x, + viewportScrollY: scroll.y, limitX: this._scrollBar?.limitX, limitY: this._scrollBar?.limitY, - isTrigger, }); }, 2); } @@ -1286,7 +1273,7 @@ export class Viewport { * @param scrollBarPos viewMain 滚动条的位置 * @param isTrigger */ - private _scrollToScrollbarPos(scrollType: SCROLL_TYPE, scrollBarPos: IScrollBarPosition, isTrigger = true) { + private _scrollToScrollbarPos(scrollType: SCROLL_TYPE, scrollBarPos: IScrollBarPosition) { const { x, y } = scrollBarPos; if (this._scrollBar == null) { return; @@ -1317,7 +1304,7 @@ export class Viewport { } const limited = this.limitedScroll(); // 限制滚动范围 - isTrigger && this.onScrollBeforeObserver.notifyObservers({ + this.onScrollBeforeObserver.notifyObservers({ viewport: this, scrollX: this.scrollX, scrollY: this.scrollY, @@ -1325,7 +1312,6 @@ export class Viewport { y, limitX: this._scrollBar?.limitX, limitY: this._scrollBar?.limitY, - isTrigger, }); if (this._scrollBar) { @@ -1337,19 +1323,21 @@ export class Viewport { this.viewportScrollY = vpScroll.y; // scroll.render-controller@onScrollAfterObserver ---> setScrollInfo but no notify - isTrigger && this.onScrollAfterObserver.notifyObservers({ + // calc startRow & offset by viewportScrollXY, then update scrollInfo + // other viewports, rowHeader & colHeader depend on this notify + this.onScrollAfterObserver.notifyObservers({ viewport: this, scrollX: this.scrollX, scrollY: this.scrollY, x, y, - actualScrollX: vpScroll.x, - actualScrollY: vpScroll.y, + viewportScrollX: vpScroll.x, + viewportScrollY: vpScroll.y, limitX: this._scrollBar?.limitX, limitY: this._scrollBar?.limitY, }); - this._triggerScrollStop(vpScroll, x, y, isTrigger); + this._triggerScrollStop(vpScroll, x, y); return limited; } @@ -1395,7 +1383,6 @@ export class Viewport { : 0b00; const shouldCacheUpdate = nearEdge | viewBoundOutCacheArea; - // console.log(`shouldCacheUpdate${shouldCacheUpdate}`, `${this.viewportKey}:`, this.preCacheBound, this.cacheBound, this.viewBound, this._preCacheVisibleBound); return shouldCacheUpdate; } diff --git a/packages/sheets-ui/src/commands/commands/set-frozen.command.ts b/packages/sheets-ui/src/commands/commands/set-frozen.command.ts index 0dff6db41471..7023a78f484d 100644 --- a/packages/sheets-ui/src/commands/commands/set-frozen.command.ts +++ b/packages/sheets-ui/src/commands/commands/set-frozen.command.ts @@ -51,7 +51,7 @@ export const SetSelectionFrozenCommand: ICommand = { id: 'sheet.command.set-scroll-relative', type: CommandType.COMMAND, + // offsetXY derived from mouse wheel event handler: async (accessor, params = { offsetX: 0, offsetY: 0 }) => { const commandService = accessor.get(ICommandService); const scrollManagerService = accessor.get(ScrollManagerService); @@ -45,15 +46,13 @@ export const SetScrollRelativeCommand: ICommand const { unitId, subUnitId, worksheet } = target; const { xSplit, ySplit } = worksheet.getConfig().freeze; - const currentScroll = scrollManagerService.getCurrentScroll(); + const currentScroll = scrollManagerService.getCurrentScrollInfo(); const { offsetX = 0, offsetY = 0 } = params || {}; const { sheetViewStartRow = 0, sheetViewStartColumn = 0, offsetX: currentOffsetX = 0, offsetY: currentOffsetY = 0, - scrollLeft, - scrollTop, } = currentScroll || {}; return commandService.executeCommand(SetScrollOperation.id, { @@ -61,10 +60,8 @@ export const SetScrollRelativeCommand: ICommand sheetId: subUnitId, sheetViewStartRow: sheetViewStartRow + ySplit, sheetViewStartColumn: sheetViewStartColumn + xSplit, - offsetX: currentOffsetX + offsetX, + offsetX: currentOffsetX + offsetX, // currentOffsetX, offsetX 0, -179, offsetX may be negative or over max offsetY: currentOffsetY + offsetY, - scrollLeft, - scrollTop, }); }, }; @@ -95,7 +92,7 @@ export const ScrollCommand: ICommand = { if (!target) return false; const { workbook, worksheet } = target; - const currentScroll = scrollManagerService.getCurrentScroll(); + const currentScroll = scrollManagerService.getCurrentScrollInfo(); if (!worksheet) { return false; diff --git a/packages/sheets-ui/src/commands/operations/scroll.operation.ts b/packages/sheets-ui/src/commands/operations/scroll.operation.ts index 3a389cc0c105..2e1c7e2adbfd 100644 --- a/packages/sheets-ui/src/commands/operations/scroll.operation.ts +++ b/packages/sheets-ui/src/commands/operations/scroll.operation.ts @@ -35,11 +35,6 @@ export const SetScrollOperation: IOperation = { const worksheet = workbook!.getSheetBySheetId(params!.sheetId); const { xSplit, ySplit } = worksheet!.getConfig().freeze; - if (!worksheet) return false; - const config = worksheet.getConfig(); - config.scrollLeft = params.scrollLeft || 0; - config.scrollTop = params.scrollTop || 0; - scrollManagerService.setScrollInfo({ ...params, sheetViewStartRow: params.sheetViewStartRow - ySplit, diff --git a/packages/sheets-ui/src/common/utils.ts b/packages/sheets-ui/src/common/utils.ts index 1ebc6a5008aa..f85211059102 100644 --- a/packages/sheets-ui/src/common/utils.ts +++ b/packages/sheets-ui/src/common/utils.ts @@ -194,18 +194,18 @@ export function transformPosition2Offset(x: number, y: number, scene: Scene, ske const freezeWidth = endSheetView.startX - startSheetView.startX; const freezeHeight = endSheetView.startY - startSheetView.startY; - const { top, left, viewportScrollX: actualScrollX, viewportScrollY: actualScrollY } = viewMain; + const { top, left, viewportScrollX, viewportScrollY } = viewMain; let offsetX: number; // viewMain or viewTop if (x > left) { - offsetX = (x - actualScrollX) * scaleX; + offsetX = (x - viewportScrollX) * scaleX; } else { offsetX = ((freezeWidth + rowHeaderWidth) - (left - x)) * scaleX; } let offsetY: number; if (y > top) { - offsetY = (y - actualScrollY) * scaleY; + offsetY = (y - viewportScrollY) * scaleY; } else { offsetY = ((freezeHeight + columnHeaderHeight) - (top - y)) * scaleX; } diff --git a/packages/sheets-ui/src/controllers/render-controllers/freeze.render-controller.ts b/packages/sheets-ui/src/controllers/render-controllers/freeze.render-controller.ts index 44beec6f744a..18ae50b2ff21 100644 --- a/packages/sheets-ui/src/controllers/render-controllers/freeze.render-controller.ts +++ b/packages/sheets-ui/src/controllers/render-controllers/freeze.render-controller.ts @@ -369,7 +369,7 @@ export class HeaderFreezeRenderController extends Disposable implements IRenderC const scene = sheetObject.scene; const scale = Math.max(scene.scaleX, scene.scaleY); - const currentScroll = this._scrollManagerService.getCurrentScroll(); + const currentScroll = this._scrollManagerService.getCurrentScrollInfo(); const skeletonViewHeight = (sheetObject.engine.height - skeleton.columnHeaderHeight) / scale; const start = currentScroll?.sheetViewStartRow ?? 0; @@ -563,7 +563,7 @@ export class HeaderFreezeRenderController extends Disposable implements IRenderC // alert(`moveColumnTo: ${this._changeToColumn}`); } - const sheetViewScroll = this._scrollManagerService.getCurrentScroll() || { + const sheetViewScroll = this._scrollManagerService.getCurrentScrollInfo() || { sheetViewStartRow: 0, sheetViewStartColumn: 0, }; @@ -689,13 +689,13 @@ export class HeaderFreezeRenderController extends Disposable implements IRenderC this.disposeWithMe( viewMain.onScrollAfterObserver.add((param: IScrollObserverParam) => { - const { scrollX, scrollY, actualScrollX, actualScrollY } = param; + const { scrollX, scrollY, viewportScrollX, viewportScrollY } = param; if (viewRowBottom.isActive) { viewRowBottom .updateScroll({ scrollY, - actualScrollY, + viewportScrollY, }); } @@ -703,14 +703,14 @@ export class HeaderFreezeRenderController extends Disposable implements IRenderC viewColumnRight .updateScroll({ scrollX, - actualScrollX, + viewportScrollX, }); } if (viewMainLeft.isActive) { viewMainLeft .updateScroll({ scrollY, - actualScrollY, + viewportScrollY, }); } @@ -718,7 +718,7 @@ export class HeaderFreezeRenderController extends Disposable implements IRenderC viewMainTop .updateScroll({ scrollX, - actualScrollX, + viewportScrollX, }); } }) @@ -849,9 +849,9 @@ export class HeaderFreezeRenderController extends Disposable implements IRenderC }); viewMainTop .updateScroll({ - actualScrollY: startSheetView.startY, + viewportScrollY: startSheetView.startY, x: viewMain.scrollX, - actualScrollX: viewMain.viewportScrollX, + viewportScrollX: viewMain.viewportScrollX, }); viewRowTop.resize({ left: 0, @@ -861,7 +861,7 @@ export class HeaderFreezeRenderController extends Disposable implements IRenderC }); viewRowTop .updateScroll({ - actualScrollY: startSheetView.startY, + viewportScrollY: startSheetView.startY, }); viewRowBottom.resize({ left: 0, @@ -904,9 +904,9 @@ export class HeaderFreezeRenderController extends Disposable implements IRenderC }); viewMainLeft .updateScroll({ - actualScrollX: startSheetView.startX, + viewportScrollX: startSheetView.startX, y: viewMain.scrollY, - actualScrollY: viewMain.viewportScrollY, + viewportScrollY: viewMain.viewportScrollY, }); viewColumnLeft.resize({ left: rowHeaderWidthAndMarginLeft, @@ -916,7 +916,7 @@ export class HeaderFreezeRenderController extends Disposable implements IRenderC }); viewColumnLeft .updateScroll({ - actualScrollX: startSheetView.startX, + viewportScrollX: startSheetView.startX, }); viewColumnRight.resize({ left: rowHeaderWidthAndMarginLeft + leftGap, @@ -968,9 +968,9 @@ export class HeaderFreezeRenderController extends Disposable implements IRenderC }); viewMainLeft .updateScroll({ - actualScrollX: startSheetView.startX, + viewportScrollX: startSheetView.startX, y: viewMain.scrollY, - actualScrollY: viewMain.viewportScrollY, + viewportScrollY: viewMain.viewportScrollY, }); viewMainTop.resize({ left: rowHeaderWidthAndMarginLeft + leftGap, @@ -980,9 +980,9 @@ export class HeaderFreezeRenderController extends Disposable implements IRenderC }); viewMainTop .updateScroll({ - actualScrollY: startSheetView.startY, + viewportScrollY: startSheetView.startY, x: viewMain.scrollX, - actualScrollX: viewMain.viewportScrollX, + viewportScrollX: viewMain.viewportScrollX, }); viewMainLeftTop.resize({ left: rowHeaderWidthAndMarginLeft, @@ -993,8 +993,8 @@ export class HeaderFreezeRenderController extends Disposable implements IRenderC viewMainLeftTop .updateScroll({ - actualScrollX: startSheetView.startX, - actualScrollY: startSheetView.startY, + viewportScrollX: startSheetView.startX, + viewportScrollY: startSheetView.startY, }); viewRowTop.resize({ @@ -1006,7 +1006,7 @@ export class HeaderFreezeRenderController extends Disposable implements IRenderC viewRowTop .updateScroll({ - actualScrollY: startSheetView.startY, + viewportScrollY: startSheetView.startY, }); viewRowBottom.resize({ @@ -1025,7 +1025,7 @@ export class HeaderFreezeRenderController extends Disposable implements IRenderC viewColumnLeft .updateScroll({ - actualScrollX: startSheetView.startX, + viewportScrollX: startSheetView.startX, }); viewColumnRight.resize({ 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 25cdf78616a3..ed56dfc91433 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 @@ -166,15 +166,9 @@ export class SheetsScrollRenderController extends Disposable implements IRenderC } const viewportMain = scene.getViewport(SHEET_VIEWPORT_KEY.VIEW_MAIN); - // const viewports = this._getViewports(); - // if (!viewports) { - // return; - // } - // const { viewMain, viewRowBottom, viewColumnRight, viewMainLeft, viewMainTop } = viewports; - this.disposeWithMe( toDisposable( - // event triggered in viewpor@_scroll + // set scrollInf, event triggered in viewport@_scrollToScrollbarPos viewportMain?.onScrollAfterObserver.add((param: IScrollObserverParam) => { const skeleton = this._sheetSkeletonManagerService.getCurrent()?.skeleton; if (skeleton == null || param.isTrigger === false) { @@ -186,23 +180,26 @@ export class SheetsScrollRenderController extends Disposable implements IRenderC return; } - const { actualScrollX = 0, actualScrollY = 0 } = param; + const { viewportScrollX = 0, viewportScrollY = 0 } = param; // according to the actual scroll position, the most suitable row, column and offset combination is recalculated. const { row, column, rowOffset, columnOffset } = skeleton.getDecomposedOffset( - actualScrollX, - actualScrollY + viewportScrollX, + viewportScrollY ); - // update scroll infos in scroll manager service - this._scrollManagerService.setScrollInfoToCurrSheetWithoutNotify({ + // update scroll infos in scrollManagerService again! + // because raw param from scroll-command offsetX may be negative or over max value. + const lastestScrollInfo = { sheetViewStartRow: row, sheetViewStartColumn: column, offsetX: columnOffset, offsetY: rowOffset, - scrollLeft: actualScrollX, - scrollTop: actualScrollY, - }); + scrollLeft: viewportScrollX, + scrollTop: viewportScrollY, + }; + this._scrollManagerService.setScrollInfoToCurrSheetWithoutNotify(lastestScrollInfo); + this._scrollManagerService.setScrollInfoToSnapshot(lastestScrollInfo); }) ) ); @@ -218,14 +215,13 @@ export class SheetsScrollRenderController extends Disposable implements IRenderC if (skeleton == null || sheetObject == null) { return; } - const { actualScrollX = 0, actualScrollY = 0 } = param; + const { viewportScrollX = 0, viewportScrollY = 0 } = param; const freeze = this._getFreeze(); - // according to the actual scroll position, the most suitable row, column and offset combination is recalculated. const { row, column, rowOffset, columnOffset } = skeleton.getDecomposedOffset( - actualScrollX, - actualScrollY + viewportScrollX, + viewportScrollY ); this._commandService.executeCommand(ScrollCommand.id, { @@ -239,10 +235,11 @@ export class SheetsScrollRenderController extends Disposable implements IRenderC ); } - // scroll command -> _scrollManagerService -> scrollInfo$ -> viewport.scrollTo private _scrollSubscribeBinding() { this.disposeWithMe( toDisposable( + // wheel event --> set-scroll.command('sheet.operation.set-scroll') --> scroll.operation.ts --> scrollManagerService.setScrollInfo(raw value, may be negative) --> scrollInfo$.next --> current fn() --> viewport.scrollTo + // --> onScrollAfterObserver.notify ---> scrollManagerService.setScrollInfo again!(valid scroll value) this._scrollManagerService.scrollInfo$.subscribe((param) => { const skeleton = this._sheetSkeletonManagerService.getCurrent()?.skeleton; const sheetObject = this._getSheetObject(); @@ -264,7 +261,7 @@ export class SheetsScrollRenderController extends Disposable implements IRenderC viewportMain.scrollTo({ x: 0, y: 0, - }, false); + }); return; } @@ -275,10 +272,13 @@ export class SheetsScrollRenderController extends Disposable implements IRenderC sheetViewStartRow, sheetViewStartColumn ); - const viewportScrollX = startX + offsetX; - const viewportScrollY = startY + offsetY; - const config = viewportMain.transViewportScroll2ScrollValue(viewportScrollX, viewportScrollY); + // viewportScrollXByEvent is not same as viewportScrollX, by event may be negative, or over max + // so, before + const viewportScrollXByEvent = startX + offsetX; + const viewportScrollYByEvent = startY + offsetY; + + const config = viewportMain.transViewportScroll2ScrollValue(viewportScrollXByEvent, viewportScrollYByEvent); viewportMain.scrollTo(config); }) ) @@ -298,31 +298,12 @@ export class SheetsScrollRenderController extends Disposable implements IRenderC const viewportMain = scene.getViewport(SHEET_VIEWPORT_KEY.VIEW_MAIN); const currScrollInfo = this._scrollManagerService.getScrollInfoByParam(param as unknown as IScrollManagerSearchParam); if (viewportMain && currScrollInfo) { - // const scrollXY = viewportMain?.transViewportScroll2ScrollValue(currScrollInfo.viewportScrollLeft!, currScrollInfo.viewportScrollTop!); viewportMain.viewportScrollX = currScrollInfo.viewportScrollLeft || 0; viewportMain.viewportScrollY = currScrollInfo.viewportScrollTop || 0; } + // this function would call setSearchParam this._updateSceneSize(param as unknown as ISheetSkeletonManagerParam); }))); - // this.disposeWithMe(toDisposable( - // this._sheetSkeletonManagerService.currentSkeleton$.subscribe((param) => { - // if (param == null) { - // return; - // } - - // const { unitId, sheetId } = param; - // const currentRender = this._renderManagerService.getRenderById(unitId); - - // if (currentRender == null) { - - // } - // this._scrollManagerService.setSearchParamAndRefresh({ - // unitId, - // sheetId, - // }); - // this._updateSceneSize(param); - // }) - // )); } private _updateSceneSize(param: ISheetSkeletonManagerParam) { @@ -496,7 +477,7 @@ export class SheetsScrollRenderController extends Disposable implements IRenderC if (startSheetViewRow === undefined && startSheetViewColumn === undefined) return false; - const { offsetX, offsetY } = this._scrollManagerService.getCurrentScroll() || {}; + const { offsetX, offsetY } = this._scrollManagerService.getCurrentScrollInfo() || {}; return this._commandService.syncExecuteCommand(ScrollCommand.id, { sheetViewStartRow: startSheetViewRow, sheetViewStartColumn: startSheetViewColumn, diff --git a/packages/sheets-ui/src/services/drag-manager.service.ts b/packages/sheets-ui/src/services/drag-manager.service.ts index 14039e4e4a2b..ae5394a5fa70 100644 --- a/packages/sheets-ui/src/services/drag-manager.service.ts +++ b/packages/sheets-ui/src/services/drag-manager.service.ts @@ -79,7 +79,7 @@ export class DragManagerService extends Disposable { const skeletonParam = this._sheetSkeletonManagerService.getCurrent(); const currentRender = this._renderManagerService.getRenderById(workbook.getUnitId()); - const scrollInfo = this._scrollManagerService.getCurrentScroll(); + const scrollInfo = this._scrollManagerService.getCurrentScrollInfo(); if (!skeletonParam || !scrollInfo || !currentRender) return; diff --git a/packages/sheets-ui/src/services/hover-manager.service.ts b/packages/sheets-ui/src/services/hover-manager.service.ts index c3ee3dc7a0bf..64ee82600d24 100644 --- a/packages/sheets-ui/src/services/hover-manager.service.ts +++ b/packages/sheets-ui/src/services/hover-manager.service.ts @@ -84,7 +84,7 @@ export class HoverManagerService extends Disposable { const skeletonParam = this._sheetSkeletonManagerService.getCurrent(); const currentRender = this._renderManagerService.getRenderById(workbook.getUnitId()); - const scrollInfo = this._scrollManagerService.getCurrentScroll(); + const scrollInfo = this._scrollManagerService.getCurrentScrollInfo(); if (!skeletonParam || !scrollInfo || !currentRender) return; diff --git a/packages/sheets-ui/src/services/scroll-manager.service.ts b/packages/sheets-ui/src/services/scroll-manager.service.ts index 801d16831a1f..1d2508782e32 100644 --- a/packages/sheets-ui/src/services/scroll-manager.service.ts +++ b/packages/sheets-ui/src/services/scroll-manager.service.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import type { Nullable } from '@univerjs/core'; +import { IUniverInstanceService, type Nullable } from '@univerjs/core'; import { BehaviorSubject } from 'rxjs'; import { Inject } from '@wendellhu/redi'; import { SheetSkeletonManagerService } from './sheet-skeleton-manager.service'; @@ -54,9 +54,9 @@ export class ScrollManagerService { private _searchParamForScroll: Nullable = null; constructor( + @IUniverInstanceService private readonly _univerInstanceService: IUniverInstanceService, @Inject(SheetSkeletonManagerService) private readonly _sheetSkeletonManagerService: SheetSkeletonManagerService ) { - window.sms = this; } dispose(): void { @@ -69,17 +69,46 @@ export class ScrollManagerService { setSearchParamAndRefresh(param: IScrollManagerSearchParam) { this._searchParamForScroll = param; - this._refresh(param); + this._notifyCurrentScrollInfo(param); } getScrollInfoByParam(param: IScrollManagerSearchParam): Readonly> { return this._getCurrentScroll(param); } - getCurrentScroll(): Readonly> { + getCurrentScrollInfo(): Readonly> { return this._getCurrentScroll(this._searchParamForScroll); } + setScrollInfoToSnapshot(scrollInfo: IScrollManagerParam) { + if (this._searchParamForScroll == null) { + return; + } + const { unitId, sheetId } = this._searchParamForScroll; + const workbook = this._univerInstanceService.getUniverSheetInstance(unitId); + const worksheet = workbook?.getSheetBySheetId(sheetId); + const cfg = worksheet?.getConfig(); + if (cfg) { + cfg.scrollLeft = scrollInfo.scrollLeft || 0; + cfg.scrollTop = scrollInfo.scrollTop || 0; + } + } + + /** + * set scrollInfo by cmd, + * call _setScrollInfo twice after one scrolling. + * first time set scrollInfo bt scrollOperation, but offsetXY is derived from scroll event. + * second time set scrollInfo by viewport.scrollTo(scrol.render-controller --> onScrollAfterObserver), this time offsetXY has been limited. + * + * wheelevent --> sheetCanvasView --> set-scroll.command('sheet.command.set-scroll-relative') --> scrollOperation --> this.setScrollInfo --> scrollInfo$.next --> scroll.render-controller@viewportMain.scrollTo & notify --> + * scroll.render-controller@onScrollAfterObserver --> this.setScrollInfoToCurrSheetWithoutNotify --> this._setScrollInfo({}, false) + * call _setScrollInfo again, a loop!, so we should call setScrollInfoToCurrSheetWithoutNotify + * @param param + */ + setScrollInfo(param: IScrollManagerInsertParam) { + this._setScrollInfo(param); + } + setScrollInfoToCurrSheet(scrollInfo: IScrollManagerParam) { if (this._searchParamForScroll == null) { return; @@ -105,16 +134,6 @@ export class ScrollManagerService { ); } - /** - * set scrollInfo by cmd, - * wheelevent --> sheetCanvasView --> cmd('sheet.operation.set-scroll') --> scrollOperation --> this.setScrollInfo --> scrollInfo$.next --> scroll.render-controller --> viewportMain.scrollTo & notify --> - * scroll.render-controller@onScrollAfterObserver --> this.setScrollInfoToCurrSheetWithoutNotify --> this._setScrollInfo - * @param param - */ - setScrollInfo(param: IScrollManagerInsertParam) { - this._setScrollInfo(param); - } - clear(): void { if (this._searchParamForScroll == null) { return; @@ -132,8 +151,8 @@ export class ScrollManagerService { // const {} = skeleton.getCellByIndex(startRow, startColumn); // } - calcViewportScrollFromOffset(newScrollInfo: IScrollManagerInsertParam) { - const { unitId } = newScrollInfo; + calcViewportScrollFromOffset(scrollInfo: IScrollManagerInsertParam) { + const { unitId } = scrollInfo; const workbookScrollInfo = this._scrollInfo.get(unitId); if (workbookScrollInfo == null) { return { @@ -142,7 +161,7 @@ export class ScrollManagerService { }; } // const scrollInfo = workbookScrollInfo.get(param.sheetId); - let { sheetViewStartColumn, sheetViewStartRow, offsetX, offsetY } = newScrollInfo; + let { sheetViewStartColumn, sheetViewStartRow, offsetX, offsetY } = scrollInfo; sheetViewStartRow = sheetViewStartRow || 0; offsetY = offsetY || 0; const skeleton = this._sheetSkeletonManagerService.getCurrent()?.skeleton; @@ -159,7 +178,7 @@ export class ScrollManagerService { }; } - private _setScrollInfo(newScrollInfo: IScrollManagerInsertParam, isRefresh = true): void { + private _setScrollInfo(newScrollInfo: IScrollManagerInsertParam, notifyScrollInfo = true): void { const { unitId, sheetId, sheetViewStartColumn, sheetViewStartRow, offsetX, offsetY } = newScrollInfo; if (!this._scrollInfo.has(unitId)) { @@ -168,7 +187,7 @@ export class ScrollManagerService { const workbookScrollInfo = this._scrollInfo.get(unitId)!; const scrollLeftTopByRowColOffset = this.calcViewportScrollFromOffset(newScrollInfo); - console.log('scrollTop', newScrollInfo.sheetId, newScrollInfo.scrollTop, scrollLeftTopByRowColOffset.scrollTop); + // console.log('scrollTop', newScrollInfo.sheetId, scrollLeftTopByRowColOffset.viewportScrollTop); const scrollInfo: IScrollManagerParam = { sheetViewStartRow, sheetViewStartColumn, @@ -178,8 +197,8 @@ export class ScrollManagerService { viewportScrollTop: scrollLeftTopByRowColOffset.viewportScrollTop, }; workbookScrollInfo.set(sheetId, scrollInfo); - if (isRefresh === true) { - this._refresh({ unitId, sheetId }); + if (notifyScrollInfo === true) { + this._notifyCurrentScrollInfo({ unitId, sheetId }); } } @@ -194,7 +213,7 @@ export class ScrollManagerService { // scrollTop: 0, }); - this._refresh(param); + this._notifyCurrentScrollInfo(param); } private _getCurrentScroll(param: Nullable) { @@ -205,7 +224,7 @@ export class ScrollManagerService { return this._scrollInfo.get(unitId)?.get(sheetId); } - private _refresh(param: IScrollManagerSearchParam): void { + private _notifyCurrentScrollInfo(param: IScrollManagerSearchParam): void { const scrollInfo = this._getCurrentScroll(param); // subscribe this._scrollManagerService.scrollInfo$ in scroll.render-controller diff --git a/packages/sheets-ui/src/views/sheet-canvas-view.ts b/packages/sheets-ui/src/views/sheet-canvas-view.ts index 6d589c3f5a74..6d7cac245ac9 100644 --- a/packages/sheets-ui/src/views/sheet-canvas-view.ts +++ b/packages/sheets-ui/src/views/sheet-canvas-view.ts @@ -118,7 +118,7 @@ export class SheetCanvasView extends RxDisposable implements IRenderController { private _initViewports(scene: Scene, rowHeader: { width: number }, columnHeader: { height: number }) { const bufferEdgeX = 100; const bufferEdgeY = 100; - window.sc = scene; + // window.sc = scene; const viewMain = new Viewport(SHEET_VIEWPORT_KEY.VIEW_MAIN, scene, { left: rowHeader.width, top: columnHeader.height, diff --git a/packages/sheets-zen-editor/src/controllers/zen-editor.controller.ts b/packages/sheets-zen-editor/src/controllers/zen-editor.controller.ts index 24ce8dcf36ba..ee9dcd689214 100644 --- a/packages/sheets-zen-editor/src/controllers/zen-editor.controller.ts +++ b/packages/sheets-zen-editor/src/controllers/zen-editor.controller.ts @@ -37,6 +37,7 @@ import { VIEWPORT_KEY, } from '@univerjs/docs'; import { DeviceInputEventType, IRenderManagerService } from '@univerjs/engine-render'; +import type { Viewport } from '@univerjs/engine-render'; import { getEditorObject, IEditorBridgeService } from '@univerjs/sheets-ui'; import type { IEditorBridgeServiceParam } from '@univerjs/sheets-ui'; import { IZenZoneService } from '@univerjs/ui'; @@ -307,9 +308,9 @@ export class ZenEditorController extends RxDisposable { docsComponent.translate(docsLeft, docsTop); docBackground.translate(docsLeft, docsTop); - const viewport = scene.getViewport(VIEWPORT_KEY.VIEW_MAIN); + const viewport = scene.getViewport(VIEWPORT_KEY.VIEW_MAIN) as Viewport; if (scrollToX !== Number.POSITIVE_INFINITY && viewport != null) { - const actualX = viewport.getBarScroll(scrollToX, 0).x; + const actualX = viewport.transScroll2ViewportScrollValue(scrollToX, 0).x; viewport.scrollTo({ x: actualX, }); diff --git a/packages/slides/src/views/render/adaptors/docs-adaptor.ts b/packages/slides/src/views/render/adaptors/docs-adaptor.ts index 71ba19bc99bb..7b1055e5045f 100644 --- a/packages/slides/src/views/render/adaptors/docs-adaptor.ts +++ b/packages/slides/src/views/render/adaptors/docs-adaptor.ts @@ -351,7 +351,7 @@ export class DocsAdaptor extends ObjectAdaptor { docsComponent.translate(docsLeft, docsTop); if (scrollToX !== Number.POSITIVE_INFINITY && viewport != null) { - const actualX = viewport.getBarScrollValueByViewportScroll(scrollToX, 0).x; + const actualX = viewport.transScroll2ViewportScrollValue(scrollToX, 0).x; viewport.scrollTo({ x: actualX, }); diff --git a/packages/slides/src/views/render/adaptors/spreadsheet-adaptor.ts b/packages/slides/src/views/render/adaptors/spreadsheet-adaptor.ts index 31b911c36a7c..64fd196e3b54 100644 --- a/packages/slides/src/views/render/adaptors/spreadsheet-adaptor.ts +++ b/packages/slides/src/views/render/adaptors/spreadsheet-adaptor.ts @@ -204,18 +204,18 @@ export class SpreadsheetAdaptor extends ObjectAdaptor { // viewMain.linkToViewport(viewLeft, LINK_VIEW_PORT_TYPE.Y); // viewMain.linkToViewport(viewTop, LINK_VIEW_PORT_TYPE.X); viewMain.onScrollAfterObserver.add((param: IScrollObserverParam) => { - const { scrollX, scrollY, actualScrollX, actualScrollY } = param; + const { scrollX, scrollY, viewportScrollX, viewportScrollY } = param; viewTop .updateScroll({ scrollX, - actualScrollX, + viewportScrollX, }); viewLeft .updateScroll({ scrollY, - actualScrollY, + viewportScrollY, }); }); diff --git a/packages/slides/src/views/render/canvas-view.ts b/packages/slides/src/views/render/canvas-view.ts index a2064ab6866a..fcb4bec7097f 100644 --- a/packages/slides/src/views/render/canvas-view.ts +++ b/packages/slides/src/views/render/canvas-view.ts @@ -109,7 +109,7 @@ export class CanvasView extends RxDisposable { if (!viewMain || !getCenterPositionViewPort) return; const { left: viewPortLeft, top: viewPortTop } = getCenterPositionViewPort; - const { x, y } = viewMain.getBarScrollValueByViewportScroll(viewPortLeft, viewPortTop); + const { x, y } = viewMain.transViewportScroll2ScrollValue(viewPortLeft, viewPortTop); viewMain.scrollTo({ x,