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

feat(sheet): range selector #1463

Merged
merged 10 commits into from
Mar 6, 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
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export const SidebarOperation: ICommand = {
onClose: () => {
editorService.setOperationSheetUnitId(null);
editorService.setOperationSheetSubUnitId(null);
editorService.changeEditorFocus();
editorService.closeRangePrompt();
},
});
break;
Expand All @@ -52,7 +52,7 @@ export const SidebarOperation: ICommand = {
default:
editorService.setOperationSheetUnitId(null);
editorService.setOperationSheetSubUnitId(null);
editorService.changeEditorFocus();
editorService.closeRangePrompt();
sidebarService.close();
break;
}
Expand Down
24 changes: 19 additions & 5 deletions examples/src/plugins/debugger/views/test-editor/TestTextEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@

import React from 'react';

import { TextEditor } from '@univerjs/ui';
import { RangeSelector, TextEditor } from '@univerjs/ui';
import { IUniverInstanceService } from '@univerjs/core';
import { useDependency } from '@wendellhu/redi/react-bindings';

const containerStyle: React.CSSProperties = {
position: 'absolute',
Expand All @@ -35,17 +37,29 @@ const editorStyle: React.CSSProperties = {
* @returns
*/
export const TestEditorContainer = () => {
const univerInstanceService = useDependency(IUniverInstanceService);
const workbook = univerInstanceService.getCurrentUniverSheetInstance();
if (workbook == null) {
return;
}

const unitId = workbook.getUnitId();

const sheetId = workbook.getActiveSheet().getSheetId();

return (
<div
style={containerStyle}
>
<TextEditor id="test-editor-1" isReadonly={true} style={editorStyle} canvasStyle={{ fontSize: 10 }} value="I found one cent on the roadside." />
<TextEditor id="test-editor-1" openForSheetUnitId={unitId} openForSheetSubUnitId={sheetId} isReadonly={true} style={editorStyle} canvasStyle={{ fontSize: 10 }} value="I found one cent on the roadside." />
<br></br>
<TextEditor id="test-editor-2" openForSheetUnitId={unitId} openForSheetSubUnitId={sheetId} onlyInputFormula={true} style={editorStyle} canvasStyle={{ fontSize: 10 }} />
<br></br>
<TextEditor id="test-editor-2" onlyInputFormula={true} style={editorStyle} canvasStyle={{ fontSize: 10 }} />
<TextEditor id="test-editor-3" openForSheetUnitId={unitId} openForSheetSubUnitId={sheetId} onlyInputRange={true} style={editorStyle} canvasStyle={{ fontSize: 10 }} />
<br></br>
<TextEditor id="test-editor-3" onlyInputRange={true} style={editorStyle} canvasStyle={{ fontSize: 10 }} />
<TextEditor id="test-editor-4" openForSheetUnitId={unitId} openForSheetSubUnitId={sheetId} isSingle={false} onlyInputContent={true} style={{ ...editorStyle, height: '140px' }} canvasStyle={{ fontSize: 14 }} />
<br></br>
<TextEditor id="test-editor-4" isSingle={false} onlyInputContent={true} style={{ ...editorStyle, height: '140px' }} canvasStyle={{ fontSize: 14 }} />
<RangeSelector id="test-rangeSelector-1" openForSheetUnitId={unitId} openForSheetSubUnitId={sheetId} />
</div>
);
};
6 changes: 5 additions & 1 deletion packages/design/src/components/dialog/index.module.less
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,13 @@

&-title {
margin: 0;
padding: 24px 28px 20px;
// padding: 24px 28px 20px;
font-size: var(--font-size-lg);
font-weight: 500;

> div:first-child {
padding: 24px 28px 20px;
}
}

&-content {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@ import type { ICommandInfo, Nullable } from '@univerjs/core';
import { Disposable, ICommandService, IUniverInstanceService, LifecycleStages, OnLifecycle } from '@univerjs/core';
import { Inject } from '@wendellhu/redi';

import { ITextSelectionRenderManager, ScrollBar } from '@univerjs/engine-render';
import { IRenderManagerService, ITextSelectionRenderManager, ScrollBar } from '@univerjs/engine-render';
import type { IRichTextEditingMutationParams } from '@univerjs/docs';
import { CoverContentCommand, DocSkeletonManagerService, RichTextEditingMutation, VIEWPORT_KEY } from '@univerjs/docs';
import { IEditorService, SetEditorResizeOperation } from '@univerjs/ui';
import { fromEvent } from 'rxjs';

@OnLifecycle(LifecycleStages.Rendered, DocEditorBridgeController)
export class DocEditorBridgeController extends Disposable {
Expand All @@ -32,7 +33,8 @@ export class DocEditorBridgeController extends Disposable {
@Inject(DocSkeletonManagerService) private readonly _docSkeletonManagerService: DocSkeletonManagerService,
@IEditorService private readonly _editorService: IEditorService,
@ICommandService private readonly _commandService: ICommandService,
@ITextSelectionRenderManager private readonly _textSelectionRenderManager: ITextSelectionRenderManager
@ITextSelectionRenderManager private readonly _textSelectionRenderManager: ITextSelectionRenderManager,
@IRenderManagerService private readonly _renderManagerService: IRenderManagerService

) {
super();
Expand Down Expand Up @@ -159,6 +161,23 @@ export class DocEditorBridgeController extends Disposable {
this._textSelectionRenderManager.blur();
})
);

this.disposeWithMe(
this._textSelectionRenderManager.onBlur$.subscribe(() => {
const unitId = this._currentUniverService.getCurrentUniverDocInstance().getUnitId();
if (unitId == null) {
return;
}

const editor = this._editorService.getEditor(unitId);

if (editor == null || editor.isSheetEditor()) {
return;
}

this._editorService.blur();
})
);
}

private _initialFocus() {
Expand All @@ -168,6 +187,39 @@ export class DocEditorBridgeController extends Disposable {
this._textSelectionRenderManager.addTextRanges([textRange]);
})
);

this.disposeWithMe(
fromEvent(window, 'mousedown').subscribe((event) => {
const target = event.target as HTMLElement;
const hasSearch = target.classList[0];
if (hasSearch?.indexOf('univer-formula-search') > -1 || hasSearch?.indexOf('univer-formula-help') > -1 || hasSearch?.indexOf('formula-help-decorator') || hasSearch?.indexOf('univer-formula-help-param')) {
this._editorService.changeSpreadsheetFocusState(true);
event.stopPropagation();
return;
}
this._editorService.changeSpreadsheetFocusState(false);
})
);

// this.disposeWithMe(
// fromEvent(window, 'mousedown').subscribe(() => {
// this._editorService.changeSpreadsheetFocusState(false);
// })
// );

const currentUniverSheet = this._currentUniverService.getAllUniverSheetsInstance();
currentUniverSheet.forEach((unit) => {
const unitId = unit.getUnitId();
const render = this._renderManagerService.getRenderById(unitId);
const canvasEle = render?.engine.getCanvas().getCanvasEle();
if (canvasEle == null) {
return;
}
fromEvent(canvasEle, 'mousedown').subscribe((evt) => {
this._editorService.changeSpreadsheetFocusState(true);
evt.stopPropagation();
});
});
}

