import Ratio from "./math/Ratio"; import { Cell, CellRef, Doc, Grid, mapRowsInRange } from "./types"; import { ActiveCellSelection, Selection } from "./selection"; import renderGrid, { RenderedGrid } from "./components/grid/renderGrid"; function defaultDoc(): Doc { const defaultCells: Cell[] = Array.from({ length: 16 }, () => ({ widthRatio: new Ratio(1, 16), })); return { grids: [ { id: window.crypto.randomUUID(), baseCellSize: 42, baseCellWidthRatio: new Ratio(1, 16), parts: [ { rows: Array.from({ length: 4 }, () => ({ cells: [...defaultCells], })), }, ], }, { id: window.crypto.randomUUID(), baseCellSize: 42, baseCellWidthRatio: new Ratio(1, 16), parts: [ { rows: Array.from({ length: 2 }, () => ({ cells: [...defaultCells], })), }, { rows: Array.from({ length: 2 }, () => ({ cells: [...defaultCells], })), }, ], }, ], }; } export default class Notive { #doc: Doc = defaultDoc(); get doc() { return this.#doc; } #gridsById = Object.fromEntries( this.#doc.grids.map((grid) => [grid.id, renderGrid(grid)]), ); getGrid(id: string): RenderedGrid | undefined { return this.#gridsById[id]; } #selection?: Selection; get selection() { return this.#selection; } #pendingSelection?: Selection; get pendingSelection() { return this.#pendingSelection; } selectCell(gridId: string, cellRef: CellRef) { this.#selection = new ActiveCellSelection(gridId, cellRef); this.#dispatchSelectionChanged(); } startSelecting(gridId: string, cellRef: CellRef) { this.#pendingSelection = new ActiveCellSelection(gridId, cellRef); this.#dispatchSelectionChanged(); } extendSelection(cellRef: CellRef) { const newSelection = this.pendingSelection?.extend(cellRef); if (newSelection !== this.pendingSelection) { this.#pendingSelection = newSelection; this.#dispatchSelectionChanged(); } } finishSelecting() { this.#selection = this.pendingSelection; this.#pendingSelection = undefined; this.#dispatchSelectionChanged(); } #dispatchSelectionChanged() { window.dispatchEvent(new CustomEvent("ntv:selectionchange")); } subdivideSelection(subdivisions: number) { const selection = this.selection; if (!selection) return; const newDoc = mapRowsInRange( this.doc, selection.gridId, selection.startCellRef(), selection.endCellRef(), (row, rowRef) => { return row; }, ); } } window.notive = new Notive();