-
Notifications
You must be signed in to change notification settings - Fork 1.7k
/
Region.cs
137 lines (106 loc) · 4.34 KB
/
Region.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#nullable disable
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.Maui.Graphics;
namespace Microsoft.Maui.Controls
{
/// <include file="../../docs/Microsoft.Maui.Controls/Region.xml" path="Type[@FullName='Microsoft.Maui.Controls.Region']/Docs/*" />
public struct Region : IEquatable<Region>
{
// While Regions are currently rectangular, they could in the future be transformed into any shape.
// As such the internals of how it keeps shapes is hidden, so that future internal changes can occur to support shapes
// such as circles if required, without affecting anything else.
IReadOnlyList<Rect> Regions { get; }
readonly Thickness? _inflation;
Region(IList<Rect> positions) : this()
{
Regions = new ReadOnlyCollection<Rect>(positions);
}
Region(IList<Rect> positions, Thickness inflation) : this(positions)
{
_inflation = inflation;
}
public static Region FromRectangles(IEnumerable<Rect> rectangles)
{
var list = rectangles.ToList();
return new Region(list);
}
/// <include file="../../docs/Microsoft.Maui.Controls/Region.xml" path="//Member[@MemberName='FromLines']/Docs/*" />
public static Region FromLines(double[] lineHeights, double maxWidth, double startX, double endX, double startY)
{
var positions = new List<Rect>();
var endLine = lineHeights.Length - 1;
var lineHeightTotal = startY;
for (var i = 0; i <= endLine; i++)
if (endLine != 0) // MultiLine
{
if (i == 0) // First Line
positions.Add(new Rect(startX, lineHeightTotal, maxWidth - startX, lineHeights[i]));
else if (i != endLine) // Middle Line
positions.Add(new Rect(0, lineHeightTotal, maxWidth, lineHeights[i]));
else // End Line
positions.Add(new Rect(0, lineHeightTotal, endX, lineHeights[i]));
lineHeightTotal += lineHeights[i];
}
else // SingleLine
positions.Add(new Rect(startX, lineHeightTotal, endX - startX, lineHeights[i]));
return new Region(positions);
}
/// <include file="../../docs/Microsoft.Maui.Controls/Region.xml" path="//Member[@MemberName='Contains'][1]/Docs/*" />
public bool Contains(Point pt)
{
return Contains(pt.X, pt.Y);
}
/// <include file="../../docs/Microsoft.Maui.Controls/Region.xml" path="//Member[@MemberName='Contains'][2]/Docs/*" />
public bool Contains(double x, double y)
{
if (Regions == null)
return false;
for (int i = 0; i < Regions.Count; i++)
if (Regions[i].Contains(x, y))
return true;
return false;
}
/// <include file="../../docs/Microsoft.Maui.Controls/Region.xml" path="//Member[@MemberName='Deflate']/Docs/*" />
public Region Deflate()
{
if (_inflation == null)
return this;
return Inflate(_inflation.Value.Left * -1, _inflation.Value.Top * -1, _inflation.Value.Right * -1, _inflation.Value.Bottom * -1);
}
/// <include file="../../docs/Microsoft.Maui.Controls/Region.xml" path="//Member[@MemberName='Inflate'][1]/Docs/*" />
public Region Inflate(double size)
{
return Inflate(size, size, size, size);
}
/// <include file="../../docs/Microsoft.Maui.Controls/Region.xml" path="//Member[@MemberName='Inflate'][2]/Docs/*" />
public Region Inflate(double left, double top, double right, double bottom)
{
if (Regions == null)
return this;
Rect[] rectangles = new Rect[Regions.Count];
for (int i = 0; i < Regions.Count; i++)
{
var region = Regions[i];
region.Top -= top;
region.Left -= left;
region.Width += right + left;
region.Height += bottom + top;
rectangles[i] = region;
}
var inflation = new Thickness(_inflation == null ? left : left + _inflation.Value.Left,
_inflation == null ? top : top + _inflation.Value.Top,
_inflation == null ? right : right + _inflation.Value.Right,
_inflation == null ? bottom : bottom + _inflation.Value.Bottom);
return new Region(rectangles, inflation);
}
public bool Equals(Region other) =>
Regions == other.Regions && _inflation == other._inflation;
public override bool Equals(object obj) => obj is Region other && Equals(other);
public override int GetHashCode() => Regions.GetHashCode() ^ _inflation?.GetHashCode() ?? 0;
public static bool operator ==(Region left, Region right) => left.Equals(right);
public static bool operator !=(Region left, Region right) => !(left == right);
}
}