Browse Source

Implemented Window.SizeToContent.

pull/81/head
Steven Kirk 11 years ago
parent
commit
14f20e81dd
  1. 54
      Perspex.Controls/TopLevel.cs
  2. 139
      Perspex.Controls/Window.cs
  3. 1
      TestApplication/Program.cs

54
Perspex.Controls/TopLevel.cs

@ -71,11 +71,6 @@ namespace Perspex.Controls
/// </summary>
private IKeyboardNavigationHandler keyboardNavigationHandler;
/// <summary>
/// Whether an auto-size operation is in progress.
/// </summary>
private bool autoSizing;
/// <summary>
/// Initializes static members of the <see cref="TopLevel"/> class.
/// </summary>
@ -254,6 +249,15 @@ namespace Perspex.Controls
set { this.SetValue(AccessText.ShowAccessKeyProperty, value); }
}
/// <summary>
/// Whether an auto-size operation is in progress.
/// </summary>
protected bool AutoSizing
{
get;
private set;
}
/// <summary>
/// Translates a point from window coordinates into screen coordinates.
/// </summary>
@ -283,8 +287,8 @@ namespace Perspex.Controls
/// </remarks>
protected IDisposable BeginAutoSizing()
{
this.autoSizing = true;
return Disposable.Create(() => this.autoSizing = false);
this.AutoSizing = true;
return Disposable.Create(() => this.AutoSizing = false);
}
/// <summary>
@ -302,6 +306,24 @@ namespace Perspex.Controls
return base.ArrangeOverride(this.PlatformImpl.ClientSize);
}
/// <summary>
/// Handles a resize notification from <see cref="ITopLevelImpl.Resized"/>.
/// </summary>
/// <param name="clientSize">The new client size.</param>
protected virtual void HandleResized(Size clientSize)
{
if (!this.AutoSizing)
{
this.Width = clientSize.Width;
this.Height = clientSize.Height;
}
this.ClientSize = clientSize;
this.renderer.Resize((int)clientSize.Width, (int)clientSize.Height);
this.LayoutManager.ExecuteLayoutPass();
this.PlatformImpl.Invalidate(new Rect(clientSize));
}
/// <summary>
/// Tries to get a service from an <see cref="IDependencyResolver"/>, throwing an
/// exception if not found.
@ -412,23 +434,5 @@ namespace Perspex.Controls
this.renderer.Render(this, handle);
this.renderManager.RenderFinished();
}
/// <summary>
/// Handles a resize notification from <see cref="ITopLevelImpl.Resized"/>.
/// </summary>
/// <param name="clientSize">The new client size.</param>
private void HandleResized(Size clientSize)
{
if (!this.autoSizing)
{
this.Width = clientSize.Width;
this.Height = clientSize.Height;
}
this.ClientSize = clientSize;
this.renderer.Resize((int)clientSize.Width, (int)clientSize.Height);
this.LayoutManager.ExecuteLayoutPass();
this.PlatformImpl.Invalidate(new Rect(clientSize));
}
}
}

139
Perspex.Controls/Window.cs

