{*********************************************}
{  TeeChart Charting Library for FireMonkey   }
{  Copyright (c) 2012-2020 by Steema Software }
{  All Rights Reserved                        }
{*********************************************}
unit FMXTee.Editor.Axis;
{$I TeeDefs.inc}

interface

uses
  System.SysUtils, System.Types, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms,
  {$IFNDEF UPTOXE3}
  FMX.StdCtrls,
  {$ENDIF}
  FMX.Edit, FMX.ListBox, FMX.Memo, FMX.Dialogs, FMX.Layouts, FMX.TabControl,
  FMXTee.Engine, FMXTee.Editor.CustomShape, FMXTee.Editor.Margins,
  {$IFDEF D21}
  FMX.ComboTrackBar, FMX.SpinBox, FMX.ComboEdit,
  {$ENDIF}
  FMXTee.Editor.Stroke, FMXTee.RadioGroup;

type
  TAxisEditor = class(TForm)
    Splitter1: TSplitter;
    PageAxis: TTabControl;
    TabScales: TTabItem;
    PageScales: TTabControl;
    TabOptions: TTabItem;
    Label2: TLabel;
    CBAutomatic: TCheckBox;
    CBLogarithmic: TCheckBox;
    CBVisible: TCheckBox;
    CBInverted: TCheckBox;
    ELogBase: TEdit;
    LogE: TCheckBox;
    TabSheet1: TTabItem;
    Label4: TLabel;
    CBAutoMin: TCheckBox;
    BAxisMin: TButton;
    UDMinOff: TSpinBox;
    CBMinRound: TCheckBox;
    TabSheet2: TTabItem;
    Label5: TLabel;
    CBAutoMax: TCheckBox;
    BAxisMax: TButton;
    UDMaxOff: TSpinBox;
    CBMaxRound: TCheckBox;
    TabSheet3: TTabItem;
    L6: TLabel;
    BIncre: TButton;
    CBShowAll: TCheckBox;
    TabTitle: TTabItem;
    PageTitle: TTabControl;
    TabTitleStyle: TTabItem;
    L14: TLabel;
    L3: TLabel;
    L9: TLabel;
    ETitle: TEdit;
    UDTitleSize: TSpinBox;
    CBTitleVisible: TCheckBox;
    TabLabels: TTabItem;
    PageLabels: TTabControl;
    TabLabStyle: TTabItem;
    L26: TLabel;
    L23: TLabel;
    L20: TLabel;
    Label3: TLabel;
    CBLabels: TCheckBox;
    CBMultiline: TCheckBox;
    CBOnAxis: TCheckBox;
    CBRoundFirst: TCheckBox;
    UDLabelsSize: TSpinBox;
    UDSepar: TSpinBox;
    CBLabelStyle: TComboBox;
    CBAlternate: TCheckBox;
    CBLabelsBehind: TCheckBox;
    TabLabOptions: TTabItem;
    LabelAxisFormat: TLabel;
    CBFormat: TComboEdit;
    CBExpo: TCheckBox;
    CBLabelAlign: TCheckBox;
    Button1: TButton;
    TabTicks: TTabItem;
    TabGrid: TTabItem;
    TabPositions: TTabItem;
    Label41: TLabel;
    Label42: TLabel;
    Label43: TLabel;
    LabelZ: TLabel;
    Label7: TLabel;
    UDPos: TSpinBox;
    UDStart: TSpinBox;
    UDEnd: TSpinBox;
    CBOtherSide: TCheckBox;
    CBHorizAxis: TCheckBox;
    UDZ: TSpinBox;
    CBPosUnits: TComboBox;
    TabItems: TTabItem;
    Splitter2: TSplitter;
    ListItems: TListBox;
    PanelItems: TPanel;
    Label10: TLabel;
    Label11: TLabel;
    EItemValue: TEdit;
    ButtonFormat: TButton;
    AxisItemText: TMemo;
    Panel3: TPanel;
    CBItemsAuto: TCheckBox;
    Panel1: TPanel;
    PanelCustomAxes: TPanel;
    BAdd: TButton;
    BDelete: TButton;
    Panel4: TPanel;
    Label1: TLabel;
    CBShow: TCheckBox;
    CBAxisBeh: TCheckBox;
    LBAxes: TListBox;
    EAxisMin: TEdit;
    EAxisMax: TEdit;
    EIncrement: TEdit;
    CBAutoInc: TCheckBox;
    TabTitleFormat: TTabItem;
    TabLabFormat: TTabItem;
    TabLabMargins: TTabItem;
    TabLabBack: TTabItem;
    Label12: TLabel;
    CBLabelsPos: TComboBox;
    TabAxis: TTabItem;
    TabControlTicks: TTabControl;
    TabOuter: TTabItem;
    TabInner: TTabItem;
    TabMinor: TTabItem;
    Layout1: TLayout;
    L28: TLabel;
    UDAxisTickLength: TSpinBox;
    CBTickOnLabels: TCheckBox;
    Layout2: TLayout;
    L29: TLabel;
    UDInnerTicksLength: TSpinBox;
    Layout3: TLayout;
    L30: TLabel;
    UDAxisMinorTickLen: TSpinBox;
    Label9: TLabel;
    UDMinorC: TSpinBox;
    TabControlGrid: TTabControl;
    TabGridBorder: TTabItem;
    TabMinorGrid: TTabItem;
    Layout4: TLayout;
    Layout5: TLayout;
    CBGridCentered: TCheckBox;
    Label6: TLabel;
    UDGridZ: TSpinBox;
    Label8: TLabel;
    UDEvery: TSpinBox;
    L31: TLabel;
    UDMinorCount: TSpinBox;
    CBAngle: TComboTrackBar;
    CBTitleAngle: TComboTrackBar;
    RGTitlePos: TRadioGroup;
    RadioButton1: TRadioButton;
    RadioButton2: TRadioButton;
    RadioButton3: TRadioButton;
    CBImages: TCheckBox;
    procedure PageAxisChange(Sender: TObject);
    procedure BAxisMinClick(Sender: TObject);
    procedure BAxisMaxClick(Sender: TObject);
    procedure BIncreClick(Sender: TObject);
    procedure PageTitleChange(Sender: TObject);
    procedure PageLabelsChange(Sender: TObject);
    procedure CBFormatChange(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure CBPosUnitsChange(Sender: TObject);
    procedure ButtonFormatClick(Sender: TObject);
    procedure BAddClick(Sender: TObject);
    procedure BDeleteClick(Sender: TObject);
    procedure LBAxesChange(Sender: TObject);
    procedure CBShowChange(Sender: TObject);
    procedure CBAxisBehChange(Sender: TObject);
    procedure CBAutomaticChange(Sender: TObject);
    procedure CBVisibleChange(Sender: TObject);
    procedure CBLogarithmicChange(Sender: TObject);
    procedure CBInvertedChange(Sender: TObject);
    procedure LogEChange(Sender: TObject);
    procedure CBTitleVisibleChange(Sender: TObject);
    procedure UDTitleSizeChangeTracking(Sender: TObject);
    procedure CBAutoMinChange(Sender: TObject);
    procedure UDMinOffChangeTracking(Sender: TObject);
    procedure CBMinRoundChange(Sender: TObject);
    procedure CBAutoMaxChange(Sender: TObject);
    procedure UDMaxOffChangeTracking(Sender: TObject);
    procedure CBMaxRoundChange(Sender: TObject);
    procedure CBShowAllChange(Sender: TObject);
    procedure CBLabelsChange(Sender: TObject);
    procedure CBMultilineChange(Sender: TObject);
    procedure CBRoundFirstChange(Sender: TObject);
    procedure CBOnAxisChange(Sender: TObject);
    procedure CBAlternateChange(Sender: TObject);
    procedure CBLabelsBehindChange(Sender: TObject);
    procedure CBLabelStyleChange(Sender: TObject);
    procedure UDLabelsSizeChangeTracking(Sender: TObject);
    procedure UDSeparChangeTracking(Sender: TObject);
    procedure CBExpoChange(Sender: TObject);
    procedure CBLabelAlignChange(Sender: TObject);
    procedure CBTickOnLabelsChange(Sender: TObject);
    procedure UDAxisTickLengthChangeTracking(Sender: TObject);
    procedure UDInnerTicksLengthChangeTracking(Sender: TObject);
    procedure UDAxisMinorTickLenChangeTracking(Sender: TObject);
    procedure UDMinorCChangeTracking(Sender: TObject);
    procedure CBGridCenteredChange(Sender: TObject);
    procedure UDGridZChangeTracking(Sender: TObject);
    procedure UDEveryChangeTracking(Sender: TObject);
    procedure UDMinorCountChangeTracking(Sender: TObject);
    procedure UDPosChangeTracking(Sender: TObject);
    procedure UDStartChangeTracking(Sender: TObject);
    procedure UDEndChangeTracking(Sender: TObject);
    procedure CBOtherSideChange(Sender: TObject);
    procedure CBHorizAxisChange(Sender: TObject);
    procedure UDZChangeTracking(Sender: TObject);
    procedure CBItemsAutoChange(Sender: TObject);
    procedure AxisItemTextChangeTracking(Sender: TObject);
    procedure ListItemsChange(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure ELogBaseTyping(Sender: TObject);
    procedure EItemValueTyping(Sender: TObject);
    procedure ETitleTyping(Sender: TObject);
    procedure CBAutoIncChange(Sender: TObject);
    procedure EIncrementChangeTracking(Sender: TObject);
    procedure EAxisMaxChangeTracking(Sender: TObject);
    procedure EAxisMinChangeTracking(Sender: TObject);
    procedure CBLabelsPosChange(Sender: TObject);
    procedure TabControlTicksChange(Sender: TObject);
    procedure TabControlGridChange(Sender: TObject);
    procedure CBAngleChangeTracking(Sender: TObject);
    procedure CBAngleChange(Sender: TObject);
    procedure CBTitleAngleChangeTracking(Sender: TObject);
    procedure CBTitleAngleChange(Sender: TObject);
    procedure RGTitlePosChange(Sender: TObject);
    procedure CBImagesChange(Sender: TObject);
  private
   { Private declarations }
    Axes : TChartAxes;

    ILabelsFormat : TTeeShapeEditor;
    ILabelsMargins: TMarginsEditor;
    IBack         : TTeeShapeEditor;

    IGrid,
    IMinorGrid,
    IOuter,
    IInner,
    IMinor,
    IAxisEditor   : TStrokeEditor;
    ITitleEditor  : TTeeShapeEditor;

    function Axis:TChartAxis;
    Procedure EnableLogBaseControls;
    procedure RefreshAxes(const AAxes:TChartAxes);
    Procedure SetAxisIndex(const Axis:TChartAxis);
    procedure SetAxisScales;
    procedure SetScaleEdit(const Value:Double; const AEdit:TEdit);
  public
   { Public declarations }
    class function CreateEditor(const AOwner:TComponent; const AAxes:TChartAxes):TAxisEditor; overload;
    class function CreateEditor(const AOwner:TComponent; const AAxis:TChartAxis):TAxisEditor; overload;
    procedure RefreshAxis(const Axis:TChartAxis);
  end;

procedure FillAxesList(const Axes:TChartAxes; const AList:TCustomListBox; AddDepth:Boolean);

implementation

{$R *.fmx}

uses
  FMXTee.Procs, FMXTee.Chart, FMXTee.Editor.Formatting,
  FMXTee.Editor.AxisMaxMin, FMXTee.Editor.AxisIncr, FMXTee.Canvas,
  FMXTee.Constants, FMXTee.Editor.Picture;

procedure TAxisEditor.PageAxisChange(Sender: TObject);

  Procedure SetAxisLabels;
  var tmp : String;
  begin  { Axis Labels  }
    with Axis.Texts do
    begin
      CBLabels.IsChecked:=Visible;
      CBLabelStyle.ItemIndex:=Ord(Style);
      CBOnAxis.IsChecked:=OnAxis;
      CBRoundFirst.IsChecked:=RoundFirst;

      CBAngle.Value:=Angle;

      UDSepar.Value:=Separation;
      UDLabelsSize.Value:=Size;
      CBMultiline.IsChecked:=MultiLine;
      CBExpo.IsChecked:=Exponent;
      CBFormat.Items.Clear;
      CBAlternate.IsChecked:=Alternate;
      CBLabelsBehind.IsChecked:=Behind;
      CBImages.IsChecked:=UseImages;
    end;

    if Axis.IsDateTime then
    begin
      With CBFormat.Items do
      if Axis.Maximum-Axis.Minimum<=1 then
      begin
        Add({$IFDEF D15}FormatSettings.{$ENDIF}ShortTimeFormat);
        Add({$IFDEF D15}FormatSettings.{$ENDIF}LongTimeFormat);
        Add('hh:nn');
        Add('hh:nn:ss');
        Add('hh:nn:ss.zzz');
      end
      else
      begin
        Add({$IFDEF D15}FormatSettings.{$ENDIF}ShortDateFormat);
        Add({$IFDEF D15}FormatSettings.{$ENDIF}LongDateFormat);
        Add('yyyy-mm-dd');
        Add('mm-dd-yyyy');
        Add('dd-mm-yyyy');
        Add('ddd');
        Add('dddd');
        Add('mmm');
        Add('mmmm');
      end;

      LabelAxisFormat.Text:=StripHotKey(TeeMsg_DateTimeFormat);

      tmp:=Axis.DateTimeFormat;
      if tmp='' then
         tmp:=DateTimeDefaultFormat(Axis.Maximum-Axis.Minimum);
    end
    else
    begin
      TFormatEditor.AddDefaultFormats(CBFormat);
      LabelAxisFormat.Text:=StripHotKey(TeeMsg_ValuesFormat);
      tmp:=Axis.AxisValuesFormat;

      if tmp='' then
         tmp:=TeeMsg_DefValueFormat;

      tmp:=DelphiToLocalFormat(tmp);
    end;

    with CBFormat.Items do
    if IndexOf(tmp)=-1 then
       Add(tmp);

    CBFormat.Text:=tmp;

    if Assigned(ILabelsFormat) then
       ILabelsFormat.RefreshShape(Axis.Texts.Format);

    if Assigned(ILabelsMargins) then
       ILabelsMargins.RefreshMargins(Axis.Texts.Format.Margins);

    if Assigned(IBack) then
       IBack.RefreshShape(Axis.Shape);
  end;

  Procedure SetAxisTicks;
  begin
    with Axis do
    begin
      UDAxisTickLength.Value:=TickLength;
      UDInnerTicksLength.Value:=TickInnerLength;
      CBTickOnLabels.IsChecked:=TickOnLabelsOnly;
      UDAxisMinorTickLen.Value:=MinorTickLength;
      UDMinorC.Value:=MinorTickCount;
    end;

    TabControlTicksChange(Self);

    if Assigned(IOuter) then
       IOuter.RefreshPen(Axis.Ticks);

    if Assigned(IInner) then
       IInner.RefreshPen(Axis.TicksInner);

    if Assigned(IMinor) then
       IMinor.RefreshPen(Axis.MinorTicks);
  end;

  Procedure SetAxisGrids;
  begin
    with Axis do
    begin
      CBGridCentered.IsChecked:=Grid.Centered;
      UDGridZ.Value:=Grid.ZPosition;
      UDEvery.Value:=Grid.DrawEvery;
      UDMinorCount.Value:=MinorTickCount;
    end;

    TabControlGridChange(Self);

    if Assigned(IGrid) then
       IGrid.RefreshPen(Axis.Grid);

    if Assigned(IMinorGrid) then
       IMinorGrid.RefreshPen(Axis.MinorGrid);
  end;

  Procedure SetAxisTitle;
  begin
    with Axis do
    begin
      ETitle.Text:=Title.Caption;
      CBTitleAngle.Value:=Title.Angle;
      UDTitleSize.Value:=TitleSize;
      CBTitleVisible.IsChecked:=Title.Visible;
      RGTitlePos.ItemIndex:=Ord(Title.Position);

      if Assigned(ITitleEditor) then
         ITitleEditor.RefreshShape(Title);
    end;
  end;

  Procedure SetAxisPositions;
  begin
    with Axis do
    begin
      UDPos.Value:=PositionPercent;
      UDStart.Value:=StartPosition;
      UDEnd.Value:=EndPosition;
      UDZ.Value:=ZPosition;
      CBPosUnits.ItemIndex:=Ord(PositionUnits);

      CBOtherSide.IsChecked:=OtherSide;
      CBOtherSide.Enabled:=LBAxes.ItemIndex>=TeeInitialCustomAxis;
      CBHorizAxis.IsChecked:=Horizontal;
      CBHorizAxis.Enabled:=LBAxes.ItemIndex>=TeeInitialCustomAxis;
      UDZ.Enabled:=not IsDepthAxis;
    end;
  end;

  procedure SetAxisAxis;
  begin
    if Assigned(IAxisEditor) then
       IAxisEditor.RefreshPen(Axis.Axis)
    else
       IAxisEditor:=TStrokeEditor.InsertForm(Axis.Axis,TabAxis);
  end;

  procedure SetAxisItems;
  var t : Integer;
      tmp : TListBoxItem;
  begin
    ListItems.Clear;

    CBItemsAuto.IsChecked:=Axis.Items.Automatic;
    CBItemsAutoChange(Self);

    with Axis.Items do
    for t:=0 to Count-1 do
    begin
      tmp:=TListBoxItem.Create(ListItems.Owner);
      tmp.Text:=Item[t].Text;
      ListItems.AddObject(tmp);
    end;

    if ListItems.Count>0 then
    begin
      ListItems.ItemIndex:=0;
      ListItemsChange(Self);
    end
    else
    begin
      EItemValue.Text:='';
      AxisItemText.Text:='';
    end;
  end;

begin
  with PageAxis do
  if ActiveTab=TabLabels then SetAxisLabels else
  if ActiveTab=TabScales then SetAxisScales else
  if ActiveTab=TabTitle then SetAxisTitle else
  if ActiveTab=TabAxis then SetAxisAxis else
  if ActiveTab=TabTicks then SetAxisTicks else
  if ActiveTab=TabGrid then SetAxisGrids else
  if ActiveTab=TabPositions then SetAxisPositions else
  if ActiveTab=TabItems then SetAxisItems;
end;

procedure TAxisEditor.CBAutoIncChange(Sender: TObject);
begin
  if CBAutoInc.IsChecked and (Axis.Increment<>0) then
  begin
    Axis.Increment:=0;
    SetAxisScales;
  end;
end;

procedure TAxisEditor.CBAutomaticChange(Sender: TObject);
begin
  Axis.Automatic:=CBAutomatic.IsChecked;

  SetScaleEdit(Axis.Minimum,EAxisMin);
  SetScaleEdit(Axis.Maximum,EAxisMax);
end;

procedure TAxisEditor.CBLogarithmicChange(Sender: TObject);
begin
  try
    try
      Axis.Logarithmic:=CBLogarithmic.IsChecked;
    except
      on AxisException do
      Begin
        Axis.Logarithmic:=False;
        CBLogarithmic.IsChecked:=False;
        Raise;
      end;
    end;
  finally
    EnableLogBaseControls;
  end;
end;

Procedure TAxisEditor.EnableLogBaseControls;
begin
  ELogBase.Enabled:=CBLogarithmic.IsChecked and CBLogarithmic.Enabled;
  LogE.Enabled:=ELogBase.Enabled;
end;

procedure TAxisEditor.ETitleTyping(Sender: TObject);
begin
  Axis.Title.Caption:=ETitle.Text;
end;

procedure TAxisEditor.CBVisibleChange(Sender: TObject);
begin
  Axis.Visible:=CBVisible.IsChecked;
end;

class function TAxisEditor.CreateEditor(const AOwner: TComponent;
  const AAxis: TChartAxis): TAxisEditor;
begin
  result:=CreateEditor(AOwner, AAxis.ParentChart.Axes);
  result.RefreshAxis(AAxis);
end;

procedure TAxisEditor.CBImagesChange(Sender: TObject);
begin
  Axis.Texts.UseImages:=CBImages.IsChecked;
end;

procedure TAxisEditor.CBInvertedChange(Sender: TObject);
begin
  Axis.Inverted:=CBInverted.IsChecked;
end;

procedure TAxisEditor.LogEChange(Sender: TObject);
begin
  Axis.LogarithmicBase:=Exp(1);
  LogE.Enabled:=False;
end;

procedure TAxisEditor.CBAutoMaxChange(Sender: TObject);
begin
  Axis.AutomaticMaximum:=CBAutoMax.IsChecked;
  SetScaleEdit(Axis.Maximum,EAxisMax);
end;

procedure TAxisEditor.CBAutoMinChange(Sender: TObject);
begin
  Axis.AutomaticMinimum:=CBAutoMin.IsChecked;
  SetScaleEdit(Axis.Minimum,EAxisMin);
end;

procedure TAxisEditor.BAxisMinClick(Sender: TObject);
begin
  if TAxisMaxMin.Edit(Self, Axis, CBAutoMin, False) then
     SetAxisScales;
end;

procedure TAxisEditor.CBMinRoundChange(Sender: TObject);
begin
  Axis.MinimumRound:=CBMinRound.IsChecked;
end;

procedure TAxisEditor.BAxisMaxClick(Sender: TObject);
begin
  if TAxisMaxMin.Edit(Self, Axis, CBAutoMax, True) then
     SetAxisScales;
end;

procedure TAxisEditor.CBMaxRoundChange(Sender: TObject);
begin
  Axis.MaximumRound:=CBMaxRound.IsChecked;
end;

procedure TAxisEditor.BIncreClick(Sender: TObject);
begin
  if TAxisIncrement.ChangeIncrement(Self, Axis) then
     SetAxisScales;
end;

procedure TAxisEditor.CBShowAllChange(Sender: TObject);
begin
  if CBShowAll.IsChecked then
     Axis.LabelsSeparation:=0
  else
     Axis.LabelsSeparation:=TeeDefaultLabelsSeparation;
end;

procedure TAxisEditor.PageTitleChange(Sender: TObject);
begin
  if (PageTitle.ActiveTab=TabTitleFormat) and (not Assigned(ITitleEditor)) then
     ITitleEditor:=TTeeShapeEditor.InsertForm(Axis.Title,TabTitleFormat);
end;

procedure TAxisEditor.UDAxisMinorTickLenChangeTracking(Sender: TObject);
begin
  if Axis<>nil then
     Axis.MinorTickLength:=Round(UDAxisMinorTickLen.Value);
end;

procedure TAxisEditor.UDAxisTickLengthChangeTracking(Sender: TObject);
begin
  if Axis<>nil then
     Axis.TickLength:=Round(UDAxisTickLength.Value);
end;

procedure TAxisEditor.UDEndChangeTracking(Sender: TObject);
begin
  if Axis<>nil then
     Axis.EndPosition:=UDEnd.Value;
end;

procedure TAxisEditor.UDEveryChangeTracking(Sender: TObject);
begin
  if Axis<>nil then
     Axis.Grid.DrawEvery:=Round(UDEvery.Value);
end;

procedure TAxisEditor.UDGridZChangeTracking(Sender: TObject);
begin
  if Axis<>nil then
     Axis.Grid.ZPosition:=UDGridZ.Value;
end;

procedure TAxisEditor.UDInnerTicksLengthChangeTracking(Sender: TObject);
begin
  if Axis<>nil then
     Axis.TickInnerLength:=Round(UDInnerTicksLength.Value);
end;

procedure TAxisEditor.UDLabelsSizeChangeTracking(Sender: TObject);
begin
  if Axis<>nil then
     Axis.LabelsSize:=Round(UDLabelsSize.Value);
end;

procedure TAxisEditor.UDMaxOffChangeTracking(Sender: TObject);
begin
  if Axis<>nil then
     Axis.MaximumOffset:=Round(UDMaxOff.Value);
end;

procedure TAxisEditor.UDMinOffChangeTracking(Sender: TObject);
begin
  if Axis<>nil then
     Axis.MinimumOffset:=Round(UDMinOff.Value);
end;

procedure TAxisEditor.UDMinorCChangeTracking(Sender: TObject);
begin
  if Axis<>nil then
  begin
    Axis.MinorTickCount:=Round(UDMinorC.Value);
    UDMinorCount.Value:=UDMinorC.Value;
  end;
end;

procedure TAxisEditor.UDMinorCountChangeTracking(Sender: TObject);
begin
  if Axis<>nil then
  begin
    Axis.MinorTickCount:=Round(UDMinorCount.Value);
    UDMinorC.Value:=UDMinorCount.Value;
  end;
end;

procedure TAxisEditor.UDPosChangeTracking(Sender: TObject);
begin
  if Axis<>nil then
     Axis.PositionPercent:=UDPos.Value;
end;

procedure TAxisEditor.UDSeparChangeTracking(Sender: TObject);
begin
  if Axis<>nil then
     Axis.LabelsSeparation:=Round(UDSepar.Value);
end;

procedure TAxisEditor.UDStartChangeTracking(Sender: TObject);
begin
  if Axis<>nil then
     Axis.StartPosition:=UDStart.Value;
end;

procedure TAxisEditor.UDTitleSizeChangeTracking(Sender: TObject);
begin
  if Axis<>nil then
     Axis.TitleSize:=Round(UDTitleSize.Value);
end;

procedure TAxisEditor.UDZChangeTracking(Sender: TObject);
begin
  if Axis<>nil then
     Axis.ZPosition:=UDZ.Value;
end;

procedure TAxisEditor.CBTitleAngleChange(Sender: TObject);
begin
  CBTitleAngleChangeTracking(Self);
end;

procedure TAxisEditor.CBTitleAngleChangeTracking(Sender: TObject);
begin
  if Axis<>nil then
     Axis.Title.Angle:=Round(CBTitleAngle.Value);
end;

procedure TAxisEditor.CBTitleVisibleChange(Sender: TObject);
begin
  Axis.Title.Visible:=CBTitleVisible.IsChecked;
end;

procedure TAxisEditor.PageLabelsChange(Sender: TObject);
begin
  if (PageLabels.ActiveTab=TabLabFormat) and (not Assigned(ILabelsFormat)) then
     ILabelsFormat:=TTeeShapeEditor.InsertForm(Axis.Texts.Format,TabLabFormat)
  else
  if (PageLabels.ActiveTab=TabLabMargins) and (not Assigned(ILabelsMargins)) then
  begin
    ILabelsMargins:=TMarginsEditor.CreateEditor(Self,Axis.LabelsFormat.Margins);
    EmbeddForm(ILabelsMargins,TabLabMargins);
  end
  else
  if (PageLabels.ActiveTab=TabLabBack) and (not Assigned(IBack)) then
  begin
    IBack:=TTeeShapeEditor.InsertForm(Axis.Shape,TabLabBack);
    IBack.TabFont.Visible:=False;
  end;
end;

procedure TAxisEditor.CBLabelsChange(Sender: TObject);
begin
  Axis.Labels:=CBLabels.IsChecked;
end;

procedure TAxisEditor.CBLabelStyleChange(Sender: TObject);
begin
  Axis.LabelStyle:=TAxisLabelStyle(CBLabelStyle.ItemIndex);
end;

procedure TAxisEditor.CBLabelsPosChange(Sender: TObject);
begin
  Axis.Texts.Position:=TAxisLabelsPosition(CBLabelsPos.ItemIndex);
end;

procedure TAxisEditor.CBMultilineChange(Sender: TObject);
begin
  Axis.LabelsMultiLine:=CBMultiline.IsChecked;
end;

procedure TAxisEditor.CBOnAxisChange(Sender: TObject);
begin
  Axis.LabelsOnAxis:=CBOnAxis.IsChecked;
end;

procedure TAxisEditor.CBOtherSideChange(Sender: TObject);
begin
  Axis.OtherSide:=CBOtherSide.IsChecked;
end;

procedure TAxisEditor.CBRoundFirstChange(Sender: TObject);
begin
  Axis.RoundFirstLabel:=CBRoundFirst.IsChecked;
end;

procedure TAxisEditor.SetScaleEdit(const Value:Double; const AEdit:TEdit);
begin
  if Axis.IsDateTime then
  begin
    if ((Value > DTMinValue) and (Value < DTMaxValue)) then
         AEdit.Text:=DateTimeToStr(Value)
    else
         AEdit.Text:=TimeToStr(Value);
  end
  else
    AEdit.Text:=FormatFloat(Axis.AxisValuesFormat,Value);
end;

procedure TAxisEditor.TabControlGridChange(Sender: TObject);
begin
  if (TabControlGrid.ActiveTab=TabGridBorder) and (not Assigned(IGrid)) then
     IGrid:=TStrokeEditor.InsertForm(Axis.Grid,TabGridBorder)
  else
  if (TabControlGrid.ActiveTab=TabMinorGrid) and (not Assigned(IMinorGrid)) then
     IMinorGrid:=TStrokeEditor.InsertForm(Axis.MinorGrid,TabMinorGrid);
end;

procedure TAxisEditor.TabControlTicksChange(Sender: TObject);
begin
  if (TabControlTicks.ActiveTab=TabOuter) and (not Assigned(IOuter)) then
     IOuter:=TStrokeEditor.InsertForm(Axis.Ticks,TabOuter)
  else
  if (TabControlTicks.ActiveTab=TabInner) and (not Assigned(IInner)) then
     IInner:=TStrokeEditor.InsertForm(Axis.TicksInner,TabInner)
  else
  if (TabControlTicks.ActiveTab=TabMinor) and (not Assigned(IMinor)) then
     IMinor:=TStrokeEditor.InsertForm(Axis.MinorTicks,TabMinor);
end;

procedure TAxisEditor.SetAxisScales;
begin
  if Axis<>nil then
  with Axis do
  begin
    EIncrement.Text:=TAxisIncrement.GetIncrementText(Self,Increment,IsDateTime,ExactDateTime,AxisValuesFormat);

    EIncrement.Enabled:=not IsDateTime;

    CBAutoInc.IsChecked:=(Increment=0);
    CBAutoInc.Enabled:=not CBAutoInc.IsChecked;

    //TF02014321
    SetScaleEdit(Minimum,EAxisMin);
    SetScaleEdit(Maximum,EAxisMax);

    CBAutomatic.IsChecked:=Automatic;
    CBAutoMax.IsChecked:=AutomaticMaximum;
    CBAutoMin.IsChecked:=AutomaticMinimum;

    UDMaxOff.Value:=MaximumOffset;
    UDMinOff.Value:=MinimumOffset;

    CBMaxRound.IsChecked:=MaximumRound;
    CBMinRound.IsChecked:=MinimumRound;
    CBMaxRound.Enabled:=AutomaticMaximum;
    CBMinRound.Enabled:=AutomaticMinimum;

    CBLogarithmic.IsChecked:=Logarithmic;
    CBLogarithmic.Enabled:=not IsDepthAxis;

    LogE.IsChecked:=LogarithmicBase=Exp(1);
    ELogBase.Text:=FloatToStr(LogarithmicBase);

    EnableLogBaseControls;

    CBVisible.IsChecked:=Visible;
    CBInverted.IsChecked:=Inverted;

    CBShowAll.IsChecked:=LabelsSeparation=0;
  end;
end;

procedure TAxisEditor.RefreshAxis(const Axis: TChartAxis);

  function AxisIndex:Integer;
  var t: Integer;
  begin
    for t := 0 to LBAxes.Count-1 do
        if LBAxes.ItemByIndex(t).Data=Axis then
           Exit(t);

    result:=-1;
  end;

begin
  if LBAxes.Selected.Data<>Axis then
     LBAxes.ItemIndex:=AxisIndex;

  PageAxisChange(Self);

  BDelete.Enabled:=LBAxes.ItemIndex>=TeeInitialCustomAxis;
  CBVisible.IsChecked:=Axis.Visible;

  CBLabelAlign.IsChecked:=Axis.Texts.Align=alDefault;
  CBLabelAlign.Enabled:=(not Axis.Horizontal) and (not Axis.IsDepthAxis);

  CBLabelsPos.ItemIndex:=Ord(Axis.Texts.Position);
end;

procedure TAxisEditor.RGTitlePosChange(Sender: TObject);
begin
  Axis.Title.Position:=TAxisTitlePosition(RGTitlePos.ItemIndex);
end;

procedure TAxisEditor.CBAlternateChange(Sender: TObject);
begin
  Axis.Texts.Alternate:=CBAlternate.IsChecked;
end;

procedure TAxisEditor.CBAngleChange(Sender: TObject);
begin
  CBAngleChangeTracking(Self);
end;

procedure TAxisEditor.CBAngleChangeTracking(Sender: TObject);
begin
  if Axis<>nil then
     Axis.Texts.Angle:=Round(CBAngle.Value);
end;

procedure TAxisEditor.CBLabelsBehindChange(Sender: TObject);
begin
  Axis.Texts.Behind:=CBLabelsBehind.IsChecked;
end;

procedure TAxisEditor.CBFormatChange(Sender: TObject);
begin
  if Axis.IsDateTime then Axis.DateTimeFormat:=CBFormat.Text
                     else Axis.AxisValuesFormat:=LocalToDelphiFormat(CBFormat.Text);
end;

procedure TAxisEditor.CBExpoChange(Sender: TObject);
begin
  Axis.Texts.Exponent:=CBExpo.IsChecked;
end;

procedure TAxisEditor.CBLabelAlignChange(Sender: TObject);
begin
  if CBLabelAlign.IsChecked then
     Axis.Texts.Align:=alDefault
  else
     Axis.Texts.Align:=alOpposite;
end;

procedure TAxisEditor.Button1Click(Sender: TObject);
begin
  CBFormat.Text:=TFormatEditor.Change(Self,CBFormat.Text,Axis.IsDateTime);
  CBFormatChange(Self);
end;

procedure TAxisEditor.CBTickOnLabelsChange(Sender: TObject);
begin
  Axis.TickOnLabelsOnly:=CBTickOnLabels.IsChecked;
end;

procedure TAxisEditor.CBGridCenteredChange(Sender: TObject);
begin
  Axis.GridCentered:=CBGridCentered.IsChecked;
end;

procedure TAxisEditor.CBHorizAxisChange(Sender: TObject);
begin
  Axis.Horizontal:=CBHorizAxis.IsChecked;
end;

procedure FillAxesList(const Axes:TChartAxes; const AList:TCustomListBox; AddDepth:Boolean);

  procedure Add(const Axis:TChartAxis; const AText:String);
  var tmp : TListBoxItem;
  begin
    tmp:=TListBoxItem.Create(AList.Owner);
    tmp.Text:=AText;
    tmp.Data:=Axis;

    AList.AddObject(tmp);
  end;

var t : Integer;
begin
  while AList.Count>0 do
        AList.ItemByIndex(0).DisposeOf;

  Add(Axes.Bottom, TeeMsg_BottomAxis);
  Add(Axes.Top, TeeMsg_TopAxis);
  Add(Axes.Left, TeeMsg_LeftAxis);
  Add(Axes.Right, TeeMsg_RightAxis);

  if AddDepth then
  begin
    Add(Axes.Depth, TeeMsg_DepthAxis);
    Add(Axes.DepthTop, TeeMsg_DepthTopAxis);
  end;

  for t:=TeeInitialCustomAxis to Axes.Count-1 do
      if Axes[t].Title.Caption='' then
         Add(Axes[t],TeeMsg_CustomAxesEditor+IntToStr(t-TeeInitialCustomAxis))
      else
         Add(Axes[t],Axes[t].Title.Caption);
end;

procedure TAxisEditor.FormCreate(Sender: TObject);
begin
  PageAxis.ActiveTab:=TabScales;
  PageScales.ActiveTab:=TabOptions;

  {$IFDEF TEELITEEMB}
  PanelCustomAxes.Visible:=False;
  {$ENDIF}

  {$IFDEF TEELITE}
  TabItems.Visible:=False;
  {$ENDIF}
end;

procedure TAxisEditor.RefreshAxes(const AAxes:TChartAxes);
begin
  Axes:=AAxes;

  CBShow.IsChecked:=Axes.Visible;
  CBAxisBeh.IsChecked:=Axes.Behind;

  FillAxesList(Axes,LBAxes,True);

  LBAxes.ItemIndex:=0;
end;

class function TAxisEditor.CreateEditor(const AOwner: TComponent; const AAxes: TChartAxes):TAxisEditor;
begin
  result:=TAxisEditor.Create(AOwner);
  result.RefreshAxes(AAxes);
end;

procedure TAxisEditor.CBPosUnitsChange(Sender: TObject);
begin
  Axis.PositionUnits:=TTeeUnits(CBPosUnits.ItemIndex);
end;

procedure TAxisEditor.ListItemsChange(Sender: TObject);
begin
  if ListItems.ItemIndex<>-1 then
  with Axis.Items[ListItems.ItemIndex] do
  begin
    EItemValue.Text:=FloatToStr(Value);
    AxisItemText.Text:=Text;
  end;

  EItemValue.Enabled:=ListItems.ItemIndex<>-1;
  ButtonFormat.Enabled:=EItemValue.Enabled;
end;

procedure TAxisEditor.EAxisMaxChangeTracking(Sender: TObject);
begin
  Axis.Maximum:=StrToFloatDef(EAxisMax.Text,Axis.Maximum);
end;

procedure TAxisEditor.EAxisMinChangeTracking(Sender: TObject);
begin
  Axis.Minimum:=StrToFloatDef(EAxisMin.Text,Axis.Minimum);
end;

procedure TAxisEditor.EIncrementChangeTracking(Sender: TObject);
begin
  Axis.Increment:=StrToFloatDef(EIncrement.Text,Axis.Increment);

  CBAutoInc.IsChecked:=Axis.Increment=0;
  CBAutoInc.Enabled:=not CBAutoInc.IsChecked;
end;

procedure TAxisEditor.EItemValueTyping(Sender: TObject);
begin
  if ListItems.ItemIndex<>-1 then
     Axis.Items[ListItems.ItemIndex].Value:=StrToFloat(EItemValue.Text);
end;

procedure TAxisEditor.ELogBaseTyping(Sender: TObject);
begin
  Axis.LogarithmicBase:=StrToFloat(ELogBase.Text);
end;

procedure TAxisEditor.ButtonFormatClick(Sender: TObject);
begin
  TTeeShapeEditor.Edit(Self, Axis.Items[ListItems.ItemIndex].Format);
end;

function TAxisEditor.Axis: TChartAxis;
begin
  if LBAxes.ItemIndex=-1 then
     result:=nil
  else
     result:=LBAxes.Selected.Data as TChartAxis;
end;

procedure TAxisEditor.AxisItemTextChangeTracking(Sender: TObject);
begin
  if (Axis<>nil) and (ListItems.ItemIndex<>-1) then
     Axis.Items[ListItems.ItemIndex].Text:=AxisItemText.Text;
end;

procedure TAxisEditor.CBItemsAutoChange(Sender: TObject);
begin
  Axis.Items.Automatic:=CBItemsAuto.IsChecked;

  PanelItems.Enabled:=not CBItemsAuto.IsChecked;
  ListItems.Enabled:=PanelItems.Enabled;

  ListItemsChange(Self);
end;

Procedure TAxisEditor.SetAxisIndex(const Axis:TChartAxis);
begin
  With Axis.ParentChart, LBAxes do
  if Axis=LeftAxis   then ItemIndex:=0 else
  if Axis=RightAxis  then ItemIndex:=1 else
  if Axis=TopAxis    then ItemIndex:=2 else
  if Axis=BottomAxis then ItemIndex:=3 else
  if Axis=DepthAxis  then ItemIndex:=4 else
  if Axis=DepthTopAxis then ItemIndex:=5 else
     ItemIndex:=Axes.IndexOf(Axis);
end;

procedure TAxisEditor.BAddClick(Sender: TObject);
var tmpAxis : TChartAxis;
begin
  tmpAxis:=TChartAxis.Create(Axis.ParentChart.CustomAxes);

  FillAxesList(Axes,LBAxes,True);
  SetAxisIndex(tmpAxis);

  PageAxisChange(Self);
end;

procedure TAxisEditor.BDeleteClick(Sender: TObject);
var tmp : Integer;
begin
  Axis.DisposeOf;

  With LBAxes do
  begin
    tmp:=ItemIndex;
    Items.Delete(tmp);
    ItemIndex:=tmp-1;
  end;

  LBAxesChange(Self);
end;

procedure TAxisEditor.CBShowChange(Sender: TObject);
begin
  Axes.Visible:=CBShow.IsChecked;
end;

procedure TAxisEditor.CBAxisBehChange(Sender: TObject);
begin
  Axes.Behind:=CBAxisBeh.IsChecked;
end;

procedure TAxisEditor.LBAxesChange(Sender: TObject);
begin
  if Axis<>nil then
     RefreshAxis(Axis);
end;

end.
