Sign in Join
Wiki copytemporary

Double Gradient: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: Double Gradient

OldNewLine
1+Now 'DoubleGradientAlphaFill' & 'nGradientAlphaFill' are included in [[BGRABitmap]] in the unit 'BGRAGradients'.
2+
3+## Double Gradient
4+
5+<figure>
6+<img src="sampledoublegd.png" title="sampledoublegd.png" />
7+<figcaption>sampledoublegd.png</figcaption>
8+</figure>
9+
10+### Unit
11+
12+#### DoubleGradient
13+
14+``` pascal
15+unit doublegradient;
16+
17+{$mode objfpc}{$H+}
18+
19+interface
20+
21+uses
22+ Classes, Graphics;
23+
24+function DoubleGradientFill(ARect: TRect; AStart1,AStop1,AStart2,AStop2: TColor;
25+ ADirection1,ADirection2,APos: TGradientDirection; AValue: Single): TBitmap;
26+
27+implementation
28+
29+function DoubleGradientFill(ARect: TRect; AStart1,AStop1,AStart2,AStop2: TColor;
30+ ADirection1,ADirection2,APos: TGradientDirection; AValue: Single): TBitmap;
31+var
32+ ABitmap: TBitmap; ARect1,ARect2: TRect;
33+begin
34+ ABitmap := TBitmap.Create;
35+ ABitmap.Width:=ARect.Right;
36+ ABitmap.Height:=ARect.Bottom;
37+ if AValue <> 0 then ARect1:=ARect;
38+ if AValue <> 1 then ARect2:=ARect;
39+ if APos = gdVertical then begin
40+ ARect1.Bottom:=Round(ARect1.Bottom * AValue);
41+ ARect2.Top:=ARect1.Bottom;
42+ end
43+ else if APos = gdHorizontal then begin
44+ ARect1.Right:=Round(ARect1.Right * AValue);
45+ ARect2.Left:=ARect1.Right;
46+ end;
47+ if AValue <> 0 then ABitmap.Canvas.GradientFill(ARect1,AStart1,AStop1,ADirection1);
48+ if AValue <> 1 then ABitmap.Canvas.GradientFill(ARect2,AStart2,AStop2,ADirection2);
49+ Result:=ABitmap;
50+end;
51+
52+end.
53+```
54+
55+#### DoubleGradientAlpha
56+
57+This requires [[BGRABitmap]].
58+
59+``` pascal
60+unit doublegradientalpha;
61+
62+{$mode objfpc}{$H+}
63+
64+interface
65+
66+uses
67+ Classes, Graphics,
68+ BGRABitmap, BGRABitmapTypes;
69+
70+function DoubleGradientAlphaFill(ARect: TRect; AStart1,AStop1,AStart2,AStop2: TBGRAPixel;
71+ ADirection1,ADirection2,APos: TGradientDirection; AValue: Single): TBGRABitmap;
72+
73+implementation
74+
75+function DoubleGradientAlphaFill(ARect: TRect; AStart1,AStop1,AStart2,AStop2: TBGRAPixel;
76+ ADirection1,ADirection2,APos: TGradientDirection; AValue: Single): TBGRABitmap;
77+var
78+ ABitmap: TBGRABitmap; ARect1,ARect2: TRect; APoint1,APoint2,APoint3,APoint4: TPointF;
79+begin
80+ ABitmap := TBGRABitmap.Create(ARect.Right,ARect.Bottom);
81+ if AValue <> 0 then ARect1:=ARect;
82+ if AValue <> 1 then ARect2:=ARect;
83+ if APos = gdVertical then begin
84+ ARect1.Bottom:=Round(ARect1.Bottom * AValue);
85+ ARect2.Top:=ARect1.Bottom;
86+ end
87+ else if APos = gdHorizontal then begin
88+ ARect1.Right:=Round(ARect1.Right * AValue);
89+ ARect2.Left:=ARect1.Right;
90+ end;
91+ if ADirection1 = gdVertical then begin
92+ APoint1:=PointF(ARect1.Left,ARect1.Top);
93+ APoint2:=PointF(ARect1.Left,ARect1.Bottom);
94+ end
95+ else if ADirection1 = gdHorizontal then begin
96+ APoint1:=PointF(ARect1.Left,ARect1.Top);
97+ APoint2:=PointF(ARect1.Right,ARect1.Top);
98+ end;
99+ if ADirection2 = gdVertical then begin
100+ APoint3:=PointF(ARect2.Left,ARect2.Top);
101+ APoint4:=PointF(ARect2.Left,ARect2.Bottom);
102+ end
103+ else if ADirection2 = gdHorizontal then begin
104+ APoint3:=PointF(ARect2.Left,ARect2.Top);
105+ APoint4:=PointF(ARect2.Right,ARect2.Top);
106+ end;
107+ if AValue <> 0 then
108+ ABitmap.GradientFill(ARect1.Left,ARect1.Top,ARect1.Right,ARect1.Bottom,
109+ AStart1,AStop1,gtLinear,APoint1,APoint2,dmDrawWithTransparency,True,False);
110+ if AValue <> 1 then
111+ ABitmap.GradientFill( ARect2.Left,ARect2.Top,ARect2.Right,ARect2.Bottom,
112+ AStart2,AStop2,gtLinear,APoint3,APoint4,dmDrawWithTransparency,True,False);
113+ Result:=ABitmap;
114+end;
115+
116+end.
117+```
118+
119+### Usage
120+
121+First you must have a 'TBitmap' to store the gradient, then you can draw the image, for example, in all the 'Form1' visible area:
122+
123+<figure>
124+<img src="defaultdbgd.png" title="defaultdbgd.png" />
125+<figcaption>defaultdbgd.png</figcaption>
126+</figure>
127+
128+*This is the result (using DoubleGradientFill).*
129+
130+``` pascal
131+procedure TForm1.FormPaint(Sender: TObject);
132+var
133+ ABitmap: TBitmap;
134+begin
135+ ABitmap:=DoubleGradientFill(Self.ClientRect,clMedGray,clWhite,clSilver,clGray,gdVertical,gdVertical,gdVertical,0.50);
136+ Self.Canvas.Draw(0,0,ABitmap);
137+ ABitmap.Free
138+end;
139+```
140+
141+If you use DoubleGradientAlphaFill first add BGRABitmap and BGRABitmapTypes in the Uses section, then use the function:
142+
143+``` pascal
144+var
145+ myBitmap: TBGRABitmap;
146+begin
147+ myBitmap:= DoubleGradientAlphaFill(
148+ Self.ClientRect,
149+ BGRA(0,0,0,10),BGRA(255,255,255,100),
150+ BGRA(100,100,100,255),BGRA(150,150,150,10),
151+ gdVertical,gdVertical,gdVertical,0.5);
152+ Self.Canvas.Draw(0,0,myBitmap.Bitmap);
153+ myBitmap.Free;
154+end;
155+```
156+
157+### Editor
158+
159+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.
160+
161+<figure>
162+<img src="dbgedit.png" title="dbgedit.png" />
163+<figcaption>dbgedit.png</figcaption>
164+</figure>
165+
166+- To access the menu right click the ScrollBox (gradient area):
167+ - Save bitmap.. Show a dialog to save as a *.bmp file.
168+ - Load gradient.. Show a dialog to load a *.doublegradient session file.
169+ - Save gradient.. Show a dialog to save the current session settings to a file.
170+ - 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.
171+
172+- default.doublegradient: this file has the last settings in the editor, is loaded at startup, saved when you close the application.
173+
174+[Double Gradient Editor 1.0 Source Code](http://www.multiupload.com/5WJ6N8E0N0) dbgdedit1.0.zip (5.64 KB)
175+
176+You are free to edit and improve this editor, this is free of charge.
177+
178+## nGradient
179+
180+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.
181+
182+### Unit
183+
184+#### nGradientFill
185+
186+Copy the code and save to a text file 'ngradient.pas':
187+
188+``` pascal
189+unit ngradient;
190+
191+{$mode objfpc}{$H+}
192+
193+interface
194+
195+uses
196+ Classes, Graphics;
197+
198+type
199+ TnGradientInfo = record
200+ StartColor,StopColor:TColor;
201+ Direction: TGradientDirection;
202+ 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
203+ end;
204+
205+function nGradientFill(ARect: TRect;APos: TGradientDirection; AGradient: array of TnGradientInfo): TBitmap;
206+
207+implementation
208+
209+function nGradientFill(ARect: TRect;APos: TGradientDirection; AGradient: array of TnGradientInfo): TBitmap;
210+var
211+ i:integer;
212+ AnRect,OldRect: TRect;
213+begin
214+ Result := TBitmap.Create;
215+ Result.Width:=ARect.Right-ARect.Left;
216+ Result.Height:=ARect.Bottom-ARect.Top;
217+ OldRect := ARect;
218+ if APos = gdVertical then OldRect.Bottom := ARect.Top
219+ else OldRect.Right := ARect.Left ; // upside down... in case of i = 0...
220+
221+ for i := 0 to high(AGradient) do
222+ begin
223+ AnRect:=OldRect;
224+ if APos = gdVertical then
225+ begin
226+ AnRect.Bottom:=Round((ARect.Bottom-ARect.Top) * AGradient[i].endPercent + ARect.Top);
227+ AnRect.Top:=OldRect.Bottom;
228+ end
229+ else
230+ begin
231+ AnRect.Right:=Round((ARect.Right-ARect.Left) * AGradient[i].endPercent + ARect.Left);
232+ AnRect.Left:=OldRect.Right;
233+ end;
234+
235+ Result.Canvas.GradientFill(AnRect,AGradient[i].StartColor,AGradient[i].StopColor,AGradient[i].Direction);
236+ OldRect := AnRect;
237+ end;
238+end;
239+```
240+
241+#### nGradientAlphaFill
242+
243+This requires [[BGRABitmap]].
244+
245+Copy the code and save to a text file 'ngradientalpha.pas':
246+
247+``` pascal
248+unit ngradientalpha;
249+
250+{$mode objfpc}{$H+}
251+
252+interface
253+
254+uses
255+ Classes, Graphics, BGRABitmap, BGRABitmapTypes;
256+
257+type
258+ TnGradientInfo = record
259+ StartColor, StopColor : TBGRAPixel;
260+ Direction : TGradientDirection;
261+ endPercent : single;
262+ end;
263+
264+function nGradientAlphaFill(ARect: TRect;APos: TGradientDirection;
265+ AGradient: array of TnGradientInfo): TBGRABitmap;
266+
267+implementation
268+
269+function nGradientAlphaFill(ARect: TRect;APos: TGradientDirection;
270+ AGradient: array of TnGradientInfo): TBGRABitmap;
271+var
272+ i:integer; AnRect, OldRect: TRect; Point1, Point2: TPointF;
273+begin
274+ Result := TBGRABitmap.Create(ARect.Right-ARect.Left,ARect.Bottom-ARect.Top);
275+ OldRect := ARect;
276+ if APos = gdVertical then OldRect.Bottom := ARect.Top else OldRect.Right := ARect.Left;
277+ for i := 0 to high(AGradient) do
278+ begin
279+ AnRect:=OldRect;
280+ if APos = gdVertical then begin
281+ AnRect.Bottom:=Round((ARect.Bottom-ARect.Top) * AGradient[i].endPercent + ARect.Top);
282+ AnRect.Top:=OldRect.Bottom;
283+ Point1:=PointF(AnRect.Left,AnRect.Top);
284+ Point2:=PointF(AnRect.Left,AnRect.Bottom);
285+ end
286+ else begin
287+ AnRect.Right:=Round((ARect.Right-ARect.Left) * AGradient[i].endPercent + ARect.Left);
288+ AnRect.Left:=OldRect.Right;
289+ Point1:=PointF(AnRect.Left,AnRect.Top);
290+ Point2:=PointF(AnRect.Right,AnRect.Top);
291+ end;
292+ Result.GradientFill(AnRect.Left,AnRect.Top,AnRect.Right,AnRect.Bottom,
293+ AGradient[i].StartColor,AGradient[i].StopColor,gtLinear,Point1,Point2,dmDrawWithTransparency,True,False);
294+ OldRect := AnRect;
295+ end;
296+end;
297+
298+end.
299+```
300+
301+### Usage
302+
303+If you use nGradientAlphaFill first add BGRABitmap and BGRABitmapTypes in the Uses section, then use the function:
304+
305+``` pascal
306+var
307+ myBitmap: TBGRABitmap;
308+ AGradInfo: array [0..1] of TnGradientInfo;
309+begin
310+ AGradInfo[0].Direction:=gdVertical;
311+ AGradInfo[0].endPercent:=0.50;
312+ AGradInfo[0].StartColor:=BGRA(0,0,0,200);
313+ AGradInfo[0].StopColor:=BGRA(255,255,255,100);
314+
315+ AGradInfo[1].Direction:=gdVertical;
316+ AGradInfo[1].endPercent:=1.00;
317+ AGradInfo[1].StartColor:=BGRA(0,0,0,100);
318+ AGradInfo[1].StopColor:=BGRA(255,255,255,50);
319+
320+ myBitmap:= nGradientAlphaFill(Self.ClientRect,gdVertical,Agradinfo);
321+ Self.Canvas.Draw(0,0,myBitmap.Bitmap);
322+ myBitmap.Free;
323+end;
324+```
325+
326+### Editor
327+
328+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.
329+
330+With nGradient Editor you can use 'n' (number) of gradients.
331+
332+<figure>
333+<img src="ngedit.png" title="ngedit.png" />
334+<figcaption>ngedit.png</figcaption>
335+</figure>
336+
337+[nGradient Editor 1.1 (With alpha support) Source Code](http://www.multiupload.com/Z5CEFYE5CO) ngdedit1.1alpha.zip (22.58 KB) / [forum attach](http://lazarus.freepascal.org/index.php?action=dlattach;topic=12145.0;attach=1641)
338+
339+**Note:** This editor doesn't use BGRABitmap, this uses their own Alpha procedures.
340+
341+[nGradient Editor 1.1 Source Code](http://www.multiupload.com/SJDCG5P21Z) ngdedit1.1.zip (26.14 KB) / [forum attach](http://lazarus.freepascal.org/index.php?action=dlattach;topic=12145.0;attach=1636)
342+
343+---
344+*From the Free Pascal wiki, page "Double Gradient", as it stood on 2020-02-14 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history