diff --git a/src/renderer/handlers/selection.js b/src/renderer/handlers/selection.js index 4e9996c..7ccd8a4 100644 --- a/src/renderer/handlers/selection.js +++ b/src/renderer/handlers/selection.js @@ -5,6 +5,8 @@ let rbActive = false; let rbStartX = 0; let rbStartY = 0; +let lastSelectedIdx = null; + export function init({ gridContainer, rubberBand, grid, state, callbacks }) { _rubberBand = rubberBand; _grid = grid; @@ -16,20 +18,59 @@ export function init({ gridContainer, rubberBand, grid, state, callbacks }) { window.addEventListener('mouseup', _onEnd); } -// 카드에 부착할 cmd+클릭 핸들러 (this = card element) +// 카드에 부착할 클릭 핸들러 (this = card element) export function onCardClick(e) { - if (!e.metaKey) return; e.stopPropagation(); const idx = parseInt(this.dataset.idx); - if (_state.selectedIdxs.has(idx)) { - _state.selectedIdxs.delete(idx); + const isCtrl = e.ctrlKey || e.metaKey; + + if (e.shiftKey && isCtrl) { + // Shift + Ctrl/Cmd → Ctrl 동작으로 처리 + _toggle(idx); + } else if (e.shiftKey) { + _selectRange(idx); + } else if (isCtrl) { + _toggle(idx); } else { - _state.selectedIdxs.add(idx); + // 수식 키 없음: 해당 카드만 단독 선택, 이미 단독 선택 중이면 해제 + if (_state.selectedIdxs.has(idx) && _state.selectedIdxs.size === 1) { + _state.selectedIdxs.clear(); + lastSelectedIdx = null; + } else { + _state.selectedIdxs.clear(); + _state.selectedIdxs.add(idx); + lastSelectedIdx = idx; + } } + _cb.refreshCardSelection(); _cb.updateSelCount(); } +function _toggle(idx) { + if (_state.selectedIdxs.has(idx)) { + _state.selectedIdxs.delete(idx); + lastSelectedIdx = null; + } else { + _state.selectedIdxs.add(idx); + lastSelectedIdx = idx; + } +} + +function _selectRange(idx) { + if (lastSelectedIdx === null) { + _state.selectedIdxs.clear(); + _state.selectedIdxs.add(idx); + lastSelectedIdx = idx; + return; + } + const start = Math.min(lastSelectedIdx, idx); + const end = Math.max(lastSelectedIdx, idx); + _state.selectedIdxs.clear(); + for (let i = start; i <= end; i++) _state.selectedIdxs.add(i); + // anchor(lastSelectedIdx)는 Shift 클릭으로 변경하지 않음 +} + function _onStart(e) { if (e.target.closest('.card')) return; if (e.target.closest('button, input, label')) return; @@ -49,6 +90,7 @@ function _onStart(e) { if (!e.shiftKey) { _state.selectedIdxs.clear(); + lastSelectedIdx = null; _cb.refreshCardSelection(); } }