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

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls,
  {$IFNDEF UPTOXE3}
  FMX.StdCtrls, FMX.Controls3D, FMX.MaterialSources,
  {$ENDIF}
  FMX.Forms, FMX.Dialogs, FMX.ListBox, FMX.Types3D,
  {$IFDEF D21}
  FMX.ComboTrackBar,
  {$ENDIF}
  FMX.TabControl, FMX.Colors, FMX.Edit;

type
  TLightsEditor = class(TForm)
    CBLight: TComboBox;
    CBEnabled: TCheckBox;
    TrackBar1: TTrackBar;
    TrackBar2: TTrackBar;
    TrackBar3: TTrackBar;
    TrackBar4: TTrackBar;
    TrackBar5: TTrackBar;
    CBLightType: TComboBox;
    ListBoxItem11: TListBoxItem;
    ListBoxItem12: TListBoxItem;
    ListBoxItem13: TListBoxItem;
    Button1: TButton;
    BDelete: TButton;
    LPosX: TLabel;
    LPosY: TLabel;
    LPosZ: TLabel;
    LRotX: TLabel;
    LRotY: TLabel;
    TabControl1: TTabControl;
    TabItem1: TTabItem;
    TabItem2: TTabItem;
    Panel1: TPanel;
    TabItem3: TTabItem;
    CBAmbient: TColorButton;
    Label1: TLabel;
    TabItem4: TTabItem;
    Label2: TLabel;
    CBDiffuse: TColorButton;
    Label3: TLabel;
    CBSpecular: TColorButton;
    CBSpotCutoff: TComboTrackBar;
    Label4: TLabel;
    CBSpotExponent: TComboTrackBar;
    Label5: TLabel;
    TabItem5: TTabItem;
    TBConstantAtt: TTrackBar;
    TBLinearAtt: TTrackBar;
    TBQuadraticAtt: TTrackBar;
    Label6: TLabel;
    Label7: TLabel;
    Label8: TLabel;
    procedure CBLightChange(Sender: TObject);
    procedure CBEnabledChange(Sender: TObject);
    procedure CBLightTypeChange(Sender: TObject);
    procedure TrackBar1Change(Sender: TObject);
    procedure TrackBar2Change(Sender: TObject);
    procedure TrackBar3Change(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure BDeleteClick(Sender: TObject);
    procedure TrackBar4Change(Sender: TObject);
    procedure TrackBar5Change(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure CBAmbientChange(Sender: TObject);
    procedure CBDiffuseClick(Sender: TObject);
    procedure CBSpecularClick(Sender: TObject);
    procedure CBSpotExponentChange(Sender: TObject);
    procedure CBSpotCutoffChange(Sender: TObject);
    procedure TBConstantAttChange(Sender: TObject);
    procedure TBLinearAttChange(Sender: TObject);
    procedure TBQuadraticAttChange(Sender: TObject);
  private
    { Private declarations }
    IView : TFmxObject;
    IReady : Boolean;

    procedure AddComboLight(const ALight:TFmxObject);
    function CoordToString(const AValue:Single):String;
    function Light:TLight;
    procedure RepaintView;
  public
    { Public declarations }
    procedure RefreshViewport(const AViewPort:TFmxObject);
  end;

implementation

{$R *.fmx}

{ TLightsEditor }

function TLightsEditor.Light:TLight;
begin
  result:=TLight(CBLight.Selected.Data);
end;

procedure TLightsEditor.AddComboLight(const ALight:TFmxObject);
var i : TListBoxItem;
begin
  i:=TListBoxItem.Create(Self);
  i.Text:='Light '+IntToStr(CBLight.Count);
  i.Data:=ALight;
  CBLight.AddObject(i);
end;

procedure TLightsEditor.Button1Click(Sender: TObject);
var l : TLight;
begin
  l:=TLight.Create(IView.Owner);
  IView.AddObject(l);
  AddComboLight(l);
  CBLight.ItemIndex:=CBLight.Count-1;
end;

procedure TLightsEditor.BDeleteClick(Sender: TObject);
begin
  Light.DisposeOf;
  CBLight.Selected.DisposeOf;
  CBLightChange(Self);
end;

procedure TLightsEditor.CBEnabledChange(Sender: TObject);
begin
  Light.Enabled:=CBEnabled.IsChecked;
end;

procedure TLightsEditor.CBLightChange(Sender: TObject);
begin
  if CBLight.ItemIndex=-1 then
  begin
    CBEnabled.Enabled:=False;
    CBLightType.Enabled:=False;
    TrackBar1.Enabled:=False;
    TrackBar2.Enabled:=False;
    TrackBar3.Enabled:=False;

    BDelete.Enabled:=False;

    LPosX.Text:='';
    LPosY.Text:='';
    LPosZ.Text:='';

    TabItem2.Enabled:=False;
    TabItem3.Enabled:=False;
  end
  else
  begin
    CBEnabled.Enabled:=True;
    CBLightType.Enabled:=True;
    TrackBar1.Enabled:=True;
    TrackBar2.Enabled:=True;
    TrackBar3.Enabled:=True;

    CBEnabled.IsChecked:=Light.Enabled;
    CBLightType.ItemIndex:=Ord(Light.LightType);

    TabItem2.Enabled:=Light.LightType=TLightType.{$IFDEF D20}Spot{$ELSE}ltSpot{$ENDIF};

    TabItem3.Enabled:=True;

    CBAmbient.Color:=Light.{$IFDEF D17}Color{$ELSE}Ambient{$ENDIF};

    {$IFDEF D17}
    CBDiffuse.Visible:=False;
    CBSpecular.Visible:=False;
    Label2.Visible:=False;
    Label3.Visible:=False;
    {$ELSE}
    CBDiffuse.Color:=Light.Diffuse;
    CBSpecular.Color:=Light.Specular;
    {$ENDIF}

    CBSpotCutoff.Value:=Light.SpotCutOff;
    CBSpotExponent.Value:=Light.SpotExponent;

    {$IFDEF D17}
    TBConstantAtt.Visible:=False;
    TBLinearAtt.Visible:=False;
    TBQuadraticAtt.Visible:=False;
    {$ELSE}
    TBConstantAtt.Value:=Light.ConstantAttenuation;
    TBLinearAtt.Value:=Light.LinearAttenuation;
    TBQuadraticAtt.Value:=Light.QuadraticAttenuation;
    {$ENDIF}

    TrackBar1.Value:=Light.Position.X*10;
    TrackBar2.Value:=Light.Position.Y*10;
    TrackBar3.Value:=Light.Position.Z*10;

    LPosX.Text:=CoordToString(Light.Position.X);
    LPosY.Text:=CoordToString(Light.Position.Y);
    LPosZ.Text:=CoordToString(Light.Position.Z);

    TrackBar4.Value:=Light.RotationAngle.X;
    TrackBar5.Value:=Light.RotationAngle.Y;

    LRotX.Text:=CoordToString(Light.RotationAngle.X);
    LRotY.Text:=CoordToString(Light.RotationAngle.Y);

    BDelete.Enabled:=True;
  end;
end;

procedure TLightsEditor.CBLightTypeChange(Sender: TObject);
begin
  Light.LightType:=TLightType(CBLightType.ItemIndex);

  TabItem2.Enabled:=Light.LightType=TLightType.{$IFDEF D20}Spot{$ELSE}ltSpot{$ENDIF};

  RepaintView;
end;

procedure TLightsEditor.CBSpecularClick(Sender: TObject);
begin
  {$IFNDEF D17}
  Light.Specular:=CBSpecular.Color;
  RepaintView;
  {$ENDIF}
end;

procedure TLightsEditor.CBSpotCutoffChange(Sender: TObject);
begin
  if IReady then
  begin
    Light.SpotCutOff:=CBSpotCutoff.Value;
    RepaintView;
  end;
end;

procedure TLightsEditor.CBSpotExponentChange(Sender: TObject);
begin
  if IReady then
  begin
    Light.SpotExponent:=CBSpotExponent.Value;
    RepaintView;
  end;
end;

function TLightsEditor.CoordToString(const AValue: Single): String;
begin
  result:=FormatFloat('0.##',AValue);
end;

procedure TLightsEditor.CBAmbientChange(Sender: TObject);
begin
  Light.{$IFDEF D17}Color{$ELSE}Ambient{$ENDIF}:=CBAmbient.Color;
  RepaintView;
end;

procedure TLightsEditor.CBDiffuseClick(Sender: TObject);
begin
  {$IFNDEF D17}
  Light.Diffuse:=CBDiffuse.Color;
  RepaintView;
  {$ENDIF}
end;

procedure TLightsEditor.FormCreate(Sender: TObject);
begin
  TabControl1.ActiveTab:=TabItem1;
  IReady:=True;
end;

procedure TLightsEditor.RefreshViewport(const AViewPort: TFmxObject);
var t : Integer;
begin
  IView:=AViewPort;

  CBLight.Clear;

  for t := 0 to IView.ChildrenCount-1 do
  if IView.Children[t] is TLight then
     AddComboLight(IView.Children[t]);

  if CBLight.Count>0 then
     CBLight.ItemIndex:=0
  else
     CBLightChange(Self);
end;

procedure TLightsEditor.RepaintView;
begin
  if IView is TControl then
     TControl(IView).Repaint;
end;

procedure TLightsEditor.TrackBar1Change(Sender: TObject);
begin
  Light.Position.X:=TrackBar1.Value*0.1;
  LPosX.Text:=CoordToString(Light.Position.X);
end;

procedure TLightsEditor.TrackBar2Change(Sender: TObject);
begin
  Light.Position.Y:=TrackBar2.Value*0.1;
  LPosY.Text:=CoordToString(Light.Position.Y);
end;

procedure TLightsEditor.TrackBar3Change(Sender: TObject);
begin
  Light.Position.Z:=TrackBar3.Value*0.1;
  LPosZ.Text:=CoordToString(Light.Position.Z);
end;

procedure TLightsEditor.TrackBar4Change(Sender: TObject);
begin
  Light.RotationAngle.X:=TrackBar4.Value;
  LRotX.Text:=CoordToString(Light.RotationAngle.X);
end;

procedure TLightsEditor.TrackBar5Change(Sender: TObject);
begin
  Light.RotationAngle.Y:=TrackBar5.Value;
  LRotY.Text:=CoordToString(Light.RotationAngle.Y);
end;

procedure TLightsEditor.TBConstantAttChange(Sender: TObject);
begin
  {$IFNDEF D17}
  Light.ConstantAttenuation:=TBConstantAtt.Value;
  RepaintView;
  {$ENDIF}
end;

procedure TLightsEditor.TBLinearAttChange(Sender: TObject);
begin
  {$IFNDEF D17}
  Light.LinearAttenuation:=TBLinearAtt.Value;
  RepaintView;
  {$ENDIF}
end;

procedure TLightsEditor.TBQuadraticAttChange(Sender: TObject);
begin
  {$IFNDEF D17}
  Light.QuadraticAttenuation:=TBQuadraticAtt.Value;
  RepaintView;
  {$ENDIF}
end;

end.
