466 lines
13 KiB
C#
466 lines
13 KiB
C#
|
using System;
|
|||
|
using System.Reflection;
|
|||
|
using Avalonia;
|
|||
|
using Avalonia.Controls;
|
|||
|
using Avalonia.Controls.Primitives;
|
|||
|
using Avalonia.Data;
|
|||
|
using Avalonia.Input;
|
|||
|
using Avalonia.Interactivity;
|
|||
|
using Avalonia.Layout;
|
|||
|
using Avalonia.Markup.Xaml;
|
|||
|
using Avalonia.Media;
|
|||
|
using DispenserCommon.Atrributes;
|
|||
|
using DispenserCommon.Utils;
|
|||
|
using DispenserHal.Camera.DTO;
|
|||
|
using DispenserUI.ViewModels.Components;
|
|||
|
using DispenserUI.ViewModels.DTO;
|
|||
|
using Masuit.Tools.Reflection;
|
|||
|
using Control = Avalonia.Controls.Control;
|
|||
|
using Cursor = Avalonia.Input.Cursor;
|
|||
|
using HorizontalAlignment = Avalonia.Layout.HorizontalAlignment;
|
|||
|
using Orientation = Avalonia.Layout.Orientation;
|
|||
|
using UserControl = Avalonia.Controls.UserControl;
|
|||
|
|
|||
|
namespace DispenserUI.Views.Controls;
|
|||
|
|
|||
|
public partial class CameraParamsEditor : UserControl
|
|||
|
{
|
|||
|
public CameraParamsEditor()
|
|||
|
{
|
|||
|
DataContext = ViewModel;
|
|||
|
InitializeComponent();
|
|||
|
ViewModel.ReloadCameraParams();
|
|||
|
}
|
|||
|
|
|||
|
public CameraParamsVM ViewModel { get; } = ServiceLocator.GetService<CameraParamsVM>();
|
|||
|
|
|||
|
|
|||
|
private void InitializeComponent()
|
|||
|
{
|
|||
|
AvaloniaXamlLoader.Load(this);
|
|||
|
CameraParamsPanel = this.Get<StackPanel>("CameraParamsPanel");
|
|||
|
RenderControls();
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 根据获取到的参数,渲染参数界面
|
|||
|
/// </summary>
|
|||
|
private void RenderControls()
|
|||
|
{
|
|||
|
var properties = typeof(CameraParams).GetProperties();
|
|||
|
|
|||
|
foreach (var property in properties)
|
|||
|
{
|
|||
|
var propertyType = property.PropertyType;
|
|||
|
switch (propertyType.Name)
|
|||
|
{
|
|||
|
case nameof(StringValue):
|
|||
|
CameraParamsPanel.Children.Add(RenderStringParams(property));
|
|||
|
break;
|
|||
|
case nameof(IntValue):
|
|||
|
CameraParamsPanel.Children.Add(RenderIntParams(property));
|
|||
|
break;
|
|||
|
case nameof(Boolean):
|
|||
|
CameraParamsPanel.Children.Add(RenderBooleanParams(property));
|
|||
|
break;
|
|||
|
case nameof(FloatValue):
|
|||
|
CameraParamsPanel.Children.Add(RenderFloatParams(property));
|
|||
|
break;
|
|||
|
case nameof(EnumValue):
|
|||
|
CameraParamsPanel.Children.Add(RenderEnumParams(property));
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 刷新页面
|
|||
|
InvalidateVisual();
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 渲染字符串参数
|
|||
|
/// </summary>
|
|||
|
/// <param name="property"></param>
|
|||
|
private Control RenderStringParams(PropertyInfo property)
|
|||
|
{
|
|||
|
var panel = new StackPanel
|
|||
|
{
|
|||
|
Orientation = Orientation.Horizontal,
|
|||
|
Height = 50,
|
|||
|
VerticalAlignment = VerticalAlignment.Center
|
|||
|
};
|
|||
|
|
|||
|
var name = new TextBlock
|
|||
|
{
|
|||
|
Text = property.GetDescription(),
|
|||
|
Margin = new Thickness(0, 0, 10, 0),
|
|||
|
TextWrapping = TextWrapping.Wrap,
|
|||
|
Width = 80,
|
|||
|
HorizontalAlignment = HorizontalAlignment.Left,
|
|||
|
VerticalAlignment = VerticalAlignment.Center
|
|||
|
};
|
|||
|
|
|||
|
var value = new TextBlock
|
|||
|
{
|
|||
|
Name = property.Name,
|
|||
|
Width = 250,
|
|||
|
HorizontalAlignment = HorizontalAlignment.Left,
|
|||
|
VerticalAlignment = VerticalAlignment.Center
|
|||
|
};
|
|||
|
|
|||
|
value.Bind(TextBlock.TextProperty, new Binding(property.Name + ".CurValue"));
|
|||
|
|
|||
|
panel.Children.Add(name);
|
|||
|
panel.Children.Add(value);
|
|||
|
return panel;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 渲染数字参数
|
|||
|
/// </summary>
|
|||
|
/// <param name="property"></param>
|
|||
|
private Control RenderIntParams(PropertyInfo property)
|
|||
|
{
|
|||
|
var panel = new StackPanel
|
|||
|
{
|
|||
|
Orientation = Orientation.Horizontal,
|
|||
|
Height = 50,
|
|||
|
VerticalAlignment = VerticalAlignment.Center
|
|||
|
};
|
|||
|
|
|||
|
var name = new TextBlock
|
|||
|
{
|
|||
|
Text = property.GetDescription(),
|
|||
|
Margin = new Thickness(0, 0, 10, 0),
|
|||
|
Width = 80,
|
|||
|
TextWrapping = TextWrapping.Wrap,
|
|||
|
HorizontalAlignment = HorizontalAlignment.Left,
|
|||
|
VerticalAlignment = VerticalAlignment.Center
|
|||
|
};
|
|||
|
|
|||
|
var grid = new Grid
|
|||
|
{
|
|||
|
Width = 250,
|
|||
|
HorizontalAlignment = HorizontalAlignment.Center,
|
|||
|
VerticalAlignment = VerticalAlignment.Center,
|
|||
|
ColumnDefinitions = new ColumnDefinitions("*,60")
|
|||
|
};
|
|||
|
|
|||
|
var slider = new Slider
|
|||
|
{
|
|||
|
Name = property.Name,
|
|||
|
Background = Brushes.Gray,
|
|||
|
Cursor = new Cursor(StandardCursorType.Hand),
|
|||
|
HorizontalAlignment = HorizontalAlignment.Center,
|
|||
|
VerticalAlignment = VerticalAlignment.Center
|
|||
|
};
|
|||
|
|
|||
|
slider.Bind(RangeBase.ValueProperty, new Binding(property.Name + ".CurValue")
|
|||
|
{
|
|||
|
Mode = BindingMode.TwoWay
|
|||
|
});
|
|||
|
|
|||
|
slider.Bind(RangeBase.MinimumProperty, new Binding(property.Name + ".Min")
|
|||
|
{
|
|||
|
Mode = BindingMode.TwoWay
|
|||
|
});
|
|||
|
|
|||
|
var pro = property.GetCustomAttribute<Property>();
|
|||
|
|
|||
|
if (pro != null && pro.Max != 0)
|
|||
|
{
|
|||
|
slider.Maximum = pro.Max;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
slider.Bind(RangeBase.MaximumProperty, new Binding(property.Name + ".Max")
|
|||
|
{
|
|||
|
Mode = BindingMode.TwoWay
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
slider.ValueChanged += OnSliderValueChanged;
|
|||
|
|
|||
|
var value = new NumericUpDown
|
|||
|
{
|
|||
|
Name = property.Name,
|
|||
|
Margin = new Thickness(10, 0, 0, 0),
|
|||
|
Width = 60,
|
|||
|
Height = 30,
|
|||
|
ShowButtonSpinner = false,
|
|||
|
FormatString = "F0",
|
|||
|
HorizontalAlignment = HorizontalAlignment.Center,
|
|||
|
VerticalAlignment = VerticalAlignment.Center
|
|||
|
};
|
|||
|
|
|||
|
value.Bind(NumericUpDown.ValueProperty, new Binding(property.Name + ".CurValue")
|
|||
|
{
|
|||
|
Mode = BindingMode.TwoWay
|
|||
|
});
|
|||
|
|
|||
|
value.ValueChanged += OnNumericValueChanged;
|
|||
|
|
|||
|
|
|||
|
grid.Children.Add(slider);
|
|||
|
grid.Children.Add(value);
|
|||
|
Grid.SetColumn(slider, 0);
|
|||
|
Grid.SetColumn(value, 1);
|
|||
|
|
|||
|
panel.Children.Add(name);
|
|||
|
panel.Children.Add(grid);
|
|||
|
return panel;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 渲染bool参数
|
|||
|
/// </summary>
|
|||
|
/// <param name="property"></param>
|
|||
|
private Control RenderBooleanParams(PropertyInfo property)
|
|||
|
{
|
|||
|
var panel = new StackPanel
|
|||
|
{
|
|||
|
Orientation = Orientation.Horizontal,
|
|||
|
Height = 50,
|
|||
|
VerticalAlignment = VerticalAlignment.Center
|
|||
|
};
|
|||
|
|
|||
|
var name = new TextBlock
|
|||
|
{
|
|||
|
Text = property.GetDescription(),
|
|||
|
Margin = new Thickness(0, 0, 10, 0),
|
|||
|
Width = 80,
|
|||
|
TextWrapping = TextWrapping.Wrap,
|
|||
|
HorizontalAlignment = HorizontalAlignment.Left,
|
|||
|
VerticalAlignment = VerticalAlignment.Center
|
|||
|
};
|
|||
|
|
|||
|
var value = new ToggleSwitch
|
|||
|
{
|
|||
|
Name = property.Name,
|
|||
|
OnContent = "开启",
|
|||
|
OffContent = "关闭",
|
|||
|
Cursor = new Cursor(StandardCursorType.Hand),
|
|||
|
HorizontalAlignment = HorizontalAlignment.Right,
|
|||
|
HorizontalContentAlignment = HorizontalAlignment.Center,
|
|||
|
VerticalContentAlignment = VerticalAlignment.Center,
|
|||
|
VerticalAlignment = VerticalAlignment.Center
|
|||
|
};
|
|||
|
|
|||
|
value.Bind(ToggleButton.IsCheckedProperty, new Binding(property.Name)
|
|||
|
{
|
|||
|
Mode = BindingMode.TwoWay
|
|||
|
});
|
|||
|
|
|||
|
value.IsCheckedChanged += OnToggleSwitchChanged;
|
|||
|
|
|||
|
panel.Children.Add(name);
|
|||
|
panel.Children.Add(value);
|
|||
|
return panel;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 渲染浮点型参数
|
|||
|
/// </summary>
|
|||
|
/// <param name="property"></param>
|
|||
|
private Control RenderFloatParams(PropertyInfo property)
|
|||
|
{
|
|||
|
var panel = new StackPanel
|
|||
|
{
|
|||
|
Orientation = Orientation.Horizontal,
|
|||
|
Height = 50,
|
|||
|
VerticalAlignment = VerticalAlignment.Center
|
|||
|
};
|
|||
|
|
|||
|
var name = new TextBlock
|
|||
|
{
|
|||
|
Text = property.GetDescription(),
|
|||
|
Margin = new Thickness(0, 0, 10, 0),
|
|||
|
Width = 80,
|
|||
|
TextWrapping = TextWrapping.Wrap,
|
|||
|
HorizontalAlignment = HorizontalAlignment.Left,
|
|||
|
VerticalAlignment = VerticalAlignment.Center
|
|||
|
};
|
|||
|
|
|||
|
var grid = new Grid
|
|||
|
{
|
|||
|
Width = 250,
|
|||
|
HorizontalAlignment = HorizontalAlignment.Center,
|
|||
|
VerticalAlignment = VerticalAlignment.Center,
|
|||
|
ColumnDefinitions = new ColumnDefinitions("*,60")
|
|||
|
};
|
|||
|
|
|||
|
var slider = new Slider
|
|||
|
{
|
|||
|
Name = property.Name,
|
|||
|
Background = Brushes.Gray,
|
|||
|
Cursor = new Cursor(StandardCursorType.Hand),
|
|||
|
VerticalAlignment = VerticalAlignment.Center
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
slider.Bind(RangeBase.ValueProperty, new Binding(property.Name + ".CurValue")
|
|||
|
{
|
|||
|
Mode = BindingMode.TwoWay
|
|||
|
});
|
|||
|
|
|||
|
slider.Bind(RangeBase.MinimumProperty, new Binding(property.Name + ".Min")
|
|||
|
{
|
|||
|
Mode = BindingMode.TwoWay
|
|||
|
});
|
|||
|
|
|||
|
var pro = property.GetCustomAttribute<Property>();
|
|||
|
|
|||
|
if (pro != null && pro.Max != 0)
|
|||
|
{
|
|||
|
slider.Maximum = pro.Max;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
slider.Bind(RangeBase.MaximumProperty, new Binding(property.Name + ".Max")
|
|||
|
{
|
|||
|
Mode = BindingMode.TwoWay
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
slider.ValueChanged += OnSliderValueChanged;
|
|||
|
|
|||
|
|
|||
|
var value = new NumericUpDown
|
|||
|
{
|
|||
|
Name = property.Name,
|
|||
|
Margin = new Thickness(10, 0, 0, 0),
|
|||
|
Width = 60,
|
|||
|
Height = 30,
|
|||
|
ShowButtonSpinner = false,
|
|||
|
FormatString = "0.###",
|
|||
|
HorizontalAlignment = HorizontalAlignment.Center,
|
|||
|
VerticalAlignment = VerticalAlignment.Center
|
|||
|
};
|
|||
|
|
|||
|
value.Bind(NumericUpDown.ValueProperty, new Binding(property.Name + ".CurValue")
|
|||
|
{
|
|||
|
Mode = BindingMode.TwoWay
|
|||
|
});
|
|||
|
|
|||
|
value.ValueChanged += OnNumericValueChanged;
|
|||
|
|
|||
|
grid.Children.Add(slider);
|
|||
|
grid.Children.Add(value);
|
|||
|
Grid.SetColumn(slider, 0);
|
|||
|
Grid.SetColumn(value, 1);
|
|||
|
|
|||
|
panel.Children.Add(name);
|
|||
|
panel.Children.Add(grid);
|
|||
|
return panel;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 渲染枚举类型参数
|
|||
|
/// </summary>
|
|||
|
/// <param name="property"></param>
|
|||
|
private Control RenderEnumParams(PropertyInfo property)
|
|||
|
{
|
|||
|
var panel = new StackPanel
|
|||
|
{
|
|||
|
Orientation = Orientation.Horizontal,
|
|||
|
Height = 50,
|
|||
|
VerticalAlignment = VerticalAlignment.Center
|
|||
|
};
|
|||
|
|
|||
|
var name = new TextBlock
|
|||
|
{
|
|||
|
Text = property.GetDescription(),
|
|||
|
Margin = new Thickness(0, 0, 10, 0),
|
|||
|
Width = 80,
|
|||
|
TextWrapping = TextWrapping.Wrap,
|
|||
|
HorizontalAlignment = HorizontalAlignment.Left,
|
|||
|
VerticalAlignment = VerticalAlignment.Center
|
|||
|
};
|
|||
|
|
|||
|
var value = new ComboBox
|
|||
|
{
|
|||
|
Name = property.Name,
|
|||
|
Width = 250,
|
|||
|
AutoScrollToSelectedItem = true
|
|||
|
};
|
|||
|
|
|||
|
value.Bind(ItemsControl.ItemsSourceProperty, new Binding(property.Name + ".Labels")
|
|||
|
{
|
|||
|
Mode = BindingMode.TwoWay
|
|||
|
});
|
|||
|
|
|||
|
value.Bind(SelectingItemsControl.SelectedIndexProperty, new Binding(property.Name + ".CurIndex")
|
|||
|
{
|
|||
|
Mode = BindingMode.TwoWay
|
|||
|
});
|
|||
|
|
|||
|
value.SelectionChanged += OnSelectionChanged;
|
|||
|
|
|||
|
panel.Children.Add(name);
|
|||
|
panel.Children.Add(value);
|
|||
|
return panel;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 当选择框发生变化时
|
|||
|
/// </summary>
|
|||
|
/// <param name="sender"></param>
|
|||
|
/// <param name="e"></param>
|
|||
|
private void OnSelectionChanged(object? sender, SelectionChangedEventArgs e)
|
|||
|
{
|
|||
|
if (sender is ComboBox { IsDropDownOpen: true } comboBox)
|
|||
|
{
|
|||
|
var property = comboBox.Name;
|
|||
|
var value = comboBox.SelectedIndex;
|
|||
|
ViewModel.UpdateCameraParams(property, value);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 当输入框发生变化时
|
|||
|
/// </summary>
|
|||
|
/// <param name="sender"></param>
|
|||
|
/// <param name="e"></param>
|
|||
|
private void OnNumericValueChanged(object? sender, RoutedEventArgs e)
|
|||
|
{
|
|||
|
if (sender is NumericUpDown { IsKeyboardFocusWithin: true } numeric)
|
|||
|
{
|
|||
|
var property = numeric.Name;
|
|||
|
var value = numeric.Value;
|
|||
|
ViewModel.UpdateCameraParams(property, value);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 当滑动条发生变化时
|
|||
|
/// </summary>
|
|||
|
/// <param name="sender"></param>
|
|||
|
/// <param name="e"></param>
|
|||
|
private void OnSliderValueChanged(object? sender, RoutedEventArgs e)
|
|||
|
{
|
|||
|
if (sender is Slider { IsFocused: true } slider)
|
|||
|
{
|
|||
|
var property = slider.Name;
|
|||
|
var value = slider.Value;
|
|||
|
ViewModel.UpdateCameraParams(property, value);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 当开关发生变化时
|
|||
|
/// </summary>
|
|||
|
/// <param name="sender"></param>
|
|||
|
/// <param name="e"></param>
|
|||
|
private void OnToggleSwitchChanged(object? sender, RoutedEventArgs e)
|
|||
|
{
|
|||
|
if (sender is ToggleButton { IsFocused: true } toggleButton)
|
|||
|
{
|
|||
|
var property = toggleButton.Name;
|
|||
|
var value = toggleButton.IsChecked;
|
|||
|
ViewModel.UpdateCameraParams(property, value);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|