fix(ui): spartito ad altezza fissa con auto-scroll; inserimento manuale segue l'ultima nota

- StaffFullView: viewport limitato (maxVisibleHeight, default 340dp) con
  scroll interno — in Pratica la card della nota rilevata resta sempre
  visibile anche con spartiti lunghi; l'auto-scroll alla riga corrente
  ora ha un viewport reale su cui agire
- ManualInputScreen: la riga delle note selezionate scorre da sola
  sull'ultima nota inserita

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
lucianoandClaude Fable 5 committed 2026-07-22 21:12:42 +02:00
1 parent d0d94c30fa
commit 0a835699e0
2 files changed
+22 -3

No files matched your search

@@ -1,6 +1,7 @@
package com.notemusicali.ui.components package com.notemusicali.ui.components
import androidx.compose.foundation.Canvas import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxWithConstraints import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
@@ -13,6 +14,7 @@ import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.rememberTextMeasurer import androidx.compose.ui.text.rememberTextMeasurer
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.notemusicali.music.MusicalNote import com.notemusicali.music.MusicalNote
@@ -29,6 +31,8 @@ fun StaffFullView(
lightTheme: Boolean = false, lightTheme: Boolean = false,
beats: Int = 4, beats: Int = 4,
beatType: Int = 4, beatType: Int = 4,
// Altezza massima visibile: oltre, lo spartito scorre da solo seguendo la nota corrente
maxVisibleHeight: Dp = 340.dp,
) { ) {
if (notes.isEmpty()) return if (notes.isEmpty()) return
@@ -65,12 +69,18 @@ fun StaffFullView(
scrollState.animateScrollTo(targetY) scrollState.animateScrollTo(targetY)
} }
Canvas( val viewportHeightDp = if (totalHeightDp < maxVisibleHeight) totalHeightDp else maxVisibleHeight
Box(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.verticalScroll(scrollState) .height(viewportHeightDp)
.height(totalHeightDp), .verticalScroll(scrollState),
) { ) {
Canvas(
modifier = Modifier
.fillMaxWidth()
.height(totalHeightDp),
) {
val lineColor = if (lightTheme) Color.Black else Color.White.copy(alpha = 0.4f) val lineColor = if (lightTheme) Color.Black else Color.White.copy(alpha = 0.4f)
val dimColor = if (lightTheme) Color.Black else Color.White.copy(alpha = 0.35f) val dimColor = if (lightTheme) Color.Black else Color.White.copy(alpha = 0.35f)
val playedColor = if (lightTheme) Color.Black.copy(alpha = 0.35f) else Color.White.copy(alpha = 0.2f) val playedColor = if (lightTheme) Color.Black.copy(alpha = 0.35f) else Color.White.copy(alpha = 0.2f)
@@ -194,5 +204,6 @@ fun StaffFullView(
} }
} }
} }
}
} }
} }
@@ -21,6 +21,8 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.widthIn import androidx.compose.foundation.layout.widthIn
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
@@ -231,7 +233,13 @@ fun ManualInputScreen(
) )
if (notes.isNotEmpty()) { if (notes.isNotEmpty()) {
val notesRowState = rememberLazyListState()
LaunchedEffect(notes.size) {
// Segui sempre l'ultima nota inserita
notesRowState.animateScrollToItem(notes.size - 1)
}
LazyRow( LazyRow(
state = notesRowState,
horizontalArrangement = Arrangement.spacedBy(6.dp), horizontalArrangement = Arrangement.spacedBy(6.dp),
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()