{*********************************************}
{  TeeChart Charting Library for FireMonkey   }
{  Copyright (c) 2012 by Steema Software      }
{  All Rights Reserved                        }
{*********************************************}
unit FMXTee.Editor.Aspect;

interface

uses
  System.SysUtils, System.Types, System.Classes, System.Variants, FMX.Types,
  FMX.Controls, FMX.Forms,
  FMX.Edit, FMX.ListBox, FMX.Dialogs, FMX.Layouts, FMX.TabControl,
  FMXTee.Procs, FMXTee.Canvas, FMXTee.Chart.GalleryPanel;

type
  TFormTee3D = class(TForm)
    PageControl1: TTabControl;
    Tab3D: TTabItem;
    L13: TLabel;
    L4: TLabel;
    L35: TLabel;
    L36: TLabel;
    LZoom: TLabel;
    LRotation: TLabel;
    LElevation: TLabel;
    Label1: TLabel;
    LHOffset: TLabel;
    Label3: TLabel;
    LVOffset: TLabel;
    Label2: TLabel;
    LPerspec: TLabel;
    LabelOrtho: TLabel;
    LTextSize: TLabel;
    Label5: TLabel;
    CBView3d: TCheckBox;
    CBOrthogonal: TCheckBox;
    SBZoom: TTrackBar;
    UDTextSize: TSpinBox;
    CBZoomText: TComboBox;
    TabViews: TTabItem;
    TabRender: TTabItem;
    Splitter1: TSplitter;
    LBRender: TListBox;
    PanelRender: TPanel;
    PanelGDI: TPanel;
    CBBuffered: TCheckBox;
    SBRotation: TTrackBar;
    SBElevation: TTrackBar;
    SBHorizOffset: TTrackBar;
    SBVertOffset: TTrackBar;
    SBPerspec: TTrackBar;
    CBClipPoints: TCheckBox;
    UDOrthoAngle: TSpinBox;
    Percent3D: TSpinBox;
    procedure FormCreate(Sender: TObject);
    procedure PageControl1Change(Sender: TObject);
    procedure SBZoomChange(Sender: TObject);
    procedure SBRotationChange(Sender: TObject);
    procedure SBElevationChange(Sender: TObject);
    procedure SBPerspecChange(Sender: TObject);
    procedure CBZoomTextChange(Sender: TObject);
    procedure LBRenderClick(Sender: TObject);
    procedure CBView3dChange(Sender: TObject);
    procedure Percent3DChange(Sender: TObject);
    procedure CBOrthogonalChange(Sender: TObject);
    procedure CBClipPointsChange(Sender: TObject);
    procedure UDOrthoAngleChange(Sender: TObject);
    procedure SBHorizOffsetChange(Sender: TObject);
    procedure SBVertOffsetChange(Sender: TObject);
    procedure CBBufferedChange(Sender: TObject);
    procedure UDTextSizeChange(Sender: TObject);
    procedure Percent3DApplyResource(Sender: TObject);
  private
   { Private declarations }
    Panel : TCustomTeePanel;
    ChartGalleryPanel1: TChartGalleryPanel;
    IDepth : Single;

    procedure AddRenders;
    function AspectFloat(const Value:Single):String;
    procedure ChartGalleryPanel1ChangeChart(Sender: TObject);
    procedure CreateViewsGallery;
    procedure EnableControls;
    procedure RefreshPanel;
    procedure Select3DPanel(APanel:TCustomTeePanel);
    procedure SetGallery3DPanel(APanel: TCustomTeePanel);
    procedure SetView3D(AView:TView3DOptions);
  public
   { Public declarations }
    class function CreateEditor(AOwner:TComponent; APanel:TCustomTeePanel):TForm;
  end;

implementation

{$R *.fmx}

uses
  System.Math, FMXTee.Engine, FMXTee.Chart, FMXTee.Constants, FMX.Types3D,
  FMXTee.Editor.Stroke;

procedure TFormTee3D.FormCreate(Sender: TObject);
begin
  PageControl1.ActiveTab:=Tab3D;

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

