Browse Source

Review comments

pull/2778/head
Nikita Tsukanov 7 years ago
parent
commit
07ed194c9d
  1. 4
      src/Avalonia.Controls/Primitives/IPopupHost.cs
  2. 14
      src/Avalonia.Controls/Primitives/OverlayPopupHost.cs
  3. 10
      src/Avalonia.Controls/Primitives/Popup.cs
  4. 6
      src/Avalonia.Controls/Primitives/PopupPositioning/ManagedPopupPositioner.cs
  5. 6
      src/Avalonia.Controls/Primitives/PopupRoot.cs
  6. 18
      src/Avalonia.Controls/Primitives/VisualLayerManager.cs
  7. 6
      src/Avalonia.Controls/ToolTip.cs
  8. 8
      src/Avalonia.Themes.Default/Avalonia.Themes.Default.csproj
  9. 18
      src/Avalonia.Themes.Default/ComboBox.xaml
  10. 2
      src/Avalonia.Themes.Default/DefaultTheme.xaml
  11. 14
      src/Avalonia.Themes.Default/OverlayPopupHost.xaml
  12. 12
      src/Avalonia.Themes.Default/PopupHost.xaml
  13. 14
      src/Avalonia.Themes.Default/PopupRoot.xaml
  14. 2
      src/Avalonia.Visuals/Media/PixelPoint.cs
  15. 1
      src/Avalonia.Visuals/Media/PixelRect.cs
  16. 2
      src/Avalonia.Visuals/Media/PixelVector.cs
  17. 6
      tests/Avalonia.Controls.UnitTests/Primitives/PopupRootTests.cs
  18. 4
      tests/Avalonia.Controls.UnitTests/Primitives/PopupTests.cs

4
src/Avalonia.Controls/Primitives/IPopupHost.cs

