// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using System.Reactive.Linq;
using System.Threading.Tasks;
using Avalonia.Controls.Platform;
using Avalonia.Input;
using Avalonia.Layout;
using Avalonia.Media;
using Avalonia.Platform;
using Avalonia.Styling;
using System.Collections.Generic;
using System.Linq;
using JetBrains.Annotations;
using System.ComponentModel;
namespace Avalonia.Controls
{
///
/// Determines how a will size itself to fit its content.
///
[Flags]
public enum SizeToContent
{
///
/// The window will not automatically size itself to fit its content.
///
Manual = 0,
///
/// The window will size itself horizontally to fit its content.
///
Width = 1,
///
/// The window will size itself vertically to fit its content.
///
Height = 2,
///
/// The window will size itself horizontally and vertically to fit its content.
///
WidthAndHeight = 3,
}
///
/// A top-level window.
///
public class Window : WindowBase, IStyleable, IFocusScope, ILayoutRoot, INameScope
{
/// Defines the property.
///
public static readonly StyledProperty SizeToContentProperty =
AvaloniaProperty.Register(nameof(SizeToContent));
///
/// Enables or disables system window decorations (title bar, buttons, etc)
///
public static readonly StyledProperty HasSystemDecorationsProperty =
AvaloniaProperty.Register(nameof(HasSystemDecorations), true);
///
/// Enables or disables the taskbar icon
///
public static readonly StyledProperty ShowInTaskbarProperty =
AvaloniaProperty.Register(nameof(ShowInTaskbar), true);
///
/// Represents the current window state (normal, minimized, maximized)
///
public static readonly StyledProperty WindowStateProperty =
AvaloniaProperty.Register(nameof(WindowState));
///
/// Defines the property.
///
public static readonly StyledProperty TitleProperty =
AvaloniaProperty.Register(nameof(Title), "Window");
///
/// Defines the property.
///
public static readonly StyledProperty IconProperty =
AvaloniaProperty.Register(nameof(Icon));
///
/// Defines the proeprty.
///
public static readonly DirectProperty WindowStartupLocationProperty =
AvaloniaProperty.RegisterDirect(
nameof(WindowStartupLocation),
o => o.WindowStartupLocation,
(o, v) => o.WindowStartupLocation = v);
public static readonly StyledProperty CanResizeProperty =
AvaloniaProperty.Register(nameof(CanResize), true);
private readonly NameScope _nameScope = new NameScope();
private object _dialogResult;
private readonly Size _maxPlatformClientSize;
private WindowStartupLocation _windowStartupLoction;
///
/// Initializes static members of the class.
///
static Window()
{
BackgroundProperty.OverrideDefaultValue(typeof(Window), Brushes.White);
TitleProperty.Changed.AddClassHandler((s, e) => s.PlatformImpl?.SetTitle((string)e.NewValue));
HasSystemDecorationsProperty.Changed.AddClassHandler(
(s, e) => s.PlatformImpl?.SetSystemDecorations((bool)e.NewValue));
ShowInTaskbarProperty.Changed.AddClassHandler((w, e) => w.PlatformImpl?.ShowTaskbarIcon((bool)e.NewValue));
IconProperty.Changed.AddClassHandler((s, e) => s.PlatformImpl?.SetIcon(((WindowIcon)e.NewValue).PlatformImpl));
CanResizeProperty.Changed.AddClassHandler((w, e) => w.PlatformImpl?.CanResize((bool)e.NewValue));
WindowStateProperty.Changed.AddClassHandler(
(w, e) => { if (w.PlatformImpl != null) w.PlatformImpl.WindowState = (WindowState)e.NewValue; });
}
///
/// Initializes a new instance of the class.
///
public Window()
: this(PlatformManager.CreateWindow())
{
}
///
/// Initializes a new instance of the class.
///
/// The window implementation.
public Window(IWindowImpl impl)
: base(impl)
{
impl.Closing = HandleClosing;
impl.WindowStateChanged = HandleWindowStateChanged;
_maxPlatformClientSize = PlatformImpl?.MaxClientSize ?? default(Size);
Screens = new Screens(PlatformImpl?.Screen);
}
///
event EventHandler INameScope.Registered
{
add { _nameScope.Registered += value; }
remove { _nameScope.Registered -= value; }
}
///
event EventHandler INameScope.Unregistered
{
add { _nameScope.Unregistered += value; }
remove { _nameScope.Unregistered -= value; }
}
public Screens Screens { get; private set; }
///
/// Gets the platform-specific window implementation.
///
[CanBeNull]
public new IWindowImpl PlatformImpl => (IWindowImpl)base.PlatformImpl;
///
/// Gets or sets a value indicating how the window will size itself to fit its content.
///
public SizeToContent SizeToContent
{
get { return GetValue(SizeToContentProperty); }
set { SetValue(SizeToContentProperty, value); }
}
///
/// Gets or sets the title of the window.
///
public string Title
{
get { return GetValue(TitleProperty); }
set { SetValue(TitleProperty, value); }
}
///
/// Enables or disables system window decorations (title bar, buttons, etc)
///
///
public bool HasSystemDecorations
{
get { return GetValue(HasSystemDecorationsProperty); }
set { SetValue(HasSystemDecorationsProperty, value); }
}
///
/// Enables or disables the taskbar icon
///
///
public bool ShowInTaskbar
{
get { return GetValue(ShowInTaskbarProperty); }
set { SetValue(ShowInTaskbarProperty, value); }
}
///
/// Gets or sets the minimized/maximized state of the window.
///
public WindowState WindowState
{
get { return GetValue(WindowStateProperty); }
set { SetValue(WindowStateProperty, value); }
}
///
/// Enables or disables resizing of the window.
/// Note that if is set to False then this property
/// has no effect and should be treated as a recommendation for the user setting HasSystemDecorations.
///
public bool CanResize
{
get { return GetValue(CanResizeProperty); }
set { SetValue(CanResizeProperty, value); }
}
///
/// Gets or sets the icon of the window.
///
public WindowIcon Icon
{
get { return GetValue(IconProperty); }
set { SetValue(IconProperty, value); }
}
///
/// Gets or sets the startup location of the window.
///
public WindowStartupLocation WindowStartupLocation
{
get { return _windowStartupLoction; }
set { SetAndRaise(WindowStartupLocationProperty, ref _windowStartupLoction, value); }
}
///
Size ILayoutRoot.MaxClientSize => _maxPlatformClientSize;
///
Type IStyleable.StyleKey => typeof(Window);
///
/// Fired before a window is closed.
///
public event EventHandler Closing;
private static void AddWindow(Window window)
{
if (Application.Current == null)
{
return;
}
Application.Current.Windows.Add(window);
}
private static void RemoveWindow(Window window)
{
if (Application.Current == null)
{
return;
}
Application.Current.Windows.Remove(window);
}
///
/// Closes the window.
///
public void Close()
{
Close(false);
}
protected override void HandleApplicationExiting()
{
base.HandleApplicationExiting();
Close(true);
}
///
/// Closes a dialog window with the specified result.
///
/// The dialog result.
///
/// When the window is shown with the method, the
/// resulting task will produce the value when the window
/// is closed.
///
public void Close(object dialogResult)
{
_dialogResult = dialogResult;
Close(false);
}
internal void Close(bool ignoreCancel)
{
try
{
if (!ignoreCancel && HandleClosing())
{
return;
}
}
finally
{
PlatformImpl?.Dispose();
HandleClosed();
}
}
///
/// Handles a closing notification from .
///
protected virtual bool HandleClosing()
{
var args = new CancelEventArgs();
Closing?.Invoke(this, args);
return args.Cancel;
}
protected virtual void HandleWindowStateChanged(WindowState state)
{
WindowState = state;
if (state == WindowState.Minimized)
{
Renderer.Stop();
}
else
{
Renderer.Start();
}
}
///
/// Hides the window but does not close it.
///
public override void Hide()
{
if (!IsVisible)
{
return;
}
using (BeginAutoSizing())
{
Renderer?.Stop();
PlatformImpl?.Hide();
}
IsVisible = false;
}
///
/// Shows the window.
///
public override void Show()
{
if (IsVisible)
{
return;
}
AddWindow(this);
EnsureInitialized();
IsVisible = true;
LayoutManager.Instance.ExecuteInitialLayoutPass(this);
using (BeginAutoSizing())
{
PlatformImpl?.Show();
Renderer?.Start();
}
SetWindowStartupLocation();
}
///
/// Shows the window as a dialog.
///
///
/// A task that can be used to track the lifetime of the dialog.
///
public Task ShowDialog()
{
return ShowDialog