unit umain; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Menus, ieview, imageenview, rulerbox, ComCtrls, ExtCtrls, StdCtrls, hyieutils, iexBitmaps, hyiedefs, iesettings, iexRulers, iexLayers; type TForm1 = class(TForm) VertRuler: TRulerBox; ImageEnView1: TImageEnView; MainMenu1: TMainMenu; FileMenu: TMenuItem; miOpen: TMenuItem; N1: TMenuItem; miExit: TMenuItem; StatusBar1: TStatusBar; HorzRuler: TRulerBox; ViewMenu: TMenuItem; miCenter: TMenuItem; miAlignRuler: TMenuItem; UnitsMenu: TMenuItem; miPixels: TMenuItem; miInches: TMenuItem; miCentimeters: TMenuItem; N2: TMenuItem; miLockGrips: TMenuItem; miMillimeters: TMenuItem; procedure Exit1Click(Sender: TObject); procedure miOpenClick(Sender: TObject); procedure ImageEnView1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure ImageEnView1ViewChange(Sender: TObject; Change: Integer); procedure Center1Click(Sender: TObject); procedure FormResize(Sender: TObject); procedure OnSelectUnits(Sender: TObject); procedure FormCreate(Sender: TObject); procedure miAlignRulerClick(Sender: TObject); private { Private declarations } fUnits : TIERulerUnits; public { Public declarations } end; var Form1: TForm1; implementation {$R *.DFM} {$R WindowsTheme.res} const Lock_Grips_To_Label = True; // snap to integer values, or closest label tick Constrain_Grips_To_Image = True; // Allow grips outside the area of the image?? procedure TForm1.FormCreate(Sender: TObject); begin fUnits := ieruPixels; HorzRuler.LabelPrecision := 2; VertRuler.LabelPrecision := 2; FormResize( nil ); StatusBar1.Panels[ 1 ].Text := ' Note: You can automatically add rulers to a TImageEnView using: ImageEnView1.ShowRulers := [ rdHorizontal, rdVertical ];'; end; // File | Exit procedure TForm1.Exit1Click(Sender: TObject); begin Close; end; // File | Open procedure TForm1.miOpenClick(Sender: TObject); begin with ImageEnView1.IO do LoadFromFile( ExecuteOpenDialog('','',false,1,'') ); FormResize( Self ); end; // mouse move procedure TForm1.ImageEnView1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); var dpix, dpiy: double; horzGripsPos, vertGripsPos : double; horzZeroPos, vertZeroPos : double; horzMaxPos, vertMaxPos : double; begin dpix := HorzRuler.DotPerUnit * 100 / ImageEnView1.Zoom; dpiy := VertRuler.DotPerUnit * 100 / ImageEnView1.Zoom; horzGripsPos := ( ImageEnView1.ViewX - ImageEnView1.OffsetX + X ) / HorzRuler.DotPerUnit; vertGripsPos := ( ImageEnView1.ViewY - ImageEnView1.OffsetY + Y ) / VertRuler.DotPerUnit; if miLockGrips.Checked and (Lock_Grips_To_Label = False) then begin horzGripsPos := round(( ImageEnView1.XScr2Bmp( X )) / dpix ); vertGripsPos := round(( ImageEnView1.YScr2Bmp( Y )) / dpiy ); end else if miLockGrips.Checked and (Lock_Grips_To_Label = TRUE) then begin horzGripsPos := round(( ImageEnView1.XScr2Bmp( X )) / dpix / HorzRuler.LabelFreq ) * HorzRuler.LabelFreq; vertGripsPos := round(( ImageEnView1.YScr2Bmp( Y )) / dpiy / VertRuler.LabelFreq ) * VertRuler.LabelFreq; end; if Constrain_Grips_To_Image then begin horzZeroPos := 0; vertZeroPos := 0; if horzGripsPos < horzZeroPos then horzGripsPos := horzZeroPos; if vertGripsPos < vertZeroPos then vertGripsPos := vertZeroPos; horzMaxPos := ( ImageEnView1.ViewX - ImageEnView1.OffsetX + ImageEnView1.XBmp2Scr( ImageEnView1.IEBitmap.Width )) / HorzRuler.DotPerUnit; vertMaxPos := ( ImageEnView1.ViewY - ImageEnView1.OffsetY + ImageEnView1.YBmp2Scr( ImageEnView1.IEBitmap.Height )) / VertRuler.DotPerUnit; if horzGripsPos > horzMaxPos then horzGripsPos := horzMaxPos; if vertGripsPos > vertMaxPos then vertGripsPos := vertMaxPos; end; HorzRuler.GripsPos[0] := horzGripsPos; VertRuler.GripsPos[0] := vertGripsPos; end; // scroll or zoom procedure TForm1.ImageEnView1ViewChange(Sender: TObject; Change: Integer); var z: double; dpi, lfrq, tfrq: double; horzViewPos: double; vertViewPos: double; begin HorzRuler.LockUpdate(); VertRuler.LockUpdate(); try case fUnits of ieruInches : begin dpi := ImageEnView1.IO.Params.Dpi; lfrq := 0.25; // Every quarter inch tfrq := lfrq / 8; end; ieruMillimeters : begin dpi := ImageEnView1.IO.Params.Dpi / CM_per_Inch / 10; lfrq := 2.5; // Every 2.5 mm tfrq := lfrq / 5; end; ieruCentimeters : begin dpi := ImageEnView1.IO.Params.Dpi / CM_per_Inch; lfrq := 0.25; // Every quarter CM tfrq := lfrq / 5; end; else { ieruPixels } begin dpi := 1; lfrq := 100; // Every 100px tfrq := lfrq / 10; end; end; z := ImageEnView1.Zoom / 100; horzViewPos := ImageEnView1.ViewX / z / dpi; vertViewPos := ImageEnView1.ViewY / z / dpi; { REMOVE if miLockGrips.Checked and (ALIGN_TO_LABEL = False) then begin horzViewPos := round( horzViewPos ); vertViewPos := round( vertViewPos ); end; if miLockGrips.Checked and (ALIGN_TO_LABEL = TRUE) then begin horzViewPos := round( horzViewPos / HorzRuler.LabelFreq ) * HorzRuler.LabelFreq; vertViewPos := round( vertViewPos / VertRuler.LabelFreq ) * VertRuler.LabelFreq; end; } if miAlignRuler.Checked = False then begin horzViewPos := horzViewPos - ImageEnView1.OffsetX / z / dpi; vertViewPos := vertViewPos - ImageEnView1.OffsetY / z / dpi; end; HorzRuler.ViewPos := horzViewPos; VertRuler.ViewPos := vertViewPos; HorzRuler.DotPerUnit := z * dpi; VertRuler.DotPerUnit := z * dpi; HorzRuler.Frequency := tfrq; VertRuler.Frequency := tfrq; HorzRuler.LabelFreq := lfrq; VertRuler.LabelFreq := lfrq; StatusBar1.Panels[ 0 ].Text := ' Zoom: ' + IntToStr( Trunc( ImageEnView1.Zoom )) + '%'; if Change = 1 then FormResize( self ); finally HorzRuler.UnlockUpdate(); VertRuler.UnlockUpdate(); end; end; // View -> Center procedure TForm1.Center1Click(Sender: TObject); begin ImageEnView1.Center := miCenter.Checked; FormResize(self); end; // Form resize, adjust rulers offsets procedure TForm1.FormResize(Sender: TObject); begin if miAlignRuler.Checked then begin // Align ruler to position of the image HorzRuler.OffsetX := ImageEnView1.OffsetX + ImageEnView1.Left - HorzRuler.Left {Due to alignment HorzRuler will be left of ImageEnView1}; VertRuler.OffsetY := ImageEnView1.OffsetY + ImageEnView1.Top - VertRuler.Top {This latter code is not needed, as ImageEnView1.Top and VertRuler.Top should be identical}; end else begin // Photoshop style: show negative values in ruler HorzRuler.OffsetX := ImageEnView1.Left - HorzRuler.Left {Due to alignment HorzRuler will be left of ImageEnView1}; VertRuler.OffsetY := ImageEnView1.Top - VertRuler.Top {This latter code is not needed, as ImageEnView1.Top and VertRuler.Top should be identical}; end; ImageEnView1ViewChange( self, 0 ); end; procedure TForm1.miAlignRulerClick(Sender: TObject); begin FormResize( Self ); end; procedure TForm1.OnSelectUnits(Sender: TObject); begin if Sender = miPixels then fUnits := ieruPixels else if Sender = miInches then fUnits := ieruInches else if Sender = miMillimeters then fUnits := ieruMillimeters else if Sender = miCentimeters then fUnits := ieruCentimeters; ImageEnView1ViewChange( self, 1 ); end; end.