Difference between revisions of "Double Gradient"

From Lazarus wiki
Jump to navigationJump to search
m
(Article separated into DoubleGradient / nGradient)
Line 1: Line 1:
 
{{Double Gradient}}
 
{{Double Gradient}}
  
== Unit ==
+
== Double Gradient ==
  
 
[[Image:sampledoublegd.png]]
 
[[Image:sampledoublegd.png]]
  
With this unit 'ngradient' you can easily make gradients for toolbars, buttons, etc. Save the below code in a text file 'ngradient.pas' and add 'ngradient' in the 'uses' section of your project.
+
=== Unit ===
 +
 
 +
==== DoubleGradient ====
  
<delphi>unit ngradient;
+
<delphi>unit doublegradient;
  
 
{$mode objfpc}{$H+}
 
{$mode objfpc}{$H+}
Line 16: Line 18:
 
   Classes, Graphics;
 
   Classes, Graphics;
  
type
+
function DoubleGradientFill(ARect: TRect; AStart1,AStop1,AStart2,AStop2: TColor;
  TnGradientInfo = record
+
  ADirection1,ADirection2,APos: TGradientDirection; AValue: Single): TBitmap;
    StartColor,StopColor:TColor;
 
    Direction: TGradientDirection;
 
    endPercent:single; // This is not the percent of the width, this is the percent of the end of the rect- which means, if this value is 1 - the rect could be from 0.99 to 1 and needs not be from 0 to 1
 
  end;
 
 
 
function nGradientFill(ARect: TRect;APos: TGradientDirection; AGradient: array of TnGradientInfo): TBitmap;
 
  
 
implementation
 
implementation
  
function nGradientFill(ARect: TRect;APos: TGradientDirection; AGradient: array of TnGradientInfo): TBitmap;
+
function DoubleGradientFill(ARect: TRect; AStart1,AStop1,AStart2,AStop2: TColor;
 +
  ADirection1,ADirection2,APos: TGradientDirection; AValue: Single): TBitmap;
 
var
 
var
   i:integer;
+
   ABitmap: TBitmap; ARect1,ARect2: TRect;
  AnRect,OldRect: TRect;
 
 
begin
 
begin
   Result := TBitmap.Create;
+
   ABitmap := TBitmap.Create;
   Result.Width:=ARect.Right-ARect.Left;
+
   ABitmap.Width:=ARect.Right;
   Result.Height:=ARect.Bottom-ARect.Top;
+
   ABitmap.Height:=ARect.Bottom;
   OldRect := ARect;
+
  if AValue <> 0 then ARect1:=ARect;
   if APos = gdVertical then OldRect.Bottom := ARect.Top
+
   if AValue <> 1 then ARect2:=ARect;
    else OldRect.Right := ARect.Left ;  // upside down... in case of i = 0...
+
   if APos = gdVertical then begin
 +
    ARect1.Bottom:=Round(ARect1.Bottom * AValue);
 +
    ARect2.Top:=ARect1.Bottom;
 +
  end
 +
  else if APos = gdHorizontal then begin
 +
    ARect1.Right:=Round(ARect1.Right * AValue);
 +
    ARect2.Left:=ARect1.Right;
 +
   end;
 +
  if AValue <> 0 then ABitmap.Canvas.GradientFill(ARect1,AStart1,AStop1,ADirection1);
 +
  if AValue <> 1 then ABitmap.Canvas.GradientFill(ARect2,AStart2,AStop2,ADirection2);
 +
  Result:=ABitmap;
 +
end;
  
  for i := 0 to high(AGradient) do
+
end.</delphi>
      begin
 
      AnRect:=OldRect;
 
      if APos = gdVertical then
 
        begin
 
        AnRect.Bottom:=Round((ARect.Bottom-ARect.Top) * AGradient[i].endPercent + ARect.Top);
 
        AnRect.Top:=OldRect.Bottom;
 
        end
 
        else
 
        begin
 
        AnRect.Right:=Round((ARect.Right-ARect.Left) * AGradient[i].endPercent + ARect.Left);
 
        AnRect.Left:=OldRect.Right;
 
        end;
 
  
      Result.Canvas.GradientFill(AnRect,AGradient[i].StartColor,AGradient[i].StopColor,AGradient[i].Direction);
