New ui for instru selection on settings

This commit is contained in:
Hasinjato 2026-09-16 14:05:18 +03:00
parent 08c6fd25c4
commit 5a39e1b79b

View file

@ -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<MidiInstrument>,
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 = {}
)
}