// 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.Concurrency;
using System.Threading;
using Avalonia.Animation;
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Controls.Templates;
using Avalonia.Input;
using Avalonia.Input.Platform;
using Avalonia.Input.Raw;
using Avalonia.Platform;
using Avalonia.Rendering;
using Avalonia.Styling;
using Avalonia.Threading;
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 : AvaloniaObject, 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;
///
public event EventHandler ResourcesChanged;
///
/// Creates an instance of the class.
///
public Application()
{
Name = "Avalonia Application";
}
///
/// 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 -= ThisResourcesChanged;
}
_resources = value;
_resources.ResourcesChanged += ThisResourcesChanged;
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;
///
/// Application lifetime, use it for things like setting the main window and exiting the app from code
/// Currently supported lifetimes are:
/// -
/// -
/// -
///
public IApplicationLifetime ApplicationLifetime { get; set; }
///
/// Initializes the application by loading XAML etc.
///
public virtual void Initialize() { }
///
bool IResourceProvider.TryGetResource(object key, out object value)
{
value = null;
return (_resources?.TryGetResource(key, out value) ?? false) ||
Styles.TryGetResource(key, out value);
}
///
/// 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().ToConstant(AvaloniaScheduler.Instance)
.Bind().ToConstant(DragDropDevice.Instance)
.Bind().ToTransient();
var clock = new RenderLoopClock();
AvaloniaLocator.CurrentMutable
.Bind().ToConstant(clock)
.GetService()?.Add(clock);
}
public virtual void OnFrameworkInitializationCompleted()
{
}
private void ThisResourcesChanged(object sender, ResourcesChangedEventArgs e)
{
ResourcesChanged?.Invoke(this, e);
}
private string _name;
///
/// Defines Name property
///
public static readonly DirectProperty NameProperty =
AvaloniaProperty.RegisterDirect("Name", o => o.Name, (o, v) => o.Name = v);
///
/// Application name to be used for various platform-specific purposes
///
public string Name
{
get => _name;
set => SetAndRaise(NameProperty, ref _name, value);
}
}
}