{**********************************************}
{  TChartGradient Editor Dialog                }
{  Copyright (c) 1999-2020 by Steema Software  }
{**********************************************}
unit TeeEdiGrad;
{$I TeeDefs.inc}

interface

uses {$IFNDEF LINUX}
     Windows, Messages,
     {$ENDIF}
     SysUtils, Classes,

     Graphics, Buttons, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls,

     {$IFDEF MSWINDOWS}
     TeeGDIPlus,
     {$ENDIF}

     {$IFDEF LINUX}
     Types,
     {$ENDIF}
     {$IFDEF D10}
     Types,
     {$ENDIF}

     {$IFDEF D16}
     System.UITypes,
     {$ENDIF}

     {$IFDEF TEEDONOTDEFINE}
     TeeEdiGrad,
     {$ENDIF}

     TeeProcs, TeCanvas, TeeGalleryPanel, TeeDraw3D;

type
  TPreviewGradient=class(TCustomTeePanelExtended)
  protected
    Procedure InternalDraw(Const UserRectangle:TRect); override;
  end;

  TTeeGradientEditor=class; // forward

  TButtonGradient=class(TTeeButton)
  private
    FEditor     : TTeeGradientEditor;
    FOldDestroy : TNotifyEvent;

    procedure EditorDestroy(Sender:TObject);
    Function GetEditor:TTeeGradientEditor;
    Function GetGradient:TCustomTeeGradient;
  protected
    procedure DrawSymbol(const ACanvas:TTeeCanvas); override;
  public
    OnlyStart : Boolean;

    procedure Click; override;
    procedure LinkGradient(const Value:TCustomTeeGradient);

    property Editor:TTeeGradientEditor read GetEditor;
    property Gradient:TCustomTeeGradient read GetGradient write LinkGradient;
  end;

  TTeeGradientEditor = class(TForm)
    PageControl1: TPageControl;
    TabColors: TTabSheet;
    TabSheet2: TTabSheet;
    Label4: TLabel;
    LabelBalance: TLabel;
    GroupBox2: TGroupBox;
    Label2: TLabel;
    Label3: TLabel;
    LRadialX: TLabel;
    LRadialY: TLabel;
    TrackBar1: TTrackBar;
    TrackBar2: TTrackBar;
    PanelButtons: TPanel;
    Panel2: TPanel;
    CBVisible: TCheckBox;
    Label1: TLabel;
    CBDirection: TComboFlat;
    TabGallery: TTabSheet;
    TabDirections: TTabSheet;
    Directions: TChartGalleryPanel;
    TabSheet5: TTabSheet;
    Label5: TLabel;
    SBTransp: TScrollBar;
    BSubEdit: TButtonGradient;
    CBSubVisible: TCheckBox;
    Label6: TLabel;
    EAngle: TEdit;
    UDAngle: TUpDown;
    TBAngle: TTrackBar;
    Gallery: TChartGalleryPanel;
    Draw3D1: TDraw3D;
    Colors: TDraw3D;
    Panel1: TPanel;
    BSwap: TButton;
    BStart: TButtonColor;
    BEnd: TButtonColor;
    BMid: TButtonColor;
    CBMid: TCheckBox;
    CBSameAsEnd: TCheckBox;
    BColor: TButtonColor;
    TrackTransp: TTrackBar;
    BDeleteColor: TSpeedButton;
    Panel3: TPanel;
    BOk: TButton;
    BCancel: TButton;
    LTransp: TLabel;
    LColorTransp: TLabel;
    TBBalance: TTrackBar;
    procedure CBVisibleClick(Sender: TObject);
    procedure CBDirectionChange(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure BCancelClick(Sender: TObject);
    procedure BSwapClick(Sender: TObject);
    procedure CBMidClick(Sender: TObject);
    procedure BMidClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure TrackBar1Change(Sender: TObject);
    procedure TrackBar2Change(Sender: TObject);
    procedure BStartClick(Sender: TObject);
    procedure BEndClick(Sender: TObject);
    procedure DirectionsChangeChart(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure SBTranspChange(Sender: TObject);
    procedure CBSubVisibleClick(Sender: TObject);
    procedure EAngleChange(Sender: TObject);
    procedure TBAngleChange(Sender: TObject);
    procedure PageControl1Change(Sender: TObject);
    procedure GalleryChangeChart(Sender: TObject);
    procedure CBSameAsEndClick(Sender: TObject);
    procedure Draw3D1Resize(Sender: TObject);
    procedure Draw3D1AfterDraw(Sender: TObject);
    procedure Draw3D1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure Draw3D1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure BColorClick(Sender: TObject);
    procedure ColorsMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure TrackTranspChange(Sender: TObject);
    procedure Draw3D1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure BDeleteColorClick(Sender: TObject);
    procedure TBBalanceChange(Sender: TObject);
  private
    { Private declarations }
    Backup : TCustomTeeGradient;
    IDragging  : Integer;
    IModified  : Boolean;
    IOnlyStart : Boolean;
    SettingProps : Boolean;

    procedure ApplyChart(const Chart:TGalleryChart);
    procedure CheckButtonColor(Index:Integer);
    procedure CheckDirection;
    procedure CheckVisible;
    function ColorHandler(Index:Integer):TRect;
    Function IsRectGradient:Boolean;
    function PointInColor(X,Y:Integer):Integer;
    procedure SelectDirection;
    procedure SetDirectionGradients;
    procedure SetLabelBalance;
    procedure SetModified;
  protected
    FOnChangedGradient : TNotifyEvent;

    procedure RefreshControls; virtual;
    procedure SetPreview; virtual;
  public
    { Public declarations }
    TheGradient : TCustomTeeGradient;

    Constructor CreateCustom(const AOwner:TComponent; const AGradient:TCustomTeeGradient; OnlyStart:Boolean=False);

    procedure CheckFull(IsOnlyStart:Boolean);
    class procedure DefaultGradient(const Gradient:TCustomTeeGradient;
                                    IsRectGradient:Boolean; Index:Integer);
    Procedure RefreshGradient(const AGradient:TCustomTeeGradient); virtual;

    class function InsertForm(const AGradient:TCustomTeeGradient; const AParent:TWinControl):TTeeGradientEditor;

    property OnChangedGradient:TNotifyEvent read FOnChangedGradient write FOnChangedGradient;
  end;

Function EditTeeGradient(const AOwner:TComponent; const AGradient:TCustomTeeGradient):Boolean; overload;
Function EditTeeGradient(const AOwner:TComponent; const AGradient:TCustomTeeGradient;
                         OnlyStart:Boolean; HideVisible:Boolean=False):Boolean; overload;

const
  TeeMaxSampleGradient=17;

implementation

{$IFNDEF LCL}
{$R *.DFM}
{$ELSE}
{$R *.lfm}
{$ENDIF}

uses
  TeeConst, Math, TeePenDlg;

Function EditTeeGradient( const AOwner:TComponent;
                          const AGradient:TCustomTeeGradient):Boolean;
begin
  result:=EditTeeGradient(AOwner,AGradient,False,False);
end;

function CreateGradientEditor( const AOwner:TComponent;
                               const AGradient:TCustomTeeGradient;
                               OnlyStart:Boolean;
                               HideVisible:Boolean=False):TTeeGradientEditor;
begin
  result:=TeeCreateForm(TTeeGradientEditor,AOwner) as TTeeGradientEditor;

  with result do
  begin
    Tag:=ObjectToTag(AGradient);
    IOnlyStart:=OnlyStart;
    CBVisible.Visible:=not HideVisible;
  end;
end;

Function EditTeeGradient( const AOwner:TComponent;
                          const AGradient:TCustomTeeGradient;
                          OnlyStart:Boolean;
                          HideVisible:Boolean=False):Boolean;
begin
  With CreateGradientEditor(AOwner,AGradient,OnlyStart,HideVisible) do
  try
    result:=ShowModal=mrOk;
  finally
    Free;
  end;
end;

Constructor TTeeGradientEditor.CreateCustom(const AOwner:TComponent; const AGradient:TCustomTeeGradient; OnlyStart:Boolean=False);
Begin
  inherited Create(AOwner);
  TheGradient:=AGradient;

  Tag:=ObjectToTag(TheGradient);

  IOnlyStart:=OnlyStart;

  PanelButtons.Visible:=False;
  BOk.Visible:=False;
  BCancel.Visible:=False;
  Height:=Height-BOk.Height;
end;

procedure TTeeGradientEditor.CheckVisible;
Begin
  EnableControls(IOnlyStart or TheGradient.Visible,
                 [CBDirection,BStart,CBMid,BMid,BEnd,BSwap,Gallery]);

  Draw3D1.Visible:=TheGradient.Visible;
end;

procedure TTeeGradientEditor.CheckDirection;
var tmp : Boolean;
begin
  With TheGradient do
  begin
    tmp:=(Direction=gdFromCenter) or
         (Direction=gdRadial) or
         (Direction=gdFromTopLeft) or
         (Direction=gdFromBottomLeft);

    EnableControls(IOnlyStart or Visible and (not tmp),[CBMid,BMid]);
    EnableControls(Direction=gdRadial,[Label2,Label3,TrackBar1,TrackBar2]);
  end;
end;

procedure TTeeGradientEditor.CBVisibleClick(Sender: TObject);
begin
  TheGradient.Visible:=CBVisible.Checked;
  CheckVisible;
  SetPreview;
end;

procedure TTeeGradientEditor.CBDirectionChange(Sender: TObject);
begin
  TheGradient.Direction:=TGradientDirection(CBDirection.ItemIndex);
  CheckDirection;

  if not IsRectGradient then Gallery.SelectedChart:=nil;

  SetPreview;

  if Directions.Charts.Count>0 then
     Directions.SelectChart(Directions[CBDirection.ItemIndex]);
end;

class function TTeeGradientEditor.InsertForm(const AGradient:TCustomTeeGradient; const AParent:TWinControl):TTeeGradientEditor;
begin
  result:=CreateCustom(AParent.Owner,AGradient);
  result.Align:=alClient;
  AddFormTo(result,AParent,AGradient);
end;

Procedure TTeeGradientEditor.RefreshGradient(const AGradient:TCustomTeeGradient);
begin
  SettingProps:=True;
  Tag:=ObjectToTag(AGradient);

  TheGradient:=AGradient;

  if Assigned(TheGradient) then
  begin
    FreeAndNil(Backup);

    Backup:=TChartGradient.Create(nil);
    Backup.Assign(TheGradient);

    BStart.LinkProperty(TheGradient,'StartColor');
    BMid.LinkProperty(TheGradient,'MidColor');
    BEnd.LinkProperty(TheGradient,'EndColor');

    RefreshControls;

    CheckVisible;
    CheckDirection;

    SelectDirection;

    CheckButtonColor(0);
  end;

  SettingProps:=False;
end;

procedure TTeeGradientEditor.SetLabelBalance;
begin
  LabelBalance.Caption:=FormatFloat(TeeMsg_DefPercentFormat,TheGradient.Balance);
end;

procedure TTeeGradientEditor.RefreshControls;
begin
  With TheGradient do
  begin
    TBBalance.Position:=Balance;
    SetLabelBalance;

    CBVisible.Checked:=Visible;
    CBDirection.ItemIndex:=Ord(Direction);
    CBMid.Checked:=MidColor=clNone;
    TrackBar1.Position:=RadialX;
    LRadialX.Caption:=IntToStr(RadialX);
    TrackBar2.Position:=RadialY;
    LRadialY.Caption:=IntToStr(RadialY);
    UDAngle.Position:=Angle;
    TBAngle.Position:=Angle;

    CBSameAsEnd.Checked:=StartIsEnd;
    BStart.Enabled:=not CBSameAsEnd.Checked;

    // SubGradient
    BSubEdit.LinkGradient(SubGradient);
    SBTransp.Position:=SubGradient.Transparency;
    CBSubVisible.Checked:=SubGradient.Visible;
  end;

  //SetDirectionGradients;
  SetPreview;
end;

procedure TTeeGradientEditor.SetDirectionGradients;
var t : Integer;
    tmp : TTeeCustomShape;
begin
  if Directions.Charts.Count>0 then
  begin
    for t:=0 to Directions.Charts.Count-1 do
    begin
      tmp:=Directions[t].BackWall;
      tmp.Gradient.Assign(TheGradient);
      tmp.Gradient.Visible:=True;
      tmp.Gradient.Direction:=TGradientDirection(t);
    end;

    if CBDirection.ItemIndex>-1 then
       Directions.SelectChart(Directions[CBDirection.ItemIndex]);
  end;
end;

procedure TTeeGradientEditor.CheckFull(IsOnlyStart:Boolean);
begin
  IOnlyStart:=IsOnlyStart;

  BEnd.Visible:=not IOnlyStart;
  BSwap.Visible:=BEnd.Visible;

  CBSameAsEnd.Visible:=not IOnlyStart;

  if BSwap.Visible then
     CBSameAsEnd.Left:=BSwap.Left+BSwap.Width+30
  else
     CBSameAsEnd.Left:=BSwap.Left;
end;

procedure TTeeGradientEditor.FormShow(Sender: TObject);
begin
  CheckFull(IOnlyStart);

  if Assigned(TheGradient) then
     RefreshGradient(TheGradient)
  else
     RefreshGradient(TCustomTeeGradient(Tag));

  IModified:=False;
  TeeTranslateControl(Self);
end;

procedure TTeeGradientEditor.BCancelClick(Sender: TObject);
begin
  if IModified then
  begin
    TheGradient.Assign(Backup);
    TheGradient.Changed(Self);
  end;
end;

procedure TTeeGradientEditor.BSwapClick(Sender: TObject);
var tmp : TColor;
begin
  with TheGradient do
  begin
    tmp:=StartColor;
    StartColor:=EndColor;
    EndColor:=tmp;
  end;

  SetPreview;
end;

procedure TTeeGradientEditor.CBMidClick(Sender: TObject);
begin
  if not SettingProps then
  begin
    if CBMid.Checked then
       TheGradient.MidColor:=clNone
    else
    begin
      TheGradient.UseMiddleColor;

      if TheGradient.MidColor=clNone then
         TheGradient.MidColor:=clWhite;
    end;

    SetPreview;
  end;
end;

procedure TTeeGradientEditor.BMidClick(Sender: TObject);
begin
  CBMid.Checked:=TheGradient.MidColor=clNone;
  SetPreview;
end;

procedure TTeeGradientEditor.FormCreate(Sender: TObject);
begin
  {$IFDEF D7}
  PageControl1.DoubleBuffered:=True;
  {$ENDIF}

  Align:=alClient;

  IDragging:=-1;
  BColor.Tag:=-1;

  PageControl1.ActivePage:=TabColors;
end;

procedure TTeeGradientEditor.SetModified;
begin
  IModified:=True;

  if Assigned(FOnChangedGradient) then
     FOnChangedGradient(Self);
end;

procedure TTeeGradientEditor.TrackBar1Change(Sender: TObject);
begin
  SetModified;
  TheGradient.RadialX:=TrackBar1.Position;
  LRadialX.Caption:=IntToStr(TheGradient.RadialX);
end;

procedure TTeeGradientEditor.TrackBar2Change(Sender: TObject);
begin
  SetModified;
  TheGradient.RadialY:=TrackBar2.Position;
  LRadialY.Caption:=IntToStr(TheGradient.RadialY);
end;

procedure TTeeGradientEditor.BStartClick(Sender: TObject);
begin
  SetPreview;
end;

procedure TTeeGradientEditor.BEndClick(Sender: TObject);
begin
  SetPreview;
end;

procedure TTeeGradientEditor.SetPreview;
begin
  SetDirectionGradients;

  BStart.Invalidate;
  BMid.Invalidate;
  BEnd.Invalidate;

  Draw3D1.Visible:=TheGradient.Visible;

  if Draw3D1.Visible then
  begin
    Colors.Gradient.Colors:=TheGradient.Colors;
    Colors.Invalidate;
    Draw3D1.Invalidate;
    BColor.Invalidate;
  end;

  if not SettingProps then
  begin
    TheGradient.Colors.Repaint;
    SetModified;
  end;
end;

Function TTeeGradientEditor.IsRectGradient:Boolean;
begin
  result:= (TheGradient.Direction=gdTopBottom) or
           (TheGradient.Direction=gdBottomTop) or
           (TheGradient.Direction=gdLeftRight) or
           (TheGradient.Direction=gdRightLeft);
end;

class procedure TTeeGradientEditor.DefaultGradient(const Gradient:TCustomTeeGradient;
                                         IsRectGradient:Boolean; Index:Integer);

  Procedure DefaultGradient(AStart,AMid,AEnd:TColor;
                            ADirection:TGradientDirection=gdTopBottom;
                            ABalance:Integer=50);
  begin
    Gradient.ResetColors;
    Gradient.StartColor:=AStart;
    Gradient.MidColor:=AMid;
    Gradient.EndColor:=AEnd;

    if (AMid<>clNone) and (not IsRectGradient) then
       Gradient.Direction:=gdTopBottom;

    Gradient.Direction:=ADirection;
    Gradient.Balance:=ABalance;
  end;

begin
  case Index of
    0: DefaultGradient($00DDDFD2,$00F50A97,$000B80F4);
    1: DefaultGradient(clSilver,clWhite,clDkGray);
    2: DefaultGradient(clRed,clNone,clYellow);
    3: DefaultGradient(clBlack,$00FF8080,clBlack,gdBottomTop,74);
    4: DefaultGradient($00006AD5,clWhite,$000062C4,gdBottomTop,4);
    5: DefaultGradient($00FFFF80,$00FF8080,clNavy,gdBottomTop,55);
    6: DefaultGradient(clWhite,$00800040,clBlack,gdTopBottom,40);
    7: DefaultGradient($00A50320,$00800040,clWhite,gdFromTopLeft);
    8: DefaultGradient($00159902,clSilver,$00D9F986,gdTopBottom);
    9: DefaultGradient($00BD3881,$0087607A,$0052EB85,gdTopBottom);
   10: DefaultGradient($00B85A06,$00A7D8AF,$00001042,gdTopBottom);
   11: DefaultGradient($00A11EE8,$000F8355,$00DD011A,gdTopBottom);
   12: DefaultGradient($00247489,$009491F6,$00FD8B9D);
   13: DefaultGradient($009A414B,$00732FF3,$0020D761);
   14: DefaultGradient($004C031C,$00BACBE1,$00291EF9);
   15: DefaultGradient($00265FB7,$00CE7185,$00604457);
   16: DefaultGradient($00FFF3EA,$00E0E6E9,$00CEDBFF);
   TeeMaxSampleGradient: DefaultGradient(clRed,clYellow,clGreen);
  end;
end;

procedure TTeeGradientEditor.DirectionsChangeChart(Sender: TObject);
var tmp : Integer;
begin
  tmp:=Directions.Charts.IndexOf(Directions.SelectedChart);
  TheGradient.Direction:=TGradientDirection(tmp);
  CBDirection.ItemIndex:=tmp;

  SetModified;
  CheckDirection;
end;

{ TPreviewGradient }

procedure TPreviewGradient.InternalDraw(const UserRectangle: TRect);
begin
  PanelPaint(UserRectangle);
end;

{ TButtonGradient }

procedure TButtonGradient.Click;
var tmp : Boolean;
begin
  if Assigned(Instance) then
  begin
    tmp:=Editor.ShowModal=mrOk;
    try
      if tmp then
      begin
        Repaint;
        inherited;
      end;
    finally
      FreeAndNil(FEditor);
    end;
  end
  else inherited;
end;

procedure TButtonGradient.DrawSymbol(const ACanvas: TTeeCanvas);
var R : TRect;
begin
  if Enabled and Assigned(Instance) then
  begin
    R:=SymbolRectangle;
    Gradient.Draw(ACanvas,R);

    with ACanvas do
    begin
      Pen.Style:=psSolid;

      if Gradient.Visible then
         Pen.Color:=clBlack
      else
         Pen.Color:=clDkGray;

      Brush.Style:=bsClear;
      Rectangle(R);
    end;
  end;
end;

procedure TButtonGradient.EditorDestroy(Sender:TObject);
begin
  if Assigned(FOldDestroy) then
     FOldDestroy(FEditor);

  FEditor:=nil;
end;

Function TButtonGradient.GetEditor:TTeeGradientEditor;
begin
  if not Assigned(FEditor) then
  begin
    FEditor:=CreateGradientEditor(Self,Gradient,OnlyStart);
    FOldDestroy:=FEditor.OnDestroy;
    FEditor.OnDestroy:=EditorDestroy;
  end;

  result:=FEditor;
end;

function TButtonGradient.GetGradient: TCustomTeeGradient;
begin
  result:=TCustomTeeGradient(Instance);
end;

procedure TButtonGradient.LinkGradient(const Value: TCustomTeeGradient);
begin
  LinkProperty(Value,'');
  Invalidate;
end;

procedure TTeeGradientEditor.FormDestroy(Sender: TObject);
begin
  //FreeAndNil(Preview);
  Backup.Free;
end;

procedure TTeeGradientEditor.SBTranspChange(Sender: TObject);
begin
  TheGradient.SubGradient.Transparency:=SBTransp.Position;
end;

procedure TTeeGradientEditor.CBSubVisibleClick(Sender: TObject);
begin
  TheGradient.SubGradient.Visible:=CBSubVisible.Checked;
end;

procedure TTeeGradientEditor.EAngleChange(Sender: TObject);
begin
  if Showing then
  begin
    TheGradient.Angle:=UDAngle.Position;
    TBAngle.Position:=UDAngle.Position;
  end;
end;

procedure TTeeGradientEditor.TBAngleChange(Sender: TObject);
begin
  if Showing then
  begin
    TheGradient.Angle:=TBAngle.Position;
    UDAngle.Position:=TBAngle.Position;
    SetModified;
  end;
end;

procedure TTeeGradientEditor.ApplyChart(const Chart:TGalleryChart);
begin
  with Chart do
  begin
    Title.Text.Clear;
    View3D:=False;
    Axes.Visible:=False;
    BackWall.Gradient.Visible:=True;
    BackWall.Transparent:=False;
    MarginLeft:=16;
    MarginTop:=22;
    MarginRight:=16;
    MarginBottom:=22;
  end;
end;

procedure TTeeGradientEditor.PageControl1Change(Sender: TObject);

  procedure AddDirectionGallery;
  var t : TGradientDirection;
      tmp : TGalleryChart;
  begin
    //Directions.DisplaySub:=False;
    Directions.NumRows:=2;
    Directions.NumCols:=5;

    for t:=Low(TGradientDirection) to High(TGradientDirection) do
    begin
      tmp:=TGalleryChart.Create(Directions);
      Directions.Charts.Add(tmp);
      tmp.Parent:=Directions;

      tmp.Hint:=CBDirection.Items[Ord(t)];
      tmp.ShowHint:=True;

      Directions.FinishAdd(tmp);
      tmp.OnEnter:=nil;

      ApplyChart(tmp);

      tmp.BackWall.Gradient.Direction:=TGradientDirection(t);
    end;

    Directions.ResizeCharts;

    TeeTranslateControl(Directions);

    SetDirectionGradients;
    SelectDirection;
  end;

  Procedure AddGallery;
  var t : Integer;
      tmp : TGalleryChart;
  begin
    Gallery.DisplaySub:=False;
    Gallery.NumRows:=4;
    Gallery.NumCols:=4;

    for t:=0 to TeeMaxSampleGradient do
    begin
      tmp:=TGalleryChart.Create(Self);
      Gallery.Charts.Add(tmp);
      tmp.Parent:=Gallery;
      Gallery.FinishAdd(tmp);
      tmp.OnEnter:=nil;
      ApplyChart(tmp);
      DefaultGradient(tmp.BackWall.Gradient,True,t);
    end;

    Gallery.ResizeCharts;
  end;

begin
  if PageControl1.ActivePage=TabDirections then
  begin
    if Directions.Charts.Count=0 then
       AddDirectionGallery;
  end
  else
  if PageControl1.ActivePage=TabGallery then
  begin
    if Gallery.Charts.Count=0 then
       AddGallery;
  end;
end;

procedure TTeeGradientEditor.SelectDirection;
begin
  if Assigned(TheGradient) then
     if Directions.Charts.Count>0 then
        Directions.SelectChart(Directions[Ord(TheGradient.Direction)]);
end;

procedure TTeeGradientEditor.GalleryChangeChart(Sender: TObject);
begin
  if Gallery.SelectedChart<>nil then
  begin
    DefaultGradient(TheGradient, IsRectGradient,
                    Gallery.Charts.IndexOf(Gallery.SelectedChart));

    RefreshControls;
  end;
end;

procedure TTeeGradientEditor.CBSameAsEndClick(Sender: TObject);
begin
  TheGradient.StartIsEnd:=CBSameAsEnd.Checked;
  BStart.Enabled:=not CBSameAsEnd.Checked;
end;

procedure TTeeGradientEditor.Draw3D1Resize(Sender: TObject);
begin
  Colors.Width:=Min(334,Draw3D1.Width-24);
end;

function TTeeGradientEditor.ColorHandler(Index:Integer):TRect;
var tmp,
    y   : Integer;
begin
  y:=Colors.Top+Colors.Height+1;
  tmp:=Colors.Left+Round(TheGradient.Colors[Index].Offset*Colors.Width);
  result:=TeeRect(tmp-3,y,tmp+3,y+6);
end;

procedure TTeeGradientEditor.Draw3D1AfterDraw(Sender: TObject);
var t : Integer;
begin
  for t:=0 to TheGradient.Colors.Count-1 do
  begin
    if t=BColor.Tag then
       Draw3D1.Canvas.Pen.Color:=clRed
    else
       Draw3D1.Canvas.Pen.Color:=clBlack;

    Draw3D1.Canvas.ReferenceCanvas.Pen.Color:=Draw3D1.Canvas.Pen.Color;

    Draw3D1.Canvas.Rectangle(ColorHandler(t));
  end;
end;

procedure TTeeGradientEditor.Draw3D1MouseMove(Sender: TObject;
  Shift: TShiftState; X, Y: Integer);
var tmp : Double;
begin
  if IDragging<>-1 then
  {$IFNDEF FMX}
  if (IDragging>0) and (IDragging<TheGradient.Colors.Count-1) then
  {$ENDIF} 
  begin
    tmp:=(X-Colors.Left)/Colors.Width;
    if tmp<0 then tmp:=0 else if tmp>1 then tmp:=1;

    TheGradient.Colors[IDragging].Offset:=tmp;

    SetPreview;
  end;

  if PointInColor(X,Y)<>-1 then
     Draw3D1.Cursor:=crHandPoint
  else
     Draw3D1.Cursor:=crDefault;
end;

function TTeeGradientEditor.PointInColor(X,Y:Integer):Integer;
var t : Integer;
begin
  for t:=0 to TheGradient.Colors.Count-1 do
      if PointInRect(ColorHandler(t),X,Y) then
      begin
        result:=t;
        Exit;
      end;

  result:=-1;
end;

procedure TTeeGradientEditor.CheckButtonColor(Index:Integer);
var tmp : Integer;
begin
  BColor.Visible:=Index<>-1;
  TrackTransp.Visible:=BColor.Visible;
  LTransp.Visible:=TrackTransp.Visible;
  LColorTransp.Visible:=TrackTransp.Visible;

  if BColor.Visible then
  begin
    BColor.SymbolColor:=TheGradient.Colors[Index].Color;
    BColor.Tag:=Index;
    TrackTransp.Position:=TheGradient.Colors[Index].Transparency;
    LColorTransp.Caption:=IntToStr(TrackTransp.Position)+' %';
  end
  else
    BColor.Tag:=-1;

  tmp:=TheGradient.Colors.Count;
  BDeleteColor.Visible:=BColor.Visible and
                        ((tmp>3) or ((BColor.Tag>0) and (BColor.Tag<tmp-1)));
end;

procedure TTeeGradientEditor.Draw3D1MouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  IDragging:=PointInColor(X,Y);
  CheckButtonColor(IDragging);
  Draw3D1.Invalidate;
end;

procedure TTeeGradientEditor.BColorClick(Sender: TObject);
begin
  TheGradient.Colors[BColor.Tag].Color:=BColor.SymbolColor;
  SetPreview;
end;

procedure TTeeGradientEditor.ColorsMouseUp(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var tmp : TTeeGradientColor;
begin
  tmp:=TheGradient.Colors.Add((X-Colors.Left)/Colors.Width,clGreen);
  CheckButtonColor(tmp.Index);
  SetPreview;
end;

procedure TTeeGradientEditor.TrackTranspChange(Sender: TObject);
begin
  TheGradient.Colors[BColor.Tag].Transparency:=TrackTransp.Position;
  LColorTransp.Caption:=IntToStr(TrackTransp.Position)+' %';
  SetPreview;
end;

procedure TTeeGradientEditor.Draw3D1MouseUp(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  IDragging:=-1;
end;

procedure TTeeGradientEditor.BDeleteColorClick(Sender: TObject);
begin
  TheGradient.Colors.Delete(BColor.Tag);
  CheckButtonColor(-1);
  SetPreview;
end;

procedure TTeeGradientEditor.TBBalanceChange(Sender: TObject);
begin
  if not SettingProps then
  begin
    SetModified;
    TheGradient.Balance:=TBBalance.Position;
  end;

  SetLabelBalance;
end;

end.

