diff --git a/js/ETypesNames.js b/js/ETypesNames.js new file mode 100644 index 0000000..1066bc8 --- /dev/null +++ b/js/ETypesNames.js @@ -0,0 +1,17 @@ +export default class ETypesNames { + + constructor(type) { + switch (type) { + case 'Class': + case 'None': + this.value = type + break + default: + throw new Error('Unexpected type name') + } + } + + toString() { + return this.value + } +} \ No newline at end of file diff --git a/js/FGuid.js b/js/FGuid.js new file mode 100644 index 0000000..96f1e7b --- /dev/null +++ b/js/FGuid.js @@ -0,0 +1,20 @@ +export default class FGuid { + constructor(guid) { + if (guid?.constructor?.name === 'String') { + this.value = guid + } else if (guid?.constructor?.name === 'FGuid') { + this.value = guid.value + } else { + let random = new Uint32Array(4); + crypto.getRandomValues(random) + this.value = "" + random.forEach(n => { + this.value += ('00000000' + n.toString(16).toUpperCase()).slice(-8) + }) + } + } + + toString() { + return this.value + } +} \ No newline at end of file diff --git a/js/UEBlueprintObject.js b/js/UEBlueprintObject.js index fe29a4a..8eb455c 100644 --- a/js/UEBlueprintObject.js +++ b/js/UEBlueprintObject.js @@ -84,10 +84,6 @@ export default class UEBlueprintObject extends USelectableDraggable { } this.style.setProperty('--ueb-position-x', this.location[0]) this.style.setProperty('--ueb-position-y', this.location[1]) - - let aDiv = document.createElement('div') - aDiv.innerHTML = this.render() - this.appendChild(aDiv.firstElementChild) } } diff --git a/js/UGraphEntity.js b/js/UGraphEntity.js new file mode 100644 index 0000000..5c46d18 --- /dev/null +++ b/js/UGraphEntity.js @@ -0,0 +1,22 @@ +/** + * A Graph Entity is an element that can stay directly (as a first child) on the blueprint grid. Those entities are either nodes or links + */ +export default class UGraphEntity extends HTMLElement { + constructor() { + super() + /** @type {import("./UEBlueprint").default}" */ + this.blueprint = null + } + + connectedCallback() { + this.blueprint = this.closest('u-blueprint') + let aDiv = document.createElement('div') + aDiv.innerHTML = this.render() + this.appendChild(aDiv.firstElementChild) + } + + // Subclasses want to rewrite this + render() { + return "" + } +} \ No newline at end of file diff --git a/js/UGraphPin.js b/js/UGraphPin.js new file mode 100644 index 0000000..a4f4336 --- /dev/null +++ b/js/UGraphPin.js @@ -0,0 +1,70 @@ +import FGuid from "./FGuid"; + +export default class UGraphPin { + constructor(Options) { + this.PinId = new FGuid(Options?.PinId) + this.PinName = Options?.PinName ?? "" + this.PinToolTip = Options?.PinToolTip ?? "" + this.PinType = { + PinCategory: Options?.PinType?.PinCategory ?? "object", + PinSubCategory: Options?.PinType?.PinSubCategory ?? "", + PinSubCategoryMemberReference: Options?.PinType?.PinSubCategoryMemberReference ?? "", + PinValueType: Options?.PinType?.PinValueType ?? "", + PinValueType: Options?.PinType?.ContainerType ?? "None", + bIsReference: Options?.PinType?.bIsReference ?? false, + bIsConst: Options?.PinType?.bIsConst ?? false, + bIsWeakPointer: Options?.PinType?.bIsWeakPointer ?? false, + bIsUObjectWrapper: Options?.PinType?.bIsUObjectWrapper ?? false + } + this.LinkedTo = Options?.LinkedTo ?? null + this.DefaultValue = Options?.DefaultValue ?? true + this.AutogeneratedDefaultValue = Options?.AutogeneratedDefaultValue ?? false + this.PersistentGuid = Options?.PersistentGuid ?? null + this.bHidden = Options?.bHidden ?? false + this.bNotConnectable = Options?.bNotConnectable ?? false + this.bDefaultValueIsReadOnly = Options?.bDefaultValueIsReadOnly ?? false + this.bDefaultValueIsIgnored = Options?.bDefaultValueIsIgnored ?? false + this.bAdvancedView = Options?.bAdvancedView ?? false + this.bOrphanedPin = Options?.bOrphanedPin ?? false + } + + static serializeValue(value) { + // No quotes + if (value === null) { + return '()' + } + if (value?.constructor?.name === 'Boolean') { + return value ? 'True' : 'False' + } + if (value?.constructor?.name === 'ETypesNames' || value?.constructor?.name === 'FGuid') { + return value.toString() + } + // Quotes + if (value?.constructor?.name === 'String') { + return `"${value}"` + } + } + + static subSerialize(prefix, object) { + let result = "" + prefix += prefix != "" ? "." : "" + for (const property in object) { + if (object[property]?.constructor?.name === 'Object') { + result += UGraphPin.subSerialize(prefix + property, object[property]) + } else { + result += `${prefix + property}=${UGraphPin.serializeValue(object[property])},` + } + } + return result + } + + serialize() { + let result = `CustomProperties Pin (${this.constructor.subSerialize('', this)})` + return result + } + + toString() { + return this.serialize() + } + +} \ No newline at end of file diff --git a/js/ULink.js b/js/ULink.js new file mode 100644 index 0000000..e0e4acb --- /dev/null +++ b/js/ULink.js @@ -0,0 +1,29 @@ +import UBlueprintEntity from "./UBlueprintEntity" + +export default class ULink extends UBlueprintEntity { + + /** + * + * @typedef {{ + * node: String, + * pin: String + * }} PinReference + * @param {?PinReference} source + * @param {?PinReference} destination + */ + constructor(source, destination) { + super() + this.source = source + this.destination = destination + } + + render() { + return ` + +` + } +} + +customElements.define('u-link', ULink) diff --git a/js/USelectableDraggable.js b/js/USelectableDraggable.js index 43c0fcf..d1630c6 100644 --- a/js/USelectableDraggable.js +++ b/js/USelectableDraggable.js @@ -1,11 +1,10 @@ import UDrag from "./input/UDrag" +import UGraphEntity from "./UGraphEntity" -export default class USelectableDraggable extends HTMLElement { +export default class USelectableDraggable extends UGraphEntity { constructor() { super() - /** @type {import("./UEBlueprint").default}" */ - this.blueprint = null this.dragObject = null this.location = [0, 0] this.selected = false @@ -17,7 +16,7 @@ export default class USelectableDraggable extends HTMLElement { } connectedCallback() { - this.blueprint = this.closest('u-blueprint') + super.connectedCallback() this.dragObject = new UDrag(this, null, { // UDrag doesn't need blueprint looseTarget: true }) diff --git a/js/exporting.js b/js/exporting.js index 0fd202d..a8d8c07 100644 --- a/js/exporting.js +++ b/js/exporting.js @@ -1,4 +1,5 @@ import UEBlueprint from "./UEBlueprint" import UEBlueprintObject from "./UEBlueprintObject" +import UGraphPin from "./UGraphPin" -export { UEBlueprint, UEBlueprintObject } \ No newline at end of file +export { UEBlueprint, UEBlueprintObject, UGraphPin } \ No newline at end of file diff --git a/ueblueprint.html b/ueblueprint.html index eaaa57c..dd61d65 100644 --- a/ueblueprint.html +++ b/ueblueprint.html @@ -14,13 +14,15 @@