diff --git a/LMEMappeCatastaliApp.csproj b/LMEMappeCatastaliApp.csproj
index 34fc145..9d843eb 100644
--- a/LMEMappeCatastaliApp.csproj
+++ b/LMEMappeCatastaliApp.csproj
@@ -28,8 +28,8 @@
com.companyname.lmemappecatastaliapp
- 0.2.28
- 32
+ 0.2.29
+ 33
None
diff --git a/wwwroot/css/app.css b/wwwroot/css/app.css
index dbf3d37..8e137cc 100644
--- a/wwwroot/css/app.css
+++ b/wwwroot/css/app.css
@@ -575,6 +575,11 @@ input[type="checkbox"] {
height: 38px;
}
+.lme-drawing-scope-actions a[aria-disabled="true"] {
+ opacity: 0.45;
+ pointer-events: none;
+}
+
.tool-sheet {
position: absolute;
top: 0;
diff --git a/wwwroot/js/lme-map.js b/wwwroot/js/lme-map.js
index b35b221..6691840 100644
--- a/wwwroot/js/lme-map.js
+++ b/wwwroot/js/lme-map.js
@@ -27,6 +27,7 @@ const lmeState = {
drawingMeasurements: null,
drawControl: null,
drawingDeleteButton: null,
+ drawingScopeMenu: null,
ignoreMapClickUntil: 0,
activeDrawHandler: null,
drawEventsBound: false,
@@ -214,6 +215,7 @@ function init(dotNetReference) {
if (event.originalEvent?._lmeDrawingSelected || Date.now() < lmeState.ignoreMapClickUntil) {
return;
}
+ hideDrawingScopeMenu();
clearManagerHighlight();
const info = await queryFeatureInfo(event.latlng);
if (info) {
@@ -238,6 +240,11 @@ function init(dotNetReference) {
});
if (!lmeState.managerOutsideSelectionBound) {
document.addEventListener("pointerdown", event => {
+ if (lmeState.drawingScopeMenu
+ && !event.target?.closest?.(".lme-drawing-scope-actions")
+ && !event.target?.closest?.(".leaflet-draw-edit-edit, .leaflet-draw-edit-remove")) {
+ hideDrawingScopeMenu();
+ }
if (!lmeState.managerHighlightedObjectId && !lmeState.managerHighlightedParentKey) {
return;
}
@@ -1796,10 +1803,13 @@ function drawingEditActive() {
function updateDrawingSelectionActions() {
const hasSelection = Boolean(lmeState.drawingSelection?.getLayers?.().length);
- lmeState.drawingDeleteButton?.classList.toggle("leaflet-disabled", !hasSelection);
+ const hasDrawings = Boolean(lmeState.drawings?.getLayers?.().length);
+ lmeState.drawingDeleteButton?.classList.toggle("leaflet-disabled", !hasDrawings);
if (lmeState.drawingDeleteButton) {
- lmeState.drawingDeleteButton.setAttribute("aria-disabled", String(!hasSelection));
+ lmeState.drawingDeleteButton.setAttribute("aria-disabled", String(!hasDrawings));
}
+ lmeState.drawingScopeMenu?.querySelector("[data-drawing-scope='selected']")
+ ?.setAttribute("aria-disabled", String(!hasSelection));
}
function setSelectedDrawing(layer) {
@@ -2207,8 +2217,8 @@ function addProjectMarker(name) {
marker.bindPopup(`${escapeHtml(label)}
${center.lat.toFixed(6)}, ${center.lng.toFixed(6)}`).openPopup();
bindDrawingLayerSelection(marker);
refreshDrawingMeasurements();
- setInfo(`POI aggiunto: ${label}`);
refreshLayerManager();
+ selectDrawingLayer(marker);
}
function configureDrawLabels() {
@@ -2217,8 +2227,8 @@ function configureDrawLabels() {
L.drawLocal.draw.toolbar.buttons.circle = "Misura cerchio";
L.drawLocal.draw.toolbar.buttons.rectangle = "Disegna rettangolo";
L.drawLocal.draw.toolbar.buttons.marker = "Aggiungi POI";
- L.drawLocal.edit.toolbar.buttons.edit = "Modifica oggetto selezionato";
- L.drawLocal.edit.toolbar.buttons.remove = "Elimina oggetto selezionato";
+ L.drawLocal.edit.toolbar.buttons.edit = "Scegli quali disegni modificare";
+ L.drawLocal.edit.toolbar.buttons.remove = "Scegli quali disegni eliminare";
L.drawLocal.draw.handlers.polygon.tooltip.start = "Tocca il primo vertice dell'area.";
L.drawLocal.draw.handlers.polygon.tooltip.cont = "Tocca per aggiungere un vertice.";
L.drawLocal.draw.handlers.polygon.tooltip.end = "Tocca il primo punto per chiudere l'area.";
@@ -2285,7 +2295,7 @@ function enableDrawTools() {
lmeState.drawControl = new L.Control.Draw({
position: "topright",
edit: {
- featureGroup: lmeState.drawingSelection,
+ featureGroup: lmeState.drawings,
remove: false,
edit: {
selectedPathOptions: {
@@ -2323,17 +2333,23 @@ function enableDrawTools() {
}
});
lmeState.map.addControl(lmeState.drawControl);
- installSelectedDrawingDeleteButton();
+ installDrawingScopeControls();
bindDrawingEvents();
setInfo("Barra strumenti attiva: seleziona un disegno sulla mappa, poi usa matita o cestino.");
}
-function installSelectedDrawingDeleteButton() {
+function installDrawingScopeControls() {
const toolbar = drawingEditToolbar();
const container = toolbar?._toolbarContainer;
if (!container) {
return;
}
+ const editButton = toolbar._modes?.[L.EditToolbar.Edit.TYPE]?.button;
+ editButton?.addEventListener("click", event => {
+ event.preventDefault();
+ event.stopImmediatePropagation();
+ showDrawingScopeMenu(editButton, "edit");
+ }, true);
const button = L.DomUtil.create("a", "leaflet-draw-edit-remove", container);
button.href = "#";
button.title = L.drawLocal.edit.toolbar.buttons.remove;
@@ -2344,11 +2360,79 @@ function installSelectedDrawingDeleteButton() {
L.DomEvent.on(button, "click", L.DomEvent.stop)
.on(button, "mousedown", L.DomEvent.stopPropagation)
.on(button, "touchstart", L.DomEvent.stopPropagation)
- .on(button, "click", removeSelectedDrawing);
+ .on(button, "click", () => showDrawingScopeMenu(button, "delete"));
lmeState.drawingDeleteButton = button;
updateDrawingSelectionActions();
}
+function showDrawingScopeMenu(button, action) {
+ if (drawingEditActive()) {
+ setInfo("Salva o annulla la modifica corrente prima di scegliere un altro comando.");
+ return;
+ }
+ if (!lmeState.drawings?.getLayers?.().length) {
+ setInfo("Non ci sono disegni o POI su cui operare.");
+ return;
+ }
+ if (lmeState.drawingScopeMenu?.dataset.action === action) {
+ hideDrawingScopeMenu();
+ return;
+ }
+ hideDrawingScopeMenu();
+ const menu = document.createElement("ul");
+ menu.className = "leaflet-draw-actions lme-drawing-scope-actions";
+ menu.dataset.action = action;
+ menu.style.display = "block";
+ menu.style.top = `${button.offsetTop - 1}px`;
+ menu.innerHTML = `
Solo selezionatoTutti`;
+ button.closest(".leaflet-draw-section")?.appendChild(menu);
+ lmeState.drawingScopeMenu = menu;
+ const hasSelection = Boolean(lmeState.drawingSelection?.getLayers?.().length);
+ const selectedAction = menu.querySelector("[data-drawing-scope='selected']");
+ selectedAction.setAttribute("aria-disabled", String(!hasSelection));
+ menu.querySelectorAll("a").forEach(link => {
+ L.DomEvent.on(link, "click", L.DomEvent.stop)
+ .on(link, "mousedown", L.DomEvent.stopPropagation)
+ .on(link, "touchstart", L.DomEvent.stopPropagation)
+ .on(link, "click", () => runDrawingScopeAction(action, link.dataset.drawingScope));
+ });
+}
+
+function hideDrawingScopeMenu() {
+ lmeState.drawingScopeMenu?.remove();
+ lmeState.drawingScopeMenu = null;
+}
+
+function runDrawingScopeAction(action, scope) {
+ const targetGroup = scope === "selected" ? lmeState.drawingSelection : lmeState.drawings;
+ if (!targetGroup?.getLayers?.().length) {
+ setInfo("Seleziona prima un oggetto sulla mappa.");
+ return;
+ }
+ hideDrawingScopeMenu();
+ if (action === "edit") {
+ startScopedDrawingEdit(targetGroup, scope);
+ } else if (scope === "selected") {
+ removeSelectedDrawing();
+ } else {
+ clearDrawings();
+ }
+}
+
+function startScopedDrawingEdit(targetGroup, scope) {
+ const toolbar = drawingEditToolbar();
+ const mode = toolbar?._modes?.[L.EditToolbar.Edit.TYPE];
+ if (!mode?.handler) {
+ return;
+ }
+ mode.handler._featureGroup = targetGroup;
+ mode.handler.options.featureGroup = targetGroup;
+ mode.handler.enable();
+ setInfo(scope === "selected"
+ ? "Modifica attiva sul solo oggetto selezionato."
+ : "Modifica attiva su tutti i disegni e POI.");
+}
+
function removeSelectedDrawing() {
const layer = lmeState.drawingSelection?.getLayers?.()[0];
if (!layer) {
@@ -2384,6 +2468,7 @@ function startMeasurementDrawing(mode) {
return;
}
bindDrawingEvents();
+ hideDrawingScopeMenu();
if (lmeState.activeDrawHandler) {
lmeState.activeDrawHandler.disable();
}
@@ -2498,6 +2583,7 @@ function setDrawToolsVisible(visible) {
lmeState.map.removeControl(lmeState.drawControl);
lmeState.drawControl = null;
lmeState.drawingDeleteButton = null;
+ lmeState.drawingScopeMenu = null;
setInfo("Strumenti di disegno nascosti.");
}