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

239 lines
8.8 KiB
C#

/*
* Copyright (c) 2022 LG Electronics Inc.
* SPDX-License-Identifier: LicenseRef-LGE-Proprietary
*/
using Aurora;
using Aurora.Api;
using Aurora.View;
using AuroraUIComponent.Sequence;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reactive.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace AuroraUIComponent.UserControls.TabView
{
/// <summary>
/// Interaction logic for UCTabControl.xaml
/// </summary>
public partial class UCTabControl : UserControl
{
readonly Aurora.Api.Logger Log = new Aurora.Api.Logger("UCTabControl");
IAuroraEnvironment _AuroraEnv;
public class TabItemEx : NotifyPropertyChangedBase
{
private string _Title = "(Unknown)";
public string Title { get => _Title; set => SetProperty(ref _Title, value); }
private FrameworkElement _Content;
public FrameworkElement Content { get => _Content; set => SetProperty(ref _Content, value); }
private Visibility _TabVisible;
public Visibility TabVisible { get => _TabVisible; set => SetProperty(ref _TabVisible, value); }
private bool _IsEnabled = true;
public bool IsEnabled { get => _IsEnabled; set => SetProperty(ref _IsEnabled, value); }
public TabItemEx(string title, FrameworkElement content, bool isVisible = true, bool isEnabled = true)
{
Title = title;
Content = content;
TabVisible = isVisible ? Visibility.Visible : Visibility.Collapsed;
IsEnabled = isEnabled;
}
}
List<TabItemEx> TabList;
private int _TabIndex = 0;
private bool _EnableMenuChangebyUI = false;
private ICommand _OnSelectionChanged;
public UCTabControl(IAuroraEnvironment aurora, List<TabItemEx> tabList, bool enableMenuChangebyUI = true, ICommand onSelectionChanged = null)
{
InitializeComponent();
_AuroraEnv = aurora;
TabList = tabList;
_TabIndex = 0;
_EnableMenuChangebyUI = enableMenuChangebyUI;
_OnSelectionChanged = onSelectionChanged;
var langTokens = Application.Current.Resources["langTokens"] as LangTokens;
foreach (var item in TabList) {
TabItem tab = new TabItem();
Binding bindingTitle = new Binding($"[{item.Title}]");
bindingTitle.Source = langTokens;
bindingTitle.Mode = BindingMode.OneWay;
tab.SetBinding(TabItem.HeaderProperty, bindingTitle);
Binding bindingVisibility = new Binding("TabVisible");
bindingVisibility.Source = item;
//bindingVisibility.Converter = (IValueConverter)this.Resources["convVisibleCollapsed"];
bindingVisibility.Mode = BindingMode.OneWay;
tab.SetBinding(TabItem.VisibilityProperty, bindingVisibility);
Binding bindingIsEnabled = new Binding("IsEnabled");
bindingIsEnabled.Source = item;
bindingIsEnabled.Mode = BindingMode.OneWay;
tab.SetBinding(TabItem.IsEnabledProperty, bindingIsEnabled);
Binding bindingContent = new Binding("Content");
bindingContent.Source = item;
bindingContent.Mode = BindingMode.OneWay;
tab.SetBinding(TabItem.ContentProperty, bindingContent);
//tab.Content = item.Content;
tabParent.Items.Add(tab);
}
_AuroraEnv.EventObservable.AsObservable(ScreenShotSequence.SYS_REQ_MENU_CHANGE_EXT).Select(x => x.Param as string).Subscribe(y => ChangeMenu(y));
}
public void ChangeMenu(string title)
{
if (TabList.Any(x => x.Title == title)) {
Log.D($"ChangeMenu : {ScreenShotSequence.SYS_REQ_MENU_CHANGE_EXT} / {title}");
var tab = TabList.FirstOrDefault(x => x.Title == title);
ChangeMenuInternal(TabList.IndexOf(tab));
}
}
public void ChangeMenu(int tabIndex)
{
ChangeMenuInternal(tabIndex);
}
private void ChangeMenuInternal(int tabIndex)
{
Application.Current.Dispatcher.Invoke(delegate {
if (tabIndex >= 0 && TabList.Count > tabIndex && tabParent.SelectedIndex != tabIndex) {
tabParent.SelectedIndex = tabIndex;
}
});
}
public void ChangeMenuVisibility(int tabIndex, Visibility visibility)
{
Application.Current.Dispatcher.Invoke(delegate {
if (tabParent.Items.Count > tabIndex) {
(tabParent.Items[tabIndex] as TabItem).Visibility = visibility;
}
});
}
public void ChangeMenuVisibility(string title, bool isVisible)
{
Application.Current.Dispatcher.Invoke(delegate {
//foreach (var tabItem in tabParent.Items) {
foreach (var tabItem in TabList) {
if (tabItem.Title == title) {
tabItem.TabVisible = isVisible ? Visibility.Visible : Visibility.Collapsed;
}
}
});
}
public void ChangeMenuEnable(string title, bool isEnabled)
{
Application.Current.Dispatcher.Invoke(delegate {
//foreach (var tabItem in tabParent.Items) {
foreach (var tabItem in TabList) {
if (tabItem.Title == title) {
tabItem.IsEnabled = isEnabled;
}
}
});
}
private void UserControl_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if (_IsChangingTab)
return;
if (!IsVisible) {
// ITabControl (CanClose) Interface 체크
if (tabParent.SelectedIndex >= 0 && tabParent.SelectedIndex < TabList.Count) {
if ((TabList[tabParent.SelectedIndex].Content.DataContext is ITabContent tabContent)) {
_IsChangingTab = true;
if (tabContent.CanClose()) {
// continue
}
_IsChangingTab = false;
}
}
}
}
private bool _IsChangingTab = false;
private void tabParent_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (_IsChangingTab)
return;
if (e.Source is TabControl tabControl) {
// Before
TabItem _CurrentTab = e.RemovedItems.Count > 0 ? e.RemovedItems[0] as TabItem : null;
// After (새로 선택된 Tab) : 현재 불필요
//TabItem _NewTab = e.AddedItems.Count > 0 ? e.AddedItems[0] as TabItem : null;
// Perform your logic here
if (!_EnableMenuChangebyUI) {
// UI로 Enable 허용하지 않을 경우 이전 TabIndex로 돌려놓기 (tab change 취소)
_IsChangingTab = true;
tabControl.SelectedItem = _CurrentTab;
_IsChangingTab = false;
return;
} else {
// ITabControl (CanClose) Interface 체크
if ((_CurrentTab?.Content is UserControl uc) && (uc.DataContext is ITabContent tabContent)) {
if (tabContent.CanClose()) {
// continue
} else {
// Cancel the tab change
_IsChangingTab = true;
tabControl.SelectedItem = _CurrentTab;
_IsChangingTab = false;
return;
}
}
}
}
// 로그 : 특정 탭에서 여러번 호출되는 원인 불명... 궁금...
//Log.FuncV($"Tab {_TabIndex} => {(sender as TabControl).SelectedIndex} : {((sender as TabControl).SelectedItem as TabItem)?.Header}");
_TabIndex = (sender as TabControl).SelectedIndex;
if (_OnSelectionChanged != null) {
_OnSelectionChanged.Execute(_TabIndex);
}
}
}
public interface ITabContent
{
bool CanClose();
}
}