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

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.ListBox,
  {$IFNDEF UPTOXE3}
  FMX.StdCtrls,
  {$ENDIF}
  FMX.TabControl, FMX.Layouts, FMX.Memo, FMX.Objects,
  FMXTee.Engine, FMXTee.Chart;

type
  TToolsGallery = class;

  TToolsGalleryHook=function(const Gallery:TToolsGallery):TObject;

  TTeeToolType=class
    ToolClass : TTeeCustomToolClass;
  end;

  TToolsGallery = class(TForm)
    PanelBottom: TPanel;
    CBView3D: TCheckBox;
    LabelClass: TText;
    PanelButtons: TPanel;
    BOk: TButton;
    Button2: TButton;
    MemoDesc: TMemo;
    TabControl1: TTabControl;
    PanelDemos: TPanel;
    TabItem1: TTabItem;
    LBTool: TListBox;
    TabItem2: TTabItem;
    TabItem3: TTabItem;
    StyleBook1: TStyleBook;
    Splitter1: TSplitter;
    procedure LBToolDblClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure LBToolChange(Sender: TObject);
    procedure CBView3DChange(Sender: TObject);
    procedure TabControl1Change(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }

    IGalleryHook : TObject;

    Function ToolAtIndex(AIndex:Integer):TTeeCustomToolClass;
  protected
    TheGalleryHook : TToolsGalleryHook;
    TypesToShow    : Array of TTeeToolType;

    DontAddTools   : Boolean;

    function AddTool(const ADesc:String; const ATool:TTeeToolType):TListBoxItem;
    procedure FillTools; virtual;
    procedure FillTypes(const AList:TTeeToolTypes);
    function FilterTool(Index:Integer):Boolean; virtual;
  public
    { Public declarations }

    class procedure ApplyListToolItem(const AItem:TListBoxItem; const AToolClass:String);
    class function Choose(const AOwner:TComponent):TTeeCustomToolClass;
    class function CreateEditor(const AOwner:TComponent):TToolsGallery;
    function FindDemoChart:TCustomChart;
    Function SelectedTool:TTeeCustomToolClass;
  end;

var
  ToolsGalleryHook : TToolsGalleryHook=nil;

implementation

{$R *.fmx}

{$R TeeTools.res}

uses
  FMXTee.Procs;

{ TToolsGallery }

Function TToolsGallery.FilterTool(Index:Integer):Boolean;
var tmp : TTeeCustomTool;
begin
  tmp:=TeeToolTypes[Index].Create(nil);
  try
    case TabControl1.TabIndex of
      0: result:=tmp is TTeeCustomToolSeries;
      1: result:=tmp is TTeeCustomToolAxis;
      2: result:=(not (tmp is TTeeCustomToolSeries)) and
                 (not (tmp is TTeeCustomToolAxis));
    else
      result:=True;
    end;
  finally
    tmp.Free;
  end;
end;

class procedure TToolsGallery.ApplyListToolItem(const AItem:TListBoxItem; const AToolClass:String);
var tmpIcon : TFmxObject;
begin
  // Change StyleLookup *after* adding to ListSeries:
  AItem.StyleLookup:='toolslistbox';
  AItem.ApplyStyleLookup;

  tmpIcon:=AItem.FindStyleResource('icon');

  if Assigned(tmpIcon) then
  begin
    TeeLoadBitmap({$IFDEF D18}AItem.ItemData.Bitmap{$ELSE}TImage(tmpIcon).Bitmap{$ENDIF},AToolClass);
    TImage(tmpIcon).Visible:=True;
  end;
end;

function TToolsGallery.AddTool(const ADesc:String; const ATool:TTeeToolType):TListBoxItem;
begin
  result:=TListBoxItem.Create(Owner);
  result.Text:=ADesc;

  result.Data:=ATool;
  LBTool.AddObject(result);

  ApplyListToolItem(result,ATool.ToolClass.ClassName);
end;

procedure TToolsGallery.FillTools;
var t : Integer;
begin
  LBTool.Clear;

  if not DontAddTools then
  for t:=Low(TypesToShow) to High(TypesToShow) do
      if FilterTool(t) then
         AddTool(TypesToShow[t].ToolClass.Description,TypesToShow[t]);

  MemoDesc.Lines.Clear;
  BOk.Enabled:=False;
end;

procedure TToolsGallery.CBView3DChange(Sender: TObject);
begin
  if Assigned(TCheckBox(Sender).TagObject) then
     TCustomChart(TCheckBox(Sender).TagObject).View3D:=TCheckBox(Sender).IsChecked;
end;

class function TToolsGallery.Choose(const AOwner: TComponent): TTeeCustomToolClass;
begin
  with TToolsGallery.CreateEditor(AOwner) do
  try
    if ShowModal=mrOk then
       result:=SelectedTool
    else
       result:=nil;
  finally
    Free;
  end;
