611 lines
16 KiB
ObjectPascal
611 lines
16 KiB
ObjectPascal
// SPDX-License-Identifier: LGPL-3.0-linking-exception
|
|
{******************************* CONTRIBUTOR(S) ******************************
|
|
- Edivando S. Santos Brasil | mailedivando@gmail.com
|
|
(Compatibility with delphi VCL 11/2018)
|
|
|
|
***************************** END CONTRIBUTOR(S) *****************************}
|
|
unit ColorSpeedButton;
|
|
|
|
{$I bgracontrols.inc}
|
|
|
|
{$ifdef windows}
|
|
{$define overridepaint}
|
|
{$endif}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, Types, {$IFDEF FPC}LCLType, LCLProc, LResources,{$ENDIF}
|
|
{$IFNDEF FPC}BGRAGraphics, GraphType, FPImage, {$ENDIF}
|
|
Forms, Controls, Graphics, Dialogs, Buttons, BGRASpeedButton, Themes
|
|
{$ifdef overridepaint}, Math{$ENDIF};
|
|
|
|
type
|
|
|
|
{ TColorState }
|
|
|
|
TColorState = class(TPersistent)
|
|
private
|
|
FOwner: TControl;
|
|
FBorderColor: TColor;
|
|
FBorderWidth: integer;
|
|
FColor: TColor;
|
|
procedure SetFBorderColor(AValue: TColor);
|
|
procedure SetFBorderWidth(AValue: integer);
|
|
procedure SetFColor(AValue: TColor);
|
|
public
|
|
constructor Create(AOwner: TControl);
|
|
published
|
|
property Color: TColor read FColor write SetFColor;
|
|
property BorderColor: TColor read FBorderColor write SetFBorderColor;
|
|
property BorderWidth: integer read FBorderWidth write SetFBorderWidth;
|
|
end;
|
|
|
|
{ TColorSpeedButton }
|
|
|
|
TColorSpeedButton = class(TBGRASpeedButton)
|
|
private
|
|
{$ifdef overridepaint}
|
|
FLastDrawDetails: TThemedElementDetails;
|
|
{$endif}
|
|
FPopupMode: boolean;
|
|
FPressed: boolean;
|
|
FStateActive: TColorState;
|
|
FStateDisabled: TColorState;
|
|
FStateHover: TColorState;
|
|
FStateNormal: TColorState;
|
|
FTextAutoSize: boolean;
|
|
FToggle: boolean;
|
|
procedure SetFPopupMode(AValue: boolean);
|
|
procedure SetFPressed(AValue: boolean);
|
|
procedure SetFStateActive(AValue: TColorState);
|
|
procedure SetFStateDisabled(AValue: TColorState);
|
|
procedure SetFStateHover(AValue: TColorState);
|
|
procedure SetFStateNormal(AValue: TColorState);
|
|
procedure SetFTextAutoSize(AValue: boolean);
|
|
procedure SetFToggle(AValue: boolean);
|
|
protected
|
|
{$ifdef overridepaint}
|
|
procedure DrawText({%H-}ACanvas: TPersistent; {%H-}Details: TThemedElementDetails;
|
|
const S: string; R: TRect; Flags, {%H-}Flags2: cardinal);
|
|
procedure MeasureDraw(Draw: boolean; PaintRect: TRect;
|
|
out PreferredWidth, PreferredHeight: integer);
|
|
procedure Paint; override;
|
|
procedure CalculatePreferredSize(var PreferredWidth, PreferredHeight: integer;
|
|
{%H-}WithThemeSpace: boolean); override;
|
|
{$endif}
|
|
procedure PaintBackground(var PaintRect: TRect); {$IFDEF FPC}override;{$ENDIF}
|
|
public
|
|
constructor Create(TheOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
procedure Click; override;
|
|
published
|
|
property TextAutoSize: boolean read FTextAutoSize write SetFTextAutoSize;
|
|
property Toggle: boolean read FToggle write SetFToggle;
|
|
property Pressed: boolean read FPressed write SetFPressed;
|
|
property PopupMode: boolean read FPopupMode write SetFPopupMode;
|
|
property StateNormal: TColorState read FStateNormal write SetFStateNormal;
|
|
property StateHover: TColorState read FStateHover write SetFStateHover;
|
|
property StateActive: TColorState read FStateActive write SetFStateActive;
|
|
property StateDisabled: TColorState read FStateDisabled write SetFStateDisabled;
|
|
end;
|
|
|
|
{$IFDEF FPC}procedure Register;{$ENDIF}
|
|
|
|
implementation
|
|
|
|
{$IFDEF FPC}
|
|
procedure Register;
|
|
begin
|
|
RegisterComponents('BGRA Button Controls', [TColorSpeedButton]);
|
|
end;
|
|
{$ENDIF}
|
|
|
|
{ TColorSpeedButton }
|
|
|
|
procedure TColorSpeedButton.SetFStateActive(AValue: TColorState);
|
|
begin
|
|
if FStateActive = AValue then
|
|
Exit;
|
|
FStateActive := AValue;
|
|
Invalidate;
|
|
end;
|
|
|
|
procedure TColorSpeedButton.SetFPopupMode(AValue: boolean);
|
|
begin
|
|
if FPopupMode = AValue then
|
|
Exit;
|
|
FPopupMode := AValue;
|
|
end;
|
|
|
|
procedure TColorSpeedButton.SetFPressed(AValue: boolean);
|
|
begin
|
|
if FPressed = AValue then
|
|
Exit;
|
|
FPressed := AValue;
|
|
Invalidate;
|
|
end;
|
|
|
|
procedure TColorSpeedButton.SetFStateDisabled(AValue: TColorState);
|
|
begin
|
|
if FStateDisabled = AValue then
|
|
Exit;
|
|
FStateDisabled := AValue;
|
|
Invalidate;
|
|
end;
|
|
|
|
procedure TColorSpeedButton.SetFStateHover(AValue: TColorState);
|
|
begin
|
|
if FStateHover = AValue then
|
|
Exit;
|
|
FStateHover := AValue;
|
|
Invalidate;
|
|
end;
|
|
|
|
procedure TColorSpeedButton.SetFStateNormal(AValue: TColorState);
|
|
begin
|
|
if FStateNormal = AValue then
|
|
Exit;
|
|
FStateNormal := AValue;
|
|
Invalidate;
|
|
end;
|
|
|
|
procedure TColorSpeedButton.SetFTextAutoSize(AValue: boolean);
|
|
begin
|
|
if FTextAutoSize = AValue then
|
|
Exit;
|
|
FTextAutoSize := AValue;
|
|
end;
|
|
|
|
procedure TColorSpeedButton.SetFToggle(AValue: boolean);
|
|
begin
|
|
if FToggle = AValue then
|
|
Exit;
|
|
FToggle := AValue;
|
|
Invalidate;
|
|
end;
|
|
|
|
{$ifdef overridepaint}
|
|
procedure TColorSpeedButton.DrawText(ACanvas: TPersistent;
|
|
Details: TThemedElementDetails; const S: string; R: TRect; Flags, Flags2: cardinal);
|
|
var
|
|
TXTStyle: TTextStyle;
|
|
begin
|
|
TXTStyle := Canvas.TextStyle;
|
|
TXTStyle.Opaque := False;
|
|
TXTStyle.Clipping := (Flags and DT_NOCLIP) = 0;
|
|
TXTStyle.ShowPrefix := (Flags and DT_NOPREFIX) = 0;
|
|
TXTStyle.SingleLine := (Flags and DT_SINGLELINE) <> 0;
|
|
|
|
if (Flags and DT_CENTER) <> 0 then
|
|
TXTStyle.Alignment := taCenter
|
|
else
|
|
if (Flags and DT_RIGHT) <> 0 then
|
|
TXTStyle.Alignment := taRightJustify
|
|
else
|
|
TXTStyle.Alignment := taLeftJustify;
|
|
|
|
if (Flags and DT_VCENTER) <> 0 then
|
|
TXTStyle.Layout := tlCenter
|
|
else
|
|
if (Flags and DT_BOTTOM) <> 0 then
|
|
TXTStyle.Layout := tlBottom
|
|
else
|
|
TXTStyle.Layout := tlTop;
|
|
TXTStyle.RightToLeft := (Flags and DT_RTLREADING) <> 0;
|
|
// set color here, otherwise SystemFont is wrong if the button was disabled before
|
|
TXTStyle.SystemFont := Canvas.Font.IsDefault;//Match System Default Style
|
|
|
|
TXTStyle.Wordbreak := (Flags and DT_WORDBREAK) <> 0;
|
|
if not TXTStyle.Wordbreak then
|
|
TXTStyle.EndEllipsis := (Flags and DT_END_ELLIPSIS) <> 0
|
|
else
|
|
TXTStyle.EndEllipsis := False;
|
|
Canvas.TextRect(R, R.Left, R.Top, S, TXTStyle);
|
|
end;
|
|
|
|
procedure TColorSpeedButton.MeasureDraw(Draw: boolean; PaintRect: TRect;
|
|
out PreferredWidth, PreferredHeight: integer);
|
|
var
|
|
GlyphWidth, GlyphHeight: integer;
|
|
Offset, OffsetCap: TPoint;
|
|
ClientSize, TotalSize, TextSize, GlyphSize: TSize;
|
|
M, S: integer;
|
|
SIndex: longint;
|
|
TMP: string;
|
|
TextFlags: integer;
|
|
DrawDetails: TThemedElementDetails;
|
|
FixedWidth: boolean;
|
|
FixedHeight: boolean;
|
|
TextRect: TRect;
|
|
HasGlyph: boolean;
|
|
HasText: boolean;
|
|
CurLayout: TButtonLayout;
|
|
begin
|
|
if Glyph = nil then
|
|
exit;
|
|
|
|
DrawDetails := GetDrawDetails;
|
|
|
|
PreferredWidth := 0;
|
|
PreferredHeight := 0;
|
|
|
|
if Draw then
|
|
begin
|
|
FLastDrawDetails := DrawDetails;
|
|
PaintBackground(PaintRect);
|
|
FixedWidth := True;
|
|
FixedHeight := True;
|
|
end
|
|
else
|
|
begin
|
|
FixedWidth := WidthIsAnchored;
|
|
FixedHeight := HeightIsAnchored;
|
|
end;
|
|
ClientSize.cx := PaintRect.Right - PaintRect.Left;
|
|
ClientSize.cy := PaintRect.Bottom - PaintRect.Top;
|
|
//debugln(['TCustomSpeedButton.MeasureDraw Step1 ',DbgSName(Self),' PaintRect=',dbgs(PaintRect)]);
|
|
// compute size of glyph
|
|
GlyphSize := GetGlyphSize(Draw, PaintRect);
|
|
GlyphWidth := GlyphSize.CX;
|
|
if NumGlyphs > 1 then
|
|
GlyphWidth := GlyphWidth div NumGlyphs;
|
|
GlyphHeight := GlyphSize.CY;
|
|
HasGlyph := (GlyphWidth <> 0) and (GlyphHeight <> 0);
|
|
//debugln(['TCustomSpeedButton.MeasureDraw Step2 ',DbgSName(Self),' PaintRect=',dbgs(PaintRect),' GlyphSize=',GlyphWidth,'x',GlyphHeight]);
|
|
|
|
// compute size of text
|
|
CurLayout := BidiAdjustButtonLayout(UseRightToLeftReading, Layout);
|
|
if ShowCaption and (Caption <> '') then
|
|
begin
|
|
TextRect := PaintRect;
|
|
// for wordbreak compute the maximum size for the text
|
|
if Margin > 0 then
|
|
InflateRect(TextRect, -Margin, -Margin);
|
|
if HasGlyph then
|
|
begin
|
|
if (Spacing >= 0) then
|
|
if CurLayout in [blGlyphLeft, blGlyphRight] then
|
|
Dec(TextRect.Right, Spacing)
|
|
else
|
|
Dec(TextRect.Bottom, Spacing);
|
|
if CurLayout in [blGlyphLeft, blGlyphRight] then
|
|
Dec(TextRect.Right, GlyphWidth)
|
|
else
|
|
Dec(TextRect.Bottom, GlyphHeight);
|
|
end;
|
|
if not FixedWidth then
|
|
begin
|
|
TextRect.Left := 0;
|
|
TextRect.Right := High(TextRect.Right) div 2;
|
|
end;
|
|
if not FixedHeight then
|
|
begin
|
|
TextRect.Top := 0;
|
|
TextRect.Bottom := High(TextRect.Bottom) div 2;
|
|
end;
|
|
TextSize := GetTextSize(Draw, TextRect);
|
|
end
|
|
else
|
|
begin
|
|
TextSize.cx := 0;
|
|
TextSize.cy := 0;
|
|
end;
|
|
HasText := (TextSize.cx <> 0) or (TextSize.cy <> 0);
|
|
|
|
if Caption <> '' then
|
|
begin
|
|
TMP := Caption;
|
|
SIndex := DeleteAmpersands(TMP);
|
|
if SIndex > 0 then
|
|
if SIndex <= Length(TMP) then
|
|
begin
|
|
//FShortcut := Ord(TMP[SIndex]);
|
|
end;
|
|
end;
|
|
|
|
if HasGlyph and HasText then
|
|
S := Spacing
|
|
else
|
|
S := 0;
|
|
M := Margin;
|
|
if not Draw then
|
|
begin
|
|
if M < 0 then
|
|
M := 2;
|
|
if S < 0 then
|
|
S := M;
|
|
end;
|
|
|
|
// Calculate caption and glyph layout
|
|
if M = -1 then
|
|
begin
|
|
// auto compute margin to center content
|
|
if S = -1 then
|
|
begin
|
|
// use the same value for Spacing and Margin
|
|
TotalSize.cx := TextSize.cx + GlyphWidth;
|
|
TotalSize.cy := TextSize.cy + GlyphHeight;
|
|
if Layout in [blGlyphLeft, blGlyphRight] then
|
|
M := (ClientSize.cx - TotalSize.cx) div 3
|
|
else
|
|
M := (ClientSize.cy - TotalSize.cy) div 3;
|
|
S := M;
|
|
end
|
|
else
|
|
begin
|
|
// fixed Spacing and center content
|
|
TotalSize.cx := GlyphWidth + S + TextSize.cx;
|
|
TotalSize.cy := GlyphHeight + S + TextSize.cy;
|
|
if Layout in [blGlyphLeft, blGlyphRight] then
|
|
M := (ClientSize.cx - TotalSize.cx) div 2
|
|
else
|
|
M := (ClientSize.cy - TotalSize.cy) div 2;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
// fixed Margin
|
|
if S = -1 then
|
|
begin
|
|
// use the rest for Spacing between Glyph and Caption
|
|
TotalSize.cx := ClientSize.cx - (Margin + GlyphWidth);
|
|
TotalSize.cy := ClientSize.cy - (Margin + GlyphHeight);
|
|
if Layout in [blGlyphLeft, blGlyphRight] then
|
|
S := (TotalSize.cx - TextSize.cx) div 2
|
|
else
|
|
S := (TotalSize.cy - TextSize.cy) div 2;
|
|
end;
|
|
end;
|
|
|
|
//debugln(['TCustomSpeedButton.MeasureDraw Step3 ',DbgSName(Self),' PaintRect=',dbgs(PaintRect),' GlyphSize=',GlyphWidth,'x',GlyphHeight,' TextSize=',TextSize.cx,'x',TextSize.cy,' S=',S,' M=',M]);
|
|
|
|
if Draw then
|
|
begin
|
|
case CurLayout of
|
|
blGlyphLeft:
|
|
begin
|
|
Offset.X := M;
|
|
Offset.Y := (ClientSize.cy - GlyphHeight) div 2;
|
|
OffsetCap.X := Offset.X + GlyphWidth + S;
|
|
OffsetCap.Y := (ClientSize.cy - TextSize.cy) div 2;
|
|
end;
|
|
blGlyphRight:
|
|
begin
|
|
Offset.X := ClientSize.cx - M - GlyphWidth;
|
|
Offset.Y := (ClientSize.cy - GlyphHeight) div 2;
|
|
OffsetCap.X := Offset.X - S - TextSize.cx;
|
|
OffsetCap.Y := (ClientSize.cy - TextSize.cy) div 2;
|
|
end;
|
|
blGlyphTop:
|
|
begin
|
|
Offset.X := (ClientSize.cx - GlyphWidth) div 2;
|
|
Offset.Y := M;
|
|
OffsetCap.X := (ClientSize.cx - TextSize.cx) div 2;
|
|
OffsetCap.Y := Offset.Y + GlyphHeight + S;
|
|
end;
|
|
blGlyphBottom:
|
|
begin
|
|
Offset.X := (ClientSize.cx - GlyphWidth) div 2;
|
|
Offset.Y := ClientSize.cy - M - GlyphHeight;
|
|
OffsetCap.X := (ClientSize.cx - TextSize.cx) div 2;
|
|
OffsetCap.Y := Offset.Y - S - TextSize.cy;
|
|
end;
|
|
end;
|
|
|
|
DrawGlyph(Canvas, PaintRect, Offset, FState, Transparent, 0);
|
|
|
|
if ShowCaption and (Caption <> '') then
|
|
begin
|
|
with PaintRect, OffsetCap do
|
|
begin
|
|
Left := Left + X;
|
|
Top := Top + Y;
|
|
end;
|
|
|
|
TextFlags := DT_LEFT or DT_TOP;
|
|
if UseRightToLeftReading then
|
|
TextFlags := TextFlags or DT_RTLREADING;
|
|
|
|
if Draw then
|
|
DrawText(Canvas, DrawDetails, Caption, PaintRect,
|
|
TextFlags, 0);
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
// measuring, not drawing
|
|
case CurLayout of
|
|
blGlyphLeft, blGlyphRight:
|
|
begin
|
|
// use text size for autosize
|
|
if FTextAutoSize then
|
|
begin
|
|
PreferredWidth := 2 * M + S + GlyphWidth + TextSize.cx;
|
|
PreferredHeight := 2 * M + Max(GlyphHeight, TextSize.cy);
|
|
end
|
|
else
|
|
begin
|
|
// ignore text size width and height
|
|
PreferredWidth := 2 * M + S + GlyphWidth;
|
|
PreferredHeight := 2 * M + {Max(}GlyphHeight{, TextSize.cy)};
|
|
end;
|
|
end;
|
|
blGlyphTop, blGlyphBottom:
|
|
begin
|
|
if FTextAutoSize then
|
|
begin
|
|
PreferredWidth := 2 * M + Max(GlyphWidth, TextSize.cx);
|
|
PreferredHeight := 2 * M + S + GlyphHeight + TextSize.cy;
|
|
end
|
|
else
|
|
begin
|
|
// ignore text size width and height
|
|
PreferredWidth := 2 * M + S + GlyphWidth;
|
|
PreferredHeight := 2 * M + S + GlyphHeight{ + TextSize.cy};
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TColorSpeedButton.Paint;
|
|
var
|
|
PaintRect: TRect;
|
|
PreferredWidth: integer;
|
|
PreferredHeight: integer;
|
|
begin
|
|
UpdateState(False);
|
|
if Glyph = nil then
|
|
exit;
|
|
|
|
PaintRect := ClientRect;
|
|
MeasureDraw(True, PaintRect, PreferredWidth, PreferredHeight);
|
|
|
|
if Assigned(OnPaint) then
|
|
OnPaint(Self);
|
|
end;
|
|
|
|
procedure TColorSpeedButton.CalculatePreferredSize(
|
|
var PreferredWidth, PreferredHeight: integer; WithThemeSpace: boolean);
|
|
var
|
|
r: TRect;
|
|
begin
|
|
r := Rect(0, 0, 0, 0);
|
|
MeasureDraw(False, r, PreferredWidth, PreferredHeight);
|
|
end;
|
|
|
|
{$endif}
|
|
|
|
procedure TColorSpeedButton.PaintBackground(var PaintRect: TRect);
|
|
var
|
|
TempState: TButtonState;
|
|
begin
|
|
TempState := FState;
|
|
if Toggle and Pressed then
|
|
TempState := bsDown;
|
|
|
|
Canvas.Pen.JoinStyle := pjsMiter; // remove rounded borders
|
|
Canvas.Pen.Style := psInsideframe; // draws border width inside equally
|
|
|
|
case TempState of
|
|
bsUp:
|
|
begin
|
|
Canvas.Pen.Color := FStateNormal.BorderColor;
|
|
Canvas.Pen.Width := FStateNormal.BorderWidth;
|
|
Canvas.Brush.Color := FStateNormal.Color;
|
|
end;
|
|
bsDisabled:
|
|
begin
|
|
Canvas.Pen.Color := FStateDisabled.BorderColor;
|
|
Canvas.Pen.Width := FStateDisabled.BorderWidth;
|
|
Canvas.Brush.Color := FStateDisabled.Color;
|
|
end;
|
|
bsDown, bsExclusive:
|
|
begin
|
|
Canvas.Pen.Color := FStateActive.BorderColor;
|
|
Canvas.Pen.Width := FStateActive.BorderWidth;
|
|
Canvas.Brush.Color := FStateActive.Color;
|
|
end;
|
|
{$IFDEF FPC}//#
|
|
bsHot:
|
|
begin
|
|
Canvas.Pen.Color := FStateHover.BorderColor;
|
|
Canvas.Pen.Width := FStateHover.BorderWidth;
|
|
Canvas.Brush.Color := FStateHover.Color;
|
|
end;
|
|
{$ENDIF}
|
|
end;
|
|
if Canvas.Pen.Width = 0 then
|
|
Canvas.Pen.Color := Canvas.Brush.Color;
|
|
Canvas.Rectangle(PaintRect);
|
|
end;
|
|
|
|
constructor TColorSpeedButton.Create(TheOwner: TComponent);
|
|
begin
|
|
inherited Create(TheOwner);
|
|
FStateNormal := TColorState.Create(Self);
|
|
FStateHover := TColorState.Create(Self);
|
|
FStateActive := TColorState.Create(Self);
|
|
FStateDisabled := TColorState.Create(Self);
|
|
{ Windows Style }
|
|
FStateNormal.Color := RGBToColor(225, 225, 225);
|
|
FStateNormal.BorderColor := RGBToColor(173, 173, 173);
|
|
FStateHover.Color := RGBToColor(229, 241, 251);
|
|
FStateHover.BorderColor := RGBToColor(0, 120, 215);
|
|
FStateActive.Color := RGBToColor(204, 228, 247);
|
|
FStateActive.BorderColor := RGBToColor(0, 84, 153);
|
|
FStateDisabled.Color := RGBToColor(204, 204, 204);
|
|
FStateDisabled.BorderColor := RGBToColor(191, 191, 191);
|
|
Font.Color := clBlack;
|
|
FTextAutoSize := True;
|
|
end;
|
|
|
|
destructor TColorSpeedButton.Destroy;
|
|
begin
|
|
FStateNormal.Free;
|
|
FStateHover.Free;
|
|
FStateActive.Free;
|
|
FStateDisabled.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TColorSpeedButton.Click;
|
|
var
|
|
p: TPoint;
|
|
begin
|
|
if Toggle then
|
|
Pressed := not Pressed;
|
|
|
|
if PopupMode then
|
|
begin
|
|
p := Parent.ClientToScreen(Point(Left, Top));
|
|
PopupMenu.PopUp(p.x, p.y + Height);
|
|
end;
|
|
|
|
inherited Click;
|
|
end;
|
|
|
|
{ TColorState }
|
|
|
|
procedure TColorState.SetFBorderColor(AValue: TColor);
|
|
begin
|
|
if FBorderColor = AValue then
|
|
Exit;
|
|
FBorderColor := AValue;
|
|
|
|
FOwner.Perform(CM_CHANGED, 0, 0);
|
|
FOwner.Invalidate;
|
|
end;
|
|
|
|
procedure TColorState.SetFBorderWidth(AValue: integer);
|
|
begin
|
|
if FBorderWidth = AValue then
|
|
Exit;
|
|
FBorderWidth := AValue;
|
|
|
|
FOwner.Perform(CM_CHANGED, 0, 0);
|
|
FOwner.Invalidate;
|
|
end;
|
|
|
|
procedure TColorState.SetFColor(AValue: TColor);
|
|
begin
|
|
if FColor = AValue then
|
|
Exit;
|
|
FColor := AValue;
|
|
|
|
FOwner.Perform(CM_CHANGED, 0, 0);
|
|
FOwner.Invalidate;
|
|
end;
|
|
|
|
constructor TColorState.Create(AOwner: TControl);
|
|
begin
|
|
inherited Create;
|
|
FOwner := AOwner;
|
|
BorderWidth := 1;
|
|
BorderColor := clBlack;
|
|
Color := clWhite;
|
|
end;
|
|
|
|
end.
|