Merge pull request #13050 from t895/marquee-helper

android: Use extension functions for view visibility and text marquee
This commit is contained in:
liamwhite 2024-02-17 22:48:36 -05:00 committed by GitHub
commit 5d3c7433b8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
31 changed files with 166 additions and 265 deletions

View File

@ -3,15 +3,15 @@
package org.yuzu.yuzu_emu.adapters package org.yuzu.yuzu_emu.adapters
import android.text.TextUtils
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import org.yuzu.yuzu_emu.R import org.yuzu.yuzu_emu.R
import org.yuzu.yuzu_emu.databinding.CardDriverOptionBinding import org.yuzu.yuzu_emu.databinding.CardDriverOptionBinding
import org.yuzu.yuzu_emu.features.settings.model.StringSetting import org.yuzu.yuzu_emu.features.settings.model.StringSetting
import org.yuzu.yuzu_emu.model.Driver import org.yuzu.yuzu_emu.model.Driver
import org.yuzu.yuzu_emu.model.DriverViewModel import org.yuzu.yuzu_emu.model.DriverViewModel
import org.yuzu.yuzu_emu.utils.ViewUtils.marquee
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
import org.yuzu.yuzu_emu.viewholder.AbstractViewHolder import org.yuzu.yuzu_emu.viewholder.AbstractViewHolder
class DriverAdapter(private val driverViewModel: DriverViewModel) : class DriverAdapter(private val driverViewModel: DriverViewModel) :
@ -44,25 +44,15 @@ class DriverAdapter(private val driverViewModel: DriverViewModel) :
} }
// Delay marquee by 3s // Delay marquee by 3s
title.postDelayed( title.marquee()
{ version.marquee()
title.isSelected = true description.marquee()
title.ellipsize = TextUtils.TruncateAt.MARQUEE
version.isSelected = true
version.ellipsize = TextUtils.TruncateAt.MARQUEE
description.isSelected = true
description.ellipsize = TextUtils.TruncateAt.MARQUEE
},
3000
)
title.text = model.title title.text = model.title
version.text = model.version version.text = model.version
description.text = model.description description.text = model.description
if (model.title != binding.root.context.getString(R.string.system_gpu_driver)) { buttonDelete.setVisible(
buttonDelete.visibility = View.VISIBLE model.title != binding.root.context.getString(R.string.system_gpu_driver)
} else { )
buttonDelete.visibility = View.GONE
}
} }
} }
} }

View File

@ -4,7 +4,6 @@
package org.yuzu.yuzu_emu.adapters package org.yuzu.yuzu_emu.adapters
import android.net.Uri import android.net.Uri
import android.text.TextUtils
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
@ -12,6 +11,7 @@ import org.yuzu.yuzu_emu.databinding.CardFolderBinding
import org.yuzu.yuzu_emu.fragments.GameFolderPropertiesDialogFragment import org.yuzu.yuzu_emu.fragments.GameFolderPropertiesDialogFragment
import org.yuzu.yuzu_emu.model.GameDir import org.yuzu.yuzu_emu.model.GameDir
import org.yuzu.yuzu_emu.model.GamesViewModel import org.yuzu.yuzu_emu.model.GamesViewModel
import org.yuzu.yuzu_emu.utils.ViewUtils.marquee
import org.yuzu.yuzu_emu.viewholder.AbstractViewHolder import org.yuzu.yuzu_emu.viewholder.AbstractViewHolder
class FolderAdapter(val activity: FragmentActivity, val gamesViewModel: GamesViewModel) : class FolderAdapter(val activity: FragmentActivity, val gamesViewModel: GamesViewModel) :
@ -29,13 +29,7 @@ class FolderAdapter(val activity: FragmentActivity, val gamesViewModel: GamesVie
override fun bind(model: GameDir) { override fun bind(model: GameDir) {
binding.apply { binding.apply {
path.text = Uri.parse(model.uriString).path path.text = Uri.parse(model.uriString).path
path.postDelayed( path.marquee()
{
path.isSelected = true
path.ellipsize = TextUtils.TruncateAt.MARQUEE
},
3000
)
buttonEdit.setOnClickListener { buttonEdit.setOnClickListener {
GameFolderPropertiesDialogFragment.newInstance(model) GameFolderPropertiesDialogFragment.newInstance(model)

View File

@ -4,7 +4,6 @@
package org.yuzu.yuzu_emu.adapters package org.yuzu.yuzu_emu.adapters
import android.net.Uri import android.net.Uri
import android.text.TextUtils
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
@ -27,6 +26,7 @@ import org.yuzu.yuzu_emu.databinding.CardGameBinding
import org.yuzu.yuzu_emu.model.Game import org.yuzu.yuzu_emu.model.Game
import org.yuzu.yuzu_emu.model.GamesViewModel import org.yuzu.yuzu_emu.model.GamesViewModel
import org.yuzu.yuzu_emu.utils.GameIconUtils import org.yuzu.yuzu_emu.utils.GameIconUtils
import org.yuzu.yuzu_emu.utils.ViewUtils.marquee
import org.yuzu.yuzu_emu.viewholder.AbstractViewHolder import org.yuzu.yuzu_emu.viewholder.AbstractViewHolder
class GameAdapter(private val activity: AppCompatActivity) : class GameAdapter(private val activity: AppCompatActivity) :
@ -44,14 +44,7 @@ class GameAdapter(private val activity: AppCompatActivity) :
binding.textGameTitle.text = model.title.replace("[\\t\\n\\r]+".toRegex(), " ") binding.textGameTitle.text = model.title.replace("[\\t\\n\\r]+".toRegex(), " ")
binding.textGameTitle.postDelayed( binding.textGameTitle.marquee()
{
binding.textGameTitle.ellipsize = TextUtils.TruncateAt.MARQUEE
binding.textGameTitle.isSelected = true
},
3000
)
binding.cardGame.setOnClickListener { onClick(model) } binding.cardGame.setOnClickListener { onClick(model) }
binding.cardGame.setOnLongClickListener { onLongClick(model) } binding.cardGame.setOnLongClickListener { onLongClick(model) }
} }

View File

@ -3,9 +3,7 @@
package org.yuzu.yuzu_emu.adapters package org.yuzu.yuzu_emu.adapters
import android.text.TextUtils
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.content.res.ResourcesCompat import androidx.core.content.res.ResourcesCompat
import androidx.lifecycle.Lifecycle import androidx.lifecycle.Lifecycle
@ -18,6 +16,8 @@ import org.yuzu.yuzu_emu.databinding.CardSimpleOutlinedBinding
import org.yuzu.yuzu_emu.model.GameProperty import org.yuzu.yuzu_emu.model.GameProperty
import org.yuzu.yuzu_emu.model.InstallableProperty import org.yuzu.yuzu_emu.model.InstallableProperty
import org.yuzu.yuzu_emu.model.SubmenuProperty import org.yuzu.yuzu_emu.model.SubmenuProperty
import org.yuzu.yuzu_emu.utils.ViewUtils.marquee
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
import org.yuzu.yuzu_emu.viewholder.AbstractViewHolder import org.yuzu.yuzu_emu.viewholder.AbstractViewHolder
class GamePropertiesAdapter( class GamePropertiesAdapter(
@ -76,23 +76,19 @@ class GamePropertiesAdapter(
) )
) )
binding.details.postDelayed({ binding.details.marquee()
binding.details.isSelected = true
binding.details.ellipsize = TextUtils.TruncateAt.MARQUEE
}, 3000)
if (submenuProperty.details != null) { if (submenuProperty.details != null) {
binding.details.visibility = View.VISIBLE binding.details.setVisible(true)
binding.details.text = submenuProperty.details.invoke() binding.details.text = submenuProperty.details.invoke()
} else if (submenuProperty.detailsFlow != null) { } else if (submenuProperty.detailsFlow != null) {
binding.details.visibility = View.VISIBLE binding.details.setVisible(true)
viewLifecycle.lifecycleScope.launch { viewLifecycle.lifecycleScope.launch {
viewLifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) { viewLifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
submenuProperty.detailsFlow.collect { binding.details.text = it } submenuProperty.detailsFlow.collect { binding.details.text = it }
} }
} }
} else { } else {
binding.details.visibility = View.GONE binding.details.setVisible(false)
} }
} }
} }
@ -112,14 +108,10 @@ class GamePropertiesAdapter(
) )
) )
if (installableProperty.install != null) { binding.buttonInstall.setVisible(installableProperty.install != null)
binding.buttonInstall.visibility = View.VISIBLE binding.buttonInstall.setOnClickListener { installableProperty.install?.invoke() }
binding.buttonInstall.setOnClickListener { installableProperty.install.invoke() } binding.buttonExport.setVisible(installableProperty.export != null)
} binding.buttonExport.setOnClickListener { installableProperty.export?.invoke() }
if (installableProperty.export != null) {
binding.buttonExport.visibility = View.VISIBLE
binding.buttonExport.setOnClickListener { installableProperty.export.invoke() }
}
} }
} }

