/* * 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 { /// /// Interaction logic for UCTabControl.xaml /// 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 TabList; private int _TabIndex = 0; private bool _EnableMenuChangebyUI = false; private ICommand _OnSelectionChanged; public UCTabControl(IAuroraEnvironment aurora, List 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(); } }