Refactored selection view item

This commit is contained in:
SSimco
2024-10-17 19:13:37 +03:00
parent fb94873230
commit c2014b16da
8 changed files with 123 additions and 239 deletions
@@ -6,7 +6,6 @@ import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.fragment.NavHostFragment;
@@ -14,22 +13,21 @@ import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import info.cemu.Cemu.R;
import info.cemu.Cemu.databinding.FragmentGameProfileEditBinding;
import info.cemu.Cemu.guibasecomponents.GenericRecyclerViewAdapter;
import info.cemu.Cemu.guibasecomponents.HeaderRecyclerViewItem;
import info.cemu.Cemu.guibasecomponents.SelectionAdapter;
import info.cemu.Cemu.guibasecomponents.SingleSelectionRecyclerViewItem;
import info.cemu.Cemu.guibasecomponents.ToggleRecyclerViewItem;
import info.cemu.Cemu.nativeinterface.NativeGameTitles;
public class GameProfileEditFragment extends Fragment {
private static @StringRes() int cpuModeToResourceNameId(int cpuMode) {
return switch (cpuMode) {
private String cpuModeToString(int cpuMode) {
int resourceId = switch (cpuMode) {
case NativeGameTitles.CPU_MODE_SINGLECOREINTERPRETER ->
R.string.cpu_mode_single_core_interpreter;
case NativeGameTitles.CPU_MODE_SINGLECORERECOMPILER ->
@@ -38,6 +36,7 @@ public class GameProfileEditFragment extends Fragment {
R.string.cpu_mode_multi_core_recompiler;
default -> R.string.cpu_mode_auto;
};
return getString(resourceId);
}
@Override
@@ -60,33 +59,21 @@ public class GameProfileEditFragment extends Fragment {
checked -> NativeGameTitles.setShaderMultiplicationAccuracyForTitleEnabled(titleId, checked));
genericRecyclerViewAdapter.addRecyclerViewItem(shaderMultiplicationAccuracyToggle);
int currentCpuMode = NativeGameTitles.getCpuModeForTitle(titleId);
var cpuModeChoices = Stream.of(NativeGameTitles.CPU_MODE_SINGLECOREINTERPRETER,
SingleSelectionRecyclerViewItem<Integer> cpuModeSelection = new SingleSelectionRecyclerViewItem<>(getString(R.string.cpu_mode),
NativeGameTitles.getCpuModeForTitle(titleId),
List.of(NativeGameTitles.CPU_MODE_SINGLECOREINTERPRETER,
NativeGameTitles.CPU_MODE_SINGLECORERECOMPILER,
NativeGameTitles.CPU_MODE_MULTICORERECOMPILER,
NativeGameTitles.CPU_MODE_AUTO)
.map(cpuMode -> new SelectionAdapter.ChoiceItem<>(t -> t.setText(cpuModeToResourceNameId(cpuMode)), cpuMode))
.collect(Collectors.toList());
SelectionAdapter<Integer> cpuSelectionAdapter = new SelectionAdapter<>(cpuModeChoices, currentCpuMode);
SingleSelectionRecyclerViewItem<Integer> cpuModeSelection = new SingleSelectionRecyclerViewItem<>(getString(R.string.cpu_mode),
getString(cpuModeToResourceNameId(currentCpuMode)), cpuSelectionAdapter,
(cpuMode, selectionRecyclerViewItem) -> {
NativeGameTitles.setCpuModeForTitle(titleId, cpuMode);
selectionRecyclerViewItem.setDescription(getString(cpuModeToResourceNameId(cpuMode)));
});
NativeGameTitles.CPU_MODE_AUTO),
this::cpuModeToString,
cpuMode -> NativeGameTitles.setCpuModeForTitle(titleId, cpuMode));
genericRecyclerViewAdapter.addRecyclerViewItem(cpuModeSelection);
int currentThreadQuantum = NativeGameTitles.getThreadQuantumForTitle(titleId);
var threadQuantumChoices = Arrays.stream(NativeGameTitles.THREAD_QUANTUM_VALUES)
.mapToObj(threadQuantum -> new SelectionAdapter.ChoiceItem<>(t -> t.setText(String.valueOf(threadQuantum)), threadQuantum))
.collect(Collectors.toList());
SelectionAdapter<Integer> threadQuantumSelectionAdapter = new SelectionAdapter<>(threadQuantumChoices, currentThreadQuantum);
SingleSelectionRecyclerViewItem<Integer> threadQuantumSelection = new SingleSelectionRecyclerViewItem<>(getString(R.string.thread_quantum),
String.valueOf(currentThreadQuantum), threadQuantumSelectionAdapter,
(threadQuantum, selectionRecyclerViewItem) -> {
NativeGameTitles.setThreadQuantumForTitle(titleId, threadQuantum);
selectionRecyclerViewItem.setDescription(String.valueOf(threadQuantum));
});
NativeGameTitles.getThreadQuantumForTitle(titleId),
Arrays.stream(NativeGameTitles.THREAD_QUANTUM_VALUES).boxed().collect(Collectors.toList()),
String::valueOf,
threadQuantum -> NativeGameTitles.setThreadQuantumForTitle(titleId, threadQuantum));
genericRecyclerViewAdapter.addRecyclerViewItem(threadQuantumSelection);
binding.recyclerView.setAdapter(genericRecyclerViewAdapter);
@@ -1,73 +0,0 @@
package info.cemu.Cemu.guibasecomponents;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import info.cemu.Cemu.R;
public abstract class BaseSingleSelectionRecyclerViewItem<T> implements RecyclerViewItem {
private static class SingleSelectionViewHolder extends RecyclerView.ViewHolder {
TextView label;
TextView description;
public SingleSelectionViewHolder(View itemView) {
super(itemView);
label = itemView.findViewById(R.id.selection_label);
description = itemView.findViewById(R.id.selection_description);
}
}
public interface OnItemSelectedListener<T> {
void onItemSelected(T selectedValue, BaseSingleSelectionRecyclerViewItem<T> selectionRecyclerViewItem);
}
private final SelectionAdapter<T> selectionAdapter;
private final String label;
private String description;
private final OnItemSelectedListener<T> onItemSelectedListener;
private SingleSelectionViewHolder singleSelectionViewHolder;
private RecyclerView.Adapter<RecyclerView.ViewHolder> recyclerViewAdapter;
public BaseSingleSelectionRecyclerViewItem(String label, String description, SelectionAdapter<T> selectionAdapter, OnItemSelectedListener<T> onItemSelectedListener) {
this.label = label;
this.description = description;
this.selectionAdapter = selectionAdapter;
this.onItemSelectedListener = onItemSelectedListener;
}
public void setDescription(String description) {
this.description = description;
recyclerViewAdapter.notifyItemChanged(singleSelectionViewHolder.getAdapterPosition());
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent) {
return new SingleSelectionViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_single_selection, parent, false));
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, RecyclerView.Adapter<RecyclerView.ViewHolder> recyclerViewAdapter) {
this.recyclerViewAdapter = recyclerViewAdapter;
singleSelectionViewHolder = (SingleSelectionViewHolder) viewHolder;
singleSelectionViewHolder.label.setText(label);
singleSelectionViewHolder.description.setText(description);
singleSelectionViewHolder.itemView.setOnClickListener(view -> {
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(viewHolder.itemView.getContext());
builder.setTitle(label).setAdapter(selectionAdapter, (dialogInterface, position) -> {
if (!selectionAdapter.isEnabled(position))
return;
T selectedValue = selectionAdapter.getItem(position);
selectionAdapter.setSelectedValue(selectedValue);
if (onItemSelectedListener != null)
onItemSelectedListener.onItemSelected(selectedValue, BaseSingleSelectionRecyclerViewItem.this);
}).setNegativeButton(R.string.cancel, (dialogInterface, i) -> dialogInterface.dismiss()).show();
});
}
}
@@ -10,6 +10,10 @@ import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
import info.cemu.Cemu.R;
public class SingleSelectionRecyclerViewItem<T> implements RecyclerViewItem {
@@ -28,6 +32,10 @@ public class SingleSelectionRecyclerViewItem<T> implements RecyclerViewItem {
void onItemSelected(T selectedValue, SingleSelectionRecyclerViewItem<T> selectionRecyclerViewItem);
}
public interface OnChoiceSelectedListener<T> {
void onChoiceSelected(T selectedValue);
}
private final BaseSelectionAdapter<T> selectionAdapter;
private final String label;
private String description;
@@ -36,6 +44,19 @@ public class SingleSelectionRecyclerViewItem<T> implements RecyclerViewItem {
private RecyclerView.Adapter<RecyclerView.ViewHolder> recyclerViewAdapter;
private AlertDialog selectAlertDialog;
public SingleSelectionRecyclerViewItem(String label, T currentChoice, List<T> choicesList, Function<T, String> choiceValueToNameFunction, OnChoiceSelectedListener<T> onChoiceSelectedListener) {
this(label,
choiceValueToNameFunction.apply(currentChoice),
new SelectionAdapter<>(choicesList.stream()
.map(channels -> new SelectionAdapter.ChoiceItem<>(t -> t.setText(choiceValueToNameFunction.apply(channels)), channels))
.collect(Collectors.toList()), currentChoice),
(selectedValue, selectionRecyclerViewItem) -> {
onChoiceSelectedListener.onChoiceSelected(selectedValue);
selectionRecyclerViewItem.setDescription(choiceValueToNameFunction.apply(selectedValue));
}
);
}
public SingleSelectionRecyclerViewItem(String label, String description, BaseSelectionAdapter<T> selectionAdapter, OnItemSelectedListener<T> onItemSelectedListener) {
this.label = label;
this.description = description;
@@ -15,11 +15,10 @@ import java.util.stream.IntStream;
import info.cemu.Cemu.R;
import info.cemu.Cemu.databinding.LayoutGenericRecyclerViewBinding;
import info.cemu.Cemu.guibasecomponents.ToggleRecyclerViewItem;
import info.cemu.Cemu.guibasecomponents.GenericRecyclerViewAdapter;
import info.cemu.Cemu.guibasecomponents.SelectionAdapter;
import info.cemu.Cemu.guibasecomponents.SingleSelectionRecyclerViewItem;
import info.cemu.Cemu.guibasecomponents.SliderRecyclerViewItem;
import info.cemu.Cemu.guibasecomponents.ToggleRecyclerViewItem;
import info.cemu.Cemu.nativeinterface.NativeInput;
@@ -71,21 +70,12 @@ public class InputOverlaySettingsFragment extends Fragment {
});
genericRecyclerViewAdapter.addRecyclerViewItem(alphaSlider);
SelectionAdapter<Integer> controllerAdapter = new SelectionAdapter<>(
IntStream.range(0, NativeInput.MAX_CONTROLLERS)
.mapToObj(i -> new SelectionAdapter.ChoiceItem<>(t -> t.setText(getString(R.string.controller_numbered, i + 1)), i))
.collect(Collectors.toList()),
overlaySettings.getControllerIndex()
);
SingleSelectionRecyclerViewItem<Integer> controllerSelection = new SingleSelectionRecyclerViewItem<>(
getString(R.string.overlay_controller),
getString(R.string.controller_numbered, overlaySettings.getControllerIndex() + 1),
controllerAdapter,
(controllerIndex, selectionRecyclerViewItem) -> {
overlaySettings.setControllerIndex(controllerIndex);
selectionRecyclerViewItem.setDescription(getString(R.string.controller_numbered, controllerIndex + 1));
overlaySettings.saveSettings();
});
overlaySettings.getControllerIndex(),
IntStream.range(0, NativeInput.MAX_CONTROLLERS).boxed().collect(Collectors.toList()),
controllerIndex -> getString(R.string.controller_numbered, controllerIndex + 1),
(controllerIndex) -> overlaySettings.setControllerIndex(controllerIndex));
genericRecyclerViewAdapter.addRecyclerViewItem(controllerSelection);
binding.recyclerView.setAdapter(genericRecyclerViewAdapter);
@@ -9,28 +9,27 @@ import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import info.cemu.Cemu.R;
import info.cemu.Cemu.databinding.LayoutGenericRecyclerViewBinding;
import info.cemu.Cemu.guibasecomponents.ToggleRecyclerViewItem;
import info.cemu.Cemu.guibasecomponents.GenericRecyclerViewAdapter;
import info.cemu.Cemu.guibasecomponents.SelectionAdapter;
import info.cemu.Cemu.guibasecomponents.SingleSelectionRecyclerViewItem;
import info.cemu.Cemu.guibasecomponents.SliderRecyclerViewItem;
import info.cemu.Cemu.guibasecomponents.ToggleRecyclerViewItem;
import info.cemu.Cemu.nativeinterface.NativeSettings;
public class AudioSettingsFragment extends Fragment {
private static int channelsToResourceNameId(int channels) {
return switch (channels) {
private String channelsToString(int channels) {
int resourceNameId = switch (channels) {
case NativeSettings.AUDIO_CHANNELS_MONO -> R.string.mono;
case NativeSettings.AUDIO_CHANNELS_STEREO -> R.string.stereo;
case NativeSettings.AUDIO_CHANNELS_SURROUND -> R.string.surround;
default -> throw new IllegalArgumentException("Invalid channels type: " + channels);
};
return getString(resourceNameId);
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
var binding = LayoutGenericRecyclerViewBinding.inflate(inflater, container, false);
@@ -50,17 +49,13 @@ public class AudioSettingsFragment extends Fragment {
checked -> NativeSettings.setAudioDeviceEnabled(checked, true));
genericRecyclerViewAdapter.addRecyclerViewItem(tvDeviceToggle);
var tvChannelsChoices = Stream.of(NativeSettings.AUDIO_CHANNELS_MONO, NativeSettings.AUDIO_CHANNELS_STEREO, NativeSettings.AUDIO_CHANNELS_SURROUND)
.map(channels -> new SelectionAdapter.ChoiceItem<>(t -> t.setText(channelsToResourceNameId(channels)), channels))
.collect(Collectors.toList());
int tvChannels = NativeSettings.getAudioDeviceChannels(true);
SelectionAdapter<Integer> tvChannelsSelectionAdapter = new SelectionAdapter<>(tvChannelsChoices, tvChannels);
SingleSelectionRecyclerViewItem<Integer> tvChannelsModeSelection = new SingleSelectionRecyclerViewItem<>(getString(R.string.tv_channels),
getString(channelsToResourceNameId(tvChannels)), tvChannelsSelectionAdapter,
(channels, selectionRecyclerViewItem) -> {
NativeSettings.setAudioDeviceChannels(channels, true);
selectionRecyclerViewItem.setDescription(getString(channelsToResourceNameId(channels)));
});
NativeSettings.getAudioDeviceChannels(true),
List.of(NativeSettings.AUDIO_CHANNELS_MONO,
NativeSettings.AUDIO_CHANNELS_STEREO,
NativeSettings.AUDIO_CHANNELS_SURROUND),
this::channelsToString,
channels -> NativeSettings.setAudioDeviceChannels(channels, true));
genericRecyclerViewAdapter.addRecyclerViewItem(tvChannelsModeSelection);
SliderRecyclerViewItem tvVolumeSlider = new SliderRecyclerViewItem(getString(R.string.tv_volume),
@@ -76,15 +71,12 @@ public class AudioSettingsFragment extends Fragment {
checked -> NativeSettings.setAudioDeviceEnabled(checked, false));
genericRecyclerViewAdapter.addRecyclerViewItem(padDeviceToggle);
var gamepadChannelsChoices = List.of(new SelectionAdapter.ChoiceItem<>(t -> t.setText(channelsToResourceNameId(NativeSettings.AUDIO_CHANNELS_STEREO)), NativeSettings.AUDIO_CHANNELS_STEREO));
int gamepadChannels = NativeSettings.getAudioDeviceChannels(false);
SelectionAdapter<Integer> gamepadChannelsSelectionAdapter = new SelectionAdapter<>(gamepadChannelsChoices, gamepadChannels);
SingleSelectionRecyclerViewItem<Integer> gamepadChannelsModeSelection = new SingleSelectionRecyclerViewItem<>(getString(R.string.gamepad_channels),
getString(channelsToResourceNameId(gamepadChannels)), gamepadChannelsSelectionAdapter,
(channels, selectionRecyclerViewItem) -> {
NativeSettings.setAudioDeviceChannels(channels, false);
selectionRecyclerViewItem.setDescription(getString(channelsToResourceNameId(channels)));
});
NativeSettings.getAudioDeviceChannels(false),
List.of(NativeSettings.AUDIO_CHANNELS_STEREO),
this::channelsToString,
channels -> NativeSettings.setAudioDeviceChannels(channels, false)
);
genericRecyclerViewAdapter.addRecyclerViewItem(gamepadChannelsModeSelection);
SliderRecyclerViewItem padVolumeSlider = new SliderRecyclerViewItem(getString(R.string.pad_volume),
@@ -6,24 +6,21 @@ import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.List;
import info.cemu.Cemu.R;
import info.cemu.Cemu.databinding.LayoutGenericRecyclerViewBinding;
import info.cemu.Cemu.guibasecomponents.ButtonRecyclerViewItem;
import info.cemu.Cemu.guibasecomponents.GenericRecyclerViewAdapter;
import info.cemu.Cemu.guibasecomponents.SelectionAdapter;
import info.cemu.Cemu.guibasecomponents.SingleSelectionRecyclerViewItem;
import info.cemu.Cemu.nativeinterface.NativeSettings;
public class GeneralSettingsFragment extends Fragment {
private static @StringRes() int consoleLanguageToResourceNameId(int channels) {
return switch (channels) {
private String consoleLanguageToString(int channels) {
int resourceId = switch (channels) {
case NativeSettings.CONSOLE_LANGUAGE_JAPANESE -> R.string.console_language_japanese;
case NativeSettings.CONSOLE_LANGUAGE_ENGLISH -> R.string.console_language_english;
case NativeSettings.CONSOLE_LANGUAGE_FRENCH -> R.string.console_language_french;
@@ -38,6 +35,7 @@ public class GeneralSettingsFragment extends Fragment {
case NativeSettings.CONSOLE_LANGUAGE_TAIWANESE -> R.string.console_language_taiwanese;
default -> throw new IllegalArgumentException("Invalid console language: " + channels);
};
return getString(resourceId);
}
@Override
@@ -48,7 +46,9 @@ public class GeneralSettingsFragment extends Fragment {
genericRecyclerViewAdapter.addRecyclerViewItem(new ButtonRecyclerViewItem(getString(R.string.add_game_path), getString(R.string.games_folder_description), () -> NavHostFragment.findNavController(GeneralSettingsFragment.this).navigate(R.id.action_generalSettingsFragment_to_gamePathsFragment)));
var consoleLanguageChoices = Stream.of(NativeSettings.CONSOLE_LANGUAGE_JAPANESE,
SingleSelectionRecyclerViewItem<Integer> consoleLanguageSelection = new SingleSelectionRecyclerViewItem<>(getString(R.string.console_language),
NativeSettings.getConsoleLanguage(),
List.of(NativeSettings.CONSOLE_LANGUAGE_JAPANESE,
NativeSettings.CONSOLE_LANGUAGE_ENGLISH,
NativeSettings.CONSOLE_LANGUAGE_FRENCH,
NativeSettings.CONSOLE_LANGUAGE_GERMAN,
@@ -59,17 +59,9 @@ public class GeneralSettingsFragment extends Fragment {
NativeSettings.CONSOLE_LANGUAGE_DUTCH,
NativeSettings.CONSOLE_LANGUAGE_PORTUGUESE,
NativeSettings.CONSOLE_LANGUAGE_RUSSIAN,
NativeSettings.CONSOLE_LANGUAGE_TAIWANESE)
.map(channels -> new SelectionAdapter.ChoiceItem<>(t -> t.setText(consoleLanguageToResourceNameId(channels)), channels))
.collect(Collectors.toList());
int currentConsoleLanguage = NativeSettings.getConsoleLanguage();
SelectionAdapter<Integer> consoleLanguageAdapter = new SelectionAdapter<>(consoleLanguageChoices, currentConsoleLanguage);
SingleSelectionRecyclerViewItem<Integer> consoleLanguageSelection = new SingleSelectionRecyclerViewItem<>(getString(R.string.console_language),
getString(consoleLanguageToResourceNameId(currentConsoleLanguage)), consoleLanguageAdapter,
(consoleLanguage, selectionRecyclerViewItem) -> {
NativeSettings.setConsoleLanguage(consoleLanguage);
selectionRecyclerViewItem.setDescription(getString(consoleLanguageToResourceNameId(consoleLanguage)));
});
NativeSettings.CONSOLE_LANGUAGE_TAIWANESE),
this::consoleLanguageToString,
NativeSettings::setConsoleLanguage);
genericRecyclerViewAdapter.addRecyclerViewItem(consoleLanguageSelection);
binding.recyclerView.setAdapter(genericRecyclerViewAdapter);
@@ -8,38 +8,38 @@ import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.List;
import info.cemu.Cemu.R;
import info.cemu.Cemu.databinding.LayoutGenericRecyclerViewBinding;
import info.cemu.Cemu.guibasecomponents.ToggleRecyclerViewItem;
import info.cemu.Cemu.guibasecomponents.GenericRecyclerViewAdapter;
import info.cemu.Cemu.guibasecomponents.SelectionAdapter;
import info.cemu.Cemu.guibasecomponents.SingleSelectionRecyclerViewItem;
import info.cemu.Cemu.guibasecomponents.ToggleRecyclerViewItem;
import info.cemu.Cemu.nativeinterface.NativeSettings;
public class GraphicsSettingsFragment extends Fragment {
private static int vsyncModeToResourceNameId(int vsyncMode) {
return switch (vsyncMode) {
private String vsyncModeToString(int vsyncMode) {
int resourceId = switch (vsyncMode) {
case NativeSettings.VSYNC_MODE_OFF -> R.string.off;
case NativeSettings.VSYNC_MODE_DOUBLE_BUFFERING -> R.string.double_buffering;
case NativeSettings.VSYNC_MODE_TRIPLE_BUFFERING -> R.string.triple_buffering;
default -> throw new IllegalArgumentException("Invalid vsync mode: " + vsyncMode);
};
return getString(resourceId);
}
private static int fullscreenScalingModeToResourceNameId(int fullscreenScaling) {
return switch (fullscreenScaling) {
private String fullscreenScalingModeToString(int fullscreenScaling) {
int resourceId = switch (fullscreenScaling) {
case NativeSettings.FULLSCREEN_SCALING_KEEP_ASPECT_RATIO -> R.string.keep_aspect_ratio;
case NativeSettings.FULLSCREEN_SCALING_STRETCH -> R.string.stretch;
default ->
throw new IllegalArgumentException("Invalid fullscreen scaling mode: " + fullscreenScaling);
};
return getString(resourceId);
}
private static int scalingFilterToResourceNameId(int scalingFilter) {
return switch (scalingFilter) {
private String scalingFilterToString(int scalingFilter) {
int resourceId = switch (scalingFilter) {
case NativeSettings.SCALING_FILTER_BILINEAR_FILTER -> R.string.bilinear;
case NativeSettings.SCALING_FILTER_BICUBIC_FILTER -> R.string.bicubic;
case NativeSettings.SCALING_FILTER_BICUBIC_HERMITE_FILTER -> R.string.hermite;
@@ -47,6 +47,7 @@ public class GraphicsSettingsFragment extends Fragment {
default ->
throw new IllegalArgumentException("Invalid scaling filter: " + scalingFilter);
};
return getString(resourceId);
}
@Override
@@ -58,61 +59,44 @@ public class GraphicsSettingsFragment extends Fragment {
ToggleRecyclerViewItem asyncShaderToggle = new ToggleRecyclerViewItem(getString(R.string.async_shader_compile), getString(R.string.async_shader_compile_description), NativeSettings.getAsyncShaderCompile(), NativeSettings::setAsyncShaderCompile);
genericRecyclerViewAdapter.addRecyclerViewItem(asyncShaderToggle);
int vsyncMode = NativeSettings.getVSyncMode();
var vsyncChoices = Stream.of(NativeSettings.VSYNC_MODE_OFF, NativeSettings.VSYNC_MODE_DOUBLE_BUFFERING, NativeSettings.VSYNC_MODE_TRIPLE_BUFFERING)
.map(vsync -> new SelectionAdapter.ChoiceItem<>(t -> t.setText(vsyncModeToResourceNameId(vsync)), vsync))
.collect(Collectors.toList());
SelectionAdapter<Integer> vsyncSelectionAdapter = new SelectionAdapter<>(vsyncChoices, vsyncMode);
SingleSelectionRecyclerViewItem<Integer> vsyncModeSelection = new SingleSelectionRecyclerViewItem<>(getString(R.string.vsync),
getString(vsyncModeToResourceNameId(vsyncMode)), vsyncSelectionAdapter,
(vsync, selectionRecyclerViewItem) -> {
NativeSettings.setVSyncMode(vsync);
selectionRecyclerViewItem.setDescription(getString(vsyncModeToResourceNameId(vsync)));
});
NativeSettings.getVSyncMode(),
List.of(NativeSettings.VSYNC_MODE_OFF,
NativeSettings.VSYNC_MODE_DOUBLE_BUFFERING,
NativeSettings.VSYNC_MODE_TRIPLE_BUFFERING),
this::vsyncModeToString,
NativeSettings::setVSyncMode);
genericRecyclerViewAdapter.addRecyclerViewItem(vsyncModeSelection);
ToggleRecyclerViewItem accurateBarriersToggle = new ToggleRecyclerViewItem(getString(R.string.accurate_barriers), getString(R.string.accurate_barriers_description), NativeSettings.getAccurateBarriers(), NativeSettings::setAccurateBarriers);
genericRecyclerViewAdapter.addRecyclerViewItem(accurateBarriersToggle);
int fullscreenScalingMode = NativeSettings.getFullscreenScaling();
var fullscreenScalingChoices = Stream.of(NativeSettings.FULLSCREEN_SCALING_KEEP_ASPECT_RATIO, NativeSettings.FULLSCREEN_SCALING_STRETCH)
.map(fullScreenScaling -> new SelectionAdapter.ChoiceItem<>(t -> t.setText(fullscreenScalingModeToResourceNameId(fullScreenScaling)), fullScreenScaling))
.collect(Collectors.toList());
SelectionAdapter<Integer> fullscreenScalingSelectionAdapter = new SelectionAdapter<>(fullscreenScalingChoices, fullscreenScalingMode);
SingleSelectionRecyclerViewItem<Integer> fullscreenScalingSelection = new SingleSelectionRecyclerViewItem<>(getString(R.string.fullscreen_scaling),
getString(fullscreenScalingModeToResourceNameId(fullscreenScalingMode)), fullscreenScalingSelectionAdapter,
(fullscreenScaling, selectionRecyclerViewItem) -> {
NativeSettings.setFullscreenScaling(fullscreenScaling);
selectionRecyclerViewItem.setDescription(getString(fullscreenScalingModeToResourceNameId(fullscreenScaling)));
});
NativeSettings.getFullscreenScaling(),
List.of(NativeSettings.FULLSCREEN_SCALING_KEEP_ASPECT_RATIO, NativeSettings.FULLSCREEN_SCALING_STRETCH),
this::fullscreenScalingModeToString,
NativeSettings::setFullscreenScaling);
genericRecyclerViewAdapter.addRecyclerViewItem(fullscreenScalingSelection);
var scalingFilterChoices = Stream.of(
NativeSettings.SCALING_FILTER_BILINEAR_FILTER,
NativeSettings.SCALING_FILTER_BICUBIC_FILTER,
NativeSettings.SCALING_FILTER_BICUBIC_HERMITE_FILTER,
NativeSettings.SCALING_FILTER_NEAREST_NEIGHBOR_FILTER
).map(scalingFilter -> new SelectionAdapter.ChoiceItem<>(t -> t.setText(scalingFilterToResourceNameId(scalingFilter)), scalingFilter))
.collect(Collectors.toList());
var scalingFilterChoices = List.of(
NativeSettings.SCALING_FILTER_BILINEAR_FILTER,
NativeSettings.SCALING_FILTER_BICUBIC_FILTER,
NativeSettings.SCALING_FILTER_BICUBIC_HERMITE_FILTER,
NativeSettings.SCALING_FILTER_NEAREST_NEIGHBOR_FILTER
);
var upscaleFilterMode = NativeSettings.getUpscalingFilter();
SelectionAdapter<Integer> upscaleFilterSelectionAdapter = new SelectionAdapter<>(scalingFilterChoices, upscaleFilterMode);
SingleSelectionRecyclerViewItem<Integer> upscaleFilterSelection = new SingleSelectionRecyclerViewItem<>(getString(R.string.upscale_filter),
getString(scalingFilterToResourceNameId(upscaleFilterMode)), upscaleFilterSelectionAdapter,
(upscaleFilter, selectionRecyclerViewItem) -> {
NativeSettings.setUpscalingFilter(upscaleFilter);
selectionRecyclerViewItem.setDescription(getString(scalingFilterToResourceNameId(upscaleFilter)));
});
NativeSettings.getUpscalingFilter(),
scalingFilterChoices,
this::scalingFilterToString,
NativeSettings::setUpscalingFilter);
genericRecyclerViewAdapter.addRecyclerViewItem(upscaleFilterSelection);
var downscaleFilterMode = NativeSettings.getDownscalingFilter() ;
SelectionAdapter<Integer> downscaleFilterSelectionAdapter = new SelectionAdapter<>(scalingFilterChoices, downscaleFilterMode);
SingleSelectionRecyclerViewItem<Integer> downscaleFilterSelection = new SingleSelectionRecyclerViewItem<>(getString(R.string.downscale_filter),
getString(scalingFilterToResourceNameId(downscaleFilterMode)), downscaleFilterSelectionAdapter,
(downscaleFilter, selectionRecyclerViewItem) -> {
NativeSettings.setDownscalingFilter(downscaleFilter);
selectionRecyclerViewItem.setDescription(getString(scalingFilterToResourceNameId(downscaleFilter)));
});
NativeSettings.getDownscalingFilter(),
scalingFilterChoices,
this::scalingFilterToString,
NativeSettings::setDownscalingFilter);
genericRecyclerViewAdapter.addRecyclerViewItem(downscaleFilterSelection);
binding.recyclerView.setAdapter(genericRecyclerViewAdapter);
@@ -8,22 +8,20 @@ import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.List;
import info.cemu.Cemu.R;
import info.cemu.Cemu.databinding.LayoutGenericRecyclerViewBinding;
import info.cemu.Cemu.guibasecomponents.ToggleRecyclerViewItem;
import info.cemu.Cemu.guibasecomponents.GenericRecyclerViewAdapter;
import info.cemu.Cemu.guibasecomponents.HeaderRecyclerViewItem;
import info.cemu.Cemu.guibasecomponents.SelectionAdapter;
import info.cemu.Cemu.guibasecomponents.SingleSelectionRecyclerViewItem;
import info.cemu.Cemu.guibasecomponents.SliderRecyclerViewItem;
import info.cemu.Cemu.guibasecomponents.ToggleRecyclerViewItem;
import info.cemu.Cemu.nativeinterface.NativeSettings;
public class OverlaySettingsFragment extends Fragment {
private static int overlayScreenPositionToResourceNameId(int overlayScreenPosition) {
return switch (overlayScreenPosition) {
private String overlayScreenPositionToString(int overlayScreenPosition) {
int resourceId = switch (overlayScreenPosition) {
case NativeSettings.OVERLAY_SCREEN_POSITION_DISABLED ->
R.string.overlay_position_disabled;
case NativeSettings.OVERLAY_SCREEN_POSITION_TOP_LEFT ->
@@ -41,6 +39,7 @@ public class OverlaySettingsFragment extends Fragment {
default ->
throw new IllegalArgumentException("Invalid overlay position: " + overlayScreenPosition);
};
return getString(resourceId);
}
@Override
@@ -49,26 +48,20 @@ public class OverlaySettingsFragment extends Fragment {
GenericRecyclerViewAdapter genericRecyclerViewAdapter = new GenericRecyclerViewAdapter();
var overlayPositionChoices = Stream.of(
NativeSettings.OVERLAY_SCREEN_POSITION_DISABLED,
NativeSettings.OVERLAY_SCREEN_POSITION_TOP_LEFT,
NativeSettings.OVERLAY_SCREEN_POSITION_TOP_CENTER,
NativeSettings.OVERLAY_SCREEN_POSITION_TOP_RIGHT,
NativeSettings.OVERLAY_SCREEN_POSITION_BOTTOM_LEFT,
NativeSettings.OVERLAY_SCREEN_POSITION_BOTTOM_CENTER,
NativeSettings.OVERLAY_SCREEN_POSITION_BOTTOM_RIGHT)
.map(position -> new SelectionAdapter.ChoiceItem<>(t -> t.setText(overlayScreenPositionToResourceNameId(position)), position))
.collect(Collectors.toList());
int overlayPosition = NativeSettings.getOverlayPosition();
var overlayPositionChoices = List.of(
NativeSettings.OVERLAY_SCREEN_POSITION_DISABLED,
NativeSettings.OVERLAY_SCREEN_POSITION_TOP_LEFT,
NativeSettings.OVERLAY_SCREEN_POSITION_TOP_CENTER,
NativeSettings.OVERLAY_SCREEN_POSITION_TOP_RIGHT,
NativeSettings.OVERLAY_SCREEN_POSITION_BOTTOM_LEFT,
NativeSettings.OVERLAY_SCREEN_POSITION_BOTTOM_CENTER,
NativeSettings.OVERLAY_SCREEN_POSITION_BOTTOM_RIGHT);
genericRecyclerViewAdapter.addRecyclerViewItem(new HeaderRecyclerViewItem(R.string.overlay));
SelectionAdapter<Integer> overlayPositionSelectionAdapter = new SelectionAdapter<>(overlayPositionChoices, overlayPosition);
SingleSelectionRecyclerViewItem<Integer> overlayPositionSelection = new SingleSelectionRecyclerViewItem<>(getString(R.string.overlay_position),
getString(overlayScreenPositionToResourceNameId(overlayPosition)), overlayPositionSelectionAdapter,
(position, selectionRecyclerViewItem) -> {
NativeSettings.setOverlayPosition(position);
selectionRecyclerViewItem.setDescription(getString(overlayScreenPositionToResourceNameId(position)));
});
NativeSettings.getOverlayPosition(),
overlayPositionChoices,
this::overlayScreenPositionToString,
NativeSettings::setOverlayPosition);
genericRecyclerViewAdapter.addRecyclerViewItem(overlayPositionSelection);
SliderRecyclerViewItem overlayTextScale = new SliderRecyclerViewItem(getString(R.string.overlay_text_scale),
@@ -106,14 +99,12 @@ public class OverlaySettingsFragment extends Fragment {
genericRecyclerViewAdapter.addRecyclerViewItem(debugToggle);
genericRecyclerViewAdapter.addRecyclerViewItem(new HeaderRecyclerViewItem(R.string.notifications));
int notificationsPosition = NativeSettings.getNotificationsPosition();
SelectionAdapter<Integer> notificationsPositionSelectionAdapter = new SelectionAdapter<>(overlayPositionChoices, notificationsPosition);
SingleSelectionRecyclerViewItem<Integer> notificationsPositionSelection = new SingleSelectionRecyclerViewItem<>(getString(R.string.overlay_position),
getString(overlayScreenPositionToResourceNameId(notificationsPosition)), notificationsPositionSelectionAdapter,
(position, selectionRecyclerViewItem) -> {
NativeSettings.setNotificationsPosition(position);
selectionRecyclerViewItem.setDescription(getString(overlayScreenPositionToResourceNameId(position)));
});
NativeSettings.getNotificationsPosition(),
overlayPositionChoices,
this::overlayScreenPositionToString,
NativeSettings::setNotificationsPosition);
genericRecyclerViewAdapter.addRecyclerViewItem(notificationsPositionSelection);
SliderRecyclerViewItem notificationTextScale = new SliderRecyclerViewItem(getString(R.string.notifications_text_scale),