import { bind, inject, observe } from "@storyteller/framework"; import * as studio from "@storyteller/studio"; import { BlockingCommand, StudioMode, TransformSpace, TransformType } from "@storyteller/studio"; import { SCENE_DATA_PROVIDER, STUDIO_PARAMS, type SceneDataProvider, type StudioParams, } from "@storyteller/studio-web"; import { ButtonElement } from "@storyteller/studio-ui/button"; import { LitElement, PropertyValues, TemplateResult, html, nothing } from "lit"; import { customElement, state } from "lit/decorators.js"; import { createRef, ref } from "lit/directives/ref.js"; import { ANIM_TIMELINE_CONTROLLER, type AnimTimelineController, } from "./anim-timeline-controller.element"; import "@storyteller/studio-web/entity-inspector"; import "@storyteller/studio-web/studio"; import "@storyteller/studio-ui/button"; import "@storyteller/studio-ui/forms/radio"; import "@storyteller/studio-ui/forms/select"; import "@storyteller/studio-ui/toolbar"; import "./anim-timeline-controls.element"; import "./studio-viewport.element.scss"; import { match } from "@storyteller/utility"; @customElement("sts-studio-viewport") export class StudioViewportElement extends LitElement { @inject(STUDIO_PARAMS) _params!: StudioParams; @observe(["selectedEntity", "selectedObject"]) @inject(SCENE_DATA_PROVIDER) _sceneData!: SceneDataProvider; @observe(["tracks"]) @inject(ANIM_TIMELINE_CONTROLLER) _timeline!: AnimTimelineController; @state() _transformSpace = TransformSpace.Local; @state() _transformType = TransformType.Translate; get #selectedEntityInTracklist() { return ( this._sceneData.selectedEntity != null && this._sceneData.selectedEntity in this._timeline.tracks ); } #fileTriggerRef = createRef(); #mediaLibraryTriggerRef = createRef(); #helpDialogTriggerRef = createRef(); get #selectedObject() { return this._sceneData.selectedObject; } protected override createRenderRoot = () => this; protected override update(changes: PropertyValues): void { if (changes.has("_transformSpace")) studio.setTransformSpace(this._transformSpace); if (changes.has("_transformType")) studio.setTransformType(this._transformType); super.update(changes); } protected override render(): TemplateResult { return html` ${match (this._params.mode, { [StudioMode.Headless]: () => nothing, [StudioMode.Viewer]: () => html` { // TODO }} > Help `, [StudioMode.Editor]: () => html`
studio.dispatchBlockingCommand(BlockingCommand.Cube)} > studio.dispatchBlockingCommand(BlockingCommand.Cylinder)} > studio.dispatchBlockingCommand(BlockingCommand.Sphere)} > studio.dispatchBlockingCommand(BlockingCommand.Torus)} >
Local Global Translate Rotate Scale
Stylize
Switch to Camera View
${this.#selectedObject != null ? html`
${this.#selectedObject.icon != null ? html` ` : nothing}

${this.#selectedObject.name}

Swap object
${this.#selectedEntityInTracklist ? html` this._timeline.addKeyframe()} > Add Keyframe ` : this._sceneData.selectedEntity != null ? html` this._timeline.addTrack(this._sceneData.selectedEntity!)} > Add to Timeline ` : nothing}
` : nothing} `, })}
{ // TODO }} > New scene { // TODO }} > New scene from template...
{ // TODO: Should we show a spinner here while we're waiting? // Toast message for success/failure? // TODO: Need to disable this when the scene is not ours studio.saveScene(); }} > Save scene { // TODO }} > Save scene as copy...
`; } }