feat: Add new border style options, including single-edge borders, to countdown trackers.

This commit is contained in:
CPTN Cosmo 2025-12-22 00:53:52 +01:00
parent 19fce22ec3
commit dfc84d0626
4 changed files with 103 additions and 2 deletions

View file

@ -1,7 +1,7 @@
{ {
"id": "dh-improved-countdowns", "id": "dh-improved-countdowns",
"title": "Improved Countdowns", "title": "Improved Countdowns",
"version": "1.1.0", "version": "1.2.0",
"compatibility": { "compatibility": {
"minimum": "13", "minimum": "13",
"verified": "13" "verified": "13"
@ -40,5 +40,5 @@
"description": "A modern, draggable countdown tracker for the Daggerheart system.", "description": "A modern, draggable countdown tracker for the Daggerheart system.",
"url": "https://github.com/cptn-cosmo/dh-improved-countdowns", "url": "https://github.com/cptn-cosmo/dh-improved-countdowns",
"manifest": "https://github.com/cptn-cosmo/dh-improved-countdowns/releases/latest/download/module.json", "manifest": "https://github.com/cptn-cosmo/dh-improved-countdowns/releases/latest/download/module.json",
"download": "https://github.com/cptn-cosmo/dh-improved-countdowns/releases/download/1.1.0/dh-improved-countdowns.zip" "download": "https://github.com/cptn-cosmo/dh-improved-countdowns/releases/download/1.2.0/dh-improved-countdowns.zip"
} }

View file

@ -62,6 +62,8 @@ export class CountdownTrackerApp extends HandlebarsApplicationMixin(ApplicationV
const enableVisualBorder = game.settings.get("dh-improved-countdowns", "enableVisualBorder"); const enableVisualBorder = game.settings.get("dh-improved-countdowns", "enableVisualBorder");
const invertBorder = game.settings.get("dh-improved-countdowns", "invertBorder"); const invertBorder = game.settings.get("dh-improved-countdowns", "invertBorder");
const borderColor = game.settings.get("dh-improved-countdowns", "borderColor"); const borderColor = game.settings.get("dh-improved-countdowns", "borderColor");
const borderStyle = game.settings.get("dh-improved-countdowns", "borderStyle");
const borderEdge = game.settings.get("dh-improved-countdowns", "borderEdge");
const gmAlwaysShowNumbers = game.settings.get("dh-improved-countdowns", "gmAlwaysShowNumbers"); const gmAlwaysShowNumbers = game.settings.get("dh-improved-countdowns", "gmAlwaysShowNumbers");
const showNumbers = (isGM && gmAlwaysShowNumbers) || displayMode === "number" || displayMode === "both"; const showNumbers = (isGM && gmAlwaysShowNumbers) || displayMode === "number" || displayMode === "both";
@ -112,6 +114,8 @@ export class CountdownTrackerApp extends HandlebarsApplicationMixin(ApplicationV
enableVisualBorder, enableVisualBorder,
invertBorder, invertBorder,
borderColor, borderColor,
borderStyle,
borderEdge,
invertProgress, invertProgress,
numberColor numberColor
}; };

View file

@ -146,6 +146,36 @@ Hooks.once('init', () => {
onChange: () => CountdownTrackerApp.instance?.render() onChange: () => CountdownTrackerApp.instance?.render()
}); });
game.settings.register("dh-improved-countdowns", "borderStyle", {
name: "Border Style",
hint: "Choose the style of the progress border (for square icons).",
scope: "client",
config: true,
type: String,
choices: {
"full": "Full Border",
"edge": "Single Edge"
},
default: "full",
onChange: () => CountdownTrackerApp.instance?.render()
});
game.settings.register("dh-improved-countdowns", "borderEdge", {
name: "Border Edge",
hint: "Choose which edge to display the border on.",
scope: "client",
config: true,
type: String,
choices: {
"bottom": "Bottom",
"top": "Top",
"left": "Left",
"right": "Right"
},
default: "bottom",
onChange: () => CountdownTrackerApp.instance?.render()
});
game.settings.register("dh-improved-countdowns", "borderColor", { game.settings.register("dh-improved-countdowns", "borderColor", {
name: "Border Color", name: "Border Color",
hint: "Color for the progress border.", hint: "Color for the progress border.",
@ -195,6 +225,8 @@ Hooks.on('renderSettingsConfig', (app, html, data) => {
const fillColorGroup = getGroup("fillColor"); const fillColorGroup = getGroup("fillColor");
const invertBorderGroup = getGroup("invertBorder"); const invertBorderGroup = getGroup("invertBorder");
const borderColorGroup = getGroup("borderColor"); const borderColorGroup = getGroup("borderColor");
const borderStyleGroup = getGroup("borderStyle");
const borderEdgeGroup = getGroup("borderEdge");
const barOrientationGroup = getGroup("barOrientation"); const barOrientationGroup = getGroup("barOrientation");
// Number specific groups // Number specific groups
@ -245,9 +277,19 @@ Hooks.on('renderSettingsConfig', (app, html, data) => {
if (borderEnabled) { if (borderEnabled) {
invertBorderGroup.show(); invertBorderGroup.show();
borderColorGroup.show(); borderColorGroup.show();
borderStyleGroup.show();
const borderStyle = html.find(`[name="${moduleId}.borderStyle"]`).val();
if (borderStyle === "edge") {
borderEdgeGroup.show();
} else {
borderEdgeGroup.hide();
}
} else { } else {
invertBorderGroup.hide(); invertBorderGroup.hide();
borderColorGroup.hide(); borderColorGroup.hide();
borderStyleGroup.hide();
borderEdgeGroup.hide();
} }
} else { } else {
// Hide all visual settings // Hide all visual settings
@ -259,6 +301,8 @@ Hooks.on('renderSettingsConfig', (app, html, data) => {
barOrientationGroup.hide(); barOrientationGroup.hide();
invertBorderGroup.hide(); invertBorderGroup.hide();
borderColorGroup.hide(); borderColorGroup.hide();
borderStyleGroup.hide();
borderEdgeGroup.hide();
} }
}; };
@ -266,6 +310,7 @@ Hooks.on('renderSettingsConfig', (app, html, data) => {
displayModeInput.on("change", updateVisibility); displayModeInput.on("change", updateVisibility);
if (enableOverlayInput.length && enableBorderInput.length) { if (enableOverlayInput.length && enableBorderInput.length) {
html.find(`[name="${moduleId}.fillType"]`).on("change", updateVisibility); html.find(`[name="${moduleId}.fillType"]`).on("change", updateVisibility);
html.find(`[name="${moduleId}.borderStyle"]`).on("change", updateVisibility);
enableOverlayInput.on("change", updateVisibility); enableOverlayInput.on("change", updateVisibility);
enableBorderInput.on("change", updateVisibility); enableBorderInput.on("change", updateVisibility);
updateVisibility(); // Initial check updateVisibility(); // Initial check

View file

@ -105,6 +105,57 @@
style="transition: stroke-dasharray 0.3s ease; opacity: 1;"></circle> style="transition: stroke-dasharray 0.3s ease; opacity: 1;"></circle>
{{/if}} {{/if}}
{{else}} {{else}}
{{#if (eq ../borderStyle "edge")}}
{{#if ../invertBorder}}
{{#if (eq ../borderEdge "bottom")}}
<line x1="1" y1="1" x2="1" y2="47" stroke="{{../borderColor}}" stroke-width="2"
stroke-linecap="round" pathLength="100"
stroke-dasharray="0 {{countdown.percentage}} {{countdown.pctRemaining}} 100"
style="transition: stroke-dasharray 0.3s ease; opacity: 1;">
</line>
{{else if (eq ../borderEdge "top")}}
<line x1="47" y1="1" x2="47" y2="47" stroke="{{../borderColor}}" stroke-width="2"
stroke-linecap="round" pathLength="100"
stroke-dasharray="0 {{countdown.percentage}} {{countdown.pctRemaining}} 100"
style="transition: stroke-dasharray 0.3s ease; opacity: 1;">
</line>
{{else if (eq ../borderEdge "left")}}
<line x1="1" y1="1" x2="47" y2="1" stroke="{{../borderColor}}" stroke-width="2"
stroke-linecap="round" pathLength="100"
stroke-dasharray="0 {{countdown.percentage}} {{countdown.pctRemaining}} 100"
style="transition: stroke-dasharray 0.3s ease; opacity: 1;">
</line>
{{else if (eq ../borderEdge "right")}}
<line x1="1" y1="47" x2="47" y2="47" stroke="{{../borderColor}}" stroke-width="2"
stroke-linecap="round" pathLength="100"
stroke-dasharray="0 {{countdown.percentage}} {{countdown.pctRemaining}} 100"
style="transition: stroke-dasharray 0.3s ease; opacity: 1;">
</line>
{{/if}}
{{else}}
{{#if (eq ../borderEdge "bottom")}}
<line x1="1" y1="1" x2="1" y2="47" stroke="{{../borderColor}}" stroke-width="2"
stroke-linecap="round" pathLength="100" stroke-dasharray="{{countdown.percentage}} 100"
style="transition: stroke-dasharray 0.3s ease; opacity: 1;">
</line>
{{else if (eq ../borderEdge "top")}}
<line x1="47" y1="1" x2="47" y2="47" stroke="{{../borderColor}}" stroke-width="2"
stroke-linecap="round" pathLength="100" stroke-dasharray="{{countdown.percentage}} 100"
style="transition: stroke-dasharray 0.3s ease; opacity: 1;">
</line>
{{else if (eq ../borderEdge "left")}}
<line x1="1" y1="1" x2="47" y2="1" stroke="{{../borderColor}}" stroke-width="2"
stroke-linecap="round" pathLength="100" stroke-dasharray="{{countdown.percentage}} 100"
style="transition: stroke-dasharray 0.3s ease; opacity: 1;">
</line>
{{else if (eq ../borderEdge "right")}}
<line x1="1" y1="47" x2="47" y2="47" stroke="{{../borderColor}}" stroke-width="2"
stroke-linecap="round" pathLength="100" stroke-dasharray="{{countdown.percentage}} 100"
style="transition: stroke-dasharray 0.3s ease; opacity: 1;">
</line>
{{/if}}
{{/if}}
{{else}}
{{#if ../invertBorder}} {{#if ../invertBorder}}
<rect x="1" y="1" width="46" height="46" rx="8" ry="8" fill="none" <rect x="1" y="1" width="46" height="46" rx="8" ry="8" fill="none"
stroke="{{../borderColor}}" stroke-width="2" pathLength="100" stroke="{{../borderColor}}" stroke-width="2" pathLength="100"
@ -119,6 +170,7 @@
style="transition: stroke-dasharray 0.3s ease; opacity: 1;"></rect> style="transition: stroke-dasharray 0.3s ease; opacity: 1;"></rect>
{{/if}} {{/if}}
{{/if}} {{/if}}
{{/if}}
</svg> </svg>
{{/if}} {{/if}}
</div> </div>