android: Rework driver fragment
Applies settings upon selection and uses a new Driver model to represent the information in-view. Also switches from an async diff list to a plain one.
This commit is contained in:
parent
93239f191a
commit
6bfc3c530c
|
@ -13,16 +13,16 @@ import androidx.core.view.WindowInsetsCompat
|
||||||
import androidx.core.view.updatePadding
|
import androidx.core.view.updatePadding
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
import androidx.lifecycle.lifecycleScope
|
|
||||||
import androidx.navigation.findNavController
|
import androidx.navigation.findNavController
|
||||||
import androidx.navigation.fragment.navArgs
|
import androidx.navigation.fragment.navArgs
|
||||||
import androidx.recyclerview.widget.GridLayoutManager
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
import com.google.android.material.transition.MaterialSharedAxis
|
import com.google.android.material.transition.MaterialSharedAxis
|
||||||
import kotlinx.coroutines.flow.collectLatest
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.withContext
|
||||||
import org.yuzu.yuzu_emu.R
|
import org.yuzu.yuzu_emu.R
|
||||||
import org.yuzu.yuzu_emu.adapters.DriverAdapter
|
import org.yuzu.yuzu_emu.adapters.DriverAdapter
|
||||||
import org.yuzu.yuzu_emu.databinding.FragmentDriverManagerBinding
|
import org.yuzu.yuzu_emu.databinding.FragmentDriverManagerBinding
|
||||||
|
import org.yuzu.yuzu_emu.model.Driver.Companion.toDriver
|
||||||
import org.yuzu.yuzu_emu.model.DriverViewModel
|
import org.yuzu.yuzu_emu.model.DriverViewModel
|
||||||
import org.yuzu.yuzu_emu.model.HomeViewModel
|
import org.yuzu.yuzu_emu.model.HomeViewModel
|
||||||
import org.yuzu.yuzu_emu.utils.FileUtil
|
import org.yuzu.yuzu_emu.utils.FileUtil
|
||||||
|
@ -85,25 +85,6 @@ class DriverManagerFragment : Fragment() {
|
||||||
adapter = DriverAdapter(driverViewModel)
|
adapter = DriverAdapter(driverViewModel)
|
||||||
}
|
}
|
||||||
|
|
||||||
viewLifecycleOwner.lifecycleScope.apply {
|
|
||||||
launch {
|
|
||||||
driverViewModel.driverList.collectLatest {
|
|
||||||
(binding.listDrivers.adapter as DriverAdapter).submitList(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
launch {
|
|
||||||
driverViewModel.newDriverInstalled.collect {
|
|
||||||
if (_binding != null && it) {
|
|
||||||
(binding.listDrivers.adapter as DriverAdapter).apply {
|
|
||||||
notifyItemChanged(driverViewModel.previouslySelectedDriver)
|
|
||||||
notifyItemChanged(driverViewModel.selectedDriver)
|
|
||||||
driverViewModel.setNewDriverInstalled(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setInsets()
|
setInsets()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,12 +158,20 @@ class DriverManagerFragment : Fragment() {
|
||||||
|
|
||||||
val driverData = GpuDriverHelper.getMetadataFromZip(driverFile)
|
val driverData = GpuDriverHelper.getMetadataFromZip(driverFile)
|
||||||
val driverInList =
|
val driverInList =
|
||||||
driverViewModel.driverList.value.firstOrNull { it.second == driverData }
|
driverViewModel.driverData.firstOrNull { it.second == driverData }
|
||||||
if (driverInList != null) {
|
if (driverInList != null) {
|
||||||
return@newInstance getString(R.string.driver_already_installed)
|
return@newInstance getString(R.string.driver_already_installed)
|
||||||
} else {
|
} else {
|
||||||
driverViewModel.addDriver(Pair(driverPath, driverData))
|
driverViewModel.onDriverAdded(Pair(driverPath, driverData))
|
||||||
driverViewModel.setNewDriverInstalled(true)
|
withContext(Dispatchers.Main) {
|
||||||
|
if (_binding != null) {
|
||||||
|
val adapter = binding.listDrivers.adapter as DriverAdapter
|
||||||
|
adapter.addItem(driverData.toDriver())
|
||||||
|
adapter.selectItem(adapter.currentList.indices.last)
|
||||||
|
binding.listDrivers
|
||||||
|
.smoothScrollToPosition(adapter.currentList.indices.last)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return@newInstance Any()
|
return@newInstance Any()
|
||||||
}.show(childFragmentManager, IndeterminateProgressDialogFragment.TAG)
|
}.show(childFragmentManager, IndeterminateProgressDialogFragment.TAG)
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
// SPDX-FileCopyrightText: 2024 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
package org.yuzu.yuzu_emu.model
|
||||||
|
|
||||||
|
import org.yuzu.yuzu_emu.utils.GpuDriverMetadata
|
||||||
|
|
||||||
|
data class Driver(
|
||||||
|
override var selected: Boolean,
|
||||||
|
val title: String,
|
||||||
|
val version: String = "",
|
||||||
|
val description: String = ""
|
||||||
|
) : SelectableItem {
|
||||||
|
override fun onSelectionStateChanged(selected: Boolean) {
|
||||||
|
this.selected = selected
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun GpuDriverMetadata.toDriver(selected: Boolean = false): Driver =
|
||||||
|
Driver(
|
||||||
|
selected,
|
||||||
|
this.name ?: "",
|
||||||
|
this.version ?: "",
|
||||||
|
this.description ?: ""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,11 +17,10 @@ import org.yuzu.yuzu_emu.R
|
||||||
import org.yuzu.yuzu_emu.YuzuApplication
|
import org.yuzu.yuzu_emu.YuzuApplication
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.StringSetting
|
import org.yuzu.yuzu_emu.features.settings.model.StringSetting
|
||||||
import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile
|
import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile
|
||||||
import org.yuzu.yuzu_emu.utils.FileUtil
|
import org.yuzu.yuzu_emu.model.Driver.Companion.toDriver
|
||||||
import org.yuzu.yuzu_emu.utils.GpuDriverHelper
|
import org.yuzu.yuzu_emu.utils.GpuDriverHelper
|
||||||
import org.yuzu.yuzu_emu.utils.GpuDriverMetadata
|
import org.yuzu.yuzu_emu.utils.GpuDriverMetadata
|
||||||
import org.yuzu.yuzu_emu.utils.NativeConfig
|
import org.yuzu.yuzu_emu.utils.NativeConfig
|
||||||
import java.io.BufferedOutputStream
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class DriverViewModel : ViewModel() {
|
class DriverViewModel : ViewModel() {
|
||||||
|
@ -38,97 +37,74 @@ class DriverViewModel : ViewModel() {
|
||||||
!loading && ready && !deleting
|
!loading && ready && !deleting
|
||||||
}.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), initialValue = false)
|
}.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), initialValue = false)
|
||||||
|
|
||||||
private val _driverList = MutableStateFlow(GpuDriverHelper.getDrivers())
|
var driverData = GpuDriverHelper.getDrivers()
|
||||||
val driverList: StateFlow<MutableList<Pair<String, GpuDriverMetadata>>> get() = _driverList
|
|
||||||
|
|
||||||
var previouslySelectedDriver = 0
|
private val _driverList = MutableStateFlow(emptyList<Driver>())
|
||||||
var selectedDriver = -1
|
val driverList: StateFlow<List<Driver>> get() = _driverList
|
||||||
|
|
||||||
// Used for showing which driver is currently installed within the driver manager card
|
// Used for showing which driver is currently installed within the driver manager card
|
||||||
private val _selectedDriverTitle = MutableStateFlow("")
|
private val _selectedDriverTitle = MutableStateFlow("")
|
||||||
val selectedDriverTitle: StateFlow<String> get() = _selectedDriverTitle
|
val selectedDriverTitle: StateFlow<String> get() = _selectedDriverTitle
|
||||||
|
|
||||||
private val _newDriverInstalled = MutableStateFlow(false)
|
private val driversToDelete = mutableListOf<String>()
|
||||||
val newDriverInstalled: StateFlow<Boolean> get() = _newDriverInstalled
|
|
||||||
|
|
||||||
val driversToDelete = mutableListOf<String>()
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val currentDriverMetadata = GpuDriverHelper.installedCustomDriverData
|
updateDriverList()
|
||||||
findSelectedDriver(currentDriverMetadata)
|
|
||||||
|
|
||||||
// If a user had installed a driver before the manager was implemented, this zips
|
|
||||||
// the installed driver to UserData/gpu_drivers/CustomDriver.zip so that it can
|
|
||||||
// be indexed and exported as expected.
|
|
||||||
if (selectedDriver == -1) {
|
|
||||||
val driverToSave =
|
|
||||||
File(GpuDriverHelper.driverStoragePath, "CustomDriver.zip")
|
|
||||||
driverToSave.createNewFile()
|
|
||||||
FileUtil.zipFromInternalStorage(
|
|
||||||
File(GpuDriverHelper.driverInstallationPath!!),
|
|
||||||
GpuDriverHelper.driverInstallationPath!!,
|
|
||||||
BufferedOutputStream(driverToSave.outputStream())
|
|
||||||
)
|
|
||||||
_driverList.value.add(Pair(driverToSave.path, currentDriverMetadata))
|
|
||||||
setSelectedDriverIndex(_driverList.value.size - 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// If a user had installed a driver before the config was reworked to be multiplatform,
|
|
||||||
// we have save the path of the previously selected driver to the new setting.
|
|
||||||
if (StringSetting.DRIVER_PATH.getString(true).isEmpty() && selectedDriver > 0 &&
|
|
||||||
StringSetting.DRIVER_PATH.global
|
|
||||||
) {
|
|
||||||
StringSetting.DRIVER_PATH.setString(_driverList.value[selectedDriver].first)
|
|
||||||
NativeConfig.saveGlobalConfig()
|
|
||||||
} else {
|
|
||||||
findSelectedDriver(GpuDriverHelper.customDriverSettingData)
|
|
||||||
}
|
|
||||||
updateDriverNameForGame(null)
|
updateDriverNameForGame(null)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setSelectedDriverIndex(value: Int) {
|
fun reloadDriverData() {
|
||||||
if (selectedDriver != -1) {
|
_areDriversLoading.value = true
|
||||||
previouslySelectedDriver = selectedDriver
|
driverData = GpuDriverHelper.getDrivers()
|
||||||
|
updateDriverList()
|
||||||
|
_areDriversLoading.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateDriverList() {
|
||||||
|
val selectedDriver = GpuDriverHelper.customDriverSettingData
|
||||||
|
val newDriverList = mutableListOf(
|
||||||
|
Driver(
|
||||||
|
selectedDriver == GpuDriverMetadata(),
|
||||||
|
YuzuApplication.appContext.getString(R.string.system_gpu_driver)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
driverData.forEach {
|
||||||
|
newDriverList.add(it.second.toDriver(it.second == selectedDriver))
|
||||||
}
|
}
|
||||||
selectedDriver = value
|
_driverList.value = newDriverList
|
||||||
}
|
|
||||||
|
|
||||||
fun setNewDriverInstalled(value: Boolean) {
|
|
||||||
_newDriverInstalled.value = value
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addDriver(driverData: Pair<String, GpuDriverMetadata>) {
|
|
||||||
val driverIndex = _driverList.value.indexOfFirst { it == driverData }
|
|
||||||
if (driverIndex == -1) {
|
|
||||||
_driverList.value.add(driverData)
|
|
||||||
setSelectedDriverIndex(_driverList.value.size - 1)
|
|
||||||
_selectedDriverTitle.value = driverData.second.name
|
|
||||||
?: YuzuApplication.appContext.getString(R.string.system_gpu_driver)
|
|
||||||
} else {
|
|
||||||
setSelectedDriverIndex(driverIndex)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun removeDriver(driverData: Pair<String, GpuDriverMetadata>) {
|
|
||||||
_driverList.value.remove(driverData)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onOpenDriverManager(game: Game?) {
|
fun onOpenDriverManager(game: Game?) {
|
||||||
if (game != null) {
|
if (game != null) {
|
||||||
SettingsFile.loadCustomConfig(game)
|
SettingsFile.loadCustomConfig(game)
|
||||||
}
|
}
|
||||||
|
updateDriverList()
|
||||||
|
}
|
||||||
|
|
||||||
val driverPath = StringSetting.DRIVER_PATH.getString()
|
fun onDriverSelected(position: Int) {
|
||||||
if (driverPath.isEmpty()) {
|
if (position == 0) {
|
||||||
setSelectedDriverIndex(0)
|
StringSetting.DRIVER_PATH.setString("")
|
||||||
} else {
|
} else {
|
||||||
findSelectedDriver(GpuDriverHelper.getMetadataFromZip(File(driverPath)))
|
StringSetting.DRIVER_PATH.setString(driverData[position - 1].first)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun onDriverRemoved(removedPosition: Int, selectedPosition: Int) {
|
||||||
|
driversToDelete.add(driverData[removedPosition - 1].first)
|
||||||
|
driverData.removeAt(removedPosition - 1)
|
||||||
|
onDriverSelected(selectedPosition)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onDriverAdded(driver: Pair<String, GpuDriverMetadata>) {
|
||||||
|
if (driversToDelete.contains(driver.first)) {
|
||||||
|
driversToDelete.remove(driver.first)
|
||||||
|
}
|
||||||
|
driverData.add(driver)
|
||||||
|
onDriverSelected(driverData.size)
|
||||||
|
}
|
||||||
|
|
||||||
fun onCloseDriverManager(game: Game?) {
|
fun onCloseDriverManager(game: Game?) {
|
||||||
_isDeletingDrivers.value = true
|
_isDeletingDrivers.value = true
|
||||||
StringSetting.DRIVER_PATH.setString(driverList.value[selectedDriver].first)
|
|
||||||
updateDriverNameForGame(game)
|
updateDriverNameForGame(game)
|
||||||
if (game == null) {
|
if (game == null) {
|
||||||
NativeConfig.saveGlobalConfig()
|
NativeConfig.saveGlobalConfig()
|
||||||
|
@ -181,20 +157,6 @@ class DriverViewModel : ViewModel() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findSelectedDriver(currentDriverMetadata: GpuDriverMetadata) {
|
|
||||||
if (driverList.value.size == 1) {
|
|
||||||
setSelectedDriverIndex(0)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
driverList.value.forEachIndexed { i: Int, driver: Pair<String, GpuDriverMetadata> ->
|
|
||||||
if (driver.second == currentDriverMetadata) {
|
|
||||||
setSelectedDriverIndex(i)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun updateDriverNameForGame(game: Game?) {
|
fun updateDriverNameForGame(game: Game?) {
|
||||||
if (!GpuDriverHelper.supportsCustomDriverLoading()) {
|
if (!GpuDriverHelper.supportsCustomDriverLoading()) {
|
||||||
return
|
return
|
||||||
|
@ -217,7 +179,6 @@ class DriverViewModel : ViewModel() {
|
||||||
|
|
||||||
private fun setDriverReady() {
|
private fun setDriverReady() {
|
||||||
_isDriverReady.value = true
|
_isDriverReady.value = true
|
||||||
_selectedDriverTitle.value = GpuDriverHelper.customDriverSettingData.name
|
updateName()
|
||||||
?: YuzuApplication.appContext.getString(R.string.system_gpu_driver)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,9 +62,6 @@ object GpuDriverHelper {
|
||||||
?.sortedByDescending { it: Pair<String, GpuDriverMetadata> -> it.second.name }
|
?.sortedByDescending { it: Pair<String, GpuDriverMetadata> -> it.second.name }
|
||||||
?.distinct()
|
?.distinct()
|
||||||
?.toMutableList() ?: mutableListOf()
|
?.toMutableList() ?: mutableListOf()
|
||||||
|
|
||||||
// TODO: Get system driver information
|
|
||||||
drivers.add(0, Pair("", GpuDriverMetadata()))
|
|
||||||
return drivers
|
return drivers
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue