diff --git a/composeApp/src/commonMain/composeResources/files/ews-456.txt b/composeApp/src/commonMain/composeResources/files/ews-456.txt index 85f4b88..65f8374 100644 --- a/composeApp/src/commonMain/composeResources/files/ews-456.txt +++ b/composeApp/src/commonMain/composeResources/files/ews-456.txt @@ -4,6 +4,6 @@ N1:s,s,-l,t,ds,drs,rm/mfl,fmdmmrl,-r/s,s,-l,t,ds,drs,rm/msfrdt,dmmrd/mfsmfssmdrm N2:m,m,s,f,f,m,m,s,s,s,s,s,/s,l,f,l,s,s,s,F,F,l,-s,/f,m,s,f,f,m,m,s,s,s,s,s,/T,l,l,l,s,s,s,s,s,f,m,/s,s,ds,s,ds,s,s,s,s,s,/s,dt,t,dt,s,s,s,s,s,s,/m,m,s,f,f,m,m,s,s,s,s,s,/T,l,l,l,s,s,s,s,s,f,m, N3:dd-t,s,s,ddt,t,t,d/d7l,l,rdt,/t,d-t,s,s,ddt,t,t,d/ddrfmrmddt,d/drmdrmmddt,dt,/t,drrdrrt,ddt,d/dd-t,s,s,ddt,t,t,d/ddrfmrmddt,d N4:d,d,m,s,s,d,d,m,s,s,s,d/dfffd,m,d,r,r,F-s,/s,d,m,s,s,d,d,m,s,s,s,d/dfffs,6d,/d7d,m,r,d,s,/s,7fm,m,r,d,/d,d,m,s,s,d,d,m,s,s,s,d/dfffs,s,s,s,s,s,d, -E1:To God be the glo_ry, great things He has done,/so loved He the world that He gave us His Son,/who yield_ed His life an a_tone_ment for sin,/and o_pened the life gate that all may go in./Praise the Lord, praise the Lord, let the earth hear His voice!/Praise the Lord, praise the Lord, let the peo_ple re_joice!/O come to the Fa_ther through Je_sus the Son, and give Him the glo_ry, great things He has done. +E1:To God be the glo_ry, great things He has done,/so loved He the world that He gave us His Son,/who yield_ed His life an a_tone_ment for sin,/and o_pened the life gate that all may go in./${R=}Praise the Lord, praise the Lord, let the earth hear His voice!/Praise the Lord, praise the Lord, let the peo_ple re_joice!/O come to the Fa_ther through Je_sus the Son, and give Him the glo_ry, great things He has done. E2:O per_fect re_demp_tion, the pur_chase of blood,/to ev'_ry be_lie_ver the pro_mise of God;/the vi_lest of_fen_der who tru_ly be_lieves,/that mo_ment from Je_sus a par_don re_ceives. E3:Great things He has taught us, great things He has done,/and great our re_joi_cing through Je_sus the Son;/but pu_rer, and high_er, and great_er will be/our won_der, our rap_ture, when Je_sus we see. diff --git a/composeApp/src/commonMain/kotlin/mg/dot/feufaro/App.kt b/composeApp/src/commonMain/kotlin/mg/dot/feufaro/App.kt index e44913c..f45ab46 100644 --- a/composeApp/src/commonMain/kotlin/mg/dot/feufaro/App.kt +++ b/composeApp/src/commonMain/kotlin/mg/dot/feufaro/App.kt @@ -46,7 +46,7 @@ fun App() { if (currentDisplayConfig.playlist.isNotEmpty()) { try { sharedScreenModel.setPlaylist(currentDisplayConfig.playlist) - solfaScreenModel.loadNextInPlaylist() + solfaScreenModel.reload() } catch (e: Exception) { println("Error loading playlist : ${e.message}") } diff --git a/composeApp/src/commonMain/kotlin/mg/dot/feufaro/ScreenSolfa.kt b/composeApp/src/commonMain/kotlin/mg/dot/feufaro/ScreenSolfa.kt index e9f369e..d7625e7 100644 --- a/composeApp/src/commonMain/kotlin/mg/dot/feufaro/ScreenSolfa.kt +++ b/composeApp/src/commonMain/kotlin/mg/dot/feufaro/ScreenSolfa.kt @@ -21,6 +21,7 @@ import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -46,7 +47,7 @@ object ScreenSolfa : Screen { val solfaScreenModel = koinScreenModel() var menuPosition by remember { mutableStateOf(Offset.Zero)} var showContextualMenu by remember { mutableStateOf(false)} - var gridWidthPx by remember { mutableStateOf(0) } + var gridWidthPx by rememberSaveable { mutableStateOf(0) } val sharedScreenModel = koinScreenModel() val tuoList by sharedScreenModel.tuoList.collectAsState() val measure by sharedScreenModel.measure.collectAsState() @@ -86,7 +87,6 @@ object ScreenSolfa : Screen { .weight(1f) .verticalScroll(rememberScrollState()) ) { - val stanza: Int by sharedScreenModel.stanza.collectAsState() FlowRow( modifier = Modifier.fillMaxWidth() .windowInsetsPadding(WindowInsets.safeDrawing) @@ -130,7 +130,7 @@ object ScreenSolfa : Screen { MGButton( enabled = (i != stanza.toInt()), onClick = { - sharedScreenModel.setStanza(i.toString()) + sharedScreenModel.setStanza(i) }, modifier = Modifier.padding(horizontal = 4.dp) ) { diff --git a/composeApp/src/commonMain/kotlin/mg/dot/feufaro/di/AppModule.kt b/composeApp/src/commonMain/kotlin/mg/dot/feufaro/di/AppModule.kt index 26466c3..e7b4e81 100644 --- a/composeApp/src/commonMain/kotlin/mg/dot/feufaro/di/AppModule.kt +++ b/composeApp/src/commonMain/kotlin/mg/dot/feufaro/di/AppModule.kt @@ -1,29 +1,21 @@ package mg.dot.feufaro.di -import PlaylistRepository import SharedScreenModel import mg.dot.feufaro.CommonFileRepository import mg.dot.feufaro.FileRepository import mg.dot.feufaro.DisplayConfigManager // Importez DisplayConfigManager -import mg.dot.feufaro.config.AppConfig import mg.dot.feufaro.musicXML.MusicXML import mg.dot.feufaro.solfa.Solfa import mg.dot.feufaro.viewmodel.SolfaScreenModel import org.koin.dsl.module import org.koin.core.module.dsl.singleOf -import org.koin.core.module.Module -import org.koin.core.module.dsl.viewModel val commonModule = module { - // Déclarez FileRepository comme un singleton. - // L'implémentation concrète (actual) sera résolue par Koin en fonction de la plateforme. - // Pour Android, Koin injectera le Context que vous avez fourni via androidContext(). singleOf(::MusicXML) single { CommonFileRepository() } single { DisplayConfigManager(fileRepository = get())} - single { SharedScreenModel(get()) } - //viewModel { SharedViewModel() } - single { PlaylistRepository() } + single { SharedScreenModel() } + single { Solfa(get(), get()) } single { SolfaScreenModel(get()) } } \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/mg/dot/feufaro/solfa/POneStanzaLyrics.kt b/composeApp/src/commonMain/kotlin/mg/dot/feufaro/solfa/POneStanzaLyrics.kt index 59cf910..ed2db95 100644 --- a/composeApp/src/commonMain/kotlin/mg/dot/feufaro/solfa/POneStanzaLyrics.kt +++ b/composeApp/src/commonMain/kotlin/mg/dot/feufaro/solfa/POneStanzaLyrics.kt @@ -2,6 +2,9 @@ package mg.dot.feufaro.solfa class POneStanzaLyrics { private val lyrics: MutableList = mutableListOf("") + fun getLyrics(stanzaNumber: Int) : String { + return this.lyrics[stanzaNumber] + } fun setLyrics(stanzaNumber: Int, lyrics: String) { while (this.lyrics.size <= stanzaNumber) { this.lyrics.add("") diff --git a/composeApp/src/commonMain/kotlin/mg/dot/feufaro/solfa/Solfa.kt b/composeApp/src/commonMain/kotlin/mg/dot/feufaro/solfa/Solfa.kt index 74765e4..a07d8d8 100644 --- a/composeApp/src/commonMain/kotlin/mg/dot/feufaro/solfa/Solfa.kt +++ b/composeApp/src/commonMain/kotlin/mg/dot/feufaro/solfa/Solfa.kt @@ -13,6 +13,7 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository private val N: MutableList = mutableListOf() private val L: MutableList = mutableListOf() private val unparsedNote = mutableListOf() + private var refrainBeginsAt = -1 companion object { val REGEX_SHIFT_PAREN_UPWARD = Regex("([^a-yA-Y\\(\\[]+)([\\)\\]])") val REGEX_SHIFT_PAREN_DOWNWARD = Regex("([\\(\\[])([^a-yA-y\\)\\]]+)") @@ -23,7 +24,7 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository val REGEX_TEMPLATE_COMMENT = Regex("(\\$[A-Z]|\\$\\{[^\\}]*\\})") val REGEX_REPETITION = Regex("([zdrmfslt-](?>[',]*))([1-9][0-9]*)") val REGEX_PARSE_META = Regex("\\|(?=[a-z]:)") - val REGEX_LYRICS_COMMENT = Regex("\\$\\{([^\\}]*)\\}") + val REGEX_LYRICS_COMMENT = Regex("\\$\\{([^\\}]:[^\\}]*)\\}") val REGEX_LYRICS_REPETITION = Regex("_(\\d)") val REGEX_VOWELS_STAGE1 = Regex("[aeiouyàéỳ,;\\.\\-:!](?![ aeiouyàéỳ,;\\.\\-:!])", RegexOption.IGNORE_CASE) val REGEX_VOWELS_STAGE2 = Regex("([aeiouyàéỳ,;\\.\\-:!])__", RegexOption.IGNORE_CASE) @@ -122,7 +123,9 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository nextNIndex = -1 nextLIndex = -1 lyricsComment.clear() - sharedScreenModel.setStanza("1") + if (sharedScreenModel.stanza.value == 0) { + sharedScreenModel.setStanza(1) + } sharedScreenModel.setNbStanzas(0) TimeUnitObject.hasMarker(false) lines.forEach { line -> @@ -449,11 +452,16 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository arrayLyrics.forEachIndexed { i, lyricsItem -> addLyricsItem(stanzaNumber, i, lyricsItem) } + if (refrainBeginsAt > 0 && stanzaNumber > 1) { + copyRefrainToStanza(stanzaNumber) + } + if (lyricsComment.isNotEmpty()) { val lyricsIterator = lyricsComment.iterator() while (lyricsIterator.hasNext()) { val item = lyricsIterator.next() - if (item.substring(0, 4) == "\${D:") { + // ${D:xxx} lyrics of DC and DSs + if (item.substring(0, 4) == $$"${D:") { item.replace(REGEX_LYRICS_COMMENT, "$1").addHyphens().split(Regex("[_/]")).drop(1).forEachIndexed { i, xval -> appendLyricsItem(stanzaNumber, i, xval) } @@ -502,11 +510,28 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository lyricsComment.addAll(matchResult) } } + private fun defineRefrainFrom(tuoNumber: Int) { + refrainBeginsAt = tuoNumber + } + private fun copyRefrainToStanza(stanzaNumber: Int) { + for (i in refrainBeginsAt..L.size-1) { + L[i].setLyrics(stanzaNumber, L[i].getLyrics(1)) + } + } private fun addLyricsItem(stanzaNumber: Int, i: Int, lyricsItem: String) { while (L.size <= i) { L.add(POneStanzaLyrics()) } - L[i].setLyrics(stanzaNumber, lyricsItem) + val strippedLyrics = + if (lyricsItem.contains($$"${R=}")) { + if (stanzaNumber == 1) { + defineRefrainFrom(i) + } + lyricsItem.replace($$"${R=}", "") + } else { + lyricsItem + } + L[i].setLyrics(stanzaNumber, strippedLyrics) } private fun appendLyricsItem(stanzaNumber: Int, i: Int, lyricsItem: String) { if (L.size > i) { diff --git a/composeApp/src/commonMain/kotlin/mg/dot/feufaro/viewmodel/SharedScreenModel.kt b/composeApp/src/commonMain/kotlin/mg/dot/feufaro/viewmodel/SharedScreenModel.kt index 60e8b2b..2b6daf2 100644 --- a/composeApp/src/commonMain/kotlin/mg/dot/feufaro/viewmodel/SharedScreenModel.kt +++ b/composeApp/src/commonMain/kotlin/mg/dot/feufaro/viewmodel/SharedScreenModel.kt @@ -5,19 +5,7 @@ import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow import mg.dot.feufaro.solfa.TimeUnitObject -// Supposons que vous ayez une autre dépendance, par exemple pour gérer les données de la playlist -class PlaylistRepository { - private val _playlists = MutableStateFlow(listOf("Playlist par défaut 1", "Playlist par défaut 2")) - val playlists: StateFlow> = _playlists.asStateFlow() - - fun addPlaylist(name: String) { - _playlists.value = _playlists.value + name - } -} - -class SharedScreenModel( - private val playlistRepository: PlaylistRepository // Exemple de dépendance partagée -) : ScreenModel { +class SharedScreenModel() : ScreenModel { private val _data = MutableStateFlow("Next ...") val data: StateFlow = _data.asStateFlow() private val _measure = MutableStateFlow("") @@ -42,7 +30,7 @@ class SharedScreenModel( private var _playlist = MutableStateFlow>(emptyList()) val playlist: StateFlow> = _playlist.asStateFlow() - private var _nextPlayed = MutableStateFlow(-1) + private var _nextPlayed = MutableStateFlow(0) val nextPlayed: StateFlow = _nextPlayed.asStateFlow() private val tempTimeUnitObjectList = mutableListOf() var _hasMarker = MutableStateFlow( false) @@ -69,9 +57,9 @@ class SharedScreenModel( fun setSongTitle(theTitle: String) { _songTitle.value = theTitle } - fun setStanza(theStanza: String) { + fun setStanza(theStanza: Int) { try { - _stanza.value = theStanza.toInt() + _stanza.value = theStanza } catch(e: NumberFormatException) { _stanza.value = 0 } @@ -101,23 +89,11 @@ class SharedScreenModel( fun playNext() { val nextIndex = (_nextPlayed.value + 1) % _playlist.value.size _nextPlayed.value = nextIndex + setStanza(1) } fun currentPlayed(): String { val playlistIndex = _nextPlayed.value return _playlist.value[playlistIndex] } - private val _sharedData = MutableStateFlow("Donnée partagée initiale") - val sharedData: StateFlow = _sharedData.asStateFlow() - val playlists: StateFlow> = playlistRepository.playlists - - fun updateSharedData(newData: String) { - _sharedData.value = newData - } - - fun addNewPlaylist(name: String) { - playlistRepository.addPlaylist(name) - } - - // Vous pouvez ajouter d'autres fonctions pour interagir avec les données partagées } \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/mg/dot/feufaro/viewmodel/SolfaScreenModel.kt b/composeApp/src/commonMain/kotlin/mg/dot/feufaro/viewmodel/SolfaScreenModel.kt index b81124b..1ff642c 100644 --- a/composeApp/src/commonMain/kotlin/mg/dot/feufaro/viewmodel/SolfaScreenModel.kt +++ b/composeApp/src/commonMain/kotlin/mg/dot/feufaro/viewmodel/SolfaScreenModel.kt @@ -10,4 +10,7 @@ class SolfaScreenModel ( fun loadNextInPlaylist() { solfa.loadNextInPlaylist() } + fun reload() { + solfa.loadSolfa() + } } \ No newline at end of file