More UI changes + replaced card fragment

This commit is contained in:
CamilleLaVey
2026-09-09 05:12:54 -04:00
parent d1df35a720
commit e54faf323e
18 changed files with 404 additions and 293 deletions
@@ -26,6 +26,22 @@ import org.yuzu.yuzu_emu.features.settings.model.AbstractShortSetting
import org.yuzu.yuzu_emu.features.settings.model.AbstractIntSetting
class QuickSettings(val emulationFragment: EmulationFragment) {
private val expandedShaders = mutableSetOf<Int>()
private fun forgetShaderSlot(index: Int) {
val shifted = mutableSetOf<Int>()
for (slot in expandedShaders) {
if (slot < index) {
shifted.add(slot)
}
if (slot > index) {
shifted.add(slot - 1)
}
}
expandedShaders.clear()
expandedShaders.addAll(shifted)
}
private fun saveSettings() {
if (emulationFragment.shouldUseCustom) {
NativeConfig.savePerGameConfig()
@@ -351,6 +367,7 @@ class QuickSettings(val emulationFragment: EmulationFragment) {
}
fun addShaderCard(
index: Int,
title: String,
summary: String,
container: ViewGroup,
@@ -373,13 +390,20 @@ class QuickSettings(val emulationFragment: EmulationFragment) {
summaryView.text = summary
}
var isExpanded = false
var isExpanded = expandedShaders.contains(index)
if (isExpanded) {
bodyView.visibility = View.VISIBLE
expandIcon.rotation = 180f
}
headerView.setOnClickListener {
isExpanded = !isExpanded
if (isExpanded) {
expandedShaders.add(index)
bodyView.visibility = View.VISIBLE
expandIcon.animate().rotation(180f).setDuration(200).start()
} else {
expandedShaders.remove(index)
bodyView.visibility = View.GONE
expandIcon.animate().rotation(0f).setDuration(200).start()
}
@@ -534,7 +558,7 @@ class QuickSettings(val emulationFragment: EmulationFragment) {
YuzuApplication.appContext.getString(R.string.post_processing_preset_locked)
}
if (NativePostProcessing.isPresetModified()) {
summary =
summary = summary + "\n" +
YuzuApplication.appContext.getString(R.string.post_processing_preset_modified)
}
@@ -574,10 +598,11 @@ class QuickSettings(val emulationFragment: EmulationFragment) {
summary = effect.description
}
val body = addShaderCard(title, summary, container) {
val body = addShaderCard(index, title, summary, container) {
emulationFragment.editPostProcessing {
NativePostProcessing.remove(index)
}
forgetShaderSlot(index)
onStructureChanged()
}
@@ -596,6 +621,7 @@ class QuickSettings(val emulationFragment: EmulationFragment) {
emulationFragment.editPostProcessing {
NativePostProcessing.clearChain()
}
expandedShaders.clear()
onStructureChanged()
}
) { picked ->
@@ -634,7 +660,7 @@ class QuickSettings(val emulationFragment: EmulationFragment) {
container,
steps,
step,
{ position -> describeUniform(uniform, position) },
{ position -> uniform.describe(position) },
{ emulationFragment.persistPostProcessing() }
) { position ->
NativePostProcessing.setValue(
@@ -647,17 +673,6 @@ class QuickSettings(val emulationFragment: EmulationFragment) {
}
}
private fun describeUniform(
uniform: NativePostProcessing.Uniform,
position: Int
): String {
val value = uniform.min + position * uniform.step
if (uniform.kind == NativePostProcessing.KIND_FLOAT) {
return String.format("%.3f", value)
}
return Math.round(value).toString()
}
fun addDivider(container: ViewGroup) {
val inflater = LayoutInflater.from(emulationFragment.requireContext())
val dividerView = inflater.inflate(R.layout.item_quick_settings_divider, container, false)
@@ -65,39 +65,3 @@ class FxUniformSliderSetting(
return currentValue().roundToInt().toString()
}
}
class FxUniformChoiceSetting(
index: Int,
uniform: NativePostProcessing.Uniform,
component: Int
) : FxUniformSetting(index, uniform, component), AbstractIntSetting {
override val defaultValue: Any
get() = uniform.defaultAt(component).roundToInt()
override fun getInt(needsGlobal: Boolean): Int = currentValue().roundToInt()
override fun setInt(value: Int) = commit(value.toFloat())
override fun getValueAsString(needsGlobal: Boolean): String = getInt().toString()
}
class FxUniformBooleanSetting(
index: Int,
uniform: NativePostProcessing.Uniform,
component: Int
) : FxUniformSetting(index, uniform, component), AbstractBooleanSetting {
override val defaultValue: Any
get() = uniform.defaultAt(component) != 0f
override fun getBoolean(needsGlobal: Boolean): Boolean = currentValue() != 0f
override fun setBoolean(value: Boolean) {
var scalar = 0f
if (value) {
scalar = 1f
}
commit(scalar)
}
override fun getValueAsString(needsGlobal: Boolean): String = getBoolean().toString()
}
@@ -1,17 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
package org.yuzu.yuzu_emu.features.settings.model.view
import androidx.annotation.StringRes
class CardSetting(
@StringRes titleId: Int = 0,
titleString: String = "",
@StringRes descriptionId: Int = 0,
descriptionString: String = "",
val expanded: Boolean,
val runnable: () -> Unit
) : SettingsItem(emptySetting, titleId, titleString, descriptionId, descriptionString) {
override val type = TYPE_CARD
}
@@ -0,0 +1,23 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
package org.yuzu.yuzu_emu.features.settings.model.view
import org.yuzu.yuzu_emu.utils.NativePostProcessing
class FxShaderCardSetting(
titleString: String,
descriptionString: String,
val index: Int,
val expanded: Boolean,
val uniforms: List<NativePostProcessing.Uniform>,
val canMoveUp: Boolean,
val canMoveDown: Boolean,
val onToggle: () -> Unit,
val onRemove: () -> Unit,
val onMoveUp: () -> Unit,
val onMoveDown: () -> Unit,
val onReset: () -> Unit
) : SettingsItem(emptySetting, 0, titleString, 0, descriptionString) {
override val type = TYPE_FX_SHADER
}
@@ -144,9 +144,9 @@ abstract class SettingsItem(
const val TYPE_LAUNCHABLE = 13
const val TYPE_PATH = 14
const val TYPE_GPU_UNSWIZZLE = 15
const val TYPE_CARD = 16
const val TYPE_FX_TOOLBAR = 17
const val TYPE_FX_PRESET = 18
const val TYPE_FX_TOOLBAR = 16
const val TYPE_FX_PRESET = 17
const val TYPE_FX_SHADER = 18
const val FASTMEM_COMBINED = "fastmem_combined"
const val GPU_UNSWIZZLE_COMBINED = "gpu_unswizzle_combined"
@@ -23,8 +23,8 @@ import com.google.android.material.timepicker.TimeFormat
import org.yuzu.yuzu_emu.R
import org.yuzu.yuzu_emu.SettingsNavigationDirections
import org.yuzu.yuzu_emu.databinding.ListItemSettingBinding
import org.yuzu.yuzu_emu.databinding.ListItemSettingCardBinding
import org.yuzu.yuzu_emu.databinding.ListItemSettingFxPresetBinding
import org.yuzu.yuzu_emu.databinding.ListItemSettingFxShaderBinding
import org.yuzu.yuzu_emu.databinding.ListItemSettingFxToolbarBinding
import org.yuzu.yuzu_emu.databinding.ListItemSettingInputBinding
import org.yuzu.yuzu_emu.databinding.ListItemSettingSwitchBinding
@@ -109,10 +109,6 @@ class SettingsAdapter(
GpuUnswizzleViewHolder(ListItemSettingBinding.inflate(inflater), this)
}
SettingsItem.TYPE_CARD -> {
CardViewHolder(ListItemSettingCardBinding.inflate(inflater, parent, false), this)
}
SettingsItem.TYPE_FX_TOOLBAR -> {
FxToolbarViewHolder(
ListItemSettingFxToolbarBinding.inflate(inflater, parent, false),
@@ -127,6 +123,13 @@ class SettingsAdapter(
)
}
SettingsItem.TYPE_FX_SHADER -> {
FxShaderCardViewHolder(
ListItemSettingFxShaderBinding.inflate(inflater, parent, false),
this
)
}
else -> {
HeaderViewHolder(ListItemSettingsHeaderBinding.inflate(inflater), this)
}
@@ -19,9 +19,6 @@ import org.yuzu.yuzu_emu.features.settings.model.AbstractBooleanSetting
import org.yuzu.yuzu_emu.features.settings.model.AbstractIntSetting
import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting
import org.yuzu.yuzu_emu.features.settings.model.FxPresetNameSetting
import org.yuzu.yuzu_emu.features.settings.model.FxUniformBooleanSetting
import org.yuzu.yuzu_emu.features.settings.model.FxUniformChoiceSetting
import org.yuzu.yuzu_emu.features.settings.model.FxUniformSliderSetting
import org.yuzu.yuzu_emu.features.settings.model.ByteSetting
import org.yuzu.yuzu_emu.features.settings.model.IntSetting
import org.yuzu.yuzu_emu.features.settings.model.LongSetting
@@ -366,144 +363,64 @@ class SettingsFragmentPresenter(
var header = entry.file
var summary = ""
var uniforms = emptyList<NativePostProcessing.Uniform>()
if (effect != null) {
header = effect.label
if (effect.techniques.size > 1) {
header = effect.label + " \u00b7 " + entry.technique
}
summary = effect.description
uniforms = effect.uniforms
}
val isOpen = expandedShaderSlots.contains(index)
add(
CardSetting(
FxShaderCardSetting(
titleString = header,
descriptionString = summary,
expanded = isOpen
) {
if (isOpen) {
expandedShaderSlots.remove(index)
} else {
expandedShaderSlots.add(index)
}
settingsViewModel.setReloadListAndNotifyDataset(true)
}
)
if (!isOpen) {
continue
}
if (effect != null) {
for (uniform in effect.uniforms) {
addUniform(this, index, uniform)
}
}
if (index > 0) {
add(
RunnableSetting(
titleId = R.string.post_processing_move_up,
isRunnable = true
) {
index = index,
expanded = isOpen,
uniforms = uniforms,
canMoveUp = index > 0,
canMoveDown = index < chain.size - 1,
onToggle = {
if (isOpen) {
expandedShaderSlots.remove(index)
} else {
expandedShaderSlots.add(index)
}
settingsViewModel.setReloadListAndNotifyDataset(true)
},
onRemove = {
NativePostProcessing.remove(index)
NativePostProcessing.store()
expandedShaderSlots.clear()
settingsViewModel.setReloadListAndNotifyDataset(true)
},
onMoveUp = {
NativePostProcessing.move(index, -1)
NativePostProcessing.store()
expandedShaderSlots.clear()
settingsViewModel.setReloadListAndNotifyDataset(true)
}
)
}
if (index < chain.size - 1) {
add(
RunnableSetting(
titleId = R.string.post_processing_move_down,
isRunnable = true
) {
},
onMoveDown = {
NativePostProcessing.move(index, 1)
NativePostProcessing.store()
expandedShaderSlots.clear()
settingsViewModel.setReloadListAndNotifyDataset(true)
},
onReset = {
NativePostProcessing.resetValues(index)
NativePostProcessing.store()
settingsViewModel.setReloadListAndNotifyDataset(true)
}
)
}
add(
RunnableSetting(
titleId = R.string.post_processing_reset,
isRunnable = true
) {
NativePostProcessing.resetValues(index)
NativePostProcessing.store()
settingsViewModel.setReloadListAndNotifyDataset(true)
}
)
add(
RunnableSetting(
titleId = R.string.post_processing_remove,
isRunnable = true
) {
NativePostProcessing.remove(index)
NativePostProcessing.store()
expandedShaderSlots.clear()
settingsViewModel.setReloadListAndNotifyDataset(true)
}
)
}
}
}
private fun addUniform(
sl: ArrayList<SettingsItem>,
index: Int,
uniform: NativePostProcessing.Uniform
) {
if (uniform.uiType == NativePostProcessing.UI_CHECKBOX ||
uniform.kind == NativePostProcessing.KIND_BOOL
) {
sl.add(
SwitchSetting(
FxUniformBooleanSetting(index, uniform, 0),
titleString = uniform.label,
descriptionString = uniform.tooltip
)
)
return
}
if (uniform.items.isNotEmpty() &&
(uniform.uiType == NativePostProcessing.UI_COMBO ||
uniform.uiType == NativePostProcessing.UI_RADIO)
) {
sl.add(
IntSingleChoiceSetting(
FxUniformChoiceSetting(index, uniform, 0),
titleString = uniform.label,
descriptionString = uniform.tooltip,
choices = uniform.items.toTypedArray(),
values = uniform.items.indices.toList().toTypedArray()
)
)
return
}
for (component in 0 until uniform.components) {
var title = uniform.label
if (uniform.components > 1) {
title = uniform.label + " [" + component + "]"
}
sl.add(
SliderSetting(
FxUniformSliderSetting(index, uniform, component),
titleString = title,
descriptionString = uniform.tooltip,
min = 0,
max = uniform.steps
)
)
}
}
private fun addConfigSettings(sl: ArrayList<SettingsItem>) {
sl.apply {
add(
@@ -1,42 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
package org.yuzu.yuzu_emu.features.settings.ui.viewholder
import android.view.View
import org.yuzu.yuzu_emu.databinding.ListItemSettingCardBinding
import org.yuzu.yuzu_emu.features.settings.model.view.CardSetting
import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem
import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
class CardViewHolder(val binding: ListItemSettingCardBinding, adapter: SettingsAdapter) :
SettingViewHolder(binding.root, adapter) {
private lateinit var setting: CardSetting
override fun bind(item: SettingsItem) {
setting = item as CardSetting
binding.textCardName.text = item.title
binding.textCardDescription.text = item.description
binding.textCardDescription.setVisible(item.description.isNotEmpty())
var rotation = 0f
if (setting.expanded) {
rotation = 180f
}
binding.cardExpand.rotation = rotation
}
override fun onClick(clicked: View) {
val target = binding.cardExpand
var rotation = 180f
if (setting.expanded) {
rotation = 0f
}
target.animate().rotation(rotation).setDuration(200).start()
setting.runnable.invoke()
}
override fun onLongClick(clicked: View): Boolean = true
}
@@ -0,0 +1,106 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
package org.yuzu.yuzu_emu.features.settings.ui.viewholder
import android.view.LayoutInflater
import android.view.View
import org.yuzu.yuzu_emu.databinding.ItemSettingFxActionsBinding
import org.yuzu.yuzu_emu.databinding.ItemSettingFxSliderBinding
import org.yuzu.yuzu_emu.databinding.ListItemSettingFxShaderBinding
import org.yuzu.yuzu_emu.features.settings.model.FxUniformSliderSetting
import org.yuzu.yuzu_emu.features.settings.model.view.FxShaderCardSetting
import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem
import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter
import org.yuzu.yuzu_emu.utils.NativePostProcessing
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
class FxShaderCardViewHolder(
val binding: ListItemSettingFxShaderBinding,
adapter: SettingsAdapter
) : SettingViewHolder(binding.root, adapter) {
private lateinit var setting: FxShaderCardSetting
override fun bind(item: SettingsItem) {
setting = item as FxShaderCardSetting
binding.shaderTitle.text = item.title
binding.shaderSummary.text = item.description
binding.shaderSummary.setVisible(item.description.isNotEmpty())
var rotation = 0f
if (setting.expanded) {
rotation = 180f
}
binding.shaderExpand.rotation = rotation
binding.shaderHeader.setOnClickListener { setting.onToggle.invoke() }
binding.shaderRemove.setOnClickListener { setting.onRemove.invoke() }
binding.shaderBody.removeAllViews()
binding.shaderBody.setVisible(setting.expanded)
if (!setting.expanded) {
return
}
val inflater = LayoutInflater.from(binding.root.context)
for (uniform in setting.uniforms) {
if (uniform.uiType == NativePostProcessing.UI_HIDDEN) {
continue
}
for (component in 0 until uniform.components) {
addSlider(inflater, uniform, component)
}
}
addActions(inflater)
}
private fun addSlider(
inflater: LayoutInflater,
uniform: NativePostProcessing.Uniform,
component: Int
) {
val row = ItemSettingFxSliderBinding.inflate(inflater, binding.shaderBody, false)
val value = FxUniformSliderSetting(setting.index, uniform, component)
var title = uniform.label
if (uniform.components > 1) {
title = uniform.label + " [" + component + "]"
}
row.fxSliderTitle.text = title
val steps = uniform.steps.toFloat()
row.fxSlider.valueFrom = 0f
row.fxSlider.valueTo = steps
row.fxSlider.stepSize = 1f
row.fxSlider.value = value.getInt(false).toFloat().coerceIn(0f, steps)
row.fxSliderValue.text = uniform.describe(row.fxSlider.value.toInt())
row.fxSlider.addOnChangeListener { _, position, fromUser ->
if (fromUser) {
value.setInt(position.toInt())
row.fxSliderValue.text = uniform.describe(position.toInt())
}
}
binding.shaderBody.addView(row.root)
}
private fun addActions(inflater: LayoutInflater) {
val row = ItemSettingFxActionsBinding.inflate(inflater, binding.shaderBody, false)
row.fxMoveUp.isEnabled = setting.canMoveUp
row.fxMoveUp.setOnClickListener { setting.onMoveUp.invoke() }
row.fxMoveDown.isEnabled = setting.canMoveDown
row.fxMoveDown.setOnClickListener { setting.onMoveDown.invoke() }
row.fxReset.setOnClickListener { setting.onReset.invoke() }
binding.shaderBody.addView(row.root)
}
override fun onClick(clicked: View) {}
override fun onLongClick(clicked: View): Boolean = true
}
@@ -106,6 +106,14 @@ object NativePostProcessing {
return count
}
fun describe(position: Int): String {
val value = min + position * step
if (kind == NativePostProcessing.KIND_FLOAT) {
return String.format("%.3f", value)
}
return Math.round(value).toString()
}
fun defaultAt(component: Int): Float {
if (component < defaults.size) {
return defaults[component]
@@ -11,27 +11,37 @@
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginTop="4dp"
android:baselineAligned="false"
android:gravity="center_vertical"
android:orientation="horizontal">
<com.google.android.material.button.MaterialButton
android:id="@+id/add_button"
style="@style/Widget.Material3.Button.TonalButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:minHeight="48dp"
android:paddingStart="12dp"
android:paddingEnd="12dp"
android:text="@string/post_processing_add"
app:icon="@drawable/ic_add" />
app:icon="@drawable/ic_add"
app:iconPadding="6dp" />
<com.google.android.material.button.MaterialButton
android:id="@+id/remove_all_button"
style="@style/Widget.Material3.Button.TonalButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_height="match_parent"
android:layout_marginStart="8dp"
android:layout_weight="1"
android:minHeight="48dp"
android:paddingStart="12dp"
android:paddingEnd="12dp"
android:text="@string/post_processing_remove_all"
android:visibility="gone"
app:icon="@drawable/ic_delete" />
app:icon="@drawable/ic_delete"
app:iconPadding="6dp" />
</LinearLayout>
@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:baselineAligned="false"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingStart="20dp"
android:paddingEnd="20dp"
android:paddingTop="8dp"
android:paddingBottom="8dp">
<com.google.android.material.button.MaterialButton
android:id="@+id/fx_move_up"
style="@style/Widget.Material3.Button.IconButton.Filled.Tonal"
android:layout_width="48dp"
android:layout_height="48dp"
android:contentDescription="@string/post_processing_move_up"
android:rotation="180"
app:icon="@drawable/ic_dropdown_arrow" />
<com.google.android.material.button.MaterialButton
android:id="@+id/fx_move_down"
style="@style/Widget.Material3.Button.IconButton.Filled.Tonal"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginStart="8dp"
android:contentDescription="@string/post_processing_move_down"
app:icon="@drawable/ic_dropdown_arrow" />
<com.google.android.material.button.MaterialButton
android:id="@+id/fx_reset"
style="@style/Widget.Material3.Button.TonalButton"
android:layout_width="0dp"
android:layout_height="48dp"
android:layout_marginStart="8dp"
android:layout_weight="1"
android:ellipsize="end"
android:maxLines="1"
android:text="@string/post_processing_reset" />
</LinearLayout>
@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingStart="20dp"
android:paddingEnd="20dp"
android:paddingTop="8dp"
android:paddingBottom="4dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/fx_slider_title"
style="@style/TextAppearance.Material3.TitleSmall"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/fx_slider_value"
style="@style/TextAppearance.Material3.BodySmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:textColor="?attr/colorOnSurfaceVariant" />
</LinearLayout>
<com.google.android.material.slider.Slider
android:id="@+id/fx_slider"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:stepSize="1"
android:valueFrom="0"
android:valueTo="100" />
</LinearLayout>
@@ -1,52 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginTop="6dp"
android:layout_marginBottom="6dp"
android:background="@drawable/shader_card_background"
android:clickable="true"
android:focusable="true"
android:orientation="horizontal"
android:paddingStart="20dp"
android:paddingEnd="16dp"
android:paddingTop="16dp"
android:paddingBottom="16dp">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:orientation="vertical">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/text_card_name"
style="@style/TextAppearance.Material3.TitleMedium"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/text_card_description"
style="@style/TextAppearance.Material3.BodySmall"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:textColor="?attr/colorOnSurfaceVariant" />
</LinearLayout>
<ImageView
android:id="@+id/card_expand"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center_vertical"
android:layout_marginStart="16dp"
android:contentDescription=""
android:src="@drawable/ic_dropdown_arrow"
app:tint="?attr/colorPrimary" />
</LinearLayout>
@@ -0,0 +1,82 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginTop="6dp"
android:layout_marginBottom="6dp"
android:background="@drawable/shader_card_background"
android:orientation="vertical">
<LinearLayout
android:id="@+id/shader_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:orientation="horizontal"
android:paddingStart="20dp"
android:paddingEnd="8dp"
android:paddingTop="14dp"
android:paddingBottom="14dp">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:orientation="vertical">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/shader_title"
style="@style/TextAppearance.Material3.TitleMedium"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/shader_summary"
style="@style/TextAppearance.Material3.BodySmall"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:textColor="?attr/colorOnSurfaceVariant" />
</LinearLayout>
<ImageView
android:id="@+id/shader_remove"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center_vertical"
android:background="?attr/selectableItemBackgroundBorderless"
android:clickable="true"
android:contentDescription="@string/post_processing_remove"
android:focusable="true"
android:padding="8dp"
android:src="@drawable/ic_delete"
app:tint="?attr/colorOnSurfaceVariant" />
<ImageView
android:id="@+id/shader_expand"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center_vertical"
android:layout_marginStart="4dp"
android:contentDescription=""
android:src="@drawable/ic_dropdown_arrow"
app:tint="?attr/colorPrimary" />
</LinearLayout>
<LinearLayout
android:id="@+id/shader_body"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="8dp"
android:visibility="gone" />
</LinearLayout>
@@ -7,6 +7,7 @@
android:layout_marginEnd="16dp"
android:layout_marginTop="6dp"
android:layout_marginBottom="6dp"
android:baselineAligned="false"
android:gravity="center_vertical"
android:orientation="horizontal">
@@ -14,25 +15,33 @@
android:id="@+id/fx_add"
style="@style/Widget.Material3.Button.TonalButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:ellipsize="end"
android:maxLines="1"
android:minHeight="48dp"
android:paddingStart="12dp"
android:paddingEnd="12dp"
android:text="@string/post_processing_add"
app:icon="@drawable/ic_add" />
app:icon="@drawable/ic_add"
app:iconPadding="6dp" />
<com.google.android.material.button.MaterialButton
android:id="@+id/fx_presets"
style="@style/Widget.Material3.Button.TonalButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_height="match_parent"
android:layout_marginStart="8dp"
android:layout_weight="1.4"
android:ellipsize="end"
android:maxLines="1"
android:minHeight="48dp"
android:paddingStart="12dp"
android:paddingEnd="12dp"
android:text="@string/post_processing_presets"
app:icon="@drawable/ic_dropdown_arrow"
app:iconGravity="textEnd" />
app:iconGravity="textEnd"
app:iconPadding="6dp" />
<com.google.android.material.button.MaterialButton
android:id="@+id/fx_create_preset"
@@ -307,7 +307,7 @@
<string name="post_processing_close_list">Close list</string>
<string name="post_processing_remove_all">Remove effects</string>
<string name="post_processing_preset_locked">Preset active. Edit it in Post-Processing Effects before starting a game.</string>
<string name="post_processing_preset_modified">Preset active, with your own changes.</string>
<string name="post_processing_preset_modified">Values changed from the original preset.</string>
<string name="post_processing_presets">Presets</string>
<string name="post_processing_preset_new">New preset</string>
<string name="post_processing_preset_new_description">Saves the effects you have loaded, with their current values, as a preset you can pick later.</string>
+2 -1
View File
@@ -254,7 +254,8 @@ bool IsActiveFxPresetModified() {
return true;
}
return SerializeFxChain(FxChain::Instance().Entries()) != preset->chain;
return SerializeFxChain(FxChain::Instance().Entries()) !=
SerializeFxChain(ParseFxChain(preset->chain));
}
} // namespace VideoCore