mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-18 10:01:23 +01:00
feat: burg group editor - form
This commit is contained in:
parent
d8009f84ad
commit
511d8f37d8
3 changed files with 81 additions and 86 deletions
|
|
@ -5358,7 +5358,6 @@
|
||||||
</colgroup>
|
</colgroup>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th data-tip="Select group to be assigned if other groups are not passed">Default</th>
|
|
||||||
<th data-tip="Type group name">Name</th>
|
<th data-tip="Type group name">Name</th>
|
||||||
<th data-tip="Set min population constraint" colspan="2">Population</th>
|
<th data-tip="Set min population constraint" colspan="2">Population</th>
|
||||||
<th data-tip="Set population percentile: 0-100, where 90 means the burg must have a population higher than 90% of all burgs">Percentile</th>
|
<th data-tip="Set population percentile: 0-100, where 90 means the burg must have a population higher than 90% of all burgs">Percentile</th>
|
||||||
|
|
@ -5369,15 +5368,12 @@
|
||||||
<th data-tip="Select allowed features">Features</th>
|
<th data-tip="Select allowed features">Features</th>
|
||||||
<th data-tip="Number of burgs in group">Count</th>
|
<th data-tip="Number of burgs in group">Count</th>
|
||||||
<th data-tip="Activate/deactivate group">Active</th>
|
<th data-tip="Activate/deactivate group">Active</th>
|
||||||
|
<th data-tip="Select group to be assigned if other groups are not passed">Default</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody id="burgGroupsBody"></tbody>
|
<tbody id="burgGroupsBody"></tbody>
|
||||||
</table>
|
</table>
|
||||||
</form>
|
</form>
|
||||||
<div id="burgGroupsBottom" style="margin-top: .3em">
|
|
||||||
<button id="burgGroupsEditorAdd" data-tip="Create a new burgs group" class="icon-plus"></button>
|
|
||||||
<button id="burgGroupsEditStyle" data-tip="Open burgs Style setup menu" class="icon-brush"></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="routesOverview" class="dialog stable" style="display: none">
|
<div id="routesOverview" class="dialog stable" style="display: none">
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,16 @@ function editBurgGroups() {
|
||||||
resizable: false,
|
resizable: false,
|
||||||
position: {my: "center", at: "center", of: "svg"},
|
position: {my: "center", at: "center", of: "svg"},
|
||||||
buttons: {
|
buttons: {
|
||||||
Apply: () => byId("burgGroupsForm").requestSubmit(),
|
Apply: () => {
|
||||||
|
byId("burgGroupsForm").requestSubmit();
|
||||||
|
},
|
||||||
|
Add: () => {
|
||||||
|
byId("burgGroupsBody").innerHTML += createLine({name: "", active: true, preview: null});
|
||||||
|
},
|
||||||
|
Restore: () => {
|
||||||
|
options.burgs.groups = Burgs.getDefaultGroups();
|
||||||
|
addLines();
|
||||||
|
},
|
||||||
Cancel: function () {
|
Cancel: function () {
|
||||||
$(this).dialog("close");
|
$(this).dialog("close");
|
||||||
}
|
}
|
||||||
|
|
@ -20,102 +29,91 @@ function editBurgGroups() {
|
||||||
modules.editBurgGroups = true;
|
modules.editBurgGroups = true;
|
||||||
|
|
||||||
// add listeners
|
// add listeners
|
||||||
byId("burgGroupsForm").on("submit", submitForm);
|
byId("burgGroupsForm").on("change", validateForm).on("submit", submitForm);
|
||||||
byId("burgGroupsForm").on("change", validateForm);
|
|
||||||
byId("burgGroupsEditorAdd").on("click", addGroup);
|
|
||||||
byId("burgGroupsEditStyle").on("click", () => editStyle("burgIcons"));
|
|
||||||
byId("burgGroupsBody").on("click", ev => {
|
byId("burgGroupsBody").on("click", ev => {
|
||||||
const group = ev.target.closest(".states")?.dataset.id;
|
const line = ev.target.closest("tr");
|
||||||
if (ev.target.classList.contains("editStyle")) editStyle("burgs", group);
|
if (line && ev.target.classList.contains("removeGroup")) {
|
||||||
else if (ev.target.classList.contains("removeGroup")) removeGroup(group);
|
const lines = byId("burgGroupsBody").children;
|
||||||
|
if (lines.length < 2) return tip("At least one group should be defined", false, "error");
|
||||||
|
|
||||||
|
confirmationDialog({
|
||||||
|
title: this.dataset.tip,
|
||||||
|
message:
|
||||||
|
"Are you sure you want to remove the group? <br>This WON'T change the burgs unless the changes are applied",
|
||||||
|
confirm: "Remove",
|
||||||
|
onConfirm: () => {
|
||||||
|
line.remove();
|
||||||
|
validateForm();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function addLines() {
|
function addLines() {
|
||||||
byId("burgGroupsBody").innerHTML = "";
|
const lines = options.burgs.groups.map(createLine);
|
||||||
|
|
||||||
const lines = options.burgs.groups.map(group => {
|
|
||||||
const count = pack.burgs.filter(burg => !burg.removed && burg.group === group.name).length;
|
|
||||||
// prettier-ignore
|
|
||||||
return /* html */ `<tr name="${group.name}">
|
|
||||||
<td data-tip="Select group to be assigned if other groups are not passed"><input type="radio" name="isDefault" ${group.isDefault && "checked"}></td>
|
|
||||||
<td data-tip="Type group name. It can contain only text, digits and underscore"><input type="text" name="name" value="${group.name}" required pattern="\\w+" /></td>
|
|
||||||
<td data-tip="Set min population constraint"><input type="number" name="min" min="0" step="any" value="${group.min || ''}" /></td>
|
|
||||||
<td data-tip="Set max population constraint"><input type="number" name="max" min="0" step="any" value="${group.max || ''}" /></td>
|
|
||||||
<td data-tip="Set population percentile"><input type="number" name="percentile" min="0" max="100" step="any" value="${group.percentile || ''}" /></td>
|
|
||||||
<td data-tip="Select allowed biomes"><button name="biomes">${group.biomes ? "some" : "all"}</button></td>
|
|
||||||
<td data-tip="Select allowed states"><button name="states">${group.states ? "some" : "all"}</button></td>
|
|
||||||
<td data-tip="Select allowed cultures"><button name="cultures">${group.cultures ? "some" : "all"}</button></td>
|
|
||||||
<td data-tip="Select allowed religions"><button name="religions">${group.religions ? "some" : "all"}</button></td>
|
|
||||||
<td data-tip="Select allowed features" ><button name="features">${group.features ? "some" : "all"}</button></td>
|
|
||||||
<td data-tip="Number of burgs in group">${count}</td>
|
|
||||||
<td data-tip="Activate/deactivate group"><input type="checkbox" name="active" class="native" ${group.active && "checked"} /></td>
|
|
||||||
</tr>`;
|
|
||||||
});
|
|
||||||
|
|
||||||
byId("burgGroupsBody").innerHTML = lines.join("");
|
byId("burgGroupsBody").innerHTML = lines.join("");
|
||||||
}
|
}
|
||||||
|
|
||||||
const DEFAULT_GROUPS = ["roads", "trails", "seaburgs"];
|
function createLine(group) {
|
||||||
|
const count = pack.burgs.filter(burg => !burg.removed && burg.group === group.name).length;
|
||||||
function addGroup() {
|
// prettier-ignore
|
||||||
prompt("Type group name", {default: "burg-group-new"}, v => {
|
return /* html */ `<tr name="${group.name}">
|
||||||
let group = v
|
<td data-tip="Type group name. It can contain only text, digits and underscore"><input type="text" name="name" value="${group.name}" required pattern="\\w+" /></td>
|
||||||
.toLowerCase()
|
<td data-tip="Set min population constraint"><input type="number" name="min" min="0" step="any" value="${group.min || ''}" /></td>
|
||||||
.replace(/ /g, "_")
|
<td data-tip="Set max population constraint"><input type="number" name="max" min="0" step="any" value="${group.max || ''}" /></td>
|
||||||
.replace(/[^\w\s]/gi, "");
|
<td data-tip="Set population percentile"><input type="number" name="percentile" min="0" max="100" step="any" value="${group.percentile || ''}" /></td>
|
||||||
|
<td data-tip="Select allowed biomes"><button type="button" name="biomes">${group.biomes ? "some" : "all"}</button></td>
|
||||||
if (!group) return tip("Invalid group name", false, "error");
|
<td data-tip="Select allowed states"><button type="button" name="states">${group.states ? "some" : "all"}</button></td>
|
||||||
if (!group.startsWith("burg-")) group = "burg-" + group;
|
<td data-tip="Select allowed cultures"><button type="button" name="cultures">${group.cultures ? "some" : "all"}</button></td>
|
||||||
if (byId(group)) return tip("Element with this name already exists. Provide a unique name", false, "error");
|
<td data-tip="Select allowed religions"><button type="button" name="religions">${group.religions ? "some" : "all"}</button></td>
|
||||||
if (Number.isFinite(+group.charAt(0))) return tip("Group name should start with a letter", false, "error");
|
<td data-tip="Select allowed features" ><button type="button" name="features">${group.features ? "some" : "all"}</button></td>
|
||||||
|
<td data-tip="Number of burgs in group">${count}</td>
|
||||||
burgs
|
<td data-tip="Activate/deactivate group"><input type="checkbox" name="active" class="native" ${group.active && "checked"} /></td>
|
||||||
.append("g")
|
<td data-tip="Select group to be assigned if other groups are not passed"><input type="radio" name="isDefault" ${group.isDefault && "checked"}></td>
|
||||||
.attr("id", group)
|
<td data-tip="Remove group"><button type="button" class="icon-trash-empty removeGroup"></button></td>
|
||||||
.attr("stroke", "#000000")
|
</tr>`;
|
||||||
.attr("stroke-width", 0.5)
|
|
||||||
.attr("stroke-dasharray", "1 0.5")
|
|
||||||
.attr("stroke-linecap", "butt");
|
|
||||||
byId("burgGroup")?.options.add(new Option(group, group));
|
|
||||||
addLines();
|
|
||||||
|
|
||||||
byId("burgCreatorGroupSelect").options.add(new Option(group, group));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeGroup(group) {
|
function validateForm() {
|
||||||
confirmationDialog({
|
const form = byId("burgGroupsForm");
|
||||||
title: "Remove burg group",
|
|
||||||
message:
|
|
||||||
"Are you sure you want to remove the entire burg group? All burgs in this group will be removed.<br>This action can't be reverted",
|
|
||||||
confirm: "Remove",
|
|
||||||
onConfirm: () => {
|
|
||||||
pack.burgs.filter(r => r.group === group).forEach(Burgs.remove);
|
|
||||||
if (!DEFAULT_GROUPS.includes(group)) burgs.select(`#${group}`).remove();
|
|
||||||
addLines();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function validateForm(event) {
|
if (form.name.length) {
|
||||||
const form = event.target.form;
|
const names = Array.from(form.name).map(input => input.value);
|
||||||
|
form.name.forEach(nameInput => {
|
||||||
|
const value = nameInput.value;
|
||||||
|
const isUnique = names.filter(n => n === value).length === 1;
|
||||||
|
nameInput.setCustomValidity(isUnique ? "" : "Group name should be unique");
|
||||||
|
nameInput.reportValidity();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const names = Array.from(form.name).map(input => input.value);
|
if (form.active.length) {
|
||||||
form.name.forEach(nameInput => {
|
const active = Array.from(form.active).map(input => input.checked);
|
||||||
const value = nameInput.value;
|
form.active[0].setCustomValidity(active.includes(true) ? "" : "At least one group should be active");
|
||||||
const isUnique = names.filter(n => n === value).length === 1;
|
form.active[0].reportValidity();
|
||||||
nameInput.setCustomValidity(isUnique ? "" : "Group name should be unique");
|
} else {
|
||||||
nameInput.reportValidity();
|
const active = form.active.checked;
|
||||||
});
|
form.active.setCustomValidity(active ? "" : "At least one group should be active");
|
||||||
|
form.active.reportValidity();
|
||||||
|
}
|
||||||
|
|
||||||
const active = Array.from(form.active).map(input => input.checked);
|
if (form.isDefault.length) {
|
||||||
form.active[0].setCustomValidity(active.includes(true) ? "" : "At least one group should be active");
|
const checked = Array.from(form.isDefault).map(input => input.checked);
|
||||||
form.active[0].reportValidity();
|
form.isDefault[0].setCustomValidity(checked.includes(true) ? "" : "At least one group should be default");
|
||||||
|
form.isDefault[0].reportValidity();
|
||||||
|
} else {
|
||||||
|
const checked = form.isDefault.checked;
|
||||||
|
form.isDefault.setCustomValidity(checked ? "" : "At least one group should be default");
|
||||||
|
form.isDefault.reportValidity();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function submitForm(event) {
|
function submitForm(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
|
const lines = Array.from(byId("burgGroupsBody").children);
|
||||||
|
if (!lines.length) return tip("At least one group should be defined", false, "error");
|
||||||
|
|
||||||
function parseInput(input) {
|
function parseInput(input) {
|
||||||
if (input.name === "name") return sanitizeId(input.value);
|
if (input.name === "name") return sanitizeId(input.value);
|
||||||
if (input.type === "radio") return input.checked;
|
if (input.type === "radio") return input.checked;
|
||||||
|
|
@ -128,7 +126,6 @@ function editBurgGroups() {
|
||||||
return input.value;
|
return input.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
const lines = Array.from(byId("burgGroupsBody").children);
|
|
||||||
options.burgs.groups = lines.map(line => {
|
options.burgs.groups = lines.map(line => {
|
||||||
const inputs = line.querySelectorAll("input");
|
const inputs = line.querySelectorAll("input");
|
||||||
const group = Array.from(inputs).reduce((obj, input) => {
|
const group = Array.from(inputs).reduce((obj, input) => {
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,10 @@ const byId = document.getElementById.bind(document);
|
||||||
|
|
||||||
Node.prototype.on = function (name, fn, options) {
|
Node.prototype.on = function (name, fn, options) {
|
||||||
this.addEventListener(name, fn, options);
|
this.addEventListener(name, fn, options);
|
||||||
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
Node.prototype.off = function (name, fn) {
|
Node.prototype.off = function (name, fn) {
|
||||||
this.removeEventListener(name, fn);
|
this.removeEventListener(name, fn);
|
||||||
|
return this;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue