Merge pull request #42 from Eldritch-Oliver/feature/resize-controls

Add the ability to tell the system the starting width/height and whether or not a sheet should be resizable
This commit is contained in:
Oliver 2025-09-17 19:22:00 -06:00 committed by GitHub
commit a50d0e8609
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 178 additions and 21 deletions

View file

@ -34,12 +34,8 @@ export class AttributeManager extends HandlebarsApplicationMixin(ApplicationV2)
}; };
static PARTS = { static PARTS = {
attributes: { attributes: { template: filePath(`templates/AttributeManager/attribute-list.hbs`) },
template: filePath(`templates/AttributeManager/attribute-list.hbs`), controls: { template: filePath(`templates/AttributeManager/controls.hbs`) },
},
controls: {
template: filePath(`templates/AttributeManager/controls.hbs`),
},
}; };
// #endregion Options // #endregion Options

View file

@ -1,9 +1,11 @@
import { __ID__, filePath } from "../consts.mjs"; import { __ID__, filePath } from "../consts.mjs";
import { AttributeManager } from "./AttributeManager.mjs"; import { AttributeManager } from "./AttributeManager.mjs";
import { attributeSorter } from "../utils/attributeSort.mjs"; import { attributeSorter } from "../utils/attributeSort.mjs";
import { ResizeControlManager } from "./ResizeControlManager.mjs";
const { HandlebarsApplicationMixin } = foundry.applications.api; const { HandlebarsApplicationMixin } = foundry.applications.api;
const { ActorSheetV2 } = foundry.applications.sheets; const { ActorSheetV2 } = foundry.applications.sheets;
const { getProperty } = foundry.utils;
export class PlayerSheet extends HandlebarsApplicationMixin(ActorSheetV2) { export class PlayerSheet extends HandlebarsApplicationMixin(ActorSheetV2) {
@ -26,6 +28,7 @@ export class PlayerSheet extends HandlebarsApplicationMixin(ActorSheetV2) {
}, },
actions: { actions: {
manageAttributes: this.#manageAttributes, manageAttributes: this.#manageAttributes,
sizeSettings: this.#configureSizeSettings,
}, },
}; };
@ -37,6 +40,30 @@ export class PlayerSheet extends HandlebarsApplicationMixin(ActorSheetV2) {
// #endregion Options // #endregion Options
// #region Lifecycle // #region Lifecycle
_initializeApplicationOptions(options) {
const sizing = getProperty(options.document, `flags.${__ID__}.PlayerSheet.size`) ?? {};
options.window ??= {};
switch (sizing.resizable) {
case `false`:
options.window.resizable ??= false;
break;
case `true`:
options.window.resizable ??= true;
break;
};
options.position ??= {};
if (sizing.width) {
options.position.width ??= sizing.width;
};
if (sizing.height) {
options.position.height ??= sizing.height;
};
return super._initializeApplicationOptions(options);
};
_getHeaderControls() { _getHeaderControls() {
const controls = super._getHeaderControls(); const controls = super._getHeaderControls();
@ -51,13 +78,22 @@ export class PlayerSheet extends HandlebarsApplicationMixin(ActorSheetV2) {
return isGM || (allowPlayerEdits && editable); return isGM || (allowPlayerEdits && editable);
}, },
}); });
controls.push({
icon: `fa-solid fa-crop-simple`,
label: `Configure Size`,
action: `sizeSettings`,
visible: () => {
const isGM = game.user.isGM;
return isGM;
},
});
return controls; return controls;
}; };
async close() { async close() {
this.attributeManager?.close(); this.#attributeManager?.close();
this.attributeManager = null; this.#attributeManager = null;
return super.close(); return super.close();
}; };
// #endregion Lifecycle // #endregion Lifecycle
@ -109,16 +145,26 @@ export class PlayerSheet extends HandlebarsApplicationMixin(ActorSheetV2) {
// #endregion Data Prep // #endregion Data Prep
// #region Actions // #region Actions
attributeManager = null; #attributeManager = null;
/** @this {PlayerSheet} */ /** @this {PlayerSheet} */
static async #manageAttributes() { static async #manageAttributes() {
this.attributeManager ??= new AttributeManager({ document: this.actor }); this.#attributeManager ??= new AttributeManager({ document: this.actor });
if (this.attributeManager.rendered) { if (this.#attributeManager.rendered) {
await this.attributeManager.bringToFront(); await this.#attributeManager.bringToFront();
} else { } else {
await this.attributeManager.render({ force: true }); await this.#attributeManager.render({ force: true });
} };
};
#sizeSettings = null;
/** @this {PlayerSheet} */
static async #configureSizeSettings() {
this.#sizeSettings ??= new ResizeControlManager({ document: this.actor });
if (this.#sizeSettings.rendered) {
await this.#sizeSettings.bringToFront();
} else {
await this.#sizeSettings.render({ force: true });
};
}; };
// #endregion Actions // #endregion Actions
}; };

