Hi,

Does anybody know of a gradient fill panel I can use?  Or the code for
a gradient fill than can be used with a panel or paint box.  I want to
fade from left to right (dark to light).  I normally use a 1 pixel
high bitmap stretched, but think I found a bug (see my previous post).

Someone on this list sent me the component attached.

Philippe

{ ----------------------------------------------------------------------------}
{ A Gradient Fill component for Delphi.                                       }
{ TGradientFill, Copyright 1995, Curtis White.  All Rights Reserved.          }
{ TNetGradient, Copyright 1997, Heiko Webers.  All Rights Reserved.           }
{ This component can be freely used and distributed in commercial and private }
{ environments, provied this notice is not modified in any way.               }
{ ----------------------------------------------------------------------------}
{ Feel free to contact me if you have any questions, comments or suggestions  }
{ at [EMAIL PROTECTED]                                                }
{ Or me at [EMAIL PROTECTED]                                                }
{ ----------------------------------------------------------------------------}
{ Date last modified:  12/06/97                                               }
{ ----------------------------------------------------------------------------}
{ ----------------------------------------------------------------------------}
{ TNetGradient v1.00                                                          }
{ ----------------------------------------------------------------------------}
{ Description:                                                                }
{   A gradient fill like in the new Netscape Communicator Options Box.        }
{ Features:                                                                   }
{   The begin and end colors can be any colors.                               }
{   The fill direction can be set to Right-To-Left or Left-To-Right.          }
{   The number of colors, between 1 and 255 can be set for the fill.          }
{   The Caption can be anything and anywhere on TNetGradient.                 }
{ ----------------------------------------------------------------------------}
{ ----------------------------------------------------------------------------}
{ Revision History:                                                           }
{ 1.00:  Initial release                                                      }
{ 1.00:  Changed to TNetGradient                                              }
{ ----------------------------------------------------------------------------}

unit SMNetGradient;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

type
  { Direction of fill }
  TFillDirection = (fdLeftToRight, fdRightToLeft);
  { Range of valid colors }
  TNumberOfColors = 1..255;

  TNetGradient = class(TGraphicControl)
  private
    { Variables for properties }
    FDirection: TFillDirection;
    FBeginColor: TColor;
    FEndColor: TColor;
   // FCenter: Boolean;
    FAutoSize: Boolean;
    FNumberOfColors: TNumberOfColors;
    FFont : TFont;
    FCaption : String;
    FTextTop : Integer;
    FTextLeft: Integer;

    { Procedures for setting property values }
    procedure SetFillDirection(Value: TFillDirection);
    procedure SetBeginColor(Value: TColor);
    procedure SetEndColor(Value: TColor);
    procedure SetNumberOfColors(Value: TNumberOfColors);
    procedure SetFont(AFont: TFont);
    procedure SetCaption(Value: String);
    procedure SetTextTop(Value: Integer);
    procedure SetTextLeft(Value: Integer);
    { Fill procedure }
    procedure GradientFill;

  protected
    procedure SetAutoSize(Value: Boolean); override;
    procedure Paint; override;
  public
    constructor Create(AOwner: TComponent); override;
  published
    { Repaint when autosized }
    property AutoSize: Boolean read FAutoSize write SetAutoSize default False;
    { Starting color of fill }
    property BeginColor: TColor read FBeginColor write SetBeginColor
        default clBlue;
    { Ending color of fill }
    property EndColor: TColor read FEndColor write SetEndColor default clBlack;
    { Direction of fill }
    property FillDirection: TFillDirection read FDirection write 
SetFillDirection default fdLeftToRight;
    { Number of colors to use in the fill (1 - 256) - default is 255.  If 1 }
    { then it uses the Begin Color.                                        }
    property NumberOfColors: TNumberOfColors read FNumberOfColors write 
SetNumberOfColors default 255;
    { Enable standard properties }
    property Font: TFont read FFont write SetFont;
    property Caption: String read FCaption write SetCaption;
    property TextTop: Integer read FTextTop write SetTextTop;
    property TextLeft: Integer read FTextLeft write SetTextLeft;
    property Align;
    property DragCursor;
    property DragMode;
    property Enabled;
    property ParentShowHint;
    property PopupMenu;
    property ShowHint;
    property Visible;
    property OnClick;
    property OnDblClick;
    property OnDragDrop;
    property OnDragOver;
    property OnEndDrag;
    property OnMouseDown;
    property OnMouseMove;
    property OnMouseUp;
  end;

procedure Register;

implementation

{ TNetGradient }

{ Override the constructor to initialize variables }
constructor TNetGradient.Create(AOwner: TComponent);
begin
  { Inherit original constructor }
  inherited Create(AOwner);
  { Add new initializations }
  Height := 25;
  Width := 400;
  FBeginColor := clSilver;
  FEndColor := $00A56D39;
  Align := alTop;
  FDirection := fdLeftToRight;
  FNumberOfColors:= 255;
  FTextLeft:= 12;
  FTextTop:= 5;
  FFont:= TFont.Create;
  FFOnt.Style:= [fsbold];
  FCaption:= '';
end;

{ Set begin color when property is changed }
procedure TNetGradient.SetBeginColor(Value: TColor);
begin
  FBeginColor := Value;
  GradientFill;
  Invalidate;
end;

{ Set end color when property is changed }
procedure TNetGradient.SetEndColor(Value: TColor);
begin
  FEndColor := Value;
  GradientFill;
  Invalidate;
end;

{ Repaint the screen upon a resize }
procedure TNetGradient.SetAutoSize(Value: Boolean);
begin
  FAutoSize := Value;
  Invalidate;
end;

