diff --git a/composeApp/src/commonMain/kotlin/mg/dot/feufaro/ui/Settings.kt b/composeApp/src/commonMain/kotlin/mg/dot/feufaro/ui/Settings.kt index 40a6ba8..063813e 100644 --- a/composeApp/src/commonMain/kotlin/mg/dot/feufaro/ui/Settings.kt +++ b/composeApp/src/commonMain/kotlin/mg/dot/feufaro/ui/Settings.kt @@ -7,14 +7,14 @@ import androidx.compose.animation.core.tween import androidx.compose.foundation.* import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.* +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.Undo -import androidx.compose.material.icons.filled.Check -import androidx.compose.material.icons.filled.DarkMode -import androidx.compose.material.icons.filled.KeyboardArrowDown -import androidx.compose.material.icons.filled.LightMode +import androidx.compose.material.icons.filled.* import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.ui.Alignment @@ -595,6 +595,7 @@ fun Settings( modifier = Modifier.padding(vertical = 12.dp) ) + var showInstrumentDialog by remember { mutableStateOf(false) } Text( text = "Règlage des Instruments", style = MaterialTheme.typography.bodyLarge, @@ -602,85 +603,47 @@ fun Settings( color = MaterialTheme.colorScheme.onSurface, modifier = Modifier.padding(bottom = 8.dp) ) - val currentProgram = 0 - Row( - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 4.dp), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically + Surface( + onClick = { showInstrumentDialog = true }, + shape = RoundedCornerShape(12.dp), + color = MaterialTheme.colorScheme.surfaceContainerHigh, + border = BorderStroke(1.dp, MaterialTheme.colorScheme.outline.copy(alpha = 0.3f)), + modifier = Modifier.fillMaxWidth() ) { - ExposedDropdownMenuBox( - expanded = expandedDropdown, - onExpandedChange = { expandedDropdown = !expandedDropdown }, - modifier = Modifier.weight(1f) + Row( + modifier = Modifier.padding(14.dp), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically ) { - OutlinedTextField( - value = "${selectedInstrument.icon} - ${selectedInstrument.name}", - onValueChange = {}, - readOnly = true, - trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expandedDropdown) }, - colors = ExposedDropdownMenuDefaults.outlinedTextFieldColors(), - modifier = Modifier.menuAnchor(type = MenuAnchorType.PrimaryEditable, true).fillMaxWidth(), - textStyle = MaterialTheme.typography.bodyMedium, - shape = RoundedCornerShape(8.dp) - ) - - DropdownMenu( - expanded = expandedDropdown, - onDismissRequest = { expandedDropdown = false }, - modifier = Modifier - .width(400.dp) - .heightIn(max = 250.dp) - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .heightIn(max = 250.dp) - .verticalScroll(menuScrollState) - ) { - instruments.forEach { instrument -> - val isSelected = selectedInstrument.program == instrument.program - DropdownMenuItem( - modifier = Modifier.fillMaxWidth(), - text = { - Text( - "${instrument.program} - ${instrument.name}", - fontWeight = if(isSelected) FontWeight.Bold else FontWeight.Normal, - style = MaterialTheme.typography.bodyMedium - ) - }, - onClick = { - globalInstrumentProgram = instrument.program - sharedScreenModel.saveVoiceInstrument(instrument.program) - expandedDropdown = false - }, - leadingIcon = { - Text(instrument.icon) - }, - trailingIcon = { - if (isSelected) { - Icon( - imageVector = Icons.Default.Check, - contentDescription = "Selected instru", - tint = MaterialTheme.colorScheme.primary, - modifier = Modifier.size(18.dp) - ) - } - }, - colors = MenuDefaults.itemColors( - textColor = if (isSelected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurface, - leadingIconColor = MaterialTheme.colorScheme.primary, - trailingIconColor = MaterialTheme.colorScheme.primary - ), - contentPadding = PaddingValues(horizontal = 16.dp, vertical = 8.dp) - ) - } - } + Column { + Text( + text = "${selectedInstrument.program} - ${selectedInstrument.name}", + style = MaterialTheme.typography.bodyLarge, + fontWeight = FontWeight.Bold, + color = MaterialTheme.colorScheme.primary + ) } + Icon( + imageVector = Icons.Default.KeyboardArrowDown, + contentDescription = "Changer l'instrument", + tint = MaterialTheme.colorScheme.primary + ) } } + if (showInstrumentDialog) { + InstrumentPickerDialog( + instruments = instruments, + selectedProgram = globalInstrumentProgram, + onInstrumentSelected = { instrument -> + globalInstrumentProgram = instrument.program + sharedScreenModel.saveVoiceInstrument(instrument.program) + showInstrumentDialog = false + }, + onDismissRequest = { showInstrumentDialog = false } + ) + } + HorizontalDivider( color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.2f), modifier = Modifier.padding(vertical = 12.dp) @@ -880,3 +843,105 @@ fun SettingsAccordion( } } } + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun InstrumentPickerDialog( + instruments: List, + selectedProgram: Int, + onInstrumentSelected: (MidiInstrument) -> Unit, + onDismissRequest: () -> Unit +) { + val filteredInstruments = remember(instruments) { + instruments + } + + val selectedInstrument = remember(selectedProgram, instruments) { + instruments.find { it.program == selectedProgram } + } + + val selectedIndex = remember(filteredInstruments, selectedProgram) { + filteredInstruments.indexOfFirst { it.program == selectedProgram }.coerceAtLeast(0) + } + + val listState = rememberLazyListState( + initialFirstVisibleItemIndex = selectedIndex + ) + + AlertDialog( + properties = DialogProperties(usePlatformDefaultWidth = false), + modifier = Modifier + .widthIn(min = 320.dp, max = 550.dp) + .fillMaxHeight(0.85f) + .fillMaxWidth(0.9f), + onDismissRequest = onDismissRequest, + title = { + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically + ) { + Text( + text = "Choisir un Instrument", + fontWeight = FontWeight.Bold, + fontSize = 20.sp + ) + IconButton(onClick = onDismissRequest) { + Icon(Icons.Default.Close, contentDescription = "Fermer") + } + } + }, + text = { + Column(modifier = Modifier.fillMaxWidth()) { + LazyColumn( + state = listState, + modifier = Modifier.fillMaxWidth() + ) { + items( + items = filteredInstruments, + key = { it.program } + ) { instrument -> + val isSelected = instrument.program == selectedProgram + + ListItem( + headlineContent = { + Text( + text = "${instrument.program} - ${instrument.name}", + fontWeight = if (isSelected) FontWeight.Bold else FontWeight.Normal, + color = if (isSelected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurface + ) + }, + leadingContent = { + Text( + text = instrument.icon.ifBlank { "🎵" }, + fontSize = 18.sp + ) + }, + trailingContent = { + if (isSelected) { + Icon( + imageVector = Icons.Default.Check, + contentDescription = "Valider ${instrument.name}", + tint = MaterialTheme.colorScheme.primary + ) + } + }, + modifier = Modifier + .fillMaxWidth() + .clip(RoundedCornerShape(8.dp)) + .clickable { onInstrumentSelected(instrument) }, + colors = ListItemDefaults.colors( + containerColor = if (isSelected) { + MaterialTheme.colorScheme.primary.copy(alpha = 0.12f) + } else { + Color.Transparent + } + ) + ) + } + } + } + }, + confirmButton = {} + ) +} \ No newline at end of file