2026-01-26 14:51:28 +09:00

287 lines
14 KiB
C#

using Aurora.Api;
using Aurora.View;
using Hermes.Functional;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Media;
using VisionCommon;
namespace VisionLight {
/// <summary>
/// Interaction logic for UCLightMainView.xaml
/// </summary>
public partial class UCLightMainView : UserControl {
private LightViewUtils _lightUtils;
private LightBase _lightDev;
private LightConfig _lightDevConfig;
private System.Type _lightDevType;
private SolidColorBrush _itemBgColor = new SolidColorBrush(Color.FromArgb(100, 230, 230, 230));
private SolidColorBrush _resultBorderBgColor = new SolidColorBrush(Colors.DarkOliveGreen);
private SolidColorBrush _resultTextFg1Color = new SolidColorBrush(Colors.DarkOliveGreen);
private SolidColorBrush _resultTextFg2Color = new SolidColorBrush(Colors.DarkMagenta);
private SolidColorBrush _resultTextFg3Color = new SolidColorBrush(Colors.DarkSalmon);
private SolidColorBrush _resultTextFgErrorColor = new SolidColorBrush(Colors.Red);
private SolidColorBrush _resultLabelFgColor = new SolidColorBrush(Colors.WhiteSmoke);
private const string RESULT = "Result";
public UCLightMainView(Device device) {
InitializeComponent();
_lightDev = device as LightBase;
if (_lightDev != null) {
_lightDevConfig = VisionEnv.AuroraEnv.DeviceManager.GetDeviceConfig(_lightDev.DeviceId) as LightConfig;
_lightUtils = new LightViewUtils();
_lightDevType = _lightUtils.GetLightDevType(_lightDev);
}
else {
MessageUtil.CreateAndShowMessageDialog("Error", "Device is Null");
}
}
#region UI Methods
private void LoadApiItems() {
MainApiItemsControl.Items.Clear(); // Clear previous items
CustomApiItemsControl.Items.Clear(); // Clear previous items
if (_lightDevType != null) {
var mainMethods = _lightUtils.GetMainPublicMethodsWithParameters(_lightDevType);
var customMethods = _lightUtils.GetCustomPublicMethodsWithParameters(_lightDevType);
AllocControlsInItemsControl(MainApiItemsControl, mainMethods);
AllocControlsInItemsControl(CustomApiItemsControl, customMethods);
}
}
private void LightMainView_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e) {
if (e.NewValue is bool isVisibile && IsVisible == true) {
LoadApiItems();
}
}
private void MakeParameter(ParameterInfo[] parameters, Panel methodPanel) {
foreach (var parameter in parameters) {
var paramNameTextBlock = new TextBlock { Text = parameter.Name + ":", MinWidth = 100 };
methodPanel.Children.Add(paramNameTextBlock);
UIElement paramObject = new TextBox();
if (parameter.ParameterType == typeof(int) || parameter.ParameterType == typeof(double) || parameter.ParameterType == typeof(decimal)) {
paramObject = new TextBox { Width = 50, Height = 30, Tag = parameter, Text = GetInitValue(parameter) };
}
else if (parameter.ParameterType == typeof(string)) {
paramObject = new TextBox { Width = 50, Height = 30, Tag = parameter, Text = GetInitValue(parameter) };
}
else if (parameter.ParameterType == typeof(bool)) {
paramObject = new ToggleButton { Width = 50, Height = 30, Tag = parameter, Content = "False", Margin = new Thickness(5) };
(paramObject as ToggleButton).Checked += (s, e) => (paramObject as ToggleButton).Content = "True";
(paramObject as ToggleButton).Unchecked += (s, e) => (paramObject as ToggleButton).Content = "False";
}
else if (parameter.ParameterType.IsEnum) {
paramObject = new ComboBox { MinWidth= 120, Height = 30, Tag = parameter, ItemsSource = Enum.GetNames(parameter.ParameterType).ToList(),
SelectedIndex = 0, Margin = new Thickness(5) };
}
methodPanel.Children.Add(paramObject);
}
}
private (StackPanel panel, TextBlock textBlock) MakeResultControl(MethodInfo method) {
var resultPanel = new StackPanel() { Orientation = Orientation.Horizontal, HorizontalAlignment = HorizontalAlignment.Right };
// Result UI
var resultBorder = new Border() { Background = _resultBorderBgColor, Margin = new Thickness(5), Padding = new Thickness(2), Height = 30, Width = 100, CornerRadius = new CornerRadius(8) };
var resultLabel = new Label { Content = RESULT, HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center, FontWeight = FontWeights.Bold, Foreground = _resultLabelFgColor };
resultBorder.Child = resultLabel;
// Result Values
var resultTextBlock = new TextBlock {
TextAlignment = TextAlignment.Right,
Foreground = _resultTextFg1Color,
HorizontalAlignment = HorizontalAlignment.Right,
Margin = new Thickness(0, 0, 20, 0),
Text = method.ReturnType == typeof(void) ? "(void) " + RESULT : RESULT
};
resultPanel.Children.Add(resultTextBlock);
resultPanel.Children.Add(resultBorder);
return (resultPanel, resultTextBlock);
}
private void AllocControlsInItemsControl(ItemsControl itemsControl, List<(MethodInfo, ParameterInfo[])> methods) {
foreach (var (method, parameters) in methods) {
var border = new Border() { Background = _itemBgColor, Margin = new Thickness(5), Padding = new Thickness(2), MinHeight = 40, CornerRadius = new CornerRadius(8) };
var methodPanel = new DockPanel();
// API 호출 Button 추가
var button = new Button {
Content = method.Name,
Tag = (_lightDevType, method),
MinWidth = 120,
Height = 30,
FontWeight = FontWeights.SemiBold,
Margin = new Thickness(5),
};
methodPanel.Children.Add(button);
// 매개변수 이름과 입력 필드 추가
MakeParameter(parameters, methodPanel);
// Result 관련 출력 필드 추가
var resultControls = MakeResultControl(method);
button.Click += (s, e) => Button_Click(s, e, parameters, resultControls.textBlock);
methodPanel.Children.Add(resultControls.panel);
border.Child = methodPanel;
// 그룹박스에 할당.
itemsControl.Items.Add(border);
}
}
#endregion
#region Alloc Params Methods
private string GetInitValue(ParameterInfo paramInfo) {
if (paramInfo == null) { return string.Empty; }
if (paramInfo.ParameterType == typeof(int) &&
(paramInfo.Name.ToLower().Equals("channel") || paramInfo.Name.ToLower().Equals("ch") || paramInfo.Name.ToLower().Equals("channel"))) {
return _lightDevConfig?.Channels.Min.ToString();
}
else if (paramInfo.ParameterType == typeof(int) &&
(paramInfo.Name.ToLower().Equals("level") || paramInfo.Name.ToLower().Equals("brightness") || paramInfo.Name.ToLower().Equals("bright"))) {
return _lightDevConfig?.DimRange.Min.ToString();
}
else if (paramInfo.ParameterType == typeof(int) || paramInfo.ParameterType == typeof(double) || paramInfo.ParameterType == typeof(decimal)) {
return 0.ToString();
}
else if(paramInfo.ParameterType.IsEnum) {
return Enum.GetNames(paramInfo.ParameterType).ToList().FirstOrDefault()?.ToString() ?? "";
}
else {
return string.Empty;
}
}
private SolidColorBrush GetNextSolidBrush(Brush Colorbrush) {
if (Colorbrush is SolidColorBrush brush) {
return brush.Color == _resultTextFg1Color.Color ? _resultTextFg2Color :
brush.Color == _resultTextFg2Color.Color ? _resultTextFg3Color :
brush.Color == _resultTextFg3Color.Color ? _resultTextFg1Color : _resultTextFg1Color; }
return _resultTextFg1Color;
}
#endregion
#region Excute Method
private void Button_Click(object sender, RoutedEventArgs e, ParameterInfo[] parameters, TextBlock resultTextBlock) {
var button = sender as Button;
var (lightType, method) = ((System.Type, MethodInfo))button.Tag;
try {
// 매개변수 값 가져오기
var parameterValues = new object[parameters.Length];
int i = 0;
foreach (var item in ((DockPanel)button.Parent).Children) {
if(item is Button || item is StackPanel || item is TextBlock) {
continue; // parameter type으로 사용하지 않는 것들.
}
if (item is TextBox textBox) {
var value = Convert.ChangeType(textBox.Text, parameters[i].ParameterType);
parameterValues[i] = value;
i++;
}
else if (item is ToggleButton toggleBtn) {
var value = Convert.ChangeType(toggleBtn.IsChecked, parameters[i].ParameterType);
parameterValues[i] = value;
i++;
}
else if (item is ComboBox comboBox) {
object value = new object();
if (parameters[i].ParameterType.IsEnum) {
value = Enum.Parse(parameters[i].ParameterType, comboBox.SelectedItem.ToString());
}
else {
value = Convert.ChangeType(comboBox.SelectedItem, parameters[i].ParameterType);
}
parameterValues[i] = value;
i++;
}
}
// 메서드 호출 및 결과 처리
var result = method.Invoke(_lightDev, parameterValues);
if (result != null) {
resultTextBlock.Text = $"{result}";
resultTextBlock.Foreground = GetNextSolidBrush(resultTextBlock.Foreground);
}
}
catch {
resultTextBlock.Text = $"Visualstudio Code Error";
resultTextBlock.Foreground = _resultTextFgErrorColor;
}
}
#endregion
}
#region utils
public class LightViewUtils {
public System.Type GetLightDevType(LightBase lightDevice) {
System.Type lightObjType = default(System.Type);
LightModelDef.LightModels.TryGetValue((VisionEnv.AuroraEnv.DeviceManager.GetDeviceConfig(lightDevice.DeviceId) as LightConfig).LightModel, out lightObjType);
return lightObjType;
}
public List<(MethodInfo Method, ParameterInfo[] Parameters)> GetCustomPublicMethodsWithParameters(System.Type lightType) {
// 주어진 타입의 public 메서드와 매개변수 정보를 가져옵니다.
return lightType.GetMethods(BindingFlags.Public | BindingFlags.Instance)
.Where(method => method.DeclaringType == lightType &&
// Get Set 함수 제거
!method.Name.StartsWith("get_") &&
!method.Name.StartsWith("set_"))
.Select(method => (method, method.GetParameters()))
.ToList();
}
public List<(MethodInfo Method, ParameterInfo[] Parameters)> GetMainPublicMethodsWithParameters(System.Type lightType) {
// 주어진 타입의 public 메서드와 매개변수 정보를 가져옵니다.
return lightType.GetMethods(BindingFlags.Public | BindingFlags.Instance)
.Where(method =>
method.DeclaringType == typeof(LightBase) &&
// Get Set 함수 제거
!method.Name.StartsWith("get_") &&
!method.Name.StartsWith("set_"))
.Select(method => (method, method.GetParameters()))
.ToList();
}
}
public class BoolVisibleCollapseConverter : IValueConverter {
public object Convert(object value, System.Type targetType, object parameter, CultureInfo culture) {
if (value != null && value is bool IsVisible) {
if (IsVisible) { return Visibility.Visible; }
else { return Visibility.Collapsed; }
}
else {
return Visibility.Collapsed;
}
}
public object ConvertBack(object value, System.Type targetType, object parameter, CultureInfo culture) {
return null;
// throw new NotImplementedException();
}
}
public class IsExistItemConverter : IValueConverter {
public object Convert(object value, System.Type targetType, object parameter, CultureInfo culture) {
if (value != null && value is int count) {
return count > 0 ? true : false;
}
return false;
}
public object ConvertBack(object value, System.Type targetType, object parameter, CultureInfo culture) {
return null;
// throw new NotImplementedException();
}
}
#endregion
}