private _initialValueChange() {
Expand Down
21 changes: 18 additions & 3 deletions packages/docs-ui/src/controllers/text-selection.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,23 @@ export class TextSelectionController extends Disposable {
this._currentUniverService.setCurrentUniverDocInstance(unitId);
}

this._textSelectionRenderManager.eventTrigger(evt);

this._setEditorFocus(unitId);
if (this._editorService.getEditor(unitId)) {
/**
* To accommodate focus switching between different editors.
* Since the editor for Univer is canvas-based,
* it primarily relies on focus and cannot use the focus event.
* Our editor's focus monitoring is based on PointerDown.
* The order of occurrence is such that PointerDown comes first.
* Translate the above text into English.
*/
setTimeout(() => {
Jocs marked this conversation as resolved.
Show resolved Hide resolved
this._textSelectionRenderManager.eventTrigger(evt);

this._setEditorFocus(unitId);
}, 0);
} else {
this._textSelectionRenderManager.eventTrigger(evt);
}

if (evt.button !== 2) {
state.stopPropagation();
Expand Down Expand Up @@ -168,6 +182,7 @@ export class TextSelectionController extends Disposable {
this._editorService.setOperationSheetUnitId(workbook.getUnitId());
// this._editorService.setOperationSheetSubUnitId(workbook.getActiveSheet().getSheetId());
}

this._editorService.focusStyle(unitId);
}

Expand Down
15 changes: 15 additions & 0 deletions packages/engine-formula/src/basics/match-token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,18 @@ export function normalizeSheetName(sheetName: string) {
}
return sheetName;
}

