From cc71d4c34051b8a7f11ae2293391751d387cee8d Mon Sep 17 00:00:00 2001 From: Hasinjato Date: Mon, 28 Sep 2026 14:11:21 +0300 Subject: [PATCH] Update ui: arrange Floatting Action Button horizontally --- .../kotlin/mg/dot/feufaro/ui/DrawerUI.kt | 272 ++++++++++-------- 1 file changed, 159 insertions(+), 113 deletions(-) diff --git a/composeApp/src/commonMain/kotlin/mg/dot/feufaro/ui/DrawerUI.kt b/composeApp/src/commonMain/kotlin/mg/dot/feufaro/ui/DrawerUI.kt index d927850..249e065 100644 --- a/composeApp/src/commonMain/kotlin/mg/dot/feufaro/ui/DrawerUI.kt +++ b/composeApp/src/commonMain/kotlin/mg/dot/feufaro/ui/DrawerUI.kt @@ -706,16 +706,16 @@ fun MainScreenWithDrawer( modifier = Modifier.fillMaxWidth() ) { if (!solfaKeyboardState.isVisible) { - Column( + Row( modifier = Modifier.fillMaxWidth().padding(5.dp), - horizontalAlignment = Alignment.End, - verticalArrangement = Arrangement.spacedBy(7.dp) + horizontalArrangement = Arrangement.spacedBy(7.dp, Alignment.End), + verticalAlignment = Alignment.CenterVertically ) { if (isEditMode) { AnimatedVisibility( visible = true, - enter = fadeIn() + scaleIn() + slideInVertically { it / 2 }, - exit = fadeOut() + scaleOut() + slideOutVertically { it / 2 } + enter = fadeIn() + scaleIn() + slideInHorizontally { it / 2 }, + exit = fadeOut() + scaleOut() + slideOutHorizontally { it / 2 } ) { MyFAB( onClick = { @@ -733,15 +733,14 @@ fun MainScreenWithDrawer( AnimatedVisibility( visible = true, - enter = fadeIn() + scaleIn() + slideInVertically { it / 2 }, - exit = fadeOut() + scaleOut() + slideOutVertically { it / 2 } + enter = fadeIn() + scaleIn() + slideInHorizontally { it / 2 }, + exit = fadeOut() + scaleOut() + slideOutHorizontally { it / 2 } ) { MyFAB( onClick = { scope.launch { try { - val initialDir = - solfaScreenModel.fileRepository.getAppPublicFolder().absolutePath + val initialDir = solfaScreenModel.fileRepository.getAppPublicFolder().absolutePath saveLauncher.launch(fileName, initialDir) } catch (e: Exception) { e.printStackTrace() @@ -754,8 +753,8 @@ fun MainScreenWithDrawer( AnimatedVisibility( visible = true, - enter = fadeIn() + scaleIn() + slideInVertically { it / 2 }, - exit = fadeOut() + scaleOut() + slideOutVertically { it / 2 } + enter = fadeIn() + scaleIn() + slideInHorizontally { it / 2 }, + exit = fadeOut() + scaleOut() + slideOutHorizontally { it / 2 } ) { MyFAB( onClick = { @@ -765,119 +764,146 @@ fun MainScreenWithDrawer( ) } } else if (!isQrVisible) { - AnimatedVisibility( - visible = isExpanded and !showMidiCtrl, - enter = fadeIn() + scaleIn() + slideInVertically { it / 2 }, - exit = fadeOut() + scaleOut() + slideOutVertically { it / 2 } - ) { - Row { - Column { + if (!showMidiCtrl) { + AnimatedVisibility( + visible = isExpanded, + enter = fadeIn() + scaleIn() + slideInHorizontally { it / 2 }, + exit = fadeOut() + scaleOut() + slideOutHorizontally { it / 2 } + ) { + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(4.dp) + ) { MyFAB( - onClick = { - sharedScreenModel.descGridCount(1) - }, + onClick = { sharedScreenModel.descGridCount(1) }, size = 30.dp, icon = Icons.Default.Remove ) - } - Column { MyFAB( - onClick = { - sharedScreenModel.addGridCount(1) - }, + onClick = { sharedScreenModel.addGridCount(1) }, size = 30.dp, icon = Icons.Default.Add ) } } - } - AnimatedVisibility( - visible = isExpanded and !showMidiCtrl, - enter = fadeIn() + scaleIn() + slideInVertically { it / 2 }, - exit = fadeOut() + scaleOut() + slideOutVertically { it / 2 } - ) { - Row( - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(8.dp) + + AnimatedVisibility( + visible = isExpanded, + enter = fadeIn() + scaleIn() + slideInHorizontally { it / 2 }, + exit = fadeOut() + scaleOut() + slideOutHorizontally { it / 2 } ) { - AnimatedVisibility( - visible = isShareExpanded, - enter = fadeIn() + expandHorizontally(), - exit = fadeOut() + shrinkHorizontally() - ) { - Row( - horizontalArrangement = Arrangement.spacedBy(8.dp), - verticalAlignment = Alignment.CenterVertically - ) { - MyFAB( - onClick = { - sharedScreenModel.toggleQRCodeVisibility() - sharedScreenModel.setExpandedFAB(false) - isShareExpanded = false - }, - icon = Icons.Filled.QrCode2 - ) - - MyFAB( - onClick = { - showPrintSettings = !showPrintSettings - isShareExpanded = false - }, - icon = Icons.Filled.Print - ) - - MyFAB( - onClick = { - isShareExpanded = false - scope.launch { - withContext(Dispatchers.IO) { - try { - val cleanS = songTitle.replace(' ','_') - val exportName = "${cleanS.ifEmpty { "partition" }}.mid" - - val savedPath = solfaScreenModel.fileRepository.pickSavePath( - defaultName = exportName, - title = "Enregistrer le fichier MIDI" - ) - - if (!savedPath.isNullOrEmpty()) { - val transpositionInterval = sharedScreenModel.transpositionInterval.value - val bpm = sharedScreenModel.getBpmFlow().value ?: 120f - - solfaScreenModel.generateMidiFile(bpm, savedPath, transpositionInterval) - println("Fichier MIDI enregistré avec succès sous : $savedPath") - } - } catch (e: Exception) { - e.printStackTrace() - } - } - } - }, - icon = Icons.Filled.AudioFile - ) - } - } - MyFAB( - onClick = { isShareExpanded = !isShareExpanded }, - icon = Icons.Filled.Share + onClick = { + sharedScreenModel.showSearchMenu(true) + scope.launch { + delay(100) + focusRequester.requestFocus() + } + sharedScreenModel.setExpandedFAB(!isExpanded) + }, + icon = if (isSearchActive) Icons.Default.Close else Icons.Default.Search ) } - } - AnimatedVisibility( - visible = isExpanded, - enter = fadeIn() + scaleIn() + slideInVertically { it / 2 }, - exit = fadeOut() + scaleOut() + slideOutVertically { it / 2 } - ) { - MyFAB( - onClick = { - sharedScreenModel.setMidiCtrl(!showMidiCtrl) - }, - icon = if (showMidiCtrl) Icons.Filled.StopCircle else Icons.Filled.PlayCircle - ) + AnimatedVisibility( + visible = isExpanded, + enter = fadeIn() + scaleIn() + slideInHorizontally { it / 2 }, + exit = fadeOut() + scaleOut() + slideOutHorizontally { it / 2 } + ) { + Box( + modifier = Modifier.size(55.dp), + contentAlignment = Alignment.BottomEnd + ) { + androidx.compose.animation.AnimatedVisibility( + visible = isShareExpanded, + enter = fadeIn() + slideInVertically { it / 2 } + scaleIn(), + exit = fadeOut() + slideOutVertically { it / 2 } + scaleOut(), + modifier = Modifier + .align(Alignment.BottomEnd) + .offset(y = (-65).dp) + .wrapContentWidth(unbounded = true) + ) { + Row( + horizontalArrangement = Arrangement.spacedBy(8.dp), + verticalAlignment = Alignment.CenterVertically + ) { + MyFAB( + onClick = { + sharedScreenModel.toggleQRCodeVisibility() + sharedScreenModel.setExpandedFAB(false) + isShareExpanded = false + }, + icon = Icons.Filled.QrCode2 + ) + + MyFAB( + onClick = { + showPrintSettings = !showPrintSettings + isShareExpanded = false + }, + icon = Icons.Filled.Print + ) + + MyFAB( + onClick = { + isShareExpanded = false + scope.launch { + withContext(Dispatchers.IO) { + try { + val cleanS = + songTitle.replace(' ', '_') + val exportName = + "${cleanS.ifEmpty { "partition" }}.mid" + val savedPath = + solfaScreenModel.fileRepository.pickSavePath( + defaultName = exportName, + title = "Enregistrer le fichier MIDI" + ) + + if (!savedPath.isNullOrEmpty()) { + val transpositionInterval = + sharedScreenModel.transpositionInterval.value + val bpm = + sharedScreenModel.getBpmFlow().value + ?: 120f + solfaScreenModel.generateMidiFile( + bpm, + savedPath, + transpositionInterval + ) + println("Fichier MIDI enregistré avec succès sous : $savedPath") + } + } catch (e: Exception) { + e.printStackTrace() + } + } + } + }, + icon = Icons.Filled.AudioFile + ) + } + } + + MyFAB( + onClick = { isShareExpanded = !isShareExpanded }, + icon = Icons.Filled.Share + ) + } + } } if (!showMidiCtrl && !isSearchActive) { + AnimatedVisibility( + visible = isExpanded, + enter = fadeIn() + scaleIn() + slideInHorizontally { it / 2 }, + exit = fadeOut() + scaleOut() + slideOutHorizontally { it / 2 } + ) { + MyFAB( + onClick = { + sharedScreenModel.setMidiCtrl(!showMidiCtrl) + }, + icon = Icons.Filled.PlayCircle + ) + } MyFAB( onClick = { sharedScreenModel.setExpandedFAB(!isExpanded) @@ -887,13 +913,20 @@ fun MainScreenWithDrawer( icon = if (isExpanded) Icons.Filled.Close else Icons.Filled.Menu ) } - AnimatedVisibility( - visible = showMidiCtrl, - enter = fadeIn() + scaleIn() + slideInVertically { it / 2 }, - exit = fadeOut() + scaleOut() + slideOutVertically { it / 2 } + } + AnimatedVisibility( + visible = showMidiCtrl, + enter = fadeIn() + scaleIn() + slideInHorizontally { it / 2 }, + exit = fadeOut() + scaleOut() + slideOutHorizontally { it / 2 } + ) { + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.Start, + verticalAlignment = Alignment.CenterVertically ) { Box( - modifier = Modifier.fillMaxWidth(0.9f) + modifier = Modifier.fillMaxWidth() + .padding(top = 15.dp) ) { if (player != null) { MidiControlPanel( @@ -927,13 +960,26 @@ fun MainScreenWithDrawer( } else { Text("Sélectionner un morceau") } + Box( + modifier = Modifier + .align(Alignment.TopEnd) + .offset(y = (-30).dp, x = (-10).dp) + ) { + MyFAB( + onClick = { + sharedScreenModel.setMidiCtrl(false) + }, + icon = Icons.Filled.StopCircle + ) + } } } } } } } - }) { paddingValues -> + } + ) { paddingValues -> Column( modifier = Modifier