All user data for FoundryVTT. Includes worlds, systems, modules, and any asset in the "foundryuserdata" directory. Does NOT include the FoundryVTT installation itself.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

207 lines
7.0 KiB

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
);
}
}