unit VisCtlOptions;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, UxPanel,
  VisCtl2D, Vcl.ExtCtrls, ScrollBoxEx;

type
  TVisCtlOptionsFrm = class(TDrawableOptionsFrm)
    pnToolbar: TUxClient;
    pnClient: TPanel;
    sbToolbar: TScrollBoxEx;
    procedure FormCreate(Sender: TObject);
  private
    Frm: TDrawableOptionsFrm;
    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 TVisCtlOptionsFrm.FormCreate(Sender: TObject);
var
  Y: Integer;
  i: Integer;

  procedure AddButton(ACaption: string; ADrawable: TDrawable);
  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
  Diagram: TDiagram;

begin

  Diagram := FDrawable as TDiagram;

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

  for i := 0 to Diagram.Control.ObjectCount - 1 do
    AddButton(Diagram.Control.Objects[i].Name, Diagram.Control.Objects[i]);

  if Assigned(FFirstButton) then
    SetPage(FFirstButton);

end;

procedure TVisCtlOptionsFrm.SetPage(Sender: TObject);
var
  B: TDrawableButton;
  D: TDrawable;
begin

  if not (Sender is TDrawableButton) then
    Exit;

  B := Sender as TDrawableButton;

  if not TDrawable.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.
