mirror of
https://github.com/dream-num/univer.git
synced 2026-09-24 15:32:18 +08:00
fix(docs): scroll to selection (#3458)
This commit is contained in:
@@ -44,6 +44,7 @@ import { getDocObject } from '../basics/component-tools';
|
||||
import { findAboveCell, findBellowCell, findLineBeforeAndAfterTable, findTableAfterLine, findTableBeforeLine, firstLineInCell, firstLineInTable, lastLineInCell, lastLineInTable } from '../basics/table';
|
||||
import { MoveCursorOperation, MoveSelectionOperation } from '../commands/operations/doc-cursor.operation';
|
||||
import { NodePositionConvertToCursor } from '../services/selection/convert-text-range';
|
||||
import { DocBackScrollRenderController } from './render-controllers/back-scroll.render-controller';
|
||||
import type { IMoveCursorOperationParams } from '../commands/operations/doc-cursor.operation';
|
||||
|
||||
@OnLifecycle(LifecycleStages.Rendered, DocMoveCursorController)
|
||||
@@ -167,6 +168,8 @@ export class DocMoveCursorController extends Disposable {
|
||||
style,
|
||||
},
|
||||
], false);
|
||||
|
||||
this._scrollToFocusNodePosition(docDataModel.getUnitId(), focusOffset);
|
||||
} else {
|
||||
const focusGlyph = skeleton.findNodeByCharIndex(focusOffset, segmentId, segmentPage);
|
||||
const documentOffsetConfig = docObject.document.getOffsetConfig();
|
||||
@@ -206,6 +209,8 @@ export class DocMoveCursorController extends Disposable {
|
||||
style,
|
||||
},
|
||||
], false);
|
||||
|
||||
this._scrollToFocusNodePosition(docDataModel.getUnitId(), newActiveRange.endOffset);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -298,6 +303,8 @@ export class DocMoveCursorController extends Disposable {
|
||||
style,
|
||||
},
|
||||
], false);
|
||||
|
||||
this._scrollToFocusNodePosition(docDataModel.getUnitId(), cursor);
|
||||
} else {
|
||||
const startNode = skeleton.findNodeByCharIndex(startOffset, segmentId, segmentPage);
|
||||
const endNode = skeleton.findNodeByCharIndex(endOffset, segmentId, segmentPage);
|
||||
@@ -331,6 +338,7 @@ export class DocMoveCursorController extends Disposable {
|
||||
style,
|
||||
},
|
||||
], false);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -346,6 +354,8 @@ export class DocMoveCursorController extends Disposable {
|
||||
style,
|
||||
},
|
||||
], false);
|
||||
|
||||
this._scrollToFocusNodePosition(docDataModel.getUnitId(), newActiveRange.endOffset);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -552,6 +562,20 @@ export class DocMoveCursorController extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
private _scrollToFocusNodePosition(unitId: string, offset: number) {
|
||||
const backScrollController = this._renderManagerService.getRenderById(unitId)?.with(DocBackScrollRenderController);
|
||||
if (backScrollController == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Scroll to the offset.
|
||||
backScrollController.scrollToRange({
|
||||
startOffset: offset,
|
||||
endOffset: offset,
|
||||
collapsed: true,
|
||||
});
|
||||
}
|
||||
|
||||
private _getDocObject() {
|
||||
return getDocObject(this._univerInstanceService, this._renderManagerService);
|
||||
}
|
||||
|
||||
+19
-26
@@ -14,14 +14,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Inject, IUniverInstanceService, RxDisposable } from '@univerjs/core';
|
||||
import { Inject, RxDisposable } from '@univerjs/core';
|
||||
import { DocSelectionManagerService, DocSkeletonManagerService } from '@univerjs/docs';
|
||||
import { IRenderManagerService } from '@univerjs/engine-render';
|
||||
import { IEditorService } from '@univerjs/ui';
|
||||
import { takeUntil } from 'rxjs';
|
||||
import type { DocumentDataModel, ITextRange, Nullable } from '@univerjs/core';
|
||||
import type { INodePosition, IRenderContext, IRenderModule } from '@univerjs/engine-render';
|
||||
import { getDocObject } from '../../basics/component-tools';
|
||||
import type { Documents, INodePosition, IRenderContext, IRenderModule } from '@univerjs/engine-render';
|
||||
import { VIEWPORT_KEY } from '../../basics/docs-view-key';
|
||||
import { NodePositionConvertToCursor } from '../../services/selection/convert-text-range';
|
||||
import { getAnchorBounding } from '../../services/selection/text-range';
|
||||
@@ -33,8 +31,7 @@ export class DocBackScrollRenderController extends RxDisposable implements IRend
|
||||
private readonly _context: IRenderContext<DocumentDataModel>,
|
||||
@Inject(DocSelectionManagerService) private readonly _textSelectionManagerService: DocSelectionManagerService,
|
||||
@IEditorService private readonly _editorService: IEditorService,
|
||||
@Inject(IUniverInstanceService) private readonly _univerInstanceService: IUniverInstanceService,
|
||||
@IRenderManagerService private readonly _renderManagerService: IRenderManagerService
|
||||
@Inject(DocSkeletonManagerService) private readonly _docSkeletonManagerService: DocSkeletonManagerService
|
||||
) {
|
||||
super();
|
||||
|
||||
@@ -49,34 +46,34 @@ export class DocBackScrollRenderController extends RxDisposable implements IRend
|
||||
|
||||
const { isEditing, unitId } = params;
|
||||
|
||||
if (isEditing) {
|
||||
this._scrollToSelection(unitId);
|
||||
if (unitId !== this._context.unitId || !isEditing) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._scrollToSelection();
|
||||
});
|
||||
}
|
||||
|
||||
scrollToRange(unitId: string, range: ITextRange) {
|
||||
const docSkeletonManagerService = this._renderManagerService.getRenderById(unitId)?.with(DocSkeletonManagerService);
|
||||
const skeleton = docSkeletonManagerService?.getSkeleton();
|
||||
scrollToRange(range: ITextRange) {
|
||||
const skeleton = this._docSkeletonManagerService.getSkeleton();
|
||||
if (!skeleton) {
|
||||
return;
|
||||
}
|
||||
const { startOffset } = range;
|
||||
const anchorNodePosition = skeleton.findNodePositionByCharIndex(startOffset);
|
||||
// const focusNodePosition = startOffset !== endOffset ? skeleton.findNodePositionByCharIndex(endOffset) : null;
|
||||
this.scrollToNode(unitId, anchorNodePosition);
|
||||
|
||||
this.scrollToNode(anchorNodePosition);
|
||||
}
|
||||
|
||||
scrollToNode(unitId: string, startNodePosition: Nullable<INodePosition>) {
|
||||
const docObject = this._getDocObject();
|
||||
const docSkeletonManagerService = this._renderManagerService.getRenderById(unitId)?.with(DocSkeletonManagerService);
|
||||
const skeleton = docSkeletonManagerService?.getSkeleton();
|
||||
scrollToNode(startNodePosition: Nullable<INodePosition>) {
|
||||
const { unitId, scene, mainComponent } = this._context;
|
||||
const skeleton = this._docSkeletonManagerService.getSkeleton();
|
||||
|
||||
if (docObject == null || skeleton == null) {
|
||||
if (mainComponent == null || skeleton == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
const documentOffsetConfig = docObject.document.getOffsetConfig();
|
||||
const documentOffsetConfig = (mainComponent as Documents).getOffsetConfig();
|
||||
const { docsLeft, docsTop } = documentOffsetConfig;
|
||||
|
||||
const convertor = new NodePositionConvertToCursor(documentOffsetConfig, skeleton);
|
||||
@@ -89,7 +86,7 @@ export class DocBackScrollRenderController extends RxDisposable implements IRend
|
||||
|
||||
const top = aTop + docsTop;
|
||||
|
||||
const viewportMain = docObject.scene.getViewport(VIEWPORT_KEY.VIEW_MAIN);
|
||||
const viewportMain = scene.getViewport(VIEWPORT_KEY.VIEW_MAIN);
|
||||
|
||||
const isEditor = !!this._editorService.getEditor(unitId);
|
||||
|
||||
@@ -126,7 +123,7 @@ export class DocBackScrollRenderController extends RxDisposable implements IRend
|
||||
}
|
||||
|
||||
// Let the selection show on the current screen.
|
||||
private _scrollToSelection(unitId: string) {
|
||||
private _scrollToSelection() {
|
||||
const activeTextRange = this._textSelectionManagerService.getActiveTextRange();
|
||||
if (activeTextRange == null) {
|
||||
return;
|
||||
@@ -138,10 +135,6 @@ export class DocBackScrollRenderController extends RxDisposable implements IRend
|
||||
return;
|
||||
}
|
||||
|
||||
this.scrollToNode(unitId, startNodePosition);
|
||||
}
|
||||
|
||||
private _getDocObject() {
|
||||
return getDocObject(this._univerInstanceService, this._renderManagerService);
|
||||
this.scrollToNode(startNodePosition);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -448,6 +448,10 @@ export class DocSelectionRenderService extends RxDisposable implements IRenderMo
|
||||
|
||||
this._moving(moveOffsetX, moveOffsetY);
|
||||
|
||||
scrollTimer.scrolling(moveOffsetX, moveOffsetY, () => {
|
||||
this._moving(moveOffsetX, moveOffsetY);
|
||||
});
|
||||
|
||||
preMoveOffsetX = moveOffsetX;
|
||||
preMoveOffsetY = moveOffsetY;
|
||||
}));
|
||||
|
||||
@@ -29,7 +29,7 @@ function scrollToTop(accessor: IAccessor) {
|
||||
endOffset: 0,
|
||||
};
|
||||
if (backScrollController) {
|
||||
backScrollController.scrollToRange(DOCS_ZEN_EDITOR_UNIT_ID_KEY, textRange as ITextRange);
|
||||
backScrollController.scrollToRange(textRange as ITextRange);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user