Fixes for issues:
- content bigger then border - issues with scroll - missing cursor when panning - zoom when Max/Min is reached cause position is changing - scrolls do not react to change of border bounds - scrolls do not react to change of content bounds
This commit is contained in:
Родитель
60d1ca107a
Коммит
cb0da193e1
|
@ -21,15 +21,16 @@ public partial class ZoomBorder : ILogicalScrollable
|
|||
/// Calculate scrollable properties.
|
||||
/// </summary>
|
||||
/// <param name="source">The source bounds.</param>
|
||||
/// <param name="borderSize">The size of border (this control)</param>
|
||||
/// <param name="matrix">The transform matrix.</param>
|
||||
/// <param name="extent">The extent of the scrollable content.</param>
|
||||
/// <param name="viewport">The size of the viewport.</param>
|
||||
/// <param name="offset">The current scroll offset.</param>
|
||||
public static void CalculateScrollable(Rect source, Matrix matrix, out Size extent, out Size viewport, out Vector offset)
|
||||
public static void CalculateScrollable(Rect source, Size borderSize, Matrix matrix, out Size extent, out Size viewport, out Vector offset)
|
||||
{
|
||||
var bounds = new Rect(0, 0, source.Width, source.Height);
|
||||
|
||||
viewport = bounds.Size;
|
||||
viewport = borderSize;
|
||||
|
||||
var transformed = bounds.TransformToAABB(matrix);
|
||||
|
||||
|
@ -188,7 +189,7 @@ public partial class ZoomBorder : ILogicalScrollable
|
|||
return;
|
||||
}
|
||||
|
||||
CalculateScrollable(_element.Bounds, _matrix, out var extent, out var viewport, out var offset);
|
||||
CalculateScrollable(_element.Bounds, this.Bounds.Size, _matrix, out var extent, out var viewport, out var offset);
|
||||
|
||||
Log($"[InvalidateScrollable] _element.Bounds: {_element.Bounds}, _matrix: {_matrix}");
|
||||
Log($"[InvalidateScrollable] _extent: {_extent}, extent: {extent}, diff: {extent - _extent}");
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using Avalonia.Controls.Metadata;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Media;
|
||||
using Avalonia.Media.Transformation;
|
||||
|
@ -11,6 +12,8 @@ namespace Avalonia.Controls.PanAndZoom;
|
|||
/// <summary>
|
||||
/// Pan and zoom control for Avalonia.
|
||||
/// </summary>
|
||||
|
||||
[PseudoClasses(":isPanning")]
|
||||
public partial class ZoomBorder : Border
|
||||
{
|
||||
[Conditional("DEBUG")]
|
||||
|
@ -136,10 +139,18 @@ public partial class ZoomBorder : Border
|
|||
Moved(e);
|
||||
}
|
||||
|
||||
private void Element_PropertyChanged(object sender, AvaloniaPropertyChangedEventArgs e)
|
||||
{
|
||||
if(e.Property == BoundsProperty)
|
||||
{
|
||||
InvalidateScrollable();
|
||||
}
|
||||
}
|
||||
|
||||
private void BoundsChanged(Rect bounds)
|
||||
{
|
||||
// Log($"[BoundsChanged] {bounds}");
|
||||
//InvalidateScrollable();
|
||||
InvalidateScrollable();
|
||||
}
|
||||
|
||||
private void ChildChanged(Control? element)
|
||||
|
@ -164,6 +175,7 @@ public partial class ZoomBorder : Border
|
|||
return;
|
||||
}
|
||||
_element = element;
|
||||
_element.PropertyChanged += Element_PropertyChanged;
|
||||
PointerWheelChanged += Border_PointerWheelChanged;
|
||||
PointerPressed += Border_PointerPressed;
|
||||
PointerReleased += Border_PointerReleased;
|
||||
|
@ -176,10 +188,12 @@ public partial class ZoomBorder : Border
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
PointerWheelChanged -= Border_PointerWheelChanged;
|
||||
PointerPressed -= Border_PointerPressed;
|
||||
PointerReleased -= Border_PointerReleased;
|
||||
PointerMoved -= Border_PointerMoved;
|
||||
_element.PropertyChanged -= Element_PropertyChanged;
|
||||
_element.RenderTransform = null;
|
||||
_element = null;
|
||||
}
|
||||
|
@ -214,6 +228,7 @@ public partial class ZoomBorder : Border
|
|||
BeginPanTo(point.X, point.Y);
|
||||
_captured = true;
|
||||
_isPanning = true;
|
||||
SetPseudoClass(":isPanning", _isPanning);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -229,6 +244,7 @@ public partial class ZoomBorder : Border
|
|||
}
|
||||
_captured = false;
|
||||
_isPanning = false;
|
||||
SetPseudoClass(":isPanning", _isPanning);
|
||||
}
|
||||
|
||||
private void Moved(PointerEventArgs e)
|
||||
|
@ -421,6 +437,11 @@ public partial class ZoomBorder : Border
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if((ZoomX >= MaxZoomX && ZoomY >= MaxZoomY && ratio > 1) || (ZoomX <= MinZoomX && ZoomY <= MinZoomY && ratio < 1))
|
||||
{
|
||||
return;
|
||||
}
|
||||
_updating = true;
|
||||
|
||||
Log("[ZoomTo]");
|
||||
|
@ -786,4 +807,6 @@ public partial class ZoomBorder : Border
|
|||
}
|
||||
AutoFit(Bounds.Width, Bounds.Height, _element.Bounds.Width, _element.Bounds.Height, skipTransitions);
|
||||
}
|
||||
|
||||
private void SetPseudoClass(string name, bool flag) => PseudoClasses.Set(name, flag);
|
||||
}
|
||||
|
|
|
@ -95,20 +95,34 @@ public class ZoomBorderTests
|
|||
[Fact]
|
||||
public void CalculateScrollable_Default()
|
||||
{
|
||||
var borderSize = new Size(300, 300);
|
||||
var bounds = new Rect(0, 0, 100, 100);
|
||||
var matrix = CreateMatrix();
|
||||
ZoomBorder.CalculateScrollable(bounds, matrix, out var extent, out var viewport, out var offset);
|
||||
Assert.Equal(new Size(100, 100), extent);
|
||||
ZoomBorder.CalculateScrollable(bounds, borderSize, matrix, out var extent, out var viewport, out var offset);
|
||||
Assert.Equal(new Size(300, 300), extent);
|
||||
Assert.Equal(new Size(300, 300), viewport);
|
||||
Assert.Equal(new Vector(0, 0), offset);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CalculateScrollable_ViewportSmallerThenContent()
|
||||
{
|
||||
var borderSize = new Size(100, 100);
|
||||
var bounds = new Rect(0, 0, 300, 300);
|
||||
var matrix = CreateMatrix();
|
||||
ZoomBorder.CalculateScrollable(bounds, borderSize, matrix, out var extent, out var viewport, out var offset);
|
||||
Assert.Equal(new Size(300, 300), extent);
|
||||
Assert.Equal(new Size(100, 100), viewport);
|
||||
Assert.Equal(new Vector(0, 0), offset);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void CalculateScrollable_OffsetX_Negative()
|
||||
{
|
||||
var borderSize = new Size(300, 300);
|
||||
var bounds = new Rect(0, 0, 300, 300);
|
||||
var matrix = CreateMatrix(offsetX: -100);
|
||||
ZoomBorder.CalculateScrollable(bounds, matrix, out var extent, out var viewport, out var offset);
|
||||
ZoomBorder.CalculateScrollable(bounds, borderSize, matrix, out var extent, out var viewport, out var offset);
|
||||
Assert.Equal(new Size(400, 300), extent);
|
||||
Assert.Equal(new Size(300, 300), viewport);
|
||||
Assert.Equal(new Vector(100, 0), offset);
|
||||
|
@ -117,9 +131,10 @@ public class ZoomBorderTests
|
|||
[Fact]
|
||||
public void CalculateScrollable_OffsetX_Positive()
|
||||
{
|
||||
var borderSize = new Size(300, 300);
|
||||
var bounds = new Rect(0, 0, 300, 300);
|
||||
var matrix = CreateMatrix(offsetX: 100);
|
||||
ZoomBorder.CalculateScrollable(bounds, matrix, out var extent, out var viewport, out var offset);
|
||||
ZoomBorder.CalculateScrollable(bounds, borderSize, matrix, out var extent, out var viewport, out var offset);
|
||||
Assert.Equal(new Size(400, 300), extent);
|
||||
Assert.Equal(new Size(300, 300), viewport);
|
||||
Assert.Equal(new Vector(0, 0), offset);
|
||||
|
@ -128,9 +143,10 @@ public class ZoomBorderTests
|
|||
[Fact]
|
||||
public void CalculateScrollable_OffsetY_Negative()
|
||||
{
|
||||
var borderSize = new Size(300, 300);
|
||||
var bounds = new Rect(0, 0, 300, 300);
|
||||
var matrix = CreateMatrix(offsetY: -100);
|
||||
ZoomBorder.CalculateScrollable(bounds, matrix, out var extent, out var viewport, out var offset);
|
||||
ZoomBorder.CalculateScrollable(bounds, borderSize, matrix, out var extent, out var viewport, out var offset);
|
||||
Assert.Equal(new Size(300, 400), extent);
|
||||
Assert.Equal(new Size(300, 300), viewport);
|
||||
Assert.Equal(new Vector(0, 100), offset);
|
||||
|
@ -139,9 +155,10 @@ public class ZoomBorderTests
|
|||
[Fact]
|
||||
public void CalculateScrollable_OffsetY_Positive()
|
||||
{
|
||||
var borderSize = new Size(300, 300);
|
||||
var bounds = new Rect(0, 0, 300, 300);
|
||||
var matrix = CreateMatrix(offsetY: 100);
|
||||
ZoomBorder.CalculateScrollable(bounds, matrix, out var extent, out var viewport, out var offset);
|
||||
ZoomBorder.CalculateScrollable(bounds, borderSize, matrix, out var extent, out var viewport, out var offset);
|
||||
Assert.Equal(new Size(300, 400), extent);
|
||||
Assert.Equal(new Size(300, 300), viewport);
|
||||
Assert.Equal(new Vector(0, 0), offset);
|
||||
|
@ -150,9 +167,10 @@ public class ZoomBorderTests
|
|||
[Fact]
|
||||
public void CalculateScrollable_ZoomIn_2x()
|
||||
{
|
||||
var borderSize = new Size(300, 300);
|
||||
var bounds = new Rect(0, 0, 300, 300);
|
||||
var matrix = CreateMatrix(scaleX: 2, scaleY: 2);
|
||||
ZoomBorder.CalculateScrollable(bounds, matrix, out var extent, out var viewport, out var offset);
|
||||
ZoomBorder.CalculateScrollable(bounds, borderSize, matrix, out var extent, out var viewport, out var offset);
|
||||
Assert.Equal(new Size(600, 600), extent);
|
||||
Assert.Equal(new Size(300, 300), viewport);
|
||||
Assert.Equal(new Vector(0, 0), offset);
|
||||
|
@ -161,9 +179,10 @@ public class ZoomBorderTests
|
|||
[Fact]
|
||||
public void CalculateScrollable_ZoomIn_2x_OffsetX_Negative()
|
||||
{
|
||||
var borderSize = new Size(300, 300);
|
||||
var bounds = new Rect(0, 0, 300, 300);
|
||||
var matrix = CreateMatrix(scaleX: 2, scaleY: 2, offsetX: -150);
|
||||
ZoomBorder.CalculateScrollable(bounds, matrix, out var extent, out var viewport, out var offset);
|
||||
ZoomBorder.CalculateScrollable(bounds, borderSize, matrix, out var extent, out var viewport, out var offset);
|
||||
Assert.Equal(new Size(600, 600), extent);
|
||||
Assert.Equal(new Size(300, 300), viewport);
|
||||
Assert.Equal(new Vector(150, 0), offset);
|
||||
|
@ -172,9 +191,10 @@ public class ZoomBorderTests
|
|||
[Fact]
|
||||
public void CalculateScrollable_ZoomIn_2x_OffsetX_Positive()
|
||||
{
|
||||
var borderSize = new Size(300, 300);
|
||||
var bounds = new Rect(0, 0, 300, 300);
|
||||
var matrix = CreateMatrix(scaleX: 2, scaleY: 2, offsetX: 150);
|
||||
ZoomBorder.CalculateScrollable(bounds, matrix, out var extent, out var viewport, out var offset);
|
||||
ZoomBorder.CalculateScrollable(bounds, borderSize, matrix, out var extent, out var viewport, out var offset);
|
||||
Assert.Equal(new Size(600, 600), extent);
|
||||
Assert.Equal(new Size(300, 300), viewport);
|
||||
Assert.Equal(new Vector(0, 0), offset);
|
||||
|
@ -183,9 +203,10 @@ public class ZoomBorderTests
|
|||
[Fact]
|
||||
public void CalculateScrollable_ZoomIn_2x_OffsetY_Negative()
|
||||
{
|
||||
var borderSize = new Size(300, 300);
|
||||
var bounds = new Rect(0, 0, 300, 300);
|
||||
var matrix = CreateMatrix(scaleX: 2, scaleY: 2, offsetY: -150);
|
||||
ZoomBorder.CalculateScrollable(bounds, matrix, out var extent, out var viewport, out var offset);
|
||||
ZoomBorder.CalculateScrollable(bounds,borderSize, matrix, out var extent, out var viewport, out var offset);
|
||||
Assert.Equal(new Size(600, 600), extent);
|
||||
Assert.Equal(new Size(300, 300), viewport);
|
||||
Assert.Equal(new Vector(0, 150), offset);
|
||||
|
@ -194,9 +215,10 @@ public class ZoomBorderTests
|
|||
[Fact]
|
||||
public void CalculateScrollable_ZoomIn_2x_OffsetY_Positive()
|
||||
{
|
||||
var borderSize = new Size(300, 300);
|
||||
var bounds = new Rect(0, 0, 300, 300);
|
||||
var matrix = CreateMatrix(scaleX: 2, scaleY: 2, offsetY: 150);
|
||||
ZoomBorder.CalculateScrollable(bounds, matrix, out var extent, out var viewport, out var offset);
|
||||
ZoomBorder.CalculateScrollable(bounds, borderSize, matrix, out var extent, out var viewport, out var offset);
|
||||
Assert.Equal(new Size(600, 600), extent);
|
||||
Assert.Equal(new Size(300, 300), viewport);
|
||||
Assert.Equal(new Vector(0, 0), offset);
|
||||
|
@ -205,9 +227,10 @@ public class ZoomBorderTests
|
|||
[Fact]
|
||||
public void CalculateScrollable_ZoomOut_0_5x()
|
||||
{
|
||||
var borderSize = new Size(300, 300);
|
||||
var bounds = new Rect(0, 0, 300, 300);
|
||||
var matrix = CreateMatrix(scaleX: 0.5, scaleY: 0.5);
|
||||
ZoomBorder.CalculateScrollable(bounds, matrix, out var extent, out var viewport, out var offset);
|
||||
ZoomBorder.CalculateScrollable(bounds, borderSize, matrix, out var extent, out var viewport, out var offset);
|
||||
Assert.Equal(new Size(300, 300), extent);
|
||||
Assert.Equal(new Size(300, 300), viewport);
|
||||
Assert.Equal(new Vector(0, 0), offset);
|
||||
|
@ -216,9 +239,10 @@ public class ZoomBorderTests
|
|||
[Fact]
|
||||
public void CalculateScrollable_ZoomOut_0_5x_OffsetX_Negative()
|
||||
{
|
||||
var borderSize = new Size(300, 300);
|
||||
var bounds = new Rect(0, 0, 300, 300);
|
||||
var matrix = CreateMatrix(scaleX: 0.5, scaleY: 0.5, offsetX: -200);
|
||||
ZoomBorder.CalculateScrollable(bounds, matrix, out var extent, out var viewport, out var offset);
|
||||
ZoomBorder.CalculateScrollable(bounds, borderSize, matrix, out var extent, out var viewport, out var offset);
|
||||
Assert.Equal(new Size(500, 300), extent);
|
||||
Assert.Equal(new Size(300, 300), viewport);
|
||||
Assert.Equal(new Vector(200, 0), offset);
|
||||
|
@ -227,9 +251,10 @@ public class ZoomBorderTests
|
|||
[Fact]
|
||||
public void CalculateScrollable_ZoomOut_0_5x_OffsetX_Positive()
|
||||
{
|
||||
var borderSize = new Size(300, 300);
|
||||
var bounds = new Rect(0, 0, 300, 300);
|
||||
var matrix = CreateMatrix(scaleX: 0.5, scaleY: 0.5, offsetX: 200);
|
||||
ZoomBorder.CalculateScrollable(bounds, matrix, out var extent, out var viewport, out var offset);
|
||||
ZoomBorder.CalculateScrollable(bounds, borderSize, matrix, out var extent, out var viewport, out var offset);
|
||||
Assert.Equal(new Size(350, 300), extent);
|
||||
Assert.Equal(new Size(300, 300), viewport);
|
||||
Assert.Equal(new Vector(0, 0), offset);
|
||||
|
@ -238,9 +263,10 @@ public class ZoomBorderTests
|
|||
[Fact]
|
||||
public void CalculateScrollable_ZoomOut_0_5x_OffsetY_Negative()
|
||||
{
|
||||
var borderSize = new Size(300, 300);
|
||||
var bounds = new Rect(0, 0, 300, 300);
|
||||
var matrix = CreateMatrix(scaleX: 0.5, scaleY: 0.5, offsetY: -200);
|
||||
ZoomBorder.CalculateScrollable(bounds, matrix, out var extent, out var viewport, out var offset);
|
||||
ZoomBorder.CalculateScrollable(bounds, borderSize, matrix, out var extent, out var viewport, out var offset);
|
||||
Assert.Equal(new Size(300, 500), extent);
|
||||
Assert.Equal(new Size(300, 300), viewport);
|
||||
Assert.Equal(new Vector(0, 200), offset);
|
||||
|
@ -249,11 +275,12 @@ public class ZoomBorderTests
|
|||
[Fact]
|
||||
public void CalculateScrollable_ZoomOut_0_5x_OffsetY_Positive()
|
||||
{
|
||||
var borderSize = new Size(300, 300);
|
||||
var bounds = new Rect(0, 0, 300, 300);
|
||||
var matrix = CreateMatrix(scaleX: 0.5, scaleY: 0.5, offsetY: 200);
|
||||
ZoomBorder.CalculateScrollable(bounds, matrix, out var extent, out var viewport, out var offset);
|
||||
ZoomBorder.CalculateScrollable(bounds, borderSize, matrix, out var extent, out var viewport, out var offset);
|
||||
Assert.Equal(new Size(300, 350), extent);
|
||||
Assert.Equal(new Size(300, 300), viewport);
|
||||
Assert.Equal(new Vector(0, 0), offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче