Link implementation wip

This commit is contained in:
barsdeveloper
2022-01-18 21:21:45 +01:00
parent ce5b184b3d
commit e90277826d
19 changed files with 580 additions and 454 deletions

View File

@@ -1,19 +1,19 @@
import BlueprintTemplate from "./template/BlueprintTemplate"
import Configuration from "./Configuration"
import Copy from "./input/common/Copy"
import MouseScrollGraph from "./input/mouse/MouseScrollGraph"
import GraphElement from "./graph/GraphElement"
import GraphLink from "./graph/GraphLink"
import GraphNode from "./graph/GraphNode"
import GraphSelector from "./graph/GraphSelector"
import KeyboardCanc from "./input/keybaord/KeyboardCanc"
import KeyboardSelectAll from "./input/keybaord/KeyboardSelectAll"
import MouseScrollGraph from "./input/mouse/MouseScrollGraph"
import MouseTracking from "./input/mouse/MouseTracking"
import Paste from "./input/common/Paste"
import Select from "./input/mouse/Select"
import Unfocus from "./input/mouse/Unfocus"
import Utility from "./Utility"
import Zoom from "./input/mouse/Zoom"
import KeyboardSelectAll from "./input/keybaord/KeyboardSelectAll"
export default class Blueprint extends GraphElement {
@@ -94,7 +94,6 @@ export default class Blueprint extends GraphElement {
createInputObjects() {
return [
new Copy(this.getGridDOMElement(), this),
new Paste(this.getGridDOMElement(), this),
new KeyboardCanc(this.getGridDOMElement(), this),

View File

@@ -10,6 +10,16 @@ export default class Utility {
return getComputedStyle(element).getPropertyValue("--ueb-scale")
}
static convertLocation(viewportLocation, movementElement) {
const scaleCorrection = 1 / Utility.getScale(movementElement)
const targetOffset = movementElement.getBoundingClientRect()
let location = [
Math.round((viewportLocation[0] - targetOffset.x) * scaleCorrection),
Math.round((viewportLocation[1] - targetOffset.y) * scaleCorrection)
]
return location
}
/**
* Sets a value in an object
* @param {String[]} keys The chained keys to access from object in order to set the value

View File

@@ -14,11 +14,11 @@ export default class GraphElement extends HTMLElement {
*/
constructor(entity, template) {
super()
/** @type {Blueprint}" */
/** @type {Blueprint} */
this.blueprint = null
/** @type {Entity}" */
/** @type {Entity} */
this.entity = entity
/** @type {Template}" */
/** @type {Template} */
this.template = template
/** @type {Context[]} */
this.inputObjects = []

View File

@@ -3,7 +3,7 @@ import LinkTemplate from "../template/LinkTemplate"
/**
* @type {import("./GraphPin").default} GraphPin
* @typedef {import("./GraphPin").default} GraphPin
*/
export default class GraphLink extends GraphElement {
@@ -20,19 +20,30 @@ export default class GraphLink extends GraphElement {
* @param {?GraphPin} destination
*/
constructor(source, destination) {
super(this, new LinkTemplate())
super({}, new LinkTemplate())
/** @type {import("../template/LinkTemplate").default} */
this.template
this.setSource(source)
this.setDestination(destination)
this.setSourcePin(source)
this.setDestinationPin(destination)
}
setSourceLocation(location) {
this.template.applySourceLocation(this.#source.getLinkLocation())
if (location == null) {
location = this.#source.template.getLinkLocation(this.#source)
}
this.template.applySourceLocation(this, location)
}
setDestinationLocation(location) {
this.template.applyDestinationLocation(this.#destination.getLinkLocation())
if (location == null) {
location = this.#destination.template.getLinkLocation(this.#destination)
}
this.template.applyDestinationLocation(this, location)
}
getSourcePin() {
return this.#source
}
/**
@@ -44,6 +55,12 @@ export default class GraphLink extends GraphElement {
this.#source = graphPin
this.#source?.addEventListener("ueb-node-delete", this.#nodeDeleteHandler)
this.#source?.addEventListener("ueb-node-drag", this.#nodeDragSourceHandler)
this.setSourceLocation()
this.originatesFromInput = this.#destination == null
}
getDestinationPin() {
return this.#destination
}
/**
@@ -56,6 +73,7 @@ export default class GraphLink extends GraphElement {
this.#destination = graphPin
this.#destination?.addEventListener("ueb-node-delete", this.#nodeDeleteHandler)
this.#destination?.addEventListener("ueb-node-drag", this.#nodeDragDestinatonHandler)
this.originatesFromInput = false
}
}

View File

@@ -1,8 +1,8 @@
import NodeTemplate from "../template/NodeTemplate"
import ObjectEntity from "../entity/ObjectEntity"
import PinEntity from "../entity/PinEntity"
import SelectableDraggable from "./SelectableDraggable"
import SerializerFactory from "../serialization/SerializerFactory"
import PinEntity from "../entity/PinEntity"
export default class GraphNode extends SelectableDraggable {

View File

@@ -1,7 +1,6 @@
import GraphElement from "./GraphElement"
import PinTemplate from "../template/PinTemplate"
import MouseCreateLink from "../input/mouse/MouseCreateLink"
import GraphLink from "./GraphLink"
export default class GraphPin extends GraphElement {
@@ -9,6 +8,8 @@ export default class GraphPin extends GraphElement {
super(entity, new PinTemplate())
/** @type {import("../entity/PinEntity").default} */
this.entity
/** @type {PinTemplate} */
this.template
/** @type {HTMLElement} */
this.clickableElement = null
}
@@ -16,7 +17,8 @@ export default class GraphPin extends GraphElement {
createInputObjects() {
return [
new MouseCreateLink(this.clickableElement, this.blueprint, {
moveEverywhere: true
moveEverywhere: true,
looseTarget: true
}),
]
}
@@ -49,15 +51,6 @@ export default class GraphPin extends GraphElement {
return this.entity.getType()
}
/**
*
* @returns {GraphLink} The link created
*/
dragLink() {
let link = new GraphLink(this)
return link
}
/**
* Returns The exact location where the link originates from or arrives at.
* @returns {Number[]} The location array

View File

@@ -29,7 +29,7 @@ export default class MouseClickDrag extends Pointing {
// Attach the listeners
movementListenedElement.addEventListener("mousemove", self.mouseStartedMovingHandler)
document.addEventListener("mouseup", self.mouseUpHandler)
self.clickedPosition = self.getLocation(e)
self.clickedPosition = self.locationFromEvent(e)
self.clicked(self.clickedPosition)
return true
}
@@ -59,7 +59,7 @@ export default class MouseClickDrag extends Pointing {
this.mouseMoveHandler = e => {
e.preventDefault()
e.stopPropagation()
const location = self.getLocation(e)
const location = self.locationFromEvent(e)
const movement = [e.movementX, e.movementY]
self.dragTo(location, movement)
}

View File

@@ -1,29 +1,61 @@
import GraphLink from "../../graph/GraphLink"
import MouseClickDrag from "./MouseClickDrag"
export default class MouseCreateLink extends MouseClickDrag {
/** @type {(e: MouseEvent) => void} */
#mouseenterHandler
/** @type {(e: MouseEvent) => void} */
#mouseleaveHandler
constructor(target, blueprint, options) {
super(target, blueprint, options)
/** @type {import("../../graph/GraphPin").default} */
this.target
/** @type {import("../../graph/GraphLink").default} */
this.link
/** @type {import("../../entity/PinEntity").default} */
this.enteredPin
let self = this
this.#mouseenterHandler = e => {
if (!self.enteredPin) {
self.enteredPin = e.target
}
}
this.#mouseleaveHandler = e => {
if (self.enteredPin == e.target) {
self.enteredPin = null
}
}
}
startDrag() {
let link = this.target.dragLink()
this.link = new GraphLink(this.target, null)
this.blueprint.nodesContainerElement.insertBefore(this.link, this.blueprint.selectorElement.nextElementSibling)
this.blueprint.querySelectorAll("ueb-pin." + this.target.isInput() ? "output" : "input")
.forEach(pin => {
pin.addEventListener("mouseenter", this.#mouseenterHandler)
pin.addEventListener("mouseleave", this.#mouseleaveHandler)
})
}
dragTo(location, movement) {
//this.selectorElement.doSelecting(location)
this.link.setDestinationLocation(location)
}
endDrag() {
if (this.started) {
//this.selectorElement.finishSelecting()
this.blueprint.querySelectorAll("ueb-pin." + this.target.isInput() ? "output" : "input")
.forEach(pin => {
pin.removeEventListener("mouseenter", this.#mouseenterHandler)
pin.removeEventListener("mouseleave", this.#mouseleaveHandler)
})
if (this.enteredPin) {
this.link.setDestinationPin(this.link)
} else {
// this.blueprint.unselectAll()
// this.link.remove()
}
this.link = null
}
}

View File

@@ -8,7 +8,7 @@ export default class MouseTracking extends Pointing {
let self = this
this.mousemoveHandler = e => {
self.blueprint.entity.mousePosition = self.getLocation(e)
self.blueprint.entity.mousePosition = self.locationFromEvent(e)
return true
}
}

View File

@@ -16,7 +16,7 @@ export default class MouseWheel extends Pointing {
this.mouseWheelHandler = e => {
e.preventDefault()
const location = self.getLocation(e)
const location = self.locationFromEvent(e)
self.wheel(Math.sign(e.deltaY), location)
return true
}

View File

@@ -13,13 +13,7 @@ export default class Pointing extends Context {
* @param {MouseEvent} mouseEvent
* @returns
*/
getLocation(mouseEvent) {
const scaleCorrection = 1 / Utility.getScale(this.target)
const targetOffset = this.movementSpace.getBoundingClientRect()
let location = [
Math.round((mouseEvent.clientX - targetOffset.x) * scaleCorrection),
Math.round((mouseEvent.clientY - targetOffset.y) * scaleCorrection)
]
return location
locationFromEvent(mouseEvent) {
return Utility.convertLocation([mouseEvent.clientX, mouseEvent.clientY], this.movementSpace)
}
}

View File

@@ -1,4 +1,5 @@
import html from "./html"
import sanitizeText from "./sanitizeText"
import Template from "./Template"
/**
@@ -25,7 +26,6 @@ export default class LinkTemplate extends Template {
*/
apply(link) {
super.apply(link)
}
/**
@@ -34,8 +34,8 @@ export default class LinkTemplate extends Template {
*/
applySourceLocation(link, initialPosition) {
// Set initial position
link.style.setProperty("--ueb-link-from-x", sanitizeText(initialPosition[0]))
link.style.setProperty("--ueb-link-from-y", sanitizeText(initialPosition[1]))
link.style.setProperty("--ueb-from-x", sanitizeText(initialPosition[0]))
link.style.setProperty("--ueb-from-y", sanitizeText(initialPosition[1]))
}
/**
@@ -43,7 +43,7 @@ export default class LinkTemplate extends Template {
* @param {GraphLink} link Link element
*/
applyDestinationLocation(link, finalPosition) {
link.style.setProperty("--ueb-link-to-x", sanitizeText(finalPosition[0]))
link.style.setProperty("--ueb-link-to-y", sanitizeText(finalPosition[1]))
link.style.setProperty("--ueb-to-x", sanitizeText(finalPosition[0]))
link.style.setProperty("--ueb-to-y", sanitizeText(finalPosition[1]))
}
}

View File

@@ -1,3 +1,4 @@
import Utility from "../Utility"
import html from "./html"
import sanitizeText from "./sanitizeText"
import Template from "./Template"
@@ -33,6 +34,18 @@ export default class PinTemplate extends Template {
apply(pin) {
super.apply(pin)
pin.classList.add("ueb-node-" + pin.isInput() ? "input" : "output", "ueb-node-value-" + sanitizeText(pin.getType()))
pin.clickableElement = pin.querySelector(".ueb-node-value-icon")
pin.clickableElement = pin
}
}
/**
*
* @param {GraphPin} pin
* @returns
*/
getLinkLocation(pin) {
const rect = pin.querySelector(".ueb-node-value-icon").getBoundingClientRect()
return Utility.convertLocation(
[(rect.left + rect.right) / 2, (rect.top + rect.bottom) / 2],
pin.blueprint.gridElement)
}
}

View File

@@ -12,7 +12,6 @@ export default class SelectorTemplate extends Template {
*/
apply(selector) {
super.apply(selector)
selector.classList.add("ueb-selector")
this.applyFinishSelecting(selector)
}
@@ -22,11 +21,11 @@ export default class SelectorTemplate extends Template {
*/
applyStartSelecting(selector, initialPosition) {
// Set initial position
selector.style.setProperty("--ueb-select-from-x", sanitizeText(initialPosition[0]))
selector.style.setProperty("--ueb-select-from-y", sanitizeText(initialPosition[1]))
selector.style.setProperty("--ueb-from-x", sanitizeText(initialPosition[0]))
selector.style.setProperty("--ueb-from-y", sanitizeText(initialPosition[1]))
// Final position coincide with the initial position, at the beginning of selection
selector.style.setProperty("--ueb-select-to-x", sanitizeText(initialPosition[0]))
selector.style.setProperty("--ueb-select-to-y", sanitizeText(initialPosition[1]))
selector.style.setProperty("--ueb-to-x", sanitizeText(initialPosition[0]))
selector.style.setProperty("--ueb-to-y", sanitizeText(initialPosition[1]))
selector.dataset.selecting = "true"
}
@@ -35,8 +34,8 @@ export default class SelectorTemplate extends Template {
* @param {GraphSelector} selector Selector element
*/
applyDoSelecting(selector, finalPosition) {
selector.style.setProperty("--ueb-select-to-x", sanitizeText(finalPosition[0]))
selector.style.setProperty("--ueb-select-to-y", sanitizeText(finalPosition[1]))
selector.style.setProperty("--ueb-to-x", sanitizeText(finalPosition[0]))
selector.style.setProperty("--ueb-to-y", sanitizeText(finalPosition[1]))
}
/**

View File

@@ -1,2 +1,5 @@
/**
* This solves the sole purpose of providing compression capability for html inside template literals strings. Check rollup.config.js function minifyHTML()
*/
const html = String.raw
export default html