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 { /// /// Interaction logic for UCLightMainView.xaml /// 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 }