| 1 | #nullable enable |
| 2 | using Avalonia; |
| 3 | using Avalonia.Media; |
| 4 | using CascadeIDE.Cockpit.Graph.Layout; |
| 5 | |
| 6 | namespace CascadeIDE.Views.SkiaKit.Graph; |
| 7 | |
| 8 | public static partial class SkiaGraphSceneDrawing |
| 9 | { |
| 10 | /// <summary>Овал вокруг узлов одного <see cref="GraphLayoutNode.LoopGroupId"/> (цикл while/for/foreach/do).</summary> |
| 11 | private static void DrawLoopGroupOutlines(DrawingContext context, GraphLayoutScene scene, SkiaGraphVisualTheme theme) |
| 12 | { |
| 13 | if (scene.Presentation != GraphLayoutPresentation.CodeControlFlow || scene.Nodes.Count == 0) |
| 14 | return; |
| 15 | |
| 16 | if (theme.LoopEdgePen.Brush is not SolidColorBrush scb) |
| 17 | return; |
| 18 | |
| 19 | var loopColor = scb.Color; |
| 20 | var stroke = new SolidColorBrush( |
| 21 | Color.FromArgb((byte)Math.Clamp((int)(loopColor.A * 0.28), 16, 72), loopColor.R, loopColor.G, loopColor.B)); |
| 22 | var dashPen = new Pen(stroke, 1.0) { DashStyle = new DashStyle([6, 5], 0) }; |
| 23 | |
| 24 | foreach (var g in scene.Nodes |
| 25 | .Where(n => n.LoopGroupId > 0) |
| 26 | .GroupBy(n => n.LoopGroupId!.Value)) |
| 27 | { |
| 28 | var nodes = g.ToList(); |
| 29 | if (nodes.Count < 2) |
| 30 | continue; |
| 31 | |
| 32 | var minX = double.PositiveInfinity; |
| 33 | var minY = double.PositiveInfinity; |
| 34 | var maxX = double.NegativeInfinity; |
| 35 | var maxY = double.NegativeInfinity; |
| 36 | foreach (var n in nodes) |
| 37 | { |
| 38 | var rEff = n.Shape == GraphNodeShape.Condition ? n.Radius * 1.08 : n.Radius; |
| 39 | minX = Math.Min(minX, n.Center.X - rEff); |
| 40 | maxX = Math.Max(maxX, n.Center.X + rEff); |
| 41 | minY = Math.Min(minY, n.Center.Y - rEff); |
| 42 | maxY = Math.Max(maxY, n.Center.Y + rEff); |
| 43 | } |
| 44 | |
| 45 | const double pad = 14; |
| 46 | var cx = (minX + maxX) * 0.5; |
| 47 | var cy = (minY + maxY) * 0.5; |
| 48 | var rx = (maxX - minX) * 0.5 + pad; |
| 49 | var ry = (maxY - minY) * 0.5 + pad; |
| 50 | if (rx < 6 || ry < 6) |
| 51 | continue; |
| 52 | |
| 53 | context.DrawEllipse(null, dashPen, new Point(cx, cy), rx, ry); |
| 54 | } |
| 55 | } |
| 56 | } |
| 57 | |