View File

@ -3,9 +3,7 @@
package org.yuzu.yuzu_emu.adapters package org.yuzu.yuzu_emu.adapters
import android.text.TextUtils
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
@ -19,6 +17,8 @@ import org.yuzu.yuzu_emu.R
import org.yuzu.yuzu_emu.databinding.CardHomeOptionBinding import org.yuzu.yuzu_emu.databinding.CardHomeOptionBinding
import org.yuzu.yuzu_emu.fragments.MessageDialogFragment import org.yuzu.yuzu_emu.fragments.MessageDialogFragment
import org.yuzu.yuzu_emu.model.HomeSetting import org.yuzu.yuzu_emu.model.HomeSetting
import org.yuzu.yuzu_emu.utils.ViewUtils.marquee
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
import org.yuzu.yuzu_emu.viewholder.AbstractViewHolder import org.yuzu.yuzu_emu.viewholder.AbstractViewHolder
class HomeSettingAdapter( class HomeSettingAdapter(
@ -64,13 +64,7 @@ class HomeSettingAdapter(
model.details.collect { updateOptionDetails(it) } model.details.collect { updateOptionDetails(it) }
} }
} }
binding.optionDetail.postDelayed( binding.optionDetail.marquee()
{
binding.optionDetail.ellipsize = TextUtils.TruncateAt.MARQUEE
binding.optionDetail.isSelected = true
},
3000
)
binding.root.setOnClickListener { onClick(model) } binding.root.setOnClickListener { onClick(model) }
} }
@ -90,7 +84,7 @@ class HomeSettingAdapter(
private fun updateOptionDetails(detailString: String) { private fun updateOptionDetails(detailString: String) {
if (detailString.isNotEmpty()) { if (detailString.isNotEmpty()) {
binding.optionDetail.text = detailString binding.optionDetail.text = detailString
binding.optionDetail.visibility = View.VISIBLE binding.optionDetail.setVisible(true)
} }
} }
} }

View File

@ -4,10 +4,10 @@
package org.yuzu.yuzu_emu.adapters package org.yuzu.yuzu_emu.adapters
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import org.yuzu.yuzu_emu.databinding.CardInstallableBinding import org.yuzu.yuzu_emu.databinding.CardInstallableBinding
import org.yuzu.yuzu_emu.model.Installable import org.yuzu.yuzu_emu.model.Installable
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
import org.yuzu.yuzu_emu.viewholder.AbstractViewHolder import org.yuzu.yuzu_emu.viewholder.AbstractViewHolder
class InstallableAdapter(installables: List<Installable>) : class InstallableAdapter(installables: List<Installable>) :
@ -26,14 +26,10 @@ class InstallableAdapter(installables: List<Installable>) :
binding.title.setText(model.titleId) binding.title.setText(model.titleId)
binding.description.setText(model.descriptionId) binding.description.setText(model.descriptionId)
if (model.install != null) { binding.buttonInstall.setVisible(model.install != null)
binding.buttonInstall.visibility = View.VISIBLE binding.buttonInstall.setOnClickListener { model.install?.invoke() }
binding.buttonInstall.setOnClickListener { model.install.invoke() } binding.buttonExport.setVisible(model.export != null)
} binding.buttonExport.setOnClickListener { model.export?.invoke() }
if (model.export != null) {
binding.buttonExport.visibility = View.VISIBLE
binding.buttonExport.setOnClickListener { model.export.invoke() }
}
} }
} }
} }

View File

