// 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.Threading;
using Avalonia.Controls;
using Avalonia.Controls.Templates;
using Avalonia.Input;
using Avalonia.Input.Platform;
using Avalonia.Layout;
using Avalonia.Rendering;
using Avalonia.Styling;
using Avalonia.Threading;
using System.Reactive.Concurrency;
using Avalonia.Input.DragDrop.Raw;
using Avalonia.Controls.Platform;
using Avalonia.Platform;
using Avalonia.Input.DragDrop;
namespace Avalonia
{
///
/// Encapsulates a Avalonia application.
///
///
/// The class encapsulates Avalonia application-specific
/// functionality, including:
/// - A global set of .
/// - A global set of .
/// - A .
/// - An .
/// - Registers services needed by the rest of Avalonia in the
/// method.
/// - Tracks the lifetime of the application.
///
public class Application : IApplicationLifecycle, IGlobalDataTemplates, IGlobalStyles, IStyleRoot, IResourceNode
{
///
/// The application-global data templates.
///
private DataTemplates _dataTemplates;
private readonly Lazy _clipboard =
new Lazy(() => (IClipboard)AvaloniaLocator.Current.GetService(typeof(IClipboard)));
private readonly Styler _styler = new Styler();
private Styles _styles;
private IResourceDictionary _resources;
///
/// Initializes a new instance of the class.
///
public Application()
{
OnExit += OnExiting;
}
///
public event EventHandler ResourcesChanged;
///
/// Gets the current instance of the class.
///
///
/// The current instance of the class.
///
public static Application Current
{
get { return AvaloniaLocator.Current.GetService(); }
}
///
/// Gets or sets the application's global data templates.
///
///
/// The application's global data templates.
///
public DataTemplates DataTemplates => _dataTemplates ?? (_dataTemplates = new DataTemplates());
///
/// Gets the application's focus manager.
///
///
/// The application's focus manager.
///
public IFocusManager FocusManager
{
get;
private set;
}
///
/// Gets the application's input manager.
///
///
/// The application's input manager.
///
public InputManager InputManager
{
get;
private set;
}
///
/// Gets the application clipboard.
///
public IClipboard Clipboard => _clipboard.Value;
///
/// Gets the application's global resource dictionary.
///
public IResourceDictionary Resources
{
get => _resources ?? (Resources = new ResourceDictionary());
set
{
Contract.Requires(value != null);
var hadResources = false;
if (_resources != null)
{
hadResources = _resources.Count > 0;
_resources.ResourcesChanged -= ResourcesChanged;
}
_resources = value;
_resources.ResourcesChanged += ResourcesChanged;
if (hadResources || _resources.Count > 0)
{
ResourcesChanged?.Invoke(this, new ResourcesChangedEventArgs());
}
}
}
///
/// Gets the application's global styles.
///
///
/// The application's global styles.
///
///
/// Global styles apply to all windows in the application.
///
public Styles Styles => _styles ?? (_styles = new Styles());
///
bool IDataTemplateHost.IsDataTemplatesInitialized => _dataTemplates != null;
///
/// Gets the styling parent of the application, which is null.
///
IStyleHost IStyleHost.StylingParent => null;
///
bool IStyleHost.IsStylesInitialized => _styles != null;
///
bool IResourceProvider.HasResources => _resources?.Count > 0;
///
IResourceNode IResourceNode.ResourceParent => null;
///
/// Initializes the application by loading XAML etc.
///
public virtual void Initialize()
{
}
///
/// Runs the application's main loop until the is closed.
///
/// The closable to track
public void Run(ICloseable closable)
{
var source = new CancellationTokenSource();
closable.Closed += OnExiting;
closable.Closed += (s, e) => source.Cancel();
Dispatcher.UIThread.MainLoop(source.Token);
}
///
/// Runs the application's main loop until the is cancelled.
///
/// The token to track
public void Run(CancellationToken token)
{
Dispatcher.UIThread.MainLoop(token);
}
///
/// Exits the application
///
public void Exit()
{
OnExit?.Invoke(this, EventArgs.Empty);
}
///
bool IResourceProvider.TryGetResource(string key, out object value)
{
value = null;
return (_resources?.TryGetResource(key, out value) ?? false) ||
Styles.TryGetResource(key, out value);
}
///
/// Sent when the application is exiting.
///
public event EventHandler OnExit;
///
/// Called when the application is exiting.
///
///
///
protected virtual void OnExiting(object sender, EventArgs e)
{
}
///
/// Register's the services needed by Avalonia.
///
public virtual void RegisterServices()
{
AvaloniaSynchronizationContext.InstallIfNeeded();
FocusManager = new FocusManager();
InputManager = new InputManager();
AvaloniaLocator.CurrentMutable
.Bind().ToTransient()
.Bind().ToConstant(this)
.Bind().ToConstant(this)
.Bind().ToConstant(FocusManager)
.Bind().ToConstant(InputManager)
.Bind().ToTransient()
.Bind().ToConstant(_styler)
.Bind().ToSingleton()
.Bind().ToConstant(this)
.Bind().ToConstant(AvaloniaScheduler.Instance)
.Bind().ToConstant(DragDropDevice.Instance)
.Bind().ToTransient();
}
}
}