implements #84 in two distinct ways: left click for a touch friendly dialog, right click for inline editing of a resource.
parent
25152ff8db
commit
a42accc7ec
|
|
@ -55,5 +55,19 @@
|
||||||
},
|
},
|
||||||
"ITEM_BROWSER": {
|
"ITEM_BROWSER": {
|
||||||
"progress": "{current}/{max}: Importiere von {compendium}"
|
"progress": "{current}/{max}: Importiere von {compendium}"
|
||||||
|
},
|
||||||
|
"RESOURCE_DIALOG": {
|
||||||
|
"Lep": {
|
||||||
|
"title": "Lebenspunkte anpassen"
|
||||||
|
},
|
||||||
|
"Aup": {
|
||||||
|
"title": "Ausdauerpunkte anpassen"
|
||||||
|
},
|
||||||
|
"Asp": {
|
||||||
|
"title": "Astralpunkte anpassen"
|
||||||
|
},
|
||||||
|
"Kap": {
|
||||||
|
"title": "Karmapunkte anpassen"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,20 @@ const {
|
||||||
ArrayField,
|
ArrayField,
|
||||||
} = foundry.data.fields;
|
} = foundry.data.fields;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @property LE
|
||||||
|
* @property AU
|
||||||
|
* @property AE
|
||||||
|
* @property KE
|
||||||
|
*/
|
||||||
|
export const ResourceType = {
|
||||||
|
LE: "Lep",
|
||||||
|
AU: "Aup",
|
||||||
|
AE: "Asp",
|
||||||
|
KE: "Kap"
|
||||||
|
}
|
||||||
|
|
||||||
export class PlayerCharacterDataModel extends foundry.abstract.TypeDataModel {
|
export class PlayerCharacterDataModel extends foundry.abstract.TypeDataModel {
|
||||||
|
|
||||||
static defineSchema() {
|
static defineSchema() {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,113 @@
|
||||||
|
import {ResourceType} from "../data/character.mjs";
|
||||||
|
|
||||||
|
const {
|
||||||
|
ApplicationV2,
|
||||||
|
HandlebarsApplicationMixin
|
||||||
|
} = foundry.applications.api
|
||||||
|
|
||||||
|
export class EditResourceDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
classes: ['dsa41', 'dialog', 'resource'],
|
||||||
|
tag: "form",
|
||||||
|
position: {
|
||||||
|
width: 480,
|
||||||
|
height: 480
|
||||||
|
},
|
||||||
|
window: {
|
||||||
|
resizable: false,
|
||||||
|
title: "Resource anpassen"
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
submitOnChange: false,
|
||||||
|
closeOnSubmit: false,
|
||||||
|
handler: EditResourceDialog.#onSubmitForm
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
setResource: EditResourceDialog.#onSetResource,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static PARTS = {
|
||||||
|
form: {
|
||||||
|
template: 'systems/DSA_4-1/templates/dialog/resource-dialog.hbs',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_actor = null;
|
||||||
|
_resourceType = null;
|
||||||
|
_min = 0;
|
||||||
|
_current = 0;
|
||||||
|
_max = 0;
|
||||||
|
|
||||||
|
constructor(actor, resourceType, min, current, max) {
|
||||||
|
super();
|
||||||
|
this._actor = actor;
|
||||||
|
this._resourceType = resourceType;
|
||||||
|
this._min = min;
|
||||||
|
this._current = current;
|
||||||
|
this._max = max;
|
||||||
|
}
|
||||||
|
|
||||||
|
static async #onSubmitForm(event, form, formData) {
|
||||||
|
event.preventDefault()
|
||||||
|
this.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
static async #onSetResource(event, target) {
|
||||||
|
const {value} = target.dataset;
|
||||||
|
switch(this._resourceType) {
|
||||||
|
case ResourceType.LE:
|
||||||
|
await this._actor.update({"system.lep.aktuell": value});
|
||||||
|
break;
|
||||||
|
case ResourceType.AU:
|
||||||
|
await this._actor.update({"system.aup.aktuell": value});
|
||||||
|
break;
|
||||||
|
case ResourceType.AE:
|
||||||
|
await this._actor.update({"system.asp.aktuell": value});
|
||||||
|
break;
|
||||||
|
case ResourceType.KE:
|
||||||
|
await this._actor.update({"system.kap.aktuell": value});
|
||||||
|
}
|
||||||
|
this.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
async _prepareContext(options) {
|
||||||
|
const context = await super._prepareContext(options)
|
||||||
|
|
||||||
|
context.steps = [];
|
||||||
|
|
||||||
|
for (let i = this._min; i <= this._max; ++i ) {
|
||||||
|
if (i < this._current) {
|
||||||
|
context.steps.push({
|
||||||
|
display: i - this._current,
|
||||||
|
value: i,
|
||||||
|
isReduction: true,
|
||||||
|
isIncreasing: false,
|
||||||
|
});
|
||||||
|
} else if (i === this._current) {
|
||||||
|
context.steps.push({
|
||||||
|
display: i - this._current,
|
||||||
|
value: i,
|
||||||
|
isReduction: false,
|
||||||
|
isIncreasing: false,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
context.steps.push({
|
||||||
|
display: "+" + (i - this._current),
|
||||||
|
value: i,
|
||||||
|
isReduction: false,
|
||||||
|
isIncreasing: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
|
||||||
|
_configureRenderOptions(options) {
|
||||||
|
super._configureRenderOptions(options)
|
||||||
|
if (options.window) {
|
||||||
|
options.window.title = game.i18n.format("RESOURCE_DIALOG." + this._resourceType + ".title")
|
||||||
|
}
|
||||||
|
return options
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -24,6 +24,8 @@ import {StandaloneLiturgies} from "./character-standalone/liturgies.mjs";
|
||||||
import {StandaloneHealth} from "./character-standalone/health.mjs";
|
import {StandaloneHealth} from "./character-standalone/health.mjs";
|
||||||
import {SpellDialog} from "../dialog/spellDialog.mjs";
|
import {SpellDialog} from "../dialog/spellDialog.mjs";
|
||||||
import {displayRoll} from "../globals/displayRoll.js";
|
import {displayRoll} from "../globals/displayRoll.js";
|
||||||
|
import {ResourceType} from "../data/character.mjs";
|
||||||
|
import {EditResourceDialog} from "../dialog/resourceDialog.mjs";
|
||||||
|
|
||||||
const {HandlebarsApplicationMixin, DocumentSheetV2} = foundry.applications.api
|
const {HandlebarsApplicationMixin, DocumentSheetV2} = foundry.applications.api
|
||||||
const {ActorSheetV2} = foundry.applications.sheets
|
const {ActorSheetV2} = foundry.applications.sheets
|
||||||
|
|
@ -76,7 +78,10 @@ class CharacterSheet extends HandlebarsApplicationMixin(ActorSheetV2) {
|
||||||
setWounds: CharacterSheet.#setWounds,
|
setWounds: CharacterSheet.#setWounds,
|
||||||
switchSet: CharacterSheet.#switchSet,
|
switchSet: CharacterSheet.#switchSet,
|
||||||
openInitiative: CharacterSheet.#openInitiative,
|
openInitiative: CharacterSheet.#openInitiative,
|
||||||
|
editLep: CharacterSheet.#editLep,
|
||||||
|
editAup: CharacterSheet.#editAup,
|
||||||
|
editAsp: CharacterSheet.#editAsp,
|
||||||
|
editKap: CharacterSheet.#editKap,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -272,6 +277,59 @@ class CharacterSheet extends HandlebarsApplicationMixin(ActorSheetV2) {
|
||||||
new SpellDialog(this.document, itemId).render(true)
|
new SpellDialog(this.document, itemId).render(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static #editAup(event, target, isRightClicked) {
|
||||||
|
|
||||||
|
if (!isRightClicked) {
|
||||||
|
const min = 0
|
||||||
|
const current = this.document.system.aup.aktuell
|
||||||
|
const max = this.document.system.aup.max
|
||||||
|
|
||||||
|
const dialog = new EditResourceDialog(this.document, ResourceType.AU, min, current, max)
|
||||||
|
dialog.render(true)
|
||||||
|
target.parentElement.querySelector('input').blur();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static #editLep(event, target, isRightClicked) {
|
||||||
|
|
||||||
|
if (!isRightClicked) {
|
||||||
|
const min = 0
|
||||||
|
const current = this.document.system.lep.aktuell
|
||||||
|
const max = this.document.system.lep.max
|
||||||
|
|
||||||
|
const dialog = new EditResourceDialog(this.document, ResourceType.LE, min, current, max)
|
||||||
|
dialog.render(true)
|
||||||
|
target.parentElement.querySelector('input').blur();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static #editAsp(event, target, isRightClicked) {
|
||||||
|
|
||||||
|
if (!isRightClicked) {
|
||||||
|
const min = 0
|
||||||
|
|
||||||
|
const current = this.document.system.asp.aktuell
|
||||||
|
const max = this.document.system.asp.max
|
||||||
|
|
||||||
|
const dialog = new EditResourceDialog(this.document, ResourceType.AE, min, current, max)
|
||||||
|
dialog.render(true)
|
||||||
|
target.parentElement.querySelector('input').blur();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static #editKap(event, target, isRightClicked) {
|
||||||
|
|
||||||
|
if (!isRightClicked) {
|
||||||
|
const min = 0
|
||||||
|
const current = this.document.system.kap.aktuell
|
||||||
|
const max = this.document.system.kap.max
|
||||||
|
|
||||||
|
const dialog = new EditResourceDialog(this.document, ResourceType.KE, min, current, max)
|
||||||
|
dialog.render(true)
|
||||||
|
target.parentElement.querySelector('input').blur();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static #startResting(event, target) {
|
static #startResting(event, target) {
|
||||||
|
|
||||||
const dialog = new RestingDialog(this.document)
|
const dialog = new RestingDialog(this.document)
|
||||||
|
|
@ -374,6 +432,22 @@ class CharacterSheet extends HandlebarsApplicationMixin(ActorSheetV2) {
|
||||||
static async #onSubmitForm(event, form, formData) {
|
static async #onSubmitForm(event, form, formData) {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
|
|
||||||
|
if (formData.object["system.lep.aktuell"]?.[1]) {
|
||||||
|
formData.object["system.lep.aktuell"] = formData.object["system.lep.aktuell"][0]
|
||||||
|
}
|
||||||
|
|
||||||
|
if (formData.object["system.aup.aktuell"]?.[1]) {
|
||||||
|
formData.object["system.aup.aktuell"] = formData.object["system.aup.aktuell"][0]
|
||||||
|
}
|
||||||
|
|
||||||
|
if (formData.object["system.asp.aktuell"]?.[1]) {
|
||||||
|
formData.object["system.asp.aktuell"] = formData.object["system.asp.aktuell"][0]
|
||||||
|
}
|
||||||
|
|
||||||
|
if (formData.object["system.kap.aktuell"]?.[1]) {
|
||||||
|
formData.object["system.kap.aktuell"] = formData.object["system.kap.aktuell"][0]
|
||||||
|
}
|
||||||
|
|
||||||
await this.document.update(formData.object)
|
await this.document.update(formData.object)
|
||||||
|
|
||||||
return false
|
return false
|
||||||
|
|
@ -797,6 +871,17 @@ class CharacterSheet extends HandlebarsApplicationMixin(ActorSheetV2) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async _postRender() {
|
||||||
|
this.element.querySelectorAll('.sidebar-element.resource-bar[data-action]').forEach( e => {
|
||||||
|
const { action} = e.dataset;
|
||||||
|
e.addEventListener('contextmenu', (event) => {
|
||||||
|
if (CharacterSheet.DEFAULT_OPTIONS.actions[action]) {
|
||||||
|
CharacterSheet.DEFAULT_OPTIONS.actions[action].bind(this)(event, event.target, true);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default CharacterSheet
|
export default CharacterSheet
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,8 @@ $talent-language-text-color: #000;
|
||||||
$talent-crafting-color: #cd9551;
|
$talent-crafting-color: #cd9551;
|
||||||
$talent-crafting-text-color: #000;
|
$talent-crafting-text-color: #000;
|
||||||
|
|
||||||
|
$help-fill-color: #60d060ff;
|
||||||
|
$help-border-color: #308030ff;
|
||||||
|
|
||||||
$harm-fill-color: #ff0000ff;
|
$harm-fill-color: #ff0000ff;
|
||||||
$harm-border-color: #3c0000ff;
|
$harm-border-color: #3c0000ff;
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@
|
||||||
|
|
||||||
.resource-bar {
|
.resource-bar {
|
||||||
|
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
height: 24px;
|
height: 24px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
@ -16,18 +18,43 @@
|
||||||
margin: 8px 0;
|
margin: 8px 0;
|
||||||
|
|
||||||
label {
|
label {
|
||||||
|
|
||||||
|
cursor: pointer;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
|
width: 40px;
|
||||||
line-height: 24px;
|
line-height: 24px;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
text-indent: 8px;
|
text-indent: 8px;
|
||||||
color: white;
|
color: white;
|
||||||
text-shadow: 2px 2px 1px rgba(0, 0, 0, 0.3);
|
text-shadow: 2px 2px 1px rgba(0, 0, 0, 0.3);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
input {
|
||||||
|
position: absolute;
|
||||||
|
left: 40px;
|
||||||
|
top: 0;
|
||||||
|
width: calc(100% - 40px);
|
||||||
|
z-index: 4;
|
||||||
|
height: 22px;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
line-height: 24px;
|
||||||
|
vertical-align: middle;
|
||||||
|
text-indent: 8px;
|
||||||
|
color: white;
|
||||||
|
font-size: large;
|
||||||
|
background: transparent;
|
||||||
|
text-shadow: 2px 2px 1px rgba(0, 0, 0, 0.3);
|
||||||
|
border: 0;
|
||||||
|
&:hover {
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
span.resource-fill {
|
span.resource-fill {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
@use "../atoms/colours" as colour;
|
||||||
|
|
||||||
|
.dsa41.dialog.resource {
|
||||||
|
|
||||||
|
section.steps {
|
||||||
|
overflow: auto;
|
||||||
|
flex: 1;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(5, 1fr);
|
||||||
|
|
||||||
|
.step {
|
||||||
|
display: inline-block;
|
||||||
|
border: 1px solid black;
|
||||||
|
width: 64px;
|
||||||
|
height: 48px;
|
||||||
|
line-height: 48px;
|
||||||
|
vertical-align: middle;
|
||||||
|
text-align: center;
|
||||||
|
justify-self: center;
|
||||||
|
font-weight: bold;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
margin: 4px;
|
||||||
|
box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.5),
|
||||||
|
2px 2px inset rgba(0, 0, 0, 0.2);
|
||||||
|
|
||||||
|
&.reducing {
|
||||||
|
background-color: colour.$harm-fill-color;
|
||||||
|
border-color: colour.$harm-border-color;
|
||||||
|
background-blend-mode: hue;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.increasing {
|
||||||
|
background-color: colour.$help-fill-color;
|
||||||
|
border-color: colour.$help-border-color;
|
||||||
|
background-blend-mode: hue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -39,4 +39,5 @@
|
||||||
@use "organisms/dialog";
|
@use "organisms/dialog";
|
||||||
@use "organisms/deity-sheet";
|
@use "organisms/deity-sheet";
|
||||||
@use "organisms/item-browser-dialog";
|
@use "organisms/item-browser-dialog";
|
||||||
|
@use "organisms/resource-dialog";
|
||||||
@use "atoms/chat";
|
@use "atoms/chat";
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
"id": "DSA_4-1",
|
"id": "DSA_4-1",
|
||||||
"title": "Das Schwarze Auge 4.1",
|
"title": "Das Schwarze Auge 4.1",
|
||||||
"description": "Noch ein Spielsystem für Das Schwarze Auge 4.1",
|
"description": "Noch ein Spielsystem für Das Schwarze Auge 4.1",
|
||||||
"version": "0.11.2",
|
"version": "0.0.1",
|
||||||
"compatibility": {
|
"compatibility": {
|
||||||
"minimum": 12,
|
"minimum": 12,
|
||||||
"verified": 13
|
"verified": 13
|
||||||
|
|
@ -364,5 +364,5 @@
|
||||||
"primaryTokenAttribute": "lep.aktuell",
|
"primaryTokenAttribute": "lep.aktuell",
|
||||||
"url": "https://git.macniel.online/macniel/foundry-dsa41-game",
|
"url": "https://git.macniel.online/macniel/foundry-dsa41-game",
|
||||||
"manifest": "https://git.macniel.online/macniel/foundry-dsa41-game/raw/branch/main/src/system.json",
|
"manifest": "https://git.macniel.online/macniel/foundry-dsa41-game/raw/branch/main/src/system.json",
|
||||||
"download": "https://git.macniel.online/macniel/foundry-dsa41-game/releases/download/0.11.2/release.zip"
|
"download": "https://git.macniel.online/macniel/foundry-dsa41-game/releases/download/0.0.1/release.zip"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,27 +31,27 @@
|
||||||
|
|
||||||
<img class="profile-img" src="{{img}}" data-action="editImage" data-edit="img" title="{{name}}"/>
|
<img class="profile-img" src="{{img}}" data-action="editImage" data-edit="img" title="{{name}}"/>
|
||||||
|
|
||||||
<div class="sidebar-element resource-bar">
|
<div class="sidebar-element resource-bar" data-action="editLep">
|
||||||
<label>LeP: {{this.lepcurrent}}</label><span class="resource-fill lep"
|
<label>LeP:</label> <input type="number" name="system.lep.aktuell" value="{{this.system.lep.aktuell}}"/><span class="resource-fill lep"
|
||||||
style="width: {{this.lepper}}%"></span>
|
style="width: {{this.lepper}}%"></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{#if ausdauer}}
|
{{#if ausdauer}}
|
||||||
<div class="sidebar-element resource-bar">
|
<div class="sidebar-element resource-bar" data-action="editAup">
|
||||||
<label>AuP: {{this.aupcurrent}}</label><span class="resource-fill aup"
|
<label>AuP:</label> <input type="number" name="system.aup.aktuell" value="{{this.system.aup.aktuell}}><span class="resource-fill aup"
|
||||||
style="width: {{this.aupper}}%"></span>
|
style="width: {{this.aupper}}%"></span>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if this.hasLiturgies}}
|
{{#if this.hasLiturgies}}
|
||||||
<div class="sidebar-element resource-bar">
|
<div class="sidebar-element resource-bar" data-action="editKap">
|
||||||
<label>KaP: {{this.kapcurrent}}</label><span class="resource-fill kap" style="width: {{this.keper}}%"></span>
|
<label>KaP:</label> <input type="number" name="system.kap.aktuell" value="{{this.kapcurrent}}"><span class="resource-fill kap" style="width: {{this.keper}}%"></span>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if this.hasSpells}}
|
{{#if this.hasSpells}}
|
||||||
<div class="sidebar-element resource-bar">
|
<div class="sidebar-element resource-bar" data-action="editAsp">
|
||||||
<label>AsP: {{this.aspcurrent}}</label><span class="resource-fill asp" style="width: {{this.aspper}}%"></span>
|
<label>AsP:</label> <input type="number" name="system.asp.aktuell" value="{{this.aspcurrent}}"><span class="resource-fill asp" style="width: {{this.aspper}}%"></span>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
<section class="steps">
|
||||||
|
|
||||||
|
{{#each steps}}<div class="step{{#if this.isReduction}} reducing{{/if}}{{#if this.isIncreasing}} increasing{{/if}}" data-action="setResource" data-value="{{this.value}}">{{this.display}}</div>{{/each}}
|
||||||
|
|
||||||
|
</section>
|
||||||
Loading…
Reference in New Issue