home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 October / Chip_2001-10_cd1.bin / zkuste / delphi / kompon / d123456 / CHEMPLOT.ZIP / TPlot / Titles.pas < prev    next >
Pascal/Delphi Source File  |  2001-07-25  |  102KB  |  2,909 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 NO_MATH}NoMath,{$ELSE}Math,{$ENDIF}
  61. {$IFDEF WINDOWS}
  62.   Wintypes,
  63.   TrimStr,
  64.   Controls, Dialogs, Graphics,
  65. {$ENDIF}
  66. {$IFDEF WIN32}
  67.   Windows,
  68.   Controls, Dialogs, Graphics,
  69. {$ENDIF}
  70. {$IFDEF LINUX}
  71.   Types,
  72.   QControls, QDialogs, QGraphics,
  73. {$ENDIF}
  74.  
  75.   Misc, Plotdefs;
  76.  
  77. const
  78.   SIN_30 = 0.5;
  79.   SIN_60 = 0.86602540378443864676372317075294;
  80.   COS_30 = 0.86602540378443864676372317075294;
  81.   COS_60 = 0.5;
  82.  
  83. type
  84. {TRectangle *******************************************************************}
  85.   TRectangle = class(TPersistent)
  86. {TRectangle is extremely important to the functioning of TSciGraph.}
  87. {}
  88. {Not only is it used for a variety of objects, it is also the base class
  89.  of many on-screen objects: Axes, Titles, Captions, Legends, etc.}
  90. {}
  91. {As well as having the properties that one would expect for a rectangle,
  92.  it also has some properties that are useful to its various descendants:
  93.  Alignment, Name and Visibility to be precise.}
  94.   private
  95.     FAlignment: TAlignment;
  96.     FFireEvents: Boolean;
  97.     FLeft: Integer;
  98.     FTop: Integer;
  99.     FRight: Integer;
  100.     FBottom: Integer;
  101.     FName: String;
  102.     FOwner: TPersistent;
  103.     FTag: Longint;
  104.     FVisible: Boolean;
  105.  
  106.   protected
  107.     FOnChange: TNotifyEvent;
  108. {Events are normally private/published, but D1 does not allow descendants to
  109.  check the assignment of events: FOnChange is inaccessible, and OnChange
  110.  cannot be examined because it is a function.}
  111.  
  112. {Get functions for virtual properties:}
  113.     function GetHeight: Integer;
  114.     function GetWidth: Integer;
  115.     function GetMidX: Integer;
  116.     function GetMidY: Integer;
  117.  
  118. {Set procedures that we may wish to override later:}
  119.     procedure SetLeft(Value: Integer); virtual;
  120. {This sets the Left screen position property. It also moves the Right by the
  121.  same amount, thereby preserving the Width. Ie: it moves the whole TRectangle.}
  122.     procedure SetMidX(Value: Integer); virtual;
  123. {This sets the MidX screen virtual position property. It thereby moves the Left and Right.}
  124.     procedure SetMidY(Value: Integer); virtual;
  125. {This sets the MidY screen virtual position property. It thereby moves the Top and Bottom.}
  126.     procedure SetTop(Value: Integer); virtual;
  127. {This sets the Top screen position property. It also moves the Bottom by the
  128.  same amount, thereby preserving the Height. Ie: it moves the whole TRectangle.}
  129.     procedure SetAlignment(Value: TAlignment);
  130.     procedure SetRight(Value: Integer); virtual;
  131.     procedure SetBottom(Value: Integer); virtual;
  132.     procedure SetVisible(Value: Boolean); virtual;
  133.  
  134. {Set procedures for virtual properties:}
  135.     procedure SetHeight(Value: Integer); virtual;
  136.     procedure SetWidth(Value: Integer); virtual;
  137.  
  138.     procedure DoHandleChange; virtual;
  139. {All Set methods call this to handle the OnChange logic.}
  140.   public
  141. {virtual write-only properties:}
  142.     //property DeltaX: Integer write SetDeltaX;
  143. {This changes the Left and Right by DeltaX, thereby moving the TRectangle.
  144.  It is similar to getting then setting the Left property, but quicker.}
  145.     //property DeltaY: Integer write SetDeltaY;
  146. {This changes the Top and Bottom by DeltaY, thereby moving the TRectangle.
  147.  It is similar to getting then setting the Top property, but quicker.}
  148.     property Owner: TPersistent read FOwner;
  149. {This is similar to TComponent.Owner: TComponent, except that:}
  150. {    1. it is a TPersistent;}
  151. {    2. this component is NOT freed automatically when the Owner is freed.}
  152.     property Tag: Longint read FTag write FTag;
  153. {The usual Tag property, as in TComponent.Tag}
  154. {}
  155. {However, DO NOT USE THIS PROPERTY !
  156.  It is used by TPlot to store the object type, and hence control the visible
  157.  behaviour of the TRectangle descendant.}
  158.  
  159.     Constructor Create(AOwner: TPersistent); virtual;
  160. {The standard constructor, where standard properties are set.}
  161.     Destructor Destroy; override;
  162. {The standard destructor, where the OnChange event is "freed".}
  163.  
  164.     {procedure Assign(Source: TPersistent); override;}
  165.     procedure AssignTo(Dest: TPersistent); override;
  166. {TRectangle's implementation of the standard Assign(To) method.}
  167.     procedure AssignToRect(Dest: TRect);
  168. {TRectangle's implementation of a non-standard AssignTo method.}
  169.     function ClickedOn(iX, iY: Integer): Boolean; virtual;
  170. {Was this TRectangle clicked on ?}
  171.     procedure MoveTo(iX, iY: Integer); virtual;
  172. {Move the rectangle to a new (Top, Left) location.}
  173.     procedure MoveBy(dX, dY: Integer); virtual;
  174. {Move the rectangle by (iX, iY) from (Top, Left) to (Top + iX, Left + iY) .}
  175.     procedure Outline(ACanvas: TCanvas); virtual;
  176. {Draws an Outline around this rectangle.}
  177.  
  178.   published
  179.     property Alignment: TAlignment read FAlignment write SetAlignment;
  180. {Can a rectangle have alignment ? Not really, but its descendants can !}
  181.     property FireEvents: Boolean read FFireEvents write FFireEvents;
  182. {Do we fire events in response to a geometry change ?
  183.  For the TCaption descendants, the answer is no, because they dance around
  184.  the screen with every repaint.}
  185.     property Name: String read FName write FName;
  186. {This is what is displayed when the user is offered a choice.
  187.  Eg: "Move the X-Axis Caption or the Bottom Border ?".}
  188.     property Left: Integer read FLeft write SetLeft;
  189. {This is the usual position property.}
  190.     property Top: Integer read FTop write SetTop;
  191. {This is the usual position property.}
  192.     property Right: Integer read FRight write SetRight;
  193. {This is the usual position property.}
  194.     property Bottom: Integer read FBottom write SetBottom;
  195. {This is the usual position property.}
  196.     Property Visible: Boolean read FVisible write SetVisible;
  197. {Is the Rectangle (or its descendants) visible ?}
  198.  
  199. {virtual properties:}
  200.     property Height: Integer read GetHeight write SetHeight;
  201. {The standard Height property.}
  202.     property Width: Integer read GetWidth write SetWidth;
  203. {The standard Width property.}
  204.     property MidX: Integer read GetMidX write SetMidX;
  205. {The X midpoint of the TRectangle.}
  206.     property MidY: Integer read GetMidY write SetMidY;
  207. {The Y midpoint of the TRectangle.}
  208.  
  209.     Property OnChange: TNotifyEvent read FOnChange write FOnChange;
  210. {The standard OnChange event (for geometry).}
  211.   end;
  212.  
  213. {TBorder **********************************************************************}
  214.   TBorder = class(TRectangle)
  215. {TBorder adds a third point to a TRectangle, hence creating a border.
  216.  The following diagram explains this:}
  217. {}
  218. {  Top, Left
  219.    ----------------------------------------====================
  220.    |                                       |                  +        |
  221.    |                                       |                  +        |
  222.    |                                       |                  +        |
  223.    |                                       |                  +        |
  224.    |                   .MidX,MidY          |<----RightGap---->+        |
  225.    |                                       |                  +        |
  226.    |                                       |                  +        |
  227.    |                                       |Right,Bottom      +    HeightEx
  228.    ----------------------------------------********************        |
  229.    +                   |                   *                  #        |
  230.    +                   |                   *                  #        |
  231.    +              BottomGap                *                  #        |
  232.    +                   |                   *                  #        |
  233.    +                   |                   *                  #        |
  234.    +=======================================*###################
  235.                                                                RightEx,BottomEx
  236.    <---------------------------WidthEx------------------------>
  237.    }
  238.   private
  239.     FRightEx: Integer;
  240.     FBottomEx: Integer;
  241.  
  242.     procedure SetRightEx(Value: Integer);
  243.     procedure SetBottomEx(Value: Integer);
  244. {Get functions for the new virtual properties:}
  245.     function GetRightGap: Integer;
  246.     function GetBottomGap: Integer;
  247.     function GetHeightEx: Integer;
  248.     function GetWidthEx: Integer;
  249. {Set procedures for the new virtual properties:}
  250.     procedure SetRightGap(Value: Integer);
  251.     procedure SetBottomGap(Value: Integer);
  252.     procedure SetHeightEx(Value: Integer);
  253.     procedure SetWidthEx(Value: Integer);
  254.  
  255.   protected
  256.     procedure SetLeft(Value: Integer); override;
  257. {Setting the Left also moves the Right and RightEx, thereby preserving the
  258.  Width and RightGap. Ie: it moves the whole TBorder.}
  259.     procedure SetTop(Value: Integer); override;
  260. {Setting the Top also moves the Bottom and BottomEx, thereby preserving the
  261.  Height and BottomGap. Ie: it moves the whole TBorder.}
  262.  
  263.   public
  264.     Constructor Create(AOwner: TPersistent); override;
  265. {The standard constructor, where standard properties are set.}
  266.  
  267.   published
  268.     property RightEx: Integer read FRightEx write SetRightEx;
  269. {The extreme right, to the right of Right.}
  270.     property BottomEx: Integer read FBottomEx write SetBottomEx;
  271. {The extreme Bottom, below Bottom.}
  272.  
  273. {the "virtual" properties:}
  274.     property RightGap: Integer read GetRightGap write SetRightGap;
  275. {The gap (or width) between the Right and RightEx.}
  276.     property BottomGap: Integer read GetBottomGap write SetBottomGap;
  277. {The gap (or height) between the Bottom and BottomEx.}
  278.     property HeightEx: Integer read GetHeightEx write SetHeightEx;
  279. {The total height between the Top and BottomEx.}
  280.     property WidthEx: Integer read GetWidthEx write SetWidthEx;
  281. {The total width between the Left and RightEx.}
  282.   end;
  283.  
  284. {TAngleRect *******************************************************************}
  285. {TAngleRect is extremely important to the functioning of TSciGraph.}
  286. {}
  287. {Not only is it used for a variety of objects, it is also the base class
  288.  of many on-screen objects: Axes, Titles, Captions, Legends, etc.}
  289. {}
  290. {As well as having the properties that one would expect for a rectangle,
  291.  it also has some properties that are useful to its various descendants:
  292.  Alignment, Name and Visibility to be precise.
  293.  
  294.              ^
  295.              .
  296.              .
  297.          __- .
  298.      _O--   \.                           ╪ - Angle between vertical and parallelogram
  299.   _--  \     \                           ╪ = 0  for Y Axis
  300.  \      \    .\                          ╪ = 90  for X Axis
  301.   \      \   . \                         ╪ = 225  for Z Axis
  302.    \      \  .  \
  303.     \      \ .   \                       Real properties are:
  304.      \      \.    \                      Origin(.x,y), Length, Breadth, Angle
  305.       \      ......\..................>
  306.        \      \     \                    Virtual properties are:
  307.         \      \     \                   Left, Top, Right, Bottom,
  308.          \      \     \                  Height, Width
  309.           \      \     \
  310.            \      \     \                Rotation by ╪:
  311.             \      \  __--                [NewX]  =  [cos╪  sin╪][X]
  312.              \    __V-                    [NewY]     [-sin╪ cos╪][Y]
  313.               \_--
  314. }
  315.  
  316.   TAngleRect = class(TRectangle)
  317.   private
  318.     FAngle: TDegrees;
  319.       FAngleRadians: Single;
  320.     FLength,
  321.     FBreadth: Word;
  322.     FCentre: TPoint;
  323.     FOrigin: TPoint;
  324.     FPolyRect: array[0..4] of TPoint;
  325.  
  326.       FSin,
  327.       FCos,
  328.       FSinM30,
  329.       FCosM30,
  330.       FSinP30,
  331.       FCosP30: Extended;
  332.  
  333.   protected
  334.  
  335. {Descendants need access to these sines and cosines:}
  336.     property Sin: Extended read FSin;
  337.     property Cos: Extended read FCos;
  338.     property SinM30: Extended read FSinM30;
  339.     property CosM30: Extended read FCosM30;
  340.     property SinP30: Extended read FSinP30;
  341.     property CosP30: Extended read FCosP30;
  342.  
  343.     procedure DoGeometry;
  344.     function RotatePoint(APoint: TPoint): TPoint;
  345.  
  346. {Real properties:}
  347.     procedure SetAngle(Value: TDegrees);
  348. {Sets the angle of the rectangle to the vertical.}
  349.     procedure SetLength(Value: Word);
  350. {Sets the length of opposite sides parallel to the Vector of the rectangle.}
  351.     procedure SetBreadth(Value: Word);
  352. {Sets the length of opposite sides perpendicular to the Vector of the rectangle.}
  353.     procedure SetOrigin(Value: TPoint);
  354. {This sets the Origin REAL screen position property.}
  355.  
  356. {Get functions for VIRTUAL properties:}
  357.     function GetVector: TPoint; virtual;
  358.  
  359. {Set procedures for virtual properties:}
  360.     procedure SetLeft(Value: Integer); override;
  361. {This sets the Left virtual screen position property,
  362.  thereby changing the MidX, inter alia.}
  363.     procedure SetTop(Value: Integer); override;
  364. {This sets the Top virtual screen position property,
  365.  thereby changing the MidY, inter alia.}
  366.     procedure SetRight(Value: Integer); override;
  367. {This sets the Right virtual screen position property,
  368.  thereby changing the Width, inter alia.}
  369.     procedure SetBottom(Value: Integer); override;
  370. {This sets the Bottom virtual screen position property,
  371.  thereby changing the Height, inter alia.}
  372.  
  373.     procedure SetMidX(Value: Integer); override;
  374. {This sets the MidX screen virtual position property. It thereby moves the Left and Right.}
  375.     procedure SetMidY(Value: Integer); override;
  376. {This sets the MidY screen virtual position property. It thereby moves the Top and Bottom.}
  377.  
  378.     procedure SetHeight(Value: Integer); override;
  379. {This sets the Height virtual screen position property,
  380.  thereby changing the ???, inter alia.}
  381.     procedure SetWidth(Value: Integer); override;
  382. {This sets the Width virtual screen position property,
  383.  thereby changing the ???, inter alia.}
  384.  
  385.     procedure SetCentre(NewCentre: TPoint); virtual;
  386. {This sets the new centre of the Rectangle.}
  387.     procedure SetVector(Value: TPoint); virtual;
  388. {This sets the Vector virtual screen position property,
  389.  thereby changing the Length and Angle.}
  390.  
  391.   public
  392. {$IFDEF BCB}
  393.     property Origin: TPoint read FOrigin write SetOrigin;
  394. {The origin of the Rectangle: eg: (MidY, Left) for an X Axis.}
  395.  
  396. {Now the virtual properties:}
  397.     property Centre: TPoint read FCentre write SetCentre;
  398. {The centre of the rotated rectangle.}
  399.     property Vector: TPoint read GetVector write SetVector;
  400. {The Vector of the Rectangle: eg: (Width, 0) for an X Axis.}
  401. {$ENDIF}
  402.  
  403.     Constructor Create(AOwner: TPersistent); override;
  404. {The standard constructor, where standard properties are set.}
  405.     Destructor Destroy; override;
  406. {The standard destructor, where the OnChange event is "freed".}
  407.  
  408.     procedure AssignTo(Dest: TPersistent); override;
  409. {TRectangle's implementation of the standard Assign(To) method.}
  410.     function ClickedOn(iX, iY: Integer): Boolean; override;
  411. {Was this TRectangle clicked on ?}
  412.     procedure MoveTo(NewX, NewY: Integer); override;
  413. {Move the rectangle to a new (Top, Left) location.}
  414.     procedure MoveBy(dX, dY: Integer); override;
  415. {Move the rectangle by (iX, iY) from (Top, Left) to (Top + iX, Left + iY) .}
  416.     procedure SetNewGeometry(NewOrigin: TPoint; NewAngle: TDegrees; NewLength, NewBreadth: Integer);
  417. {Move the rectangle to a new (Top, Left) location.}
  418.     procedure Outline(ACanvas: TCanvas); override;
  419. {Draws an Outline around this rectangle.}
  420.  
  421.   published
  422. {Real properties:}
  423. {A rectangle does not really have alignment - but its descendants do,
  424.  and it is neccessary to to put the arrows on the axes.
  425.         - taLeftJustify  means that the arrow points towards the Origin
  426.         - taRightJustify means that the arrow points away from the Origin
  427.         - taCenter means no arrow.}
  428.     property Angle: TDegrees read FAngle write SetAngle;
  429. {The angle between the rotated rectangle and the vertical.}
  430.     property Breadth: Word read FBreadth write SetBreadth;
  431. {The broadness of the rectangle - can be either the Width or Height or something else.}
  432.     property Length: Word read FLength write SetLength;
  433. {The Length of the rectangle - can be either the Width or Height or something else.}
  434. {$IFNDEF BCB}
  435.     property Origin: TPoint read FOrigin write SetOrigin;
  436. {The origin of the Rectangle: eg: (MidY, Left) for an X Axis.}
  437.  
  438. {Now the virtual properties:}
  439.     property Centre: TPoint read FCentre write SetCentre;
  440. {The centre of the rotated rectangle.}
  441.     property Vector: TPoint read GetVector write SetVector;
  442. {The Vector of the Rectangle: eg: (Width, 0) for an X Axis.}
  443. {$ENDIF}
  444.   end;
  445.  
  446. {TCaption *********************************************************************}
  447.   TCaption = class(TRectangle)
  448. {A TCaption inherits the positional behaviour of TRectangle,
  449.  and adds a Caption and a Font.}
  450.   private
  451.     FCaption: String;
  452.     FFont: TFont;
  453.  
  454.     FOnCaptionChange: TNotifyEvent;
  455.  
  456.   protected
  457.     procedure CreateName; virtual;
  458. {This sets the name after the Caption is set.}
  459.     procedure SetCaption(Value: String); virtual;
  460. {This sets the Caption and calls CreateName.}
  461.     procedure SetFont(Value: TFont);
  462.   public
  463.     constructor Create(AOwner: TPersistent); override;
  464.     destructor Destroy; override;
  465.  
  466. {The standard constructor, where standard properties are set.}
  467.     {procedure Assign(Source: TPersistent); override;}
  468.     procedure AssignTo(Dest: TPersistent); override;
  469.  
  470.   published
  471.     property Caption: String read FCaption write SetCaption;
  472. {This is the text that is displayed on the screen.
  473.  Eg: "X-Axis". Setting the Caption also sets the Name:}
  474. {}
  475. { FName := FCaption + ' Caption';}
  476.     property Font: TFont read FFont write SetFont;
  477. {The font used to display the caption.}
  478.  
  479.     Property OnCaptionChange: TNotifyEvent read FOnCaptionChange write FOnCaptionChange;
  480. {Has the Caption changed ?}
  481.   end;
  482.  
  483. {TTitle ***********************************************************************}
  484.   TTitle = class(TCaption)
  485. {This is an extended TCaption that dances around the screen depending on
  486.  Alignment, Orientation and Direction, and Draws itself.}
  487.   private
  488.     FDirection : TDirection;
  489.     FOrientation: TOrientation;
  490.     FEnvelope: TRect;
  491.     FUnits: String;
  492.  
  493.     FFullCaption: String;
  494.  
  495.     procedure SetDirection(Value: TDirection);
  496.     procedure SetOrientation(Value: TOrientation);
  497.     procedure SetEnvelope(Value: TRect);
  498.     procedure SetUnits(Value: String);
  499.  
  500.   protected
  501.     procedure DoGeometry(ACanvas: TCanvas; TheText: String); dynamic;
  502. {This determines where the TTitle is exactly on the screen, depending on the
  503.  Envelope, Direction, Orientation and Alignment.}
  504.  
  505.     procedure SetCaption(Value: String); override;
  506. {This handles the tricky question of Caption and Units. If Value contains a
  507.  pair of brackets '()', then the contents of these brackets is taken to be the
  508.  Units. If it doesn't, then the FullCaption is constructed from Value and Units.}
  509.  
  510.   public
  511.     property Envelope: TRect read FEnvelope write SetEnvelope;
  512. {This is the region just outside which the Caption can appear.
  513.  Its exact position will depend on the Alignment, Direction and Orientation}
  514.     property FullCaption: String read FFullCaption;
  515. {This is a read-only property formed from the Caption and the Units.}
  516.  
  517.     constructor Create(AOwner: TPersistent); override;
  518. {The standard constructor, where standard properties are set.}
  519.  
  520.     procedure Draw(ACanvas: TCanvas);
  521.     {procedure Assign(Source: TPersistent); override;}
  522.     procedure AssignTo(Dest: TPersistent); override;
  523. {This Draws the TTitle on the given Canvas. It calls DoGeometry, and also
  524.  various API functions to create a vertical font if neccessary.}
  525.   published
  526.     property Units: String read FUnits write SetUnits;
  527. {These are the physical units, eg: mm, mV, seconds, etc, of the Axis.}
  528.     property Direction : TDirection read FDirection write SetDirection;
  529. {Is the Caption drawn Horizontal or Vertical ?}
  530.     property Orientation: TOrientation read FOrientation write SetOrientation;
  531. {Is the caption to the Left or Right of the Axis ?}
  532.   end;
  533.  
  534. {TLegend **********************************************************************}
  535.   TLegend = class(TRectangle)
  536. {This is an extended TCaption that dances around the screen depending on
  537.  Alignment, Orientation and Direction, and Draws itself.}
  538.   private
  539.     FCheckboxes: Boolean;
  540.     FDirection : TDirection;
  541.     FFont: TFont;
  542.     FFontHeight: Integer;
  543.     FStringWidth: Integer;
  544.     FCheckWidth: Integer;
  545.     FLineWidth: Integer;
  546.     FSeriesList: TList;
  547.  
  548.   protected
  549.     function GetItemWidth: Integer;
  550.     procedure SetCheckboxes(Value: Boolean);
  551.     procedure SetDirection(Value: TDirection);
  552.     procedure SetFont(Value: TFont);
  553.  
  554.     //procedure SetFontHeight(Value: Integer);
  555.     //procedure SetStringWidth(Value: Integer);
  556.  
  557.   public
  558.     property FontHeight: Integer read FFontHeight;
  559. {The height of the font.}
  560.     //property StringWidth: Integer read FStringWidth;
  561. {The width of the text portion of the Legend.}
  562.     //property SymbolWidth: Integer read GetSymbolWidth;
  563. {The width of the Symbol + Line portion of the Legend.}
  564. {It is 1/3rd of the StringWidth.}
  565.     property ItemWidth: Integer read GetItemWidth;
  566.  
  567.     constructor CreateList(AOwner: TPersistent; SeriesList: TList); virtual;
  568.     destructor Destroy; override;
  569.  
  570.     function GetHit(iX, iY: Integer; var TheRect: TRect): Integer;
  571. {The rectangle of the series name under the point iX, iY.}
  572.     procedure Draw(ACanvas: TCanvas; SeriesIncrement: Integer);
  573.  
  574.   published
  575.     property CheckBoxes: Boolean read FCheckBoxes write SetCheckBoxes;
  576. {Display Checkboxes ?}
  577.     property Direction : TDirection read FDirection write SetDirection;
  578. {Is the Legend drawn Horizontal or Vertical ?}
  579.     property Font: TFont read FFont write SetFont;
  580. {The font used to display the caption.}
  581.   end;
  582.  
  583. {TNote ************************************************************************}
  584.   TNote = class(TCaption)
  585.   private
  586.     FArrowLeft: Integer;
  587.     FArrowTop: Integer;
  588.     FArrowLeftReal: Single;
  589.     FArrowTopReal: Single;
  590.     FOwner: TPersistent; {ie: TPlot}
  591.     FLeftReal: Single;
  592.     FTopReal: Single;
  593.     //FOnNoteChange: TNotifyEvent;
  594.  
  595.     ArrowStartLeft: Integer;
  596.     ArrowStartTop: Integer;
  597.  
  598.   protected
  599.     procedure SetLeft(Value: Integer); override;
  600.     procedure SetTop(Value: Integer); override;
  601.     procedure SetArrowLeft(Value: Integer); virtual;
  602.     procedure SetArrowTop(Value: Integer); virtual;
  603.     procedure SetArrowLeftReal(Value: Single); virtual;
  604.     procedure SetArrowTopReal(Value: Single); virtual;
  605.     procedure SetLeftReal(Value: Single); virtual;
  606.     procedure SetTopReal(Value: Single); virtual;
  607.  
  608.   public
  609.     constructor Create(AOwner: TPersistent); override;
  610.     {destructor Destroy; override;}
  611.     procedure AssignTo(Dest: TPersistent); override;
  612.     {procedure Assign(Source: TPersistent); override;}
  613.     procedure Draw(ACanvas: TCanvas);
  614. {This Draws the TTitle on the given Canvas. It calls DoGeometry, and also
  615.  various API functions to create a vertical font if neccessary.}
  616.     procedure TracePointerTo(ACanvas: TCanvas; iX, iY: Integer);
  617.   published
  618.     property ArrowLeft: Integer read FArrowLeft write SetArrowLeft;
  619.     property ArrowTop: Integer read FArrowTop write SetArrowTop;
  620.     property ArrowLeftReal: Single read FArrowLeftReal write SetArrowLeftReal;
  621.     property ArrowTopReal: Single read FArrowTopReal write SetArrowTopReal;
  622.     property LeftReal: Single read FLeftReal write SetLeftReal;
  623.     property TopReal: Single read FTopReal write SetTopReal;
  624.     //Property OnNoteChange: TNotifyEvent read FOnNoteChange write FOnNoteChange;
  625.   end;
  626.  
  627. implementation
  628.  
  629. uses
  630.   Data, Plot;
  631.  
  632. {Constructor and Destructor:-------------------------------------------------}
  633. {------------------------------------------------------------------------------
  634.   Constructor: TRectangle.Create
  635.   Description: Standard Constructor for TRectangle
  636.        Author: Mat Ballard
  637.  Date created: 02/25/2000
  638. Date modified: 02/25/2000 by Mat Ballard
  639.       Purpose: initializes component and properties
  640.  Known Issues:
  641.  ------------------------------------------------------------------------------}
  642. Constructor TRectangle.Create(AOwner: TPersistent);
  643. begin
  644. {First call the ancestor:
  645.   inherited Create; - TObject.Create does nothing}
  646.  
  647.   FOwner := AOwner;
  648.  
  649. {we insert the default values that cannot be "defaulted":}
  650.   FAlignment := taCenter;
  651.   FLeft := 10;
  652.   FTop := 10;
  653.   SetRight(100);
  654.   SetBottom(100);
  655.   FVisible := TRUE;
  656. {global change event handler:}
  657.   FOnChange := nil;
  658. {we do fire events with a geometry change:}
  659.   FireEvents := TRUE;
  660. end;
  661.  
  662. {------------------------------------------------------------------------------
  663.    Destructor: TRectangle.Destroy
  664.   Description: standard destructor
  665.        Author: Mat Ballard
  666.  Date created: 02/25/2000
  667. Date modified: 02/25/2000 by Mat Ballard
  668.       Purpose: frees the OnChange event
  669.  Known Issues:
  670.  ------------------------------------------------------------------------------}
  671. Destructor TRectangle.Destroy;
  672. begin
  673.   FOnChange := nil;
  674. {then call ancestor:}
  675.   inherited Destroy;
  676. end;
  677.  
  678. {------------------------------------------------------------------------------
  679.     Procedure: TRectangle.Assign
  680.   Description: standard Assign method
  681.        Author: Mat Ballard
  682.  Date created: 07/06/2000
  683. Date modified: 07/06/2000 by Mat Ballard
  684.       Purpose: implements Assign
  685.  Known Issues:
  686.  ------------------------------------------------------------------------------}
  687. {procedure TRectangle.Assign(Source: TPersistent);
  688. begin
  689.   inherited Assign(Source);
  690.   FLeft := TRectangle(Source).Left;
  691.   FTop := TRectangle(Source).Top;
  692.   FRight := TRectangle(Source).Right;
  693.   FBottom := TRectangle(Source).Bottom;
  694. end;}
  695.  
  696. {------------------------------------------------------------------------------
  697.     Procedure: TRectangle.AssignTo
  698.   Description: standard AssignTo method
  699.        Author: Mat Ballard
  700.  Date created: 07/06/2000
  701. Date modified: 07/06/2000 by Mat Ballard
  702.       Purpose: implements AssignTo
  703.  Known Issues:
  704.  ------------------------------------------------------------------------------}
  705. procedure TRectangle.AssignTo(Dest: TPersistent);
  706. begin
  707. {we DON'T call the ancestor, because TPersistent.AssignTo simply throws an
  708.  exception:
  709.   inherited AssignTo(Dest);}
  710.   TRectangle(Dest).Left := FLeft;
  711.   TRectangle(Dest).Top := FTop;
  712.   TRectangle(Dest).Right := FRight;
  713.   TRectangle(Dest).Bottom := FBottom;
  714. end;
  715.  
  716. {------------------------------------------------------------------------------
  717.     Procedure: TRectangle.AssignToRect
  718.   Description: non-standard AssignTo method
  719.        Author: Mat Ballard
  720.  Date created: 07/06/2001
  721. Date modified: 07/06/2001 by Mat Ballard
  722.       Purpose: implements a non-standard AssignTo
  723.  Known Issues:
  724.  ------------------------------------------------------------------------------}
  725. procedure TRectangle.AssignToRect(Dest: TRect);
  726. begin
  727.   Dest.Left := FLeft;
  728.   Dest.Top := FTop;
  729.   Dest.Right := FRight;
  730.   Dest.Bottom := FBottom;
  731. end;
  732.  
  733. {Begin Set and Get Functions and Procedures----------------------------------}
  734. {Get Functions for virtual properties ---------------------------------------}
  735. {------------------------------------------------------------------------------
  736.      Function: TRectangle.GetHeight
  737.   Description: private property Get function
  738.        Author: Mat Ballard
  739.  Date created: 02/25/2000
  740. Date modified: 02/25/2000 by Mat Ballard
  741.       Purpose: Gets the Height, which is a virtual property
  742.  Known Issues:
  743.  ------------------------------------------------------------------------------}
  744. function TRectangle.GetHeight: Integer;
  745. begin
  746.   GetHeight := FBottom -  FTop;
  747. end;
  748.  
  749. {------------------------------------------------------------------------------
  750.      Function: TRectangle.GetWidth
  751.   Description: private property Get function
  752.        Author: Mat Ballard
  753.  Date created: 02/25/2000
  754. Date modified: 02/25/2000 by Mat Ballard
  755.       Purpose: Gets the Width, which is a virtual property
  756.  Known Issues:
  757.  ------------------------------------------------------------------------------}
  758. function TRectangle.GetWidth: Integer;
  759. begin
  760.   GetWidth := FRight - FLeft;
  761. end;
  762.  
  763. {------------------------------------------------------------------------------
  764.      Function: TRectangle.GetMidX
  765.   Description: private property Get function
  766.        Author: Mat Ballard
  767.  Date created: 02/25/2000
  768. Date modified: 02/25/2000 by Mat Ballard
  769.       Purpose: Gets the MidX, which is a virtual property
  770.  Known Issues:
  771.  ------------------------------------------------------------------------------}
  772. function TRectangle.GetMidX: Integer;
  773. begin
  774.   GetMidX := (FLeft + FRight) div 2;
  775. end;
  776.  
  777. {------------------------------------------------------------------------------
  778.      Function: TRectangle.GetMidY
  779.   Description: private property Get function
  780.        Author: Mat Ballard
  781.  Date created: 02/25/2000
  782. Date modified: 02/25/2000 by Mat Ballard
  783.       Purpose: Gets the MidY, which is a virtual property
  784.  Known Issues:
  785.  ------------------------------------------------------------------------------}
  786. function TRectangle.GetMidY: Integer;
  787. begin
  788.   GetMidY := (FTop + FBottom) div 2;
  789. end;
  790.  
  791. {Set Procedures -------------------------------------------------------------}
  792. {------------------------------------------------------------------------------
  793.     Procedure: TRectangle.SetAlignment
  794.   Description: private property Set procedure
  795.        Author: Mat Ballard
  796.  Date created: 02/25/2000
  797. Date modified: 02/25/2000 by Mat Ballard
  798.       Purpose: sets the Alignment
  799.  Known Issues:
  800.  ------------------------------------------------------------------------------}
  801. procedure TRectangle.SetAlignment(Value: TAlignment);
  802. begin
  803.   if (Value = FAlignment) then exit;
  804.  
  805.   FAlignment := Value;
  806.   DoHandleChange;
  807. end;
  808.  
  809. {------------------------------------------------------------------------------
  810.     Procedure: TRectangle.SetLeft
  811.   Description: protected property Set procedure
  812.        Author: Mat Ballard
  813.  Date created: 02/25/2000
  814. Date modified: 02/25/2000 by Mat Ballard
  815.       Purpose: sets the Left, which also moves the Right, thereby preserving the Width
  816.  Known Issues:
  817.  ------------------------------------------------------------------------------}
  818. procedure TRectangle.SetLeft(Value: Integer);
  819. begin
  820.   if (Value = FLeft) then exit;
  821.   FRight := FRight + (Value - FLeft);
  822.   FLeft := Value;
  823.   DoHandleChange;
  824. end;
  825.  
  826. {------------------------------------------------------------------------------
  827.     Procedure: TRectangle.SetTop
  828.   Description: protected property Set procedure
  829.        Author: Mat Ballard
  830.  Date created: 02/25/2000
  831. Date modified: 02/25/2000 by Mat Ballard
  832.       Purpose: sets the Top, which also also moves the Bottom, thereby preserving the Height
  833.  Known Issues:
  834.  ------------------------------------------------------------------------------}
  835. procedure TRectangle.SetTop(Value: Integer);
  836. begin
  837.   if (Value = FTop) then exit;
  838.   FBottom := FBottom + (Value - FTop);
  839.   FTop := Value;
  840.   DoHandleChange;
  841. end;
  842.  
  843. {------------------------------------------------------------------------------
  844.     Procedure: TRectangle.SetRight
  845.   Description: private property Set procedure
  846.        Author: Mat Ballard
  847.  Date created: 02/25/2000
  848. Date modified: 02/25/2000 by Mat Ballard
  849.       Purpose: sets the Right
  850.  Known Issues:
  851.  ------------------------------------------------------------------------------}
  852. procedure TRectangle.SetRight(Value: Integer);
  853. begin
  854.   if (Value = FRight) then exit;
  855.   FRight := Value;
  856.   DoHandleChange;
  857. end;
  858.  
  859. {------------------------------------------------------------------------------
  860.     Procedure: TRectangle.SetBottom
  861.   Description: private property Set procedure
  862.        Author: Mat Ballard
  863.  Date created: 02/25/2000
  864. Date modified: 02/25/2000 by Mat Ballard
  865.       Purpose: sets the Bottom
  866.  Known Issues:
  867.  ------------------------------------------------------------------------------}
  868. procedure TRectangle.SetBottom(Value: Integer);
  869. begin
  870.   if (Value = FBottom) then exit;
  871.   FBottom := Value;
  872.   DoHandleChange;
  873. end;
  874.  
  875. {Set procedures for virtual properties ---------------------------------------}
  876. {------------------------------------------------------------------------------
  877.     Procedure: TRectangle.SetHeight
  878.   Description: private property Set procedure
  879.        Author: Mat Ballard
  880.  Date created: 02/25/2000
  881. Date modified: 02/25/2000 by Mat Ballard
  882.       Purpose: sets the Height, a virtual property, by moving the Bottom
  883.  Known Issues:
  884.  ------------------------------------------------------------------------------}
  885. procedure TRectangle.SetHeight(Value: Integer);
  886. begin
  887.   if ((Value = 0) or (Value = GetHeight)) then exit;
  888.   Inc(FBottom, Value - (FBottom - FTop));
  889.   DoHandleChange;
  890. end;
  891.  
  892. {------------------------------------------------------------------------------
  893.     Procedure: TRectangle.SetWidth
  894.   Description: private property Set procedure
  895.        Author: Mat Ballard
  896.  Date created: 02/25/2000
  897. Date modified: 02/25/2000 by Mat Ballard
  898.       Purpose: sets the Width, a virtual property, by moving the Right
  899.  Known Issues:
  900.  ------------------------------------------------------------------------------}
  901. procedure TRectangle.SetWidth(Value: Integer);
  902. begin
  903.   if ((Value = 0) or (Value = GetWidth)) then exit;
  904.   Inc(FRight, Value - (FRight - FLeft));
  905.   DoHandleChange;
  906. end;
  907.  
  908. {------------------------------------------------------------------------------
  909.     Procedure: TRectangle.SetMidX
  910.   Description: private property Set procedure
  911.        Author: Mat Ballard
  912.  Date created: 02/25/2000
  913. Date modified: 02/25/2000 by Mat Ballard
  914.       Purpose: sets the MidX, a virtual property, by moving the Left and Right
  915.  Known Issues:
  916.  ------------------------------------------------------------------------------}
  917. procedure TRectangle.SetMidX(Value: Integer);
  918. var
  919.   OldMidX: Integer;
  920.   Change: Integer;
  921. begin
  922.   if (Value = GetMidX) then exit;
  923.   OldMidX := (FRight + FLeft) div 2;
  924.   Change := Value - OldMidX;
  925.   Inc(FLeft, Change);
  926.   Inc(FRight, Change);
  927.   DoHandleChange;
  928. end;
  929.  
  930. {------------------------------------------------------------------------------
  931.     Procedure: TRectangle.SetMidY
  932.   Description: private property Set procedure
  933.        Author: Mat Ballard
  934.  Date created: 02/25/2000
  935. Date modified: 02/25/2000 by Mat Ballard
  936.       Purpose: sets the MidY, a virtual property, by moving the Top and Bottom
  937.  Known Issues:
  938.  ------------------------------------------------------------------------------}
  939. procedure TRectangle.SetMidY(Value: Integer);
  940. var
  941.   OldMidY: Integer;
  942.   Change: Integer;
  943. begin
  944.   if (Value = GetMidY) then exit;
  945.   OldMidY := (FTop + FBottom) div 2;
  946.   Change := Value - OldMidY;
  947.   Inc(FTop, Change);
  948.   Inc(FBottom, Change);
  949.   DoHandleChange;
  950. end;
  951.  
  952. {------------------------------------------------------------------------------
  953.     Procedure: TRectangle.SetDeltaX
  954.   Description: private property Set procedure
  955.        Author: Mat Ballard
  956.  Date created: 02/25/2000
  957. Date modified: 02/25/2000 by Mat Ballard
  958.       Purpose: moves the Rectangle in the X direction, by changing the Left and Right
  959.  Known Issues:
  960.  ------------------------------------------------------------------------------}
  961. {procedure TRectangle.SetDeltaX(Value: Integer);
  962. begin
  963.   if (Value = 0) then exit;
  964.   Inc(FLeft, Value);
  965.   Inc(FRight, Value);
  966.   DoHandleChange;
  967. end;}
  968.  
  969. {------------------------------------------------------------------------------
  970.     Procedure: TRectangle.SetDeltaY
  971.   Description: private property Set procedure
  972.        Author: Mat Ballard
  973.  Date created: 02/25/2000
  974. Date modified: 02/25/2000 by Mat Ballard
  975.       Purpose: moves the Rectangle in the Y direction, by changing the Top and Bottom
  976.  Known Issues:
  977.  ------------------------------------------------------------------------------}
  978. {procedure TRectangle.SetDeltaY(Value: Integer);
  979. begin
  980.   if (Value = 0) then exit;
  981.   Inc(FTop, Value);
  982.   Inc(FBottom, Value);
  983.   DoHandleChange;
  984. end;}
  985.  
  986. {------------------------------------------------------------------------------
  987.     Procedure: TRectangle.SetVisible
  988.   Description: private property Set procedure
  989.        Author: Mat Ballard
  990.  Date created: 02/25/2000
  991. Date modified: 02/25/2000 by Mat Ballard
  992.       Purpose: sets the Visibility
  993.  Known Issues:
  994.  ------------------------------------------------------------------------------}
  995. procedure TRectangle.SetVisible(Value: Boolean);
  996. begin
  997.   if (FVisible = Value) then exit;
  998.   FVisible := Value;
  999.   DoHandleChange;
  1000. end;
  1001.  
  1002. {------------------------------------------------------------------------------
  1003.     Procedure: TRectangle.ClickedOn
  1004.   Description: Was this TRectangle clicked on ?
  1005.        Author: Mat Ballard
  1006.  Date created: 01/22/2001
  1007. Date modified: 01/22/2001 by Mat Ballard
  1008.       Purpose: screen click management
  1009.  Known Issues:
  1010.  ------------------------------------------------------------------------------}
  1011. function TRectangle.ClickedOn(iX, iY: Integer): Boolean;
  1012. begin
  1013.   if ((FLeft <= iX) and
  1014.       (iX <= FRight) and
  1015.       (FTop <= iY) and
  1016.       (iY <= FBottom) and
  1017.       (FVisible)) then
  1018.     ClickedOn := TRUE
  1019.    else
  1020.     ClickedOn := FALSE; 
  1021. end;
  1022.  
  1023. {------------------------------------------------------------------------------
  1024.     Procedure: TRectangle.Outline
  1025.   Description: Draws an Outline around this rectangle
  1026.        Author: Mat Ballard
  1027.  Date created: 01/22/2001
  1028. Date modified: 01/22/2001 by Mat Ballard
  1029.       Purpose: gives the user a guide to what they are moving with the mouse
  1030.  Known Issues:
  1031.  ------------------------------------------------------------------------------}
  1032. procedure TRectangle.Outline(ACanvas: TCanvas);
  1033. begin
  1034.   ACanvas.Pen.Color := clBlack;
  1035.   ACanvas.Pen.Mode := pmNotXOR;
  1036.   ACanvas.Pen.Style := psDash;
  1037.   ACanvas.Rectangle(FLeft, FTop, FRight, FBottom);
  1038. end;
  1039.  
  1040. {------------------------------------------------------------------------------
  1041.     Procedure: TRectangle.MoveTo
  1042.   Description: Move the rectangle to a new (Top, Left) location.
  1043.        Author: Mat Ballard
  1044.  Date created: 06/12/2001
  1045. Date modified: 06/12/2001 by Mat Ballard
  1046.       Purpose: location / geometry management
  1047.  Known Issues:
  1048.  ------------------------------------------------------------------------------}
  1049. procedure TRectangle.MoveTo(iX, iY: Integer); 
  1050. begin
  1051.   if ((FLeft = iX) and (FTop = iY)) then exit;
  1052.  
  1053.   FRight := FRight + (iX - FLeft);
  1054.   FLeft := iX;
  1055. {Trigger a change event:}
  1056.   Top := iY;
  1057. end;
  1058.  
  1059. {------------------------------------------------------------------------------
  1060.     Procedure: TRectangle.MoveBy
  1061.   Description: Move the rectangle by (iX, iY) from (Top, Left) to (Top + iX, Left + iY).
  1062.        Author: Mat Ballard
  1063.  Date created: 06/12/2001
  1064. Date modified: 06/12/2001 by Mat Ballard
  1065.       Purpose: location / geometry management
  1066.  Known Issues:
  1067.  ------------------------------------------------------------------------------}
  1068. procedure TRectangle.MoveBy(dX, dY: Integer);
  1069. begin
  1070.   if ((dX = 0) and (dY = 0)) then exit;
  1071.  
  1072.   Inc(FRight, dX);
  1073.   Inc(FLeft, dX);
  1074. {Trigger a change event:}
  1075.   Top := FTop + dY;
  1076. end;
  1077.  
  1078. {------------------------------------------------------------------------------
  1079.     Procedure: TRectangle.DoHandleChange
  1080.   Description: private property Set procedure
  1081.        Author: Mat Ballard
  1082.  Date created: 02/27/2000
  1083. Date modified: 02/27/2000 by Mat Ballard
  1084.       Purpose: all Change Event firing passes through here
  1085.  Known Issues:
  1086.  ------------------------------------------------------------------------------}
  1087. procedure TRectangle.DoHandleChange;
  1088. begin
  1089.   if (FireEvents and assigned(FOnChange) and FVisible) then OnChange(Self);
  1090. end;
  1091.  
  1092. {TBorder Constructor and Destructor:-------------------------------------------}
  1093. {------------------------------------------------------------------------------
  1094.   Constructor: TBorder.Create
  1095.   Description: Standard Constructor for TBorder
  1096.        Author: Mat Ballard
  1097.  Date created: 02/25/2000
  1098. Date modified: 02/25/2000 by Mat Ballard
  1099.       Purpose: initializes component and properties
  1100.  Known Issues:
  1101.  ------------------------------------------------------------------------------}
  1102. Constructor TBorder.Create(AOwner: TPersistent);
  1103. begin
  1104. {First call the ancestor:}
  1105.   inherited Create(AOwner);
  1106.  
  1107. {we insert the default values that cannot be "defaulted":}
  1108.   FRightEx := Right + 10;
  1109.   FBottomEx := Bottom + 10;
  1110. end;
  1111.  
  1112. {Begin Get Functions --------------------------------------------------------}
  1113. {the "virtual" properties:}
  1114. {------------------------------------------------------------------------------
  1115.      Function: TBorder.GetRightGap
  1116.   Description: private property Get function
  1117.        Author: Mat Ballard
  1118.  Date created: 02/25/2000
  1119. Date modified: 02/25/2000 by Mat Ballard
  1120.       Purpose: Gets the Right Gap
  1121.  Known Issues:
  1122.  ------------------------------------------------------------------------------}
  1123. function TBorder.GetRightGap: Integer;
  1124. begin
  1125.   GetRightGap := FRightEx - Right;
  1126. end;
  1127.  
  1128. {------------------------------------------------------------------------------
  1129.      Function: TBorder.GetBottomGap
  1130.   Description: private property Get function
  1131.        Author: Mat Ballard
  1132.  Date created: 02/25/2000
  1133. Date modified: 02/25/2000 by Mat Ballard
  1134.       Purpose: Gets the Bottom Gap
  1135.  Known Issues:
  1136.  ------------------------------------------------------------------------------}
  1137. function TBorder.GetBottomGap: Integer;
  1138. begin
  1139.   GetBottomGap := FBottomEx - Bottom;
  1140. end;
  1141.  
  1142. {------------------------------------------------------------------------------
  1143.      Function: TBorder.GetHeightEx
  1144.   Description: private property Get function
  1145.        Author: Mat Ballard
  1146.  Date created: 02/25/2000
  1147. Date modified: 02/25/2000 by Mat Ballard
  1148.       Purpose: Gets the Total Height (Height + BottomGap)
  1149.  Known Issues:
  1150.  ------------------------------------------------------------------------------}
  1151. function TBorder.GetHeightEx: Integer;
  1152. begin
  1153.   GetHeightEx := FBottomEx - Top;
  1154. end;
  1155.  
  1156. {------------------------------------------------------------------------------
  1157.      Function: TBorder.GetWidthEx
  1158.   Description: private property Get function
  1159.        Author: Mat Ballard
  1160.  Date created: 02/25/2000
  1161. Date modified: 02/25/2000 by Mat Ballard
  1162.       Purpose: Gets the Total Width (Width + RightGap)
  1163.  Known Issues:
  1164.  ------------------------------------------------------------------------------}
  1165. function TBorder.GetWidthEx: Integer;
  1166. begin
  1167.   GetWidthEx := FRightEx - Left;
  1168. end;
  1169.  
  1170. {Begin Set Procedures -------------------------------------------------------}
  1171. {------------------------------------------------------------------------------
  1172.     Procedure: TBorder.SetLeft
  1173.   Description: protected property Set procedure
  1174.        Author: Mat Ballard
  1175.  Date created: 02/25/2000
  1176. Date modified: 02/25/2000 by Mat Ballard
  1177.       Purpose: sets the Left, which DOES NOT move the Right and the RightEx, unlike TRectangle.SetLeft
  1178.  Known Issues:
  1179.  ------------------------------------------------------------------------------}
  1180. procedure TBorder.SetLeft(Value: Integer);
  1181. begin
  1182.   if (Value = FLeft) then exit;
  1183.   FLeft := Value;
  1184.   DoHandleChange;
  1185. end;
  1186.  
  1187. {------------------------------------------------------------------------------
  1188.     Procedure: TBorder.SetTop
  1189.   Description: protected property Set procedure
  1190.        Author: Mat Ballard
  1191.  Date created: 02/25/2000
  1192. Date modified: 02/25/2000 by Mat Ballard
  1193.       Purpose: sets the Top, which DOES NOT move the Bottom and BottomEx, unlike TRectangle.SetTop
  1194.  Known Issues:
  1195.  ------------------------------------------------------------------------------}
  1196. procedure TBorder.SetTop(Value: Integer);
  1197. begin
  1198.   if (Value = FTop) then exit;
  1199.   FTop := Value;
  1200.   DoHandleChange;
  1201. end;
  1202.  
  1203. {------------------------------------------------------------------------------
  1204.     Procedure: TBorder.SetRightEx
  1205.   Description: private property Set procedure
  1206.        Author: Mat Ballard
  1207.  Date created: 02/25/2000
  1208. Date modified: 02/25/2000 by Mat Ballard
  1209.       Purpose: sets the RightEx
  1210.       Comment: the design philosophy is that changing the RightEx changes the value
  1211.                of both Right, AND RightEX. If the user changes the RightEx, then that is about
  1212.                making the whole object bigger.
  1213.  Known Issues:
  1214.  ------------------------------------------------------------------------------}
  1215. procedure TBorder.SetRightEx(Value: Integer);
  1216. var
  1217.   Change: Integer;
  1218. begin
  1219.   if (Value = FRightEx) then exit;
  1220.   Change := Value - FRightEx;
  1221.   FRightEx := Value;
  1222.   Inc(FRight, Change);
  1223.   DoHandleChange;
  1224. end;
  1225.  
  1226. {------------------------------------------------------------------------------
  1227.     Procedure: TBorder.SetBottomEx
  1228.   Description: private property Set procedure
  1229.        Author: Mat Ballard
  1230.  Date created: 02/25/2000
  1231. Date modified: 02/25/2000 by Mat Ballard
  1232.       Purpose: sets the BottomEx
  1233.      Comments: See comments for SetRightEx
  1234.  Known Issues:
  1235.  ------------------------------------------------------------------------------}
  1236. procedure TBorder.SetBottomEx(Value: Integer);
  1237. var
  1238.   Change: Integer;
  1239. begin
  1240.   if (Value = FBottomEx) then exit;
  1241.   Change := Value - FBottomEx;
  1242.   FBottomEx := Value;
  1243.   Inc(FBottom, Change);
  1244.   DoHandleChange;
  1245. end;
  1246.  
  1247. {Begin Set Procedures for virtual properties --------------------------------}
  1248. {------------------------------------------------------------------------------
  1249.     Procedure: TBorder.SetRightGap
  1250.   Description: private property Set procedure
  1251.        Author: Mat Ballard
  1252.  Date created: 02/25/2000
  1253. Date modified: 02/25/2000 by Mat Ballard
  1254.       Purpose: sets the Right Gap
  1255.       Comment: the design philosophy is that changing the Right Gap changes the value
  1256.                of Right, NOT RightEX. If the user changes the gap, then that is about
  1257.                re-apportioning the available space (Left -> RightEx) between the Right Gap and
  1258.                the Width (Right-Left)
  1259.  Known Issues:
  1260.  ------------------------------------------------------------------------------}
  1261. procedure TBorder.SetRightGap(Value: Integer);
  1262. var
  1263.   OldRightGap, Change, NewRight: Integer;
  1264. begin
  1265.   if (Value <= 0) then exit;
  1266.   if (Value = GetRightGap) then exit;
  1267.  
  1268.   OldRightGap := FRightEx - Right;
  1269.   Change := Value - OldRightGap;
  1270.   NewRight := Right - Change;
  1271.  
  1272.   if (NewRight <= Left) then exit;
  1273.  
  1274.   Right := NewRight;
  1275.   DoHandleChange;
  1276. end;
  1277.  
  1278. {------------------------------------------------------------------------------
  1279.     Procedure: TBorder.SetBottomGap
  1280.   Description: private property Set procedure
  1281.        Author: Mat Ballard
  1282.  Date created: 02/25/2000
  1283. Date modified: 02/25/2000 by Mat Ballard
  1284.       Purpose: sets the Bottom Gap.
  1285.       Comment: See comments for SetRightGap
  1286.  Known Issues:
  1287.  ------------------------------------------------------------------------------}
  1288. procedure TBorder.SetBottomGap(Value: Integer);
  1289. var
  1290.   OldBottomGap, Change, NewBottom: Integer;
  1291. begin
  1292.   if (Value <= 0) then exit;
  1293.   if (Value = GetBottomGap) then exit;
  1294.  
  1295.   OldBottomGap := FBottomEx - Bottom;
  1296.   Change := Value - OldBottomGap;
  1297.   NewBottom := Bottom - Change;
  1298.  
  1299.   if (NewBottom <= Top) then exit;
  1300.  
  1301.   Bottom := NewBottom;
  1302.   DoHandleChange;
  1303. end;
  1304.  
  1305. {------------------------------------------------------------------------------
  1306.     Procedure: TBorder.SetHeightEx
  1307.   Description: private property Set procedure
  1308.        Author: Mat Ballard
  1309.  Date created: 02/25/2000
  1310. Date modified: 02/25/2000 by Mat Ballard
  1311.       Purpose: sets the
  1312.       Comment: the design philosophy is that changing the Total Height changes the value
  1313.                of Bottom AND BottomEX. If the user changes the Total Height, then that is about
  1314.                making the Height larger or smaller whilst preserving the BottomGap
  1315.  Known Issues:
  1316.  ------------------------------------------------------------------------------}
  1317. procedure TBorder.SetHeightEx(Value: Integer);
  1318. var
  1319.   OldHeightEx, Change: Integer;
  1320. begin
  1321.   if (Value <= GetBottomGap) then exit;
  1322.   if (Value = GetHeightEx) then exit;
  1323.  
  1324.   OldHeightEx := FBottomEx - Top;
  1325.   Change := Value - OldHeightEx;
  1326.  
  1327.   Bottom := Bottom + Change;
  1328.   Inc(FBottomEx, Change);
  1329.   DoHandleChange;
  1330. end;
  1331.  
  1332. {------------------------------------------------------------------------------
  1333.     Procedure: TBorder.SetWidthEx
  1334.   Description: private property Set procedure
  1335.        Author: Mat Ballard
  1336.  Date created: 02/25/2000
  1337. Date modified: 02/25/2000 by Mat Ballard
  1338.       Purpose: sets the WidthEx
  1339.      Comments: See comment about SetHeightEx
  1340.  Known Issues:
  1341.  ------------------------------------------------------------------------------}
  1342. procedure TBorder.SetWidthEx(Value: Integer);
  1343. var
  1344.   OldWidthEx, Change: Integer;
  1345. begin
  1346.   if (Value <= GetRightGap) then exit;
  1347.   if (Value = GetWidthEx) then exit;
  1348.  
  1349.   OldWidthEx := FRightEx - Left;
  1350.   Change := Value - OldWidthEx;
  1351.  
  1352.   Right := Right + Change;
  1353.   Inc(FRightEx, Change);
  1354.   DoHandleChange;
  1355. end;
  1356.  
  1357. {Constructor and Destructor:-------------------------------------------------}
  1358. {------------------------------------------------------------------------------
  1359.   Constructor: TAngleRect.Create
  1360.   Description: Standard Constructor for TRectangle
  1361.        Author: Mat Ballard
  1362.  Date created: 02/25/2000
  1363. Date modified: 02/25/2000 by Mat Ballard
  1364.       Purpose: initializes component and properties
  1365.  Known Issues:
  1366.  ------------------------------------------------------------------------------}
  1367. Constructor TAngleRect.Create(AOwner: TPersistent);
  1368. begin
  1369. {First call the ancestor:
  1370.   inherited Create; - TObject.Create does nothing}
  1371.  
  1372.   FOwner := AOwner;
  1373.  
  1374. {we insert the default values that cannot be "defaulted":}
  1375.   FAlignment := taCenter;
  1376.   FOrigin.x := 100;
  1377.   FOrigin.y := 100;
  1378.   FLength := 100;
  1379.   FBreadth := 50;
  1380.   FVisible := TRUE;
  1381. {global change event handler:}
  1382.   FOnChange := nil;
  1383. {we do fire events with a geometry change:}
  1384.   FireEvents := TRUE;
  1385.   Angle := 90;
  1386. end;
  1387.  
  1388. {------------------------------------------------------------------------------
  1389.    Destructor: TAngleRect.Destroy
  1390.   Description: standard destructor
  1391.        Author: Mat Ballard
  1392.  Date created: 02/25/2000
  1393. Date modified: 02/25/2000 by Mat Ballard
  1394.       Purpose: frees the OnChange event
  1395.  Known Issues:
  1396.  ------------------------------------------------------------------------------}
  1397. Destructor TAngleRect.Destroy;
  1398. begin
  1399.   FOnChange := nil;
  1400. {then call ancestor:}
  1401.   inherited Destroy;
  1402. end;
  1403.  
  1404. {------------------------------------------------------------------------------
  1405.     Procedure: TAngleRect.AssignTo
  1406.   Description: standard AssignTo method
  1407.        Author: Mat Ballard
  1408.  Date created: 07/06/2000
  1409. Date modified: 07/06/2000 by Mat Ballard
  1410.       Purpose: implements AssignTo
  1411.  Known Issues:
  1412.  ------------------------------------------------------------------------------}
  1413. procedure TAngleRect.AssignTo(Dest: TPersistent);
  1414. begin
  1415.   TAngleRect(Dest).Angle := FAngle;
  1416.   TAngleRect(Dest).Origin := FOrigin;
  1417.   TAngleRect(Dest).Length := FLength;
  1418.   TAngleRect(Dest).Breadth := FBreadth;
  1419. end;
  1420.  
  1421. {------------------------------------------------------------------------------
  1422.     Procedure: TAngleRect.DoGeometry
  1423.   Description: works out where the corners of the rectangle are.
  1424.        Author: Mat Ballard
  1425.  Date created: 06/08/2001
  1426. Date modified: 06/08/2000 by Mat Ballard
  1427.       Purpose: geometry management
  1428.  Known Issues:
  1429.  ------------------------------------------------------------------------------}
  1430. procedure TAngleRect.DoGeometry;
  1431. var
  1432.   i: Integer;
  1433. begin
  1434. {Step 1: calculate centre:}
  1435.   FCentre.x := FOrigin.x + Round(FSin * FLength / 2.0);
  1436.   FCentre.y := FOrigin.y - Round(FCos * FLength / 2.0);
  1437.  
  1438. {Step 2: set up rectangle of corners:}
  1439.   FPolyRect[0].x := - (FBreadth div 2);
  1440.   FPolyRect[0].y := - (FLength div 2);
  1441.   FPolyRect[1].x := FPolyRect[0].x + FBreadth;
  1442.   FPolyRect[1].y := FPolyRect[0].y;
  1443.   FPolyRect[2].x := FPolyRect[1].x;
  1444.   FPolyRect[2].y := FPolyRect[1].y + FLength;
  1445.   FPolyRect[3].x := FPolyRect[0].x;
  1446.   FPolyRect[3].y := FPolyRect[2].y;
  1447.  
  1448. {Step 3: rotate and translate}
  1449.   for i := 0 to 3 do
  1450.   begin
  1451.     FPolyRect[i] := RotatePoint(FPolyRect[i]);
  1452.     FPolyRect[i].x := FPolyRect[i].x + FCentre.x;
  1453.     FPolyRect[i].y := FPolyRect[i].y + FCentre.y;
  1454.   end;
  1455. {Need to close the polyline:}
  1456.   FPolyRect[4].x := FPolyRect[0].x;
  1457.   FPolyRect[4].y := FPolyRect[0].y;
  1458.  
  1459. {Calculate the positions:}
  1460. {Left:}
  1461.   FLeft := FPolyRect[0].x;
  1462.   if (FPolyRect[1].x < FLeft) then
  1463.     FLeft := FPolyRect[1].x;
  1464.   if (FPolyRect[2].x < FLeft) then
  1465.     FLeft := FPolyRect[2].x;
  1466.   if (FPolyRect[3].x < FLeft) then
  1467.     FLeft := FPolyRect[3].x;
  1468.  
  1469. {Top:}
  1470.   FTop := FPolyRect[0].y;
  1471.   if (FPolyRect[1].y < FPolyRect[0].y) then
  1472.     FTop := FPolyRect[1].y;
  1473.   if (FPolyRect[2].y < FTop) then
  1474.     FTop := FPolyRect[2].y;
  1475.   if (FPolyRect[3].y < FTop) then
  1476.     FTop := FPolyRect[3].y;
  1477.  
  1478. {Right}
  1479.   FRight := FPolyRect[0].x;
  1480.   if (FPolyRect[1].x > FPolyRect[0].x) then
  1481.     FRight := FPolyRect[1].x;
  1482.   if (FPolyRect[2].x > FRight) then
  1483.     FRight := FPolyRect[2].x;
  1484.   if (FPolyRect[3].x > FRight) then
  1485.     FRight := FPolyRect[3].x;
  1486.  
  1487. {Bottom:}
  1488.   FBottom := FPolyRect[0].y;
  1489.   if (FPolyRect[1].y > FPolyRect[0].y) then
  1490.     FBottom := FPolyRect[1].y;
  1491.   if (FPolyRect[2].y > FBottom) then
  1492.     FBottom := FPolyRect[2].y;
  1493.   if (FPolyRect[3].y > FBottom) then
  1494.     FBottom := FPolyRect[3].y;
  1495.  
  1496.   DoHandleChange;
  1497. end;
  1498.  
  1499. {------------------------------------------------------------------------------
  1500.      Function: TAngleRect.RotatePoint
  1501.   Description: rotates a point about the Centre
  1502.        Author: Mat Ballard
  1503.  Date created: 02/25/2000
  1504. Date modified: 02/25/2000 by Mat Ballard
  1505.       Purpose: geometry management
  1506.  Return Value: TPoint;
  1507.  Known Issues:
  1508.     Equations: Rotation by ╪:
  1509.                 [NewX]  =  [cos╪  sin╪][X]
  1510.                 [NewY]     [-sin╪ cos╪][Y]
  1511.  ------------------------------------------------------------------------------}
  1512. function TAngleRect.RotatePoint(APoint: TPoint): TPoint;
  1513. begin
  1514.   Result.x := Round(FCos * APoint.x - FSin * APoint.y);
  1515.   Result.y := Round(FSin * APoint.x + FCos * APoint.y);
  1516. end;
  1517.  
  1518. {Begin Set and Get Functions and Procedures----------------------------------}
  1519. {Set Procedure for REAL properties ---------------------------------------}
  1520. {------------------------------------------------------------------------------
  1521.     Procedure: TAngleRect.SetAngle
  1522.   Description: standard property Set procedure
  1523.        Author: Mat Ballard
  1524.  Date created: 06/06/2001
  1525. Date modified: 06/06/2001 by Mat Ballard
  1526.       Purpose: sets the Angle Property
  1527.  Known Issues:
  1528.  ------------------------------------------------------------------------------}
  1529. procedure TAngleRect.SetAngle(Value: TDegrees);
  1530. begin
  1531.   FAngle := Value;
  1532.   FAngleRadians := Pi * FAngle / 180;
  1533.   if (FAngle = 0) then
  1534.   begin
  1535.     FSin := 0;
  1536.     FCos := 1;
  1537.     FSinM30 := -SIN_30;
  1538.     FCosM30 := COS_30;
  1539.     FSinP30 := SIN_30;
  1540.     FCosP30 := COS_30;
  1541.   end
  1542.   else if (FAngle = 90) then
  1543.   begin
  1544.     FSin := 1;
  1545.     FCos := 0;
  1546.     FSinM30 := SIN_60;
  1547.     FCosM30 := COS_60;
  1548.     FSinP30 := SIN_60;
  1549.     FCosP30 := -COS_60;
  1550.   end
  1551.   else if (FAngle = 180) then
  1552.   begin
  1553.     FSin := 0;
  1554.     FCos := -1;
  1555.     FSinM30 := SIN_30;
  1556.     FCosM30 := -COS_30;
  1557.     FSinP30 := -SIN_30;
  1558.     FCosP30 := -COS_30;
  1559.   end
  1560.   else if (FAngle = 270) then
  1561.   begin
  1562.     FSin := -1;
  1563.     FCos := 0;
  1564.     FSinM30 := -SIN_60;
  1565.     FCosM30 := -COS_60;
  1566.     FSinP30 := -SIN_60;
  1567.     FCosP30 := COS_60;
  1568.   end
  1569.   else
  1570.   begin
  1571. {this is twice as fast as calling them individually:}
  1572.     SinCos(FAngleRadians, FSin, FCos);
  1573. {look back along the axis, then 30 degrees less, for the arrow:}
  1574.     SinCos(FAngleRadians + Pi*(1/2 - 1/6), FSinM30, FCosM30);
  1575. {look back along the axis, then 30 degrees more:}
  1576.     SinCos(FAngleRadians + Pi*(1/2 + 1/6), FSinP30, FCosP30);
  1577.   end;
  1578.  
  1579.   DoGeometry;
  1580. end;
  1581.  
  1582.  
  1583. {------------------------------------------------------------------------------
  1584.     Procedure: TAngleRect.SetOrigin
  1585.   Description: private property Set procedure
  1586.        Author: Mat Ballard
  1587.  Date created: 06/06/2001
  1588. Date modified: 06/06/2001 by Mat Ballard
  1589.       Purpose: sets the Origin, a virtual property, by moving the Right
  1590.  Known Issues:
  1591.  ------------------------------------------------------------------------------}
  1592. procedure TAngleRect.SetOrigin(Value: TPoint);
  1593. begin
  1594.   if ((FOrigin.x = Value.x) and
  1595.       (FOrigin.y = Value.y)) then
  1596.     exit;  
  1597.  
  1598.   FOrigin.x := Value.x;
  1599.   FOrigin.y := Value.y;
  1600.  
  1601.   DoGeometry;
  1602. end;
  1603.  
  1604. {------------------------------------------------------------------------------
  1605.     Procedure: TAngleRect.SetBreadth
  1606.   Description: standard property Set procedure
  1607.        Author: Mat Ballard
  1608.  Date created: 06/06/2001
  1609. Date modified: 06/06/2001 by Mat Ballard
  1610.       Purpose: sets the Breadth Property
  1611.  Known Issues:
  1612.  ------------------------------------------------------------------------------}
  1613. procedure TAngleRect.SetBreadth(Value: Word);
  1614. begin
  1615.   if (Value = FBreadth) then exit;
  1616.  
  1617.   FBreadth := Value;
  1618.   DoGeometry;
  1619. end;
  1620.  
  1621.  
  1622. {------------------------------------------------------------------------------
  1623.     Procedure: TAngleRect.SetLength
  1624.   Description: standard property Set procedure
  1625.        Author: Mat Ballard
  1626.  Date created: 06/06/2001
  1627. Date modified: 06/06/2001 by Mat Ballard
  1628.       Purpose: sets the Length Property
  1629.  Known Issues:
  1630.  ------------------------------------------------------------------------------}
  1631. procedure TAngleRect.SetLength(Value: Word);
  1632. begin
  1633.   if (Value = FLength) then exit;
  1634.  
  1635.   FLength := Value;
  1636.   DoGeometry;
  1637. end;
  1638.  
  1639. {------------------------------------------------------------------------------
  1640.     Procedure: TAngleRect.SetMidX
  1641.   Description: standard property Set procedure
  1642.        Author: Mat Ballard
  1643.  Date created: 02/25/2000
  1644. Date modified: 06/06/2001 by Mat Ballard
  1645.       Purpose: sets the MidX
  1646.  Known Issues:
  1647.  ------------------------------------------------------------------------------}
  1648. procedure TAngleRect.SetMidX(Value: Integer);
  1649. begin
  1650.   if (FCentre.x = Value) then exit;
  1651.   FCentre.x := Value;
  1652.  
  1653.   DoGeometry;
  1654. end;
  1655.  
  1656. {------------------------------------------------------------------------------
  1657.     Procedure: TAngleRect.SetMidY
  1658.   Description: standard property Set procedure
  1659.        Author: Mat Ballard
  1660.  Date created: 02/25/2000
  1661. Date modified: 06/06/2001 by Mat Ballard
  1662.       Purpose: sets the MidY property
  1663.  Known Issues:
  1664.  ------------------------------------------------------------------------------}
  1665. procedure TAngleRect.SetMidY(Value: Integer);
  1666. begin
  1667.   if (FCentre.y = Value) then exit;
  1668.   FCentre.y := Value;
  1669.  
  1670.   DoGeometry;
  1671. end;
  1672.  
  1673. {Get Functions for VIRTUAL properties ---------------------------------------}
  1674.  
  1675. {------------------------------------------------------------------------------
  1676.      Function: TAngleRect.GetVector
  1677.   Description: private property Get function
  1678.        Author: Mat Ballard
  1679.  Date created: 02/25/2000
  1680. Date modified: 06/06/2001 by Mat Ballard
  1681.       Purpose: Gets the Vector, which is a virtual property
  1682.  Known Issues:
  1683.  ------------------------------------------------------------------------------}
  1684. function TAngleRect.GetVector: TPoint;
  1685. begin
  1686.   Result.x := Round(FSin * FLength);
  1687.   Result.y := Round(FCos * FLength);
  1688. end;
  1689.  
  1690.  
  1691. {Set Procedures for VIRTUAL properties ---------------------------------------}
  1692. {------------------------------------------------------------------------------
  1693.     Procedure: TAngleRect.SetCentre
  1694.   Description: standard property Set procedure
  1695.        Author: Mat Ballard
  1696.  Date created: 06/06/2001
  1697. Date modified: 06/06/2001 by Mat Ballard
  1698.       Purpose: sets the Centre Property
  1699.  Known Issues: we do this by changing the origin
  1700.  ------------------------------------------------------------------------------}
  1701. procedure TAngleRect.SetCentre(NewCentre: TPoint);
  1702. begin
  1703.   FOrigin.x := FOrigin.x + (NewCentre.x - FCentre.x);
  1704.   FOrigin.y := FOrigin.y + (NewCentre.y - FCentre.y);
  1705.  
  1706.   DoGeometry;
  1707. end;
  1708.  
  1709. {------------------------------------------------------------------------------
  1710.     Procedure: TAngleRect.SetLeft
  1711.   Description: protected property Set procedure
  1712.        Author: Mat Ballard
  1713.  Date created: 02/25/2000
  1714. Date modified: 06/08/2001 by Mat Ballard
  1715.       Purpose: sets the Left, which also moves the Right, thereby preserving the Width
  1716.  Known Issues:
  1717.  ------------------------------------------------------------------------------}
  1718. procedure TAngleRect.SetLeft(Value: Integer);
  1719. var
  1720.   OldValue: Integer;
  1721. begin
  1722.   OldValue := FLeft;
  1723.   if (Value = OldValue) then exit;
  1724.  
  1725.   FOrigin.x := FOrigin.x + (Value - OldValue);
  1726.   DoGeometry;
  1727. end;
  1728.  
  1729. {------------------------------------------------------------------------------
  1730.     Procedure: TAngleRect.SetTop
  1731.   Description: protected property Set procedure
  1732.        Author: Mat Ballard
  1733.  Date created: 02/25/2000
  1734. Date modified: 06/08/2001 by Mat Ballard
  1735.       Purpose: sets the Top, which also also moves the Bottom, thereby preserving the Height
  1736.  Known Issues:
  1737.  ------------------------------------------------------------------------------}
  1738. procedure TAngleRect.SetTop(Value: Integer);
  1739. var
  1740.   OldValue: Integer;
  1741. begin
  1742.   OldValue := FTop;
  1743.   if (Value = OldValue) then exit;
  1744.  
  1745.   FOrigin.y := FOrigin.y + (Value - OldValue);
  1746.   DoGeometry;
  1747. end;
  1748.  
  1749. {------------------------------------------------------------------------------
  1750.     Procedure: TAngleRect.SetRight
  1751.   Description: private property Set procedure
  1752.        Author: Mat Ballard
  1753.  Date created: 02/25/2000
  1754. Date modified: 06/08/2001 by Mat Ballard
  1755.       Purpose: sets the Right
  1756.  Known Issues:
  1757.  ------------------------------------------------------------------------------}
  1758. procedure TAngleRect.SetRight(Value: Integer);
  1759. begin
  1760.   if (Value = FRight) then exit;
  1761.  
  1762.   if (FAngle > 180) then
  1763.     FOrigin.x := FOrigin.x + (Value - FRight);
  1764.   Width := Width + (Value - FRight)
  1765. end;
  1766.  
  1767. {------------------------------------------------------------------------------
  1768.     Procedure: TAngleRect.SetBottom
  1769.   Description: private property Set procedure
  1770.        Author: Mat Ballard
  1771.  Date created: 02/25/2000
  1772. Date modified: 02/25/2000 by Mat Ballard
  1773.       Purpose: sets the Bottom
  1774.  Known Issues:
  1775.  ------------------------------------------------------------------------------}
  1776. procedure TAngleRect.SetBottom(Value: Integer);
  1777. begin
  1778.   if (Value = FBottom) then exit;
  1779.  
  1780.   if ((FAngle < 90) or (FAngle > 270)) then
  1781.     FOrigin.y := FOrigin.y + (Value - FBottom);
  1782.   Height := Height + (Value - FBottom);
  1783. end;
  1784.  
  1785. {Set procedures for virtual properties ---------------------------------------}
  1786. {------------------------------------------------------------------------------
  1787.     Procedure: TAngleRect.SetHeight
  1788.   Description: private property Set procedure
  1789.        Author: Mat Ballard
  1790.  Date created: 02/25/2000
  1791. Date modified: 02/25/2000 by Mat Ballard
  1792.       Purpose: sets the Length or Breadth, depending on the angle
  1793.  Known Issues:
  1794.  ------------------------------------------------------------------------------}
  1795. procedure TAngleRect.SetHeight(Value: Integer);
  1796. begin
  1797. {All these eventually trigger a DoGeometry:}
  1798.   case FAngle of
  1799.     0..44: Length := Round(Abs(FCos * Value));
  1800.     45..134: Breadth := Round(Abs(FSin * Value));
  1801.     135..224: Length := Round(Abs(FCos * Value));
  1802.     225..314: Breadth := Round(Abs(FSin * Value));
  1803.     315 ..359: Length := Round(Abs(FCos * Value));
  1804.   end;
  1805. end;
  1806.  
  1807. {------------------------------------------------------------------------------
  1808.     Procedure: TAngleRect.SetWidth
  1809.   Description: private property Set procedure
  1810.        Author: Mat Ballard
  1811.  Date created: 06/06/2001
  1812. Date modified: 06/06/2001 by Mat Ballard
  1813.       Purpose: sets the Length or Breadth depending on Angle
  1814.  Known Issues:
  1815.  ------------------------------------------------------------------------------}
  1816. procedure TAngleRect.SetWidth(Value: Integer);
  1817. begin
  1818.   case FAngle of
  1819.     0..44: Breadth := Round(Abs(FCos * Value));
  1820.     45..134: Length := Round(Abs(FSin * Value));
  1821.     135..224: Breadth := Round(Abs(FCos * Value));
  1822.     225..314: Length := Round(Abs(FSin * Value));
  1823.     315 ..359: Breadth := Round(Abs(FCos * Value));
  1824.   end;
  1825. end;
  1826.  
  1827. {------------------------------------------------------------------------------
  1828.     Procedure: TAngleRect.SetVector
  1829.   Description: private property Set procedure
  1830.        Author: Mat Ballard
  1831.  Date created: 06/06/2001
  1832. Date modified: 06/06/2001 by Mat Ballard
  1833.       Purpose: sets the Vector, a virtual property
  1834.  Known Issues:
  1835.  ------------------------------------------------------------------------------}
  1836. procedure TAngleRect.SetVector(Value: TPoint);
  1837. begin
  1838.   FLength := Round(Sqrt(Value.x*Value.x + Value.y*Value.y));
  1839.   FAngle := Round(GetAngle(Value.x, Value.y));
  1840.   DoGeoMetry;
  1841. end;
  1842.  
  1843. {------------------------------------------------------------------------------
  1844.     Procedure: TAngleRect.ClickedOn
  1845.   Description: Was this TRectangle clicked on ?
  1846.        Author: Mat Ballard
  1847.  Date created: 01/22/2001
  1848. Date modified: 01/22/2001 by Mat Ballard
  1849.       Purpose: screen click management
  1850.  Known Issues:
  1851.  ------------------------------------------------------------------------------}
  1852. function TAngleRect.ClickedOn(iX, iY: Integer): Boolean;
  1853. begin
  1854.   if ((FLeft <= iX) and
  1855.       (iX <= FRight) and
  1856.       (FTop <= iY) and
  1857.       (iY <= FBottom) and
  1858.       (FVisible)) then
  1859.     ClickedOn := TRUE
  1860.    else
  1861.     ClickedOn := FALSE; 
  1862. end;
  1863.  
  1864. {------------------------------------------------------------------------------
  1865.     Procedure: TAngleRect.MoveTo
  1866.   Description: Move the rectangle to a new (Top, Left) location.
  1867.        Author: Mat Ballard
  1868.  Date created: 06/12/2001
  1869. Date modified: 06/12/2001 by Mat Ballard
  1870.       Purpose: location / geometry management
  1871.  Known Issues:
  1872.  ------------------------------------------------------------------------------}
  1873. procedure TAngleRect.MoveTo(NewX, NewY: Integer);
  1874. begin
  1875.   //if ((FOrigin.x = iX) and (FOrigin.y = iY)) then exit;
  1876.  
  1877.   if ((FAngle mod 90) = 0) then
  1878.   begin
  1879.     FOrigin.x := FOrigin.x + (NewX - FLeft);
  1880.     FOrigin.y := FOrigin.y + (NewY - FTop);
  1881.   end
  1882.   else
  1883.   begin
  1884.     FOrigin.x := NewX;
  1885.     FOrigin.y := NewY;
  1886.   end;
  1887.  
  1888.   DoGeometry;
  1889. end;
  1890.  
  1891. {------------------------------------------------------------------------------
  1892.     Procedure: TAngleRect.MoveBy
  1893.   Description: Move the rectangle by (iX, iY) from (Top, Left) to (Top + iX, Left + iY).
  1894.        Author: Mat Ballard
  1895.  Date created: 06/12/2001
  1896. Date modified: 06/12/2001 by Mat Ballard
  1897.       Purpose: location / geometry management
  1898.  Known Issues:
  1899.  ------------------------------------------------------------------------------}
  1900. procedure TAngleRect.MoveBy(dX, dY: Integer);
  1901. begin
  1902.   if ((dX = 0) and (dY = 0)) then exit;
  1903.  
  1904.   Inc(FRight, dX);
  1905.   Inc(FLeft, dX);
  1906. {Trigger a change event:}
  1907.   Top := FTop + dY;
  1908. end;
  1909.  
  1910. {------------------------------------------------------------------------------
  1911.     Procedure: TAngleRect.SetNewGeometry
  1912.   Description: Initializes the AngleRect
  1913.        Author: Mat Ballard
  1914.  Date created: 06/12/2001
  1915. Date modified: 06/12/2001 by Mat Ballard
  1916.       Purpose: location / geometry management
  1917.  Known Issues:
  1918.  ------------------------------------------------------------------------------}
  1919. procedure TAngleRect.SetNewGeometry(NewOrigin: TPoint; NewAngle: TDegrees; NewLength, NewBreadth: Integer);
  1920. begin
  1921.   FOrigin := NewOrigin;
  1922.   FLength := NewLength;
  1923.   FBreadth := NewBreadth;
  1924.   Angle := NewAngle;
  1925. end;
  1926.  
  1927. {------------------------------------------------------------------------------
  1928.     Procedure: TAngleRect.Outline
  1929.   Description: Draws an Outline around this rectangle
  1930.        Author: Mat Ballard
  1931.  Date created: 01/22/2001
  1932. Date modified: 01/22/2001 by Mat Ballard
  1933.       Purpose: gives the user a guide to what they are moving with the mouse
  1934.  Known Issues:
  1935.  ------------------------------------------------------------------------------}
  1936. procedure TAngleRect.Outline(ACanvas: TCanvas);
  1937. begin
  1938.   ACanvas.Pen.Color := clBlack;
  1939.   ACanvas.Pen.Mode := pmNotXOR;
  1940.   ACanvas.Pen.Style := psDot;
  1941.   ACanvas.PolyLine(Self.FPolyRect);
  1942. end;
  1943.  
  1944. {TCaption -------------------------------------------------------------------}
  1945. {Constructor and Destructor -------------------------------------------------}
  1946. {------------------------------------------------------------------------------
  1947.   Constructor: TCaption.Create
  1948.   Description: Standard Constructor for TCaption
  1949.        Author: Mat Ballard
  1950.  Date created: 02/25/2000
  1951. Date modified: 02/25/2000 by Mat Ballard
  1952.       Purpose: initializes component and properties
  1953.  Known Issues:
  1954.  ------------------------------------------------------------------------------}
  1955. Constructor TCaption.Create(AOwner: TPersistent);
  1956. begin
  1957. {First call the ancestor:}
  1958.   inherited Create(AOwner);
  1959.  
  1960. {Create font:}
  1961.   FFont := TFont.Create;
  1962.   FFont.Name := sArial;
  1963.   FFont.Size := SMALL_FONT_SIZE;
  1964. end;
  1965.  
  1966. destructor TCaption.Destroy; 
  1967. begin
  1968.   FFont.Free;
  1969. end;
  1970.  
  1971. {Begin Set Procedures -------------------------------------------------------}
  1972. {------------------------------------------------------------------------------
  1973.     Procedure: TCaption.SetCaption
  1974.   Description: private property Set procedure
  1975.        Author: Mat Ballard
  1976.  Date created: 02/25/2000
  1977. Date modified: 02/25/2000 by Mat Ballard
  1978.       Purpose: sets the Caption of TCaption
  1979.  Known Issues:
  1980.  ------------------------------------------------------------------------------}
  1981. procedure TCaption.SetCaption(Value: String);
  1982. begin
  1983.   if (Value = FCaption) then exit;
  1984.   FCaption := Value;
  1985.   CreateName;
  1986.   DoHandleChange;
  1987.   if assigned(FOnCaptionChange) then OnCaptionChange(Self);
  1988. end;
  1989.  
  1990. {------------------------------------------------------------------------------
  1991.     Procedure: TCaption.SetFont
  1992.   Description: private property Set procedure
  1993.        Author: Mat Ballard
  1994.  Date created: 02/25/2000
  1995. Date modified: 02/25/2000 by Mat Ballard
  1996.       Purpose: sets the Font
  1997.  Known Issues:
  1998.  ------------------------------------------------------------------------------}
  1999. procedure TCaption.SetFont(Value: TFont);
  2000. begin
  2001.   FFont.Assign(Value);
  2002.   DoHandleChange;
  2003. end;
  2004.  
  2005. {General purpose methods ------------------------------------------------------}
  2006. {------------------------------------------------------------------------------
  2007.     Procedure: TCaption.CreateName
  2008.   Description: protected procedure to set a useful name
  2009.        Author: Mat Ballard
  2010.  Date created: 02/25/2000
  2011. Date modified: 02/25/2000 by Mat Ballard
  2012.       Purpose: sets the Name, generally in response to a Caption change
  2013.  Known Issues:
  2014.  ------------------------------------------------------------------------------}
  2015. procedure TCaption.CreateName;
  2016. begin
  2017. {eg: Caption: X Axis
  2018.      Name: X Axis Caption.}
  2019.   Name := FCaption + ' ' + sCaption;
  2020. end;
  2021.  
  2022. {------------------------------------------------------------------------------
  2023.     Procedure: TCaption.Assign
  2024.   Description: standard Assign method
  2025.        Author: Mat Ballard
  2026.  Date created: 07/06/2000
  2027. Date modified: 07/06/2000 by Mat Ballard
  2028.       Purpose: implements Assign
  2029.  Known Issues:
  2030.  ------------------------------------------------------------------------------}
  2031. {procedure TCaption.Assign(Source: TPersistent);
  2032. begin
  2033.   inherited Assign(Source);
  2034.   FCaption := TCaption(Source).Caption;
  2035.   FFont.Assign(TCaption(Source).Font);
  2036. end;}
  2037.  
  2038. {------------------------------------------------------------------------------
  2039.     Procedure: TCaption.AssignTo
  2040.   Description: standard AssignTo method
  2041.        Author: Mat Ballard
  2042.  Date created: 07/06/2000
  2043. Date modified: 07/06/2000 by Mat Ballard
  2044.       Purpose: implements AssignTo
  2045.  Known Issues:
  2046.  ------------------------------------------------------------------------------}
  2047. procedure TCaption.AssignTo(Dest: TPersistent);
  2048. begin
  2049.   inherited AssignTo(Dest);
  2050.   TCaption(Dest).Caption := FCaption;
  2051.   TCaption(Dest).Font.Assign(FFont);
  2052. end;
  2053.  
  2054. {TTitle -------------------------------------------------------------------}
  2055. {Constructor and Destructor -------------------------------------------------}
  2056. {------------------------------------------------------------------------------
  2057.   Constructor: TTitle.Create
  2058.   Description: Standard Constructor for TTitle
  2059.        Author: Mat Ballard
  2060.  Date created: 02/25/2000
  2061. Date modified: 02/25/2000 by Mat Ballard
  2062.       Purpose: initializes component and properties
  2063.  Known Issues:
  2064.  ------------------------------------------------------------------------------}
  2065. Constructor TTitle.Create(AOwner: TPersistent);
  2066. begin
  2067. {First call the ancestor:}
  2068.   inherited Create(AOwner);
  2069.  
  2070.   FEnvelope.Left := 0;
  2071.   FEnvelope.Right := 100;
  2072.   FEnvelope.Top := 90;
  2073.   FEnvelope.Bottom := 110;
  2074. {we don't fire events with a geometry change:}
  2075.   FireEvents := FALSE;
  2076.   Self.Height := 20;
  2077. end;
  2078.  
  2079. {Get methods -----------------------------------------------------------------}
  2080.  
  2081. {Set procedures --------------------------------------------------------------}
  2082. {------------------------------------------------------------------------------
  2083.     Procedure: TTitle.SetCaption
  2084.   Description: protected property Set procedure
  2085.        Author: Mat Ballard
  2086.  Date created: 02/25/2000
  2087. Date modified: 02/25/2000 by Mat Ballard
  2088.       Purpose: sets the Caption, which is complicated by the presence of Units.
  2089.  Known Issues:
  2090.  ------------------------------------------------------------------------------}
  2091. procedure TTitle.SetCaption(Value: String);
  2092. var
  2093.   NewValue: String;
  2094. begin
  2095.   if (Pos('(', Value) > 0) then
  2096.   begin
  2097. {There is a "()" in the value, indicating the presence of Units}
  2098.     NewValue := Trim(GetWord(Value, '('));
  2099.     FUnits := GetWord(Value, ')');
  2100.     if (Length(FUnits) = 0) then
  2101.       FFullCaption := NewValue
  2102.      else
  2103.       FFullCaption := NewValue + ' (' + FUnits + ')';
  2104.     inherited SetCaption(NewValue);
  2105.   end
  2106.   else
  2107.   begin
  2108.     if (Length(FUnits) = 0) then
  2109.       FFullCaption := Value
  2110.      else
  2111.       FFullCaption := Value + ' (' + FUnits + ')';
  2112.     inherited SetCaption(Value);
  2113.   end;
  2114. end;
  2115.  
  2116. {------------------------------------------------------------------------------
  2117.     Procedure: TTitle.SetDirection
  2118.   Description: private property Set procedure
  2119.        Author: Mat Ballard
  2120.  Date created: 02/25/2000
  2121. Date modified: 02/25/2000 by Mat Ballard
  2122.       Purpose: sets the Direction
  2123.  Known Issues:
  2124.  ------------------------------------------------------------------------------}
  2125. procedure TTitle.SetDirection(Value: TDirection);
  2126. begin
  2127.   if (Value = FDirection) then exit;
  2128.   FDirection := Value;
  2129.   DoHandleChange;
  2130. end;
  2131.  
  2132. {------------------------------------------------------------------------------
  2133.     Procedure: TTitle.SetOrientation
  2134.   Description: private property Set procedure
  2135.        Author: Mat Ballard
  2136.  Date created: 02/25/2000
  2137. Date modified: 02/25/2000 by Mat Ballard
  2138.       Purpose: sets the Orientation
  2139.  Known Issues:
  2140.  ------------------------------------------------------------------------------}
  2141. procedure TTitle.SetOrientation(Value: TOrientation);
  2142. begin
  2143.   if (Value = FOrientation) then exit;
  2144.   FOrientation := Value;
  2145.   DoHandleChange;
  2146. end;
  2147.  
  2148. {------------------------------------------------------------------------------
  2149.     Procedure: TTitle.SetEnvelope
  2150.   Description: private property Set procedure
  2151.        Author: Mat Ballard
  2152.  Date created: 02/25/2000
  2153. Date modified: 02/25/2000 by Mat Ballard
  2154.       Purpose: sets the Envelope: the screen region around which the Title dances
  2155.  Known Issues:
  2156.  ------------------------------------------------------------------------------}
  2157. procedure TTitle.SetEnvelope(Value: TRect);
  2158. begin
  2159.   if ((Value.Left = FEnvelope.Left) and
  2160.       (Value.Top = FEnvelope.Top) and
  2161.       (Value.Right = FEnvelope.Right) and
  2162.       (Value.Bottom = FEnvelope.Bottom)) then exit;
  2163.   FEnvelope := Value;
  2164.   DoHandleChange;
  2165. end;
  2166.  
  2167. {------------------------------------------------------------------------------
  2168.     Procedure: TTitle.SetUnits
  2169.   Description: private property Set procedure
  2170.        Author: Mat Ballard
  2171.  Date created: 02/25/2000
  2172. Date modified: 02/25/2000 by Mat Ballard
  2173.       Purpose: sets the Units (eg: Furlongs / Fortnight ^3), and also the FullCaption
  2174.  Known Issues:
  2175.  ------------------------------------------------------------------------------}
  2176. procedure TTitle.SetUnits(Value: String);
  2177. begin
  2178.   if (Value = FUnits) then exit;
  2179.   FUnits := Value;
  2180.   if (Length(FUnits) = 0) then
  2181.     FFullCaption := FCaption
  2182.    else
  2183.     FFullCaption := FCaption + ' (' + FUnits + ')';
  2184.   DoHandleChange;
  2185. end;
  2186.  
  2187. {Drawing ----------------------------------------------------------------------}
  2188. {------------------------------------------------------------------------------
  2189.     Procedure: TTitle.DoGeometry
  2190.   Description: TTitle Geometry manager
  2191.        Author: Mat Ballard
  2192.  Date created: 02/25/2000
  2193. Date modified: 02/25/2000 by Mat Ballard
  2194.       Purpose: sets the precise screen position of the TTitle.
  2195.  Known Issues:
  2196.  ------------------------------------------------------------------------------}
  2197. procedure TTitle.DoGeometry(ACanvas: TCanvas; TheText: String);
  2198. begin
  2199.   if (FDirection = drHorizontal) then
  2200.   begin
  2201. {BUG BUG BUG: if ACanvas is a metafile canvas, then TextHeight and TextWidth
  2202.  both return zero in D1!}
  2203.     Height := Abs(ACanvas.Font.Height);
  2204.     Width := ACanvas.TextWidth(TheText);
  2205. {Note how "neat" this is: when D1 returns 0 for these Text dimensions,
  2206.  TRectangle rejects them, so Height and Width are unchanged !
  2207.  Therefore, when we use them below, we use the previous screen values !}
  2208.     if (FOrientation = orLeft) then
  2209.     begin
  2210.       Top := FEnvelope.Top - Height;
  2211.       if (Alignment = taLeftJustify) then
  2212.         Left := FEnvelope.Left
  2213.        else if (Alignment = taRightJustify) then
  2214.         Left := FEnvelope.Right - Width
  2215.        else {Alignment = taCenter}
  2216.         Left := (FEnvelope.Left + FEnvelope.Right - Width) div 2;
  2217.     end
  2218.     else {FOrientation = oRight}
  2219.     begin
  2220.       Top := FEnvelope.Bottom;
  2221.       if (Alignment = taLeftJustify) then
  2222.         Left := FEnvelope.Left
  2223.        else if (Alignment = taRightJustify) then
  2224.         Left := FEnvelope.Right - Width
  2225.        else {Alignment = taCenter}
  2226.         Left := (FEnvelope.Left + FEnvelope.Right - Width) div 2;
  2227.     end;
  2228.   end
  2229.   else {FDirection = dVertical}
  2230.   begin
  2231. {BUG BUG BUG: if ACanvas is a metafile canvas, then TextHeight and TextWidth
  2232.  both return zero in D1!}
  2233.     Width := Abs(ACanvas.Font.Height);
  2234.     Height := ACanvas.TextWidth(TheText);
  2235.     if (FOrientation = orLeft) then
  2236.     begin
  2237.       Left := FEnvelope.Left - Width;
  2238.       if (Alignment = taLeftJustify) then
  2239.         Top := FEnvelope.Bottom - Height
  2240.        else if (Alignment = taRightJustify) then
  2241.         Top := FEnvelope.Top
  2242.        else {Alignment = taCenter}
  2243.         Top := (FEnvelope.Top + FEnvelope.Bottom - Height) div 2;
  2244.     end
  2245.     else {FOrientation = oRight}
  2246.     begin
  2247.       Left := FEnvelope.Right;
  2248.       if (Alignment = taLeftJustify) then
  2249.         Top := FEnvelope.Bottom - Height
  2250.        else if (Alignment = taRightJustify) then
  2251.         Top := FEnvelope.Top
  2252.        else {Alignment = taCenter}
  2253.         Top := (FEnvelope.Top + FEnvelope.Bottom - Height) div 2;
  2254.     end;
  2255.   end;
  2256. end;
  2257.  
  2258. {------------------------------------------------------------------------------
  2259.     Procedure: TTitle.Draw
  2260.   Description: public Drawing method
  2261.        Author: Mat Ballard
  2262.  Date created: 02/25/2000
  2263. Date modified: 02/25/2000 by Mat Ballard
  2264.       Purpose: Draws the Caption, either horizontally or vertically, at the desired position
  2265.  Known Issues:
  2266.  ------------------------------------------------------------------------------}
  2267. procedure TTitle.Draw(ACanvas: TCanvas);
  2268. var
  2269.   iY: Integer;
  2270.   TheText: String;
  2271. begin
  2272.   if (not Visible) then exit;
  2273.   if (Length(FCaption) = 0) then exit;
  2274. {$IFDEF DELPHI3_UP}
  2275.   Assert(ACanvas <> nil, 'TTitle.Draw: ' + sACanvasIsNil);
  2276. {$ENDIF}
  2277.  
  2278.   ACanvas.Font.Assign(FFont);
  2279.   TheText := FCaption;
  2280.   if (Length(FUnits) > 0) then
  2281.     TheText := TheText + ' (' + FUnits + ')';
  2282.   DoGeometry(ACanvas, TheText);
  2283.  
  2284. {output text to screen:}
  2285.   if (FDirection = drHorizontal) then
  2286.   begin
  2287.     iY := Top;
  2288.     while (Pos(#10, TheText) > 0) do
  2289.     begin
  2290.       ACanvas.TextOut(Left, iY, GetWord(TheText, #10));
  2291.       Inc(iY, Abs(ACanvas.Font.Height));
  2292.     end;
  2293.     ACanvas.TextOut(Left, iY, TheText);
  2294.   end
  2295.   else {FDirection = dVertical}
  2296.   begin
  2297.     iY := Left;
  2298.     while (Pos(#10, TheText) > 0) do
  2299.     begin
  2300.       TextOutAngle(ACanvas, 90,
  2301.         Left, Top + ACanvas.TextWidth(TheText),
  2302.         GetWord(TheText, #10));
  2303.       ACanvas.TextOut(Left, iY, GetWord(TheText, #10));
  2304.       Inc(iY, Abs(ACanvas.Font.Height));
  2305.     end;
  2306.     TextOutAngle(ACanvas, 90, Left, Top + ACanvas.TextWidth(TheText), TheText);
  2307.   end;
  2308. end;
  2309.  
  2310. {------------------------------------------------------------------------------
  2311.     Procedure: TTitle.Assign
  2312.   Description: standard Assign method
  2313.        Author: Mat Ballard
  2314.  Date created: 07/06/2000
  2315. Date modified: 07/06/2000 by Mat Ballard
  2316.       Purpose: implements Assign
  2317.  Known Issues:
  2318.  ------------------------------------------------------------------------------}
  2319. {procedure TTitle.Assign(Source: TPersistent);
  2320. begin
  2321.   inherited Assign(Source);
  2322.   FDirection := TTitle(Source).Direction;
  2323.   FOrientation := TTitle(Source).Orientation;
  2324.   FUnits := TTitle(Source).Units;
  2325. end;}
  2326.  
  2327. {------------------------------------------------------------------------------
  2328.     Procedure: TTitle.AssignTo
  2329.   Description: standard AssignTo method
  2330.        Author: Mat Ballard
  2331.  Date created: 07/06/2000
  2332. Date modified: 07/06/2000 by Mat Ballard
  2333.       Purpose: implements AssignTo
  2334.  Known Issues:
  2335.  ------------------------------------------------------------------------------}
  2336. procedure TTitle.AssignTo(Dest: TPersistent);
  2337. begin
  2338.   inherited AssignTo(Dest);
  2339.   TTitle(Dest).Direction := FDirection;
  2340.   TTitle(Dest).Orientation := FOrientation;
  2341.   TTitle(Dest).Units := FUnits;
  2342. end;
  2343.  
  2344. {TLegend ----------------------------------------------------------------------}
  2345. {------------------------------------------------------------------------------
  2346.   Constructor: TCaption.Create
  2347.   Description: Standard Constructor for TCaption
  2348.        Author: Mat Ballard
  2349.  Date created: 02/25/2000
  2350. Date modified: 02/25/2000 by Mat Ballard
  2351.       Purpose: initializes component and properties
  2352.  Known Issues:
  2353.  ------------------------------------------------------------------------------}
  2354. Constructor TLegend.Createlist(AOwner: TPersistent; SeriesList: TList);
  2355. begin
  2356. {First call the ancestor:}
  2357.   inherited Create(AOwner);
  2358.   FSeriesList := SeriesList;
  2359.  
  2360. {Create font:}
  2361.   FFont := TFont.Create;
  2362.   FFont.Name := sArial;
  2363.   FFont.Size := SMALL_FONT_SIZE;
  2364.   FCheckBoxes := TRUE;
  2365. end;
  2366.  
  2367. destructor TLegend.Destroy;
  2368. begin
  2369.   FFont.Free;
  2370. end;
  2371.  
  2372. {Get functions ----------------------------------------------------------------}
  2373. {------------------------------------------------------------------------------
  2374.      Function: TLegend.GetHit
  2375.   Description: Interprets mouse click position
  2376.        Author: Mat Ballard
  2377.  Date created: 02/25/2000
  2378. Date modified: 02/25/2000 by Mat Ballard
  2379.       Purpose: Gets the region of the line of the Legend under the input position
  2380.  Known Issues:
  2381.  ------------------------------------------------------------------------------}
  2382. function TLegend.GetHit(iX, iY: Integer; var TheRect: TRect): Integer;
  2383. var
  2384.   SeriesWidth,
  2385.   TheHit,
  2386.   TheOffset: Integer;
  2387. begin
  2388.   if (FDirection = drHorizontal) then
  2389.   begin
  2390.     SeriesWidth :=  FCheckWidth + FLineWidth + FStringWidth + 5;
  2391.     TheHit := (iX - Left) div SeriesWidth;
  2392.     TheRect.Left := Left + TheHit * SeriesWidth;
  2393.     TheRect.Right := TheRect.Left + SeriesWidth;
  2394.     TheRect.Top := Top;
  2395.     TheRect.Bottom := Bottom;
  2396.     TheOffset := (iX - Left) mod SeriesWidth;
  2397.   end
  2398.   else
  2399.   begin {dVertical}
  2400.     TheHit := (iY - Top) div FFontHeight;
  2401.     TheRect.Left := Left;
  2402.     TheRect.Right := Right;
  2403.     TheRect.Top := Top + TheHit * FFontHeight;
  2404.     TheRect.Bottom := TheRect.Top + FFontHeight;
  2405.     TheOffset := iX - Left;
  2406.   end;
  2407.   if (TheOffset <= FCheckWidth) then
  2408.     TSeries(FSeriesList.Items[TheHit]).Visible :=
  2409.       not TSeries(FSeriesList.Items[TheHit]).Visible;
  2410.  
  2411.   GetHit := TheHit;
  2412. end;
  2413.  
  2414. function TLegend.GetItemWidth: Integer;
  2415. begin
  2416.   GetItemWidth :=  FCheckWidth + FLineWidth + FStringWidth;
  2417. end;
  2418.  
  2419. {Set procedures ---------------------------------------------------------------}
  2420. {------------------------------------------------------------------------------
  2421.     Procedure: TLegend.SetCheckBoxes
  2422.   Description: private property Set procedure
  2423.        Author: Mat Ballard
  2424.  Date created: 04/12/2001
  2425. Date modified: 04/12/2001 by Mat Ballard
  2426.       Purpose: sets whether or not the CheckBoxes are visible
  2427.  Known Issues:
  2428.  ------------------------------------------------------------------------------}
  2429. procedure TLegend.SetCheckBoxes(Value: Boolean);
  2430. begin
  2431.   if (Value = FCheckboxes) then exit;
  2432.   FCheckboxes := Value;
  2433.   DoHandleChange;
  2434. end;
  2435.  
  2436. {------------------------------------------------------------------------------
  2437.     Procedure: TLegend.SetDirection
  2438.   Description: private property Set procedure
  2439.        Author: Mat Ballard
  2440.  Date created: 02/25/2000
  2441. Date modified: 02/25/2000 by Mat Ballard
  2442.       Purpose: sets the Direction
  2443.  Known Issues:
  2444.  ------------------------------------------------------------------------------}
  2445. procedure TLegend.SetDirection(Value: TDirection);
  2446. begin
  2447.   if (Value = FDirection) then exit;
  2448.   FDirection := Value;
  2449.   DoHandleChange;
  2450. end;
  2451.  
  2452. {------------------------------------------------------------------------------
  2453.     Procedure: TLegend.SetFont
  2454.   Description: private property Set procedure
  2455.        Author: Mat Ballard
  2456.  Date created: 02/25/2000
  2457. Date modified: 02/25/2000 by Mat Ballard
  2458.       Purpose: sets the Font
  2459.  Known Issues:
  2460.  ------------------------------------------------------------------------------}
  2461. procedure TLegend.SetFont(Value: TFont);
  2462. begin
  2463.   FFont.Assign(Value);
  2464.   DoHandleChange;
  2465. end;
  2466.  
  2467. {------------------------------------------------------------------------------
  2468.     Procedure: TLegend.Draw
  2469.   Description: draws the legend
  2470.        Author: Mat Ballard
  2471.  Date created: 04/19/2001
  2472. Date modified: 04/19/2001 by Mat Ballard
  2473.       Purpose: screen drawing
  2474.  Known Issues:
  2475.  ------------------------------------------------------------------------------}
  2476. procedure TLegend.Draw(ACanvas: TCanvas; SeriesIncrement: Integer);
  2477. var
  2478.   Chars,
  2479.   i,
  2480.   iX,
  2481.   iMaxChars,
  2482.   MaxChars,
  2483.   LineY,
  2484.   TextY: Integer;
  2485.  
  2486. {$IFDEF LINUX}
  2487.   //ARect: TRect;
  2488. {$ENDIF}
  2489.  
  2490.   procedure DoGeometry;
  2491.   begin
  2492. {Allow for symbols and lines:}
  2493.     FStringWidth := ACanvas.TextWidth(
  2494.       TSeries(FSeriesList.Items[iMaxChars]).Name);
  2495.     FLineWidth := 2 * FStringWidth div 5;
  2496.     FFontHeight := ACanvas.TextHeight('Ap');
  2497.     if (FCheckBoxes) then
  2498.       FCheckWidth := 7*FFontHeight div 10
  2499.      else
  2500.       FCheckWidth := 0;
  2501.  
  2502.     if (FDirection = drHorizontal) then
  2503.     begin
  2504.       Height := FFontHeight;
  2505.   {       <-----LineWidth---->
  2506.    <Check><Line><Symbol><Line><Text---StringWidth--->}
  2507.       Width := FSeriesList.Count *
  2508.         (FCheckWidth + FLineWidth + FStringWidth + 5);
  2509.     end
  2510.     else
  2511.     begin
  2512.       Height := FSeriesList.Count * FFontHeight;
  2513.       Width := FCheckWidth + FLineWidth + FStringWidth + 5;
  2514.     end;
  2515.   end;
  2516.  
  2517.   procedure DrawCheck(Value: Boolean; X, Y, Size: Integer);
  2518.   begin
  2519.     ACanvas.Pen.Color := clBlack;
  2520.     ACanvas.Pen.Width := 1;
  2521.     ACanvas.Pen.Style := psSolid;
  2522.     ACanvas.Brush.Color := clWhite;
  2523.     ACanvas.Brush.Style := bsSolid;
  2524.     ACanvas.Rectangle(X, Y, X + Size, Y + Size);
  2525.  
  2526.     ACanvas.Pen.Color := clBtnShadow;
  2527.     ACanvas.MoveTo(X + Size-2, Y+1);
  2528.     ACanvas.LineTo(X+1, Y+1);
  2529.     ACanvas.LineTo(X+1, Y + Size-1);
  2530.  
  2531.     ACanvas.Pen.Color := clBtnFace;
  2532.     ACanvas.MoveTo(X + Size - 2, Y+1);
  2533.     ACanvas.LineTo(X + Size - 2, Y + Size - 2);
  2534.     ACanvas.LineTo(X+1, Y + Size - 2);
  2535.  
  2536.     {ACanvas.Pen.Color := clBlack;
  2537.     ACanvas.MoveTo(X + Size - 3, Y+2);
  2538.     ACanvas.LineTo(X+2, Y+2);
  2539.     ACanvas.LineTo(X+2, Y + Size - 3);}
  2540.  
  2541.     if (Value) then
  2542.     begin
  2543.       ACanvas.Pen.Color := clBlack;
  2544.       ACanvas.Pen.Width := 2;
  2545.       ACanvas.MoveTo(X+2, Y + Size div 2 +1);
  2546.       ACanvas.LineTo(X + Size div 2, Y + Size - 3);
  2547.       ACanvas.LineTo(X + Size -3, Y + 2);
  2548.       {ACanvas.MoveTo(X+3, Y + Size div 2);
  2549.       ACanvas.LineTo(X + Size div 2, Y + Size - 2);
  2550.       ACanvas.LineTo(X + Size -3, Y + 2);}
  2551.     end;
  2552.   end;
  2553.  
  2554. begin
  2555. {$IFDEF DELPHI3_UP}
  2556.   Assert(ACanvas <> nil, 'TLegend.Draw: ' + sACanvasIsNil);
  2557. {$ENDIF}
  2558.  
  2559.   if (not Self.Visible) then exit;
  2560.   if (FSeriesList.Count = 0) then exit;
  2561.  
  2562.   ACanvas.Font.Assign(Self.Font);
  2563.  
  2564.   MaxChars := 0;
  2565.   iMaxChars := -1;
  2566.   for i := 0 to FSeriesList.Count-1 do
  2567.   begin
  2568.     Chars := Length(TSeries(FSeriesList.Items[i]).Name);
  2569.     if (MaxChars < Chars) then
  2570.     begin
  2571.       MaxChars := Chars;
  2572.       iMaxChars := i;
  2573.     end;
  2574.   end;
  2575.   if (iMaxChars < 0) then exit;
  2576.  
  2577.   DoGeometry;
  2578.  
  2579.   LineY := Self.Top + Self.FontHeight div 2;
  2580.   TextY := Self.Top;
  2581.  
  2582.   i := 0;
  2583.  
  2584.   if (Self.Direction = drVertical) then
  2585.   begin
  2586.     while i < FSeriesList.Count do
  2587.     //for i := 0 to SeriesList.Count-1 do
  2588.     begin
  2589.       DrawCheck(TSeries(FSeriesList.Items[i]).Visible,
  2590.         Self.Left, LineY-FCheckWidth div 2, FCheckWidth);
  2591.       ACanvas.Pen.Assign(TSeries(FSeriesList.Items[i]).Pen);
  2592.       ACanvas.MoveTo(Self.Left + FCheckWidth+1, LineY);
  2593.       ACanvas.LineTo(Self.Left + FCheckWidth + FLineWidth, LineY);
  2594.       ACanvas.Brush.Assign(TSeries(FSeriesList.Items[i]).Brush);
  2595.       TSeries(FSeriesList.Items[i]).DrawSymbol(ACanvas,
  2596.         Self.Left + FCheckWidth + FLineWidth div 2, LineY);
  2597.       ACanvas.Brush.Style := bsClear;
  2598.   {output text to screen:}
  2599.       ACanvas.Font.Color := ACanvas.Pen.Color;
  2600.       ACanvas.TextOut(Self.Left + FCheckWidth + FLineWidth+1, TextY,
  2601.         TSeries(FSeriesList.Items[i]).Name);
  2602.       Inc(LineY, Self.FontHeight);
  2603.       Inc(TextY, Self.FontHeight);
  2604.       Inc(i, SeriesIncrement);
  2605.     end;
  2606.   end
  2607.   else {Horizontal}
  2608.   begin
  2609. {Note: in Horizontal mode, the size of each series name is:}
  2610. {<---LineWidth---><---StringWidth---><-LineWidth->}
  2611. {<-Symbol + Line-><-Name of Series--><--Space---->}
  2612.     LineY := Self.Top + Self.FontHeight div 2;
  2613.     TextY := Self.Top;
  2614.     iX := Self.Left;
  2615.     while i < FSeriesList.Count do
  2616.     //for i := 0 to SeriesList.Count-1 do
  2617.     begin
  2618.       DrawCheck(TSeries(FSeriesList.Items[i]).Visible,
  2619.         iX, LineY - FCheckWidth div 2, FCheckWidth);
  2620.       ACanvas.Pen.Assign(TSeries(FSeriesList.Items[i]).Pen);
  2621.       ACanvas.MoveTo(iX + FCheckWidth+1, LineY);
  2622.       ACanvas.LineTo(iX + FCheckWidth + FLineWidth, LineY);
  2623.       ACanvas.Brush.Assign(TSeries(FSeriesList.Items[i]).Brush);
  2624.       TSeries(FSeriesList.Items[i]).DrawSymbol(ACanvas,
  2625.         iX + FCheckWidth + FLineWidth div 2, LineY);
  2626.       ACanvas.Brush.Style := bsClear;
  2627.   {output text to screen:}
  2628.       ACanvas.Font.Color := ACanvas.Pen.Color;
  2629.       ACanvas.TextOut(iX + FCheckWidth + FLineWidth +1, TextY,
  2630.         TSeries(FSeriesList.Items[i]).Name);
  2631.       iX := iX + FCheckWidth + FLineWidth + FStringWidth + 5;
  2632.       Inc(i, SeriesIncrement);
  2633.     end; {for}
  2634.     Self.Width := iX - Self.Left;
  2635.     Self.Height := Self.FontHeight;
  2636.   end; {if}
  2637. end;
  2638.  
  2639. {TNote ------------------------------------------------------------------------}
  2640. procedure TNote.AssignTo(Dest: TPersistent);
  2641. begin
  2642.   inherited AssignTo(Dest);
  2643.   TNote(Dest).ArrowLeft := FArrowLeft;
  2644.   TNote(Dest).ArrowTop := FArrowTop;
  2645.   TNote(Dest).ArrowLeftReal := FArrowLeftReal;
  2646.   TNote(Dest).ArrowTopReal := FArrowTopReal;
  2647.   TNote(Dest).LeftReal := FLeftReal;
  2648.   TNote(Dest).TopReal := FTopReal;
  2649. end;
  2650.  
  2651. constructor TNote.Create(AOwner: TPersistent);
  2652. {var
  2653.   StartPoint: TPoint;}
  2654. begin
  2655.   inherited Create(AOwner);
  2656.   FOwner := AOwner;
  2657. {a note can only ever be a note:}
  2658.   Tag := Ord(soNote);
  2659.   {StartPoint := TPlot(AOwner).ScreenToClient(Mouse.CursorPos);
  2660.   ArrowLeft := StartPoint.X;
  2661.   ArrowTop := StartPoint.Y;}
  2662.   Caption := InputBox(sNewNote1, sNewNote2, sNewNote1);
  2663. end;
  2664.  
  2665. {destructor TNote.Destroy;
  2666. begin
  2667.  
  2668. end;}
  2669.  
  2670. procedure TNote.Draw(ACanvas: TCanvas);
  2671. var
  2672.   TextSize: TSize;
  2673. {$IFDEF LINUX}
  2674.   //ARect: TRect;
  2675. {$ENDIF}
  2676. begin
  2677.   if (not Visible) then exit;
  2678.   if (Length(Caption) = 0) then exit;
  2679. {$IFDEF DELPHI3_UP}
  2680.   Assert(ACanvas <> nil, 'TNote.Draw: ' + sACanvasIsNil);
  2681. {$ENDIF}
  2682.  
  2683.   ACanvas.Font.Assign(FFont);
  2684.   ACanvas.Pen.Color := FFont.Color;
  2685.  
  2686. {we do the geometry;
  2687.  note that if a Zoom-in has occurred, then the note position changes:}
  2688.   FLeft := TPlot(FOwner).XAxis.FofX(FLeftReal);
  2689.   FTop := TPlot(FOwner).YAxis.FofY(FTopReal);
  2690.   FArrowLeft := TPlot(FOwner).XAxis.FofX(FArrowLeftReal);
  2691.   FArrowTop := TPlot(FOwner).YAxis.FofY(FArrowTopReal);
  2692.  
  2693.   TextSize := ACanvas.TextExtent(Caption
  2694.   {$IFDEF LINUX}
  2695.     , 0
  2696.   {$ENDIF}
  2697.     );
  2698.  
  2699.   Width := TextSize.cx;
  2700.   Height := TextSize.cy;
  2701.  
  2702.   if (FArrowLeft < Left) then
  2703.     ArrowStartLeft := Left
  2704.   else if (FArrowLeft > Left+Width) then
  2705.     ArrowStartLeft := Left + Width
  2706.   else
  2707.     ArrowStartLeft := Left + Width div 2;
  2708.  
  2709.   if (FArrowTop < Top) then
  2710.     ArrowStartTop := Top
  2711.   else if (FArrowTop > Top+Height) then
  2712.     ArrowStartTop := Top + Height
  2713.   else
  2714.     ArrowStartTop := Top + Height div 2;
  2715.  
  2716.   if ((FArrowLeft < Left) or
  2717.       (FArrowLeft > Left+Width) or
  2718.       (FArrowTop < Top) or
  2719.       (FArrowTop > Top+Height)) then
  2720.   begin
  2721.     ACanvas.MoveTo(ArrowStartLeft, ArrowStartTop);
  2722.     ACanvas.LineTo(FArrowLeft, FArrowTop);
  2723.   end;
  2724. {output text to screen:}
  2725. {$IFDEF MSWINDOWS}
  2726.   ACanvas.TextOut(Left, Top, Caption);
  2727. {$ENDIF}
  2728. {$IFDEF LINUX}
  2729.   ACanvas.TextOut(Left, Top {+ Abs(ACanvas.Font.Height)}, Caption);
  2730.   //ACanvas.TextRect(ARect, Left, Top, Caption, TOPLEFT_ALIGN);
  2731. {$ENDIF}
  2732. end;
  2733.  
  2734. {------------------------------------------------------------------------------
  2735.     Procedure: TNote.TracePointerTo
  2736.   Description: Moves the end of the note pointer to X, Y
  2737.        Author: Mat Ballard
  2738.  Date created: 11/23/2000
  2739. Date modified: 11/23/2000 by Mat Ballard
  2740.       Purpose: manages movement of the note pointer
  2741.  Known Issues:
  2742.  ------------------------------------------------------------------------------}
  2743. procedure TNote.TracePointerTo(ACanvas: TCanvas; iX, iY: Integer);
  2744. begin
  2745. {rub out the old line:}
  2746.   ACanvas.Pen.Mode := pmNotXOR;
  2747.   if ((FArrowLeft < Left) or
  2748.       (FArrowLeft > Left+Width) or
  2749.       (FArrowTop < Top) or
  2750.       (FArrowTop > Top+Height)) then
  2751.   begin
  2752.     ACanvas.MoveTo(ArrowStartLeft, ArrowStartTop);
  2753.     ACanvas.LineTo(FArrowLeft, FArrowTop);
  2754.   end;
  2755. {go to new coordinates:}
  2756.   ArrowLeft := iX;
  2757.   ArrowTop := iY;
  2758. {draw the new one:}
  2759.   ACanvas.MoveTo(ArrowStartLeft, ArrowStartTop);
  2760.   ACanvas.LineTo(FArrowLeft, FArrowTop);
  2761. end;
  2762.  
  2763. {------------------------------------------------------------------------------
  2764.     Procedure: TNote.SetArrowLeft
  2765.   Description: protected property Set procedure
  2766.        Author: Mat Ballard
  2767.  Date created: 11/15/2000
  2768. Date modified: 11/15/2000 by Mat Ballard
  2769.       Purpose: sets the ArrowLeft, which also re-calculates the RealArrowLeft
  2770.  Known Issues:
  2771.  ------------------------------------------------------------------------------}
  2772. procedure TNote.SetArrowLeft(Value: Integer);
  2773. begin
  2774.   if (FArrowLeft = Value) then exit;
  2775.  
  2776.   FArrowLeft := Value;
  2777.   FArrowLeftReal := TPlot(FOwner).XAxis.XofF(FArrowLeft);
  2778.   DoHandleChange;
  2779. end;
  2780.  
  2781. {------------------------------------------------------------------------------
  2782.     Procedure: TNote.SetArrowTop
  2783.   Description: protected property Set procedure
  2784.        Author: Mat Ballard
  2785.  Date created: 11/15/2000
  2786. Date modified: 11/15/2000 by Mat Ballard
  2787.       Purpose: sets the ArrowTop, which also re-calculates the RealArrowTop
  2788.  Known Issues:
  2789.  ------------------------------------------------------------------------------}
  2790. procedure TNote.SetArrowTop(Value: Integer);
  2791. begin
  2792.   if (FArrowTop = Value) then exit;
  2793.  
  2794.   FArrowTop := Value;
  2795.   FArrowTopReal := TPlot(FOwner).YAxis.YofF(FArrowTop);
  2796.   DoHandleChange;
  2797. end;
  2798.  
  2799. {------------------------------------------------------------------------------
  2800.     Procedure: TNote.SetLeft
  2801.   Description: protected property Set procedure
  2802.        Author: Mat Ballard
  2803.  Date created: 02/25/2000
  2804. Date modified: 02/25/2000 by Mat Ballard
  2805.       Purpose: sets the (Screen)Left, which also re-calculates the LeftReal
  2806.  Known Issues:
  2807.  ------------------------------------------------------------------------------}
  2808. procedure TNote.SetLeft(Value: Integer);
  2809. begin
  2810.   if (Value = FLeft) then exit;
  2811.  
  2812.   FLeft := Value;
  2813.   FLeftReal := TPlot(FOwner).XAxis.XofF(FLeft);
  2814.   DoHandleChange;
  2815. end;
  2816.  
  2817. {------------------------------------------------------------------------------
  2818.     Procedure: TNote.SetTop
  2819.   Description: protected property Set procedure
  2820.        Author: Mat Ballard
  2821.  Date created: 02/25/2000
  2822. Date modified: 02/25/2000 by Mat Ballard
  2823.       Purpose: sets the (Screen)Top, which also re-calculates the TopReal
  2824.  Known Issues:
  2825.  ------------------------------------------------------------------------------}
  2826. procedure TNote.SetTop(Value: Integer);
  2827. begin
  2828.   if (Value = FTop) then exit;
  2829.  
  2830.   FTop := Value;
  2831.   FTopReal := TPlot(FOwner).YAxis.YofF(FTop);
  2832.   DoHandleChange;
  2833. end;
  2834.  
  2835. {------------------------------------------------------------------------------
  2836.     Procedure: TNote.SetLeftReal
  2837.   Description: protected property Set procedure
  2838.        Author: Mat Ballard
  2839.  Date created: 02/25/2000
  2840. Date modified: 02/25/2000 by Mat Ballard
  2841.       Purpose: sets the (Data)LeftReal, which also re-calculates the Left
  2842.  Known Issues:
  2843.  ------------------------------------------------------------------------------}
  2844. procedure TNote.SetLeftReal(Value: Single);
  2845. begin
  2846.   if (FLeftReal = Value) then exit;
  2847.  
  2848.   FLeftReal := Value;
  2849.   FLeft := TPlot(FOwner).XAxis.FofX(FLeftReal);
  2850.   DoHandleChange;
  2851. end;
  2852.  
  2853. {------------------------------------------------------------------------------
  2854.     Procedure: TNote.SetTopReal
  2855.   Description: protected property Set procedure
  2856.        Author: Mat Ballard
  2857.  Date created: 02/25/2000
  2858. Date modified: 02/25/2000 by Mat Ballard
  2859.       Purpose: sets the (Data)TopReal, which also re-calculates the Top
  2860.  Known Issues:
  2861.  ------------------------------------------------------------------------------}
  2862. procedure TNote.SetTopReal(Value: Single);
  2863. begin
  2864.   if (FTopReal = Value) then exit;
  2865.  
  2866.   FTopReal := Value;
  2867.   FTop := TPlot(FOwner).YAxis.FofY(FTopReal);
  2868.   DoHandleChange;
  2869. end;
  2870.  
  2871. {------------------------------------------------------------------------------
  2872.     Procedure: TNote.SetArrowLeftReal
  2873.   Description: protected property Set procedure
  2874.        Author: Mat Ballard
  2875.  Date created: 02/25/2000
  2876. Date modified: 02/25/2000 by Mat Ballard
  2877.       Purpose: sets the (Data)ArrowLeftReal, which also re-calculates the Left
  2878.  Known Issues:
  2879.  ------------------------------------------------------------------------------}
  2880. procedure TNote.SetArrowLeftReal(Value: Single);
  2881. begin
  2882.   if (FArrowLeftReal = Value) then exit;
  2883.  
  2884.   FArrowLeftReal := Value;
  2885.   FLeft := TPlot(FOwner).XAxis.FofX(FArrowLeftReal);
  2886.   DoHandleChange;
  2887. end;
  2888.  
  2889. {------------------------------------------------------------------------------
  2890.     Procedure: TNote.SetArrowTopReal
  2891.   Description: protected property Set procedure
  2892.        Author: Mat Ballard
  2893.  Date created: 02/25/2000
  2894. Date modified: 02/25/2000 by Mat Ballard
  2895.       Purpose: sets the (Data)ArrowTopReal, which also re-calculates the Top
  2896.  Known Issues:
  2897.  ------------------------------------------------------------------------------}
  2898. procedure TNote.SetArrowTopReal(Value: Single);
  2899. begin
  2900.   if (FArrowTopReal = Value) then exit;
  2901.  
  2902.   FArrowTopReal := Value;
  2903.   FTop := TPlot(FOwner).YAxis.FofY(FArrowTopReal);
  2904.   DoHandleChange;
  2905. end;
  2906.  
  2907.  
  2908. end.
  2909.