unit Vis3D_TextRectSettings;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, TextEditor, Vcl.StdCtrls, rgl,
  UxPanel, Vcl.ExtCtrls, ColorContainer, ScrollBoxEx, Vcl.ComCtrls;

type
  TVis3D_TextRectSettingsFrm = class(TDrawableOptionsFrm3D)
    btnApply: TUxButton;
    ScrollBox1: TScrollBoxEx;
    lblStyleName: TLabel;
    Label1: TLabel;
    lblPosition: TLabel;
    ePosX: TTextEditor;
    ePosY: TTextEditor;
    ePosZ: TTextEditor;
    lblDirection: TLabel;
    eDirX: TTextEditor;
    eDirY: TTextEditor;
    eDirZ: TTextEditor;
    lblScale: TLabel;
    eScaleX: TTextEditor;
    eScaleY: TTextEditor;
    lblRotation: TLabel;
    eRot: TTextEditor;
    Label17: TLabel;
    Label2: TLabel;
    eText: TTextEditor;
    pnTextFont: TPanel;
    btnTextFont: TUxButton;
    Label3: TLabel;
    pnAnchors: TPanel;
    btnATopLeft: TUxButton;
    btnATop: TUxButton;
    btnATopRight: TUxButton;
    btnALeft: TUxButton;
    btnACenter: TUxButton;
    btnARight: TUxButton;
    btnABottomLeft: TUxButton;
    btnABottom: TUxButton;
    btnABottomRight: TUxButton;
    lblOpacity: TLabel;
    eOpacity: TTextEditor;
    cbFaceScreen: TCheckBox;
    lblDisplacement: TLabel;
    eDispX: TTextEditor;
    eDispY: TTextEditor;
    lblQuality: TLabel;
    tbQuality: TTrackBar;
    procedure btnApplyClick(Sender: TObject);
    procedure ccColorChange(Sender: TObject);
    procedure btnTextFontClick(Sender: TObject);
    procedure SetAnchor(Sender: TObject);
    procedure eTextChange(Sender: TObject);
    procedure cbFaceScreenClick(Sender: TObject);
  private
    FRecomputeAspect: Boolean;
  public
    procedure Initialize; override;
    procedure UpdateDrawable; override;
  end;

implementation

uses
  Math, VisCtl2D;

{$R *.dfm}

procedure TVis3D_TextRectSettingsFrm.btnApplyClick(Sender: TObject);
begin
  UpdateDrawable;
end;

procedure TVis3D_TextRectSettingsFrm.btnTextFontClick(Sender: TObject);
begin
  with TFontDialog.Create(nil) do
    try
      Font := pnTextFont.Font;
      if Execute then
      begin
        pnTextFont.Font := Font;
        pnTextFont.Caption := Format('%s, %d pt', [Font.Name, Font.Size]);
        UpdateDrawable;
      end;
    finally
      Free;
    end;
end;

procedure TVis3D_TextRectSettingsFrm.cbFaceScreenClick(Sender: TObject);
begin
  lblDisplacement.Enabled := cbFaceScreen.Checked;
  eDispX.Enabled := cbFaceScreen.Checked;
  eDispY.Enabled := cbFaceScreen.Checked;
  UpdateDrawable;
end;

procedure TVis3D_TextRectSettingsFrm.ccColorChange(Sender: TObject);
begin
  UpdateDrawable;
end;

procedure TVis3D_TextRectSettingsFrm.eTextChange(Sender: TObject);
begin
  try
    FRecomputeAspect := True;
    UpdateDrawable;
  finally
    FRecomputeAspect := False;
  end;
end;

