feat: Improve robustness of settings panel dynamic visibility and scale reset button injection by using a dedicated group finder and more flexible element targeting.

This commit is contained in:
CPTN Cosmo 2025-12-19 01:55:06 +01:00
parent 409528b30d
commit 52929e9cdb

View file

@ -128,85 +128,101 @@ Hooks.once('init', () => {
*/ */
Hooks.on('renderSettingsConfig', (app, html, data) => { Hooks.on('renderSettingsConfig', (app, html, data) => {
const $html = $(html); const $html = $(html);
// Use a more robust selector for the select elements, in case implicit binding changes
const iconTypeSelect = $html.find(`select[name="${MODULE_ID}.iconType"]`); const iconTypeSelect = $html.find(`select[name="${MODULE_ID}.iconType"]`);
const themeSelect = $html.find(`select[name="${MODULE_ID}.colorTheme"]`); const themeSelect = $html.find(`select[name="${MODULE_ID}.colorTheme"]`);
const updateVisibility = () => { // If we can't find the main selects, we can't do anything (likely custom settings window or other issue)
const iconType = iconTypeSelect.val(); if (!iconTypeSelect.length || !themeSelect.length) return;
const theme = themeSelect.val();
// Icon Inputs {
// Standard data-setting-id // Helper to find setting group
let presetGroup = $html.find(`.form-group[data-setting-id="${MODULE_ID}.presetIcon"]`); const findGroup = (key) => {
let customIconGroup = $html.find(`.form-group[data-setting-id="${MODULE_ID}.customIcon"]`); // Try data-setting-id first (standard in V10/V11+)
let customSvgGroup = $html.find(`.form-group[data-setting-id="${MODULE_ID}.customSvgPath"]`); let group = $html.find(`.form-group[data-setting-id="${MODULE_ID}.${key}"]`);
if (group.length) return group;
// Fallback: Find input by name and traverse to form-group // Fallback: Find input/select by name and go up to form-group
if (!presetGroup.length) presetGroup = $html.find(`select[name="${MODULE_ID}.presetIcon"]`).closest('.form-group'); const input = $html.find(`[name="${MODULE_ID}.${key}"]`);
if (!customIconGroup.length) customIconGroup = $html.find(`input[name="${MODULE_ID}.customIcon"]`).closest('.form-group'); if (input.length) return input.closest('.form-group');
// SVG Fallback: Ensure we find it separately because it might be wrapped differently return null;
if (!customSvgGroup.length) { };
const svgInput = $html.find(`input[name="${MODULE_ID}.customSvgPath"]`);
// Traverse up to find the closest form-group
customSvgGroup = svgInput.closest('.form-group');
}
// Reset const updateVisibility = () => {
presetGroup.hide(); const iconType = iconTypeSelect.val();
customIconGroup.hide(); const theme = themeSelect.val();
customSvgGroup.hide();
if (iconType === 'preset') { // Locate Groups
presetGroup.show(); const presetGroup = findGroup('presetIcon');
} else if (iconType === 'custom') { const customIconGroup = findGroup('customIcon');
customIconGroup.show(); const customSvgGroup = findGroup('customSvgPath');
} else if (iconType === 'custom-svg') {
customSvgGroup.show();
}
// Color Inputs // Reset Visibility
let fullColorGroup = $html.find(`.form-group[data-setting-id="${MODULE_ID}.fullColor"]`); if (presetGroup) presetGroup.hide();
let emptyColorGroup = $html.find(`.form-group[data-setting-id="${MODULE_ID}.emptyColor"]`); if (customIconGroup) customIconGroup.hide();
let scaleGroup = $html.find(`.form-group[data-setting-id="${MODULE_ID}.trackerScale"]`); if (customSvgGroup) customSvgGroup.hide();
if (!fullColorGroup.length) fullColorGroup = $html.find(`input[name="${MODULE_ID}.fullColor"]`).closest('.form-group'); // Apply Logic
if (!emptyColorGroup.length) emptyColorGroup = $html.find(`input[name="${MODULE_ID}.emptyColor"]`).closest('.form-group'); if (iconType === 'preset' && presetGroup) {
if (!scaleGroup.length) scaleGroup = $html.find(`input[name="${MODULE_ID}.trackerScale"]`).closest('.form-group'); presetGroup.show();
} else if (iconType === 'custom' && customIconGroup) {
customIconGroup.show();
} else if (iconType === 'custom-svg' && customSvgGroup) {
customSvgGroup.show();
}
if (theme === 'custom') { // Color Inputs
fullColorGroup.show(); const fullColorGroup = findGroup('fullColor');
emptyColorGroup.show(); const emptyColorGroup = findGroup('emptyColor');
} else {
fullColorGroup.hide();
emptyColorGroup.hide();
}
// Inject Scale Reset Button if not present if (fullColorGroup && emptyColorGroup) {
if (scaleGroup.length && !scaleGroup.find('.scale-reset-btn').length) { if (theme === 'custom') {
const input = scaleGroup.find('input[type="range"]'); fullColorGroup.show();
const rangeValue = scaleGroup.find('.range-value'); emptyColorGroup.show();
if (input.length) {
const resetBtn = $(`<button type="button" class="scale-reset-btn" title="Reset to 1.0x" style="flex: 0 0 30px; margin-left: 5px;"><i class="fas fa-undo"></i></button>`);
resetBtn.on('click', () => {
input.val(1.0).trigger('change');
if (rangeValue.length) rangeValue.text("1.0");
});
// Append after the range value display usually found in Foundry sliders
if (rangeValue.length) {
rangeValue.after(resetBtn);
} else { } else {
input.after(resetBtn); fullColorGroup.hide();
emptyColorGroup.hide();
} }
} }
}
};
iconTypeSelect.on('change', updateVisibility); // Tracker Scale Reset Button
themeSelect.on('change', updateVisibility); const scaleGroup = findGroup('trackerScale');
updateVisibility(); if (scaleGroup && !scaleGroup.find('.scale-reset-btn').length) {
const input = scaleGroup.find('input[type="range"]'); // Try range first
const numberInput = scaleGroup.find(`input[name="${MODULE_ID}.trackerScale"]`); // Fallback/Number input
const rangeValue = scaleGroup.find('.range-value');
// We want to control the input that actually stores the value
const targetInput = numberInput.length ? numberInput : input;
if (targetInput.length) {
const resetBtn = $(`<button type="button" class="scale-reset-btn" title="Reset to 1.0x" style="flex: 0 0 30px; margin-left: 5px;"><i class="fas fa-undo"></i></button>`);
resetBtn.on('click', () => {
targetInput.val(1.0).trigger('change');
// Retrieve the range input again to update it visually if we targeted the number input
if (input.length) input.val(1.0);
if (rangeValue.length) rangeValue.text("1.0");
});
// Append logic
const container = scaleGroup.find('.form-fields');
if (container.length) {
container.append(resetBtn);
} else if (rangeValue.length) {
rangeValue.after(resetBtn);
} else {
targetInput.after(resetBtn);
}
}
}
};
iconTypeSelect.on('change', updateVisibility);
themeSelect.on('change', updateVisibility);
updateVisibility();
}
}); });
/** /**