Proof-of-concept inspector mutations

This commit is contained in:
Danny McGee
2024-03-21 06:15:09 -04:00
parent 0c52ea6eec
commit 46d784c695
7 changed files with 145 additions and 47 deletions
@@ -1,3 +1,4 @@
import * as studio from "@storyteller/studio";
import { bind } from "@storyteller/framework";
import { LitElement, PropertyValues, type TemplateResult, html, unsafeCSS } from "lit";
import { customElement, property } from "lit/decorators.js";
@@ -13,8 +14,20 @@ export class NameInspectorElement extends LitElement {
@property() value = "";
protected override updated(changes: PropertyValues<this>): void {
if (changes.has("value"))
console.log("New value:", this.value);
// FIXME: `Name` component needs special handling due to:
// 1. Its `hash` field, which doesn't get updated by just directly
// mutating the `name` field
// 2. Its use in our hierarchy. We'll need to add some logic to check
// for changed names on existing entities and notify the frontend so
// the hierarchy can reflect the new value.
// if (changes.has("value")) {
// studio.updateComponentField({
// component: "bevy_core::name::Name",
// reflectPath: "name",
// value: this.value,
// });
// }
super.updated(changes);
}
@@ -17,7 +17,17 @@ h4 {
margin: 0 0 0.25rem;
}
fieldset {
.fieldset {
position: relative;
padding-block-start: math.div(14, 16) + 0.333rem !important;
legend {
position: absolute;
inset-block-start: 0;
}
}
fieldset, .fieldset {
display: flex;
width: 100%;
padding: 0;
@@ -33,14 +43,10 @@ fieldset {
input {
appearance: textfield;
width: math.div(1, 3) * 100%;
padding: 0.5rem;
border-radius: 0.25rem;
background: #0004;
border: 1px solid #FFF2 {
left: 4px solid #FFF2;
}
border: 1px solid #FFF2;
color: #FFFC;
transition: {
property: background-color, border-color, color;
@@ -60,6 +66,29 @@ fieldset {
color: #FFFF;
}
&::-webkit-outer-spin-button,
&::-webkit-inner-spin-button {
appearance: none;
margin: 0;
}
}
sts-text-field::part(input) {
flex: unset;
width: 100%;
&::-webkit-outer-spin-button,
&::-webkit-inner-spin-button {
appearance: none;
margin: 0;
}
}
input, sts-text-field {
padding: 0.5rem;
width: math.div(1, 3) * 100%;
border-left-width: 4px;
&:nth-of-type(1) {
border-left-color: rgb(220, 53, 69);
&:focus {
@@ -78,11 +107,5 @@ fieldset {
border-left-color: rgb(47, 131, 255);
}
}
&::-webkit-outer-spin-button,
&::-webkit-inner-spin-button {
appearance: none;
margin: 0;
}
}
}
@@ -1,3 +1,4 @@
import * as studio from "@storyteller/studio"
import { LitElement, html, unsafeCSS } from "lit";
import { customElement, property } from "lit/decorators.js";
import { type Quat, type Vec3 } from "./inspector.types";
@@ -17,27 +18,76 @@ export class TransformInspectorElement extends LitElement {
@property({ attribute: false })
scale: Vec3 = { x: 1, y: 1, z: 1 };
updateField(reflectPath: `${"translation"|"rotation"|"scale"}.${"x"|"y"|"z"}`) {
return ({ detail }: CustomEvent<string>) => {
const value = parseFloat(detail);
if (Number.isFinite(value) && !Number.isNaN(value)) {
studio.updateComponentField({
component: "bevy_transform::components::transform::Transform",
reflectPath,
value,
});
}
}
}
protected override render = () => html`
<!-- TODO -->
<h4>Transform</h4>
<fieldset>
<div class="fieldset" role="group">
<legend>Translation</legend>
<input type="number" value=${this.translation.x.toFixed(3)} />
<input type="number" value=${this.translation.y.toFixed(3)} />
<input type="number" value=${this.translation.z.toFixed(3)} />
</fieldset>
<fieldset>
<sts-text-field
type="number"
.value=${this.translation.x.toFixed(3)}
@value-change=${this.updateField("translation.x")}
></sts-text-field>
<sts-text-field
type="number"
.value=${this.translation.y.toFixed(3)}
@value-change=${this.updateField("translation.y")}
></sts-text-field>
<sts-text-field
type="number"
.value=${this.translation.z.toFixed(3)}
@value-change=${this.updateField("translation.z")}
></sts-text-field>
</div>
<div class="fieldset" role="group">
<legend>Rotation</legend>
<input type="number" value=${this.rotation.x.toFixed(3)} />
<input type="number" value=${this.rotation.y.toFixed(3)} />
<input type="number" value=${this.rotation.z.toFixed(3)} />
<!-- TODO: This is not how quaternions work lol -->
<sts-text-field
type="number"
.value=${this.rotation.x.toFixed(3)}
@value-change=${this.updateField("rotation.x")}
></sts-text-field>
<sts-text-field
type="number"
.value=${this.rotation.y.toFixed(3)}
@value-change=${this.updateField("rotation.y")}
></sts-text-field>
<sts-text-field
type="number"
.value=${this.rotation.z.toFixed(3)}
@value-change=${this.updateField("rotation.z")}
></sts-text-field>
<!-- <input type="number" value=${this.rotation.w.toFixed(3)} /> -->
</fieldset>
<fieldset>
</div>
<div class="fieldset" role="group">
<legend>Scale</legend>
<input type="number" value=${this.scale.x.toFixed(3)} />
<input type="number" value=${this.scale.y.toFixed(3)} />
<input type="number" value=${this.scale.z.toFixed(3)} />
</fieldset>
<sts-text-field
type="number"
.value=${this.scale.x.toFixed(3)}
@value-change=${this.updateField("scale.x")}
></sts-text-field>
<sts-text-field
type="number"
.value=${this.scale.y.toFixed(3)}
@value-change=${this.updateField("scale.y")}
></sts-text-field>
<sts-text-field
type="number"
.value=${this.scale.z.toFixed(3)}
@value-change=${this.updateField("scale.z")}
></sts-text-field>
</div>
`;
}
@@ -6,7 +6,7 @@ import {
type EntityMultiSpawnEvent,
type EntitySelectEvent,
type EntitySpawnEvent,
type InspectorChanged,
type InspectorChangedEvent,
} from "@storyteller/studio";
import { TREE_SELECTION_PROVIDER, TreeSelectionProvider } from "@storyteller/studio-ui/tree";
import { match } from "@storyteller/utility";
@@ -109,7 +109,7 @@ export class SceneDataProviderElement
}
@on("window:inspector-changed")
onInspectorChanged({ detail: json }: InspectorChanged): void {
onInspectorChanged({ detail: json }: InspectorChangedEvent): void {
this._components = json ? JSON.parse(json) : [];
}