lazarus-ccr/components/Comba_Animation/samples/controlssample/frmcontrolsample.pas
2017-03-06 22:32:35 +00:00

622 lines
20 KiB
ObjectPascal

unit frmcontrolsample;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
StdCtrls, Buttons, uanimationbasic, uanimationcontrol
(* Still not working
, uanimationbitmap
*)
;
type
{ TfrmAnimationControls }
TfrmAnimationControls = class(TForm)
BitBtn1: TBitBtn;
butSliding: TBitBtn;
butReverse: TButton;
butPause: TButton;
butBounceCaption: TButton;
butDropDown: TButton;
butAlphaBlend: TButton;
butZoomTest: TButton;
CheckBox1: TCheckBox;
chkMetronome: TCheckBox;
chkLabelFlashing: TCheckBox;
chkMarquee: TCheckBox;
grpButtons: TGroupBox;
imgFlareMarquee: TImage;
Label1: TLabel;
lblFPS: TLabel;
lblFlashingLabel: TLabel;
lblDropDownMessage: TLabel;
Label3: TLabel;
Label4: TLabel;
Label5: TLabel;
lblMarqueeText: TLabel;
lbSampleEntries: TListBox;
Panel1: TPanel;
pnlMarquee: TPanel;
pnlAttached: TPanel;
pnlDropDownContents: TPanel;
pnlDropDownHeader: TPanel;
pnlDropDown: TPanel;
pnlText1: TPanel;
pnlCheckbox: TPanel;
Shape1: TShape;
shpTri1: TShape;
shpTri2: TShape;
shpSliding: TShape;
tmrAnimatedCadence: TTimer;
procedure BitBtn1Click(Sender: TObject);
procedure butAlphaBlendClick(Sender: TObject);
procedure butBounceCaptionClick(Sender: TObject);
procedure butDropDownClick(Sender: TObject);
procedure butReverseClick(Sender: TObject);
procedure butPauseClick(Sender: TObject);
procedure butSlidingClick(Sender: TObject);
procedure butZoomTestClick(Sender: TObject);
procedure CheckBox1Change(Sender: TObject);
procedure chkMarqueeChange(Sender: TObject);
procedure chkMetronomeChange(Sender: TObject);
procedure chkLabelFlashingChange(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormResize(Sender: TObject);
procedure tmrAnimatedCadenceTimer(Sender: TObject);
private
{ private declarations }
AnimationQueue: TAnimationQueue;
FDropDownExpandedHeight: Integer;
FAnimateTri1: TAnimationControlTranslate;
FAnimateTri2: TAnimationControlTranslate;
procedure DropPanelEndAnimationCollapse(Sender: TAnimationItem);
procedure MetronomeEndAnimation(Sender: TAnimationItem);
public
{ public declarations }
end;
{ TAnimationSampleBrushColor }
TAnimationSampleBrushColor=class(TAnimationCustomControlColor)
protected
procedure DoChangeColor(const aNewColor: integer); override;
public
property InitialColor;
property FinalColor;
property TransitionMode;
end;
var
frmAnimationControls: TfrmAnimationControls;
implementation
{$R *.lfm}
{ TAnimationSampleBrushColor }
procedure TAnimationSampleBrushColor.DoChangeColor(const aNewColor: integer);
begin
// Brush color instead Control.Color
(Self.FControl as TShape).Brush.Color:=aNewColor;
end;
{ TfrmAnimationControls }
procedure TfrmAnimationControls.butBounceCaptionClick(Sender: TObject);
var
Ef: TAnimationControlCaptionCapital;
begin
AnimationQueue.RemoveGroupID(butBounceCaption);
Ef:=TAnimationControlCaptionCapital.Create(butBounceCaption);
{$PUSH}{$HINTS OFF} // Hide hint about use int64
Ef.Duration:=50*Length(butBounceCaption.Caption);
{$POP}
ef.Repeats:=2;
ef.AutoReverse:=true;
ef.TransitionMode:=eAnimationTransitionBallisticBoth;
EF.AnimationOnEndAction:=eAnimationOnEndFree;
AnimationQueue.Add(Ef);
EF.Start;
end;
procedure TfrmAnimationControls.butAlphaBlendClick(Sender: TObject);
var
lAlphaBlend: TAnimationControlAlphaBlend;
begin
AnimationQueue.RemoveGroupID(Self);
lAlphaBlend:=TAnimationControlAlphaBlend.Create(Self);
lAlphaBlend.AnimationOnEndAction:=TAnimationOnEndAction.eAnimationOnEndFree;
lAlphaBlend.Duration:=1000;
lAlphaBlend.Repeats:=2;
lAlphaBlend.AutoReverse:=true;
lAlphaBlend.TransitionMode:=TAnimationTransitionMode.eAnimationTransitionLinear;
lAlphaBlend.InitialBlend:=255;
lAlphaBlend.FinalBlend:=0;
lAlphaBlend.FinalizeBehavior:=eAnimationFinalizeBehaviorInitial;
AnimationQueue.Add(lAlphaBlend);
lAlphaBlend.Start;
end;
procedure TfrmAnimationControls.BitBtn1Click(Sender: TObject);
(* Still not working
var
lAnimBitmap: TAnimationControlBitBtnPicture;
*)
begin
(* Still not working
AnimationQueue.RemoveGroupID(BitBtn1);
lAnimBitmap:=TAnimationControlBitBtnPicture.Create(BitBtn1);
lAnimBitmap.AnimationOnEndAction:=TAnimationOnEndAction.eAnimationOnEndFree;
lAnimBitmap.Duration:=2000;
lAnimBitmap.Repeats:=1;
lAnimBitmap.InitialAngle:=0;
lAnimBitmap.FinalAngle:=360;
AnimationQueue.Add(lAnimBitmap);
lAnimBitmap.Start;
*)
end;
procedure TfrmAnimationControls.butDropDownClick(Sender: TObject);
var
lDropAnimation: TAnimationControlZoom;
lDropRotate: TAnimationControlFontRotator;
lDropText: TAnimationControlCaptionReplace;
lFinalRect: TRect;
lList: TFPList;
procedure ReverseList(aList: TFPList);
var
j: integer;
begin
for j := 0 to Pred(aList.Count) do begin
if not TAnimationItem(lList[j]).Reverse then begin
//writeln('Can''t reverse now');
end;
end;
end;
begin
lList:=AnimationQueue.FindGroupID(pnlDropDown);
try
if lList.Count>0 then begin
// Reverse all the related controls
ReverseList(lList);
lList.Free;
lList:=AnimationQueue.FindGroupID(lbSampleEntries);
ReverseList(lList);
lList.Free;
lList:=AnimationQueue.FindGroupID(lblDropDownMessage);
ReverseList(lList);
end else begin
AnimationQueue.RemoveGroupID(pnlDropDown);
AnimationQueue.RemoveGroupID(lbSampleEntries);
AnimationQueue.RemoveGroupID(lblDropDownMessage);
lDropAnimation:=TAnimationControlZoom.Create(pnlDropDown);
lDropAnimation.AnimationOnEndAction:=TAnimationOnEndAction.eAnimationOnEndFree;
lDropAnimation.Duration:=500;
lDropAnimation.Repeats:=1;
lDropAnimation.TransitionMode:=TAnimationTransitionMode.eAnimationTransitionBallisticBoth;
lDropRotate:=TAnimationControlFontRotator.Create(lbSampleEntries);
lDropRotate.AnimationOnEndAction:=TAnimationOnEndAction.eAnimationOnEndFree;
lDropRotate.Duration:=lDropAnimation.Duration;
lDropRotate.Repeats:=lDropAnimation.Repeats;
lDropRotate.TransitionMode:=TAnimationTransitionMode.eAnimationTransitionLinear;
lDropText:=TAnimationControlCaptionReplace.Create(lblDropDownMessage);
lDropText.AnimationOnEndAction:=TAnimationOnEndAction.eAnimationOnEndFree;
lDropText.Duration:=lDropAnimation.Duration;
lDropText.Repeats:=lDropAnimation.Repeats;
lDropText.TransitionMode:=TAnimationTransitionMode.eAnimationTransitionLinear;
if butDropDown.Tag=0 then begin
//writeln('Collapse');
// DropDown panel is expanded
// Store current height to recover when expand
if FDropDownExpandedHeight=0 then begin
FDropDownExpandedHeight:=pnlDropDown.Height;
end;
butDropDown.Caption:='_';
lFinalRect:=pnlDropDown.BoundsRect;
lFinalRect.Bottom:=pnlDropDownHeader.Height+pnlDropDown.Top;
lDropAnimation.SetFinalSize(lFinalRect);
lDropAnimation.OnAnimationEnd:=@DropPanelEndAnimationCollapse;
lDropRotate.InitialAngle:=0;
lDropRotate.FinalAngle:=90;
lDropText.FinalText:='Now press the button again to expand the panel.';
end else begin
//writeln('Expand');
butDropDown.Caption:='^';
lFinalRect:=pnlDropDown.BoundsRect;
lFinalRect.Bottom:=FDropDownExpandedHeight+pnlDropDown.Top;
lDropAnimation.SetFinalSize(lFinalRect);
lDropAnimation.OnAnimationEnd:=@DropPanelEndAnimationCollapse;
lDropRotate.InitialAngle:=90;
lDropRotate.FinalAngle:=0;
pnlDropDownContents.Enabled:=true;
lDropText.FinalText:='Press the button to collapse the panel below.';
end;
AnimationQueue.Add(lDropAnimation);
AnimationQueue.Add(lDropRotate);
AnimationQueue.Add(lDropText);
lDropAnimation.Start;
lDropRotate.Start;
lDropText.Start;
end;
finally
lList.Free;
end;
end;
procedure TfrmAnimationControls.DropPanelEndAnimationCollapse(
Sender: TAnimationItem);
begin
// Disable contents so controls will not be reached by tabstop even when
// its visual size is zero.
if Sender.Reversed then begin
if butDropDown.Tag=1 then begin
// Reversed expansion, disable again
//writeln('End reversed expand');
pnlDropDownContents.Enabled:=false;
end else begin
// Reversed collapse, do nothing
//writeln('End reversed collapse');
end;
end else begin
if butDropDown.Tag=1 then begin
// Finished expansion
//writeln('End expand');
butDropDown.Tag:=0;
end else begin
// Finished collapse
//writeln('End collapse');
butDropDown.Tag:=1;
pnlDropDownContents.Enabled:=false;
end;
end;
end;
procedure TfrmAnimationControls.butReverseClick(Sender: TObject);
begin
AnimationQueue.Reversed:=not AnimationQueue.Reversed;
end;
procedure TfrmAnimationControls.butPauseClick(Sender: TObject);
begin
AnimationQueue.Paused:=not AnimationQueue.Paused;
end;
procedure TfrmAnimationControls.butSlidingClick(Sender: TObject);
var
Button: TAnimationControlTranslate;
Zoom: TAnimationControlZoom;
lList: TFPList;
begin
lList:=AnimationQueue.FindGroupID(butSliding);
try
if lList.Count>0 then begin
// Do not start new animation until current finish.
exit;
end;
Button:=TAnimationControlTranslate.Create(butSliding);
Button.Duration:=1500;
Button.Repeats:=4;
Button.AnimationOnEndAction:=eAnimationOnEndFree;
Button.AutoReverse:=true;
Button.SetFinalPosition(Point(shpSliding.Left+shpSliding.Width-butSliding.Width,butSliding.Top));
Button.AnchorLocation:=eAnimationAnchorLocationLeft;
Button.FreeWithQueue:=true;
Button.TransitionMode:=eAnimationTransitionBallisticBoth;
Button.FinalizeBehavior:=eAnimationFinalizeBehaviorInitial;
AnimationQueue.Add(Button);
Zoom:=TAnimationControlZoom.Create(butSliding);
Zoom.Duration:=750;
Zoom.Repeats:=2;
Zoom.AutoReverse:=true;
Zoom.AnimationOnEndAction:=eAnimationOnEndFree;
Zoom.SetFinalZoom(0.1);
Zoom.FreeWithQueue:=true;
Zoom.ZoomMode:=eAnimationZoomModeHeightBottom;
Zoom.FinalizeBehavior:=eAnimationFinalizeBehaviorInitial;
Zoom.RemoveAnchors:=true;
Button.AddSyncStartStopAnimation(Zoom); //Synchronize restart/reverse action for Zoom when button restarts.
//This can cause problems with Repeats counter
AnimationQueue.Add(Zoom);
Button.Start;
Zoom.Start;
finally
lList.Free;
end;
end;
procedure TfrmAnimationControls.butZoomTestClick(Sender: TObject);
var
butAnim: TAnimationControlZoom;
begin
// All animation references to butZoomTest must be removed
// before as in the creation process we capture the current
// dimensions. Removing ID before creation of new animation
// first finalizes control and then captures original dimensions.
// If not done this way starting butZoomTest dimensions will be
// the current Zoom factor which is almost always small.
AnimationQueue.RemoveGroupID(butZoomTest);
butAnim:=TAnimationControlZoom.Create(butZoomTest);
butAnim.SetFinalZoom(0.25);
butAnim.ZoomMode:=TAnimationZoomMode.eAnimationZoomModeAll;
butAnim.TransitionMode:=TAnimationTransitionMode.eAnimationTransitionLinear;
butAnim.AutoReverse:=true;
butAnim.Repeats:=2;
butAnim.AnimationOnEndAction:=TAnimationOnEndAction.eAnimationOnEndFree;
butAnim.Duration:=100;
butAnim.GroupID:=butZoomTest;
AnimationQueue.Add(butAnim,true);
butAnim.Start;
end;
procedure TfrmAnimationControls.CheckBox1Change(Sender: TObject);
var
CheckboxAnim: TAnimationControlZoom;
LightAnim: TAnimationControlColor;
begin
AnimationQueue.RemoveGroupID(CheckBox1);
CheckboxAnim:=TAnimationControlZoom.Create(CheckBox1);
CheckboxAnim.SetFinalZoom(0.25);
CheckboxAnim.ZoomMode:=TAnimationZoomMode.eAnimationZoomModeWidthLeft;
CheckboxAnim.TransitionMode:=TAnimationTransitionMode.eAnimationTransitionLinear;
CheckboxAnim.AutoReverse:=true;
CheckboxAnim.Repeats:=2;
CheckboxAnim.AnimationOnEndAction:=TAnimationOnEndAction.eAnimationOnEndFree;
CheckboxAnim.Duration:=250;
AnimationQueue.Add(CheckboxAnim,true);
CheckboxAnim.Start;
LightAnim:=TAnimationControlColor.Create(pnlCheckbox);
LightAnim.InitialColor:=ColorToRGB(clBtnFace);
LightAnim.FinalColor:=$00FF00;
LightAnim.TransitionMode:=TAnimationTransitionMode.eAnimationTransitionBallisticOut;
LightAnim.AutoReverse:=true;
LightAnim.Repeats:=2;
LightAnim.AnimationOnEndAction:=TAnimationOnEndAction.eAnimationOnEndFree;
LightAnim.Duration:=150;
LightAnim.FinalizeBehavior:=eAnimationFinalizeBehaviorInitial;
AnimationQueue.Add(LightAnim);
LightAnim.Start;
end;
procedure TfrmAnimationControls.chkMarqueeChange(Sender: TObject);
var
lMarqueeBackground: TAnimationControlTranslate;
lList: TFPList;
begin
lList:=AnimationQueue.FindGroupID(imgFlareMarquee);
try
if lList.Count=0 then exit;
lMarqueeBackground:=TObject(lList[0]) as TAnimationControlTranslate;
if chkMarquee.Checked then begin
if lMarqueeBackground.State=eAnimationStatePaused then begin
lMarqueeBackground.Pause;
end else begin
lMarqueeBackground.Start;
end;
end else begin
lMarqueeBackground.Pause;
end;
finally
lList.Free;
end;
end;
procedure TfrmAnimationControls.chkMetronomeChange(Sender: TObject);
var
TriangleColor1,TriangleColor2: TAnimationSampleBrushColor;
begin
if not chkMetronome.Checked then begin
AnimationQueue.RemoveGroupID(shpTri1);
AnimationQueue.RemoveGroupID(shpTri2);
end else begin
FAnimateTri1:=TAnimationControlTranslate.Create(shpTri1);
FAnimateTri1.Duration:=1000;
FAnimateTri1.AnimationOnEndAction:=eAnimationOnEndStop;
FAnimateTri1.AutoReverse:=true;
FAnimateTri1.Repeats:=2;
FAnimateTri1.SetInitialPosition(Point((Self.Width div 2)-shpTri1.Width,shpTri1.Top));
FAnimateTri1.SetFinalPosition(Point(0,shpTri1.Top));
FAnimateTri1.FreeWithQueue:=true;
FAnimateTri1.TransitionMode:=eAnimationTransitionBallisticIn;
FAnimateTri1.FinalizeBehavior:=eAnimationFinalizeBehaviorInitial;
FAnimateTri1.OnAnimationEnd:=@MetronomeEndAnimation;
AnimationQueue.Add(FAnimateTri1);
TriangleColor1:=TAnimationSampleBrushColor.Create(shpTri1);
TriangleColor1.Duration:=2000;
TriangleColor1.AnimationOnEndAction:=eAnimationOnEndStop;
TriangleColor1.AutoReverse:=false;
TriangleColor1.Repeats:=1;
TriangleColor1.InitialColor:=ColorToRGB(clRed);
TriangleColor1.FinalColor:=ColorToRGB(clWhite);
TriangleColor1.FreeWithQueue:=true;
TriangleColor1.TransitionMode:=eAnimationTransitionBallisticOut;
AnimationQueue.Add(TriangleColor1);
FAnimateTri2:=TAnimationControlTranslate.Create(shpTri2);
FAnimateTri2.Duration:=1000;
FAnimateTri2.AnimationOnEndAction:=eAnimationOnEndStop;
FAnimateTri2.AutoReverse:=true;
FAnimateTri2.Repeats:=2;
FAnimateTri2.SetInitialPosition(Point((Self.Width div 2),shpTri2.Top));
FAnimateTri2.SetFinalPosition(Point(Self.Width-shpTri2.Width,shpTri2.Top));
FAnimateTri2.FreeWithQueue:=true;
FAnimateTri2.TransitionMode:=eAnimationTransitionBallisticIn;
FAnimateTri2.FinalizeBehavior:=eAnimationFinalizeBehaviorInitial;
FAnimateTri2.OnAnimationEnd:=@MetronomeEndAnimation;
AnimationQueue.Add(FAnimateTri2);
TriangleColor2:=TAnimationSampleBrushColor.Create(shpTri2);
TriangleColor2.Duration:=2000;
TriangleColor2.AnimationOnEndAction:=eAnimationOnEndStop;
TriangleColor2.AutoReverse:=false;
TriangleColor2.Repeats:=1;
TriangleColor2.InitialColor:=ColorToRGB(clRed);
TriangleColor2.FinalColor:=ColorToRGB(clWhite);
TriangleColor2.FreeWithQueue:=true;
TriangleColor2.TransitionMode:=eAnimationTransitionBallisticOut;
AnimationQueue.Add(TriangleColor2);
TriangleColor1.Start;
FAnimateTri1.Start;
end;
end;
procedure TfrmAnimationControls.chkLabelFlashingChange(Sender: TObject);
var
lFlashing: TAnimationControlColor;
lList: TFPList;
begin
if TCheckBox(Sender).Checked then begin
AnimationQueue.RemoveGroupID(lblFlashingLabel);
lFlashing:=TAnimationControlColor.Create(lblFlashingLabel);
lFlashing.Duration:=1000;
lFlashing.InitialColor:=ColorToRGB(clBtnFace);
lFlashing.FinalColor:=ColorToRGB(TColor($000000FF));
lFlashing.AutoReverse:=true;
lFlashing.Repeats:=0; // infinite
lFlashing.FinalizeBehavior:=eAnimationFinalizeBehaviorInitial;
AnimationQueue.Add(lFlashing);
lFlashing.Start;
end else begin
lList:=AnimationQueue.FindGroupID(lblFlashingLabel);
try
if lList.Count>0 then begin
lFlashing:=TObject(lList[0]) as TAnimationControlColor;
lFlashing.FinalizeASAP(true);
end;
finally
lList.Free;
end;
end;
end;
procedure TfrmAnimationControls.FormCreate(Sender: TObject);
var
Button: TAnimationControlTranslate;
MarqueeBackground: TAnimationControlTranslate;
begin
AnimationQueue:=TAnimationQueue.Create;
Button:=TAnimationControlTranslate.Create(butPause);
Button.Duration:=2000;
Button.AnimationOnEndAction:=eAnimationOnEndFree;
Button.AutoReverse:=false;
Button.Repeats:=1;
Button.SetFinalPosition(Point(0,butPause.Top));
Button.AnchorLocation:=eAnimationAnchorLocationCenter;
Button.SwapOriginWithFinal;
Button.FreeWithQueue:=true;
Button.TransitionMode:=eAnimationTransitionBallisticIn;
AnimationQueue.Add(Button);
AnimationQueue.Start(true);
MarqueeBackground:=TAnimationControlTranslate.Create(imgFlareMarquee);
MarqueeBackground.Duration:=Trunc(imgFlareMarquee.Parent.Width*10);
MarqueeBackground.AnimationOnEndAction:=eAnimationOnEndFree;
MarqueeBackground.AutoReverse:=false;
MarqueeBackground.Repeats:=0;
MarqueeBackground.SetInitialPosition(Point(imgFlareMarquee.Width*-1,0));
MarqueeBackground.SetFinalPosition(Point(imgFlareMarquee.Parent.Width,0));
MarqueeBackground.AnchorLocation:=eAnimationAnchorLocationCenter;
MarqueeBackground.FreeWithQueue:=true;
MarqueeBackground.TransitionMode:=eAnimationTransitionLinear;
AnimationQueue.Add(MarqueeBackground);
MarqueeBackground.Stop;
end;
procedure TfrmAnimationControls.FormDestroy(Sender: TObject);
begin
FreeAndNil(AnimationQueue);
end;
procedure TfrmAnimationControls.FormResize(Sender: TObject);
var
lAnimations: TFPList;
lFlareAnimation: TAnimationControlTranslate;
begin
// Find the animation related to imgFlareMarquee
lAnimations:=AnimationQueue.FindGroupID(imgFlareMarquee);
try
if lAnimations.Count=0 then begin
// Not found ? Exit
exit;
end;
try
lFlareAnimation:=TObject(lAnimations[0]) as TAnimationControlTranslate;
// Now readjust final position and animation duration
// Changing duration we get a constant speed, but better is constant time in this case.
//lFlareAnimation.Duration:=Trunc(lFlareAnimation.Control.Parent.Width*10);
lFlareAnimation.SetFinalPosition(Point(lFlareAnimation.Control.Parent.Width,lFlareAnimation.Control.Top));
except
// Eat exceptions, so program will not break if something
// goes really wrong.
end;
finally
lAnimations.Free;
end;
end;
procedure TfrmAnimationControls.MetronomeEndAnimation(Sender: TAnimationItem);
var
lList: TFPList=nil;
j: integer;
A: TAnimationItem;
begin
try
if Sender=FAnimateTri1 then begin
lList:=AnimationQueue.FindGroupID(shpTri2);
end else begin
lList:=AnimationQueue.FindGroupID(shpTri1);
end;
for j := 0 to Pred(lList.Count) do begin
A:=TAnimationItem(lList[j]);
A.Start;
end;
finally
lList.Free;
end;
end;
procedure TfrmAnimationControls.tmrAnimatedCadenceTimer(Sender: TObject);
begin
Self.DisableAlign;
AnimationQueue.Animate;
Self.EnableAlign;
// Adding Self.Invalidate improves smooth animation but can make
// the form less responsive in low power machines.
// When used removes some animation artifacts in controls translation.
//Self.Invalidate;
lblFPS.Caption:=format('FPS: %.2f',[AnimationQueue.AverageFPS]);
end;
end.