import { GroupArea, GroupSelection } from '@/lib/types/group'; import { Store } from '@/lib/store'; import { BODY_CELL, BODY_CELL_HANDLE, ROLE } from '@/lib/constants/dom-role'; import { getElementByRole } from '@/lib/utils/dom'; import { CELL_EDITABLE, CELL_SELECTED } from '@/lib/constants/dom-class'; import { BodyMenuOperator } from '@/lib/operator/BodyMenuOperator'; import {log} from "@/lib/utils/log"; export class BodyClickedOperator { private readonly store: Store; private bodyMenuOperator: BodyMenuOperator; constructor(store: Store) { this.store = store; } public concatBodyMenu(bodyMenuOperator: BodyMenuOperator) { this.bodyMenuOperator = bodyMenuOperator; } public isSomeCellClicked() { return !!this.store.state.activeStatus.clickedBodyCell; } public getClickedPin() { return this.store.state.activeStatus.clickedBodyCell.pin; } public getClickedArea(): GroupArea { const { columnId, rowId } = this.store.state.activeStatus.clickedBodyCell; const columnIndex = this.store.state.index.columnRecord[columnId].index; const rowIndex = this.store.state.view.rowRecord[rowId].index; return { pin: this.store.state.activeStatus.clickedBodyCell.pin, column: [columnIndex, columnIndex], row: [rowIndex, rowIndex], }; } public getClickedSelection(): GroupSelection { const { columnId, rowId } = this.store.state.activeStatus.clickedBodyCell; const columnIndex = this.store.state.index.columnRecord[columnId].index; const rowIndex = this.store.state.view.rowRecord[rowId].index; return { hit: true, column: [columnIndex, columnIndex], row: [rowIndex, rowIndex], }; } public click(e: PointerEvent) { // 防止与计算按压事件冲突 if (BODY_CELL_HANDLE === (e.target as Element).getAttribute(ROLE)) { return; } const cellElement = getElementByRole(e.target as Element, BODY_CELL); if (cellElement) { const rowId = cellElement.getAttribute('row-id'); const columnId = cellElement.getAttribute('column-id'); const pin = this.store.state.index.columnRecord[columnId].pin; // 已经被双击的无法附加单击效果 const dbCell = this.getDbClickedBodyCell(); if ( dbCell && dbCell.rowId === rowId && dbCell.columnId === columnId && dbCell.pin === pin ) { return; } this.store.mutation.inactiveRightMenu(); this.store.mutation.destroySelecting(); this.store.mutation.clickedBodyCell(pin, rowId, columnId); } } public dbClick(e: PointerEvent) { const cellElement = getElementByRole(e.target as Element, BODY_CELL); if (!this.isEditableCell(e)) return; if (cellElement) { const rowId = cellElement.getAttribute('row-id'); const columnId = cellElement.getAttribute('column-id'); const pin = this.store.state.index.columnRecord[columnId].pin; this.store.mutation.dbClickedBodyCell(pin, rowId, columnId); } } public getDbClickedBodyCell() { return this.store.state.activeStatus.dbClickedBodyCell; } public contextMenu(e: PointerEvent) { log('[event]onBodyContextMenu'); // 假如目前已经有选中区域,切正在点击区域则直接唤起菜单,否则先激活单元格再唤起菜单 if (!this.isHitSelectingArea(e)) { this.click(e); } this.bodyMenuOperator.active(e).then(); } public inactiveClicked() { this.store.mutation.inactiveClicked(); } private isEditableCell = (e: PointerEvent) => { const cellElement = getElementByRole(e.target as Element, BODY_CELL); return cellElement && cellElement.className.split(' ').includes(CELL_EDITABLE); }; private isHitSelectingArea = (e: PointerEvent) => { const cellElement = getElementByRole(e.target as Element, BODY_CELL); return cellElement && cellElement.className.split(' ').includes(CELL_SELECTED); }; }