|
|
|
@ -1,4 +1,5 @@ |
|
|
|
using System; |
|
|
|
using System.Collections.Generic; |
|
|
|
using System.ComponentModel; |
|
|
|
using System.Linq; |
|
|
|
using System.Reactive.Linq; |
|
|
|
@ -68,6 +69,8 @@ namespace Avalonia.Controls |
|
|
|
/// </summary>
|
|
|
|
public class Window : WindowBase, IStyleable, IFocusScope, ILayoutRoot |
|
|
|
{ |
|
|
|
private List<Window> _children = new List<Window>(); |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Defines the <see cref="SizeToContent"/> property.
|
|
|
|
/// </summary>
|
|
|
|
@ -131,7 +134,7 @@ namespace Avalonia.Controls |
|
|
|
/// </summary>
|
|
|
|
public static readonly RoutedEvent WindowClosedEvent = |
|
|
|
RoutedEvent.Register<Window, RoutedEventArgs>("WindowClosed", RoutingStrategies.Direct); |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Routed event that can be used for global tracking of opening windows
|
|
|
|
/// </summary>
|
|
|
|
@ -183,6 +186,7 @@ namespace Avalonia.Controls |
|
|
|
: base(impl) |
|
|
|
{ |
|
|
|
impl.Closing = HandleClosing; |
|
|
|
impl.GotInputWhenDisabled = OnGotInputWhenDisabled; |
|
|
|
impl.WindowStateChanged = HandleWindowStateChanged; |
|
|
|
_maxPlatformClientSize = PlatformImpl?.MaxClientSize ?? default(Size); |
|
|
|
this.GetObservable(ClientSizeProperty).Skip(1).Subscribe(x => PlatformImpl?.Resize(x)); |
|
|
|
@ -302,7 +306,7 @@ namespace Avalonia.Controls |
|
|
|
PlatformImpl?.Move(value); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Starts moving a window with left button being held. Should be called from left mouse button press event handler
|
|
|
|
/// </summary>
|
|
|
|
@ -323,7 +327,7 @@ namespace Avalonia.Controls |
|
|
|
/// <summary>
|
|
|
|
/// Fired before a window is closed.
|
|
|
|
/// </summary>
|
|
|
|
public event EventHandler<CancelEventArgs> Closing; |
|
|
|
public event EventHandler<CancelEventArgs> Closing; |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Closes the window.
|
|
|
|
@ -365,19 +369,59 @@ namespace Avalonia.Controls |
|
|
|
{ |
|
|
|
if (close) |
|
|
|
{ |
|
|
|
PlatformImpl?.Dispose(); |
|
|
|
CloseInternal(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private void CloseInternal() |
|
|
|
{ |
|
|
|
foreach (var child in _children.ToList()) |
|
|
|
{ |
|
|
|
// if we HandleClosing() before then there will be no children.
|
|
|
|
child.CloseInternal(); |
|
|
|
} |
|
|
|
|
|
|
|
if (Owner is Window owner) |
|
|
|
{ |
|
|
|
owner.RemoveChild(this); |
|
|
|
} |
|
|
|
|
|
|
|
Owner = null; |
|
|
|
|
|
|
|
PlatformImpl?.Dispose(); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Handles a closing notification from <see cref="IWindowImpl.Closing"/>.
|
|
|
|
/// </summary>
|
|
|
|
protected virtual bool HandleClosing() |
|
|
|
{ |
|
|
|
var args = new CancelEventArgs(); |
|
|
|
OnClosing(args); |
|
|
|
return args.Cancel; |
|
|
|
bool canClose = true; |
|
|
|
|
|
|
|
foreach (var child in _children.ToList()) |
|
|
|
{ |
|
|
|
if (!child.HandleClosing()) |
|
|
|
{ |
|
|
|
child.CloseInternal(); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
canClose = false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (canClose) |
|
|
|
{ |
|
|
|
var args = new CancelEventArgs(); |
|
|
|
OnClosing(args); |
|
|
|
|
|
|
|
return args.Cancel; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
return !canClose; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
protected virtual void HandleWindowStateChanged(WindowState state) |
|
|
|
@ -407,6 +451,14 @@ namespace Avalonia.Controls |
|
|
|
using (BeginAutoSizing()) |
|
|
|
{ |
|
|
|
Renderer?.Stop(); |
|
|
|
|
|
|
|
if (Owner is Window owner) |
|
|
|
{ |
|
|
|
owner.RemoveChild(this); |
|
|
|
} |
|
|
|
|
|
|
|
Owner = null; |
|
|
|
|
|
|
|
PlatformImpl?.Hide(); |
|
|
|
} |
|
|
|
|
|
|
|
@ -519,7 +571,10 @@ namespace Avalonia.Controls |
|
|
|
|
|
|
|
using (BeginAutoSizing()) |
|
|
|
{ |
|
|
|
PlatformImpl?.ShowDialog(owner.PlatformImpl); |
|
|
|
PlatformImpl.SetParent(owner.PlatformImpl); |
|
|
|
Owner = owner; |
|
|
|
owner.AddChild(this); |
|
|
|
PlatformImpl?.Show(); |
|
|
|
|
|
|
|
Renderer?.Start(); |
|
|
|
|
|
|
|
@ -541,6 +596,37 @@ namespace Avalonia.Controls |
|
|
|
return result.Task; |
|
|
|
} |
|
|
|
|
|
|
|
private void UpdateEnabled() |
|
|
|
{ |
|
|
|
PlatformImpl.SetEnabled(_children.Count == 0); |
|
|
|
} |
|
|
|
|
|
|
|
private void AddChild(Window window) |
|
|
|
{ |
|
|
|
_children.Add(window); |
|
|
|
UpdateEnabled(); |
|
|
|
} |
|
|
|
|
|
|
|
private void RemoveChild(Window window) |
|
|
|
{ |
|
|
|
_children.Remove(window); |
|
|
|
UpdateEnabled(); |
|
|
|
} |
|
|
|
|
|
|
|
private void OnGotInputWhenDisabled() |
|
|
|
{ |
|
|
|
var firstChild = _children.FirstOrDefault(); |
|
|
|
|
|
|
|
if (firstChild != null) |
|
|
|
{ |
|
|
|
firstChild.OnGotInputWhenDisabled(); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
Activate(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private void SetWindowStartupLocation(IWindowBaseImpl owner = null) |
|
|
|
{ |
|
|
|
var scaling = owner?.Scaling ?? PlatformImpl?.Scaling ?? 1; |
|
|
|
@ -631,6 +717,13 @@ namespace Avalonia.Controls |
|
|
|
RaiseEvent(new RoutedEventArgs(WindowClosedEvent)); |
|
|
|
|
|
|
|
base.HandleClosed(); |
|
|
|
|
|
|
|
if (Owner is Window owner) |
|
|
|
{ |
|
|
|
owner.RemoveChild(this); |
|
|
|
} |
|
|
|
|
|
|
|
Owner = null; |
|
|
|
} |
|
|
|
|
|
|
|
/// <inheritdoc/>
|
|
|
|
|