procedure TFormTee3D.PageControl1Change(Sender: TObject);
begin
  if not Assigned(Panel) then
     Exit;

  if PageControl1.ActiveTab=TabViews then
  begin
    if not Assigned(ChartGalleryPanel1) then
       CreateViewsGallery;

    Select3DPanel(Panel);
  end
  else
  if PageControl1.ActiveTab=Tab3D then
     RefreshPanel;
end;

procedure TFormTee3D.Select3DPanel(APanel:TCustomTeePanel);
var t,tmp : Integer;
    tmpC  : TCustomChart;
begin
  tmp:=-1;

  with ChartGalleryPanel1 do
  begin
    for t:=0 to Charts.Count-1 do
    begin
      tmpC:=Charts[t];

      with tmpC do
      if (View3D=APanel.View3D) and
         (View3DOptions.Orthogonal=APanel.View3DOptions.Orthogonal) and
         (View3DOptions.OrthoAngle=APanel.View3DOptions.OrthoAngle) and
         (View3DOptions.Rotation=APanel.View3DOptions.Rotation) and
         (View3DOptions.Elevation=APanel.View3DOptions.Elevation) then
      begin
        tmp:=t;
        break;
      end;
    end;

    if tmp=-1 then SelectChart(nil)
              else SelectChart(Charts[tmp]);
  end;
end;

procedure TFormTee3D.SetGallery3DPanel(APanel:TCustomTeePanel);
begin
  with ChartGalleryPanel1 do
  if SelectedChart<>nil then
  with SelectedChart do
  begin
    APanel.View3D:=View3D;
    APanel.View3DOptions.Orthogonal:=View3DOptions.Orthogonal;
    APanel.View3DOptions.OrthoAngle:=View3DOptions.OrthoAngle;
    APanel.View3DOptions.Rotation:=View3DOptions.Rotation;
    APanel.View3DOptions.Elevation:=View3DOptions.Elevation;
  end;
end;

procedure TFormTee3D.CBView3dChange(Sender: TObject);
begin
  Panel.View3D:=CBView3d.IsChecked;

  EnableControls;
end;

function TFormTee3D.AspectFloat(const Value:Single):String;
begin
  result:=FormatFloat('0.##',Value);
end;

procedure TFormTee3D.SBHorizOffsetChange(Sender: TObject);
begin
  Panel.View3DOptions.HorizOffsetFloat:=SBHorizOffset.Value;

  if Panel.Parent is TControl3D then
     TControl3D(Panel.Parent).Position.X:=SBHorizOffset.Value*0.01;

  LHOffset.Text:=AspectFloat(SBHorizOffset.Value);
end;

procedure TFormTee3D.UDOrthoAngleChange(Sender: TObject);
begin
  Panel.View3DOptions.OrthoAngle:=Round(UDOrthoAngle.Value);
end;

procedure TFormTee3D.UDTextSizeChange(Sender: TObject);
begin
  if Assigned(Panel) then
  begin
    Panel.View3DOptions.FontZoom:=Max(1,Round(UDTextSize.Value));

    if Panel.Parent is TControl3D then
       Panel.Invalidate;
  end;
end;

procedure TFormTee3D.Percent3DApplyResource(Sender: TObject);
begin
  TStrokeEditor.SetRepeatClick(TSpinBox(Sender),True);
end;

procedure TFormTee3D.Percent3DChange(Sender: TObject);
begin
  TCustomAxisPanel(Panel).Chart3DPercent:=Round(Percent3D.Value);

  if Panel.Parent is TControl3D then
     TControl3D(Panel.Parent).Depth:=IDepth*Percent3D.Value*0.01;
end;

procedure TFormTee3D.CBOrthogonalChange(Sender: TObject);
begin
  Panel.View3DOptions.Orthogonal:=CBOrthogonal.IsChecked;
  EnableControls;
end;

procedure TFormTee3D.SBZoomChange(Sender: TObject);
begin
  Panel.View3DOptions.ZoomFloat:=SBZoom.Value;
  LZoom.Text:=AspectFloat(SBZoom.Value)+'%';  // Do not localize
end;

procedure TFormTee3D.SBRotationChange(Sender: TObject);
begin
  Panel.View3DOptions.RotationFloat:=SBRotation.Value;

  if Panel.Parent is TControl3D then
     TControl3D(Panel.Parent).RotationAngle.Y:=SBRotation.Value;

  LRotation.Text:=AspectFloat(SBRotation.Value);
