91 lines
2.5 KiB
JavaScript
91 lines
2.5 KiB
JavaScript
import {EVENT_SELECT} from './config.js';
|
|
import {add, copy, mult} from './vector.js';
|
|
|
|
export class Select {
|
|
sim = undefined;
|
|
box = {
|
|
start: undefined,
|
|
end: undefined,
|
|
};
|
|
selectedSingle = undefined;
|
|
selectedGroup = [];
|
|
|
|
constructor(sim) {
|
|
this.sim = sim;
|
|
|
|
// TODO: Move this to a new Keyboard class singleton
|
|
window.addEventListener('keydown', (e) => {
|
|
switch (e.key) {
|
|
case 'Tab': {
|
|
e.preventDefault();
|
|
if (!this.selectedGroup.length) return;
|
|
const currentIdx = this.selectedGroup.indexOf(this.selectedSingle);
|
|
const newIdx = (currentIdx + 1) % this.selectedGroup.length;
|
|
this.selectedSingle = this.selectedGroup[newIdx];
|
|
break;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
handlePointerDown({x: clientX, y: clientY}) {
|
|
this.box.start = this.sim.screenToSim(clientX, clientY);
|
|
this.box.end = this.box.start;
|
|
// this.getSelectedObjects();
|
|
}
|
|
|
|
handlePointerMove({x: clientX, y: clientY}) {
|
|
if (!this.box.start) return;
|
|
this.box.end = this.sim.screenToSim(clientX, clientY);
|
|
}
|
|
|
|
handlePointerUp() {
|
|
if (!this.box.start) return;
|
|
const start = copy(this.box.start);
|
|
const end = copy(this.box.end);
|
|
this.box.start = {
|
|
x: Math.min(start.x, end.x),
|
|
y: Math.min(start.y, end.y),
|
|
};
|
|
this.box.end = {
|
|
x: Math.max(start.x, end.x),
|
|
y: Math.max(start.y, end.y),
|
|
};
|
|
this.getSelectedObjects();
|
|
this.sim.div.dispatchEvent(new CustomEvent(EVENT_SELECT));
|
|
this.box = {
|
|
start: undefined,
|
|
end: undefined,
|
|
};
|
|
}
|
|
|
|
frame(elapsedTime) {
|
|
if (!this.box.start) return;
|
|
// If panning, let's update the position of our box so it doesn't drift away
|
|
const {velocity} = this.sim.panning;
|
|
const delta = mult(velocity, elapsedTime);
|
|
this.box.start = add(this.box.start, delta);
|
|
this.box.end = add(this.box.end, delta);
|
|
// Display the box
|
|
this.sim.display.drawBox(this.box.start, this.box.end);
|
|
}
|
|
|
|
getSelectedObjects() {
|
|
const {start, end} = this.box;
|
|
if (!start) return;
|
|
this.selectedGroup = this.sim.system.filter(({position: {x, y}}) => {
|
|
return x >= start.x && x <= end.x && y >= start.y && y <= end.y;
|
|
});
|
|
// For now, first object in group is selected single
|
|
this.selectedSingle = this.selectedGroup[0] ?? undefined;
|
|
}
|
|
|
|
// cb: ({selectedGroup, selectedSingle}) => undefined
|
|
onSelect(cb) {
|
|
this.sim.div.addEventListener(EVENT_SELECT, () => {
|
|
const {selectedGroup, selectedSingle} = this;
|
|
cb({selectedGroup, selectedSingle});
|
|
});
|
|
}
|
|
}
|