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

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  System.Generics.Collections, 
  FMX.Types, FMX.Controls, FMX.Forms,
  {$IFNDEF UPTOXE3}
  FMX.StdCtrls,
  {$ENDIF}
  {$IFDEF D21}
  FMX.SpinBox,
  {$ENDIF}
  FMX.ListBox, FMX.Edit, FMX.Dialogs, FMX.TabControl, FMXTee.Engine,
  FMXTee.Series, FMX.Layouts, FMXTee.Chart.GalleryPanel,
  FMXTee.Editor.Gradient, FMXTee.Editor.Stroke, FMXTee.Editor.Brush,
  FMXTee.Editor.Shadow;

type
  TSeriesPointerEditor = class(TForm)
    PanelBottom: TPanel;
    Panel1: TPanel;
    Button1: TButton;
    PageControl1: TTabControl;
    TabFormat: TTabItem;
    LTransp: TLabel;
    CBDrawPoint: TCheckBox;
    CB3dPoint: TCheckBox;
    CBPoDark: TCheckBox;
    CBColorEach: TCheckBox;
    CBIgnoreNulls: TCheckBox;
    TBTransp: TTrackBar;
    TabSize: TTabItem;
    Label1: TLabel;
    Label2: TLabel;
    Label4: TLabel;
    UDPointHorizSize: TSpinBox;
    UDPointVertSize: TSpinBox;
    UDPointDepth: TSpinBox;
    CBInflate: TCheckBox;
    TabStyle: TTabItem;
    TabPattern: TTabItem;
    TabBorder: TTabItem;
    TabShadow: TTabItem;
    TabEmboss: TTabItem;
    Panel2: TPanel;
    CBDefBrushColor: TCheckBox;
    Panel3: TPanel;
    Label3: TLabel;
    CBStyle: TComboBox;
    ListBoxItem1: TListBoxItem;
    ListBoxItem2: TListBoxItem;
    ListBoxItem3: TListBoxItem;
    ListBoxItem4: TListBoxItem;
    ListBoxItem5: TListBoxItem;
    ListBoxItem6: TListBoxItem;
    ListBoxItem7: TListBoxItem;
    ListBoxItem8: TListBoxItem;
    ListBoxItem9: TListBoxItem;
    ListBoxItem10: TListBoxItem;
    ListBoxItem11: TListBoxItem;
    ListBoxItem12: TListBoxItem;
    ListBoxItem13: TListBoxItem;
    ListBoxItem14: TListBoxItem;
    StyleGallery: TChartGalleryPanel;
    ListBoxItem15: TListBoxItem;
    Label5: TLabel;
    SBSize: TSpinBox;
    ListBoxItem16: TListBoxItem;
    procedure FormCreate(Sender: TObject);
    procedure CBStyleChange(Sender: TObject);
    procedure TBTranspChange(Sender: TObject);
    procedure CBDrawPointChange(Sender: TObject);
    procedure CB3dPointChange(Sender: TObject);
    procedure CBColorEachChange(Sender: TObject);
    procedure CBIgnoreNullsChange(Sender: TObject);
    procedure CBInflateChange(Sender: TObject);
    procedure CBPoDarkChange(Sender: TObject);
    procedure CBDefBrushColorChange(Sender: TObject);
    procedure UDPointDepthChangeTracking(Sender: TObject);
    procedure UDPointVertSizeChangeTracking(Sender: TObject);
    procedure UDPointHorizSizeChangeTracking(Sender: TObject);
    procedure FormActivate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure PageControl1Change(Sender: TObject);
    procedure StyleGalleryChangeChart(Sender: TObject);
    procedure StyleGalleryResize(Sender: TObject);
    procedure SBSizeChange(Sender: TObject);
  private
   { Private declarations }
    Pointer : TSeriesPointer;

    IPatternEditor : TBrushEditor;
    IBorderEditor  : TStrokeEditor;
    IShadowEditor,
    IEmbossEditor  : TShadowEditor;

    ISelecting : Boolean;

    Procedure CheckDefColor;
    function CustomSeries:TCustomLineSeries;
    procedure RefreshPointer(const APointer:TSeriesPointer);
  public
   { Public declarations }
    class function CreateEditor(const AOwner:TComponent; const APointer:TSeriesPointer):TForm;
    class function Edit(const AOwner:TComponent; const APointer:TSeriesPointer):Boolean;
    procedure HideSizeOptions;
    class function InsertForm(const APointer:TSeriesPointer; const AParent:TControl):TSeriesPointerEditor;
  end;

implementation

{$R *.fmx}

uses
  {$IFDEF D17}
  System.UIConsts,
  {$ENDIF}
  FMXTee.Canvas, FMXTee.Procs;

procedure TSeriesPointerEditor.FormActivate(Sender: TObject);
begin
  if (not Assigned(Pointer)) and Assigned(TagObject) and (CustomSeries<>TagObject) then
     RefreshPointer(TCustomSeries(TagObject).Pointer);
end;

