From 0ef97f99db89d9fbcbd394288e7c02eb1164ae3d Mon Sep 17 00:00:00 2001 From: sekelsenmat Date: Sun, 18 Mar 2012 22:25:18 +0000 Subject: [PATCH] LCL-CustomDrawn and CustomDrawn: Advances the migration to TFPCustomCanvas which allowed to support TUpDown and TSpeedButton in LCL-CustomDrawn git-svn-id: trunk@36155 - --- .../customdrawn/customdrawn_android.pas | 102 ++++++++-------- components/customdrawn/customdrawn_wince.pas | 22 ++-- components/customdrawn/customdrawn_winxp.pas | 97 +++++++-------- lcl/customdrawn_common.pas | 112 +++++++++--------- lcl/customdrawncontrols.pas | 2 + lcl/customdrawndrawers.pas | 6 +- .../customdrawn/customdrawnwinapi.inc | 70 ++++++----- 7 files changed, 216 insertions(+), 195 deletions(-) diff --git a/components/customdrawn/customdrawn_android.pas b/components/customdrawn/customdrawn_android.pas index 8e716494d0..9bbaa53081 100644 --- a/components/customdrawn/customdrawn_android.pas +++ b/components/customdrawn/customdrawn_android.pas @@ -57,7 +57,7 @@ type // Standard Tab // =================================== // TCDButton - procedure DrawButton(ADest: TCanvas; ASize: TSize; + procedure DrawButton(ADest: TFPCustomCanvas; ASize: TSize; AState: TCDControlState; AStateEx: TCDButtonStateEx); override; { // TCDEdit procedure DrawEditBackground(ADest: TCanvas; ADestPos: TPoint; ASize: TSize; @@ -310,9 +310,10 @@ begin // Don't draw anything, tickmarks are impressed into the general images end; -procedure TCDDrawerAndroid.DrawButton(ADest: TCanvas; ASize: TSize; +procedure TCDDrawerAndroid.DrawButton(ADest: TFPCustomCanvas; ASize: TSize; AState: TCDControlState; AStateEx: TCDButtonStateEx); var + lDest: TCanvas absolute ADest; Str: string; lGlyphLeftSpacing: Integer = 0; lTextOutPos: TPoint; @@ -320,90 +321,91 @@ var lColor: TColor; lRect: TRect; begin + if not (ADest is TCanvas) then Exit; // ToDo // Background corners lColor := AStateEx.ParentRGBColor; - ADest.Pixels[0, 0] := lColor; - ADest.Pixels[1, 0] := lColor; - ADest.Pixels[0, 1] := lColor; - ADest.Pixels[ASize.cx-1, 0] := lColor; - ADest.Pixels[ASize.cx-2, 0] := lColor; - ADest.Pixels[ASize.cx-1, 1] := lColor; - ADest.Pixels[0, ASize.cy-1] := lColor; - ADest.Pixels[1, ASize.cy-1] := lColor; - ADest.Pixels[0, ASize.cy-2] := lColor; - ADest.Pixels[ASize.cx-1, ASize.cy-1] := lColor; - ADest.Pixels[ASize.cx-2, ASize.cy-1] := lColor; - ADest.Pixels[ASize.cx-1, ASize.cy-2] := lColor; + lDest.Pixels[0, 0] := lColor; + lDest.Pixels[1, 0] := lColor; + lDest.Pixels[0, 1] := lColor; + lDest.Pixels[ASize.cx-1, 0] := lColor; + lDest.Pixels[ASize.cx-2, 0] := lColor; + lDest.Pixels[ASize.cx-1, 1] := lColor; + lDest.Pixels[0, ASize.cy-1] := lColor; + lDest.Pixels[1, ASize.cy-1] := lColor; + lDest.Pixels[0, ASize.cy-2] := lColor; + lDest.Pixels[ASize.cx-1, ASize.cy-1] := lColor; + lDest.Pixels[ASize.cx-2, ASize.cy-1] := lColor; + lDest.Pixels[ASize.cx-1, ASize.cy-2] := lColor; // Darker corners lColor := ANDROID_BUTTON_CORNERS; - ADest.Pixels[1, 1] := lColor; - ADest.Pixels[2, 0] := lColor; - ADest.Pixels[0, 2] := lColor; - ADest.Pixels[ASize.cx-3, 0] := lColor; - ADest.Pixels[ASize.cx-2, 1] := lColor; - ADest.Pixels[ASize.cx-1, 2] := lColor; - ADest.Pixels[0, ASize.cy-3] := lColor; - ADest.Pixels[1, ASize.cy-2] := lColor; - ADest.Pixels[2, ASize.cy-1] := lColor; - ADest.Pixels[ASize.cx-1, ASize.cy-3] := lColor; - ADest.Pixels[ASize.cx-2, ASize.cy-2] := lColor; - ADest.Pixels[ASize.cx-3, ASize.cy-1] := lColor; + lDest.Pixels[1, 1] := lColor; + lDest.Pixels[2, 0] := lColor; + lDest.Pixels[0, 2] := lColor; + lDest.Pixels[ASize.cx-3, 0] := lColor; + lDest.Pixels[ASize.cx-2, 1] := lColor; + lDest.Pixels[ASize.cx-1, 2] := lColor; + lDest.Pixels[0, ASize.cy-3] := lColor; + lDest.Pixels[1, ASize.cy-2] := lColor; + lDest.Pixels[2, ASize.cy-1] := lColor; + lDest.Pixels[ASize.cx-1, ASize.cy-3] := lColor; + lDest.Pixels[ASize.cx-2, ASize.cy-2] := lColor; + lDest.Pixels[ASize.cx-3, ASize.cy-1] := lColor; // Button image if csfSunken in AState then begin // Top lines - DrawAndroidAlternatedHorzLine(ADest, 3, ASize.cx-3, 0, ANDROID_BUTTON_SUNKEN_FIRST_LINE_A, ANDROID_BUTTON_SUNKEN_FIRST_LINE_B); - DrawAndroidAlternatedHorzLine(ADest, 2, ASize.cx-2, 1, ANDROID_BUTTON_SUNKEN_SECOND_LINE_A, ANDROID_BUTTON_SUNKEN_SECOND_LINE_B); - DrawAndroidAlternatedHorzLine(ADest, 1, ASize.cx-1, 2, ANDROID_BUTTON_SUNKEN_THIRD_LINE_A, ANDROID_BUTTON_SUNKEN_THIRD_LINE_B); + DrawAndroidAlternatedHorzLine(lDest, 3, ASize.cx-3, 0, ANDROID_BUTTON_SUNKEN_FIRST_LINE_A, ANDROID_BUTTON_SUNKEN_FIRST_LINE_B); + DrawAndroidAlternatedHorzLine(lDest, 2, ASize.cx-2, 1, ANDROID_BUTTON_SUNKEN_SECOND_LINE_A, ANDROID_BUTTON_SUNKEN_SECOND_LINE_B); + DrawAndroidAlternatedHorzLine(lDest, 1, ASize.cx-1, 2, ANDROID_BUTTON_SUNKEN_THIRD_LINE_A, ANDROID_BUTTON_SUNKEN_THIRD_LINE_B); // The central gradient lRect := Bounds(0, 3, ASize.cx, (ASize.cy-6) div 3+1); - DrawAndroidMixedVertGradientFill(ADest, lRect, ANDROID_BUTTON_SUNKEN_TOP_GRADIENT_A, + DrawAndroidMixedVertGradientFill(lDest, lRect, ANDROID_BUTTON_SUNKEN_TOP_GRADIENT_A, ANDROID_BUTTON_SUNKEN_MIDDLE_GRADIENT_A, ANDROID_BUTTON_SUNKEN_TOP_GRADIENT_B, ANDROID_BUTTON_SUNKEN_MIDDLE_GRADIENT_B); lRect := Bounds(0, 3+(ASize.cy-6) div 3, ASize.cx, (ASize.cy-6) div 3+1); - DrawAndroidMixedFill(ADest, lRect, ANDROID_BUTTON_SUNKEN_MIDDLE_GRADIENT_A, ANDROID_BUTTON_SUNKEN_MIDDLE_GRADIENT_B); + DrawAndroidMixedFill(lDest, lRect, ANDROID_BUTTON_SUNKEN_MIDDLE_GRADIENT_A, ANDROID_BUTTON_SUNKEN_MIDDLE_GRADIENT_B); lRect := Bounds(0, 3+2*(ASize.cy-6) div 3, ASize.cx, (ASize.cy-6) div 3+1); - DrawAndroidMixedVertGradientFill(ADest, lRect, ANDROID_BUTTON_SUNKEN_MIDDLE_GRADIENT_A, + DrawAndroidMixedVertGradientFill(lDest, lRect, ANDROID_BUTTON_SUNKEN_MIDDLE_GRADIENT_A, ANDROID_BUTTON_SUNKEN_BOTTOM_GRADIENT_A, ANDROID_BUTTON_SUNKEN_MIDDLE_GRADIENT_B, ANDROID_BUTTON_SUNKEN_BOTTOM_GRADIENT_B); // Bottom lines - DrawAndroidAlternatedHorzLine(ADest, 1, ASize.cx-1, ASize.cy-3, ANDROID_BUTTON_SUNKEN_PREPRELAST_LINE_A, ANDROID_BUTTON_SUNKEN_PREPRELAST_LINE_B); - DrawAndroidAlternatedHorzLine(ADest, 2, ASize.cx-2, ASize.cy-2, ANDROID_BUTTON_SUNKEN_PRELAST_LINE_A, ANDROID_BUTTON_SUNKEN_PRELAST_LINE_B); - DrawAndroidAlternatedHorzLine(ADest, 3, ASize.cx-3, ASize.cy-1, ANDROID_BUTTON_SUNKEN_LAST_LINE_A, ANDROID_BUTTON_SUNKEN_LAST_LINE_B); + DrawAndroidAlternatedHorzLine(lDest, 1, ASize.cx-1, ASize.cy-3, ANDROID_BUTTON_SUNKEN_PREPRELAST_LINE_A, ANDROID_BUTTON_SUNKEN_PREPRELAST_LINE_B); + DrawAndroidAlternatedHorzLine(lDest, 2, ASize.cx-2, ASize.cy-2, ANDROID_BUTTON_SUNKEN_PRELAST_LINE_A, ANDROID_BUTTON_SUNKEN_PRELAST_LINE_B); + DrawAndroidAlternatedHorzLine(lDest, 3, ASize.cx-3, ASize.cy-1, ANDROID_BUTTON_SUNKEN_LAST_LINE_A, ANDROID_BUTTON_SUNKEN_LAST_LINE_B); end else begin // Top lines - DrawAndroidAlternatedHorzLine(ADest, 3, ASize.cx-3, 0, ANDROID_BUTTON_FIRST_LINE_A, ANDROID_BUTTON_FIRST_LINE_B); - DrawAndroidAlternatedHorzLine(ADest, 2, ASize.cx-2, 1, ANDROID_BUTTON_SECOND_LINE_A, ANDROID_BUTTON_SECOND_LINE_B); - DrawAndroidAlternatedHorzLine(ADest, 1, ASize.cx-1, 2, ANDROID_BUTTON_THIRD_LINE_A, ANDROID_BUTTON_THIRD_LINE_B); + DrawAndroidAlternatedHorzLine(lDest, 3, ASize.cx-3, 0, ANDROID_BUTTON_FIRST_LINE_A, ANDROID_BUTTON_FIRST_LINE_B); + DrawAndroidAlternatedHorzLine(lDest, 2, ASize.cx-2, 1, ANDROID_BUTTON_SECOND_LINE_A, ANDROID_BUTTON_SECOND_LINE_B); + DrawAndroidAlternatedHorzLine(lDest, 1, ASize.cx-1, 2, ANDROID_BUTTON_THIRD_LINE_A, ANDROID_BUTTON_THIRD_LINE_B); // The central gradient lRect := Bounds(0, 3, ASize.cx, (ASize.cy-6) div 3+1); - DrawAndroidMixedVertGradientFill(ADest, lRect, ANDROID_BUTTON_TOP_GRADIENT_A, + DrawAndroidMixedVertGradientFill(lDest, lRect, ANDROID_BUTTON_TOP_GRADIENT_A, ANDROID_BUTTON_MIDDLE_GRADIENT_A, ANDROID_BUTTON_TOP_GRADIENT_B, ANDROID_BUTTON_MIDDLE_GRADIENT_B); lRect := Bounds(0, 3+(ASize.cy-6) div 3, ASize.cx, (ASize.cy-6) div 3+1); - DrawAndroidMixedFill(ADest, lRect, ANDROID_BUTTON_MIDDLE_GRADIENT_A, ANDROID_BUTTON_MIDDLE_GRADIENT_B); + DrawAndroidMixedFill(lDest, lRect, ANDROID_BUTTON_MIDDLE_GRADIENT_A, ANDROID_BUTTON_MIDDLE_GRADIENT_B); lRect := Bounds(0, 3+2*(ASize.cy-6) div 3, ASize.cx, (ASize.cy-6) div 3+1); - DrawAndroidMixedVertGradientFill(ADest, lRect, ANDROID_BUTTON_MIDDLE_GRADIENT_A, + DrawAndroidMixedVertGradientFill(lDest, lRect, ANDROID_BUTTON_MIDDLE_GRADIENT_A, ANDROID_BUTTON_BOTTOM_GRADIENT_A, ANDROID_BUTTON_MIDDLE_GRADIENT_B, ANDROID_BUTTON_BOTTOM_GRADIENT_B); // Bottom lines - DrawAndroidAlternatedHorzLine(ADest, 1, ASize.cx-1, ASize.cy-3, ANDROID_BUTTON_PREPRELAST_LINE_A, ANDROID_BUTTON_PREPRELAST_LINE_B); - DrawAndroidAlternatedHorzLine(ADest, 2, ASize.cx-2, ASize.cy-2, ANDROID_BUTTON_PRELAST_LINE_A, ANDROID_BUTTON_PRELAST_LINE_B); - DrawAndroidAlternatedHorzLine(ADest, 3, ASize.cx-3, ASize.cy-1, ANDROID_BUTTON_LAST_LINE_A, ANDROID_BUTTON_LAST_LINE_B); + DrawAndroidAlternatedHorzLine(lDest, 1, ASize.cx-1, ASize.cy-3, ANDROID_BUTTON_PREPRELAST_LINE_A, ANDROID_BUTTON_PREPRELAST_LINE_B); + DrawAndroidAlternatedHorzLine(lDest, 2, ASize.cx-2, ASize.cy-2, ANDROID_BUTTON_PRELAST_LINE_A, ANDROID_BUTTON_PRELAST_LINE_B); + DrawAndroidAlternatedHorzLine(lDest, 3, ASize.cx-3, ASize.cy-1, ANDROID_BUTTON_LAST_LINE_A, ANDROID_BUTTON_LAST_LINE_B); end; if csfHasFocus in AState then - DrawFocusRect(ADest, Point(5, 5), Size(ASize.cx-10, ASize.cy-10)); + DrawFocusRect(lDest, Point(5, 5), Size(ASize.cx-10, ASize.cy-10)); // Position calculations ADest.Font.Assign(AStateEx.Font); Str := AStateEx.Caption; - lGlyphCaptionHeight := Max(ADest.TextHeight(Str), AStateEx.Glyph.Height); - lTextOutPos.X := (ASize.cx - ADest.TextWidth(Str) - AStateEx.Glyph.Width) div 2; + lGlyphCaptionHeight := Max(lDest.TextHeight(Str), AStateEx.Glyph.Height); + lTextOutPos.X := (ASize.cx - lDest.TextWidth(Str) - AStateEx.Glyph.Width) div 2; lTextOutPos.Y := (ASize.cy - lGlyphCaptionHeight) div 2; lTextOutPos.X := Max(lTextOutPos.X, 5); lTextOutPos.Y := Max(lTextOutPos.Y, 5); @@ -411,13 +413,13 @@ begin // Button glyph if not AStateEx.Glyph.Empty then begin - ADest.Draw(lTextOutPos.X, lTextOutPos.Y, AStateEx.Glyph); + lDest.Draw(lTextOutPos.X, lTextOutPos.Y, AStateEx.Glyph); lGlyphLeftSpacing := AStateEx.Glyph.Width+5; end; // Button text lTextOutPos.X := lTextOutPos.X + lGlyphLeftSpacing; - lTextOutPos.Y := (ASize.cy - ADest.TextHeight(Str)) div 2; + lTextOutPos.Y := (ASize.cy - lDest.TextHeight(Str)) div 2; ADest.Brush.Style := bsClear; ADest.Pen.Style := psSolid; if csfSunken in AState then @@ -425,7 +427,7 @@ begin Inc(lTextOutPos.X); Inc(lTextOutPos.Y); end; - ADest.TextOut(lTextOutPos.X, lTextOutPos.Y, Str) + lDest.TextOut(lTextOutPos.X, lTextOutPos.Y, Str) end; procedure TCDDrawerAndroid.DrawCheckBoxSquare(ADest: TCanvas; ADestPos: TPoint; diff --git a/components/customdrawn/customdrawn_wince.pas b/components/customdrawn/customdrawn_wince.pas index cceea37898..213eb42a3f 100644 --- a/components/customdrawn/customdrawn_wince.pas +++ b/components/customdrawn/customdrawn_wince.pas @@ -32,7 +32,7 @@ type // Standard Tab // =================================== // TCDButton - procedure DrawButton(ADest: TCanvas; ASize: TSize; + procedure DrawButton(ADest: TFPCustomCanvas; ASize: TSize; AState: TCDControlState; AStateEx: TCDButtonStateEx); override; // TCDEdit procedure DrawEditFrame(ADest: TCanvas; ADestPos: TPoint; ASize: TSize; @@ -85,41 +85,43 @@ begin ADest.Rectangle(Bounds(ADestPos.X, ADestPos.Y, ASize.cx, ASize.cy)); end; -procedure TCDDrawerWinCE.DrawButton(ADest: TCanvas; +procedure TCDDrawerWinCE.DrawButton(ADest: TFPCustomCanvas; ASize: TSize; AState: TCDControlState; AStateEx: TCDButtonStateEx); var + lDest: TCanvas absolute ADest; Str: string; begin + if not (ADest is TCanvas) then Exit; // ToDo support non-TCanvas // Button background if csfSunken in AState then begin ADest.Brush.Style := bsSolid; - ADest.Brush.Color := Palette.BtnShadow; - ADest.Pen.Color := clBlack; + lDest.Brush.Color := Palette.BtnShadow; + lDest.Pen.Color := clBlack; ADest.Pen.Style := psSolid; ADest.Rectangle(0, 0, ASize.cx, ASize.cy); end else begin ADest.Brush.Style := bsSolid; - ADest.Brush.Color := AStateEx.RGBColor; - ADest.Pen.Color := clBlack; + lDest.Brush.Color := AStateEx.RGBColor; + lDest.Pen.Color := clBlack; ADest.Pen.Style := psSolid; ADest.Rectangle(0, 0, ASize.cx, ASize.cy); end; // Focus if (csfHasFocus in AState) and not (csfSunken in AState) then - DrawFocusRect(ADest, Point(4, 4), Size(ASize.cx-8, ASize.cy-8)); + DrawFocusRect(lDest, Point(4, 4), Size(ASize.cx-8, ASize.cy-8)); // Button text ADest.Font.Assign(AStateEx.Font); ADest.Brush.Style := bsClear; ADest.Pen.Style := psSolid; - if csfSunken in AState then ADest.Font.Color := clWhite; + if csfSunken in AState then lDest.Font.Color := clWhite; Str := AStateEx.Caption; - ADest.TextOut((ASize.cx - ADest.TextWidth(Str)) div 2, - (ASize.cy - ADest.TextHeight(Str)) div 2, Str); + lDest.TextOut((ASize.cx - lDest.TextWidth(Str)) div 2, + (ASize.cy - lDest.TextHeight(Str)) div 2, Str); end; procedure TCDDrawerWinCE.DrawEditFrame(ADest: TCanvas; ADestPos: TPoint; diff --git a/components/customdrawn/customdrawn_winxp.pas b/components/customdrawn/customdrawn_winxp.pas index 7595609309..da14e12a6f 100644 --- a/components/customdrawn/customdrawn_winxp.pas +++ b/components/customdrawn/customdrawn_winxp.pas @@ -6,7 +6,7 @@ interface uses // RTL - Classes, SysUtils, Types, + Classes, SysUtils, Types, fpcanvas, fpimage, // LCL -> Use only TForm, TWinControl, TCanvas and TLazIntfImage Graphics, Controls, LCLType, // @@ -38,7 +38,7 @@ type // Standard Tab // =================================== // TCDButton - procedure DrawButton(ADest: TCanvas; ASize: TSize; + procedure DrawButton(ADest: TFPCustomCanvas; ASize: TSize; AState: TCDControlState; AStateEx: TCDButtonStateEx); override; // TCDEdit procedure DrawEditFrame(ADest: TCanvas; ADestPos: TPoint; ASize: TSize; @@ -152,9 +152,10 @@ begin ADest.Line(ADestPos.X+i, ADestPos.Y+4-i, ADestPos.X+i, ADestPos.Y+3+4-i); end; -procedure TCDDrawerWinXP.DrawButton(ADest: TCanvas; +procedure TCDDrawerWinXP.DrawButton(ADest: TFPCustomCanvas; ASize: TSize; AState: TCDControlState; AStateEx: TCDButtonStateEx); var + lDest: TCanvas absolute ADest; Str: string; lColor: TColor; lRect: TRect; @@ -163,39 +164,39 @@ var begin // Background corners lColor := AStateEx.ParentRGBColor; - ADest.Pixels[0, 0] := lColor; - ADest.Pixels[ASize.cx-1, 0] := lColor; - ADest.Pixels[0, ASize.cy-1] := lColor; - ADest.Pixels[ASize.cx-1, ASize.cy-1] := lColor; + lDest.Pixels[0, 0] := lColor; + lDest.Pixels[ASize.cx-1, 0] := lColor; + lDest.Pixels[0, ASize.cy-1] := lColor; + lDest.Pixels[ASize.cx-1, ASize.cy-1] := lColor; // Main body if csfSunken in AState then begin ADest.Brush.Style := bsSolid; - ADest.Brush.Color := WINXP_BUTTON_SUNKEN_BODY_BOTTOM; - ADest.Pen.Color := WINXP_BUTTON_SUNKEN_BODY_BOTTOM; + lDest.Brush.Color := WINXP_BUTTON_SUNKEN_BODY_BOTTOM; + lDest.Pen.Color := WINXP_BUTTON_SUNKEN_BODY_BOTTOM; ADest.Rectangle(1, 1, ASize.cx-1, ASize.cy-1); end else if csfEnabled in AState then begin // First the gradient lRect := Bounds(1, 1, ASize.cx-4, ASize.cy-5); - ADest.GradientFill(lRect, WINXP_BUTTON_BODY_TOP, WINXP_BUTTON_BODY_BOTTOM, gdVertical); + lDest.GradientFill(lRect, WINXP_BUTTON_BODY_TOP, WINXP_BUTTON_BODY_BOTTOM, gdVertical); // Now the extra lines which make the bottom-right - ADest.Pen.Color := WINXP_BUTTON_BODY_LINES_PREPRELAST; + lDest.Pen.Color := WINXP_BUTTON_BODY_LINES_PREPRELAST; ADest.Line(1, ASize.cy-4, ASize.cx-3, ASize.cy-4); ADest.Line(ASize.cx-3, ASize.cy-4, ASize.cx-3, 1); - ADest.Pen.Color := WINXP_BUTTON_BODY_LINES_PRELAST; + lDest.Pen.Color := WINXP_BUTTON_BODY_LINES_PRELAST; ADest.Line(2, ASize.cy-3, ASize.cx-2, ASize.cy-3); ADest.Line(ASize.cx-2, ASize.cy-3, ASize.cx-2, 2); - ADest.Pen.Color := WINXP_BUTTON_BODY_LINES_LAST; + lDest.Pen.Color := WINXP_BUTTON_BODY_LINES_LAST; ADest.Line(3, ASize.cy-1, ASize.cx-3, ASize.cy-1); end else // disabled begin ADest.Brush.Style := bsSolid; - ADest.Brush.Color := WINXP_BUTTON_DISABLED_BODY; - ADest.Pen.Color := WINXP_BUTTON_DISABLED_BODY; + lDest.Brush.Color := WINXP_BUTTON_DISABLED_BODY; + lDest.Pen.Color := WINXP_BUTTON_DISABLED_BODY; ADest.Rectangle(1, 1, ASize.cx-1, ASize.cy-1); end; @@ -215,35 +216,35 @@ begin lFrameLight := WINXP_BUTTON_FRAME_LIGHT_DISABLED; end; - ADest.Pixels[1, 0] := lFrameMedium; - ADest.Pixels[0, 1] := lFrameMedium; - ADest.Pixels[1, 1] := lFrameMedDark; - ADest.Pixels[2, 1] := lFrameLight; - ADest.Pixels[1, 2] := lFrameLight; + lDest.Pixels[1, 0] := lFrameMedium; + lDest.Pixels[0, 1] := lFrameMedium; + lDest.Pixels[1, 1] := lFrameMedDark; + lDest.Pixels[2, 1] := lFrameLight; + lDest.Pixels[1, 2] := lFrameLight; - ADest.Pixels[ASize.cx-2, 0] := lFrameMedium; - ADest.Pixels[ASize.cx-1, 1] := lFrameMedium; - ADest.Pixels[ASize.cx-2, 1] := lFrameMedDark; - ADest.Pixels[ASize.cx-3, 1] := lFrameLight; - ADest.Pixels[ASize.cx-2, 2] := lFrameLight; + lDest.Pixels[ASize.cx-2, 0] := lFrameMedium; + lDest.Pixels[ASize.cx-1, 1] := lFrameMedium; + lDest.Pixels[ASize.cx-2, 1] := lFrameMedDark; + lDest.Pixels[ASize.cx-3, 1] := lFrameLight; + lDest.Pixels[ASize.cx-2, 2] := lFrameLight; - ADest.Pixels[1, ASize.cy-1] := lFrameMedium; - ADest.Pixels[0, ASize.cy-2] := lFrameMedium; - ADest.Pixels[1, ASize.cy-2] := lFrameMedDark; - ADest.Pixels[2, ASize.cy-2] := lFrameLight; - ADest.Pixels[1, ASize.cy-3] := lFrameLight; + lDest.Pixels[1, ASize.cy-1] := lFrameMedium; + lDest.Pixels[0, ASize.cy-2] := lFrameMedium; + lDest.Pixels[1, ASize.cy-2] := lFrameMedDark; + lDest.Pixels[2, ASize.cy-2] := lFrameLight; + lDest.Pixels[1, ASize.cy-3] := lFrameLight; - ADest.Pixels[ASize.cx-2, ASize.cy-1] := lFrameMedium; - ADest.Pixels[ASize.cx-1, ASize.cy-2] := lFrameMedium; - ADest.Pixels[ASize.cx-2, ASize.cy-2] := lFrameMedDark; - ADest.Pixels[ASize.cx-3, ASize.cy-2] := lFrameLight; - ADest.Pixels[ASize.cx-2, ASize.cy-3] := lFrameLight; + lDest.Pixels[ASize.cx-2, ASize.cy-1] := lFrameMedium; + lDest.Pixels[ASize.cx-1, ASize.cy-2] := lFrameMedium; + lDest.Pixels[ASize.cx-2, ASize.cy-2] := lFrameMedDark; + lDest.Pixels[ASize.cx-3, ASize.cy-2] := lFrameLight; + lDest.Pixels[ASize.cx-2, ASize.cy-3] := lFrameLight; - ADest.Pen.Color := lFrameDark; - ADest.Line(2, 0, ASize.cx-2, 0); - ADest.Line(2, ASize.cy-1, ASize.cx-2, ASize.cy-1); - ADest.Line(0, 2, 0, ASize.cy-2); - ADest.Line(ASize.cx-1, 2, ASize.cx-1, ASize.cy-2); + lDest.Pen.Color := lFrameDark; + lDest.Line(2, 0, ASize.cx-2, 0); + lDest.Line(2, ASize.cy-1, ASize.cx-2, ASize.cy-1); + lDest.Line(0, 2, 0, ASize.cy-2); + lDest.Line(ASize.cx-1, 2, ASize.cx-1, ASize.cy-2); // Now focus / mouseover indication, note that both disappear when sunked in WinXP if ((csfHasFocus in AState) or (csfMouseOver in AState)) and not (csfSunken in AState) then @@ -264,19 +265,19 @@ begin end; // Top - ADest.Pen.Color := lSelTop; + lDest.Pen.Color := lSelTop; ADest.Line(2, 1, ASize.cx-2, 1); - ADest.Pen.Color := lSelTopGrad; + lDest.Pen.Color := lSelTopGrad; ADest.Line(1, 2, ASize.cx-1, 2); // Gradient lRect := Bounds(1, 2, 2, ASize.cy-4); - ADest.GradientFill(lRect, lSelTopGrad, lSelBottomGrad, gdVertical); + lDest.GradientFill(lRect, lSelTopGrad, lSelBottomGrad, gdVertical); lRect := Bounds(ASize.cx-3, 2, 2, ASize.cy-4); - ADest.GradientFill(lRect, lSelTopGrad, lSelBottomGrad, gdVertical); + lDest.GradientFill(lRect, lSelTopGrad, lSelBottomGrad, gdVertical); // Bottom - ADest.Pen.Color := lSelBottomGrad; + lDest.Pen.Color := lSelBottomGrad; ADest.Line(1, ASize.cy-3, ASize.cx-1, ASize.cy-3); - ADest.Pen.Color := lSelBottom; + lDest.Pen.Color := lSelBottom; ADest.Line(2, ASize.cy-2, ASize.cx-2, ASize.cy-2); end; @@ -285,8 +286,8 @@ begin ADest.Brush.Style := bsClear; ADest.Pen.Style := psSolid; Str := AStateEx.Caption; - ADest.TextOut((ASize.cx - ADest.TextWidth(Str)) div 2, - (ASize.cy - ADest.TextHeight(Str)) div 2, Str); + lDest.TextOut((ASize.cx - lDest.TextWidth(Str)) div 2, + (ASize.cy - lDest.TextHeight(Str)) div 2, Str); end; procedure TCDDrawerWinXP.DrawEditFrame(ADest: TCanvas; ADestPos: TPoint; diff --git a/lcl/customdrawn_common.pas b/lcl/customdrawn_common.pas index 9b720390a8..401e3443fc 100644 --- a/lcl/customdrawn_common.pas +++ b/lcl/customdrawn_common.pas @@ -6,7 +6,7 @@ interface uses // RTL / FCL - Classes, SysUtils, Types, Math, fpcanvas, + Classes, SysUtils, Types, Math, fpcanvas, fpimage, // LazUtils lazutf8, // LCL -> Use only TForm, TWinControl, TCanvas and TLazIntfImage @@ -55,7 +55,7 @@ type // Standard Tab // =================================== // TCDButton - procedure DrawButton(ADest: TCanvas; ASize: TSize; + procedure DrawButton(ADest: TFPCustomCanvas; ASize: TSize; AState: TCDControlState; AStateEx: TCDButtonStateEx); override; // TCDEdit procedure DrawEditBackground(ADest: TCanvas; ADestPos: TPoint; ASize: TSize; @@ -638,7 +638,7 @@ begin ADest.FillRect(0, 0, ASize.cx, ASize.cy); end; -procedure TCDDrawerCommon.DrawButton(ADest: TCanvas; +procedure TCDDrawerCommon.DrawButton(ADest: TFPCustomCanvas; ASize: TSize; AState: TCDControlState; AStateEx: TCDButtonStateEx); var Str: string; @@ -648,20 +648,20 @@ var begin // background ADest.Brush.Style := bsSolid; - ADest.Brush.Color := AStateEx.RGBColor; - ADest.Pen.Color := clWhite; + ADest.Brush.FPColor := AStateEx.FPRGBColor; + ADest.Pen.FPColor := colWhite; ADest.Pen.Style := psSolid; ADest.Rectangle(0, 0, ASize.cx - 1, ASize.cy - 1); - ADest.Pen.Color := clWhite; + ADest.Pen.FPColor := colWhite; ADest.Line(0, 0, ASize.cx - 1, 0); ADest.Line(0, 0, 0, ASize.cy - 1); - ADest.Pen.Color := clGray; + ADest.Pen.FPColor := colGray; ADest.Line(0, ASize.cy - 1, ASize.cx - 1, ASize.cy - 1); ADest.Line(ASize.cx - 1, ASize.cy - 1, ASize.cx - 1, -1); - ADest.Pen.Color := $0099A8AC; + ADest.Pen.FPColor := TColorToFPColor($0099A8AC); ADest.Line(1, ASize.cy - 2, ASize.cx - 2, ASize.cy - 2); ADest.Line(ASize.cx - 2, ASize.cx - 2, ASize.cx - 2, 0); - ADest.Pen.Color := $00E2EFF1; + ADest.Pen.FPColor := TColorToFPColor($00E2EFF1); ADest.Line(1, 1, ASize.cx - 2, 1); ADest.Line(1, 1, 1, ASize.cy - 2); @@ -669,70 +669,74 @@ begin if csfSunken in AState then begin ADest.Brush.Style := bsSolid; - ADest.Brush.Color := AStateEx.RGBColor; - ADest.Pen.Color := clWhite; + ADest.Brush.FPColor := AStateEx.FPRGBColor; + ADest.Pen.FPColor := colWhite; ADest.Pen.Style := psSolid; ADest.Rectangle(0, 0, ASize.cx - 1, ASize.cy - 1); - ADest.Pen.Color := clGray; + ADest.Pen.FPColor := colGray; ADest.Line(0, 0, ASize.cx - 1, 0); ADest.Line(0, 0, 0, ASize.cy - 1); - ADest.Pen.Color := clWhite; + ADest.Pen.FPColor := colWhite; ADest.Line(0, ASize.cy - 1, ASize.cx - 1, ASize.cy - 1); ADest.Line(ASize.cx - 1, ASize.cy - 1, ASize.cx - 1, -1); - ADest.Pen.Color := $00E2EFF1; + ADest.Pen.FPColor := TColorToFPColor($00E2EFF1); ADest.Line(1, ASize.cy - 2, ASize.cx - 2, ASize.cy - 2); ADest.Line(ASize.cx - 2, ASize.cy - 2, ASize.cx - 2, 0); - ADest.Pen.Color := $0099A8AC; + ADest.Pen.FPColor := TColorToFPColor($0099A8AC); ADest.Line(1, 1, ASize.cx - 2, 1); ADest.Line(1, 1, 1, ASize.cy - 2); end else if csfHasFocus in AState then begin - DrawFocusRect(ADest, Point(3, 3), Size(ASize.cx - 7, ASize.cy - 7)); + if ADest is TCanvas then + DrawFocusRect(TCanvas(ADest), Point(3, 3), Size(ASize.cx - 7, ASize.cy - 7)); end; // Position calculations - ADest.Font.Assign(AStateEx.Font); - Str := AStateEx.Caption; - lGlyphCaptionHeight := Max(ADest.TextHeight(Str), AStateEx.Glyph.Height); - lTextOutPos.X := (ASize.cx - ADest.TextWidth(Str) - AStateEx.Glyph.Width) div 2; - lTextOutPos.Y := (ASize.cy - lGlyphCaptionHeight) div 2; - lTextOutPos.X := Max(lTextOutPos.X, 5); - lTextOutPos.Y := Max(lTextOutPos.Y, 5); - - // Button glyph - if not AStateEx.Glyph.Empty then + if ADest is TCanvas then begin - ADest.Draw(lTextOutPos.X, lTextOutPos.Y, AStateEx.Glyph); - lGlyphLeftSpacing := AStateEx.Glyph.Width+5; - end; + ADest.Font.Assign(AStateEx.Font); + Str := AStateEx.Caption; + lGlyphCaptionHeight := Max(TCanvas(ADest).TextHeight(Str), AStateEx.Glyph.Height); + lTextOutPos.X := (ASize.cx - TCanvas(ADest).TextWidth(Str) - AStateEx.Glyph.Width) div 2; + lTextOutPos.Y := (ASize.cy - lGlyphCaptionHeight) div 2; + lTextOutPos.X := Max(lTextOutPos.X, 5); + lTextOutPos.Y := Max(lTextOutPos.Y, 5); - // Button text - lTextOutPos.X := lTextOutPos.X + lGlyphLeftSpacing; - lTextOutPos.Y := (ASize.cy - ADest.TextHeight(Str)) div 2; - ADest.Brush.Style := bsClear; - ADest.Pen.Style := psSolid; - if csfEnabled in AState then - begin - if csfSunken in AState then + // Button glyph + if not AStateEx.Glyph.Empty then begin + TCanvas(ADest).Draw(lTextOutPos.X, lTextOutPos.Y, AStateEx.Glyph); + lGlyphLeftSpacing := AStateEx.Glyph.Width+5; + end; + + // Button text + lTextOutPos.X := lTextOutPos.X + lGlyphLeftSpacing; + lTextOutPos.Y := (ASize.cy - TCanvas(ADest).TextHeight(Str)) div 2; + ADest.Brush.Style := bsClear; + ADest.Pen.Style := psSolid; + if csfEnabled in AState then + begin + if csfSunken in AState then + begin + Inc(lTextOutPos.X); + Inc(lTextOutPos.Y); + end; + ADest.TextOut(lTextOutPos.X, lTextOutPos.Y, Str) + end + else + begin + // The disabled text is composed by a white shadow under it and a grey text + TCanvas(ADest).Font.Color := clWhite; Inc(lTextOutPos.X); Inc(lTextOutPos.Y); + TCanvas(ADest).TextOut(lTextOutPos.X, lTextOutPos.Y, Str); + // + TCanvas(ADest).Font.Color := WIN2000_DISABLED_TEXT; + Dec(lTextOutPos.X); + Dec(lTextOutPos.Y); + ADest.TextOut(lTextOutPos.X, lTextOutPos.Y, Str); end; - ADest.TextOut(lTextOutPos.X, lTextOutPos.Y, Str) - end - else - begin - // The disabled text is composed by a white shadow under it and a grey text - ADest.Font.Color := clWhite; - Inc(lTextOutPos.X); - Inc(lTextOutPos.Y); - ADest.TextOut(lTextOutPos.X, lTextOutPos.Y, Str); - // - ADest.Font.Color := WIN2000_DISABLED_TEXT; - Dec(lTextOutPos.X); - Dec(lTextOutPos.Y); - ADest.TextOut(lTextOutPos.X, lTextOutPos.Y, Str); end; end; @@ -1175,10 +1179,10 @@ begin if FCaptionMiddle = 0 then FCaptionMiddle := 5; // Background - ADest.Brush.FPColor := TColorToFPColor(AStateEx.ParentRGBColor); + ADest.Brush.FPColor := AStateEx.FPParentRGBColor; ADest.Brush.Style := bsSolid; ADest.Pen.Style := psSolid; - ADest.Pen.FPColor := TColorToFPColor(AStateEx.ParentRGBColor); + ADest.Pen.FPColor := AStateEx.FPParentRGBColor; ADest.Rectangle(0, 0, ASize.cx, ASize.cy); // frame @@ -1201,7 +1205,7 @@ begin // fill the text background ADest.Brush.Style := bsSolid; - ADest.Brush.FPColor := TColorToFPColor(AStateEx.ParentRGBColor); + ADest.Brush.FPColor := AStateEx.FPParentRGBColor; ADest.Pen.Style := psClear; ADest.Rectangle(Bounds(FCaptionMiddle, 0, lTextSize.cx+5, lTextSize.cy)); diff --git a/lcl/customdrawncontrols.pas b/lcl/customdrawncontrols.pas index 55b50ee1d1..60bb05240a 100644 --- a/lcl/customdrawncontrols.pas +++ b/lcl/customdrawncontrols.pas @@ -810,9 +810,11 @@ procedure TCDControl.PrepareControlStateEx; begin if Parent <> nil then FStateEx.ParentRGBColor := Parent.GetRGBColorResolvingParent else FStateEx.ParentRGBColor := clSilver; + FStateEx.FPParentRGBColor := TColorToFPColor(FStateEx.ParentRGBColor); if Color = clDefault then FStateEx.RGBColor := FDrawer.GetControlDefaultColor(GetControlId()) else FStateEx.RGBColor := GetRGBColorResolvingParent; + FStateEx.FPRGBColor := TColorToFPColor(FStateEx.RGBColor); FStateEx.Caption := Caption; FStateEx.Font := Font; diff --git a/lcl/customdrawndrawers.pas b/lcl/customdrawndrawers.pas index c6c309e5f3..0e501f56cf 100644 --- a/lcl/customdrawndrawers.pas +++ b/lcl/customdrawndrawers.pas @@ -5,7 +5,7 @@ unit customdrawndrawers; interface uses - Classes, SysUtils, Types, fpcanvas, + Classes, SysUtils, Types, fpcanvas, fpimage, // LCL for types Controls, Graphics, ComCtrls, ExtCtrls; @@ -129,7 +129,9 @@ type TCDControlStateEx = class public ParentRGBColor: TColor; + FPParentRGBColor: TFPColor; RGBColor: TColor; + FPRGBColor: TFPColor; Caption: string; Font: TFont; // Just a reference, never Free AutoSize: Boolean; @@ -312,7 +314,7 @@ type procedure DrawControl(ADest: TCanvas; ASize: TSize; AState: TCDControlState; AStateEx: TCDControlStateEx); virtual; abstract; // TCDButton - procedure DrawButton(ADest: TCanvas; ASize: TSize; + procedure DrawButton(ADest: TFPCustomCanvas; ASize: TSize; AState: TCDControlState; AStateEx: TCDButtonStateEx); virtual; abstract; // TCDEdit procedure DrawEditBackground(ADest: TCanvas; ADestPos: TPoint; ASize: TSize; diff --git a/lcl/interfaces/customdrawn/customdrawnwinapi.inc b/lcl/interfaces/customdrawn/customdrawnwinapi.inc index fba6c6713a..2524b40192 100644 --- a/lcl/interfaces/customdrawn/customdrawnwinapi.inc +++ b/lcl/interfaces/customdrawn/customdrawnwinapi.inc @@ -1146,6 +1146,8 @@ function TCDWidgetSet.DrawFrameControl(DC: HDC; const Rect: TRect; uType, var LazDC: TLazCanvas absolute DC; lControlStateEx: TCDControlStateEx; + lState: TCDControlState; + lSize: TSize; begin Result := False; @@ -1160,44 +1162,50 @@ begin case uType of DFC_BUTTON: begin - lControlStateEx := TCDControlStateEx.Create; + lSize := Types.Size(Rect.Right-Rect.Left, Rect.Bottom-Rect.Top); + + if (DFCS_BUTTONPUSH and uState) <> 0 then + lControlStateEx := TCDButtonStateEx.Create + else + lControlStateEx := TCDControlStateEx.Create; + try lControlStateEx.Font := TFont.Create; - {if uState and DFCS_FLAT <> 0 then - Features := QStyleOptionButtonFlat - else - Features := QStyleOptionButtonNone; - if (uState and $1F) in [DFCS_BUTTONCHECK, DFCS_BUTTON3STATE] then - Element := QStyleCE_CheckBox - else - if (DFCS_BUTTONRADIO and uState) <> 0 then - Element := QStyleCE_RadioButton - else - if (DFCS_BUTTONPUSH and uState) <> 0 then - Element := QStyleCE_PushButton - else - if (DFCS_BUTTONRADIOIMAGE and uState) <> 0 then - Element := QStyleCE_RadioButton - //TODO: what to implement here ? - else - if (DFCS_BUTTONRADIOMASK and uState) <> 0 then - Element := QStyleCE_RadioButton - //TODO: what to implement here ? - ;} - {Opt := QStyleOptionButton_create(); - QStyleOptionButton_setFeatures(Opt, Features); - QStyleOption_setRect(Opt, @Rect); - QStyleOption_setState(Opt, State); - QStyle_drawControl(QApplication_style(), Element, Opt, Painter, Widget); - QStyleOptionButton_destroy(Opt);} + lControlStateEx.ParentRGBColor := clSilver; + lControlStateEx.FPParentRGBColor := colSilver; + lControlStateEx.RGBColor := GetDefaultDrawer().FallbackPalette.BtnFace; + lControlStateEx.FPRGBColor := TColorToFPColor(lControlStateEx.RGBColor); - //GetDefaultDrawer().DrawButton(); + //if uState and DFCS_FLAT <> 0 then lState := [csfEnabled]; + if uState and DFCS_INACTIVE = 0 then lState := lState + [csfEnabled]; + if uState and DFCS_PUSHED <> 0 then lState := lState + [csfSunken]; + + if (uState and $1F) in [DFCS_BUTTONCHECK, DFCS_BUTTON3STATE] then + begin + //Element := QStyleCE_CheckBox + end + else if (DFCS_BUTTONRADIO and uState) <> 0 then + begin + //Element := QStyleCE_RadioButton + end + else if (DFCS_BUTTONPUSH and uState) <> 0 then + begin + GetDefaultDrawer().DrawButton(LazDC, lSize, lState, TCDButtonStateEx(lControlStateEx)); + end + else if (DFCS_BUTTONRADIOIMAGE and uState) <> 0 then + begin + //Element := QStyleCE_RadioButton + //TODO: what to implement here ? + end + else if (DFCS_BUTTONRADIOMASK and uState) <> 0 then + begin + //Element := QStyleCE_RadioButton + //TODO: what to implement here ? + end; finally lControlStateEx.Font.Free; lControlStateEx.Free; end; - begin - end; end; DFC_CAPTION: ; // title bar captions DFC_MENU: ; // menu