From 46dc8f13f6d30668e72d21998f61cadf06adafbc Mon Sep 17 00:00:00 2001 From: Curtis Wensley Date: Tue, 26 Nov 2024 16:38:35 -0800 Subject: [PATCH] Wpf: Drawable updates for large canvases in a scrollable --- src/Eto.Wpf/Forms/Controls/DrawableHandler.cs | 49 +++++++++++++------ .../Forms/Controls/ScrollableHandler.cs | 3 -- .../Sections/Controls/DrawableSection.cs | 4 +- 3 files changed, 37 insertions(+), 19 deletions(-) mode change 100644 => 100755 src/Eto.Wpf/Forms/Controls/DrawableHandler.cs mode change 100644 => 100755 src/Eto.Wpf/Forms/Controls/ScrollableHandler.cs diff --git a/src/Eto.Wpf/Forms/Controls/DrawableHandler.cs b/src/Eto.Wpf/Forms/Controls/DrawableHandler.cs old mode 100644 new mode 100755 index c1f47e640a..d7fb90fffd --- a/src/Eto.Wpf/Forms/Controls/DrawableHandler.cs +++ b/src/Eto.Wpf/Forms/Controls/DrawableHandler.cs @@ -5,9 +5,9 @@ namespace Eto.Wpf.Forms.Controls public class DrawableHandler : DrawableHandler { } public class DrawableHandler : WpfPanel, Drawable.IHandler - where TControl : swc.Canvas - where TWidget : Drawable - where TCallback : Drawable.ICallback + where TControl : swc.Canvas + where TWidget : Drawable + where TCallback : Drawable.ICallback { bool tiled; sw.FrameworkElement content; @@ -27,6 +27,8 @@ public bool OptimizedInvalidateRect public bool AllowTiling { get; set; } + public bool PartialInvalidate { get; set; } + public bool SupportsCreateGraphics { get { return false; } } public Size TileSize @@ -66,13 +68,9 @@ protected override void OnRender(swm.DrawingContext dc) if (!Handler.tiled) { var rect = new sw.Rect(0, 0, ActualWidth, ActualHeight); - var cliprect = rect.ToEto(); - if (!cliprect.IsEmpty) + if (!rect.IsEmpty) { - using (var graphics = new Graphics(new GraphicsHandler(this, dc, rect, new RectangleF(Handler.ClientSize), false))) - { - Handler.Callback.OnPaint(Handler.Widget, new PaintEventArgs(graphics, cliprect)); - } + Handler.Render(this, dc, rect); } } } @@ -88,7 +86,7 @@ private sw.Size ContentMeasureOverride(sw.Size constraint) var content = Handler.content; if (content == null) return size; - + // content should be used to measure, if present content.Measure(constraint); return content.DesiredSize; @@ -104,6 +102,22 @@ protected override sw.Size ArrangeOverride(sw.Size arrangeSize) } } + private void Render(swm.Visual canvas, swm.DrawingContext dc, sw.Rect rect) + { + var cliprect = rect.ToEtoF(); + if (PartialInvalidate && scrollable != null) + { + var visibleRect = new RectangleF(scrollable.VisibleRect.Size); + visibleRect = scrollable.RectangleToScreen(visibleRect); + visibleRect = Widget.RectangleFromScreen(visibleRect); + cliprect.Intersect(visibleRect); + } + using (var graphics = new Graphics(new GraphicsHandler(canvas, dc, rect, cliprect, false))) + { + Callback.OnPaint(Widget, new PaintEventArgs(graphics, cliprect)); + } + } + class EtoTile : sw.FrameworkElement { Rectangle bounds; @@ -181,7 +195,8 @@ public void Create() { } public void Create(bool largeCanvas) { - AllowTiling = largeCanvas; + // AllowTiling = largeCanvas; + PartialInvalidate = largeCanvas; Create(); } @@ -237,12 +252,14 @@ void UnRegisterScrollable() void RegisterScrollable() { UnRegisterScrollable(); - if (AllowTiling) + if (AllowTiling || PartialInvalidate) { scrollable = Widget.FindParent(); if (scrollable != null) scrollable.Scroll += scrollable_Scroll; - + } + if (AllowTiling) + { Control.SizeChanged += Control_SizeChanged; SetMaxTiles(); tiled = true; @@ -274,7 +291,7 @@ void UpdateTiles(bool rebuildKeys = false) if (scroll != null) { // only show tiles in the visible rect of the scrollable - var visibleRect = new Rectangle(scroll.ClientSize); + var visibleRect = new Rectangle(scroll.VisibleRect.Size); var scrollableHandler = (ScrollableHandler)scroll.Handler; visibleRect.Offset(-Control.TranslatePoint(new sw.Point(), scrollableHandler.ContentControl).ToEtoPoint()); rect.Intersect(visibleRect); @@ -365,6 +382,10 @@ void UpdateTiles(bool rebuildKeys = false) void scrollable_Scroll(object sender, ScrollEventArgs e) { + if (PartialInvalidate) + { + Invalidate(false); + } UpdateTiles(); } diff --git a/src/Eto.Wpf/Forms/Controls/ScrollableHandler.cs b/src/Eto.Wpf/Forms/Controls/ScrollableHandler.cs old mode 100644 new mode 100755 index 4cfb2323bf..115ff68e89 --- a/src/Eto.Wpf/Forms/Controls/ScrollableHandler.cs +++ b/src/Eto.Wpf/Forms/Controls/ScrollableHandler.cs @@ -109,7 +109,6 @@ public Point ScrollPosition { get { - EnsureLoaded(); return new Point((int)scroller.HorizontalOffset, (int)scroller.VerticalOffset); } set @@ -124,7 +123,6 @@ public Size ScrollSize { get { - EnsureLoaded(); return new Size((int)scroller.ExtentWidth, (int)scroller.ExtentHeight); } set @@ -149,7 +147,6 @@ public override Size ClientSize { if (!Widget.Loaded) return Size; - EnsureLoaded(); var info = scroller.GetScrollInfo(); return info != null ? new Size((int)info.ViewportWidth, (int)info.ViewportHeight) : Size.Empty; } diff --git a/test/Eto.Test/Sections/Controls/DrawableSection.cs b/test/Eto.Test/Sections/Controls/DrawableSection.cs index 74362881b8..c834d58abf 100644 --- a/test/Eto.Test/Sections/Controls/DrawableSection.cs +++ b/test/Eto.Test/Sections/Controls/DrawableSection.cs @@ -92,9 +92,9 @@ Control WithBackground() Control LargeCanvas() { - var control = new Drawable + var control = new Drawable(true) { - Size = new Size(1000, 1000), + Size = new Size(2000, 2000), BackgroundColor = Colors.Blue }; var image = TestIcons.TestImage;