@ -15,50 +15,125 @@ namespace Perspex.Controls
using Perspex.Styling;
using Splat;
/// <summary>
/// Determines how a <see cref="Window"/> will size itself to fit its content.
/// </summary>
public enum SizeToContent
{
/// <summary>
/// The window will not automatically size itself to fit its content.
/// </summary>
Manual,
/// <summary>
/// The window will size itself horizontally to fit its content.
/// </summary>
Width,
/// <summary>
/// The window will size itself vertically to fit its content.
/// </summary>
Height,
/// <summary>
/// The window will size itself horizontally and vertically to fit its content.
/// </summary>
WidthAndHeight,
}
/// <summary>
/// A top-level window.
/// </summary>
public class Window : TopLevel, IStyleable, IFocusScope
{
/// <summary>
/// Defines the <see cref="SizeToContent"/> property.
/// </summary>
public static readonly PerspexProperty<SizeToContent> SizeToContentProperty =
PerspexProperty.Register<Window, SizeToContent>(nameof(SizeToContent));
/// <summary>
/// Defines the <see cref="Title"/> property.
/// </summary>
public static readonly PerspexProperty<string> TitleProperty =
PerspexProperty.Register<Window, string>("Title", "Window");
PerspexProperty.Register<Window, string>(nameof(Title), "Window");
private object dialogResult;
/// <summary>
/// Initializes static members of the <see cref="Window"/> class.
/// </summary>
static Window()
{
BackgroundProperty.OverrideDefaultValue(typeof(Window), Brushes.White);
}
/// <summary>
/// Initializes a new instance of the <see cref="Window"/> class.
/// </summary>
public Window()
: base(Locator.Current.GetService<IWindowImpl>())
{
}
/// <summary>
/// Gets the platform-specific window implementation.
/// </summary>
public new IWindowImpl PlatformImpl
{
get { return (IWindowImpl)base.PlatformImpl; }
}
/// <summary>
/// Gets or sets a value indicating how the window will size itself to fit its content.
/// </summary>
public SizeToContent SizeToContent
{
get { return this.GetValue(SizeToContentProperty); }
set { this.SetValue(SizeToContentProperty, value); }
}
/// <summary>
/// Gets or sets the title of the window.
/// </summary>
public string Title
{
get { return this.GetValue(TitleProperty); }
set { this.SetValue(TitleProperty, value); }
}
/// <inheritdoc/>
Type IStyleable.StyleKey
{
get { return typeof(Window); }
}
/// <summary>
/// Closes the window.
/// </summary>
public void Close()
{
this.PlatformImpl.Dispose();
}
/// <summary>
/// Closes a dialog window with the specified result.
/// </summary>
/// <param name="dialogResult">The dialog result.</param>
/// <remarks>
/// When the window is shown with the <see cref="ShowDialog{TResult}"/> method, the
/// resulting task will produce the <see cref="dialogResult"/> value when the window
/// is closed.
/// </remarks>
public void Close(object dialogResult)
{
this.dialogResult = dialogResult;
this.Close();
}
/// <summary>
/// Hides the window but does not close it.
/// </summary>
public void Hide()
{
using (this.BeginAutoSizing())
@ -67,6 +142,9 @@ namespace Perspex.Controls
}
}
/// <summary>
/// Shows the window.
/// </summary>
public void Show()
{
this.LayoutManager.ExecuteLayoutPass();
@ -77,11 +155,26 @@ namespace Perspex.Controls
}
}
/// <summary>
/// Shows the window as a dialog.
/// </summary>
/// <returns>
/// A task that can be used to track the lifetime of the dialog.
/// </returns>
public Task ShowDialog()
{
return this.ShowDialog<object>();
}
/// <summary>
/// Shows the window as a dialog.
/// </summary>
/// <typeparam name="TResult">
/// The type of the result produced by the dialog.
/// </typeparam>
/// <returns>.
/// A task that can be used to retrive the result of the dialog when it closes.
/// </returns>
public Task<TResult> ShowDialog<TResult>()
{
this.LayoutManager.ExecuteLayoutPass();
@ -102,5 +195,49 @@ namespace Perspex.Controls
return result.Task;
}
}
/// <inheritdoc/>
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);
}
/// <inheritdoc/>
protected override void HandleResized(Size clientSize)
{
if (!this.AutoSizing)
{
this.SizeToContent = SizeToContent.Manual;
}
base.HandleResized(clientSize);
}
}
}

1
TestApplication/Program.cs

@ -118,6 +118,7 @@ namespace TestApplication
Window window = new Window
{
Title = "Perspex Test Application",
SizeToContent = SizeToContent.WidthAndHeight,
Content = new Grid
{
ColumnDefinitions = new ColumnDefinitions

Loading…
Cancel
Save