Skip to content

Commit

Permalink
fix: float dom after freeze (#4587)
Browse files Browse the repository at this point in the history
  • Loading branch information
lumixraku authored Feb 7, 2025
1 parent ef8dd1b commit 9b2274f
Show file tree
Hide file tree
Showing 9 changed files with 164 additions and 61 deletions.
1 change: 1 addition & 0 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,3 +204,4 @@ export { isNodeEnv } from './shared/tools';
export { Skeleton } from './skeleton.ts';
export type { IGetRowColByPosOptions } from './sheets/sheet-skeleton';
export type { IPosition } from './sheets/typedef.ts';
export * from './sheets/sheet-skeleton';
7 changes: 4 additions & 3 deletions packages/core/src/sheets/typedef.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@

import type { IResources } from '../services/resource-manager/type';
import type { IObjectArrayPrimitiveType, IObjectMatrixPrimitiveType, Nullable } from '../shared';
import type { BooleanNumber } from '../types/enum';
import type { LocaleType } from '../types/enum/locale-type';
import type { IDocumentData } from '../types/interfaces';
import type { ICellCustomRender } from '../types/interfaces/i-cell-custom-render';
import type { IStyleData } from '../types/interfaces/i-style-data';
import { type BooleanNumber, CellValueType } from '../types/enum';
import { CellValueType } from '../types/enum';

/**
* Snapshot of a workbook.
Expand Down Expand Up @@ -378,12 +379,12 @@ export interface IFreeze {
*/
ySplit: number;
/**
* scrollable start row
* scrollable start row(viewMain start row)
*/
startRow: number;

/**
* scrollable start column
* scrollable start column(viewMain start column)
*/
startColumn: number;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ import type {
} from '@univerjs/core';
import type { IDocumentSkeletonColumn } from '../../basics/i-document-skeleton-cached';
import type { ITransformChangeState } from '../../basics/interfaces';
import type { IBoundRectNoAngle, IViewportInfo } from '../../basics/vector2';
import type { IBoundRectNoAngle, IPoint, IViewportInfo } from '../../basics/vector2';
import type { Scene } from '../../scene';
import type { BorderCache, IFontCacheItem, IStylesCache } from './interfaces';
import {
Expand Down Expand Up @@ -1437,6 +1437,27 @@ export class SpreadsheetSkeleton extends SheetSkeleton {
};
}

getDistanceFromTopLeft(row: number, col: number): IPoint {
return {
x: this.colStartX(col),
y: this.rowStartY(row),
};
}

colStartX(col: number): number {
const arr = this.columnWidthAccumulation;
const i = col - 1;
if (i === -1) return 0;
return arr[i];
}

rowStartY(row: number): number {
const arr = this.rowHeightAccumulation;
const i = row - 1;
if (i === -1) return 0;
return arr[i];
}

getHiddenRowsInRange(range: IRowRange) {
const hiddenRows = [];
for (let i = range.startRow; i <= range.endRow; i++) {
Expand Down
11 changes: 4 additions & 7 deletions packages/engine-render/src/viewport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ export class Viewport {
/**
* bound of visible area
*/
private _viewBound: IBoundRectNoAngle;
private _viewBound: IBoundRectNoAngle = { top: 0, left: 0, bottom: 0, right: 0 };
private _preViewBound: IBoundRectNoAngle;

/**
Expand Down Expand Up @@ -354,8 +354,6 @@ export class Viewport {

set viewportScrollY(val: number) {
this._viewportScrollY = val;
// const { y } = this.transViewportScroll2ScrollValue(this._viewportScrollX, this._viewportScrollY);
// this.scrollY = y;
}

get viewportScrollY() {
Expand All @@ -364,14 +362,10 @@ export class Viewport {

set scrollX(val: number) {
this._scrollX = val;
// const { x } = this.transScroll2ViewportScrollValue(this._scrollX, this._scrollY);
// this._viewportScrollX = x;
}

set scrollY(val: number) {
this._scrollY = val;
// const { y } = this.transScroll2ViewportScrollValue(this._scrollX, this._scrollY);
// this._viewportScrollY = y;
}

get scrollX() {
Expand Down Expand Up @@ -449,6 +443,9 @@ export class Viewport {
this._active = false;
}

/**
* canvas resize & freeze change would invoke this method
*/
resetCanvasSizeAndUpdateScroll() {
this._resizeCacheCanvas();
this._updateScrollByViewportScrollValue();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ export interface IDOMAnchor {
}

export interface ILimitBound extends IBoundRectNoAngle {
/**
* Actually, it means fixed.
* When left is true, dom is fixed to left of dom pos when dom width is shrinking. or dom is fixed to right of dom pos when dom width is shrinking.
* When top is true, dom is fixed to top of dom pos when dom height is shrinking. or dom is fixed to bottom of dom pos when dom height is shrinking.
*/
absolute: {
left: boolean;
top: boolean;
Expand All @@ -102,17 +107,24 @@ export interface ILimitBound extends IBoundRectNoAngle {

/**
* Adjust dom bound size when scrolling (dom bound would shrink when scrolling if over the edge of viewMain)
* @param posOfFloatObject
* @param posOfFloatObject The position of float object, relative to sheet content, scale & scrolling does not affect it.
* @param scene
* @param skeleton
* @param worksheet
* @returns ILimitBound
*/
// eslint-disable-next-line max-lines-per-function
export function transformBound2DOMBound(posOfFloatObject: IBoundRectNoAngle, scene: Scene, skeleton: SpreadsheetSkeleton, worksheet: Worksheet, floatDomInfo?: ICanvasFloatDomInfo): ILimitBound {
const { scaleX, scaleY } = scene.getAncestorScale();
const viewMain = scene.getViewport(SHEET_VIEWPORT_KEY.VIEW_MAIN);

const freeze = worksheet.getFreeze();
const { startColumn: viewMainStartColumn, startRow: viewMainStartRow, xSplit: freezedCol, ySplit: freezedRow } = freeze;
/**
* Actually, it means fixed.
*/
const absolute = {
left: true,
left: true, // left means the left of pic is in a viewMainLeft
top: true,
};

Expand All @@ -123,16 +135,20 @@ export function transformBound2DOMBound(posOfFloatObject: IBoundRectNoAngle, sce
};
}
const { left, right, top, bottom } = posOfFloatObject;
let { top: topBoundOfViewArea, left: leftBoundViewArea, viewportScrollX, viewportScrollY } = viewMain;

let { top: viewBoundsTop, left: viewBoundsLeft, viewportScrollX, viewportScrollY } = viewMain;
// specify edge of viewbound. if not specify, use viewMain.
const { boundsOfViewArea, scrollDirectionResponse } = floatDomInfo || {};
if (boundsOfViewArea) {
const { boundsOfViewArea: specBoundsOfViewArea, scrollDirectionResponse } = floatDomInfo || {};
const { rowHeaderWidth, columnHeaderHeight } = skeleton;
const boundsOfViewArea = {
top: columnHeaderHeight,
left: rowHeaderWidth,
};
if (specBoundsOfViewArea) {
if (Tools.isDefine(boundsOfViewArea.top)) {
topBoundOfViewArea = boundsOfViewArea.top;
boundsOfViewArea.top = specBoundsOfViewArea.top;
}
if (Tools.isDefine(boundsOfViewArea.left)) {
leftBoundViewArea = boundsOfViewArea.left;
boundsOfViewArea.left = specBoundsOfViewArea.left;
}
}
if (scrollDirectionResponse === ScrollDirectionResponse.HORIZONTAL) {
Expand All @@ -142,51 +158,75 @@ export function transformBound2DOMBound(posOfFloatObject: IBoundRectNoAngle, sce
viewportScrollX = 0;
}

let offsetLeft: number;
let offsetRight: number;

// viewMain or viewTop
if (left < leftBoundViewArea) {
absolute.left = true;
offsetLeft = ((leftBoundViewArea) + (left - leftBoundViewArea)) * scaleX;
offsetRight = Math.max(
Math.min(
((leftBoundViewArea) + (right - leftBoundViewArea)) * scaleX,
(leftBoundViewArea) * scaleX
),
(right - viewportScrollX) * scaleX);
} else {
let offsetLeft: number = 0;
let offsetRight: number = 0;

/**
* freezed viewport start & end position
*/
const freezeStartY = skeleton.rowStartY(viewMainStartRow - freezedRow) + columnHeaderHeight;
const freezeStartX = skeleton.colStartX(viewMainStartColumn - freezedCol) + rowHeaderWidth;
const freezeEndY = skeleton.rowStartY(viewMainStartRow) + columnHeaderHeight;
const freezeEndX = skeleton.colStartX(viewMainStartColumn) + rowHeaderWidth;

if (freezedCol === 0) {
absolute.left = false;
offsetLeft = Math.max((left - viewportScrollX) * scaleX, (leftBoundViewArea) * scaleX);
offsetRight = Math.max((right - viewportScrollX) * scaleX, (leftBoundViewArea) * scaleX);
offsetLeft = (left - viewportScrollX) * scaleX;
offsetRight = (right - viewportScrollX) * scaleX;
} else {
// freeze
// viewMainLeft may not start at col = 0
// DO NOT use viewMainLeft?.viewBound.right. It's not accurate. there is a delay to set viewBound!
const leftToCanvas = left - (freezeStartX - rowHeaderWidth);
const rightToCanvas = right - (freezeStartX - rowHeaderWidth);
if (right < freezeEndX) {
offsetLeft = leftToCanvas * scaleX;
offsetRight = rightToCanvas * scaleX;
} else if (left <= freezeEndX && right >= freezeEndX) {
offsetLeft = leftToCanvas * scaleX;
offsetRight = Math.max(viewBoundsLeft, (right - viewportScrollX) * scaleX);
} else if (left > freezeEndX) {
absolute.left = false;
offsetLeft = Math.max((left - viewportScrollX) * scaleX, viewBoundsLeft);
offsetRight = Math.max((right - viewportScrollX) * scaleX, viewBoundsLeft);
}
}

let offsetTop: number;
let offsetBottom: number;
// viewMain or viewTop
if (top < topBoundOfViewArea) {
absolute.top = true;
offsetTop = ((topBoundOfViewArea) + (top - topBoundOfViewArea)) * scaleY;
offsetBottom = Math.max(
Math.min(
((topBoundOfViewArea) + (right - topBoundOfViewArea)) * scaleY,
(topBoundOfViewArea) * scaleY
),
(bottom - viewportScrollY) * scaleY
);
} else {
let offsetTop: number = 0;
let offsetBottom: number = 0;
if (freezedRow === 0) {
absolute.top = false;
offsetTop = Math.max((top - viewportScrollY) * scaleY, (topBoundOfViewArea) * scaleY);
offsetBottom = Math.max((bottom - viewportScrollY) * scaleY, (topBoundOfViewArea) * scaleY);
offsetTop = (top - viewportScrollY) * scaleY;
offsetBottom = (bottom - viewportScrollY) * scaleY;
} else {
const topToCanvas = top - (freezeStartY - columnHeaderHeight);
const bottomToCanvas = bottom - (freezeStartY - columnHeaderHeight);
if (bottom < freezeEndY) {
offsetTop = topToCanvas * scaleY;
offsetBottom = bottomToCanvas * scaleY;
} else if (top <= freezeEndY && bottom >= freezeEndY) {
offsetTop = topToCanvas * scaleY;
offsetBottom = Math.max(viewBoundsTop, (bottom - viewportScrollY) * scaleY);
} else if (top > freezeEndY) {
absolute.top = false;
offsetTop = Math.max((top - viewportScrollY) * scaleY, viewBoundsTop);
offsetBottom = Math.max((bottom - viewportScrollY) * scaleY, viewBoundsTop);
}
}

return {
offsetLeft = Math.max(offsetLeft, boundsOfViewArea.left);
offsetTop = Math.max(offsetTop, boundsOfViewArea.top);
offsetRight = Math.max(offsetRight, boundsOfViewArea.left);
offsetBottom = Math.max(offsetBottom, boundsOfViewArea.top);

const rs = {
left: offsetLeft,
right: offsetRight,
top: offsetTop,
bottom: offsetBottom,
absolute,
};
return rs;
}

/**
Expand Down Expand Up @@ -728,6 +768,7 @@ export class SheetCanvasFloatDomManagerService extends Disposable {
};
}

// eslint-disable-next-line max-lines-per-function, complexity
addFloatDomToRange(range: IRange, config: ICanvasFloatDom, domAnchor: Partial<IDOMAnchor>, propId?: string) {
const target = getSheetCommandTarget(this._univerInstanceService, {
unitId: config.unitId,
Expand Down Expand Up @@ -796,8 +837,8 @@ export class SheetCanvasFloatDomManagerService extends Disposable {
if (!skMangerService) {
return;
}
const skeleton = skMangerService.getWorksheetSkeleton(subUnitId);
if (!skeleton) {
const skeletonParam = skMangerService.getWorksheetSkeleton(subUnitId);
if (!skeletonParam) {
return;
}

Expand Down Expand Up @@ -870,9 +911,11 @@ export class SheetCanvasFloatDomManagerService extends Disposable {
const disposableCollection = new DisposableCollection();

const viewMain = scene.getMainViewport();
const { rowHeaderWidth, columnHeaderHeight } = skeletonParam.skeleton;

const boundsOfViewArea: IBoundRectNoAngle = {
top: viewMain.top,
left: viewMain.left,
top: columnHeaderHeight,
left: rowHeaderWidth,
bottom: viewMain.bottom,
right: viewMain.right,
};
Expand All @@ -886,7 +929,7 @@ export class SheetCanvasFloatDomManagerService extends Disposable {
subUnitId,
} as unknown as ICanvasFloatDomInfo;

const initedPosition = calcPosition(domRect, renderObject.renderUnit, skeleton.skeleton, target.worksheet, floatDomInfo);
const initedPosition = calcPosition(domRect, renderObject.renderUnit, skeletonParam.skeleton, target.worksheet, floatDomInfo);
const position$ = new BehaviorSubject<IFloatDomLayout>(initedPosition);
floatDomInfo.position$ = position$;

Expand Down Expand Up @@ -943,7 +986,7 @@ export class SheetCanvasFloatDomManagerService extends Disposable {
height: domAnchor.height ?? newRangePos.height,
zIndex: this._drawingManagerService.getDrawingOrder(unitId, subUnitId).length - 1,
});
const newPos = calcPosition(newRect, renderObject.renderUnit, skeleton.skeleton, target.worksheet, floatDomInfo);
const newPos = calcPosition(newRect, renderObject.renderUnit, skeletonParam.skeleton, target.worksheet, floatDomInfo);
position$.next(newPos);
}));
const skm = this._renderManagerService.getRenderById(unitId)?.with(SheetSkeletonManagerService);
Expand All @@ -956,7 +999,7 @@ export class SheetCanvasFloatDomManagerService extends Disposable {
});

const listener = domRect.onTransformChange$.subscribeEvent(() => {
const newPosition = calcPosition(domRect, renderObject.renderUnit, skeleton.skeleton, target.worksheet, floatDomInfo);
const newPosition = calcPosition(domRect, renderObject.renderUnit, skeletonParam.skeleton, target.worksheet, floatDomInfo);
position$.next(
newPosition
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,10 @@ export class FormatPainterController extends Disposable {
}

private _commandExecutedListener() {
const selectionRenderService = this._renderManagerService.getCurrentTypeOfRenderer(UniverInstanceType.UNIVER_SHEET)!.with(ISheetSelectionRenderService);
const unitId = this._univerInstanceService.getFocusedUnit()?.getUnitId() || '';
const renderUnit = this._renderManagerService.getRenderById(unitId);
if (!renderUnit) return;
const selectionRenderService = renderUnit.with(ISheetSelectionRenderService);

this.disposeWithMe(
selectionRenderService.selectionMoveEnd$.subscribe((selections) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -884,6 +884,36 @@ export class HeaderFreezeRenderController extends Disposable implements IRenderM
right: 0,
});
viewMain.resetPadding();
viewMainLeft.resizeWhenFreezeChange({
left: rowHeaderWidthAndMarginLeft,
top: columnHeaderHeightAndMarginTop,
bottom: 0,
width: 0,
});
viewMainTop.resizeWhenFreezeChange({
left: rowHeaderWidthAndMarginLeft,
top: columnHeaderHeightAndMarginTop,
height: 0,
right: 0,
});
viewMainLeftTop.resizeWhenFreezeChange({
left: rowHeaderWidthAndMarginLeft,
top: columnHeaderHeightAndMarginTop,
width: 0,
height: 0,
});
viewRowTop.resizeWhenFreezeChange({
left: 0,
top: columnHeaderHeightAndMarginTop,
width: rowHeaderWidthAndMarginLeft,
height: 0,
});
viewColumnLeft.resizeWhenFreezeChange({
left: 0,
top: 0,
height: columnHeaderHeightAndMarginTop,
width: 0,
});
} else if (isTopView === true && isLeftView === false) {
// freeze row
const topGap = endSheetView.startY - startSheetView.startY;
Expand Down
Loading

0 comments on commit 9b2274f

Please sign in to comment.