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

@ -1,24 +1,37 @@
import * as d3 from "d3";
import {findGridCell, getGridPolygon} from "utils/graphUtils";
import {tip, clearMainTip} from "scripts/tooltips";
import {rn} from "utils/numberUtils";
import {ra} from "utils/probabilityUtils";
import {parseTransform} from "utils/stringUtils";
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 editIce() {
if (customization) return;
export function open() {
closeDialogs(".stable");
if (!layerIsOn("toggleIce")) toggleIce();
if (!layerIsOn("toggleIce")) toggleLayer("toggleIce");
elSelected = d3.select(d3.event.target);
const type = elSelected.attr("type") ? "Glacier" : "Iceberg";
document.getElementById("iceRandomize").style.display = type === "Glacier" ? "none" : "inline-block";
document.getElementById("iceSize").style.display = type === "Glacier" ? "none" : "inline-block";
if (type === "Iceberg") document.getElementById("iceSize").value = +elSelected.attr("size");
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({
@ -32,29 +45,31 @@ export function editIce() {
isLoaded = true;
// add listeners
document.getElementById("iceEditStyle").addEventListener("click", () => editStyle("ice"));
document.getElementById("iceRandomize").addEventListener("click", randomizeShape);
document.getElementById("iceSize").addEventListener("input", changeSize);
document.getElementById("iceNew").addEventListener("click", toggleAdd);
document.getElementById("iceRemove").addEventListener("click", removeIce);
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 = ra(grid.cells.i),
cn = grid.points[i];
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() {
function changeSize(this: HTMLInputElement) {
const c = grid.points[+elSelected.attr("cell")];
const s = +elSelected.attr("size");
const flat = elSelected
.attr("points")
.split(",")
.map(el => +el);
.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]);
@ -64,21 +79,21 @@ export function editIce() {
}
function toggleAdd() {
document.getElementById("iceNew").classList.toggle("pressed");
if (document.getElementById("iceNew").classList.contains("pressed")) {
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();
viewbox.on("click", clicked).style("cursor", "default");
restoreDefaultEvents();
}
}
function addIcebergOnClick() {
function addIcebergOnClick(this: d3.ContainerElement) {
const [x, y] = d3.mouse(this);
const i = findGridCell(x, y, grid);
const c = grid.points[i];
const s = +document.getElementById("iceSize").value;
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);
@ -88,7 +103,7 @@ export function editIce() {
function removeIce() {
const type = elSelected.attr("type") ? "Glacier" : "Iceberg";
alertMessage.innerHTML = /* html */ `Are you sure you want to remove the ${type}?`;
byId("alertMessage")!.innerHTML = `Are you sure you want to remove the ${type}?`;
$("#alert").dialog({
resizable: false,
title: "Remove " + type,
@ -105,14 +120,13 @@ export function editIce() {
});
}
function dragElement() {
function dragElement(this: Element) {
const tr = parseTransform(this.getAttribute("transform"));
const dx = +tr[0] - d3.event.x,
dy = +tr[1] - d3.event.y;
const dx = +tr[0] - d3.event.x;
const dy = +tr[1] - d3.event.y;
d3.event.on("drag", function () {
const x = d3.event.x,
y = d3.event.y;
d3.event.on("drag", function (this: Element) {
const {x, y} = d3.event;
this.setAttribute("transform", `translate(${dx + x},${dy + y})`);
});
}
@ -120,7 +134,7 @@ export function editIce() {
function closeEditor() {
ice.selectAll("*").classed("draggable", false).call(d3.drag().on("drag", null));
clearMainTip();
iceNew.classList.remove("pressed");
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"

View file

@ -210,7 +210,7 @@ export function editRegiment(selector) {
tip("Click on map to create new regiment or fleet", true);
} else {
clearMainTip();
viewbox.on("click", clicked).style("cursor", "default");
restoreDefaultEvents();
}
}
@ -240,8 +240,8 @@ export function editRegiment(selector) {
armies.selectAll(":scope > g").classed("draggable", false);
} else {
clearMainTip();
restoreDefaultEvents();
armies.selectAll(":scope > g").classed("draggable", true);
viewbox.on("click", clicked).style("cursor", "default");
}
}
@ -313,7 +313,7 @@ export function editRegiment(selector) {
} else {
clearMainTip();
armies.selectAll(":scope > g").classed("draggable", true);
viewbox.on("click", clicked).style("cursor", "default");
restoreDefaultEvents();
}
}

View file

@ -7,6 +7,7 @@ import {rn} from "utils/numberUtils";
import {capitalize} from "utils/stringUtils";
import {si} from "utils/unitUtils";
import {closeDialogs} from "dialogs/utils";
import {restoreDefaultEvents} from "scripts/events";
let isLoaded = false;
@ -170,7 +171,7 @@ export function overviewRegiments(state) {
if (regimentAdd.offsetParent) regimentAdd.classList.add("pressed");
} else {
clearMainTip();
viewbox.on("click", clicked).style("cursor", "default");
restoreDefaultEvents();
addLines();
if (regimentAdd.offsetParent) regimentAdd.classList.remove("pressed");
}

View file

@ -6,6 +6,7 @@ import {rn} from "utils/numberUtils";
import {getNextId} from "utils/nodeUtils";
import {round} from "utils/stringUtils";
import {closeDialogs} from "dialogs/utils";
import {restoreDefaultEvents} from "../../scripts/events";
let isLoaded = false;
@ -278,7 +279,7 @@ export function editRoute(onClick) {
elSelected.on("click", null);
} else {
clearMainTip();
viewbox.on("click", clicked).style("cursor", "default");
restoreDefaultEvents();
elSelected.on("click", addInterimControlPoint).attr("data-new", null);
}
}

View file

@ -12,7 +12,11 @@ import {showMainTip, tip} from "./tooltips";
export function restoreDefaultEvents() {
Zoom.setZoomBehavior();
viewbox.style("cursor", "default").on(".drag", null).on("click", clicked).on("touchmove mousemove", onMouseMove);
viewbox
.style("cursor", "default")
.on(".drag", null)
.on("click", handleMapClick)
.on("touchmove mousemove", onMouseMove);
scaleBar.on("mousemove", () => tip("Click to open Units Editor")).on("click", () => openDialog("unitsEditor"));
legend
.on("mousemove", () => tip("Drag to change the position. Click to hide the legend"))
@ -21,7 +25,7 @@ export function restoreDefaultEvents() {
}
// on viewbox click event - run function based on target
function clicked() {
function handleMapClick() {
const el = d3.event.target;
if (!el || !el.parentElement || !el.parentElement.parentElement) return;
const parent = el.parentElement;
@ -35,7 +39,7 @@ function clicked() {
else if (grand.id === "routes") editRoute();
else if (el.tagName === "tspan" && grand.parentNode.parentNode.id === "labels") editLabel();
else if (grand.id === "burgLabels" || grand.id === "burgIcons") openDialog("burgEditor", null, {id: +el.dataset.id});
else if (parent.id === "ice") editIce();
else if (parent.id === "ice") openDialog("iceEditor");
else if (parent.id === "terrain") editReliefIcon();
else if (grand.id === "markers" || great.id === "markers") editMarker();
else if (grand.id === "coastline") openDialog("coastlineEditor", null, {node: d3.event.target});

View file

@ -7,7 +7,7 @@ import {assignSpeakerBehavior} from "./speaker";
import {addResizeListener} from "modules/ui/options";
// @ts-ignore
import {addDragToUpload} from "modules/io/load";
import {addHotkeyListeners} from "modules/ui/hotkeys";
import {addHotkeyListeners} from "scripts/hotkeys";
export function addGlobalListeners() {
if (PRODUCTION) {

8
src/types/grid.d.ts vendored
View file

@ -2,16 +2,22 @@ interface IGrid {
spacing: number;
boundary: TPoints;
points: TPoints;
features: IFeature[];
vertices: {
p: TPoints;
v: number[][];
c: number[][];
};
cells: {
i: IntArray;
b: IntArray;
c: number[][];
v: number[][];
h: IntArray;
t: IntArray;
f: IntArray;
prec: IntArray;
};
features: IFeature[];
}
interface IFeature {
i: number;

View file

@ -156,7 +156,7 @@ export function findCell(x: number, y: number, radius = Infinity): number | unde
}
// get polygon points for initial cells knowing cell id
export function getGridPolygon(i: number) {
export function getGridPolygon(i: number): TPoints {
return grid.cells.v[i].map(v => grid.vertices.p[v]);
}

View file

@ -40,7 +40,7 @@ export function splitInTwo(str: string) {
}
// transform string to array [translateX,translateY,rotateDeg,rotateX,rotateY,scale]
export function parseTransform(str: string) {
export function parseTransform(str: string | null) {
if (!str) return [0, 0, 0, 0, 0, 1];
const a = str