mirror of
https://github.com/storytold/storyteller-bevy.git
synced 2026-10-13 23:52:55 +00:00
added tabs to side bar, including hierarchy
This commit is contained in:
@@ -53,8 +53,13 @@ $hierarchy-width: 290px;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
display: grid;
|
||||
sts-inspector {}
|
||||
|
||||
|
||||
|
||||
.sidebar, sts-inspector {
|
||||
pointer-events: all;
|
||||
// display: grid;
|
||||
grid-area: sidebar;
|
||||
grid-template-rows: subgrid;
|
||||
z-index: 1;
|
||||
@@ -63,8 +68,8 @@ $hierarchy-width: 290px;
|
||||
|
||||
|
||||
position: relative;
|
||||
padding: var(--padding);
|
||||
padding-left: 0.5rem;
|
||||
// padding: var(--padding);
|
||||
// padding-left: 0.5rem;
|
||||
|
||||
.resize-handle {
|
||||
position: absolute;
|
||||
|
||||
@@ -37,6 +37,7 @@ import "@storyteller/studio-web/studio";
|
||||
import "@storyteller/studio-web/transform-toolbar";
|
||||
import "./anim-editor.element";
|
||||
import "./help.element";
|
||||
import "./inspector.element";
|
||||
import "./temp-video-preview.element";
|
||||
|
||||
import "./app.element.scss";
|
||||
@@ -231,31 +232,7 @@ export class AppElement extends LitElement {
|
||||
<sts-transform-toolbar></sts-transform-toolbar>
|
||||
</div>
|
||||
|
||||
<section
|
||||
${ref(this.#inspectorRef)}
|
||||
class="sidebar"
|
||||
style=${styleMap({
|
||||
width: `${this.inspectorWidth}px`,
|
||||
})}
|
||||
aria-labelledby="sidebar-heading"
|
||||
>
|
||||
<div class="sidebar-header">
|
||||
${this.sidebars.map(({title, name}) => {
|
||||
return html`<sts-button class=${classMap({"current-tab": name === this.currentSidebar, "sidebar-tab": true})}>${title}</sts-button>`
|
||||
})}
|
||||
</div>
|
||||
|
||||
${this.renderSidebar()}
|
||||
|
||||
<div
|
||||
class="resize-handle"
|
||||
${drag({
|
||||
start: this.onPanelResizeStart,
|
||||
end: this.onPanelResizeEnd,
|
||||
move: this.resizeInspectorWidth,
|
||||
})}
|
||||
></div>
|
||||
</section>
|
||||
<sts-inspector></sts-inspector>
|
||||
|
||||
<div class="entity-inspector">
|
||||
<sts-entity-inspector></sts-entity-inspector>
|
||||
|
||||
@@ -1,10 +1,22 @@
|
||||
@use "sass:math";
|
||||
|
||||
:host {
|
||||
// background: red;
|
||||
font-family: "Fira Sans", sans-serif;
|
||||
font-size: 15px;
|
||||
color: #fff;
|
||||
|
||||
label {
|
||||
display: block;
|
||||
margin-bottom: .5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.studio-bubble-options {
|
||||
display: flex;
|
||||
gap: 0.6rem;
|
||||
box-sizing: border-box;
|
||||
overflow-x: scroll;
|
||||
padding: 4px 4px 1rem;
|
||||
}
|
||||
|
||||
*, *::before, *::after {
|
||||
@@ -12,6 +24,7 @@
|
||||
}
|
||||
|
||||
.bubble {
|
||||
// pointer-events: all;
|
||||
position: relative;
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
@@ -26,9 +39,9 @@
|
||||
}
|
||||
|
||||
outline: #FFF2 solid 2px;
|
||||
color: rgba(#fff, 0.75);
|
||||
color: transparent;
|
||||
transition: {
|
||||
property: background-color, outline-color;
|
||||
property: color, background-color, outline-color;
|
||||
duration: 200ms;
|
||||
timing-function: ease;
|
||||
}
|
||||
@@ -49,9 +62,16 @@
|
||||
|
||||
.label {
|
||||
position: relative;
|
||||
// color: transparent;
|
||||
width: 100%;
|
||||
text-wrap: wrap;
|
||||
font: {
|
||||
size: math.div(12, 16) * 1rem;
|
||||
weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: rgba(#fff, 0.75);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,27 +28,30 @@ export class BubbleSelect extends FormFieldBaseElement {
|
||||
}
|
||||
|
||||
protected override render = () => html`
|
||||
${ this.options.map(({ label, value, imageUrl }) => html`
|
||||
<div
|
||||
class=${classMap({
|
||||
"bubble": true,
|
||||
"selected": value === this.value,
|
||||
})}
|
||||
style=${styleMap({
|
||||
"background-image": `url(${imageUrl})`,
|
||||
})}
|
||||
@click=${() => {
|
||||
// this.onChange({ target: { name: this.name, value: itemValue } });
|
||||
this.dispatchEvent(new CustomEvent("value-change", {
|
||||
detail: value,
|
||||
}))
|
||||
} }
|
||||
>
|
||||
<div class="gradient"></div>
|
||||
<span class="label">
|
||||
${ label }
|
||||
</span>
|
||||
</div>`
|
||||
)}
|
||||
<label>Select base style</label>
|
||||
<div class="studio-bubble-options">
|
||||
${ this.options.map(({ label, value, imageUrl }) => html`
|
||||
<div
|
||||
class=${classMap({
|
||||
"bubble": true,
|
||||
"selected": value === this.value,
|
||||
})}
|
||||
style=${styleMap({
|
||||
"background-image": `url(${imageUrl})`,
|
||||
})}
|
||||
@click=${() => {
|
||||
// this.onChange({ target: { name: this.name, value: itemValue } });
|
||||
this.dispatchEvent(new CustomEvent("value-change", {
|
||||
detail: value,
|
||||
}))
|
||||
} }
|
||||
>
|
||||
<div class="gradient"></div>
|
||||
<span class="label">
|
||||
${ label }
|
||||
</span>
|
||||
</div>`
|
||||
)}
|
||||
</div>
|
||||
`
|
||||
}
|
||||
|
||||
@@ -1,5 +1,27 @@
|
||||
.inspector-input-set {
|
||||
label {
|
||||
display: block;
|
||||
color: #fff;
|
||||
margin-bottom: .5rem;
|
||||
}
|
||||
textarea {
|
||||
background: var(--color-panel-item-name-background);
|
||||
border: none;
|
||||
box-sizing: border-box;
|
||||
color: #fff;
|
||||
font-family: "Fira Sans", sans-serif;
|
||||
outline: none;
|
||||
padding: .5rem;
|
||||
border-radius: .5rem;
|
||||
margin-bottom: 1rem;
|
||||
resize: none;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.sidebar-button-row {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
}
|
||||
@@ -154,8 +154,6 @@ export class StyleTab extends LitElement {
|
||||
|
||||
protected override render = (): TemplateResult => html`
|
||||
<section class="inspector-input-set">
|
||||
${ this.vstStyle }
|
||||
<button @click=${ this.thingy }>State</button>
|
||||
<sts-bubble-select
|
||||
.options=${STYLE_OPTIONS}
|
||||
.value=${bind(this, "vstStyle")}
|
||||
@@ -163,6 +161,7 @@ export class StyleTab extends LitElement {
|
||||
|
||||
<label htmlFor="inspector-posPrompt">Positive Prompt</label>
|
||||
<textarea
|
||||
rows="7"
|
||||
id="inspector-posPrompt"
|
||||
name="posPrompt"
|
||||
@input=${ this.inputChange }
|
||||
@@ -171,17 +170,24 @@ export class StyleTab extends LitElement {
|
||||
|
||||
<label htmlFor="inspector-posPrompt">Negative Prompt</label>
|
||||
<textarea
|
||||
rows="7"
|
||||
id="inspector-negPrompt"
|
||||
name="negPrompt"
|
||||
placeholder="Type here to filter out the things you don’t want in the scene..."
|
||||
@input=${ this.inputChange }
|
||||
.value=${ this.negPrompt }
|
||||
></textarea>
|
||||
|
||||
<sts-button
|
||||
@click=${this.compositorEnqueue(this.sceneToken)}
|
||||
>
|
||||
Generate your movie
|
||||
</sts-button>
|
||||
<div class="sidebar-button-row">
|
||||
<sts-button primary
|
||||
@click=${this.compositorEnqueue(this.sceneToken)}
|
||||
>
|
||||
Generate your movie
|
||||
</sts-button>
|
||||
</div>
|
||||
<!-- debugging stuff -V
|
||||
${ this.vstStyle }
|
||||
<button @click=${ this.thingy }>State</button> -->
|
||||
</section>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
:host {
|
||||
font-family: "Fira Sans", sans-serif;
|
||||
font-size: 15px;
|
||||
color: #fff;
|
||||
|
||||
label {
|
||||
display: block;
|
||||
margin-bottom: .5rem;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.studio-sidebar-frame {
|
||||
padding: 1rem;
|
||||
}
|
||||
+21
-16
@@ -1,16 +1,18 @@
|
||||
import { LitElement, type PropertyValues, html, nothing, unsafeCSS } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators.js";
|
||||
import { createRef, ref } from "lit/directives/ref.js";
|
||||
import "@storyteller/studio-ui/tree";
|
||||
import "./tabs.element";
|
||||
import "./bubble-select.element";
|
||||
import "./inspector-tabs/style-tab";
|
||||
import styles from "./inspector.element.scss?inline";
|
||||
import "@storyteller/studio-ui/button";
|
||||
import "@storyteller/studio-web/scene-hierarchy";
|
||||
|
||||
// const abc = "word";
|
||||
|
||||
enum InspectorMode {
|
||||
Properties,
|
||||
Hierarchy,
|
||||
Style
|
||||
}
|
||||
|
||||
@@ -20,10 +22,11 @@ export class Inspector extends LitElement {
|
||||
@state() selectedTab = InspectorMode.Style;
|
||||
@property() sceneToken = "";
|
||||
@property() styleMediaToken = "";
|
||||
#hierarchyRef = createRef<SceneHierarchyElement>();
|
||||
|
||||
tabs = [{
|
||||
label: "Properties",
|
||||
value: InspectorMode.Properties
|
||||
label: "Hierarchy",
|
||||
value: InspectorMode.Hierarchy
|
||||
},{
|
||||
label: "Style",
|
||||
value: InspectorMode.Style
|
||||
@@ -33,28 +36,30 @@ export class Inspector extends LitElement {
|
||||
console.log("🏎️", this.styleMediaToken);
|
||||
}
|
||||
|
||||
propertiesTab = html`<div>Properties</div>`;
|
||||
propertiesTab = html`<sts-scene-hierarchy
|
||||
${ref(this.#hierarchyRef)}
|
||||
class="hierarchy sidebar-view"
|
||||
></sts-scene-hierarchy>`;
|
||||
|
||||
tabContent = () => {
|
||||
switch (this.selectedTab) {
|
||||
case InspectorMode.Properties: return this.propertiesTab;
|
||||
case InspectorMode.Hierarchy: return this.propertiesTab;
|
||||
case InspectorMode.Style: return html`<sts-style-tab .sceneToken=${this.sceneToken}></sts-style-tab>`;
|
||||
}
|
||||
}
|
||||
|
||||
protected override render = () => html`
|
||||
<div class="studio-inspector">
|
||||
<button @click=${ this.thingy }>State</button>
|
||||
<sts-tabs
|
||||
.onChange=${ ({ target }: any) => {
|
||||
<sts-tabs
|
||||
.onChange=${
|
||||
({ target }: any) => {
|
||||
this.selectedTab = target.value;
|
||||
} }
|
||||
.tabs=${this.tabs}
|
||||
.value=${this.selectedTab}
|
||||
></sts-tabs>
|
||||
<div>
|
||||
${ this.tabContent() }
|
||||
</div>
|
||||
}
|
||||
}
|
||||
.tabs=${this.tabs}
|
||||
.value=${this.selectedTab}
|
||||
></sts-tabs>
|
||||
<div class="studio-sidebar-frame">
|
||||
${ this.tabContent() }
|
||||
</div>
|
||||
`
|
||||
}
|
||||
@@ -1,20 +1,35 @@
|
||||
:host {
|
||||
font-family: "Fira Sans", sans-serif;
|
||||
font-size: 15px;
|
||||
// margin-bottom: ;
|
||||
}
|
||||
|
||||
.studio-tabs {
|
||||
// background: red;
|
||||
display: flex;
|
||||
appearance: none;
|
||||
display: grid;
|
||||
grid-auto-flow: column;
|
||||
grid-auto-columns: 1fr;
|
||||
list-style: none;
|
||||
margin-block-start: 0px;
|
||||
margin-block-end: 0px;
|
||||
width: 100%;
|
||||
padding-inline-start: 0px;
|
||||
|
||||
li {
|
||||
.studio-tabs-tab {
|
||||
|
||||
// width: max-content;
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
// flex: 1;
|
||||
border: none;
|
||||
padding: 1rem 1.4rem;
|
||||
padding: 1rem;
|
||||
border-bottom: 4px solid transparent;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
cursor: pointer;
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
border-bottom: 4px solid var(--color-toolbar-background-light);
|
||||
|
||||
&.selected-tab {
|
||||
color: #fff;
|
||||
border-bottom: 4px solid #e66462;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,15 +12,18 @@ export class Tabs extends LitElement {
|
||||
@property() value = "";
|
||||
|
||||
protected override render = () => html`
|
||||
<ul class="studio-tabs">
|
||||
<div class="studio-tabs">
|
||||
${ this.tabs.map(({ label, value: itemValue },i) =>
|
||||
html`<li
|
||||
class=${ itemValue === this.value ? "selected-tab" : "" }
|
||||
html`<div
|
||||
class=${
|
||||
`studio-tabs-tab${ itemValue === this.value ? " selected-tab" : "" }`
|
||||
}
|
||||
@click=${ ({ target }: any) => {
|
||||
console.log("💎");
|
||||
this.onChange({ target: { name: this.name, value: itemValue } });
|
||||
} }
|
||||
>${ label }</li>`
|
||||
>${ label }</div>`
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
Reference in New Issue
Block a user