Optimize & sync with measure(multiple) column count on TUO
This commit is contained in:
parent
b6f370504e
commit
91e9af73cc
1 changed files with 99 additions and 25 deletions
|
|
@ -445,31 +445,87 @@ data class TUOWidthMeasure(val width: Dp, val isReady: Boolean)
|
||||||
data class HairpinRange(val startBlock: Int, val endBlock: Int, val symbol: Char)
|
data class HairpinRange(val startBlock: Int, val endBlock: Int, val symbol: Char)
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun bestTUOWidth(items: List<TimeUnitObject>): TUOWidthMeasure {
|
fun bestTUOWidth(
|
||||||
|
items: List<TimeUnitObject>,
|
||||||
|
stanzaNumber: Int = 1,
|
||||||
|
transpositionInterval: Int = 0,
|
||||||
|
noteStyle: TextStyle = MaterialTheme.typography.bodyLarge,
|
||||||
|
reducedLyricStyle: TextStyle = MaterialTheme.typography.labelLarge
|
||||||
|
): TUOWidthMeasure {
|
||||||
val textMeasurer = rememberTextMeasurer()
|
val textMeasurer = rememberTextMeasurer()
|
||||||
val density = LocalDensity.current
|
val density = LocalDensity.current
|
||||||
|
|
||||||
var maxWidth by remember(items) { mutableStateOf(0.dp) }
|
var maxWidth by remember(items, noteStyle, transpositionInterval) {
|
||||||
var isReady by remember(items) { mutableStateOf(false) }
|
mutableStateOf(0.dp)
|
||||||
LaunchedEffect(items) {
|
}
|
||||||
|
var isReady by remember(items, noteStyle, transpositionInterval) {
|
||||||
|
mutableStateOf(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
LaunchedEffect(items, noteStyle, transpositionInterval) {
|
||||||
isReady = false
|
isReady = false
|
||||||
maxWidth = 0.dp
|
var max = 0.dp
|
||||||
items.forEach {
|
// println("=== [DEBUG TUO] Début mesure de ${items.size} blocs TUO ===")
|
||||||
val textLayoutResult: TextLayoutResult = textMeasurer.measure(
|
|
||||||
text = it.noteAsMultiString(),
|
items.forEach { tuo ->
|
||||||
maxLines = 1
|
val rawNotes = tuo.noteAsMultiString()
|
||||||
|
val transposedNotes = Transpose.transposeText(text = rawNotes, interval = transpositionInterval)
|
||||||
|
val noteLines = transposedNotes.lines()
|
||||||
|
var maxNoteWidthPx = 0
|
||||||
|
|
||||||
|
noteLines.forEachIndexed { lineIdx, line ->
|
||||||
|
val annotatedNote = parseNoteToAnnotatedString(line)
|
||||||
|
val noteResult = textMeasurer.measure(
|
||||||
|
text = annotatedNote,
|
||||||
|
style = noteStyle,
|
||||||
|
maxLines = 1,
|
||||||
|
softWrap = false
|
||||||
)
|
)
|
||||||
val textWidth = with(density) {
|
val widthPx = noteResult.size.width
|
||||||
textLayoutResult.size.width.toDp()
|
if (widthPx > maxNoteWidthPx) {
|
||||||
|
maxNoteWidthPx = widthPx
|
||||||
}
|
}
|
||||||
if (textWidth > maxWidth) {
|
// println("TUO #${tuo.getNum()} | Ligne $lineIdx | Brut: \"$line\" | Annoté: \"${annotatedNote.text}\" -> Largeur: ${widthPx}px")
|
||||||
maxWidth = textWidth
|
}
|
||||||
|
|
||||||
|
val tuoMaxWidthDp = with(density) { maxNoteWidthPx.toDp() }
|
||||||
|
// println("--> TUO #${tuo.getNum()} | Largeur max du bloc: $tuoMaxWidthDp ou ${maxNoteWidthPx}px")
|
||||||
|
|
||||||
|
if (tuoMaxWidthDp > max) {
|
||||||
|
max = tuoMaxWidthDp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
maxWidth = max
|
||||||
isReady = true
|
isReady = true
|
||||||
|
// println("=== [DEBUG TUO] Largeur retenue (maxWidth finale) : $maxWidth ===")
|
||||||
}
|
}
|
||||||
return TUOWidthMeasure(maxWidth + 13.dp, isReady)
|
|
||||||
|
return TUOWidthMeasure(maxWidth, isReady)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun parseNoteToAnnotatedString(
|
||||||
|
rawNote: String,
|
||||||
|
superscriptStyle: SpanStyle = SpanStyle(
|
||||||
|
fontSize = 10.sp,
|
||||||
|
baselineShift = BaselineShift.Superscript
|
||||||
|
)
|
||||||
|
): AnnotatedString {
|
||||||
|
return buildAnnotatedString {
|
||||||
|
val parts = rawNote.split(">")
|
||||||
|
parts.forEachIndexed { index, text ->
|
||||||
|
if (index % 2 == 1) {
|
||||||
|
withStyle(superscriptStyle) {
|
||||||
|
append(text + " ")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
append(text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun AutoResizingText(
|
fun AutoResizingText(
|
||||||
text: String,
|
text: String,
|
||||||
|
|
@ -591,11 +647,20 @@ fun LazyVerticalGridTUO(
|
||||||
focusRequester.requestFocus()
|
focusRequester.requestFocus()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
val numerator = viewModel.measure.substringBefore("/").toIntOrNull() ?: 4
|
||||||
|
val multiple = when (numerator) {
|
||||||
|
2, 4, 8, 10 -> 4
|
||||||
|
3, 6, 9, 12 -> 3
|
||||||
|
else -> 4
|
||||||
|
}
|
||||||
val density = LocalDensity.current
|
val density = LocalDensity.current
|
||||||
val horizontalArrangementSpacing: Dp = 0.dp
|
val horizontalArrangementSpacing: Dp = 0.dp
|
||||||
val columnGroupString = regexMeasure?.groupValues?.get(1) ?: "1"
|
val columnGroupString = regexMeasure?.groupValues?.get(1) ?: "1"
|
||||||
val columnGroup = columnGroupString.toInt().coerceAtLeast(1)
|
val columnGroup = columnGroupString.toInt().coerceAtLeast(1)
|
||||||
val tuoWidthMeasure = bestTUOWidth(tuoList)
|
val tuoWidthMeasure = bestTUOWidth(
|
||||||
|
items = tuoList,
|
||||||
|
noteStyle = MaterialTheme.typography.bodyLarge
|
||||||
|
)
|
||||||
val itemMinBaseWidth = tuoWidthMeasure.width
|
val itemMinBaseWidth = tuoWidthMeasure.width
|
||||||
val gridWidthDp = with(density) { gridWidthPx.toDp() }
|
val gridWidthDp = with(density) { gridWidthPx.toDp() }
|
||||||
|
|
||||||
|
|
@ -604,18 +669,27 @@ fun LazyVerticalGridTUO(
|
||||||
|
|
||||||
val gridCount by sharedScreenModel.gridCount.collectAsState()
|
val gridCount by sharedScreenModel.gridCount.collectAsState()
|
||||||
|
|
||||||
var gridColumnCount: Int = remember(gridWidthDp, itemMinBaseWidth, columnGroup) {
|
var gridColumnCount: Int = remember(gridWidthDp, tuoWidthMeasure.isReady, tuoWidthMeasure.width, multiple) {
|
||||||
if (gridWidthDp == 0.dp) return@remember columnGroup
|
if (!tuoWidthMeasure.isReady || gridWidthDp <= 0.dp || tuoWidthMeasure.width <= 0.dp) {
|
||||||
var calculatedCols =
|
return@remember multiple
|
||||||
(gridWidthDp / (itemMinBaseWidth + horizontalArrangementSpacing)).toInt()
|
|
||||||
if (calculatedCols == 0) calculatedCols = columnGroup
|
|
||||||
if (calculatedCols % columnGroup != 0) {
|
|
||||||
calculatedCols = (calculatedCols / columnGroup) * columnGroup
|
|
||||||
if (calculatedCols == 0) calculatedCols = columnGroup
|
|
||||||
}
|
}
|
||||||
val actualColumnCount: Int = calculatedCols.coerceAtLeast(columnGroup)
|
|
||||||
actualColumnCount
|
val rawCapacity = (gridWidthDp + 9.dp) / tuoWidthMeasure.width
|
||||||
|
val rawColsInt = rawCapacity.toInt()
|
||||||
|
val roundedToMultiple = (rawColsInt / multiple) * multiple
|
||||||
|
val finalCols = roundedToMultiple.coerceAtLeast(multiple)
|
||||||
|
|
||||||
|
// println("Largeur écran/grille : $gridWidthDp")
|
||||||
|
// println("Largeur bloc TUO max : ${tuoWidthMeasure.width}")
|
||||||
|
// println("Signature temps (multiple) : $multiple")
|
||||||
|
// println("Capacité brute d'accueil : $rawCapacity blocs ($rawColsInt entiers)")
|
||||||
|
// println("Arrondi au multiple inférieur : $roundedToMultiple colonnes")
|
||||||
|
// println("Nombre final retenu (min $multiple) : $finalCols colonnes")
|
||||||
|
// println("=========================")
|
||||||
|
|
||||||
|
finalCols
|
||||||
}
|
}
|
||||||
|
|
||||||
gridColumnCount += gridCount
|
gridColumnCount += gridCount
|
||||||
val flowRowSize: Float = 0.98f / gridColumnCount
|
val flowRowSize: Float = 0.98f / gridColumnCount
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue