1
- import React , { useCallback , useEffect , useRef , useState } from 'react' ;
1
+ import React , { useCallback , useEffect , useRef } from 'react' ;
2
2
3
3
import './GridInput.css' ;
4
4
import useMusicStore , { type GridNote } from '../store' ;
@@ -11,110 +11,48 @@ interface GridInputProps {
11
11
gridIndex : number ;
12
12
}
13
13
14
- const debounce = ( func : Function , delay : number ) => {
15
- let timeoutId : NodeJS . Timeout | null = null ;
16
-
17
- return ( ...args : any ) => {
18
- if ( timeoutId ) {
19
- clearTimeout ( timeoutId ) ;
20
- }
21
-
22
- timeoutId = setTimeout ( ( ) => {
23
- func ( ...args ) ;
24
- } , delay ) ;
25
- } ;
26
- } ;
27
14
28
15
const GridInput : React . FC < GridInputProps > = ( { gridIndex } ) => {
29
- const { grids, setGrid, updateNoteVelocity, setOrUpdateNoteInGrid } = useMusicStore ( ) ;
16
+ const { grids, setGrid, updateNoteVelocity, setOrUpdateNoteInGrid, deleteNoteFromGrid } = useMusicStore ( ) ;
30
17
const grid = grids [ gridIndex ] ;
31
18
const gridRef = useRef < HTMLDivElement | null > ( null ) ;
32
19
const cellRefs = useRef < ( HTMLDivElement | null ) [ ] [ ] > ( Array . from ( { length : GRID_PITCH_RANGE } , ( ) => Array ( grid ? grid . numColumns : 0 ) . fill ( null ) ) ) ;
33
20
34
- const [ isCtrlPressed , setIsCtrlPressed ] = useState ( false ) ;
35
- const [ draggingNote , setDraggingNote ] = useState < GridNote | null > ( null ) ;
36
-
37
- const toggleNote = useCallback ( ( pitch : number , beatIndex : number , velocity : number = 100 ) => {
21
+ const toggleNote = useCallback ( ( pitch : number , beatIndex : number , velocity ?: number | undefined ) => {
38
22
const grid = grids [ gridIndex ] ;
39
23
40
24
const notes = grid . beats [ beatIndex ] ?. notes || { } ;
41
25
const existingNote = notes [ pitch ] ;
42
26
43
27
if ( existingNote ) {
44
- if ( isCtrlPressed ) {
45
- // Adjust velocity if CTRL is pressed
28
+ if ( velocity ) {
46
29
existingNote . velocity = velocity ;
47
30
updateNoteVelocity ( gridIndex , beatIndex , pitch , velocity ) ;
48
- // dispatchPlayNoteNowEvent(pitch, velocity);
49
31
} else {
50
32
// Remove the note if it exists and CTRL is not pressed
51
33
delete notes [ pitch ] ;
52
- setOrUpdateNoteInGrid ( gridIndex , beatIndex , { pitch, velocity : 0 } ) ; // Use a default velocity if needed
34
+ deleteNoteFromGrid ( gridIndex , beatIndex , pitch ) ;
53
35
}
54
36
} else {
55
37
// Add a new note if it does not exist
56
- const newNote : GridNote = { pitch, velocity } ;
38
+ const newNote : GridNote = { pitch, velocity : velocity || 75 } ;
57
39
setOrUpdateNoteInGrid ( gridIndex , beatIndex , newNote ) ;
58
- dispatchPlayNoteNowEvent ( pitch , velocity ) ;
40
+ dispatchPlayNoteNowEvent ( pitch , velocity || 75 ) ;
59
41
}
60
- } , [ isCtrlPressed , gridIndex , setOrUpdateNoteInGrid , updateNoteVelocity , grids ] ) ;
61
-
62
- const debouncedToggleNoteRef = useRef ( debounce ( toggleNote , 25 ) ) ;
63
- // Update the ref whenever toggleNote changes
64
- useEffect ( ( ) => {
65
- debouncedToggleNoteRef . current = debounce ( toggleNote , 25 ) ;
66
- } , [ toggleNote ] ) ;
42
+ } , [ gridIndex , setOrUpdateNoteInGrid , deleteNoteFromGrid , updateNoteVelocity , grids ] ) ;
67
43
68
44
const handleMouseDown = ( pitch : number , e : React . MouseEvent < HTMLDivElement > ) => {
69
45
const beatIndex = Number ( e . currentTarget . dataset . beat ) ;
70
46
if ( e . ctrlKey ) {
71
- setIsCtrlPressed ( true ) ;
72
-
73
- // Access the current grid from the store
74
- const grid = grids [ gridIndex ] ;
75
-
76
- // Check if the note exists in the specified beat
77
- const note = grid . beats [ beatIndex ] ?. notes [ pitch ] ;
78
-
79
- // Set dragging note to the existing note or create a new one
80
- setDraggingNote ( note || { pitch, velocity : 75 } ) ;
47
+ const velocity = Number ( prompt ( 'Enter new velocity (1-127)' , '75' ) ) ;
48
+ if ( velocity ) {
49
+ toggleNote ( pitch , beatIndex , velocity ) ;
50
+ }
81
51
} else {
82
- toggleNote ( pitch , beatIndex ) ; // Call toggleNote with the updated signature
52
+ toggleNote ( pitch , beatIndex ) ;
83
53
}
84
54
} ;
85
55
86
- const handleMouseMove = useCallback ( ( e : MouseEvent ) => {
87
- if ( draggingNote && isCtrlPressed ) {
88
- if ( ! gridRef . current ?. clientWidth ) return ;
89
-
90
- // Use the dragging note's pitch and calculate the velocity based on the mouse Y position
91
- const velocity = Math . max ( 0 , Math . min ( 127 , 127 - e . clientY / 4 ) ) ;
92
-
93
- const beatIndex = Math . floor ( e . clientX / ( gridRef . current ?. clientWidth / grid . numColumns ) ) ; // Adjust based on your layout
94
- // toggleNote(draggingNote.pitch, beatIndex, velocity); // Use stored pitch from dragging note
95
- debouncedToggleNoteRef . current ( draggingNote . pitch , beatIndex , velocity ) ; // Use debounced function
96
- }
97
- } , [ draggingNote , grid . numColumns , isCtrlPressed ] ) ;
98
-
99
-
100
- const handleMouseUp = ( ) => {
101
- setIsCtrlPressed ( false ) ;
102
- setDraggingNote ( null ) ;
103
- } ;
104
-
105
- // Set up event listeners for drag
106
- useEffect ( ( ) => {
107
- if ( isCtrlPressed && draggingNote ) {
108
- window . addEventListener ( 'mousemove' , handleMouseMove ) ;
109
- window . addEventListener ( 'mouseup' , handleMouseUp ) ;
110
- }
111
-
112
- return ( ) => {
113
- window . removeEventListener ( 'mousemove' , handleMouseMove ) ;
114
- window . removeEventListener ( 'mouseup' , handleMouseUp ) ;
115
- } ;
116
- } , [ isCtrlPressed , draggingNote , handleMouseMove ] ) ;
117
-
118
56
const calculateOpacity = ( velocity : number ) => {
119
57
return velocity / 127 ; // Normalize velocity to opacity range [0, 1]
120
58
} ;
0 commit comments