www.spaceplanner.app

Web client to the spaceplanner API
git clone git://jacobedwards.org/www.spaceplanner.app
Log | Files | Refs

commit 90f696680da70f94354591b8b4b9a3c7eedd7ecb
parent 3db7e43dc3a46f84b873095bb12ae534b707ba4d
Author: Jacob R. Edwards <jacob@jacobedwards.org>
Date:   Fri, 23 Aug 2024 14:51:57 -0700

Add handler for removing points

This required a little hack to support alongside the point adding
handler but turned out okay. I have some ideas for how to improve
the whole system in the future to maybe make this easier.

So really what happened was two new handlers were added, and edit
handler (which so far only supports removing points), and a main
point handler which handles executing either add or edit depending
on the state of things.

Diffstat:
Mfiles/floorplans/floorplan/main.js | 133+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
Mfiles/lib/ui.js | 1+
2 files changed, 117 insertions(+), 17 deletions(-)

diff --git a/files/floorplans/floorplan/main.js b/files/floorplans/floorplan/main.js @@ -173,11 +173,12 @@ let modes = { points: true, handlers: { contextmenu: preventDefaultHandler, - mousedown: preciseAddWallHandler, - mousemove: preciseAddWallHandler, - mouseup: preciseAddWallHandler, - keydown: [zoomKeysHandler, undoRedoHandler, preciseAddWallHandler, pointMapTypeHandler], - click: pointMapTypeHandler + mousedown: precisePointHandler, + mousemove: precisePointHandler, + mouseup: precisePointHandler, + keydown: [zoomKeysHandler, undoRedoHandler, precisePointHandler, pointMapTypeHandler], + click: [precisePointHandler, pointMapTypeHandler], + dblclick: precisePointHandler, } } } @@ -342,8 +343,48 @@ function undoRedoHandler(event, editor) { event.preventDefault() } -// mousedown, mousemove, mouseup, keydown -function preciseAddWallHandler(event, editor, state) { +function precisePointHandler(event, editor, state) { + const subs = { + add: preciseAddPointHandler, + edit: preciseEditPointHandler + } + const callSubWithEvent = function(name, event) { + state[name] = state[name] ?? {} + let done = subs[name](event, editor, state[name]) + if (event.type === "cleanup") { + return + } + if (done) { + delete state.handler + } else if (event.defaultPrevented && name !== "add") { + state.handler = name + } + return done + } + const callSub = function(name) { + callSubWithEvent(name, event) + } + const cleanupSub = function(name) { + callSubWithEvent(name, { type: "cleanup" }) + } + + if (state.handler) { + if (callSub(state.handler)) { + callSub("add") + } + } + + callSub("add") + if (event.type === "dblclick" && !event.defaultPrevented) { + callSub("edit") + if (event.defaultPrevented) { + callSubWithEvent("add", { type: "cleanup" }) + } + } +} + +// mousedown, mousemove, mouseup, keydown, dblclick +function preciseAddPointHandler(event, editor, state) { const cleanup = function() { state.line.remove() state.point.remove() @@ -379,23 +420,28 @@ function preciseAddWallHandler(event, editor, state) { editor.finishAction() } + if (event.type === "cleanup") { + if (state.point) { + cleanup() + } + return + } + if (!event.key && event.button !== buttons.left) { return } let p = editor.draw.point(event.clientX, event.clientY).vec() + if (event.type === "dblclick") { + if (state.point && state.from.vec().distanceTo(p) > 0) { + addWall() + event.preventDefault() + } + return + } + if (event.type === "mousedown") { if (state.point) { - if (!state.moving && - (Date.now() - state.lastmoving <= movingAddTimeout)) { - if (state.from.vec().distanceTo(p) > 0) { - addWall() - } else { - cleanup(); - } - event.preventDefault() - return - } if (state.point.inside(p.x, p.y)) { state.moving = true } @@ -476,6 +522,59 @@ function preciseAddWallHandler(event, editor, state) { event.preventDefault() } +// mousedown, dblclick +function preciseEditPointHandler(event, editor, state) { + const cleanup = function() { + console.warn("Done with edit") + state.menu.remove() + for (let i in state) { + delete state[i] + } + state.done = true + } + + if ((event.type !== "dblclick" && event.type !== "mousedown") || + event.button != buttons.left) { + return state.done + } + + let point = editor.pointAt(editor.draw.point(event.clientX, event.clientY)) + if (!point) { + if (state.point) { + cleanup() + event.preventDefault() + return true + } + return + } + + if (state.point && state.point != point) { + cleanup() + event.preventDefault() + return true + } + + if (event.type === "dblclick") { + state.done = false + state.point = point + state.menu = document.createElement("li") + state.menu.appendChild(document.createTextNode("Point: ")) + state.menu.appendChild( + ui.input("Delete", "Delete point", { + attributes: { type: "button" }, + handlers: { click: function() { + editor.removePoint(state.point) + cleanup() + }}, + }) + ) + state.point.select() + document.querySelector(".toolbar") + .appendChild(state.menu) + event.preventDefault() + } +} + function parseUserLength(editor, length) { let a = length.replaceAll(" ", "").split(/([0-9]+)/) let amount diff --git a/files/lib/ui.js b/files/lib/ui.js @@ -6,6 +6,7 @@ export function input(name, memo, options) { let e = document.createElement("input") e.name = name e.placeholder = name + e.setAttribute("value", name) // can be over-ridden by attributes e.setAttribute("title", memo) if (!options) {