Accueil > > > BARRE DE PROGRESSION À LA CLEARLOOKS
BARRE DE PROGRESSION À LA CLEARLOOKS
Information sur la source
Description
Voici un composant basé sur la librairie Graphics32 qui permet d'être utilisé en tant que barre de progression animée. Une option "marquee" permet de rendre son état indéterminé. Pour compiler la source, il vous faut les librairies: Graphics32 : http://graphics32.org/wiki/ The GR32 Extension Components Pack : http://code.google.com/p/gr32ex/ Pour tester l'exemple, renommer le fichier "Exemple.exec" en "Exemple.exe" (merci Nicolas)
Source
- unit GrProgressBar;
-
- (* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is GrProgressBar
- *
- * The Initial Developer of the Original Code is
- * Yann Papouin <yann.papouin at @ gmail.com>
- *
- * ***** END LICENSE BLOCK ***** *)
-
- { $DEFINE DEBUG}
-
- interface
-
- uses
- {$IfDef DEBUG}DbugIntf,{$ENDIF}
- Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Math,
- GR32, GR32_Image, GR32_Polygons, SimpleTimer;
-
- type
- TBarDirection = (
- bdRight,
- bdLeft
- );
-
- TGrProgressbar = class(TCustomImage32)
- private
- FModulo : integer;
- FInvalidateColor : boolean;
- FApplyingSystemColor: boolean;
- FColor1 : TColor32;
- FColor2 : TColor32;
- FBarDirection : TBarDirection;
- FLimitRight : integer;
- FLimitLeft : integer;
- FBar : TPolygon32;
- FAniTimer: TSimpleTimer;
- FInvalidatePattern : boolean;
- FFiller: TBitmapPolygonFiller;
- FUseSystemColors: boolean;
- FAnimated: boolean;
- FMax: integer;
- FMin: integer;
- FPosition: integer;
- FMarquee: boolean;
- FMarqueeWidth: single;
- FMarqueeSpeed: integer;
- FColor: TColor;
- FAnimAtMax: boolean;
- FFlip: boolean;
- procedure SetUseSystemColors(const Value: boolean);
- procedure SetAnimated(const Value: boolean);
- { Déclarations privées }
- procedure ComputePattern;
- procedure InvalidatePattern;
- procedure SetMax(const Value: integer);
- procedure SetMin(const Value: integer);
- procedure SetPosition(Value: integer);
- procedure DoAniTimer(Sender: TObject);
- procedure SetInterval(const Value: Cardinal);
- function GetInterval: Cardinal;
- procedure SetMarquee(const Value: boolean);
- procedure SetMarqueeWidth(Value: single);
- procedure SetMarqueeSpeed(const Value: integer);
- procedure SetColor(const Value: TColor);
- procedure SetAnimAtMax(const Value: boolean);
- procedure SetFlip(const Value: boolean);
- protected
- procedure BuildBar;
- procedure Resize; override;
- procedure DoPaintBuffer; override;
- function InternalPaintBuffer(aBitmap32: TBitmap32): Boolean;
- procedure DrawBackground(aBitmap32: TBitmap32);
- procedure CMStyleChanged( var msg: TMessage); message WM_THEMECHANGED;
- procedure CMShowingChanged(var msg: TMessage); message CM_SHOWINGCHANGED;
- public
- { Déclarations publiques }
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- procedure Loaded; override;
- published
- property Align;
- property AlignWithMargins;
- property Anchors;
- property Margins;
- property AnimAtMax : boolean read FAnimAtMax write SetAnimAtMax;
- property Animated : boolean read FAnimated write SetAnimated;
- property Interval : Cardinal read GetInterval write SetInterval;
- property UseSystemColors : boolean read FUseSystemColors write SetUseSystemColors;
- property Max : integer read FMax write SetMax;
- property Min : integer read FMin write SetMin;
- property Position : integer read FPosition write SetPosition;
- property Marquee : boolean read FMarquee write SetMarquee;
- property MarqueeWidth : single read FMarqueeWidth write SetMarqueeWidth;
- property MarqueeSpeed : integer read FMarqueeSpeed write SetMarqueeSpeed;
- property Color : TColor read FColor write SetColor;
- property Flip : boolean read FFlip write SetFlip;
- end;
-
-
- procedure Register;
-
- implementation
-
- uses
- Themes, UxTheme;
-
- var
- SystemColor : TColor;
-
- procedure Register;
- begin
- RegisterComponents('GLDali', [TGrProgressbar]);
- end;
-
-
- function Linearize(Ax, Ay, Bx, By, Value : Single): Single;
- begin
- if (Bx <> Ax) and (Ay <> By) then
- result := Ay + (Value - Ax) / (Bx - Ax) * (By-Ay)
- else
- result := 0;
- end;
-
-
- { TGrProgressbar }
-
- constructor TGrProgressbar.Create(AOwner: TComponent);
- begin
- inherited;
-
- Height := 15;
- Width := 150;
-
- FFlip := true;
- FModulo := Height;
- FMin := 0;
- FMax := 100;
- FMarqueeWidth := 0.25;
- FMarqueeSpeed := 5;
- FBar := TPolygon32.Create;
-
- FAniTimer := TSimpleTimer.CreateEx(50, DoAniTimer);
- FFiller := TBitmapPolygonFiller.Create;
-
- ControlStyle := [csAcceptsControls, csCaptureMouse, csClickEvents,
- csSetCaption, csParentBackground, csDoubleClicks, csReplicatable, csPannable];
-
- //Color := clHighlight;
- Animated := true;
- end;
-
- destructor TGrProgressbar.Destroy;
- begin
- FAniTimer.Free;
- FFiller.Free;
- FBar.Free;
- inherited;
- end;
-
- procedure TGrProgressbar.Loaded;
- begin
- inherited Loaded;
- Buffer.SetSize(Width,Height);
- BuildBar;
- InvalidatePattern;
- {$IfDef DEBUG}SendDebugFmt('Progress bar named %s loaded',[Name]);{$ENDIF}
- end;
-
-
- procedure TGrProgressbar.InvalidatePattern;
- begin
- FInvalidatePattern := true;
- Changed;
- end;
-
-
- // The pattern is computed only once
- // It need to be recomputed after a resize of the control or a color (theme) change
- procedure TGrProgressbar.ComputePattern;
- var
- Polygon : TPolygon32;
- PatternWidth : integer;
- PatternHeight : integer;
- begin
- PatternHeight := Height;
- PatternWidth := PatternHeight*2;
- FModulo := PatternWidth;
-
- if Assigned(FFiller.Pattern) then
- FFiller.Pattern.Free;
-
- // First create a rectangle with the wanted color
- FFiller.Pattern := TBitmap32.Create;
- FFiller.Pattern.SetSize(PatternWidth,PatternHeight);
- FFiller.Pattern.FillRectTS(0,0,PatternWidth,PatternHeight, FColor1);
-
- PatternHeight := PatternHeight;
-
- Polygon := TPolygon32.Create;
-
- // Next draw a transparent parallelogram (a rectangle that is skewed)
- with Polygon do
- begin
- Antialiased := true;
- Add(FixedPoint(0,0));
- Add(FixedPoint(PatternWidth div 2,0));
- Add(FixedPoint(PatternWidth, PatternHeight));
- Add(FixedPoint(PatternWidth div 2, PatternHeight));
- DrawFill(FFiller.Pattern, SetAlpha(FColor2,127));
-
- // Mirror operation on vertical axis if needed
- if Flip then
- FFiller.Pattern.FlipHorz(FFiller.Pattern);
- end;
- Polygon.Free;
-
- // Finally draw a crystal effect
- FFiller.Pattern.FillRectTS(0, 0, PatternWidth, PatternHeight div 2, SetAlpha(CLWhite32,60));
- end;
-
-
- procedure TGrProgressbar.BuildBar;
- var
- LPosition : integer;
- Offset : integer;
- Inflate : integer;
- DrawRect : TRect;
- begin
-
- if not Assigned(Parent) then
- Exit;
-
- // Inflate value help to reduce the bar size from it's background
- Inflate := -3;
-
- // An offset is here to correct the 3D effect
- Offset := -1;
-
- // Get X coordinate from the Min, Max and Position Values
- if not Marquee then
- begin
- LPosition := Round(Linearize(Min, -2* Inflate + Offset, Max, Width, Position));
- {$IfDef DEBUG}SendInteger('LPosition',LPosition);{$ENDIF}
- end;
-
- DrawRect := ClientRect;
-
- // Limits are used by the marquee animation
- FLimitRight := DrawRect.Right + Inflate;
- FLimitLeft := DrawRect.Left - Inflate + Offset;
-
- if not Marquee then
- DrawRect.Right := LPosition
- else
- DrawRect.Right := Round(DrawRect.Right*MarqueeWidth); // setting the marquee width by using it's percent value
-
- // Apply the offset
- DrawRect.Top := DrawRect.Top + Offset;
- DrawRect.Left := DrawRect.Left + Offset;
-
- InflateRect(DrawRect, Inflate, Inflate);
-
- {$IfDef DEBUG}SendInteger('DrawRect.Left',DrawRect.Left);{$ENDIF}
- {$IfDef DEBUG}SendInteger('DrawRect.Right',DrawRect.Right);{$ENDIF}
-
- // Drawing the bar polygon
- with FBar do
- begin
- Clear;
- if DrawRect.Left <> DrawRect.Right then
- begin
- Add(FixedPoint(DrawRect.Left,DrawRect.Top));
- Add(FixedPoint(DrawRect.Right,DrawRect.Top));
- Add(FixedPoint(DrawRect.Right,DrawRect.Bottom));
- Add(FixedPoint(DrawRect.Left,DrawRect.Bottom));
- end;
- end;
- end;
-
- procedure TGrProgressbar.DrawBackground(aBitmap32: TBitmap32);
- var
- R: TRect;
- cl: TColor;
- FProgressThemeData : HTHEME;
- begin
-
- if UseThemes then
- begin
- // Apply the WinXP style
- FProgressThemeData := OpenThemeData(Handle, 'Progress');
- R := ClientRect;
- DrawThemeBackground(FProgressThemeData, aBitmap32.Handle, PP_BAR, 0, R, nil);
- end
- else
- begin
- // Mimic the Win2K style by drawing a lowered borders
- aBitmap32.RaiseRectTS(0,0,width,height,-50);
- end;
-
- end;
-
-
- function TGrProgressbar.InternalPaintBuffer(aBitmap32: TBitmap32): Boolean;
- var
- Polygon : TPolygon32;
- LPosition : integer;
- Inflate : integer;
- DrawRect : TRect;
- begin
-
- // Do not try to draw anything is there is no parent for self
- if not Assigned(Parent) then
- begin
- aBitmap32.Clear(clRed32);
- Exit;
- end;
-
- // Recalc color after a theme change
- if FInvalidateColor then
- begin
- UseSystemColors := UseSystemColors;
- FInvalidateColor := false;
- end;
-
- // Recalc pattern on resize or color change
- if FInvalidatePattern then
- begin
- FInvalidatePattern := false;
- ComputePattern;
- end;
-
- // Draw the control background (themed if we can)
- DrawBackground(aBitmap32);
-
- // Draw the bar itself by using the pattern
- if ((Position > 0) and not Marquee) or Marquee then
- begin
- with FBar do
- begin
- // The pattern is automatically repeated on x-axis and y-axis
- DrawFill(aBitmap32, FFiller);
- DrawEdge(aBitmap32, SetAlpha(clBlack32, 100));
- end;
- end;
-
- result := true;
- end;
-
- procedure TGrProgressbar.DoPaintBuffer;
- begin
- inherited;
- InternalPaintBuffer(self.Buffer);
- end;
-
- // Recompute bar size and pattern size
- procedure TGrProgressbar.Resize;
- begin
- inherited;
- BuildBar;
- InvalidatePattern;
- end;
-
- procedure TGrProgressbar.DoAniTimer(Sender: TObject);
- begin
- if not FMarquee then
- begin
- if not ((Position = Max) and not FAnimAtMax) then
- begin
- // Animate pattern of the bar with a scroll
- FFiller.OffsetX := (FFiller.OffsetX-1) mod FModulo;
- end;
- end
- else
- if FMarquee then
- begin
- // Changing direction from right to left
- if (FBar.Points[0][1].X >= Fixed(FLimitRight)) and (FBarDirection = bdRight) then
- begin
- FBarDirection := bdLeft;
- end;
-
- // Changing direction from left to right
- if (FBar.Points[0][0].X <= Fixed(FLimitLeft)) and (FBarDirection = bdLeft) then
- begin
- FBarDirection := bdRight;
- end;
-
- // Move the bar itself without moving the pattern
- case FBarDirection of
- bdRight :
- begin
- FBar.Offset(Fixed(FMarqueeSpeed), Fixed(0));
- end;
- bdLeft :
- begin
- FBar.Offset(Fixed(-FMarqueeSpeed), Fixed(0));
- end;
- end;
-
- end;
-
- // Repaint control
- Changed;
- end;
-
- // Boolean value to enable/disable animation
- procedure TGrProgressbar.SetAnimated(const Value: boolean);
- begin
- FAnimated := Value;
-
- if Visible then
- FAniTimer.Enabled := FAnimated;
-
- // Reset pattern position
- if not FAnimated then
- FFiller.OffsetX := 0;
- end;
-
- // Continue scrolling when Position = Max ?
- procedure TGrProgressbar.SetAnimAtMax(const Value: boolean);
- begin
- FAnimAtMax := Value;
- end;
-
- function TGrProgressbar.GetInterval: Cardinal;
- begin
- result := FAniTimer.Interval;
- end;
-
- procedure TGrProgressbar.SetInterval(const Value: Cardinal);
- begin
- FAniTimer.Interval := Value;
- end;
-
- // A marquee progress bar is a progress bar with unknow min, max and position values
- // It's a feedback to state to warn the user that a thing is currently doing something
- procedure TGrProgressbar.SetMarquee(const Value: boolean);
- begin
- if FMarquee <> Value then
- begin
- FMarquee := Value;
- if not FMarquee then
- begin
- Position := Min;
- end;
- end;
-
- BuildBar;
- end;
-
- // The marquee width is it's width in percentage of the bar width
- procedure TGrProgressbar.SetMarqueeWidth(Value: single);
- begin
- Value := Math.Min(1.0,Value);
- Value := Math.Max(0.0,Value);
- if FMarqueeWidth <> Value then
- begin
- FMarqueeWidth := Value;
-
- BuildBar;
- end;
- end;
-
- procedure TGrProgressbar.SetMarqueeSpeed(const Value: integer);
- begin
- if FMarqueeSpeed <> Value then
- begin
- FMarqueeSpeed := Value;
- FMarqueeSpeed := Math.Min(100,FMarqueeSpeed);
- FMarqueeSpeed := Math.Max(1,FMarqueeSpeed);
- end;
- end;
-
- procedure TGrProgressbar.SetMax(const Value: integer);
- begin
- if FMax <> Value then
- begin
- FMax := Value;
- BuildBar;
- end;
- Position := Position;
- end;
-
- procedure TGrProgressbar.SetMin(const Value: integer);
- begin
- if FMin <> Value then
- begin
- FMin := Value;
- BuildBar;
- end;
- Position := Position;
- end;
-
-
- procedure TGrProgressbar.SetPosition(Value: integer);
- begin
- // First, limit the setted value to min and max position
- Value := Math.Min(Max, Value);
- Value := Math.Max(Min, Value);
-
- // Disable marquee if we write a new position
- FMarquee := false;
-
- if FPosition <> Value then
- begin
- FPosition := Value;
- BuildBar;
- Changed;
- end;
- end;
-
- procedure TGrProgressbar.SetUseSystemColors(const Value: boolean);
- var
- ABmp : TBitmap;
- PickColor: TColor;
- FProgressThemeData : HTHEME;
- begin
- FUseSystemColors := Value;
-
- if FUseSystemColors then
- begin
- FApplyingSystemColor := true;
-
- // Check if Windows Themes are enabled
- if UseThemes then
- begin
-
- // A small way (not really clean) to get the color of a themed progress bar
- if (SystemColor = clNone) then
- begin
- {$IfDef DEBUG}SendDebug('SystemColor is None');{$ENDIF}
-
- // We create a local bitmap where we painting on it a themed progress bar
- ABmp := TBitmap.Create;
- ABmp.SetSize(16,16);
- FProgressThemeData := OpenThemeData(Handle, 'Progress');
- DrawThemeBackground(FProgressThemeData, ABmp.Canvas.Handle, PP_CHUNK, 0, ABmp.Canvas.ClipRect, nil);
- CloseThemeData(FProgressThemeData);
-
- // After painting, we pick the color at a logical position
- // Just hope that there is a valid color here
- PickColor := ABmp.Canvas.Pixels[2,2];
- if PickColor <> CLR_INVALID then
- begin
- SystemColor := PickColor;
- {$IfDef DEBUG}SendDebug('System color found, extracted from BITMAP');{$ENDIF}
- end
- else
- begin
- SystemColor := clHighlight;
- {$IfDef DEBUG}SendDebug('System color not found, using the Highlight one');{$ENDIF}
- end;
-
- ABmp.Free;
- end;
-
- Color := SystemColor;
- {$IfDef DEBUG}SendDebug('Using previous computed system color');{$ENDIF}
- end
- else
- begin
- // If theming is not enabled then use the default highlight color
- Color := clHighlight;
- {$IfDef DEBUG}SendDebug('No theme is used, default highlight color');{$ENDIF}
- end;
- FApplyingSystemColor := false;
- end;
-
- end;
-
-
-
- procedure TGrProgressbar.SetColor(const Value: TColor);
- var
- H,S,L : Byte;
- begin
- if FColor <> Value then
- begin
-
- // Disable system color only if SetColor is not called by the UseSystemColors method
- if not FApplyingSystemColor then
- UseSystemColors := false;
-
- FColor := Value;
-
- // Extracting the Wincolor to Hue, Saturation and Luminosity values
- FColor1 := Color32(FColor);
- RGBtoHSL(FColor1, H, S, L);
-
- // Small way to set the color of the slashes
- if Intensity(FColor1) > 160
- then
- FColor2 := clBlack32
- else
- FColor2 := clWhite32;
-
- // Redraw the pattern with new colors
- InvalidatePattern;
- end;
-
- end;
-
- // Property that allow the flippig of the slashes
- procedure TGrProgressbar.SetFlip(const Value: boolean);
- begin
- FFlip := Value;
- InvalidatePattern;
- end;
-
- /// Catched Windows messages
-
- // If the theme is changed by a new theme then invalidate the system color
- // It will be recomputed by the first progress bar with UseSystemColor property enabled
- procedure TGrProgressbar.CMStyleChanged(var msg: TMessage);
- begin
- {$IfDef DEBUG}SendDebug('TGrProgressbar.CMStyleChanged');{$ENDIF}
- // Update colors
- SystemColor := clNone;
- FInvalidateColor := true;
- end;
-
-
- // Stop the timer when this control is not visible, else re-enable it
- procedure TGrProgressbar.CMShowingChanged(var msg: TMessage);
- begin
- inherited;
- {$IfDef DEBUG}SendDebug('CMShowingChanged');{$ENDIF}
-
- if Showing then
- begin
- if Animated and not FAniTimer.Enabled then
- begin
- FAniTimer.Enabled := true;
- {$IfDef DEBUG}SendDebugFmt('Timer of %s started',[Name]);{$ENDIF}
- end;
- end
- else
- begin
- if Animated and FAniTimer.Enabled then
- begin
- FAniTimer.Enabled := false;
- {$IfDef DEBUG}SendDebugFmt('Timer of %s stopped',[Name]);{$ENDIF}
- end;
- end;
- end;
-
- initialization
- SystemColor := clNone;
-
- finalization
-
-
- end.
unit GrProgressBar;
(* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is GrProgressBar
*
* The Initial Developer of the Original Code is
* Yann Papouin <yann.papouin at @ gmail.com>
*
* ***** END LICENSE BLOCK ***** *)
{ $DEFINE DEBUG}
interface
uses
{$IfDef DEBUG}DbugIntf,{$ENDIF}
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Math,
GR32, GR32_Image, GR32_Polygons, SimpleTimer;
type
TBarDirection = (
bdRight,
bdLeft
);
TGrProgressbar = class(TCustomImage32)
private
FModulo : integer;
FInvalidateColor : boolean;
FApplyingSystemColor: boolean;
FColor1 : TColor32;
FColor2 : TColor32;
FBarDirection : TBarDirection;
FLimitRight : integer;
FLimitLeft : integer;
FBar : TPolygon32;
FAniTimer: TSimpleTimer;
FInvalidatePattern : boolean;
FFiller: TBitmapPolygonFiller;
FUseSystemColors: boolean;
FAnimated: boolean;
FMax: integer;
FMin: integer;
FPosition: integer;
FMarquee: boolean;
FMarqueeWidth: single;
FMarqueeSpeed: integer;
FColor: TColor;
FAnimAtMax: boolean;
FFlip: boolean;
procedure SetUseSystemColors(const Value: boolean);
procedure SetAnimated(const Value: boolean);
{ Déclarations privées }
procedure ComputePattern;
procedure InvalidatePattern;
procedure SetMax(const Value: integer);
procedure SetMin(const Value: integer);
procedure SetPosition(Value: integer);
procedure DoAniTimer(Sender: TObject);
procedure SetInterval(const Value: Cardinal);
function GetInterval: Cardinal;
procedure SetMarquee(const Value: boolean);
procedure SetMarqueeWidth(Value: single);
procedure SetMarqueeSpeed(const Value: integer);
procedure SetColor(const Value: TColor);
procedure SetAnimAtMax(const Value: boolean);
procedure SetFlip(const Value: boolean);
protected
procedure BuildBar;
procedure Resize; override;
procedure DoPaintBuffer; override;
function InternalPaintBuffer(aBitmap32: TBitmap32): Boolean;
procedure DrawBackground(aBitmap32: TBitmap32);
procedure CMStyleChanged( var msg: TMessage); message WM_THEMECHANGED;
procedure CMShowingChanged(var msg: TMessage); message CM_SHOWINGCHANGED;
public
{ Déclarations publiques }
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Loaded; override;
published
property Align;
property AlignWithMargins;
property Anchors;
property Margins;
property AnimAtMax : boolean read FAnimAtMax write SetAnimAtMax;
property Animated : boolean read FAnimated write SetAnimated;
property Interval : Cardinal read GetInterval write SetInterval;
property UseSystemColors : boolean read FUseSystemColors write SetUseSystemColors;
property Max : integer read FMax write SetMax;
property Min : integer read FMin write SetMin;
property Position : integer read FPosition write SetPosition;
property Marquee : boolean read FMarquee write SetMarquee;
property MarqueeWidth : single read FMarqueeWidth write SetMarqueeWidth;
property MarqueeSpeed : integer read FMarqueeSpeed write SetMarqueeSpeed;
property Color : TColor read FColor write SetColor;
property Flip : boolean read FFlip write SetFlip;
end;
procedure Register;
implementation
uses
Themes, UxTheme;
var
SystemColor : TColor;
procedure Register;
begin
RegisterComponents('GLDali', [TGrProgressbar]);
end;
function Linearize(Ax, Ay, Bx, By, Value : Single): Single;
begin
if (Bx <> Ax) and (Ay <> By) then
result := Ay + (Value - Ax) / (Bx - Ax) * (By-Ay)
else
result := 0;
end;
{ TGrProgressbar }
constructor TGrProgressbar.Create(AOwner: TComponent);
begin
inherited;
Height := 15;
Width := 150;
FFlip := true;
FModulo := Height;
FMin := 0;
FMax := 100;
FMarqueeWidth := 0.25;
FMarqueeSpeed := 5;
FBar := TPolygon32.Create;
FAniTimer := TSimpleTimer.CreateEx(50, DoAniTimer);
FFiller := TBitmapPolygonFiller.Create;
ControlStyle := [csAcceptsControls, csCaptureMouse, csClickEvents,
csSetCaption, csParentBackground, csDoubleClicks, csReplicatable, csPannable];
//Color := clHighlight;
Animated := true;
end;
destructor TGrProgressbar.Destroy;
begin
FAniTimer.Free;
FFiller.Free;
FBar.Free;
inherited;
end;
procedure TGrProgressbar.Loaded;
begin
inherited Loaded;
Buffer.SetSize(Width,Height);
BuildBar;
InvalidatePattern;
{$IfDef DEBUG}SendDebugFmt('Progress bar named %s loaded',[Name]);{$ENDIF}
end;
procedure TGrProgressbar.InvalidatePattern;
begin
FInvalidatePattern := true;
Changed;
end;
// The pattern is computed only once
// It need to be recomputed after a resize of the control or a color (theme) change
procedure TGrProgressbar.ComputePattern;
var
Polygon : TPolygon32;
PatternWidth : integer;
PatternHeight : integer;
begin
PatternHeight := Height;
PatternWidth := PatternHeight*2;
FModulo := PatternWidth;
if Assigned(FFiller.Pattern) then
FFiller.Pattern.Free;
// First create a rectangle with the wanted color
FFiller.Pattern := TBitmap32.Create;
FFiller.Pattern.SetSize(PatternWidth,PatternHeight);
FFiller.Pattern.FillRectTS(0,0,PatternWidth,PatternHeight, FColor1);
PatternHeight := PatternHeight;
Polygon := TPolygon32.Create;
// Next draw a transparent parallelogram (a rectangle that is skewed)
with Polygon do
begin
Antialiased := true;
Add(FixedPoint(0,0));
Add(FixedPoint(PatternWidth div 2,0));
Add(FixedPoint(PatternWidth, PatternHeight));
Add(FixedPoint(PatternWidth div 2, PatternHeight));
DrawFill(FFiller.Pattern, SetAlpha(FColor2,127));
// Mirror operation on vertical axis if needed
if Flip then
FFiller.Pattern.FlipHorz(FFiller.Pattern);
end;
Polygon.Free;
// Finally draw a crystal effect
FFiller.Pattern.FillRectTS(0, 0, PatternWidth, PatternHeight div 2, SetAlpha(CLWhite32,60));
end;
procedure TGrProgressbar.BuildBar;
var
LPosition : integer;
Offset : integer;
Inflate : integer;
DrawRect : TRect;
begin
if not Assigned(Parent) then
Exit;
// Inflate value help to reduce the bar size from it's background
Inflate := -3;
// An offset is here to correct the 3D effect
Offset := -1;
// Get X coordinate from the Min, Max and Position Values
if not Marquee then
begin
LPosition := Round(Linearize(Min, -2* Inflate + Offset, Max, Width, Position));
{$IfDef DEBUG}SendInteger('LPosition',LPosition);{$ENDIF}
end;
DrawRect := ClientRect;
// Limits are used by the marquee animation
FLimitRight := DrawRect.Right + Inflate;
FLimitLeft := DrawRect.Left - Inflate + Offset;
if not Marquee then
DrawRect.Right := LPosition
else
DrawRect.Right := Round(DrawRect.Right*MarqueeWidth); // setting the marquee width by using it's percent value
// Apply the offset
DrawRect.Top := DrawRect.Top + Offset;
DrawRect.Left := DrawRect.Left + Offset;
InflateRect(DrawRect, Inflate, Inflate);
{$IfDef DEBUG}SendInteger('DrawRect.Left',DrawRect.Left);{$ENDIF}
{$IfDef DEBUG}SendInteger('DrawRect.Right',DrawRect.Right);{$ENDIF}
// Drawing the bar polygon
with FBar do
begin
Clear;
if DrawRect.Left <> DrawRect.Right then
begin
Add(FixedPoint(DrawRect.Left,DrawRect.Top));
Add(FixedPoint(DrawRect.Right,DrawRect.Top));
Add(FixedPoint(DrawRect.Right,DrawRect.Bottom));
Add(FixedPoint(DrawRect.Left,DrawRect.Bottom));
end;
end;
end;
procedure TGrProgressbar.DrawBackground(aBitmap32: TBitmap32);
var
R: TRect;
cl: TColor;
FProgressThemeData : HTHEME;
begin
if UseThemes then
begin
// Apply the WinXP style
FProgressThemeData := OpenThemeData(Handle, 'Progress');
R := ClientRect;
DrawThemeBackground(FProgressThemeData, aBitmap32.Handle, PP_BAR, 0, R, nil);
end
else
begin
// Mimic the Win2K style by drawing a lowered borders
aBitmap32.RaiseRectTS(0,0,width,height,-50);
end;
end;
function TGrProgressbar.InternalPaintBuffer(aBitmap32: TBitmap32): Boolean;
var
Polygon : TPolygon32;
LPosition : integer;
Inflate : integer;
DrawRect : TRect;
begin
// Do not try to draw anything is there is no parent for self
if not Assigned(Parent) then
begin
aBitmap32.Clear(clRed32);
Exit;
end;
// Recalc color after a theme change
if FInvalidateColor then
begin
UseSystemColors := UseSystemColors;
FInvalidateColor := false;
end;
// Recalc pattern on resize or color change
if FInvalidatePattern then
begin
FInvalidatePattern := false;
ComputePattern;
end;
// Draw the control background (themed if we can)
DrawBackground(aBitmap32);
// Draw the bar itself by using the pattern
if ((Position > 0) and not Marquee) or Marquee then
begin
with FBar do
begin
// The pattern is automatically repeated on x-axis and y-axis
DrawFill(aBitmap32, FFiller);
DrawEdge(aBitmap32, SetAlpha(clBlack32, 100));
end;
end;
result := true;
end;
procedure TGrProgressbar.DoPaintBuffer;
begin
inherited;
InternalPaintBuffer(self.Buffer);
end;
// Recompute bar size and pattern size
procedure TGrProgressbar.Resize;
begin
inherited;
BuildBar;
InvalidatePattern;
end;
procedure TGrProgressbar.DoAniTimer(Sender: TObject);
begin
if not FMarquee then
begin
if not ((Position = Max) and not FAnimAtMax) then
begin
// Animate pattern of the bar with a scroll
FFiller.OffsetX := (FFiller.OffsetX-1) mod FModulo;
end;
end
else
if FMarquee then
begin
// Changing direction from right to left
if (FBar.Points[0][1].X >= Fixed(FLimitRight)) and (FBarDirection = bdRight) then
begin
FBarDirection := bdLeft;
end;
// Changing direction from left to right
if (FBar.Points[0][0].X <= Fixed(FLimitLeft)) and (FBarDirection = bdLeft) then
begin
FBarDirection := bdRight;
end;
// Move the bar itself without moving the pattern
case FBarDirection of
bdRight :
begin
FBar.Offset(Fixed(FMarqueeSpeed), Fixed(0));
end;
bdLeft :
begin
FBar.Offset(Fixed(-FMarqueeSpeed), Fixed(0));
end;
end;
end;
// Repaint control
Changed;
end;
// Boolean value to enable/disable animation
procedure TGrProgressbar.SetAnimated(const Value: boolean);
begin
FAnimated := Value;
if Visible then
FAniTimer.Enabled := FAnimated;
// Reset pattern position
if not FAnimated then
FFiller.OffsetX := 0;
end;
// Continue scrolling when Position = Max ?
procedure TGrProgressbar.SetAnimAtMax(const Value: boolean);
begin
FAnimAtMax := Value;
end;
function TGrProgressbar.GetInterval: Cardinal;
begin
result := FAniTimer.Interval;
end;
procedure TGrProgressbar.SetInterval(const Value: Cardinal);
begin
FAniTimer.Interval := Value;
end;
// A marquee progress bar is a progress bar with unknow min, max and position values
// It's a feedback to state to warn the user that a thing is currently doing something
procedure TGrProgressbar.SetMarquee(const Value: boolean);
begin
if FMarquee <> Value then
begin
FMarquee := Value;
if not FMarquee then
begin
Position := Min;
end;
end;
BuildBar;
end;
// The marquee width is it's width in percentage of the bar width
procedure TGrProgressbar.SetMarqueeWidth(Value: single);
begin
Value := Math.Min(1.0,Value);
Value := Math.Max(0.0,Value);
if FMarqueeWidth <> Value then
begin
FMarqueeWidth := Value;
BuildBar;
end;
end;
procedure TGrProgressbar.SetMarqueeSpeed(const Value: integer);
begin
if FMarqueeSpeed <> Value then
begin
FMarqueeSpeed := Value;
FMarqueeSpeed := Math.Min(100,FMarqueeSpeed);
FMarqueeSpeed := Math.Max(1,FMarqueeSpeed);
end;
end;
procedure TGrProgressbar.SetMax(const Value: integer);
begin
if FMax <> Value then
begin
FMax := Value;
BuildBar;
end;
Position := Position;
end;
procedure TGrProgressbar.SetMin(const Value: integer);
begin
if FMin <> Value then
begin
FMin := Value;
BuildBar;
end;
Position := Position;
end;
procedure TGrProgressbar.SetPosition(Value: integer);
begin
// First, limit the setted value to min and max position
Value := Math.Min(Max, Value);
Value := Math.Max(Min, Value);
// Disable marquee if we write a new position
FMarquee := false;
if FPosition <> Value then
begin
FPosition := Value;
BuildBar;
Changed;
end;
end;
procedure TGrProgressbar.SetUseSystemColors(const Value: boolean);
var
ABmp : TBitmap;
PickColor: TColor;
FProgressThemeData : HTHEME;
begin
FUseSystemColors := Value;
if FUseSystemColors then
begin
FApplyingSystemColor := true;
// Check if Windows Themes are enabled
if UseThemes then
begin
// A small way (not really clean) to get the color of a themed progress bar
if (SystemColor = clNone) then
begin
{$IfDef DEBUG}SendDebug('SystemColor is None');{$ENDIF}
// We create a local bitmap where we painting on it a themed progress bar
ABmp := TBitmap.Create;
ABmp.SetSize(16,16);
FProgressThemeData := OpenThemeData(Handle, 'Progress');
DrawThemeBackground(FProgressThemeData, ABmp.Canvas.Handle, PP_CHUNK, 0, ABmp.Canvas.ClipRect, nil);
CloseThemeData(FProgressThemeData);
// After painting, we pick the color at a logical position
// Just hope that there is a valid color here
PickColor := ABmp.Canvas.Pixels[2,2];
if PickColor <> CLR_INVALID then
begin
SystemColor := PickColor;
{$IfDef DEBUG}SendDebug('System color found, extracted from BITMAP');{$ENDIF}
end
else
begin
SystemColor := clHighlight;
{$IfDef DEBUG}SendDebug('System color not found, using the Highlight one');{$ENDIF}
end;
ABmp.Free;
end;
Color := SystemColor;
{$IfDef DEBUG}SendDebug('Using previous computed system color');{$ENDIF}
end
else
begin
// If theming is not enabled then use the default highlight color
Color := clHighlight;
{$IfDef DEBUG}SendDebug('No theme is used, default highlight color');{$ENDIF}
end;
FApplyingSystemColor := false;
end;
end;
procedure TGrProgressbar.SetColor(const Value: TColor);
var
H,S,L : Byte;
begin
if FColor <> Value then
begin
// Disable system color only if SetColor is not called by the UseSystemColors method
if not FApplyingSystemColor then
UseSystemColors := false;
FColor := Value;
// Extracting the Wincolor to Hue, Saturation and Luminosity values
FColor1 := Color32(FColor);
RGBtoHSL(FColor1, H, S, L);
// Small way to set the color of the slashes
if Intensity(FColor1) > 160
then
FColor2 := clBlack32
else
FColor2 := clWhite32;
// Redraw the pattern with new colors
InvalidatePattern;
end;
end;
// Property that allow the flippig of the slashes
procedure TGrProgressbar.SetFlip(const Value: boolean);
begin
FFlip := Value;
InvalidatePattern;
end;
/// Catched Windows messages
// If the theme is changed by a new theme then invalidate the system color
// It will be recomputed by the first progress bar with UseSystemColor property enabled
procedure TGrProgressbar.CMStyleChanged(var msg: TMessage);
begin
{$IfDef DEBUG}SendDebug('TGrProgressbar.CMStyleChanged');{$ENDIF}
// Update colors
SystemColor := clNone;
FInvalidateColor := true;
end;
// Stop the timer when this control is not visible, else re-enable it
procedure TGrProgressbar.CMShowingChanged(var msg: TMessage);
begin
inherited;
{$IfDef DEBUG}SendDebug('CMShowingChanged');{$ENDIF}
if Showing then
begin
if Animated and not FAniTimer.Enabled then
begin
FAniTimer.Enabled := true;
{$IfDef DEBUG}SendDebugFmt('Timer of %s started',[Name]);{$ENDIF}
end;
end
else
begin
if Animated and FAniTimer.Enabled then
begin
FAniTimer.Enabled := false;
{$IfDef DEBUG}SendDebugFmt('Timer of %s stopped',[Name]);{$ENDIF}
end;
end;
end;
initialization
SystemColor := clNone;
finalization
end.
Historique
- 15 novembre 2008 01:02:45 :
- Correction
- 17 novembre 2008 08:50:37 :
- Ajout du code du composant ...
- 18 novembre 2008 10:01:52 :
- Ajout d'un exécutable "Exemple.exec"
Sources de la même categorie
Commentaires et avis
Discussions en rapport avec ce code source dans le forum
Insérer une barre de progression lors d'un chargement d'un base .... [ par burnx22 ]
Je suis au Cégep en Informatique et je dois savoir absolument comment faire pour faire fonctionner une barre de progression (progress bar) lorsque j'i
Barre de progression réelle [ par mighty_warrior ]
Bonjour,Ca fait pas mal de temps maintenant que je bidouille un p'tit programme disposant d'une interface en 3D. Le truc c'est que le programme met un
SplashScreen + barre de progression [ par cantador ]
Bonjour à tous, Dans une appli, je crée un SplashScreen au démarrage(5 x 10 cm)avec une barre de progression qui s'incrémente au fur et à mesure des
afficher icone dans une fiche (Tform) comme ceux de la barre d'outils [ par mighty_warrior ]
Bonjours,Je sollicite votre aide car j'ai besoin de savoir comment faire pour afficher les icones des programmes dans une fiche delphi comme on les vo
comment detecter qu'une entree se fait pas lecteur code barre [ par kiou9 ]
salut a tousj'ai encore une question du tonnerre de Zeusj'ai un programme de gestion client-produit-activitéje voudrai pouvoir detecter le fait que j'
program invisible dans la barre de tache [ par Ali_usto ]
salut tout le monde voila je voudrais savoir comment faire pour rendre un programme invisible dans la barre de tache , j'ai trouvé un exemple sur le s
animation copie fichier [ par sisi231 ]
Bonjour, je souhaiterais reprendre l'animation de copie de fichier et de destruction de fichier qui s'affiche dans les boîtes de dialogue de SHFileOpe
Dimension de l'écran avec barre à outils [ par yvessimon ]
Bonjour,La taille total de l'écran est accéssible avec " screen ".Hors la barre d'outils windows peut être horizontale ou verticale et de largeur vari
composant Tanimate [ par mighty_warrior ]
Bonjour,Est-ce que quelqu'un pourrait me renseigné sur le composant Tanimate parce que l'aide de delphi ne m'apporte pas grand chose.D'aprés ce que j'
Minimiser des forms non principales. [ par Fat ]
Je ne sais pas si c'est normal, mais dans une appli en VB par exemple, quand vous creez plusieurs forms, quand vous les minimiser, elles se retrouvent
|
Derniers Blogs
UNE JOLIE-HORLOGE ET PAS QU'UN PEU !UNE JOLIE-HORLOGE ET PAS QU'UN PEU ! par neodante
Pour les possesseurs d'iPhone, ça y est Bijin Tokei - qui se traduit littéralement en Français par " Jolie Horloge " - est arrivé et GRATUITEMENT s'il vous plaît ! Après la version Tokyo, Hokkaido, night club, racing, Gal, "pour les mademoiselles'", . voi...
Cliquez pour lire la suite de l'article par neodante TECHDAYS PARIS 2010 : CONNECTEZ VOS DONNéES à SHAREPOINT 2010 AVEC LES BUSINESS CONNECTIVITY SERVICESTECHDAYS PARIS 2010 : CONNECTEZ VOS DONNéES à SHAREPOINT 2010 AVEC LES BUSINESS CONNECTIVITY SERVICES par ROMELARD Fabrice
Animé par: Gaetan Bouveret et Julien Chomarat Business Connectivity Services (BCS) est dans SharePoint 2010 la version 2 de Business Data Catalog (BDC dans SharePoint 2007). Il s'agit de la solution permettant de visualiser des données provenan...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice [DIVERS] SUIVRE VOS SéRIES PRéFéRéS SUR LA TOILE[DIVERS] SUIVRE VOS SéRIES PRéFéRéS SUR LA TOILE par orion
Comme de nombreux geek, je suis un grand amateur de série TV et je rate régulièrement des épisodes de mes séries préférés. Une solution s'offre à vous avec ce merveilleux site : Tv Gorge - www.tvgorge.com Moteur de recherche à l'appui, vous pouvez ...
Cliquez pour lire la suite de l'article par orion TECHDAYS PARIS 2010 : LA BI DANS SHAREPOINT 2010TECHDAYS PARIS 2010 : LA BI DANS SHAREPOINT 2010 par ROMELARD Fabrice
Animé par: Vincent Bellet et Baptiste Giraudier La BI dans SharePoint 2010, Les nouveaux services d'application dans SP2010 et SQL Server Reporting services 2008 R2. La BI dans SharePoint est généralisée pour tous afin de permettre à tous les coll...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice
Logiciels
DB-MAIN (9.1.0)DB-MAIN (9.1.0)DB-MAIN is a data-modeling and data-architecture tool. It is designed to help developers and anal... Cliquez pour télécharger DB-MAIN Xilisoft DPG Convertisseur (5.1.37.0120)XILISOFT DPG CONVERTISSEUR (5.1.37.0120)Xilisoft DPG Convertisseur offre aux fans de Nintendo DS une bonne solution leur permettant de dé... Cliquez pour télécharger Xilisoft DPG Convertisseur GraphicsGale (2.01.01)GRAPHICSGALE (2.01.01)GraphicsGale est un logiciel de PixelArt avec de nombreuse fonctionnalités permettant de réalisé ... Cliquez pour télécharger GraphicsGale Architecte 3D (Platinum 2010)ARCHITECTE 3D (PLATINUM 2010)Architecte 3D Platinium vous permet de concevoir facilement les plans votre future maison, de l'é... Cliquez pour télécharger Architecte 3D TeamViewer 5 (TeamViewer 5)TEAMVIEWER 5 (TEAMVIEWER 5)Dépanner un ami,expliquer une manipulation devient un jeu d'enfant.
Prise en main d'un autre ord... Cliquez pour télécharger TeamViewer 5
|