import { insertArtSelectButton } from '../../applications/artSelect.js'; import { showArtSelect } from '../../token-variants.mjs'; import { TVA_CONFIG } from '../settings.js'; import { SEARCH_TYPE, updateActorImage } from '../utils.js'; import { registerHook, unregisterHook } from './hooks.js'; const feature_id = 'ArtSelect'; export function registerArtSelectButtonHooks() { // Insert right-click listeners to open up ArtSelect forms from various contexts if (TVA_CONFIG.permissions.portrait_right_click[game.user.role]) { registerHook(feature_id, 'renderActorSheet', _modActorSheet); registerHook(feature_id, 'renderItemSheet', _modItemSheet); registerHook(feature_id, 'renderItemActionSheet', _modItemSheet); registerHook(feature_id, 'renderJournalSheet', _modJournalSheet); registerHook(feature_id, 'renderRollTableConfig', _modRollTableSheet); } else { [ 'renderActorSheet', 'renderItemSheet', 'renderItemActionSheet', 'renderJournalSheet', 'renderRollTableConfig', ].forEach((name) => unregisterHook(feature_id, name)); } // Insert buttons if (TVA_CONFIG.permissions.image_path_button[game.user.role]) { registerHook(feature_id, 'renderTileConfig', _modTileConfig); registerHook(feature_id, 'renderMeasuredTemplateConfig', _modTemplateConfig); registerHook(feature_id, 'renderTokenConfig', _modTokenConfig); registerHook(feature_id, 'renderDrawingConfig', _modDrawingConfig); registerHook(feature_id, 'renderNoteConfig', _modNoteConfig); registerHook(feature_id, 'renderSceneConfig', _modSceneConfig); registerHook(feature_id, 'renderMacroConfig', _modMacroConfig); registerHook(feature_id, 'renderActiveEffectConfig', _modActiveEffectConfig); } else { [ 'renderTileConfig', 'renderMeasuredTemplateConfig', 'renderTokenConfig', 'renderDrawingConfig', 'renderNoteConfig', 'renderSceneConfig', `renderActiveEffectConfig`, ].forEach((name) => unregisterHook(feature_id, name)); } } function _modTokenConfig(config, html) { insertArtSelectButton(html, 'texture.src', { search: config.object.name, searchType: SEARCH_TYPE.TOKEN, }); } function _modTemplateConfig(config, html) { insertArtSelectButton(html, 'texture', { search: 'Template', searchType: SEARCH_TYPE.TILE }); } function _modDrawingConfig(config, html) { insertArtSelectButton(html, 'texture', { search: 'Drawing', searchType: TVA_CONFIG.customImageCategories.includes('Drawing') ? 'Drawing' : SEARCH_TYPE.TILE, }); } function _modNoteConfig(config, html) { insertArtSelectButton(html, 'icon.custom', { search: 'Note', searchType: TVA_CONFIG.customImageCategories.includes('Note') ? 'Note' : SEARCH_TYPE.ITEM, }); } function _modSceneConfig(config, html) { insertArtSelectButton(html, 'background.src', { search: config.object.name, searchType: TVA_CONFIG.customImageCategories.includes('Scene') ? 'Scene' : SEARCH_TYPE.TILE, }); insertArtSelectButton(html, 'foreground', { search: config.object.name, searchType: TVA_CONFIG.customImageCategories.includes('Scene') ? 'Scene' : SEARCH_TYPE.TILE, }); insertArtSelectButton(html, 'fogOverlay', { search: config.object.name, searchType: TVA_CONFIG.customImageCategories.includes('Fog') ? 'Fog' : SEARCH_TYPE.TILE, }); } function _modTileConfig(tileConfig, html) { insertArtSelectButton(html, 'texture.src', { search: tileConfig.object.getFlag('token-variants', 'tileName') || 'Tile', searchType: SEARCH_TYPE.TILE, }); } function _modActiveEffectConfig(effectConfig, html) { const inserted = insertArtSelectButton(html, 'icon', { search: effectConfig.object.name || 'Active Effect', searchType: TVA_CONFIG.customImageCategories.includes('Active Effect') ? 'Active Effect' : SEARCH_TYPE.ITEM, }); if (!inserted) { const img = $(html).find('.effect-icon'); img.on('contextmenu', () => { showArtSelect(effectConfig.object?.name ?? 'Active Effect', { searchType: SEARCH_TYPE.ITEM, callback: (imgSrc) => img.attr('src', imgSrc), }); }); } } function _modItemSheet(itemSheet, html, options) { $(html) .find('img.profile, .profile-img, [data-edit="img"]') .on('contextmenu', () => { const item = itemSheet.object; if (!item) return; showArtSelect(item.name, { searchType: SEARCH_TYPE.ITEM, callback: (imgSrc) => item.update({ img: imgSrc }), }); }); } function _modMacroConfig(macroConfig, html, options) { const img = $(html).find('.sheet-header > img'); img.on('contextmenu', () => { showArtSelect(macroConfig.object?.name ?? 'Macro', { searchType: SEARCH_TYPE.MACRO, callback: (imgSrc) => img.attr('src', imgSrc), }); }); } function _modJournalSheet(journalSheet, html, options) { $(html) .find('.header-button.entry-image') .on('contextmenu', () => { const journal = journalSheet.object; if (!journal) return; showArtSelect(journal.name, { searchType: SEARCH_TYPE.JOURNAL, callback: (imgSrc) => journal.update({ img: imgSrc }), }); }); } function _modRollTableSheet(sheet, html) { $(html) .find('.result-image') .on('contextmenu', (event) => { const table = sheet.object; if (!table) return; const img = $(event.target).closest('.result-image').find('img'); showArtSelect(table.name, { searchType: TVA_CONFIG.customImageCategories.includes('RollTable') ? 'RollTable' : SEARCH_TYPE.ITEM, callback: (imgSrc) => { img.attr('src', imgSrc); sheet._onSubmit(event); }, }); }); } /** * Adds right-click listener to Actor Sheet profile image to open up * the 'Art Select' screen. */ function _modActorSheet(actorSheet, html, options) { if (options.editable && TVA_CONFIG.permissions.portrait_right_click[game.user.role]) { let profile = null; let profileQueries = { all: ['.profile', '.profile-img', '.profile-image'], pf2e: ['.player-image', '.actor-icon', '.sheet-header img', '.actor-image'], }; for (let query of profileQueries.all) { profile = html[0].querySelector(query); if (profile) break; } if (!profile && game.system.id in profileQueries) { for (let query of profileQueries[game.system.id]) { profile = html[0].querySelector(query); if (profile) break; } } if (!profile) { console.warn('TVA |', game.i18n.localize('token-variants.notifications.warn.profile-image-not-found')); return; } profile.addEventListener( 'contextmenu', function (ev) { showArtSelect(actorSheet.object.name, { callback: (imgSrc, name) => updateActorImage(actorSheet.object, imgSrc), searchType: SEARCH_TYPE.PORTRAIT, object: actorSheet.object, }); }, false ); } }