Begin making the BookGeistSheet have the final design
This commit is contained in:
parent
798e7441b4
commit
28345bdef0
8 changed files with 360 additions and 64 deletions
|
|
@ -2,21 +2,27 @@ import { filePath } from "../../consts.mjs";
|
||||||
import { GenericAppMixin } from "../mixins/GenericApp.mjs";
|
import { GenericAppMixin } from "../mixins/GenericApp.mjs";
|
||||||
import { LaidOutAppMixin } from "../mixins/LaidOutAppMixin.mjs";
|
import { LaidOutAppMixin } from "../mixins/LaidOutAppMixin.mjs";
|
||||||
import { localizer } from "../../utils/Localizer.mjs";
|
import { localizer } from "../../utils/Localizer.mjs";
|
||||||
|
import { editItemFromElement, deleteItemFromElement } from "../utils.mjs";
|
||||||
|
|
||||||
const { HandlebarsApplicationMixin } = foundry.applications.api;
|
const { HandlebarsApplicationMixin } = foundry.applications.api;
|
||||||
const { ActorSheetV2 } = foundry.applications.sheets;
|
const { ActorSheetV2 } = foundry.applications.sheets;
|
||||||
|
|
||||||
export class BookGeistSheet extends LaidOutAppMixin(GenericAppMixin(HandlebarsApplicationMixin(ActorSheetV2))) {
|
export class BookGeistSheet extends
|
||||||
|
LaidOutAppMixin(
|
||||||
|
GenericAppMixin(
|
||||||
|
HandlebarsApplicationMixin(
|
||||||
|
ActorSheetV2,
|
||||||
|
))) {
|
||||||
// #region Options
|
// #region Options
|
||||||
static DEFAULT_OPTIONS = {
|
static DEFAULT_OPTIONS = {
|
||||||
classes: [
|
classes: [
|
||||||
`ripcrypt--actor`,
|
`ripcrypt--actor`,
|
||||||
`BookGeistSheet`,
|
`BookGeistSheet`,
|
||||||
],
|
],
|
||||||
// position: {
|
position: {
|
||||||
// width: ``,
|
width: `auto`,
|
||||||
// height: ``,
|
height: `auto`,
|
||||||
// },
|
},
|
||||||
window: {
|
window: {
|
||||||
resizable: true,
|
resizable: true,
|
||||||
},
|
},
|
||||||
|
|
@ -31,52 +37,71 @@ export class BookGeistSheet extends LaidOutAppMixin(GenericAppMixin(HandlebarsAp
|
||||||
root: true,
|
root: true,
|
||||||
template: filePath(`templates/Apps/BookGeistSheet/layout.hbs`),
|
template: filePath(`templates/Apps/BookGeistSheet/layout.hbs`),
|
||||||
},
|
},
|
||||||
image: {
|
image: { template: filePath(`templates/Apps/BookGeistSheet/image.hbs`) },
|
||||||
template: filePath(`templates/Apps/BookGeistSheet/image.hbs`),
|
header: { template: filePath(`templates/Apps/BookGeistSheet/header.hbs`) },
|
||||||
},
|
stats: { template: filePath(`templates/Apps/BookGeistSheet/stats.hbs`) },
|
||||||
header: {
|
items: { template: filePath(`templates/Apps/BookGeistSheet/items.hbs`) },
|
||||||
template: filePath(`templates/Apps/BookGeistSheet/header.hbs`),
|
|
||||||
},
|
|
||||||
stats: {
|
|
||||||
template: filePath(`templates/Apps/BookGeistSheet/stats.hbs`),
|
|
||||||
},
|
|
||||||
items: {
|
|
||||||
template: filePath(`templates/Apps/BookGeistSheet/items.hbs`),
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
// #endregion Options
|
// #endregion Options
|
||||||
|
|
||||||
// #region Lifecycle
|
// #region Lifecycle
|
||||||
|
async _onRender() {
|
||||||
|
await super._onRender();
|
||||||
|
|
||||||
|
new ContextMenu(
|
||||||
|
this.element,
|
||||||
|
`[data-ctx-menu="item"]`,
|
||||||
|
[
|
||||||
|
{
|
||||||
|
name: localizer(`RipCrypt.common.edit`),
|
||||||
|
condition: (el) => {
|
||||||
|
const itemId = el.dataset.itemId;
|
||||||
|
return itemId !== ``;
|
||||||
|
},
|
||||||
|
callback: editItemFromElement,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: localizer(`RipCrypt.common.delete`),
|
||||||
|
condition: (el) => {
|
||||||
|
const itemId = el.dataset.itemId;
|
||||||
|
return itemId !== ``;
|
||||||
|
},
|
||||||
|
callback: deleteItemFromElement,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
{ jQuery: false, fixed: true },
|
||||||
|
);
|
||||||
|
};
|
||||||
// #endregion Lifecycle
|
// #endregion Lifecycle
|
||||||
|
|
||||||
// #region Data Prep
|
// #region Data Prep
|
||||||
_preparePartContext(partID, ctx) {
|
async _preparePartContext(partID, ctx) {
|
||||||
|
|
||||||
switch (partID) {
|
switch (partID) {
|
||||||
case `layout`: this._prepareLayoutContext(ctx); break;
|
case `layout`: await this._prepareLayoutContext(ctx); break;
|
||||||
case `image`: this._prepareImageContext(ctx); break;
|
case `image`: await this._prepareImageContext(ctx); break;
|
||||||
case `header`: this._prepareHeaderContext(ctx); break;
|
case `header`: await this._prepareHeaderContext(ctx); break;
|
||||||
case `stats`: this._prepareStatsContext(ctx); break;
|
case `stats`: await this._prepareStatsContext(ctx); break;
|
||||||
case `items`: this._prepareItemsContext(ctx); break;
|
case `items`: await this._prepareItemsContext(ctx); break;
|
||||||
};
|
};
|
||||||
|
|
||||||
return ctx;
|
return ctx;
|
||||||
};
|
};
|
||||||
|
|
||||||
_prepareLayoutContext(ctx) {
|
async _prepareLayoutContext(ctx) {
|
||||||
ctx.imageVisible = true;
|
ctx.imageVisible = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
_prepareImageContext(ctx) {
|
async _prepareImageContext(ctx) {
|
||||||
ctx.url = this.actor.img;
|
ctx.url = this.actor.img;
|
||||||
};
|
};
|
||||||
|
|
||||||
_prepareHeaderContext(ctx) {
|
async _prepareHeaderContext(ctx) {
|
||||||
ctx.name = this.actor.name;
|
ctx.name = this.actor.name;
|
||||||
ctx.description = null; // this.actor.system.description;
|
ctx.description = null; // this.actor.system.description;
|
||||||
};
|
};
|
||||||
|
|
||||||
_prepareStatsContext(ctx) {
|
async _prepareStatsContext(ctx) {
|
||||||
const system = this.actor.system;
|
const system = this.actor.system;
|
||||||
|
|
||||||
const fate = system.fate;
|
const fate = system.fate;
|
||||||
|
|
@ -98,14 +123,45 @@ export class BookGeistSheet extends LaidOutAppMixin(GenericAppMixin(HandlebarsAp
|
||||||
ctx.speed = system.speed;
|
ctx.speed = system.speed;
|
||||||
};
|
};
|
||||||
|
|
||||||
_prepareItemsContext(ctx) {
|
async _prepareItemsContext(ctx) {
|
||||||
ctx.attacks = [];
|
ctx.attacks = [];
|
||||||
ctx.defense = {
|
ctx.defense = {
|
||||||
locations: `None`,
|
locations: `None`,
|
||||||
protection: 0,
|
protection: 0,
|
||||||
shield: false,
|
shield: false,
|
||||||
};
|
};
|
||||||
ctx.traits = [];
|
ctx.traits = []; // Array<{name: string}>
|
||||||
|
|
||||||
|
for (const item of this.actor.items) {
|
||||||
|
switch (item.type) {
|
||||||
|
case `weapon`: {
|
||||||
|
if (!item.system.equipped) { continue };
|
||||||
|
ctx.attacks.push(this._prepareWeapon(item));
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
case `trait`: {
|
||||||
|
ctx.traits.push(this._prepareTrait(item));
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
_prepareWeapon(weapon) {
|
||||||
|
return {
|
||||||
|
uuid: weapon.uuid,
|
||||||
|
name: weapon.name,
|
||||||
|
damage: weapon.system.damage,
|
||||||
|
range: weapon.system.range,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
_prepareTrait(trait) {
|
||||||
|
return {
|
||||||
|
uuid: trait.uuid,
|
||||||
|
name: trait.name,
|
||||||
|
description: trait.system.description,
|
||||||
|
};
|
||||||
};
|
};
|
||||||
// #endregion Data Prep
|
// #endregion Data Prep
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,22 @@
|
||||||
<div>
|
<div>
|
||||||
|
<div class="overview">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
name="name"
|
name="name"
|
||||||
value="{{name}}"
|
value="{{name}}"
|
||||||
>
|
>
|
||||||
|
<div class="grow"></div>
|
||||||
|
Rank
|
||||||
|
<select name="">
|
||||||
|
<option value="novice">0</option>
|
||||||
|
<option value="adept">I</option>
|
||||||
|
<option value="master">II</option>
|
||||||
|
<option value="expert">III</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
{{#if description}}
|
||||||
|
<div class="description">
|
||||||
|
{{{description}}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,8 @@
|
||||||
<div>
|
<div class="img-wrapper">
|
||||||
IMAGE
|
<img
|
||||||
|
src="{{url}}"
|
||||||
|
alt=""
|
||||||
|
data-action="editImage"
|
||||||
|
data-edit="img"
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1 +1,47 @@
|
||||||
<div>ITEMS</div>
|
<div class="items">
|
||||||
|
<div>Attacks</div>
|
||||||
|
<div>
|
||||||
|
{{#each attacks as |attack|}}
|
||||||
|
<div
|
||||||
|
class="attack"
|
||||||
|
data-ctx-menu="item"
|
||||||
|
data-item-id="{{attack.uuid}}"
|
||||||
|
>
|
||||||
|
{{attack.name}}
|
||||||
|
</div>
|
||||||
|
{{else}}
|
||||||
|
Unarmed!
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
<div>Defense</div>
|
||||||
|
<div>
|
||||||
|
Armour
|
||||||
|
{{rc-ifOut defense.protection}}
|
||||||
|
/
|
||||||
|
{{defense.locations}}
|
||||||
|
{{#if defense.shield}}
|
||||||
|
, <span>Shield</span>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
<div>Traits</div>
|
||||||
|
<ul class="traits">
|
||||||
|
{{#each traits as |trait|}}
|
||||||
|
<li
|
||||||
|
class="trait"
|
||||||
|
data-ctx-menu="item"
|
||||||
|
data-item-id="{{trait.uuid}}"
|
||||||
|
>
|
||||||
|
{{trait.name}}
|
||||||
|
{{#if trait.description}}
|
||||||
|
<rc-icon
|
||||||
|
var:fill="currentColor"
|
||||||
|
name="icons/info-circle"
|
||||||
|
data-tooltip="{{trait.description}}"
|
||||||
|
/>
|
||||||
|
{{/if}}
|
||||||
|
</li>
|
||||||
|
{{else}}
|
||||||
|
None
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,98 @@
|
||||||
<div>
|
<div>
|
||||||
<ul>
|
{{log this}}
|
||||||
<li>Path: {{path}}</li>
|
<table>
|
||||||
<li>Grit: {{grit}}</li>
|
<thead>
|
||||||
<li>Gait: {{gait}}</li>
|
<tr>
|
||||||
<li>Grip: {{grip}}</li>
|
<td class="alt">Path</td>
|
||||||
<li>Glim: {{glim}}</li>
|
<td>Grit</td>
|
||||||
<li>Guts: {{guts.value}} / {{guts.max}}</li>
|
<td>Gait</td>
|
||||||
<li>Move: {{speed.move}} / {{speed.run}}</li>
|
<td>Grip</td>
|
||||||
</ul>
|
<td>Glim</td>
|
||||||
|
<td class="alt">Guts</td>
|
||||||
|
<td class="alt">Move</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
class="alt"
|
||||||
|
data-tooltip="{{path.full}}"
|
||||||
|
>
|
||||||
|
{{path.abbv}}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{#if meta.editable}}
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
id="{{meta.idp}}-grit"
|
||||||
|
value="{{grit}}"
|
||||||
|
name="system.ability.grit"
|
||||||
|
>
|
||||||
|
{{else if meta.limited}}
|
||||||
|
???
|
||||||
|
{{else}}
|
||||||
|
{{grit}}
|
||||||
|
{{/if}}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{#if meta.editable}}
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
id="{{meta.idp}}-gait"
|
||||||
|
value="{{gait}}"
|
||||||
|
name="system.ability.gait"
|
||||||
|
>
|
||||||
|
{{else if meta.limited}}
|
||||||
|
???
|
||||||
|
{{else}}
|
||||||
|
{{gait}}
|
||||||
|
{{/if}}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{#if meta.editable}}
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
id="{{meta.idp}}-grip"
|
||||||
|
value="{{grip}}"
|
||||||
|
name="system.ability.grip"
|
||||||
|
>
|
||||||
|
{{else if meta.limited}}
|
||||||
|
???
|
||||||
|
{{else}}
|
||||||
|
{{grip}}
|
||||||
|
{{/if}}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{#if meta.editable}}
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
id="{{meta.idp}}-glim"
|
||||||
|
value="{{glim}}"
|
||||||
|
name="system.ability.glim"
|
||||||
|
>
|
||||||
|
{{else if meta.limited}}
|
||||||
|
???
|
||||||
|
{{else}}
|
||||||
|
{{glim}}
|
||||||
|
{{/if}}
|
||||||
|
</td>
|
||||||
|
<td class="alt">
|
||||||
|
{{#if meta.editable}}
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
id="{{meta.idp}}-guts-value"
|
||||||
|
value="{{guts.value}}"
|
||||||
|
name="system.guts.value"
|
||||||
|
>
|
||||||
|
/ {{guts.max}}
|
||||||
|
{{else if meta.limited}}
|
||||||
|
??/??
|
||||||
|
{{else}}
|
||||||
|
{{guts.value}}/{{guts.max}}
|
||||||
|
{{/if}}
|
||||||
|
</td>
|
||||||
|
<td class="alt">{{speed.move}} / {{speed.run}}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,98 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
|
padding: 8px;
|
||||||
|
color: var(--base-text);
|
||||||
|
background: var(--base-background);
|
||||||
}
|
}
|
||||||
|
|
||||||
.info {
|
.info {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.img-wrapper {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 150px;
|
||||||
|
height: 150px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.overview {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
gap: 4px;
|
||||||
|
|
||||||
|
input {
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
td {
|
||||||
|
border: 1px solid var(--accent-1);
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
input {
|
||||||
|
width: 30px;
|
||||||
|
background: unset;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
thead td {
|
||||||
|
font-weight: bold;
|
||||||
|
border-top-width: 0;
|
||||||
|
|
||||||
|
&:first-of-type, &:last-of-type {
|
||||||
|
border-left-width: 0;
|
||||||
|
border-right-width: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody tr {
|
||||||
|
td:first-of-type, td:last-of-type {
|
||||||
|
border-left-width: 0;
|
||||||
|
border-right-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-of-type td {
|
||||||
|
border-bottom-width: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.alt {
|
||||||
|
background-color: var(--alt-row-background);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.items {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: minmax(0, 1fr) minmax(0, 4fr);
|
||||||
|
grid-template-rows: repeat(3, auto);
|
||||||
|
gap: 2px;
|
||||||
|
|
||||||
|
.traits {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
gap: 8px;
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trait {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
background-color: var(--accent-2);
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 2px 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
@import url("./common.css");
|
||||||
@import url("./AllItemSheetV1/style.css");
|
@import url("./AllItemSheetV1/style.css");
|
||||||
@import url("./CombinedHeroSheet/style.css");
|
@import url("./CombinedHeroSheet/style.css");
|
||||||
@import url("./DelveDiceHUD/style.css");
|
@import url("./DelveDiceHUD/style.css");
|
||||||
|
|
@ -12,21 +13,3 @@
|
||||||
|
|
||||||
@import url("./popover.css");
|
@import url("./popover.css");
|
||||||
@import url("./popovers/AmmoTracker/style.css");
|
@import url("./popovers/AmmoTracker/style.css");
|
||||||
|
|
||||||
.ripcrypt {
|
|
||||||
.window-content {
|
|
||||||
flex: initial;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.StatsCardV1,
|
|
||||||
.SkillsCardV1,
|
|
||||||
.CraftCardV1 {
|
|
||||||
padding: 8px;
|
|
||||||
/* height: 270px; */
|
|
||||||
width: 680px;
|
|
||||||
--col-gap: 2px;
|
|
||||||
--row-gap: 4px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
17
templates/Apps/common.css
Normal file
17
templates/Apps/common.css
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
.ripcrypt {
|
||||||
|
.window-content {
|
||||||
|
flex: initial;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.StatsCardV1,
|
||||||
|
.SkillsCardV1,
|
||||||
|
.CraftCardV1 {
|
||||||
|
padding: 8px;
|
||||||
|
/* height: 270px; */
|
||||||
|
width: 680px;
|
||||||
|
--col-gap: 2px;
|
||||||
|
--row-gap: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue