Browse Source

OverlayLayer is now a glorified Canvas

pull/2778/head
Nikita Tsukanov 7 years ago
parent
commit
52aff15ed3
  1. 118
      src/Avalonia.Controls/Primitives/OverlayLayer.cs
  2. 14
      src/Avalonia.Controls/Primitives/PopupHost.cs

118
src/Avalonia.Controls/Primitives/OverlayLayer.cs

@ -3,102 +3,9 @@ using Avalonia.VisualTree;
namespace Avalonia.Controls.Primitives namespace Avalonia.Controls.Primitives
{ {
public class OverlayLayer : Control public class OverlayLayer : Canvas
{ {
/// <summary>
/// Defines the Left attached property.
/// </summary>
public static readonly AttachedProperty<double> LeftProperty =
AvaloniaProperty.RegisterAttached<OverlayLayer, Control, double>("Left", 0);
/// <summary>
/// Defines the Top attached property.
/// </summary>
public static readonly AttachedProperty<double> TopProperty =
AvaloniaProperty.RegisterAttached<OverlayLayer, Control, double>("Top", 0);
/// <summary>
/// Defines the InfiniteAvailableSize attached property.
/// </summary>
public static readonly AttachedProperty<bool> InfiniteAvailableSizeProperty =
AvaloniaProperty.RegisterAttached<OverlayLayer, Control, bool>("InfiniteAvailableSize", false);
static OverlayLayer()
{
foreach (var p in new []{LeftProperty, TopProperty})
{
p.Changed.AddClassHandler<Control>((target, e) =>
{
if (target.GetVisualParent() is OverlayLayer layer)
layer.InvalidateArrange();
});
}
}
public Size AvailableSize { get; private set; } public Size AvailableSize { get; private set; }
/// <summary>
/// Gets the value of the Left attached property for a control.
/// </summary>
/// <param name="element">The control.</param>
/// <returns>The control's left coordinate.</returns>
public static double GetLeft(AvaloniaObject element)
{
return element.GetValue(LeftProperty);
}
/// <summary>
/// Sets the value of the Left attached property for a control.
/// </summary>
/// <param name="element">The control.</param>
/// <param name="value">The left value.</param>
public static void SetLeft(AvaloniaObject element, double value)
{
element.SetValue(LeftProperty, value);
}
/// <summary>
/// Gets the value of the Top attached property for a control.
/// </summary>
/// <param name="element">The control.</param>
/// <returns>The control's top coordinate.</returns>
public static double GetTop(AvaloniaObject element)
{
return element.GetValue(TopProperty);
}
/// <summary>
/// Sets the value of the Top attached property for a control.
/// </summary>
/// <param name="element">The control.</param>
/// <param name="value">The top value.</param>
public static void SetTop(AvaloniaObject element, double value)
{
element.SetValue(TopProperty, value);
}
/// <summary>
/// Gets the value of the Top attached property for a control.
/// </summary>
/// <param name="element">The control.</param>
/// <returns>The control's top coordinate.</returns>
public static bool GetInfiniteAvailableSize(AvaloniaObject element)
{
return element.GetValue(InfiniteAvailableSizeProperty);
}
/// <summary>
/// Sets the value of the Top attached property for a control.
/// </summary>
/// <param name="element">The control.</param>
/// <param name="value">The top value.</param>
public static void SetInfiniteAvailableSize(AvaloniaObject element, bool value)
{
element.SetValue(InfiniteAvailableSizeProperty, value);
}
public static OverlayLayer GetOverlayLayer(IVisual visual) public static OverlayLayer GetOverlayLayer(IVisual visual)
{ {
foreach(var v in visual.GetVisualAncestors()) foreach(var v in visual.GetVisualAncestors())
@ -113,34 +20,13 @@ namespace Avalonia.Controls.Primitives
return null; return null;
} }
public void Add(Control v)
{
VisualChildren.Add(v);
InvalidateMeasure();
InvalidateArrange();
}
public void Remove(Control v) => VisualChildren.Remove(v);
protected override Size MeasureOverride(Size availableSize)
{
var infinite = new Size(double.PositiveInfinity, double.PositiveInfinity);
foreach (Control v in VisualChildren)
v.Measure(GetInfiniteAvailableSize(v) ? infinite : availableSize);
return new Size();
}
protected override Size ArrangeOverride(Size finalSize) protected override Size ArrangeOverride(Size finalSize)
{ {
// We are saving it here since child controls might need to know the entire size of the overlay // We are saving it here since child controls might need to know the entire size of the overlay
// and Bounds won't be updated in time // and Bounds won't be updated in time
AvailableSize = finalSize; AvailableSize = finalSize;
foreach (Control v in VisualChildren) return base.ArrangeOverride(finalSize);
v.Arrange(new Rect(GetLeft(v), GetTop(v), v.DesiredSize.Width, v.DesiredSize.Height));
return finalSize;
} }
} }
} }

14
src/Avalonia.Controls/Primitives/PopupHost.cs

@ -12,7 +12,7 @@ using Avalonia.VisualTree;
namespace Avalonia.Controls.Primitives namespace Avalonia.Controls.Primitives
{ {
public class PopupHost : Control, IPopupHost, IInteractive, IManagedPopupPositionerPopup public class PopupHost : Decorator, IPopupHost, IInteractive, IManagedPopupPositionerPopup
{ {
private readonly OverlayLayer _overlayLayer; private readonly OverlayLayer _overlayLayer;
private PopupPositionerParameters _positionerParameters = new PopupPositionerParameters(); private PopupPositionerParameters _positionerParameters = new PopupPositionerParameters();
@ -28,13 +28,7 @@ namespace Avalonia.Controls.Primitives
public void SetContent(IControl control) public void SetContent(IControl control)
{ {
if (_content == control) Child = control;
return;
if (_content != null)
VisualChildren.Remove(_content);
_content = control;
if (_content != null)
VisualChildren.Add(_content);
} }
public IVisual VisualRoot => null; public IVisual VisualRoot => null;
@ -47,13 +41,13 @@ namespace Avalonia.Controls.Primitives
public void Show() public void Show()
{ {
_overlayLayer.Add(this); _overlayLayer.Children.Add(this);
_shown = true; _shown = true;
} }
public void Hide() public void Hide()
{ {
_overlayLayer.Remove(this); _overlayLayer.Children.Remove(this);
_shown = false; _shown = false;
} }

Loading…
Cancel
Save