{ Set the number of colors to be used in the fill }
procedure TNetGradient.SetNumberOfColors(Value: TNumberOfColors);
begin
  FNumberOfColors := Value;
  Invalidate;
end;

// Set the Font
procedure TNetGradient.SetFont(AFont: TFont);
begin
if AFont <> FFont then
  begin
    FFont.Assign(AFont);
  end;
    GradientFill;  
end;

// Set the Caption on NG
procedure TNetGradient.SetCaption(Value: String);
begin
 FCaption:= Value;
 GradientFill;
end;

// Set the Position of the Caption  (Top)
procedure TNetGradient.SetTextTop(Value: Integer);
begin
 FTextTop:= Value;
 GradientFill;
end;

// Set the Position of the Caption (Left)
procedure TNetGradient.SetTextLeft(Value: Integer);
begin
 FTextLeft:= Value;
 GradientFill;
end;


{ Perform the fill when paint is called }
procedure TNetGradient.Paint;
begin
  GradientFill;
end;

{ Gradient fill procedure - the actual routine }
procedure TNetGradient.GradientFill;
var
  { Set up working variables }
  BeginRGBValue  : array[0..2] of Byte;    { Begin RGB values }
  RGBDifference  : array[0..2] of integer; { Difference between begin and end }
                                           { RGB values                       }
  ColorBand : TRect;    { Color band rectangular coordinates }
  I         : Integer;  { Color band index }
  R         : Byte;     { Color band Red value }
  G         : Byte;     { Color band Green value }
  B         : Byte;     { Color band Blue value }
  WorkBmp   : TBitmap;  { Off screen working bitmap }
begin
{ Create the working bitmap and set its width and height }
WorkBmp := TBitmap.Create;
WorkBmp.Width := Width;
WorkBmp.Height := Height;

{ Use working bitmap to draw the gradient }
with WorkBmp do
begin
  { Extract the begin RGB values }
  case FDirection of

     fdLeftToRight:
      begin
        { Set the Red, Green and Blue colors }
        BeginRGBValue[0] := GetRValue (ColorToRGB (FBeginColor));
        BeginRGBValue[1] := GetGValue (ColorToRGB (FBeginColor));
        BeginRGBValue[2] := GetBValue (ColorToRGB (FBeginColor));
        { Calculate the difference between begin and end RGB values }
        RGBDifference[0] := GetRValue (ColorToRGB (FEndColor)) -
                            BeginRGBValue[0];
        RGBDifference[1] := GetGValue (ColorToRGB (FEndColor)) -
                            BeginRGBValue[1];
        RGBDifference[2] := GetBValue (ColorToRGB (FEndColor)) -
                            BeginRGBValue[2];
      end;

    fdRightToLeft:
      begin
        { Set the Red, Green and Blue colors }
        BeginRGBValue[0] := GetRValue (ColorToRGB (FEndColor));
        BeginRGBValue[1] := GetGValue (ColorToRGB (FEndColor));
        BeginRGBValue[2] := GetBValue (ColorToRGB (FEndColor));
        { Calculate the difference between begin and end RGB values }
        RGBDifference[0] := GetRValue (ColorToRGB (FBeginColor)) -
                            BeginRGBValue[0];
        RGBDifference[1] := GetGValue (ColorToRGB (FBeginColor)) -
                            BeginRGBValue[1];
        RGBDifference[2] := GetBValue (ColorToRGB (FBeginColor)) -
                            BeginRGBValue[2];
      end;
  end;

  { Set the pen style and mode }
  Canvas.Pen.Style := psSolid;
  Canvas.Pen.Mode := pmCopy;

  case FDirection of

   { Calculate the color band's left and right coordinates }
   { for LeftToRight and RightToLeft fills }
    fdLeftToRight, fdRightToLeft:
      begin
        ColorBand.Top := 0;
        ColorBand.Bottom := Height;
      end;
  end;

  { Perform the fill }
  for I := 0 to FNumberOfColors do
    begin
    case FDirection of

     { Calculate the color band's left and right coordinates }
      fdLeftToRight, fdRightToLeft:
        begin
          ColorBand.Left    := MulDiv (I    , Width, FNumberOfColors);
          ColorBand.Right := MulDiv (I + 1, Width, FNumberOfColors);
        end;
    end;

    { Calculate the color band's color }
    if FNumberOfColors > 1 then
    begin
      R := BeginRGBValue[0] + MulDiv (I, RGBDifference[0], FNumberOfColors - 1);
      G := BeginRGBValue[1] + MulDiv (I, RGBDifference[1], FNumberOfColors - 1);
      B := BeginRGBValue[2] + MulDiv (I, RGBDifference[2], FNumberOfColors - 1);
    end
    else
    { Set to the Begin Color if set to only one color }
    begin
      R := BeginRGBValue[0];
      G := BeginRGBValue[1];
      B := BeginRGBValue[2];
    end;

    { Select the brush and paint the color band }
    Canvas.Brush.Color := RGB (R, G, B);
    Canvas.FillRect (ColorBand);
    end;
  end;

  { Copy the working bitmap to the main canvas }
  Canvas.Draw(0, 0, WorkBmp);

  // <TextOut>
   Canvas.Brush.Style:= bsClear;
   Canvas.Font.Assign(FFont);
   Canvas.Textout(FTextLeft, FTextTop, FCaption);
  // </TextOut>

  { Release the working bitmap resources }
  WorkBmp.Free;
end;

{ Set the fill direction }
procedure TNetGradient.SetFillDirection(Value: TFillDirection);
begin
  if Value <> FDirection then
  begin
    FDirection := Value;
    GradientFill;
    Invalidate;
  end;
end;

{ Register the component }
procedure Register;
begin
  RegisterComponents('SMACE', [TNetGradient]);
end;

end.

Reply via email to