mirror of
https://github.com/barsdeveloper/ueblueprint.git
synced 2026-02-04 08:50:33 +08:00
* Fix node reference when changing elements * Fix ScriptVariables parsing * Fix invariant text and niagara types * Niagara convert nodes * Move node tests to own files * More Niagara tests * Niagara float and smaller fixes * More Decoding * More decoding * WIP * Float is real * WIP * More types and colors * Test case and small polish * WIP * WIP * Fix niagara script variables merging * Fix Niagara variables * Fixing mirrored ExportPath * Fix Export paths name adjustments * Simplify arc calculation * Simplify a bit arc calculation * source / destionation => origin / target * Minor refactoring * Fix switched link position * Rename some properties for uniformity * Fix input escape * Simplify test * About window * Dialog backdrop style * About dialog touches * Remove dependency and minot improvement * Light mode * Fix link location and css small improvement * Link direction and minor fixes * Some minor fixes and refactoring * Refactoring WIP * Shorting repetitive bits * More tests * Simplify linking tests
175 lines
6.4 KiB
JavaScript
Executable File
175 lines
6.4 KiB
JavaScript
Executable File
import { html, nothing } from "lit"
|
|
import nodeSubtitle from "../../decoding/nodeSubtitle.js"
|
|
import ElementFactory from "../../element/ElementFactory.js"
|
|
import SVGIcon from "../../SVGIcon.js"
|
|
import ISelectableDraggableTemplate from "../ISelectableDraggableTemplate.js"
|
|
|
|
/** @extends {ISelectableDraggableTemplate<NodeElement>} */
|
|
export default class NodeTemplate extends ISelectableDraggableTemplate {
|
|
|
|
static nodeStyleClasses = ["ueb-node-style-default"]
|
|
|
|
#subtitle
|
|
|
|
/** @type {() => PinEntity<IEntity>} */
|
|
pinInserter
|
|
|
|
/** @type {HTMLElement} */
|
|
inputContainer
|
|
|
|
/** @type {HTMLElement} */
|
|
outputContainer
|
|
|
|
/** @type {PinElement} */
|
|
pinElement
|
|
|
|
addPinHandler = () => {
|
|
const pin = this.pinInserter?.()
|
|
if (pin) {
|
|
if (this.defaultPin && this.defaultPin.isInput() === pin.isInput()) {
|
|
this.defaultPin.before(this.createPinElement(pin))
|
|
} else {
|
|
(pin.isInput() ? this.inputContainer : this.outputContainer).appendChild(this.createPinElement(pin))
|
|
}
|
|
this.element.acknowledgeUpdate()
|
|
}
|
|
}
|
|
|
|
toggleAdvancedDisplayHandler = () => {
|
|
this.element.toggleShowAdvancedPinDisplay()
|
|
this.element.requestUpdate()
|
|
this.element.updateComplete.then(() => this.element.acknowledgeUpdate())
|
|
}
|
|
|
|
/** @param {PinEntity<IEntity>} pinEntity */
|
|
createPinElement(pinEntity) {
|
|
const pinElement = /** @type {PinElementConstructor} */(ElementFactory.getConstructor("ueb-pin"))
|
|
.newObject(pinEntity, undefined, this.element)
|
|
if (this.pinInserter && !this.defaultPin && pinElement.getPinName() === "Default") {
|
|
this.defaultPin = pinElement
|
|
this.defaultPin.classList.add("ueb-node-variadic-default")
|
|
}
|
|
return pinElement
|
|
}
|
|
|
|
/** @param {NodeElement} element */
|
|
initialize(element) {
|
|
super.initialize(element)
|
|
this.#subtitle = nodeSubtitle(element.entity)
|
|
this.element.classList.add(.../** @type {typeof NodeTemplate} */(this.constructor).nodeStyleClasses)
|
|
this.element.style.setProperty("--ueb-node-color", this.element.entity.nodeColor().cssText)
|
|
this.pinInserter = this.element.entity.additionalPinInserter()
|
|
if (this.pinInserter) {
|
|
this.element.classList.add("ueb-node-is-variadic")
|
|
}
|
|
}
|
|
|
|
render() {
|
|
return html`
|
|
<div class="ueb-node-border">
|
|
<div class="ueb-node-wrapper">
|
|
<div class="ueb-node-top">${this.renderTop()}</div>
|
|
<div class="ueb-node-inputs"></div>
|
|
<div class="ueb-node-outputs"></div>
|
|
${this.pinInserter ? html`
|
|
<div class="ueb-node-variadic" @click="${this.addPinHandler}">
|
|
Add pin ${SVGIcon.plusCircle}
|
|
</div>
|
|
`: nothing}
|
|
${this.element.entity.isDevelopmentOnly() ? html`
|
|
<div class="ueb-node-developmentonly">
|
|
<span class="ueb-node-developmentonly-text">Development Only</span>
|
|
</div>
|
|
` : nothing}
|
|
${this.element.advancedPinDisplay ? html`
|
|
<div class="ueb-node-expansion" @click="${this.toggleAdvancedDisplayHandler}">
|
|
${SVGIcon.expandIcon}
|
|
</div>
|
|
` : nothing}
|
|
</div>
|
|
</div>
|
|
`
|
|
}
|
|
|
|
renderNodeIcon() {
|
|
return this.element.entity.nodeIcon()
|
|
}
|
|
|
|
renderNodeName() {
|
|
return this.element.nodeDisplayName
|
|
}
|
|
|
|
renderTop() {
|
|
const icon = this.renderNodeIcon()
|
|
const name = this.renderNodeName()
|
|
return html`
|
|
<div class="ueb-node-name">
|
|
${icon ? html`
|
|
<div class="ueb-node-name-symbol">${icon}</div>
|
|
` : nothing}
|
|
${name ? html`
|
|
<div class="ueb-node-name-text ueb-ellipsis-nowrap-text">
|
|
${name}
|
|
${this.#subtitle ? html`
|
|
<div class="ueb-node-subtitle-text ueb-ellipsis-nowrap-text">${this.#subtitle}</div>
|
|
`: nothing}
|
|
</div>
|
|
` : nothing}
|
|
</div>
|
|
`
|
|
}
|
|
|
|
/** @param {PropertyValues} changedProperties */
|
|
firstUpdated(changedProperties) {
|
|
super.firstUpdated(changedProperties)
|
|
this.inputContainer = this.element.querySelector(".ueb-node-inputs")
|
|
this.outputContainer = this.element.querySelector(".ueb-node-outputs")
|
|
this.setupPins()
|
|
this.element.updateComplete.then(() => this.element.acknowledgeUpdate())
|
|
}
|
|
|
|
setupPins() {
|
|
this.element.nodeNameElement = /** @type {HTMLElement} */(this.element.querySelector(".ueb-node-name-text"))
|
|
let hasInput = false
|
|
let hasOutput = false
|
|
for (const p of this.getPinElements()) {
|
|
if (p === this.defaultPin) {
|
|
continue
|
|
}
|
|
if (p.isInput()) {
|
|
this.inputContainer.appendChild(p)
|
|
hasInput = true
|
|
} else if (p.isOutput()) {
|
|
this.outputContainer.appendChild(p)
|
|
hasOutput = true
|
|
}
|
|
}
|
|
if (this.defaultPin) {
|
|
(this.defaultPin.isInput() ? this.inputContainer : this.outputContainer).appendChild(this.defaultPin)
|
|
}
|
|
if (hasInput) {
|
|
this.element.classList.add("ueb-node-has-inputs")
|
|
}
|
|
if (hasOutput) {
|
|
this.element.classList.add("ueb-node-has-outputs")
|
|
}
|
|
}
|
|
|
|
getPinElements() {
|
|
return this.element.getPinElements()
|
|
}
|
|
|
|
createPinElements() {
|
|
return this.element.getPinEntities()
|
|
.filter(v => !v.isHidden())
|
|
.map(pinEntity => this.createPinElement(pinEntity))
|
|
}
|
|
|
|
/** All the link connected to this node */
|
|
getAllConnectedLinks() {
|
|
const nodeTitle = this.element.nodeTitle
|
|
const query = `ueb-link[data-origin-node="${nodeTitle}"],ueb-link[data-target-node="${nodeTitle}"]`
|
|
return /** @type {LinkElement[]} */([...this.blueprint.querySelectorAll(query)])
|
|
}
|
|
}
|