unit uDemoFeatured;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  uMASelectionManager, uMASelectionCreator, jpeg, ExtCtrls, Menus, ComCtrls,
  StdCtrls, uMATypeLibrary, ImgList, uMAClasses, uMASelectionControl, uMARoutines,
  Spin, Buttons, uInsertText, ToolWin, ExtDlgs,uGenericClasses;

type
  TfrmDemoFeatured = class(TForm)
    ScrollBox1: TScrollBox;
    ImgMain: TImage;
    MainMenu1: TMainMenu;
    File1: TMenuItem;
    Exit1: TMenuItem;
    N2: TMenuItem;
    PrintSetup1: TMenuItem;
    Print1: TMenuItem;
    N3: TMenuItem;
    SaveAs1: TMenuItem;
    Save1: TMenuItem;
    Open1: TMenuItem;
    New1: TMenuItem;
    Selection1: TMenuItem;
    Help1: TMenuItem;
    SelectAll1: TMenuItem;
    SelectNone1: TMenuItem;
    ImportMask1: TMenuItem;
    N1: TMenuItem;
    ExportMask1: TMenuItem;
    N4: TMenuItem;
    Invert1: TMenuItem;
    SelectionControl1: TSelectionControl;
    SelectionCreator1: TSelectionCreator;
    SelectionManager1: TSelectionManager;
    ColorDialog: TColorDialog;
    OPD: TOpenPictureDialog;
    SPD: TSavePictureDialog;
    CoolBarTop: TCoolBar;
    ToolBarTop: TToolBar;
    btnOpenImage: TSpeedButton;
    btnSaveImage: TSpeedButton;
    btnReload: TSpeedButton;
    CoolBarLeft: TCoolBar;
    ToolBar1: TToolBar;
    PanelLeft: TPanel;
    Shape2: TShape;
    Shape1: TShape;
    btnSelectionShape: TSpeedButton;
    btnArrow: TSpeedButton;
    btnSelectionFreehand: TSpeedButton;
    btnSelectionP2P: TSpeedButton;
    btnSelectionMagicWand: TSpeedButton;
    btnSelectionText: TSpeedButton;
    btnPen: TSpeedButton;
    btnCrop: TSpeedButton;
    btnEyeDrop: TSpeedButton;
    btnFloodFill: TSpeedButton;
    Shape3: TShape;
    Shape4: TShape;
    chkLockToImage: TCheckBox;
    btnExtractData: TBitBtn;
    Panel6: TPanel;
    sBackGround: TShape;
    sForeGround: TShape;
    imgSwapColors: TImage;
    imgBW: TImage;
    CoolBarRight: TCoolBar;
    About1: TMenuItem;
    ToolBar3: TToolBar;
    pnlControlPanel: TPanel;
    Shape5: TShape;
    Label8: TLabel;
    Label9: TLabel;
    Label10: TLabel;
    Label1: TLabel;
    Label2: TLabel;
    Shape6: TShape;
    NotebookMA: TNotebook;
    lblCornerRounding: TLabel;
    Label12: TLabel;
    seRoundCorner: TSpinEdit;
    cbToolShape: TComboBox;
    lblMagicWandTolerance: TLabel;
    tbMagicWandTolerance: TTrackBar;
    cbLinePattern: TComboBox;
    seSpeed: TSpinEdit;
    cbDirection: TComboBox;
    NotebookTO: TNotebook;
    Label3: TLabel;
    Label7: TLabel;
    cbLineWidth: TComboBox;
    cbLineStyle: TComboBox;
    lblFillTolerance: TLabel;
    tbFillTolerance: TTrackBar;
    btnZoomIn: TSpeedButton;
    btnZoomOut: TSpeedButton;
    StatusBar1: TStatusBar;
    procedure FormCreate(Sender: TObject);
    procedure cbLinePatternChange(Sender: TObject);
    procedure cbToolShapeChange(Sender: TObject);
    procedure seSpeedChange(Sender: TObject);
    procedure seRoundCornerChange(Sender: TObject);
    procedure cbDirectionChange(Sender: TObject);
    procedure btnSelectionToolClick(Sender: TObject);
    procedure SelectionManager1MouseUp(Sender: TObject; Button: TMouseButton;
              Shift: TShiftState; X, Y: Integer);
    procedure SelectionManager1MouseMove(Sender: TObject; Shift: TShiftState; X,
              Y: Integer);
    procedure SelectionManager1MouseDown(Sender: TObject; Button: TMouseButton;
              Shift: TShiftState; X, Y: Integer);
    procedure btnReloadClick(Sender: TObject);
    procedure SelectionManager1SelectionChange(Sender: TObject; Region: HRGN);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure chkLockToImageClick(Sender: TObject);
    procedure btnExtractDataClick(Sender: TObject);
    procedure FormActivate(Sender: TObject);
    procedure ScrollBox1Resize(Sender: TObject);
    procedure SelectionControl1MouseMove(Sender: TObject; Shift: TShiftState; X,Y: Integer);
    procedure Invert1Click(Sender: TObject);
    procedure SelectAll1Click(Sender: TObject);
    procedure SelectNone1Click(Sender: TObject);
    procedure SelectionControl1MouseDown(Sender: TObject; Button: TMouseButton;
              Shift: TShiftState; X, Y: Integer);
    procedure SelectionControl1MouseUp(Sender: TObject; Button: TMouseButton;
              Shift: TShiftState; X, Y: Integer);
    procedure btnToolClick(Sender: TObject);
    procedure btnArrowClick(Sender: TObject);
    procedure imgSwapColorsClick(Sender: TObject);
    procedure imgBWClick(Sender: TObject);
    procedure About1Click(Sender: TObject);
    procedure cbLineWidthDrawItem(Control: TWinControl;
              Index: Integer; Rect: TRect; State: TOwnerDrawState);
    procedure cbLineStyleDrawItem(Control: TWinControl;
              Index: Integer; Rect: TRect; State: TOwnerDrawState);
    procedure tbMagicWandToleranceChange(Sender: TObject);
    procedure tbFillToleranceChange(Sender: TObject);
    procedure ExportMask1Click(Sender: TObject);
    procedure ImportMask1Click(Sender: TObject);
    procedure ColorSelectionMouseDown(Sender: TObject; Button: TMouseButton;
              Shift: TShiftState; X, Y: Integer);
    procedure btnOpenImageClick(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure btnZoomInClick(Sender: TObject);
    procedure btnZoomOutClick(Sender: TObject);
    procedure btnSaveImageClick(Sender: TObject);
    procedure btnCropClick(Sender: TObject);
  private
    Drawing: Boolean;
    ImageZoom : TImageZoom;
    procedure DisplayHint(Sender: TObject);
    procedure AddAdditionalCursors;
    procedure ImageZoomChange(Sender : TObject);
    procedure UpdateDataResizingAndPositioning;
    procedure UpdateMagicWandBitmap;
  public
  end;

const
  FileName : string = 'castlefull.bmp';

var
  frmDemoFeatured: TfrmDemoFeatured;

implementation

uses uExtractData, uGraphicsRoutines, uGenericRoutines, uAbout;

{$R *.DFM}
{$R CURSORS.RES}

(******************************************************************************)
(* Cursors in additional to those built into MarchingAnts *********************)
(******************************************************************************)

const
  // Unique ID's - assumed not being used by the system
  CRZOOMOUT   = 1101; // Not used as of yet in this demo
  CRZOOMIN    = 1102; // Not used as of yet in this demo
  CRPATH      = 1103;
  CREYEDROP   = 1104;
  CRBRUSH     = 1105; // Not used as of yet in this demo
  CRPEN       = 1106;
  CRTEXT      = 1107;
  CRFILL      = 1108;

procedure TfrmDemoFeatured.AddAdditionalCursors;
begin
  Screen.Cursors[CRZOOMOUT] := LoadCursor(HINSTANCE,'CRZOOMOUT');
  Screen.Cursors[CRZOOMIN]  := LoadCursor(HINSTANCE,'CRZOOMIN');
  Screen.Cursors[CRPATH]    := LoadCursor(HINSTANCE,'CRPATH');
  Screen.Cursors[CREYEDROP] := LoadCursor(HINSTANCE,'CREYEDROP');
  Screen.Cursors[CRBRUSH]   := LoadCursor(HINSTANCE,'CRBRUSH');
  Screen.Cursors[CRPEN]     := LoadCursor(HINSTANCE,'CRPEN');
  Screen.Cursors[CRTEXT]    := LoadCursor(HINSTANCE,'CRTEXT');
  Screen.Cursors[CRFILL]    := LoadCursor(HINSTANCE,'CRFILL');
end;

(******************************************************************************)
(* System *********************************************************************)
(******************************************************************************)

procedure TfrmDemoFeatured.FormCreate(Sender: TObject);
begin
  ImageZoom := TImageZoom.Create;
  ImageZoom.onZoomChanged := ImageZoomChange;
  ImageZoom.Reset(@imgMain);
  Application.OnHint := DisplayHint;
  Scrollbox1.Brush.Style := bsDiagCross;
  Scrollbox1.Brush.Color := clBtnFace;
  SelectionControl1.WinControl := Scrollbox1;
  SelectionCreator1.Tolerance := tbMagicWandTolerance.Position;  
  cbToolShape.ItemIndex := integer(SelectionCreator1.SelectionShapetype);
  cbLinePattern.ItemIndex := integer(SelectionManager1.LinesPattern);
  cbDirection.ItemIndex := integer(SelectionManager1.Direction);
  tbMagicWandToleranceChange(nil);
  tbFillToleranceChange(nil);
  AddAdditionalCursors;
  cbLineWidth.ItemIndex := 0;
  cbLineStyle.ItemIndex := 0;
end;

(******************************************************************************)

procedure TfrmDemoFeatured.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  StopLockToImage(ImgMain.Canvas, False);
end;

(******************************************************************************)

procedure TfrmDemoFeatured.FormDestroy(Sender: TObject);
begin
  ImageZoom.Free;
end;

(******************************************************************************)

procedure TfrmDemoFeatured.FormActivate(Sender: TObject);
begin
  CenterGraphicInScollControl(Scrollbox1,ImgMain);
end;

(******************************************************************************)

procedure TfrmDemoFeatured.ScrollBox1Resize(Sender: TObject);
begin
  UpdateDataResizingAndPositioning;
end;

(******************************************************************************)

procedure TfrmDemoFeatured.DisplayHint(Sender: TObject);
begin
  Statusbar1.Panels[0].Text := Application.Hint;
end;

(* SelectionManager Mouse Events **********************************************)
(* Demonstrates how to manipulate canvas - like moving a clipping area.       *)
(* These mouse events are only triggered from activity inside selections.     *)
(******************************************************************************)

procedure TfrmDemoFeatured.SelectionManager1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  // To guarantee that slow rendering machines keep up in drag operations
  SelectionManager1.LockToCursor := True;
  if chkLockToImage.Checked then
  begin
    SelectionManager1.Animate := False;
    StartLockToImage(SelectionControl1.DrawingBounds.Region,SelectionManager1.Region,
                          ImgMain.Canvas,X,Y,sBackGround.Brush.Color,ImageZoom.GetZoomFactor);
  end;
end;

(******************************************************************************)

procedure TfrmDemoFeatured.SelectionManager1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
  MoveLockToImage(ImgMain.Canvas,X,Y,ImageZoom.GetZoomFactor);  // Drag Image around
end;

(******************************************************************************)

procedure TfrmDemoFeatured.SelectionManager1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  StopLockToImage(ImgMain.Canvas, True);
  SelectionManager1.Animate := True;
  SelectionManager1.LockToCursor := False;
end;

(******************************************************************************)

procedure TfrmDemoFeatured.SelectionManager1SelectionChange(Sender: TObject; Region: HRGN);
begin
  StopLockToImage(ImgMain.Canvas, False);
end;

(******************************************************************************)

procedure TfrmDemoFeatured.chkLockToImageClick(Sender: TObject);
begin
  StopLockToImage(ImgMain.Canvas, False);
  SelectionControl1.DrawingBounds.Refresh;
end;

(******************************************************************************)

procedure TfrmDemoFeatured.btnExtractDataClick(Sender: TObject);
begin
  PreviewExtractRegion(Self, Scrollbox1, Canvas, SelectionManager1.GetTPath(wtZoomed_Form_TL), SelectionManager1.GetTRegion(wtZoomed_Form_TL))
end;

(* Applying Tools *************************************************************)
(* Below demonstrates how to extract a clipping area to manipulate.           *)
(* MarchingAnts makes this process very easy for any tool.                    *)
(******************************************************************************)

procedure TfrmDemoFeatured.SelectionControl1MouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  Rgn : HRGN;
  Bitmap : TBitmap;
  XY : TPoint;
begin
  XY := SubtractPoints(Point(X,Y), SelectionControl1.DrawingBounds.StartPoint);
  XY := TransformPoint(XY, ImageZoom.GetZoomFactor, True);
  // Text Tool (Create and Open dialog)
  if btnSelectionText.Down then
  begin
    frmInsertText := TfrmInsertText.Create(nil);
    try
      if (frmInsertText.ShowModal = mrOK) then
        with frmInsertText.edtText do
          SelectionCreator1.CreateTextSelection(Text,Font.Name,Font.Style,Font.Size,XY.X,XY.Y);
    finally
      frmInsertText.Release;
    end;
    Exit;
  end;
  Drawing := True;
  SelectionManager1.Animate := False;
  MoveToEx(ImgMain.Canvas.Handle,XY.X,XY.Y,0);
  // Eye Drop Tool
  if btnEyeDrop.Down then
  begin
    if SelectionManager1.PointInSelectionRegion(XY, True) then
    begin
      if (ssRight in Shift) then
        sBackGround.Brush.Color := GetPixel(Handle,XY.X,XY.Y)
      else sForeGround.Brush.Color := GetPixel(Handle,XY.X,XY.Y);
    end;
  end else
  // Flood Fill Tool
  if btnFloodFill.Down then
  begin
    Rgn := GenerateColorRangeRegion(SelectionControl1.DrawingBounds.Region,
                                     ImgMain.Picture.Bitmap.Handle,
                                     XY.X,XY.Y, tbFillTolerance.Position,True);
    CombineRgn(Rgn,Rgn,SelectionManager1.Region, RGN_AND);
    ImgMain.Canvas.Brush.Color := sForeGround.Brush.Color;
    PaintRgn(ImgMain.Picture.Bitmap.Canvas.Handle,Rgn);
    ImgMain.Invalidate;
    DeleteObject(Rgn);
  end else
  // Pen Tool
  if btnPen.Down then
    ImgMain.Canvas.Pen.Handle :=
       CreatePen(cbLineStyle.ItemIndex,cbLineWidth.ItemIndex+1,sForeGround.Brush.Color,PS_ENDCAP_ROUND);
end;

(******************************************************************************)

procedure TfrmDemoFeatured.SelectionControl1MouseMove(Sender: TObject; Shift: TShiftState; X,Y: Integer);
var
  XY : TPoint;
begin
  XY := SubtractPoints(Point(X,Y), SelectionControl1.DrawingBounds.StartPoint);
  XY := TransformPoint(XY, ImageZoom.GetZoomFactor, True);
  if PtInRegion(SelectionControl1.DrawingBounds.Region,XY.X, XY.Y) then
    StatusBar1.Panels[1].Text := PointToStr(XY,True)
  else StatusBar1.Panels[1].Text := '';
  with ImgMain.Canvas do
    if Drawing then
    begin
      // Pen Tool
      if btnPen.Down then
      begin
        SelectClipRgn(Handle, SelectionManager1.Region);
        Windows.LineTo(Handle,XY.X,XY.Y);
        InvalidateRegion(Scrollbox1.Handle, SelectionManager1.ClippedWNDRegion);
        UpdateWindow(Scrollbox1.Handle);
      end else
      // Eye Drop Tool
      if btnEyeDrop.Down then
      begin
        if (ssRight in Shift) then
          sBackGround.Brush.Color := GetPixel(Handle,XY.X,XY.Y)
        else sForeGround.Brush.Color := GetPixel(Handle,XY.X,XY.Y);
      end;
   end;
end;

(******************************************************************************)

procedure TfrmDemoFeatured.SelectionControl1MouseUp(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  Drawing := False;
  SelectionManager1.Animate := True;
  SelectClipRgn(ImgMain.Picture.Bitmap.Handle, 0);  // Reset clipping areas to NIL
  UpdateWindow(Scrollbox1.Handle);
end;

(******************************************************************************)
(* Tools - general procedures *************************************************)
(******************************************************************************)

procedure TfrmDemoFeatured.btnToolClick(Sender: TObject);
begin
  SelectionControl1.RunEngine := False;
  with (Sender as TComponent) do
  begin
    Scrollbox1.Cursor := Tag;
    case Tag of
    CRPEN   : NotebookTO.PageIndex := 0;
    CRTEXT  : NotebookTO.PageIndex := 1;
    CRFILL  : NotebookTO.PageIndex := 2;
    end;
  end;
  NotebookTO.Visible := True;
end;

(******************************************************************************)

procedure TfrmDemoFeatured.cbToolShapeChange(Sender: TObject);
begin
  SelectionCreator1.SelectionShapetype := TSelectionShapetype(cbToolShape.ItemIndex);
  // Enable/Disable non essential Controls
  lblCornerRounding.Enabled := cbToolShape.ItemIndex > 3;
  seRoundCorner.Enabled := cbToolShape.ItemIndex > 3;
end;

(******************************************************************************)

procedure TfrmDemoFeatured.cbLinePatternChange(Sender: TObject);
begin
  SelectionManager1.LinesPattern := TLinesPattern(cbLinePattern.ItemIndex);
end;

(******************************************************************************)

procedure TfrmDemoFeatured.seSpeedChange(Sender: TObject);
begin
  SelectionManager1.Speed := seSpeed.Value;
end;

(******************************************************************************)

procedure TfrmDemoFeatured.seRoundCornerChange(Sender: TObject);
begin
  SelectionCreator1.RoundValue := seRoundCorner.Value;
end;

(******************************************************************************)

procedure TfrmDemoFeatured.cbDirectionChange(Sender: TObject);
begin
  SelectionManager1.Direction := TDirection(cbDirection.ItemIndex);
end;

(******************************************************************************)

procedure TfrmDemoFeatured.btnSelectionToolClick(Sender: TObject);
begin
  SelectionControl1.RunEngine := not(btnArrow.Down);
  SelectionCreator1.DrawingMode := TDrawingMode((Sender as TComponent).Tag);
  UpdateMagicWandBitmap;
  NotebookMA.PageIndex := (Sender as TComponent).Tag;
  NotebookTO.Visible := False;
end;

(******************************************************************************)

procedure TfrmDemoFeatured.btnArrowClick(Sender: TObject);
begin
  btnSelectionToolClick(Self);
  Scrollbox1.Cursor := crDefault;  
end;

(******************************************************************************)

procedure TfrmDemoFeatured.cbLineWidthDrawItem(Control: TWinControl;
  Index: Integer; Rect: TRect; State: TOwnerDrawState);
const
  Margin = 5;
var
  i : integer;
begin
  with (Control as TComboBox).Canvas do
  begin
    Brush.Color := clWhite;
    FillRect(Rect);
    Pen.Handle := CreatePen(PS_SOLID,index+1,clBlack,PS_ENDCAP_SQUARE);
    i := ((Index - (Index mod 2)) div 2);
    MoveTo((Rect.Left + Margin + Index - i),((Rect.Top + Rect.Bottom) div 2));
    LineTo((Rect.Right - (Margin + i)),((Rect.Top + Rect.Bottom) div 2))
  end;
end;

(******************************************************************************)

procedure TfrmDemoFeatured.cbLineStyleDrawItem(Control: TWinControl;
  Index: Integer; Rect: TRect; State: TOwnerDrawState);
const
  Margin = 5;
var
  i : integer;
begin
  with (Control as TComboBox).Canvas do
  begin
    Brush.Color := clWhite;
    FillRect(Rect);
    Pen.Handle := CreatePen(Index,2,clBlack,PS_ENDCAP_SQUARE);
    i := ((Index - (Index mod 2)) div 2);
    MoveTo((Rect.Left + Margin + Index - i),((Rect.Top + Rect.Bottom) div 2));
    LineTo((Rect.Right - (Margin + i)),((Rect.Top + Rect.Bottom) div 2))
  end;
end;

(******************************************************************************)

procedure TfrmDemoFeatured.tbMagicWandToleranceChange(Sender: TObject);
begin
  lblMagicWandTolerance.caption := 'Tolerance ('+inttostr(tbMagicWandTolerance.Position)+')';
  SelectionCreator1.Tolerance := tbMagicWandTolerance.Position;
end;

(******************************************************************************)

procedure TfrmDemoFeatured.tbFillToleranceChange(Sender: TObject);
begin
  lblFillTolerance.caption := 'Tolerance ('+inttostr(tbFillTolerance.Position)+')';
end;

(******************************************************************************)
(* Selection Menu options *****************************************************)
(******************************************************************************)

procedure TfrmDemoFeatured.Invert1Click(Sender: TObject);
begin
  SelectionManager1.InverseSelection;
end;

(******************************************************************************)

procedure TfrmDemoFeatured.SelectAll1Click(Sender: TObject);
begin
  SelectionManager1.SelectAll;
end;

(******************************************************************************)

procedure TfrmDemoFeatured.SelectNone1Click(Sender: TObject);
begin
  SelectionManager1.ClearAll(True);
end;

(******************************************************************************)

procedure TfrmDemoFeatured.ExportMask1Click(Sender: TObject);
var
  Bitmap : TBitmap;
  Rect : TRect;
begin
  if SPD.Execute then
  try
    Bitmap := TBitmap.Create;
    Bitmap.Handle := GenerateRegionMask(SelectionControl1.DrawingBounds.Region,
                                        SelectionManager1.Region, False);
    // Trim Bitmap of wasted space
    GetRgnBox(SelectionManager1.Region,Rect);
    Bitmap.Width := Rect.Right;
    Bitmap.Height := Rect.Bottom;
    Bitmap.SaveToFile(SPD.FileName);
  finally
    Bitmap.Free;
  end;
end;

(******************************************************************************)

procedure TfrmDemoFeatured.ImportMask1Click(Sender: TObject);
var
  Bitmap : TBitmap;
  Region : HRGN;
begin
  if OPD.Execute then
  begin
    Bitmap := TBitmap.Create;
    try
      Bitmap.LoadFromFile(OPD.FileName);
      Region := MaskToRegion(Bitmap.Handle);
      SelectionManager1.LoadRegion(Region,[]);
    finally
      Bitmap.Free;
      DeleteObject(Region);
    end;
  end;
end;

(******************************************************************************)
(* Color Selection Controls ***************************************************)
(******************************************************************************)

procedure TfrmDemoFeatured.ColorSelectionMouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  ColorDialog.Color := (Sender as TShape).Brush.Color;
  if ColorDialog.Execute then
    (Sender as TShape).Brush.Color := ColorDialog.Color;
end;

(******************************************************************************)

procedure TfrmDemoFeatured.imgSwapColorsClick(Sender: TObject);
var
  Color : TColor;
begin
  Color := sForeGround.Brush.Color;
  sForeGround.Brush.Color := sBackground.Brush.Color;
  sBackground.Brush.Color := Color;
end;

(******************************************************************************)

procedure TfrmDemoFeatured.imgBWClick(Sender: TObject);
begin
  sForeGround.Brush.Color := clWhite;
  sBackground.Brush.Color := clBlack;
end;

(******************************************************************************)
(* Open|Save|Reset ************************************************************)
(******************************************************************************)

procedure TfrmDemoFeatured.btnOpenImageClick(Sender: TObject);
begin
  if OPD.Execute then
  begin
    SelectionManager1.ClearAll(True);
    FileName := OPD.FileName;
    ImgMain.Picture.Graphic.LoadFromFile(FileName);
    UpdateMagicWandBitmap;
    ImageZoom.Reset(@imgMain);
    UpdateDataResizingAndPositioning;
  end;
end;

(******************************************************************************)

procedure TfrmDemoFeatured.btnSaveImageClick(Sender: TObject);
begin
{ TODO : Implement save image }
end;

(******************************************************************************)

procedure TfrmDemoFeatured.btnReloadClick(Sender: TObject);
begin
  if FileExists(FileName) then
  begin
    if MessageDlg('Are you sure you want to reload the image?'+#13#10+
                  'All changes will be lost. Continue?',
                  mtConfirmation,[mbYes,mbNo],0) = mrYes then
    begin
      StopLockToImage(ImgMain.Canvas, False);
      if FileExists(FileName) then
      begin
        ImgMain.Picture.LoadFromFile(FileName);
        UpdateMagicWandBitmap;
        UpdateDataResizingAndPositioning;
        SelectionControl1.DrawingBounds.Refresh;
      end;
    end;
  end else MessageDlg('Reload has failed: the file "'+ FileName +'" not found!',mtWarning,[mbOK],0);
end;

(* Zooming ********************************************************************)
(* NOTE:Uses TImageZoom which doubles the image size very inefficently and the*)
(* reason why zooming is capped to x5. Read class desc in uGenericClasses.pas *)
(* for more details.                                                          *)
(******************************************************************************)

procedure TfrmDemoFeatured.btnZoomInClick(Sender: TObject);
begin
  ImageZoom.ZoomIn;
  UpdateDataResizingAndPositioning;
end;

(******************************************************************************)

procedure TfrmDemoFeatured.btnZoomOutClick(Sender: TObject);
begin
  ImageZoom.ZoomOut;
  UpdateDataResizingAndPositioning;
  Scrollbox1.Invalidate; // To any selection areas outside of BoundaryRegion
end;

(******************************************************************************)

procedure TfrmDemoFeatured.ImageZoomChange(Sender: TObject);
begin
  StatusBar1.Panels[2].Text := ImageZoom.GenerateZoomFactorString;
  SelectionControl1.ZoomFactor := ImageZoom.GetZoomFactor;
end;

(******************************************************************************)
(* Miscellaneous **************************************************************)
(******************************************************************************)

procedure TfrmDemoFeatured.About1Click(Sender: TObject);
begin
  ShowAbout;
end;

procedure TfrmDemoFeatured.UpdateDataResizingAndPositioning;
begin
  CenterGraphicInScollControl(Scrollbox1,ImgMain);
  with SelectionControl1.DrawingBounds do
  begin
    SetDimensions(ImgMain.Picture.Width,ImgMain.Picture.Height);
    StartPoint := ImgMain.BoundsRect.TopLeft;
  end;
end;

procedure TfrmDemoFeatured.UpdateMagicWandBitmap;
begin
(* Re-associate a HBitmap to the SelectionCreator after every Load/Reload if  *)
(* the MagicWand tool is currently selected.                                  *)
  if (SelectionCreator1.DrawingMode = dmMagicWand) then
    SelectionCreator1.BitmapHandle := imgMain.Picture.Bitmap.Handle;
end;

procedure TfrmDemoFeatured.btnCropClick(Sender: TObject);
var
  Bitmap : TBitmap;
  nRect : TRect;
begin
  SelectionControl1.DrawingBounds.Refresh;
  if IsRegionRectangle(SelectionManager1.Region) then
  begin
    if MessageDlg('Continue with cropping?', mtConfirmation,[mbYes,mbNo],0) = MrYes then
    begin
      GetRgnBox(SelectionManager1.Region, nRect);
      Bitmap := TBitmap.Create;
      try
        Bitmap.PixelFormat := imgMain.Picture.Bitmap.PixelFormat;
        Bitmap.Width := nRect.Right-nRect.Left;
        Bitmap.Height := nRect.Bottom-nRect.Top;
        Bitmap.Canvas.CopyRect(Rect(0,0,Bitmap.Width,Bitmap.Height), imgMain.Picture.Bitmap.Canvas, nRect);
        imgMain.Picture.Bitmap.Assign(nil);
        imgMain.Picture.Bitmap.Handle := Bitmap.ReleaseHandle;
      finally;
        Bitmap.Free;
        SelectionManager1.ClearAll(True);
        ImageZoom.Reset(@imgMain);
        UpdateDataResizingAndPositioning;
        UpdateMagicWandBitmap;
        FileName := '';
      end;
     end; 
    end else
      MessageDlg('Please note that only a simple region (Rectangle) can be used for cropping.',
                  mtWarning,[mbOK],0);
end;

initialization
  FileName := ExtractFilePath(Application.ExeName)+FileName;
end.


