// ----------------------------------------------------------------------- // // Copyright 2014 MIT Licence. See licence.md for more information. // // ----------------------------------------------------------------------- namespace Perspex.Controls { using System; using System.Reactive.Linq; using System.Threading.Tasks; using Perspex.Input; using Perspex.Media; using Perspex.Platform; using Perspex.Styling; using Splat; /// /// Determines how a will size itself to fit its content. /// public enum SizeToContent { /// /// The window will not automatically size itself to fit its content. /// Manual, /// /// The window will size itself horizontally to fit its content. /// Width, /// /// The window will size itself vertically to fit its content. /// Height, /// /// The window will size itself horizontally and vertically to fit its content. /// WidthAndHeight, } /// /// A top-level window. /// public class Window : TopLevel, IStyleable, IFocusScope { /// /// Defines the property. /// public static readonly PerspexProperty SizeToContentProperty = PerspexProperty.Register(nameof(SizeToContent)); /// /// Defines the property. /// public static readonly PerspexProperty TitleProperty = PerspexProperty.Register(nameof(Title), "Window"); private object dialogResult; /// /// Initializes static members of the class. /// static Window() { BackgroundProperty.OverrideDefaultValue(typeof(Window), Brushes.White); } /// /// Initializes a new instance of the class. /// public Window() : base(Locator.Current.GetService()) { } /// /// Gets the platform-specific window implementation. /// public new IWindowImpl PlatformImpl { get { return (IWindowImpl)base.PlatformImpl; } } /// /// Gets or sets a value indicating how the window will size itself to fit its content. /// public SizeToContent SizeToContent { get { return this.GetValue(SizeToContentProperty); } set { this.SetValue(SizeToContentProperty, value); } } /// /// Gets or sets the title of the window. /// public string Title { get { return this.GetValue(TitleProperty); } set { this.SetValue(TitleProperty, value); } } /// Type IStyleable.StyleKey { get { return typeof(Window); } } /// /// Closes the window. /// public void Close() { this.PlatformImpl.Dispose(); } /// /// 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) { this.dialogResult = dialogResult; this.Close(); } /// /// Hides the window but does not close it. /// public void Hide() { using (this.BeginAutoSizing()) { this.PlatformImpl.Hide(); } } /// /// Shows the window. /// public void Show() { this.LayoutManager.ExecuteLayoutPass(); using (this.BeginAutoSizing()) { this.PlatformImpl.Show(); } } /// /// Shows the window as a dialog. /// /// /// A task that can be used to track the lifetime of the dialog. /// public Task ShowDialog() { return this.ShowDialog(); } /// /// Shows the window as a dialog. /// /// /// The type of the result produced by the dialog. /// /// . /// A task that can be used to retrive the result of the dialog when it closes. /// public Task ShowDialog() { this.LayoutManager.ExecuteLayoutPass(); using (this.BeginAutoSizing()) { var modal = this.PlatformImpl.ShowDialog(); var result = new TaskCompletionSource(); Observable.FromEventPattern(this, nameof(this.Closed)) .Take(1) .Subscribe(_ => { modal.Dispose(); result.SetResult((TResult)this.dialogResult); }); return result.Task; } } /// protected override Size ArrangeOverride(Size finalSize) { var sizeToContent = this.SizeToContent; if (sizeToContent != SizeToContent.Manual) { Size size; switch (sizeToContent) { case SizeToContent.Width: size = new Size(finalSize.Width, this.ClientSize.Height); break; case SizeToContent.Height: size = new Size(this.ClientSize.Width, finalSize.Height); break; case SizeToContent.WidthAndHeight: size = new Size(finalSize.Width, finalSize.Height); break; default: throw new InvalidOperationException("Invalid value for SizeToContent."); } using (this.BeginAutoSizing()) { this.PlatformImpl.ClientSize = size; } } return base.ArrangeOverride(this.PlatformImpl.ClientSize); } /// protected override void HandleResized(Size clientSize) { if (!this.AutoSizing) { this.SizeToContent = SizeToContent.Manual; } base.HandleResized(clientSize); } } }