mirror of
https://github.com/barsdeveloper/ueblueprint.git
synced 2026-03-03 05:27:31 +08:00
Paste event handling WIP
This commit is contained in:
@@ -6,6 +6,7 @@ import Select from "./input/Select"
|
||||
import Utility from "./Utility"
|
||||
import Zoom from "./input/Zoom"
|
||||
import BlueprintData from "./BlueprintData"
|
||||
import Paste from "./input/Paste"
|
||||
|
||||
/** @typedef {import("./graph/GraphNode").default} GraphNode */
|
||||
export default class Blueprint extends GraphElement {
|
||||
@@ -84,6 +85,8 @@ export default class Blueprint extends GraphElement {
|
||||
moveEverywhere: true,
|
||||
exitAnyButton: true
|
||||
})
|
||||
|
||||
this.pasteObject = new Paste(this.getGridDOMElement(), this)
|
||||
}
|
||||
|
||||
getGridDOMElement() {
|
||||
@@ -94,6 +97,7 @@ export default class Blueprint extends GraphElement {
|
||||
super.disconnectedCallback()
|
||||
this.dragObject.unlistenDOMElement()
|
||||
this.selectObject.unlistenDOMElement()
|
||||
this.pasteObject.unlistenDOMElement()
|
||||
}
|
||||
|
||||
getScroll() {
|
||||
|
||||
@@ -24,4 +24,12 @@ export default class ObjectEntity extends Entity {
|
||||
getAttributes() {
|
||||
return ObjectEntity.attributes
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns {String} The name of the node
|
||||
*/
|
||||
getNodeDisplayName() {
|
||||
return this.Name
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,14 @@ export default class PinEntity extends Entity {
|
||||
return PinEntity.attributes
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns {String}
|
||||
*/
|
||||
getPinDisplayName() {
|
||||
return this.PinName
|
||||
}
|
||||
|
||||
isOutput() {
|
||||
if (this.Direction === "EGPD_Output") {
|
||||
return true
|
||||
|
||||
@@ -15,7 +15,7 @@ export default class MouseClickDrag extends Pointing {
|
||||
const movementListenedElement = this.moveEverywhere ? document.documentElement : this.movementSpace
|
||||
let self = this
|
||||
|
||||
this.mouseDownHandler = function (e) {
|
||||
this.mouseDownHandler = e => {
|
||||
switch (e.button) {
|
||||
case self.clickButton:
|
||||
// Either doesn't matter or consider the click only when clicking on the parent, not descandants
|
||||
@@ -37,7 +37,7 @@ export default class MouseClickDrag extends Pointing {
|
||||
}
|
||||
}
|
||||
|
||||
this.mouseStartedMovingHandler = function (e) {
|
||||
this.mouseStartedMovingHandler = e => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
|
||||
@@ -50,7 +50,7 @@ export default class MouseClickDrag extends Pointing {
|
||||
self.started = true
|
||||
}
|
||||
|
||||
this.mouseMoveHandler = function (e) {
|
||||
this.mouseMoveHandler = e => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
const location = self.getLocation(e)
|
||||
@@ -58,7 +58,7 @@ export default class MouseClickDrag extends Pointing {
|
||||
self.dragTo(location, movement)
|
||||
}
|
||||
|
||||
this.mouseUpHandler = function (e) {
|
||||
this.mouseUpHandler = e => {
|
||||
if (!self.exitAnyButton || e.button == self.clickButton) {
|
||||
// Remove the handlers of "mousemove" and "mouseup"
|
||||
movementListenedElement.removeEventListener('mousemove', self.mouseStartedMovingHandler)
|
||||
|
||||
@@ -13,7 +13,7 @@ export default class MouseWheel extends Pointing {
|
||||
this.looseTarget = options?.looseTarget ?? true
|
||||
let self = this
|
||||
|
||||
this.mouseWheelHandler = function (e) {
|
||||
this.mouseWheelHandler = e => {
|
||||
e.preventDefault()
|
||||
const location = self.getLocation(e)
|
||||
self.wheel(Math.sign(e.deltaY), location)
|
||||
|
||||
29
js/input/Paste.js
Normal file
29
js/input/Paste.js
Normal file
@@ -0,0 +1,29 @@
|
||||
import GraphNode from "../graph/GraphNode"
|
||||
import ObjectSerializer from "../serialization/ObjectSerializer"
|
||||
|
||||
export default class Paste {
|
||||
|
||||
constructor(target, blueprint, options) {
|
||||
/** @type {HTMLElement} */
|
||||
this.target = target
|
||||
/** @type {import("../Blueprint").default}" */
|
||||
this.blueprint = blueprint
|
||||
this.serializer = new ObjectSerializer()
|
||||
|
||||
let self = this
|
||||
this.pasteHandler = e => {
|
||||
self.pasted(e.clipboardData.getData("text"))
|
||||
}
|
||||
this.target.addEventListener("paste", this.pasteHandler)
|
||||
}
|
||||
|
||||
pasted(value) {
|
||||
let nodes = this.serializer.readMultiple(value).map(entity => new GraphNode(entity))
|
||||
this.blueprint.addNode(...nodes)
|
||||
}
|
||||
|
||||
unlistenDOMElement() {
|
||||
this.target.removeEventListener("paste", this.pasteHandler)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -29,6 +29,20 @@ export default class ObjectSerializer extends Serializer {
|
||||
return parseResult.value
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {String} value
|
||||
* @returns {ObjectEntity[]}
|
||||
*/
|
||||
readMultiple(value) {
|
||||
const parseResult = Serializer.grammar.MultipleObject.parse(value)
|
||||
if (!parseResult.status) {
|
||||
console.error("Error when trying to parse the object.")
|
||||
return parseResult
|
||||
}
|
||||
return parseResult.value
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {ObjectEntity} object
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
import PinEntity from "../entity/PinEntity"
|
||||
import Template from "./Template"
|
||||
|
||||
/**
|
||||
* @typedef {import("../entity/ObjectEntity").default} ObjectEntity
|
||||
*/
|
||||
export default class NodeTemplate extends Template {
|
||||
|
||||
/**
|
||||
* Computes the html content of the target element.
|
||||
* @param {HTMLElement} entity Entity representing the element
|
||||
* @param {ObjectEntity} entity Entity representing the element
|
||||
* @returns The computed html
|
||||
*/
|
||||
header(entity) {
|
||||
@@ -13,7 +16,7 @@ export default class NodeTemplate extends Template {
|
||||
<div class="ueb-node-header">
|
||||
<span class="ueb-node-name">
|
||||
<span class="ueb-node-symbol"></span>
|
||||
<span class="ueb-node-text">${entity.graphNodeName}</span>
|
||||
<span class="ueb-node-text">${entity.getNodeDisplayName()}</span>
|
||||
</span>
|
||||
</div>
|
||||
`
|
||||
@@ -21,10 +24,11 @@ export default class NodeTemplate extends Template {
|
||||
|
||||
/**
|
||||
* Computes the html content of the target element.
|
||||
* @param {import("../entity/ObjectEntity").default} entity Entity representing the element
|
||||
* @param {ObjectEntity} entity Entity representing the element
|
||||
* @returns The computed html
|
||||
*/
|
||||
body(entity) {
|
||||
/** @type {PinEntity[]} */
|
||||
let inputs = entity.CustomProperties.filter(v => v instanceof PinEntity)
|
||||
let outputs = inputs.filter(v => v.isOutput())
|
||||
inputs = inputs.filter(v => !v.isOutput())
|
||||
@@ -34,14 +38,14 @@ export default class NodeTemplate extends Template {
|
||||
${inputs.map((input, index) => `
|
||||
<div class="ueb-node-input ueb-node-value-${input.type}">
|
||||
<span class="ueb-node-value-icon ${inputs[index].connected ? 'ueb-node-value-fill' : ''}"></span>
|
||||
${input.name}
|
||||
${input.getPinDisplayName()}
|
||||
</div>
|
||||
`).join("") ?? ""}
|
||||
</div>
|
||||
<div class="ueb-node-outputs">
|
||||
${outputs.map((output, index) => `
|
||||
<div class="ueb-node-output ueb-node-value-${output.type}">
|
||||
${output.name}
|
||||
${output.getPinDisplayName()}
|
||||
<span class="ueb-node-value-icon ${outputs[index].connected ? 'ueb-node-value-fill' : ''}"></span>
|
||||
</div>
|
||||
`).join("") ?? ''}
|
||||
@@ -52,7 +56,7 @@ export default class NodeTemplate extends Template {
|
||||
|
||||
/**
|
||||
* Computes the html content of the target element.
|
||||
* @param {HTMLElement} entity Entity representing the element
|
||||
* @param {ObjectEntity} entity Entity representing the element
|
||||
* @returns The computed html
|
||||
*/
|
||||
render(entity) {
|
||||
|
||||
@@ -9,7 +9,7 @@ export default class Template {
|
||||
* @returns The computed html
|
||||
*/
|
||||
render(entity) {
|
||||
return ``
|
||||
return ""
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user