Selection fixed, SimpleSelectionModel added

This commit is contained in:
barsdeveloper
2021-10-03 00:41:25 +02:00
parent 44355afa3e
commit dbff7a2c5f
7 changed files with 219 additions and 69 deletions

View File

@@ -1,6 +1,6 @@
import OrderedIndexArray from "./OrderedIndexArray.js" import OrderedIndexArray from "./OrderedIndexArray.js"
export default class SelectionModel { export default class FastSelectionModel {
/** /**
* @typedef {{ * @typedef {{
@@ -31,6 +31,8 @@ export default class SelectionModel {
this.secondaryOrder = new OrderedIndexArray((element) => this.metadata[element].secondaryBoundary) this.secondaryOrder = new OrderedIndexArray((element) => this.metadata[element].secondaryBoundary)
this.selectToggleFunction = selectToggleFunction this.selectToggleFunction = selectToggleFunction
this.rectangles = rectangles this.rectangles = rectangles
this.primaryOrder.reserve(this.rectangles.length)
this.secondaryOrder.reserve(this.rectangles.length)
rectangles.forEach((rect, index) => { rectangles.forEach((rect, index) => {
/** @type Metadata */ /** @type Metadata */
let rectangleMetadata = { let rectangleMetadata = {
@@ -42,6 +44,16 @@ export default class SelectionModel {
this.metadata[index] = rectangleMetadata this.metadata[index] = rectangleMetadata
selectToggleFunction(rect, false) // Initially deselected (Eventually) selectToggleFunction(rect, false) // Initially deselected (Eventually)
const rectangleBoundaries = boundariesFunc(rect) const rectangleBoundaries = boundariesFunc(rect)
// Secondary axis first because it may be inserted in this.secondaryOrder during the primary axis check
if (this.initialPosition[1] < rectangleBoundaries.secondaryInf) { // Initial position is before the rectangle
rectangleMetadata.secondaryBoundary = rectangleBoundaries.secondaryInf
} else if (rectangleBoundaries.secondarySup < this.initialPosition[1]) { // Initial position is after the rectangle
rectangleMetadata.secondaryBoundary = rectangleBoundaries.secondarySup
} else {
rectangleMetadata.onSecondaryAxis = true
}
if (this.initialPosition[0] < rectangleBoundaries.primaryInf) { // Initial position is before the rectangle if (this.initialPosition[0] < rectangleBoundaries.primaryInf) { // Initial position is before the rectangle
rectangleMetadata.primaryBoundary = rectangleBoundaries.primaryInf rectangleMetadata.primaryBoundary = rectangleBoundaries.primaryInf
this.primaryOrder.insert(index) this.primaryOrder.insert(index)
@@ -56,13 +68,6 @@ export default class SelectionModel {
selectToggleFunction(rect, true) selectToggleFunction(rect, true)
} }
} }
if (this.initialPosition[1] < rectangleBoundaries.secondaryInf) { // Initial position is before the rectangle
rectangleMetadata.secondaryBoundary = rectangleBoundaries.secondaryInf
} else if (rectangleBoundaries.secondarySup < this.initialPosition[1]) { // Initial position is after the rectangle
rectangleMetadata.secondaryBoundary = rectangleBoundaries.secondarySup
} else {
rectangleMetadata.onSecondaryAxis = true
}
}) })
this.primaryOrder.currentPosition = this.primaryOrder.getPosition(this.initialPosition[0]) this.primaryOrder.currentPosition = this.primaryOrder.getPosition(this.initialPosition[0])
this.secondaryOrder.currentPosition = this.secondaryOrder.getPosition(this.initialPosition[1]) this.secondaryOrder.currentPosition = this.secondaryOrder.getPosition(this.initialPosition[1])
@@ -98,12 +103,11 @@ export default class SelectionModel {
Math.sign(finalPosition[0] - this.initialPosition[0]), Math.sign(finalPosition[0] - this.initialPosition[0]),
Math.sign(finalPosition[1] - this.initialPosition[1]) Math.sign(finalPosition[1] - this.initialPosition[1])
] ]
const primaryBoundaryCrossed = (index, expanding) => { const primaryBoundaryCrossed = (index, added) => {
this.primaryOrder.currentPosition += direction[0] * (expanding ? 1 : -1)
if (this.metadata[index].onSecondaryAxis) { if (this.metadata[index].onSecondaryAxis) {
this.selectToggleFunction(this.rectangles[index], expanding) this.selectToggleFunction(this.rectangles[index], added)
} else { } else {
if (expanding) { if (added) {
this.secondaryOrder.insert(index, finalPosition[1]) this.secondaryOrder.insert(index, finalPosition[1])
const secondaryBoundary = this.metadata[index].secondaryBoundary const secondaryBoundary = this.metadata[index].secondaryBoundary
if ( if (
@@ -125,23 +129,34 @@ export default class SelectionModel {
} }
if (finalPosition[0] < this.boundaries.primaryN.value) { if (finalPosition[0] < this.boundaries.primaryN.value) {
primaryBoundaryCrossed(this.boundaries.primaryN.index, finalPosition[0] < this.initialPosition[0]) --this.primaryOrder.currentPosition
primaryBoundaryCrossed(
this.boundaries.primaryN.index,
this.initialPosition[0] > this.boundaries.primaryN.value && finalPosition[0] < this.initialPosition[0])
} else if (finalPosition[0] > this.boundaries.primaryP.value) { } else if (finalPosition[0] > this.boundaries.primaryP.value) {
primaryBoundaryCrossed(this.boundaries.primaryP.index, this.initialPosition[0] < finalPosition[0]) ++this.primaryOrder.currentPosition
primaryBoundaryCrossed(
this.boundaries.primaryP.index,
this.initialPosition[0] < this.boundaries.primaryP.value && this.initialPosition[0] < finalPosition[0])
} }
const secondaryBoundaryCrossed = (index, expanding) => { const secondaryBoundaryCrossed = (index, added) => {
this.secondaryOrder.currentPosition += direction[1] * (expanding ? 1 : -1) this.selectToggleFunction(this.rectangles[index], added)
this.selectToggleFunction(this.rectangles[index], expanding)
this.computeBoundaries(finalPosition) this.computeBoundaries(finalPosition)
this.selectTo(finalPosition) this.selectTo(finalPosition)
} }
if (finalPosition[1] < this.boundaries.secondaryN.value) { if (finalPosition[1] < this.boundaries.secondaryN.value) {
secondaryBoundaryCrossed(this.boundaries.secondaryN.index, finalPosition[1] < this.initialPosition[1]); --this.secondaryOrder.currentPosition
secondaryBoundaryCrossed(
this.boundaries.secondaryN.index,
this.initialPosition[1] > this.boundaries.secondaryN.value && finalPosition[1] < this.initialPosition[1]);
} else if (finalPosition[1] > this.boundaries.secondaryP.value) { } else if (finalPosition[1] > this.boundaries.secondaryP.value) {
secondaryBoundaryCrossed(this.boundaries.secondaryP.index, this.initialPosition[1] < finalPosition[1]); ++this.secondaryOrder.currentPosition
secondaryBoundaryCrossed(
this.boundaries.secondaryP.index,
this.initialPosition[1] < this.boundaries.secondaryP.value && this.initialPosition[1] < finalPosition[1]);
} }
this.finalPosition = finalPosition this.finalPosition = finalPosition
} }

View File

@@ -17,7 +17,10 @@ export default class OrderedIndexArray {
* @returns The element of the array * @returns The element of the array
*/ */
get(index) { get(index) {
return this.array[index] if (index >= 0 && index < this.length) {
return this.array[index]
}
return null
} }
/** /**
@@ -35,7 +38,7 @@ export default class OrderedIndexArray {
*/ */
getPosition(value) { getPosition(value) {
let l = 0 let l = 0
let r = this.array.length let r = this.length
while (l < r) { while (l < r) {
let m = Math.floor((l + r) / 2) let m = Math.floor((l + r) / 2)
if (this.comparisonValueSupplier(this.array[m]) < value) { if (this.comparisonValueSupplier(this.array[m]) < value) {
@@ -47,24 +50,46 @@ export default class OrderedIndexArray {
return l return l
} }
reserve(length) {
if (this.array.length < length) {
let newArray = new Uint32Array(length)
newArray.set(this.array)
this.array = newArray
}
}
/** /**
* Inserts the element in the array. * Inserts the element in the array.
* @param element {number} The value to insert into the array. * @param element {number} The value to insert into the array.
* @returns {number} The position into occupied by value into the array. * @returns {number} The position into occupied by value into the array.
*/ */
insert(element, comparisonValue = null) { insert(element, comparisonValue = null) {
let i = 0;
for (i = 0; i < this.length; ++i) {
if (element == this.array[i]) {
console.log("error");
break;
}
}
let position = this.getPosition(this.comparisonValueSupplier(element)) let position = this.getPosition(this.comparisonValueSupplier(element))
if ( if (
position < this.currentPosition position < this.currentPosition
|| comparisonValue != null && position == this.currentPosition && this.comparisonValueSupplier(element) < comparisonValue) { || comparisonValue != null && position == this.currentPosition && this.comparisonValueSupplier(element) < comparisonValue) {
++this.currentPosition ++this.currentPosition
} }
/*
let newArray = new Uint32Array(this.array.length + 1) let newArray = new Uint32Array(this.array.length + 1)
newArray.set(this.array.subarray(0, position), 0) newArray.set(this.array.subarray(0, position), 0)
newArray[position] = element newArray[position] = element
newArray.set(this.array.subarray(position), position + 1) newArray.set(this.array.subarray(position), position + 1)
this.array = newArray this.array = newArray
this.length = this.array.length */
this.shiftRight(position)
this.array[position] = element
++this.length
if (this.length > this.array.length) {
console.log("error2")
}
return position return position
} }
@@ -87,23 +112,26 @@ export default class OrderedIndexArray {
if (position < this.currentPosition) { if (position < this.currentPosition) {
--this.currentPosition --this.currentPosition
} }
/*
let newArray = new Uint32Array(this.array.length - 1) let newArray = new Uint32Array(this.array.length - 1)
newArray.set(this.array.subarray(0, position), 0) newArray.set(this.array.subarray(0, position), 0)
newArray.set(this.array.subarray(position + 1), position) newArray.set(this.array.subarray(position + 1), position)
this.array = newArray this.array = newArray
this.length = this.array.length */
this.shiftLeft(position)
--this.length
return position return position
} }
getNext() { getNext() {
if (this.currentPosition >= 0 && this.currentPosition < this.array.length) { if (this.currentPosition >= 0 && this.currentPosition < this.length) {
return this.get(this.currentPosition) return this.get(this.currentPosition)
} }
return null return null
} }
getNextValue() { getNextValue() {
if (this.currentPosition >= 0 && this.currentPosition < this.array.length) { if (this.currentPosition >= 0 && this.currentPosition < this.length) {
return this.comparisonValueSupplier(this.get(this.currentPosition)) return this.comparisonValueSupplier(this.get(this.currentPosition))
} else { } else {
return Number.MAX_SAFE_INTEGER return Number.MAX_SAFE_INTEGER
@@ -124,4 +152,12 @@ export default class OrderedIndexArray {
return Number.MIN_SAFE_INTEGER return Number.MIN_SAFE_INTEGER
} }
} }
shiftLeft(leftLimit, steps = 1) {
this.array.set(this.array.subarray(leftLimit + steps), leftLimit)
}
shiftRight(leftLimit, steps = 1) {
this.array.set(this.array.subarray(leftLimit, -steps), leftLimit + steps)
}
} }

View File

@@ -0,0 +1,44 @@
export default class SimpleSelectionModel {
/**
* @typedef {{
* primaryInf: number,
* primarySup: number,
* secondaryInf: number,
* secondarySup: number
* }} BoundariesInfo
* @typedef {numeric} Rectangle
* @param {number[]} initialPosition Coordinates of the starting point of selection [primaryAxisValue, secondaryAxisValue].
* @param {Rectangle[]} rectangles Rectangles that can be selected by this object.
* @param {(rect: Rectangle) => BoundariesInfo} boundariesFunc A function that, given a rectangle, it provides the boundaries of such rectangle.
* @param {(rect: Rectangle, selected: bool) => void} selectToggleFunction A function that selects or deselects individual rectangles.
*/
constructor(initialPosition, rectangles, boundariesFunc, selectToggleFunction) {
this.initialPosition = initialPosition
this.finalPosition = initialPosition
this.boundariesFunc = boundariesFunc
this.selectToggleFunction = selectToggleFunction
this.rectangles = rectangles
}
selectTo(finalPosition) {
let primaryInf = Math.min(finalPosition[0], this.initialPosition[0])
let primarySup = Math.max(finalPosition[0], this.initialPosition[0])
let secondaryInf = Math.min(finalPosition[1], this.initialPosition[1])
let secondarySup = Math.max(finalPosition[1], this.initialPosition[1])
this.finalPosition = finalPosition
this.rectangles.forEach(rect => {
let boundaries = this.boundariesFunc(rect)
if (
Math.max(boundaries.primaryInf, primaryInf) < Math.min(boundaries.primarySup, primarySup)
&& Math.max(boundaries.secondaryInf, secondaryInf) < Math.min(boundaries.secondarySup, secondarySup)
) {
this.selectToggleFunction(rect, true)
} else {
this.selectToggleFunction(rect, false)
}
})
}
}

View File

@@ -1,7 +1,8 @@
import Utility from "./Utility.js" import Utility from "./Utility.js"
import UEBlueprintDragScroll from "./UEBlueprintDragScroll.js" import UEBlueprintDragScroll from "./UEBlueprintDragScroll.js"
import UEBlueprintSelect from "./UEBlueprintSelect.js" import UEBlueprintSelect from "./UEBlueprintSelect.js"
import SelectionModel from "./SelectionModel.js" import FastSelectionModel from "./FastSelectionModel.js"
import SimpleSelectionModel from "./SimpleSelectionModel.js"
/** /**
* @typedef {import("./UEBlueprintObject.js").default} UEBlueprintObject * @typedef {import("./UEBlueprintObject.js").default} UEBlueprintObject
@@ -72,7 +73,7 @@ export default class UEBlueprint extends HTMLElement {
this.zoom = 0 this.zoom = 0
/** @type {HTMLElement} */ /** @type {HTMLElement} */
this.headerElement = null this.headerElement = null
/** @type {SelectionModel} */ /** @type {FastSelectionModel} */
this.selectionModel = null this.selectionModel = null
/** @type {(node: UEBlueprintObject) => BoundariesInfo} */ /** @type {(node: UEBlueprintObject) => BoundariesInfo} */
this.nodeBoundariesSupplier = (node) => { this.nodeBoundariesSupplier = (node) => {
@@ -336,7 +337,7 @@ export default class UEBlueprint extends HTMLElement {
this.selectorElement.style.setProperty('--ueb-select-to-x', initialPosition[0]) this.selectorElement.style.setProperty('--ueb-select-to-x', initialPosition[0])
this.selectorElement.style.setProperty('--ueb-select-to-y', initialPosition[1]) this.selectorElement.style.setProperty('--ueb-select-to-y', initialPosition[1])
this.selectorElement.dataset.selecting = "true" this.selectorElement.dataset.selecting = "true"
this.selectionModel = new SelectionModel(initialPosition, this.nodes, this.nodeBoundariesSupplier, this.nodeSelectToggleFunction) this.selectionModel = new FastSelectionModel(initialPosition, this.nodes, this.nodeBoundariesSupplier, this.nodeSelectToggleFunction)
} }
finishSelecting() { finishSelecting() {

View File

@@ -96,6 +96,9 @@ export default class UEBlueprintObject extends UEBlueprintDraggableObject {
} }
setSelected(value = true) { setSelected(value = true) {
if (this.selected == value) {
return
}
this.selected = value this.selected = value
if (value) { if (value) {
this.classList.add('ueb-selected') this.classList.add('ueb-selected')

File diff suppressed because one or more lines are too long

View File

@@ -190,7 +190,10 @@ class OrderedIndexArray {
* @returns The element of the array * @returns The element of the array
*/ */
get(index) { get(index) {
return this.array[index] if (index >= 0 && index < this.length) {
return this.array[index]
}
return null
} }
/** /**
@@ -208,7 +211,7 @@ class OrderedIndexArray {
*/ */
getPosition(value) { getPosition(value) {
let l = 0; let l = 0;
let r = this.array.length; let r = this.length;
while (l < r) { while (l < r) {
let m = Math.floor((l + r) / 2); let m = Math.floor((l + r) / 2);
if (this.comparisonValueSupplier(this.array[m]) < value) { if (this.comparisonValueSupplier(this.array[m]) < value) {
@@ -220,24 +223,46 @@ class OrderedIndexArray {
return l return l
} }
reserve(length) {
if (this.array.length < length) {
let newArray = new Uint32Array(length);
newArray.set(this.array);
this.array = newArray;
}
}
/** /**
* Inserts the element in the array. * Inserts the element in the array.
* @param element {number} The value to insert into the array. * @param element {number} The value to insert into the array.
* @returns {number} The position into occupied by value into the array. * @returns {number} The position into occupied by value into the array.
*/ */
insert(element, comparisonValue = null) { insert(element, comparisonValue = null) {
let i = 0;
for (i = 0; i < this.length; ++i) {
if (element == this.array[i]) {
console.log("error");
break;
}
}
let position = this.getPosition(this.comparisonValueSupplier(element)); let position = this.getPosition(this.comparisonValueSupplier(element));
if ( if (
position < this.currentPosition position < this.currentPosition
|| comparisonValue != null && position == this.currentPosition && this.comparisonValueSupplier(element) < comparisonValue) { || comparisonValue != null && position == this.currentPosition && this.comparisonValueSupplier(element) < comparisonValue) {
++this.currentPosition; ++this.currentPosition;
} }
let newArray = new Uint32Array(this.array.length + 1); /*
newArray.set(this.array.subarray(0, position), 0); let newArray = new Uint32Array(this.array.length + 1)
newArray[position] = element; newArray.set(this.array.subarray(0, position), 0)
newArray.set(this.array.subarray(position), position + 1); newArray[position] = element
this.array = newArray; newArray.set(this.array.subarray(position), position + 1)
this.length = this.array.length; this.array = newArray
*/
this.shiftRight(position);
this.array[position] = element;
++this.length;
if (this.length > this.array.length) {
console.log("error2");
}
return position return position
} }
@@ -260,23 +285,26 @@ class OrderedIndexArray {
if (position < this.currentPosition) { if (position < this.currentPosition) {
--this.currentPosition; --this.currentPosition;
} }
let newArray = new Uint32Array(this.array.length - 1); /*
newArray.set(this.array.subarray(0, position), 0); let newArray = new Uint32Array(this.array.length - 1)
newArray.set(this.array.subarray(position + 1), position); newArray.set(this.array.subarray(0, position), 0)
this.array = newArray; newArray.set(this.array.subarray(position + 1), position)
this.length = this.array.length; this.array = newArray
*/
this.shiftLeft(position);
--this.length;
return position return position
} }
getNext() { getNext() {
if (this.currentPosition >= 0 && this.currentPosition < this.array.length) { if (this.currentPosition >= 0 && this.currentPosition < this.length) {
return this.get(this.currentPosition) return this.get(this.currentPosition)
} }
return null return null
} }
getNextValue() { getNextValue() {
if (this.currentPosition >= 0 && this.currentPosition < this.array.length) { if (this.currentPosition >= 0 && this.currentPosition < this.length) {
return this.comparisonValueSupplier(this.get(this.currentPosition)) return this.comparisonValueSupplier(this.get(this.currentPosition))
} else { } else {
return Number.MAX_SAFE_INTEGER return Number.MAX_SAFE_INTEGER
@@ -297,9 +325,17 @@ class OrderedIndexArray {
return Number.MIN_SAFE_INTEGER return Number.MIN_SAFE_INTEGER
} }
} }
shiftLeft(leftLimit, steps = 1) {
this.array.set(this.array.subarray(leftLimit + steps), leftLimit);
}
shiftRight(leftLimit, steps = 1) {
this.array.set(this.array.subarray(leftLimit, -steps), leftLimit + steps);
}
} }
class SelectionModel { class FastSelectionModel {
/** /**
* @typedef {{ * @typedef {{
@@ -330,6 +366,8 @@ class SelectionModel {
this.secondaryOrder = new OrderedIndexArray((element) => this.metadata[element].secondaryBoundary); this.secondaryOrder = new OrderedIndexArray((element) => this.metadata[element].secondaryBoundary);
this.selectToggleFunction = selectToggleFunction; this.selectToggleFunction = selectToggleFunction;
this.rectangles = rectangles; this.rectangles = rectangles;
this.primaryOrder.reserve(this.rectangles.length);
this.secondaryOrder.reserve(this.rectangles.length);
rectangles.forEach((rect, index) => { rectangles.forEach((rect, index) => {
/** @type Metadata */ /** @type Metadata */
let rectangleMetadata = { let rectangleMetadata = {
@@ -341,6 +379,16 @@ class SelectionModel {
this.metadata[index] = rectangleMetadata; this.metadata[index] = rectangleMetadata;
selectToggleFunction(rect, false); // Initially deselected (Eventually) selectToggleFunction(rect, false); // Initially deselected (Eventually)
const rectangleBoundaries = boundariesFunc(rect); const rectangleBoundaries = boundariesFunc(rect);
// Secondary axis first because it may be inserted in this.secondaryOrder during the primary axis check
if (this.initialPosition[1] < rectangleBoundaries.secondaryInf) { // Initial position is before the rectangle
rectangleMetadata.secondaryBoundary = rectangleBoundaries.secondaryInf;
} else if (rectangleBoundaries.secondarySup < this.initialPosition[1]) { // Initial position is after the rectangle
rectangleMetadata.secondaryBoundary = rectangleBoundaries.secondarySup;
} else {
rectangleMetadata.onSecondaryAxis = true;
}
if (this.initialPosition[0] < rectangleBoundaries.primaryInf) { // Initial position is before the rectangle if (this.initialPosition[0] < rectangleBoundaries.primaryInf) { // Initial position is before the rectangle
rectangleMetadata.primaryBoundary = rectangleBoundaries.primaryInf; rectangleMetadata.primaryBoundary = rectangleBoundaries.primaryInf;
this.primaryOrder.insert(index); this.primaryOrder.insert(index);
@@ -355,13 +403,6 @@ class SelectionModel {
selectToggleFunction(rect, true); selectToggleFunction(rect, true);
} }
} }
if (this.initialPosition[1] < rectangleBoundaries.secondaryInf) { // Initial position is before the rectangle
rectangleMetadata.secondaryBoundary = rectangleBoundaries.secondaryInf;
} else if (rectangleBoundaries.secondarySup < this.initialPosition[1]) { // Initial position is after the rectangle
rectangleMetadata.secondaryBoundary = rectangleBoundaries.secondarySup;
} else {
rectangleMetadata.onSecondaryAxis = true;
}
}); });
this.primaryOrder.currentPosition = this.primaryOrder.getPosition(this.initialPosition[0]); this.primaryOrder.currentPosition = this.primaryOrder.getPosition(this.initialPosition[0]);
this.secondaryOrder.currentPosition = this.secondaryOrder.getPosition(this.initialPosition[1]); this.secondaryOrder.currentPosition = this.secondaryOrder.getPosition(this.initialPosition[1]);
@@ -397,12 +438,11 @@ class SelectionModel {
Math.sign(finalPosition[0] - this.initialPosition[0]), Math.sign(finalPosition[0] - this.initialPosition[0]),
Math.sign(finalPosition[1] - this.initialPosition[1]) Math.sign(finalPosition[1] - this.initialPosition[1])
]; ];
const primaryBoundaryCrossed = (index, expanding) => { const primaryBoundaryCrossed = (index, added) => {
this.primaryOrder.currentPosition += direction[0] * (expanding ? 1 : -1);
if (this.metadata[index].onSecondaryAxis) { if (this.metadata[index].onSecondaryAxis) {
this.selectToggleFunction(this.rectangles[index], expanding); this.selectToggleFunction(this.rectangles[index], added);
} else { } else {
if (expanding) { if (added) {
this.secondaryOrder.insert(index, finalPosition[1]); this.secondaryOrder.insert(index, finalPosition[1]);
const secondaryBoundary = this.metadata[index].secondaryBoundary; const secondaryBoundary = this.metadata[index].secondaryBoundary;
if ( if (
@@ -424,23 +464,34 @@ class SelectionModel {
}; };
if (finalPosition[0] < this.boundaries.primaryN.value) { if (finalPosition[0] < this.boundaries.primaryN.value) {
primaryBoundaryCrossed(this.boundaries.primaryN.index, finalPosition[0] < this.initialPosition[0]); --this.primaryOrder.currentPosition;
primaryBoundaryCrossed(
this.boundaries.primaryN.index,
this.initialPosition[0] > this.boundaries.primaryN.value && finalPosition[0] < this.initialPosition[0]);
} else if (finalPosition[0] > this.boundaries.primaryP.value) { } else if (finalPosition[0] > this.boundaries.primaryP.value) {
primaryBoundaryCrossed(this.boundaries.primaryP.index, this.initialPosition[0] < finalPosition[0]); ++this.primaryOrder.currentPosition;
primaryBoundaryCrossed(
this.boundaries.primaryP.index,
this.initialPosition[0] < this.boundaries.primaryP.value && this.initialPosition[0] < finalPosition[0]);
} }
const secondaryBoundaryCrossed = (index, expanding) => { const secondaryBoundaryCrossed = (index, added) => {
this.secondaryOrder.currentPosition += direction[1] * (expanding ? 1 : -1); this.selectToggleFunction(this.rectangles[index], added);
this.selectToggleFunction(this.rectangles[index], expanding);
this.computeBoundaries(finalPosition); this.computeBoundaries(finalPosition);
this.selectTo(finalPosition); this.selectTo(finalPosition);
}; };
if (finalPosition[1] < this.boundaries.secondaryN.value) { if (finalPosition[1] < this.boundaries.secondaryN.value) {
secondaryBoundaryCrossed(this.boundaries.secondaryN.index, finalPosition[1] < this.initialPosition[1]); --this.secondaryOrder.currentPosition;
secondaryBoundaryCrossed(
this.boundaries.secondaryN.index,
this.initialPosition[1] > this.boundaries.secondaryN.value && finalPosition[1] < this.initialPosition[1]);
} else if (finalPosition[1] > this.boundaries.secondaryP.value) { } else if (finalPosition[1] > this.boundaries.secondaryP.value) {
secondaryBoundaryCrossed(this.boundaries.secondaryP.index, this.initialPosition[1] < finalPosition[1]); ++this.secondaryOrder.currentPosition;
secondaryBoundaryCrossed(
this.boundaries.secondaryP.index,
this.initialPosition[1] < this.boundaries.secondaryP.value && this.initialPosition[1] < finalPosition[1]);
} }
this.finalPosition = finalPosition; this.finalPosition = finalPosition;
} }
@@ -516,7 +567,7 @@ class UEBlueprint extends HTMLElement {
this.zoom = 0; this.zoom = 0;
/** @type {HTMLElement} */ /** @type {HTMLElement} */
this.headerElement = null; this.headerElement = null;
/** @type {SelectionModel} */ /** @type {FastSelectionModel} */
this.selectionModel = null; this.selectionModel = null;
/** @type {(node: UEBlueprintObject) => BoundariesInfo} */ /** @type {(node: UEBlueprintObject) => BoundariesInfo} */
this.nodeBoundariesSupplier = (node) => { this.nodeBoundariesSupplier = (node) => {
@@ -780,7 +831,7 @@ class UEBlueprint extends HTMLElement {
this.selectorElement.style.setProperty('--ueb-select-to-x', initialPosition[0]); this.selectorElement.style.setProperty('--ueb-select-to-x', initialPosition[0]);
this.selectorElement.style.setProperty('--ueb-select-to-y', initialPosition[1]); this.selectorElement.style.setProperty('--ueb-select-to-y', initialPosition[1]);
this.selectorElement.dataset.selecting = "true"; this.selectorElement.dataset.selecting = "true";
this.selectionModel = new SelectionModel(initialPosition, this.nodes, this.nodeBoundariesSupplier, this.nodeSelectToggleFunction); this.selectionModel = new FastSelectionModel(initialPosition, this.nodes, this.nodeBoundariesSupplier, this.nodeSelectToggleFunction);
} }
finishSelecting() { finishSelecting() {
@@ -946,6 +997,9 @@ class UEBlueprintObject extends UEBlueprintDraggableObject {
} }
setSelected(value = true) { setSelected(value = true) {
if (this.selected == value) {
return
}
this.selected = value; this.selected = value;
if (value) { if (value) {
this.classList.add('ueb-selected'); this.classList.add('ueb-selected');