Focus with bordered grid on editing
This commit is contained in:
parent
14c27b541a
commit
d59eeac52e
1 changed files with 50 additions and 5 deletions
|
|
@ -6,7 +6,9 @@ import androidx.compose.animation.core.tween
|
||||||
import androidx.compose.foundation.Canvas
|
import androidx.compose.foundation.Canvas
|
||||||
import androidx.compose.foundation.LocalIndication
|
import androidx.compose.foundation.LocalIndication
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.border
|
||||||
import androidx.compose.foundation.combinedClickable
|
import androidx.compose.foundation.combinedClickable
|
||||||
|
import androidx.compose.foundation.focusable
|
||||||
import androidx.compose.foundation.gestures.detectTapGestures
|
import androidx.compose.foundation.gestures.detectTapGestures
|
||||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
import androidx.compose.foundation.interaction.collectIsHoveredAsState
|
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.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.*
|
||||||
|
|
@ -28,6 +28,8 @@ import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.drawBehind
|
import androidx.compose.ui.draw.drawBehind
|
||||||
import androidx.compose.ui.draw.drawWithContent
|
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.Offset
|
||||||
import androidx.compose.ui.geometry.Size
|
import androidx.compose.ui.geometry.Size
|
||||||
import androidx.compose.ui.graphics.Color
|
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.input.pointer.pointerInput
|
||||||
import androidx.compose.ui.layout.onSizeChanged
|
import androidx.compose.ui.layout.onSizeChanged
|
||||||
import androidx.compose.ui.platform.LocalDensity
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
|
import androidx.compose.ui.platform.LocalFocusManager
|
||||||
import androidx.compose.ui.text.*
|
import androidx.compose.ui.text.*
|
||||||
import androidx.compose.ui.text.font.FontFamily
|
import androidx.compose.ui.text.font.FontFamily
|
||||||
import androidx.compose.ui.text.font.FontStyle
|
import androidx.compose.ui.text.font.FontStyle
|
||||||
|
|
@ -265,7 +268,9 @@ fun TimeUnitComposable(
|
||||||
tuo: TimeUnitObject,
|
tuo: TimeUnitObject,
|
||||||
stanzaNumber: Int,
|
stanzaNumber: Int,
|
||||||
gridColumnCount: 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 col = if (tuo.getNum() % 2 == 0) Color(0xff, 0xfa, 0xf7) else Color(0xfb, 0xf3, 0xff)
|
||||||
val currentDensity = LocalDensity.current
|
val currentDensity = LocalDensity.current
|
||||||
|
|
@ -274,6 +279,8 @@ fun TimeUnitComposable(
|
||||||
targetValue = if (gridActive) Color.Cyan.copy(alpha = 0.5f) else col,
|
targetValue = if (gridActive) Color.Cyan.copy(alpha = 0.5f) else col,
|
||||||
animationSpec = tween(durationMillis = 100) // Très court pour rester réactif
|
animationSpec = tween(durationMillis = 100) // Très court pour rester réactif
|
||||||
)
|
)
|
||||||
|
val focusRequesters = remember { List(4) { FocusRequester() } }
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.background(animatedColor)
|
.background(animatedColor)
|
||||||
|
|
@ -569,6 +576,9 @@ fun LazyVerticalGridTUO(
|
||||||
var selectedIndex by remember { mutableStateOf(-1) }
|
var selectedIndex by remember { mutableStateOf(-1) }
|
||||||
val regexMeasure = Regex("(\\d)/\\d").find(viewModel.measure)
|
val regexMeasure = Regex("(\\d)/\\d").find(viewModel.measure)
|
||||||
|
|
||||||
|
val focusRequester = remember { FocusRequester() }
|
||||||
|
var selectedGridIndex by remember { mutableStateOf(0) }
|
||||||
|
|
||||||
LaunchedEffect(tuoList) {
|
LaunchedEffect(tuoList) {
|
||||||
showContextualMenu = false
|
showContextualMenu = false
|
||||||
showEditDialog = false
|
showEditDialog = false
|
||||||
|
|
@ -580,13 +590,21 @@ fun LazyVerticalGridTUO(
|
||||||
|
|
||||||
val editMode by sharedScreenModel.modeEditor.collectAsState()
|
val editMode by sharedScreenModel.modeEditor.collectAsState()
|
||||||
|
|
||||||
|
val focusManager = LocalFocusManager.current
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.onSizeChanged { size ->
|
.onSizeChanged { size ->
|
||||||
onGridWidthMeasured(size.width)
|
onGridWidthMeasured(size.width)
|
||||||
}
|
}
|
||||||
|
.focusRequester(focusRequester)
|
||||||
|
.focusable()
|
||||||
) {
|
) {
|
||||||
|
LaunchedEffect(editMode) {
|
||||||
|
if (editMode) {
|
||||||
|
focusRequester.requestFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
val density = LocalDensity.current
|
val density = LocalDensity.current
|
||||||
val horizontalArrangementSpacing: Dp = 0.dp
|
val horizontalArrangementSpacing: Dp = 0.dp
|
||||||
val columnGroupString = regexMeasure?.groupValues?.get(1) ?: "1"
|
val columnGroupString = regexMeasure?.groupValues?.get(1) ?: "1"
|
||||||
|
|
@ -765,6 +783,7 @@ fun LazyVerticalGridTUO(
|
||||||
measureTUOs.forEachIndexed { indexInMeasure, oneTUO ->
|
measureTUOs.forEachIndexed { indexInMeasure, oneTUO ->
|
||||||
val globalIndex = (measureIndex * gridColumnCount) + indexInMeasure
|
val globalIndex = (measureIndex * gridColumnCount) + indexInMeasure
|
||||||
val isActive = (globalIndex == activeRowIndex)
|
val isActive = (globalIndex == activeRowIndex)
|
||||||
|
val isSelectedByKeyboard = (globalIndex == selectedGridIndex)
|
||||||
|
|
||||||
val myTimestamp = sharedScreenModel.tuoTimestamps.value.getOrElse(globalIndex) { 0L }
|
val myTimestamp = sharedScreenModel.tuoTimestamps.value.getOrElse(globalIndex) { 0L }
|
||||||
var menuOffset by remember { mutableStateOf(Offset.Zero) }
|
var menuOffset by remember { mutableStateOf(Offset.Zero) }
|
||||||
|
|
@ -774,6 +793,11 @@ fun LazyVerticalGridTUO(
|
||||||
key(oneTUO.numBlock) {
|
key(oneTUO.numBlock) {
|
||||||
Box(modifier = Modifier
|
Box(modifier = Modifier
|
||||||
.width(gridWidthDp / gridColumnCount)
|
.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(
|
.background(
|
||||||
if (isHovered) Color.Black.copy(alpha = 0.05f) else Color.Transparent,
|
if (isHovered) Color.Black.copy(alpha = 0.05f) else Color.Transparent,
|
||||||
RoundedCornerShape(4.dp)
|
RoundedCornerShape(4.dp)
|
||||||
|
|
@ -787,6 +811,7 @@ fun LazyVerticalGridTUO(
|
||||||
detectTapGestures(
|
detectTapGestures(
|
||||||
onTap = { offset ->
|
onTap = { offset ->
|
||||||
if(editMode) {
|
if(editMode) {
|
||||||
|
selectedGridIndex = globalIndex
|
||||||
menuOffset = offset
|
menuOffset = offset
|
||||||
selectedTUO = oneTUO
|
selectedTUO = oneTUO
|
||||||
selectedIndex = globalIndex
|
selectedIndex = globalIndex
|
||||||
|
|
@ -802,7 +827,9 @@ fun LazyVerticalGridTUO(
|
||||||
tuo = oneTUO,
|
tuo = oneTUO,
|
||||||
stanzaNumber = currentStanza,
|
stanzaNumber = currentStanza,
|
||||||
gridColumnCount = gridColumnCount,
|
gridColumnCount = gridColumnCount,
|
||||||
gridActive = isActive
|
gridActive = isActive,
|
||||||
|
isCurrentBlock = isSelectedByKeyboard && editMode,
|
||||||
|
parentFocusRequester = focusRequester
|
||||||
)
|
)
|
||||||
|
|
||||||
if (showContextualMenu && selectedIndex == globalIndex) {
|
if (showContextualMenu && selectedIndex == globalIndex) {
|
||||||
|
|
@ -877,7 +904,8 @@ fun LazyVerticalGridTUO(
|
||||||
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
|
silentDuration = blankPrefix,
|
||||||
|
sep = oneTUO.sep0
|
||||||
)
|
)
|
||||||
TUODetailDialog(
|
TUODetailDialog(
|
||||||
editState = editState,
|
editState = editState,
|
||||||
|
|
@ -1422,4 +1450,21 @@ fun autoFixNote(rawNote: String, template: String): String {
|
||||||
|
|
||||||
// println("on a RES ${finalResult}")
|
// println("on a RES ${finalResult}")
|
||||||
return 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("'", "¹")
|
||||||
}
|
}
|
||||||
Loading…
Add table
Reference in a new issue