nc-planner/scripts/planner-resize.js

201 lines
7.2 KiB
JavaScript

import { registerLoadCallback } from "./main.js";
import { awaitEvent, listenTo } from "./events.js";
import {
createPlannerCell,
createPlannerPlane,
getPlannerDom,
getPlannerMultiblockSize, getPlannerMultiblockType,
maxMultiblockSize
} from "./planner.js";
import { DomList } from "./dom-list.js";
registerLoadCallback(() => {
listenTo("planner:resize", e => {
if (e.detail.state) {
initializeResize();
} else {
cleanUpResize();
}
});
awaitEvent("dev-mode:end").then(async () => {
await awaitEvent("fileLoad:end");
initializeResize();
});
});
function createButton({ axis, n, add, topLeft }) {
const div = document.createElement("div");
div.innerText = add ? "+" : "-";
if (axis === "y") {
div.classList.add(`planner--resize--${add ? "add" : "remove"}-layer`);
if (!add) {
div.addEventListener("mouseenter", () => highlight(axis, n, add));
div.addEventListener("mouseleave", () => highlight(null));
}
} else {
div.classList.add(`planner--resize--${add ? "add" : "remove"}-${axis}`);
div.classList.add(`planner--resize--${topLeft ? "top-left" : "bottom-right"}`);
div.style.setProperty(`--${axis}`, `${n}`);
div.addEventListener("mouseenter", () => highlight(axis, n, add));
div.addEventListener("mouseleave", () => highlight(null));
}
div.addEventListener("click", e => resize(axis, n, add, e));
return div;
}
function highlight(axis, n, add) {
const planner = getPlannerDom();
const resizes = [...planner.querySelectorAll(":scope > .planner--resize")];
if (!axis) {
resizes.forEach(r => {
r.querySelectorAll(":scope > .planner--resize--highlight").forEach(e => r.removeChild(e));
});
return;
}
if (axis === "y") {
const div = document.createElement("div");
div.classList.add("planner--resize--highlight", `planner--resize--highlight__remove-layer`);
resizes[n].appendChild(div);
return;
}
resizes.forEach(r => {
const div = document.createElement("div");
div.classList.add("planner--resize--highlight", `planner--resize--highlight__${add ? "add" : "remove"}-${axis}`);
div.style.setProperty(`--${axis}`, `${n}`);
r.appendChild(div);
});
}
function resize(axis, n, add, e) {
const planner = getPlannerDom();
const size = getPlannerMultiblockSize();
if (!add) {
if (axis === "y") {
const resizes = planner.querySelectorAll(`:scope > .planner--resize`);
planner.removeChild(resizes[n]);
size[1]--;
} else {
const tiles = planner.querySelectorAll(`[data-${axis}="${n}"]`);
const tileGroups = Object.values(Object.groupBy(tiles, t => t.parentElement.dataset.y));
for (const tg of tileGroups) {
const parent = tg[0].parentElement;
tg.forEach(t => parent.removeChild(t));
}
size[axis === "x" ? 0 : 2]--;
}
} else {
if (axis === "y") {
const list = new DomList(planner);
const plane = list.makeItem();
createPlannerPlane(plane, 0, null);
const parentPlane = document.createElement("div");
parentPlane.classList.add("planner--resize");
parentPlane.appendChild(plane)
const nextSibling = planner.querySelector(`:scope > .planner--resize[data-y="${n+1}"]`);
planner.insertBefore(parentPlane, nextSibling);
size[1]++;
} else {
const tiles = planner.querySelectorAll(`[data-${axis}="${n}"]`);
const tileGroups = Object.values(Object.groupBy(tiles, t => t.parentElement.dataset.y));
for (const tg of tileGroups) {
const parent = tg[0].parentElement;
const grid = new DomList(parent);
tg.forEach(t => {
const cell = grid.makeItem();
createPlannerCell(cell, 0, 0, 0, -1);
parent.insertBefore(cell, axis === "x" ? t : tg[0]);
});
}
size[axis === "x" ? 0 : 2]++;
}
}
fixPlannerNumbering();
cleanUpResize();
initializeResize();
}
function initializeResize() {
const planner = getPlannerDom();
const size = getPlannerMultiblockSize();
const type = getPlannerMultiblockType();
const grids = [...planner.querySelectorAll(":scope > .grid")];
grids.forEach((grid, gridIndex) => {
const casing = gridIndex === 0 || gridIndex === grids.length - 1;
const removedGrid = planner.removeChild(grid);
const newDiv = document.createElement("div");
newDiv.classList.add("planner--resize");
newDiv.style.setProperty("--width", `${size[0]}`);
newDiv.style.setProperty("--height", `${size[2]}`);
newDiv.dataset.y = gridIndex.toString(10);
if (casing) {
newDiv.dataset.casing = "";
}
if (!casing && size[1] > maxMultiblockSize[type][1]) {
newDiv.appendChild(createButton({ axis: "y", add: false, n: gridIndex }));
}
if (!casing) {
for (let x = 0; x < size[0] - 1 && size[0] < maxMultiblockSize[type][0]; x++) {
newDiv.appendChild(createButton({ axis: "x", add: true, n: x+1, topLeft: true }));
}
for (let x = 0; x < size[0] - 2 && size[0] > maxMultiblockSize[type][0]; x++) {
newDiv.appendChild(createButton({ axis: "x", add: false, n: x+1, topLeft: true }));
}
for (let z = 0; z < size[2] - 1 && size[2] < maxMultiblockSize[type][2]; z++) {
newDiv.appendChild(createButton({ axis: "z", add: true, n: z+1, topLeft: true }));
}
for (let z = 0; z < size[2] - 2 && size[2] > maxMultiblockSize[type][2]; z++) {
newDiv.appendChild(createButton({ axis: "z", add: false, n: z+1, topLeft: true }));
}
}
newDiv.appendChild(removedGrid);
planner.appendChild(newDiv);
if (!casing) {
for (let x = 0; x < size[0] - 1 && size[0] < maxMultiblockSize[type][0]; x++) {
newDiv.appendChild(createButton({ axis: "x", add: true, n: x+1, topLeft: false }));
}
for (let x = 0; x < size[0] - 2 && size[0] > maxMultiblockSize[type][0]; x++) {
newDiv.appendChild(createButton({ axis: "x", add: false, n: x+1, topLeft: false }));
}
for (let z = 0; z < size[2] - 1 && size[2] < maxMultiblockSize[type][2]; z++) {
newDiv.appendChild(createButton({ axis: "z", add: true, n: z+1, topLeft: false }));
}
for (let z = 0; z < size[2] - 2 && size[2] > maxMultiblockSize[type][2]; z++) {
newDiv.appendChild(createButton({ axis: "z", add: false, n: z+1, topLeft: false }));
}
}
planner.appendChild(newDiv);
if (gridIndex !== grids.length - 1 && size[1] < maxMultiblockSize[type][1]) {
planner.appendChild(createButton({ axis: "y", add: true, n: gridIndex }));
}
});
}
function cleanUpResize() {
const planner = getPlannerDom();
planner.replaceChildren(...planner.querySelectorAll(":scope > .planner--resize > .grid"), ...planner.querySelectorAll(":scope > template"));
}
function fixPlannerNumbering() {
const planner = getPlannerDom();
const size = getPlannerMultiblockSize();
const grids = planner.querySelectorAll(":scope > .planner--resize > .grid");
grids.forEach(grid => {
grid.style.setProperty("--width", size[0].toString(10));
const tiles = [...grid.querySelectorAll("[data-tile]")];
for (let z = 0; z < size[2]; z++) {
for (let x = 0; x < size[0]; x++) {
const tile = tiles.shift();
tile.dataset.x = x.toString(10);
tile.dataset.z = z.toString(10);
}
}
});
}