Refactor KeyboardComponent note calculation logic
Extracted MIDI note calculation into a reusable `getMidiNoteFromMousePosition` function. Replaced redundant inline logic in mouse event handlers and key drawing sections for improved readability and maintainability.
This commit is contained in:
@@ -97,6 +97,32 @@ class KeyboardComponent(
|
|||||||
pressedNotes.clear()
|
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() {
|
override fun HtmlBuilder.render() {
|
||||||
div(KeyboardCls.name) {
|
div(KeyboardCls.name) {
|
||||||
style = "width: ${keyboardWidth}px; height: ${keyboardHeight + 60}px"
|
style = "width: ${keyboardWidth}px; height: ${keyboardHeight + 60}px"
|
||||||
@@ -157,79 +183,21 @@ class KeyboardComponent(
|
|||||||
// Define mouse event handlers at the SVG level
|
// Define mouse event handlers at the SVG level
|
||||||
onMouseDownFunction = { event ->
|
onMouseDownFunction = { event ->
|
||||||
if (event is MouseEvent) {
|
if (event is MouseEvent) {
|
||||||
val x = event.offsetX
|
getMidiNoteFromMousePosition(event.offsetX, event.offsetY)?.let { noteDown(it) }
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onMouseUpFunction = { event ->
|
onMouseUpFunction = { event ->
|
||||||
if (event is MouseEvent) {
|
if (event is MouseEvent) {
|
||||||
val x = event.offsetX
|
getMidiNoteFromMousePosition(event.offsetX, event.offsetY)?.let { noteUp(it) }
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw white keys
|
// Draw white keys
|
||||||
for (i in 0 until 7) {
|
for (i in 0 until 7) {
|
||||||
val midiNote = whiteKeys[i] + (octave - 5) * 12
|
val midiNote = whiteKeys[i] + getOctaveOffset()
|
||||||
val isPressed = pressedNotes.contains(midiNote)
|
val isPressed = pressedNotes.contains(midiNote)
|
||||||
rect(
|
rect(
|
||||||
i * whiteKeyWidth,
|
i * whiteKeyWidth,
|
||||||
@@ -243,7 +211,7 @@ class KeyboardComponent(
|
|||||||
|
|
||||||
// Draw black keys
|
// Draw black keys
|
||||||
for (i in 0 until 5) {
|
for (i in 0 until 5) {
|
||||||
val midiNote = blackKeys[i] + (octave - 5) * 12
|
val midiNote = blackKeys[i] + getOctaveOffset()
|
||||||
val isPressed = pressedNotes.contains(midiNote)
|
val isPressed = pressedNotes.contains(midiNote)
|
||||||
rect(
|
rect(
|
||||||
blackKeyPositions[i],
|
blackKeyPositions[i],
|
||||||
|
|||||||
Reference in New Issue
Block a user