Skip to content

Commit c22eddb

Browse files
author
YCode
committed
feat: StepLine实现
1 parent 191ef4d commit c22eddb

File tree

5 files changed

+216
-4
lines changed

5 files changed

+216
-4
lines changed

YCode.Designer.Demo/Demo/Playground/Playground.xaml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,7 @@
3838
Mounting="OnMounting"
3939
Mounted="OnMounted"
4040
GridType="Dot"
41-
LineType="Straight"
42-
Orientation="Vertical"
41+
LineType="Step"
4342
ToolTemplate="{StaticResource ToolDataTemplate}"
4443
ItemContainerStyle="{StaticResource FluxoNodeStyle}"
4544
Source="{Binding Source}" />

YCode.Designer.Fluxo/Lines/FluxoLine.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ protected override void OnRender(DrawingContext drawingContext)
160160
if (p.HasValue)
161161
{
162162
drawingContext.DrawRectangle(Brushes.Orange, new Pen(Brushes.Transparent, 1),
163-
new Rect(p.Value.X-5, p.Value.Y-5, 10, 10));
163+
new Rect(p.Value.X - 5, p.Value.Y - 5, 10, 10));
164164
}
165165
}
166166

@@ -209,7 +209,11 @@ private FluxoLineParameter GetParameter(FluxoNode source, FluxoNode target)
209209
tp.Right = tpv.Right;
210210
}
211211

212-
return new FluxoLineParameter(sp, tp);
212+
return new FluxoLineParameter(sp, tp)
213+
{
214+
SourcePosition = FluxoLinePosition.Right,
215+
TargetPosition = FluxoLinePosition.Left
216+
};
213217
}
214218

215219
private DependencyObject? FindNode(string nodeId)

YCode.Designer.Fluxo/Lines/Impl/FluxoLineParameter.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,7 @@ public class FluxoLineParameter(FluxoPoint source, FluxoPoint target)
77

