Settings management started
This commit is contained in:
@@ -9,6 +9,7 @@ public static class AppManager
|
||||
public static ICogwheelConsole SzConsole { get; } = new SessionZeroConsole();
|
||||
public static CommandsManager CommandsManager { get; } = new();
|
||||
public static ConsoleControl ConsoleControl { get; } = new();
|
||||
public static AppSettings Settings { get; } = new();
|
||||
|
||||
public static void ShowConsole()
|
||||
{
|
||||
@@ -27,4 +28,10 @@ public static class AppManager
|
||||
{
|
||||
MainWindow.ChangePage(pageName);
|
||||
}
|
||||
|
||||
[Command(Name = "test")]
|
||||
private static void Test()
|
||||
{
|
||||
COGWHEEL.LogWarning($"Trim size is: {ConsoleControl.OutputTrimSize}");
|
||||
}
|
||||
}
|
||||
326
SessionZero/AppSettings.cs
Normal file
326
SessionZero/AppSettings.cs
Normal file
@@ -0,0 +1,326 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Avalonia.Media;
|
||||
using Cogwheel;
|
||||
|
||||
namespace SessionZero;
|
||||
|
||||
public class AppSettings
|
||||
{
|
||||
public string SettingsFilePath { get; set; } = "";
|
||||
public Dictionary<string, AppSetting> Settings { get; set; } = new();
|
||||
|
||||
public AppSetting CreateSetting(string settingName, Type settingType)
|
||||
{
|
||||
return new AppSetting(settingName, settingType);
|
||||
}
|
||||
|
||||
public void AddSetting(AppSetting setting)
|
||||
{
|
||||
if (!Settings.TryAdd(setting.SettingName, setting))
|
||||
{
|
||||
COGWHEEL.LogError($"Cannot add setting: '{setting.SettingName}'. Setting already exists.");
|
||||
}
|
||||
}
|
||||
|
||||
public AppSetting? GetSetting(string settingName)
|
||||
{
|
||||
if (!Settings.TryGetValue(settingName, out var setting))
|
||||
{
|
||||
COGWHEEL.LogError($"Cannot get setting: '{settingName}'. Setting does not exist.");
|
||||
return null;
|
||||
}
|
||||
|
||||
return setting;
|
||||
}
|
||||
|
||||
public void RemoveSetting(string settingName)
|
||||
{
|
||||
if (!Settings.Remove(settingName))
|
||||
{
|
||||
COGWHEEL.LogError($"Cannot remove setting: '{settingName}. It may not exist.");
|
||||
}
|
||||
}
|
||||
|
||||
public bool SetSettingValue<T>(string settingName, T value)
|
||||
{
|
||||
if (Settings.TryGetValue(settingName, out var setting))
|
||||
{
|
||||
return setting.SetValue(value);
|
||||
}
|
||||
|
||||
COGWHEEL.LogError($"Cannot set setting: '{settingName}'. Setting does not exist.");
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool SetSettingValue(string settingName, string value)
|
||||
{
|
||||
if (Settings.TryGetValue(settingName, out var setting))
|
||||
{
|
||||
return setting.SetValue(value);
|
||||
}
|
||||
|
||||
COGWHEEL.LogError($"Cannot set setting: '{settingName}'. Setting does not exist.");
|
||||
return false;
|
||||
}
|
||||
|
||||
public T? GetValue<T>(string settingName)
|
||||
{
|
||||
if (Settings.TryGetValue(settingName, out var setting))
|
||||
{
|
||||
return setting.GetValue<T>();
|
||||
}
|
||||
|
||||
return default;
|
||||
}
|
||||
|
||||
public string GetValueAsString(string settingName)
|
||||
{
|
||||
if (!Settings.TryGetValue(settingName, out var setting) || setting == null)
|
||||
{
|
||||
COGWHEEL.LogError($"Cannot get setting '{settingName}'. Setting does not exist.");
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
var type = setting.SettingType;
|
||||
|
||||
try
|
||||
{
|
||||
var method = typeof(AppSetting).GetMethod(nameof(AppSetting.GetValue))!;
|
||||
var generic = method.MakeGenericMethod(type);
|
||||
|
||||
var valueObj = generic.Invoke(setting, null);
|
||||
|
||||
if (valueObj == null)
|
||||
return string.Empty;
|
||||
|
||||
if (type == typeof(string))
|
||||
return (string)valueObj;
|
||||
|
||||
if (type.IsPrimitive || type.IsEnum || type == typeof(decimal))
|
||||
return Convert.ToString(valueObj) ?? string.Empty;
|
||||
|
||||
return valueObj.ToString() ?? string.Empty;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
COGWHEEL.LogError($"Failed to get setting '{settingName}' as string: {ex.Message}");
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public void SaveToFile() {}
|
||||
public void LoadFromFile() {}
|
||||
}
|
||||
|
||||
public class AppSetting(string settingName, Type settingType)
|
||||
{
|
||||
public string SettingName { get; } = settingName;
|
||||
public Type SettingType { get; } = settingType;
|
||||
|
||||
private object? _settingValue;
|
||||
|
||||
public T GetValue<T>()
|
||||
{
|
||||
if (typeof(T) != SettingType)
|
||||
{
|
||||
COGWHEEL.LogError($"Cannot get value of setting '{SettingName}': Setting is type '{SettingType.Name}' but GetValue was called with type '{typeof(T).Name}'.'");
|
||||
}
|
||||
|
||||
return _settingValue is null ? default! : (T)_settingValue;
|
||||
}
|
||||
|
||||
|
||||
public bool SetValue<T>(T value)
|
||||
{
|
||||
if (typeof(T) != SettingType)
|
||||
{
|
||||
COGWHEEL.LogError($"Cannot set value of setting '{SettingName}': Setting is type '{SettingType.Name}' but SetValue was called with type '{typeof(T).Name}'.'");
|
||||
return false;
|
||||
}
|
||||
|
||||
_settingValue = value!;
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool SetValue(object? value)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
_settingValue = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (SettingType.IsInstanceOfType(value))
|
||||
{
|
||||
_settingValue = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var converted = Convert.ChangeType(value, SettingType);
|
||||
_settingValue = converted;
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
COGWHEEL.LogError($"Cannot convert value '{value}' to {SettingType.Name} for setting '{SettingName}'.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool SetValue(string valueString)
|
||||
{
|
||||
try
|
||||
{
|
||||
object? parsedValue = null;
|
||||
|
||||
if (SettingType == typeof(string))
|
||||
{
|
||||
parsedValue = valueString;
|
||||
}
|
||||
else if (SettingType == typeof(int))
|
||||
{
|
||||
if (!int.TryParse(valueString, out var i))
|
||||
{
|
||||
COGWHEEL.LogError($"Cannot parse '{valueString}' as int for setting '{SettingName}'.");
|
||||
return false;
|
||||
}
|
||||
parsedValue = i;
|
||||
}
|
||||
else if (SettingType == typeof(float))
|
||||
{
|
||||
if (!float.TryParse(valueString, out var f))
|
||||
{
|
||||
COGWHEEL.LogError($"Cannot parse '{valueString}' as float for setting '{SettingName}'.");
|
||||
return false;
|
||||
}
|
||||
parsedValue = f;
|
||||
}
|
||||
else if (SettingType == typeof(bool))
|
||||
{
|
||||
if (!bool.TryParse(valueString, out var b))
|
||||
{
|
||||
COGWHEEL.LogError($"Cannot parse '{valueString}' as bool for setting '{SettingName}'.");
|
||||
return false;
|
||||
}
|
||||
parsedValue = b;
|
||||
}
|
||||
else
|
||||
{
|
||||
COGWHEEL.LogError(
|
||||
$"Unsupported setting type '{SettingType.Name}' in SetValue(string) for setting '{SettingName}'.");
|
||||
return false;
|
||||
}
|
||||
|
||||
_settingValue = parsedValue;
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
COGWHEEL.LogError($"Failed to set setting '{SettingName}' to '{valueString}': {ex.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class AppSettingsCommands
|
||||
{
|
||||
[Command(Name = "setsetting")]
|
||||
public static void SetSetting(string settingName, string value)
|
||||
{
|
||||
if (AppManager.Settings.SetSettingValue(settingName, value))
|
||||
{
|
||||
COGWHEEL.Log($"Setting '{settingName}' set to '{value}'.");
|
||||
}
|
||||
// else
|
||||
// {
|
||||
// COGWHEEL.LogError($"Could not set setting '{settingName}' to '{value}'.");
|
||||
// }
|
||||
}
|
||||
|
||||
[Command(Name = "getsetting")]
|
||||
public static void GetSetting(string settingName)
|
||||
{
|
||||
var value = AppManager.Settings.GetValueAsString(settingName);
|
||||
COGWHEEL.Log($"Setting '{settingName}' value is: ({AppManager.Settings.GetSetting(settingName)?.SettingType.Name}){value}.");
|
||||
}
|
||||
|
||||
[Command(Name = "listsettings")]
|
||||
public static void ListSettings(string settingName = "")
|
||||
{
|
||||
var outputString = $"-- Settings --\n";
|
||||
if (string.IsNullOrEmpty(settingName))
|
||||
{
|
||||
foreach (var setting in AppManager.Settings.Settings)
|
||||
{
|
||||
outputString +=
|
||||
$"{setting.Value.SettingName}: {setting.Value.SettingType.Name} = {AppManager.Settings.GetValueAsString(setting.Key)}\n";
|
||||
}
|
||||
|
||||
AppManager.ConsoleControl.Log(outputString, Colors.CadetBlue);
|
||||
}
|
||||
else
|
||||
{
|
||||
COGWHEEL.LogWarning($"Searching for settings is not implemented yet.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// TODO: Go update Cogwheel to accept array arguments somehow
|
||||
// [Command(Name = "setting")]
|
||||
// public static void SettingCommand(string[] args)
|
||||
// {
|
||||
// if (args.Length == 0)
|
||||
// {
|
||||
// COGWHEEL.LogError("No arguments supplied. Usage: 'setting <action>'");
|
||||
// }
|
||||
//
|
||||
// var action = args[0];
|
||||
// List<string> actionArgs = new();
|
||||
// for (int i = 1; i < args.Length; i++)
|
||||
// {
|
||||
// actionArgs.Add(args[i]);
|
||||
// }
|
||||
//
|
||||
// switch (action)
|
||||
// {
|
||||
// case "set":
|
||||
// if (actionArgs.Count == 2)
|
||||
// {
|
||||
// var settingName = args[0];
|
||||
// var settingValue = args[1];
|
||||
//
|
||||
// if (AppManager.Settings.SetSettingValue(settingName, settingValue))
|
||||
// {
|
||||
// COGWHEEL.Log($"Setting '{settingName}' successfully set to '{settingValue}'.");
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// COGWHEEL.LogError($"Invalid number of arguments for '{action}'. Usage: 'setting set <settingName> <settingValue>'");
|
||||
// }
|
||||
// break;
|
||||
// case "get":
|
||||
// if (actionArgs.Count == 1)
|
||||
// {
|
||||
// var val = AppManager.Settings.GetValueAsString(args[0]);
|
||||
// COGWHEEL.Log($"Value of Setting '{args[0]}' is '{val}'.");
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// COGWHEEL.LogError($"Invalid number of arguments for '{action}'. Usage: 'setting get <settingName>'");
|
||||
// }
|
||||
// break;
|
||||
// case "add":
|
||||
// break;
|
||||
// case "remove":
|
||||
// break;
|
||||
// default:
|
||||
// COGWHEEL.LogError($"Unknown argument '{action}' for 'setting' command. Options are 'set, get, add, remove'.");
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
@@ -5,7 +5,9 @@
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="SessionZero.Cogwheel.ConsoleControl">
|
||||
<Grid Background="Transparent" RowDefinitions="*, Auto, *" HorizontalAlignment="Stretch">
|
||||
<TextBlock Grid.Row="0" Name="Output" Foreground="White" Background="#7F272727" HorizontalAlignment="Stretch" TextWrapping="Wrap"></TextBlock>
|
||||
<ScrollViewer Name="OutputScrollView">
|
||||
<TextBlock Grid.Row="0" Name="Output" Foreground="White" Background="#7F272727" HorizontalAlignment="Stretch" TextWrapping="Wrap"></TextBlock>
|
||||
</ScrollViewer>
|
||||
<TextBox Grid.Row="1" Name="Input" Background="#7F272727" Foreground="White" Height="30" AcceptsReturn="False" AcceptsTab="False"></TextBox>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
||||
@@ -10,8 +10,11 @@ namespace SessionZero.Cogwheel;
|
||||
|
||||
public partial class ConsoleControl : UserControl
|
||||
{
|
||||
public int OutputTrimSize { get; set; } = 200;
|
||||
|
||||
private TextBlock? _output;
|
||||
private TextBox? _input;
|
||||
private ScrollViewer? _outputScrollViewer;
|
||||
|
||||
public ConsoleControl()
|
||||
{
|
||||
@@ -19,6 +22,7 @@ public partial class ConsoleControl : UserControl
|
||||
|
||||
_output = this.FindControl<TextBlock>("Output");
|
||||
_input = this.FindControl<TextBox>("Input");
|
||||
_outputScrollViewer = this.FindControl<ScrollViewer>("OutputScrollView");
|
||||
|
||||
_input?.KeyDown += Input_OnKeyDown;
|
||||
}
|
||||
@@ -27,14 +31,37 @@ public partial class ConsoleControl : UserControl
|
||||
{
|
||||
if (e.Key == Key.Enter)
|
||||
{
|
||||
var inputText = _input!.Text ?? string.Empty;
|
||||
Log(inputText);
|
||||
if (inputText.Length > 0) COGWHEEL.RunCommand(inputText);
|
||||
_input.Text = string.Empty;
|
||||
SubmitInput();
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void SubmitInput()
|
||||
{
|
||||
var inputText = _input!.Text ?? string.Empty;
|
||||
Log(inputText);
|
||||
if (inputText.Length > 0) COGWHEEL.RunCommand(inputText);
|
||||
_input.Text = string.Empty;
|
||||
TrimOutput();
|
||||
ScrollToEnd();
|
||||
}
|
||||
|
||||
private void TrimOutput()
|
||||
{
|
||||
var maxInLines = OutputTrimSize * 3;
|
||||
while (_output?.Inlines?.Count > maxInLines)
|
||||
{
|
||||
if (_output?.Inlines?.Count >= 3)
|
||||
{
|
||||
_output?.Inlines?.RemoveRange(0,3);
|
||||
}
|
||||
else
|
||||
{
|
||||
_output?.Inlines?.RemoveAt(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Log(string text, Color? color = null)
|
||||
{
|
||||
if (_output == null)
|
||||
@@ -58,4 +85,9 @@ public partial class ConsoleControl : UserControl
|
||||
{
|
||||
_output?.Inlines?.Clear();
|
||||
}
|
||||
|
||||
public void ScrollToEnd()
|
||||
{
|
||||
_outputScrollViewer?.ScrollToEnd();
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,9 @@ public partial class MainWindow : Window
|
||||
KeyDownEvent.AddClassHandler<TopLevel>(OnKeyDown, handledEventsToo: true);
|
||||
|
||||
ChangePage("Home");
|
||||
|
||||
AppManager.Settings.AddSetting(new AppSetting("test", typeof(int)));
|
||||
AppManager.Settings.SetSettingValue("test", 1);
|
||||
}
|
||||
|
||||
public void ChangePage(string pageName)
|
||||
|
||||
@@ -6,5 +6,15 @@
|
||||
x:Class="SessionZero.Pages.SettingsPage">
|
||||
<StackPanel>
|
||||
<Label FontSize="20">Settings</Label>
|
||||
|
||||
<StackPanel Orientation="Horizontal" Spacing="15">
|
||||
<Label FontSize="15" VerticalAlignment="Center">Console Output Max Size</Label>
|
||||
<Slider Name="ConsoleTrimSlider" Minimum="10" Maximum="1000" Width="200" HorizontalAlignment="Left"></Slider>
|
||||
<TextBlock Name="ConsoleTrimSliderValue" VerticalAlignment="Center">10</TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal" Spacing="15">
|
||||
<Label VerticalAlignment="Center" FontSize="15">Log To File</Label>
|
||||
<CheckBox Name="LogToFileCheckbox"></CheckBox>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
namespace SessionZero.Pages;
|
||||
@@ -8,10 +9,28 @@ public partial class SettingsPage : UserControl, IPageBase
|
||||
{
|
||||
public string PageName { get; set; } = "Settings";
|
||||
|
||||
private Slider? _consoleTrimSlider;
|
||||
private TextBlock? _consoleTrimSliderLabel;
|
||||
|
||||
public SettingsPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
_consoleTrimSlider = this.FindControl<Slider>("ConsoleTrimSlider");
|
||||
_consoleTrimSliderLabel = this.FindControl<TextBlock>("ConsoleTrimSliderValue");
|
||||
|
||||
_consoleTrimSlider?.ValueChanged += ConsoleTrimSliderOnValueChanged;
|
||||
}
|
||||
|
||||
private void ConsoleTrimSliderOnValueChanged(object? sender, RangeBaseValueChangedEventArgs e)
|
||||
{
|
||||
AppManager.ConsoleControl.OutputTrimSize = (int)e.NewValue;
|
||||
_consoleTrimSliderLabel?.Text = AppManager.ConsoleControl.OutputTrimSize.ToString();
|
||||
}
|
||||
|
||||
public void Refresh()
|
||||
{
|
||||
_consoleTrimSlider?.Value = AppManager.ConsoleControl.OutputTrimSize;
|
||||
_consoleTrimSliderLabel?.Text = AppManager.ConsoleControl.OutputTrimSize.ToString();
|
||||
}
|
||||
|
||||
public void Refresh() { }
|
||||
}
|
||||
@@ -2,4 +2,5 @@
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ACOGWHEEL_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003Fhome_003Fchris_003F_002Econfig_003FJetBrains_003FRider2025_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F2ee8efbdf4144b7e9741475fab7c883d5800_003Fa0_003F83e60bea_003FCOGWHEEL_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ACommandsManager_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003Fhome_003Fchris_003F_002Econfig_003FJetBrains_003FRider2025_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F2ee8efbdf4144b7e9741475fab7c883d5800_003F6f_003F28a7ba06_003FCommandsManager_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AICogwheelConsole_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003Fhome_003Fchris_003F_002Econfig_003FJetBrains_003FRider2025_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F2ee8efbdf4144b7e9741475fab7c883d5800_003F77_003Fe0eaad3c_003FICogwheelConsole_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AMethodBaseInvoker_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003Fhome_003Fchris_003F_002Econfig_003FJetBrains_003FRider2025_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fd6b757e154dd7f8c23e0e785431c97a76e4b9c6bdae38b978238421dbab55d_003FMethodBaseInvoker_002Ecs/@EntryIndexedValue">ForceIncluded</s:String></wpf:ResourceDictionary>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AMethodBaseInvoker_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003Fhome_003Fchris_003F_002Econfig_003FJetBrains_003FRider2025_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fd6b757e154dd7f8c23e0e785431c97a76e4b9c6bdae38b978238421dbab55d_003FMethodBaseInvoker_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AString_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003Fhome_003Fchris_003F_002Econfig_003FJetBrains_003FRider2025_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fdad3f0ebff0dd1f8e1d244c3c44c649be8228d5e25fb37ef1de7f3c0e261c_003FString_002Ecs/@EntryIndexedValue">ForceIncluded</s:String></wpf:ResourceDictionary>
|
||||
Reference in New Issue
Block a user