detail: switch to sort dialogs
Use the new sort dialogs on in detail views.
This commit is contained in:
parent
ec7f2d979a
commit
3340914c51
13 changed files with 230 additions and 211 deletions
|
@ -41,7 +41,6 @@ import org.oxycblt.auxio.list.Item
|
||||||
import org.oxycblt.auxio.list.ListFragment
|
import org.oxycblt.auxio.list.ListFragment
|
||||||
import org.oxycblt.auxio.list.ListViewModel
|
import org.oxycblt.auxio.list.ListViewModel
|
||||||
import org.oxycblt.auxio.list.Menu
|
import org.oxycblt.auxio.list.Menu
|
||||||
import org.oxycblt.auxio.list.Sort
|
|
||||||
import org.oxycblt.auxio.music.Album
|
import org.oxycblt.auxio.music.Album
|
||||||
import org.oxycblt.auxio.music.Music
|
import org.oxycblt.auxio.music.Music
|
||||||
import org.oxycblt.auxio.music.MusicParent
|
import org.oxycblt.auxio.music.MusicParent
|
||||||
|
@ -196,30 +195,7 @@ class AlbumDetailFragment :
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onOpenSortMenu(anchor: View) {
|
override fun onOpenSortMenu(anchor: View) {
|
||||||
openMenu(anchor, R.menu.sort_album) {
|
findNavController().navigateSafe(AlbumDetailFragmentDirections.sort())
|
||||||
// Select the corresponding sort mode option
|
|
||||||
val sort = detailModel.albumSongSort
|
|
||||||
unlikelyToBeNull(menu.findItem(sort.mode.itemId)).isChecked = true
|
|
||||||
// Select the corresponding sort direction option
|
|
||||||
val directionItemId =
|
|
||||||
when (sort.direction) {
|
|
||||||
Sort.Direction.ASCENDING -> R.id.option_sort_asc
|
|
||||||
Sort.Direction.DESCENDING -> R.id.option_sort_dec
|
|
||||||
}
|
|
||||||
unlikelyToBeNull(menu.findItem(directionItemId)).isChecked = true
|
|
||||||
setOnMenuItemClickListener { item ->
|
|
||||||
item.isChecked = !item.isChecked
|
|
||||||
detailModel.albumSongSort =
|
|
||||||
when (item.itemId) {
|
|
||||||
// Sort direction options
|
|
||||||
R.id.option_sort_asc -> sort.withDirection(Sort.Direction.ASCENDING)
|
|
||||||
R.id.option_sort_dec -> sort.withDirection(Sort.Direction.DESCENDING)
|
|
||||||
// Any other option is a sort mode
|
|
||||||
else -> sort.withMode(unlikelyToBeNull(Sort.Mode.fromItemId(item.itemId)))
|
|
||||||
}
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onNavigateToParentArtist() {
|
override fun onNavigateToParentArtist() {
|
||||||
|
|
|
@ -41,7 +41,6 @@ import org.oxycblt.auxio.list.Item
|
||||||
import org.oxycblt.auxio.list.ListFragment
|
import org.oxycblt.auxio.list.ListFragment
|
||||||
import org.oxycblt.auxio.list.ListViewModel
|
import org.oxycblt.auxio.list.ListViewModel
|
||||||
import org.oxycblt.auxio.list.Menu
|
import org.oxycblt.auxio.list.Menu
|
||||||
import org.oxycblt.auxio.list.Sort
|
|
||||||
import org.oxycblt.auxio.music.Album
|
import org.oxycblt.auxio.music.Album
|
||||||
import org.oxycblt.auxio.music.Artist
|
import org.oxycblt.auxio.music.Artist
|
||||||
import org.oxycblt.auxio.music.Music
|
import org.oxycblt.auxio.music.Music
|
||||||
|
@ -202,32 +201,7 @@ class ArtistDetailFragment :
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onOpenSortMenu(anchor: View) {
|
override fun onOpenSortMenu(anchor: View) {
|
||||||
openMenu(anchor, R.menu.sort_artist) {
|
findNavController().navigateSafe(ArtistDetailFragmentDirections.sort())
|
||||||
// Select the corresponding sort mode option
|
|
||||||
val sort = detailModel.artistSongSort
|
|
||||||
unlikelyToBeNull(menu.findItem(sort.mode.itemId)).isChecked = true
|
|
||||||
// Select the corresponding sort direction option
|
|
||||||
val directionItemId =
|
|
||||||
when (sort.direction) {
|
|
||||||
Sort.Direction.ASCENDING -> R.id.option_sort_asc
|
|
||||||
Sort.Direction.DESCENDING -> R.id.option_sort_dec
|
|
||||||
}
|
|
||||||
unlikelyToBeNull(menu.findItem(directionItemId)).isChecked = true
|
|
||||||
setOnMenuItemClickListener { item ->
|
|
||||||
item.isChecked = !item.isChecked
|
|
||||||
|
|
||||||
detailModel.artistSongSort =
|
|
||||||
when (item.itemId) {
|
|
||||||
// Sort direction options
|
|
||||||
R.id.option_sort_asc -> sort.withDirection(Sort.Direction.ASCENDING)
|
|
||||||
R.id.option_sort_dec -> sort.withDirection(Sort.Direction.DESCENDING)
|
|
||||||
// Any other option is a sort mode
|
|
||||||
else -> sort.withMode(unlikelyToBeNull(Sort.Mode.fromItemId(item.itemId)))
|
|
||||||
}
|
|
||||||
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateArtist(artist: Artist?) {
|
private fun updateArtist(artist: Artist?) {
|
||||||
|
|
|
@ -109,13 +109,8 @@ constructor(
|
||||||
get() = _albumInstructions
|
get() = _albumInstructions
|
||||||
|
|
||||||
/** The current [Sort] used for [Song]s in [albumList]. */
|
/** The current [Sort] used for [Song]s in [albumList]. */
|
||||||
var albumSongSort: Sort
|
val albumSongSort: Sort
|
||||||
get() = musicSettings.albumSongSort
|
get() = musicSettings.albumSongSort
|
||||||
set(value) {
|
|
||||||
musicSettings.albumSongSort = value
|
|
||||||
// Refresh the album list to reflect the new sort.
|
|
||||||
currentAlbum.value?.let { refreshAlbumList(it, true) }
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The [PlaySong] instructions to use when playing a [Song] from [Album] details. */
|
/** The [PlaySong] instructions to use when playing a [Song] from [Album] details. */
|
||||||
val playInAlbumWith
|
val playInAlbumWith
|
||||||
|
@ -365,6 +360,11 @@ constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun applyAlbumSongSort(sort: Sort) {
|
||||||
|
musicSettings.albumSongSort = sort
|
||||||
|
_currentAlbum.value?.let { refreshAlbumList(it, true) }
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a new [currentArtist] from it's [Music.UID]. [currentArtist] and [artistList] will be
|
* Set a new [currentArtist] from it's [Music.UID]. [currentArtist] and [artistList] will be
|
||||||
* updated to align with the new [Artist].
|
* updated to align with the new [Artist].
|
||||||
|
@ -380,6 +380,11 @@ constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun applyArtistSongSort(sort: Sort) {
|
||||||
|
musicSettings.artistSongSort = sort
|
||||||
|
_currentArtist.value?.let { refreshArtistList(it, true) }
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a new [currentGenre] from it's [Music.UID]. [currentGenre] and [genreList] will be
|
* Set a new [currentGenre] from it's [Music.UID]. [currentGenre] and [genreList] will be
|
||||||
* updated to align with the new album.
|
* updated to align with the new album.
|
||||||
|
@ -395,6 +400,11 @@ constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun applyGenreSongSort(sort: Sort) {
|
||||||
|
musicSettings.genreSongSort = sort
|
||||||
|
_currentGenre.value?.let { refreshGenreList(it, true) }
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a new [currentPlaylist] from it's [Music.UID]. If the [Music.UID] differs,
|
* Set a new [currentPlaylist] from it's [Music.UID]. If the [Music.UID] differs,
|
||||||
* [currentPlaylist] and [currentPlaylist] will be updated to align with the new album.
|
* [currentPlaylist] and [currentPlaylist] will be updated to align with the new album.
|
||||||
|
|
|
@ -41,7 +41,6 @@ import org.oxycblt.auxio.list.Item
|
||||||
import org.oxycblt.auxio.list.ListFragment
|
import org.oxycblt.auxio.list.ListFragment
|
||||||
import org.oxycblt.auxio.list.ListViewModel
|
import org.oxycblt.auxio.list.ListViewModel
|
||||||
import org.oxycblt.auxio.list.Menu
|
import org.oxycblt.auxio.list.Menu
|
||||||
import org.oxycblt.auxio.list.Sort
|
|
||||||
import org.oxycblt.auxio.music.Artist
|
import org.oxycblt.auxio.music.Artist
|
||||||
import org.oxycblt.auxio.music.Genre
|
import org.oxycblt.auxio.music.Genre
|
||||||
import org.oxycblt.auxio.music.Music
|
import org.oxycblt.auxio.music.Music
|
||||||
|
@ -199,30 +198,7 @@ class GenreDetailFragment :
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onOpenSortMenu(anchor: View) {
|
override fun onOpenSortMenu(anchor: View) {
|
||||||
openMenu(anchor, R.menu.sort_genre) {
|
findNavController().navigateSafe(GenreDetailFragmentDirections.sort())
|
||||||
// Select the corresponding sort mode option
|
|
||||||
val sort = detailModel.genreSongSort
|
|
||||||
unlikelyToBeNull(menu.findItem(sort.mode.itemId)).isChecked = true
|
|
||||||
// Select the corresponding sort direction option
|
|
||||||
val directionItemId =
|
|
||||||
when (sort.direction) {
|
|
||||||
Sort.Direction.ASCENDING -> R.id.option_sort_asc
|
|
||||||
Sort.Direction.DESCENDING -> R.id.option_sort_dec
|
|
||||||
}
|
|
||||||
unlikelyToBeNull(menu.findItem(directionItemId)).isChecked = true
|
|
||||||
setOnMenuItemClickListener { item ->
|
|
||||||
item.isChecked = !item.isChecked
|
|
||||||
detailModel.genreSongSort =
|
|
||||||
when (item.itemId) {
|
|
||||||
// Sort direction options
|
|
||||||
R.id.option_sort_asc -> sort.withDirection(Sort.Direction.ASCENDING)
|
|
||||||
R.id.option_sort_dec -> sort.withDirection(Sort.Direction.DESCENDING)
|
|
||||||
// Any other option is a sort mode
|
|
||||||
else -> sort.withMode(unlikelyToBeNull(Sort.Mode.fromItemId(item.itemId)))
|
|
||||||
}
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updatePlaylist(genre: Genre?) {
|
private fun updatePlaylist(genre: Genre?) {
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 Auxio Project
|
||||||
|
* AlbumSongSortDialog.kt is part of Auxio.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.oxycblt.auxio.detail.sort
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import androidx.fragment.app.activityViewModels
|
||||||
|
import androidx.navigation.fragment.findNavController
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
import org.oxycblt.auxio.databinding.DialogSortBinding
|
||||||
|
import org.oxycblt.auxio.detail.DetailViewModel
|
||||||
|
import org.oxycblt.auxio.list.Sort
|
||||||
|
import org.oxycblt.auxio.list.sort.SortDialog
|
||||||
|
import org.oxycblt.auxio.music.Album
|
||||||
|
import org.oxycblt.auxio.util.collectImmediately
|
||||||
|
import org.oxycblt.auxio.util.logD
|
||||||
|
|
||||||
|
@AndroidEntryPoint
|
||||||
|
class AlbumSongSortDialog : SortDialog() {
|
||||||
|
private val detailModel: DetailViewModel by activityViewModels()
|
||||||
|
|
||||||
|
override fun onBindingCreated(binding: DialogSortBinding, savedInstanceState: Bundle?) {
|
||||||
|
super.onBindingCreated(binding, savedInstanceState)
|
||||||
|
|
||||||
|
// --- VIEWMODEL SETUP ---
|
||||||
|
collectImmediately(detailModel.currentAlbum, ::updateAlbum)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getInitialSort() = detailModel.albumSongSort
|
||||||
|
|
||||||
|
override fun applyChosenSort(sort: Sort) {
|
||||||
|
detailModel.applyAlbumSongSort(sort)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getModeChoices() = listOf(Sort.Mode.ByDisc, Sort.Mode.ByTrack)
|
||||||
|
|
||||||
|
private fun updateAlbum(album: Album?) {
|
||||||
|
if (album == null) {
|
||||||
|
logD("No album to sort, navigating away")
|
||||||
|
findNavController().navigateUp()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 Auxio Project
|
||||||
|
* ArtistSongSortDialog.kt is part of Auxio.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.oxycblt.auxio.detail.sort
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import androidx.fragment.app.activityViewModels
|
||||||
|
import androidx.navigation.fragment.findNavController
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
import org.oxycblt.auxio.databinding.DialogSortBinding
|
||||||
|
import org.oxycblt.auxio.detail.DetailViewModel
|
||||||
|
import org.oxycblt.auxio.list.Sort
|
||||||
|
import org.oxycblt.auxio.list.sort.SortDialog
|
||||||
|
import org.oxycblt.auxio.music.Artist
|
||||||
|
import org.oxycblt.auxio.util.collectImmediately
|
||||||
|
import org.oxycblt.auxio.util.logD
|
||||||
|
|
||||||
|
@AndroidEntryPoint
|
||||||
|
class ArtistSongSortDialog : SortDialog() {
|
||||||
|
private val detailModel: DetailViewModel by activityViewModels()
|
||||||
|
|
||||||
|
override fun onBindingCreated(binding: DialogSortBinding, savedInstanceState: Bundle?) {
|
||||||
|
super.onBindingCreated(binding, savedInstanceState)
|
||||||
|
|
||||||
|
// --- VIEWMODEL SETUP ---
|
||||||
|
collectImmediately(detailModel.currentArtist, ::updateArtist)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getInitialSort() = detailModel.artistSongSort
|
||||||
|
|
||||||
|
override fun applyChosenSort(sort: Sort) {
|
||||||
|
detailModel.applyArtistSongSort(sort)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getModeChoices() =
|
||||||
|
listOf(Sort.Mode.ByName, Sort.Mode.ByAlbum, Sort.Mode.ByDate, Sort.Mode.ByDuration)
|
||||||
|
|
||||||
|
private fun updateArtist(artist: Artist?) {
|
||||||
|
if (artist == null) {
|
||||||
|
logD("No artist to sort, navigating away")
|
||||||
|
findNavController().navigateUp()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 Auxio Project
|
||||||
|
* GenreSongSortDialog.kt is part of Auxio.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.oxycblt.auxio.detail.sort
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import androidx.fragment.app.activityViewModels
|
||||||
|
import androidx.navigation.fragment.findNavController
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
import org.oxycblt.auxio.databinding.DialogSortBinding
|
||||||
|
import org.oxycblt.auxio.detail.DetailViewModel
|
||||||
|
import org.oxycblt.auxio.list.Sort
|
||||||
|
import org.oxycblt.auxio.list.sort.SortDialog
|
||||||
|
import org.oxycblt.auxio.music.Genre
|
||||||
|
import org.oxycblt.auxio.util.collectImmediately
|
||||||
|
import org.oxycblt.auxio.util.logD
|
||||||
|
|
||||||
|
@AndroidEntryPoint
|
||||||
|
class GenreSongSortDialog : SortDialog() {
|
||||||
|
private val detailModel: DetailViewModel by activityViewModels()
|
||||||
|
|
||||||
|
override fun onBindingCreated(binding: DialogSortBinding, savedInstanceState: Bundle?) {
|
||||||
|
super.onBindingCreated(binding, savedInstanceState)
|
||||||
|
|
||||||
|
// --- VIEWMODEL SETUP ---
|
||||||
|
collectImmediately(detailModel.currentGenre, ::updateGenre)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getInitialSort() = detailModel.genreSongSort
|
||||||
|
|
||||||
|
override fun applyChosenSort(sort: Sort) {
|
||||||
|
detailModel.applyGenreSongSort(sort)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getModeChoices() =
|
||||||
|
listOf(
|
||||||
|
Sort.Mode.ByName,
|
||||||
|
Sort.Mode.ByArtist,
|
||||||
|
Sort.Mode.ByAlbum,
|
||||||
|
Sort.Mode.ByDate,
|
||||||
|
Sort.Mode.ByDuration)
|
||||||
|
|
||||||
|
private fun updateGenre(genre: Genre?) {
|
||||||
|
if (genre == null) {
|
||||||
|
logD("No genre to sort, navigating away")
|
||||||
|
findNavController().navigateUp()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,14 +18,9 @@
|
||||||
|
|
||||||
package org.oxycblt.auxio.list
|
package org.oxycblt.auxio.list
|
||||||
|
|
||||||
import android.view.View
|
|
||||||
import androidx.annotation.MenuRes
|
|
||||||
import androidx.appcompat.widget.PopupMenu
|
|
||||||
import androidx.core.view.MenuCompat
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import androidx.viewbinding.ViewBinding
|
import androidx.viewbinding.ViewBinding
|
||||||
import org.oxycblt.auxio.music.Music
|
import org.oxycblt.auxio.music.Music
|
||||||
import org.oxycblt.auxio.util.logD
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Fragment containing a selectable list.
|
* A Fragment containing a selectable list.
|
||||||
|
@ -34,14 +29,6 @@ import org.oxycblt.auxio.util.logD
|
||||||
*/
|
*/
|
||||||
abstract class ListFragment<in T : Music, VB : ViewBinding> :
|
abstract class ListFragment<in T : Music, VB : ViewBinding> :
|
||||||
SelectionFragment<VB>(), SelectableListListener<T> {
|
SelectionFragment<VB>(), SelectableListListener<T> {
|
||||||
private var currentMenu: PopupMenu? = null
|
|
||||||
|
|
||||||
override fun onDestroyBinding(binding: VB) {
|
|
||||||
super.onDestroyBinding(binding)
|
|
||||||
currentMenu?.dismiss()
|
|
||||||
currentMenu = null
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when [onClick] is called, but does not result in the item being selected. This more or
|
* Called when [onClick] is called, but does not result in the item being selected. This more or
|
||||||
* less corresponds to an [onClick] implementation in a non-[ListFragment].
|
* less corresponds to an [onClick] implementation in a non-[ListFragment].
|
||||||
|
@ -63,30 +50,4 @@ abstract class ListFragment<in T : Music, VB : ViewBinding> :
|
||||||
final override fun onSelect(item: T) {
|
final override fun onSelect(item: T) {
|
||||||
listModel.select(item)
|
listModel.select(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Open a menu. This menu will be managed by the Fragment and closed when the view is destroyed.
|
|
||||||
* If a menu is already opened, this call is ignored.
|
|
||||||
*
|
|
||||||
* @param anchor The [View] to anchor the menu to.
|
|
||||||
* @param menuRes The resource of the menu to load.
|
|
||||||
* @param block A block that is ran within [PopupMenu] that allows further configuration.
|
|
||||||
*/
|
|
||||||
protected fun openMenu(anchor: View, @MenuRes menuRes: Int, block: PopupMenu.() -> Unit) {
|
|
||||||
if (currentMenu != null) {
|
|
||||||
logD("Menu already present, not launching")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
logD("Opening popup menu menu")
|
|
||||||
|
|
||||||
currentMenu =
|
|
||||||
PopupMenu(requireContext(), anchor).apply {
|
|
||||||
inflate(menuRes)
|
|
||||||
MenuCompat.setGroupDividerEnabled(menu, true)
|
|
||||||
block()
|
|
||||||
setOnDismissListener { currentMenu = null }
|
|
||||||
show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
package org.oxycblt.auxio.list
|
package org.oxycblt.auxio.list
|
||||||
|
|
||||||
import androidx.annotation.IdRes
|
import androidx.annotation.IdRes
|
||||||
|
import java.lang.IllegalStateException
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
import org.oxycblt.auxio.IntegerTable
|
import org.oxycblt.auxio.IntegerTable
|
||||||
import org.oxycblt.auxio.R
|
import org.oxycblt.auxio.R
|
||||||
|
@ -406,7 +407,7 @@ data class Sort(val mode: Mode, val direction: Direction) {
|
||||||
get() = IntegerTable.SORT_BY_DISC
|
get() = IntegerTable.SORT_BY_DISC
|
||||||
|
|
||||||
override val itemId: Int
|
override val itemId: Int
|
||||||
get() = R.id.option_sort_disc
|
get() = throw IllegalStateException()
|
||||||
|
|
||||||
override val stringRes: Int
|
override val stringRes: Int
|
||||||
get() = R.string.lbl_disc
|
get() = R.string.lbl_disc
|
||||||
|
@ -428,7 +429,7 @@ data class Sort(val mode: Mode, val direction: Direction) {
|
||||||
get() = IntegerTable.SORT_BY_TRACK
|
get() = IntegerTable.SORT_BY_TRACK
|
||||||
|
|
||||||
override val itemId: Int
|
override val itemId: Int
|
||||||
get() = R.id.option_sort_track
|
get() = throw IllegalStateException()
|
||||||
|
|
||||||
override val stringRes: Int
|
override val stringRes: Int
|
||||||
get() = R.string.lbl_track
|
get() = R.string.lbl_track
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<group android:checkableBehavior="single"
|
|
||||||
android:id="@+id/sort_modes">
|
|
||||||
<item
|
|
||||||
android:id="@+id/option_sort_disc"
|
|
||||||
android:title="@string/lbl_disc" />
|
|
||||||
<item
|
|
||||||
android:id="@+id/option_sort_track"
|
|
||||||
android:title="@string/lbl_track" />
|
|
||||||
</group>
|
|
||||||
<group android:checkableBehavior="single"
|
|
||||||
android:id="@+id/sort_direction">
|
|
||||||
<item
|
|
||||||
android:id="@+id/option_sort_asc"
|
|
||||||
android:title="@string/lbl_sort_asc" />
|
|
||||||
<item
|
|
||||||
android:id="@+id/option_sort_dec"
|
|
||||||
android:title="@string/lbl_sort_dsc" />
|
|
||||||
</group>
|
|
||||||
</menu>
|
|
|
@ -1,27 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<group android:checkableBehavior="single"
|
|
||||||
android:id="@+id/sort_modes">
|
|
||||||
<item
|
|
||||||
android:id="@+id/option_sort_name"
|
|
||||||
android:title="@string/lbl_name" />
|
|
||||||
<item
|
|
||||||
android:id="@+id/option_sort_album"
|
|
||||||
android:title="@string/lbl_album" />
|
|
||||||
<item
|
|
||||||
android:id="@+id/option_sort_year"
|
|
||||||
android:title="@string/lbl_date" />
|
|
||||||
<item
|
|
||||||
android:id="@+id/option_sort_duration"
|
|
||||||
android:title="@string/lbl_duration" />
|
|
||||||
</group>
|
|
||||||
<group android:checkableBehavior="single"
|
|
||||||
android:id="@+id/sort_direction">
|
|
||||||
<item
|
|
||||||
android:id="@+id/option_sort_asc"
|
|
||||||
android:title="@string/lbl_sort_asc" />
|
|
||||||
<item
|
|
||||||
android:id="@+id/option_sort_dec"
|
|
||||||
android:title="@string/lbl_sort_dsc" />
|
|
||||||
</group>
|
|
||||||
</menu>
|
|
|
@ -1,30 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<group android:checkableBehavior="single"
|
|
||||||
android:id="@+id/sort_modes">
|
|
||||||
<item
|
|
||||||
android:id="@+id/option_sort_name"
|
|
||||||
android:title="@string/lbl_name" />
|
|
||||||
<item
|
|
||||||
android:id="@+id/option_sort_artist"
|
|
||||||
android:title="@string/lbl_artist" />
|
|
||||||
<item
|
|
||||||
android:id="@+id/option_sort_album"
|
|
||||||
android:title="@string/lbl_album" />
|
|
||||||
<item
|
|
||||||
android:id="@+id/option_sort_year"
|
|
||||||
android:title="@string/lbl_date" />
|
|
||||||
<item
|
|
||||||
android:id="@+id/option_sort_duration"
|
|
||||||
android:title="@string/lbl_duration" />
|
|
||||||
</group>
|
|
||||||
<group android:checkableBehavior="single"
|
|
||||||
android:id="@+id/sort_direction">
|
|
||||||
<item
|
|
||||||
android:id="@+id/option_sort_asc"
|
|
||||||
android:title="@string/lbl_sort_asc" />
|
|
||||||
<item
|
|
||||||
android:id="@+id/option_sort_dec"
|
|
||||||
android:title="@string/lbl_sort_dsc" />
|
|
||||||
</group>
|
|
||||||
</menu>
|
|
|
@ -138,6 +138,9 @@
|
||||||
<argument
|
<argument
|
||||||
android:name="albumUid"
|
android:name="albumUid"
|
||||||
app:argType="org.oxycblt.auxio.music.Music$UID" />
|
app:argType="org.oxycblt.auxio.music.Music$UID" />
|
||||||
|
<action
|
||||||
|
android:id="@+id/sort"
|
||||||
|
app:destination="@+id/album_song_sort_dialog" />
|
||||||
<action
|
<action
|
||||||
android:id="@+id/show_song"
|
android:id="@+id/show_song"
|
||||||
app:destination="@id/song_detail_dialog" />
|
app:destination="@id/song_detail_dialog" />
|
||||||
|
@ -162,11 +165,14 @@
|
||||||
<action
|
<action
|
||||||
android:id="@+id/play_from_genre"
|
android:id="@+id/play_from_genre"
|
||||||
app:destination="@id/play_from_genre_dialog" />
|
app:destination="@id/play_from_genre_dialog" />
|
||||||
<action
|
|
||||||
android:id="@+id/sort"
|
|
||||||
app:destination="@id/sort_dialog" />
|
|
||||||
</fragment>
|
</fragment>
|
||||||
|
|
||||||
|
<dialog
|
||||||
|
android:id="@+id/album_song_sort_dialog"
|
||||||
|
android:name="org.oxycblt.auxio.detail.sort.AlbumSongSortDialog"
|
||||||
|
android:label="AlbumSongSortDialog"
|
||||||
|
tools:layout="@layout/dialog_sort" />
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/artist_detail_fragment"
|
android:id="@+id/artist_detail_fragment"
|
||||||
android:name="org.oxycblt.auxio.detail.ArtistDetailFragment"
|
android:name="org.oxycblt.auxio.detail.ArtistDetailFragment"
|
||||||
|
@ -175,6 +181,9 @@
|
||||||
<argument
|
<argument
|
||||||
android:name="artistUid"
|
android:name="artistUid"
|
||||||
app:argType="org.oxycblt.auxio.music.Music$UID" />
|
app:argType="org.oxycblt.auxio.music.Music$UID" />
|
||||||
|
<action
|
||||||
|
android:id="@+id/sort"
|
||||||
|
app:destination="@+id/artist_song_sort_dialog" />
|
||||||
<action
|
<action
|
||||||
android:id="@+id/show_song"
|
android:id="@+id/show_song"
|
||||||
app:destination="@id/song_detail_dialog" />
|
app:destination="@id/song_detail_dialog" />
|
||||||
|
@ -198,6 +207,12 @@
|
||||||
app:destination="@id/play_from_genre_dialog" />
|
app:destination="@id/play_from_genre_dialog" />
|
||||||
</fragment>
|
</fragment>
|
||||||
|
|
||||||
|
<dialog
|
||||||
|
android:id="@+id/artist_song_sort_dialog"
|
||||||
|
android:name="org.oxycblt.auxio.detail.sort.ArtistSongSortDialog"
|
||||||
|
android:label="ArtistSongSortDialog"
|
||||||
|
tools:layout="@layout/dialog_sort" />
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/genre_detail_fragment"
|
android:id="@+id/genre_detail_fragment"
|
||||||
android:name="org.oxycblt.auxio.detail.GenreDetailFragment"
|
android:name="org.oxycblt.auxio.detail.GenreDetailFragment"
|
||||||
|
@ -206,6 +221,9 @@
|
||||||
<argument
|
<argument
|
||||||
android:name="genreUid"
|
android:name="genreUid"
|
||||||
app:argType="org.oxycblt.auxio.music.Music$UID" />
|
app:argType="org.oxycblt.auxio.music.Music$UID" />
|
||||||
|
<action
|
||||||
|
android:id="@+id/sort"
|
||||||
|
app:destination="@+id/genre_song_sort_dialog" />
|
||||||
<action
|
<action
|
||||||
android:id="@+id/show_song"
|
android:id="@+id/show_song"
|
||||||
app:destination="@id/song_detail_dialog" />
|
app:destination="@id/song_detail_dialog" />
|
||||||
|
@ -232,6 +250,12 @@
|
||||||
app:destination="@id/play_from_artist_dialog" />
|
app:destination="@id/play_from_artist_dialog" />
|
||||||
</fragment>
|
</fragment>
|
||||||
|
|
||||||
|
<dialog
|
||||||
|
android:id="@+id/genre_song_sort_dialog"
|
||||||
|
android:name="org.oxycblt.auxio.detail.sort.GenreSongSortDialog"
|
||||||
|
android:label="GenreSongSortDialog"
|
||||||
|
tools:layout="@layout/dialog_sort" />
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/playlist_detail_fragment"
|
android:id="@+id/playlist_detail_fragment"
|
||||||
android:name="org.oxycblt.auxio.detail.PlaylistDetailFragment"
|
android:name="org.oxycblt.auxio.detail.PlaylistDetailFragment"
|
||||||
|
@ -391,10 +415,4 @@
|
||||||
android:name="parcel"
|
android:name="parcel"
|
||||||
app:argType="org.oxycblt.auxio.list.Menu$ForPlaylist$Parcel" />
|
app:argType="org.oxycblt.auxio.list.Menu$ForPlaylist$Parcel" />
|
||||||
</dialog>
|
</dialog>
|
||||||
|
|
||||||
<dialog
|
|
||||||
android:id="@+id/sort_dialog"
|
|
||||||
android:name="org.oxycblt.auxio.list.sort.SortDialog"
|
|
||||||
android:label="sort_dialog"
|
|
||||||
tools:layout="@layout/dialog_sort" />
|
|
||||||
</navigation>
|
</navigation>
|
Loading…
Reference in a new issue