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 { LaidOutAppMixin } from "../mixins/LaidOutAppMixin.mjs";
|
||||
import { localizer } from "../../utils/Localizer.mjs";
|
||||
import { editItemFromElement, deleteItemFromElement } from "../utils.mjs";
|
||||
|
||||
const { HandlebarsApplicationMixin } = foundry.applications.api;
|
||||
const { ActorSheetV2 } = foundry.applications.sheets;
|
||||
|
||||
export class BookGeistSheet extends LaidOutAppMixin(GenericAppMixin(HandlebarsApplicationMixin(ActorSheetV2))) {
|
||||
export class BookGeistSheet extends
|
||||
LaidOutAppMixin(
|
||||
GenericAppMixin(
|
||||
HandlebarsApplicationMixin(
|
||||
ActorSheetV2,
|
||||
))) {
|
||||
// #region Options
|
||||
static DEFAULT_OPTIONS = {
|
||||
classes: [
|
||||
`ripcrypt--actor`,
|
||||
`BookGeistSheet`,
|
||||
],
|
||||
// position: {
|
||||
// width: ``,
|
||||
// height: ``,
|
||||
// },
|
||||
position: {
|
||||
width: `auto`,
|
||||
height: `auto`,
|
||||
},
|
||||
window: {
|
||||
resizable: true,
|
||||
},
|
||||
|
|
@ -31,52 +37,71 @@ export class BookGeistSheet extends LaidOutAppMixin(GenericAppMixin(HandlebarsAp
|
|||
root: true,
|
||||
template: filePath(`templates/Apps/BookGeistSheet/layout.hbs`),
|
||||
},
|
||||
image: {
|
||||
template: filePath(`templates/Apps/BookGeistSheet/image.hbs`),
|
||||
},
|
||||
header: {
|
||||
template: filePath(`templates/Apps/BookGeistSheet/header.hbs`),
|
||||
},
|
||||
stats: {
|
||||
template: filePath(`templates/Apps/BookGeistSheet/stats.hbs`),
|
||||
},
|
||||
items: {
|
||||
template: filePath(`templates/Apps/BookGeistSheet/items.hbs`),
|
||||
},
|
||||
image: { template: filePath(`templates/Apps/BookGeistSheet/image.hbs`) },
|
||||
header: { 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
|
||||
|
||||
// #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
|
||||
|
||||
// #region Data Prep
|
||||
_preparePartContext(partID, ctx) {
|
||||
async _preparePartContext(partID, ctx) {
|
||||
|
||||
switch (partID) {
|
||||
case `layout`: this._prepareLayoutContext(ctx); break;
|
||||
case `image`: this._prepareImageContext(ctx); break;
|
||||
case `header`: this._prepareHeaderContext(ctx); break;
|
||||
case `stats`: this._prepareStatsContext(ctx); break;
|
||||
case `items`: this._prepareItemsContext(ctx); break;
|
||||
case `layout`: await this._prepareLayoutContext(ctx); break;
|
||||
case `image`: await this._prepareImageContext(ctx); break;
|
||||
case `header`: await this._prepareHeaderContext(ctx); break;
|
||||
case `stats`: await this._prepareStatsContext(ctx); break;
|
||||
case `items`: await this._prepareItemsContext(ctx); break;
|
||||
};
|
||||
|
||||
return ctx;
|
||||
};
|
||||
|
||||
_prepareLayoutContext(ctx) {
|
||||
async _prepareLayoutContext(ctx) {
|
||||
ctx.imageVisible = true;
|
||||
};
|
||||
|
||||
_prepareImageContext(ctx) {
|
||||
async _prepareImageContext(ctx) {
|
||||
ctx.url = this.actor.img;
|
||||
};
|
||||
|
||||
_prepareHeaderContext(ctx) {
|
||||
async _prepareHeaderContext(ctx) {
|
||||
ctx.name = this.actor.name;
|
||||
ctx.description = null; // this.actor.system.description;
|
||||
};
|
||||
|
||||
_prepareStatsContext(ctx) {
|
||||
async _prepareStatsContext(ctx) {
|
||||
const system = this.actor.system;
|
||||
|
||||
const fate = system.fate;
|
||||
|
|
@ -98,14 +123,45 @@ export class BookGeistSheet extends LaidOutAppMixin(GenericAppMixin(HandlebarsAp
|
|||
ctx.speed = system.speed;
|
||||
};
|
||||
|
||||
_prepareItemsContext(ctx) {
|
||||
async _prepareItemsContext(ctx) {
|
||||
ctx.attacks = [];
|
||||
ctx.defense = {
|
||||
locations: `None`,
|
||||
protection: 0,
|
||||
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
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,22 @@
|
|||
<div>
|
||||
<div class="overview">
|
||||
<input
|
||||
type="text"
|
||||
name="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>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,8 @@
|
|||
<div>
|
||||
IMAGE
|
||||
<div class="img-wrapper">
|
||||
<img
|
||||
src="{{url}}"
|
||||
alt=""
|
||||
data-action="editImage"
|
||||
data-edit="img"
|
||||
>
|
||||
</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>
|
||||
<ul>
|
||||
<li>Path: {{path}}</li>
|
||||
<li>Grit: {{grit}}</li>
|
||||
<li>Gait: {{gait}}</li>
|
||||
<li>Grip: {{grip}}</li>
|
||||
<li>Glim: {{glim}}</li>
|
||||
<li>Guts: {{guts.value}} / {{guts.max}}</li>
|
||||
<li>Move: {{speed.move}} / {{speed.run}}</li>
|
||||
</ul>
|
||||
{{log this}}
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<td class="alt">Path</td>
|
||||
<td>Grit</td>
|
||||
<td>Gait</td>
|
||||
<td>Grip</td>
|
||||
<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>
|
||||
|
|
|
|||
|
|
@ -3,11 +3,98 @@
|
|||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 4px;
|
||||
padding: 8px;
|
||||
color: var(--base-text);
|
||||
background: var(--base-background);
|
||||
}
|
||||
|
||||
.info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
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("./CombinedHeroSheet/style.css");
|
||||
@import url("./DelveDiceHUD/style.css");
|
||||
|
|
@ -12,21 +13,3 @@
|
|||
|
||||
@import url("./popover.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