unit uecZoomBarComponent;

interface
uses
  Windows, messages,forms,sysutils,Classes, Graphics,  Controls, StdCtrls, ExtCtrls,
  uecNativeMapControl,uecMapUtil;

type

  TZoomBarComponent = class(TECCustomTool)
  private

   tmZoom    : TTimer;

   FPanelBar : TPanel;
   FNextZoom ,
   FPrevZoom : Tbutton;

   FButtonSize : integer;

   FInProgressiveZoom,
   FProgressiveZoom : boolean;

   FXYRadius : integer;

   procedure setXYRadius(const Value: integer);

   procedure setProgressiveZoom(const value:boolean);

   procedure setButtonSize(const value:integer);

   procedure doNextZoom(Sender:TObject);
   procedure doPrevZoom(Sender:TObject);

   procedure doNextMouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: integer);
   procedure doNextMouseUp(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: integer);

   procedure tmZoomTimer(Sender: TObject);

   procedure ChangeZoom;

   protected
    procedure setLayout(const value:TECCustomToolLayout);  override;

   public
   constructor Create(Map : TNativeMapControl);  override;
   destructor  Destroy; override;


   property ButtonSize : integer read FButtonSize  write setButtonSize;

   property ProgressiveZoom : boolean read FProgressiveZoom write setProgressiveZoom;

   property XYRadius : integer read FXYRadius write setXYRadius;


  end;

implementation

constructor TZoomBarComponent.Create(Map : TNativeMapControl);
begin

  inherited;


  // create zoom bar

  // FPanelBar will be the support that determines the total occupancy of our component
  // It will be connected to TECNativeMap

  FPanelBar  := TPanel.Create(nil);
  FPanelBar.BevelOuter := bvNone;
  FPanelBar.ParentBackground := false;
  FPanelBar.Color := clBtnFace;
  FPanelBar.showHint := true;


  // place buttons on the panel

  FNextZoom := TButton.Create(FPanelBar);
  FNextZoom.Parent := FPanelBar;
  FNextZoom.Caption:= '+';
  FNextZoom.Hint   := doubleToStrDigit(map.NumericalZoom,1);
  FNextZoom.font.size := 11;
  FNextZoom.onClick := doNextZoom;

  FPrevZoom := TButton.Create(FPanelBar);
  FPrevZoom.Parent := FPanelBar;
  FPrevZoom.Caption:= '-';
  FPrevZoom.Hint   := doubleToStrDigit(map.NumericalZoom,1);
  FPrevZoom.font.size := 11;
  FPrevZoom.onClick:= doPrevZoom;


   // Anchoring the panel on the map

  add('ZoomBar',FPanelBar,ecTopRight);

  ButtonSize := 32;

 // A timer is used to manage the progressive zoom
 // triggered when a zoom button is pressed.

  tmZoom := TTimer.Create(nil);
  tmZoom.Enabled  := false;
  tmZoom.Interval := 80;
  tmZoom.OnTimer := tmZoomTimer;

  ProgressiveZoom := true;

  XYRadius := 4;

end;

procedure TZoomBarComponent.setXYRadius(const Value: integer);
begin


  if Value <= 10 then
    FXYRadius := Value
  else
  if FXYRadius=10 then
   exit
  else
    FXYRadius := 10;


RoundCornerOf( FPanelBar,XYRadius);


end;
procedure TZoomBarComponent.setProgressiveZoom(const value:boolean);
begin

  FProgressiveZoom := value;

  if value then
  begin
    FNextZoom.OnMouseDown := doNextMouseDown;
    FNextZoom.OnMouseUp   := doNextMouseUp;
    FPrevZoom.OnMouseDown := doNextMouseDown;
    FPrevZoom.OnMouseUp   := doNextMouseUp;
  end
  else
  begin
    FNextZoom.OnMouseDown := nil;
    FNextZoom.OnMouseUp   := nil;
    FPrevZoom.OnMouseDown := nil;
    FPrevZoom.OnMouseUp   := nil;
  end;
end;

procedure TZoomBarComponent.setButtonSize(const value:integer);
begin
 FButtonSize := value;

 FNextZoom.width  := FButtonSize;
 FNextZoom.Height := FButtonSize;

 FPrevZoom.width  := FButtonSize;
 FPrevZoom.Height := FButtonSize;

 // recalculate button layout
 Layout:=Layout;

end;

procedure TZoomBarComponent.setLayout(const value:TECCustomToolLayout);
begin
  inherited;

  FNextZoom.Top    := -1;
  FNextZoom.Left   := -1;

 if (Layout=ctlVertical) then
 begin
   Width := FButtonSize-1;
   Height := 2*FButtonSize-2;
   FPrevZoom.Top    := FButtonSize-2;
   FPrevZoom.Left   := -1;
 end
 else
 begin
   Width := 2*FButtonSize-1;
   Height:= FButtonSize-1;
   FPrevZoom.Top    := -1;
   FPrevZoom.Left   := FButtonSize-1;
 end;

 RoundCornerOf( FPanelBar,XYRadius);

end;


procedure TZoomBarComponent.ChangeZoom;
begin
   FNextZoom.Hint   := doubleToStrDigit(map.NumericalZoom,1);
   FPrevZoom.Hint   := doubleToStrDigit(map.NumericalZoom,1);
end;


procedure TZoomBarComponent.doNextZoom(Sender:TObject);
begin
 if not FInProgressiveZoom then
 begin
   Map.Zoom := Map.Zoom + 1;
   ChangeZoom;
 end;

 FInProgressiveZoom := false;
end;

procedure TZoomBarComponent.doPrevZoom(Sender:TObject);
begin
  if not FInProgressiveZoom then
  begin
    Map.Zoom := Map.Zoom - 1;
    ChangeZoom;
  end;

  FInProgressiveZoom := false;
end;

// ============= automatic Zoom ================================================

// activate the timer when the button is pressed
// a progressive zoom will then be automatically performed
procedure TZoomBarComponent.doNextMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: integer);
begin
 // save the button pressed to react on it.
 tmZoom.Tag       := integer(Sender);
 tmZoom.Enabled   := true;
end;


// cancel progressive zoom

procedure TZoomBarComponent.doNextMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: integer);
begin
 tmZoom.Enabled   := false;
 ChangeZoom;
end;



// Progressive zoom in or out
// Allows to go beyond the maximum zoom managed by the tile server
procedure TZoomBarComponent.tmZoomTimer(Sender: TObject);
begin

  FInProgressiveZoom := true;

  if (TButton(tmZoom.Tag) = FNextZoom) then
  begin
    map.ZoomScaleFactor := map.ZoomScaleFactor + 10
  end
  else
   map.ZoomScaleFactor := map.ZoomScaleFactor - 10;

end;

//------------------------------------------------------------------------------



destructor  TZoomBarComponent.Destroy;
begin
 inherited;
 tmZoom.free;
 FPanelBar.Free;
end;


end.
