mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-11 19:25:21 +01:00
104 lines
3.4 KiB
JavaScript
104 lines
3.4 KiB
JavaScript
/**
|
|
* A singleton class that handles preview tokens.
|
|
*/
|
|
|
|
export default class DhTokenManager {
|
|
#activePreview;
|
|
#actor;
|
|
#resolve;
|
|
|
|
/**
|
|
* Create a template preview, deactivating any existing ones.
|
|
* @param {object} data
|
|
*/
|
|
async createPreview(actor, tokenData) {
|
|
this.#actor = actor;
|
|
const token = await canvas.tokens._createPreview(
|
|
{
|
|
...actor.prototypeToken,
|
|
displayName: 50,
|
|
...tokenData
|
|
},
|
|
{ renderSheet: false, actor }
|
|
);
|
|
|
|
this.#activePreview = {
|
|
document: token.document,
|
|
object: token,
|
|
origin: { x: token.document.x, y: token.document.y }
|
|
};
|
|
|
|
this.#activePreview.events = {
|
|
contextmenu: this.#cancelTemplate.bind(this),
|
|
mousedown: this.#confirmTemplate.bind(this),
|
|
mousemove: this.#onDragMouseMove.bind(this)
|
|
};
|
|
|
|
canvas.stage.on('mousemove', this.#activePreview.events.mousemove);
|
|
canvas.stage.on('mousedown', this.#activePreview.events.mousedown);
|
|
canvas.app.view.addEventListener('contextmenu', this.#activePreview.events.contextmenu);
|
|
}
|
|
|
|
/* Currently intended for using as a preview of where to create a token. (note the flag) */
|
|
async createPreviewAsync(actor, tokenData = {}) {
|
|
return new Promise(resolve => {
|
|
this.#resolve = resolve;
|
|
this.createPreview(actor, { ...tokenData, flags: { daggerheart: { createPlacement: true } } });
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Handles the movement of the token preview on mousedrag.
|
|
* @param {mousemove Event} event
|
|
*/
|
|
#onDragMouseMove(event) {
|
|
event.stopPropagation();
|
|
const { moveTime, object } = this.#activePreview;
|
|
const update = {};
|
|
|
|
const now = Date.now();
|
|
if (now - (moveTime || 0) <= 16) return;
|
|
this.#activePreview.moveTime = now;
|
|
|
|
let cursor = event.getLocalPosition(canvas.templates);
|
|
|
|
Object.assign(update, canvas.grid.getTopLeftPoint(cursor));
|
|
|
|
object.document.updateSource(update);
|
|
object.renderFlags.set({ refresh: true });
|
|
}
|
|
|
|
/**
|
|
* Cancels the preview token on right-click.
|
|
* @param {contextmenu Event} event
|
|
*/
|
|
#cancelTemplate(_event, resolved) {
|
|
const { mousemove, mousedown, contextmenu } = this.#activePreview.events;
|
|
this.#activePreview.object.destroy();
|
|
|
|
canvas.stage.off('mousemove', mousemove);
|
|
canvas.stage.off('mousedown', mousedown);
|
|
canvas.app.view.removeEventListener('contextmenu', contextmenu);
|
|
if (this.#resolve && !resolved) this.#resolve(false);
|
|
}
|
|
|
|
/**
|
|
* Creates a real Actor and token at the preview location and cancels the preview.
|
|
* @param {click Event} event
|
|
*/
|
|
async #confirmTemplate(event) {
|
|
event.stopPropagation();
|
|
this.#cancelTemplate(event, true);
|
|
|
|
const actor = this.#actor.inCompendium
|
|
? await game.system.api.documents.DhpActor.create(this.#actor.toObject())
|
|
: this.#actor;
|
|
const tokenData = await actor.getTokenDocument();
|
|
const result = await canvas.scene.createEmbeddedDocuments('Token', [
|
|
{ ...tokenData, x: this.#activePreview.document.x, y: this.#activePreview.document.y }
|
|
]);
|
|
|
|
this.#activePreview = undefined;
|
|
if (this.#resolve && result.length) this.#resolve(result[0]);
|
|
}
|
|
}
|