{**********************************************}
{   TeeChart Pro 3D editor options             }
{   Copyright (c) 1999-2007 by Steema Software }
{**********************************************}
unit TeeEdi3D;
{$I TeeDefs.inc}

interface

uses {$IFNDEF LINUX}
     Windows, Messages,
     {$ENDIF}
     SysUtils, Classes,

     Graphics, Controls, Forms, Dialogs, StdCtrls, ComCtrls, ExtCtrls,

     TeePenDlg, TeeProcs, TeCanvas, TeEngine, Chart, TeeGalleryPanel;

type
  TFormTee3D = class(TForm)
    PageControl1: TPageControl;
    Tab3D: TTabSheet;
    TabViews: TTabSheet;
    L4: TLabel;
    LRot: TLabel;
    LElev: TLabel;
    LZoom: TLabel;
    LRotation: TLabel;
    LElevation: TLabel;
    Label1: TLabel;
    LHOffset: TLabel;
    Label3: TLabel;
    LVOffset: TLabel;
    Label2: TLabel;
    LPerspec: TLabel;
    Label4: TLabel;
    LTextSize: TLabel;
    CBView3d: TCheckBox;
    CBOrthogonal: TCheckBox;
    SBZoom: TTrackBar;
    SBRotation: TTrackBar;
    SBElevation: TTrackBar;
    SBHOffset: TTrackBar;
    SBVOffset: TTrackBar;
    SBPerspec: TTrackBar;
    EOrthoAngle: TEdit;
    UDOrthoAngle: TUpDown;
    CBClipPoints: TCheckBox;
    ETextSize: TEdit;
    UDTextSize: TUpDown;
    Views: TChartGalleryPanel;
    TabRender: TTabSheet;
    LBRender: TListBox;
    PanelRender: TPanel;
    PanelGDI: TPanel;
    CBBuffered: TCheckBox;
    Splitter1: TSplitter;
    CBZoomText: TComboFlat;
    Label5: TLabel;
    Label6: TLabel;
    CBTextQuality: TComboFlat;
    TB3D: TTrackBar;
    procedure CBOrthogonalClick(Sender: TObject);
    procedure SBZoomChange(Sender: TObject);
    procedure SBRotationChange(Sender: TObject);
    procedure SBElevationChange(Sender: TObject);
    procedure CBView3dClick(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure SBHOffsetChange(Sender: TObject);
    procedure SBVOffsetChange(Sender: TObject);
    procedure SBPerspecChange(Sender: TObject);
    procedure EOrthoAngleChange(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure CBClipPointsClick(Sender: TObject);
    procedure ETextSizeChange(Sender: TObject);
    procedure PageControl1Change(Sender: TObject);
    procedure LBRenderClick(Sender: TObject);
    procedure CBBufferedClick(Sender: TObject);
    procedure CBZoomTextChange(Sender: TObject);
    procedure ViewsChangeChart(Sender: TObject);
    procedure CBTextQualityChange(Sender: TObject);
    procedure TB3DChange(Sender: TObject);
  private
    { Private declarations }
    AllowRotation : Boolean;
    Changing      : Boolean;
    CreatingViews : Boolean;

    procedure AddRenderClasses;
    procedure CreateViewsGallery;
    Function GetRotation:Integer;
    procedure RefreshOptions;
    procedure Select3DPanel(APanel:TCustomTeePanel);
    procedure SetGallery3DPanel(APanel:TCustomTeePanel);
    procedure ShowCanvasEditor;
  public
    { Public declarations }
    ResetTab3D : Boolean;
    ThePanel   : TCustomTeePanel;

    Procedure CheckControls;
  end;

implementation

{$IFNDEF LCL}
{$R *.DFM}
{$ELSE}
{$R *.lfm}
{$ENDIF}

uses
  Math, Series, TeeConst;

Procedure TFormTee3D.CheckControls;
var tmpSeries : TChartSeries;
begin
  if not Assigned(ThePanel) then
     ThePanel:=TCustomTeePanel(Tag);

  if ThePanel is TCustomChart then
     tmpSeries:=TCustomChart(ThePanel).GetASeries
  else
     tmpSeries:=nil;

  AllowRotation:=ThePanel.Canvas.SupportsFullRotation or
                 (not Assigned(tmpSeries)) or
                 (not (tmpSeries is TPieSeries));

  if ResetTab3D then
     if PageControl1.ActivePage<>Tab3D then
        PageControl1.ActivePage:=Tab3D;

  with ThePanel do
  begin
    CBOrthogonal.Enabled:=View3D and AllowRotation;

    SBElevation.Enabled :=View3D and (Canvas.SupportsFullRotation or (not View3DOptions.Orthogonal));
    LElev.Enabled:=SBElevation.Enabled;
    LElevation.Enabled:=LElev.Enabled;

    SBRotation.Enabled  :=SBElevation.Enabled and CBOrthogonal.Enabled;
    LRot.Enabled:=SBRotation.Enabled;
    LRotation.Enabled:=LRot.Enabled;

    EOrthoAngle.Enabled:=CBOrthogonal.Enabled;
    UDOrthoAngle.Enabled:=EOrthoAngle.Enabled;

    TB3D.Enabled:=View3D;
  end;
end;

procedure TFormTee3D.CBOrthogonalClick(Sender: TObject);
begin
  if not Changing then
  begin
    ThePanel.View3DOptions.Orthogonal:=CBOrthogonal.Checked;
    CheckControls;
  end;
end;

procedure TFormTee3D.SBZoomChange(Sender: TObject);
begin
  ThePanel.View3DOptions.Zoom:=SBZoom.Position;
  LZoom.Caption:=IntToStr(SBZoom.Position)+'%'; // Do not localize
end;

Function TFormTee3D.GetRotation:Integer;
begin
  result:=SBRotation.Position;
end;

procedure TFormTee3D.SBRotationChange(Sender: TObject);
var tmp : Integer;
begin
  tmp:=GetRotation;

  if not Changing then
     if Assigned(ThePanel) and Assigned(ThePanel.View3DOptions) then
        ThePanel.View3DOptions.Rotation:=tmp;

  LRotation.Caption:=IntToStr(tmp);
end;

procedure TFormTee3D.SBElevationChange(Sender: TObject);
begin
  if not Changing then
     if Assigned(ThePanel) and Assigned(ThePanel.View3DOptions) then
        ThePanel.View3DOptions.Elevation:=SBElevation.Position;

  LElevation.Caption:=IntToStr(SBElevation.Position);
end;

procedure TFormTee3D.CBView3dClick(Sender: TObject);
begin
  if not Changing then
  begin
    ThePanel.View3D:=CBView3D.Checked;
    CheckControls;
  end;
end;

procedure TFormTee3D.FormShow(Sender: TObject);
begin
  ThePanel:=TCustomTeePanel(Tag);

  if Assigned(ThePanel) then
  begin
    //TabRender.TabVisible:=not (csDesigning in ThePanel.ComponentState);

    RefreshOptions;
  end;
end;

procedure TFormTee3D.AddRenderClasses;
var t   : Integer;
    tmp : Integer;
    tmpS : String;
begin
  LBRender.Clear;

  tmp:=-1;

  for t:=0 to TeeRenderClasses.Count-1 do
  begin
    tmpS:=TCanvas3DClass(TeeRenderClasses[t]).Description;

    // Big Trick here.
    // Obsolete deprecated TAntiAliasCanvas should only appear here in
    // this list when the actual ThePanel.Canvas is of that class:

    if (TClass(TeeRenderClasses[t]).ClassName<>'TAntiAliasCanvas') or
       (TClass(TeeRenderClasses[t])=ThePanel.Canvas.ClassType) then
          LBRender.Items.AddObject(tmpS,TObject(t));

    if TClass(TeeRenderClasses[t])=ThePanel.Canvas.ClassType then
       tmp:=LBRender.Items.Count-1;
  end;

  LBRender.ItemIndex:=tmp;
  LBRenderClick(Self);

  ShowCanvasEditor;
end;

procedure TFormTee3D.RefreshOptions;
begin
  Changing:=True;

  with ThePanel do
  begin
    CBView3D.Checked:=View3D;

    if ThePanel is TCustomAxisPanel then
    begin
      TB3D.Position:=TCustomAxisPanel(ThePanel).Chart3DPercent;
      CBClipPoints.Checked:=TCustomAxisPanel(ThePanel).ClipPoints;
    end
    else
    begin
      TB3D.Hide;
      CBClipPoints.Hide;
    end;

    if Canvas.SupportsFullRotation then
    begin
      SBRotation.Min:=0;
      SBRotation.Frequency:=20;
      SBElevation.Min:=0;
      SBElevation.Frequency:=20;
    end
    else
    begin
      SBRotation.Min:=0;
      SBRotation.Frequency:=45;
      SBElevation.Min:=TeeMinAngle;
      SBElevation.Frequency:=10;
    end;

    With View3DOptions do
    begin
      SBZoom.Position      :=Zoom;
      CBOrthogonal.Checked :=Orthogonal;
      SBRotation.Position  :=Rotation;
      SBElevation.Position :=Elevation;

      if Abs(HorizOffset)>SBHOffset.Max then
      begin
        SBHOffset.Max:=Min(32767,Round(Abs(HorizOffset)*1.5));
        SBHOffset.Min:=-SBHOffset.Max;
      end;

      SBHOffset.Position:=HorizOffset;

      if Abs(VertOffset)>SBVOffset.Max then
      begin
        SBVOffset.Max:=Min(32767,Round(Abs(VertOffset)*1.5));
        SBVOffset.Min:=-SBVOffset.Max;
      end;

      SBVOffset.Position:=VertOffset;

      CBZoomText.ItemIndex:=Ord(ZoomText);
      CBZoomTextChange(Self);

      SBPerspec.Position   :=Perspective;
      UDOrthoAngle.Position:=OrthoAngle;
      UDTextSize.Position  :=FontZoom;
    end;
  end;

  CheckControls;

  Changing:=False;
end;

procedure TFormTee3D.SBHOffsetChange(Sender: TObject);
begin
  ThePanel.View3DOptions.HorizOffset:=SBHOffset.Position;
  LHOffset.Caption:=IntToStr(SBHOffset.Position);
end;

procedure TFormTee3D.SBVOffsetChange(Sender: TObject);
begin
  ThePanel.View3DOptions.VertOffset:=SBVOffset.Position;
  LVOffset.Caption:=IntToStr(SBVOffset.Position);
end;

procedure TFormTee3D.SBPerspecChange(Sender: TObject);
begin
  ThePanel.View3DOptions.Perspective:=SBPerspec.Position;
  LPerspec.Caption:=IntToStr(SBPerspec.Position);
end;

procedure TFormTee3D.EOrthoAngleChange(Sender: TObject);
begin
  if Showing and (not Changing) then
     ThePanel.View3DOptions.OrthoAngle:=UDOrthoAngle.Position;
end;

procedure TFormTee3D.SetGallery3DPanel(APanel:TCustomTeePanel);
begin
  with Views 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.Select3DPanel(APanel:TCustomTeePanel);
var t,tmp : Integer;
    tmpC  : TCustomChart;
begin
  tmp:=-1;

  with Views do
  begin
    Charts[0].View3DOptions:=ThePanel.View3DOptions;
    Charts[0].View3D:=ThePanel.View3D;

    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.FormCreate(Sender: TObject);
begin
  Align:=alClient;
  ResetTab3D:=True;
end;

type
  TGalleryAccess=class(TChartGalleryPanel);

procedure TFormTee3D.CreateViewsGallery;

  Function AddNewChart(const ATitle:String; Is3D:Boolean=False):TCustomChart;
  var t : Integer;
  begin
    result:=Views.CreateChart(TeeSeriesTypes.Find(TFastLineSeries)) as TCustomChart;

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

      View3D:=Is3D;
      
      if Is3D then
      begin
        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
  CreatingViews:=True;

  if ThePanel.Canvas is TCanvas3D then
     TGalleryAccess(Views).CanvasClass:=TCanvas3DClass(ThePanel.Canvas.ClassType);

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

    NumCols:=3;
    NumRows:=3;
  end;

  AddNewChart(TeeMsg_Default);

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

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

  with AddNewChart(TeeMsg_ViewOrthoLeft) do
  begin
    View3D:=True;
    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;

  with AddNewChart(TeeMsg_Top,True) do
  begin
    View3DOptions.Rotation:=0;
    View3DOptions.Elevation:=270;
  end;

  with AddNewChart(TeeMsg_Back,True) do
  begin
    View3DOptions.Rotation:=180;
    View3DOptions.Elevation:=360;
  end;

  Views.ResizeCharts;

  CreatingViews:=False;
end;

procedure TFormTee3D.CBClipPointsClick(Sender: TObject);
begin
  if ThePanel is TCustomAxisPanel then
     TCustomAxisPanel(ThePanel).ClipPoints:=CBClipPoints.Checked;
end;

procedure TFormTee3D.ETextSizeChange(Sender: TObject);
begin
  if Showing and (not Changing) then
     ThePanel.View3DOptions.FontZoom:=UDTextSize.Position;
end;

procedure TFormTee3D.PageControl1Change(Sender: TObject);
begin
  if PageControl1.ActivePage=TabViews then
  begin
    if Views.Charts.Count=0 then
       CreateViewsGallery;

    Select3DPanel(ThePanel);
  end
  else
  if PageControl1.ActivePage=TabRender then
  begin
    if TabRender.TabVisible then
       AddRenderClasses;
  end
  else
     RefreshOptions;
end;

procedure TFormTee3D.LBRenderClick(Sender: TObject);
var tmp : TCanvas3DClass;
    tmp2 : TCanvas3D;
begin
  if LBRender.ItemIndex<>-1 then
  begin
    tmp:=TCanvas3DClass(TeeRenderClasses[Integer(LBRender.Items.Objects[LBRender.ItemIndex])]);

    if tmp<>ThePanel.Canvas.ClassType then
    begin
      Screen.Cursor:=crHourGlass;
      try
        tmp2:=tmp.Create;
        ThePanel.Canvas:=tmp2;

        ShowCanvasEditor;
      finally
        Screen.Cursor:=crDefault;
      end;
    end;
  end;
end;

type
  TCanvasAccess=class(TTeeCanvas3D);

procedure TFormTee3D.ShowCanvasEditor;
var tmpFormClass : TFormClass;
    tmpForm      : TForm;
begin
  Changing:=True;

  while PanelRender.ControlCount>0 do
  if PanelRender.Controls[0]=PanelGDI then
  begin
    PanelGDI.Parent:=nil;
    PanelGDI.Hide;
  end
  else
    PanelRender.Controls[0].Free;

  tmpFormClass:=TFormClass(TeeGetClass(ThePanel.Canvas.EditorClass));

  if Assigned(tmpFormClass) then
  begin
    tmpForm:=tmpFormClass.Create(Self);
    tmpForm.Align:=alClient;

    TeeTranslateControl(tmpForm);
    AddFormTo(tmpForm,PanelRender,ThePanel.Canvas);
  end
  else
  if ThePanel.Canvas is TTeeCanvas3D then
  begin
    PanelGDI.Parent:=PanelRender;
    PanelGDI.Show;

    CBBuffered.Checked:=ThePanel.Canvas.UseBuffer;

    case TCanvasAccess(ThePanel.Canvas).FontQuality of
         fqBest : CBTextQuality.ItemIndex:=0;
      fqDefault : CBTextQuality.ItemIndex:=1;
    fqClearType : CBTextQuality.ItemIndex:=2;
    else
      CBTextQuality.ItemIndex:=3;
    end;
  end;

  Changing:=False;
end;

procedure TFormTee3D.CBBufferedClick(Sender: TObject);
begin
  if not Changing then
  begin
    ThePanel.Canvas.UseBuffer:=CBBuffered.Checked;
    ThePanel.Invalidate;
  end;
end;

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

procedure TFormTee3D.ViewsChangeChart(Sender: TObject);
begin
  if not CreatingViews then
     SetGallery3DPanel(ThePanel);
end;

procedure TFormTee3D.CBTextQualityChange(Sender: TObject);
begin
  if not Changing then
  begin
    case CBTextQuality.ItemIndex of
      0: TCanvasAccess(ThePanel.Canvas).FontQuality:=fqBest;
      1: TCanvasAccess(ThePanel.Canvas).FontQuality:=fqDefault;
      2: TCanvasAccess(ThePanel.Canvas).FontQuality:=fqClearType;
    else
      TCanvasAccess(ThePanel.Canvas).FontQuality:=fqNormal;
    end;

    ThePanel.Invalidate;
  end;
end;

procedure TFormTee3D.TB3DChange(Sender: TObject);
begin
  if Showing and (not Changing) then
     if ThePanel is TCustomAxisPanel then
        TCustomAxisPanel(ThePanel).Chart3DPercent:=TB3D.Position;
end;

end.
