hfs2/progFrmLib.pas
Massimo Melina b654228675 first commit
2020-05-02 19:04:16 +02:00

204 lines
5.1 KiB
ObjectPascal

{
Copyright (C) 2002-2008 Massimo Melina (www.rejetto.com)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
}
unit progFrmLib;
interface
uses
ComCtrls, Forms, controls, ExtCtrls, buttons, graphics;
type
TprogressForm = class
private
prog: TProgressBar;
frm: Tform;
msgPnl: Tpanel;
cancelBtn: TbitBtn;
btnPnl: Tpanel;
stack: array of record ofs,length:real end;
partialLength: real;
canceled: boolean;
function getPos():real;
procedure setPos(x:real);
function getGlobalPos():real;
procedure setGlobalPos(x:real);
function getCaption():string;
procedure setCaption(x:string);
function getVisible():boolean;
procedure onCancel(Sender: TObject);
procedure onResize(Sender: TObject);
public
preventBackward: boolean;
constructor create;
procedure show(caption_:string=''; cancel:boolean=FALSE);
procedure hide();
property progress:real read getPos write setPos;
property globalPosition:real read getGlobalPos write setGlobalPos;
property caption:string read getCaption write setCaption;
property visible:boolean read getVisible;
property cancelRequested:boolean read canceled;
procedure push(sublength:real);
procedure pop();
procedure showCancel();
procedure hideCancel();
procedure reset();
end;
implementation
function max(a,b:integer):integer;
begin if a > b then result:=a else result:=b end;
constructor TprogressForm.create;
begin
frm:=Tform.create(NIL);
frm.Position:=poScreenCenter;
frm.Width:=200;
frm.BorderStyle:=bsNone;
frm.BorderWidth:=15;
frm.Height:=25+frm.BorderWidth*2;
frm.OnResize:=onResize;
//frm.FormStyle:=fsStayOnTop;
msgPnl:=Tpanel.create(frm);
msgPnl.Parent:=frm;
msgPnl.align:=alTop;
msgPnl.height:=20;
msgPnl.BevelOuter:=bvLowered;
prog:=TProgressBar.Create(frm);
prog.Parent:=frm;
prog.BorderWidth:=3;
prog.Min:=0;
prog.max:=100; // resolution
prog.Align:=alClient;
prog.smooth:=TRUE;
btnPnl:=Tpanel.create(frm);
btnPnl.parent:=frm;
btnPnl.Align:=alBottom;
btnPnl.BevelOuter:=bvLowered;
cancelBtn:=TbitBtn.create(frm);
cancelBtn.parent:=btnPnl;
cancelBtn.Kind:=bkCancel;
cancelBtn.top:=10;
cancelBtn.OnClick:=onCancel;
btnPnl.Height:=cancelBtn.Height+cancelBtn.top*2;
btnPnl.Hide();
partialLength:=1;
push(1); // init stack
frm.Height:=frm.Height+msgPnl.Height;
end; // constructor
function TprogressForm.getVisible():boolean;
begin result:=frm.Visible end;
procedure TprogressForm.showCancel();
begin
if btnPnl.visible then exit;
frm.Height:=frm.Height+btnPnl.Height;
btnPnl.show();
end; // showCancel
procedure TprogressForm.hideCancel();
begin
if not btnPnl.visible then exit;
frm.Height:=frm.Height-btnPnl.Height;
btnPnl.hide();
end; // hideCancel
procedure TprogressForm.show(caption_: string; cancel:boolean);
begin
canceled:=FALSE;
if not frm.visible then reset();
if caption_ > '' then caption:=caption_;
if cancel then showCancel();
frm.Show();
end; // show
procedure TprogressForm.hide();
begin
frm.hide();
hideCancel();
end;
function TprogressForm.getCaption():string;
begin result:=msgPnl.caption end;
procedure TprogressForm.setCaption(x:string);
begin
msgPnl.caption:=x;
frm.Width:=max(200,
frm.Canvas.TextWidth(x)+(msgPnl.BorderWidth+frm.BorderWidth)*2+20 );
end;
procedure TprogressForm.setGlobalPos(x:real);
begin
x:=x*prog.max;
if preventBackward and (prog.position > x) then x:=prog.position;
prog.position:=round(x);
end; // setGlobalPos
function TprogressForm.getGlobalPos():real;
begin result:=prog.position/prog.max end;
procedure TprogressForm.setPos(x:real);
begin setGlobalPos(stack[length(stack)-1].ofs + x*partialLength ) end;
function TprogressForm.getPos():real;
begin result:=getGlobalPos()/partialLength + stack[length(stack)-1].ofs end;
procedure TprogressForm.push(sublength:real);
var
i: integer;
begin
assert(sublength <= 1,'TprogressForm.push(X): X>1');
i:=length(stack);
setLength(stack, i+1);
stack[i].ofs:=globalPosition;
stack[i].length:=partialLength;
partialLength:=partialLength*sublength;
end; // push
procedure TprogressForm.pop();
var
i: integer;
begin
assert(length(stack) > 1, 'TprogressForm.pop(): empty stack');
progress:=1;
i:=length(stack)-1;
partialLength:=stack[i].length;
setlength(stack, i);
end; // pop
procedure TprogressForm.onCancel(Sender: TObject);
begin canceled:=TRUE end;
procedure TprogressForm.onResize(Sender: TObject);
begin cancelBtn.left:=(frm.width-cancelBtn.width) div 2-frm.borderWidth end;
procedure TprogressForm.reset();
begin prog.position:=0 end;
end.