unit FMXTee.Editor.Series.Contour;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs, FMXTee.Chart.ListBox,
  FMX.TabControl, FMXTee.Series.Surface, FMX.Edit, FMX.ListBox, FMX.Colors,
  FMX.Layouts, FMX.Grid, FMXTee.Chart.Grid, FMXTee.Editor.Series.Pointer;

type
  TContourSeriesEditor = class(TForm)
    TabControl1: TTabControl;
    TabOptions: TTabItem;
    CBSmooth: TCheckBox;
    BPen: TButton;
    BFrame: TButton;
    UDContourTransp: TSpinBox;
    Label6: TLabel;
    TabGrid3D: TTabItem;
    BCellPen: TButton;
    CBColorEach: TCheckBox;
    CBInterpolate: TCheckBox;
    CBFill: TCheckBox;
    TabLevels: TTabItem;
    TabMarks: TTabItem;
    TabPointer: TTabItem;
    TabPosition: TTabItem;
    CBAutoLevels: TCheckBox;
    GroupBox1: TGroupBox;
    UDNum: TSpinBox;
    Label1: TLabel;
    UDLevel: TSpinBox;
    Label2: TLabel;
    EText: TEdit;
    EValue: TEdit;
    Label3: TLabel;
    Label4: TLabel;
    BLevelPen: TButton;
    BLevelColor: TButton;
    CBEmpty: TCheckBox;
    CBDefaultPen: TCheckBox;
    Label5: TLabel;
    LSegmentCount: TLabel;
    UDDensity: TSpinBox;
    Label7: TLabel;
    UDMargin: TSpinBox;
    Label8: TLabel;
    CBMarks: TCheckBox;
    CBMarksColor: TCheckBox;
    CBMarksSegments: TCheckBox;
    CBOverlap: TCheckBox;
    CBYPosLevel: TCheckBox;
    SEYPos: TEdit;
    Label9: TLabel;
    CBBottom: TCheckBox;
    BMarksColor: TColorComboBox;
    procedure FormActivate(Sender: TObject);
    procedure CBSmoothChange(Sender: TObject);
    procedure BPenClick(Sender: TObject);
    procedure BFrameClick(Sender: TObject);
    procedure UDContourTranspChange(Sender: TObject);
    procedure BCellPenClick(Sender: TObject);
    procedure CBInterpolateChange(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure CBColorEachChange(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure BLevelPenClick(Sender: TObject);
    procedure UDNumChange(Sender: TObject);
    procedure CBYPosLevelChange(Sender: TObject);
    procedure SEYPosChange(Sender: TObject);
    procedure CBAutoLevelsChange(Sender: TObject);
    procedure BLevelColorClick(Sender: TObject);
    procedure CBEmptyChange(Sender: TObject);
    procedure UDLevelChange(Sender: TObject);
    procedure ETextChange(Sender: TObject);
    procedure CBDefaultPenChange(Sender: TObject);
    procedure CBFillChange(Sender: TObject);
    procedure CBMarksColorChange(Sender: TObject);
    procedure CBMarksSegmentsChange(Sender: TObject);
    procedure UDDensityChange(Sender: TObject);
    procedure UDMarginChange(Sender: TObject);
    procedure CBMarksChange(Sender: TObject);
    procedure CBBottomChange(Sender: TObject);
    procedure CBOverlapChange(Sender: TObject);
    procedure EValueChange(Sender: TObject);
  private
    { Private declarations }
    CreatingForm : Boolean;
    Grid3DForm   : TCustomForm;
    Contour      : TContourSeries;

    procedure CheckBottom;
    procedure DoCreateAutoLevels;
    function Level:TContourLevel;
    procedure SetLevel;
    function VisualColor:TAlphaColor;
  public
    { Public declarations }
  end;

implementation

{$R *.fmx}

uses
  FMXTee.Editor.Stroke, FMXTee.Editor.Series, FMXTee.Editor.Series.Grid,
  FMXTee.Engine, FMXTee.Procs, FMXTee.Canvas;

procedure TContourSeriesEditor.CheckBottom;
begin
  CBBottom.IsChecked:=Contour.YPosition=Contour.MinYValue;
  CBBottom.Enabled:=not CBBottom.IsChecked;
end;

procedure TContourSeriesEditor.DoCreateAutoLevels;
begin
  if Contour.AutomaticLevels then
     Contour.CreateAutoLevels;
end;

procedure TContourSeriesEditor.ETextChange(Sender: TObject);
begin
  if Assigned(Contour) and not CreatingForm then
  if EValue.Enabled then
  begin
    Level.UpToValue:=StrToFloat(EValue.Text);
    CBAutoLevels.IsChecked:=Contour.AutomaticLevels;
  end;
end;

procedure TContourSeriesEditor.EValueChange(Sender: TObject);
begin
  if not CreatingForm and Assigned(Contour) then
  if EText.Enabled then
  begin
    Level.Text:=EText.Text;
  end;
end;

function TContourSeriesEditor.Level:TContourLevel;
begin
  result:=Contour.Levels[Round(UDLevel.Value)];
end;

procedure TContourSeriesEditor.SetLevel;
var OldCreating : Boolean;
    tmp         : TColor;
    tmpOk       : Boolean;
begin
  OldCreating:=CreatingForm;
  CreatingForm:=True;

  tmpOk:=Contour.Levels.Count>UDLevel.Value;

  EnableControls(tmpOk, [UDLevel, EValue, BLevelPen,
                         BLevelColor, CBDefaultPen, EText]);

  if tmpOk then
  With Level do
  begin
    tmp:=VisualColor;
    CBEmpty.IsChecked:=tmp=clNone;

    EValue.Text:=FormatFloat('0.###',UpToValue); // Do not localize

    EText.Text:=Text;

    cbDefaultPen.IsChecked:=DefaultPen;
    BLevelPen.Enabled     :=not DefaultPen;

    LSegmentCount.Text:=IntToStr(SegmentCount);
  end;

  CreatingForm:=OldCreating;
end;

procedure TContourSeriesEditor.SEYPosChange(Sender: TObject);
begin
  if not CreatingForm and Assigned(Contour) then
  begin
    Contour.YPosition:=StrToFloatDef(SEYPos.Text,Contour.YPosition);
    CheckBottom;
  end;
end;

function TContourSeriesEditor.VisualColor:TAlphaColor;
begin
 result:=Level.Color;

 if result=clTeeColor then
    if Assigned(Contour.ParentChart) then
       result:=Contour.ParentChart.GetDefaultColor(Round(UDLevel.Value)) // 7.04
    else
       result:=TColorRec.White;
end;

procedure TContourSeriesEditor.CBAutoLevelsChange(Sender: TObject);
begin
  if not CreatingForm and Assigned(Contour) then
  begin
    Contour.AutomaticLevels:=CBAutoLevels.IsChecked;
    DoCreateAutoLevels;
    EnableControls(Contour.AutomaticLevels,[UDNum,CBColorEach]);
    SetLevel;
  end;
end;

procedure TContourSeriesEditor.CBBottomChange(Sender: TObject);
begin
  if Assigned(Contour) then
  begin
    Contour.YPosition:=Contour.MinYValue;
    CBBottom.Enabled:=False;
  end;
end;

procedure TContourSeriesEditor.CBColorEachChange(Sender: TObject);
begin
  if not CreatingForm and assigned(Contour) then
  begin
    Contour.ColorEachPoint:=CBColorEach.IsChecked;
    Contour.CreateAutoLevels;
    SetLevel;
  end;
end;

procedure TContourSeriesEditor.CBDefaultPenChange(Sender: TObject);
begin
  if not CreatingForm and Assigned(Contour) then
  begin
    BLevelPen.Enabled:=not CBDefaultPen.IsChecked;

    if CBDefaultPen.IsChecked then
      Level.Pen:=nil;
  end;
end;

procedure TContourSeriesEditor.CBEmptyChange(Sender: TObject);
begin
  if Assigned(Contour) then
  begin
    if CBEmpty.IsChecked then
       Level.Color:=clNone
    else
    if Level.Color=clNone then
       Level.Color:=clTeeColor;

    Level.Pen.Color:=Level.Color;
  end;
end;

procedure TContourSeriesEditor.CBFillChange(Sender: TObject);
begin
  if not CreatingForm and Assigned(Contour) then
  begin
    if CBFill.IsChecked then
       Contour.Brush.Style:=bsSolid
    else
       Contour.Brush.Style:=bsClear;

    Contour.Brush.Image:=nil;
  end;
end;

procedure TContourSeriesEditor.CBInterpolateChange(Sender: TObject);
begin
  if assigned(Contour) then
    Contour.Smoothing.Interpolate:=CBInterpolate.IsChecked;
end;

procedure TContourSeriesEditor.CBMarksChange(Sender: TObject);
begin
  if Assigned(Contour) then
    Contour.Marks.Visible:=CBMarks.IsChecked;
end;

procedure TContourSeriesEditor.CBMarksColorChange(Sender: TObject);
begin
  if Assigned(Contour) then
  begin
    Contour.ContourMarks.ColorLevel:=CBMarksColor.IsChecked;
    BMarksColor.Enabled:=not Contour.ContourMarks.ColorLevel;
  end;
end;

procedure TContourSeriesEditor.CBMarksSegmentsChange(Sender: TObject);
begin
  if Assigned(Contour) then
    Contour.ContourMarks.AtSegments:=CBMarksSegments.IsChecked;
end;

procedure TContourSeriesEditor.CBOverlapChange(Sender: TObject);
begin
  if Assigned(Contour) then
    Contour.ContourMarks.AntiOverlap:=CBOverlap.IsChecked;
end;

procedure TContourSeriesEditor.CBSmoothChange(Sender: TObject);
begin
  if assigned(Contour) then
  begin
    Contour.Smoothing.Active:=CBSmooth.IsChecked;
    CBInterpolate.Enabled:=CBSmooth.IsChecked;
  end;
end;

procedure TContourSeriesEditor.CBYPosLevelChange(Sender: TObject);
begin
  if Assigned(Contour) then
  begin
    Contour.YPositionLevel:=CBYPosLevel.IsChecked;
    SEYPos.Enabled:=not CBYPosLevel.IsChecked;
  end;
end;

procedure TContourSeriesEditor.BFrameClick(Sender: TObject);
begin
  if Assigned (Contour) then
    TStrokeEditor.Edit(Self, Contour.Frame)
end;

procedure TContourSeriesEditor.BLevelColorClick(Sender: TObject);
  var tmp : TColor;
begin
  if BLevelColor.Enabled then
  With Level do
  begin
    tmp:=Color;

    if EditColorDialog(Self,tmp) then
    begin
      Color:=tmp;

      if not DefaultPen then
        Pen.Color:=Color;

      CBEmpty.IsChecked:=Color=clNone;
    end;
  end;

  CBAutoLevels.IsChecked:=Contour.AutomaticLevels;
end;

procedure TContourSeriesEditor.BLevelPenClick(Sender: TObject);
begin
  if Assigned (Contour) and BLevelPen.Enabled and (Contour.Levels.Count>UDLevel.Value) then
  with Level do
  if TStrokeEditor.Edit(Self, Pen) then
  begin
    CBDefaultPen.IsChecked:=DefaultPen;
    Color:=Level.Pen.Color;
  end;
end;

procedure TContourSeriesEditor.BPenClick(Sender: TObject);
begin
  if Assigned(Contour) then
    TStrokeEditor.Edit(Self, Contour.Pen);
end;

procedure TContourSeriesEditor.BCellPenClick(Sender: TObject);
begin
  if Assigned(Contour) then
    TStrokeEditor.Edit(Self, Contour.CellPen);
end;

procedure TContourSeriesEditor.FormActivate(Sender: TObject);
begin
  if not Assigned(Contour) then
  begin
    Contour:=TContourSeries(TagObject);

    if Assigned(Contour) then
    With Contour do
    begin
      CBColorEach.IsChecked :=ColorEachPoint;
      CBYPosLevel.IsChecked :=YPositionLevel;
      SEYPos.Enabled        :=not YPositionLevel;
      SEYPos.Text           :=FloatToStr(YPosition);

      CheckBottom;

      CBAutoLevels.IsChecked:=AutomaticLevels;
      UDNum.Value           :=NumLevels;

      UDLevel.Max           :=NumLevels-1;

      CBSmooth.IsChecked     :=Smoothing.Active;
      CBInterpolate.IsChecked:=Smoothing.Interpolate;
      CBInterpolate.Enabled  :=Smoothing.Active;
      CBFill.IsChecked       :=Brush.Style<>TBrushKind.bkNone;

      with ContourMarks do
      begin
        CBMarks.IsChecked        :=Visible;
        CBMarksSegments.IsChecked:=AtSegments;
        CBMarksColor.IsChecked   :=ColorLevel;
        UDDensity.Value          :=Density;
        UDMargin.Value           :=Margin;
        CBOverlap.IsChecked      :=AntiOverlap;
      end;

      UDContourTransp.Value:=Transparency;

      BMarksColor.Color  :=Contour.Marks.Font.Color;
      BMarksColor.Enabled:=not ContourMarks.ColorLevel;

      EnableControls(AutomaticLevels,[UDNum,CBColorEach]);

      EmbeddForm(TSeriesPointerEditor.CreateEditor(Self, Pointer),TabPointer);
      TabPointer.Visible:=False;  //Pointer editor disabled for now
    end;

    TGrid3DSeriesEditor.CreateEmbedd(Self,Contour,TabGrid3D);
  end;
  CreatingForm:=False;
end;

procedure TContourSeriesEditor.FormCreate(Sender: TObject);
begin
  CreatingForm:=True;
end;

procedure TContourSeriesEditor.FormDestroy(Sender: TObject);
begin
  FreeAndNil(Grid3DForm);
end;

procedure TContourSeriesEditor.UDContourTranspChange(Sender: TObject);
begin
  if Assigned(Contour) then
    Contour.Transparency:=Round(UDContourTransp.Value);
end;

procedure TContourSeriesEditor.UDDensityChange(Sender: TObject);
begin
  if Assigned(Contour) then
     Contour.ContourMarks.Density:=Round(UDDensity.Value);
end;

procedure TContourSeriesEditor.UDLevelChange(Sender: TObject);
begin
  if Assigned(Contour) and not CreatingForm and (Contour.Levels.Count>0) then
     SetLevel;
end;

procedure TContourSeriesEditor.UDMarginChange(Sender: TObject);
begin
  if Assigned(Contour) then
     Contour.ContourMarks.Margin:=Round(UDMargin.Value);
end;

procedure TContourSeriesEditor.UDNumChange(Sender: TObject);
begin
  if not CreatingForm and Assigned(Contour) then
  begin
    Contour.NumLevels:=Round(UDNum.Value);
    DoCreateAutoLevels;

    With UDLevel do
    begin
      Max:=Contour.NumLevels-1;
      UDLevel.Value:=Value;
      SetLevel;
    end;
  end;
end;

initialization
  RegisterSeriesEditor(TContourSeriesEditor);
end.
