CraftSynth.ImageEditor – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 using System;
2 using System.Diagnostics;
3 using System.Drawing;
4 using System.Drawing.Drawing2D;
5 using System.Globalization;
6 using System.Runtime.Serialization;
7 using System.Windows.Forms;
8  
9 namespace CraftSynth.ImageEditor
10 {
11 /// <summary>
12 /// Base class for all draw objects
13 /// </summary>
14 [Serializable]
15 public abstract class DrawObject : IComparable, IDisposable
16 {
17 #region Members
18 // Object properties
19 private bool selected;
20 private Color color;
21 private Color fillColor;
22 private bool filled;
23 private int penWidth;
24 private Pen drawpen;
25 private Brush drawBrush;
26 private DrawingPens.PenType _penType;
27 private LineCap _endCap;
28 private FillBrushes.BrushType _brushType;
29 private string tipText;
30  
31 // Last used property values (may be kept in the Registry)
32 private static Color lastUsedColor = Color.Black;
33 private static int lastUsedPenWidth = 1;
34  
35 // Entry names for serialization
36 private const string entryColor = "Color";
37 private const string entryPenWidth = "PenWidth";
38 private const string entryPen = "DrawPen";
39 private const string entryBrush = "DrawBrush";
40 private const string entryFillColor = "FillColor";
41 private const string entryFilled = "Filled";
42 private const string entryZOrder = "ZOrder";
43 private const string entryRotation = "Rotation";
44 private const string entryTipText = "TipText";
45  
46 private bool dirty;
47 private int _id;
48 private int _zOrder;
49 private int _rotation = 0;
50 private Point _center;
51  
52 private bool _disposed;
53 #endregion Members
54  
55 #region Properties
56 /// <summary>
57 /// Center of the object being drawn.
58 /// </summary>
59 public Point Center
60 {
61 get { return _center; }
62 set { _center = value; }
63 }
64  
65 /// <summary>
66 /// Rotation of the object in degrees. Negative is Left, Positive is Right.
67 /// </summary>
68 public int Rotation
69 {
70 get { return _rotation; }
71 set
72 {
73 if (value > 360)
74 _rotation = value - 360;
75 else if (value < -360)
76 _rotation = value + 360;
77 else
78 _rotation = value;
79 }
80 }
81  
82 /// <summary>
83 /// ZOrder is the order the objects will be drawn in - lower the ZOrder, the closer the to top the object is.
84 /// </summary>
85 public int ZOrder
86 {
87 get { return _zOrder; }
88 set { _zOrder = value; }
89 }
90  
91 /// <summary>
92 /// Object ID used for Undo Redo functions
93 /// </summary>
94 public int ID
95 {
96 get { return _id; }
97 set { _id = value; }
98 }
99  
100 /// <summary>
101 /// Set to true whenever the object changes
102 /// </summary>
103 public bool Dirty
104 {
105 get { return dirty; }
106 set { dirty = value; }
107 }
108  
109 /// <summary>
110 /// Draw object filled?
111 /// </summary>
112 public bool Filled
113 {
114 get { return filled; }
115 set { filled = value; }
116 }
117  
118 /// <summary>
119 /// Selection flag
120 /// </summary>
121 public bool Selected
122 {
123 get { return selected; }
124 set { selected = value; }
125 }
126  
127 /// <summary>
128 /// Fill Color
129 /// </summary>
130 public Color FillColor
131 {
132 get { return fillColor; }
133 set { fillColor = value; }
134 }
135  
136 /// <summary>
137 /// Border (line) Color
138 /// </summary>
139 public Color Color
140 {
141 get { return color; }
142 set { color = value; }
143 }
144  
145 /// <summary>
146 /// Pen width
147 /// </summary>
148 public int PenWidth
149 {
150 get { return penWidth; }
151 set { penWidth = value; }
152 }
153  
154 public FillBrushes.BrushType BrushType
155 {
156 get { return _brushType; }
157 set { _brushType = value; }
158 }
159  
160 /// <summary>
161 /// Brush used to paint object
162 /// </summary>
163 public Brush DrawBrush
164 {
165 get { return drawBrush; }
166 set { drawBrush = value; }
167 }
168  
169 public DrawingPens.PenType PenType
170 {
171 get { return _penType; }
172 set { _penType = value; }
173 }
174  
175 public LineCap EndCap
176 {
177 get { return _endCap; }
178 set { _endCap = value; }
179 }
180  
181 /// <summary>
182 /// Pen used to draw object
183 /// </summary>
184 public Pen DrawPen
185 {
186 get { return drawpen; }
187 set { drawpen = value; }
188 }
189  
190 /// <summary>
191 /// Number of handles
192 /// </summary>
193 public virtual int HandleCount
194 {
195 get { return 0; }
196 }
197 /// <summary>
198 /// Number of Connection Points
199 /// </summary>
200 public virtual int ConnectionCount
201 {
202 get { return 0; }
203 }
204 /// <summary>
205 /// Last used color
206 /// </summary>
207 public static Color LastUsedColor
208 {
209 get { return lastUsedColor; }
210 set { lastUsedColor = value; }
211 }
212  
213 /// <summary>
214 /// Last used pen width
215 /// </summary>
216 public static int LastUsedPenWidth
217 {
218 get { return lastUsedPenWidth; }
219 set { lastUsedPenWidth = value; }
220 }
221  
222 /// <summary>
223 /// Text to display when mouse is over an object
224 /// </summary>
225 public string TipText
226 {
227 get { return tipText; }
228 set { tipText = value; }
229 }
230  
231 #endregion Properties
232 #region Constructor
233  
234 protected DrawObject()
235 {
236 // ReSharper disable DoNotCallOverridableMethodsInConstructor
237 ID = GetHashCode();
238 // ReSharper restore DoNotCallOverridableMethodsInConstructor
239 }
240 #endregion
241  
242 #region Virtual Functions
243 /// <summary>
244 /// Clone this instance.
245 /// </summary>
246 public abstract DrawObject Clone();
247  
248 /// <summary>
249 /// Draw object
250 /// </summary>
251 /// <param name="g">Graphics object will be drawn on</param>
252 public virtual void Draw(Graphics g)
253 {
254 }
255  
256 #region Selection handle methods
257 /// <summary>
258 /// Get handle point by 1-based number
259 /// </summary>
260 /// <param name="handleNumber">1-based handle number to return</param>
261 /// <returns>Point where handle is located, if found</returns>
262 public virtual Point GetHandle(int handleNumber)
263 {
264 return new Point(0, 0);
265 }
266  
267 /// <summary>
268 /// Get handle rectangle by 1-based number
269 /// </summary>
270 /// <param name="handleNumber"></param>
271 /// <returns>Rectangle structure to draw the handle</returns>
272 public virtual Rectangle GetHandleRectangle(int handleNumber)
273 {
274 Point point = GetHandle(handleNumber);
275 // Take into account width of pen
276 return new Rectangle(point.X - (penWidth + 3), point.Y - (penWidth + 3), 7 + penWidth, 7 + penWidth);
277 }
278  
279 /// <summary>
280 /// Draw tracker for selected object
281 /// </summary>
282 /// <param name="g">Graphics to draw on</param>
283 public virtual void DrawTracker(Graphics g)
284 {
285 if (!Selected)
286 return;
287 SolidBrush brush = new SolidBrush(Color.Black);
288  
289 for (int i = 1; i <= HandleCount; i++)
290 {
291 g.FillRectangle(brush, GetHandleRectangle(i));
292 }
293 brush.Dispose();
294 }
295 #endregion Selection handle methods
296 #region Connection Point methods
297 /// <summary>
298 /// Get connection point by 0-based number
299 /// </summary>
300 /// <param name="connectionNumber">0-based connection number to return</param>
301 /// <returns>Point where connection is located, if found</returns>
302 public virtual Point GetConnection(int connectionNumber)
303 {
304 return new Point(0, 0);
305 }
306 /// <summary>
307 /// Get connectionPoint rectangle that defines the ellipse for the requested connection
308 /// </summary>
309 /// <param name="connectionNumber">0-based connection number</param>
310 /// <returns>Rectangle structure to draw the connection</returns>
311 public virtual Rectangle GetConnectionEllipse(int connectionNumber)
312 {
313 Point p = GetConnection(connectionNumber);
314 // Take into account width of pen
315 return new Rectangle(p.X - (penWidth + 3), p.Y - (penWidth + 3), 7 + penWidth, 7 + penWidth);
316 }
317 public virtual void DrawConnection(Graphics g, int connectionNumber)
318 {
319 SolidBrush b = new SolidBrush(System.Drawing.Color.Red);
320 Pen p = new Pen(System.Drawing.Color.Red, -1.0f);
321 g.DrawEllipse(p, GetConnectionEllipse(connectionNumber));
322 g.FillEllipse(b, GetConnectionEllipse(connectionNumber));
323 p.Dispose();
324 b.Dispose();
325 }
326 /// <summary>
327 /// Draws the ellipse for the connection handles on the object
328 /// </summary>
329 /// <param name="g">Graphics to draw on</param>
330 public virtual void DrawConnections(Graphics g)
331 {
332 if (!Selected)
333 return;
334 SolidBrush b = new SolidBrush(System.Drawing.Color.White);
335 Pen p = new Pen(System.Drawing.Color.Black, -1.0f);
336 for (int i = 0; i < ConnectionCount; i++)
337 {
338 g.DrawEllipse(p, GetConnectionEllipse(i));
339 g.FillEllipse(b, GetConnectionEllipse(i));
340 }
341 p.Dispose();
342 b.Dispose();
343 }
344 #endregion Connection Point methods
345 /// <summary>
346 /// Hit test to determine if object is hit.
347 /// </summary>
348 /// <param name="point">Point to test</param>
349 /// <returns> (-1) no hit
350 /// (0) hit anywhere
351 /// (1 to n) handle number</returns>
352 public virtual int HitTest(Point point)
353 {
354 return -1;
355 }
356  
357  
358 /// <summary>
359 /// Test whether point is inside of the object
360 /// </summary>
361 /// <param name="point">Point to test</param>
362 /// <returns>true if in object, false if not</returns>
363 protected virtual bool PointInObject(Point point)
364 {
365 return false;
366 }
367  
368  
369 public abstract Rectangle GetBounds(Graphics g);
370  
371  
372 /// <summary>
373 /// Get cursor for the handle
374 /// </summary>
375 /// <param name="handleNumber">handle number to return cursor for</param>
376 /// <returns>Cursor object</returns>
377 public virtual Cursor GetHandleCursor(int handleNumber)
378 {
379 return Cursors.Default;
380 }
381  
382 /// <summary>
383 /// Test whether object intersects with rectangle
384 /// </summary>
385 /// <param name="rectangle">Rectangle structure to test</param>
386 /// <returns>true if intersect, false if not</returns>
387 public virtual bool IntersectsWith(Rectangle rectangle)
388 {
389 return false;
390 }
391  
392 /// <summary>
393 /// Move object
394 /// </summary>
395 /// <param name="deltaX">Distance along X-axis: (+)=Right, (-)=Left</param>
396 /// <param name="deltaY">Distance along Y axis: (+)=Down, (-)=Up</param>
397 public virtual void Move(int deltaX, int deltaY)
398 {
399 }
400  
401 /// <summary>
402 /// Move handle to the point
403 /// </summary>
404 /// <param name="point">Point to Move Handle to</param>
405 /// <param name="handleNumber">Handle number to move</param>
406 public virtual void MoveHandleTo(Point point, int handleNumber)
407 {
408 }
409  
410 /// <summary>
411 /// Dump (for debugging)
412 /// </summary>
413 public virtual void Dump()
414 {
415 Trace.WriteLine("");
416 Trace.WriteLine(GetType().Name);
417 Trace.WriteLine("Selected = " + selected.ToString(CultureInfo.InvariantCulture));
418 }
419  
420 /// <summary>
421 /// Normalize object.
422 /// Call this function in the end of object resizing.
423 /// </summary>
424 public virtual void Normalize()
425 {
426 }
427  
428 // Public implementation of Dispose pattern callable by consumers.
429 public void Dispose()
430 {
431 this.Dispose(true);
432 GC.SuppressFinalize(this);
433 }
434  
435 // Protected implementation of Dispose pattern.
436 protected virtual void Dispose(bool disposing)
437 {
438 if (!this._disposed)
439 {
440 if (disposing)
441 {
442 // Free any managed objects here.
443 //
444 if (this.drawpen != null)
445 {
446 this.drawpen.Dispose();
447 }
448 if (this.drawBrush != null)
449 {
450 this.drawBrush.Dispose();
451 }
452 }
453  
454 // Free any unmanaged objects here.
455 //
456  
457 this._disposed = true;
458 }
459 }
460  
461 ~DrawObject()
462 {
463 this.Dispose(false);
464 }
465  
466 #region Save / Load methods
467 /// <summary>
468 /// Save object to serialization stream
469 /// </summary>
470 /// <param name="info">The data being written to disk</param>
471 /// <param name="orderNumber">Index of the Layer being saved</param>
472 /// <param name="objectIndex">Index of the object on the Layer</param>
473 public virtual void SaveToStream(SerializationInfo info, int orderNumber, int objectIndex)
474 {
475 info.AddValue(
476 String.Format(CultureInfo.InvariantCulture,
477 "{0}{1}-{2}",
478 entryColor, orderNumber, objectIndex),
479 Color.ToArgb());
480  
481 info.AddValue(
482 String.Format(CultureInfo.InvariantCulture,
483 "{0}{1}-{2}",
484 entryPenWidth, orderNumber, objectIndex),
485 PenWidth);
486  
487 info.AddValue(
488 string.Format(CultureInfo.InvariantCulture,
489 "{0}{1}-{2}",
490 entryPen, orderNumber, objectIndex),
491 PenType);
492  
493 info.AddValue(
494 string.Format(CultureInfo.InvariantCulture,
495 "{0}{1}-{2}",
496 entryBrush, orderNumber, objectIndex),
497 BrushType);
498  
499 info.AddValue(
500 String.Format(CultureInfo.InvariantCulture,
501 "{0}{1}-{2}",
502 entryFillColor, orderNumber, objectIndex),
503 FillColor.ToArgb());
504  
505 info.AddValue(
506 String.Format(CultureInfo.InvariantCulture,
507 "{0}{1}-{2}",
508 entryFilled, orderNumber, objectIndex),
509 Filled);
510  
511 info.AddValue(
512 String.Format(CultureInfo.InvariantCulture,
513 "{0}{1}-{2}",
514 entryZOrder, orderNumber, objectIndex),
515 ZOrder);
516  
517 info.AddValue(
518 String.Format(CultureInfo.InvariantCulture,
519 "{0}{1}-{2}",
520 entryRotation, orderNumber, objectIndex),
521 Rotation);
522  
523 info.AddValue(
524 String.Format(CultureInfo.InvariantCulture,
525 "{0}{1}-{2}",
526 entryTipText, orderNumber, objectIndex),
527 tipText);
528 }
529  
530 /// <summary>
531 /// Load object from serialization stream
532 /// </summary>
533 /// <param name="info">Data from disk to parse into an object</param>
534 /// <param name="orderNumber">Index of the layer object resides on</param>
535 /// <param name="objectData">Index of the object on the layer</param>
536 public virtual void LoadFromStream(SerializationInfo info, int orderNumber, int objectData)
537 {
538 int n = info.GetInt32(
539 String.Format(CultureInfo.InvariantCulture,
540 "{0}{1}-{2}",
541 entryColor, orderNumber, objectData));
542  
543 Color = Color.FromArgb(n);
544  
545 PenWidth = info.GetInt32(
546 String.Format(CultureInfo.InvariantCulture,
547 "{0}{1}-{2}",
548 entryPenWidth, orderNumber, objectData));
549  
550 PenType = (DrawingPens.PenType)info.GetValue(
551 String.Format(CultureInfo.InvariantCulture,
552 "{0}{1}-{2}",
553 entryPen, orderNumber, objectData),
554 typeof(DrawingPens.PenType));
555  
556 BrushType = (FillBrushes.BrushType)info.GetValue(
557 string.Format(CultureInfo.InvariantCulture,
558 "{0}{1}-{2}",
559 entryBrush, orderNumber, objectData),
560 typeof(FillBrushes.BrushType));
561  
562 n = info.GetInt32(
563 String.Format(CultureInfo.InvariantCulture,
564 "{0}{1}-{2}",
565 entryFillColor, orderNumber, objectData));
566  
567 FillColor = Color.FromArgb(n);
568  
569 Filled = info.GetBoolean(
570 String.Format(CultureInfo.InvariantCulture,
571 "{0}{1}-{2}",
572 entryFilled, orderNumber, objectData));
573  
574 ZOrder = info.GetInt32(
575 String.Format(CultureInfo.InvariantCulture,
576 "{0}{1}-{2}",
577 entryZOrder, orderNumber, objectData));
578  
579 Rotation = info.GetInt32(
580 String.Format(CultureInfo.InvariantCulture,
581 "{0}{1}-{2}",
582 entryRotation, orderNumber, objectData));
583  
584 tipText = info.GetString(String.Format(CultureInfo.InvariantCulture,
585 "{0}{1}-{2}",
586 entryTipText, orderNumber, objectData));
587  
588 // Set the Pen and the Brush, if defined
589 //if (PenType != DrawingPens.PenType.Generic)
590 // DrawPen = DrawingPens.SetCurrentPen(PenType);
591 if (BrushType != FillBrushes.BrushType.NoBrush)
592 DrawBrush = FillBrushes.SetCurrentBrush(BrushType);
593 }
594 #endregion Save/Load methods
595 #endregion Virtual Functions
596  
597 #region Other functions
598 /// <summary>
599 /// Initialization
600 /// </summary>
601 protected void Initialize()
602 {
603 }
604  
605 // private
606 /// <summary>
607 /// Copy fields from this instance to cloned instance drawObject.
608 /// Called from Clone functions of derived classes.
609 /// </summary>
610 /// <param name="drawObject">Object being cloned</param>
611 protected void FillDrawObjectFields(DrawObject drawObject)
612 {
613 drawObject.selected = selected;
614 drawObject.color = color;
615 drawObject.penWidth = penWidth;
616 drawObject._endCap = _endCap;
617 drawObject.ID = ID;
618 drawObject._brushType = _brushType;
619 drawObject._penType = _penType;
620 drawObject.drawBrush = drawBrush;
621 drawObject.drawpen = drawpen;
622 drawObject.filled = filled;
623 drawObject.fillColor = fillColor;
624 drawObject._rotation = _rotation;
625 drawObject._center = _center;
626 drawObject.tipText = tipText;
627 }
628 #endregion Other functions
629  
630 #region IComparable Members
631 /// <summary>
632 /// Returns (-1), (0), (+1) to represent the relative Z-order of the object being compared with this object
633 /// </summary>
634 /// <param name="obj">DrawObject that is compared to this object</param>
635 /// <returns> (-1) if the object is less (further back) than this object.
636 /// (0) if the object is equal to this object (same level graphically).
637 /// (1) if the object is greater (closer to the front) than this object.</returns>
638 public int CompareTo(object obj)
639 {
640 DrawObject d = obj as DrawObject;
641 int x = 0;
642 if (d != null)
643 if (d.ZOrder == ZOrder)
644 x = 0;
645 else if (d.ZOrder > ZOrder)
646 x = -1;
647 else
648 x = 1;
649  
650 return x;
651 }
652 #endregion IComparable Members
653 }
654 }