88
public FluxoPoint Source { get; set; } = source;
99
public FluxoPoint Target { get; set; } = target;
10+
11+
public FluxoLinePosition SourcePosition { get; set; } = FluxoLinePosition.None;
12+
public FluxoLinePosition TargetPosition { get; set; } = FluxoLinePosition.None;
1013
}
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
namespace YCode.Designer.Fluxo;
2+
3+
public class FluxoStepLine(FluxoDesigner designer) : FluxoBaseLine(LineType.Step, designer)
4+
{
5+
private readonly double _spacing = 0d;
6+
7+
public override void DrawLine(FluxoLineParameter @params, StreamGeometryContext context)
8+
{
9+
base.DrawLine(@params, context);
10+
11+
context.BeginFigure(this.Parameter.Start, false, false);
12+
context.LineTo(this.Points[0], true, true);
13+
context.LineTo(this.Points[1], true, true);
14+
context.LineTo(this.Points[2], true, true);
15+
context.LineTo(this.Points[3], true, true);
16+
context.LineTo(this.Parameter.End, true, true);
17+
}
18+
19+
protected override void OnHorizontal()
20+
{
21+
var points = GetLinePoints(this.Parameter.Source.Right, this.Parameter.Target.Left);
22+
23+
this.Points.AddRanage([points.P0, points.P1, points.P2, points.P3]);
24+
}
25+
26+
protected override void OnVertical()
27+
{
28+
throw new NotImplementedException();
29+
}
30+
31+
protected override void OnCross()
32+
{
33+
throw new NotImplementedException();
34+
}
35+
36+
private (Point P0, Point P1, Point P2, Point P3) GetLinePoints(Point source, Point target)
37+
{
38+
var sourceDir = GetConnectorDirection(this.Parameter.SourcePosition);
39+
var targetDir = GetConnectorDirection(this.Parameter.TargetPosition);
40+
41+
this.Parameter.Start = source + new Vector(_spacing * sourceDir.X, _spacing * sourceDir.Y);
42+
43+
this.Parameter.End = target + new Vector(_spacing * targetDir.X, _spacing * targetDir.Y);
44+
45+
var connectionDir = GetConnectionDirection(this.Parameter.Start, this.Parameter.SourcePosition, this.Parameter.End);
46+
47+
var horizontalConnection = connectionDir.X != 0;
48+
49+
if (IsOppositePosition(this.Parameter.SourcePosition, this.Parameter.TargetPosition))
50+
{
51+
var (p1, p2) = GetOppositePositionPoints();
52+
53+
return (this.Parameter.Start, p1, p2, this.Parameter.End);
54+
}
55+
56+
if (this.Parameter.SourcePosition == this.Parameter.TargetPosition)
57+
{
58+
var p = GetSamePositionPoint();
59+
return (this.Parameter.Start, p, p, this.Parameter.End);
60+
}
61+
62+
var isSameDir = horizontalConnection ? sourceDir.X == targetDir.Y : sourceDir.Y == targetDir.X;
63+
var startGreaterThanEnd = horizontalConnection ? this.Parameter.Start.Y > this.Parameter.End.Y : this.Parameter.Start.X > this.Parameter.End.X;
64+
65+
var positiveDir = horizontalConnection ? sourceDir.X == 1 : sourceDir.Y == 1;
66+
var shouldFlip = positiveDir
67+
? isSameDir ? !startGreaterThanEnd : startGreaterThanEnd
68+
: isSameDir
69+
? startGreaterThanEnd
70+
: !startGreaterThanEnd;
71+
72+
if (shouldFlip)
73+
{
74+
var sourceTarget = new Point(this.Parameter.Start.X, this.Parameter.End.Y);
75+
var targetSource = new Point(this.Parameter.End.X, this.Parameter.Start.Y);
76+
77+
var pf = horizontalConnection ? sourceTarget : targetSource;
78+
return (this.Parameter.Start, pf, pf, this.Parameter.End);
79+
}
80+
81+
var pp = GetSamePositionPoint();
82+
return (this.Parameter.Start, pp, pp, this.Parameter.End);
83+
84+
(Point P1, Point P2) GetOppositePositionPoints()
85+
{
86+
var center = this.Parameter.Start + (this.Parameter.End - this.Parameter.Start) / 2;
87+
88+
(Point P1, Point P2) verticalSplit = (new Point(center.X, this.Parameter.Start.Y), new Point(center.X, this.Parameter.End.Y));
89+
(Point P1, Point P2) horizontalSplit = (new Point(this.Parameter.Start.X, center.Y), new Point(this.Parameter.End.X, center.Y));
90+
91+
if (horizontalConnection)
92+
{
93+
// left to right / right to left
94+
return sourceDir.X == connectionDir.X ? verticalSplit : horizontalSplit;
95+
}
96+
97+
// top to bottom / bottom to top
98+
return sourceDir.Y == connectionDir.Y ? horizontalSplit : verticalSplit;
99+
}
100+
101+
Point GetSamePositionPoint()
102+
{
103+
var sourceTarget = new Point(this.Parameter.Start.X, this.Parameter.End.Y);
104+
var targetSource = new Point(this.Parameter.End.X, this.Parameter.Start.Y);
105+
106+
if (horizontalConnection)
107+
{
108+
return sourceDir.X == connectionDir.X ? targetSource : sourceTarget;
109+
}
110+
111+
return sourceDir.Y == connectionDir.Y ? sourceTarget : targetSource;
112+
}
113+
114+
static Point GetConnectionDirection(in Point source, FluxoLinePosition sourcePosition, in Point target)
115+
{
116+
return sourcePosition == FluxoLinePosition.Left || sourcePosition == FluxoLinePosition.Right
117+
? new Point(Math.Sign(target.X - source.X), 0)
118+
: new Point(0, Math.Sign(target.Y - source.Y));
119+
}
120+
121+
static Point GetConnectorDirection(FluxoLinePosition position)
122+
=> position switch
123+
{
124+
FluxoLinePosition.Top => new Point(0, -1),
125+
FluxoLinePosition.Left => new Point(-1, 0),
126+
FluxoLinePosition.Bottom => new Point(0, 1),
127+
FluxoLinePosition.Right => new Point(1, 0),
128+
_ => default,
129+
};
130+
131+
static bool IsOppositePosition(FluxoLinePosition sourcePosition, FluxoLinePosition targetPosition)
132+
{
133+
return sourcePosition == FluxoLinePosition.Left && targetPosition == FluxoLinePosition.Right
134+
|| sourcePosition == FluxoLinePosition.Right && targetPosition == FluxoLinePosition.Left
135+
|| sourcePosition == FluxoLinePosition.Top && targetPosition == FluxoLinePosition.Bottom
136+
|| sourcePosition == FluxoLinePosition.Bottom && targetPosition == FluxoLinePosition.Top;
137+
}
138+
}
139+
140+
public override Point GetPoint(double target)
141+
{
142+
var current = 0d;
143+
144+
var start = this.Points[0];
145+
146+
var length = this.GetLength();
147+
148+
var targetLength = length * target;
149+
150+
var prePoint = new Point(start.X, start.Y);
151+
152+
for (var i = 1; i < this.Points.Count; i++)
153+
{
154+
var pointToLength = Math.Sqrt(Math.Pow(prePoint.X - this.Points[i].X, 2) +
155+
Math.Pow(prePoint.Y - this.Points[i].Y, 2));
156+
157+
var distance = Point.Subtract(this.Points[i], prePoint).Length;
158+
159+
if (current + distance >= targetLength)
160+
{
161+
var extra = targetLength - current;
162+
163+
var factor = extra / distance;
164+
165+
return new Point(
166+
prePoint.X + (factor * this.Points[i].X - prePoint.X),
167+
prePoint.Y + (factor * this.Points[i].Y - prePoint.Y));
168+
}
169+
170+
prePoint = this.Points[i];
171+
172+
current += pointToLength;
173+
}
174+
175+
return prePoint;
176+
}
177+
178+
public override double GetLength()
179+
{
180+
var start = this.Points[0];
181+
182+
var length = 0d;
183+
184+
var prePoint = new Point(start.X, start.Y);
185+
186+
for (var i = 1; i < this.Points.Count; i++)
187+
{
188+
length += Math.Sqrt(Math.Pow(prePoint.X - this.Points[i].X, 2) +
189+
Math.Pow(prePoint.Y - this.Points[i].Y, 2));
190+
191+
prePoint = this.Points[i];
192+
}
193+
194+
return length;
195+
}
196+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace YCode.Designer.Fluxo;
2+
3+
public enum FluxoLinePosition
4+
{
5+
None,
6+
Left,
7+
Right,
8+
Top,
9+
Bottom
10+
}

0 commit comments

Comments
 (0)