View file

@ -0,0 +1,61 @@
import { __ID__, filePath } from "../consts.mjs";
const { HandlebarsApplicationMixin, DocumentSheetV2 } = foundry.applications.api;
const { getProperty } = foundry.utils;
export class ResizeControlManager extends HandlebarsApplicationMixin(DocumentSheetV2) {
// #region Options
static DEFAULT_OPTIONS = {
classes: [
__ID__,
`ResizeControlManager`,
],
position: {
width: 400,
height: `auto`,
},
window: {
resizable: true,
},
form: {
submitOnChange: false,
closeOnSubmit: true,
},
actions: {},
};
static PARTS = {
settings: { template: filePath(`templates/ResizeControlManager/settings.hbs`) },
controls: { template: filePath(`templates/ResizeControlManager/controls.hbs`) },
};
// #endregion Options
// #region Instance Data
get title() {
return `Sizing Settings For : ${this.document.name}`;
};
// #endregion Instance Data
// #region Data Prep
async _prepareContext() {
const sizing = getProperty(this.document, `flags.${__ID__}.PlayerSheet.size`) ?? {};
const ctx = {
meta: {
idp: this.id,
},
width: sizing.width,
height: sizing.height,
resizable: sizing.resizable,
resizeOptions: [
{ label: `Default`, value: `` },
{ label: `Resizable`, value: `true` },
{ label: `No Resizing`, value: `false` },
],
};
return ctx;
};
// #endregion Data Prep
};

View file

@ -0,0 +1,20 @@
.taf.ResizeControlManager {
fieldset {
display: grid;
grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
align-items: center;
gap: 8px;
border: 1px solid rebeccapurple;
border-radius: 4px;
}
.controls {
display: flex;
flex-direction: row;
gap: 8px;
button {
flex-grow: 1;
}
}
}

View file

@ -20,3 +20,4 @@
@import url("./Apps/Ask.css") layer(apps); @import url("./Apps/Ask.css") layer(apps);
@import url("./Apps/AttributeManager.css") layer(apps); @import url("./Apps/AttributeManager.css") layer(apps);
@import url("./Apps/PlayerSheet.css") layer(apps); @import url("./Apps/PlayerSheet.css") layer(apps);
@import url("./Apps/ResizeControlManager.css") layer(apps);

View file

@ -4,18 +4,15 @@
"description": "An intentionally minimalist system that enables you to play rules-light games without getting in your way!", "description": "An intentionally minimalist system that enables you to play rules-light games without getting in your way!",
"version": "2.2.1", "version": "2.2.1",
"download": "#{DOWNLOAD}#", "download": "#{DOWNLOAD}#",
"manifest": "https://github.com/Oliver-Akins/Text-Actors-Foundry/releases/latest/download/system.json", "manifest": "https://github.com/Eldritch-Oliver/Text-Actors-Foundry/releases/latest/download/system.json",
"url": "https://github.com/Oliver-Akins/Text-Actors-Foundry", "url": "https://github.com/Eldritch-Oliver/Text-Actors-Foundry",
"compatibility": { "compatibility": {
"minimum": 13, "minimum": 13,
"verified": 13, "verified": 13,
"maximum": 13 "maximum": 13
}, },
"authors": [ "authors": [
{ { "name": "Oliver" }
"name": "Oliver Akins",
"url": "https://oliver.akins.me"
}
], ],
"esmodules": [ "esmodules": [
"./module/main.mjs" "./module/main.mjs"

View file

@ -0,0 +1,7 @@
<div class="controls">
<button
type="submit"
>
Save and Close
</button>
</div>

View file

@ -0,0 +1,29 @@
<div class="settings">
<p>
Changes to these settings will only take effect after a reload of Foundry.
</p>
<fieldset>
<legend>Sizing</legend>
<label for="{{ meta.idp }}-width">Width</label>
<input
type="number"
id="{{ meta.idp }}-width"
value="{{ width }}"
name="flags.taf.PlayerSheet.size.width"
>
<label for="{{ meta.idp }}-height">Height</label>
<input
type="number"
id="{{ meta.idp }}-height"
value="{{ height }}"
name="flags.taf.PlayerSheet.size.height"
>
<label for="{{ meta.idp }}-resizable">Resizable?</label>
<select
id="{{ meta.idp }}-resizable"
name="flags.taf.PlayerSheet.size.resizable"
>
{{ taf-options resizable resizeOptions }}
</select>
</fieldset>
</div>