diff --git a/components/exctrls/exctrlspkg.lpk b/components/exctrls/exctrlspkg.lpk
index 58d5c9e3f..6e1c8b27f 100644
--- a/components/exctrls/exctrlspkg.lpk
+++ b/components/exctrls/exctrlspkg.lpk
@@ -17,7 +17,7 @@
- CurrencyEdit
- TRadioButton, TCheckbox, TRadioGroup and TCheckGroup: drawn by ThemeServices/Canvas, not by widgetset, button/text layout, wordwrap, user-provided check images"/>
-
+
@@ -31,6 +31,10 @@
+
+
+
+
diff --git a/components/exctrls/exctrlspkg.pas b/components/exctrls/exctrlspkg.pas
index 403753cc9..ed4fb1d19 100644
--- a/components/exctrls/exctrlspkg.pas
+++ b/components/exctrls/exctrlspkg.pas
@@ -8,7 +8,7 @@ unit ExCtrlsPkg;
interface
uses
- ExCheckCtrls, ExEditCtrls, ExCtrlsReg, LazarusPackageIntf;
+ ExCheckCtrls, ExEditCtrls, ExCtrlsReg, ExButtons, LazarusPackageIntf;
implementation
diff --git a/components/exctrls/images/imagelist.txt b/components/exctrls/images/imagelist.txt
index 7d6b03466..afc1b7ba1 100644
--- a/components/exctrls/images/imagelist.txt
+++ b/components/exctrls/images/imagelist.txt
@@ -1,3 +1,6 @@
+tbuttonex.png
+tbuttonex_150.png
+tbuttonex_200.png
tradiobuttonex.png
tradiobuttonex_150.png
tradiobuttonex_200.png
diff --git a/components/exctrls/images/tbuttonex.png b/components/exctrls/images/tbuttonex.png
new file mode 100644
index 000000000..493530ba7
Binary files /dev/null and b/components/exctrls/images/tbuttonex.png differ
diff --git a/components/exctrls/images/tbuttonex_150.png b/components/exctrls/images/tbuttonex_150.png
new file mode 100644
index 000000000..d3f9ac36c
Binary files /dev/null and b/components/exctrls/images/tbuttonex_150.png differ
diff --git a/components/exctrls/images/tbuttonex_200.png b/components/exctrls/images/tbuttonex_200.png
new file mode 100644
index 000000000..e9adcc773
Binary files /dev/null and b/components/exctrls/images/tbuttonex_200.png differ
diff --git a/components/exctrls/source/exbuttons.pas b/components/exctrls/source/exbuttons.pas
new file mode 100644
index 000000000..29b85b8d9
--- /dev/null
+++ b/components/exctrls/source/exbuttons.pas
@@ -0,0 +1,1013 @@
+unit ExButtons;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Graphics, Classes, SysUtils, LMessages, Types, Controls, StdCtrls, Forms;
+
+type
+ TButtonExState = (bxsNormal, bxsHot, bxsDown, bxsFocused, bxsDisabled);
+ TButtonExBorderWidth = 1..10;
+
+ TButtonEx = class;
+
+ TButtonExBorder = class(TPersistent)
+ private
+ FButton: TButtonEx;
+ FColorNormal: TColor;
+ FColorHot: TColor;
+ FColorDown: TColor;
+ FColorDisabled: TColor;
+ FColorFocused: TColor;
+ FWidthNormal: TButtonExBorderWidth;
+ FWidthHot: TButtonExBorderWidth;
+ FWidthDown: TButtonExBorderWidth;
+ FWidthDisabled: TButtonExBorderWidth;
+ FWidthFocused: TButtonExBorderWidth;
+ procedure SetWidthNormal(const Value: TButtonExBorderWidth);
+ procedure SetColorNormal(const Value: TColor);
+ public
+ constructor Create(AButton: TButtonEx);
+ published
+ property ColorNormal: TColor read FColorNormal write SetColorNormal;
+ property ColorHot: TColor read FColorHot write FColorHot;
+ property ColorDown: TColor read FColorDown write FColorDown;
+ property ColorDisabled: TColor read FColorDisabled write FColorDisabled;
+ property ColorFocused: TColor read FColorFocused write FColorFocused;
+ property WidthNormal: TButtonExBorderWidth read FWidthNormal write SetWidthNormal;
+ property WidthHot: TButtonExBorderWidth read FWidthHot write FWidthHot;
+ property WidthDown: TButtonExBorderWidth read FWidthDown write FWidthDown;
+ property WidthDisabled: TButtonExBorderWidth read FWidthDisabled write FWidthDisabled;
+ property WidthFocused: TButtonExBorderWidth read FWidthFocused write FWidthFocused;
+ end;
+
+ TButtonExColors = class(TPersistent)
+ private
+ FButton: TButtonEx;
+ FColorNormalFrom: TColor;
+ FColorNormalTo: TColor;
+ FColorHotFrom: TColor;
+ FColorHotTo: TColor;
+ FColorDownFrom: TColor;
+ FColorDownTo: TColor;
+ FColorDisabledFrom: TColor;
+ FColorDisabledTo: TColor;
+ FColorFocusedFrom: TColor;
+ FColorFocusedTo: TColor;
+ procedure SetColorNormalFrom(const Value: TColor);
+ procedure SetColorNormalTo(const Value: TColor);
+ public
+ constructor Create(AButton: TButtonEx);
+ published
+ property ColorNormalFrom: TColor read FColorNormalFrom write SetColorNormalFrom;
+ property ColorNormalTo: TColor read FColorNormalTo write SetColorNormalTo;
+ property ColorHotFrom: TColor read FColorHotFrom write FColorHotFrom;
+ property ColorHotTo: TColor read FColorHotTo write FColorHotTo;
+ property ColorDownFrom: TColor read FColorDownFrom write FColorDownFrom;
+ property ColorDownTo: TColor read FColorDownTo write FColorDownTo;
+ property ColorDisabledFrom: TColor read FColorDisabledFrom write FColorDisabledFrom;
+ property ColorDisabledTo: TColor read FColorDisabledTo write FColorDisabledTo;
+ property ColorFocusedFrom: TColor read FColorFocusedFrom write FColorFocusedFrom;
+ property ColorFocusedTo: TColor read FColorFocusedTo write FColorFocusedTo;
+ end;
+{
+ TButtonExPictures = class(TPersistent)
+ private
+ FButton: TButtonEx;
+ FAlignment: TLeftRight;
+ FTransparent: boolean;
+ FPictureNormal: TPicture;
+ FPictureHot: TPicture;
+ FPictureDown: TPicture;
+ FPictureDisabled: TPicture;
+ FPictureFocused: TPicture;
+ procedure SetPictureNormal(const Value: TPicture);
+ procedure SetPictureDisabled(const Value: TPicture);
+ procedure SetPictureDown(const Value: TPicture);
+ procedure SetPictureFocused(const Value: TPicture);
+ procedure SetPictureHot(const Value: TPicture);
+ procedure SetAlignment(const Value: TLeftRight);
+ procedure SetTransparent(const Value: boolean);
+ public
+ constructor Create(AButton: TButtonEx);
+ destructor Destroy; override;
+ published
+ property PictureNormal: TPicture read FPictureNormal write SetPictureNormal;
+ property PictureHot: TPicture read FPictureHot write SetPictureHot;
+ property PictureDown: TPicture read FPictureDown write SetPictureDown;
+ property PictureDisabled: TPicture read FPictureDisabled write SetPictureDisabled;
+ property PictureFocused: TPicture read FPictureFocused write SetPictureFocused;
+ property Alignment: TLeftRight read FAlignment write SetAlignment default taLeftJustify;
+ property Transparent: boolean read FTransparent write SetTransparent default False;
+ end;
+}
+ TButtonEx = class(TCustomButton)
+ private
+ FAlignment: TAlignment;
+ FBorder: TButtonExBorder;
+ FCanvas: TCanvas;
+ FColors: TButtonExColors;
+ FDefaultDrawing: Boolean;
+ FFontDisabled: TFont;
+ FFontDown: TFont;
+ FFontFocused: TFont;
+ FFontHot: TFont;
+ FGradient: Boolean;
+ FMargin: integer;
+ FShowFocusRect: Boolean;
+ FState: TButtonExState;
+ FWordwrap: Boolean;
+ procedure SetAlignment(const Value: TAlignment);
+ procedure SetDefaultDrawing(const Value: Boolean);
+ procedure SetGradient(const Value: Boolean);
+ procedure SetShowFocusRect(const Value: Boolean);
+// procedure SetSpacing(const Value: integer);
+ procedure SetMargin(const Value: integer);
+ procedure SetWordWrap(const Value: Boolean);
+ protected
+ procedure CalculatePreferredSize(var PreferredWidth, PreferredHeight: Integer;
+ WithThemeSpace: Boolean); override;
+ class function GetControlClassDefaultSize: TSize; override;
+ function GetDrawTextFlags: Cardinal;
+ procedure MouseEnter; override;
+ procedure MouseLeave; override;
+ procedure PaintCustomButton;
+ procedure PaintThemedButton;
+ procedure WMKillFocus(var Message: TLMKillFocus); message LM_KILLFOCUS;
+ procedure WMPaint(var Msg: TLMPaint); message LM_PAINT;
+ procedure WMSetFocus(var Message: TLMSetFocus); message LM_SETFOCUS;
+ procedure WndProc(var Message: TLMessage); override;
+ public
+ constructor Create(AOwner: TComponent); override;
+ destructor Destroy; override;
+ //procedure Click; override;
+ published
+ property Align;
+ property Anchors;
+ property AutoSize;
+ property BorderSpacing;
+ property Cancel;
+ property Caption;
+ //property Color; removed for new property Colors
+ property Constraints;
+ property Cursor;
+ property Default;
+// property DoubleBuffered; // PaintButton is not called when this is set.
+ property DragCursor;
+ property DragKind;
+ property DragMode;
+ property Enabled;
+ property Font;
+ property Height;
+ property HelpContext;
+ property HelpKeyword;
+ property HelpType;
+ property Hint;
+ property Left;
+ property ModalResult;
+ property ParentBiDiMode;
+// property ParentDoubleBuffered;
+ property ParentFont;
+ property ParentShowHint;
+ property PopupMenu;
+ property ShowHint;
+ property TabOrder;
+ property TabStop default True;
+ property Tag;
+ property Top;
+ property Visible;
+ property Width;
+
+ property OnChangeBounds;
+ property OnClick;
+ property OnContextPopup;
+ property OnDragDrop;
+ property OnDragOver;
+ property OnEndDrag;
+ property OnEnter;
+ property OnExit;
+ property OnKeyDown;
+ property OnKeyPress;
+ property OnKeyUp;
+ property OnMouseDown;
+ property OnMouseEnter;
+ property OnMouseLeave;
+ property OnMouseMove;
+ property OnMouseUp;
+ property OnResize;
+ property OnStartDrag;
+ property OnUTF8KeyPress;
+
+ property Alignment: TAlignment read FAlignment write SetAlignment default taCenter;
+ property Border: TButtonExBorder read FBorder write FBorder;
+ property Colors: TButtonExColors read FColors write FColors;
+ property DefaultDrawing: Boolean read FDefaultDrawing write SetDefaultDrawing default true;
+ property FontDisabled: TFont read FFontDisabled write FFontDisabled;
+ property FontDown: TFont read FFontDown write FFontDown;
+ property FontFocused: TFont read FFontFocused write FFontFocused;
+ property FontHot: TFont read FFontHot write FFontHot;
+ property Gradient: Boolean read FGradient write SetGradient default true;
+ property Margin: integer read FMargin write SetMargin;
+ property ShowFocusRect: Boolean read FShowFocusRect write SetShowFocusRect default true;
+ property Wordwrap: Boolean read FWordWrap write SetWordWrap default false;
+ end;
+
+
+implementation
+
+uses
+ LCLType, LCLIntf, Themes;
+
+
+{ TButtonExBorder }
+
+constructor TButtonExBorder.Create(AButton: TButtonEx);
+begin
+ inherited Create;
+ FButton := AButton;
+end;
+
+procedure TButtonExBorder.SetColorNormal(const Value: TColor);
+begin
+ if FColorNormal = Value then exit;
+ FColorNormal := Value;
+ FButton.Invalidate;
+end;
+
+procedure TButtonExBorder.SetWidthNormal(const Value: TButtonExBorderWidth);
+begin
+ if FWidthNormal = Value then exit;
+ FWidthNormal := Value;
+ FButton.Invalidate;
+end;
+
+
+{ TButtonExColors }
+
+constructor TButtonExColors.Create(AButton: TButtonEx);
+begin
+ inherited Create;
+ FButton := AButton;
+end;
+
+procedure TButtonExColors.SetColorNormalFrom(const Value: TColor);
+begin
+ if FColorNormalFrom = Value then
+ exit;
+ FColorNormalFrom := Value;
+ FButton.Invalidate;
+end;
+
+procedure TButtonExColors.SetColorNormalTo(const Value: TColor);
+begin
+ if FColorNormalTo = Value then
+ exit;
+ FColorNormalTo := Value;
+ FButton.Invalidate;
+end;
+
+
+(*
+{ TButtonExPictures }
+
+constructor TButtonExPictures.Create(AButton: TButtonEx);
+begin
+ inherited Create;
+ FButton := AButton;
+ FAlignment := taLeftJustify;
+ FTransparent := False;
+ FPictureNormal := TPicture.Create;
+ FPictureHot := TPicture.Create;
+ FPictureDown := TPicture.Create;
+ FPictureDisabled := TPicture.Create;
+ FPictureFocused := TPicture.Create;
+end;
+
+destructor TButtonExPictures.Destroy;
+begin
+ FPictureNormal.Free;
+ FPictureHot.Free;
+ FPictureDown.Free;
+ FPictureDisabled.Free;
+ FPictureFocused.Free;
+ inherited;
+end;
+
+procedure TButtonExPictures.SetAlignment(const Value: TLeftRight);
+begin
+ if FAlignment = Value then
+ exit;
+ FAlignment := Value;
+ FButton.Invalidate;
+end;
+
+procedure TButtonExPictures.SetPictureDisabled(const Value: TPicture);
+begin
+ FPictureDisabled.Assign(Value);
+end;
+
+procedure TButtonExPictures.SetPictureDown(const Value: TPicture);
+begin
+ FPictureDown.Assign(Value);
+end;
+
+procedure TButtonExPictures.SetPictureFocused(const Value: TPicture);
+begin
+ FPictureFocused.Assign(Value);
+end;
+
+procedure TButtonExPictures.SetPictureHot(const Value: TPicture);
+begin
+ FPictureHot.Assign(Value);
+end;
+
+procedure TButtonExPictures.SetPictureNormal(const Value: TPicture);
+begin
+ FPictureNormal.Assign(Value);
+ FButton.Invalidate;
+end;
+
+procedure TButtonExPictures.SetTransparent(const Value: boolean);
+begin
+ FTransparent := Value;
+ FButton.Invalidate;
+end;
+*)
+
+
+{ TButtonEx }
+
+constructor TButtonEx.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+
+ FCanvas := TControlCanvas.Create;
+ TControlCanvas(FCanvas).Control := Self;
+
+ FDefaultDrawing := true;
+ FGradient := true;
+ FShowFocusRect := true;
+
+ FBorder := TButtonExBorder.Create(Self);
+ FColors := TButtonExColors.Create(Self);
+ //FPictures := TButtonExPictures.Create(Self);
+
+ // Button
+ FColors.ColorNormalFrom := $00FCFCFC;
+ FColors.ColorNormalTo := $00CFCFCF;
+ FColors.ColorHotFrom := $00FCFCFC;
+ FColors.ColorHotTo := $00F5D9A7;
+ FColors.ColorDownFrom := $00FCFCFC;
+ FColors.ColorDownTo := $00DBB368;
+ FColors.ColorDisabledFrom := $00F4F4F4;
+ FColors.ColorDisabledTo := $00F4F4F4;
+ FColors.ColorFocusedFrom := $00FCFCFC;
+ FColors.ColorFocusedTo := $00CFCFCF;
+
+ // Fonts
+ FFontDisabled := TFont.Create;
+ FFontDisabled.Assign(Font);
+ FFontDisabled.Color := clGrayText;
+ FFontDisabled.OnChange := @FontChanged;
+ FFontDown := TFont.Create;
+ FFontDown.Assign(Font);
+ FFontDown.OnChange := @FontChanged;
+ FFontFocused := TFont.Create;
+ FFontFocused.Assign(Font);
+ FFontFocused.OnChange := @FontChanged;
+ FFontHot := TFont.Create;
+ FFontHot.Assign(Font);
+ FFontHot.OnChange := @FontChanged;
+
+ // Border
+ FBorder.ColorNormal := $00707070;
+ FBorder.ColorHot := $00B17F3C;
+ FBorder.ColorDown := $008B622C;
+ FBorder.ColorDisabled := $00B5B2AD;
+ FBorder.ColorFocused := $00B17F3C;
+ FBorder.WidthNormal := 1;
+ FBorder.WidthHot := 1;
+ FBorder.WidthDown := 1;
+ FBorder.WidthDisabled := 1;
+ FBorder.WidthFocused := 1;
+
+ // Other
+// FSpacing := 5;
+ FMargin := 5;
+ FAlignment := taCenter;
+ FState := bxsNormal;
+// TabStop := True;
+// FModalResult := 0;
+// FCancel := False;
+// FDefault := False;
+// Width := 85;
+// Height := 30;
+end;
+
+destructor TButtonEx.Destroy;
+begin
+ FFontHot.Free;
+ FFontDown.Free;
+ FFontDisabled.Free;
+ FFontFocused.Free;
+ //FPictures.Free;
+ FColors.Free;
+ FBorder.Free;
+ FCanvas.Free;
+ inherited;
+end;
+
+procedure TButtonEx.CalculatePreferredSize(var PreferredWidth,
+ PreferredHeight: Integer; WithThemeSpace: Boolean);
+var
+ flags: Cardinal;
+ txtSize: TSize;
+ R: TRect;
+ details: TThemedElementDetails;
+begin
+ FCanvas.Font.Assign(Font);
+
+ R := ClientRect;
+ InflateRect(R, -FMargin, 0);
+ R.Bottom := MaxInt; // Max height possible
+
+ flags := GetDrawTextFlags + DT_CALCRECT;
+
+ // rectangle available for text
+ details := ThemeServices.GetElementDetails(tbPushButtonNormal);
+ if FWordWrap then
+ begin
+ with ThemeServices.GetTextExtent(FCanvas.Handle, details, Caption, flags, @R) do begin
+ txtSize.CX := Right;
+ txtSize.CY := Bottom;
+ end;
+ end else
+ with ThemeServices.GetTextExtent(FCanvas.Handle, details, Caption, flags, nil) do begin
+ txtSize.CX := Right;
+ txtSize.CY := Bottom;
+ end;
+
+ PreferredHeight := txtSize.CY + 2 * FMargin;
+ PreferredWidth := txtSize.CX + 2 * FMargin;
+
+ if not FWordWrap then
+ PreferredHeight := 0;
+ {
+ if FWordWrap then //and AutoSize then
+ begin
+ PreferredWidth := 0 ;
+ PreferredHeight := txtSize.CY + 2*FMargin;
+ end else
+ begin
+ PreferredWidth := txtSize.CX + 2 * FMargin;
+ PreferredHeight := 0;
+ end;
+ }
+end;
+
+ (*
+procedure TButtonEx.Click;
+var
+ Form: TCustomForm;
+begin
+ Form := GetParentForm(Self);
+ if Form <> nil then
+ Form.ModalResult := FModalResult;
+ inherited;
+end;
+
+procedure TButtonEx.FontChanged(Sender: TObject);
+begin
+ Invalidate;
+end;
+ *)
+
+class function TButtonEx.GetControlClassDefaultSize: TSize;
+begin
+ Result.CX := 75;
+ Result.CY := 25;
+end;
+
+function TButtonEx.GetDrawTextFlags: Cardinal;
+begin
+ Result := DT_VCENTER;
+ case FAlignment of
+ taLeftJustify:
+ if IsRightToLeft then Result := Result or DT_RIGHT else Result := Result or DT_LEFT;
+ taRightJustify:
+ if IsRightToLeft then Result := Result or DT_LEFT else Result := Result or DT_RIGHT;
+ taCenter:
+ Result := Result or DT_CENTER;
+ end;
+ if IsRightToLeft then
+ result := Result or DT_RTLREADING;
+ if FWordWrap then
+ Result := Result or DT_WORDBREAK and not DT_SINGLELINE
+ else
+ Result := Result or DT_SINGLELINE and not DT_WORDBREAK;;
+end;
+
+procedure TButtonEx.MouseEnter;
+begin
+ if FState <> bxsDisabled then
+ begin
+ FState := bxsHot;
+ Invalidate;
+ end;
+ inherited;
+end;
+
+procedure TButtonEx.MouseLeave;
+begin
+ if (FState <> bxsDisabled) then
+ begin
+ if Focused then
+ FState := bxsFocused
+ else
+ FState := bxsNormal;
+ Invalidate;
+ end;
+ inherited;
+end;
+
+procedure TButtonEx.PaintThemedButton;
+var
+ btn: TThemedButton;
+ details: TThemedElementDetails;
+ lRect: TRect;
+ flags: Cardinal;
+ txtSize: TSize;
+ txtPt: TPoint;
+begin
+ if (csDestroying in ComponentState) or not HandleAllocated then
+ exit;
+
+ lRect.Left := 0;
+ lRect.Right := Width;
+ lRect.Top := 0;
+ lRect.Bottom := Height;
+
+ if FState = bxsDisabled then
+ btn := tbPushButtonDisabled
+ else if FState = bxsDown then
+ btn := tbPushButtonPressed
+ else if FState = bxsHot then
+ btn := tbPushButtonHot
+ else
+ if Focused or Default then
+ btn := tbPushButtonDefaulted
+ else
+ btn := tbPushButtonNormal;
+
+ // Background
+ details := ThemeServices.GetElementDetails(btn);
+ InflateRect(lRect, 1, 1);
+ ThemeServices.DrawElement(FCanvas.Handle, details, lRect);
+ InflateRect(lRect, -1, -1);
+
+ // Text
+ FCanvas.Font.Assign(Font);
+ flags := GetDrawTextFlags;
+
+ with ThemeServices.GetTextExtent(FCanvas.Handle, details, Caption, flags, @lRect) do begin
+ txtSize.CX := Right;
+ txtSize.CY := Bottom;
+ end;
+
+ case FAlignment of
+ taLeftJustify:
+ if IsRightToLeft then
+ txtPt.X := Width - txtSize.CX - FMargin
+ else
+ txtPt.X := FMargin;
+ taRightJustify:
+ if IsRightToLeft then
+ txtPt.X := FMargin
+ else
+ txtPt.X := Width - txtSize.CX - FMargin;
+ taCenter:
+ txtPt.X := (Width - txtSize.CX) div 2;
+ end;
+ txtPt.Y := (Height + 1 - txtSize.CY) div 2;
+ lRect := Rect(txtPt.X, txtPt.Y, txtPt.X + txtSize.CX, txtPt.Y + txtSize.CY);
+ ThemeServices.DrawText(FCanvas, details, Caption, lRect, flags, 0);
+end;
+
+procedure TButtonEx.PaintCustomButton;
+var
+ lCanvas: TCanvas;
+ lBitmap: TBitmap;
+ lRect, R: TRect;
+ lBorderColor: TColor;
+ lBorderWidth: integer;
+ lColorFrom: TColor;
+ lColorTo: TColor;
+ lTextFont: TFont;
+ flags: Cardinal;
+ i: integer;
+ txtSize: TSize;
+ txtPt: TPoint;
+begin
+ if (csDestroying in ComponentState) or not HandleAllocated then
+ exit;
+
+ // Bitmap
+ lBitmap := TBitmap.Create;
+ lBitmap.Width := Width;
+ lBitmap.Height := Height;
+ lCanvas := lBitmap.Canvas;
+
+ // State
+ lBorderColor := Border.ColorNormal;
+ lColorFrom := Colors.ColorNormalFrom;
+ lColorTo := Colors.ColorNormalTo;
+ lTextFont := Font;
+ lBorderWidth := Border.WidthNormal;
+ //lPicture := FPictures.PictureNormal;
+
+ if not (csDesigning in ComponentState) then
+ begin
+ case FState of
+ bxsFocused:
+ begin
+ lBorderColor := FBorder.ColorFocused;
+ lColorFrom := FColors.ColorFocusedFrom;
+ lColorTo := FColors.ColorFocusedTo;
+ lTextFont := FFontFocused;
+ lBorderWidth := FBorder.WidthFocused;
+ {
+ if FPictures.PictureFocused.Graphic <> nil then
+ lPicture := FPictures.PictureFocused;
+ }
+ end;
+ bxsHot:
+ begin
+ lBorderColor := FBorder.ColorHot;
+ lColorFrom := FColors.ColorHotFrom;
+ lColorTo := FColors.ColorHotTo;
+ lTextFont := FFontHot;
+ lBorderWidth := FBorder.WidthHot;
+ {
+ if FPictures.PictureHot.Graphic <> nil then
+ lPicture := FPictures.PictureHot;
+ }
+ end;
+ bxsDown:
+ begin
+ lBorderColor := FBorder.ColorDown;
+ lColorFrom := FColors.ColorDownFrom;
+ lColorTo := FColors.ColorDownTo;
+ lTextFont := FFontDown;
+ lBorderWidth := FBorder.WidthDown;
+ {
+ if FPictures.PictureDown.Graphic <> nil then
+ lPicture := FPictures.PictureDown;
+ }
+ end;
+ bxsDisabled:
+ begin
+ lBorderColor := FBorder.ColorDisabled;
+ lColorFrom := FColors.ColorDisabledFrom;
+ lColorTo := FColors.ColorDisabledTo;
+ lTextFont := FFontDisabled;
+ lBorderWidth := FBorder.WidthDisabled;
+ {
+ if FPictures.PictureDisabled.Graphic <> nil then
+ lPicture := FPictures.PictureDisabled;
+ }
+ end;
+ end;
+ end;
+
+ // Background
+ lRect.Left := 0;
+ lRect.Right := Width;
+ lRect.Top := 0; //lBorderWidth;
+ lRect.Bottom := Height; // - lBorderWidth;
+
+ if FGradient then
+ lCanvas.GradientFill(lRect, lColorFrom, lColorTo, gdVertical)
+ else
+ begin
+ lCanvas.Brush.Style := bsSolid;
+ lCanvas.Brush.Color := lColorFrom;
+ lCanvas.FillRect(lRect);
+ end;
+
+ {
+ // Image
+ lPicLeft := 0;
+ if lPicture.Graphic <> nil then
+ begin
+ lPicture.Graphic.Transparent := FPictures.Transparent;
+ case FPictures.Alignment of
+ taLeftJustify : lPicLeft := Border.WidthNormal + FMargin;
+ taRightJustify: lPicLeft := Width - Border.WidthNormal - FMargin - lPicture.Graphic.Width;
+ end;
+ lPicTop := (Height - lPicture.Height) div 2;
+ lCanvas.Draw(lPicLeft, lPicTop, lPicture.Graphic);
+ end;
+ }
+ // Border
+ lCanvas.Pen.Width := 1;
+ lCanvas.Pen.Color := lBorderColor;
+ for i := 1 to lBorderWidth do
+ begin
+ lCanvas.MoveTo(i - 1, i - 1);
+ lCanvas.LineTo(Width - i, i - 1);
+ lCanvas.LineTo(Width - i, Height - i);
+ lCanvas.LineTo(i - 1, Height - i);
+ lCanvas.LineTo(i - 1, i - 1);
+ end;
+
+ (*
+ // Corner
+ lCanvas.Pixels[0, 0] := Color;
+ lCanvas.Pixels[lBorderWidth, lBorderWidth] := lBorderColor;
+ lCanvas.Pixels[Width - 1, 0] := Color;
+ lCanvas.Pixels[Width - 1 - lBorderWidth, lBorderWidth] := lBorderColor;
+ lCanvas.Pixels[0, Height - 1] := Color;
+ lCanvas.Pixels[lBorderWidth, Height - 1 - lBorderWidth] := lBorderColor;
+ lCanvas.Pixels[Width - 1, Height - 1] := Color;
+ lCanvas.Pixels[Width - 1 - lBorderWidth, Height - 1 - lBorderWidth] := lBorderColor;
+ *)
+
+ // Text
+ lCanvas.Pen.Width := 1;
+ lCanvas.Brush.Style := bsClear;
+ lCanvas.Font.Assign(lTextFont);
+
+ flags := GetDrawTextFlags;
+ R := lRect;
+ DrawText(FCanvas.Handle, PChar(Caption), Length(Caption), R, flags + DT_CALCRECT);
+ txtSize.CX := R.Right - R.Left;
+ txtSize.CY := R.Bottom - R.Top;
+
+ case FAlignment of
+ taLeftJustify:
+ if IsRightToLeft then
+ txtPt.X := Width - txtSize.CX - FMargin
+ else
+ txtPt.X := FMargin;
+ taRightJustify:
+ if IsRightToLeft then
+ txtPt.X := FMargin
+ else
+ txtPt.X := Width - txtSize.CX - FMargin;
+ taCenter:
+ txtPt.X := (Width - txtSize.CX) div 2;
+ end;
+ txtPt.Y := (Height - txtSize.CY + 1) div 2;
+ R := Rect(txtPt.X, txtPt.Y, txtPt.X + txtSize.CX, txtPt.Y + txtSize.CY);
+ (*
+ case FAlignment of
+ taLeftJustify:
+ begin
+ lRect.Left := lRect.Left + FBorder.WidthNormal + FMargin;
+ lAlignment := DT_LEFT;
+ end;
+ taRightJustify:
+ begin
+ lRect.Right := lRect.Right - FBorder.WidthNormal - FMargin;
+ lAlignment := DT_RIGHT;
+ end;
+ else
+ lAlignment := DT_CENTER;
+ end;
+ *)
+ {
+ if (lPicture.Graphic <> nil) and (Alignment <> taCenter) then
+ begin
+ case FPictures.Alignment of
+ taLeftJustify: lRect.Left := lPicLeft + lPicture.Graphic.Width + FSpacing;
+ taRightJustify: lRect.Right := lPicLeft - FSpacing;
+ end;
+ end;
+ }
+ DrawText(lCanvas.Handle, PChar(Caption), -1, R, flags); //lAlignment or DT_NOPREFIX or DT_VCENTER or DT_SINGLELINE);
+
+ // Draw focus rectangle
+ if FShowFocusRect and Focused then
+ begin
+ InflateRect(lRect, -3, -2);
+ DrawFocusRect(lCanvas.Handle, lRect);
+ end;
+
+ // Draw the button
+ FCanvas.Draw(0, 0, lBitmap);
+
+ lBitmap.Free;
+end;
+
+procedure TButtonEx.SetAlignment(const Value: TAlignment);
+begin
+ if FAlignment = Value then
+ exit;
+ FAlignment := Value;
+ Invalidate;
+end;
+
+procedure TButtonEx.SetDefaultDrawing(const Value: Boolean);
+begin
+ if FDefaultDrawing = Value then
+ exit;
+ FDefaultDrawing := Value;
+ Invalidate;
+end;
+
+procedure TButtonEx.SetGradient(const Value: Boolean);
+begin
+ if FGradient = Value then
+ exit;
+ FGradient := Value;
+ Invalidate;
+end;
+
+procedure TButtonEx.SetShowFocusRect(const Value: Boolean);
+begin
+ if FShowFocusRect = Value then
+ exit;
+ FShowFocusRect := Value;
+ if Focused then Invalidate;
+end;
+
+procedure TButtonEx.SetMargin(const Value: integer);
+begin
+ if FMargin = Value then
+ exit;
+ FMargin := Value;
+ Invalidate;
+end;
+
+{
+procedure TButtonEx.SetSpacing(const Value: integer);
+begin
+ if FSpacing = Value then
+ exit;
+ FSpacing := Value;
+ Invalidate;
+end;
+}
+
+procedure TButtonEx.SetWordWrap(const Value: Boolean);
+begin
+ if FWordWrap = Value then
+ exit;
+ FWordWrap := Value;
+ //if AutoSize then AdjustSize;
+ Invalidate;
+end;
+
+procedure TButtonEx.WMKillFocus(var Message: TLMKillFocus);
+begin
+ inherited WMKillFocus(Message);
+ if (FState = bxsFocused) then
+ begin
+ FState := bxsNormal;
+ Invalidate;
+ end;
+end;
+
+procedure TButtonEx.WMSetFocus(var Message: TLMSetFocus);
+begin
+ inherited WMSetFocus(Message);
+ if (FState = bxsNormal) then
+ begin
+ FState := bxsFocused;
+ Invalidate;
+ end;
+end;
+
+procedure TButtonEx.WMPaint(var Msg: TLMPaint);
+begin
+ inherited;
+ if FDefaultDrawing then
+ PaintThemedButton
+ else
+ PaintCustomButton;
+end;
+
+procedure TButtonEx.WndProc(var Message: TLMessage);
+begin
+ {
+ if Message.Msg = LM_PAINT then
+ PaintButton;
+
+ if Message.Msg = CM_TEXTCHANGED then
+ PaintButton;
+
+ if Message.Msg = CM_COLORCHANGED then
+ PaintButton;
+
+ if Message.Msg = CM_BORDERCHANGED then
+ PaintButton;
+
+ if Message.Msg = LM_ERASEBKGND then
+ Exit;
+}
+ if not (csDesigning in ComponentState) then
+ begin
+ case Message.Msg of
+
+ LM_KEYDOWN:
+ begin
+ if (Message.WParam = VK_RETURN) or (Message.WParam = VK_SPACE) then
+ if FState <> bxsDisabled then
+ FState := bxsDown;
+ Invalidate;
+ end;
+
+ LM_KEYUP:
+ begin
+ if (Message.WParam = VK_RETURN) or (Message.WParam = VK_SPACE) then
+ if FState <> bxsDisabled then
+ FState := bxsFocused;
+ Invalidate;
+ end;
+
+ {
+ LM_CHAR:
+ begin
+ if (Message.WParam = VK_RETURN) or (Message.WParam = VK_SPACE) and (FState <> bxsDisabled) then
+ begin
+ Click;
+ end;
+ end;
+
+ CM_MOUSEENTER:
+ begin
+ FState := bxsHot;
+ PaintButton;
+ end;
+ CM_MOUSELEAVE:
+ begin
+ if (FState <> bxsDisabled) then
+ begin
+ if Focused then
+ FState := bxsFocused
+ else
+ FState := bxsNormal;
+ PaintButton;
+ end;
+ end;
+ }
+ CM_DIALOGKEY:
+ begin
+ if (Message.WParam = VK_RETURN) and Default and (not Focused) and (FState <> bxsDisabled) then
+ Click;
+ if (Message.WParam = VK_ESCAPE) and Cancel and (FState <> bxsDisabled) then
+ Click;
+ end;
+
+ {
+ CM_FOCUSCHANGED:
+ begin
+ if Focused and (FState = bxsNormal) then
+ FState := bxsFocused;
+ if (not Focused) and (FState = bxsFocused) then
+ FState := bxsNormal;
+ PaintButton;
+ end;
+ }
+ CM_ENABLEDCHANGED:
+ begin
+ if not Enabled then
+ FState := bxsDisabled
+ else
+ FState := bxsNormal;
+ Invalidate;
+// PaintButton;
+ end;
+ LM_LBUTTONDOWN:
+ begin
+ FState := bxsDown;
+ Invalidate;
+// PaintButton;
+ end;
+ LM_LBUTTONUP:
+ begin
+ if (FState <> bxsNormal) and (FState <> bxsFocused) and (FState <> bxsDisabled) then
+ begin
+ FState := bxsHot;
+ Invalidate;
+ //PaintButton;
+ end;
+ end;
+ {
+ LM_LBUTTONDBLCLK:
+ begin
+ FState := bxsDown;
+ PaintButton;
+ Click;
+ end;
+ }
+ end;
+ end;
+
+ inherited;
+end;
+
+end.
+
diff --git a/components/exctrls/source/exctrlsreg.pas b/components/exctrls/source/exctrlsreg.pas
index 61d5033d6..521990af1 100644
--- a/components/exctrls/source/exctrlsreg.pas
+++ b/components/exctrls/source/exctrlsreg.pas
@@ -12,14 +12,14 @@ procedure Register;
implementation
uses
- ExCheckCtrls, ExEditCtrls;
+ ExButtons, ExCheckCtrls, ExEditCtrls;
{$R exctrlsreg.res}
procedure Register;
begin
RegisterComponents('ExCtrls', [
- TCheckboxEx, TRadioButtonEx, TCheckGroupEx, TRadioGroupEx
+ TButtonEx, TCheckboxEx, TRadioButtonEx, TCheckGroupEx, TRadioGroupEx
]);
RegisterComponents('LazControls', [
TCurrSpinEditEx
diff --git a/components/exctrls/source/exctrlsreg.res b/components/exctrls/source/exctrlsreg.res
index a2679ce11..b1b574a50 100644
Binary files a/components/exctrls/source/exctrlsreg.res and b/components/exctrls/source/exctrlsreg.res differ