FMX的控件的外观以Style为主,但是也有不方便的地方,比如要任意改变TPanel的颜色,只能写代码,摸索了几天,初步实现了
unit FMX.JKPanelEx;
interface
uses
System.SysUtils, System.Classes, System.Types, System.UITypes, FMX.Types, FMX.Controls, FMX.Objects, FMX.Graphics,
FMX.Controls.Presentation, FMX.StdCtrls;
type
TAppearanceUpdateKind = (None, Fill, Stroke, CornerSize);
TJKPanelEx = class(TPanel)
private
FAppearance: TRectangle;
FFill: TBrush;
FStroke: TStrokeBrush;
FCornerSize: Single;
FAppearanceUpdateKind: TAppearanceUpdateKind;
procedure SetFill(const Value: TBrush);
procedure SetStroke(const Value: TStrokeBrush);
procedure SetCornerSize(const Value: Single);
protected
procedure ApplyStyle; override;
procedure FreeStyle; override;
procedure FillChanged(Sender: TObject); virtual;
procedure StrokeChanged(Sender: TObject); virtual;
procedure UpdateAppearanceFill;
procedure UpdateAppearanceStroke;
procedure UpdateAppearanceCornerSize;
procedure UpdateAppearance;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
property Appearance: TRectangle read FAppearance write FAppearance;
published
property Fill: TBrush read FFill write SetFill;
property Stroke: TStrokeBrush read FStroke write SetStroke;
property CornerSize: Single read FCornerSize write SetCornerSize;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('JKFMXControl', [TJKPanelEx]);
end;
{ TJKPanelEx }
procedure TJKPanelEx.ApplyStyle;
begin
inherited;
if not Assigned(FAppearance) then
begin
if not FindStyleResource<TRectangle>('Background', FAppearance) and (ResourceControl is TRectangle) then
FAppearance := TRectangle(ResourceControl);
UpdateAppearanceCornerSize;
UpdateAppearanceFill;
UpdateAppearanceStroke;
end
else
begin
UpdateAppearance;
end;
end;
constructor TJKPanelEx.Create(AOwner: TComponent);
begin
inherited;
FAppearance := nil;
FAppearanceUpdateKind := TAppearanceUpdateKind.None;
FFill := TBrush.Create(TBrushKind.Solid, TAlphaColor($FFE0E0E0));
FStroke := TStrokeBrush.Create(TBrushKind.Solid, TAlphaColors.Black);
FFill.OnChanged := FillChanged;
FStroke.OnChanged := StrokeChanged;
end;
destructor TJKPanelEx.Destroy;
begin
FreeAndNil(FFill);
FreeAndNil(FStroke);
inherited;
end;
procedure TJKPanelEx.FillChanged(Sender: TObject);
begin
FAppearanceUpdateKind := TAppearanceUpdateKind.Fill;
ApplyStyle;
end;
procedure TJKPanelEx.FreeStyle;
begin
inherited;
FAppearance := nil;
end;
procedure TJKPanelEx.SetCornerSize(const Value: Single);
begin
if FCornerSize <> Value then
begin
FAppearanceUpdateKind := TAppearanceUpdateKind.CornerSize;
FCornerSize := Value;
UpdateAppearanceCornerSize;
end;
end;
procedure TJKPanelEx.SetFill(const Value: TBrush);
begin
FFill.Assign(Value);
end;
procedure TJKPanelEx.SetStroke(const Value: TStrokeBrush);
begin
FStroke.Assign(Value);
end;
procedure TJKPanelEx.StrokeChanged(Sender: TObject);
begin
FAppearanceUpdateKind := TAppearanceUpdateKind.Stroke;
ApplyStyle;
end;
procedure TJKPanelEx.UpdateAppearance;
begin
case FAppearanceUpdateKind of
TAppearanceUpdateKind.None: ;
TAppearanceUpdateKind.Fill: UpdateAppearanceFill;
TAppearanceUpdateKind.Stroke: UpdateAppearanceStroke;
TAppearanceUpdateKind.CornerSize: UpdateAppearanceCornerSize;
end;
end;
procedure TJKPanelEx.UpdateAppearanceFill;
begin
if FAppearance <> nil then
begin
FAppearance.Fill.Assign(FFill);
end;
end;
procedure TJKPanelEx.UpdateAppearanceStroke;
begin
if FAppearance <> nil then
begin
FAppearance.Stroke.Assign(FStroke);
end;
end;
procedure TJKPanelEx.UpdateAppearanceCornerSize;
begin
if FAppearance <> nil then
begin
FAppearance.XRadius := FCornerSize;
FAppearance.YRadius := FCornerSize;
end;
end;
end.