1 unit CustomDrawn_Common;
2
3 {$mode objfpc}{$H+}
4
5 interface
6
7 uses
8 // RTL / FCL
9 Classes, SysUtils, Types, Math, fpcanvas, fpimage,
10 // LazUtils
11 lazutf8,
12 // LCL -> Use only TForm, TWinControl, TCanvas and TLazIntfImage
13 Graphics, Controls, LCLType,
14 // Others only for types
15 StdCtrls, ComCtrls, Forms,
16 //
17 customdrawndrawers, ExtCtrls;
18
19 type
20
21 { TCDDrawerCommon }
22
23 TCDDrawerCommon = class(TCDDrawer)
24 public
PalDefaultUsesNativePalettenull25 function PalDefaultUsesNativePalette: Boolean; override;
26 procedure LoadFallbackPaletteColors; override;
27 // General
GetMeasuresnull28 function GetMeasures(AMeasureID: Integer): Integer; override;
GetMeasuresExnull29 function GetMeasuresEx(ADest: TCanvas; AMeasureID: Integer;
30 AState: TCDControlState; AStateEx: TCDControlStateEx): Integer; override;
31 procedure CalculatePreferredSize(ADest: TCanvas; AControlId: TCDControlID;
32 AState: TCDControlState; AStateEx: TCDControlStateEx;
33 var PreferredWidth, PreferredHeight: integer; WithThemeSpace, AAllowUseOfMeasuresEx: Boolean); override;
GetColornull34 function GetColor(AColorID: Integer): TColor; override;
GetClientAreanull35 function GetClientArea(ADest: TCanvas; ASize: TSize; AControlId: TCDControlID;
36 AState: TCDControlState; AStateEx: TCDControlStateEx): TRect; override;
DPIAdjustmentnull37 function DPIAdjustment(const AValue: Integer): Integer;
38 // General drawing routines
39 procedure DrawFocusRect(ADest: TFPCustomCanvas; ADestPos: TPoint; ASize: TSize); override;
40 procedure DrawRaisedFrame(ADest: TCanvas; ADestPos: TPoint; ASize: TSize); override;
41 procedure DrawFrame3D(ADest: TFPCustomCanvas; ADestPos: TPoint; ASize: TSize;
42 const FrameWidth : integer; const Style : TBevelCut); override;
43 procedure DrawSunkenFrame(ADest: TCanvas; ADestPos: TPoint; ASize: TSize); override;
44 procedure DrawShallowSunkenFrame(ADest: TCanvas; ADestPos: TPoint; ASize: TSize); override;
45 procedure DrawTickmark(ADest: TFPCustomCanvas; ADestPos: TPoint; AState: TCDControlState); override;
46 procedure DrawSlider(ADest: TCanvas; ADestPos: TPoint; ASize: TSize; AState: TCDControlState); override;
47 procedure DrawArrow(ADest: TCanvas; ADestPos: TPoint; ADirection: TCDControlState; ASize: Integer = 7); override;
48 // Extra buttons drawing routines
49 procedure DrawSmallCloseButton(ADest: TCanvas; ADestPos: TPoint); override;
50 procedure DrawButtonWithArrow(ADest: TCanvas; ADestPos: TPoint; ASize: TSize; AState: TCDControlState); override;
51 // TCDControl
52 procedure DrawControl(ADest: TCanvas; ASize: TSize;
53 AState: TCDControlState; AStateEx: TCDControlStateEx); override;
54 // ===================================
55 // Standard Tab
56 // ===================================
57 // TCDButton
58 procedure DrawButton(ADest: TFPCustomCanvas; ADestPos: TPoint; ASize: TSize;
59 AState: TCDControlState; AStateEx: TCDButtonStateEx); override;
60 // TCDEdit
61 procedure DrawEditBackground(ADest: TCanvas; ADestPos: TPoint; ASize: TSize;
62 AState: TCDControlState; AStateEx: TCDEditStateEx); override;
63 procedure DrawEditFrame(ADest: TCanvas; ADestPos: TPoint; ASize: TSize;
64 AState: TCDControlState; AStateEx: TCDEditStateEx); override;
65 procedure DrawCaret(ADest: TCanvas; ADestPos: TPoint; ASize: TSize;
66 AState: TCDControlState; AStateEx: TCDEditStateEx); override;
67 procedure DrawEdit(ADest: TCanvas; ASize: TSize;
68 AState: TCDControlState; AStateEx: TCDEditStateEx); override;
69 // TCDCheckBox
70 procedure DrawCheckBoxSquare(ADest: TCanvas; ADestPos: TPoint; ASize: TSize;
71 AState: TCDControlState; AStateEx: TCDControlStateEx); override;
72 procedure DrawCheckBox(ADest: TCanvas; ASize: TSize;
73 AState: TCDControlState; AStateEx: TCDControlStateEx); override;
74 // TCDRadioButton
75 procedure DrawRadioButtonCircle(ADest: TCanvas; ADestPos: TPoint; ASize: TSize;
76 AState: TCDControlState; AStateEx: TCDControlStateEx); override;
77 procedure DrawRadioButton(ADest: TCanvas; ASize: TSize;
78 AState: TCDControlState; AStateEx: TCDControlStateEx); override;
79 // TCDComboBox
80 procedure DrawComboBox(ADest: TCanvas; ASize: TSize;
81 AState: TCDControlState; AStateEx: TCDEditStateEx); override;
82 // TCDScrollBar
83 procedure DrawScrollBar(ADest: TCanvas; ASize: TSize;
84 AState: TCDControlState; AStateEx: TCDPositionedCStateEx); override;
85 // TCDGroupBox
86 procedure DrawGroupBox(ADest: TFPCustomCanvas; ADestPos: TPoint; ASize: TSize;
87 AState: TCDControlState; AStateEx: TCDControlStateEx); override;
88 // TCDPanel
89 procedure DrawPanel(ADest: TCanvas; ASize: TSize;
90 AState: TCDControlState; AStateEx: TCDPanelStateEx); override;
91 // ===================================
92 // Additional Tab
93 // ===================================
94 procedure DrawStaticText(ADest: TCanvas; ASize: TSize;
95 AState: TCDControlState; AStateEx: TCDControlStateEx); override;
96 // ===================================
97 // Common Controls Tab
98 // ===================================
99 // TCDTrackBar
100 procedure DrawTrackBar(ADest: TCanvas; ASize: TSize;
101 AState: TCDControlState; AStateEx: TCDPositionedCStateEx); override;
102 // TCDProgressBar
103 procedure DrawProgressBar(ADest: TCanvas; ASize: TSize;
104 AState: TCDControlState; AStateEx: TCDProgressBarStateEx); override;
105 // TCDListView
106 procedure DrawListView(ADest: TCanvas; ASize: TSize;
107 AState: TCDControlState; AStateEx: TCDListViewStateEx); override;
108 procedure DrawReportListView(ADest: TCanvas; ADestPos: TPoint; ASize: TSize;
109 AState: TCDControlState; AStateEx: TCDListViewStateEx); override;
110 procedure DrawReportListViewItem(ADest: TCanvas; ADestPos: TPoint; ASize: TSize;
111 ACurItem: TCDListItems; AState: TCDControlState; AStateEx: TCDListViewStateEx); override;
112 // TCDToolBar
113 procedure DrawToolBar(ADest: TCanvas; ASize: TSize;
114 AState: TCDControlState; AStateEx: TCDToolBarStateEx); override;
115 procedure DrawToolBarItem(ADest: TCanvas; ASize: TSize;
116 ACurItem: TCDToolBarItem; AX, AY: Integer;
117 AState: TCDControlState; AStateEx: TCDToolBarStateEx); override;
118 // TCDCustomTabControl
119 procedure DrawCTabControl(ADest: TCanvas; ASize: TSize;
120 AState: TCDControlState; AStateEx: TCDCTabControlStateEx); override;
121 procedure DrawCTabControlFrame(ADest: TCanvas; ADestPos: TPoint; ASize: TSize;
122 AState: TCDControlState; AStateEx: TCDCTabControlStateEx); override;
123 procedure DrawTabSheet(ADest: TCanvas; ADestPos: TPoint; ASize: TSize;
124 AState: TCDControlState; AStateEx: TCDCTabControlStateEx); override;
125 procedure DrawTabs(ADest: TCanvas; ADestPos: TPoint; ASize: TSize;
126 AState: TCDControlState; AStateEx: TCDCTabControlStateEx); override;
127 procedure DrawTab(ADest: TCanvas; ADestPos: TPoint; ASize: TSize;
128 AState: TCDControlState; AStateEx: TCDCTabControlStateEx); override;
129 // ===================================
130 // Misc Tab
131 // ===================================
132 procedure DrawSpinEdit(ADest: TCanvas; ADestPos: TPoint; ASize: TSize;
133 AState: TCDControlState; AStateEx: TCDSpinStateEx); override;
134 end;
135
136 implementation
137
138 const
139 WIN2000_FRAME_WHITE = clWhite;
140 WIN2000_FRAME_LIGHT_GRAY = $00E2EFF1;
141 WIN2000_FRAME_GRAY = $0099A8AC;
142 WIN2000_FRAME_DARK_GRAY = $00646F71;
143
144 WIN2000_DISABLED_TEXT = WIN2000_FRAME_GRAY;
145
146 WIN2000_SELECTION_BACKGROUND = $00C56A31;
147
148 WIN2000_SCROLLBAR_BACKGROUND = $00ECF4F6;
149 WIN2000_LIGHTGRAY_BACKGROUND = $00ECF4F6;
150
151 WIN2000_PROGRESSBAR_BLUE = $00C56A31;
152
153 WIN2000_BTNFACE = $00D8E9EC;
154
155 WIN2000_FORM = WIN2000_BTNFACE;
156
157 { TCDDrawerCommon }
158
PalDefaultUsesNativePalettenull159 function TCDDrawerCommon.PalDefaultUsesNativePalette: Boolean;
160 begin
161 {$ifdef MSWindows}
162 Result := True;
163 {$else}
164 Result := False;
165 {$endif}
166 end;
167
168 procedure TCDDrawerCommon.LoadFallbackPaletteColors;
169 begin
170 Palette.ScrollBar := $C8D0D4;
171 Palette.Background := $984E00;
172 Palette.ActiveCaption := $E35400;
173 Palette.InactiveCaption := $DF967A;
174 Palette.Menu := $FFFFFF;
175 Palette.Window := clWhite; // The inside of a Edit control, for example
176 Palette.WindowFrame := $0;
177 Palette.MenuText := $0;
178 Palette.WindowText := $0;
179 Palette.CaptionText := $FFFFFF;
180 Palette.ActiveBorder := $C8D0D4;
181 Palette.InactiveBorder := $C8D0D4;
182 Palette.AppWorkspace := $808080;
183 Palette.Highlight := $C56A31;
184 Palette.HighlightText := $FFFFFF;
185 Palette.BtnFace := WIN2000_BTNFACE;
186 Palette.BtnShadow := $99A8AC;
187 Palette.GrayText := $99A8AC;
188 Palette.BtnText := $0;
189 Palette.InactiveCaptionText := $F8E4D8;
190 Palette.BtnHighlight := $FFFFFF;
191 Palette.color3DDkShadow := $646F71;
192 Palette.color3DLight := $E2EFF1;
193 Palette.InfoText := $0;
194 Palette.InfoBk := $E1FFFF;
195 //
196 Palette.HotLight := $800000;
197 Palette.GradientActiveCaption := $FF953D;
198 Palette.GradientInactiveCaption := $EBB99D;
199 Palette.MenuHighlight := $C56A31;
200 Palette.MenuBar := $D8E9EC;
201 Palette.Form := WIN2000_FORM;
202 end;
203
GetMeasuresnull204 function TCDDrawerCommon.GetMeasures(AMeasureID: Integer): Integer;
205 begin
206 case AMeasureID of
207 TCDEDIT_LEFT_TEXT_SPACING: Result := 6;
208 TCDEDIT_RIGHT_TEXT_SPACING: Result := 3;
209 TCDEDIT_TOP_TEXT_SPACING: Result := 3;
210 TCDEDIT_BOTTOM_TEXT_SPACING: Result := 3;
211 //
212 TCDCHECKBOX_SQUARE_HALF_HEIGHT: Result := Floor(GetMeasures(TCDCHECKBOX_SQUARE_HEIGHT)/2);
213 TCDCHECKBOX_SQUARE_HEIGHT: Result := DPIAdjustment(15);
214 //
215 TCDCOMBOBOX_DEFAULT_HEIGHT: Result := 21;
216 //
217 TCDRADIOBUTTON_CIRCLE_HEIGHT: Result := 15;
218 //
219 TCDSCROLLBAR_BUTTON_WIDTH: Result := 17;
220 TCDSCROLLBAR_LEFT_SPACING: Result := 17;
221 TCDSCROLLBAR_RIGHT_SPACING: Result := 17;
222 TCDSCROLLBAR_LEFT_BUTTON_POS: Result := 0;
223 TCDSCROLLBAR_RIGHT_BUTTON_POS: Result := -17;
224 //
225 TCDTRACKBAR_LEFT_SPACING: Result := 9;
226 TCDTRACKBAR_RIGHT_SPACING: Result := 9;
227 TCDTRACKBAR_TOP_SPACING: Result := 5;
228 TCDTRACKBAR_FRAME_HEIGHT: Result := DPIAdjustment(17);
229 //
230 TCDLISTVIEW_COLUMN_LEFT_SPACING: Result := 10;
231 TCDLISTVIEW_COLUMN_RIGHT_SPACING: Result := 10;
232 TCDLISTVIEW_COLUMN_TEXT_LEFT_SPACING: Result := 5;
233 TCDLISTVIEW_LINE_TOP_SPACING: Result := 3;
234 TCDLISTVIEW_LINE_BOTTOM_SPACING: Result := 3;
235 //
236 TCDTOOLBAR_ITEM_SPACING: Result := 2;
237 TCDTOOLBAR_ITEM_ARROW_WIDTH: Result := 7;
238 TCDTOOLBAR_ITEM_BUTTON_DEFAULT_WIDTH: Result := 23;
239 TCDTOOLBAR_ITEM_ARROW_RESERVED_WIDTH: Result := 35 - 23;
240 TCDTOOLBAR_ITEM_SEPARATOR_DEFAULT_WIDTH: Result := 8;
241 TCDTOOLBAR_DEFAULT_HEIGHT: Result := 26;
242 //
243 TCDCTABCONTROL_CLOSE_TAB_BUTTON_WIDTH: Result := 10;
244 TCDCTABCONTROL_CLOSE_TAB_BUTTON_EXTRA_SPACING: Result := 10;
245 else
246 Result := 0;
247 end;
248 end;
249
TCDDrawerCommon.GetMeasuresExnull250 function TCDDrawerCommon.GetMeasuresEx(ADest: TCanvas; AMeasureID: Integer;
251 AState: TCDControlState; AStateEx: TCDControlStateEx): Integer;
252 const
253 TCDTabControl_Common_TabCaptionExtraWidth = 20;
254 var
255 ATabsStateEx: TCDCTabControlStateEx absolute AStateEx;
256 lCaption: String;
257 lTabWidth, i, t: Integer;
258 IsPainting: Boolean = False;
259 begin
260 ADest.Font.Assign(AStateEx.Font);
261
262 case AMeasureID of
263 TCDCONTROL_CAPTION_WIDTH: Result := ADest.TextWidth(AStateEx.Caption);
264 TCDCONTROL_CAPTION_HEIGHT: Result := ADest.TextHeight(cddTestStr);
265 TCDCTABCONTROL_TAB_HEIGHT: Result := ADest.TextHeight(cddTestStr)+10;
266 TCDCTABCONTROL_TAB_WIDTH:
267 begin
268 if ATabsStateEx.CurTabIndex < ATabsStateEx.TabCount then
269 begin
270 lCaption := ATabsStateEx.Tabs.Strings[ATabsStateEx.CurTabIndex];
271 Result := ADest.TextWidth(lCaption) + TCDTabControl_Common_TabCaptionExtraWidth;
272 if (nboShowCloseButtons in ATabsStateEx.Options) then
273 Result := Result + GetMeasures(TCDCTABCONTROL_CLOSE_TAB_BUTTON_WIDTH)
274 + GetMeasures(TCDCTABCONTROL_CLOSE_TAB_BUTTON_EXTRA_SPACING);
275 end
276 // in any other case we are referring to the aditional + button for adding a new tab
277 else
278 Result := ADest.TextWidth('+') + TCDTabControl_Common_TabCaptionExtraWidth;
279 end;
280 TCDCTABCONTROL_TAB_LEFT_POS:
281 begin
282 Result := 0;
283 for i := 0 to ATabsStateEx.CurTabIndex-1 do
284 begin
285 if i = ATabsStateEx.LeftmostTabVisibleIndex then IsPainting := True;
286
287 if IsPainting then
288 begin
289 t := ATabsStateEx.CurTabIndex;
290 ATabsStateEx.CurTabIndex := i;
291 Result := Result + GetMeasuresEx(ADest, TCDCTABCONTROL_TAB_WIDTH, AState, AStateEx);
292 ATabsStateEx.CurTabIndex := t;
293 end;
294 end;
295 end;
296 TCDCTABCONTROL_CLOSE_BUTTON_POS_X:
297 begin
298 lTabWidth := GetMeasuresEx(ADest, TCDCTABCONTROL_TAB_WIDTH, AState, AStateEx);
299 Result := GetMeasuresEx(ADest, TCDCTABCONTROL_TAB_LEFT_POS, AState, AStateEx)
300 +lTabWidth
301 -GetMeasures(TCDCTABCONTROL_CLOSE_TAB_BUTTON_WIDTH)
302 -GetMeasures(TCDCTABCONTROL_CLOSE_TAB_BUTTON_EXTRA_SPACING);
303 end;
304 TCDCTABCONTROL_CLOSE_BUTTON_POS_Y:
305 begin
306 if ATabsStateEx.TabIndex = ATabsStateEx.CurTabIndex then Result := 8
307 else Result := 10;
308 end;
309 else
310 Result := 0;
311 end;
312 end;
313
314 procedure TCDDrawerCommon.CalculatePreferredSize(ADest: TCanvas;
315 AControlId: TCDControlID; AState: TCDControlState;
316 AStateEx: TCDControlStateEx; var PreferredWidth, PreferredHeight: integer;
317 WithThemeSpace, AAllowUseOfMeasuresEx: Boolean);
318 begin
319 PreferredWidth := 0;
320 PreferredHeight := 0;
321
322 case AControlId of
323 // In the LCL TEdit AutoSizes only its Height, so follow this here
324 cidEdit: PreferredHeight := GetMeasuresEx(ADest, TCDCONTROL_CAPTION_HEIGHT, AState, AStateEx)+8;
325 cidCheckBox, cidRadioButton:
326 begin
327 if AStateEx.AutoSize and AAllowUseOfMeasuresEx then
328 begin
329 PreferredWidth := GetMeasures(TCDCHECKBOX_SQUARE_HEIGHT);
330 PreferredWidth := PreferredWidth
331 + GetMeasuresEx(ADest, TCDCONTROL_CAPTION_WIDTH, AState, AStateEx) + 6;
332 end;
333
334 PreferredHeight := GetMeasures(TCDCHECKBOX_SQUARE_HEIGHT);
335 if AAllowUseOfMeasuresEx then
336 PreferredHeight := Max(PreferredHeight,
337 GetMeasuresEx(ADest, TCDCONTROL_CAPTION_HEIGHT, AState, AStateEx));
338 end;
339 // In the LCL TComboBox AutoSizes only its Height, so follow this here
340 cidComboBox:
341 begin
342 PreferredHeight := GetMeasures(TCDCOMBOBOX_DEFAULT_HEIGHT);
343 if AAllowUseOfMeasuresEx then
344 PreferredHeight := Max(PreferredHeight,
345 GetMeasuresEx(ADest, TCDCONTROL_CAPTION_HEIGHT, AState, AStateEx));
346 end;
347 end;
348 end;
349
GetColornull350 function TCDDrawerCommon.GetColor(AColorID: Integer): TColor;
351 begin
352 case AColorId of
353 TCDEDIT_BACKGROUND_COLOR: Result := clWhite;
354 TCDEDIT_TEXT_COLOR: Result := clBlack;
355 TCDEDIT_SELECTED_BACKGROUND_COLOR: Result := clBlue;
356 TCDEDIT_SELECTED_TEXT_COLOR: Result := clWhite;
357 TCDBUTTON_DEFAULT_COLOR: Result := $00F1F5F5;
358 else
359 Result := clBlack;
360 end;
361 end;
362
TCDDrawerCommon.GetClientAreanull363 function TCDDrawerCommon.GetClientArea(ADest: TCanvas; ASize: TSize;
364 AControlId: TCDControlID; AState: TCDControlState; AStateEx: TCDControlStateEx
365 ): TRect;
366 begin
367 Result := Bounds(0, 0, ASize.cx, ASize.cy);
368
369 case AControlId of
370 cidCTabControl:
371 begin
372 Result.Top := GetMeasuresEx(ADest, TCDCTABCONTROL_TAB_HEIGHT, AState, AStateEx) + 2;
373 Result.Left := 2;
374 Result.Right := Result.Right - 2;
375 Result.Bottom := Result.Bottom - 2;
376 end;
377 end;
378 end;
379
DPIAdjustmentnull380 function TCDDrawerCommon.DPIAdjustment(const AValue: Integer): Integer;
381 begin
382 if Screen.PixelsPerInch <= 125 then Result := AValue
383 else Result := Round(AValue * Screen.PixelsPerInch / 125);
384 end;
385
386 procedure TCDDrawerCommon.DrawFocusRect(ADest: TFPCustomCanvas; ADestPos: TPoint;
387 ASize: TSize);
388 begin
389 ADest.Pen.FPColor := colWhite;
390 ADest.Pen.Style := psSolid;
391 ADest.Brush.Style := bsClear;
392 ADest.Rectangle(ADestPos.X, ADestPos.Y, ADestPos.X + ASize.CX, ADestPos.Y + ASize.CY);
393 ADest.Pen.FPColor := colBlack;
394 ADest.Pen.Style := psDot;
395 ADest.Rectangle(ADestPos.X, ADestPos.Y, ADestPos.X + ASize.CX, ADestPos.Y + ASize.CY);
396 end;
397
398 procedure TCDDrawerCommon.DrawRaisedFrame(ADest: TCanvas; ADestPos: TPoint;
399 ASize: TSize);
400 begin
401 // white lines in the left and top
402 ADest.Pen.Style := psSolid;
403 ADest.Brush.Style := bsClear;
404 ADest.Pen.Color := WIN2000_FRAME_WHITE;
405 ADest.MoveTo(ADestPos.X, ADestPos.Y+ASize.cy-1);
406 ADest.LineTo(ADestPos.X, ADestPos.Y);
407 ADest.LineTo(ADestPos.X+ASize.cx-1, ADestPos.Y);
408 // Grey line on the inside left and top
409 ADest.Pen.Color := WIN2000_FRAME_LIGHT_GRAY;
410 ADest.MoveTo(ADestPos.X+1, ADestPos.Y+ASize.cy-2);
411 ADest.LineTo(ADestPos.X+1, ADestPos.Y+1);
412 ADest.LineTo(ADestPos.X+ASize.cx-1, ADestPos.Y+1);
413 // Dark grey line on the right and bottom
414 ADest.Pen.Color := WIN2000_FRAME_DARK_GRAY;
415 ADest.MoveTo(ADestPos.X, ADestPos.Y+ASize.cy-1);
416 ADest.LineTo(ADestPos.X+ASize.cx-1, ADestPos.Y+ASize.cy-1);
417 ADest.LineTo(ADestPos.X+ASize.cx-1, ADestPos.Y);
418 // Grey line on the inside right and bottom
419 ADest.Pen.Color := WIN2000_FRAME_GRAY;
420 ADest.MoveTo(ADestPos.X+1, ADestPos.Y+ASize.cy-2);
421 ADest.LineTo(ADestPos.X+ASize.cx-2, ADestPos.Y+ASize.cy-2);
422 ADest.LineTo(ADestPos.X+ASize.cx-2, ADestPos.Y-1);
423 end;
424
425 procedure TCDDrawerCommon.DrawFrame3D(ADest: TFPCustomCanvas; ADestPos: TPoint; ASize: TSize;
426 const FrameWidth : integer; const Style : TBevelCut);
427 var
428 i: Integer;
429 ARect: TRect;
430 begin
431 ARect := Bounds(ADestPos.X, ADestPos.Y, ASize.cx, ASize.cy);
432 for i := 0 to FrameWidth-1 do
433 begin
434 case Style of
435 bvLowered:
436 begin
437 // white lines in the left and top
438 ADest.Pen.Style := psSolid;
439 ADest.Brush.Style := bsClear;
440 ADest.Pen.FPColor := TColorToFPColor(WIN2000_FRAME_GRAY);
441 ADest.MoveTo(ARect.Left, ARect.Bottom);
442 ADest.LineTo(ARect.Left, ARect.Top);
443 ADest.LineTo(ARect.Right, ARect.Top);
444 // Dark grey line on the right and bottom
445 ADest.Pen.FPColor := TColorToFPColor(WIN2000_FRAME_WHITE);
446 ADest.MoveTo(ARect.Left, ARect.Bottom);
447 ADest.LineTo(ARect.Right, ARect.Bottom);
448 ADest.LineTo(ARect.Right, ARect.Top);
449 end;
450 bvRaised:
451 begin
452 // white lines in the left and top
453 ADest.Pen.Style := psSolid;
454 ADest.Brush.Style := bsClear;
455 ADest.Pen.FPColor := TColorToFPColor(WIN2000_FRAME_WHITE);
456 ADest.MoveTo(ARect.Left, ARect.Bottom);
457 ADest.LineTo(ARect.Left, ARect.Top);
458 ADest.LineTo(ARect.Right, ARect.Top);
459 // Dark grey line on the right and bottom
460 ADest.Pen.FPColor := TColorToFPColor(WIN2000_FRAME_GRAY);
461 ADest.MoveTo(ARect.Left, ARect.Bottom);
462 ADest.LineTo(ARect.Right, ARect.Bottom);
463 ADest.LineTo(ARect.Right, ARect.Top);
464 end;
465 bvSpace:
466 begin
467 end;
468 end;
469
470 InflateRect(ARect, -1, -1);
471 end;
472 end;
473
474 procedure TCDDrawerCommon.DrawSunkenFrame(ADest: TCanvas; ADestPos: TPoint;
475 ASize: TSize);
476 begin
477 // The Frame, except the lower-bottom which is white anyway
478 // outter top-right
479 ADest.Pen.Style := psSolid;
480 ADest.Pen.Color := WIN2000_FRAME_GRAY;
481 ADest.MoveTo(ADestPos.X, ADestPos.Y+ASize.cy-1);
482 ADest.LineTo(ADestPos.X, ADestPos.Y);
483 ADest.LineTo(ADestPos.X+ASize.cx-1, ADestPos.Y);
484 // inner top-right
485 ADest.Pen.Color := WIN2000_FRAME_DARK_GRAY;
486 ADest.MoveTo(ADestPos.X+1, ADestPos.Y+ASize.cy-2);
487 ADest.LineTo(ADestPos.X+1, ADestPos.Y+1);
488 ADest.LineTo(ADestPos.X+ASize.cx-2, ADestPos.Y+1);
489 // inner bottom-right
490 ADest.Pen.Color := WIN2000_FRAME_LIGHT_GRAY;
491 ADest.MoveTo(ADestPos.X+1, ADestPos.Y+ASize.cy-2);
492 ADest.LineTo(ADestPos.X+ASize.cx-2, ADestPos.Y+ASize.cy-2);
493 ADest.LineTo(ADestPos.X+ASize.cx-2, ADestPos.Y);
494 // outter bottom-right
495 ADest.Pen.Color := WIN2000_FRAME_WHITE;
496 ADest.MoveTo(ADestPos.X+1, ADestPos.Y+ASize.cy-1);
497 ADest.LineTo(ADestPos.X+ASize.cx-1, ADestPos.Y+ASize.cy-1);
498 ADest.LineTo(ADestPos.X+ASize.cx-1, ADestPos.Y);
499 end;
500
501 procedure TCDDrawerCommon.DrawShallowSunkenFrame(ADest: TCanvas;
502 ADestPos: TPoint; ASize: TSize);
503 begin
504 // Inside area, there is no background because the control occupies the entire area
505 ADest.Pen.Style := psSolid;
506 ADest.Pen.Color := WIN2000_FRAME_GRAY;
507 ADest.MoveTo(ADestPos.X, ADestPos.Y + ASize.cy);
508 ADest.LineTo(ADestPos.X, ADestPos.Y);
509 ADest.LineTo(ADestPos.X + ASize.cx, ADestPos.Y);
510 ADest.Pen.Color := WIN2000_FRAME_WHITE;
511 ADest.MoveTo(ADestPos.X, ADestPos.Y + ASize.cy-1);
512 ADest.LineTo(ADestPos.X + ASize.cx-1, ADestPos.Y + ASize.cy-1);
513 ADest.LineTo(ADestPos.X + ASize.cx-1, ADestPos.Y-1);
514 end;
515
516 procedure TCDDrawerCommon.DrawTickmark(ADest: TFPCustomCanvas; ADestPos: TPoint; AState: TCDControlState);
517 var
518 i: Integer;
519 lSpacing5, lFirstLinesEnd, lSecondLinesEnd: Integer;
520 begin
521 if csfPartiallyOn in AState then
522 ADest.Pen.FPColor := TColorToFPColor(WIN2000_FRAME_GRAY)
523 else
524 ADest.Pen.FPColor := colBlack;
525 ADest.Pen.Style := psSolid;
526
527 if Screen.PixelsPerInch <= 125 then
528 begin
529 // 4 lines going down and to the right
530 for i := 0 to 3 do
531 ADest.Line(ADestPos.X+1+i, ADestPos.Y+2+i, ADestPos.X+1+i, ADestPos.Y+5+i);
532 // Now 5 lines going up and to the right
533 for i := 4 to 8 do
534 ADest.Line(ADestPos.X+1+i, ADestPos.Y+2+6-i, ADestPos.X+1+i, ADestPos.Y+5+6-i);
535 Exit;
536 end;
537
538 lSpacing5 := DPIAdjustment(5);
539 lFirstLinesEnd := DPIAdjustment(4)-1;
540 lSecondLinesEnd := DPIAdjustment(9)-1;
541
542 // 4 lines going down and to the right
543 for i := 0 to lFirstLinesEnd do
544 ADest.Line(ADestPos.X+2+i, ADestPos.Y+2+i, ADestPos.X+2+i, ADestPos.Y+lSpacing5+i);
545 // Now 5 lines going up and to the right
546 for i := lFirstLinesEnd+1 to lSecondLinesEnd do
547 ADest.Line(ADestPos.X+2+i, ADestPos.Y+2+lFirstLinesEnd*2-i, ADestPos.X+2+i, ADestPos.Y+2+lFirstLinesEnd*2+lSpacing5-i);
548 end;
549
550 procedure TCDDrawerCommon.DrawSlider(ADest: TCanvas; ADestPos: TPoint;
551 ASize: TSize; AState: TCDControlState);
552 var
553 lPoints: array[0..4] of TPoint;
554 lSliderBottom: Integer;
555 lSpacing5, lSpacing10: Integer;
556 begin
557 lSpacing5 := (ASize.cx-1)div 2;
558 lSpacing10 := (ASize.cx-1);
559
560 ADest.Brush.Color := Palette.BtnFace;
561 ADest.Brush.Style := bsSolid;
562 ADest.Pen.Color := WIN2000_FRAME_WHITE;
563
564 if csfHorizontal in AState then
565 begin
566 lSliderBottom := ADestPos.Y+ASize.CY;
567 // outter white frame
568 lPoints[0] := Point(ADestPos.X+lSpacing5, lSliderBottom);
569 lPoints[1] := Point(ADestPos.X, lSliderBottom-lSpacing5);
570 lPoints[2] := Point(ADestPos.X, ADestPos.Y);
571 lPoints[3] := Point(ADestPos.X+lSpacing10, ADestPos.Y);
572 lPoints[4] := Point(ADestPos.X+lSpacing10, lSliderBottom-lSpacing5);
573 ADest.Polygon(lPoints);
574 // left-top inner frame
575 ADest.Pen.Color := WIN2000_FRAME_LIGHT_GRAY;
576 ADest.MoveTo(ADestPos.X+lSpacing5, lSliderBottom-1);
577 ADest.LineTo(ADestPos.X+1, lSliderBottom-lSpacing5);
578 ADest.LineTo(ADestPos.X+1, ADestPos.Y+1);
579 ADest.LineTo(ADestPos.X+lSpacing10-1, ADestPos.Y+1);
580 // right inner frame
581 ADest.Pen.Color := WIN2000_FRAME_GRAY;
582 ADest.MoveTo(ADestPos.X+lSpacing5, lSliderBottom-1);
583 ADest.LineTo(ADestPos.X+lSpacing10-1, lSliderBottom-lSpacing5);
584 ADest.LineTo(ADestPos.X+lSpacing10-1, ADestPos.Y);
585 // right outter frame
586 ADest.Pen.Color := WIN2000_FRAME_DARK_GRAY;
587 ADest.MoveTo(ADestPos.X+lSpacing5, lSliderBottom);
588 ADest.LineTo(ADestPos.X+lSpacing10, lSliderBottom-lSpacing5);
589 ADest.LineTo(ADestPos.X+lSpacing10, ADestPos.Y-1);
590 end
591 else
592 begin
593 lSliderBottom := ADestPos.Y+ASize.CY;
594 // outter white frame
595 lPoints[0] := Point(lSliderBottom, ADestPos.X+lSpacing5);
596 lPoints[1] := Point(lSliderBottom-lSpacing5, ADestPos.X);
597 lPoints[2] := Point(ADestPos.Y, ADestPos.X);
598 lPoints[3] := Point(ADestPos.Y, ADestPos.X+lSpacing10);
599 lPoints[4] := Point(lSliderBottom-lSpacing5, ADestPos.X+lSpacing10);
600 ADest.Polygon(lPoints);
601 // left-top inner frame
602 ADest.Pen.Color := WIN2000_FRAME_LIGHT_GRAY;
603 ADest.MoveTo(lSliderBottom-1, ADestPos.X+lSpacing5);
604 ADest.LineTo(lSliderBottom-lSpacing5, ADestPos.X+1);
605 ADest.LineTo(ADestPos.Y+1, ADestPos.X+1);
606 ADest.LineTo(ADestPos.Y+1, ADestPos.X+lSpacing10-1);
607 // right inner frame
608 ADest.Pen.Color := WIN2000_FRAME_GRAY;
609 ADest.MoveTo(lSliderBottom-1, ADestPos.X+lSpacing5);
610 ADest.LineTo(lSliderBottom-lSpacing5, ADestPos.X+lSpacing10-1);
611 ADest.LineTo(ADestPos.Y, ADestPos.X+lSpacing10-1);
612 // right outter frame
613 ADest.Pen.Color := WIN2000_FRAME_DARK_GRAY;
614 ADest.MoveTo(lSliderBottom, ADestPos.X+lSpacing5);
615 ADest.LineTo(lSliderBottom-lSpacing5, ADestPos.X+lSpacing10);
616 ADest.LineTo(ADestPos.Y-1, ADestPos.X+lSpacing10);
617 end;
618 end;
619
620 procedure TCDDrawerCommon.DrawArrow(ADest: TCanvas; ADestPos: TPoint;
621 ADirection: TCDControlState; ASize: Integer = 7);
622 var
623 lPoints: array[0..2] of TPoint;
624 lPos: TPoint;
625 lSize, lSizeHalf: Integer;
626 begin
627 lPos := ADestPos;
628 lSize := ASize - 1;
629 lSizeHalf := ASize div 2;
630 // Move the arrow a little bit when a sunken state is passed
631 if csfSunken in ADirection then lPos := Point(lPos.X+1, lPos.Y+1);
632
633 if csfLeftArrow in ADirection then
634 begin
635 lPoints[0] := Point(lPos.X, lPos.Y+lSizeHalf);// left point
636 lPoints[1] := Point(lPos.X+lSizeHalf, lPos.Y+lSize);// lower point
637 lPoints[2] := Point(lPos.X+lSizeHalf, lPos.Y); // upper point
638 end
639 else if csfRightArrow in ADirection then
640 begin
641 lPoints[0] := Point(lPos.X+1, lPos.Y); // upper point
642 lPoints[1] := Point(lPos.X+1, lPos.Y+lSize);// lower point
643 lPoints[2] := Point(lPos.X+1+lSizeHalf, lPos.Y+lSizeHalf);// right point
644 end
645 else if csfUpArrow in ADirection then
646 begin
647 lPoints[0] := Point(lPos.X+lSizeHalf, lPos.Y); // upper point
648 lPoints[1] := Point(lPos.X, lPos.Y+lSizeHalf);// left point
649 lPoints[2] := Point(lPos.X+lSize, lPos.Y+lSizeHalf);// right point
650 end
651 else // downArrow
652 begin
653 lPoints[0] := Point(lPos.X, lPos.Y+1);// left point
654 lPoints[1] := Point(lPos.X+lSize, lPos.Y+1);// right point
655 lPoints[2] := Point(lPos.X+lSizeHalf, lPos.Y+1+lSizeHalf);// lower point
656 end;
657 ADest.Brush.Style := bsSolid;
658 ADest.Brush.Color := clBlack;
659 ADest.Pen.Style := psSolid;
660 ADest.Pen.Color := clBlack;
661 ADest.Polygon(lPoints);
662 end;
663
664 procedure TCDDrawerCommon.DrawSmallCloseButton(ADest: TCanvas; ADestPos: TPoint);
665 begin
666 ADest.Pen.Style := psSolid;
667 ADest.Pen.Color := clGray;
668 ADest.Pen.Width := 4;
669 ADest.Line(ADestPos.X, ADestPos.Y, ADestPos.X+10, ADestPos.Y+10);
670 ADest.Line(ADestPos.X+9, ADestPos.Y, ADestPos.X-1, ADestPos.Y+10);
671 ADest.Pen.Width := 1;
672 end;
673
674 procedure TCDDrawerCommon.DrawButtonWithArrow(ADest: TCanvas; ADestPos: TPoint;
675 ASize: TSize; AState: TCDControlState);
676 begin
677 // First the background color
678 ADest.Brush.Color := WIN2000_BTNFACE;
679 ADest.Brush.Style := bsSolid;
680 ADest.FillRect(Bounds(ADestPos.X, ADestPos.Y, ASize.CX, ASize.CY));
681
682 // Now the button frame
683 if csfSunken in AState then DrawSunkenFrame(ADest, ADestPos, ASize)
684 else DrawRaisedFrame(ADest, ADestPos, ASize);
685
686 // Now the arrow
687 DrawArrow(ADest, Point(ADestPos.X + ASize.CY div 4, ADestPos.Y + ASize.CY * 3 div 8), AState, ASize.CY div 2);
688 end;
689
690 procedure TCDDrawerCommon.DrawControl(ADest: TCanvas;
691 ASize: TSize; AState: TCDControlState; AStateEx: TCDControlStateEx);
692 var
693 lColor: TColor;
694 begin
695 // Background
696 lColor := AStateEx.RGBColor;
697 ADest.Brush.Color := lColor;
698 ADest.Brush.Style := bsSolid;
699 ADest.Pen.Style := psSolid;
700 ADest.Pen.Color := lColor;
701 ADest.FillRect(0, 0, ASize.cx, ASize.cy);
702 end;
703
704 procedure TCDDrawerCommon.DrawButton(ADest: TFPCustomCanvas;
705 ADestPos: TPoint; ASize: TSize; AState: TCDControlState; AStateEx: TCDButtonStateEx);
706 var
707 Str: string;
708 lGlyphLeftSpacing: Integer = 0;
709 lGlyphExtra: Integer = 0;
710 lTextOutPos: TPoint;
711 lGlyphCaptionHeight: Integer;
712 begin
713 // background
714 ADest.Brush.Style := bsSolid;
715 ADest.Brush.FPColor := AStateEx.FPRGBColor;
716 ADest.Pen.FPColor := colWhite;
717 ADest.Pen.Style := psSolid;
718 ADest.Rectangle(0, 0, ASize.cx - 1, ASize.cy - 1);
719 ADest.Pen.FPColor := colWhite;
720 ADest.Line(0, 0, ASize.cx - 1, 0);
721 ADest.Line(0, 0, 0, ASize.cy - 1);
722 ADest.Pen.FPColor := colGray;
723 ADest.Line(0, ASize.cy - 1, ASize.cx - 1, ASize.cy - 1);
724 ADest.Line(ASize.cx - 1, ASize.cy - 1, ASize.cx - 1, -1);
725 ADest.Pen.FPColor := TColorToFPColor($0099A8AC);
726 ADest.Line(1, ASize.cy - 2, ASize.cx - 2, ASize.cy - 2);
727 ADest.Line(ASize.cx - 2, ASize.cy - 2, ASize.cx - 2, 0);
728 ADest.Pen.FPColor := TColorToFPColor($00E2EFF1);
729 ADest.Line(1, 1, ASize.cx - 2, 1);
730 ADest.Line(1, 1, 1, ASize.cy - 2);
731
732 // Button image
733 if csfSunken in AState then
734 begin
735 ADest.Brush.Style := bsSolid;
736 ADest.Brush.FPColor := AStateEx.FPRGBColor;
737 ADest.Pen.FPColor := colWhite;
738 ADest.Pen.Style := psSolid;
739 ADest.Rectangle(0, 0, ASize.cx - 1, ASize.cy - 1);
740 ADest.Pen.FPColor := colGray;
741 ADest.Line(0, 0, ASize.cx - 1, 0);
742 ADest.Line(0, 0, 0, ASize.cy - 1);
743 ADest.Pen.FPColor := colWhite;
744 ADest.Line(0, ASize.cy - 1, ASize.cx - 1, ASize.cy - 1);
745 ADest.Line(ASize.cx - 1, ASize.cy - 1, ASize.cx - 1, -1);
746 ADest.Pen.FPColor := TColorToFPColor($00E2EFF1);
747 ADest.Line(1, ASize.cy - 2, ASize.cx - 2, ASize.cy - 2);
748 ADest.Line(ASize.cx - 2, ASize.cy - 2, ASize.cx - 2, 0);
749 ADest.Pen.FPColor := TColorToFPColor($0099A8AC);
750 ADest.Line(1, 1, ASize.cx - 2, 1);
751 ADest.Line(1, 1, 1, ASize.cy - 2);
752 end
753 else if csfHasFocus in AState then
754 begin
755 if ADest is TCanvas then
756 DrawFocusRect(TCanvas(ADest), Point(3, 3), Size(ASize.cx - 7, ASize.cy - 7));
757 end;
758
759 // Position calculations
760 if ADest is TCanvas then
761 begin
762 ADest.Font.Assign(AStateEx.Font);
763 Str := AStateEx.Caption;
764 lGlyphCaptionHeight := Max(TCanvas(ADest).TextHeight(Str), AStateEx.Glyph.Height);
765 lTextOutPos.X := (ASize.cx - TCanvas(ADest).TextWidth(Str) - AStateEx.Glyph.Width) div 2;
766 lTextOutPos.Y := (ASize.cy - lGlyphCaptionHeight) div 2;
767 lTextOutPos.X := Max(lTextOutPos.X, 5);
768 lTextOutPos.Y := Max(lTextOutPos.Y, 5);
769
770 // Button glyph
771 if not AStateEx.Glyph.Empty then
772 begin
773 if csfSunken in AState then lGlyphExtra := 1;
774 TCanvas(ADest).Draw(lTextOutPos.X + lGlyphExtra, lTextOutPos.Y + lGlyphExtra, AStateEx.Glyph);
775 lGlyphLeftSpacing := AStateEx.Glyph.Width+5;
776 end;
777
778 // Button text
779 lTextOutPos.X := lTextOutPos.X + lGlyphLeftSpacing;
780 lTextOutPos.Y := (ASize.cy - TCanvas(ADest).TextHeight(Str)) div 2;
781 ADest.Brush.Style := bsClear;
782 ADest.Pen.Style := psSolid;
783 if csfEnabled in AState then
784 begin
785 if csfSunken in AState then
786 begin
787 Inc(lTextOutPos.X);
788 Inc(lTextOutPos.Y);
789 end;
790 ADest.TextOut(lTextOutPos.X, lTextOutPos.Y, Str)
791 end
792 else
793 begin
794 // The disabled text is composed by a white shadow under it and a grey text
795 TCanvas(ADest).Font.Color := clWhite;
796 Inc(lTextOutPos.X);
797 Inc(lTextOutPos.Y);
798 TCanvas(ADest).TextOut(lTextOutPos.X, lTextOutPos.Y, Str);
799 //
800 TCanvas(ADest).Font.Color := WIN2000_DISABLED_TEXT;
801 Dec(lTextOutPos.X);
802 Dec(lTextOutPos.Y);
803 ADest.TextOut(lTextOutPos.X, lTextOutPos.Y, Str);
804 end;
805 end;
806 end;
807
808 procedure TCDDrawerCommon.DrawEditBackground(ADest: TCanvas;
809 ADestPos: TPoint; ASize: TSize; AState: TCDControlState;
810 AStateEx: TCDEditStateEx);
811 begin
812 // The background
813 ADest.Brush.Color := clWhite;
814 ADest.Brush.Style := bsSolid;
815 ADest.Pen.Color := WIN2000_FRAME_WHITE;
816 ADest.Pen.Style := psSolid;
817 ADest.Rectangle(0, 0, ASize.cx, ASize.cy);
818 end;
819
820 procedure TCDDrawerCommon.DrawEditFrame(ADest: TCanvas; ADestPos: TPoint;
821 ASize: TSize; AState: TCDControlState; AStateEx: TCDEditStateEx);
822 begin
823 // The Frame, except the lower-bottom which is white anyway
824 // outter top-right
825 ADest.Pen.Style := psSolid;
826 ADest.Pen.Color := WIN2000_FRAME_GRAY;
827 ADest.MoveTo(0, ASize.cy-1);
828 ADest.LineTo(0, 0);
829 ADest.LineTo(ASize.cx-1, 0);
830 // inner top-right
831 ADest.Pen.Color := WIN2000_FRAME_DARK_GRAY;
832 ADest.MoveTo(1, ASize.cy-2);
833 ADest.LineTo(1, 1);
834 ADest.LineTo(ASize.cx-2, 1);
835 // inner bottom-right
836 ADest.Pen.Color := WIN2000_FRAME_LIGHT_GRAY;
837 ADest.MoveTo(1, ASize.cy-2);
838 ADest.LineTo(ASize.cx-2, ASize.cy-2);
839 ADest.LineTo(ASize.cx-2, 0);
840 end;
841
842 procedure TCDDrawerCommon.DrawCaret(ADest: TCanvas; ADestPos: TPoint;
843 ASize: TSize; AState: TCDControlState; AStateEx: TCDEditStateEx);
844 var
845 lTextTopSpacing, lCaptionHeight, lLineHeight, lLineTop: Integer;
846 lControlText, lTmpText: string;
847 lTextBottomSpacing, lCaretPixelPos: Integer;
848 begin
849 if not AStateEx.CaretIsVisible then Exit;
850
851 if AStateEx.Lines.Count = 0 then lControlText := ''
852 else lControlText := AStateEx.Lines.Strings[AStateEx.CaretPos.Y];
853 lCaptionHeight := GetMeasuresEx(ADest, TCDCONTROL_CAPTION_HEIGHT, AState, AStateEx);
854 lTextBottomSpacing := GetMeasures(TCDEDIT_BOTTOM_TEXT_SPACING);
855 lTextTopSpacing := GetMeasures(TCDEDIT_TOP_TEXT_SPACING);
856 lLineHeight := ADest.TextHeight(cddTestStr)+2;
857 lLineHeight := Min(ASize.cy-lTextBottomSpacing, lLineHeight);
858 lLineTop := lTextTopSpacing + AStateEx.CaretPos.Y * lLineHeight;
859
860 lTmpText := UTF8Copy(lControlText, AStateEx.VisibleTextStart.X, AStateEx.CaretPos.X-AStateEx.VisibleTextStart.X+1);
861 lTmpText := VisibleText(lTmpText, AStateEx.PasswordChar);
862 lCaretPixelPos := ADest.TextWidth(lTmpText) + GetMeasures(TCDEDIT_LEFT_TEXT_SPACING)
863 + AStateEx.LeftTextMargin;
864 ADest.Pen.Color := clBlack;
865 ADest.Pen.Style := psSolid;
866 ADest.Line(lCaretPixelPos, lLineTop, lCaretPixelPos, lLineTop+lCaptionHeight);
867 end;
868
869 procedure TCDDrawerCommon.DrawEdit(ADest: TCanvas;
870 ASize: TSize; AState: TCDControlState; AStateEx: TCDEditStateEx);
871 var
872 lVisibleText, lControlText: TCaption;
873 lSelLeftPos, lSelLeftPixelPos, lSelLength, lSelRightPos: Integer;
874 lTextWidth, lLineHeight, lLineTop: Integer;
875 lControlTextLen: PtrInt;
876 lTextLeftSpacing, lTextTopSpacing, lTextBottomSpacing: Integer;
877 lTextColor: TColor;
878 i, lVisibleLinesCount: Integer;
879 begin
880 // Background
881 DrawEditBackground(ADest, Point(0, 0), ASize, AState, AStateEx);
882
883 // General text configurations which apply to all lines
884 // Configure the text color
885 if csfEnabled in AState then
886 lTextColor := AStateEx.Font.Color
887 else
888 lTextColor := WIN2000_DISABLED_TEXT;
889
890 ADest.Brush.Style := bsClear;
891 ADest.Font.Assign(AStateEx.Font);
892 ADest.Font.Color := lTextColor;
893 lTextLeftSpacing := GetMeasures(TCDEDIT_LEFT_TEXT_SPACING);
894 //lTextRightSpacing := GetMeasures(TCDEDIT_RIGHT_TEXT_SPACING);
895 lTextTopSpacing := GetMeasures(TCDEDIT_TOP_TEXT_SPACING);
896 lTextBottomSpacing := GetMeasures(TCDEDIT_BOTTOM_TEXT_SPACING);
897
898 lLineHeight := ADest.TextHeight(cddTestStr)+2;
899 lLineHeight := Min(ASize.cy-lTextBottomSpacing, lLineHeight);
900
901 // Fill this to be used in other parts
902 AStateEx.LineHeight := lLineHeight;
903 AStateEx.FullyVisibleLinesCount := ASize.cy - lTextTopSpacing - lTextBottomSpacing;
904 AStateEx.FullyVisibleLinesCount := AStateEx.FullyVisibleLinesCount div lLineHeight;
905 AStateEx.FullyVisibleLinesCount := Min(AStateEx.FullyVisibleLinesCount, AStateEx.Lines.Count);
906
907 // Calculate how many lines to draw
908 if AStateEx.Multiline then
909 lVisibleLinesCount := AStateEx.FullyVisibleLinesCount + 1
910 else
911 lVisibleLinesCount := 1;
912 lVisibleLinesCount := Min(lVisibleLinesCount, AStateEx.Lines.Count);
913
914 // Now draw each line
915 for i := 0 to lVisibleLinesCount - 1 do
916 begin
917 lControlText := AStateEx.Lines.Strings[AStateEx.VisibleTextStart.Y+i];
918 lControlText := VisibleText(lControlText, AStateEx.PasswordChar);
919 lControlTextLen := UTF8Length(lControlText);
920 lLineTop := lTextTopSpacing + i * lLineHeight;
921
922 // The text
923 ADest.Pen.Style := psClear;
924 ADest.Brush.Style := bsClear;
925 // ToDo: Implement multi-line selection
926 if (AStateEx.SelLength = 0) or (AStateEx.SelStart.Y <> AStateEx.VisibleTextStart.Y+i) then
927 begin
928 lVisibleText := UTF8Copy(lControlText, AStateEx.VisibleTextStart.X, lControlTextLen);
929 ADest.TextOut(lTextLeftSpacing, lLineTop, lVisibleText);
930 end
931 // Text and Selection
932 else
933 begin
934 lSelLeftPos := AStateEx.SelStart.X;
935 if AStateEx.SelLength < 0 then lSelLeftPos := lSelLeftPos + AStateEx.SelLength;
936
937 lSelRightPos := AStateEx.SelStart.X;
938 if AStateEx.SelLength > 0 then lSelRightPos := lSelRightPos + AStateEx.SelLength;
939
940 lSelLength := AStateEx.SelLength;
941 if lSelLength < 0 then lSelLength := lSelLength * -1;
942
943 // Text left of the selection
944 lVisibleText := UTF8Copy(lControlText, AStateEx.VisibleTextStart.X, lSelLeftPos-AStateEx.VisibleTextStart.X+1);
945 ADest.TextOut(lTextLeftSpacing, lLineTop, lVisibleText);
946 lSelLeftPixelPos := ADest.TextWidth(lVisibleText)+lTextLeftSpacing;
947
948 // The selection background
949 lVisibleText := UTF8Copy(lControlText, lSelLeftPos+1, lSelLength);
950 lTextWidth := ADest.TextWidth(lVisibleText);
951 ADest.Brush.Color := WIN2000_SELECTION_BACKGROUND;
952 ADest.Brush.Style := bsSolid;
953 ADest.Rectangle(Bounds(lSelLeftPixelPos, lLineTop, lTextWidth, lLineHeight));
954 ADest.Brush.Style := bsClear;
955
956 // The selection text
957 ADest.Font.Color := clWhite;
958 ADest.TextOut(lSelLeftPixelPos, lLineTop, lVisibleText);
959 lSelLeftPixelPos := lSelLeftPixelPos + lTextWidth;
960
961 // Text right of the selection
962 ADest.Brush.Color := clWhite;
963 ADest.Font.Color := lTextColor;
964 lVisibleText := UTF8Copy(lControlText, lSelLeftPos+lSelLength+1, lControlTextLen);
965 ADest.TextOut(lSelLeftPixelPos, lLineTop, lVisibleText);
966 end;
967 end;
968
969 // And the caret
970 DrawCaret(ADest, Point(0, 0), ASize, AState, AStateEx);
971
972 // In the end the frame, because it must be on top of everything
973 DrawEditFrame(ADest, Point(0, 0), ASize, AState, AStateEx);
974 end;
975
976 procedure TCDDrawerCommon.DrawCheckBoxSquare(ADest: TCanvas; ADestPos: TPoint;
977 ASize: TSize; AState: TCDControlState; AStateEx: TCDControlStateEx);
978 var
979 lHalf, lSquareHalf, lSquareHeight: Integer;
980 begin
981 lHalf := ASize.cy div 2;
982 lSquareHalf := GetMeasures(TCDCHECKBOX_SQUARE_HALF_HEIGHT);
983 lSquareHeight := GetMeasures(TCDCHECKBOX_SQUARE_HEIGHT);
984
985 // the square background
986 ADest.Pen.Style := psClear;
987 ADest.Brush.Style := bsSolid;
988 if csfPartiallyOn in AState then ADest.Brush.Color := WIN2000_LIGHTGRAY_BACKGROUND
989 else ADest.Brush.Color := Palette.Window;
990 ADest.Rectangle(Bounds(1, lHalf - lSquareHalf, lSquareHeight, lSquareHeight));
991
992 // the square frame
993 DrawSunkenFrame(ADest, Point(1, lHalf - lSquareHalf),
994 Size(lSquareHeight, lSquareHeight));
995
996 { // The selection inside the square
997 ADest.Brush.Style := bsClear;
998 ADest.Pen.Color := RGBToColor($31, $C6, $D6);
999 ADest.Pen.Style := psSolid;
1000 if csfHasFocus in AState then
1001 begin
1002 ADest.Rectangle(
1003 2,
1004 lHalf - lSquareHalf+1,
1005 lSquareHeight,
1006 lHalf + lSquareHalf-1);
1007 end;}
1008 end;
1009
1010 procedure TCDDrawerCommon.DrawCheckBox(ADest: TCanvas;
1011 ASize: TSize; AState: TCDControlState; AStateEx: TCDControlStateEx);
1012 var
1013 lColor: TColor;
1014 lSquareHeight, lValue3: Integer;
1015 lTextHeight, lTextY: Integer;
1016 begin
1017 lSquareHeight := GetMeasures(TCDCHECKBOX_SQUARE_HEIGHT);
1018 lValue3 := DPIAdjustment(3);
1019
1020 // Background
1021 lColor := AStateEx.ParentRGBColor;
1022 ADest.Brush.Color := lColor;
1023 ADest.Brush.Style := bsSolid;
1024 ADest.Pen.Style := psClear;
1025 ADest.FillRect(0, 0, ASize.cx, ASize.cy);
1026
1027 // The checkbox item itself
1028 DrawCheckBoxSquare(ADest, Point(0, 0), ASize, AState, AStateEx);
1029
1030 // The Tickmark
1031 if (csfOn in AState) or (csfPartiallyOn in AState) then
1032 DrawTickmark(ADest, Point(lValue3, ASize.cy div 2 - GetMeasures(TCDCHECKBOX_SQUARE_HALF_HEIGHT)+lValue3), AState);
1033
1034 // The text selection
1035 if csfHasFocus in AState then
1036 DrawFocusRect(ADest, Point(lSquareHeight+4, 0),
1037 Size(ASize.cx-lSquareHeight-4, ASize.cy));
1038
1039 // Now the text
1040 ADest.Brush.Style := bsClear;
1041 ADest.Pen.Style := psClear;
1042 ADest.Font.Assign(AStateEx.Font);
1043 lTextHeight := ADest.TextHeight(cddTestStr);
1044 // put the text in the center
1045 if lSquareHeight > lTextHeight then lTextY := (lSquareHeight - ADest.TextHeight(cddTestStr)) div 2
1046 else lTextY := 0;
1047 lTextY := Max(0, lTextY - 1);
1048
1049 ADest.TextOut(lSquareHeight+5, lTextY, AStateEx.Caption);
1050 end;
1051
1052 procedure TCDDrawerCommon.DrawRadioButtonCircle(ADest: TCanvas;
1053 ADestPos: TPoint; ASize: TSize; AState: TCDControlState;
1054 AStateEx: TCDControlStateEx);
1055 var
1056 lCircleThird, lCircleHeight: Integer;
1057 begin
1058 //lHalf := ASize.cy div 2;
1059 lCircleHeight := GetMeasures(TCDRADIOBUTTON_CIRCLE_HEIGHT);
1060 lCircleThird := lCircleHeight div 3;
1061
1062 // the circle background
1063 ADest.Pen.Style := psClear;
1064 ADest.Brush.Style := bsSolid;
1065 ADest.Brush.Color := Palette.Window; // or WIN2000_FRAME_WHITE ?
1066 ADest.Rectangle(Bounds(ADestPos.X, ADestPos.Y+lCircleThird-1, lCircleHeight-2, lCircleThird));
1067 ADest.Rectangle(Bounds(ADestPos.X+lCircleThird-1, ADestPos.Y, lCircleThird, lCircleHeight-2));
1068
1069 // The circle itself
1070 ADest.Pen.Style := psSolid;
1071 // Gray area
1072 ADest.Pixels[ADestPos.X+4, ADestPos.Y] := WIN2000_FRAME_GRAY;
1073 ADest.Pixels[ADestPos.X+5, ADestPos.Y] := WIN2000_FRAME_GRAY;
1074 ADest.Pixels[ADestPos.X+6, ADestPos.Y] := WIN2000_FRAME_GRAY;
1075 ADest.Pixels[ADestPos.X+7, ADestPos.Y] := WIN2000_FRAME_GRAY;
1076 ADest.Pixels[ADestPos.X+8, ADestPos.Y+1] := WIN2000_FRAME_GRAY;
1077 ADest.Pixels[ADestPos.X+9, ADestPos.Y+1] := WIN2000_FRAME_GRAY;
1078 ADest.Pixels[ADestPos.X+3, ADestPos.Y+1] := WIN2000_FRAME_GRAY;
1079 ADest.Pixels[ADestPos.X+2, ADestPos.Y+1] := WIN2000_FRAME_GRAY;
1080 ADest.Pixels[ADestPos.X+1, ADestPos.Y+2] := WIN2000_FRAME_GRAY;
1081 ADest.Pixels[ADestPos.X+1, ADestPos.Y+3] := WIN2000_FRAME_GRAY;
1082 ADest.Pixels[ADestPos.X, ADestPos.Y+4] := WIN2000_FRAME_GRAY;
1083 ADest.Pixels[ADestPos.X, ADestPos.Y+5] := WIN2000_FRAME_GRAY;
1084 ADest.Pixels[ADestPos.X, ADestPos.Y+6] := WIN2000_FRAME_GRAY;
1085 ADest.Pixels[ADestPos.X, ADestPos.Y+7] := WIN2000_FRAME_GRAY;
1086 ADest.Pixels[ADestPos.X+1, ADestPos.Y+8] := WIN2000_FRAME_GRAY;
1087 ADest.Pixels[ADestPos.X+1, ADestPos.Y+9] := WIN2000_FRAME_GRAY;
1088 // Dark area
1089 ADest.Pixels[ADestPos.X+4, ADestPos.Y+1] := WIN2000_FRAME_DARK_GRAY;
1090 ADest.Pixels[ADestPos.X+5, ADestPos.Y+1] := WIN2000_FRAME_DARK_GRAY;
1091 ADest.Pixels[ADestPos.X+6, ADestPos.Y+1] := WIN2000_FRAME_DARK_GRAY;
1092 ADest.Pixels[ADestPos.X+7, ADestPos.Y+1] := WIN2000_FRAME_DARK_GRAY;
1093 ADest.Pixels[ADestPos.X+8, ADestPos.Y+2] := WIN2000_FRAME_DARK_GRAY;
1094 ADest.Pixels[ADestPos.X+9, ADestPos.Y+2] := WIN2000_FRAME_DARK_GRAY;
1095 ADest.Pixels[ADestPos.X+3, ADestPos.Y+2] := WIN2000_FRAME_DARK_GRAY;
1096 ADest.Pixels[ADestPos.X+2, ADestPos.Y+2] := WIN2000_FRAME_DARK_GRAY;
1097 ADest.Pixels[ADestPos.X+2, ADestPos.Y+3] := WIN2000_FRAME_DARK_GRAY;
1098 ADest.Pixels[ADestPos.X+1, ADestPos.Y+4] := WIN2000_FRAME_DARK_GRAY;
1099 ADest.Pixels[ADestPos.X+1, ADestPos.Y+5] := WIN2000_FRAME_DARK_GRAY;
1100 ADest.Pixels[ADestPos.X+1, ADestPos.Y+6] := WIN2000_FRAME_DARK_GRAY;
1101 ADest.Pixels[ADestPos.X+1, ADestPos.Y+7] := WIN2000_FRAME_DARK_GRAY;
1102 ADest.Pixels[ADestPos.X+2, ADestPos.Y+8] := WIN2000_FRAME_DARK_GRAY;
1103 // Light area
1104 ADest.Pixels[ADestPos.X+9, ADestPos.Y+3] := WIN2000_FRAME_LIGHT_GRAY;
1105 ADest.Pixels[ADestPos.X+10, ADestPos.Y+4] := WIN2000_FRAME_LIGHT_GRAY;
1106 ADest.Pixels[ADestPos.X+10, ADestPos.Y+5] := WIN2000_FRAME_LIGHT_GRAY;
1107 ADest.Pixels[ADestPos.X+10, ADestPos.Y+6] := WIN2000_FRAME_LIGHT_GRAY;
1108 ADest.Pixels[ADestPos.X+10, ADestPos.Y+7] := WIN2000_FRAME_LIGHT_GRAY;
1109 ADest.Pixels[ADestPos.X+9, ADestPos.Y+8] := WIN2000_FRAME_LIGHT_GRAY;
1110 ADest.Pixels[ADestPos.X+9, ADestPos.Y+9] := WIN2000_FRAME_LIGHT_GRAY;
1111 ADest.Pixels[ADestPos.X+8, ADestPos.Y+9] := WIN2000_FRAME_LIGHT_GRAY;
1112 ADest.Pixels[ADestPos.X+7, ADestPos.Y+10] := WIN2000_FRAME_LIGHT_GRAY;
1113 ADest.Pixels[ADestPos.X+6, ADestPos.Y+10] := WIN2000_FRAME_LIGHT_GRAY;
1114 ADest.Pixels[ADestPos.X+5, ADestPos.Y+10] := WIN2000_FRAME_LIGHT_GRAY;
1115 ADest.Pixels[ADestPos.X+4, ADestPos.Y+10] := WIN2000_FRAME_LIGHT_GRAY;
1116 ADest.Pixels[ADestPos.X+3, ADestPos.Y+9] := WIN2000_FRAME_LIGHT_GRAY;
1117 ADest.Pixels[ADestPos.X+2, ADestPos.Y+9] := WIN2000_FRAME_LIGHT_GRAY;
1118 // white area
1119 ADest.Pixels[ADestPos.X+10, ADestPos.Y+2] := WIN2000_FRAME_WHITE;
1120 ADest.Pixels[ADestPos.X+10, ADestPos.Y+3] := WIN2000_FRAME_WHITE;
1121 ADest.Pixels[ADestPos.X+10, ADestPos.Y+8] := WIN2000_FRAME_WHITE;
1122 ADest.Pixels[ADestPos.X+10, ADestPos.Y+9] := WIN2000_FRAME_WHITE;
1123 ADest.Pixels[ADestPos.X+9, ADestPos.Y+10] := WIN2000_FRAME_WHITE;
1124 ADest.Pixels[ADestPos.X+8, ADestPos.Y+10] := WIN2000_FRAME_WHITE;
1125 ADest.Pixels[ADestPos.X+3, ADestPos.Y+10] := WIN2000_FRAME_WHITE;
1126 ADest.Pixels[ADestPos.X+2, ADestPos.Y+10] := WIN2000_FRAME_WHITE;
1127 ADest.Pixels[ADestPos.X+3, ADestPos.Y+3] := WIN2000_FRAME_WHITE;
1128 ADest.Pixels[ADestPos.X+3, ADestPos.Y+8] := WIN2000_FRAME_WHITE;
1129 ADest.Pixels[ADestPos.X+8, ADestPos.Y+3] := WIN2000_FRAME_WHITE;
1130 ADest.Pixels[ADestPos.X+8, ADestPos.Y+8] := WIN2000_FRAME_WHITE;
1131
1132 // The Tickmark
1133 if csfOn in AState then
1134 begin
1135 ADest.Pen.Style := psSolid;
1136 ADest.Pen.Color := clBlack;
1137 ADest.Rectangle(ADestPos.X+4, ADestPos.Y+5, ADestPos.X+8, ADestPos.Y+7);
1138 ADest.Rectangle(ADestPos.X+5, ADestPos.Y+4, ADestPos.X+7, ADestPos.Y+8);
1139 end;
1140 end;
1141
1142 procedure TCDDrawerCommon.DrawRadioButton(ADest: TCanvas;
1143 ASize: TSize; AState: TCDControlState; AStateEx: TCDControlStateEx);
1144 var
1145 lColor: TColor;
1146 lCircleHeight: Integer;
1147 lTextHeight, lTextY: Integer;
1148 begin
1149 lCircleHeight := GetMeasures(TCDRADIOBUTTON_CIRCLE_HEIGHT);
1150
1151 // Background
1152 lColor := AStateEx.ParentRGBColor;
1153 ADest.Brush.Color := lColor;
1154 ADest.Brush.Style := bsSolid;
1155 ADest.Pen.Style := psClear;
1156 ADest.FillRect(0, 0, ASize.cx, ASize.cy);
1157
1158 // The radiobutton circle itself
1159 DrawRadioButtonCircle(ADest, Point(0, 0), ASize, AState, AStateEx);
1160
1161 // The text selection
1162 if csfHasFocus in AState then
1163 DrawFocusRect(ADest, Point(lCircleHeight+3, 0),
1164 Size(ASize.cx-lCircleHeight-3, ASize.cy));
1165
1166 // Now the text
1167 ADest.Brush.Style := bsClear;
1168 ADest.Font.Assign(AStateEx.Font);
1169 lTextHeight := ADest.TextHeight(cddTestStr);
1170 // put the text in the center
1171 if lCircleHeight > lTextHeight then lTextY := (lCircleHeight - ADest.TextHeight(cddTestStr)) div 2
1172 else lTextY := 0;
1173 lTextY := Max(0, lTextY - 1);
1174 ADest.TextOut(lCircleHeight+5, lTextY, AStateEx.Caption);
1175 end;
1176
1177 procedure TCDDrawerCommon.DrawComboBox(ADest: TCanvas; ASize: TSize;
1178 AState: TCDControlState; AStateEx: TCDEditStateEx);
1179 begin
1180 // First the edit, with a margin on the right for the button
1181 AStateEx.RightTextMargin := ASize.CY;
1182 DrawEdit(ADest, ASize, AState, AStateEx);
1183
1184 // Now the button
1185 DrawButtonWithArrow(ADest, Point(ASize.CX - ASize.CY, 0), Size(ASize.CY, ASize.CY),
1186 AStateEx.ExtraButtonState);
1187 end;
1188
1189 procedure TCDDrawerCommon.DrawScrollBar(ADest: TCanvas;
1190 ASize: TSize; AState: TCDControlState; AStateEx: TCDPositionedCStateEx);
1191 var
1192 lPos: TPoint;
1193 lSize: TSize;
1194 lArrowState: TCDControlState;
1195 begin
1196 // Background
1197 ADest.Brush.Color := WIN2000_SCROLLBAR_BACKGROUND;
1198 ADest.Brush.Style := bsSolid;
1199 ADest.Pen.Style := psSolid;
1200 ADest.Pen.Color := WIN2000_SCROLLBAR_BACKGROUND;
1201 ADest.Rectangle(0, 0, ASize.cx, ASize.cy);
1202
1203 // Left/Top button
1204 lPos := Point(0, 0);
1205
1206 if csfHorizontal in AState then
1207 lSize := Size(GetMeasures(TCDSCROLLBAR_BUTTON_WIDTH), ASize.CY)
1208 else lSize := Size(ASize.CX, GetMeasures(TCDSCROLLBAR_BUTTON_WIDTH));
1209
1210 ADest.Brush.Color := Palette.BtnFace;
1211 ADest.Brush.Style := bsSolid;
1212 ADest.Rectangle(Bounds(lPos.X, lPos.Y, lSize.cx, lSize.cy));
1213 if csfLeftArrow in AState then
1214 begin
1215 DrawSunkenFrame(ADest, lPos, lSize);
1216 lArrowState := [csfSunken];
1217 end
1218 else
1219 begin
1220 DrawRaisedFrame(ADest, lPos, lSize);
1221 lArrowState := [];
1222 end;
1223
1224 if csfHorizontal in AState then
1225 DrawArrow(ADest, Point(lPos.X+5, lPos.Y+5), [csfLeftArrow]+lArrowState)
1226 else DrawArrow(ADest, Point(lPos.X+5, lPos.Y+5), [csfUpArrow]+lArrowState);
1227
1228 // Right/Bottom button
1229 if csfHorizontal in AState then
1230 lPos.X := lPos.X+ASize.CX-GetMeasures(TCDSCROLLBAR_BUTTON_WIDTH)
1231 else
1232 lPos.Y := lPos.Y+ASize.CY-GetMeasures(TCDSCROLLBAR_BUTTON_WIDTH);
1233 ADest.Brush.Color := Palette.BtnFace;
1234 ADest.Brush.Style := bsSolid;
1235 ADest.Rectangle(Bounds(lPos.X, lPos.Y, lSize.cx, lSize.cy));
1236 if csfRightArrow in AState then
1237 begin
1238 DrawSunkenFrame(ADest, lPos, lSize);
1239 lArrowState := [csfSunken];
1240 end
1241 else
1242 begin
1243 DrawRaisedFrame(ADest, lPos, lSize);
1244 lArrowState := [];
1245 end;
1246
1247 if csfHorizontal in AState then
1248 DrawArrow(ADest, Point(lPos.X+5, lPos.Y+5), [csfRightArrow] + lArrowState)
1249 else DrawArrow(ADest, Point(lPos.X+5, lPos.Y+5), [csfDownArrow] + lArrowState);
1250
1251 // The slider
1252 lPos := Point(0, 0);
1253 if csfHorizontal in AState then
1254 begin
1255 if AStateEx.FloatPageSize > 0 then lSize.cx := Round(
1256 AStateEx.FloatPageSize * (ASize.cx - GetMeasures(TCDSCROLLBAR_BUTTON_WIDTH) * 2));
1257 if lSize.cx < 5 then lSize.cx := 5;
1258
1259 lPos.X := Round(GetMeasures(TCDSCROLLBAR_BUTTON_WIDTH)
1260 + AStateEx.FloatPos * (ASize.cx - GetMeasures(TCDSCROLLBAR_BUTTON_WIDTH) * 2 - lSize.cx));
1261 end
1262 else
1263 begin
1264 if AStateEx.FloatPageSize > 0 then lSize.cy := Round(
1265 AStateEx.FloatPageSize * (ASize.cy - GetMeasures(TCDSCROLLBAR_BUTTON_WIDTH) * 2));
1266 if lSize.cy < 5 then lSize.cy := 5;
1267
1268 lPos.Y := Round(GetMeasures(TCDSCROLLBAR_BUTTON_WIDTH)
1269 + AStateEx.FloatPos * (ASize.cy - GetMeasures(TCDSCROLLBAR_BUTTON_WIDTH) * 2 - lSize.cy));
1270 end;
1271 ADest.Brush.Color := Palette.BtnFace;
1272 ADest.Brush.Style := bsSolid;
1273 ADest.Rectangle(Bounds(lPos.X, lPos.Y, lSize.cx, lSize.cy));
1274 DrawRaisedFrame(ADest, lPos, lSize);
1275 end;
1276
1277 procedure TCDDrawerCommon.DrawGroupBox(ADest: TFPCustomCanvas;
1278 ADestPos: TPoint; ASize: TSize; AState: TCDControlState; AStateEx: TCDControlStateEx);
1279 var
1280 FCaptionMiddle: integer = 0;
1281 lTextSize: TSize;
1282 lCaption: String;
1283 begin
1284 if ADest is TCanvas then FCaptionMiddle := (ADest as TCanvas).TextHeight(cddTestStr) div 2;
1285 if FCaptionMiddle = 0 then FCaptionMiddle := AStateEx.Font.Size div 2;
1286 if FCaptionMiddle = 0 then FCaptionMiddle := 5;
1287
1288 // Background
1289 ADest.Brush.FPColor := AStateEx.FPParentRGBColor;
1290 ADest.Brush.Style := bsSolid;
1291 ADest.Pen.Style := psSolid;
1292 ADest.Pen.FPColor := AStateEx.FPParentRGBColor;
1293 ADest.Rectangle(0, 0, ASize.cx, ASize.cy);
1294
1295 // frame
1296 ADest.Pen.FPColor := TColorToFPColor(WIN2000_FRAME_WHITE);
1297 ADest.Pen.Style := psSolid;
1298 ADest.Brush.Style := bsClear;
1299 ADest.Rectangle(Bounds(1, 1+FCaptionMiddle, ASize.cx-1, ASize.cy-1-FCaptionMiddle));
1300 ADest.Pen.FPColor := TColorToFPColor(WIN2000_FRAME_GRAY);
1301 ADest.Rectangle(Bounds(0, FCaptionMiddle, ASize.cx-1, ASize.cy-1-FCaptionMiddle));
1302 if ADest is TCanvas then
1303 begin
1304 (ADest as TCanvas).Pixels[0, ASize.cy-1] := WIN2000_FRAME_WHITE;
1305 (ADest as TCanvas).Pixels[ASize.cx-1, FCaptionMiddle] := WIN2000_FRAME_WHITE;
1306 end;
1307
1308 // ToDo: Make the caption smaller if it is too big
1309 lCaption := AStateEx.Caption;
1310 if ADest is TCanvas then lTextSize := (ADest as TCanvas).TextExtent(lCaption)
1311 else lTextSize := Size(50, AStateEx.Font.Size);
1312
1313 // fill the text background
1314 ADest.Brush.Style := bsSolid;
1315 ADest.Brush.FPColor := AStateEx.FPParentRGBColor;
1316 ADest.Pen.Style := psClear;
1317 ADest.Rectangle(Bounds(FCaptionMiddle, 0, lTextSize.cx+5, lTextSize.cy));
1318
1319 // paint text
1320 ADest.Pen.Style := psClear;
1321 ADest.Brush.Style := bsClear;
1322 if ADest is TCanvas then ADest.TextOut(FCaptionMiddle+3, 0, lCaption);
1323 end;
1324
1325 procedure TCDDrawerCommon.DrawPanel(ADest: TCanvas; ASize: TSize;
1326 AState: TCDControlState; AStateEx: TCDPanelStateEx);
1327 var
1328 NextRectFactor: Integer = 0;
1329 //TS : TTextStyle;
1330 begin
1331 // Background
1332 ADest.Brush.Color := Palette.BtnFace;
1333 ADest.Brush.Style := bsSolid;
1334 ADest.Pen.Style := psClear;
1335 ADest.FillRect(0, 0, ASize.cx, ASize.cy);
1336
1337 // The outter frame
1338
1339 // if BevelOuter is set then draw a frame with BevelWidth
1340 if (AStateEx.BevelOuter <> bvNone) then
1341 begin
1342 NextRectFactor := AStateEx.BevelWidth;
1343 DrawFrame3d(ADest, Point(0, 0), ASize, AStateEx.BevelWidth, AStateEx.BevelOuter); // Note: Frame3D inflates ARect
1344 end;
1345
1346 ASize.cx := ASize.cx - NextRectFactor*2;
1347 ASize.cy := ASize.cy - NextRectFactor*2;
1348
1349 // if BevelInner is set then skip the BorderWidth and draw a frame with BevelWidth
1350 if (AStateEx.BevelInner <> bvNone) then
1351 DrawFrame3d(ADest, Point(NextRectFactor, NextRectFactor), ASize, AStateEx.BevelWidth, AStateEx.BevelInner); // Note: Frame3D inflates ARect
1352
1353 {if Caption <> '' then
1354 begin
1355 TS := Canvas.TextStyle;
1356 TS.Alignment := BidiFlipAlignment(Self.Alignment, UseRightToLeftAlignment);
1357 if BiDiMode<>bdLeftToRight then
1358 TS.RightToLeft:= True;
1359 TS.Layout:= tlCenter;
1360 TS.Opaque:= false;
1361 TS.Clipping:= false;
1362 TS.SystemFont:=Canvas.Font.IsDefault;
1363 if not Enabled then
1364 begin
1365 Canvas.Font.Color := clBtnHighlight;
1366 OffsetRect(ARect, 1, 1);
1367 Canvas.TextRect(ARect, ARect.Left, ARect.Top, Caption, TS);
1368 Canvas.Font.Color := clBtnShadow;
1369 OffsetRect(ARect, -1, -1);
1370 end
1371 else
1372 Canvas.Font.Color := Font.Color;
1373
1374 Canvas.TextRect(ARect,ARect.Left,ARect.Top, Caption, TS);
1375 end;}
1376 end;
1377
1378 procedure TCDDrawerCommon.DrawStaticText(ADest: TCanvas;
1379 ASize: TSize; AState: TCDControlState; AStateEx: TCDControlStateEx);
1380 var
1381 lColor: TColor;
1382 begin
1383 // Background
1384 lColor := AStateEx.ParentRGBColor;
1385 ADest.Brush.Color := lColor;
1386 ADest.Brush.Style := bsSolid;
1387 ADest.Pen.Style := psClear;
1388 ADest.FillRect(0, 0, ASize.cx, ASize.cy);
1389
1390 // Now the text
1391 ADest.Brush.Style := bsClear;
1392 ADest.Font.Assign(AStateEx.Font);
1393 ADest.TextOut(0, 0, AStateEx.Caption);
1394 end;
1395
1396 procedure TCDDrawerCommon.DrawTrackBar(ADest: TCanvas;
1397 ASize: TSize; AState: TCDControlState; AStateEx: TCDPositionedCStateEx);
1398 var
1399 StepsCount, i: Integer;
1400 lTickmarkLeft, lTickmarkTop: integer; // for drawing the decorative bars
1401 CDBarSpacing: Integer;
1402 pStepWidth, lTickmarkLeftFloat: Double;
1403 lPoint: TPoint;
1404 lSize, lMeasureSize: TSize;
1405 lValue5, lValue11: Integer;
1406 begin
1407 lValue5 := DPIAdjustment(5);
1408 lValue11 := DPIAdjustment(11);
1409 // The orientation i
1410 if csfHorizontal in AState then lMeasureSize := ASize
1411 else lMeasureSize := Size(ASize.CY, ASize.CX);
1412
1413 CDBarSpacing := GetMeasures(TCDTRACKBAR_LEFT_SPACING) + GetMeasures(TCDTRACKBAR_RIGHT_SPACING);
1414
1415 // Preparations
1416 StepsCount := AStateEx.PosCount;
1417 if StepsCount > 0 then pStepWidth := (lMeasureSize.cx - CDBarSpacing) / (StepsCount-1)
1418 else pStepWidth := 0.0;
1419
1420 // Background
1421
1422 ADest.Brush.Color := AStateEx.ParentRGBColor;
1423 ADest.Brush.Style := bsSolid;
1424 ADest.Pen.Style := psSolid;
1425 ADest.Pen.Color := AStateEx.ParentRGBColor;
1426 ADest.Rectangle(0, 0, ASize.cx, ASize.cy);
1427
1428 // Draws the frame and its inner white area
1429 if csfHorizontal in AState then
1430 begin
1431 lPoint := Point(GetMeasures(TCDTRACKBAR_LEFT_SPACING),
1432 GetMeasures(TCDTRACKBAR_TOP_SPACING));
1433 lSize := Size(ASize.CX - CDBarSpacing, GetMeasures(TCDTRACKBAR_FRAME_HEIGHT));
1434 end
1435 else
1436 begin
1437 lPoint := Point(GetMeasures(TCDTRACKBAR_TOP_SPACING),
1438 GetMeasures(TCDTRACKBAR_LEFT_SPACING));
1439 lSize := Size(GetMeasures(TCDTRACKBAR_FRAME_HEIGHT), ASize.CY - CDBarSpacing);
1440 end;
1441 ADest.Brush.Color := Palette.Window;
1442 ADest.Pen.Style := psClear;
1443 ADest.Rectangle(Bounds(lPoint.X, lPoint.Y, lSize.cx, lSize.cy));
1444 DrawSunkenFrame(ADest, lPoint, lSize);
1445
1446 // Draws the tickmarks and also the slider button
1447 lTickmarkLeft := GetMeasures(TCDTRACKBAR_LEFT_SPACING);
1448 lTickmarkLeftFloat := lTickmarkLeft;
1449 lTickmarkTop := GetMeasures(TCDTRACKBAR_TOP_SPACING) + GetMeasures(TCDTRACKBAR_FRAME_HEIGHT)+5;
1450 ADest.Pen.Style := psSolid;
1451 for i := 0 to StepsCount - 1 do
1452 begin
1453 ADest.Pen.Color := clBlack;
1454 if csfHorizontal in AState then
1455 ADest.Line(lTickmarkLeft, lTickmarkTop, lTickmarkLeft, lTickmarkTop+3)
1456 else
1457 ADest.Line(lTickmarkTop, lTickmarkLeft, lTickmarkTop+3, lTickmarkLeft);
1458
1459 // Draw the slider
1460 if i = AStateEx.Position then
1461 DrawSlider(ADest,
1462 Point(lTickmarkLeft-lValue5, GetMeasures(TCDTRACKBAR_TOP_SPACING)-2),
1463 Size(lValue11, GetMeasures(TCDTRACKBAR_FRAME_HEIGHT)+lValue5), AState);
1464
1465 lTickmarkLeftFloat := lTickmarkLeftFloat + pStepWidth;
1466 lTickmarkLeft := Round(lTickmarkLeftFloat);
1467 end;
1468
1469 // Draw the focus
1470 if csfHasFocus in AState then
1471 DrawFocusRect(ADest,
1472 Point(1, 1),
1473 Size(ASize.CX - 2, ASize.CY - 2));
1474 end;
1475
1476 // Felipe: Smooth=False is not supported for now
1477 procedure TCDDrawerCommon.DrawProgressBar(ADest: TCanvas;
1478 ASize: TSize; AState: TCDControlState; AStateEx: TCDProgressBarStateEx);
1479 var
1480 lProgPos, lProgMult: TPoint;
1481 lProgSize: TSize;
1482 lProgWidth: Integer;
1483 begin
1484 // Inside area, there is no background because the control occupies the entire area
1485 ADest.Brush.Color := WIN2000_BTNFACE;
1486 ADest.Brush.Style := bsSolid;
1487 ADest.Pen.Style := psClear;
1488 ADest.Rectangle(0, 0, ASize.cx, ASize.cy);
1489
1490 // The Frame
1491 DrawShallowSunkenFrame(ADest, Point(0, 0), ASize);
1492
1493 // Preparations to have 1 code for all orientations
1494 lProgSize := Size(ASize.cx-4, ASize.cy-4);
1495 if csfHorizontal in AState then
1496 begin
1497 lProgPos := Point(2, 2);
1498 lProgMult := Point(1, 0);
1499 lProgWidth := lProgSize.cx;
1500 end
1501 else if csfVertical in AState then
1502 begin
1503 lProgPos := Point(2, ASize.cy-2);
1504 lProgMult := Point(0, -1);
1505 lProgWidth := lProgSize.cy;
1506 end else if csfRightToLeft in AState then
1507 begin
1508 lProgPos := Point(ASize.cx-2, 2);
1509 lProgMult := Point(-1, 0);
1510 lProgWidth := lProgSize.cx;
1511 end
1512 else
1513 begin
1514 lProgPos := Point(2, 2);
1515 lProgMult := Point(0, 1);
1516 lProgWidth := lProgSize.cy;
1517 end;
1518 lProgWidth := Round(lProgWidth * AStateEx.PercentPosition);
1519
1520 // Draws the filling
1521 ADest.Pen.Color := WIN2000_PROGRESSBAR_BLUE;
1522 ADest.Pen.Style := psSolid;
1523 ADest.Brush.Color := WIN2000_PROGRESSBAR_BLUE;
1524 ADest.Brush.Style := bsSolid;
1525 ADest.Rectangle(
1526 lProgPos.X,
1527 lProgPos.Y,
1528 lProgPos.X+lProgWidth*lProgMult.X+lProgSize.cx*Abs(lProgMult.Y),
1529 lProgPos.Y+lProgWidth*lProgMult.Y+lProgSize.cy*Abs(lProgMult.X));
1530 end;
1531
1532 procedure TCDDrawerCommon.DrawListView(ADest: TCanvas;
1533 ASize: TSize; AState: TCDControlState; AStateEx: TCDListViewStateEx);
1534 begin
1535 // Inside area, there is no background because the control occupies the entire area
1536 ADest.Brush.Color := Palette.Window;
1537 ADest.Brush.Style := bsSolid;
1538 ADest.Pen.Style := psClear;
1539 ADest.Rectangle(0, 0, ASize.cx, ASize.cy);
1540
1541 // The frame
1542 DrawSunkenFrame(ADest, Point(0, 0), ASize);
1543
1544 // The contents depend on the view style
1545 case AStateEx.ViewStyle of
1546 vsReport: DrawReportListView(ADest, Point(0, 0), ASize, AState, AStateEx);
1547 end;
1548 end;
1549
1550 procedure TCDDrawerCommon.DrawReportListView(ADest: TCanvas; ADestPos: TPoint;
1551 ASize: TSize; AState: TCDControlState; AStateEx: TCDListViewStateEx);
1552 var
1553 lColumn: TListColumn;
1554 i, j: Integer;
1555 lCurPos: TPoint;
1556 lItemSize: TSize;
1557 lItemCount: Integer;
1558 lCurItem: TCDListItems;
1559 begin
1560 lCurPos := Point(2, 2);
1561 lItemCount := AStateEx.Items.GetItemCount();
1562
1563 // i is an column zero-based index
1564 for i := AStateEx.FirstVisibleColumn to AStateEx.Columns.Count-1 do
1565 begin
1566 lColumn := AStateEx.Columns[i];
1567 lCurPos.Y := 2;
1568
1569 // get the column width
1570 if lColumn.AutoSize then
1571 begin
1572 lItemSize.cx := ADest.GetTextWidth(lColumn.Caption)
1573 + GetMeasures(TCDLISTVIEW_COLUMN_LEFT_SPACING)
1574 + GetMeasures(TCDLISTVIEW_COLUMN_RIGHT_SPACING);
1575 if (lColumn.MinWidth > 0) and (lItemSize.cx < lColumn.MinWidth) then lItemSize.cx := lColumn.MinWidth
1576 else if (lColumn.MaxWidth > 0) and (lItemSize.cx > lColumn.MaxWidth) then lItemSize.cx := lColumn.MaxWidth;
1577 end
1578 else lItemSize.cx := lColumn.Width;
1579
1580 // line height measure
1581 lItemSize.cy := ADest.TextHeight(cddTestStr)
1582 + GetMeasures(TCDLISTVIEW_LINE_TOP_SPACING)
1583 + GetMeasures(TCDLISTVIEW_LINE_BOTTOM_SPACING);
1584
1585 // Draw the column header
1586 if AStateEx.ShowColumnHeader then
1587 begin
1588 // Foreground
1589 ADest.Brush.Style := bsSolid;
1590 ADest.Brush.Color := Palette.BtnFace; // WIN2000_BTNFACE
1591 ADest.Pen.Style := psClear;
1592 ADest.FillRect(Bounds(lCurPos.X, lCurPos.Y, lItemSize.cx, lItemSize.cy));
1593
1594 // Frame
1595 DrawRaisedFrame(ADest, lCurPos, lItemSize);
1596
1597 // The caption
1598 ADest.Brush.Style := bsClear;
1599 ADest.Pen.Style := psClear;
1600 ADest.TextOut(
1601 lCurPos.X+GetMeasures(TCDLISTVIEW_COLUMN_TEXT_LEFT_SPACING),
1602 lCurPos.Y+GetMeasures(TCDLISTVIEW_LINE_TOP_SPACING),
1603 lColumn.Caption);
1604
1605 Inc(lCurPos.Y, lItemSize.cy);
1606 end;
1607
1608 // j is a zero-based index for lines, ignoring the header
1609 // Draw all items until we get out of the visible area
1610 for j := 0 to lItemCount-1 do
1611 begin
1612 lCurItem := nil;
1613 if i = 0 then lCurItem := AStateEx.Items.GetItem(j)
1614 else if AStateEx.Items.GetItem(j).GetItemCount >= i then
1615 lCurItem := AStateEx.Items.GetItem(j).GetItem(i-1);
1616
1617 if lCurItem = nil then Continue;
1618
1619 // Draw the item
1620 DrawReportListViewItem(ADest, lCurPos, lItemSize, lCurItem, AState, AStateEx);
1621
1622 Inc(lCurPos.Y, lItemSize.CY);
1623 end;
1624
1625 Inc(lCurPos.X, lItemSize.CX);
1626 end;
1627 end;
1628
1629 procedure TCDDrawerCommon.DrawReportListViewItem(ADest: TCanvas;
1630 ADestPos: TPoint; ASize: TSize; ACurItem: TCDListItems; AState: TCDControlState;
1631 AStateEx: TCDListViewStateEx);
1632 begin
1633 ADest.Brush.Style := bsClear;
1634 ADest.Pen.Style := psClear;
1635 ADest.TextOut(
1636 ADestPos.X+GetMeasures(TCDLISTVIEW_COLUMN_TEXT_LEFT_SPACING),
1637 ADestPos.Y+GetMeasures(TCDLISTVIEW_LINE_TOP_SPACING),
1638 ACurItem.Caption);
1639 end;
1640
1641 procedure TCDDrawerCommon.DrawToolBar(ADest: TCanvas; ASize: TSize;
1642 AState: TCDControlState; AStateEx: TCDToolBarStateEx);
1643 var
1644 lX, lY, lX2: Integer;
1645 lItemSize: TSize;
1646 i: Integer;
1647 lCurItem: TCDToolBarItem;
1648 lItemState: TCDControlState = [];
1649 begin
1650 // Background
1651 ADest.Pen.Style := psSolid;
1652 ADest.Pen.Color := AStateEx.ParentRGBColor;
1653 ADest.Brush.Style := bsSolid;
1654 ADest.Brush.Color := AStateEx.ParentRGBColor;
1655 ADest.Rectangle(0, 0, ASize.cx, ASize.cy);
1656
1657 // Items
1658 lX := GetMeasures(TCDTOOLBAR_ITEM_SPACING);
1659 lY := GetMeasures(TCDTOOLBAR_ITEM_SPACING);
1660 lItemSize.CY := AStateEx.ToolBarHeight - GetMeasures(TCDTOOLBAR_ITEM_SPACING) * 2;
1661 for i := 0 to AStateEx.Items.Count-1 do
1662 begin
1663 lCurItem := TCDToolBarItem(AStateEx.Items[i]);
1664
1665 // make space for the arrow if necessary
1666 if lCurItem.Kind = tikDropDownButton then
1667 lItemSize.CX := lCurItem.Width - GetMeasures(TCDTOOLBAR_ITEM_ARROW_RESERVED_WIDTH)
1668 else
1669 lItemSize.CX := lCurItem.Width;
1670
1671 lCurItem.SubpartKind := tiskMain;
1672 DrawToolBarItem(ADest, lItemSize, lCurItem, lX, lY, lCurItem.State, AStateEx);
1673
1674 if lCurItem.Kind = tikDropDownButton then
1675 begin
1676 lCurItem.SubpartKind := tiskArrow;
1677 lX2 := lX + lCurItem.Width - GetMeasures(TCDTOOLBAR_ITEM_ARROW_RESERVED_WIDTH);
1678 lItemSize.CX := GetMeasures(TCDTOOLBAR_ITEM_ARROW_RESERVED_WIDTH);
1679 DrawToolBarItem(ADest, lItemSize, lCurItem, lX2, lY, lCurItem.State, AStateEx);
1680 end;
1681
1682 lX := lX + lCurItem.Width;
1683 end;
1684 end;
1685
1686 procedure TCDDrawerCommon.DrawToolBarItem(ADest: TCanvas; ASize: TSize;
1687 ACurItem: TCDToolBarItem; AX, AY: Integer; AState: TCDControlState; AStateEx: TCDToolBarStateEx);
1688 var
1689 lX, lY1, lY2: Integer;
1690
1691 procedure DrawToolBarItemBorder();
1692 begin
1693 ADest.Pen.Style := psSolid;
1694 ADest.Pen.Color := $AFAFAF;
1695 ADest.Brush.Style := bsClear;
1696 ADest.Rectangle(Bounds(AX, AY, ASize.cx, ASize.cy));
1697 end;
1698
1699 begin
1700 // tikDivider is centralized, tikSeparator is left-aligned
1701 case ACurItem.Kind of
1702 tikSeparator, tikDivider:
1703 begin
1704 lX := AX;
1705 if ACurItem.Kind = tikDivider then
1706 lX := AX + ASize.CX div 2 - 1;
1707
1708 lY1 := AY;
1709 lY2 := AY+ASize.CY;
1710
1711 ADest.Pen.Style := psSolid;
1712 ADest.Pen.Color := $DCDEE1;
1713 ADest.Line(lX+1, lY1, lX+1, lY2);
1714 ADest.Line(lX+3, lY1, lX+3, lY2);
1715 ADest.Pen.Style := psSolid;
1716 ADest.Pen.Color := $93979E;
1717 ADest.Line(lX+2, lY1, lX+2, lY2);
1718 end;
1719 tikButton, tikCheckButton, tikDropDownButton:
1720 begin
1721 if ACurItem.SubpartKind = tiskArrow then
1722 begin
1723 // Centralize the arrow in the available space
1724 lX := AX + ASize.CX div 2 - GetMeasures(TCDTOOLBAR_ITEM_ARROW_WIDTH) div 2;
1725 lY1 := AY + ASize.CY div 2 - GetMeasures(TCDTOOLBAR_ITEM_ARROW_WIDTH) div 2;
1726 DrawArrow(ADest, Point(lX, lY1), [csfDownArrow], GetMeasures(TCDTOOLBAR_ITEM_ARROW_WIDTH));
1727 Exit;
1728 end;
1729
1730 if csfSunken in AState then
1731 begin
1732 ADest.GradientFill(Bounds(AX, AY, ASize.CX, ASize.CY),
1733 $C4C4C4, $DBDBDB, gdVertical);
1734 DrawToolBarItemBorder();
1735 end
1736 else if csfMouseOver in AState then
1737 begin
1738 ADest.GradientFill(Bounds(AX, AY, ASize.CX, ASize.CY),
1739 $E3E3E3, $F7F7F7, gdVertical);
1740 DrawToolBarItemBorder();
1741 end;
1742 end;
1743 end;
1744 end;
1745
1746 procedure TCDDrawerCommon.DrawCTabControl(ADest: TCanvas;
1747 ASize: TSize; AState: TCDControlState; AStateEx: TCDCTabControlStateEx);
1748 begin
1749 // Background
1750 ADest.Pen.Style := psSolid;
1751 ADest.Pen.Color := AStateEx.ParentRGBColor;
1752 ADest.Brush.Style := bsSolid;
1753 ADest.Brush.Color := AStateEx.ParentRGBColor;
1754 ADest.Rectangle(0, 0, ASize.cx, ASize.cy);
1755
1756 // frame
1757 DrawCTabControlFrame(ADest, Point(0, 0), ASize, AState, AStateEx);
1758
1759 // Tabs
1760 ADest.Font.Assign(AStateEx.Font);
1761 DrawTabs(ADest, Point(0, 0), ASize, AState, AStateEx);
1762 end;
1763
1764 procedure TCDDrawerCommon.DrawCTabControlFrame(ADest: TCanvas;
1765 ADestPos: TPoint; ASize: TSize; AState: TCDControlState;
1766 AStateEx: TCDCTabControlStateEx);
1767 var
1768 CaptionHeight: Integer;
1769 begin
1770 if AStateEx.TabCount = 0 then CaptionHeight := 0
1771 else CaptionHeight := GetMeasuresEx(ADest, TCDCTABCONTROL_TAB_HEIGHT, AState, AStateEx);
1772
1773 DrawRaisedFrame(ADest, Point(0, CaptionHeight), Size(ASize.cx, ASize.cy-CaptionHeight));
1774 end;
1775
1776 procedure TCDDrawerCommon.DrawTabSheet(ADest: TCanvas; ADestPos: TPoint;
1777 ASize: TSize; AState: TCDControlState; AStateEx: TCDCTabControlStateEx);
1778 begin
1779 ADest.Brush.Color := AStateEx.RGBColor;
1780 ADest.Brush.Style := bsSolid;
1781 ADest.Pen.Style := psSolid;
1782 ADest.Pen.Color := AStateEx.RGBColor;
1783 ADest.Rectangle(0, 0, ASize.cx, ASize.cy);
1784 end;
1785
1786 procedure TCDDrawerCommon.DrawTabs(ADest: TCanvas; ADestPos: TPoint;
1787 ASize: TSize; AState: TCDControlState; AStateEx: TCDCTabControlStateEx);
1788 var
1789 IsPainting: Boolean = False;
1790 lLastTabIndex, i: Integer;
1791 begin
1792 AStateEx.CurStartLeftPos := 0;
1793 if nboShowAddTabButton in AStateEx.Options then lLastTabIndex := AStateEx.Tabs.Count
1794 else lLastTabIndex := AStateEx.Tabs.Count - 1;
1795
1796 for i := 0 to lLastTabIndex do
1797 begin
1798 if i = AStateEx.LeftmostTabVisibleIndex then
1799 IsPainting := True;
1800
1801 if IsPainting then
1802 begin
1803 AStateEx.CurTabIndex := i;
1804 DrawTab(ADest, ADestPos, ASize, AState, AStateEx);
1805 AStateEx.CurStartLeftPos := AStateEx.CurStartLeftPos + GetMeasuresEx(ADest, TCDCTABCONTROL_TAB_WIDTH, AState, AStateEx);
1806 end;
1807 end;
1808 end;
1809
1810 procedure TCDDrawerCommon.DrawTab(ADest: TCanvas; ADestPos: TPoint;
1811 ASize: TSize; AState: TCDControlState; AStateEx: TCDCTabControlStateEx);
1812 var
1813 IsSelected, IsAddButton: Boolean;
1814 lTabWidth, lTabHeight, lTabTopPos: Integer;
1815 Points: array of TPoint;
1816 lCaption: String;
1817 lTabHeightCorrection: Integer = 0;
1818 lTabRightBorderExtraHeight: Integer = 0;
1819 lCloseButtonPos: TPoint;
1820 begin
1821 IsSelected := AStateEx.TabIndex = AStateEx.CurTabIndex;
1822 IsAddButton := AStateEx.CurTabIndex = AStateEx.Tabs.Count;
1823
1824 if not IsSelected then lTabHeightCorrection := 3;
1825 if IsSelected then lTabRightBorderExtraHeight := 1;
1826
1827 lTabTopPos := lTabHeightCorrection;
1828 lTabHeight := GetMeasuresEx(ADest, TCDCTABCONTROL_TAB_HEIGHT, AState, AStateEx)-lTabHeightCorrection;
1829 lTabWidth := GetMeasuresEx(ADest, TCDCTABCONTROL_TAB_WIDTH, AState, AStateEx);
1830
1831 // Fill the area inside the outer border
1832 // And at the same time fill the white border (part of it will be erased later)
1833 ADest.Pen.Style := psSolid;
1834 ADest.Pen.Color := WIN2000_FRAME_WHITE;
1835 ADest.Brush.Style := bsSolid;
1836 ADest.Brush.Color := AStateEx.RGBColor;
1837 SetLength(Points, 6);
1838 Points[0] := Point(AStateEx.CurStartLeftPos, lTabTopPos+lTabHeight);
1839 Points[1] := Point(AStateEx.CurStartLeftPos, lTabTopPos+2);
1840 Points[2] := Point(AStateEx.CurStartLeftPos+2, lTabTopPos);
1841 Points[3] := Point(AStateEx.CurStartLeftPos+lTabWidth-3, lTabTopPos);
1842 Points[4] := Point(AStateEx.CurStartLeftPos+lTabWidth-1, lTabTopPos+2);
1843 Points[5] := Point(AStateEx.CurStartLeftPos+lTabWidth-1, lTabTopPos+lTabHeight);
1844 ADest.Polygon(Points);
1845
1846 // Draw the inner border of the top and right sides,
1847 ADest.Pen.Style := psSolid;
1848 ADest.Brush.Style := bsClear;
1849 ADest.Pen.Color := WIN2000_FRAME_LIGHT_GRAY;
1850 ADest.MoveTo(AStateEx.CurStartLeftPos+1, lTabTopPos+lTabHeight-1);
1851 ADest.LineTo(AStateEx.CurStartLeftPos+1, lTabTopPos+2);
1852 ADest.LineTo(AStateEx.CurStartLeftPos+2, lTabTopPos+1);
1853 ADest.LineTo(AStateEx.CurStartLeftPos+lTabWidth-3, lTabTopPos+1);
1854
1855 // Draw the inner border of the right side
1856 ADest.Pen.Color := WIN2000_FRAME_GRAY;
1857 ADest.MoveTo(AStateEx.CurStartLeftPos+lTabWidth-2, lTabTopPos+2);
1858 ADest.LineTo(AStateEx.CurStartLeftPos+lTabWidth-2, lTabTopPos+lTabHeight+lTabRightBorderExtraHeight);
1859 // Draw the outter border of the right side
1860 ADest.Pen.Color := WIN2000_FRAME_DARK_GRAY;
1861 ADest.MoveTo(AStateEx.CurStartLeftPos+lTabWidth-1, lTabTopPos+2);
1862 ADest.LineTo(AStateEx.CurStartLeftPos+lTabWidth-1, lTabTopPos+lTabHeight+lTabRightBorderExtraHeight);
1863 ADest.Pixels[AStateEx.CurStartLeftPos+lTabWidth-2, lTabTopPos+1] := WIN2000_FRAME_DARK_GRAY;
1864
1865 if IsSelected then
1866 begin
1867 // If it is selected, add a selection frame
1868 DrawFocusRect(ADest, Point(AStateEx.CurStartLeftPos+3, lTabTopPos+3),
1869 Size(lTabWidth-8, lTabHeight-6));
1870
1871 // and Clear the bottom area if selected
1872 ADest.Pen.Style := psSolid;
1873 ADest.Pen.Color := AStateEx.RGBColor;
1874 ADest.Line(AStateEx.CurStartLeftPos+1, lTabTopPos+lTabHeight,
1875 AStateEx.CurStartLeftPos+lTabWidth-2, lTabTopPos+lTabHeight);
1876 ADest.Line(AStateEx.CurStartLeftPos+1, lTabTopPos+lTabHeight+1,
1877 AStateEx.CurStartLeftPos+lTabWidth-2, lTabTopPos+lTabHeight+1);
1878 end;
1879
1880 // Now the text
1881 if IsAddButton then lCaption := '+'
1882 else lCaption := AStateEx.Tabs.Strings[AStateEx.CurTabIndex];
1883 ADest.TextOut(AStateEx.CurStartLeftPos+5, lTabTopPos+5, lCaption);
1884
1885 // Now the close button
1886 if (not IsAddButton) and (nboShowCloseButtons in AStateEx.Options) then
1887 begin
1888 lCloseButtonPos.X := GetMeasuresEx(ADest, TCDCTABCONTROL_CLOSE_BUTTON_POS_X, AState, AStateEx);
1889 lCloseButtonPos.Y := GetMeasuresEx(ADest, TCDCTABCONTROL_CLOSE_BUTTON_POS_Y, AState, AStateEx);
1890 DrawSmallCloseButton(ADest, lCloseButtonPos);
1891 end;
1892 end;
1893
1894 procedure TCDDrawerCommon.DrawSpinEdit(ADest: TCanvas; ADestPos: TPoint;
1895 ASize: TSize; AState: TCDControlState; AStateEx: TCDSpinStateEx);
1896 begin
1897
1898 end;
1899
1900 { TCDListViewDrawerCommon }
1901
1902 initialization
1903 RegisterDrawer(TCDDrawerCommon.Create, dsCommon);
1904 end.
1905
1906