/*
* 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() {
}
}
}