UI styling, main workspace layout (#119)

This commit is contained in:
Danny McGee
2024-04-05 20:15:09 -04:00
committed by GitHub
parent c5a0250d9f
commit bfc638b644
57 changed files with 2004 additions and 694 deletions
+73 -132
View File
@@ -1,14 +1,14 @@
import { drag, on, provide } from "@storyteller/framework";
import * as studio from "@storyteller/studio";
import {
type SceneSavedEvent,
type SceneStateEvent,
SceneState,
StudioMode,
type DebugModeToggled,
} from "@storyteller/studio";
import { ButtonElement } from "@storyteller/studio-ui/button";
import { DialogElement } from "@storyteller/studio-ui/dialog";
import {
STUDIO_PARAMS,
SceneHierarchyElement,
StorytellerApi,
StorytellerLocalApi,
@@ -18,10 +18,9 @@ import {
} from "@storyteller/studio-web";
import { match } from "@storyteller/utility";
import { LitElement, TemplateResult, html, nothing } from "lit";
import { customElement, property, state } from "lit/decorators.js";
import { customElement, state } from "lit/decorators.js";
import { classMap } from "lit/directives/class-map.js";
import { createRef, ref } from "lit/directives/ref.js";
import { styleMap } from "lit/directives/style-map.js";
import "@storyteller/studio-ui/button";
import "@storyteller/studio-ui/dialog";
@@ -39,7 +38,9 @@ import "@storyteller/studio-web/scene-hierarchy";
import "@storyteller/studio-web/studio";
import "@storyteller/studio-web/transform-toolbar";
import "./anim-editor.element";
import "./anim-timeline-controller.element";
import "./help.element";
import "./studio-viewport.element";
import "./temp-video-preview.element";
import "./app.element.scss";
@@ -49,12 +50,16 @@ import "./app.element.scss";
token: StorytellerApi,
provide() { return this.api; }
})
@provide({
token: STUDIO_PARAMS,
provide() { return this.params; }
})
export class AppElement extends LitElement {
@state() showHelp = false;
@state() loading = true;
@state() resizingPanel = false;
@state() inspectorWidth = 320;
// @state() resizingPanel = false;
// @state() inspectorWidth = 320;
@state() debugMode = false;
@@ -62,16 +67,13 @@ export class AppElement extends LitElement {
@state() currentSidebar : string = 'hierarchy';
@property({ attribute: false }) api: StorytellerApi = new StorytellerApi(mockApi ? new StorytellerLocalApi() : new StorytellerRemoteApi());
api = new StorytellerApi(mockApi ? new StorytellerLocalApi() : new StorytellerRemoteApi());
params = new StudioURLParams();
#addToSceneButtonRef = createRef<ButtonElement>();
#videoStylePreviewBtnRef = createRef<ButtonElement>();
#mediaLibraryRef = createRef<DialogElement>();
#inspectorRef = createRef<HTMLDivElement>();
#hierarchyRef = createRef<SceneHierarchyElement>();
#params = new StudioURLParams();
protected override createRenderRoot(): Element | ShadowRoot {
return this;
}
@@ -80,7 +82,7 @@ export class AppElement extends LitElement {
async onSceneSaved({ detail: scene }: SceneSavedEvent): Promise<void> {
try {
const file = new File([scene], "scene.scn.ron", { type: "text/ron" });
const token = await this.api.createScene(file);
this.dispatchEvent(new CustomEvent("scene-uploaded", {
@@ -88,7 +90,7 @@ export class AppElement extends LitElement {
bubbles: true,
composed: true,
}));
}
catch (err) {
console.error(err);
@@ -106,22 +108,18 @@ export class AppElement extends LitElement {
}
@on("window:debug-mode-toggled")
onDebugModeToggled({detail: { debugModeActive }}: studio.DebugModeToggled ): void {
onDebugModeToggled({detail: { debugModeActive }}: DebugModeToggled ): void {
this.debugMode = debugModeActive;
}
onPanelResizeStart(): void {
this.resizingPanel = true;
}
// onPanelResizeEnd(): void {
// this.resizingPanel = false;
// }
onPanelResizeEnd(): void {
this.resizingPanel = false;
}
resizeInspectorWidth(event: PointerEvent): void {
const updated = this.inspectorWidth - event.movementX;
this.inspectorWidth = Math.max(Math.min(updated, 1024), 128);
}
// resizeInspectorWidth(event: PointerEvent): void {
// const updated = this.inspectorWidth - event.movementX;
// this.inspectorWidth = Math.max(Math.min(updated, 1024), 128);
// }
toggleHelp(): void {
this.showHelp = !this.showHelp;
@@ -140,134 +138,77 @@ export class AppElement extends LitElement {
protected override render() {
return html`
<sts-canvas-provider class=${classMap({"app-root": true, "debug-mode": this.debugMode})}>
<sts-canvas-provider>
<sts-scene-data-provider>
<sts-overlay-provider>
<sts-anim-timeline-controller>
<sts-overlay-provider
class=${classMap({
"app-root": true,
"debug-mode": this.debugMode,
})}
>
<sts-iframe-messaging-bridge></sts-iframe-messaging-bridge>
${this.#params.mode === StudioMode.Editor ? html`
<sts-add-to-scene-menu
.trigger=${this.#addToSceneButtonRef}
@open-media-library=${() => {
this.#mediaLibraryRef.value?.open();
}}
></sts-add-to-scene-menu>
<sts-dialog
${ref(this.#mediaLibraryRef)}
tag="sts-media-library-dialog"
nonBlocking
></sts-dialog>
` : html`<></>`}
<div class="wrapper" style=${styleMap({ "--sidebar-width": `${this.inspectorWidth}px` })}>
<!-- Scene view -->
<sts-studio
class=${classMap({
"studio-scene": true,
"block-pointer-events": this.resizingPanel,
})}
.objectId=${this.#params.objectId}
.bvhPath=${this.#params.bvh}
.mixamoPath=${this.#params.mixamo}
.sceneImport=${this.#params.sceneImport}
.storytellerScene=${this.#params.scene}
.skyboxId=${this.#params.skybox ?? "test_scene"}
.mode=${this.#params.mode}
></sts-studio>
<!-- Actions toolbar -->
<sts-toolbar class="action-toolbar">
<sts-toolbar-group>
${this.#params.mode === StudioMode.Editor ? html`
<sts-button
@click=${() => studio.saveScene()}
>
Save Scene
</sts-button>
` : nothing}
<sts-button
class=${classMap({ active: this.showHelp })}
@click=${this.toggleHelp}
>
Help
</sts-button>
</sts-toolbar-group>
</sts-toolbar>
<sts-studio-viewport class="viewport"></sts-studio-viewport>
<!-- Studio-mode-only elements -->
${this.#params.mode === StudioMode.Editor ? html`
<div class="transform-toolbar">
<sts-button
${ref(this.#addToSceneButtonRef)}
icon="plus-large"
class="add-to-scene-dropdown"
>
</sts-button>
<sts-button
${ref(this.#videoStylePreviewBtnRef)}
icon="films"
class="video-style-preview-dropdown"
>
</sts-button>
<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>
<div class="entity-inspector">
<sts-entity-inspector></sts-entity-inspector>
${this.params.mode === StudioMode.Editor ? html`
<section
${ref(this.#inspectorRef)}
class="sidebar"
aria-labelledby="sidebar-heading"
>
<div class="sidebar-header">
${this.sidebars.map(({title, name}) => html`
<sts-button
class=${classMap({
"current-tab": name === this.currentSidebar,
"sidebar-tab": true
})}
>
${title}
</sts-button>
`)}
</div>
<sts-anim-editor
class="timeline"
style=${styleMap({
right: `${this.inspectorWidth + 32}px`
})}
></sts-anim-editor>
${this.renderSidebar()}
<!-- <div
class="resize-handle"
${/*drag({
start: this.onPanelResizeStart,
end: this.onPanelResizeEnd,
move: this.resizeInspectorWidth,
})*/ nothing}
></div> -->
</section>
<!-- TODO
<div class="entity-inspector">
<sts-entity-inspector></sts-entity-inspector>
</div>
-->
<sts-anim-editor class="timeline"></sts-anim-editor>
` : nothing}
<!-- Dialogs and modals -->
<sts-temp-video-preview
.trigger=${ this.#videoStylePreviewBtnRef }>
</sts-temp-video-preview>
<!-- Dialogs and modals -->
${this.showHelp ? html`
<div class="help">
<sts-help></sts-help>
<div class="help">
<sts-help></sts-help>
</div>
` : nothing}
</div>
${this.loading ? html`
<sts-loading></sts-loading>
` : nothing}
</sts-overlay-provider>
</sts-anim-timeline-controller>
</sts-scene-data-provider>
</sts-canvas-provider>
`;