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
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.fillMaxWidth
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.platform.LocalDensity
import androidx.compose.ui.text.rememberTextMeasurer
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.notemusicali.music.MusicalNote
@@ -29,6 +31,8 @@ fun StaffFullView(
lightTheme: Boolean = false,
beats: 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
@@ -65,12 +69,18 @@ fun StaffFullView(
scrollState.animateScrollTo(targetY)
}
Canvas(
val viewportHeightDp = if (totalHeightDp < maxVisibleHeight) totalHeightDp else maxVisibleHeight
Box(
modifier = Modifier
.fillMaxWidth()
.verticalScroll(scrollState)
.height(totalHeightDp),
.height(viewportHeightDp)
.verticalScroll(scrollState),
) {
Canvas(
modifier = Modifier
.fillMaxWidth()
.height(totalHeightDp),
) {
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 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.width
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.items
import androidx.compose.foundation.rememberScrollState
@@ -231,7 +233,13 @@ fun ManualInputScreen(
)
if (notes.isNotEmpty()) {
val notesRowState = rememberLazyListState()
LaunchedEffect(notes.size) {
// Segui sempre l'ultima nota inserita
notesRowState.animateScrollToItem(notes.size - 1)
}
LazyRow(
state = notesRowState,
horizontalArrangement = Arrangement.spacedBy(6.dp),
modifier = Modifier
.fillMaxWidth()