{*********************************************}
{  TeeChart Pro Charting Library              }
{  Filters Editor Dialog                      }
{  Copyright (c) 2006-2020 by Steema Software }
{  All Rights Reserved                        }
{*********************************************}
unit TeeFiltersEditor;
{$I TeeDefs.inc}

interface

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

     {$IFDEF D9}
     Types,
     {$ENDIF}

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

     {$IFDEF MSWINDOWS}
     TeeGDIPlus,
     {$ENDIF}

     TeeProcs, TeCanvas, TeePenDlg, TeeDraw3D, TeeFilters, TeEngine, Series, Chart;

type
  TFormItem=class
  public
    PropName : String;
    OnChange : TNotifyEvent;
  end;

  TFormItems=class(TList)
  private
    function Get(Index:Integer):TFormItem;
  public
    Procedure Clear; override;
    property Items[Index:Integer]:TFormItem read Get; default;
  end;

  TFormCreator=class(TComponent,IFormCreator)
  private
    FParent   : TWinControl;
    FOnChange : TNotifyEvent;

    IChanging : Boolean;
    IPosY     : Integer;

    function AddItem(const PropName:String; AOnChange:TNotifyEvent=nil):TFormItem;
    procedure ChangeProp(Sender:TObject; const Value:Variant);
    procedure CheckBoxChanged(Sender:TObject);
    procedure ColorChanged(Sender:TObject);
    procedure ComboChanged(Sender:TObject);
    procedure EditChanged(Sender:TObject);
    procedure ScrollChanged(Sender:TObject);
  public
    Instance : TObject;
    Items    : TFormItems;

    Constructor Create(AOwner:TComponent); override;
    Destructor Destroy; override;

    function AddCheckBox(const PropName,ACaption:String; OnChange:TNotifyEvent=nil):TCheckBox;
    function AddColor(const PropName,ACaption:String):TButton;
    function AddCombo(const PropName:String):TComboBox;
    function AddInteger(const PropName,ACaption:String; AMin,AMax:Integer):TEdit;
    function AddScroll(const PropName:String; AMin,AMax:Integer):TScrollBar;

    property OnChange:TNotifyEvent read FOnChange write FOnChange;
  end;

  TFiltersEditor = class(TForm)
    PageControl1: TPageControl;
    TabSheet1: TTabSheet;
    Splitter1: TSplitter;
    Panel1: TPanel;
    Panel2: TPanel;
    BAdd: TSpeedButton;
    BDelete: TSpeedButton;
    BMoveUp: TSpeedButton;
    BMoveDown: TSpeedButton;
    Filters: TCheckListBox;
    Image: TDraw3D;
    Panel3: TPanel;
    Panel4: TPanel;
    BOK: TButton;
    PageProps: TPageControl;
    Properties: TTabSheet;
    TabRegion: TTabSheet;
    Splitter2: TSplitter;
    Timer1: TTimer;
    Label1: TLabel;
    ELeft: TEdit;
    UDLeft: TUpDown;
    Label2: TLabel;
    ETop: TEdit;
    UDTop: TUpDown;
    Label3: TLabel;
    EWidth: TEdit;
    UDWidth: TUpDown;
    Label4: TLabel;
    EHeight: TEdit;
    UDHeight: TUpDown;
    CBPreview: TComboFlat;
    Label5: TLabel;
    TabHistogram: TTabSheet;
    Chart1: TChart;
    Series1: TFastLineSeries;
    Series2: TFastLineSeries;
    Series3: TFastLineSeries;
    Series4: TFastLineSeries;
    procedure FormCreate(Sender: TObject);
    procedure FiltersClick(Sender: TObject);
    procedure BAddClick(Sender: TObject);
    procedure FiltersClickCheck(Sender: TObject);
    procedure BDeleteClick(Sender: TObject);
    procedure BMoveUpClick(Sender: TObject);
    procedure BMoveDownClick(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure ImageResize(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure CBScaledClick(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure ELeftChange(Sender: TObject);
    procedure ETopChange(Sender: TObject);
    procedure EWidthChange(Sender: TObject);
    procedure EHeightChange(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure CBPreviewChange(Sender: TObject);
    procedure PageControl1Change(Sender: TObject);
  private
    { Private declarations }

    Backup      : TFilterItems;
    Creator     : TFormCreator;
    IBitmap     : TBitmap;
    IChanging   : Boolean;
    HistogramReady : Boolean;

    procedure ClearProperties;
    procedure ChangedProperties(Sender: TObject);
    function CurrentFilter:TTeeFilter;
    procedure EnableButtons;
    procedure Preview;
    procedure RepaintPreview;
    procedure Swap(A,B:Integer);
  public
    { Public declarations }
    Changed     : TNotifyEvent;
    FilterItems : TFilterItems;
    Picture     : TGraphic;

    procedure SetPicture(const APicture:TGraphic);
    class function InsertForm(const APicture:TTeePicture; const AParent:TWinControl):TFiltersEditor;
  end;

function ShowFiltersEditor(const AOwner:TComponent; const APicture:TTeePicture):Boolean; overload;
function ShowFiltersEditor(const AOwner:TComponent; const APicture:TGraphic; const AFilters:TFilterItems):Boolean; overload;

implementation

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

uses
  Math,
  TeeFilterGallery,
  TeeConst,
  TypInfo;

function ShowFiltersEditor(const AOwner:TComponent; const APicture:TGraphic; const AFilters:TFilterItems):Boolean;
begin
  with TFiltersEditor.Create(AOwner) do
  try
    Picture:=APicture;
    FilterItems:=AFilters;
    result:=ShowModal=mrOk;
  finally
    Free;
  end;
end;

function ShowFiltersEditor(const AOwner:TComponent; const APicture:TTeePicture):Boolean;
begin
  result:=ShowFiltersEditor(AOwner,APicture.Graphic,APicture.Filters);

  if result then
     APicture.Repaint;
end;

procedure TFiltersEditor.FormCreate(Sender: TObject);
begin
  IChanging:=True;

  PageControl1.ActivePage:=TabSheet1;
  
  Height:=TeeReadIntegerOption('FiltersHeight',Height);
  Width:=TeeReadIntegerOption('FiltersWidth',Width);

  TeeLoadArrowBitmaps(BMoveUp.Glyph,BMoveDown.Glyph);
  Creator:=TFormCreator.Create(Properties);
  Creator.OnChange:=ChangedProperties;
end;

procedure TFiltersEditor.EnableButtons;
begin
  BDelete.Enabled:=Filters.ItemIndex<>-1;
  BMoveUp.Enabled:=Filters.ItemIndex>0;
  BMoveDown.Enabled:=BDelete.Enabled and (Filters.ItemIndex<Filters.Items.Count-1);
end;

procedure TFiltersEditor.ChangedProperties(Sender: TObject);
begin
  Preview;
end;

procedure TFiltersEditor.ClearProperties;
begin
  with Properties do
       while ControlCount>0 do Controls[0].Free;
end;

type
  TFilterAccess=class(TTeeFilter);

procedure TFiltersEditor.FiltersClick(Sender: TObject);

  procedure CreateProperties;
  var tmp : TTabSheet;
  begin
    if Filters.ItemIndex<>-1 then
    begin
      tmp:=PageProps.ActivePage;

      try
        Creator.Items.Clear;
        Creator.IPosY:=8;
        Creator.Instance:=CurrentFilter;

        Creator.IChanging:=True;
        try
          CurrentFilter.CreateEditor(Creator,ChangedProperties);
        finally
          Creator.IChanging:=False;
        end;

        Properties.TabVisible:=Properties.ControlCount>0;
        TabRegion.TabVisible:=TFilterAccess(Creator.Instance).AllowRegion;

        if (not Properties.TabVisible) and (not TabRegion.TabVisible) then
           PageProps.Hide
        else
        begin
          TeeTranslateControl(Properties);

          PageProps.Show;

          if not Properties.TabVisible then
             tmp:=TabRegion;

          if TabRegion.TabVisible then
          with CurrentFilter.Region do
          begin
            UDLeft.Position:=Left;
            UDTop.Position:=Top;
            UDWidth.Position:=Width;
            UDHeight.Position:=Height;
          end
          else
            tmp:=Properties;
        end;

      finally
        PageProps.ActivePage:=tmp;
      end;
    end;

    PageProps.Visible:=Filters.ItemIndex<>-1;
  end;

begin
  IChanging:=True;
  try
    EnableButtons;
    ClearProperties;
    CreateProperties;
  finally
    IChanging:=False;
  end;
end;

procedure TFiltersEditor.BAddClick(Sender: TObject);
var tmpFilter : TFilterClass;
    tmp       : Integer;
    tmpItem   : TTeeFilter;
begin
  tmpFilter:=TFilterGallery.Choose(Self, Picture);

  if Assigned(tmpFilter) then
  begin
    tmpItem:=tmpFilter.Create(FilterItems);

    tmp:=Filters.Items.AddObject(tmpFilter.Description,tmpItem);

    Filters.Checked[tmp]:=True;
    Filters.ItemIndex:=tmp;
    FiltersClick(Self);

    Preview;
    TeeTranslateControl(Self);

    PageProps.ActivePageIndex:=0;
  end;
end;

procedure TFiltersEditor.RepaintPreview;

  function GetFilteredBitmap:TGraphic;
  begin
    if not Assigned(IBitmap) then
       IBitmap:=TBitmap.Create;

    TTeePicture.AssignGraphic(IBitmap,Picture);

    if Assigned(FilterItems) then
       FilterItems.ApplyTo(IBitmap);

    result:=IBitmap;
  end;

  // Similar to TRectF.Fit:
  function BestFit(const Source:TGraphic):TPoint;
  var SourceRatio : Double;
  begin
    SourceRatio:=Source.Width/Source.Height;

    if (Image.Width/Image.Height)>SourceRatio then
       result:=TeePoint(Round(Image.Height*SourceRatio),Image.Height)
    else
       result:=TeePoint(Image.Width, Round(Image.Width/SourceRatio))
  end;

var tmp : TGraphic;
    P   : TPoint;
begin
  if (Image.BackImage<>nil) and Assigned(Picture) then
  begin
    tmp:=GetFilteredBitmap;
    Image.BackImage.Assign(tmp);

    case CBPreview.ItemIndex of
      0: begin
           Image.BackImageMode:=pbmCustom;
           Image.BackImage.Bounds:=TeeZeroRect;
         end;

      1: begin
           Image.BackImageMode:=pbmCustom;
           P:=BestFit(tmp);
           Image.BackImage.Bounds:=Rect(0,0,P.X,P.Y);
         end;
    else
      Image.BackImageMode:=pbmStretch;
    end;

    (*
    Image.BackImageMode:=pbmCustom;

    tmp:=GetFilteredBitmap;

    case CBPreview.ItemIndex of
       1: begin
            P:=BestFit(tmp);
            TFilterGallery.StretchTo(tmp,Image.BackImage,P.X,P.Y);
          end;
       2: TFilterGallery.StretchTo(tmp,Image.BackImage,Image.Width,Image.Height)
    else
       Image.BackImage.Assign(tmp);
    end;
    *)
  end;
end;

procedure TFiltersEditor.Preview;
begin
  RepaintPreview;

  if Assigned(Changed) then
     Changed(Self);

  if Assigned(Picture) and Assigned(Picture.OnChange) then
     Picture.OnChange(Self);

  // Refresh Histogram, if visible:
  HistogramReady:=False;
  PageControl1Change(Self);
end;

function TFiltersEditor.CurrentFilter:TTeeFilter;
begin
  result:=TTeeFilter(Filters.Items.Objects[Filters.ItemIndex]);
end;

procedure TFiltersEditor.ImageResize(Sender: TObject);
begin
  RepaintPreview;
end;

procedure TFiltersEditor.FiltersClickCheck(Sender: TObject);
begin
  CurrentFilter.Enabled:=Filters.Checked[Filters.ItemIndex];
  Preview;
end;

procedure TFiltersEditor.BDeleteClick(Sender: TObject);
var tmp : Integer;
begin
  tmp:=Filters.ItemIndex;
  CurrentFilter.Free;

  Filters.Items.Delete(Filters.ItemIndex);

  if tmp>=Filters.Items.Count then
     tmp:=Filters.Items.Count-1;

  if tmp>=0 then
  begin
    Filters.ItemIndex:=tmp;
    FiltersClick(Self);
  end
  else
    ClearProperties;

  EnableButtons;
  PageProps.Visible:=Filters.ItemIndex<>-1;

  Preview;
end;

procedure TFiltersEditor.Swap(A,B:Integer);
var tmp : TTeeFilter;
begin
  Filters.Items.Exchange(A,B);
  tmp:=FilterItems.Item[B];
  FilterItems.Item[A].Index:=B;
  tmp.Index:=A;
  EnableButtons;
  Preview;
end;

procedure TFiltersEditor.BMoveUpClick(Sender: TObject);
begin
  with Filters do
  if ItemIndex>0 then
     Swap(ItemIndex,ItemIndex-1);
end;

procedure TFiltersEditor.BMoveDownClick(Sender: TObject);
begin
  with Filters do
  if (ItemIndex<>-1) and (ItemIndex<Items.Count-1) then
     Swap(ItemIndex,ItemIndex+1);
end;

procedure TFiltersEditor.FormShow(Sender: TObject);
var t : Integer;
begin
  Backup:=TFilterItems.Create(Self,TTeeFilter);

  if Assigned(FilterItems) then
  begin
    Backup.Assign(FilterItems);

    for t:=0 to FilterItems.Count-1 do
    begin
      Filters.Items.AddObject(FilterItems[t].Description,FilterItems[t]);
      Filters.Checked[t]:=FilterItems[t].Enabled;
    end;
  end;

  CBPreview.Enabled:=Assigned(Picture);

  PageProps.ActivePage:=Properties;

  if Filters.Items.Count>0 then
  begin
    Filters.ItemIndex:=0;
    FiltersClick(Self);
    Preview;
  end;

  PageProps.Visible:=Filters.Items.Count>0;

  TeeTranslateControl(Self);
end;

procedure TFiltersEditor.FormDestroy(Sender: TObject);
begin
  Creator.Free;
  Backup.Free;
  IBitmap.Free;
end;

procedure TFiltersEditor.CBScaledClick(Sender: TObject);
begin
end;

{ TFormCreator }

Constructor TFormCreator.Create(AOwner:TComponent);
begin
  inherited;
  FParent:=AOwner as TWinControl;
  Items:=TFormItems.Create;
end;

Destructor TFormCreator.Destroy;
begin
  while Items.Count>0 do
  begin
    TFormItem(Items[0]).Free;
    Items.Delete(0);
  end;

  Items.Free;
  inherited;
end;

function TFormCreator.AddCheckBox(const PropName,
  ACaption: String; OnChange:TNotifyEvent=nil): TCheckBox;
begin
  result:=TCheckBox.Create(FParent);

  with result do
  begin
    Parent:=FParent;
    SetBounds(4,IPosY,75,16);
    Caption:=ACaption;

    Checked:=GetPropValue(Instance,PropName);

    OnClick:=CheckBoxChanged;
    Inc(IPosY,Height+2);
    Tag:=ObjectToTag(AddItem(PropName,OnChange));
  end;
end;

function TFormCreator.AddItem(const PropName:String; AOnChange:TNotifyEvent=nil):TFormItem;
begin
  result:=TFormItem.Create;
  result.PropName:=PropName;
  result.OnChange:=AOnChange;
  Items.Add(result);
end;

function TFormCreator.AddScroll(const PropName: String; AMin,
  AMax: Integer): TScrollBar;
begin
  result:=TScrollBar.Create(FParent);

  with TLabel.Create(FParent) do
  begin
    Left:=4;
    Top:=IPosY-2;

    Caption:=PropName;
    Parent:=FParent;
    FocusControl:=result;
    Inc(IPosY,Height);
  end;

  with result do
  begin
    Parent:=FParent;

    SetBounds(4,IPosY,FParent.Width-8,16);

    Min:=AMin;
    Max:=AMax;

    Position:=GetPropValue(Instance,PropName);

    OnChange:=ScrollChanged;
    Inc(IPosY,Height+6);
    Tag:=ObjectToTag(AddItem(PropName));
  end;
end;

procedure TFormCreator.ScrollChanged(Sender:TObject);
begin
  ChangeProp(Sender,(Sender as TScrollBar).Position);
end;

procedure TFormCreator.ComboChanged(Sender:TObject);
begin
  ChangeProp(Sender,(Sender as TComboBox).ItemIndex);
end;

procedure TFormCreator.CheckBoxChanged(Sender:TObject);
begin
  ChangeProp(Sender,(Sender as TCheckBox).Checked);
end;

procedure TFormCreator.ChangeProp(Sender:TObject; const Value:Variant);
var tmp : TFormItem;
begin
  if not IChanging then
  begin
    tmp:=TFormItem((Sender as TComponent).Tag);

    SetPropValue(Instance,tmp.PropName,Value);

    if Assigned(tmp.OnChange) then
       tmp.OnChange(Sender);

    FOnChange(Instance);
  end;
end;

procedure TFormCreator.ColorChanged(Sender:TObject);
begin
  FOnChange(Instance);
end;

procedure TFormCreator.EditChanged(Sender:TObject);
begin
  ChangeProp(Sender,(Sender as TEdit).Text);
end;

function TFormCreator.AddColor(const PropName,ACaption: String): TButton;
begin
  result:=TButtonColor.Create(FParent);

  with result as TButtonColor do
  begin
    Parent:=FParent;
    Caption:=ACaption;
    LinkProperty(Self.Instance,PropName);
    Left:=4;
    Top:=IPosY;
    OnClick:=ColorChanged;
    Inc(IPosY,Height+6);
    Tag:=ObjectToTag(AddItem(PropName));
  end;
end;

function TFormCreator.AddCombo(const PropName: String): TComboBox;

  function GetReadableEnum(const S:String):String;
  var i : Integer;
  begin
    result:=S;

    //if ReadableEnums then
    begin
      while Length(result)>0 do
      begin
        if result[1]=UpCase(result[1]) then
           break
        else
           Delete(result,1,1)
      end;

      i:=2;
      while i<Length(result) do
      begin
        if result[i]=UpCase(result[i]) then
        begin
          Insert(' ',result,i);
          Inc(i,2);
        end
        else
           Inc(i);
      end;

      if result='' then
         result:=S;
    end;
  end;

var P  : PPropInfo;
    D  : PTypeData;
    t  : Integer;
    P2 : PTypeInfo;
begin
  result:=TComboFlat.Create(FParent);

  with result do
  begin
    Parent:=FParent;
    SetBounds(4,IPosY,Parent.Width-8,Height);
    Style:=csDropDownList;
    Inc(IPosY,Height+6);
    OnChange:=ComboChanged;

    P:=GetPropInfo(Instance,PropName);

    if Assigned(P) then
    begin
      P2:=P.PropType{$IFNDEF LCL}^{$ENDIF};

      // Warning: BaseType pending at VCL.Net TypInfo.pas
      D:=GetTypeData(GetTypeData(P2).BaseType{$IFNDEF LCL}^{$ENDIF});

      for t:=D.MinValue to D.MaxValue do
          Items.Add(GetReadableEnum(GetEnumName(P2, t)));

      ItemIndex:=GetEnumValue(P2,GetPropValue(Instance,PropName));
    end;

    Tag:=ObjectToTag(Self.AddItem(PropName));
  end;
end;

function TFormCreator.AddInteger(const PropName,ACaption:String; AMin,AMax:Integer): TEdit;
const
  SameRow=True;
begin
  result:=TEdit.Create(FParent);

  with TLabel.Create(FParent) do
  begin
    Parent:=FParent;
    Left:=4;
    Top:=IPosY+4;

    if ACaption='' then Caption:=PropName
                   else Caption:=ACaption;

    if not SameRow then
       Inc(IPosY,Height+2);

    FocusControl:=result;

    if Pos(cHotKeyPrefix,Caption)=0 then
       Caption:=cHotKeyPrefix+Caption;
  end;

  with result do
  begin
    Parent:=FParent;

    if SameRow then
       SetBounds(44,IPosY,Parent.Width-52-16,Height)
    else
       SetBounds(4,IPosY,Parent.Width-8-16,Height);

    Inc(IPosY,Height+6);
    OnChange:=EditChanged;
    Tag:=ObjectToTag(Self.AddItem(PropName));

    with TUpDown.Create(FParent) do
    begin
      Parent:=FParent;
      Handle;
      Associate:=result;
      Max:=AMax;
      Min:=AMin;

      Position:=GetPropValue(Instance,PropName);
    end;
  end;
end;

procedure TFiltersEditor.Timer1Timer(Sender: TObject);
begin
  Timer1.Enabled:=False;
  FiltersClick(Self);
end;

procedure TFiltersEditor.ELeftChange(Sender: TObject);
begin
  if not IChanging then
  begin
    CurrentFilter.Region.Left:=UDLeft.Position;
    ChangedProperties(Self);
  end;
end;

procedure TFiltersEditor.ETopChange(Sender: TObject);
begin
  if not IChanging then
  begin
    CurrentFilter.Region.Top:=UDTop.Position;
    ChangedProperties(Self);
  end;
end;

procedure TFiltersEditor.EWidthChange(Sender: TObject);
begin
  if not IChanging then
  begin
    CurrentFilter.Region.Width:=UDWidth.Position;
    ChangedProperties(Self);
  end;
end;

procedure TFiltersEditor.EHeightChange(Sender: TObject);
begin
  if not IChanging then
  begin
    CurrentFilter.Region.Height:=UDHeight.Position;
    ChangedProperties(Self);
  end;
end;

{ TFormItems }

procedure TFormItems.Clear;
var t : Integer;
begin
  for t:=0 to Count-1 do Items[t].Free;
  inherited;
end;

function TFormItems.Get(Index: Integer): TFormItem;
begin
  result:=TFormItem({$IFOPT R-}List{$ELSE}inherited Items{$ENDIF}[Index]);
end;

procedure TFiltersEditor.FormClose(Sender: TObject;
  var Action: TCloseAction);
begin
  if WindowState<>wsMaximized then
  begin
    TeeSaveIntegerOption('FiltersHeight',Height);
    TeeSaveIntegerOption('FiltersWidth',Width);
  end;
end;

procedure TFiltersEditor.CBPreviewChange(Sender: TObject);
begin
  if CBPreview.ItemIndex=3 then
     Image.BackImage:=nil
  else
     Preview;
end;

procedure TFiltersEditor.PageControl1Change(Sender: TObject);

  procedure CreateHistogram;
  var t,
      x,y : Integer;
      bins : Array[0..3,0..255] of Integer;

      {$IFNDEF FMX}
      IsRGBA : Boolean;
      Lines          : TRGBArray;
      {$ENDIF}
      LinesRGBA      : TRGBAArray;
  begin
    Chart1.SeriesList.ClearValues;

    if Assigned(IBitmap) then
    begin
      for t:=0 to 3 do
          for x:=0 to 255 do
              bins[t,x]:=0;

      {$IFDEF FMX}
      TeeCalcLines(LinesRGBA,IBitmap)
      {$ELSE}
      IsRGBA:=IBitmap.PixelFormat=pf32bit;
      Series4.Visible:=IsRGBA;

      if IsRGBA then
         TeeCalcLines(LinesRGBA,IBitmap)
      {$IFDEF LCL}
          ;
      {$ELSE}
      else
         TeeCalcLines(Lines,IBitmap);
      {$ENDIF}
      {$ENDIF}

      {$IFOPT R+}
      {$DEFINE WASRANGE}
      {$ENDIF}
      {$R-}

      for y:=0 to IBitmap.Height-1 do
          for x:=0 to IBitmap.Width-1 do
          {$IFNDEF FMX}
          if IsRGBA then
          {$ENDIF}
             with LinesRGBA[y,x] do
             begin
               Inc(bins[0,Red]);
               Inc(bins[1,Green]);
               Inc(bins[2,Blue]);
               Inc(bins[3,Alpha]);
             end
          {$IFNDEF FMX}
          else
             with Lines[y,x] do
             begin
               Inc(bins[0,Red]);
               Inc(bins[1,Green]);
               Inc(bins[2,Blue]);
             end;
          {$ENDIF}

      {$IFDEF FMX}
      ;
      {$ENDIF}

      {$IFDEF WASRANGE}
      {$R+}
      {$ENDIF}
      
      for t:=0 to 3 do
      begin
        Chart1[t].BeginUpdate;

        for x:=0 to 255 do
            Chart1[t].Add(bins[t,x]);

        Chart1[t].EndUpdate;
      end;
    end;
  end;

begin
  if PageControl1.ActivePage=TabHistogram then
     if not HistogramReady then
     begin
       CreateHistogram;
       HistogramReady:=True;
     end;
end;

class function TFiltersEditor.InsertForm(const APicture: TTeePicture;
  const AParent: TWinControl): TFiltersEditor;
begin
  result:=TFiltersEditor.Create(AParent.Owner);
  result.Picture:=APicture.Graphic;
  result.FilterItems:=APicture.Filters;

  result.BOK.Visible:=False;

  result.Align:=alClient;
  
  AddFormTo(result,AParent);
end;

procedure TFiltersEditor.SetPicture(const APicture: TGraphic);
begin
  Picture:=APicture;
  RepaintPreview;
  HistogramReady:=False;
end;

end.
