Files
HawkeyeVision/VisionBuilder.UI.Blazor/Dialogs/SettingsDialog.razor
EugeneTes 83597b8763 web UI
2026-03-19 09:03:41 +01:00

227 lines
8.8 KiB
Plaintext

@using MudBlazor
@using System.ComponentModel
@using System.Reflection
@using Inspectron.Settings
<MudDialog>
<DialogContent>
<div class="settings-layout">
<div class="settings-tree">
<MudTreeView T="string" SelectedValueChanged="OnCategorySelected" Dense="true">
<SettingsTreeNode Nodes="_treeRoot" />
</MudTreeView>
</div>
<div class="settings-content">
@if (_selectedCategory != null && GetSettingsForCategory(_selectedCategory) is { Count: > 0 } settings)
{
@foreach (var setting in settings)
{
<div class="settings-field">
@if (setting.Property.PropertyType == typeof(bool))
{
var boolVal = (bool)(setting.Value ?? false);
<MudSwitch T="bool" Value="boolVal"
ValueChanged="@(v => setting.Value = v)"
Label="@setting.Description" Color="Color.Primary" />
}
else if (setting.Property.PropertyType == typeof(int))
{
var intVal = (int)(setting.Value ?? 0);
<MudNumericField T="int" Value="intVal"
ValueChanged="@(v => setting.Value = v)"
Label="@setting.Description" Variant="Variant.Outlined" />
}
else if (setting.Property.PropertyType == typeof(double))
{
var dblVal = (double)(setting.Value ?? 0.0);
<MudNumericField T="double" Value="dblVal"
ValueChanged="@(v => setting.Value = v)"
Label="@setting.Description" Variant="Variant.Outlined" />
}
else if (setting.Property.PropertyType.IsEnum)
{
<MudSelect T="object" Value="setting.Value"
ValueChanged="@(v => setting.Value = v)"
Label="@setting.Description" Variant="Variant.Outlined">
@foreach (var enumVal in Enum.GetValues(setting.Property.PropertyType))
{
<MudSelectItem T="object" Value="@enumVal">@enumVal.ToString()</MudSelectItem>
}
</MudSelect>
}
else
{
var strVal = setting.Value?.ToString() ?? "";
<MudTextField T="string" Value="strVal"
ValueChanged="@(v => setting.Value = v)"
Label="@setting.Description" Variant="Variant.Outlined" />
}
</div>
}
}
else
{
<MudText Typo="Typo.body2" Class="pa-4">Select a category to view settings.</MudText>
}
</div>
</div>
</DialogContent>
<DialogActions>
<MudButton OnClick="Cancel">Cancel</MudButton>
<MudButton Color="Color.Primary" OnClick="Save">Save</MudButton>
</DialogActions>
</MudDialog>
@code {
[CascadingParameter] private IMudDialogInstance MudDialog { get; set; } = null!;
[Parameter] public InspectronSettings? Settings { get; set; }
private Dictionary<string, List<SettingEntry>> _categories = new();
private string? _selectedCategory;
private List<CategoryNode> _treeRoot = new();
protected override void OnParametersSet()
{
if (Settings == null) return;
LoadSettings();
}
private void LoadSettings()
{
_categories.Clear();
_treeRoot = new List<CategoryNode>();
var treeView = Settings!.UserSettings;
var root = treeView.Root as Tree<object>;
if (root != null)
Traverse(root, "");
// Build the UI tree from category paths
foreach (var categoryPath in _categories.Keys)
{
var parts = categoryPath.Split('/');
var currentList = _treeRoot;
for (int i = 0; i < parts.Length; i++)
{
var existing = currentList.FirstOrDefault(n => n.Label == parts[i]);
if (existing == null)
{
existing = new CategoryNode
{
Label = parts[i],
FullPath = string.Join("/", parts.Take(i + 1))
};
currentList.Add(existing);
}
currentList = existing.ChildNodes;
}
}
}
private void Traverse(Tree<object> node, string path)
{
object value = node.Value;
if (value is string folderName)
{
string newPath = string.IsNullOrEmpty(path) ? folderName : $"{path}/{folderName}";
foreach (Tree<object> child in node.Children)
Traverse(child, newPath);
}
else if (value is InspectronSettings.UserSettingsInfo info)
{
string groupName = info.Name;
string groupPath = string.IsNullOrEmpty(path) ? groupName : $"{path}/{groupName}";
foreach (PropertyDescriptor pd in info.Settings)
{
if (pd is BoundPropertyDescriptor bpd)
{
var owner = bpd.Owner;
var description = string.IsNullOrEmpty(pd.Description) ? bpd.DisplayName : pd.Description;
var entry = new SettingEntry
{
Owner = owner,
Property = bpd.PropertyInfo,
Description = description,
Value = bpd.PropertyInfo.GetValue(owner)
};
if (!_categories.TryGetValue(groupPath, out var list))
{
list = new List<SettingEntry>();
_categories[groupPath] = list;
}
list.Add(entry);
}
}
}
}
private void OnCategorySelected(string? category)
{
_selectedCategory = category;
}
private List<SettingEntry> GetSettingsForCategory(string category)
{
// Exact match first
if (_categories.TryGetValue(category, out var exact))
return exact;
// Otherwise aggregate all sub-categories
var prefix = category + "/";
return _categories
.Where(kvp => kvp.Key.StartsWith(prefix))
.SelectMany(kvp => kvp.Value)
.ToList();
}
private void Save()
{
foreach (var list in _categories.Values)
{
foreach (var setting in list)
{
var currentValue = setting.Property.GetValue(setting.Owner);
if (!Equals(currentValue, setting.Value))
{
try
{
if (setting.Value != null && setting.Value.GetType() != setting.Property.PropertyType)
{
var converted = Convert.ChangeType(setting.Value, setting.Property.PropertyType);
setting.Property.SetValue(setting.Owner, converted);
}
else
{
setting.Property.SetValue(setting.Owner, setting.Value);
}
}
catch
{
// Skip properties that fail to convert
}
}
}
}
Settings?.SaveSettings();
MudDialog.Close(DialogResult.Ok(true));
}
private void Cancel() => MudDialog.Cancel();
private class SettingEntry
{
public object Owner { get; set; } = null!;
public PropertyInfo Property { get; set; } = null!;
public string Description { get; set; } = "";
public object? Value { get; set; }
}
public class CategoryNode
{
public string Label { get; set; } = "";
public string FullPath { get; set; } = "";
public List<CategoryNode> ChildNodes { get; set; } = new();
}
}