end;

procedure TFormTee3D.SBElevationChange(Sender: TObject);
begin
  Panel.View3DOptions.ElevationFloat:=SBElevation.Value;

  if Panel.Parent is TControl3D then
     TControl3D(Panel.Parent).RotationAngle.X:=SBElevation.Value;

  LElevation.Text:=AspectFloat(SBElevation.Value);
end;

procedure TFormTee3D.SBVertOffsetChange(Sender: TObject);
begin
  Panel.View3DOptions.VertOffsetFloat:=SBVertOffset.Value;

  if Panel.Parent is TControl3D then
     TControl3D(Panel.Parent).Position.Y:=SBVertOffset.Value*0.01;

  LVOffset.Text:=AspectFloat(SBVertOffset.Value);
end;

procedure TFormTee3D.SBPerspecChange(Sender: TObject);
begin
  Panel.View3DOptions.Perspective:=Round(SBPerspec.Value);
  LPerspec.Text:=IntToStr(Panel.View3DOptions.Perspective);
end;

procedure TFormTee3D.SetView3D(AView:TView3DOptions);

  function FixAngle(const Angle:Single):Single;
  begin
    result:=Angle;
    while result>360 do result:=result-360;
    if result<0 then result:=360+result;
  end;

begin
  CBOrthogonal.IsChecked:=AView.Orthogonal;
  UDOrthoAngle.Value:=AView.OrthoAngle;
  UDTextSize.Value:=AView.FontZoom;
  CBZoomText.ItemIndex:=Ord(AView.ZoomText);
  SBZoom.Value:=AView.ZoomFloat;
  SBRotation.Value:=FixAngle(AView.RotationFloat);
  SBElevation.Value:=FixAngle(AView.ElevationFloat);
  SBHorizOffset.Value:=AView.HorizOffsetFloat;
  SBVertOffset.Value:=AView.VertOffsetFloat;
  SBPerspec.Value:=AView.Perspective;
end;

procedure TFormTee3D.RefreshPanel;
begin
  if Panel.Parent is TControl3D then
  begin
    SBElevation.Min:=0;
    IDepth:=TControl3D(Panel.Parent).Depth;
  end
  else
    IDepth:=0;

  CBView3d.IsChecked:=Panel.View3D;

  if Panel is TCustomAxisPanel then
  begin
    CBClipPoints.IsChecked:=TCustomAxisPanel(Panel).ClipPoints;
    Percent3D.Value:=TCustomAxisPanel(Panel).Chart3DPercent;
  end;

  SetView3D(Panel.View3DOptions);

  EnableControls;

  if Panel.Parent is TControl3D then
  begin
    CBOrthogonal.Visible:=False;
    LabelOrtho.Visible:=False;
    UDOrthoAngle.Visible:=False;
    SBPerspec.Visible:=False;
    LPerspec.Visible:=False;
    Label2.Visible:=False;
    L4.Visible:=False;
    LZoom.Visible:=False;
    SBZoom.Visible:=False;
  end;
end;

procedure TFormTee3D.EnableControls;
begin
  SBZoom.Enabled:=Panel.View3D;
  Percent3D.Enabled:=Panel.View3D;
  SBHorizOffset.Enabled:=Panel.View3D;
  SBVertOffset.Enabled:=Panel.View3D;
  CBOrthogonal.Enabled:=Panel.View3D;

  SBRotation.Enabled:=Panel.View3D and (not Panel.View3DOptions.Orthogonal);
  SBElevation.Enabled:=SBRotation.Enabled;
  SBPerspec.Enabled:=SBRotation.Enabled;

  UDOrthoAngle.Enabled:=Panel.View3DOptions.Orthogonal;
end;

class function TFormTee3D.CreateEditor(AOwner: TComponent; APanel: TCustomTeePanel):TForm;
begin
  result:=TFormTee3D.Create(AOwner);

  with TFormTee3D(result) do
  begin
    Panel:=APanel;

    AddRenders;
    RefreshPanel;
  end;
end;

