fixed bug with keyboard
This commit is contained in:
parent
8b68261701
commit
c4cf8749fb
@ -1,12 +1,10 @@
|
|||||||
package net.sergeych.karabass
|
package net.sergeych.karabass
|
||||||
|
|
||||||
import androidx.compose.foundation.Canvas
|
import androidx.compose.foundation.Canvas
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.geometry.Offset
|
import androidx.compose.ui.geometry.Offset
|
||||||
import androidx.compose.ui.geometry.Rect
|
|
||||||
import androidx.compose.ui.geometry.Size
|
import androidx.compose.ui.geometry.Size
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.drawscope.DrawScope
|
import androidx.compose.ui.graphics.drawscope.DrawScope
|
||||||
@ -44,14 +42,16 @@ fun PianoKeyboard(
|
|||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.pointerInput(synth, whiteKeys, blackKeys, isHorizontal, availableNotes) {
|
.pointerInput(synth, whiteKeys, blackKeys, isHorizontal, availableNotes) {
|
||||||
awaitPointerEventScope {
|
awaitPointerEventScope {
|
||||||
// Карта для отслеживания активных указателей и их нот
|
// Карта для отслеживания активных указателей и их текущих нот
|
||||||
val activePointers = mutableMapOf<PointerId, String>()
|
val activePointers = mutableMapOf<PointerId, Pair<String, Float>>()
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
val event = awaitPointerEvent()
|
val event = awaitPointerEvent()
|
||||||
|
|
||||||
// Обрабатываем все изменения в событии
|
// Временный набор для обновления активных клавиш
|
||||||
for (change in event.changes) {
|
val newActiveKeys = mutableSetOf<String>()
|
||||||
|
|
||||||
|
event.changes.forEach { change ->
|
||||||
val pointerId = change.id
|
val pointerId = change.id
|
||||||
val position = change.position
|
val position = change.position
|
||||||
val canvasSize = Size(size.width.toFloat(), size.height.toFloat())
|
val canvasSize = Size(size.width.toFloat(), size.height.toFloat())
|
||||||
@ -70,10 +70,9 @@ fun PianoKeyboard(
|
|||||||
change.pressed -> {
|
change.pressed -> {
|
||||||
key?.let { (noteName, frequency) ->
|
key?.let { (noteName, frequency) ->
|
||||||
// Запоминаем связь указатель-нота
|
// Запоминаем связь указатель-нота
|
||||||
activePointers[pointerId] = noteName
|
activePointers[pointerId] = noteName to frequency
|
||||||
activeKeys = activeKeys + noteName
|
newActiveKeys.add(noteName)
|
||||||
|
|
||||||
println("startNote $noteName $frequency")
|
|
||||||
if (synth.isActive()) {
|
if (synth.isActive()) {
|
||||||
// Легато - плавный переход на новую ноту
|
// Легато - плавный переход на новую ноту
|
||||||
synth.changeNote(frequency)
|
synth.changeNote(frequency)
|
||||||
@ -86,21 +85,16 @@ fun PianoKeyboard(
|
|||||||
|
|
||||||
// ОТПУСКАНИЕ - когда указатель отпущен
|
// ОТПУСКАНИЕ - когда указатель отпущен
|
||||||
!change.pressed -> {
|
!change.pressed -> {
|
||||||
val releasedNoteName = activePointers.remove(pointerId)
|
val releasedNote = activePointers.remove(pointerId)
|
||||||
releasedNoteName?.let { noteName ->
|
releasedNote?.let { (noteName, _) ->
|
||||||
activeKeys = activeKeys - noteName
|
|
||||||
|
|
||||||
if (activePointers.isEmpty()) {
|
if (activePointers.isEmpty()) {
|
||||||
// Все клавиши отпущены - останавливаем ноту
|
// Все клавиши отпущены - останавливаем ноту
|
||||||
synth.stopNote()
|
synth.stopNote()
|
||||||
} else {
|
} else {
|
||||||
// Есть другие активные клавиши - переключаемся на одну из них
|
// Есть другие активные клавиши - переключаемся на одну из них
|
||||||
val remainingNoteName = activePointers.values.firstOrNull()
|
val remainingNote = activePointers.values.firstOrNull()
|
||||||
remainingNoteName?.let { name ->
|
remainingNote?.let {
|
||||||
val remainingNote = availableNotes.find { it.first == name }
|
synth.changeNote(it.second)
|
||||||
remainingNote?.let {
|
|
||||||
synth.changeNote(it.second)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -109,16 +103,12 @@ fun PianoKeyboard(
|
|||||||
// ПЕРЕМЕЩЕНИЕ - когда указатель переместился
|
// ПЕРЕМЕЩЕНИЕ - когда указатель переместился
|
||||||
change.positionChanged() -> {
|
change.positionChanged() -> {
|
||||||
key?.let { (newNoteName, newFrequency) ->
|
key?.let { (newNoteName, newFrequency) ->
|
||||||
val currentNoteName = activePointers[pointerId]
|
val currentNote = activePointers[pointerId]
|
||||||
|
|
||||||
// Если указатель переместился на другую клавишу
|
// Если указатель переместился на другую клавишу
|
||||||
if (currentNoteName != newNoteName) {
|
if (currentNote?.first != newNoteName) {
|
||||||
// Обновляем активные клавиши
|
// Обновляем активную ноту для этого указателя
|
||||||
currentNoteName?.let {
|
activePointers[pointerId] = newNoteName to newFrequency
|
||||||
activeKeys = activeKeys - it
|
|
||||||
}
|
|
||||||
activeKeys = activeKeys + newNoteName
|
|
||||||
activePointers[pointerId] = newNoteName
|
|
||||||
|
|
||||||
// Плавно переключаем ноту
|
// Плавно переключаем ноту
|
||||||
if (synth.isActive()) {
|
if (synth.isActive()) {
|
||||||
@ -132,6 +122,17 @@ fun PianoKeyboard(
|
|||||||
// Всегда сообщаем, что обработали событие
|
// Всегда сообщаем, что обработали событие
|
||||||
change.consume()
|
change.consume()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ОБНОВЛЯЕМ АКТИВНЫЕ КЛАВИШИ на основе текущего состояния всех указателей
|
||||||
|
// Это гарантирует, что визуальное состояние всегда соответствует звуковому
|
||||||
|
activePointers.values.forEach { (noteName, _) ->
|
||||||
|
newActiveKeys.add(noteName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Применяем обновление активных клавиш
|
||||||
|
if (activeKeys != newActiveKeys) {
|
||||||
|
activeKeys = newActiveKeys
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -155,7 +156,7 @@ fun PianoKeyboard(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Вспомогательные функции остаются без изменений:
|
// Остальные вспомогательные функции остаются без изменений:
|
||||||
|
|
||||||
private fun findKeyAtOffset(
|
private fun findKeyAtOffset(
|
||||||
offset: Offset,
|
offset: Offset,
|
||||||
@ -183,7 +184,7 @@ private fun findKeyAtOffsetHorizontal(
|
|||||||
blackKeys.forEachIndexed { index, blackKey ->
|
blackKeys.forEachIndexed { index, blackKey ->
|
||||||
val blackKeyX = (getWhiteKeyIndexForBlackKey(blackKey.first, whiteKeys) * whiteKeyWidth) -
|
val blackKeyX = (getWhiteKeyIndexForBlackKey(blackKey.first, whiteKeys) * whiteKeyWidth) -
|
||||||
(whiteKeyWidth * 0.25f)
|
(whiteKeyWidth * 0.25f)
|
||||||
val blackKeyRect = Rect(
|
val blackKeyRect = androidx.compose.ui.geometry.Rect(
|
||||||
left = blackKeyX,
|
left = blackKeyX,
|
||||||
top = 0f,
|
top = 0f,
|
||||||
right = blackKeyX + whiteKeyWidth * 0.5f,
|
right = blackKeyX + whiteKeyWidth * 0.5f,
|
||||||
@ -196,7 +197,7 @@ private fun findKeyAtOffsetHorizontal(
|
|||||||
|
|
||||||
// Затем проверяем белые клавиши
|
// Затем проверяем белые клавиши
|
||||||
whiteKeys.forEachIndexed { index, whiteKey ->
|
whiteKeys.forEachIndexed { index, whiteKey ->
|
||||||
val whiteKeyRect = Rect(
|
val whiteKeyRect = androidx.compose.ui.geometry.Rect(
|
||||||
left = index * whiteKeyWidth,
|
left = index * whiteKeyWidth,
|
||||||
top = 0f,
|
top = 0f,
|
||||||
right = (index + 1) * whiteKeyWidth,
|
right = (index + 1) * whiteKeyWidth,
|
||||||
@ -222,7 +223,7 @@ private fun findKeyAtOffsetVertical(
|
|||||||
blackKeys.forEachIndexed { index, blackKey ->
|
blackKeys.forEachIndexed { index, blackKey ->
|
||||||
val blackKeyY = (getWhiteKeyIndexForBlackKey(blackKey.first, whiteKeys) * whiteKeyHeight) -
|
val blackKeyY = (getWhiteKeyIndexForBlackKey(blackKey.first, whiteKeys) * whiteKeyHeight) -
|
||||||
(whiteKeyHeight * 0.25f)
|
(whiteKeyHeight * 0.25f)
|
||||||
val blackKeyRect = Rect(
|
val blackKeyRect = androidx.compose.ui.geometry.Rect(
|
||||||
left = size.width * 0.4f,
|
left = size.width * 0.4f,
|
||||||
top = blackKeyY,
|
top = blackKeyY,
|
||||||
right = size.width,
|
right = size.width,
|
||||||
@ -235,7 +236,7 @@ private fun findKeyAtOffsetVertical(
|
|||||||
|
|
||||||
// Затем проверяем белые клавиши
|
// Затем проверяем белые клавиши
|
||||||
whiteKeys.forEachIndexed { index, whiteKey ->
|
whiteKeys.forEachIndexed { index, whiteKey ->
|
||||||
val whiteKeyRect = Rect(
|
val whiteKeyRect = androidx.compose.ui.geometry.Rect(
|
||||||
left = 0f,
|
left = 0f,
|
||||||
top = index * whiteKeyHeight,
|
top = index * whiteKeyHeight,
|
||||||
right = size.width,
|
right = size.width,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user