/* * Copyright (c) 2025 LG Electronics Inc. * SPDX-License-Identifier: LicenseRef-LGE-Proprietary */ using Aurora.Api; using System; using System.Windows; using VisionCommon; using System.Windows.Controls; using System.Collections.Generic; using VisionCommonUI; using VisionCommonUI.Resources; using System.Linq; #if USE_COGNEX using CogUI; #else using MilUI; #endif namespace VisionUI.Camera { /// /// 메인 카메라 뷰 /// MainCameraView.xaml BehindCode /// public partial class MainCameraView : UserControl, IDisposable { private static Logger _Logger = new Logger("MainCameraView"); private IDisposable _EventDisposable; private Dictionary _OldFovRecipes = new Dictionary(); private bool _IsViewInitialized = false; public eDisplayType _displayType; /// /// 생성자 /// /// 디스플레이 타입 public MainCameraView(eDisplayType displayType) { _displayType = displayType; InitializeComponent(); SetObservable(); CreateView(); } /// /// 디스플레이 타입 가져오기 /// /// 디스플레이 타입 public eDisplayType GetDisplayType() { return _displayType; } private void SetObservable() { if (_EventDisposable == null) { VisionEnv.AuroraEnv.EventObservable.AsObservable(AuroraSysEvent.SYS_DEVICE_ACTIVATED). Subscribe(msg => ResetCameraView(msg)); var observable = VisionEventId.GetRecipeUpdateObservable(); _EventDisposable = observable.Subscribe(_ => RefreshView()); } } private void RefreshView() { if (HasToRefreshView()) { Application.Current.Dispatcher.BeginInvoke( new System.Action(() => { _IsViewInitialized = false; CreateView(); })); } } private bool HasToRefreshView() { try { foreach (var newFovInfo in VisionRecipeManager.GetFovInfos()) { var newFovRecipe = VisionRecipeManager.GetFovRecipe(newFovInfo); var newMainUiRecipes = newFovRecipe.MainUiRecipes; if (_OldFovRecipes.ContainsKey(newFovInfo)) { var oldMainUiRecipes = _OldFovRecipes[newFovInfo].MainUiRecipes; for (int i = 0; i < oldMainUiRecipes.Count; i++) { if (i < newMainUiRecipes.Count) { if (oldMainUiRecipes[i].FovUiPos != newMainUiRecipes[i].FovUiPos) { return true; } else if (oldMainUiRecipes[i].MainDisplayType != newMainUiRecipes[i].MainDisplayType) { return true; } } } } } } catch (Exception e) { _Logger.FuncE(e.Message); } return false; } /// /// 카메라 디바이스가 다시 Activated될 때, 메인 화면 카메라 뷰를 갱신 /// /// 이벤트 메시지 private void ResetCameraView(EventMessage msg) { if (!_IsViewInitialized) { return; } foreach (eCamId camId in VisionRecipeManager.GetCamIds(_OldFovRecipes.Values.ToList())) { if (msg.From.Equals(camId.ToString())) { foreach (FovInfo fovInfo in VisionRecipeManager.GetFovInfos(camId)) { var fovRecipe = VisionRecipeManager.GetFovRecipe(fovInfo); if (fovRecipe == null) { continue; } if (IsInDisplay(fovRecipe)) { var ltFovUiPosRow = new int(); var ltFovUiPosCol = new int(); foreach (var mainUiRecipe in fovRecipe.MainUiRecipes) { if (mainUiRecipe.MainDisplayType == _displayType) { (ltFovUiPosRow, ltFovUiPosCol) = FovRecipe.GetFovUiPosRowCol(mainUiRecipe.FovUiPos); } } Application.Current.Dispatcher.Invoke( new Action(() => { var camView = gridMainCameraView.Children.OfType().Where(child => child.GetFovInfo().Equals(fovInfo)).FirstOrDefault(); gridMainCameraView.Children.Remove(camView); camView.Dispose(); camView = IpViewManager.CreateCameraView(fovInfo, _displayType); Grid.SetRow(camView, ltFovUiPosRow); Grid.SetColumn(camView, ltFovUiPosCol); gridMainCameraView.Children.Add(camView); })); } } } } CameraViewManager.Instance.InitVisibilities(); } /// /// 현재 카메라 뷰 가져오기 /// /// 현재 카메라 뷰 public CameraView GetCurrentCameraView() { var TopCameraView = gridMainCameraView.Children.OfType().Where(child => child.Visibility == Visibility.Visible).FirstOrDefault(); return TopCameraView as CameraView; } /// /// Camera View 생성 /// CameraView를 미리 만들어 놓기 위해 프로그램 로딩시 수행 (권장) /// public void CreateView() { Application.Current.Dispatcher.BeginInvoke((Action)(() => { if (!_IsViewInitialized) { CreateViewInternal(); _IsViewInitialized = true; } })); } private bool IsInDisplay(FovRecipe fovRecipe) { bool displayCheck = false; foreach (var mainUiRecipe in fovRecipe.MainUiRecipes) { if (mainUiRecipe.MainDisplayType == _displayType) { displayCheck = true; } } return displayCheck; } private void CreateViewInternal() { try { ClearView(); AddRowColumnDefinitions(); var fovInfos = VisionRecipeManager.GetFovInfos(); if (fovInfos.Count > 0) { foreach (var fovInfo in fovInfos) { var fovRecipe = VisionRecipeManager.GetFovRecipe(fovInfo); if (fovRecipe != null) { _OldFovRecipes[fovInfo] = fovRecipe.Clone(); if (IsInDisplay(fovRecipe)) { var cameraView = IpViewManager.CreateCameraView(fovInfo, _displayType); if (fovRecipe != null && cameraView != null) { var ltFovUiPosRow = new int(); var ltFovUiPosCol = new int(); foreach (var mainUiRecipe in fovRecipe.MainUiRecipes) { if (mainUiRecipe.MainDisplayType == _displayType) { (ltFovUiPosRow, ltFovUiPosCol) = FovRecipe.GetFovUiPosRowCol(mainUiRecipe.FovUiPos); } } Grid.SetRow(cameraView, ltFovUiPosRow); Grid.SetColumn(cameraView, ltFovUiPosCol); gridMainCameraView.Children.Add(cameraView); } } } } CameraViewManager.Instance.InitVisibilities(); } else { PrintRecipeError(); } } catch (Exception e) { _Logger.FuncE(e.Message); } } private void ClearView() { foreach (UserControl camView in gridMainCameraView.Children) { IpViewManager.DisposeCameraView(camView); } gridMainCameraView.Children.Clear(); gridMainCameraView.RowDefinitions.Clear(); gridMainCameraView.ColumnDefinitions.Clear(); _OldFovRecipes.Clear(); } private void AddRowColumnDefinitions() { var rows = GetUiPosRows(); foreach (var row in rows) { gridMainCameraView.RowDefinitions.Add(new RowDefinition()); } var cols = GetUiPosCols(); foreach (var col in cols) { gridMainCameraView.ColumnDefinitions.Add(new ColumnDefinition()); } } private List GetUiPosRows() { var rows = new SortedSet(); foreach (var fovInfo in VisionRecipeManager.GetFovInfos()) { var fovRecipe = VisionRecipeManager.GetFovRecipe(fovInfo); if (fovRecipe != null) { var ltFovUiPosRow = new int(); var ltFovUiPosCol = new int(); foreach (var mainUiRecipe in fovRecipe.MainUiRecipes) { if (mainUiRecipe.MainDisplayType == _displayType) { (ltFovUiPosRow, ltFovUiPosCol) = FovRecipe.GetFovUiPosRowCol(mainUiRecipe.FovUiPos); } } if (ltFovUiPosRow != -1) { rows.Add(ltFovUiPosRow); } } } return new List(rows); } private List GetUiPosCols() { var cols = new SortedSet(); foreach (var fovInfo in VisionRecipeManager.GetFovInfos()) { var fovRecipe = VisionRecipeManager.GetFovRecipe(fovInfo); if (fovRecipe != null) { var ltFovUiPosRow = new int(); var ltFovUiPosCol = new int(); foreach (var mainUiRecipe in fovRecipe.MainUiRecipes) { if (mainUiRecipe.MainDisplayType == _displayType) { (ltFovUiPosRow, ltFovUiPosCol) = FovRecipe.GetFovUiPosRowCol(mainUiRecipe.FovUiPos); } } if (ltFovUiPosCol != -1) { cols.Add(ltFovUiPosCol); } } } return new List(cols); } /// /// 메인 카메라 연결 해제 /// /// 카메라 뷰 /// 유저컨트롤 리스트 (카메라 뷰) public List DisconnectMainCamera(UserControl camView) { List list = new List(); int row = 0; int col = 0; for (int i = 0; i < gridMainCameraView.Children.Count; i++) { var child = gridMainCameraView.Children[i]; if (child is ICameraView cview) { var ucCamView = cview as UserControl; if (ucCamView.Name == camView.Name) { row = Grid.GetRow(ucCamView); col = Grid.GetColumn(ucCamView); break; } } } foreach (var child in gridMainCameraView.Children) { if (child is ICameraView cv) { var ucCamView = cv as UserControl; int temprow = Grid.GetRow(ucCamView); int tempcol = Grid.GetColumn(ucCamView); if (row == temprow && col == tempcol) { cv.Row = row; cv.Col = col; list.Add(ucCamView); } } } foreach (var cv in list) { gridMainCameraView.Children.Remove(cv); } return list; } internal void RestoreMainCamera(List camViewList) { try { foreach (ICameraView camView in camViewList) { camView.MenuShowCamWindow.Visibility = Visibility.Visible; gridMainCameraView.Children.Add(camView as UserControl); } } catch (Exception e) { _Logger.FuncE(e.Message); } } private void PrintRecipeError() { var errMsg = string.Format(StrTokens.RecipeErrorMessage, typeof(FovRecipe).Name); gridMainCameraView.Children.Add(new UCRecipeErrorTextBlock(errMsg) { Margin = new Thickness(15) }); gridMainCameraView.VerticalAlignment = VerticalAlignment.Center; gridMainCameraView.HorizontalAlignment = HorizontalAlignment.Center; } private void UserControl_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e) { bool isVisible = (bool)e.NewValue; if (isVisible == true) { //if (!_IsViewInitialized) { // CreateView(); //} } } public void Dispose() { } } }