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:
parent
c69144fac2
commit
7ea9d08cb3
1 changed files with 119 additions and 19 deletions
|
|
@ -3,9 +3,6 @@ package mg.dot.feufaro.solfa
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.foundation.layout.*
|
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.ui.Modifier
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.LocalTextStyle
|
import androidx.compose.material3.LocalTextStyle
|
||||||
|
|
@ -46,7 +43,7 @@ import SharedScreenModel
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.text.TextMeasurer
|
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_TRIOLET_COLOR = Color.DarkGray
|
||||||
val FEUFAROO_KEY_CHANGE_COLOR = Color.Blue
|
val FEUFAROO_KEY_CHANGE_COLOR = Color.Blue
|
||||||
|
|
@ -270,7 +267,7 @@ fun TimeUnitComposable(
|
||||||
val hairPinSymbol = tuo.hasHairPin()
|
val hairPinSymbol = tuo.hasHairPin()
|
||||||
val yHeight = with(density) { lineHeightDp.toPx()}
|
val yHeight = with(density) { lineHeightDp.toPx()}
|
||||||
|
|
||||||
if (tuo.isTriolet()) {
|
/*if (tuo.isTriolet()) {
|
||||||
Canvas(modifier = Modifier.fillMaxSize()) {
|
Canvas(modifier = Modifier.fillMaxSize()) {
|
||||||
val arcWidth = with(density) { size.width * 0.75f}
|
val arcWidth = with(density) { size.width * 0.75f}
|
||||||
drawArc(
|
drawArc(
|
||||||
|
|
@ -324,8 +321,8 @@ fun TimeUnitComposable(
|
||||||
}
|
}
|
||||||
if (text.contains("p")) {
|
if (text.contains("p")) {
|
||||||
fontWeight = FontWeight.Bold
|
fontWeight = FontWeight.Bold
|
||||||
}
|
}*/
|
||||||
AutoResizingText(
|
/*AutoResizingText(
|
||||||
text = text,
|
text = text,
|
||||||
minFontSize = 18.sp,
|
minFontSize = 18.sp,
|
||||||
maxFontSize = 18.sp,
|
maxFontSize = 18.sp,
|
||||||
|
|
@ -333,7 +330,7 @@ fun TimeUnitComposable(
|
||||||
fontStyle = fontStyle,
|
fontStyle = fontStyle,
|
||||||
fontWeight = fontWeight,
|
fontWeight = fontWeight,
|
||||||
modifier = Modifier.fillMaxWidth()
|
modifier = Modifier.fillMaxWidth()
|
||||||
.height(lineHeightDp))
|
.height(lineHeightDp))*/
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -587,6 +584,99 @@ fun LazyVerticalGridTUO(
|
||||||
){
|
){
|
||||||
measures.forEachIndexed { measureIndex, measureTUOs ->
|
measures.forEachIndexed { measureIndex, measureTUOs ->
|
||||||
Column(modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp)) {
|
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()) {
|
Row(modifier = Modifier.fillMaxWidth()) {
|
||||||
measureTUOs.forEachIndexed { indexInMeasure, oneTUO ->
|
measureTUOs.forEachIndexed { indexInMeasure, oneTUO ->
|
||||||
val globalIndex = (measureIndex * gridColumnCount) + indexInMeasure
|
val globalIndex = (measureIndex * gridColumnCount) + indexInMeasure
|
||||||
|
|
@ -644,13 +734,13 @@ fun LazyVerticalGridTUO(
|
||||||
val isTooLong = textWidthDp > containerWidthDp
|
val isTooLong = textWidthDp > containerWidthDp
|
||||||
|
|
||||||
val spacer = makeSpaceBetweenSyllables(textMeasurer, gridWidthDp / gridColumnCount)
|
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(
|
||||||
text = dynamicSpaceSyl,
|
text = dynamicSpaceSyl,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(end = 4.dp)
|
.padding(end = 4.dp)/*.border(1.dp, Color.Yellow, RectangleShape)*/
|
||||||
.wrapContentSize(unbounded = true, align = Alignment.Center,),
|
.wrapContentSize(unbounded = true, align = alignText),
|
||||||
softWrap = false,
|
softWrap = false,
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
overflow = TextOverflow.Visible,
|
overflow = TextOverflow.Visible,
|
||||||
|
|
@ -683,34 +773,43 @@ fun makeSpaceBetweenSyllables(
|
||||||
textMeasurer: TextMeasurer,
|
textMeasurer: TextMeasurer,
|
||||||
noteWidthDp: Dp,
|
noteWidthDp: Dp,
|
||||||
fontSize: TextUnit = 16.sp
|
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 density = LocalDensity.current
|
||||||
val noteWidthPx = with(density) { noteWidthDp.toPx() }
|
val noteWidthPx = with(density) { noteWidthDp.toPx() }
|
||||||
val style = TextStyle(fontSize = fontSize)
|
val style = TextStyle(fontSize = fontSize)
|
||||||
val spaceWidthPx = textMeasurer.measure("\u00A0", style).size.width
|
val spaceWidthPx = textMeasurer.measure("\u00A0", style).size.width
|
||||||
|
|
||||||
|
|
||||||
return { currentSyl, allT, s_i, index ->
|
return { currentSyl, allT, s_i, index ->
|
||||||
if (currentSyl.isEmpty()) ""
|
var textAlign = Alignment.Center
|
||||||
|
if (currentSyl.isEmpty()) "" to textAlign
|
||||||
else {
|
else {
|
||||||
val currentWidth = textMeasurer.measure(currentSyl, style).size.width
|
val currentWidth = textMeasurer.measure(currentSyl, style).size.width
|
||||||
val next_syl = allT.getOrNull(s_i + 1)?.getOrNull(index) ?: ""
|
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 prev_syl = if (s_i > 0) allT.getOrNull(s_i - 1)?.getOrNull(index) ?: "" else ""
|
||||||
|
|
||||||
val excessPx = currentWidth - noteWidthPx
|
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) ?: ""
|
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 {
|
val totalSpacesPossible = (noteWidthPx / spaceWidthPx).toInt()
|
||||||
excessPx > 0 && next_syl.length < prev_syl.length -> {
|
val paddingNeeded = totalSpacesPossible - (currentSyl.length+4)
|
||||||
// Ici, currentSyl se décale à gauche.
|
val resultText = when {
|
||||||
|
!isExcess && (paddingNeeded > 0) -> {
|
||||||
|
textAlign = Alignment.TopStart
|
||||||
|
currentSyl + "\u00A0".repeat(paddingNeeded)
|
||||||
|
}
|
||||||
|
isExcess && next_syl.length < prev_syl.length -> {
|
||||||
"\u00A0".repeat(neededSpaces) + currentSyl
|
"\u00A0".repeat(neededSpaces) + currentSyl
|
||||||
}
|
}
|
||||||
excessPx > 0 && next_syl.length >= prev_syl.length -> {
|
isExcess && next_syl.length >= prev_syl.length -> {
|
||||||
currentSyl + "\u00A0".repeat(neededSpaces)
|
currentSyl + "\u00A0".repeat(neededSpaces)
|
||||||
}
|
}
|
||||||
|
|
||||||
next_syl.isNotEmpty() -> {
|
isExcess && next_syl.isNotEmpty() -> {
|
||||||
val nextWidth = textMeasurer.measure(next_syl, style).size.width
|
val nextWidth = textMeasurer.measure(next_syl, style).size.width
|
||||||
val nextExcess = nextWidth - noteWidthPx
|
val nextExcess = nextWidth - noteWidthPx
|
||||||
|
|
||||||
|
|
@ -725,6 +824,7 @@ fun makeSpaceBetweenSyllables(
|
||||||
|
|
||||||
else -> currentSyl
|
else -> currentSyl
|
||||||
}
|
}
|
||||||
|
resultText to textAlign
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Add table
Reference in a new issue