android: Add search for settings
This commit is contained in:
parent
d786d19880
commit
fd5c7b21dd
|
@ -12,6 +12,7 @@ import android.view.LayoutInflater
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.navigation.findNavController
|
import androidx.navigation.findNavController
|
||||||
import androidx.recyclerview.widget.AsyncDifferConfig
|
import androidx.recyclerview.widget.AsyncDifferConfig
|
||||||
|
@ -37,7 +38,7 @@ import org.yuzu.yuzu_emu.features.settings.ui.viewholder.*
|
||||||
import org.yuzu.yuzu_emu.model.SettingsViewModel
|
import org.yuzu.yuzu_emu.model.SettingsViewModel
|
||||||
|
|
||||||
class SettingsAdapter(
|
class SettingsAdapter(
|
||||||
private val fragment: SettingsFragment,
|
private val fragment: Fragment,
|
||||||
private val context: Context
|
private val context: Context
|
||||||
) : ListAdapter<SettingsItem, SettingViewHolder>(AsyncDifferConfig.Builder(DiffCallback()).build()),
|
) : ListAdapter<SettingsItem, SettingViewHolder>(AsyncDifferConfig.Builder(DiffCallback()).build()),
|
||||||
DialogInterface.OnClickListener {
|
DialogInterface.OnClickListener {
|
||||||
|
|
|
@ -13,12 +13,14 @@ 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.navigation.findNavController
|
||||||
import androidx.navigation.fragment.navArgs
|
import androidx.navigation.fragment.navArgs
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import com.google.android.material.divider.MaterialDividerItemDecoration
|
import com.google.android.material.divider.MaterialDividerItemDecoration
|
||||||
import com.google.android.material.transition.MaterialSharedAxis
|
import com.google.android.material.transition.MaterialSharedAxis
|
||||||
import org.yuzu.yuzu_emu.R
|
import org.yuzu.yuzu_emu.R
|
||||||
import org.yuzu.yuzu_emu.databinding.FragmentSettingsBinding
|
import org.yuzu.yuzu_emu.databinding.FragmentSettingsBinding
|
||||||
|
import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile
|
||||||
import org.yuzu.yuzu_emu.model.SettingsViewModel
|
import org.yuzu.yuzu_emu.model.SettingsViewModel
|
||||||
|
|
||||||
class SettingsFragment : Fragment() {
|
class SettingsFragment : Fragment() {
|
||||||
|
@ -84,11 +86,43 @@ class SettingsFragment : Fragment() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
settingsViewModel.isUsingSearch.observe(viewLifecycleOwner) {
|
||||||
|
if (it) {
|
||||||
|
reenterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true)
|
||||||
|
exitTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
|
||||||
|
} else {
|
||||||
|
reenterTransition = MaterialSharedAxis(MaterialSharedAxis.X, false)
|
||||||
|
exitTransition = MaterialSharedAxis(MaterialSharedAxis.X, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.menuTag == SettingsFile.FILE_NAME_CONFIG) {
|
||||||
|
binding.toolbarSettings.inflateMenu(R.menu.menu_settings)
|
||||||
|
binding.toolbarSettings.setOnMenuItemClickListener {
|
||||||
|
when (it.itemId) {
|
||||||
|
R.id.action_search -> {
|
||||||
|
reenterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true)
|
||||||
|
exitTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
|
||||||
|
view.findNavController()
|
||||||
|
.navigate(R.id.action_settingsFragment_to_settingsSearchFragment)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
presenter.onViewCreated()
|
presenter.onViewCreated()
|
||||||
|
|
||||||
setInsets()
|
setInsets()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
settingsViewModel.setIsUsingSearch(false)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onDetach() {
|
override fun onDetach() {
|
||||||
super.onDetach()
|
super.onDetach()
|
||||||
settingsAdapter?.closeDialog()
|
settingsAdapter?.closeDialog()
|
||||||
|
|
|
@ -0,0 +1,189 @@
|
||||||
|
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
package org.yuzu.yuzu_emu.fragments
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.view.inputmethod.InputMethodManager
|
||||||
|
import androidx.core.view.ViewCompat
|
||||||
|
import androidx.core.view.WindowInsetsCompat
|
||||||
|
import androidx.core.view.updatePadding
|
||||||
|
import androidx.core.widget.doOnTextChanged
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.fragment.app.activityViewModels
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import com.google.android.material.divider.MaterialDividerItemDecoration
|
||||||
|
import com.google.android.material.transition.MaterialSharedAxis
|
||||||
|
import info.debatty.java.stringsimilarity.Cosine
|
||||||
|
import org.yuzu.yuzu_emu.R
|
||||||
|
import org.yuzu.yuzu_emu.databinding.FragmentSettingsSearchBinding
|
||||||
|
import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem
|
||||||
|
import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter
|
||||||
|
import org.yuzu.yuzu_emu.model.SettingsViewModel
|
||||||
|
import org.yuzu.yuzu_emu.utils.NativeConfig
|
||||||
|
|
||||||
|
class SettingsSearchFragment : Fragment() {
|
||||||
|
private var _binding: FragmentSettingsSearchBinding? = null
|
||||||
|
private val binding get() = _binding!!
|
||||||
|
|
||||||
|
private var settingsAdapter: SettingsAdapter? = null
|
||||||
|
|
||||||
|
private val settingsViewModel: SettingsViewModel by activityViewModels()
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
enterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
|
||||||
|
returnTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View {
|
||||||
|
_binding = FragmentSettingsSearchBinding.inflate(layoutInflater)
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
settingsViewModel.setIsUsingSearch(true)
|
||||||
|
|
||||||
|
if (savedInstanceState != null) {
|
||||||
|
binding.searchText.setText(savedInstanceState.getString(SEARCH_TEXT))
|
||||||
|
}
|
||||||
|
|
||||||
|
settingsAdapter = SettingsAdapter(this, requireContext())
|
||||||
|
|
||||||
|
val dividerDecoration = MaterialDividerItemDecoration(
|
||||||
|
requireContext(),
|
||||||
|
LinearLayoutManager.VERTICAL
|
||||||
|
)
|
||||||
|
dividerDecoration.isLastItemDecorated = false
|
||||||
|
binding.settingsList.apply {
|
||||||
|
adapter = settingsAdapter
|
||||||
|
layoutManager = LinearLayoutManager(requireContext())
|
||||||
|
addItemDecoration(dividerDecoration)
|
||||||
|
}
|
||||||
|
|
||||||
|
focusSearch()
|
||||||
|
|
||||||
|
binding.backButton.setOnClickListener { settingsViewModel.setShouldNavigateBack(true) }
|
||||||
|
binding.searchBackground.setOnClickListener { focusSearch() }
|
||||||
|
binding.clearButton.setOnClickListener { binding.searchText.setText("") }
|
||||||
|
binding.searchText.doOnTextChanged { _, _, _, _ ->
|
||||||
|
search()
|
||||||
|
binding.settingsList.smoothScrollToPosition(0)
|
||||||
|
}
|
||||||
|
settingsViewModel.shouldReloadSettingsList.observe(viewLifecycleOwner) {
|
||||||
|
if (it) {
|
||||||
|
settingsViewModel.setShouldReloadSettingsList(false)
|
||||||
|
search()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
search()
|
||||||
|
|
||||||
|
setInsets()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDetach() {
|
||||||
|
super.onDetach()
|
||||||
|
settingsAdapter?.closeDialog()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSaveInstanceState(outState: Bundle) {
|
||||||
|
super.onSaveInstanceState(outState)
|
||||||
|
outState.putString(SEARCH_TEXT, binding.searchText.text.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun search() {
|
||||||
|
val searchTerm = binding.searchText.text.toString().lowercase()
|
||||||
|
binding.clearButton.visibility =
|
||||||
|
if (searchTerm.isEmpty()) View.INVISIBLE else View.VISIBLE
|
||||||
|
if (searchTerm.isEmpty()) {
|
||||||
|
binding.noResultsView.visibility = View.VISIBLE
|
||||||
|
settingsAdapter?.submitList(emptyList())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val baseList = SettingsItem.settingsItems
|
||||||
|
val similarityAlgorithm = if (searchTerm.length > 2) Cosine() else Cosine(1)
|
||||||
|
val sortedList: List<SettingsItem> = baseList.mapNotNull { item ->
|
||||||
|
val title = getString(item.value.nameId).lowercase()
|
||||||
|
val similarity = similarityAlgorithm.similarity(searchTerm, title)
|
||||||
|
if (similarity > 0.08) {
|
||||||
|
Pair(similarity, item)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}.sortedByDescending { it.first }.mapNotNull {
|
||||||
|
val item = it.second.value
|
||||||
|
val pairedSettingKey = item.setting.pairedSettingKey
|
||||||
|
val optionalSetting: SettingsItem? = if (pairedSettingKey.isNotEmpty()) {
|
||||||
|
val pairedSettingValue = NativeConfig.getBoolean(pairedSettingKey, false)
|
||||||
|
if (pairedSettingValue) it.second.value else null
|
||||||
|
} else {
|
||||||
|
it.second.value
|
||||||
|
}
|
||||||
|
optionalSetting
|
||||||
|
}
|
||||||
|
settingsAdapter?.submitList(sortedList)
|
||||||
|
binding.noResultsView.visibility =
|
||||||
|
if (sortedList.isEmpty()) View.VISIBLE else View.INVISIBLE
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun focusSearch() {
|
||||||
|
binding.searchText.requestFocus()
|
||||||
|
val imm = requireActivity()
|
||||||
|
.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager?
|
||||||
|
imm?.showSoftInput(binding.searchText, InputMethodManager.SHOW_IMPLICIT)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setInsets() =
|
||||||
|
ViewCompat.setOnApplyWindowInsetsListener(
|
||||||
|
binding.root
|
||||||
|
) { _: View, windowInsets: WindowInsetsCompat ->
|
||||||
|
val extraListSpacing = resources.getDimensionPixelSize(R.dimen.spacing_med)
|
||||||
|
val sideMargin = resources.getDimensionPixelSize(R.dimen.spacing_medlarge)
|
||||||
|
val topMargin = resources.getDimensionPixelSize(R.dimen.spacing_chip)
|
||||||
|
|
||||||
|
val barInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||||
|
val cutoutInsets = windowInsets.getInsets(WindowInsetsCompat.Type.displayCutout())
|
||||||
|
|
||||||
|
val leftInsets = barInsets.left + cutoutInsets.left
|
||||||
|
val rightInsets = barInsets.right + cutoutInsets.right
|
||||||
|
|
||||||
|
binding.settingsList.updatePadding(bottom = barInsets.bottom + extraListSpacing)
|
||||||
|
binding.frameSearch.updatePadding(
|
||||||
|
left = leftInsets + sideMargin,
|
||||||
|
top = barInsets.top + topMargin,
|
||||||
|
right = rightInsets + sideMargin
|
||||||
|
)
|
||||||
|
binding.noResultsView.updatePadding(
|
||||||
|
left = leftInsets,
|
||||||
|
right = rightInsets,
|
||||||
|
bottom = barInsets.bottom
|
||||||
|
)
|
||||||
|
|
||||||
|
val mlpSettingsList = binding.settingsList.layoutParams as ViewGroup.MarginLayoutParams
|
||||||
|
mlpSettingsList.leftMargin = leftInsets + sideMargin
|
||||||
|
mlpSettingsList.rightMargin = rightInsets + sideMargin
|
||||||
|
binding.settingsList.layoutParams = mlpSettingsList
|
||||||
|
|
||||||
|
val mlpDivider = binding.divider.layoutParams as ViewGroup.MarginLayoutParams
|
||||||
|
mlpDivider.leftMargin = leftInsets + sideMargin
|
||||||
|
mlpDivider.rightMargin = rightInsets + sideMargin
|
||||||
|
binding.divider.layoutParams = mlpDivider
|
||||||
|
|
||||||
|
windowInsets
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val SEARCH_TEXT = "SearchText"
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,6 +27,9 @@ class SettingsViewModel : ViewModel() {
|
||||||
private val _shouldReloadSettingsList = MutableLiveData(false)
|
private val _shouldReloadSettingsList = MutableLiveData(false)
|
||||||
val shouldReloadSettingsList: LiveData<Boolean> get() = _shouldReloadSettingsList
|
val shouldReloadSettingsList: LiveData<Boolean> get() = _shouldReloadSettingsList
|
||||||
|
|
||||||
|
private val _isUsingSearch = MutableLiveData(false)
|
||||||
|
val isUsingSearch: LiveData<Boolean> get() = _isUsingSearch
|
||||||
|
|
||||||
fun setToolbarTitle(value: String) {
|
fun setToolbarTitle(value: String) {
|
||||||
_toolbarTitle.value = value
|
_toolbarTitle.value = value
|
||||||
}
|
}
|
||||||
|
@ -47,6 +50,10 @@ class SettingsViewModel : ViewModel() {
|
||||||
_shouldReloadSettingsList.value = value
|
_shouldReloadSettingsList.value = value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setIsUsingSearch(value: Boolean) {
|
||||||
|
_isUsingSearch.value = value
|
||||||
|
}
|
||||||
|
|
||||||
fun clear() {
|
fun clear() {
|
||||||
game = null
|
game = null
|
||||||
shouldSave = false
|
shouldSave = false
|
||||||
|
|
|
@ -0,0 +1,120 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/relativeLayout"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/divider">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/no_results_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/icon_no_results"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="80dp"
|
||||||
|
android:src="@drawable/ic_search" />
|
||||||
|
|
||||||
|
<com.google.android.material.textview.MaterialTextView
|
||||||
|
android:id="@+id/notice_text"
|
||||||
|
style="@style/TextAppearance.Material3.TitleLarge"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:paddingTop="8dp"
|
||||||
|
android:text="@string/search_settings"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/settings_list"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:clipToPadding="false" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/frame_search"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<com.google.android.material.card.MaterialCardView
|
||||||
|
android:id="@+id/search_background"
|
||||||
|
style="?attr/materialCardViewFilledStyle"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="56dp"
|
||||||
|
app:cardCornerRadius="28dp">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/search_container"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginEnd="56dp"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/back_button"
|
||||||
|
style="?attr/materialIconButtonFilledTonalStyle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
app:backgroundTint="@android:color/transparent"
|
||||||
|
app:icon="@drawable/ic_back" />
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/search_text"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
android:hint="@string/search_settings"
|
||||||
|
android:imeOptions="flagNoFullscreen"
|
||||||
|
android:inputType="text"
|
||||||
|
android:maxLines="1" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/clear_button"
|
||||||
|
style="?attr/materialIconButtonFilledTonalStyle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical|end"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:visibility="invisible"
|
||||||
|
app:backgroundTint="@android:color/transparent"
|
||||||
|
app:icon="@drawable/ic_clear"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.divider.MaterialDivider
|
||||||
|
android:id="@+id/divider"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/frame_search" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -0,0 +1,11 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_search"
|
||||||
|
android:icon="@drawable/ic_search"
|
||||||
|
android:title="@string/home_search"
|
||||||
|
app:showAsAction="always" />
|
||||||
|
|
||||||
|
</menu>
|
|
@ -15,10 +15,18 @@
|
||||||
android:name="game"
|
android:name="game"
|
||||||
app:argType="org.yuzu.yuzu_emu.model.Game"
|
app:argType="org.yuzu.yuzu_emu.model.Game"
|
||||||
app:nullable="true" />
|
app:nullable="true" />
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_settingsFragment_to_settingsSearchFragment"
|
||||||
|
app:destination="@id/settingsSearchFragment" />
|
||||||
</fragment>
|
</fragment>
|
||||||
|
|
||||||
<action
|
<action
|
||||||
android:id="@+id/action_global_settingsFragment"
|
android:id="@+id/action_global_settingsFragment"
|
||||||
app:destination="@id/settingsFragment" />
|
app:destination="@id/settingsFragment" />
|
||||||
|
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/settingsSearchFragment"
|
||||||
|
android:name="org.yuzu.yuzu_emu.fragments.SettingsSearchFragment"
|
||||||
|
android:label="SettingsSearchFragment" />
|
||||||
|
|
||||||
</navigation>
|
</navigation>
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
<string name="add_games_warning_description">Games won\'t be displayed in the Games list if a folder isn\'t selected.</string>
|
<string name="add_games_warning_description">Games won\'t be displayed in the Games list if a folder isn\'t selected.</string>
|
||||||
<string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string>
|
<string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string>
|
||||||
<string name="home_search_games">Search games</string>
|
<string name="home_search_games">Search games</string>
|
||||||
|
<string name="search_settings">Search settings</string>
|
||||||
<string name="games_dir_selected">Games directory selected</string>
|
<string name="games_dir_selected">Games directory selected</string>
|
||||||
<string name="install_prod_keys">Install prod.keys</string>
|
<string name="install_prod_keys">Install prod.keys</string>
|
||||||
<string name="install_prod_keys_description">Required to decrypt retail games</string>
|
<string name="install_prod_keys_description">Required to decrypt retail games</string>
|
||||||
|
|
Reference in New Issue