Compare commits
No commits in common. "6b8ce0cecf05ed10eb9b240aba7abec983b2c89e" and "a5977d5dd105174cb2dfea24103358f833f1bfe0" have entirely different histories.
6b8ce0cecf
...
a5977d5dd1
6 changed files with 75 additions and 316 deletions
|
|
@ -384,27 +384,13 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository
|
||||||
// println("fullLine = '$fullLine'")
|
// println("fullLine = '$fullLine'")
|
||||||
|
|
||||||
val afterU0 = fullLine.substringAfter("U0:")
|
val afterU0 = fullLine.substringAfter("U0:")
|
||||||
val blankPrefixRegex = Regex("^(.*?z)([0-9A-Z_+\\-]+)(:)")
|
val blankPrefixRegex = Regex("^(.*?z[0-9A-Z]:)")
|
||||||
val match = blankPrefixRegex.find(afterU0)
|
val match = blankPrefixRegex.find(afterU0)
|
||||||
var blankPrefix: String = ""
|
val blankPrefix = match?.value ?: ""
|
||||||
var body: String = ""
|
val body = if (match != null) {
|
||||||
if (match != null) {
|
afterU0.substring(blankPrefix.length)
|
||||||
body = afterU0.substring(blankPrefix.length)
|
|
||||||
|
|
||||||
if (editState.silentDuration == "-1") {
|
|
||||||
blankPrefix = match.value
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
println("voici ${match.groupValues.joinToString(",")}")
|
|
||||||
val beforeDuration = match.groups[1]?.value ?: ""
|
|
||||||
val restOfSilenceBlock = match.groups[3]?.value ?: ":"
|
|
||||||
|
|
||||||
blankPrefix = "$beforeDuration${editState.silentDuration}$restOfSilenceBlock"
|
|
||||||
}
|
|
||||||
body = afterU0.substring(match.value.length)
|
|
||||||
} else {
|
} else {
|
||||||
blankPrefix = afterU0.substringBefore(":") + ":"
|
afterU0
|
||||||
body = afterU0.substringAfter(":")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val measure = measureString.split("/")[0].toIntOrNull() ?: 4
|
val measure = measureString.split("/")[0].toIntOrNull() ?: 4
|
||||||
|
|
@ -520,26 +506,29 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository
|
||||||
val fullPath = directory + fileName
|
val fullPath = directory + fileName
|
||||||
val rawIncludedContent = fileRepository.readFileLines(fullPath)
|
val rawIncludedContent = fileRepository.readFileLines(fullPath)
|
||||||
|
|
||||||
if (parts.size > 2 && parts[2].isNotEmpty()) {
|
if (parts.size > 2 && parts[2].startsWith("^")) {
|
||||||
val regexIgnoreString = parts[2]
|
val patternInside = parts[2]
|
||||||
|
.substringAfter("(", "")
|
||||||
|
.substringBefore(")", "")
|
||||||
|
|
||||||
val ignoredLinesRegex = try {
|
val prefixesToIgnore = if (patternInside.isNotEmpty()) {
|
||||||
Regex(regexIgnoreString)
|
patternInside.split("|")
|
||||||
} catch (e: Exception) {
|
} else {
|
||||||
Regex("^:")
|
listOf(parts[2].substring(1))
|
||||||
}
|
}
|
||||||
|
|
||||||
val filteredLines = rawIncludedContent.filter { incLine ->
|
val filteredLines = rawIncludedContent.filter { incLine ->
|
||||||
ignoredLinesRegex.find(incLine) == null
|
prefixesToIgnore.none { prefix ->
|
||||||
|
incLine.trim().startsWith(prefix)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lineBuilder.append(filteredLines.joinToString("\n"))
|
lineBuilder.append(filteredLines.joinToString("\n"))
|
||||||
} else {
|
} else {
|
||||||
lineBuilder.append(rawIncludedContent.joinToString("\n"))
|
lineBuilder.append(rawIncludedContent.joinToString("\n"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
lineBuilder.append("// Erreur inclusion: ${e.message}")
|
lineBuilder.append("// Erreur: ${e.message}")
|
||||||
}
|
}
|
||||||
lastIndex = match.range.last + 1
|
lastIndex = match.range.last + 1
|
||||||
}
|
}
|
||||||
|
|
@ -779,12 +768,6 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository
|
||||||
newMarkerValue: String,
|
newMarkerValue: String,
|
||||||
editState: TUOEditState
|
editState: TUOEditState
|
||||||
): String {
|
): String {
|
||||||
/* On ne modifie pas le template tant que les notes ne sont pas modifiées
|
|
||||||
* Et tant qu'une marker est ajouter */
|
|
||||||
if (newMarkerValue.isEmpty()) {
|
|
||||||
println("Aucune modification détectée (marqueur vide), on retourne le template original.")
|
|
||||||
return templateLine
|
|
||||||
}
|
|
||||||
val isT0 = templateLine.startsWith("T0")
|
val isT0 = templateLine.startsWith("T0")
|
||||||
|
|
||||||
val prefix: String
|
val prefix: String
|
||||||
|
|
@ -1308,7 +1291,6 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository
|
||||||
var lookK = k
|
var lookK = k
|
||||||
var lookC = charIdx + 1
|
var lookC = charIdx + 1
|
||||||
var searching = true
|
var searching = true
|
||||||
var crossedParenthesis = false
|
|
||||||
|
|
||||||
while (searching) {
|
while (searching) {
|
||||||
if (lookC >= buff[lookK].length) {
|
if (lookC >= buff[lookK].length) {
|
||||||
|
|
@ -1335,28 +1317,20 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository
|
||||||
lookC++
|
lookC++
|
||||||
}
|
}
|
||||||
|
|
||||||
next == '(' || next == ')' -> {
|
|
||||||
crossedParenthesis = true
|
|
||||||
lookC++
|
|
||||||
}
|
|
||||||
next == 'z' && lookK == k && char == 'D' -> {
|
next == 'z' && lookK == k && char == 'D' -> {
|
||||||
if (crossedParenthesis) {
|
var hasFutureResonance = false
|
||||||
searching = false
|
if (k + 1 < buff.size) {
|
||||||
|
if (buff[k + 1].replace(Regex("\\$\\{.*?\\}|\\$."), "")
|
||||||
|
.startsWith("-")
|
||||||
|
) hasFutureResonance = true
|
||||||
|
}
|
||||||
|
if (!hasFutureResonance && currentStr.contains(".") && currentStr.contains(",")) {
|
||||||
|
val resDur = getDurationAt(currentStr, lookC, k)
|
||||||
|
totalDuration += resDur
|
||||||
|
consumedGlobally.add(lookK to lookC)
|
||||||
|
lookC++
|
||||||
} else {
|
} else {
|
||||||
var hasFutureResonance = false
|
searching = false
|
||||||
if (k + 1 < buff.size) {
|
|
||||||
if (buff[k + 1].replace(Regex("\\$\\{.*?\\}|\\$."), "")
|
|
||||||
.startsWith("-")
|
|
||||||
) hasFutureResonance = true
|
|
||||||
}
|
|
||||||
if (!hasFutureResonance && currentStr.contains(".") && currentStr.contains(",")) {
|
|
||||||
val resDur = getDurationAt(currentStr, lookC, k)
|
|
||||||
totalDuration += resDur
|
|
||||||
consumedGlobally.add(lookK to lookC)
|
|
||||||
lookC++
|
|
||||||
} else {
|
|
||||||
searching = false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1437,15 +1411,6 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
val cleanedBlocks = buff2.map { it.replace(" ", "") }
|
val cleanedBlocks = buff2.map { it.replace(" ", "") }
|
||||||
/*val durationModifierRegex = Regex("^(.*?z)[0-9A-Z_+\\-](:|/)")
|
|
||||||
val match = durationModifierRegex.find(prefix)
|
|
||||||
|
|
||||||
val newPrefix = if (match != null) {
|
|
||||||
val beforeDuration = match.groups[1]?.value ?: ""
|
|
||||||
val separator = match.groups[2]?.value ?: ":"
|
|
||||||
"$beforeDuration${editState.silentDuration}$separator"
|
|
||||||
} else prefix*/
|
|
||||||
|
|
||||||
val finalLines = (prefix + cleanedBlocks.joinToString(""))
|
val finalLines = (prefix + cleanedBlocks.joinToString(""))
|
||||||
.replace("2z11", "y")
|
.replace("2z11", "y")
|
||||||
.replace("/", "/ ")
|
.replace("/", "/ ")
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,6 @@ import androidx.compose.material.icons.automirrored.filled.ArrowForward
|
||||||
import androidx.compose.material.icons.filled.Add
|
import androidx.compose.material.icons.filled.Add
|
||||||
import androidx.compose.material.icons.filled.Build
|
import androidx.compose.material.icons.filled.Build
|
||||||
import androidx.compose.material.icons.filled.Clear
|
import androidx.compose.material.icons.filled.Clear
|
||||||
import androidx.compose.material.icons.filled.KeyboardDoubleArrowLeft
|
|
||||||
import androidx.compose.material.icons.filled.KeyboardDoubleArrowRight
|
|
||||||
import androidx.compose.material3.*
|
import androidx.compose.material3.*
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
|
|
@ -65,7 +63,6 @@ fun TUODetailDialog(
|
||||||
var templateFragment by remember { mutableStateOf(editState.templateFragment) }
|
var templateFragment by remember { mutableStateOf(editState.templateFragment) }
|
||||||
|
|
||||||
var marker by remember { mutableStateOf(editState.marker) }
|
var marker by remember { mutableStateOf(editState.marker) }
|
||||||
val initialMarker = remember { editState.marker }
|
|
||||||
|
|
||||||
LaunchedEffect(notes.toMap()) {
|
LaunchedEffect(notes.toMap()) {
|
||||||
val tempState = TUOEditState(
|
val tempState = TUOEditState(
|
||||||
|
|
@ -119,79 +116,6 @@ fun TUODetailDialog(
|
||||||
horizontalArrangement = Arrangement.SpaceBetween,
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically
|
||||||
) {
|
) {
|
||||||
// Modif silence duration
|
|
||||||
if (currentIndex == 0) {
|
|
||||||
val silentDurationOrder = listOf(
|
|
||||||
"0", "4", "8", "A", "C", "E", "G", "K", "O", "S", "W"
|
|
||||||
)
|
|
||||||
Row(
|
|
||||||
modifier = Modifier.width(125.dp),
|
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
|
||||||
horizontalArrangement = Arrangement.SpaceBetween
|
|
||||||
) {
|
|
||||||
IconButton(
|
|
||||||
onClick = {
|
|
||||||
val currentIdx = silentDurationOrder.indexOf(editState.silentDuration)
|
|
||||||
val newIdx = if (currentIdx > 0) currentIdx - 1 else 0
|
|
||||||
val newDuration = silentDurationOrder[newIdx]
|
|
||||||
|
|
||||||
val state = TUOEditState(
|
|
||||||
tuoIndex = globalIndex,
|
|
||||||
notesByVoice = notes.toMap(),
|
|
||||||
originalNotes = originalNotes.toMap(),
|
|
||||||
originalLyricsByStanza = originalLyricsByStz.toMutableMap(),
|
|
||||||
lyricsByStanza = mutableMapOf(currentStanza to lyricsLines.joinToString(" ")),
|
|
||||||
templateFragment = templateFragment,
|
|
||||||
marker = if(marker != initialMarker) marker else "",
|
|
||||||
silentDuration = newDuration
|
|
||||||
)
|
|
||||||
onSave(state)
|
|
||||||
},
|
|
||||||
enabled = silentDurationOrder.indexOf(editState.silentDuration) >= 0,
|
|
||||||
modifier = Modifier.size(20.dp)
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Default.KeyboardDoubleArrowLeft,
|
|
||||||
contentDescription = "Diminuer",
|
|
||||||
tint = if (silentDurationOrder.indexOf(editState.silentDuration) > 0) Color.LightGray else Color.DarkGray
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
Text(
|
|
||||||
text = editState.silentDuration,
|
|
||||||
color = Color.White,
|
|
||||||
style = MaterialTheme.typography.bodyLarge
|
|
||||||
)
|
|
||||||
|
|
||||||
IconButton(
|
|
||||||
onClick = {
|
|
||||||
val currentIdx = silentDurationOrder.indexOf(editState.silentDuration)
|
|
||||||
val newIdx = if (currentIdx != -1 && currentIdx < silentDurationOrder.lastIndex) currentIdx + 1 else currentIdx
|
|
||||||
val newDuration = silentDurationOrder[newIdx]
|
|
||||||
|
|
||||||
val state = TUOEditState(
|
|
||||||
tuoIndex = globalIndex,
|
|
||||||
notesByVoice = notes.toMap(),
|
|
||||||
originalNotes = originalNotes.toMap(),
|
|
||||||
originalLyricsByStanza = originalLyricsByStz.toMutableMap(),
|
|
||||||
lyricsByStanza = mutableMapOf(currentStanza to lyricsLines.joinToString(" ")),
|
|
||||||
templateFragment = templateFragment,
|
|
||||||
marker = if(marker != initialMarker) marker else "",
|
|
||||||
silentDuration = newDuration
|
|
||||||
)
|
|
||||||
onSave(state)
|
|
||||||
},
|
|
||||||
enabled = silentDurationOrder.indexOf(editState.silentDuration) < silentDurationOrder.lastIndex,
|
|
||||||
modifier = Modifier.size(20.dp)
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Default.KeyboardDoubleArrowRight,
|
|
||||||
contentDescription = "Augmenter",
|
|
||||||
tint = if (silentDurationOrder.indexOf(editState.silentDuration) < silentDurationOrder.lastIndex) Color.LightGray else Color.DarkGray
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (currentIndex > 0) {
|
if (currentIndex > 0) {
|
||||||
IconButton(
|
IconButton(
|
||||||
onClick = {
|
onClick = {
|
||||||
|
|
@ -206,15 +130,15 @@ fun TUODetailDialog(
|
||||||
tint = Color.White
|
tint = Color.White
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
Text(
|
|
||||||
text = "N°$currentIndex",
|
|
||||||
fontSize = 15.sp,
|
|
||||||
fontWeight = FontWeight.Bold,
|
|
||||||
color = Color.White
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = "N°$currentIndex",
|
||||||
|
fontSize = 15.sp,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
color = Color.White
|
||||||
|
)
|
||||||
|
|
||||||
IconButton(
|
IconButton(
|
||||||
onClick = {
|
onClick = {
|
||||||
currentIndex++
|
currentIndex++
|
||||||
|
|
@ -364,9 +288,7 @@ fun TUODetailDialog(
|
||||||
if (isEditable || canAdd) {
|
if (isEditable || canAdd) {
|
||||||
IconButton(
|
IconButton(
|
||||||
onClick = {
|
onClick = {
|
||||||
if (index >= 0) {
|
if (index == 0) lyricsLines.add("_") else lyricsLines.removeAt(index)
|
||||||
if (index == 0) lyricsLines.add("_") else lyricsLines.removeAt(index)
|
|
||||||
}
|
|
||||||
}) {
|
}) {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = if (index == 0) Icons.Default.Add else Icons.Default.Clear,
|
imageVector = if (index == 0) Icons.Default.Add else Icons.Default.Clear,
|
||||||
|
|
@ -401,8 +323,7 @@ fun TUODetailDialog(
|
||||||
originalLyricsByStanza = originalLyricsByStz.toMutableMap(),
|
originalLyricsByStanza = originalLyricsByStz.toMutableMap(),
|
||||||
lyricsByStanza = mutableMapOf(currentStanza to lyricsLines.joinToString(" ")),
|
lyricsByStanza = mutableMapOf(currentStanza to lyricsLines.joinToString(" ")),
|
||||||
templateFragment = templateFragment,
|
templateFragment = templateFragment,
|
||||||
/* On ne ré-insere pas la même marker*/
|
marker = marker
|
||||||
marker = if(marker != initialMarker) marker else "",
|
|
||||||
)
|
)
|
||||||
onSave(state)
|
onSave(state)
|
||||||
},
|
},
|
||||||
|
|
@ -646,7 +567,7 @@ private fun notesToTemplate(notes: String): String {
|
||||||
.replace("si", "S")
|
.replace("si", "S")
|
||||||
.replace("ta", "T")
|
.replace("ta", "T")
|
||||||
|
|
||||||
val noteRegex = Regex("""([drmfsltDRFSTz][ia]?|[.,()\s-])""")
|
val noteRegex = Regex("""([drmfsltDRFSTz]+|[.,()\s-])""")
|
||||||
val template = StringBuilder()
|
val template = StringBuilder()
|
||||||
val matches = noteRegex.findAll(cleaned)
|
val matches = noteRegex.findAll(cleaned)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,5 @@ data class TUOEditState(
|
||||||
val lyricsByStanza: MutableMap<Int, String> = mutableMapOf(),
|
val lyricsByStanza: MutableMap<Int, String> = mutableMapOf(),
|
||||||
val originalLyricsByStanza: MutableMap<Int, String> = mutableMapOf(),
|
val originalLyricsByStanza: MutableMap<Int, String> = mutableMapOf(),
|
||||||
val templateFragment: String = "",
|
val templateFragment: String = "",
|
||||||
val marker: String = "",
|
val marker: String = ""
|
||||||
val silentDuration: String = "-1"
|
|
||||||
)
|
)
|
||||||
|
|
@ -16,11 +16,9 @@ import androidx.compose.foundation.text.BasicTextField
|
||||||
import androidx.compose.foundation.text.KeyboardOptions
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.automirrored.filled.Undo
|
import androidx.compose.material.icons.automirrored.filled.Undo
|
||||||
import androidx.compose.material.icons.filled.ArrowBackIosNew
|
|
||||||
import androidx.compose.material.icons.filled.Build
|
import androidx.compose.material.icons.filled.Build
|
||||||
import androidx.compose.material.icons.filled.Close
|
import androidx.compose.material.icons.filled.Close
|
||||||
import androidx.compose.material.icons.filled.Description
|
import androidx.compose.material.icons.filled.Description
|
||||||
import androidx.compose.material.icons.filled.KeyboardDoubleArrowLeft
|
|
||||||
import androidx.compose.material.icons.filled.Save
|
import androidx.compose.material.icons.filled.Save
|
||||||
import androidx.compose.material3.*
|
import androidx.compose.material3.*
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
|
|
@ -276,7 +274,7 @@ fun TimeUnitComposable(
|
||||||
)
|
)
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.background(animatedColor)
|
.background(/*if(gridActive) Color.Cyan.copy(alpha = 0.5f) else col*/animatedColor)
|
||||||
) {
|
) {
|
||||||
if (TimeUnitObject._hasMarker) {
|
if (TimeUnitObject._hasMarker) {
|
||||||
val lineHeight = 20.sp
|
val lineHeight = 20.sp
|
||||||
|
|
@ -843,25 +841,6 @@ fun LazyVerticalGridTUO(
|
||||||
val template = oneTUO.pTemplate.template
|
val template = oneTUO.pTemplate.template
|
||||||
val expectedTemplate = template.count { it.isLetter() } == 2 && template.contains(".")
|
val expectedTemplate = template.count { it.isLetter() } == 2 && template.contains(".")
|
||||||
|
|
||||||
val fileC = sharedScreenModel.fileContent.value ?: ""
|
|
||||||
val lines = fileC.split("\n").toMutableList()
|
|
||||||
val u0Idx = lines.indexOfFirst { it.startsWith("U0:") }
|
|
||||||
val t0Idx = lines.indexOfFirst { it.startsWith("T0:") }
|
|
||||||
|
|
||||||
val fullLine = when {
|
|
||||||
t0Idx != -1 -> {
|
|
||||||
lines[t0Idx]
|
|
||||||
}
|
|
||||||
u0Idx != -1 -> {
|
|
||||||
lines[u0Idx]
|
|
||||||
}
|
|
||||||
else -> ""
|
|
||||||
}
|
|
||||||
val afterU0T0 = fullLine.substringAfter("0:")
|
|
||||||
val blankPrefixRegex =Regex("""z([0-9A-Z])[:]""")
|
|
||||||
val match = blankPrefixRegex.find(afterU0T0)
|
|
||||||
val blankPrefix = match?.groups?.get(1)?.value ?: ""
|
|
||||||
|
|
||||||
val editState = TUOEditState(
|
val editState = TUOEditState(
|
||||||
tuoIndex = oneTUO.firstTuoIndex,
|
tuoIndex = oneTUO.firstTuoIndex,
|
||||||
notesByVoice = (0..3).associate { i ->
|
notesByVoice = (0..3).associate { i ->
|
||||||
|
|
@ -876,8 +855,7 @@ fun LazyVerticalGridTUO(
|
||||||
marker = listOfNotNull(
|
marker = listOfNotNull(
|
||||||
oneTUO.pTemplate.markerToString().takeIf { it.isNotBlank() },
|
oneTUO.pTemplate.markerToString().takeIf { it.isNotBlank() },
|
||||||
oneTUO.hasHairPin()?.toString()?.takeIf { it.isNotBlank() }
|
oneTUO.hasHairPin()?.toString()?.takeIf { it.isNotBlank() }
|
||||||
).joinToString(" "),
|
).joinToString(" ")
|
||||||
silentDuration = blankPrefix
|
|
||||||
)
|
)
|
||||||
TUODetailDialog(
|
TUODetailDialog(
|
||||||
editState = editState,
|
editState = editState,
|
||||||
|
|
@ -1296,16 +1274,12 @@ fun EditorActionButtons(isUndoVisible: Boolean, onUndo: () -> Unit, onBuild: ()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun autoFixNote(rawNote: String, template: String): String {
|
fun autoFixNote(rawNote: String, template: String): String {
|
||||||
// println("\n==================================================")
|
println("ça on a t $template => $rawNote")
|
||||||
// println(" ENTRÉE autoFixNote")
|
|
||||||
// println(" • Template : \"$template\"")
|
|
||||||
// println(" • RawNote : \"$rawNote\"")
|
|
||||||
// println("==================================================")
|
|
||||||
if (rawNote == "_") return rawNote
|
if (rawNote == "_") return rawNote
|
||||||
|
|
||||||
val noteRegex = Regex("([drmfsltDRFSTw][ia]?|―)[0-9'¹²³⁴₁₂₃₄,]*")
|
val noteRegex = Regex("([drmfsltDRFSTw][ia]?|―)[0-9'¹²³⁴₁₂₃₄,]*")
|
||||||
val actualNotes = if (rawNote.isEmpty()) emptyList() else noteRegex.findAll(rawNote).map { it.value }.toList()
|
val actualNotes = if (rawNote.isEmpty()) emptyList() else noteRegex.findAll(rawNote).map { it.value }.toList()
|
||||||
// println(" • Notes détectées dans RawNote : $actualNotes (Taille: ${actualNotes.size})")
|
|
||||||
/*if (rawNote.contains("•") || rawNote.contains("―") || rawNote.contains(",")) {
|
/*if (rawNote.contains("•") || rawNote.contains("―") || rawNote.contains(",")) {
|
||||||
val templateNotesCount = template.count { c ->
|
val templateNotesCount = template.count { c ->
|
||||||
c in 'A'..'Y' || c in 'a'..'y'
|
c in 'A'..'Y' || c in 'a'..'y'
|
||||||
|
|
@ -1315,32 +1289,24 @@ fun autoFixNote(rawNote: String, template: String): String {
|
||||||
val requiredNotesCount = template.count { it in 'A'..'Y' || it in 'a'..'y' }
|
val requiredNotesCount = template.count { it in 'A'..'Y' || it in 'a'..'y' }
|
||||||
|
|
||||||
val shouldIncludeParentheses = actualNotes.size >= requiredNotesCount
|
val shouldIncludeParentheses = actualNotes.size >= requiredNotesCount
|
||||||
// println(" • Notes requises par le template : $requiredNotesCount")
|
|
||||||
// println(" • Inclusion des parenthèses autorisée ? : $shouldIncludeParentheses")
|
|
||||||
// println("--------------------------------------------------")
|
|
||||||
val result = StringBuilder()
|
val result = StringBuilder()
|
||||||
var noteIdx = 0
|
var noteIdx = 0
|
||||||
|
|
||||||
for (i in template.indices) {
|
for (i in template.indices) {
|
||||||
val char = template[i]
|
val char = template[i]
|
||||||
// print("[Étape $i] Caractère template = '$char' | Index note actuel = $noteIdx -> ")
|
|
||||||
when {
|
when {
|
||||||
(char in 'A'..'Y' || char in 'a'..'y') -> {
|
(char in 'A'..'Y' || char in 'a'..'y') -> {
|
||||||
if (noteIdx < actualNotes.size) {
|
if (noteIdx < actualNotes.size) {
|
||||||
val noteToAdd = actualNotes[noteIdx]
|
val noteToAdd = actualNotes[noteIdx]
|
||||||
if (noteIdx > 0 && result.isNotEmpty()) {
|
if (noteIdx > 0 && result.isNotEmpty()) {
|
||||||
val lastChar = result.last()
|
val lastChar = result.last()
|
||||||
// println()
|
if (lastChar != '•' && lastChar != ',' && lastChar != '(' && lastChar != ' ') {
|
||||||
// println(" [INFO ESPACE] lastC '$lastChar' avant d'ajouter la note \"$noteToAdd\"")
|
|
||||||
/* if (lastChar != '•' && lastChar != ',' && lastChar != '(' && lastChar != ')') {
|
|
||||||
result.append(" ")
|
result.append(" ")
|
||||||
} */
|
}
|
||||||
// println(" [INFO ESPACE] Maintenant res est \"${result.toString()}\"")
|
|
||||||
// print(" -> Continuité Étape $i : ")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
result.append(noteToAdd)
|
result.append(noteToAdd)
|
||||||
// println("Action : Ajout de la note utilisateur \"$noteToAdd\"")
|
|
||||||
noteIdx++
|
noteIdx++
|
||||||
} else {
|
} else {
|
||||||
/*if (rawNote.isEmpty()) {*/
|
/*if (rawNote.isEmpty()) {*/
|
||||||
|
|
@ -1348,78 +1314,35 @@ fun autoFixNote(rawNote: String, template: String): String {
|
||||||
/*} else {
|
/*} else {
|
||||||
result.append("―")
|
result.append("―")
|
||||||
}*/
|
}*/
|
||||||
// println("Action : Plus de notes utilisateur ! Ajout du silence par défaut \"z\"")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
char == '-' -> {
|
char == '-' -> {
|
||||||
if (noteIdx < actualNotes.size && actualNotes[noteIdx] == "―") {
|
if (noteIdx < actualNotes.size && actualNotes[noteIdx] == "―") {
|
||||||
result.append("―")
|
result.append("―")
|
||||||
// println("Action : Consommation et ajout du tiret utilisateur \"―\"")
|
|
||||||
noteIdx++
|
noteIdx++
|
||||||
} else {
|
} else {
|
||||||
val prev = if (i > 0) template[i - 1] else null
|
val prev = if (i > 0) template[i - 1] else null
|
||||||
val next = if (i < template.lastIndex) template[i + 1] else null
|
val next = if (i < template.lastIndex) template[i + 1] else null
|
||||||
if (prev == '.' && next == ',') {
|
if (prev == '.' && next == ',') result.append(" ") else result.append("―")
|
||||||
result.append(" ")
|
|
||||||
// println("Action : Structure .-, détectée -> Ajout d'un espace \" \"")
|
|
||||||
} else {
|
|
||||||
result.append("―")
|
|
||||||
// println("Action : Ajout du tiret automatique \"―\"")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
char == 'z' -> {
|
char == 'z' -> result.append(" ")
|
||||||
result.append(" ")
|
|
||||||
// println("Action : Caractère 'z' du template -> Ajout d'un espace \" \"")
|
|
||||||
}
|
|
||||||
char == '.' -> {
|
char == '.' -> {
|
||||||
val currentText = result.toString()
|
val currentText = result.toString()
|
||||||
if (!currentText.endsWith("•")) {
|
if (!currentText.endsWith("•")) result.append("•")
|
||||||
result.append("•")
|
|
||||||
// println("Action : Ajout du point musical \"•\"")
|
|
||||||
} else {
|
|
||||||
// println("Action : Ignoré (se termine déjà par un point)")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
char == ',' -> {
|
char == ',' -> {
|
||||||
val currentText = result.toString()
|
val currentText = result.toString()
|
||||||
if (!currentText.endsWith(",")) {
|
if (!currentText.endsWith(",")) result.append(",")
|
||||||
result.append(",")
|
|
||||||
// println("Action : Ajout de la virgule \",\"")
|
|
||||||
} else {
|
|
||||||
// println("Action : Ignoré (se termine déjà par une virgule)")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
char == '(' -> {
|
char == '(' -> {
|
||||||
if (shouldIncludeParentheses) {
|
if (shouldIncludeParentheses) result.append("(")
|
||||||
result.append("(")
|
|
||||||
// println("Action : Ajout parenthèse ouvrante \"(\"")
|
|
||||||
} else {
|
|
||||||
// println("Action : Ignoré (pas assez de notes)")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
char == ')' -> {
|
char == ')' -> {
|
||||||
if (shouldIncludeParentheses) {
|
if (shouldIncludeParentheses) result.append(")")
|
||||||
result.append(")")
|
|
||||||
// println("Action : Ajout parenthèse fermante \")\"")
|
|
||||||
} else {
|
|
||||||
// println("Action : Ignoré (pas assez de notes)")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
// println("Action : Aucun comportement défini pour '$char'")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// println(" ↳ État actuel du buffer : \"${result.toString()}\"")
|
|
||||||
}
|
}
|
||||||
var finalResult = result.toString()
|
// println("on a RES ${result.toString()}")
|
||||||
// println(" • Avant formatage final : \"$finalResult\"")
|
return result.toString()
|
||||||
|
|
||||||
finalResult = finalResult
|
|
||||||
.replace("( ", "(")
|
|
||||||
.replace(" )", ")")
|
|
||||||
.replace("•,", "• ,")
|
|
||||||
|
|
||||||
// println("on a RES ${finalResult}")
|
|
||||||
return finalResult
|
|
||||||
}
|
}
|
||||||
|
|
@ -16,7 +16,6 @@ import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowLeft
|
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowLeft
|
||||||
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight
|
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight
|
||||||
import androidx.compose.material.icons.filled.*
|
import androidx.compose.material.icons.filled.*
|
||||||
import androidx.compose.material.icons.filled.KeyboardDoubleArrowRight
|
|
||||||
import androidx.compose.material3.*
|
import androidx.compose.material3.*
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
|
|
@ -250,7 +249,7 @@ fun MidiControlPanel(
|
||||||
modifier = Modifier.background(Color(0XFF2C3130)),
|
modifier = Modifier.background(Color(0XFF2C3130)),
|
||||||
onClick = { updateTempoByBpmStep(-10) }) {
|
onClick = { updateTempoByBpmStep(-10) }) {
|
||||||
Icon(
|
Icon(
|
||||||
Icons.Default.KeyboardDoubleArrowLeft,
|
Icons.AutoMirrored.Filled.KeyboardArrowLeft,
|
||||||
"gauche",
|
"gauche",
|
||||||
tint = Color.White.copy(0.7f),
|
tint = Color.White.copy(0.7f),
|
||||||
modifier = Modifier.size(22.dp)
|
modifier = Modifier.size(22.dp)
|
||||||
|
|
@ -298,7 +297,7 @@ fun MidiControlPanel(
|
||||||
modifier = Modifier.background(Color(0XFF2C3130)),
|
modifier = Modifier.background(Color(0XFF2C3130)),
|
||||||
onClick = { updateTempoByBpmStep(10) }) {
|
onClick = { updateTempoByBpmStep(10) }) {
|
||||||
Icon(
|
Icon(
|
||||||
Icons.Default.KeyboardDoubleArrowRight,
|
Icons.AutoMirrored.Filled.KeyboardArrowRight,
|
||||||
"droite",
|
"droite",
|
||||||
tint = Color.White.copy(0.7f),
|
tint = Color.White.copy(0.7f),
|
||||||
modifier = Modifier.size(22.dp)
|
modifier = Modifier.size(22.dp)
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,7 @@ import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
||||||
import androidx.compose.material3.Card
|
import androidx.compose.material3.Card
|
||||||
import androidx.compose.material3.CardDefaults
|
|
||||||
import androidx.compose.material3.CircularProgressIndicator
|
import androidx.compose.material3.CircularProgressIndicator
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
|
|
@ -16,20 +14,14 @@ import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.produceState
|
import androidx.compose.runtime.produceState
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
|
||||||
import androidx.compose.ui.draw.shadow
|
import androidx.compose.ui.draw.shadow
|
||||||
import androidx.compose.ui.graphics.Color
|
|
||||||
import androidx.compose.ui.graphics.ImageBitmap
|
import androidx.compose.ui.graphics.ImageBitmap
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
|
||||||
import feufaro.composeapp.generated.resources.Res
|
|
||||||
import feufaro.composeapp.generated.resources.compose_multiplatform
|
|
||||||
import mg.dot.feufaro.FileRepository
|
import mg.dot.feufaro.FileRepository
|
||||||
import mg.dot.feufaro.solfa.ColorPrefixA
|
import mg.dot.feufaro.solfa.ColorPrefixA
|
||||||
import mg.dot.feufaro.solfa.ColorPrefixB
|
import mg.dot.feufaro.solfa.ColorPrefixB
|
||||||
import mg.dot.feufaro.solfa.ColorValue
|
import mg.dot.feufaro.solfa.ColorValue
|
||||||
import org.jetbrains.compose.resources.painterResource
|
|
||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
import java.util.zip.GZIPOutputStream
|
import java.util.zip.GZIPOutputStream
|
||||||
import kotlin.io.encoding.Base64
|
import kotlin.io.encoding.Base64
|
||||||
|
|
@ -55,91 +47,53 @@ fun QRDisplay(sharedScreenModel: SharedScreenModel, fileRepository: FileReposito
|
||||||
val compressedData = Base64.UrlSafe.encode(compressedBytes).trim('=')
|
val compressedData = Base64.UrlSafe.encode(compressedBytes).trim('=')
|
||||||
|
|
||||||
val uri = "feufaro://song?file=${compressedData}&name=$fileName"
|
val uri = "feufaro://song?file=${compressedData}&name=$fileName"
|
||||||
value = generateQRCode(uri, size = 1200)
|
value = generateQRCode(uri, size = 800)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.background(Color.Black.copy(alpha = 0.6f)) // Assombrissement moderne
|
.background(MaterialTheme.colorScheme.scrim.copy(alpha = 0.5f)) // Fond semi-transparent
|
||||||
.clickable { sharedScreenModel.toggleQRCodeVisibility() } // Fermer au clic
|
.clickable { sharedScreenModel.toggleQRCodeVisibility() } // Fermer au clic
|
||||||
.imePadding()
|
.imePadding()
|
||||||
.systemBarsPadding(),
|
.systemBarsPadding(),
|
||||||
contentAlignment = Alignment.Center
|
contentAlignment = Alignment.Center
|
||||||
) {
|
) {
|
||||||
Card(
|
Card(
|
||||||
modifier = Modifier
|
modifier = Modifier.wrapContentSize().shadow(16.dp, shape = MaterialTheme.shapes.large)
|
||||||
.width(400.dp)
|
|
||||||
.wrapContentHeight()
|
|
||||||
.shadow(24.dp, shape = RoundedCornerShape(28.dp)),
|
|
||||||
shape = RoundedCornerShape(28.dp),
|
|
||||||
colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface)
|
|
||||||
) {
|
) {
|
||||||
Column(
|
Column(
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
modifier = Modifier.padding(24.dp)
|
modifier = Modifier.padding(24.dp)
|
||||||
) {
|
) {
|
||||||
Text(
|
Text("Scanner pour ouvrir ce partition")
|
||||||
text = "Partager la partition",
|
|
||||||
style = MaterialTheme.typography.titleLarge.copy(
|
|
||||||
fontWeight = FontWeight.Bold,
|
|
||||||
letterSpacing = 0.5.sp
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
Text(
|
|
||||||
text = "Scannez pour ouvrir instantanément",
|
|
||||||
style = MaterialTheme.typography.bodyMedium.copy(
|
|
||||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
|
||||||
),
|
|
||||||
modifier = Modifier.padding(top = 4.dp, bottom = 24.dp)
|
|
||||||
)
|
|
||||||
|
|
||||||
if (qrCodeImage != null) {
|
if (qrCodeImage != null) {
|
||||||
Box(
|
Image(
|
||||||
contentAlignment = Alignment.Center,
|
bitmap = qrCodeImage!!,
|
||||||
modifier = Modifier
|
contentDescription = "Code QR du fichier actif",
|
||||||
.size(350.dp)
|
modifier = Modifier.size(400.dp)
|
||||||
.clip(RoundedCornerShape(16.dp))
|
)
|
||||||
.background(Color.White)
|
|
||||||
.padding(5.dp)
|
|
||||||
) {
|
|
||||||
Image(
|
|
||||||
bitmap = qrCodeImage!!,
|
|
||||||
contentDescription = "Code QR du fichier actif",
|
|
||||||
modifier = Modifier.fillMaxSize()
|
|
||||||
)
|
|
||||||
|
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
|
||||||
.size(54.dp)
|
|
||||||
.background(Color.White, shape = RoundedCornerShape(12.dp))
|
|
||||||
.padding(4.dp),
|
|
||||||
contentAlignment = Alignment.Center
|
|
||||||
) {
|
|
||||||
Image(
|
|
||||||
painter = painterResource(Res.drawable.compose_multiplatform),
|
|
||||||
contentDescription = "App Logo",
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxSize()
|
|
||||||
.clip(RoundedCornerShape(8.dp))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier.size(280.dp),
|
modifier = Modifier
|
||||||
|
.size(400.dp)
|
||||||
|
.padding(16.dp),
|
||||||
contentAlignment = Alignment.Center
|
contentAlignment = Alignment.Center
|
||||||
) {
|
) {
|
||||||
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
Column(
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
verticalArrangement = Arrangement.Center
|
||||||
|
) {
|
||||||
CircularProgressIndicator(
|
CircularProgressIndicator(
|
||||||
modifier = Modifier.size(48.dp),
|
modifier = Modifier.size(48.dp),
|
||||||
color = ColorPrefixA,
|
color = ColorPrefixA,
|
||||||
strokeWidth = 4.dp,
|
strokeWidth = 4.dp,
|
||||||
trackColor = ColorPrefixB.copy(alpha = 0.2f)
|
trackColor = ColorPrefixB.copy(alpha = 0.2f)
|
||||||
)
|
)
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
||||||
Text(
|
Text(
|
||||||
text = "Génération du QR Code...",
|
text = "Génération du QR Code...",
|
||||||
style = MaterialTheme.typography.bodyMedium.copy(
|
style = MaterialTheme.typography.bodyMedium.copy(
|
||||||
|
|
@ -150,8 +104,6 @@ fun QRDisplay(sharedScreenModel: SharedScreenModel, fileRepository: FileReposito
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(12.dp))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue