Skip to content

Commit

Permalink
Add Style Settings V2
Browse files Browse the repository at this point in the history
  • Loading branch information
mclemente committed May 28, 2024
1 parent 2f88391 commit 364a543
Show file tree
Hide file tree
Showing 7 changed files with 244 additions and 191 deletions.
2 changes: 1 addition & 1 deletion src/module.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@
"license": "https://choosealicense.com/licenses/mit/",
"bugs": "https://github.com/mclemente/healthEstimate/issues",
"compatibility": {
"minimum": "11",
"minimum": "12",
"verified": "12"
}
}
170 changes: 98 additions & 72 deletions src/module/forms/StyleSettings.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,36 @@
import { sGet, sSet, t } from "../utils.js";
import { HealthEstimateSettings } from "./templates/Base.js";

export default class HealthEstimateStyleSettings extends HealthEstimateSettings {
constructor(object, options = {}) {
super(object, options);
this.path = "core.menuSettings";
this.gradColors = [];
Hooks.once("renderHealthEstimateStyleSettings", this.initHooks.bind(this));
Hooks.once("closeHealthEstimateStyleSettings", () => {
delete this.gp;
});
}
import { HealthEstimateSettingsV2 } from "./templates/BaseV2.js";

export default class HealthEstimateStyleSettings extends HealthEstimateSettingsV2 {
gradColors = [];

path = "core.menuSettings";

static DEFAULT_OPTIONS = {
actions: {
reset: HealthEstimateStyleSettings.reset,
},
form: {
handler: HealthEstimateStyleSettings.#onSubmit,
},
window: {
icon: "fas fa-palette",
},
};

static get defaultOptions() {
return mergeObject(super.defaultOptions, {
static PARTS = {
form: {
id: "health-estimate-style-form",
title: `Health Estimate: ${t("core.menuSettings.styleSettings.plural")}`,
template: "./modules/healthEstimate/templates/styleSettings.hbs",
});
},
...HealthEstimateSettingsV2.PARTS,
};

get title() {
return `Health Estimate: ${t("core.menuSettings.styleSettings.plural")}`;
}

getData(options) {
_prepareContext(options) {
return {
fontFamily: this.prepSelection("fontFamily"),
useColor: this.prepSetting("useColor"),
Expand All @@ -35,31 +45,38 @@ export default class HealthEstimateStyleSettings extends HealthEstimateSettings
scaleToGridSize: this.prepSetting("scaleToGridSize"),
scaleToZoom: this.prepSetting("scaleToZoom"),
deadText: game.settings.get("healthEstimate", "core.deathStateName"),
...HealthEstimateSettingsV2.BUTTONS,
};
}

initHooks() {
_onRender(context, options) {
const gradientPositions = game.settings.get("healthEstimate", "core.menuSettings.gradient");
const mode = document.getElementById("mode");
const useColorCheckbox = document.querySelector('input[name="useColor"]');
const mode = this.element.querySelector("#mode");
const useColorCheckbox = this.element.querySelector('input[name="useColor"]');

this.fontFamily = document.getElementById("fontFamily");
this.fontFamily = this.element.querySelector("#fontFamily");
this.useColor = sGet("core.menuSettings.useColor");

const deadColor = document.querySelector("input[name=deadColor]");
this.deadColor = document.querySelector("input[data-edit=deadColor]");
this.deadColor = this.element.querySelector("color-picker[name=deadColor]");
this.deadOutline = sGet("core.variables.deadOutline");

this.outlineMode = document.getElementById("outlineMode");
this.outlineIntensity = document.getElementById("outlineIntensity");
this.fontSize = document.getElementById("fontSize");
this.textPosition = document.getElementById("position");
this.smoothGradient = document.getElementById("smoothGradient");
this.gradEx = document.getElementById("gradientExampleHE");
this.outlineMode = this.element.querySelector("#outlineMode");
this.outlineIntensity = this.element.querySelector("input[name=outlineIntensity]");
this.fontSize = this.element.querySelector("input[name=fontSize]");
this.textPosition = this.element.querySelector("input[name=position]");
this.smoothGradient = this.element.querySelector("#smoothGradient");
this.gradEx = this.element.querySelector("#gradientExampleHE");

this.fontSize.value = Number.isNumeric(this.fontSize.value) ? this.fontSize.value : 24;
this.textPosition.value = Number.isNumeric(this.textPosition.value) ? this.textPosition.value : 0;

const gradientForm = this.element.querySelector('div[class="form-group gradient"]');

this.hideForm(this.smoothGradient.parentElement, this.useColor);
this.hideForm(gradientForm, this.useColor);
this.hideForm(this.deadColor.parentElement, this.useColor);
this.hideForm(this.outlineMode.parentElement, this.useColor);

this.gp = new Grapick({
el: "#gradientControlsHE",
colorEl: '<input id="colorpicker"/>',
Expand All @@ -82,18 +99,25 @@ export default class HealthEstimateStyleSettings extends HealthEstimateSettings
this.updateGradientFunction();
});

for (let el of [deadColor, this.deadColor]) {
el.addEventListener("change", (ev) => {
this.deadOutline = this.outlFn(ev.target.value);
this.deadColor.value = ev.target.value;
this.updateSample();
});
}
this.deadColor.addEventListener("change", (ev) => {
this.deadOutline = this.outlFn(ev.target.value);
// this.deadColor.value = ev.target.value;
this.updateSample();
});
useColorCheckbox.addEventListener("change", (ev) => {
this.useColor = !this.useColor;
this.updateSample();
this.hideForm(this.smoothGradient.parentElement, ev.target.checked);
this.hideForm(gradientForm, ev.target.checked);
this.hideForm(this.deadColor.parentElement, ev.target.checked);
this.hideForm(this.outlineMode.parentElement, ev.target.checked);
});

for (const range of this.element.querySelectorAll("input[type=range]")) {
range.addEventListener("change", (event) => {
range.nextElementSibling.innerHTML = event.target.value;
});
}
this.gp.on("change", (complete) => {
this.updateGradient();
});
Expand All @@ -113,14 +137,18 @@ export default class HealthEstimateStyleSettings extends HealthEstimateSettings
}
}

hideForm(form, boolean) {
form.style.display = !boolean ? "none" : "flex";
}

async setHandlers(positions) {
for (let [i, v] of positions.colors.entries()) {
this.gp.addHandler(positions.positions[i] * 100, v);
}
}

updateGradientFunction() {
const mode = document.getElementById("mode").value;
const mode = this.element.querySelector("#mode").value;
/**
*
* @param {Number} amount
Expand Down Expand Up @@ -173,9 +201,9 @@ export default class HealthEstimateStyleSettings extends HealthEstimateSettings
}

updateSample() {
const sample = document.getElementById("healthEstimateSample");
const sampleAnimation = document.getElementById("SampleAnimation");
const deadSample = document.getElementById("healthEstimateSample").children[0];
const sample = this.element.querySelector("#healthEstimateSample");
const sampleAnimation = this.element.querySelector("#SampleAnimation");
const deadSample = this.element.querySelector("#healthEstimateSample").children[0];
const deadColor = this.useColor ? this.deadColor.value : "#FFF";
const deadOutline = this.useColor ? this.deadOutline : "#000";
sample.style.fontFamily = this.fontFamily.value;
Expand Down Expand Up @@ -217,58 +245,56 @@ export default class HealthEstimateStyleSettings extends HealthEstimateSettings
}
}

async activateListeners(html) {
super.activateListeners(html);
html.find("button[name=reset]").on("click", async (event) => {
const paths = [
"menuSettings.useColor",
"menuSettings.smoothGradient",
"menuSettings.deadColor",
"menuSettings.fontSize",
"menuSettings.position",
"menuSettings.position2",
"menuSettings.mode",
"menuSettings.outline",
"menuSettings.outlineIntensity",
"menuSettings.scaleToGridSize",
"menuSettings.scaleToZoom",
"variables.colors",
"variables.outline",
"variables.deadColor",
"variables.deadOutline",
];
await Promise.all(paths.map(this.resetToDefault));
this.close();
});
static async reset() {
const paths = [
"menuSettings.useColor",
"menuSettings.smoothGradient",
"menuSettings.deadColor",
"menuSettings.fontSize",
"menuSettings.position",
"menuSettings.position2",
"menuSettings.mode",
"menuSettings.outline",
"menuSettings.outlineIntensity",
"menuSettings.scaleToGridSize",
"menuSettings.scaleToZoom",
"variables.colors",
"variables.outline",
"variables.deadColor",
"variables.deadOutline",
];
await Promise.all(paths.map(this.resetToDefault));
this.close();
}

async close(options = {}) {
this.clearKeyframes();
// delete this.gp;
super.close(options);
}

async _updateObject(event, formData) {
if (event.type !== "submit") return;
const menuSettingsKeys = Object.keys(formData).filter((key) => key.indexOf("outline") === -1);
const updates = menuSettingsKeys.map((key) => sSet(`core.menuSettings.${key}`, formData[key]));
static async #onSubmit(event, form, formData) {
const settings = foundry.utils.expandObject(formData.object);
const menuSettingsKeys = Object.keys(settings).filter((key) => key.indexOf("outline") === -1);
const updates = menuSettingsKeys.map((key) => sSet(`core.menuSettings.${key}`, settings[key]));
await Promise.all(updates);

if (!formData.useColor) {
if (!settings.useColor) {
this.gradColors = ["#FFF"];
this.outlColors = ["#000"];
this.deadOutline = "#000";
formData.deadColor = "#FFF";
settings.deadColor = "#FFF";
}
const variableUpdates = [
sSet("core.menuSettings.gradient", {
colors: this.gp.handlers.map((a) => a.color),
positions: this.gp.handlers.map((a) => Math.round(a.position) / 100),
}),
sSet("core.menuSettings.outline", formData.outlineMode),
sSet("core.menuSettings.outlineIntensity", formData.outlineIntensity),
sSet("core.menuSettings.outline", settings.outlineMode),
sSet("core.menuSettings.outlineIntensity", settings.outlineIntensity),
sSet("core.variables.colors", this.gradColors),
sSet("core.variables.outline", this.outlColors),
sSet("core.variables.deadColor", formData.deadColor),
sSet("core.variables.deadColor", settings.deadColor),
sSet("core.variables.deadOutline", this.deadOutline),
];
await Promise.all(variableUpdates);
Expand Down
83 changes: 83 additions & 0 deletions src/module/forms/templates/BaseV2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { settingData, sGet, sSet } from "../../utils.js";

const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;

export class HealthEstimateSettingsV2 extends HandlebarsApplicationMixin(ApplicationV2) {
path = "core";

static DEFAULT_OPTIONS = {
classes: ["form", "healthEstimate"],
position: {
width: 640,
height: "auto",
},
form: {
closeOnSubmit: true,
},
tag: "form",
window: {
contentClasses: ["standard-form"],
},
};

static PARTS = {
footer: {
template: "templates/generic/form-footer.hbs",
},
};

static BUTTONS = {
buttons: [
{ type: "submit", icon: "fa-solid fa-save", label: "SETTINGS.Save" },
{ type: "reset", action: "reset", icon: "fa-solid fa-undo", label: "SETTINGS.Reset" },
],
};

_initializeApplicationOptions(options) {
options = super._initializeApplicationOptions(options);
options.uniqueId = `${this.constructor.name}`;
return options;
}

prepSelection(key) {
const path = `${this.path}.${key}`;
const data = settingData(path);
const { name, hint } = data;
const selected = sGet(path);
const select = Object.entries(data.choices).map(([key, value]) => ({ key, value }));
return { select, name, hint, selected };
}

prepSetting(key) {
const path = `${this.path}.${key}`;
const { name, hint } = settingData(path);
return {
value: sGet(path),
name,
hint,
};
}

async resetToDefault(key) {
const path = `core.${key}`;
const defaultValue = game.settings.settings.get(`healthEstimate.${path}`).default;
await game.settings.set("healthEstimate", path, defaultValue);
if (game.healthEstimate.alwaysShow) canvas.scene?.tokens.forEach((token) => token.object.refresh());
}

/**
* Executes on form submission
* @param {Event} event - the form submission event
* @param {Object} formData - the form data
*/
async _updateObject(event, formData) {
await Promise.all(
Object.entries(formData).map(async ([key, value]) => {
let current = game.settings.get("healthEstimate", `core.${key}`);
// eslint-disable-next-line eqeqeq
if (value != current) await sSet(`core.${key}`, value);
})
);
if (game.healthEstimate.alwaysShow) canvas.scene?.tokens.forEach((token) => token.object.refresh());
}
}
1 change: 0 additions & 1 deletion src/module/healthEstimate.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ Hooks.on("deleteActiveEffect", HealthEstimateHooks.deleteActiveEffect);
// Rendering
Hooks.on("renderChatMessage", HealthEstimateHooks.onRenderChatMessage);
Hooks.on("renderSettingsConfig", HealthEstimateHooks.renderSettingsConfigHandler);
Hooks.on("renderHealthEstimateStyleSettings", HealthEstimateHooks.renderHealthEstimateStyleSettingsHandler);
Hooks.on("renderTokenConfig", HealthEstimateHooks.renderTokenConfigHandler);

function setKeybinds() {
Expand Down
25 changes: 0 additions & 25 deletions src/module/hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -208,31 +208,6 @@ export class HealthEstimateHooks {
}
}

static renderHealthEstimateStyleSettingsHandler(settingsConfig, html) {
const useColor = game.settings.get("healthEstimate", "core.menuSettings.useColor");
const useColorCheckbox = html.find('input[name="useColor"]');
const smoothGradientForm = html.find('input[name="smoothGradient"]').parent()[0];
const gradientForm = html.find('div[class="form-group gradient"]')[0];
const deadColorForm = html.find('input[name="deadColor"]').parent()[0];
const outlineModeForm = html.find('select[id="outlineMode"]').parent()[0];

function hideForm(form, boolean) {
form.style.display = !boolean ? "none" : "flex";
}

hideForm(smoothGradientForm, useColor);
hideForm(gradientForm, useColor);
hideForm(deadColorForm, useColor);
hideForm(outlineModeForm, useColor);

useColorCheckbox.on("change", (event) => {
hideForm(smoothGradientForm, event.target.checked);
hideForm(gradientForm, event.target.checked);
hideForm(deadColorForm, event.target.checked);
hideForm(outlineModeForm, event.target.checked);
});
}

/**
* Handler called when token configuration window is opened. Injects custom form html and deals
* with updating token.
Expand Down
Loading

0 comments on commit 364a543

Please sign in to comment.