diff --git a/src/renderer/handlers/selection.js b/src/renderer/handlers/selection.js index 3bf03bb..d1cafb2 100644 --- a/src/renderer/handlers/selection.js +++ b/src/renderer/handlers/selection.js @@ -8,6 +8,7 @@ let _rafPending = false; let _lastMoveEvent = null; let lastSelectedIdx = null; +let _rbStartSelection = new Set(); // 러버밴드 시작 시점의 선택 스냅샷 export function resetAnchor() { lastSelectedIdx = null; @@ -95,8 +96,10 @@ function _onStart(e) { }); const preserve = e.shiftKey || e.ctrlKey || e.metaKey; + _rbStartSelection = new Set(_state.selectedIdxs); // 토글 기준점 스냅샷 if (!preserve) { _state.selectedIdxs.clear(); + _rbStartSelection.clear(); lastSelectedIdx = null; _cb.refreshCardSelection(); } @@ -127,12 +130,20 @@ function _processMove() { }); const sel = { left, top, right: left + width, bottom: top + height }; - const preserve = e.shiftKey || e.ctrlKey || e.metaKey; + const shiftToggle = e.shiftKey && !e.ctrlKey && !e.metaKey; + const preserve = e.ctrlKey || e.metaKey; Array.from(_grid.children).forEach((card, i) => { const r = card.getBoundingClientRect(); const overlaps = !(r.right < sel.left || r.left > sel.right || r.bottom < sel.top || r.top > sel.bottom); - if (overlaps) { + if (shiftToggle) { + // 러버밴드 안: 시작 시점 기준으로 토글 (밖: 시작 시점 상태 복원) + if (overlaps ? !_rbStartSelection.has(i) : _rbStartSelection.has(i)) { + _state.selectedIdxs.add(i); + } else { + _state.selectedIdxs.delete(i); + } + } else if (overlaps) { _state.selectedIdxs.add(i); } else if (!preserve) { _state.selectedIdxs.delete(i);