Forge
csharpdeeb25a2
1#nullable enable
2using Avalonia;
3using CascadeIDE.Cockpit.Graph.Layout;
4
5namespace CascadeIDE.Views.SkiaKit.Graph;
6
7/// <summary>Pointer hit-test для сцены графа (порядок отрисовки, масштаб viewport).</summary>
8public static class SkiaGraphSceneHitTesting
9{
10 /// <summary>Узел под точкой <paramref name="pointInLayoutSpace"/> или null.</summary>
11 public static GraphLayoutNode? FindNodeAt(GraphLayoutScene scene, Point pointInLayoutSpace)
12 {
13 GraphLayoutNode? best = null;
14 var bestDistance = double.MaxValue;
15
16 for (var i = scene.Nodes.Count - 1; i >= 0; i--)
17 {
18 var n = scene.Nodes[i];
19 if (!SkiaGraphSceneDrawing.HitTestNode(n, pointInLayoutSpace))
20 continue;
21
22 var dx = pointInLayoutSpace.X - n.Center.X;
23 var dy = pointInLayoutSpace.Y - n.Center.Y;
24 var distance = Math.Sqrt(dx * dx + dy * dy);
25 if (distance >= bestDistance)
26 continue;
27
28 bestDistance = distance;
29 best = n;
30 }
31
32 return best;
33 }
34
35 /// <summary>Координаты клика в control → логические координаты укладки.</summary>
36 public static Point MapControlPointToLayout(
37 Point controlPoint,
38 double controlWidth,
39 double controlHeight,
40 double layoutViewportWidth,
41 double layoutViewportHeight)
42 {
43 if (layoutViewportWidth > 0 && layoutViewportHeight > 0
44 && controlWidth > 0 && controlHeight > 0
45 && (Math.Abs(controlWidth - layoutViewportWidth) > 0.5
46 || Math.Abs(controlHeight - layoutViewportHeight) > 0.5))
47 {
48 return new Point(
49 controlPoint.X * layoutViewportWidth / controlWidth,
50 controlPoint.Y * layoutViewportHeight / controlHeight);
51 }
52
53 return controlPoint;
54 }
55}
56
View only · write via MCP/CIDE