home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 September / Chip_2001-09_cd1.bin / zkuste / delphi / kolekce / d12345 / CHEMPLOT.ZIP / TPlot / Titles.pas < prev    next >
Pascal/Delphi Source File  |  2001-05-02  |  75KB  |  2,134 lines

  1. unit Titles;
  2.  
  3. {$I Plot.inc}
  4.  
  5. {-----------------------------------------------------------------------------
  6. The contents of this file are subject to the Q Public License
  7. ("QPL"); you may not use this file except in compliance
  8. with the QPL. You may obtain a copy of the QPL from 
  9. the file QPL.html in this distribution, derived from:
  10.  
  11. http://www.trolltech.com/products/download/freelicense/license.html
  12.  
  13. The QPL prohibits development of proprietary software. 
  14. There is a Professional Version of this software available for this. 
  15. Contact sales@chemware.hypermart.net for more information.
  16.  
  17. Software distributed under the QPL is distributed on an "AS IS" basis,
  18. WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the QPL for
  19. the specific language governing rights and limitations under the QPL.
  20.  
  21. The Original Code is: Titles.pas, released 12 September 2000.
  22.  
  23. The Initial Developer of the Original Code is Mat Ballard.
  24. Portions created by Mat Ballard are Copyright (C) 1999 Mat Ballard.
  25. Portions created by Microsoft are Copyright (C) 1998, 1999 Microsoft Corp.
  26. All Rights Reserved.
  27.  
  28. Contributor(s): Mat Ballard                 e-mail: mat.ballard@chemware.hypermart.net.
  29.  
  30. Last Modified: 02/25/2000
  31. Current Version: 2.00
  32.  
  33. You may retrieve the latest version of this file from:
  34.  
  35.         http://Chemware.hypermart.net/
  36.  
  37. This work was created with the Project JEDI VCL guidelines:
  38.  
  39.         http://www.delphi-jedi.org/Jedi:VCLVCL
  40.  
  41. in mind. 
  42.  
  43. Purpose:
  44. This unit contains many sub-components:
  45.      TRectangle
  46.      TBorder
  47.      TCaption
  48.      TLegend
  49.      TTitle
  50. that manage various screen areas and objects for TPlot.
  51.  
  52. Known Issues:
  53.       - This would normally be called Series, but TeeChart already uses that unit name.
  54. -----------------------------------------------------------------------------}
  55.  
  56. interface
  57.  
  58. uses
  59.   Classes, SysUtils,
  60. {$IFDEF WINDOWS}
  61.   Wintypes,
  62.   TrimStr,
  63.   Controls, Dialogs, Graphics,
  64. {$ENDIF}
  65. {$IFDEF WIN32}
  66.   Windows,
  67.   Controls, Dialogs, Graphics,
  68. {$ENDIF}
  69. {$IFDEF LINUX}
  70.   Types,
  71.   QControls, QDialogs, QGraphics,
  72. {$ENDIF}
  73.  
  74.   Misc, Plotdefs;
  75.  
  76. resourcestring  
  77.   sLegendDrawError = 'TLegend.Draw: ACanvas is nil !';
  78.  
  79. {const
  80.   STRING_DIV_SYMBOL = 3;}
  81. {The ratio of the width of the String portion of a Legend to the Symbol portion.}
  82.  
  83. type
  84.   TDirection = (drHorizontal, drVertical);
  85. {Screen objects are often Horizontal or Vertical.}
  86.  
  87.   TOrientation = (orRight, orLeft);
  88. {Other screen objects can be Left or Right aligned.}
  89.  
  90. {TRectangle *******************************************************************}
  91.   TRectangle = class(TPersistent)
  92. {TRectangle is extremely important to the functioning of TSciGraph.}
  93. {}
  94. {Not only is it used for a variety of objects, it is also the base class
  95.  of many on-screen objects: Axes, Titles, Captions, Legends, etc.}
  96. {}
  97. {As well as having the properties that one would expect for a rectangle,
  98.  it also has some properties that are useful to its various descendants:
  99.  Alignment, Name and Visibility to be precise.}
  100.   private
  101.     FAlignment: TAlignment;
  102.     FFireEvents: Boolean;
  103.     FLeft: Integer;
  104.     FTop: Integer;
  105.     FRight: Integer;
  106.     FBottom: Integer;
  107.     FName: String;
  108.     FOwner: TPersistent;
  109.     FTag: Longint;
  110.     FVisible: Boolean;
  111.  
  112. {Get functions for virtual properties:}
  113.     function GetHeight: Integer;
  114.     function GetWidth: Integer;
  115.  
  116.   protected
  117.     FOnChange: TNotifyEvent;
  118. {Events are normally private/published, but D1 does not allow descendants to
  119.  check the assignment of events: FOnChange is inaccessible, and OnChange
  120.  cannot be examined because it is a function.}
  121.  
  122.     function GetMidX: Integer;
  123.     function GetMidY: Integer;
  124.  
  125. {Set procedures that we may wish to override later:}
  126.     procedure SetLeft(Value: Integer); virtual;
  127. {This sets the Left screen position property. It also moves the Right by the
  128.  same amount, thereby preserving the Width. Ie: it moves the whole TRectangle.}
  129.     procedure SetMidX(Value: Integer); virtual;
  130. {This sets the MidX screen virtual position property. It thereby moves the Left and Right.}
  131.     procedure SetMidY(Value: Integer); virtual;
  132. {This sets the MidY screen virtual position property. It thereby moves the Top and Bottom.}
  133.     procedure SetTop(Value: Integer); virtual;
  134. {This sets the Top screen position property. It also moves the Bottom by the
  135.  same amount, thereby preserving the Height. Ie: it moves the whole TRectangle.}
  136.     procedure SetAlignment(Value: TAlignment);
  137.     procedure SetRight(Value: Integer);
  138.     procedure SetBottom(Value: Integer);
  139.     procedure SetVisible(Value: Boolean);
  140.  
  141. {Set procedures for virtual properties:}
  142.     procedure SetHeight(Value: Integer);
  143.     procedure SetWidth(Value: Integer);
  144.     procedure SetDeltaX(Value: Integer);
  145.     procedure SetDeltaY(Value: Integer);
  146.  
  147.     procedure DoHandleChange; virtual;
  148. {All Set methods call this to handle the OnChange logic.}
  149.   public
  150. {virtual write-only properties:}
  151.     property DeltaX: Integer write SetDeltaX;
  152. {This changes the Left and Right by DeltaX, thereby moving the TRectangle.
  153.  It is similar to getting then setting the Left property, but quicker.}
  154.     property DeltaY: Integer write SetDeltaY;
  155. {This changes the Top and Bottom by DeltaY, thereby moving the TRectangle.
  156.  It is similar to getting then setting the Top property, but quicker.}
  157.     property Owner: TPersistent read FOwner;
  158. {This is similar to TComponent.Owner: TComponent, except that:}
  159. {    1. it is a TPersistent;}
  160. {    2. this component is NOT freed automatically when the Owner is freed.}
  161.     property Tag: Longint read FTag write FTag;
  162. {The usual Tag property, as in TComponent.Tag}
  163. {}
  164. {However, DO NOT USE THIS PROPERTY !
  165.  It is used by TPlot to store the object type, and hence control the visible
  166.  behaviour of the TRectangle descendant.}
  167.  
  168.     Constructor Create(AOwner: TPersistent); virtual;
  169. {The standard constructor, where standard properties are set.}
  170.     Destructor Destroy; override;
  171. {The standard destructor, where the OnChange event is "freed".}
  172.  
  173.     {procedure Assign(Source: TPersistent); override;}
  174.     procedure AssignTo(Dest: TPersistent); override;
  175. {TRectangle's implementation of the standard Assign(To) method.}
  176.     function ClickedOn(iX, iY: Integer): Boolean; virtual;
  177. {Was this TRectangle clicked on ?}
  178.     procedure Outline(ACanvas: TCanvas);
  179. {Draws an Outline around this rectangle.}
  180.  
  181.   published
  182.     property Alignment: TAlignment read FAlignment write SetAlignment;
  183. {Can a rectangle have alignment ? Not really, but its descendants can !}
  184.     property FireEvents: Boolean read FFireEvents write FFireEvents;
  185. {Do we fire events in response to a geometry change ?
  186.  For the TCaption descendants, the answer is no, because they dance around
  187.  the screen with every repaint.}
  188.     property Name: String read FName write FName;
  189. {This is what is displayed when the user is offered a choice.
  190.  Eg: "Move the X-Axis Caption or the Bottom Border ?".}
  191.     property Left: Integer read FLeft write SetLeft;
  192. {This is the usual position property.}
  193.     property Top: Integer read FTop write SetTop;
  194. {This is the usual position property.}
  195.     property Right: Integer read FRight write SetRight;
  196. {This is the usual position property.}
  197.     property Bottom: Integer read FBottom write SetBottom;
  198. {This is the usual position property.}
  199.     Property Visible: Boolean read FVisible write SetVisible;
  200. {Is the Rectangle (or its descendants) visible ?}
  201.  
  202. {virtual properties:}
  203.     property Height: Integer read GetHeight write SetHeight;
  204. {The standard Height property.}
  205.     property Width: Integer read GetWidth write SetWidth;
  206. {The standard Width property.}
  207.     property MidX: Integer read GetMidX write SetMidX;
  208. {The X midpoint of the TRectangle.}
  209.     property MidY: Integer read GetMidY write SetMidY;
  210. {The Y midpoint of the TRectangle.}
  211.  
  212.     Property OnChange: TNotifyEvent read FOnChange write FOnChange;
  213. {The standard OnChange event (for geometry).}
  214.   end;
  215.  
  216. {TBorder **********************************************************************}
  217.   TBorder = class(TRectangle)
  218. {TBorder adds a third point to a TRectangle, hence creating a border.
  219.  The following diagram explains this:}
  220. {}
  221. {  Top, Left
  222.    ----------------------------------------====================
  223.    |                                       |                  +        |
  224.    |                                       |                  +        |
  225.    |                                       |                  +        |
  226.    |                                       |                  +        |
  227.    |                   .MidX,MidY          |<----RightGap---->+        |
  228.    |                                       |                  +        |
  229.    |                                       |                  +        |
  230.    |                                       |Right,Bottom      +    HeightEx
  231.    ----------------------------------------********************        |
  232.    +                   |                   *                  #        |
  233.    +                   |                   *                  #        |
  234.    +              BottomGap                *                  #        |
  235.    +                   |                   *                  #        |
  236.    +                   |                   *                  #        |
  237.    +=======================================*###################
  238.                                                                RightEx,BottomEx
  239.    <---------------------------WidthEx------------------------>
  240.    }
  241.   private
  242.     FRightEx: Integer;
  243.     FBottomEx: Integer;
  244.  
  245.     procedure SetRightEx(Value: Integer);
  246.     procedure SetBottomEx(Value: Integer);
  247. {Get functions for the new virtual properties:}
  248.     function GetRightGap: Integer;
  249.     function GetBottomGap: Integer;
  250.     function GetHeightEx: Integer;
  251.     function GetWidthEx: Integer;
  252. {Set procedures for the new virtual properties:}
  253.     procedure SetRightGap(Value: Integer);
  254.     procedure SetBottomGap(Value: Integer);
  255.     procedure SetHeightEx(Value: Integer);
  256.     procedure SetWidthEx(Value: Integer);
  257.  
  258.   protected
  259.     procedure SetLeft(Value: Integer); override;
  260. {Setting the Left also moves the Right and RightEx, thereby preserving the
  261.  Width and RightGap. Ie: it moves the whole TBorder.}
  262.     procedure SetTop(Value: Integer); override;
  263. {Setting the Top also moves the Bottom and BottomEx, thereby preserving the
  264.  Height and BottomGap. Ie: it moves the whole TBorder.}
  265.  
  266.   public
  267.     Constructor Create(AOwner: TPersistent); override;
  268. {The standard constructor, where standard properties are set.}
  269.  
  270.   published
  271.     property RightEx: Integer read FRightEx write SetRightEx;
  272. {The extreme right, to the right of Right.}
  273.     property BottomEx: Integer read FBottomEx write SetBottomEx;
  274. {The extreme Bottom, below Bottom.}
  275.  
  276. {the "virtual" properties:}
  277.     property RightGap: Integer read GetRightGap write SetRightGap;
  278. {The gap (or width) between the Right and RightEx.}
  279.     property BottomGap: Integer read GetBottomGap write SetBottomGap;
  280. {The gap (or height) between the Bottom and BottomEx.}
  281.     property HeightEx: Integer read GetHeightEx write SetHeightEx;
  282. {The total height between the Top and BottomEx.}
  283.     property WidthEx: Integer read GetWidthEx write SetWidthEx;
  284. {The total width between the Left and RightEx.}
  285.   end;
  286.  
  287. {TParallelogram ***************************************************************}
  288.   {TParallelogram = class(TRectangle)
  289. {A TCaption inherits the positional behaviour of TRectangle,
  290.  and adds angularity.
  291.     FAngle: Word;
  292.     FAngleRadians: Single;
  293.     FLength: Word;
  294.  
  295.     FEndX,
  296.     FEndY: Integer;
  297.     FSin,
  298.     FCos,
  299.     FSinM30,
  300.     FCosM30,
  301.     FSinP30,
  302.     FCosP30: Extended;
  303.   protected
  304.     procedure SetAngle(Value: Word);
  305.     procedure SetLength(Value: Word);
  306.  
  307.   public
  308.  
  309.   published
  310.  
  311.   end;}
  312.  
  313. {TCaption *********************************************************************}
  314.   TCaption = class(TRectangle)
  315. {A TCaption inherits the positional behaviour of TRectangle,
  316.  and adds a Caption and a Font.}
  317.   private
  318.     FCaption: String;
  319.     FFont: TFont;
  320.  
  321.     FOnCaptionChange: TNotifyEvent;
  322.  
  323.   protected
  324.     procedure CreateName; virtual;
  325. {This sets the name after the Caption is set.}
  326.     procedure SetCaption(Value: String); virtual;
  327. {This sets the Caption and calls CreateName.}
  328.     procedure SetFont(Value: TFont);
  329.   public
  330.     constructor Create(AOwner: TPersistent); override;
  331.     destructor Destroy; override;
  332.  
  333. {The standard constructor, where standard properties are set.}
  334.     {procedure Assign(Source: TPersistent); override;}
  335.     procedure AssignTo(Dest: TPersistent); override;
  336.  
  337.   published
  338.     property Caption: String read FCaption write SetCaption;
  339. {This is the text that is displayed on the screen.
  340.  Eg: "X-Axis". Setting the Caption also sets the Name:}
  341. {}
  342. { FName := FCaption + ' Caption';}
  343.     property Font: TFont read FFont write SetFont;
  344. {The font used to display the caption.}
  345.  
  346.     Property OnCaptionChange: TNotifyEvent read FOnCaptionChange write FOnCaptionChange;
  347. {Has the Caption changed ?}
  348.   end;
  349.  
  350. {TTitle ***********************************************************************}
  351.   TTitle = class(TCaption)
  352. {This is an extended TCaption that dances around the screen depending on
  353.  Alignment, Orientation and Direction, and Draws itself.}
  354.   private
  355.     FDirection : TDirection;
  356.     FOrientation: TOrientation;
  357.     FEnvelope: TRect;
  358.     FUnits: String;
  359.  
  360.     FFullCaption: String;
  361.  
  362.     procedure SetDirection(Value: TDirection);
  363.     procedure SetOrientation(Value: TOrientation);
  364.     procedure SetEnvelope(Value: TRect);
  365.     procedure SetUnits(Value: String);
  366.  
  367.   protected
  368.     procedure DoGeometry(ACanvas: TCanvas; TheText: String); dynamic;
  369. {This determines where the TTitle is exactly on the screen, depending on the
  370.  Envelope, Direction, Orientation and Alignment.}
  371.  
  372.     procedure SetCaption(Value: String); override;
  373. {This handles the tricky question of Caption and Units. If Value contains a
  374.  pair of brackets '()', then the contents of these brackets is taken to be the
  375.  Units. If it doesn't, then the FullCaption is constructed from Value and Units.}
  376.  
  377.   public
  378.     property Envelope: TRect read FEnvelope write SetEnvelope;
  379. {This is the region just outside which the Caption can appear.
  380.  Its exact position will depend on the Alignment, Direction and Orientation}
  381.     property FullCaption: String read FFullCaption;
  382. {This is a read-only property formed from the Caption and the Units.}
  383.  
  384.     constructor Create(AOwner: TPersistent); override;
  385. {The standard constructor, where standard properties are set.}
  386.  
  387.     procedure Draw(ACanvas: TCanvas);
  388.     {procedure Assign(Source: TPersistent); override;}
  389.     procedure AssignTo(Dest: TPersistent); override;
  390. {This Draws the TTitle on the given Canvas. It calls DoGeometry, and also
  391.  various API functions to create a vertical font if neccessary.}
  392.   published
  393.     property Units: String read FUnits write SetUnits;
  394. {These are the physical units, eg: mm, mV, seconds, etc, of the Axis.}
  395.     property Direction : TDirection read FDirection write SetDirection;
  396. {Is the Caption drawn Horizontal or Vertical ?}
  397.     property Orientation: TOrientation read FOrientation write SetOrientation;
  398. {Is the caption to the Left or Right of the Axis ?}
  399.   end;
  400.  
  401. {TLegend **********************************************************************}
  402.   TLegend = class(TRectangle)
  403. {This is an extended TCaption that dances around the screen depending on
  404.  Alignment, Orientation and Direction, and Draws itself.}
  405.   private
  406.     FCheckboxes: Boolean;
  407.     FDirection : TDirection;
  408.     FFont: TFont;
  409.     FFontHeight: Integer;
  410.     FStringWidth: Integer;
  411.     FCheckWidth: Integer;
  412.     FLineWidth: Integer;
  413.     FSeriesList: TList;
  414.  
  415.   protected
  416.     function GetItemWidth: Integer;
  417.     procedure SetCheckboxes(Value: Boolean);
  418.     procedure SetDirection(Value: TDirection);
  419.     procedure SetFont(Value: TFont);
  420.  
  421.     //procedure SetFontHeight(Value: Integer);
  422.     //procedure SetStringWidth(Value: Integer);
  423.  
  424.   public
  425.     property FontHeight: Integer read FFontHeight;
  426. {The height of the font.}
  427.     //property StringWidth: Integer read FStringWidth;
  428. {The width of the text portion of the Legend.}
  429.     //property SymbolWidth: Integer read GetSymbolWidth;
  430. {The width of the Symbol + Line portion of the Legend.}
  431. {It is 1/3rd of the StringWidth.}
  432.     property ItemWidth: Integer read GetItemWidth;
  433.  
  434.     constructor CreateList(AOwner: TPersistent; SeriesList: TList); virtual;
  435.     destructor Destroy; override;
  436.  
  437.     function GetHit(iX, iY: Integer; var TheRect: TRect): Integer;
  438. {The rectangle of the series name under the point iX, iY.}
  439.     procedure Draw(ACanvas: TCanvas; SeriesIncrement: Integer);
  440.  
  441.   published
  442.     property CheckBoxes: Boolean read FCheckBoxes write SetCheckBoxes;
  443. {Display Checkboxes ?}
  444.     property Direction : TDirection read FDirection write SetDirection;
  445. {Is the Legend drawn Horizontal or Vertical ?}
  446.     property Font: TFont read FFont write SetFont;
  447. {The font used to display the caption.}
  448.   end;
  449.  
  450. {TNote ************************************************************************}
  451.   TNote = class(TCaption)
  452.   private
  453.     FArrowLeft: Integer;
  454.     FArrowTop: Integer;
  455.     FArrowLeftReal: Single;
  456.     FArrowTopReal: Single;
  457.     FOwner: TPersistent; {ie: TPlot}
  458.     FLeftReal: Single;
  459.     FTopReal: Single;
  460.     //FOnNoteChange: TNotifyEvent;
  461.  
  462.     ArrowStartLeft: Integer;
  463.     ArrowStartTop: Integer;
  464.  
  465.   protected
  466.     procedure SetLeft(Value: Integer); override;
  467.     procedure SetTop(Value: Integer); override;
  468.     procedure SetArrowLeft(Value: Integer); virtual;
  469.     procedure SetArrowTop(Value: Integer); virtual;
  470.     procedure SetArrowLeftReal(Value: Single); virtual;
  471.     procedure SetArrowTopReal(Value: Single); virtual;
  472.     procedure SetLeftReal(Value: Single); virtual;
  473.     procedure SetTopReal(Value: Single); virtual;
  474.  
  475.   public
  476.     constructor Create(AOwner: TPersistent); override;
  477.     {destructor Destroy; override;}
  478.     procedure AssignTo(Dest: TPersistent); override;
  479.     {procedure Assign(Source: TPersistent); override;}
  480.     procedure Draw(ACanvas: TCanvas);
  481. {This Draws the TTitle on the given Canvas. It calls DoGeometry, and also
  482.  various API functions to create a vertical font if neccessary.}
  483.     procedure TracePointerTo(ACanvas: TCanvas; iX, iY: Integer);
  484.   published
  485.     property ArrowLeft: Integer read FArrowLeft write SetArrowLeft;
  486.     property ArrowTop: Integer read FArrowTop write SetArrowTop;
  487.     property ArrowLeftReal: Single read FArrowLeftReal write SetArrowLeftReal;
  488.     property ArrowTopReal: Single read FArrowTopReal write SetArrowTopReal;
  489.     property LeftReal: Single read FLeftReal write SetLeftReal;
  490.     property TopReal: Single read FTopReal write SetTopReal;
  491.     //Property OnNoteChange: TNotifyEvent read FOnNoteChange write FOnNoteChange;
  492.   end;
  493.  
  494. implementation
  495.  
  496. uses
  497.   Data, Plot;
  498.  
  499. {Constructor and Destructor:-------------------------------------------------}
  500. {------------------------------------------------------------------------------
  501.   Constructor: TRectangle.Create
  502.   Description: Standard Constructor for TRectangle
  503.        Author: Mat Ballard
  504.  Date created: 02/25/2000
  505. Date modified: 02/25/2000 by Mat Ballard
  506.       Purpose: initializes component and properties
  507.  Known Issues:
  508.  ------------------------------------------------------------------------------}
  509. Constructor TRectangle.Create(AOwner: TPersistent);
  510. begin
  511. {First call the ancestor:
  512.   inherited Create; - TObject.Create does nothing}
  513.  
  514.   FOwner := AOwner;
  515.  
  516. {we insert the default values that cannot be "defaulted":}
  517.   FAlignment := taCenter;
  518.   FLeft := 10;
  519.   FTop := 10;
  520.   SetRight(100);
  521.   SetBottom(100);
  522.   FVisible := TRUE;
  523. {global change event handler:}
  524.   FOnChange := nil;
  525. {we do fire events with a geometry change:}
  526.   FireEvents := TRUE;
  527. end;
  528.  
  529. {------------------------------------------------------------------------------
  530.    Destructor: TRectangle.Destroy
  531.   Description: standard destructor
  532.        Author: Mat Ballard
  533.  Date created: 02/25/2000
  534. Date modified: 02/25/2000 by Mat Ballard
  535.       Purpose: frees the OnChange event
  536.  Known Issues:
  537.  ------------------------------------------------------------------------------}
  538. Destructor TRectangle.Destroy;
  539. begin
  540.   FOnChange := nil;
  541. {then call ancestor:}
  542.   inherited Destroy;
  543. end;
  544.  
  545. {------------------------------------------------------------------------------
  546.     Procedure: TRectangle.Assign
  547.   Description: standard Assign method
  548.        Author: Mat Ballard
  549.  Date created: 07/06/2000
  550. Date modified: 07/06/2000 by Mat Ballard
  551.       Purpose: implements Assign
  552.  Known Issues:
  553.  ------------------------------------------------------------------------------}
  554. {procedure TRectangle.Assign(Source: TPersistent);
  555. begin
  556.   inherited Assign(Source);
  557.   FLeft := TRectangle(Source).Left;
  558.   FTop := TRectangle(Source).Top;
  559.   FRight := TRectangle(Source).Right;
  560.   FBottom := TRectangle(Source).Bottom;
  561. end;}
  562.  
  563. {------------------------------------------------------------------------------
  564.     Procedure: TRectangle.AssignTo
  565.   Description: standard AssignTo method
  566.        Author: Mat Ballard
  567.  Date created: 07/06/2000
  568. Date modified: 07/06/2000 by Mat Ballard
  569.       Purpose: implements AssignTo
  570.  Known Issues:
  571.  ------------------------------------------------------------------------------}
  572. procedure TRectangle.AssignTo(Dest: TPersistent);
  573. begin
  574. {we DON'T call the ancestor, because TPersistent.AssignTo simply throws an
  575.  exception:
  576.   inherited AssignTo(Dest);}
  577.   TRectangle(Dest).Left := FLeft;
  578.   TRectangle(Dest).Top := FTop;
  579.   TRectangle(Dest).Right := FRight;
  580.   TRectangle(Dest).Bottom := FBottom;
  581. end;
  582.  
  583. {Begin Set and Get Functions and Procedures----------------------------------}
  584. {Get Functions for virtual properties ---------------------------------------}
  585. {------------------------------------------------------------------------------
  586.      Function: TRectangle.GetHeight
  587.   Description: private property Get function
  588.        Author: Mat Ballard
  589.  Date created: 02/25/2000
  590. Date modified: 02/25/2000 by Mat Ballard
  591.       Purpose: Gets the Height, which is a virtual property
  592.  Known Issues:
  593.  ------------------------------------------------------------------------------}
  594. function TRectangle.GetHeight: Integer;
  595. begin
  596.   GetHeight := FBottom -  FTop;
  597. end;
  598.  
  599. {------------------------------------------------------------------------------
  600.      Function: TRectangle.GetWidth
  601.   Description: private property Get function
  602.        Author: Mat Ballard
  603.  Date created: 02/25/2000
  604. Date modified: 02/25/2000 by Mat Ballard
  605.       Purpose: Gets the Width, which is a virtual property
  606.  Known Issues:
  607.  ------------------------------------------------------------------------------}
  608. function TRectangle.GetWidth: Integer;
  609. begin
  610.   GetWidth := FRight - FLeft;
  611. end;
  612.  
  613. {------------------------------------------------------------------------------
  614.      Function: TRectangle.GetMidX
  615.   Description: private property Get function
  616.        Author: Mat Ballard
  617.  Date created: 02/25/2000
  618. Date modified: 02/25/2000 by Mat Ballard
  619.       Purpose: Gets the MidX, which is a virtual property
  620.  Known Issues:
  621.  ------------------------------------------------------------------------------}
  622. function TRectangle.GetMidX: Integer;
  623. begin
  624.   GetMidX := (FLeft + FRight) div 2;
  625. end;
  626.  
  627. {------------------------------------------------------------------------------
  628.      Function: TRectangle.GetMidY
  629.   Description: private property Get function
  630.        Author: Mat Ballard
  631.  Date created: 02/25/2000
  632. Date modified: 02/25/2000 by Mat Ballard
  633.       Purpose: Gets the MidY, which is a virtual property
  634.  Known Issues:
  635.  ------------------------------------------------------------------------------}
  636. function TRectangle.GetMidY: Integer;
  637. begin
  638.   GetMidY := (FTop + FBottom) div 2;
  639. end;
  640.  
  641. {Set Procedures -------------------------------------------------------------}
  642. {------------------------------------------------------------------------------
  643.     Procedure: TRectangle.SetAlignment
  644.   Description: private property Set procedure
  645.        Author: Mat Ballard
  646.  Date created: 02/25/2000
  647. Date modified: 02/25/2000 by Mat Ballard
  648.       Purpose: sets the Alignment
  649.  Known Issues:
  650.  ------------------------------------------------------------------------------}
  651. procedure TRectangle.SetAlignment(Value: TAlignment);
  652. begin
  653.   if (Value = FAlignment) then exit;
  654.  
  655.   FAlignment := Value;
  656.   DoHandleChange;
  657. end;
  658.  
  659. {------------------------------------------------------------------------------
  660.     Procedure: TRectangle.SetLeft
  661.   Description: protected property Set procedure
  662.        Author: Mat Ballard
  663.  Date created: 02/25/2000
  664. Date modified: 02/25/2000 by Mat Ballard
  665.       Purpose: sets the Left, which also moves the Right, thereby preserving the Width
  666.  Known Issues:
  667.  ------------------------------------------------------------------------------}
  668. procedure TRectangle.SetLeft(Value: Integer);
  669. begin
  670.   if (Value = FLeft) then exit;
  671.   FRight := FRight + (Value - FLeft);
  672.   FLeft := Value;
  673.   DoHandleChange;
  674. end;
  675.  
  676. {------------------------------------------------------------------------------
  677.     Procedure: TRectangle.SetTop
  678.   Description: protected property Set procedure
  679.        Author: Mat Ballard
  680.  Date created: 02/25/2000
  681. Date modified: 02/25/2000 by Mat Ballard
  682.       Purpose: sets the Top, which also also moves the Bottom, thereby preserving the Height
  683.  Known Issues:
  684.  ------------------------------------------------------------------------------}
  685. procedure TRectangle.SetTop(Value: Integer);
  686. begin
  687.   if (Value = FTop) then exit;
  688.   FBottom := FBottom + (Value - FTop);
  689.   FTop := Value;
  690.   DoHandleChange;
  691. end;
  692.  
  693. {------------------------------------------------------------------------------
  694.     Procedure: TRectangle.SetRight
  695.   Description: private property Set procedure
  696.        Author: Mat Ballard
  697.  Date created: 02/25/2000
  698. Date modified: 02/25/2000 by Mat Ballard
  699.       Purpose: sets the Right
  700.  Known Issues:
  701.  ------------------------------------------------------------------------------}
  702. procedure TRectangle.SetRight(Value: Integer);
  703. begin
  704.   if (Value = FRight) then exit;
  705.   FRight := Value;
  706.   DoHandleChange;
  707. end;
  708.  
  709. {------------------------------------------------------------------------------
  710.     Procedure: TRectangle.SetBottom
  711.   Description: private property Set procedure
  712.        Author: Mat Ballard
  713.  Date created: 02/25/2000
  714. Date modified: 02/25/2000 by Mat Ballard
  715.       Purpose: sets the Bottom
  716.  Known Issues:
  717.  ------------------------------------------------------------------------------}
  718. procedure TRectangle.SetBottom(Value: Integer);
  719. begin
  720.   if (Value = FBottom) then exit;
  721.   FBottom := Value;
  722.   DoHandleChange;
  723. end;
  724.  
  725. {Set procedures for virtual properties ---------------------------------------}
  726. {------------------------------------------------------------------------------
  727.     Procedure: TRectangle.SetHeight
  728.   Description: private property Set procedure
  729.        Author: Mat Ballard
  730.  Date created: 02/25/2000
  731. Date modified: 02/25/2000 by Mat Ballard
  732.       Purpose: sets the Height, a virtual property, by moving the Bottom
  733.  Known Issues:
  734.  ------------------------------------------------------------------------------}
  735. procedure TRectangle.SetHeight(Value: Integer);
  736. begin
  737.   if ((Value = 0) or (Value = GetHeight)) then exit;
  738.   Inc(FBottom, Value - (FBottom - FTop));
  739.   DoHandleChange;
  740. end;
  741.  
  742. {------------------------------------------------------------------------------
  743.     Procedure: TRectangle.SetWidth
  744.   Description: private property Set procedure
  745.        Author: Mat Ballard
  746.  Date created: 02/25/2000
  747. Date modified: 02/25/2000 by Mat Ballard
  748.       Purpose: sets the Width, a virtual property, by moving the Right
  749.  Known Issues:
  750.  ------------------------------------------------------------------------------}
  751. procedure TRectangle.SetWidth(Value: Integer);
  752. begin
  753.   if ((Value = 0) or (Value = GetWidth)) then exit;
  754.   Inc(FRight, Value - (FRight - FLeft));
  755.   DoHandleChange;
  756. end;
  757.  
  758. {------------------------------------------------------------------------------
  759.     Procedure: TRectangle.SetMidX
  760.   Description: private property Set procedure
  761.        Author: Mat Ballard
  762.  Date created: 02/25/2000
  763. Date modified: 02/25/2000 by Mat Ballard
  764.       Purpose: sets the MidX, a virtual property, by moving the Left and Right
  765.  Known Issues:
  766.  ------------------------------------------------------------------------------}
  767. procedure TRectangle.SetMidX(Value: Integer);
  768. var
  769.   OldMidX: Integer;
  770.   Change: Integer;
  771. begin
  772.   if (Value = GetMidX) then exit;
  773.   OldMidX := (FRight + FLeft) div 2;
  774.   Change := Value - OldMidX;
  775.   Inc(FLeft, Change);
  776.   Inc(FRight, Change);
  777.   DoHandleChange;
  778. end;
  779.  
  780. {------------------------------------------------------------------------------
  781.     Procedure: TRectangle.SetMidY
  782.   Description: private property Set procedure
  783.        Author: Mat Ballard
  784.  Date created: 02/25/2000
  785. Date modified: 02/25/2000 by Mat Ballard
  786.       Purpose: sets the MidY, a virtual property, by moving the Top and Bottom
  787.  Known Issues:
  788.  ------------------------------------------------------------------------------}
  789. procedure TRectangle.SetMidY(Value: Integer);
  790. var
  791.   OldMidY: Integer;
  792.   Change: Integer;
  793. begin
  794.   if (Value = GetMidY) then exit;
  795.   OldMidY := (FTop + FBottom) div 2;
  796.   Change := Value - OldMidY;
  797.   Inc(FTop, Change);
  798.   Inc(FBottom, Change);
  799.   DoHandleChange;
  800. end;
  801.  
  802. {------------------------------------------------------------------------------
  803.     Procedure: TRectangle.SetDeltaX
  804.   Description: private property Set procedure
  805.        Author: Mat Ballard
  806.  Date created: 02/25/2000
  807. Date modified: 02/25/2000 by Mat Ballard
  808.       Purpose: moves the Rectangle in the X direction, by changing the Left and Right
  809.  Known Issues:
  810.  ------------------------------------------------------------------------------}
  811. procedure TRectangle.SetDeltaX(Value: Integer);
  812. begin
  813.   if (Value = 0) then exit;
  814.   Inc(FLeft, Value);
  815.   Inc(FRight, Value);
  816.   DoHandleChange;
  817. end;
  818.  
  819. {------------------------------------------------------------------------------
  820.     Procedure: TRectangle.SetDeltaY
  821.   Description: private property Set procedure
  822.        Author: Mat Ballard
  823.  Date created: 02/25/2000
  824. Date modified: 02/25/2000 by Mat Ballard
  825.       Purpose: moves the Rectangle in the Y direction, by changing the Top and Bottom
  826.  Known Issues:
  827.  ------------------------------------------------------------------------------}
  828. procedure TRectangle.SetDeltaY(Value: Integer);
  829. begin
  830.   if (Value = 0) then exit;
  831.   Inc(FTop, Value);
  832.   Inc(FBottom, Value);
  833.   DoHandleChange;
  834. end;
  835.  
  836. {------------------------------------------------------------------------------
  837.     Procedure: TRectangle.SetVisible
  838.   Description: private property Set procedure
  839.        Author: Mat Ballard
  840.  Date created: 02/25/2000
  841. Date modified: 02/25/2000 by Mat Ballard
  842.       Purpose: sets the Visibility
  843.  Known Issues:
  844.  ------------------------------------------------------------------------------}
  845. procedure TRectangle.SetVisible(Value: Boolean);
  846. begin
  847.   if (FVisible = Value) then exit;
  848.   FVisible := Value;
  849.   DoHandleChange;
  850. end;
  851.  
  852. {------------------------------------------------------------------------------
  853.     Procedure: TRectangle.ClickedOn
  854.   Description: Was this TRectangle clicked on ?
  855.        Author: Mat Ballard
  856.  Date created: 01/22/2001
  857. Date modified: 01/22/2001 by Mat Ballard
  858.       Purpose: screen click management
  859.  Known Issues:
  860.  ------------------------------------------------------------------------------}
  861. function TRectangle.ClickedOn(iX, iY: Integer): Boolean;
  862. begin
  863.   if ((FLeft <= iX) and
  864.       (iX <= FRight) and
  865.       (FTop <= iY) and
  866.       (iY <= FBottom) and
  867.       (FVisible)) then
  868.     ClickedOn := TRUE
  869.    else
  870.     ClickedOn := FALSE; 
  871. end;
  872.  
  873. {------------------------------------------------------------------------------
  874.     Procedure: TRectangle.Outline
  875.   Description: Draws an Outline around this rectangle
  876.        Author: Mat Ballard
  877.  Date created: 01/22/2001
  878. Date modified: 01/22/2001 by Mat Ballard
  879.       Purpose: gives the user a guide to what they are moving with the mouse
  880.  Known Issues:
  881.  ------------------------------------------------------------------------------}
  882. procedure TRectangle.Outline(ACanvas: TCanvas);
  883. begin
  884.   ACanvas.Pen.Color := clBlack;
  885.   ACanvas.Pen.Mode := pmNotXOR;
  886.   ACanvas.Pen.Style := psDash;
  887.   ACanvas.Rectangle(FLeft, FTop, FRight, FBottom);
  888. end;
  889.  
  890. {------------------------------------------------------------------------------
  891.     Procedure: TRectangle.DoHandleChange
  892.   Description: private property Set procedure
  893.        Author: Mat Ballard
  894.  Date created: 02/27/2000
  895. Date modified: 02/27/2000 by Mat Ballard
  896.       Purpose: all Change Event firing passes through here
  897.  Known Issues:
  898.  ------------------------------------------------------------------------------}
  899. procedure TRectangle.DoHandleChange;
  900. begin
  901.   if (FireEvents and assigned(FOnChange) and FVisible) then OnChange(Self);
  902. end;
  903.  
  904. {TBorder Constructor and Destructor:-------------------------------------------}
  905. {------------------------------------------------------------------------------
  906.   Constructor: TBorder.Create
  907.   Description: Standard Constructor for TBorder
  908.        Author: Mat Ballard
  909.  Date created: 02/25/2000
  910. Date modified: 02/25/2000 by Mat Ballard
  911.       Purpose: initializes component and properties
  912.  Known Issues:
  913.  ------------------------------------------------------------------------------}
  914. Constructor TBorder.Create(AOwner: TPersistent);
  915. begin
  916. {First call the ancestor:}
  917.   inherited Create(AOwner);
  918.  
  919. {we insert the default values that cannot be "defaulted":}
  920.   FRightEx := Right + 10;
  921.   FBottomEx := Bottom + 10;
  922. end;
  923.  
  924. {Begin Get Functions --------------------------------------------------------}
  925. {the "virtual" properties:}
  926. {------------------------------------------------------------------------------
  927.      Function: TBorder.GetRightGap
  928.   Description: private property Get function
  929.        Author: Mat Ballard
  930.  Date created: 02/25/2000
  931. Date modified: 02/25/2000 by Mat Ballard
  932.       Purpose: Gets the Right Gap
  933.  Known Issues:
  934.  ------------------------------------------------------------------------------}
  935. function TBorder.GetRightGap: Integer;
  936. begin
  937.   GetRightGap := FRightEx - Right;
  938. end;
  939.  
  940. {------------------------------------------------------------------------------
  941.      Function: TBorder.GetBottomGap
  942.   Description: private property Get function
  943.        Author: Mat Ballard
  944.  Date created: 02/25/2000
  945. Date modified: 02/25/2000 by Mat Ballard
  946.       Purpose: Gets the Bottom Gap
  947.  Known Issues:
  948.  ------------------------------------------------------------------------------}
  949. function TBorder.GetBottomGap: Integer;
  950. begin
  951.   GetBottomGap := FBottomEx - Bottom;
  952. end;
  953.  
  954. {------------------------------------------------------------------------------
  955.      Function: TBorder.GetHeightEx
  956.   Description: private property Get function
  957.        Author: Mat Ballard
  958.  Date created: 02/25/2000
  959. Date modified: 02/25/2000 by Mat Ballard
  960.       Purpose: Gets the Total Height (Height + BottomGap)
  961.  Known Issues:
  962.  ------------------------------------------------------------------------------}
  963. function TBorder.GetHeightEx: Integer;
  964. begin
  965.   GetHeightEx := FBottomEx - Top;
  966. end;
  967.  
  968. {------------------------------------------------------------------------------
  969.      Function: TBorder.GetWidthEx
  970.   Description: private property Get function
  971.        Author: Mat Ballard
  972.  Date created: 02/25/2000
  973. Date modified: 02/25/2000 by Mat Ballard
  974.       Purpose: Gets the Total Width (Width + RightGap)
  975.  Known Issues:
  976.  ------------------------------------------------------------------------------}
  977. function TBorder.GetWidthEx: Integer;
  978. begin
  979.   GetWidthEx := FRightEx - Left;
  980. end;
  981.  
  982. {Begin Set Procedures -------------------------------------------------------}
  983. {------------------------------------------------------------------------------
  984.     Procedure: TBorder.SetLeft
  985.   Description: protected property Set procedure
  986.        Author: Mat Ballard
  987.  Date created: 02/25/2000
  988. Date modified: 02/25/2000 by Mat Ballard
  989.       Purpose: sets the Left, which DOES NOT move the Right and the RightEx, unlike TRectangle.SetLeft
  990.  Known Issues:
  991.  ------------------------------------------------------------------------------}
  992. procedure TBorder.SetLeft(Value: Integer);
  993. begin
  994.   if (Value = FLeft) then exit;
  995.   FLeft := Value;
  996.   DoHandleChange;
  997. end;
  998.  
  999. {------------------------------------------------------------------------------
  1000.     Procedure: TBorder.SetTop
  1001.   Description: protected property Set procedure
  1002.        Author: Mat Ballard
  1003.  Date created: 02/25/2000
  1004. Date modified: 02/25/2000 by Mat Ballard
  1005.       Purpose: sets the Top, which DOES NOT move the Bottom and BottomEx, unlike TRectangle.SetTop
  1006.  Known Issues:
  1007.  ------------------------------------------------------------------------------}
  1008. procedure TBorder.SetTop(Value: Integer);
  1009. begin
  1010.   if (Value = FTop) then exit;
  1011.   FTop := Value;
  1012.   DoHandleChange;
  1013. end;
  1014.  
  1015. {------------------------------------------------------------------------------
  1016.     Procedure: TBorder.SetRightEx
  1017.   Description: private property Set procedure
  1018.        Author: Mat Ballard
  1019.  Date created: 02/25/2000
  1020. Date modified: 02/25/2000 by Mat Ballard
  1021.       Purpose: sets the RightEx
  1022.       Comment: the design philosophy is that changing the RightEx changes the value
  1023.                of both Right, AND RightEX. If the user changes the RightEx, then that is about
  1024.                making the whole object bigger.
  1025.  Known Issues:
  1026.  ------------------------------------------------------------------------------}
  1027. procedure TBorder.SetRightEx(Value: Integer);
  1028. var
  1029.   Change: Integer;
  1030. begin
  1031.   if (Value = FRightEx) then exit;
  1032.   Change := Value - FRightEx;
  1033.   FRightEx := Value;
  1034.   Inc(FRight, Change);
  1035.   DoHandleChange;
  1036. end;
  1037.  
  1038. {------------------------------------------------------------------------------
  1039.     Procedure: TBorder.SetBottomEx
  1040.   Description: private property Set procedure
  1041.        Author: Mat Ballard
  1042.  Date created: 02/25/2000
  1043. Date modified: 02/25/2000 by Mat Ballard
  1044.       Purpose: sets the BottomEx
  1045.      Comments: See comments for SetRightEx
  1046.  Known Issues:
  1047.  ------------------------------------------------------------------------------}
  1048. procedure TBorder.SetBottomEx(Value: Integer);
  1049. var
  1050.   Change: Integer;
  1051. begin
  1052.   if (Value = FBottomEx) then exit;
  1053.   Change := Value - FBottomEx;
  1054.   FBottomEx := Value;
  1055.   Inc(FBottom, Change);
  1056.   DoHandleChange;
  1057. end;
  1058.  
  1059. {Begin Set Procedures for virtual properties --------------------------------}
  1060. {------------------------------------------------------------------------------
  1061.     Procedure: TBorder.SetRightGap
  1062.   Description: private property Set procedure
  1063.        Author: Mat Ballard
  1064.  Date created: 02/25/2000
  1065. Date modified: 02/25/2000 by Mat Ballard
  1066.       Purpose: sets the Right Gap
  1067.       Comment: the design philosophy is that changing the Right Gap changes the value
  1068.                of Right, NOT RightEX. If the user changes the gap, then that is about
  1069.                re-apportioning the available space (Left -> RightEx) between the Right Gap and
  1070.                the Width (Right-Left)
  1071.  Known Issues:
  1072.  ------------------------------------------------------------------------------}
  1073. procedure TBorder.SetRightGap(Value: Integer);
  1074. var
  1075.   OldRightGap, Change, NewRight: Integer;
  1076. begin
  1077.   if (Value <= 0) then exit;
  1078.   if (Value = GetRightGap) then exit;
  1079.  
  1080.   OldRightGap := FRightEx - Right;
  1081.   Change := Value - OldRightGap;
  1082.   NewRight := Right - Change;
  1083.  
  1084.   if (NewRight <= Left) then exit;
  1085.  
  1086.   Right := NewRight;
  1087.   DoHandleChange;
  1088. end;
  1089.  
  1090. {------------------------------------------------------------------------------
  1091.     Procedure: TBorder.SetBottomGap
  1092.   Description: private property Set procedure
  1093.        Author: Mat Ballard
  1094.  Date created: 02/25/2000
  1095. Date modified: 02/25/2000 by Mat Ballard
  1096.       Purpose: sets the Bottom Gap.
  1097.       Comment: See comments for SetRightGap
  1098.  Known Issues:
  1099.  ------------------------------------------------------------------------------}
  1100. procedure TBorder.SetBottomGap(Value: Integer);
  1101. var
  1102.   OldBottomGap, Change, NewBottom: Integer;
  1103. begin
  1104.   if (Value <= 0) then exit;
  1105.   if (Value = GetBottomGap) then exit;
  1106.  
  1107.   OldBottomGap := FBottomEx - Bottom;
  1108.   Change := Value - OldBottomGap;
  1109.   NewBottom := Bottom - Change;
  1110.  
  1111.   if (NewBottom <= Top) then exit;
  1112.  
  1113.   Bottom := NewBottom;
  1114.   DoHandleChange;
  1115. end;
  1116.  
  1117. {------------------------------------------------------------------------------
  1118.     Procedure: TBorder.SetHeightEx
  1119.   Description: private property Set procedure
  1120.        Author: Mat Ballard
  1121.  Date created: 02/25/2000
  1122. Date modified: 02/25/2000 by Mat Ballard
  1123.       Purpose: sets the
  1124.       Comment: the design philosophy is that changing the Total Height changes the value
  1125.                of Bottom AND BottomEX. If the user changes the Total Height, then that is about
  1126.                making the Height larger or smaller whilst preserving the BottomGap
  1127.  Known Issues:
  1128.  ------------------------------------------------------------------------------}
  1129. procedure TBorder.SetHeightEx(Value: Integer);
  1130. var
  1131.   OldHeightEx, Change: Integer;
  1132. begin
  1133.   if (Value <= GetBottomGap) then exit;
  1134.   if (Value = GetHeightEx) then exit;
  1135.  
  1136.   OldHeightEx := FBottomEx - Top;
  1137.   Change := Value - OldHeightEx;
  1138.  
  1139.   Bottom := Bottom + Change;
  1140.   Inc(FBottomEx, Change);
  1141.   DoHandleChange;
  1142. end;
  1143.  
  1144. {------------------------------------------------------------------------------
  1145.     Procedure: TBorder.SetWidthEx
  1146.   Description: private property Set procedure
  1147.        Author: Mat Ballard
  1148.  Date created: 02/25/2000
  1149. Date modified: 02/25/2000 by Mat Ballard
  1150.       Purpose: sets the WidthEx
  1151.      Comments: See comment about SetHeightEx
  1152.  Known Issues:
  1153.  ------------------------------------------------------------------------------}
  1154. procedure TBorder.SetWidthEx(Value: Integer);
  1155. var
  1156.   OldWidthEx, Change: Integer;
  1157. begin
  1158.   if (Value <= GetRightGap) then exit;
  1159.   if (Value = GetWidthEx) then exit;
  1160.  
  1161.   OldWidthEx := FRightEx - Left;
  1162.   Change := Value - OldWidthEx;
  1163.  
  1164.   Right := Right + Change;
  1165.   Inc(FRightEx, Change);
  1166.   DoHandleChange;
  1167. end;
  1168.  
  1169. {TCaption -------------------------------------------------------------------}
  1170. {Constructor and Destructor -------------------------------------------------}
  1171. {------------------------------------------------------------------------------
  1172.   Constructor: TCaption.Create
  1173.   Description: Standard Constructor for TCaption
  1174.        Author: Mat Ballard
  1175.  Date created: 02/25/2000
  1176. Date modified: 02/25/2000 by Mat Ballard
  1177.       Purpose: initializes component and properties
  1178.  Known Issues:
  1179.  ------------------------------------------------------------------------------}
  1180. Constructor TCaption.Create(AOwner: TPersistent);
  1181. begin
  1182. {First call the ancestor:}
  1183.   inherited Create(AOwner);
  1184.  
  1185. {Create font:}
  1186.   FFont := TFont.Create;
  1187.   FFont.Name := sArial;
  1188.   FFont.Size := SMALL_FONT_SIZE;
  1189. end;
  1190.  
  1191. destructor TCaption.Destroy; 
  1192. begin
  1193.   FFont.Free;
  1194. end;
  1195.  
  1196. {Begin Set Procedures -------------------------------------------------------}
  1197. {------------------------------------------------------------------------------
  1198.     Procedure: TCaption.SetCaption
  1199.   Description: private property Set procedure
  1200.        Author: Mat Ballard
  1201.  Date created: 02/25/2000
  1202. Date modified: 02/25/2000 by Mat Ballard
  1203.       Purpose: sets the Caption of TCaption
  1204.  Known Issues:
  1205.  ------------------------------------------------------------------------------}
  1206. procedure TCaption.SetCaption(Value: String);
  1207. begin
  1208.   if (Value = FCaption) then exit;
  1209.   FCaption := Value;
  1210.   CreateName;
  1211.   DoHandleChange;
  1212.   if assigned(FOnCaptionChange) then OnCaptionChange(Self);
  1213. end;
  1214.  
  1215. {------------------------------------------------------------------------------
  1216.     Procedure: TCaption.SetFont
  1217.   Description: private property Set procedure
  1218.        Author: Mat Ballard
  1219.  Date created: 02/25/2000
  1220. Date modified: 02/25/2000 by Mat Ballard
  1221.       Purpose: sets the Font
  1222.  Known Issues:
  1223.  ------------------------------------------------------------------------------}
  1224. procedure TCaption.SetFont(Value: TFont);
  1225. begin
  1226.   FFont.Assign(Value);
  1227.   DoHandleChange;
  1228. end;
  1229.  
  1230. {General purpose methods ------------------------------------------------------}
  1231. {------------------------------------------------------------------------------
  1232.     Procedure: TCaption.CreateName
  1233.   Description: protected procedure to set a useful name
  1234.        Author: Mat Ballard
  1235.  Date created: 02/25/2000
  1236. Date modified: 02/25/2000 by Mat Ballard
  1237.       Purpose: sets the Name, generally in response to a Caption change
  1238.  Known Issues:
  1239.  ------------------------------------------------------------------------------}
  1240. procedure TCaption.CreateName;
  1241. begin
  1242. {eg: Caption: X Axis
  1243.      Name: X Axis Caption.}
  1244.   Name := FCaption + ' Caption';
  1245. end;
  1246.  
  1247. {------------------------------------------------------------------------------
  1248.     Procedure: TCaption.Assign
  1249.   Description: standard Assign method
  1250.        Author: Mat Ballard
  1251.  Date created: 07/06/2000
  1252. Date modified: 07/06/2000 by Mat Ballard
  1253.       Purpose: implements Assign
  1254.  Known Issues:
  1255.  ------------------------------------------------------------------------------}
  1256. {procedure TCaption.Assign(Source: TPersistent);
  1257. begin
  1258.   inherited Assign(Source);
  1259.   FCaption := TCaption(Source).Caption;
  1260.   FFont.Assign(TCaption(Source).Font);
  1261. end;}
  1262.  
  1263. {------------------------------------------------------------------------------
  1264.     Procedure: TCaption.AssignTo
  1265.   Description: standard AssignTo method
  1266.        Author: Mat Ballard
  1267.  Date created: 07/06/2000
  1268. Date modified: 07/06/2000 by Mat Ballard
  1269.       Purpose: implements AssignTo
  1270.  Known Issues:
  1271.  ------------------------------------------------------------------------------}
  1272. procedure TCaption.AssignTo(Dest: TPersistent);
  1273. begin
  1274.   inherited AssignTo(Dest);
  1275.   TCaption(Dest).Caption := FCaption;
  1276.   TCaption(Dest).Font.Assign(FFont);
  1277. end;
  1278.  
  1279. {TTitle -------------------------------------------------------------------}
  1280. {Constructor and Destructor -------------------------------------------------}
  1281. {------------------------------------------------------------------------------
  1282.   Constructor: TTitle.Create
  1283.   Description: Standard Constructor for TTitle
  1284.        Author: Mat Ballard
  1285.  Date created: 02/25/2000
  1286. Date modified: 02/25/2000 by Mat Ballard
  1287.       Purpose: initializes component and properties
  1288.  Known Issues:
  1289.  ------------------------------------------------------------------------------}
  1290. Constructor TTitle.Create(AOwner: TPersistent);
  1291. begin
  1292. {First call the ancestor:}
  1293.   inherited Create(AOwner);
  1294.  
  1295.   FEnvelope.Left := 0;
  1296.   FEnvelope.Right := 100;
  1297.   FEnvelope.Top := 90;
  1298.   FEnvelope.Bottom := 110;
  1299. {we don't fire events with a geometry change:}
  1300.   FireEvents := FALSE;
  1301.   Self.Height := 20;
  1302. end;
  1303.  
  1304. {Get methods -----------------------------------------------------------------}
  1305.  
  1306. {Set procedures --------------------------------------------------------------}
  1307. {------------------------------------------------------------------------------
  1308.     Procedure: TTitle.SetCaption
  1309.   Description: protected property Set procedure
  1310.        Author: Mat Ballard
  1311.  Date created: 02/25/2000
  1312. Date modified: 02/25/2000 by Mat Ballard
  1313.       Purpose: sets the Caption, which is complicated by the presence of Units.
  1314.  Known Issues:
  1315.  ------------------------------------------------------------------------------}
  1316. procedure TTitle.SetCaption(Value: String);
  1317. var
  1318.   NewValue: String;
  1319. begin
  1320.   if (Pos('(', Value) > 0) then
  1321.   begin
  1322. {There is a "()" in the value, indicating the presence of Units}
  1323.     NewValue := Trim(GetWord(Value, '('));
  1324.     FUnits := GetWord(Value, ')');
  1325.     if (Length(FUnits) = 0) then
  1326.       FFullCaption := NewValue
  1327.      else
  1328.       FFullCaption := NewValue + ' (' + FUnits + ')';
  1329.     inherited SetCaption(NewValue);
  1330.   end
  1331.   else
  1332.   begin
  1333.     if (Length(FUnits) = 0) then
  1334.       FFullCaption := Value
  1335.      else
  1336.       FFullCaption := Value + ' (' + FUnits + ')';
  1337.     inherited SetCaption(Value);
  1338.   end;
  1339. end;
  1340.  
  1341. {------------------------------------------------------------------------------
  1342.     Procedure: TTitle.SetDirection
  1343.   Description: private property Set procedure
  1344.        Author: Mat Ballard
  1345.  Date created: 02/25/2000
  1346. Date modified: 02/25/2000 by Mat Ballard
  1347.       Purpose: sets the Direction
  1348.  Known Issues:
  1349.  ------------------------------------------------------------------------------}
  1350. procedure TTitle.SetDirection(Value: TDirection);
  1351. begin
  1352.   if (Value = FDirection) then exit;
  1353.   FDirection := Value;
  1354.   DoHandleChange;
  1355. end;
  1356.  
  1357. {------------------------------------------------------------------------------
  1358.     Procedure: TTitle.SetOrientation
  1359.   Description: private property Set procedure
  1360.        Author: Mat Ballard
  1361.  Date created: 02/25/2000
  1362. Date modified: 02/25/2000 by Mat Ballard
  1363.       Purpose: sets the Orientation
  1364.  Known Issues:
  1365.  ------------------------------------------------------------------------------}
  1366. procedure TTitle.SetOrientation(Value: TOrientation);
  1367. begin
  1368.   if (Value = FOrientation) then exit;
  1369.   FOrientation := Value;
  1370.   DoHandleChange;
  1371. end;
  1372.  
  1373. {------------------------------------------------------------------------------
  1374.     Procedure: TTitle.SetEnvelope
  1375.   Description: private property Set procedure
  1376.        Author: Mat Ballard
  1377.  Date created: 02/25/2000
  1378. Date modified: 02/25/2000 by Mat Ballard
  1379.       Purpose: sets the Envelope: the screen region around which the Title dances
  1380.  Known Issues:
  1381.  ------------------------------------------------------------------------------}
  1382. procedure TTitle.SetEnvelope(Value: TRect);
  1383. begin
  1384.   if ((Value.Left = FEnvelope.Left) and
  1385.       (Value.Top = FEnvelope.Top) and
  1386.       (Value.Right = FEnvelope.Right) and
  1387.       (Value.Bottom = FEnvelope.Bottom)) then exit;
  1388.   FEnvelope := Value;
  1389.   DoHandleChange;
  1390. end;
  1391.  
  1392. {------------------------------------------------------------------------------
  1393.     Procedure: TTitle.SetUnits
  1394.   Description: private property Set procedure
  1395.        Author: Mat Ballard
  1396.  Date created: 02/25/2000
  1397. Date modified: 02/25/2000 by Mat Ballard
  1398.       Purpose: sets the Units (eg: Furlongs / Fortnight ^3), and also the FullCaption
  1399.  Known Issues:
  1400.  ------------------------------------------------------------------------------}
  1401. procedure TTitle.SetUnits(Value: String);
  1402. begin
  1403.   if (Value = FUnits) then exit;
  1404.   FUnits := Value;
  1405.   if (Length(FUnits) = 0) then
  1406.     FFullCaption := FCaption
  1407.    else
  1408.     FFullCaption := FCaption + ' (' + FUnits + ')';
  1409.   DoHandleChange;
  1410. end;
  1411.  
  1412. {Drawing ----------------------------------------------------------------------}
  1413. {------------------------------------------------------------------------------
  1414.     Procedure: TTitle.DoGeometry
  1415.   Description: TTitle Geometry manager
  1416.        Author: Mat Ballard
  1417.  Date created: 02/25/2000
  1418. Date modified: 02/25/2000 by Mat Ballard
  1419.       Purpose: sets the precise screen position of the TTitle.
  1420.  Known Issues:
  1421.  ------------------------------------------------------------------------------}
  1422. procedure TTitle.DoGeometry(ACanvas: TCanvas; TheText: String);
  1423. begin
  1424.   if (FDirection = drHorizontal) then
  1425.   begin
  1426. {BUG BUG BUG: if ACanvas is a metafile canvas, then TextHeight and TextWidth
  1427.  both return zero in D1!}
  1428.     Height := Abs(ACanvas.Font.Height);
  1429.     Width := ACanvas.TextWidth(TheText);
  1430. {Note how "neat" this is: when D1 returns 0 for these Text dimensions,
  1431.  TRectangle rejects them, so Height and Width are unchanged !
  1432.  Therefore, when we use them below, we use the previous screen values !}
  1433.     if (FOrientation = orLeft) then
  1434.     begin
  1435.       Top := FEnvelope.Top - Height;
  1436.       if (Alignment = taLeftJustify) then
  1437.         Left := FEnvelope.Left
  1438.        else if (Alignment = taRightJustify) then
  1439.         Left := FEnvelope.Right - Width
  1440.        else {Alignment = taCenter}
  1441.         Left := (FEnvelope.Left + FEnvelope.Right - Width) div 2;
  1442.     end
  1443.     else {FOrientation = oRight}
  1444.     begin
  1445.       Top := FEnvelope.Bottom;
  1446.       if (Alignment = taLeftJustify) then
  1447.         Left := FEnvelope.Left
  1448.        else if (Alignment = taRightJustify) then
  1449.         Left := FEnvelope.Right - Width
  1450.        else {Alignment = taCenter}
  1451.         Left := (FEnvelope.Left + FEnvelope.Right - Width) div 2;
  1452.     end;
  1453.   end
  1454.   else {FDirection = dVertical}
  1455.   begin
  1456. {BUG BUG BUG: if ACanvas is a metafile canvas, then TextHeight and TextWidth
  1457.  both return zero in D1!}
  1458.     Width := Abs(ACanvas.Font.Height);
  1459.     Height := ACanvas.TextWidth(TheText);
  1460.     if (FOrientation = orLeft) then
  1461.     begin
  1462.       Left := FEnvelope.Left - Width;
  1463.       if (Alignment = taLeftJustify) then
  1464.         Top := FEnvelope.Bottom - Height
  1465.        else if (Alignment = taRightJustify) then
  1466.         Top := FEnvelope.Top
  1467.        else {Alignment = taCenter}
  1468.         Top := (FEnvelope.Top + FEnvelope.Bottom - Height) div 2;
  1469.     end
  1470.     else {FOrientation = oRight}
  1471.     begin
  1472.       Left := FEnvelope.Right;
  1473.       if (Alignment = taLeftJustify) then
  1474.         Top := FEnvelope.Bottom - Height
  1475.        else if (Alignment = taRightJustify) then
  1476.         Top := FEnvelope.Top
  1477.        else {Alignment = taCenter}
  1478.         Top := (FEnvelope.Top + FEnvelope.Bottom - Height) div 2;
  1479.     end;
  1480.   end;
  1481. end;
  1482.  
  1483. {------------------------------------------------------------------------------
  1484.     Procedure: TTitle.Draw
  1485.   Description: public Drawing method
  1486.        Author: Mat Ballard
  1487.  Date created: 02/25/2000
  1488. Date modified: 02/25/2000 by Mat Ballard
  1489.       Purpose: Draws the Caption, either horizontally or vertically, at the desired position
  1490.  Known Issues:
  1491.  ------------------------------------------------------------------------------}
  1492. procedure TTitle.Draw(ACanvas: TCanvas);
  1493. var
  1494.   iY: Integer;
  1495.   TheText: String;
  1496. begin
  1497.   if (not Visible) then exit;
  1498.   if (Length(FCaption) = 0) then exit;
  1499. {$IFDEF DELPHI3_UP}
  1500.   Assert(ACanvas <> nil, 'TTitle.Draw: ACanvas is nil !');
  1501. {$ENDIF}
  1502.  
  1503.   ACanvas.Font.Assign(FFont);
  1504.   TheText := FCaption;
  1505.   if (Length(FUnits) > 0) then
  1506.     TheText := TheText + ' (' + FUnits + ')';
  1507.   DoGeometry(ACanvas, TheText);
  1508.  
  1509. {output text to screen:}
  1510.   if (FDirection = drHorizontal) then
  1511.   begin
  1512.     iY := Top;
  1513.     while (Pos(#10, TheText) > 0) do
  1514.     begin
  1515.       ACanvas.TextOut(Left, iY, GetWord(TheText, #10));
  1516.       Inc(iY, Abs(ACanvas.Font.Height));
  1517.     end;
  1518.     ACanvas.TextOut(Left, iY, TheText);
  1519.   end
  1520.   else {FDirection = dVertical}
  1521.   begin
  1522.     iY := Left;
  1523.     while (Pos(#10, TheText) > 0) do
  1524.     begin
  1525.       TextOutAngle(ACanvas, 90,
  1526.         Left, Top + ACanvas.TextWidth(TheText),
  1527.         GetWord(TheText, #10));
  1528.       ACanvas.TextOut(Left, iY, GetWord(TheText, #10));
  1529.       Inc(iY, Abs(ACanvas.Font.Height));
  1530.     end;
  1531.     TextOutAngle(ACanvas, 90, Left, Top + ACanvas.TextWidth(TheText), TheText);
  1532.   end;
  1533. end;
  1534.  
  1535. {------------------------------------------------------------------------------
  1536.     Procedure: TTitle.Assign
  1537.   Description: standard Assign method
  1538.        Author: Mat Ballard
  1539.  Date created: 07/06/2000
  1540. Date modified: 07/06/2000 by Mat Ballard
  1541.       Purpose: implements Assign
  1542.  Known Issues:
  1543.  ------------------------------------------------------------------------------}
  1544. {procedure TTitle.Assign(Source: TPersistent);
  1545. begin
  1546.   inherited Assign(Source);
  1547.   FDirection := TTitle(Source).Direction;
  1548.   FOrientation := TTitle(Source).Orientation;
  1549.   FUnits := TTitle(Source).Units;
  1550. end;}
  1551.  
  1552. {------------------------------------------------------------------------------
  1553.     Procedure: TTitle.AssignTo
  1554.   Description: standard AssignTo method
  1555.        Author: Mat Ballard
  1556.  Date created: 07/06/2000
  1557. Date modified: 07/06/2000 by Mat Ballard
  1558.       Purpose: implements AssignTo
  1559.  Known Issues:
  1560.  ------------------------------------------------------------------------------}
  1561. procedure TTitle.AssignTo(Dest: TPersistent);
  1562. begin
  1563.   inherited AssignTo(Dest);
  1564.   TTitle(Dest).Direction := FDirection;
  1565.   TTitle(Dest).Orientation := FOrientation;
  1566.   TTitle(Dest).Units := FUnits;
  1567. end;
  1568.  
  1569. {TLegend ----------------------------------------------------------------------}
  1570. {------------------------------------------------------------------------------
  1571.   Constructor: TCaption.Create
  1572.   Description: Standard Constructor for TCaption
  1573.        Author: Mat Ballard
  1574.  Date created: 02/25/2000
  1575. Date modified: 02/25/2000 by Mat Ballard
  1576.       Purpose: initializes component and properties
  1577.  Known Issues:
  1578.  ------------------------------------------------------------------------------}
  1579. Constructor TLegend.Createlist(AOwner: TPersistent; SeriesList: TList);
  1580. begin
  1581. {First call the ancestor:}
  1582.   inherited Create(AOwner);
  1583.   FSeriesList := SeriesList;
  1584.  
  1585. {Create font:}
  1586.   FFont := TFont.Create;
  1587.   FFont.Name := sArial;
  1588.   FFont.Size := SMALL_FONT_SIZE;
  1589.   FCheckBoxes := TRUE;
  1590. end;
  1591.  
  1592. destructor TLegend.Destroy;
  1593. begin
  1594.   FFont.Free;
  1595. end;
  1596.  
  1597. {Get functions ----------------------------------------------------------------}
  1598. {------------------------------------------------------------------------------
  1599.      Function: TLegend.GetHit
  1600.   Description: Interprets mouse click position
  1601.        Author: Mat Ballard
  1602.  Date created: 02/25/2000
  1603. Date modified: 02/25/2000 by Mat Ballard
  1604.       Purpose: Gets the region of the line of the Legend under the input position
  1605.  Known Issues:
  1606.  ------------------------------------------------------------------------------}
  1607. function TLegend.GetHit(iX, iY: Integer; var TheRect: TRect): Integer;
  1608. var
  1609.   SeriesWidth,
  1610.   TheHit,
  1611.   TheOffset: Integer;
  1612. begin
  1613.   if (FDirection = drHorizontal) then
  1614.   begin
  1615.     SeriesWidth :=  FCheckWidth + FLineWidth + FStringWidth + 5;
  1616.     TheHit := (iX - Left) div SeriesWidth;
  1617.     TheRect.Left := Left + TheHit * SeriesWidth;
  1618.     TheRect.Right := TheRect.Left + SeriesWidth;
  1619.     TheRect.Top := Top;
  1620.     TheRect.Bottom := Bottom;
  1621.     TheOffset := (iX - Left) mod SeriesWidth;
  1622.   end
  1623.   else
  1624.   begin {dVertical}
  1625.     TheHit := (iY - Top) div FFontHeight;
  1626.     TheRect.Left := Left;
  1627.     TheRect.Right := Right;
  1628.     TheRect.Top := Top + TheHit * FFontHeight;
  1629.     TheRect.Bottom := TheRect.Top + FFontHeight;
  1630.     TheOffset := iX - Left;
  1631.   end;
  1632.   if (TheOffset <= FCheckWidth) then
  1633.     TSeries(FSeriesList.Items[TheHit]).Visible :=
  1634.       not TSeries(FSeriesList.Items[TheHit]).Visible;
  1635.  
  1636.   GetHit := TheHit;
  1637. end;
  1638.  
  1639. function TLegend.GetItemWidth: Integer;
  1640. begin
  1641.   GetItemWidth :=  FCheckWidth + FLineWidth + FStringWidth;
  1642. end;
  1643.  
  1644. {Set procedures ---------------------------------------------------------------}
  1645. {------------------------------------------------------------------------------
  1646.     Procedure: TLegend.SetCheckBoxes
  1647.   Description: private property Set procedure
  1648.        Author: Mat Ballard
  1649.  Date created: 04/12/2001
  1650. Date modified: 04/12/2001 by Mat Ballard
  1651.       Purpose: sets whether or not the CheckBoxes are visible
  1652.  Known Issues:
  1653.  ------------------------------------------------------------------------------}
  1654. procedure TLegend.SetCheckBoxes(Value: Boolean);
  1655. begin
  1656.   if (Value = FCheckboxes) then exit;
  1657.   FCheckboxes := Value;
  1658.   DoHandleChange;
  1659. end;
  1660.  
  1661. {------------------------------------------------------------------------------
  1662.     Procedure: TLegend.SetDirection
  1663.   Description: private property Set procedure
  1664.        Author: Mat Ballard
  1665.  Date created: 02/25/2000
  1666. Date modified: 02/25/2000 by Mat Ballard
  1667.       Purpose: sets the Direction
  1668.  Known Issues:
  1669.  ------------------------------------------------------------------------------}
  1670. procedure TLegend.SetDirection(Value: TDirection);
  1671. begin
  1672.   if (Value = FDirection) then exit;
  1673.   FDirection := Value;
  1674.   DoHandleChange;
  1675. end;
  1676.  
  1677. {------------------------------------------------------------------------------
  1678.     Procedure: TLegend.SetFont
  1679.   Description: private property Set procedure
  1680.        Author: Mat Ballard
  1681.  Date created: 02/25/2000
  1682. Date modified: 02/25/2000 by Mat Ballard
  1683.       Purpose: sets the Font
  1684.  Known Issues:
  1685.  ------------------------------------------------------------------------------}
  1686. procedure TLegend.SetFont(Value: TFont);
  1687. begin
  1688.   FFont.Assign(Value);
  1689.   DoHandleChange;
  1690. end;
  1691.  
  1692. {------------------------------------------------------------------------------
  1693.     Procedure: TLegend.Draw
  1694.   Description: draws the legend
  1695.        Author: Mat Ballard
  1696.  Date created: 04/19/2001
  1697. Date modified: 04/19/2001 by Mat Ballard
  1698.       Purpose: screen drawing
  1699.  Known Issues:
  1700.  ------------------------------------------------------------------------------}
  1701. procedure TLegend.Draw(ACanvas: TCanvas; SeriesIncrement: Integer);
  1702. var
  1703.   Chars,
  1704.   i,
  1705.   iX,
  1706.   iMaxChars,
  1707.   MaxChars,
  1708.   LineY,
  1709.   TextY: Integer;
  1710.  
  1711. {$IFDEF LINUX}
  1712.   //ARect: TRect;
  1713. {$ENDIF}
  1714.  
  1715.   procedure DoGeometry;
  1716.   begin
  1717. {Allow for symbols and lines:}
  1718.     FStringWidth := ACanvas.TextWidth(
  1719.       TSeries(FSeriesList.Items[iMaxChars]).Name);
  1720.     FLineWidth := 2 * FStringWidth div 5;
  1721.     FFontHeight := ACanvas.TextHeight('Ap');
  1722.     if (FCheckBoxes) then
  1723.       FCheckWidth := 7*FFontHeight div 10
  1724.      else
  1725.       FCheckWidth := 0;
  1726.  
  1727.     if (FDirection = drHorizontal) then
  1728.     begin
  1729.       Height := FFontHeight;
  1730.   {       <-----LineWidth---->
  1731.    <Check><Line><Symbol><Line><Text---StringWidth--->}
  1732.       Width := FSeriesList.Count *
  1733.         (FCheckWidth + FLineWidth + FStringWidth + 5);
  1734.     end
  1735.     else
  1736.     begin
  1737.       Height := FSeriesList.Count * FFontHeight;
  1738.       Width := FCheckWidth + FLineWidth + FStringWidth + 5;
  1739.     end;
  1740.   end;
  1741.  
  1742.   procedure DrawCheck(Value: Boolean; X, Y, Size: Integer);
  1743.   begin
  1744.     ACanvas.Pen.Color := clBlack;
  1745.     ACanvas.Pen.Width := 1;
  1746.     ACanvas.Pen.Style := psSolid;
  1747.     ACanvas.Brush.Color := clWhite;
  1748.     ACanvas.Brush.Style := bsSolid;
  1749.     ACanvas.Rectangle(X, Y, X + Size, Y + Size);
  1750.  
  1751.     ACanvas.Pen.Color := clBtnShadow;
  1752.     ACanvas.MoveTo(X + Size-2, Y+1);
  1753.     ACanvas.LineTo(X+1, Y+1);
  1754.     ACanvas.LineTo(X+1, Y + Size-1);
  1755.  
  1756.     ACanvas.Pen.Color := clBtnFace;
  1757.     ACanvas.MoveTo(X + Size - 2, Y+1);
  1758.     ACanvas.LineTo(X + Size - 2, Y + Size - 2);
  1759.     ACanvas.LineTo(X+1, Y + Size - 2);
  1760.  
  1761.     {ACanvas.Pen.Color := clBlack;
  1762.     ACanvas.MoveTo(X + Size - 3, Y+2);
  1763.     ACanvas.LineTo(X+2, Y+2);
  1764.     ACanvas.LineTo(X+2, Y + Size - 3);}
  1765.  
  1766.     if (Value) then
  1767.     begin
  1768.       ACanvas.Pen.Color := clBlack;
  1769.       ACanvas.Pen.Width := 2;
  1770.       ACanvas.MoveTo(X+2, Y + Size div 2 +1);
  1771.       ACanvas.LineTo(X + Size div 2, Y + Size - 3);
  1772.       ACanvas.LineTo(X + Size -3, Y + 2);
  1773.       {ACanvas.MoveTo(X+3, Y + Size div 2);
  1774.       ACanvas.LineTo(X + Size div 2, Y + Size - 2);
  1775.       ACanvas.LineTo(X + Size -3, Y + 2);}
  1776.     end;
  1777.   end;
  1778.  
  1779. begin
  1780. {$IFDEF DELPHI3_UP}
  1781.   Assert(ACanvas <> nil, sLegendDrawError);
  1782. {$ENDIF}
  1783.  
  1784.   if (not Self.Visible) then exit;
  1785.   if (FSeriesList.Count = 0) then exit;
  1786.  
  1787.   ACanvas.Font.Assign(Self.Font);
  1788.  
  1789.   MaxChars := 0;
  1790.   iMaxChars := -1;
  1791.   for i := 0 to FSeriesList.Count-1 do
  1792.   begin
  1793.     Chars := Length(TSeries(FSeriesList.Items[i]).Name);
  1794.     if (MaxChars < Chars) then
  1795.     begin
  1796.       MaxChars := Chars;
  1797.       iMaxChars := i;
  1798.     end;
  1799.   end;
  1800.   if (iMaxChars < 0) then exit;
  1801.  
  1802.   DoGeometry;
  1803.  
  1804.   LineY := Self.Top + Self.FontHeight div 2;
  1805.   TextY := Self.Top;
  1806.  
  1807.   i := 0;
  1808.  
  1809.   if (Self.Direction = drVertical) then
  1810.   begin
  1811.     while i < FSeriesList.Count do
  1812.     //for i := 0 to SeriesList.Count-1 do
  1813.     begin
  1814.       DrawCheck(TSeries(FSeriesList.Items[i]).Visible,
  1815.         Self.Left, LineY-FCheckWidth div 2, FCheckWidth);
  1816.       ACanvas.Pen.Assign(TSeries(FSeriesList.Items[i]).Pen);
  1817.       ACanvas.MoveTo(Self.Left + FCheckWidth+1, LineY);
  1818.       ACanvas.LineTo(Self.Left + FCheckWidth + FLineWidth, LineY);
  1819.       ACanvas.Brush.Assign(TSeries(FSeriesList.Items[i]).Brush);
  1820.       TSeries(FSeriesList.Items[i]).DrawSymbol(ACanvas,
  1821.         Self.Left + FCheckWidth + FLineWidth div 2, LineY);
  1822.       ACanvas.Brush.Style := bsClear;
  1823.   {output text to screen:}
  1824.       ACanvas.Font.Color := ACanvas.Pen.Color;
  1825.       ACanvas.TextOut(Self.Left + FCheckWidth + FLineWidth+1, TextY,
  1826.         TSeries(FSeriesList.Items[i]).Name);
  1827.       Inc(LineY, Self.FontHeight);
  1828.       Inc(TextY, Self.FontHeight);
  1829.       Inc(i, SeriesIncrement);
  1830.     end;
  1831.   end
  1832.   else {Horizontal}
  1833.   begin
  1834. {Note: in Horizontal mode, the size of each series name is:}
  1835. {<---LineWidth---><---StringWidth---><-LineWidth->}
  1836. {<-Symbol + Line-><-Name of Series--><--Space---->}
  1837.     LineY := Self.Top + Self.FontHeight div 2;
  1838.     TextY := Self.Top;
  1839.     iX := Self.Left;
  1840.     while i < FSeriesList.Count do
  1841.     //for i := 0 to SeriesList.Count-1 do
  1842.     begin
  1843.       DrawCheck(TSeries(FSeriesList.Items[i]).Visible,
  1844.         iX, LineY - FCheckWidth div 2, FCheckWidth);
  1845.       ACanvas.Pen.Assign(TSeries(FSeriesList.Items[i]).Pen);
  1846.       ACanvas.MoveTo(iX + FCheckWidth+1, LineY);
  1847.       ACanvas.LineTo(iX + FCheckWidth + FLineWidth, LineY);
  1848.       ACanvas.Brush.Assign(TSeries(FSeriesList.Items[i]).Brush);
  1849.       TSeries(FSeriesList.Items[i]).DrawSymbol(ACanvas,
  1850.         iX + FCheckWidth + FLineWidth div 2, LineY);
  1851.       ACanvas.Brush.Style := bsClear;
  1852.   {output text to screen:}
  1853.       ACanvas.Font.Color := ACanvas.Pen.Color;
  1854.       ACanvas.TextOut(iX + FCheckWidth + FLineWidth +1, TextY,
  1855.         TSeries(FSeriesList.Items[i]).Name);
  1856.       iX := iX + FCheckWidth + FLineWidth + FStringWidth + 5;
  1857.       Inc(i, SeriesIncrement);
  1858.     end; {for}
  1859.     Self.Width := iX - Self.Left;
  1860.     Self.Height := Self.FontHeight;
  1861.   end; {if}
  1862. end;
  1863.  
  1864. {TNote ------------------------------------------------------------------------}
  1865. procedure TNote.AssignTo(Dest: TPersistent);
  1866. begin
  1867.   inherited AssignTo(Dest);
  1868.   TNote(Dest).ArrowLeft := FArrowLeft;
  1869.   TNote(Dest).ArrowTop := FArrowTop;
  1870.   TNote(Dest).ArrowLeftReal := FArrowLeftReal;
  1871.   TNote(Dest).ArrowTopReal := FArrowTopReal;
  1872.   TNote(Dest).LeftReal := FLeftReal;
  1873.   TNote(Dest).TopReal := FTopReal;
  1874. end;
  1875.  
  1876. constructor TNote.Create(AOwner: TPersistent);
  1877. {var
  1878.   StartPoint: TPoint;}
  1879. begin
  1880.   inherited Create(AOwner);
  1881.   FOwner := AOwner;
  1882. {a note can only ever be a note:}
  1883.   Tag := Ord(soNote);
  1884.   {StartPoint := TPlot(AOwner).ScreenToClient(Mouse.CursorPos);
  1885.   ArrowLeft := StartPoint.X;
  1886.   ArrowTop := StartPoint.Y;}
  1887.   Caption := InputBox('New Note', 'Please enter the new note', 'New Note');
  1888. end;
  1889.  
  1890. {destructor TNote.Destroy;
  1891. begin
  1892.  
  1893. end;}
  1894.  
  1895. procedure TNote.Draw(ACanvas: TCanvas);
  1896. var
  1897.   TextSize: TSize;
  1898. {$IFDEF LINUX}
  1899.   //ARect: TRect;
  1900. {$ENDIF}
  1901. begin
  1902.   if (not Visible) then exit;
  1903.   if (Length(Caption) = 0) then exit;
  1904. {$IFDEF DELPHI3_UP}
  1905.   Assert(ACanvas <> nil, 'TNote.Draw: ACanvas is nil !');
  1906. {$ENDIF}
  1907.  
  1908.   ACanvas.Font.Assign(FFont);
  1909.   ACanvas.Pen.Color := FFont.Color;
  1910.  
  1911. {we do the geometry;
  1912.  note that if a Zoom-in has occurred, then the note position changes:}
  1913.   FLeft := TPlot(FOwner).XAxis.FofX(FLeftReal);
  1914.   FTop := TPlot(FOwner).YAxis.FofY(FTopReal);
  1915.   FArrowLeft := TPlot(FOwner).XAxis.FofX(FArrowLeftReal);
  1916.   FArrowTop := TPlot(FOwner).YAxis.FofY(FArrowTopReal);
  1917.  
  1918.   TextSize := ACanvas.TextExtent(Caption
  1919.   {$IFDEF LINUX}
  1920.     , 0
  1921.   {$ENDIF}
  1922.     );
  1923.  
  1924.   Width := TextSize.cx;
  1925.   Height := TextSize.cy;
  1926.  
  1927.   if (FArrowLeft < Left) then
  1928.     ArrowStartLeft := Left
  1929.   else if (FArrowLeft > Left+Width) then
  1930.     ArrowStartLeft := Left + Width
  1931.   else
  1932.     ArrowStartLeft := Left + Width div 2;
  1933.  
  1934.   if (FArrowTop < Top) then
  1935.     ArrowStartTop := Top
  1936.   else if (FArrowTop > Top+Height) then
  1937.     ArrowStartTop := Top + Height
  1938.   else
  1939.     ArrowStartTop := Top + Height div 2;
  1940.  
  1941.   if ((FArrowLeft < Left) or
  1942.       (FArrowLeft > Left+Width) or
  1943.       (FArrowTop < Top) or
  1944.       (FArrowTop > Top+Height)) then
  1945.   begin
  1946.     ACanvas.MoveTo(ArrowStartLeft, ArrowStartTop);
  1947.     ACanvas.LineTo(FArrowLeft, FArrowTop);
  1948.   end;
  1949. {output text to screen:}
  1950. {$IFDEF MSWINDOWS}
  1951.   ACanvas.TextOut(Left, Top, Caption);
  1952. {$ENDIF}
  1953. {$IFDEF LINUX}
  1954.   ACanvas.TextOut(Left, Top {+ Abs(ACanvas.Font.Height)}, Caption);
  1955.   //ACanvas.TextRect(ARect, Left, Top, Caption, TOPLEFT_ALIGN);
  1956. {$ENDIF}
  1957. end;
  1958.  
  1959. {------------------------------------------------------------------------------
  1960.     Procedure: TNote.TracePointerTo
  1961.   Description: Moves the end of the note pointer to X, Y
  1962.        Author: Mat Ballard
  1963.  Date created: 11/23/2000
  1964. Date modified: 11/23/2000 by Mat Ballard
  1965.       Purpose: manages movement of the note pointer
  1966.  Known Issues:
  1967.  ------------------------------------------------------------------------------}
  1968. procedure TNote.TracePointerTo(ACanvas: TCanvas; iX, iY: Integer);
  1969. begin
  1970. {rub out the old line:}
  1971.   ACanvas.Pen.Mode := pmNotXOR;
  1972.   if ((FArrowLeft < Left) or
  1973.       (FArrowLeft > Left+Width) or
  1974.       (FArrowTop < Top) or
  1975.       (FArrowTop > Top+Height)) then
  1976.   begin
  1977.     ACanvas.MoveTo(ArrowStartLeft, ArrowStartTop);
  1978.     ACanvas.LineTo(FArrowLeft, FArrowTop);
  1979.   end;
  1980. {go to new coordinates:}
  1981.   ArrowLeft := iX;
  1982.   ArrowTop := iY;
  1983. {draw the new one:}
  1984.   ACanvas.MoveTo(ArrowStartLeft, ArrowStartTop);
  1985.   ACanvas.LineTo(FArrowLeft, FArrowTop);
  1986. end;
  1987.  
  1988. {------------------------------------------------------------------------------
  1989.     Procedure: TNote.SetArrowLeft
  1990.   Description: protected property Set procedure
  1991.        Author: Mat Ballard
  1992.  Date created: 11/15/2000
  1993. Date modified: 11/15/2000 by Mat Ballard
  1994.       Purpose: sets the ArrowLeft, which also re-calculates the RealArrowLeft
  1995.  Known Issues:
  1996.  ------------------------------------------------------------------------------}
  1997. procedure TNote.SetArrowLeft(Value: Integer);
  1998. begin
  1999.   if (FArrowLeft = Value) then exit;
  2000.  
  2001.   FArrowLeft := Value;
  2002.   FArrowLeftReal := TPlot(FOwner).XAxis.XofF(FArrowLeft);
  2003.   DoHandleChange;
  2004. end;
  2005.  
  2006. {------------------------------------------------------------------------------
  2007.     Procedure: TNote.SetArrowTop
  2008.   Description: protected property Set procedure
  2009.        Author: Mat Ballard
  2010.  Date created: 11/15/2000
  2011. Date modified: 11/15/2000 by Mat Ballard
  2012.       Purpose: sets the ArrowTop, which also re-calculates the RealArrowTop
  2013.  Known Issues:
  2014.  ------------------------------------------------------------------------------}
  2015. procedure TNote.SetArrowTop(Value: Integer);
  2016. begin
  2017.   if (FArrowTop = Value) then exit;
  2018.  
  2019.   FArrowTop := Value;
  2020.   FArrowTopReal := TPlot(FOwner).YAxis.YofF(FArrowTop);
  2021.   DoHandleChange;
  2022. end;
  2023.  
  2024. {------------------------------------------------------------------------------
  2025.     Procedure: TNote.SetLeft
  2026.   Description: protected property Set procedure
  2027.        Author: Mat Ballard
  2028.  Date created: 02/25/2000
  2029. Date modified: 02/25/2000 by Mat Ballard
  2030.       Purpose: sets the (Screen)Left, which also re-calculates the LeftReal
  2031.  Known Issues:
  2032.  ------------------------------------------------------------------------------}
  2033. procedure TNote.SetLeft(Value: Integer);
  2034. begin
  2035.   if (Value = FLeft) then exit;
  2036.  
  2037.   FLeft := Value;
  2038.   FLeftReal := TPlot(FOwner).XAxis.XofF(FLeft);
  2039.   DoHandleChange;
  2040. end;
  2041.  
  2042. {------------------------------------------------------------------------------
  2043.     Procedure: TNote.SetTop
  2044.   Description: protected property Set procedure
  2045.        Author: Mat Ballard
  2046.  Date created: 02/25/2000
  2047. Date modified: 02/25/2000 by Mat Ballard
  2048.       Purpose: sets the (Screen)Top, which also re-calculates the TopReal
  2049.  Known Issues:
  2050.  ------------------------------------------------------------------------------}
  2051. procedure TNote.SetTop(Value: Integer);
  2052. begin
  2053.   if (Value = FTop) then exit;
  2054.  
  2055.   FTop := Value;
  2056.   FTopReal := TPlot(FOwner).YAxis.YofF(FTop);
  2057.   DoHandleChange;
  2058. end;
  2059.  
  2060. {------------------------------------------------------------------------------
  2061.     Procedure: TNote.SetLeftReal
  2062.   Description: protected property Set procedure
  2063.        Author: Mat Ballard
  2064.  Date created: 02/25/2000
  2065. Date modified: 02/25/2000 by Mat Ballard
  2066.       Purpose: sets the (Data)LeftReal, which also re-calculates the Left
  2067.  Known Issues:
  2068.  ------------------------------------------------------------------------------}
  2069. procedure TNote.SetLeftReal(Value: Single);
  2070. begin
  2071.   if (FLeftReal = Value) then exit;
  2072.  
  2073.   FLeftReal := Value;
  2074.   FLeft := TPlot(FOwner).XAxis.FofX(FLeftReal);
  2075.   DoHandleChange;
  2076. end;
  2077.  
  2078. {------------------------------------------------------------------------------
  2079.     Procedure: TNote.SetTopReal
  2080.   Description: protected property Set procedure
  2081.        Author: Mat Ballard
  2082.  Date created: 02/25/2000
  2083. Date modified: 02/25/2000 by Mat Ballard
  2084.       Purpose: sets the (Data)TopReal, which also re-calculates the Top
  2085.  Known Issues:
  2086.  ------------------------------------------------------------------------------}
  2087. procedure TNote.SetTopReal(Value: Single);
  2088. begin
  2089.   if (FTopReal = Value) then exit;
  2090.  
  2091.   FTopReal := Value;
  2092.   FTop := TPlot(FOwner).YAxis.FofY(FTopReal);
  2093.   DoHandleChange;
  2094. end;
  2095.  
  2096. {------------------------------------------------------------------------------
  2097.     Procedure: TNote.SetArrowLeftReal
  2098.   Description: protected property Set procedure
  2099.        Author: Mat Ballard
  2100.  Date created: 02/25/2000
  2101. Date modified: 02/25/2000 by Mat Ballard
  2102.       Purpose: sets the (Data)ArrowLeftReal, which also re-calculates the Left
  2103.  Known Issues:
  2104.  ------------------------------------------------------------------------------}
  2105. procedure TNote.SetArrowLeftReal(Value: Single);
  2106. begin
  2107.   if (FArrowLeftReal = Value) then exit;
  2108.  
  2109.   FArrowLeftReal := Value;
  2110.   FLeft := TPlot(FOwner).XAxis.FofX(FArrowLeftReal);
  2111.   DoHandleChange;
  2112. end;
  2113.  
  2114. {------------------------------------------------------------------------------
  2115.     Procedure: TNote.SetArrowTopReal
  2116.   Description: protected property Set procedure
  2117.        Author: Mat Ballard
  2118.  Date created: 02/25/2000
  2119. Date modified: 02/25/2000 by Mat Ballard
  2120.       Purpose: sets the (Data)ArrowTopReal, which also re-calculates the Top
  2121.  Known Issues:
  2122.  ------------------------------------------------------------------------------}
  2123. procedure TNote.SetArrowTopReal(Value: Single);
  2124. begin
  2125.   if (FArrowTopReal = Value) then exit;
  2126.  
  2127.   FArrowTopReal := Value;
  2128.   FTop := TPlot(FOwner).YAxis.FofY(FArrowTopReal);
  2129.   DoHandleChange;
  2130. end;
  2131.  
  2132.  
  2133. end.
  2134.