import { group } from '../core/library.js';
import { mergeOver, pushUnique, removeItem, xtGet, Ωempty } from '../helper/utilities.js';
import { releaseArray, requestArray } from '../helper/array-pool.js';This mixin sets up the Scrawl-canvas functionality required to perform its Display cycle.
The mixin also includes code to assist drag-and-drop functionality.
import { group } from '../core/library.js';
import { mergeOver, pushUnique, removeItem, xtGet, Ωempty } from '../helper/utilities.js';
import { releaseArray, requestArray } from '../helper/array-pool.js';Shared constants
import { _floor, REVERSE_BY_DELTA, UPDATE_BY_DELTA } from '../helper/shared-vars.js';Local constants
const ADD_ARTEFACT_CLASSES = 'addArtefactClasses',
REMOVE_ARTEFACT_CLASSES = 'removeArtefactClasses',
SET_ARTEFACTS = 'setArtefacts',
UPDATE_ARTEFACTS = 'updateArtefacts';export default function (P = Ωempty) { const defaultAttributes = {The groups attribute holds the String names of all the Group objects associated with the controller object.
groups: null,The groupBuckets attribute holds a reference to each Group object, in a set of arrays grouping Groups according to their order values.
groupBuckets: null,The batchResort Boolean flag determines whether the Groups will be sorted by their order value before instructions get passed to each in sequence. Best to leave this flag alone to do its job.
batchResort: true,
};
P.defs = mergeOver(P.defs, defaultAttributes); const G = P.getters,
S = P.setters;groups
G.groups = function () {
return [].concat(this.groups);
};Passes the first argument to the addGroups function. Not recommended
S.groups = function (item) {
this.groups.length = 0;
this.addGroups(item);
};sortGroups - internal function - Groups are sorted from the groups Array into the groupBuckets array using a bespoke bucket sort algorithm, based on each Group object’s order attribute
P.sortGroups = function () {
if (this.batchResort) {
this.batchResort = false;
const {groups, groupBuckets} = this;
const buckets = requestArray();
let i, iz, obj, name, order, arr;
for (i = 0, iz = groups.length; i < iz; i++) {
name = groups[i];
obj = group[name];
if (obj) {
order = _floor(obj.order) || 0;
if (!buckets[order]) buckets[order] = requestArray();
buckets[order].push(obj);
}
}
groupBuckets.length = 0;
for (i = 0, iz = buckets.length; i < iz; i++) {
arr = buckets[i];
if (arr) {
groupBuckets.push(...arr);
releaseArray(arr);
}
}
releaseArray(buckets);
}
};initializeCascade - internal function used by factory constructors
P.initializeCascade = function () {
this.groups = [];
this.groupBuckets = [];
};Groups should be added to, and removed from, the controller object using the addGroups and removeGroups functions. The argument can be one or more Group object’s name attribute, or the Group object(s) itself.
addGroups
P.addGroups = function (...args) {
const groups = this.groups;
args.forEach(item => {
if (item.substring) pushUnique(groups, item);
else if (group[item]) pushUnique(groups, item.name);
}, this);
this.batchResort = true;
return this;
};removeGroups
P.removeGroups = function (...args) {
const groups = this.groups;
args.forEach( item => {
if (item.substring) removeItem(groups, item);
else if (group[item]) removeItem(groups, item.name);
}, this);
this.batchResort = true;
return this;
};cascadeAction - internal helper function used by the functions below
P.cascadeAction = function (items, action) {
let g;
this.groups.forEach(name => {
g = group[name];
if (g) g[action](items);
}, this);
return this;
};updateArtefacts - Update all artefact objects in all the controller object’s Groups. The supplied argument will be passed on to each artefact’s setDelta function.
P.updateArtefacts = function (items) {
this.cascadeAction(items, UPDATE_ARTEFACTS);
return this;
};updateArtefacts - Set all artefact objects in all the controller object’s Groups. The supplied argument will be passed on to each artefact’s set functions
P.setArtefacts = function (items) {
this.cascadeAction(items, SET_ARTEFACTS);
return this;
};addArtefactClasses - specific to DOM-related artefacts (Stack, Canvas, Element)
P.addArtefactClasses = function (items) {
this.cascadeAction(items, ADD_ARTEFACT_CLASSES);
return this;
};removeArtefactClasses - specific to DOM-related artefacts (Stack, Canvas, Element)
P.removeArtefactClasses = function (items) {
this.cascadeAction(items, REMOVE_ARTEFACT_CLASSES);
return this;
};updateByDelta - triggers the related artefact function, to update (add) its attributes by values held in its delta object attribute
P.updateByDelta = function () {
this.cascadeAction(false, UPDATE_BY_DELTA);
return this;
};reverseByDelta - triggers the related artefact function, to reverse (subtract) its attributes by values held in its delta object attribute
P.reverseByDelta = function () {
this.cascadeAction(false, REVERSE_BY_DELTA);
return this;
};The getArtefactAt function checks to see if any of the controller object’s Groups’ artefacts are located at the supplied coordinates in the argument object.
P.getArtefactAt = function (items) {
items = xtGet(items, this.here, false);
if (items) {
let g, res;
for (let i = this.groups.length - 1; i >= 0; i--) {
g = group[this.groups[i]];
if (g) {
res = g.getArtefactAt(items);
if (res) return res;
}
}
}
return false;
};The getAllArtefactsAt function returns all of the controller object’s Groups’ artefacts located at the supplied coordinates in the argument object.
P.getAllArtefactsAt = function (items) {
items = xtGet(items, this.here, false);
const results = [];
if (items) {
let g, res;
for (let i = this.groups.length - 1; i >= 0; i--) {
g = group[this.groups[i]];
if (g) {
res = g.getAllArtefactsAt(items);
if (res) results.push(...res);
}
}
}
return results;
};
}