From c6cae93dffcf2ca24d7f3ef13827deb8b9198d02 Mon Sep 17 00:00:00 2001 From: Hasinjato Date: Mon, 1 Jun 2026 15:16:55 +0300 Subject: [PATCH] Add measure separator "/" on Popup Editing mode with tooltip --- .../kotlin/mg/dot/feufaro/solfa/Solfa.kt | 19 +++- .../mg/dot/feufaro/solfa/TUODetailDialog.kt | 98 +++++++++++++++---- .../mg/dot/feufaro/solfa/TUOEditState.kt | 4 +- 3 files changed, 96 insertions(+), 25 deletions(-) diff --git a/composeApp/src/commonMain/kotlin/mg/dot/feufaro/solfa/Solfa.kt b/composeApp/src/commonMain/kotlin/mg/dot/feufaro/solfa/Solfa.kt index b9e2823..549a979 100644 --- a/composeApp/src/commonMain/kotlin/mg/dot/feufaro/solfa/Solfa.kt +++ b/composeApp/src/commonMain/kotlin/mg/dot/feufaro/solfa/Solfa.kt @@ -780,9 +780,12 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository editState: TUOEditState ): String { /* On ne modifie pas le template tant que les notes ne sont pas modifiées - * Et tant qu'une marker est ajouter */ + * Et tant qu'un marker est ajouter + * Ou une séparateur de mesure est ajouter */ val notesByVoice = editState.notesByVoice val originalNotes = editState.originalNotes + val separat = editState.sep + val originalSeparat = editState.originalSep var anyNoteModified = false for (voiceNum in 0..3) { val newNot = notesByVoice[voiceNum] ?: "" @@ -793,6 +796,9 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository break } } + if((originalSeparat != separat)) { + anyNoteModified = true + } if (!anyNoteModified && newMarkerValue.isEmpty()) { println("Aucune modification détectée, on retourne le template original.") return templateLine @@ -885,7 +891,7 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository } } - val rawProcessed = leadingCloseParentheses + newMarkerValue + existingMarker + adjustedTemplate + val rawProcessed = separat + leadingCloseParentheses + newMarkerValue + existingMarker + adjustedTemplate var cleanedProcessed = rawProcessed while (cleanedProcessed.contains("((") || cleanedProcessed.contains("))")) { @@ -969,7 +975,14 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository // currentLogicalIdx, rawBlockText, actionTaken, compactedBlock.toString())) resultBody.append(compactedBlock) - if (i < body.length) resultBody.append(body[i]) + if (i < body.length) { +// println("$currentLogicalIdx == ${targetPointer - 1} && ($separat) && ${body[i]} in separators") + if (currentLogicalIdx == (targetPointer-1) && separat.isEmpty() && body[i] in separators) { + resultBody.append('|') + } else { + resultBody.append(body[i]) + } + } currentBlock.clear() currentLogicalIdx++ diff --git a/composeApp/src/commonMain/kotlin/mg/dot/feufaro/solfa/TUODetailDialog.kt b/composeApp/src/commonMain/kotlin/mg/dot/feufaro/solfa/TUODetailDialog.kt index 63dadf2..6bdda6e 100644 --- a/composeApp/src/commonMain/kotlin/mg/dot/feufaro/solfa/TUODetailDialog.kt +++ b/composeApp/src/commonMain/kotlin/mg/dot/feufaro/solfa/TUODetailDialog.kt @@ -11,11 +11,7 @@ import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.automirrored.filled.ArrowForward -import androidx.compose.material.icons.filled.Add -import androidx.compose.material.icons.filled.Build -import androidx.compose.material.icons.filled.Clear -import androidx.compose.material.icons.filled.KeyboardDoubleArrowLeft -import androidx.compose.material.icons.filled.KeyboardDoubleArrowRight +import androidx.compose.material.icons.filled.* import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.ui.Alignment @@ -23,12 +19,11 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.SolidColor -import androidx.compose.ui.text.TextRange import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.input.KeyboardType -import androidx.compose.ui.text.input.TextFieldValue +import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.* import androidx.compose.ui.window.Popup import androidx.compose.ui.window.PopupProperties @@ -63,10 +58,14 @@ fun TUODetailDialog( } var templateFragment by remember { mutableStateOf(editState.templateFragment) } + var newSep by remember { mutableStateOf(editState.sep) } var marker by remember { mutableStateOf(editState.marker) } + val initialSep = remember { editState.sep } val initialMarker = remember { editState.marker } + var canAddSep = mutableStateOf(false) + LaunchedEffect(notes.toMap()) { val tempState = TUOEditState( tuoIndex = editState.tuoIndex, @@ -237,7 +236,62 @@ fun TUODetailDialog( .verticalScroll(rememberScrollState()) ) { // --- SECTION TEMPLATE --- - Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) { + Row(horizontalArrangement = Arrangement.SpaceEvenly, verticalAlignment = Alignment.CenterVertically) { + if(globalIndex != 0) { + Column( + modifier = Modifier.width(20.dp) + ) { + val isSeparator = (newSep.isNotEmpty() || canAddSep.value) && newSep == "/" + val tooltipText = if (isSeparator) { + "Enlever la barre de mesure" + } else { + "Ajouter une barre de mesure" + } + + TooltipBox( + positionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(), + tooltip = { + PlainTooltip( + containerColor = Color.DarkGray, + contentColor = Color.White + ) { + Text(text = tooltipText, fontSize = 12.sp) + } + }, + state = rememberTooltipState() + ) { + if(isSeparator) { + IconButton( + modifier = Modifier.size(20.dp), + onClick = { + canAddSep.value = false + newSep = "" + }) { + Text( + text = "/", + color = Color.Cyan, + fontSize = 18.sp, + fontWeight = FontWeight.Bold, + textAlign = TextAlign.Center + ) + } + } else { + IconButton( + modifier = Modifier.size(20.dp), + onClick = { + canAddSep.value = true + newSep = "/" + }) { + Icon( + imageVector = Icons.Default.Add, + tint = Color.Cyan, + contentDescription = null + ) + } + } + } + } + } Column( modifier = Modifier.weight(1f) ) { @@ -269,19 +323,19 @@ fun TUODetailDialog( onValueChng = { marker = it } ) } - } else { - IconButton( - modifier = Modifier.size(30.dp), - onClick = { - canAddMark.value = true - }) { - Icon( - imageVector = Icons.Default.Add, - tint = Color.Green, - contentDescription = null - ) - } + } else { + IconButton( + modifier = Modifier.size(30.dp), + onClick = { + canAddMark.value = true + }) { + Icon( + imageVector = Icons.Default.Add, + tint = Color.Green, + contentDescription = null + ) } + } } Spacer(modifier = Modifier.height(8.dp)) @@ -403,6 +457,8 @@ fun TUODetailDialog( templateFragment = templateFragment, /* On ne ré-insere pas la même marker*/ marker = if(marker != initialMarker) marker else "", + originalSep = initialSep, + sep = if(newSep != initialSep) newSep else "" ) onSave(state) }, @@ -420,7 +476,7 @@ fun TUODetailDialog( } } } -fun transformMusicalInput(input: String): String { +private fun transformMusicalInput(input: String): String { return input.lowercase() .replace(";", "• ,") .replace(".", "•") diff --git a/composeApp/src/commonMain/kotlin/mg/dot/feufaro/solfa/TUOEditState.kt b/composeApp/src/commonMain/kotlin/mg/dot/feufaro/solfa/TUOEditState.kt index 5a280b5..228c565 100644 --- a/composeApp/src/commonMain/kotlin/mg/dot/feufaro/solfa/TUOEditState.kt +++ b/composeApp/src/commonMain/kotlin/mg/dot/feufaro/solfa/TUOEditState.kt @@ -8,5 +8,7 @@ data class TUOEditState( val originalLyricsByStanza: MutableMap = mutableMapOf(), val templateFragment: String = "", val marker: String = "", - val silentDuration: String = "-1" + val silentDuration: String = "-1", + val originalSep: String = " ", + val sep: String = " " ) \ No newline at end of file