home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2005 June (DVD) / DPPRO0605DVD.iso / Install / program files / Borland / BDS / 3.0 / Demos / Delphi.Net / CLR / Shapes / Shape.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  2004-10-22  |  6.4 KB  |  223 lines

  1. unit Shape;
  2. {*******************************************************************************
  3.   ShapesDemo
  4.   Written by David Clegg, davidclegg@optusnet.com.au.
  5.  
  6.   This unit contains the base Shape class used to render onto a GDI+ drawing
  7.   surface.
  8. *******************************************************************************}
  9.  
  10. interface
  11.  
  12. uses
  13.   System.Drawing, System.Drawing.Drawing2D, System.Collections;
  14.  
  15. type
  16.  
  17.   //Forward declaration
  18.   TShape = class;
  19.  
  20.   /// <summary>
  21.   /// Strongly typed collection of TShape objects.
  22.   /// </summary>
  23.   TShapes = class(CollectionBase)
  24.   private
  25.     function GetShape(Index: integer): TShape;
  26.     procedure SetShape(Index: integer; Value: TShape);
  27.   public
  28.     property Shape[Index: integer]: TShape read GetShape write SetShape; default;
  29.     function Add(pShape: TShape): integer;
  30.     function IndexOf(pShape: TShape): integer;
  31.     procedure Remove(pShape: TShape);
  32.     function Contains(pShape: TShape): boolean;
  33.     procedure Insert(pIndex: integer; pShape: TShape);
  34.   end;
  35.  
  36.     /// <summary>
  37.     /// Base class for all shapes to descend from. It implements the logic for
  38.     /// drawing an outline of the shape, and for filling the shape using the
  39.     /// specified brush. It implements the IDisposable interface as the canvas
  40.     /// reference needs to be disposed
  41.     /// Concrete classes need only implement the GetShape method which should
  42.     /// return a GraphicsPath instance representing the bounds of the shape.
  43.     /// As a contrast, some concrete classes may also implement alternative
  44.     /// methods for drawing the outline and filling the shape.
  45.     /// </summary>
  46.   TShape = class
  47.   private
  48.     FOldStartPoint: Point;
  49.     FOldEndPoint: Point;
  50.     FCanvas: Graphics;
  51.     FDisposed: boolean;
  52.     FStartPoint: Point;
  53.     FEndPoint: Point;
  54.     FDrawBrush: Brush;
  55.     procedure DoOutline(pPen: Pen; pStartPoint, pEndPoint: Point);
  56.     function GetRectangle: Rectangle;
  57.   protected
  58.     property Canvas: Graphics read FCanvas;
  59.         function GetShape(pStartPoint, pEndPoint: Point): GraphicsPath; virtual; abstract;
  60.     function DoGetRectangle(pStartPoint, pEndPoint: Point): Rectangle;
  61.   public
  62.     StartPoint: Point;
  63.     EndPoint: Point;
  64.     procedure Dispose;
  65.     procedure Draw(pStartPoint, pEndPoint: Point; pBrush: Brush); overload;
  66.     procedure Draw; overload;
  67.     procedure DrawOutline(pStartPoint, pEndPoint: Point);
  68.     property DrawBrush: Brush read FDrawBrush write FDrawBrush;
  69.     property Rectangle: System.Drawing.Rectangle read GetRectangle;
  70.     constructor Create(pCanvas: Graphics);
  71.     destructor Destroy; override;
  72.   end;
  73.  
  74. implementation
  75.  
  76. { TShapes }
  77. function TShapes.Add(pShape: TShape): integer;
  78. begin
  79.   Result := List.Add(pShape);
  80. end;
  81.  
  82. procedure TShapes.Remove(pShape: TShape);
  83. begin
  84.   List.Remove(pShape);
  85. end;
  86.  
  87. procedure TShapes.Insert(pIndex: integer; pShape: TShape);
  88. begin
  89.   List.Insert(pIndex, pShape);
  90. end;
  91.  
  92. function TShapes.IndexOf(pShape: TShape): integer;
  93. begin
  94.   Result := List.IndexOf(pShape);
  95. end;
  96.  
  97. function TShapes.Contains(pShape: TShape): boolean;
  98. begin
  99.   Result := List.Contains(pShape);
  100. end;
  101.  
  102. function TShapes.GetShape(Index: integer): TShape;
  103. begin
  104.   Result := List[Index] as TShape;
  105. end;
  106.  
  107. procedure TShapes.SetShape(Index: integer; Value: TShape);
  108. begin
  109.   List[Index] := Value;
  110. end;
  111.  
  112. { TShape }
  113. constructor TShape.Create(pCanvas: Graphics);
  114. begin
  115.   inherited Create;
  116.   FCanvas := pCanvas;
  117.   FDisposed := False;
  118.   FStartPoint := Point.Create(0, 0);
  119.   FEndPoint := Point.Create(0, 0);
  120. end;
  121.  
  122. /// <summary>
  123. /// Destructor is used to call .Dispose to ensure that fCanvas.Dispose
  124. /// is called if it hasn't already been done.
  125. /// </summary>
  126. destructor TShape.Destroy;
  127. begin
  128.   Dispose;
  129.   inherited;
  130. end;
  131.  
  132. /// <summary>
  133. /// Implement IDisposable.Dispose to ensure the fCanvas Graphics reference
  134. /// is explicitly disposed.
  135. /// </summary>
  136. procedure TShape.Dispose;
  137. begin
  138.   if not FDisposed then
  139.     FCanvas.Dispose;
  140.   FDisposed := True;
  141. end;
  142.  
  143. /// <summary>
  144. /// Draws a solid shape based on the startPoint and endPoint
  145. /// co-ordinates. Concrete classes must implement the GetShape method
  146. /// to determine the bounds for the shape.
  147. /// </summary>
  148. procedure TShape.Draw(pStartPoint, pEndPoint: Point; pBrush: Brush);
  149. begin
  150.   //Draw the shape
  151.   FCanvas.FillRegion(pBrush, Region.Create(GetShape(pStartPoint, pEndPoint)));
  152.  
  153.   //As the outline has a size of 1, it will still be visible along
  154.   //some points of the shape. Draw another outline which uses a pen
  155.   //the same color as the fill if it uses a SolidBrush, or one that
  156.   //uses the same color as the original outline for other brush types.
  157.   if pBrush is SolidBrush then
  158.     DoOutline(Pen.Create((SolidBrush(pBrush)).Color, 1), pStartPoint, pEndPoint)
  159.   else
  160.     DoOutline(Pen.Create(Color.Black, 1), pStartPoint, pEndPoint);
  161. end;
  162.  
  163. /// <summary>
  164. /// Draws a solid shape based on the StartPoint, EndPoint and Brush properties
  165. /// </summary>
  166. procedure TShape.Draw;
  167. begin
  168.   Draw(StartPoint, EndPoint, FDrawBrush);
  169. end;
  170.  
  171. /// <summary>
  172. /// Draws an outline of a shape based in the startPoint and endPoint
  173. /// co-ordinates. Concrete classes must implement the GetShape method
  174. /// to determine the bounds for the shape.
  175. /// </summary>
  176. procedure TShape.DrawOutline(pStartPoint, pEndPoint: Point);
  177. var
  178.   lPen: Pen;
  179. begin
  180.   //First erase the last outline
  181.   lPen := Pen.Create(Color.White, 1);
  182.   DoOutline(lPen, FOldStartPoint, FOldEndPoint);
  183.  
  184.   //Draw the new outline
  185.   lPen := Pen.Create(Color.Black, 1);
  186.   DoOutline(lPen, pStartPoint, pEndPoint);
  187.  
  188.   //Save the start and end points
  189.   FOldStartPoint := pStartPoint;
  190.   FOldEndPoint := pEndPoint;
  191. end;
  192.  
  193. /// <summary>
  194. /// Return a Rectangle structure to represent the bounds of the shape.
  195. /// </summary>
  196. function TShape.DoGetRectangle(pStartPoint, pEndPoint: Point): Rectangle;
  197. begin
  198.   Result := System.Drawing.Rectangle.FromLTRB(pStartPoint.X, pStartPoint.Y,
  199.     pEndPoint.X, pEndPoint.Y);
  200. end;
  201.  
  202. /// <summary>
  203. /// Return a Rectangle structure, based on FStartPoint and FEndPoint
  204. /// </summary>
  205. function TShape.GetRectangle: Rectangle;
  206. begin
  207.   Result := DoGetRectangle(FStartPoint, FEndPoint);
  208. end;
  209.  
  210. /// <summary>
  211. /// Draws the outline for the shape.
  212. /// </summary>
  213. procedure TShape.DoOutline(pPen: Pen; pStartPoint, pEndPoint: Point);
  214. var
  215.   lGraphicsPath: GraphicsPath;
  216. begin
  217.   lGraphicsPath := GetShape(pStartPoint, pEndPoint);
  218.   FCanvas.DrawPath(pPen, lGraphicsPath);
  219. end;
  220.  
  221. end.
  222.  
  223.