diff --git a/src/jsMain/kotlin/nl/astraeus/vst/ui/components/KeyboardComponent.kt b/src/jsMain/kotlin/nl/astraeus/vst/ui/components/KeyboardComponent.kt index 0c53885..a7fbf85 100644 --- a/src/jsMain/kotlin/nl/astraeus/vst/ui/components/KeyboardComponent.kt +++ b/src/jsMain/kotlin/nl/astraeus/vst/ui/components/KeyboardComponent.kt @@ -97,6 +97,32 @@ class KeyboardComponent( pressedNotes.clear() } + private fun getOctaveOffset(): Int = (octave - 5) * 12 + + private fun getMidiNoteFromMousePosition(x: Double, y: Double): Int? { + // Check if click is on a black key (black keys are on top of white keys) + if (y <= blackKeyHeight) { + for (j in 0 until 5) { + if (x >= blackKeyPositions[j] && x <= blackKeyPositions[j] + blackKeyWidth) { + return blackKeys[j] + getOctaveOffset() + } + } + + // If no black key was pressed, check for white key + val keyIndex = (x / whiteKeyWidth).toInt() + if (keyIndex in 0..6) { + return whiteKeys[keyIndex] + getOctaveOffset() + } + } else { + // If y > blackKeyHeight, it's definitely a white key + val keyIndex = (x / whiteKeyWidth).toInt() + if (keyIndex in 0..6) { + return whiteKeys[keyIndex] + getOctaveOffset() + } + } + return null + } + override fun HtmlBuilder.render() { div(KeyboardCls.name) { style = "width: ${keyboardWidth}px; height: ${keyboardHeight + 60}px" @@ -157,79 +183,21 @@ class KeyboardComponent( // Define mouse event handlers at the SVG level onMouseDownFunction = { event -> if (event is MouseEvent) { - val x = event.offsetX - val y = event.offsetY - - // Check if click is on a black key (black keys are on top of white keys) - if (y <= blackKeyHeight) { - var blackKeyPressed = false - for (j in 0 until 5) { - if (x >= blackKeyPositions[j] && x <= blackKeyPositions[j] + blackKeyWidth) { - noteDown(blackKeys[j] + (octave - 5) * 12) - blackKeyPressed = true - break - } - } - - // If no black key was pressed, check for white key - if (!blackKeyPressed) { - // Check if click is on a white key - val keyIndex = (x / whiteKeyWidth).toInt() - if (keyIndex in 0..6) { - noteDown(whiteKeys[keyIndex] + (octave - 5) * 12) - } - } - } else { - // If y > blackKeyHeight, it's definitely a white key - val keyIndex = (x / whiteKeyWidth).toInt() - if (keyIndex in 0..6) { - noteDown(whiteKeys[keyIndex] + (octave - 5) * 12) - } - } - + getMidiNoteFromMousePosition(event.offsetX, event.offsetY)?.let { noteDown(it) } event.preventDefault() } } onMouseUpFunction = { event -> if (event is MouseEvent) { - val x = event.offsetX - val y = event.offsetY - - // Check if release is on a black key (black keys are on top of white keys) - if (y <= blackKeyHeight) { - var blackKeyReleased = false - for (j in 0 until 5) { - if (x >= blackKeyPositions[j] && x <= blackKeyPositions[j] + blackKeyWidth) { - noteUp(blackKeys[j] + (octave - 5) * 12) - blackKeyReleased = true - break - } - } - - // If no black key was released, check for white key - if (!blackKeyReleased) { - // Check if release is on a white key - val keyIndex = (x / whiteKeyWidth).toInt() - if (keyIndex in 0..6) { - noteUp(whiteKeys[keyIndex] + (octave - 5) * 12) - } - } - } else { - // If y > blackKeyHeight, it's definitely a white key - val keyIndex = (x / whiteKeyWidth).toInt() - if (keyIndex in 0..6) { - noteUp(whiteKeys[keyIndex] + (octave - 5) * 12) - } - } - + getMidiNoteFromMousePosition(event.offsetX, event.offsetY)?.let { noteUp(it) } event.preventDefault() } } // Draw white keys for (i in 0 until 7) { - val midiNote = whiteKeys[i] + (octave - 5) * 12 + val midiNote = whiteKeys[i] + getOctaveOffset() val isPressed = pressedNotes.contains(midiNote) rect( i * whiteKeyWidth, @@ -243,7 +211,7 @@ class KeyboardComponent( // Draw black keys for (i in 0 until 5) { - val midiNote = blackKeys[i] + (octave - 5) * 12 + val midiNote = blackKeys[i] + getOctaveOffset() val isPressed = pressedNotes.contains(midiNote) rect( blackKeyPositions[i],