diff --git a/composeApp/src/commonMain/kotlin/mg/dot/feufaro/ScreenSolfa.kt b/composeApp/src/commonMain/kotlin/mg/dot/feufaro/ScreenSolfa.kt index f9e64b4..118b354 100644 --- a/composeApp/src/commonMain/kotlin/mg/dot/feufaro/ScreenSolfa.kt +++ b/composeApp/src/commonMain/kotlin/mg/dot/feufaro/ScreenSolfa.kt @@ -1,20 +1,23 @@ package mg.dot.feufaro import SharedScreenModel +import androidx.compose.foundation.VerticalScrollbar import androidx.compose.foundation.background import androidx.compose.foundation.gestures.detectTapGestures import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.FlowRow import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.safeDrawing import androidx.compose.foundation.layout.windowInsetsPadding -import androidx.compose.foundation.lazy.grid.rememberLazyGridState import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.rememberScrollbarAdapter import androidx.compose.foundation.verticalScroll import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -56,109 +59,113 @@ object ScreenSolfa : Screen { val measure by sharedScreenModel.measure.collectAsState() val stanza by sharedScreenModel.stanza.collectAsState() val gridTUOData = GridTUOData(measure, tuoList, stanza) - val lazyGridState = rememberLazyGridState() val coroutineScope = rememberCoroutineScope() - Column( - Modifier.fillMaxSize() - .pointerInput(Unit) { - detectTapGestures( - onDoubleTap = { - offset -> - menuPosition = offset - showContextualMenu = true - } - ) - }, - horizontalAlignment = Alignment.CenterHorizontally, + val scrollState = rememberScrollState() + Box(Modifier.fillMaxSize() ) { - val columnScrollState = rememberScrollState() - if (showContextualMenu) { - Popup( - alignment = Alignment.TopStart, - offset = IntOffset(menuPosition.x.roundToInt(), - menuPosition.y.roundToInt()), - onDismissRequest = { - showContextualMenu = false - } - ) { - ContextualMenu(onMenuItemClick = { item -> - println("Clicked: $item") - showContextualMenu = false - }) - } - } Column( - modifier = Modifier - .fillMaxWidth() - .weight(1f) - .verticalScroll(columnScrollState) + Modifier + .verticalScroll(scrollState) + .pointerInput(Unit) { + detectTapGestures( + onDoubleTap = { offset -> + menuPosition = offset + showContextualMenu = true + } + ) + }, + horizontalAlignment = Alignment.CenterHorizontally, ) { - FlowRow( - modifier = Modifier.fillMaxWidth() - .windowInsetsPadding(WindowInsets.safeDrawing) - .padding(start = 8.dp, end = 8.dp, top = 8.dp), - horizontalArrangement = Arrangement.spacedBy(16.dp), - verticalArrangement = Arrangement.spacedBy(4.dp) - ) { - val measureString: String by sharedScreenModel.measure.collectAsState() - val songTitle: String by sharedScreenModel.songTitle.collectAsState() - val songKey: String by sharedScreenModel.songKey.collectAsState() - Text(text = songTitle, fontWeight = FontWeight.Bold) - Text( - text = songKey, - modifier = Modifier.background(Color(0xff, 0xea, 0xe7)) - .padding(horizontal = 4.dp) - ) - Text(text = measureString) - Text(text = "Stanza: $stanza") - ScreenTranspose.Content() - } - LazyVerticalGridTUO( - gridTUOData, - gridWidthPx = gridWidthPx, - onGridWidthMeasured = { width -> gridWidthPx = width }, - lazyGridState = lazyGridState - ) - MGButton(onClick = { - //showContent = !showContent - - solfaScreenModel.loadNextInPlaylist() - }, modifier = Modifier.height(40.dp)) { - val nextLabel: String by sharedScreenModel.nextLabel.collectAsState() - Text(nextLabel) - } - FlowRow( - modifier = Modifier.fillMaxWidth() - .windowInsetsPadding(WindowInsets.safeDrawing) - .padding(start = 8.dp, end = 8.dp, top = 8.dp), - horizontalArrangement = Arrangement.spacedBy(16.dp), - verticalArrangement = Arrangement.spacedBy(4.dp) - ) { - val nbStanzas: Int by sharedScreenModel.nbStanzas.collectAsState() - for (i in 1..nbStanzas) { - MGButton( - enabled = (i != stanza.toInt()), - onClick = { - sharedScreenModel.setStanza(i) - coroutineScope.launch { - lazyGridState.animateScrollToItem(0) - columnScrollState.animateScrollTo(0) - } - }, - modifier = Modifier.padding(horizontal = 4.dp) - ) { - Text("$i") + if (showContextualMenu) { + Popup( + alignment = Alignment.TopStart, + offset = IntOffset( + menuPosition.x.roundToInt(), + menuPosition.y.roundToInt() + ), + onDismissRequest = { + showContextualMenu = false } + ) { + ContextualMenu(onMenuItemClick = { item -> + println("Clicked: $item") + showContextualMenu = false + }) } - val songAuthor: String by sharedScreenModel.songAuthor.collectAsState() - val songComposer: String by sharedScreenModel.songComposer.collectAsState() - val songRhythm: String by sharedScreenModel.songRhythm.collectAsState() - Text(text = songAuthor, fontStyle = FontStyle.Italic) - Text(text = songRhythm) - Text(text = songComposer) + } + Column( + modifier = Modifier + .fillMaxSize() + ) { + FlowRow( + modifier = Modifier.fillMaxWidth() + .windowInsetsPadding(WindowInsets.safeDrawing) + .padding(start = 8.dp, end = 8.dp, top = 8.dp), + horizontalArrangement = Arrangement.spacedBy(16.dp), + verticalArrangement = Arrangement.spacedBy(4.dp) + ) { + val measureString: String by sharedScreenModel.measure.collectAsState() + val songTitle: String by sharedScreenModel.songTitle.collectAsState() + val songKey: String by sharedScreenModel.songKey.collectAsState() + Text(text = songTitle, fontWeight = FontWeight.Bold) + Text( + text = songKey, + modifier = Modifier.background(Color(0xff, 0xea, 0xe7)) + .padding(horizontal = 4.dp) + ) + Text(text = measureString) + Text(text = "Stanza: $stanza") + ScreenTranspose.Content() + } + LazyVerticalGridTUO( + gridTUOData, + gridWidthPx = gridWidthPx, + onGridWidthMeasured = { width -> gridWidthPx = width } + ) + MGButton(onClick = { + //showContent = !showContent + solfaScreenModel.loadNextInPlaylist() + }, modifier = Modifier.height(40.dp)) { + val nextLabel: String by sharedScreenModel.nextLabel.collectAsState() + Text(nextLabel) + } + FlowRow( + modifier = Modifier.fillMaxWidth() + .windowInsetsPadding(WindowInsets.safeDrawing) + .padding(start = 8.dp, end = 8.dp, top = 8.dp), + horizontalArrangement = Arrangement.spacedBy(16.dp), + verticalArrangement = Arrangement.spacedBy(4.dp) + ) { + val nbStanzas: Int by sharedScreenModel.nbStanzas.collectAsState() + for (i in 1..nbStanzas) { + MGButton( + enabled = (i != stanza.toInt()), + onClick = { + sharedScreenModel.setStanza(i) + coroutineScope.launch { + scrollState.animateScrollTo(0) + } + }, + modifier = Modifier.padding(horizontal = 4.dp) + ) { + Text("$i") + } + } + val songAuthor: String by sharedScreenModel.songAuthor.collectAsState() + val songComposer: String by sharedScreenModel.songComposer.collectAsState() + val songRhythm: String by sharedScreenModel.songRhythm.collectAsState() + Text(text = songAuthor, fontStyle = FontStyle.Italic) + Text(text = songRhythm) + Text(text = songComposer) + + } } } + VerticalScrollbar( + adapter = rememberScrollbarAdapter(scrollState), + modifier = Modifier.fillMaxHeight(0.5f).background(Color.Green).align(Alignment.CenterEnd) + ) } } @Throws(ObjectStreamException::class) // C'est une méthode de sérialisation Java, donc l'exception est nécessaire diff --git a/composeApp/src/commonMain/kotlin/mg/dot/feufaro/solfa/TimeUnitObject.kt b/composeApp/src/commonMain/kotlin/mg/dot/feufaro/solfa/TimeUnitObject.kt index ef5a1f0..361ee70 100644 --- a/composeApp/src/commonMain/kotlin/mg/dot/feufaro/solfa/TimeUnitObject.kt +++ b/composeApp/src/commonMain/kotlin/mg/dot/feufaro/solfa/TimeUnitObject.kt @@ -21,7 +21,6 @@ import androidx.compose.ui.draw.drawWithContent import androidx.compose.ui.geometry.Offset import androidx.compose.foundation.Canvas import androidx.compose.foundation.combinedClickable -import androidx.compose.foundation.lazy.grid.itemsIndexed import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.onSizeChanged import androidx.compose.ui.platform.LocalDensity @@ -509,8 +508,7 @@ fun LazyVerticalGridTUO( viewModel: GridTUOData, gridWidthPx: Int, onGridWidthMeasured: (Int) -> Unit, - modifier: Modifier = Modifier, - lazyGridState: LazyGridState + modifier: Modifier = Modifier ) { val regexMeasure = Regex("(\\d)/\\d").find(viewModel.measure) val tuoList = viewModel.tuoList @@ -529,8 +527,8 @@ fun LazyVerticalGridTUO( val itemMinBaseWidth = bestTUOWidth(tuoList) val gridWidthDp = with(density) { gridWidthPx.toDp() } - val (gridCells: GridCells, gridColumnCount: Int) = remember(gridWidthDp, itemMinBaseWidth, columnGroup) { - if (gridWidthDp == 0.dp) return@remember Pair(GridCells.Fixed(columnGroup), columnGroup) + val gridColumnCount: Int = remember(gridWidthDp, itemMinBaseWidth, columnGroup) { + if (gridWidthDp == 0.dp) return@remember columnGroup var calculatedCols = (gridWidthDp / (itemMinBaseWidth + horizontalArrangementSpacing)).toInt() if (calculatedCols == 0) calculatedCols = columnGroup @@ -539,24 +537,24 @@ fun LazyVerticalGridTUO( if (calculatedCols == 0) calculatedCols = columnGroup } val actualColumnCount: Int = calculatedCols.coerceAtLeast(columnGroup) - Pair(GridCells.Fixed(actualColumnCount), actualColumnCount) + actualColumnCount } + val flowRowSize: Float = 0.98f / gridColumnCount val currentStanza = viewModel.stanza - LazyVerticalGrid( - columns = gridCells, - modifier = Modifier.fillMaxWidth().heightIn(max = 800.dp), + FlowRow( + modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(horizontalArrangementSpacing), verticalArrangement = Arrangement.spacedBy(8.dp), - contentPadding = PaddingValues(8.dp), // c'est juste le padding extérieur de toute la liste - state = lazyGridState + //contentPadding = PaddingValues(8.dp), // c'est juste le padding extérieur de toute la liste + // state = lazyGridState ) { - itemsIndexed(items = tuoList.drop(1), key = { _, it -> it.numBlock }) { relativeIndex, oneTUO -> + tuoList.drop(n=1).forEachIndexed { relativeIndex, oneTUO -> Box( modifier = Modifier - .fillMaxWidth() + .fillMaxWidth(flowRowSize) .combinedClickable( onClick = { println("Clicked: ${oneTUO.numBlock} / relative index: $relativeIndex")