end;

class function TToolsGallery.CreateEditor(const AOwner: TComponent): TToolsGallery;
begin
  result:=Self.Create(AOwner);

  with result do
  begin
    LabelClass.Visible:=csDesigning in ComponentState;
    LabelClass.Text:='';

    PanelDemos.Visible:=Assigned(ToolsGalleryHook);
    CBView3D.Visible:=PanelDemos.Visible;

    if not PanelDemos.Visible then
    begin
      TabControl1.Align:=TAlignLayout.{$IFDEF D20}Client{$ELSE}alClient{$ENDIF};
      Width:=300;
    end;

    // Force OnShow to call LBChange, specially when this editor is embedded.
    if Assigned(OnShow) then
       OnShow(result);

    //TeeTranslateControl(Self);
  end;
end;

procedure TToolsGallery.FillTypes(const AList:TTeeToolTypes);
var t : Integer;
begin
  SetLength(TypesToShow,TeeToolTypes.Count);

  for t := 0 to TeeToolTypes.Count-1 do
  begin
    TypesToShow[t]:=TTeeToolType.Create;
    TypesToShow[t].ToolClass:=TeeToolTypes[t];
  end;
end;

procedure TToolsGallery.FormCreate(Sender: TObject);
begin
  FillTypes(TeeToolTypes);

  TheGalleryHook:=ToolsGalleryHook;
end;

procedure TToolsGallery.FormDestroy(Sender: TObject);
var t : Integer;
begin
  for t:=Low(TypesToShow) to High(TypesToShow) do
      TypesToShow[t].Free;

  TypesToShow:=nil;

  IGalleryHook.Free;
end;

procedure TToolsGallery.FormShow(Sender: TObject);
begin
  TabControl1.ActiveTab:=TabItem1;
  TabControl1Change(Self);
end;

procedure TToolsGallery.LBToolChange(Sender: TObject);
var tmp : TCustomChart;
begin
  BOk.Enabled:=LBTool.ItemIndex<>-1;

  tmp:=FindDemoChart;

  if Assigned(tmp) then
     tmp.{$IFDEF AUTOREFCOUNT}Parent:=nil{$ELSE}Free{$ENDIF};

  if LBTool.ItemIndex=-1 then
  begin
    LabelClass.Text:='';
    MemoDesc.Lines.Clear;
    CBView3D.Visible:=False;
  end
  else
  begin
    if Assigned(Application) and (csDesigning in Application.ComponentState) then
       LabelClass.Text:=ToolAtIndex(LBTool.ItemIndex).ClassName;

    MemoDesc.Lines.Text:=ToolAtIndex(LBTool.ItemIndex).LongDescription;

    //TeeTranslateControl(MemoDesc);

    if Assigned(TheGalleryHook) then
    begin
      IGalleryHook.Free;
      IGalleryHook:=TheGalleryHook(Self);

      tmp:=FindDemoChart;

      //TeeTranslateControl(PanelDemos);

      CBView3D.OnChange:=nil;

      if Assigned(tmp) then
      begin
        CBView3D.Visible:=True;
        CBView3D.Enabled:=True;
        CBView3D.IsChecked:=tmp.View3D;
        CBView3D.TagObject:=tmp;
        CBView3D.OnChange:=CBView3DChange;
      end
      else
        CBView3D.Visible:=False;
    end;
  end;
end;

procedure TToolsGallery.LBToolDblClick(Sender: TObject);
begin
  ModalResult:=mrOk;
end;

function TToolsGallery.FindDemoChart:TCustomChart;

  function FindChartIn(const AControl:TControl):TCustomChart;
  var t : Integer;
      tmp : TControl;
  begin
    result:=nil;

    for t:=0 to AControl.ControlsCount-1 do
    begin
      tmp:=AControl.Controls[t];

      if tmp is TCustomChart then
         result:=TCustomChart(tmp)
      else
        result:=FindChartIn(tmp);

      if Assigned(result) then
         break;
    end;
  end;

begin
  result:=FindChartIn(PanelDemos);
end;

function TToolsGallery.SelectedTool: TTeeCustomToolClass;
begin
  result:=ToolAtIndex(LBTool.ItemIndex);
end;

procedure TToolsGallery.TabControl1Change(Sender: TObject);
begin
  FillTools;
  LBTool.Parent:=TabControl1.ActiveTab;

  if LBTool.ItemIndex=-1 then
     if LBTool.Count>0 then
        LBTool.ItemIndex:=0;
end;

Function TToolsGallery.ToolAtIndex(AIndex:Integer):TTeeCustomToolClass;
begin
  result:=TTeeToolType(LBTool.Items.Objects[AIndex]).ToolClass;
end;

initialization
  ToolsGalleryHook:=nil;
end.