@ -7,9 +7,9 @@ namespace Avalonia.Controls.Primitives
{
public interface IPopupHost : IDisposable
{
void SetContent(IControl control);
void SetChild(IControl control);
IContentPresenter Presenter { get; }
IVisual VisualRoot { get; }
IVisual HostedVisualTreeRoot { get; }
event EventHandler<TemplateAppliedEventArgs> TemplateApplied;

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

@ -9,25 +9,26 @@ using Avalonia.VisualTree;
namespace Avalonia.Controls.Primitives
{
public class PopupHost : ContentControl, IPopupHost, IInteractive, IManagedPopupPositionerPopup
public class OverlayPopupHost : ContentControl, IPopupHost, IInteractive, IManagedPopupPositionerPopup
{
private readonly OverlayLayer _overlayLayer;
private PopupPositionerParameters _positionerParameters = new PopupPositionerParameters();
private ManagedPopupPositioner _positioner;
private Point _lastRequestedPosition;
private bool _shown;
public PopupHost(OverlayLayer overlayLayer)
public OverlayPopupHost(OverlayLayer overlayLayer)
{
_overlayLayer = overlayLayer;
_positioner = new ManagedPopupPositioner(this);
}
public void SetContent(IControl control)
public void SetChild(IControl control)
{
Content = control;
}
public IVisual VisualRoot => null;
public IVisual HostedVisualTreeRoot => null;
/// <inheritdoc/>
IInteractive IInteractive.InteractiveParent => Parent;
@ -88,7 +89,7 @@ namespace Avalonia.Controls.Primitives
}
void UpdatePosition()
private void UpdatePosition()
{
// Don't bother the positioner with layout system artifacts
if (_positionerParameters.Size.Width == 0 || _positionerParameters.Size.Height == 0)
@ -111,7 +112,6 @@ namespace Avalonia.Controls.Primitives
Rect IManagedPopupPositionerPopup.ParentClientAreaScreenGeometry =>
new Rect(default, _overlayLayer.Bounds.Size);
private Point _lastRequestedPosition;
void IManagedPopupPositionerPopup.MoveAndResize(Point devicePoint, Size virtualSize)
{
_lastRequestedPosition = devicePoint;
@ -138,7 +138,7 @@ namespace Avalonia.Controls.Primitives
"Unable to create IPopupImpl and no overlay layer is found for the target control");
return new PopupHost(overlayLayer);
return new OverlayPopupHost(overlayLayer);
}
public override void Render(DrawingContext context)

10
src/Avalonia.Controls/Primitives/Popup.cs

@ -211,7 +211,7 @@ namespace Avalonia.Controls.Primitives
/// <summary>
/// Gets the root of the popup window.
/// </summary>
IVisual IVisualTreeHost.Root => _popupHost?.VisualRoot;
IVisual IVisualTreeHost.Root => _popupHost?.HostedVisualTreeRoot;
/// <summary>
/// Opens the popup.
@ -234,12 +234,12 @@ namespace Avalonia.Controls.Primitives
"Attempted to open a popup not attached to a TopLevel");
}
_popupHost = PopupHost.CreatePopupHost(placementTarget, DependencyResolver);
_popupHost = OverlayPopupHost.CreatePopupHost(placementTarget, DependencyResolver);
_bindings.Add(_popupHost.BindConstraints(this, WidthProperty, MinWidthProperty, MaxWidthProperty,
HeightProperty, MinHeightProperty, MaxHeightProperty, TopmostProperty));
_popupHost.SetContent(Child);
_popupHost.SetChild(Child);
((ISetLogicalParent)_popupHost).SetParent(this);
_popupHost.ConfigurePosition(placementTarget,
PlacementMode, new Point(HorizontalOffset, VerticalOffset));
@ -319,7 +319,7 @@ namespace Avalonia.Controls.Primitives
foreach(var b in _bindings)
b.Dispose();
_bindings.Clear();
_popupHost.SetContent(null);
_popupHost.SetChild(null);
_popupHost.Hide();
((ISetLogicalParent)_popupHost).SetParent(null);
_popupHost.Dispose();
@ -455,7 +455,7 @@ namespace Avalonia.Controls.Primitives
public bool IsInsidePopup(IVisual visual)
{
return _popupHost != null && ((IVisual)_popupHost)?.FindCommonVisualAncestor(visual) == _popupHost;
return _popupHost != null && ((IVisual)_popupHost)?.IsVisualAncestorOf(visual) == true;
}
public bool IsPointerOverPopup => ((IInputElement)_popupHost).IsPointerOver;

6
src/Avalonia.Controls/Primitives/PopupPositioning/ManagedPopupPositioner.cs

@ -35,7 +35,7 @@ namespace Avalonia.Controls.Primitives.PopupPositioning
}
static Point GetAnchorPoint(Rect anchorRect, PopupPositioningEdge edge)
private static Point GetAnchorPoint(Rect anchorRect, PopupPositioningEdge edge)
{
double x, y;
if ((edge & PopupPositioningEdge.Left) != 0)
@ -54,7 +54,7 @@ namespace Avalonia.Controls.Primitives.PopupPositioning
return new Point(x, y);
}
static Point Gravitate(Point anchorPoint, Size size, PopupPositioningEdge gravity)
private static Point Gravitate(Point anchorPoint, Size size, PopupPositioningEdge gravity)
{
double x, y;
if ((gravity & PopupPositioningEdge.Left) != 0)
@ -84,7 +84,7 @@ namespace Avalonia.Controls.Primitives.PopupPositioning
}
void Update(Size translatedSize, Size originalSize,
private void Update(Size translatedSize, Size originalSize,
Rect anchorRect, PopupPositioningEdge anchor, PopupPositioningEdge gravity,
PopupPositionerConstraintAdjustment constraintAdjustment, Point offset)
{

6
src/Avalonia.Controls/Primitives/PopupRoot.cs

@ -77,7 +77,7 @@ namespace Avalonia.Controls.Primitives
/// <inheritdoc/>
public void Dispose() => PlatformImpl?.Dispose();
void UpdatePosition()
private void UpdatePosition()
{
PlatformImpl?.PopupPositioner.Update(_positionerParameters);
}
@ -93,9 +93,9 @@ namespace Avalonia.Controls.Primitives
UpdatePosition();
}
public void SetContent(IControl control) => Content = control;
public void SetChild(IControl control) => Content = control;
IVisual IPopupHost.VisualRoot => this;
IVisual IPopupHost.HostedVisualTreeRoot => this;
public IDisposable BindConstraints(AvaloniaObject popup, StyledProperty<double> widthProperty, StyledProperty<double> minWidthProperty,
StyledProperty<double> maxWidthProperty, StyledProperty<double> heightProperty, StyledProperty<double> minHeightProperty,

18
src/Avalonia.Controls/Primitives/VisualLayerManager.cs

@ -8,14 +8,12 @@ namespace Avalonia.Controls.Primitives
{
private const int AdornerZIndex = int.MaxValue - 100;
private const int OverlayZIndex = int.MaxValue - 99;
private IStyleHost _styleRoot;
private readonly List<Control> _layers = new List<Control>();
private bool _isAttachedToLogicalTree;
private IStyleHost _styleHost;
public bool IsPopup { get; set; }
List<Control> _layers = new List<Control>();
public AdornerLayer AdornerLayer
{
get
@ -54,8 +52,8 @@ namespace Avalonia.Controls.Primitives
((ISetLogicalParent)layer).SetParent(this);
layer.ZIndex = zindex;
VisualChildren.Add(layer);
if (_isAttachedToLogicalTree)
((ILogical)layer).NotifyAttachedToLogicalTree(new LogicalTreeAttachmentEventArgs(_styleHost));
if (((ILogical)this).IsAttachedToLogicalTree)
((ILogical)layer).NotifyAttachedToLogicalTree(new LogicalTreeAttachmentEventArgs(_styleRoot));
InvalidateArrange();
}
@ -63,8 +61,7 @@ namespace Avalonia.Controls.Primitives
protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e)
{
base.OnAttachedToLogicalTree(e);
_isAttachedToLogicalTree = true;
_styleHost = e.Root;
_styleRoot = e.Root;
foreach (var l in _layers)
((ILogical)l).NotifyAttachedToLogicalTree(e);
@ -72,8 +69,7 @@ namespace Avalonia.Controls.Primitives
protected override void OnDetachedFromLogicalTree(LogicalTreeAttachmentEventArgs e)
{
_styleHost = null;
_isAttachedToLogicalTree = false;
_styleRoot = null;
base.OnDetachedFromLogicalTree(e);
foreach (var l in _layers)
((ILogical)l).NotifyDetachedFromLogicalTree(e);

6
src/Avalonia.Controls/ToolTip.cs

@ -235,8 +235,8 @@ namespace Avalonia.Controls
{
Close();
_popup = PopupHost.CreatePopupHost(control, null);
_popup.SetContent(this);
_popup = OverlayPopupHost.CreatePopupHost(control, null);
_popup.SetChild(this);
((ISetLogicalParent)_popup).SetParent(control);
_popup.ConfigurePosition(control, GetPlacement(control),
@ -248,7 +248,7 @@ namespace Avalonia.Controls
{
if (_popup != null)
{
_popup.SetContent(null);
_popup.SetChild(null);
_popup.Hide();
_popup = null;
}

8
src/Avalonia.Themes.Default/Avalonia.Themes.Default.csproj

@ -12,11 +12,11 @@
<ProjectReference Include="..\Avalonia.Layout\Avalonia.Layout.csproj" />
<ProjectReference Include="..\Avalonia.Visuals\Avalonia.Visuals.csproj" />
<ProjectReference Include="..\Avalonia.Styling\Avalonia.Styling.csproj" />
<AvaloniaResource Include="DefaultTheme.xaml"/>
<AvaloniaResource Include="Accents/*.xaml"/>
<AvaloniaResource Include="DefaultTheme.xaml" />
<AvaloniaResource Include="Accents/*.xaml" />
<!-- Compatibility with old apps, probably need to replace with AvaloniaResource -->
<EmbeddedResource Include="**/*.xaml"/>
<EmbeddedResource Include="**/*.xaml" />
</ItemGroup>
<Import Project="..\..\build\BuildTargets.targets"/>
<Import Project="..\..\build\BuildTargets.targets" />
<Import Project="..\..\build\Rx.props" />
</Project>

18
src/Avalonia.Themes.Default/ComboBox.xaml

@ -39,16 +39,14 @@
StaysOpen="False">
<Border BorderBrush="{DynamicResource ThemeBorderMidBrush}"
BorderThickness="1">
<VisualLayerManager IsPopup="True" Margin="-1 -1 0 0">
<ScrollViewer>
<ItemsPresenter Name="PART_ItemsPresenter"
Items="{TemplateBinding Items}"
ItemsPanel="{TemplateBinding ItemsPanel}"
ItemTemplate="{TemplateBinding ItemTemplate}"
VirtualizationMode="{TemplateBinding VirtualizationMode}"
/>
</ScrollViewer>
</VisualLayerManager>
<ScrollViewer>
<ItemsPresenter Name="PART_ItemsPresenter"
Items="{TemplateBinding Items}"
ItemsPanel="{TemplateBinding ItemsPanel}"
ItemTemplate="{TemplateBinding ItemTemplate}"
VirtualizationMode="{TemplateBinding VirtualizationMode}"
/>
</ScrollViewer>
</Border>
</Popup>
</Grid>

2
src/Avalonia.Themes.Default/DefaultTheme.xaml

@ -19,7 +19,7 @@
<StyleInclude Source="resm:Avalonia.Themes.Default.Menu.xaml?assembly=Avalonia.Themes.Default"/>
<StyleInclude Source="resm:Avalonia.Themes.Default.ContextMenu.xaml?assembly=Avalonia.Themes.Default"/>
<StyleInclude Source="resm:Avalonia.Themes.Default.MenuItem.xaml?assembly=Avalonia.Themes.Default"/>
<StyleInclude Source="resm:Avalonia.Themes.Default.PopupHost.xaml?assembly=Avalonia.Themes.Default"/>
<StyleInclude Source="resm:Avalonia.Themes.Default.OverlayPopupHost.xaml?assembly=Avalonia.Themes.Default"/>
<StyleInclude Source="resm:Avalonia.Themes.Default.PopupRoot.xaml?assembly=Avalonia.Themes.Default"/>
<StyleInclude Source="resm:Avalonia.Themes.Default.ProgressBar.xaml?assembly=Avalonia.Themes.Default"/>
<StyleInclude Source="resm:Avalonia.Themes.Default.RadioButton.xaml?assembly=Avalonia.Themes.Default"/>

14
src/Avalonia.Themes.Default/OverlayPopupHost.xaml

@ -0,0 +1,14 @@
<Style xmlns="https://github.com/avaloniaui" Selector="OverlayPopupHost">
<Setter Property="Background" Value="{DynamicResource ThemeBackgroundBrush}"/>
<Setter Property="Template">
<ControlTemplate>
<VisualLayerManager IsPopup="True" Margin="-1 -1 0 0">
<ContentPresenter Name="PART_ContentPresenter"
Background="{TemplateBinding Background}"
ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"
Padding="{TemplateBinding Padding}"/>
</VisualLayerManager>
</ControlTemplate>
</Setter>
</Style>

12
src/Avalonia.Themes.Default/PopupHost.xaml

@ -1,12 +0,0 @@
<Style xmlns="https://github.com/avaloniaui" Selector="PopupHost">
<Setter Property="Background" Value="{DynamicResource ThemeBackgroundBrush}"/>
<Setter Property="Template">
<ControlTemplate>
<ContentPresenter Name="PART_ContentPresenter"
Background="{TemplateBinding Background}"
ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"
Padding="{TemplateBinding Padding}"/>
</ControlTemplate>
</Setter>
</Style>

14
src/Avalonia.Themes.Default/PopupRoot.xaml

@ -2,11 +2,13 @@
<Setter Property="Background" Value="{DynamicResource ThemeBackgroundBrush}"/>
<Setter Property="Template">
<ControlTemplate>
<ContentPresenter Name="PART_ContentPresenter"
Background="{TemplateBinding Background}"
ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"
Padding="{TemplateBinding Padding}"/>
<VisualLayerManager IsPopup="True" Margin="-1 -1 0 0">
<ContentPresenter Name="PART_ContentPresenter"
Background="{TemplateBinding Background}"
ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"
Padding="{TemplateBinding Padding}"/>
</VisualLayerManager>
</ControlTemplate>
</Setter>
</Style>
</Style>

2
src/Avalonia.Visuals/Media/PixelPoint.cs

@ -160,8 +160,6 @@ namespace Avalonia
}
}
/// <summary>
/// Returns a new <see cref="PixelPoint"/> with the same Y co-ordinate and the specified X co-ordinate.
/// </summary>

1
src/Avalonia.Visuals/Media/PixelRect.cs

@ -272,7 +272,6 @@ namespace Avalonia
return new PixelRect(Position + offset, Size);
}
/// <summary>
/// Gets the union of two rectangles.
/// </summary>

2
src/Avalonia.Visuals/Media/PixelVector.cs

@ -130,9 +130,7 @@ namespace Avalonia
/// <returns></returns>
public bool Equals(PixelVector other)
{
// ReSharper disable CompareOfFloatsByEqualityOperator
return _x == other._x && _y == other._y;
// ReSharper restore CompareOfFloatsByEqualityOperator
}
/// <summary>

6
tests/Avalonia.Controls.UnitTests/Primitives/PopupRootTests.cs

@ -75,10 +75,14 @@ namespace Avalonia.Controls.UnitTests.Primitives
Assert.Single(((Visual)target.Host).GetVisualChildren());
var templatedChild = ((Visual)target.Host).GetVisualChildren().Single();
Assert.IsType<ContentPresenter>(templatedChild);
Assert.IsType<VisualLayerManager>(templatedChild);
var contentPresenter = templatedChild.VisualChildren.Single();
Assert.IsType<ContentPresenter>(contentPresenter);
Assert.Equal((PopupRoot)target.Host, ((IControl)templatedChild).TemplatedParent);
Assert.Equal((PopupRoot)target.Host, ((IControl)contentPresenter).TemplatedParent);
}
}

4
tests/Avalonia.Controls.UnitTests/Primitives/PopupTests.cs

@ -252,6 +252,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
Assert.Equal(
new[]
{
"VisualLayerManager",
"ContentPresenter",
"ContentPresenter",
"Border",
@ -265,6 +266,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
Assert.Equal(
new object[]
{
popupRoot,
popupRoot,
target,
null,
@ -320,7 +322,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
target.Open();
if (UsePopupHost)
Assert.IsType<PopupHost>(target.Host);
Assert.IsType<OverlayPopupHost>(target.Host);
else
Assert.IsType<PopupRoot>(target.Host);
}

Loading…
Cancel
Save