Merge pull request #11662 from t895/kotlin-settings
Android: Convert Settings to Kotlin
This commit is contained in:
commit
002a96adb0
|
@ -160,7 +160,7 @@ class CheatsActivity : AppCompatActivity(), PanelSlideListener {
|
|||
|
||||
fun loadGameSpecificSettings(): Settings {
|
||||
val settings = Settings()
|
||||
settings.loadSettings(gameId, revision, isWii)
|
||||
settings.loadSettings(gameId!!, revision, isWii)
|
||||
return settings
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ abstract class SettingDisabledWarningFragment(
|
|||
super.onResume()
|
||||
val activity = requireActivity() as CheatsActivity
|
||||
activity.loadGameSpecificSettings().use {
|
||||
val cheatsEnabled = setting.getBoolean()
|
||||
val cheatsEnabled = setting.boolean
|
||||
requireView().visibility = if (cheatsEnabled) View.GONE else View.VISIBLE
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,8 +46,8 @@ public class InputDeviceSetting extends StringSingleChoiceSetting
|
|||
{
|
||||
String[] devices = ControllerInterface.getAllDeviceStrings();
|
||||
|
||||
mChoices = devices;
|
||||
mValues = devices;
|
||||
setChoices(devices);
|
||||
setValues(devices);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
package org.dolphinemu.dolphinemu.features.input.ui
|
||||
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
|
@ -14,6 +13,7 @@ import com.google.android.material.divider.MaterialDividerItemDecoration
|
|||
import org.dolphinemu.dolphinemu.R
|
||||
import org.dolphinemu.dolphinemu.databinding.DialogInputProfilesBinding
|
||||
import org.dolphinemu.dolphinemu.features.settings.ui.MenuTag
|
||||
import org.dolphinemu.dolphinemu.utils.SerializableHelper.serializable
|
||||
|
||||
class ProfileDialog : BottomSheetDialogFragment() {
|
||||
private var presenter: ProfileDialogPresenter? = null
|
||||
|
@ -22,11 +22,7 @@ class ProfileDialog : BottomSheetDialogFragment() {
|
|||
private val binding get() = _binding!!
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
val menuTag: MenuTag = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
requireArguments().getSerializable(KEY_MENU_TAG, MenuTag::class.java) as MenuTag
|
||||
} else {
|
||||
requireArguments().getSerializable(KEY_MENU_TAG) as MenuTag
|
||||
}
|
||||
val menuTag = requireArguments().serializable<MenuTag>(KEY_MENU_TAG)
|
||||
|
||||
presenter = ProfileDialogPresenter(this, menuTag)
|
||||
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
public interface AbstractBooleanSetting extends AbstractSetting
|
||||
{
|
||||
boolean getBoolean();
|
||||
|
||||
void setBoolean(@NonNull Settings settings, boolean newValue);
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model
|
||||
|
||||
interface AbstractBooleanSetting : AbstractSetting {
|
||||
val boolean: Boolean
|
||||
|
||||
fun setBoolean(settings: Settings, newValue: Boolean)
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
public interface AbstractFloatSetting extends AbstractSetting
|
||||
{
|
||||
float getFloat();
|
||||
|
||||
void setFloat(@NonNull Settings settings, float newValue);
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model
|
||||
|
||||
interface AbstractFloatSetting : AbstractSetting {
|
||||
val float: Float
|
||||
|
||||
fun setFloat(settings: Settings, newValue: Float)
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
public interface AbstractIntSetting extends AbstractSetting
|
||||
{
|
||||
int getInt();
|
||||
|
||||
void setInt(@NonNull Settings settings, int newValue);
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model
|
||||
|
||||
interface AbstractIntSetting : AbstractSetting {
|
||||
val int: Int
|
||||
|
||||
fun setInt(settings: Settings, newValue: Int)
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
public interface AbstractSetting
|
||||
{
|
||||
boolean isOverridden();
|
||||
|
||||
boolean isRuntimeEditable();
|
||||
|
||||
boolean delete(@NonNull Settings settings);
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model
|
||||
|
||||
interface AbstractSetting {
|
||||
val isOverridden: Boolean
|
||||
val isRuntimeEditable: Boolean
|
||||
|
||||
fun delete(settings: Settings): Boolean
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
public interface AbstractStringSetting extends AbstractSetting
|
||||
{
|
||||
@NonNull
|
||||
String getString();
|
||||
|
||||
void setString(@NonNull Settings settings, @NonNull String newValue);
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model
|
||||
|
||||
interface AbstractStringSetting : AbstractSetting {
|
||||
val string: String
|
||||
|
||||
fun setString(settings: Settings, newValue: String)
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
public class AdHocBooleanSetting implements AbstractBooleanSetting
|
||||
{
|
||||
private final String mFile;
|
||||
private final String mSection;
|
||||
private final String mKey;
|
||||
private final boolean mDefaultValue;
|
||||
|
||||
public AdHocBooleanSetting(String file, String section, String key, boolean defaultValue)
|
||||
{
|
||||
mFile = file;
|
||||
mSection = section;
|
||||
mKey = key;
|
||||
mDefaultValue = defaultValue;
|
||||
|
||||
if (!NativeConfig.isSettingSaveable(file, section, key))
|
||||
{
|
||||
throw new IllegalArgumentException("File/section/key is unknown or legacy");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverridden()
|
||||
{
|
||||
return NativeConfig.isOverridden(mFile, mSection, mKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRuntimeEditable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean delete(@NonNull Settings settings)
|
||||
{
|
||||
return NativeConfig.deleteKey(settings.getWriteLayer(), mFile, mSection, mKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getBoolean()
|
||||
{
|
||||
return NativeConfig.getBoolean(NativeConfig.LAYER_ACTIVE, mFile, mSection, mKey, mDefaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBoolean(@NonNull Settings settings, boolean newValue)
|
||||
{
|
||||
NativeConfig.setBoolean(settings.getWriteLayer(), mFile, mSection, mKey, newValue);
|
||||
}
|
||||
|
||||
public static boolean getBooleanGlobal(String file, String section, String key,
|
||||
boolean defaultValue)
|
||||
{
|
||||
return NativeConfig.getBoolean(NativeConfig.LAYER_ACTIVE, file, section, key, defaultValue);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model
|
||||
|
||||
class AdHocBooleanSetting(
|
||||
private val file: String,
|
||||
private val section: String,
|
||||
private val key: String,
|
||||
private val defaultValue: Boolean
|
||||
) : AbstractBooleanSetting {
|
||||
init {
|
||||
require(
|
||||
NativeConfig.isSettingSaveable(
|
||||
file,
|
||||
section,
|
||||
key
|
||||
)
|
||||
) { "File/section/key is unknown or legacy" }
|
||||
}
|
||||
|
||||
override val isOverridden: Boolean
|
||||
get() = NativeConfig.isOverridden(file, section, key)
|
||||
|
||||
override val isRuntimeEditable: Boolean = true
|
||||
|
||||
override fun delete(settings: Settings): Boolean {
|
||||
return NativeConfig.deleteKey(settings.writeLayer, file, section, key)
|
||||
}
|
||||
|
||||
override val boolean: Boolean
|
||||
get() = NativeConfig.getBoolean(NativeConfig.LAYER_ACTIVE, file, section, key, defaultValue)
|
||||
|
||||
override fun setBoolean(settings: Settings, newValue: Boolean) {
|
||||
NativeConfig.setBoolean(settings.writeLayer, file, section, key, newValue)
|
||||
}
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
public class AdHocStringSetting implements AbstractStringSetting
|
||||
{
|
||||
private final String mFile;
|
||||
private final String mSection;
|
||||
private final String mKey;
|
||||
private final String mDefaultValue;
|
||||
|
||||
public AdHocStringSetting(String file, String section, String key, String defaultValue)
|
||||
{
|
||||
mFile = file;
|
||||
mSection = section;
|
||||
mKey = key;
|
||||
mDefaultValue = defaultValue;
|
||||
|
||||
if (!NativeConfig.isSettingSaveable(file, section, key))
|
||||
{
|
||||
throw new IllegalArgumentException("File/section/key is unknown or legacy");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverridden()
|
||||
{
|
||||
return NativeConfig.isOverridden(mFile, mSection, mKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRuntimeEditable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean delete(@NonNull Settings settings)
|
||||
{
|
||||
return NativeConfig.deleteKey(settings.getWriteLayer(), mFile, mSection, mKey);
|
||||
}
|
||||
|
||||
@NonNull @Override
|
||||
public String getString()
|
||||
{
|
||||
return NativeConfig.getString(NativeConfig.LAYER_ACTIVE, mFile, mSection, mKey, mDefaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setString(@NonNull Settings settings, @NonNull String newValue)
|
||||
{
|
||||
NativeConfig.setString(settings.getWriteLayer(), mFile, mSection, mKey, newValue);
|
||||
}
|
||||
|
||||
public static String getStringGlobal(String file, String section, String key, String defaultValue)
|
||||
{
|
||||
return NativeConfig.getString(NativeConfig.LAYER_ACTIVE, file, section, key, defaultValue);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model
|
||||
|
||||
class AdHocStringSetting(
|
||||
private val file: String,
|
||||
private val section: String,
|
||||
private val key: String,
|
||||
private val defaultValue: String
|
||||
) : AbstractStringSetting {
|
||||
init {
|
||||
require(
|
||||
NativeConfig.isSettingSaveable(
|
||||
file,
|
||||
section,
|
||||
key
|
||||
)
|
||||
) { "File/section/key is unknown or legacy" }
|
||||
}
|
||||
|
||||
override val isOverridden: Boolean
|
||||
get() = NativeConfig.isOverridden(file, section, key)
|
||||
|
||||
override val isRuntimeEditable: Boolean = true
|
||||
|
||||
override fun delete(settings: Settings): Boolean {
|
||||
return NativeConfig.deleteKey(settings.writeLayer, file, section, key)
|
||||
}
|
||||
|
||||
override val string: String
|
||||
get() = NativeConfig.getString(NativeConfig.LAYER_ACTIVE, file, section, key, defaultValue)
|
||||
|
||||
override fun setString(settings: Settings, newValue: String) {
|
||||
NativeConfig.setString(settings.writeLayer, file, section, key, newValue)
|
||||
}
|
||||
}
|
|
@ -1,371 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public enum BooleanSetting implements AbstractBooleanSetting
|
||||
{
|
||||
// These entries have the same names and order as in C++, just for consistency.
|
||||
|
||||
MAIN_SKIP_IPL(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "SkipIPL", true),
|
||||
MAIN_DSP_HLE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "DSPHLE", true),
|
||||
MAIN_FASTMEM(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "Fastmem", true),
|
||||
MAIN_CPU_THREAD(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "CPUThread", true),
|
||||
MAIN_SYNC_ON_SKIP_IDLE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "SyncOnSkipIdle", true),
|
||||
MAIN_ENABLE_CHEATS(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "EnableCheats", false),
|
||||
MAIN_OVERRIDE_REGION_SETTINGS(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE,
|
||||
"OverrideRegionSettings", false),
|
||||
MAIN_AUDIO_STRETCH(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "AudioStretch", false),
|
||||
MAIN_BBA_XLINK_CHAT_OSD(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "BBA_XLINK_CHAT_OSD",
|
||||
false),
|
||||
MAIN_ADAPTER_RUMBLE_0(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "AdapterRumble0", true),
|
||||
MAIN_ADAPTER_RUMBLE_1(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "AdapterRumble1", true),
|
||||
MAIN_ADAPTER_RUMBLE_2(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "AdapterRumble2", true),
|
||||
MAIN_ADAPTER_RUMBLE_3(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "AdapterRumble3", true),
|
||||
MAIN_SIMULATE_KONGA_0(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "SimulateKonga0", false),
|
||||
MAIN_SIMULATE_KONGA_1(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "SimulateKonga1", false),
|
||||
MAIN_SIMULATE_KONGA_2(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "SimulateKonga2", false),
|
||||
MAIN_SIMULATE_KONGA_3(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "SimulateKonga3", false),
|
||||
MAIN_WII_SD_CARD(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "WiiSDCard", true),
|
||||
MAIN_WII_SD_CARD_ENABLE_FOLDER_SYNC(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE,
|
||||
"WiiSDCardEnableFolderSync", false),
|
||||
MAIN_WIIMOTE_CONTINUOUS_SCANNING(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE,
|
||||
"WiimoteContinuousScanning", false),
|
||||
MAIN_WIIMOTE_ENABLE_SPEAKER(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE,
|
||||
"WiimoteEnableSpeaker", false),
|
||||
MAIN_MMU(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "MMU", false),
|
||||
MAIN_PAUSE_ON_PANIC(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "PauseOnPanic", false),
|
||||
MAIN_ACCURATE_CPU_CACHE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "AccurateCPUCache",
|
||||
false),
|
||||
MAIN_SYNC_GPU(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "SyncGPU", false),
|
||||
MAIN_FAST_DISC_SPEED(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "FastDiscSpeed",
|
||||
false),
|
||||
MAIN_OVERCLOCK_ENABLE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "OverclockEnable", false),
|
||||
MAIN_RAM_OVERRIDE_ENABLE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "RAMOverrideEnable",
|
||||
false),
|
||||
MAIN_CUSTOM_RTC_ENABLE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "EnableCustomRTC",
|
||||
false),
|
||||
MAIN_AUTO_DISC_CHANGE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "AutoDiscChange", false),
|
||||
MAIN_ALLOW_SD_WRITES(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "WiiSDCardAllowWrites",
|
||||
true),
|
||||
MAIN_ENABLE_SAVESTATES(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "EnableSaveStates",
|
||||
false),
|
||||
|
||||
MAIN_DSP_JIT(Settings.FILE_DOLPHIN, Settings.SECTION_INI_DSP, "EnableJIT", true),
|
||||
|
||||
MAIN_EXPAND_TO_CUTOUT_AREA(Settings.FILE_DOLPHIN, Settings.SECTION_INI_INTERFACE,
|
||||
"ExpandToCutoutArea", false),
|
||||
MAIN_USE_PANIC_HANDLERS(Settings.FILE_DOLPHIN, Settings.SECTION_INI_INTERFACE,
|
||||
"UsePanicHandlers", true),
|
||||
MAIN_OSD_MESSAGES(Settings.FILE_DOLPHIN, Settings.SECTION_INI_INTERFACE,
|
||||
"OnScreenDisplayMessages", true),
|
||||
|
||||
MAIN_ANALYTICS_ENABLED(Settings.FILE_DOLPHIN, Settings.SECTION_ANALYTICS, "Enabled", false),
|
||||
MAIN_ANALYTICS_PERMISSION_ASKED(Settings.FILE_DOLPHIN, Settings.SECTION_ANALYTICS,
|
||||
"PermissionAsked", false),
|
||||
|
||||
MAIN_RECURSIVE_ISO_PATHS(Settings.FILE_DOLPHIN, Settings.SECTION_INI_GENERAL,
|
||||
"RecursiveISOPaths", false),
|
||||
MAIN_USE_GAME_COVERS(Settings.FILE_DOLPHIN, Settings.SECTION_INI_GENERAL,
|
||||
"UseGameCovers", true),
|
||||
|
||||
MAIN_DEBUG_JIT_OFF(Settings.FILE_DOLPHIN, Settings.SECTION_DEBUG, "JitOff", false),
|
||||
MAIN_DEBUG_JIT_LOAD_STORE_OFF(Settings.FILE_DOLPHIN, Settings.SECTION_DEBUG, "JitLoadStoreOff",
|
||||
false),
|
||||
MAIN_DEBUG_JIT_LOAD_STORE_FLOATING_OFF(Settings.FILE_DOLPHIN, Settings.SECTION_DEBUG,
|
||||
"JitLoadStoreFloatingOff", false),
|
||||
MAIN_DEBUG_JIT_LOAD_STORE_PAIRED_OFF(Settings.FILE_DOLPHIN, Settings.SECTION_DEBUG,
|
||||
"JitLoadStorePairedOff", false),
|
||||
MAIN_DEBUG_JIT_FLOATING_POINT_OFF(Settings.FILE_DOLPHIN, Settings.SECTION_DEBUG,
|
||||
"JitFloatingPointOff", false),
|
||||
MAIN_DEBUG_JIT_INTEGER_OFF(Settings.FILE_DOLPHIN, Settings.SECTION_DEBUG, "JitIntegerOff", false),
|
||||
MAIN_DEBUG_JIT_PAIRED_OFF(Settings.FILE_DOLPHIN, Settings.SECTION_DEBUG, "JitPairedOff", false),
|
||||
MAIN_DEBUG_JIT_SYSTEM_REGISTERS_OFF(Settings.FILE_DOLPHIN, Settings.SECTION_DEBUG,
|
||||
"JitSystemRegistersOff", false),
|
||||
MAIN_DEBUG_JIT_BRANCH_OFF(Settings.FILE_DOLPHIN, Settings.SECTION_DEBUG, "JitBranchOff", false),
|
||||
MAIN_DEBUG_JIT_REGISTER_CACHE_OFF(Settings.FILE_DOLPHIN, Settings.SECTION_DEBUG,
|
||||
"JitRegisterCacheOff", false),
|
||||
|
||||
MAIN_EMULATE_SKYLANDER_PORTAL(Settings.FILE_DOLPHIN, Settings.SECTION_EMULATED_USB_DEVICES,
|
||||
"EmulateSkylanderPortal", false),
|
||||
|
||||
MAIN_SHOW_GAME_TITLES(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID,
|
||||
"ShowGameTitles", true),
|
||||
MAIN_USE_BLACK_BACKGROUNDS(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID,
|
||||
"UseBlackBackgrounds", false),
|
||||
MAIN_JOYSTICK_REL_CENTER(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID,
|
||||
"JoystickRelCenter", true),
|
||||
MAIN_SHOW_INPUT_OVERLAY(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID,
|
||||
"ShowInputOverlay", true),
|
||||
MAIN_IR_ALWAYS_RECENTER(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID,
|
||||
"IRAlwaysRecenter", false),
|
||||
|
||||
MAIN_BUTTON_TOGGLE_GC_0(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleGCButtonA", true),
|
||||
MAIN_BUTTON_TOGGLE_GC_1(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleGCButtonB", true),
|
||||
MAIN_BUTTON_TOGGLE_GC_2(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleGCButtonX", true),
|
||||
MAIN_BUTTON_TOGGLE_GC_3(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleGCButtonY", true),
|
||||
MAIN_BUTTON_TOGGLE_GC_4(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleGCButtonZ", true),
|
||||
MAIN_BUTTON_TOGGLE_GC_5(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleGCButtonStart", true),
|
||||
MAIN_BUTTON_TOGGLE_GC_6(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleGCTriggerL", true),
|
||||
MAIN_BUTTON_TOGGLE_GC_7(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleGCTriggerR", true),
|
||||
MAIN_BUTTON_TOGGLE_GC_8(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleGCDPad", true),
|
||||
MAIN_BUTTON_TOGGLE_GC_9(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleGCStickMain", true),
|
||||
MAIN_BUTTON_TOGGLE_GC_10(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleGCStickC", true),
|
||||
MAIN_BUTTON_TOGGLE_CLASSIC_0(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleClassicButtonA", true),
|
||||
MAIN_BUTTON_TOGGLE_CLASSIC_1(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleClassicButtonB", true),
|
||||
MAIN_BUTTON_TOGGLE_CLASSIC_2(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleClassicButtonX", true),
|
||||
MAIN_BUTTON_TOGGLE_CLASSIC_3(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleClassicButtonY", true),
|
||||
MAIN_BUTTON_TOGGLE_CLASSIC_4(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleClassicButtonPlus", true),
|
||||
MAIN_BUTTON_TOGGLE_CLASSIC_5(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleClassicButtonMinus", true),
|
||||
MAIN_BUTTON_TOGGLE_CLASSIC_6(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleClassicButtonHome", true),
|
||||
MAIN_BUTTON_TOGGLE_CLASSIC_7(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleClassicTriggerL", true),
|
||||
MAIN_BUTTON_TOGGLE_CLASSIC_8(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleClassicTriggerR", true),
|
||||
MAIN_BUTTON_TOGGLE_CLASSIC_9(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleClassicButtonZL", true),
|
||||
MAIN_BUTTON_TOGGLE_CLASSIC_10(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleClassicButtonZR", true),
|
||||
MAIN_BUTTON_TOGGLE_CLASSIC_11(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleClassicDPad", true),
|
||||
MAIN_BUTTON_TOGGLE_CLASSIC_12(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleClassicStickLeft", true),
|
||||
MAIN_BUTTON_TOGGLE_CLASSIC_13(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleClassicStickRight", true),
|
||||
MAIN_BUTTON_TOGGLE_WII_0(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleWiimoteButtonA", true),
|
||||
MAIN_BUTTON_TOGGLE_WII_1(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleWiimoteButtonB", true),
|
||||
MAIN_BUTTON_TOGGLE_WII_2(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleWiimoteButton1", true),
|
||||
MAIN_BUTTON_TOGGLE_WII_3(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleWiimoteButton2", true),
|
||||
MAIN_BUTTON_TOGGLE_WII_4(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleWiimoteButtonPlus", true),
|
||||
MAIN_BUTTON_TOGGLE_WII_5(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleWiimoteButtonMinus", true),
|
||||
MAIN_BUTTON_TOGGLE_WII_6(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleWiimoteButtonHome", true),
|
||||
MAIN_BUTTON_TOGGLE_WII_7(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleWiimoteDPad", true),
|
||||
MAIN_BUTTON_TOGGLE_WII_8(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleNunchukC", true),
|
||||
MAIN_BUTTON_TOGGLE_WII_9(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleNunchukZ", true),
|
||||
MAIN_BUTTON_TOGGLE_WII_10(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleNunchukStick", true),
|
||||
|
||||
SYSCONF_SCREENSAVER(Settings.FILE_SYSCONF, "IPL", "SSV", false),
|
||||
SYSCONF_WIDESCREEN(Settings.FILE_SYSCONF, "IPL", "AR", true),
|
||||
SYSCONF_PROGRESSIVE_SCAN(Settings.FILE_SYSCONF, "IPL", "PGS", true),
|
||||
SYSCONF_PAL60(Settings.FILE_SYSCONF, "IPL", "E60", true),
|
||||
|
||||
SYSCONF_WIIMOTE_MOTOR(Settings.FILE_SYSCONF, "BT", "MOT", true),
|
||||
|
||||
GFX_WIDESCREEN_HACK(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "wideScreenHack", false),
|
||||
GFX_CROP(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "Crop", false),
|
||||
GFX_SHOW_FPS(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "ShowFPS", false),
|
||||
GFX_SHOW_FTIMES(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "ShowFTimes", false),
|
||||
GFX_SHOW_VPS(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "ShowVPS", false),
|
||||
GFX_SHOW_VTIMES(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "ShowVTimes", false),
|
||||
GFX_SHOW_GRAPHS(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "ShowGraphs", false),
|
||||
GFX_SHOW_SPEED(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "ShowSpeed", false),
|
||||
GFX_SHOW_SPEED_COLORS(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "ShowSpeedColors", true),
|
||||
GFX_LOG_RENDER_TIME_TO_FILE(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS,
|
||||
"LogRenderTimeToFile", false),
|
||||
GFX_OVERLAY_STATS(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "OverlayStats", false),
|
||||
GFX_DUMP_TEXTURES(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "DumpTextures", false),
|
||||
GFX_DUMP_MIP_TEXTURES(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "DumpMipTextures", false),
|
||||
GFX_DUMP_BASE_TEXTURES(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "DumpBaseTextures",
|
||||
false),
|
||||
GFX_HIRES_TEXTURES(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "HiresTextures", false),
|
||||
GFX_CACHE_HIRES_TEXTURES(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "CacheHiresTextures",
|
||||
false),
|
||||
GFX_DUMP_EFB_TARGET(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "DumpEFBTarget", false),
|
||||
GFX_DUMP_XFB_TARGET(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "DumpXFBTarget", false),
|
||||
GFX_INTERNAL_RESOLUTION_FRAME_DUMPS(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS,
|
||||
"InternalResolutionFrameDumps", false),
|
||||
GFX_ENABLE_GPU_TEXTURE_DECODING(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS,
|
||||
"EnableGPUTextureDecoding", false),
|
||||
GFX_ENABLE_PIXEL_LIGHTING(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS,
|
||||
"EnablePixelLighting", false),
|
||||
GFX_FAST_DEPTH_CALC(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "FastDepthCalc", true),
|
||||
GFX_TEXFMT_OVERLAY_ENABLE(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "TexFmtOverlayEnable",
|
||||
false),
|
||||
GFX_ENABLE_WIREFRAME(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "WireFrame", false),
|
||||
GFX_DISABLE_FOG(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "DisableFog", false),
|
||||
GFX_ENABLE_VALIDATION_LAYER(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS,
|
||||
"EnableValidationLayer", false),
|
||||
GFX_BACKEND_MULTITHREADING(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS,
|
||||
"BackendMultithreading", true),
|
||||
GFX_WAIT_FOR_SHADERS_BEFORE_STARTING(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS,
|
||||
"WaitForShadersBeforeStarting", false),
|
||||
GFX_SAVE_TEXTURE_CACHE_TO_STATE(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS,
|
||||
"SaveTextureCacheToState", true),
|
||||
GFX_PREFER_VS_FOR_LINE_POINT_EXPANSION(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS,
|
||||
"PreferVSForLinePointExpansion", false),
|
||||
GFX_CPU_CULL(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "CPUCull", false),
|
||||
GFX_MODS_ENABLE(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "EnableMods", false),
|
||||
|
||||
GFX_ENHANCE_FORCE_TRUE_COLOR(Settings.FILE_GFX, Settings.SECTION_GFX_ENHANCEMENTS,
|
||||
"ForceTrueColor", true),
|
||||
GFX_ENHANCE_DISABLE_COPY_FILTER(Settings.FILE_GFX, Settings.SECTION_GFX_ENHANCEMENTS,
|
||||
"DisableCopyFilter", true),
|
||||
GFX_ENHANCE_ARBITRARY_MIPMAP_DETECTION(Settings.FILE_GFX, Settings.SECTION_GFX_ENHANCEMENTS,
|
||||
"ArbitraryMipmapDetection", true),
|
||||
|
||||
GFX_STEREO_SWAP_EYES(Settings.FILE_GFX, Settings.SECTION_STEREOSCOPY, "StereoSwapEyes", false),
|
||||
|
||||
GFX_HACK_EFB_ACCESS_ENABLE(Settings.FILE_GFX, Settings.SECTION_GFX_HACKS, "EFBAccessEnable",
|
||||
true),
|
||||
GFX_HACK_EFB_DEFER_INVALIDATION(Settings.FILE_GFX, Settings.SECTION_GFX_HACKS,
|
||||
"EFBAccessDeferInvalidation", false),
|
||||
GFX_HACK_BBOX_ENABLE(Settings.FILE_GFX, Settings.SECTION_GFX_HACKS, "BBoxEnable", false),
|
||||
GFX_HACK_SKIP_EFB_COPY_TO_RAM(Settings.FILE_GFX, Settings.SECTION_GFX_HACKS,
|
||||
"EFBToTextureEnable", true),
|
||||
GFX_HACK_SKIP_XFB_COPY_TO_RAM(Settings.FILE_GFX, Settings.SECTION_GFX_HACKS,
|
||||
"XFBToTextureEnable", true),
|
||||
GFX_HACK_DISABLE_COPY_TO_VRAM(Settings.FILE_GFX, Settings.SECTION_GFX_HACKS, "DisableCopyToVRAM",
|
||||
false),
|
||||
GFX_HACK_DEFER_EFB_COPIES(Settings.FILE_GFX, Settings.SECTION_GFX_HACKS, "DeferEFBCopies", true),
|
||||
GFX_HACK_IMMEDIATE_XFB(Settings.FILE_GFX, Settings.SECTION_GFX_HACKS, "ImmediateXFBEnable",
|
||||
false),
|
||||
GFX_HACK_SKIP_DUPLICATE_XFBS(Settings.FILE_GFX, Settings.SECTION_GFX_HACKS, "SkipDuplicateXFBs",
|
||||
true),
|
||||
GFX_HACK_COPY_EFB_SCALED(Settings.FILE_GFX, Settings.SECTION_GFX_HACKS, "EFBScaledCopy", true),
|
||||
GFX_HACK_EFB_EMULATE_FORMAT_CHANGES(Settings.FILE_GFX, Settings.SECTION_GFX_HACKS,
|
||||
"EFBEmulateFormatChanges", false),
|
||||
GFX_HACK_VERTEX_ROUNDING(Settings.FILE_GFX, Settings.SECTION_GFX_HACKS, "VertexRounding", false),
|
||||
GFX_HACK_VI_SKIP(Settings.FILE_GFX, Settings.SECTION_GFX_HACKS, "VISkip", false),
|
||||
GFX_HACK_FAST_TEXTURE_SAMPLING(Settings.FILE_GFX, Settings.SECTION_GFX_HACKS,
|
||||
"FastTextureSampling", true),
|
||||
|
||||
LOGGER_WRITE_TO_FILE(Settings.FILE_LOGGER, Settings.SECTION_LOGGER_OPTIONS, "WriteToFile", false);
|
||||
|
||||
private static final BooleanSetting[] NOT_RUNTIME_EDITABLE_ARRAY = new BooleanSetting[]{
|
||||
MAIN_DSP_HLE,
|
||||
MAIN_CPU_THREAD,
|
||||
MAIN_ENABLE_CHEATS,
|
||||
MAIN_OVERRIDE_REGION_SETTINGS,
|
||||
MAIN_MMU,
|
||||
MAIN_PAUSE_ON_PANIC,
|
||||
MAIN_ACCURATE_CPU_CACHE,
|
||||
MAIN_RAM_OVERRIDE_ENABLE,
|
||||
MAIN_CUSTOM_RTC_ENABLE,
|
||||
MAIN_DSP_JIT,
|
||||
MAIN_EMULATE_SKYLANDER_PORTAL,
|
||||
};
|
||||
|
||||
private static final Set<BooleanSetting> NOT_RUNTIME_EDITABLE =
|
||||
new HashSet<>(Arrays.asList(NOT_RUNTIME_EDITABLE_ARRAY));
|
||||
|
||||
private final String mFile;
|
||||
private final String mSection;
|
||||
private final String mKey;
|
||||
private final boolean mDefaultValue;
|
||||
|
||||
BooleanSetting(String file, String section, String key, boolean defaultValue)
|
||||
{
|
||||
mFile = file;
|
||||
mSection = section;
|
||||
mKey = key;
|
||||
mDefaultValue = defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverridden()
|
||||
{
|
||||
return NativeConfig.isOverridden(mFile, mSection, mKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRuntimeEditable()
|
||||
{
|
||||
if (mFile.equals(Settings.FILE_SYSCONF))
|
||||
return false;
|
||||
|
||||
for (BooleanSetting setting : NOT_RUNTIME_EDITABLE)
|
||||
{
|
||||
if (setting == this)
|
||||
return false;
|
||||
}
|
||||
|
||||
return NativeConfig.isSettingSaveable(mFile, mSection, mKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean delete(@NonNull Settings settings)
|
||||
{
|
||||
if (!NativeConfig.isSettingSaveable(mFile, mSection, mKey))
|
||||
{
|
||||
throw new UnsupportedOperationException(
|
||||
"Unsupported setting: " + mFile + ", " + mSection + ", " + mKey);
|
||||
}
|
||||
|
||||
return NativeConfig.deleteKey(settings.getWriteLayer(), mFile, mSection, mKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getBoolean()
|
||||
{
|
||||
return NativeConfig.getBoolean(NativeConfig.LAYER_ACTIVE, mFile, mSection, mKey, mDefaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBoolean(@NonNull Settings settings, boolean newValue)
|
||||
{
|
||||
if (!NativeConfig.isSettingSaveable(mFile, mSection, mKey))
|
||||
{
|
||||
throw new UnsupportedOperationException(
|
||||
"Unsupported setting: " + mFile + ", " + mSection + ", " + mKey);
|
||||
}
|
||||
|
||||
NativeConfig.setBoolean(settings.getWriteLayer(), mFile, mSection, mKey, newValue);
|
||||
}
|
||||
|
||||
public void setBoolean(int layer, boolean newValue)
|
||||
{
|
||||
if (!NativeConfig.isSettingSaveable(mFile, mSection, mKey))
|
||||
{
|
||||
throw new UnsupportedOperationException(
|
||||
"Unsupported setting: " + mFile + ", " + mSection + ", " + mKey);
|
||||
}
|
||||
|
||||
NativeConfig.setBoolean(layer, mFile, mSection, mKey, newValue);
|
||||
}
|
||||
|
||||
public static BooleanSetting getSettingForAdapterRumble(int channel)
|
||||
{
|
||||
return new BooleanSetting[]{MAIN_ADAPTER_RUMBLE_0, MAIN_ADAPTER_RUMBLE_1, MAIN_ADAPTER_RUMBLE_2,
|
||||
MAIN_ADAPTER_RUMBLE_3}[channel];
|
||||
}
|
||||
|
||||
public static BooleanSetting getSettingForSimulateKonga(int channel)
|
||||
{
|
||||
return new BooleanSetting[]{MAIN_SIMULATE_KONGA_0, MAIN_SIMULATE_KONGA_1, MAIN_SIMULATE_KONGA_2,
|
||||
MAIN_SIMULATE_KONGA_3}[channel];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,747 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model
|
||||
|
||||
import java.util.*
|
||||
|
||||
enum class BooleanSetting(
|
||||
private val file: String,
|
||||
private val section: String,
|
||||
private val key: String,
|
||||
private val defaultValue: Boolean
|
||||
) : AbstractBooleanSetting {
|
||||
// These entries have the same names and order as in C++, just for consistency.
|
||||
MAIN_SKIP_IPL(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "SkipIPL", true),
|
||||
MAIN_DSP_HLE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "DSPHLE", true),
|
||||
MAIN_FASTMEM(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "Fastmem", true),
|
||||
MAIN_CPU_THREAD(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "CPUThread", true),
|
||||
MAIN_SYNC_ON_SKIP_IDLE(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_CORE,
|
||||
"SyncOnSkipIdle",
|
||||
true
|
||||
),
|
||||
MAIN_ENABLE_CHEATS(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "EnableCheats", false),
|
||||
MAIN_OVERRIDE_REGION_SETTINGS(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_CORE,
|
||||
"OverrideRegionSettings",
|
||||
false
|
||||
),
|
||||
MAIN_AUDIO_STRETCH(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "AudioStretch", false),
|
||||
MAIN_BBA_XLINK_CHAT_OSD(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_CORE,
|
||||
"BBA_XLINK_CHAT_OSD",
|
||||
false
|
||||
),
|
||||
MAIN_ADAPTER_RUMBLE_0(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "AdapterRumble0", true),
|
||||
MAIN_ADAPTER_RUMBLE_1(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "AdapterRumble1", true),
|
||||
MAIN_ADAPTER_RUMBLE_2(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "AdapterRumble2", true),
|
||||
MAIN_ADAPTER_RUMBLE_3(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "AdapterRumble3", true),
|
||||
MAIN_SIMULATE_KONGA_0(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_CORE,
|
||||
"SimulateKonga0",
|
||||
false
|
||||
),
|
||||
MAIN_SIMULATE_KONGA_1(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_CORE,
|
||||
"SimulateKonga1",
|
||||
false
|
||||
),
|
||||
MAIN_SIMULATE_KONGA_2(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_CORE,
|
||||
"SimulateKonga2",
|
||||
false
|
||||
),
|
||||
MAIN_SIMULATE_KONGA_3(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_CORE,
|
||||
"SimulateKonga3",
|
||||
false
|
||||
),
|
||||
MAIN_WII_SD_CARD(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "WiiSDCard", true),
|
||||
MAIN_WII_SD_CARD_ENABLE_FOLDER_SYNC(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_CORE,
|
||||
"WiiSDCardEnableFolderSync",
|
||||
false
|
||||
),
|
||||
MAIN_WIIMOTE_CONTINUOUS_SCANNING(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_CORE,
|
||||
"WiimoteContinuousScanning",
|
||||
false
|
||||
),
|
||||
MAIN_WIIMOTE_ENABLE_SPEAKER(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_CORE,
|
||||
"WiimoteEnableSpeaker",
|
||||
false
|
||||
),
|
||||
MAIN_MMU(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "MMU", false),
|
||||
MAIN_PAUSE_ON_PANIC(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "PauseOnPanic", false),
|
||||
MAIN_ACCURATE_CPU_CACHE(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_CORE,
|
||||
"AccurateCPUCache",
|
||||
false
|
||||
),
|
||||
MAIN_SYNC_GPU(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "SyncGPU", false),
|
||||
MAIN_FAST_DISC_SPEED(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "FastDiscSpeed", false),
|
||||
MAIN_OVERCLOCK_ENABLE(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_CORE,
|
||||
"OverclockEnable",
|
||||
false
|
||||
),
|
||||
MAIN_RAM_OVERRIDE_ENABLE(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_CORE,
|
||||
"RAMOverrideEnable",
|
||||
false
|
||||
),
|
||||
MAIN_CUSTOM_RTC_ENABLE(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_CORE,
|
||||
"EnableCustomRTC",
|
||||
false
|
||||
),
|
||||
MAIN_AUTO_DISC_CHANGE(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_CORE,
|
||||
"AutoDiscChange",
|
||||
false
|
||||
),
|
||||
MAIN_ALLOW_SD_WRITES(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_CORE,
|
||||
"WiiSDCardAllowWrites",
|
||||
true
|
||||
),
|
||||
MAIN_ENABLE_SAVESTATES(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_CORE,
|
||||
"EnableSaveStates",
|
||||
false
|
||||
),
|
||||
MAIN_DSP_JIT(Settings.FILE_DOLPHIN, Settings.SECTION_INI_DSP, "EnableJIT", true),
|
||||
MAIN_EXPAND_TO_CUTOUT_AREA(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_INTERFACE,
|
||||
"ExpandToCutoutArea",
|
||||
false
|
||||
),
|
||||
MAIN_USE_PANIC_HANDLERS(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_INTERFACE,
|
||||
"UsePanicHandlers",
|
||||
true
|
||||
),
|
||||
MAIN_OSD_MESSAGES(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_INTERFACE,
|
||||
"OnScreenDisplayMessages",
|
||||
true
|
||||
),
|
||||
MAIN_ANALYTICS_ENABLED(Settings.FILE_DOLPHIN, Settings.SECTION_ANALYTICS, "Enabled", false),
|
||||
MAIN_ANALYTICS_PERMISSION_ASKED(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_ANALYTICS,
|
||||
"PermissionAsked",
|
||||
false
|
||||
),
|
||||
MAIN_RECURSIVE_ISO_PATHS(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_GENERAL,
|
||||
"RecursiveISOPaths",
|
||||
false
|
||||
),
|
||||
MAIN_USE_GAME_COVERS(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_GENERAL,
|
||||
"UseGameCovers",
|
||||
true
|
||||
),
|
||||
MAIN_DEBUG_JIT_OFF(Settings.FILE_DOLPHIN, Settings.SECTION_DEBUG, "JitOff", false),
|
||||
MAIN_DEBUG_JIT_LOAD_STORE_OFF(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_DEBUG,
|
||||
"JitLoadStoreOff",
|
||||
false
|
||||
),
|
||||
MAIN_DEBUG_JIT_LOAD_STORE_FLOATING_OFF(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_DEBUG,
|
||||
"JitLoadStoreFloatingOff",
|
||||
false
|
||||
),
|
||||
MAIN_DEBUG_JIT_LOAD_STORE_PAIRED_OFF(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_DEBUG,
|
||||
"JitLoadStorePairedOff",
|
||||
false
|
||||
),
|
||||
MAIN_DEBUG_JIT_FLOATING_POINT_OFF(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_DEBUG,
|
||||
"JitFloatingPointOff",
|
||||
false
|
||||
),
|
||||
MAIN_DEBUG_JIT_INTEGER_OFF(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_DEBUG,
|
||||
"JitIntegerOff",
|
||||
false
|
||||
),
|
||||
MAIN_DEBUG_JIT_PAIRED_OFF(Settings.FILE_DOLPHIN, Settings.SECTION_DEBUG, "JitPairedOff", false),
|
||||
MAIN_DEBUG_JIT_SYSTEM_REGISTERS_OFF(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_DEBUG,
|
||||
"JitSystemRegistersOff",
|
||||
false
|
||||
),
|
||||
MAIN_DEBUG_JIT_BRANCH_OFF(Settings.FILE_DOLPHIN, Settings.SECTION_DEBUG, "JitBranchOff", false),
|
||||
MAIN_DEBUG_JIT_REGISTER_CACHE_OFF(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_DEBUG,
|
||||
"JitRegisterCacheOff",
|
||||
false
|
||||
),
|
||||
MAIN_EMULATE_SKYLANDER_PORTAL(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_EMULATED_USB_DEVICES,
|
||||
"EmulateSkylanderPortal",
|
||||
false
|
||||
),
|
||||
MAIN_SHOW_GAME_TITLES(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID,
|
||||
"ShowGameTitles",
|
||||
true
|
||||
),
|
||||
MAIN_USE_BLACK_BACKGROUNDS(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID,
|
||||
"UseBlackBackgrounds",
|
||||
false
|
||||
),
|
||||
MAIN_JOYSTICK_REL_CENTER(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID,
|
||||
"JoystickRelCenter",
|
||||
true
|
||||
),
|
||||
MAIN_SHOW_INPUT_OVERLAY(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID,
|
||||
"ShowInputOverlay",
|
||||
true
|
||||
),
|
||||
MAIN_IR_ALWAYS_RECENTER(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID,
|
||||
"IRAlwaysRecenter",
|
||||
false
|
||||
),
|
||||
MAIN_BUTTON_TOGGLE_GC_0(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleGCButtonA",
|
||||
true
|
||||
),
|
||||
MAIN_BUTTON_TOGGLE_GC_1(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleGCButtonB",
|
||||
true
|
||||
),
|
||||
MAIN_BUTTON_TOGGLE_GC_2(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleGCButtonX",
|
||||
true
|
||||
),
|
||||
MAIN_BUTTON_TOGGLE_GC_3(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleGCButtonY",
|
||||
true
|
||||
),
|
||||
MAIN_BUTTON_TOGGLE_GC_4(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleGCButtonZ",
|
||||
true
|
||||
),
|
||||
MAIN_BUTTON_TOGGLE_GC_5(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleGCButtonStart",
|
||||
true
|
||||
),
|
||||
MAIN_BUTTON_TOGGLE_GC_6(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleGCTriggerL",
|
||||
true
|
||||
),
|
||||
MAIN_BUTTON_TOGGLE_GC_7(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleGCTriggerR",
|
||||
true
|
||||
),
|
||||
MAIN_BUTTON_TOGGLE_GC_8(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleGCDPad",
|
||||
true
|
||||
),
|
||||
MAIN_BUTTON_TOGGLE_GC_9(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleGCStickMain",
|
||||
true
|
||||
),
|
||||
MAIN_BUTTON_TOGGLE_GC_10(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleGCStickC",
|
||||
true
|
||||
),
|
||||
MAIN_BUTTON_TOGGLE_CLASSIC_0(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleClassicButtonA",
|
||||
true
|
||||
),
|
||||
MAIN_BUTTON_TOGGLE_CLASSIC_1(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleClassicButtonB",
|
||||
true
|
||||
),
|
||||
MAIN_BUTTON_TOGGLE_CLASSIC_2(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleClassicButtonX",
|
||||
true
|
||||
),
|
||||
MAIN_BUTTON_TOGGLE_CLASSIC_3(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleClassicButtonY",
|
||||
true
|
||||
),
|
||||
MAIN_BUTTON_TOGGLE_CLASSIC_4(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleClassicButtonPlus",
|
||||
true
|
||||
),
|
||||
MAIN_BUTTON_TOGGLE_CLASSIC_5(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleClassicButtonMinus",
|
||||
true
|
||||
),
|
||||
MAIN_BUTTON_TOGGLE_CLASSIC_6(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleClassicButtonHome",
|
||||
true
|
||||
),
|
||||
MAIN_BUTTON_TOGGLE_CLASSIC_7(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleClassicTriggerL",
|
||||
true
|
||||
),
|
||||
MAIN_BUTTON_TOGGLE_CLASSIC_8(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleClassicTriggerR",
|
||||
true
|
||||
),
|
||||
MAIN_BUTTON_TOGGLE_CLASSIC_9(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleClassicButtonZL",
|
||||
true
|
||||
),
|
||||
MAIN_BUTTON_TOGGLE_CLASSIC_10(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleClassicButtonZR",
|
||||
true
|
||||
),
|
||||
MAIN_BUTTON_TOGGLE_CLASSIC_11(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleClassicDPad",
|
||||
true
|
||||
),
|
||||
MAIN_BUTTON_TOGGLE_CLASSIC_12(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleClassicStickLeft",
|
||||
true
|
||||
),
|
||||
MAIN_BUTTON_TOGGLE_CLASSIC_13(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleClassicStickRight",
|
||||
true
|
||||
),
|
||||
MAIN_BUTTON_TOGGLE_WII_0(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleWiimoteButtonA",
|
||||
true
|
||||
),
|
||||
MAIN_BUTTON_TOGGLE_WII_1(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleWiimoteButtonB",
|
||||
true
|
||||
),
|
||||
MAIN_BUTTON_TOGGLE_WII_2(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleWiimoteButton1",
|
||||
true
|
||||
),
|
||||
MAIN_BUTTON_TOGGLE_WII_3(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleWiimoteButton2",
|
||||
true
|
||||
),
|
||||
MAIN_BUTTON_TOGGLE_WII_4(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleWiimoteButtonPlus",
|
||||
true
|
||||
),
|
||||
MAIN_BUTTON_TOGGLE_WII_5(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleWiimoteButtonMinus",
|
||||
true
|
||||
),
|
||||
MAIN_BUTTON_TOGGLE_WII_6(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleWiimoteButtonHome",
|
||||
true
|
||||
),
|
||||
MAIN_BUTTON_TOGGLE_WII_7(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleWiimoteDPad",
|
||||
true
|
||||
),
|
||||
MAIN_BUTTON_TOGGLE_WII_8(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleNunchukC",
|
||||
true
|
||||
),
|
||||
MAIN_BUTTON_TOGGLE_WII_9(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleNunchukZ",
|
||||
true
|
||||
),
|
||||
MAIN_BUTTON_TOGGLE_WII_10(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"ButtonToggleNunchukStick",
|
||||
true
|
||||
),
|
||||
SYSCONF_SCREENSAVER(Settings.FILE_SYSCONF, "IPL", "SSV", false),
|
||||
SYSCONF_WIDESCREEN(Settings.FILE_SYSCONF, "IPL", "AR", true),
|
||||
SYSCONF_PROGRESSIVE_SCAN(Settings.FILE_SYSCONF, "IPL", "PGS", true),
|
||||
SYSCONF_PAL60(Settings.FILE_SYSCONF, "IPL", "E60", true),
|
||||
SYSCONF_WIIMOTE_MOTOR(Settings.FILE_SYSCONF, "BT", "MOT", true),
|
||||
GFX_WIDESCREEN_HACK(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "wideScreenHack", false),
|
||||
GFX_CROP(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "Crop", false),
|
||||
GFX_SHOW_FPS(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "ShowFPS", false),
|
||||
GFX_SHOW_FTIMES(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "ShowFTimes", false),
|
||||
GFX_SHOW_VPS(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "ShowVPS", false),
|
||||
GFX_SHOW_VTIMES(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "ShowVTimes", false),
|
||||
GFX_SHOW_GRAPHS(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "ShowGraphs", false),
|
||||
GFX_SHOW_SPEED(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "ShowSpeed", false),
|
||||
GFX_SHOW_SPEED_COLORS(
|
||||
Settings.FILE_GFX,
|
||||
Settings.SECTION_GFX_SETTINGS,
|
||||
"ShowSpeedColors",
|
||||
true
|
||||
),
|
||||
GFX_LOG_RENDER_TIME_TO_FILE(
|
||||
Settings.FILE_GFX,
|
||||
Settings.SECTION_GFX_SETTINGS,
|
||||
"LogRenderTimeToFile",
|
||||
false
|
||||
),
|
||||
GFX_OVERLAY_STATS(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "OverlayStats", false),
|
||||
GFX_DUMP_TEXTURES(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "DumpTextures", false),
|
||||
GFX_DUMP_MIP_TEXTURES(
|
||||
Settings.FILE_GFX,
|
||||
Settings.SECTION_GFX_SETTINGS,
|
||||
"DumpMipTextures",
|
||||
false
|
||||
),
|
||||
GFX_DUMP_BASE_TEXTURES(
|
||||
Settings.FILE_GFX,
|
||||
Settings.SECTION_GFX_SETTINGS,
|
||||
"DumpBaseTextures",
|
||||
false
|
||||
),
|
||||
GFX_HIRES_TEXTURES(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "HiresTextures", false),
|
||||
GFX_CACHE_HIRES_TEXTURES(
|
||||
Settings.FILE_GFX,
|
||||
Settings.SECTION_GFX_SETTINGS,
|
||||
"CacheHiresTextures",
|
||||
false
|
||||
),
|
||||
GFX_DUMP_EFB_TARGET(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "DumpEFBTarget", false),
|
||||
GFX_DUMP_XFB_TARGET(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "DumpXFBTarget", false),
|
||||
GFX_INTERNAL_RESOLUTION_FRAME_DUMPS(
|
||||
Settings.FILE_GFX,
|
||||
Settings.SECTION_GFX_SETTINGS,
|
||||
"InternalResolutionFrameDumps",
|
||||
false
|
||||
),
|
||||
GFX_ENABLE_GPU_TEXTURE_DECODING(
|
||||
Settings.FILE_GFX,
|
||||
Settings.SECTION_GFX_SETTINGS,
|
||||
"EnableGPUTextureDecoding",
|
||||
false
|
||||
),
|
||||
GFX_ENABLE_PIXEL_LIGHTING(
|
||||
Settings.FILE_GFX,
|
||||
Settings.SECTION_GFX_SETTINGS,
|
||||
"EnablePixelLighting",
|
||||
false
|
||||
),
|
||||
GFX_FAST_DEPTH_CALC(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "FastDepthCalc", true),
|
||||
GFX_TEXFMT_OVERLAY_ENABLE(
|
||||
Settings.FILE_GFX,
|
||||
Settings.SECTION_GFX_SETTINGS,
|
||||
"TexFmtOverlayEnable",
|
||||
false
|
||||
),
|
||||
GFX_ENABLE_WIREFRAME(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "WireFrame", false),
|
||||
GFX_DISABLE_FOG(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "DisableFog", false),
|
||||
GFX_ENABLE_VALIDATION_LAYER(
|
||||
Settings.FILE_GFX,
|
||||
Settings.SECTION_GFX_SETTINGS,
|
||||
"EnableValidationLayer",
|
||||
false
|
||||
),
|
||||
GFX_BACKEND_MULTITHREADING(
|
||||
Settings.FILE_GFX,
|
||||
Settings.SECTION_GFX_SETTINGS,
|
||||
"BackendMultithreading",
|
||||
true
|
||||
),
|
||||
GFX_WAIT_FOR_SHADERS_BEFORE_STARTING(
|
||||
Settings.FILE_GFX,
|
||||
Settings.SECTION_GFX_SETTINGS,
|
||||
"WaitForShadersBeforeStarting",
|
||||
false
|
||||
),
|
||||
GFX_SAVE_TEXTURE_CACHE_TO_STATE(
|
||||
Settings.FILE_GFX,
|
||||
Settings.SECTION_GFX_SETTINGS,
|
||||
"SaveTextureCacheToState",
|
||||
true
|
||||
),
|
||||
GFX_PREFER_VS_FOR_LINE_POINT_EXPANSION(
|
||||
Settings.FILE_GFX,
|
||||
Settings.SECTION_GFX_SETTINGS,
|
||||
"PreferVSForLinePointExpansion",
|
||||
false
|
||||
),
|
||||
GFX_CPU_CULL(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "CPUCull", false),
|
||||
GFX_MODS_ENABLE(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "EnableMods", false),
|
||||
GFX_ENHANCE_FORCE_TRUE_COLOR(
|
||||
Settings.FILE_GFX,
|
||||
Settings.SECTION_GFX_ENHANCEMENTS,
|
||||
"ForceTrueColor",
|
||||
true
|
||||
),
|
||||
GFX_ENHANCE_DISABLE_COPY_FILTER(
|
||||
Settings.FILE_GFX,
|
||||
Settings.SECTION_GFX_ENHANCEMENTS,
|
||||
"DisableCopyFilter",
|
||||
true
|
||||
),
|
||||
GFX_ENHANCE_ARBITRARY_MIPMAP_DETECTION(
|
||||
Settings.FILE_GFX,
|
||||
Settings.SECTION_GFX_ENHANCEMENTS,
|
||||
"ArbitraryMipmapDetection",
|
||||
true
|
||||
),
|
||||
GFX_STEREO_SWAP_EYES(Settings.FILE_GFX, Settings.SECTION_STEREOSCOPY, "StereoSwapEyes", false),
|
||||
GFX_HACK_EFB_ACCESS_ENABLE(
|
||||
Settings.FILE_GFX,
|
||||
Settings.SECTION_GFX_HACKS,
|
||||
"EFBAccessEnable",
|
||||
true
|
||||
),
|
||||
GFX_HACK_EFB_DEFER_INVALIDATION(
|
||||
Settings.FILE_GFX,
|
||||
Settings.SECTION_GFX_HACKS,
|
||||
"EFBAccessDeferInvalidation",
|
||||
false
|
||||
),
|
||||
GFX_HACK_BBOX_ENABLE(Settings.FILE_GFX, Settings.SECTION_GFX_HACKS, "BBoxEnable", false),
|
||||
GFX_HACK_SKIP_EFB_COPY_TO_RAM(
|
||||
Settings.FILE_GFX,
|
||||
Settings.SECTION_GFX_HACKS,
|
||||
"EFBToTextureEnable",
|
||||
true
|
||||
),
|
||||
GFX_HACK_SKIP_XFB_COPY_TO_RAM(
|
||||
Settings.FILE_GFX,
|
||||
Settings.SECTION_GFX_HACKS,
|
||||
"XFBToTextureEnable",
|
||||
true
|
||||
),
|
||||
GFX_HACK_DISABLE_COPY_TO_VRAM(
|
||||
Settings.FILE_GFX,
|
||||
Settings.SECTION_GFX_HACKS,
|
||||
"DisableCopyToVRAM",
|
||||
false
|
||||
),
|
||||
GFX_HACK_DEFER_EFB_COPIES(
|
||||
Settings.FILE_GFX,
|
||||
Settings.SECTION_GFX_HACKS,
|
||||
"DeferEFBCopies",
|
||||
true
|
||||
),
|
||||
GFX_HACK_IMMEDIATE_XFB(
|
||||
Settings.FILE_GFX,
|
||||
Settings.SECTION_GFX_HACKS,
|
||||
"ImmediateXFBEnable",
|
||||
false
|
||||
),
|
||||
GFX_HACK_SKIP_DUPLICATE_XFBS(
|
||||
Settings.FILE_GFX,
|
||||
Settings.SECTION_GFX_HACKS,
|
||||
"SkipDuplicateXFBs",
|
||||
true
|
||||
),
|
||||
GFX_HACK_COPY_EFB_SCALED(Settings.FILE_GFX, Settings.SECTION_GFX_HACKS, "EFBScaledCopy", true),
|
||||
GFX_HACK_EFB_EMULATE_FORMAT_CHANGES(
|
||||
Settings.FILE_GFX,
|
||||
Settings.SECTION_GFX_HACKS,
|
||||
"EFBEmulateFormatChanges",
|
||||
false
|
||||
),
|
||||
GFX_HACK_VERTEX_ROUNDING(
|
||||
Settings.FILE_GFX,
|
||||
Settings.SECTION_GFX_HACKS,
|
||||
"VertexRounding",
|
||||
false
|
||||
),
|
||||
GFX_HACK_VI_SKIP(Settings.FILE_GFX, Settings.SECTION_GFX_HACKS, "VISkip", false),
|
||||
GFX_HACK_FAST_TEXTURE_SAMPLING(
|
||||
Settings.FILE_GFX,
|
||||
Settings.SECTION_GFX_HACKS,
|
||||
"FastTextureSampling",
|
||||
true
|
||||
),
|
||||
LOGGER_WRITE_TO_FILE(
|
||||
Settings.FILE_LOGGER,
|
||||
Settings.SECTION_LOGGER_OPTIONS,
|
||||
"WriteToFile",
|
||||
false
|
||||
);
|
||||
|
||||
override val isOverridden: Boolean
|
||||
get() = NativeConfig.isOverridden(file, section, key)
|
||||
|
||||
override val isRuntimeEditable: Boolean
|
||||
get() {
|
||||
if (file == Settings.FILE_SYSCONF) return false
|
||||
for (setting in NOT_RUNTIME_EDITABLE) {
|
||||
if (setting == this) return false
|
||||
}
|
||||
return NativeConfig.isSettingSaveable(file, section, key)
|
||||
}
|
||||
|
||||
override fun delete(settings: Settings): Boolean {
|
||||
if (!NativeConfig.isSettingSaveable(file, section, key)) {
|
||||
throw UnsupportedOperationException("Unsupported setting: $file, $section, $key")
|
||||
}
|
||||
return NativeConfig.deleteKey(settings.writeLayer, file, section, key)
|
||||
}
|
||||
|
||||
override val boolean: Boolean
|
||||
get() = NativeConfig.getBoolean(
|
||||
NativeConfig.LAYER_ACTIVE,
|
||||
file,
|
||||
section,
|
||||
key,
|
||||
defaultValue
|
||||
)
|
||||
|
||||
override fun setBoolean(settings: Settings, newValue: Boolean) {
|
||||
if (!NativeConfig.isSettingSaveable(file, section, key)) {
|
||||
throw UnsupportedOperationException("Unsupported setting: $file, $section, $key")
|
||||
}
|
||||
NativeConfig.setBoolean(settings.writeLayer, file, section, key, newValue)
|
||||
}
|
||||
|
||||
fun setBoolean(layer: Int, newValue: Boolean) {
|
||||
if (!NativeConfig.isSettingSaveable(file, section, key)) {
|
||||
throw UnsupportedOperationException("Unsupported setting: $file, $section, $key")
|
||||
}
|
||||
NativeConfig.setBoolean(layer, file, section, key, newValue)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val NOT_RUNTIME_EDITABLE_ARRAY = arrayOf(
|
||||
MAIN_DSP_HLE,
|
||||
MAIN_CPU_THREAD,
|
||||
MAIN_ENABLE_CHEATS,
|
||||
MAIN_OVERRIDE_REGION_SETTINGS,
|
||||
MAIN_MMU,
|
||||
MAIN_PAUSE_ON_PANIC,
|
||||
MAIN_ACCURATE_CPU_CACHE,
|
||||
MAIN_RAM_OVERRIDE_ENABLE,
|
||||
MAIN_CUSTOM_RTC_ENABLE,
|
||||
MAIN_DSP_JIT,
|
||||
MAIN_EMULATE_SKYLANDER_PORTAL
|
||||
)
|
||||
private val NOT_RUNTIME_EDITABLE: Set<BooleanSetting> =
|
||||
HashSet(listOf(*NOT_RUNTIME_EDITABLE_ARRAY))
|
||||
|
||||
@JvmStatic
|
||||
fun getSettingForAdapterRumble(channel: Int): BooleanSetting {
|
||||
return arrayOf(
|
||||
MAIN_ADAPTER_RUMBLE_0,
|
||||
MAIN_ADAPTER_RUMBLE_1,
|
||||
MAIN_ADAPTER_RUMBLE_2,
|
||||
MAIN_ADAPTER_RUMBLE_3
|
||||
)[channel]
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getSettingForSimulateKonga(channel: Int): BooleanSetting {
|
||||
return arrayOf(
|
||||
MAIN_SIMULATE_KONGA_0,
|
||||
MAIN_SIMULATE_KONGA_1,
|
||||
MAIN_SIMULATE_KONGA_2,
|
||||
MAIN_SIMULATE_KONGA_3
|
||||
)[channel]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
public enum FloatSetting implements AbstractFloatSetting
|
||||
{
|
||||
// These entries have the same names and order as in C++, just for consistency.
|
||||
|
||||
MAIN_EMULATION_SPEED(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "EmulationSpeed", 1.0f),
|
||||
MAIN_OVERCLOCK(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "Overclock", 1.0f);
|
||||
|
||||
private final String mFile;
|
||||
private final String mSection;
|
||||
private final String mKey;
|
||||
private final float mDefaultValue;
|
||||
|
||||
FloatSetting(String file, String section, String key, float defaultValue)
|
||||
{
|
||||
mFile = file;
|
||||
mSection = section;
|
||||
mKey = key;
|
||||
mDefaultValue = defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverridden()
|
||||
{
|
||||
return NativeConfig.isOverridden(mFile, mSection, mKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRuntimeEditable()
|
||||
{
|
||||
return NativeConfig.isSettingSaveable(mFile, mSection, mKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean delete(@NonNull Settings settings)
|
||||
{
|
||||
if (!NativeConfig.isSettingSaveable(mFile, mSection, mKey))
|
||||
{
|
||||
throw new UnsupportedOperationException(
|
||||
"Unsupported setting: " + mFile + ", " + mSection + ", " + mKey);
|
||||
}
|
||||
|
||||
return NativeConfig.deleteKey(settings.getWriteLayer(), mFile, mSection, mKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getFloat()
|
||||
{
|
||||
return NativeConfig.getFloat(NativeConfig.LAYER_ACTIVE, mFile, mSection, mKey, mDefaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFloat(@NonNull Settings settings, float newValue)
|
||||
{
|
||||
if (!NativeConfig.isSettingSaveable(mFile, mSection, mKey))
|
||||
{
|
||||
throw new UnsupportedOperationException(
|
||||
"Unsupported setting: " + mFile + ", " + mSection + ", " + mKey);
|
||||
}
|
||||
|
||||
NativeConfig.setFloat(settings.getWriteLayer(), mFile, mSection, mKey, newValue);
|
||||
}
|
||||
|
||||
public void setFloat(int layer, float newValue)
|
||||
{
|
||||
NativeConfig.setFloat(layer, mFile, mSection, mKey, newValue);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model
|
||||
|
||||
enum class FloatSetting(
|
||||
private val file: String,
|
||||
private val section: String,
|
||||
private val key: String,
|
||||
private val defaultValue: Float
|
||||
) : AbstractFloatSetting {
|
||||
// These entries have the same names and order as in C++, just for consistency.
|
||||
MAIN_EMULATION_SPEED(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "EmulationSpeed", 1.0f),
|
||||
MAIN_OVERCLOCK(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "Overclock", 1.0f);
|
||||
|
||||
override val isOverridden: Boolean
|
||||
get() = NativeConfig.isOverridden(file, section, key)
|
||||
|
||||
override val isRuntimeEditable: Boolean
|
||||
get() = NativeConfig.isSettingSaveable(file, section, key)
|
||||
|
||||
override fun delete(settings: Settings): Boolean {
|
||||
if (!NativeConfig.isSettingSaveable(file, section, key)) {
|
||||
throw UnsupportedOperationException("Unsupported setting: $file, $section, $key")
|
||||
}
|
||||
return NativeConfig.deleteKey(settings.writeLayer, file, section, key)
|
||||
}
|
||||
|
||||
override val float: Float
|
||||
get() = NativeConfig.getFloat(NativeConfig.LAYER_ACTIVE, file, section, key, defaultValue)
|
||||
|
||||
override fun setFloat(settings: Settings, newValue: Float) {
|
||||
if (!NativeConfig.isSettingSaveable(file, section, key)) {
|
||||
throw UnsupportedOperationException("Unsupported setting: $file, $section, $key")
|
||||
}
|
||||
NativeConfig.setFloat(settings.writeLayer, file, section, key, newValue)
|
||||
}
|
||||
|
||||
fun setFloat(layer: Int, newValue: Float) {
|
||||
NativeConfig.setFloat(layer, file, section, key, newValue)
|
||||
}
|
||||
}
|
|
@ -1,196 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model;
|
||||
|
||||
import android.content.pm.ActivityInfo;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.dolphinemu.dolphinemu.NativeLibrary;
|
||||
import org.dolphinemu.dolphinemu.overlay.InputOverlayPointer;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public enum IntSetting implements AbstractIntSetting
|
||||
{
|
||||
// These entries have the same names and order as in C++, just for consistency.
|
||||
|
||||
MAIN_CPU_CORE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "CPUCore",
|
||||
NativeLibrary.DefaultCPUCore()),
|
||||
MAIN_GC_LANGUAGE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "SelectedLanguage", 0),
|
||||
MAIN_MEM1_SIZE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "MEM1Size", 0x01800000),
|
||||
MAIN_MEM2_SIZE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "MEM2Size", 0x04000000),
|
||||
MAIN_SLOT_A(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "SlotA", 8),
|
||||
MAIN_SLOT_B(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "SlotB", 255),
|
||||
MAIN_SERIAL_PORT_1(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "SerialPort1", 255),
|
||||
MAIN_FALLBACK_REGION(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "FallbackRegion", 2),
|
||||
MAIN_SI_DEVICE_0(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "SIDevice0", 6),
|
||||
MAIN_SI_DEVICE_1(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "SIDevice1", 0),
|
||||
MAIN_SI_DEVICE_2(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "SIDevice2", 0),
|
||||
MAIN_SI_DEVICE_3(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "SIDevice3", 0),
|
||||
|
||||
MAIN_AUDIO_VOLUME(Settings.FILE_DOLPHIN, Settings.SECTION_INI_DSP, "Volume", 100),
|
||||
|
||||
MAIN_OVERLAY_GC_CONTROLLER(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID,
|
||||
"OverlayGCController", 0), // Defaults to GameCube controller 1
|
||||
MAIN_OVERLAY_WII_CONTROLLER(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID,
|
||||
"OverlayWiiController", 4), // Defaults to Wii Remote 1
|
||||
MAIN_CONTROL_SCALE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID, "ControlScale", 50),
|
||||
MAIN_CONTROL_OPACITY(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID, "ControlOpacity", 65),
|
||||
MAIN_EMULATION_ORIENTATION(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID,
|
||||
"EmulationOrientation", ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE),
|
||||
MAIN_INTERFACE_THEME(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID, "InterfaceTheme", 0),
|
||||
MAIN_INTERFACE_THEME_MODE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID,
|
||||
"InterfaceThemeMode", -1),
|
||||
MAIN_LAST_PLATFORM_TAB(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID, "LastPlatformTab", 0),
|
||||
MAIN_IR_MODE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID, "IRMode",
|
||||
InputOverlayPointer.MODE_FOLLOW),
|
||||
|
||||
MAIN_DOUBLE_TAP_BUTTON(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"DoubleTapButton", NativeLibrary.ButtonType.WIIMOTE_BUTTON_A),
|
||||
|
||||
SYSCONF_LANGUAGE(Settings.FILE_SYSCONF, "IPL", "LNG", 0x01),
|
||||
SYSCONF_SOUND_MODE(Settings.FILE_SYSCONF, "IPL", "SND", 0x01),
|
||||
|
||||
SYSCONF_SENSOR_BAR_POSITION(Settings.FILE_SYSCONF, "BT", "BAR", 0x01),
|
||||
SYSCONF_SENSOR_BAR_SENSITIVITY(Settings.FILE_SYSCONF, "BT", "SENS", 0x03),
|
||||
SYSCONF_SPEAKER_VOLUME(Settings.FILE_SYSCONF, "BT", "SPKV", 0x58),
|
||||
|
||||
GFX_ASPECT_RATIO(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "AspectRatio", 0),
|
||||
GFX_SAFE_TEXTURE_CACHE_COLOR_SAMPLES(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS,
|
||||
"SafeTextureCacheColorSamples", 128),
|
||||
GFX_PNG_COMPRESSION_LEVEL(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "PNGCompressionLevel",
|
||||
6),
|
||||
GFX_MSAA(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "MSAA", 1),
|
||||
GFX_EFB_SCALE(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "InternalResolution", 1),
|
||||
GFX_SHADER_COMPILATION_MODE(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS,
|
||||
"ShaderCompilationMode", 0),
|
||||
|
||||
GFX_ENHANCE_FORCE_TEXTURE_FILTERING(Settings.FILE_GFX, Settings.SECTION_GFX_ENHANCEMENTS,
|
||||
"ForceTextureFiltering", 0),
|
||||
|
||||
GFX_ENHANCE_MAX_ANISOTROPY(Settings.FILE_GFX, Settings.SECTION_GFX_ENHANCEMENTS, "MaxAnisotropy",
|
||||
0),
|
||||
|
||||
GFX_STEREO_MODE(Settings.FILE_GFX, Settings.SECTION_STEREOSCOPY, "StereoMode", 0),
|
||||
GFX_STEREO_DEPTH(Settings.FILE_GFX, Settings.SECTION_STEREOSCOPY, "StereoDepth", 20),
|
||||
GFX_STEREO_CONVERGENCE_PERCENTAGE(Settings.FILE_GFX, Settings.SECTION_STEREOSCOPY,
|
||||
"StereoConvergencePercentage", 100),
|
||||
|
||||
GFX_PERF_SAMP_WINDOW(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "PerfSampWindowMS", 1000),
|
||||
|
||||
LOGGER_VERBOSITY(Settings.FILE_LOGGER, Settings.SECTION_LOGGER_OPTIONS, "Verbosity", 1),
|
||||
|
||||
WIIMOTE_1_SOURCE(Settings.FILE_WIIMOTE, "Wiimote1", "Source", 1),
|
||||
WIIMOTE_2_SOURCE(Settings.FILE_WIIMOTE, "Wiimote2", "Source", 0),
|
||||
WIIMOTE_3_SOURCE(Settings.FILE_WIIMOTE, "Wiimote3", "Source", 0),
|
||||
WIIMOTE_4_SOURCE(Settings.FILE_WIIMOTE, "Wiimote4", "Source", 0),
|
||||
WIIMOTE_BB_SOURCE(Settings.FILE_WIIMOTE, "BalanceBoard", "Source", 0);
|
||||
|
||||
private static final IntSetting[] NOT_RUNTIME_EDITABLE_ARRAY = new IntSetting[]{
|
||||
MAIN_CPU_CORE,
|
||||
MAIN_GC_LANGUAGE,
|
||||
MAIN_MEM1_SIZE,
|
||||
MAIN_MEM2_SIZE,
|
||||
MAIN_SLOT_A, // Can actually be changed, but specific code is required
|
||||
MAIN_SLOT_B, // Can actually be changed, but specific code is required
|
||||
MAIN_SERIAL_PORT_1,
|
||||
MAIN_FALLBACK_REGION,
|
||||
MAIN_SI_DEVICE_0, // Can actually be changed, but specific code is required
|
||||
MAIN_SI_DEVICE_1, // Can actually be changed, but specific code is required
|
||||
MAIN_SI_DEVICE_2, // Can actually be changed, but specific code is required
|
||||
MAIN_SI_DEVICE_3, // Can actually be changed, but specific code is required
|
||||
};
|
||||
|
||||
private static final Set<IntSetting> NOT_RUNTIME_EDITABLE =
|
||||
new HashSet<>(Arrays.asList(NOT_RUNTIME_EDITABLE_ARRAY));
|
||||
|
||||
private final String mFile;
|
||||
private final String mSection;
|
||||
private final String mKey;
|
||||
private final int mDefaultValue;
|
||||
|
||||
IntSetting(String file, String section, String key, int defaultValue)
|
||||
{
|
||||
mFile = file;
|
||||
mSection = section;
|
||||
mKey = key;
|
||||
mDefaultValue = defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverridden()
|
||||
{
|
||||
return NativeConfig.isOverridden(mFile, mSection, mKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRuntimeEditable()
|
||||
{
|
||||
if (mFile.equals(Settings.FILE_SYSCONF))
|
||||
return false;
|
||||
|
||||
for (IntSetting setting : NOT_RUNTIME_EDITABLE)
|
||||
{
|
||||
if (setting == this)
|
||||
return false;
|
||||
}
|
||||
|
||||
return NativeConfig.isSettingSaveable(mFile, mSection, mKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean delete(@NonNull Settings settings)
|
||||
{
|
||||
if (!NativeConfig.isSettingSaveable(mFile, mSection, mKey))
|
||||
{
|
||||
throw new UnsupportedOperationException(
|
||||
"Unsupported setting: " + mFile + ", " + mSection + ", " + mKey);
|
||||
}
|
||||
|
||||
return NativeConfig.deleteKey(settings.getWriteLayer(), mFile, mSection, mKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInt()
|
||||
{
|
||||
return NativeConfig.getInt(NativeConfig.LAYER_ACTIVE, mFile, mSection, mKey, mDefaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInt(@NonNull Settings settings, int newValue)
|
||||
{
|
||||
if (!NativeConfig.isSettingSaveable(mFile, mSection, mKey))
|
||||
{
|
||||
throw new UnsupportedOperationException(
|
||||
"Unsupported setting: " + mFile + ", " + mSection + ", " + mKey);
|
||||
}
|
||||
|
||||
NativeConfig.setInt(settings.getWriteLayer(), mFile, mSection, mKey, newValue);
|
||||
}
|
||||
|
||||
public void setInt(int layer, int newValue)
|
||||
{
|
||||
if (!NativeConfig.isSettingSaveable(mFile, mSection, mKey))
|
||||
{
|
||||
throw new UnsupportedOperationException(
|
||||
"Unsupported setting: " + mFile + ", " + mSection + ", " + mKey);
|
||||
}
|
||||
|
||||
NativeConfig.setInt(layer, mFile, mSection, mKey, newValue);
|
||||
}
|
||||
|
||||
public static IntSetting getSettingForSIDevice(int channel)
|
||||
{
|
||||
return new IntSetting[]{MAIN_SI_DEVICE_0, MAIN_SI_DEVICE_1, MAIN_SI_DEVICE_2, MAIN_SI_DEVICE_3}
|
||||
[channel];
|
||||
}
|
||||
|
||||
public static IntSetting getSettingForWiimoteSource(int index)
|
||||
{
|
||||
return new IntSetting[]{WIIMOTE_1_SOURCE, WIIMOTE_2_SOURCE, WIIMOTE_3_SOURCE, WIIMOTE_4_SOURCE,
|
||||
WIIMOTE_BB_SOURCE}[index];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,219 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model
|
||||
|
||||
import android.content.pm.ActivityInfo
|
||||
import org.dolphinemu.dolphinemu.NativeLibrary
|
||||
import org.dolphinemu.dolphinemu.overlay.InputOverlayPointer
|
||||
import java.util.*
|
||||
|
||||
enum class IntSetting(
|
||||
private val file: String,
|
||||
private val section: String,
|
||||
private val key: String,
|
||||
private val defaultValue: Int
|
||||
) : AbstractIntSetting {
|
||||
// These entries have the same names and order as in C++, just for consistency.
|
||||
MAIN_CPU_CORE(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_CORE,
|
||||
"CPUCore",
|
||||
NativeLibrary.DefaultCPUCore()
|
||||
),
|
||||
MAIN_GC_LANGUAGE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "SelectedLanguage", 0),
|
||||
MAIN_MEM1_SIZE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "MEM1Size", 0x01800000),
|
||||
MAIN_MEM2_SIZE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "MEM2Size", 0x04000000),
|
||||
MAIN_SLOT_A(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "SlotA", 8),
|
||||
MAIN_SLOT_B(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "SlotB", 255),
|
||||
MAIN_SERIAL_PORT_1(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "SerialPort1", 255),
|
||||
MAIN_FALLBACK_REGION(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "FallbackRegion", 2),
|
||||
MAIN_SI_DEVICE_0(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "SIDevice0", 6),
|
||||
MAIN_SI_DEVICE_1(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "SIDevice1", 0),
|
||||
MAIN_SI_DEVICE_2(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "SIDevice2", 0),
|
||||
MAIN_SI_DEVICE_3(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "SIDevice3", 0),
|
||||
MAIN_AUDIO_VOLUME(Settings.FILE_DOLPHIN, Settings.SECTION_INI_DSP, "Volume", 100),
|
||||
MAIN_OVERLAY_GC_CONTROLLER(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID,
|
||||
"OverlayGCController",
|
||||
0
|
||||
),
|
||||
|
||||
// Defaults to GameCube controller 1
|
||||
MAIN_OVERLAY_WII_CONTROLLER(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID,
|
||||
"OverlayWiiController",
|
||||
4
|
||||
),
|
||||
|
||||
// Defaults to Wii Remote 1
|
||||
MAIN_CONTROL_SCALE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID, "ControlScale", 50),
|
||||
MAIN_CONTROL_OPACITY(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID, "ControlOpacity", 65),
|
||||
MAIN_EMULATION_ORIENTATION(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID,
|
||||
"EmulationOrientation",
|
||||
ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
|
||||
),
|
||||
MAIN_INTERFACE_THEME(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID, "InterfaceTheme", 0),
|
||||
MAIN_INTERFACE_THEME_MODE(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID,
|
||||
"InterfaceThemeMode",
|
||||
-1
|
||||
),
|
||||
MAIN_LAST_PLATFORM_TAB(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID,
|
||||
"LastPlatformTab",
|
||||
0
|
||||
),
|
||||
MAIN_IR_MODE(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID,
|
||||
"IRMode",
|
||||
InputOverlayPointer.MODE_FOLLOW
|
||||
),
|
||||
MAIN_DOUBLE_TAP_BUTTON(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
|
||||
"DoubleTapButton",
|
||||
NativeLibrary.ButtonType.WIIMOTE_BUTTON_A
|
||||
),
|
||||
SYSCONF_LANGUAGE(Settings.FILE_SYSCONF, "IPL", "LNG", 0x01),
|
||||
SYSCONF_SOUND_MODE(Settings.FILE_SYSCONF, "IPL", "SND", 0x01),
|
||||
SYSCONF_SENSOR_BAR_POSITION(Settings.FILE_SYSCONF, "BT", "BAR", 0x01),
|
||||
SYSCONF_SENSOR_BAR_SENSITIVITY(Settings.FILE_SYSCONF, "BT", "SENS", 0x03),
|
||||
SYSCONF_SPEAKER_VOLUME(Settings.FILE_SYSCONF, "BT", "SPKV", 0x58),
|
||||
GFX_ASPECT_RATIO(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "AspectRatio", 0),
|
||||
GFX_SAFE_TEXTURE_CACHE_COLOR_SAMPLES(
|
||||
Settings.FILE_GFX,
|
||||
Settings.SECTION_GFX_SETTINGS,
|
||||
"SafeTextureCacheColorSamples",
|
||||
128
|
||||
),
|
||||
GFX_PNG_COMPRESSION_LEVEL(
|
||||
Settings.FILE_GFX,
|
||||
Settings.SECTION_GFX_SETTINGS,
|
||||
"PNGCompressionLevel",
|
||||
6
|
||||
),
|
||||
GFX_MSAA(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "MSAA", 1),
|
||||
GFX_EFB_SCALE(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "InternalResolution", 1),
|
||||
GFX_SHADER_COMPILATION_MODE(
|
||||
Settings.FILE_GFX,
|
||||
Settings.SECTION_GFX_SETTINGS,
|
||||
"ShaderCompilationMode",
|
||||
0
|
||||
),
|
||||
GFX_ENHANCE_FORCE_TEXTURE_FILTERING(
|
||||
Settings.FILE_GFX,
|
||||
Settings.SECTION_GFX_ENHANCEMENTS,
|
||||
"ForceTextureFiltering",
|
||||
0
|
||||
),
|
||||
GFX_ENHANCE_MAX_ANISOTROPY(
|
||||
Settings.FILE_GFX,
|
||||
Settings.SECTION_GFX_ENHANCEMENTS,
|
||||
"MaxAnisotropy",
|
||||
0
|
||||
),
|
||||
GFX_STEREO_MODE(Settings.FILE_GFX, Settings.SECTION_STEREOSCOPY, "StereoMode", 0),
|
||||
GFX_STEREO_DEPTH(Settings.FILE_GFX, Settings.SECTION_STEREOSCOPY, "StereoDepth", 20),
|
||||
GFX_STEREO_CONVERGENCE_PERCENTAGE(
|
||||
Settings.FILE_GFX,
|
||||
Settings.SECTION_STEREOSCOPY,
|
||||
"StereoConvergencePercentage",
|
||||
100
|
||||
),
|
||||
GFX_PERF_SAMP_WINDOW(
|
||||
Settings.FILE_GFX,
|
||||
Settings.SECTION_GFX_SETTINGS,
|
||||
"PerfSampWindowMS",
|
||||
1000
|
||||
),
|
||||
LOGGER_VERBOSITY(Settings.FILE_LOGGER, Settings.SECTION_LOGGER_OPTIONS, "Verbosity", 1),
|
||||
WIIMOTE_1_SOURCE(Settings.FILE_WIIMOTE, "Wiimote1", "Source", 1),
|
||||
WIIMOTE_2_SOURCE(Settings.FILE_WIIMOTE, "Wiimote2", "Source", 0),
|
||||
WIIMOTE_3_SOURCE(Settings.FILE_WIIMOTE, "Wiimote3", "Source", 0),
|
||||
WIIMOTE_4_SOURCE(Settings.FILE_WIIMOTE, "Wiimote4", "Source", 0),
|
||||
WIIMOTE_BB_SOURCE(Settings.FILE_WIIMOTE, "BalanceBoard", "Source", 0);
|
||||
|
||||
override val isOverridden: Boolean
|
||||
get() = NativeConfig.isOverridden(file, section, key)
|
||||
|
||||
override val isRuntimeEditable: Boolean
|
||||
get() {
|
||||
if (file == Settings.FILE_SYSCONF) return false
|
||||
for (setting in NOT_RUNTIME_EDITABLE) {
|
||||
if (setting == this) return false
|
||||
}
|
||||
return NativeConfig.isSettingSaveable(file, section, key)
|
||||
}
|
||||
|
||||
override fun delete(settings: Settings): Boolean {
|
||||
if (!NativeConfig.isSettingSaveable(file, section, key)) {
|
||||
throw UnsupportedOperationException("Unsupported setting: $file, $section, $key")
|
||||
}
|
||||
return NativeConfig.deleteKey(settings.writeLayer, file, section, key)
|
||||
}
|
||||
|
||||
override val int: Int
|
||||
get() = NativeConfig.getInt(NativeConfig.LAYER_ACTIVE, file, section, key, defaultValue)
|
||||
|
||||
override fun setInt(settings: Settings, newValue: Int) {
|
||||
if (!NativeConfig.isSettingSaveable(file, section, key)) {
|
||||
throw UnsupportedOperationException("Unsupported setting: $file, $section, $key")
|
||||
}
|
||||
NativeConfig.setInt(settings.writeLayer, file, section, key, newValue)
|
||||
}
|
||||
|
||||
fun setInt(layer: Int, newValue: Int) {
|
||||
if (!NativeConfig.isSettingSaveable(file, section, key)) {
|
||||
throw UnsupportedOperationException("Unsupported setting: $file, $section, $key")
|
||||
}
|
||||
NativeConfig.setInt(layer, file, section, key, newValue)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val NOT_RUNTIME_EDITABLE_ARRAY = arrayOf(
|
||||
MAIN_CPU_CORE,
|
||||
MAIN_GC_LANGUAGE,
|
||||
MAIN_MEM1_SIZE,
|
||||
MAIN_MEM2_SIZE,
|
||||
MAIN_SLOT_A,
|
||||
MAIN_SLOT_B,
|
||||
MAIN_SERIAL_PORT_1,
|
||||
MAIN_FALLBACK_REGION,
|
||||
MAIN_SI_DEVICE_0,
|
||||
MAIN_SI_DEVICE_1,
|
||||
MAIN_SI_DEVICE_2,
|
||||
MAIN_SI_DEVICE_3
|
||||
)
|
||||
|
||||
private val NOT_RUNTIME_EDITABLE: Set<IntSetting> =
|
||||
HashSet(listOf(*NOT_RUNTIME_EDITABLE_ARRAY))
|
||||
|
||||
@JvmStatic
|
||||
fun getSettingForSIDevice(channel: Int): IntSetting {
|
||||
return arrayOf(
|
||||
MAIN_SI_DEVICE_0,
|
||||
MAIN_SI_DEVICE_1,
|
||||
MAIN_SI_DEVICE_2,
|
||||
MAIN_SI_DEVICE_3
|
||||
)[channel]
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getSettingForWiimoteSource(index: Int): IntSetting {
|
||||
return arrayOf(
|
||||
WIIMOTE_1_SOURCE,
|
||||
WIIMOTE_2_SOURCE,
|
||||
WIIMOTE_3_SOURCE,
|
||||
WIIMOTE_4_SOURCE,
|
||||
WIIMOTE_BB_SOURCE
|
||||
)[index]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model;
|
||||
|
||||
public class NativeConfig
|
||||
{
|
||||
public static final int LAYER_BASE_OR_CURRENT = 0;
|
||||
public static final int LAYER_BASE = 1;
|
||||
public static final int LAYER_LOCAL_GAME = 2;
|
||||
public static final int LAYER_ACTIVE = 3;
|
||||
public static final int LAYER_CURRENT = 4;
|
||||
|
||||
public static native boolean isSettingSaveable(String file, String section, String key);
|
||||
|
||||
public static native void loadGameInis(String gameId, int revision);
|
||||
|
||||
public static native void unloadGameInis();
|
||||
|
||||
public static native void save(int layer);
|
||||
|
||||
public static native void deleteAllKeys(int layer);
|
||||
|
||||
public static native boolean isOverridden(String file, String section, String key);
|
||||
|
||||
public static native boolean deleteKey(int layer, String file, String section, String key);
|
||||
|
||||
public static native boolean exists(int layer, String file, String section, String key);
|
||||
|
||||
public static native String getString(int layer, String file, String section, String key,
|
||||
String defaultValue);
|
||||
|
||||
public static native boolean getBoolean(int layer, String file, String section, String key,
|
||||
boolean defaultValue);
|
||||
|
||||
public static native int getInt(int layer, String file, String section, String key,
|
||||
int defaultValue);
|
||||
|
||||
public static native float getFloat(int layer, String file, String section, String key,
|
||||
float defaultValue);
|
||||
|
||||
public static native void setString(int layer, String file, String section, String key,
|
||||
String value);
|
||||
|
||||
public static native void setBoolean(int layer, String file, String section, String key,
|
||||
boolean value);
|
||||
|
||||
public static native void setInt(int layer, String file, String section, String key, int value);
|
||||
|
||||
public static native void setFloat(int layer, String file, String section, String key,
|
||||
float value);
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model
|
||||
|
||||
object NativeConfig {
|
||||
const val LAYER_BASE_OR_CURRENT = 0
|
||||
const val LAYER_BASE = 1
|
||||
const val LAYER_LOCAL_GAME = 2
|
||||
const val LAYER_ACTIVE = 3
|
||||
const val LAYER_CURRENT = 4
|
||||
|
||||
@JvmStatic
|
||||
external fun isSettingSaveable(file: String, section: String, key: String): Boolean
|
||||
|
||||
@JvmStatic
|
||||
external fun loadGameInis(gameId: String, revision: Int)
|
||||
|
||||
@JvmStatic
|
||||
external fun unloadGameInis()
|
||||
|
||||
@JvmStatic
|
||||
external fun save(layer: Int)
|
||||
|
||||
@JvmStatic
|
||||
external fun deleteAllKeys(layer: Int)
|
||||
|
||||
@JvmStatic
|
||||
external fun isOverridden(file: String, section: String, key: String): Boolean
|
||||
|
||||
@JvmStatic
|
||||
external fun deleteKey(layer: Int, file: String, section: String, key: String): Boolean
|
||||
|
||||
@JvmStatic
|
||||
external fun exists(layer: Int, file: String, section: String, key: String): Boolean
|
||||
|
||||
@JvmStatic
|
||||
external fun getString(
|
||||
layer: Int,
|
||||
file: String,
|
||||
section: String,
|
||||
key: String,
|
||||
defaultValue: String
|
||||
): String
|
||||
|
||||
@JvmStatic
|
||||
external fun getBoolean(
|
||||
layer: Int,
|
||||
file: String,
|
||||
section: String,
|
||||
key: String,
|
||||
defaultValue: Boolean
|
||||
): Boolean
|
||||
|
||||
@JvmStatic
|
||||
external fun getInt(
|
||||
layer: Int,
|
||||
file: String,
|
||||
section: String,
|
||||
key: String,
|
||||
defaultValue: Int
|
||||
): Int
|
||||
|
||||
@JvmStatic
|
||||
external fun getFloat(
|
||||
layer: Int,
|
||||
file: String,
|
||||
section: String,
|
||||
key: String,
|
||||
defaultValue: Float
|
||||
): Float
|
||||
|
||||
@JvmStatic
|
||||
external fun setString(
|
||||
layer: Int,
|
||||
file: String,
|
||||
section: String,
|
||||
key: String,
|
||||
value: String?
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
external fun setBoolean(
|
||||
layer: Int,
|
||||
file: String,
|
||||
section: String,
|
||||
key: String,
|
||||
value: Boolean
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
external fun setInt(
|
||||
layer: Int,
|
||||
file: String,
|
||||
section: String,
|
||||
key: String,
|
||||
value: Int
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
external fun setFloat(
|
||||
layer: Int,
|
||||
file: String,
|
||||
section: String,
|
||||
key: String,
|
||||
value: Float
|
||||
)
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
public class PostProcessing
|
||||
{
|
||||
@NonNull
|
||||
public static native String[] getShaderList();
|
||||
|
||||
@NonNull
|
||||
public static native String[] getAnaglyphShaderList();
|
||||
|
||||
@NonNull
|
||||
public static native String[] getPassiveShaderList();
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model
|
||||
|
||||
object PostProcessing {
|
||||
@JvmStatic
|
||||
val shaderList: Array<String?>
|
||||
external get
|
||||
|
||||
@JvmStatic
|
||||
val anaglyphShaderList: Array<String?>
|
||||
external get
|
||||
|
||||
@JvmStatic
|
||||
val passiveShaderList: Array<String?>
|
||||
external get
|
||||
}
|
|
@ -6,21 +6,18 @@ class ScaledIntSetting(
|
|||
private val scale: Int,
|
||||
private val setting: AbstractIntSetting
|
||||
) : AbstractIntSetting {
|
||||
override fun isOverridden(): Boolean {
|
||||
return setting.isOverridden()
|
||||
}
|
||||
override val isOverridden: Boolean
|
||||
get() = setting.isOverridden
|
||||
|
||||
override fun isRuntimeEditable(): Boolean {
|
||||
return setting.isRuntimeEditable
|
||||
}
|
||||
override val isRuntimeEditable: Boolean
|
||||
get() = setting.isRuntimeEditable
|
||||
|
||||
override fun delete(settings: Settings): Boolean {
|
||||
return setting.delete(settings)
|
||||
}
|
||||
|
||||
override fun getInt(): Int {
|
||||
return setting.getInt() / scale
|
||||
}
|
||||
override val int: Int
|
||||
get() = setting.int / scale
|
||||
|
||||
override fun setInt(settings: Settings, newValue: Int) {
|
||||
return setting.setInt(settings, newValue * scale)
|
||||
|
|
|
@ -1,181 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.dolphinemu.dolphinemu.NativeLibrary;
|
||||
import org.dolphinemu.dolphinemu.R;
|
||||
import org.dolphinemu.dolphinemu.features.input.model.MappingCommon;
|
||||
import org.dolphinemu.dolphinemu.services.GameFileCacheManager;
|
||||
|
||||
import java.io.Closeable;
|
||||
|
||||
public class Settings implements Closeable
|
||||
{
|
||||
public static final String FILE_DOLPHIN = "Dolphin";
|
||||
public static final String FILE_SYSCONF = "SYSCONF";
|
||||
public static final String FILE_GFX = "GFX";
|
||||
public static final String FILE_LOGGER = "Logger";
|
||||
public static final String FILE_WIIMOTE = "WiimoteNew";
|
||||
public static final String FILE_GAME_SETTINGS_ONLY = "GameSettingsOnly";
|
||||
|
||||
public static final String SECTION_INI_ANDROID = "Android";
|
||||
public static final String SECTION_INI_ANDROID_OVERLAY_BUTTONS = "AndroidOverlayButtons";
|
||||
public static final String SECTION_INI_GENERAL = "General";
|
||||
public static final String SECTION_INI_CORE = "Core";
|
||||
public static final String SECTION_INI_INTERFACE = "Interface";
|
||||
public static final String SECTION_INI_DSP = "DSP";
|
||||
|
||||
public static final String SECTION_LOGGER_LOGS = "Logs";
|
||||
public static final String SECTION_LOGGER_OPTIONS = "Options";
|
||||
|
||||
public static final String SECTION_GFX_SETTINGS = "Settings";
|
||||
public static final String SECTION_GFX_ENHANCEMENTS = "Enhancements";
|
||||
public static final String SECTION_GFX_HACKS = "Hacks";
|
||||
|
||||
public static final String SECTION_DEBUG = "Debug";
|
||||
public static final String SECTION_EMULATED_USB_DEVICES = "EmulatedUSBDevices";
|
||||
|
||||
public static final String SECTION_STEREOSCOPY = "Stereoscopy";
|
||||
|
||||
public static final String SECTION_BINDINGS = "Android";
|
||||
public static final String SECTION_PROFILE = "Profile";
|
||||
|
||||
public static final String SECTION_ANALYTICS = "Analytics";
|
||||
|
||||
private String mGameId;
|
||||
private int mRevision;
|
||||
private boolean mIsWii;
|
||||
|
||||
private boolean mSettingsLoaded = false;
|
||||
|
||||
private boolean mLoadedRecursiveIsoPathsValue = false;
|
||||
|
||||
public boolean isGameSpecific()
|
||||
{
|
||||
return !TextUtils.isEmpty(mGameId);
|
||||
}
|
||||
|
||||
public boolean isWii()
|
||||
{
|
||||
return mIsWii;
|
||||
}
|
||||
|
||||
public int getWriteLayer()
|
||||
{
|
||||
return isGameSpecific() ? NativeConfig.LAYER_LOCAL_GAME : NativeConfig.LAYER_BASE_OR_CURRENT;
|
||||
}
|
||||
|
||||
public boolean areSettingsLoaded()
|
||||
{
|
||||
return mSettingsLoaded;
|
||||
}
|
||||
|
||||
public void loadSettings()
|
||||
{
|
||||
// The value of isWii doesn't matter if we don't have any SettingsActivity
|
||||
loadSettings(true);
|
||||
}
|
||||
|
||||
public void loadSettings(boolean isWii)
|
||||
{
|
||||
mIsWii = isWii;
|
||||
mSettingsLoaded = true;
|
||||
|
||||
if (isGameSpecific())
|
||||
{
|
||||
// Loading game INIs while the core is running will mess with the game INIs loaded by the core
|
||||
if (NativeLibrary.IsRunning())
|
||||
throw new IllegalStateException("Attempted to load game INI while emulating");
|
||||
|
||||
NativeConfig.loadGameInis(mGameId, mRevision);
|
||||
}
|
||||
|
||||
mLoadedRecursiveIsoPathsValue = BooleanSetting.MAIN_RECURSIVE_ISO_PATHS.getBoolean();
|
||||
}
|
||||
|
||||
public void loadSettings(String gameId, int revision, boolean isWii)
|
||||
{
|
||||
mGameId = gameId;
|
||||
mRevision = revision;
|
||||
loadSettings(isWii);
|
||||
}
|
||||
|
||||
public void saveSettings(Context context)
|
||||
{
|
||||
if (!isGameSpecific())
|
||||
{
|
||||
if (context != null)
|
||||
Toast.makeText(context, R.string.settings_saved, Toast.LENGTH_SHORT).show();
|
||||
|
||||
MappingCommon.save();
|
||||
|
||||
NativeConfig.save(NativeConfig.LAYER_BASE);
|
||||
|
||||
NativeLibrary.ReloadLoggerConfig();
|
||||
NativeLibrary.UpdateGCAdapterScanThread();
|
||||
|
||||
if (mLoadedRecursiveIsoPathsValue != BooleanSetting.MAIN_RECURSIVE_ISO_PATHS.getBoolean())
|
||||
{
|
||||
// Refresh game library
|
||||
GameFileCacheManager.startRescan();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// custom game settings
|
||||
|
||||
if (context != null)
|
||||
{
|
||||
Toast.makeText(context, context.getString(R.string.settings_saved_game_specific, mGameId),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
NativeConfig.save(NativeConfig.LAYER_LOCAL_GAME);
|
||||
}
|
||||
}
|
||||
|
||||
public void clearGameSettings()
|
||||
{
|
||||
NativeConfig.deleteAllKeys(NativeConfig.LAYER_LOCAL_GAME);
|
||||
}
|
||||
|
||||
public boolean gameIniContainsJunk()
|
||||
{
|
||||
// Older versions of Android Dolphin would copy the entire contents of most of the global INIs
|
||||
// into any game INI that got saved (with some of the sections renamed to match the game INI
|
||||
// section names). The problems with this are twofold:
|
||||
//
|
||||
// 1. The user game INIs will contain entries that Dolphin doesn't support reading from
|
||||
// game INIs. This is annoying when editing game INIs manually but shouldn't really be
|
||||
// a problem for those who only use the GUI.
|
||||
//
|
||||
// 2. Global settings will stick around in user game INIs. For instance, if someone wants to
|
||||
// change the texture cache accuracy to safe for all games, they have to edit not only the
|
||||
// global settings but also every single game INI they have created, since the old value of
|
||||
// the texture cache accuracy setting has been copied into every user game INI.
|
||||
//
|
||||
// These problems are serious enough that we should detect and delete such INI files.
|
||||
// Problem 1 is easy to detect, but due to the nature of problem 2, it's unfortunately not
|
||||
// possible to know which lines were added intentionally by the user and which lines were added
|
||||
// unintentionally, which is why we have to delete the whole file in order to fix everything.
|
||||
|
||||
if (!isGameSpecific())
|
||||
return false;
|
||||
|
||||
return NativeConfig.exists(NativeConfig.LAYER_LOCAL_GAME, FILE_DOLPHIN, SECTION_INI_INTERFACE,
|
||||
"ThemeName");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close()
|
||||
{
|
||||
if (isGameSpecific())
|
||||
{
|
||||
NativeConfig.unloadGameInis();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,144 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model
|
||||
|
||||
import android.content.Context
|
||||
import android.text.TextUtils
|
||||
import android.widget.Toast
|
||||
import org.dolphinemu.dolphinemu.NativeLibrary
|
||||
import org.dolphinemu.dolphinemu.R
|
||||
import org.dolphinemu.dolphinemu.features.input.model.MappingCommon
|
||||
import org.dolphinemu.dolphinemu.services.GameFileCacheManager
|
||||
import java.io.Closeable
|
||||
|
||||
class Settings : Closeable {
|
||||
private var gameId: String = ""
|
||||
private var revision = 0
|
||||
|
||||
var isWii = false
|
||||
private set
|
||||
|
||||
private var settingsLoaded = false
|
||||
private var loadedRecursiveIsoPathsValue = false
|
||||
|
||||
private val isGameSpecific: Boolean
|
||||
get() = !TextUtils.isEmpty(gameId)
|
||||
|
||||
val writeLayer: Int
|
||||
get() = if (isGameSpecific) NativeConfig.LAYER_LOCAL_GAME else NativeConfig.LAYER_BASE_OR_CURRENT
|
||||
|
||||
fun areSettingsLoaded(): Boolean {
|
||||
return settingsLoaded
|
||||
}
|
||||
|
||||
@JvmOverloads
|
||||
fun loadSettings(isWii: Boolean = true) {
|
||||
this.isWii = isWii
|
||||
settingsLoaded = true
|
||||
|
||||
if (isGameSpecific) {
|
||||
// Loading game INIs while the core is running will mess with the game INIs loaded by the core
|
||||
check(!NativeLibrary.IsRunning()) { "Attempted to load game INI while emulating" }
|
||||
NativeConfig.loadGameInis(gameId, revision)
|
||||
}
|
||||
|
||||
loadedRecursiveIsoPathsValue = BooleanSetting.MAIN_RECURSIVE_ISO_PATHS.boolean
|
||||
}
|
||||
|
||||
fun loadSettings(gameId: String, revision: Int, isWii: Boolean) {
|
||||
this.gameId = gameId
|
||||
this.revision = revision
|
||||
loadSettings(isWii)
|
||||
}
|
||||
|
||||
fun saveSettings(context: Context?) {
|
||||
if (!isGameSpecific) {
|
||||
if (context != null) Toast.makeText(
|
||||
context,
|
||||
R.string.settings_saved,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
|
||||
MappingCommon.save()
|
||||
|
||||
NativeConfig.save(NativeConfig.LAYER_BASE)
|
||||
|
||||
NativeLibrary.ReloadLoggerConfig()
|
||||
NativeLibrary.UpdateGCAdapterScanThread()
|
||||
|
||||
if (loadedRecursiveIsoPathsValue != BooleanSetting.MAIN_RECURSIVE_ISO_PATHS.boolean) {
|
||||
// Refresh game library
|
||||
GameFileCacheManager.startRescan()
|
||||
}
|
||||
} else {
|
||||
// custom game settings
|
||||
if (context != null) {
|
||||
Toast.makeText(
|
||||
context, context.getString(R.string.settings_saved_game_specific, gameId),
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
NativeConfig.save(NativeConfig.LAYER_LOCAL_GAME)
|
||||
}
|
||||
}
|
||||
|
||||
fun clearGameSettings() {
|
||||
NativeConfig.deleteAllKeys(NativeConfig.LAYER_LOCAL_GAME)
|
||||
}
|
||||
|
||||
fun gameIniContainsJunk(): Boolean {
|
||||
// Older versions of Android Dolphin would copy the entire contents of most of the global INIs
|
||||
// into any game INI that got saved (with some of the sections renamed to match the game INI
|
||||
// section names). The problems with this are twofold:
|
||||
//
|
||||
// 1. The user game INIs will contain entries that Dolphin doesn't support reading from
|
||||
// game INIs. This is annoying when editing game INIs manually but shouldn't really be
|
||||
// a problem for those who only use the GUI.
|
||||
//
|
||||
// 2. Global settings will stick around in user game INIs. For instance, if someone wants to
|
||||
// change the texture cache accuracy to safe for all games, they have to edit not only the
|
||||
// global settings but also every single game INI they have created, since the old value of
|
||||
// the texture cache accuracy Setting has been copied into every user game INI.
|
||||
//
|
||||
// These problems are serious enough that we should detect and delete such INI files.
|
||||
// Problem 1 is easy to detect, but due to the nature of problem 2, it's unfortunately not
|
||||
// possible to know which lines were added intentionally by the user and which lines were added
|
||||
// unintentionally, which is why we have to delete the whole file in order to fix everything.
|
||||
return if (!isGameSpecific) false else NativeConfig.exists(
|
||||
NativeConfig.LAYER_LOCAL_GAME,
|
||||
FILE_DOLPHIN,
|
||||
SECTION_INI_INTERFACE,
|
||||
"ThemeName"
|
||||
)
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
if (isGameSpecific) {
|
||||
NativeConfig.unloadGameInis()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val FILE_DOLPHIN = "Dolphin"
|
||||
const val FILE_SYSCONF = "SYSCONF"
|
||||
const val FILE_GFX = "GFX"
|
||||
const val FILE_LOGGER = "Logger"
|
||||
const val FILE_WIIMOTE = "WiimoteNew"
|
||||
const val FILE_GAME_SETTINGS_ONLY = "GameSettingsOnly"
|
||||
const val SECTION_INI_ANDROID = "Android"
|
||||
const val SECTION_INI_ANDROID_OVERLAY_BUTTONS = "AndroidOverlayButtons"
|
||||
const val SECTION_INI_GENERAL = "General"
|
||||
const val SECTION_INI_CORE = "Core"
|
||||
const val SECTION_INI_INTERFACE = "Interface"
|
||||
const val SECTION_INI_DSP = "DSP"
|
||||
const val SECTION_LOGGER_LOGS = "Logs"
|
||||
const val SECTION_LOGGER_OPTIONS = "Options"
|
||||
const val SECTION_GFX_SETTINGS = "Settings"
|
||||
const val SECTION_GFX_ENHANCEMENTS = "Enhancements"
|
||||
const val SECTION_GFX_HACKS = "Hacks"
|
||||
const val SECTION_DEBUG = "Debug"
|
||||
const val SECTION_EMULATED_USB_DEVICES = "EmulatedUSBDevices"
|
||||
const val SECTION_STEREOSCOPY = "Stereoscopy"
|
||||
const val SECTION_ANALYTICS = "Analytics"
|
||||
}
|
||||
}
|
|
@ -1,113 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.dolphinemu.dolphinemu.NativeLibrary;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public enum StringSetting implements AbstractStringSetting
|
||||
{
|
||||
// These entries have the same names and order as in C++, just for consistency.
|
||||
|
||||
MAIN_DEFAULT_ISO(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "DefaultISO", ""),
|
||||
|
||||
MAIN_BBA_MAC(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "BBA_MAC", ""),
|
||||
MAIN_BBA_XLINK_IP(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "BBA_XLINK_IP", ""),
|
||||
|
||||
// Schthack PSO Server - https://schtserv.com/
|
||||
MAIN_BBA_BUILTIN_DNS(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "BBA_BUILTIN_DNS",
|
||||
"149.56.167.128"),
|
||||
|
||||
MAIN_CUSTOM_RTC_VALUE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "CustomRTCValue",
|
||||
"0x386d4380"),
|
||||
|
||||
MAIN_GFX_BACKEND(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "GFXBackend",
|
||||
NativeLibrary.GetDefaultGraphicsBackendName()),
|
||||
|
||||
MAIN_DUMP_PATH(Settings.FILE_DOLPHIN, Settings.SECTION_INI_GENERAL, "DumpPath", ""),
|
||||
MAIN_LOAD_PATH(Settings.FILE_DOLPHIN, Settings.SECTION_INI_GENERAL, "LoadPath", ""),
|
||||
MAIN_RESOURCEPACK_PATH(Settings.FILE_DOLPHIN, Settings.SECTION_INI_GENERAL, "ResourcePackPath",
|
||||
""),
|
||||
MAIN_FS_PATH(Settings.FILE_DOLPHIN, Settings.SECTION_INI_GENERAL, "NANDRootPath", ""),
|
||||
MAIN_WII_SD_CARD_IMAGE_PATH(Settings.FILE_DOLPHIN, Settings.SECTION_INI_GENERAL, "WiiSDCardPath",
|
||||
""),
|
||||
MAIN_WII_SD_CARD_SYNC_FOLDER_PATH(Settings.FILE_DOLPHIN, Settings.SECTION_INI_GENERAL,
|
||||
"WiiSDCardSyncFolder", ""),
|
||||
MAIN_WFS_PATH(Settings.FILE_DOLPHIN, Settings.SECTION_INI_GENERAL, "WFSPath", ""),
|
||||
|
||||
GFX_ENHANCE_POST_SHADER(Settings.FILE_GFX, Settings.SECTION_GFX_ENHANCEMENTS,
|
||||
"PostProcessingShader", "");
|
||||
|
||||
private static final StringSetting[] NOT_RUNTIME_EDITABLE_ARRAY = new StringSetting[]{
|
||||
MAIN_CUSTOM_RTC_VALUE,
|
||||
MAIN_GFX_BACKEND,
|
||||
};
|
||||
|
||||
private static final Set<StringSetting> NOT_RUNTIME_EDITABLE =
|
||||
new HashSet<>(Arrays.asList(NOT_RUNTIME_EDITABLE_ARRAY));
|
||||
|
||||
private final String mFile;
|
||||
private final String mSection;
|
||||
private final String mKey;
|
||||
private final String mDefaultValue;
|
||||
|
||||
StringSetting(String file, String section, String key, String defaultValue)
|
||||
{
|
||||
mFile = file;
|
||||
mSection = section;
|
||||
mKey = key;
|
||||
mDefaultValue = defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverridden()
|
||||
{
|
||||
return NativeConfig.isOverridden(mFile, mSection, mKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRuntimeEditable()
|
||||
{
|
||||
for (StringSetting setting : NOT_RUNTIME_EDITABLE)
|
||||
{
|
||||
if (setting == this)
|
||||
return false;
|
||||
}
|
||||
|
||||
return NativeConfig.isSettingSaveable(mFile, mSection, mKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean delete(@NonNull Settings settings)
|
||||
{
|
||||
return NativeConfig.deleteKey(settings.getWriteLayer(), mFile, mSection, mKey);
|
||||
}
|
||||
|
||||
@NonNull @Override
|
||||
public String getString()
|
||||
{
|
||||
if (!NativeConfig.isSettingSaveable(mFile, mSection, mKey))
|
||||
{
|
||||
throw new UnsupportedOperationException(
|
||||
"Unsupported setting: " + mFile + ", " + mSection + ", " + mKey);
|
||||
}
|
||||
|
||||
return NativeConfig.getString(NativeConfig.LAYER_ACTIVE, mFile, mSection, mKey, mDefaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setString(@NonNull Settings settings, @NonNull String newValue)
|
||||
{
|
||||
NativeConfig.setString(settings.getWriteLayer(), mFile, mSection, mKey, newValue);
|
||||
}
|
||||
|
||||
public void setString(int layer, String newValue)
|
||||
{
|
||||
NativeConfig.setString(layer, mFile, mSection, mKey, newValue);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model
|
||||
|
||||
import org.dolphinemu.dolphinemu.NativeLibrary
|
||||
import java.util.*
|
||||
|
||||
enum class StringSetting(
|
||||
private val file: String,
|
||||
private val section: String,
|
||||
private val key: String,
|
||||
private val defaultValue: String
|
||||
) : AbstractStringSetting {
|
||||
// These entries have the same names and order as in C++, just for consistency.
|
||||
MAIN_DEFAULT_ISO(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "DefaultISO", ""),
|
||||
MAIN_BBA_MAC(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "BBA_MAC", ""),
|
||||
MAIN_BBA_XLINK_IP(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "BBA_XLINK_IP", ""),
|
||||
|
||||
// Schthack PSO Server - https://schtserv.com/
|
||||
MAIN_BBA_BUILTIN_DNS(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_CORE,
|
||||
"BBA_BUILTIN_DNS",
|
||||
"149.56.167.128"
|
||||
),
|
||||
MAIN_CUSTOM_RTC_VALUE(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_CORE,
|
||||
"CustomRTCValue",
|
||||
"0x386d4380"
|
||||
),
|
||||
MAIN_GFX_BACKEND(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_CORE,
|
||||
"GFXBackend",
|
||||
NativeLibrary.GetDefaultGraphicsBackendName()
|
||||
),
|
||||
MAIN_DUMP_PATH(Settings.FILE_DOLPHIN, Settings.SECTION_INI_GENERAL, "DumpPath", ""),
|
||||
MAIN_LOAD_PATH(Settings.FILE_DOLPHIN, Settings.SECTION_INI_GENERAL, "LoadPath", ""),
|
||||
MAIN_RESOURCEPACK_PATH(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_GENERAL,
|
||||
"ResourcePackPath",
|
||||
""
|
||||
),
|
||||
MAIN_FS_PATH(Settings.FILE_DOLPHIN, Settings.SECTION_INI_GENERAL, "NANDRootPath", ""),
|
||||
MAIN_WII_SD_CARD_IMAGE_PATH(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_GENERAL,
|
||||
"WiiSDCardPath",
|
||||
""
|
||||
),
|
||||
MAIN_WII_SD_CARD_SYNC_FOLDER_PATH(
|
||||
Settings.FILE_DOLPHIN,
|
||||
Settings.SECTION_INI_GENERAL,
|
||||
"WiiSDCardSyncFolder",
|
||||
""
|
||||
),
|
||||
MAIN_WFS_PATH(Settings.FILE_DOLPHIN, Settings.SECTION_INI_GENERAL, "WFSPath", ""),
|
||||
GFX_ENHANCE_POST_SHADER(
|
||||
Settings.FILE_GFX,
|
||||
Settings.SECTION_GFX_ENHANCEMENTS,
|
||||
"PostProcessingShader",
|
||||
""
|
||||
);
|
||||
|
||||
override val isOverridden: Boolean
|
||||
get() = NativeConfig.isOverridden(file, section, key)
|
||||
|
||||
override val isRuntimeEditable: Boolean
|
||||
get() {
|
||||
for (setting in NOT_RUNTIME_EDITABLE) {
|
||||
if (setting == this) return false
|
||||
}
|
||||
return NativeConfig.isSettingSaveable(file, section, key)
|
||||
}
|
||||
|
||||
override fun delete(settings: Settings): Boolean {
|
||||
return NativeConfig.deleteKey(settings.writeLayer, file, section, key)
|
||||
}
|
||||
|
||||
override val string: String
|
||||
get() = if (!NativeConfig.isSettingSaveable(file, section, key)) {
|
||||
throw UnsupportedOperationException("Unsupported setting: $file, $section, $key")
|
||||
} else NativeConfig.getString(NativeConfig.LAYER_ACTIVE, file, section, key, defaultValue)
|
||||
|
||||
override fun setString(settings: Settings, newValue: String) {
|
||||
NativeConfig.setString(settings.writeLayer, file, section, key, newValue)
|
||||
}
|
||||
|
||||
fun setString(layer: Int, newValue: String?) {
|
||||
NativeConfig.setString(layer, file, section, key, newValue)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val NOT_RUNTIME_EDITABLE_ARRAY = arrayOf(
|
||||
MAIN_CUSTOM_RTC_VALUE,
|
||||
MAIN_GFX_BACKEND
|
||||
)
|
||||
|
||||
private val NOT_RUNTIME_EDITABLE: Set<StringSetting> =
|
||||
HashSet(listOf(*NOT_RUNTIME_EDITABLE_ARRAY))
|
||||
}
|
||||
}
|
|
@ -3,29 +3,22 @@
|
|||
package org.dolphinemu.dolphinemu.features.settings.model.view
|
||||
|
||||
import android.content.Context
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractSetting
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractStringSetting
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings
|
||||
|
||||
class DateTimeChoiceSetting(
|
||||
context: Context,
|
||||
private val setting: AbstractStringSetting,
|
||||
override val setting: AbstractStringSetting,
|
||||
nameId: Int,
|
||||
descriptionId: Int
|
||||
) : SettingsItem(context, nameId, descriptionId) {
|
||||
override fun getType(): Int {
|
||||
return TYPE_DATETIME_CHOICE
|
||||
}
|
||||
|
||||
override fun getSetting(): AbstractSetting {
|
||||
return setting
|
||||
}
|
||||
override val type: Int = TYPE_DATETIME_CHOICE
|
||||
|
||||
fun setSelectedValue(settings: Settings, selection: String) {
|
||||
setting.setString(settings, selection)
|
||||
}
|
||||
|
||||
fun getSelectedValue(): String {
|
||||
return setting.getString()
|
||||
return setting.string
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model.view;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractStringSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
|
||||
|
||||
public final class FilePicker extends SettingsItem
|
||||
{
|
||||
private AbstractStringSetting mSetting;
|
||||
private int mRequestType;
|
||||
private String mDefaultPathRelativeToUserDirectory;
|
||||
|
||||
public FilePicker(Context context, AbstractStringSetting setting, int titleId, int descriptionId,
|
||||
int requestType, @Nullable String defaultPathRelativeToUserDirectory)
|
||||
{
|
||||
super(context, titleId, descriptionId);
|
||||
mSetting = setting;
|
||||
mRequestType = requestType;
|
||||
mDefaultPathRelativeToUserDirectory = defaultPathRelativeToUserDirectory;
|
||||
}
|
||||
|
||||
public String getSelectedValue()
|
||||
{
|
||||
return mSetting.getString();
|
||||
}
|
||||
|
||||
public void setSelectedValue(Settings settings, String selection)
|
||||
{
|
||||
mSetting.setString(settings, selection);
|
||||
}
|
||||
|
||||
public int getRequestType()
|
||||
{
|
||||
return mRequestType;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getDefaultPathRelativeToUserDirectory()
|
||||
{
|
||||
return mDefaultPathRelativeToUserDirectory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getType()
|
||||
{
|
||||
return TYPE_FILE_PICKER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractSetting getSetting()
|
||||
{
|
||||
return mSetting;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model.view
|
||||
|
||||
import android.content.Context
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractStringSetting
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings
|
||||
|
||||
class FilePicker(
|
||||
context: Context,
|
||||
override var setting: AbstractStringSetting,
|
||||
titleId: Int,
|
||||
descriptionId: Int,
|
||||
val requestType: Int,
|
||||
val defaultPathRelativeToUserDirectory: String?
|
||||
) : SettingsItem(context, titleId, descriptionId) {
|
||||
override val type: Int = TYPE_FILE_PICKER
|
||||
|
||||
fun getSelectedValue() : String {
|
||||
return setting.string
|
||||
}
|
||||
|
||||
fun setSelectedValue(settings: Settings, selection: String) {
|
||||
setting.setString(settings, selection)
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model.view;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractFloatSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
|
||||
|
||||
public class FloatSliderSetting extends SliderSetting
|
||||
{
|
||||
protected AbstractFloatSetting mSetting;
|
||||
|
||||
public FloatSliderSetting(Context context, AbstractFloatSetting setting, int titleId,
|
||||
int descriptionId, int min, int max, String units, int stepSize)
|
||||
{
|
||||
super(context, titleId, descriptionId, min, max, units, stepSize);
|
||||
mSetting = setting;
|
||||
}
|
||||
|
||||
public FloatSliderSetting(AbstractFloatSetting setting, CharSequence name,
|
||||
CharSequence description, int min, int max, String units)
|
||||
{
|
||||
super(name, description, min, max, units);
|
||||
mSetting = setting;
|
||||
}
|
||||
|
||||
public int getSelectedValue()
|
||||
{
|
||||
return Math.round(mSetting.getFloat());
|
||||
}
|
||||
|
||||
public void setSelectedValue(Settings settings, float selection)
|
||||
{
|
||||
mSetting.setFloat(settings, selection);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractSetting getSetting()
|
||||
{
|
||||
return mSetting;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model.view
|
||||
|
||||
import android.content.Context
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractFloatSetting
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractSetting
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
open class FloatSliderSetting : SliderSetting {
|
||||
var floatSetting: AbstractFloatSetting
|
||||
|
||||
override val setting: AbstractSetting
|
||||
get() = floatSetting
|
||||
|
||||
constructor(
|
||||
context: Context,
|
||||
setting: AbstractFloatSetting,
|
||||
titleId: Int,
|
||||
descriptionId: Int,
|
||||
min: Int,
|
||||
max: Int,
|
||||
units: String?,
|
||||
stepSize: Int
|
||||
) : super(context, titleId, descriptionId, min, max, units, stepSize) {
|
||||
floatSetting = setting
|
||||
}
|
||||
|
||||
constructor(
|
||||
setting: AbstractFloatSetting,
|
||||
name: CharSequence,
|
||||
description: CharSequence?,
|
||||
min: Int,
|
||||
max: Int,
|
||||
units: String?
|
||||
) : super(name, description, min, max, units) {
|
||||
floatSetting = setting
|
||||
}
|
||||
|
||||
override val selectedValue: Int
|
||||
get() = floatSetting.float.roundToInt()
|
||||
|
||||
open fun setSelectedValue(settings: Settings?, selection: Float) {
|
||||
floatSetting.setFloat(settings!!, selection)
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model.view;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractSetting;
|
||||
|
||||
public class HeaderSetting extends SettingsItem
|
||||
{
|
||||
public HeaderSetting(Context context, int titleId, int descriptionId)
|
||||
{
|
||||
super(context, titleId, descriptionId);
|
||||
}
|
||||
|
||||
public HeaderSetting(CharSequence title, CharSequence description)
|
||||
{
|
||||
super(title, description);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getType()
|
||||
{
|
||||
return SettingsItem.TYPE_HEADER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractSetting getSetting()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model.view
|
||||
|
||||
import android.content.Context
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractSetting
|
||||
|
||||
open class HeaderSetting : SettingsItem {
|
||||
override val setting: AbstractSetting? = null
|
||||
|
||||
constructor(
|
||||
context: Context,
|
||||
titleId: Int,
|
||||
descriptionId: Int
|
||||
) : super(context, titleId, descriptionId)
|
||||
|
||||
constructor(title: CharSequence, description: CharSequence?) : super(title, description)
|
||||
|
||||
override val type: Int = TYPE_HEADER
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model.view;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
public final class HyperLinkHeaderSetting extends HeaderSetting
|
||||
{
|
||||
public HyperLinkHeaderSetting(Context context, int titleId, int descriptionId)
|
||||
{
|
||||
super(context, titleId, descriptionId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getType()
|
||||
{
|
||||
return SettingsItem.TYPE_HYPERLINK_HEADER;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model.view
|
||||
|
||||
import android.content.Context
|
||||
|
||||
class HyperLinkHeaderSetting(
|
||||
context: Context,
|
||||
titleId: Int,
|
||||
descriptionId: Int
|
||||
) : HeaderSetting(context, titleId, descriptionId)
|
|
@ -1,72 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model.view;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractStringSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
|
||||
import org.dolphinemu.dolphinemu.features.settings.ui.MenuTag;
|
||||
|
||||
public class InputStringSetting extends SettingsItem
|
||||
{
|
||||
private AbstractStringSetting mSetting;
|
||||
|
||||
private MenuTag mMenuTag;
|
||||
|
||||
public InputStringSetting(Context context, AbstractStringSetting setting, int titleId,
|
||||
int descriptionId, MenuTag menuTag)
|
||||
{
|
||||
super(context, titleId, descriptionId);
|
||||
mSetting = setting;
|
||||
mMenuTag = menuTag;
|
||||
}
|
||||
|
||||
public InputStringSetting(Context context, AbstractStringSetting setting, int titleId,
|
||||
int descriptionId)
|
||||
{
|
||||
this(context, setting, titleId, descriptionId, null);
|
||||
}
|
||||
|
||||
public InputStringSetting(Context context, AbstractStringSetting setting, int titleId,
|
||||
int descriptionId, int choicesId, int valuesId, MenuTag menuTag)
|
||||
{
|
||||
super(context, titleId, descriptionId);
|
||||
mSetting = setting;
|
||||
mMenuTag = menuTag;
|
||||
}
|
||||
|
||||
public InputStringSetting(Context context, AbstractStringSetting setting, int titleId,
|
||||
int descriptionId, int choicesId, int valuesId)
|
||||
{
|
||||
this(context, setting, titleId, descriptionId, choicesId, valuesId, null);
|
||||
}
|
||||
|
||||
public String getSelectedValue()
|
||||
{
|
||||
return mSetting.getString();
|
||||
}
|
||||
|
||||
public MenuTag getMenuTag()
|
||||
{
|
||||
return mMenuTag;
|
||||
}
|
||||
|
||||
public void setSelectedValue(Settings settings, String selection)
|
||||
{
|
||||
mSetting.setString(settings, selection);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getType()
|
||||
{
|
||||
return TYPE_STRING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractSetting getSetting()
|
||||
{
|
||||
return mSetting;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model.view
|
||||
|
||||
import android.content.Context
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractSetting
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractStringSetting
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings
|
||||
|
||||
class InputStringSetting(
|
||||
context: Context,
|
||||
setting: AbstractStringSetting,
|
||||
titleId: Int,
|
||||
descriptionId: Int,
|
||||
) : SettingsItem(context, titleId, descriptionId) {
|
||||
override val type: Int = TYPE_STRING
|
||||
|
||||
private var stringSetting: AbstractStringSetting = setting
|
||||
|
||||
override val setting: AbstractSetting
|
||||
get() = stringSetting
|
||||
|
||||
val selectedValue: String
|
||||
get() = stringSetting.string
|
||||
|
||||
fun setSelectedValue(settings: Settings, selection: String) {
|
||||
stringSetting.setString(settings, selection)
|
||||
}
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model.view;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractIntSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
|
||||
|
||||
public final class IntSliderSetting extends SliderSetting
|
||||
{
|
||||
private AbstractIntSetting mSetting;
|
||||
|
||||
public IntSliderSetting(Context context, AbstractIntSetting setting, int titleId,
|
||||
int descriptionId, int min, int max, String units, int stepSize)
|
||||
{
|
||||
super(context, titleId, descriptionId, min, max, units, stepSize);
|
||||
mSetting = setting;
|
||||
}
|
||||
|
||||
public int getSelectedValue()
|
||||
{
|
||||
return mSetting.getInt();
|
||||
}
|
||||
|
||||
public void setSelectedValue(Settings settings, int selection)
|
||||
{
|
||||
mSetting.setInt(settings, selection);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractSetting getSetting()
|
||||
{
|
||||
return mSetting;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model.view
|
||||
|
||||
import android.content.Context
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractIntSetting
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractSetting
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings
|
||||
|
||||
class IntSliderSetting(
|
||||
context: Context,
|
||||
private val intSetting: AbstractIntSetting,
|
||||
titleId: Int,
|
||||
descriptionId: Int,
|
||||
min: Int,
|
||||
max: Int,
|
||||
units: String?,
|
||||
stepSize: Int
|
||||
) : SliderSetting(context, titleId, descriptionId, min, max, units, stepSize) {
|
||||
override val setting: AbstractSetting
|
||||
get() = intSetting
|
||||
|
||||
override val selectedValue: Int
|
||||
get() = intSetting.int
|
||||
|
||||
fun setSelectedValue(settings: Settings?, selection: Int) {
|
||||
intSetting.setInt(settings!!, selection)
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model.view;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractBooleanSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
|
||||
|
||||
public final class InvertedSwitchSetting extends SwitchSetting
|
||||
{
|
||||
public InvertedSwitchSetting(Context context, AbstractBooleanSetting setting, int titleId,
|
||||
int descriptionId)
|
||||
{
|
||||
super(context, setting, titleId, descriptionId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChecked()
|
||||
{
|
||||
return !mSetting.getBoolean();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChecked(Settings settings, boolean checked)
|
||||
{
|
||||
mSetting.setBoolean(settings, !checked);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractSetting getSetting()
|
||||
{
|
||||
return mSetting;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model.view
|
||||
|
||||
import android.content.Context
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractBooleanSetting
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractSetting
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings
|
||||
|
||||
class InvertedSwitchSetting(
|
||||
context: Context,
|
||||
setting: AbstractBooleanSetting,
|
||||
titleId: Int,
|
||||
descriptionId: Int
|
||||
) : SwitchSetting(context, setting, titleId, descriptionId) {
|
||||
override val setting: AbstractSetting
|
||||
get() = booleanSetting
|
||||
|
||||
override val isChecked: Boolean
|
||||
get() = !booleanSetting.boolean
|
||||
|
||||
override fun setChecked(settings: Settings?, checked: Boolean) {
|
||||
booleanSetting.setBoolean(settings!!, !checked)
|
||||
}
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model.view;
|
||||
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AdHocBooleanSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
|
||||
|
||||
public class LogSwitchSetting extends SwitchSetting
|
||||
{
|
||||
String mKey;
|
||||
|
||||
public LogSwitchSetting(String key, CharSequence title, CharSequence description)
|
||||
{
|
||||
super(new AdHocBooleanSetting(Settings.FILE_LOGGER, Settings.SECTION_LOGGER_LOGS, key, false),
|
||||
title, description);
|
||||
mKey = key;
|
||||
}
|
||||
|
||||
public String getKey()
|
||||
{
|
||||
return mKey;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model.view
|
||||
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AdHocBooleanSetting
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings
|
||||
|
||||
class LogSwitchSetting(
|
||||
var key: String,
|
||||
title: CharSequence?,
|
||||
description: CharSequence?
|
||||
) : SwitchSetting(
|
||||
AdHocBooleanSetting(
|
||||
Settings.FILE_LOGGER,
|
||||
Settings.SECTION_LOGGER_LOGS,
|
||||
key,
|
||||
false
|
||||
),
|
||||
title,
|
||||
description
|
||||
)
|
|
@ -1,36 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model.view;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractFloatSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
|
||||
|
||||
public final class PercentSliderSetting extends FloatSliderSetting
|
||||
{
|
||||
public PercentSliderSetting(Context context, AbstractFloatSetting setting, int titleId,
|
||||
int descriptionId, int min, int max, String units, int stepSize)
|
||||
{
|
||||
super(context, setting, titleId, descriptionId, min, max, units, stepSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSelectedValue()
|
||||
{
|
||||
return Math.round(mSetting.getFloat() * 100);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelectedValue(Settings settings, float selection)
|
||||
{
|
||||
mSetting.setFloat(settings, selection / 100);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractSetting getSetting()
|
||||
{
|
||||
return mSetting;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model.view
|
||||
|
||||
import android.content.Context
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractFloatSetting
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractSetting
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
class PercentSliderSetting(
|
||||
context: Context,
|
||||
override val setting: AbstractFloatSetting,
|
||||
titleId: Int,
|
||||
descriptionId: Int,
|
||||
min: Int,
|
||||
max: Int,
|
||||
units: String?,
|
||||
stepSize: Int
|
||||
) : FloatSliderSetting(context, setting, titleId, descriptionId, min, max, units, stepSize) {
|
||||
override val selectedValue: Int
|
||||
get() = (floatSetting.float * 100).roundToInt()
|
||||
|
||||
override fun setSelectedValue(settings: Settings?, selection: Float) {
|
||||
floatSetting.setFloat(settings!!, selection / 100)
|
||||
}
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model.view;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import org.dolphinemu.dolphinemu.NativeLibrary;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractSetting;
|
||||
|
||||
public final class RunRunnable extends SettingsItem
|
||||
{
|
||||
private final int mAlertText;
|
||||
private final int mToastTextAfterRun;
|
||||
private final boolean mWorksDuringEmulation;
|
||||
private final Runnable mRunnable;
|
||||
|
||||
public RunRunnable(Context context, int titleId, int descriptionId, int alertText,
|
||||
int toastTextAfterRun, boolean worksDuringEmulation, Runnable runnable)
|
||||
{
|
||||
super(context, titleId, descriptionId);
|
||||
mAlertText = alertText;
|
||||
mToastTextAfterRun = toastTextAfterRun;
|
||||
mWorksDuringEmulation = worksDuringEmulation;
|
||||
mRunnable = runnable;
|
||||
}
|
||||
|
||||
public int getAlertText()
|
||||
{
|
||||
return mAlertText;
|
||||
}
|
||||
|
||||
public int getToastTextAfterRun()
|
||||
{
|
||||
return mToastTextAfterRun;
|
||||
}
|
||||
|
||||
public Runnable getRunnable()
|
||||
{
|
||||
return mRunnable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getType()
|
||||
{
|
||||
return TYPE_RUN_RUNNABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractSetting getSetting()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEditable()
|
||||
{
|
||||
return mWorksDuringEmulation || !NativeLibrary.IsRunning();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model.view
|
||||
|
||||
import android.content.Context
|
||||
import org.dolphinemu.dolphinemu.NativeLibrary
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractSetting
|
||||
|
||||
class RunRunnable(
|
||||
context: Context,
|
||||
titleId: Int,
|
||||
descriptionId: Int,
|
||||
val alertText: Int,
|
||||
val toastTextAfterRun: Int,
|
||||
private val worksDuringEmulation: Boolean,
|
||||
val runnable: Runnable
|
||||
) : SettingsItem(context, titleId, descriptionId) {
|
||||
override val type: Int = TYPE_RUN_RUNNABLE
|
||||
|
||||
override val setting: AbstractSetting? = null
|
||||
|
||||
override val isEditable: Boolean
|
||||
get() = worksDuringEmulation || !NativeLibrary.IsRunning()
|
||||
}
|
|
@ -1,107 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model.view;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import org.dolphinemu.dolphinemu.NativeLibrary;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
|
||||
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsAdapter;
|
||||
|
||||
/**
|
||||
* ViewModel abstraction for an Item in the RecyclerView powering SettingsFragments.
|
||||
* Most of them correspond to a single line in an INI file, but there are a few with multiple
|
||||
* analogues and a few with none (Headers, for example, do not correspond to anything on disk.)
|
||||
*/
|
||||
public abstract class SettingsItem
|
||||
{
|
||||
public static final int TYPE_HEADER = 0;
|
||||
public static final int TYPE_SWITCH = 1;
|
||||
public static final int TYPE_SINGLE_CHOICE = 2;
|
||||
public static final int TYPE_SLIDER = 3;
|
||||
public static final int TYPE_SUBMENU = 4;
|
||||
public static final int TYPE_INPUT_MAPPING_CONTROL = 5;
|
||||
public static final int TYPE_STRING_SINGLE_CHOICE = 6;
|
||||
public static final int TYPE_SINGLE_CHOICE_DYNAMIC_DESCRIPTIONS = 8;
|
||||
public static final int TYPE_FILE_PICKER = 9;
|
||||
public static final int TYPE_RUN_RUNNABLE = 10;
|
||||
public static final int TYPE_STRING = 11;
|
||||
public static final int TYPE_HYPERLINK_HEADER = 12;
|
||||
public static final int TYPE_DATETIME_CHOICE = 13;
|
||||
|
||||
private final CharSequence mName;
|
||||
private final CharSequence mDescription;
|
||||
|
||||
/**
|
||||
* Base constructor.
|
||||
*
|
||||
* @param name A text string to be displayed as this setting's name.
|
||||
* @param description A text string to be displayed as this setting's description.
|
||||
*/
|
||||
public SettingsItem(CharSequence name, CharSequence description)
|
||||
{
|
||||
mName = name;
|
||||
mDescription = description;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param nameId Resource ID for a text string to be displayed as this setting's name.
|
||||
* @param descriptionId Resource ID for a text string to be displayed as this setting's description.
|
||||
*/
|
||||
public SettingsItem(Context context, int nameId, int descriptionId)
|
||||
{
|
||||
mName = nameId == 0 ? "" : context.getText(nameId);
|
||||
mDescription = descriptionId == 0 ? "" : context.getText(descriptionId);
|
||||
}
|
||||
|
||||
public CharSequence getName()
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
|
||||
public CharSequence getDescription()
|
||||
{
|
||||
return mDescription;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by {@link SettingsAdapter}'s onCreateViewHolder()
|
||||
* method to determine which type of ViewHolder should be created.
|
||||
*
|
||||
* @return An integer (ideally, one of the constants defined in this file)
|
||||
*/
|
||||
public abstract int getType();
|
||||
|
||||
protected abstract AbstractSetting getSetting();
|
||||
|
||||
public boolean isOverridden()
|
||||
{
|
||||
AbstractSetting setting = getSetting();
|
||||
return setting != null && setting.isOverridden();
|
||||
}
|
||||
|
||||
public boolean isEditable()
|
||||
{
|
||||
if (!NativeLibrary.IsRunning())
|
||||
return true;
|
||||
|
||||
AbstractSetting setting = getSetting();
|
||||
return setting != null && setting.isRuntimeEditable();
|
||||
}
|
||||
|
||||
public boolean hasSetting()
|
||||
{
|
||||
return getSetting() != null;
|
||||
}
|
||||
|
||||
public boolean canClear()
|
||||
{
|
||||
return hasSetting();
|
||||
}
|
||||
|
||||
public void clear(Settings settings)
|
||||
{
|
||||
getSetting().delete(settings);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model.view
|
||||
|
||||
import android.content.Context
|
||||
import org.dolphinemu.dolphinemu.NativeLibrary
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractSetting
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings
|
||||
|
||||
/**
|
||||
* ViewModel abstraction for an Item in the RecyclerView powering SettingsFragments.
|
||||
* Most of them correspond to a single line in an INI file, but there are a few with multiple
|
||||
* analogues and a few with none (Headers, for example, do not correspond to anything on disk.)
|
||||
*/
|
||||
abstract class SettingsItem {
|
||||
val name: CharSequence
|
||||
val description: CharSequence?
|
||||
|
||||
/**
|
||||
* Base constructor.
|
||||
*
|
||||
* @param name A text string to be displayed as this Setting's name.
|
||||
* @param description A text string to be displayed as this Setting's description.
|
||||
*/
|
||||
constructor(name: CharSequence, description: CharSequence?) {
|
||||
this.name = name
|
||||
this.description = description
|
||||
}
|
||||
|
||||
/**
|
||||
* @param nameId Resource ID for a text string to be displayed as this Setting's name.
|
||||
* @param descriptionId Resource ID for a text string to be displayed as this Setting's description.
|
||||
*/
|
||||
constructor(context: Context, nameId: Int, descriptionId: Int) {
|
||||
name = if (nameId == 0) "" else context.getText(nameId)
|
||||
description = if (descriptionId == 0) "" else context.getText(descriptionId)
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by [SettingsAdapter]'s onCreateViewHolder()
|
||||
* method to determine which type of ViewHolder should be created.
|
||||
*
|
||||
* @return An integer (ideally, one of the constants defined in this file)
|
||||
*/
|
||||
abstract val type: Int
|
||||
|
||||
abstract val setting: AbstractSetting?
|
||||
|
||||
val isOverridden: Boolean
|
||||
get() {
|
||||
val setting = setting
|
||||
return setting != null && setting.isOverridden
|
||||
}
|
||||
|
||||
open val isEditable: Boolean
|
||||
get() {
|
||||
if (!NativeLibrary.IsRunning()) return true
|
||||
val setting = setting
|
||||
return setting != null && setting.isRuntimeEditable
|
||||
}
|
||||
|
||||
private fun hasSetting(): Boolean {
|
||||
return setting != null
|
||||
}
|
||||
|
||||
open fun canClear(): Boolean {
|
||||
return hasSetting()
|
||||
}
|
||||
|
||||
open fun clear(settings: Settings) {
|
||||
setting!!.delete(settings)
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val TYPE_HEADER = 0
|
||||
const val TYPE_SWITCH = 1
|
||||
const val TYPE_SINGLE_CHOICE = 2
|
||||
const val TYPE_SLIDER = 3
|
||||
const val TYPE_SUBMENU = 4
|
||||
const val TYPE_INPUT_MAPPING_CONTROL = 5
|
||||
const val TYPE_STRING_SINGLE_CHOICE = 6
|
||||
const val TYPE_SINGLE_CHOICE_DYNAMIC_DESCRIPTIONS = 8
|
||||
const val TYPE_FILE_PICKER = 9
|
||||
const val TYPE_RUN_RUNNABLE = 10
|
||||
const val TYPE_STRING = 11
|
||||
const val TYPE_HYPERLINK_HEADER = 12
|
||||
const val TYPE_DATETIME_CHOICE = 13
|
||||
}
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model.view;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractIntSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
|
||||
import org.dolphinemu.dolphinemu.features.settings.ui.MenuTag;
|
||||
|
||||
public final class SingleChoiceSetting extends SettingsItem
|
||||
{
|
||||
private AbstractIntSetting mSetting;
|
||||
|
||||
private int mChoicesId;
|
||||
private int mValuesId;
|
||||
private MenuTag menuTag;
|
||||
|
||||
public SingleChoiceSetting(Context context, AbstractIntSetting setting, int titleId,
|
||||
int descriptionId, int choicesId, int valuesId, MenuTag menuTag)
|
||||
{
|
||||
super(context, titleId, descriptionId);
|
||||
mSetting = setting;
|
||||
mValuesId = valuesId;
|
||||
mChoicesId = choicesId;
|
||||
this.menuTag = menuTag;
|
||||
}
|
||||
|
||||
public SingleChoiceSetting(Context context, AbstractIntSetting setting, int titleId,
|
||||
int descriptionId, int choicesId, int valuesId)
|
||||
{
|
||||
this(context, setting, titleId, descriptionId, choicesId, valuesId, null);
|
||||
}
|
||||
|
||||
public int getChoicesId()
|
||||
{
|
||||
return mChoicesId;
|
||||
}
|
||||
|
||||
public int getValuesId()
|
||||
{
|
||||
return mValuesId;
|
||||
}
|
||||
|
||||
public int getSelectedValue()
|
||||
{
|
||||
return mSetting.getInt();
|
||||
}
|
||||
|
||||
public MenuTag getMenuTag()
|
||||
{
|
||||
return menuTag;
|
||||
}
|
||||
|
||||
public void setSelectedValue(Settings settings, int selection)
|
||||
{
|
||||
mSetting.setInt(settings, selection);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getType()
|
||||
{
|
||||
return TYPE_SINGLE_CHOICE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractSetting getSetting()
|
||||
{
|
||||
return mSetting;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
package org.dolphinemu.dolphinemu.features.settings.model.view
|
||||
|
||||
import android.content.Context
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractIntSetting
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractSetting
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings
|
||||
import org.dolphinemu.dolphinemu.features.settings.ui.MenuTag
|
||||
|
||||
class SingleChoiceSetting(
|
||||
context: Context,
|
||||
private val intSetting: AbstractIntSetting,
|
||||
titleId: Int,
|
||||
descriptionId: Int,
|
||||
val choicesId: Int,
|
||||
val valuesId: Int,
|
||||
val menuTag: MenuTag? = null
|
||||
) : SettingsItem(context, titleId, descriptionId) {
|
||||
override val type: Int = TYPE_SINGLE_CHOICE
|
||||
|
||||
override val setting: AbstractSetting
|
||||
get() = intSetting
|
||||
|
||||
val selectedValue: Int
|
||||
get() = intSetting.int
|
||||
|
||||
fun setSelectedValue(settings: Settings?, selection: Int) {
|
||||
intSetting.setInt(settings!!, selection)
|
||||
}
|
||||
}
|
|
@ -1,89 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model.view;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractIntSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
|
||||
import org.dolphinemu.dolphinemu.features.settings.ui.MenuTag;
|
||||
|
||||
public final class SingleChoiceSettingDynamicDescriptions extends SettingsItem
|
||||
{
|
||||
private AbstractIntSetting mSetting;
|
||||
|
||||
private int mChoicesId;
|
||||
private int mValuesId;
|
||||
private int mDescriptionChoicesId;
|
||||
private int mDescriptionValuesId;
|
||||
private MenuTag menuTag;
|
||||
|
||||
public SingleChoiceSettingDynamicDescriptions(Context context, AbstractIntSetting setting,
|
||||
int titleId, int descriptionId, int choicesId, int valuesId, int descriptionChoicesId,
|
||||
int descriptionValuesId, MenuTag menuTag)
|
||||
{
|
||||
super(context, titleId, descriptionId);
|
||||
mSetting = setting;
|
||||
mValuesId = valuesId;
|
||||
mChoicesId = choicesId;
|
||||
mDescriptionChoicesId = descriptionChoicesId;
|
||||
mDescriptionValuesId = descriptionValuesId;
|
||||
this.menuTag = menuTag;
|
||||
}
|
||||
|
||||
public SingleChoiceSettingDynamicDescriptions(Context context, AbstractIntSetting setting,
|
||||
int titleId, int descriptionId, int choicesId, int valuesId, int descriptionChoicesId,
|
||||
int descriptionValuesId)
|
||||
{
|
||||
this(context, setting, titleId, descriptionId, choicesId, valuesId, descriptionChoicesId,
|
||||
descriptionValuesId, null);
|
||||
}
|
||||
|
||||
public int getChoicesId()
|
||||
{
|
||||
return mChoicesId;
|
||||
}
|
||||
|
||||
public int getValuesId()
|
||||
{
|
||||
return mValuesId;
|
||||
}
|
||||
|
||||
public int getDescriptionChoicesId()
|
||||
{
|
||||
return mDescriptionChoicesId;
|
||||
}
|
||||
|
||||
public int getDescriptionValuesId()
|
||||
{
|
||||
return mDescriptionValuesId;
|
||||
}
|
||||
|
||||
public int getSelectedValue()
|
||||
{
|
||||
return mSetting.getInt();
|
||||
}
|
||||
|
||||
public MenuTag getMenuTag()
|
||||
{
|
||||
return menuTag;
|
||||
}
|
||||
|
||||
public void setSelectedValue(Settings settings, int selection)
|
||||
{
|
||||
mSetting.setInt(settings, selection);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getType()
|
||||
{
|
||||
return TYPE_SINGLE_CHOICE_DYNAMIC_DESCRIPTIONS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractSetting getSetting()
|
||||
{
|
||||
return mSetting;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model.view
|
||||
|
||||
import android.content.Context
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractIntSetting
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings
|
||||
|
||||
class SingleChoiceSettingDynamicDescriptions(
|
||||
context: Context,
|
||||
override val setting: AbstractIntSetting,
|
||||
titleId: Int,
|
||||
descriptionId: Int,
|
||||
val choicesId: Int,
|
||||
val valuesId: Int,
|
||||
val descriptionChoicesId: Int,
|
||||
val descriptionValuesId: Int,
|
||||
) : SettingsItem(context, titleId, descriptionId) {
|
||||
override val type: Int = TYPE_SINGLE_CHOICE_DYNAMIC_DESCRIPTIONS
|
||||
|
||||
val selectedValue: Int
|
||||
get() = setting.int
|
||||
|
||||
fun setSelectedValue(settings: Settings, selection: Int) {
|
||||
setting.setInt(settings, selection)
|
||||
}
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model.view;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
|
||||
|
||||
public abstract class SliderSetting extends SettingsItem
|
||||
{
|
||||
private int mMin;
|
||||
private int mMax;
|
||||
private String mUnits;
|
||||
private int mStepSize;
|
||||
|
||||
public SliderSetting(Context context, int nameId, int descriptionId, int min, int max,
|
||||
String units, int stepSize)
|
||||
{
|
||||
super(context, nameId, descriptionId);
|
||||
mMin = min;
|
||||
mMax = max;
|
||||
mUnits = units;
|
||||
mStepSize = stepSize;
|
||||
}
|
||||
|
||||
public SliderSetting(CharSequence name, CharSequence description, int min, int max, String units)
|
||||
{
|
||||
super(name, description);
|
||||
mMin = min;
|
||||
mMax = max;
|
||||
mUnits = units;
|
||||
}
|
||||
|
||||
public abstract int getSelectedValue();
|
||||
|
||||
public int getMin()
|
||||
{
|
||||
return mMin;
|
||||
}
|
||||
|
||||
public int getMax()
|
||||
{
|
||||
return mMax;
|
||||
}
|
||||
|
||||
public String getUnits()
|
||||
{
|
||||
return mUnits;
|
||||
}
|
||||
|
||||
public int getStepSize()
|
||||
{
|
||||
return mStepSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getType()
|
||||
{
|
||||
return TYPE_SLIDER;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model.view
|
||||
|
||||
import android.content.Context
|
||||
|
||||
abstract class SliderSetting : SettingsItem {
|
||||
override val type: Int = TYPE_SLIDER
|
||||
|
||||
var min: Int
|
||||
private set
|
||||
var max: Int
|
||||
private set
|
||||
var units: String?
|
||||
private set
|
||||
var stepSize = 0
|
||||
private set
|
||||
|
||||
constructor(
|
||||
context: Context,
|
||||
nameId: Int,
|
||||
descriptionId: Int,
|
||||
min: Int,
|
||||
max: Int,
|
||||
units: String?,
|
||||
stepSize: Int
|
||||
) : super(context, nameId, descriptionId) {
|
||||
this.min = min
|
||||
this.max = max
|
||||
this.units = units
|
||||
this.stepSize = stepSize
|
||||
}
|
||||
|
||||
constructor(
|
||||
name: CharSequence,
|
||||
description: CharSequence?,
|
||||
min: Int,
|
||||
max: Int,
|
||||
units: String?
|
||||
) : super(name, description) {
|
||||
this.min = min
|
||||
this.max = max
|
||||
this.units = units
|
||||
}
|
||||
|
||||
abstract val selectedValue: Int
|
||||
}
|
|
@ -1,153 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model.view;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import org.dolphinemu.dolphinemu.DolphinApplication;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractStringSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
|
||||
import org.dolphinemu.dolphinemu.features.settings.ui.MenuTag;
|
||||
|
||||
public class StringSingleChoiceSetting extends SettingsItem
|
||||
{
|
||||
private final AbstractStringSetting mSetting;
|
||||
|
||||
protected String[] mChoices;
|
||||
protected String[] mValues;
|
||||
private final MenuTag mMenuTag;
|
||||
private int mNoChoicesAvailableString = 0;
|
||||
|
||||
public StringSingleChoiceSetting(Context context, AbstractStringSetting setting, int titleId,
|
||||
int descriptionId, String[] choices, String[] values, MenuTag menuTag)
|
||||
{
|
||||
super(context, titleId, descriptionId);
|
||||
mSetting = setting;
|
||||
mChoices = choices;
|
||||
mValues = values;
|
||||
mMenuTag = menuTag;
|
||||
}
|
||||
|
||||
public StringSingleChoiceSetting(Context context, AbstractStringSetting setting, int titleId,
|
||||
int descriptionId, String[] choices, String[] values)
|
||||
{
|
||||
this(context, setting, titleId, descriptionId, choices, values, null);
|
||||
}
|
||||
|
||||
public StringSingleChoiceSetting(Context context, AbstractStringSetting setting, int titleId,
|
||||
int descriptionId, String[] choices, String[] values, int noChoicesAvailableString)
|
||||
{
|
||||
this(context, setting, titleId, descriptionId, choices, values, null);
|
||||
mNoChoicesAvailableString = noChoicesAvailableString;
|
||||
}
|
||||
|
||||
public StringSingleChoiceSetting(Context context, AbstractStringSetting setting, int titleId,
|
||||
int descriptionId, int choicesId, int valuesId, MenuTag menuTag)
|
||||
{
|
||||
super(context, titleId, descriptionId);
|
||||
mSetting = setting;
|
||||
mChoices = DolphinApplication.getAppContext().getResources().getStringArray(choicesId);
|
||||
mValues = DolphinApplication.getAppContext().getResources().getStringArray(valuesId);
|
||||
mMenuTag = menuTag;
|
||||
}
|
||||
|
||||
public StringSingleChoiceSetting(Context context, AbstractStringSetting setting, int titleId,
|
||||
int descriptionId, int choicesId, int valuesId)
|
||||
{
|
||||
this(context, setting, titleId, descriptionId, choicesId, valuesId, null);
|
||||
}
|
||||
|
||||
public String[] getChoices()
|
||||
{
|
||||
return mChoices;
|
||||
}
|
||||
|
||||
public String[] getValues()
|
||||
{
|
||||
return mValues;
|
||||
}
|
||||
|
||||
public String getChoiceAt(int index)
|
||||
{
|
||||
if (mChoices == null)
|
||||
return null;
|
||||
|
||||
if (index >= 0 && index < mChoices.length)
|
||||
{
|
||||
return mChoices[index];
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public String getValueAt(int index)
|
||||
{
|
||||
if (mValues == null)
|
||||
return null;
|
||||
|
||||
if (index >= 0 && index < mValues.length)
|
||||
{
|
||||
return mValues[index];
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public String getSelectedChoice()
|
||||
{
|
||||
return getChoiceAt(getSelectedValueIndex());
|
||||
}
|
||||
|
||||
public String getSelectedValue()
|
||||
{
|
||||
return mSetting.getString();
|
||||
}
|
||||
|
||||
public int getSelectedValueIndex()
|
||||
{
|
||||
String selectedValue = getSelectedValue();
|
||||
for (int i = 0; i < mValues.length; i++)
|
||||
{
|
||||
if (mValues[i].equals(selectedValue))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public MenuTag getMenuTag()
|
||||
{
|
||||
return mMenuTag;
|
||||
}
|
||||
|
||||
public int getNoChoicesAvailableString()
|
||||
{
|
||||
return mNoChoicesAvailableString;
|
||||
}
|
||||
|
||||
public void setSelectedValue(Settings settings, String selection)
|
||||
{
|
||||
mSetting.setString(settings, selection);
|
||||
}
|
||||
|
||||
public void refreshChoicesAndValues()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getType()
|
||||
{
|
||||
return TYPE_STRING_SINGLE_CHOICE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractSetting getSetting()
|
||||
{
|
||||
return mSetting;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model.view
|
||||
|
||||
import android.content.Context
|
||||
import org.dolphinemu.dolphinemu.DolphinApplication
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractSetting
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractStringSetting
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings
|
||||
import org.dolphinemu.dolphinemu.features.settings.ui.MenuTag
|
||||
|
||||
open class StringSingleChoiceSetting : SettingsItem {
|
||||
override val type: Int = TYPE_SINGLE_CHOICE
|
||||
|
||||
private val stringSetting: AbstractStringSetting?
|
||||
|
||||
override val setting: AbstractSetting?
|
||||
get() = stringSetting
|
||||
|
||||
var choices: Array<String?>?
|
||||
protected set
|
||||
var values: Array<String?>?
|
||||
protected set
|
||||
val menuTag: MenuTag?
|
||||
var noChoicesAvailableString = 0
|
||||
private set
|
||||
|
||||
open val selectedChoice: String?
|
||||
get() = getChoiceAt(selectedValueIndex)
|
||||
|
||||
open val selectedValue: String
|
||||
get() = stringSetting!!.string
|
||||
|
||||
@JvmOverloads
|
||||
constructor(
|
||||
context: Context,
|
||||
setting: AbstractStringSetting?,
|
||||
titleId: Int,
|
||||
descriptionId: Int,
|
||||
choices: Array<String?>?,
|
||||
values: Array<String?>?,
|
||||
menuTag: MenuTag? = null
|
||||
) : super(context, titleId, descriptionId) {
|
||||
stringSetting = setting
|
||||
this.choices = choices
|
||||
this.values = values
|
||||
this.menuTag = menuTag
|
||||
}
|
||||
|
||||
constructor(
|
||||
context: Context,
|
||||
setting: AbstractStringSetting,
|
||||
titleId: Int,
|
||||
descriptionId: Int,
|
||||
choices: Array<String?>,
|
||||
values: Array<String?>,
|
||||
noChoicesAvailableString: Int
|
||||
) : this(context, setting, titleId, descriptionId, choices, values) {
|
||||
this.noChoicesAvailableString = noChoicesAvailableString
|
||||
}
|
||||
|
||||
@JvmOverloads
|
||||
constructor(
|
||||
context: Context,
|
||||
setting: AbstractStringSetting,
|
||||
titleId: Int,
|
||||
descriptionId: Int,
|
||||
choicesId: Int,
|
||||
valuesId: Int,
|
||||
menuTag: MenuTag? = null
|
||||
) : super(context, titleId, descriptionId) {
|
||||
stringSetting = setting
|
||||
choices = DolphinApplication.getAppContext().resources.getStringArray(choicesId)
|
||||
values = DolphinApplication.getAppContext().resources.getStringArray(valuesId)
|
||||
this.menuTag = menuTag
|
||||
}
|
||||
|
||||
fun getChoiceAt(index: Int): String? {
|
||||
if (choices == null) return null
|
||||
|
||||
return if (index >= 0 && index < choices!!.size) {
|
||||
choices!![index]
|
||||
} else ""
|
||||
}
|
||||
|
||||
fun getValueAt(index: Int): String? {
|
||||
if (values == null) return null
|
||||
|
||||
return if (index >= 0 && index < values!!.size) {
|
||||
values!![index]
|
||||
} else ""
|
||||
}
|
||||
|
||||
val selectedValueIndex: Int
|
||||
get() {
|
||||
val selectedValue = selectedValue
|
||||
for (i in values!!.indices) {
|
||||
if (values!![i] == selectedValue) {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
open fun setSelectedValue(settings: Settings?, selection: String?) {
|
||||
stringSetting!!.setString(settings!!, selection!!)
|
||||
}
|
||||
|
||||
open fun refreshChoicesAndValues() {}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model.view;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.ui.MenuTag;
|
||||
|
||||
public final class SubmenuSetting extends SettingsItem
|
||||
{
|
||||
private MenuTag mMenuKey;
|
||||
|
||||
public SubmenuSetting(Context context, int titleId, MenuTag menuKey)
|
||||
{
|
||||
super(context, titleId, 0);
|
||||
mMenuKey = menuKey;
|
||||
}
|
||||
|
||||
public MenuTag getMenuKey()
|
||||
{
|
||||
return mMenuKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getType()
|
||||
{
|
||||
return TYPE_SUBMENU;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractSetting getSetting()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model.view
|
||||
|
||||
import android.content.Context
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractSetting
|
||||
import org.dolphinemu.dolphinemu.features.settings.ui.MenuTag
|
||||
|
||||
class SubmenuSetting(
|
||||
context: Context,
|
||||
titleId: Int,
|
||||
val menuKey: MenuTag
|
||||
) : SettingsItem(context, titleId, 0) {
|
||||
override val type: Int = TYPE_SUBMENU
|
||||
|
||||
override val setting: AbstractSetting? = null
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model.view;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractBooleanSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
|
||||
|
||||
public class SwitchSetting extends SettingsItem
|
||||
{
|
||||
protected AbstractBooleanSetting mSetting;
|
||||
|
||||
public SwitchSetting(Context context, AbstractBooleanSetting setting, int titleId,
|
||||
int descriptionId)
|
||||
{
|
||||
super(context, titleId, descriptionId);
|
||||
mSetting = setting;
|
||||
}
|
||||
|
||||
public SwitchSetting(AbstractBooleanSetting setting, CharSequence title,
|
||||
CharSequence description)
|
||||
{
|
||||
super(title, description);
|
||||
mSetting = setting;
|
||||
}
|
||||
|
||||
public boolean isChecked()
|
||||
{
|
||||
return mSetting.getBoolean();
|
||||
}
|
||||
|
||||
public void setChecked(Settings settings, boolean checked)
|
||||
{
|
||||
mSetting.setBoolean(settings, checked);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getType()
|
||||
{
|
||||
return TYPE_SWITCH;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractSetting getSetting()
|
||||
{
|
||||
return mSetting;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model.view
|
||||
|
||||
import android.content.Context
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractBooleanSetting
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractSetting
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings
|
||||
|
||||
open class SwitchSetting : SettingsItem {
|
||||
override val type: Int = TYPE_SWITCH
|
||||
|
||||
protected var booleanSetting: AbstractBooleanSetting
|
||||
|
||||
override val setting: AbstractSetting
|
||||
get() = booleanSetting
|
||||
|
||||
constructor(
|
||||
context: Context,
|
||||
setting: AbstractBooleanSetting,
|
||||
titleId: Int,
|
||||
descriptionId: Int
|
||||
) : super(context, titleId, descriptionId) {
|
||||
booleanSetting = setting
|
||||
}
|
||||
|
||||
constructor(
|
||||
setting: AbstractBooleanSetting,
|
||||
title: CharSequence?,
|
||||
description: CharSequence?
|
||||
) : super(title!!, description) {
|
||||
booleanSetting = setting
|
||||
}
|
||||
|
||||
open val isChecked: Boolean
|
||||
get() = booleanSetting.boolean
|
||||
|
||||
open fun setChecked(settings: Settings?, checked: Boolean) {
|
||||
booleanSetting.setBoolean(settings!!, checked)
|
||||
}
|
||||
}
|
|
@ -1,165 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.ui;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.dolphinemu.dolphinemu.features.input.model.controlleremu.EmulatedController;
|
||||
|
||||
public enum MenuTag
|
||||
{
|
||||
SETTINGS("settings"),
|
||||
CONFIG("config"),
|
||||
CONFIG_GENERAL("config_general"),
|
||||
CONFIG_INTERFACE("config_interface"),
|
||||
CONFIG_AUDIO("config_audio"),
|
||||
CONFIG_PATHS("config_paths"),
|
||||
CONFIG_GAME_CUBE("config_gamecube"),
|
||||
CONFIG_SERIALPORT1("config_serialport1"),
|
||||
CONFIG_WII("config_wii"),
|
||||
CONFIG_ADVANCED("config_advanced"),
|
||||
CONFIG_LOG("config_log"),
|
||||
DEBUG("debug"),
|
||||
GRAPHICS("graphics"),
|
||||
ENHANCEMENTS("enhancements"),
|
||||
STEREOSCOPY("stereoscopy"),
|
||||
HACKS("hacks"),
|
||||
STATISTICS("statistics"),
|
||||
ADVANCED_GRAPHICS("advanced_graphics"),
|
||||
GCPAD_TYPE("gc_pad_type"),
|
||||
WIIMOTE("wiimote"),
|
||||
WIIMOTE_EXTENSION("wiimote_extension"),
|
||||
GCPAD_1("gcpad", 0),
|
||||
GCPAD_2("gcpad", 1),
|
||||
GCPAD_3("gcpad", 2),
|
||||
GCPAD_4("gcpad", 3),
|
||||
WIIMOTE_1("wiimote", 0),
|
||||
WIIMOTE_2("wiimote", 1),
|
||||
WIIMOTE_3("wiimote", 2),
|
||||
WIIMOTE_4("wiimote", 3),
|
||||
WIIMOTE_EXTENSION_1("wiimote_extension", 0),
|
||||
WIIMOTE_EXTENSION_2("wiimote_extension", 1),
|
||||
WIIMOTE_EXTENSION_3("wiimote_extension", 2),
|
||||
WIIMOTE_EXTENSION_4("wiimote_extension", 3),
|
||||
WIIMOTE_GENERAL_1("wiimote_general", 0),
|
||||
WIIMOTE_GENERAL_2("wiimote_general", 1),
|
||||
WIIMOTE_GENERAL_3("wiimote_general", 2),
|
||||
WIIMOTE_GENERAL_4("wiimote_general", 3),
|
||||
WIIMOTE_MOTION_SIMULATION_1("wiimote_motion_simulation", 0),
|
||||
WIIMOTE_MOTION_SIMULATION_2("wiimote_motion_simulation", 1),
|
||||
WIIMOTE_MOTION_SIMULATION_3("wiimote_motion_simulation", 2),
|
||||
WIIMOTE_MOTION_SIMULATION_4("wiimote_motion_simulation", 3),
|
||||
WIIMOTE_MOTION_INPUT_1("wiimote_motion_input", 0),
|
||||
WIIMOTE_MOTION_INPUT_2("wiimote_motion_input", 1),
|
||||
WIIMOTE_MOTION_INPUT_3("wiimote_motion_input", 2),
|
||||
WIIMOTE_MOTION_INPUT_4("wiimote_motion_input", 3);
|
||||
|
||||
private String tag;
|
||||
private int subType = -1;
|
||||
|
||||
MenuTag(String tag)
|
||||
{
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
MenuTag(String tag, int subtype)
|
||||
{
|
||||
this.tag = tag;
|
||||
this.subType = subtype;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
if (subType != -1)
|
||||
{
|
||||
return tag + subType;
|
||||
}
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
public String getTag()
|
||||
{
|
||||
return tag;
|
||||
}
|
||||
|
||||
public int getSubType()
|
||||
{
|
||||
return subType;
|
||||
}
|
||||
|
||||
public EmulatedController getCorrespondingEmulatedController()
|
||||
{
|
||||
if (isGCPadMenu())
|
||||
return EmulatedController.getGcPad(getSubType());
|
||||
else if (isWiimoteMenu())
|
||||
return EmulatedController.getWiimote(getSubType());
|
||||
else
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public boolean isSerialPort1Menu()
|
||||
{
|
||||
return this == CONFIG_SERIALPORT1;
|
||||
}
|
||||
|
||||
public boolean isGCPadMenu()
|
||||
{
|
||||
return this == GCPAD_1 || this == GCPAD_2 || this == GCPAD_3 || this == GCPAD_4;
|
||||
}
|
||||
|
||||
public boolean isWiimoteMenu()
|
||||
{
|
||||
return this == WIIMOTE_1 || this == WIIMOTE_2 || this == WIIMOTE_3 || this == WIIMOTE_4;
|
||||
}
|
||||
|
||||
public boolean isWiimoteExtensionMenu()
|
||||
{
|
||||
return this == WIIMOTE_EXTENSION_1 || this == WIIMOTE_EXTENSION_2
|
||||
|| this == WIIMOTE_EXTENSION_3 || this == WIIMOTE_EXTENSION_4;
|
||||
}
|
||||
|
||||
public static MenuTag getGCPadMenuTag(int subtype)
|
||||
{
|
||||
return getMenuTag("gcpad", subtype);
|
||||
}
|
||||
|
||||
public static MenuTag getWiimoteMenuTag(int subtype)
|
||||
{
|
||||
return getMenuTag("wiimote", subtype);
|
||||
}
|
||||
|
||||
public static MenuTag getWiimoteExtensionMenuTag(int subtype)
|
||||
{
|
||||
return getMenuTag("wiimote_extension", subtype);
|
||||
}
|
||||
|
||||
public static MenuTag getWiimoteGeneralMenuTag(int subtype)
|
||||
{
|
||||
return getMenuTag("wiimote_general", subtype);
|
||||
}
|
||||
|
||||
public static MenuTag getWiimoteMotionSimulationMenuTag(int subtype)
|
||||
{
|
||||
return getMenuTag("wiimote_motion_simulation", subtype);
|
||||
}
|
||||
|
||||
public static MenuTag getWiimoteMotionInputMenuTag(int subtype)
|
||||
{
|
||||
return getMenuTag("wiimote_motion_input", subtype);
|
||||
}
|
||||
|
||||
private static MenuTag getMenuTag(String tag, int subtype)
|
||||
{
|
||||
for (MenuTag menuTag : MenuTag.values())
|
||||
{
|
||||
if (menuTag.tag.equals(tag) && menuTag.subType == subtype)
|
||||
return menuTag;
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("You are asking for a menu that is not available or " +
|
||||
"passing a wrong subtype");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.ui
|
||||
|
||||
import org.dolphinemu.dolphinemu.features.input.model.controlleremu.EmulatedController
|
||||
|
||||
enum class MenuTag {
|
||||
SETTINGS("settings"),
|
||||
CONFIG("config"),
|
||||
CONFIG_GENERAL("config_general"),
|
||||
CONFIG_INTERFACE("config_interface"),
|
||||
CONFIG_AUDIO("config_audio"),
|
||||
CONFIG_PATHS("config_paths"),
|
||||
CONFIG_GAME_CUBE("config_gamecube"),
|
||||
CONFIG_SERIALPORT1("config_serialport1"),
|
||||
CONFIG_WII("config_wii"),
|
||||
CONFIG_ADVANCED("config_advanced"),
|
||||
CONFIG_LOG("config_log"),
|
||||
DEBUG("debug"),
|
||||
GRAPHICS("graphics"),
|
||||
ENHANCEMENTS("enhancements"),
|
||||
STEREOSCOPY("stereoscopy"),
|
||||
HACKS("hacks"),
|
||||
STATISTICS("statistics"),
|
||||
ADVANCED_GRAPHICS("advanced_graphics"),
|
||||
GCPAD_TYPE("gc_pad_type"),
|
||||
WIIMOTE("wiimote"),
|
||||
WIIMOTE_EXTENSION("wiimote_extension"),
|
||||
GCPAD_1("gcpad", 0),
|
||||
GCPAD_2("gcpad", 1),
|
||||
GCPAD_3("gcpad", 2),
|
||||
GCPAD_4("gcpad", 3),
|
||||
WIIMOTE_1("wiimote", 0),
|
||||
WIIMOTE_2("wiimote", 1),
|
||||
WIIMOTE_3("wiimote", 2),
|
||||
WIIMOTE_4("wiimote", 3),
|
||||
WIIMOTE_EXTENSION_1("wiimote_extension", 0),
|
||||
WIIMOTE_EXTENSION_2("wiimote_extension", 1),
|
||||
WIIMOTE_EXTENSION_3("wiimote_extension", 2),
|
||||
WIIMOTE_EXTENSION_4("wiimote_extension", 3),
|
||||
WIIMOTE_GENERAL_1("wiimote_general", 0),
|
||||
WIIMOTE_GENERAL_2("wiimote_general", 1),
|
||||
WIIMOTE_GENERAL_3("wiimote_general", 2),
|
||||
WIIMOTE_GENERAL_4("wiimote_general", 3),
|
||||
WIIMOTE_MOTION_SIMULATION_1("wiimote_motion_simulation", 0),
|
||||
WIIMOTE_MOTION_SIMULATION_2("wiimote_motion_simulation", 1),
|
||||
WIIMOTE_MOTION_SIMULATION_3("wiimote_motion_simulation", 2),
|
||||
WIIMOTE_MOTION_SIMULATION_4("wiimote_motion_simulation", 3),
|
||||
WIIMOTE_MOTION_INPUT_1("wiimote_motion_input", 0),
|
||||
WIIMOTE_MOTION_INPUT_2("wiimote_motion_input", 1),
|
||||
WIIMOTE_MOTION_INPUT_3("wiimote_motion_input", 2),
|
||||
WIIMOTE_MOTION_INPUT_4("wiimote_motion_input", 3);
|
||||
|
||||
var tag: String
|
||||
private set
|
||||
var subType = -1
|
||||
private set
|
||||
|
||||
constructor(tag: String) {
|
||||
this.tag = tag
|
||||
}
|
||||
|
||||
constructor(tag: String, subtype: Int) {
|
||||
this.tag = tag
|
||||
subType = subtype
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return if (subType != -1) {
|
||||
tag + subType
|
||||
} else tag
|
||||
}
|
||||
|
||||
val correspondingEmulatedController: EmulatedController
|
||||
get() = if (isGCPadMenu) EmulatedController.getGcPad(subType) else if (isWiimoteMenu) EmulatedController.getWiimote(
|
||||
subType
|
||||
) else throw UnsupportedOperationException()
|
||||
|
||||
val isSerialPort1Menu: Boolean
|
||||
get() = this == CONFIG_SERIALPORT1
|
||||
|
||||
val isGCPadMenu: Boolean
|
||||
get() = this == GCPAD_1 || this == GCPAD_2 || this == GCPAD_3 || this == GCPAD_4
|
||||
|
||||
val isWiimoteMenu: Boolean
|
||||
get() = this == WIIMOTE_1 || this == WIIMOTE_2 || this == WIIMOTE_3 || this == WIIMOTE_4
|
||||
|
||||
val isWiimoteExtensionMenu: Boolean
|
||||
get() = this == WIIMOTE_EXTENSION_1 || this == WIIMOTE_EXTENSION_2 || this == WIIMOTE_EXTENSION_3 || this == WIIMOTE_EXTENSION_4
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun getGCPadMenuTag(subtype: Int): MenuTag {
|
||||
return getMenuTag("gcpad", subtype)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getWiimoteMenuTag(subtype: Int): MenuTag {
|
||||
return getMenuTag("wiimote", subtype)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getWiimoteExtensionMenuTag(subtype: Int): MenuTag {
|
||||
return getMenuTag("wiimote_extension", subtype)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getWiimoteGeneralMenuTag(subtype: Int): MenuTag {
|
||||
return getMenuTag("wiimote_general", subtype)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getWiimoteMotionSimulationMenuTag(subtype: Int): MenuTag {
|
||||
return getMenuTag("wiimote_motion_simulation", subtype)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getWiimoteMotionInputMenuTag(subtype: Int): MenuTag {
|
||||
return getMenuTag("wiimote_motion_input", subtype)
|
||||
}
|
||||
|
||||
private fun getMenuTag(tag: String, subtype: Int): MenuTag {
|
||||
for (menuTag in values()) {
|
||||
if (menuTag.tag == tag && menuTag.subType == subtype) return menuTag
|
||||
}
|
||||
throw IllegalArgumentException(
|
||||
"You are asking for a menu that is not available or " +
|
||||
"passing a wrong subtype"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,401 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.ui;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.graphics.Insets;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.core.view.WindowCompat;
|
||||
import androidx.core.view.WindowInsetsCompat;
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
import com.google.android.material.appbar.CollapsingToolbarLayout;
|
||||
import com.google.android.material.color.MaterialColors;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
|
||||
import org.dolphinemu.dolphinemu.NativeLibrary;
|
||||
import org.dolphinemu.dolphinemu.R;
|
||||
import org.dolphinemu.dolphinemu.databinding.ActivitySettingsBinding;
|
||||
import org.dolphinemu.dolphinemu.ui.main.MainPresenter;
|
||||
import org.dolphinemu.dolphinemu.utils.FileBrowserHelper;
|
||||
import org.dolphinemu.dolphinemu.utils.InsetsHelper;
|
||||
import org.dolphinemu.dolphinemu.utils.ThemeHelper;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public final class SettingsActivity extends AppCompatActivity implements SettingsActivityView
|
||||
{
|
||||
private static final String ARG_MENU_TAG = "menu_tag";
|
||||
private static final String ARG_GAME_ID = "game_id";
|
||||
private static final String ARG_REVISION = "revision";
|
||||
private static final String ARG_IS_WII = "is_wii";
|
||||
private static final String KEY_MAPPING_ALL_DEVICES = "all_devices";
|
||||
private static final String FRAGMENT_TAG = "settings";
|
||||
private static final String FRAGMENT_DIALOG_TAG = "settings_dialog";
|
||||
|
||||
private SettingsActivityPresenter mPresenter;
|
||||
private AlertDialog dialog;
|
||||
private CollapsingToolbarLayout mToolbarLayout;
|
||||
|
||||
private ActivitySettingsBinding mBinding;
|
||||
|
||||
private boolean mMappingAllDevices = false;
|
||||
|
||||
public static void launch(Context context, MenuTag menuTag, String gameId, int revision,
|
||||
boolean isWii)
|
||||
{
|
||||
Intent settings = new Intent(context, SettingsActivity.class);
|
||||
settings.putExtra(ARG_MENU_TAG, menuTag);
|
||||
settings.putExtra(ARG_GAME_ID, gameId);
|
||||
settings.putExtra(ARG_REVISION, revision);
|
||||
settings.putExtra(ARG_IS_WII, isWii);
|
||||
context.startActivity(settings);
|
||||
}
|
||||
|
||||
public static void launch(Context context, MenuTag menuTag)
|
||||
{
|
||||
Intent settings = new Intent(context, SettingsActivity.class);
|
||||
settings.putExtra(ARG_MENU_TAG, menuTag);
|
||||
settings.putExtra(ARG_IS_WII, !NativeLibrary.IsRunning() || NativeLibrary.IsEmulatingWii());
|
||||
context.startActivity(settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
ThemeHelper.setTheme(this);
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
// If we came here from the game list, we don't want to rescan when returning to the game list.
|
||||
// But if we came here after UserDataActivity restarted the app, we do want to rescan.
|
||||
if (savedInstanceState == null)
|
||||
{
|
||||
MainPresenter.skipRescanningLibrary();
|
||||
}
|
||||
else
|
||||
{
|
||||
mMappingAllDevices = savedInstanceState.getBoolean(KEY_MAPPING_ALL_DEVICES);
|
||||
}
|
||||
|
||||
mBinding = ActivitySettingsBinding.inflate(getLayoutInflater());
|
||||
setContentView(mBinding.getRoot());
|
||||
|
||||
WindowCompat.setDecorFitsSystemWindows(getWindow(), false);
|
||||
|
||||
Intent launcher = getIntent();
|
||||
String gameID = launcher.getStringExtra(ARG_GAME_ID);
|
||||
if (gameID == null)
|
||||
gameID = "";
|
||||
int revision = launcher.getIntExtra(ARG_REVISION, 0);
|
||||
boolean isWii = launcher.getBooleanExtra(ARG_IS_WII, true);
|
||||
MenuTag menuTag = (MenuTag) launcher.getSerializableExtra(ARG_MENU_TAG);
|
||||
|
||||
mPresenter = new SettingsActivityPresenter(this, getSettings());
|
||||
mPresenter.onCreate(savedInstanceState, menuTag, gameID, revision, isWii, this);
|
||||
|
||||
mToolbarLayout = mBinding.toolbarSettingsLayout;
|
||||
setSupportActionBar(mBinding.toolbarSettings);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
// TODO: Remove this when CollapsingToolbarLayouts are fixed by Google
|
||||
// https://github.com/material-components/material-components-android/issues/1310
|
||||
ViewCompat.setOnApplyWindowInsetsListener(mToolbarLayout, null);
|
||||
|
||||
setInsets();
|
||||
ThemeHelper.enableScrollTint(this, mBinding.toolbarSettings, mBinding.appbarSettings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu)
|
||||
{
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.menu_settings, menu);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(@NonNull Bundle outState)
|
||||
{
|
||||
// Critical: If super method is not called, rotations will be busted.
|
||||
super.onSaveInstanceState(outState);
|
||||
|
||||
mPresenter.saveState(outState);
|
||||
|
||||
outState.putBoolean(KEY_MAPPING_ALL_DEVICES, mMappingAllDevices);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart()
|
||||
{
|
||||
super.onStart();
|
||||
mPresenter.onStart();
|
||||
}
|
||||
|
||||
/**
|
||||
* If this is called, the user has left the settings screen (potentially through the
|
||||
* home button) and will expect their changes to be persisted.
|
||||
*/
|
||||
@Override
|
||||
protected void onStop()
|
||||
{
|
||||
super.onStop();
|
||||
mPresenter.onStop(isFinishing());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy()
|
||||
{
|
||||
super.onDestroy();
|
||||
mPresenter.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showSettingsFragment(MenuTag menuTag, Bundle extras, boolean addToStack,
|
||||
String gameID)
|
||||
{
|
||||
if (!addToStack && getFragment() != null)
|
||||
return;
|
||||
|
||||
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
|
||||
|
||||
if (addToStack)
|
||||
{
|
||||
if (areSystemAnimationsEnabled())
|
||||
{
|
||||
transaction.setCustomAnimations(
|
||||
R.anim.anim_settings_fragment_in,
|
||||
R.anim.anim_settings_fragment_out,
|
||||
0,
|
||||
R.anim.anim_pop_settings_fragment_out);
|
||||
}
|
||||
|
||||
transaction.addToBackStack(null);
|
||||
}
|
||||
transaction.replace(R.id.frame_content_settings,
|
||||
SettingsFragment.newInstance(menuTag, gameID, extras), FRAGMENT_TAG);
|
||||
|
||||
transaction.commit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showDialogFragment(DialogFragment fragment)
|
||||
{
|
||||
fragment.show(getSupportFragmentManager(), FRAGMENT_DIALOG_TAG);
|
||||
}
|
||||
|
||||
private boolean areSystemAnimationsEnabled()
|
||||
{
|
||||
float duration = Settings.Global.getFloat(
|
||||
getContentResolver(),
|
||||
Settings.Global.ANIMATOR_DURATION_SCALE, 1);
|
||||
float transition = Settings.Global.getFloat(
|
||||
getContentResolver(),
|
||||
Settings.Global.TRANSITION_ANIMATION_SCALE, 1);
|
||||
return duration != 0 && transition != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent result)
|
||||
{
|
||||
super.onActivityResult(requestCode, resultCode, result);
|
||||
|
||||
// If the user picked a file, as opposed to just backing out.
|
||||
if (resultCode == RESULT_OK)
|
||||
{
|
||||
if (requestCode != MainPresenter.REQUEST_DIRECTORY)
|
||||
{
|
||||
Uri uri = canonicalizeIfPossible(result.getData());
|
||||
|
||||
Set<String> validExtensions = requestCode == MainPresenter.REQUEST_GAME_FILE ?
|
||||
FileBrowserHelper.GAME_EXTENSIONS : FileBrowserHelper.RAW_EXTENSION;
|
||||
|
||||
int flags = Intent.FLAG_GRANT_READ_URI_PERMISSION;
|
||||
if (requestCode != MainPresenter.REQUEST_GAME_FILE)
|
||||
flags |= Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
|
||||
int takeFlags = flags & result.getFlags();
|
||||
|
||||
FileBrowserHelper.runAfterExtensionCheck(this, uri, validExtensions, () ->
|
||||
{
|
||||
getContentResolver().takePersistableUriPermission(uri, takeFlags);
|
||||
getFragment().getAdapter().onFilePickerConfirmation(uri.toString());
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
String path = FileBrowserHelper.getSelectedPath(result);
|
||||
getFragment().getAdapter().onFilePickerConfirmation(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private Uri canonicalizeIfPossible(@NonNull Uri uri)
|
||||
{
|
||||
Uri canonicalizedUri = getContentResolver().canonicalize(uri);
|
||||
return canonicalizedUri != null ? canonicalizedUri : uri;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showLoading()
|
||||
{
|
||||
if (dialog == null)
|
||||
{
|
||||
dialog = new MaterialAlertDialogBuilder(this)
|
||||
.setTitle(getString(R.string.load_settings))
|
||||
.setView(R.layout.dialog_indeterminate_progress)
|
||||
.create();
|
||||
}
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideLoading()
|
||||
{
|
||||
dialog.dismiss();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showGameIniJunkDeletionQuestion()
|
||||
{
|
||||
new MaterialAlertDialogBuilder(this)
|
||||
.setTitle(getString(R.string.game_ini_junk_title))
|
||||
.setMessage(getString(R.string.game_ini_junk_question))
|
||||
.setPositiveButton(R.string.yes, (dialogInterface, i) -> mPresenter.clearGameSettings())
|
||||
.setNegativeButton(R.string.no, null)
|
||||
.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.dolphinemu.dolphinemu.features.settings.model.Settings getSettings()
|
||||
{
|
||||
return new ViewModelProvider(this).get(SettingsViewModel.class).getSettings();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSettingsFileLoaded(
|
||||
org.dolphinemu.dolphinemu.features.settings.model.Settings settings)
|
||||
{
|
||||
SettingsFragmentView fragment = getFragment();
|
||||
|
||||
if (fragment != null)
|
||||
{
|
||||
fragment.onSettingsFileLoaded(settings);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSettingsFileNotFound()
|
||||
{
|
||||
SettingsFragmentView fragment = getFragment();
|
||||
|
||||
if (fragment != null)
|
||||
{
|
||||
fragment.loadDefaultSettings();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showToastMessage(String message)
|
||||
{
|
||||
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSettingChanged()
|
||||
{
|
||||
mPresenter.onSettingChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onControllerSettingsChanged()
|
||||
{
|
||||
getFragment().onControllerSettingsChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMenuTagAction(@NonNull MenuTag menuTag, int value)
|
||||
{
|
||||
mPresenter.onMenuTagAction(menuTag, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasMenuTagActionForValue(@NonNull MenuTag menuTag, int value)
|
||||
{
|
||||
return mPresenter.hasMenuTagActionForValue(menuTag, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onSupportNavigateUp()
|
||||
{
|
||||
onBackPressed();
|
||||
return true;
|
||||
}
|
||||
|
||||
private SettingsFragment getFragment()
|
||||
{
|
||||
return (SettingsFragment) getSupportFragmentManager().findFragmentByTag(FRAGMENT_TAG);
|
||||
}
|
||||
|
||||
public void setToolbarTitle(String title)
|
||||
{
|
||||
mBinding.toolbarSettingsLayout.setTitle(title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMappingAllDevices(boolean allDevices)
|
||||
{
|
||||
mMappingAllDevices = allDevices;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMappingAllDevices()
|
||||
{
|
||||
return mMappingAllDevices;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setOldControllerSettingsWarningVisibility(boolean visible)
|
||||
{
|
||||
// We use INVISIBLE instead of GONE to avoid getting a stale height for the return value
|
||||
mBinding.oldControllerSettingsWarning.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
|
||||
return visible ? mBinding.oldControllerSettingsWarning.getHeight() : 0;
|
||||
}
|
||||
|
||||
private void setInsets()
|
||||
{
|
||||
ViewCompat.setOnApplyWindowInsetsListener(mBinding.appbarSettings, (v, windowInsets) ->
|
||||
{
|
||||
Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars());
|
||||
|
||||
InsetsHelper.insetAppBar(insets, mBinding.appbarSettings);
|
||||
|
||||
mBinding.frameContentSettings.setPadding(insets.left, 0, insets.right, 0);
|
||||
|
||||
int textPadding = getResources().getDimensionPixelSize(R.dimen.spacing_large);
|
||||
mBinding.oldControllerSettingsWarning.setPadding(textPadding + insets.left, textPadding,
|
||||
textPadding + insets.right, textPadding + insets.bottom);
|
||||
|
||||
InsetsHelper.applyNavbarWorkaround(insets.bottom, mBinding.workaroundView);
|
||||
ThemeHelper.setNavigationBarColor(this,
|
||||
MaterialColors.getColor(mBinding.appbarSettings, R.attr.colorSurface));
|
||||
|
||||
return windowInsets;
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,323 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.ui
|
||||
|
||||
import android.content.Context
|
||||
import android.content.DialogInterface
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.google.android.material.appbar.CollapsingToolbarLayout
|
||||
import com.google.android.material.color.MaterialColors
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import org.dolphinemu.dolphinemu.NativeLibrary
|
||||
import org.dolphinemu.dolphinemu.R
|
||||
import org.dolphinemu.dolphinemu.databinding.ActivitySettingsBinding
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings
|
||||
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsFragment.Companion.newInstance
|
||||
import org.dolphinemu.dolphinemu.ui.main.MainPresenter
|
||||
import org.dolphinemu.dolphinemu.utils.FileBrowserHelper
|
||||
import org.dolphinemu.dolphinemu.utils.InsetsHelper
|
||||
import org.dolphinemu.dolphinemu.utils.SerializableHelper.serializable
|
||||
import org.dolphinemu.dolphinemu.utils.ThemeHelper.enableScrollTint
|
||||
import org.dolphinemu.dolphinemu.utils.ThemeHelper.setNavigationBarColor
|
||||
import org.dolphinemu.dolphinemu.utils.ThemeHelper.setTheme
|
||||
|
||||
class SettingsActivity : AppCompatActivity(), SettingsActivityView {
|
||||
private var presenter: SettingsActivityPresenter? = null
|
||||
private var dialog: AlertDialog? = null
|
||||
private var toolbarLayout: CollapsingToolbarLayout? = null
|
||||
private var binding: ActivitySettingsBinding? = null
|
||||
|
||||
override var isMappingAllDevices = false
|
||||
|
||||
override val settings: Settings
|
||||
get() = ViewModelProvider(this)[SettingsViewModel::class.java].settings
|
||||
|
||||
private val fragment: SettingsFragment?
|
||||
get() = supportFragmentManager.findFragmentByTag(FRAGMENT_TAG) as SettingsFragment?
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
setTheme(this)
|
||||
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
// If we came here from the game list, we don't want to rescan when returning to the game list.
|
||||
// But if we came here after UserDataActivity restarted the app, we do want to rescan.
|
||||
if (savedInstanceState == null) {
|
||||
MainPresenter.skipRescanningLibrary()
|
||||
} else {
|
||||
isMappingAllDevices = savedInstanceState.getBoolean(KEY_MAPPING_ALL_DEVICES)
|
||||
}
|
||||
|
||||
binding = ActivitySettingsBinding.inflate(layoutInflater)
|
||||
setContentView(binding!!.root)
|
||||
|
||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||
|
||||
val launcher = intent
|
||||
var gameID = launcher.getStringExtra(ARG_GAME_ID)
|
||||
if (gameID == null) gameID = ""
|
||||
val revision = launcher.getIntExtra(ARG_REVISION, 0)
|
||||
val isWii = launcher.getBooleanExtra(ARG_IS_WII, true)
|
||||
val menuTag = launcher.serializable<MenuTag>(ARG_MENU_TAG)
|
||||
|
||||
presenter = SettingsActivityPresenter(this, settings)
|
||||
presenter!!.onCreate(savedInstanceState, menuTag, gameID, revision, isWii, this)
|
||||
toolbarLayout = binding!!.toolbarSettingsLayout
|
||||
setSupportActionBar(binding!!.toolbarSettings)
|
||||
supportActionBar!!.setDisplayHomeAsUpEnabled(true)
|
||||
|
||||
// TODO: Remove this when CollapsingToolbarLayouts are fixed by Google
|
||||
// https://github.com/material-components/material-components-android/issues/1310
|
||||
ViewCompat.setOnApplyWindowInsetsListener(toolbarLayout!!, null)
|
||||
setInsets()
|
||||
enableScrollTint(this, binding!!.toolbarSettings, binding!!.appbarSettings)
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
val inflater = menuInflater
|
||||
inflater.inflate(R.menu.menu_settings, menu)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
// Critical: If super method is not called, rotations will be busted.
|
||||
super.onSaveInstanceState(outState)
|
||||
presenter!!.saveState(outState)
|
||||
outState.putBoolean(KEY_MAPPING_ALL_DEVICES, isMappingAllDevices)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
presenter!!.onStart()
|
||||
}
|
||||
|
||||
/**
|
||||
* If this is called, the user has left the settings screen (potentially through the
|
||||
* home button) and will expect their changes to be persisted.
|
||||
*/
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
presenter!!.onStop(isFinishing)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
presenter!!.onDestroy()
|
||||
}
|
||||
|
||||
override fun showSettingsFragment(
|
||||
menuTag: MenuTag,
|
||||
extras: Bundle?,
|
||||
addToStack: Boolean,
|
||||
gameId: String
|
||||
) {
|
||||
if (!addToStack && fragment != null) return
|
||||
val transaction = supportFragmentManager.beginTransaction()
|
||||
if (addToStack) {
|
||||
if (areSystemAnimationsEnabled()) {
|
||||
transaction.setCustomAnimations(
|
||||
R.anim.anim_settings_fragment_in,
|
||||
R.anim.anim_settings_fragment_out,
|
||||
0,
|
||||
R.anim.anim_pop_settings_fragment_out
|
||||
)
|
||||
}
|
||||
transaction.addToBackStack(null)
|
||||
}
|
||||
transaction.replace(
|
||||
R.id.frame_content_settings,
|
||||
newInstance(menuTag, gameId, extras), FRAGMENT_TAG
|
||||
)
|
||||
transaction.commit()
|
||||
}
|
||||
|
||||
override fun showDialogFragment(fragment: DialogFragment) {
|
||||
fragment.show(supportFragmentManager, FRAGMENT_DIALOG_TAG)
|
||||
}
|
||||
|
||||
private fun areSystemAnimationsEnabled(): Boolean {
|
||||
val duration = android.provider.Settings.Global.getFloat(
|
||||
contentResolver,
|
||||
android.provider.Settings.Global.ANIMATOR_DURATION_SCALE,
|
||||
1f
|
||||
)
|
||||
val transition = android.provider.Settings.Global.getFloat(
|
||||
contentResolver,
|
||||
android.provider.Settings.Global.TRANSITION_ANIMATION_SCALE,
|
||||
1f
|
||||
)
|
||||
return duration != 0f && transition != 0f
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, result: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, result)
|
||||
|
||||
// If the user picked a file, as opposed to just backing out.
|
||||
if (resultCode == RESULT_OK) {
|
||||
if (requestCode != MainPresenter.REQUEST_DIRECTORY) {
|
||||
val uri = canonicalizeIfPossible(result!!.data!!)
|
||||
val validExtensions: Set<String> =
|
||||
if (requestCode == MainPresenter.REQUEST_GAME_FILE) FileBrowserHelper.GAME_EXTENSIONS else FileBrowserHelper.RAW_EXTENSION
|
||||
var flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||
if (requestCode != MainPresenter.REQUEST_GAME_FILE) flags =
|
||||
flags or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
||||
val takeFlags = flags and result.flags
|
||||
FileBrowserHelper.runAfterExtensionCheck(this, uri, validExtensions) {
|
||||
contentResolver.takePersistableUriPermission(uri, takeFlags)
|
||||
fragment!!.adapter!!.onFilePickerConfirmation(uri.toString())
|
||||
}
|
||||
} else {
|
||||
val path = FileBrowserHelper.getSelectedPath(result)
|
||||
fragment!!.adapter!!.onFilePickerConfirmation(path!!)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun canonicalizeIfPossible(uri: Uri): Uri {
|
||||
val canonicalizedUri = contentResolver.canonicalize(uri)
|
||||
return canonicalizedUri ?: uri
|
||||
}
|
||||
|
||||
override fun showLoading() {
|
||||
if (dialog == null) {
|
||||
dialog = MaterialAlertDialogBuilder(this)
|
||||
.setTitle(getString(R.string.load_settings))
|
||||
.setView(R.layout.dialog_indeterminate_progress)
|
||||
.create()
|
||||
}
|
||||
dialog!!.show()
|
||||
}
|
||||
|
||||
override fun hideLoading() {
|
||||
dialog!!.dismiss()
|
||||
}
|
||||
|
||||
override fun showGameIniJunkDeletionQuestion() {
|
||||
MaterialAlertDialogBuilder(this)
|
||||
.setTitle(getString(R.string.game_ini_junk_title))
|
||||
.setMessage(getString(R.string.game_ini_junk_question))
|
||||
.setPositiveButton(R.string.yes) { _: DialogInterface?, _: Int -> presenter!!.clearGameSettings() }
|
||||
.setNegativeButton(R.string.no, null)
|
||||
.show()
|
||||
}
|
||||
|
||||
override fun onSettingsFileLoaded(settings: Settings) {
|
||||
val fragment: SettingsFragmentView? = fragment
|
||||
fragment?.onSettingsFileLoaded(settings)
|
||||
}
|
||||
|
||||
override fun onSettingsFileNotFound() {
|
||||
val fragment: SettingsFragmentView? = fragment
|
||||
fragment?.loadDefaultSettings()
|
||||
}
|
||||
|
||||
override fun showToastMessage(message: String) {
|
||||
Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
override fun onSettingChanged() {
|
||||
presenter!!.onSettingChanged()
|
||||
}
|
||||
|
||||
override fun onControllerSettingsChanged() {
|
||||
fragment!!.onControllerSettingsChanged()
|
||||
}
|
||||
|
||||
override fun onMenuTagAction(menuTag: MenuTag, value: Int) {
|
||||
presenter!!.onMenuTagAction(menuTag, value)
|
||||
}
|
||||
|
||||
override fun hasMenuTagActionForValue(menuTag: MenuTag, value: Int): Boolean {
|
||||
return presenter!!.hasMenuTagActionForValue(menuTag, value)
|
||||
}
|
||||
|
||||
override fun onSupportNavigateUp(): Boolean {
|
||||
onBackPressed()
|
||||
return true
|
||||
}
|
||||
|
||||
override fun setToolbarTitle(title: String) {
|
||||
binding!!.toolbarSettingsLayout.title = title
|
||||
}
|
||||
|
||||
override fun setOldControllerSettingsWarningVisibility(visible: Boolean): Int {
|
||||
// We use INVISIBLE instead of GONE to avoid getting a stale height for the return value
|
||||
binding!!.oldControllerSettingsWarning.visibility =
|
||||
if (visible) View.VISIBLE else View.INVISIBLE
|
||||
return if (visible) binding!!.oldControllerSettingsWarning.height else 0
|
||||
}
|
||||
|
||||
private fun setInsets() {
|
||||
ViewCompat.setOnApplyWindowInsetsListener(binding!!.appbarSettings) { _: View?, windowInsets: WindowInsetsCompat ->
|
||||
val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||
|
||||
InsetsHelper.insetAppBar(insets, binding!!.appbarSettings)
|
||||
|
||||
binding!!.frameContentSettings.setPadding(insets.left, 0, insets.right, 0)
|
||||
val textPadding = resources.getDimensionPixelSize(R.dimen.spacing_large)
|
||||
binding!!.oldControllerSettingsWarning.setPadding(
|
||||
textPadding + insets.left,
|
||||
textPadding,
|
||||
textPadding + insets.right,
|
||||
textPadding + insets.bottom
|
||||
)
|
||||
|
||||
InsetsHelper.applyNavbarWorkaround(insets.bottom, binding!!.workaroundView)
|
||||
setNavigationBarColor(
|
||||
this,
|
||||
MaterialColors.getColor(binding!!.appbarSettings, R.attr.colorSurface)
|
||||
)
|
||||
|
||||
windowInsets
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val ARG_MENU_TAG = "menu_tag"
|
||||
private const val ARG_GAME_ID = "game_id"
|
||||
private const val ARG_REVISION = "revision"
|
||||
private const val ARG_IS_WII = "is_wii"
|
||||
private const val KEY_MAPPING_ALL_DEVICES = "all_devices"
|
||||
private const val FRAGMENT_TAG = "settings"
|
||||
private const val FRAGMENT_DIALOG_TAG = "settings_dialog"
|
||||
|
||||
@JvmStatic
|
||||
fun launch(
|
||||
context: Context,
|
||||
menuTag: MenuTag?,
|
||||
gameId: String?,
|
||||
revision: Int,
|
||||
isWii: Boolean
|
||||
) {
|
||||
val settings = Intent(context, SettingsActivity::class.java)
|
||||
settings.putExtra(ARG_MENU_TAG, menuTag)
|
||||
settings.putExtra(ARG_GAME_ID, gameId)
|
||||
settings.putExtra(ARG_REVISION, revision)
|
||||
settings.putExtra(ARG_IS_WII, isWii)
|
||||
context.startActivity(settings)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun launch(context: Context, menuTag: MenuTag?) {
|
||||
val settings = Intent(context, SettingsActivity::class.java)
|
||||
settings.putExtra(ARG_MENU_TAG, menuTag)
|
||||
settings.putExtra(
|
||||
ARG_IS_WII,
|
||||
!NativeLibrary.IsRunning() || NativeLibrary.IsEmulatingWii()
|
||||
)
|
||||
context.startActivity(settings)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,197 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.ui;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.app.ComponentActivity;
|
||||
|
||||
import org.dolphinemu.dolphinemu.R;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
|
||||
import org.dolphinemu.dolphinemu.utils.AfterDirectoryInitializationRunner;
|
||||
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization;
|
||||
import org.dolphinemu.dolphinemu.utils.Log;
|
||||
|
||||
public final class SettingsActivityPresenter
|
||||
{
|
||||
private static final String KEY_SHOULD_SAVE = "should_save";
|
||||
|
||||
private SettingsActivityView mView;
|
||||
|
||||
private Settings mSettings;
|
||||
|
||||
private boolean mShouldSave;
|
||||
|
||||
private MenuTag mMenuTag;
|
||||
private String mGameId;
|
||||
private int mRevision;
|
||||
private boolean mIsWii;
|
||||
private ComponentActivity mActivity;
|
||||
|
||||
SettingsActivityPresenter(SettingsActivityView view, Settings settings)
|
||||
{
|
||||
mView = view;
|
||||
mSettings = settings;
|
||||
}
|
||||
|
||||
public void onCreate(Bundle savedInstanceState, MenuTag menuTag, String gameId, int revision,
|
||||
boolean isWii, ComponentActivity activity)
|
||||
{
|
||||
this.mMenuTag = menuTag;
|
||||
this.mGameId = gameId;
|
||||
this.mRevision = revision;
|
||||
this.mIsWii = isWii;
|
||||
this.mActivity = activity;
|
||||
|
||||
mShouldSave = savedInstanceState != null && savedInstanceState.getBoolean(KEY_SHOULD_SAVE);
|
||||
}
|
||||
|
||||
public void onDestroy()
|
||||
{
|
||||
if (mSettings != null)
|
||||
{
|
||||
mSettings.close();
|
||||
mSettings = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void onStart()
|
||||
{
|
||||
prepareDolphinDirectoriesIfNeeded();
|
||||
}
|
||||
|
||||
private void loadSettingsUI()
|
||||
{
|
||||
mView.hideLoading();
|
||||
|
||||
if (!mSettings.areSettingsLoaded())
|
||||
{
|
||||
if (!TextUtils.isEmpty(mGameId))
|
||||
{
|
||||
mSettings.loadSettings(mGameId, mRevision, mIsWii);
|
||||
|
||||
if (mSettings.gameIniContainsJunk())
|
||||
{
|
||||
mView.showGameIniJunkDeletionQuestion();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mSettings.loadSettings(mIsWii);
|
||||
}
|
||||
}
|
||||
|
||||
mView.showSettingsFragment(mMenuTag, null, false, mGameId);
|
||||
mView.onSettingsFileLoaded(mSettings);
|
||||
}
|
||||
|
||||
private void prepareDolphinDirectoriesIfNeeded()
|
||||
{
|
||||
mView.showLoading();
|
||||
|
||||
new AfterDirectoryInitializationRunner().runWithLifecycle(mActivity, this::loadSettingsUI);
|
||||
}
|
||||
|
||||
public Settings getSettings()
|
||||
{
|
||||
return mSettings;
|
||||
}
|
||||
|
||||
public void clearGameSettings()
|
||||
{
|
||||
mSettings.clearGameSettings();
|
||||
onSettingChanged();
|
||||
}
|
||||
|
||||
public void onStop(boolean finishing)
|
||||
{
|
||||
if (mSettings != null && finishing && mShouldSave)
|
||||
{
|
||||
Log.debug("[SettingsActivity] Settings activity stopping. Saving settings to INI...");
|
||||
mSettings.saveSettings(mActivity);
|
||||
}
|
||||
}
|
||||
|
||||
public void onSettingChanged()
|
||||
{
|
||||
mShouldSave = true;
|
||||
}
|
||||
|
||||
public void saveState(Bundle outState)
|
||||
{
|
||||
outState.putBoolean(KEY_SHOULD_SAVE, mShouldSave);
|
||||
}
|
||||
|
||||
public boolean shouldSave()
|
||||
{
|
||||
return mShouldSave;
|
||||
}
|
||||
|
||||
public void onMenuTagAction(@NonNull MenuTag menuTag, int value)
|
||||
{
|
||||
if (menuTag.isSerialPort1Menu())
|
||||
{
|
||||
if (value != 0 && value != 255) // Not disabled or dummy
|
||||
{
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt(SettingsFragmentPresenter.ARG_SERIALPORT1_TYPE, value);
|
||||
mView.showSettingsFragment(menuTag, bundle, true, mGameId);
|
||||
}
|
||||
}
|
||||
|
||||
if (menuTag.isGCPadMenu())
|
||||
{
|
||||
if (value != 0) // Not disabled
|
||||
{
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt(SettingsFragmentPresenter.ARG_CONTROLLER_TYPE, value);
|
||||
mView.showSettingsFragment(menuTag, bundle, true, mGameId);
|
||||
}
|
||||
}
|
||||
|
||||
if (menuTag.isWiimoteMenu())
|
||||
{
|
||||
if (value == 1) // Emulated Wii Remote
|
||||
{
|
||||
mView.showSettingsFragment(menuTag, null, true, mGameId);
|
||||
}
|
||||
}
|
||||
|
||||
if (menuTag.isWiimoteExtensionMenu())
|
||||
{
|
||||
if (value != 0) // Not disabled
|
||||
{
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt(SettingsFragmentPresenter.ARG_CONTROLLER_TYPE, value);
|
||||
mView.showSettingsFragment(menuTag, bundle, true, mGameId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasMenuTagActionForValue(@NonNull MenuTag menuTag, int value)
|
||||
{
|
||||
if (menuTag.isSerialPort1Menu())
|
||||
{
|
||||
return (value != 0 && value != 255); // Not disabled or dummy
|
||||
}
|
||||
|
||||
if (menuTag.isGCPadMenu())
|
||||
{
|
||||
return (value != 0); // Not disabled
|
||||
}
|
||||
|
||||
if (menuTag.isWiimoteMenu())
|
||||
{
|
||||
return (value == 1); // Emulated Wii Remote
|
||||
}
|
||||
|
||||
if (menuTag.isWiimoteExtensionMenu())
|
||||
{
|
||||
return (value != 0); // Not disabled
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,147 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.ui
|
||||
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings
|
||||
import org.dolphinemu.dolphinemu.utils.AfterDirectoryInitializationRunner
|
||||
import org.dolphinemu.dolphinemu.utils.Log
|
||||
|
||||
class SettingsActivityPresenter(
|
||||
private val activityView: SettingsActivityView,
|
||||
var settings: Settings?
|
||||
) {
|
||||
private var shouldSave = false
|
||||
private var menuTag: MenuTag? = null
|
||||
private var gameId: String? = null
|
||||
private var revision = 0
|
||||
private var isWii = false
|
||||
private lateinit var activity: AppCompatActivity
|
||||
|
||||
fun onCreate(
|
||||
savedInstanceState: Bundle?,
|
||||
menuTag: MenuTag?,
|
||||
gameId: String?,
|
||||
revision: Int,
|
||||
isWii: Boolean,
|
||||
activity: AppCompatActivity
|
||||
) {
|
||||
this.menuTag = menuTag
|
||||
this.gameId = gameId
|
||||
this.revision = revision
|
||||
this.isWii = isWii
|
||||
this.activity = activity
|
||||
shouldSave = savedInstanceState != null && savedInstanceState.getBoolean(KEY_SHOULD_SAVE)
|
||||
}
|
||||
|
||||
fun onDestroy() {
|
||||
if (settings != null) {
|
||||
settings!!.close()
|
||||
settings = null
|
||||
}
|
||||
}
|
||||
|
||||
fun onStart() {
|
||||
prepareDolphinDirectoriesIfNeeded()
|
||||
}
|
||||
|
||||
private fun loadSettingsUI() {
|
||||
activityView.hideLoading()
|
||||
if (!settings!!.areSettingsLoaded()) {
|
||||
if (!TextUtils.isEmpty(gameId)) {
|
||||
settings!!.loadSettings(gameId!!, revision, isWii)
|
||||
if (settings!!.gameIniContainsJunk()) {
|
||||
activityView.showGameIniJunkDeletionQuestion()
|
||||
}
|
||||
} else {
|
||||
settings!!.loadSettings(isWii)
|
||||
}
|
||||
}
|
||||
activityView.showSettingsFragment(menuTag!!, null, false, gameId!!)
|
||||
activityView.onSettingsFileLoaded(settings!!)
|
||||
}
|
||||
|
||||
private fun prepareDolphinDirectoriesIfNeeded() {
|
||||
activityView.showLoading()
|
||||
AfterDirectoryInitializationRunner().runWithLifecycle(activity) { loadSettingsUI() }
|
||||
}
|
||||
|
||||
fun clearGameSettings() {
|
||||
settings!!.clearGameSettings()
|
||||
onSettingChanged()
|
||||
}
|
||||
|
||||
fun onStop(finishing: Boolean) {
|
||||
if (settings != null && finishing && shouldSave) {
|
||||
Log.debug("[SettingsActivity] Settings activity stopping. Saving settings to INI...")
|
||||
settings!!.saveSettings(activity)
|
||||
}
|
||||
}
|
||||
|
||||
fun onSettingChanged() {
|
||||
shouldSave = true
|
||||
}
|
||||
|
||||
fun saveState(outState: Bundle) {
|
||||
outState.putBoolean(KEY_SHOULD_SAVE, shouldSave)
|
||||
}
|
||||
|
||||
fun onMenuTagAction(menuTag: MenuTag, value: Int) {
|
||||
if (menuTag.isSerialPort1Menu) {
|
||||
// Not disabled or dummy
|
||||
if (value != 0 && value != 255) {
|
||||
val bundle = Bundle()
|
||||
bundle.putInt(SettingsFragmentPresenter.ARG_SERIALPORT1_TYPE, value)
|
||||
activityView.showSettingsFragment(menuTag, bundle, true, gameId!!)
|
||||
}
|
||||
}
|
||||
if (menuTag.isGCPadMenu) {
|
||||
// Not disabled
|
||||
if (value != 0)
|
||||
{
|
||||
val bundle = Bundle()
|
||||
bundle.putInt(SettingsFragmentPresenter.ARG_CONTROLLER_TYPE, value)
|
||||
activityView.showSettingsFragment(menuTag, bundle, true, gameId!!)
|
||||
}
|
||||
}
|
||||
if (menuTag.isWiimoteMenu) {
|
||||
// Emulated Wii Remote
|
||||
if (value == 1) {
|
||||
activityView.showSettingsFragment(menuTag, null, true, gameId!!)
|
||||
}
|
||||
}
|
||||
if (menuTag.isWiimoteExtensionMenu) {
|
||||
// Not disabled
|
||||
if (value != 0) {
|
||||
val bundle = Bundle()
|
||||
bundle.putInt(SettingsFragmentPresenter.ARG_CONTROLLER_TYPE, value)
|
||||
activityView.showSettingsFragment(menuTag, bundle, true, gameId!!)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun hasMenuTagActionForValue(menuTag: MenuTag, value: Int): Boolean {
|
||||
if (menuTag.isSerialPort1Menu) {
|
||||
// Not disabled or dummy
|
||||
return value != 0 && value != 255
|
||||
}
|
||||
if (menuTag.isGCPadMenu) {
|
||||
// Not disabled
|
||||
return value != 0
|
||||
}
|
||||
if (menuTag.isWiimoteMenu) {
|
||||
// Emulated Wii Remote
|
||||
return value == 1
|
||||
}
|
||||
return if (menuTag.isWiimoteExtensionMenu) {
|
||||
// Not disabled
|
||||
value != 0
|
||||
} else false
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val KEY_SHOULD_SAVE = "should_save"
|
||||
}
|
||||
}
|
|
@ -1,137 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.ui;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
|
||||
|
||||
/**
|
||||
* Abstraction for the Activity that manages SettingsFragments.
|
||||
*/
|
||||
public interface SettingsActivityView
|
||||
{
|
||||
/**
|
||||
* Show a new SettingsFragment.
|
||||
*
|
||||
* @param menuTag Identifier for the settings group that should be displayed.
|
||||
* @param addToStack Whether or not this fragment should replace a previous one.
|
||||
*/
|
||||
void showSettingsFragment(MenuTag menuTag, Bundle extras, boolean addToStack, String gameId);
|
||||
|
||||
/**
|
||||
* Shows a DialogFragment.
|
||||
*
|
||||
* Only one can be shown at a time.
|
||||
*/
|
||||
void showDialogFragment(DialogFragment fragment);
|
||||
|
||||
/**
|
||||
* Called by a contained Fragment to get access to the Setting HashMap
|
||||
* loaded from disk, so that each Fragment doesn't need to perform its own
|
||||
* read operation.
|
||||
*
|
||||
* @return A possibly null HashMap of Settings.
|
||||
*/
|
||||
Settings getSettings();
|
||||
|
||||
/**
|
||||
* Called when an asynchronous load operation completes.
|
||||
*
|
||||
* @param settings The (possibly null) result of the ini load operation.
|
||||
*/
|
||||
void onSettingsFileLoaded(Settings settings);
|
||||
|
||||
/**
|
||||
* Called when an asynchronous load operation fails.
|
||||
*/
|
||||
void onSettingsFileNotFound();
|
||||
|
||||
/**
|
||||
* Display a popup text message on screen.
|
||||
*
|
||||
* @param message The contents of the onscreen message.
|
||||
*/
|
||||
void showToastMessage(String message);
|
||||
|
||||
/**
|
||||
* End the activity.
|
||||
*/
|
||||
void finish();
|
||||
|
||||
/**
|
||||
* Called by a containing Fragment to tell the Activity that a setting was changed;
|
||||
* unless this has been called, the Activity will not save to disk.
|
||||
*/
|
||||
void onSettingChanged();
|
||||
|
||||
/**
|
||||
* Refetches the values of all controller settings.
|
||||
*
|
||||
* To be used when loading an input profile or performing some other action that changes all
|
||||
* controller settings at once.
|
||||
*/
|
||||
void onControllerSettingsChanged();
|
||||
|
||||
/**
|
||||
* Called by a containing Fragment to tell the containing Activity that the user wants to open the
|
||||
* MenuTag associated with a setting.
|
||||
*
|
||||
* @param menuTag The MenuTag of the setting.
|
||||
* @param value The current value of the setting.
|
||||
*/
|
||||
void onMenuTagAction(@NonNull MenuTag menuTag, int value);
|
||||
|
||||
/**
|
||||
* Returns whether anything will happen when the user wants to open the MenuTag associated with a
|
||||
* setting, given the current value of the setting.
|
||||
*
|
||||
* @param menuTag The MenuTag of the setting.
|
||||
* @param value The current value of the setting.
|
||||
*/
|
||||
boolean hasMenuTagActionForValue(@NonNull MenuTag menuTag, int value);
|
||||
|
||||
/**
|
||||
* Show loading dialog while loading the settings
|
||||
*/
|
||||
void showLoading();
|
||||
|
||||
/**
|
||||
* Hide the loading dialog
|
||||
*/
|
||||
void hideLoading();
|
||||
|
||||
/**
|
||||
* Tell the user that there is junk in the game INI and ask if they want to delete the whole file.
|
||||
*/
|
||||
void showGameIniJunkDeletionQuestion();
|
||||
|
||||
/**
|
||||
* Accesses the material toolbar layout and changes the title
|
||||
*/
|
||||
void setToolbarTitle(String title);
|
||||
|
||||
/**
|
||||
* Sets whether the input mapping dialog should detect inputs from all devices,
|
||||
* not just the device configured for the controller.
|
||||
*/
|
||||
void setMappingAllDevices(boolean allDevices);
|
||||
|
||||
/**
|
||||
* Returns whether the input mapping dialog should detect inputs from all devices,
|
||||
* not just the device configured for the controller.
|
||||
*/
|
||||
boolean isMappingAllDevices();
|
||||
|
||||
/**
|
||||
* Shows or hides a warning telling the user that they're using incompatible controller settings.
|
||||
* The warning is hidden by default.
|
||||
*
|
||||
* @param visible Whether the warning should be visible.
|
||||
* @return The height of the warning view, or 0 if the view is now invisible.
|
||||
*/
|
||||
int setOldControllerSettingsWarningVisibility(boolean visible);
|
||||
}
|
|
@ -0,0 +1,135 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.ui
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings
|
||||
|
||||
/**
|
||||
* Abstraction for the Activity that manages SettingsFragments.
|
||||
*/
|
||||
interface SettingsActivityView {
|
||||
/**
|
||||
* Show a new SettingsFragment.
|
||||
*
|
||||
* @param menuTag Identifier for the settings group that should be displayed.
|
||||
* @param addToStack Whether or not this fragment should replace a previous one.
|
||||
*/
|
||||
fun showSettingsFragment(
|
||||
menuTag: MenuTag,
|
||||
extras: Bundle?,
|
||||
addToStack: Boolean,
|
||||
gameId: String
|
||||
)
|
||||
|
||||
/**
|
||||
* Shows a DialogFragment.
|
||||
*
|
||||
* Only one can be shown at a time.
|
||||
*/
|
||||
fun showDialogFragment(fragment: DialogFragment)
|
||||
|
||||
/**
|
||||
* Called by a contained Fragment to get access to the Setting HashMap
|
||||
* loaded from disk, so that each Fragment doesn't need to perform its own
|
||||
* read operation.
|
||||
*
|
||||
* @return A possibly null HashMap of Settings.
|
||||
*/
|
||||
val settings: Settings
|
||||
|
||||
/**
|
||||
* Called when an asynchronous load operation completes.
|
||||
*
|
||||
* @param settings The (possibly null) result of the ini load operation.
|
||||
*/
|
||||
fun onSettingsFileLoaded(settings: Settings)
|
||||
|
||||
/**
|
||||
* Called when an asynchronous load operation fails.
|
||||
*/
|
||||
fun onSettingsFileNotFound()
|
||||
|
||||
/**
|
||||
* Display a popup text message on screen.
|
||||
*
|
||||
* @param message The contents of the onscreen message.
|
||||
*/
|
||||
fun showToastMessage(message: String)
|
||||
|
||||
/**
|
||||
* End the activity.
|
||||
*/
|
||||
fun finish()
|
||||
|
||||
/**
|
||||
* Called by a containing Fragment to tell the Activity that a Setting was changed;
|
||||
* unless this has been called, the Activity will not save to disk.
|
||||
*/
|
||||
fun onSettingChanged()
|
||||
|
||||
/**
|
||||
* Refetches the values of all controller settings.
|
||||
*
|
||||
* To be used when loading an input profile or performing some other action that changes all
|
||||
* controller settings at once.
|
||||
*/
|
||||
fun onControllerSettingsChanged()
|
||||
|
||||
/**
|
||||
* Called by a containing Fragment to tell the containing Activity that the user wants to open the
|
||||
* MenuTag associated with a Setting.
|
||||
*
|
||||
* @param menuTag The MenuTag of the Setting.
|
||||
* @param value The current value of the Setting.
|
||||
*/
|
||||
fun onMenuTagAction(menuTag: MenuTag, value: Int)
|
||||
|
||||
/**
|
||||
* Returns whether anything will happen when the user wants to open the MenuTag associated with a
|
||||
* Setting, given the current value of the Setting.
|
||||
*
|
||||
* @param menuTag The MenuTag of the Setting.
|
||||
* @param value The current value of the Setting.
|
||||
*/
|
||||
fun hasMenuTagActionForValue(menuTag: MenuTag, value: Int): Boolean
|
||||
|
||||
/**
|
||||
* Show loading dialog while loading the settings
|
||||
*/
|
||||
fun showLoading()
|
||||
|
||||
/**
|
||||
* Hide the loading dialog
|
||||
*/
|
||||
fun hideLoading()
|
||||
|
||||
/**
|
||||
* Tell the user that there is junk in the game INI and ask if they want to delete the whole file.
|
||||
*/
|
||||
fun showGameIniJunkDeletionQuestion()
|
||||
|
||||
/**
|
||||
* Accesses the material toolbar layout and changes the title
|
||||
*/
|
||||
fun setToolbarTitle(title: String)
|
||||
/**
|
||||
* Returns whether the input mapping dialog should detect inputs from all devices,
|
||||
* not just the device configured for the controller.
|
||||
*/
|
||||
/**
|
||||
* Sets whether the input mapping dialog should detect inputs from all devices,
|
||||
* not just the device configured for the controller.
|
||||
*/
|
||||
var isMappingAllDevices: Boolean
|
||||
|
||||
/**
|
||||
* Shows or hides a warning telling the user that they're using incompatible controller settings.
|
||||
* The warning is hidden by default.
|
||||
*
|
||||
* @param visible Whether the warning should be visible.
|
||||
* @return The height of the warning view, or 0 if the view is now invisible.
|
||||
*/
|
||||
fun setOldControllerSettingsWarningVisibility(visible: Boolean): Int
|
||||
}
|
|
@ -1,703 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.ui;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.provider.DocumentsContract;
|
||||
import android.text.format.DateFormat;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.google.android.material.color.MaterialColors;
|
||||
import com.google.android.material.datepicker.CalendarConstraints;
|
||||
import com.google.android.material.datepicker.MaterialDatePicker;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import com.google.android.material.elevation.ElevationOverlayProvider;
|
||||
import com.google.android.material.slider.Slider;
|
||||
import com.google.android.material.textfield.TextInputEditText;
|
||||
import com.google.android.material.timepicker.MaterialTimePicker;
|
||||
import com.google.android.material.timepicker.TimeFormat;
|
||||
|
||||
import org.dolphinemu.dolphinemu.R;
|
||||
import org.dolphinemu.dolphinemu.databinding.DialogAdvancedMappingBinding;
|
||||
import org.dolphinemu.dolphinemu.databinding.DialogInputStringBinding;
|
||||
import org.dolphinemu.dolphinemu.databinding.DialogSliderBinding;
|
||||
import org.dolphinemu.dolphinemu.databinding.ListItemHeaderBinding;
|
||||
import org.dolphinemu.dolphinemu.databinding.ListItemMappingBinding;
|
||||
import org.dolphinemu.dolphinemu.databinding.ListItemSettingBinding;
|
||||
import org.dolphinemu.dolphinemu.databinding.ListItemSettingSwitchBinding;
|
||||
import org.dolphinemu.dolphinemu.databinding.ListItemSubmenuBinding;
|
||||
import org.dolphinemu.dolphinemu.features.input.ui.AdvancedMappingDialog;
|
||||
import org.dolphinemu.dolphinemu.features.input.ui.MotionAlertDialog;
|
||||
import org.dolphinemu.dolphinemu.features.input.model.view.InputMappingControlSetting;
|
||||
import org.dolphinemu.dolphinemu.features.input.ui.viewholder.InputMappingControlSettingViewHolder;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.view.DateTimeChoiceSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.view.SwitchSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.view.FilePicker;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.view.FloatSliderSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.view.IntSliderSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.view.SingleChoiceSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.view.SingleChoiceSettingDynamicDescriptions;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.view.SliderSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.view.InputStringSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.view.StringSingleChoiceSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.view.SubmenuSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.ui.viewholder.DateTimeSettingViewHolder;
|
||||
import org.dolphinemu.dolphinemu.features.settings.ui.viewholder.FilePickerViewHolder;
|
||||
import org.dolphinemu.dolphinemu.features.settings.ui.viewholder.HeaderHyperLinkViewHolder;
|
||||
import org.dolphinemu.dolphinemu.features.settings.ui.viewholder.HeaderViewHolder;
|
||||
import org.dolphinemu.dolphinemu.features.settings.ui.viewholder.InputStringSettingViewHolder;
|
||||
import org.dolphinemu.dolphinemu.features.settings.ui.viewholder.RunRunnableViewHolder;
|
||||
import org.dolphinemu.dolphinemu.features.settings.ui.viewholder.SettingViewHolder;
|
||||
import org.dolphinemu.dolphinemu.features.settings.ui.viewholder.SingleChoiceViewHolder;
|
||||
import org.dolphinemu.dolphinemu.features.settings.ui.viewholder.SliderViewHolder;
|
||||
import org.dolphinemu.dolphinemu.features.settings.ui.viewholder.SubmenuViewHolder;
|
||||
import org.dolphinemu.dolphinemu.features.settings.ui.viewholder.SwitchSettingViewHolder;
|
||||
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization;
|
||||
import org.dolphinemu.dolphinemu.utils.FileBrowserHelper;
|
||||
import org.dolphinemu.dolphinemu.utils.Log;
|
||||
import org.dolphinemu.dolphinemu.utils.PermissionsHandler;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.TimeZone;
|
||||
|
||||
public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolder>
|
||||
implements DialogInterface.OnClickListener, Slider.OnChangeListener
|
||||
{
|
||||
private final SettingsFragmentView mView;
|
||||
private final Context mContext;
|
||||
private ArrayList<SettingsItem> mSettings;
|
||||
|
||||
private SettingsItem mClickedItem;
|
||||
private int mClickedPosition;
|
||||
private int mSeekbarProgress;
|
||||
|
||||
private AlertDialog mDialog;
|
||||
private TextView mTextSliderValue;
|
||||
|
||||
public SettingsAdapter(SettingsFragmentView view, Context context)
|
||||
{
|
||||
mView = view;
|
||||
mContext = context;
|
||||
mClickedPosition = -1;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public SettingViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
|
||||
{
|
||||
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
|
||||
switch (viewType)
|
||||
{
|
||||
case SettingsItem.TYPE_HEADER:
|
||||
return new HeaderViewHolder(ListItemHeaderBinding.inflate(inflater), this);
|
||||
|
||||
case SettingsItem.TYPE_SWITCH:
|
||||
return new SwitchSettingViewHolder(ListItemSettingSwitchBinding.inflate(inflater),
|
||||
this);
|
||||
|
||||
case SettingsItem.TYPE_STRING_SINGLE_CHOICE:
|
||||
case SettingsItem.TYPE_SINGLE_CHOICE_DYNAMIC_DESCRIPTIONS:
|
||||
case SettingsItem.TYPE_SINGLE_CHOICE:
|
||||
return new SingleChoiceViewHolder(ListItemSettingBinding.inflate(inflater), this);
|
||||
|
||||
case SettingsItem.TYPE_SLIDER:
|
||||
return new SliderViewHolder(ListItemSettingBinding.inflate(inflater), this, mContext);
|
||||
|
||||
case SettingsItem.TYPE_SUBMENU:
|
||||
return new SubmenuViewHolder(ListItemSubmenuBinding.inflate(inflater), this);
|
||||
|
||||
case SettingsItem.TYPE_INPUT_MAPPING_CONTROL:
|
||||
return new InputMappingControlSettingViewHolder(ListItemMappingBinding.inflate(inflater),
|
||||
this);
|
||||
|
||||
case SettingsItem.TYPE_FILE_PICKER:
|
||||
return new FilePickerViewHolder(ListItemSettingBinding.inflate(inflater), this);
|
||||
|
||||
case SettingsItem.TYPE_RUN_RUNNABLE:
|
||||
return new RunRunnableViewHolder(ListItemSettingBinding.inflate(inflater), this, mContext);
|
||||
|
||||
case SettingsItem.TYPE_STRING:
|
||||
return new InputStringSettingViewHolder(ListItemSettingBinding.inflate(inflater), this);
|
||||
|
||||
case SettingsItem.TYPE_HYPERLINK_HEADER:
|
||||
return new HeaderHyperLinkViewHolder(ListItemHeaderBinding.inflate(inflater), this);
|
||||
|
||||
case SettingsItem.TYPE_DATETIME_CHOICE:
|
||||
return new DateTimeSettingViewHolder(ListItemSettingBinding.inflate(inflater), this);
|
||||
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid view type: " + viewType);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull SettingViewHolder holder, int position)
|
||||
{
|
||||
holder.bind(getItem(position));
|
||||
}
|
||||
|
||||
private SettingsItem getItem(int position)
|
||||
{
|
||||
return mSettings.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount()
|
||||
{
|
||||
if (mSettings != null)
|
||||
{
|
||||
return mSettings.size();
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position)
|
||||
{
|
||||
return getItem(position).getType();
|
||||
}
|
||||
|
||||
public Settings getSettings()
|
||||
{
|
||||
return mView.getSettings();
|
||||
}
|
||||
|
||||
public void setSettings(ArrayList<SettingsItem> settings)
|
||||
{
|
||||
mSettings = settings;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void clearSetting(SettingsItem item)
|
||||
{
|
||||
item.clear(getSettings());
|
||||
|
||||
mView.onSettingChanged();
|
||||
}
|
||||
|
||||
public void notifyAllSettingsChanged()
|
||||
{
|
||||
notifyItemRangeChanged(0, getItemCount());
|
||||
|
||||
mView.onSettingChanged();
|
||||
}
|
||||
|
||||
public void onBooleanClick(SwitchSetting item, boolean checked)
|
||||
{
|
||||
item.setChecked(getSettings(), checked);
|
||||
|
||||
mView.onSettingChanged();
|
||||
}
|
||||
|
||||
public void onInputStringClick(InputStringSetting item, int position)
|
||||
{
|
||||
LayoutInflater inflater = LayoutInflater.from(mContext);
|
||||
|
||||
DialogInputStringBinding binding = DialogInputStringBinding.inflate(inflater);
|
||||
TextInputEditText input = binding.input;
|
||||
input.setText(item.getSelectedValue());
|
||||
|
||||
mDialog = new MaterialAlertDialogBuilder(mView.getActivity())
|
||||
.setView(binding.getRoot())
|
||||
.setMessage(item.getDescription())
|
||||
.setPositiveButton(R.string.ok, (dialogInterface, i) ->
|
||||
{
|
||||
String editTextInput = input.getText().toString();
|
||||
|
||||
if (!item.getSelectedValue().equals(editTextInput))
|
||||
{
|
||||
notifyItemChanged(position);
|
||||
mView.onSettingChanged();
|
||||
}
|
||||
|
||||
item.setSelectedValue(mView.getSettings(), editTextInput);
|
||||
})
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.show();
|
||||
}
|
||||
|
||||
public void onSingleChoiceClick(SingleChoiceSetting item, int position)
|
||||
{
|
||||
mClickedItem = item;
|
||||
mClickedPosition = position;
|
||||
|
||||
int value = getSelectionForSingleChoiceValue(item);
|
||||
|
||||
mDialog = new MaterialAlertDialogBuilder(mView.getActivity())
|
||||
.setTitle(item.getName())
|
||||
.setSingleChoiceItems(item.getChoicesId(), value, this)
|
||||
.show();
|
||||
}
|
||||
|
||||
public void onStringSingleChoiceClick(StringSingleChoiceSetting item, int position)
|
||||
{
|
||||
mClickedItem = item;
|
||||
mClickedPosition = position;
|
||||
|
||||
item.refreshChoicesAndValues();
|
||||
|
||||
String[] choices = item.getChoices();
|
||||
int noChoicesAvailableString = item.getNoChoicesAvailableString();
|
||||
if (noChoicesAvailableString != 0 && choices.length == 0)
|
||||
{
|
||||
mDialog = new MaterialAlertDialogBuilder(mView.getActivity())
|
||||
.setTitle(item.getName())
|
||||
.setMessage(noChoicesAvailableString)
|
||||
.setPositiveButton(R.string.ok, null)
|
||||
.show();
|
||||
}
|
||||
else
|
||||
{
|
||||
mDialog = new MaterialAlertDialogBuilder(mView.getActivity())
|
||||
.setTitle(item.getName())
|
||||
.setSingleChoiceItems(item.getChoices(), item.getSelectedValueIndex(),
|
||||
this)
|
||||
.show();
|
||||
}
|
||||
}
|
||||
|
||||
public void onSingleChoiceDynamicDescriptionsClick(SingleChoiceSettingDynamicDescriptions item,
|
||||
int position)
|
||||
{
|
||||
mClickedItem = item;
|
||||
mClickedPosition = position;
|
||||
|
||||
int value = getSelectionForSingleChoiceDynamicDescriptionsValue(item);
|
||||
|
||||
mDialog = new MaterialAlertDialogBuilder(mView.getActivity())
|
||||
.setTitle(item.getName())
|
||||
.setSingleChoiceItems(item.getChoicesId(), value, this)
|
||||
.show();
|
||||
}
|
||||
|
||||
public void onSliderClick(SliderSetting item, int position)
|
||||
{
|
||||
mClickedItem = item;
|
||||
mClickedPosition = position;
|
||||
mSeekbarProgress = item.getSelectedValue();
|
||||
|
||||
LayoutInflater inflater = LayoutInflater.from(mView.getActivity());
|
||||
DialogSliderBinding binding = DialogSliderBinding.inflate(inflater);
|
||||
|
||||
mTextSliderValue = binding.textValue;
|
||||
mTextSliderValue.setText(String.valueOf(mSeekbarProgress));
|
||||
|
||||
binding.textUnits.setText(item.getUnits());
|
||||
|
||||
Slider slider = binding.slider;
|
||||
slider.setValueFrom(item.getMin());
|
||||
slider.setValueTo(item.getMax());
|
||||
slider.setValue(mSeekbarProgress);
|
||||
slider.setStepSize(item.getStepSize());
|
||||
|
||||
slider.addOnChangeListener(this);
|
||||
|
||||
mDialog = new MaterialAlertDialogBuilder(mView.getActivity())
|
||||
.setTitle(item.getName())
|
||||
.setView(binding.getRoot())
|
||||
.setPositiveButton(R.string.ok, this)
|
||||
.show();
|
||||
}
|
||||
|
||||
public void onSubmenuClick(SubmenuSetting item)
|
||||
{
|
||||
mView.loadSubMenu(item.getMenuKey());
|
||||
}
|
||||
|
||||
public void onInputMappingClick(final InputMappingControlSetting item, final int position)
|
||||
{
|
||||
if (item.getController().getDefaultDevice().isEmpty() && !mView.isMappingAllDevices())
|
||||
{
|
||||
new MaterialAlertDialogBuilder(mView.getActivity())
|
||||
.setMessage(R.string.input_binding_no_device)
|
||||
.setPositiveButton(R.string.ok, this)
|
||||
.show();
|
||||
return;
|
||||
}
|
||||
|
||||
final MotionAlertDialog dialog = new MotionAlertDialog(mView.getActivity(), item,
|
||||
mView.isMappingAllDevices());
|
||||
|
||||
Drawable background = ContextCompat.getDrawable(mContext, R.drawable.dialog_round);
|
||||
@ColorInt int color = new ElevationOverlayProvider(dialog.getContext()).compositeOverlay(
|
||||
MaterialColors.getColor(dialog.getWindow().getDecorView(), R.attr.colorSurface),
|
||||
dialog.getWindow().getDecorView().getElevation());
|
||||
background.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
|
||||
dialog.getWindow().setBackgroundDrawable(background);
|
||||
|
||||
dialog.setTitle(R.string.input_binding);
|
||||
dialog.setMessage(String.format(mContext.getString(R.string.input_binding_description),
|
||||
item.getName()));
|
||||
dialog.setButton(AlertDialog.BUTTON_NEGATIVE, mContext.getString(R.string.cancel), this);
|
||||
dialog.setButton(AlertDialog.BUTTON_NEUTRAL, mContext.getString(R.string.clear),
|
||||
(dialogInterface, i) -> item.clearValue());
|
||||
dialog.setOnDismissListener(dialog1 ->
|
||||
{
|
||||
notifyItemChanged(position);
|
||||
mView.onSettingChanged();
|
||||
});
|
||||
dialog.setCanceledOnTouchOutside(false);
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
public void onAdvancedInputMappingClick(final InputMappingControlSetting item, final int position)
|
||||
{
|
||||
LayoutInflater inflater = LayoutInflater.from(mContext);
|
||||
|
||||
DialogAdvancedMappingBinding binding = DialogAdvancedMappingBinding.inflate(inflater);
|
||||
|
||||
final AdvancedMappingDialog dialog = new AdvancedMappingDialog(mContext, binding,
|
||||
item.getControlReference(), item.getController());
|
||||
|
||||
Drawable background = ContextCompat.getDrawable(mContext, R.drawable.dialog_round);
|
||||
@ColorInt int color = new ElevationOverlayProvider(dialog.getContext()).compositeOverlay(
|
||||
MaterialColors.getColor(dialog.getWindow().getDecorView(), R.attr.colorSurface),
|
||||
dialog.getWindow().getDecorView().getElevation());
|
||||
background.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
|
||||
dialog.getWindow().setBackgroundDrawable(background);
|
||||
|
||||
dialog.setTitle(item.isInput() ?
|
||||
R.string.input_configure_input : R.string.input_configure_output);
|
||||
dialog.setView(binding.getRoot());
|
||||
dialog.setButton(AlertDialog.BUTTON_POSITIVE, mContext.getString(R.string.ok),
|
||||
(dialogInterface, i) ->
|
||||
{
|
||||
item.setValue(dialog.getExpression());
|
||||
notifyItemChanged(position);
|
||||
mView.onSettingChanged();
|
||||
});
|
||||
dialog.setButton(AlertDialog.BUTTON_NEGATIVE, mContext.getString(R.string.cancel), this);
|
||||
dialog.setButton(AlertDialog.BUTTON_NEUTRAL, mContext.getString(R.string.clear),
|
||||
(dialogInterface, i) ->
|
||||
{
|
||||
item.clearValue();
|
||||
notifyItemChanged(position);
|
||||
mView.onSettingChanged();
|
||||
});
|
||||
dialog.setCanceledOnTouchOutside(false);
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
public void onFilePickerDirectoryClick(SettingsItem item, int position)
|
||||
{
|
||||
mClickedItem = item;
|
||||
mClickedPosition = position;
|
||||
|
||||
if (!PermissionsHandler.isExternalStorageLegacy())
|
||||
{
|
||||
new MaterialAlertDialogBuilder(mContext)
|
||||
.setMessage(R.string.path_not_changeable_scoped_storage)
|
||||
.setPositiveButton(R.string.ok, (dialog, i) -> dialog.dismiss())
|
||||
.show();
|
||||
}
|
||||
else
|
||||
{
|
||||
FileBrowserHelper.openDirectoryPicker(mView.getActivity(), FileBrowserHelper.GAME_EXTENSIONS);
|
||||
}
|
||||
}
|
||||
|
||||
public void onFilePickerFileClick(SettingsItem item, int position)
|
||||
{
|
||||
mClickedItem = item;
|
||||
mClickedPosition = position;
|
||||
FilePicker filePicker = (FilePicker) item;
|
||||
|
||||
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
intent.setType("*/*");
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
|
||||
{
|
||||
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, filePicker.getSelectedValue());
|
||||
}
|
||||
|
||||
mView.getActivity().startActivityForResult(intent, filePicker.getRequestType());
|
||||
}
|
||||
|
||||
public void onDateTimeClick(DateTimeChoiceSetting item, int position)
|
||||
{
|
||||
mClickedItem = item;
|
||||
mClickedPosition = position;
|
||||
long storedTime = Long.decode(item.getSelectedValue()) * 1000;
|
||||
|
||||
// Helper to extract hour and minute from epoch time
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTimeInMillis(storedTime);
|
||||
calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
|
||||
// Start and end epoch times available for the Wii's date picker
|
||||
CalendarConstraints calendarConstraints = new CalendarConstraints.Builder()
|
||||
.setStart(946684800000L)
|
||||
.setEnd(2082672000000L)
|
||||
.build();
|
||||
|
||||
int timeFormat = TimeFormat.CLOCK_12H;
|
||||
if (DateFormat.is24HourFormat(mView.getActivity()))
|
||||
{
|
||||
timeFormat = TimeFormat.CLOCK_24H;
|
||||
}
|
||||
|
||||
MaterialDatePicker<Long> datePicker = MaterialDatePicker.Builder.datePicker()
|
||||
.setSelection(storedTime)
|
||||
.setTitleText(R.string.select_rtc_date)
|
||||
.setCalendarConstraints(calendarConstraints)
|
||||
.build();
|
||||
MaterialTimePicker timePicker = new MaterialTimePicker.Builder()
|
||||
.setTimeFormat(timeFormat)
|
||||
.setHour(calendar.get(Calendar.HOUR_OF_DAY))
|
||||
.setMinute(calendar.get(Calendar.MINUTE))
|
||||
.setTitleText(R.string.select_rtc_time)
|
||||
.build();
|
||||
|
||||
datePicker.addOnPositiveButtonClickListener(
|
||||
selection -> timePicker.show(mView.getActivity().getSupportFragmentManager(),
|
||||
"TimePicker"));
|
||||
timePicker.addOnPositiveButtonClickListener(selection ->
|
||||
{
|
||||
long epochTime = datePicker.getSelection() / 1000;
|
||||
epochTime += (long) timePicker.getHour() * 60 * 60;
|
||||
epochTime += (long) timePicker.getMinute() * 60;
|
||||
String rtcString = "0x" + Long.toHexString(epochTime);
|
||||
if (!item.getSelectedValue().equals(rtcString))
|
||||
{
|
||||
notifyItemChanged(mClickedPosition);
|
||||
mView.onSettingChanged();
|
||||
}
|
||||
|
||||
item.setSelectedValue(mView.getSettings(), rtcString);
|
||||
|
||||
mClickedItem = null;
|
||||
});
|
||||
datePicker.show(mView.getActivity().getSupportFragmentManager(), "DatePicker");
|
||||
}
|
||||
|
||||
public void onFilePickerConfirmation(String selectedFile)
|
||||
{
|
||||
FilePicker filePicker = (FilePicker) mClickedItem;
|
||||
|
||||
if (!filePicker.getSelectedValue().equals(selectedFile))
|
||||
{
|
||||
notifyItemChanged(mClickedPosition);
|
||||
mView.onSettingChanged();
|
||||
}
|
||||
|
||||
filePicker.setSelectedValue(mView.getSettings(), selectedFile);
|
||||
|
||||
mClickedItem = null;
|
||||
}
|
||||
|
||||
public static void clearLog()
|
||||
{
|
||||
// Don't delete the log in case it is being monitored by another app.
|
||||
File log = new File(DirectoryInitialization.getUserDirectory() + "/Logs/dolphin.log");
|
||||
|
||||
try
|
||||
{
|
||||
RandomAccessFile raf = new RandomAccessFile(log, "rw");
|
||||
raf.setLength(0);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
Log.error("[SettingsAdapter] Failed to clear log file: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void onMenuTagAction(@NonNull MenuTag menuTag, int value)
|
||||
{
|
||||
mView.onMenuTagAction(menuTag, value);
|
||||
}
|
||||
|
||||
public boolean hasMenuTagActionForValue(@NonNull MenuTag menuTag, int value)
|
||||
{
|
||||
return mView.hasMenuTagActionForValue(menuTag, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
if (mClickedItem instanceof SingleChoiceSetting)
|
||||
{
|
||||
SingleChoiceSetting scSetting = (SingleChoiceSetting) mClickedItem;
|
||||
|
||||
int value = getValueForSingleChoiceSelection(scSetting, which);
|
||||
if (scSetting.getSelectedValue() != value)
|
||||
mView.onSettingChanged();
|
||||
|
||||
scSetting.setSelectedValue(getSettings(), value);
|
||||
|
||||
closeDialog();
|
||||
}
|
||||
else if (mClickedItem instanceof SingleChoiceSettingDynamicDescriptions)
|
||||
{
|
||||
SingleChoiceSettingDynamicDescriptions scSetting =
|
||||
(SingleChoiceSettingDynamicDescriptions) mClickedItem;
|
||||
|
||||
int value = getValueForSingleChoiceDynamicDescriptionsSelection(scSetting, which);
|
||||
if (scSetting.getSelectedValue() != value)
|
||||
mView.onSettingChanged();
|
||||
|
||||
scSetting.setSelectedValue(getSettings(), value);
|
||||
|
||||
closeDialog();
|
||||
}
|
||||
else if (mClickedItem instanceof StringSingleChoiceSetting)
|
||||
{
|
||||
StringSingleChoiceSetting scSetting = (StringSingleChoiceSetting) mClickedItem;
|
||||
String value = scSetting.getValueAt(which);
|
||||
if (!scSetting.getSelectedValue().equals(value))
|
||||
mView.onSettingChanged();
|
||||
|
||||
scSetting.setSelectedValue(getSettings(), value);
|
||||
|
||||
closeDialog();
|
||||
}
|
||||
else if (mClickedItem instanceof IntSliderSetting)
|
||||
{
|
||||
IntSliderSetting sliderSetting = (IntSliderSetting) mClickedItem;
|
||||
if (sliderSetting.getSelectedValue() != mSeekbarProgress)
|
||||
mView.onSettingChanged();
|
||||
|
||||
sliderSetting.setSelectedValue(getSettings(), mSeekbarProgress);
|
||||
|
||||
closeDialog();
|
||||
}
|
||||
else if (mClickedItem instanceof FloatSliderSetting)
|
||||
{
|
||||
FloatSliderSetting sliderSetting = (FloatSliderSetting) mClickedItem;
|
||||
if (sliderSetting.getSelectedValue() != mSeekbarProgress)
|
||||
mView.onSettingChanged();
|
||||
|
||||
sliderSetting.setSelectedValue(getSettings(), mSeekbarProgress);
|
||||
|
||||
closeDialog();
|
||||
}
|
||||
|
||||
mClickedItem = null;
|
||||
mSeekbarProgress = -1;
|
||||
}
|
||||
|
||||
public void closeDialog()
|
||||
{
|
||||
if (mDialog != null)
|
||||
{
|
||||
if (mClickedPosition != -1)
|
||||
{
|
||||
notifyItemChanged(mClickedPosition);
|
||||
mClickedPosition = -1;
|
||||
}
|
||||
mDialog.dismiss();
|
||||
mDialog = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onValueChange(@NonNull Slider slider, float progress, boolean fromUser)
|
||||
{
|
||||
mSeekbarProgress = (int) progress;
|
||||
mTextSliderValue.setText(String.valueOf(mSeekbarProgress));
|
||||
}
|
||||
|
||||
private int getValueForSingleChoiceSelection(SingleChoiceSetting item, int which)
|
||||
{
|
||||
int valuesId = item.getValuesId();
|
||||
|
||||
if (valuesId > 0)
|
||||
{
|
||||
int[] valuesArray = mContext.getResources().getIntArray(valuesId);
|
||||
return valuesArray[which];
|
||||
}
|
||||
else
|
||||
{
|
||||
return which;
|
||||
}
|
||||
}
|
||||
|
||||
private int getSelectionForSingleChoiceValue(SingleChoiceSetting item)
|
||||
{
|
||||
int value = item.getSelectedValue();
|
||||
int valuesId = item.getValuesId();
|
||||
|
||||
if (valuesId > 0)
|
||||
{
|
||||
int[] valuesArray = mContext.getResources().getIntArray(valuesId);
|
||||
for (int index = 0; index < valuesArray.length; index++)
|
||||
{
|
||||
int current = valuesArray[index];
|
||||
if (current == value)
|
||||
{
|
||||
return index;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
private int getValueForSingleChoiceDynamicDescriptionsSelection(
|
||||
SingleChoiceSettingDynamicDescriptions item, int which)
|
||||
{
|
||||
int valuesId = item.getValuesId();
|
||||
|
||||
if (valuesId > 0)
|
||||
{
|
||||
int[] valuesArray = mContext.getResources().getIntArray(valuesId);
|
||||
return valuesArray[which];
|
||||
}
|
||||
else
|
||||
{
|
||||
return which;
|
||||
}
|
||||
}
|
||||
|
||||
private int getSelectionForSingleChoiceDynamicDescriptionsValue(
|
||||
SingleChoiceSettingDynamicDescriptions item)
|
||||
{
|
||||
int value = item.getSelectedValue();
|
||||
int valuesId = item.getValuesId();
|
||||
|
||||
if (valuesId > 0)
|
||||
{
|
||||
int[] valuesArray = mContext.getResources().getIntArray(valuesId);
|
||||
for (int index = 0; index < valuesArray.length; index++)
|
||||
{
|
||||
int current = valuesArray[index];
|
||||
if (current == value)
|
||||
{
|
||||
return index;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,590 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.ui
|
||||
|
||||
import android.content.Context
|
||||
import android.content.DialogInterface
|
||||
import android.content.Intent
|
||||
import android.graphics.PorterDuff
|
||||
import android.os.Build
|
||||
import android.provider.DocumentsContract
|
||||
import android.text.format.DateFormat
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.color.MaterialColors
|
||||
import com.google.android.material.datepicker.CalendarConstraints
|
||||
import com.google.android.material.datepicker.MaterialDatePicker
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.elevation.ElevationOverlayProvider
|
||||
import com.google.android.material.slider.Slider
|
||||
import com.google.android.material.timepicker.MaterialTimePicker
|
||||
import com.google.android.material.timepicker.TimeFormat
|
||||
import org.dolphinemu.dolphinemu.R
|
||||
import org.dolphinemu.dolphinemu.databinding.*
|
||||
import org.dolphinemu.dolphinemu.features.input.model.view.InputMappingControlSetting
|
||||
import org.dolphinemu.dolphinemu.features.input.ui.AdvancedMappingDialog
|
||||
import org.dolphinemu.dolphinemu.features.input.ui.MotionAlertDialog
|
||||
import org.dolphinemu.dolphinemu.features.input.ui.viewholder.InputMappingControlSettingViewHolder
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.view.*
|
||||
import org.dolphinemu.dolphinemu.features.settings.ui.viewholder.*
|
||||
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization
|
||||
import org.dolphinemu.dolphinemu.utils.FileBrowserHelper
|
||||
import org.dolphinemu.dolphinemu.utils.Log
|
||||
import org.dolphinemu.dolphinemu.utils.PermissionsHandler
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.io.RandomAccessFile
|
||||
import java.util.*
|
||||
|
||||
class SettingsAdapter(
|
||||
private val fragmentView: SettingsFragmentView,
|
||||
private val context: Context
|
||||
) :
|
||||
RecyclerView.Adapter<SettingViewHolder>(), DialogInterface.OnClickListener,
|
||||
Slider.OnChangeListener {
|
||||
private var settingsList: ArrayList<SettingsItem>? = null
|
||||
private var clickedItem: SettingsItem? = null
|
||||
private var clickedPosition: Int = -1
|
||||
private var seekbarProgress = 0
|
||||
private var dialog: AlertDialog? = null
|
||||
private var textSliderValue: TextView? = null
|
||||
|
||||
val settings: Settings?
|
||||
get() = fragmentView.settings
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SettingViewHolder {
|
||||
val inflater = LayoutInflater.from(parent.context)
|
||||
return when (viewType) {
|
||||
SettingsItem.TYPE_HEADER -> HeaderViewHolder(
|
||||
ListItemHeaderBinding.inflate(inflater),
|
||||
this
|
||||
)
|
||||
SettingsItem.TYPE_SWITCH -> SwitchSettingViewHolder(
|
||||
ListItemSettingSwitchBinding.inflate(inflater),
|
||||
this
|
||||
)
|
||||
SettingsItem.TYPE_STRING_SINGLE_CHOICE,
|
||||
SettingsItem.TYPE_SINGLE_CHOICE_DYNAMIC_DESCRIPTIONS,
|
||||
SettingsItem.TYPE_SINGLE_CHOICE -> SingleChoiceViewHolder(
|
||||
ListItemSettingBinding.inflate(inflater),
|
||||
this
|
||||
)
|
||||
SettingsItem.TYPE_SLIDER -> SliderViewHolder(
|
||||
ListItemSettingBinding.inflate(
|
||||
inflater
|
||||
), this, context
|
||||
)
|
||||
SettingsItem.TYPE_SUBMENU -> SubmenuViewHolder(
|
||||
ListItemSubmenuBinding.inflate(
|
||||
inflater
|
||||
), this
|
||||
)
|
||||
SettingsItem.TYPE_INPUT_MAPPING_CONTROL -> InputMappingControlSettingViewHolder(
|
||||
ListItemMappingBinding.inflate(inflater),
|
||||
this
|
||||
)
|
||||
SettingsItem.TYPE_FILE_PICKER -> FilePickerViewHolder(
|
||||
ListItemSettingBinding.inflate(
|
||||
inflater
|
||||
), this
|
||||
)
|
||||
SettingsItem.TYPE_RUN_RUNNABLE -> RunRunnableViewHolder(
|
||||
ListItemSettingBinding.inflate(
|
||||
inflater
|
||||
), this, context
|
||||
)
|
||||
SettingsItem.TYPE_STRING -> InputStringSettingViewHolder(
|
||||
ListItemSettingBinding.inflate(
|
||||
inflater
|
||||
), this
|
||||
)
|
||||
SettingsItem.TYPE_HYPERLINK_HEADER -> HeaderHyperLinkViewHolder(
|
||||
ListItemHeaderBinding.inflate(
|
||||
inflater
|
||||
), this
|
||||
)
|
||||
SettingsItem.TYPE_DATETIME_CHOICE -> DateTimeSettingViewHolder(
|
||||
ListItemSettingBinding.inflate(
|
||||
inflater
|
||||
), this
|
||||
)
|
||||
else -> throw IllegalArgumentException("Invalid view type: $viewType")
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: SettingViewHolder, position: Int) {
|
||||
holder.bind(getItem(position))
|
||||
}
|
||||
|
||||
private fun getItem(position: Int): SettingsItem {
|
||||
return settingsList!![position]
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return if (settingsList != null) {
|
||||
settingsList!!.size
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemViewType(position: Int): Int {
|
||||
return getItem(position).type
|
||||
}
|
||||
|
||||
fun setSettings(settings: ArrayList<SettingsItem>?) {
|
||||
settingsList = settings
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
fun clearSetting(item: SettingsItem) {
|
||||
item.clear(settings!!)
|
||||
fragmentView.onSettingChanged()
|
||||
}
|
||||
|
||||
fun notifyAllSettingsChanged() {
|
||||
notifyItemRangeChanged(0, itemCount)
|
||||
fragmentView.onSettingChanged()
|
||||
}
|
||||
|
||||
fun onBooleanClick(item: SwitchSetting, checked: Boolean) {
|
||||
item.setChecked(settings, checked)
|
||||
fragmentView.onSettingChanged()
|
||||
}
|
||||
|
||||
fun onInputStringClick(item: InputStringSetting, position: Int) {
|
||||
val inflater = LayoutInflater.from(context)
|
||||
val binding = DialogInputStringBinding.inflate(inflater)
|
||||
val input = binding.input
|
||||
input.setText(item.selectedValue)
|
||||
dialog = MaterialAlertDialogBuilder(fragmentView.fragmentActivity)
|
||||
.setView(binding.root)
|
||||
.setMessage(item.description)
|
||||
.setPositiveButton(R.string.ok) { _: DialogInterface?, _: Int ->
|
||||
val editTextInput = input.text.toString()
|
||||
if (item.selectedValue != editTextInput) {
|
||||
notifyItemChanged(position)
|
||||
fragmentView.onSettingChanged()
|
||||
}
|
||||
item.setSelectedValue(fragmentView.settings!!, editTextInput)
|
||||
}
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.show()
|
||||
}
|
||||
|
||||
fun onSingleChoiceClick(item: SingleChoiceSetting, position: Int) {
|
||||
clickedItem = item
|
||||
clickedPosition = position
|
||||
val value = getSelectionForSingleChoiceValue(item)
|
||||
dialog = MaterialAlertDialogBuilder(fragmentView.fragmentActivity)
|
||||
.setTitle(item.name)
|
||||
.setSingleChoiceItems(item.choicesId, value, this)
|
||||
.show()
|
||||
}
|
||||
|
||||
fun onStringSingleChoiceClick(item: StringSingleChoiceSetting, position: Int) {
|
||||
clickedItem = item
|
||||
clickedPosition = position
|
||||
item.refreshChoicesAndValues()
|
||||
val choices = item.choices
|
||||
val noChoicesAvailableString = item.noChoicesAvailableString
|
||||
dialog = if (noChoicesAvailableString != 0 && choices!!.isEmpty()) {
|
||||
MaterialAlertDialogBuilder(fragmentView.fragmentActivity)
|
||||
.setTitle(item.name)
|
||||
.setMessage(noChoicesAvailableString)
|
||||
.setPositiveButton(R.string.ok, null)
|
||||
.show()
|
||||
} else {
|
||||
MaterialAlertDialogBuilder(fragmentView.fragmentActivity)
|
||||
.setTitle(item.name)
|
||||
.setSingleChoiceItems(
|
||||
item.choices, item.selectedValueIndex,
|
||||
this
|
||||
)
|
||||
.show()
|
||||
}
|
||||
}
|
||||
|
||||
fun onSingleChoiceDynamicDescriptionsClick(
|
||||
item: SingleChoiceSettingDynamicDescriptions,
|
||||
position: Int
|
||||
) {
|
||||
clickedItem = item
|
||||
clickedPosition = position
|
||||
|
||||
val value = getSelectionForSingleChoiceDynamicDescriptionsValue(item)
|
||||
|
||||
dialog = MaterialAlertDialogBuilder(fragmentView.fragmentActivity)
|
||||
.setTitle(item.name)
|
||||
.setSingleChoiceItems(item.choicesId, value, this)
|
||||
.show()
|
||||
}
|
||||
|
||||
fun onSliderClick(item: SliderSetting, position: Int) {
|
||||
clickedItem = item
|
||||
clickedPosition = position
|
||||
seekbarProgress = item.selectedValue
|
||||
|
||||
val inflater = LayoutInflater.from(fragmentView.fragmentActivity)
|
||||
val binding = DialogSliderBinding.inflate(inflater)
|
||||
|
||||
textSliderValue = binding.textValue
|
||||
textSliderValue!!.text = seekbarProgress.toString()
|
||||
|
||||
binding.textUnits.text = item.units
|
||||
|
||||
val slider = binding.slider
|
||||
slider.valueFrom = item.min.toFloat()
|
||||
slider.valueTo = item.max.toFloat()
|
||||
slider.value = seekbarProgress.toFloat()
|
||||
slider.stepSize = item.stepSize.toFloat()
|
||||
slider.addOnChangeListener(this)
|
||||
|
||||
dialog = MaterialAlertDialogBuilder(fragmentView.fragmentActivity)
|
||||
.setTitle(item.name)
|
||||
.setView(binding.root)
|
||||
.setPositiveButton(R.string.ok, this)
|
||||
.show()
|
||||
}
|
||||
|
||||
fun onSubmenuClick(item: SubmenuSetting) {
|
||||
fragmentView.loadSubMenu(item.menuKey)
|
||||
}
|
||||
|
||||
fun onInputMappingClick(item: InputMappingControlSetting, position: Int) {
|
||||
if (item.controller.defaultDevice.isEmpty() && !fragmentView.isMappingAllDevices) {
|
||||
MaterialAlertDialogBuilder(fragmentView.fragmentActivity)
|
||||
.setMessage(R.string.input_binding_no_device)
|
||||
.setPositiveButton(R.string.ok, this)
|
||||
.show()
|
||||
return
|
||||
}
|
||||
|
||||
val dialog = MotionAlertDialog(
|
||||
fragmentView.fragmentActivity, item,
|
||||
fragmentView.isMappingAllDevices
|
||||
)
|
||||
|
||||
val background = ContextCompat.getDrawable(context, R.drawable.dialog_round)
|
||||
@ColorInt val color = ElevationOverlayProvider(dialog.context).compositeOverlay(
|
||||
MaterialColors.getColor(dialog.window!!.decorView, R.attr.colorSurface),
|
||||
dialog.window!!.decorView.elevation
|
||||
)
|
||||
background!!.setColorFilter(color, PorterDuff.Mode.SRC_ATOP)
|
||||
dialog.window!!.setBackgroundDrawable(background)
|
||||
|
||||
dialog.setTitle(R.string.input_binding)
|
||||
dialog.setMessage(
|
||||
String.format(
|
||||
context.getString(R.string.input_binding_description),
|
||||
item.name
|
||||
)
|
||||
)
|
||||
dialog.setButton(AlertDialog.BUTTON_NEGATIVE, context.getString(R.string.cancel), this)
|
||||
dialog.setButton(
|
||||
AlertDialog.BUTTON_NEUTRAL,
|
||||
context.getString(R.string.clear)
|
||||
) { _: DialogInterface?, _: Int -> item.clearValue() }
|
||||
dialog.setOnDismissListener {
|
||||
notifyItemChanged(position)
|
||||
fragmentView.onSettingChanged()
|
||||
}
|
||||
dialog.setCanceledOnTouchOutside(false)
|
||||
dialog.show()
|
||||
}
|
||||
|
||||
fun onAdvancedInputMappingClick(item: InputMappingControlSetting, position: Int) {
|
||||
val inflater = LayoutInflater.from(context)
|
||||
val binding = DialogAdvancedMappingBinding.inflate(inflater)
|
||||
val dialog = AdvancedMappingDialog(
|
||||
context,
|
||||
binding,
|
||||
item.controlReference,
|
||||
item.controller
|
||||
)
|
||||
|
||||
val background = ContextCompat.getDrawable(context, R.drawable.dialog_round)
|
||||
@ColorInt val color = ElevationOverlayProvider(dialog.context).compositeOverlay(
|
||||
MaterialColors.getColor(dialog.window!!.decorView, R.attr.colorSurface),
|
||||
dialog.window!!.decorView.elevation
|
||||
)
|
||||
background!!.setColorFilter(color, PorterDuff.Mode.SRC_ATOP)
|
||||
dialog.window!!.setBackgroundDrawable(background)
|
||||
|
||||
dialog.setTitle(if (item.isInput) R.string.input_configure_input else R.string.input_configure_output)
|
||||
dialog.setView(binding.root)
|
||||
dialog.setButton(
|
||||
AlertDialog.BUTTON_POSITIVE, context.getString(R.string.ok)
|
||||
) { _: DialogInterface?, _: Int ->
|
||||
item.value = dialog.expression
|
||||
notifyItemChanged(position)
|
||||
fragmentView.onSettingChanged()
|
||||
}
|
||||
dialog.setButton(AlertDialog.BUTTON_NEGATIVE, context.getString(R.string.cancel), this)
|
||||
dialog.setButton(
|
||||
AlertDialog.BUTTON_NEUTRAL,
|
||||
context.getString(R.string.clear)
|
||||
) { _: DialogInterface?, _: Int ->
|
||||
item.clearValue()
|
||||
notifyItemChanged(position)
|
||||
fragmentView.onSettingChanged()
|
||||
}
|
||||
dialog.setCanceledOnTouchOutside(false)
|
||||
dialog.show()
|
||||
}
|
||||
|
||||
fun onFilePickerDirectoryClick(item: SettingsItem?, position: Int) {
|
||||
clickedItem = item
|
||||
clickedPosition = position
|
||||
|
||||
if (!PermissionsHandler.isExternalStorageLegacy()) {
|
||||
MaterialAlertDialogBuilder(context)
|
||||
.setMessage(R.string.path_not_changeable_scoped_storage)
|
||||
.setPositiveButton(R.string.ok) { dialog: DialogInterface, _: Int -> dialog.dismiss() }
|
||||
.show()
|
||||
} else {
|
||||
FileBrowserHelper.openDirectoryPicker(
|
||||
fragmentView.fragmentActivity,
|
||||
FileBrowserHelper.GAME_EXTENSIONS
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun onFilePickerFileClick(item: SettingsItem, position: Int) {
|
||||
clickedItem = item
|
||||
clickedPosition = position
|
||||
val filePicker = item as FilePicker
|
||||
|
||||
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE)
|
||||
intent.type = "*/*"
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, filePicker.getSelectedValue())
|
||||
}
|
||||
|
||||
fragmentView.fragmentActivity.startActivityForResult(intent, filePicker.requestType)
|
||||
}
|
||||
|
||||
fun onDateTimeClick(item: DateTimeChoiceSetting, position: Int) {
|
||||
clickedItem = item
|
||||
clickedPosition = position
|
||||
val storedTime = java.lang.Long.decode(item.getSelectedValue()) * 1000
|
||||
|
||||
// Helper to extract hour and minute from epoch time
|
||||
val calendar = Calendar.getInstance()
|
||||
calendar.timeInMillis = storedTime
|
||||
calendar.timeZone = TimeZone.getTimeZone("UTC")
|
||||
|
||||
// Start and end epoch times available for the Wii's date picker
|
||||
val calendarConstraints = CalendarConstraints.Builder()
|
||||
.setStart(946684800000L)
|
||||
.setEnd(2082672000000L)
|
||||
.build()
|
||||
|
||||
var timeFormat = TimeFormat.CLOCK_12H
|
||||
if (DateFormat.is24HourFormat(fragmentView.fragmentActivity)) {
|
||||
timeFormat = TimeFormat.CLOCK_24H
|
||||
}
|
||||
|
||||
val datePicker = MaterialDatePicker.Builder.datePicker()
|
||||
.setSelection(storedTime)
|
||||
.setTitleText(R.string.select_rtc_date)
|
||||
.setCalendarConstraints(calendarConstraints)
|
||||
.build()
|
||||
val timePicker = MaterialTimePicker.Builder()
|
||||
.setTimeFormat(timeFormat)
|
||||
.setHour(calendar[Calendar.HOUR_OF_DAY])
|
||||
.setMinute(calendar[Calendar.MINUTE])
|
||||
.setTitleText(R.string.select_rtc_time)
|
||||
.build()
|
||||
|
||||
datePicker.addOnPositiveButtonClickListener {
|
||||
timePicker.show(
|
||||
fragmentView.fragmentActivity.supportFragmentManager,
|
||||
"TimePicker"
|
||||
)
|
||||
}
|
||||
timePicker.addOnPositiveButtonClickListener {
|
||||
var epochTime = datePicker.selection!! / 1000
|
||||
epochTime += timePicker.hour.toLong() * 60 * 60
|
||||
epochTime += timePicker.minute.toLong() * 60
|
||||
val rtcString = "0x" + java.lang.Long.toHexString(epochTime)
|
||||
if (item.getSelectedValue() != rtcString) {
|
||||
notifyItemChanged(clickedPosition)
|
||||
fragmentView.onSettingChanged()
|
||||
}
|
||||
item.setSelectedValue(fragmentView.settings!!, rtcString)
|
||||
clickedItem = null
|
||||
}
|
||||
datePicker.show(fragmentView.fragmentActivity.supportFragmentManager, "DatePicker")
|
||||
}
|
||||
|
||||
fun onFilePickerConfirmation(selectedFile: String) {
|
||||
val filePicker = clickedItem as FilePicker?
|
||||
|
||||
if (filePicker!!.getSelectedValue() != selectedFile) {
|
||||
notifyItemChanged(clickedPosition)
|
||||
fragmentView.onSettingChanged()
|
||||
}
|
||||
|
||||
filePicker.setSelectedValue(fragmentView.settings!!, selectedFile)
|
||||
|
||||
clickedItem = null
|
||||
}
|
||||
|
||||
fun onMenuTagAction(menuTag: MenuTag, value: Int) {
|
||||
fragmentView.onMenuTagAction(menuTag, value)
|
||||
}
|
||||
|
||||
fun hasMenuTagActionForValue(menuTag: MenuTag, value: Int): Boolean {
|
||||
return fragmentView.hasMenuTagActionForValue(menuTag, value)
|
||||
}
|
||||
|
||||
override fun onClick(dialog: DialogInterface, which: Int) {
|
||||
when (clickedItem) {
|
||||
is SingleChoiceSetting -> {
|
||||
val scSetting = clickedItem as SingleChoiceSetting
|
||||
|
||||
val value = getValueForSingleChoiceSelection(scSetting, which)
|
||||
if (scSetting.selectedValue != value) fragmentView.onSettingChanged()
|
||||
|
||||
scSetting.setSelectedValue(settings, value)
|
||||
|
||||
closeDialog()
|
||||
}
|
||||
is SingleChoiceSettingDynamicDescriptions -> {
|
||||
val scSetting = clickedItem as SingleChoiceSettingDynamicDescriptions
|
||||
|
||||
val value = getValueForSingleChoiceDynamicDescriptionsSelection(scSetting, which)
|
||||
if (scSetting.selectedValue != value) fragmentView.onSettingChanged()
|
||||
|
||||
scSetting.setSelectedValue(settings!!, value)
|
||||
|
||||
closeDialog()
|
||||
}
|
||||
is StringSingleChoiceSetting -> {
|
||||
val scSetting = clickedItem as StringSingleChoiceSetting
|
||||
|
||||
val value = scSetting.getValueAt(which)
|
||||
if (scSetting.selectedValue != value) fragmentView.onSettingChanged()
|
||||
|
||||
scSetting.setSelectedValue(settings, value)
|
||||
|
||||
closeDialog()
|
||||
}
|
||||
is IntSliderSetting -> {
|
||||
val sliderSetting = clickedItem as IntSliderSetting
|
||||
if (sliderSetting.selectedValue != seekbarProgress) fragmentView.onSettingChanged()
|
||||
sliderSetting.setSelectedValue(settings, seekbarProgress)
|
||||
closeDialog()
|
||||
}
|
||||
is FloatSliderSetting -> {
|
||||
val sliderSetting = clickedItem as FloatSliderSetting
|
||||
|
||||
if (sliderSetting.selectedValue != seekbarProgress) fragmentView.onSettingChanged()
|
||||
|
||||
sliderSetting.setSelectedValue(settings, seekbarProgress.toFloat())
|
||||
|
||||
closeDialog()
|
||||
}
|
||||
}
|
||||
clickedItem = null
|
||||
seekbarProgress = -1
|
||||
}
|
||||
|
||||
fun closeDialog() {
|
||||
if (dialog != null) {
|
||||
if (clickedPosition != -1) {
|
||||
notifyItemChanged(clickedPosition)
|
||||
clickedPosition = -1
|
||||
}
|
||||
dialog!!.dismiss()
|
||||
dialog = null
|
||||
}
|
||||
}
|
||||
|
||||
override fun onValueChange(slider: Slider, progress: Float, fromUser: Boolean) {
|
||||
seekbarProgress = progress.toInt()
|
||||
textSliderValue!!.text = seekbarProgress.toString()
|
||||
}
|
||||
|
||||
private fun getValueForSingleChoiceSelection(item: SingleChoiceSetting, which: Int): Int {
|
||||
val valuesId = item.valuesId
|
||||
|
||||
return if (valuesId > 0) {
|
||||
val valuesArray = context.resources.getIntArray(valuesId)
|
||||
valuesArray[which]
|
||||
} else {
|
||||
which
|
||||
}
|
||||
}
|
||||
|
||||
private fun getSelectionForSingleChoiceValue(item: SingleChoiceSetting): Int {
|
||||
val value = item.selectedValue
|
||||
val valuesId = item.valuesId
|
||||
|
||||
if (valuesId > 0) {
|
||||
val valuesArray = context.resources.getIntArray(valuesId)
|
||||
for (index in valuesArray.indices) {
|
||||
val current = valuesArray[index]
|
||||
if (current == value) {
|
||||
return index
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return value
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
private fun getValueForSingleChoiceDynamicDescriptionsSelection(
|
||||
item: SingleChoiceSettingDynamicDescriptions,
|
||||
which: Int
|
||||
): Int {
|
||||
val valuesId = item.valuesId
|
||||
return if (valuesId > 0) {
|
||||
val valuesArray = context.resources.getIntArray(valuesId)
|
||||
valuesArray[which]
|
||||
} else {
|
||||
which
|
||||
}
|
||||
}
|
||||
|
||||
private fun getSelectionForSingleChoiceDynamicDescriptionsValue(
|
||||
item: SingleChoiceSettingDynamicDescriptions
|
||||
): Int {
|
||||
val value = item.selectedValue
|
||||
val valuesId = item.valuesId
|
||||
if (valuesId > 0) {
|
||||
val valuesArray = context.resources.getIntArray(valuesId)
|
||||
for (index in valuesArray.indices) {
|
||||
val current = valuesArray[index]
|
||||
if (current == value) {
|
||||
return index
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return value
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun clearLog() {
|
||||
// Don't delete the log in case it is being monitored by another app.
|
||||
val log = File(DirectoryInitialization.getUserDirectory() + "/Logs/dolphin.log")
|
||||
try {
|
||||
val raf = RandomAccessFile(log, "rw")
|
||||
raf.setLength(0)
|
||||
} catch (e: IOException) {
|
||||
Log.error("[SettingsAdapter] Failed to clear log file: " + e.message)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,295 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.ui;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.graphics.Insets;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.core.view.WindowInsetsCompat;
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import org.dolphinemu.dolphinemu.R;
|
||||
import org.dolphinemu.dolphinemu.databinding.FragmentSettingsBinding;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public final class SettingsFragment extends Fragment implements SettingsFragmentView
|
||||
{
|
||||
private static final String ARGUMENT_MENU_TAG = "menu_tag";
|
||||
private static final String ARGUMENT_GAME_ID = "game_id";
|
||||
|
||||
private SettingsFragmentPresenter mPresenter;
|
||||
private SettingsActivityView mActivity;
|
||||
|
||||
private SettingsAdapter mAdapter;
|
||||
|
||||
private int mOldControllerSettingsWarningHeight = 0;
|
||||
|
||||
private static final Map<MenuTag, Integer> titles = new HashMap<>();
|
||||
|
||||
static
|
||||
{
|
||||
titles.put(MenuTag.SETTINGS, R.string.settings);
|
||||
titles.put(MenuTag.CONFIG, R.string.config);
|
||||
titles.put(MenuTag.CONFIG_GENERAL, R.string.general_submenu);
|
||||
titles.put(MenuTag.CONFIG_INTERFACE, R.string.interface_submenu);
|
||||
titles.put(MenuTag.CONFIG_AUDIO, R.string.audio_submenu);
|
||||
titles.put(MenuTag.CONFIG_PATHS, R.string.paths_submenu);
|
||||
titles.put(MenuTag.CONFIG_GAME_CUBE, R.string.gamecube_submenu);
|
||||
titles.put(MenuTag.CONFIG_SERIALPORT1, R.string.serialport1_submenu);
|
||||
titles.put(MenuTag.CONFIG_WII, R.string.wii_submenu);
|
||||
titles.put(MenuTag.CONFIG_ADVANCED, R.string.advanced_submenu);
|
||||
titles.put(MenuTag.DEBUG, R.string.debug_submenu);
|
||||
titles.put(MenuTag.GRAPHICS, R.string.graphics_settings);
|
||||
titles.put(MenuTag.ENHANCEMENTS, R.string.enhancements_submenu);
|
||||
titles.put(MenuTag.STEREOSCOPY, R.string.stereoscopy_submenu);
|
||||
titles.put(MenuTag.HACKS, R.string.hacks_submenu);
|
||||
titles.put(MenuTag.STATISTICS, R.string.statistics_submenu);
|
||||
titles.put(MenuTag.ADVANCED_GRAPHICS, R.string.advanced_graphics_submenu);
|
||||
titles.put(MenuTag.CONFIG_LOG, R.string.log_submenu);
|
||||
titles.put(MenuTag.GCPAD_TYPE, R.string.gcpad_settings);
|
||||
titles.put(MenuTag.WIIMOTE, R.string.wiimote_settings);
|
||||
titles.put(MenuTag.WIIMOTE_EXTENSION, R.string.wiimote_extensions);
|
||||
titles.put(MenuTag.GCPAD_1, R.string.controller_0);
|
||||
titles.put(MenuTag.GCPAD_2, R.string.controller_1);
|
||||
titles.put(MenuTag.GCPAD_3, R.string.controller_2);
|
||||
titles.put(MenuTag.GCPAD_4, R.string.controller_3);
|
||||
titles.put(MenuTag.WIIMOTE_1, R.string.wiimote_0);
|
||||
titles.put(MenuTag.WIIMOTE_2, R.string.wiimote_1);
|
||||
titles.put(MenuTag.WIIMOTE_3, R.string.wiimote_2);
|
||||
titles.put(MenuTag.WIIMOTE_4, R.string.wiimote_3);
|
||||
titles.put(MenuTag.WIIMOTE_EXTENSION_1, R.string.wiimote_extension_0);
|
||||
titles.put(MenuTag.WIIMOTE_EXTENSION_2, R.string.wiimote_extension_1);
|
||||
titles.put(MenuTag.WIIMOTE_EXTENSION_3, R.string.wiimote_extension_2);
|
||||
titles.put(MenuTag.WIIMOTE_EXTENSION_4, R.string.wiimote_extension_3);
|
||||
titles.put(MenuTag.WIIMOTE_GENERAL_1, R.string.wiimote_general);
|
||||
titles.put(MenuTag.WIIMOTE_GENERAL_2, R.string.wiimote_general);
|
||||
titles.put(MenuTag.WIIMOTE_GENERAL_3, R.string.wiimote_general);
|
||||
titles.put(MenuTag.WIIMOTE_GENERAL_4, R.string.wiimote_general);
|
||||
titles.put(MenuTag.WIIMOTE_MOTION_SIMULATION_1, R.string.wiimote_motion_simulation);
|
||||
titles.put(MenuTag.WIIMOTE_MOTION_SIMULATION_2, R.string.wiimote_motion_simulation);
|
||||
titles.put(MenuTag.WIIMOTE_MOTION_SIMULATION_3, R.string.wiimote_motion_simulation);
|
||||
titles.put(MenuTag.WIIMOTE_MOTION_SIMULATION_4, R.string.wiimote_motion_simulation);
|
||||
titles.put(MenuTag.WIIMOTE_MOTION_INPUT_1, R.string.wiimote_motion_input);
|
||||
titles.put(MenuTag.WIIMOTE_MOTION_INPUT_2, R.string.wiimote_motion_input);
|
||||
titles.put(MenuTag.WIIMOTE_MOTION_INPUT_3, R.string.wiimote_motion_input);
|
||||
titles.put(MenuTag.WIIMOTE_MOTION_INPUT_4, R.string.wiimote_motion_input);
|
||||
}
|
||||
|
||||
private FragmentSettingsBinding mBinding;
|
||||
|
||||
public static Fragment newInstance(MenuTag menuTag, String gameId, Bundle extras)
|
||||
{
|
||||
SettingsFragment fragment = new SettingsFragment();
|
||||
|
||||
Bundle arguments = new Bundle();
|
||||
if (extras != null)
|
||||
{
|
||||
arguments.putAll(extras);
|
||||
}
|
||||
|
||||
arguments.putSerializable(ARGUMENT_MENU_TAG, menuTag);
|
||||
arguments.putString(ARGUMENT_GAME_ID, gameId);
|
||||
|
||||
fragment.setArguments(arguments);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(@NonNull Context context)
|
||||
{
|
||||
super.onAttach(context);
|
||||
|
||||
mActivity = (SettingsActivityView) context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
Bundle args = getArguments();
|
||||
MenuTag menuTag = (MenuTag) args.getSerializable(ARGUMENT_MENU_TAG);
|
||||
String gameId = getArguments().getString(ARGUMENT_GAME_ID);
|
||||
|
||||
mPresenter = new SettingsFragmentPresenter(this, getContext());
|
||||
mAdapter = new SettingsAdapter(this, getContext());
|
||||
|
||||
mPresenter.onCreate(menuTag, gameId, args);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
mBinding = FragmentSettingsBinding.inflate(inflater, container, false);
|
||||
return mBinding.getRoot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState)
|
||||
{
|
||||
Bundle args = getArguments();
|
||||
MenuTag menuTag = (MenuTag) args.getSerializable(ARGUMENT_MENU_TAG);
|
||||
|
||||
if (titles.containsKey(menuTag))
|
||||
{
|
||||
mActivity.setToolbarTitle(getString(titles.get(menuTag)));
|
||||
}
|
||||
|
||||
LinearLayoutManager manager = new LinearLayoutManager(getActivity());
|
||||
|
||||
RecyclerView recyclerView = mBinding.listSettings;
|
||||
|
||||
recyclerView.setAdapter(mAdapter);
|
||||
recyclerView.setLayoutManager(manager);
|
||||
|
||||
SettingsDividerItemDecoration divider = new SettingsDividerItemDecoration(requireActivity());
|
||||
recyclerView.addItemDecoration(divider);
|
||||
|
||||
setInsets();
|
||||
|
||||
SettingsActivityView activity = (SettingsActivityView) getActivity();
|
||||
mPresenter.onViewCreated(menuTag, activity.getSettings());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView()
|
||||
{
|
||||
super.onDestroyView();
|
||||
mBinding = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetach()
|
||||
{
|
||||
super.onDetach();
|
||||
mActivity = null;
|
||||
|
||||
if (mAdapter != null)
|
||||
{
|
||||
mAdapter.closeDialog();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSettingsFileLoaded(
|
||||
org.dolphinemu.dolphinemu.features.settings.model.Settings settings)
|
||||
{
|
||||
mPresenter.setSettings(settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showSettingsList(ArrayList<SettingsItem> settingsList)
|
||||
{
|
||||
mAdapter.setSettings(settingsList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadDefaultSettings()
|
||||
{
|
||||
mPresenter.loadDefaultSettings();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SettingsAdapter getAdapter()
|
||||
{
|
||||
return mAdapter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSubMenu(MenuTag menuKey)
|
||||
{
|
||||
mActivity.showSettingsFragment(menuKey, null, true, getArguments().getString(ARGUMENT_GAME_ID));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showDialogFragment(DialogFragment fragment)
|
||||
{
|
||||
mActivity.showDialogFragment(fragment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showToastMessage(String message)
|
||||
{
|
||||
mActivity.showToastMessage(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Settings getSettings()
|
||||
{
|
||||
return mPresenter.getSettings();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSettingChanged()
|
||||
{
|
||||
mActivity.onSettingChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onControllerSettingsChanged()
|
||||
{
|
||||
mAdapter.notifyAllSettingsChanged();
|
||||
mPresenter.updateOldControllerSettingsWarningVisibility();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMenuTagAction(@NonNull MenuTag menuTag, int value)
|
||||
{
|
||||
mActivity.onMenuTagAction(menuTag, value);
|
||||
}
|
||||
|
||||
public boolean hasMenuTagActionForValue(@NonNull MenuTag menuTag, int value)
|
||||
{
|
||||
return mActivity.hasMenuTagActionForValue(menuTag, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMappingAllDevices(boolean allDevices)
|
||||
{
|
||||
mActivity.setMappingAllDevices(allDevices);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMappingAllDevices()
|
||||
{
|
||||
return mActivity.isMappingAllDevices();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOldControllerSettingsWarningVisibility(boolean visible)
|
||||
{
|
||||
mOldControllerSettingsWarningHeight =
|
||||
mActivity.setOldControllerSettingsWarningVisibility(visible);
|
||||
|
||||
// Trigger the insets listener we've registered
|
||||
mBinding.listSettings.requestApplyInsets();
|
||||
}
|
||||
|
||||
private void setInsets()
|
||||
{
|
||||
ViewCompat.setOnApplyWindowInsetsListener(mBinding.listSettings, (v, windowInsets) ->
|
||||
{
|
||||
Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars());
|
||||
int listSpacing = getResources().getDimensionPixelSize(R.dimen.spacing_list);
|
||||
v.setPadding(0, 0, 0, insets.bottom + listSpacing + mOldControllerSettingsWarningHeight);
|
||||
return windowInsets;
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,242 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.ui
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.core.view.updatePadding
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import org.dolphinemu.dolphinemu.R
|
||||
import org.dolphinemu.dolphinemu.databinding.FragmentSettingsBinding
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem
|
||||
import org.dolphinemu.dolphinemu.utils.SerializableHelper.serializable
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
class SettingsFragment : Fragment(), SettingsFragmentView {
|
||||
private lateinit var presenter: SettingsFragmentPresenter
|
||||
private var activityView: SettingsActivityView? = null
|
||||
|
||||
private lateinit var menuTag: MenuTag
|
||||
|
||||
override val fragmentActivity: FragmentActivity
|
||||
get() = requireActivity()
|
||||
|
||||
override var adapter: SettingsAdapter? = null
|
||||
|
||||
private var oldControllerSettingsWarningHeight = 0
|
||||
|
||||
private var binding: FragmentSettingsBinding? = null
|
||||
|
||||
override fun onAttach(context: Context) {
|
||||
super.onAttach(context)
|
||||
|
||||
activityView = context as SettingsActivityView
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
menuTag = requireArguments().serializable(ARGUMENT_MENU_TAG)!!
|
||||
|
||||
val gameId = requireArguments().getString(ARGUMENT_GAME_ID)
|
||||
presenter = SettingsFragmentPresenter(this, requireContext())
|
||||
adapter = SettingsAdapter(this, requireContext())
|
||||
|
||||
presenter.onCreate(menuTag, gameId, requireArguments())
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
binding = FragmentSettingsBinding.inflate(inflater, container, false)
|
||||
return binding!!.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
if (titles.containsKey(menuTag)) {
|
||||
activityView!!.setToolbarTitle(getString(titles[menuTag]!!))
|
||||
}
|
||||
|
||||
val manager = LinearLayoutManager(activity)
|
||||
|
||||
val recyclerView = binding!!.listSettings
|
||||
recyclerView.adapter = adapter
|
||||
recyclerView.layoutManager = manager
|
||||
|
||||
val divider = SettingsDividerItemDecoration(requireActivity())
|
||||
recyclerView.addItemDecoration(divider)
|
||||
|
||||
setInsets()
|
||||
|
||||
val activity = activity as SettingsActivityView?
|
||||
presenter.onViewCreated(menuTag, activity!!.settings)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
binding = null
|
||||
}
|
||||
|
||||
override fun onDetach() {
|
||||
super.onDetach()
|
||||
activityView = null
|
||||
|
||||
if (adapter != null) {
|
||||
adapter!!.closeDialog()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSettingsFileLoaded(settings: Settings) {
|
||||
presenter.settings = settings
|
||||
}
|
||||
|
||||
override fun showSettingsList(settingsList: ArrayList<SettingsItem>) {
|
||||
adapter!!.setSettings(settingsList)
|
||||
}
|
||||
|
||||
override fun loadDefaultSettings() {
|
||||
presenter.loadDefaultSettings()
|
||||
}
|
||||
|
||||
override fun loadSubMenu(menuKey: MenuTag) {
|
||||
activityView!!.showSettingsFragment(
|
||||
menuKey,
|
||||
null,
|
||||
true,
|
||||
requireArguments().getString(ARGUMENT_GAME_ID)!!
|
||||
)
|
||||
}
|
||||
|
||||
override fun showDialogFragment(fragment: DialogFragment) {
|
||||
activityView!!.showDialogFragment(fragment)
|
||||
}
|
||||
|
||||
override fun showToastMessage(message: String) {
|
||||
activityView!!.showToastMessage(message)
|
||||
}
|
||||
|
||||
override val settings: Settings?
|
||||
get() = presenter.settings
|
||||
|
||||
override fun onSettingChanged() {
|
||||
activityView!!.onSettingChanged()
|
||||
}
|
||||
|
||||
override fun onControllerSettingsChanged() {
|
||||
adapter!!.notifyAllSettingsChanged()
|
||||
presenter.updateOldControllerSettingsWarningVisibility()
|
||||
}
|
||||
|
||||
override fun onMenuTagAction(menuTag: MenuTag, value: Int) {
|
||||
activityView!!.onMenuTagAction(menuTag, value)
|
||||
}
|
||||
|
||||
override fun hasMenuTagActionForValue(menuTag: MenuTag, value: Int): Boolean {
|
||||
return activityView!!.hasMenuTagActionForValue(menuTag, value)
|
||||
}
|
||||
|
||||
override var isMappingAllDevices: Boolean
|
||||
get() = activityView!!.isMappingAllDevices
|
||||
set(allDevices) {
|
||||
activityView!!.isMappingAllDevices = allDevices
|
||||
}
|
||||
|
||||
override fun setOldControllerSettingsWarningVisibility(visible: Boolean) {
|
||||
oldControllerSettingsWarningHeight =
|
||||
activityView!!.setOldControllerSettingsWarningVisibility(visible)
|
||||
|
||||
// Trigger the insets listener we've registered
|
||||
binding!!.listSettings.requestApplyInsets()
|
||||
}
|
||||
|
||||
private fun setInsets() {
|
||||
ViewCompat.setOnApplyWindowInsetsListener(binding!!.listSettings) { v: View, windowInsets: WindowInsetsCompat ->
|
||||
val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||
val listSpacing = resources.getDimensionPixelSize(R.dimen.spacing_list)
|
||||
v.updatePadding(bottom = insets.bottom + listSpacing + oldControllerSettingsWarningHeight)
|
||||
windowInsets
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val ARGUMENT_MENU_TAG = "menu_tag"
|
||||
private const val ARGUMENT_GAME_ID = "game_id"
|
||||
private val titles: MutableMap<MenuTag, Int> = EnumMap(MenuTag::class.java)
|
||||
|
||||
init {
|
||||
titles[MenuTag.SETTINGS] = R.string.settings
|
||||
titles[MenuTag.CONFIG] = R.string.config
|
||||
titles[MenuTag.CONFIG_GENERAL] = R.string.general_submenu
|
||||
titles[MenuTag.CONFIG_INTERFACE] = R.string.interface_submenu
|
||||
titles[MenuTag.CONFIG_AUDIO] = R.string.audio_submenu
|
||||
titles[MenuTag.CONFIG_PATHS] = R.string.paths_submenu
|
||||
titles[MenuTag.CONFIG_GAME_CUBE] = R.string.gamecube_submenu
|
||||
titles[MenuTag.CONFIG_SERIALPORT1] = R.string.serialport1_submenu
|
||||
titles[MenuTag.CONFIG_WII] = R.string.wii_submenu
|
||||
titles[MenuTag.CONFIG_ADVANCED] = R.string.advanced_submenu
|
||||
titles[MenuTag.DEBUG] = R.string.debug_submenu
|
||||
titles[MenuTag.GRAPHICS] = R.string.graphics_settings
|
||||
titles[MenuTag.ENHANCEMENTS] = R.string.enhancements_submenu
|
||||
titles[MenuTag.STEREOSCOPY] = R.string.stereoscopy_submenu
|
||||
titles[MenuTag.HACKS] = R.string.hacks_submenu
|
||||
titles[MenuTag.STATISTICS] = R.string.statistics_submenu
|
||||
titles[MenuTag.ADVANCED_GRAPHICS] = R.string.advanced_graphics_submenu
|
||||
titles[MenuTag.CONFIG_LOG] = R.string.log_submenu
|
||||
titles[MenuTag.GCPAD_TYPE] = R.string.gcpad_settings
|
||||
titles[MenuTag.WIIMOTE] = R.string.wiimote_settings
|
||||
titles[MenuTag.WIIMOTE_EXTENSION] = R.string.wiimote_extensions
|
||||
titles[MenuTag.GCPAD_1] = R.string.controller_0
|
||||
titles[MenuTag.GCPAD_2] = R.string.controller_1
|
||||
titles[MenuTag.GCPAD_3] = R.string.controller_2
|
||||
titles[MenuTag.GCPAD_4] = R.string.controller_3
|
||||
titles[MenuTag.WIIMOTE_1] = R.string.wiimote_0
|
||||
titles[MenuTag.WIIMOTE_2] = R.string.wiimote_1
|
||||
titles[MenuTag.WIIMOTE_3] = R.string.wiimote_2
|
||||
titles[MenuTag.WIIMOTE_4] = R.string.wiimote_3
|
||||
titles[MenuTag.WIIMOTE_EXTENSION_1] = R.string.wiimote_extension_0
|
||||
titles[MenuTag.WIIMOTE_EXTENSION_2] = R.string.wiimote_extension_1
|
||||
titles[MenuTag.WIIMOTE_EXTENSION_3] = R.string.wiimote_extension_2
|
||||
titles[MenuTag.WIIMOTE_EXTENSION_4] = R.string.wiimote_extension_3
|
||||
titles[MenuTag.WIIMOTE_GENERAL_1] = R.string.wiimote_general
|
||||
titles[MenuTag.WIIMOTE_GENERAL_2] = R.string.wiimote_general
|
||||
titles[MenuTag.WIIMOTE_GENERAL_3] = R.string.wiimote_general
|
||||
titles[MenuTag.WIIMOTE_GENERAL_4] = R.string.wiimote_general
|
||||
titles[MenuTag.WIIMOTE_MOTION_SIMULATION_1] = R.string.wiimote_motion_simulation
|
||||
titles[MenuTag.WIIMOTE_MOTION_SIMULATION_2] = R.string.wiimote_motion_simulation
|
||||
titles[MenuTag.WIIMOTE_MOTION_SIMULATION_3] = R.string.wiimote_motion_simulation
|
||||
titles[MenuTag.WIIMOTE_MOTION_SIMULATION_4] = R.string.wiimote_motion_simulation
|
||||
titles[MenuTag.WIIMOTE_MOTION_INPUT_1] = R.string.wiimote_motion_input
|
||||
titles[MenuTag.WIIMOTE_MOTION_INPUT_2] = R.string.wiimote_motion_input
|
||||
titles[MenuTag.WIIMOTE_MOTION_INPUT_3] = R.string.wiimote_motion_input
|
||||
titles[MenuTag.WIIMOTE_MOTION_INPUT_4] = R.string.wiimote_motion_input
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun newInstance(menuTag: MenuTag?, gameId: String?, extras: Bundle?): Fragment {
|
||||
val fragment = SettingsFragment()
|
||||
|
||||
val arguments = Bundle()
|
||||
if (extras != null) {
|
||||
arguments.putAll(extras)
|
||||
}
|
||||
|
||||
arguments.putSerializable(ARGUMENT_MENU_TAG, menuTag)
|
||||
arguments.putString(ARGUMENT_GAME_ID, gameId)
|
||||
|
||||
fragment.arguments = arguments
|
||||
return fragment
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,123 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.ui;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Abstraction for a screen showing a list of settings. Instances of
|
||||
* this type of view will each display a layer of the setting hierarchy.
|
||||
*/
|
||||
public interface SettingsFragmentView
|
||||
{
|
||||
/**
|
||||
* Called by the containing Activity to notify the Fragment that an
|
||||
* asynchronous load operation completed.
|
||||
*
|
||||
* @param settings The (possibly null) result of the ini load operation.
|
||||
*/
|
||||
void onSettingsFileLoaded(Settings settings);
|
||||
|
||||
/**
|
||||
* Pass an ArrayList of settings to the View so that it can be displayed on screen.
|
||||
*
|
||||
* @param settingsList The settings to display
|
||||
*/
|
||||
void showSettingsList(ArrayList<SettingsItem> settingsList);
|
||||
|
||||
/**
|
||||
* Called by the containing Activity when an asynchronous load operation fails.
|
||||
* Instructs the Fragment to load the settings screen with defaults selected.
|
||||
*/
|
||||
void loadDefaultSettings();
|
||||
|
||||
/**
|
||||
* @return The Fragment's containing activity.
|
||||
*/
|
||||
FragmentActivity getActivity();
|
||||
|
||||
/**
|
||||
* @return The Fragment's SettingsAdapter.
|
||||
*/
|
||||
SettingsAdapter getAdapter();
|
||||
|
||||
/**
|
||||
* Tell the Fragment to tell the containing Activity to show a new
|
||||
* Fragment containing a submenu of settings.
|
||||
*
|
||||
* @param menuKey Identifier for the settings group that should be shown.
|
||||
*/
|
||||
void loadSubMenu(MenuTag menuKey);
|
||||
|
||||
void showDialogFragment(DialogFragment fragment);
|
||||
|
||||
/**
|
||||
* Tell the Fragment to tell the containing activity to display a toast message.
|
||||
*
|
||||
* @param message Text to be shown in the Toast
|
||||
*/
|
||||
void showToastMessage(String message);
|
||||
|
||||
/**
|
||||
* @return The backing settings store.
|
||||
*/
|
||||
Settings getSettings();
|
||||
|
||||
/**
|
||||
* Have the fragment tell the containing Activity that a setting was modified.
|
||||
*/
|
||||
void onSettingChanged();
|
||||
|
||||
/**
|
||||
* Refetches the values of all controller settings.
|
||||
*
|
||||
* To be used when loading an input profile or performing some other action that changes all
|
||||
* controller settings at once.
|
||||
*/
|
||||
void onControllerSettingsChanged();
|
||||
|
||||
/**
|
||||
* Have the fragment tell the containing Activity that the user wants to open the MenuTag
|
||||
* associated with a setting.
|
||||
*
|
||||
* @param menuTag The MenuTag of the setting.
|
||||
* @param value The current value of the setting.
|
||||
*/
|
||||
void onMenuTagAction(@NonNull MenuTag menuTag, int value);
|
||||
|
||||
/**
|
||||
* Returns whether anything will happen when the user wants to open the MenuTag associated with a
|
||||
* setting, given the current value of the setting.
|
||||
*
|
||||
* @param menuTag The MenuTag of the setting.
|
||||
* @param value The current value of the setting.
|
||||
*/
|
||||
boolean hasMenuTagActionForValue(@NonNull MenuTag menuTag, int value);
|
||||
|
||||
/**
|
||||
* Sets whether the input mapping dialog should detect inputs from all devices,
|
||||
* not just the device configured for the controller.
|
||||
*/
|
||||
void setMappingAllDevices(boolean allDevices);
|
||||
|
||||
/**
|
||||
* Returns whether the input mapping dialog should detect inputs from all devices,
|
||||
* not just the device configured for the controller.
|
||||
*/
|
||||
boolean isMappingAllDevices();
|
||||
|
||||
/**
|
||||
* Shows or hides a warning telling the user that they're using incompatible controller settings.
|
||||
* The warning is hidden by default.
|
||||
*
|
||||
* @param visible Whether the warning should be visible.
|
||||
*/
|
||||
void setOldControllerSettingsWarningVisibility(boolean visible);
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.ui
|
||||
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem
|
||||
|
||||
/**
|
||||
* Abstraction for a screen showing a list of settings. Instances of
|
||||
* this type of view will each display a layer of the Setting hierarchy.
|
||||
*/
|
||||
interface SettingsFragmentView {
|
||||
/**
|
||||
* Called by the containing Activity to notify the Fragment that an
|
||||
* asynchronous load operation completed.
|
||||
*
|
||||
* @param settings The (possibly null) result of the ini load operation.
|
||||
*/
|
||||
fun onSettingsFileLoaded(settings: Settings)
|
||||
|
||||
/**
|
||||
* Pass an ArrayList of settings to the View so that it can be displayed on screen.
|
||||
*
|
||||
* @param settingsList The settings to display
|
||||
*/
|
||||
fun showSettingsList(settingsList: ArrayList<SettingsItem>)
|
||||
|
||||
/**
|
||||
* Called by the containing Activity when an asynchronous load operation fails.
|
||||
* Instructs the Fragment to load the settings screen with defaults selected.
|
||||
*/
|
||||
fun loadDefaultSettings()
|
||||
|
||||
/**
|
||||
* @return The Fragment's containing activity.
|
||||
*/
|
||||
val fragmentActivity: FragmentActivity
|
||||
|
||||
/**
|
||||
* @return The Fragment's SettingsAdapter.
|
||||
*/
|
||||
val adapter: SettingsAdapter?
|
||||
|
||||
/**
|
||||
* Tell the Fragment to tell the containing Activity to show a new
|
||||
* Fragment containing a submenu of settings.
|
||||
*
|
||||
* @param menuKey Identifier for the settings group that should be shown.
|
||||
*/
|
||||
fun loadSubMenu(menuKey: MenuTag)
|
||||
fun showDialogFragment(fragment: DialogFragment)
|
||||
|
||||
/**
|
||||
* Tell the Fragment to tell the containing activity to display a toast message.
|
||||
*
|
||||
* @param message Text to be shown in the Toast
|
||||
*/
|
||||
fun showToastMessage(message: String)
|
||||
|
||||
/**
|
||||
* @return The backing settings store.
|
||||
*/
|
||||
val settings: Settings?
|
||||
|
||||
/**
|
||||
* Have the fragment tell the containing Activity that a Setting was modified.
|
||||
*/
|
||||
fun onSettingChanged()
|
||||
|
||||
/**
|
||||
* Refetches the values of all controller settings.
|
||||
*
|
||||
* To be used when loading an input profile or performing some other action that changes all
|
||||
* controller settings at once.
|
||||
*/
|
||||
fun onControllerSettingsChanged()
|
||||
|
||||
/**
|
||||
* Have the fragment tell the containing Activity that the user wants to open the MenuTag
|
||||
* associated with a Setting.
|
||||
*
|
||||
* @param menuTag The MenuTag of the Setting.
|
||||
* @param value The current value of the Setting.
|
||||
*/
|
||||
fun onMenuTagAction(menuTag: MenuTag, value: Int)
|
||||
|
||||
/**
|
||||
* Returns whether anything will happen when the user wants to open the MenuTag associated with a
|
||||
* stringSetting, given the current value of the Setting.
|
||||
*
|
||||
* @param menuTag The MenuTag of the Setting.
|
||||
* @param value The current value of the Setting.
|
||||
*/
|
||||
fun hasMenuTagActionForValue(menuTag: MenuTag, value: Int): Boolean
|
||||
/**
|
||||
* Returns whether the input mapping dialog should detect inputs from all devices,
|
||||
* not just the device configured for the controller.
|
||||
*/
|
||||
/**
|
||||
* Sets whether the input mapping dialog should detect inputs from all devices,
|
||||
* not just the device configured for the controller.
|
||||
*/
|
||||
var isMappingAllDevices: Boolean
|
||||
|
||||
/**
|
||||
* Shows or hides a warning telling the user that they're using incompatible controller settings.
|
||||
* The warning is hidden by default.
|
||||
*
|
||||
* @param visible Whether the warning should be visible.
|
||||
*/
|
||||
fun setOldControllerSettingsWarningVisibility(visible: Boolean)
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.ui;
|
||||
|
||||
import androidx.lifecycle.ViewModel;
|
||||
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
|
||||
|
||||
public class SettingsViewModel extends ViewModel
|
||||
{
|
||||
private final Settings mSettings = new Settings();
|
||||
|
||||
public Settings getSettings()
|
||||
{
|
||||
return mSettings;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.ui
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings
|
||||
|
||||
class SettingsViewModel : ViewModel() {
|
||||
val settings = Settings()
|
||||
}
|
|
@ -18,12 +18,15 @@ class DateTimeSettingViewHolder(
|
|||
private val binding: ListItemSettingBinding,
|
||||
adapter: SettingsAdapter
|
||||
) : SettingViewHolder(binding.root, adapter) {
|
||||
private var mItem: DateTimeChoiceSetting? = null
|
||||
lateinit var setting: DateTimeChoiceSetting
|
||||
|
||||
override val item: SettingsItem
|
||||
get() = setting
|
||||
|
||||
override fun bind(item: SettingsItem) {
|
||||
mItem = item as DateTimeChoiceSetting
|
||||
val inputTime = mItem!!.getSelectedValue()
|
||||
binding.textSettingName.text = item.getName()
|
||||
setting = item as DateTimeChoiceSetting
|
||||
val inputTime = setting.getSelectedValue()
|
||||
binding.textSettingName.text = item.name
|
||||
|
||||
if (!TextUtils.isEmpty(inputTime)) {
|
||||
val epochTime = inputTime.substring(2).toLong(16)
|
||||
|
@ -32,21 +35,17 @@ class DateTimeSettingViewHolder(
|
|||
val dateFormatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM)
|
||||
binding.textSettingDescription.text = dateFormatter.format(zonedTime)
|
||||
} else {
|
||||
binding.textSettingDescription.text = item.getDescription()
|
||||
binding.textSettingDescription.text = item.description
|
||||
}
|
||||
setStyle(binding.textSettingName, mItem)
|
||||
setStyle(binding.textSettingName, setting)
|
||||
}
|
||||
|
||||
override fun onClick(clicked: View) {
|
||||
if (!mItem!!.isEditable) {
|
||||
if (!setting.isEditable) {
|
||||
showNotRuntimeEditableError()
|
||||
return
|
||||
}
|
||||
adapter.onDateTimeClick(mItem, bindingAdapterPosition)
|
||||
setStyle(binding.textSettingName, mItem)
|
||||
}
|
||||
|
||||
override fun getItem(): SettingsItem? {
|
||||
return mItem
|
||||
adapter.onDateTimeClick(setting, bindingAdapterPosition)
|
||||
setStyle(binding.textSettingName, setting)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,99 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.ui.viewholder;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.dolphinemu.dolphinemu.R;
|
||||
import org.dolphinemu.dolphinemu.databinding.ListItemSettingBinding;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.view.FilePicker;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem;
|
||||
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsAdapter;
|
||||
import org.dolphinemu.dolphinemu.ui.main.MainPresenter;
|
||||
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization;
|
||||
import org.dolphinemu.dolphinemu.utils.FileBrowserHelper;
|
||||
|
||||
public final class FilePickerViewHolder extends SettingViewHolder
|
||||
{
|
||||
private FilePicker mFilePicker;
|
||||
private SettingsItem mItem;
|
||||
|
||||
private final ListItemSettingBinding mBinding;
|
||||
|
||||
public FilePickerViewHolder(ListItemSettingBinding binding, SettingsAdapter adapter)
|
||||
{
|
||||
super(binding.getRoot(), adapter);
|
||||
mBinding = binding;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind(SettingsItem item)
|
||||
{
|
||||
mFilePicker = (FilePicker) item;
|
||||
mItem = item;
|
||||
|
||||
String path = mFilePicker.getSelectedValue();
|
||||
|
||||
if (FileBrowserHelper.isPathEmptyOrValid(path))
|
||||
{
|
||||
itemView.setBackground(mBinding.getRoot().getBackground());
|
||||
}
|
||||
else
|
||||
{
|
||||
itemView.setBackgroundResource(R.drawable.invalid_setting_background);
|
||||
}
|
||||
|
||||
mBinding.textSettingName.setText(item.getName());
|
||||
|
||||
if (!TextUtils.isEmpty(item.getDescription()))
|
||||
{
|
||||
mBinding.textSettingDescription.setText(item.getDescription());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (TextUtils.isEmpty(path))
|
||||
{
|
||||
String defaultPathRelative = mFilePicker.getDefaultPathRelativeToUserDirectory();
|
||||
if (defaultPathRelative != null)
|
||||
{
|
||||
path = DirectoryInitialization.getUserDirectory() + defaultPathRelative;
|
||||
}
|
||||
}
|
||||
|
||||
mBinding.textSettingDescription.setText(path);
|
||||
}
|
||||
|
||||
setStyle(mBinding.textSettingName, mItem);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View clicked)
|
||||
{
|
||||
if (!mItem.isEditable())
|
||||
{
|
||||
showNotRuntimeEditableError();
|
||||
return;
|
||||
}
|
||||
|
||||
int position = getBindingAdapterPosition();
|
||||
if (mFilePicker.getRequestType() == MainPresenter.REQUEST_DIRECTORY)
|
||||
{
|
||||
getAdapter().onFilePickerDirectoryClick(mItem, position);
|
||||
}
|
||||
else
|
||||
{
|
||||
getAdapter().onFilePickerFileClick(mItem, position);
|
||||
}
|
||||
|
||||
setStyle(mBinding.textSettingName, mItem);
|
||||
}
|
||||
|
||||
@Nullable @Override
|
||||
protected SettingsItem getItem()
|
||||
{
|
||||
return mItem;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.ui.viewholder
|
||||
|
||||
import android.text.TextUtils
|
||||
import android.view.View
|
||||
import org.dolphinemu.dolphinemu.R
|
||||
import org.dolphinemu.dolphinemu.databinding.ListItemSettingBinding
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.view.FilePicker
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem
|
||||
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsAdapter
|
||||
import org.dolphinemu.dolphinemu.ui.main.MainPresenter
|
||||
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization
|
||||
import org.dolphinemu.dolphinemu.utils.FileBrowserHelper
|
||||
|
||||
class FilePickerViewHolder(
|
||||
private val binding: ListItemSettingBinding,
|
||||
adapter: SettingsAdapter?
|
||||
) : SettingViewHolder(binding.getRoot(), adapter!!) {
|
||||
lateinit var setting: FilePicker
|
||||
|
||||
override val item: SettingsItem
|
||||
get() = setting
|
||||
|
||||
override fun bind(item: SettingsItem) {
|
||||
setting = item as FilePicker
|
||||
|
||||
var path = setting.getSelectedValue()
|
||||
|
||||
if (FileBrowserHelper.isPathEmptyOrValid(path)) {
|
||||
itemView.background = binding.getRoot().background
|
||||
} else {
|
||||
itemView.setBackgroundResource(R.drawable.invalid_setting_background)
|
||||
}
|
||||
|
||||
binding.textSettingName.text = setting.name
|
||||
|
||||
if (!TextUtils.isEmpty(setting.description)) {
|
||||
binding.textSettingDescription.text = setting.description
|
||||
} else {
|
||||
if (TextUtils.isEmpty(path)) {
|
||||
val defaultPathRelative = setting.defaultPathRelativeToUserDirectory
|
||||
if (defaultPathRelative != null) {
|
||||
path = DirectoryInitialization.getUserDirectory() + defaultPathRelative
|
||||
}
|
||||
}
|
||||
binding.textSettingDescription.text = path
|
||||
}
|
||||
|
||||
setStyle(binding.textSettingName, setting)
|
||||
}
|
||||
|
||||
override fun onClick(clicked: View) {
|
||||
if (!setting.isEditable) {
|
||||
showNotRuntimeEditableError()
|
||||
return
|
||||
}
|
||||
|
||||
val position = bindingAdapterPosition
|
||||
if (setting.requestType == MainPresenter.REQUEST_DIRECTORY) {
|
||||
adapter.onFilePickerDirectoryClick(setting, position)
|
||||
} else {
|
||||
adapter.onFilePickerFileClick(setting, position)
|
||||
}
|
||||
|
||||
setStyle(binding.textSettingName, setting)
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.ui.viewholder;
|
||||
|
||||
import android.text.method.LinkMovementMethod;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.material.color.MaterialColors;
|
||||
|
||||
import org.dolphinemu.dolphinemu.R;
|
||||
import org.dolphinemu.dolphinemu.databinding.ListItemHeaderBinding;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem;
|
||||
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsAdapter;
|
||||
|
||||
public final class HeaderHyperLinkViewHolder extends HeaderViewHolder
|
||||
{
|
||||
private final ListItemHeaderBinding mBinding;
|
||||
|
||||
public HeaderHyperLinkViewHolder(@NonNull ListItemHeaderBinding binding, SettingsAdapter adapter)
|
||||
{
|
||||
super(binding, adapter);
|
||||
mBinding = binding;
|
||||
itemView.setOnClickListener(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind(@NonNull SettingsItem item)
|
||||
{
|
||||
super.bind(item);
|
||||
|
||||
mBinding.textHeaderName.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
mBinding.textHeaderName.setLinkTextColor(
|
||||
MaterialColors.getColor(itemView, R.attr.colorTertiary));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.ui.viewholder
|
||||
|
||||
import android.text.method.LinkMovementMethod
|
||||
import com.google.android.material.color.MaterialColors
|
||||
import org.dolphinemu.dolphinemu.R
|
||||
import org.dolphinemu.dolphinemu.databinding.ListItemHeaderBinding
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem
|
||||
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsAdapter
|
||||
|
||||
class HeaderHyperLinkViewHolder(
|
||||
private val binding: ListItemHeaderBinding,
|
||||
adapter: SettingsAdapter?
|
||||
) : HeaderViewHolder(binding, adapter) {
|
||||
init {
|
||||
itemView.setOnClickListener(null)
|
||||
}
|
||||
|
||||
override fun bind(item: SettingsItem) {
|
||||
super.bind(item)
|
||||
binding.textHeaderName.movementMethod = LinkMovementMethod.getInstance()
|
||||
binding.textHeaderName.setLinkTextColor(
|
||||
MaterialColors.getColor(itemView, R.attr.colorTertiary)
|
||||
)
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.ui.viewholder;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem;
|
||||
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsAdapter;
|
||||
import org.dolphinemu.dolphinemu.databinding.ListItemHeaderBinding;
|
||||
|
||||
public class HeaderViewHolder extends SettingViewHolder
|
||||
{
|
||||
private final ListItemHeaderBinding mBinding;
|
||||
|
||||
public HeaderViewHolder(@NonNull ListItemHeaderBinding binding, SettingsAdapter adapter)
|
||||
{
|
||||
super(binding.getRoot(), adapter);
|
||||
itemView.setOnClickListener(null);
|
||||
mBinding = binding;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind(@NonNull SettingsItem item)
|
||||
{
|
||||
mBinding.textHeaderName.setText(item.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View clicked)
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
|
||||
@Nullable @Override
|
||||
protected SettingsItem getItem()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.ui.viewholder
|
||||
|
||||
import android.view.View
|
||||
import org.dolphinemu.dolphinemu.databinding.ListItemHeaderBinding
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem
|
||||
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsAdapter
|
||||
|
||||
open class HeaderViewHolder(
|
||||
private val binding: ListItemHeaderBinding,
|
||||
adapter: SettingsAdapter?
|
||||
) : SettingViewHolder(binding.root, adapter!!) {
|
||||
override val item: SettingsItem? = null
|
||||
|
||||
init {
|
||||
itemView.setOnClickListener(null)
|
||||
}
|
||||
|
||||
override fun bind(item: SettingsItem) {
|
||||
binding.textHeaderName.text = item.name
|
||||
}
|
||||
|
||||
override fun onClick(clicked: View) {
|
||||
// no-op
|
||||
}
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.ui.viewholder;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.dolphinemu.dolphinemu.databinding.ListItemSettingBinding;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.view.InputStringSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem;
|
||||
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsAdapter;
|
||||
|
||||
public final class InputStringSettingViewHolder extends SettingViewHolder
|
||||
{
|
||||
private InputStringSetting mInputString;
|
||||
|
||||
private final ListItemSettingBinding mBinding;
|
||||
|
||||
public InputStringSettingViewHolder(@NonNull ListItemSettingBinding binding,
|
||||
SettingsAdapter adapter)
|
||||
{
|
||||
super(binding.getRoot(), adapter);
|
||||
mBinding = binding;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind(SettingsItem item)
|
||||
{
|
||||
mInputString = (InputStringSetting) item;
|
||||
|
||||
String inputString = mInputString.getSelectedValue();
|
||||
|
||||
mBinding.textSettingName.setText(item.getName());
|
||||
|
||||
if (!TextUtils.isEmpty(inputString))
|
||||
{
|
||||
mBinding.textSettingDescription.setText(inputString);
|
||||
}
|
||||
else
|
||||
{
|
||||
mBinding.textSettingDescription.setText(item.getDescription());
|
||||
}
|
||||
|
||||
setStyle(mBinding.textSettingName, mInputString);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View clicked)
|
||||
{
|
||||
if (!mInputString.isEditable())
|
||||
{
|
||||
showNotRuntimeEditableError();
|
||||
return;
|
||||
}
|
||||
|
||||
int position = getBindingAdapterPosition();
|
||||
|
||||
getAdapter().onInputStringClick(mInputString, position);
|
||||
|
||||
setStyle(mBinding.textSettingName, mInputString);
|
||||
}
|
||||
|
||||
@Nullable @Override
|
||||
protected SettingsItem getItem()
|
||||
{
|
||||
return mInputString;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.ui.viewholder
|
||||
|
||||
import android.text.TextUtils
|
||||
import android.view.View
|
||||
import org.dolphinemu.dolphinemu.databinding.ListItemSettingBinding
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.view.InputStringSetting
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem
|
||||
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsAdapter
|
||||
|
||||
class InputStringSettingViewHolder(
|
||||
private val binding: ListItemSettingBinding,
|
||||
adapter: SettingsAdapter
|
||||
) : SettingViewHolder(binding.getRoot(), adapter) {
|
||||
private lateinit var setting: InputStringSetting
|
||||
|
||||
override val item: SettingsItem
|
||||
get() = setting
|
||||
|
||||
override fun bind(item: SettingsItem) {
|
||||
setting = item as InputStringSetting
|
||||
|
||||
val inputString = setting.selectedValue
|
||||
|
||||
binding.textSettingName.text = setting.name
|
||||
|
||||
if (!TextUtils.isEmpty(inputString)) {
|
||||
binding.textSettingDescription.text = inputString
|
||||
} else {
|
||||
binding.textSettingDescription.text = setting.description
|
||||
}
|
||||
|
||||
setStyle(binding.textSettingName, setting)
|
||||
}
|
||||
|
||||
override fun onClick(clicked: View) {
|
||||
if (!setting.isEditable) {
|
||||
showNotRuntimeEditableError()
|
||||
return
|
||||
}
|
||||
|
||||
val position = bindingAdapterPosition
|
||||
|
||||
adapter.onInputStringClick(setting, position)
|
||||
|
||||
setStyle(binding.textSettingName, setting)
|
||||
}
|
||||
}
|
|
@ -1,93 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.ui.viewholder;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
|
||||
import org.dolphinemu.dolphinemu.R;
|
||||
import org.dolphinemu.dolphinemu.databinding.ListItemSettingBinding;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.view.RunRunnable;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem;
|
||||
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsAdapter;
|
||||
|
||||
public final class RunRunnableViewHolder extends SettingViewHolder
|
||||
{
|
||||
private RunRunnable mItem;
|
||||
|
||||
private final Context mContext;
|
||||
|
||||
private final ListItemSettingBinding mBinding;
|
||||
|
||||
public RunRunnableViewHolder(@NonNull ListItemSettingBinding binding, SettingsAdapter adapter,
|
||||
Context context)
|
||||
{
|
||||
super(binding.getRoot(), adapter);
|
||||
mBinding = binding;
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind(SettingsItem item)
|
||||
{
|
||||
mItem = (RunRunnable) item;
|
||||
|
||||
mBinding.textSettingName.setText(item.getName());
|
||||
mBinding.textSettingDescription.setText(item.getDescription());
|
||||
|
||||
setStyle(mBinding.textSettingName, mItem);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View clicked)
|
||||
{
|
||||
if (!mItem.isEditable())
|
||||
{
|
||||
showNotRuntimeEditableError();
|
||||
return;
|
||||
}
|
||||
|
||||
int alertTextID = mItem.getAlertText();
|
||||
|
||||
if (alertTextID > 0)
|
||||
{
|
||||
new MaterialAlertDialogBuilder(mContext)
|
||||
.setTitle(mItem.getName())
|
||||
.setMessage(alertTextID)
|
||||
.setPositiveButton(R.string.ok, (dialog, whichButton) ->
|
||||
{
|
||||
runRunnable();
|
||||
dialog.dismiss();
|
||||
})
|
||||
.setNegativeButton(R.string.cancel, (dialog, whichButton) -> dialog.dismiss())
|
||||
.show();
|
||||
}
|
||||
else
|
||||
{
|
||||
runRunnable();
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable @Override
|
||||
protected SettingsItem getItem()
|
||||
{
|
||||
return mItem;
|
||||
}
|
||||
|
||||
private void runRunnable()
|
||||
{
|
||||
mItem.getRunnable().run();
|
||||
|
||||
if (mItem.getToastTextAfterRun() > 0)
|
||||
{
|
||||
Toast.makeText(mContext, mContext.getString(mItem.getToastTextAfterRun()), Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.ui.viewholder
|
||||
|
||||
import android.content.Context
|
||||
import android.content.DialogInterface
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import org.dolphinemu.dolphinemu.R
|
||||
import org.dolphinemu.dolphinemu.databinding.ListItemSettingBinding
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.view.RunRunnable
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem
|
||||
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsAdapter
|
||||
|
||||
class RunRunnableViewHolder(
|
||||
private val mBinding: ListItemSettingBinding, adapter: SettingsAdapter?,
|
||||
private val mContext: Context
|
||||
) : SettingViewHolder(mBinding.getRoot(), adapter!!) {
|
||||
private lateinit var setting: RunRunnable
|
||||
|
||||
override val item: SettingsItem
|
||||
get() = setting
|
||||
|
||||
override fun bind(item: SettingsItem) {
|
||||
setting = item as RunRunnable
|
||||
|
||||
mBinding.textSettingName.text = setting.name
|
||||
mBinding.textSettingDescription.text = setting.description
|
||||
|
||||
setStyle(mBinding.textSettingName, setting)
|
||||
}
|
||||
|
||||
override fun onClick(clicked: View) {
|
||||
if (!setting.isEditable) {
|
||||
showNotRuntimeEditableError()
|
||||
return
|
||||
}
|
||||
|
||||
val alertTextID = setting.alertText
|
||||
|
||||
if (alertTextID > 0) {
|
||||
MaterialAlertDialogBuilder(mContext)
|
||||
.setTitle(setting.name)
|
||||
.setMessage(alertTextID)
|
||||
.setPositiveButton(R.string.ok) { dialog: DialogInterface, _: Int ->
|
||||
runRunnable()
|
||||
dialog.dismiss()
|
||||
}
|
||||
.setNegativeButton(R.string.cancel) { dialog: DialogInterface, _: Int -> dialog.dismiss() }
|
||||
.show()
|
||||
} else {
|
||||
runRunnable()
|
||||
}
|
||||
}
|
||||
|
||||
private fun runRunnable() {
|
||||
setting.runnable.run()
|
||||
|
||||
if (setting.toastTextAfterRun > 0) {
|
||||
Toast.makeText(
|
||||
mContext,
|
||||
mContext.getString(setting.toastTextAfterRun),
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,111 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.ui.viewholder;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Typeface;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
|
||||
import org.dolphinemu.dolphinemu.DolphinApplication;
|
||||
import org.dolphinemu.dolphinemu.R;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem;
|
||||
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsAdapter;
|
||||
|
||||
public abstract class SettingViewHolder extends RecyclerView.ViewHolder
|
||||
implements View.OnClickListener, View.OnLongClickListener
|
||||
{
|
||||
private SettingsAdapter mAdapter;
|
||||
|
||||
public SettingViewHolder(View itemView, SettingsAdapter adapter)
|
||||
{
|
||||
super(itemView);
|
||||
|
||||
mAdapter = adapter;
|
||||
|
||||
itemView.setOnClickListener(this);
|
||||
itemView.setOnLongClickListener(this);
|
||||
}
|
||||
|
||||
protected SettingsAdapter getAdapter()
|
||||
{
|
||||
return mAdapter;
|
||||
}
|
||||
|
||||
protected void setStyle(TextView textView, SettingsItem settingsItem)
|
||||
{
|
||||
boolean overridden = settingsItem.isOverridden();
|
||||
textView.setTypeface(null, overridden ? Typeface.BOLD : Typeface.NORMAL);
|
||||
|
||||
if (!settingsItem.isEditable())
|
||||
textView.setPaintFlags(textView.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
|
||||
}
|
||||
|
||||
protected static void showNotRuntimeEditableError()
|
||||
{
|
||||
Toast.makeText(DolphinApplication.getAppContext(), R.string.setting_not_runtime_editable,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
protected static void showIplNotAvailableError()
|
||||
{
|
||||
Toast.makeText(DolphinApplication.getAppContext(), R.string.ipl_not_found, Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the adapter to set this ViewHolder's child views to display the list item
|
||||
* it must now represent.
|
||||
*
|
||||
* @param item The list item that should be represented by this ViewHolder.
|
||||
*/
|
||||
public abstract void bind(SettingsItem item);
|
||||
|
||||
/**
|
||||
* Called when this ViewHolder's view is clicked on. Implementations should usually pass
|
||||
* this event up to the adapter.
|
||||
*
|
||||
* @param clicked The view that was clicked on.
|
||||
*/
|
||||
public abstract void onClick(View clicked);
|
||||
|
||||
@Nullable
|
||||
protected abstract SettingsItem getItem();
|
||||
|
||||
public boolean onLongClick(View clicked)
|
||||
{
|
||||
SettingsItem item = getItem();
|
||||
|
||||
if (item == null || !item.canClear())
|
||||
return false;
|
||||
|
||||
if (!item.isEditable())
|
||||
{
|
||||
showNotRuntimeEditableError();
|
||||
return true;
|
||||
}
|
||||
|
||||
Context context = clicked.getContext();
|
||||
|
||||
new MaterialAlertDialogBuilder(context)
|
||||
.setMessage(R.string.setting_clear_confirm)
|
||||
.setPositiveButton(R.string.ok, (dialog, whichButton) ->
|
||||
{
|
||||
getAdapter().clearSetting(item);
|
||||
bind(item);
|
||||
Toast.makeText(context, R.string.setting_cleared, Toast.LENGTH_SHORT).show();
|
||||
dialog.dismiss();
|
||||
})
|
||||
.setNegativeButton(R.string.cancel, (dialog, whichButton) -> dialog.dismiss())
|
||||
.show();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.ui.viewholder
|
||||
|
||||
import android.content.DialogInterface
|
||||
import android.graphics.Paint
|
||||
import android.graphics.Typeface
|
||||
import android.view.View
|
||||
import android.view.View.OnLongClickListener
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import org.dolphinemu.dolphinemu.DolphinApplication
|
||||
import org.dolphinemu.dolphinemu.R
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem
|
||||
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsAdapter
|
||||
|
||||
abstract class SettingViewHolder(itemView: View, protected val adapter: SettingsAdapter) :
|
||||
RecyclerView.ViewHolder(itemView), View.OnClickListener, OnLongClickListener {
|
||||
|
||||
init {
|
||||
itemView.setOnClickListener(this)
|
||||
itemView.setOnLongClickListener(this)
|
||||
}
|
||||
|
||||
protected fun setStyle(textView: TextView, settingsItem: SettingsItem) {
|
||||
val overridden = settingsItem.isOverridden
|
||||
textView.setTypeface(null, if (overridden) Typeface.BOLD else Typeface.NORMAL)
|
||||
|
||||
if (!settingsItem.isEditable) textView.paintFlags =
|
||||
textView.paintFlags or Paint.STRIKE_THRU_TEXT_FLAG
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the adapter to set this ViewHolder's child views to display the list item
|
||||
* it must now represent.
|
||||
*
|
||||
* @param item The list item that should be represented by this ViewHolder.
|
||||
*/
|
||||
abstract fun bind(item: SettingsItem)
|
||||
|
||||
/**
|
||||
* Called when this ViewHolder's view is clicked on. Implementations should usually pass
|
||||
* this event up to the adapter.
|
||||
*
|
||||
* @param clicked The view that was clicked on.
|
||||
*/
|
||||
abstract override fun onClick(clicked: View)
|
||||
|
||||
protected abstract val item: SettingsItem?
|
||||
|
||||
override fun onLongClick(clicked: View): Boolean {
|
||||
val item = item
|
||||
|
||||
if (item == null || !item.canClear()) return false
|
||||
|
||||
if (!item.isEditable) {
|
||||
showNotRuntimeEditableError()
|
||||
return true
|
||||
}
|
||||
|
||||
val context = clicked.context
|
||||
|
||||
MaterialAlertDialogBuilder(context)
|
||||
.setMessage(R.string.setting_clear_confirm)
|
||||
.setPositiveButton(R.string.ok) { dialog: DialogInterface, _: Int ->
|
||||
adapter.clearSetting(item)
|
||||
bind(item)
|
||||
Toast.makeText(
|
||||
context,
|
||||
R.string.setting_cleared,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
dialog.dismiss()
|
||||
}
|
||||
.setNegativeButton(R.string.cancel) { dialog: DialogInterface, _: Int -> dialog.dismiss() }
|
||||
.show()
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
protected fun showIplNotAvailableError() {
|
||||
Toast.makeText(
|
||||
DolphinApplication.getAppContext(),
|
||||
R.string.ipl_not_found,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
|
||||
protected fun showNotRuntimeEditableError() {
|
||||
Toast.makeText(
|
||||
DolphinApplication.getAppContext(),
|
||||
R.string.setting_not_runtime_editable,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
|
@ -1,148 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.ui.viewholder;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.dolphinemu.dolphinemu.databinding.ListItemSettingBinding;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.view.SingleChoiceSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.view.SingleChoiceSettingDynamicDescriptions;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.view.StringSingleChoiceSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.ui.MenuTag;
|
||||
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsAdapter;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public final class SingleChoiceViewHolder extends SettingViewHolder
|
||||
{
|
||||
private SettingsItem mItem;
|
||||
|
||||
private final ListItemSettingBinding mBinding;
|
||||
|
||||
public SingleChoiceViewHolder(@NonNull ListItemSettingBinding binding, SettingsAdapter adapter)
|
||||
{
|
||||
super(binding.getRoot(), adapter);
|
||||
mBinding = binding;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind(SettingsItem item)
|
||||
{
|
||||
mItem = item;
|
||||
|
||||
mBinding.textSettingName.setText(item.getName());
|
||||
|
||||
if (!TextUtils.isEmpty(item.getDescription()))
|
||||
{
|
||||
mBinding.textSettingDescription.setText(item.getDescription());
|
||||
}
|
||||
else if (item instanceof SingleChoiceSetting)
|
||||
{
|
||||
SingleChoiceSetting setting = (SingleChoiceSetting) item;
|
||||
int selected = setting.getSelectedValue();
|
||||
Resources resMgr = mBinding.textSettingDescription.getContext().getResources();
|
||||
String[] choices = resMgr.getStringArray(setting.getChoicesId());
|
||||
int[] values = resMgr.getIntArray(setting.getValuesId());
|
||||
for (int i = 0; i < values.length; ++i)
|
||||
{
|
||||
if (values[i] == selected)
|
||||
{
|
||||
mBinding.textSettingDescription.setText(choices[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (item instanceof StringSingleChoiceSetting)
|
||||
{
|
||||
StringSingleChoiceSetting setting = (StringSingleChoiceSetting) item;
|
||||
String choice = setting.getSelectedChoice();
|
||||
mBinding.textSettingDescription.setText(choice);
|
||||
}
|
||||
else if (item instanceof SingleChoiceSettingDynamicDescriptions)
|
||||
{
|
||||
SingleChoiceSettingDynamicDescriptions setting =
|
||||
(SingleChoiceSettingDynamicDescriptions) item;
|
||||
int selected = setting.getSelectedValue();
|
||||
Resources resMgr = mBinding.textSettingDescription.getContext().getResources();
|
||||
String[] choices = resMgr.getStringArray(setting.getDescriptionChoicesId());
|
||||
int[] values = resMgr.getIntArray(setting.getDescriptionValuesId());
|
||||
for (int i = 0; i < values.length; ++i)
|
||||
{
|
||||
if (values[i] == selected)
|
||||
{
|
||||
mBinding.textSettingDescription.setText(choices[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MenuTag menuTag = null;
|
||||
Supplier<Integer> getSelectedValue = null;
|
||||
if (item instanceof SingleChoiceSetting)
|
||||
{
|
||||
SingleChoiceSetting setting = (SingleChoiceSetting) item;
|
||||
menuTag = setting.getMenuTag();
|
||||
getSelectedValue = setting::getSelectedValue;
|
||||
}
|
||||
else if (item instanceof StringSingleChoiceSetting)
|
||||
{
|
||||
StringSingleChoiceSetting setting = (StringSingleChoiceSetting) item;
|
||||
menuTag = setting.getMenuTag();
|
||||
getSelectedValue = setting::getSelectedValueIndex;
|
||||
}
|
||||
|
||||
if (menuTag != null && getAdapter().hasMenuTagActionForValue(menuTag, getSelectedValue.get()))
|
||||
{
|
||||
mBinding.buttonMoreSettings.setVisibility(View.VISIBLE);
|
||||
|
||||
final MenuTag finalMenuTag = menuTag;
|
||||
final Supplier<Integer> finalGetSelectedValue = getSelectedValue;
|
||||
mBinding.buttonMoreSettings.setOnClickListener((view) ->
|
||||
getAdapter().onMenuTagAction(finalMenuTag, finalGetSelectedValue.get()));
|
||||
}
|
||||
else
|
||||
{
|
||||
mBinding.buttonMoreSettings.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
setStyle(mBinding.textSettingName, mItem);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View clicked)
|
||||
{
|
||||
if (!mItem.isEditable())
|
||||
{
|
||||
showNotRuntimeEditableError();
|
||||
return;
|
||||
}
|
||||
|
||||
int position = getBindingAdapterPosition();
|
||||
if (mItem instanceof SingleChoiceSetting)
|
||||
{
|
||||
getAdapter().onSingleChoiceClick((SingleChoiceSetting) mItem, position);
|
||||
}
|
||||
else if (mItem instanceof StringSingleChoiceSetting)
|
||||
{
|
||||
getAdapter().onStringSingleChoiceClick((StringSingleChoiceSetting) mItem, position);
|
||||
}
|
||||
else if (mItem instanceof SingleChoiceSettingDynamicDescriptions)
|
||||
{
|
||||
getAdapter().onSingleChoiceDynamicDescriptionsClick(
|
||||
(SingleChoiceSettingDynamicDescriptions) mItem, position);
|
||||
}
|
||||
|
||||
setStyle(mBinding.textSettingName, mItem);
|
||||
}
|
||||
|
||||
@Nullable @Override
|
||||
protected SettingsItem getItem()
|
||||
{
|
||||
return mItem;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue