import { html, nothing } from "lit" import ElementFactory from "../../element/ElementFactory.js" import ISelectableDraggableTemplate from "../ISelectableDraggableTemplate.js" import SVGIcon from "../../SVGIcon.js" import Utility from "../../Utility.js" /** * @typedef {import("../../element/NodeElement.js").default} NodeElement * @typedef {import("../../element/PinElement.js").default} PinElement * @typedef {import("../../element/PinElement.js").PinElementConstructor} PinElementConstructor * @typedef {import("lit").PropertyValues} PropertyValues */ /** @extends {ISelectableDraggableTemplate} */ export default class NodeTemplate extends ISelectableDraggableTemplate { /** @typedef {typeof NodeTemplate} NodeTemplateConstructor */ #hasSubtitle = false static nodeStyleClasses = ["ueb-node-style-default"] toggleAdvancedDisplayHandler = () => { this.element.toggleShowAdvancedPinDisplay() this.element.requestUpdate() this.element.updateComplete.then(() => this.element.acknowledgeReflow()) } /** @param {NodeElement} element */ initialize(element) { super.initialize(element) this.element.classList.add(.../** @type {NodeTemplateConstructor} */(this.constructor).nodeStyleClasses) this.element.style.setProperty("--ueb-node-color", this.getColor().cssText) } getColor() { return this.element.entity.nodeColor() } render() { return html`
${this.renderTop()}
${this.element.entity.isDevelopmentOnly() ? html`
Development Only
` : nothing} ${this.element.advancedPinDisplay ? html`
${SVGIcon.expandIcon}
` : nothing}
` } renderNodeIcon() { return this.element.entity.nodeIcon() } renderNodeName() { return this.element.getNodeDisplayName() } renderTop() { const icon = this.renderNodeIcon() const name = this.renderNodeName() return html`
${icon ? html`
${icon}
` : nothing} ${name ? html`
${name} ${this.#hasSubtitle && this.getTargetType().length > 0 ? html`
Target is ${Utility.formatStringName(this.getTargetType())}
`: nothing}
` : nothing}
` } /** @param {PropertyValues} changedProperties */ firstUpdated(changedProperties) { super.firstUpdated(changedProperties) this.setupPins() this.element.updateComplete.then(() => this.element.acknowledgeReflow()) } setupPins() { const inputContainer = /** @type {HTMLElement} */(this.element.querySelector(".ueb-node-inputs")) const outputContainer = /** @type {HTMLElement} */(this.element.querySelector(".ueb-node-outputs")) this.element.nodeNameElement = /** @type {HTMLElement} */(this.element.querySelector(".ueb-node-name-text")) let hasInput = false let hasOutput = false this.element.getPinElements().forEach(p => { if (p.isInput()) { inputContainer.appendChild(p) hasInput = true } else if (p.isOutput()) { outputContainer.appendChild(p) hasOutput = true } }) if (hasInput) { this.element.classList.add("ueb-node-has-inputs") } if (hasOutput) { this.element.classList.add("ueb-node-has-outputs") } } createPinElements() { return this.element.getPinEntities() .filter(v => !v.isHidden()) .map(pinEntity => { this.#hasSubtitle = this.#hasSubtitle || pinEntity.PinName === "self" && pinEntity.getDisplayName() === "Target" let pinElement = /** @type {PinElementConstructor} */(ElementFactory.getConstructor("ueb-pin")) .newObject(pinEntity, undefined, this.element) return pinElement }) } getTargetType() { return this.element.entity.FunctionReference?.MemberParent?.getName() ?? "Untitled" } /** * @param {NodeElement} node * @returns {NodeListOf} */ getPinElements(node) { return node.querySelectorAll("ueb-pin") } linksChanged() { } }