-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathShapeContainer.cs
More file actions
253 lines (224 loc) · 7.97 KB
/
ShapeContainer.cs
File metadata and controls
253 lines (224 loc) · 7.97 KB
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
using System;
using System.Collections.Generic;
using System.Drawing;
namespace ShapesGraphics
{
[Serializable]
class ShapeContainer
{
private List<Shape> shapesList;
// Events for min/max area size handling
// Note: Can't be serialized;
// Form needs to resubscribe after deserialization !
[field:NonSerialized]
public event Action<bool> tooSmallAreaEvent;
[field:NonSerialized]
public event Action<bool> tooLargeAreaEvent;
public const int MIN_AREA = 20;
public const int MAX_AREA = 1500000;
private double largestArea;
private double smallestArea;
public ShapeContainer(int size)
{
shapesList = new List<Shape>(size);
largestArea = 0;
smallestArea = MAX_AREA;
}
// Indexer
public Shape this[int index]
{
get
{
if (index < 0 || index >= shapesList.Count)
{
throw new IndexOutOfRangeException("MyMessage: Index out of range: " + index.ToString() +
"; Count is: " + shapesList.Count);
}
else
return shapesList[index];
}
set
{
if (index >= 0 && index < shapesList.Count)
shapesList[index] = value;
else
{
throw new IndexOutOfRangeException("MyMessage: Index out of range: " + index.ToString() +
"; Count is: " + shapesList.Count);
}
}
}
// Add an element
public void Add(Shape s)
{
shapesList.Add(s);
}
// Remove an element by index
public void Remove(int index)
{
if ((shapesList.Count >= 1) && (index >= 0))
shapesList.RemoveAt(index);
}
// Remove element
public bool Remove(Shape s)
{
return shapesList.Remove(s);
}
// Remove all / Clear all
public void RemoveAll()
{
shapesList.Clear();
}
public void RemoveLastInput()
{
int highOrder = 0;
int highIndex = 0;
for (int i = 0; i < shapesList.Count; i++ )
{
// find the shape with the highest input order...
if (shapesList[i].shapeInputOrder > highOrder)
{
highOrder = shapesList[i].shapeInputOrder;
highIndex = i;
}
}
Remove(highIndex);
}
// Resize all
public void ResizeAll(int percent)
{
for (int i = 0 ; i < shapesList.Count; i++)
{
shapesList[i].Resize(percent);
}
}
// Draw all
public void DrawAll(Graphics g)
{
largestArea = 0;
smallestArea = MAX_AREA;
for (int i = 0; i < shapesList.Count; i++)
{
// 1. Draw all
shapesList[i].Draw(g);
// 2. Update area info
if (shapesList[i].Area > largestArea)
largestArea = shapesList[i].Area;
if (shapesList[i].Area < smallestArea)
smallestArea = shapesList[i].Area;
}
// 3. Invoke event methods if needed,
// if area is too small or too large
if (tooSmallAreaEvent != null)
if (smallestArea <= MIN_AREA)
tooSmallAreaEvent(true);
else
tooSmallAreaEvent(false);
if (tooLargeAreaEvent != null)
if (largestArea >= MAX_AREA)
tooLargeAreaEvent(true);
else
tooLargeAreaEvent(false);
}
// Get count
public int Size()
{
return shapesList.Count;
}
// Sort Shapes by IComarer object
public void Sort(IComparer<Shape> sortObj)
{
shapesList.Sort(sortObj);
}
// Sort Shapes by size (area)
public void Sort()
{
shapesList.Sort();
}
public void SetShowType(ShapeType type)
{
for (int i = 0; i < shapesList.Count; i++)
{
switch (shapesList[i].GetType().Name)
{
case "Line":
{
if ((type & ShapeType.LINE) == ShapeType.LINE)
shapesList[i].Show = true;
else
shapesList[i].Show = false;
break;
}
case "Circle":
{
if ((type & ShapeType.CIRCLE) == ShapeType.CIRCLE)
shapesList[i].Show = true;
else
shapesList[i].Show = false;
break;
}
case "Rectangle":
{
if ((type & ShapeType.RECTANGLE) == ShapeType.RECTANGLE)
shapesList[i].Show = true;
else
shapesList[i].Show = false;
break;
}
case "FreeDraw":
{
if ((type & ShapeType.FREE) == ShapeType.FREE)
shapesList[i].Show = true;
else
shapesList[i].Show = false;
break;
}
}
}
}
public Shape GetShapeAtPosition(Point p)
{
int? index = null;
// Loop on list and find the first shape that contains point p
for (int i = shapesList.Count - 1; i >= 0; i--)
{
if ((shapesList[i].Contains(p)) && (shapesList[i].Show))
{
index = i;
break;
}
}
if (index.HasValue)
return shapesList[(int)index];
else
return null;
}
public void ChangeShapeInputOrder(Shape shape, int position)
{
// *** Send to back *** (position 0 is drawn first)
if (position == 0)
{
// Move all shapes (only those that are in a smaller position) 1 number up
for (int i = 0; i < shapesList.Count; i++)
{
if (shapesList[i].shapeInputOrder < shape.shapeInputOrder)
shapesList[i].shapeInputOrder++;
}
// Set this shape as the first one
shape.shapeInputOrder = 0;
}
// *** Bring to front *** (will be drawn last)
else if (position == 1)
{
// Move all shapes (only those that are in a larger position) 1 number down
for (int i = 0; i < shapesList.Count; i++)
{
if (shapesList[i].shapeInputOrder > shape.shapeInputOrder)
shapesList[i].shapeInputOrder--;
}
// Set this shape as the last one
shape.shapeInputOrder = Shape.InputOrder-1;
}
}
}
}