diff --git a/scripts/countdown-app.js b/scripts/countdown-app.js
index 48745ca..5357482 100644
--- a/scripts/countdown-app.js
+++ b/scripts/countdown-app.js
@@ -54,12 +54,18 @@ export class CountdownTrackerApp extends HandlebarsApplicationMixin(ApplicationV
const iconShape = game.settings.get("dh-improved-countdowns", "iconShape");
const displayMode = game.settings.get("dh-improved-countdowns", "displayMode");
const barOrientation = game.settings.get("dh-improved-countdowns", "barOrientation");
- const visualColor = game.settings.get("dh-improved-countdowns", "visualColor");
const enableVisualOverlay = game.settings.get("dh-improved-countdowns", "enableVisualOverlay");
+ const fillType = game.settings.get("dh-improved-countdowns", "fillType");
+ const invertProgress = game.settings.get("dh-improved-countdowns", "invertProgress");
+ const numberColor = game.settings.get("dh-improved-countdowns", "numberColor");
+ const fillColor = game.settings.get("dh-improved-countdowns", "fillColor");
const enableVisualBorder = game.settings.get("dh-improved-countdowns", "enableVisualBorder");
+ const invertBorder = game.settings.get("dh-improved-countdowns", "invertBorder");
+ const borderColor = game.settings.get("dh-improved-countdowns", "borderColor");
const gmAlwaysShowNumbers = game.settings.get("dh-improved-countdowns", "gmAlwaysShowNumbers");
- const showNumbers = (isGM && gmAlwaysShowNumbers) || displayMode === "number";
+ const showNumbers = (isGM && gmAlwaysShowNumbers) || displayMode === "number" || displayMode === "both";
+ const showVisuals = displayMode === "visual" || displayMode === "both";
// Fetch countdowns from system settings
const systemCountdownSetting = game.settings.get("daggerheart", "Countdowns");
@@ -71,12 +77,20 @@ export class CountdownTrackerApp extends HandlebarsApplicationMixin(ApplicationV
if (ownership !== CONST.DOCUMENT_OWNERSHIP_LEVELS.NONE) {
const current = countdown.progress.current;
const max = countdown.progress.start;
- const percentage = Math.max(0, Math.min(100, (current / max) * 100));
+ let percentage = Math.max(0, Math.min(100, (current / max) * 100));
+ const pctRemaining = 100 - percentage;
+
+ /*
+ if (invertProgress) {
+ // We handle inversion in template now to preserve position
+ }
+ */
countdowns[id] = {
...countdown,
editable: isGM || ownership === CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER,
percentage,
+ pctRemaining,
cssClass: `shape-${iconShape}`
};
}
@@ -89,11 +103,17 @@ export class CountdownTrackerApp extends HandlebarsApplicationMixin(ApplicationV
isMinimized,
isLocked,
showNumbers,
+ showVisuals,
iconShape,
barOrientation,
- visualColor,
enableVisualOverlay,
- enableVisualBorder
+ fillType,
+ fillColor,
+ enableVisualBorder,
+ invertBorder,
+ borderColor,
+ invertProgress,
+ numberColor
};
}
@@ -130,13 +150,13 @@ export class CountdownTrackerApp extends HandlebarsApplicationMixin(ApplicationV
static async #onToggleView(event, target) {
const current = game.settings.get("dh-improved-countdowns", "minimized");
await game.settings.set("dh-improved-countdowns", "minimized", !current);
- this.instance.render();
+ CountdownTrackerApp.instance?.render();
}
static async #onToggleLock(event, target) {
const current = game.settings.get("dh-improved-countdowns", "locked");
await game.settings.set("dh-improved-countdowns", "locked", !current);
- this.instance.render();
+ CountdownTrackerApp.instance?.render();
}
_onRender(context, options) {
diff --git a/scripts/module.js b/scripts/module.js
index c36b4ab..50bb41f 100644
--- a/scripts/module.js
+++ b/scripts/module.js
@@ -14,7 +14,7 @@ Hooks.once('init', () => {
name: "Lock Tracker Position",
hint: "Prevents the countdown tracker from being dragged.",
scope: "client",
- config: true,
+ config: false, // Hidden from settings menu, toggled via UI
type: Boolean,
default: false,
onChange: () => CountdownTrackerApp.instance?.render()
@@ -29,6 +29,21 @@ Hooks.once('init', () => {
onChange: () => CountdownTrackerApp.instance?.render()
});
+ game.settings.register("dh-improved-countdowns", "displayMode", {
+ name: "Display Mode",
+ hint: "Choose how the countdown value is displayed.",
+ scope: "world",
+ config: true,
+ type: String,
+ choices: {
+ "number": "Number Only",
+ "visual": "Visual Only",
+ "both": "Visual + Number"
+ },
+ default: "number",
+ onChange: () => CountdownTrackerApp.instance?.render()
+ });
+
game.settings.register("dh-improved-countdowns", "iconShape", {
name: "Icon Shape",
hint: "Choose the shape of the countdown icons.",
@@ -43,17 +58,13 @@ Hooks.once('init', () => {
onChange: () => CountdownTrackerApp.instance?.render()
});
- game.settings.register("dh-improved-countdowns", "displayMode", {
- name: "Display Mode",
- hint: "Choose how the countdown value is displayed.",
- scope: "world",
+ game.settings.register("dh-improved-countdowns", "numberColor", {
+ name: "Number Color",
+ hint: "Color for the numerical text.",
+ scope: "client",
config: true,
type: String,
- choices: {
- "number": "Number",
- "visual": "Visual (Bar/Clock)"
- },
- default: "number",
+ default: "#ffffff",
onChange: () => CountdownTrackerApp.instance?.render()
});
@@ -71,16 +82,6 @@ Hooks.once('init', () => {
onChange: () => CountdownTrackerApp.instance?.render()
});
- game.settings.register("dh-improved-countdowns", "visualColor", {
- name: "Visual Color",
- hint: "Choose the color for the progress overlay and border.",
- scope: "client",
- config: true,
- type: String,
- default: "#ffffff",
- onChange: () => CountdownTrackerApp.instance?.render()
- });
-
game.settings.register("dh-improved-countdowns", "enableVisualOverlay", {
name: "Enable Fill Overlay",
hint: "Show the filled progress overlay (Bar or Clock).",
@@ -91,6 +92,40 @@ Hooks.once('init', () => {
onChange: () => CountdownTrackerApp.instance?.render()
});
+ game.settings.register("dh-improved-countdowns", "fillType", {
+ name: "Fill Type",
+ hint: "Choose between a color overlay or a grayscale filter method.",
+ scope: "client",
+ config: true,
+ type: String,
+ choices: {
+ "color": "Color Overlay",
+ "grayscale": "Grayscale Filter"
+ },
+ default: "color",
+ onChange: () => CountdownTrackerApp.instance?.render()
+ });
+
+ game.settings.register("dh-improved-countdowns", "invertProgress", {
+ name: "Invert Fill Overlay",
+ hint: "Fill the empty space instead of the current value.",
+ scope: "client",
+ config: true,
+ type: Boolean,
+ default: false,
+ onChange: () => CountdownTrackerApp.instance?.render()
+ });
+
+ game.settings.register("dh-improved-countdowns", "fillColor", {
+ name: "Fill Overlay Color",
+ hint: "Color for the filled progress overlay.",
+ scope: "client",
+ config: true,
+ type: String,
+ default: "#ffffff",
+ onChange: () => CountdownTrackerApp.instance?.render()
+ });
+
game.settings.register("dh-improved-countdowns", "enableVisualBorder", {
name: "Enable Border Progress",
hint: "Show a progress border around the icon.",
@@ -101,6 +136,26 @@ Hooks.once('init', () => {
onChange: () => CountdownTrackerApp.instance?.render()
});
+ game.settings.register("dh-improved-countdowns", "invertBorder", {
+ name: "Invert Border Progress",
+ hint: "Fill the empty space instead of the current value for the border.",
+ scope: "client",
+ config: true,
+ type: Boolean,
+ default: false,
+ onChange: () => CountdownTrackerApp.instance?.render()
+ });
+
+ game.settings.register("dh-improved-countdowns", "borderColor", {
+ name: "Border Color",
+ hint: "Color for the progress border.",
+ scope: "client",
+ config: true,
+ type: String,
+ default: "#ffffff",
+ onChange: () => CountdownTrackerApp.instance?.render()
+ });
+
game.settings.register("dh-improved-countdowns", "gmAlwaysShowNumbers", {
name: "GM Always Shows Numbers",
hint: "If enabled, the GM will always see the numerical value even if Display Mode is set to Visual.",
@@ -112,6 +167,111 @@ Hooks.once('init', () => {
});
});
+Hooks.on('renderSettingsConfig', (app, html, data) => {
+ // Ensure html is a jQuery object
+ html = $(html);
+
+ const moduleId = "dh-improved-countdowns";
+ console.log("Improved Countdowns | Settings Config Rendered");
+
+ // Helper to find the form group for a setting
+ const getGroup = (settingName) => {
+ const input = html.find(`[name="${moduleId}.${settingName}"]`);
+ const group = input.closest(".form-group");
+ if (!group.length) console.warn(`Improved Countdowns | Could not find form group for ${settingName}`);
+ return group;
+ };
+
+ const enableOverlayInput = html.find(`[name="${moduleId}.enableVisualOverlay"]`);
+ const enableBorderInput = html.find(`[name="${moduleId}.enableVisualBorder"]`);
+ const displayModeInput = html.find(`[name="${moduleId}.displayMode"]`);
+
+ // Debug findings
+ if (!enableOverlayInput.length) console.warn("Improved Countdowns | Enable Overlay Input not found");
+ // if (!displayModeInput.length) console.warn("Improved Countdowns | Display Mode Input not found");
+
+ const fillTypeGroup = getGroup("fillType");
+ const invertProgressGroup = getGroup("invertProgress");
+ const fillColorGroup = getGroup("fillColor");
+ const invertBorderGroup = getGroup("invertBorder");
+ const borderColorGroup = getGroup("borderColor");
+ const barOrientationGroup = getGroup("barOrientation");
+
+ // Number specific groups
+ const numberColorGroup = getGroup("numberColor");
+ // Visual specific groups - we already have them above
+ const enableOverlayGroup = getGroup("enableVisualOverlay");
+ const enableBorderGroup = getGroup("enableVisualBorder");
+
+ const updateVisibility = () => {
+ const displayMode = displayModeInput.val();
+ const showVisualSettings = displayMode === "visual" || displayMode === "both";
+ const showNumberSettings = displayMode === "number" || displayMode === "both";
+
+ // Number Settings Visibility
+ if (showNumberSettings) {
+ numberColorGroup.show();
+ } else {
+ numberColorGroup.hide();
+ }
+
+ // Visual Settings Visibility
+ if (showVisualSettings) {
+ enableOverlayGroup.show();
+ enableBorderGroup.show();
+
+ // Nested visual settings logic
+ const overlayEnabled = enableOverlayInput.prop("checked");
+ const borderEnabled = enableBorderInput.prop("checked");
+ const fillType = html.find(`[name="${moduleId}.fillType"]`).val();
+
+ if (overlayEnabled) {
+ fillTypeGroup.show();
+ invertProgressGroup.show();
+ barOrientationGroup.show();
+
+ if (fillType === "grayscale") {
+ fillColorGroup.hide();
+ } else {
+ fillColorGroup.show();
+ }
+ } else {
+ fillTypeGroup.hide();
+ invertProgressGroup.hide();
+ fillColorGroup.hide();
+ barOrientationGroup.hide();
+ }
+
+ if (borderEnabled) {
+ invertBorderGroup.show();
+ borderColorGroup.show();
+ } else {
+ invertBorderGroup.hide();
+ borderColorGroup.hide();
+ }
+ } else {
+ // Hide all visual settings
+ enableOverlayGroup.hide();
+ enableBorderGroup.hide();
+ fillTypeGroup.hide();
+ invertProgressGroup.hide();
+ fillColorGroup.hide();
+ barOrientationGroup.hide();
+ invertBorderGroup.hide();
+ borderColorGroup.hide();
+ }
+ };
+
+ // Listeners
+ displayModeInput.on("change", updateVisibility);
+ if (enableOverlayInput.length && enableBorderInput.length) {
+ html.find(`[name="${moduleId}.fillType"]`).on("change", updateVisibility);
+ enableOverlayInput.on("change", updateVisibility);
+ enableBorderInput.on("change", updateVisibility);
+ updateVisibility(); // Initial check
+ }
+});
+
Hooks.once('ready', () => {
// Hide default countdown tracker via CSS (handled in countdown.css)
diff --git a/styles/countdown.css b/styles/countdown.css
index 118a6b8..b455568 100644
--- a/styles/countdown.css
+++ b/styles/countdown.css
@@ -214,6 +214,14 @@
/* Rotation handled inline to start at top */
}
+/* Grayscale Filter */
+.grayscale-filter {
+ backdrop-filter: grayscale(100%) !important;
+ background: transparent !important;
+ opacity: 1 !important;
+ box-shadow: none !important;
+}
+
.bar-visual.vertical {
width: 100%;
/* height is set inline */
diff --git a/templates/countdown-tracker.hbs b/templates/countdown-tracker.hbs
index 57dfb98..88a8f1d 100644
--- a/templates/countdown-tracker.hbs
+++ b/templates/countdown-tracker.hbs
@@ -38,41 +38,98 @@
../isMinimized}}data-tooltip="{{countdown.name}}" {{/if}}>
- {{#if ../showNumbers}}
-