/** * 3D Foundation Project * Copyright 2024 Smithsonian Institution * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import "@ff/ui/Splitter"; import "@ff/ui/Button"; import "./PropertyView"; import CVActionsTask from "../../components/CVActionsTask"; import { TaskView, customElement, html, property } from "../../components/CVTask"; import List from "client/../../libs/ff-ui/source/List"; import { EActionPlayStyle, EActionTrigger, EActionType, IAction, IAudioClip, TActionType } from "client/schema/meta"; //import Notification from "@ff/ui/Notification"; import CVAnnotationView from "client/components/CVAnnotationView"; //////////////////////////////////////////////////////////////////////////////// @customElement("sv-actions-task-view") export default class ActionsTaskView extends TaskView { protected connected() { super.connected(); this.task.on("update", this.onUpdate, this); } protected disconnected() { this.task.off("update", this.onUpdate, this); super.disconnected(); } protected render() { if(!this.task.actionManager) { return; } const ins = this.task.ins; const node = this.activeNode; const actionList = node && node.hasComponent(CVAnnotationView) && this.task.actions; if (!actionList) { return html`
Please select a model node to edit its actions.
`; } const accessibilityNotice = ins.type.value === EActionType.PlayAudio && (ins.trigger.value === EActionTrigger.OnTourStep || ins.trigger.value === EActionTrigger.OnLoad) ? html`
Trigger/Action combination not supported for accessibility.
` : null; const actionElement = actionList.find((action) => action.id === ins.activeId.value); const audioActionView = ins.type.value === EActionType.PlayAudio ? html` ` : null; const animClamp = ins.style.value === EActionPlayStyle.Single ? html` ` : null; const animActionView = ins.type.value === EActionType.PlayAnimation ? html` ${animClamp} ` : null; const annoView = ins.trigger.value === EActionTrigger.OnAnnotation ? html` ` : null; const annoActionView = ins.type.value === EActionType.ShowAnnotation || ins.type.value === EActionType.HideAnnotation || ins.type.value === EActionType.ToggleAnnotation ? html` ` : null; const tourView = ins.trigger.value === EActionTrigger.OnTourStep ? html` ` : null; const actionEventView = ins.trigger.value === EActionTrigger.OnActionEnd || ins.trigger.value === EActionTrigger.OnActionBegin ? html` ` : null; const detailView = actionElement ? html`
${accessibilityNotice} ${annoView} ${tourView} ${actionEventView} ${audioActionView} ${animActionView} ${annoActionView}
` : null; return html`
Name
Type/Trigger
${detailView}
`; } protected onClickCreate() { this.task.ins.create.set(); } protected onClickDelete() { this.task.ins.delete.set(); } protected onSelectAction(event: ISelectActionEvent) { this.task.ins.activeId.setValue(event.detail.action ? event.detail.action.id : ""); this.onUpdate(); } } //////////////////////////////////////////////////////////////////////////////// interface ISelectActionEvent extends CustomEvent { target: ActionList; detail: { action: IAction; index: number; } } @customElement("sv-action-list") export class ActionList extends List { @property({ attribute: false }) selectedItem: IAction = null; protected firstConnected() { super.firstConnected(); this.classList.add("sv-action-list"); } protected renderItem(item: IAction) { return html`
${item.name}
${item.type}/${item.trigger}
`; } protected isItemSelected(item: IAction) { return item === this.selectedItem; } protected onClickItem(event: MouseEvent, item: IAction, index: number) { this.dispatchEvent(new CustomEvent("select", { detail: { action: item, index } })); } protected onClickEmpty(event: MouseEvent) { this.dispatchEvent(new CustomEvent("select", { detail: { action: null, index: -1 } })); } }