summaryrefslogtreecommitdiff
path: root/web/src/index.ts
diff options
context:
space:
mode:
Diffstat (limited to 'web/src/index.ts')
-rw-r--r--web/src/index.ts80
1 files changed, 75 insertions, 5 deletions
diff --git a/web/src/index.ts b/web/src/index.ts
index f923c56..35af24c 100644
--- a/web/src/index.ts
+++ b/web/src/index.ts
@@ -1,7 +1,10 @@
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";
+import renderGrid, {
+ getRenderedCell,
+ RenderedGrid,
+} from "./components/grid/renderGrid";
function defaultDoc(): Doc {
const defaultCells: Cell[] = Array.from({ length: 16 }, () => ({
@@ -101,18 +104,85 @@ export default class Notive {
subdivideSelection(subdivisions: number) {
const selection = this.selection;
-
if (!selection) return;
+ const grid = this.getGrid(selection.gridId);
+ if (!grid) return;
+
+ const startCellRef = selection.startCellRef();
+ const endCellRef = selection.endCellRef();
+
+ const startCell = getRenderedCell(grid, startCellRef);
+ const endCell = getRenderedCell(grid, endCellRef);
+ if (!startCell || !endCell) return;
+
+ const startRatio =
+ startCell.startRatio.compare(endCell.startRatio) <= 0
+ ? startCell.startRatio
+ : endCell.startRatio;
+
+ const endRatio =
+ startCell.endRatio.compare(endCell.endRatio) >= 0
+ ? startCell.endRatio
+ : endCell.endRatio;
+
+ const totalWidth = endRatio.subtract(startRatio);
+ const subdivisionWidth = totalWidth.divideRatio(
+ Ratio.fromInteger(subdivisions),
+ );
+
const newDoc = mapRowsInRange(
this.doc,
selection.gridId,
- selection.startCellRef(),
- selection.endCellRef(),
+ startCellRef,
+ endCellRef,
(row, rowRef) => {
- return row;
+ const newCells: Cell[] = [];
+ let currentRatio = Ratio.fromInteger(0);
+
+ for (const cell of row.cells) {
+ const cellStart = currentRatio;
+ const cellEnd = currentRatio.add(cell.widthRatio);
+
+ // Cell is entirely before selection
+ if (cellEnd.compare(startRatio) <= 0) {
+ newCells.push(cell);
+ currentRatio = cellEnd;
+ continue;
+ }
+
+ // Cell is entirely after selection
+ if (cellStart.compare(endRatio) >= 0) {
+ newCells.push(cell);
+ currentRatio = cellEnd;
+ continue;
+ }
+
+ // First cell that overlaps - insert subdivisions
+ if (newCells.length === 0 || currentRatio.compare(startRatio) < 0) {
+ for (let i = 0; i < subdivisions; i++) {
+ newCells.push({ widthRatio: subdivisionWidth });
+ }
+ }
+
+ currentRatio = cellEnd;
+ }
+
+ return { ...row, cells: newCells };
},
);
+
+ this.#doc = newDoc;
+
+ this.#gridsById = Object.fromEntries(
+ this.#doc.grids.map((grid) => [grid.id, renderGrid(grid)]),
+ );
+
+ window.dispatchEvent(
+ new CustomEvent("ntv:grid:change", {
+ detail: { gridId: selection.gridId },
+ }),
+ );
}
}