/**
* Determine whether the character is a token keyword for the formula engine.
* @param char
*/
export function matchRefDrawToken(char: string) {
return (
(isFormulaLexerToken(char) &&
char !== matchToken.CLOSE_BRACES &&
char !== matchToken.CLOSE_BRACKET &&
char !== matchToken.SINGLE_QUOTATION &&
char !== matchToken.DOUBLE_QUOTATION) ||
char === ' '
);
}
1 change: 1 addition & 0 deletions packages/engine-formula/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,4 @@ export { FormulaExecutedStateType, type IAllRuntimeData } from './services/runti
export { SetNumfmtFormulaDataMutation } from './commands/mutations/set-numfmt-formula-data.mutation';
export type { ISetNumfmtFormulaDataMutationParams } from './commands/mutations/set-numfmt-formula-data.mutation';
export { isReferenceString } from './basics/regex';
export { matchRefDrawToken } from './basics/match-token';
2 changes: 2 additions & 0 deletions packages/engine-render/src/canvas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ export class Canvas {
this._canvasEle.style.left = '0';
this._canvasEle.style.zIndex = '8';

this._canvasEle.className = 'univer-render-canvas';

// support focus
this._canvasEle.tabIndex = 1;
this._canvasEle.style.touchAction = 'none';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,9 +214,11 @@ export class TextSelectionRenderManager extends RxDisposable implements ITextSel

private _input!: HTMLDivElement;

private _moveObserver: Nullable<Observer<IPointerEvent | IMouseEvent>>;
private _moveObservers: Nullable<Observer<IPointerEvent | IMouseEvent>>[] = [];

private _upObserver: Nullable<Observer<IPointerEvent | IMouseEvent>>;
private _upObservers: Nullable<Observer<IPointerEvent | IMouseEvent>>[] = [];

private _scrollTimers: ScrollTimer[] = [];

private _viewportScrollX: number = 0;

Expand Down Expand Up @@ -479,6 +481,7 @@ export class TextSelectionRenderManager extends RxDisposable implements ITextSel
scene.disableEvent();

const scrollTimer = ScrollTimer.create(scene);
this._scrollTimers.push(scrollTimer);
scrollTimer.startScroll(evtOffsetX, evtOffsetY);

const { scrollX, scrollY } = getCurrentScrollXY(scrollTimer);
Expand All @@ -492,7 +495,7 @@ export class TextSelectionRenderManager extends RxDisposable implements ITextSel

let preMoveOffsetY = evtOffsetY;

this._moveObserver = scene.onPointerMoveObserver.add((moveEvt: IPointerEvent | IMouseEvent) => {
this._moveObservers.push(scene.onPointerMoveObserver.add((moveEvt: IPointerEvent | IMouseEvent) => {
const { offsetX: moveOffsetX, offsetY: moveOffsetY } = moveEvt;
scene.setCursor(CURSOR_TYPE.TEXT);

Expand All @@ -508,11 +511,23 @@ export class TextSelectionRenderManager extends RxDisposable implements ITextSel

preMoveOffsetX = moveOffsetX;
preMoveOffsetY = moveOffsetY;
});
}));

this._upObservers.push(scene.onPointerUpObserver.add(() => {
// scene.onPointerMoveObserver.remove(this._moveObserver);
// scene.onPointerUpObserver.remove(this._upObserver);

this._moveObservers.forEach((obs) => {
obs?.dispose();
});

this._upObservers.forEach((obs) => {
obs?.dispose();
});

this._moveObservers = [];

this._upObserver = scene.onPointerUpObserver.add(() => {
scene.onPointerMoveObserver.remove(this._moveObserver);
scene.onPointerUpObserver.remove(this._upObserver);
this._upObservers = [];

scene.enableEvent();

Expand All @@ -523,9 +538,14 @@ export class TextSelectionRenderManager extends RxDisposable implements ITextSel
isEditing: false,
});

scrollTimer.dispose();
this._scrollTimers.forEach((timer) => {
timer?.dispose();
});

this._scrollTimers = [];

this._updateInputPosition();
});
}));
}

removeAllTextRanges() {
Expand Down
6 changes: 5 additions & 1 deletion packages/engine-render/src/engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,11 @@ export class Engine extends ThinEngine<Scene> {
* preventing the events from becoming ineffective once the mouse leaves the host.
*/
override setRemainCapture() {
this._canvasEle.setPointerCapture(this._remainCapture);
try {
this._canvasEle.setPointerCapture(this._remainCapture);
} catch {
console.warn('no capture');
}
}

getPixelRatio() {
Expand Down
17 changes: 15 additions & 2 deletions packages/engine-render/src/shape/base-scroll-bar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,17 @@ export class BaseScrollBar extends Disposable {
) {
return 1;
}
return (

const ratio = (
((this.horizontalThumbWidth - this.horizontalMinusMiniThumb) * this.miniThumbRatioX) /
this.horizontalBarWidth
);

if (Number.isNaN(ratio)) {
return 1;
} else {
return ratio;
}
}

get ratioScrollY(): number {
Expand All @@ -101,9 +108,15 @@ export class BaseScrollBar extends Disposable {
) {
return 1;
}
return (
const ratio = (
((this.verticalThumbHeight - this.verticalMinusMiniThumb) * this.miniThumbRatioY) / this.verticalBarHeight
);

if (Number.isNaN(ratio)) {
return 1;
} else {
return ratio;
}
}

get miniThumbRatioX() {
Expand Down
8 changes: 8 additions & 0 deletions packages/engine-render/src/viewport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,8 @@ export class Viewport {
x /= scaleX;
} else if (this.actualScrollX !== undefined) {
x = this.actualScrollX;
} else {
x = 0;
}

if (this._scrollBar.ratioScrollY !== 0) {
Expand All @@ -453,6 +455,8 @@ export class Viewport {
y /= scaleY;
} else if (this.actualScrollY !== undefined) {
y = this.actualScrollY;
} else {
y = 0;
}

// console.log(y, this._scrollBar.miniThumbRatioY);
Expand All @@ -461,10 +465,14 @@ export class Viewport {
} else {
if (this.actualScrollX !== undefined) {
x = this.actualScrollX;
} else {
x = 0;
}

if (this.actualScrollY !== undefined) {
y = this.actualScrollY;
} else {
y = 0;
}
}

Expand Down
Loading
Loading