diff --git a/ConfigApp/MainWindow.xaml.cs b/ConfigApp/MainWindow.xaml.cs index 0744338a5..6f8b44761 100644 --- a/ConfigApp/MainWindow.xaml.cs +++ b/ConfigApp/MainWindow.xaml.cs @@ -5,6 +5,7 @@ using System.Windows.Input; using System.Windows.Media; using ConfigApp.Tabs; +using ConfigApp.Tabs.Settings; using ConfigApp.Tabs.Voting; using static ConfigApp.Effects; @@ -15,7 +16,7 @@ public partial class MainWindow : Window private readonly Dictionary m_Tabs = new() { //{ "Meta", new MetaTab() }, - { "Misc", new MiscTab() }, + { "Settings", new SettingsTab() }, { "Voting", new VotingTab() }, { "Workshop", new WorkshopTab() }, { "More", new MoreTab() } diff --git a/ConfigApp/Tabs/MiscTab.cs b/ConfigApp/Tabs/MiscTab.cs index a63f12786..cef940c54 100644 --- a/ConfigApp/Tabs/MiscTab.cs +++ b/ConfigApp/Tabs/MiscTab.cs @@ -29,7 +29,6 @@ public class MiscTab : Tab private CheckBox? m_EnableDistanceBasedDispatch = null; private TextBox? m_DistanceBasedDispatchDistance = null; private ComboBox? m_DistanceBasedDispatchType = null; - private CheckBox? m_EnableCrossingChallenge = null; private static ColorPicker GenerateCommonColorPicker(Color defaultColor) { @@ -128,8 +127,6 @@ protected override void InitContent() }); grid.PopRow(); - grid.PushRowSpacedPair("Enable Crossing Challenge™", m_EnableCrossingChallenge = Utils.GenerateCommonCheckBox()); - scrollViewer.Content = grid.Grid; PushRowElement(scrollViewer); @@ -186,8 +183,6 @@ public override void OnLoadValues() m_DistanceBasedDispatchDistance.Text = OptionsManager.ConfigFile.ReadValue("DistanceToActivateEffect", "250"); if (m_DistanceBasedDispatchType is not null) m_DistanceBasedDispatchType.SelectedIndex = OptionsManager.ConfigFile.ReadValueInt("DistanceType", 0); - if (m_EnableCrossingChallenge is not null) - m_EnableCrossingChallenge.IsChecked = OptionsManager.ConfigFile.ReadValueBool("EnableCrossingChallenge", false); } public override void OnSaveValues() @@ -214,7 +209,6 @@ public override void OnSaveValues() OptionsManager.ConfigFile.WriteValue("EnableDistanceBasedEffectDispatch", m_EnableDistanceBasedDispatch?.IsChecked); OptionsManager.ConfigFile.WriteValue("DistanceToActivateEffect", m_DistanceBasedDispatchDistance?.Text); OptionsManager.ConfigFile.WriteValue("DistanceType", m_DistanceBasedDispatchType?.SelectedIndex); - OptionsManager.ConfigFile.WriteValue("EnableCrossingChallenge", m_EnableCrossingChallenge?.IsChecked); } } } diff --git a/ConfigApp/Tabs/Settings/ColorsTab.cs b/ConfigApp/Tabs/Settings/ColorsTab.cs new file mode 100644 index 000000000..160446e33 --- /dev/null +++ b/ConfigApp/Tabs/Settings/ColorsTab.cs @@ -0,0 +1,70 @@ +using System.Windows; +using System.Windows.Controls; +using System.Windows.Media; +using Xceed.Wpf.Toolkit; + +namespace ConfigApp.Tabs.Settings +{ + public class ColorsTab : Tab + { + private ColorPicker? m_TimerBarColor = null; + private ColorPicker? m_EffectTextColor = null; + private ColorPicker? m_EffectTimerBarColor = null; + + private static ColorPicker GenerateCommonColorPicker(Color defaultColor) + { + return new ColorPicker() + { + Width = 60f, + Height = 25f, + SelectedColor = defaultColor, + ShowStandardColors = false, + UsingAlphaChannel = false + }; + } + + protected override void InitContent() + { + PushNewColumn(new GridLength(1f, GridUnitType.Star)); + SetRowHeight(new GridLength(1f, GridUnitType.Star)); + + var scrollViewer = new ScrollViewer(); + + var grid = new ChaosGrid(); + grid.PushNewColumn(new GridLength(310f)); + grid.PushNewColumn(new GridLength(10f)); + grid.PushNewColumn(new GridLength(100f)); + grid.PushNewColumn(new GridLength(450f)); + grid.PushNewColumn(new GridLength(10f)); + grid.PushNewColumn(new GridLength()); + + grid.PushRowSpacedPair("Timer bar color", m_TimerBarColor = GenerateCommonColorPicker(Color.FromRgb(0x40, 0x40, 0xFF))); + grid.PopRow(); + + grid.PushRowSpacedPair("Effect text color", m_EffectTextColor = GenerateCommonColorPicker(Color.FromRgb(0xFF, 0xFF, 0xFF))); + grid.PushRowSpacedPair("Effect timer bar color", m_EffectTimerBarColor = GenerateCommonColorPicker(Color.FromRgb(0xB4, 0xB4, 0xB4))); + grid.PopRow(); + + scrollViewer.Content = grid.Grid; + + PushRowElement(scrollViewer); + } + + public override void OnLoadValues() + { + if (OptionsManager.ConfigFile.HasKey("EffectTimerColor") && m_TimerBarColor is not null) + m_TimerBarColor.SelectedColor = (Color)ColorConverter.ConvertFromString(OptionsManager.ConfigFile.ReadValue("EffectTimerColor")); + if (OptionsManager.ConfigFile.HasKey("EffectTextColor") && m_EffectTextColor is not null) + m_EffectTextColor.SelectedColor = (Color)ColorConverter.ConvertFromString(OptionsManager.ConfigFile.ReadValue("EffectTextColor")); + if (OptionsManager.ConfigFile.HasKey("EffectTimedTimerColor") && m_EffectTimerBarColor is not null) + m_EffectTimerBarColor.SelectedColor = (Color)ColorConverter.ConvertFromString(OptionsManager.ConfigFile.ReadValue("EffectTimedTimerColor")); + } + + public override void OnSaveValues() + { + OptionsManager.ConfigFile.WriteValue("EffectTimerColor", m_TimerBarColor?.SelectedColor.ToString()); + OptionsManager.ConfigFile.WriteValue("EffectTextColor", m_EffectTextColor?.SelectedColor.ToString()); + OptionsManager.ConfigFile.WriteValue("EffectTimedTimerColor", m_EffectTimerBarColor?.SelectedColor.ToString()); + } + } +} diff --git a/ConfigApp/Tabs/Settings/GeneralTab.cs b/ConfigApp/Tabs/Settings/GeneralTab.cs new file mode 100644 index 000000000..e2c68eac8 --- /dev/null +++ b/ConfigApp/Tabs/Settings/GeneralTab.cs @@ -0,0 +1,85 @@ +using System.Windows; +using System.Windows.Controls; + +namespace ConfigApp.Tabs.Settings +{ + public class GeneralTab : Tab + { + private CheckBox? m_DisableModOnStartup = null; + private TextBox? m_MaxRunningEffects = null; + private CheckBox? m_DisableDrawTimer = null; + private CheckBox? m_DisableDrawEffectText = null; + private TextBox? m_RandomSeed = null; + private CheckBox? m_EnableEffectGroupWeighting = null; + private CheckBox? m_EnableModSplashTexts = null; + private CheckBox? m_EnableFailsafe = null; + + protected override void InitContent() + { + PushNewColumn(new GridLength(1f, GridUnitType.Star)); + SetRowHeight(new GridLength(1f, GridUnitType.Star)); + + var scrollViewer = new ScrollViewer(); + + var grid = new ChaosGrid(); + grid.PushNewColumn(new GridLength(310f)); + grid.PushNewColumn(new GridLength(10f)); + grid.PushNewColumn(new GridLength(100f)); + grid.PushNewColumn(new GridLength(450f)); + grid.PushNewColumn(new GridLength(10f)); + grid.PushNewColumn(new GridLength()); + + grid.PushRowSpacedPair("Disable mod on startup by default", m_DisableModOnStartup = Utils.GenerateCommonCheckBox()); + grid.PushRowSpacedPair("Max amount of simultaneously running effects", m_MaxRunningEffects = Utils.GenerateCommonNumericOnlyTextBox(2)); + grid.PopRow(); + + grid.PushRowSpacedPair("Don't draw timer bar", m_DisableDrawTimer = Utils.GenerateCommonCheckBox()); + grid.PushRowSpacedPair("Don't draw effect text", m_DisableDrawEffectText = Utils.GenerateCommonCheckBox()); + grid.PopRow(); + + grid.PushRowSpacedPair("Random Seed (Leave empty for random seed every time)", m_RandomSeed = Utils.GenerateCommonNumericOnlyTextBox()); + grid.PushRowSpacedPair("Enable effect group weighting", m_EnableEffectGroupWeighting = Utils.GenerateCommonCheckBox()); + grid.PopRow(); + + grid.PushRowSpacedPair("Show mod splash texts", m_EnableModSplashTexts = Utils.GenerateCommonCheckBox()); + grid.PushRowSpacedPair("Allow prevention of repetitive mission fails (Failsafe)", m_EnableFailsafe = Utils.GenerateCommonCheckBox()); + grid.PopRow(); + + scrollViewer.Content = grid.Grid; + + PushRowElement(scrollViewer); + } + + public override void OnLoadValues() + { + if (m_DisableDrawTimer is not null) + m_DisableDrawTimer.IsChecked = OptionsManager.ConfigFile.ReadValueBool("DisableTimerBarDraw", false); + if (m_DisableDrawEffectText is not null) + m_DisableDrawEffectText.IsChecked = OptionsManager.ConfigFile.ReadValueBool("DisableEffectTextDraw", false); + if (m_RandomSeed is not null) + m_RandomSeed.Text = OptionsManager.ConfigFile.ReadValue("Seed"); + if (m_MaxRunningEffects is not null) + m_MaxRunningEffects.Text = OptionsManager.ConfigFile.ReadValue("MaxParallelRunningEffects", "99"); + if (m_EnableEffectGroupWeighting is not null) + m_EnableEffectGroupWeighting.IsChecked = OptionsManager.ConfigFile.ReadValueBool("EnableGroupWeightingAdjustments", true); + if (m_DisableModOnStartup is not null) + m_DisableModOnStartup.IsChecked = OptionsManager.ConfigFile.ReadValueBool("DisableStartup", false); + if (m_EnableFailsafe is not null) + m_EnableFailsafe.IsChecked = OptionsManager.ConfigFile.ReadValueBool("EnableFailsafe", true); + if (m_EnableModSplashTexts is not null) + m_EnableModSplashTexts.IsChecked = OptionsManager.ConfigFile.ReadValueBool("EnableModSplashTexts", true); + } + + public override void OnSaveValues() + { + OptionsManager.ConfigFile.WriteValue("DisableTimerBarDraw", m_DisableDrawTimer?.IsChecked); + OptionsManager.ConfigFile.WriteValue("DisableEffectTextDraw", m_DisableDrawEffectText?.IsChecked); + OptionsManager.ConfigFile.WriteValue("Seed", m_RandomSeed?.Text); + OptionsManager.ConfigFile.WriteValue("MaxParallelRunningEffects", m_MaxRunningEffects?.Text); + OptionsManager.ConfigFile.WriteValue("EnableGroupWeightingAdjustments", m_EnableEffectGroupWeighting?.IsChecked); + OptionsManager.ConfigFile.WriteValue("DisableStartup", m_DisableModOnStartup?.IsChecked); + OptionsManager.ConfigFile.WriteValue("EnableFailsafe", m_EnableFailsafe?.IsChecked); + OptionsManager.ConfigFile.WriteValue("EnableModSplashTexts", m_EnableModSplashTexts?.IsChecked); + } + } +} diff --git a/ConfigApp/Tabs/Settings/ModesTab.cs b/ConfigApp/Tabs/Settings/ModesTab.cs new file mode 100644 index 000000000..a5e7aa2b0 --- /dev/null +++ b/ConfigApp/Tabs/Settings/ModesTab.cs @@ -0,0 +1,152 @@ +using System.Windows; +using System.Windows.Controls; + +namespace ConfigApp.Tabs.Settings +{ + public class ModesTab : Tab + { + private enum DispatchModeType + { + Time, + Distance + }; + private static readonly Dictionary DispatchModes = new() + { + { DispatchModeType.Time, "Time"}, + { DispatchModeType.Distance, "Distance" } + }; + + private ComboBox? m_DispatchMode = null; + + private ChaosGrid? m_TimeGrid = null; + private TextBox? m_EffectDispatchTimer = null; + private TextBox? m_TimedEffectDuration = null; + private TextBox? m_ShortTimedEffectDuration = null; + + private ChaosGrid? m_DistanceGrid = null; + private TextBox? m_DistanceBasedDispatchDistance = null; + private ComboBox? m_DistanceBasedDispatchType = null; + + private CheckBox? m_EnableCrossingChallenge = null; + + private void UpdateDispatchModeGridVisibility() + { + if (m_DispatchMode is null || m_TimeGrid is null || m_DistanceGrid is null) + return; + + switch ((DispatchModeType)m_DispatchMode.SelectedIndex) + { + case DispatchModeType.Time: + m_TimeGrid.Grid.Visibility = Visibility.Visible; + m_DistanceGrid.Grid.Visibility = Visibility.Collapsed; + break; + case DispatchModeType.Distance: + m_TimeGrid.Grid.Visibility = Visibility.Collapsed; + m_DistanceGrid.Grid.Visibility = Visibility.Visible; + break; + default: + break; + } + } + + protected override void InitContent() + { + static ChaosGrid createCommonGrid() + { + var grid = new ChaosGrid(); + grid.PushNewColumn(new GridLength(310f)); + grid.PushNewColumn(new GridLength(10f)); + grid.PushNewColumn(new GridLength(100f)); + grid.PushNewColumn(new GridLength(450f)); + grid.PushNewColumn(new GridLength(10f)); + grid.PushNewColumn(new GridLength()); + return grid; + } + + PushNewColumn(new GridLength(1f, GridUnitType.Star)); + SetRowHeight(new GridLength(1f, GridUnitType.Star)); + + var scrollViewer = new ScrollViewer(); + + var grid = new ChaosGrid(); + grid.PushNewColumn(new GridLength()); + + var headerGrid = createCommonGrid(); + headerGrid.PushRowSpacedPair("Effect dispatch mode", m_DispatchMode = new ComboBox() + { + Width = 80f, + Height = 25f, + ItemsSource = DispatchModes.Values + }); + m_DispatchMode.SelectionChanged += (sender, args) => UpdateDispatchModeGridVisibility(); + grid.PushRowElement(headerGrid.Grid); + grid.PopRow(); + + var body = new StackPanel(); + grid.SetRowHeight(new GridLength(100f)); + grid.PushRowElement(body); + grid.PopRow(); + + m_TimeGrid = createCommonGrid(); + m_TimeGrid.PushRowSpacedPair("New effect timer (in seconds)", m_EffectDispatchTimer = Utils.GenerateCommonNumericOnlyTextBox()); + m_TimeGrid.PushRowSpacedPair("Timed effect duration (in seconds)", m_TimedEffectDuration = Utils.GenerateCommonNumericOnlyTextBox()); + m_TimeGrid.PopRow(); + m_TimeGrid.PushRowSpacedPair("Short timed effect duration (in seconds)", m_ShortTimedEffectDuration = Utils.GenerateCommonNumericOnlyTextBox()); + body.Children.Add(m_TimeGrid.Grid); + + m_DistanceGrid = createCommonGrid(); + m_DistanceGrid.PushRowSpacedPair("Distance to activate effect (in meters)", m_DistanceBasedDispatchDistance = Utils.GenerateCommonNumericOnlyTextBox()); + m_DistanceGrid.PushRowSpacedPair("Type of travel distance", m_DistanceBasedDispatchType = new ComboBox() + { + Width = 120f, + Height = 25f, + ItemsSource = new string[] + { + "Distance", + "Displacement" + } + }); + body.Children.Add(m_DistanceGrid.Grid); + + var footerGrid = createCommonGrid(); + footerGrid.PushRowSpacedPair("Enable Crossing Challenge™", m_EnableCrossingChallenge = Utils.GenerateCommonCheckBox()); + grid.PushRowElement(footerGrid.Grid); + + scrollViewer.Content = grid.Grid; + + PushRowElement(scrollViewer); + } + + public override void OnLoadValues() + { + if (m_DispatchMode is not null) + { + m_DispatchMode.SelectedIndex = !OptionsManager.ConfigFile.ReadValueBool("EnableDistanceBasedEffectDispatch", false) ? 0 : 1; + UpdateDispatchModeGridVisibility(); + } + if (m_EffectDispatchTimer is not null) + m_EffectDispatchTimer.Text = OptionsManager.ConfigFile.ReadValue("NewEffectSpawnTime", "30"); + if (m_TimedEffectDuration is not null) + m_TimedEffectDuration.Text = OptionsManager.ConfigFile.ReadValue("EffectTimedDur", "90"); + if (m_ShortTimedEffectDuration is not null) + m_ShortTimedEffectDuration.Text = OptionsManager.ConfigFile.ReadValue("EffectTimedShortDur", "30"); + if (m_DistanceBasedDispatchDistance is not null) + m_DistanceBasedDispatchDistance.Text = OptionsManager.ConfigFile.ReadValue("DistanceToActivateEffect", "250"); + if (m_DistanceBasedDispatchType is not null) + m_DistanceBasedDispatchType.SelectedIndex = OptionsManager.ConfigFile.ReadValueInt("DistanceType", 0); + if (m_EnableCrossingChallenge is not null) + m_EnableCrossingChallenge.IsChecked = OptionsManager.ConfigFile.ReadValueBool("EnableCrossingChallenge", false); + } + + public override void OnSaveValues() + { + OptionsManager.ConfigFile.WriteValue("NewEffectSpawnTime", m_EffectDispatchTimer?.Text); + OptionsManager.ConfigFile.WriteValue("EffectTimedDur", m_TimedEffectDuration?.Text); + OptionsManager.ConfigFile.WriteValue("EffectTimedShortDur", m_ShortTimedEffectDuration?.Text); + OptionsManager.ConfigFile.WriteValue("EnableDistanceBasedEffectDispatch", m_DispatchMode?.SelectedIndex); + OptionsManager.ConfigFile.WriteValue("DistanceToActivateEffect", m_DistanceBasedDispatchDistance?.Text); + OptionsManager.ConfigFile.WriteValue("DistanceType", m_DistanceBasedDispatchType?.SelectedIndex); + OptionsManager.ConfigFile.WriteValue("EnableCrossingChallenge", m_EnableCrossingChallenge?.IsChecked); + } + } +} diff --git a/ConfigApp/Tabs/Settings/SettingsTab.cs b/ConfigApp/Tabs/Settings/SettingsTab.cs new file mode 100644 index 000000000..eb7849199 --- /dev/null +++ b/ConfigApp/Tabs/Settings/SettingsTab.cs @@ -0,0 +1,63 @@ +using System.Windows; +using System.Windows.Controls; +using System.Windows.Media; + +namespace ConfigApp.Tabs.Settings +{ + public class SettingsTab : Tab + { + private readonly Dictionary m_Tabs = new() + { + { "General", new GeneralTab() }, + { "Modes", new ModesTab() }, + { "Shortcuts", new ShortcutsTab() }, + { "Colors", new ColorsTab() } + }; + + protected override void InitContent() + { + PushNewColumn(new GridLength(1f, GridUnitType.Star)); + SetRowHeight(new GridLength(1f, GridUnitType.Star)); + + var tabControl = new TabControl() + { + Background = null, + BorderBrush = new SolidColorBrush(Color.FromRgb(0xD3, 0xD3, 0xD3)), + BorderThickness = new Thickness(0f, 1f, 0f, 0f) + }; + + foreach (var tab in m_Tabs) + { + var tabItem = new TabItem() + { + Header = tab.Key, + Background = new SolidColorBrush(Color.FromRgb(0xF0, 0xF0, 0xF0)), + BorderBrush = new SolidColorBrush(Color.FromRgb(0xD3, 0xD3, 0xD3)) + }; + + var grid = new Grid(); + + tab.Value.Init(grid); + + tabItem.Content = grid; + + tabControl.Items.Add(tabItem); + } + + PushRowElement(tabControl); + PopRow(); + } + + public override void OnLoadValues() + { + foreach (var tab in m_Tabs) + tab.Value.OnLoadValues(); + } + + public override void OnSaveValues() + { + foreach (var tab in m_Tabs) + tab.Value.OnSaveValues(); + } + } +} diff --git a/ConfigApp/Tabs/Settings/ShortcutsTab.cs b/ConfigApp/Tabs/Settings/ShortcutsTab.cs new file mode 100644 index 000000000..3177ee631 --- /dev/null +++ b/ConfigApp/Tabs/Settings/ShortcutsTab.cs @@ -0,0 +1,68 @@ +using System.Windows; +using System.Windows.Controls; + +namespace ConfigApp.Tabs.Settings +{ + public class ShortcutsTab : Tab + { + private CheckBox? m_EnableToggleModShortcut = null; + private CheckBox? m_EnableClearActiveEffectsShortcut = null; + private CheckBox? m_EnablePauseTimerShortcut = null; + private CheckBox? m_EnableEffectsMenu = null; + private CheckBox? m_EnableAntiSoftlockShortcut = null; + + protected override void InitContent() + { + PushNewColumn(new GridLength(1f, GridUnitType.Star)); + SetRowHeight(new GridLength(1f, GridUnitType.Star)); + + var scrollViewer = new ScrollViewer(); + + var grid = new ChaosGrid(); + grid.PushNewColumn(new GridLength(310f)); + grid.PushNewColumn(new GridLength(10f)); + grid.PushNewColumn(new GridLength(100f)); + grid.PushNewColumn(new GridLength(450f)); + grid.PushNewColumn(new GridLength(10f)); + grid.PushNewColumn(new GridLength()); + + grid.PushRowSpacedPair("Enable toggle mod shortcut (CTRL + L)", m_EnableToggleModShortcut = Utils.GenerateCommonCheckBox()); + grid.PushRowSpacedPair("Enable clear active effects shortcut (CTRL + -)", m_EnableClearActiveEffectsShortcut = Utils.GenerateCommonCheckBox()); + grid.PopRow(); + + grid.PushRowSpacedPair("Enable pause timer shortcut (CTRL + .)", m_EnablePauseTimerShortcut = Utils.GenerateCommonCheckBox()); + grid.PushRowSpacedPair("Enable effects menu (allows you to choose effects manually, CTRL + ,)", m_EnableEffectsMenu = Utils.GenerateCommonCheckBox()); + grid.PopRow(); + + grid.PushRowSpacedPair("Enable black screen softlock prevention shortcut (CTRL + SHIFT + K)", m_EnableAntiSoftlockShortcut = Utils.GenerateCommonCheckBox()); + grid.PopRow(); + + scrollViewer.Content = grid.Grid; + + PushRowElement(scrollViewer); + } + + public override void OnLoadValues() + { + if (m_EnableToggleModShortcut is not null) + m_EnableToggleModShortcut.IsChecked = OptionsManager.ConfigFile.ReadValueBool("EnableToggleModShortcut", true); + if (m_EnableClearActiveEffectsShortcut is not null) + m_EnableClearActiveEffectsShortcut.IsChecked = OptionsManager.ConfigFile.ReadValueBool("EnableClearEffectsShortcut", true); + if (m_EnablePauseTimerShortcut is not null) + m_EnablePauseTimerShortcut.IsChecked = OptionsManager.ConfigFile.ReadValueBool("EnablePauseTimerShortcut", false); + if (m_EnableEffectsMenu is not null) + m_EnableEffectsMenu.IsChecked = OptionsManager.ConfigFile.ReadValueBool("EnableDebugMenu", false); + if (m_EnableAntiSoftlockShortcut is not null) + m_EnableAntiSoftlockShortcut.IsChecked = OptionsManager.ConfigFile.ReadValueBool("EnableAntiSoftlockShortcut", true); + } + + public override void OnSaveValues() + { + OptionsManager.ConfigFile.WriteValue("EnableToggleModShortcut", m_EnableToggleModShortcut?.IsChecked); + OptionsManager.ConfigFile.WriteValue("EnableClearEffectsShortcut", m_EnableClearActiveEffectsShortcut?.IsChecked); + OptionsManager.ConfigFile.WriteValue("EnableDebugMenu", m_EnableEffectsMenu?.IsChecked); + OptionsManager.ConfigFile.WriteValue("EnablePauseTimerShortcut", m_EnablePauseTimerShortcut?.IsChecked); + OptionsManager.ConfigFile.WriteValue("EnableAntiSoftlockShortcut", m_EnableAntiSoftlockShortcut?.IsChecked); + } + } +}