Skip to content

Commit

Permalink
fix(sheet): sheet interceptor and user experience
Browse files Browse the repository at this point in the history
  • Loading branch information
DR-Univer committed Dec 8, 2023
1 parent f384a1e commit 04da06e
Show file tree
Hide file tree
Showing 13 changed files with 152 additions and 55 deletions.
13 changes: 11 additions & 2 deletions packages/core/src/sheets/styles.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { IKeyType, Nullable } from '../shared';
import { Tools } from '../shared';
import type { ICellData, IStyleData } from '../types/interfaces';
import type { ICellDataForSheetInterceptor, IStyleData } from '../types/interfaces';

/**
* Styles in a workbook, cells locate styles based on style IDs
Expand Down Expand Up @@ -88,14 +88,23 @@ export class Styles {
return this._styles;
}

getStyleByCell(cell: Nullable<ICellData>): Nullable<IStyleData> {
getStyleByCell(cell: Nullable<ICellDataForSheetInterceptor>): Nullable<IStyleData> {
let style;
if (cell && Tools.isObject(cell.s)) {
style = cell.s as IStyleData;
} else {
style = cell?.s && this.get(cell.s);
}

const interceptStyle = cell?.interceptorStyle;

if (interceptStyle) {
return {
...style,
...interceptStyle,
} as IStyleData;
}

return style as IStyleData;
}

Expand Down
8 changes: 4 additions & 4 deletions packages/core/src/sheets/view-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import type { IDisposable } from '@wendellhu/redi';
import { remove } from '../common/array';
import type { Nullable } from '../common/type-utils';
import { Disposable, toDisposable } from '../shared/lifecycle';
import type { ICellData } from '../types/interfaces/i-cell-data';
import type { ICellDataForSheetInterceptor } from '../types/interfaces/i-cell-data';

export interface ICellContentInterceptor {
getCell(row: number, col: number): Nullable<ICellData>;
getCell(row: number, col: number): Nullable<ICellDataForSheetInterceptor>;
}

export interface IRowFilteredInterceptor {}
Expand All @@ -21,7 +21,7 @@ export interface ISheetViewModel {
registerRowVisibleInterceptor(interceptor: IRowVisibleInterceptor): IDisposable;
registerColVisibleInterceptor(interceptor: IColVisibleInterceptor): IDisposable;

getCell(row: number, col: number): Nullable<ICellData>;
getCell(row: number, col: number): Nullable<ICellDataForSheetInterceptor>;
}

/**
Expand All @@ -42,7 +42,7 @@ export class SheetViewModel extends Disposable implements ISheetViewModel {
this._colVisibleInterceptors.length = 0;
}

getCell(row: number, col: number): Nullable<ICellData> {
getCell(row: number, col: number): Nullable<ICellDataForSheetInterceptor> {
for (const interceptor of this._cellContentInterceptors) {
const result = interceptor.getCell(row, col);
if (typeof result !== 'undefined') {
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/sheets/worksheet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { createRowColIter } from '../shared/row-col-iter';
import { DEFAULT_WORKSHEET } from '../types/const';
import type { SheetTypes } from '../types/enum';
import { BooleanNumber } from '../types/enum';
import type { ICellData, IFreeze, IRange, IWorksheetData } from '../types/interfaces';
import type { ICellData, ICellDataForSheetInterceptor, IFreeze, IRange, IWorksheetData } from '../types/interfaces';
import { ColumnManager } from './column-manager';
import { Range } from './range';
import { RowManager } from './row-manager';
Expand Down Expand Up @@ -161,7 +161,7 @@ export class Worksheet {
return null;
}

getCell(row: number, col: number): Nullable<ICellData> {
getCell(row: number, col: number): Nullable<ICellDataForSheetInterceptor> {
if (row < 0 || col < 0) {
return null;
}
Expand Down
5 changes: 5 additions & 0 deletions packages/core/src/types/interfaces/i-cell-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ export interface ICellData {
si?: Nullable<string>; // formula id
}

export interface ICellDataForSheetInterceptor extends ICellData {
interceptorStyle?: Nullable<IStyleData>;
isInArrayFormulaRange?: Nullable<boolean>;
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function isICellData(value: any): value is ICellData {
return (
Expand Down
25 changes: 9 additions & 16 deletions packages/engine-render/src/scene.input-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ import type { Viewport } from './viewport';

export class InputManager {
/** The distance in pixel that you have to move to prevent some events */
static DragMovementThreshold = 10; // in pixels
static DragMovementThreshold = 2; // in pixels

/** Time in milliseconds to wait to raise long press events if button is still pressed */
static LongPressDelay = 500; // in milliseconds

/** Time in milliseconds with two consecutive clicks will be considered as a double or triple click */
static DoubleOrTripleClickDelay = 600; // in milliseconds
static DoubleOrTripleClickDelay = 400; // in milliseconds

/** If you need to check double click without raising a single click at first click, enable this flag */
static ExclusiveDoubleClickMode = false;
Expand Down Expand Up @@ -330,34 +330,26 @@ export class InputManager {
private _prePointerDoubleOrTripleClick(evt: IPointerEvent) {
const { clientX, clientY } = evt;

if (this._doubleClickOccurred === 0) {
this._startingPosition.x = clientX;
this._startingPosition.y = clientY;
}

this._doubleClickOccurred += 1;

this._delayedTimeout = setTimeout(() => {
this._resetDoubleClickParam();
}, InputManager.DoubleOrTripleClickDelay);

if (this._doubleClickOccurred < 2) {
return;
}

const isMoveThreshold = this._isPointerSwiping(clientX, clientY);

if (isMoveThreshold) {
this._resetDoubleClickParam();
return;
}

this._doubleClickOccurred += 1;

if (this._doubleClickOccurred === 2) {
this._scene?.pick(Vector2.FromArray([evt.offsetX, evt.offsetY]))?.triggerDblclick(evt);

if (this._scene.onDblclickObserver.hasObservers()) {
this._scene.onDblclickObserver.notifyObservers(evt);
}

this._resetDoubleClickParam();
}

// eslint-disable-next-line no-magic-numbers
Expand All @@ -370,12 +362,13 @@ export class InputManager {

this._resetDoubleClickParam();
}

this._startingPosition.x = clientX;
this._startingPosition.y = clientY;
}

private _resetDoubleClickParam() {
this._doubleClickOccurred = 0;
this._startingPosition.x = Infinity;
this._startingPosition.y = Infinity;
clearTimeout(this._delayedTimeout);
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
import { TinyColor } from '@ctrl/tinycolor';
import type { ICellData, IRange, Nullable } from '@univerjs/core';
import type { ICellDataForSheetInterceptor, ICommandInfo, IRange, Nullable } from '@univerjs/core';
import {
Disposable,
IUniverInstanceService,
ICommandService,
LifecycleStages,
ObjectMatrix,
OnLifecycle,
ThemeService,
toDisposable,
} from '@univerjs/core';
import { FormulaDataModel, FormulaEngineService } from '@univerjs/engine-formula';
import { FormulaDataModel, FormulaEngineService, SetFormulaCalculationResultMutation } from '@univerjs/engine-formula';
import { IRenderManagerService } from '@univerjs/engine-render';
import {
IEditorBridgeService,
IMarkSelectionService,
ISelectionRenderService,
SelectionShape,
SheetSkeletonManagerService,
Expand All @@ -25,19 +24,19 @@ export class FormulaEditorShowController extends Disposable {
private _previousShape: Nullable<SelectionShape>;

constructor(
@Inject(IUniverInstanceService) private _univerInstanceService: IUniverInstanceService,
@Inject(IEditorBridgeService) private _editorBridgeService: IEditorBridgeService,
@Inject(FormulaDataModel) private readonly _formulaDataModel: FormulaDataModel,
@Inject(FormulaEngineService) private readonly _formulaEngineService: FormulaEngineService,
@IMarkSelectionService private readonly _markSelectionService: IMarkSelectionService,
@Inject(ThemeService) private readonly _themeService: ThemeService,
@IUniverInstanceService private readonly _currentService: IUniverInstanceService,
@IRenderManagerService private readonly _renderManagerService: IRenderManagerService,
@ISelectionRenderService private readonly _selectionRenderService: ISelectionRenderService,
@Inject(SheetSkeletonManagerService) private readonly _sheetSkeletonManagerService: SheetSkeletonManagerService
@Inject(SheetSkeletonManagerService) private readonly _sheetSkeletonManagerService: SheetSkeletonManagerService,
@ICommandService private readonly _commandService: ICommandService
) {
super();
this._initInterceptorEditorStart();

this._commandExecutedListener();
}

private _initInterceptorEditorStart() {
Expand All @@ -56,7 +55,7 @@ export class FormulaEditorShowController extends Disposable {
return next(value);
}

let cellInfo: Nullable<ICellData> = null;
let cellInfo: Nullable<ICellDataForSheetInterceptor> = null;

const formulaDataItem = this._formulaDataModel.getFormulaDataItem(
row,
Expand Down Expand Up @@ -99,6 +98,9 @@ export class FormulaEditorShowController extends Disposable {
const matrixRange = arrayFormulaMatrixRange?.[workbookId]?.[worksheetId];
if (matrixRange != null) {
new ObjectMatrix(matrixRange).forValue((rowIndex, columnIndex, range) => {
if (range == null) {
return true;
}
const { startRow, startColumn, endRow, endColumn } = range;
if (rowIndex === row && columnIndex === col) {
this._createArrayFormulaRangeShape(range, workbookId);
Expand All @@ -119,6 +121,7 @@ export class FormulaEditorShowController extends Disposable {
if (cellInfo == null) {
cellInfo = {
f: formulaDataItem.f,
isInArrayFormulaRange: true,
};
}

Expand All @@ -140,6 +143,16 @@ export class FormulaEditorShowController extends Disposable {
);
}

private _commandExecutedListener() {
this.disposeWithMe(
this._commandService.onCommandExecuted((command: ICommandInfo) => {
if (command.id === SetFormulaCalculationResultMutation.id) {
this._removeArrayFormulaRangeShape();
}
})
);
}

private _createArrayFormulaRangeShape(arrayRange: IRange, unitId: string) {
const styleSheet = this._themeService.getCurrentTheme();
const fill = new TinyColor(styleSheet.colorWhite).setAlpha(0).toString();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -843,7 +843,7 @@ export class PromptController extends Disposable {
themeColor = this._stringColor;
}

if (themeColor.length > 0) {
if (themeColor && themeColor.length > 0) {
textRuns.push({
st: startIndex + 1,
ed: endIndex + 2,
Expand Down
6 changes: 3 additions & 3 deletions packages/sheets-numfmt/src/controllers/numfmt.controller.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { ICellData, IRange } from '@univerjs/core';
import type { ICellData, ICellDataForSheetInterceptor, IRange } from '@univerjs/core';
import {
CellValueType,
Disposable,
Expand Down Expand Up @@ -265,13 +265,13 @@ export class NumfmtController extends Disposable implements INumfmtController {
return next(cell);
}

const res: ICellData = { v: numfmtRes };
const res: ICellDataForSheetInterceptor = { v: numfmtRes };

if (info.color) {
const color = this._themeService.getCurrentTheme()[`${info.color}500`];

if (color) {
res.s = { cl: { rgb: color } };
res.interceptorStyle = { cl: { rgb: color } };
}
}

Expand Down
22 changes: 21 additions & 1 deletion packages/sheets-ui/src/controllers/editor-bridge.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
LifecycleStages,
makeCellToSelection,
OnLifecycle,
ThemeService,
} from '@univerjs/core';
import { DeviceInputEventType, getCanvasOffsetByEngine, IRenderManagerService } from '@univerjs/engine-render';
import type { ISelectionWithStyle } from '@univerjs/sheets';
Expand Down Expand Up @@ -34,7 +35,8 @@ export class EditorBridgeController extends Disposable {
@IRenderManagerService private readonly _renderManagerService: IRenderManagerService,
@IEditorBridgeService private readonly _editorBridgeService: IEditorBridgeService,
@Inject(SelectionManagerService) private readonly _selectionManagerService: SelectionManagerService,
@ISelectionRenderService private readonly _selectionRenderService: ISelectionRenderService
@ISelectionRenderService private readonly _selectionRenderService: ISelectionRenderService,
@Inject(ThemeService) private readonly _themeService: ThemeService
) {
super();

Expand Down Expand Up @@ -146,6 +148,23 @@ export class EditorBridgeController extends Disposable {

documentLayoutObject.documentModel?.setZoomRatio(Math.max(scaleX, scaleY));

if (cell?.isInArrayFormulaRange === true) {
const body = documentLayoutObject.documentModel?.getBody();
if (body) {
body.textRuns = [
{
st: 0,
ed: body.dataStream.length,
ts: {
cl: {
rgb: this._themeService.getCurrentTheme().textColorSecondary,
},
},
},
];
}
}

this._commandService.executeCommand(SetActivateCellEditOperation.id, {
position: {
startX,
Expand All @@ -162,6 +181,7 @@ export class EditorBridgeController extends Disposable {
sheetId,
documentLayoutObject,
editorUnitId: DOCS_NORMAL_EDITOR_UNIT_ID_KEY,
isInArrayFormulaRange: cell?.isInArrayFormulaRange,
});
}

Expand Down
Loading

0 comments on commit 04da06e

Please sign in to comment.