+
==== DoubleGradientAlpha ====
      OldRect := AnRect;
+
This requires [[BGRABitmap]].
      end;
 
end;</delphi>
 
  
 
+
<delphi>unit doublegradientalpha;
DoubleGradientFill & DoubleGradientAlphaFill:
 
 
 
<delphi>unit doublegradient;
 
  
 
{$mode objfpc}{$H+}
 
{$mode objfpc}{$H+}
Line 73: Line 63:
 
function DoubleGradientAlphaFill(ARect: TRect; AStart1,AStop1,AStart2,AStop2: TBGRAPixel;
 
function DoubleGradientAlphaFill(ARect: TRect; AStart1,AStop1,AStart2,AStop2: TBGRAPixel;
 
   ADirection1,ADirection2,APos: TGradientDirection; AValue: Single): TBGRABitmap;
 
   ADirection1,ADirection2,APos: TGradientDirection; AValue: Single): TBGRABitmap;
 
function DoubleGradientFill(ARect: TRect; AStart1,AStop1,AStart2,AStop2: TColor;
 
  ADirection1,ADirection2,APos: TGradientDirection; AValue: Single): TBitmap;
 
  
 
implementation
 
implementation
Line 118: Line 105:
 
   AStart2,AStop2,gtLinear,APoint3,APoint4,dmDrawWithTransparency,True,False);
 
   AStart2,AStop2,gtLinear,APoint3,APoint4,dmDrawWithTransparency,True,False);
 
   Result:=ABitmap;
 
   Result:=ABitmap;
end;
+
end;</delphi>
  
function DoubleGradientFill(ARect: TRect; AStart1,AStop1,AStart2,AStop2: TColor;
+
=== Usage ===
  ADirection1,ADirection2,APos: TGradientDirection; AValue: Single): TBitmap;
 
var
 
  ABitmap: TBitmap; ARect1,ARect2: TRect;
 
begin
 
  ABitmap := TBitmap.Create;
 
  ABitmap.Width:=ARect.Right;
 
  ABitmap.Height:=ARect.Bottom;
 
  if AValue <> 0 then ARect1:=ARect;
 
  if AValue <> 1 then ARect2:=ARect;
 
  if APos = gdVertical then begin
 
    ARect1.Bottom:=Round(ARect1.Bottom * AValue);
 
    ARect2.Top:=ARect1.Bottom;
 
  end
 
  else if APos = gdHorizontal then begin
 
    ARect1.Right:=Round(ARect1.Right * AValue);
 
    ARect2.Left:=ARect1.Right;
 
  end;
 
  if AValue <> 0 then ABitmap.Canvas.GradientFill(ARect1,AStart1,AStop1,ADirection1);
 
  if AValue <> 1 then ABitmap.Canvas.GradientFill(ARect2,AStart2,AStop2,ADirection2);
 
  Result:=ABitmap;
 
end;
 
 
 
end.</delphi>
 
 
 
== Usage ==
 
  
 
First you must have a 'TBitmap' to store the gradient, then you can draw the image, for example, in all the 'Form1' visible area:
 
First you must have a 'TBitmap' to store the gradient, then you can draw the image, for example, in all the 'Form1' visible area:
Line 162: Line 124:
 
end;</delphi>
 
end;</delphi>
  
== Editor ==
+
=== Editor ===
 +
 
 +
You can use the 'Double Gradient Editor' that is a GUI to instantly see the result (only for double gradients), save to a bitmap file, save to '*.doublegradient' session file or just copy code to clipboard to use in lazarus.
 +
 
 +
