refactor: ice editor dialog

This commit is contained in:
Azgaar 2022-07-09 21:08:49 +03:00
parent 0dd7468184
commit 3125366944
12 changed files with 75 additions and 46 deletions

View file

@ -11,6 +11,7 @@ import {rn} from "utils/numberUtils";
import {rand} from "utils/probabilityUtils";
import {parseTransform} from "utils/stringUtils";
import {convertTemperature, getHeight} from "utils/unitUtils";
import {restoreDefaultEvents} from "scripts/events";
let isLoaded = false;
@ -483,7 +484,8 @@ export function open({id} = {}) {
}
} else {
clearMainTip();
viewbox.on("click", clicked).style("cursor", "default");
restoreDefaultEvents();
if (layerIsOn("toggleCells") && toggler.dataset.forced) {
toggleCells();
toggler.dataset.forced = false;

View file

@ -0,0 +1,140 @@
import * as d3 from "d3";
import {closeDialogs} from "dialogs/utils";
import {layerIsOn, toggleLayer} from "layers";
import {clearMainTip, tip} from "scripts/tooltips";
import {findGridCell, getGridPolygon} from "utils/graphUtils";
import {getInputNumber} from "utils/nodeUtils";
import {rn} from "utils/numberUtils";
import {rand} from "utils/probabilityUtils";
import {byId} from "utils/shorthands";
import {parseTransform} from "utils/stringUtils";
// @ts-expect-error js module
import {editStyle} from "modules/style";
// @ts-expect-error js module
import {restoreDefaultEvents} from "scripts/events";
// @ts-expect-error js module
import {unselect} from "modules/ui/editors";
let isLoaded = false;
export function open() {
closeDialogs(".stable");
if (!layerIsOn("toggleIce")) toggleLayer("toggleIce");
elSelected = d3.select(d3.event.target);
const type = elSelected.attr("type") ? "Glacier" : "Iceberg";
if (byId("iceRandomize")) byId("iceRandomize")!.style.display = type === "Glacier" ? "none" : "inline-block";
const $iceSize = byId("iceSize") as HTMLInputElement;
if ($iceSize) {
$iceSize.style.display = type === "Glacier" ? "none" : "inline-block";
if (type === "Iceberg") $iceSize.value = elSelected.attr("size");
}
ice.selectAll("*").classed("draggable", true).call(d3.drag().on("drag", dragElement));
$("#iceEditor").dialog({
title: "Edit " + type,
resizable: false,
position: {my: "center top+60", at: "top", of: d3.event, collision: "fit"},
close: closeEditor
});
if (isLoaded) return;
isLoaded = true;
// add listeners
byId("iceEditStyle")?.on("click", () => editStyle("ice"));
byId("iceRandomize")?.on("click", randomizeShape);
byId("iceSize")?.on("input", changeSize);
byId("iceNew")?.on("click", toggleAdd);
byId("iceRemove")?.on("click", removeIce);
function randomizeShape() {
const c = grid.points[+elSelected.attr("cell")];
const s = +elSelected.attr("size");
const i = rand(0, grid.cells.i.length);
const cn = grid.points[i];
const poly = getGridPolygon(i).map(p => [p[0] - cn[0], p[1] - cn[1]]);
const points = poly.map(p => [rn(c[0] + p[0] * s, 2), rn(c[1] + p[1] * s, 2)]);
elSelected.attr("points", points);
}
function changeSize(this: HTMLInputElement) {
const c = grid.points[+elSelected.attr("cell")];
const s = +elSelected.attr("size");
const flat = elSelected
.attr("points")
.split(",")
.map((pointString: string) => +pointString);
const pairs = [];
while (flat.length) pairs.push(flat.splice(0, 2));
const poly = pairs.map(p => [(p[0] - c[0]) / s, (p[1] - c[1]) / s]);
const size = +this.value;
const points = poly.map(p => [rn(c[0] + p[0] * size, 2), rn(c[1] + p[1] * size, 2)]);
elSelected.attr("points", points).attr("size", size);
}
function toggleAdd() {
byId("iceNew")?.classList.toggle("pressed");
if (byId("iceNew")?.classList.contains("pressed")) {
viewbox.style("cursor", "crosshair").on("click", addIcebergOnClick);
tip("Click on map to create an iceberg. Hold Shift to add multiple", true);
} else {
clearMainTip();
restoreDefaultEvents();
}
}
function addIcebergOnClick(this: d3.ContainerElement) {
const [x, y] = d3.mouse(this);
const i = findGridCell(x, y, grid);
const c = grid.points[i];
const s = getInputNumber("iceSize");
const points = getGridPolygon(i).map(p => [(p[0] + (c[0] - p[0]) / s) | 0, (p[1] + (c[1] - p[1]) / s) | 0]);
const iceberg = ice.append("polygon").attr("points", points).attr("cell", i).attr("size", s);
iceberg.call(d3.drag().on("drag", dragElement));
if (d3.event.shiftKey === false) toggleAdd();
}
function removeIce() {
const type = elSelected.attr("type") ? "Glacier" : "Iceberg";
byId("alertMessage")!.innerHTML = `Are you sure you want to remove the ${type}?`;
$("#alert").dialog({
resizable: false,
title: "Remove " + type,
buttons: {
Remove: function () {
$(this).dialog("close");
elSelected.remove();
$("#iceEditor").dialog("close");
},
Cancel: function () {
$(this).dialog("close");
}
}
});
}
function dragElement(this: Element) {
const tr = parseTransform(this.getAttribute("transform"));
const dx = +tr[0] - d3.event.x;
const dy = +tr[1] - d3.event.y;
d3.event.on("drag", function (this: Element) {
const {x, y} = d3.event;
this.setAttribute("transform", `translate(${dx + x},${dy + y})`);
});
}
function closeEditor() {
ice.selectAll("*").classed("draggable", false).call(d3.drag().on("drag", null));
clearMainTip();
byId("iceNew")?.classList.remove("pressed");
unselect();
}
}

View file

@ -10,6 +10,7 @@ const dialogsMap = {
heightmapEditor: "heightmap-editor",
heightmapSelection: "heightmap-selection",
hierarchyTree: "hierarchy-tree",
iceEditor: "ice-editor",
religionsEditor: "religions-editor",
statesEditor: "states-editor",
unitsEditor: "units-editor"