procedure TFormTee3D.CreateViewsGallery;

  Function AddNewChart(const ATitle:String; Is3D:Boolean=False):TCustomChart;
  var t : Integer;
  begin
    result:=ChartGalleryPanel1.CreateChart(TeeSeriesTypes[0]) as TCustomChart;

    with result do
    begin
      Walls.Back.Transparent:=False;
      Walls.Size:=5;
      SeriesList.ClearValues;
      Title.Text[0]:=ATitle;

      if Is3D then
      begin
        View3D:=True;
        View3DOptions.Orthogonal:=False;

        for t:=0 to SeriesCount-1 do
            Series[t].VertAxis:=aBothVertAxis;

        View3DOptions.Elevation:=360;
        Axes.Left.Labels:=True;
      end;
    end;
  end;

var t : Integer;
begin
  ChartGalleryPanel1:=TChartGalleryPanel.Create(Self);
  ChartGalleryPanel1.Align:=TAlignLayout.alClient;
  TabViews.AddObject(ChartGalleryPanel1);
  ChartGalleryPanel1.OnChangeChart:=ChartGalleryPanel1ChangeChart;

  with ChartGalleryPanel1 do
  begin
    Smooth:=False;
    DisplaySub:=False;
    FocusRotation:=False;

    NumCols:=3;
    NumRows:=2;

    with AddNewChart(TeeMsg_View2D) do
    begin
      View3D:=False;
      Axes.Left.Labels:=True;
    end;

    with AddNewChart(TeeMsg_ViewOrthoRight) do
    begin
      View3DOptions.Orthogonal:=True;
      Axes.Left.Labels:=True;
    end;

    with AddNewChart(TeeMsg_ViewOrthoLeft) do
    begin
      View3DOptions.Orthogonal:=True;
      Walls.Left.Hide;
      Walls.Right.Visible:=True;

      for t:=0 to SeriesCount-1 do
          Series[t].VertAxis:=aRightAxis;

      Axes.Right.ZPosition:=0;
      View3DOptions.OrthoAngle:=135;
    end;

    with AddNewChart(TeeMsg_View3DFront,True) do
    begin
      Walls.Left.Visible:=True;
      Walls.Right.Visible:=True;
      Axes.Right.ZPosition:=0;
      View3DOptions.Rotation:=360;
    end;

    with AddNewChart(TeeMsg_View3DRight,True) do
    begin
      Walls.Left.Visible:=True;
      Walls.Right.Hide;
      Axes.Right.ZPosition:=100;
      View3DOptions.Rotation:=300;
    end;

    with AddNewChart(TeeMsg_View3DLeft,True) do
    begin
      Walls.Left.Hide;
      Walls.Right.Visible:=True;
      Axes.Right.ZPosition:=0;
      Axes.Left.ZPosition:=100;
      View3DOptions.Rotation:=45;
    end;
  end;
end;

procedure TFormTee3D.CBClipPointsChange(Sender: TObject);
begin
  TCustomAxisPanel(Panel).ClipPoints:=CBClipPoints.IsChecked;
end;

procedure TFormTee3D.AddRenders;
var item : TListBoxItem;
begin
  if Assigned(Panel.Canvas.ReferenceCanvas) then
  begin
    item:=TListBoxItem.Create(Self);
    item.Text:=Panel.Canvas.ReferenceCanvas.ClassName;
    item.Text:=Copy(item.Text,2,Length(item.Text));
    LBRender.AddObject(item);
  end;
end;

procedure TFormTee3D.CBZoomTextChange(Sender: TObject);
begin
  Panel.View3DOptions.ZoomText:=TCanvasZoomText(CBZoomText.ItemIndex);
  UDTextSize.Enabled:=Panel.View3DOptions.ZoomText=ztManual;

  if Panel.Parent is TControl3D then
     Panel.Invalidate;
end;

procedure TFormTee3D.ChartGalleryPanel1ChangeChart(Sender: TObject);
begin
  SetGallery3DPanel(Panel);
end;

procedure TFormTee3D.LBRenderClick(Sender: TObject);
begin
// TODO
end;

procedure TFormTee3D.CBBufferedChange(Sender: TObject);
begin
  Panel.Canvas.UseBuffer:=CBBuffered.IsChecked;
end;

end.
