Browse Source

Restore missing DPI correction for GridSplitter behavior.

pull/5767/head
Dariusz Komosiński 5 years ago
parent
commit
ee383659e2
  1. 18
      src/Avalonia.Controls/GridSplitter.cs
  2. 14
      src/Avalonia.Controls/Presenters/ContentPresenter.cs
  3. 19
      src/Avalonia.Layout/LayoutHelper.cs
  4. 16
      src/Avalonia.Layout/Layoutable.cs

18
src/Avalonia.Controls/GridSplitter.cs

@ -609,10 +609,20 @@ namespace Avalonia.Controls
private void MoveSplitter(double horizontalChange, double verticalChange) private void MoveSplitter(double horizontalChange, double verticalChange)
{ {
Debug.Assert(_resizeData != null, "_resizeData should not be null when calling MoveSplitter"); Debug.Assert(_resizeData != null, "_resizeData should not be null when calling MoveSplitter");
// Calculate the offset to adjust the splitter. // Calculate the offset to adjust the splitter. If layout rounding is enabled, we
var delta = _resizeData.ResizeDirection == GridResizeDirection.Columns ? horizontalChange : verticalChange; // need to round to an integer physical pixel value to avoid round-ups of children that
// expand the bounds of the Grid. In practice this only happens in high dpi because
// horizontal/vertical offsets here are never fractional (they correspond to mouse movement
// across logical pixels). Rounding error only creeps in when converting to a physical
// display with something other than the logical 96 dpi.
double delta = _resizeData.ResizeDirection == GridResizeDirection.Columns ? horizontalChange : verticalChange;
if (UseLayoutRounding)
{
delta = LayoutHelper.RoundLayoutValue(delta, LayoutHelper.GetLayoutScale(this));
}
DefinitionBase definition1 = _resizeData.Definition1; DefinitionBase definition1 = _resizeData.Definition1;
DefinitionBase definition2 = _resizeData.Definition2; DefinitionBase definition2 = _resizeData.Definition2;

14
src/Avalonia.Controls/Presenters/ContentPresenter.cs

@ -378,7 +378,7 @@ namespace Avalonia.Controls.Presenters
var useLayoutRounding = UseLayoutRounding; var useLayoutRounding = UseLayoutRounding;
var availableSize = finalSize; var availableSize = finalSize;
var sizeForChild = availableSize; var sizeForChild = availableSize;
var scale = GetLayoutScale(); var scale = LayoutHelper.GetLayoutScale(this);
var originX = offset.X; var originX = offset.X;
var originY = offset.Y; var originY = offset.Y;
@ -462,18 +462,6 @@ namespace Avalonia.Controls.Presenters
PseudoClasses.Set(":empty", Content is null); PseudoClasses.Set(":empty", Content is null);
} }
private double GetLayoutScale()
{
var result = (VisualRoot as ILayoutRoot)?.LayoutScaling ?? 1.0;
if (result == 0 || double.IsNaN(result) || double.IsInfinity(result))
{
throw new Exception($"Invalid LayoutScaling returned from {VisualRoot.GetType()}");
}
return result;
}
private void TemplatedParentChanged(AvaloniaPropertyChangedEventArgs e) private void TemplatedParentChanged(AvaloniaPropertyChangedEventArgs e)
{ {
var host = e.NewValue as IContentPresenterHost; var host = e.NewValue as IContentPresenterHost;

19
src/Avalonia.Layout/LayoutHelper.cs

@ -82,6 +82,25 @@ namespace Avalonia.Layout
InnerInvalidateMeasure(control); InnerInvalidateMeasure(control);
} }
/// <summary>
/// Obtains layout scale of the given control.
/// </summary>
/// <param name="control">The control.</param>
/// <exception cref="Exception">Thrown when control has no root or returned layout scaling is invalid.</exception>
public static double GetLayoutScale(ILayoutable control)
{
var visualRoot = control.VisualRoot;
var result = (visualRoot as ILayoutRoot)?.LayoutScaling ?? 1.0;
if (result == 0 || double.IsNaN(result) || double.IsInfinity(result))
{
throw new Exception($"Invalid LayoutScaling returned from {visualRoot.GetType()}");
}
return result;
}
/// <summary> /// <summary>
/// Rounds a size to integer values for layout purposes, compensating for high DPI screen /// Rounds a size to integer values for layout purposes, compensating for high DPI screen
/// coordinates. /// coordinates.

16
src/Avalonia.Layout/Layoutable.cs

@ -590,7 +590,7 @@ namespace Avalonia.Layout
if (UseLayoutRounding) if (UseLayoutRounding)
{ {
var scale = GetLayoutScale(); var scale = LayoutHelper.GetLayoutScale(this);
width = LayoutHelper.RoundLayoutValue(width, scale); width = LayoutHelper.RoundLayoutValue(width, scale);
height = LayoutHelper.RoundLayoutValue(height, scale); height = LayoutHelper.RoundLayoutValue(height, scale);
} }
@ -652,7 +652,7 @@ namespace Avalonia.Layout
var horizontalAlignment = HorizontalAlignment; var horizontalAlignment = HorizontalAlignment;
var verticalAlignment = VerticalAlignment; var verticalAlignment = VerticalAlignment;
var size = availableSizeMinusMargins; var size = availableSizeMinusMargins;
var scale = GetLayoutScale(); var scale = LayoutHelper.GetLayoutScale(this);
var useLayoutRounding = UseLayoutRounding; var useLayoutRounding = UseLayoutRounding;
if (horizontalAlignment != HorizontalAlignment.Stretch) if (horizontalAlignment != HorizontalAlignment.Stretch)
@ -833,17 +833,5 @@ namespace Avalonia.Layout
{ {
return new Size(Math.Max(size.Width, 0), Math.Max(size.Height, 0)); return new Size(Math.Max(size.Width, 0), Math.Max(size.Height, 0));
} }
private double GetLayoutScale()
{
var result = (VisualRoot as ILayoutRoot)?.LayoutScaling ?? 1.0;
if (result == 0 || double.IsNaN(result) || double.IsInfinity(result))
{
throw new Exception($"Invalid LayoutScaling returned from {VisualRoot.GetType()}");
}
return result;
}
} }
} }

Loading…
Cancel
Save