Переходы кнопок Delphi с использованием VCL - PullRequest
0 голосов
/ 17 апреля 2019

Есть ли способ сделать переход (например, красная кнопка становится зеленой при нажатии на нее), используя Delphi с VCL?Нечто похожее на CSS переходы ...

Ответы [ 2 ]

2 голосов
/ 17 апреля 2019

Это результат быстрого исследования, которое я провел

  • Сначала вам понадобится TAnimateEasing из этого репозитория sourceForge.
  • Этот Ответ написано в Java о том, как перейти от одного цвета к другому.
  • Этот Ответ (мой) о пользовательском TSpeedButton.

И вы объединяете всеони должны иметь это

enter image description here

, и, как вы можете видеть, мой перевод ответа Java не так хорош, но это был бы другой вопрос.Вы спросили, как бы вы перешли в кнопку, и это ваш ответ

unit NCRSpeedButton;

interface

uses
  Winapi.Windows, Vcl.Controls, Winapi.Messages, Vcl.Graphics, System.Classes, AnimateEasing;

type
  TButtonState = (bs_Down, bs_Normal, bs_Active);

  TNCRSpeedButton = class(TGraphicControl)
  private
    FEasingAnimation: TAnimateEasing;
    FColor: TColor;
    FFromColor : TColor;
    FToColor : TColor;
    FBorderColor: TColor;
    procedure CMMouseDown(var Message: TMessage); message WM_LBUTTONDOWN;
    procedure CMMouseUp(var Message: TMessage); message WM_LBUTTONUP;
    procedure SetBorderColor(aBorderColor: TColor);
    procedure SetFromColor(const Value: TColor);
    procedure SetToColor(const Value: TColor);
    procedure AnimateTickEvent(Sender: TObject; Value: Extended);
    procedure ANotifyEvent(Sender: TObject);
  protected
    procedure Paint; override;
  public
    Constructor Create(Owner: TComponent); override;
    Destructor Destroy; override;
  published
    property FromColor: TColor read FFromColor write SetFromColor;
    property ToColor: TColor read FToColor write SetToColor;
    property BorderColor: TColor read FBorderColor write SetBorderColor;
    property ParentShowHint;
    property ParentBiDiMode;
    property PopupMenu;
    property ShowHint;
    property Visible;
    property OnClick;
    property OnDblClick;
    property OnMouseActivate;
    property OnMouseDown;
    property OnMouseEnter;
    property OnMouseLeave;
    property OnMouseMove;
    property OnMouseUp;
  end;


implementation
 Uses
  System.Math,
  System.UITypes;


{ TNCRSpeedButton }

Constructor TNCRSpeedButton.Create(Owner: TComponent);
begin
  inherited Create(Owner);
  FColor := clBtnFace;
  FBorderColor := clBlue;
  SetBounds(0, 0, 200, 50);
  FEasingAnimation := TAnimateEasing.Create;
  FEasingAnimation.OnTick := AnimateTickEvent;
  FEasingAnimation.OnFinish := ANotifyEvent;
end;

Destructor TNCRSpeedButton.Destroy;
begin
  FEasingAnimation.Free;
  inherited;
end;

procedure TNCRSpeedButton.Paint;
begin

  Canvas.Brush.Color := FColor;
  Canvas.FillRect(ClientRect);

  // Drawing Borders

  Canvas.Pen.Color := FBorderColor;
  Canvas.MoveTo(0, 0);
  Canvas.LineTo(Width-1, 0);
  Canvas.LineTo(Width-1, Height-1);
  Canvas.LineTo(0, Height-1);
  Canvas.LineTo(0, 0);

end;

procedure TNCRSpeedButton.AnimateTickEvent(Sender: TObject; Value: Extended);
var
  Ratio: Integer;
begin
  Ratio := 1 - Floor(Value);

  TColorRec(FColor).R := Floor((Ratio  * TColorRec(FToColor).R) + ((1 - Ratio) * TColorRec(FFromColor).R));
  TColorRec(FColor).G := Floor((Ratio  * TColorRec(FToColor).G) + ((1 - Ratio) * TColorRec(FFromColor).G));
  TColorRec(FColor).B := Floor((Ratio  * TColorRec(FToColor).B) + ((1 - Ratio) * TColorRec(FFromColor).B));

  Invalidate;
end;

procedure TNCRSpeedButton.ANotifyEvent(Sender: TObject);
begin
  FColor := FToColor;
  Invalidate;
end;

procedure TNCRSpeedButton.CMMouseDown(var Message: TMessage);
begin
  inherited;
  Invalidate;
end;

procedure TNCRSpeedButton.CMMouseUp(var Message: TMessage);
begin
  inherited;
  Invalidate;
  FColor := FFromColor;

  FEasingAnimation.Animating(0, 500, 2000, TEasingType.etBackEaseIn);
end;

procedure TNCRSpeedButton.SetBorderColor(aBorderColor: TColor);
begin
  FBorderColor := aBorderColor;
  Invalidate;
end;

procedure TNCRSpeedButton.SetFromColor(const Value: TColor);
begin
  FColor := Value;
  FFromColor  := Value;
  Invalidate;
end;

procedure TNCRSpeedButton.SetToColor(const Value: TColor);
begin
  FToColor := Value;
  Invalidate;
end;

end. 

Я оставлю, как вы решите черный цвет при переходе к вам:).

2 голосов
/ 17 апреля 2019

Стандарт TButton не поддерживает то, что вы просите.По умолчанию он получает окраску из ОС, а не из VCL.

Вам нужна кнопка, нарисованная владельцем, чтобы изменить окраску, например TBitBtn или TSpeedBtn, в противном случае вы можете создать подкласс TButton длявручную включите стиль окна BS_OWNERDRAW и обработайте уведомление WM_DRAWITEM.Или используйте сторонние рамки скининга.Или используйте стили VCL, если ваша IDE поддерживает их.

В любом случае, если у вас есть кнопка, которая может изменить цвет, вы можете просто использовать TTimer для анимации перехода одного цвета в другой по мере необходимости.

...