procedure TVis3D_TextRectSettingsFrm.Initialize;
begin
  inherited;
  var Obj := FDrawable as TTextRect;
  eText.PlainText := Obj.Text;
  pnTextFont.Font := Obj.Font;
  pnTextFont.Font.Color := Obj.Color;
  pnTextFont.Caption := Format('%s, %d pt', [pnTextFont.Font.Name, pnTextFont.Font.Size]);
  eOpacity.PlainText := FormatFloat('0.00#', Obj.Opacity);
  for var i := 0 to pnAnchors.ControlCount - 1 do
    if pnAnchors.Controls[i] is TUxButton then
      TUxButton(pnAnchors.Controls[i]).Down := pnAnchors.Controls[i].Tag = Ord(Obj.AnchorPoint);
  ePosX.PlainText := Obj.Position.x.ToString;
  ePosY.PlainText := Obj.Position.y.ToString;
  ePosZ.PlainText := Obj.Position.z.ToString;
  eDirX.PlainText := Obj.Direction.x.ToString;
  eDirY.PlainText := Obj.Direction.y.ToString;
  eDirZ.PlainText := Obj.Direction.z.ToString;
  eScaleX.PlainText := Obj.Scale.x.ToString;
  eScaleY.PlainText := Obj.Scale.y.ToString;
  eRot.PlainText := Obj.Rotation.ToString;
  cbFaceScreen.Checked := Obj.FaceScreen;
  eDispX.PlainText := FormatFloat('0.00##', Obj.Displacement.x);
  eDispY.PlainText := FormatFloat('0.00##', Obj.Displacement.y);
  tbQuality.Position := EnsureRange(Round(4*Obj.TextResFactor), tbQuality.Min, tbQuality.Max);
end;

procedure TVis3D_TextRectSettingsFrm.SetAnchor(Sender: TObject);
begin
  if Sender is TUxButton then
  begin
    for var i := 0 to pnAnchors.ControlCount - 1 do
      if (pnAnchors.Controls[i] is TUxButton) and (pnAnchors.Controls[i].Tag < 10) then
        TUxButton(pnAnchors.Controls[i]).Down := pnAnchors.Controls[i] = Sender;
    UpdateDrawable;
  end;
end;

procedure TVis3D_TextRectSettingsFrm.UpdateDrawable;
begin
  if not FInitialized then
    Exit;
  var Obj := FDrawable as TTextRect;
  Obj.Text := eText.PlainText;
  Obj.Font := pnTextFont.Font;
  Obj.Color := pnTextFont.Font.Color;
  Obj.Opacity := StrToFloat(eOpacity.PlainText);
  if btnATopLeft.Down then
    Obj.AnchorPoint := apTopLeft
  else if btnATop.Down then
    Obj.AnchorPoint := apTop
  else if btnATopRight.Down then
    Obj.AnchorPoint := apTopRight
  else if btnALeft.Down then
    Obj.AnchorPoint := apLeft
  else if btnACenter.Down then
    Obj.AnchorPoint := apCenter
  else if btnARight.Down then
    Obj.AnchorPoint := apRight
  else if btnABottomLeft.Down then
    Obj.AnchorPoint := apBottomLeft
  else if btnABottom.Down then
    Obj.AnchorPoint := apBottom
  else if btnABottomRight.Down then
    Obj.AnchorPoint := apBottomRight
  else
    Obj.AnchorPoint := apTopLeft;
  Obj.Position := vec(
    StrToFloat(ePosX.PlainText),
    StrToFloat(ePosY.PlainText),
    StrToFloat(ePosZ.PlainText)
  );
  Obj.Direction := vec(
    StrToFloat(eDirX.PlainText),
    StrToFloat(eDirY.PlainText),
    StrToFloat(eDirZ.PlainText)
  );
  if FRecomputeAspect then
  begin
    FRecomputeAspect := False;
    eScaleY.PlainText := FloatToStr(StrToFloatDef(eScaleX.PlainText, 1.0) * Obj.Aspect);
  end;
  Obj.Scale := vec(
    StrToFloat(eScaleX.PlainText),
    StrToFloat(eScaleY.PlainText),
    1.0
  );
  Obj.Rotation := StrToFloat(eRot.PlainText);
  Obj.FaceScreen := cbFaceScreen.Checked;
  if Obj.FaceScreen then
    Obj.Displacement := vec2(
      StrToFloat(eDispX.PlainText),
      StrToFloat(eDispY.PlainText)
    );
  Obj.TextResFactor := EnsureRange(0.25 * tbQuality.Position, 0.1, 2.0);
  inherited;
end;

end.
