CraftSynth.ImageEditor – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | using System; |
2 | using System.Collections; |
||
3 | using System.Drawing; |
||
4 | using System.Globalization; |
||
5 | using System.Reflection; |
||
6 | using System.Runtime.Serialization; |
||
7 | using System.Security.Permissions; |
||
8 | using System.Windows.Forms; |
||
9 | |||
10 | namespace CraftSynth.ImageEditor |
||
11 | { |
||
12 | /// <summary> |
||
13 | /// Collection of <see cref="Layer"/>s used to organize the drawing surface |
||
14 | /// </summary> |
||
15 | [Serializable] |
||
16 | public class Layers : ISerializable, IDisposable |
||
17 | { |
||
18 | // Contains the list of Layers |
||
19 | private ArrayList layerList; |
||
20 | |||
21 | private bool _isDirty; |
||
22 | |||
23 | /// <summary> |
||
24 | /// Dirty is True if any graphic element in any Layer is dirty, else False |
||
25 | /// </summary> |
||
26 | public bool Dirty |
||
27 | { |
||
28 | get |
||
29 | { |
||
30 | if (_isDirty == false) |
||
31 | { |
||
32 | foreach (Layer l in layerList) |
||
33 | { |
||
34 | if (l.Dirty) |
||
35 | { |
||
36 | _isDirty = true; |
||
37 | break; |
||
38 | } |
||
39 | } |
||
40 | } |
||
41 | return _isDirty; |
||
42 | } |
||
43 | //set |
||
44 | //{ |
||
45 | // foreach (Layer l in layerList) |
||
46 | // l.Dirty = false; |
||
47 | // _isDirty = false; |
||
48 | //} |
||
49 | } |
||
50 | |||
51 | private const string entryCount = "LayerCount"; |
||
52 | private const string entryLayer = "LayerType"; |
||
53 | |||
54 | public Layers() |
||
55 | { |
||
56 | layerList = new ArrayList(); |
||
57 | } |
||
58 | |||
59 | /// <summary> |
||
60 | /// Returns the index of the Active Layer - only one Layer may be active at any one time |
||
61 | /// </summary> |
||
62 | public int ActiveLayerIndex |
||
63 | { |
||
64 | get |
||
65 | { |
||
66 | int i = 0; |
||
67 | foreach (Layer l in layerList) |
||
68 | { |
||
69 | if (l.IsActive) |
||
70 | break; |
||
71 | i++; |
||
72 | } |
||
73 | return i; |
||
74 | } |
||
75 | } |
||
76 | |||
77 | protected Layers(SerializationInfo info, StreamingContext context) |
||
78 | { |
||
79 | layerList = new ArrayList(); |
||
80 | |||
81 | int n = info.GetInt32(entryCount); |
||
82 | |||
83 | for (int i = 0; i < n; i++) |
||
84 | { |
||
85 | string typeName; |
||
86 | typeName = info.GetString( |
||
87 | String.Format(CultureInfo.InvariantCulture, |
||
88 | "{0}{1}", |
||
89 | entryLayer, i)); |
||
90 | |||
91 | object _layer; |
||
92 | _layer = Assembly.GetExecutingAssembly().CreateInstance(typeName); |
||
93 | ((Layer)_layer).LoadFromStream(info, i); |
||
94 | layerList.Add(_layer); |
||
95 | } |
||
96 | } |
||
97 | |||
98 | /// <summary> |
||
99 | /// Save object to serialization stream |
||
100 | /// </summary> |
||
101 | /// <param name="info"></param> |
||
102 | /// <param name="context"></param> |
||
103 | [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)] |
||
104 | public virtual void GetObjectData(SerializationInfo info, StreamingContext context) |
||
105 | { |
||
106 | info.AddValue(entryCount, layerList.Count); |
||
107 | |||
108 | int i = 0; |
||
109 | |||
110 | foreach (Layer l in layerList) |
||
111 | { |
||
112 | info.AddValue( |
||
113 | String.Format(CultureInfo.InvariantCulture, |
||
114 | "{0}{1}", |
||
115 | entryLayer, i), |
||
116 | l.GetType().FullName); |
||
117 | |||
118 | l.SaveToStream(info, i); |
||
119 | i++; |
||
120 | } |
||
121 | } |
||
122 | |||
123 | /// <summary> |
||
124 | /// Draw all objects contained in all visible layers |
||
125 | /// </summary> |
||
126 | /// <param name="g">Graphics object to draw on</param> |
||
127 | public void Draw(Graphics g) |
||
128 | { |
||
129 | foreach (Layer l in layerList) |
||
130 | { |
||
131 | if (l.IsVisible) |
||
132 | l.Draw(g); |
||
133 | } |
||
134 | } |
||
135 | |||
136 | /// <summary> |
||
137 | /// Clear all objects in the list |
||
138 | /// </summary> |
||
139 | /// <returns> |
||
140 | /// true if at least one object is deleted |
||
141 | /// </returns> |
||
142 | public bool Clear() |
||
143 | { |
||
144 | bool result = (layerList.Count > 0); |
||
145 | foreach (Layer l in layerList) |
||
146 | l.Graphics.Clear(); |
||
147 | |||
148 | if (layerList.Count > 0) |
||
149 | { |
||
150 | for (int i = layerList.Count - 1; i >= 0; i--) |
||
151 | { |
||
152 | if (layerList[i] != null) |
||
153 | { |
||
154 | ((DrawObject) layerList[i]).Dispose(); |
||
155 | } |
||
156 | layerList.RemoveAt(i); |
||
157 | } |
||
158 | } |
||
159 | // Create a default Layer since there must be at least one Layer at all times |
||
160 | CreateNewLayer("Default"); |
||
161 | |||
162 | // Set dirty flag based on result. Result is true only if at least one item was cleared and since the list is empty, there can be nothing dirty. |
||
163 | if (result) |
||
164 | _isDirty = false; |
||
165 | return result; |
||
166 | } |
||
167 | |||
168 | /// <summary> |
||
169 | /// Returns number layers in the collection - useful for for loops |
||
170 | /// </summary> |
||
171 | public int Count |
||
172 | { |
||
173 | get { return layerList.Count; } |
||
174 | } |
||
175 | |||
176 | /// <summary> |
||
177 | /// Allows iterating through the list of layers using a for loop |
||
178 | /// </summary> |
||
179 | /// <param name="index">the index of the layer to return</param> |
||
180 | /// <returns>the specified layer object</returns> |
||
181 | public Layer this[int index] |
||
182 | { |
||
183 | get |
||
184 | { |
||
185 | if (index < 0 || |
||
186 | index >= layerList.Count) |
||
187 | return null; |
||
188 | return (Layer)layerList[index]; |
||
189 | } |
||
190 | } |
||
191 | |||
192 | /// <summary> |
||
193 | /// Adds a new layer to the collection |
||
194 | /// </summary> |
||
195 | /// <param name="obj">The layer object to add</param> |
||
196 | public void Add(Layer obj) |
||
197 | { |
||
198 | layerList.Add(obj); |
||
199 | // insert to the top of z-order |
||
200 | //layerList.Insert(0, obj); |
||
201 | } |
||
202 | |||
203 | /// <summary> |
||
204 | /// Create a new layer at the head of the layers list and set it to Active and Visible. |
||
205 | /// </summary> |
||
206 | /// <param name="theName">The name to assign to the new layer</param> |
||
207 | public void CreateNewLayer(string theName) |
||
208 | { |
||
209 | // Deactivate the currently active Layer |
||
210 | if (layerList.Count > 0) |
||
211 | ((Layer)layerList[ActiveLayerIndex]).IsActive = false; |
||
212 | // Create new Layer, set it visible and active |
||
213 | Layer l = new Layer(); |
||
214 | l.IsVisible = true; |
||
215 | l.IsActive = true; |
||
216 | l.LayerName = theName; |
||
217 | // Initialize empty GraphicsList for future objects |
||
218 | l.Graphics = new GraphicsList(); |
||
219 | // Add to Layers collection |
||
220 | Add(l); |
||
221 | } |
||
222 | |||
223 | /// <summary> |
||
224 | /// Inactivate the active <see cref="Layer"/> by setting all layers to inactive. |
||
225 | /// Brute force approach |
||
226 | /// </summary> |
||
227 | public void InactivateAllLayers() |
||
228 | { |
||
229 | foreach (Layer l in layerList) |
||
230 | { |
||
231 | l.IsActive = false; |
||
232 | // Make sure nothing is selected on the currently active layer before switching layers. |
||
233 | if (l.Graphics != null) |
||
234 | l.Graphics.UnselectAll(); |
||
235 | } |
||
236 | } |
||
237 | |||
238 | /// <summary> |
||
239 | /// Makes the specified <see cref="Layer"/> invisible |
||
240 | /// </summary> |
||
241 | /// <param name="p">index of <see cref="Layer"/> to make invisible</param> |
||
242 | public void MakeLayerInvisible(int p) |
||
243 | { |
||
244 | if (p > -1 && |
||
245 | p < layerList.Count) |
||
246 | ((Layer)layerList[p]).IsVisible = false; |
||
247 | } |
||
248 | |||
249 | /// <summary> |
||
250 | /// Makes the specified <see cref="Layer"/> visible |
||
251 | /// </summary> |
||
252 | /// <param name="p">index of <see cref="Layer"/> to make visible</param> |
||
253 | public void MakeLayerVisible(int p) |
||
254 | { |
||
255 | if (p > -1 && |
||
256 | p < layerList.Count) |
||
257 | ((Layer)layerList[p]).IsVisible = true; |
||
258 | } |
||
259 | |||
260 | /// <summary> |
||
261 | /// Changes the active <see cref="Layer"/> to the one indicated |
||
262 | /// </summary> |
||
263 | /// <param name="p">index of the <see cref="Layer"/> to activate</param> |
||
264 | public void SetActiveLayer(int p) |
||
265 | { |
||
266 | //// If the current layer is the same as the layer we are switching to, then do nothing. |
||
267 | //if (ActiveLayerIndex == p) |
||
268 | // return; |
||
269 | |||
270 | // Ensure the index is valid |
||
271 | if (p > -1 && |
||
272 | p < layerList.Count) |
||
273 | { |
||
274 | // Make sure nothing is selected on the currently active layer before switching layers. |
||
275 | //if (((Layer)layerList[ActiveLayerIndex]).Graphics != null) |
||
276 | // ((Layer)layerList[ActiveLayerIndex]).Graphics.UnselectAll(); |
||
277 | //((Layer)layerList[ActiveLayerIndex]).IsActive = false; |
||
278 | |||
279 | ((Layer)layerList[p]).IsActive = true; |
||
280 | ((Layer)layerList[p]).IsVisible = true; |
||
281 | } |
||
282 | } |
||
283 | |||
284 | /// <summary> |
||
285 | /// Removes the specified <see cref="Layer"/> from the collection - deleting all graphic objects the <see cref="Layer"/> contains |
||
286 | /// </summary> |
||
287 | /// <param name="p">index of the <see cref="Layer"/> to remove</param> |
||
288 | public void RemoveLayer(int p) |
||
289 | { |
||
290 | if (ActiveLayerIndex == p) |
||
291 | { |
||
292 | MessageBox.Show("Cannot Remove the Active Layer"); |
||
293 | return; |
||
294 | } |
||
295 | if (layerList.Count == 1) |
||
296 | { |
||
297 | MessageBox.Show("There is only one Layer in this drawing! You Cannot Remove the Only Layer!"); |
||
298 | return; |
||
299 | } |
||
300 | // Ensure the index is valid |
||
301 | if (p > -1 && |
||
302 | p < layerList.Count) |
||
303 | { |
||
304 | ((Layer)layerList[p]).Graphics.Clear(); |
||
305 | layerList.RemoveAt(p); |
||
306 | } |
||
307 | } |
||
308 | |||
309 | // Public implementation of Dispose pattern callable by consumers. |
||
310 | public void Dispose() |
||
311 | { |
||
312 | this.Dispose(true); |
||
313 | GC.SuppressFinalize(this); |
||
314 | } |
||
315 | |||
316 | // Flag: Has Dispose already been called? |
||
317 | bool _disposed = false; |
||
318 | |||
319 | // Protected implementation of Dispose pattern. |
||
320 | protected virtual void Dispose(bool disposing) |
||
321 | { |
||
322 | if (!this._disposed) |
||
323 | { |
||
324 | |||
325 | if (disposing) |
||
326 | { |
||
327 | // Free any managed objects here. |
||
328 | // |
||
329 | if (layerList != null) |
||
330 | { |
||
331 | foreach (Layer layer in layerList) |
||
332 | { |
||
333 | if (layer != null) |
||
334 | { |
||
335 | layer.Dispose(); |
||
336 | } |
||
337 | } |
||
338 | } |
||
339 | } |
||
340 | |||
341 | // Free any unmanaged objects here. |
||
342 | // |
||
343 | |||
344 | this._disposed = true; |
||
345 | } |
||
346 | } |
||
347 | |||
348 | ~Layers() |
||
349 | { |
||
350 | this.Dispose(false); |
||
351 | } |
||
352 | } |
||
353 | } |