mirror of
https://github.com/barsdeveloper/ueblueprint.git
synced 2026-02-15 17:54:52 +08:00
Various fixes to hid nodes
This commit is contained in:
@@ -31,6 +31,18 @@ export default class Configuration {
|
||||
"text": css`226, 121, 167`,
|
||||
"wildcard": css`128, 120, 120`,
|
||||
}
|
||||
static #keyName = {
|
||||
"A_AccentGrave": "à",
|
||||
"E_AccentGrave": "è",
|
||||
"E_AccentAigu": "é",
|
||||
"Add": "Num +",
|
||||
"Decimal": "Num .",
|
||||
"Divide": "Num /",
|
||||
"Multiply": "Num *",
|
||||
"Subtract": "Num -",
|
||||
"Section": "§",
|
||||
"C_Cedille": "ç",
|
||||
}
|
||||
static alphaPattern = "repeating-conic-gradient(#7c8184 0% 25%, #c2c3c4 0% 50%) 50% / 10px 10px"
|
||||
static colorDragEventName = "ueb-color-drag"
|
||||
static colorPickEventName = "ueb-color-pick"
|
||||
@@ -61,6 +73,28 @@ export default class Configuration {
|
||||
static gridShrinkThreshold = 4 // exceding size factor threshold to cause a shrink event
|
||||
static gridSize = 16 // px
|
||||
static hexColorRegex = /^\s*#(?<r>[0-9a-fA-F]{2})(?<g>[0-9a-fA-F]{2})(?<b>[0-9a-fA-F]{2})([0-9a-fA-F]{2})?|#(?<rs>[0-9a-fA-F])(?<gs>[0-9a-fA-F])(?<bs>[0-9a-fA-F])\s*$/
|
||||
/** @param {String} value */
|
||||
static keyName(value) {
|
||||
let result = Configuration.#keyName[value]
|
||||
if (result) {
|
||||
return result
|
||||
}
|
||||
result = Utility.numberFromText(value)
|
||||
if (result) {
|
||||
return result
|
||||
}
|
||||
const match = value.match(/NumPad([a-zA-Z]+)/)
|
||||
if (match) {
|
||||
result = Utility.numberFromText(match[1])
|
||||
if (result) {
|
||||
return "Num " + result
|
||||
}
|
||||
}
|
||||
}
|
||||
/** @param {NodeElement} node */
|
||||
static hidAttribute(node) {
|
||||
return node.entity.InputKey ?? node.entity.AxisKey ?? node.entity.InputAxisKey
|
||||
}
|
||||
static keysSeparator = "+"
|
||||
static linkCurveHeight = 15 // px
|
||||
static linkCurveWidth = 80 // px
|
||||
@@ -84,7 +118,9 @@ export default class Configuration {
|
||||
switch (node.getType()) {
|
||||
case Configuration.nodeType.doN: return SVGIcon.doN
|
||||
case Configuration.nodeType.dynamicCast: return SVGIcon.cast
|
||||
case Configuration.nodeType.event: return SVGIcon.event
|
||||
case Configuration.nodeType.event:
|
||||
case Configuration.nodeType.customEvent:
|
||||
return SVGIcon.event
|
||||
case Configuration.nodeType.executionSequence: return SVGIcon.sequence
|
||||
case Configuration.nodeType.forEachElementInEnum: return SVGIcon.loop
|
||||
case Configuration.nodeType.forEachLoop: return SVGIcon.forEachLoop
|
||||
@@ -104,19 +140,27 @@ export default class Configuration {
|
||||
if (node.entity.getClass() === Configuration.nodeType.macro) {
|
||||
return SVGIcon.macro
|
||||
}
|
||||
if (Configuration.hidAttribute(node)?.toString().includes("Mouse")) {
|
||||
return SVGIcon.mouse
|
||||
}
|
||||
return SVGIcon.functionSymbol
|
||||
}
|
||||
/** @param {NodeElement} node */
|
||||
static nodeColor(node) {
|
||||
const functionColor = css`84, 122, 156`
|
||||
const pureFunctionColor = css`95, 129, 90`
|
||||
const functionColor = css`84, 122, 156` // Blue
|
||||
const pureFunctionColor = css`95, 129, 90` // Green
|
||||
const eventColor = css`151, 33, 32` // Red
|
||||
switch (node.entity.getClass()) {
|
||||
case Configuration.nodeType.callFunction:
|
||||
return node.entity.bIsPureFunc
|
||||
? pureFunctionColor
|
||||
: functionColor
|
||||
case Configuration.nodeType.event:
|
||||
return css`151, 33, 32`
|
||||
case Configuration.nodeType.customEvent:
|
||||
case Configuration.nodeType.inputKey:
|
||||
case Configuration.nodeType.inputAxisKeyEvent:
|
||||
case Configuration.nodeType.inputDebugKey:
|
||||
return eventColor
|
||||
case Configuration.nodeType.makeArray:
|
||||
case Configuration.nodeType.makeMap:
|
||||
case Configuration.nodeType.select:
|
||||
@@ -124,9 +168,15 @@ export default class Configuration {
|
||||
case Configuration.nodeType.executionSequence:
|
||||
case Configuration.nodeType.ifThenElse:
|
||||
case Configuration.nodeType.macro:
|
||||
return css`150,150,150`
|
||||
return css`150,150,150` // Gray
|
||||
case Configuration.nodeType.dynamicCast:
|
||||
return css`46, 104, 106`
|
||||
return css`46, 104, 106` // Turquoise
|
||||
}
|
||||
if (node.entity.bIsPureFunc) {
|
||||
return pureFunctionColor
|
||||
}
|
||||
if (node.isEvent()) {
|
||||
return eventColor
|
||||
}
|
||||
return functionColor
|
||||
}
|
||||
@@ -185,22 +235,30 @@ export default class Configuration {
|
||||
return `Event ${(node.entity.EventReference?.MemberName ?? "").replace(/^Receive/, "")}`
|
||||
case Configuration.nodeType.executionSequence:
|
||||
return "Sequence"
|
||||
case Configuration.nodeType.ifThenElse:
|
||||
return "Branch"
|
||||
case Configuration.nodeType.forEachElementInEnum:
|
||||
return `For Each ${node.entity.Enum.getName()}`
|
||||
case Configuration.nodeType.forEachLoopWithBreak:
|
||||
return "For Each Loop with Break"
|
||||
case Configuration.nodeType.ifThenElse:
|
||||
return "Branch"
|
||||
case Configuration.nodeType.variableGet:
|
||||
return ""
|
||||
case Configuration.nodeType.variableSet:
|
||||
return "SET"
|
||||
default:
|
||||
if (node.entity.getClass() === Configuration.nodeType.macro) {
|
||||
return Utility.formatStringName(node.entity.MacroGraphReference.getMacroName())
|
||||
} else {
|
||||
return Utility.formatStringName(node.entity.getNameAndCounter()[0])
|
||||
}
|
||||
}
|
||||
const keyNameSymbol = Configuration.hidAttribute(node)
|
||||
if (keyNameSymbol) {
|
||||
const keyName = keyNameSymbol.toString()
|
||||
let title = Configuration.keyName(keyName) ?? Utility.formatStringName(keyName)
|
||||
if (node.entity.getClass() === Configuration.nodeType.inputDebugKey) {
|
||||
title = "Debug Key " + title
|
||||
}
|
||||
return title
|
||||
}
|
||||
if (node.entity.getClass() === Configuration.nodeType.macro) {
|
||||
return Utility.formatStringName(node.entity.MacroGraphReference.getMacroName())
|
||||
} else {
|
||||
return Utility.formatStringName(node.entity.getNameAndCounter()[0])
|
||||
}
|
||||
}
|
||||
static nodeRadius = 8 // px
|
||||
@@ -221,7 +279,11 @@ export default class Configuration {
|
||||
forLoop: "/Engine/EditorBlueprintResources/StandardMacros.StandardMacros:ForLoop",
|
||||
forLoopWithBreak: "/Engine/EditorBlueprintResources/StandardMacros.StandardMacros:ForLoopWithBreak",
|
||||
functionEntry: "/Script/BlueprintGraph.K2Node_FunctionEntry",
|
||||
getInputAxisKeyValue: "/Script/BlueprintGraph.K2Node_GetInputAxisKeyValue",
|
||||
ifThenElse: "/Script/BlueprintGraph.K2Node_IfThenElse",
|
||||
inputAxisKeyEvent: "/Script/BlueprintGraph.K2Node_InputAxisKeyEvent",
|
||||
inputDebugKey: "/Script/InputBlueprintNodes.K2Node_InputDebugKey",
|
||||
inputKey: "/Script/BlueprintGraph.K2Node_InputKey",
|
||||
knot: "/Script/BlueprintGraph.K2Node_Knot",
|
||||
macro: "/Script/BlueprintGraph.K2Node_MacroInstance",
|
||||
makeArray: "/Script/BlueprintGraph.K2Node_MakeArray",
|
||||
|
||||
@@ -115,7 +115,13 @@ export default class SVGIcon {
|
||||
static genericPin = html`
|
||||
<svg viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle class="ueb-pin-tofill" cx="16" cy="16" r="13" fill="black" stroke="currentColor" stroke-width="5" />
|
||||
<path d="M 34 6 L 34 26 L 42 16 Z" fill="currentColor" />
|
||||
<path fill="currentColor" d="M 34 6 L 34 26 L 42 16 Z" />
|
||||
</svg>
|
||||
`
|
||||
|
||||
static keyboard = html `
|
||||
<svg viewBox="0 -3 16 16" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="white" d="M 1 10 H 15 c 0.2652 0 0.5195 -0.1054 0.707 -0.293 c 0.1875 -0.1875 0.293 -0.4418 0.293 -0.707 v -8 c 0 -0.2652 -0.1054 -0.5195 -0.293 -0.707 c -0.1875 -0.1875 -0.4418 -0.293 -0.707 -0.293 H 1 c -0.2652 0 -0.5195 0.1054 -0.707 0.293 c -0.1875 0.1875 -0.293 0.4418 -0.293 0.707 V 9 c 0 0.2652 0.1054 0.5195 0.293 0.707 c 0.1875 0.1875 0.4418 0.293 0.707 0.293 Z M 14 6 h -3 v -2 h 3 v 2 Z M 13 1 h 2 v 2 h -2 v -2 Z M 10 1 h 2 v 2 h -2 v -2 Z M 10 6 h -2 v -2 h 2 v 2 Z M 7 1 h 2 v 2 h -2 v -2 Z M 7 6 h -2 v -2 h 2 v 2 Z M 4 1 h 2 v 2 h -2 v -2 Z M 4 6 h -2 v -2 h 2 v 2 Z M 1 1 h 2 v 2 h -2 v -2 Z M 1 7 h 2 v 2 h -2 v -2 M 4 7 h 8 v 2 h -8 v -2 M 13 7 h 2 v 2 h -2 v -2 Z" />
|
||||
</svg>
|
||||
`
|
||||
|
||||
@@ -206,6 +212,13 @@ export default class SVGIcon {
|
||||
</svg>
|
||||
`
|
||||
|
||||
static mouse = html`
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path opacity="0.5" fill-rule="evenodd" clip-rule="evenodd" d="M8.85714 8.34043H14L13.9143 6.6383H8.85714V0H7.14286V6.6383H2.08571L2 8.34043H7.14286H8.85714Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.85714 0C11 0.595745 13.4 3.31915 13.9143 6.6383H8.85714V0ZM7.14286 0C5 0.595745 2.6 3.31915 2.08571 6.6383H7.14286V0ZM8.85714 8.34043H7.14286H2C2 12.5957 3.02857 16 8 16C12.9714 16 14 12.5957 14 8.34043H8.85714Z" fill="white"/>
|
||||
</svg>
|
||||
`
|
||||
|
||||
static referencePin = html`
|
||||
<svg viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
|
||||
<polygon class="ueb-pin-tofill" points="4 16 16 4 28 16 16 28" stroke="currentColor" stroke-width="5" />
|
||||
|
||||
@@ -63,6 +63,23 @@ export default class Utility {
|
||||
return num.toFixed(decimals)
|
||||
}
|
||||
|
||||
/** @param {String} value */
|
||||
static numberFromText(value = "") {
|
||||
value = value.toLowerCase()
|
||||
switch(value) {
|
||||
case "zero": return 0
|
||||
case "one": return 1
|
||||
case "two": return 2
|
||||
case "three": return 3
|
||||
case "four": return 4
|
||||
case "five": return 5
|
||||
case "six": return 6
|
||||
case "seven": return 7
|
||||
case "eight": return 8
|
||||
case "nine": return 9
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Number} num
|
||||
* @param {Number} decimals
|
||||
|
||||
@@ -133,13 +133,17 @@ export default class NodeElement extends ISelectableDraggableElement {
|
||||
}
|
||||
switch (nodeEntity.getClass()) {
|
||||
case Configuration.nodeType.comment:
|
||||
case Configuration.nodeType.customEvent:
|
||||
return CommentNodeTemplate
|
||||
case Configuration.nodeType.event: return EventNodeTemplate
|
||||
case Configuration.nodeType.event:
|
||||
case Configuration.nodeType.customEvent:
|
||||
return EventNodeTemplate
|
||||
case Configuration.nodeType.knot: return KnotNodeTemplate
|
||||
case Configuration.nodeType.variableGet: return VariableAccessNodeTemplate
|
||||
case Configuration.nodeType.variableSet: return VariableAccessNodeTemplate
|
||||
}
|
||||
if (nodeEntity.getDelegatePin()) {
|
||||
return EventNodeTemplate
|
||||
}
|
||||
return NodeTemplate
|
||||
}
|
||||
|
||||
@@ -275,6 +279,10 @@ export default class NodeElement extends ISelectableDraggableElement {
|
||||
super.setLocation(x, y, acknowledge)
|
||||
}
|
||||
|
||||
isEvent() {
|
||||
return this.template instanceof EventNodeTemplate
|
||||
}
|
||||
|
||||
acknowledgeReflow() {
|
||||
this.requestUpdate()
|
||||
this.updateComplete.then(() => this.computeSizes())
|
||||
|
||||
@@ -210,7 +210,7 @@ export default class PinElement extends IElement {
|
||||
|
||||
/** @param {IElement[]} nodesWhitelist */
|
||||
sanitizeLinks(nodesWhitelist = []) {
|
||||
this.entity.LinkedTo = this.getLinks().filter(pinReference => {
|
||||
this.entity.LinkedTo = this.entity.LinkedTo?.filter(pinReference => {
|
||||
let pin = this.blueprint.getPin(pinReference)
|
||||
if (pin) {
|
||||
if (nodesWhitelist.length && !nodesWhitelist.includes(pin.nodeElement)) {
|
||||
|
||||
@@ -8,7 +8,10 @@ export default class FunctionReferenceEntity extends IEntity {
|
||||
type: ObjectReferenceEntity,
|
||||
showDefault: false
|
||||
},
|
||||
MemberName: "",
|
||||
MemberName: {
|
||||
type: String,
|
||||
showDefault: false,
|
||||
},
|
||||
}
|
||||
|
||||
static {
|
||||
|
||||
@@ -58,12 +58,6 @@ export default class IEntity {
|
||||
/** @type {AttributeInformation} */
|
||||
let attribute = attributes[attributeName]
|
||||
|
||||
if (!attribute) {
|
||||
// Remember attributeName can come from the values and be not defined in the attributes
|
||||
target[attributeName] = value
|
||||
continue
|
||||
}
|
||||
|
||||
if (attribute instanceof SubAttributesDeclaration) {
|
||||
target[attributeName] = {}
|
||||
defineAllAttributes(
|
||||
@@ -93,6 +87,12 @@ export default class IEntity {
|
||||
}
|
||||
}
|
||||
|
||||
if (!attribute) {
|
||||
// Remember attributeName can come from the values and be not defined in the attributes
|
||||
target[attributeName] = value
|
||||
continue
|
||||
}
|
||||
|
||||
let defaultValue = attribute.value
|
||||
let defaultType = attribute.type
|
||||
if (attribute.serialized && defaultType instanceof Function) {
|
||||
|
||||
@@ -18,6 +18,14 @@ export default class ObjectEntity extends IEntity {
|
||||
type: ObjectReferenceEntity,
|
||||
},
|
||||
Name: "",
|
||||
AxisKey: {
|
||||
type: SymbolEntity,
|
||||
showDefault: false,
|
||||
},
|
||||
InputAxisKey: {
|
||||
type: SymbolEntity,
|
||||
showDefault: false,
|
||||
},
|
||||
bIsPureFunc: {
|
||||
value: false,
|
||||
showDefault: false,
|
||||
@@ -36,14 +44,18 @@ export default class ObjectEntity extends IEntity {
|
||||
value: null,
|
||||
showDefault: false,
|
||||
},
|
||||
EventReference: {
|
||||
type: FunctionReferenceEntity,
|
||||
value: null,
|
||||
showDefault: false,
|
||||
},
|
||||
FunctionReference: {
|
||||
type: FunctionReferenceEntity,
|
||||
value: null,
|
||||
showDefault: false,
|
||||
},
|
||||
EventReference: {
|
||||
type: FunctionReferenceEntity,
|
||||
value: null,
|
||||
CustomFunctionName: {
|
||||
type: String,
|
||||
showDefault: false,
|
||||
},
|
||||
TargetType: {
|
||||
@@ -60,6 +72,46 @@ export default class ObjectEntity extends IEntity {
|
||||
type: ObjectReferenceEntity,
|
||||
showDefault: false,
|
||||
},
|
||||
InputKey: {
|
||||
type: SymbolEntity,
|
||||
showDefault: false,
|
||||
},
|
||||
bOverrideFunction: {
|
||||
type: Boolean,
|
||||
showDefault: false,
|
||||
},
|
||||
bInternalEvent: {
|
||||
type: Boolean,
|
||||
showDefault: false,
|
||||
},
|
||||
bConsumeInput: {
|
||||
type: Boolean,
|
||||
showDefault: false,
|
||||
},
|
||||
bExecuteWhenPaused: {
|
||||
type: Boolean,
|
||||
showDefault: false,
|
||||
},
|
||||
bOverrideParentBinding: {
|
||||
type: Boolean,
|
||||
showDefault: false,
|
||||
},
|
||||
bControl: {
|
||||
type: Boolean,
|
||||
showDefault: false,
|
||||
},
|
||||
bAlt: {
|
||||
type: Boolean,
|
||||
showDefault: false,
|
||||
},
|
||||
bShift: {
|
||||
type: Boolean,
|
||||
showDefault: false,
|
||||
},
|
||||
bCommand: {
|
||||
type: Boolean,
|
||||
showDefault: false,
|
||||
},
|
||||
CommentColor: {
|
||||
type: LinearColorEntity,
|
||||
showDefault: false,
|
||||
@@ -143,9 +195,15 @@ export default class ObjectEntity extends IEntity {
|
||||
super(values, suppressWarns)
|
||||
/** @type {ObjectReferenceEntity} */ this.Class
|
||||
/** @type {String} */ this.Name
|
||||
/** @type {SymbolEntity?} */ this.AxisKey
|
||||
/** @type {SymbolEntity?} */ this.InputAxisKey
|
||||
/** @type {SymbolEntity?} */ this.InputKey
|
||||
/** @type {Boolean?} */ this.bIsPureFunc
|
||||
/** @type {Boolean?} */ this.bIsConstFunc
|
||||
/** @type {VariableReferenceEntity?} */ this.VariableReference
|
||||
/** @type {SymbolEntity?} */ this.SelfContextInfo
|
||||
/** @type {FunctionReferenceEntity?} */ this.FunctionReference
|
||||
/** @type {String} */ this.CustomFunctionName
|
||||
/** @type {FunctionReferenceEntity?} */ this.EventReference
|
||||
/** @type {ObjectReferenceEntity?} */ this.TargetType
|
||||
/** @type {MacroGraphReferenceEntity?} */ this.MacroGraphReference
|
||||
@@ -242,7 +300,7 @@ export default class ObjectEntity extends IEntity {
|
||||
if (!this.NodePosX) {
|
||||
this.NodePosX = new IntegerEntity()
|
||||
}
|
||||
this.NodePosX.value = value
|
||||
this.NodePosX.value = Math.round(value)
|
||||
}
|
||||
|
||||
getNodePosY() {
|
||||
@@ -254,6 +312,16 @@ export default class ObjectEntity extends IEntity {
|
||||
if (!this.NodePosY) {
|
||||
this.NodePosY = new IntegerEntity()
|
||||
}
|
||||
this.NodePosY.value = value
|
||||
this.NodePosY.value = Math.round(value)
|
||||
}
|
||||
|
||||
isDevelopmentOnly() {
|
||||
const nodeClass = this.getClass()
|
||||
return this.EnabledState?.toString() === "DevelopmentOnly"
|
||||
|| nodeClass.includes("Debug", Math.max(0, nodeClass.lastIndexOf(".")))
|
||||
}
|
||||
|
||||
getDelegatePin() {
|
||||
return this.CustomProperties?.find(pin => pin.PinType.PinCategory === "delegate")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -266,10 +266,9 @@ export default class PinEntity extends IEntity {
|
||||
&& pinReferenceEntity.pinGuid.valueOf() == targetPinEntity.PinId.valueOf()
|
||||
})
|
||||
if (indexElement >= 0) {
|
||||
if (this.LinkedTo.length == 1) {
|
||||
this.LinkedTo.splice(indexElement, 1)
|
||||
if (this.LinkedTo.length === 0 && !PinEntity.attributes.LinkedTo.showDefault) {
|
||||
this.LinkedTo = undefined
|
||||
} else {
|
||||
this.LinkedTo.splice(indexElement, 1)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -14,4 +14,12 @@ export default class SymbolEntity extends IEntity {
|
||||
super(values)
|
||||
/** @type {String} */ this.value
|
||||
}
|
||||
|
||||
valueOf() {
|
||||
return this.value
|
||||
}
|
||||
|
||||
toString() {
|
||||
return this.value
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ export default class ISerializer {
|
||||
}
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* @param {String} value
|
||||
* @returns {T}
|
||||
*/
|
||||
@@ -54,6 +55,7 @@ export default class ISerializer {
|
||||
}
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* @param {T} object
|
||||
* @param {Boolean} insideString
|
||||
* @returns {String}
|
||||
@@ -63,12 +65,14 @@ export default class ISerializer {
|
||||
}
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* @param {AnyValue} value
|
||||
* @param {String[]} fullKey
|
||||
* @param {Boolean} insideString
|
||||
*/
|
||||
writeValue(entity, value, fullKey, insideString) {
|
||||
const type = Utility.getType(value)
|
||||
// @ts-expect-error
|
||||
const serializer = SerializerFactory.getSerializer(type)
|
||||
if (!serializer) {
|
||||
throw new Error(`Unknown value type "${type.name}", a serializer must be registered in the SerializerFactory class, check initializeSerializerFactory.js`)
|
||||
@@ -81,6 +85,7 @@ export default class ISerializer {
|
||||
}
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* @param {String[]} key
|
||||
* @param {Object} object
|
||||
* @param {Boolean} insideString
|
||||
|
||||
@@ -46,7 +46,7 @@ export default class NodeTemplate extends ISelectableDraggableTemplate {
|
||||
<div class="ueb-node-inputs"></div>
|
||||
<div class="ueb-node-outputs"></div>
|
||||
</div>
|
||||
${this.element.enabledState?.toString() == "DevelopmentOnly" ? html`
|
||||
${this.element.entity.isDevelopmentOnly() ? html`
|
||||
<div class="ueb-node-developmentonly">
|
||||
<span class="ueb-node-developmentonly-text">Development Only</span>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user