// 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); } } }