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