diff --git a/css/ueblueprint-style.css b/css/ueblueprint-style.css index aa2cf76..9ca2294 100644 --- a/css/ueblueprint-style.css +++ b/css/ueblueprint-style.css @@ -294,6 +294,7 @@ u-blueprint { } .ueb-selector { + display : block; position : absolute; visibility: hidden; top : min(var(--ueb-select-from-y) * 1px, var(--ueb-select-to-y) * 1px); diff --git a/js/GraphNode.js b/js/GraphNode.js index 2537b41..b78c4fb 100644 --- a/js/GraphNode.js +++ b/js/GraphNode.js @@ -11,6 +11,7 @@ export default class GraphNode extends SelectableDraggable { } connectedCallback() { + const type = this.getAttribute('type')?.trim() super.connectedCallback() this.classList.add('ueb-node') if (this.selected) { @@ -21,4 +22,4 @@ export default class GraphNode extends SelectableDraggable { } } -customElements.define('u-object', GraphNode) +customElements.define('u-node', GraphNode) diff --git a/js/GraphSelector.js b/js/GraphSelector.js new file mode 100644 index 0000000..2e30280 --- /dev/null +++ b/js/GraphSelector.js @@ -0,0 +1,54 @@ +import FastSelectionModel from "./selection/FastSelectionModel"; +import GraphEntity from "./GraphEntity"; +import Template from "./template/Template"; + +export default class GraphSelector extends GraphEntity { + + constructor() { + super(new Template()) + /** + * @type {import("./GraphSelector").default} + */ + this.selectionModel = null + } + + connectedCallback() { + super.connectedCallback() + this.classList.add('ueb-selector') + this.dataset.selecting = "false" + } + + /** + * Create a selection rectangle starting from the specified position + * @param {number[]} initialPosition - Selection rectangle initial position (relative to the .ueb-grid element) + */ + startSelecting(initialPosition) { + initialPosition = this.blueprint.compensateTranslation(initialPosition) + // Set initial position + this.style.setProperty('--ueb-select-from-x', initialPosition[0]) + this.style.setProperty('--ueb-select-from-y', initialPosition[1]) + // Final position coincide with the initial position, at the beginning of selection + this.style.setProperty('--ueb-select-to-x', initialPosition[0]) + this.style.setProperty('--ueb-select-to-y', initialPosition[1]) + this.dataset.selecting = "true" + this.selectionModel = new FastSelectionModel(initialPosition, this.blueprint.nodes, this.blueprint.nodeBoundariesSupplier, this.blueprint.nodeSelectToggleFunction) + } + + /** + * Move selection rectagle to the specified final position. The initial position was specified by startSelecting() + * @param {number[]} finalPosition - Selection rectangle final position (relative to the .ueb-grid element) + */ + doSelecting(finalPosition) { + finalPosition = this.blueprint.compensateTranslation(finalPosition) + this.style.setProperty('--ueb-select-to-x', finalPosition[0]) + this.style.setProperty('--ueb-select-to-y', finalPosition[1]) + this.selectionModel.selectTo(finalPosition) + } + + finishSelecting() { + this.dataset.selecting = "false" + this.selectionModel = null + } +} + +customElements.define('u-selector', GraphSelector) \ No newline at end of file diff --git a/js/UEBlueprint.js b/js/UEBlueprint.js index 54619bf..d67a891 100644 --- a/js/UEBlueprint.js +++ b/js/UEBlueprint.js @@ -2,13 +2,12 @@ import Utility from "./Utility" import DragScroll from "./input/DragScroll" import Select from "./input/Select" import Zoom from "./input/Zoom" -import FastSelectionModel from "./selection/FastSelectionModel" -import SimpleSelectionModel from "./selection/SimpleSelectionModel" import GraphEntity from "./GraphEntity" import BlueprintTemplate from "./template/BlueprintTemplate" +import GraphSelector from "./GraphSelector" /** - * @typedef {import("./GraphNode").default} GrapNode + * @typedef {import("./GraphNode").default} GraphNode */ export default class UEBlueprint extends GraphEntity { @@ -18,7 +17,7 @@ export default class UEBlueprint extends GraphEntity { constructor() { super(new BlueprintTemplate()) - /** @type {GrapNode[]}" */ + /** @type {GraphNode[]}" */ this.nodes = new Array() this.expandGridSize = 400 /** @type {HTMLElement} */ @@ -41,10 +40,7 @@ export default class UEBlueprint extends GraphEntity { this.zoom = 0 /** @type {HTMLElement} */ this.headerElement = null - /** @type {FastSelectionModel} */ - this.selectionModel = null - let self = this - /** @type {(node: GrapNode) => BoundariesInfo} */ + /** @type {(node: GraphNode) => BoundariesInfo} */ this.nodeBoundariesSupplier = (node) => { let rect = node.getBoundingClientRect() let gridRect = this.nodesContainerElement.getBoundingClientRect() @@ -57,7 +53,7 @@ export default class UEBlueprint extends GraphEntity { secondarySup: (rect.bottom - gridRect.bottom) * scaleCorrection } } - /** @type {(node: GrapNode, selected: bool) => void}} */ + /** @type {(node: GraphNode, selected: bool) => void}} */ this.nodeSelectToggleFunction = (node, selected) => { node.setSelected(selected) } @@ -67,7 +63,7 @@ export default class UEBlueprint extends GraphEntity { super.connectedCallback() this.classList.add('ueb', `ueb-zoom-${this.zoom}`) - this.headerElement = this.querySelector('.ueb-node-header') + this.headerElement = this.querySelector('.ueb-viewport-header') console.assert(this.headerElement, "Header element not provided by the template.") this.overlayElement = this.querySelector('.ueb-viewport-overlay') console.assert(this.overlayElement, "Overlay element not provided by the template.") @@ -75,10 +71,10 @@ export default class UEBlueprint extends GraphEntity { console.assert(this.viewportElement, "Viewport element not provided by the template.") this.gridElement = this.viewportElement.querySelector('.ueb-grid') console.assert(this.gridElement, "Grid element not provided by the template.") - this.selectorElement = this.viewportElement.querySelector('.ueb-selector') - console.assert(this.selectorElement, "Selector element not provided by the template.") + this.selectorElement = new GraphSelector() this.nodesContainerElement = this.querySelector('[data-nodes]') console.assert(this.nodesContainerElement, "Nodes container element not provided by the template.") + this.nodesContainerElement.append(this.selectorElement) this.insertChildren() this.dragObject = new DragScroll(this.getGridDOMElement(), this, { @@ -290,38 +286,6 @@ export default class UEBlueprint extends GraphEntity { return position } - /** - * Create a selection rectangle starting from the specified position - * @param {number[]} initialPosition - Selection rectangle initial position (relative to the .ueb-grid element) - */ - startSelecting(initialPosition) { - initialPosition = this.compensateTranslation(initialPosition) - // Set initial position - this.selectorElement.style.setProperty('--ueb-select-from-x', initialPosition[0]) - this.selectorElement.style.setProperty('--ueb-select-from-y', initialPosition[1]) - // Final position coincide with the initial position, at the beginning of selection - this.selectorElement.style.setProperty('--ueb-select-to-x', initialPosition[0]) - this.selectorElement.style.setProperty('--ueb-select-to-y', initialPosition[1]) - this.selectorElement.dataset.selecting = "true" - this.selectionModel = new FastSelectionModel(initialPosition, this.nodes, this.nodeBoundariesSupplier, this.nodeSelectToggleFunction) - } - - finishSelecting() { - this.selectorElement.dataset.selecting = "false" - this.selectionModel = null - } - - /** - * Move selection rectagle to the specified final position. The initial position was specified by startSelecting() - * @param {number[]} finalPosition - Selection rectangle final position (relative to the .ueb-grid element) - */ - doSelecting(finalPosition) { - finalPosition = this.compensateTranslation(finalPosition) - this.selectorElement.style.setProperty('--ueb-select-to-x', finalPosition[0]) - this.selectorElement.style.setProperty('--ueb-select-to-y', finalPosition[1]) - this.selectionModel.selectTo(finalPosition) - } - /** * Unselect all nodes */ @@ -331,7 +295,7 @@ export default class UEBlueprint extends GraphEntity { /** * - * @param {...GrapNode} blueprintNodes + * @param {...GraphNode} blueprintNodes */ addNode(...blueprintNodes) { [...blueprintNodes].reduce( diff --git a/js/input/Select.js b/js/input/Select.js index 28c7891..5011b84 100644 --- a/js/input/Select.js +++ b/js/input/Select.js @@ -6,19 +6,20 @@ export default class Select extends MouseClickDrag { super(target, blueprint, options) this.stepSize = options?.stepSize this.mousePosition = [0, 0] + this.selectorElement = this.blueprint.selectorElement } startDrag() { - this.blueprint.startSelecting(this.clickedPosition) + this.selectorElement.startSelecting(this.clickedPosition) } dragTo(location, movement) { - this.blueprint.doSelecting(location) + this.selectorElement.doSelecting(location) } endDrag() { if (this.started) { - this.blueprint.finishSelecting() + this.selectorElement.finishSelecting() } else { this.blueprint.unselectAll() } diff --git a/js/template/BlueprintTemplate.js b/js/template/BlueprintTemplate.js index 2be497a..2b98a2e 100644 --- a/js/template/BlueprintTemplate.js +++ b/js/template/BlueprintTemplate.js @@ -25,9 +25,7 @@ export default class BlueprintTemplate extends Template {
` diff --git a/js/template/Template.js b/js/template/Template.js index d5689d3..5da40b9 100644 --- a/js/template/Template.js +++ b/js/template/Template.js @@ -1,8 +1,11 @@ +/** + * @typedef {import("./GraphNode").default} GraphNode + */ export default class Template { /** * Computes the html content of the target element. - * @param {HTMLElement} element Target element + * @param {GraphNode} element Target element * @returns The computed html */ render(element) { @@ -11,7 +14,7 @@ export default class Template { /** * Returns the html elements rendered by this template. - * @param {HTMLElement} element Target element + * @param {GraphNode} element Target element * @returns The rendered elements */ getElements(element) { diff --git a/ueblueprint.html b/ueblueprint.html index 0c0e1c7..08da7b9 100644 --- a/ueblueprint.html +++ b/ueblueprint.html @@ -20,9 +20,6 @@ let node0 = new GraphNode(); node0.setLocation([985, 393]); let node1 = new GraphNode(); node1.setLocation([999, 114]); let node2 = new GraphNode(); node2.setLocation([811, 253]); let node3 = new GraphNode(); node3.setLocation([802, 146]); let node4 = new GraphNode(); node4.setLocation([597, 105]); let node5 = new GraphNode(); node5.setLocation([789, 233]); let node6 = new GraphNode(); node6.setLocation([549, 289]); let node7 = new GraphNode(); node7.setLocation([678, 193]); let node8 = new GraphNode(); node8.setLocation([1078, 244]); let node9 = new GraphNode(); node9.setLocation([751, 151]); let node10 = new GraphNode(); node10.setLocation([1046, -14]); let node11 = new GraphNode(); node11.setLocation([714, 267]); let node12 = new GraphNode(); node12.setLocation([767, 36]); let node13 = new GraphNode(); node13.setLocation([807, 219]); let node14 = new GraphNode(); node14.setLocation([1031, 70]); let node15 = new GraphNode(); node15.setLocation([906, 389]); let node16 = new GraphNode(); node16.setLocation([936, 131]); let node17 = new GraphNode(); node17.setLocation([689, 249]); let node18 = new GraphNode(); node18.setLocation([1153, 343]); let node19 = new GraphNode(); node19.setLocation([626, 209]); blueprint.addNode(node0, node1, node2, node3, node4, node5, node6, node7, node8, node9, node10, node11, node12, node13, node14, node15, node16, node17, node18, node19); document.querySelector('body').appendChild(blueprint) - let Pin = new GraphPin() - let a = Pin.serialize() - let c = "ciao"