Move all markers in the new Row separated like lyrics to resolve 'ffpm-657-1 4/4 Miadana kely' & ffpm-211 (markers)

This commit is contained in:
hasina 2026-02-02 15:36:11 +03:00
parent c69144fac2
commit 7ea9d08cb3

View file

@ -3,9 +3,6 @@ package mg.dot.feufaro.solfa
import androidx.compose.foundation.background
import androidx.compose.runtime.Composable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyGridState
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.ui.Modifier
import androidx.compose.material3.Text
import androidx.compose.material3.LocalTextStyle
@ -46,7 +43,7 @@ import SharedScreenModel
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.text.TextMeasurer
import kotlinx.coroutines.delay
import androidx.compose.ui.text.style.TextAlign
val FEUFAROO_TRIOLET_COLOR = Color.DarkGray
val FEUFAROO_KEY_CHANGE_COLOR = Color.Blue
@ -270,7 +267,7 @@ fun TimeUnitComposable(
val hairPinSymbol = tuo.hasHairPin()
val yHeight = with(density) { lineHeightDp.toPx()}
if (tuo.isTriolet()) {
/*if (tuo.isTriolet()) {
Canvas(modifier = Modifier.fillMaxSize()) {
val arcWidth = with(density) { size.width * 0.75f}
drawArc(
@ -324,8 +321,8 @@ fun TimeUnitComposable(
}
if (text.contains("p")) {
fontWeight = FontWeight.Bold
}
AutoResizingText(
}*/
/*AutoResizingText(
text = text,
minFontSize = 18.sp,
maxFontSize = 18.sp,
@ -333,7 +330,7 @@ fun TimeUnitComposable(
fontStyle = fontStyle,
fontWeight = fontWeight,
modifier = Modifier.fillMaxWidth()
.height(lineHeightDp))
.height(lineHeightDp))*/
}
@ -587,6 +584,99 @@ fun LazyVerticalGridTUO(
){
measures.forEachIndexed { measureIndex, measureTUOs ->
Column(modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp)) {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically
) {
measureTUOs.forEachIndexed { indexInMeasure, tuo ->
Column(
modifier = Modifier
.weight(1f)
) {
if (TimeUnitObject._hasMarker) {
val lineHeight = 20.sp
val density = LocalDensity.current
val lineHeightDp : Dp = with(density) {
lineHeight.toDp()
}
var fontStyle = FontStyle.Normal
var fontWeight = FontWeight.Normal
val hairPinSymbol = tuo.hasHairPin()
val yHeight = with(density) { lineHeightDp.toPx()}
if (tuo.isTriolet()) {
Canvas(modifier = Modifier.fillMaxSize()) {
val arcWidth = with(density) { size.width * 0.75f}
drawArc(
color = FEUFAROO_TRIOLET_COLOR,
startAngle = 200f,
sweepAngle = 140f,
useCenter = false,
topLeft = Offset(0f, yHeight / 2),
size = Size(arcWidth, yHeight),
style = Stroke(width = 2f)
)
}
}
if ((hairPinSymbol == '=') && (TimeUnitObject.lastHairPinSymbol != null)) {
println("LastHairpin: ${TimeUnitObject.lastHairPinSymbol} ${TimeUnitObject.lastHairPinStart}")
val hairPinStart = TimeUnitObject.lastHairPinStart
val lastHairPinSymbol = TimeUnitObject.lastHairPinSymbol
val hairPinStartLine: Int = (hairPinStart - 1) / gridColumnCount
val hairPinEndLine: Int = (tuo.numBlock - 1) / gridColumnCount
if (hairPinStartLine == hairPinEndLine) {
Canvas(
modifier = Modifier.fillMaxSize()
) {
val xStart = if (lastHairPinSymbol == '>') -size.width * (tuo.numBlock - hairPinStart) else size.width/2
val xEnd = if (lastHairPinSymbol == '>') size.width/2 else -size.width * (tuo.numBlock - hairPinStart)
drawLine(
Color.DarkGray,
start = Offset(x=xStart, y=0f),
end = Offset(xEnd, yHeight/2)
)
drawLine(
Color.DarkGray,
start = Offset(xStart, yHeight),
end = Offset(xEnd, yHeight/2)
)
}
TimeUnitObject.endHairPin()
}
}
if (hairPinSymbol != null && hairPinSymbol != '=') {
TimeUnitObject.startHairPin(hairPinSymbol, tuo.numBlock)
}
// @todo pTemplate.markerToString retourne les marqueurs comme une seule chaîne
// problème si template = $QD:,-$QD
tuo.pTemplate.resetCalledMarker()
val text = tuo.pTemplate.markerToString()
if (text.contains(Regex("^([mfp]+|[rR]it.*)$"))) {
fontStyle = FontStyle.Italic
}
if (text.contains(Regex("^\\s*(ppp|pp|p|mp|mf|f|ff|fff)\\s*$"))) {
fontWeight = FontWeight.Bold
}
Text(text = text,
modifier = Modifier
.wrapContentSize(unbounded = true, align = Alignment.CenterStart,),
softWrap = false,
maxLines = 1,
fontStyle = fontStyle,
fontWeight = fontWeight,
style = TextStyle(
color = Color.Black,
fontSize = 17.sp
)
)
}
}
}
}
Row(modifier = Modifier.fillMaxWidth()) {
measureTUOs.forEachIndexed { indexInMeasure, oneTUO ->
val globalIndex = (measureIndex * gridColumnCount) + indexInMeasure
@ -644,13 +734,13 @@ fun LazyVerticalGridTUO(
val isTooLong = textWidthDp > containerWidthDp
val spacer = makeSpaceBetweenSyllables(textMeasurer, gridWidthDp / gridColumnCount)
val dynamicSpaceSyl = spacer(syl, allTemps, syls_i, index)
val (dynamicSpaceSyl, alignText) = spacer(syl, allTemps, syls_i, index)
Text(
text = dynamicSpaceSyl,
modifier = Modifier
.fillMaxWidth()
.padding(end = 4.dp)
.wrapContentSize(unbounded = true, align = Alignment.Center,),
.padding(end = 4.dp)/*.border(1.dp, Color.Yellow, RectangleShape)*/
.wrapContentSize(unbounded = true, align = alignText),
softWrap = false,
maxLines = 1,
overflow = TextOverflow.Visible,
@ -683,34 +773,43 @@ fun makeSpaceBetweenSyllables(
textMeasurer: TextMeasurer,
noteWidthDp: Dp,
fontSize: TextUnit = 16.sp
): (String, List<List<String>>, Int, Int) -> String {
): (String, List<List<String>>, Int, Int) -> Pair<String, Alignment> {
val density = LocalDensity.current
val noteWidthPx = with(density) { noteWidthDp.toPx() }
val style = TextStyle(fontSize = fontSize)
val spaceWidthPx = textMeasurer.measure("\u00A0", style).size.width
return { currentSyl, allT, s_i, index ->
if (currentSyl.isEmpty()) ""
var textAlign = Alignment.Center
if (currentSyl.isEmpty()) "" to textAlign
else {
val currentWidth = textMeasurer.measure(currentSyl, style).size.width
val next_syl = allT.getOrNull(s_i + 1)?.getOrNull(index) ?: ""
val prev_syl = if (s_i > 0) allT.getOrNull(s_i - 1)?.getOrNull(index) ?: "" else ""
val excessPx = currentWidth - noteWidthPx
val neededSpaces = if (excessPx > 0) (excessPx / spaceWidthPx).toInt() + 1 else 0
val isExcess = (excessPx > 0)
val neededSpaces = if (isExcess) (excessPx / spaceWidthPx).toInt() + 1 else 0
val nextNextSyl = allT.getOrNull(s_i + 2)?.getOrNull(index) ?: ""
// println("801: prev: [$prev_syl]${prev_syl.length}:[${textMeasurer.measure(prev_syl, style).size.width}], current [$currentSyl]:[${textMeasurer.measure(currentSyl, style).size.width}], next [$next_syl]:[${textMeasurer.measure(next_syl, style).size.width}], isExcess=$excessPx & need $neededSpaces \t spwp $spaceWidthPx\n")
when {
excessPx > 0 && next_syl.length < prev_syl.length -> {
// Ici, currentSyl se décale à gauche.
val totalSpacesPossible = (noteWidthPx / spaceWidthPx).toInt()
val paddingNeeded = totalSpacesPossible - (currentSyl.length+4)
val resultText = when {
!isExcess && (paddingNeeded > 0) -> {
textAlign = Alignment.TopStart
currentSyl + "\u00A0".repeat(paddingNeeded)
}
isExcess && next_syl.length < prev_syl.length -> {
"\u00A0".repeat(neededSpaces) + currentSyl
}
excessPx > 0 && next_syl.length >= prev_syl.length -> {
isExcess && next_syl.length >= prev_syl.length -> {
currentSyl + "\u00A0".repeat(neededSpaces)
}
next_syl.isNotEmpty() -> {
isExcess && next_syl.isNotEmpty() -> {
val nextWidth = textMeasurer.measure(next_syl, style).size.width
val nextExcess = nextWidth - noteWidthPx
@ -725,6 +824,7 @@ fun makeSpaceBetweenSyllables(
else -> currentSyl
}
resultText to textAlign
}
}
}