Compare commits

..

No commits in common. "6b8ce0cecf05ed10eb9b240aba7abec983b2c89e" and "a5977d5dd105174cb2dfea24103358f833f1bfe0" have entirely different histories.

6 changed files with 75 additions and 316 deletions

View file

@ -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("/", "/ ")

View file

@ -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 = "$currentIndex",
fontSize = 15.sp,
fontWeight = FontWeight.Bold,
color = Color.White
)
} }
Text(
text = "$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)

View file

@ -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"
) )

View file

@ -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
} }

View file

@ -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)

View file

@ -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))
} }
} }
} }