@@ -430,6 +436,59 @@ export default {
}
});
+ // ── Manual Pick Mode ──────────────────────────────────────
+ const btnManualPick = document.getElementById('btn-manual-pick');
+ const mapContainer = document.getElementById('map-container');
+
+ if (btnManualPick && mapContainer) {
+ btnManualPick.addEventListener('click', () => {
+ isManualPickMode = !isManualPickMode;
+ if (isManualPickMode) {
+ btnManualPick.classList.add('btn-success');
+ btnManualPick.classList.remove('btn-secondary');
+ mapContainer.style.cursor = 'crosshair';
+ } else {
+ btnManualPick.classList.remove('btn-success');
+ btnManualPick.classList.add('btn-secondary');
+ mapContainer.style.cursor = 'default';
+ }
+ });
+
+ mapContainer.addEventListener('click', (e) => {
+ if (!isManualPickMode) return;
+ // Ignore clicks on existing markers
+ if (e.target.classList.contains('spot-marker')) return;
+
+ const rect = mapContainer.getBoundingClientRect();
+ const xClick = e.clientX - rect.left;
+ const yClick = e.clientY - rect.top;
+
+ const w = bounds.xMax - bounds.xMin;
+ const h = bounds.yMax - bounds.yMin;
+
+ const x = bounds.xMin + (xClick / rect.width) * w;
+ const y = bounds.yMax - (yClick / rect.height) * h;
+
+ const check = IK.checkWorkspace(x, y);
+ if (!check.valid) {
+ UI.log(check.reason, 'warning');
+ return;
+ }
+
+ // Execute move
+ if (listEl) listEl.value = ''; // Deselect predefined spots
+ goBtn.disabled = true;
+
+ executeMove({ id: 'manual', label: `Manual [${x.toFixed(1)}, ${y.toFixed(1)}]`, x, y });
+
+ // Turn off mode automatically (one-shot)
+ isManualPickMode = false;
+ btnManualPick.classList.remove('btn-success');
+ btnManualPick.classList.add('btn-secondary');
+ mapContainer.style.cursor = 'default';
+ });
+ }
+
// ── Sync Steps from BLE ───────────────────────────────────
const onBLEStatus = (e) => {
const msg = e.detail;