@ -4,12 +4,12 @@
package org.yuzu.yuzu_emu.adapters package org.yuzu.yuzu_emu.adapters
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import org.yuzu.yuzu_emu.databinding.ListItemSettingBinding import org.yuzu.yuzu_emu.databinding.ListItemSettingBinding
import org.yuzu.yuzu_emu.fragments.LicenseBottomSheetDialogFragment import org.yuzu.yuzu_emu.fragments.LicenseBottomSheetDialogFragment
import org.yuzu.yuzu_emu.model.License import org.yuzu.yuzu_emu.model.License
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
import org.yuzu.yuzu_emu.viewholder.AbstractViewHolder import org.yuzu.yuzu_emu.viewholder.AbstractViewHolder
class LicenseAdapter(private val activity: AppCompatActivity, licenses: List<License>) : class LicenseAdapter(private val activity: AppCompatActivity, licenses: List<License>) :
@ -25,7 +25,7 @@ class LicenseAdapter(private val activity: AppCompatActivity, licenses: List<Lic
binding.apply { binding.apply {
textSettingName.text = root.context.getString(model.titleId) textSettingName.text = root.context.getString(model.titleId)
textSettingDescription.text = root.context.getString(model.descriptionId) textSettingDescription.text = root.context.getString(model.descriptionId)
textSettingValue.visibility = View.GONE textSettingValue.setVisible(false)
root.setOnClickListener { onClick(model) } root.setOnClickListener { onClick(model) }
} }

View File

@ -5,7 +5,6 @@ package org.yuzu.yuzu_emu.adapters
import android.text.Html import android.text.Html
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.res.ResourcesCompat import androidx.core.content.res.ResourcesCompat
@ -17,6 +16,7 @@ import org.yuzu.yuzu_emu.model.SetupCallback
import org.yuzu.yuzu_emu.model.SetupPage import org.yuzu.yuzu_emu.model.SetupPage
import org.yuzu.yuzu_emu.model.StepState import org.yuzu.yuzu_emu.model.StepState
import org.yuzu.yuzu_emu.utils.ViewUtils import org.yuzu.yuzu_emu.utils.ViewUtils
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
import org.yuzu.yuzu_emu.viewholder.AbstractViewHolder import org.yuzu.yuzu_emu.viewholder.AbstractViewHolder
class SetupAdapter(val activity: AppCompatActivity, pages: List<SetupPage>) : class SetupAdapter(val activity: AppCompatActivity, pages: List<SetupPage>) :
@ -30,8 +30,8 @@ class SetupAdapter(val activity: AppCompatActivity, pages: List<SetupPage>) :
AbstractViewHolder<SetupPage>(binding), SetupCallback { AbstractViewHolder<SetupPage>(binding), SetupCallback {
override fun bind(model: SetupPage) { override fun bind(model: SetupPage) {
if (model.stepCompleted.invoke() == StepState.COMPLETE) { if (model.stepCompleted.invoke() == StepState.COMPLETE) {
binding.buttonAction.visibility = View.INVISIBLE binding.buttonAction.setVisible(visible = false, gone = false)
binding.textConfirmation.visibility = View.VISIBLE binding.textConfirmation.setVisible(true)
} }
binding.icon.setImageDrawable( binding.icon.setImageDrawable(

View File

@ -27,6 +27,7 @@ import org.yuzu.yuzu_emu.R
import org.yuzu.yuzu_emu.databinding.FragmentSettingsSearchBinding import org.yuzu.yuzu_emu.databinding.FragmentSettingsSearchBinding
import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem
import org.yuzu.yuzu_emu.utils.NativeConfig import org.yuzu.yuzu_emu.utils.NativeConfig
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
import org.yuzu.yuzu_emu.utils.ViewUtils.updateMargins import org.yuzu.yuzu_emu.utils.ViewUtils.updateMargins
class SettingsSearchFragment : Fragment() { class SettingsSearchFragment : Fragment() {
@ -106,10 +107,9 @@ class SettingsSearchFragment : Fragment() {
private fun search() { private fun search() {
val searchTerm = binding.searchText.text.toString().lowercase() val searchTerm = binding.searchText.text.toString().lowercase()
binding.clearButton.visibility = binding.clearButton.setVisible(visible = searchTerm.isNotEmpty(), gone = false)
if (searchTerm.isEmpty()) View.INVISIBLE else View.VISIBLE
if (searchTerm.isEmpty()) { if (searchTerm.isEmpty()) {
binding.noResultsView.visibility = View.VISIBLE binding.noResultsView.setVisible(visible = false, gone = false)
settingsAdapter?.submitList(emptyList()) settingsAdapter?.submitList(emptyList())
return return
} }
@ -136,8 +136,7 @@ class SettingsSearchFragment : Fragment() {
optionalSetting optionalSetting
} }
settingsAdapter?.submitList(sortedList) settingsAdapter?.submitList(sortedList)
binding.noResultsView.visibility = binding.noResultsView.setVisible(visible = sortedList.isEmpty(), gone = false)
if (sortedList.isEmpty()) View.VISIBLE else View.INVISIBLE
} }
private fun focusSearch() { private fun focusSearch() {

View File

@ -14,6 +14,7 @@ import org.yuzu.yuzu_emu.features.settings.model.view.DateTimeSetting
import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem
import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter
import org.yuzu.yuzu_emu.utils.NativeConfig import org.yuzu.yuzu_emu.utils.NativeConfig
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
class DateTimeViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAdapter) : class DateTimeViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAdapter) :
SettingViewHolder(binding.root, adapter) { SettingViewHolder(binding.root, adapter) {
@ -22,27 +23,18 @@ class DateTimeViewHolder(val binding: ListItemSettingBinding, adapter: SettingsA
override fun bind(item: SettingsItem) { override fun bind(item: SettingsItem) {
setting = item as DateTimeSetting setting = item as DateTimeSetting
binding.textSettingName.text = item.title binding.textSettingName.text = item.title
if (setting.description.isNotEmpty()) { binding.textSettingDescription.setVisible(item.description.isNotEmpty())
binding.textSettingDescription.text = item.description binding.textSettingDescription.text = item.description
binding.textSettingDescription.visibility = View.VISIBLE binding.textSettingValue.setVisible(true)
} else {
binding.textSettingDescription.visibility = View.GONE
}
binding.textSettingValue.visibility = View.VISIBLE
val epochTime = setting.getValue() val epochTime = setting.getValue()
val instant = Instant.ofEpochMilli(epochTime * 1000) val instant = Instant.ofEpochMilli(epochTime * 1000)
val zonedTime = ZonedDateTime.ofInstant(instant, ZoneId.of("UTC")) val zonedTime = ZonedDateTime.ofInstant(instant, ZoneId.of("UTC"))
val dateFormatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM) val dateFormatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM)
binding.textSettingValue.text = dateFormatter.format(zonedTime) binding.textSettingValue.text = dateFormatter.format(zonedTime)
binding.buttonClear.visibility = if (setting.setting.global || binding.buttonClear.setVisible(
!NativeConfig.isPerGameConfigLoaded() !setting.setting.global || NativeConfig.isPerGameConfigLoaded()
) { )
View.GONE
} else {
View.VISIBLE
}
binding.buttonClear.setOnClickListener { binding.buttonClear.setOnClickListener {
adapter.onClearClick(setting, bindingAdapterPosition) adapter.onClearClick(setting, bindingAdapterPosition)
} }

View File

@ -9,6 +9,7 @@ import org.yuzu.yuzu_emu.features.settings.model.view.InputProfileSetting
import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem
import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter
import org.yuzu.yuzu_emu.R import org.yuzu.yuzu_emu.R
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
class InputProfileViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAdapter) : class InputProfileViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAdapter) :
SettingViewHolder(binding.root, adapter) { SettingViewHolder(binding.root, adapter) {
@ -20,10 +21,10 @@ class InputProfileViewHolder(val binding: ListItemSettingBinding, adapter: Setti
binding.textSettingValue.text = binding.textSettingValue.text =
setting.getCurrentProfile().ifEmpty { binding.root.context.getString(R.string.not_set) } setting.getCurrentProfile().ifEmpty { binding.root.context.getString(R.string.not_set) }
binding.textSettingDescription.visibility = View.GONE binding.textSettingDescription.setVisible(false)
binding.buttonClear.visibility = View.GONE binding.buttonClear.setVisible(false)
binding.icon.visibility = View.GONE binding.icon.setVisible(false)
binding.buttonClear.visibility = View.GONE binding.buttonClear.setVisible(false)
} }
override fun onClick(clicked: View) = override fun onClick(clicked: View) =

View File

@ -12,6 +12,7 @@ import org.yuzu.yuzu_emu.features.settings.model.view.InputSetting
import org.yuzu.yuzu_emu.features.settings.model.view.ModifierInputSetting import org.yuzu.yuzu_emu.features.settings.model.view.ModifierInputSetting
import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem
import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
class InputViewHolder(val binding: ListItemSettingInputBinding, adapter: SettingsAdapter) : class InputViewHolder(val binding: ListItemSettingInputBinding, adapter: SettingsAdapter) :
SettingViewHolder(binding.root, adapter) { SettingViewHolder(binding.root, adapter) {
@ -22,38 +23,26 @@ class InputViewHolder(val binding: ListItemSettingInputBinding, adapter: Setting
binding.textSettingName.text = setting.title binding.textSettingName.text = setting.title
binding.textSettingValue.text = setting.getSelectedValue() binding.textSettingValue.text = setting.getSelectedValue()
binding.buttonOptions.visibility = when (item) { when (item) {
is AnalogInputSetting -> { is AnalogInputSetting -> {
val param = NativeInput.getStickParam(item.playerIndex, item.nativeAnalog) val param = NativeInput.getStickParam(item.playerIndex, item.nativeAnalog)
if ( binding.buttonOptions.setVisible(
param.get("engine", "") == "analog_from_button" || param.get("engine", "") == "analog_from_button" ||
param.has("axis_x") || param.has("axis_y") param.has("axis_x") || param.has("axis_y")
) { )
View.VISIBLE
} else {
View.GONE
}
} }
is ButtonInputSetting -> { is ButtonInputSetting -> {
val param = NativeInput.getButtonParam(item.playerIndex, item.nativeButton) val param = NativeInput.getButtonParam(item.playerIndex, item.nativeButton)
if ( binding.buttonOptions.setVisible(
param.has("code") || param.has("button") || param.has("hat") || param.has("code") || param.has("button") || param.has("hat") ||
param.has("axis") param.has("axis")
) { )
View.VISIBLE
} else {
View.GONE
}
} }
is ModifierInputSetting -> { is ModifierInputSetting -> {
val params = NativeInput.getStickParam(item.playerIndex, item.nativeAnalog) val params = NativeInput.getStickParam(item.playerIndex, item.nativeAnalog)
if (params.has("modifier")) { binding.buttonOptions.setVisible(params.has("modifier"))
View.VISIBLE
} else {
View.GONE
}
} }
} }

View File

@ -9,6 +9,7 @@ import org.yuzu.yuzu_emu.databinding.ListItemSettingBinding
import org.yuzu.yuzu_emu.features.settings.model.view.RunnableSetting import org.yuzu.yuzu_emu.features.settings.model.view.RunnableSetting
import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem
import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
class RunnableViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAdapter) : class RunnableViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAdapter) :
SettingViewHolder(binding.root, adapter) { SettingViewHolder(binding.root, adapter) {
@ -16,8 +17,8 @@ class RunnableViewHolder(val binding: ListItemSettingBinding, adapter: SettingsA
override fun bind(item: SettingsItem) { override fun bind(item: SettingsItem) {
setting = item as RunnableSetting setting = item as RunnableSetting
binding.icon.setVisible(setting.iconId != 0)
if (setting.iconId != 0) { if (setting.iconId != 0) {
binding.icon.visibility = View.VISIBLE
binding.icon.setImageDrawable( binding.icon.setImageDrawable(
ResourcesCompat.getDrawable( ResourcesCompat.getDrawable(
binding.icon.resources, binding.icon.resources,
@ -25,19 +26,13 @@ class RunnableViewHolder(val binding: ListItemSettingBinding, adapter: SettingsA
binding.icon.context.theme binding.icon.context.theme
) )
) )
} else {
binding.icon.visibility = View.GONE
} }
binding.textSettingName.text = setting.title binding.textSettingName.text = setting.title
if (setting.description.isNotEmpty()) { binding.textSettingDescription.setVisible(setting.description.isNotEmpty())
binding.textSettingDescription.setText(item.descriptionId) binding.textSettingDescription.text = item.description
binding.textSettingDescription.visibility = View.VISIBLE binding.textSettingValue.setVisible(false)
} else { binding.buttonClear.setVisible(false)
binding.textSettingDescription.visibility = View.GONE
}
binding.textSettingValue.visibility = View.GONE
binding.buttonClear.visibility = View.GONE
setStyle(setting.isEditable, binding) setStyle(setting.isEditable, binding)
} }

View File

@ -11,6 +11,7 @@ import org.yuzu.yuzu_emu.features.settings.model.view.SingleChoiceSetting
import org.yuzu.yuzu_emu.features.settings.model.view.StringSingleChoiceSetting import org.yuzu.yuzu_emu.features.settings.model.view.StringSingleChoiceSetting
import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter
import org.yuzu.yuzu_emu.utils.NativeConfig import org.yuzu.yuzu_emu.utils.NativeConfig
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
class SingleChoiceViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAdapter) : class SingleChoiceViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAdapter) :
SettingViewHolder(binding.root, adapter) { SettingViewHolder(binding.root, adapter) {
@ -19,14 +20,10 @@ class SingleChoiceViewHolder(val binding: ListItemSettingBinding, adapter: Setti
override fun bind(item: SettingsItem) { override fun bind(item: SettingsItem) {
setting = item setting = item
binding.textSettingName.text = setting.title binding.textSettingName.text = setting.title
if (item.description.isNotEmpty()) { binding.textSettingDescription.setVisible(item.description.isNotEmpty())
binding.textSettingDescription.text = item.description binding.textSettingDescription.text = item.description
binding.textSettingDescription.visibility = View.VISIBLE
} else {
binding.textSettingDescription.visibility = View.GONE
}
binding.textSettingValue.visibility = View.VISIBLE binding.textSettingValue.setVisible(true)
when (item) { when (item) {
is SingleChoiceSetting -> { is SingleChoiceSetting -> {
val resMgr = binding.textSettingValue.context.resources val resMgr = binding.textSettingValue.context.resources
@ -48,16 +45,12 @@ class SingleChoiceViewHolder(val binding: ListItemSettingBinding, adapter: Setti
} }
} }
if (binding.textSettingValue.text.isEmpty()) { if (binding.textSettingValue.text.isEmpty()) {
binding.textSettingValue.visibility = View.GONE binding.textSettingValue.setVisible(false)
} }
binding.buttonClear.visibility = if (setting.setting.global || binding.buttonClear.setVisible(
!NativeConfig.isPerGameConfigLoaded() !setting.setting.global || NativeConfig.isPerGameConfigLoaded()
) { )
View.GONE
} else {
View.VISIBLE
}
binding.buttonClear.setOnClickListener { binding.buttonClear.setOnClickListener {
adapter.onClearClick(setting, bindingAdapterPosition) adapter.onClearClick(setting, bindingAdapterPosition)
} }

View File

@ -10,6 +10,7 @@ import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem
import org.yuzu.yuzu_emu.features.settings.model.view.SliderSetting import org.yuzu.yuzu_emu.features.settings.model.view.SliderSetting
import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter
import org.yuzu.yuzu_emu.utils.NativeConfig import org.yuzu.yuzu_emu.utils.NativeConfig
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
class SliderViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAdapter) : class SliderViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAdapter) :
SettingViewHolder(binding.root, adapter) { SettingViewHolder(binding.root, adapter) {
@ -18,26 +19,18 @@ class SliderViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAda
override fun bind(item: SettingsItem) { override fun bind(item: SettingsItem) {
setting = item as SliderSetting setting = item as SliderSetting
binding.textSettingName.text = setting.title binding.textSettingName.text = setting.title
if (item.description.isNotEmpty()) { binding.textSettingDescription.setVisible(item.description.isNotEmpty())
binding.textSettingDescription.text = setting.description binding.textSettingDescription.text = setting.description
binding.textSettingDescription.visibility = View.VISIBLE binding.textSettingValue.setVisible(true)
} else {
binding.textSettingDescription.visibility = View.GONE
}
binding.textSettingValue.visibility = View.VISIBLE
binding.textSettingValue.text = String.format( binding.textSettingValue.text = String.format(
binding.textSettingValue.context.getString(R.string.value_with_units), binding.textSettingValue.context.getString(R.string.value_with_units),
setting.getSelectedValue(), setting.getSelectedValue(),
setting.units setting.units
) )
binding.buttonClear.visibility = if (setting.setting.global || binding.buttonClear.setVisible(
!NativeConfig.isPerGameConfigLoaded() !setting.setting.global || NativeConfig.isPerGameConfigLoaded()
) { )
View.GONE
} else {
View.VISIBLE
}
binding.buttonClear.setOnClickListener { binding.buttonClear.setOnClickListener {
adapter.onClearClick(setting, bindingAdapterPosition) adapter.onClearClick(setting, bindingAdapterPosition)
} }

View File

@ -9,6 +9,7 @@ import org.yuzu.yuzu_emu.databinding.ListItemSettingBinding
import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem
import org.yuzu.yuzu_emu.features.settings.model.view.SubmenuSetting import org.yuzu.yuzu_emu.features.settings.model.view.SubmenuSetting
import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
class SubmenuViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAdapter) : class SubmenuViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAdapter) :
SettingViewHolder(binding.root, adapter) { SettingViewHolder(binding.root, adapter) {
@ -16,8 +17,8 @@ class SubmenuViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAd
override fun bind(item: SettingsItem) { override fun bind(item: SettingsItem) {
setting = item as SubmenuSetting setting = item as SubmenuSetting
binding.icon.setVisible(setting.iconId != 0)
if (setting.iconId != 0) { if (setting.iconId != 0) {
binding.icon.visibility = View.VISIBLE
binding.icon.setImageDrawable( binding.icon.setImageDrawable(
ResourcesCompat.getDrawable( ResourcesCompat.getDrawable(
binding.icon.resources, binding.icon.resources,
@ -25,19 +26,13 @@ class SubmenuViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAd
binding.icon.context.theme binding.icon.context.theme
) )
) )
} else {
binding.icon.visibility = View.GONE
} }
binding.textSettingName.text = setting.title binding.textSettingName.text = setting.title
if (setting.description.isNotEmpty()) { binding.textSettingDescription.setVisible(setting.description.isNotEmpty())
binding.textSettingDescription.text = setting.description binding.textSettingDescription.text = setting.description
binding.textSettingDescription.visibility = View.VISIBLE binding.textSettingValue.setVisible(false)
} else { binding.buttonClear.setVisible(false)
binding.textSettingDescription.visibility = View.GONE
}
binding.textSettingValue.visibility = View.GONE
binding.buttonClear.visibility = View.GONE
} }
override fun onClick(clicked: View) { override fun onClick(clicked: View) {

View File

@ -10,6 +10,7 @@ import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem
import org.yuzu.yuzu_emu.features.settings.model.view.SwitchSetting import org.yuzu.yuzu_emu.features.settings.model.view.SwitchSetting
import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter
import org.yuzu.yuzu_emu.utils.NativeConfig import org.yuzu.yuzu_emu.utils.NativeConfig
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
class SwitchSettingViewHolder(val binding: ListItemSettingSwitchBinding, adapter: SettingsAdapter) : class SwitchSettingViewHolder(val binding: ListItemSettingSwitchBinding, adapter: SettingsAdapter) :
SettingViewHolder(binding.root, adapter) { SettingViewHolder(binding.root, adapter) {
@ -19,12 +20,8 @@ class SwitchSettingViewHolder(val binding: ListItemSettingSwitchBinding, adapter
override fun bind(item: SettingsItem) { override fun bind(item: SettingsItem) {
setting = item as SwitchSetting setting = item as SwitchSetting
binding.textSettingName.text = setting.title binding.textSettingName.text = setting.title
if (setting.description.isNotEmpty()) { binding.textSettingDescription.setVisible(setting.description.isNotEmpty())
binding.textSettingDescription.text = setting.description binding.textSettingDescription.text = setting.description
binding.textSettingDescription.visibility = View.VISIBLE
} else {
binding.textSettingDescription.visibility = View.GONE
}
binding.switchWidget.setOnCheckedChangeListener(null) binding.switchWidget.setOnCheckedChangeListener(null)
binding.switchWidget.isChecked = setting.getIsChecked(setting.needsRuntimeGlobal) binding.switchWidget.isChecked = setting.getIsChecked(setting.needsRuntimeGlobal)
@ -32,13 +29,9 @@ class SwitchSettingViewHolder(val binding: ListItemSettingSwitchBinding, adapter
adapter.onBooleanClick(setting, binding.switchWidget.isChecked, bindingAdapterPosition) adapter.onBooleanClick(setting, binding.switchWidget.isChecked, bindingAdapterPosition)
} }
binding.buttonClear.visibility = if (setting.setting.global || binding.buttonClear.setVisible(
!NativeConfig.isPerGameConfigLoaded() !setting.setting.global || NativeConfig.isPerGameConfigLoaded()
) { )
View.GONE
} else {
View.VISIBLE
}
binding.buttonClear.setOnClickListener { binding.buttonClear.setOnClickListener {
adapter.onClearClick(setting, bindingAdapterPosition) adapter.onClearClick(setting, bindingAdapterPosition)
} }

View File

@ -63,6 +63,7 @@ import org.yuzu.yuzu_emu.model.EmulationViewModel
import org.yuzu.yuzu_emu.overlay.model.OverlayControl import org.yuzu.yuzu_emu.overlay.model.OverlayControl
import org.yuzu.yuzu_emu.overlay.model.OverlayLayout import org.yuzu.yuzu_emu.overlay.model.OverlayLayout
import org.yuzu.yuzu_emu.utils.* import org.yuzu.yuzu_emu.utils.*
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
import java.lang.NullPointerException import java.lang.NullPointerException
class EmulationFragment : Fragment(), SurfaceHolder.Callback { class EmulationFragment : Fragment(), SurfaceHolder.Callback {
@ -500,14 +501,12 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
binding.drawerLayout.close() binding.drawerLayout.close()
} }
if (showInputOverlay) { if (showInputOverlay) {
binding.surfaceInputOverlay.visibility = View.INVISIBLE binding.surfaceInputOverlay.setVisible(visible = false, gone = false)
} }
} else { } else {
if (showInputOverlay && emulationViewModel.emulationStarted.value) { binding.surfaceInputOverlay.setVisible(
binding.surfaceInputOverlay.visibility = View.VISIBLE showInputOverlay && emulationViewModel.emulationStarted.value
} else { )
binding.surfaceInputOverlay.visibility = View.INVISIBLE
}
if (!isInFoldableLayout) { if (!isInFoldableLayout) {
if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) { if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
binding.surfaceInputOverlay.layout = OverlayLayout.Portrait binding.surfaceInputOverlay.layout = OverlayLayout.Portrait
@ -544,7 +543,9 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
} }
private fun updateShowFpsOverlay() { private fun updateShowFpsOverlay() {
if (BooleanSetting.SHOW_PERFORMANCE_OVERLAY.getBoolean()) { val showOverlay = BooleanSetting.SHOW_PERFORMANCE_OVERLAY.getBoolean()
binding.showFpsText.setVisible(showOverlay)
if (showOverlay) {
val SYSTEM_FPS = 0 val SYSTEM_FPS = 0
val FPS = 1 val FPS = 1
val FRAMETIME = 2 val FRAMETIME = 2
@ -564,17 +565,17 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
} }
} }
perfStatsUpdateHandler.post(perfStatsUpdater!!) perfStatsUpdateHandler.post(perfStatsUpdater!!)
binding.showFpsText.visibility = View.VISIBLE
} else { } else {
if (perfStatsUpdater != null) { if (perfStatsUpdater != null) {
perfStatsUpdateHandler.removeCallbacks(perfStatsUpdater!!) perfStatsUpdateHandler.removeCallbacks(perfStatsUpdater!!)
} }
binding.showFpsText.visibility = View.GONE
} }
} }
private fun updateThermalOverlay() { private fun updateThermalOverlay() {
if (BooleanSetting.SHOW_THERMAL_OVERLAY.getBoolean()) { val showOverlay = BooleanSetting.SHOW_THERMAL_OVERLAY.getBoolean()
binding.showThermalsText.setVisible(showOverlay)
if (showOverlay) {
thermalStatsUpdater = { thermalStatsUpdater = {
if (emulationViewModel.emulationStarted.value && if (emulationViewModel.emulationStarted.value &&
!emulationViewModel.isEmulationStopping.value !emulationViewModel.isEmulationStopping.value
@ -596,12 +597,10 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
} }
} }
thermalStatsUpdateHandler.post(thermalStatsUpdater!!) thermalStatsUpdateHandler.post(thermalStatsUpdater!!)
binding.showThermalsText.visibility = View.VISIBLE
} else { } else {
if (thermalStatsUpdater != null) { if (thermalStatsUpdater != null) {
thermalStatsUpdateHandler.removeCallbacks(thermalStatsUpdater!!) thermalStatsUpdateHandler.removeCallbacks(thermalStatsUpdater!!)
} }
binding.showThermalsText.visibility = View.GONE
} }
} }
@ -870,12 +869,12 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
} }
} }
} }
binding.doneControlConfig.visibility = View.VISIBLE binding.doneControlConfig.setVisible(false)
binding.surfaceInputOverlay.setIsInEditMode(true) binding.surfaceInputOverlay.setIsInEditMode(true)
} }
private fun stopConfiguringControls() { private fun stopConfiguringControls() {
binding.doneControlConfig.visibility = View.GONE binding.doneControlConfig.setVisible(false)
binding.surfaceInputOverlay.setIsInEditMode(false) binding.surfaceInputOverlay.setIsInEditMode(false)
// Unlock the orientation if it was locked for editing // Unlock the orientation if it was locked for editing
if (IntSetting.RENDERER_SCREEN_LAYOUT.getInt() == EmulationOrientation.Unspecified.int) { if (IntSetting.RENDERER_SCREEN_LAYOUT.getInt() == EmulationOrientation.Unspecified.int) {

View File

@ -27,6 +27,7 @@ import org.yuzu.yuzu_emu.databinding.FragmentGameInfoBinding
import org.yuzu.yuzu_emu.model.GameVerificationResult import org.yuzu.yuzu_emu.model.GameVerificationResult
import org.yuzu.yuzu_emu.model.HomeViewModel import org.yuzu.yuzu_emu.model.HomeViewModel
import org.yuzu.yuzu_emu.utils.GameMetadata import org.yuzu.yuzu_emu.utils.GameMetadata
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
import org.yuzu.yuzu_emu.utils.ViewUtils.updateMargins import org.yuzu.yuzu_emu.utils.ViewUtils.updateMargins
class GameInfoFragment : Fragment() { class GameInfoFragment : Fragment() {
@ -85,7 +86,7 @@ class GameInfoFragment : Fragment() {
copyToClipboard(getString(R.string.developer), args.game.developer) copyToClipboard(getString(R.string.developer), args.game.developer)
} }
} else { } else {
developer.visibility = View.GONE developer.setVisible(false)
} }
version.setHint(R.string.version) version.setHint(R.string.version)

View File

@ -7,7 +7,6 @@ import android.annotation.SuppressLint
import android.content.pm.ShortcutInfo import android.content.pm.ShortcutInfo
import android.content.pm.ShortcutManager import android.content.pm.ShortcutManager
import android.os.Bundle import android.os.Bundle
import android.text.TextUtils
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
@ -46,6 +45,7 @@ import org.yuzu.yuzu_emu.utils.FileUtil
import org.yuzu.yuzu_emu.utils.GameIconUtils import org.yuzu.yuzu_emu.utils.GameIconUtils
import org.yuzu.yuzu_emu.utils.GpuDriverHelper import org.yuzu.yuzu_emu.utils.GpuDriverHelper
import org.yuzu.yuzu_emu.utils.MemoryUtil import org.yuzu.yuzu_emu.utils.MemoryUtil
import org.yuzu.yuzu_emu.utils.ViewUtils.marquee
import org.yuzu.yuzu_emu.utils.ViewUtils.updateMargins import org.yuzu.yuzu_emu.utils.ViewUtils.updateMargins
import java.io.BufferedOutputStream import java.io.BufferedOutputStream
import java.io.File import java.io.File
@ -107,13 +107,7 @@ class GamePropertiesFragment : Fragment() {
GameIconUtils.loadGameIcon(args.game, binding.imageGameScreen) GameIconUtils.loadGameIcon(args.game, binding.imageGameScreen)
binding.title.text = args.game.title binding.title.text = args.game.title
binding.title.postDelayed( binding.title.marquee()
{
binding.title.ellipsize = TextUtils.TruncateAt.MARQUEE
binding.title.isSelected = true
},
3000
)
binding.buttonStart.setOnClickListener { binding.buttonStart.setOnClickListener {
LaunchGameDialogFragment.newInstance(args.game) LaunchGameDialogFragment.newInstance(args.game)

View File

@ -22,6 +22,7 @@ import kotlinx.coroutines.launch
import org.yuzu.yuzu_emu.R import org.yuzu.yuzu_emu.R
import org.yuzu.yuzu_emu.databinding.DialogProgressBarBinding import org.yuzu.yuzu_emu.databinding.DialogProgressBarBinding
import org.yuzu.yuzu_emu.model.TaskViewModel import org.yuzu.yuzu_emu.model.TaskViewModel
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
class ProgressDialogFragment : DialogFragment() { class ProgressDialogFragment : DialogFragment() {
private val taskViewModel: TaskViewModel by activityViewModels() private val taskViewModel: TaskViewModel by activityViewModels()
@ -120,10 +121,8 @@ class ProgressDialogFragment : DialogFragment() {
launch { launch {
repeatOnLifecycle(Lifecycle.State.CREATED) { repeatOnLifecycle(Lifecycle.State.CREATED) {
taskViewModel.message.collect { taskViewModel.message.collect {
if (it.isEmpty()) { binding.message.setVisible(it.isNotEmpty())
binding.message.visibility = View.GONE if (it.isNotEmpty()) {
} else {
binding.message.visibility = View.VISIBLE
binding.message.text = it binding.message.text = it
} }
} }

View File

@ -35,6 +35,7 @@ import org.yuzu.yuzu_emu.layout.AutofitGridLayoutManager
import org.yuzu.yuzu_emu.model.Game import org.yuzu.yuzu_emu.model.Game
import org.yuzu.yuzu_emu.model.GamesViewModel import org.yuzu.yuzu_emu.model.GamesViewModel
import org.yuzu.yuzu_emu.model.HomeViewModel import org.yuzu.yuzu_emu.model.HomeViewModel
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
class SearchFragment : Fragment() { class SearchFragment : Fragment() {
private var _binding: FragmentSearchBinding? = null private var _binding: FragmentSearchBinding? = null
@ -81,11 +82,7 @@ class SearchFragment : Fragment() {
binding.chipGroup.setOnCheckedStateChangeListener { _, _ -> filterAndSearch() } binding.chipGroup.setOnCheckedStateChangeListener { _, _ -> filterAndSearch() }
binding.searchText.doOnTextChanged { text: CharSequence?, _: Int, _: Int, _: Int -> binding.searchText.doOnTextChanged { text: CharSequence?, _: Int, _: Int, _: Int ->
if (text.toString().isNotEmpty()) { binding.clearButton.setVisible(text.toString().isNotEmpty())
binding.clearButton.visibility = View.VISIBLE
} else {
binding.clearButton.visibility = View.INVISIBLE
}
filterAndSearch() filterAndSearch()
} }
@ -109,11 +106,7 @@ class SearchFragment : Fragment() {
repeatOnLifecycle(Lifecycle.State.CREATED) { repeatOnLifecycle(Lifecycle.State.CREATED) {
gamesViewModel.searchedGames.collect { gamesViewModel.searchedGames.collect {
(binding.gridGamesSearch.adapter as GameAdapter).submitList(it) (binding.gridGamesSearch.adapter as GameAdapter).submitList(it)
if (it.isEmpty()) { binding.noResultsView.setVisible(it.isEmpty())
binding.noResultsView.visibility = View.VISIBLE
} else {
binding.noResultsView.visibility = View.GONE
}
} }
} }
} }

View File

@ -46,6 +46,7 @@ import org.yuzu.yuzu_emu.ui.main.MainActivity
import org.yuzu.yuzu_emu.utils.DirectoryInitialization import org.yuzu.yuzu_emu.utils.DirectoryInitialization
import org.yuzu.yuzu_emu.utils.NativeConfig import org.yuzu.yuzu_emu.utils.NativeConfig
import org.yuzu.yuzu_emu.utils.ViewUtils import org.yuzu.yuzu_emu.utils.ViewUtils
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
class SetupFragment : Fragment() { class SetupFragment : Fragment() {
private var _binding: FragmentSetupBinding? = null private var _binding: FragmentSetupBinding? = null
@ -292,12 +293,8 @@ class SetupFragment : Fragment() {
val backIsVisible = savedInstanceState.getBoolean(KEY_BACK_VISIBILITY) val backIsVisible = savedInstanceState.getBoolean(KEY_BACK_VISIBILITY)
hasBeenWarned = savedInstanceState.getBooleanArray(KEY_HAS_BEEN_WARNED)!! hasBeenWarned = savedInstanceState.getBooleanArray(KEY_HAS_BEEN_WARNED)!!
if (nextIsVisible) { binding.buttonNext.setVisible(nextIsVisible)
binding.buttonNext.visibility = View.VISIBLE binding.buttonBack.setVisible(backIsVisible)
}
if (backIsVisible) {
binding.buttonBack.visibility = View.VISIBLE
}
} else { } else {
hasBeenWarned = BooleanArray(pages.size) hasBeenWarned = BooleanArray(pages.size)
} }

View File

@ -26,6 +26,7 @@ import org.yuzu.yuzu_emu.databinding.FragmentGamesBinding
import org.yuzu.yuzu_emu.layout.AutofitGridLayoutManager import org.yuzu.yuzu_emu.layout.AutofitGridLayoutManager
import org.yuzu.yuzu_emu.model.GamesViewModel import org.yuzu.yuzu_emu.model.GamesViewModel
import org.yuzu.yuzu_emu.model.HomeViewModel import org.yuzu.yuzu_emu.model.HomeViewModel
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
import org.yuzu.yuzu_emu.utils.ViewUtils.updateMargins import org.yuzu.yuzu_emu.utils.ViewUtils.updateMargins
class GamesFragment : Fragment() { class GamesFragment : Fragment() {
@ -93,11 +94,10 @@ class GamesFragment : Fragment() {
repeatOnLifecycle(Lifecycle.State.RESUMED) { repeatOnLifecycle(Lifecycle.State.RESUMED) {
gamesViewModel.isReloading.collect { gamesViewModel.isReloading.collect {
binding.swipeRefresh.isRefreshing = it binding.swipeRefresh.isRefreshing = it
if (gamesViewModel.games.value.isEmpty() && !it) { binding.noticeText.setVisible(
binding.noticeText.visibility = View.VISIBLE visible = gamesViewModel.games.value.isEmpty() && !it,
} else { gone = false
binding.noticeText.visibility = View.INVISIBLE )
}
} }
} }
} }

View File

@ -47,6 +47,7 @@ import org.yuzu.yuzu_emu.model.InstallResult
import org.yuzu.yuzu_emu.model.TaskState import org.yuzu.yuzu_emu.model.TaskState
import org.yuzu.yuzu_emu.model.TaskViewModel import org.yuzu.yuzu_emu.model.TaskViewModel
import org.yuzu.yuzu_emu.utils.* import org.yuzu.yuzu_emu.utils.*
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
import java.io.BufferedInputStream import java.io.BufferedInputStream
import java.io.BufferedOutputStream import java.io.BufferedOutputStream
import java.util.zip.ZipEntry import java.util.zip.ZipEntry
@ -139,8 +140,8 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
// Prevents navigation from being drawn for a short time on recreation if set to hidden // Prevents navigation from being drawn for a short time on recreation if set to hidden
if (!homeViewModel.navigationVisible.value.first) { if (!homeViewModel.navigationVisible.value.first) {
binding.navigationView.visibility = View.INVISIBLE binding.navigationView.setVisible(visible = false, gone = false)
binding.statusBarShade.visibility = View.INVISIBLE binding.statusBarShade.setVisible(visible = false, gone = false)
} }
lifecycleScope.apply { lifecycleScope.apply {
@ -214,18 +215,14 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
private fun showNavigation(visible: Boolean, animated: Boolean) { private fun showNavigation(visible: Boolean, animated: Boolean) {
if (!animated) { if (!animated) {
if (visible) { binding.navigationView.setVisible(visible)
binding.navigationView.visibility = View.VISIBLE
} else {
binding.navigationView.visibility = View.INVISIBLE
}
return return
} }
val smallLayout = resources.getBoolean(R.bool.small_layout) val smallLayout = resources.getBoolean(R.bool.small_layout)
binding.navigationView.animate().apply { binding.navigationView.animate().apply {
if (visible) { if (visible) {
binding.navigationView.visibility = View.VISIBLE binding.navigationView.setVisible(true)
duration = 300 duration = 300
interpolator = PathInterpolator(0.05f, 0.7f, 0.1f, 1f) interpolator = PathInterpolator(0.05f, 0.7f, 0.1f, 1f)
@ -264,7 +261,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
} }
}.withEndAction { }.withEndAction {
if (!visible) { if (!visible) {
binding.navigationView.visibility = View.INVISIBLE binding.navigationView.setVisible(visible = false, gone = false)
} }
}.start() }.start()
} }
@ -272,7 +269,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
private fun showStatusBarShade(visible: Boolean) { private fun showStatusBarShade(visible: Boolean) {
binding.statusBarShade.animate().apply { binding.statusBarShade.animate().apply {
if (visible) { if (visible) {
binding.statusBarShade.visibility = View.VISIBLE binding.statusBarShade.setVisible(true)
binding.statusBarShade.translationY = binding.statusBarShade.height.toFloat() * -2 binding.statusBarShade.translationY = binding.statusBarShade.height.toFloat() * -2
duration = 300 duration = 300
translationY(0f) translationY(0f)
@ -284,7 +281,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
} }
}.withEndAction { }.withEndAction {
if (!visible) { if (!visible) {
binding.statusBarShade.visibility = View.INVISIBLE binding.statusBarShade.setVisible(visible = false, gone = false)
} }
}.start() }.start()
} }

View File

@ -3,8 +3,10 @@
package org.yuzu.yuzu_emu.utils package org.yuzu.yuzu_emu.utils
import android.text.TextUtils
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.TextView
object ViewUtils { object ViewUtils {
fun showView(view: View, length: Long = 300) { fun showView(view: View, length: Long = 300) {
@ -57,4 +59,35 @@ object ViewUtils {
} }
this.layoutParams = layoutParams this.layoutParams = layoutParams
} }
/**
* Shows or hides a view.
* @param visible Whether a view will be made View.VISIBLE or View.INVISIBLE/GONE.
* @param gone Optional parameter for hiding a view. Uses View.GONE if true and View.INVISIBLE otherwise.
*/
fun View.setVisible(visible: Boolean, gone: Boolean = true) {
visibility = if (visible) {
View.VISIBLE
} else {
if (gone) {
View.GONE
} else {
View.INVISIBLE
}
}
}
/**
* Starts a marquee on some text.
* @param delay Optional parameter for changing the start delay. 3 seconds of delay by default.
*/
fun TextView.marquee(delay: Long = 3000) {
ellipsize = null
marqueeRepeatLimit = -1
isSingleLine = true
postDelayed({
ellipsize = TextUtils.TruncateAt.MARQUEE
isSelected = true
}, delay)
}
} }

View File

@ -39,10 +39,7 @@
style="@style/TextAppearance.Material3.TitleMedium" style="@style/TextAppearance.Material3.TitleMedium"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:ellipsize="none"
android:marqueeRepeatLimit="marquee_forever"
android:requiresFadingEdge="horizontal" android:requiresFadingEdge="horizontal"
android:singleLine="true"
android:textAlignment="viewStart" android:textAlignment="viewStart"
tools:text="@string/select_gpu_driver_default" /> tools:text="@string/select_gpu_driver_default" />
@ -52,10 +49,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="6dp" android:layout_marginTop="6dp"
android:ellipsize="none"
android:marqueeRepeatLimit="marquee_forever"
android:requiresFadingEdge="horizontal" android:requiresFadingEdge="horizontal"
android:singleLine="true"
android:textAlignment="viewStart" android:textAlignment="viewStart"
tools:text="@string/install_gpu_driver_description" /> tools:text="@string/install_gpu_driver_description" />
@ -65,10 +59,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="6dp" android:layout_marginTop="6dp"
android:ellipsize="none"
android:marqueeRepeatLimit="marquee_forever"
android:requiresFadingEdge="horizontal" android:requiresFadingEdge="horizontal"
android:singleLine="true"
android:textAlignment="viewStart" android:textAlignment="viewStart"
tools:text="@string/install_gpu_driver_description" /> tools:text="@string/install_gpu_driver_description" />

View File

@ -21,10 +21,7 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical|start" android:layout_gravity="center_vertical|start"
android:ellipsize="none"
android:marqueeRepeatLimit="marquee_forever"
android:requiresFadingEdge="horizontal" android:requiresFadingEdge="horizontal"
android:singleLine="true"
android:textAlignment="viewStart" android:textAlignment="viewStart"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/button_layout" app:layout_constraintEnd_toStartOf="@+id/button_layout"

View File

@ -40,10 +40,7 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:ellipsize="none"
android:marqueeRepeatLimit="marquee_forever"
android:requiresFadingEdge="horizontal" android:requiresFadingEdge="horizontal"
android:singleLine="true"
android:textAlignment="center" android:textAlignment="center"
android:textSize="14sp" android:textSize="14sp"
app:layout_constraintEnd_toEndOf="@+id/image_game_screen" app:layout_constraintEnd_toEndOf="@+id/image_game_screen"

View File

@ -59,9 +59,6 @@
android:textAlignment="viewStart" android:textAlignment="viewStart"
android:textSize="14sp" android:textSize="14sp"
android:textStyle="bold" android:textStyle="bold"
android:singleLine="true"
android:marqueeRepeatLimit="marquee_forever"
android:ellipsize="none"
android:requiresFadingEdge="horizontal" android:requiresFadingEdge="horizontal"
android:layout_marginTop="6dp" android:layout_marginTop="6dp"
android:visibility="gone" android:visibility="gone"

View File

@ -76,10 +76,7 @@
android:layout_marginTop="12dp" android:layout_marginTop="12dp"
android:layout_marginBottom="12dp" android:layout_marginBottom="12dp"
android:layout_marginHorizontal="16dp" android:layout_marginHorizontal="16dp"
android:ellipsize="none"
android:marqueeRepeatLimit="marquee_forever"
android:requiresFadingEdge="horizontal" android:requiresFadingEdge="horizontal"
android:singleLine="true"
android:textAlignment="center" android:textAlignment="center"
tools:text="deko_basic" /> tools:text="deko_basic" />