mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-12 03:31:07 +01:00
118 lines
3.7 KiB
JavaScript
118 lines
3.7 KiB
JavaScript
/**
|
|
* A singleton class that handles preview templates.
|
|
*/
|
|
|
|
export default class DhTemplateManager {
|
|
#activePreview;
|
|
|
|
|
|
getActivePreview() {
|
|
return this.#activePreview;
|
|
}
|
|
|
|
/**
|
|
* Create a template preview, deactivating any existing ones.
|
|
* @param {object} data
|
|
*/
|
|
async createPreview(data) {
|
|
const template = await canvas.templates._createPreview(data, { renderSheet: false });
|
|
|
|
this.#activePreview = {
|
|
document: template.document,
|
|
object: template,
|
|
origin: { x: template.document.x, y: template.document.y }
|
|
};
|
|
|
|
this.#activePreview.events = {
|
|
contextmenu: this.#cancelTemplate.bind(this),
|
|
mousedown: this.#confirmTemplate.bind(this),
|
|
mousemove: this.#onDragMouseMove.bind(this),
|
|
wheel: this.#onMouseWheel.bind(this)
|
|
};
|
|
canvas.stage.on('mousemove', this.#activePreview.events.mousemove);
|
|
canvas.stage.on('mousedown', this.#activePreview.events.mousedown);
|
|
|
|
canvas.app.view.addEventListener('wheel', this.#activePreview.events.wheel, true);
|
|
canvas.app.view.addEventListener('contextmenu', this.#activePreview.events.contextmenu);
|
|
return this.#activePreview;
|
|
}
|
|
|
|
/**
|
|
* Handles the movement of the temlate 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.getCenterPoint(cursor));
|
|
|
|
object.document.updateSource(update);
|
|
object.renderFlags.set({ refresh: true });
|
|
}
|
|
|
|
/**
|
|
* Handles the rotation of the preview template on scrolling.
|
|
* @param {wheel Event} event
|
|
*/
|
|
#onMouseWheel(event) {
|
|
if (!this.#activePreview) {
|
|
return;
|
|
}
|
|
if (!event.shiftKey && !event.ctrlKey) return;
|
|
event.stopPropagation();
|
|
event.preventDefault();
|
|
const { moveTime, object } = this.#activePreview;
|
|
|
|
const now = Date.now();
|
|
if (now - (moveTime || 0) <= 16) return;
|
|
this.#activePreview.moveTime = now;
|
|
|
|
const multiplier = event.shiftKey ? 0.2 : 0.1;
|
|
|
|
object.document.updateSource({
|
|
direction: object.document.direction + event.deltaY * multiplier
|
|
});
|
|
object.renderFlags.set({ refresh: true });
|
|
}
|
|
|
|
/**
|
|
* Cancels the preview template on right-click.
|
|
* @param {contextmenu Event} event
|
|
*/
|
|
#cancelTemplate(event) {
|
|
const { mousemove, mousedown, contextmenu, wheel } = this.#activePreview.events;
|
|
canvas.templates._onDragLeftCancel(event);
|
|
|
|
canvas.stage.off('mousemove', mousemove);
|
|
canvas.stage.off('mousedown', mousedown);
|
|
canvas.app.view.removeEventListener('contextmenu', contextmenu);
|
|
canvas.app.view.removeEventListener('wheel', wheel);
|
|
}
|
|
|
|
/**
|
|
* Creates a real MeasuredTemplate at the preview location and cancels the preview.
|
|
* @param {click Event} event
|
|
*/
|
|
#confirmTemplate(event) {
|
|
event.stopPropagation();
|
|
this.#cancelTemplate(event);
|
|
|
|
canvas.scene.createEmbeddedDocuments('MeasuredTemplate', [this.#activePreview.document.toObject()]);
|
|
this.#activePreview = undefined;
|
|
}
|
|
|
|
cancelActivePreview(event) {
|
|
if (this.#activePreview) {
|
|
this.#cancelTemplate(event);
|
|
this.#activePreview = undefined;
|
|
}
|
|
}
|
|
}
|