Small refactoring, set variable node

This commit is contained in:
barsdeveloper
2022-11-19 18:40:20 +01:00
parent 0981c15372
commit b55779312b
34 changed files with 524 additions and 253 deletions

View File

@@ -354,7 +354,7 @@ ueb-node[data-selected=true] > .ueb-node-border {
padding: 1px;
box-shadow: inset 0 0 2px 0 black;
border-radius: var(--ueb-node-radius);
background: rgba(10, 10, 10, 0.8);
background: rgba(14, 16, 10, 0.8);
overflow: hidden;
}
@@ -484,18 +484,18 @@ ueb-node[data-advanced-display=Shown] .ueb-node-expansion > svg {
transform: scaleY(-1);
}
ueb-node.ueb-node-type-variable .ueb-node-wrapper,
ueb-node.ueb-node-type-variable .ueb-node-border,
ueb-node.ueb-node-type-variable {
ueb-node.ueb-node-style-glass .ueb-node-wrapper,
ueb-node.ueb-node-style-glass .ueb-node-border,
ueb-node.ueb-node-style-glass {
border-radius: 15px;
box-shadow: none;
}
ueb-node.ueb-node-type-variable .ueb-node-wrapper {
ueb-node.ueb-node-style-glass .ueb-node-wrapper {
border: 1px solid black;
box-shadow: 1px 1px 0 0 rgba(255, 255, 255, 0.6) inset, 0 -2px 2px 1px rgba(0, 0, 0, 0.5) inset;
background: linear-gradient(to bottom, rgba(255, 255, 255, 0.188) 0%, rgba(255, 255, 255, 0.063) 49%, rgba(0, 0, 0, 0.251) 49%), linear-gradient(to right, transparent 10%, rgba(var(--ueb-node-color), 0.3) 50%, transparent 90%);
background-size: 100%, 100% 82%;
background: linear-gradient(to bottom, rgba(255, 255, 255, 0.188) 0%, rgba(255, 255, 255, 0.063) 14px, rgba(0, 0, 0, 0.251) 14px), linear-gradient(to right, transparent 10%, rgba(var(--ueb-node-color), 0.3) 50%, transparent 90%);
background-size: 100%, 100% 28px;
background-repeat: repeat, no-repeat;
}
@@ -504,6 +504,20 @@ ueb-node[data-selected=true] .ueb-node-border {
background: none;
}
ueb-node.ueb-node-style-glass .ueb-node-top,
ueb-node.ueb-node-style-glass .ueb-node-name {
margin: 0;
box-shadow: none;
border-radius: 0;
background: none;
}
ueb-node.ueb-node-style-glass .ueb-node-top {
position: absolute;
left: 50%;
translate: -50%;
}
ueb-blueprint {
--ueb-pin-color-dim: #afafaf;
}
@@ -592,6 +606,10 @@ ueb-pin[data-linked=true] .ueb-pin-tofill {
visibility: hidden;
}
ueb-node[data-type="/Script/BlueprintGraph.K2Node_VariableSet"] ueb-pin[data-direction=output] .ueb-pin-content {
display: none;
}
.ueb-pin-input-wrapper {
padding-left: 8px;
}

View File

@@ -1 +1 @@
{"version":3,"sourceRoot":"","sources":["../../scss/style.scss","../../scss/ueb-knot.scss","../../scss/ueb-link.scss","../../scss/ueb-node.scss","../../scss/ueb-pin.scss","../../scss/ueb-ui-controls.scss","../../scss/ueb-window.scss"],"names":[],"mappings":"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AGJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;;AAGJ;EACI;EACA;EACA;;;ACzKR;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI;;;AAIR;EACI;EACA;EACA;EACA;;;AAGJ;EACI;EACA;;AAEA;EAEI;EACA;EACA;EACA;EACA;EACA;;AAGJ;EACI;EACA;;AAGJ;EACI;EACA;;;AAIR;AAAA;EAEI;EACA;EACA;EACA;;;AAGJ;EACI;EACA;;AAEA;EACI;;;AAIR;EACI;;;AAGJ;EACI;EACA;EACA;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;;;AAKA;EACI;EACA;EACA;EACA;EACA;EACA;;AAGJ;EACI;;;AC5FR;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA;;;AAGJ;EACI;EACA;;;AAGJ;EACI;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;;;AAGJ;AAAA;EAEI;EACA;;;AAGJ;EACI;EACA;;;AAGJ;EACI;EACA;EACA;EACA;EACA,YACI;;;AAWR;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGJ;EACI;EACA;;;AAGJ;AAAA;EAEI;EACA;EACA;;;AAGJ;EACI;EACA;;;AAGJ;EACI;EACA;;;AAGJ;EACI;;;AAGJ;EACI;;;AAGJ;EACI;;;AAGJ;EACI;EACA;;AAEA;EAEI;EACA;EACA;EACA;EACA;EACA;;AAGJ;EACI;;;AAIR;AAAA;EAEI;EACA;;;AAGJ;EACI;;;AAGJ;AAAA;EAEI;;;AAGJ;EACI;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;EACA;;;AAGJ;EACI;EACA;EACA;;AAEA;EACI;;;AAIR;EACI;;;AAGJ;EACI;;;AAGJ;EACI;;;AAGJ;EACI;;;AAGJ;EACI;;;AAGJ;EACI;;;AAGJ;EACI;;;AAGJ;EACI;;;AAGJ;EACI;;;AAGJ;EACI;;;AAGJ;EACI;EACA;;;AAGJ;EACI;EACA;EACA;EACA","file":"ueb-style.css"}
{"version":3,"sourceRoot":"","sources":["../../scss/style.scss","../../scss/ueb-knot.scss","../../scss/ueb-link.scss","../../scss/ueb-node.scss","../../scss/ueb-pin.scss","../../scss/ueb-ui-controls.scss","../../scss/ueb-window.scss"],"names":[],"mappings":"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ACI;EACA;EACA;EACA;EACA;EACA;;;AAGJ;EACI;;;AAGJ;EACI;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;;AAGJ;EACI;EACA;EACA;;;AC7KR;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI;;;AAIR;EACI;EACA;EACA;EACA;;;AAGJ;EACI;EACA;;AAEA;EAEI;EACA;EACA;EACA;EACA;EACA;;AAGJ;EACI;EACA;;AAGJ;EACI;EACA;;;AAIR;AAAA;EAEI;EACA;EACA;EACA;;;AAGJ;EACI;EACA;;AAEA;EACI;;;AAIR;EACI;;;AAGJ;EACI;EACA;EACA;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;;;AAKA;EACI;EACA;EACA;EACA;EACA;EACA;;AAGJ;EACI;;;AC5FR;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA;;;AAGJ;EACI;EACA;;;AAGJ;EACI;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;;;AAGJ;AAAA;EAEI;EACA;;;AAGJ;EACI;EACA;;;AAGJ;EACI;EACA;EACA;EACA;EACA,YACI;;;AAWR;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGJ;EACI;EACA;;;AAGJ;AAAA;EAEI;EACA;EACA;;;AAGJ;EACI;EACA;;;AAGJ;EACI;EACA;;;AAGJ;EACI;;;AAGJ;EACI;;;AAGJ;EACI;;;AAGJ;EACI;EACA;;AAEA;EAEI;EACA;EACA;EACA;EACA;EACA;;AAGJ;EACI;;;AAIR;AAAA;EAEI;EACA;;;AAGJ;EACI;;;AAGJ;AAAA;EAEI;;;AAGJ;EACI;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;EACA;;;AAGJ;EACI;EACA;EACA;;AAEA;EACI;;;AAIR;EACI;;;AAGJ;EACI;;;AAGJ;EACI;;;AAGJ;EACI;;;AAGJ;EACI;;;AAGJ;EACI;;;AAGJ;EACI;;;AAGJ;EACI;;;AAGJ;EACI;;;AAGJ;EACI;;;AAGJ;EACI;EACA;;;AAGJ;EACI;EACA;EACA;EACA","file":"ueb-style.css"}

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
{"version":3,"sourceRoot":"","sources":["../../scss/style.scss","../../scss/ueb-knot.scss","../../scss/ueb-link.scss","../../scss/ueb-node.scss","../../scss/ueb-pin.scss","../../scss/ueb-ui-controls.scss","../../scss/ueb-window.scss"],"names":[],"mappings":"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","file":"ueb-style.min.css"}
{"version":3,"sourceRoot":"","sources":["../../scss/style.scss","../../scss/ueb-knot.scss","../../scss/ueb-link.scss","../../scss/ueb-node.scss","../../scss/ueb-pin.scss","../../scss/ueb-ui-controls.scss","../../scss/ueb-window.scss"],"names":[],"mappings":"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","file":"ueb-style.min.css"}

302
dist/ueblueprint.js vendored
View File

@@ -136,9 +136,11 @@ class Configuration {
ifThenElse: "/Script/BlueprintGraph.K2Node_IfThenElse",
knot: "/Script/BlueprintGraph.K2Node_Knot",
macro: "/Script/BlueprintGraph.K2Node_MacroInstance",
makeArray: "/Script/BlueprintGraph.K2Node_MakeArray",
pawn: "/Script/Engine.Pawn",
reverseForEachLoop: "/Engine/EditorBlueprintResources/StandardMacros.StandardMacros:ReverseForEachLoop",
variableGet: "/Script/BlueprintGraph.K2Node_VariableGet",
variableSet: "/Script/BlueprintGraph.K2Node_VariableSet",
whileLoop: "/Engine/EditorBlueprintResources/StandardMacros.StandardMacros:WhileLoop",
}
static selectAllKeyboardKey = "(bCtrl=True,Key=A)"
@@ -464,9 +466,31 @@ class SerializerFactory {
}
}
/**
* @template T
* @typedef {import("./TypeInitialization").AnyValueConstructor<T>} AnyValueConstructor
*/
class UnionType {
#types
get types() {
return this.#types
}
/** @param {...AnyValueConstructor<any>} types */
constructor(...types) {
this.#types = types;
}
getFirstType() {
return this.#types[0]
}
}
/**
* @typedef {import("./IEntity").default} IEntity
* @typedef {IEntity | String | Number | Boolean | Array} AnyValue
* @typedef {import("./IEntity").default} IEntity
*/
/**
* @template {AnyValue} T
@@ -474,7 +498,7 @@ class SerializerFactory {
*/
/**
* @template {AnyValue} T
* @typedef {IEntityConstructor<T> | StringConstructor | NumberConstructor | BooleanConstructor | ArrayConstructor} AnyValueConstructor
* @typedef {IEntityConstructor<T> | StringConstructor | NumberConstructor | BooleanConstructor | ArrayConstructor | UnionType} AnyValueConstructor
*/
/** @template {AnyValue} T */
@@ -523,15 +547,22 @@ class TypeInitialization {
this.#ignored = v;
}
static isValueOfType(value, type) {
return value != null && (value instanceof type || value.constructor === type)
}
static sanitize(value, targetType) {
if (targetType === undefined) {
targetType = value?.constructor;
}
if (
targetType
// value is not of type targetType
&& !(value?.constructor === targetType || value instanceof targetType)
) {
if (targetType instanceof Array) {
let type = targetType.find(t => TypeInitialization.isValueOfType(value, t));
if (!type) {
type = targetType[0];
}
targetType = type;
}
if (targetType && !TypeInitialization.isValueOfType(value, targetType)) {
value = new targetType(value);
}
if (value instanceof Boolean || value instanceof Number || value instanceof String) {
@@ -720,7 +751,7 @@ class Utility {
/**
* @param {AnyValue | AnyValueConstructor<IEntity>} value
* @returns {AnyValueConstructor<IEntity>}
* @returns {AnyValueConstructor<IEntity> | AnyValueConstructor<IEntity>[]}
*/
static getType(value) {
if (value === null) {
@@ -729,6 +760,9 @@ class Utility {
if (value instanceof TypeInitialization) {
return Utility.getType(value.type)
}
if (value instanceof UnionType) {
return value.types
}
if (value instanceof Function) {
// value is already a constructor
return value
@@ -816,7 +850,7 @@ class Utility {
return value
.trim()
.replace(/^b/, "") // Remove leading b (for boolean values) or newlines
.replaceAll(/^K2_|(?<=[a-z])(?=[A-Z])|_|\s+/g, " ") // Insert a space between a lowercase and uppercase letter, instead of an underscore or multiple spaces
.replaceAll(/^K2(?:Node|node)?_|(?<=[a-z])(?=[A-Z])|_|\s+/g, " ") // Insert a space between a lowercase and uppercase letter, instead of an underscore or multiple spaces
.split(" ")
.map(v => Utility.capitalFirstLetter(v))
.join(" ")
@@ -937,7 +971,6 @@ class IEntity extends Observable {
if (defaultValue.serialized) {
defaultValue = "";
} else {
// @ts-expect-error
defaultType = defaultValue.type;
defaultValue = defaultValue.value;
if (defaultValue instanceof Function) {
@@ -945,6 +978,10 @@ class IEntity extends Observable {
}
}
}
if (defaultValue instanceof UnionType) {
defaultType = defaultValue.getFirstType();
defaultValue = TypeInitialization.sanitize(null, defaultType);
}
if (defaultValue instanceof Array) {
defaultValue = [];
}
@@ -1473,7 +1510,7 @@ class PinEntity extends IEntity {
static attributes = {
PinId: GuidEntity,
PinName: "",
PinFriendlyName: new TypeInitialization(LocalizedTextEntity, false, null),
PinFriendlyName: new TypeInitialization(new UnionType(LocalizedTextEntity, String), false, null),
PinToolTip: new TypeInitialization(String, false, ""),
Direction: new TypeInitialization(String, false, ""),
PinType: {
@@ -1522,7 +1559,7 @@ class PinEntity extends IEntity {
super(options);
/** @type {GuidEntity} */ this.PinId;
/** @type {String} */ this.PinName;
/** @type {LocalizedTextEntity} */ this.PinFriendlyName;
/** @type {LocalizedTextEntity | String} */ this.PinFriendlyName;
/** @type {String} */ this.PinToolTip;
/** @type {String} */ this.Direction;
/**
@@ -1579,6 +1616,10 @@ class PinEntity extends IEntity {
return this.DefaultValue
}
isExecution() {
return this.PinType.PinCategory === "exec"
}
isHidden() {
return this.bHidden
}
@@ -1672,7 +1713,7 @@ class ObjectEntity extends IEntity {
CustomProperties: [PinEntity],
}
static nameRegex = /(\w+)(?:_(\d+))?/
static nameRegex = /^(\w+?)(?:_(\d+))?$/
constructor(options = {}) {
super(options);
@@ -1745,6 +1786,10 @@ class ObjectEntity extends IEntity {
return `For Each ${this.Enum.getName()}`
case Configuration.nodeType.forEachLoopWithBreak:
return "For Each Loop with Break"
case Configuration.nodeType.variableGet:
return ""
case Configuration.nodeType.variableSet:
return "SET"
default:
if (this.getClass() === Configuration.nodeType.macro) {
return Utility.formatStringName(this.MacroGraphReference.getMacroName())
@@ -1796,10 +1841,9 @@ class Grammar {
P.string("("),
attributeType
.map(v => Grammar.getGrammarForType(r, Utility.getType(v)))
.reduce((accum, cur) =>
!cur || accum === r.AttributeAnyValue
? r.AttributeAnyValue
: accum.or(cur)
.reduce((accum, cur) => !cur || accum === r.AttributeAnyValue
? r.AttributeAnyValue
: accum.or(cur)
)
.trim(P.optWhitespace)
.sepBy(P.string(","))
@@ -1843,6 +1887,14 @@ class Grammar {
return r.SimpleSerializationVector
case String:
return r.String
case UnionType:
return attributeType.types
.map(v => Grammar.getGrammarForType(r, Utility.getType(v)))
.reduce((accum, cur) => !cur || accum === r.AttributeAnyValue
? r.AttributeAnyValue
: accum.or(cur))
case VariableReferenceEntity:
return r.VariableReference
case VectorEntity:
return r.Vector
default:
@@ -1892,7 +1944,7 @@ class Grammar {
.trim(P.optWhitespace) // Drop spaces around a attribute assignment
.sepBy(P.string(",")) // Assignments are separated by comma
.skip(P.regex(/,?/).then(P.optWhitespace)), // Optional trailing comma and maybe additional space
P.string(')'),
P.string(")"),
(_0, attributes, _2) => {
let values = {};
attributes.forEach(attributeSetter => attributeSetter(values));
@@ -1949,7 +2001,7 @@ class Grammar {
.desc('string (with possibility to escape the quote using \")')
/** @param {Grammar} r */
AttributeName = r => r.Word.sepBy1(P.string(".")).tieWith(".").desc('words separated by ""')
AttributeName = r => r.Word.sepBy1(P.string(".")).tieWith(".").desc("dot-separated words")
/* --- Entity --- */
@@ -2084,6 +2136,9 @@ class Grammar {
/** @param {Grammar} r */
FunctionReference = r => Grammar.createEntityGrammar(r, FunctionReferenceEntity)
/** @param {Grammar} r */
VariableReference = r => Grammar.createEntityGrammar(r, VariableReferenceEntity)
/** @param {Grammar} r */
MacroGraphReference = r => Grammar.createEntityGrammar(r, MacroGraphReferenceEntity)
@@ -3820,6 +3875,14 @@ class SVGIcon {
</svg>
`
static breakStruct = $`
<svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 14L10 12L11 11L13 13L14 12L14 15L11 15L12 14Z" fill="white"/>
<path d="M13 3L11 5L10 4L12 2L11 1L14 1L14 4L13 3Z" fill="white"/>
<path d="M7.975 6H3.025C1.90662 6 1 6.90662 1 8.025V8.475C1 9.59338 1.90662 10.5 3.025 10.5H7.975C9.09338 10.5 10 9.59338 10 8.475V8.025C10 6.90662 9.09338 6 7.975 6Z" fill="white"/>
</svg>
`
static cast = $`
<svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 12L16 7.5L12 3V12Z" fill="white"/>
@@ -3920,6 +3983,22 @@ class SVGIcon {
</svg>
`
static makeArray = $`
<svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M15 4H13V6H15V4Z" fill="white"/>
<path d="M15 7H13V9H15V7Z" fill="white"/>
<path d="M15 10H13V12H15V10Z" fill="white"/>
<path d="M12 4H10V6H12V4Z" fill="white"/>
<path d="M12 7H10V9H12V7Z" fill="white"/>
<path d="M12 10H10V12H12V10Z" fill="white"/>
<path d="M9 4H7V6H9V4Z" fill="white"/>
<path d="M9 7H7V9H9V7Z" fill="white"/>
<path d="M9 10H7V12H9V10Z" fill="white"/>
<path d="M3 4L1 1.99995L2 1L4 3L5 1.99995L5 5L2 5L3 4Z" fill="white"/>
<path d="M4 13L1.99995 15L1 14L3 12L1.99995 11L5 11L5 14L4 13Z" fill="white"/>
</svg>
`
static makeStruct = $`
<svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M3 4L1 1.99995L2 1L4 3L5 1.99995L5 5L2 5L3 4Z" fill="white"/>
@@ -4457,7 +4536,7 @@ class PinTemplate extends ITemplate {
/** @param {Map} changedProperties */
firstUpdated(changedProperties) {
super.firstUpdated(changedProperties);
this.element.style.setProperty("--ueb-pin-color-rgb", Configuration.getPinColor(this.element));
this.element.style.setProperty("--ueb-pin-color-rgb", Configuration.getPinColor(this.element).cssText);
this.#iconElement = this.element.querySelector(".ueb-pin-icon") ?? this.element;
}
@@ -4665,7 +4744,6 @@ class ISelectableDraggableTemplate extends IDraggablePositionedTemplate {
class NodeTemplate extends ISelectableDraggableTemplate {
static #nodeIcon = {
[Configuration.nodeType.callFunction]: SVGIcon.functionSymbol,
[Configuration.nodeType.doN]: SVGIcon.doN,
[Configuration.nodeType.dynamicCast]: SVGIcon.cast,
[Configuration.nodeType.executionSequence]: SVGIcon.sequence,
@@ -4675,6 +4753,7 @@ class NodeTemplate extends ISelectableDraggableTemplate {
[Configuration.nodeType.forLoop]: SVGIcon.loop,
[Configuration.nodeType.forLoopWithBreak]: SVGIcon.loop,
[Configuration.nodeType.ifThenElse]: SVGIcon.branchNode,
[Configuration.nodeType.makeArray]: SVGIcon.makeArray,
[Configuration.nodeType.whileLoop]: SVGIcon.loop,
default: SVGIcon.functionSymbol
}
@@ -4686,12 +4765,15 @@ class NodeTemplate extends ISelectableDraggableTemplate {
getColor() {
const functionColor = r$2`84, 122, 156`;
const pureFunctionColor = r$2`95, 129, 90`;
switch (this.element.entity.getClass()) {
case Configuration.nodeType.callFunction:
if (this.element.entity.bIsPureFunc) {
return r$2`95, 129, 90`
return pureFunctionColor
}
return functionColor
case Configuration.nodeType.makeArray:
return pureFunctionColor
case Configuration.nodeType.macro:
case Configuration.nodeType.executionSequence:
return r$2`150,150,150`
@@ -4750,6 +4832,9 @@ class NodeTemplate extends ISelectableDraggableTemplate {
if (icon) {
return icon
}
if (this.element.getNodeDisplayName().startsWith("Break")) {
return SVGIcon.breakStruct
}
if (this.element.entity.getClass() === Configuration.nodeType.macro) {
return SVGIcon.macro
}
@@ -4890,27 +4975,60 @@ class KnotNodeTemplate extends NodeTemplate {
* @typedef {import("../element/PinElement").default} PinElement
*/
class VariableNodeTemplate extends NodeTemplate {
class VariableAccessNodeTemplate extends NodeTemplate {
#hasInput = false
#hasOutput = false
#displayName = ""
/** @param {NodeElement} element */
constructed(element) {
super.constructed(element);
this.element.classList.add("ueb-node-type-variable");
this.element.classList.add("ueb-node-style-glass");
this.#displayName = this.element.getNodeDisplayName();
}
render() {
return $`
<div class="ueb-node-border">
<div class="ueb-node-wrapper">
<div class="ueb-node-outputs"></div>
${this.#displayName ? $`
<div class="ueb-node-top">
<div class="ueb-node-name">
<span class="ueb-node-name-text ueb-ellipsis-nowrap-text">
${this.#displayName}
</span>
</div>
</div>
` : w}
<div class="ueb-node-content">
${this.#hasInput ? $`
<div class="ueb-node-inputs"></div>
` : w}
${this.#hasOutput ? $`
<div class="ueb-node-outputs"></div>
` : w}
</div>
</div>
</div>
`
}
createPinElements() {
return this.element.getPinEntities()
.filter(v => !v.isHidden())
.map(v => {
this.#hasInput ||= v.isInput();
this.#hasOutput ||= v.isOutput();
return /** @type {PinElement} */(
new (ElementFactory.getConstructor("ueb-pin"))(v, undefined, this.element)
)
})
}
setupPins() {
super.setupPins();
let outputPin = this.element.getPinElements().find(p => p.isOutput());
let outputPin = this.element.getPinElements().find(p => !p.entity.isHidden() && !p.entity.isExecution());
this.element.style.setProperty("--ueb-node-color", outputPin.getColor().cssText);
}
}
@@ -4922,7 +5040,8 @@ class NodeElement extends ISelectableDraggableElement {
static #typeTemplateMap = {
[Configuration.nodeType.knot]: KnotNodeTemplate,
[Configuration.nodeType.variableGet]: VariableNodeTemplate,
[Configuration.nodeType.variableGet]: VariableAccessNodeTemplate,
[Configuration.nodeType.variableSet]: VariableAccessNodeTemplate,
}
static properties = {
@@ -6067,9 +6186,9 @@ class MouseIgnore extends IMouseClickDrag {
/**
* @extends PinTemplate<Boolean>
*/
class BoolPinTemplate extends PinTemplate {
class BoolInputPinTemplate extends PinTemplate {
/** @type {HTMLInputElement} */
/** @type {HTMLInputElement?} */
#input
#onChangeHandler = _ => this.element.setDefaultValue(this.#input.checked)
@@ -6078,12 +6197,12 @@ class BoolPinTemplate extends PinTemplate {
firstUpdated(changedProperties) {
super.firstUpdated(changedProperties);
this.#input = this.element.querySelector(".ueb-pin-input");
this.#input.addEventListener("change", this.#onChangeHandler);
this.#input?.addEventListener("change", this.#onChangeHandler);
}
cleanup() {
super.cleanup();
this.#input.removeEventListener("change", this.#onChangeHandler);
this.#input?.removeEventListener("change", this.#onChangeHandler);
}
createInputObjects() {
@@ -6263,8 +6382,8 @@ class INumericPinTemplate extends IInputPinTemplate {
/** @typedef {import("../entity/IntegerEntity").default} IntEntity */
/** @extends INumericPinTemplate<IntEntity> */
class IntPinTemplate extends INumericPinTemplate {
/** @extends INumericInputPinTemplate<IntEntity> */
class IntInputPinTemplate extends INumericPinTemplate {
setDefaultValue(values = [], rawValues = values) {
this.element.setDefaultValue(new IntegerEntity(values[0]));
@@ -6715,55 +6834,44 @@ class ColorPickerWindowTemplate extends WindowTemplate {
}
/**
* @typedef {import("../element/PinElement").default} PinElement
* @typedef {import("../element/WindowElement").default} WindowElement
* @typedef {import("../entity/LinearColorEntity").default} LinearColorEntity
*/
/** @extends PinTemplate<LinearColorEntity> */
class LinearColorPinTemplate extends PinTemplate {
/** @type {HTMLInputElement} */
#input
class LinearColorInputPinTemplate extends PinTemplate {
/** @type {WindowElement} */
#window
#launchColorPickerWindow =
/** @param {MouseEvent} e */
e => {
e.preventDefault();
this.element.blueprint.setFocused(true);
this.#window = /** @type {WindowElement} */ (
new (ElementFactory.getConstructor("ueb-window"))({
type: ColorPickerWindowTemplate,
windowOptions: {
// The created window will use the following functions to get and set the color
getPinColor: () => this.element.defaultValue,
/** @param {LinearColorEntity} color */
setPinColor: color => this.element.setDefaultValue(color),
},
})
);
this.element.blueprint.append(this.#window);
const windowApplyHandler = () => {
this.element.setDefaultValue(
/** @param {MouseEvent} e */
#launchColorPickerWindow = e => {
e.preventDefault();
this.element.blueprint.setFocused(true);
this.#window = /** @type {WindowElement} */ (
new (ElementFactory.getConstructor("ueb-window"))({
type: ColorPickerWindowTemplate,
windowOptions: {
// The created window will use the following functions to get and set the color
getPinColor: () => this.element.defaultValue,
/** @param {LinearColorEntity} color */
setPinColor: color => this.element.setDefaultValue(color),
},
})
);
this.element.blueprint.append(this.#window);
const windowApplyHandler = () => {
this.element.setDefaultValue(
/** @type {ColorPickerWindowTemplate} */(this.#window.template).color
);
};
const windowCloseHandler = () => {
this.#window.removeEventListener(Configuration.windowApplyEventName, windowApplyHandler);
this.#window.removeEventListener(Configuration.windowCloseEventName, windowCloseHandler);
this.#window = null;
};
this.#window.addEventListener(Configuration.windowApplyEventName, windowApplyHandler);
this.#window.addEventListener(Configuration.windowCloseEventName, windowCloseHandler);
}
/** @param {Map} changedProperties */
firstUpdated(changedProperties) {
super.firstUpdated(changedProperties);
this.#input = this.element.querySelector(".ueb-pin-input");
);
};
const windowCloseHandler = () => {
this.#window.removeEventListener(Configuration.windowApplyEventName, windowApplyHandler);
this.#window.removeEventListener(Configuration.windowCloseEventName, windowCloseHandler);
this.#window = null;
};
this.#window.addEventListener(Configuration.windowApplyEventName, windowApplyHandler);
this.#window.addEventListener(Configuration.windowCloseEventName, windowCloseHandler);
}
renderInput() {
@@ -6778,7 +6886,7 @@ class LinearColorPinTemplate extends PinTemplate {
/** @typedef {import("../element/PinElement").default} PinElement */
class NamePinTemplate extends IInputPinTemplate {
class NameInputPinTemplate extends IInputPinTemplate {
static singleLineInput = true
}
@@ -6787,7 +6895,7 @@ class NamePinTemplate extends IInputPinTemplate {
* @template {Number} T
* @extends INumericPinTemplate<T>
*/
class RealPinTemplate extends INumericPinTemplate {
class RealInputPinTemplate extends INumericPinTemplate {
setDefaultValue(values = [], rawValues = values) {
this.element.setDefaultValue(values[0]);
@@ -6814,7 +6922,7 @@ class ReferencePinTemplate extends PinTemplate {
/** @typedef {import("../entity/RotatorEntity").default} Rotator */
/** @extends INumericPinTemplate<Rotator> */
class RotatorPinTemplate extends INumericPinTemplate {
class RotatorInputPinTemplate extends INumericPinTemplate {
setDefaultValue(values = [], rawValues = values) {
if (!(this.element.entity.DefaultValue instanceof RotatorEntity)) {
@@ -6850,7 +6958,7 @@ class RotatorPinTemplate extends INumericPinTemplate {
}
/** @extends IInputPinTemplate<String> */
class StringPinTemplate extends IInputPinTemplate {
class StringInputPinTemplate extends IInputPinTemplate {
}
/** @typedef {import("../entity/LinearColorEntity").default} LinearColorEntity */
@@ -6859,7 +6967,7 @@ class StringPinTemplate extends IInputPinTemplate {
* @template {VectorEntity} T
* @extends INumericPinTemplate<T>
*/
class VectorPinTemplate extends INumericPinTemplate {
class VectorInputPinTemplate extends INumericPinTemplate {
/**
* @param {Number[]} values
@@ -6917,17 +7025,16 @@ class VectorPinTemplate extends INumericPinTemplate {
*/
class PinElement extends IElement {
static #typeTemplateMap = {
"/Script/CoreUObject.LinearColor": LinearColorPinTemplate,
"/Script/CoreUObject.Rotator": RotatorPinTemplate,
"/Script/CoreUObject.Vector": VectorPinTemplate,
"bool": BoolPinTemplate,
"exec": ExecPinTemplate,
"int": IntPinTemplate,
static #inputPinTemplates = {
"/Script/CoreUObject.LinearColor": LinearColorInputPinTemplate,
"/Script/CoreUObject.Rotator": RotatorInputPinTemplate,
"/Script/CoreUObject.Vector": VectorInputPinTemplate,
"bool": BoolInputPinTemplate,
"int": IntInputPinTemplate,
"MUTABLE_REFERENCE": ReferencePinTemplate,
"name": NamePinTemplate,
"real": RealPinTemplate,
"string": StringPinTemplate,
"name": NameInputPinTemplate,
"real": RealInputPinTemplate,
"string": StringInputPinTemplate,
}
static properties = {
@@ -6987,11 +7094,16 @@ class PinElement extends IElement {
* @return {new () => PinTemplate}
*/
static getTypeTemplate(pinEntity) {
let result = PinElement.#typeTemplateMap[
pinEntity.PinType.bIsReference && !pinEntity.PinType.bIsConst
? "MUTABLE_REFERENCE"
: pinEntity.getType()
];
if (pinEntity.PinType.bIsReference && !pinEntity.PinType.bIsConst) {
return PinElement.#inputPinTemplates["MUTABLE_REFERENCE"]
}
if (pinEntity.getType() === "exec") {
return ExecPinTemplate
}
let result;
if (pinEntity.isInput()) {
result = PinElement.#inputPinTemplates[pinEntity.getType()];
}
return result ?? PinTemplate
}
@@ -7326,6 +7438,7 @@ function initializeSerializerFactory() {
(array, insideString) =>
`(${array
.map(v =>
// @ts-expect-error
SerializerFactory.getSerializer(Utility.getType(v)).serialize(v, insideString) + ","
)
.join("")
@@ -7473,6 +7586,11 @@ function initializeSerializerFactory() {
)
);
SerializerFactory.registerSerializer(
VariableReferenceEntity,
new GeneralSerializer(bracketsWrapped, VariableReferenceEntity)
);
SerializerFactory.registerSerializer(
VectorEntity,
new GeneralSerializer(bracketsWrapped, VectorEntity)

File diff suppressed because one or more lines are too long

View File

@@ -112,9 +112,11 @@ export default class Configuration {
ifThenElse: "/Script/BlueprintGraph.K2Node_IfThenElse",
knot: "/Script/BlueprintGraph.K2Node_Knot",
macro: "/Script/BlueprintGraph.K2Node_MacroInstance",
makeArray: "/Script/BlueprintGraph.K2Node_MakeArray",
pawn: "/Script/Engine.Pawn",
reverseForEachLoop: "/Engine/EditorBlueprintResources/StandardMacros.StandardMacros:ReverseForEachLoop",
variableGet: "/Script/BlueprintGraph.K2Node_VariableGet",
variableSet: "/Script/BlueprintGraph.K2Node_VariableSet",
whileLoop: "/Engine/EditorBlueprintResources/StandardMacros.StandardMacros:WhileLoop",
}
static selectAllKeyboardKey = "(bCtrl=True,Key=A)"

View File

@@ -11,6 +11,14 @@ export default class SVGIcon {
</svg>
`
static breakStruct = html`
<svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 14L10 12L11 11L13 13L14 12L14 15L11 15L12 14Z" fill="white"/>
<path d="M13 3L11 5L10 4L12 2L11 1L14 1L14 4L13 3Z" fill="white"/>
<path d="M7.975 6H3.025C1.90662 6 1 6.90662 1 8.025V8.475C1 9.59338 1.90662 10.5 3.025 10.5H7.975C9.09338 10.5 10 9.59338 10 8.475V8.025C10 6.90662 9.09338 6 7.975 6Z" fill="white"/>
</svg>
`
static cast = html`
<svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 12L16 7.5L12 3V12Z" fill="white"/>
@@ -111,6 +119,22 @@ export default class SVGIcon {
</svg>
`
static makeArray = html`
<svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M15 4H13V6H15V4Z" fill="white"/>
<path d="M15 7H13V9H15V7Z" fill="white"/>
<path d="M15 10H13V12H15V10Z" fill="white"/>
<path d="M12 4H10V6H12V4Z" fill="white"/>
<path d="M12 7H10V9H12V7Z" fill="white"/>
<path d="M12 10H10V12H12V10Z" fill="white"/>
<path d="M9 4H7V6H9V4Z" fill="white"/>
<path d="M9 7H7V9H9V7Z" fill="white"/>
<path d="M9 10H7V12H9V10Z" fill="white"/>
<path d="M3 4L1 1.99995L2 1L4 3L5 1.99995L5 5L2 5L3 4Z" fill="white"/>
<path d="M4 13L1.99995 15L1 14L3 12L1.99995 11L5 11L5 14L4 13Z" fill="white"/>
</svg>
`
static makeStruct = html`
<svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M3 4L1 1.99995L2 1L4 3L5 1.99995L5 5L2 5L3 4Z" fill="white"/>

View File

@@ -1,5 +1,6 @@
import CalculatedType from "./entity/CalculatedType"
import TypeInitialization from "./entity/TypeInitialization"
import UnionType from "./entity/UnionType"
/**
* @typedef {import("./element/IElement").default} IElement
@@ -158,7 +159,7 @@ export default class Utility {
/**
* @param {AnyValue | AnyValueConstructor<IEntity>} value
* @returns {AnyValueConstructor<IEntity>}
* @returns {AnyValueConstructor<IEntity> | AnyValueConstructor<IEntity>[]}
*/
static getType(value) {
if (value === null) {
@@ -167,6 +168,9 @@ export default class Utility {
if (value instanceof TypeInitialization) {
return Utility.getType(value.type)
}
if (value instanceof UnionType) {
return value.types
}
if (value instanceof Function) {
// value is already a constructor
return value
@@ -254,7 +258,7 @@ export default class Utility {
return value
.trim()
.replace(/^b/, "") // Remove leading b (for boolean values) or newlines
.replaceAll(/^K2_|(?<=[a-z])(?=[A-Z])|_|\s+/g, " ") // Insert a space between a lowercase and uppercase letter, instead of an underscore or multiple spaces
.replaceAll(/^K2(?:Node|node)?_|(?<=[a-z])(?=[A-Z])|_|\s+/g, " ") // Insert a space between a lowercase and uppercase letter, instead of an underscore or multiple spaces
.split(" ")
.map(v => Utility.capitalFirstLetter(v))
.join(" ")

View File

@@ -8,7 +8,7 @@ import PinEntity from "../entity/PinEntity"
import PinReferenceEntity from "../entity/PinReferenceEntity"
import SerializerFactory from "../serialization/SerializerFactory"
import Utility from "../Utility"
import VariableNodeTemplate from "../template/VariableNodeTemplate"
import VariableAccessNodeTemplate from "../template/VariableAccessNodeTemplate"
/** @typedef {import("./IElement").default} IElement */
@@ -17,7 +17,8 @@ export default class NodeElement extends ISelectableDraggableElement {
static #typeTemplateMap = {
[Configuration.nodeType.knot]: KnotNodeTemplate,
[Configuration.nodeType.variableGet]: VariableNodeTemplate,
[Configuration.nodeType.variableGet]: VariableAccessNodeTemplate,
[Configuration.nodeType.variableSet]: VariableAccessNodeTemplate,
}
static properties = {

View File

@@ -1,21 +1,21 @@
import BoolPinTemplate from "../template/BoolPinTemplate"
import BoolInputPinTemplate from "../template/BoolPinTemplate"
import Configuration from "../Configuration"
import ElementFactory from "./ElementFactory"
import ExecPinTemplate from "../template/ExecPinTemplate"
import GuidEntity from "../entity/GuidEntity"
import IElement from "./IElement"
import IntPinTemplate from "../template/IntPinTemplate"
import IntInputPinTemplate from "../template/IntPinTemplate"
import ISerializer from "../serialization/ISerializer"
import LinearColorEntity from "../entity/LinearColorEntity"
import LinearColorPinTemplate from "../template/LinearColorPinTemplate"
import NamePinTemplate from "../template/NamePinTemplate"
import LinearColorInputPinTemplate from "../template/LinearColorPinTemplate"
import NameInputPinTemplate from "../template/NamePinTemplate"
import PinTemplate from "../template/PinTemplate"
import RealPinTemplate from "../template/RealPinTemplate"
import RealInputPinTemplate from "../template/RealInputPinTemplate"
import ReferencePinTemplate from "../template/ReferencePinTemplate"
import RotatorPinTemplate from "../template/RotatorPinTemplate"
import StringPinTemplate from "../template/StringPinTemplate"
import RotatorInputPinTemplate from "../template/RotatorInputPinTemplate"
import StringInputPinTemplate from "../template/StringInputPinTemplate"
import Utility from "../Utility"
import VectorPinTemplate from "../template/VectorPinTemplate"
import VectorInputPinTemplate from "../template/VectorInputPinTemplate"
/**
* @typedef {import("../entity/PinReferenceEntity").default} PinReferenceEntity
@@ -33,17 +33,16 @@ import VectorPinTemplate from "../template/VectorPinTemplate"
*/
export default class PinElement extends IElement {
static #typeTemplateMap = {
"/Script/CoreUObject.LinearColor": LinearColorPinTemplate,
"/Script/CoreUObject.Rotator": RotatorPinTemplate,
"/Script/CoreUObject.Vector": VectorPinTemplate,
"bool": BoolPinTemplate,
"exec": ExecPinTemplate,
"int": IntPinTemplate,
static #inputPinTemplates = {
"/Script/CoreUObject.LinearColor": LinearColorInputPinTemplate,
"/Script/CoreUObject.Rotator": RotatorInputPinTemplate,
"/Script/CoreUObject.Vector": VectorInputPinTemplate,
"bool": BoolInputPinTemplate,
"int": IntInputPinTemplate,
"MUTABLE_REFERENCE": ReferencePinTemplate,
"name": NamePinTemplate,
"real": RealPinTemplate,
"string": StringPinTemplate,
"name": NameInputPinTemplate,
"real": RealInputPinTemplate,
"string": StringInputPinTemplate,
}
static properties = {
@@ -103,11 +102,16 @@ export default class PinElement extends IElement {
* @return {new () => PinTemplate}
*/
static getTypeTemplate(pinEntity) {
let result = PinElement.#typeTemplateMap[
pinEntity.PinType.bIsReference && !pinEntity.PinType.bIsConst
? "MUTABLE_REFERENCE"
: pinEntity.getType()
]
if (pinEntity.PinType.bIsReference && !pinEntity.PinType.bIsConst) {
return PinElement.#inputPinTemplates["MUTABLE_REFERENCE"]
}
if (pinEntity.getType() === "exec") {
return ExecPinTemplate
}
let result
if (pinEntity.isInput()) {
result = PinElement.#inputPinTemplates[pinEntity.getType()]
}
return result ?? PinTemplate
}

View File

@@ -3,6 +3,7 @@ import Observable from "../Observable"
import SerializerFactory from "../serialization/SerializerFactory"
import TypeInitialization from "./TypeInitialization"
import Utility from "../Utility"
import UnionType from "./UnionType"
/**
* @template {IEntity} T
@@ -81,7 +82,6 @@ export default class IEntity extends Observable {
if (defaultValue.serialized) {
defaultValue = ""
} else {
// @ts-expect-error
defaultType = defaultValue.type
defaultValue = defaultValue.value
if (defaultValue instanceof Function) {
@@ -89,6 +89,10 @@ export default class IEntity extends Observable {
}
}
}
if (defaultValue instanceof UnionType) {
defaultType = defaultValue.getFirstType()
defaultValue = TypeInitialization.sanitize(null, defaultType)
}
if (defaultValue instanceof Array) {
defaultValue = []
}

View File

@@ -33,7 +33,7 @@ export default class ObjectEntity extends IEntity {
CustomProperties: [PinEntity],
}
static nameRegex = /(\w+)(?:_(\d+))?/
static nameRegex = /^(\w+?)(?:_(\d+))?$/
constructor(options = {}) {
super(options)
@@ -107,6 +107,10 @@ export default class ObjectEntity extends IEntity {
return `For Each ${this.Enum.getName()}`
case Configuration.nodeType.forEachLoopWithBreak:
return "For Each Loop with Break"
case Configuration.nodeType.variableGet:
return ""
case Configuration.nodeType.variableSet:
return "SET"
default:
if (this.getClass() === Configuration.nodeType.macro) {
return Utility.formatStringName(this.MacroGraphReference.getMacroName())

View File

@@ -10,6 +10,7 @@ import RotatorEntity from "./RotatorEntity"
import SimpleSerializationRotatorEntity from "./SimpleSerializationRotatorEntity"
import SimpleSerializationVectorEntity from "./SimpleSerializationVectorEntity"
import TypeInitialization from "./TypeInitialization"
import UnionType from "./UnionType"
import VectorEntity from "./VectorEntity"
/** @typedef {import("./TypeInitialization").AnyValue} AnyValue */
@@ -36,7 +37,7 @@ export default class PinEntity extends IEntity {
static attributes = {
PinId: GuidEntity,
PinName: "",
PinFriendlyName: new TypeInitialization(LocalizedTextEntity, false, null),
PinFriendlyName: new TypeInitialization(new UnionType(LocalizedTextEntity, String), false, null),
PinToolTip: new TypeInitialization(String, false, ""),
Direction: new TypeInitialization(String, false, ""),
PinType: {
@@ -85,7 +86,7 @@ export default class PinEntity extends IEntity {
super(options)
/** @type {GuidEntity} */ this.PinId
/** @type {String} */ this.PinName
/** @type {LocalizedTextEntity} */ this.PinFriendlyName
/** @type {LocalizedTextEntity | String} */ this.PinFriendlyName
/** @type {String} */ this.PinToolTip
/** @type {String} */ this.Direction
/**
@@ -142,6 +143,10 @@ export default class PinEntity extends IEntity {
return this.DefaultValue
}
isExecution() {
return this.PinType.PinCategory === "exec"
}
isHidden() {
return this.bHidden
}

View File

@@ -1,7 +1,8 @@
import UnionType from "./UnionType"
/**
* @typedef {import("./IEntity").default} IEntity
* @typedef {IEntity | String | Number | Boolean | Array} AnyValue
* @typedef {import("./IEntity").default} IEntity
*/
/**
* @template {AnyValue} T
@@ -9,7 +10,7 @@
*/
/**
* @template {AnyValue} T
* @typedef {IEntityConstructor<T> | StringConstructor | NumberConstructor | BooleanConstructor | ArrayConstructor} AnyValueConstructor
* @typedef {IEntityConstructor<T> | StringConstructor | NumberConstructor | BooleanConstructor | ArrayConstructor | UnionType} AnyValueConstructor
*/
/** @template {AnyValue} T */
@@ -58,15 +59,22 @@ export default class TypeInitialization {
this.#ignored = v
}
static isValueOfType(value, type) {
return value != null && (value instanceof type || value.constructor === type)
}
static sanitize(value, targetType) {
if (targetType === undefined) {
targetType = value?.constructor
}
if (
targetType
// value is not of type targetType
&& !(value?.constructor === targetType || value instanceof targetType)
) {
if (targetType instanceof Array) {
let type = targetType.find(t => TypeInitialization.isValueOfType(value, t))
if (!type) {
type = targetType[0]
}
targetType = type
}
if (targetType && !TypeInitialization.isValueOfType(value, targetType)) {
value = new targetType(value)
}
if (value instanceof Boolean || value instanceof Number || value instanceof String) {

21
js/entity/UnionType.js Normal file
View File

@@ -0,0 +1,21 @@
/**
* @template T
* @typedef {import("./TypeInitialization").AnyValueConstructor<T>} AnyValueConstructor
*/
export default class UnionType {
#types
get types() {
return this.#types
}
/** @param {...AnyValueConstructor<any>} types */
constructor(...types) {
this.#types = types
}
getFirstType() {
return this.#types[0]
}
}

View File

@@ -19,8 +19,10 @@ import RotatorEntity from "../entity/RotatorEntity"
import SimpleSerializationRotatorEntity from "../entity/SimpleSerializationRotatorEntity"
import SimpleSerializationVectorEntity from "../entity/SimpleSerializationVectorEntity"
import TypeInitialization from "../entity/TypeInitialization"
import UnionType from "../entity/UnionType"
import Utility from "../Utility"
import VectorEntity from "../entity/VectorEntity"
import VariableReferenceEntity from "../entity/VariableReferenceEntity"
let P = Parsimmon
@@ -43,10 +45,9 @@ export default class Grammar {
P.string("("),
attributeType
.map(v => Grammar.getGrammarForType(r, Utility.getType(v)))
.reduce((accum, cur) =>
!cur || accum === r.AttributeAnyValue
? r.AttributeAnyValue
: accum.or(cur)
.reduce((accum, cur) => !cur || accum === r.AttributeAnyValue
? r.AttributeAnyValue
: accum.or(cur)
)
.trim(P.optWhitespace)
.sepBy(P.string(","))
@@ -90,6 +91,14 @@ export default class Grammar {
return r.SimpleSerializationVector
case String:
return r.String
case UnionType:
return attributeType.types
.map(v => Grammar.getGrammarForType(r, Utility.getType(v)))
.reduce((accum, cur) => !cur || accum === r.AttributeAnyValue
? r.AttributeAnyValue
: accum.or(cur))
case VariableReferenceEntity:
return r.VariableReference
case VectorEntity:
return r.Vector
default:
@@ -139,7 +148,7 @@ export default class Grammar {
.trim(P.optWhitespace) // Drop spaces around a attribute assignment
.sepBy(P.string(",")) // Assignments are separated by comma
.skip(P.regex(/,?/).then(P.optWhitespace)), // Optional trailing comma and maybe additional space
P.string(')'),
P.string(")"),
(_0, attributes, _2) => {
let values = {}
attributes.forEach(attributeSetter => attributeSetter(values))
@@ -196,7 +205,7 @@ export default class Grammar {
.desc('string (with possibility to escape the quote using \")')
/** @param {Grammar} r */
AttributeName = r => r.Word.sepBy1(P.string(".")).tieWith(".").desc('words separated by ""')
AttributeName = r => r.Word.sepBy1(P.string(".")).tieWith(".").desc("dot-separated words")
/* --- Entity --- */
@@ -331,6 +340,9 @@ export default class Grammar {
/** @param {Grammar} r */
FunctionReference = r => Grammar.createEntityGrammar(r, FunctionReferenceEntity)
/** @param {Grammar} r */
VariableReference = r => Grammar.createEntityGrammar(r, VariableReferenceEntity)
/** @param {Grammar} r */
MacroGraphReference = r => Grammar.createEntityGrammar(r, MacroGraphReferenceEntity)

View File

@@ -22,6 +22,7 @@ import SimpleSerializationRotatorEntity from "../entity/SimpleSerializationRotat
import SimpleSerializationVectorEntity from "../entity/SimpleSerializationVectorEntity"
import ToStringSerializer from "./ToStringSerializer"
import Utility from "../Utility"
import VariableReferenceEntity from "../entity/VariableReferenceEntity"
import VectorEntity from "../entity/VectorEntity"
export default function initializeSerializerFactory() {
@@ -43,6 +44,7 @@ export default function initializeSerializerFactory() {
(array, insideString) =>
`(${array
.map(v =>
// @ts-expect-error
SerializerFactory.getSerializer(Utility.getType(v)).serialize(v, insideString) + ","
)
.join("")
@@ -190,6 +192,11 @@ export default function initializeSerializerFactory() {
)
)
SerializerFactory.registerSerializer(
VariableReferenceEntity,
new GeneralSerializer(bracketsWrapped, VariableReferenceEntity)
)
SerializerFactory.registerSerializer(
VectorEntity,
new GeneralSerializer(bracketsWrapped, VectorEntity)

View File

@@ -5,9 +5,9 @@ import PinTemplate from "./PinTemplate"
/**
* @extends PinTemplate<Boolean>
*/
export default class BoolPinTemplate extends PinTemplate {
export default class BoolInputPinTemplate extends PinTemplate {
/** @type {HTMLInputElement} */
/** @type {HTMLInputElement?} */
#input
#onChangeHandler = _ => this.element.setDefaultValue(this.#input.checked)
@@ -16,12 +16,12 @@ export default class BoolPinTemplate extends PinTemplate {
firstUpdated(changedProperties) {
super.firstUpdated(changedProperties)
this.#input = this.element.querySelector(".ueb-pin-input")
this.#input.addEventListener("change", this.#onChangeHandler)
this.#input?.addEventListener("change", this.#onChangeHandler)
}
cleanup() {
super.cleanup()
this.#input.removeEventListener("change", this.#onChangeHandler)
this.#input?.removeEventListener("change", this.#onChangeHandler)
}
createInputObjects() {

View File

@@ -1,11 +1,11 @@
import { html } from "lit"
import IntegerEntity from "../entity/IntegerEntity"
import INumericPinTemplate from "./INumericPinTemplate"
import INumericInputPinTemplate from "./INumericInputPinTemplate"
/** @typedef {import("../entity/IntegerEntity").default} IntEntity */
/** @extends INumericPinTemplate<IntEntity> */
export default class IntPinTemplate extends INumericPinTemplate {
/** @extends INumericInputPinTemplate<IntEntity> */
export default class IntInputPinTemplate extends INumericInputPinTemplate {
setDefaultValue(values = [], rawValues = values) {
this.element.setDefaultValue(new IntegerEntity(values[0]))

View File

@@ -5,55 +5,44 @@ import ElementFactory from "../element/ElementFactory"
import PinTemplate from "./PinTemplate"
/**
* @typedef {import("../element/PinElement").default} PinElement
* @typedef {import("../element/WindowElement").default} WindowElement
* @typedef {import("../entity/LinearColorEntity").default} LinearColorEntity
*/
/** @extends PinTemplate<LinearColorEntity> */
export default class LinearColorPinTemplate extends PinTemplate {
/** @type {HTMLInputElement} */
#input
export default class LinearColorInputPinTemplate extends PinTemplate {
/** @type {WindowElement} */
#window
#launchColorPickerWindow =
/** @param {MouseEvent} e */
e => {
e.preventDefault()
this.element.blueprint.setFocused(true)
this.#window = /** @type {WindowElement} */ (
new (ElementFactory.getConstructor("ueb-window"))({
type: ColorPickerWindowTemplate,
windowOptions: {
// The created window will use the following functions to get and set the color
getPinColor: () => this.element.defaultValue,
/** @param {LinearColorEntity} color */
setPinColor: color => this.element.setDefaultValue(color),
},
})
)
this.element.blueprint.append(this.#window)
const windowApplyHandler = () => {
this.element.setDefaultValue(
/** @param {MouseEvent} e */
#launchColorPickerWindow = e => {
e.preventDefault()
this.element.blueprint.setFocused(true)
this.#window = /** @type {WindowElement} */ (
new (ElementFactory.getConstructor("ueb-window"))({
type: ColorPickerWindowTemplate,
windowOptions: {
// The created window will use the following functions to get and set the color
getPinColor: () => this.element.defaultValue,
/** @param {LinearColorEntity} color */
setPinColor: color => this.element.setDefaultValue(color),
},
})
)
this.element.blueprint.append(this.#window)
const windowApplyHandler = () => {
this.element.setDefaultValue(
/** @type {ColorPickerWindowTemplate} */(this.#window.template).color
)
}
const windowCloseHandler = () => {
this.#window.removeEventListener(Configuration.windowApplyEventName, windowApplyHandler)
this.#window.removeEventListener(Configuration.windowCloseEventName, windowCloseHandler)
this.#window = null
}
this.#window.addEventListener(Configuration.windowApplyEventName, windowApplyHandler)
this.#window.addEventListener(Configuration.windowCloseEventName, windowCloseHandler)
)
}
/** @param {Map} changedProperties */
firstUpdated(changedProperties) {
super.firstUpdated(changedProperties)
this.#input = this.element.querySelector(".ueb-pin-input")
const windowCloseHandler = () => {
this.#window.removeEventListener(Configuration.windowApplyEventName, windowApplyHandler)
this.#window.removeEventListener(Configuration.windowCloseEventName, windowCloseHandler)
this.#window = null
}
this.#window.addEventListener(Configuration.windowApplyEventName, windowApplyHandler)
this.#window.addEventListener(Configuration.windowCloseEventName, windowCloseHandler)
}
renderInput() {

View File

@@ -2,7 +2,7 @@ import IInputPinTemplate from "./IInputPinTemplate"
/** @typedef {import("../element/PinElement").default} PinElement */
export default class NamePinTemplate extends IInputPinTemplate {
export default class NameInputPinTemplate extends IInputPinTemplate {
static singleLineInput = true
}

View File

@@ -13,7 +13,6 @@ import SVGIcon from "../SVGIcon"
export default class NodeTemplate extends ISelectableDraggableTemplate {
static #nodeIcon = {
[Configuration.nodeType.callFunction]: SVGIcon.functionSymbol,
[Configuration.nodeType.doN]: SVGIcon.doN,
[Configuration.nodeType.dynamicCast]: SVGIcon.cast,
[Configuration.nodeType.executionSequence]: SVGIcon.sequence,
@@ -23,6 +22,7 @@ export default class NodeTemplate extends ISelectableDraggableTemplate {
[Configuration.nodeType.forLoop]: SVGIcon.loop,
[Configuration.nodeType.forLoopWithBreak]: SVGIcon.loop,
[Configuration.nodeType.ifThenElse]: SVGIcon.branchNode,
[Configuration.nodeType.makeArray]: SVGIcon.makeArray,
[Configuration.nodeType.whileLoop]: SVGIcon.loop,
default: SVGIcon.functionSymbol
}
@@ -34,12 +34,15 @@ export default class NodeTemplate extends ISelectableDraggableTemplate {
getColor() {
const functionColor = css`84, 122, 156`
const pureFunctionColor = css`95, 129, 90`
switch (this.element.entity.getClass()) {
case Configuration.nodeType.callFunction:
if (this.element.entity.bIsPureFunc) {
return css`95, 129, 90`
return pureFunctionColor
}
return functionColor
case Configuration.nodeType.makeArray:
return pureFunctionColor
case Configuration.nodeType.macro:
case Configuration.nodeType.executionSequence:
return css`150,150,150`
@@ -98,6 +101,9 @@ export default class NodeTemplate extends ISelectableDraggableTemplate {
if (icon) {
return icon
}
if (this.element.getNodeDisplayName().startsWith("Break")) {
return SVGIcon.breakStruct
}
if (this.element.entity.getClass() === Configuration.nodeType.macro) {
return SVGIcon.macro
}

View File

@@ -80,7 +80,7 @@ export default class PinTemplate extends ITemplate {
/** @param {Map} changedProperties */
firstUpdated(changedProperties) {
super.firstUpdated(changedProperties)
this.element.style.setProperty("--ueb-pin-color-rgb", Configuration.getPinColor(this.element))
this.element.style.setProperty("--ueb-pin-color-rgb", Configuration.getPinColor(this.element).cssText)
this.#iconElement = this.element.querySelector(".ueb-pin-icon") ?? this.element
}

View File

@@ -1,13 +1,13 @@
import { html } from "lit"
import IInputPinTemplate from "./IInputPinTemplate"
import INumericPinTemplate from "./INumericPinTemplate"
import INumericPinTemplate from "./INumericInputPinTemplate"
import Utility from "../Utility"
/**
* @template {Number} T
* @extends INumericPinTemplate<T>
*/
export default class RealPinTemplate extends INumericPinTemplate {
export default class RealInputPinTemplate extends INumericPinTemplate {
setDefaultValue(values = [], rawValues = values) {
this.element.setDefaultValue(values[0])

View File

@@ -1,12 +1,12 @@
import { html } from "lit"
import IInputPinTemplate from "./IInputPinTemplate"
import INumericPinTemplate from "./INumericPinTemplate"
import INumericPinTemplate from "./INumericInputPinTemplate"
import RotatorEntity from "../entity/RotatorEntity"
/** @typedef {import("../entity/RotatorEntity").default} Rotator */
/** @extends INumericPinTemplate<Rotator> */
export default class RotatorPinTemplate extends INumericPinTemplate {
export default class RotatorInputPinTemplate extends INumericPinTemplate {
setDefaultValue(values = [], rawValues = values) {
if (!(this.element.entity.DefaultValue instanceof RotatorEntity)) {

View File

@@ -1,5 +1,5 @@
import IInputPinTemplate from "./IInputPinTemplate"
/** @extends IInputPinTemplate<String> */
export default class StringPinTemplate extends IInputPinTemplate {
export default class StringInputPinTemplate extends IInputPinTemplate {
}

View File

@@ -0,0 +1,66 @@
import { html, nothing } from "lit"
import ElementFactory from "../element/ElementFactory"
import NodeTemplate from "./NodeTemplate"
/**
* @typedef {import("../element/NodeElement").default} NodeElement
* @typedef {import("../element/PinElement").default} PinElement
*/
export default class VariableAccessNodeTemplate extends NodeTemplate {
#hasInput = false
#hasOutput = false
#displayName = ""
/** @param {NodeElement} element */
constructed(element) {
super.constructed(element)
this.element.classList.add("ueb-node-style-glass")
this.#displayName = this.element.getNodeDisplayName()
}
render() {
return html`
<div class="ueb-node-border">
<div class="ueb-node-wrapper">
${this.#displayName ? html`
<div class="ueb-node-top">
<div class="ueb-node-name">
<span class="ueb-node-name-text ueb-ellipsis-nowrap-text">
${this.#displayName}
</span>
</div>
</div>
` : nothing}
<div class="ueb-node-content">
${this.#hasInput ? html`
<div class="ueb-node-inputs"></div>
` : nothing}
${this.#hasOutput ? html`
<div class="ueb-node-outputs"></div>
` : nothing}
</div>
</div>
</div>
`
}
createPinElements() {
return this.element.getPinEntities()
.filter(v => !v.isHidden())
.map(v => {
this.#hasInput ||= v.isInput()
this.#hasOutput ||= v.isOutput()
return /** @type {PinElement} */(
new (ElementFactory.getConstructor("ueb-pin"))(v, undefined, this.element)
)
})
}
setupPins() {
super.setupPins()
let outputPin = this.element.getPinElements().find(p => !p.entity.isHidden() && !p.entity.isExecution())
this.element.style.setProperty("--ueb-node-color", outputPin.getColor().cssText)
}
}

View File

@@ -1,35 +0,0 @@
import { html } from "lit"
import Configuration from "../Configuration"
import ElementFactory from "../element/ElementFactory"
import KnotPinTemplate from "./KnotPinTemplate"
import NodeTemplate from "./NodeTemplate"
/**
* @typedef {import("../element/NodeElement").default} NodeElement
* @typedef {import("../element/PinElement").default} PinElement
*/
export default class VariableNodeTemplate extends NodeTemplate {
/** @param {NodeElement} element */
constructed(element) {
super.constructed(element)
this.element.classList.add("ueb-node-type-variable")
}
render() {
return html`
<div class="ueb-node-border">
<div class="ueb-node-wrapper">
<div class="ueb-node-outputs"></div>
</div>
</div>
`
}
setupPins() {
super.setupPins()
let outputPin = this.element.getPinElements().find(p => p.isOutput())
this.element.style.setProperty("--ueb-node-color", outputPin.getColor().cssText)
}
}

View File

@@ -1,5 +0,0 @@
import NodeTemplate from "./NodeTemplate"
export default class VariadicNodeTemplate extends NodeTemplate {
}

View File

@@ -1,6 +1,6 @@
import { html } from "lit"
import IInputPinTemplate from "./IInputPinTemplate"
import INumericPinTemplate from "./INumericPinTemplate"
import INumericPinTemplate from "./INumericInputPinTemplate"
import Utility from "../Utility"
import VectorEntity from "../entity/VectorEntity"
@@ -10,7 +10,7 @@ import VectorEntity from "../entity/VectorEntity"
* @template {VectorEntity} T
* @extends INumericPinTemplate<T>
*/
export default class VectorPinTemplate extends INumericPinTemplate {
export default class VectorInputPinTemplate extends INumericPinTemplate {
/**
* @param {Number[]} values

View File

@@ -51,7 +51,7 @@ ueb-node[data-selected="true"]>.ueb-node-border {
padding: 1px;
box-shadow: inset 0 0 2px 0 black;
border-radius: var(--ueb-node-radius);
background: rgba(10, 10, 10, 0.8);
background: rgba(14, 16, 10, 0.8);
overflow: hidden;
}
@@ -194,20 +194,20 @@ ueb-node[data-advanced-display="Shown"] .ueb-node-expansion>svg {
transform: scaleY(-1)
}
ueb-node.ueb-node-type-variable .ueb-node-wrapper,
ueb-node.ueb-node-type-variable .ueb-node-border,
ueb-node.ueb-node-type-variable {
ueb-node.ueb-node-style-glass .ueb-node-wrapper,
ueb-node.ueb-node-style-glass .ueb-node-border,
ueb-node.ueb-node-style-glass {
border-radius: 15px;
box-shadow: none;
}
ueb-node.ueb-node-type-variable .ueb-node-wrapper {
ueb-node.ueb-node-style-glass .ueb-node-wrapper {
border: 1px solid black;
box-shadow: 1px 1px 0 0 rgba(255, 255, 255, 0.6) inset, 0 -2px 2px 1px rgba(0, 0, 0, 0.5) inset;
background:
linear-gradient(to bottom, rgba(255, 255, 255, 0.188) 0%, rgba(255, 255, 255, 0.063) 49%, rgba(0, 0, 0, 0.251) 49%),
linear-gradient(to bottom, rgba(255, 255, 255, 0.188) 0%, rgba(255, 255, 255, 0.063) 14px, rgba(0, 0, 0, 0.251) 14px),
linear-gradient(to right, transparent 10%, rgba(var(--ueb-node-color), 0.3) 50%, transparent 90%);
background-size: 100%, 100% 82%;
background-size: 100%, 100% 28px;
background-repeat: repeat, no-repeat;
}
@@ -215,3 +215,17 @@ ueb-node[data-selected="true"] .ueb-node-border {
box-shadow: inset 0 0 0px 6px #ce8700;
background: none;
}
ueb-node.ueb-node-style-glass .ueb-node-top,
ueb-node.ueb-node-style-glass .ueb-node-name {
margin: 0;
box-shadow: none;
border-radius: 0;
background: none;
}
ueb-node.ueb-node-style-glass .ueb-node-top {
position: absolute;
left: 50%;
translate: -50%;
}

View File

@@ -87,6 +87,10 @@ ueb-pin[data-linked="true"] .ueb-pin-tofill {
visibility: hidden;
}
ueb-node[data-type="/Script/BlueprintGraph.K2Node_VariableSet"] ueb-pin[data-direction="output"] .ueb-pin-content {
display: none;
}
.ueb-pin-input-wrapper {
padding-left: 8px;
}