commit a3f7e11caf8e385e8bda0557f584e810014288cd
parent b20cceac1e920e3729aae9ad1f30beb7c49112fb
Author: Jacob R. Edwards <jacob@jacobedwards.org>
Date: Thu, 17 Oct 2024 11:59:06 -0700
Add easier multi-selection
There is now a selectionBoxHandler which will select everything
within the box from where you press to where you release.
(This practically required the last change to function; it wouldn't
be able to co-exist with panning and zooming otherwise.)
Diffstat:
1 file changed, 97 insertions(+), 1 deletion(-)
diff --git a/files/floorplans/floorplan/main.js b/files/floorplans/floorplan/main.js
@@ -48,7 +48,11 @@ const modes = {
points: true,
handlers: {
contextmenu: preventDefaultHandler,
- pointerdown: selectionHandler,
+ pointerdown: [singlePointerHandler, selectionHandler, selectionBoxHandler],
+ pointermove: [singlePointerHandler, selectionBoxHandler],
+ pointerup: [singlePointerHandler, selectionBoxHandler],
+ pointercancel: [singlePointerHandler, selectionBoxHandler],
+ keydown: keyHandler,
keydown: keyHandler,
select: selectHandler,
reselect: selectHandler
@@ -572,6 +576,90 @@ function selectionHandler(event, editor) {
}
}
+// pointerdown, pointercancel, pointermove, pointerup
+function selectionBoxHandler(ev, editor, state) {
+ const cleanup = function() {
+ if (state.rect) {
+ state.rect.remove()
+ }
+ for (let k in state) {
+ delete state[k]
+ }
+ }
+ const useEv = function(ev) {
+ if (ev.pointerType === "mouse") {
+ if (ev.type === "pointermove") {
+ return true
+ }
+ return !primaryPointer(ev)
+ } else {
+ return primaryPointer(ev)
+ }
+ }
+
+ if (ev.type === "pointercancel") {
+ cleanup()
+ return
+ }
+
+ if (ev.type === "pointerdown" && useEv(ev)) {
+ handled(ev)
+ let p = editor.draw.point(ev.clientX, ev.clientY)
+ if (state.rect) {
+ console.error("selectionBoxHandler state got messed up")
+ cleanup()
+ }
+ state.origin = structuredClone(p)
+ state.rect = editor.ui.top.rect(0, 0)
+ .move(p.x, p.y)
+ .stroke({ width: 50, dasharray: [350, 350], color: "blue" })
+ .fill("rgba(0,0,1,.025)")
+ return
+ }
+
+ if (!state.rect) {
+ return
+ }
+
+ let p = editor.draw.point(ev.clientX, ev.clientY)
+ if (ev.type === "pointermove" && useEv(ev)) {
+ handled(ev)
+ let params = {}
+ if (state.origin.x > p.x) {
+ params.x = p.x
+ params.width = state.origin.x - p.x
+ } else {
+ params.x = state.origin.x
+ params.width = p.x - state.origin.x
+ }
+ if (state.origin.y > p.y) {
+ params.y = p.y
+ params.height = state.origin.y - p.y
+ } else {
+ params.y = state.origin.y
+ params.height = p.y - state.origin.y
+ }
+ state.rect.move(params.x, params.y).size(params.width, params.height)
+ } else if (ev.type === "pointerup" && useEv(ev)) {
+ handled(ev)
+ let objects = editor.draw.find("#floorplan > :not(#furniture_layouts, #door_swings) > *, #furniture_layouts > * > *")
+ let s = state.rect.rbox(state.rect.root())
+ let selection = []
+ objects.each(function() {
+ let b = this.rbox(this.root())
+ if (((b.x >= s.x && b.x <= s.x2) || (b.x2 >= s.x && b.x2 <= s.x2)) &&
+ ((b.y >= s.y && b.y <= s.y2) || (b.y2 >= s.y && b.y2 <= s.y2))) {
+ selection.push(this)
+ }
+
+ })
+ if (selection.length > 0) {
+ addSelection(editor, selection).selectList()
+ }
+ cleanup()
+ }
+}
+
function keyHandler(ev, editor) {
if (ev.key === "Escape") {
escape()
@@ -1613,6 +1701,14 @@ function escape() {
})
}
+function primaryPointer(ev) {
+ if (ev.type === "pointermove") {
+ return primaryMove(ev)
+ } else {
+ return truelyPrimary(ev)
+ }
+}
+
function truelyPrimary(ev) {
if (ev.pointerType === "mouse") {
return ev.button === buttons.left