[[Image:dbgedit.png]]
 +
 
 +
* To access the menu right click the ScrollBox (gradient area):
 +
** Save bitmap.. Show a dialog to save as a *.bmp file.
 +
** Load gradient.. Show a dialog to load a *.doublegradient session file.
 +
** Save gradient.. Show a dialog to save the current session settings to a file.
 +
** Copy code to clipboard.. Just copy the settings as text in the clipboard, then you can use it to paste in lazarus source editor to call the doublegradientfill procedure.
  
nGradient Editor is an updated version of Double Gradient Editor with a lot of changes and improvements, like the ability to create gradients with 'n' number of gradients.
+
* default.doublegradient: this file has the last settings in the editor, is loaded at startup, saved when you close the application.
 +
 
 +
[http://www.multiupload.com/5WJ6N8E0N0 Double Gradient Editor 1.0 Source Code] dbgdedit1.0.zip (5.64 KB)
 +
 
 +
You are free to edit and improve this editor, this is free of charge.
  
=== nGradient Editor ===
+
== nGradient ==
With nGradient Editor you can use 'n' (number) of gradients.
 
  
[[Image:ngedit.png]]
+
With this unit 'ngradient' you can easily make gradients for toolbars, buttons, etc. Save the below code in a text file 'ngradient.pas' and add 'ngradient' in the 'uses' section of your project.
  
Version 1.1
+
=== Unit ===
* Renamed to 'n Gradient Edit', just because it is not any more double...
 
* I don't really understand how to save configs - please correct it. Thanks
 
* I commented the Copy-to-clipboard thing - to lazy to correct it...
 
* I stopped the dpi thing because the editor doesn't look ok on my pc, remove "//" in Form.Create if you want to use it.
 
* I changed the editor for arrays, I use a stringlist.  Double Click on StartColor /StopColor or Gradient for an Combobox / ColorDialog.
 
* I paint on an Image.
 
* The image is not longer in the middle - I had some problems, if you could fix it : great.
 
* You can scale the form.
 
* I tried to separate render and the rest...
 
  
Bugfixes:
+
<delphi>unit ngradient;
<delphi>(Rect.Bottom) *37
 
//and I corrected them to
 
(Rect.Bottom - Rect.Top) * 37 + Rect.Top.
 
//If Top and Left was 0 there was no problem ...</delphi>
 
  
<delphi>//Also I just changed the line
+
{$mode objfpc}{$H+}
GradientPB.Canvas.Draw(0,0,ABitmap); 
 
//to
 
Panel1.Canvas.Draw(0,0,ABitmap);</delphi>
 
  
=== Double Gradient Editor ===
+
interface
  
Also you can use the 'Double Gradient Editor' that is a GUI to instantly see the result (only for double gradients), save to a bitmap file, save to '*.doublegradient' session file or just copy code to clipboard to use in lazarus.
+
uses
 +
  Classes, Graphics;
  
[[Image:dbgedit.png]]
+
type
 +
  TnGradientInfo = record
 +
    StartColor,StopColor:TColor;
 +
    Direction: TGradientDirection;
 +
    endPercent:single; // This is not the percent of the width, this is the percent of the end of the rect- which means, if this value is 1 - the rect could be from 0.99 to 1 and needs not be from 0 to 1
 +
  end;
 +
 
 +
function nGradientFill(ARect: TRect;APos: TGradientDirection; AGradient: array of TnGradientInfo): TBitmap;
 +
 
 +
implementation
  
* To access the menu right click the ScrollBox (gradient area):
+
function nGradientFill(ARect: TRect;APos: TGradientDirection; AGradient: array of TnGradientInfo): TBitmap;
** Save bitmap.. Show a dialog to save as a *.bmp file.
+
var
** Load gradient.. Show a dialog to load a *.doublegradient session file.
+
  i:integer;
** Save gradient.. Show a dialog to save the current session settings to a file.
+
  AnRect,OldRect: TRect;
** Copy code to clipboard.. Just copy the settings as text in the clipboard, then you can use it to paste in lazarus source editor to call the doublegradientfill procedure.
+
begin
 +
  Result := TBitmap.Create;
 +
  Result.Width:=ARect.Right-ARect.Left;
 +
  Result.Height:=ARect.Bottom-ARect.Top;
 +
  OldRect := ARect;
 +
  if APos = gdVertical then OldRect.Bottom := ARect.Top
 +
    else OldRect.Right := ARect.Left ;  // upside down... in case of i = 0...
  
* default.doublegradient: this file has the last settings in the editor, is loaded at startup, saved when you close the application.
+
  for i := 0 to high(AGradient) do
 +
      begin
 +
      AnRect:=OldRect;
 +
      if APos = gdVertical then
 +
        begin
 +
        AnRect.Bottom:=Round((ARect.Bottom-ARect.Top) * AGradient[i].endPercent + ARect.Top);
 +
        AnRect.Top:=OldRect.Bottom;
 +
        end
 +
        else
 +
        begin
 +
        AnRect.Right:=Round((ARect.Right-ARect.Left) * AGradient[i].endPercent + ARect.Left);
 +
        AnRect.Left:=OldRect.Right;
 +
        end;
  
== Downloads ==
+
      Result.Canvas.GradientFill(AnRect,AGradient[i].StartColor,AGradient[i].StopColor,AGradient[i].Direction);
 +
      OldRect := AnRect;
 +
      end;
 +
end;</delphi>
  
[http://www.multiupload.com/Z5CEFYE5CO nGradient Editor 1.1 (With alpha support) Source Code] ngdedit1.1alpha.zip (22.58 KB) / [http://lazarus.freepascal.org/index.php?action=dlattach;topic=12145.0;attach=1641 forum attach]
+
=== Editor ===
  
[http://www.multiupload.com/SJDCG5P21Z nGradient Editor 1.1 Source Code] ngdedit1.1.zip (26.14 KB) / [http://lazarus.freepascal.org/index.php?action=dlattach;topic=12145.0;attach=1636 forum attach]
+
nGradient Editor is an updated version of Double Gradient Editor with a lot of changes and improvements, like the ability to create gradients with 'n' number of gradients.
  
[http://www.multiupload.com/5WJ6N8E0N0 Double Gradient Editor 1.0 Source Code] dbgdedit1.0.zip (5.64 KB)
+
With nGradient Editor you can use 'n' (number) of gradients.
  
You are free to edit and improve this editor, this is free of charge.
+
[[Image:ngedit.png]]
  
== External Links ==
+
[http://www.multiupload.com/Z5CEFYE5CO nGradient Editor 1.1 (With alpha support) Source Code] ngdedit1.1alpha.zip (22.58 KB) / [http://lazarus.freepascal.org/index.php?action=dlattach;topic=12145.0;attach=1641 forum attach]
[http://lazarus.freepascal.org/index.php/topic,12145.0.html Forum about this article]
 
  
[http://wiki.lazarus.freepascal.org/Gradient_Filler Gradient Filler]
+
[http://www.multiupload.com/SJDCG5P21Z nGradient Editor 1.1 Source Code] ngdedit1.1.zip (26.14 KB) / [http://lazarus.freepascal.org/index.php?action=dlattach;topic=12145.0;attach=1636 forum attach]

Revision as of 22:53, 13 March 2011

Deutsch (de) English (en)

Double Gradient

sampledoublegd.png

Unit

DoubleGradient

<delphi>unit doublegradient;

{$mode objfpc}{$H+}

interface

uses

 Classes, Graphics;

function DoubleGradientFill(ARect: TRect; AStart1,AStop1,AStart2,AStop2: TColor;

 ADirection1,ADirection2,APos: TGradientDirection; AValue: Single): TBitmap;

implementation

function DoubleGradientFill(ARect: TRect; AStart1,AStop1,AStart2,AStop2: TColor;

 ADirection1,ADirection2,APos: TGradientDirection; AValue: Single): TBitmap;

var

 ABitmap: TBitmap; ARect1,ARect2: TRect;

begin

 ABitmap := TBitmap.Create;
 ABitmap.Width:=ARect.Right;
 ABitmap.Height:=ARect.Bottom;
 if AValue <> 0 then ARect1:=ARect;
 if AValue <> 1 then ARect2:=ARect;
 if APos = gdVertical then begin
   ARect1.Bottom:=Round(ARect1.Bottom * AValue);
   ARect2.Top:=ARect1.Bottom;
 end
 else if APos = gdHorizontal then begin
   ARect1.Right:=Round(ARect1.Right * AValue);
   ARect2.Left:=ARect1.Right;
 end;
 if AValue <> 0 then ABitmap.Canvas.GradientFill(ARect1,AStart1,AStop1,ADirection1);
 if AValue <> 1 then ABitmap.Canvas.GradientFill(ARect2,AStart2,AStop2,ADirection2);
 Result:=ABitmap;

end;

end.</delphi>

DoubleGradientAlpha

This requires BGRABitmap.

<delphi>unit doublegradientalpha;

{$mode objfpc}{$H+}

interface

uses

 Classes, Graphics,
 BGRABitmap, BGRABitmapTypes;

function DoubleGradientAlphaFill(ARect: TRect; AStart1,AStop1,AStart2,AStop2: TBGRAPixel;

 ADirection1,ADirection2,APos: TGradientDirection; AValue: Single): TBGRABitmap;

implementation

function DoubleGradientAlphaFill(ARect: TRect; AStart1,AStop1,AStart2,AStop2: TBGRAPixel;

 ADirection1,ADirection2,APos: TGradientDirection; AValue: Single): TBGRABitmap;

var

 ABitmap: TBGRABitmap; ARect1,ARect2: TRect; APoint1,APoint2,APoint3,APoint4: TPointF;

begin

 ABitmap := TBGRABitmap.Create(ARect.Right,ARect.Bottom);
 if AValue <> 0 then ARect1:=ARect;
 if AValue <> 1 then ARect2:=ARect;
 if APos = gdVertical then begin
   ARect1.Bottom:=Round(ARect1.Bottom * AValue);
   ARect2.Top:=ARect1.Bottom;
 end
 else if APos = gdHorizontal then begin
   ARect1.Right:=Round(ARect1.Right * AValue);
   ARect2.Left:=ARect1.Right;
 end;
 if ADirection1 = gdVertical then begin
   APoint1:=PointF(ARect1.Left,ARect1.Top);
   APoint2:=PointF(ARect1.Left,ARect1.Bottom);
 end
 else if ADirection1 = gdHorizontal then begin
   APoint1:=PointF(ARect1.Left,ARect1.Top);
   APoint2:=PointF(ARect1.Right,ARect1.Top);
 end;
 if ADirection2 = gdVertical then begin
   APoint3:=PointF(ARect2.Left,ARect2.Top);
   APoint4:=PointF(ARect2.Left,ARect2.Bottom);
 end
 else if ADirection2 = gdHorizontal then begin
   APoint3:=PointF(ARect2.Left,ARect2.Top);
   APoint4:=PointF(ARect2.Right,ARect2.Top);
 end;
 if AValue <> 0 then
 ABitmap.GradientFill(ARect1.Left,ARect1.Top,ARect1.Right,ARect1.Bottom,
 AStart1,AStop1,gtLinear,APoint1,APoint2,dmDrawWithTransparency,True,False);
 if AValue <> 1 then
 ABitmap.GradientFill( ARect2.Left,ARect2.Top,ARect2.Right,ARect2.Bottom,
 AStart2,AStop2,gtLinear,APoint3,APoint4,dmDrawWithTransparency,True,False);
 Result:=ABitmap;

end;</delphi>

Usage

First you must have a 'TBitmap' to store the gradient, then you can draw the image, for example, in all the 'Form1' visible area:

defaultdbgd.png

This is the result (using DoubleGradientFill).

<delphi>procedure TForm1.FormPaint(Sender: TObject); var

 ABitmap: TBitmap;

begin

 ABitmap:=DoubleGradientFill(Self.ClientRect,clMedGray,clWhite,clSilver,clGray,gdVertical,gdVertical,gdVertical,0.50);
 Self.Canvas.Draw(0,0,ABitmap);
 ABitmap.Free

end;</delphi>

Editor

You can use the 'Double Gradient Editor' that is a GUI to instantly see the result (only for double gradients), save to a bitmap file, save to '*.doublegradient' session file or just copy code to clipboard to use in lazarus.

dbgedit.png

  • To access the menu right click the ScrollBox (gradient area):
    • Save bitmap.. Show a dialog to save as a *.bmp file.
    • Load gradient.. Show a dialog to load a *.doublegradient session file.
    • Save gradient.. Show a dialog to save the current session settings to a file.
    • Copy code to clipboard.. Just copy the settings as text in the clipboard, then you can use it to paste in lazarus source editor to call the doublegradientfill procedure.
  • default.doublegradient: this file has the last settings in the editor, is loaded at startup, saved when you close the application.

Double Gradient Editor 1.0 Source Code dbgdedit1.0.zip (5.64 KB)

You are free to edit and improve this editor, this is free of charge.

nGradient

With this unit 'ngradient' you can easily make gradients for toolbars, buttons, etc. Save the below code in a text file 'ngradient.pas' and add 'ngradient' in the 'uses' section of your project.

Unit

<delphi>unit ngradient;

{$mode objfpc}{$H+}

interface

uses

 Classes, Graphics;

type

 TnGradientInfo = record
   StartColor,StopColor:TColor;
   Direction: TGradientDirection;
   endPercent:single; // This is not the percent of the width, this is the percent of the end of the rect- which means, if this value is 1 - the rect could be from 0.99 to 1 and needs not be from 0 to 1
 end;

function nGradientFill(ARect: TRect;APos: TGradientDirection; AGradient: array of TnGradientInfo): TBitmap;

implementation

function nGradientFill(ARect: TRect;APos: TGradientDirection; AGradient: array of TnGradientInfo): TBitmap; var

 i:integer;
 AnRect,OldRect: TRect;

begin

 Result := TBitmap.Create;
 Result.Width:=ARect.Right-ARect.Left;
 Result.Height:=ARect.Bottom-ARect.Top;
 OldRect := ARect;
 if APos = gdVertical then OldRect.Bottom := ARect.Top
    else OldRect.Right := ARect.Left ;   // upside down...  in case of i = 0...
 for i := 0 to high(AGradient) do
     begin
     AnRect:=OldRect;
     if APos = gdVertical then
        begin
        AnRect.Bottom:=Round((ARect.Bottom-ARect.Top) * AGradient[i].endPercent + ARect.Top);
        AnRect.Top:=OldRect.Bottom;
        end
       else
        begin
        AnRect.Right:=Round((ARect.Right-ARect.Left) * AGradient[i].endPercent + ARect.Left);
        AnRect.Left:=OldRect.Right;
        end;
     Result.Canvas.GradientFill(AnRect,AGradient[i].StartColor,AGradient[i].StopColor,AGradient[i].Direction);
     OldRect := AnRect;
     end;

end;</delphi>

Editor

nGradient Editor is an updated version of Double Gradient Editor with a lot of changes and improvements, like the ability to create gradients with 'n' number of gradients.

With nGradient Editor you can use 'n' (number) of gradients.

ngedit.png

nGradient Editor 1.1 (With alpha support) Source Code ngdedit1.1alpha.zip (22.58 KB) / forum attach

nGradient Editor 1.1 Source Code ngdedit1.1.zip (26.14 KB) / forum attach