diff --git a/composeApp/src/commonMain/kotlin/mg/dot/feufaro/solfa/TimeUnitObject.kt b/composeApp/src/commonMain/kotlin/mg/dot/feufaro/solfa/TimeUnitObject.kt index 1dc2531..4e979c5 100644 --- a/composeApp/src/commonMain/kotlin/mg/dot/feufaro/solfa/TimeUnitObject.kt +++ b/composeApp/src/commonMain/kotlin/mg/dot/feufaro/solfa/TimeUnitObject.kt @@ -6,7 +6,9 @@ import androidx.compose.animation.core.tween import androidx.compose.foundation.Canvas import androidx.compose.foundation.LocalIndication import androidx.compose.foundation.background +import androidx.compose.foundation.border import androidx.compose.foundation.combinedClickable +import androidx.compose.foundation.focusable import androidx.compose.foundation.gestures.detectTapGestures import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.interaction.collectIsHoveredAsState @@ -16,11 +18,9 @@ import androidx.compose.foundation.text.BasicTextField import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material.icons.Icons 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.Close import androidx.compose.material.icons.filled.Description -import androidx.compose.material.icons.filled.KeyboardDoubleArrowLeft import androidx.compose.material.icons.filled.Save import androidx.compose.material3.* import androidx.compose.runtime.* @@ -28,6 +28,8 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.drawBehind import androidx.compose.ui.draw.drawWithContent +import androidx.compose.ui.focus.FocusRequester +import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.geometry.Offset import androidx.compose.ui.geometry.Size import androidx.compose.ui.graphics.Color @@ -36,6 +38,7 @@ import androidx.compose.ui.graphics.drawscope.Stroke import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.layout.onSizeChanged import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.text.* import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontStyle @@ -265,7 +268,9 @@ fun TimeUnitComposable( tuo: TimeUnitObject, stanzaNumber: Int, gridColumnCount: Int, - gridActive: Boolean + gridActive: Boolean, + isCurrentBlock: Boolean = false, + parentFocusRequester: FocusRequester? = null ) { val col = if (tuo.getNum() % 2 == 0) Color(0xff, 0xfa, 0xf7) else Color(0xfb, 0xf3, 0xff) val currentDensity = LocalDensity.current @@ -274,6 +279,8 @@ fun TimeUnitComposable( targetValue = if (gridActive) Color.Cyan.copy(alpha = 0.5f) else col, animationSpec = tween(durationMillis = 100) // Très court pour rester réactif ) + val focusRequesters = remember { List(4) { FocusRequester() } } + Column( modifier = Modifier .background(animatedColor) @@ -569,6 +576,9 @@ fun LazyVerticalGridTUO( var selectedIndex by remember { mutableStateOf(-1) } val regexMeasure = Regex("(\\d)/\\d").find(viewModel.measure) + val focusRequester = remember { FocusRequester() } + var selectedGridIndex by remember { mutableStateOf(0) } + LaunchedEffect(tuoList) { showContextualMenu = false showEditDialog = false @@ -580,13 +590,21 @@ fun LazyVerticalGridTUO( val editMode by sharedScreenModel.modeEditor.collectAsState() + val focusManager = LocalFocusManager.current Column( modifier = Modifier .fillMaxWidth() .onSizeChanged { size -> onGridWidthMeasured(size.width) } + .focusRequester(focusRequester) + .focusable() ) { + LaunchedEffect(editMode) { + if (editMode) { + focusRequester.requestFocus() + } + } val density = LocalDensity.current val horizontalArrangementSpacing: Dp = 0.dp val columnGroupString = regexMeasure?.groupValues?.get(1) ?: "1" @@ -765,6 +783,7 @@ fun LazyVerticalGridTUO( measureTUOs.forEachIndexed { indexInMeasure, oneTUO -> val globalIndex = (measureIndex * gridColumnCount) + indexInMeasure val isActive = (globalIndex == activeRowIndex) + val isSelectedByKeyboard = (globalIndex == selectedGridIndex) val myTimestamp = sharedScreenModel.tuoTimestamps.value.getOrElse(globalIndex) { 0L } var menuOffset by remember { mutableStateOf(Offset.Zero) } @@ -774,6 +793,11 @@ fun LazyVerticalGridTUO( key(oneTUO.numBlock) { Box(modifier = Modifier .width(gridWidthDp / gridColumnCount) + .border( + width = if (isSelectedByKeyboard && editMode) 2.dp else 0.dp, + color = if (isSelectedByKeyboard && editMode) Color(0xFF9C27B0) else Color.Transparent, + shape = RoundedCornerShape(4.dp) + ) .background( if (isHovered) Color.Black.copy(alpha = 0.05f) else Color.Transparent, RoundedCornerShape(4.dp) @@ -787,6 +811,7 @@ fun LazyVerticalGridTUO( detectTapGestures( onTap = { offset -> if(editMode) { + selectedGridIndex = globalIndex menuOffset = offset selectedTUO = oneTUO selectedIndex = globalIndex @@ -802,7 +827,9 @@ fun LazyVerticalGridTUO( tuo = oneTUO, stanzaNumber = currentStanza, gridColumnCount = gridColumnCount, - gridActive = isActive + gridActive = isActive, + isCurrentBlock = isSelectedByKeyboard && editMode, + parentFocusRequester = focusRequester ) if (showContextualMenu && selectedIndex == globalIndex) { @@ -877,7 +904,8 @@ fun LazyVerticalGridTUO( oneTUO.pTemplate.markerToString().takeIf { it.isNotBlank() }, oneTUO.hasHairPin()?.toString()?.takeIf { it.isNotBlank() } ).joinToString(" "), - silentDuration = blankPrefix + silentDuration = blankPrefix, + sep = oneTUO.sep0 ) TUODetailDialog( editState = editState, @@ -1422,4 +1450,21 @@ fun autoFixNote(rawNote: String, template: String): String { // println("on a RES ${finalResult}") return finalResult +} +private fun transformMusicalInput(input: String): String { + return input.lowercase() + .replace(";", "• ,") + .replace(".", "•") + .replace("-", "―") + .replace("(?<=[a-z])[']".toRegex(), "¹") + .replace("(?<=[a-z])[,]".toRegex(), "₁") + .replace("¹¹", "²") + .replace("¹'", "²") + .replace("²¹", "³") + .replace("²'", "³") + .replace("₁,", "₂") + .replace("₁₁", "₂") + .replace("₂,", "₃") + .replace("₂₁", "₃") + .replace("'", "¹") } \ No newline at end of file