mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 09:41:24 +01:00
refactor: map events
This commit is contained in:
parent
3c850d8d46
commit
ff97c9227d
32 changed files with 433 additions and 329 deletions
|
|
@ -5855,11 +5855,7 @@
|
||||||
<div id="notesBody"></div>
|
<div id="notesBody"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div id="tooltip" style="opacity: 0"></div>
|
||||||
id="tooltip"
|
|
||||||
style="opacity: 0"
|
|
||||||
data-main="Сlick the arrow button for options. Zoom in to see the map in details"
|
|
||||||
></div>
|
|
||||||
|
|
||||||
<div id="mapOverlay" style="display: none">Drop a .map file to open</div>
|
<div id="mapOverlay" style="display: none">Drop a .map file to open</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import * as d3 from "d3";
|
import * as d3 from "d3";
|
||||||
|
|
||||||
import {closeDialogs} from "dialogs/utils";
|
import {closeDialogs} from "dialogs/utils";
|
||||||
import {restoreDefaultEvents} from "scripts/events";
|
import {setDefaultEventHandlers} from "scripts/events";
|
||||||
import {clearMainTip, showMainTip, tip} from "scripts/tooltips";
|
import {clearMainTip, showMainTip, tip} from "scripts/tooltips";
|
||||||
import {getRandomColor} from "utils/colorUtils";
|
import {getRandomColor} from "utils/colorUtils";
|
||||||
import {findAll, findCell, getPackPolygon, isLand} from "utils/graphUtils";
|
import {findAll, findCell, getPackPolygon, isLand} from "utils/graphUtils";
|
||||||
|
|
@ -467,7 +467,7 @@ export function open() {
|
||||||
biomesFooter.style.display = "block";
|
biomesFooter.style.display = "block";
|
||||||
if (!close) $("#biomesEditor").dialog({position: {my: "right top", at: "right-10 top+10", of: "svg"}});
|
if (!close) $("#biomesEditor").dialog({position: {my: "right top", at: "right-10 top+10", of: "svg"}});
|
||||||
|
|
||||||
restoreDefaultEvents();
|
setDefaultEventHandlers();
|
||||||
clearMainTip();
|
clearMainTip();
|
||||||
const selected = document.querySelector("#biomesBody > div.selected");
|
const selected = document.querySelector("#biomesBody > div.selected");
|
||||||
if (selected) selected.classList.remove("selected");
|
if (selected) selected.classList.remove("selected");
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import {rn} from "utils/numberUtils";
|
||||||
import {rand} from "utils/probabilityUtils";
|
import {rand} from "utils/probabilityUtils";
|
||||||
import {parseTransform} from "utils/stringUtils";
|
import {parseTransform} from "utils/stringUtils";
|
||||||
import {convertTemperature, getHeight, getBurgPopulation, getBurgPopulationPoints} from "utils/unitUtils";
|
import {convertTemperature, getHeight, getBurgPopulation, getBurgPopulationPoints} from "utils/unitUtils";
|
||||||
import {restoreDefaultEvents} from "scripts/events";
|
import {setDefaultEventHandlers} from "scripts/events";
|
||||||
|
|
||||||
let isLoaded = false;
|
let isLoaded = false;
|
||||||
|
|
||||||
|
|
@ -484,7 +484,7 @@ export function open({id} = {}) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
clearMainTip();
|
clearMainTip();
|
||||||
restoreDefaultEvents();
|
setDefaultEventHandlers();
|
||||||
|
|
||||||
if (layerIsOn("toggleCells") && toggler.dataset.forced) {
|
if (layerIsOn("toggleCells") && toggler.dataset.forced) {
|
||||||
toggleCells();
|
toggleCells();
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import {openDialog} from "dialogs";
|
||||||
import {closeDialogs} from "dialogs/utils";
|
import {closeDialogs} from "dialogs/utils";
|
||||||
import {layerIsOn, toggleLayer} from "layers";
|
import {layerIsOn, toggleLayer} from "layers";
|
||||||
import {applySorting} from "modules/ui/editors";
|
import {applySorting} from "modules/ui/editors";
|
||||||
import {restoreDefaultEvents} from "scripts/events";
|
import {setDefaultEventHandlers} from "scripts/events";
|
||||||
import {clearMainTip, tip} from "scripts/tooltips";
|
import {clearMainTip, tip} from "scripts/tooltips";
|
||||||
import {getCoordinates} from "utils/coordinateUtils";
|
import {getCoordinates} from "utils/coordinateUtils";
|
||||||
import {findCell} from "utils/graphUtils";
|
import {findCell} from "utils/graphUtils";
|
||||||
|
|
@ -312,7 +312,7 @@ export function open() {
|
||||||
|
|
||||||
function exitAddBurgMode() {
|
function exitAddBurgMode() {
|
||||||
customization = 0;
|
customization = 0;
|
||||||
restoreDefaultEvents();
|
setDefaultEventHandlers();
|
||||||
clearMainTip();
|
clearMainTip();
|
||||||
if (addBurgTool.classList.contains("pressed")) addBurgTool.classList.remove("pressed");
|
if (addBurgTool.classList.contains("pressed")) addBurgTool.classList.remove("pressed");
|
||||||
if (addNewBurg.classList.contains("pressed")) addNewBurg.classList.remove("pressed");
|
if (addNewBurg.classList.contains("pressed")) addNewBurg.classList.remove("pressed");
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import * as d3 from "d3";
|
||||||
|
|
||||||
import {openDialog} from "dialogs";
|
import {openDialog} from "dialogs";
|
||||||
import {closeDialogs} from "dialogs/utils";
|
import {closeDialogs} from "dialogs/utils";
|
||||||
import {restoreDefaultEvents} from "scripts/events";
|
import {setDefaultEventHandlers} from "scripts/events";
|
||||||
import {clearMainTip, showMainTip, tip} from "scripts/tooltips";
|
import {clearMainTip, showMainTip, tip} from "scripts/tooltips";
|
||||||
import {debounce} from "utils/functionUtils";
|
import {debounce} from "utils/functionUtils";
|
||||||
import {findAll, findCell, getPackPolygon, isLand} from "utils/graphUtils";
|
import {findAll, findCell, getPackPolygon, isLand} from "utils/graphUtils";
|
||||||
|
|
@ -811,7 +811,7 @@ function exitCulturesManualAssignment(close) {
|
||||||
if (!close) $("#culturesEditor").dialog({position: {my: "right top", at: "right-10 top+10", of: "svg"}});
|
if (!close) $("#culturesEditor").dialog({position: {my: "right top", at: "right-10 top+10", of: "svg"}});
|
||||||
|
|
||||||
debug.select("#cultureCenters").style("display", null);
|
debug.select("#cultureCenters").style("display", null);
|
||||||
restoreDefaultEvents();
|
setDefaultEventHandlers();
|
||||||
clearMainTip();
|
clearMainTip();
|
||||||
const selected = $body.querySelector("div.selected");
|
const selected = $body.querySelector("div.selected");
|
||||||
if (selected) selected.classList.remove("selected");
|
if (selected) selected.classList.remove("selected");
|
||||||
|
|
@ -829,7 +829,7 @@ function enterAddCulturesMode() {
|
||||||
|
|
||||||
function exitAddCultureMode() {
|
function exitAddCultureMode() {
|
||||||
customization = 0;
|
customization = 0;
|
||||||
restoreDefaultEvents();
|
setDefaultEventHandlers();
|
||||||
clearMainTip();
|
clearMainTip();
|
||||||
$body.querySelectorAll("div > input, select, span, svg").forEach(e => (e.style.pointerEvents = "all"));
|
$body.querySelectorAll("div > input, select, span, svg").forEach(e => (e.style.pointerEvents = "all"));
|
||||||
if (culturesAdd.classList.contains("pressed")) culturesAdd.classList.remove("pressed");
|
if (culturesAdd.classList.contains("pressed")) culturesAdd.classList.remove("pressed");
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import * as d3 from "d3";
|
||||||
|
|
||||||
import {closeDialogs} from "dialogs/utils";
|
import {closeDialogs} from "dialogs/utils";
|
||||||
import {layerIsOn} from "layers";
|
import {layerIsOn} from "layers";
|
||||||
import {restoreDefaultEvents} from "scripts/events";
|
import {setDefaultEventHandlers} from "scripts/events";
|
||||||
import {clearMainTip, tip} from "scripts/tooltips";
|
import {clearMainTip, tip} from "scripts/tooltips";
|
||||||
import {findCell} from "utils/graphUtils";
|
import {findCell} from "utils/graphUtils";
|
||||||
import {applySorting} from "modules/ui/editors";
|
import {applySorting} from "modules/ui/editors";
|
||||||
|
|
@ -455,7 +455,7 @@ export function open() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function closeDiplomacyEditor() {
|
function closeDiplomacyEditor() {
|
||||||
restoreDefaultEvents();
|
setDefaultEventHandlers();
|
||||||
clearMainTip();
|
clearMainTip();
|
||||||
const selected = body.querySelector("div.Self");
|
const selected = body.querySelector("div.Self");
|
||||||
if (selected) selected.classList.remove("Self");
|
if (selected) selected.classList.remove("Self");
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import {moveCircle, removeCircle} from "modules/ui/editors";
|
||||||
import {changeViewMode} from "modules/ui/options";
|
import {changeViewMode} from "modules/ui/options";
|
||||||
import {addZones} from "modules/zones";
|
import {addZones} from "modules/zones";
|
||||||
import {aleaPRNG} from "scripts/aleaPRNG";
|
import {aleaPRNG} from "scripts/aleaPRNG";
|
||||||
import {restoreDefaultEvents} from "scripts/events";
|
import {setDefaultEventHandlers} from "scripts/events";
|
||||||
import {undraw} from "scripts/generation";
|
import {undraw} from "scripts/generation";
|
||||||
import {prompt} from "scripts/prompt";
|
import {prompt} from "scripts/prompt";
|
||||||
import {rankCells} from "scripts/rankCells";
|
import {rankCells} from "scripts/rankCells";
|
||||||
|
|
@ -182,7 +182,7 @@ export function open(options) {
|
||||||
if (byId("options").querySelector(".tab > button.active").id === "toolsTab") toolsContent.style.display = "block";
|
if (byId("options").querySelector(".tab > button.active").id === "toolsTab") toolsContent.style.display = "block";
|
||||||
layersPreset.disabled = false;
|
layersPreset.disabled = false;
|
||||||
exitCustomization.style.display = "none"; // hide finalize button
|
exitCustomization.style.display = "none"; // hide finalize button
|
||||||
restoreDefaultEvents();
|
setDefaultEventHandlers();
|
||||||
clearMainTip();
|
clearMainTip();
|
||||||
closeDialogs();
|
closeDialogs();
|
||||||
Zoom.reset();
|
Zoom.reset();
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,7 @@ import {byId} from "utils/shorthands";
|
||||||
import {parseTransform} from "utils/stringUtils";
|
import {parseTransform} from "utils/stringUtils";
|
||||||
// @ts-expect-error js module
|
// @ts-expect-error js module
|
||||||
import {editStyle} from "modules/style";
|
import {editStyle} from "modules/style";
|
||||||
// @ts-expect-error js module
|
import {setDefaultEventHandlers} from "scripts/events";
|
||||||
import {restoreDefaultEvents} from "scripts/events";
|
|
||||||
// @ts-expect-error js module
|
// @ts-expect-error js module
|
||||||
import {unselect} from "modules/ui/editors";
|
import {unselect} from "modules/ui/editors";
|
||||||
|
|
||||||
|
|
@ -85,7 +84,7 @@ export function open() {
|
||||||
tip("Click on map to create an iceberg. Hold Shift to add multiple", true);
|
tip("Click on map to create an iceberg. Hold Shift to add multiple", true);
|
||||||
} else {
|
} else {
|
||||||
clearMainTip();
|
clearMainTip();
|
||||||
restoreDefaultEvents();
|
setDefaultEventHandlers();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import * as d3 from "d3";
|
||||||
import {openDialog} from "dialogs";
|
import {openDialog} from "dialogs";
|
||||||
import {closeDialogs} from "dialogs/utils";
|
import {closeDialogs} from "dialogs/utils";
|
||||||
import {applySortingByHeader} from "modules/ui/editors";
|
import {applySortingByHeader} from "modules/ui/editors";
|
||||||
import {restoreDefaultEvents} from "scripts/events";
|
import {setDefaultEventHandlers} from "scripts/events";
|
||||||
import {clearMainTip, showMainTip, tip} from "scripts/tooltips";
|
import {clearMainTip, showMainTip, tip} from "scripts/tooltips";
|
||||||
import {debounce} from "utils/functionUtils";
|
import {debounce} from "utils/functionUtils";
|
||||||
import {findAll, findCell, getPackPolygon, isLand} from "utils/graphUtils";
|
import {findAll, findCell, getPackPolygon, isLand} from "utils/graphUtils";
|
||||||
|
|
@ -710,7 +710,7 @@ function exitReligionsManualAssignment(close) {
|
||||||
if (!close) $("#religionsEditor").dialog({position: {my: "right top", at: "right-10 top+10", of: "svg"}});
|
if (!close) $("#religionsEditor").dialog({position: {my: "right top", at: "right-10 top+10", of: "svg"}});
|
||||||
|
|
||||||
debug.select("#religionCenters").style("display", null);
|
debug.select("#religionCenters").style("display", null);
|
||||||
restoreDefaultEvents();
|
setDefaultEventHandlers();
|
||||||
clearMainTip();
|
clearMainTip();
|
||||||
const $selected = $body.querySelector("div.selected");
|
const $selected = $body.querySelector("div.selected");
|
||||||
if ($selected) $selected.classList.remove("selected");
|
if ($selected) $selected.classList.remove("selected");
|
||||||
|
|
@ -728,7 +728,7 @@ function enterAddReligionMode() {
|
||||||
|
|
||||||
function exitAddReligionMode() {
|
function exitAddReligionMode() {
|
||||||
customization = 0;
|
customization = 0;
|
||||||
restoreDefaultEvents();
|
setDefaultEventHandlers();
|
||||||
clearMainTip();
|
clearMainTip();
|
||||||
$body.querySelectorAll("div > input, select, span, svg").forEach(e => (e.style.pointerEvents = "all"));
|
$body.querySelectorAll("div > input, select, span, svg").forEach(e => (e.style.pointerEvents = "all"));
|
||||||
if (religionsAdd.classList.contains("pressed")) religionsAdd.classList.remove("pressed");
|
if (religionsAdd.classList.contains("pressed")) religionsAdd.classList.remove("pressed");
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import * as d3 from "d3";
|
||||||
import {openDialog} from "dialogs";
|
import {openDialog} from "dialogs";
|
||||||
import {closeDialogs} from "dialogs/utils";
|
import {closeDialogs} from "dialogs/utils";
|
||||||
import {applySortingByHeader, unfog} from "modules/ui/editors";
|
import {applySortingByHeader, unfog} from "modules/ui/editors";
|
||||||
import {restoreDefaultEvents} from "scripts/events";
|
import {setDefaultEventHandlers} from "scripts/events";
|
||||||
import {clearMainTip, showMainTip, tip} from "scripts/tooltips";
|
import {clearMainTip, showMainTip, tip} from "scripts/tooltips";
|
||||||
import {getMixedColor, getRandomColor} from "utils/colorUtils";
|
import {getMixedColor, getRandomColor} from "utils/colorUtils";
|
||||||
import {findAll, findCell, getPackPolygon, isLand} from "utils/graphUtils";
|
import {findAll, findCell, getPackPolygon, isLand} from "utils/graphUtils";
|
||||||
|
|
@ -1217,7 +1217,7 @@ function exitStatesManualAssignment(close) {
|
||||||
if (!close)
|
if (!close)
|
||||||
$("#statesEditor").dialog({position: {my: "right top", at: "right-10 top+10", of: "svg", collision: "fit"}});
|
$("#statesEditor").dialog({position: {my: "right top", at: "right-10 top+10", of: "svg", collision: "fit"}});
|
||||||
|
|
||||||
restoreDefaultEvents();
|
setDefaultEventHandlers();
|
||||||
clearMainTip();
|
clearMainTip();
|
||||||
const selected = $body.querySelector("div.selected");
|
const selected = $body.querySelector("div.selected");
|
||||||
if (selected) selected.classList.remove("selected");
|
if (selected) selected.classList.remove("selected");
|
||||||
|
|
@ -1349,7 +1349,7 @@ function addState() {
|
||||||
|
|
||||||
function exitAddStateMode() {
|
function exitAddStateMode() {
|
||||||
customization = 0;
|
customization = 0;
|
||||||
restoreDefaultEvents();
|
setDefaultEventHandlers();
|
||||||
clearMainTip();
|
clearMainTip();
|
||||||
$body.querySelectorAll("div > input, select, span, svg").forEach(e => (e.style.pointerEvents = "all"));
|
$body.querySelectorAll("div > input, select, span, svg").forEach(e => (e.style.pointerEvents = "all"));
|
||||||
if (statesAdd.classList.contains("pressed")) statesAdd.classList.remove("pressed");
|
if (statesAdd.classList.contains("pressed")) statesAdd.classList.remove("pressed");
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import * as d3 from "d3";
|
import * as d3 from "d3";
|
||||||
|
|
||||||
import {restoreDefaultEvents} from "scripts/events";
|
import {setDefaultEventHandlers} from "scripts/events";
|
||||||
import {findCell} from "utils/graphUtils";
|
import {findCell} from "utils/graphUtils";
|
||||||
import {tip} from "scripts/tooltips";
|
import {tip} from "scripts/tooltips";
|
||||||
import {prompt} from "scripts/prompt";
|
import {prompt} from "scripts/prompt";
|
||||||
|
|
@ -174,7 +174,7 @@ export function open() {
|
||||||
|
|
||||||
function toggleOpisometerMode() {
|
function toggleOpisometerMode() {
|
||||||
if (this.classList.contains("pressed")) {
|
if (this.classList.contains("pressed")) {
|
||||||
restoreDefaultEvents();
|
setDefaultEventHandlers();
|
||||||
clearMainTip();
|
clearMainTip();
|
||||||
this.classList.remove("pressed");
|
this.classList.remove("pressed");
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -193,7 +193,7 @@ export function open() {
|
||||||
});
|
});
|
||||||
|
|
||||||
d3.event.on("end", function () {
|
d3.event.on("end", function () {
|
||||||
restoreDefaultEvents();
|
setDefaultEventHandlers();
|
||||||
clearMainTip();
|
clearMainTip();
|
||||||
addOpisometer.classList.remove("pressed");
|
addOpisometer.classList.remove("pressed");
|
||||||
if (opisometer.points.length < 2) rulers.remove(opisometer.id);
|
if (opisometer.points.length < 2) rulers.remove(opisometer.id);
|
||||||
|
|
@ -206,7 +206,7 @@ export function open() {
|
||||||
|
|
||||||
function toggleRouteOpisometerMode() {
|
function toggleRouteOpisometerMode() {
|
||||||
if (this.classList.contains("pressed")) {
|
if (this.classList.contains("pressed")) {
|
||||||
restoreDefaultEvents();
|
setDefaultEventHandlers();
|
||||||
clearMainTip();
|
clearMainTip();
|
||||||
this.classList.remove("pressed");
|
this.classList.remove("pressed");
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -235,7 +235,7 @@ export function open() {
|
||||||
});
|
});
|
||||||
|
|
||||||
d3.event.on("end", function () {
|
d3.event.on("end", function () {
|
||||||
restoreDefaultEvents();
|
setDefaultEventHandlers();
|
||||||
clearMainTip();
|
clearMainTip();
|
||||||
addRouteOpisometer.classList.remove("pressed");
|
addRouteOpisometer.classList.remove("pressed");
|
||||||
if (routeOpisometer.points.length < 2) {
|
if (routeOpisometer.points.length < 2) {
|
||||||
|
|
@ -243,7 +243,7 @@ export function open() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
restoreDefaultEvents();
|
setDefaultEventHandlers();
|
||||||
clearMainTip();
|
clearMainTip();
|
||||||
addRouteOpisometer.classList.remove("pressed");
|
addRouteOpisometer.classList.remove("pressed");
|
||||||
tip("Must start in a cell with a route in it", false, "error");
|
tip("Must start in a cell with a route in it", false, "error");
|
||||||
|
|
@ -255,7 +255,7 @@ export function open() {
|
||||||
|
|
||||||
function togglePlanimeterMode() {
|
function togglePlanimeterMode() {
|
||||||
if (this.classList.contains("pressed")) {
|
if (this.classList.contains("pressed")) {
|
||||||
restoreDefaultEvents();
|
setDefaultEventHandlers();
|
||||||
clearMainTip();
|
clearMainTip();
|
||||||
this.classList.remove("pressed");
|
this.classList.remove("pressed");
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -274,7 +274,7 @@ export function open() {
|
||||||
});
|
});
|
||||||
|
|
||||||
d3.event.on("end", function () {
|
d3.event.on("end", function () {
|
||||||
restoreDefaultEvents();
|
setDefaultEventHandlers();
|
||||||
clearMainTip();
|
clearMainTip();
|
||||||
addPlanimeter.classList.remove("pressed");
|
addPlanimeter.classList.remove("pressed");
|
||||||
if (planimeter.points.length < 3) rulers.remove(planimeter.id);
|
if (planimeter.points.length < 3) rulers.remove(planimeter.id);
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import * as d3 from "d3";
|
||||||
|
|
||||||
import {INFO} from "config/logging";
|
import {INFO} from "config/logging";
|
||||||
import {updatePresetInput} from "layers";
|
import {updatePresetInput} from "layers";
|
||||||
import {restoreDefaultEvents} from "scripts/events";
|
import {setDefaultEventHandlers} from "scripts/events";
|
||||||
import {ldb} from "scripts/indexedDB";
|
import {ldb} from "scripts/indexedDB";
|
||||||
import {tip} from "scripts/tooltips";
|
import {tip} from "scripts/tooltips";
|
||||||
import {last} from "utils/arrayUtils";
|
import {last} from "utils/arrayUtils";
|
||||||
|
|
@ -624,7 +624,7 @@ async function parseLoadedData(data) {
|
||||||
eraInput.value = options.era;
|
eraInput.value = options.era;
|
||||||
shapeRendering.value = viewbox.attr("shape-rendering") || "geometricPrecision";
|
shapeRendering.value = viewbox.attr("shape-rendering") || "geometricPrecision";
|
||||||
|
|
||||||
restoreDefaultEvents();
|
setDefaultEventHandlers();
|
||||||
focusOn(); // based on searchParams focus on point, cell or burg
|
focusOn(); // based on searchParams focus on point, cell or burg
|
||||||
Zoom.invoke();
|
Zoom.invoke();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import * as d3 from "d3";
|
import * as d3 from "d3";
|
||||||
|
|
||||||
import {restoreDefaultEvents} from "scripts/events";
|
import {setDefaultEventHandlers} from "scripts/events";
|
||||||
import {tip} from "scripts/tooltips";
|
import {tip} from "scripts/tooltips";
|
||||||
import {findCell} from "utils/graphUtils";
|
import {findCell} from "utils/graphUtils";
|
||||||
import {minmax, normalize, rn} from "utils/numberUtils";
|
import {minmax, normalize, rn} from "utils/numberUtils";
|
||||||
|
|
@ -11,7 +11,7 @@ import {getBurgPopulation} from "utils/unitUtils";
|
||||||
|
|
||||||
// clear elSelected variable
|
// clear elSelected variable
|
||||||
export function unselect() {
|
export function unselect() {
|
||||||
restoreDefaultEvents();
|
setDefaultEventHandlers();
|
||||||
if (!elSelected) return;
|
if (!elSelected) return;
|
||||||
elSelected.call(d3.drag().on("drag", null)).attr("class", null);
|
elSelected.call(d3.drag().on("drag", null)).attr("class", null);
|
||||||
debug.selectAll("*").remove();
|
debug.selectAll("*").remove();
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import * as d3 from "d3";
|
import * as d3 from "d3";
|
||||||
|
|
||||||
import {restoreDefaultEvents} from "scripts/events";
|
import {setDefaultEventHandlers} from "scripts/events";
|
||||||
import {findCell} from "utils/graphUtils";
|
import {findCell} from "utils/graphUtils";
|
||||||
import {clearMainTip} from "scripts/tooltips";
|
import {clearMainTip} from "scripts/tooltips";
|
||||||
import {rn} from "utils/numberUtils";
|
import {rn} from "utils/numberUtils";
|
||||||
|
|
@ -271,7 +271,7 @@ export function editMarker(markerI) {
|
||||||
unselect();
|
unselect();
|
||||||
addMarker.classList.remove("pressed");
|
addMarker.classList.remove("pressed");
|
||||||
markerAdd.classList.remove("pressed");
|
markerAdd.classList.remove("pressed");
|
||||||
restoreDefaultEvents();
|
setDefaultEventHandlers();
|
||||||
clearMainTip();
|
clearMainTip();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import {restoreDefaultEvents} from "scripts/events";
|
import {setDefaultEventHandlers} from "scripts/events";
|
||||||
import {clearMainTip} from "scripts/tooltips";
|
import {clearMainTip} from "scripts/tooltips";
|
||||||
import {closeDialogs} from "dialogs/utils";
|
import {closeDialogs} from "dialogs/utils";
|
||||||
|
|
||||||
|
|
@ -197,7 +197,7 @@ export function overviewMarkers() {
|
||||||
|
|
||||||
addMarker.classList.remove("pressed");
|
addMarker.classList.remove("pressed");
|
||||||
markerAdd.classList.remove("pressed");
|
markerAdd.classList.remove("pressed");
|
||||||
restoreDefaultEvents();
|
setDefaultEventHandlers();
|
||||||
clearMainTip();
|
clearMainTip();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import {openDialog} from "dialogs";
|
||||||
import {closeDialogs} from "dialogs/utils";
|
import {closeDialogs} from "dialogs/utils";
|
||||||
import {turnLayerButtonOff} from "layers";
|
import {turnLayerButtonOff} from "layers";
|
||||||
import {unfog} from "modules/ui/editors";
|
import {unfog} from "modules/ui/editors";
|
||||||
import {restoreDefaultEvents} from "scripts/events";
|
import {setDefaultEventHandlers} from "scripts/events";
|
||||||
import {clearMainTip, showMainTip, tip} from "scripts/tooltips";
|
import {clearMainTip, showMainTip, tip} from "scripts/tooltips";
|
||||||
import {unique} from "utils/arrayUtils";
|
import {unique} from "utils/arrayUtils";
|
||||||
import {getRandomColor} from "utils/colorUtils";
|
import {getRandomColor} from "utils/colorUtils";
|
||||||
|
|
@ -993,7 +993,7 @@ export function editProvinces() {
|
||||||
if (!close)
|
if (!close)
|
||||||
$("#provincesEditor").dialog({position: {my: "right top", at: "right-10 top+10", of: "svg", collision: "fit"}});
|
$("#provincesEditor").dialog({position: {my: "right top", at: "right-10 top+10", of: "svg", collision: "fit"}});
|
||||||
|
|
||||||
restoreDefaultEvents();
|
setDefaultEventHandlers();
|
||||||
clearMainTip();
|
clearMainTip();
|
||||||
const selected = body.querySelector("div.selected");
|
const selected = body.querySelector("div.selected");
|
||||||
if (selected) selected.classList.remove("selected");
|
if (selected) selected.classList.remove("selected");
|
||||||
|
|
@ -1069,7 +1069,7 @@ export function editProvinces() {
|
||||||
|
|
||||||
function exitAddProvinceMode() {
|
function exitAddProvinceMode() {
|
||||||
customization = 0;
|
customization = 0;
|
||||||
restoreDefaultEvents();
|
setDefaultEventHandlers();
|
||||||
clearMainTip();
|
clearMainTip();
|
||||||
body.querySelectorAll("div > input, select, span, svg").forEach(e => (e.style.pointerEvents = "all"));
|
body.querySelectorAll("div > input, select, span, svg").forEach(e => (e.style.pointerEvents = "all"));
|
||||||
if (provincesAdd.classList.contains("pressed")) provincesAdd.classList.remove("pressed");
|
if (provincesAdd.classList.contains("pressed")) provincesAdd.classList.remove("pressed");
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import * as d3 from "d3";
|
import * as d3 from "d3";
|
||||||
|
|
||||||
import {restoreDefaultEvents} from "scripts/events";
|
import {setDefaultEventHandlers} from "scripts/events";
|
||||||
import {findCell} from "utils/graphUtils";
|
import {findCell} from "utils/graphUtils";
|
||||||
import {last} from "utils/arrayUtils";
|
import {last} from "utils/arrayUtils";
|
||||||
import {tip, clearMainTip} from "scripts/tooltips";
|
import {tip, clearMainTip} from "scripts/tooltips";
|
||||||
|
|
@ -210,7 +210,7 @@ export function editRegiment(selector) {
|
||||||
tip("Click on map to create new regiment or fleet", true);
|
tip("Click on map to create new regiment or fleet", true);
|
||||||
} else {
|
} else {
|
||||||
clearMainTip();
|
clearMainTip();
|
||||||
restoreDefaultEvents();
|
setDefaultEventHandlers();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -240,7 +240,7 @@ export function editRegiment(selector) {
|
||||||
armies.selectAll(":scope > g").classed("draggable", false);
|
armies.selectAll(":scope > g").classed("draggable", false);
|
||||||
} else {
|
} else {
|
||||||
clearMainTip();
|
clearMainTip();
|
||||||
restoreDefaultEvents();
|
setDefaultEventHandlers();
|
||||||
armies.selectAll(":scope > g").classed("draggable", true);
|
armies.selectAll(":scope > g").classed("draggable", true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -313,7 +313,7 @@ export function editRegiment(selector) {
|
||||||
} else {
|
} else {
|
||||||
clearMainTip();
|
clearMainTip();
|
||||||
armies.selectAll(":scope > g").classed("draggable", true);
|
armies.selectAll(":scope > g").classed("draggable", true);
|
||||||
restoreDefaultEvents();
|
setDefaultEventHandlers();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -453,7 +453,7 @@ export function editRegiment(selector) {
|
||||||
document.getElementById("regimentAdd").classList.remove("pressed");
|
document.getElementById("regimentAdd").classList.remove("pressed");
|
||||||
document.getElementById("regimentAttack").classList.remove("pressed");
|
document.getElementById("regimentAttack").classList.remove("pressed");
|
||||||
document.getElementById("regimentAttach").classList.remove("pressed");
|
document.getElementById("regimentAttach").classList.remove("pressed");
|
||||||
restoreDefaultEvents();
|
setDefaultEventHandlers();
|
||||||
elSelected = null;
|
elSelected = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import {rn} from "utils/numberUtils";
|
||||||
import {capitalize} from "utils/stringUtils";
|
import {capitalize} from "utils/stringUtils";
|
||||||
import {si} from "utils/unitUtils";
|
import {si} from "utils/unitUtils";
|
||||||
import {closeDialogs} from "dialogs/utils";
|
import {closeDialogs} from "dialogs/utils";
|
||||||
import {restoreDefaultEvents} from "scripts/events";
|
import {setDefaultEventHandlers} from "scripts/events";
|
||||||
|
|
||||||
let isLoaded = false;
|
let isLoaded = false;
|
||||||
|
|
||||||
|
|
@ -171,7 +171,7 @@ export function overviewRegiments(state) {
|
||||||
if (regimentAdd.offsetParent) regimentAdd.classList.add("pressed");
|
if (regimentAdd.offsetParent) regimentAdd.classList.add("pressed");
|
||||||
} else {
|
} else {
|
||||||
clearMainTip();
|
clearMainTip();
|
||||||
restoreDefaultEvents();
|
setDefaultEventHandlers();
|
||||||
addLines();
|
addLines();
|
||||||
if (regimentAdd.offsetParent) regimentAdd.classList.remove("pressed");
|
if (regimentAdd.offsetParent) regimentAdd.classList.remove("pressed");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import * as d3 from "d3";
|
import * as d3 from "d3";
|
||||||
|
|
||||||
import {restoreDefaultEvents} from "scripts/events";
|
import {setDefaultEventHandlers} from "scripts/events";
|
||||||
import {findCell} from "utils/graphUtils";
|
import {findCell} from "utils/graphUtils";
|
||||||
import {tip, showMainTip, clearMainTip} from "scripts/tooltips";
|
import {tip, showMainTip, clearMainTip} from "scripts/tooltips";
|
||||||
import {rn} from "utils/numberUtils";
|
import {rn} from "utils/numberUtils";
|
||||||
|
|
@ -92,7 +92,7 @@ export function editReliefIcon() {
|
||||||
|
|
||||||
removeCircle();
|
removeCircle();
|
||||||
updateReliefSizeInput();
|
updateReliefSizeInput();
|
||||||
restoreDefaultEvents();
|
setDefaultEventHandlers();
|
||||||
clearMainTip();
|
clearMainTip();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import * as d3 from "d3";
|
import * as d3 from "d3";
|
||||||
|
|
||||||
import {restoreDefaultEvents} from "scripts/events";
|
import {setDefaultEventHandlers} from "scripts/events";
|
||||||
import {getPackPolygon, findCell} from "utils/graphUtils";
|
import {getPackPolygon, findCell} from "utils/graphUtils";
|
||||||
import {last} from "utils/arrayUtils";
|
import {last} from "utils/arrayUtils";
|
||||||
import {tip, clearMainTip} from "scripts/tooltips";
|
import {tip, clearMainTip} from "scripts/tooltips";
|
||||||
|
|
@ -140,7 +140,7 @@ export function createRiver() {
|
||||||
function closeRiverCreator() {
|
function closeRiverCreator() {
|
||||||
body.innerHTML = "";
|
body.innerHTML = "";
|
||||||
debug.select("#controlCells").remove();
|
debug.select("#controlCells").remove();
|
||||||
restoreDefaultEvents();
|
setDefaultEventHandlers();
|
||||||
clearMainTip();
|
clearMainTip();
|
||||||
|
|
||||||
const forced = +document.getElementById("toggleCells").dataset.forced;
|
const forced = +document.getElementById("toggleCells").dataset.forced;
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import {rn} from "utils/numberUtils";
|
||||||
import {getNextId} from "utils/nodeUtils";
|
import {getNextId} from "utils/nodeUtils";
|
||||||
import {round} from "utils/stringUtils";
|
import {round} from "utils/stringUtils";
|
||||||
import {closeDialogs} from "dialogs/utils";
|
import {closeDialogs} from "dialogs/utils";
|
||||||
import {restoreDefaultEvents} from "../../scripts/events";
|
import {setDefaultEventHandlers} from "../../scripts/events";
|
||||||
|
|
||||||
let isLoaded = false;
|
let isLoaded = false;
|
||||||
|
|
||||||
|
|
@ -279,7 +279,7 @@ export function editRoute(onClick) {
|
||||||
elSelected.on("click", null);
|
elSelected.on("click", null);
|
||||||
} else {
|
} else {
|
||||||
clearMainTip();
|
clearMainTip();
|
||||||
restoreDefaultEvents();
|
setDefaultEventHandlers();
|
||||||
elSelected.on("click", addInterimControlPoint).attr("data-new", null);
|
elSelected.on("click", addInterimControlPoint).attr("data-new", null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import {closeDialogs} from "dialogs/utils";
|
||||||
import {renderLayer, toggleLayer, turnLayerButtonOn} from "layers";
|
import {renderLayer, toggleLayer, turnLayerButtonOn} from "layers";
|
||||||
import {unfog} from "modules/ui/editors";
|
import {unfog} from "modules/ui/editors";
|
||||||
import {aleaPRNG} from "scripts/aleaPRNG";
|
import {aleaPRNG} from "scripts/aleaPRNG";
|
||||||
import {restoreDefaultEvents} from "scripts/events";
|
import {setDefaultEventHandlers} from "scripts/events";
|
||||||
import {prompt} from "scripts/prompt";
|
import {prompt} from "scripts/prompt";
|
||||||
import {clearMainTip, tip} from "scripts/tooltips";
|
import {clearMainTip, tip} from "scripts/tooltips";
|
||||||
import {last} from "utils/arrayUtils";
|
import {last} from "utils/arrayUtils";
|
||||||
|
|
@ -465,7 +465,7 @@ function regenerateZones(event) {
|
||||||
|
|
||||||
function unpressClickToAddButton() {
|
function unpressClickToAddButton() {
|
||||||
addFeature.querySelectorAll("button.pressed").forEach(b => b.classList.remove("pressed"));
|
addFeature.querySelectorAll("button.pressed").forEach(b => b.classList.remove("pressed"));
|
||||||
restoreDefaultEvents();
|
setDefaultEventHandlers();
|
||||||
clearMainTip();
|
clearMainTip();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import * as d3 from "d3";
|
||||||
|
|
||||||
import {closeDialogs} from "dialogs/utils";
|
import {closeDialogs} from "dialogs/utils";
|
||||||
import {unfog} from "modules/ui/editors";
|
import {unfog} from "modules/ui/editors";
|
||||||
import {restoreDefaultEvents} from "scripts/events";
|
import {setDefaultEventHandlers} from "scripts/events";
|
||||||
import {clearMainTip, showMainTip, tip} from "scripts/tooltips";
|
import {clearMainTip, showMainTip, tip} from "scripts/tooltips";
|
||||||
import {unique} from "utils/arrayUtils";
|
import {unique} from "utils/arrayUtils";
|
||||||
import {findAll, findCell, getPackPolygon} from "utils/graphUtils";
|
import {findAll, findCell, getPackPolygon} from "utils/graphUtils";
|
||||||
|
|
@ -329,7 +329,7 @@ export function editZones() {
|
||||||
if (!close)
|
if (!close)
|
||||||
$("#zonesEditor").dialog({position: {my: "right top", at: "right-10 top+10", of: "svg", collision: "fit"}});
|
$("#zonesEditor").dialog({position: {my: "right top", at: "right-10 top+10", of: "svg", collision: "fit"}});
|
||||||
|
|
||||||
restoreDefaultEvents();
|
setDefaultEventHandlers();
|
||||||
clearMainTip();
|
clearMainTip();
|
||||||
zones.selectAll("g").each(function () {
|
zones.selectAll("g").each(function () {
|
||||||
this.removeAttribute("data-init");
|
this.removeAttribute("data-init");
|
||||||
|
|
|
||||||
|
|
@ -1,262 +0,0 @@
|
||||||
import * as d3 from "d3";
|
|
||||||
|
|
||||||
import {openDialog} from "dialogs";
|
|
||||||
import {layerIsOn} from "layers";
|
|
||||||
// @ts-expect-error js module
|
|
||||||
import {clearLegend, dragLegendBox} from "modules/legend";
|
|
||||||
// @ts-expect-error js module
|
|
||||||
import {updateCellInfo} from "modules/ui/cell-info";
|
|
||||||
import {debounce} from "utils/functionUtils";
|
|
||||||
import {findCell, findGridCell, isLand} from "utils/graphUtils";
|
|
||||||
import {byId} from "utils/shorthands";
|
|
||||||
import {
|
|
||||||
convertTemperature,
|
|
||||||
getBurgPopulation,
|
|
||||||
getCellIdPrecipitation,
|
|
||||||
getFriendlyHeight,
|
|
||||||
getCellPopulation,
|
|
||||||
getPopulationTip,
|
|
||||||
si
|
|
||||||
} from "utils/unitUtils";
|
|
||||||
import {showMainTip, tip} from "./tooltips";
|
|
||||||
|
|
||||||
export function restoreDefaultEvents() {
|
|
||||||
window.Zoom.setZoomBehavior();
|
|
||||||
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"))
|
|
||||||
.on("click", clearLegend)
|
|
||||||
.call(d3.drag().on("start", dragLegendBox));
|
|
||||||
}
|
|
||||||
|
|
||||||
// on viewbox click event - run function based on target
|
|
||||||
function handleMapClick(this: d3.ContainerElement) {
|
|
||||||
const el: HTMLElement = d3.event.target;
|
|
||||||
if (!el?.parentElement?.parentElement?.parentElement) return;
|
|
||||||
|
|
||||||
const parent = el.parentElement;
|
|
||||||
const grand = parent.parentElement!;
|
|
||||||
const great = grand.parentElement!;
|
|
||||||
const greatGreat = great.parentElement;
|
|
||||||
|
|
||||||
const p = d3.mouse(this);
|
|
||||||
const i = findCell(p[0], p[1]);
|
|
||||||
|
|
||||||
if (grand.id === "emblems" && defineEmblemData(el)) openDialog("emblemEditor", null, defineEmblemData(el));
|
|
||||||
else if (parent.id === "rivers") editRiver(el.id);
|
|
||||||
else if (grand.id === "routes") editRoute();
|
|
||||||
else if (el.tagName === "tspan" && greatGreat?.id === "labels") openDialog("labelEditor", null, {el});
|
|
||||||
else if (grand.id === "burgLabels" || grand.id === "burgIcons")
|
|
||||||
openDialog("burgEditor", null, {id: +(el.dataset.id || 0)});
|
|
||||||
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, {el});
|
|
||||||
else if (great.id === "armies") editRegiment();
|
|
||||||
else if (pack.cells.t[i] === 1) {
|
|
||||||
openDialog("coastlineEditor", null, {node: byId("island_" + pack.cells.f[i])});
|
|
||||||
} else if (grand.id === "lakes") openDialog("lakeEditor", null, {el});
|
|
||||||
}
|
|
||||||
|
|
||||||
function defineEmblemData(el: HTMLElement) {
|
|
||||||
const i = +(el.dataset?.i || 0);
|
|
||||||
|
|
||||||
type TEmblemType = "state" | "burg" | "province";
|
|
||||||
type TEmblemTypeArray = IPack[`${TEmblemType}s`];
|
|
||||||
|
|
||||||
const emblemTypeMap: Dict<[TEmblemTypeArray, TEmblemType]> = {
|
|
||||||
burgEmblems: [pack.burgs, "burg"],
|
|
||||||
provinceEmblems: [pack.provinces, "province"],
|
|
||||||
stateEmblems: [pack.states, "state"]
|
|
||||||
};
|
|
||||||
|
|
||||||
const emblemType = el.parentElement?.id;
|
|
||||||
if (emblemType && emblemType in emblemTypeMap) {
|
|
||||||
const [data, type] = emblemTypeMap[emblemType];
|
|
||||||
return {type, id: type + "COA" + i, el: data[i]};
|
|
||||||
}
|
|
||||||
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
const onMouseMove = debounce(handleMouseMove, 100);
|
|
||||||
function handleMouseMove(this: d3.ContainerElement) {
|
|
||||||
const point = d3.mouse(this);
|
|
||||||
const i = findCell(point[0], point[1]); // pack cell id
|
|
||||||
if (i === undefined) return;
|
|
||||||
|
|
||||||
showNotes(d3.event);
|
|
||||||
const gridCell = findGridCell(point[0], point[1], grid);
|
|
||||||
if (byId("tooltip")?.dataset.main) showMainTip();
|
|
||||||
else showTooltipOnMapHover(point, d3.event, i, gridCell);
|
|
||||||
if (byId("cellInfo")?.offsetParent) updateCellInfo(point, i, gridCell);
|
|
||||||
}
|
|
||||||
|
|
||||||
// show note box on hover (if any)
|
|
||||||
function showNotes(event: Event) {
|
|
||||||
if (byId("notesEditor")?.offsetParent) return;
|
|
||||||
|
|
||||||
const el = event.target as SVGElement;
|
|
||||||
if (!el?.parentElement?.parentElement?.parentElement) return;
|
|
||||||
|
|
||||||
const parent = el.parentElement;
|
|
||||||
const grand = parent.parentElement!;
|
|
||||||
|
|
||||||
let id = el.id || parent.id || grand.id;
|
|
||||||
if (grand.id === "burgLabels") id = "burg" + el.dataset.id;
|
|
||||||
else if (grand.id === "burgIcons") id = "burg" + el.dataset.id;
|
|
||||||
|
|
||||||
const note = notes.find(note => note.id === id);
|
|
||||||
if (note !== undefined && note.legend !== "") {
|
|
||||||
byId("notes")!.style.display = "block";
|
|
||||||
byId("notesHeader")!.innerHTML = note.name;
|
|
||||||
byId("notesBody")!.innerHTML = note.legend;
|
|
||||||
} else if (!options.pinNotes && !byId("markerEditor")?.offsetParent) {
|
|
||||||
byId("notes")!.style.display = "none";
|
|
||||||
byId("notesHeader")!.innerHTML = "";
|
|
||||||
byId("notesBody")!.innerHTML = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// show viewbox tooltip if main tooltip is blank
|
|
||||||
function showTooltipOnMapHover(point: TPoint, event: Event, packCellId: number, gridCellId: number) {
|
|
||||||
tip(""); // clear tip
|
|
||||||
const path = event.composedPath() as HTMLElement[];
|
|
||||||
if (!path[path.length - 8]) return;
|
|
||||||
|
|
||||||
const group = path[path.length - 7].id;
|
|
||||||
const subgroup = path[path.length - 8].id;
|
|
||||||
|
|
||||||
const element = event.target as HTMLElement;
|
|
||||||
const parent = element.parentElement!;
|
|
||||||
|
|
||||||
const land = isLand(packCellId);
|
|
||||||
|
|
||||||
// specific elements
|
|
||||||
if (group === "armies") return tip(parent.dataset.name + ". Click to edit");
|
|
||||||
|
|
||||||
if (group === "emblems" && element.tagName === "use") {
|
|
||||||
d3.select(element).raise();
|
|
||||||
d3.select(parent).raise();
|
|
||||||
|
|
||||||
const emblemData = defineEmblemData(element);
|
|
||||||
if (!emblemData) return;
|
|
||||||
|
|
||||||
const {type, el} = emblemData;
|
|
||||||
const name = ("fullName" in el && el.fullName) || el.name;
|
|
||||||
tip(`${name} ${type} emblem. Click to edit`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (group === "rivers") {
|
|
||||||
const riverId = +element.id.slice(5);
|
|
||||||
const river = pack.rivers.find(r => r.i === riverId);
|
|
||||||
const name = river ? `${river.name} ${river.type}` : "";
|
|
||||||
tip(name + ". Click to edit");
|
|
||||||
|
|
||||||
const $riversOverview = byId("riversOverview")!;
|
|
||||||
if ($riversOverview?.offsetParent) highlightEditorLine($riversOverview, riverId, 5000);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (group === "routes") return tip("Click to edit the Route");
|
|
||||||
|
|
||||||
if (group === "terrain") return tip("Click to edit the Relief Icon");
|
|
||||||
|
|
||||||
if (subgroup === "burgLabels" || subgroup === "burgIcons") {
|
|
||||||
const burgId = +(path[path.length - 10].dataset.id || 0);
|
|
||||||
const burg = pack.burgs[burgId];
|
|
||||||
|
|
||||||
const population = si(getBurgPopulation(burg.population));
|
|
||||||
tip(`${burg.name}. Population: ${population}. Click to edit`);
|
|
||||||
|
|
||||||
const $burgOverview = byId("burgOverview");
|
|
||||||
if ($burgOverview?.offsetParent) highlightEditorLine($burgOverview, burgId, 5000);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (group === "labels") return tip("Click to edit the Label");
|
|
||||||
|
|
||||||
if (group === "markers") return tip("Click to edit the Marker and pin the marker note");
|
|
||||||
|
|
||||||
if (group === "ruler") {
|
|
||||||
const tag = element.tagName;
|
|
||||||
const className = element.getAttribute("class");
|
|
||||||
if (tag === "circle" && className === "edge")
|
|
||||||
return tip("Drag to adjust. Hold Ctrl and drag to add a point. Click to remove the point");
|
|
||||||
if (tag === "circle" && className === "control")
|
|
||||||
return tip("Drag to adjust. Hold Shift and drag to keep axial direction. Click to remove the point");
|
|
||||||
if (tag === "circle") return tip("Drag to adjust the measurer");
|
|
||||||
if (tag === "polyline") return tip("Click on drag to add a control point");
|
|
||||||
if (tag === "path") return tip("Drag to move the measurer");
|
|
||||||
if (tag === "text") return tip("Drag to move, click to remove the measurer");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (subgroup === "burgIcons") return tip("Click to edit the Burg");
|
|
||||||
|
|
||||||
if (subgroup === "burgLabels") return tip("Click to edit the Burg");
|
|
||||||
|
|
||||||
if (group === "lakes" && !land) {
|
|
||||||
const lakeId = +element.dataset.f;
|
|
||||||
const name = pack.features[lakeId]?.name;
|
|
||||||
const fullName = subgroup === "freshwater" ? name : name + " " + subgroup;
|
|
||||||
tip(`${fullName} lake. Click to edit`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (group === "coastline") return tip("Click to edit the coastline");
|
|
||||||
|
|
||||||
if (group === "zones") {
|
|
||||||
const zone = path[path.length - 8];
|
|
||||||
tip(zone.dataset.description);
|
|
||||||
if (zonesEditor?.offsetParent) highlightEditorLine(zonesEditor, zone.id, 5000);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (group === "ice") return tip("Click to edit the Ice");
|
|
||||||
|
|
||||||
// covering elements
|
|
||||||
if (layerIsOn("togglePrec") && land) tip("Annual Precipitation: " + getCellIdPrecipitation(packCellId));
|
|
||||||
else if (layerIsOn("togglePopulation")) {
|
|
||||||
const [rural, urban] = getCellPopulation(packCellId);
|
|
||||||
tip(getPopulationTip("Cell population", rural, urban));
|
|
||||||
} else if (layerIsOn("toggleTemp")) tip("Temperature: " + convertTemperature(grid.cells.temp[gridCellId]));
|
|
||||||
else if (layerIsOn("toggleBiomes") && pack.cells.biome[packCellId]) {
|
|
||||||
const biome = pack.cells.biome[packCellId];
|
|
||||||
tip("Biome: " + biomesData.name[biome]);
|
|
||||||
if (biomesEditor?.offsetParent) highlightEditorLine(biomesEditor, biome);
|
|
||||||
} else if (layerIsOn("toggleReligions") && pack.cells.religion[packCellId]) {
|
|
||||||
const religion = pack.cells.religion[packCellId];
|
|
||||||
const r = pack.religions[religion];
|
|
||||||
const type = r.type === "Cult" || r.type == "Heresy" ? r.type : r.type + " religion";
|
|
||||||
tip(type + ": " + r.name);
|
|
||||||
if (religionsEditor?.offsetParent) highlightEditorLine(religionsEditor, religion);
|
|
||||||
} else if (pack.cells.state[packCellId] && (layerIsOn("toggleProvinces") || layerIsOn("toggleStates"))) {
|
|
||||||
const state = pack.cells.state[packCellId];
|
|
||||||
const stateName = pack.states[state].fullName;
|
|
||||||
const province = pack.cells.province[packCellId];
|
|
||||||
const prov = province ? pack.provinces[province].fullName + ", " : "";
|
|
||||||
tip(prov + stateName);
|
|
||||||
if (byId("statesEditor")?.offsetParent) highlightEditorLine(statesEditor, state);
|
|
||||||
if (byId("diplomacyEditor")?.offsetParent) highlightEditorLine(diplomacyEditor, state);
|
|
||||||
if (byId("militaryOverview")?.offsetParent) highlightEditorLine(militaryOverview, state);
|
|
||||||
if (byId("provincesEditor")?.offsetParent) highlightEditorLine(provincesEditor, province);
|
|
||||||
} else if (layerIsOn("toggleCultures") && pack.cells.culture[packCellId]) {
|
|
||||||
const culture = pack.cells.culture[packCellId];
|
|
||||||
tip("Culture: " + pack.cultures[culture].name);
|
|
||||||
if (byId("culturesEditor")?.offsetParent) highlightEditorLine(culturesEditor, culture);
|
|
||||||
} else if (layerIsOn("toggleHeight")) tip("Height: " + getFriendlyHeight(point));
|
|
||||||
}
|
|
||||||
|
|
||||||
function highlightEditorLine($editor, id, timeout = 10000) {
|
|
||||||
Array.from($editor.getElementsByClassName("states hovered")).forEach(el => el.classList.remove("hovered")); // clear all hovered
|
|
||||||
const hovered = Array.from($editor.querySelectorAll("div")).find(el => el.dataset.id == id);
|
|
||||||
if (hovered) hovered.classList.add("hovered"); // add hovered class
|
|
||||||
if (timeout)
|
|
||||||
setTimeout(() => {
|
|
||||||
hovered && hovered.classList.remove("hovered");
|
|
||||||
}, timeout);
|
|
||||||
}
|
|
||||||
25
src/scripts/events/index.ts
Normal file
25
src/scripts/events/index.ts
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
import * as d3 from "d3";
|
||||||
|
|
||||||
|
import {openDialog} from "dialogs";
|
||||||
|
import {tip} from "scripts/tooltips";
|
||||||
|
import {handleMapClick} from "./onclick";
|
||||||
|
import {onMouseMove} from "./onhover";
|
||||||
|
// @ts-expect-error js module
|
||||||
|
import {clearLegend, dragLegendBox} from "modules/legend";
|
||||||
|
|
||||||
|
export function setDefaultEventHandlers() {
|
||||||
|
window.Zoom.setZoomBehavior();
|
||||||
|
|
||||||
|
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"))
|
||||||
|
.on("click", clearLegend)
|
||||||
|
.call(d3.drag().on("start", dragLegendBox));
|
||||||
|
}
|
||||||
65
src/scripts/events/onclick.ts
Normal file
65
src/scripts/events/onclick.ts
Normal file
|
|
@ -0,0 +1,65 @@
|
||||||
|
import * as d3 from "d3";
|
||||||
|
|
||||||
|
import {openDialog} from "dialogs";
|
||||||
|
// @ts-expect-error js module
|
||||||
|
import {clearLegend, dragLegendBox} from "modules/legend";
|
||||||
|
// @ts-expect-error js module
|
||||||
|
import {updateCellInfo} from "modules/ui/cell-info";
|
||||||
|
import {findCell} from "utils/graphUtils";
|
||||||
|
import {defineEmblemData} from "./utils";
|
||||||
|
|
||||||
|
const getClickedElement = (
|
||||||
|
tagName: string,
|
||||||
|
parentId: string,
|
||||||
|
grandId: string,
|
||||||
|
greatId: string,
|
||||||
|
greatGrandId: string,
|
||||||
|
isCoastalCell: boolean
|
||||||
|
) => {
|
||||||
|
if (grandId === "emblems") return "emblem";
|
||||||
|
if (parentId === "rivers") return "river";
|
||||||
|
if (grandId === "routes") return "route";
|
||||||
|
if (tagName === "tspan" && greatGrandId === "labels") return "label";
|
||||||
|
if (grandId === "burgLabels" || grandId === "burgIcons") return "burg";
|
||||||
|
if (parentId === "ice") return "ice";
|
||||||
|
if (parentId === "terrain") return "reliefIcon";
|
||||||
|
if (grandId === "markers" || greatId === "markers") return "marker";
|
||||||
|
if (grandId === "coastline" || isCoastalCell) return "coastline";
|
||||||
|
if (greatId === "armies") return "regiment";
|
||||||
|
if (grandId === "lakes") return "lake";
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
type ClickedElement = ReturnType<typeof getClickedElement>;
|
||||||
|
type OnClickEvent = (el: HTMLElement) => void;
|
||||||
|
type OnClickEventMap = {[key in Exclude<ClickedElement, null>]: OnClickEvent};
|
||||||
|
|
||||||
|
const onClickEventsMap: OnClickEventMap = {
|
||||||
|
emblem: el => openDialog("emblemEditor", null, defineEmblemData(el)),
|
||||||
|
river: el => openDialog("riverEditor", null, el.id),
|
||||||
|
route: () => openDialog("routeEditor"),
|
||||||
|
label: el => openDialog("labelEditor", null, {el}),
|
||||||
|
burg: el => openDialog("burgEditor", null, {id: +(el.dataset.id || 0)}),
|
||||||
|
ice: () => openDialog("iceEditor"),
|
||||||
|
reliefIcon: () => openDialog("reliefEditor"),
|
||||||
|
marker: () => openDialog("markerEditor"),
|
||||||
|
coastline: el => openDialog("coastlineEditor", null, {el}),
|
||||||
|
regiment: () => openDialog("regimentEditor"),
|
||||||
|
lake: el => openDialog("lakeEditor", null, {el})
|
||||||
|
};
|
||||||
|
|
||||||
|
// on viewbox click event - run function based on target
|
||||||
|
export function handleMapClick(this: d3.ContainerElement) {
|
||||||
|
const path = d3.event.composedPath() as HTMLElement[];
|
||||||
|
const [el, parent, grand, great, greatGrand] = path;
|
||||||
|
if (!el || !parent || !grand || !great || !greatGrand) return;
|
||||||
|
|
||||||
|
const p = d3.mouse(this);
|
||||||
|
const i = findCell(p[0], p[1]);
|
||||||
|
const isCoastalCell = pack.cells.t[i] === 1;
|
||||||
|
|
||||||
|
const clickedElement = getClickedElement(el.tagName, parent.id, grand.id, great.id, greatGrand.id, isCoastalCell);
|
||||||
|
if (clickedElement && clickedElement in onClickEventsMap) {
|
||||||
|
onClickEventsMap[clickedElement](el);
|
||||||
|
}
|
||||||
|
}
|
||||||
251
src/scripts/events/onhover.ts
Normal file
251
src/scripts/events/onhover.ts
Normal file
|
|
@ -0,0 +1,251 @@
|
||||||
|
import * as d3 from "d3";
|
||||||
|
|
||||||
|
import {layerIsOn} from "layers";
|
||||||
|
// @ts-expect-error js module
|
||||||
|
import {clearLegend, dragLegendBox} from "modules/legend";
|
||||||
|
// @ts-expect-error js module
|
||||||
|
import {updateCellInfo} from "modules/ui/cell-info";
|
||||||
|
import {debounce} from "utils/functionUtils";
|
||||||
|
import {findCell, findGridCell, isLand} from "utils/graphUtils";
|
||||||
|
import {byId} from "utils/shorthands";
|
||||||
|
import {
|
||||||
|
convertTemperature,
|
||||||
|
getBurgPopulation,
|
||||||
|
getCellIdPrecipitation,
|
||||||
|
getFriendlyHeight,
|
||||||
|
getCellPopulation,
|
||||||
|
getPopulationTip,
|
||||||
|
si
|
||||||
|
} from "utils/unitUtils";
|
||||||
|
import {showMainTip, tip} from "scripts/tooltips";
|
||||||
|
import {defineEmblemData} from "./utils";
|
||||||
|
|
||||||
|
export const onMouseMove = debounce(handleMouseMove, 100);
|
||||||
|
|
||||||
|
function handleMouseMove(this: d3.ContainerElement) {
|
||||||
|
const [x, y] = d3.mouse(this);
|
||||||
|
const i = findCell(x, y); // pack cell id
|
||||||
|
if (i === undefined) return;
|
||||||
|
|
||||||
|
showNotes(d3.event);
|
||||||
|
const gridCell = findGridCell(x, y, grid);
|
||||||
|
if (byId("tooltip")?.dataset.main) showMainTip();
|
||||||
|
else showTooltipOnMapHover([x, y], d3.event, i, gridCell);
|
||||||
|
if (byId("cellInfo")?.offsetParent) updateCellInfo([x, y], i, gridCell);
|
||||||
|
}
|
||||||
|
|
||||||
|
// show note box on hover (if any)
|
||||||
|
function showNotes(event: Event) {
|
||||||
|
if (byId("notesEditor")?.offsetParent) return;
|
||||||
|
|
||||||
|
const path = event.composedPath() as HTMLElement[];
|
||||||
|
const [el, parent, grand] = path;
|
||||||
|
if (!el || !parent || !grand) return;
|
||||||
|
|
||||||
|
let id = el.id || parent.id || grand.id;
|
||||||
|
if (grand.id === "burgLabels") id = "burg" + el.dataset.id;
|
||||||
|
else if (grand.id === "burgIcons") id = "burg" + el.dataset.id;
|
||||||
|
|
||||||
|
const note = notes.find(note => note.id === id);
|
||||||
|
if (note !== undefined && note.legend !== "") {
|
||||||
|
byId("notes")!.style.display = "block";
|
||||||
|
byId("notesHeader")!.innerHTML = note.name;
|
||||||
|
byId("notesBody")!.innerHTML = note.legend;
|
||||||
|
} else if (!options.pinNotes && !byId("markerEditor")?.offsetParent) {
|
||||||
|
byId("notes")!.style.display = "none";
|
||||||
|
byId("notesHeader")!.innerHTML = "";
|
||||||
|
byId("notesBody")!.innerHTML = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getHoveredElement = (tagName: string, group: string, subgroup: string, isLand: boolean, cellId: number) => {
|
||||||
|
const {biome, religion, state, culture} = pack.cells;
|
||||||
|
|
||||||
|
if (group === "armies") return "regiment";
|
||||||
|
if (group === "emblems" && tagName === "use") return "emblem";
|
||||||
|
if (group === "rivers") return "river";
|
||||||
|
if (group === "routes") return "route";
|
||||||
|
if (group === "terrain") return "reliefIcon";
|
||||||
|
if (subgroup === "burgLabels" || subgroup === "burgIcons") return "burg";
|
||||||
|
if (group === "labels") return "label";
|
||||||
|
if (group === "markers") return "marker";
|
||||||
|
if (group === "ruler") return "ruler";
|
||||||
|
if (group === "lakes" && !isLand) return "lake";
|
||||||
|
if (group === "coastline") return "coastline";
|
||||||
|
if (group === "zones") return "zone";
|
||||||
|
if (group === "ice") return "ice";
|
||||||
|
if (layerIsOn("togglePrec") && isLand) return "precipitationLayer";
|
||||||
|
if (layerIsOn("togglePopulation")) return "populationLayer";
|
||||||
|
if (layerIsOn("toggleTemp")) return "temperatureLayer";
|
||||||
|
if (layerIsOn("toggleBiomes") && biome[cellId]) return "biomesLayer";
|
||||||
|
if (layerIsOn("toggleReligions") && religion[cellId]) return "religionsLayer";
|
||||||
|
if (layerIsOn("toggleProvinces") || (layerIsOn("toggleStates") && state[cellId])) return "statesLayer";
|
||||||
|
if (layerIsOn("toggleCultures") && culture[cellId]) return "culturesLayer";
|
||||||
|
if (layerIsOn("toggleHeight")) return "heightLayer";
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
type HoveredElement = ReturnType<typeof getHoveredElement>;
|
||||||
|
type OnHoverEvent = (props: {
|
||||||
|
path: HTMLElement[];
|
||||||
|
element: HTMLElement;
|
||||||
|
parent: HTMLElement;
|
||||||
|
subgroup: string;
|
||||||
|
point: TPoint;
|
||||||
|
packCellId: number;
|
||||||
|
gridCellId: number;
|
||||||
|
}) => void;
|
||||||
|
type OnHoverEventMap = {[key in Exclude<HoveredElement, null>]: OnHoverEvent};
|
||||||
|
|
||||||
|
const onHoverEventsMap: OnHoverEventMap = {
|
||||||
|
regiment: ({parent}) => tip(parent.dataset.name + ". Click to edit"),
|
||||||
|
|
||||||
|
emblem: ({element, parent}) => {
|
||||||
|
d3.select(element).raise();
|
||||||
|
d3.select(parent).raise();
|
||||||
|
|
||||||
|
const emblemData = defineEmblemData(element);
|
||||||
|
if (emblemData) {
|
||||||
|
const {type, el} = emblemData;
|
||||||
|
const name = ("fullName" in el && el.fullName) || el.name;
|
||||||
|
tip(`${name} ${type} emblem. Click to edit`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
river: ({element}) => {
|
||||||
|
const riverId = +element.id.slice(5);
|
||||||
|
const river = pack.rivers.find(r => r.i === riverId);
|
||||||
|
const name = river ? `${river.name} ${river.type}` : "";
|
||||||
|
tip(name + ". Click to edit");
|
||||||
|
|
||||||
|
highlightDialogLine("riversOverview", riverId, 5000);
|
||||||
|
},
|
||||||
|
|
||||||
|
route: () => tip("Click to edit the Route"),
|
||||||
|
|
||||||
|
reliefIcon: () => tip("Click to edit the Relief Icon"),
|
||||||
|
|
||||||
|
burg: ({path}) => {
|
||||||
|
const burgId = +(path.at(-10)?.dataset.id || 0);
|
||||||
|
const {population, name} = pack.burgs[burgId];
|
||||||
|
tip(`${name}. Population: ${si(getBurgPopulation(population))}. Click to edit`);
|
||||||
|
|
||||||
|
highlightDialogLine("burgOverview", burgId, 5000);
|
||||||
|
},
|
||||||
|
|
||||||
|
label: () => tip("Click to edit the Label"),
|
||||||
|
|
||||||
|
marker: () => tip("Click to edit the Marker and pin the marker note"),
|
||||||
|
|
||||||
|
ruler: ({element}) => {
|
||||||
|
const tag = element.tagName;
|
||||||
|
const className = element.getAttribute("class");
|
||||||
|
|
||||||
|
if (tag === "circle" && className === "edge")
|
||||||
|
return tip("Drag to adjust. Hold Ctrl and drag to add a point. Click to remove the point");
|
||||||
|
if (tag === "circle" && className === "control")
|
||||||
|
return tip("Drag to adjust. Hold Shift and drag to keep axial direction. Click to remove the point");
|
||||||
|
if (tag === "circle") return tip("Drag to adjust the measurer");
|
||||||
|
if (tag === "polyline") return tip("Click on drag to add a control point");
|
||||||
|
if (tag === "path") return tip("Drag to move the measurer");
|
||||||
|
if (tag === "text") return tip("Drag to move, click to remove the measurer");
|
||||||
|
},
|
||||||
|
|
||||||
|
lake: ({element, subgroup}) => {
|
||||||
|
const lakeId = +(element.dataset.f || 0);
|
||||||
|
const name = pack.features[lakeId]?.name;
|
||||||
|
const fullName = subgroup === "freshwater" ? name : name + " " + subgroup;
|
||||||
|
tip(`${fullName} lake. Click to edit`);
|
||||||
|
},
|
||||||
|
|
||||||
|
coastline: () => tip("Click to edit the coastline"),
|
||||||
|
|
||||||
|
zone: ({path}) => {
|
||||||
|
const $zone = path[path.length - 8];
|
||||||
|
tip($zone.dataset.description || "");
|
||||||
|
|
||||||
|
highlightDialogLine("zonesEditor", $zone.id, 5000);
|
||||||
|
},
|
||||||
|
|
||||||
|
ice: () => tip("Click to edit the Ice"),
|
||||||
|
|
||||||
|
precipitationLayer: ({packCellId}) => tip("Annual Precipitation: " + getCellIdPrecipitation(packCellId)),
|
||||||
|
|
||||||
|
populationLayer: ({packCellId}) => {
|
||||||
|
const [rural, urban] = getCellPopulation(packCellId);
|
||||||
|
tip(getPopulationTip("Cell population", rural, urban));
|
||||||
|
},
|
||||||
|
|
||||||
|
temperatureLayer: ({gridCellId}) => tip("Temperature: " + convertTemperature(grid.cells.temp[gridCellId])),
|
||||||
|
|
||||||
|
biomesLayer: ({packCellId}) => {
|
||||||
|
const biome = pack.cells.biome[packCellId];
|
||||||
|
tip("Biome: " + biomesData.name[biome]);
|
||||||
|
|
||||||
|
highlightDialogLine("biomesEditor", biome);
|
||||||
|
},
|
||||||
|
|
||||||
|
religionsLayer: ({packCellId}) => {
|
||||||
|
const religionId = pack.cells.religion[packCellId];
|
||||||
|
const {type, name} = pack.religions[religionId] || {};
|
||||||
|
const typeTip = type === "Cult" || type == "Heresy" ? type : type + " religion";
|
||||||
|
tip(`${typeTip}: ${name}`);
|
||||||
|
|
||||||
|
highlightDialogLine("religionsEditor", religionId);
|
||||||
|
},
|
||||||
|
|
||||||
|
statesLayer: ({packCellId}) => {
|
||||||
|
const state = pack.cells.state[packCellId];
|
||||||
|
const stateName = pack.states[state].fullName;
|
||||||
|
const province = pack.cells.province[packCellId];
|
||||||
|
const prov = province ? `${pack.provinces[province].fullName}, ` : "";
|
||||||
|
tip(prov + stateName);
|
||||||
|
|
||||||
|
highlightDialogLine("statesEditor", state);
|
||||||
|
highlightDialogLine("diplomacyEditor", state);
|
||||||
|
highlightDialogLine("militaryEditor", state);
|
||||||
|
highlightDialogLine("provincesEditor", province);
|
||||||
|
},
|
||||||
|
|
||||||
|
culturesLayer: ({packCellId}) => {
|
||||||
|
const culture = pack.cells.culture[packCellId];
|
||||||
|
tip("Culture: " + pack.cultures[culture].name);
|
||||||
|
|
||||||
|
highlightDialogLine("culturesEditor", culture);
|
||||||
|
},
|
||||||
|
|
||||||
|
heightLayer: ({point}) => tip("Height: " + getFriendlyHeight(point))
|
||||||
|
};
|
||||||
|
|
||||||
|
// show viewbox tooltip if main tooltip is blank
|
||||||
|
function showTooltipOnMapHover(point: TPoint, event: Event, packCellId: number, gridCellId: number) {
|
||||||
|
tip(""); // clear tip
|
||||||
|
|
||||||
|
const path = event.composedPath() as HTMLElement[];
|
||||||
|
const [element, parent] = path;
|
||||||
|
if (!element || !parent || !path.at(-7) || !path.at(-8)) return;
|
||||||
|
|
||||||
|
const group = path.at(-7)!.id;
|
||||||
|
const subgroup = path.at(-8)!.id;
|
||||||
|
const land = isLand(packCellId);
|
||||||
|
|
||||||
|
const hoveredMapElement = getHoveredElement(element.tagName, group, subgroup, land, packCellId);
|
||||||
|
if (hoveredMapElement && hoveredMapElement in onHoverEventsMap) {
|
||||||
|
onHoverEventsMap[hoveredMapElement]({path, element, parent, subgroup, point, packCellId, gridCellId});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function highlightDialogLine(dialogId: string, lineId: number | string, timeout = 5000) {
|
||||||
|
const $dialog = byId(dialogId);
|
||||||
|
if (!$dialog || !$dialog.offsetParent) return; // check if dialog is visible
|
||||||
|
|
||||||
|
Array.from($dialog.getElementsByClassName("states hovered")).forEach(el => el.classList.remove("hovered")); // clear all hovered
|
||||||
|
const hovered = Array.from($dialog.querySelectorAll("div")).find(el => el.dataset.id === String(lineId));
|
||||||
|
if (hovered) hovered.classList.add("hovered"); // add hovered class
|
||||||
|
|
||||||
|
if (timeout)
|
||||||
|
setTimeout(() => {
|
||||||
|
hovered && hovered.classList.remove("hovered");
|
||||||
|
}, timeout);
|
||||||
|
}
|
||||||
20
src/scripts/events/utils.ts
Normal file
20
src/scripts/events/utils.ts
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
type TEmblemType = "state" | "burg" | "province";
|
||||||
|
type TEmblemTypeArray = IPack[`${TEmblemType}s`];
|
||||||
|
|
||||||
|
const emblemTypeMap: {[key: string]: [TEmblemTypeArray, TEmblemType]} = {
|
||||||
|
burgEmblems: [pack.burgs, "burg"],
|
||||||
|
provinceEmblems: [pack.provinces, "province"],
|
||||||
|
stateEmblems: [pack.states, "state"]
|
||||||
|
};
|
||||||
|
|
||||||
|
export function defineEmblemData(el: HTMLElement) {
|
||||||
|
const i = +(el.dataset?.i || 0);
|
||||||
|
|
||||||
|
const emblemType = el.parentElement?.id;
|
||||||
|
if (emblemType && emblemType in emblemTypeMap) {
|
||||||
|
const [data, type] = emblemTypeMap[emblemType];
|
||||||
|
return {type, id: type + "COA" + i, el: data[i]};
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
@ -2,7 +2,7 @@ import * as d3 from "d3";
|
||||||
|
|
||||||
import {ERROR, WARN} from "config/logging";
|
import {ERROR, WARN} from "config/logging";
|
||||||
import {loadMapFromURL} from "modules/io/load";
|
import {loadMapFromURL} from "modules/io/load";
|
||||||
import {restoreDefaultEvents} from "scripts/events";
|
import {setDefaultEventHandlers} from "scripts/events";
|
||||||
import {ldb} from "scripts/indexedDB";
|
import {ldb} from "scripts/indexedDB";
|
||||||
import {getInputValue} from "utils/nodeUtils";
|
import {getInputValue} from "utils/nodeUtils";
|
||||||
import {generateMapOnLoad} from "./generation";
|
import {generateMapOnLoad} from "./generation";
|
||||||
|
|
@ -11,7 +11,7 @@ export function addOnLoadListener() {
|
||||||
document.on("DOMContentLoaded", async () => {
|
document.on("DOMContentLoaded", async () => {
|
||||||
await loadOrGenerateMap();
|
await loadOrGenerateMap();
|
||||||
hideLoading();
|
hideLoading();
|
||||||
restoreDefaultEvents();
|
setDefaultEventHandlers();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
1
src/types/grid.d.ts
vendored
1
src/types/grid.d.ts
vendored
|
|
@ -15,6 +15,7 @@ interface IGrid {
|
||||||
h: IntArray;
|
h: IntArray;
|
||||||
t: IntArray;
|
t: IntArray;
|
||||||
f: IntArray;
|
f: IntArray;
|
||||||
|
temp: IntArray;
|
||||||
prec: IntArray;
|
prec: IntArray;
|
||||||
};
|
};
|
||||||
features: IFeature[];
|
features: IFeature[];
|
||||||
|
|
|
||||||
11
src/types/pack.d.ts
vendored
11
src/types/pack.d.ts
vendored
|
|
@ -12,9 +12,16 @@ interface IPack {
|
||||||
c: number[][];
|
c: number[][];
|
||||||
g: IntArray;
|
g: IntArray;
|
||||||
h: IntArray;
|
h: IntArray;
|
||||||
|
t: IntArray;
|
||||||
|
f: IntArray;
|
||||||
|
biome: IntArray;
|
||||||
pop: Float32Array;
|
pop: Float32Array;
|
||||||
burg: IntArray;
|
|
||||||
area: IntArray;
|
area: IntArray;
|
||||||
|
state: IntArray;
|
||||||
|
culture: IntArray;
|
||||||
|
religion: IntArray;
|
||||||
|
province: IntArray;
|
||||||
|
burg: IntArray;
|
||||||
q: d3.Quadtree<number[]>;
|
q: d3.Quadtree<number[]>;
|
||||||
};
|
};
|
||||||
states: IState[];
|
states: IState[];
|
||||||
|
|
@ -27,6 +34,7 @@ interface IPack {
|
||||||
|
|
||||||
interface IFeature {
|
interface IFeature {
|
||||||
i: number;
|
i: number;
|
||||||
|
name: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IState {
|
interface IState {
|
||||||
|
|
@ -62,6 +70,7 @@ interface IBurg {
|
||||||
interface IReligion {
|
interface IReligion {
|
||||||
i: number;
|
i: number;
|
||||||
name: string;
|
name: string;
|
||||||
|
type: "Folk" | "Orgamized" | "Cult" | "Heresy";
|
||||||
removed?: boolean;
|
removed?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ export function convertTemperature(temp: number) {
|
||||||
// ***
|
// ***
|
||||||
|
|
||||||
// get user-friendly (real-world) height value from coordinates
|
// get user-friendly (real-world) height value from coordinates
|
||||||
export function getFriendlyHeight([x, y]: [number, number]) {
|
export function getFriendlyHeight([x, y]: TPoint) {
|
||||||
const packH = pack.cells.h[findCell(x, y)];
|
const packH = pack.cells.h[findCell(x, y)];
|
||||||
const gridH = grid.cells.h[findGridCell(x, y, grid)];
|
const gridH = grid.cells.h[findGridCell(x, y, grid)];
|
||||||
const h = packH < 20 ? gridH : packH;
|
const h = packH < 20 ? gridH : packH;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue