Advertisement
jpfassis

MyCircleProgress - Delphi - GDI

Apr 1st, 2020
937
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 7.12 KB | None | 0 0
  1. unit UMyCircleProgress;
  2.  
  3. interface
  4.  
  5. uses
  6.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms;
  7.  
  8. const
  9.   FORE_COLOR = clTeal;
  10.   BACK_COLOR = clSilver;
  11.   PEN_WIDTH  = 4;
  12.  
  13. type
  14.   TCircleProgress = class(TGraphicControl)
  15.   private
  16.     { Private declarations }
  17.     FMinValue: Longint;
  18.     FMaxValue: Longint;
  19.     FCurValue: Longint;
  20.     FPenWidth: Integer;
  21.     FShowText: Boolean;
  22.     FForeColor: TColor;
  23.     FBackColor: TColor;
  24.     FFullCover: Boolean;
  25.  
  26.     procedure SetShowText(const Value: Boolean);
  27.     procedure SetForeColor(const Value: TColor);
  28.     procedure SetBackColor(const Value: TColor);
  29.     procedure SetFullCover(const Value: Boolean);
  30.     procedure SetMinValue(const Value: Longint);
  31.     procedure SetMaxValue(const Value: Longint);
  32.     procedure SetProgress(const Value: Longint);
  33.     procedure SetPenWidth(const Value: Integer);
  34.     //draw
  35.     procedure DrawBackground(const ACanvas: TCanvas);
  36.     procedure DrawProgress(const ACanvas: TCanvas);
  37.   protected
  38.     { Protected declarations }
  39.     procedure Paint; override;
  40.     procedure Resize; override;
  41.   public
  42.     { Public declarations }
  43.     constructor Create(AOwner: TComponent); override;
  44.   published
  45.     property Align;
  46.     property Anchors;
  47.     property BackColor: TColor read FBackColor write SetBackColor default BACK_COLOR;
  48.     property FullCover: Boolean read FFullCover write SetFullCover default False;
  49.     property Color;
  50.     property Constraints;
  51.     property Enabled;
  52.     property ForeColor: TColor read FForeColor write SetForeColor default FORE_COLOR;
  53.     property Font;
  54.     property MinValue: Longint read FMinValue write SetMinValue default 0;
  55.     property MaxValue: Longint read FMaxValue write SetMaxValue default 100;
  56.     property ParentColor;
  57.     property ParentFont;
  58.     property ParentShowHint;
  59.     property PenWidth: Integer read FPenWidth write SetPenWidth;
  60.     property PopupMenu;
  61.     property Progress: Longint read FCurValue write SetProgress;
  62.     property ShowHint;
  63.     property ShowText: Boolean read FShowText write SetShowText default True;
  64.     property Visible;
  65.   end;
  66.  
  67. procedure Register;
  68.  
  69. implementation
  70.  
  71. uses
  72.   Math, Consts, GDIPOBJ, GDIPAPI;
  73.  
  74. procedure Register;
  75. begin
  76.   RegisterComponents('My Componentes', [TCircleProgress]);
  77. end;
  78.  
  79. { TCircleProgress }
  80.  
  81. constructor TCircleProgress.Create(AOwner: TComponent);
  82. begin
  83.   inherited Create(AOwner);
  84.  
  85.   ControlStyle := ControlStyle + [csFramed, csOpaque];
  86.   { default values }
  87.   FMinValue := 0;
  88.   FMaxValue := 100;
  89.   FCurValue := 0;
  90.   FShowText := True;
  91.   FForeColor := FORE_COLOR;
  92.   FBackColor := BACK_COLOR;
  93.   FPenWidth := PEN_WIDTH;
  94.   Width := 100;
  95.   Height := 100;
  96. end;
  97.  
  98. procedure TCircleProgress.DrawBackground(const ACanvas: TCanvas);
  99. var
  100.   g: TGPGraphics;
  101.   p: TGPPen;
  102.   r: TGPRectF;
  103.   pw: Integer;
  104. begin
  105.   //background
  106.   ACanvas.Brush.Color := Self.Color;
  107.   ACanvas.FillRect(Self.ClientRect);
  108.  
  109.   //track
  110.   g := TGPGraphics.Create(ACanvas.Handle);
  111.   pw := FPenWidth;
  112.   if not FFullCover then
  113.   Inc(pw, 2);
  114.   p := TGPPen.Create(ColorRefToARGB(FBackColor), pw);
  115.   try
  116.     r := MakeRect(pw / 2, pw / 2, Self.Width - pw - 1, Self.Height - pw - 1);
  117.     g.SetSmoothingMode(SmoothingModeAntiAlias);
  118.     g.DrawEllipse(p, r);
  119.   finally
  120.     p.Free;
  121.     g.Free;
  122.   end;
  123. end;
  124.  
  125. procedure TCircleProgress.DrawProgress(const ACanvas: TCanvas);
  126.   procedure DrawPercent(g: TGPGraphics);
  127.   var
  128.     percent: Integer;
  129.     sb: TGPSolidBrush;
  130.     fm: TGPFontFamily;
  131.     f: TGPFont;
  132.     sf: TGPStringFormat;
  133.   begin
  134.     percent := Round(FCurValue * 100 / (FMaxValue - FMinValue));
  135.     sb := TGPSolidBrush.Create(ColorRefToARGB(Font.Color));
  136.     fm := TGPFontFamily.Create(Self.Font.Name);
  137.     f := TGPFont.Create(fm, Self.Font.Size, FontStyleRegular, UnitPoint);
  138.     sf := TGPStringFormat.Create();
  139.     sf.SetAlignment(StringAlignmentCenter);
  140.     sf.SetLineAlignment(StringAlignmentCenter);
  141.     g.DrawString(Format('%d%%', [percent]), -1, f, MakeRect(0.0, 0.0, Self.Width, Self.Height), sf, sb);
  142.   end;
  143.  
  144. var
  145.   g: TGPGraphics;
  146.   p: TGPPen;
  147.   pw: Integer;
  148.   r: TGPRectF;
  149.   angle: Single;
  150. begin
  151.   g := TGPGraphics.Create(ACanvas.Handle);
  152.   p := TGPPen.Create(ColorRefToARGB(FForeColor), FPenWidth);
  153.   try
  154.     pw := FPenWidth;
  155.     if not FFullCover then
  156.       pw := pw + 2;
  157.     r := MakeRect(pw / 2, pw / 2, Self.Width - pw - 1, Self.Height - pw - 1);
  158.  
  159.     g.SetSmoothingMode(SmoothingModeHighQuality);
  160.     angle := (FCurValue - FMinValue) * 360 / FMaxValue;
  161.     g.DrawArc(p, r, -90, angle);
  162.  
  163.     //Paint percentage
  164.     if FShowText then
  165.       DrawPercent(g);
  166.   finally
  167.     p.Free;
  168.     g.Free;
  169.   end;
  170. end;
  171.  
  172. procedure TCircleProgress.Paint;
  173. var
  174.   bmp: TBitmap;
  175. begin
  176.   inherited;
  177.  
  178.   bmp := TBitmap.Create;
  179.   try
  180.     bmp.Height := Height;
  181.     bmp.Width := Width;
  182.     DrawBackground(bmp.Canvas);
  183.     DrawProgress(bmp.Canvas);
  184.  
  185.     Canvas.CopyMode := cmSrcCopy;
  186.     Canvas.Draw(0, 0, bmp)
  187.   finally
  188.     bmp.Free;
  189.   end;
  190. end;
  191.  
  192. procedure TCircleProgress.ReSize;
  193. begin
  194.   inherited;
  195.  
  196.   if FPenWidth > Self.Width div 2 - 1 then
  197.   begin
  198.     FPenWidth := Self.Width div 2 - 1;
  199.     Invalidate;
  200.   end;
  201. end;
  202.  
  203. procedure TCircleProgress.SetBackColor(const Value: TColor);
  204. begin
  205.   if FBackColor <> Value then
  206.   begin
  207.     FBackColor := Value;
  208.     Invalidate;
  209.   end;
  210. end;
  211.  
  212. procedure TCircleProgress.SetForeColor(const Value: TColor);
  213. begin
  214.   if FForeColor <> Value then
  215.   begin
  216.     FForeColor := Value;
  217.     Invalidate;
  218.   end;
  219. end;
  220.  
  221. procedure TCircleProgress.SetFullCover(const Value: Boolean);
  222. begin
  223.   if FFullCover <> Value then
  224.   begin
  225.     FFullCover := Value;
  226.     Invalidate;
  227.   end;
  228. end;
  229.  
  230. procedure TCircleProgress.SetMaxValue(const Value: Integer);
  231. begin
  232.   if FMaxValue <> Value then
  233.   begin
  234.     if Value < FMinValue then
  235.       if not (csLoading in ComponentState) then
  236.         raise EInvalidOperation.CreateFmt(SOutOfRange, [FMinValue + 1, MaxInt]);
  237.  
  238.     FMaxValue := Value;
  239.     if FCurValue > Value then FCurValue := Value;
  240.     Invalidate;
  241.   end;
  242. end;
  243.  
  244. procedure TCircleProgress.SetMinValue(const Value: Integer);
  245. begin
  246.   if FMinValue <> Value then
  247.   begin
  248.     if Value > FMaxValue then
  249.       if not (csLoading in ComponentState) then
  250.         raise EInvalidOperation.CreateFmt(SOutOfRange, [-MaxInt, FMaxValue - 1]);
  251.  
  252.     FMinValue := Value;
  253.     if FCurValue < Value then FCurValue := Value;
  254.     Invalidate;
  255.   end;
  256. end;
  257.  
  258. procedure TCircleProgress.SetPenWidth(const Value: Integer);
  259. begin
  260.   if FPenWidth <> Value then
  261.   begin
  262.     FPenWidth := Value;
  263.     if FPenWidth < 1 then
  264.       FPenWidth := 1
  265.     else if FPenWidth > Self.Width div 2 - 1 then
  266.       FPenWidth := Self.Width div 2 - 1;
  267.     Invalidate;
  268.   end;
  269. end;
  270.  
  271. procedure TCircleProgress.SetProgress(const Value: Integer);
  272. begin
  273.   iF FCurValue <> Value then
  274.   begin
  275.     FCurValue := Value;
  276.     if FCurValue < FMinValue then
  277.       FCurValue := FMinValue
  278.     else if FCurValue > FMaxValue then
  279.       FCurValue := FMaxValue;
  280.  
  281.     Invalidate;
  282.   end;
  283. end;
  284.  
  285. procedure TCircleProgress.SetShowText(const Value: Boolean);
  286. begin
  287.   if FShowText <> Value then
  288.   begin
  289.     FShowText := Value;
  290.     Invalidate;
  291.   end;
  292. end;
  293.  
  294. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement