diff --git a/CommonHelpers/BaseSettings.cs b/CommonHelpers/BaseSettings.cs new file mode 100644 index 0000000..3174f47 --- /dev/null +++ b/CommonHelpers/BaseSettings.cs @@ -0,0 +1,114 @@ +using System.Collections.Concurrent; +using System.ComponentModel; +using System.Runtime.InteropServices; +using System.Text; + +namespace CommonHelpers +{ + [TypeConverter(typeof(ExpandableObjectConverter))] + public abstract class BaseSettings + { + private String settingsKey; + private String configFile; + private IDictionary cachedValues = new ConcurrentDictionary(); + + public event Action SettingChanging; + public event Action SettingChanged; + + [Browsable(false)] + public bool TouchSettings { get; set; } + + protected BaseSettings(string settingsKey) + { + this.settingsKey = settingsKey; + this.configFile = System.Reflection.Assembly.GetEntryAssembly()?.Location + ".ini"; + + this.SettingChanging += delegate { }; + this.SettingChanged += delegate { }; + } + + public override string ToString() + { + return ""; + } + + protected bool Set(string key, T value) + { + var typeConverter = TypeDescriptor.GetConverter(typeof(T)); + var valueString = typeConverter.ConvertToString(value); + if (valueString is null) + return false; + + SettingChanging(key); + if (!SetString(key, valueString)) + return false; + + cachedValues[key] = value; + SettingChanged(key); + return true; + } + + protected T Get(string key, T defaultValue, bool touchSettings = false) + { + if (cachedValues.TryGetValue(key, out var cachedValue)) + return ((T?)cachedValue) ?? defaultValue; + + var typeConverter = TypeDescriptor.GetConverter(typeof(T)); + var defaultString = typeConverter.ConvertToString(defaultValue); + if (defaultString is null) + { + cachedValues[key] = defaultValue; + return defaultValue; + } + + try + { + var valueString = GetString(key, defaultString); + var value = (T?)typeConverter.ConvertFromString(valueString); + if (value is null) + { + cachedValues[key] = defaultValue; + return defaultValue; + } + + if ((TouchSettings || touchSettings) && valueString == defaultString) + { + // Persist current value on a first access + SetString(key, valueString); + } + + cachedValues[key] = value; + return value; + } + catch (Exception e) + { + Log.TraceLine("Settings: {0}/{1}: {2}", settingsKey, key, e); + cachedValues[key] = defaultValue; + return defaultValue; + } + } + + protected string GetString(string key, string defaultValue) + { + StringBuilder sb = new StringBuilder(500); + uint res = GetPrivateProfileString(settingsKey, key, defaultValue, sb, (uint)sb.Capacity, configFile); + if (res != 0) + return sb.ToString(); + return defaultValue; + } + + protected bool SetString(string key, string value) + { + lock (this) + { + return WritePrivateProfileString(settingsKey, key, value, configFile); + } + } + + [DllImport("kernel32.dll")] + static extern bool WritePrivateProfileString(string lpAppName, string lpKeyName, string lpString, string lpFileName); + + [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] + static extern uint GetPrivateProfileString(string lpAppName, string lpKeyName, string lpDefault, StringBuilder lpReturnedString, uint nSize, string lpFileName); + } +} diff --git a/PowerControl/App.config b/PowerControl/App.config deleted file mode 100644 index ce94943..0000000 --- a/PowerControl/App.config +++ /dev/null @@ -1,40 +0,0 @@ - - - - -
- - -
- - - - - - Ctrl+Win+Numpad8 - - - Ctrl+Win+Numpad2 - - - Ctrl+Win+Numpad4 - - - Ctrl+Win+Numpad6 - - - - - - - True - - - True - - - False - - - - \ No newline at end of file diff --git a/RELEASE.md b/RELEASE.md index 4c88dbc..8a66170 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -16,3 +16,4 @@ It does help this project on being supported. - Detect GamePad UI open temporarily for controller layout - Automatically manage steam controller configs when using Steam Input - Allow to assign BackPanel keys to X360 controller (breaks all current configs to set mappings) +- All SteamController settings are stored in `.ini` file in root folder diff --git a/SteamController/Managers/SteamConfigsManager.cs b/SteamController/Managers/SteamConfigsManager.cs index e78240e..a399438 100644 --- a/SteamController/Managers/SteamConfigsManager.cs +++ b/SteamController/Managers/SteamConfigsManager.cs @@ -39,7 +39,7 @@ namespace SteamController.Managers Settings.Default.SettingChanging -= UnlockControllerFiles; } - private void UnlockControllerFiles(object sender, System.Configuration.SettingChangingEventArgs e) + private void UnlockControllerFiles(string key) { SetSteamControllerFilesLock(false); } diff --git a/SteamController/ProfilesSettings/BackPanelSettings.cs b/SteamController/ProfilesSettings/BackPanelSettings.cs index 1b425c2..07354ef 100644 --- a/SteamController/ProfilesSettings/BackPanelSettings.cs +++ b/SteamController/ProfilesSettings/BackPanelSettings.cs @@ -4,7 +4,7 @@ using System.Configuration; namespace SteamController.ProfilesSettings { [Category("Mappings")] - internal abstract class BackPanelSettings : BaseSettings + internal abstract class BackPanelSettings : CommonHelpers.BaseSettings { private const String MappingsDescription = @"Only some of those keys do work. Allowed mappings are to be changed in future release."; @@ -12,40 +12,32 @@ namespace SteamController.ProfilesSettings { } - [UserScopedSettingAttribute()] - [DefaultSettingValueAttribute("None")] [Description(MappingsDescription)] public VirtualKeyCode L4_KEY { - get { return ((VirtualKeyCode)(this["L4_KEY"])); } - set { this["L4_KEY"] = value; } + get { return Get("L4_KEY", VirtualKeyCode.None); } + set { Set("L4_KEY", value); } } - [UserScopedSettingAttribute()] - [DefaultSettingValueAttribute("None")] [Description(MappingsDescription)] public VirtualKeyCode L5_KEY { - get { return ((VirtualKeyCode)(this["L5_KEY"])); } - set { this["L5_KEY"] = value; } + get { return Get("L5_KEY", VirtualKeyCode.None); } + set { Set("L5_KEY", value); } } - [UserScopedSettingAttribute()] - [DefaultSettingValueAttribute("None")] [Description(MappingsDescription)] public VirtualKeyCode R4_KEY { - get { return ((VirtualKeyCode)(this["R4_KEY"])); } - set { this["R4_KEY"] = value; } + get { return Get("R4_KEY", VirtualKeyCode.None); } + set { Set("R4_KEY", value); } } - [UserScopedSettingAttribute()] - [DefaultSettingValueAttribute("None")] [Description(MappingsDescription)] public VirtualKeyCode R5_KEY { - get { return ((VirtualKeyCode)(this["R5_KEY"])); } - set { this["R5_KEY"] = value; } + get { return Get("R5_KEY", VirtualKeyCode.None); } + set { Set("R5_KEY", value); } } } } diff --git a/SteamController/ProfilesSettings/BaseSettings.cs b/SteamController/ProfilesSettings/BaseSettings.cs deleted file mode 100644 index d8ef376..0000000 --- a/SteamController/ProfilesSettings/BaseSettings.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System.ComponentModel; -using System.Configuration; -using WindowsInput; - -namespace SteamController.ProfilesSettings -{ - [TypeConverter(typeof(ExpandableObjectConverter))] - internal abstract class BaseSettings : ApplicationSettingsBase - { - public BaseSettings(String settingsKey) : base(settingsKey) - { - PropertyChanged += delegate - { - Save(); - }; - } - - public override string ToString() - { - return ""; - } - } -} \ No newline at end of file diff --git a/SteamController/ProfilesSettings/DesktopPanelSettings.cs b/SteamController/ProfilesSettings/DesktopPanelSettings.cs index 25b714b..dd2686a 100644 --- a/SteamController/ProfilesSettings/DesktopPanelSettings.cs +++ b/SteamController/ProfilesSettings/DesktopPanelSettings.cs @@ -5,10 +5,9 @@ namespace SteamController.ProfilesSettings { internal class DesktopPanelSettings : BackPanelSettings { - public static DesktopPanelSettings Default { get; } = (DesktopPanelSettings)ApplicationSettingsBase.Synchronized( - new DesktopPanelSettings("DesktopPanelSettings")); + public static DesktopPanelSettings Default { get; } = new DesktopPanelSettings(); - public DesktopPanelSettings(String settingsKey) : base(settingsKey) + public DesktopPanelSettings() : base("DesktopPanelSettings") { } } diff --git a/SteamController/ProfilesSettings/X360BackPanelSettings.cs b/SteamController/ProfilesSettings/X360BackPanelSettings.cs index c6deda0..475de3d 100644 --- a/SteamController/ProfilesSettings/X360BackPanelSettings.cs +++ b/SteamController/ProfilesSettings/X360BackPanelSettings.cs @@ -7,47 +7,38 @@ namespace SteamController.ProfilesSettings { private const String MappingsDescription = @"Mappings are to be changed in future release."; - public static X360BackPanelSettings Default { get; } = (X360BackPanelSettings)ApplicationSettingsBase.Synchronized( - new X360BackPanelSettings("X360BackPanelSettings")); + public static X360BackPanelSettings Default { get; } = new X360BackPanelSettings(); - public X360BackPanelSettings(String settingsKey) : base(settingsKey) + public X360BackPanelSettings() : base("X360BackPanelSettings") { } - [UserScopedSettingAttribute()] - [DefaultSettingValueAttribute("None")] [Description(MappingsDescription)] public VirtualX360Code L4_X360 { - get { return ((VirtualX360Code)(this["L4_X360"])); } - set { this["L4_X360"] = value; } + get { return Get("L4_X360", VirtualX360Code.None); } + set { Set("L4_X360", value); } } - [UserScopedSettingAttribute()] - [DefaultSettingValueAttribute("None")] [Description(MappingsDescription)] public VirtualX360Code L5_X360 { - get { return ((VirtualX360Code)(this["L5_X360"])); } - set { this["L5_X360"] = value; } + get { return Get("L5_X360", VirtualX360Code.None); } + set { Set("L5_X360", value); } } - [UserScopedSettingAttribute()] - [DefaultSettingValueAttribute("None")] [Description(MappingsDescription)] public VirtualX360Code R4_X360 { - get { return ((VirtualX360Code)(this["R4_X360"])); } - set { this["R4_X360"] = value; } + get { return Get("R4_X360", VirtualX360Code.None); } + set { Set("R4_X360", value); } } - [UserScopedSettingAttribute()] - [DefaultSettingValueAttribute("None")] [Description(MappingsDescription)] public VirtualX360Code R5_X360 { - get { return ((VirtualX360Code)(this["R5_X360"])); } - set { this["R5_X360"] = value; } + get { return Get("R5_X360", VirtualX360Code.None); } + set { Set("R5_X360", value); } } } } \ No newline at end of file diff --git a/SteamController/ProfilesSettings/X360HapticSettings.cs b/SteamController/ProfilesSettings/X360HapticSettings.cs index 8669c69..c8892df 100644 --- a/SteamController/ProfilesSettings/X360HapticSettings.cs +++ b/SteamController/ProfilesSettings/X360HapticSettings.cs @@ -1,46 +1,38 @@ using System.ComponentModel; using System.Configuration; -using WindowsInput; namespace SteamController.ProfilesSettings { [Category("Settings")] - internal sealed class X360HapticSettings : BaseSettings + internal sealed class X360HapticSettings : CommonHelpers.BaseSettings { public const sbyte MinIntensity = -2; public const sbyte MaxIntensity = 10; - public static X360HapticSettings Default { get; } = (X360HapticSettings)ApplicationSettingsBase.Synchronized( - new X360HapticSettings("X360HapticSettings")); + public static X360HapticSettings Default = new X360HapticSettings(); - public X360HapticSettings(String settingsKey) : base(settingsKey) + public X360HapticSettings() : base("X360HapticSettings") { } - [UserScopedSettingAttribute()] - [DefaultSettingValueAttribute("Weak")] public Devices.SteamController.HapticStyle HapticStyle { - get { return ((Devices.SteamController.HapticStyle)(this["HapticStyle"])); } - set { this["HapticStyle"] = value; } + get { return Get("HapticStyle", Devices.SteamController.HapticStyle.Weak); } + set { Set("HapticStyle", value); } } - [UserScopedSettingAttribute()] - [DefaultSettingValueAttribute("2")] [Description("Haptic intensity between -2dB and 10dB")] public sbyte LeftIntensity { - get { return ((sbyte)(this["LeftIntensity"])); } - set { this["LeftIntensity"] = Math.Clamp(value, MinIntensity, MaxIntensity); } + get { return Get("LeftIntensity", 2); } + set { Set("LeftIntensity", Math.Clamp(value, MinIntensity, MaxIntensity)); } } - [UserScopedSettingAttribute()] - [DefaultSettingValueAttribute("2")] [Description("Haptic intensity between -2dB and 10dB")] public sbyte RightIntensity { - get { return ((sbyte)(this["RightIntensity"])); } - set { this["RightIntensity"] = Math.Clamp(value, MinIntensity, MaxIntensity); } + get { return Get("RightIntensity", 2); } + set { Set("RightIntensity", Math.Clamp(value, MinIntensity, MaxIntensity)); } } } } diff --git a/SteamController/Settings.cs b/SteamController/Settings.cs index 91a6933..dc07a8a 100644 --- a/SteamController/Settings.cs +++ b/SteamController/Settings.cs @@ -5,35 +5,28 @@ namespace SteamController { [Category("Settings")] [TypeConverter(typeof(ExpandableObjectConverter))] - internal sealed partial class Settings : ApplicationSettingsBase + internal sealed partial class Settings : CommonHelpers.BaseSettings { - public static readonly Settings Default = (Settings)Synchronized(new Settings()); + public static readonly Settings Default = new Settings(); + private static readonly ProfilesSettings.Helpers.ProfileName DefaultProfileDefault = new ProfilesSettings.Helpers.ProfileName("Default"); - public Settings() + public Settings() : base("Settings") { - PropertyChanged += delegate - { - Save(); - }; } - [UserScopedSetting] - [DefaultSettingValue("False")] [BrowsableAttribute(false)] public bool EnableSteamDetection { - get { return ((bool)(this["EnableSteamDetection"])); } - set { this["EnableSteamDetection"] = value; } + get { return Get("EnableSteamDetection", false); } + set { Set("EnableSteamDetection", value); } } - [UserScopedSetting] - [DefaultSettingValue("Desktop")] [Description("Default profile used when going back to Desktop mode")] [BrowsableAttribute(true)] public ProfilesSettings.Helpers.ProfileName DefaultProfile { - get { return ((ProfilesSettings.Helpers.ProfileName)(this["DefaultProfile"])); } - set { this["DefaultProfile"] = value; } + get { return Get("DefaultProfile", DefaultProfileDefault); } + set { Set("DefaultProfile", value); } } public enum ScrollMode : int @@ -42,14 +35,12 @@ namespace SteamController DownScrollDown = 1 } - [UserScopedSetting] - [DefaultSettingValue("DownScrollDown")] [Description("Scroll direction for right pad and joystick.")] [BrowsableAttribute(true)] public ScrollMode ScrollDirection { - get { return ((ScrollMode)(this["ScrollDirection"])); } - set { this["ScrollDirection"] = value; } + get { return Get("ScrollDirection", ScrollMode.DownScrollDown); } + set { Set("ScrollDirection", value); } } public enum SteamControllerConfigsMode @@ -58,16 +49,14 @@ namespace SteamController Overwrite } - [UserScopedSetting] [BrowsableAttribute(true)] - [DefaultSettingValue("Overwrite")] [Description("This does replace Steam configuration for controllers to prevent double inputs. " + "Might require going to Steam > Settings > Controller > Desktop to apply " + "'SteamController provided empty configuration'.")] public SteamControllerConfigsMode SteamControllerConfigs { - get { return ((SteamControllerConfigsMode)(this["SteamControllerConfigs"])); } - set { this["SteamControllerConfigs"] = value; } + get { return Get("SteamControllerConfigs", SteamControllerConfigsMode.Overwrite); } + set { Set("SteamControllerConfigs", value); } } [UserScopedSetting] @@ -76,8 +65,8 @@ namespace SteamController [Description("Show Touch Keyboard or CTRL+WIN+O")] public bool ShowTouchKeyboard { - get { return ((bool)(this["ShowTouchKeyboard"])); } - set { this["ShowTouchKeyboard"] = value; } + get { return Get("ShowTouchKeyboard", true); } + set { Set("ShowTouchKeyboard", value); } } public override string ToString()