procedure TSeriesPointerEditor.FormCreate(Sender: TObject);
begin
  PageControl1.ActiveTab:=TabFormat;
end;

procedure TSeriesPointerEditor.HideSizeOptions;
begin
  Label1.Visible:=False;
  UDPointHorizSize.Visible:=False;
  Label2.Visible:=False;
  UDPointVertSize.Visible:=False;
end;

class function TSeriesPointerEditor.InsertForm(const APointer: TSeriesPointer;
  const AParent: TControl): TSeriesPointerEditor;
begin
  result:=TSeriesPointerEditor.CreateEditor(AParent.Owner, APointer) as TSeriesPointerEditor;
  EmbeddForm(result,AParent);
end;

procedure TSeriesPointerEditor.PageControl1Change(Sender: TObject);

  procedure CreateStyleGallery;
  var t : Integer;
      tmp : TGalleryChart;
      tmpColor : TColor;
  begin
    for t:=0 to CBStyle.Items.Count-1 do
    begin
      tmp:=TGalleryChart.Create(StyleGallery);
      tmp.AddSeries(TPointSeries).Add(0);

      tmp.View3DOptions.Orthogonal:=True;

      tmp.Axes.Hide;
      tmp.Walls.Hide;

      TPointSeries(tmp[0]).Pointer.Style:=TSeriesPointerStyle(t);
      TPointSeries(tmp[0]).Pointer.Size:=14;

      tmpColor:=Pointer.Color;
      if tmpColor=clDefault then
         tmpColor:=Pointer.ParentSeries.Color;

      TPointSeries(tmp[0]).Pointer.Color:=tmpColor;

      tmp.Title.Caption:=CBStyle.Items[t];

      StyleGallery.Charts.Add(tmp);
      tmp.Parent:=StyleGallery;
      StyleGallery.FinishAdd(tmp);
    end;

    StyleGallery.ResizeCharts;

    CBStyleChange(Self);
  end;

begin
  if not Assigned(Pointer) then
     Exit;

  if (PageControl1.ActiveTab=TabPattern) and (not Assigned(IPatternEditor)) then
     IPatternEditor:=TBrushEditor.InsertForm(Pointer.Brush,TabPattern)
  else
  if PageControl1.ActiveTab=TabStyle then
  begin
    if StyleGallery.Charts.Count=0 then
       CreateStyleGallery
    else
       CBStyle.Repaint;
  end
  else
  if (PageControl1.ActiveTab=TabBorder) and (not Assigned(IBorderEditor)) then
     IBorderEditor:=TStrokeEditor.InsertForm(Pointer.Pen,TabBorder)
  else
  if PageControl1.ActiveTab=TabFormat then
     CheckDefColor
  else
  if (PageControl1.ActiveTab=TabShadow) and (not Assigned(IShadowEditor)) then
     IShadowEditor:=TShadowEditor.InsertForm(Pointer.Shadow,TabShadow)
  else
  if (PageControl1.ActiveTab=TabEmboss) and (not Assigned(IEmbossEditor)) then
     IEmbossEditor:=TShadowEditor.InsertForm(Pointer.Emboss,TabEmboss)
end;

function TSeriesPointerEditor.CustomSeries:TCustomLineSeries;
begin
  if Assigned(Pointer) and (Pointer.ParentSeries is TCustomLineSeries) then
     result:=TCustomLineSeries(Pointer.ParentSeries)
  else
     result:=nil;
end;

procedure TSeriesPointerEditor.RefreshPointer(const APointer: TSeriesPointer);
begin
  Pointer:=APointer;

  CBDrawPoint.IsChecked:=Pointer.Visible;
  CB3dPoint.IsChecked:=Pointer.Draw3D;
  CBStyle.ItemIndex:=Ord(Pointer.Style);
  CBPoDark.IsChecked:=Pointer.Dark3D;

  CBColorEach.Enabled:=Assigned(Pointer.ParentSeries);

  if CBColorEach.Enabled then
     CBColorEach.IsChecked:=Pointer.ParentSeries.ColorEachPoint;

  CBIgnoreNulls.Enabled:=(CustomSeries<>nil);

  if CBIgnoreNulls.Enabled then
     CBIgnoreNulls.IsChecked:=CustomSeries.TreatNulls=tnIgnore;

  CBInflate.IsChecked:=Pointer.InflateMargins;

  TBTransp.Value:=Pointer.Transparency;

  CheckDefColor;

  ISelecting:=True;

  SBSize.Value:=Pointer.Size;
  UDPointHorizSize.Value:=Pointer.HorizSize;
  UDPointVertSize.Value:=Pointer.VertSize;
  UDPointDepth.Value:=Pointer.Depth;

  ISelecting:=False;
end;

procedure TSeriesPointerEditor.SBSizeChange(Sender: TObject);
begin
  if (not ISelecting) and (Pointer.Size<>Round(SBSize.Value)) then
  begin
    Pointer.Size:=Round(SBSize.Value);
    UDPointHorizSize.Value:=Pointer.Size;
    UDPointVertSize.Value:=Pointer.Size;
  end;
end;

procedure TSeriesPointerEditor.StyleGalleryChangeChart(Sender: TObject);
begin
  CBStyle.ItemIndex:=StyleGallery.Charts.IndexOf(StyleGallery.SelectedChart);
  CBStyleChange(Self);
end;

procedure TSeriesPointerEditor.StyleGalleryResize(Sender: TObject);
var tmp,t : Integer;
begin
  tmp:=Round(0.25*(StyleGallery.Width/StyleGallery.NumCols));

  for t:=0 to StyleGallery.Charts.Count-1 do
      TCustomSeries(StyleGallery.Charts[t].Series[0]).Pointer.Size:=tmp;
end;

procedure TSeriesPointerEditor.CBDrawPointChange(Sender: TObject);
begin
  Pointer.Visible:=CBDrawPoint.IsChecked;
end;

procedure TSeriesPointerEditor.CB3dPointChange(Sender: TObject);
begin
  Pointer.Draw3D:=CB3dPoint.IsChecked;
end;

procedure TSeriesPointerEditor.CBStyleChange(Sender: TObject);
begin
  if CBStyle.ItemIndex>-1 then
  begin
    Pointer.Style:=TSeriesPointerStyle(CBStyle.ItemIndex);

    //Enable3DPoint;

    if StyleGallery.Charts.Count>0 then
    begin
      ISelecting:=True;
      StyleGallery.SelectedChart:=StyleGallery.Charts[CBStyle.ItemIndex];
      ISelecting:=False;
    end;
  end;
end;

procedure TSeriesPointerEditor.CheckDefColor;
begin
  if Assigned(Pointer) then
     CBDefBrushColor.IsChecked:=(Pointer.Color=clTeeColor) and (Pointer.Pen.Color=clTeeColor);
end;

class function TSeriesPointerEditor.CreateEditor(const AOwner: TComponent;
  const APointer: TSeriesPointer): TForm;
begin
  result:=TSeriesPointerEditor.Create(AOwner);
  TSeriesPointerEditor(result).RefreshPointer(APointer);
end;

class function TSeriesPointerEditor.Edit(const AOwner: TComponent;
  const APointer: TSeriesPointer): Boolean;
begin
  with CreateEditor(AOwner, APointer) as TSeriesPointerEditor do
  try
    PanelBottom.Visible:=True;
    result:=ShowModal=mrOk;
  finally
    Free;
  end;
end;

procedure TSeriesPointerEditor.CBPoDarkChange(Sender: TObject);
begin
  Pointer.Dark3D:=CBPoDark.IsChecked;
end;

procedure TSeriesPointerEditor.CBColorEachChange(Sender: TObject);
begin
  Pointer.ParentSeries.ColorEachPoint:=CBColorEach.IsChecked;
end;

procedure TSeriesPointerEditor.CBIgnoreNullsChange(Sender: TObject);
begin
  if CBIgnoreNulls.IsChecked then
     CustomSeries.TreatNulls:=tnIgnore
  else
     CustomSeries.TreatNulls:=tnDontPaint;
end;

procedure TSeriesPointerEditor.Button1Click(Sender: TObject);
begin
  Close;
end;

procedure TSeriesPointerEditor.TBTranspChange(Sender: TObject);
begin
  Pointer.Transparency:=Round(TBTransp.Value);
end;

procedure TSeriesPointerEditor.UDPointDepthChangeTracking(Sender: TObject);
begin
  if Assigned(Pointer) and (not ISelecting) then
     Pointer.Depth:=Round(UDPointDepth.Value);
end;

procedure TSeriesPointerEditor.UDPointHorizSizeChangeTracking(Sender: TObject);
begin
  if Assigned(Pointer) and (not ISelecting) then
  begin
    Pointer.HorizSize:=Round(UDPointHorizSize.Value);

    if Pointer.HorizSize=Pointer.VertSize then
       SBSize.Value:=Pointer.Size;
  end;
end;

procedure TSeriesPointerEditor.UDPointVertSizeChangeTracking(Sender: TObject);
begin
  if Assigned(Pointer) and (not ISelecting) then
  begin
     Pointer.VertSize:=Round(UDPointVertSize.Value);

     if Pointer.HorizSize=Pointer.VertSize then
        SBSize.Value:=Pointer.Size;
  end;
end;

procedure TSeriesPointerEditor.CBDefBrushColorChange(Sender: TObject);
begin
  if CBDefBrushColor.IsChecked then
  begin
    Pointer.Color:=clTeeColor;
    Pointer.Pen.Color:=clTeeColor;
  end
  else
  if Pointer.Pen.Color=clTeeColor then
     Pointer.Pen.Color:=claBlack;

  //BPoinPenCol.Repaint;
  CBStyle.Repaint;
end;

procedure TSeriesPointerEditor.CBInflateChange(Sender: TObject);
begin
  Pointer.InflateMargins:=CBInflate.IsChecked;
end;

initialization
  RegisterSeriesEditor(TSeriesPointerEditor); // <-- iOS exit?
end.
