unit Thumbnail;

{
[ufrmThumbnail] [1.0]
Delphi 2005
September 2007

LICENSE

The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
"http://www.mozilla.org/MPL/"

Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
the specific language governing rights and limitations under the License.

The Original Code is "[Thumbnail.pas] and [Thumbnail.dfm]".

The Initial Developer of the Original Code is Martin Holmes (Victoria,
BC, Canada, "http://www.mholmes.com/"). Copyright (C) 2007 Martin Holmes
and the University of Victoria Computing and Media Centre. The code was 
co-developed for university and personal projects, and rights are shared
by Martin Holmes and the University of Victoria. All Rights Reserved.
}

{
Written by Martin Holmes, Fall 2007.

This unit provides a dialog box for settings used to create a thumbnail
image from the main loaded image, or from a selected annotation area on
that image.

Dependencies:

TntUnicodeControls (Troy Wolbrink)
FormState for saving size/position etc.

}
interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, TntForms, StdCtrls, Buttons, TntButtons, Spin, TntStdCtrls, FormState,
  AppEvnts, mdhSpin;

type
  TufrmThumbnail = class(TTntForm)
    urbThumbnailFromImage: TTntRadioButton;
    urbThumbnailFromSelection: TTntRadioButton;
    ulbThumbnailWidth: TTntLabel;
    mseThumbnailWidth: TMdhSpinEdit;
    mseThumbnailHeight: TMdhSpinEdit;
    ulbThumbnailHeight: TTntLabel;
    uspdProportionate: TTntSpeedButton;
    ubnOK: TTntBitBtn;
    ubnCancel: TTntBitBtn;
    aeThumbnail: TApplicationEvents;
    procedure urbThumbnailFromSelectionClick(Sender: TObject);
    procedure urbThumbnailFromImageClick(Sender: TObject);
    procedure aeThumbnailIdle(Sender: TObject; var Done: Boolean);
    procedure TntFormDestroy(Sender: TObject);
    procedure TntFormShow(Sender: TObject);
  private
    FFormStateSaver: TFormStateSaver;
    FSelWidth: integer;
    FSelHeight: integer;
    FImgWidth: integer;
    FImgHeight: integer;
    FSelRatio: Double;
    FImgRatio: Double;
    FDoProportionCalc: Boolean;
    FUsingSelection: Boolean;
    procedure SetUsingSelection(const Value: Boolean);
    { Private declarations }
  public
    { Public declarations }
    function SetValues(SelWidth, SelHeight, ImgWidth, ImgHeight: integer): Boolean;
    function CalculateWidthHeight(Sender: TMdhSpinEdit): Boolean;
  published
    property UsingSelection: Boolean read FUsingSelection
                             write SetUsingSelection default False;
  end;

var
  ufrmThumbnail: TufrmThumbnail;

implementation

{$R *.DFM}

procedure TufrmThumbnail.TntFormShow(Sender: TObject);
begin
  FFormStateSaver := TFormStateSaver.Create(Self, True);
  FDoProportionCalc := True;
end;

procedure TufrmThumbnail.TntFormDestroy(Sender: TObject);
begin
  FreeAndNil(FFormStateSaver);
end;

function TufrmThumbnail.SetValues(SelWidth, SelHeight, ImgWidth,
  ImgHeight: integer): Boolean;
begin
  Result := True;
  try
    FSelWidth := SelWidth;
    FSelHeight := SelHeight;
    if (FSelWidth > 0) and (FSelHeight > 0) then
      FSelRatio := SelWidth / SelHeight
    else
      FSelRatio := 1;
    FImgWidth := ImgWidth;
    FImgHeight := ImgHeight;
    if (FImgHeight > 0) and (FImgWidth > 0) then
      FImgRatio := ImgWidth / ImgHeight
    else
      FImgRatio := 1;

//Now set the control values
//First disable auto-updating of sizes
    FDoProportionCalc := False;

//Set the values
//Assume that if there's a selection, that's what should be used
    if (FSelWidth > 0) and (FSelHeight > 0) then
      begin
        urbThumbnailFromSelection.Enabled := True;
        urbThumbnailFromSelection.Checked := True;
        mseThumbnailWidth.Value := FSelWidth;
        mseThumbnailHeight.Value := FSelHeight;
      end
    else
      begin
        urbThumbnailFromImage.Checked := True;
        urbThumbnailFromSelection.Enabled := False;
        mseThumbnailWidth.Value := FImgWidth;
        mseThumbnailHeight.Value := FImgHeight;
      end;

//Re-enable proportion calculation
    FDoProportionCalc := True;
  except
    Result := False;
  end;
end;

function TufrmThumbnail.CalculateWidthHeight(Sender: TMdhSpinEdit): Boolean;
var
ActiveRatio: Double;
Val: integer;

begin
  Result := True;
//If the form isn't showing, bail
  if Visible = False then
    Exit;

//If we're already in the middle of doing something, bail on this.
  if FDoProportionCalc = False then
    Exit;

//No need for calculation if not using proportionate values
  if uspdProportionate.Down = False then
    Exit;

  Application.ProcessMessages;

//Decide which ratio we're going to use
  if urbThumbnailFromSelection.Checked then
    ActiveRatio := FSelRatio
  else
    ActiveRatio := FImgRatio;
  try
    FDoProportionCalc := False;

    Application.ProcessMessages;

    try
      if Sender.Name = mseThumbnailHeight.Name then
        begin
          Val := Round(mseThumbnailHeight.Value * ActiveRatio);
          if mseThumbnailWidth.Value <> Val then
            mseThumbnailWidth.Value := Val;
        end
      else
  //Default is to calculate based on Width.
        begin
          Val := Round(mseThumbnailWidth.Value / ActiveRatio);
          if mseThumbnailHeight.Value <> Val then
            mseThumbnailHeight.Value := Val;
        end;
    finally
      Application.ProcessMessages;
      FDoProportionCalc := True;
    end;
  except
    Result := False;
  end;
end;

procedure TufrmThumbnail.aeThumbnailIdle(Sender: TObject; var Done: Boolean);
begin
  if Visible = False then
    Exit;
  if ActiveControl.Name = mseThumbnailHeight.Name then
    CalculateWidthHeight(mseThumbnailHeight)
  else
    CalculateWidthHeight(mseThumbnailWidth);
end;

procedure TufrmThumbnail.urbThumbnailFromImageClick(Sender: TObject);
begin
  UsingSelection := (not(urbThumbnailFromImage.Checked));
end;

procedure TufrmThumbnail.urbThumbnailFromSelectionClick(Sender: TObject);
begin
  UsingSelection := urbThumbnailFromSelection.Checked;
end;

procedure TufrmThumbnail.SetUsingSelection(const Value: Boolean);
begin
  if FUsingSelection <> Value then
    begin
//A different radio button has been selected, so we need to reset the
//values in the size boxes.
      //Now set the control values
//First disable auto-updating of sizes
      FDoProportionCalc := False;

      Application.ProcessMessages;
      try
//Set the new value
        FUsingSelection := Value;

//Set the values
        if FUsingSelection then
          begin
            mseThumbnailWidth.Value := FSelWidth;
            mseThumbnailHeight.Value := FSelHeight;
          end
        else
          begin
            mseThumbnailWidth.Value := FImgWidth;
            mseThumbnailHeight.Value := FImgHeight;
          end;

        Application.ProcessMessages;
      finally
//Re-enable proportion calculation
        FDoProportionCalc := True;
      end;
    end;
end;



end.