{**********************************************}
{   TeeChart - Scrolling and blinking Banner   }
{   Copyright (c) 2006-2020 by Steema Software }
{**********************************************}
unit TeeBannerTool;
{$I TeeDefs.inc}

interface

uses
  {$IFNDEF LINUX}
  {$IFNDEF FMX}
  Windows, Messages,
  {$ENDIF}
  {$ENDIF}
  SysUtils, Classes,

  {$IFDEF FMX}
  FMX.Types, System.UITypes,
  {$ELSE}
  Graphics, Controls, ExtCtrls,
  {$ENDIF}

  {$IFDEF FMX}
  FMXTee.Engine, FMXTee.Tools, FMXTee.Chart
  {$ELSE}
  TeEngine, TeeTools, Chart
  {$ENDIF}
  ;

type
  TScrollDirection=(sdRightLeft,sdLeftRight);

  TBannerTool=class(TAnnotationTool)
  private
    FBlinkOff  : Integer;
    FBlinkOn   : Integer;
    FScrollDir : TScrollDirection;
    FStep      : Integer;

    IBlink  : TTimer;
    IDraw   : Boolean;
    IXPos   : Integer;

    procedure DoBlink(Sender:TObject);
    procedure DoScroll(Sender:TObject);
    function GetBlink: Boolean;
    function GetScroll: Boolean;
    function GetScrollDelay: Integer;
    procedure SetBlink(const Value: Boolean);
    procedure SetBlinkOff(const Value: Integer);
    procedure SetBlinkOn(const Value: Integer);
    procedure SetScroll(const Value: Boolean);
    procedure SetScrollDelay(const Value: Integer);
    procedure SetScrollDir(const Value: TScrollDirection);
    procedure SetScrollStep(const Value: Integer);
  protected
    IScroll : TTimer;

    function GetXOffset:Integer; override;
    Procedure ChartEvent(AEvent:TChartToolEvent); override;
    class Function GetEditorClass:String; override;
  public
    Constructor Create(AOwner:TComponent); override;
    Destructor Destroy; override;

    procedure Assign(Source:TPersistent); override;
    class Function Description:String; override;
    class Function LongDescription:String; override;
  published
    property Blink:Boolean read GetBlink write SetBlink default False;
    property BlinkDelayOff:Integer read FBlinkOff write SetBlinkOff default 1000;
    property BlinkDelayOn:Integer read FBlinkOn write SetBlinkOn default 1000;
    property Scroll:Boolean read GetScroll write SetScroll default True;
    property ScrollDelay:Integer read GetScrollDelay write SetScrollDelay default 50;
    property ScrollDirection:TScrollDirection read FScrollDir write SetScrollDir default sdRightLeft;
    property ScrollStep:Integer read FStep write SetScrollStep default 5;
  end;

implementation

Uses
  Math,
  {$IFDEF FMX}
  FMXTee.ProConstants
  {$ELSE}
  TeeProCo
  {$ENDIF}
  ;

{ TBannerTool }

Constructor TBannerTool.Create(AOwner: TComponent);
begin
  inherited;

  FBlinkOn:=1000;
  FBlinkOff:=1000;

  IScroll:=TTimer.Create(nil);
  IScroll.Interval:=50;
  IScroll.OnTimer:=DoScroll;

  FStep:=5;

  IBlink:=TTimer.Create(nil);
  IBlink.Enabled:=False;
  IBlink.Interval:=FBlinkOn;
  IBlink.OnTimer:=DoBlink;

  IDraw:=True;
end;

Destructor TBannerTool.Destroy;
begin
  IBlink.Free;
  IScroll.Free;
  inherited;
end;

procedure TBannerTool.DoBlink(Sender:TObject);
begin
  if Visible then
  begin
    IBlink.Enabled:=False;
    IDraw:=not IDraw;

    if IDraw then
       IBlink.Interval:=FBlinkOn
    else
       IBlink.Interval:=FBlinkOff;

    Repaint;

    IBlink.Enabled:=True;
  end;
end;

procedure TBannerTool.DoScroll(Sender:TObject);
begin
  if Visible then
  begin
    IScroll.Enabled:=False;

    if FScrollDir=sdRightLeft then
    begin
      Dec(IXPos,FStep);

      if IXPos<-2*Width then
         IXPos:=0;
    end
    else
    begin
      Inc(IXPos,FStep);

      if IXPos>2*Width then
         IXPos:=0;
    end;

    Repaint;

    IScroll.Enabled:=True;
  end;
end;

function TBannerTool.GetScrollDelay: Integer;
begin
  result:=IScroll.Interval;
end;

function TBannerTool.GetScroll: Boolean;
begin
  result:=IScroll.Enabled;
end;

procedure TBannerTool.SetScrollDelay(const Value: Integer);
begin
  IScroll.Interval:=Value;
end;

procedure TBannerTool.SetScroll(const Value: Boolean);
begin
  IScroll.Enabled:=Value;

  if Visible then
     Repaint;
end;

function TBannerTool.GetXOffset:Integer;
begin
  if IScroll.Enabled then
     if FScrollDir=sdRightLeft then
        result:=Width+IXPos
     else
        result:=-(Width-IXPos)
  else
     result:=0;
end;

class function TBannerTool.GetEditorClass: String;
begin
  result:='TBannerEditor'; // Do not localize
end;

function TBannerTool.GetBlink: Boolean;
begin
  result:=IBlink.Enabled;
end;

procedure TBannerTool.SetBlink(const Value: Boolean);
begin
  IBlink.Enabled:=Value;

  if Visible then
     Repaint;
end;

procedure TBannerTool.SetBlinkOn(const Value: Integer);
begin
  SetIntegerProperty(FBlinkOn,Value);
end;

procedure TBannerTool.ChartEvent(AEvent: TChartToolEvent);
begin
  if IDraw then
     inherited;
end;

procedure TBannerTool.Assign(Source: TPersistent);
begin
  if Source is TBannerTool then
  with TBannerTool(Source) do
  begin
    Self.FBlinkOff:=FBlinkOff;
    Self.FBlinkOn:=FBlinkOn;
    Self.FScrollDir:=FScrollDir;
    Self.FStep:=FStep;

    Self.IBlink.Enabled:=IBlink.Enabled;
    Self.IScroll.Enabled:=IScroll.Enabled;
    Self.IScroll.Interval:=IScroll.Interval;
  end;

  inherited;
end;

class function TBannerTool.Description: String;
begin
  result:=TeeMsg_BannerTool;
end;

class function TBannerTool.LongDescription: String;
begin
  result:=TeeMsg_BannerToolDesc;
end;

procedure TBannerTool.SetBlinkOff(const Value: Integer);
begin
  SetIntegerProperty(FBlinkOff,Value);
end;

procedure TBannerTool.SetScrollDir(const Value: TScrollDirection);
begin
  if FScrollDir<>Value then
  begin
    FScrollDir:=Value;
    IXPos:=0;

    if Visible then
       Repaint;
  end;
end;

procedure TBannerTool.SetScrollStep(const Value: Integer);
begin
  SetIntegerProperty(FStep,Max(1,Value));
end;

initialization
  RegisterTeeTools([TBannerTool]);
finalization
  UnRegisterTeeTools([TBannerTool]);
end.
