Finalize aappv2 data models migration
This commit is contained in:
225
modules/applications/sheets/malefices-base-actor-sheet.mjs
Normal file
225
modules/applications/sheets/malefices-base-actor-sheet.mjs
Normal file
@@ -0,0 +1,225 @@
|
||||
const { HandlebarsApplicationMixin } = foundry.applications.api
|
||||
|
||||
import { MaleficesUtility } from "../../malefices-utility.js"
|
||||
|
||||
export default class MaleficesActorSheet extends HandlebarsApplicationMixin(foundry.applications.sheets.ActorSheetV2) {
|
||||
|
||||
constructor(options = {}) {
|
||||
super(options)
|
||||
this.#dragDrop = this.#createDragDropHandlers()
|
||||
this._editScore = true
|
||||
}
|
||||
|
||||
#dragDrop
|
||||
|
||||
/** @override */
|
||||
static DEFAULT_OPTIONS = {
|
||||
classes: ["fvtt-malefices", "actor"],
|
||||
position: {
|
||||
width: 640,
|
||||
height: 680,
|
||||
},
|
||||
form: {
|
||||
submitOnChange: true,
|
||||
},
|
||||
window: {
|
||||
resizable: true,
|
||||
},
|
||||
dragDrop: [{ dragSelector: ".item-list .item", dropSelector: null }],
|
||||
actions: {
|
||||
editImage: MaleficesActorSheet.#onEditImage,
|
||||
toggleSheet: MaleficesActorSheet.#onToggleSheet,
|
||||
editItem: MaleficesActorSheet.#onEditItem,
|
||||
deleteItem: MaleficesActorSheet.#onDeleteItem,
|
||||
createItem: MaleficesActorSheet.#onCreateItem,
|
||||
equipItem: MaleficesActorSheet.#onEquipItem,
|
||||
modifyQuantity: MaleficesActorSheet.#onModifyQuantity,
|
||||
modifyAmmo: MaleficesActorSheet.#onModifyAmmo,
|
||||
rollAttribut: MaleficesActorSheet.#onRollAttribut,
|
||||
rollArme: MaleficesActorSheet.#onRollArme,
|
||||
editSubActor: MaleficesActorSheet.#onEditSubActor,
|
||||
deleteSubActor: MaleficesActorSheet.#onDeleteSubActor,
|
||||
},
|
||||
}
|
||||
|
||||
/** @type {object} */
|
||||
tabGroups = { primary: "main" }
|
||||
|
||||
/** @override */
|
||||
async _prepareContext() {
|
||||
const actor = this.document
|
||||
return {
|
||||
actor,
|
||||
system: actor.system,
|
||||
source: actor.toObject(),
|
||||
fields: actor.schema.fields,
|
||||
systemFields: actor.system.schema.fields,
|
||||
isEditable: this.isEditable,
|
||||
cssClass: this.isEditable ? "editable" : "locked",
|
||||
isGM: game.user.isGM,
|
||||
config: game.system.malefices.config,
|
||||
editScore: this._editScore,
|
||||
}
|
||||
}
|
||||
|
||||
/** @override */
|
||||
_onRender(context, options) {
|
||||
super._onRender(context, options)
|
||||
this.#dragDrop.forEach((d) => d.bind(this.element))
|
||||
|
||||
// Ignore Enter key in text inputs (not textarea)
|
||||
this.element.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Enter' && e.target.tagName !== 'TEXTAREA') e.preventDefault()
|
||||
})
|
||||
|
||||
// Manual tab navigation
|
||||
const nav = this.element.querySelector('nav.tabs[data-group]')
|
||||
if (nav) {
|
||||
const group = nav.dataset.group
|
||||
const activeTab = this.tabGroups[group] || "main"
|
||||
nav.querySelectorAll('[data-tab]').forEach(link => {
|
||||
link.classList.toggle('active', link.dataset.tab === activeTab)
|
||||
link.addEventListener('click', (event) => {
|
||||
event.preventDefault()
|
||||
this.tabGroups[group] = link.dataset.tab
|
||||
this.render()
|
||||
})
|
||||
})
|
||||
this.element.querySelectorAll(`[data-group="${group}"][data-tab]`).forEach(content => {
|
||||
content.classList.toggle('active', content.dataset.tab === activeTab)
|
||||
})
|
||||
}
|
||||
|
||||
// Handle .update-field change events (legacy support)
|
||||
this.element.querySelectorAll('.update-field').forEach(el => {
|
||||
el.addEventListener('change', (ev) => {
|
||||
const fieldName = ev.currentTarget.dataset.fieldName
|
||||
const value = Number(ev.currentTarget.value)
|
||||
this.actor.update({ [fieldName]: value })
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// #region Drag-and-Drop
|
||||
#createDragDropHandlers() {
|
||||
return this.options.dragDrop.map((d) => {
|
||||
d.permissions = {
|
||||
dragstart: this._canDragStart.bind(this),
|
||||
drop: this._canDragDrop.bind(this),
|
||||
}
|
||||
d.callbacks = {
|
||||
dragstart: this._onDragStart.bind(this),
|
||||
dragover: this._onDragOver.bind(this),
|
||||
drop: this._onDrop.bind(this),
|
||||
}
|
||||
return new foundry.applications.ux.DragDrop.implementation(d)
|
||||
})
|
||||
}
|
||||
|
||||
_canDragStart(selector) { return this.isEditable }
|
||||
_canDragDrop(selector) { return this.isEditable }
|
||||
|
||||
_onDragStart(event) {
|
||||
const li = event.currentTarget.closest('.item')
|
||||
if (!li) return
|
||||
const itemId = li.dataset.itemId
|
||||
const item = this.actor.items.get(itemId)
|
||||
if (item) {
|
||||
event.dataTransfer.setData("text/plain", JSON.stringify({ type: "Item", uuid: item.uuid }))
|
||||
}
|
||||
}
|
||||
|
||||
_onDragOver(event) {}
|
||||
|
||||
async _onDrop(event) {
|
||||
const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event)
|
||||
if (data?.type === "Actor") {
|
||||
const actor = await fromUuid(data.uuid)
|
||||
if (actor) this.actor.addSubActor(actor.id)
|
||||
} else {
|
||||
super._onDrop(event)
|
||||
}
|
||||
}
|
||||
// #endregion
|
||||
|
||||
// #region Actions
|
||||
static async #onEditImage(event, target) {
|
||||
const fp = new FilePicker({
|
||||
type: "image",
|
||||
current: this.document.img,
|
||||
callback: (path) => { this.document.update({ img: path }) },
|
||||
})
|
||||
return fp.browse()
|
||||
}
|
||||
|
||||
static async #onToggleSheet(event, target) {
|
||||
this._editScore = !this._editScore
|
||||
this.render()
|
||||
}
|
||||
|
||||
static async #onEditItem(event, target) {
|
||||
const li = target.closest(".item")
|
||||
const itemId = li?.dataset.itemId
|
||||
if (!itemId) return
|
||||
this.actor.items.get(itemId)?.sheet.render(true)
|
||||
}
|
||||
|
||||
static async #onDeleteItem(event, target) {
|
||||
const li = target.closest(".item")
|
||||
MaleficesUtility.confirmDelete(this, li)
|
||||
}
|
||||
|
||||
static async #onCreateItem(event, target) {
|
||||
const dataType = target.dataset.type
|
||||
this.actor.createEmbeddedDocuments('Item', [{ name: "NewItem", type: dataType }], { renderSheet: true })
|
||||
}
|
||||
|
||||
static async #onEquipItem(event, target) {
|
||||
const li = target.closest(".item")
|
||||
const itemId = li?.dataset.itemId
|
||||
if (!itemId) return
|
||||
await this.actor.equipItem(itemId)
|
||||
this.render()
|
||||
}
|
||||
|
||||
static async #onModifyQuantity(event, target) {
|
||||
const li = target.closest(".item")
|
||||
const itemId = li?.dataset.itemId
|
||||
if (!itemId) return
|
||||
const delta = parseInt(target.dataset.delta) || 0
|
||||
this.actor.incDecQuantity(itemId, delta)
|
||||
}
|
||||
|
||||
static async #onModifyAmmo(event, target) {
|
||||
const li = target.closest(".item")
|
||||
const itemId = li?.dataset.itemId
|
||||
if (!itemId) return
|
||||
const delta = parseInt(target.dataset.delta) || 0
|
||||
this.actor.incDecAmmo(itemId, delta)
|
||||
}
|
||||
|
||||
static async #onRollAttribut(event, target) {
|
||||
const attrKey = target.dataset.attrKey
|
||||
this.actor.rollAttribut(attrKey)
|
||||
}
|
||||
|
||||
static async #onRollArme(event, target) {
|
||||
const armeId = target.dataset.armeId
|
||||
this.actor.rollArme(armeId)
|
||||
}
|
||||
|
||||
static async #onEditSubActor(event, target) {
|
||||
const li = target.closest(".item")
|
||||
const actorId = li?.dataset.actorId
|
||||
if (!actorId) return
|
||||
game.actors.get(actorId)?.sheet.render(true)
|
||||
}
|
||||
|
||||
static async #onDeleteSubActor(event, target) {
|
||||
const li = target.closest(".item")
|
||||
const actorId = li?.dataset.actorId
|
||||
if (!actorId) return
|
||||
this.actor.delSubActor(actorId)
|
||||
}
|
||||
// #endregion
|
||||
}
|
||||
Reference in New Issue
Block a user