unit ProgressHintFrm;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Gauges, StdCtrls, ExtCtrls, Math;

type
  TProgressHintForm = class(TForm)
    Shape: TShape;
    gProgress: TGauge;
    gSubProgress: TGauge;
    lblProgressHint: TLabel;
    lblSubProgressHint: TLabel;
    lblMainHint: TLabel;
    lblPrecent: TLabel;
    lblSubPrecent: TLabel;
  private
    FHintProgress: Boolean;
    FHasSubProgress: Boolean;
    procedure InitForm;
  public
    constructor Create(AHintProgress, AHasSubProgress: Boolean);
    destructor Destroy; override;
  end;

var
  ProgressHintForm: TProgressHintForm;

procedure ShowProgressHint(const AHint: string; AMaxValue: Integer = 0;
  const ASubHint: string = ''; ASubMaxValue: Integer = 0);
procedure UpdateProgressMaxValue(AMaxValue: Integer; AIsSub: Boolean = False);
procedure UpdateProgressPosition(APos: Integer; ASubPos: Integer = 0); overload;
procedure UpdateProgressPosition(AIsSub: Boolean = False); overload;
procedure UpdateProgressHint(const AHint: string; AIsSub: Boolean = False); overload;
procedure UpdateProgressHint(APos: Integer; AIsSub: Boolean = False); overload;
procedure CloseProgressHint;

implementation

{$R *.dfm}

procedure ShowProgressHint(const AHint: string; AMaxValue: Integer = 0;
  const ASubHint: string = ''; ASubMaxValue: Integer = 0);
begin
  ProgressHintForm := TProgressHintForm.Create(AMaxValue <> 0, ASubMaxValue <> 0);
  ProgressHintForm.lblProgressHint.Caption := AHint;
  ProgressHintForm.gProgress.MaxValue := AMaxValue;
  ProgressHintForm.lblSubProgressHint.Caption := ASubHint;
  ProgressHintForm.gSubProgress.MaxValue := ASubMaxValue;
  ProgressHintForm.Show;
end;

procedure UpdateProgressMaxValue(AMaxValue: Integer; AIsSub: Boolean = False);
begin
  if AIsSub then
    ProgressHintForm.gSubProgress.MaxValue := AMaxValue
  else
    ProgressHintForm.gProgress.MaxValue := aMaxValue;
  ProgressHintForm.Update;
end;

procedure UpdateProgressPosition(APos: Integer; ASubPos: Integer = 0);
begin
  with ProgressHintForm do
  begin
    gSubProgress.Progress := ASubPos;
    lblSubPrecent.Caption := Format('%3d', [gSubProgress.PercentDone])+'%';
    gProgress.Progress := APos;
    lblPrecent.Caption := Format('%3d', [gProgress.PercentDone])+'%';
    Update;
  end;
end;

procedure UpdateProgressPosition(AIsSub: Boolean = False);
begin
  with ProgressHintForm do
  begin
    if AIsSub then
    begin
      gSubProgress.Progress := Min(gSubProgress.Progress + 1, gSubProgress.MaxValue);
      lblSubPrecent.Caption := Format('%3d', [gSubProgress.PercentDone])+'%'
    end
    else
    begin
      gProgress.Progress := Min(gProgress.Progress + 1, gProgress.MaxValue);
      lblPrecent.Caption := Format('%3d', [gProgress.PercentDone])+'%';
    end;
    Update;
  end;
end;

procedure UpdateProgressHint(const AHint: string; AIsSub: Boolean = False);
begin
  if AIsSub then
    ProgressHintForm.lblSubProgressHint.Caption := AHint
  else
    ProgressHintForm.lblProgressHint.Caption := AHint;
  ProgressHintForm.Update;
end;

procedure UpdateProgressHint(APos: Integer; AIsSub: Boolean = False);
begin
  with ProgressHintForm do
    if AIsSub then
    begin
      gSubProgress.Progress := gSubProgress.Progress + APos;
      if gSubProgress.Progress > gSubProgress.MaxValue then
        gSubProgress.Progress := 0;
      lblSubPrecent.Caption := Format('%3d', [gSubProgress.PercentDone])+'%';
    end
    else
    begin
      gProgress.Progress := gProgress.Progress + APos;
      lblPrecent.Caption := Format('%3d', [gProgress.PercentDone])+'%';
    end;
  ProgressHintForm.Update;
end;

procedure CloseProgressHint;
begin
  FreeAndNil(ProgressHintForm);
end;

{ TProgressHintForm }

constructor TProgressHintForm.Create(AHintProgress, AHasSubProgress: Boolean);
begin
  inherited Create(nil);
  FHintProgress := AHintProgress;
  FHasSubProgress := AHasSubProgress;
  InitForm;
end;

destructor TProgressHintForm.Destroy;
begin
  inherited;
end;

procedure TProgressHintForm.InitForm;
begin
  if not FHintProgress then
    Height := 48
  else if FHasSubProgress then
    Height := 106
  else
    Height := 66;
  lblPrecent.Visible := FHintProgress;
  gProgress.Visible := FHintProgress;
  lblSubProgressHint.Visible := FHasSubProgress;
  lblSubPrecent.Visible := FHasSubProgress;
  gSubProgress.Visible := FHasSubProgress;
end;

end.
