import { calculateSelectionArea } from '@/lib/calculate/area'; import { GroupArea, GroupPin } from '@/lib/types/group'; import { getMinAndMax } from '@/lib/utils/math'; import { getMinAndMaxColumn } from '@/lib/utils/row-column'; import { Store } from '@/lib/store'; import { BodyMenuOperator } from '@/lib/operator/BodyMenuOperator'; export class SelectingOperator { private readonly store: Store; private lastUpdateRowId: string; private lastUpdateColumnId: string; private bodyMenuOperator: BodyMenuOperator; constructor(store: Store, bodyMenuOperator: BodyMenuOperator) { this.store = store; this.lastUpdateColumnId = ''; this.lastUpdateRowId = ''; this.bodyMenuOperator = bodyMenuOperator; } public activeSelection(columnId: string, rowId: string) { this.silentEnvironment(); this.store.mutation.activeSelecting(rowId, columnId); this.store.mutation.triggerSelectingChanging(true); } public updateSelection(columnId: string, rowId: string) { if (this.lastUpdateRowId === rowId && this.lastUpdateColumnId === columnId) { return; } // 移除已有被点击事件激活的单元格 this.store.mutation.inactiveClicked(); this.lastUpdateColumnId = columnId; this.lastUpdateRowId = rowId; this.store.mutation.updateSelecting(rowId, columnId); const { leftArea, rightArea, scrollArea } = calculateSelectionArea( this.store.state.index.columnGroupRecord.left.ids.length, this.store.state.index.columnGroupRecord.scroll.ids.length, )(this.store.state.selectionStatus); this.store.mutation.updateSelectArea({ leftArea, rightArea, scrollArea }); } public finishSelection() { this.store.mutation.triggerSelectingChanging(false); } public getHitSelectionWhenSingleHit() { return this.store.state.selectionStatus.leftArea.hit ? this.store.state.selectionStatus.leftArea : this.store.state.selectionStatus.scrollArea.hit ? this.store.state.selectionStatus.scrollArea : this.store.state.selectionStatus.rightArea; } public getHitAreaWhenSingleHit(): GroupArea { if (this.store.state.selectionStatus.leftArea.hit) return { pin: GroupPin.left, column: this.store.state.selectionStatus.leftArea.column, row: this.store.state.selectionStatus.leftArea.row, }; if (this.store.state.selectionStatus.rightArea.hit) return { pin: GroupPin.right, column: this.store.state.selectionStatus.rightArea.column, row: this.store.state.selectionStatus.rightArea.row, }; return { pin: GroupPin.scroll, column: this.store.state.selectionStatus.scrollArea.column, row: this.store.state.selectionStatus.scrollArea.row, }; } public getGroupPinWhenSingleHit() { return this.store.state.selectionStatus.leftArea.hit ? GroupPin.left : this.store.state.selectionStatus.scrollArea.hit ? GroupPin.scroll : GroupPin.right; } public getTopLeftCellWhenSingleHit() { const { minColumn, minRowIndex } = this.getAngleCell(); return { columnPin: minColumn.pin, columnIndex: minColumn.index, columnId: this.store.state.index.columnGroupRecord[minColumn.pin].ids[minColumn.index], rowIndex: minRowIndex, rowId: this.store.state.view.rowIndex2Id[minRowIndex], }; } public getTopRightCellWhenSingleHit() { const { maxColumn, minRowIndex } = this.getAngleCell(); return { columnPin: maxColumn.pin, columnIndex: maxColumn.index, columnId: this.store.state.index.columnGroupRecord[maxColumn.pin].ids[maxColumn.index], rowIndex: minRowIndex, rowId: this.store.state.view.rowIndex2Id[minRowIndex], }; } public getBottomLeftCellWhenSingleHit() { const { minColumn, maxRowIndex } = this.getAngleCell(); return { columnPin: minColumn.pin, columnIndex: minColumn.index, columnId: this.store.state.index.columnGroupRecord[minColumn.pin].ids[minColumn.index], rowIndex: maxRowIndex, rowId: this.store.state.view.rowIndex2Id[maxRowIndex], }; } private getAngleCell() { const [minRowIndex, maxRowIndex] = getMinAndMax( this.store.state.selectionStatus.startRowIndex, this.store.state.selectionStatus.endRowIndex, ); const [minColumn, maxColumn] = getMinAndMaxColumn( this.store.state.selectionStatus.startColumn, this.store.state.selectionStatus.endColumn, ); return { minRowIndex, maxRowIndex, minColumn, maxColumn, }; } private silentEnvironment() { this.bodyMenuOperator.inactive(); } }