home *** CD-ROM | disk | FTP | other *** search
/ PC Format Collection 48 / SENT14D.ISO / tech / delphi / disk15 / sampsrc.pak / GAUGES.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1995-08-24  |  10.0 KB  |  394 lines

  1. unit Gauges;
  2.  
  3. interface
  4.  
  5. uses WinTypes, Messages, Classes, Graphics, Controls, Forms, StdCtrls;
  6.  
  7. type
  8.  
  9.   TGaugeKind = (gkText, gkHorizontalBar, gkVerticalBar, gkPie, gkNeedle);
  10.  
  11.   TGauge = class(TGraphicControl)
  12.   private
  13.     FMinValue: Longint;
  14.     FMaxValue: Longint;
  15.     FCurValue: Longint;
  16.     FKind: TGaugeKind;
  17.     FShowText: Boolean;
  18.     FBorderStyle: TBorderStyle;
  19.     FForeColor: TColor;
  20.     FBackColor: TColor;
  21.     procedure PaintBackground(AnImage: TBitmap);
  22.     procedure PaintAsText(AnImage: TBitmap; PaintRect: TRect);
  23.     procedure PaintAsNothing(AnImage: TBitmap; PaintRect: TRect);
  24.     procedure PaintAsBar(AnImage: TBitmap; PaintRect: TRect);
  25.     procedure PaintAsPie(AnImage: TBitmap; PaintRect: TRect);
  26.     procedure PaintAsNeedle(AnImage: TBitmap; PaintRect: TRect);
  27.     procedure SetGaugeKind(Value: TGaugeKind);
  28.     procedure SetShowText(Value: Boolean);
  29.     procedure SetBorderStyle(Value: TBorderStyle);
  30.     procedure SetForeColor(Value: TColor);
  31.     procedure SetBackColor(Value: TColor);
  32.     procedure SetMinValue(Value: Longint);
  33.     procedure SetMaxValue(Value: Longint);
  34.     procedure SetProgress(Value: Longint);
  35.     function GetPercentDone: Longint;
  36.   protected
  37.     procedure Paint; override;
  38.   public
  39.     constructor Create(AOwner: TComponent); override;
  40.     procedure AddProgress(Value: Longint);
  41.     property PercentDone: Longint read GetPercentDone;
  42.   published
  43.     property Align;
  44.     property Color;
  45.     property Enabled;
  46.     property Kind: TGaugeKind read FKind write SetGaugeKind default gkHorizontalBar;
  47.     property ShowText: Boolean read FShowText write SetShowText default True;
  48.     property Font;
  49.     property BorderStyle: TBorderStyle read FBorderStyle write SetBorderStyle default bsSingle;
  50.     property ForeColor: TColor read FForeColor write SetForeColor default clBlack;
  51.     property BackColor: TColor read FBackColor write SetBackColor default clWhite;
  52.     property MinValue: Longint read FMinValue write SetMinValue default 0;
  53.     property MaxValue: Longint read FMaxValue write SetMaxValue default 100;
  54.     property ParentColor;
  55.     property ParentFont;
  56.     property ParentShowHint;
  57.     property Progress: Longint read FCurValue write SetProgress;
  58.     property ShowHint;
  59.     property Visible;
  60.   end;
  61.  
  62. implementation
  63.  
  64. uses WinProcs, SysUtils;
  65.  
  66. type
  67.   TBltBitmap = class(TBitmap)
  68.     procedure MakeLike(ATemplate: TBitmap);
  69.   end;
  70.  
  71. procedure TBltBitmap.MakeLike(ATemplate: TBitmap);
  72. begin
  73.   Width := ATemplate.Width;
  74.   Height := ATemplate.Height;
  75.   Canvas.Brush.Color := clWindowFrame;
  76.   Canvas.Brush.Style := bsSolid;
  77.   Canvas.FillRect(Rect(0, 0, Width, Height));
  78. end;
  79.  
  80. { This function solves for x in the equation "x is y% of z". }
  81. function SolveForX(Y, Z: Longint): Integer;
  82. begin
  83.   SolveForX := Trunc( Z * (Y * 0.01) );
  84. end;
  85.  
  86. { This function solves for y in the equation "x is y% of z". }
  87. function SolveForY(X, Z: Longint): Integer;
  88. begin
  89.   if Z = 0 then SolveForY := 0
  90.   else SolveForY := Trunc( (X * 100) / Z );
  91. end;
  92.  
  93. { TGauge }
  94. constructor TGauge.Create(AOwner: TComponent);
  95. begin
  96.   inherited Create(AOwner);
  97.   ControlStyle := ControlStyle + [csFramed, csOpaque];
  98.   { default values }
  99.   FMinValue := 0;
  100.   FMaxValue := 100;
  101.   FCurValue := 0;
  102.   FKind := gkHorizontalBar;
  103.   FShowText := True;
  104.   FBorderStyle := bsSingle;
  105.   FForeColor := clBlack;
  106.   FBackColor := clWhite;
  107.   Width := 100;
  108.   Height := 100;
  109. end;
  110.  
  111. function TGauge.GetPercentDone: Longint;
  112. begin
  113.   GetPercentDone := SolveForY(FCurValue - FMinValue, FMaxValue - FMinValue);
  114. end;
  115.  
  116. procedure TGauge.Paint;
  117. var
  118.   TheImage: TBitmap;
  119.   OverlayImage: TBltBitmap;
  120.   PaintRect: TRect;
  121. begin
  122.   with Canvas do
  123.   begin
  124.     TheImage := TBitmap.Create;
  125.     try
  126.       TheImage.Height := Height;
  127.       TheImage.Width := Width;
  128.       PaintBackground(TheImage);
  129.       PaintRect := ClientRect;
  130.       if FBorderStyle = bsSingle then InflateRect(PaintRect, -1, -1);
  131.       OverlayImage := TBltBitmap.Create;
  132.       try
  133.         OverlayImage.MakeLike(TheImage);
  134.         PaintBackground(OverlayImage);
  135.         case FKind of
  136.           gkText: PaintAsNothing(OverlayImage, PaintRect);
  137.           gkHorizontalBar, gkVerticalBar: PaintAsBar(OverlayImage, PaintRect);
  138.           gkPie: PaintAsPie(OverlayImage, PaintRect);
  139.           gkNeedle: PaintAsNeedle(OverlayImage, PaintRect);
  140.         end;
  141.         TheImage.Canvas.CopyMode := cmSrcInvert;
  142.         TheImage.Canvas.Draw(0, 0, OverlayImage);
  143.         TheImage.Canvas.CopyMode := cmSrcCopy;
  144.         if ShowText then PaintAsText(TheImage, PaintRect);
  145.       finally
  146.         OverlayImage.Free;
  147.       end;
  148.       Canvas.CopyMode := cmSrcCopy;
  149.       Canvas.Draw(0, 0, TheImage);
  150.     finally
  151.       TheImage.Destroy;
  152.     end;
  153.   end;
  154. end;
  155.  
  156. procedure TGauge.PaintBackground(AnImage: TBitmap);
  157. var
  158.   ARect: TRect;
  159. begin
  160.   with AnImage.Canvas do
  161.   begin
  162.     CopyMode := cmBlackness;
  163.     ARect := Rect(0, 0, Width, Height);
  164.     CopyRect(ARect, Animage.Canvas, ARect);
  165.     CopyMode := cmSrcCopy;
  166.   end;
  167. end;
  168.  
  169. procedure TGauge.PaintAsText(AnImage: TBitmap; PaintRect: TRect);
  170. var
  171.   S: string;
  172.   X, Y: Integer;
  173.   OverRect: TBltBitmap;
  174. begin
  175.   OverRect := TBltBitmap.Create;
  176.   try
  177.     OverRect.MakeLike(AnImage);
  178.     PaintBackground(OverRect);
  179.     S := Format('%d%%', [PercentDone]);
  180.     with OverRect.Canvas do
  181.     begin
  182.       Brush.Style := bsClear;
  183.       Font := Self.Font;
  184.       Font.Color := clWhite;
  185.       with PaintRect do
  186.       begin
  187.         X := (Right - Left + 1 - TextWidth(S)) div 2;
  188.         Y := (Bottom - Top + 1 - TextHeight(S)) div 2;
  189.       end;
  190.       TextRect(PaintRect, X, Y, S);
  191.     end;
  192.     AnImage.Canvas.CopyMode := cmSrcInvert;
  193.     AnImage.Canvas.Draw(0, 0, OverRect);
  194.   finally
  195.     OverRect.Free;
  196.   end;
  197. end;
  198.  
  199. procedure TGauge.PaintAsNothing(AnImage: TBitmap; PaintRect: TRect);
  200. begin
  201.   with AnImage do
  202.   begin
  203.     Canvas.Brush.Color := BackColor;
  204.     Canvas.FillRect(PaintRect);
  205.   end;
  206. end;
  207.  
  208. procedure TGauge.PaintAsBar(AnImage: TBitmap; PaintRect: TRect);
  209. var
  210.   FillSize: Longint;
  211.   W, H: Integer;
  212. begin
  213.   W := PaintRect.Right - PaintRect.Left + 1;
  214.   H := PaintRect.Bottom - PaintRect.Top + 1;
  215.   with AnImage.Canvas do
  216.   begin
  217.     Brush.Color := BackColor;
  218.     FillRect(PaintRect);
  219.     Pen.Color := ForeColor;
  220.     Pen.Width := 1;
  221.     Brush.Color := ForeColor;
  222.     case FKind of
  223.       gkHorizontalBar:
  224.         begin
  225.           FillSize := SolveForX(PercentDone, W);
  226.           if FillSize > W then FillSize := W;
  227.           if FillSize > 0 then FillRect(Rect(PaintRect.Left, PaintRect.Top,
  228.             FillSize, H));
  229.         end;
  230.       gkVerticalBar:
  231.         begin
  232.           FillSize := SolveForX(PercentDone, H);
  233.           if FillSize >= H then FillSize := H - 1;
  234.           FillRect(Rect(PaintRect.Left, H - FillSize, W, H));
  235.         end;
  236.     end;
  237.   end;
  238. end;
  239.  
  240. procedure TGauge.PaintAsPie(AnImage: TBitmap; PaintRect: TRect);
  241. var
  242.   MiddleX, MiddleY: Integer;
  243.   Angle: Double;
  244.   X, Y, W, H: Integer;
  245.   OverRect: TBltBitmap;
  246. begin
  247.   W := PaintRect.Right - PaintRect.Left;
  248.   H := PaintRect.Bottom - PaintRect.Top;
  249.   if FBorderStyle = bsSingle then
  250.   begin
  251.     Inc(W);
  252.     Inc(H);
  253.   end;
  254.   with AnImage.Canvas do
  255.   begin
  256.     Brush.Color := Color;
  257.     FillRect(PaintRect);
  258.     Brush.Color := BackColor;
  259.     Pen.Color := ForeColor;
  260.     Pen.Width := 1;
  261.     Ellipse(PaintRect.Left, PaintRect.Top, W, H);
  262.     if PercentDone > 0 then
  263.     begin
  264.       Brush.Color := ForeColor;
  265.       MiddleX := W div 2;
  266.       MiddleY := H div 2;
  267.       Angle := (Pi * ((PercentDone / 50) + 0.5));
  268.       Pie(PaintRect.Left, PaintRect.Top, W, H, Round(MiddleX * (1 - Cos(Angle))),
  269.         Round(MiddleY * (1 - Sin(Angle))), MiddleX, 0);
  270.     end;
  271.   end;
  272. end;
  273.  
  274. procedure TGauge.PaintAsNeedle(AnImage: TBitmap; PaintRect: TRect);
  275. var
  276.   MiddleX: Integer;
  277.   Angle: Double;
  278.   X, Y, W, H: Integer;
  279.   OverRect: TBltBitmap;
  280. begin
  281.   with PaintRect do
  282.   begin
  283.     X := Left;
  284.     Y := Top;
  285.     W := Right - Left;
  286.     H := Bottom - Top;
  287.     if FBorderStyle = bsSingle then
  288.     begin
  289.       Inc(W);
  290.       Inc(H);
  291.     end;
  292.   end;
  293.   with AnImage.Canvas do
  294.   begin
  295.     Brush.Color := Color;
  296.     FillRect(PaintRect);
  297.     Brush.Color := BackColor;
  298.     Pen.Color := ForeColor;
  299.     Pen.Width := 1;
  300.     Pie(X, Y, W, H * 2 - 1, X + W, PaintRect.Bottom - 1, X, PaintRect.Bottom - 1);
  301.     MoveTo(X, PaintRect.Bottom);
  302.     LineTo(X + W, PaintRect.Bottom);
  303.     if PercentDone > 0 then
  304.     begin
  305.       Pen.Color := ForeColor;
  306.       MiddleX := Width div 2;
  307.       MoveTo(MiddleX, PaintRect.Bottom - 1);
  308.       Angle := (Pi * ((PercentDone / 100)));
  309.       LineTo(Round(MiddleX * (1 - Cos(Angle))), Round((PaintRect.Bottom - 1) *
  310.         (1 - Sin(Angle))));
  311.     end;
  312.   end;
  313. end;
  314.  
  315. procedure TGauge.SetGaugeKind(Value: TGaugeKind);
  316. begin
  317.   if Value <> FKind then
  318.   begin
  319.     FKind := Value;
  320.     Refresh;
  321.   end;
  322. end;
  323.  
  324. procedure TGauge.SetShowText(Value: Boolean);
  325. begin
  326.   if Value <> FShowText then
  327.   begin
  328.     FShowText := Value;
  329.     Refresh;
  330.   end;
  331. end;
  332.  
  333. procedure TGauge.SetBorderStyle(Value: TBorderStyle);
  334. begin
  335.   if Value <> FBorderStyle then
  336.   begin
  337.     FBorderStyle := Value;
  338.     Refresh;
  339.   end;
  340. end;
  341.  
  342. procedure TGauge.SetForeColor(Value: TColor);
  343. begin
  344.   if Value <> FForeColor then
  345.   begin
  346.     FForeColor := Value;
  347.     Refresh;
  348.   end;
  349. end;
  350.  
  351. procedure TGauge.SetBackColor(Value: TColor);
  352. begin
  353.   if Value <> FBackColor then
  354.   begin
  355.     FBackColor := Value;
  356.     Refresh;
  357.   end;
  358. end;
  359.  
  360. procedure TGauge.SetMinValue(Value: Longint);
  361. begin
  362.   if Value <> FMinValue then
  363.   begin
  364.     FMinValue := Value;
  365.     Refresh;
  366.   end;
  367. end;
  368.  
  369. procedure TGauge.SetMaxValue(Value: Longint);
  370. begin
  371.   if Value <> FMaxValue then
  372.   begin
  373.     FMaxValue := Value;
  374.     Refresh;
  375.   end;
  376. end;
  377.  
  378. procedure TGauge.SetProgress(Value: Longint);
  379. begin
  380.   if (FCurValue <> Value) and (Value >= FMinValue) and (Value <= FMaxValue) then
  381.   begin
  382.     FCurValue := Value;
  383.     Refresh;
  384.   end;
  385. end;
  386.  
  387. procedure TGauge.AddProgress(Value: Longint);
  388. begin
  389.   Progress := FCurValue + Value;
  390.   Refresh;
  391. end;
  392.  
  393. end.
  394.