home *** CD-ROM | disk | FTP | other *** search
/ Chip 1997 April / Chip_1997-04_cd.bin / prezent / cb / data.z / GAUGES.CPP < prev    next >
C/C++ Source or Header  |  1997-01-16  |  10KB  |  348 lines

  1. //---------------------------------------------------------------------------
  2. // Borland C++Builder
  3. // Copyright (c) 1987, 1997 Borland International Inc.  All Rights Reserved.
  4. //---------------------------------------------------------------------------
  5. #if !defined (REGISTER_ALL_CONTROLS)
  6.   #include  "gauges.h"
  7. #else
  8.   #include "gauges\gauges.h"
  9. #endif
  10.  
  11. #include <memory>       //for auto_ptr STL class
  12.  
  13. //#pragma resource "*.res"   //IDE links .res automatically for components
  14.  
  15. namespace Gauges{
  16. void __fastcall Register()
  17. {
  18.   TComponentClass classes[1] = {__classid(TGauge)};
  19.   RegisterComponents("Samples", classes, 0);
  20. }
  21. } //namespace
  22.  
  23.  
  24. /* TBltBitmap */
  25. __fastcall TBltBitmap::TBltBitmap(): Graphics::TBitmap(){}
  26.  
  27. void __fastcall TBltBitmap::MakeLike(Graphics::TBitmap* ATemplate)
  28. {
  29.   Width = ATemplate->Width;
  30.   Height = ATemplate->Height;
  31.   Canvas->Brush->Color = TColor(clWindowFrame);
  32.   Canvas->Brush->Style = bsSolid;
  33.   Canvas->FillRect(Rect(0, 0, Width, Height));
  34. }
  35.  
  36. /* This function solves for x in the equation "x is y% of z". */
  37. Longint SolveForX(Longint Y, Longint Z)
  38. {
  39.   return floor( Z * (Y * 0.01) );
  40. }
  41.  
  42. /* This function solves for y in the equation "x is y% of z". */
  43. Longint SolveForY(Longint X, Longint Z)
  44. {
  45.   if (Z==0)
  46.     return 0;
  47.   else
  48.     return floor( (X * 100.0) / Z );
  49. }
  50.  
  51.  
  52. /* TGauge */
  53.  
  54. __fastcall TGauge::TGauge(TComponent *AOwner)
  55.                  : TGraphicControl(AOwner) 
  56.  
  57. {
  58.   ControlStyle << csFramed << csOpaque;
  59.   /* default values */
  60.   FMinValue = 0;
  61.   FMaxValue = 100;
  62.   FCurValue = 0;
  63.   FKind = gkHorizontalBar;
  64.   FShowText = True;
  65.   FBorderStyle = bsSingle;
  66.   FForeColor = clBlack;
  67.   FBackColor = clWhite;
  68.   Width = 100;
  69.   Height = 100;
  70. }
  71.  
  72. Longint __fastcall TGauge::GetPercentDone()
  73. {
  74.   return SolveForY(FCurValue - FMinValue, FMaxValue - FMinValue);
  75. }
  76.  
  77. void __fastcall TGauge::Paint()
  78. {
  79.   std::auto_ptr<Graphics::TBitmap> TheImage(new Graphics::TBitmap());
  80.   std::auto_ptr<TBltBitmap> OverlayImage(new TBltBitmap());
  81.   TRect PaintTRect;
  82.  
  83.   TheImage->Height = Height;
  84.   TheImage->Width = Width;
  85.   PaintBackground(TheImage.get());
  86.   PaintTRect = ClientRect;
  87.   if (FBorderStyle == bsSingle)
  88.     InflateRect(&RECT(PaintTRect), -1, -1);
  89.   OverlayImage->MakeLike(TheImage.get());
  90.   PaintBackground(OverlayImage.get());
  91.   switch(FKind){
  92.     case gkText:
  93.       PaintAsNothing(OverlayImage.get(), PaintTRect);
  94.       break;
  95.     case gkHorizontalBar:
  96.     case gkVerticalBar:
  97.       PaintAsBar(OverlayImage.get(), PaintTRect);
  98.       break;
  99.     case gkPie:
  100.       PaintAsPie(OverlayImage.get(), PaintTRect);
  101.       break;
  102.     case gkNeedle:
  103.       PaintAsNeedle(OverlayImage.get(), PaintTRect);
  104.       break;
  105.   }
  106.   TheImage->Canvas->CopyMode = cmSrcInvert;
  107.   TheImage->Canvas->Draw(0, 0, OverlayImage.get());
  108.   TheImage->Canvas->CopyMode = cmSrcCopy;
  109.   if (ShowText == True)
  110.     PaintAsText(TheImage.get(), PaintTRect);
  111.   Canvas->CopyMode = cmSrcCopy;
  112.   Canvas->Draw(0, 0, TheImage.get());
  113. }
  114.  
  115. void __fastcall TGauge::PaintBackground(Graphics::TBitmap* AnImage)
  116. {
  117.   TRect  ARect;
  118.   AnImage->Canvas->CopyMode = cmBlackness;
  119.   ARect = Rect(0, 0, Width, Height);
  120.   AnImage->Canvas->CopyRect(ARect, AnImage->Canvas, ARect);
  121.   AnImage->Canvas->CopyMode = cmSrcCopy;
  122. }
  123.  
  124. void __fastcall TGauge::PaintAsText(Graphics::TBitmap* AnImage, const TRect& PaintRect)
  125. {
  126.   String  S;
  127.   Integer X, Y;
  128.   std::auto_ptr<TBltBitmap> OverRect(new TBltBitmap);
  129.  
  130.   OverRect->MakeLike(AnImage);
  131.   PaintBackground(OverRect.get());
  132.   S = AnsiString((int)PercentDone);
  133.   S += "%";
  134.   OverRect->Canvas->Brush->Style = bsClear;
  135.   OverRect->Canvas->Font = Font;
  136.   OverRect->Canvas->Font->Color = clWhite;
  137.   X = (PaintRect.Right - PaintRect.Left + 1 - OverRect->Canvas->TextWidth(S)) / 2;
  138.   Y = (PaintRect.Bottom - PaintRect.Top + 1 - OverRect->Canvas->TextHeight(S)) / 2;
  139.   OverRect->Canvas->TextRect(PaintRect, X, Y, S);
  140.   AnImage->Canvas->CopyMode = cmSrcInvert;
  141.   AnImage->Canvas->Draw(0, 0, OverRect.get());
  142. }
  143.  
  144. void __fastcall TGauge::PaintAsNothing(Graphics::TBitmap* AnImage, const TRect &PaintRect)
  145. {
  146.     AnImage->Canvas->Brush->Color = BackColor;
  147.     AnImage->Canvas->FillRect(PaintRect);
  148. }
  149.  
  150. void __fastcall TGauge::PaintAsBar(Graphics::TBitmap* AnImage, const TRect& PaintRect)
  151. {
  152.   Longint  FillSize;
  153.   Integer  W, H;
  154.  
  155.   W = PaintRect.Right - PaintRect.Left + 1;
  156.   H = PaintRect.Bottom - PaintRect.Top + 1;
  157.  
  158.   AnImage->Canvas->Brush->Color = BackColor;
  159.   AnImage->Canvas->FillRect(PaintRect);
  160.   AnImage->Canvas->Pen->Color = ForeColor;
  161.   AnImage->Canvas->Pen->Width = 1;
  162.   AnImage->Canvas->Brush->Color = ForeColor;
  163.   switch(FKind){
  164.     case gkHorizontalBar:
  165.       FillSize = SolveForX(PercentDone, W);
  166.       if (FillSize > W)
  167.          FillSize = W;
  168.       if (FillSize > 0)
  169.          AnImage->Canvas->FillRect(Rect(PaintRect.Left,
  170.                                         PaintRect.Top,
  171.                                         FillSize,
  172.                                         H));
  173.      break;
  174.    case gkVerticalBar:
  175.      FillSize = SolveForX(PercentDone, H);
  176.      if (FillSize >= H)
  177.        AnImage->Canvas->FillRect(Rect(PaintRect.Left,
  178.                                       H - FillSize,
  179.                                       W,
  180.                                       H));
  181.      break;
  182.   }
  183. }
  184.  
  185. void __fastcall TGauge::PaintAsPie(Graphics::TBitmap* AnImage, const TRect& PaintRect)
  186. {
  187.   Integer  MiddleX, MiddleY;
  188.   Double  Angle;
  189.   Integer  W, H;
  190.  
  191.   W = PaintRect.Right - PaintRect.Left;
  192.   H = PaintRect.Bottom - PaintRect.Top;
  193.  
  194.   if (FBorderStyle == bsSingle){
  195.       W++;
  196.       H++;
  197.   }
  198.   AnImage->Canvas->Brush->Color = Color;
  199.   AnImage->Canvas->FillRect(PaintRect);
  200.   AnImage->Canvas->Brush->Color = BackColor;
  201.   AnImage->Canvas->Pen->Color = ForeColor;
  202.   AnImage->Canvas->Pen->Width = 1;
  203.   AnImage->Canvas->Ellipse(PaintRect.Left,
  204.                            PaintRect.Top,
  205.                            W, H);
  206.   if (PercentDone > 0) {
  207.      AnImage->Canvas->Brush->Color = ForeColor;
  208.      MiddleX = W / 2;
  209.      MiddleY = H / 2;
  210.      Angle = (Pi * ((PercentDone / 50) + 0.5));
  211.      AnImage->Canvas->Pie(PaintRect.Left,
  212.                           PaintRect.Top,
  213.                           W, H,
  214.                           floor(MiddleX * (1 - cos(Angle))), //should be rounded, really
  215.                           floor(MiddleY * (1 - sin(Angle))),
  216.                           MiddleX, 0);
  217.   }
  218. }
  219.  
  220. void __fastcall TGauge::PaintAsNeedle(Graphics::TBitmap* AnImage, const TRect& PaintRect)
  221. {
  222.   Integer  MiddleX;
  223.   Double   Angle;
  224.   Integer  X, Y, W, H;
  225.  
  226.   X = PaintRect.Left;
  227.   Y = PaintRect.Top;
  228.   W = PaintRect.Right - PaintRect.Left;
  229.   H = PaintRect.Bottom - PaintRect.Top;
  230.   if (FBorderStyle == bsSingle){
  231.         W++;
  232.         H++;
  233.   }
  234.  
  235.   AnImage->Canvas->Brush->Color = Color;
  236.   AnImage->Canvas->FillRect(PaintRect);
  237.   AnImage->Canvas->Brush->Color = BackColor;
  238.   AnImage->Canvas->Pen->Color = ForeColor;
  239.   AnImage->Canvas->Pen->Width = 1;
  240.   AnImage->Canvas->Pie(X, Y,
  241.                        W, H * 2 - 1,
  242.                        X + W,
  243.                        PaintRect.Bottom - 1,
  244.                        X,
  245.                        PaintRect.Bottom - 1);
  246.   AnImage->Canvas->MoveTo(X, PaintRect.Bottom);
  247.   AnImage->Canvas->LineTo(X + W, PaintRect.Bottom);
  248.   if (PercentDone > 0){
  249.     AnImage->Canvas->Pen->Color = ForeColor;
  250.     MiddleX = Width / 2;
  251.     AnImage->Canvas->MoveTo(MiddleX, PaintRect.Bottom - 1);
  252.     Angle = (Pi * ((PercentDone / 100)));
  253.     AnImage->Canvas->LineTo(floor(MiddleX * (1 - cos(Angle))),
  254.                             floor((PaintRect.Bottom - 1) * (1 - sin(Angle))));
  255.   }
  256. }
  257.  
  258. void __fastcall TGauge::SetGaugeKind(TGaugeKind Value)
  259. {
  260.   if (Value != FKind){
  261.       FKind = Value;
  262.       Refresh();
  263.   }
  264. }
  265.  
  266. void __fastcall TGauge::SetShowText(Boolean Value)
  267. {
  268.   if (Value != FShowText){
  269.       FShowText = Value;
  270.       Refresh();
  271.   }
  272. }
  273.  
  274. void __fastcall TGauge::SetBorderStyle(TBorderStyle Value)
  275. {
  276.   if (Value != FBorderStyle) {
  277.       FBorderStyle = Value;
  278.       Refresh();
  279.   }
  280. }
  281.  
  282. void __fastcall TGauge::SetForeColor(TColor Value)
  283. {
  284.   if (Value != FForeColor){
  285.       FForeColor = Value;
  286.       Refresh();
  287.   }
  288. }
  289.  
  290. void __fastcall TGauge::SetBackColor(TColor Value)
  291. {
  292.   if (Value != FBackColor){
  293.       FBackColor = Value;
  294.       Refresh();
  295.   }
  296. }
  297.  
  298. void __fastcall TGauge::SetMinValue(Longint Value)
  299. {
  300.   if (Value!= FMinValue){
  301.     if (Value > FMaxValue)
  302.       throw new Exception(SOutOfRange);//,  !GC various constructors for Exception
  303.                           //-MaxInt,        !object not available at this time ! !
  304.                           //FMaxValue - 1);
  305.     FMinValue = Value;
  306.     if (FCurValue < Value)
  307.       FCurValue = Value;
  308.     Refresh();
  309.   }
  310. }
  311.  
  312. void __fastcall TGauge::SetMaxValue(Longint Value)
  313. {
  314.   if (Value){
  315.     if (Value)
  316.       throw new Exception(SOutOfRange);//,
  317.                          // FMinValue + 1,  !GC various constructors for Exception
  318.                          // MaxInt);        !object not available at this time ! !
  319.     FMaxValue = Value;
  320.     if (FCurValue > Value)
  321.       FCurValue = Value;
  322.     Refresh();
  323.   }
  324. }
  325.  
  326. void __fastcall TGauge::SetProgress(Longint Value)
  327. {
  328.   Longint  TempPercent;
  329.   TempPercent = GetPercentDone();  // remember where we were
  330.   if (Value < FMinValue)
  331.     Value = FMinValue;
  332.   else if (Value > FMaxValue)
  333.     Value = FMaxValue;
  334.   if (FCurValue != Value){
  335.     FCurValue = Value;
  336.     if (TempPercent != GetPercentDone()) //only refresh if percentage changed
  337.       Refresh();
  338.   }
  339. }
  340.  
  341. void __fastcall TGauge::AddProgress(Longint Value)
  342. {
  343.   Progress = FCurValue + Value;
  344.   Refresh();
  345. }
  346.  
  347. //End of conversion...
  348.