mirror of
https://github.com/barsdeveloper/ueblueprint.git
synced 2026-02-15 09:44:49 +08:00
New templates, node advanced display, style fixes
This commit is contained in:
2
dist/css/ueb-style.css
vendored
2
dist/css/ueb-style.css
vendored
File diff suppressed because one or more lines are too long
2
dist/css/ueb-style.css.map
vendored
2
dist/css/ueb-style.css.map
vendored
@@ -1 +1 @@
|
||||
{"version":3,"sourceRoot":"","sources":["../../scss/style.scss","../../scss/ueb-node.scss","../../scss/ueb-pin.scss","../../scss/ueb-link.scss","../../scss/ueb-type-color.scss"],"names":[],"mappings":"AAAA,WACI,qBACA,iBACA,IACI,kGAIR,WACI,qBACA,mBACA,IACI,sGAIR,cACI,cACA,kBACA,8EACA,+BACA,iBAGJ,qBACI,aACA,kBACA,MACA,QACA,OACA,aACA,0BACA,UAGJ,mBACI,iBACA,gBACA,eAGJ,mBACI,kBACA,gCACA,gBACA,kBAGJ,oDACI,gBAGJ,UACI,kFACA,kBACA,eACA,gBACA,kEACA,mEACA,yBACA,iBAEI,s3BA0BJ,gBAEI,sZAQJ,sFACA,gEACA,oDACA,qBACA,gBAGJ,kDACI,gBAGJ,mDACI,eAGJ,qBAEI,eACA,6CAGJ,gBACI,eAGJ,gBACI,mBAGJ,gBACI,kBAGJ,gBACI,mBAGJ,gBACI,iBAGJ,gBACI,mBAGJ,gBACI,kBAGJ,iBACI,mBAGJ,iBACI,kBAGJ,iBACI,mBAGJ,iBACI,iBACA,uDAGJ,iBACI,mBACA,uDAGJ,iBACI,sBACA,uDAGJ,iBACI,iBACA,uDAGJ,iBACI,sBACA,uDAGJ,iBACI,sBACA,uDAGJ,kBACI,iBACA,uDAGJ,kBACI,sBACA,uDAGJ,kBACI,sBACA,uDAGJ,kBACI,kBACA,QACA,SACA,wGAGJ,sBACI,QACA,SAGJ,gEACI,8DACA,8DACA,8DACA,8DACA,oGACA,qGACA,kBACA,wCACA,yCACA,0CACA,4CAGJ,aACI,cACA,kBACA,kBACA,MACA,OACA,QACA,SACA,iBAEI,wlDAmDJ,gBAEI,gQAWJ,oBAEI,wJAOJ,4BAGJ,gDACI,mBAIJ,eACI,mBClUJ,SACI,cACA,kBACA,sGACA,qCACA,uDACA,oBAGJ,wEACI,YAGJ,iBACI,YACA,YACA,+CAGJ,+BACI,iBACI,kNAIJ,oDACA,0CACA,sDACA,0BACA,oBAGJ,kBACI,kBACA,YACA,gCACA,qCACA,6BACA,gBAGJ,iBACI,kBACA,0FAGA,gEACA,8EACA,aACA,gBACA,mBAGJ,eACI,mGACA,qBACA,mBAGJ,eACI,aACA,cACA,WACA,gBACA,mBAGJ,iBACI,kBACA,iBAGJ,kBACI,iBACA,kBAGJ,iBACI,aAGJ,iDACI,cClFJ,QACI,cACA,aACA,gBAEA,UACI,qBACA,sBAIR,wEACI,aAGJ,6EACI,qCACA,iBAGJ,0BACI,iBAGJ,mBACI,qBACA,wBAGJ,oBACI,qBACA,kBACA,sBACA,uBACA,wBACA,wBAGJ,4BACI,WACA,cACA,kBACA,MACA,QACA,SACA,OACA,sCACA,kBAGJ,iDACI,gCAGJ,2BACI,WACA,cACA,kBACA,qBACA,sBACA,QACA,SACA,kCACA,qCACA,4CAGJ,cACI,qBACA,sBAGJ,4BACI,aAGJ,eACI,qBACA,sBACA,gBACA,yBACA,kBACA,oBACA,aAEA,4FAII,qBACA,aAIR,uBACI,cACA,aACA,YACA,UACA,eACA,gBACA,gBACA,gBACA,cACA,YACA,cAEA,0CACI,WACA,YAGJ,gDACI,mBACA,mBACA,WCnHR,SACI,kEAEA,uEACA,cACA,8CAKA,kBAGJ,aACI,iEACA,kBACA,MACA,OACA,WACA,YACA,eACA,8FACA,iBAGJ,kBACI,mBACA,4BACA,eAGJ,8DAEI,eACA,4BAGJ,iBACI,cACA,mBACA,kBACA,kDACA,qHAOA,sBACA,gBACA,kBACA,4EACA,+BACA,mBACA,gBCvDJ,KAGI,uBACA,6BAGJ,iBAEI,yBAGJ,eAEI,yBAGJ,eAEI,yBAGJ,aAEI,yBAGJ,cAEI,yBAGJ,gBAGI,yBAGJ,iBAEI,yBAGJ,gBAEI,yBACA,mGAGJ,gBAEI","file":"ueb-style.css"}
|
||||
{"version":3,"sourceRoot":"","sources":["../../scss/style.scss","../../scss/ueb-node.scss","../../scss/ueb-pin.scss","../../scss/ueb-link.scss","../../scss/ueb-type-color.scss"],"names":[],"mappings":"AAAA,WACI,qBACA,iBACA,IACI,kGAIR,WACI,qBACA,mBACA,IACI,sGAIR,cACI,cACA,kBACA,8EACA,+BACA,WACA,iBAGJ,qBACI,aACA,kBACA,MACA,QACA,OACA,aACA,0BACA,UAGJ,mBACI,iBACA,gBACA,eAGJ,mBACI,kBACA,gCACA,gBACA,kBAGJ,oDACI,gBAGJ,UACI,kFACA,kBACA,eACA,gBACA,kEACA,mEACA,yBACA,iBAEI,s3BA0BJ,gBAEI,sZAQJ,sFACA,gEACA,oDACA,qBACA,gBAGJ,kDACI,gBAGJ,mDACI,eAGJ,qBAEI,eACA,6CAGJ,gBACI,eAGJ,gBACI,mBAGJ,gBACI,kBAGJ,gBACI,mBAGJ,gBACI,iBAGJ,gBACI,mBAGJ,gBACI,kBAGJ,iBACI,mBAGJ,iBACI,kBAGJ,iBACI,mBAGJ,iBACI,iBACA,uDAGJ,iBACI,mBACA,uDAGJ,iBACI,sBACA,uDAGJ,iBACI,iBACA,uDAGJ,iBACI,sBACA,uDAGJ,iBACI,sBACA,uDAGJ,kBACI,iBACA,uDAGJ,kBACI,sBACA,uDAGJ,kBACI,sBACA,uDAGJ,kBACI,kBACA,QACA,SACA,wGAGJ,sBACI,QACA,SAGJ,gEACI,8DACA,8DACA,8DACA,8DACA,oGACA,qGACA,kBACA,wCACA,yCACA,0CACA,4CAGJ,aACI,cACA,kBACA,kBACA,MACA,OACA,QACA,SACA,iBAEI,wlDAmDJ,gBAEI,gQAWJ,oBAEI,wJAOJ,4BAGJ,gDACI,mBAIJ,eACI,mBCnUJ,SACI,cACA,kBACA,sGACA,qCACA,uDACA,oBAGJ,wEACI,YAGJ,iBACI,YACA,YACA,+CAGJ,+BACI,iBACI,kNAIJ,oDACA,0CACA,sDACA,0BACA,oBAGJ,kBACI,kBACA,YACA,gCACA,qCACA,6BACA,gBAGJ,iBACI,kBACA,0FAGA,gEACA,8EACA,aACA,gBACA,mBAGJ,eACI,mGACA,qBACA,mBAGJ,eACI,aACA,cACA,gBACA,mBAGJ,iBACI,kBACA,iBAGJ,kBACI,iBACA,kBAGJ,oBACI,aACA,kBAGJ,0BACI,yBACA,eAGJ,oDACI,cCvFJ,QACI,cACA,aACA,gBAEA,UACI,qBACA,sBAIR,wEACI,aAGJ,6EACI,qCACA,iBAGJ,0BACI,iBAGJ,mBACI,qBACA,wBAGJ,oBACI,qBACA,kBACA,WACA,YACA,wBACA,wBAGJ,4BACI,WACA,cACA,kBACA,MACA,QACA,SACA,OACA,sCACA,kBAGJ,iDACI,gCAGJ,2BACI,WACA,cACA,kBACA,QACA,UACA,QACA,SACA,kCACA,qCACA,4CAGJ,cACI,qBACA,sBAGJ,4BACI,aAGJ,eACI,qBACA,sBACA,gBACA,yBACA,kBACA,oBACA,aAEA,4FAII,qBACA,aAIR,uBACI,cACA,aACA,YACA,UACA,eACA,gBACA,gBACA,gBACA,cACA,YACA,cAEA,0CACI,WACA,YAGJ,gDACI,mBACA,mBACA,WCnHR,SACI,kEAEA,uEACA,cACA,8CAKA,kBAGJ,aACI,iEACA,kBACA,MACA,OACA,WACA,YACA,eACA,8FACA,iBAGJ,kBACI,mBACA,4BACA,eAGJ,8DAEI,eACA,4BAGJ,iBACI,cACA,mBACA,kBACA,kDACA,qHAOA,sBACA,gBACA,kBACA,4EACA,+BACA,mBACA,gBCvDJ,KAGI,uBACA,6BAGJ,iBAEI,yBAGJ,eAEI,yBAGJ,eAEI,yBAGJ,aAEI,yBAGJ,cAEI,yBAGJ,gBAGI,yBAGJ,iBAEI,yBAGJ,gBAEI,yBACA,mGAGJ,gBAEI","file":"ueb-style.css"}
|
||||
214
dist/ueblueprint.js
vendored
214
dist/ueblueprint.js
vendored
@@ -431,13 +431,22 @@ class Utility {
|
||||
/**
|
||||
* @param {String} value
|
||||
*/
|
||||
static sanitizeInputString(value) {
|
||||
static sanitizeString(value, input = false) {
|
||||
return value
|
||||
.replace(/\n$/, "") // Remove trailing newline
|
||||
.replaceAll("\u00A0", " ") // Replace special space symbol
|
||||
.replaceAll("\n", String.raw`\r\n`) // Replace newline with \r\n
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {String} value
|
||||
*/
|
||||
static renderInputString(value) {
|
||||
return value
|
||||
.replaceAll(" ", "\u00A0") // Replace special space symbol
|
||||
.replaceAll(String.raw`\r\n`, "<br />\n") // Replace newline with \r\n
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {String} value
|
||||
*/
|
||||
@@ -795,6 +804,10 @@ class PinEntity extends IEntity {
|
||||
/** @type {Boolean} */ this.bOrphanedPin;
|
||||
}
|
||||
|
||||
getDefaultValue() {
|
||||
return this.DefaultValue ?? ""
|
||||
}
|
||||
|
||||
isInput() {
|
||||
return !this.bHidden && this.Direction != "EGPD_Output"
|
||||
}
|
||||
@@ -1419,7 +1432,11 @@ const html = String.raw;
|
||||
class ITemplate {
|
||||
|
||||
/** @type {IInput[]} */
|
||||
inputObjects = []
|
||||
#inputObjects = []
|
||||
|
||||
get inputObjects() {
|
||||
return this.#inputObjects
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {T} entity
|
||||
@@ -1440,14 +1457,14 @@ class ITemplate {
|
||||
* @param {T} element
|
||||
*/
|
||||
inputSetup(element) {
|
||||
this.inputObjects = this.createInputObjects(element);
|
||||
this.#inputObjects = this.createInputObjects(element);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {T} element
|
||||
*/
|
||||
cleanup(element) {
|
||||
this.inputObjects.forEach(v => v.unlistenDOMElement());
|
||||
this.#inputObjects.forEach(v => v.unlistenDOMElement());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2776,6 +2793,8 @@ class MouseCreateLink extends IMouseClickDrag {
|
||||
|
||||
class PinTemplate extends ITemplate {
|
||||
|
||||
hasInput = false
|
||||
|
||||
/**
|
||||
* @param {PinElement} pin
|
||||
* @returns {IInput[]}
|
||||
@@ -2789,10 +2808,6 @@ class PinTemplate extends ITemplate {
|
||||
]
|
||||
}
|
||||
|
||||
hasInput() {
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {PinElement} pin
|
||||
*/
|
||||
@@ -2882,7 +2897,31 @@ class ExecPinTemplate extends PinTemplate {
|
||||
renderIcon(pin) {
|
||||
return html`
|
||||
<svg class="ueb-pin-icon-exec" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path d="M2 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h7.08a2 2 0 0 0 1.519-.698l4.843-5.651a1 1 0 0 0 0-1.302L10.6 1.7A2 2 0 0 0 9.08 1H2zm7.08 1a1 1 0 0 1 .76.35L14.682 8l-4.844 5.65a1 1 0 0 1-.759.35H2a1 1 0 0 1-1-1V3a1 1 0 0 1 1-1h7.08z"/>
|
||||
<path d="
|
||||
M 2 1
|
||||
a 2 2 0 0 0 -2 2
|
||||
v 10
|
||||
a 2 2 0 0 0 2 2
|
||||
h 7.08
|
||||
a 2 2 0 0 0 1.519 -.698
|
||||
l 4.843 -5.651
|
||||
a 1 1 0 0 0 0 -1.302
|
||||
L 10.6 1.7
|
||||
A 2 2 0 0 0 9.08 1
|
||||
H 2
|
||||
z
|
||||
m 7.08 1
|
||||
a 1 1 0 0 1 .76 .35
|
||||
L 14.682 8
|
||||
l -4.844 5.65
|
||||
a 1 1 0 0 1 -.759 .35
|
||||
H 2
|
||||
a 1 1 0 0 1 -1 -1
|
||||
V 3
|
||||
a 1 1 0 0 1 1 -1
|
||||
h 7.08
|
||||
z
|
||||
" />
|
||||
</svg>
|
||||
`
|
||||
}
|
||||
@@ -2909,37 +2948,11 @@ class MouseIgnore extends IMouseClickDrag {
|
||||
* @typedef {import("../element/PinElement").default} PinElement
|
||||
*/
|
||||
|
||||
class StringPinTemplate extends PinTemplate {
|
||||
class IInputPinTemplate extends PinTemplate {
|
||||
|
||||
/** @type {HTMLElement} */
|
||||
input = null
|
||||
|
||||
hasInput() {
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {PinElement} pin
|
||||
*/
|
||||
getInput(pin) {
|
||||
return Utility.sanitizeInputString(
|
||||
/** @type {HTMLElement} */(pin.querySelector(".ueb-pin-input-content")).innerText
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {PinElement} pin
|
||||
*/
|
||||
renderInput(pin) {
|
||||
if (pin.isInput()) {
|
||||
return html`
|
||||
<div class="ueb-pin-input">
|
||||
<div class="ueb-pin-input-content" role="textbox" contenteditable="true"></div>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
return ""
|
||||
}
|
||||
hasInput = true
|
||||
|
||||
/**
|
||||
* @param {PinElement} pin
|
||||
@@ -2947,13 +2960,14 @@ class StringPinTemplate extends PinTemplate {
|
||||
setup(pin) {
|
||||
super.setup(pin);
|
||||
if (this.input = pin.querySelector(".ueb-pin-input-content")) {
|
||||
let self = this;
|
||||
this.onFocusHandler = (e) => {
|
||||
pin.blueprint.dispatchEditTextEvent(true);
|
||||
};
|
||||
this.onFocusOutHandler = (e) => {
|
||||
e.preventDefault();
|
||||
document.getSelection().removeAllRanges(); // Deselect text inside the input
|
||||
pin.entity.DefaultValue = this.getInput(pin);
|
||||
self.acceptInput(pin);
|
||||
pin.blueprint.dispatchEditTextEvent(false);
|
||||
};
|
||||
this.input.addEventListener("focus", this.onFocusHandler);
|
||||
@@ -2984,6 +2998,64 @@ class StringPinTemplate extends PinTemplate {
|
||||
}
|
||||
return super.createInputObjects(pin)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {PinElement} pin
|
||||
*/
|
||||
getInput(pin) {
|
||||
return Utility.sanitizeString(
|
||||
/** @type {HTMLElement} */(pin.querySelector(".ueb-pin-input-content")).innerText
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {PinElement} pin
|
||||
*/
|
||||
acceptInput(pin) {
|
||||
pin.entity.DefaultValue = this.getInput(pin);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {PinElement} pin
|
||||
*/
|
||||
renderInput(pin) {
|
||||
if (pin.isInput()) {
|
||||
return html`
|
||||
<div class="ueb-pin-input">
|
||||
<div class="ueb-pin-input-content" role="textbox" contenteditable="true">
|
||||
${Utility.renderInputString(sanitizeText(pin.entity.getDefaultValue()))}
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
// @ts-check
|
||||
|
||||
/**
|
||||
* @typedef {import("../element/PinElement").default} PinElement
|
||||
*/
|
||||
|
||||
class StringPinTemplate extends IInputPinTemplate {
|
||||
|
||||
/**
|
||||
* @param {PinElement} pin
|
||||
*/
|
||||
setup(pin) {
|
||||
super.setup(pin);
|
||||
}
|
||||
}
|
||||
|
||||
// @ts-check
|
||||
|
||||
/**
|
||||
* @typedef {import("../element/PinElement").default} PinElement
|
||||
*/
|
||||
|
||||
class RealPinTemplate extends PinTemplate {
|
||||
|
||||
}
|
||||
|
||||
// @ts-check
|
||||
@@ -3002,6 +3074,7 @@ class PinElement extends IElement {
|
||||
|
||||
static #typeTemplateMap = {
|
||||
"exec": ExecPinTemplate,
|
||||
"real": RealPinTemplate,
|
||||
"string": StringPinTemplate,
|
||||
}
|
||||
|
||||
@@ -3015,6 +3088,9 @@ class PinElement extends IElement {
|
||||
|
||||
connections = 0
|
||||
|
||||
/**
|
||||
* @param {PinEntity} entity
|
||||
*/
|
||||
constructor(entity) {
|
||||
super(
|
||||
entity,
|
||||
@@ -3048,7 +3124,7 @@ class PinElement extends IElement {
|
||||
* @returns {String}
|
||||
*/
|
||||
getPinDisplayName() {
|
||||
return this.entity.PinName
|
||||
return Utility.formatStringName(this.entity.PinName)
|
||||
}
|
||||
|
||||
isInput() {
|
||||
@@ -3249,6 +3325,8 @@ class SelectableDraggableTemplate extends ITemplate {
|
||||
|
||||
class NodeTemplate extends SelectableDraggableTemplate {
|
||||
|
||||
toggleAdvancedDisplayHandler
|
||||
|
||||
/**
|
||||
* Computes the html content of the target element.
|
||||
* @param {NodeElement} node Graph node element
|
||||
@@ -3270,17 +3348,36 @@ class NodeTemplate extends SelectableDraggableTemplate {
|
||||
<div class="ueb-node-inputs"></div>
|
||||
<div class="ueb-node-outputs"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ueb-node-expand">
|
||||
<span class="ueb-node-expand-icon"></span>
|
||||
${node.entity.AdvancedPinDisplay ? html`
|
||||
<div class="ueb-node-expansion">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
height="16"
|
||||
fill="currentColor"
|
||||
class="ueb-node-expansion-icon"
|
||||
viewBox="4 2 24 24"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="
|
||||
M 16.003 18.626
|
||||
l 7.081 -7.081
|
||||
L 25 13.46
|
||||
l -8.997 8.998 -9.003 -9 1.917 -1.916
|
||||
z
|
||||
"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
` : ""}
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the style to the element.
|
||||
* @param {NodeElement} node Element of the graph
|
||||
* @param {NodeElement} node
|
||||
*/
|
||||
setup(node) {
|
||||
super.setup(node);
|
||||
@@ -3289,9 +3386,7 @@ class NodeTemplate extends SelectableDraggableTemplate {
|
||||
if (node.selected) {
|
||||
node.classList.add("ueb-selected");
|
||||
}
|
||||
if (node.entity.AdvancedPinDisplay) {
|
||||
node.dataset.advancedDisplay = node.entity.AdvancedPinDisplay.toString();
|
||||
}
|
||||
this.applyAdvancedPinDisplay(node);
|
||||
node.style.setProperty("--ueb-position-x", sanitizeText(node.location[0]));
|
||||
node.style.setProperty("--ueb-position-y", sanitizeText(node.location[1]));
|
||||
/** @type {HTMLElement} */
|
||||
@@ -3301,11 +3396,23 @@ class NodeTemplate extends SelectableDraggableTemplate {
|
||||
let pins = node.getPinEntities();
|
||||
pins.filter(v => v.isInput()).forEach(v => inputContainer.appendChild(new PinElement(v)));
|
||||
pins.filter(v => v.isOutput()).forEach(v => outputContainer.appendChild(new PinElement(v)));
|
||||
this.toggleAdvancedDisplayHandler = _ => {
|
||||
node.toggleShowAdvancedPinDisplay();
|
||||
};
|
||||
node.querySelector(".ueb-node-expansion").addEventListener("click", this.toggleAdvancedDisplayHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the style to the element.
|
||||
* @param {NodeElement} node Element of the graph
|
||||
* @param {NodeElement} node
|
||||
*/
|
||||
applyAdvancedPinDisplay(node) {
|
||||
if (node.entity.AdvancedPinDisplay) {
|
||||
node.dataset.advancedDisplay = node.entity.AdvancedPinDisplay.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {NodeElement} node
|
||||
*/
|
||||
applyRename(node) {
|
||||
const nodeName = node.entity.getFullName();
|
||||
@@ -3412,6 +3519,15 @@ class NodeElement extends ISelectableDraggableElement {
|
||||
});
|
||||
this.dispatchEvent(deleteEvent);
|
||||
}
|
||||
|
||||
setShowAdvancedPinDisplay(value) {
|
||||
this.entity.AdvancedPinDisplay = new IdentifierEntity(value ? "Shown" : "Hidden");
|
||||
this.template.applyAdvancedPinDisplay(this);
|
||||
}
|
||||
|
||||
toggleShowAdvancedPinDisplay() {
|
||||
this.setShowAdvancedPinDisplay(this.entity.AdvancedPinDisplay.value != "Shown");
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("ueb-node", NodeElement);
|
||||
|
||||
29
index.html
29
index.html
@@ -20,17 +20,24 @@
|
||||
<script type="module">
|
||||
import { Blueprint, NodeElement, Configuration } from "./dist/ueblueprint.js"
|
||||
Configuration.deleteNodesKeyboardKey = "Delete"
|
||||
let node1 = NodeElement.fromSerializedObject(`Begin Object Class=/Script/BlueprintGraph.K2Node_CommutativeAssociativeBinaryOperator Name="K2Node_CommutativeAssociativeBinaryOperator_1"
|
||||
bIsPureFunc=True
|
||||
FunctionReference=(MemberParent=Class'"/Script/Engine.KismetStringLibrary"',MemberName="Concat_StrStr")
|
||||
NodePosX=30
|
||||
NodePosY=50
|
||||
NodeGuid=43D899AC42EB640EF98BFCA1597FD6C9
|
||||
CustomProperties Pin (PinId=FB3490034B2B6127D29E1397E04F6BD6,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target Kismet String Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.KismetStringLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=True,DefaultObject="/Script/Engine.Default__KismetStringLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
|
||||
CustomProperties Pin (PinId=22257AFF4730E84DE3EF0DBA7A92E1EE,PinName="A",PinToolTip="A String The original string",PinType.PinCategory="string",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,LinkedTo=(K2Node_CallFunction_1 DB96A96142631A1B113BC69C8B77B9BD,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
|
||||
CustomProperties Pin (PinId=81E183294B6CBC122C5E88A8C37F13A3,PinName="B",PinToolTip="B String The string to append to A",PinType.PinCategory="string",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,LinkedTo=(K2Node_CallFunction_1 DB96A96142631A1B113BC69C8B77B9BD,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
|
||||
CustomProperties Pin (PinId=E9BBB3A54DE64C213F52B2AFC8197637,PinName="ReturnValue",PinToolTip="Return Value String A new string which is the concatenation of A+B",Direction="EGPD_Output",PinType.PinCategory="string",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
|
||||
End Object`)
|
||||
let node1 = NodeElement.fromSerializedObject(`Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_1"
|
||||
FunctionReference=(MemberParent=Class'"/Script/Engine.KismetSystemLibrary"',MemberName="PrintString")
|
||||
NodePosX=-32
|
||||
NodePosY=16
|
||||
AdvancedPinDisplay=Hidden
|
||||
EnabledState=DevelopmentOnly
|
||||
NodeGuid=98549611450D8A376DABBEBE0E9C9DA0
|
||||
CustomProperties Pin (PinId=02E98A344D671590D0DF1C8CB0CB2F11,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
|
||||
CustomProperties Pin (PinId=AA195A404C96984C092A66956D71E609,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
|
||||
CustomProperties Pin (PinId=3A8D79AC401EEBE2DE14FD82ED99B29F,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet System Library Object Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/Engine.KismetSystemLibrary"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,DefaultObject="/Script/Engine.Default__KismetSystemLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
|
||||
CustomProperties Pin (PinId=9FBD56F74479A7DC40151ABBA295D5F4,PinName="WorldContextObject",PinToolTip="World Context Object\nObject Reference",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=Class'"/Script/CoreUObject.Object"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
|
||||
CustomProperties Pin (PinId=6A691A014ECBED618805B2B54AA10271,PinName="InString",PinToolTip="In String\nString\n\nThe string to log out",PinType.PinCategory="string",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,DefaultValue="\r\n\r\nHell\r\n\r\no2 ",AutogeneratedDefaultValue="Hello",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
|
||||
CustomProperties Pin (PinId=32E95A54483C6A233CAAD39D87023B85,PinName="bPrintToScreen",PinToolTip="Print to Screen\nBoolean\n\nWhether or not to print the output to the screen",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,DefaultValue="true",AutogeneratedDefaultValue="true",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
|
||||
CustomProperties Pin (PinId=1080D06D4FE1274BFA2701B146CC8E52,PinName="bPrintToLog",PinToolTip="Print to Log\nBoolean\n\nWhether or not to print the output to the log",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,DefaultValue="true",AutogeneratedDefaultValue="true",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
|
||||
CustomProperties Pin (PinId=54F79BED4EB60BD71B98D68C47C95300,PinName="TextColor",PinToolTip="Text Color\nLinear Color Structure\n\nThe color of the text to display",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=ScriptStruct'"/Script/CoreUObject.LinearColor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,DefaultValue="(R=0.000000,G=0.660000,B=1.000000,A=1.000000)",AutogeneratedDefaultValue="(R=0.000000,G=0.660000,B=1.000000,A=1.000000)",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
|
||||
CustomProperties Pin (PinId=DD99696C4E607FC8393114A9C641BC17,PinName="Duration",PinToolTip="Duration\nFloat (single-precision)\n\nThe display duration (if Print to Screen is True). Using negative number will result in loading the duration time from the config.",PinType.PinCategory="real",PinType.PinSubCategory="float",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,DefaultValue="2.000000",AutogeneratedDefaultValue="2.000000",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
|
||||
CustomProperties Pin (PinId=F62FC7574699383B1F74E0A4338B770E,PinName="Key",PinToolTip="Key\nName\n\nIf a non-empty key is provided, the message will replace any existing on-screen messages with the same key.",PinType.PinCategory="name",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,DefaultValue="None",AutogeneratedDefaultValue="None",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
|
||||
End Object`)
|
||||
let blueprint = new Blueprint()
|
||||
document.querySelector('body').appendChild(blueprint)
|
||||
blueprint.addGraphElement(node1)
|
||||
|
||||
@@ -149,13 +149,22 @@ export default class Utility {
|
||||
/**
|
||||
* @param {String} value
|
||||
*/
|
||||
static sanitizeInputString(value) {
|
||||
static sanitizeString(value, input = false) {
|
||||
return value
|
||||
.replace(/\n$/, "") // Remove trailing newline
|
||||
.replaceAll("\u00A0", " ") // Replace special space symbol
|
||||
.replaceAll("\n", String.raw`\r\n`) // Replace newline with \r\n
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {String} value
|
||||
*/
|
||||
static renderInputString(value) {
|
||||
return value
|
||||
.replaceAll(" ", "\u00A0") // Replace special space symbol
|
||||
.replaceAll(String.raw`\r\n`, "<br />\n") // Replace newline with \r\n
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {String} value
|
||||
*/
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
// @ts-check
|
||||
|
||||
import Configuration from "../Configuration"
|
||||
import IdentifierEntity from "../entity/IdentifierEntity"
|
||||
import ISelectableDraggableElement from "./ISelectableDraggableElement"
|
||||
import NodeTemplate from "../template/NodeTemplate"
|
||||
import ObjectEntity from "../entity/ObjectEntity"
|
||||
import PinEntity from "../entity/PinEntity"
|
||||
import SerializerFactory from "../serialization/SerializerFactory"
|
||||
import PinReferenceEntity from "../entity/PinReferenceEntity"
|
||||
import SerializerFactory from "../serialization/SerializerFactory"
|
||||
|
||||
/**
|
||||
* @extends {ISelectableDraggableElement<ObjectEntity, NodeTemplate>}
|
||||
@@ -95,6 +96,15 @@ export default class NodeElement extends ISelectableDraggableElement {
|
||||
})
|
||||
this.dispatchEvent(deleteEvent)
|
||||
}
|
||||
|
||||
setShowAdvancedPinDisplay(value) {
|
||||
this.entity.AdvancedPinDisplay = new IdentifierEntity(value ? "Shown" : "Hidden")
|
||||
this.template.applyAdvancedPinDisplay(this)
|
||||
}
|
||||
|
||||
toggleShowAdvancedPinDisplay() {
|
||||
this.setShowAdvancedPinDisplay(this.entity.AdvancedPinDisplay.value != "Shown")
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("ueb-node", NodeElement)
|
||||
|
||||
@@ -4,7 +4,9 @@ import ExecPinTemplate from "../template/ExecPinTemplate"
|
||||
import IElement from "./IElement"
|
||||
import LinkElement from "./LinkElement"
|
||||
import PinTemplate from "../template/PinTemplate"
|
||||
import RealPinTemplate from "../template/RealPinTemplate"
|
||||
import StringPinTemplate from "../template/StringPinTemplate"
|
||||
import Utility from "../Utility"
|
||||
|
||||
/**
|
||||
* @typedef {import("../entity/GuidEntity").default} GuidEntity
|
||||
@@ -20,6 +22,7 @@ export default class PinElement extends IElement {
|
||||
|
||||
static #typeTemplateMap = {
|
||||
"exec": ExecPinTemplate,
|
||||
"real": RealPinTemplate,
|
||||
"string": StringPinTemplate,
|
||||
}
|
||||
|
||||
@@ -33,6 +36,9 @@ export default class PinElement extends IElement {
|
||||
|
||||
connections = 0
|
||||
|
||||
/**
|
||||
* @param {PinEntity} entity
|
||||
*/
|
||||
constructor(entity) {
|
||||
super(
|
||||
entity,
|
||||
@@ -66,7 +72,7 @@ export default class PinElement extends IElement {
|
||||
* @returns {String}
|
||||
*/
|
||||
getPinDisplayName() {
|
||||
return this.entity.PinName
|
||||
return Utility.formatStringName(this.entity.PinName)
|
||||
}
|
||||
|
||||
isInput() {
|
||||
|
||||
@@ -75,6 +75,10 @@ export default class PinEntity extends IEntity {
|
||||
/** @type {Boolean} */ this.bOrphanedPin
|
||||
}
|
||||
|
||||
getDefaultValue() {
|
||||
return this.DefaultValue ?? ""
|
||||
}
|
||||
|
||||
isInput() {
|
||||
return !this.bHidden && this.Direction != "EGPD_Output"
|
||||
}
|
||||
|
||||
@@ -15,7 +15,31 @@ export default class ExecPinTemplate extends PinTemplate {
|
||||
renderIcon(pin) {
|
||||
return html`
|
||||
<svg class="ueb-pin-icon-exec" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
|
||||
<path d="M2 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h7.08a2 2 0 0 0 1.519-.698l4.843-5.651a1 1 0 0 0 0-1.302L10.6 1.7A2 2 0 0 0 9.08 1H2zm7.08 1a1 1 0 0 1 .76.35L14.682 8l-4.844 5.65a1 1 0 0 1-.759.35H2a1 1 0 0 1-1-1V3a1 1 0 0 1 1-1h7.08z"/>
|
||||
<path d="
|
||||
M 2 1
|
||||
a 2 2 0 0 0 -2 2
|
||||
v 10
|
||||
a 2 2 0 0 0 2 2
|
||||
h 7.08
|
||||
a 2 2 0 0 0 1.519 -.698
|
||||
l 4.843 -5.651
|
||||
a 1 1 0 0 0 0 -1.302
|
||||
L 10.6 1.7
|
||||
A 2 2 0 0 0 9.08 1
|
||||
H 2
|
||||
z
|
||||
m 7.08 1
|
||||
a 1 1 0 0 1 .76 .35
|
||||
L 14.682 8
|
||||
l -4.844 5.65
|
||||
a 1 1 0 0 1 -.759 .35
|
||||
H 2
|
||||
a 1 1 0 0 1 -1 -1
|
||||
V 3
|
||||
a 1 1 0 0 1 1 -1
|
||||
h 7.08
|
||||
z
|
||||
" />
|
||||
</svg>
|
||||
`
|
||||
}
|
||||
|
||||
95
js/template/IInputPinTemplate.js
Normal file
95
js/template/IInputPinTemplate.js
Normal file
@@ -0,0 +1,95 @@
|
||||
// @ts-check
|
||||
|
||||
import html from "./html"
|
||||
import MouseIgnore from "../input/mouse/MouseIgnore"
|
||||
import PinTemplate from "./PinTemplate"
|
||||
import sanitizeText from "./sanitizeText"
|
||||
import Utility from "../Utility"
|
||||
|
||||
/**
|
||||
* @typedef {import("../element/PinElement").default} PinElement
|
||||
*/
|
||||
|
||||
export default class IInputPinTemplate extends PinTemplate {
|
||||
|
||||
/** @type {HTMLElement} */
|
||||
input = null
|
||||
hasInput = true
|
||||
|
||||
/**
|
||||
* @param {PinElement} pin
|
||||
*/
|
||||
setup(pin) {
|
||||
super.setup(pin)
|
||||
if (this.input = pin.querySelector(".ueb-pin-input-content")) {
|
||||
let self = this
|
||||
this.onFocusHandler = (e) => {
|
||||
pin.blueprint.dispatchEditTextEvent(true)
|
||||
}
|
||||
this.onFocusOutHandler = (e) => {
|
||||
e.preventDefault()
|
||||
document.getSelection().removeAllRanges() // Deselect text inside the input
|
||||
self.acceptInput(pin)
|
||||
pin.blueprint.dispatchEditTextEvent(false)
|
||||
}
|
||||
this.input.addEventListener("focus", this.onFocusHandler)
|
||||
this.input.addEventListener("focusout", this.onFocusOutHandler)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {PinElement} pin
|
||||
*/
|
||||
cleanup(pin) {
|
||||
super.cleanup(pin)
|
||||
if (this.input) {
|
||||
this.input.removeEventListener("focus", this.onFocusHandler)
|
||||
this.input.removeEventListener("focusout", this.onFocusOutHandler)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {PinElement} pin
|
||||
*/
|
||||
createInputObjects(pin) {
|
||||
if (pin.isInput()) {
|
||||
return [
|
||||
...super.createInputObjects(pin),
|
||||
new MouseIgnore(pin.querySelector(".ueb-pin-input-content"), pin.blueprint),
|
||||
]
|
||||
}
|
||||
return super.createInputObjects(pin)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {PinElement} pin
|
||||
*/
|
||||
getInput(pin) {
|
||||
return Utility.sanitizeString(
|
||||
/** @type {HTMLElement} */(pin.querySelector(".ueb-pin-input-content")).innerText
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {PinElement} pin
|
||||
*/
|
||||
acceptInput(pin) {
|
||||
pin.entity.DefaultValue = this.getInput(pin)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {PinElement} pin
|
||||
*/
|
||||
renderInput(pin) {
|
||||
if (pin.isInput()) {
|
||||
return html`
|
||||
<div class="ueb-pin-input">
|
||||
<div class="ueb-pin-input-content" role="textbox" contenteditable="true">
|
||||
${Utility.renderInputString(sanitizeText(pin.entity.getDefaultValue()))}
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
return ""
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,11 @@
|
||||
export default class ITemplate {
|
||||
|
||||
/** @type {IInput[]} */
|
||||
inputObjects = []
|
||||
#inputObjects = []
|
||||
|
||||
get inputObjects() {
|
||||
return this.#inputObjects
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {T} entity
|
||||
@@ -32,14 +36,14 @@ export default class ITemplate {
|
||||
* @param {T} element
|
||||
*/
|
||||
inputSetup(element) {
|
||||
this.inputObjects = this.createInputObjects(element)
|
||||
this.#inputObjects = this.createInputObjects(element)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {T} element
|
||||
*/
|
||||
cleanup(element) {
|
||||
this.inputObjects.forEach(v => v.unlistenDOMElement())
|
||||
this.#inputObjects.forEach(v => v.unlistenDOMElement())
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,6 +11,8 @@ import SelectableDraggableTemplate from "./SelectableDraggableTemplate"
|
||||
|
||||
export default class NodeTemplate extends SelectableDraggableTemplate {
|
||||
|
||||
toggleAdvancedDisplayHandler
|
||||
|
||||
/**
|
||||
* Computes the html content of the target element.
|
||||
* @param {NodeElement} node Graph node element
|
||||
@@ -32,17 +34,36 @@ export default class NodeTemplate extends SelectableDraggableTemplate {
|
||||
<div class="ueb-node-inputs"></div>
|
||||
<div class="ueb-node-outputs"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ueb-node-expand">
|
||||
<span class="ueb-node-expand-icon"></span>
|
||||
${node.entity.AdvancedPinDisplay ? html`
|
||||
<div class="ueb-node-expansion">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
height="16"
|
||||
fill="currentColor"
|
||||
class="ueb-node-expansion-icon"
|
||||
viewBox="4 2 24 24"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="
|
||||
M 16.003 18.626
|
||||
l 7.081 -7.081
|
||||
L 25 13.46
|
||||
l -8.997 8.998 -9.003 -9 1.917 -1.916
|
||||
z
|
||||
"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
` : ""}
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the style to the element.
|
||||
* @param {NodeElement} node Element of the graph
|
||||
* @param {NodeElement} node
|
||||
*/
|
||||
setup(node) {
|
||||
super.setup(node)
|
||||
@@ -51,9 +72,7 @@ export default class NodeTemplate extends SelectableDraggableTemplate {
|
||||
if (node.selected) {
|
||||
node.classList.add("ueb-selected")
|
||||
}
|
||||
if (node.entity.AdvancedPinDisplay) {
|
||||
node.dataset.advancedDisplay = node.entity.AdvancedPinDisplay.toString()
|
||||
}
|
||||
this.applyAdvancedPinDisplay(node)
|
||||
node.style.setProperty("--ueb-position-x", sanitizeText(node.location[0]))
|
||||
node.style.setProperty("--ueb-position-y", sanitizeText(node.location[1]))
|
||||
/** @type {HTMLElement} */
|
||||
@@ -63,11 +82,24 @@ export default class NodeTemplate extends SelectableDraggableTemplate {
|
||||
let pins = node.getPinEntities()
|
||||
pins.filter(v => v.isInput()).forEach(v => inputContainer.appendChild(new PinElement(v)))
|
||||
pins.filter(v => v.isOutput()).forEach(v => outputContainer.appendChild(new PinElement(v)))
|
||||
let self = this
|
||||
this.toggleAdvancedDisplayHandler = _ => {
|
||||
node.toggleShowAdvancedPinDisplay()
|
||||
}
|
||||
node.querySelector(".ueb-node-expansion").addEventListener("click", this.toggleAdvancedDisplayHandler)
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the style to the element.
|
||||
* @param {NodeElement} node Element of the graph
|
||||
* @param {NodeElement} node
|
||||
*/
|
||||
applyAdvancedPinDisplay(node) {
|
||||
if (node.entity.AdvancedPinDisplay) {
|
||||
node.dataset.advancedDisplay = node.entity.AdvancedPinDisplay.toString()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {NodeElement} node
|
||||
*/
|
||||
applyRename(node) {
|
||||
const nodeName = node.entity.getFullName()
|
||||
|
||||
@@ -14,6 +14,8 @@ import Utility from "../Utility"
|
||||
|
||||
export default class PinTemplate extends ITemplate {
|
||||
|
||||
hasInput = false
|
||||
|
||||
/**
|
||||
* @param {PinElement} pin
|
||||
* @returns {IInput[]}
|
||||
@@ -27,10 +29,6 @@ export default class PinTemplate extends ITemplate {
|
||||
]
|
||||
}
|
||||
|
||||
hasInput() {
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {PinElement} pin
|
||||
*/
|
||||
|
||||
11
js/template/RealPinTemplate.js
Normal file
11
js/template/RealPinTemplate.js
Normal file
@@ -0,0 +1,11 @@
|
||||
// @ts-check
|
||||
|
||||
import PinTemplate from "./PinTemplate"
|
||||
|
||||
/**
|
||||
* @typedef {import("../element/PinElement").default} PinElement
|
||||
*/
|
||||
|
||||
export default class RealPinTemplate extends PinTemplate {
|
||||
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
// @ts-check
|
||||
|
||||
import MouseMoveNodes from "../input/mouse/MouseMoveNodes"
|
||||
import ITemplate from "./ITemplate"
|
||||
import MouseMoveNodes from "../input/mouse/MouseMoveNodes"
|
||||
import sanitizeText from "./sanitizeText"
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,87 +1,17 @@
|
||||
// @ts-check
|
||||
|
||||
import html from "./html"
|
||||
import MouseIgnore from "../input/mouse/MouseIgnore"
|
||||
import PinTemplate from "./PinTemplate"
|
||||
import Utility from "../Utility"
|
||||
import IInputPinTemplate from "./IInputPinTemplate"
|
||||
|
||||
/**
|
||||
* @typedef {import("../element/PinElement").default} PinElement
|
||||
*/
|
||||
|
||||
export default class StringPinTemplate extends PinTemplate {
|
||||
|
||||
/** @type {HTMLElement} */
|
||||
input = null
|
||||
|
||||
hasInput() {
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {PinElement} pin
|
||||
*/
|
||||
getInput(pin) {
|
||||
return Utility.sanitizeInputString(
|
||||
/** @type {HTMLElement} */(pin.querySelector(".ueb-pin-input-content")).innerText
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {PinElement} pin
|
||||
*/
|
||||
renderInput(pin) {
|
||||
if (pin.isInput()) {
|
||||
return html`
|
||||
<div class="ueb-pin-input">
|
||||
<div class="ueb-pin-input-content" role="textbox" contenteditable="true"></div>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
return ""
|
||||
}
|
||||
export default class StringPinTemplate extends IInputPinTemplate {
|
||||
|
||||
/**
|
||||
* @param {PinElement} pin
|
||||
*/
|
||||
setup(pin) {
|
||||
super.setup(pin)
|
||||
if (this.input = pin.querySelector(".ueb-pin-input-content")) {
|
||||
this.onFocusHandler = (e) => {
|
||||
pin.blueprint.dispatchEditTextEvent(true)
|
||||
}
|
||||
this.onFocusOutHandler = (e) => {
|
||||
e.preventDefault()
|
||||
document.getSelection().removeAllRanges() // Deselect text inside the input
|
||||
pin.entity.DefaultValue = this.getInput(pin)
|
||||
pin.blueprint.dispatchEditTextEvent(false)
|
||||
}
|
||||
this.input.addEventListener("focus", this.onFocusHandler)
|
||||
this.input.addEventListener("focusout", this.onFocusOutHandler)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {PinElement} pin
|
||||
*/
|
||||
cleanup(pin) {
|
||||
super.cleanup(pin)
|
||||
if (this.input) {
|
||||
this.input.removeEventListener("focus", this.onFocusHandler)
|
||||
this.input.removeEventListener("focusout", this.onFocusOutHandler)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {PinElement} pin
|
||||
*/
|
||||
createInputObjects(pin) {
|
||||
if (pin.isInput()) {
|
||||
return [
|
||||
...super.createInputObjects(pin),
|
||||
new MouseIgnore(pin.querySelector(".ueb-pin-input-content"), pin.blueprint),
|
||||
]
|
||||
}
|
||||
return super.createInputObjects(pin)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ ueb-blueprint {
|
||||
position: relative;
|
||||
font-family: Roboto, Noto, Oxygen, Ubuntu, "Open Sans", "Helvetica Neue", sans-serif;
|
||||
font-size: var(--ueb-font-size);
|
||||
color: #fff;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,6 @@ ueb-blueprint[data-drag-scrolling="false"][data-selecting="false"] ueb-node {
|
||||
.ueb-node-body {
|
||||
display: flex;
|
||||
padding: 1px 0;
|
||||
color: white;
|
||||
font-weight: 100;
|
||||
white-space: nowrap;
|
||||
}
|
||||
@@ -75,10 +74,16 @@ ueb-blueprint[data-drag-scrolling="false"][data-selecting="false"] ueb-node {
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
.ueb-node-expand {
|
||||
.ueb-node-expansion {
|
||||
display: none;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
ueb-node[data-advanced-display] .ueb-node-expand {
|
||||
.ueb-node-expansion:hover {
|
||||
background-color: #656765;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
ueb-node[data-advanced-display] .ueb-node-expansion {
|
||||
display: block;
|
||||
}
|
||||
@@ -30,8 +30,8 @@ ueb-blueprint[data-drag-scrolling="false"][data-selecting="false"] ueb-pin:hover
|
||||
.ueb-pin-icon-value {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: calc(1em - 1px);
|
||||
height: calc(1em - 1px);
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
vertical-align: baseline;
|
||||
margin: 0 0.5em -1px 0.1em;
|
||||
}
|
||||
@@ -56,8 +56,8 @@ ueb-pin.ueb-pin-fill .ueb-pin-icon-value::before {
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: calc(50% - 0.3em);
|
||||
left: calc(100% + 1px);
|
||||
top: 3px;
|
||||
left: 13px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-top: 0.3em solid transparent;
|
||||
|
||||
Reference in New Issue
Block a user