diff --git a/src/components/MainContent.tsx b/src/components/MainContent.tsx index 6b2099d..274eea7 100644 --- a/src/components/MainContent.tsx +++ b/src/components/MainContent.tsx @@ -122,6 +122,9 @@ const MainContent: React.FC = ({ editingRegionIds: mainContentGlobalTracks.editingRegionIds, findProjectRegionById: mainContentRegions.selection.findProjectRegionById, }); + const deleteSelectedRegularRegions = mainContentRegions.deleteSelectedRegions; + const deleteSelectedGlobalRegions = mainContentGlobalTracks.deleteSelectedGlobalRegions; + const isGlobalRegionId = mainContentRegions.selection.isGlobalRegionId; const deleteSelectedTrackAutomationPoints = useCallback((): boolean => { if (!activeTrackAutomationTrackId || !activeTrackAutomationType || selectedTrackAutomationPointIds.length === 0) { @@ -159,22 +162,22 @@ const MainContent: React.FC = ({ useEffect(() => { regionDeleteManager.registerDeleteCallback(() => { - if (mainContentGlobalTracks.deleteSelectedGlobalRegions()) { + if (deleteSelectedGlobalRegions()) { return true; } if (deleteSelectedTrackAutomationPoints()) { return true; } - return mainContentRegions.deleteSelectedRegions(); + return deleteSelectedRegularRegions(); }); return () => { regionDeleteManager.unregisterDeleteCallback(); }; }, [ + deleteSelectedGlobalRegions, + deleteSelectedRegularRegions, deleteSelectedTrackAutomationPoints, - mainContentGlobalTracks, - mainContentRegions, ]); useEffect(() => { @@ -192,12 +195,12 @@ const MainContent: React.FC = ({ if (event.key === 'Backspace' || event.key === 'Delete') { const isInPianoRoll = document.querySelector('.piano-roll')?.contains(event.target as Node); - const hasSelectedGlobalRegions = selectedRegionIds.some(mainContentRegions.selection.isGlobalRegionId); + const hasSelectedGlobalRegions = selectedRegionIds.some(isGlobalRegionId); if (!isInPianoRoll && (!showPianoRoll || hasSelectedGlobalRegions)) { - const deleted = mainContentGlobalTracks.deleteSelectedGlobalRegions() + const deleted = deleteSelectedGlobalRegions() || deleteSelectedTrackAutomationPoints() - || mainContentRegions.deleteSelectedRegions(); + || deleteSelectedRegularRegions(); if (deleted) { event.preventDefault(); } @@ -208,9 +211,10 @@ const MainContent: React.FC = ({ window.addEventListener('keydown', handleKeyDown); return () => window.removeEventListener('keydown', handleKeyDown); }, [ + deleteSelectedGlobalRegions, + deleteSelectedRegularRegions, deleteSelectedTrackAutomationPoints, - mainContentGlobalTracks, - mainContentRegions, + isGlobalRegionId, selectedRegionIds, showPianoRoll, ]); diff --git a/src/components/track/TrackGridItem.tsx b/src/components/track/TrackGridItem.tsx index 51df9c6..99cf731 100644 --- a/src/components/track/TrackGridItem.tsx +++ b/src/components/track/TrackGridItem.tsx @@ -9,6 +9,7 @@ import type { RegionClickOptions, RegionPreviewContentStyle, RegionUI, ResizeAct import { REGION_CONSTANTS, DEBUG_MODE } from '../../constants'; import { KGMainContentState } from '../../core/state/KGMainContentState'; import { useProjectStore } from '../../stores/projectStore'; +import { isModifierKeyPressed } from '../../util/osUtil'; interface RegionResizePreviewBaseline { regionId: string; @@ -201,21 +202,26 @@ const TrackGridItem: React.FC = ({ // Track tool state for cursor feedback. useEffect(() => { - const syncCursorState = () => { + const syncCursorState = (event?: KeyboardEvent | MouseEvent) => { + const isPencilMode = KGMainContentState.instance().getActiveTool() === 'pencil'; + const hasModifierPressed = event ? isModifierKeyPressed(event) : false; + setIsModifierPressed(isPencilMode || hasModifierPressed); + }; + const syncCursorStateFromFocus = () => { setIsModifierPressed(KGMainContentState.instance().getActiveTool() === 'pencil'); }; // Add global event listeners window.addEventListener('keydown', syncCursorState); window.addEventListener('keyup', syncCursorState); - window.addEventListener('focus', syncCursorState); - syncCursorState(); + window.addEventListener('focus', syncCursorStateFromFocus); + syncCursorStateFromFocus(); // Cleanup listeners on unmount return () => { window.removeEventListener('keydown', syncCursorState); window.removeEventListener('keyup', syncCursorState); - window.removeEventListener('focus', syncCursorState); + window.removeEventListener('focus', syncCursorStateFromFocus); }; }, []); diff --git a/src/hooks/useMainContentGlobalTracks.ts b/src/hooks/useMainContentGlobalTracks.ts index a836d96..727c4f0 100644 --- a/src/hooks/useMainContentGlobalTracks.ts +++ b/src/hooks/useMainContentGlobalTracks.ts @@ -1,4 +1,4 @@ -import { useCallback, useMemo, useState } from 'react'; +import { useCallback, useState } from 'react'; import type { KeySignature } from '../core/KGProject'; import { KGCore } from '../core/KGCore'; import { GlobalTrackType, KGGlobalTrack } from '../core/global-track'; @@ -88,37 +88,21 @@ export function useMainContentGlobalTracks({ const [editingTempoText, setEditingTempoText] = useState(''); const [editingChordRegionId, setEditingChordRegionId] = useState(null); - const markerTrack = useMemo( - () => globalTracks.find(track => track.getType() === GlobalTrackType.Marker) ?? null, - [globalTracks] + const markerTrack = globalTracks.find(track => track.getType() === GlobalTrackType.Marker) ?? null; + const markerRegions = (markerTrack?.getRegions() ?? []).filter( + (region): region is KGMarkerRegion => region instanceof KGMarkerRegion ); - const markerRegions = useMemo( - () => (markerTrack?.getRegions() ?? []).filter((region): region is KGMarkerRegion => region instanceof KGMarkerRegion), - [markerTrack] - ); - const signatureTrack = useMemo( - () => globalTracks.find(track => track.getType() === GlobalTrackType.Signature) ?? null, - [globalTracks] - ); - const signatureRegions = useMemo( - () => (signatureTrack ? getSortedKeySignatureRegions(signatureTrack, timeSignature.numerator) : []), - [signatureTrack, timeSignature.numerator] - ); - const tempoTrack = useMemo( - () => globalTracks.find(track => track.getType() === GlobalTrackType.Tempo) ?? null, - [globalTracks] - ); - const tempoRegions = useMemo( - () => (tempoTrack ? getSortedTempoRegions(tempoTrack, timeSignature.numerator) : []), - [tempoTrack, timeSignature.numerator] - ); - const chordTrack = useMemo( - () => globalTracks.find(track => track.getType() === GlobalTrackType.Chord) ?? null, - [globalTracks] - ); - const chordRegions = useMemo( - () => (chordTrack?.getRegions() ?? []).filter((region): region is KGChordRegion => region instanceof KGChordRegion), - [chordTrack] + const signatureTrack = globalTracks.find(track => track.getType() === GlobalTrackType.Signature) ?? null; + const signatureRegions = signatureTrack + ? getSortedKeySignatureRegions(signatureTrack, timeSignature.numerator) + : []; + const tempoTrack = globalTracks.find(track => track.getType() === GlobalTrackType.Tempo) ?? null; + const tempoRegions = tempoTrack + ? getSortedTempoRegions(tempoTrack, timeSignature.numerator) + : []; + const chordTrack = globalTracks.find(track => track.getType() === GlobalTrackType.Chord) ?? null; + const chordRegions = (chordTrack?.getRegions() ?? []).filter( + (region): region is KGChordRegion => region instanceof KGChordRegion ); const beginEditingGlobalRegion = useCallback((regionId: string) => { @@ -202,7 +186,6 @@ export function useMainContentGlobalTracks({ return; } - selectGlobalRegion(createdRegion.getId(), DEFAULT_REGION_CLICK_OPTIONS); setEditingGlobalRegionId(createdRegion.getId()); setEditingGlobalRegionText(createdRegion.getName()); } catch (error) { @@ -253,7 +236,6 @@ export function useMainContentGlobalTracks({ return; } - selectGlobalRegion(createdRegion.getId(), DEFAULT_REGION_CLICK_OPTIONS); setEditingKeySignatureRegionId(createdRegion.getId()); } catch (error) { console.error('Error creating key signature region:', error); @@ -339,7 +321,6 @@ export function useMainContentGlobalTracks({ return; } - selectGlobalRegion(createdRegion.getId(), DEFAULT_REGION_CLICK_OPTIONS); setEditingTempoRegionId(createdRegion.getId()); setEditingTempoText(createdRegion.getBpm().toString()); } catch (error) { @@ -385,7 +366,6 @@ export function useMainContentGlobalTracks({ return; } - selectGlobalRegion(createdRegion.getId(), DEFAULT_REGION_CLICK_OPTIONS); setEditingChordRegionId(createdRegion.getId()); } catch (error) { console.error('Error creating chord region:', error); @@ -416,7 +396,6 @@ export function useMainContentGlobalTracks({ return null; } - selectGlobalRegion(createdRegion.getId(), DEFAULT_REGION_CLICK_OPTIONS); setEditingChordRegionId(createdRegion.getId()); return createdRegion; } catch (error) {