import { toggleTemplateOnSelected } from '../scripts/hooks/effectMappingHooks.js'; import { CORE_TEMPLATES } from '../scripts/mappingTemplates.js'; import { TVA_CONFIG, updateSettings } from '../scripts/settings.js'; import { BASE_IMAGE_CATEGORIES, uploadTokenImage } from '../scripts/utils.js'; import { sortMappingsToGroups } from './effectMappingForm.js'; import { Templates } from './templates.js'; import TokenCustomConfig from './tokenCustomConfig.js'; // Edit overlay configuration as a json string export function showOverlayJsonConfigDialog(overlayConfig, callback) { const config = deepClone(overlayConfig || {}); delete config.effect; let content = `
`; new Dialog({ title: `Overlay Configuration`, content: content, buttons: { yes: { icon: "", label: 'Save', callback: (html) => { let json = $(html).find('.configJson').val(); if (json) { try { json = JSON.parse(json); } catch (e) { console.warn(`TVA |`, e); json = {}; } } else { json = {}; } callback(json); }, }, }, default: 'yes', }).render(true); } // Change categories assigned to a path export async function showPathSelectCategoryDialog(event) { event.preventDefault(); const typesInput = $(event.target).closest('.path-category').find('input'); const selectedTypes = typesInput.val().split(','); const categories = BASE_IMAGE_CATEGORIES.concat(TVA_CONFIG.customImageCategories); let content = '
'; // Split into rows of 4 const splits = []; let currSplit = []; for (let i = 0; i < categories.length; i++) { if (i > 0 && i + 1 != categories.length && i % 4 == 0) { splits.push(currSplit); currSplit = []; } currSplit.push(categories[i]); } if (currSplit.length) splits.push(currSplit); for (const split of splits) { content += '
'; for (const type of split) { content += ``; } content += '
'; } content += '
'; new Dialog({ title: `Image Categories/Filters`, content: content, buttons: { yes: { icon: "", label: 'Apply', callback: (html) => { const types = []; $(html) .find('.category') .each(function () { if ($(this).is(':checked')) { types.push($(this).attr('name')); } }); typesInput.val(types.join(',')); }, }, }, default: 'yes', }).render(true); } // Change configs assigned to a path export async function showPathSelectConfigForm(event) { event.preventDefault(); const configInput = $(event.target).closest('.path-config').find('input'); let config = {}; try { config = JSON.parse(configInput.val()); } catch (e) {} const setting = game.settings.get('core', DefaultTokenConfig.SETTING); const data = new foundry.data.PrototypeToken(setting); const token = new TokenDocument(data, { actor: null }); new TokenCustomConfig( token, {}, null, null, (conf) => { if (!conf) conf = {}; if (conf.flags == null || isEmpty(conf.flags)) delete conf.flags; configInput.val(JSON.stringify(conf)); const cog = configInput.siblings('.select-config'); if (isEmpty(conf)) cog.removeClass('active'); else cog.addClass('active'); }, config ).render(true); } export async function showTokenCaptureDialog(token) { if (!token) return; let content = `
`; new Dialog({ title: `Save Token/Overlay Image`, content: content, buttons: { yes: { icon: "", label: 'Save', callback: (html) => { const options = {}; $(html) .find('[name]') .each(function () { let val = parseFloat(this.value); if (isNaN(val)) val = this.value; options[this.name] = val; }); uploadTokenImage(token, options); }, }, }, render: (html) => { html.find('.file-picker').click(() => { new FilePicker({ type: 'folder', current: html.find('[name="path"]').val(), callback: (path) => { html.find('[name="path"]').val(path); }, }).render(); }); }, default: 'yes', }).render(true); } export function showMappingSelectDialog( mappings, { title1 = 'Mappings', title2 = 'Select Mappings', buttonTitle = 'Confirm', callback = null } = {} ) { if (!mappings || !mappings.length) return; let content = `

${title2}

`; const [_, mappingGroups] = sortMappingsToGroups(mappings); for (const [group, obj] of Object.entries(mappingGroups)) { if (obj.list.length) { content += `

${group}

`; for (const mapping of obj.list) { content += `
`; } } } content += `
`; new Dialog({ title: title1, content: content, buttons: { Ok: { label: buttonTitle, callback: async (html) => { if (!callback) return; const selectedMappings = []; html.find('input[type="checkbox"]').each(function () { if (this.checked) { const mapping = mappings.find((m) => m.id === this.name); if (mapping) { const cMapping = deepClone(mapping); selectedMappings.push(cMapping); delete cMapping.targetActors; } } }); callback(selectedMappings); }, }, }, close: () => callback(null), render: (html) => { html.find('.select-all').click(() => { html.find('input[type="checkbox"]').prop('checked', true); }); }, }).render(true); } export function showUserTemplateCreateDialog(mappings) { let content = `
`; let dialog; dialog = new Dialog({ title: 'Mapping Templates', content, buttons: { create: { label: 'Create Template', callback: (html) => { const name = html.find('[name="templateName"]').val().trim(); const hint = html.find('[name="templateHint"]').val().trim(); const img = html.find('[name="img"]').val().trim(); if (name.trim()) { TVA_CONFIG.templateMappings.push({ id: randomID(), name, hint, img, mappings: deepClone(mappings) }); updateSettings({ templateMappings: TVA_CONFIG.templateMappings }); } }, }, cancel: { label: 'Cancel', }, }, default: 'cancel', }); dialog.render(true); } export function toggleTemplateDialog() { new Templates({ callback: (templateName, mappings) => toggleTemplateOnSelected(templateName, mappings) }).render( true ); }