unit Vis3D_SceneSettings;

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;

type
  TVis3D_SceneSettingsFrm = class(TDrawableOptionsFrm3D)
    pnToolbar: TUxClient;
    pnClient: TPanel;
    sbToolbar: TScrollBoxEx;
    procedure FormCreate(Sender: TObject);
  private
    Frm: TDrawableOptionsFrm3D;
    FFirstButton: TUxButton;
    procedure SetPage(Sender: TObject);
  public
  end;

implementation

{$R *.dfm}

uses TDMessageBox;

function Scale(X: Integer): Integer;
begin
  Result := MulDiv(X, Screen.PixelsPerInch, 96);
end;

type
  TDrawableButton = class(TUxButton)
  public
    DrawableRef: TGUID;
  end;

procedure TVis3D_SceneSettingsFrm.FormCreate(Sender: TObject);
var
  Y: Integer;
  i: Integer;

  procedure AddButton(ACaption: string; ADrawable: TDrawable3D);
  var
    B: TDrawableButton;
  begin
    B := TDrawableButton.Create(Self);
    B.Parent := sbToolbar;
    B.Caption := ACaption;
    B.Left := 0;
    B.Top := Y;
    B.Width := sbToolbar.Width;
    B.Height := Scale(40);
    B.Anchors := [akLeft, akTop, akRight];
    if Assigned(ADrawable) then
      B.DrawableRef := ADrawable.GUID;
    B.OnClick := SetPage;
    Inc(Y, B.Height);
    if FFirstButton = nil then
      FFirstButton := B;
  end;

var
  Scene: TScene;

begin

  Scene := FDrawable as TScene;

  Y := 0;
  AddButton('View', Scene.Control.View);
  AddButton('Axes', Scene.Control.Axes);
  AddButton('Objects', Scene.Control.ObjectMgr);
  Inc(Y, Scale(20));

  for i := 0 to Scene.Control.ObjectCount - 1 do
    if
      (Scene.Control.Objects[i].Parent = nil)
        and
      (Scene.Control.Objects[i] <> Scene.Control.Axes)
    then
      AddButton(Scene.Control.Objects[i].Name, Scene.Control.Objects[i]);

  if Assigned(FFirstButton) then
    SetPage(FFirstButton);

end;

procedure TVis3D_SceneSettingsFrm.SetPage(Sender: TObject);
var
  B: TDrawableButton;
  D: TDrawable3D;
begin

  if not (Sender is TDrawableButton) then
    Exit;

  B := Sender as TDrawableButton;

  if not TDrawable3D.TryGetDrawableByGUID(B.DrawableRef, D) then
  begin
    B.Enabled := False;
    TD.MessageBox(Caption, 'This object has been deleted.', '', tdiInformation, [tcbOk]);
    Exit;
  end;

  if B.Down and Assigned(Frm) and (Frm.Drawable = D) then
    Exit;

  for var i := 0 to sbToolbar.ControlCount - 1 do
    if sbToolbar.Controls[i] is TDrawableButton then
      TDrawableButton(sbToolbar.Controls[i]).Down := sbToolbar.Controls[i] = B;

  Screen.Cursor := crHourGlass;
  try
    pnClient.Perform(WM_SETREDRAW, Ord(False), 0);
    try

      FreeAndNil(Frm);
      if Assigned(D.OptionsFormClass) then
      begin
        Frm := D.OptionsFormClass.Create(Self, D);
        Frm.BorderStyle := bsNone;
        Frm.Parent := pnClient;
        Frm.Align := alClient;
        Frm.Show;
        if Visible and Frm.Visible and Frm.CanFocus then
          Frm.SetFocus;
      end;

    finally
      pnClient.Perform(WM_SETREDRAW, Ord(True), 0);
      RedrawWindow(pnClient.Handle, nil, 0, RDW_ERASE or RDW_FRAME or RDW_INVALIDATE or RDW_ALLCHILDREN);
    end;
  finally
    Screen.Cursor := crDefault;
  end;

end;

end.
