private TextBox TryInterpretAsBox(List<Section> sections, bool oneSideAnchored, out bool potentialSelection)
{
potentialSelection = false;
// Conditions to detect a box (continued):
// 1. If one endpoint is anchored, 4 sides are required to confirm
// that the user really does want to create a (non-anchored) box.
// 2. There are 2 to 4 points.
// 3. The initial line is vertical or horizontal.
// 4. The rotation between all adjacent lines is the same, either 90
// or -90 degrees
// 5. If there are two lines, the endpoint must be down and right of
// the start point (this is also a potential selection box)
// 6. The dimensions of the box enclose the first three lines. The
// endpoint of the fourth line, if any, must not be far outside the
// box.
int minSides = oneSideAnchored ? 4 : 2;
if (sections.Count >= minSides && sections.Count <= 5)
{
int turn = TurnBetween(sections[0], sections[1]);
if ((sections[0].AngleMod8 & 1) == 0 && (turn == 2 || turn == 6))
{
for (int i = 1; i < sections.Count; i++)
if (TurnBetween(sections[i - 1], sections[i]) != turn)
return null;
VectorT dif;
if (sections.Count == 2)
potentialSelection = (dif = sections[1].EndSS.Sub(sections[0].StartSS)).X > 0 && dif.Y > 0;
if (sections.Count > 2 || potentialSelection)
{
var tolerance = Control.InputTransform.Transform(new VectorT(20, 20)).Abs();
var extents = sections.Take(3).Select(s => s.StartSS.To(s.EndSS).ToBoundingBox()).Union();
if (sections.Count < 4 || extents.Inflated(tolerance.X, tolerance.Y).Contains(sections[3].EndSS))
{
// Confirmed, we can interpret as a box
return new TextBox(extents) { Style = Control.BoxStyle };
}
}
}
}
return null;
}