1 unit CustomDrawn_WinXP;
2
3 {$mode objfpc}{$H+}
4
5 interface
6
7 uses
8 // RTL
9 Classes, SysUtils, Types, fpcanvas, fpimage,
10 // LCL -> Use only TForm, TWinControl, TCanvas and TLazIntfImage
11 Graphics, Controls, LCLType,
12 //
13 customdrawndrawers, customdrawn_common;
14
15 type
16
17 { TCDDrawerWinXP }
18
19 TCDDrawerWinXP = class(TCDDrawerCommon)
20 public
21 // General
GetMeasuresnull22 function GetMeasures(AMeasureID: Integer): Integer; override;
GetMeasuresExnull23 //function GetMeasuresEx(ADest: TCanvas; AMeasureID: Integer;
24 //AState: TCDControlState; AStateEx: TCDControlStateEx): Integer; override;
25 //
26 function GetDrawStyle: TCDDrawStyle; override;
27 procedure LoadFallbackPaletteColors; override;
28 // General drawing routines
29 {procedure DrawFocusRect(ADest: TCanvas; ADestPos: TPoint; ASize: TSize); override;
30 procedure DrawRaisedFrame(ADest: TCanvas; ADestPos: TPoint; ASize: TSize); override;
31 procedure DrawSunkenFrame(ADest: TCanvas; ADestPos: TPoint; ASize: TSize); override;
32 procedure DrawShallowSunkenFrame(ADest: TCanvas; ADestPos: TPoint; ASize: TSize); override;}
33 procedure DrawTickmark(ADest: TFPCustomCanvas; ADestPos: TPoint; AState: TCDControlState); override;
34 {procedure DrawSlider(ADest: TCanvas; ADestPos: TPoint; ASize: TSize; AState: TCDControlState); override;
35 procedure DrawCompactArrow(ADest: TCanvas; ADestPos: TPoint; ADirection: TCDControlState); override;}
36 // ===================================
37 // Standard Tab
38 // ===================================
39 // TCDButton
40 procedure DrawButton(ADest: TFPCustomCanvas; ADestPos: TPoint; ASize: TSize;
41 AState: TCDControlState; AStateEx: TCDButtonStateEx); override;
42 // TCDEdit
43 procedure DrawEditFrame(ADest: TCanvas; ADestPos: TPoint; ASize: TSize;
44 AState: TCDControlState; AStateEx: TCDEditStateEx); override;
45 // TCDCheckBox
46 procedure DrawCheckBoxSquare(ADest: TCanvas; ADestPos: TPoint; ASize: TSize;
47 AState: TCDControlState; AStateEx: TCDControlStateEx); override;
48 end;
49
50 implementation
51
52 const
53
54 // Button
55
56 WINXP_BUTTON_BODY_TOP = $00FFFFFF;
57 WINXP_BUTTON_BODY_BOTTOM = $00EAF0F0;
58
59 WINXP_BUTTON_BODY_LINES_PREPRELAST = $00E6EBEC;
60 WINXP_BUTTON_BODY_LINES_PRELAST = $00D6DFE2;
61 WINXP_BUTTON_BODY_LINES_LAST = $00C5D0D6;
62
63 WINXP_BUTTON_SUNKEN_BODY_BOTTOM = $00E3E9EA;
64
65 WINXP_BUTTON_FRAME_DARK_BLUE = $00743C00;
66 WINXP_BUTTON_FRAME_MED_DARK_BLUE = $00A27055;
67 WINXP_BUTTON_FRAME_MEDIUM_BLUE = $00A8957A;
68 WINXP_BUTTON_FRAME_LIGHT_BLUE = $00DDCFC0;
69
70 WINXP_BUTTON_DISABLED_BODY = $00EAF4F5;
71
72 WINXP_BUTTON_FRAME_DARK_DISABLED = $00BAC7C9;
73 WINXP_BUTTON_FRAME_MEDIUM_DISABLED = $00CAD6D8;
74 WINXP_BUTTON_FRAME_LIGHT_DISABLED = $00E2EDEE;
75
76 WINXP_BUTTON_FOCUS_TOP = $00FFE7CE;
77 WINXP_BUTTON_FOCUS_TOP_GRAD = $00F6D4BC;
78 WINXP_BUTTON_FOCUS_BOTTOM_GRAD = $00E4AD89;
79 WINXP_BUTTON_FOCUS_BOTTOM = $00EF8269;
80
81 WINXP_BUTTON_MOUSEOVER_TOP = $00CFF0FF;
82 WINXP_BUTTON_MOUSEOVER_TOP_GRAD = $0089D8FD;
83 WINXP_BUTTON_MOUSEOVER_BOTTOM_GRAD = $0030B3F8;
84 WINXP_BUTTON_MOUSEOVER_BOTTOM = $000097E5;
85
86 // CheckBox
87
88 WINXP_CHECKBOX_GRADIENT_1 = $00D6DED6;
89 WINXP_CHECKBOX_GRADIENT_2 = $00CED6D6;
90 WINXP_CHECKBOX_GRADIENT_3 = $00D6DED6;
91 WINXP_CHECKBOX_GRADIENT_4 = $00D6D6D6;
92 WINXP_CHECKBOX_GRADIENT_5 = $00DEE7DE;
93 WINXP_CHECKBOX_GRADIENT_6 = $00D6DEDE;
94 WINXP_CHECKBOX_GRADIENT_7 = $00E7E7DE;
95 WINXP_CHECKBOX_GRADIENT_8 = $00DEE7E7;
96 WINXP_CHECKBOX_GRADIENT_9 = $00EFEFE7;
97 WINXP_CHECKBOX_GRADIENT_10 = $00E7E7E7;
98
99 WINXP_CHECKBOX_GRADIENT_DIAGONAL = $00D6DED6; // The biggest diagonal
100
101 WINXP_CHECKBOX_GRADIENT_11 = $00EFEFF7;
102 WINXP_CHECKBOX_GRADIENT_12 = $00F7EFEF;
103 WINXP_CHECKBOX_GRADIENT_13 = $00EFEFEF;
104 WINXP_CHECKBOX_GRADIENT_14 = $00F7FFF7;
105 WINXP_CHECKBOX_GRADIENT_15 = $00F7F7FF;
106 WINXP_CHECKBOX_GRADIENT_16 = $00FFF7F7;
107 WINXP_CHECKBOX_GRADIENT_17 = $00F7F7F7;
108 WINXP_CHECKBOX_GRADIENT_18 = $00F7FFF7;
109 WINXP_CHECKBOX_GRADIENT_19 = $00F7F7FF;
110 WINXP_CHECKBOX_GRADIENT_20 = $00FFF7F7;
111
112 WINXP_TICKMARK = $0021A521;
113 WINXP_GRAY_TICKMARK = $0099A8AC;
114
115 WINXP_FRAME_BLUE = $00B99D7F;
116 WINXP_FORM = $00D8E9EC;
117
118 { TCDDrawerWinXP }
119
GetMeasuresnull120 function TCDDrawerWinXP.GetMeasures(AMeasureID: Integer): Integer;
121 begin
122 case AMeasureID of
123 TCDCHECKBOX_SQUARE_HALF_HEIGHT: Result := 6;
124 TCDCHECKBOX_SQUARE_HEIGHT: Result := 13;
125 else
126 Result:=inherited GetMeasures(AMeasureID);
127 end;
128 end;
129
TCDDrawerWinXP.GetDrawStylenull130 function TCDDrawerWinXP.GetDrawStyle: TCDDrawStyle;
131 begin
132 Result := dsWinXP;
133 end;
134
135 procedure TCDDrawerWinXP.LoadFallbackPaletteColors;
136 begin
137 Palette.ScrollBar := $C8D0D4;
138 Palette.Background := $984E00;
139 Palette.ActiveCaption := $E35400;
140 Palette.InactiveCaption := $DF967A;
141 Palette.Menu := $FFFFFF;
142 Palette.Window := clWhite; // The inside of a Edit control, for example
143 Palette.WindowFrame := $0;
144 Palette.MenuText := $0;
145 Palette.WindowText := $0;
146 Palette.CaptionText := $FFFFFF;
147 Palette.ActiveBorder := $C8D0D4;
148 Palette.InactiveBorder := $C8D0D4;
149 Palette.AppWorkspace := $808080;
150 Palette.Highlight := $C56A31;
151 Palette.HighlightText := $FFFFFF;
152 Palette.BtnFace := WINXP_FORM;
153 Palette.BtnShadow := $99A8AC;
154 Palette.GrayText := $99A8AC;
155 Palette.BtnText := $0;
156 Palette.InactiveCaptionText := $F8E4D8;
157 Palette.BtnHighlight := $FFFFFF;
158 Palette.color3DDkShadow := $646F71;
159 Palette.color3DLight := $E2EFF1;
160 Palette.InfoText := $0;
161 Palette.InfoBk := $E1FFFF;
162 //
163 Palette.HotLight := $800000;
164 Palette.GradientActiveCaption := $FF953D;
165 Palette.GradientInactiveCaption := $EBB99D;
166 Palette.MenuHighlight := $C56A31;
167 Palette.MenuBar := $D8E9EC;
168 Palette.Form := WINXP_FORM;
169 end;
170
171 procedure TCDDrawerWinXP.DrawTickmark(ADest: TFPCustomCanvas; ADestPos: TPoint; AState: TCDControlState);
172 var
173 i: Integer;
174 begin
175 if csfPartiallyOn in AState then ADest.Pen.FPColor := TColorToFPColor(WINXP_GRAY_TICKMARK)
176 else ADest.Pen.FPColor := TColorToFPColor(WINXP_TICKMARK);
177 ADest.Pen.Style := psSolid;
178 // 3 lines going down and to the right
179 for i := 0 to 2 do
180 ADest.Line(ADestPos.X+i, ADestPos.Y+i, ADestPos.X+i, ADestPos.Y+3+i);
181 // Now 4 lines going up and to the right
182 for i := 3 to 6 do
183 ADest.Line(ADestPos.X+i, ADestPos.Y+4-i, ADestPos.X+i, ADestPos.Y+3+4-i);
184 end;
185
186 procedure TCDDrawerWinXP.DrawButton(ADest: TFPCustomCanvas;
187 ADestPos: TPoint; ASize: TSize; AState: TCDControlState; AStateEx: TCDButtonStateEx);
188 var
189 lDest: TCanvas absolute ADest;
190 Str: string;
191 lColor: TColor;
192 lRect: TRect;
193 lFrameDark, lFrameMedDark, lFrameMedium, lFrameLight: TColor;
194 lSelTop, lSelTopGrad, lSelBottomGrad, lSelBottom: TColor;
195 begin
196 // Background corners
197 lColor := AStateEx.ParentRGBColor;
198 lDest.Pixels[0, 0] := lColor;
199 lDest.Pixels[ASize.cx-1, 0] := lColor;
200 lDest.Pixels[0, ASize.cy-1] := lColor;
201 lDest.Pixels[ASize.cx-1, ASize.cy-1] := lColor;
202
203 // Main body
204 if csfSunken in AState then
205 begin
206 ADest.Brush.Style := bsSolid;
207 lDest.Brush.Color := WINXP_BUTTON_SUNKEN_BODY_BOTTOM;
208 lDest.Pen.Color := WINXP_BUTTON_SUNKEN_BODY_BOTTOM;
209 ADest.Rectangle(1, 1, ASize.cx-1, ASize.cy-1);
210 end
211 else if csfEnabled in AState then
212 begin
213 // First the gradient
214 lRect := Bounds(1, 1, ASize.cx-4, ASize.cy-5);
215 lDest.GradientFill(lRect, WINXP_BUTTON_BODY_TOP, WINXP_BUTTON_BODY_BOTTOM, gdVertical);
216 // Now the extra lines which make the bottom-right
217 lDest.Pen.Color := WINXP_BUTTON_BODY_LINES_PREPRELAST;
218 ADest.Line(1, ASize.cy-4, ASize.cx-3, ASize.cy-4);
219 ADest.Line(ASize.cx-3, ASize.cy-4, ASize.cx-3, 1);
220 lDest.Pen.Color := WINXP_BUTTON_BODY_LINES_PRELAST;
221 ADest.Line(2, ASize.cy-3, ASize.cx-2, ASize.cy-3);
222 ADest.Line(ASize.cx-2, ASize.cy-3, ASize.cx-2, 2);
223 lDest.Pen.Color := WINXP_BUTTON_BODY_LINES_LAST;
224 ADest.Line(3, ASize.cy-1, ASize.cx-3, ASize.cy-1);
225 end
226 else // disabled
227 begin
228 ADest.Brush.Style := bsSolid;
229 lDest.Brush.Color := WINXP_BUTTON_DISABLED_BODY;
230 lDest.Pen.Color := WINXP_BUTTON_DISABLED_BODY;
231 ADest.Rectangle(1, 1, ASize.cx-1, ASize.cy-1);
232 end;
233
234 // Now the frame
235 if csfEnabled in AState then
236 begin
237 lFrameDark := WINXP_BUTTON_FRAME_DARK_BLUE;
238 lFrameMedDark := WINXP_BUTTON_FRAME_MED_DARK_BLUE;
239 lFrameMedium := WINXP_BUTTON_FRAME_MEDIUM_BLUE;
240 lFrameLight := WINXP_BUTTON_FRAME_LIGHT_BLUE;
241 end
242 else
243 begin
244 lFrameDark := WINXP_BUTTON_FRAME_DARK_DISABLED;
245 lFrameMedDark := WINXP_BUTTON_FRAME_MEDIUM_DISABLED;
246 lFrameMedium := WINXP_BUTTON_FRAME_MEDIUM_DISABLED;
247 lFrameLight := WINXP_BUTTON_FRAME_LIGHT_DISABLED;
248 end;
249
250 lDest.Pixels[1, 0] := lFrameMedium;
251 lDest.Pixels[0, 1] := lFrameMedium;
252 lDest.Pixels[1, 1] := lFrameMedDark;
253 lDest.Pixels[2, 1] := lFrameLight;
254 lDest.Pixels[1, 2] := lFrameLight;
255
256 lDest.Pixels[ASize.cx-2, 0] := lFrameMedium;
257 lDest.Pixels[ASize.cx-1, 1] := lFrameMedium;
258 lDest.Pixels[ASize.cx-2, 1] := lFrameMedDark;
259 lDest.Pixels[ASize.cx-3, 1] := lFrameLight;
260 lDest.Pixels[ASize.cx-2, 2] := lFrameLight;
261
262 lDest.Pixels[1, ASize.cy-1] := lFrameMedium;
263 lDest.Pixels[0, ASize.cy-2] := lFrameMedium;
264 lDest.Pixels[1, ASize.cy-2] := lFrameMedDark;
265 lDest.Pixels[2, ASize.cy-2] := lFrameLight;
266 lDest.Pixels[1, ASize.cy-3] := lFrameLight;
267
268 lDest.Pixels[ASize.cx-2, ASize.cy-1] := lFrameMedium;
269 lDest.Pixels[ASize.cx-1, ASize.cy-2] := lFrameMedium;
270 lDest.Pixels[ASize.cx-2, ASize.cy-2] := lFrameMedDark;
271 lDest.Pixels[ASize.cx-3, ASize.cy-2] := lFrameLight;
272 lDest.Pixels[ASize.cx-2, ASize.cy-3] := lFrameLight;
273
274 lDest.Pen.Color := lFrameDark;
275 lDest.Line(2, 0, ASize.cx-2, 0);
276 lDest.Line(2, ASize.cy-1, ASize.cx-2, ASize.cy-1);
277 lDest.Line(0, 2, 0, ASize.cy-2);
278 lDest.Line(ASize.cx-1, 2, ASize.cx-1, ASize.cy-2);
279
280 // Now focus / mouseover indication, note that both disappear when sunked in WinXP
281 if ((csfHasFocus in AState) or (csfMouseOver in AState)) and not (csfSunken in AState) then
282 begin
283 if (csfHasFocus in AState) then
284 begin
285 lSelTop := WINXP_BUTTON_FOCUS_TOP;
286 lSelTopGrad := WINXP_BUTTON_FOCUS_TOP_GRAD;
287 lSelBottomGrad := WINXP_BUTTON_FOCUS_BOTTOM_GRAD;
288 lSelBottom := WINXP_BUTTON_FOCUS_BOTTOM;
289 end
290 else
291 begin
292 lSelTop := WINXP_BUTTON_MOUSEOVER_TOP;
293 lSelTopGrad := WINXP_BUTTON_MOUSEOVER_TOP_GRAD;
294 lSelBottomGrad := WINXP_BUTTON_MOUSEOVER_BOTTOM_GRAD;
295 lSelBottom := WINXP_BUTTON_MOUSEOVER_BOTTOM;
296 end;
297
298 // Top
299 lDest.Pen.Color := lSelTop;
300 ADest.Line(2, 1, ASize.cx-2, 1);
301 lDest.Pen.Color := lSelTopGrad;
302 ADest.Line(1, 2, ASize.cx-1, 2);
303 // Gradient
304 lRect := Bounds(1, 2, 2, ASize.cy-4);
305 lDest.GradientFill(lRect, lSelTopGrad, lSelBottomGrad, gdVertical);
306 lRect := Bounds(ASize.cx-3, 2, 2, ASize.cy-4);
307 lDest.GradientFill(lRect, lSelTopGrad, lSelBottomGrad, gdVertical);
308 // Bottom
309 lDest.Pen.Color := lSelBottomGrad;
310 ADest.Line(1, ASize.cy-3, ASize.cx-1, ASize.cy-3);
311 lDest.Pen.Color := lSelBottom;
312 ADest.Line(2, ASize.cy-2, ASize.cx-2, ASize.cy-2);
313 end;
314
315 // Button text, note that it doesn't move downwards when clicked in WinXP
316 ADest.Font.Assign(AStateEx.Font);
317 ADest.Brush.Style := bsClear;
318 ADest.Pen.Style := psSolid;
319 Str := AStateEx.Caption;
320 lDest.TextOut((ASize.cx - lDest.TextWidth(Str)) div 2,
321 (ASize.cy - lDest.TextHeight(Str)) div 2, Str);
322 end;
323
324 procedure TCDDrawerWinXP.DrawEditFrame(ADest: TCanvas; ADestPos: TPoint;
325 ASize: TSize; AState: TCDControlState; AStateEx: TCDEditStateEx);
326 begin
327 // The frame
328 ADest.Brush.Style := bsClear;
329 ADest.Pen.Color := WINXP_FRAME_BLUE;
330 ADest.Pen.Style := psSolid;
331 ADest.Rectangle(0, 0, ASize.cx, ASize.cy);
332 end;
333
334 procedure TCDDrawerWinXP.DrawCheckBoxSquare(ADest: TCanvas; ADestPos: TPoint;
335 ASize: TSize; AState: TCDControlState; AStateEx: TCDControlStateEx);
336 begin
337 ADest.Pen.Style := psSolid;
338 ADest.Brush.Style := bsClear;
339 ADest.Pen.Color := clBlack;
340 ADest.Rectangle(0,0,13,13);
341 ADest.Pixels[1,1] := WINXP_CHECKBOX_GRADIENT_1;
342 ADest.Pen.Color := WINXP_CHECKBOX_GRADIENT_2;
343 ADest.Line(1,2,3,0);
344 ADest.Pen.Color := WINXP_CHECKBOX_GRADIENT_3;
345 ADest.Line(1,3,4,0);
346 ADest.Pen.Color := WINXP_CHECKBOX_GRADIENT_4;
347 ADest.Line(1,4,5,0);
348 ADest.Pen.Color := WINXP_CHECKBOX_GRADIENT_5;
349 ADest.Line(1,5,6,0);
350 ADest.Pen.Color := WINXP_CHECKBOX_GRADIENT_6;
351 ADest.Line(1,6,7,0);
352 ADest.Pen.Color := WINXP_CHECKBOX_GRADIENT_7;
353 ADest.Line(1,7,8,0);
354 ADest.Pen.Color := WINXP_CHECKBOX_GRADIENT_8;
355 ADest.Line(1,8,9,0);
356 ADest.Pen.Color := WINXP_CHECKBOX_GRADIENT_9;
357 ADest.Line(1,9,10,0);
358 ADest.Pen.Color := WINXP_CHECKBOX_GRADIENT_10;
359 ADest.Line(1,10,11,0);
360 ADest.Pen.Color := WINXP_CHECKBOX_GRADIENT_DIAGONAL;
361 ADest.Line(1,11,12,0);
362 ADest.Pen.Color := WINXP_CHECKBOX_GRADIENT_11;
363 ADest.Line(2,11,12,1);
364 ADest.Pen.Color := WINXP_CHECKBOX_GRADIENT_12;
365 ADest.Line(3,11,12,2);
366 ADest.Pen.Color := WINXP_CHECKBOX_GRADIENT_13;
367 ADest.Line(4,11,12,3);
368 ADest.Pen.Color := WINXP_CHECKBOX_GRADIENT_14;
369 ADest.Line(5,11,12,4);
370 ADest.Pen.Color := WINXP_CHECKBOX_GRADIENT_15;
371 ADest.Line(6,11,12,5);
372 ADest.Pen.Color := WINXP_CHECKBOX_GRADIENT_16;
373 ADest.Line(7,11,12,6);
374 ADest.Pen.Color := WINXP_CHECKBOX_GRADIENT_17;
375 ADest.Line(8,11,12,7);
376 ADest.Pen.Color := WINXP_CHECKBOX_GRADIENT_18;
377 ADest.Line(9,11,12,8);
378 ADest.Pen.Color := WINXP_CHECKBOX_GRADIENT_19;
379 ADest.Line(10,11,12,9);
380 ADest.Pixels[11,11] := WINXP_CHECKBOX_GRADIENT_20;
381 end;
382
383 initialization
384 RegisterDrawer(TCDDrawerWinXP.Create, dsWinXP);
385 end.
386
387