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.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<DetachedElement> _detachedElements;
private IResolutionService _resolutionService;
private INotificationProvider _notificationProvider;
public RelayCommand<FrameworkElement> DetachToWindowCommand { get; private set; }
public RelayCommand<FrameworkElement> AttachFromWindowCommand { get; private set; }
public DefaultWindowsManager(IResolutionService resolutionService, INotificationProvider notificationProvider)
{
_resolutionService = resolutionService;
_notificationProvider = notificationProvider;
_detachedElements = new List<DetachedElement>();
DetachToWindowCommand = new RelayCommand<FrameworkElement>(DetachToWindow);
AttachFromWindowCommand = new RelayCommand<FrameworkElement>(AttachFromWindow);
}
public void DetachToWindow(FrameworkElement element)
{
ChildWindow window = new ChildWindow();
ChildWindowVM vm = new ChildWindowVM();
vm.NotificationProvider = new DefaultNotificationProvider();
window.DataContext = vm;
window.Title = "Tango FSE";
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);
}
}
}
}