settings for avalonia
libcamera bugfix
This commit is contained in:
@@ -0,0 +1,320 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Layout;
|
||||
using Avalonia.Media;
|
||||
using Avalonia.Platform.Storage;
|
||||
using Inspectron.Settings.Attributes;
|
||||
|
||||
namespace Inspectron.Settings.Avalonia.Configuration;
|
||||
|
||||
public class DefaultControlFactory : IControlFactory
|
||||
{
|
||||
public virtual Control CreateControl(string name, string description, PropertyInfo propertyInfo,
|
||||
object initialValue, Action<object> valueChangedCallback, OptionsWindow optionsWindow)
|
||||
{
|
||||
var type = propertyInfo.PropertyType;
|
||||
|
||||
var settingDescriptionAttribute = propertyInfo.GetCustomAttribute<SettingDescriptionAttribute>();
|
||||
string? settingDescription = settingDescriptionAttribute?.Description;
|
||||
|
||||
var previewAttribute = propertyInfo.GetCustomAttribute<SettingPreviewAttribute>();
|
||||
TextBlock? previewLabel = null;
|
||||
Func<object, string>? getPreview = null;
|
||||
|
||||
if (previewAttribute != null)
|
||||
{
|
||||
var method = previewAttribute.PreviewClass.GetMethod(previewAttribute.PreviewFunction, BindingFlags.Public | BindingFlags.Static);
|
||||
if (method != null)
|
||||
{
|
||||
getPreview = value => (string)method.Invoke(null, new[] { value })!;
|
||||
previewLabel = new TextBlock
|
||||
{
|
||||
Width = 600,
|
||||
Height = 30,
|
||||
Padding = new Thickness(15, 0, 0, 0),
|
||||
FontStyle = FontStyle.Italic,
|
||||
FontSize = 13,
|
||||
Text = getPreview(initialValue)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>))
|
||||
{
|
||||
return CreateListControl(name, description, type, initialValue, valueChangedCallback, optionsWindow, settingDescription, previewLabel, getPreview);
|
||||
}
|
||||
else if (type == typeof(string) && propertyInfo.GetCustomAttribute<FileAttribute>() != null)
|
||||
{
|
||||
return CreateFileControl(name, description, initialValue, valueChangedCallback, optionsWindow, settingDescription, previewLabel, getPreview, propertyInfo.GetCustomAttribute<FileAttribute>()!.Filter);
|
||||
}
|
||||
else if (type == typeof(string) && name.EndsWith("Path", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return CreatePathControl(name, description, initialValue, valueChangedCallback, optionsWindow, settingDescription, previewLabel, getPreview);
|
||||
}
|
||||
else if (type == typeof(string))
|
||||
{
|
||||
return CreateStringControl(description, initialValue, valueChangedCallback, settingDescription, previewLabel, getPreview);
|
||||
}
|
||||
else if (type == typeof(int))
|
||||
{
|
||||
return CreateIntControl(description, initialValue, valueChangedCallback, settingDescription, previewLabel, getPreview);
|
||||
}
|
||||
else if (type == typeof(bool))
|
||||
{
|
||||
return CreateBoolControl(description, initialValue, valueChangedCallback, settingDescription, previewLabel, getPreview);
|
||||
}
|
||||
else if (type.IsEnum)
|
||||
{
|
||||
return CreateEnumControl(description, type, initialValue, valueChangedCallback, settingDescription, previewLabel, getPreview);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new TextBlock { Text = $"Unsupported type: {type.Name}" };
|
||||
}
|
||||
}
|
||||
|
||||
private Control CreateListControl(string name, string description, Type listType, object initialValue,
|
||||
Action<object> valueChangedCallback, OptionsWindow optionsWindow, string? settingDescription,
|
||||
TextBlock? previewLabel, Func<object, string>? getPreview)
|
||||
{
|
||||
var elementType = listType.GetGenericArguments()[0];
|
||||
var list = (IList)initialValue ?? (IList)Activator.CreateInstance(listType)!;
|
||||
|
||||
var label = new TextBlock { Text = description, Padding = new Thickness(0, 5, 0, 0) };
|
||||
var textBox = new TextBox
|
||||
{
|
||||
Text = GetListDisplayText(list),
|
||||
Width = 500,
|
||||
Height = 60,
|
||||
IsReadOnly = true,
|
||||
AcceptsReturn = true,
|
||||
TextWrapping = TextWrapping.Wrap
|
||||
};
|
||||
var editButton = new Button { Content = "Edit" };
|
||||
|
||||
editButton.Click += async (s, e) =>
|
||||
{
|
||||
var listEditor = new ListEditorDialog(elementType, list, this, optionsWindow, name);
|
||||
var result = await listEditor.ShowDialog<IList?>(optionsWindow);
|
||||
if (result != null)
|
||||
{
|
||||
list.Clear();
|
||||
foreach (object o in result)
|
||||
{
|
||||
list.Add(o);
|
||||
}
|
||||
|
||||
textBox.Text = GetListDisplayText(list);
|
||||
valueChangedCallback(list);
|
||||
if (previewLabel != null && getPreview != null)
|
||||
previewLabel.Text = getPreview(list);
|
||||
}
|
||||
};
|
||||
|
||||
return CreateOuterPanel(settingDescription, previewLabel, label, textBox, editButton);
|
||||
}
|
||||
|
||||
private string GetListDisplayText(IList list)
|
||||
{
|
||||
if (list == null || list.Count == 0)
|
||||
return "(empty list)";
|
||||
|
||||
var items = new List<string>();
|
||||
foreach (var item in list)
|
||||
{
|
||||
items.Add(item?.ToString() ?? "(null)");
|
||||
}
|
||||
return string.Join(Environment.NewLine, items);
|
||||
}
|
||||
|
||||
private Control CreatePathControl(string name, string description, object initialValue, Action<object> valueChangedCallback,
|
||||
OptionsWindow optionsWindow, string? settingDescription, TextBlock? previewLabel, Func<object, string>? getPreview)
|
||||
{
|
||||
var textBox = new TextBox { Text = initialValue as string, Width = 400 };
|
||||
var label = new TextBlock { Text = description, Padding = new Thickness(0, 5, 0, 0) };
|
||||
var browseButton = new Button { Content = "Browse" };
|
||||
|
||||
browseButton.Click += async (s, e) =>
|
||||
{
|
||||
var storageProvider = optionsWindow.StorageProvider;
|
||||
var result = await storageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
|
||||
{
|
||||
AllowMultiple = false,
|
||||
Title = "Select Folder"
|
||||
});
|
||||
if (result.Count > 0)
|
||||
{
|
||||
var path = result[0].Path.LocalPath;
|
||||
textBox.Text = path;
|
||||
valueChangedCallback(path);
|
||||
if (previewLabel != null && getPreview != null)
|
||||
previewLabel.Text = getPreview(path);
|
||||
}
|
||||
};
|
||||
|
||||
textBox.TextChanged += (s, e) =>
|
||||
{
|
||||
valueChangedCallback(textBox.Text ?? "");
|
||||
if (previewLabel != null && getPreview != null)
|
||||
previewLabel.Text = getPreview(textBox.Text ?? "");
|
||||
};
|
||||
|
||||
var row = new StackPanel { Orientation = Orientation.Horizontal, Spacing = 8 };
|
||||
row.Children.Add(textBox);
|
||||
row.Children.Add(browseButton);
|
||||
|
||||
return CreateOuterPanel(settingDescription, previewLabel, label, row);
|
||||
}
|
||||
|
||||
private Control CreateFileControl(string name, string description, object initialValue, Action<object> valueChangedCallback,
|
||||
OptionsWindow optionsWindow, string? settingDescription, TextBlock? previewLabel, Func<object, string>? getPreview, string filter)
|
||||
{
|
||||
var textBox = new TextBox { Text = initialValue as string, Width = 400 };
|
||||
var label = new TextBlock { Text = description, Padding = new Thickness(0, 5, 0, 0) };
|
||||
var browseButton = new Button { Content = "Browse" };
|
||||
|
||||
browseButton.Click += async (s, e) =>
|
||||
{
|
||||
var storageProvider = optionsWindow.StorageProvider;
|
||||
var result = await storageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
||||
{
|
||||
AllowMultiple = false,
|
||||
Title = "Select File",
|
||||
FileTypeFilter = new[] { new FilePickerFileType(filter) { Patterns = new[] { filter } } }
|
||||
});
|
||||
if (result.Count > 0)
|
||||
{
|
||||
var path = result[0].Path.LocalPath;
|
||||
textBox.Text = path;
|
||||
valueChangedCallback(path);
|
||||
if (previewLabel != null && getPreview != null)
|
||||
previewLabel.Text = getPreview(path);
|
||||
}
|
||||
};
|
||||
|
||||
textBox.TextChanged += (s, e) =>
|
||||
{
|
||||
valueChangedCallback(textBox.Text ?? "");
|
||||
if (previewLabel != null && getPreview != null)
|
||||
previewLabel.Text = getPreview(textBox.Text ?? "");
|
||||
};
|
||||
|
||||
var row = new StackPanel { Orientation = Orientation.Horizontal, Spacing = 8 };
|
||||
row.Children.Add(textBox);
|
||||
row.Children.Add(browseButton);
|
||||
|
||||
return CreateOuterPanel(settingDescription, previewLabel, label, row);
|
||||
}
|
||||
|
||||
private Control CreateStringControl(string description, object initialValue, Action<object> valueChangedCallback,
|
||||
string? settingDescription, TextBlock? previewLabel, Func<object, string>? getPreview)
|
||||
{
|
||||
var textBox = new TextBox { Text = initialValue as string, Width = 600 };
|
||||
var label = new TextBlock { Text = description, Padding = new Thickness(0, 5, 0, 0) };
|
||||
|
||||
textBox.TextChanged += (s, e) =>
|
||||
{
|
||||
valueChangedCallback(textBox.Text ?? "");
|
||||
if (previewLabel != null && getPreview != null)
|
||||
previewLabel.Text = getPreview(textBox.Text ?? "");
|
||||
};
|
||||
|
||||
return CreateOuterPanel(settingDescription, previewLabel, label, textBox);
|
||||
}
|
||||
|
||||
private Control CreateIntControl(string description, object initialValue, Action<object> valueChangedCallback,
|
||||
string? settingDescription, TextBlock? previewLabel, Func<object, string>? getPreview)
|
||||
{
|
||||
var label = new TextBlock { Text = description, Padding = new Thickness(0, 5, 0, 0) };
|
||||
var numericUpDown = new NumericUpDown
|
||||
{
|
||||
Minimum = 0,
|
||||
Maximum = 99999999999,
|
||||
Value = Convert.ToDecimal(initialValue),
|
||||
Width = 200,
|
||||
FormatString = "0"
|
||||
};
|
||||
|
||||
numericUpDown.ValueChanged += (s, e) =>
|
||||
{
|
||||
valueChangedCallback(Convert.ToInt32(numericUpDown.Value));
|
||||
if (previewLabel != null && getPreview != null)
|
||||
previewLabel.Text = getPreview(Convert.ToInt32(numericUpDown.Value));
|
||||
};
|
||||
|
||||
return CreateOuterPanel(settingDescription, previewLabel, label, numericUpDown);
|
||||
}
|
||||
|
||||
private Control CreateBoolControl(string description, object initialValue, Action<object> valueChangedCallback,
|
||||
string? settingDescription, TextBlock? previewLabel, Func<object, string>? getPreview)
|
||||
{
|
||||
var checkBox = new CheckBox { Content = description, IsChecked = (bool)initialValue };
|
||||
|
||||
checkBox.IsCheckedChanged += (s, e) =>
|
||||
{
|
||||
var isChecked = checkBox.IsChecked == true;
|
||||
valueChangedCallback(isChecked);
|
||||
if (previewLabel != null && getPreview != null)
|
||||
previewLabel.Text = getPreview(isChecked);
|
||||
};
|
||||
|
||||
return CreateOuterPanel(settingDescription, previewLabel, checkBox);
|
||||
}
|
||||
|
||||
private Control CreateEnumControl(string description, Type enumType, object initialValue, Action<object> valueChangedCallback,
|
||||
string? settingDescription, TextBlock? previewLabel, Func<object, string>? getPreview)
|
||||
{
|
||||
var label = new TextBlock { Text = description, Padding = new Thickness(0, 5, 0, 0) };
|
||||
var comboBox = new ComboBox { Width = 200 };
|
||||
|
||||
var enumValues = Enum.GetValues(enumType);
|
||||
foreach (var value in enumValues)
|
||||
{
|
||||
comboBox.Items.Add(value);
|
||||
}
|
||||
|
||||
comboBox.SelectedItem = initialValue;
|
||||
|
||||
comboBox.SelectionChanged += (s, e) =>
|
||||
{
|
||||
if (comboBox.SelectedItem != null)
|
||||
{
|
||||
valueChangedCallback(comboBox.SelectedItem);
|
||||
if (previewLabel != null && getPreview != null)
|
||||
previewLabel.Text = getPreview(comboBox.SelectedItem);
|
||||
}
|
||||
};
|
||||
|
||||
return CreateOuterPanel(settingDescription, previewLabel, label, comboBox);
|
||||
}
|
||||
|
||||
private Control CreateOuterPanel(string? settingDescription, TextBlock? previewLabel, params Control[] controls)
|
||||
{
|
||||
var outerPanel = new StackPanel { Orientation = Orientation.Vertical, Spacing = 4, Margin = new Thickness(0, 25, 0, 0), HorizontalAlignment = HorizontalAlignment.Left };
|
||||
|
||||
if (!string.IsNullOrEmpty(settingDescription))
|
||||
{
|
||||
var descriptionLabel = new TextBlock
|
||||
{
|
||||
Text = settingDescription,
|
||||
FontStyle = FontStyle.Italic,
|
||||
Padding = new Thickness(0, 5, 0, 0)
|
||||
};
|
||||
outerPanel.Children.Add(descriptionLabel);
|
||||
}
|
||||
|
||||
foreach (var control in controls)
|
||||
{
|
||||
outerPanel.Children.Add(control);
|
||||
}
|
||||
|
||||
if (previewLabel != null)
|
||||
outerPanel.Children.Add(previewLabel);
|
||||
|
||||
return outerPanel;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user