mirror of
https://github.com/barsdeveloper/ueblueprint.git
synced 2026-02-15 01:24:41 +08:00
Links wip (broken)
This commit is contained in:
2139
dist/ueblueprint.js
vendored
2139
dist/ueblueprint.js
vendored
File diff suppressed because it is too large
Load Diff
@@ -12,7 +12,6 @@
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div>Hello</div>
|
||||
<script type="module">
|
||||
import { Blueprint, NodeElement, Configuration } from "./dist/ueblueprint.js"
|
||||
Configuration.deleteNodesKeyboardKey = "Delete"
|
||||
|
||||
@@ -18,6 +18,7 @@ import Zoom from "./input/mouse/Zoom"
|
||||
export default class Blueprint extends IElement {
|
||||
|
||||
static tagName = "ueb-blueprint"
|
||||
#pinGuidMap = new Map()
|
||||
/** @type {number} */
|
||||
gridSize = Configuration.gridSize
|
||||
/** @type {NodeElement[]}" */
|
||||
@@ -334,22 +335,36 @@ export default class Blueprint extends IElement {
|
||||
* @param {...IElement} graphElements
|
||||
*/
|
||||
addGraphElement(...graphElements) {
|
||||
const intoArray = element => {
|
||||
if (element instanceof NodeElement) {
|
||||
this.nodes.push(element)
|
||||
element.getPinElements().forEach(
|
||||
pinElement => this.#pinGuidMap[
|
||||
pinElement.]
|
||||
)
|
||||
} else if (element instanceof LinkElement) {
|
||||
this.links.push(element)
|
||||
}
|
||||
}
|
||||
if (this.nodesContainerElement) {
|
||||
graphElements.forEach(element => {
|
||||
if (element.closest(Blueprint.tagName) != this) {
|
||||
// If not already the in target DOM position
|
||||
this.nodesContainerElement.appendChild(element)
|
||||
intoArray(element)
|
||||
}
|
||||
this.nodes = [...this.querySelectorAll(NodeElement.tagName)]
|
||||
this.links = [...this.querySelectorAll(LinkElement.tagName)]
|
||||
})
|
||||
} else {
|
||||
graphElements.forEach(element => {
|
||||
if (element instanceof NodeElement) {
|
||||
this.nodes.push(element)
|
||||
} else if (element instanceof LinkElement) {
|
||||
this.links.push(element)
|
||||
}
|
||||
})
|
||||
graphElements
|
||||
.filter(element => {
|
||||
if (element instanceof NodeElement) {
|
||||
return !this.nodes.includes(element)
|
||||
} else if (element instanceof LinkElement) {
|
||||
return !this.links.includes(element)
|
||||
}
|
||||
return false
|
||||
})
|
||||
.forEach(intoArray)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@ export default class NodeElement extends ISelectableDraggableElement {
|
||||
super(entity, new NodeTemplate())
|
||||
/** @type {ObjectEntity} */
|
||||
this.entity
|
||||
/** @type {NodeTemplate} */
|
||||
this.template
|
||||
this.dragLinkObjects = []
|
||||
super.setLocation([this.entity.NodePosX, this.entity.NodePosY])
|
||||
}
|
||||
@@ -34,6 +36,10 @@ export default class NodeElement extends ISelectableDraggableElement {
|
||||
return this.entity.getName()
|
||||
}
|
||||
|
||||
getPinElements() {
|
||||
return this.template.getPinElements(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {PinEntity[]}
|
||||
*/
|
||||
|
||||
@@ -4,6 +4,7 @@ import PinTemplate from "../template/PinTemplate"
|
||||
|
||||
/**
|
||||
* @typedef {import("./NodeElement").default} NodeElement
|
||||
* @typedef {import("../entity/GuidEntity").default} GuidEntity
|
||||
*/
|
||||
export default class PinElement extends IElement {
|
||||
|
||||
@@ -40,6 +41,11 @@ export default class PinElement extends IElement {
|
||||
]
|
||||
}
|
||||
|
||||
/** @type {GuidEntity} */
|
||||
GetPinId() {
|
||||
return this.entity.PinId
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {String}
|
||||
*/
|
||||
@@ -51,7 +57,7 @@ export default class PinElement extends IElement {
|
||||
* @returns {String}
|
||||
*/
|
||||
getPinDisplayName() {
|
||||
return this.entity.PinFriendlyName
|
||||
return this.entity.PinName
|
||||
}
|
||||
|
||||
isInput() {
|
||||
@@ -90,6 +96,12 @@ export default class PinElement extends IElement {
|
||||
return this.closest("ueb-node")
|
||||
}
|
||||
|
||||
getLinks() {
|
||||
return this.entity.LinkedTo.map(pinReference =>
|
||||
pinReference
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {PinElement} targetPinElement
|
||||
*/
|
||||
|
||||
@@ -46,7 +46,7 @@ export default class IEntity {
|
||||
if (defaultValue instanceof Function) {
|
||||
defaultValue = TypeInitialization.sanitize(new defaultValue())
|
||||
}
|
||||
target[property] = defaultValue
|
||||
target[property] = TypeInitialization.sanitize(defaultValue)
|
||||
}
|
||||
}
|
||||
defineAllAttributes([], this, this.constructor.attributes)
|
||||
|
||||
@@ -18,9 +18,10 @@ export default class IMouseClickDrag extends IPointing {
|
||||
/** @type {(e: MouseEvent) => void} */
|
||||
#mouseUpHandler
|
||||
|
||||
/** @type {Boolean} */
|
||||
#trackingMouse = false
|
||||
|
||||
started = false
|
||||
|
||||
constructor(target, blueprint, options) {
|
||||
super(target, blueprint, options)
|
||||
this.clickButton = options?.clickButton ?? 0
|
||||
@@ -28,7 +29,6 @@ export default class IMouseClickDrag extends IPointing {
|
||||
this.moveEverywhere = options?.moveEverywhere ?? false
|
||||
this.looseTarget = options?.looseTarget ?? false
|
||||
this.consumeClickEvent = options?.consumeClickEvent ?? true
|
||||
this.started = false
|
||||
this.clickedPosition = [0, 0]
|
||||
|
||||
const movementListenedElement = this.moveEverywhere ? document.documentElement : this.movementSpace
|
||||
@@ -44,10 +44,8 @@ export default class IMouseClickDrag extends IPointing {
|
||||
if (this.consumeClickEvent) {
|
||||
e.stopImmediatePropagation() // Captured, don't call anyone else
|
||||
}
|
||||
self.started = false
|
||||
// Attach the listeners
|
||||
movementListenedElement.addEventListener("mousemove", self.#mouseStartedMovingHandler)
|
||||
document.addEventListener("mouseup", self.#mouseUpHandler)
|
||||
self.clickedPosition = self.locationFromEvent(e)
|
||||
self.clicked(self.clickedPosition)
|
||||
}
|
||||
@@ -62,9 +60,13 @@ export default class IMouseClickDrag extends IPointing {
|
||||
|
||||
this.#mouseStartedMovingHandler = e => {
|
||||
e.preventDefault()
|
||||
if (this.consumeClickEvent) {
|
||||
e.stopImmediatePropagation() // Captured, don't call anyone else
|
||||
}
|
||||
// Delegate from now on to self.#mouseMoveHandler
|
||||
movementListenedElement.removeEventListener("mousemove", self.#mouseStartedMovingHandler)
|
||||
movementListenedElement.addEventListener("mousemove", self.#mouseMoveHandler)
|
||||
document.addEventListener("mouseup", self.#mouseUpHandler)
|
||||
// Handler calls e.preventDefault() when it receives the event, this means dispatchEvent returns false
|
||||
const dragEvent = self.getEvent(Configuration.trackingMouseEventName.begin)
|
||||
self.#trackingMouse = this.target.dispatchEvent(dragEvent) == false
|
||||
@@ -75,6 +77,9 @@ export default class IMouseClickDrag extends IPointing {
|
||||
|
||||
this.#mouseMoveHandler = e => {
|
||||
e.preventDefault()
|
||||
if (this.consumeClickEvent) {
|
||||
e.stopImmediatePropagation() // Captured, don't call anyone else
|
||||
}
|
||||
const location = self.locationFromEvent(e)
|
||||
const movement = [e.movementX, e.movementY]
|
||||
self.dragTo(location, movement)
|
||||
@@ -86,6 +91,9 @@ export default class IMouseClickDrag extends IPointing {
|
||||
this.#mouseUpHandler = e => {
|
||||
if (!self.exitAnyButton || e.button == self.clickButton) {
|
||||
e.preventDefault()
|
||||
if (this.consumeClickEvent) {
|
||||
e.stopImmediatePropagation() // Captured, don't call anyone else
|
||||
}
|
||||
// Remove the handlers of "mousemove" and "mouseup"
|
||||
movementListenedElement.removeEventListener("mousemove", self.#mouseStartedMovingHandler)
|
||||
movementListenedElement.removeEventListener("mousemove", self.#mouseMoveHandler)
|
||||
@@ -96,6 +104,7 @@ export default class IMouseClickDrag extends IPointing {
|
||||
this.target.dispatchEvent(dragEvent)
|
||||
self.#trackingMouse = false
|
||||
}
|
||||
self.started = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ export default class MouseCreateLink extends IMouseClickDrag {
|
||||
let self = this
|
||||
this.#mouseenterHandler = e => {
|
||||
if (!self.enteredPin) {
|
||||
e.preventDefault()
|
||||
self.linkValid = false
|
||||
self.enteredPin = e.target
|
||||
const a = self.enteredPin, b = self.target
|
||||
@@ -53,6 +54,7 @@ export default class MouseCreateLink extends IMouseClickDrag {
|
||||
}
|
||||
this.#mouseleaveHandler = e => {
|
||||
if (self.enteredPin == e.target) {
|
||||
e.preventDefault()
|
||||
self.enteredPin = null
|
||||
self.linkValid = false
|
||||
this.setLinkMessage(LinkMessageElement.placeNode())
|
||||
@@ -94,6 +96,7 @@ export default class MouseCreateLink extends IMouseClickDrag {
|
||||
}
|
||||
this.enteredPin = null
|
||||
this.link = null
|
||||
this.#listenedPins = null
|
||||
}
|
||||
|
||||
setLinkMessage(linkMessage) {
|
||||
|
||||
@@ -51,4 +51,11 @@ export default class NodeTemplate extends SelectableDraggableTemplate {
|
||||
pins.filter(v => v.isInput()).forEach(v => inputContainer.appendChild(new PinElement(v)))
|
||||
pins.filter(v => v.isOutput()).forEach(v => outputContainer.appendChild(new PinElement(v)))
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {NodeElement} node
|
||||
*/
|
||||
getPinElements(node) {
|
||||
return node.querySelectorAll(PinElement.tagName)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import html from "./html"
|
||||
import ITemplate from "./ITemplate"
|
||||
import sanitizeText from "./sanitizeText"
|
||||
import Utility from "../Utility"
|
||||
import NodeElement from "../element/NodeElement"
|
||||
|
||||
/**
|
||||
* @typedef {import("../element/NodeElement").default} NodeElement
|
||||
@@ -36,14 +37,14 @@ export default class PinTemplate extends ITemplate {
|
||||
super.apply(pin)
|
||||
pin.classList.add(
|
||||
"ueb-node-" + (pin.isInput() ? "input" : pin.isOutput() ? "output" : "hidden"),
|
||||
"ueb-pin-" + sanitizeText(pin.getType()),
|
||||
pin.isConnected() ? "ueb-pin-fill" : null
|
||||
"ueb-pin-" + sanitizeText(pin.getType())
|
||||
)
|
||||
pin.clickableElement = pin
|
||||
pin.nodeElement = pin.closest("ueb-node")
|
||||
pin.nodeElement = pin.closest(NodeElement.tagName)
|
||||
if (!pin.nodeElement) {
|
||||
window.customElements.whenDefined(linkMessage.constructor.tagName).then(linkMessage)
|
||||
}
|
||||
pin.getLin
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user