mirror of
https://github.com/barsdeveloper/ueblueprint.git
synced 2026-02-27 10:44:43 +08:00
Refactoring WIP
This commit is contained in:
@@ -85,7 +85,6 @@ export default class Blueprint extends IElement {
|
||||
nodesNames = new Map()
|
||||
/** @type {Coordinates} */
|
||||
mousePosition = [0, 0]
|
||||
waitingExpandUpdate = false
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
|
||||
@@ -93,9 +93,9 @@ export default class Configuration {
|
||||
static mouseWheelZoomThreshold = 80
|
||||
static nodeDragEventName = "ueb-node-drag"
|
||||
static nodeDragGeneralEventName = "ueb-node-drag-general"
|
||||
static nodeTitle = (name, counter) => `${name}_${counter}`
|
||||
static nodeRadius = 8 // px
|
||||
static nodeReflowEventName = "ueb-node-reflow"
|
||||
static nodeTitle = (name, counter) => `${name}_${counter}`
|
||||
static nodeUpdateEventName = "ueb-node-update"
|
||||
static paths = {
|
||||
actorBoundEvent: "/Script/BlueprintGraph.K2Node_ActorBoundEvent",
|
||||
addDelegate: "/Script/BlueprintGraph.K2Node_AddDelegate",
|
||||
@@ -215,6 +215,7 @@ export default class Configuration {
|
||||
timeline: "/Script/BlueprintGraph.K2Node_Timeline",
|
||||
timeManagementBlueprintLibrary: "/Script/TimeManagement.TimeManagementBlueprintLibrary",
|
||||
transform: "/Script/CoreUObject.Transform",
|
||||
typedElementHandleLibrary: "/Script/TypedElementFramework.TypedElementHandleLibrary",
|
||||
userDefinedEnum: "/Script/Engine.UserDefinedEnum",
|
||||
variableGet: "/Script/BlueprintGraph.K2Node_VariableGet",
|
||||
variableSet: "/Script/BlueprintGraph.K2Node_VariableSet",
|
||||
@@ -226,6 +227,7 @@ export default class Configuration {
|
||||
whileLoop: "/Engine/EditorBlueprintResources/StandardMacros.StandardMacros:WhileLoop",
|
||||
}
|
||||
static pinInputWrapWidth = 145 // px
|
||||
static pinUpdateEventName = "ueb-pin-update"
|
||||
static removeEventName = "ueb-element-delete"
|
||||
static scale = {
|
||||
[-12]: 0.133333,
|
||||
|
||||
@@ -88,9 +88,10 @@ export default function nodeTemplateClass(nodeEntity) {
|
||||
const memberName = nodeEntity.FunctionReference?.MemberName?.toString()
|
||||
if (
|
||||
memberName && (
|
||||
memberParent === paths.kismetMathLibrary
|
||||
|| memberParent === paths.kismetArrayLibrary
|
||||
memberParent === paths.kismetArrayLibrary
|
||||
|| memberParent === paths.kismetMathLibrary
|
||||
|| memberParent === paths.kismetStringLibrary
|
||||
|| memberParent === paths.typedElementHandleLibrary
|
||||
)) {
|
||||
if (memberName.startsWith("Conv_")) {
|
||||
return VariableConversionNodeTemplate
|
||||
@@ -117,6 +118,7 @@ export default function nodeTemplateClass(nodeEntity) {
|
||||
case "BMin":
|
||||
case "CrossProduct2D":
|
||||
case "DotProduct2D":
|
||||
case "Equal":
|
||||
case "Exp":
|
||||
case "FMax":
|
||||
case "FMin":
|
||||
|
||||
@@ -375,6 +375,7 @@ export default function nodeTitle(entity) {
|
||||
case paths.kismetStringLibrary:
|
||||
case paths.slateBlueprintLibrary:
|
||||
case paths.timeManagementBlueprintLibrary:
|
||||
case paths.typedElementHandleLibrary:
|
||||
const leadingLetter = memberName.match(/[BF]([A-Z]\w+)/)
|
||||
if (leadingLetter) {
|
||||
// Some functions start with B or F (Like FCeil, FMax, BMin)
|
||||
@@ -385,6 +386,7 @@ export default function nodeTitle(entity) {
|
||||
case "BooleanAND": return "AND"
|
||||
case "BooleanNAND": return "NAND"
|
||||
case "BooleanOR": return "OR"
|
||||
case "Equal": return "=="
|
||||
case "Exp": return "e"
|
||||
case "LineTraceSingle": return "Line Trace By Channel"
|
||||
case "Max": return "MAX"
|
||||
|
||||
@@ -5,6 +5,7 @@ import Utility from "../Utility.js"
|
||||
import BooleanEntity from "../entity/BooleanEntity.js"
|
||||
import LinkTemplate from "../template/LinkTemplate.js"
|
||||
import IFromToPositionedElement from "./IFromToPositionedElement.js"
|
||||
import LinearColorEntity from "../entity/LinearColorEntity.js"
|
||||
|
||||
/** @extends {IFromToPositionedElement<Object, LinkTemplate>} */
|
||||
export default class LinkElement extends IFromToPositionedElement {
|
||||
@@ -43,6 +44,9 @@ export default class LinkElement extends IFromToPositionedElement {
|
||||
converter: BooleanEntity.booleanConverter,
|
||||
reflect: true,
|
||||
},
|
||||
color: {
|
||||
type: LinearColorEntity,
|
||||
},
|
||||
svgPathD: {
|
||||
type: String,
|
||||
attribute: false,
|
||||
@@ -75,6 +79,29 @@ export default class LinkElement extends IFromToPositionedElement {
|
||||
this.#setPin(pin, true)
|
||||
}
|
||||
|
||||
/** @param {UEBNodeUpdateEvent} e */
|
||||
#nodeUpdateHandler = e => {
|
||||
if (this.#origin.nodeElement === e.target) {
|
||||
if (this.originNode != this.#origin.nodeElement.nodeTitle) {
|
||||
this.originNode = this.#origin.nodeElement.nodeTitle
|
||||
}
|
||||
this.setOriginLocation()
|
||||
} else if (this.#target.nodeElement === e.target) {
|
||||
if (this.targetNode != this.#target.nodeElement.nodeTitle) {
|
||||
this.targetNode = this.#target.nodeElement.nodeTitle
|
||||
}
|
||||
this.setTargetLocation()
|
||||
} else {
|
||||
throw new Error("Unexpected node update")
|
||||
}
|
||||
}
|
||||
/** @param {UEBNodeUpdateEvent} e */
|
||||
#pinUpdateHandler = e => {
|
||||
const colorReferencePin = this.getOutputPin(true)
|
||||
if (!this.color?.equals(colorReferencePin.color)) {
|
||||
this.color = colorReferencePin.color
|
||||
}
|
||||
}
|
||||
#nodeDeleteHandler = () => this.remove()
|
||||
/** @param {UEBDragEvent} e */
|
||||
#nodeDragOriginHandler = e => this.addOriginLocation(...e.detail.value)
|
||||
@@ -104,6 +131,7 @@ export default class LinkElement extends IFromToPositionedElement {
|
||||
this.targetNode = ""
|
||||
this.targetPin = ""
|
||||
this.originatesFromInput = false
|
||||
this.color = new LinearColorEntity()
|
||||
this.startPercentage = 0
|
||||
this.svgPathD = ""
|
||||
this.startPixels = 0
|
||||
@@ -153,15 +181,13 @@ export default class LinkElement extends IFromToPositionedElement {
|
||||
}
|
||||
if (getCurrentPin()) {
|
||||
const nodeElement = getCurrentPin().getNodeElement()
|
||||
nodeElement.removeEventListener(Configuration.nodeUpdateEventName, this.#nodeUpdateHandler)
|
||||
nodeElement.removeEventListener(Configuration.removeEventName, this.#nodeDeleteHandler)
|
||||
nodeElement.removeEventListener(
|
||||
Configuration.nodeDragEventName,
|
||||
isTargetPin ? this.#nodeDragTargetHandler : this.#nodeDragOriginHandler
|
||||
)
|
||||
nodeElement.removeEventListener(
|
||||
Configuration.nodeReflowEventName,
|
||||
isTargetPin ? this.#nodeReflowTargetHandler : this.#nodeReflowOriginHandler
|
||||
)
|
||||
getCurrentPin().removeEventListener(Configuration.pinUpdateEventName, this.#pinUpdateHandler)
|
||||
this.#unlinkPins()
|
||||
}
|
||||
if (isTargetPin) {
|
||||
@@ -175,20 +201,20 @@ export default class LinkElement extends IFromToPositionedElement {
|
||||
}
|
||||
if (getCurrentPin()) {
|
||||
const nodeElement = getCurrentPin().getNodeElement()
|
||||
nodeElement.addEventListener(Configuration.nodeUpdateEventName, this.#nodeUpdateHandler)
|
||||
nodeElement.addEventListener(Configuration.pinUpdateEventName, this.#pinUpdateHandler)
|
||||
nodeElement.addEventListener(Configuration.removeEventName, this.#nodeDeleteHandler)
|
||||
nodeElement.addEventListener(
|
||||
Configuration.nodeDragEventName,
|
||||
isTargetPin ? this.#nodeDragTargetHandler : this.#nodeDragOriginHandler
|
||||
)
|
||||
nodeElement.addEventListener(
|
||||
Configuration.nodeReflowEventName,
|
||||
isTargetPin ? this.#nodeReflowTargetHandler : this.#nodeReflowOriginHandler
|
||||
)
|
||||
getCurrentPin().addEventListener(Configuration.pinUpdateEventName, this.#pinUpdateHandler)
|
||||
isTargetPin
|
||||
? this.setTargetLocation()
|
||||
: (this.setOriginLocation(), this.originatesFromInput = this.origin.isInputVisually())
|
||||
this.#linkPins()
|
||||
}
|
||||
this.color = this.getOutputPin(true)?.color
|
||||
}
|
||||
|
||||
#linkPins() {
|
||||
|
||||
@@ -138,18 +138,11 @@ export default class NodeElement extends ISelectableDraggableElement {
|
||||
this.#redirectLinksBeforeRename(newName?.toString())
|
||||
this.nodeTitle = newName?.toString()
|
||||
this.nodeDisplayName = nodeTitle(entity)
|
||||
this.acknowledgeUpdate()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
async getUpdateComplete() {
|
||||
let result = await super.getUpdateComplete()
|
||||
for (const pin of this.getPinElements()) {
|
||||
result &&= await pin.updateComplete
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/** @param {NodeElement} commentNode */
|
||||
bindToComment(commentNode) {
|
||||
if (commentNode != this && !this.boundComments.includes(commentNode)) {
|
||||
@@ -192,14 +185,14 @@ export default class NodeElement extends ISelectableDraggableElement {
|
||||
setNodeWidth(value) {
|
||||
this.entity.setNodeWidth(value)
|
||||
this.sizeX = value
|
||||
this.acknowledgeReflow()
|
||||
this.acknowledgeUpdate(true)
|
||||
}
|
||||
|
||||
/** @param {Number} value */
|
||||
setNodeHeight(value) {
|
||||
this.entity.setNodeHeight(value)
|
||||
this.sizeY = value
|
||||
this.acknowledgeReflow()
|
||||
this.acknowledgeUpdate(true)
|
||||
}
|
||||
|
||||
/** @param {IElement[]} nodesWhitelist */
|
||||
@@ -222,11 +215,13 @@ export default class NodeElement extends ISelectableDraggableElement {
|
||||
super.setLocation(x, y, acknowledge)
|
||||
}
|
||||
|
||||
acknowledgeReflow() {
|
||||
this.requestUpdate()
|
||||
this.updateComplete.then(() => this.computeSizes())
|
||||
let reflowEvent = new CustomEvent(Configuration.nodeReflowEventName)
|
||||
this.dispatchEvent(reflowEvent)
|
||||
acknowledgeUpdate(resize = false) {
|
||||
const event = new CustomEvent(Configuration.nodeUpdateEventName)
|
||||
if (resize) {
|
||||
this.requestUpdate()
|
||||
this.updateComplete.then(() => this.computeSizes())
|
||||
}
|
||||
this.dispatchEvent(event)
|
||||
}
|
||||
|
||||
setShowAdvancedPinDisplay(value) {
|
||||
|
||||
@@ -44,7 +44,8 @@ export default class PinElement extends IElement {
|
||||
fromAttribute: (value, type) => value
|
||||
? LinearColorEntity.getLinearColorFromAnyFormat().parse(value)
|
||||
: null,
|
||||
toAttribute: (value, type) => value ? LinearColorEntity.printLinearColor(value) : null,
|
||||
/** @param {LinearColorEntity} value */
|
||||
toAttribute: (value, type) => value?.toString() ?? "",
|
||||
},
|
||||
attribute: "data-color",
|
||||
reflect: true,
|
||||
@@ -96,10 +97,11 @@ export default class PinElement extends IElement {
|
||||
this.connectable = !entity.bNotConnectable?.valueOf()
|
||||
super.initialize(entity, template)
|
||||
this.pinId = this.entity.PinId
|
||||
this.pinType = this.entity.getType()
|
||||
this.updateType()
|
||||
this.defaultValue = this.entity.getDefaultValue()
|
||||
this.pinDirection = entity.isInput() ? "input" : entity.isOutput() ? "output" : "hidden"
|
||||
this.updateColor()
|
||||
/** @type {LinearColorEntity} */
|
||||
this.color = PinElement.properties.color.converter.fromAttribute(this.entity.pinColor().toString())
|
||||
}
|
||||
|
||||
setup() {
|
||||
@@ -107,8 +109,13 @@ export default class PinElement extends IElement {
|
||||
this.nodeElement = this.closest("ueb-node")
|
||||
}
|
||||
|
||||
updateColor() {
|
||||
this.color = PinElement.properties.color.converter.fromAttribute(this.entity.pinColor().toString())
|
||||
updateType() {
|
||||
this.pinType = this.entity.getType()
|
||||
const newColor = PinElement.properties.color.converter.fromAttribute(this.entity.pinColor().toString())
|
||||
if (!this.color?.equals(newColor)) {
|
||||
this.color = newColor
|
||||
this.acknowledgeUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
createPinReference() {
|
||||
@@ -289,4 +296,9 @@ export default class PinElement extends IElement {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
acknowledgeUpdate() {
|
||||
let event = new CustomEvent(Configuration.pinUpdateEventName)
|
||||
this.dispatchEvent(event)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,8 @@ import Vector2DEntity from "./Vector2DEntity.js"
|
||||
import Vector4DEntity from "./Vector4DEntity.js"
|
||||
import VectorEntity from "./VectorEntity.js"
|
||||
|
||||
const paths = Configuration.paths
|
||||
|
||||
/** @template {IEntity} T */
|
||||
export default class PinEntity extends IEntity {
|
||||
|
||||
@@ -49,24 +51,24 @@ export default class PinEntity extends IEntity {
|
||||
"name": StringEntity,
|
||||
"real": NumberEntity,
|
||||
"string": StringEntity,
|
||||
[Configuration.paths.linearColor]: LinearColorEntity,
|
||||
[Configuration.paths.niagaraBool]: BooleanEntity,
|
||||
[Configuration.paths.niagaraFloat]: NumberEntity,
|
||||
[Configuration.paths.niagaraPosition]: VectorEntity,
|
||||
[Configuration.paths.rotator]: RotatorEntity,
|
||||
[Configuration.paths.vector]: VectorEntity,
|
||||
[Configuration.paths.vector2D]: Vector2DEntity,
|
||||
[Configuration.paths.vector4f]: Vector4DEntity,
|
||||
[paths.linearColor]: LinearColorEntity,
|
||||
[paths.niagaraBool]: BooleanEntity,
|
||||
[paths.niagaraFloat]: NumberEntity,
|
||||
[paths.niagaraPosition]: VectorEntity,
|
||||
[paths.rotator]: RotatorEntity,
|
||||
[paths.vector]: VectorEntity,
|
||||
[paths.vector2D]: Vector2DEntity,
|
||||
[paths.vector4f]: Vector4DEntity,
|
||||
}
|
||||
static #alternativeTypeEntityMap = {
|
||||
"enum": EnumDisplayValueEntity,
|
||||
"rg": RBSerializationVector2DEntity,
|
||||
[Configuration.paths.niagaraPosition]: SimpleSerializationVectorEntity.flagAllowShortSerialization(),
|
||||
[Configuration.paths.rotator]: SimpleSerializationRotatorEntity,
|
||||
[Configuration.paths.vector]: SimpleSerializationVectorEntity,
|
||||
[Configuration.paths.vector2D]: SimpleSerializationVector2DEntity,
|
||||
[Configuration.paths.vector3f]: SimpleSerializationVectorEntity,
|
||||
[Configuration.paths.vector4f]: SimpleSerializationVector4DEntity,
|
||||
[paths.niagaraPosition]: SimpleSerializationVectorEntity.flagAllowShortSerialization(),
|
||||
[paths.rotator]: SimpleSerializationRotatorEntity,
|
||||
[paths.vector]: SimpleSerializationVectorEntity,
|
||||
[paths.vector2D]: SimpleSerializationVector2DEntity,
|
||||
[paths.vector3f]: SimpleSerializationVectorEntity,
|
||||
[paths.vector4f]: SimpleSerializationVector4DEntity,
|
||||
}
|
||||
static attributes = {
|
||||
PinId: GuidEntity.withDefault(),
|
||||
@@ -216,9 +218,9 @@ export default class PinEntity extends IEntity {
|
||||
case "rg":
|
||||
return "rg"
|
||||
case "rgb":
|
||||
return Configuration.paths.vector
|
||||
return paths.vector
|
||||
case "rgba":
|
||||
return Configuration.paths.linearColor
|
||||
return paths.linearColor
|
||||
default:
|
||||
return subCategory
|
||||
}
|
||||
@@ -254,14 +256,14 @@ export default class PinEntity extends IEntity {
|
||||
|
||||
isEnum() {
|
||||
const type = this.PinType.PinSubCategoryObject?.type
|
||||
return type === Configuration.paths.enum
|
||||
|| type === Configuration.paths.userDefinedEnum
|
||||
return type === paths.enum
|
||||
|| type === paths.userDefinedEnum
|
||||
|| type?.toLowerCase() === "enum"
|
||||
}
|
||||
|
||||
isExecution() {
|
||||
return this.PinType.PinCategory.toString() === "exec"
|
||||
|| this.getType() === Configuration.paths.niagaraParameterMap
|
||||
|| this.getType() === paths.niagaraParameterMap
|
||||
}
|
||||
|
||||
isHidden() {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { html, nothing } from "lit"
|
||||
import Configuration from "../Configuration.js"
|
||||
import ElementFactory from "../element/ElementFactory.js"
|
||||
import LinearColorEntity from "../entity/LinearColorEntity.js"
|
||||
import KnotEntity from "../entity/objects/KnotEntity.js"
|
||||
import KeyboardShortcut from "../input/keyboard/KeyboardShortcut.js"
|
||||
import MouseClick from "../input/mouse/MouseClick.js"
|
||||
@@ -53,8 +52,6 @@ export default class LinkTemplate extends IFromToPositionedTemplate {
|
||||
this.blueprint.addGraphElement(knot) // Important: keep it before changing existing links
|
||||
const inputPin = this.element.getInputPin()
|
||||
const outputPin = this.element.getOutputPin()
|
||||
this.element.origin = null
|
||||
this.element.target = null
|
||||
const link = /** @type {LinkElementConstructor} */(ElementFactory.getConstructor("ueb-link"))
|
||||
.newObject(outputPin, knotTemplate.inputPin)
|
||||
this.blueprint.addGraphElement(link)
|
||||
@@ -181,24 +178,28 @@ export default class LinkTemplate extends IFromToPositionedTemplate {
|
||||
/** @param {PropertyValues} changedProperties */
|
||||
update(changedProperties) {
|
||||
super.update(changedProperties)
|
||||
const referencePin = this.element.getOutputPin(true)
|
||||
if (referencePin) {
|
||||
this.element.style.setProperty("--ueb-link-color-rgb", LinearColorEntity.printLinearColor(referencePin.color))
|
||||
const style = this.element.style
|
||||
if (changedProperties.has("color")) {
|
||||
style.setProperty("--ueb-link-color-rgb", this.element.color?.toString() ?? "255, 255, 255")
|
||||
}
|
||||
this.element.style.setProperty("--ueb-start-percentage", `${Math.round(this.element.startPercentage)}%`)
|
||||
this.element.style.setProperty("--ueb-link-start", `${Math.round(this.element.startPixels)}`)
|
||||
style.setProperty("--ueb-start-percentage", `${Math.round(this.element.startPercentage)}%`)
|
||||
style.setProperty("--ueb-link-start", `${Math.round(this.element.startPixels)}`)
|
||||
const mirrorV = (this.element.originY > this.element.targetY ? -1 : 1) // If from is below to => mirror
|
||||
* (this.element.originatesFromInput ? -1 : 1) // Unless fro refers to an input pin
|
||||
* (this.element.origin?.isInputVisually() && this.element.target?.isInputVisually() ? -1 : 1)
|
||||
const mirrorH = (this.element.origin?.isInputVisually() && this.element.target?.isInputVisually() ? -1 : 1)
|
||||
this.element.style.setProperty("--ueb-link-scale-y", `${mirrorV}`)
|
||||
this.element.style.setProperty("--ueb-link-scale-x", `${mirrorH}`)
|
||||
style.setProperty("--ueb-link-scale-y", `${mirrorV}`)
|
||||
style.setProperty("--ueb-link-scale-x", `${mirrorH}`)
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<svg version="1.2" baseProfile="tiny" width="100%" height="100%" viewBox="0 0 100 100" preserveAspectRatio="none">
|
||||
<path id="${this.#uniqueId}" fill="none" vector-effect="non-scaling-stroke" d="${this.element.svgPathD}" />
|
||||
<svg version="1.2" baseProfile="tiny" width="100%" height="100%" viewBox="0 0 100 100"
|
||||
preserveAspectRatio="none"
|
||||
>
|
||||
<path id="${this.#uniqueId}" fill="none" vector-effect="non-scaling-stroke"
|
||||
d="${this.element.svgPathD}"
|
||||
/>
|
||||
<use href="#${this.#uniqueId}" class="ueb-link-area" pointer-events="all" />
|
||||
<use href="#${this.#uniqueId}" class="ueb-link-path" pointer-events="none" />
|
||||
</svg>
|
||||
|
||||
@@ -14,7 +14,7 @@ export default class KnotNodeTemplate extends NodeTemplate {
|
||||
return
|
||||
}
|
||||
this.#switchDirectionsVisually = value
|
||||
this.element.acknowledgeReflow()
|
||||
this.element.acknowledgeUpdate()
|
||||
}
|
||||
|
||||
/** @type {PinElement} */
|
||||
@@ -35,17 +35,6 @@ export default class KnotNodeTemplate extends NodeTemplate {
|
||||
this.element.classList.add("ueb-node-style-minimal")
|
||||
}
|
||||
|
||||
/** @param {PropertyValues} changedProperties */
|
||||
update(changedProperties) {
|
||||
super.update(changedProperties)
|
||||
if (!this.#inputPin.isLinked && !this.#outputPin.isLinked) {
|
||||
this.#inputPin.entity.PinType.PinCategory.value = "wildcard"
|
||||
this.#inputPin.updateColor()
|
||||
this.#outputPin.entity.PinType.PinCategory.value = "wildcard"
|
||||
this.#inputPin.updateColor()
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<div class="ueb-node-border"></div>
|
||||
|
||||
@@ -31,14 +31,14 @@ export default class NodeTemplate extends ISelectableDraggableTemplate {
|
||||
} else {
|
||||
(pin.isInput() ? this.inputContainer : this.outputContainer).appendChild(this.createPinElement(pin))
|
||||
}
|
||||
this.element.acknowledgeReflow()
|
||||
this.element.acknowledgeUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
toggleAdvancedDisplayHandler = () => {
|
||||
this.element.toggleShowAdvancedPinDisplay()
|
||||
this.element.requestUpdate()
|
||||
this.element.updateComplete.then(() => this.element.acknowledgeReflow())
|
||||
this.element.updateComplete.then(() => this.element.acknowledgeUpdate())
|
||||
}
|
||||
|
||||
/** @param {PinEntity<IEntity>} pinEntity */
|
||||
@@ -125,7 +125,7 @@ export default class NodeTemplate extends ISelectableDraggableTemplate {
|
||||
this.inputContainer = this.element.querySelector(".ueb-node-inputs")
|
||||
this.outputContainer = this.element.querySelector(".ueb-node-outputs")
|
||||
this.setupPins()
|
||||
this.element.updateComplete.then(() => this.element.acknowledgeReflow())
|
||||
this.element.updateComplete.then(() => this.element.acknowledgeUpdate())
|
||||
}
|
||||
|
||||
setupPins() {
|
||||
|
||||
@@ -78,13 +78,13 @@ export default class IInputPinTemplate extends PinTemplate {
|
||||
}
|
||||
if (Self.canWrapInput && this.isInputRendered()) {
|
||||
this.element.addEventListener("input", this.#checkWrapHandler)
|
||||
this.element.nodeElement.addEventListener(Configuration.nodeReflowEventName, this.#checkWrapHandler)
|
||||
this.element.nodeElement.addEventListener(Configuration.nodeUpdateEventName, this.#checkWrapHandler)
|
||||
}
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
super.cleanup()
|
||||
this.element.nodeElement.removeEventListener(Configuration.nodeReflowEventName, this.#checkWrapHandler)
|
||||
this.element.nodeElement.removeEventListener(Configuration.nodeUpdateEventName, this.#checkWrapHandler)
|
||||
this.element.removeEventListener("input", this.#checkWrapHandler)
|
||||
this.element.removeEventListener("input", this.#setInput)
|
||||
this.element.removeEventListener("focusout", this.#setInput)
|
||||
@@ -112,7 +112,7 @@ export default class IInputPinTemplate extends PinTemplate {
|
||||
this.setDefaultValue(values.map(v => IInputPinTemplate.stringFromInputToUE(v)), values)
|
||||
}
|
||||
this.element.requestUpdate()
|
||||
this.element.nodeElement.acknowledgeReflow()
|
||||
this.element.updateComplete.then(() => this.element.nodeElement.acknowledgeUpdate())
|
||||
}
|
||||
|
||||
setDefaultValue(values = [], rawValues = values) {
|
||||
|
||||
@@ -1,13 +1,68 @@
|
||||
import { html } from "lit"
|
||||
import FunctionReferenceEntity from "../../entity/FunctionReferenceEntity.js"
|
||||
import ObjectReferenceEntity from "../../entity/ObjectReferenceEntity.js"
|
||||
import PinTypeEntity from "../../entity/PinTypeEntity.js"
|
||||
import StringEntity from "../../entity/StringEntity.js"
|
||||
import MinimalPinTemplate from "./MinimalPinTemplate.js"
|
||||
|
||||
/** @extends MinimalPinTemplate<KnotEntity> */
|
||||
export default class KnotPinTemplate extends MinimalPinTemplate {
|
||||
|
||||
static #wildcardPinType = new PinTypeEntity({
|
||||
PinCategory: new StringEntity("wildcard"),
|
||||
PinSubCategoryObject: ObjectReferenceEntity.createNoneInstance(),
|
||||
PinSubCategoryMemberReference: new FunctionReferenceEntity(),
|
||||
})
|
||||
|
||||
/** @param {PinTypeEntity} type */
|
||||
#setType(type) {
|
||||
const oppositePin = this.getoppositePin()
|
||||
this.element.entity.PinType.copyTypeFrom(type)
|
||||
oppositePin.entity.PinType.copyTypeFrom(type)
|
||||
this.element.updateType()
|
||||
oppositePin.updateType()
|
||||
}
|
||||
|
||||
render() {
|
||||
return this.element.isOutput() ? super.render() : html``
|
||||
}
|
||||
|
||||
/** @param {PropertyValues} changedProperties */
|
||||
update(changedProperties) {
|
||||
super.update(changedProperties)
|
||||
if (changedProperties.has("isLinked")) {
|
||||
const oppositePin = this.getoppositePin()
|
||||
if (!this.element.isLinked && !oppositePin.isLinked) {
|
||||
this.#setType(KnotPinTemplate.#wildcardPinType)
|
||||
} else if (this.element.isLinked && this.element.pinType == "wildcard") {
|
||||
const type = this.element
|
||||
.getLinks()
|
||||
.map(r => this.blueprint.getPin(r))
|
||||
.find(p => p && p.pinType != "wildcard")
|
||||
?.entity
|
||||
.PinType
|
||||
if (type) {
|
||||
/** @type {KnotPinTemplate[]} */
|
||||
const propagated = [this]
|
||||
for (let i = 0; i < propagated.length; ++i) {
|
||||
let current = propagated[i]
|
||||
current.#setType(type)
|
||||
current = /** @type {KnotPinTemplate} */(current.getoppositePin().template)
|
||||
current.#setType(type)
|
||||
propagated.push(
|
||||
...current.element.getLinks().map(r => (
|
||||
/** @type {KnotPinTemplate} */(
|
||||
this.blueprint.getPin(r).template
|
||||
)
|
||||
))
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getoppositePin() {
|
||||
const nodeTemplate = /** @type {KnotNodeTemplate} */(this.element.nodeElement.template)
|
||||
return this.element.isOutput() ? nodeTemplate.inputPin : nodeTemplate.outputPin
|
||||
|
||||
@@ -159,14 +159,16 @@ export default class PinTemplate extends ITemplate {
|
||||
// When connected, an input may drop its input fields which means the node has to reflow
|
||||
const node = this.element.nodeElement
|
||||
this.element.requestUpdate()
|
||||
this.element.updateComplete.then(() => node.acknowledgeReflow())
|
||||
this.element.updateComplete.then(() => node.acknowledgeUpdate())
|
||||
}
|
||||
if (changedProperties.has("color")) {
|
||||
this.element.style.setProperty("--ueb-pin-color-rgb", this.element.color.toString())
|
||||
}
|
||||
}
|
||||
|
||||
/** @param {PropertyValues} changedProperties */
|
||||
firstUpdated(changedProperties) {
|
||||
super.firstUpdated(changedProperties)
|
||||
this.element.style.setProperty("--ueb-pin-color-rgb", this.element.entity.pinColor().cssText)
|
||||
this.#iconElement = this.element.querySelector(".ueb-pin-icon svg") ?? this.element
|
||||
this.#wrapperElement = this.element.querySelector(".ueb-pin-wrapper")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user