using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using Tango.Core.Commands; using Tango.FSE.Common; using Tango.FSE.Common.Build; using Tango.FSE.Common.Notifications; using Tango.FSE.Common.Resolution; using Tango.FSE.Common.WindowsManager; using Tango.FSE.UI.Notifications; using Tango.FSE.UI.Resolution; using Tango.SharedUI.Effects; using Tango.SharedUI.Helpers; namespace Tango.FSE.UI.WindowsManager { public class DefaultWindowsManager : IWindowsManager { private class DetachedElement { public ChildWindow Window { get; set; } public FrameworkElement Element { get; set; } public FrameworkElement Parent { get; set; } public FrameworkElement PlaceHolder { get; set; } } private List _detachedElements; private IResolutionService _resolutionService; private INotificationProvider _notificationProvider; private IBuildProvider _buildProvider; public RelayCommand DetachToWindowCommand { get; private set; } public RelayCommand AttachFromWindowCommand { get; private set; } public DefaultWindowsManager(IResolutionService resolutionService, INotificationProvider notificationProvider, IBuildProvider buildProvider) { _resolutionService = resolutionService; _notificationProvider = notificationProvider; _buildProvider = buildProvider; _detachedElements = new List(); DetachToWindowCommand = new RelayCommand(DetachToWindow); AttachFromWindowCommand = new RelayCommand(AttachFromWindow); } public void DetachToWindow(FrameworkElement element) { ChildWindow window = new ChildWindow(); ChildWindowVM vm = new ChildWindowVM(); vm.NotificationProvider = new DefaultNotificationProvider(); window.DataContext = vm; window.Title = _buildProvider.BuildName; var title = WindowsManagerHelper.GetWindowTitle(element); if (title != null) { window.Title += " - " + title; } var oldDataContext = element.DataContext; DetachedElement detachedElement = new DetachedElement(); detachedElement.Window = window; detachedElement.Element = element; detachedElement.Parent = element.Parent as FrameworkElement; if (WindowsManagerHelper.GetPreservePlaceHolder(element)) { PlaceHolder holder = new PlaceHolder(); detachedElement.PlaceHolder = holder; var snapshot = element.TakeSnapshot(); Image img = new Image(); img.Stretch = System.Windows.Media.Stretch.Uniform; img.Source = snapshot; img.Effect = new DisplaySettingEffect() { SaturationLevel = 0 }; holder.InnerContent = img; //holder.Width = element.ActualWidth; //holder.Height = element.ActualHeight; UIHelper.RemoveChild(element.Parent, element); UIHelper.AddChild(detachedElement.Parent, holder); } else { UIHelper.RemoveChild(element.Parent, element); } window.contentBorder.Child = element; window.Owner = Application.Current.MainWindow; window.ShowInTaskbar = true; window.ShowActivated = true; _detachedElements.Add(detachedElement); window.Closed += (_, __) => { AttachFromWindow(element); }; if (oldDataContext is FSEViewModel) { if (!WindowsManagerHelper.GetDisableResolutionServiceInjection(element)) { (oldDataContext as FSEViewModel).ResolutionService = new DefaultResolutionService(window); } (oldDataContext as FSEViewModel).NotificationProvider = vm.NotificationProvider; } //Apply custom settings... double? startWidth = WindowsManagerHelper.GetStartWidth(element); double? startHeight = WindowsManagerHelper.GetStartHeight(element); double? minWidth = WindowsManagerHelper.GetMinWidth(element); double? minHeight = WindowsManagerHelper.GetMinHeight(element); bool lockAspectRatio = WindowsManagerHelper.GetLockAspectRatio(element); if (startWidth != null) window.Width = startWidth.Value; if (startHeight != null) window.Height = startHeight.Value; if (minWidth != null) window.MinWidth = minWidth.Value; if (minHeight != null) window.MinHeight = minHeight.Value; window.btnMaximize.IsEnabled = !WindowsManagerHelper.GetDisableMaximize(element); if (lockAspectRatio && startWidth != null && startHeight != null) { double ratio = startWidth.Value / startHeight.Value; window.Tag = false; window.SizeChanged += (_, e) => { if (!(bool)window.Tag) { //window.Tag = true; //if (e.NewSize.Height != e.PreviousSize.Height) //{ window.Width = window.Height * ratio; //} //else if (e.NewSize.Width != e.PreviousSize.Width) //{ // window.Height = window.Width / ratio; //} //window.Tag = false; } }; } window.Show(); if (element.DataContext != oldDataContext) { element.DataContext = oldDataContext; } WindowsManagerHelper.SetIsDetached(element, true); element.RaiseEvent(new RoutedEventArgs(WindowsManagerHelper.DetachedEvent, element)); } public void AttachFromWindow(FrameworkElement element) { var detachedElement = _detachedElements.SingleOrDefault(x => x.Element == element); if (detachedElement != null) { UIHelper.RemoveChild(detachedElement.Window.contentBorder, detachedElement.Element); detachedElement.Window.Close(); if (element.DataContext is FSEViewModel) { if (!WindowsManagerHelper.GetDisableResolutionServiceInjection(element)) { (element.DataContext as FSEViewModel).ResolutionService = _resolutionService; } (element.DataContext as FSEViewModel).NotificationProvider = _notificationProvider; } if (detachedElement.PlaceHolder != null) { UIHelper.RemoveChild(detachedElement.Parent, detachedElement.PlaceHolder); } UIHelper.AddChild(detachedElement.Parent, detachedElement.Element); _detachedElements.Remove(detachedElement); WindowsManagerHelper.SetIsDetached(element, false); element.RaiseEvent(new RoutedEventArgs(WindowsManagerHelper.AttachedEvent, element)); } } public void CloseAll() { foreach (var detachedElement in _detachedElements.ToList()) { AttachFromWindow(detachedElement.Element); } } } }