From b339d69a510d35aa184478d6c50126fc98ae73ac Mon Sep 17 00:00:00 2001 From: Michael Oborne Date: Tue, 25 Jul 2023 11:43:05 +1000 Subject: [PATCH] FormsRender: DrawOntoCanvas move to static shared --- ExtLibs/Xamarin/SkiaTest/Program.cs | 175 +----------- .../Xamarin/Xamarin/GCSViews/WinForms.xaml.cs | 164 +----------- GCSViews/FlightData.cs | 2 +- ZZZLibShims.cs | 253 ++++++++++++++++++ 4 files changed, 258 insertions(+), 336 deletions(-) diff --git a/ExtLibs/Xamarin/SkiaTest/Program.cs b/ExtLibs/Xamarin/SkiaTest/Program.cs index 78336e667f..5b3ab08738 100644 --- a/ExtLibs/Xamarin/SkiaTest/Program.cs +++ b/ExtLibs/Xamarin/SkiaTest/Program.cs @@ -389,177 +389,6 @@ protected override void Dispose(bool disposing) public sealed class SkiaWindow : SkiaWindowBase { - - - private SKPaint paint = new SKPaint() {FilterQuality = SKFilterQuality.Low}; - - private bool DrawOntoCanvas(IntPtr handle, SKCanvas Canvas, TreeNode tree, bool forcerender = false) - { - var hwnd = Hwnd.ObjectFromHandle(handle); - - var x = 0; - var y = 0; - var wasdrawn = false; - - XplatUI.driver.ClientToScreen(hwnd.client_window, ref x, ref y); - - var width = 0; - var height = 0; - var client_width = 0; - var client_height = 0; - - - if (hwnd.hwndbmp != null && hwnd.Mapped && hwnd.Visible && !hwnd.zombie) - { - // setup clip - var parent = hwnd; - /* Canvas.ClipRect( - SKRect.Create(0, 0, Screen.PrimaryScreen.Bounds.Width * 2, - Screen.PrimaryScreen.Bounds.Height * 2), (SKClipOperation) 5); - */ - while (parent != null) - { - var xp = 0; - var yp = 0; - XplatUI.driver.ClientToScreen(parent.client_window, ref xp, ref yp); - /* - Canvas.ClipRect(SKRect.Create(xp, yp, parent.Width, parent.Height), - SKClipOperation.Intersect); - */ - parent = parent.parent; - } - - Monitor.Enter(XplatUIMine.paintlock); - - if (hwnd.ClientWindow != hwnd.WholeWindow) - { - var frm = Control.FromHandle(hwnd.ClientWindow) as Form; - - Hwnd.Borders borders = new Hwnd.Borders(); - - if (frm != null) - { - borders = Hwnd.GetBorders(frm.GetCreateParams(), null); - /* - Canvas.ClipRect( - SKRect.Create(0, 0, Screen.PrimaryScreen.Bounds.Width * 2, - Screen.PrimaryScreen.Bounds.Height * 2), (SKClipOperation) 5);*/ - } - - if (Canvas.DeviceClipBounds.Width > 0 && - Canvas.DeviceClipBounds.Height > 0) - { - if (hwnd.DrawNeeded || forcerender) - { - if (hwnd.hwndbmpNC != null) - Canvas.DrawImage(hwnd.hwndbmpNC, - new SKPoint(x - borders.left, y - borders.top), new SKPaint() - { - ColorFilter = - SKColorFilter.CreateColorMatrix(new float[] - { - 0.75f, 0.25f, 0.025f, 0, 0, - 0.25f, 0.75f, 0.25f, 0, 0, - 0.25f, 0.25f, 0.75f, 0, 0, - 0, 0, 0, 1, 0 - }) - }); - - /*Canvas.ClipRect( - SKRect.Create(x, y, hwnd.width - borders.right - borders.left, - hwnd.height - borders.top - borders.bottom), SKClipOperation.Intersect); - */ - Canvas.DrawDrawable(hwnd.hwndbmp, - new SKPoint(x, y)); - - wasdrawn = true; - } - - hwnd.DrawNeeded = false; - } - else - { - Monitor.Exit(XplatUIMine.paintlock); - return true; - } - } - else - { - if (Canvas.DeviceClipBounds.Width > 0 && - Canvas.DeviceClipBounds.Height > 0) - { - if (hwnd.DrawNeeded || forcerender) - { - Canvas.DrawDrawable(hwnd.hwndbmp, - new SKPoint(x + 0, y + 0)); - - wasdrawn = true; - } - - hwnd.DrawNeeded = false; -/* - surface.Canvas.DrawText(Control.FromHandle(hwnd.ClientWindow).Name, - new SKPoint(x, y + 15), - new SKPaint() {Color = SKColor.Parse("55ffff00")}); - /*surface.Canvas.DrawText(hwnd.ClientWindow.ToString(), new SKPoint(x,y+15), - new SKPaint() {Color = SKColor.Parse("ffff00")});*/ - - } - else - { - Monitor.Exit(XplatUIMine.paintlock); - return true; - } - } - - Monitor.Exit(XplatUIMine.paintlock); - } - - var ctrl = Control.FromHandle(hwnd.ClientWindow); - - Canvas.DrawText(x + " " + y + " " + ctrl.Name + " " + hwnd.width + " " + hwnd.Height, x, y + 10, - new SKPaint() {Color = SKColors.Red}); - - if (hwnd.Mapped && hwnd.Visible) - { - IEnumerable children; - children = tree.FindID(hwnd.Handle.ToInt32())?.Children.Select(a => (Hwnd)a.Value); - /* children = Hwnd.windows.OfType() - .Where(hwnd2 => - { - var Key = (IntPtr) hwnd2.Key; - var Value = (Hwnd) hwnd2.Value; - if (Value.ClientWindow == Key && Value.Parent == hwnd && Value.Visible && - Value.Mapped && !Value.zombie) - return true; - return false; - }).Select(a => (Hwnd) a.Value).ToArray(); - */ - if (children != null) - { - children = children.OrderBy((hwnd2) => - { - var info = XplatUIMine.GetInstance().GetZOrder(hwnd2.client_window); - if (info.top) - return 1000; - if (info.bottom) - return 0; - return 500; - - }); - - foreach (var child in children) - { - DrawOntoCanvas(child.ClientWindow, Canvas, tree, true); - } - } - } - - return true; - } - - - protected override void OnSkiaPaint(SKSurface e) { try @@ -595,7 +424,7 @@ protected override void OnSkiaPaint(SKSurface e) try { - DrawOntoCanvas(form.Handle, canvas, newtree, true); + FormsRender.DrawOntoCanvas(form.Handle, canvas, true); } catch (Exception ex) { @@ -612,7 +441,7 @@ protected override void OnSkiaPaint(SKSurface e) { var ctlmenu = Control.FromHandle(hw.ClientWindow); if (ctlmenu != null) - DrawOntoCanvas(hw.ClientWindow, canvas, newtree, true); + FormsRender.DrawOntoCanvas(hw.ClientWindow, canvas, true); } canvas.Restore(); diff --git a/ExtLibs/Xamarin/Xamarin/GCSViews/WinForms.xaml.cs b/ExtLibs/Xamarin/Xamarin/GCSViews/WinForms.xaml.cs index bcce682551..70b51414bb 100644 --- a/ExtLibs/Xamarin/Xamarin/GCSViews/WinForms.xaml.cs +++ b/ExtLibs/Xamarin/Xamarin/GCSViews/WinForms.xaml.cs @@ -851,166 +851,6 @@ private void SkCanvasView_Touch(object sender, SkiaSharp.Views.Forms.SKTouchEven } catch {} } - private SKPaint paint = new SKPaint() {FilterQuality = SKFilterQuality.Low}; - - private bool DrawOntoCanvas(IntPtr handle, SKCanvas Canvas, bool forcerender = false) - { - var hwnd = Hwnd.ObjectFromHandle(handle); - - var x = 0; - var y = 0; - var wasdrawn = false; - - XplatUI.driver.ClientToScreen(hwnd.client_window, ref x, ref y); - - var width = 0; - var height = 0; - var client_width = 0; - var client_height = 0; - - - if (hwnd.hwndbmp != null && hwnd.Mapped && hwnd.Visible && !hwnd.zombie) - { - // setup clip - var parent = hwnd; - Canvas.ClipRect( - SKRect.Create(0, 0, Screen.PrimaryScreen.Bounds.Width*2, - Screen.PrimaryScreen.Bounds.Height*2), (SKClipOperation) 5); - - while (parent != null) - { - var xp = 0; - var yp = 0; - XplatUI.driver.ClientToScreen(parent.client_window, ref xp, ref yp); - - Canvas.ClipRect(SKRect.Create(xp, yp, parent.Width, parent.Height), - SKClipOperation.Intersect); - - parent = parent.parent; - } - - Monitor.Enter(XplatUIMine.paintlock); - try - { - if (hwnd.ClientWindow != hwnd.WholeWindow) - { - var frm = Control.FromHandle(hwnd.ClientWindow) as Form; - - Hwnd.Borders borders = new Hwnd.Borders(); - - if (frm != null) - { - borders = Hwnd.GetBorders(frm.GetCreateParams(), null); - - Canvas.ClipRect( - SKRect.Create(0, 0, Screen.PrimaryScreen.Bounds.Width * 2, - Screen.PrimaryScreen.Bounds.Height * 2), (SKClipOperation) 5); - } - - if (Canvas.DeviceClipBounds.Width > 0 && - Canvas.DeviceClipBounds.Height > 0) - { - if (hwnd.DrawNeeded || forcerender) - { - if (hwnd.hwndbmpNC != null) - Canvas.DrawImage(hwnd.hwndbmpNC, - new SKPoint(x - borders.left, y - borders.top), paint); - - Canvas.ClipRect( - SKRect.Create(x, y, hwnd.width - borders.right - borders.left, - hwnd.height - borders.top - borders.bottom), SKClipOperation.Intersect); - - if (hwnd.hwndbmp != null) - Canvas.DrawDrawable(hwnd.hwndbmp, - new SKPoint(x, y)); - - wasdrawn = true; - } - - hwnd.DrawNeeded = false; - } - else - { - return true; - } - } - else - { - if (Canvas.DeviceClipBounds.Width > 0 && - Canvas.DeviceClipBounds.Height > 0) - { - if (hwnd.DrawNeeded || forcerender) - { - if (hwnd.hwndbmp != null) - Canvas.DrawDrawable(hwnd.hwndbmp, - new SKPoint(x + 0, y + 0)); - - wasdrawn = true; - } - - hwnd.DrawNeeded = false; -/* - surface.Canvas.DrawText(Control.FromHandle(hwnd.ClientWindow).Name, - new SKPoint(x, y + 15), - new SKPaint() {Color = SKColor.Parse("55ffff00")}); - /*surface.Canvas.DrawText(hwnd.ClientWindow.ToString(), new SKPoint(x,y+15), - new SKPaint() {Color = SKColor.Parse("ffff00")});*/ - - } - else - { - return true; - } - } - } - catch (Exception ex) - { - Console.WriteLine(ex); - return true; - } - finally - { - Monitor.Exit(XplatUIMine.paintlock); - } - } - - //surface.Canvas.DrawText(x + " " + y, x, y+10, new SKPaint() { Color = SKColors.Red}); - - if (hwnd.Mapped && hwnd.Visible) - { - IEnumerable children; - lock (Hwnd.windows) - children = Hwnd.windows.OfType() - .Where(hwnd2 => - { - var Key = (IntPtr) hwnd2.Key; - var Value = (Hwnd) hwnd2.Value; - if (Value.ClientWindow == Key && Value.Parent == hwnd && Value.Visible && - Value.Mapped && !Value.zombie) - return true; - return false; - }).Select(a => (Hwnd) a.Value).ToArray(); - - children = children.OrderBy((hwnd2) => - { - var info = XplatUIMine.GetInstance().GetZOrder(hwnd2.client_window); - if (info.top) - return 1000; - if (info.bottom) - return 0; - return 500; - - }); - - foreach (var child in children) - { - DrawOntoCanvas(child.ClientWindow, Canvas, true); - } - } - - return true; - } - private void SkCanvasView_PaintSurface(object sender, SkiaSharp.Views.Forms.SKPaintSurfaceEventArgs e) { SkCanvasView_PaintSurface(sender, new SKPaintGLSurfaceEventArgs(e.Surface, null)); @@ -1036,7 +876,7 @@ private void SkCanvasView_PaintSurface(object sender, SkiaSharp.Views.Forms.SKPa try { - DrawOntoCanvas(form.Handle, canvas, true); + FormsRender.DrawOntoCanvas(form.Handle, canvas, true); } catch (Exception ex) { @@ -1053,7 +893,7 @@ private void SkCanvasView_PaintSurface(object sender, SkiaSharp.Views.Forms.SKPa { var ctlmenu = Control.FromHandle(hw.ClientWindow); if (ctlmenu != null) - DrawOntoCanvas(hw.ClientWindow, canvas, true); + FormsRender.DrawOntoCanvas(hw.ClientWindow, canvas, true); } if (Device.RuntimePlatform != Device.macOS && Device.RuntimePlatform != Device.UWP) diff --git a/GCSViews/FlightData.cs b/GCSViews/FlightData.cs index 3e5799e5c5..ee47d1107b 100644 --- a/GCSViews/FlightData.cs +++ b/GCSViews/FlightData.cs @@ -5196,7 +5196,7 @@ private void updateBindingSourceWork() { try { - if (this.Visible) + if (this.Visible && !this.IsDisposed) { //Console.Write("bindingSource1 "); MainV2.comPort.MAV.cs.UpdateCurrentSettings(bindingSource1.UpdateDataSource(MainV2.comPort.MAV.cs)); diff --git a/ZZZLibShims.cs b/ZZZLibShims.cs index 336308d051..092ebec94c 100644 --- a/ZZZLibShims.cs +++ b/ZZZLibShims.cs @@ -8,6 +8,7 @@ using System.Drawing.Imaging; using System.Globalization; using System.IO; +using System.Linq; using System.Net; using System.Reflection; using System.Text; @@ -18,6 +19,258 @@ using MissionPlanner.Utilities; using SkiaSharp; +public class FormsRender +{ + public class TreeNode + { + public int? Id { get; set; } + public object Value { get; set; } + public int? Parent { get; set; } + public List Children { get; set; } = new List(); + + public TreeNode() + { + } + + public static TreeNode BuildTree(List nodes) + { + if (nodes == null) + { + throw new ArgumentNullException("nodes"); + } + return new TreeNode().BuildTreeI(nodes); + } + + private TreeNode BuildTreeI(List nodes) + { + if (nodes.Count == 0) { return this; } + + var children = FetchChildren(this, nodes).ToList(); + Children.AddRange(children); + RemoveChildren(this, nodes); + + for (int i = 0; i < children.Count; i++) + { + children[i] = children[i].BuildTreeI(nodes); + if (nodes.Count == 0) { break; } + } + + return this; + } + + public static IEnumerable FetchChildren(TreeNode root, List nodes) + { + return nodes.Where(n => n.Parent == root.Id); + } + + public static void RemoveChildren(TreeNode root, List nodes) + { + foreach (var node in root.Children) + { + nodes.Remove(node); + } + } + + public TreeNode FindID(int handle) + { + var search = this.Children.Where(a => a.Id == handle); + if (search.Count() > 0) + return search.First(); + + foreach (var child in this.Children) + { + var ans = child.FindID(handle); + if (ans != null) + return ans; + } + + return null; + } + } + + /* + var treeflat = Hwnd.windows + .OfType() + .Select(a=>new KeyValuePair((IntPtr)a.Key,(Hwnd)a.Value)) + .Where(a => a.Value.Mapped && a.Value.Visible && !a.Value.zombie) + .Select((a, idx) => new TreeNode() + { + Id = (int?)a.Key, + Value = a.Value, + Parent = (int?)(a.Value.parent?.Handle.ToInt64()) + }); + + var newtree = TreeNode.BuildTree(treeflat.ToList()); + + */ + + + static SKPaint paint = new SKPaint() { FilterQuality = SKFilterQuality.Low }; + + public static bool DrawOntoCanvas(IntPtr handle, SKCanvas Canvas, bool forcerender = false) + { + var hwnd = Hwnd.ObjectFromHandle(handle); + + var x = 0; + var y = 0; + var wasdrawn = false; + + XplatUI.driver.ClientToScreen(hwnd.client_window, ref x, ref y); + + var width = 0; + var height = 0; + var client_width = 0; + var client_height = 0; + + + if (hwnd.hwndbmp != null && hwnd.Mapped && hwnd.Visible && !hwnd.zombie) + { + // setup clip + var parent = hwnd; + /* Canvas.ClipRect( + SKRect.Create(0, 0, Screen.PrimaryScreen.Bounds.Width * 2, + Screen.PrimaryScreen.Bounds.Height * 2), (SKClipOperation)5); + */ + while (parent != null) + { + var xp = 0; + var yp = 0; + XplatUI.driver.ClientToScreen(parent.client_window, ref xp, ref yp); + + /* Canvas.ClipRect(SKRect.Create(xp, yp, parent.Width, parent.Height), + SKClipOperation.Intersect); + */ + parent = parent.parent; + } + + Monitor.Enter(XplatUIMine.paintlock); + try + { + if (hwnd.ClientWindow != hwnd.WholeWindow) + { + var frm = Control.FromHandle(hwnd.ClientWindow) as Form; + + Hwnd.Borders borders = new Hwnd.Borders(); + + if (frm != null) + { + borders = Hwnd.GetBorders(frm.GetCreateParams(), null); + /* + Canvas.ClipRect( + SKRect.Create(0, 0, Screen.PrimaryScreen.Bounds.Width * 2, + Screen.PrimaryScreen.Bounds.Height * 2), (SKClipOperation)5); + */ + } + + if (Canvas.DeviceClipBounds.Width > 0 && + Canvas.DeviceClipBounds.Height > 0) + { + if (hwnd.DrawNeeded || forcerender) + { + if (hwnd.hwndbmpNC != null) + Canvas.DrawImage(hwnd.hwndbmpNC, + new SKPoint(x - borders.left, y - borders.top), paint); + /* + Canvas.ClipRect( + SKRect.Create(x, y, hwnd.width - borders.right - borders.left, + hwnd.height - borders.top - borders.bottom), SKClipOperation.Intersect); + */ + if (hwnd.hwndbmp != null) + Canvas.DrawDrawable(hwnd.hwndbmp, + new SKPoint(x, y)); + + wasdrawn = true; + } + + hwnd.DrawNeeded = false; + } + else + { + return true; + } + } + else + { + if (Canvas.DeviceClipBounds.Width > 0 && + Canvas.DeviceClipBounds.Height > 0) + { + if (hwnd.DrawNeeded || forcerender) + { + if (hwnd.hwndbmp != null) + Canvas.DrawDrawable(hwnd.hwndbmp, + new SKPoint(x + 0, y + 0)); + + wasdrawn = true; + } + + hwnd.DrawNeeded = false; + /* + surface.Canvas.DrawText(Control.FromHandle(hwnd.ClientWindow).Name, + new SKPoint(x, y + 15), + new SKPaint() {Color = SKColor.Parse("55ffff00")}); + /*surface.Canvas.DrawText(hwnd.ClientWindow.ToString(), new SKPoint(x,y+15), + new SKPaint() {Color = SKColor.Parse("ffff00")});*/ + + } + else + { + return true; + } + } + } + catch (Exception ex) + { + Console.WriteLine(ex); + return true; + } + finally + { + Monitor.Exit(XplatUIMine.paintlock); + } + } + /* + var ctrl = Control.FromHandle(hwnd.ClientWindow); + + Canvas.DrawText(x + " " + y + " " + ctrl.Name + " " + hwnd.width + " " + hwnd.Height, x, y + 10, + new SKPaint() { Color = SKColors.Red }); + */ + if (hwnd.Mapped && hwnd.Visible) + { + IEnumerable children; + lock (Hwnd.windows) + children = Hwnd.windows.OfType() + .Where(hwnd2 => + { + var Key = (IntPtr)hwnd2.Key; + var Value = (Hwnd)hwnd2.Value; + if (Value.ClientWindow == Key && Value.Parent == hwnd && Value.Visible && + Value.Mapped && !Value.zombie) + return true; + return false; + }).Select(a => (Hwnd)a.Value).ToArray(); + + children = children.OrderBy((hwnd2) => + { + var info = XplatUIMine.GetInstance().GetZOrder(hwnd2.client_window); + if (info.top) + return 1000; + if (info.bottom) + return 0; + return 500; + + }); + + foreach (var child in children) + { + DrawOntoCanvas(child.ClientWindow, Canvas, true); + } + } + + return true; + } + +} + namespace tlogThumbnailHandler { public class tlogThumbnailHandler