{==============================================================================

  Copyright (C) 2000-2001 by Evgeny Kryukov
  All rights reserved

  All contents of this file and all other files included in this archive
  are Copyright (C) 2001 Evgeny Kryukov. Use and/or distribution of
  them requires acceptance of the License Agreement.

  See License.txt for licence information

===============================================================================}

unit EpIIBitmapsDsgn;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  DesignIntf, DesignWindows, StdCtrls, ExtCtrls, KsBitmap, KsUtils, EpIIBitmaps,
  Buttons, Grids, ExtDlgs, ComCtrls, DesignEditors;

type

  TEpBitmapsDsgn = class(TDesignWindow)
    btnAdd: TBitBtn;
    btnDelete: TBitBtn;
    Bevel1: TBevel;
    btnClose: TBitBtn;
    OpenBitmap: TOpenPictureDialog;
    BitmapGrid: TDrawGrid;
    procedure FormResize(Sender: TObject);
    procedure btnAddClick(Sender: TObject);
    procedure btnDeleteClick(Sender: TObject);
    procedure BitmapGridDrawCell(Sender: TObject; ACol, ARow: Integer;
      Rect: TRect; State: TGridDrawState);
  private
    { Private declarations }
    FBitmapList: TEpBitmapList;
    procedure BuildGrid;
  protected
  public
    { Public declarations }
  end;

{ IDE Editors }

  TEpBitmapListEditor = class(TDefaultEditor)
  public
    procedure Edit; override;
    procedure ExecuteVerb (Index: Integer); override;
    function GetVerb (Index: Integer): String; override;
    function GetVerbCount: Integer; override;
  end;

var
  EpBitmapsDsgn: TEpBitmapsDsgn;

implementation {===============================================================}

{$R *.DFM}

{ TEpBitmapsDsgn }

procedure TEpBitmapsDsgn.BuildGrid;
begin
  if FBitmapList <> nil then
  begin
    { Set ColCount and RowCount }
    FormResize(Self);
    { }
  end;
end;

procedure TEpBitmapsDsgn.FormResize(Sender: TObject);
begin
  { Calc Grid's ColCount and RowCount }
  if FBitmapList <> nil then
    with BitmapGrid do
    begin
      ColCount := Width div DefaultColWidth;
      RowCount := FBitmapList.Bitmaps.Count div ColCount +
        FBitmapList.Bitmaps.Count mod ColCount;
      { Update }
      Invalidate;
    end;
end;

procedure TEpBitmapsDsgn.BitmapGridDrawCell(Sender: TObject; ACol,
  ARow: Integer; Rect: TRect; State: TGridDrawState);
var
  Cache: TKsBitmap;
  Bitmap: TKsBitmap;
  Index: integer;
  DstRect, SrcRect: TRect;
  Ratio: single;
begin
  { Draw Cell }
  if FBitmapList <> nil then
  begin
    { Calc index }
    Index := ACol + ARow * BitmapGrid.ColCount;
    if Index >= FBitmapList.Bitmaps.Count then Exit;
    { Draw }
    with BitmapGrid do
    begin
      Cache := TKsBitmap.Create;
      try
        Cache.SetSize(DefaultColWidth, DefaultRowHeight);
        Cache.Clear(KColor(clWindow));

        Bitmap := FBitmapList.Bitmaps[Index];
        { Calc SrcRect }
        if (Bitmap.Width <= Cache.Width) and (Bitmap.Height <= Cache.Height) then
        begin
          SrcRect := Classes.Rect(0, 0, Bitmap.Width, Bitmap.Height);
          DstRect := Classes.Rect(0, 0, Bitmap.Width, Bitmap.Height);
          OffsetRect(DstRect, (Cache.Width - Bitmap.Width) div 2,
            (Cache.Height - Bitmap.Height) div 2);
        end
        else
        begin
          if Cache.Width / Bitmap.Width < Cache.Height / Bitmap.Height then
            Ratio := Cache.Width / Bitmap.Width
          else
            Ratio := Cache.Height / Bitmap.Height;

          SrcRect := Classes.Rect(0, 0, Bitmap.Width, Bitmap.Height);
          DstRect := Classes.Rect(0, 0, Trunc(Bitmap.Width * Ratio), Trunc(Bitmap.Height * Ratio));

          OffsetRect(DstRect, (Cache.Width - RectWidth(DstRect)) div 2,
            (Cache.Height - RectHeight(DstRect)) div 2);
        end;
        { Draw bitmap }
        Bitmap.Draw(Cache, DstRect, SrcRect);
        { Draw Select rect }
        if (gdSelected in State) or (gdFocused in State) then
        begin
          Cache.DrawEdge(DstRect, KColor(clRed), KColor(clBlue));
        end;
        { Draw Cache }
        Cache.Draw(Canvas, Rect.Left, Rect.Top);
      finally
        Cache.Free;
      end;
    end;
  end;
end;

procedure TEpBitmapsDsgn.btnAddClick(Sender: TObject);
var
  Picture: TPicture;
  Bitmap: TKsBitmap;
  i: integer;
begin
  if FBitmapList = nil then Exit;
  { Add Bitmap }
  if OpenBitmap.Execute then
  begin
    for i := 0 to OpenBitmap.Files.Count-1 do
    begin
      Picture := TPicture.Create;
      try
        Picture.LoadFromFile(OpenBitmap.Files[i]);
        { }
        Bitmap := TKsBitmap.Create;
        Bitmap.Assign(Picture);
        Bitmap.Name := ExtractFileName(OpenBitmap.FileName);
        { Add }
        FBitmapList.Bitmaps.Add(Bitmap);
      finally
        Picture.Free;
      end;
    end;
    { }
    FormResize(Self);
  end;
end;

procedure TEpBitmapsDsgn.btnDeleteClick(Sender: TObject);
var
  Index: integer;
begin
  if FBitmapList = nil then Exit;
  { Calc index }
  Index := BitmapGrid.Col + BitmapGrid.Row * BitmapGrid.ColCount;
  if Index >= FBitmapList.Bitmaps.Count then Exit;
  { Delete Bitmap }
  FBitmapList.Bitmaps.Delete(Index);
  { Update }
  FormResize(Self);
end;

{ TEpBitmapListEditor =========================================================}

procedure TEpBitmapListEditor.Edit;
var
  Dsgn: TEpBitmapsDsgn;
begin
  if Assigned(Component) then
  begin
    Dsgn := TEpBitmapsDsgn.Create(Application);
    Dsgn.FBitmapList := TEpBitmapList(Component);
    Dsgn.BuildGrid;
    Dsgn.ShowModal;
    Dsgn.Free;

    Designer.Modified;
  end;
end;

procedure TEpBitmapListEditor.ExecuteVerb (Index: Integer);
begin
  if Index = 0 then
    Edit;
end;

function TEpBitmapListEditor.GetVerbCount: Integer;
begin
  Result := 1;
end;

function TEpBitmapListEditor.GetVerb(Index: Integer): String;
begin
  if Index = 0 then
    Result := 'Edit...'
  else
    Result := '';
end;

end.
