CraftSynth.ImageEditor – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 using System;
2 using System.Collections;
3 using System.Collections.Generic;
4 using System.Drawing;
5 using System.Globalization;
6 using System.Reflection;
7 using System.Runtime.Serialization;
8 using System.Windows.Forms;
9  
10 namespace CraftSynth.ImageEditor
11 {
12 /// <summary>
13 /// List of graphic objects
14 /// </summary>
15 [Serializable]
16 public class GraphicsList: IDisposable
17 {
18 private ArrayList graphicsList;
19  
20 private bool _isDirty;
21  
22 public bool Dirty
23 {
24 get
25 {
26 if (_isDirty == false)
27 {
28 foreach (DrawObject o in graphicsList)
29 {
30 if (o.Dirty)
31 {
32 _isDirty = true;
33 break;
34 }
35 }
36 }
37 return _isDirty;
38 }
39 set
40 {
41 foreach (DrawObject o in graphicsList)
42 o.Dirty = false;
43 _isDirty = false;
44 }
45 }
46  
47 /// <summary>
48 /// Returns IEnumerable object which may be used for enumeration
49 /// of selected objects.
50 ///
51 /// Note: returning IEnumerable<DrawObject> breaks CLS-compliance
52 /// (assembly CLSCompliant = true is removed from AssemblyInfo.cs).
53 /// To make this program CLS-compliant, replace
54 /// IEnumerable<DrawObject> with IEnumerable. This requires
55 /// casting to object at runtime.
56 /// </summary>
57 /// <value></value>
58 public IEnumerable<DrawObject> Selection
59 {
60 get
61 {
62 foreach (DrawObject o in graphicsList)
63 {
64 if (o.Selected)
65 {
66 yield return o;
67 }
68 }
69 }
70 }
71  
72 private const string entryCount = "ObjectCount";
73 private const string entryType = "ObjectType";
74  
75 public GraphicsList()
76 {
77 graphicsList = new ArrayList();
78 }
79  
80 // Public implementation of Dispose pattern callable by consumers.
81 public void Dispose()
82 {
83 this.Dispose(true);
84 GC.SuppressFinalize(this);
85 }
86  
87 // Flag: Has Dispose already been called?
88 bool _disposed = false;
89  
90 // Protected implementation of Dispose pattern.
91 protected virtual void Dispose(bool disposing)
92 {
93 if (!this._disposed)
94 {
95 if (disposing)
96 {
97 // Free any managed objects here.
98 //
99 if (this.graphicsList != null)
100 {
101 for (int i = 0; i < this.graphicsList.Count; i++)
102 {
103 if (this.graphicsList[i] != null)
104 {
105 ((DrawObject) this.graphicsList[i]).Dispose();
106 }
107 }
108 }
109 }
110  
111 // Free any unmanaged objects here.
112 //
113  
114 this._disposed = true;
115 }
116 }
117  
118 ~GraphicsList()
119 {
120 this.Dispose(false);
121 }
122  
123 /// <summary>
124 /// Load the GraphicsList from data pulled from disk
125 /// </summary>
126 /// <param name="info">Data from disk</param>
127 /// <param name="orderNumber">Layer number to be loaded</param>
128 public void LoadFromStream(SerializationInfo info, int orderNumber)
129 {
130 graphicsList = new ArrayList();
131  
132 // Get number of DrawObjects in this GraphicsList
133 int numberObjects = info.GetInt32(
134 String.Format(CultureInfo.InvariantCulture,
135 "{0}{1}",
136 entryCount, orderNumber));
137  
138 for (int i = 0; i < numberObjects; i++)
139 {
140 string typeName;
141 typeName = info.GetString(
142 String.Format(CultureInfo.InvariantCulture,
143 "{0}{1}",
144 entryType, i));
145  
146 object drawObject;
147 drawObject = Assembly.GetExecutingAssembly().CreateInstance(
148 typeName);
149  
150 // Let the Draw Object load itself
151 ((DrawObject)drawObject).LoadFromStream(info, orderNumber, i);
152  
153 graphicsList.Add(drawObject);
154 }
155 }
156  
157 /// <summary>
158 /// Save GraphicsList to the stream
159 /// </summary>
160 /// <param name="info">Stream to place the GraphicsList into</param>
161 /// <param name="orderNumber">Layer Number the List is on</param>
162 public void SaveToStream(SerializationInfo info, int orderNumber)
163 {
164 // First store the number of DrawObjects in the list
165 info.AddValue(
166 String.Format(CultureInfo.InvariantCulture,
167 "{0}{1}",
168 entryCount, orderNumber),
169 graphicsList.Count);
170 // Next save each individual object
171 int i = 0;
172 foreach (DrawObject o in graphicsList)
173 {
174 info.AddValue(
175 String.Format(CultureInfo.InvariantCulture,
176 "{0}{1}",
177 entryType, i),
178 o.GetType().FullName);
179 // Let each object save itself
180 o.SaveToStream(info, orderNumber, i);
181 i++;
182 }
183 }
184 /// <summary>
185 /// Draw all the visible objects in the List
186 /// </summary>
187 /// <param name="g">Graphics to draw on</param>
188 public void Draw(Graphics g)
189 {
190 int numberObjects = graphicsList.Count;
191  
192 // Enumerate list in reverse order
193 // to get first object on the top
194 //graphicsList.Sort();
195 for (int i = numberObjects - 1; i >= 0; i--)
196 {
197 DrawObject o;
198 o = (DrawObject)graphicsList[i];
199 // Only draw objects that are visible
200 if (o.IntersectsWith(Rectangle.Round(g.ClipBounds)))
201 o.Draw(g);
202  
203 if (o.Selected)
204 o.DrawTracker(g);
205 }
206 }
207  
208 /// <summary>
209 /// Clear all objects in the list
210 /// </summary>
211 /// <returns>
212 /// true if at least one object is deleted
213 /// </returns>
214 public bool Clear()
215 {
216 bool result = (graphicsList.Count > 0);
217 if (graphicsList.Count > 0)
218 {
219 for (int i = graphicsList.Count - 1; i >= 0; i--)
220 {
221 if (graphicsList[i] != null)
222 {
223 ((DrawObject) graphicsList[i]).Dispose();
224 }
225 graphicsList.RemoveAt(i);
226 }
227 }
228 // 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.
229 if (result)
230 _isDirty = false;
231 return result;
232 }
233  
234 /// <summary>
235 /// Count and this [nIndex] allow to read all graphics objects
236 /// from GraphicsList in the loop.
237 /// </summary>
238 public int Count
239 {
240 get { return graphicsList.Count; }
241 }
242 /// <summary>
243 /// Allow accessing Draw Objects by index
244 /// </summary>
245 /// <param name="index">0-based index to retrieve</param>
246 /// <returns>Selected DrawObject</returns>
247 public DrawObject this[int index]
248 {
249 get
250 {
251 if (index < 0 ||
252 index >= graphicsList.Count)
253 return null;
254  
255 return (DrawObject)graphicsList[index];
256 }
257 }
258  
259 /// <summary>
260 /// SelectedCount and GetSelectedObject allow to read
261 /// selected objects in the loop
262 /// </summary>
263 public int SelectionCount
264 {
265 get
266 {
267 int n = 0;
268  
269 foreach (DrawObject o in graphicsList)
270 {
271 if (o.Selected)
272 n++;
273 }
274  
275 return n;
276 }
277 }
278  
279 public DrawObject GetSelectedObject(int index)
280 {
281 int n = -1;
282  
283 foreach (DrawObject o in graphicsList)
284 {
285 if (o.Selected)
286 {
287 n++;
288  
289 if (n == index)
290 return o;
291 }
292 }
293  
294 return null;
295 }
296  
297 public void Add(DrawObject obj)
298 {
299 graphicsList.Sort();
300 foreach (DrawObject o in graphicsList)
301 o.ZOrder++;
302  
303 graphicsList.Insert(0, obj);
304 }
305 public void AddAsInitialGraphic(DrawObject obj)
306 {
307 graphicsList.Add(obj);
308  
309 }
310  
311 /// <summary>
312 /// Thanks to Member 3272353 for this fix to object ordering problem.
313 /// </summary>
314 /// <param name="obj"></param>
315 public void Append(DrawObject obj)
316 {
317 graphicsList.Add(obj);
318 }
319  
320 public void SelectInRectangle(Rectangle rectangle)
321 {
322 UnselectAll();
323  
324 foreach (DrawObject o in graphicsList)
325 {
326 if (o.IntersectsWith(rectangle))
327 o.Selected = true;
328 }
329 }
330  
331 public void UnselectAll()
332 {
333 foreach (DrawObject o in graphicsList)
334 {
335 o.Selected = false;
336 }
337 }
338  
339 public void SelectAll()
340 {
341 foreach (DrawObject o in graphicsList)
342 {
343 o.Selected = true;
344 }
345 }
346  
347 /// <summary>
348 /// Delete selected items
349 /// </summary>
350 /// <returns>
351 /// true if at least one object is deleted
352 /// </returns>
353 public bool DeleteSelection()
354 {
355 bool result = false;
356  
357 int n = graphicsList.Count;
358  
359 for (int i = n - 1; i >= 0; i--)
360 {
361 if (((DrawObject)graphicsList[i]).Selected)
362 {
363 graphicsList.RemoveAt(i);
364 result = true;
365 }
366 }
367 if (result)
368 _isDirty = true;
369 return result;
370 }
371  
372 /// <summary>
373 /// Delete last added object from the list
374 /// (used for Undo operation).
375 /// </summary>
376 public void DeleteLastAddedObject()
377 {
378 if (graphicsList.Count > 0)
379 {
380 graphicsList.RemoveAt(0);
381 }
382 }
383  
384 /// <summary>
385 /// Replace object in specified place.
386 /// Used for Undo.
387 /// </summary>
388 public void Replace(int index, DrawObject obj)
389 {
390 if (index >= 0 &&
391 index < graphicsList.Count)
392 {
393 graphicsList.RemoveAt(index);
394 graphicsList.Insert(index, obj);
395 }
396 }
397  
398 /// <summary>
399 /// Remove object by index.
400 /// Used for Undo.
401 /// </summary>
402 public void RemoveAt(int index)
403 {
404 graphicsList.RemoveAt(index);
405 }
406  
407 /// <summary>
408 /// Move selected items to front (beginning of the list)
409 /// </summary>
410 /// <returns>
411 /// true if at least one object is moved
412 /// </returns>
413 public bool MoveSelectionToFront()
414 {
415 int n;
416 int i;
417 ArrayList tempList;
418  
419 tempList = new ArrayList();
420 n = graphicsList.Count;
421  
422 // Read source list in reverse order, add every selected item
423 // to temporary list and remove it from source list
424 for (i = n - 1; i >= 0; i--)
425 {
426 if (((DrawObject)graphicsList[i]).Selected)
427 {
428 tempList.Add(graphicsList[i]);
429 graphicsList.RemoveAt(i);
430 }
431 }
432  
433 // Read temporary list in direct order and insert every item
434 // to the beginning of the source list
435 n = tempList.Count;
436  
437 for (i = 0; i < n; i++)
438 {
439 graphicsList.Insert(0, tempList[i]);
440 }
441 if (n > 0)
442 _isDirty = true;
443 return (n > 0);
444 }
445  
446 /// <summary>
447 /// Move selected items to back (end of the list)
448 /// </summary>
449 /// <returns>
450 /// true if at least one object is moved
451 /// </returns>
452 public bool MoveSelectionToBack()
453 {
454 int n;
455 int i;
456 ArrayList tempList;
457  
458 tempList = new ArrayList();
459 n = graphicsList.Count;
460  
461 // Read source list in reverse order, add every selected item
462 // to temporary list and remove it from source list
463 for (i = n - 1; i >= 0; i--)
464 {
465 if (((DrawObject)graphicsList[i]).Selected)
466 {
467 tempList.Add(graphicsList[i]);
468 graphicsList.RemoveAt(i);
469 }
470 }
471  
472 // Read temporary list in reverse order and add every item
473 // to the end of the source list
474 n = tempList.Count;
475  
476 for (i = n - 1; i >= 0; i--)
477 {
478 graphicsList.Add(tempList[i]);
479 }
480 if (n > 0)
481 _isDirty = true;
482 return (n > 0);
483 }
484  
485 /// <summary>
486 /// Get properties from selected objects and fill GraphicsProperties instance
487 /// </summary>
488 /// <returns></returns>
489 private GraphicsProperties GetProperties()
490 {
491 GraphicsProperties properties = new GraphicsProperties();
492  
493 //int n = SelectionCount;
494  
495 //if (n < 1)
496 // return properties;
497  
498 //DrawObject o = GetSelectedObject(0);
499  
500 //int firstColor = o.Color.ToArgb();
501 //int firstPenWidth = o.PenWidth;
502  
503 //bool allColorsAreEqual = true;
504 //bool allWidthAreEqual = true;
505  
506 //for (int i = 1; i < n; i++)
507 //{
508 // if (GetSelectedObject(i).Color.ToArgb() != firstColor)
509 // allColorsAreEqual = false;
510  
511 // if (GetSelectedObject(i).PenWidth != firstPenWidth)
512 // allWidthAreEqual = false;
513 //}
514  
515 //if (allColorsAreEqual)
516 //{
517 // properties.ColorDefined = true;
518 // properties.Color = Color.FromArgb(firstColor);
519 //}
520  
521 //if (allWidthAreEqual)
522 //{
523 // properties.PenWidthDefined = true;
524 // properties.PenWidth = firstPenWidth;
525 //}
526  
527 return properties;
528 }
529  
530 /// <summary>
531 /// Apply properties for all selected objects
532 /// </summary>
533 private void ApplyProperties()
534 {
535 //foreach (DrawObject o in graphicsList)
536 //{
537 // if (o.Selected)
538 // {
539 // if (properties.ColorDefined)
540 // {
541 // o.Color = properties.Color;
542 // DrawObject.LastUsedColor = properties.Color;
543 // }
544  
545 // if (properties.PenWidthDefined)
546 // {
547 // o.PenWidth = properties.PenWidth;
548 // DrawObject.LastUsedPenWidth = properties.PenWidth;
549 // }
550 // }
551 //}
552 }
553  
554 /// <summary>
555 /// Show Properties dialog. Return true if list is changed
556 /// </summary>
557 /// <param name="parent"></param>
558 /// <returns></returns>
559 public bool ShowPropertiesDialog(IWin32Window parent)
560 {
561 if (SelectionCount < 1)
562 return false;
563  
564 GraphicsProperties properties = GetProperties();
565 PropertiesDialog dlg = new PropertiesDialog();
566 dlg.Properties = properties;
567  
568 if (dlg.ShowDialog(parent) !=
569 DialogResult.OK)
570 return false;
571  
572 ApplyProperties();
573  
574 return true;
575 }
576 }
577 }