16842 lines
543 KiB
Plaintext
16842 lines
543 KiB
Plaintext
(* ImageEn Build 7.0.0.06.2637 @ 7-4-17 14:58:42.679 *)
|
|
(*
|
|
Copyright (c) 1998-2017 by Carlotta Calandra. All rights reserved.
|
|
Copyright (c) 2011-2017 by Xequte Software.
|
|
|
|
This software comes without express or implied warranty.
|
|
In no case shall the author be liable for any damage or unwanted behavior of any
|
|
computer hardware and/or software.
|
|
|
|
Author grants you the right to include the component
|
|
in your application, whether COMMERCIAL, SHAREWARE, or FREEWARE.
|
|
|
|
ImageEn, IEvolution and ImageEn ActiveX may not be included in any
|
|
commercial, shareware or freeware libraries or components.
|
|
|
|
www.ImageEn.com
|
|
*)
|
|
|
|
(*
|
|
File version 1100
|
|
Doc revision 1004
|
|
*)
|
|
|
|
unit iemview;
|
|
|
|
{$R-}
|
|
{$Q-}
|
|
|
|
{$I ie.inc}
|
|
|
|
{$IFDEF IEINCLUDEMULTIVIEW}
|
|
|
|
interface
|
|
|
|
uses
|
|
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, SyncObjs,
|
|
{$ifdef IEHASTYPES} Types, {$endif}
|
|
{$ifdef IEHASUITYPES} System.UITypes, {$endif}
|
|
ExtCtrls, Clipbrd, stdctrls, iexBitmaps, hyiedefs, ImageEnView, ImageEnProc, ImageEnIO, ieview, iemio, iepresetim, ievect,
|
|
ieanimation, iexTransitions, hyieutils;
|
|
|
|
type
|
|
|
|
|
|
{!!
|
|
<FS>TIEImageAddEvent
|
|
|
|
<FM>Declaration<FC>
|
|
type TIEImageAddEvent = procedure(Sender : TObject;
|
|
idx : integer;
|
|
const sFilename : string;
|
|
bFolder : boolean;
|
|
bHiddenFile : boolean;
|
|
iFileSizeBytes : Int64;
|
|
CreateDate : TDateTime;
|
|
EditDate : TDateTime;
|
|
var bAllow : Boolean) of object;
|
|
|
|
<FM>Description<FN>
|
|
Occurs whenever an image is added to a <A TImageEnFolderMView> or when using <L TImageEnMView.FillFromDirectory>TImageEnMView.FillFromDirectory</L>.
|
|
|
|
Set bAllow to skip the addition of certain files.
|
|
|
|
<TABLE>
|
|
<R> <H>Value</H> <H>Description</H> </R>
|
|
<R> <C>Sender</C> <C>The <A TImageEnFolderMView> or <A TImageEnMView></C> </R>
|
|
<R> <C>idx</C> <C>The new position for this file</C> </R>
|
|
<R> <C>sFilename</C> <C>The full path of the file or folder</C> </R>
|
|
<R> <C>bFolder</C> <C>True for folders, false for files</C> </R>
|
|
<R> <C>bHiddenFile</C> <C>True for files marked hidden in file properties</C> </R>
|
|
<R> <C>iFileSizeBytes</C> <C>Size of the file in bytes</C> </R>
|
|
<R> <C>CreateDate</C> <C>Date the file was created</C> </R>
|
|
<R> <C>EditDate</C> <C>Date the file was last modified</C> </R>
|
|
<R> <C>bAllow</C> <C>Defaults to false. Set to true to skip the addition of this file</C> </R>
|
|
</TABLE>
|
|
|
|
<FM>Examples<FC>
|
|
procedure TfMain.ImageEnMView1ImageAdd(Sender : TObject; idx : integer; const sFilename : string; bFolder : boolean; bHiddenFile : boolean; iFileSizeBytes : Int64; CreateDate : TDateTime; EditDate : TDateTime; var bAllow : Boolean);
|
|
const
|
|
ONE_MB = 1024 * 1024;
|
|
begin
|
|
// Don't add files larger than one MB
|
|
if iFileSizeBytes > ONE_MB then
|
|
bAllow := False;
|
|
end;
|
|
|
|
procedure TfMain.ImageEnMView1ImageAdd(Sender : TObject; idx : integer; const sFilename : string;
|
|
bFolder : boolean; bHiddenFile : boolean; iFileSizeBytes : Int64;
|
|
CreateDate : TDateTime; EditDate : TDateTime; var bAllow : Boolean);
|
|
const
|
|
ONE_YEAR = 365;
|
|
begin
|
|
// Don't add files more than a year old
|
|
if EditDate < Now - ONE_YEAR then
|
|
bAllow := False;
|
|
end;
|
|
!!}
|
|
TIEImageAddEvent = procedure(Sender : TObject;
|
|
idx : integer;
|
|
const sFilename : string;
|
|
bFolder : boolean;
|
|
bHiddenFile : boolean;
|
|
iFileSizeBytes : Int64;
|
|
CreateDate : TDateTime;
|
|
EditDate : TDateTime;
|
|
var bAllow : Boolean) of object;
|
|
|
|
{!!
|
|
<FS>TIEImageSelectEvent
|
|
|
|
<FM>Declaration<FC>
|
|
type TIEImageSelectEvent = procedure(Sender: TObject; idx: integer) of object;
|
|
|
|
<FM>Description<FN>
|
|
Occurs whenever the user selects or deselects an image
|
|
<FC>idx<FN> is the index of the selected image.
|
|
!!}
|
|
TIEImageSelectEvent = procedure(Sender: TObject; idx: integer) of object;
|
|
|
|
|
|
{!!
|
|
<FS>TIEMViewImageNotifyEvent
|
|
|
|
<FM>Declaration<FC>
|
|
type TIEMViewImageNotifyEvent = procedure(Sender: TObject; idx: integer) of object;
|
|
|
|
<FM>Description<FN>
|
|
Used by <A TImageEnMView.OnImageAdded> and <A TImageEnMView.OnImageLoaded>.
|
|
<FC>idx<FN> is the index of the relevant image.
|
|
!!}
|
|
TIEMViewImageNotifyEvent = procedure(Sender: TObject; idx: integer) of object;
|
|
|
|
{!!
|
|
<FS>TIESelectionChangingEvent
|
|
|
|
<FM>Declaration<FC>
|
|
type TIESelectionChangingEvent = procedure(Sender: TObject; var bAllow: Boolean) of object;
|
|
|
|
<FM>Description<FN>
|
|
Occurs prior to a change in the selected frame/thumbnail due to user action (i.e. mouse or keyboard).
|
|
|
|
This can be used to prevent changing of a selection (e.g. due to the current selection not being saved).
|
|
|
|
<FM>Example<FC>
|
|
procedure TfMain.ImageEnMView1SelectionChanging(Sender: TObject; var bAllow: Boolean);
|
|
begin
|
|
// Don't allow changing of the selection if the user cancels saving of the selected image
|
|
if fSelectedImageChanged and (PromptToSaveSelectedImageChanges = False) then
|
|
bAllow := False;
|
|
end;
|
|
!!}
|
|
TIESelectionChangingEvent = procedure(Sender: TObject; var bAllow: Boolean) of object;
|
|
|
|
|
|
{!!
|
|
<FS>TIECheckboxClickEvent
|
|
|
|
<FM>Declaration<FC>
|
|
type TIECheckboxClickEvent = procedure(Sender: TObject; idx: integer; var bChecked : Boolean) of object;
|
|
|
|
<FM>Description<FN>
|
|
Occurs whenever a user clicks a checkbox.
|
|
|
|
<FC>idx<FN> is the index of the clicked image.
|
|
<FC>bChecked<FN> specifies the new status of the image. You can override it, e.g. set it to false if the image cannot be checked
|
|
|
|
Note: Don't read <A TImageEnMView.CheckedCount> in this event which will not yet be valid. Use OnClick or OnMouseUp.
|
|
|
|
<FM>Example<FC>
|
|
procedure TfMain.ImageEnMView1CheckboxClick(Sender: TObject; idx: integer; var bChecked : Boolean);
|
|
begin
|
|
// Only allow JPEG images to be checked
|
|
if bChecked and (IEFileIsOfFormat(ImageEnMView1.ImageFilename[idx], ioJPEG) = False) then
|
|
begin
|
|
MessageBeep(MB_ICONEXCLAMATION);
|
|
bChecked := False;
|
|
end;
|
|
end;
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.Checkboxes>
|
|
- <A TImageEnMView.CheckedCount>
|
|
!!}
|
|
TIECheckboxClickEvent = procedure(Sender: TObject; idx: integer; var bChecked : Boolean) of object;
|
|
|
|
|
|
{!!
|
|
<FS>TIEImageIDRequestEvent
|
|
|
|
<FM>Declaration<FC>
|
|
type TIEImageIDRequestEvent = procedure(Sender: TObject; Index, ID: integer; var Bitmap: TBitmap) of object;
|
|
|
|
<FM>Description<FN>
|
|
Occurs when an image is required if you have specified a value for the <A TImageEnMView.ImageID> property.
|
|
|
|
<FC>Index<FN> is the index of the image being displayed (i.e. 0 for first image in the grid, 1 for second, etc.)
|
|
<FC>ID<FN> is the value you have specified in <A TImageEnMView.ImageID> property.
|
|
<FC>Bitmap<FN> is the image to display. The bitmap is copied in <A TImageEnMView>, and then automatically freed.
|
|
!!}
|
|
TIEImageIDRequestEvent = procedure(Sender: TObject; Index, ID: integer; var Bitmap: TBitmap) of object;
|
|
|
|
{!!
|
|
<FS>TIEImageIDRequestExEvent
|
|
|
|
<FM>Declaration<FC>
|
|
type TIEImageIDRequestExEvent = procedure(Sender: TObject; Index, ID: integer; var Bitmap: <A TIEBitmap>) of object;
|
|
|
|
<FM>Description<FN>
|
|
Occurs when an image is required if you have specified a value for the <A TImageEnMView.ImageID> property.
|
|
|
|
<FC>Index<FN> is the index of the image being displayed (i.e. 0 for first image in the grid, 1 for second, etc.)
|
|
<FC>ID<FN> is the value you have specified in <A TImageEnMView.ImageID> property
|
|
<FC>Bitmap<FN> is the image to display. The bitmap is copied in <A TImageEnMView>, and then automatically freed.
|
|
!!}
|
|
TIEImageIDRequestExEvent = procedure(Sender: TObject; Index, ID: integer; var Bitmap: TIEBitmap) of object;
|
|
|
|
{!!
|
|
<FS>TIEMProgressEvent
|
|
|
|
<FM>Declaration<FC>
|
|
TIEMProgressEvent = procedure(Sender: TObject; per: integer; idx: integer) of object;
|
|
|
|
<FM>Description<FN>
|
|
Occurs during <A TImageEnMView.PaintTo>.
|
|
|
|
<FC>per<FN> is the percentage of the progress (i.e. 100 indicates painting has finished).
|
|
<FC>idx<FN> is the index of the image currently being drawn.
|
|
!!}
|
|
TIEMProgressEvent = procedure(Sender: TObject; per: integer; idx: integer) of object;
|
|
|
|
{!!
|
|
<FS>TIEWrongImageEvent
|
|
|
|
<FM>Declaration<FC>
|
|
TIEWrongImageEvent = procedure(Sender: TObject; OutBitmap: <A TIEBitmap>; idx: integer; var Handled: boolean) of object;
|
|
|
|
<FM>Description<FN>
|
|
Used by <A TImageEnMView.OnWrongImage> whenever TImageEnMView cannot load the image specified in <A TImageEnMView.ImageFileName> property, for instance when the file is corrupted or of an unrecognized format.
|
|
|
|
<FC>idx<FN> specifies the image index.
|
|
If you change the <FC>OutBitmap<FN>, also set <FC>Handled<FN> to True.
|
|
If <FC>Handled<FN> is false, <A TImageEnMView> replaces the bitmap with a question mark image.
|
|
!!}
|
|
TIEWrongImageEvent = procedure(Sender: TObject; OutBitmap: TIEBitmap; idx: integer; var Handled: boolean) of object;
|
|
|
|
{!!
|
|
<FS>TIEImageDrawEvent
|
|
|
|
<FM>Declaration<FC>
|
|
TIEImageDrawEvent = procedure(Sender: TObject; idx: integer; Left, Top: integer; Canvas: TCanvas) of object;
|
|
|
|
<FM>Description<FN>
|
|
<FC>idx<FN> is the index of the image being painted
|
|
<FC>Left<FN> is the X coordinate of the top-left corner of the thumbnail
|
|
<FC>Top<FN> is the Y coordinate of the top-left corner of the thumbnail.
|
|
<FC>Canvas<FN> is the canvas to draw to.
|
|
!!}
|
|
TIEImageDrawEvent = procedure(Sender: TObject; idx: integer; Left, Top: integer; Canvas: TCanvas) of object;
|
|
|
|
{!!
|
|
<FS>TIEImageDraw2Event
|
|
|
|
<FM>Declaration<FC>
|
|
TIEImageDraw2Event = procedure(Sender: TObject; idx: integer; Left, Top: integer; ImageRect: TRect; Canvas: TCanvas) of object;
|
|
|
|
<FM>Description<FN>
|
|
<FC>idx<FN> is the index of the image being painted
|
|
<FC>Left<FN> is the X coordinate of the top-left corner of the thumbnail
|
|
<FC>Top<FN> is the Y coordinate of the top-left corner of the thumbnail.
|
|
<FC>ImageRect<FN> is the actual image rectangle.
|
|
<FC>Canvas<FN> is the canvas to draw to.
|
|
!!}
|
|
TIEImageDraw2Event = procedure(Sender: TObject; idx: integer; Left, Top: integer; ImageRect: TRect; Canvas: TCanvas) of object;
|
|
|
|
|
|
{!!
|
|
<FS>TIEImageDrawEventEx
|
|
|
|
<FM>Declaration<FC>
|
|
}
|
|
TIEImageDrawEventEx = procedure(Sender: TObject; idx: integer; Left, Top: integer; Dest: TBitmap; var ThumbRect: TRect) of object;
|
|
{!!}
|
|
|
|
|
|
{!!
|
|
<FS>TIEImageOutEvent
|
|
|
|
<FM>Declaration<FC>
|
|
TIEImageOutEvent = procedure(Sender: TObject; idx: integer; OutBitmap: <A TIEBitmap>) of object;
|
|
|
|
<FM>Description<FN>
|
|
Used by <A TImageEnMView.OnImageOut> during thumbnail drawing, just prior to the drawing of the image.
|
|
|
|
<FC>idx<FN> specifies the image index. <FC>OutBitmap<FN> is the image to be drawn.
|
|
!!}
|
|
TIEImageOutEvent = procedure(Sender: TObject; idx: integer; OutBitmap: TIEBitmap) of object;
|
|
|
|
|
|
{!!
|
|
<FS>TIEImageAtPosEvent
|
|
|
|
<FM>Declaration<FC>
|
|
TIEImageAtPosEvent = procedure(Sender: TObject; var idx: integer; x, y: Integer) of object;
|
|
|
|
<FM>Description<FN>
|
|
Used by the <A TImageEnMView.OnImageAtPos> event to check if the specified coordinates are inside a thumbnail.
|
|
<FC>idx<FN> contains the proposed image thumbnail index. You can change this value or set it to -1 for no thumbnail.
|
|
|
|
!!}
|
|
TIEImageAtPosEvent = procedure(Sender: TObject; var idx: integer; x, y: Integer) of object;
|
|
|
|
|
|
{!!
|
|
<FS>TIECreateImageEvent
|
|
|
|
<FM>Declaration<FC>
|
|
TIECreateImageEvent = procedure(Sender: TObject; idx: integer) of object;
|
|
|
|
<FM>Description<FN>
|
|
Used by <A TImageEnMView.OnCreateImage> whenever (immediately after) a new image is created.
|
|
!!}
|
|
TIECreateImageEvent = procedure(Sender: TObject; idx: integer) of object;
|
|
|
|
|
|
{!!
|
|
<FS>TIEDestroyImageEvent
|
|
|
|
<FM>Declaration<FC>
|
|
TIEDestroyImageEvent = procedure(Sender: TObject; idx: integer) of object;
|
|
|
|
<FM>Description<FN>
|
|
Used by <A TImageEnMView.OnDestroyImage> whenever (immediately before) an image is destroyed.
|
|
!!}
|
|
TIEDestroyImageEvent = procedure(Sender: TObject; idx: integer) of object;
|
|
|
|
|
|
{!!
|
|
<FS>TIEProcessStreamEvent
|
|
|
|
<FM>Declaration<FC>
|
|
TIEProcessStreamEvent = procedure(Sender: TObject; Stream: TStream) of object;
|
|
|
|
<FM>Description<FN>
|
|
Used when loading/saving snapshots to specify extra parameters.
|
|
!!}
|
|
TIEProcessStreamEvent = procedure(Sender: TObject; Stream: TStream; Version : Byte) of object;
|
|
|
|
{!!
|
|
<FS>TIEImageEnMViewSortCompare
|
|
|
|
<FM>Declaration<FC>
|
|
TIEImageEnMViewSortCompare = function(Item1, Item2: integer): Integer;
|
|
|
|
<FM>Description<FN>
|
|
A comparison function that indicates how the items are to be ordered.
|
|
|
|
Return a value below 0 if Item1 is less than Item2
|
|
Return 0 if they are equal
|
|
Return a value above 0 if Item1 is greater than Item2
|
|
!!}
|
|
TIEImageEnMViewSortCompare = function(Item1, Item2: integer): Integer;
|
|
|
|
{!!
|
|
<FS>TIEImageEnMViewSortCompareEx
|
|
|
|
<FM>Declaration<FC>
|
|
TIEImageEnMViewSortCompareEx = function(Item1, Item2: integer): Integer of object;
|
|
|
|
<FM>Description<FN>
|
|
A comparison function that indicates how the items are to be ordered.
|
|
|
|
Return a value below 0 if Item1 is less than Item2
|
|
Return 0 if they are equal
|
|
Return a value above 0 if Item1 is greater than Item2
|
|
!!}
|
|
TIEImageEnMViewSortCompareEx = function(Item1, Item2: integer): Integer of object;
|
|
|
|
{!!
|
|
<FS>TIEImageEnMViewSortBy
|
|
|
|
<FM>Declaration<FC>
|
|
TIEImageEnMViewSortBy = (iesbFilename, iesbTopText, iesbBottomText, iesbInfoText, iesbImageSize, iesbFilenameWithoutPath, iesbFileExtension, iesbFileSize, iesbCreateDate, iesbEditDate, iesbFileType, iesbNone);
|
|
|
|
<FM>Description<FN>
|
|
<TABLE>
|
|
<R> <H>Value</H> <H>Description</H> </R>
|
|
<R> <C>iesbFilename</C> <C>Sorts by the full file path (using <A TImageEnMView.ImageFileName>)</C> </R>
|
|
<R> <C>iesbTopText</C> <C>Alphabetical sort on <A TImageEnMView.ImageTopText></C> </R>
|
|
<R> <C>iesbBottomText</C> <C>Alphabetical sort on <A TImageEnMView.ImageBottomText></C> </R>
|
|
<R> <C>iesbInfoText</C> <C>Alphabetical sort on <A TImageEnMView.ImageInfoText></C> </R>
|
|
<R> <C>iesbImageSize</C> <C>Sorting by the image dimensions (<A TImageEnMView.ImageOriginalWidth> x <A TImageEnMView.ImageOriginalHeight>)</C> </R>
|
|
<R> <C>iesbFilenameWithoutPath</C> <C>Sorts only on the name portion of the file (i.e. excluding the file path)</C> </R>
|
|
<R> <C>iesbFileExtension</C> <C>Sorts by the extension of the file (e.g. .jpeg or .tiff)</C> </R>
|
|
<R> <C>iesbFileSize</C> <C>Sorting by the size of the files on disk</C> </R>
|
|
<R> <C>iesbCreateDate</C> <C>Sorting by the date that the files were created (Note: If the image contains an <L TIOParams.EXIF_DateTimeOriginal2>EXIF date</L>, it is used rather than the file date for improved accuracy)</C> </R>
|
|
<R> <C>iesbEditDate</C> <C>Sorting by the date that the files were last modified</C> </R>
|
|
<R> <C>iesbFileType</C> <C>Sorting by the file type</C> </R>
|
|
<R> <C>iesbCustom</C> <C><A TImageEnFolderMView> only: Sorts using the event, <A TImageEnFolderMView.OnCustomSortCompare> (has no effect in TImageEnMView)</C> </R>
|
|
<R> <C>iesbNone</C> <C>No sorting</C> </R>
|
|
</TABLE>
|
|
|
|
!!}
|
|
TIEImageEnMViewSortBy = (iesbFilename, iesbTopText, iesbBottomText, iesbInfoText, iesbImageSize, iesbFilenameWithoutPath, iesbFileExtension, iesbFileSize, iesbCreateDate, iesbEditDate, iesbFileType, iesbCustom, iesbNone);
|
|
|
|
|
|
{!!
|
|
<FS>TIEImageEnMViewIconSize
|
|
|
|
<FM>Declaration<FC>
|
|
TIEImageEnMViewIconSize = (ieicStandardSize, ieicDoubleSize, ieicStretchHD, ieicStretchAll);
|
|
|
|
<FM>Description<FN>
|
|
<TABLE>
|
|
<R> <H>Value</H> <H>Description</H> </R>
|
|
<R> <C>ieicStandardSize</C> <C>Displays a 32x32 icon in the centre of the thumbnail box</C> </R>
|
|
<R> <C>ieicDoubleSize</C> <C>Stretches the icon to 64x64 and displays it in the centre of the thumbnail box</C> </R>
|
|
<R> <C>ieicStretchHD</C> <C>Under Windows Vista and newer, high quality icons are stretched to the display size, Low quality icons are shown at double size (ieicDoubleSize). On XP and older versions of Windows it functions the same as _icoDoubleSize.</C> </R>
|
|
<R> <C>ieicStretchAll</C> <C>Under Windows Vista and newer, all icons (low and high quality) are stretched to the display size. On XP and older versions of Windows it functions the same as _icoDoubleSize.</C> </R>
|
|
</TABLE>
|
|
|
|
!!}
|
|
TIEImageEnMViewIconSize = (ieicStandardSize, ieicDoubleSize, ieicStretchHD, ieicStretchAll);
|
|
|
|
|
|
{!!
|
|
<FS>TIEMCheckboxType
|
|
|
|
<FM>Declaration<FC>
|
|
TIEMCheckboxType = (iecbNone, iecbShowOnHover, iecbAlways);
|
|
|
|
<FM>Description<FN>
|
|
<TABLE>
|
|
<R> <H>Value</H> <H>Description</H> </R>
|
|
<R> <C>iecbNone</C> <C>Checkboxes are not shown/supported</C> </R>
|
|
<R> <C>iecbShowOnHover</C> <C>Checkboxes are shown when a thumbnail is selected, checked, or when hovered over with the mouse</C> </R>
|
|
<R> <C>iecbAlways</C> <C>Checkboxes are always shown on thumbnails</C> </R>
|
|
</TABLE>
|
|
|
|
!!}
|
|
TIEMCheckboxType = (iecbNone, iecbShowOnHover, iecbAlways);
|
|
|
|
{!!
|
|
<FS>TIEMCheckboxPos
|
|
|
|
<FM>Declaration<FC>
|
|
TIEMCheckboxPos = (iecpTopLeft, iecpTopRight, iecpBottomLeft, iecpBottomRight);
|
|
|
|
<FM>Description<FN>
|
|
<TABLE>
|
|
<R> <H>Value</H> <H>Description</H> </R>
|
|
<R> <C>iecpTopLeft</C> <C>Checkboxes display in the top left of the thumbnail box</C> </R>
|
|
<R> <C>iecpTopRight</C> <C>Checkboxes display in the top right of the thumbnail box</C> </R>
|
|
<R> <C>iecpBottomLeft</C> <C>Checkboxes display in the bottom left of the thumbnail box</C> </R>
|
|
<R> <C>iecpBottomRight</C> <C>Checkboxes display in the bottom right of the thumbnail box</C> </R>
|
|
</TABLE>
|
|
|
|
!!}
|
|
TIEMCheckboxPos = (iecpTopLeft, iecpTopRight, iecpBottomLeft, iecpBottomRight);
|
|
|
|
|
|
{!!
|
|
<FS>TIEMSelectMode
|
|
|
|
<FM>Declaration<FC>
|
|
TIEMSelectMode = (imsNever, imsAuto, imsAlways);
|
|
|
|
<FM>Description<FN>
|
|
<TABLE>
|
|
<R> <H>Value</H> <H>Description</H> </R>
|
|
<R> <C>imsNever</C> <C>The inserted frame is not selected</C> </R>
|
|
<R> <C>imsAuto</C> <C>The inserted frame is selected if there is currently no selection</C> </R>
|
|
<R> <C>imsAlways</C> <C>The inserted frame is selected</C> </R>
|
|
</TABLE>
|
|
|
|
!!}
|
|
TIEMSelectMode = (imsNever, imsAuto, imsAlways);
|
|
|
|
|
|
{!!
|
|
<FS>TIEThumbSizeType
|
|
|
|
<FM>Declaration<FC>
|
|
TIEThumbSizeType = (itsImage, itsCell, itsOuter);
|
|
|
|
<FM>Description<FN>
|
|
<TABLE>
|
|
<R> <H>Value</H> <H>Description</H> </R>
|
|
<R> <C>itsImage</C> <C>Returns the size of the thumbnail image as displayed</C> </R>
|
|
<R> <C>itsCell</C> <C>Returns the size of the thumbnail cell (image, text and cell border)</C> </R>
|
|
<R> <C>itsOuter</C> <C>Returns the size of the thumbnail cell and its external spacing (image, text, cell border and horizontal/vertical border)</C> </R>
|
|
</TABLE>
|
|
|
|
!!}
|
|
TIEThumbSizeType = (itsImage, itsCell, itsOuter);
|
|
|
|
{!!
|
|
<FS>TIEImageEnMViewDefaultText
|
|
|
|
<FM>Declaration<FC>
|
|
type TIEImageEnMViewDefaultText = (iedtNone, iedtFilename, iedtFilenameNoExt, iedtFilePath, iedtImageDimensions, iedtImageDimAndSize, iedtFileSize, iedtFileCreateDate, iedtFileCreateDateTime, iedtFileCreateDateAndSize, iedtFileEditDate, iedtFileEditDateTime, iedtFileEditDateAndSize, iedtFileType, iedtFileExt)
|
|
|
|
<FM>Description<FN>
|
|
Default values for <A TImageEnMView.ImageTopText>, <A TImageEnMView.ImageInfoText> and <A TImageEnMView.ImageBottomText>
|
|
|
|
<TABLE>
|
|
<R> <H>Value</H> <H>Uses Field</H> <H>Displays</H> <H>Example</H> </R>
|
|
<R> <C>iedtNone</C> <C></C> <C>Caption will be blank, by default</C> <C></C> </R>
|
|
<R> <C>iedtFilename</C> <C>IEM_Filename</C> <C>Name of the file (without path)</C> <C>'MyImage.jpg'</C> </R>
|
|
<R> <C>iedtFilenameNoExt</C> <C>IEM_FilenameNoExt</C> <C>Name of the file without its extension (or path)</C> <C>'MyImage'</C> </R>
|
|
<R> <C>iedtFilePath</C> <C>IEM_FilePath</C> <C>Path of the file</C> <C>'C:\Data\My Pictures\'</C> </R>
|
|
<R> <C>iedtImageDimensions</C> <C>IEM_ImageDimensions</C> <C>Dimensions and color depth of images (Nothing is shown for non-images)</C> <C>'1200 x 800'</C> </R>
|
|
<R> <C>iedtImageDimAndSize</C> <C>IEM_ImageDimAndSize</C> <C>Dimensions of images with the file size</C> <C>'1200 x 800, 3,900 KB'</C> </R>
|
|
<R> <C>iedtFileSize</C> <C>IEM_FileSize</C> <C>Size of the file on disk</C> <C>'3,900 KB'</C> </R>
|
|
<R> <C>iedtFileCreateDate</C> <C>IEM_FileCreateDate</C> <C>The date that the file was created</C> <C>'7/5/13'</C> </R>
|
|
<R> <C>iedtFileCreateDateTime</C> <C>IEM_FileCreateDateTime</C> <C>The date and time that the file was created</C> <C>'7/5/13 8:03am'</C> </R>
|
|
<R> <C>iedtFileCreateDateAndSize</C> <C>IEM_FileCreateDateAndSize</C> <C>The create date of the file and its size</C> <C>'7/5/13, 3,900 KB'</C> </R>
|
|
<R> <C>iedtFileEditDate</C> <C>IEM_FileEditDate</C> <C>The date that the file was last edited</C> <C>'7/5/13'</C> </R>
|
|
<R> <C>iedtFileEditDateTime</C> <C>IEM_FileEditDateTime</C> <C>The date and time that the file was last edited</C> <C>'7/5/13 8:03am'</C> </R>
|
|
<R> <C>iedtFileEditDateAndSize</C> <C>IEM_FileEditDateAndSize</C> <C>The last edit date of the file and its size</C> <C>'7/5/13, 3,900 KB'</C> </R>
|
|
<R> <C>iedtFileType</C> <C>IEM_FileType</C> <C>The ImageEn type for this file</C> <C>'JPEG Image'</C> </R>
|
|
<R> <C>iedtFileExt</C> <C>IEM_FileExt</C> <C>The extension only of the file, e.g. JPEG for 'MyImage.jpeg'</C> <C>'JPEG'</C> </R>
|
|
</TABLE>
|
|
|
|
<FM>Example<FC>
|
|
// Display the filename and dimensions for each image in C:\Images
|
|
IEFolderMView1.DefaultImageInfoText := iedtImageDimensions;
|
|
IEFolderMView1.DefaultImageBottomText := iedtFilename;
|
|
IEFolderMView1.RefreshFileList;
|
|
end;
|
|
!!}
|
|
TIEImageEnMViewDefaultText = (iedtNone ,
|
|
iedtFilename ,
|
|
iedtFilenameNoExt ,
|
|
iedtFilePath ,
|
|
iedtImageDimensions ,
|
|
iedtImageDimAndSize ,
|
|
iedtFileSize ,
|
|
iedtFileCreateDate ,
|
|
iedtFileCreateDateTime ,
|
|
iedtFileCreateDateAndSize ,
|
|
iedtFileEditDate ,
|
|
iedtFileEditDateTime ,
|
|
iedtFileEditDateAndSize ,
|
|
iedtFileType ,
|
|
iedtFileExt );
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TIEStoreType
|
|
|
|
<FM>Declaration<FC>
|
|
type TIEStoreType = (ietNormal, ietThumb, ietFastThumb);
|
|
|
|
<FM>Description<FN>
|
|
Specifies how images are loaded.
|
|
|
|
<TABLE>
|
|
<R> <H>Value</H> <H>Description</H> </R>
|
|
<R> <C>ietNormal</C> <C>The full bitmap is kept in memory</C> </R>
|
|
<R> <C>ietThumb</C> <C>A sub-sampled copy of the bitmap is kept in memory (of the size specified by <A TImageEnMView.ThumbWidth> and <A TImageEnMView.ThumbHeight>).</C> </R>
|
|
<R> <C>ietFastThumb</C> <C>Only the cached image of the display thumbnail is held in memory. If the thumbnail is cleared from the cache it will need to be reloaded</C> </R>
|
|
</TABLE>
|
|
|
|
|
|
<FM>ietThumb vs ietFastThumb<FN>
|
|
When using ietFastThumb, creation of the thumbnail is delayed until it is shown on screen. Prior to this a full size image of each frame may be held in memory. For this reason ietFastThumb should not be used unless thumbnail frames are being loaded on demand (or there is not a large amount of off-screen frames).
|
|
|
|
ietFastThumb can improve the quality of thumbnails, particularly when using <A TImageEnMView.ImageInfoText> and <A TImageEnMView.ThumbnailClipping>. It cannot be used if you have disabled <L TImageEnMView.EnableImageCaching>image caching</L>.
|
|
|
|
If you are using ietFastThumb then you should significantly increase the <A TImageEnMView.ImageCacheSize> to something larger, such as 200.
|
|
|
|
!!}
|
|
TIEStoreType = (
|
|
// the image will be full loaded
|
|
ietNormal,
|
|
// the image will loaded as thumbnail (see ThumbWidth, ThumbHeight))
|
|
ietThumb,
|
|
// Thumbnail creation is delayed until it is drawn, then it is stored in CacheImage and Image is cleared
|
|
ietFastThumb
|
|
);
|
|
|
|
|
|
{!!
|
|
<FS>TIEFolderImageType
|
|
|
|
<FM>Declaration<FC>
|
|
type TIEFolderImageType = (ieftSupportedImage, ieftFile, ieftFolder);
|
|
|
|
<FM>Description<FN>
|
|
Returns the type of file for a frame/thumbnail.
|
|
|
|
<TABLE>
|
|
<R> <H>Value</H> <H>Description</H> </R>
|
|
<R> <C>ieftSupportedImage</C> <C>The frame is a supported image (or video) type</C> </R>
|
|
<R> <C>ieftFile</C> <C>The frame is for an unknown file type</C> </R>
|
|
<R> <C>ieftFolder</C> <C>The frame is a system folder or drive</C> </R>
|
|
</TABLE>
|
|
|
|
|
|
!!}
|
|
TIEFolderImageType = (ieftSupportedImage, ieftFile, ieftFolder);
|
|
|
|
|
|
{!!
|
|
<FS>TIEMTextPos
|
|
|
|
<FM>Declaration<FC>
|
|
}
|
|
TIEMTextPos = (iemtpTop, iemtpBottom, iemtpInfo);
|
|
{!!}
|
|
|
|
|
|
// Whether thumbnails in the cache list can be reused after an update
|
|
// Only supported by TIEDBMultiBitmap
|
|
TIEImageCacheReusage = (iecrNone, // No reuse of cached images
|
|
iecrLoose, // Most Reuse: Any cached thumbnails with matching filename
|
|
iecrStrict // Least Reuse: Any cached thumbnails with matching filename at same indexed position
|
|
);
|
|
|
|
|
|
{!!
|
|
<FS>TIEGetTextEvent
|
|
|
|
<FM>Declaration<FC>
|
|
type TIEGetTextEvent = procedure(Sender: TObject; Index: integer; Position : <A TIEMTextPos>; var Text: WideString) of object;
|
|
|
|
<FM>Description<FN>
|
|
Occurs before text is output when drawing a thumbnail allowing you to insert or modify the displayed text (by specifying a new value for <FC>Text<FN>).
|
|
|
|
<TABLE>
|
|
<R> <H>Position</H> <H>Description</H> </R>
|
|
<R> <C>iemtpTop</C> <C>Overrides the text specified for <A TImageEnMView.ImageTopText></C> </R>
|
|
<R> <C>iemtpInfo</C> <C>Overrides the text specified for <A TImageEnMView.ImageInfoText></C> </R>
|
|
<R> <C>iemtpBottom</C> <C>Overrides the text specified for <A TImageEnMView.ImageBottomText></C> </R>
|
|
</TABLE>
|
|
|
|
Note:
|
|
- Ensure that you have set <A TImageEnMView.UpperGap>/<A TImageEnMView.BottomGap> to allow space for the text
|
|
- Setting <FC>Text<FN> only modifies the text that is displayed, not the value in ImageTopText/ImageInfoText/ImageBottomText
|
|
|
|
<FM>Example<FC>
|
|
// Note: In form create we set IEFolderMView.UpperGap := 20;
|
|
|
|
// Display the file index above the frame
|
|
procedure TForm1.IEFolderMViewGetText(Sender: TObject; Index: Integer; Position: TIEMTextPos; var Text: WideString);
|
|
begin
|
|
if Position = iemtpTop then
|
|
Text := 'File #' + IntToStr(Index + 1);
|
|
end;
|
|
|
|
!!}
|
|
TIEGetTextEvent = procedure(Sender: TObject; Index: integer; Position : TIEMTextPos; var Text: WideString) of object;
|
|
|
|
{!!
|
|
<FS>TIEGetTextExEvent
|
|
|
|
<FM>Declaration<FC>
|
|
type TIEGetTextExEvent = procedure(Sender: TObject; Index: integer; Position : <A TIEMTextPos>; var Text: WideString;
|
|
Font : TFont; var BackgroundStyle: TBrushStyle; var BackgroundColor: TColor;
|
|
var TruncSide: <A TIEMTruncSide>) of object;
|
|
|
|
<FM>Description<FN>
|
|
Occurs before text is output when drawing a thumbnail allowing you to insert or modify the displayed text or change its formatting.
|
|
|
|
<TABLE>
|
|
<R> <H>Position</H> <H>Description</H> </R>
|
|
<R> <C>iemtpTop</C> <C>Overrides the text specified for <A TImageEnMView.ImageTopText></C> </R>
|
|
<R> <C>iemtpInfo</C> <C>Overrides the text specified for <A TImageEnMView.ImageInfoText></C> </R>
|
|
<R> <C>iemtpBottom</C> <C>Overrides the text specified for <A TImageEnMView.ImageBottomText></C> </R>
|
|
</TABLE>
|
|
|
|
Note:
|
|
- Ensure that you have set <A TImageEnMView.UpperGap>/<A TImageEnMView.BottomGap> to allow space for the text
|
|
- Setting <FC>Text<FN> only modifies the text that is displayed, not the value in ImageTopText/ImageInfoText/ImageBottomText
|
|
- Font.Color cannot be overriden for selected or disabled frames
|
|
|
|
<FM>Example<FC>
|
|
// Display the file as bold if it is JPEG
|
|
procedure TForm1.IEFolderMViewGetTextEx(Sender: TObject; Index: Integer; Position: TIEMTextPos; var Text: WideString;
|
|
Font : TFont; var BackgroundStyle: TBrushStyle; var BackgroundColor: TColor;
|
|
var TruncSide: TIEMTruncSide);
|
|
begin
|
|
if Position <> iemtpBottom then
|
|
exit;
|
|
sFileExt := ExtractFileExt( Text );
|
|
if IEExtToFileFormat( sFileExt ) = ioJPEG then
|
|
Font.Style := [fsBold]
|
|
else
|
|
Font.Style := [];
|
|
end;
|
|
|
|
// Give text on every thumb a random background color
|
|
procedure TForm1.IEFolderMViewGetTextEx(Sender: TObject; Index: Integer; Position: TIEMTextPos; var Text: WideString;
|
|
Font : TFont; var BackgroundStyle: TBrushStyle; var BackgroundColor: TColor;
|
|
var TruncSide: TIEMTruncSide);
|
|
begin
|
|
BackgroundColor := RGB(Random(255), Random(255), Random(255));;
|
|
BackgroundStyle := bsSolid;
|
|
end;
|
|
|
|
!!}
|
|
TIEGetTextExEvent = procedure(Sender: TObject; Index: integer; Position : TIEMTextPos; var Text: WideString;
|
|
Font : TFont; var BackgroundStyle: TBrushStyle; var BackgroundColor: TColor;
|
|
var TruncSide: TIEMTruncSide) of object;
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TIEMThumbnailOptionsEx
|
|
|
|
<FM>Declaration<FC>
|
|
type TIEMThumbnailOptionsEx = set of (ietxCenterThumbnailColumn, ietxShowIconForUnknownFormat, ietxShowIconWhileLoading, ietxShowShadowForIcons, ietxShowShadowForFolders, ietxEnableInternalIcons, ietxStretchSmallImages, ietxOnlyShowIcons);
|
|
|
|
<FM>Description<FN>
|
|
<TABLE>
|
|
<R> <H>Value</H> <H>Description</H> </R>
|
|
<R> <C>ietxCenterThumbnailColumn</C> <C>If enabled and one or more columns are displayed (i.e. <A TImageEnMView.GridWidth> <> 0) then the thumbnails will be centered horizontally in the view (but not vertically centered).
|
|
If enabled and only one row is displayed (i.e. <A TImageEnMView.GridWidth> = 0) then the thumbnails will be centered vertically in the view (but not horizontally centered).
|
|
When not enabled, the top-left thumbnail will always be at a distance of <A TImageEnMView.HorizBorder> x <A TImageEnMView.VertBorder> from the corner.</C> </R>
|
|
<R> <C>ietxShowIconForUnknownFormat</C> <C>If enabled, then for any ImageFileName of an unknown format ImageEn will load the default icon for that file type (retrieved from Windows using the ShGetFileInfo Shell API function). Otherwise a question mark is displayed.
|
|
Note: Don't disable this option if you are showing folders</C> </R>
|
|
<R> <C>ietxShowIconWhileLoading</C> <C>If enabled, then the default icon for each file type is displayed while the content is loaded (retrieved from Windows using the ShGetFileInfo Shell API function). Otherwise a blank thumbnail is displayed.</C> </R>
|
|
<R> <C>ietxShowShadowForIcons</C> <C>If <A TImageEnMView.SoftShadow> is enabled, then this option determines whether the shadow is displayed for file icons</C> </R>
|
|
<R> <C>ietxShowShadowForFolders</C> <C>If <A TImageEnMView.SoftShadow> is enabled, then this option determines whether the shadow is displayed for folder icons</C> </R>
|
|
<R> <C>ietxEnableInternalIcons</C> <C>If ietxShowIconWhileLoading is not specified, then while loading either a blank or internal icon will be displayed (can be set with <A TImageEnMView.DefaultFileIcon>). Also, when specified an internal icon is shown for files that cannot be found(can be set with <A TImageEnMView.MissingFileIcon>).</C> </R>
|
|
<R> <C>ietxStretchSmallImages</C> <C>If specified, images smaller than the thumbnail cell will be stretched (resampled) to the size of other thumbnail images. If not specified, small images shown at 100% size.</C> </R>
|
|
<R> <C>ietxOnlyShowIcons</C> <C>Disables image thumbnails and only shows file icons (even for supported image types.</C> </R>
|
|
</TABLE>
|
|
|
|
<FM>Example 1<FC>
|
|
// Use icons for unknown files
|
|
ImageEnMView1.ThumbnailOptionsEx := ImageEnMView1.ThumbnailOptionsEx + [ietxShowIconForUnknownFormat];
|
|
|
|
// Display all files (not only image files)
|
|
ImageEnMView1.FillFromDirectory('C:\', -1, true);
|
|
|
|
<FM>Example 2<FC>
|
|
// Do not show shadows for any icon types
|
|
ImageEnMView1.ThumbnailOptionsEx := ImageEnMView1.ThumbnailOptionsEx - [ietxShowShadowForIcons, ietxShowShadowForFolders];
|
|
|
|
// Redraw the display
|
|
ImageEnMView1.Update;
|
|
|
|
<FM>Example 3<FC>
|
|
// Create a single column of centered thumbnails
|
|
ImageEnMView1.GridWidth := 1;
|
|
ImageEnMView1.ThumbnailOptionsEx := ImageEnMView1.ThumbnailOptionsEx + [ietxCenterThumbnailColumn];
|
|
ImageEnMView1.Update;
|
|
|
|
<FM>Example 4<FC>
|
|
// Show file list with icons
|
|
ImageEnMView1.ThumbnailOptionsEx := ImageEnMView1.ThumbnailOptionsEx + [ ietxOnlyShowIcons ];
|
|
ImageEnMView1.GridWidth := 1
|
|
ImageEnMView1.SetStyleEx( iemsFlatAndWide, iedtNone, iedtNone, iedtFileName, -24 );
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.GridWidth>
|
|
- <A TImageEnMView.SoftShadow>
|
|
- <A TImageEnMView.IconSize>
|
|
!!}
|
|
|
|
TIEMThumbnailOptionsExItems = (ietxCenterThumbnailColumn, ietxShowIconForUnknownFormat, ietxShowIconWhileLoading, ietxShowShadowForIcons, ietxShowShadowForFolders, ietxEnableInternalIcons, ietxStretchSmallImages, ietxOnlyShowIcons);
|
|
TIEMThumbnailOptionsEx = set of TIEMThumbnailOptionsExItems;
|
|
|
|
|
|
{!!
|
|
<FS>TIEMIOOptionsEx
|
|
|
|
<FM>Declaration<FC>
|
|
type TIEMIOOptionsEx = set of (ieixLoadOnlyByFileExt, ieixWantParams, ieixRemoveCorrupted);
|
|
|
|
<FM>Description<FN>
|
|
<TABLE>
|
|
<R> <H>Value</H> <H>Description</H> </R>
|
|
<R> <C>ieixLoadOnlyByFileExt</C> <C>By default, file types are determined by analyzing the message header. A quicker method is to use the file extension to determine the file type. Though this means that images with incorrect or invalid file extensions will not load</C> </R>
|
|
<R> <C>ieixWantParams</C> <C>When using <FC>ieixLoadOnlyByFileExt<FN> or <A TImageEnMView.EnableLoadExplorerThumbnails> loading of <A TImageEnMIO.Params> is skipped, so <L TImageEnMView.DefaultTopText>text fields</L> that display this data will be empty. Enabling this option forces the loading of params</C> </R>
|
|
<R> <C>ieixRemoveCorrupted</C> <C>Images within the grid that are invalid will be automatically removed</C> </R>
|
|
</TABLE>
|
|
|
|
<FM>Example<FC>
|
|
// Use the file extension to determine its type (to increase speed)
|
|
ImageEnMView1.IOOptionsEx := ImageEnMView1.IOOptionsEx + [ ieixLoadOnlyByFileExt ];
|
|
|
|
// Automatically remove any corrupted (unreadable) images from the grid.
|
|
ImageEnMView1.IOOptionsEx := ImageEnMView1.IOOptionsEx + [ ieixRemoveCorrupted ];
|
|
!!}
|
|
|
|
TIEMIOOptionsExItems = (ieixLoadOnlyByFileExt, ieixWantParams, ieixRemoveCorrupted);
|
|
TIEMIOOptionsEx = set of TIEMIOOptionsExItems;
|
|
|
|
|
|
// automatic interactions with mouse
|
|
{!!
|
|
<FS>TIEMMouseInteractItems
|
|
|
|
<FM>Declaration<FC>
|
|
}
|
|
TIEMMouseInteractItems = (
|
|
mmiScroll, // Hand-scroll. Mouse drag scrolls images.
|
|
mmiSelect // Images selection. Mouse click select images.
|
|
);
|
|
{!!}
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TIEMMouseInteract
|
|
|
|
<FM>Declaration<FC>
|
|
type TIEMMouseInteract = set of <A TIEMMouseInteractItems>;
|
|
|
|
<FM>Description<FN>
|
|
<TABLE>
|
|
<R> <H>Value</H> <H>Description</H> </R>
|
|
<R> <C>mmiScroll</C> <C>Dragging the mouse will scroll the images</C> </R>
|
|
<R> <C>mmiSelect</C> <C>Clicking the mouse will select images</C> </R>
|
|
</TABLE>
|
|
|
|
!!}
|
|
TIEMMouseInteract = set of TIEMMouseInteractItems;
|
|
|
|
{!!
|
|
<FS>TIEMKeyInteractItems
|
|
|
|
<FM>Declaration<FC>
|
|
}
|
|
// automatic interaction with keyboard
|
|
TIEMKeyInteractItems = (
|
|
mkiMoveSelected // move selected item (up, down, left, right)
|
|
);
|
|
{!!}
|
|
|
|
{!!
|
|
<FS>TIEMKeyInteract
|
|
|
|
<FM>Declaration<FC>
|
|
TIEMKeyInteract = set of <A TIEMKeyInteractItems>;
|
|
!!}
|
|
TIEMKeyInteract = set of TIEMKeyInteractItems;
|
|
|
|
{!!
|
|
<FS>TIEMDisplayMode
|
|
|
|
<FM>Declaration<FC>
|
|
type TIEMDisplayMode = (mdGrid, mdSingle);
|
|
|
|
<FM>Description<FN>
|
|
<TABLE>
|
|
<R> <H>Value</H> <H>Description</H> </R>
|
|
<R> <C>mdGrid</C> <C>Thumbnail view: Images are shown in a grid (of <A TImageEnMView.GridWidth> columns)</C> </R>
|
|
<R> <C>mdSingle</C> <C>Frame view: Only one image is shown at a time (specified by <A TImageEnMView.VisibleFrame> property)</C> </R>
|
|
</TABLE>
|
|
|
|
!!}
|
|
TIEMDisplayMode = (
|
|
mdGrid, // grid (active fGridWidth property)
|
|
mdSingle // single frame
|
|
);
|
|
|
|
{!!
|
|
<FS>TIESeek
|
|
|
|
<FM>Declaration<FC>
|
|
TIESeek = (iskLeft, iskRight, iskUp, iskDown, iskFirst, iskLast, iskPagDown, iskPagUp);
|
|
|
|
<FM>Description<FN>
|
|
<TABLE>
|
|
<R> <H>Value</H> <H>Description</H> </R>
|
|
<R> <C>iskLeft</C> <C>Move to the left (by one column)</C> </R>
|
|
<R> <C>iskRight</C> <C>Move to the right (by one column)</C> </R>
|
|
<R> <C>iskUp</C> <C>Move up (by one row)</C> </R>
|
|
<R> <C>iskDown</C> <C>Move down (by one row)</C> </R>
|
|
<R> <C>iskFirst</C> <C>Move to first image</C> </R>
|
|
<R> <C>iskLast</C> <C>Move to the last image</C> </R>
|
|
<R> <C>iskPagDown</C> <C>Move to the next page</C> </R>
|
|
<R> <C>iskPagUp</C> <C>Move to the previous page</C> </R>
|
|
<R> <C>iskPrior</C> <C>Same as iskLeft, but reversed when <A TImageEnMView.BiDiMode> is bdRightToLeft</C> </R>
|
|
<R> <C>iskNext</C> <C>Same as iskRight, but reversed when <A TImageEnMView.BiDiMode> is bdRightToLeft</C> </R>
|
|
</TABLE>
|
|
!!}
|
|
TIESeek = (iskLeft, iskRight, iskUp, iskDown, iskFirst, iskLast, iskPagDown, iskPagUp, iskPrior, iskNext);
|
|
|
|
{!!
|
|
<FS>TIEMStyle
|
|
|
|
<FM>Declaration<FC>
|
|
TIEMStyle = (iemsFlat, iemsACD, iemsFlatAndWide, iemsColumns);
|
|
|
|
<FM>Description<FN>
|
|
<TABLE>
|
|
<R> <H>Value</H> <H>Description</H> </R>
|
|
<R> <C>iemsFlat</C> <C>Flat style</C></R>
|
|
<R> <C>iemsACD</C> <C>3D style (default)</C></R>
|
|
<R> <C>iemsFlatAndWide</C> <C>Flat style with text on the right-hand side</C></R>
|
|
<R> <C>iemsColumns</C> <C>Separate columns are used for thumbnails and text fields</C></R>
|
|
</TABLE>
|
|
|
|
<FM>Notes on iemsColumns<FN>
|
|
A header row is displayed with the <FC>iemsColumns<FN> style. <A TImageEnMView.InfoTextFont> is used for the font formatting, but this can be overriden in the <A TImageEnMView.OnGetTextEx> event. The header row caption is based on the <L TImageEnMView.DefaultTopText>default text</L>, but can be overriden in <A TImageEnMView.OnGetText> or <A TImageEnMView.OnGetTextEx>.
|
|
Columns will be shown for text fields which have text specified (e.g. using <A TImageEnMView.DefaultTopText>) and a valid <L TImageEnMView.TextColumnWidths>width</L>. Columns are displayed in the order: <A TImageEnMView.DefaultTopText>, <A TImageEnMView.DefaultBottomText>, <A TImageEnMView.DefaultInfoText>.
|
|
<IMG help_images\Columns.jpg>
|
|
!!}
|
|
TIEMStyle = (iemsFlat, iemsACD, iemsFlatAndWide, iemsColumns);
|
|
|
|
|
|
{!!
|
|
<FS>TIEMultiSelectionOptions
|
|
|
|
<FM>Declaration<FC>
|
|
TIEMultiSelectionOptions = set of (iemoRegion, iemoSelectOnMouseUp, iemoLeaveOneSelected, iemoRegionOnShift, iemoOptimizeForDragging, iemoSelectOnRightClick);
|
|
|
|
<FM>Description<FN>
|
|
<TABLE>
|
|
<R> <H>Value</H> <H>Description</H> </R>
|
|
<R> <C>iemoRegion</C> <C>Select only items inside selection rectangle</C> </R>
|
|
<R> <C>iemoSelectOnMouseUp</C> <C>By default, ImageEn selects an image on mouse down. If iemoSelectOnMouseUp is specified, ImageEn delays selection until mouse up</C> </R>
|
|
<R> <C>iemoLeaveOneSelected</C> <C>If specified, at least one item remains selected. Note: works only when the user deselects multiple images</C> </R>
|
|
<R> <C>iemoRegionOnShift</C> <C>If specified, pressing <FC>Shift<FN> only selects items inside rectangle</C> </R>
|
|
<R> <C>iemoOptimizeForDragging</C> <C>Makes the behavior closer to Windows Explorer when selecting a region. If you click outside a selection it creates a region, if you click on an existing selection it does nothing. This is particularly useful if you need to support dragging</C> </R>
|
|
<R> <C>iemoSelectOnRightClick</C> <C>Makes the behavior closer to Windows Explorer. When right-clicking outside the selection the new frame is selected. By default this is not specified, meaning that right-clicking has no effect on selection</C> </R>
|
|
</TABLE>
|
|
!!}
|
|
TIEMultiSelectionOptions = set of (iemoRegion, iemoSelectOnMouseUp, iemoLeaveOneSelected, iemoRegionOnShift, iemoOptimizeForDragging, iemoSelectOnRightClick);
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TIEPlayFrameEvent
|
|
|
|
<FM>Declaration<FC>
|
|
}
|
|
TIEPlayFrameEvent = procedure(Sender: TObject; FrameIndex: integer; var bShowFrame: Boolean) of object;
|
|
{!!}
|
|
|
|
|
|
TImageEnMView = class;
|
|
|
|
TIEStarter = class(TThread)
|
|
public
|
|
mview: TImageEnMView;
|
|
resumeEvent: THandle;
|
|
constructor Create;
|
|
destructor Destroy; override;
|
|
procedure Execute; override;
|
|
end;
|
|
|
|
|
|
|
|
// CLASSES TO HANDLE CACHING OF ICONS
|
|
// NPC: 10/6/14
|
|
TCachedIconType = (citFullDraw, citIconOnly);
|
|
TIECachedIcon = class
|
|
private
|
|
public
|
|
Bmp : TIEBitmap;
|
|
Ext : string;
|
|
constructor Create(aBmp: TIEBitmap; const sExt: string);
|
|
destructor Destroy(); override;
|
|
function MatchesExt(const sExt : string) : Boolean;
|
|
end;
|
|
|
|
TIECachedIconList = class
|
|
private
|
|
fOwner : TImageEnMView;
|
|
fMaxIconCount : Integer;
|
|
fDataList : TList;
|
|
fOwnerSoftShadowEnabled : Boolean;
|
|
fOwnerSoftShadowRadius : Double;
|
|
|
|
procedure ClearLastItem();
|
|
function LookUpExt(const sExt : string) : Integer;
|
|
function GetCacheName(aType : TCachedIconType; const sFilename : string; bIsFolder : Boolean) : string;
|
|
public
|
|
constructor Create(Owner : TImageEnMView; iMaxIconCount : Integer);
|
|
destructor Destroy(); override;
|
|
procedure Clear();
|
|
function RetrieveFromCache(aType : TCachedIconType; const sFilename : string; bIsFolder : Boolean; var Dest : TIEBitmap; bWantCopy : Boolean): boolean;
|
|
procedure SaveToCache(Image : TIEBitmap; aType : TCachedIconType; const sFilename : string; bIsFolder : Boolean);
|
|
end;
|
|
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TIEAnimationTextEvent
|
|
|
|
<FM>Declaration<FC>
|
|
}
|
|
TIEAnimationTextEvent = procedure(Sender: TObject; imageIndex: integer; var text: WideString) of object;
|
|
{!!}
|
|
|
|
|
|
{!!
|
|
<FS>TIEAfterEvent
|
|
|
|
<FM>Declaration<FC>
|
|
TIEAfterEventEvent = procedure(Sender: TObject; Event: <A TIEAfterEvent>) of object;
|
|
|
|
<FM>Description<FN>
|
|
}
|
|
TIEAfterEvent = (ieaeMouseDown, ieaeMouseUp, ieaeKeyDown, ieaeKeyUp, ieaePaint);
|
|
{!!}
|
|
|
|
|
|
{!!
|
|
<FS>TIEAfterEventEvent
|
|
|
|
<FM>Declaration<FC>
|
|
TIEAfterEventEvent = procedure(Sender: TObject; Event: <A TIEAfterEvent>) of object;
|
|
|
|
<FM>Description<FN>
|
|
Occurs after ImageEn has processed an event.
|
|
!!}
|
|
TIEAfterEventEvent = procedure(Sender: TObject; Event: TIEAfterEvent) of object;
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TIEMViewerGestures
|
|
|
|
<FM>Description<FN>
|
|
TImageEnMView supports native Windows gestures:
|
|
- Dragging the screen to pan an image
|
|
- Pinching to zoom in
|
|
- Reverse-pinching to zoom out
|
|
|
|
This class contains the properties to configure the gestures.
|
|
|
|
<FM>Methods and Properties<FN>
|
|
<TABLE2>
|
|
<R> <C_IMG_PROPERTY> <C><A TIEMViewerGestures.Enabled></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TIEMViewerGestures.Pan></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TIEMViewerGestures.Zoom></C> </R>
|
|
</TABLE>
|
|
!!}
|
|
TIEMViewerGestures = class
|
|
private
|
|
fPan: TIEGesturePanOptions;
|
|
fZoom: TIEGestureZoomOptions;
|
|
|
|
function GetEnabled(): boolean;
|
|
|
|
public
|
|
constructor Create();
|
|
destructor Destroy(); override;
|
|
|
|
{!!
|
|
<FS>TIEMViewerGestures.Enabled
|
|
|
|
<FM>Declaration<FC>
|
|
property Enabled: boolean; (Read-only)
|
|
|
|
<FM>Description<FN>
|
|
Returns true whenever at least one gesture is enabled.
|
|
|
|
!!}
|
|
property Enabled: boolean read GetEnabled;
|
|
|
|
{!!
|
|
<FS>TIEMViewerGestures.Pan
|
|
|
|
<FM>Declaration<FC>
|
|
property Pan: <A TIEGesturePanOptions>;
|
|
|
|
<FM>Description<FN>
|
|
Allows enabling and configuration of the Pan (image scrolling) gesture. The Windows gesture to "Pan with inertia" is performed on the action of "dragging 1 or 2 fingers".
|
|
!!}
|
|
property Pan: TIEGesturePanOptions read fPan;
|
|
|
|
{!!
|
|
<FS>TIEMViewerGestures.Zoom
|
|
|
|
<FM>Declaration<FC>
|
|
property Zoom: <A TIEGestureZoomOptions>;
|
|
|
|
<FM>Description<FN>
|
|
Allows enabling and configuration of the Zoom gesture. The Windows gesture of "Zoom" is performed by "moving two fingers apart/towards each other".
|
|
!!}
|
|
property Zoom: TIEGestureZoomOptions read fZoom;
|
|
end;
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView
|
|
|
|
<FM>Description<FN>
|
|
The TImageEnMView component is similar to a <A TImageEnView>, but is designed for multiple images:
|
|
- Multiple images can be displayed in a grid (similar to a thumbnail view in Windows Explorer)
|
|
- A single frame of a multiple-frame image (such as a GIF, AVI or TIFF) can be displayed. This can also be animated.
|
|
|
|
ImageEn supports loading and saving multiple frames from GIF, TIFF, AVI, DCX, DICOM and ICO formats. It can also load from CUR format, and save to PDF and PS format (loading of PDF is supported if a <L TImageEnMIO.LoadFromFilePDF>relevant plug-in</L> is installed).
|
|
|
|
The images can be stored as full images, as thumbnails (a sub-resampled image of the original), loaded when displayed (you need only specify the file name), or upon request (an event is generated whenever an image needs to be shown).
|
|
Thumbnails for video formats are retrieved from Windows Explorer. This can be disabled or expanded by setting <A TIEImageEnGlobalSettings.MViewExplorerThumbnailExts>.
|
|
|
|
For rapid UI development a full set of <L TImageEnMView Actions>actions</L> is also available.
|
|
|
|
You can also specify a custom function whenever an image is shown (i.e., to paint the image index near the image).
|
|
|
|
Note: Do not attach a <A TImageEnIO> component to TImageEnMView. Only the <A TImageEnMIO> component can be attached to a TImageEnMView component, or you can use embedded <A TImageEnMView.MIO> object.
|
|
|
|
|
|
<IMG help_images\IEMView_Thumbnails.gif> <IMG help_images\IEMView_Multiframe.gif>
|
|
|
|
<FM>Demos<FN>
|
|
<TABLE2>
|
|
<R> <C_IMG_DEMO> <C>Demos\Multi\... </C> </R>
|
|
<R> <C_IMG_DEMO> <C>Demos\Other\Actions_MView\MViewActions.dpr </C> </R>
|
|
</TABLE>
|
|
|
|
<FM>Example<FC>
|
|
// In FormCreate()
|
|
with ImageEnMView1 do
|
|
begin
|
|
// Update to the most modern styling
|
|
SetModernStyling(False);
|
|
|
|
ThumbWidth := 140; // Better size for thumbnails
|
|
ThumbHeight := 150;
|
|
|
|
GridWidth := -1; // Auto-column widths
|
|
BorderStyle := bsNone; // Normally don't require a 3D border
|
|
|
|
StoreType := ietThumb; // Don't need to store whole image in memory, just a sub-sampled thumbnail
|
|
end;
|
|
|
|
// Now display the images of a folder in the grid
|
|
ImageEnMView1.FillFromDirectory('C:\MyImages\', -1, False, '', False, '', True);
|
|
|
|
<FM>Methods and Properties<FN>
|
|
<FI>Display<FN>
|
|
<TABLE2>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.Animation></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.AnnotationsVisible></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.Background></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.BackgroundStyle></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.BiDiMode></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.CenterFrame></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.ClearImageCache></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.DefaultFileIcon></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.DisplayImageAt></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.DisplayMode></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.EnableAlphaChannel></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.FlatScrollBars></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.GradientEndColor></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.GridWidth> (Column count)</C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.LockPaint></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.LockPaintCount></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.LockUpdate></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.LockUpdateCount></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.MaximumViewX></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.MaximumViewY></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.MissingFileIcon></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.SetChessboardStyle></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.SetPresetThumbnailFrame> </C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.SetModernStyling></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.SetStyleEx></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.SetViewXY></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.SoftShadow></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.Style></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.UnLockPaint></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.UnLockUpdate></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.ViewX></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.ViewY></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.VisibleFrame></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.Wallpaper></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.WallpaperStyle></C> </R>
|
|
</TABLE>
|
|
|
|
<FI>Frame Editing<FN>
|
|
<TABLE2>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.Assign></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.AssignEx></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.AppendImage></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.AppendSplit></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.Clear></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.CreateMorphingSequence></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.DeleteImage> </C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.ImageCount></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.InsertImageEx></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.InsertImage></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.InsertTransitionFrames></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.InsertTransitionFramesEx></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.MoveImage></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.RemoveBlankPages></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.RemoveDuplicates></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.Sort></C> </R>
|
|
</TABLE>
|
|
|
|
<FI>Image Access<FN>
|
|
<TABLE2>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.Bitmap></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.CopyToIEBitmap></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.GetBitmap></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.GetTIEBitmap></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.IEBitmap></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.PrepareSpaceFor></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.ReleaseBitmap></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.SetImage></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.SetImageEx></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.SetImageRect></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.UpdateImage></C> </R>
|
|
</TABLE>
|
|
|
|
<FI>Image Information<FN>
|
|
<TABLE2>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.FilenameToIndex></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.ImageBitCount></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.ImageCol></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.ImageCreateDate> </C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.ImageEditDate></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.ImageFileName></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.ImageFileSize></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.ImageFileType></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.ImageHeight></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.ImageID></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.ImageOriginalHeight></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.ImageOriginalWidth></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.ImageRow></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.ImageTag></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.ImageUserPointer></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.ImageWidth></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.ImageX></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.ImageY></C> </R>
|
|
</TABLE>
|
|
|
|
<FI>Image Text<FN>
|
|
<TABLE2>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.BottomTextFont></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.DefaultBottomText></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.DefaultInfoText></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.DefaultTopText></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.ImageBottomText></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.ImageInfoText></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.ImageTopText></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.InfoTextFont></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.SelectedFontColor></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.SetAllText></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.ShowText></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.TextColumnWidths></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.TextBackgroundColor></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.TextBackgroundStyle></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.TextBlockWidth></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.TextMargin></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.TextTruncSide></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.TopTextFont></C> </R>
|
|
</TABLE>
|
|
|
|
<FI>Thumbnail Appearance<FN>
|
|
<TABLE2>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.BottomGap></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.DrawImageBackground></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.HorizBorder></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.IconSize></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.FillThumbnail></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.ImageBackground></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.SetThumbnailSize></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.ShowThumbnailHint></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.SideGap></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.ThumbHeight></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.ThumbnailClipping></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.ThumbnailDisplayFilter></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.ThumbnailFrameRect></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.ThumbnailFrameSelected></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.ThumbnailFrame></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.ThumbnailResampleFilter></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.ThumbnailsBackground></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.ThumbnailsBackgroundSelected></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.ThumbnailsBackgroundStyle></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.ThumbnailsBorderColor></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.ThumbnailsBorderCurved></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.ThumbnailsBorderWidth></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.ThumbnailsInternalBorderColor></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.ThumbnailsInternalBorder></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.ThumbnailOptionsEx></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.ThumbsRounded></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.ThumbWidth></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.UpperGap></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.VertBorder></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.Zoom></C> </R>
|
|
</TABLE>
|
|
|
|
<FI>Input/Output<FN>
|
|
<TABLE2>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.EnableAdjustOrientation> (Auto-Rotate)</C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.EnableImageCaching></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.EnableLoadEXIFThumbnails></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.EnableLoadExplorerThumbnails></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.EnsureImageLoaded></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.FillFromDirectory></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.GetImageToFile></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.GetImageToStream></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.ImageCacheSize></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.ImageCacheUseDisk></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.IOOptionsEx></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.JobsRunning></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.JobsWaiting></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.LoadFromFileOnDemand></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.LoadSnapshot></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.LookAhead></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.MaintainInvisibleImages></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.MIO></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.ReloadImage></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.SaveSnapshot></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.Seek></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.SetImageFromFile></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.SetImageFromStream></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.ThreadPoolSize></C> </R>
|
|
</TABLE>
|
|
|
|
<FI>Selections<FN>
|
|
<TABLE2>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.BeginSelectImages></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.CenterSelected></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.CheckThumbBoundsOnSelect></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.DeleteSelectedImages></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.Deselect></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.EnableMultiSelect></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.EndSelectImages></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.IsSelected></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.MoveSelectedImagesTo></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.MultiSelectedImages></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.MultiSelectedImagesCount></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.MultiSelectedImagesList></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.MultiSelecting></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.MultiSelectionOptions></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.MultiSelectSortList></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.SelectAll></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.SelectedImage></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.SelectedImageAlwaysVisible></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.SelectionColor></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.SelectionWidth></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.SelectionWidthNoFocus></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.SelectSeek></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.TrackMouseSelection></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.UnselectImage></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.VisibleSelection></C> </R>
|
|
</TABLE>
|
|
|
|
<FI>Checkboxes<FN>
|
|
<TABLE2>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.Checkboxes></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.Checked></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.CheckedCount></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.CheckboxPos></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.SetCheckboxParams></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.CheckAll></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.UncheckAll></C> </R>
|
|
</TABLE>
|
|
|
|
<FI>User Interaction<FN>
|
|
<TABLE2>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.Gestures></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.GetImageVisibility></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.HScrollBarParams></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.ImageAtGridPos></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.ImageAtPos></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.InsertingPoint></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.IsVisible></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.KeyInteract></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.MouseInteract></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.MouseWheelParams> (Default)</C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.MouseWheelParamsAlt> (Ctrl Key)</C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.ScrollBars></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.ScrollBarsAlwaysVisible></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.VScrollBarParams></C> </R>
|
|
</TABLE>
|
|
|
|
<FI>Animations and Transitions<FN>
|
|
<TABLE2>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.ImageDelayTime></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.Playing></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.PlayLoop></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.TransitionDuration></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.TransitionEffect></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.TransitionRunning></C> </R>
|
|
</TABLE>
|
|
|
|
<FI>Other<FN>
|
|
<TABLE2>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.AssignLayers></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.CalcGridHeight></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.CalcGridWidth></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.IEBeginDrag></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.IEEndDrag></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.IEMBitmap></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.ImageEnVersion></C> </R>
|
|
<R> <C_IMG_PROPERTY> <C><A TImageEnMView.Proc></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.SetExternalMBitmap></C> </R>
|
|
<R> <C_IMG_PUBLISHED> <C><A TImageEnMView.StoreType></C> </R>
|
|
<R> <C_IMG_METHOD> <C><A TImageEnMView.Update></C> </R>
|
|
</TABLE>
|
|
|
|
<FM>Events<FN>
|
|
<TABLE2>
|
|
<R> <C_IMG_EVENT> <C><A TImageEnMView.OnAcquireBitmap></C> </R>
|
|
<R> <C_IMG_EVENT> <C><A TImageEnMView.OnAfterEvent></C> </R>
|
|
<R> <C_IMG_EVENT> <C><A TImageEnMView.OnAllDisplayed></C> </R>
|
|
<R> <C_IMG_EVENT> <C><A TImageEnMView.OnAnimationText></C> </R>
|
|
<R> <C_IMG_EVENT> <C><A TImageEnMView.OnBeforeImageDrawEx></C> </R>
|
|
<R> <C_IMG_EVENT> <C><A TImageEnMView.OnBeforeImageDraw></C> </R>
|
|
<R> <C_IMG_EVENT> <C><A TImageEnMView.OnCheckboxClick></C> </R>
|
|
<R> <C_IMG_EVENT> <C><A TImageEnMView.OnCreateImage></C> </R>
|
|
<R> <C_IMG_EVENT> <C><A TImageEnMView.OnDestroyImage></C> </R>
|
|
<R> <C_IMG_EVENT> <C><A TImageEnMView.OnDrawProgress></C> </R>
|
|
<R> <C_IMG_EVENT> <C><A TImageEnMView.OnFinishWork></C> </R>
|
|
<R> <C_IMG_EVENT> <C><A TImageEnMView.OnGetText></C> </R>
|
|
<R> <C_IMG_EVENT> <C><A TImageEnMView.OnGetTextEx></C> </R>
|
|
<R> <C_IMG_EVENT> <C><A TImageEnMView.OnImageAdd></C> </R>
|
|
<R> <C_IMG_EVENT> <C><A TImageEnMView.OnImageAdded></C> </R>
|
|
<R> <C_IMG_EVENT> <C><A TImageEnMView.OnImageAtPos></C> </R>
|
|
<R> <C_IMG_EVENT> <C><A TImageEnMView.OnImageDeselect></C> </R>
|
|
<R> <C_IMG_EVENT> <C><A TImageEnMView.OnImageDraw></C> </R>
|
|
<R> <C_IMG_EVENT> <C><A TImageEnMView.OnImageDraw2></C> </R>
|
|
<R> <C_IMG_EVENT> <C><A TImageEnMView.OnImageIDRequestEx></C> </R>
|
|
<R> <C_IMG_EVENT> <C><A TImageEnMView.OnImageIDRequest></C> </R>
|
|
<R> <C_IMG_EVENT> <C><A TImageEnMView.OnImageEnGesture></C> </R>
|
|
<R> <C_IMG_EVENT> <C><A TImageEnMView.OnImageLoaded></C> </R>
|
|
<R> <C_IMG_EVENT> <C><A TImageEnMView.OnImageOut></C> </R>
|
|
<R> <C_IMG_EVENT> <C><A TImageEnMView.OnImageSelect></C> </R>
|
|
<R> <C_IMG_EVENT> <C><A TImageEnMView.OnIOProgress></C> </R>
|
|
<R> <C_IMG_EVENT> <C><A TIEView.OnMouseEnter></C> </R>
|
|
<R> <C_IMG_EVENT> <C><A TIEView.OnMouseLeave></C> </R>
|
|
<R> <C_IMG_EVENT> <C><A TImageEnMView.OnPlayFrame></C> </R>
|
|
<R> <C_IMG_EVENT> <C><A TImageEnMView.OnProgress></C> </R>
|
|
<R> <C_IMG_EVENT> <C><A TImageEnMView.OnSelectionChanging></C> </R>
|
|
<R> <C_IMG_EVENT> <C><A TImageEnMView.OnViewChange></C> </R>
|
|
<R> <C_IMG_EVENT> <C><A TImageEnMView.OnWrongImage></C> </R>
|
|
</TABLE>
|
|
|
|
!!}
|
|
{$ifdef IEHASPLATFORMATTRIBUTE}
|
|
[ComponentPlatformsAttribute(pidWin32 or pidWin64)]
|
|
{$endif}
|
|
TImageEnMView = class(TIEView)
|
|
private
|
|
/////////////////////////
|
|
// P R I V A T E
|
|
fMDown: boolean;
|
|
fBackBuffer: TIEBitmap;
|
|
fHSVX1, fHSVY1: integer; // view in mouse down
|
|
fHoverCheckLastIdx : Integer; // for drawing of hover checkboxes
|
|
fHoverCheckLastPos : TPoint; // Only show checkbox on reasonable mouse movement
|
|
fScrollBars: TIEScrollStyle;
|
|
fRXScroll, fRYScroll: Double;
|
|
fViewX, fViewY: integer;
|
|
fCacheList: TIEVirtualImageList;
|
|
fIconList : TIECachedIconList;
|
|
fStoreType: TIEStoreType; // how to store images
|
|
fThumbWidth, fThumbHeight: integer; // thumbnail size
|
|
fZoom: double; // Internally adjusts ThumbWidth and ThumbHeight
|
|
fHorizBorder: integer; // horizontal border
|
|
fVertBorder: integer; // vertical border
|
|
fVWidth, fVHeight: integer; // virtual space size (Updated by UpdateCoords)
|
|
fOnViewChange: TViewChangeEvent;
|
|
fOnImageAtPos: TIEImageAtPosEvent;
|
|
fOnCreateImage: TIECreateImageEvent;
|
|
fOnDestroyImage: TIEDestroyImageEvent;
|
|
fOnDrawProgress: TIEMProgressEvent;
|
|
fOnWrongImage: TIEWrongImageEvent;
|
|
fHDrawDib: HDRAWDIB; // to draw on display
|
|
fOnImageIDRequest: TIEImageIDRequestEvent;
|
|
fOnImageIDRequestEx: TIEImageIDRequestExEvent;
|
|
fOnImageDraw: TIEImageDrawEvent;
|
|
fOnImageDraw2: TIEImageDraw2Event;
|
|
fOnImageOut: TIEImageOutEvent;
|
|
fOnIOProgress: TIEProgressEvent;
|
|
fBottomGap: integer;
|
|
fUpperGap: integer;
|
|
fTopTextHeight: Integer;
|
|
fInfoTextHeight: Integer;
|
|
fBottomTextHeight: Integer;
|
|
fSideGap : Integer;
|
|
fModernStyling : Boolean; // Set to true if SetModernStyling
|
|
fTextMargin : Integer;
|
|
fTextBlockWidth : Integer;
|
|
fDisplayMode: TIEMDisplayMode; // display mode
|
|
fGridWidth: integer; // number of horizontal images (1=all vertical, other is a grid)
|
|
fCurrentGridWidth : Integer; // Number of horizontal lines as displayed
|
|
fHSX1, fHSY1: integer; // mouse down coordinates
|
|
fHSIDX, fLHSIDX: integer;
|
|
fHSIDXSelected : Boolean; // whether the cell we clicked on was already selected
|
|
fSelectIdxOnMouseUp : integer; // Delay selection till mouse up so that it does not affect our dragging
|
|
FLastRegionIdx: integer;
|
|
fPriorHSIDX: Integer;
|
|
fLastMouseMoveX, fLastMouseMoveY: integer;
|
|
fImageEnIO: TImageEnIO; // to load images
|
|
fLockPaint: integer; // 0 = Paint unlocked
|
|
fLockUpdate: integer; // 0 = Update unlocked
|
|
fDrawImageBackground: boolean; // true=draw image background false=draw component background
|
|
fScrollBarsAlwaysVisible: boolean; // true if the scrollbars are always visible
|
|
fVScrollBarParams: TIEScrollBarParams;
|
|
fHScrollBarParams: TIEScrollBarParams;
|
|
fMouseWheelParams: TIEMouseWheelParams;
|
|
fMouseWheelParamsAlt: TIEMouseWheelParams;
|
|
fThumbnailResampleFilter: TResampleFilter;
|
|
fThumbnailDisplayFilter: TResampleFilter;
|
|
fThumbnailClipping : Integer;
|
|
fDestroying: boolean; // component is destroying
|
|
fStyle: TIEMStyle;
|
|
fDoubleClicking: boolean;
|
|
fThumbnailsBackground: TColor;
|
|
fThumbnailsBackgroundSelected: TColor;
|
|
fThumbnailsBorderWidth: integer;
|
|
fThumbnailsBorderColor: TColor;
|
|
fThumbnailsBorderCurved: boolean;
|
|
fThumbnailsInternalBorder: boolean;
|
|
fThumbnailsInternalBorderColor: TColor;
|
|
fUpdating: boolean;
|
|
fIconSize : TIEImageEnMViewIconSize;
|
|
fThumbsRounded: Integer;
|
|
fEnableAdjustOrientation: Boolean;
|
|
fEnableLoadEXIFThumbnails: Boolean; // if we need thumbnails, allow to use EXIF thumbnails
|
|
fEnableLoadExplorerThumbnails: Boolean; // Retrieve thumbnails from Explorer
|
|
// when true (default) the image will be resized to the thumbnail sizes
|
|
fEnableAlphaChannel: boolean;
|
|
fBackgroundStyle: TIEBackgroundStyle;
|
|
fThumbnailsBackgroundStyle: TIEBackgroundStyle;
|
|
fFillThumbnail: boolean;
|
|
fCurrentCompare: TIEImageEnMViewSortCompare;
|
|
fCurrentCompareEx: TIEImageEnMViewSortCompareEx;
|
|
fCurrentOrderBy: TIEImageEnMViewSortBy;
|
|
fCurrentAscending: boolean;
|
|
fCurrentCaseSensitive : Boolean;
|
|
|
|
// Multithread
|
|
fThreadPoolSize: integer; // maximum threads count (0=disable multithread)
|
|
fThreadPoolIO: TList; // list of TImageEnIO objects (maximum size is fThreadPoolSize)
|
|
fThreadRequests: TList; // list of integers, the indexes of the image to load (no maximum size)
|
|
fThreadStarter: TIEStarter; // starter main thread
|
|
fLookAheadList: TList; // list of lookaheaded images (index of)
|
|
// Wall paper
|
|
fWallpaper: TPicture;
|
|
fWallpaperStyle: TIEWallpaperStyle;
|
|
// Selections
|
|
fSelectedItem: integer; // selected image index (-1 none)
|
|
fVisibleSelection: boolean;
|
|
fSelectionBorderWidth: integer; // selection width with focus
|
|
fSelectionBorderWidthNoFocus: integer; // selection width without focus
|
|
fThumbnailsSelectedBorderColor: TColor; // selection color
|
|
fOnImageSelect: TIEImageSelectEvent;
|
|
fOnImageDeselect: TIEImageSelectEvent;
|
|
fOnSelectionChanging : TIESelectionChangingEvent;
|
|
fOnImageAdd : TIEImageAddEvent;
|
|
fOnImageAdded : TIEMViewImageNotifyEvent;
|
|
fOnImageLoaded : TIEMViewImageNotifyEvent;
|
|
fOnGetText: TIEGetTextEvent;
|
|
fOnGetTextEx: TIEGetTextExEvent;
|
|
fMouseInteract: TIEMMouseInteract;
|
|
fThumbnailOptionsEx : TIEMThumbnailOptionsEx;
|
|
fIOOptionsEx : TIEMIOOptionsEx;
|
|
fKeyInteract: TIEMKeyInteract;
|
|
fSelectedBitmap: TIEBitmap;
|
|
fMultiSelecting: boolean;
|
|
fEnableMultiSelect: boolean;
|
|
fHaveMultiselected: boolean; // last mouseMove has selected images
|
|
fSelectInclusive: boolean; // when true reselecting an image doesn't unselect it
|
|
fMultiSelectionOptions: TIEMultiSelectionOptions;
|
|
fSelectImages: boolean; // if true we are inside BeginSelectImages and EndSelectImages
|
|
fChangedSel: boolean; // true if the selected is changed
|
|
fSelectedFontColor : TColor; // text color for selected cells
|
|
|
|
// Play
|
|
fPlaying: boolean; // true=play actived
|
|
fPlayTimer: integer; // timer for playback of frames (0=not allocated)
|
|
fPlayLoop: boolean; // when True executes in loop
|
|
fTimerInProgress: boolean;
|
|
fFrame: integer; // current frame on single image mode
|
|
fSaveDM: TIEMDisplayMode; // displaymode before the animation
|
|
fSaveSel: integer; // SelectedImage before the play
|
|
// Following three fields are used by TImageEnMIO to get it updated on added or removed images.
|
|
fLastImOp: integer; // last operation of insert(1)/delete(2)/move(3)/swap(4) (0=no op)
|
|
fLastImIdx: integer; // index of processed image by fLastImOp
|
|
fLastImP1: Integer; // param 1
|
|
fLastImGroup: TIEArrayOfInteger; // used by IEM_OP_MOVEGROUP
|
|
// transition effects
|
|
fTransition: TIETransitionEffects; // effect engine
|
|
fTransitionEffect: TIETransitionType; // transition type
|
|
fTransitionDuration: integer; // transition duration ms
|
|
//
|
|
fOnProgress: TIEProgressEvent;
|
|
fOnBeforeImageDraw: TIEImageDrawEvent;
|
|
fOnBeforeImageDrawEx: TIEImageDrawEventEx;
|
|
fEnableImageCaching: boolean;
|
|
fSoftShadow: TIEVSoftShadow;
|
|
fChessboardSize: integer;
|
|
fChessboardBrushStyle: TBrushStyle;
|
|
fChessboardColor2Customized: Boolean;
|
|
fGradientEndColor: TColor;
|
|
fShowText: boolean;
|
|
fFlatScrollBars: Boolean;
|
|
fThumbnailFrame: TIEBitmap;
|
|
fThumbnailFrameSelected: TIEBitmap;
|
|
fThumbnailFrameRect: TRect;
|
|
fMultiOnDemands: TList; // list of TImageEnIO for on demand multi page
|
|
fMaintainInvisibleImages: Integer; // how much invisible images maintain when they are loaded on demand (-1 = maintain all)
|
|
fLookAhead: Integer;
|
|
fOnAllDisplayed: TNotifyEvent; // when all images are displayed
|
|
fAllDisplayed: Boolean;
|
|
fUserAction: Boolean; // if true user has made an action with mouse or keyboard, events fire
|
|
fOnFinishWork: TNotifyEvent;
|
|
fOnAcquireBitmap: TIEAcquireBitmapEvent;
|
|
fOnPlayFrame: TIEPlayFrameEvent;
|
|
fThreadCS: TCriticalSection;
|
|
fBottomTextFont: TFont;
|
|
fTopTextFont: TFont;
|
|
fInfoTextFont: TFont;
|
|
fTextBackgroundStyle: TBrushStyle;
|
|
fTextBackgroundColor: TColor;
|
|
fTextTruncSide: TIEMTruncSide;
|
|
fTrackMouseSelection: Boolean;
|
|
fDrawMouseSelection: Boolean;
|
|
fCheckThumbBoundsOnSelect: Boolean;
|
|
fSelectedImageAlwaysVisible : Boolean;
|
|
fOnAfterEvent: TIEAfterEventEvent;
|
|
fFileTypeList: TStringList; // Used only when sorting by iesbFileType so we do not need to store file types for all files
|
|
fMissingFileIcon : TIEBitmap; // Shown for files that cannot be found
|
|
fDefaultFileIcon : TIEBitmap; // Shown while loading if icon display is disabled
|
|
fAnnotationsVisible: Boolean; // Show Wang and ImageEn annotations
|
|
fImageCacheReusage: TIEImageCacheReusage; // Whether thumbnails in the cache list can be reused after an update. Only supported by TIEDBMultiBitmap
|
|
fTextColumnWidths : array[ iemtpTop .. iemtpInfo ] of Integer; // Width of each column if style is iemsColumns
|
|
|
|
// For resizing of text columns by dragging
|
|
fTextColsCurrentRight : array[ iemtpTop .. iemtpInfo ] of Integer; // The right-hand side of each text column of each column if style is iemsColumns for resizing
|
|
fResizingTextColIdx : Integer;
|
|
fResizingTextColClickX : Integer;
|
|
fResizingTextColWidth : Integer;
|
|
|
|
// animations
|
|
fAnimation: TIEAnimation;
|
|
fAnimationTimer: TTimer;
|
|
fAnimationDraggingSlider: Boolean;
|
|
fOnAnimationText: TIEAnimationTextEvent;
|
|
|
|
// Automatic scrolling when dragging
|
|
fDragScrollTimer : TTimer;
|
|
fDragScrollCount : Integer;
|
|
|
|
// Checkbox support
|
|
fCheckboxes : TIEMCheckboxType; // Show checkboxes?
|
|
fCheckboxPos : TIEMCheckboxPos; // Corner that checkbox is shown
|
|
fOnCheckboxClick : TIECheckboxClickEvent;
|
|
fCheckedCount : Integer; // Cache checked count
|
|
fCheckedBitmap : TBitmap; // images to draw checkboxes
|
|
fUncheckedBitmap : TBitmap;
|
|
fCheckboxMargins : TPoint; // Position of checkbox from edges
|
|
|
|
fDefaultTopText : TIEImageEnMViewDefaultText;
|
|
fDefaultInfoText : TIEImageEnMViewDefaultText;
|
|
fDefaultBottomText : TIEImageEnMViewDefaultText;
|
|
|
|
// Gestures
|
|
fGestures: TIEMViewerGestures;
|
|
fOnImageEnGesture: TIEImageEnGestureEvent;
|
|
fGestureStartX: integer;
|
|
fGestureStartY: integer;
|
|
fGestureBaseViewX: integer;
|
|
fGestureBaseViewY: integer;
|
|
fGestureBaseZoom: double;
|
|
fGestureStartValue: integer;
|
|
|
|
// Automatic scrolling when dragging
|
|
procedure InitializeDragScrollTimer;
|
|
procedure TerminateDragScrollTimer;
|
|
procedure DragScrollTimer(Sender: TObject);
|
|
|
|
function ThumbnailsOrigin : TPoint;
|
|
function CurrentTextBlockWidth() : integer;
|
|
function CurrentHeaderRowHeight : Integer;
|
|
function GetHintStr(idx : Integer) : string;
|
|
procedure GetMaxViewXY(var mx, my: integer);
|
|
procedure SetViewX(v: integer);
|
|
procedure SetViewY(v: integer);
|
|
function GetImageX(idx: integer): integer;
|
|
function GetImageY(idx: integer): integer;
|
|
function GetImageCol(idx: integer): integer;
|
|
function GetImageRow(idx: integer): integer;
|
|
procedure SetThumbWidth(v: integer);
|
|
procedure SetThumbHeight(v: integer);
|
|
procedure SetZoom(value: double);
|
|
function GetImageCount: integer;
|
|
procedure SetImageTopText(idx: integer; v: WideString);
|
|
procedure SetImageBottomText(idx: integer; v: WideString);
|
|
procedure SetImageInfoText(idx: integer; v: WideString);
|
|
procedure SetImageFileName(idx: integer; v: WideString);
|
|
function GetImageFileName(idx: integer): WideString;
|
|
procedure SetImageID(idx, v: integer);
|
|
function GetImageID(idx: integer): integer;
|
|
procedure SetImageTag(idx, v: integer);
|
|
function GetImageTag(idx: integer): integer;
|
|
procedure SetImageUserPointer(idx: Integer; v: pointer);
|
|
function GetImageUserPointer(idx: Integer): pointer;
|
|
function GetImageFileType(idx: integer): WideString;
|
|
procedure SetHorizBorder(v: integer);
|
|
procedure SetVertBorder(v: integer);
|
|
procedure SetSelectedImageAlwaysVisible(v: boolean);
|
|
procedure SetMouseWheelParams(v: TIEMouseWheelParams);
|
|
procedure SetMouseWheelParamsAlt(v: TIEMouseWheelParams);
|
|
function DeleteImageNU(idx: integer; bBatchProcessing : Boolean = False): boolean;
|
|
procedure DeleteAllImages();
|
|
procedure SetCheckboxes(v: TIEMCheckboxType);
|
|
procedure SetCheckboxPos(v: TIEMCheckboxPos);
|
|
function GetChecked(index: integer): Boolean;
|
|
procedure SetChecked(index: integer; v : Boolean);
|
|
procedure SetVisibleSelection(v: boolean);
|
|
procedure SetSelectionBorderWidth(v: integer);
|
|
procedure SetSelectionBorderWidthNoFocus(v: integer);
|
|
procedure SetThumbnailsSelectedBorderColor(v: TColor);
|
|
procedure SetSelectedItem(v: integer);
|
|
procedure SetBottomGap(v: integer);
|
|
procedure SetUpperGap(v: integer);
|
|
procedure SetSideGap(v: integer);
|
|
procedure SetTextMargin(v: integer);
|
|
procedure SetTextBlockWidth(v: integer);
|
|
procedure SetImageBackground(idx: integer; v: TColor);
|
|
function GetImageBackground(idx: integer): TColor;
|
|
procedure SetImageDelayTime(idx: integer; v: Double);
|
|
function GetImageDelayTime(idx: integer): Double;
|
|
function ObtainImageThreaded(idx: integer; priority: Integer): boolean;
|
|
procedure SetDisplayMode(v: TIEMDisplayMode);
|
|
procedure SetGridWidth(v: integer);
|
|
procedure SetPlaying(v: boolean);
|
|
procedure PlayFrame;
|
|
procedure SetSelectedItemNU(v: integer);
|
|
procedure DeselectNU;
|
|
procedure SetVisibleFrame(v: integer);
|
|
function GetMouseInteract: TIEMMouseInteract;
|
|
function GetKeyInteract: TIEMKeyInteract;
|
|
procedure SetDrawImageBackground(v: boolean);
|
|
function GetScrollBarsAlwaysVisible: boolean;
|
|
procedure SetScrollBarsAlwaysVisible(v: boolean);
|
|
procedure SetImageCacheSize(v: integer);
|
|
function GetImageCacheSize : integer;
|
|
procedure SetImageCacheUseDisk(v: boolean);
|
|
function GetImageCacheUseDisk : boolean;
|
|
function GetTransitionRunning: boolean;
|
|
function GetImageTopText(idx: integer): WideString;
|
|
function GetImageBottomText(idx: integer): WideString;
|
|
function GetImageInfoText(idx: integer): WideString;
|
|
procedure SetStyle(value: TIEMStyle);
|
|
procedure SetEnableMultiSelect(Value: boolean);
|
|
function GetMultiSelectedImages(index: integer): integer;
|
|
function GetMultiSelectedImagesCount: integer;
|
|
function GetMultiSelectedImagesList(): TIEArrayOfInteger;
|
|
function GetTextColumnWidths(Col: TIEMTextPos): integer;
|
|
procedure SetTextColumnWidths(Col: TIEMTextPos; value: integer);
|
|
function CurrentTextColumnWidths(Col: TIEMTextPos): integer;
|
|
procedure SetThumbnailsBorderWidth(Value: integer);
|
|
procedure SetThumbnailsBorderColor(Value: TColor);
|
|
procedure SetThumbnailsBorderCurved(Value: boolean);
|
|
procedure SetThumbnailsInternalBorder(Value: boolean);
|
|
procedure SetThumbnailsInternalBorderColor(Value: TColor);
|
|
{$ifdef IEIncludeDeprecatedInV5}
|
|
// Deprecated in 6.0.0 (2015-03-06)
|
|
procedure SetEnableResamplingOnMinor(Value: boolean);
|
|
{$endif}
|
|
function GetEnableResamplingOnMinor : boolean;
|
|
procedure SetIconSize(Value: TIEImageEnMViewIconSize);
|
|
procedure DrawImage(DestBitmap: TBitmap; info: TIEImageInfo; IsSelected: boolean; Index: integer);
|
|
procedure DrawColumnsHeaderRow(DestBitmap: TBitmap);
|
|
procedure ThreadFinish(Sender: TObject);
|
|
function GetImageBitCount(idx: integer): integer;
|
|
function GetMaximumViewX: integer;
|
|
function GetMaximumViewY: integer;
|
|
procedure SetEnableImageCaching(v: boolean);
|
|
function SetImageFromStreamOrFile(idx: integer; Stream: TStream; const FileName: WideString; SourceImageIndex: Integer; FileFormat: TIOFileType): boolean;
|
|
procedure SetEnableAlphaChannel(v: boolean);
|
|
procedure SetBackgroundStyle(v: TIEBackgroundStyle);
|
|
procedure SetThumbnailsBackgroundStyle(v: TIEBackgroundStyle);
|
|
procedure SetGradientEndColor(Value: TColor);
|
|
procedure SetFillThumbnail(Value: boolean);
|
|
procedure SetAnnotationsVisible(Value: boolean);
|
|
procedure SetShowText(Value: boolean);
|
|
procedure SetThumbnailClipping(Value: Integer);
|
|
{$ifdef IEINCLUDEFLATSB}
|
|
procedure SetFlatScrollBars(Value: Boolean);
|
|
{$endif}
|
|
function GetJobsRunning: Integer;
|
|
function GetJobsWaiting: Integer;
|
|
function SortCompareFunction(index1, index2: Integer): Integer;
|
|
function SortCompareBy(index1, index2: Integer): Integer;
|
|
function GetOnDemandIO(const filename: WideString; var FrameIndex: Integer): TImageEnIO;
|
|
procedure ClearOnDemandIOList;
|
|
procedure LoadMultiOnDemand(io: TImageEnIO; frameindex: Integer; var dt: Double);
|
|
function IsOnDemand(info: TIEImageInfo): Boolean;
|
|
function IsLookAhead(idx: Integer): Boolean;
|
|
procedure SetOnFinishWork(v: TNotifyEvent); virtual;
|
|
function GetOnFinishWork: TNotifyEvent; virtual;
|
|
procedure SetOnAcquireBitmap(v: TIEAcquireBitmapEvent); virtual;
|
|
function GetOnAcquireBitmap: TIEAcquireBitmapEvent; virtual;
|
|
function GetImageEnVersion: String;
|
|
procedure SetImageEnVersion(Value: String);
|
|
procedure AbortImageLoading(idx: Integer);
|
|
procedure Sort2(Compare: TIEImageEnMViewSortCompare; CompareEx: TIEImageEnMViewSortCompareEx);
|
|
function ImageAtPosWithCheckEvent(x, y: integer; checkBounds: Boolean; bRelativeToWindow: boolean = true): Integer;
|
|
procedure SetAnimation(value: TIEAnimation);
|
|
procedure AnimGetImageInfo(Sender: TObject; imageIndex: Integer; isVisible: Boolean; var ImageWidth: Integer; var ImageHeight: Integer; var text: WideString);
|
|
procedure AnimGetImage(Sender: TObject; imageIndex: Integer; var image: TIEBitmap; var text: WideString);
|
|
procedure AnimReleaseImage(Sender: TObject; imageIndex: Integer; var image: TIEBitmap);
|
|
procedure AnimPaintTo(dest: TIEBitmap);
|
|
procedure AnimTimer(Sender: TObject);
|
|
function BiDiModeIsRTL : Boolean;
|
|
procedure CheckSelectedImageIsVisible;
|
|
procedure DoAfterEvent(e: TIEAfterEvent);
|
|
procedure ProcessUndoRedo(Sender : TObject; bIsUndo : Boolean; Source : TIEUndoSource; UndoObj : TObject; iIndex : Integer; var bHandled : Boolean);
|
|
function CheckSelectionChangingAllowed : Boolean;
|
|
procedure WMGestureNotify(var Msg: TIEWMGestureNotify); message IEWM_GESTURENOTIFY;
|
|
procedure WMEnabled(var Msg: TMessage); message WM_ENABLE;
|
|
procedure WMGesture(var Msg: TMessage); message IEWM_GESTURE;
|
|
procedure DoImageEnGestureEvent(const GInfo: TIEGESTUREINFO; var Handled: boolean); virtual;
|
|
function PerformZoomSnap(Value: double): double;
|
|
function IEMBitmap_IsTIEDBMultiBitmap: Boolean;
|
|
procedure Reset(bClear: Boolean = False);
|
|
function GetStyleInt() : Integer;
|
|
procedure SetStyleInt(v : Integer);
|
|
procedure SetShowThumbnailHint(const Value: Boolean);
|
|
|
|
procedure SetDefaultTopText(Value : TIEImageEnMViewDefaultText);
|
|
procedure SetDefaultInfoText(Value : TIEImageEnMViewDefaultText);
|
|
procedure SetDefaultBottomText(Value : TIEImageEnMViewDefaultText);
|
|
|
|
procedure UpdateTopTextHeight(bHasText: Boolean);
|
|
procedure UpdateInfoTextHeight(bHasText: Boolean);
|
|
procedure UpdateBottomTextHeight(bHasText: Boolean);
|
|
procedure TopTextFontChange(Sender: TObject);
|
|
procedure InfoTextFontChange(Sender: TObject);
|
|
procedure BottomTextFontChange(Sender: TObject);
|
|
protected
|
|
///////////////////////
|
|
// P R O T E C T E D
|
|
//
|
|
|
|
// encapsulated components
|
|
fImageEnMIO: TImageEnMIO;
|
|
fImageEnProc: TImageEnProc;
|
|
|
|
// selections
|
|
fMultiSelectedImages: TList; // array of selected images (pointer=integer=index of the selected image)
|
|
|
|
fIEMBitmap: TIECustomMultiBitmap; // contains our images
|
|
fIEMBitmapIsExternal: Boolean; // True if user has attached a custom IEMBitmap to this control
|
|
|
|
fShowThumbnailHint : Boolean;
|
|
fDragging: Boolean;
|
|
|
|
function GetIEMBitmap: TIECustomMultiBitmap;
|
|
procedure UpdateParams(Sender : TObject; Operation: Integer; Idx : integer; ExtraParam: Integer);
|
|
function GetImageEnMIO: TImageEnMIO; virtual;
|
|
function GetImageEnProc: TImageEnProc; virtual;
|
|
procedure SetScrollBars(v: TIEScrollStyle); virtual;
|
|
procedure SetStoreType(v : TIEStoreType);
|
|
procedure IEMAutoScroll(var Message: TMessage); message IEM_AUTOSCROLL;
|
|
procedure WMSize(var Message: TWMSize); message WM_SIZE;
|
|
procedure WMEraseBkgnd(var Message: TMessage); message WM_ERASEBKGND;
|
|
procedure WMVScroll(var Message: TMessage); message WM_VSCROLL;
|
|
procedure WMHScroll(var Message: TMessage); message WM_HSCROLL;
|
|
procedure WMTimer(var Message: TWMTimer); message WM_TIMER;
|
|
procedure CMWantSpecialKey(var Msg: TCMWantSpecialKey); message CM_WANTSPECIALKEY;
|
|
procedure CNKEYUP(var Message: TMessage); message CN_KEYUP;
|
|
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
|
|
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
|
|
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
|
|
procedure WMLButtonDblClk(var Message: TWMLButtonDblClk); message WM_LBUTTONDBLCLK;
|
|
procedure WMKillFocus(var Msg: TWMKillFocus); message WM_KILLFOCUS;
|
|
procedure WMSetFocus(var Msg: TWMSetFocus); message WM_SETFOCUS;
|
|
procedure WMMouseWheel(var Message: TMessage); message WM_MOUSEWHEEL;
|
|
procedure CMHintShow(var Message: TMessage); message CM_HINTSHOW;
|
|
procedure ViewChange(c: integer); virtual;
|
|
function PaletteChanged(Foreground: Boolean): Boolean; override;
|
|
procedure SetBackground(cl: TColor); override;
|
|
function GetFBitmap: TBitmap; override;
|
|
function GetIEBitmap: TIEBitmap; override;
|
|
procedure SetThumbnailOptionsEx(v : TIEMThumbnailOptionsEx);
|
|
procedure SetIOOptionsEx(v : TIEMIOOptionsEx);
|
|
procedure SetMouseInteract(v: TIEMMouseInteract); virtual;
|
|
procedure SetKeyInteract(v: TIEMKeyInteract); virtual;
|
|
function GetImageWidth(idx: integer): integer;
|
|
function GetImageHeight(idx: integer): integer;
|
|
function GetImageOriginalWidth(idx: integer): integer;
|
|
function GetImageOriginalHeight(idx: integer): integer;
|
|
function GetImageCreateDate(idx: integer): TDateTime;
|
|
function GetImageFileSize(idx: integer): Int64;
|
|
function GetImageEditDate(idx: integer): TDateTime;
|
|
function GetImageType(idx: integer): TIEFolderImageType;
|
|
procedure SetImageOriginalWidth(idx: integer; Value: integer);
|
|
procedure SetImageOriginalHeight(idx: integer; Value: integer);
|
|
procedure SetImageCreateDate(idx: integer; Value: TDateTime);
|
|
procedure SetImageFileSize(idx: integer; Value: Int64);
|
|
procedure SetImageEditDate(idx: integer; Value: TDateTime);
|
|
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
|
|
procedure KeyUp(var Key: Word; Shift: TShiftState); override;
|
|
procedure SelectAtPos(X, Y: integer; Shift: TShiftState);
|
|
procedure SetWallpaper(Value: TPicture);
|
|
procedure SetWallpaperStyle(Value: TIEWallpaperStyle);
|
|
function GetHasAlphaChannel: boolean; override;
|
|
function GetAlphaChannel: TIEBitmap; override;
|
|
procedure SetOnProgress(v: TIEProgressEvent); virtual;
|
|
function GetOnProgress: TIEProgressEvent; virtual;
|
|
procedure ClearThreadsAndRequests; virtual;
|
|
procedure ClearCache;
|
|
procedure DoWrongImage(OutBitmap: TIEBitmap; idx: integer; var ASourceType : TIESourceType); virtual;
|
|
procedure DoImageSelect(idx: integer); virtual;
|
|
procedure DoImageDeselect(idx: integer); virtual;
|
|
{$ifdef IEDOTNETVERSION}
|
|
procedure WMContextMenu(var Message: TWMContextMenu); message WM_CONTEXTMENU;
|
|
{$endif}
|
|
procedure SwapImages(idx1, idx2: Integer);
|
|
function IsRequested(idx: Integer): Integer;
|
|
procedure PaintBackgroundTo(DestBitmap: TBitmap);
|
|
function ImageAtPosEx(x, y: integer; checkBounds: Boolean = true; bRelativeToWindow: boolean = true): Integer;
|
|
function ReplaceIEMConst(const ws : WideString; idx : Integer) : WideString; overload;
|
|
function ReplaceIEMConst(const DefaultText : TIEImageEnMViewDefaultText; idx : Integer) : WideString; overload;
|
|
procedure GetFileDetailsForImage(idx: integer);
|
|
procedure DrawCheckbox(ACanvas : TCanvas; Index : Integer; ThumbRect : TRect; IsSelected : Boolean; bRelativeToView : Boolean = False); overload;
|
|
procedure DrawCheckbox(ACanvas : TCanvas; Index : Integer; IsSelected : Boolean; bRelativeToView : Boolean = False); overload;
|
|
function CheckboxAtPos(X, Y : Integer) : Integer;
|
|
procedure ClickCheckboxAtPos(X, Y : Integer);
|
|
function ThumbToCheckboxRect(ThumbRect : TRect; bRelativeToView : Boolean = False) : TRect;
|
|
procedure _UpdateImage(idx: integer; bInvalidateOnly : Boolean);
|
|
procedure ClickColumnsHeaderRowCell(Col: TIEMTextPos); virtual;
|
|
procedure DrawColumnsHeaderRowCell(Canvas: TCanvas; Rect: TRect; Col: TIEMTextPos); virtual;
|
|
|
|
public
|
|
/////////////////////
|
|
// P U B L I C
|
|
constructor Create(Owner: TComponent); override;
|
|
destructor Destroy; override;
|
|
|
|
{$IFDEF UNITTESTING}
|
|
function UnitTesting_ObtainImageThreaded(idx: integer): boolean;
|
|
{$ENDIF}
|
|
|
|
// display
|
|
procedure Update; override;
|
|
procedure UpdateEx(bUpdateCache : Boolean; bRespositionSelection : Boolean = False);
|
|
procedure PaintTo(DestBitmap: TBitmap); virtual;
|
|
procedure PaintToCanvas(DestCanvas: TCanvas); virtual;
|
|
procedure Paint; override;
|
|
property ClientWidth;
|
|
property ClientHeight;
|
|
property ViewX: integer read fViewX write SetViewX;
|
|
property ViewY: integer read fViewY write SetViewY;
|
|
property Zoom: double read fZoom write SetZoom;
|
|
property MaximumViewX: integer read GetMaximumViewX;
|
|
property MaximumViewY: integer read GetMaximumViewY;
|
|
procedure SetViewXY(x, y: integer);
|
|
procedure CenterSelected;
|
|
procedure CenterFrame;
|
|
procedure LockPaint; override;
|
|
procedure LockUpdate; virtual;
|
|
function UnLockPaint: Integer; override;
|
|
function UnlockUpdate: Integer; virtual;
|
|
function UnLockUpdateEx: integer;
|
|
function NPUnLockPaint: integer; override;
|
|
function ThumbSizeInfo(Data: TIEThumbSizeType): TPoint;
|
|
|
|
// Whether thumbnails in the cache list can be reused after an update. Only supported by TIEDBMultiBitmap
|
|
property ImageCacheReusage : TIEImageCacheReusage read fImageCacheReusage write fImageCacheReusage;
|
|
function FindImageInCache( idx: Integer; const sFilename: string ): Pointer;
|
|
|
|
function ObtainImageNow(idx: integer): boolean;
|
|
|
|
procedure SetLastImOp(LastImOp: integer; // last operation of insert(1)/delete(2)/move(3)/swap(4) (0=no op)
|
|
LastImIdx: integer; // index of processed image by fLastImOp
|
|
LastImP1: Integer = 0); overload; // param 1
|
|
procedure SetLastImOp(LastImOp: integer;
|
|
LastImIdx: integer;
|
|
LastImP1: Integer;
|
|
LastImGroup: TIEArrayOfInteger); overload; // setting LastImGroup default value (nil) generates incorrect C++ headers
|
|
|
|
{!!
|
|
<FS>TImageEnMView.LockPaintCount
|
|
|
|
<FM>Declaration<FC>
|
|
property LockPaintCount: Integer;
|
|
|
|
<FM>Description<FN>
|
|
Returns the lock painting state. A value of 0 means no locking. A value greater than zero means locking is in place (i.e. painting is disabled).
|
|
|
|
Calling <A TImageEnMView.LockPaint> increments <A TImageEnMView.LockPaintCount>, <A TImageEnMView.UnLockPaint> decrements it.
|
|
!!}
|
|
property LockPaintCount: integer read fLockPaint;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.LockUpdateCount
|
|
|
|
<FM>Declaration<FC>
|
|
property LockUpdateCount: Integer;
|
|
|
|
<FM>Description<FN>
|
|
Returns the lock updating state. A value of 0 means no locking. A value greater than zero means locking is in place (i.e. updating is disabled).
|
|
|
|
Calling <A TImageEnMView.LockUpdate> increments <A TImageEnMView.LockUpdateCount>, <A TImageEnMView.UnLockUpdate> decrements it.
|
|
!!}
|
|
property LockUpdateCount: integer read fLockUpdate;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.SoftShadow
|
|
|
|
<FM>Declaration<FC>
|
|
property SoftShadow: <A TIEVSoftShadow>;
|
|
|
|
<FM>Description<FN>
|
|
Paints a soft shadow beneath the thumbnails.
|
|
|
|
Notes:
|
|
- You will need to enable the <L TImageEnMView.EnableAlphaChannel>alpha channel</L>.
|
|
- Soft shadows are hidden if thumbnails are very small
|
|
|
|
<IMG help_images\ThumbShadow.jpg>
|
|
|
|
<FM>Demo<FN>
|
|
<TABLE2>
|
|
<R> <C_IMG_DEMO> <C>Demos\Multi\Thumbnails2\Thumbnails2.dpr </C> </R>
|
|
</TABLE>
|
|
|
|
<FM>Example<FC>
|
|
ImageEnMView.EnableAlphaChannel := True;
|
|
ImageEnMView.SoftShadow.Enabled := True;
|
|
ImageEnMView.SoftShadow.ShadowColor := TColor2TRGB( clBlue );
|
|
!!}
|
|
property SoftShadow: TIEVSoftShadow read fSoftShadow;
|
|
|
|
procedure SetChessboardStyle(Size: Integer; BrushStyle: TBrushStyle = bsSolid; Color1: TColor = clNone_; Color2: TColor = clNone_);
|
|
|
|
property GradientEndColor: TColor read fGradientEndColor write SetGradientEndColor;
|
|
|
|
property FillThumbnail: boolean read fFillThumbnail write SetFillThumbnail;
|
|
|
|
procedure SetModernStyling(bAutoGridWidth : Boolean = False; iThumbWidth : Integer = 0; iThumbHeight : Integer = 0; bSoftShadow: Boolean = True);
|
|
|
|
property AnnotationsVisible: Boolean read fAnnotationsVisible write SetAnnotationsVisible;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ThumbsRounded
|
|
|
|
<FM>Declaration<FC>
|
|
property ThumbsRounded: Integer;
|
|
|
|
<FM>Description<FN>
|
|
If value greater than zero is specified for ThumbsRounded then the image is drawn with rounded corners.
|
|
|
|
Smaller values provide the maximum roundness, while large value produce minimal roundness.
|
|
|
|
<FM>Demo<FN>
|
|
<TABLE2>
|
|
<R> <C_IMG_DEMO> <C>Demos\Multi\Thumbnails2\Thumbnails2.dpr </C> </R>
|
|
</TABLE>
|
|
|
|
<FM>Example<FC>
|
|
ImageEnMView1.ThumbsRounded := 5;
|
|
!!}
|
|
property ThumbsRounded: Integer read fThumbsRounded write fThumbsRounded;
|
|
|
|
procedure SetPresetThumbnailFrame(PresetIndex: Integer; UnselectedColor: TColor; SelectedColor: TColor);
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ThumbnailFrame
|
|
|
|
<FM>Declaration<FC>
|
|
property ThumbnailFrame: <A TIEBitmap>;
|
|
|
|
<FM>Description<FN>
|
|
Specifies a bitmap to display under the thumbnail.
|
|
|
|
<FM>Examples<FC>
|
|
ImageEnMView1.ThumbnailFrame := ImageEnViewUnselected.IEBitmap;
|
|
ImageEnMView1.ThumbnailFrameSelected := ImageEnViewSelected.IEBitmap;
|
|
ImageEnMView1.ThumbnailFrameRect := Rect(10, 10, 50, 50);
|
|
!!}
|
|
property ThumbnailFrame: TIEBitmap read fThumbnailFrame write fThumbnailFrame;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ThumbnailFrameSelected
|
|
|
|
<FM>Declaration<FC>
|
|
property ThumbnailFrameSelected: <A TIEBitmap>;
|
|
|
|
<FM>Description<FN>
|
|
Specifies a bitmap to display under the thumbnail when it is selected.
|
|
|
|
<FM>Examples<FC>
|
|
ImageEnMView1.ThumbnailFrame := ImageEnViewUnselected.IEBitmap;
|
|
ImageEnMView1.ThumbnailFrameSelected := ImageEnViewSelected.IEBitmap;
|
|
ImageEnMView1.ThumbnailFrameRect := Rect(10, 10, 50, 50);
|
|
!!}
|
|
property ThumbnailFrameSelected: TIEBitmap read fThumbnailFrameSelected write fThumbnailFrameSelected;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ThumbnailFrameRect
|
|
|
|
<FM>Declaration<FC>
|
|
property ThumbnailFrameRect: TRect;
|
|
|
|
<FM>Description<FN>
|
|
Using <A TImageEnMView.ThumbnailFrameSelected> and <A TImageEnMView.ThumbnailFrame>, this property specifies where the image (the thumbnail) will be drawn.
|
|
|
|
<FM>Examples<FC>
|
|
ImageEnMView1.ThumbnailFrame := ImageEnViewUnselected.IEBitmap;
|
|
ImageEnMView1.ThumbnailFrameSelected := ImageEnViewSelected.IEBitmap;
|
|
ImageEnMView1.ThumbnailFrameRect := Rect(10, 10, 50, 50);
|
|
!!}
|
|
property ThumbnailFrameRect: TRect read fThumbnailFrameRect write fThumbnailFrameRect;
|
|
|
|
// others
|
|
property MouseCapture;
|
|
procedure Assign(Source: TPersistent); override;
|
|
procedure AssignEx(Source: TObject; bCopyParams: Boolean = False);
|
|
procedure AssignLayers(Source: TImageEnView; HighlightSel: Boolean; DoClear: Boolean = True);
|
|
procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override;
|
|
function GetLastOp(): integer;
|
|
function GetLastOpIdx(): integer;
|
|
function GetLastOpP1(): integer;
|
|
function GetLastOpGroup(): TIEArrayOfInteger;
|
|
property ScrollBarsAlwaysVisible: boolean read GetScrollBarsAlwaysVisible write SetScrollBarsAlwaysVisible; // NB: No default. Always store!
|
|
function RemoveBlankPages(Tolerance: Double = 0; Complete: boolean = true; LeftToRight: boolean = true): Integer;
|
|
function RemoveDuplicates(): Integer;
|
|
function CalcGridWidth(): Integer;
|
|
function CalcGridHeight(): Integer;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.VScrollBarParams
|
|
|
|
<FM>Declaration<FC>
|
|
property VScrollBarParams: <A TIEScrollBarParams>;
|
|
|
|
<FM>Description<FN>
|
|
Properties to customize the behavior of the vertical scroll bar. This includes tracking (display refresh on mouse dragging), up/down buttons scroll distance and pagedown/up scroll distance.
|
|
|
|
<FM>Example<FC>
|
|
// disable tracking
|
|
ImageEnMView1.VScrollBarParams.Tracking := False;
|
|
!!}
|
|
property VScrollBarParams: TIEScrollBarParams read fVScrollBarParams;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.HScrollBarParams
|
|
|
|
<FM>Declaration<FC>
|
|
property HScrollBarParams: <A TIEScrollBarParams>;
|
|
|
|
<FM>Description<FN>
|
|
Properties to customize the behavior of the horizontal scroll bar. This includes tracking (display refresh on mouse dragging), up/down buttons scroll distance and pagedown/up scroll distance.
|
|
|
|
<FM>Example<FC>
|
|
// disable tracking
|
|
ImageEnMView1.HScrollBarParams.Tracking := False;
|
|
!!}
|
|
property HScrollBarParams: TIEScrollBarParams read fHScrollBarParams;
|
|
|
|
|
|
procedure RemoveAlphaChannel(Merge: boolean); override;
|
|
procedure CallBitmapChangeEvents; override;
|
|
procedure EnsureImageLoaded(idx : Integer);
|
|
procedure FillFromDirectory(const Directory: WideString; Limit : integer = -1; AllowUnknownFormats : boolean = false; const ExcludeExtensions : WideString = '';
|
|
DetectFileFormat : boolean = false; const FilterMask : WideString = ''; IncludeVideoFiles : Boolean = False;
|
|
LoadOnDemand : boolean = true;
|
|
DefaultTopText : TIEImageEnMViewDefaultText = iedtNone;
|
|
DefaultInfoText : TIEImageEnMViewDefaultText = iedtNone;
|
|
DefaultBottomText : TIEImageEnMViewDefaultText = iedtFilename;
|
|
bShowHiddenFiles : Boolean = False;
|
|
bShowFolders : Boolean = False);
|
|
|
|
{!!
|
|
<FS>TImageEnMView.EnableAdjustOrientation
|
|
|
|
<FM>Declaration<FC>
|
|
property EnableAdjustOrientation: Boolean;
|
|
|
|
<FM>Description<FN>
|
|
When this property is True all images which have orientation information (typically jpeg with EXIF data) will be automatically rotated for display (actual file is not modified).
|
|
|
|
Orientation information is often found in digital photos from high-end cameras. ImageEn uses the data found in <A TIOParams.EXIF_Orientation> or <A TIOParams.TIFF_Orientation> to determine the orientation.
|
|
|
|
!!}
|
|
property EnableAdjustOrientation: Boolean read fEnableAdjustOrientation write fEnableAdjustOrientation;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.MaintainInvisibleImages
|
|
|
|
<FM>Declaration<FC>
|
|
property MaintainInvisibleImages: Integer;
|
|
|
|
<FM>Description<FN>
|
|
Specifies the number of images to maintain when they are no longer visible (scrolled out of view).
|
|
|
|
Default: 15
|
|
|
|
Specify -1 to maintain all images in memory.
|
|
Specify 0 to discard all images when they are not visible.
|
|
|
|
Note: This property only applies when images are loaded on demand, e.g. by setting <A TImageEnMView.ImageFileName>, <A TImageEnMView.FillFromDirectory> or <A TImageEnMView.LoadFromFileOnDemand>.
|
|
!!}
|
|
property MaintainInvisibleImages: Integer read fMaintainInvisibleImages write fMaintainInvisibleImages;
|
|
|
|
procedure LoadFromFileOnDemand(const FileName: WideString; Append: Boolean = false);
|
|
|
|
{!!
|
|
<FS>TImageEnMView.EnableLoadEXIFThumbnails
|
|
|
|
<FM>Declaration<FC>
|
|
property EnableLoadEXIFThumbnails : Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Images from digital camera often contain a small thumnbail in their <L TIOParams.EXIF_Bitmap>Exif data</L>. When this option is enabled, ImageEn will use the EXIF thumbnail for display rather than loading and sub-sampling the full size image. This speeds up loading of large images.
|
|
|
|
By default, EnableLoadEXIFThumbnails is true.
|
|
|
|
Note: Has no effect if <A TImageEnMView.StoreType> is ietNormal.
|
|
|
|
<FM>Example<FC>
|
|
// Do not use EXIF thumbnails for digital camera images
|
|
ImageEnMView1.EnableLoadEXIFThumbnails := False;
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.EnableLoadExplorerThumbnails>
|
|
!!}
|
|
property EnableLoadEXIFThumbnails: Boolean read fEnableLoadEXIFThumbnails write fEnableLoadEXIFThumbnails;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.EnableLoadExplorerThumbnails
|
|
|
|
<FM>Declaration<FC>
|
|
property EnableLoadExplorerThumbnails : Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Rather than generating thumbnails, they will be obtained from Windows Explorer. This is significantly quicker, and also thumbnails will be cached to disk for fast reuse.
|
|
|
|
By default, EnableLoadExplorerThumbnails is False.
|
|
|
|
Notes:
|
|
- Has no effect if <A TImageEnMView.StoreType> is ietNormal
|
|
- <L TImageEnMIO.Params>Image meta-data</L> will not be valid if EnableLoadExplorerThumbnails is used unless <L TImageEnMView.IOOptionsEx>ieixWantParams</L> is enabled
|
|
|
|
<FM>Example<FC>
|
|
// Use Windows Explorer thumbnails
|
|
ImageEnMView1.EnableLoadExplorerThumbnails := True;
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.EnableLoadEXIFThumbnails>
|
|
!!}
|
|
property EnableLoadExplorerThumbnails: Boolean read fEnableLoadExplorerThumbnails write fEnableLoadExplorerThumbnails;
|
|
|
|
|
|
|
|
procedure CreateMorphingSequence(Source: TImageEnVect; Target: TImageEnVect; FramesCount: Integer);
|
|
// multithreads
|
|
property JobsRunning: Integer read GetJobsRunning;
|
|
property JobsWaiting: Integer read GetJobsWaiting;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.LookAhead
|
|
|
|
<FM>Declaration<FC>
|
|
property LookAhead: Integer;
|
|
|
|
<FM>Description<FN>
|
|
Specifies the number of images to pre-load (load before they are required for display).
|
|
|
|
Note: This property only applies when images are loaded on demand, e.g. by setting <A TImageEnMView.ImageFileName>, <A TImageEnMView.FillFromDirectory> or <A TImageEnMView.LoadFromFileOnDemand>.
|
|
|
|
Default: 0
|
|
!!}
|
|
property LookAhead: Integer read fLookAhead write fLookAhead;
|
|
|
|
// cache
|
|
procedure ClearImageCache(idx: integer);
|
|
property EnableImageCaching: boolean read fEnableImageCaching write SetEnableImageCaching default true;
|
|
// images
|
|
property ImageWidth[idx: integer]: integer read GetImageWidth;
|
|
property ImageHeight[idx: integer]: integer read GetImageHeight;
|
|
property ImageOriginalWidth[idx: integer]: integer read GetImageOriginalWidth write SetImageOriginalWidth;
|
|
property ImageOriginalHeight[idx: integer]: integer read GetImageOriginalHeight write SetImageOriginalHeight;
|
|
property ImageBitCount[idx: integer]: integer read GetImageBitCount;
|
|
property ImageX[idx: integer]: integer read GetImageX;
|
|
property ImageY[idx: integer]: integer read GetImageY;
|
|
property ImageRow[idx: integer]: integer read GetImageRow;
|
|
property ImageCol[idx: integer]: integer read GetImageCol;
|
|
property ImageFileName[idx: integer]: WideString read GetImageFileName write SetImageFileName;
|
|
property ImageID[idx: integer]: integer read GetImageID write SetImageID;
|
|
property ImageTag[idx: integer]: integer read GetImageTag write SetImageTag;
|
|
property ImageUserPointer[idx: Integer]: pointer read GetImageUserPointer write SetImageUserPointer;
|
|
property ImageBackground[idx: integer]: TColor read GetImageBackground write SetImageBackground;
|
|
property ImageDelayTime[idx: integer]: Double read GetImageDelayTime write SetimageDelayTime;
|
|
property ImageCreateDate[idx: Integer]: TDateTime read GetImageCreateDate write SetImageCreateDate;
|
|
property ImageEditDate[idx: integer]: TDateTime read GetImageEditDate write SetImageEditDate;
|
|
property ImageFileSize[idx: integer]: Int64 read GetImageFileSize write SetImageFileSize;
|
|
property ImageTopText[idx: integer]: WideString read GetImageTopText write SetImageTopText;
|
|
property ImageBottomText[idx: integer]: WideString read GetImageBottomText write SetImageBottomText;
|
|
property ImageInfoText[idx: integer]: WideString read GetImageInfoText write SetImageInfoText;
|
|
property ImageFileType[idx: integer]: WideString read GetImageFileType;
|
|
|
|
{$ifdef IEIncludeDeprecatedInV5}
|
|
// Deprecated in 6.0.0 (2015-02-27)
|
|
// Keep for legacy projects
|
|
property DefaultBottomTextFont: TFont read fBottomTextFont;
|
|
property DefaultTopTextFont: TFont read fTopTextFont;
|
|
property DefaultInfoTextFont: TFont read fInfoTextFont;
|
|
property DefaultTextBackgroundStyle: TBrushStyle read fTextBackgroundStyle write fTextBackgroundStyle;
|
|
{$endif}
|
|
|
|
{$ifdef IEIncludeDeprecatedInV5}
|
|
// Deprecated in 6.0.0 (2015-03-06)
|
|
property EnableResamplingOnMinor: boolean read GetEnableResamplingOnMinor write SetEnableResamplingOnMinor;
|
|
{$endif}
|
|
|
|
{!!
|
|
<FS>TImageEnMView.BottomTextFont
|
|
|
|
<FM>Declaration<FC>
|
|
property BottomTextFont: TFont;
|
|
|
|
<FM>Description<FN>
|
|
Specify the font if you are using <A TImageEnMView.ImageBottomText> to add text to your thumbnails.
|
|
|
|
Notes:
|
|
- If you need to change the font or styling of particular thumbnails, use the <A TImageEnMView.OnGetTextEx> event.
|
|
- The color of this font may be overridden if <A TIEImageEnGlobalSettings.EnableTheming> is enabled.
|
|
|
|
<FM>Example<FC>
|
|
ImageEnMView1.BottomTextFont.Height := 14;
|
|
ImageEnMView1.BottomTextFont.Name := 'Arial';
|
|
ImageEnMView1.FillFromDirectory('C:\Pictures');
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.InfoTextFont>
|
|
- <A TImageEnMView.TopTextFont>
|
|
- <A TImageEnMView.OnGetTextEx>
|
|
!!}
|
|
property BottomTextFont: TFont read fBottomTextFont;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.TopTextFont
|
|
|
|
<FM>Declaration<FC>
|
|
property TopTextFont: TFont;
|
|
|
|
<FM>Description<FN>
|
|
Specify the font if you are using <A TImageEnMView.ImageTopText> to add text to your thumbnails.
|
|
|
|
Notes:
|
|
- If you need to change the font or styling of particular thumbnails, use the <A TImageEnMView.OnGetTextEx> event.
|
|
- The color of this font may be overridden if <A TIEImageEnGlobalSettings.EnableTheming> is enabled.
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.BottomTextFont>
|
|
- <A TImageEnMView.InfoTextFont>
|
|
- <A TImageEnMView.OnGetTextEx>
|
|
!!}
|
|
property TopTextFont: TFont read fTopTextFont;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.InfoTextFont
|
|
|
|
<FM>Declaration<FC>
|
|
property InfoTextFont: TFont;
|
|
|
|
<FM>Description<FN>
|
|
Specify the font if you are using <A TImageEnMView.ImageInfoText> to add text to your thumbnails.
|
|
|
|
Notes:
|
|
- If you need to change the font or styling of particular thumbnails, use the <A TImageEnMView.OnGetTextEx> event.
|
|
- The color of this font may be overridden if <A TIEImageEnGlobalSettings.EnableTheming> is enabled.
|
|
- If <A TImageEnMView.Style> is <FC>iemsColumns<FN> then <FC>InfoTextFont<FN> is also used for the header row font (though it can be overriden in the <A TImageEnMView.OnGetTextEx> event)
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.BottomTextFont>
|
|
- <A TImageEnMView.TopTextFont>
|
|
- <A TImageEnMView.OnGetTextEx>
|
|
!!}
|
|
property InfoTextFont: TFont read fInfoTextFont;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.TextBackgroundStyle
|
|
|
|
<FM>Declaration<FC>
|
|
property TextBackgroundStyle: TBrushStyle;
|
|
|
|
<FM>Description<FN>
|
|
Specify a background style for your thumbnail text.
|
|
|
|
Note: You can customize the styling of specific frames using the <A TImageEnMView.OnGetTextEx> event.
|
|
|
|
<FM>Example<FC>
|
|
// Give Thumbnail text a solid yellow background
|
|
ImageEnMView1.TextBackgroundStyle := bsSolid;
|
|
ImageEnMView1.TextBackgroundColor := clYellow;
|
|
ImageEnMView1.FillFromDirectory('C:\Pictures');
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.ImageTopText>
|
|
- <A TImageEnMView.ImageInfoText>
|
|
- <A TImageEnMView.ImageBottomText>
|
|
- <A TImageEnMView.OnGetTextEx>
|
|
!!}
|
|
property TextBackgroundStyle: TBrushStyle read fTextBackgroundStyle write fTextBackgroundStyle;
|
|
|
|
property TextColumnWidths[Col : TIEMTextPos] : Integer read GetTextColumnWidths write SetTextColumnWidths;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.TextBackgroundColor
|
|
|
|
<FM>Declaration<FC>
|
|
property TextBackgroundColor: TColor;
|
|
|
|
<FM>Description<FN>
|
|
Specify a background Color for your thumbnail text.
|
|
|
|
Note:
|
|
- You can customize the styling of specific frames using the <A TImageEnMView.OnGetTextEx> event.
|
|
- This value may be overridden if <A TIEImageEnGlobalSettings.EnableTheming> is enabled.
|
|
|
|
<FM>Example<FC>
|
|
// Give Thumbnail text a solid yellow background
|
|
ImageEnMView1.TextBackgroundStyle := bsSolid;
|
|
ImageEnMView1.TextBackgroundColor := clYellow;
|
|
ImageEnMView1.FillFromDirectory('C:\Pictures');
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.ImageTopText>
|
|
- <A TImageEnMView.ImageInfoText>
|
|
- <A TImageEnMView.ImageBottomText>
|
|
- <A TImageEnMView.OnGetTextEx>
|
|
!!}
|
|
property TextBackgroundColor: TColor read fTextBackgroundColor write fTextBackgroundColor;
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.TextTruncSide
|
|
|
|
<FM>Declaration<FC>
|
|
property TextTruncSide: <A TIEMTruncSide>;
|
|
|
|
<FM>Description<FN>
|
|
Specifies the side to truncate the text if it is too wide to be displayed.
|
|
!!}
|
|
property TextTruncSide: TIEMTruncSide read fTextTruncSide write fTextTruncSide;
|
|
|
|
|
|
property ShowText: boolean read fShowText write SetShowText;
|
|
procedure UpdateImage(idx: integer);
|
|
|
|
procedure InsertImage(Idx : integer); overload;
|
|
procedure InsertImage(Idx : integer; Stream : TStream); overload;
|
|
procedure InsertImage(Idx : integer; Bitmap : TIEBitmap); overload;
|
|
procedure InsertImage(Idx : integer; Bitmap : TBitmap); overload;
|
|
procedure InsertImage(Idx : integer; Width, Height : integer; PixelFormat : TIEPixelFormat = ie24RGB); overload;
|
|
procedure InsertImage(Idx : integer; const FileName : string); overload;
|
|
procedure InsertImage(Idx : integer; const FileName : string;
|
|
LoadOnDemand : boolean;
|
|
DefaultTopText : TIEImageEnMViewDefaultText = iedtNone;
|
|
DefaultInfoText : TIEImageEnMViewDefaultText = iedtNone;
|
|
DefaultBottomText : TIEImageEnMViewDefaultText = iedtFilename;
|
|
bSelectIt : Boolean = true); overload;
|
|
|
|
procedure InsertImageEx(idx: integer; SelectMode : TIEMSelectMode = imsNever);
|
|
|
|
procedure InsertTransitionFrames(Idx : integer; iFrameCount : Integer; Effect : TIETransitionType; iWidth : Integer = -1; iHeight : Integer = -1;
|
|
BackgroundColor : TColor = -1; ResamplingFilter: TResampleFilter = rfFastLinear);
|
|
procedure InsertTransitionFramesEx(Idx : integer; iFrameCount : Integer; Effect : TIETransitionType;
|
|
StartRect, EndRect : TRect; RectMaintainAspectRatio : boolean = True;
|
|
iWidth : Integer = -1; iHeight : Integer = -1; bStretchSmall : Boolean = False;
|
|
BackgroundColor : TColor = -1; ResamplingFilter: TResampleFilter = rfFastLinear;
|
|
Smoothing: Integer = 96; Timing : TIETransitionTiming = iettLinear);
|
|
|
|
procedure MoveImage(idx: integer; destination: integer);
|
|
procedure MoveSelectedImagesTo(beforeImage: Integer; bUseDisplayOrder: Boolean = true);
|
|
procedure Sort(Compare: TIEImageEnMViewSortCompare); overload;
|
|
procedure Sort(Compare: TIEImageEnMViewSortCompareEx); overload;
|
|
procedure Sort(OrderBy: TIEImageEnMViewSortBy; Ascending: boolean = true; CaseSensitive: boolean = true); overload;
|
|
function AppendImage(): integer; overload;
|
|
function AppendImage(Stream: TStream): integer; overload;
|
|
function AppendImage(Bitmap: TIEBitmap): integer; overload;
|
|
function AppendImage(Bitmap : TBitmap): integer; overload;
|
|
function AppendImage(Width, Height: Integer; PixelFormat: TIEPixelFormat = ie24RGB): Integer; overload;
|
|
function AppendImage(const FileName: String): integer; overload;
|
|
function AppendImage(const FileName: String;
|
|
LoadOnDemand : boolean;
|
|
DefaultTopText : TIEImageEnMViewDefaultText = iedtNone;
|
|
DefaultInfoText : TIEImageEnMViewDefaultText = iedtNone;
|
|
DefaultBottomText : TIEImageEnMViewDefaultText = iedtFilename;
|
|
bSelectIt : Boolean = true): integer; overload;
|
|
|
|
{$ifdef IEIncludeDeprecatedInV5}
|
|
// Deprecated in 6.0.0 (2014-11-11)
|
|
function AppendImage2(Width, Height: Integer; PixelFormat: TIEPixelFormat=ie24RGB): Integer; {$ifdef IEWarningForDeprecated} deprecated {$ifdef IESupportDeprecatedDescription} 'Use AppendImage instead - http://imageen.com/help/Compatibility.html' {$endif}; {$endif}
|
|
{$endif}
|
|
function AppendSplit(SourceGrid: TIEBitmap; cellWidth: Integer; cellHeight: Integer; maxCount: Integer = 0): Integer;
|
|
procedure DeleteImage(idx: integer);
|
|
procedure DeleteSelectedImages;
|
|
property ImageCount: integer read GetImageCount;
|
|
procedure UpdateCoords;
|
|
procedure SetImage(idx: integer; srcImage: TBitmap); overload;
|
|
procedure SetImage(idx: integer; srcImage: TIEBaseBitmap); overload;
|
|
procedure SetImage(idx: Integer; width, height: Integer; PixelFormat: TIEPixelFormat); overload;
|
|
procedure SetImageEx(idx: integer; srcImage: TBitmap);
|
|
procedure SetIEBitmapEx(idx: integer; srcImage: TIEBaseBitmap);
|
|
{$ifdef IEIncludeDeprecatedInV6}
|
|
// Deprecated in 6.2.0 (2015-08-24)
|
|
procedure SetIEBitmap(idx: integer; srcImage: TIEBaseBitmap); {$ifdef IEWarningForDeprecated} deprecated {$ifdef IESupportDeprecatedDescription} 'Use SetImage instead - http://imageen.com/help/Compatibility.html' {$endif}; {$endif}
|
|
{$endif}
|
|
function SetImageFromFile(idx: integer; const FileName: WideString; SourceImageIndex: Integer = 0; FileFormat: TIOFileType = ioUnknown): boolean;
|
|
function SetImageFromStream(idx: integer; Stream: TStream; SourceImageIndex: Integer = 0; FileFormat: TIOFileType = ioUnknown): boolean;
|
|
procedure GetImageToFile(idx: Integer; const FileName: WideString);
|
|
procedure GetImageToStream(idx: Integer; Stream: TStream; ImageFormat: TIOFileType);
|
|
procedure SetImageRect(idx: integer; srcImage: TBitmap; x1, y1, x2, y2: integer); overload;
|
|
procedure SetImageRect(idx: integer; srcImage: TIEBitmap; x1, y1, x2, y2: integer); overload;
|
|
procedure Clear;
|
|
function GetBitmap(idx: integer): TBitmap;
|
|
procedure ReleaseBitmap(idx: integer; saveChanges: Boolean = true);
|
|
function GetTIEBitmap(idx: integer): TIEBitmap;
|
|
function GetImageVisibility(idx: integer): integer;
|
|
function ImageAtPos(x, y: integer; checkBounds: Boolean = true): integer;
|
|
function ImageAtGridPos(row, col: integer): integer;
|
|
function InsertingPoint(x, y: integer): integer;
|
|
|
|
procedure SetThumbnailSize(width, height: Integer; SetImageSize: Boolean = False);
|
|
property ThumbnailClipping : Integer read fThumbnailClipping write SetThumbnailClipping default 0;
|
|
|
|
property IconSize : TIEImageEnMViewIconSize read fIconSize write SetIconSize;
|
|
|
|
procedure CopyToIEBitmap(idx: integer; bmp: TIEBitmap);
|
|
function IsVisible(idx: integer): boolean;
|
|
procedure ReloadImage(idx: Integer);
|
|
// allocations
|
|
procedure PrepareSpaceFor(Width, Height: integer; Bitcount: integer; ImageCount: integer);
|
|
property ImageCacheUseDisk: Boolean read GetImageCacheUseDisk write SetImageCacheUseDisk;
|
|
// selection
|
|
property SelectedImage: integer read fSelectedItem write SetSelectedItem;
|
|
property SelectedImageAlwaysVisible: Boolean read fSelectedImageAlwaysVisible write SetSelectedImageAlwaysVisible;
|
|
procedure Deselect;
|
|
procedure SelectSeek(pos: TIESeek);
|
|
procedure CopySelection(SourceMView: TImageEnMView);
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.CheckThumbBoundsOnSelect
|
|
|
|
<FM>Declaration<FC>
|
|
property CheckThumbBoundsOnSelect: Boolean;
|
|
|
|
<FM>Description<FN>
|
|
When enabled, ImageEn checks the thumbnail bounding rectangle before selecting it. The default is False, which allows more flexible selections.
|
|
|
|
Note: When using multi-selection, CheckThumbBoundsOnSelect must be set to false (the default)
|
|
!!}
|
|
property CheckThumbBoundsOnSelect: Boolean read fCheckThumbBoundsOnSelect write fCheckThumbBoundsOnSelect;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.TrackMouseSelection
|
|
|
|
<FM>Declaration<FC>
|
|
property TrackMouseSelection: Boolean;
|
|
|
|
<FM>Description<FN>
|
|
If True a semi-transparent rectangle is shown during mouse selection.
|
|
|
|
Default: False
|
|
|
|
<FM>Demo<FN>
|
|
<TABLE2>
|
|
<R> <C_IMG_DEMO> <C>Demos\Multi\Multiview\Multiview.dpr </C> </R>
|
|
</TABLE>
|
|
!!}
|
|
property TrackMouseSelection: Boolean read fTrackMouseSelection write fTrackMouseSelection;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.MultiSelecting
|
|
|
|
<FM>Declaration<FC>
|
|
property MultiSelecting: Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Set MultiSelecting to True to simulate a CTRL key press. It allows the user to select multiple images with mouse or arrow keys without pressing the CTRL key.
|
|
Also, MultiSelecting can be used to select more than one image using the <A TImageEnMView.SelectedImage> property.
|
|
|
|
Note: To allow multi-selection, the <A TImageEnMView.EnableMultiSelect> property must be True.
|
|
|
|
<FM>Example<FC>
|
|
// select images 0 and 1 (assumes that you have set ImageEnMView1.EnableMultiSelect := True at design time)
|
|
ImageEnMView1.Deselect;
|
|
ImageEnMView1.MultiSelecting := True;
|
|
ImageEnMView1.SelectedImage := 0;
|
|
ImageEnMView1.SelectedImage := 1;
|
|
ImageEnMView1.MultiSelecting := False;
|
|
!!}
|
|
property MultiSelecting: boolean read fMultiSelecting write fMultiSelecting;
|
|
|
|
property MultiSelectedImages[index: integer]: integer read GetMultiSelectedImages;
|
|
property MultiSelectedImagesCount: integer read GetMultiSelectedImagesCount;
|
|
property MultiSelectedImagesList: TIEArrayOfInteger read GetMultiSelectedImagesList;
|
|
|
|
procedure MultiSelectSortList;
|
|
procedure UnselectImage(idx: integer);
|
|
procedure ToggleSelectImage(idx: integer);
|
|
procedure SelectImage(idx: integer);
|
|
procedure SelectAll;
|
|
procedure BeginSelectImages;
|
|
procedure EndSelectImages;
|
|
function IsSelected(idx: integer): boolean;
|
|
procedure DisplayImageAt(idx: Integer; x, y: Integer);
|
|
|
|
// play
|
|
property Playing: boolean read fPlaying write SetPlaying;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.PlayLoop
|
|
|
|
<FM>Declaration<FC>
|
|
property PlayLoop: boolean;
|
|
|
|
<FM>Description<FN>
|
|
Set PlayLoop to True to continuously loop playback of animated GIF and AVI files (when <A TImageEnMView.Playing> is enabled).
|
|
|
|
!!}
|
|
property PlayLoop: boolean read fPlayLoop write fPlayLoop;
|
|
|
|
property VisibleFrame: integer read fFrame write SetVisibleFrame;
|
|
//
|
|
property TransitionRunning: boolean read GetTransitionRunning;
|
|
|
|
// encapsulated components
|
|
|
|
{!!
|
|
<FS>TImageEnMView.MIO
|
|
|
|
<FM>Declaration<FC>
|
|
property MIO: <A TImageEnMIO>;
|
|
|
|
<FM>Description<FN>
|
|
Encapsulates the <A TImageEnMIO> component inside TImageEnMView (it is created automatically the first time that it is used).
|
|
|
|
<FM>Example<FC>
|
|
ImageEnMView1.MIO.LoadFromFile('C:\film.avi');
|
|
|
|
ImageEnMView1.MIO.Acquire;
|
|
!!}
|
|
property MIO: TImageEnMIO read GetImageEnMIO;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.IEMBitmap
|
|
|
|
<FM>Declaration<FC>
|
|
property IEMBitmap: <A TIEMultiBitmap>;
|
|
|
|
<FM>Description<FN>
|
|
Encapsulates the <A TIEMultiBitmap> object which stores all images of the TImageEnMView.
|
|
|
|
Note: You must call <A TImageEnMView.Update> if you modify <FC>IEMBitmap<FN> directly. Though not for built-in TIEMultiBitmap methods such as Read, Flip, Rotate, Resample, etc.
|
|
|
|
<FM>Example<FC>
|
|
ImageEnMView1.IEMBitmap.RotateAll( 90 );
|
|
!!}
|
|
property IEMBitmap: TIECustomMultiBitmap read GetIEMBitmap;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.Proc
|
|
|
|
<FM>Declaration<FC>
|
|
property Proc: <A TImageEnProc>;
|
|
|
|
<FM>Description<FN>
|
|
The Proc property encapsulates the <A TImageEnProc> component inside TImageEnMView (it is created automatically the first time that it is used). It allows you to perform image editing on the selected image.
|
|
|
|
<FM>Example<FC>
|
|
// Reverse colors of the selected image
|
|
ImageEnMView1.Proc.Negative;
|
|
|
|
// Reverse colors of all images in the TImageEnMView
|
|
ImageEnMView1.LockUpdate;
|
|
for i := 0 to ImageEnMView1.ImageCount - 1 do
|
|
begin
|
|
ImageEnMView1.SelectedImage := i;
|
|
ImageEnMView1.Proc.Negative;
|
|
end;
|
|
ImageEnMView1.SelectedImage := 0;
|
|
ImageEnMView1.UnlockUpdate;
|
|
|
|
!!}
|
|
property Proc: TImageEnProc read GetImageEnProc;
|
|
|
|
|
|
procedure SetExternalMBitmap(value : TIECustomMultiBitmap);
|
|
{$IFDEF UNITTESTING}
|
|
function UnitTesting_GetExternalMBitmap: TIECustomMultiBitmap;
|
|
{$ENDIF}
|
|
|
|
// drag&drop
|
|
procedure IEBeginDrag(Immediate: Boolean; Threshold: Integer=-1);
|
|
procedure IEEndDrag;
|
|
|
|
// input&output
|
|
procedure SaveSnapshot(Stream: TStream; SaveCache: Boolean = True; Compressed: Boolean = False; SaveParams: Boolean = False); overload; virtual;
|
|
procedure SaveSnapshot(FileName: WideString; SaveCache: Boolean = True; Compressed: Boolean = False; SaveParams: Boolean = False); overload; virtual;
|
|
procedure SaveSnapshotEx(Stream: TStream; SaveCache: Boolean; Compressed: Boolean; SaveParams: Boolean; GetExtraParams: TIEProcessStreamEvent);
|
|
function LoadSnapshot(Stream: TStream): Boolean; overload; virtual;
|
|
function LoadSnapshot(FileName: WideString): Boolean; overload; virtual;
|
|
function LoadSnapshotEx(Stream: TStream; SetExtraParams: TIEProcessStreamEvent): Boolean;
|
|
|
|
// animations
|
|
property Animation: TIEAnimation read fAnimation write SetAnimation;
|
|
|
|
function Seek(Destination: TIEIOSeekDestination) : integer;
|
|
|
|
// Checkboxes
|
|
property CheckboxPos : TIEMCheckboxPos read fCheckboxPos write SetCheckboxPos;
|
|
function CheckedCount : Integer;
|
|
property Checked[index: integer]: Boolean read GetChecked write SetChecked;
|
|
procedure SetCheckboxParams(iHorzMargin, iVertMargin : Integer; CustomCheckedImage : TBitmap = nil; CustomUncheckedImage : TBitmap = nil);
|
|
procedure CheckAll;
|
|
procedure UncheckAll;
|
|
|
|
// Gestures
|
|
{!!
|
|
<FS>TImageEnMView.Gestures
|
|
|
|
<FM>Declaration<FC>
|
|
property Gestures: <A TIEMViewerGestures>;
|
|
|
|
<FM>Description<FN>
|
|
TImageEnMView supports native Windows gestures:
|
|
- Dragging the screen to pan an image
|
|
- Pinching to zoom in
|
|
- Reverse-pinching to zoom out
|
|
|
|
ImageEn automatically handles the Windows gesture events, so adding gesture support to your applications requires only that you enable the relevant Gesture property.
|
|
|
|
<FM>Example<FC>
|
|
// enable Pan (scroll) and Zoom gestures
|
|
ImageEnMView1.Gestures.Pan.Enabled := True;
|
|
ImageEnMView1.Gestures.Zoom.Enabled := True;
|
|
!!}
|
|
property Gestures: TIEMViewerGestures read fGestures; // not: cannot stay in published section without an property editor
|
|
|
|
procedure SetAllText(TopText : TIEImageEnMViewDefaultText;
|
|
InfoText : TIEImageEnMViewDefaultText;
|
|
BottomText : TIEImageEnMViewDefaultText);
|
|
|
|
property TextBlockWidth: integer read fTextBlockWidth write SetTextBlockWidth;
|
|
|
|
function FilenameToIndex(const sFilename : string) : integer;
|
|
|
|
// Thumbnails
|
|
property SelectionWidthNoFocus: integer read fSelectionBorderWidthNoFocus write SetSelectionBorderWidthNoFocus;
|
|
property ThumbnailsBorderCurved: boolean read fThumbnailsBorderCurved write SetThumbnailsBorderCurved;
|
|
{$ifdef IEIncludeDeprecatedInV6}
|
|
// Deprecated in 7.0.0 (14/3/2017)
|
|
property SelectionAntialiased: Boolean read fThumbnailsBorderCurved write SetThumbnailsBorderCurved;
|
|
{$endif}
|
|
|
|
procedure ProbeLastSort(out OrderBy: TIEImageEnMViewSortBy; out Ascending: boolean; out CaseSensitive: Boolean);
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.MissingFileIcon
|
|
|
|
<FM>Declaration<FC>
|
|
property MissingFileIcon: TIEBitmap;
|
|
|
|
<FM>Description<FN>
|
|
Image that is displayed for files that cannot be found (i.e. have an invalid file path).
|
|
|
|
Note: Only valid if ietxEnableInternalIcons is specified in <A TImageEnMView.ThumbnailOptionsEx>
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.DefaultFileIcon>
|
|
!!}
|
|
property MissingFileIcon: TIEBitmap read fMissingFileIcon;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.DefaultFileIcon
|
|
|
|
<FM>Declaration<FC>
|
|
property DefaultFileIcon: TIEBitmap;
|
|
|
|
<FM>Description<FN>
|
|
Image that is displayed for files while loading.
|
|
|
|
Note: Only valid if ietxEnableInternalIcons is specified in <A TImageEnMView.ThumbnailOptionsEx>, and ietxShowIconWhileLoading is not included.
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.MissingFileIcon>
|
|
!!}
|
|
property DefaultFileIcon: TIEBitmap read fDefaultFileIcon;
|
|
|
|
published
|
|
///////////////////////
|
|
// P U B L I S H E D
|
|
property ScrollBars: TIEScrollStyle read fScrollBars write SetScrollBars default ssBoth;
|
|
|
|
property StoreType: TIEStoreType read fStoreType write SetStoreType; // NB: No default. Always store!
|
|
|
|
property ThumbWidth: integer read fThumbWidth write SetThumbWidth; // NB: No default. Always store!
|
|
property ThumbHeight: integer read fThumbHeight write SetThumbHeight; // NB: No default. Always store!
|
|
property HorizBorder: integer read fHorizBorder write SetHorizBorder; // NB: No default. Always store!
|
|
property VertBorder: integer read fVertBorder write SetVertBorder; // NB: No default. Always store!
|
|
property BottomGap: integer read fBottomGap write SetBottomGap default 0;
|
|
property UpperGap: integer read fUpperGap write SetUpperGap default 0;
|
|
property SideGap: integer read fSideGap write SetSideGap default 0;
|
|
property TextMargin: integer read fTextMargin write SetTextMargin default 0;
|
|
|
|
property ThumbnailOptionsEx : TIEMThumbnailOptionsEx read fThumbnailOptionsEx write SetThumbnailOptionsEx default [ietxShowIconForUnknownFormat, ietxShowIconWhileLoading, ietxEnableInternalIcons, ietxStretchSmallImages];
|
|
property IOOptionsEx : TIEMIOOptionsEx read fIOOptionsEx write SetIOOptionsEx default [];
|
|
|
|
{!!
|
|
<FS>TImageEnMView.OnViewChange
|
|
|
|
<FM>Declaration<FC>
|
|
property OnViewChange: <A TViewChangeEvent>;
|
|
|
|
<FM>Description<FN>
|
|
Occurs when the <A TImageEnMView.ViewX> or <A TImageEnMView.ViewY> properties change.
|
|
!!}
|
|
property OnViewChange: TViewChangeEvent read fOnViewChange write fOnViewChange;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.OnImageAtPos
|
|
|
|
<FM>Declaration<FC>
|
|
property OnImageAtPos: <A TIEImageAtPosEvent>;
|
|
|
|
<FM>Description<FN>
|
|
Occurs whenever it is necessary to check if specified coordinates are inside a thumbnail.
|
|
|
|
!!}
|
|
property OnImageAtPos: TIEImageAtPosEvent read fOnImageAtPos write fOnImageAtPos;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.OnCreateImage
|
|
|
|
<FM>Declaration<FC>
|
|
property OnCreateImage: <A TIECreateImageEvent>;
|
|
|
|
<FM>Description<FN>
|
|
Occurs whenever (immediately after) a new image is created (i.e whenever a new image is added to the TImageEnMView).
|
|
!!}
|
|
property OnCreateImage: TIECreateImageEvent read fOnCreateImage write fOnCreateImage;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.OnDestroyImage
|
|
|
|
<FM>Declaration<FC>
|
|
property OnDestroyImage: <A TIEDestroyImageEvent>;
|
|
|
|
<FM>Description<FN>
|
|
Occurs whenever (immediately before) an image is destroyed (i.e whenever an image is removed from the TImageEnMView).
|
|
!!}
|
|
property OnDestroyImage: TIEDestroyImageEvent read fOnDestroyImage write fOnDestroyImage;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.OnImageIDRequest
|
|
|
|
<FM>Declaration<FC>
|
|
property OnImageIDRequest: <A TIEImageIDRequestEvent>;
|
|
|
|
<FM>Description<FN>
|
|
Occurs whenever an image is required, if you have specified a value for its <A TImageEnMView.ImageID> property.
|
|
|
|
<FC>ID<FN> is the value you have specified in <A TImageEnMView.ImageID> property;
|
|
<FC>Bitmap<FN> is the image to display. It is a TBitmap (use <A TImageEnMView.OnImageIDRequestEx> if you require a <A TIEBitmap>). The bitmap is copied in TImageEnMView, and then automatically freed.
|
|
|
|
<FM>Example<FC>
|
|
procedure TMyForm.ImageEnMViewOnImageIDRequest(Sender: TObject; ID: integer; var Bitmap: TBitmap);
|
|
begin
|
|
// Retrieve the image from a TImageList
|
|
Bitmap := TBitmap.create;
|
|
ImageList1.GetBitmap(ID, Bitmap);
|
|
end;
|
|
|
|
!!}
|
|
property OnImageIDRequest: TIEImageIDRequestEvent read fOnImageIDRequest write fOnImageIDRequest;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.OnImageIDRequestEx
|
|
|
|
<FM>Declaration<FC>
|
|
property OnImageIDRequestEx: <A TIEImageIDRequestExEvent>;
|
|
|
|
<FM>Description<FN>
|
|
Occurs whenever an image is required if you have specified a value for the <A TImageEnMView.ImageID> property.
|
|
|
|
<FC>ID<FN> is the value you have specified in <A TImageEnMView.ImageID> property;
|
|
<FC>Bitmap<FN> is the image to display. It is a <A TIEBitmap> (use <A TImageEnMView.OnImageIDRequest> if you require a TBitmap). The bitmap is copied in TImageEnMView, and then automatically freed.
|
|
|
|
<FM>Example<FC>
|
|
procedure TMyForm.ImageEnMViewOnImageIDRequestEx(Sender: TObject; ID: integer; var Bitmap: TIEBitmap);
|
|
begin
|
|
// Create the image dynamically
|
|
Bitmap := TIEBitmap.create;
|
|
GenerateChartOfID(ID, Bitmap);
|
|
end;
|
|
|
|
!!}
|
|
property OnImageIDRequestEx: TIEImageIDRequestExEvent read fOnImageIDRequestEx write fOnImageIDRequestEx;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.OnBeforeImageDraw
|
|
|
|
<FM>Declaration<FC>
|
|
property OnBeforeImageDraw: <A TIEImageDrawEvent>;
|
|
|
|
<FM>Description<FN>
|
|
Occurs immediately before an image is drawn. It can be used to prepare parameters prior to drawing the image (e.g. <A TImageEnMView.ImageTopText>, <A TImageEnMView.ImageBottomText> and <A TImageEnMView.ImageInfoText>).
|
|
|
|
Note: <FC>OnBeforeImageDraw<FN> and <A TImageEnMView.OnBeforeImageDrawEx> are identical, except that <A TImageEnMView.OnBeforeImageDrawEx> includes a <FC>ThumbRect<FN> parameter. Also if <A TImageEnMView.OnBeforeImageDrawEx> is used the selection is not shown.
|
|
!!}
|
|
property OnBeforeImageDraw: TIEImageDrawEvent read fOnBeforeImageDraw write fOnBeforeImageDraw;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.OnBeforeImageDrawEx
|
|
|
|
<FM>Declaration<FC>
|
|
property OnBeforeImageDrawEx: <A TIEImageDrawEventEx>;
|
|
|
|
<FM>Description<FN>
|
|
|
|
Occurs immediately before the image of index, <FC>idx<FN>, is painted.
|
|
<FC>Left<FN>, <FC>Top<FN> are the top-left coordinates where the image will be drawn (i.e. destination bitmap coordinates).
|
|
<FC>Dest<FN> is the destination bitmap (containing the canvas where the image must be drawn).
|
|
<FC>ThumbRect<FN> specifies the destination rectangle for the image. You can change this parameter to control where the image is drawn.
|
|
|
|
Note: When this event is assigned, the selection is not shown.
|
|
|
|
See the Multi\CustomThumbs demo for more info.
|
|
|
|
Note: <A TImageEnMView.OnBeforeImageDraw> and <FC>OnBeforeImageDrawEx<FN> are identical, except that <FC>OnBeforeImageDrawEx<FN> includes a <FC>ThumbRect<FN> parameter. Also if <FC>OnBeforeImageDrawEx<FN> is used the selection is not shown.
|
|
!!}
|
|
property OnBeforeImageDrawEx: TIEImageDrawEventEx read fOnBeforeImageDrawEx write fOnBeforeImageDrawEx;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.OnImageDraw
|
|
|
|
<FM>Declaration<FC>
|
|
property OnImageDraw: <A TIEImageDrawEvent>;
|
|
|
|
<FM>Description<FN>
|
|
Occurs whenever an image is painted.
|
|
|
|
Note: <FC>OnImageDraw<FN> and <A TImageEnMView.OnImageDraw2> are identical, except that <A TImageEnMView.OnImageDraw2> includes a <FC>ThumbRect<FN> parameter to return the thumbnail rectangle.
|
|
|
|
<FM>Example<FC>
|
|
// Display the image index and sizes on bottom of the thumbnail
|
|
// Ensure you have set the BottomGap property
|
|
procedure TForm1.ImageEnMView1ImageDraw(Sender: TObject; idx: Integer; Left, Top: Integer; Canvas: TCanvas);
|
|
begin
|
|
with canvas do
|
|
begin
|
|
Font.Height := 15;
|
|
Font.Color := clWhite;
|
|
TextOut(Left, Top + imageenmview1.ThumbHeight - imageenmview1.bottomgap + 2, IntToStr(idx));
|
|
TextOut(Left, Top, IntToStr(imageenmview1.ImageWidth[idx]) + 'x' + IntToStr(imageenmview1.ImageHeight[idx]));
|
|
end;
|
|
end;
|
|
!!}
|
|
property OnImageDraw: TIEImageDrawEvent read fOnImageDraw write fOnImageDraw;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.OnImageDraw2
|
|
|
|
<FM>Declaration<FC>
|
|
property OnImageDraw2: <A TIEImageDraw2Event>;
|
|
|
|
<FM>Description<FN>
|
|
Occurs whenever an image is painted.
|
|
|
|
Note: <A TImageEnMView.OnImageDraw> and <FC>OnImageDraw2<FN> are identical, except that <FC>OnImageDraw2<FN> includes a <FC>ThumbRect<FN> parameter to return the thumbnail rectangle.
|
|
|
|
<FM>Demo<FN>
|
|
<TABLE2>
|
|
<R> <C_IMG_DEMO> <C>Demos\Multi\CustomThumbs2\CustomThumbs2.dpr </C> </R>
|
|
</TABLE>
|
|
|
|
<FM>Example<FC>
|
|
// Display the image index and sizes on bottom of the thumbnail
|
|
// Ensure you have set the BottomGap property
|
|
procedure TForm1.ImageEnMView1ImageDraw2(Sender: TObject; idx: Integer; Left, Top: Integer; Canvas: TCanvas);
|
|
begin
|
|
with canvas do
|
|
begin
|
|
Font.Height := 15;
|
|
Font.Color := clWhite;
|
|
TextOut(Left, Top + imageenmview1.ThumbHeight - imageenmview1.bottomgap + 2, IntToStr(idx));
|
|
TextOut(Left, Top, IntToStr(imageenmview1.ImageWidth[idx]) + 'x' + IntToStr(imageenmview1.ImageHeight[idx]));
|
|
end;
|
|
end;
|
|
!!}
|
|
property OnImageDraw2: TIEImageDraw2Event read fOnImageDraw2 write fOnImageDraw2;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.OnImageOut
|
|
|
|
<FM>Declaration<FC>
|
|
property OnImageOut: <A TIEImageOutEvent>;
|
|
|
|
<FM>Description<FN>
|
|
Occurs during the drawing of thumbnails, just prior to the painting of the image. It can be used to manipulate the image (rotate, color effects, etc) or add annotations.
|
|
|
|
Note: Only the drawing of the image is affected, not the image itself.
|
|
|
|
<FM>Example<FC>
|
|
// Rotate all images 90 dec. CCW
|
|
procedure TForm1.ImageEnMView1ImageOut(Sender: TObject; idx: Integer; OutBitmap: TIEBitmap);
|
|
begin
|
|
OutBitmap.Rotate( 90 );
|
|
end;
|
|
!!}
|
|
property OnImageOut: TIEImageOutEvent read fOnImageOut write fOnImageOut;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.OnImageSelect
|
|
|
|
<FM>Declaration<FC>
|
|
property OnImageSelect: <A TIEImageSelectEvent>;
|
|
|
|
<FM>Description<FN>
|
|
Occurs whenever an image is selected.
|
|
|
|
<FM>Example<FC>
|
|
// Show the selected image in a TImageEnView
|
|
procedure TMainForm.ImageEnMView1ImageSelect(Sender: TObject; idx: Integer);
|
|
begin
|
|
ImageEnMView1.CopyToIEBitmap( idx, ImageEnView1.IEBitmap );
|
|
ImageEnVeiw1.Update;
|
|
end;
|
|
!!}
|
|
property OnImageSelect: TIEImageSelectEvent read fOnImageSelect write fOnImageSelect;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.OnImageAdd
|
|
|
|
<FM>Declaration<FC>
|
|
property OnImageAdd: <A TIEImageAddEvent>;
|
|
|
|
<FM>Description<FN>
|
|
Occurs whenever an image is added to a <A TImageEnFolderMView> or when using <L TImageEnMView.FillFromDirectory>TImageEnMView.FillFromDirectory</L>.
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.OnImageAdded>
|
|
- <A TImageEnMView.OnImageLoaded>
|
|
!!}
|
|
property OnImageAdd: TIEImageAddEvent read fOnImageAdd write fOnImageAdd;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.OnImageAdded
|
|
|
|
<FM>Declaration<FC>
|
|
property OnImageAdded: <A TIEMViewImageNotifyEvent>;
|
|
|
|
<FM>Description<FN>
|
|
Occurs whenever an image has been added to the control.
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.OnImageAdd>
|
|
- <A TImageEnMView.OnImageLoaded>
|
|
!!}
|
|
property OnImageAdded: TIEMViewImageNotifyEvent read fOnImageAdded write fOnImageAdded;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.OnImageLoaded
|
|
|
|
<FM>Declaration<FC>
|
|
property OnImageLoaded: <A TIEMViewImageNotifyEvent>;
|
|
|
|
<FM>Description<FN>
|
|
Occurs whenever an image is completes loading within the control. If an image is loaded on demand, some properties of the image, such as its <A TImageEnMIO.Params> are not available. This event occurs once the image has completed loading and its content and properties are available.
|
|
|
|
Note: The <A TImageEnMView.OnAllDisplayed> event occurs once <FB>all<FN> images are loaded and displayed
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.OnImageAdded>
|
|
- <A TImageEnMView.OnAllDisplayed>
|
|
!!}
|
|
property OnImageLoaded: TIEMViewImageNotifyEvent read fOnImageLoaded write fOnImageLoaded;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.OnGetText
|
|
|
|
<FM>Declaration<FC>
|
|
property OnGetText: <A TIEGetTextEvent>;
|
|
|
|
<FM>Description<FN>
|
|
Occurs before text is output when drawing a thumbnail allowing you to insert or modify the displayed text.
|
|
|
|
Notes:
|
|
- If <A TImageEnMView.Style> is <FC>iemsColumns<FN> then <FC>OnGetText<FN> is also called for the header row. The <FC>Index<FN> will be -1.
|
|
- If default text has not been specified for any thumbnails, you may need to set <A TImageEnMView.UpperGap>/<A TImageEnMView.BottomGap> to allow space for the text
|
|
|
|
<FM>Example<FC>
|
|
// Note: In form create we set IEFolderMView.UpperGap := 20;
|
|
|
|
// Display the file index above the frame
|
|
procedure TForm1.IEFolderMViewGetText(Sender: TObject; Index: Integer; Position: TIEMTextPos; var Text: WideString);
|
|
begin
|
|
if Index = -1 then
|
|
Text := 'File Number' // Header row
|
|
else
|
|
if Position = iemtpTop then
|
|
Text := 'File #' + IntToStr(Index + 1);
|
|
end;
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.OnGetTextEx>
|
|
!!}
|
|
property OnGetText: TIEGetTextEvent read fOnGetText write fOnGetText;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.OnGetTextEx
|
|
|
|
<FM>Declaration<FC>
|
|
property OnGetTextEx: <A TIEGetTextExEvent>;
|
|
|
|
<FM>Description<FN>
|
|
Occurs before text is output when drawing a thumbnail allowing you to insert or modify the displayed text and change the styling.
|
|
|
|
Notes:
|
|
- If <A TImageEnMView.Style> is <FC>iemsColumns<FN> then <FC>OnGetText<FN> is also called for the header row. The <FC>Index<FN> will be -1.
|
|
- If default text has not been specified for any thumbnails, or you are increasing the size of the font, you may need to set <A TImageEnMView.UpperGap>/<A TImageEnMView.BottomGap> to allow space for the text
|
|
|
|
<FM>Example<FC>
|
|
// Display the file as bold if it is JPEG
|
|
procedure TForm1.IEFolderMViewGetTextEx(Sender: TObject; Index: Integer; Position: TIEMTextPos; var Text: WideString;
|
|
var Font : TFont; var BackgroundStyle: TBrushStyle; var BackgroundColor: TColor;
|
|
var TruncSide: TIEMTruncSide);
|
|
begin
|
|
if ( Position <> iemtpBottom ) or ( Index = -1 ) then
|
|
exit;
|
|
sFileExt := ExtractFileExt( Text );
|
|
if IEExtToFileFormat( sFileExt ) = ioJPEG then
|
|
Font.Style := [fsBold]
|
|
else
|
|
Font.Style := [];
|
|
end;
|
|
|
|
// Give text on every thumb a random background color
|
|
procedure TForm1.IEFolderMViewGetTextEx(Sender: TObject; Index: Integer; Position: TIEMTextPos; var Text: WideString;
|
|
Font : TFont; var BackgroundStyle: TBrushStyle; var BackgroundColor: TColor;
|
|
var TruncSide: TIEMTruncSide);
|
|
begin
|
|
BackgroundColor := RGB( Random( 256 ), Random( 256 ), Random( 256 ));
|
|
BackgroundStyle := bsSolid;
|
|
end;
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.OnGetText>
|
|
|
|
!!}
|
|
property OnGetTextEx: TIEGetTextExEvent read fOnGetTextEx write fOnGetTextEx;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.OnImageDeselect
|
|
|
|
<FM>Declaration<FC>
|
|
property OnImageDeselect: <A TIEImageSelectEvent>;
|
|
|
|
<FM>Description<FN>
|
|
Occurs whenever the user removes the selection from an image.
|
|
|
|
Note: <A TImageEnMView.EnableMultiSelect> must be true.
|
|
!!}
|
|
property OnImageDeselect: TIEImageSelectEvent read fOnImageDeselect write fOnImageDeselect;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.OnSelectionChanging
|
|
|
|
<FM>Declaration<FC>
|
|
property OnSelectionChanging: <A TIESelectionChangingEvent>;
|
|
|
|
<FM>Description<FN>
|
|
Occurs prior to a change in the selected frame/thumbnail due to user action (i.e. mouse or keyboard).
|
|
|
|
This can be used to prevent changing of a selection (e.g. due to the current selection not being saved).
|
|
!!}
|
|
property OnSelectionChanging: TIESelectionChangingEvent read fOnSelectionChanging write fOnSelectionChanging;
|
|
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.OnIOProgress
|
|
|
|
<FM>Declaration<FC>
|
|
property OnIOProgress: <A TIEProgressEvent>;
|
|
|
|
<FM>Description<FN>
|
|
Occurs during input/output operations to advise the progress of the operation.
|
|
!!}
|
|
property OnIOProgress: TIEProgressEvent read fOnIOProgress write fOnIOProgress;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.OnDrawProgress
|
|
|
|
<FM>Declaration<FC>
|
|
property OnDrawProgress: <A TIEMProgressEvent>;
|
|
|
|
<FM>Description<FN>
|
|
Occurs during painting for each image drawn.
|
|
|
|
<FM>Example<FC>
|
|
procedure TForm1.ImageEnMView1DrawProgress(Sender: TObject; per, idx: Integer);
|
|
begin
|
|
ProgressBar1.Position := per;
|
|
end;
|
|
!!}
|
|
property OnDrawProgress: TIEMProgressEvent read fOnDrawProgress write fOnDrawProgress;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.OnWrongImage
|
|
|
|
<FM>Declaration<FC>
|
|
property OnWrongImage: <A TIEWrongImageEvent>;
|
|
|
|
<FM>Description<FN>
|
|
Occurs whenever TImageEnMView cannot load the image specified by the <A TImageEnMView.ImageFileName> property, for instance when the file is corrupt or of an unrecognized format.
|
|
|
|
You can specify an alternative bitmap to display by changing the OutBitmap property.
|
|
|
|
<FM>Example<FC>
|
|
Procedure MyForm1OnWrongImage(Sender: TObject; OutBitmap: TIEBitmap; idx: Integer; var Handled: Boolean);
|
|
Var
|
|
io: TImageEnIO;
|
|
begin
|
|
io := TImageEnIO.CreateFromBitmap(OutBitmap);
|
|
io.LoadFromFile('error_image.bmp');
|
|
io.Free;
|
|
Handled := True;
|
|
end;
|
|
!!}
|
|
property OnWrongImage: TIEWrongImageEvent read fOnWrongImage write fOnWrongImage;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.OnCheckboxClick
|
|
|
|
<FM>Declaration<FC>
|
|
property OnCheckboxClick: <A TIECheckboxClickEvent>;
|
|
|
|
<FM>Description<FN>
|
|
Occurs whenever a user clicks a checkbox.
|
|
|
|
<FC>idx<FN> is the index of the clicked image.
|
|
<FC>bChecked<FN> specifies the new status of the image. You can override it, e.g. set it to false if the image cannot be checked
|
|
|
|
Note: Don't read <A TImageEnMView.CheckedCount> in this event which will not yet be valid. Use OnClick or OnMouseUp.
|
|
|
|
<FM>Example<FC>
|
|
procedure TfMain.ImageEnMView1CheckboxClick(Sender: TObject; idx: integer; var bChecked : Boolean);
|
|
begin
|
|
// Only allow JPEG images to be checked
|
|
if bChecked and (IEFileIsOfFormat(ImageEnMView1.ImageFilename[idx], ioJPEG) = False) then
|
|
begin
|
|
MessageBeep(MB_ICONEXCLAMATION);
|
|
bChecked := False;
|
|
end;
|
|
end;
|
|
|
|
<FM>See also<FN>
|
|
- <A TImageEnMView.Checkboxes>
|
|
- <A TImageEnMView.CheckedCount>
|
|
!!}
|
|
property OnCheckboxClick: TIECheckboxClickEvent read fOnCheckboxClick write fOnCheckboxClick;
|
|
|
|
property Checkboxes : TIEMCheckboxType read fCheckboxes write SetCheckboxes default iecbNone;
|
|
|
|
property VisibleSelection: boolean read fVisibleSelection write SetVisibleSelection default true;
|
|
property MouseInteract: TIEMMouseInteract read GetMouseInteract write SetMouseInteract default [mmiSelect];
|
|
property KeyInteract: TIEMKeyInteract read GetKeyInteract write SetKeyInteract default [mkiMoveSelected];
|
|
property DisplayMode: TIEMDisplayMode read fDisplayMode write SetDisplayMode default mdGrid;
|
|
property GridWidth: integer read fGridWidth write SetGridWidth; // NB: No default. Always store!
|
|
property SelectionWidth: integer read fSelectionBorderWidth write SetSelectionBorderWidth default 2;
|
|
property SelectionColor: TColor read fThumbnailsSelectedBorderColor write SetThumbnailsSelectedBorderColor;
|
|
property DrawImageBackground: boolean read fDrawImageBackground write SetDrawImageBackground default false;
|
|
property ImageCacheSize: integer read GetImageCacheSize write SetImageCacheSize default 10;
|
|
{!!
|
|
<FS>TImageEnMView.TransitionEffect
|
|
|
|
<FM>Declaration<FC>
|
|
property TransitionEffect: <A TIETransitionType>;
|
|
|
|
<FM>Description<FN>
|
|
Specifies the effect to apply when the application changes the currently displayed frame.
|
|
|
|
Note: <A TImageEnMView.DisplayMode> must be <FC>mdSingle<FN>. To change current frame, use the <A TImageEnMView.VisibleFrame> property.
|
|
|
|
<FB>iettShreddedFromLeft<FN>
|
|
|
|
<IMG help_images\Transition.jpg>
|
|
|
|
<FB>iettCubeRotateFromTop2<FN>
|
|
|
|
<IMG help_images\CubeTransition.jpg>
|
|
|
|
<FM>Example<FC>
|
|
// Design time properties...
|
|
ImageEnMView1.DisplayMode := mdSingle;
|
|
ImageEnMView1.TransitionEffect := iettCrossDissolve;
|
|
ImageEnMView1.TransitionDuration := 1500;
|
|
|
|
// Display next frame using cross dissolve effect
|
|
ImageEnMView1.VisibleFrame := ImageEnMView1.VisibleFrame + 1;
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.TransitionDuration>
|
|
!!}
|
|
property TransitionEffect: TIETransitionType read fTransitionEffect write fTransitionEffect default iettNone;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.TransitionDuration
|
|
|
|
<FM>Declaration<FC>
|
|
property TransitionDuration: Integer;
|
|
|
|
<FM>Description<FN>
|
|
Specifies the duration of the transition in milliseconds.
|
|
|
|
<FM>Example<FC>
|
|
// Design time properties...
|
|
ImageEnMView1.DisplayMode := mdSingle;
|
|
ImageEnMView1.TransitionEffect := iettCrossDissolve;
|
|
ImageEnMView1.TransitionDuration := 1500;
|
|
|
|
// Display next frame using cross dissolve effect
|
|
ImageEnMView1.VisibleFrame := ImageEnMView1.VisibleFrame + 1;
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.TransitionEffect>
|
|
!!}
|
|
property TransitionDuration: integer read fTransitionDuration write fTransitionDuration default 1000;
|
|
|
|
property Style: TIEMStyle read fStyle write SetStyle; // NB: No default. Always store!
|
|
|
|
procedure SetStyleEx(aStyle: TIEMStyle;
|
|
TopText : TIEImageEnMViewDefaultText;
|
|
InfoText : TIEImageEnMViewDefaultText;
|
|
BottomText : TIEImageEnMViewDefaultText;
|
|
iThumbZoom: Double = 0;
|
|
bAdjustSpacing: Boolean = True;
|
|
bAdjustStyle: Boolean = True;
|
|
bAdjustFont: Boolean = True);
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ThumbnailsBackground
|
|
|
|
<FM>Declaration<FC>
|
|
property ThumbnailsBackground: TColor;
|
|
|
|
<FM>Description<FN>
|
|
Specifies the background color of the thumbnails when they are NOT selected. Use <A TImageEnMView.ThumbnailsBackgroundSelected> to set the color when selected.
|
|
|
|
Notes:
|
|
- This value may be overridden if <A TIEImageEnGlobalSettings.EnableTheming> is enabled.
|
|
- Not used if <A TImageEnMView.DrawImageBackground> is enabled
|
|
!!}
|
|
property ThumbnailsBackground: TColor read fThumbnailsBackground write fThumbnailsBackground; // NB: No default. Always store!
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ThumbnailsBackgroundSelected
|
|
|
|
<FM>Declaration<FC>
|
|
property ThumbnailsBackgroundSelected: TColor;
|
|
|
|
<FM>Description<FN>
|
|
Specifies the background color of the thumbnails when they are selected. Use <A TImageEnMView.ThumbnailsBackground> to set the color when NOT selected.
|
|
|
|
Notes:
|
|
- This value may be overridden if <A TIEImageEnGlobalSettings.EnableTheming> is enabled.
|
|
- Not used if <A TImageEnMView.DrawImageBackground> is enabled
|
|
!!}
|
|
property ThumbnailsBackgroundSelected: TColor read fThumbnailsBackgroundSelected write fThumbnailsBackgroundSelected; // NB: No default. Always store!
|
|
|
|
|
|
|
|
property EnableMultiSelect: boolean read fEnableMultiSelect write SetEnableMultiSelect default false;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.MultiSelectionOptions
|
|
|
|
<FM>Declaration<FC>
|
|
property MultiSelectionOptions: <A TIEMultiSelectionOptions>;
|
|
|
|
<FM>Description<FN>
|
|
Controls the behaviour of selection.
|
|
|
|
<FM>Example<FC>
|
|
// If you do not specify iemoRegion the entire row is selected:
|
|
ImageEnMView1.MultiSelectionOptions := [];
|
|
|
|
<IMG help_images\NormSel.jpg>
|
|
|
|
|
|
// By specifying iemoRegion only the specified columns are selected:
|
|
ImageEnMView1.MultiSelectionOptions := [iemoRegion];
|
|
|
|
<IMG help_images\RegionSel.jpg>
|
|
!!}
|
|
property MultiSelectionOptions: TIEMultiSelectionOptions read fMultiSelectionOptions write fMultiSelectionOptions; // NB: No default
|
|
|
|
property ThumbnailsBorderWidth: integer read fThumbnailsBorderWidth write SetThumbnailsBorderWidth; // NB: No default
|
|
property ThumbnailsBorderColor: TColor read fThumbnailsBorderColor write SetThumbnailsBorderColor default clBtnFace;
|
|
property ThumbnailsInternalBorder: boolean read fThumbnailsInternalBorder write SetThumbnailsInternalBorder default false;
|
|
property ThumbnailsInternalBorderColor: TColor read fThumbnailsInternalBorderColor write SetThumbnailsInternalBorderColor default clBlack;
|
|
property Wallpaper: TPicture read fWallpaper write SetWallpaper;
|
|
property WallpaperStyle: TIEWallpaperStyle read fWallpaperStyle write SetWallpaperStyle default iewoNormal;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ThreadPoolSize
|
|
|
|
<FM>Declaration<FC>
|
|
property ThreadPoolSize: Integer;
|
|
|
|
<FM>Description<FN>
|
|
Specifies how many threads can be created to load images (to load images in the background). If ThreadPoolSize is set to 0 all images are loaded in the main thread.
|
|
!!}
|
|
property ThreadPoolSize: integer read fThreadPoolSize write fThreadPoolSize default 5;
|
|
|
|
property EnableAlphaChannel: boolean read fEnableAlphaChannel write SetEnableAlphaChannel default true;
|
|
property BackgroundStyle: TIEBackgroundStyle read fBackgroundStyle write SetBackgroundStyle default iebsSolid;
|
|
property ThumbnailsBackgroundStyle: TIEBackgroundStyle read fThumbnailsBackgroundStyle write SetThumbnailsBackgroundStyle default iebsSolid;
|
|
|
|
property OnProgress: TIEProgressEvent read GetOnProgress write SetOnProgress;
|
|
property OnAcquireBitmap: TIEAcquireBitmapEvent read GetOnAcquireBitmap write SetOnAcquireBitmap;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.OnAllDisplayed
|
|
|
|
<FM>Declaration<FC>
|
|
property OnAllDisplayed: TNotifyEvent;
|
|
|
|
<FM>Description<FN>
|
|
Occurs when all images have been loaded and displayed.
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.OnImageLoaded>
|
|
!!}
|
|
property OnAllDisplayed: TNotifyEvent read fOnAllDisplayed write fOnAllDisplayed;
|
|
|
|
property OnFinishWork: TNotifyEvent read GetOnFinishWork write SetOnFinishWork;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.OnPlayFrame
|
|
|
|
<FM>Declaration<FC>
|
|
property OnPlayFrame: <A TIEPlayFrameEvent>;
|
|
|
|
<FM>Description<FN>
|
|
Occurs whenever a frame is displayed. You can set <FC>bShowFrame<FN> to False to skip playback of specific frames.
|
|
|
|
See also: <A TImageEnMView.Playing>.
|
|
|
|
<FM>Example<FC>
|
|
// We have two TImageEnMViews showing the same set of images: iemFileList shows thumbnails of all images. iemDisplay shows a slideshow. A button displays a slideshow of all checked images in iemFileList
|
|
procedure TMainForm.iemDisplayPlayFrame(Sender: TObject; FrameIndex: integer; var bShowFrame: Boolean);
|
|
begin
|
|
if iemFileList.Checked[FrameIndex] = False then
|
|
bShowFrame := False;
|
|
end;
|
|
!!}
|
|
property OnPlayFrame: TIEPlayFrameEvent read fOnPlayFrame write fOnPlayFrame;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.OnAnimationText
|
|
|
|
<FM>Declaration<FC>
|
|
property OnAnimationText: <A TIEAnimationTextEvent>;
|
|
|
|
<FM>Description<FN>
|
|
Occurs whenever text needs to be displayed during an animation.
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.Animation>
|
|
!!}
|
|
property OnAnimationText: TIEAnimationTextEvent read fOnAnimationText write fOnAnimationText;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.OnAfterEvent
|
|
|
|
<FM>Declaration<FC>
|
|
property OnAfterEvent: <A TIEAfterEventEvent>;
|
|
|
|
<FM>Description<FN>
|
|
Occurs immediately after ImageEn has processed an event.
|
|
|
|
See <A TIEAfterEvent> for a list of handled events.
|
|
!!}
|
|
property OnAfterEvent: TIEAfterEventEvent read fOnAfterEvent write fOnAfterEvent;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.OnImageEnGesture
|
|
|
|
<FM>Declaration<FC>
|
|
property OnImageEnGesture: <A TIEImageEnGestureEvent>;
|
|
|
|
<FM>Description<FN>
|
|
Occurs whenever a gesture is handled by ImageEn.
|
|
!!}
|
|
property OnImageEnGesture: TIEImageEnGestureEvent read fOnImageEnGesture write fOnImageEnGesture;
|
|
|
|
property DefaultTopText : TIEImageEnMViewDefaultText read fDefaultTopText write SetDefaultTopText Default iedtNone;
|
|
property DefaultInfoText : TIEImageEnMViewDefaultText read fDefaultInfoText write SetDefaultInfoText Default iedtNone;
|
|
property DefaultBottomText : TIEImageEnMViewDefaultText read fDefaultBottomText write SetDefaultBottomText; // NO DEFAULT
|
|
|
|
property ImageEnVersion: String read GetImageEnVersion write SetImageEnVersion stored false;
|
|
{$ifdef IEINCLUDEFLATSB}
|
|
property FlatScrollBars: Boolean read fFlatScrollBars write SetFlatScrollBars default False;
|
|
{$endif}
|
|
|
|
property OnMouseWheel;
|
|
property OnMouseWheelDown;
|
|
property OnMouseWheelUp;
|
|
|
|
property Align;
|
|
property Anchors;
|
|
|
|
property ShowThumbnailHint: Boolean read fShowThumbnailHint write SetShowThumbnailHint default False;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ThumbnailResampleFilter
|
|
|
|
<FM>Declaration<FC>
|
|
property ThumbnailResampleFilter: <A TResampleFilter>;
|
|
|
|
<FM>Description<FN>
|
|
Specifies the filter to use when thumbnails are generated (when assigning images to a TImageEnMView and <A TImageEnMView.StoreType> = ietThumb). Filters improve the quality of the thumbnail, but can slow down the application.
|
|
A value of <FC>rfNone<FN> provides no quality enhancement. Filters such as <FC>rfLanczos3<FN> provide excellent quality, but are slower.
|
|
|
|
Default: rfFastLinear (improve quality with negligible speed impact)
|
|
|
|
Note: Unlike <A TImageEnMView.ThumbnailDisplayFilter>, ThumbnailResampleFilter is only used once for each image (when it first assigned/loaded)
|
|
|
|
<FM>Example<FC>
|
|
// insert image 1.jpg and 2.jpg. Only 1.jpg will be filtered.
|
|
ImageEnMView1.ThumbnailResampleFilter := rfBSpline;
|
|
Idx := ImageEnMView1.AppendImage;
|
|
ImageEnMView1.SetImageFromFile('1.jpg');
|
|
|
|
ImageEnMView1.ThumbnailResampleFilter := rfNone;
|
|
Idx := ImageEnMView1.AppendImage;
|
|
ImageEnMView1.SetImageFromFile('2.jpg');
|
|
!!}
|
|
property ThumbnailResampleFilter: TResampleFilter read fThumbnailResampleFilter write fThumbnailResampleFilter;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ThumbnailDisplayFilter
|
|
|
|
<FM>Declaration<FC>
|
|
property ThumbnailDisplayFilter: <A TResampleFilter>;
|
|
|
|
<FM>Description<FN>
|
|
ThumbnailDisplayFilter specifies a filter to apply when an image (thumbnail) need to be resized for display. Filters improve the quality of the thumbnail, but can slow down the application.
|
|
A value of <FC>rfNone<FN> provides no quality enhancement. Filters such as <FC>rfLanczos3<FN> provide excellent quality, but are slower. A typical value is <FC>rfFastLinear<FN> which improves quality with negligible speed impact.
|
|
|
|
Notes:
|
|
- Unlike <A TImageEnMView.ThumbnailResampleFilter>, ThumbnailDisplayFilter is used every time the image needs to be displayed
|
|
- For black/white images <FC>rfFastLinear<FN> is always used.
|
|
|
|
Default: rfNone
|
|
|
|
<FM>Example<FC>
|
|
// Use high quality thumbnails
|
|
ImageEnMView1.ThumbnailDisplayFilter := rfLanczos3;
|
|
ImageEnMView1.Repaint;
|
|
!!}
|
|
property ThumbnailDisplayFilter: TResampleFilter read fThumbnailDisplayFilter write fThumbnailDisplayFilter;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.SelectedFontColor
|
|
|
|
<FM>Declaration<FC>
|
|
property SelectedFontColor: TColor;
|
|
|
|
<FM>Description<FN>
|
|
By default (when SelectedFontColor = clNone) the color of the text on both selected and unselected thumbnails is the same (as specified by <A TImageEnMView.ImageBottomText>, <A TImageEnMView.ImageInfoText> and <A TImageEnMView.ImageTopText>).
|
|
If you specify a color for SelectedFontColor it will be used for selected cells.
|
|
|
|
Note: This value may be overridden if <A TIEImageEnGlobalSettings.EnableTheming> is enabled.
|
|
|
|
Default: clNone
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.ThumbnailsBackgroundSelected>
|
|
!!}
|
|
property SelectedFontColor: TColor read fSelectedFontColor write fSelectedFontColor;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.MouseWheelParams
|
|
|
|
<FM>Declaration<FC>
|
|
property MouseWheelParams: <A TIEMouseWheelParams>;
|
|
|
|
<FM>Description<FN>
|
|
<FC>MouseWheelParams<FN> and <A TImageEnMView.MouseWheelParamsAlt> allow you to customize the behavior of the mouse wheel. <FC>MouseWheelParams<FN> is used to specify the default mouse wheel behaviour, whereas <A TImageEnMView.MouseWheelParamsAlt> is used when the Ctrl key is pressed.
|
|
|
|
<FM>Examples<FC>
|
|
// For iemwVScroll used with iemwPercentage, TImageEnMView assumes a theoretical grid of 12.5 thumbnails high
|
|
// So the default of 8% will scroll one thumbnail with each wheel click
|
|
// Whereas 16% would scroll the height of two thumbnails
|
|
ImageEnMView1.MouseWheelParams.Action := iemwVScroll;
|
|
ImageEnMView1.MouseWheelParams.Variation := iemwPercentage;
|
|
ImageEnMView1.MouseWheelParams.value := 4; // half a thumbnail
|
|
|
|
// Mouse wheel will navigate to the next or previous image
|
|
ImageEnMView1.MouseWheelParams.Action := iemwNavigate;
|
|
|
|
// Explorer like behavior. Mouse wheel scrolls the control and Ctrl + Mouse wheel changes the thumbnail view
|
|
ImageEnMView1.MouseWheelParams.Action := iemwVScroll;
|
|
ImageEnMView1.MouseWheelParamsAlt.Action := iemwZoomView;
|
|
|
|
<FM>Demo<FN>
|
|
<TABLE2>
|
|
<R> <C_IMG_DEMO> <C>Demos\Other\MouseWheel\MouseWheelParams.dpr </C> </R>
|
|
</TABLE>
|
|
!!}
|
|
property MouseWheelParams: TIEMouseWheelParams read fMouseWheelParams write SetMouseWheelParams;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.MouseWheelParamsAlt
|
|
|
|
<FM>Declaration<FC>
|
|
property MouseWheelParams: <A TIEMouseWheelParams>;
|
|
|
|
<FM>Description<FN>
|
|
<A TImageEnMView.MouseWheelParams> and <FC>MouseWheelParamsAlt<FN> allow you to customize the behavior of the mouse wheel. <A TImageEnMView.MouseWheelParams> is used to specify the default mouse wheel behaviour, whereas <FC>TImageEnMView.MouseWheelParamsAlt<FN> is used when the Ctrl key is pressed.
|
|
|
|
<FM>Examples<FC>
|
|
// Explorer like behavior. Mouse wheel scrolls the control and Ctrl + Mouse wheel changes the thumbnail view
|
|
ImageEnMView1.MouseWheelParams.Action := iemwVScroll;
|
|
ImageEnMView1.MouseWheelParamsAlt.Action := iemwZoomView;
|
|
|
|
<FM>Demo<FN>
|
|
<TABLE2>
|
|
<R> <C_IMG_DEMO> <C>\Other\MouseWheel\MouseWheelParams.dpr </C> </R>
|
|
</TABLE>
|
|
!!}
|
|
property MouseWheelParamsAlt: TIEMouseWheelParams read fMouseWheelParamsAlt write SetMouseWheelParamsAlt;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.BiDiMode
|
|
|
|
<FM>Declaration<FC>
|
|
property BiDiMode: TBiDiMode;
|
|
|
|
<FM>Description<FN>
|
|
Determine whether grid is filled left to right (bdLeftToRight) or right to left (bdRightToLeft).
|
|
|
|
Note: bdRightToLeftNoAlign and bdRightToLeftReadingOnly are treated as bdLeftToRight.
|
|
|
|
!!}
|
|
property BiDiMode;
|
|
property DragCursor;
|
|
property DragMode;
|
|
property Enabled;
|
|
property ParentShowHint;
|
|
property PopupMenu;
|
|
property ShowHint;
|
|
property Visible;
|
|
property TabOrder;
|
|
property TabStop;
|
|
property OnClick;
|
|
property OnDblClick;
|
|
property OnDragDrop;
|
|
property OnDragOver;
|
|
property OnEndDrag;
|
|
property OnMouseDown;
|
|
property OnMouseMove;
|
|
property OnMouseUp;
|
|
property OnStartDrag;
|
|
property OnKeyDown;
|
|
property OnKeyPress;
|
|
property OnKeyUp;
|
|
property OnContextPopup;
|
|
{$ifdef IEHASONGESTURE}
|
|
property OnGesture;
|
|
{$endif}
|
|
end;
|
|
|
|
function IEMDefaultTextToStr(DefaultText: TIEImageEnMViewDefaultText): string;
|
|
|
|
const
|
|
IEM_Path_Index_Delimiter = '::'; // Delimits a filename from its image index. See ImageFilename[]
|
|
|
|
// Possible consts for captions that are replaced at paint time
|
|
IEM_Filename = '$IEM_FILENAME$';
|
|
IEM_FilenameNoExt = '$IEM_FILENAMENOEXT$';
|
|
IEM_FilePath = '$IEM_FILEPATH$';
|
|
IEM_ImageDimensions = '$IEM_IMAGE_DIMENSIONS$';
|
|
IEM_ImageDimAndSize = '$IEM_IMAGE_DIM_AND_SIZE$';
|
|
IEM_FileSize = '$IEM_FILESIZE$';
|
|
IEM_FileCreateDate = '$IEM_FILECREATEDATE$';
|
|
IEM_FileCreateDateTime = '$IEM_FILECREATEDATETIME$';
|
|
IEM_FileCreateDateAndSize = '$IEM_FILECREATEDATE_AND_SIZE$';
|
|
IEM_FileEditDate = '$IEM_FILEEDITDATE$';
|
|
IEM_FileEditDateTime = '$IEM_FILEEDITDATETIME$';
|
|
IEM_FileEditDateAndSize = '$IEM_FILEEDITDATE_AND_SIZE$';
|
|
IEM_FileType = '$IEM_FILETYPE$';
|
|
IEM_FileExt = '$IEM_FILEEXT$';
|
|
IEM_ImageDict = '$IEM_IMAGEDICT$';
|
|
|
|
// a faux file item that adds a "My Computer" item
|
|
IEF_Drives_Folder = 'IEF_DRIVES_FOLDER';
|
|
|
|
Max_Icon_Images_To_Cache = 50; // How many icons should be cached in memory?
|
|
|
|
Thumbnail_Background_When_Disabled = cl3DLight;
|
|
Thumbnail_Border_When_Disabled = clBtnShadow;
|
|
Text_Color_When_Disabled = clGrayText;
|
|
|
|
|
|
implementation
|
|
|
|
uses
|
|
math,
|
|
{$IFDEF IEHASTHEMING}
|
|
Themes, uxTheme { For checkbox drawing },
|
|
{$ENDIF}
|
|
{$ifdef IEINCLUDEFLATSB}
|
|
flatsb,
|
|
{$endif}
|
|
{$ifdef IEUSEVCLZLIB}zlib, {$else}iezlib, {$endif}
|
|
{$ifdef IEVISION}
|
|
ievision,
|
|
{$endif}
|
|
{$IFDEF VIDEO_THUMBNAILS}
|
|
iexShellThumbnails,
|
|
{$ENDIF}
|
|
iexThemes, iegdiplus, bmpfilt, iesettings, ShellApi, iexCanvasUtils;
|
|
|
|
|
|
// Icons to show as "Default" (1000) and "Missing" (1001) files (PNG files stored as RT_RCDATA resources)
|
|
{$R imvres.res}
|
|
const
|
|
IMVRES_DEFAULT_IMAGE = 1000;
|
|
IMVRES_BROKEN_IMAGE = 1001;
|
|
|
|
|
|
{$R-}
|
|
|
|
const
|
|
CALCULATE_NOW = -13; // Delay calcuation of text heights requiring canvas until handle is created
|
|
|
|
|
|
{$IFDEF VIDEO_THUMBNAILS}
|
|
function OleInitialize(pwReserved: Pointer): HResult; stdcall; external 'ole32.dll' name 'OleInitialize';
|
|
procedure OleUninitialize; stdcall; external 'ole32.dll' name 'OleUninitialize';
|
|
{$ENDIF}
|
|
|
|
|
|
constructor TImageEnMView.Create(Owner: TComponent);
|
|
begin
|
|
fThreadCS := TCriticalSection.Create();
|
|
fBackBuffer := TIEBitmap.Create;
|
|
fBackBuffer.Location := ieTBitmap;
|
|
fImageEnMIO := nil;
|
|
fImageEnProc := nil;
|
|
inherited Create(Owner);
|
|
|
|
{$ifdef IEVISION}
|
|
if (csDesigning in ComponentState) then
|
|
begin
|
|
// design mode, unload ievision
|
|
IEFinalize_ievision();
|
|
end;
|
|
{$endif}
|
|
|
|
IEGDIPLoadLibrary();
|
|
fUpdating := false;
|
|
fMultiSelectedImages := TList.Create;
|
|
fDestroying := false;
|
|
fScrollBarsAlwaysVisible := false;
|
|
fRXScroll := 1;
|
|
fRYScroll := 1;
|
|
fHoverCheckLastIdx := -1;
|
|
fHoverCheckLastPos.X := -1;
|
|
fScrollBars := ssBoth;
|
|
Height := 90;
|
|
Width := 180;
|
|
fIEMBitmap := TIEMultiBitmap.Create( not ( csDesigning in ComponentState ));
|
|
fIEMBitmapIsExternal := False;
|
|
fIEMBitmap.fOwner := Self;
|
|
fIEMBitmap.OnUpdateParams := UpdateParams;
|
|
fStoreType := ietNormal;
|
|
fThumbWidth := 100;
|
|
fThumbHeight := 100;
|
|
fZoom := 100.0;
|
|
fHorizBorder := 4;
|
|
fVertBorder := 4;
|
|
fVWidth := 0;
|
|
fVHeight := 0;
|
|
fOnViewChange := nil;
|
|
fOnImageIDRequest := nil;
|
|
fOnImageIDRequestEx := nil;
|
|
fOnImageDraw := nil;
|
|
fOnImageDraw2 := nil;
|
|
fOnImageOut := nil;
|
|
fOnImageSelect := nil;
|
|
fOnImageAdd := nil;
|
|
fOnImageAdded := nil;
|
|
fOnImageLoaded := nil;
|
|
fOnImageDeselect := nil;
|
|
fOnSelectionChanging := nil;
|
|
fOnBeforeImageDrawEx := nil;
|
|
fOnDrawProgress := nil;
|
|
fOnWrongImage := nil;
|
|
fOnCreateImage := nil;
|
|
fOnDestroyImage := nil;
|
|
fOnCheckboxClick := nil;
|
|
fOnImageEnGesture := nil;
|
|
fHDrawDib := IEDrawDibOpen;
|
|
fImageEnIO := TImageEnIO.Create(self);
|
|
fSelectedItem := -1;
|
|
fVisibleSelection := true;
|
|
fSelectionBorderWidth := 2;
|
|
fSelectionBorderWidthNoFocus := -1;
|
|
fThumbnailsSelectedBorderColor := clExplorer_Selection_Border_Color;
|
|
fBottomGap := 0;
|
|
fUpperGap := 0;
|
|
fTopTextHeight := 0;
|
|
fInfoTextHeight := 0;
|
|
fBottomTextHeight := 0;
|
|
fSideGap := 0;
|
|
fTextMargin := 0;
|
|
fTextBlockWidth := -1;
|
|
fModernStyling := False;
|
|
fMouseInteract := [mmiSelect];
|
|
fKeyInteract := [mkiMoveSelected];
|
|
fDisplayMode := mdGrid;
|
|
fGridWidth := 0;
|
|
fCurrentGridWidth := 0;
|
|
fPlayTimer := 0;
|
|
fPlayLoop := true;
|
|
fLastImOp := IEM_OP_NONE;
|
|
fLastImIdx := 0;
|
|
fLastImP1 := 0;
|
|
fTimerInProgress := false;
|
|
fFrame := 0;
|
|
fLockPaint := 0;
|
|
fLockUpdate := 0;
|
|
fOnIOProgress := nil;
|
|
fOnImageAtPos := nil;
|
|
fDrawImageBackground := false;
|
|
fThumbnailResampleFilter := rfFastLinear;
|
|
fThumbnailDisplayFilter := rfNone;
|
|
fThumbnailClipping := 0;
|
|
fVScrollBarParams := TIEScrollBarParams.Create;
|
|
fHScrollBarParams := TIEScrollBarParams.Create;
|
|
fMouseWheelParams := TIEMouseWheelParams.Create( iemwVScroll );
|
|
fMouseWheelParamsAlt := TIEMouseWheelParams.Create( iemwZoom );
|
|
fCacheList := TIEVirtualImageList.Create('ICACHE', GetImageCacheUseDisk);
|
|
fIconList := TIECachedIconList.create(Self, Max_Icon_Images_To_Cache);
|
|
fTransition := TIETransitionEffects.Create( Self );
|
|
fTransitionEffect := iettNone;
|
|
fTransitionDuration := 1000;
|
|
fStyle := iemsACD;
|
|
fDoubleClicking := false;
|
|
fThumbnailsBackground := clBtnFace;
|
|
fThumbnailsBackgroundSelected := clBtnFace;
|
|
fMultiSelecting := false;
|
|
fEnableMultiSelect := false;
|
|
fSelectInclusive := false;
|
|
fMultiSelectionOptions := [];
|
|
fThumbnailsBorderWidth := 0;
|
|
fThumbnailsBorderColor := clBtnFace;
|
|
fThumbnailsBorderCurved := True;
|
|
fThumbnailsInternalBorderColor := clBlack;
|
|
fWallpaper := TPicture.Create;
|
|
fWallpaperStyle := iewoNormal;
|
|
fIconSize := ieicStretchHD;
|
|
fOnProgress := nil;
|
|
fOnBeforeImageDraw := nil;
|
|
fThreadPoolSize := 5;
|
|
fThreadPoolIO := TList.Create;
|
|
fThreadRequests := TList.Create;
|
|
fLookAheadList := TList.Create;
|
|
fThreadStarter := TIEStarter.Create;
|
|
fThreadStarter.mview := self;
|
|
fSelectImages := false;
|
|
fEnableImageCaching := true;
|
|
fHaveMultiselected := false;
|
|
fSoftShadow := TIEVSoftShadow.Create;
|
|
fEnableAlphaChannel := true;
|
|
fBackgroundStyle := iebsSolid;
|
|
fThumbnailsBackgroundStyle := iebsSolid;
|
|
fChessboardSize := 16;
|
|
fChessboardBrushStyle := bsSolid;
|
|
fChessboardColor2Customized := False;
|
|
fGradientEndColor := clBtnShadow;
|
|
fFillThumbnail := true;
|
|
fMDown := false;
|
|
fShowText := true;
|
|
fCurrentCompare := nil;
|
|
fCurrentCompareEx := nil;
|
|
fChangedSel := false;
|
|
fThumbsRounded := 0;
|
|
fFlatScrollBars := false;
|
|
fThumbnailFrame := nil;
|
|
fThumbnailFrameSelected := nil;
|
|
fThumbnailFrameRect := Rect(0, 0, 0, 0);
|
|
fDragging := false;
|
|
fEnableAdjustOrientation := false;
|
|
fMultiOnDemands := TList.Create;
|
|
fMaintainInvisibleImages := 15;
|
|
fLookAhead := 0;
|
|
fOnAllDisplayed := nil;
|
|
fAllDisplayed := false;
|
|
fUserAction := false;
|
|
fEnableLoadEXIFThumbnails := true;
|
|
fEnableLoadExplorerThumbnails:= False;
|
|
fOnFinishWork := nil;
|
|
fOnAcquireBitmap := nil;
|
|
fSelectedFontColor := clNone_;
|
|
fOnPlayFrame := nil;
|
|
fOnAnimationText := nil;
|
|
fOnAfterEvent := nil;
|
|
fBottomTextFont := TFont.Create;
|
|
fBottomTextFont.OnChange := BottomTextFontChange;
|
|
fTopTextFont := TFont.Create;
|
|
fTopTextFont.OnChange := TopTextFontChange;
|
|
fInfoTextFont := TFont.Create;
|
|
fInfoTextFont.OnChange := InfoTextFontChange;
|
|
fTextBackgroundStyle := bsClear;
|
|
fTextBackgroundColor := clBtnFace;
|
|
fTextTruncSide := iemtsLeft;
|
|
fAnimation := nil;
|
|
fAnimationDraggingSlider := false;
|
|
fAnimationTimer := TTimer.Create(self);
|
|
fLastMouseMoveX := -1;
|
|
fLastMouseMoveY := -1;
|
|
fTrackMouseSelection := false;
|
|
fDrawMouseSelection := false;
|
|
fCheckThumbBoundsOnSelect := false;
|
|
fSelectedImageAlwaysVisible := True;
|
|
fThumbnailOptionsEx := [ietxShowIconForUnknownFormat, ietxShowIconWhileLoading, ietxEnableInternalIcons, ietxStretchSmallImages];
|
|
fIOOptionsEx := [];
|
|
fCheckboxes := iecbNone;
|
|
fCheckedCount := -1;
|
|
fCheckedBitmap := nil;
|
|
fUncheckedBitmap := nil;
|
|
fMissingFileIcon := nil;
|
|
fDefaultFileIcon := nil;
|
|
fAnnotationsVisible := False;
|
|
fCheckboxPos := iecpTopLeft;
|
|
fCheckboxMargins := Point(4, 4);
|
|
fTextColumnWidths[ iemtpTop ] := -1;
|
|
fTextColumnWidths[ iemtpBottom ] := -1;
|
|
fTextColumnWidths[ iemtpInfo ] := -1;
|
|
fResizingTextColIdx := -1;
|
|
fResizingTextColClickX := -1;
|
|
fShowThumbnailHint := False;
|
|
|
|
fDefaultTopText := iedtNone;
|
|
fDefaultInfoText := iedtNone;
|
|
fDefaultBottomText := iedtNone;
|
|
if ClassName = 'TImageEnFolderMView' then
|
|
begin
|
|
fDefaultBottomText := iedtFilename;
|
|
fBottomTextHeight := CALCULATE_NOW;
|
|
end;
|
|
|
|
fGestures := TIEMViewerGestures.Create();
|
|
fImageCacheReusage := iecrNone;
|
|
end;
|
|
|
|
procedure TImageEnMView.ClearThreadsAndRequests;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
fThreadCS.Enter();
|
|
try
|
|
fLookAheadList.Clear;
|
|
fThreadRequests.Clear;
|
|
for i := 0 to fThreadPoolIO.Count - 1 do
|
|
if TImageEnIO(fThreadPoolIO[i]).Tag > -1 then
|
|
begin
|
|
TImageEnIO(fThreadPoolIO[i]).Tag := -2;
|
|
TImageEnIO(fThreadPoolIO[i]).Aborting := true;
|
|
end;
|
|
finally
|
|
fThreadCS.Leave();
|
|
end;
|
|
// wait up to 1 second
|
|
for i := 1 to 10 do
|
|
if fThreadPoolIO.Count > 0 then
|
|
sleep(100);
|
|
end;
|
|
|
|
procedure TImageEnMView.AbortImageLoading(idx: Integer);
|
|
var
|
|
i: Integer;
|
|
begin
|
|
if assigned(fThreadRequests) and assigned(fLookAheadList) and assigned(fThreadPoolIO) then
|
|
begin
|
|
fThreadCS.Enter();
|
|
try
|
|
fThreadRequests.Remove(pointer(idx));
|
|
fLookAheadList.Remove(pointer(idx));
|
|
for i := 0 to fThreadPoolIO.Count - 1 do
|
|
if TImageEnIO(fThreadPoolIO[i]).Tag = idx then
|
|
begin
|
|
TImageEnIO(fThreadPoolIO[i]).Tag := -2;
|
|
TImageEnIO(fThreadPoolIO[i]).Aborting := true;
|
|
break;
|
|
end;
|
|
finally
|
|
fThreadCS.Leave();
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
// note: the timer object is not destroyed because the win32 should destroy it.
|
|
destructor TImageEnMView.Destroy;
|
|
var
|
|
toDestroy: TIEBitmap;
|
|
begin
|
|
fDestroying := true;
|
|
|
|
// Disconnect any attached IEMBitmap
|
|
SetExternalMBitmap( nil );
|
|
|
|
DeselectNU;
|
|
|
|
fThreadStarter.Terminate;
|
|
Windows.SetEvent(fThreadStarter.resumeEvent);
|
|
fThreadStarter.WaitFor();
|
|
|
|
// threads
|
|
ClearThreadsAndRequests;
|
|
while fThreadPoolIO.Count > 0 do
|
|
begin
|
|
toDestroy := TImageEnIO(fThreadPoolIO[0]).IEBitmap;
|
|
TImageEnIO(fThreadPoolIO[0]).free;
|
|
fThreadPoolIO[0] := nil;
|
|
FreeAndNil(toDestroy);
|
|
fThreadPoolIO.Delete(0);
|
|
end;
|
|
|
|
FreeAndNil(fThreadStarter);
|
|
FreeAndNil(fThreadRequests);
|
|
FreeAndNil(fThreadPoolIO);
|
|
//
|
|
ClearOnDemandIOList;
|
|
FreeAndNil(fMultiOnDemands);
|
|
//
|
|
if assigned(fImageEnMIO) then
|
|
FreeAndNil(fImageEnMIO);
|
|
if assigned(fImageEnProc) then
|
|
FreeAndNil(fImageEnProc);
|
|
// remove all objects
|
|
DeleteAllImages();
|
|
//
|
|
FreeAndNil(fWallpaper);
|
|
FreeAndNil(fTransition);
|
|
Deselect;
|
|
FreeAndNil(fCacheList);
|
|
FreeAndNil(fIconList);
|
|
FreeAndNil(fIEMBitmap);
|
|
IEDrawDibClose(fHDrawDib);
|
|
FreeAndNil(fImageEnIO);
|
|
FreeAndNil(fMultiSelectedImages);
|
|
if assigned(fThumbnailFrame) then
|
|
FreeAndNil(fThumbnailFrame);
|
|
if assigned(fThumbnailFrameSelected) then
|
|
FreeAndNil(fThumbnailFrameSelected);
|
|
//
|
|
if assigned(fDragScrollTimer) then
|
|
FreeAndNil(fDragScrollTimer);
|
|
|
|
FreeAndNil(fVScrollBarParams);
|
|
FreeAndNil(fHScrollBarParams);
|
|
FreeAndNil(fMouseWheelParams);
|
|
FreeAndNil(fMouseWheelParamsAlt);
|
|
FreeAndNil(fSoftShadow);
|
|
FreeAndNil(fLookAheadlist);
|
|
FreeAndNil(fBottomTextFont);
|
|
FreeAndNil(fTopTextFont);
|
|
FreeAndNil(fInfoTextFont);
|
|
|
|
FreeAndNil(fCheckedBitmap);
|
|
FreeAndNil(fUncheckedBitmap);
|
|
|
|
FreeAndNil(fMissingFileIcon);
|
|
FreeAndNil(fDefaultFileIcon);
|
|
|
|
FreeAndNil(fGestures);
|
|
|
|
FreeAndNil(fAnimationTimer);
|
|
if assigned(fAnimation) then
|
|
FreeAndNil(fAnimation);
|
|
|
|
FreeAndNil(fBackBuffer);
|
|
FreeAndNil(fThreadCS);
|
|
|
|
IEGDIPUnLoadLibrary();
|
|
|
|
inherited;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ScrollBars
|
|
|
|
<FM>Declaration<FC>
|
|
property ScrollBars: TScrollType;
|
|
|
|
<FM>Description<FN>
|
|
Specifies whether the TImageEnView control displays scroll bars.
|
|
|
|
Note: Scrollbars are never displayed if they are not required (unless <A TImageEnMView.ScrollBarsAlwaysVisible> is set to true)
|
|
|
|
<TABLE>
|
|
<R> <H>Value</H> <H>Description</H> </R>
|
|
<R> <C><FC>ssNone<FN></C> <C>No scroll bars are shown</C> </R>
|
|
<R> <C><FC>ssHorizontal<FN></C> <C>A single scroll bar is shown along the bottom edge when needed</C> </R>
|
|
<R> <C><FC>ssVertical<FN></C> <C>A single scroll bar is shown along the right edge when needed</C> </R>
|
|
<R> <C><FC>ssBoth<FN></C> <C>Scroll bars are shown on both the bottom and right edges when needed</C> </R>
|
|
</TABLE>
|
|
!!}
|
|
procedure TImageEnMView.SetScrollBars(v: TIEScrollStyle);
|
|
begin
|
|
fScrollBars := v;
|
|
if ((GetParentForm(self) = nil) and (ParentWindow = 0)) or (not HandleAllocated) then
|
|
exit;
|
|
if (fScrollBars <> ssVertical) and (fScrollBars <> ssBoth) then
|
|
IEShowScrollBar(handle, SB_VERT, false, fFlatScrollBars);
|
|
if (fScrollBars <> ssHorizontal) and (fScrollBars <> ssBoth) then
|
|
IEShowScrollBar(handle, SB_HORZ, false, fFlatScrollBars);
|
|
UpdateEx(false);
|
|
end;
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.StoreType
|
|
|
|
<FM>Declaration<FC>
|
|
property StoreType: <A TIEStoreType>;
|
|
|
|
<FM>Description<FN>
|
|
Specifies how image used by the TImageEnMView component are stored in memory (as full size images or thumbnails at their display size)
|
|
!!}
|
|
procedure TImageEnMView.SetStoreType(v : TIEStoreType);
|
|
begin
|
|
fStoreType := v;
|
|
if fStoreType = ietFastThumb then
|
|
begin
|
|
fEnableImageCaching := True;
|
|
if fThumbnailDisplayFilter = rfNone then
|
|
fThumbnailDisplayFilter := rfFastLinear;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
procedure TImageEnMView.WMSize(var Message: TWMSize);
|
|
begin
|
|
inherited;
|
|
UpdateEx(false);
|
|
end;
|
|
|
|
|
|
procedure TImageEnMView.IEMAutoScroll(var Message: TMessage);
|
|
var
|
|
iX, iY: integer;
|
|
begin
|
|
try
|
|
if HiByte(GetAsyncKeyState(VK_LBUTTON)) <> 0 then
|
|
begin
|
|
// Mouse still down
|
|
iX := ScreenToClient(Mouse.CursorPos).X;
|
|
iY := ScreenToClient(Mouse.CursorPos).Y;
|
|
MouseMove([], iX, iY);
|
|
end;
|
|
except
|
|
// Unexpected mouse error
|
|
end;
|
|
end;
|
|
|
|
procedure TImageEnMView.WMEraseBkgnd(var Message: TMessage);
|
|
begin
|
|
Message.Result := 0;
|
|
end;
|
|
|
|
procedure TImageEnMView.WMMouseWheel(var Message: TMessage);
|
|
var
|
|
zDelta, nPos: integer;
|
|
dir: integer;
|
|
Params: TIEMouseWheelParams;
|
|
begin
|
|
inherited;
|
|
|
|
// Ctrl key pressed?
|
|
if GetKeyState( VK_CONTROL) < 0 then
|
|
Params := fMouseWheelParamsAlt
|
|
else
|
|
Params := fMouseWheelParams;
|
|
|
|
if Params.Action = iemwNone then
|
|
exit;
|
|
|
|
fUserAction := true;
|
|
try
|
|
zDelta := smallint($FFFF and (Message.wParam shr 16));
|
|
if zDelta > 0 then
|
|
dir := -1
|
|
else
|
|
dir := 1;
|
|
if Params.InvertDirection then
|
|
dir := -1 * dir;
|
|
|
|
case Params.Action of
|
|
iemwVScroll:
|
|
begin
|
|
case Params.Variation of
|
|
iemwAbsolute: // pixel based
|
|
if fCurrentGridWidth = 0 then
|
|
begin
|
|
// horizontal
|
|
nPos := fViewX + dir * Params.Value;
|
|
SetViewX(nPos);
|
|
end
|
|
else
|
|
begin
|
|
// vertical
|
|
nPos := fViewY + dir * Params.Value;
|
|
SetViewY(nPos);
|
|
end;
|
|
iemwPercentage: // thumbnail based
|
|
|
|
// NOTE: DEFAULT VALUE OF Params is Value=8/Variation=iemwPercentage
|
|
// For compatibility with TImageEnView and previous versions of TImageEnMView
|
|
// We will work on a theoretical grid of 12.5 thumbnails high, so "8% of window"
|
|
// will always equate to one thumbnail height regardless of thumbnail size
|
|
|
|
if fCurrentGridWidth = 0 then
|
|
begin
|
|
// Horizontal scroll
|
|
nPos := fViewX + dir * Trunc( ThumbSizeInfo( itsOuter ).X / 8 * Params.Value );
|
|
SetViewX(nPos);
|
|
end
|
|
else
|
|
begin
|
|
// Vertical scroll
|
|
nPos := fViewY + dir * Trunc( ThumbSizeInfo( itsOuter ).Y / 8 * Params.Value );
|
|
SetViewY(nPos);
|
|
end;
|
|
end;
|
|
ViewChange(0);
|
|
end;
|
|
iemwZoom:
|
|
begin
|
|
case Params.Variation of
|
|
iemwAbsolute:
|
|
Zoom := fZoom + dir * Params.Value;
|
|
iemwPercentage:
|
|
Zoom := fZoom + imax(round(fZoom * Params.Value / 100), 1) * dir;
|
|
end;
|
|
end;
|
|
iemwZoomView: SetStyleInt( GetStyleInt - dir );
|
|
iemwNavigate:
|
|
begin
|
|
if dir < 0 then
|
|
Seek(ieioSeekPrior)
|
|
else
|
|
Seek(ieioSeekNext);
|
|
end;
|
|
end;
|
|
|
|
finally // user action in ViewChange could raise exceptions
|
|
fUserAction := false;
|
|
end;
|
|
end;
|
|
|
|
procedure TImageEnMView.WMVScroll(var Message: TMessage);
|
|
var
|
|
nPos: integer;
|
|
mx, my: integer;
|
|
begin
|
|
inherited;
|
|
fUserAction := true;
|
|
try
|
|
case Message.WParamLo of
|
|
SB_THUMBPOSITION, SB_THUMBTRACK:
|
|
begin
|
|
if (not fVScrollBarParams.Tracking) and (Message.WParamLo = SB_THUMBTRACK) then
|
|
exit;
|
|
nPos := trunc(Message.WParamHi * fRYScroll);
|
|
end;
|
|
SB_BOTTOM:
|
|
begin
|
|
GetMaxViewXY(mx, my);
|
|
nPos := my;
|
|
end;
|
|
SB_TOP:
|
|
nPos := 0;
|
|
SB_LINEDOWN:
|
|
if fVScrollBarParams.LineStep = -1 then
|
|
nPos := fViewY + ThumbSizeInfo( itsOuter ).Y
|
|
else
|
|
nPos := fViewY + fVScrollBarParams.LineStep;
|
|
SB_LINEUP:
|
|
if fVScrollBarParams.LineStep = -1 then
|
|
nPos := fViewY - ThumbSizeInfo( itsCell ).Y - fVertBorder
|
|
else
|
|
nPos := fViewY - fVScrollBarParams.LineStep;
|
|
SB_PAGEDOWN:
|
|
if fVScrollBarParams.PageStep = -1 then
|
|
nPos := fViewY + ClientHeight
|
|
else
|
|
nPos := fViewY + fVScrollBarParams.PageStep;
|
|
SB_PAGEUP:
|
|
if fVScrollBarParams.PageStep = -1 then
|
|
nPos := fViewY - ClientHeight
|
|
else
|
|
nPos := fViewY - fVScrollBarParams.PageStep;
|
|
else
|
|
nPos := fViewY;
|
|
end;
|
|
SetViewY(nPos);
|
|
ViewChange(0);
|
|
finally
|
|
fUserAction := false;
|
|
end;
|
|
end;
|
|
|
|
procedure TImageEnMView.WMHScroll(var Message: TMessage);
|
|
var
|
|
nPos: integer;
|
|
mx, my: integer;
|
|
begin
|
|
inherited;
|
|
fUserAction := true;
|
|
try
|
|
case Message.WParamLo of
|
|
SB_THUMBPOSITION, SB_THUMBTRACK:
|
|
begin
|
|
if (not fHScrollBarParams.Tracking) and (Message.WParamLo = SB_THUMBTRACK) then
|
|
exit;
|
|
nPos := trunc(Message.WParamHi * fRXScroll);
|
|
end;
|
|
SB_BOTTOM:
|
|
begin
|
|
GetMaxViewXY(mx, my);
|
|
nPos := mx;
|
|
end;
|
|
SB_TOP:
|
|
nPos := 0;
|
|
SB_LINEDOWN:
|
|
if fHScrollBarParams.LineStep = -1 then
|
|
nPos := fViewX + ThumbSizeInfo( itsOuter ).X
|
|
else
|
|
nPos := fViewX + fVScrollBarParams.LineStep;
|
|
SB_LINEUP:
|
|
if fVScrollBarParams.LineStep = -1 then
|
|
nPos := fViewX - ThumbSizeInfo( itsCell ).X - fHorizBorder
|
|
else
|
|
nPos := fViewX - fVScrollBarParams.LineStep;
|
|
SB_PAGEDOWN:
|
|
if fHScrollBarParams.PageStep = -1 then
|
|
nPos := fViewX + ClientWidth
|
|
else
|
|
nPos := fViewX + fVScrollBarParams.PageStep;
|
|
SB_PAGEUP:
|
|
if fVScrollBarParams.PageStep = -1 then
|
|
nPos := fViewX - ClientWidth
|
|
else
|
|
nPos := fViewX - fVScrollBarParams.PageStep;
|
|
else
|
|
nPos := fViewX;
|
|
end;
|
|
SetViewX(nPos);
|
|
ViewChange(0);
|
|
finally
|
|
fUserAction := false;
|
|
end;
|
|
end;
|
|
|
|
Procedure _SetLoadParams(MView : TImageEnMView; Params : TIOParams);
|
|
const
|
|
SMALLEST_RAW_IMAGE_WIDTH = 1800;
|
|
SMALLEST_RAW_IMAGE_HEIGHT = 1400;
|
|
Quality_Scaler = 3; // Improve quality of thumbnails when resampled
|
|
var
|
|
iMaxX, iMaxY : Integer;
|
|
begin
|
|
if mview.fStoreType in [ietThumb, ietFastThumb] then
|
|
begin
|
|
Params.JPEG_Scale := IOJPEG_AUTOCALC;
|
|
Params.JPEG_GetExifThumbnail := ( mview.ThumbSizeInfo( itsImage ).X <= 200 ) and (mview.ThumbSizeInfo( itsImage ).Y <= 200) and mview.fEnableLoadEXIFThumbnails;
|
|
Params.JPEG_DCTMethod := ioJPEG_IFAST;
|
|
|
|
iMaxX := MulDiv( mview.ThumbSizeInfo( itsImage ).X, 100 + mView.ThumbnailClipping, 100 );
|
|
iMaxY := MulDiv( mview.ThumbSizeInfo( itsImage ).Y, 100 + mView.ThumbnailClipping, 100 );
|
|
|
|
if mview.fStoreType = ietFastThumb then
|
|
begin
|
|
iMaxX := iMaxX * Quality_Scaler;
|
|
iMaxY := iMaxY * Quality_Scaler;
|
|
end;
|
|
|
|
Params.Width := iMaxX;
|
|
Params.Height := iMaxY;
|
|
{$ifdef IEINCLUDERAWFORMATS}
|
|
Params.RAW_GetExifThumbnail := mview.fEnableLoadEXIFThumbnails and ( mview.ThumbSizeInfo( itsImage ).X <= 200 ) and (mview.ThumbSizeInfo( itsImage ).Y <= 200);
|
|
Params.RAW_HalfSize := ( mview.ThumbSizeInfo( itsImage ).X <= SMALLEST_RAW_IMAGE_WIDTH ) and ( mview.ThumbSizeInfo( itsImage ).Y <= SMALLEST_RAW_IMAGE_HEIGHT );
|
|
{$endif}
|
|
Params.IEN_GetThumbnail := ( mview.ThumbSizeInfo( itsImage ).X <= IEGlobalSettings().ThumbnailSize ) and ( mview.ThumbSizeInfo( itsImage ).Y <= IEGlobalSettings().ThumbnailSize );
|
|
end
|
|
else
|
|
Params.JPEG_Scale := IOJPEG_FULLSIZE;
|
|
Params.EnableAdjustOrientation := mview.fEnableAdjustOrientation;
|
|
end;
|
|
|
|
|
|
// frees some I/O parameters when loading thumbnails
|
|
procedure StripOffIOParams(MView: TImageEnMView; Params: TIOParams);
|
|
begin
|
|
if mview.fStoreType in [ietThumb, ietFastThumb] then
|
|
begin
|
|
Params.TIFF_PhotoshopImageResources := nil;
|
|
Params.TIFF_PhotoshopImageSourceData := nil;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
// double click
|
|
procedure TImageEnMView.WMLButtonDblClk(var Message: TWMLButtonDblClk);
|
|
begin
|
|
fDoubleClicking := true;
|
|
inherited;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.Assign
|
|
|
|
<FM>Declaration<FC>
|
|
procedure Assign(Source: TPersistent);
|
|
|
|
<FM>Description<FN>
|
|
Replace the existing content with the frames in TImageEnMView, <A TIEMultiBitmap>, <A TIEBitmap>, TBitmap or TImageList.
|
|
|
|
Notes:
|
|
- <L TIOParams>Params</L> are NOT copied. See <A TImageEnMView.AssignEx>
|
|
Cannot be used if a <A TIEDBMultiBitmap> is <L TImageEnMView.SetExternalMBitmap>attached to the control</L>
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.AssignEx>
|
|
- <A TIEMultiBitmap.Assign>
|
|
!!}
|
|
procedure TImageEnMView.Assign(Source: TPersistent);
|
|
begin
|
|
AssignEx( Source );
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.AssignEx
|
|
|
|
<FM>Declaration<FC>
|
|
procedure AssignEx(Source: TObject; bCopyParams: Boolean = False);
|
|
|
|
<FM>Description<FN>
|
|
Replace the existing content with the frames in TImageEnMView, <A TIEMultiBitmap>, <A TIEBitmap>, TBitmap or TImageList.
|
|
if bCopyParams is true then <L TIOParams>Params</L> are also copied.
|
|
|
|
Note: Cannot be used if a <A TIEDBMultiBitmap> is <L TImageEnMView.SetExternalMBitmap>attached to the control</L>
|
|
!!}
|
|
procedure TImageEnMView.AssignEx(Source: TObject; bCopyParams: Boolean = False);
|
|
begin
|
|
if IEMBitmap_IsTIEDBMultiBitmap then
|
|
raise EIEException.create('Cannot assign to a TIEDBMultiBitmap');
|
|
|
|
TIEMultiBitmap( fIEMBitmap ).Assign( Source );
|
|
|
|
if bCopyParams and ( Source is TIECustomMultiBitmap ) and TIECustomMultiBitmap( Source ).ParamsEnabled then
|
|
MIO.fParamsList.Assign( TIECustomMultiBitmap( Source ).ParamsList )
|
|
else
|
|
if bCopyParams and ( Source is TIEBitmap ) and TIEBitmap( Source ).ParamsEnabled then
|
|
MIO.Params[ 0 ].Assign( TIEBitmap( Source ).Params )
|
|
else
|
|
if bCopyParams and ( Source is TImageEnMView ) then
|
|
MIO.fParamsList.Assign( TImageEnMView( Source ).MIO.ParamsList );
|
|
|
|
Update;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.AssignLayers
|
|
|
|
<FM>Declaration<FC>
|
|
procedure TImageEnMView.AssignLayers(Source: <A TImageEnView>; HighlightSel: Boolean; DoClear: Boolean = True);
|
|
|
|
<FM>Description<FN>
|
|
Fill content with the layers of a TImageEnView.
|
|
If <FC>HighlightSel<FN> is true, the selected layers will be also be shown as selected in this TImageEnMView.
|
|
Set <FC>DoClear<FN> to true if you don't wish to clear the existing content.
|
|
|
|
<AC><IMG help_images\Layers.jpg><AL>
|
|
|
|
<FM>Example<FC>
|
|
// Show layer content of a TImageEnView in a TImageEnMView. Allow selection of layers via the TImageEnMView
|
|
// For more info, see the demo: \Demos\ImageEditing\Layers\Layers.dpr
|
|
|
|
procedure Tfmain.ImageEnMView1ImageSelect(Sender: TObject; idx: Integer);
|
|
begin
|
|
ImageEnView1.LayersCurrent := idx;
|
|
end;
|
|
|
|
procedure Tfmain.ImageEnMView1ImageDeselect(Sender: TObject; idx: Integer);
|
|
begin
|
|
ImageEnView1.Layers[ idx ].Selected := False;
|
|
end;
|
|
|
|
procedure Tfmain.ImageEnView1LayerNotify(Sender: TObject; layer: Integer; event: TIELayerEvent);
|
|
begin
|
|
if event in [ ielSelected, ielDeselected, ielMoved, ielResized, ielRotated, ielCreated, ielAction ] then
|
|
RefreshLayerViewer();
|
|
end;
|
|
|
|
procedure Tfmain.LayerControlChange(Sender: TObject);
|
|
begin
|
|
RefreshLayerViewer();
|
|
end;
|
|
|
|
procedure Tfmain.ImageEnView1NewLayer(Sender: TObject; LayerIdx: Integer; LayerKind: TIELayerKind);
|
|
begin
|
|
RefreshLayerViewer();
|
|
end;
|
|
|
|
procedure Tfmain.RefreshLayerViewer();
|
|
begin
|
|
ImageEnMView1.AssignLayers( ImageEnView1, True );
|
|
end;
|
|
!!}
|
|
// Fill ImageEnMView1 with all layers of ImageEnView1
|
|
procedure TImageEnMView.AssignLayers(Source: TImageEnView; HighlightSel: Boolean; DoClear: Boolean = True);
|
|
var
|
|
bmp: TIEBitmap;
|
|
i, idx, offsetIndex: integer;
|
|
begin
|
|
bmp := TIEBitmap.create;
|
|
LockUpdate();
|
|
try
|
|
|
|
if DoClear then
|
|
Clear;
|
|
offsetIndex := ImageCount;
|
|
|
|
for i := 0 to Source.LayersCount - 1 do
|
|
begin
|
|
if StoreType = ietNormal then
|
|
Source.Layers[i].CopyToBitmap( bmp, -1, -1 )
|
|
else
|
|
Source.Layers[i].CopyToBitmap( bmp, ThumbSizeInfo( itsImage ).X, ThumbSizeInfo( itsImage ).Y );
|
|
idx := AppendImage( bmp );
|
|
if Source.Layers[i].Name = '' then
|
|
ImageTopText[ idx ] := 'Layer ' + inttostr( i + 1 )
|
|
else
|
|
ImageTopText[ idx ] := Source.Layers[i].Name;
|
|
end;
|
|
|
|
// Mark selected layers and highlight the current layer
|
|
if HighlightSel then
|
|
begin
|
|
BeginSelectImages;
|
|
for i := 0 to Source.LayersCount - 1 do
|
|
if Source.Layers[ i ].Selected then
|
|
SelectedImage := offsetIndex + i;
|
|
SelectedImage := offsetIndex + Source.LayersCurrent; // Make it the active image
|
|
EndSelectImages;
|
|
end;
|
|
|
|
finally
|
|
UnlockUpdate();
|
|
bmp.Free();
|
|
end;
|
|
end;
|
|
|
|
procedure TImageEnMView.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
|
|
begin
|
|
inherited;
|
|
end;
|
|
|
|
procedure TImageEnMView.GetMaxViewXY(var mx, my: integer);
|
|
begin
|
|
mx := imax(fVWidth - ClientWidth, 0);
|
|
my := imax(fVHeight - ClientHeight, 0);
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ViewX
|
|
|
|
<FM>Declaration<FC>
|
|
property ViewX: integer;
|
|
|
|
<FM>Description<FN>
|
|
ViewX is the first column visible at the top-left corner of the control, in pixels (for example, if the user has scrolled horizontally by two columns then it will return 2 * <A TImageEnMView.ThumbWidth>). It is only relevant when <A TImageEnMView.GridWidth> has a value greater than zero (otherwise it always returns 0).
|
|
|
|
You can set ViewX to simulate horizontal scrollbar movement.
|
|
|
|
See also: <A TImageEnMView.ViewY>.
|
|
!!}
|
|
procedure TImageEnMView.SetViewX(v: integer);
|
|
var
|
|
max_x, max_y: integer;
|
|
begin
|
|
if v = fViewX then
|
|
exit;
|
|
GetMaxViewXY(max_x, max_y);
|
|
fViewX := ilimit(v, 0, max_x);
|
|
invalidate;
|
|
if (fScrollBars = ssHorizontal) or (fScrollBars = ssBoth) then
|
|
IESetScrollPos(Handle, SB_HORZ, trunc(fViewX / fRXScroll), true, fFlatScrollBars);
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ViewY
|
|
|
|
<FM>Declaration<FC>
|
|
property ViewY: integer;
|
|
|
|
<FM>Description<FN>
|
|
ViewY is the first row visible at the top-left corner of the control, in pixels (for example, if the user has scrolled vertically by two rows then it will return 2 * <A TImageEnMView.ThumbHeight>). It is not relevant if <A TImageEnMView.GridWidth> = 0 (in which case it always returns 0).
|
|
|
|
You can set ViewY to simulate vertical scrollbar movement.
|
|
|
|
See also: <A TImageEnMView.ViewX>.
|
|
!!}
|
|
procedure TImageEnMView.SetViewY(v: integer);
|
|
var
|
|
max_x, max_y: integer;
|
|
begin
|
|
if v = fViewY then
|
|
exit;
|
|
GetMaxViewXY(max_x, max_y);
|
|
fViewY := ilimit(v, 0, max_y);
|
|
invalidate;
|
|
if (fScrollBars = ssVertical) or (fScrollBars = ssBoth) then
|
|
IESetScrollPos(Handle, SB_VERT, trunc(fViewY / fRYScroll), true, fFlatScrollBars);
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.SetViewXY
|
|
|
|
<FM>Declaration<FC>
|
|
procedure SetViewXY(x, y: integer);
|
|
|
|
<FM>Description<FN>
|
|
Sets <A TImageEnMView.ViewX> and <A TImageEnMView.ViewY> simultaneously.
|
|
!!}
|
|
procedure TImageEnMView.SetViewXY(x, y: integer);
|
|
var
|
|
max_x, max_y: integer;
|
|
begin
|
|
if Parent = nil then
|
|
exit;
|
|
if (x = fViewX) and (y = fViewY) then
|
|
exit;
|
|
GetMaxViewXY(max_x, max_y);
|
|
fViewX := ilimit(x, 0, max_x);
|
|
fViewY := ilimit(y, 0, max_y);
|
|
invalidate;
|
|
if (fScrollBars = ssHorizontal) or (fScrollBars = ssBoth) then
|
|
IESetScrollPos(Handle, SB_HORZ, trunc(fViewX / fRXScroll), true, fFlatScrollBars);
|
|
if (fScrollBars = ssVertical) or (fScrollBars = ssBoth) then
|
|
IESetScrollPos(Handle, SB_VERT, trunc(fViewY / fRYScroll), true, fFlatScrollBars);
|
|
end;
|
|
|
|
procedure TImageEnMView.PaintToCanvas(DestCanvas: TCanvas);
|
|
var
|
|
iStartX, iStartY: integer;
|
|
begin
|
|
if fLockPaint = 0 then
|
|
begin
|
|
if (not HandleAllocated) or (ClientWidth=0) or (ClientHeight=0) then // 3.0.0
|
|
exit;
|
|
if (fBackBuffer.Width <> ClientWidth) or (fBackBuffer.Height <> ClientHeight) then
|
|
fBackBuffer.Allocate(ClientWidth, ClientHeight, ie24RGB);
|
|
|
|
if fLockUpdate = 0 then
|
|
begin
|
|
if assigned(fAnimation) then
|
|
AnimPaintTo(fBackBuffer)
|
|
else
|
|
begin
|
|
PaintTo(fBackBuffer.VclBitmap);
|
|
if fTrackMouseSelection and fDrawMouseSelection then
|
|
with TIECanvas.Create(fBackBuffer.Canvas) do
|
|
begin
|
|
Brush.Color := $85664F;
|
|
Brush.Style := bsSolid;
|
|
Brush.Transparency := 128;
|
|
Pen.Color := Brush.Color;
|
|
Pen.Width := 1;
|
|
Pen.Style := psSolid;
|
|
Pen.Transparency := 255;
|
|
iStartX := fHSVX1 + fHSX1 - ViewX;
|
|
iStartY := fHSVY1 + fHSY1 - ViewY;
|
|
Rectangle(iStartX, iStartY, fLastMouseMoveX, fLastMouseMoveY);
|
|
Free();
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
if (IEGlobalSettings().SystemColors < 24) and not IEGlobalSettings().IsRemoteSession then
|
|
begin
|
|
// dithering needed (for example display with 16bit depth need dithering)
|
|
SetStretchBltMode(DestCanvas.Handle, HALFTONE);
|
|
StretchBlt(DestCanvas.Handle, 0, 0, fBackBuffer.Width, fBackBuffer.Height, fBackBuffer.Canvas.Handle, 0, 0, fBackBuffer.Width, fBackBuffer.Height, SRCCOPY);
|
|
end
|
|
else
|
|
begin
|
|
// no dithering needed (fastest way)
|
|
BitBlt(DestCanvas.handle, 0, 0, fBackBuffer.Width, fBackBuffer.Height, fBackBuffer.Canvas.Handle, 0, 0, SRCCOPY);
|
|
end;
|
|
|
|
end;
|
|
end;
|
|
|
|
procedure TImageEnMView.Paint;
|
|
begin
|
|
PaintToCanvas(Canvas);
|
|
DoAfterEvent(ieaePaint);
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ImageWidth
|
|
|
|
<FM>Declaration<FC>
|
|
property ImageWidth[idx: Integer]: Integer;
|
|
|
|
<FM>Description<FN>
|
|
ImageWidth and <A TImageEnMView.ImageHeight> return the dimensions of the image, <FC>idx<FN>.
|
|
|
|
Note: If images are being loaded on demand, then the image dimensions will not be valid until the image is loaded. Either use the <A TImageEnMView.OnImageLoaded> to delay until the image is ready, or force loading of the image by using <A TImageEnMView.EnsureImageLoaded>
|
|
|
|
<FM>Example<FC>
|
|
// Display the image size below the thumbnail
|
|
// Ensure you have set the BottomGap property
|
|
procedure TForm1.ImageEnMView1ImageDraw(Sender: TObject; idx: Integer; Left, Top: Integer; Canvas: TCanvas);
|
|
begin
|
|
Canvas.Font.Height := 15;
|
|
Canvas.Font.Color := clWhite;
|
|
Canvas.TextOut(Left,
|
|
Top + imageenmview1.ThumbHeight - imageenmview1.bottomgap + 2,
|
|
IntToStr(imageenmview1.ImageWidth[idx]) + 'x' + IntToStr(imageenmview1.ImageHeight[idx]));
|
|
end;
|
|
!!}
|
|
function TImageEnMView.GetImageWidth(idx: integer): integer;
|
|
begin
|
|
result := fIEMBitmap.ImageWidth[ idx ];
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ImageHeight
|
|
|
|
<FM>Declaration<FC>
|
|
property ImageHeight[idx: Integer]: Integer;
|
|
|
|
<FM>Description<FN>
|
|
<A TImageEnMView.ImageWidth> and ImageHeight return the dimensions of the image, <FC>idx<FN>.
|
|
|
|
Note: If images are being loaded on demand, then the image dimensions will not be valid until the image is loaded. Either use the <A TImageEnMView.OnImageLoaded> to delay until the image is ready, or force loading of the image by using <A TImageEnMView.EnsureImageLoaded>
|
|
|
|
<FM>Example<FC>
|
|
// Display the image size below the thumbnail
|
|
// Ensure you have set the BottomGap property
|
|
procedure TForm1.ImageEnMView1ImageDraw(Sender: TObject; idx: Integer; Left, Top: Integer; Canvas: TCanvas);
|
|
begin
|
|
Canvas.Font.Height := 15;
|
|
Canvas.Font.Color := clWhite;
|
|
Canvas.TextOut(Left,
|
|
Top + imageenmview1.ThumbHeight - imageenmview1.bottomgap + 2,
|
|
IntToStr(imageenmview1.ImageWidth[idx]) + 'x' + IntToStr(imageenmview1.ImageHeight[idx]));
|
|
end;
|
|
!!}
|
|
function TImageEnMView.GetImageHeight(idx: integer): integer;
|
|
begin
|
|
result := fIEMBitmap.ImageHeight[ idx ];
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ImageOriginalWidth
|
|
|
|
<FM>Declaration<FC>
|
|
property ImageOriginalWidth[idx: Integer]: Integer;
|
|
|
|
<FM>Description<FN>
|
|
Use ImageOriginalWidth to read or set the original width of the image, <FC>idx<FN>.
|
|
|
|
This is useful only when images are stored as thumbnails (<A TImageEnMView.StoreType> = ietThumb/ietFastThumb) and you need to know the original image size.
|
|
|
|
Note: If images are being loaded on demand, then the image dimensions will not be valid until the image is loaded. Either use the <A TImageEnMView.OnImageLoaded> to delay until the image is ready, or force loading of the image by using <A TImageEnMView.EnsureImageLoaded>
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.ImageOriginalHeight>
|
|
!!}
|
|
function TImageEnMView.GetImageOriginalWidth(idx: integer): integer;
|
|
begin
|
|
result := 0;
|
|
if (idx >= 0) and (idx < fIEMBitmap.Count) then
|
|
with fIEMBitmap.GetImageInfo( idx ) do
|
|
begin
|
|
if image <> nil then
|
|
result := fIEMBitmap.fImageList.GetImageOriginalWidth( image )
|
|
else
|
|
if cacheImage <> nil then
|
|
result := fCacheList.GetImageOriginalWidth(cacheImage);
|
|
end;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ImageOriginalHeight
|
|
|
|
<FM>Declaration<FC>
|
|
property ImageOriginalHeight[idx: Integer]: Integer;
|
|
|
|
<FM>Description<FN>
|
|
Use ImageOriginalHeight to read or set the original height of the image, <FC>idx<FN>.
|
|
|
|
This is useful only when images are stored as thumbnails (<A TImageEnMView.StoreType> = ietThumb/ietFastThumb) and you need to know the original image size.
|
|
|
|
Note: If images are being loaded on demand, then the image dimensions will not be valid until the image is loaded. Either use the <A TImageEnMView.OnImageLoaded> to delay until the image is ready, or force loading of the image by using <A TImageEnMView.EnsureImageLoaded>
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.ImageOriginalWidth>
|
|
!!}
|
|
function TImageEnMView.GetImageOriginalHeight(idx: integer): integer;
|
|
begin
|
|
result := 0;
|
|
if (idx >= 0) and (idx < fIEMBitmap.Count) then
|
|
with fIEMBitmap.GetImageInfo( idx ) do
|
|
begin
|
|
if image <> nil then
|
|
result := fIEMBitmap.fImageList.GetImageOriginalHeight( image )
|
|
else
|
|
if cacheImage <> nil then
|
|
result := fCacheList.GetImageOriginalHeight(cacheImage);
|
|
end;
|
|
end;
|
|
|
|
procedure TImageEnMView.SetImageOriginalWidth(idx: integer; Value: integer);
|
|
begin
|
|
fIEMBitmap.ImageOriginalWidth[ idx ] := Value;
|
|
end;
|
|
|
|
procedure TImageEnMView.SetImageOriginalHeight(idx: integer; Value: integer);
|
|
begin
|
|
fIEMBitmap.ImageOriginalHeight[ idx ] := Value;
|
|
end;
|
|
|
|
// Retrieve the size and dates of the image at idx, from the file system
|
|
procedure TImageEnMView.GetFileDetailsForImage(idx: integer);
|
|
var
|
|
ii: TIEImageInfo;
|
|
iFileSizeBytes: Int64;
|
|
dtCreateDate: TDateTime;
|
|
dtModifiedDate: TDateTime;
|
|
begin
|
|
// Assumes we have already checked index is valid!
|
|
ii := fIEMBitmap.GetImageInfo( idx );
|
|
|
|
if ii.FileSize = -1 then
|
|
exit; // we have already checked this
|
|
|
|
if (ii.Filename <> '') and IEGetFileDetails(ii.Filename, iFileSizeBytes, dtCreateDate, dtModifiedDate) then
|
|
begin
|
|
ii.FileSize := iFileSizeBytes;
|
|
ii.CreateDate := dtCreateDate;
|
|
ii.EditDate := dtModifiedDate;
|
|
end
|
|
else
|
|
begin
|
|
ii.FileSize := -1;
|
|
ii.CreateDate := 0;
|
|
ii.EditDate := 0;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ImageCreateDate
|
|
|
|
<FM>Declaration<FC>
|
|
property ImageCreateDate[idx: Integer]: TDateTime;
|
|
|
|
<FM>Description<FN>
|
|
Returns the creation date for the file at index, idx. If the file is a JPEG then this will be read from the EXIF data for greater accuracy. Otherwise it is read from the file system.
|
|
|
|
Result is 0 if this frame does not exist as a file on disk and has no exif data.
|
|
|
|
See also: <A TImageEnMView.ImageEditDate>.
|
|
!!}
|
|
function TImageEnMView.GetImageCreateDate(idx: integer): TDateTime;
|
|
begin
|
|
result := 0;
|
|
if (idx >= 0) and (idx < fIEMBitmap.Count) then
|
|
begin
|
|
result := fIEMBitmap.GetImageInfo( idx ).CreateDate;
|
|
if Result = 0 then
|
|
begin
|
|
GetFileDetailsForImage(idx);
|
|
result := fIEMBitmap.GetImageInfo( idx ).CreateDate;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TImageEnMView.SetImageCreateDate(idx: integer; Value: TDateTime);
|
|
begin
|
|
if (idx >= 0) and (idx < fIEMBitmap.Count) then
|
|
fIEMBitmap.GetImageInfo( idx ).CreateDate := Value;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ImageEditDate
|
|
|
|
<FM>Declaration<FC>
|
|
property ImageEditDate[idx: Integer]: TDateTime;
|
|
|
|
<FM>Description<FN>
|
|
Returns the last modification date for the file at index, idx, which is read from the file system.
|
|
|
|
Result is 0 if this frame does not exist as a file on disk.
|
|
|
|
See also: <A TImageEnMView.ImageCreateDate>.
|
|
!!}
|
|
function TImageEnMView.GetImageEditDate(idx: integer): TDateTime;
|
|
begin
|
|
result := 0;
|
|
if (idx >= 0) and (idx < fIEMBitmap.Count) then
|
|
begin
|
|
result := fIEMBitmap.GetImageInfo( idx ).EditDate;
|
|
if Result = 0 then
|
|
begin
|
|
GetFileDetailsForImage(idx);
|
|
result := fIEMBitmap.GetImageInfo( idx ).EditDate;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TImageEnMView.SetImageEditDate(idx: integer; Value: TDateTime);
|
|
begin
|
|
if (idx >= 0) and (idx < fIEMBitmap.Count) then
|
|
fIEMBitmap.GetImageInfo( idx ).EditDate := Value;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ImageFileSize
|
|
|
|
<FM>Declaration<FC>
|
|
property ImageFileSize[idx: Integer]: Int64;
|
|
|
|
<FM>Description<FN>
|
|
Returns the file size (in Bytes) for the file at index, idx. Result is -1 if this frame does not exist as a file on disk.
|
|
|
|
!!}
|
|
function TImageEnMView.GetImageFileSize(idx: integer): Int64;
|
|
begin
|
|
Result := -1;
|
|
if (idx >= 0) and (idx < fIEMBitmap.Count) then
|
|
begin
|
|
result := fIEMBitmap.GetImageInfo( idx ).FileSize;
|
|
if Result = -1 then
|
|
begin
|
|
GetFileDetailsForImage(idx);
|
|
result := fIEMBitmap.GetImageInfo( idx ).FileSize;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ImageFileType
|
|
|
|
<FM>Declaration<FC>
|
|
property ImageFileType[idx: Integer]: WideString;
|
|
|
|
<FM>Description<FN>
|
|
Returns the Window's file type for the file at index, idx.
|
|
|
|
!!}
|
|
function TImageEnMView.GetImageFileType(idx: integer): WideString;
|
|
|
|
function IEGetFileFileType(const sFilename : String): String;
|
|
var
|
|
shfi: TShFileInfo;
|
|
begin
|
|
try
|
|
ShGetFileInfo(PChar(sFilename), 0, shfi, SizeOf(TShFileInfo), SHGFI_TYPENAME);
|
|
Result := shfi.szTypeName;
|
|
except
|
|
Result := '';
|
|
end;
|
|
end;
|
|
|
|
var
|
|
sFilename: string;
|
|
begin
|
|
Result := '';
|
|
if (idx >= 0) and (idx < fIEMBitmap.Count) then
|
|
begin
|
|
sFilename := fIEMBitmap.GetImageInfo( idx ).Filename;
|
|
if sFilename <> '' then
|
|
result := IEGetFileFileType(sFilename);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ImageType
|
|
|
|
<FM>Declaration<FC>
|
|
property ImageType[idx: Integer]: <A TIEFolderImageType>;
|
|
|
|
<FM>Description<FN>
|
|
Determines the type of file at at index, <FC>idx<FN>.
|
|
|
|
<FM>Example<FC>
|
|
case IEFolderMView1.ImageType[idx] of
|
|
ieftFolder : Caption := 'Folder';
|
|
ieftSupportedImage : Caption := 'Image/Video';
|
|
ieftFile : Caption := 'File';
|
|
end;
|
|
|
|
!!}
|
|
function TImageEnMView.GetImageType(idx: integer): TIEFolderImageType;
|
|
begin
|
|
Result := ieftSupportedImage;
|
|
if (idx >= 0) and (idx < fIEMBitmap.Count) then
|
|
begin
|
|
if fIEMBitmap.GetImageInfo( idx ).SourceType = iestFolderIcon then
|
|
Result := ieftFolder
|
|
else
|
|
if IsKnownFormat(fIEMBitmap.GetImageInfo( idx ).Filename) then
|
|
Result := ieftSupportedImage
|
|
else
|
|
Result := ieftFile;
|
|
end;
|
|
end;
|
|
|
|
procedure TImageEnMView.SetImageFileSize(idx: integer; Value: Int64);
|
|
begin
|
|
if (idx >= 0) and (idx < fIEMBitmap.Count) then
|
|
fIEMBitmap.GetImageInfo( idx ).FileSize := Value;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ImageBitCount
|
|
|
|
<FM>Declaration<FC>
|
|
property ImageBitCount[idx: Integer]: Integer;
|
|
|
|
<FM>Description<FN>
|
|
Returns the bit count of the image, <FC>idx<FN>. It can be:
|
|
1 : Black/white image
|
|
24 : True color image
|
|
|
|
Note: If images are being loaded on demand, then the image dimensions will not be valid until the image is loaded. Either use the <A TImageEnMView.OnImageLoaded> to delay until the image is ready, or force loading of the image by using <A TImageEnMView.EnsureImageLoaded>
|
|
|
|
!!}
|
|
function TImageEnMView.GetImageBitCount(idx: integer): integer;
|
|
begin
|
|
result := 0;
|
|
if (idx >= 0) and (idx < fIEMBitmap.Count) then
|
|
with fIEMBitmap.GetImageInfo( idx ) do
|
|
begin
|
|
if image <> nil then
|
|
result := fIEMBitmap.fImageList.GetImageBitCount(image)
|
|
else
|
|
if cacheImage <> nil then
|
|
result := fCacheList.GetImageBitCount(cacheImage);
|
|
end;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ImageY
|
|
|
|
<FM>Declaration<FC>
|
|
property ImageY[idx: Integer]: integer;
|
|
|
|
<FM>Description<FN>
|
|
Returns the Y position (in pixels) where image <FC>idx<FN> will be shown.
|
|
|
|
Read-only
|
|
|
|
!!}
|
|
function TImageEnMView.GetImageY(idx: integer): integer;
|
|
begin
|
|
result := 0;
|
|
if (idx >= 0) and (idx < fIEMBitmap.Count) then
|
|
result := fIEMBitmap.GetImageInfo( idx ).Y;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ImageX
|
|
|
|
<FM>Declaration<FC>
|
|
property ImageX[idx: Integer]: integer;
|
|
|
|
<FM>Description<FN>
|
|
Returns the X position (in pixels) where image <FC>idx<FN> will be shown.
|
|
|
|
Read-only
|
|
|
|
!!}
|
|
function TImageEnMView.GetImageX(idx: integer): integer;
|
|
begin
|
|
result := 0;
|
|
if (idx >= 0) and (idx < fIEMBitmap.Count) then
|
|
result := fIEMBitmap.GetImageInfo( idx ).X;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ImageRow
|
|
|
|
<FM>Declaration<FC>
|
|
property ImageRow[idx: Integer]: integer; (Read-only)
|
|
|
|
<FM>Description<FN>
|
|
Returns the row where image <FC>idx<FN> will be shown. ImageRow[] returns 0 for the first image, 1 for an image on the second row, etc.
|
|
|
|
!!}
|
|
function TImageEnMView.GetImageRow(idx: integer): integer;
|
|
begin
|
|
result := 0;
|
|
if (idx >= 0) and (idx < fIEMBitmap.Count) then
|
|
result := fIEMBitmap.GetImageInfo( idx ).row;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ImageCol
|
|
|
|
<FM>Declaration<FC>
|
|
property ImageCol[idx: Integer]: integer; (Read-only)
|
|
|
|
<FM>Description<FN>
|
|
ImageCol returns the column where is the image <FC>idx<FN> will be shown. ImageCol[] returns 0 for the first image, 1 for an image on the second column, etc.
|
|
|
|
!!}
|
|
function TImageEnMView.GetImageCol(idx: integer): integer;
|
|
begin
|
|
result := 0;
|
|
if (idx >= 0) and (idx < fIEMBitmap.Count) then
|
|
result := fIEMBitmap.GetImageInfo( idx ).col;
|
|
end;
|
|
|
|
// Note: set ID = -1
|
|
procedure TImageEnMView.SetImageFileName(idx: integer; v: WideString);
|
|
begin
|
|
fIEMBitmap.ImageFileName[ idx ] := v;
|
|
end;
|
|
|
|
|
|
procedure TImageEnMView.SetImageTopText(idx: integer; v: WideString);
|
|
begin
|
|
if (idx >= 0) and (idx < fIEMBitmap.Count) then
|
|
with fIEMBitmap.GetImageInfo( idx ) do
|
|
if TopText <> v then
|
|
begin
|
|
TopText := v;
|
|
if v <> '' then
|
|
UpdateTopTextHeight( True );
|
|
Update;
|
|
end;
|
|
end;
|
|
|
|
procedure TImageEnMView.SetImageBottomText(idx: integer; v: WideString);
|
|
begin
|
|
if (idx >= 0) and (idx < fIEMBitmap.Count) then
|
|
with fIEMBitmap.GetImageInfo( idx ) do
|
|
if BottomText <> v then
|
|
begin
|
|
BottomText := v;
|
|
if v <> '' then
|
|
UpdateBottomTextHeight( True );
|
|
Update;
|
|
end;
|
|
end;
|
|
|
|
procedure TImageEnMView.SetImageInfoText(idx: integer; v: WideString);
|
|
begin
|
|
if (idx >= 0) and (idx < fIEMBitmap.Count) then
|
|
with fIEMBitmap.GetImageInfo( idx ) do
|
|
if InfoText <> v then
|
|
begin
|
|
InfoText := v;
|
|
if v <> '' then
|
|
UpdateInfoTextHeight( True );
|
|
Update;
|
|
end;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ImageFileName
|
|
|
|
<FM>Declaration<FC>
|
|
property ImageFileName[idx: Integer]: WideString;
|
|
|
|
<FM>Description<FN>
|
|
Specifies the file from where TImageEnMView will load the image for index, <FC>idx<FN> (loading is delayed until it needs to be shown).
|
|
|
|
A full file path must be specified. Optionally an image index can be specified for multi-page files in the form: "FullFilePath::ImageIndex"
|
|
|
|
<FM>Example 1<FC>
|
|
// Load image1.jpg as thumbnail 0 and image2.jpg as thumbnail 1
|
|
ImageEnView1.ImageFileName[0] := 'C:\image1.jpg';
|
|
ImageEnView1.ImageFileName[1] := 'C:\image2.jpg';
|
|
|
|
<FM>Example 2<FC>
|
|
// Load frame 0 and 1 from input.mpeg
|
|
ImageEnView1.ImageFileName[0] := 'C:\input.mpeg::0';
|
|
ImageEnView1.ImageFileName[1] := 'C:\input.mpeg::1';
|
|
|
|
<FM>Example 3<FC>
|
|
This example inserts two images. The first is loaded from 'one.tif' and the second from 'two.tif'.
|
|
The images are loaded only when these are shown (otherwise they are freed).
|
|
|
|
ImageEnMView1.InsertImage(0);
|
|
ImageEnMView1.ImageFileName[0] := 'C:\one.tif';
|
|
ImageEnMView1.InsertImage(1);
|
|
ImageEnMView1.ImageFileName[1] := 'C:\two.tif';
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.LoadFromFileOnDemand>
|
|
!!}
|
|
function TImageEnMView.GetImageFileName(idx: integer): WideString;
|
|
begin
|
|
result := fIEMBitmap.ImageFileName[ idx ];
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ImageTopText
|
|
|
|
<FM>Declaration<FC>
|
|
property ImageTopText[idx: Integer]: WideString;
|
|
|
|
<FM>Description<FN>
|
|
Use <FC>ImageTopText<FN> to specify custom text to appear above the thumbnail of index, <FC>idx<FN>.
|
|
The default top text is specified by <A TImageEnMView.DefaultTopText> but you can override this for a specific thumbnail by setting a value for <FC>ImageTopText<FN>.
|
|
|
|
Notes:
|
|
- The font style is set by <A TImageEnMView.TopTextFont>. But you can customize it for specific thumbnails using the <A TImageEnMView.OnGetTextEx> event.
|
|
- <A TImageEnMView.UpperGap> will be adjusted to fit the text.
|
|
- Other text fields that can be set are: <A TImageEnMView.ImageBottomText> and <A TImageEnMView.ImageInfoText>
|
|
|
|
You can optionally specify the following constants:
|
|
<TABLE>
|
|
<R> <H>Value</H> <H>Displays</H> <H>Example</H> </R>
|
|
<R> <C>IEM_Filename</C> <C>Name of the file</C> <C>'MyImage.jpg'</C> </R>
|
|
<R> <C>IEM_FilenameNoExt</C> <C>Name of the file without its extension (or path)</C> <C>'MyImage'</C> </R>
|
|
<R> <C>IEM_FilePath</C> <C>Path of the file</C> <C>'C:\Data\My Pictures\'</C> </R>
|
|
<R> <C>IEM_ImageDimensions</C> <C>Dimensions and color depth of images (Nothing is shown for non-images)</C> <C>'1200 x 800'</C> </R>
|
|
<R> <C>IEM_ImageDimAndSize</C> <C>Dimensions of images with the file size</C> <C>'1200 x 800, 3,900 KB'</C> </R>
|
|
<R> <C>IEM_FileSize</C> <C>Size of the file on disk</C> <C>'3,900 KB'</C> </R>
|
|
<R> <C>IEM_FileCreateDate</C> <C>The date that the file was created</C> <C>'7/5/13'</C> </R>
|
|
<R> <C>IEM_FileCreateDateTime</C> <C>The date and time that the file was created</C> <C>'7/5/13 8:03am'</C> </R>
|
|
<R> <C>IEM_FileCreateDateAndSize</C> <C>The create date of the file and its size</C> <C>'7/5/13, 3,900 KB'</C> </R>
|
|
<R> <C>IEM_FileEditDate</C> <C>The date that the file was last edited</C> <C>'7/5/13'</C> </R>
|
|
<R> <C>IEM_FileEditDateTime</C> <C>The date and time that the file was last edited</C> <C>'7/5/13 8:03am'</C> </R>
|
|
<R> <C>IEM_FileEditDateAndSize</C> <C>The last edit date of the file and its size</C> <C>'7/5/13, 3,900 KB'</C> </R>
|
|
<R> <C>IEM_FileType</C> <C>The ImageEn type for this file</C> <C>'JPEG Image'</C> </R>
|
|
<R> <C>IEM_FileExt</C> <C>The extension only of the file, e.g. JPEG for 'MyImage.jpeg'</C> <C>'JPEG'</C> </R>
|
|
<R> <C>IEM_ImageDict"xyz"</C> <C>Returns the value of key xyz from the <A TIEMultiBitmap.ImageDictionary></C> <C>'Some Dictionary Value'</C> </R>
|
|
</TABLE>
|
|
|
|
<FM>Example<FC>
|
|
ImageEnMView1.ImageTopText[idx] := 'Top text';
|
|
ImageEnMView1.ImageInfoText[idx] := 'Info text';
|
|
ImageEnMView1.ImageBottomText[idx] := 'Bottom text';
|
|
|
|
<IMG help_images\ThumbText.jpg>
|
|
|
|
// Display the filename and dimensions for each image
|
|
for I := 0 to ImageEnMView1.ImageCount - 1 do
|
|
begin
|
|
ImageInfoText[I] := IEM_ImageDimensions;
|
|
ImageBottomText[I] := IEM_Filename;
|
|
end;
|
|
|
|
<FM>Compatibility Notes<FN>
|
|
Prior to v6.0.0, ImageTopText was a class that held properties for Font, Caption, etc. This was simplified in v6.0.0. ImageTopText is now only a widestring that carries the caption for a cell.
|
|
|
|
So code that was previously:
|
|
ImageTopText[idx].Caption := 'Abc';
|
|
|
|
Is now:
|
|
ImageTopText[idx] := 'Abc';
|
|
|
|
To set the font of the text, use <A TImageEnMView.TopTextFont>. <A TImageEnMView.TextBackgroundStyle> and <A TImageEnMView.TextBackgroundColor> now control the background for all cells, and <A TImageEnMView.TextTruncSide> allows you to change the truncation. These properties affect all cells, so to customize the styling of a particular cell use the <A TImageEnMView.OnGetTextEx> event.
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.OnGetText>
|
|
!!}
|
|
function TImageEnMView.GetImageTopText(idx: integer): WideString;
|
|
begin
|
|
result := '';
|
|
if (idx >= 0) and (idx < fIEMBitmap.Count) then
|
|
result := fIEMBitmap.GetImageInfo( idx ).TopText;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ImageBottomText
|
|
|
|
<FM>Declaration<FC>
|
|
property ImageBottomText[idx: Integer]: WideString;
|
|
|
|
<FM>Description<FN>
|
|
Use <FC>ImageBottomText<FN> to specify custom text to appear below the thumbnail of index, <FC>idx<FN>.
|
|
The default bottom text is specified by <A TImageEnMView.DefaultBottomText> but you can override this for a specific thumbnail by setting a value for <FC>ImageBottomText<FN>.
|
|
|
|
Notes:
|
|
- The font style is set by <A TImageEnMView.BottomTextFont>. But you can customize it for specific thumbnails using the <A TImageEnMView.OnGetTextEx> event.
|
|
- <A TImageEnMView.BottomGap> will be adjusted to fit the text.
|
|
- Other text fields that can be set are: <A TImageEnMView.ImageTopText> and <A TImageEnMView.ImageInfoText>
|
|
|
|
You can optionally specify the following constants:
|
|
<TABLE>
|
|
<R> <H>Value</H> <H>Displays</H> <H>Example</H> </R>
|
|
<R> <C>IEM_Filename</C> <C>Name of the file</C> <C>'MyImage.jpg'</C> </R>
|
|
<R> <C>IEM_FilenameNoExt</C> <C>Name of the file without its extension (or path)</C> <C>'MyImage'</C> </R>
|
|
<R> <C>IEM_FilePath</C> <C>Path of the file</C> <C>'C:\Data\My Pictures\'</C> </R>
|
|
<R> <C>IEM_ImageDimensions</C> <C>Dimensions and color depth of images (Nothing is shown for non-images)</C> <C>'1200 x 800'</C> </R>
|
|
<R> <C>IEM_ImageDimAndSize</C> <C>Dimensions of images with the file size</C> <C>'1200 x 800, 3,900 KB'</C> </R>
|
|
<R> <C>IEM_FileSize</C> <C>Size of the file on disk</C> <C>'3,900 KB'</C> </R>
|
|
<R> <C>IEM_FileCreateDate</C> <C>The date that the file was created</C> <C>'7/5/13'</C> </R>
|
|
<R> <C>IEM_FileCreateDateTime</C> <C>The date and time that the file was created</C> <C>'7/5/13 8:03am'</C> </R>
|
|
<R> <C>IEM_FileCreateDateAndSize</C> <C>The create date of the file and its size</C> <C>'7/5/13, 3,900 KB'</C> </R>
|
|
<R> <C>IEM_FileEditDate</C> <C>The date that the file was last edited</C> <C>'7/5/13'</C> </R>
|
|
<R> <C>IEM_FileEditDateTime</C> <C>The date and time that the file was last edited</C> <C>'7/5/13 8:03am'</C> </R>
|
|
<R> <C>IEM_FileEditDateAndSize</C> <C>The last edit date of the file and its size</C> <C>'7/5/13, 3,900 KB'</C> </R>
|
|
<R> <C>IEM_FileType</C> <C>The ImageEn type for this file</C> <C>'JPEG Image'</C> </R>
|
|
<R> <C>IEM_FileExt</C> <C>The extension only of the file, e.g. JPEG for 'MyImage.jpeg'</C> <C>'JPEG'</C> </R>
|
|
<R> <C>IEM_ImageDict"xyz"</C> <C>Returns the value of key xyz from the <A TIEMultiBitmap.ImageDictionary></C> <C>'Some Dictionary Value'</C> </R>
|
|
</TABLE>
|
|
|
|
<FM>Example<FC>
|
|
ImageEnMView1.ImageTopText[idx] := 'Top text';
|
|
ImageEnMView1.ImageInfoText[idx] := 'Info text';
|
|
ImageEnMView1.ImageBottomText[idx] := 'Bottom text';
|
|
|
|
<IMG help_images\ThumbText.jpg>
|
|
|
|
// Display the filename and dimensions for each image
|
|
for I := 0 to ImageEnMView1.ImageCount - 1 do
|
|
begin
|
|
ImageInfoText[I] := IEM_ImageDimensions;
|
|
ImageBottomText[I] := IEM_Filename;
|
|
end;
|
|
|
|
<FM>Compatibility Notes<FN>
|
|
Prior to v6.0.0, ImageBottomText was a class that held properties for Font, Caption, etc. This was simplified in v6.0.0. ImageBottomText is now only a widestring that carries the caption for a cell.
|
|
|
|
So code that was previously:
|
|
ImageBottomText[idx].Caption := 'Abc';
|
|
|
|
Is now:
|
|
ImageBottomText[idx] := 'Abc';
|
|
|
|
To set the font of the text, use <A TImageEnMView.BottomTextFont>. <A TImageEnMView.TextBackgroundStyle> and <A TImageEnMView.TextBackgroundColor> now control the background for all cells, and <A TImageEnMView.TextTruncSide> allows you to change the truncation. These properties affect all cells, so to customize the styling of a particular cell use the <A TImageEnMView.OnGetTextEx> event.
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.OnGetText>
|
|
!!}
|
|
function TImageEnMView.GetImageBottomText(idx: integer): WideString;
|
|
begin
|
|
result := '';
|
|
if (idx >= 0) and (idx < fIEMBitmap.Count) then
|
|
result := fIEMBitmap.GetImageInfo( idx ).BottomText;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ImageInfoText
|
|
|
|
<FM>Declaration<FC>
|
|
property ImageInfoText[idx: Integer]: WideString;
|
|
|
|
<FM>Description<FN>
|
|
Use <FC>ImageInfoText<FN> to specify custom text to appear directly below the thumbnail of index, <FC>idx<FN> (above <A TImageEnMView.ImageBottomText>).
|
|
The default info text is specified by <A TImageEnMView.DefaultInfoText> but you can override this for a specific thumbnail by setting a value for <FC>ImageInfoText<FN>.
|
|
|
|
Notes:
|
|
- The font style is set by <A TImageEnMView.InfoTextFont>. But you can customize it for specific thumbnails using the <A TImageEnMView.OnGetTextEx> event.
|
|
- Other text fields that can be set are: <A TImageEnMView.ImageTopText> and <A TImageEnMView.ImageBottomText>
|
|
|
|
You can optionally specify the following constants:
|
|
<TABLE>
|
|
<R> <H>Value</H> <H>Displays</H> <H>Example</H> </R>
|
|
<R> <C>IEM_Filename</C> <C>Name of the file</C> <C>'MyImage.jpg'</C> </R>
|
|
<R> <C>IEM_FilenameNoExt</C> <C>Name of the file without its extension (or path)</C> <C>'MyImage'</C> </R>
|
|
<R> <C>IEM_FilePath</C> <C>Path of the file</C> <C>'C:\Data\My Pictures\'</C> </R>
|
|
<R> <C>IEM_ImageDimensions</C> <C>Dimensions and color depth of images (Nothing is shown for non-images)</C> <C>'1200 x 800'</C> </R>
|
|
<R> <C>IEM_ImageDimAndSize</C> <C>Dimensions of images with the file size</C> <C>'1200 x 800, 3,900 KB'</C> </R>
|
|
<R> <C>IEM_FileSize</C> <C>Size of the file on disk</C> <C>'3,900 KB'</C> </R>
|
|
<R> <C>IEM_FileCreateDate</C> <C>The date that the file was created</C> <C>'7/5/13'</C> </R>
|
|
<R> <C>IEM_FileCreateDateTime</C> <C>The date and time that the file was created</C> <C>'7/5/13 8:03am'</C> </R>
|
|
<R> <C>IEM_FileCreateDateAndSize</C> <C>The create date of the file and its size</C> <C>'7/5/13, 3,900 KB'</C> </R>
|
|
<R> <C>IEM_FileEditDate</C> <C>The date that the file was last edited</C> <C>'7/5/13'</C> </R>
|
|
<R> <C>IEM_FileEditDateTime</C> <C>The date and time that the file was last edited</C> <C>'7/5/13 8:03am'</C> </R>
|
|
<R> <C>IEM_FileEditDateAndSize</C> <C>The last edit date of the file and its size</C> <C>'7/5/13, 3,900 KB'</C> </R>
|
|
<R> <C>IEM_FileType</C> <C>The ImageEn type for this file</C> <C>'JPEG Image'</C> </R>
|
|
<R> <C>IEM_FileExt</C> <C>The extension only of the file, e.g. JPEG for 'MyImage.jpeg'</C> <C>'JPEG'</C> </R>
|
|
<R> <C>IEM_ImageDict"xyz"</C> <C>Returns the value of key xyz from the <A TIEMultiBitmap.ImageDictionary></C> <C>'Some Dictionary Value'</C> </R>
|
|
</TABLE>
|
|
|
|
<FM>Example<FC>
|
|
ImageEnMView1.ImageTopText[idx] := 'Top text';
|
|
ImageEnMView1.ImageInfoText[idx] := 'Info text';
|
|
ImageEnMView1.ImageBottomText[idx] := 'Bottom text';
|
|
|
|
<IMG help_images\ThumbText.jpg>
|
|
|
|
// Display the filename and dimensions for each image
|
|
for I := 0 to ImageEnMView1.ImageCount - 1 do
|
|
begin
|
|
ImageInfoText[I] := IEM_ImageDimensions;
|
|
ImageBottomText[I] := IEM_Filename;
|
|
end;
|
|
|
|
<FM>Compatibility Notes<FN>
|
|
Prior to v6.0.0, ImageInfoText was a class that held properties for Font, Caption, etc. This was simplified in v6.0.0. ImageInfoText is now only a widestring that carries the caption for a cell.
|
|
|
|
So code that was previously:
|
|
ImageInfoText[idx].Caption := 'Abc';
|
|
|
|
Is now:
|
|
ImageInfoText[idx] := 'Abc';
|
|
|
|
To set the font of the text, use <A TImageEnMView.InfoTextFont>. <A TImageEnMView.TextBackgroundStyle> and <A TImageEnMView.TextBackgroundColor> now control the background for all cells, and <A TImageEnMView.TextTruncSide> allows you to change the truncation. These properties affect all cells, so to customize the styling of a particular cell use the <A TImageEnMView.OnGetTextEx> event.
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.OnGetText>
|
|
!!}
|
|
function TImageEnMView.GetImageInfoText(idx: integer): WideString;
|
|
begin
|
|
result := '';
|
|
if (idx >= 0) and (idx < fIEMBitmap.Count) then
|
|
result := fIEMBitmap.GetImageInfo( idx ).InfoText;
|
|
end;
|
|
|
|
|
|
// set name=''
|
|
procedure TImageEnMView.SetImageID(idx, v: integer);
|
|
begin
|
|
if (idx >= 0) and (idx < fIEMBitmap.Count) then
|
|
with fIEMBitmap.GetImageInfo( idx ) do
|
|
begin
|
|
ID := v;
|
|
Filename := '';
|
|
end;
|
|
end;
|
|
|
|
procedure TImageEnMView.SetImageTag(idx, v: integer);
|
|
begin
|
|
fIEMBitmap.ImageTag[ idx ] := v;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ImageTag
|
|
|
|
<FM>Declaration<FC>
|
|
property ImageTag[idx: Integer]: integer;
|
|
|
|
<FM>Description<FN>
|
|
Associates a numeric integer value with the image, <FC>idx<FN>.
|
|
|
|
Note:
|
|
- This property is not used by TImageEnMView in any way and is provided for custom use (similar to the Tag property of components).
|
|
- The value is not loaded/saved from file and streams, or copied/pasted to clipboard.
|
|
!!}
|
|
function TImageEnMView.GetImageTag(idx: integer): integer;
|
|
begin
|
|
result := fIEMBitmap.ImageTag[ idx ];
|
|
end;
|
|
|
|
|
|
|
|
procedure TImageEnMView.SetImageUserPointer(idx: Integer; v: pointer);
|
|
begin
|
|
fIEMBitmap.ImageUserPointer[ idx ] := v;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ImageUserPointer
|
|
|
|
<FM>Declaration<FC>
|
|
property ImageUserPointer[idx: Integer]: pointer;
|
|
|
|
<FM>Description<FN>
|
|
ImageUserPointer associates a pointer with image, <FC>idx<FN>.
|
|
|
|
Note:
|
|
- This property is not used by TImageEnMView in any way and is provided for custom use.
|
|
- The value is not loaded/saved from file and streams, or copied/pasted to clipboard.
|
|
|
|
<FM>Example<FC>
|
|
// Store a description and record ID when adding files to our grid
|
|
type
|
|
TFileDataRecord = Record
|
|
Description : string[100];
|
|
RecordID : Byte;
|
|
end;
|
|
|
|
Procedure TfMain.AddImageToGrid(const sFilename, sDescription : string; iRecordID : Integer);
|
|
var
|
|
POurRecord : ^TFileDataRecord;
|
|
iNewIndex: Integer;
|
|
begin
|
|
// Allocate memory
|
|
GetMem(POurRecord, SizeOf(TFileDataRecord));
|
|
|
|
iNewIndex := ImageEnMView1.AppendImage(sFilename);
|
|
POurRecord.Description := sDescription;
|
|
POurRecord.RecordID := iRecordID;
|
|
|
|
ImageEnMView1.ImageUserPointer[iNewIndex] := POurRecord;
|
|
end;
|
|
|
|
// When removing items from the ImageEnMView1 deallocate the memory...
|
|
Procedure TfMain.ClearGrid;
|
|
begin
|
|
for i := 0 to ImageEnMView1.ImageCount - 1 do
|
|
FreeMem(ImageEnMView1.ImageUserPointer[i]);
|
|
ImageEnMView1.Clear;
|
|
end;
|
|
|
|
!!}
|
|
function TImageEnMView.GetImageUserPointer(idx: Integer): pointer;
|
|
begin
|
|
result := fIEMBitmap.ImageUserPointer[ idx ];
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ImageID
|
|
|
|
<FM>Declaration<FC>
|
|
property ImageID[idx: Integer]: integer;
|
|
|
|
<FM>Description<FN>
|
|
ImageID associates a numeric ID with image, <FC>idx<FN>. It is mainly used to allow dynamic loading of content into a TImageEnMView.
|
|
|
|
This ID is returned in the <A TImageEnMView.OnImageIDRequest> and <A TImageEnMView.OnImageIDRequestEx> events.
|
|
|
|
Note: <A TImageEnMView.ImageFilename> is not valid when using <FC>ImageID<FN>.
|
|
|
|
<FM>Example<FC>
|
|
// Display all bitmaps in a TImageList in a TImageEnView
|
|
procedure TMyForm.FormShow(Sender: TObject);
|
|
var
|
|
I : Integer;
|
|
begin
|
|
ImageEnMView1.Clear;
|
|
|
|
// Add an ID for every bitmap in a TImageList
|
|
for I := 0 to ImageList1.Count - 1 do
|
|
begin
|
|
ImageEnMView1.InsertImage(I);
|
|
ImageEnMView1.ImageID[I] := I;
|
|
end;
|
|
end;
|
|
|
|
procedure TMyForm.ImageEnMViewOnImageIDRequest(Sender: TObject; ID: integer; var Bitmap: TBitmap);
|
|
begin
|
|
// Retrieve the image from a TImageList
|
|
Bitmap := TBitmap.create;
|
|
ImageList1.GetBitmap(ID, Bitmap);
|
|
end;
|
|
!!}
|
|
function TImageEnMView.GetImageID(idx: integer): integer;
|
|
begin
|
|
result := -1;
|
|
if (idx >= 0) and (idx < fIEMBitmap.Count) then
|
|
result := fIEMBitmap.GetImageInfo( idx ).ID;
|
|
end;
|
|
|
|
procedure TImageEnMView.SetImageBackground(idx: integer; v: TColor);
|
|
begin
|
|
if (idx >= 0) and (idx < fIEMBitmap.Count) then
|
|
begin
|
|
fIEMBitmap.ImageBackground[ idx ] := v;
|
|
ClearImageCache(idx);
|
|
UpdateEx(false);
|
|
end;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ImageBackground
|
|
|
|
<FM>Declaration<FC>
|
|
property ImageBackground: TColor;
|
|
|
|
<FM>Description<FN>
|
|
Specifies the color of the area between images.
|
|
|
|
!!}
|
|
function TImageEnMView.GetImageBackground(idx: integer): TColor;
|
|
begin
|
|
result := fIEMBitmap.ImageBackground[ idx ];
|
|
end;
|
|
|
|
procedure TImageEnMView.SetImageDelayTime(idx: integer; v: Double);
|
|
begin
|
|
fIEMBitmap.ImageDelayTime[ idx ] := v;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ImageDelayTime
|
|
|
|
<FM>Declaration<FC>
|
|
property ImageDelayTime[idx: Integer]: Double;
|
|
|
|
<FM>Description<FN>
|
|
ImageDelayTime is the time in milliseconds the image, <FC>idx<FN>, will be shown during playback (<A TImageEnMView.Playing> = True).
|
|
|
|
!!}
|
|
function TImageEnMView.GetImageDelayTime(idx: integer): Double;
|
|
begin
|
|
result := fIEMBitmap.ImageDelayTime[ idx ];
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ThumbWidth
|
|
|
|
<FM>Declaration<FC>
|
|
property ThumbWidth: integer;
|
|
|
|
<FM>Description<FN>
|
|
Specifies the width of the thumbnails displayed in the TImageEnView.
|
|
|
|
Note: This is the width of the thumbnail frame (when the <A TImageEnMView.Style> is iemsFlat). The thumbnail image itself will be ThumbWidth less 2 x <A TImageEnMView.SideGap>. See <A TImageEnMView.ThumbSizeInfo> for actual display size. Use <A TImageEnMView.SetThumbnailSize> if you want to set the display size of the image itself.
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.ThumbHeight>
|
|
- <A TImageEnMView.SetThumbnailSize>
|
|
- <A TImageEnMView.ThumbSizeInfo>
|
|
!!}
|
|
procedure TImageEnMView.SetThumbWidth(v: integer);
|
|
begin
|
|
fThumbWidth := v;
|
|
ClearCache;
|
|
Update;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ThumbHeight
|
|
|
|
<FM>Declaration<FC>
|
|
property ThumbHeight: integer;
|
|
|
|
<FM>Description<FN>
|
|
Specifies the height of the thumbnails displayed in the TImageEnView.
|
|
|
|
Note: This is the height of the thumbnail frame (when the <A TImageEnMView.Style> is iemsFlat). The thumbnail image itself will be ThumbHeight less <A TImageEnMView.UpperGap> and <A TImageEnMView.BottomGap>. See <A TImageEnMView.ThumbSizeInfo> for actual display size. Use <A TImageEnMView.SetThumbnailSize> if you want to set the display size of the image itself.
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.ThumbWidth>
|
|
- <A TImageEnMView.SetThumbnailSize>
|
|
- <A TImageEnMView.ThumbSizeInfo>
|
|
!!}
|
|
procedure TImageEnMView.SetThumbHeight(v: integer);
|
|
begin
|
|
fThumbHeight := v;
|
|
ClearCache;
|
|
Update;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ThumbSizeInfo
|
|
|
|
<FM>Declaration<FC>
|
|
function ThumbSizeInfo(Data: <A TIEThumbSizeType>): TPoint;
|
|
|
|
<FM>Description<FN>
|
|
Returns internal information about the current displayed size of thumbnail cells in the TImageEnView.
|
|
|
|
Data can be one of:
|
|
<TABLE>
|
|
<R> <H>Value</H> <H>Description</H> </R>
|
|
<R> <C>itsImage</C> <C>Returns the size of the thumbnail image as displayed</C> </R>
|
|
<R> <C>itsCell</C> <C>Returns the size of the thumbnail cell (image, text and cell border)</C> </R>
|
|
<R> <C>itsOuter</C> <C>Returns the size of the thumbnail cell and its external spacing (image, text, cell border and horizontal/vertical border)</C> </R>
|
|
</TABLE>
|
|
|
|
It takes into account:
|
|
- <A TImageEnMView.ThumbWidth> and <A TImageEnMView.ThumbHeight>
|
|
- <A TImageEnMView.Zoom>
|
|
- <A TImageEnMView.SideGap>, <A TImageEnMView.UpperGap> and <A TImageEnMView.BottomGap>
|
|
- <A TImageEnMView.HorizBorder> and <A TImageEnMView.VertBorder>
|
|
!!}
|
|
{
|
|
Here is a filled TImageEnMView:
|
|
|
|
_[o]_[o]_[o]_[o]_
|
|
_[o]_[o]_[o]_[o]_
|
|
_[o]_[o]_[o]_[o]_
|
|
_[o]_[o]_[o]_[o]_
|
|
|
|
itsImage: Just the thumbnail "o"
|
|
itsCell: Just the thumb cell "[o]"
|
|
itsOuter: Cell and the spacing around it "_[o]_"
|
|
}
|
|
function TImageEnMView.ThumbSizeInfo(Data: TIEThumbSizeType): TPoint;
|
|
var
|
|
iWidth, iHeight: Integer;
|
|
ActUpperGap, ActBottomGap: Integer;
|
|
begin
|
|
// WIDTH
|
|
iWidth := trunc( fThumbWidth * fZoom / 100.0 );
|
|
if Data = itsImage then
|
|
Dec( iWidth, 2 * fSideGap );
|
|
if Data in [ itsCell, itsOuter ] then
|
|
Inc( iWidth, CurrentTextBlockWidth );
|
|
if Data = itsOuter then
|
|
Inc( iWidth, fHorizBorder );
|
|
|
|
// HEIGHT
|
|
iHeight := trunc( fThumbHeight * fZoom / 100.0 );
|
|
if Data = itsImage then
|
|
begin
|
|
// UPPER
|
|
ActUpperGap := fUpperGap;
|
|
if fShowText and ( CurrentTextBlockWidth = 0 ) then
|
|
begin
|
|
if fTopTextHeight = CALCULATE_NOW then
|
|
UpdateTopTextHeight( True );
|
|
{$ifdef IEIncludeDeprecatedInV6}
|
|
// Legacy Handling - Prior to v6.2.2 UpperGap was enlarged to handle text height
|
|
if fUpperGap > 12 then
|
|
ActUpperGap := fUpperGap
|
|
else
|
|
{$endif}
|
|
ActUpperGap := fUpperGap + fTopTextHeight
|
|
end;
|
|
|
|
// LOWER
|
|
ActBottomGap := fBottomGap;
|
|
if fShowText and ( CurrentTextBlockWidth = 0 ) then
|
|
begin
|
|
if fBottomTextHeight = CALCULATE_NOW then
|
|
UpdateBottomTextHeight( True );
|
|
{$ifdef IEIncludeDeprecatedInV6}
|
|
// Legacy Handling - Prior to v6.2.2 UpperGap was enlarged to handle text height
|
|
if fBottomGap > 12 then
|
|
ActBottomGap := fBottomGap
|
|
else
|
|
{$endif}
|
|
ActBottomGap := fBottomGap + fBottomTextHeight
|
|
end;
|
|
|
|
Dec( iHeight, ActUpperGap + ActBottomGap );
|
|
end;
|
|
if Data = itsOuter then
|
|
Inc( iHeight, fVertBorder );
|
|
|
|
Result := Point( iWidth, iHeight );
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.SetThumbnailSize
|
|
|
|
<FM>Declaration<FC>
|
|
procedure SetThumbnailSize(width, height: Integer);
|
|
|
|
<FM>Description<FN>
|
|
Sets <A TImageEnMView.ThumbWidth> and <A TImageEnMView.ThumbHeight> in one step.
|
|
|
|
If <FC>SetImageSize<FN> is false, then the specified size is for thumbnail area (including border and text space). Otherwise, if true, it specifies the display size of the image only.
|
|
|
|
<FM>Declaration<FC>
|
|
// Set thumbnails to 200, 150
|
|
ImageEnMView1.SetThumbnailSize( 200, 150 );
|
|
|
|
// Set so images in the grid are shown at exactly 200, 150
|
|
ImageEnMView1.SetThumbnailSize( 200, 150, True );
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.ThumbWidth>
|
|
- <A TImageEnMView.ThumbHeight>
|
|
- <A TImageEnMView.ThumbSizeInfo>
|
|
!!}
|
|
procedure TImageEnMView.SetThumbnailSize(width, height: Integer; SetImageSize: Boolean = False);
|
|
var
|
|
horzGap, vertGap: Integer;
|
|
imgSize: TPoint;
|
|
begin
|
|
horzGap := 0;
|
|
vertGap := 0;
|
|
if SetImageSize then
|
|
begin
|
|
imgSize := ThumbSizeInfo( itsImage );
|
|
horzGap := trunc( fThumbWidth * fZoom / 100.0 ) - imgSize.X;
|
|
vertGap := trunc( fThumbHeight * fZoom / 100.0 ) - imgSize.Y;
|
|
end;
|
|
|
|
fThumbWidth := width + horzGap;
|
|
fThumbHeight := height + vertGap;
|
|
ClearCache;
|
|
Update;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.Zoom
|
|
|
|
<FM>Declaration<FC>
|
|
property Zoom: Double;
|
|
|
|
<FM>Description<FN>
|
|
Enlarge or reduce the size of the thumbnail display.
|
|
|
|
Note: This property is only recomended for handling of temporary display enlargement. It is better to <L TImageEnMView.ThumbWidth>set the size of the thumbnails</L>.
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.ThumbWidth>
|
|
- <A TImageEnMView.ThumbHeight>
|
|
!!}
|
|
procedure TImageEnMView.SetZoom(value: double);
|
|
begin
|
|
fCurrentGridWidth := fGridWidth;
|
|
if Value <> 100 then
|
|
fCurrentGridWidth := CalcGridWidth();
|
|
SetViewXY(round(ViewX / (fZoom / 100.0) * (value / 100.0)),
|
|
round(ViewY / (fZoom / 100.0) * (value / 100.0)));
|
|
fZoom := value;
|
|
ClearCache();
|
|
Update();
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ImageCount
|
|
|
|
<FM>Declaration<FC>
|
|
property ImageCount: integer; (Read-only)
|
|
|
|
<FM>Description<FN>
|
|
Returns the number of images stored in the TImageEnMView component.
|
|
|
|
<FM>Example<FC>
|
|
// Display the filename and dimensions for each image
|
|
for I := 0 to ImageEnMView1.ImageCount - 1 do
|
|
begin
|
|
ImageInfoText[I] := IEM_ImageDimensions;
|
|
ImageBottomText[I] := IEM_Filename;
|
|
end;
|
|
!!}
|
|
function TImageEnMView.GetImageCount: integer;
|
|
begin
|
|
result := fIEMBitmap.Count;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.HorizBorder
|
|
|
|
<FM>Declaration<FC>
|
|
property HorizBorder: integer;
|
|
|
|
<FM>Description<FN>
|
|
Specifies the horizontal distance between thumbnail cells.
|
|
|
|
See also: <A TImageEnMView.VertBorder>
|
|
!!}
|
|
procedure TImageEnMView.SetHorizBorder(v: integer);
|
|
begin
|
|
fHorizBorder := v;
|
|
Update;
|
|
end;
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.VertBorder
|
|
|
|
<FM>Declaration<FC>
|
|
property VertBorder: integer;
|
|
|
|
<FM>Description<FN>
|
|
Specifies the vertical distance between thumbnail cells.
|
|
|
|
See also: <A TImageEnMView.HorizBorder>
|
|
!!}
|
|
procedure TImageEnMView.SetVertBorder(v: integer);
|
|
begin
|
|
fVertBorder := v;
|
|
Update;
|
|
end;
|
|
|
|
|
|
|
|
// The top-left point of the top-left thumbnail
|
|
function TImageEnMView.ThumbnailsOrigin : TPoint;
|
|
const
|
|
Header_Gap = 4; // Space between header and first item
|
|
var
|
|
iLeft, iTop: Integer;
|
|
iColCount: Integer;
|
|
iHeadHeight: Integer;
|
|
begin
|
|
// LEFT POSITION
|
|
iLeft := 0;
|
|
if (fDisplayMode = mdGrid) and (ietxCenterThumbnailColumn in fThumbnailOptionsEx) then
|
|
begin
|
|
if fCurrentGridWidth = 1 then
|
|
iLeft := ( ClientWidth - ThumbSizeInfo( itsCell ).X ) div 2
|
|
else
|
|
if fCurrentGridWidth <> 0 then
|
|
begin
|
|
iColCount := fCurrentGridWidth;
|
|
if iColCount = -1 then
|
|
iColCount := CalcGridWidth();
|
|
iLeft := imax(0, (ClientWidth - ( iColCount * ThumbSizeInfo( itsOuter ).X )) div 2);
|
|
end;
|
|
end;
|
|
|
|
// TOP POSITION
|
|
iTop := 0;
|
|
|
|
// If in columns mode add the height of the fixed row + margin.
|
|
iHeadHeight := CurrentHeaderRowHeight;
|
|
if iHeadHeight > 0 then
|
|
inc( iTop, iHeadHeight + Header_Gap );
|
|
|
|
// Center vertically if we have only a single row
|
|
if (fDisplayMode = mdGrid) and (ietxCenterThumbnailColumn in fThumbnailOptionsEx) and (fCurrentGridWidth = 0) then
|
|
iTop := ( ClientHeight - ThumbSizeInfo( itsCell ).Y ) div 2;
|
|
|
|
Result := Point( iLeft, iTop );
|
|
end;
|
|
|
|
|
|
// recalc x, y image positions
|
|
// update fVWidth and fVHeight
|
|
procedure TImageEnMView.UpdateCoords;
|
|
var
|
|
q, xx, yy, gw: integer;
|
|
begin
|
|
fCurrentGridWidth := fGridWidth;
|
|
if fZoom <> 100 then
|
|
fCurrentGridWidth := CalcGridWidth();
|
|
|
|
gw := CalcGridWidth();
|
|
xx := 0;
|
|
yy := 0;
|
|
fVWidth := 0;
|
|
fVHeight := 0;
|
|
|
|
for q := 0 to fIEMBitmap.Count - 1 do
|
|
begin
|
|
with fIEMBitmap.GetImageInfo( q ) do
|
|
begin
|
|
if BiDiModeIsRTL() then
|
|
x := ( gw - xx - 1 ) * ThumbSizeInfo( itsOuter ).X
|
|
else
|
|
x := xx * ThumbSizeInfo( itsOuter ).X;
|
|
y := yy * ThumbSizeInfo( itsOuter ).Y;
|
|
if fDisplayMode = mdGrid then
|
|
begin
|
|
inc( x, imax( ThumbnailsOrigin.X, fHorizBorder ));
|
|
inc( y, imax( ThumbnailsOrigin.Y, fVertBorder ));
|
|
end;
|
|
row := yy;
|
|
col := xx;
|
|
if x > fVWidth then
|
|
fVWidth := x;
|
|
if y > fVHeight then
|
|
fVHeight := y;
|
|
end;
|
|
// calculates next position
|
|
inc(xx);
|
|
if ( fDisplayMode = mdSingle ) or ( xx = gw ) then
|
|
begin
|
|
// horizontal limit, clear column, go to next row
|
|
xx := 0;
|
|
inc(yy);
|
|
if fDisplayMode = mdSingle then
|
|
begin
|
|
// vertical limit, go back to top-left side
|
|
yy := 0;
|
|
xx := 0;
|
|
end;
|
|
end;
|
|
end;
|
|
inc( fVWidth, ThumbSizeInfo( itsOuter ).X );
|
|
inc( fVHeight, ThumbSizeInfo( itsOuter ).Y );
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.InsertImage
|
|
|
|
<FM>Declaration<FC>
|
|
procedure InsertImage(idx: integer);
|
|
procedure InsertImage(Idx : integer; Stream : TStream);
|
|
procedure InsertImage(Idx : integer; Bitmap : <A TIEBitmap>);
|
|
procedure InsertImage(Idx : integer; Bitmap : TBitmap);
|
|
procedure InsertImage(Idx : integer; Width, Height : integer; PixelFormat : <A TIEPixelFormat> = ie24RGB);
|
|
procedure InsertImage(Idx : integer; const FileName : string);
|
|
procedure InsertImage(const FileName: String;
|
|
LoadOnDemand : boolean;
|
|
DefaultTopText : <A TIEImageEnMViewDefaultText> = iedtNone;
|
|
DefaultInfoText : <A TIEImageEnMViewDefaultText> = iedtNone;
|
|
DefaultBottomText : <A TIEImageEnMViewDefaultText> = iedtFilename;
|
|
bSelectIt : Boolean = true);
|
|
|
|
<FM>Description<FN>
|
|
Inserts a new image at position, <FC>idx<FN> (0 is the first).
|
|
|
|
Note: First overload, InsertImage(idx: integer), doesn't create the bitmap.
|
|
|
|
The parameters for the final overload are as follows:
|
|
<TABLE>
|
|
<R> <H>Parameter</H> <H>Description</H> </R>
|
|
<R> <C><FC>Filename<FN></C> <C>A file or folder available on the system, or an HTTP or FTP link to a remote file</C> </R>
|
|
<R> <C><FC>LoadOnDemand<FN></C> <C>If True, the image will not be loaded from disk until it is displayed (i.e. when it is scrolled into view)</C> </R>
|
|
<R> <C><FC>DefaultTopText<FN></C> <C>Specify <L TIEImageEnMViewDefaultText>the text</L> that is applied to <A TImageEnMView.ImageTopText></C> </R>
|
|
<R> <C><FC>DefaultInfoText<FN></C> <C>Specify <L TIEImageEnMViewDefaultText>the text</L> that is applied to <A TImageEnMView.ImageInfoText></C> </R>
|
|
<R> <C><FC>DefaultBottomText<FN></C> <C>Specify <L TIEImageEnMViewDefaultText>the text</L> that is applied to <A TImageEnMView.ImageBottomText> (defaults to the filename)</C> </R>
|
|
<R> <C><FC>bSelectIt<FN></C> <C>The new image will be selected in the control</C> </R>
|
|
</TABLE>
|
|
|
|
<FM>Examples<FC>
|
|
ImageEnView1.IO.LoadFromFile('C:\000.tif');
|
|
ImageEnMView1.InsertImage(0);
|
|
ImageEnMView1.SetImage(0, ImageEnView1.Bitmap);
|
|
|
|
// Which is the same as...
|
|
ImageEnMView1.InsertImage(0, 'C:\000.tif');
|
|
|
|
// Insert 256 x 256 bitmap
|
|
ImageEnMView1.InsertImage(0, 256, 256, ie24RGB);
|
|
|
|
// Insert a file from the web
|
|
ImageEnMView1.InsertImage(0, 'http://www.imageen.com/graphics/imageen.gif');
|
|
|
|
// Show the first ten frames of a video file
|
|
for I := 0 to 9 do
|
|
ImageEnMView1.InsertImage( I, 'D:\Temp\Cement.avi' + IEM_Path_Index_Delimiter + IntToStr( I * 10 ));
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.InsertImageEx>
|
|
- <A TImageEnMView.AppendImage>
|
|
!!}
|
|
procedure TImageEnMView.InsertImage(idx: integer);
|
|
begin
|
|
if IEMBitmap_IsTIEDBMultiBitmap then
|
|
begin
|
|
fIEMBitmap.InsertImage( Idx );
|
|
exit;
|
|
end;
|
|
|
|
|
|
InsertImageEx(idx, imsAlways);
|
|
if assigned( fOnImageAdded ) then
|
|
fOnImageAdded( self, idx );
|
|
end;
|
|
|
|
procedure TImageEnMView.InsertImage(Idx : integer; Stream : TStream);
|
|
begin
|
|
if IEMBitmap_IsTIEDBMultiBitmap then
|
|
begin
|
|
fIEMBitmap.InsertImage( Idx, Stream );
|
|
exit;
|
|
end;
|
|
|
|
|
|
InsertImageEx(idx, imsAlways);
|
|
SetImageFromStream(Idx, Stream);
|
|
if assigned( fOnImageAdded ) then
|
|
fOnImageAdded( self, idx );
|
|
if assigned(fAnimation) then
|
|
fAnimation.RestartAnimation;
|
|
end;
|
|
|
|
procedure TImageEnMView.InsertImage(Idx : integer; Bitmap : TIEBitmap);
|
|
begin
|
|
if IEMBitmap_IsTIEDBMultiBitmap then
|
|
begin
|
|
fIEMBitmap.InsertImage( Idx, Bitmap );
|
|
exit;
|
|
end;
|
|
|
|
|
|
InsertImageEx(idx, imsAlways);
|
|
SetImage(Idx, Bitmap);
|
|
if assigned( fOnImageAdded ) then
|
|
fOnImageAdded( self, idx );
|
|
if assigned(fAnimation) then
|
|
fAnimation.RestartAnimation;
|
|
end;
|
|
|
|
procedure TImageEnMView.InsertImage(Idx : integer; Bitmap : TBitmap);
|
|
begin
|
|
if IEMBitmap_IsTIEDBMultiBitmap then
|
|
begin
|
|
fIEMBitmap.InsertImage( Idx, Bitmap );
|
|
exit;
|
|
end;
|
|
|
|
|
|
InsertImageEx(idx, imsAlways);
|
|
SetImage(Idx, Bitmap);
|
|
if assigned( fOnImageAdded ) then
|
|
fOnImageAdded( self, idx );
|
|
if assigned(fAnimation) then
|
|
fAnimation.RestartAnimation;
|
|
end;
|
|
|
|
procedure TImageEnMView.InsertImage(Idx : integer; Width, Height : integer; PixelFormat : TIEPixelFormat);
|
|
var
|
|
temp: TIEBitmap;
|
|
begin
|
|
if IEMBitmap_IsTIEDBMultiBitmap then
|
|
begin
|
|
fIEMBitmap.InsertImage( Idx, Width, Height, PixelFormat );
|
|
exit;
|
|
end;
|
|
|
|
|
|
InsertImageEx(idx, imsAlways);
|
|
temp := TIEBitmap.Create;
|
|
try
|
|
temp.Allocate(Width, Height, PixelFormat);
|
|
temp.Fill(clBlack);
|
|
SetImage(Idx, temp);
|
|
if assigned( fOnImageAdded ) then
|
|
fOnImageAdded( self, idx );
|
|
if assigned(fAnimation) then
|
|
fAnimation.RestartAnimation;
|
|
finally
|
|
temp.free;
|
|
end;
|
|
end;
|
|
|
|
procedure TImageEnMView.InsertImage(Idx : integer; const FileName : string);
|
|
begin
|
|
if IEMBitmap_IsTIEDBMultiBitmap then
|
|
begin
|
|
fIEMBitmap.InsertImage( Idx, FileName );
|
|
exit;
|
|
end;
|
|
|
|
|
|
InsertImageEx(idx, imsAlways);
|
|
// Load on demand
|
|
if Pos(IEM_Path_Index_Delimiter, Filename) > 0 then
|
|
ImageFileName[ Idx ] := FileName
|
|
else
|
|
SetImageFromFile(Idx, FileName);
|
|
if assigned( fOnImageAdded ) then
|
|
fOnImageAdded( self, idx );
|
|
if assigned(fAnimation) then
|
|
fAnimation.RestartAnimation;
|
|
end;
|
|
|
|
|
|
function StripShortcutExt(const sFilename : string) : string;
|
|
const
|
|
Windows_Shortcut_File_Ext = '.LNK';
|
|
var
|
|
iPos: Integer;
|
|
begin
|
|
Result := sFilename;
|
|
iPos := Pos(Windows_Shortcut_File_Ext, uppercase(Result));
|
|
if (iPos > 0) and (iPos = Length(Result) - Length(Windows_Shortcut_File_Ext) + 1) then
|
|
SetLength(Result, iPos - 1);
|
|
end;
|
|
|
|
|
|
function GetDisplayName(const sFilename : string; bStripShortcutExt : Boolean = False) : string;
|
|
begin
|
|
Result := IEExtractFileNameW( sFileName );
|
|
if bStripShortcutExt then
|
|
Result := StripShortcutExt( Result );
|
|
if Result = '' then
|
|
Result := sFileName // Drive?
|
|
{$ifdef VIDEO_THUMBNAILS}
|
|
else
|
|
if SameText( Result, IEF_Drives_Folder ) then
|
|
Result := IEGetMyComputerName;
|
|
{$endif}
|
|
end;
|
|
|
|
function ConstToIEMDefaultText(const value: WideString) : TIEImageEnMViewDefaultText;
|
|
begin
|
|
Result := iedtNone;
|
|
if (value = '') or (value[1] <> '$') then
|
|
exit;
|
|
|
|
if SameText(value, IEM_Filename) then
|
|
Result := iedtFilename
|
|
else
|
|
if SameText(value, IEM_FilenameNoExt) then
|
|
Result := iedtFilenameNoExt
|
|
else
|
|
if SameText(value, IEM_FilePath) then
|
|
Result := iedtFilePath
|
|
else
|
|
if SameText(value, IEM_ImageDimensions) then
|
|
Result := iedtImageDimensions
|
|
else
|
|
if SameText(value, IEM_ImageDimAndSize) then
|
|
Result := iedtImageDimAndSize
|
|
else
|
|
if SameText(value, IEM_FileSize) then
|
|
Result := iedtFileSize
|
|
else
|
|
if SameText(value, IEM_FileCreateDate) then
|
|
Result := iedtFileCreateDate
|
|
else
|
|
if SameText(value, IEM_FileCreateDateTime) then
|
|
Result := iedtFileCreateDateTime
|
|
else
|
|
if SameText(value, IEM_FileCreateDateAndSize) then
|
|
Result := iedtFileCreateDateAndSize
|
|
else
|
|
if SameText(value, IEM_FileEditDate) then
|
|
Result := iedtFileEditDate
|
|
else
|
|
if SameText(value, IEM_FileEditDateTime) then
|
|
Result := iedtFileEditDateTime
|
|
else
|
|
if SameText(value, IEM_FileEditDateAndSize) then
|
|
Result := iedtFileEditDateAndSize
|
|
else
|
|
if SameText(value, IEM_FileType) then
|
|
Result := iedtFileType
|
|
else
|
|
if SameText(value, IEM_FileExt) then
|
|
Result := iedtFileExt;
|
|
end;
|
|
|
|
|
|
function IEMDefaultTextToConst(DefaultText : TIEImageEnMViewDefaultText) : WideString;
|
|
begin
|
|
Result := '';
|
|
case DefaultText of
|
|
iedtFilename : Result := IEM_Filename ;
|
|
iedtFilenameNoExt : Result := IEM_FilenameNoExt ;
|
|
iedtFilePath : Result := IEM_FilePath ;
|
|
iedtImageDimensions : Result := IEM_ImageDimensions ;
|
|
iedtImageDimAndSize : Result := IEM_ImageDimAndSize ;
|
|
iedtFileSize : Result := IEM_FileSize ;
|
|
iedtFileCreateDate : Result := IEM_FileCreateDate ;
|
|
iedtFileCreateDateTime : Result := IEM_FileCreateDateTime ;
|
|
iedtFileCreateDateAndSize : Result := IEM_FileCreateDateAndSize;
|
|
iedtFileEditDate : Result := IEM_FileEditDate ;
|
|
iedtFileEditDateTime : Result := IEM_FileEditDateTime ;
|
|
iedtFileEditDateAndSize : Result := IEM_FileEditDateAndSize ;
|
|
iedtFileType : Result := IEM_FileType ;
|
|
iedtFileExt : Result := IEM_FileExt ;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TImageEnMView.InsertImage(Idx : integer; const FileName : string;
|
|
LoadOnDemand : boolean;
|
|
DefaultTopText : TIEImageEnMViewDefaultText = iedtNone;
|
|
DefaultInfoText : TIEImageEnMViewDefaultText = iedtNone;
|
|
DefaultBottomText : TIEImageEnMViewDefaultText = iedtFilename;
|
|
bSelectIt : Boolean = true);
|
|
begin
|
|
if bSelectIt then
|
|
InsertImageEx(Idx, imsAlways)
|
|
else
|
|
InsertImageEx(Idx, imsAuto);
|
|
|
|
ImageFileName[idx] := FileName;
|
|
if LoadOnDemand = False then
|
|
SetImageFromFile(Idx, FileName);
|
|
|
|
if DefaultTopText = iedtFilename then
|
|
ImageTopText[idx] := GetDisplayName( FileName, True )
|
|
else
|
|
ImageTopText[idx] := IEMDefaultTextToConst(DefaultTopText);
|
|
|
|
if DefaultInfoText = iedtFilename then
|
|
ImageInfoText[idx] := GetDisplayName( FileName, True )
|
|
else
|
|
ImageInfoText[idx] := IEMDefaultTextToConst(DefaultInfoText);
|
|
|
|
if DefaultBottomText = iedtFilename then
|
|
ImageBottomText[idx] := GetDisplayName( FileName, True )
|
|
else
|
|
ImageBottomText[idx] := IEMDefaultTextToConst(DefaultBottomText);
|
|
|
|
if assigned(fAnimation) then
|
|
fAnimation.RestartAnimation;
|
|
end;
|
|
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.InsertImageEx
|
|
|
|
<FM>Declaration<FC>
|
|
procedure InsertImageEx(idx: integer; SelectMode : <A TIEMSelectMode> = imsNever);
|
|
|
|
<FM>Description<FN>
|
|
InsertImageEx inserts a new image in position, <FC>idx<FN> (0 is the first).
|
|
|
|
Unlike <A TImageEnMView.InsertImage>, InsertImageEx doesn't create the bitmap. Also, you can configure whether the <L TIEMSelectMode>image is selected</L>.
|
|
|
|
<FM>Examples<FC>
|
|
ImageEnView1.IO.LoadFromFile('000.tif');
|
|
ImageEnMView1.InsertImageEx(0);
|
|
ImageEnMView1.SetImage(0, ImageEnView1.Bitmap);
|
|
|
|
// Append an image without selecting it
|
|
ImageEnMView1.InsertImageEx( ImageEnMView1.ImageCount, imsNever );
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.InsertImage>
|
|
- <A TImageEnMView.DeleteImage>
|
|
- <A TImageEnMView.AppendImage>
|
|
|
|
!!}
|
|
// Insert a new image
|
|
// idx is the index where to insert the new image
|
|
// If idx is equal to ImageCount it is added at the end
|
|
// The bitmap (Image[]) is created as "nil"
|
|
// The bitmap position is based on fHorizImages and fVertImages values
|
|
// calls Update
|
|
// The image is not selected
|
|
// disable player
|
|
procedure TImageEnMView.InsertImageEx(idx: integer; SelectMode : TIEMSelectMode = imsNever);
|
|
var
|
|
bAppend: Boolean;
|
|
begin
|
|
SetPlaying(false);
|
|
|
|
fIEMBitmap.InsertImage( idx );
|
|
|
|
if ( SelectMode = imsAlways ) or
|
|
(( SelectMode = imsAuto ) and (fSelectedItem < 0 )) then
|
|
SetSelectedItemNU(idx);
|
|
|
|
bAppend := idx >= GetImageCount;
|
|
if ( SelectMode <> imsNever ) and bAppend then
|
|
fPriorHSIDX := fSelectedItem;
|
|
|
|
if assigned(fOnCreateImage) then
|
|
fOnCreateImage(self, idx);
|
|
if ( fLockPaint = 0 ) and ( fLockUpdate = 0 ) and assigned( fAnimation ) then
|
|
fAnimation.InsertImage(idx);
|
|
|
|
CallBitmapChangeEvents;
|
|
fCheckedCount := -1;
|
|
UpdateEx(false, ( SelectMode <> imsNever ) and fSelectedImageAlwaysVisible );
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.InsertTransitionFrames
|
|
|
|
<FM>Declaration<FC>
|
|
procedure InsertTransitionFrames(Idx : integer; iFrameCount : integer; Effect : <A TIETransitionType>; iWidth : Integer = -1; iHeight : Integer = -1; BackgroundColor : TColor = -1; ResamplingFilter: <A TResampleFilter> = rfFastLinear);
|
|
|
|
<FM>Description<FN>
|
|
Create a series of transition frames from the image at <FC>Idx - 1<FN> to the image at <FC>Idx<FN> (and insert them at position <FC>Idx<FN>). If <FC>Idx<FN> = 0 then the transition is from a blank frame to the first image. If <FC>Idx<FN> = ImageCount then the transition is from the last image to a blank frame.
|
|
|
|
<TABLE>
|
|
<R> <H>Parameter</H> <H>Description</H> </R>
|
|
<R> <C><FC>Idx<FN></C> <C>The insertion position</C> </R>
|
|
<R> <C><FC>iFrameCount<FN></C> <C>The number of frames to insert</C> </R>
|
|
<R> <C><FC>Effect<FN></C> <C>The desired <L TIETransitionType>transition effect</L></C> </R>
|
|
<R> <C><FC>iWidth, iHeight<FN></C> <C>The size to create the transition bitmaps. If either of these are -1 then the size will be the larger of the two images in each dimension. Aspect Ratios will be maintained and any non-image area will be filled with <FC>BackgroundColor<FN>.</C> </R>
|
|
<R> <C><FC>BackgroundColor<FN></C> <C>The color that will be used for blank frames or non-image area (if -1 then <A TImageEnMView.Background> is used)</C> </R>
|
|
<R> <C><FC>ResamplingFilter<FN></C> <C>The <L TResampleFilter>algorithm</L> that is used to improve quality when resizing images</C> </R>
|
|
</TABLE>
|
|
|
|
Notes:
|
|
- Does not call <A TImageEnMView.OnCreateImage>
|
|
- Use <A TImageEnMView.InsertTransitionFramesEx> if you need to create frames for an iettPanZoom transition
|
|
- Cannot be used if a <A TIEDBMultiBitmap> is <L TImageEnMView.SetExternalMBitmap>attached to the control</L>
|
|
|
|
<FM>Demo<FN>
|
|
<TABLE2>
|
|
<R> <C_IMG_DEMO> <C>Demos\Multi\CreateTransitionFrames\CreateTransitionFrames.dpr </C> </R>
|
|
</TABLE>
|
|
|
|
<FM>Example<FC>
|
|
// Create ten frames that use a cross dissolve transition from image 5 to image 6
|
|
ImageEnMView1.InsertTransitionFrames(6, 10, iettCrossDissolve);
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.InsertTransitionFramesEx>
|
|
!!}
|
|
procedure TImageEnMView.InsertTransitionFrames(Idx : integer; iFrameCount : integer; Effect : TIETransitionType; iWidth : Integer = -1; iHeight : Integer = -1;
|
|
BackgroundColor : TColor = -1; ResamplingFilter: TResampleFilter = rfFastLinear);
|
|
begin
|
|
if IEMBitmap_IsTIEDBMultiBitmap then
|
|
raise EIEException.create('Not available when attached to TIEDBMultiBitmap');
|
|
|
|
LockPaint;
|
|
try
|
|
TIEMultiBitmap( fIEMBitmap ).InsertTransitionFrames(Idx, iFrameCount, Effect, iWidth, iHeight, BackgroundColor, ResamplingFilter);
|
|
finally
|
|
UnLockPaint;
|
|
Update;
|
|
end;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.InsertTransitionFramesEx
|
|
|
|
<FM>Declaration<FC>
|
|
procedure InsertTransitionFramesEx(Idx : Integer; iFrameCount : Integer; Effect : <A TIETransitionType>;
|
|
StartRect, EndRect : TRect; RectMaintainAspectRatio : boolean = True;
|
|
iWidth : Integer = -1; iHeight : Integer = -1; bStretchSmall : Boolean = False;
|
|
BackgroundColor : TColor = -1; ResamplingFilter : <A TResampleFilter>;
|
|
Smoothing: Integer = 96; Timing : <A TIETransitionTiming> = iettLinear);
|
|
|
|
|
|
<FM>Description<FN>
|
|
This is an extended version of <A TImageEnMView.InsertTransitionFrames> that includes more parameters and is primarily used when you need to create a series of frames that show a Pan Zoom from <FC>StartRect<FN> to <FC>EndRect<FN> for the image specified at <FC>Idx - 1<FN>.
|
|
|
|
<TABLE>
|
|
<R> <H>Parameter</H> <H>Description</H> </R>
|
|
<R> <C><FC>Idx<FN></C> <C>The insertion position</C> </R>
|
|
<R> <C><FC>iFrameCount<FN></C> <C>The number of frames to insert</C> </R>
|
|
<R> <C><FC>Effect<FN></C> <C>The desired <L TIETransitionType>transition effect</L></C> </R>
|
|
<R> <C><FC>StartRect<FN></C> <C>When using an iettPanZoom effect this is the portion of the image that is shown at the start</C> </R>
|
|
<R> <C><FC>EndRect<FN></C> <C>When using an iettPanZoom effect this is the portion of the image that is shown at the end</C> </R>
|
|
<R> <C><FC>RectMaintainAspectRatio<FN></C> <C>ImageEn will ensure that the starting and ending rects are automatically adjusted to ensure the resultant image has the correct aspect ratio (iettPanZoom only)</C> </R>
|
|
<R> <C><FC>iWidth, iHeight<FN></C> <C>The size to create the transition bitmaps. If either of these are -1 then the size will be the larger of the two images in each dimension. Aspect Ratios will be maintained and any non-image area will be filled with <FC>BackgroundColor<FN>.</C> </R>
|
|
<R> <C><FC>bStretchSmall<FN></C> <C>If the images are smaller than the transition bitmap size (<FC>iWidth<FN> x <FC>iHeight<FN>) should they be stretched to fit (which can lead to distortion).</C> </R>
|
|
<R> <C><FC>BackgroundColor<FN></C> <C>The color that will be used for blank frames or non-image area (if -1 then <A TImageEnMView.Background> is used)</C> </R>
|
|
<R> <C><FC>ResamplingFilter<FN></C> <C>The <L TResampleFilter>algorithm</L> that is used to improve quality when resizing images</C> </R>
|
|
<R> <C><FC>Timing<FN></C> <C>The <L TIETransitionTiming>rate</L> at which the transition progresses</C> </R>
|
|
<R> <C><FC>Smoothing<FN></C> <C>In order to reduce the "jumpiness" of pan zoom effects, transition frames are alpha blended. A low value will improve smoothness, but increase blurriness. A high value will improve clarity, but increase jumpiness. Typical range is 64 - 196. 255 means no alpha blending</C> </R>
|
|
</TABLE>
|
|
|
|
Notes:
|
|
- Does not call <A TImageEnMView.OnCreateImage>
|
|
- Cannot be used if a <A TIEDBMultiBitmap> is <L TImageEnMView.SetExternalMBitmap>attached to the control</L>
|
|
|
|
<FM>Example<FC>
|
|
// Create ten Pan Zoom frames for the image at index 5
|
|
|
|
// Top Left corner of image
|
|
StartingRect := Rect(0, 0, ImageEnMView1.ImageWidth[5] div 4, ImageEnMView1.ImageHeight[5] div 4);
|
|
|
|
// Bottom right corner of image
|
|
EndingRect := Rect(MulDiv(ImageEnMView1.ImageWidth[5], 3, 4), MulDiv(ImageEnMView1.ImageHeight[5], 3, 4), ImageEnMView1.ImageWidth[5], ImageEnMView1.ImageHeight[5]);
|
|
|
|
// Create frames
|
|
ImageEnMView1.InsertTransitionFramesEx(5, 10, iettPanZoom, StartRect, EndRect);
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.InsertTransitionFrames>
|
|
|
|
!!}
|
|
procedure TImageEnMView.InsertTransitionFramesEx(Idx : integer; iFrameCount : Integer; Effect : TIETransitionType;
|
|
StartRect, EndRect : TRect; RectMaintainAspectRatio : boolean = True;
|
|
iWidth : Integer = -1; iHeight : Integer = -1; bStretchSmall : Boolean = False;
|
|
BackgroundColor : TColor = -1; ResamplingFilter: TResampleFilter = rfFastLinear;
|
|
Smoothing: Integer = 96; Timing : TIETransitionTiming = iettLinear);
|
|
begin
|
|
if IEMBitmap_IsTIEDBMultiBitmap then
|
|
raise EIEException.create('Not available when attached to TIEDBMultiBitmap');
|
|
|
|
LockPaint;
|
|
try
|
|
TIEMultiBitmap( fIEMBitmap ).InsertTransitionFramesEx( Idx, iFrameCount, Effect, StartRect, EndRect, RectMaintainAspectRatio,
|
|
iWidth, iHeight, bStretchSmall, BackgroundColor, ResamplingFilter,
|
|
Smoothing, Timing);
|
|
finally
|
|
UnLockPaint;
|
|
Update;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.AppendImage
|
|
|
|
<FM>Declaration<FC>
|
|
function AppendImage: Integer;
|
|
function AppendImage(Stream: TStream): integer;
|
|
function AppendImage(Bitmap: <A TIEBitmap>): integer;
|
|
function AppendImage(Bitmap : TBitmap): integer;
|
|
function AppendImage(Width, Height: Integer; PixelFormat: <A TIEPixelFormat> = ie24RGB): Integer;
|
|
function AppendImage(const FileName: String): integer;
|
|
function AppendImage(const FileName: String;
|
|
LoadOnDemand : boolean;
|
|
DefaultTopText : <A TIEImageEnMViewDefaultText> = iedtNone;
|
|
DefaultInfoText : <A TIEImageEnMViewDefaultText> = iedtNone;
|
|
DefaultBottomText : <A TIEImageEnMViewDefaultText> = iedtFilename;
|
|
bSelectIt : Boolean = true): integer;
|
|
|
|
<FM>Description<FN>
|
|
AppendImage appends a new image at last position in the list and returns the new image position.
|
|
|
|
Note: First overload of AppendImage doesn't create the bitmap. Others load image from a file or a stream.
|
|
|
|
The parameters for the final overload are as follows:
|
|
<TABLE>
|
|
<R> <H>Parameter</H> <H>Description</H> </R>
|
|
<R> <C><FC>Filename<FN></C> <C>A file or folder available on the system, or an HTTP or FTP link to a remote file. You can load a particular frame from a multi-frame image or video by delimiting it with <FC>IEM_Path_Index_Delimiter<FN> </C> </R>
|
|
<R> <C><FC>LoadOnDemand<FN></C> <C>If True, the image will not be loaded from disk until it is displayed (i.e. when it is scrolled into view)</C> </R>
|
|
<R> <C><FC>DefaultTopText<FN></C> <C>Specify <L TIEImageEnMViewDefaultText>the text</L> that is applied to <A TImageEnMView.ImageTopText></C> </R>
|
|
<R> <C><FC>DefaultInfoText<FN></C> <C>Specify <L TIEImageEnMViewDefaultText>the text</L> that is applied to <A TImageEnMView.ImageInfoText></C> </R>
|
|
<R> <C><FC>DefaultBottomText<FN></C> <C>Specify <L TIEImageEnMViewDefaultText>the text</L> that is applied to <A TImageEnMView.ImageBottomText> (defaults to the filename)</C> </R>
|
|
<R> <C><FC>bSelectIt<FN></C> <C>The new image will be selected in the control</C> </R>
|
|
</TABLE>
|
|
|
|
<FM>Examples<FC>
|
|
ImageEnView1.IO.LoadFromFile( 'C:\MyImage.tif' );
|
|
idx := ImageEnMView1.AppendImage;
|
|
ImageEnMView1.SetImage( idx, ImageEnView1.Bitmap );
|
|
|
|
// Which is the same as...
|
|
ImageEnMView1.AppendImage( 'C:\MyImage.tif' );
|
|
|
|
// Load the fifth image of MyImage.tif
|
|
ImageEnMView1.AppendImage( 'C:\MyImage.tif' + IEM_Path_Index_Delimiter + 4 );
|
|
|
|
// Append 256 x 256 bitmap
|
|
ImageEnMView1.AppendImage( 256, 256, ie24RGB );
|
|
|
|
// Append a file from the web
|
|
ImageEnMView1.AppendImage( 'http://www.imageen.com/graphics/imageen.gif' );
|
|
|
|
// Show ten frames of a video file
|
|
for I := 0 to 9 do
|
|
ImageEnMView1.AppendImage( 'D:\Temp\Cement.avi' + IEM_Path_Index_Delimiter + IntToStr( I * 10 ));
|
|
|
|
// Append all pages of a TIFF to the current content
|
|
iPageCount := EnumTIFFIm( sFileName );
|
|
for I := 0 to iPageCount - 1 do
|
|
ImageEnMView1.AppendImage( sFileName + IEM_Path_Index_Delimiter + IntToStr( I ));
|
|
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.InsertImage>
|
|
- <A TImageEnMView.InsertImageEx>
|
|
!!}
|
|
function TImageEnMView.AppendImage(): integer;
|
|
begin
|
|
result := fIEMBitmap.Count;
|
|
InsertImage( result );
|
|
end;
|
|
|
|
function TImageEnMView.AppendImage(Stream: TStream): integer;
|
|
begin
|
|
result := fIEMBitmap.Count;
|
|
InsertImage(Result, Stream);
|
|
end;
|
|
|
|
function TImageEnMView.AppendImage(Bitmap: TIEBitmap): integer;
|
|
begin
|
|
result := fIEMBitmap.Count;
|
|
InsertImage(Result, Bitmap);
|
|
end;
|
|
|
|
function TImageEnMView.AppendImage(Bitmap : TBitmap): integer;
|
|
begin
|
|
result := fIEMBitmap.Count;
|
|
InsertImage(Result, Bitmap);
|
|
end;
|
|
|
|
function TImageEnMView.AppendImage(Width, Height: Integer; PixelFormat: TIEPixelFormat): Integer;
|
|
begin
|
|
result := fIEMBitmap.Count;
|
|
InsertImage(Result, Width, Height, PixelFormat);
|
|
end;
|
|
|
|
function TImageEnMView.AppendImage(const FileName: String): integer;
|
|
begin
|
|
result := fIEMBitmap.Count;
|
|
InsertImage(result, FileName);
|
|
end;
|
|
|
|
function TImageEnMView.AppendImage(const FileName: String;
|
|
LoadOnDemand : boolean;
|
|
DefaultTopText : TIEImageEnMViewDefaultText = iedtNone;
|
|
DefaultInfoText : TIEImageEnMViewDefaultText = iedtNone;
|
|
DefaultBottomText : TIEImageEnMViewDefaultText = iedtFilename;
|
|
bSelectIt : Boolean = true): integer;
|
|
begin
|
|
result := fIEMBitmap.Count;
|
|
InsertImage(result, FileName, LoadOnDemand, DefaultTopText, DefaultInfoText, DefaultBottomText, bSelectIt);
|
|
end;
|
|
|
|
|
|
|
|
{$ifdef IEIncludeDeprecatedInV5}
|
|
// Deprecated in 6.0.0 (2014-11-11)
|
|
function TImageEnMView.AppendImage2(Width, Height: Integer; PixelFormat: TIEPixelFormat): Integer;
|
|
begin
|
|
result := AppendImage(Width, Height, PixelFormat);
|
|
end;
|
|
{$endif}
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.AppendSplit
|
|
|
|
<FM>Declaration<FC>
|
|
function AppendSplit(SourceGrid: <A TIEBitmap>; cellWidth: Integer; cellHeight: Integer; maxCount: Integer = 0): Integer;
|
|
|
|
<FM>Description<FN>
|
|
Splits the source image into cells of the specified size and adds each cell to the TImageEnMView
|
|
|
|
Result is the count of added images.
|
|
|
|
<TABLE>
|
|
<R> <H>Parameter</H> <H>Description</H> </R>
|
|
<R> <C><FC>SourceGrid<FN></C> <C>Source bitmap containing cells to split.</C> </R>
|
|
<R> <C><FC>cellWidth<FN></C> <C>Width of a cell.</C> </R>
|
|
<R> <C><FC>cellHeight<FN></C> <C>Height of a cell.</C> </R>
|
|
<R> <C><FC>maxCount<FN></C> <C>Maximum number of cells to add. 0 = all suitable cells.</C> </R>
|
|
</TABLE>
|
|
!!}
|
|
function TImageEnMView.AppendSplit(SourceGrid: TIEBitmap; cellWidth: Integer; cellHeight: Integer; maxCount: Integer): Integer;
|
|
var
|
|
x, y: Integer;
|
|
idx: Integer;
|
|
begin
|
|
result := 0;
|
|
y := 0;
|
|
while y < SourceGrid.Height do
|
|
begin
|
|
x := 0;
|
|
while x < SourceGrid.Width do
|
|
begin
|
|
idx := AppendImage;
|
|
SetImageRect( idx, SourceGrid, x, y, x + cellWidth - 1, y + cellHeight - 1 );
|
|
inc(result);
|
|
if (maxCount>0) and (maxCount=result) then
|
|
exit;
|
|
inc(x, cellWidth);
|
|
end;
|
|
inc(y, cellHeight);
|
|
end;
|
|
end;
|
|
|
|
|
|
// Delete image idx
|
|
// doesn't call Update
|
|
// Return true if image correctly deleted
|
|
// Disable playing
|
|
// use bBatchProcessing = True if this is being called by DeleteAllImages
|
|
function TImageEnMView.DeleteImageNU(idx: integer; bBatchProcessing : Boolean = False): boolean;
|
|
var
|
|
psel: integer;
|
|
begin
|
|
result := false;
|
|
SetPlaying(false);
|
|
if (idx >= 0) and (idx < fIEMBitmap.Count) then
|
|
begin
|
|
AbortImageLoading(idx);
|
|
|
|
psel := fSelectedItem;
|
|
if bBatchProcessing = False then
|
|
DeselectNU;
|
|
|
|
if assigned(fOnDestroyImage) then
|
|
fOnDestroyImage(self, idx);
|
|
|
|
if fIEMBitmap.GetImageInfo( idx ).image <> nil then
|
|
ClearImageCache(idx);
|
|
|
|
fIEMBitmap.DeleteImage( idx );
|
|
|
|
if bBatchProcessing = False then
|
|
begin
|
|
if (psel = idx) and (idx >= fIEMBitmap.Count) then
|
|
SetSelectedItemNU(fIEMBitmap.Count - 1)
|
|
else
|
|
if psel > idx then
|
|
SetSelectedItemNU(psel - 1)
|
|
else
|
|
SetSelectedItemNU(psel);
|
|
|
|
if ( fLockPaint = 0 ) and ( fLockUpdate = 0 ) and assigned( fAnimation ) then
|
|
fAnimation.DeleteImage(idx);
|
|
end;
|
|
|
|
CallBitmapChangeEvents;
|
|
fCheckedCount := -1;
|
|
result := true;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TImageEnMView.DeleteAllImages();
|
|
var
|
|
idx: integer;
|
|
begin
|
|
SetPlaying(false);
|
|
DeselectNU();
|
|
for idx := fIEMBitmap.Count - 1 downto 0 do
|
|
DeleteImageNU(idx, True);
|
|
fPriorHSIDX := 0;
|
|
end;
|
|
|
|
function ComparePointers(Item1, Item2: Pointer): Integer;
|
|
begin
|
|
result := NativeInt(Item1) - NativeInt(Item2);
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.DeleteSelectedImages
|
|
|
|
<FM>Declaration<FC>
|
|
procedure DeleteSelectedImages;
|
|
|
|
<FM>Description<FN>
|
|
Removes all selected images.
|
|
!!}
|
|
procedure TImageEnMView.DeleteSelectedImages;
|
|
var
|
|
q: integer;
|
|
cp: array of integer;
|
|
begin
|
|
if DisplayMode = mdSingle then
|
|
DeleteImageNU(VisibleFrame)
|
|
else
|
|
if EnableMultiSelect = False then
|
|
DeleteImageNU(SelectedImage)
|
|
else
|
|
begin
|
|
MultiSelectSortList;
|
|
SetLength(cp, fMultiSelectedImages.Count);
|
|
for q := 0 to fMultiSelectedImages.Count - 1 do
|
|
cp[q] := integer(fMultiSelectedImages[q]);
|
|
for q := length(cp) - 1 downto 0 do
|
|
DeleteImageNU(cp[q]);
|
|
end;
|
|
UpdateEx(false, fSelectedImageAlwaysVisible);
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.DeleteImage
|
|
|
|
<FM>Declaration<FC>
|
|
procedure DeleteImage(idx: integer);
|
|
|
|
<FM>Description<FN>
|
|
Deletes image, <FC>idx<FN> (freeing its associated bitmap).
|
|
!!}
|
|
procedure TImageEnMView.DeleteImage(idx: integer);
|
|
begin
|
|
if DeleteImageNU(idx) then
|
|
UpdateEx(false, fSelectedImageAlwaysVisible);
|
|
end;
|
|
|
|
// This method is called whenever the zoom or viewx/y changes.
|
|
procedure TImageEnMView.ViewChange(c: integer);
|
|
begin
|
|
if assigned(fOnViewChange) and fUserAction then
|
|
fOnViewChange(self, c);
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.Update
|
|
|
|
<FM>Declaration<FC>
|
|
procedure Update;
|
|
|
|
<FM>Description<FN>
|
|
Updates the display to show the current content and properties.
|
|
!!}
|
|
procedure TImageEnMView.Update;
|
|
begin
|
|
if assigned(fAnimation) then
|
|
fAnimation.ImageCount := ImageCount;
|
|
UpdateEx(true);
|
|
end;
|
|
|
|
procedure TImageEnMView.UpdateEx(bUpdateCache: Boolean; bRespositionSelection : Boolean = False);
|
|
var
|
|
max_x, max_y, i: integer;
|
|
lClientWidth, lClientHeight: integer;
|
|
bb: boolean;
|
|
begin
|
|
if (fLockPaint > 0) or (fLockUpdate > 0) then
|
|
exit;
|
|
if fUpdating then
|
|
exit;
|
|
if fDestroying then
|
|
exit;
|
|
if not HandleAllocated then
|
|
exit;
|
|
if (ComponentState <> []) and (ComponentState <> [csDesigning]) and (ComponentState <> [csFreeNotification]) then
|
|
exit;
|
|
if (GetParentForm(self) = nil) and (ParentWindow = 0) then
|
|
exit;
|
|
|
|
if not (csDesigning in ComponentState) then
|
|
begin
|
|
fUpdating := true;
|
|
if bUpdateCache then
|
|
ClearCache;
|
|
UpdateCoords;
|
|
for i := 0 to 8 do
|
|
begin
|
|
lClientWidth := ClientWidth;
|
|
lClientHeight := ClientHeight;
|
|
bb := false;
|
|
GetMaxViewXY(max_x, max_y);
|
|
if fViewX > max_x then
|
|
begin
|
|
fViewX := max_x;
|
|
bb := true;
|
|
end;
|
|
if fViewY > max_y then
|
|
begin
|
|
fViewY := max_y;
|
|
bb := true;
|
|
end;
|
|
if bb then
|
|
ViewChange(0);
|
|
try
|
|
if ((fScrollBars = ssHorizontal) or (fScrollBars = ssBoth)) and not assigned(fAnimation) then
|
|
begin
|
|
if (max_x > 0) then
|
|
begin
|
|
fRXScroll := (max_x + ClientWidth - 1) / 65536;
|
|
IESetScrollBar(Handle, SB_HORZ, 0, 65535, trunc(ClientWidth / fRXScroll), trunc(fViewX / fRXScroll), true, fFlatScrollBars);
|
|
IEEnableScrollBar(Handle, SB_HORZ, ESB_ENABLE_BOTH, fFlatScrollBars);
|
|
IEShowScrollBar(handle, SB_HORZ, true, fFlatScrollBars);
|
|
end
|
|
else
|
|
if fScrollBarsAlwaysVisible then
|
|
begin
|
|
IEEnableScrollBar(Handle, SB_HORZ, ESB_DISABLE_BOTH, fFlatScrollBars);
|
|
IEShowScrollBar(handle, SB_HORZ, true, fFlatScrollBars);
|
|
end
|
|
else
|
|
IEShowScrollBar(handle, SB_HORZ, false, fFlatScrollBars);
|
|
end;
|
|
if (fScrollBars = ssVertical) or (fScrollBars = ssBoth) and not assigned(fAnimation) then
|
|
begin
|
|
if (max_y > 0) then
|
|
begin
|
|
fRYScroll := (max_y + ClientHeight - 1) / 65536;
|
|
IESetScrollBar(Handle, SB_VERT, 0, 65535, trunc(ClientHeight / fRYScroll), trunc(fViewY / fRYScroll), true, fFlatScrollBars);
|
|
IEEnableScrollBar(Handle, SB_VERT, ESB_ENABLE_BOTH, fFlatScrollBars);
|
|
IEShowScrollBar(handle, SB_VERT, true, fFlatScrollBars);
|
|
end
|
|
else
|
|
if fScrollBarsAlwaysVisible then
|
|
begin
|
|
IEEnableScrollBar(Handle, SB_VERT, ESB_DISABLE_BOTH, fFlatScrollBars);
|
|
IEShowScrollBar(handle, SB_VERT, true, fFlatScrollBars);
|
|
end
|
|
else
|
|
IEShowScrollBar(handle, SB_VERT, false, fFlatScrollBars);
|
|
end;
|
|
except
|
|
end;
|
|
if (lClientWidth = ClientWidth) and (lClientHeight = ClientHeight) then
|
|
break; // exit from for loop (no other adjustments necessary)
|
|
end;
|
|
|
|
if assigned(fAnimation) then
|
|
begin
|
|
fAnimation.ViewWidth := ClientWidth;
|
|
fAnimation.ViewHeight := ClientHeight;
|
|
fAnimation.CurrentImage := SelectedImage;
|
|
end;
|
|
|
|
CallBitmapChangeEvents;
|
|
fUpdating := false;
|
|
end;
|
|
if bRespositionSelection then
|
|
CheckSelectedImageIsVisible;
|
|
invalidate;
|
|
redrawwindow(handle, nil, 0, RDW_FRAME or RDW_INVALIDATE or RDW_ALLCHILDREN);
|
|
end;
|
|
|
|
function TImageEnMView.PaletteChanged(Foreground: Boolean): Boolean;
|
|
begin
|
|
{$IFNDEF OCXVERSION}
|
|
if assigned(application) and assigned(application.mainform) and assigned(application.mainform.canvas) then
|
|
begin
|
|
if IEDrawDibRealize(fHDrawDib, application.mainform.canvas.handle, false) > 0 then
|
|
invalidate;
|
|
end
|
|
else
|
|
invalidate;
|
|
{$ELSE}
|
|
invalidate;
|
|
{$ENDIF}
|
|
result := true;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.Background
|
|
|
|
<FM>Declaration<FC>
|
|
property Background: TColor;
|
|
|
|
<FM>Description<FN>
|
|
Specifies the background color of the component.
|
|
|
|
Note: This value may be overridden if <A TIEImageEnGlobalSettings.EnableTheming> is enabled.
|
|
|
|
TImageEnMView Default: clBtnFace
|
|
TImageEnFolderMView Default: clWindow
|
|
!!}
|
|
procedure TImageEnMView.SetBackground(cl: TColor);
|
|
begin
|
|
inherited SetBackground(cl);
|
|
fIEMBitmap.fBackground := cl;
|
|
Update;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.SetImageEx
|
|
|
|
<FM>Declaration<FC>
|
|
procedure SetImageEx(idx: Integer; srcImage: TBitmap);
|
|
|
|
<FM>Description<FN>
|
|
Sets the image assigned to index, <FC>idx<FN>. The <FC>srcImage<FN> bitmap is copied internally; therefore you can free <FC>srcImage<FN> after calling SetImageEx.
|
|
|
|
SetImageEx doesn't call <A TImageEnMView.Update> (the only difference from <A TImageEnMView.SetImage>).
|
|
|
|
<FM>Example<FC>
|
|
ImageEnView1.IO.LoadFromFile('000.tif');
|
|
ImageEnMView1.InsertImageEx(0);
|
|
ImageEnMView1.SetImageEx(0, ImageEnView1.Bitmap);
|
|
ImageEnMView1.Update; // not needed for SetImage()
|
|
|
|
!!}
|
|
procedure TImageEnMView.SetImageEx(idx: integer; srcImage: TBitmap);
|
|
var
|
|
tbmp: TIEBitmap;
|
|
begin
|
|
if IEMBitmap_IsTIEDBMultiBitmap then
|
|
begin
|
|
fIEMBitmap.SetImage( idx, srcImage );
|
|
exit;
|
|
end;
|
|
|
|
|
|
if srcImage <> nil then
|
|
begin
|
|
tbmp := TIEBitmap.Create;
|
|
try
|
|
tbmp.EncapsulateTBitmap(srcImage, true);
|
|
SetIEBitmapEx(idx, tbmp);
|
|
finally
|
|
FreeAndNil(tbmp);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
// SetIEBitmapEx creates a new copy of "srcImage" (then srcImage can be freed)
|
|
// Doesn't call Update
|
|
procedure TImageEnMView.SetIEBitmapEx(idx: integer; srcImage: TIEBaseBitmap);
|
|
var
|
|
bmp: TIEBitmap;
|
|
ww, hh: integer;
|
|
wDummy, hDummy : integer;
|
|
bDoResample: Boolean;
|
|
begin
|
|
if srcImage <> nil then
|
|
begin
|
|
if (idx > -1) and (idx < fIEMBitmap.Count) then
|
|
begin
|
|
if fIEMBitmap.GetImageInfo( idx ).image <> nil then
|
|
begin
|
|
fIEMBitmap.fImageList.Delete(fIEMBitmap.GetImageInfo( idx ).image);
|
|
ClearImageCache(idx);
|
|
end;
|
|
|
|
if (fStoreType = ietThumb) and (GetEnableResamplingOnMinor or ( srcImage.Width > ThumbSizeInfo( itsImage ).X ) or ( srcImage.Height > ThumbSizeInfo( itsImage ).Y )) then
|
|
begin
|
|
if (srcImage.Width = 0) or (srcImage.Height = 0) then
|
|
begin
|
|
ww := ThumbSizeInfo( itsImage ).X;
|
|
hh := ThumbSizeInfo( itsImage ).Y;
|
|
end
|
|
else
|
|
begin
|
|
IEGetFitResampleSizeWithAutoCrop(srcImage.width, srcImage.height, ThumbSizeInfo( itsImage ).X, ThumbSizeInfo( itsImage ).Y, wDummy, hDummy, fThumbnailClipping, ww, hh);
|
|
end;
|
|
|
|
if GetEnableResamplingOnMinor then
|
|
bDoResample := (srcImage.Width <> ww) or (srcImage.Height <> hh)
|
|
else
|
|
bDoResample := (srcImage.Width > ww) or (srcImage.Height > hh);
|
|
|
|
if bDoResample and (srcImage.Width > 0) and (srcImage.Height > 0) then
|
|
begin
|
|
bmp := TIEBitmap.Create;
|
|
try
|
|
bmp.allocate(ww, hh, ie24RGB);
|
|
|
|
if (srcImage is TIEBitmap) and (srcImage as TIEBitmap).HasAlphaChannel then
|
|
_IESetAlpha0Color(srcImage as TIEBitmap, CreateRGB(128, 128, 128));
|
|
if srcImage.pixelformat = ie1g then
|
|
begin
|
|
_SubResample1bitFilteredEx(srcImage, 0, 0, srcImage.width - 1, srcImage.height - 1, bmp)
|
|
end
|
|
else
|
|
begin
|
|
if srcImage.PixelFormat <> ie24RGB then
|
|
begin
|
|
bmp.PixelFormat := srcImage.PixelFormat;
|
|
_IEBmpStretchEx(srcImage, bmp, nil, nil);
|
|
end
|
|
else
|
|
if (fThumbnailResampleFilter = rfNone) then
|
|
begin
|
|
bmp.PixelFormat := srcImage.PixelFormat;
|
|
_IEBmpStretchEx(srcImage, bmp, nil, nil);
|
|
end
|
|
else
|
|
_ResampleEx(srcImage, bmp, nil, fThumbnailResampleFilter, nil, nil);
|
|
end;
|
|
|
|
if (srcImage is TIEBitmap) and (srcImage as TIEBitmap).HasAlphaChannel then
|
|
begin
|
|
if fThumbnailResampleFilter = rfNone then
|
|
_Resampleie8g((srcImage as TIEBitmap).AlphaChannel, bmp.AlphaChannel, rfFastLinear)
|
|
else
|
|
_Resampleie8g((srcImage as TIEBitmap).AlphaChannel, bmp.AlphaChannel, fThumbnailResampleFilter);
|
|
bmp.AlphaChannel.Full := (srcImage as TIEBitmap).AlphaChannel.Full;
|
|
end;
|
|
|
|
fIEMBitmap.GetImageInfo( idx ).image := fIEMBitmap.fImageList.AddIEBitmap(bmp);
|
|
finally
|
|
FreeAndNil(bmp);
|
|
end;
|
|
end
|
|
else
|
|
fIEMBitmap.GetImageInfo( idx ).image := fIEMBitmap.fImageList.AddIEBitmap(srcImage);
|
|
|
|
end
|
|
else
|
|
begin
|
|
fIEMBitmap.GetImageInfo( idx ).image := fIEMBitmap.fImageList.AddIEBitmapNoMap(srcImage);
|
|
end;
|
|
fIEMBitmap.fImageList.SetImageOriginalWidth(fIEMBitmap.GetImageInfo( idx ).image, srcImage.Width);
|
|
fIEMBitmap.fImageList.SetImageOriginalHeight(fIEMBitmap.GetImageInfo( idx ).image, srcImage.Height);
|
|
end;
|
|
|
|
if idx = fSelectedItem then
|
|
begin
|
|
fSelectedBitmap := nil;
|
|
CallBitmapChangeEvents;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.SetImage
|
|
|
|
<FM>Declaration<FC>
|
|
procedure SetImage(idx: Integer; srcImage: <A TIEBaseBitmap>); overload;
|
|
procedure SetImage(idx: Integer; srcImage: TBitmap); overload;
|
|
procedure SetImage(idx: Integer; width, height: Integer; PixelFormat: <A TIEPixelFormat>); overload;
|
|
|
|
<FM>Description<FN>
|
|
Sets the image assigned to index, <FC>idx<FN>. The <FC>srcImage<FN> bitmap is copied internally; therefore you can free <FC>srcImage<FN> after calling SetImage.
|
|
|
|
<FM>Example<FC>
|
|
ImageEnView1.IO.LoadFromFile('000.tif');
|
|
ImageEnMView1.InsertImageEx(0);
|
|
ImageEnMView1.SetImage(0, ImageEnView1.IEBitmap);
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.SetImageFromFile>
|
|
- <A TImageEnMView.SetImageFromStream>
|
|
!!}
|
|
procedure TImageEnMView.SetImage(idx: Integer; srcImage: TBitmap);
|
|
begin
|
|
SetImageEx(idx, srcImage);
|
|
ClearImageCache(idx);
|
|
UpdateEx(false);
|
|
end;
|
|
|
|
procedure TImageEnMView.SetImage(idx: Integer; width, height: Integer; PixelFormat: TIEPixelFormat);
|
|
var
|
|
temp: TIEBitmap;
|
|
begin
|
|
temp := TIEBitmap.Create(Width, Height, PixelFormat);
|
|
try
|
|
SetImage( idx, temp );
|
|
finally
|
|
temp.free;
|
|
end;
|
|
end;
|
|
|
|
procedure TImageEnMView.SetImage(idx: integer; srcImage: TIEBaseBitmap);
|
|
begin
|
|
if IEMBitmap_IsTIEDBMultiBitmap then
|
|
begin
|
|
fIEMBitmap.SetImage( idx, srcImage );
|
|
exit;
|
|
end;
|
|
|
|
|
|
if srcImage <> nil then
|
|
begin
|
|
SetIEBitmapEx(idx, srcImage);
|
|
ClearImageCache(idx);
|
|
UpdateEx(false);
|
|
end;
|
|
end;
|
|
|
|
|
|
{$ifdef IEIncludeDeprecatedInV6}
|
|
// Deprecated in 6.2.0 (2015-08-24)
|
|
procedure TImageEnMView.SetIEBitmap(idx: integer; srcImage: TIEBaseBitmap);
|
|
begin
|
|
SetImage( idx, srcImage );
|
|
end;
|
|
{$endif}
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.SetImageRect
|
|
|
|
<FM>Declaration<FC>
|
|
procedure SetImageRect(idx: Integer; srcImage: TBitmap; x1, y1, x2, y2: Integer);
|
|
procedure SetImageRect(idx: Integer; srcImage: <A TIEBitmap>; x1, y1, x2, y2: Integer);
|
|
|
|
<FM>Description<FN>
|
|
Sets the image assigned to index, <FC>idx<FN>.
|
|
|
|
The rectangle <FC>x1, y1, x2, y2<FN> of <FC>srcImage<FN> bitmap is copied internally. After calling SetImageRect you can free the <FC>srcImage<FN> bitmap.
|
|
!!}
|
|
// creates a new copy of "srcImage" (then srcImage can be freed)
|
|
procedure TImageEnMView.SetImageRect(idx: integer; srcImage: TBitmap; x1, y1, x2, y2: integer);
|
|
begin
|
|
if idx < fIEMBitmap.Count then
|
|
begin
|
|
x1 := imin(srcImage.width - 1, x1);
|
|
y1 := imin(srcImage.height - 1, y1);
|
|
x2 := imin(srcImage.width - 1, x2);
|
|
y2 := imin(srcImage.height - 1, y2);
|
|
if fIEMBitmap.GetImageInfo( idx ).image <> nil then
|
|
begin
|
|
fIEMBitmap.fImageList.Delete(fIEMBitmap.GetImageInfo( idx ).image);
|
|
ClearImageCache(idx);
|
|
end;
|
|
fIEMBitmap.GetImageInfo( idx ).image := fIEMBitmap.fImageList.AddBitmapRect(srcImage, x1, y1, x2 - x1 + 1, y2 - y1 + 1);
|
|
fIEMBitmap.fImageList.SetImageOriginalWidth(fIEMBitmap.GetImageInfo( idx ).image, srcImage.Width);
|
|
fIEMBitmap.fImageList.SetImageOriginalHeight(fIEMBitmap.GetImageInfo( idx ).image, srcImage.Height);
|
|
if idx = fSelectedItem then
|
|
begin
|
|
fSelectedBitmap := nil;
|
|
CallBitmapChangeEvents;
|
|
end;
|
|
ClearImageCache(idx);
|
|
UpdateEx(false);
|
|
end;
|
|
end;
|
|
|
|
// creates a new copy of "srcImage" (then srcImage can be freed)
|
|
procedure TImageEnMView.SetImageRect(idx: integer; srcImage: TIEBitmap; x1, y1, x2, y2: integer);
|
|
var
|
|
temp: TIEBitmap;
|
|
begin
|
|
temp := TIEBitmap.Create;
|
|
try
|
|
temp.Allocate(x2 - x1 + 1, y2 - y1 + 1, srcImage.PixelFormat);
|
|
srcImage.CopyRectTo(temp, x1, y1, 0, 0, temp.Width, temp.Height, true);
|
|
if temp.HasAlphaChannel then
|
|
temp.AlphaChannel.SyncFull();
|
|
SetImage( idx, temp );
|
|
finally
|
|
temp.free;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ImageAtPos
|
|
|
|
<FM>Declaration<FC>
|
|
function ImageAtPos(x, y: Integer; checkBounds: Boolean = true): Integer;
|
|
|
|
<FM>Description<FN>
|
|
Use ImageAtPos to determine which image exists at the specified location within the control.
|
|
The <FC>x, y<FN> parameters specify the position in "client coordinates".
|
|
If <FC>checkBounds<FN> is True, thumbnail bounds are checked to ensure that we are positioned within the thumbnail area (Specifying False is useful for finding the nearest thumbnail).
|
|
|
|
If there is no thumbnail at the specified position, ImageAtPos returns -1.
|
|
|
|
|
|
<FM>Example<FC>
|
|
// Display the file name in the status bar for the image under the cursor
|
|
procedure TForm1.ImageEnMView1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
|
|
begin
|
|
// Note: ImageFileName[] will return '' if -1 is passed
|
|
StatusBar1.SimpleText := ImageEnMView1.ImageFileName[ ImageEnMView1.ImageAtPos(x, y) ];
|
|
end;
|
|
|
|
!!}
|
|
// returns image index at x, y position
|
|
// -1 no image
|
|
// Friendly wrapper for ImageAtPosEx
|
|
function TImageEnMView.ImageAtPos(x, y: integer; checkBounds: Boolean): Integer;
|
|
begin
|
|
Result := ImageAtPosEx(x, y, checkBounds, True);
|
|
end;
|
|
|
|
|
|
// ImageAtPos with bRelativeToWindow
|
|
function TImageEnMView.ImageAtPosEx(x, y: integer; checkBounds: Boolean; bRelativeToWindow : Boolean): integer;
|
|
var
|
|
ix, iy: integer;
|
|
x1, y1, x2, y2: integer;
|
|
info: TIEImageInfo;
|
|
begin
|
|
if fDisplayMode = mdSingle then
|
|
begin
|
|
// SINGLE VIEW
|
|
result := fFrame;
|
|
end
|
|
else
|
|
if assigned(fAnimation) then
|
|
begin
|
|
// ANIMATION
|
|
Result := fAnimation.FindImageAt(x, y);
|
|
end
|
|
else
|
|
begin
|
|
// GRID
|
|
if y < CurrentHeaderRowHeight then
|
|
begin
|
|
Result := -1;
|
|
exit;
|
|
end;
|
|
|
|
if bRelativeToWindow then
|
|
begin
|
|
ix := imin( ( x + fViewX - ThumbnailsOrigin.X ) div ThumbSizeInfo( itsOuter ).X, CalcGridWidth() - 1 );
|
|
iy := imin( ( y + fViewY - ThumbnailsOrigin.Y ) div ThumbSizeInfo( itsOuter ).Y, CalcGridHeight() - 1 );
|
|
end
|
|
else
|
|
begin
|
|
ix := imin( ( x - ThumbnailsOrigin.X ) div ThumbSizeInfo( itsOuter ).X, CalcGridWidth() - 1 );
|
|
iy := imin( ( y - ThumbnailsOrigin.Y ) div ThumbSizeInfo( itsOuter ).Y, CalcGridHeight() - 1 );
|
|
end;
|
|
|
|
if BiDiModeIsRTL() then
|
|
ix := CalcGridWidth() - ix - 1;
|
|
if fCurrentGridWidth = 0 then
|
|
iy := 0;
|
|
|
|
result := ImageAtGridPos(iy, ix);
|
|
|
|
if result >= ImageCount then
|
|
begin
|
|
if iemoRegion in fMultiSelectionOptions then
|
|
result := ImageCount-1
|
|
else
|
|
result := -1;
|
|
end;
|
|
|
|
if checkBounds and (result >= 0) then
|
|
begin
|
|
// verify if inside the thumbnail rectangle
|
|
info := fIEMBitmap.GetImageInfo( result );
|
|
if bRelativeToWindow then
|
|
begin
|
|
x1 := info.X - fViewX;
|
|
y1 := info.Y - fViewY;
|
|
end
|
|
else
|
|
begin
|
|
x1 := info.X;
|
|
y1 := info.Y;
|
|
end;
|
|
x2 := x1 + ThumbSizeInfo( itsCell ).X - 1;
|
|
y2 := y1 + ThumbSizeInfo( itsCell ).Y;
|
|
if not IEPointInRect(x, y, x1, y1, x2, y2) then
|
|
result := -1;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
function TImageEnMView.ImageAtPosWithCheckEvent(x, y: integer; checkBounds: Boolean; bRelativeToWindow : Boolean): integer;
|
|
begin
|
|
result := ImageAtPosEx(x, y, checkBounds, bRelativeToWindow);
|
|
if assigned(fOnImageAtPos) then
|
|
fOnImageAtPos(self, result, x, y);
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ImageAtGridPos
|
|
|
|
<FM>Declaration<FC>
|
|
function ImageAtGridPos(row, col: Integer): Integer;
|
|
|
|
<FM>Description<FN>
|
|
ImageAtGridPos returns the index of the image at row, col position, e.g. ImageAtGridPos(0, 0) would return the top-left image (i.e. 0).
|
|
!!}
|
|
function TImageEnMView.ImageAtGridPos(row, col: integer): integer;
|
|
begin
|
|
result := row * CalcGridWidth() + col;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.InsertingPoint
|
|
|
|
<FM>Declaration<FC>
|
|
function InsertingPoint(x, y: Integer): Integer;
|
|
|
|
<FM>Description<FN>
|
|
Returns the index of the image before or after the <FC>x, y<FN> position. It is useful when an image needs to be inserted at a particular cursor position.
|
|
|
|
<FM>Example<FC>
|
|
// this drag/drop event copy all selected images of ImageEnMView1 to ImageEnMView2, starting at X, Y mouse position
|
|
procedure TForm1.ImageEnMView2DragDrop(Sender, Source: TObject; X, Y: Integer);
|
|
var
|
|
i: integer;
|
|
idx, im: integer;
|
|
tmpbmp: TBitmap;
|
|
begin
|
|
im := ImageEnMView2.InsertingPoint(X, Y);
|
|
for i := 0 to ImageEnMView1.MultiSelectedImagesCount-1 do
|
|
begin
|
|
idx := ImageEnMView1.MultiSelectedImages[i];
|
|
tmpbmp := ImageEnMView1.GetBitmap( idx );
|
|
ImageEnMView2.InsertImage(im);
|
|
ImageEnMView2.SetImage(im, tmpbmp);
|
|
inc(im);
|
|
ImageEnMView1.ReleaseBitmap( idx );
|
|
end;
|
|
end;
|
|
!!}
|
|
// return =fIEMBitmap.Count if after last thumbnail
|
|
function TImageEnMView.InsertingPoint(x, y: integer): integer;
|
|
var
|
|
ix, iy, gw: integer;
|
|
begin
|
|
ix := ( x + fViewX - ThumbnailsOrigin.X ) div ThumbSizeInfo( itsOuter ).X;
|
|
iy := ( y + fViewY - ThumbnailsOrigin.Y ) div ThumbSizeInfo( itsOuter ).Y;
|
|
gw := CalcGridWidth();
|
|
if (gw > 0) and (ix > gw) then
|
|
ix := gw;
|
|
result := imin(iy * gw + ix, fIEMBitmap.Count); // not fIEMBitmap.Count-1 !!
|
|
end;
|
|
|
|
procedure TImageEnMView.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
|
var
|
|
sidx: Integer;
|
|
lSelectInclusive: boolean;
|
|
lMultiSelecting: boolean;
|
|
idx: Integer;
|
|
begin
|
|
inherited;
|
|
fUserAction := true;
|
|
try
|
|
if fDoubleClicking then
|
|
begin
|
|
fDoubleClicking := false;
|
|
exit;
|
|
end;
|
|
|
|
if fResizingTextColIdx > -1 then
|
|
begin
|
|
// Text column is being resized
|
|
fResizingTextColClickX := X;
|
|
fResizingTextColWidth := CurrentTextColumnWidths( TIEMTextPos( fResizingTextColIdx ));
|
|
exit;
|
|
end;
|
|
|
|
{$IFDEF OCXVERSION}
|
|
SetFocus();
|
|
{$ELSE}
|
|
if CanFocus then
|
|
Windows.SetFocus(Handle);
|
|
{$ENDIF}
|
|
|
|
fHSX1 := X;
|
|
fHSY1 := Y;
|
|
fHSVX1 := ViewX;
|
|
fHSVY1 := ViewY;
|
|
fHSIDX := ImageAtPosWithCheckEvent(x, y, fCheckThumbBoundsOnSelect);
|
|
fHSIDXSelected := IsSelected(ImageAtPosWithCheckEvent(x, y, True));
|
|
fSelectIdxOnMouseUp := -1;
|
|
if fHSIDXSelected and ((ssCtrl in Shift) = False) and ((ssShift in Shift) = False) then
|
|
fSelectIdxOnMouseUp := fHSIDX;
|
|
fLHSIDX := fHSIDX;
|
|
FLastRegionIdx := ImageAtPosEx(x, y, True, False);
|
|
fHaveMultiselected := false;
|
|
fMDown := true;
|
|
fChangedSel := false;
|
|
|
|
if (assigned(fAnimation) = False) and (iemoSelectOnRightClick in fMultiSelectionOptions) and (Button = mbRight) then
|
|
begin
|
|
// Make functionality much closer to Windows Explorer
|
|
idx := ImageAtPosWithCheckEvent(x, y, True);
|
|
if (idx >= 0) and (IsSelected(idx) = False) then
|
|
begin
|
|
Button := mbLeft;
|
|
Shift := [];
|
|
end;
|
|
end;
|
|
|
|
if assigned(fAnimation) and (Button = mbLeft) then
|
|
begin
|
|
// animation mode
|
|
|
|
// show an image clicking on it
|
|
sidx := fAnimation.FindImageAt(X, Y);
|
|
if sidx > -1 then
|
|
begin
|
|
fAnimation.CurrentImage := sidx;
|
|
SelectedImage := fAnimation.CurrentImage;
|
|
end;
|
|
|
|
// start scrollbar slider dragging
|
|
if fAnimation.ShowScrollbar then
|
|
begin
|
|
if fAnimation.IsInsideScrollbarSlider(X, Y) then
|
|
fAnimationDraggingSlider := true
|
|
// directly move to the clicked scrollbar position
|
|
else
|
|
if fAnimation.IsInsideScrollbar(X, Y) then
|
|
begin
|
|
fAnimation.MoveScrollbarSliderTo(X);
|
|
SelectedImage := fAnimation.CurrentImage;
|
|
end;
|
|
end;
|
|
|
|
end
|
|
else
|
|
if ((iemoSelectOnMouseUp in fMultiSelectionOptions) = False) and (Button = mbLeft) and (CheckboxAtPos(X, Y) > -1) then
|
|
begin
|
|
ClickCheckboxAtPos(X, Y);
|
|
end
|
|
else
|
|
if not (iemoSelectOnMouseUp in fMultiSelectionOptions) and (Button = mbLeft) and (mmiSelect in fMouseInteract) then
|
|
begin
|
|
// select on mouse down
|
|
sidx := ImageAtPosWithCheckEvent(x, y, fCheckThumbBoundsOnSelect);
|
|
|
|
if CheckSelectionChangingAllowed = False then
|
|
begin
|
|
// Do nothing
|
|
end
|
|
else
|
|
if (ssShift in Shift) and fEnableMultiSelect then
|
|
begin
|
|
sidx := fPriorHSIDX;
|
|
if sidx < 0 then
|
|
sidx := 0;
|
|
lSelectInclusive := fSelectInclusive;
|
|
lMultiSelecting := fMultiSelecting;
|
|
fMultiSelecting := false;
|
|
fSelectInclusive := true;
|
|
DeselectNU;
|
|
SetSelectedItemNU(sidx);
|
|
fMultiSelecting := lMultiSelecting;
|
|
SelectAtPos(X, Y, [ssShift]);
|
|
fSelectInclusive := lSelectInclusive;
|
|
fHaveMultiselected := true;
|
|
end
|
|
else
|
|
if not IsSelected(sidx) then
|
|
begin
|
|
fPriorHSIDX := sidx;
|
|
SelectAtPos(X, Y, Shift);
|
|
end
|
|
else
|
|
begin
|
|
fPriorHSIDX := sidx;
|
|
if (ssCtrl in Shift) and (iemoOptimizeForDragging in fMultiSelectionOptions) and (MultiSelectedImagesCount > 1) then
|
|
UnselectImage(sidx);
|
|
end;
|
|
end;
|
|
|
|
finally
|
|
fUserAction := false;
|
|
DoAfterEvent(ieaeMouseDown);
|
|
end;
|
|
end;
|
|
|
|
function TImageEnMView.GetHintStr(idx : Integer) : string;
|
|
|
|
procedure _AddLine(sText : string);
|
|
begin
|
|
if sText <> '' then
|
|
begin
|
|
if Result = '' then
|
|
Result := sText
|
|
else
|
|
Result := Result + #13#10 + sText;
|
|
end;
|
|
end;
|
|
|
|
procedure _AddLineEx(ACaption : TMsgLanguageWords; sText : string);
|
|
begin
|
|
sText := ReplaceIEMConst(sText, idx);
|
|
if sText <> '' then
|
|
_AddLine( iemsg(ACaption) + ': ' + sText );
|
|
end;
|
|
|
|
var
|
|
sFilename: WideString;
|
|
begin
|
|
Result := '';
|
|
|
|
sFilename := ImageFilename[idx];
|
|
if sFilename = '' then
|
|
begin
|
|
_AddLine( ImageTopText[idx] );
|
|
_AddLine( ImageInfoText[idx] );
|
|
_AddLine( ImageBottomText[idx] );
|
|
exit; // invalid file
|
|
end;
|
|
|
|
if GetImageType(idx) = ieftFolder then
|
|
begin
|
|
_AddLineEx(IEMSG_Folder, sFilename );
|
|
end
|
|
else
|
|
begin
|
|
_AddLineEx(IEMSG_FILE, GetDisplayName( sFileName ));
|
|
_AddLineEx(IEMSG_Folder, IEM_FilePath);
|
|
_AddLineEx(IEMSG_Dimensions, IEM_ImageDimensions);
|
|
_AddLineEx(IEMSG_Type, IEM_FileType);
|
|
_AddLineEx(IEMSG_SIZE, IEM_FileSize);
|
|
end;
|
|
|
|
_AddLineEx(IEMSG_Created, IEM_FileCreateDate);
|
|
_AddLineEx(IEMSG_Modified, IEM_FileEditDate);
|
|
end;
|
|
|
|
|
|
|
|
procedure TImageEnMView.MouseMove(Shift: TShiftState; X, Y: Integer);
|
|
const
|
|
Scroll_Area_Size = 20;
|
|
Auto_Scroll_Amount = 10;
|
|
Mouse_Move_Threshold = 10;
|
|
Proportional_Scroll_Divisor = 3;
|
|
Drag_Scroll_Area = 20;
|
|
Column_Split_Width = 5;
|
|
var
|
|
lSelectInclusive: boolean;
|
|
lMultiSelecting: boolean;
|
|
idx: integer;
|
|
iNewX, iNewY: integer;
|
|
iRgnIdx: integer;
|
|
AutoScrollProp: integer;
|
|
sCurrentHint: string;
|
|
bCanSelect: Boolean;
|
|
iMaxWidth: Integer;
|
|
Itt: TIEMTextPos;
|
|
begin
|
|
inherited;
|
|
sCurrentHint := Hint;
|
|
fUserAction := true;
|
|
fLastMouseMoveX := X;
|
|
fLastMouseMoveY := Y;
|
|
if fResizingTextColClickX < 0 then
|
|
fResizingTextColIdx := -1;
|
|
try
|
|
if assigned(fAnimation) then
|
|
begin
|
|
// animation mode
|
|
if fAnimation.ShowScrollbar then
|
|
begin
|
|
// change mouse cursor (hand when inside the scrollbar slider, default otherwise)
|
|
if fAnimation.IsInsideScrollbarSlider(X, Y) then
|
|
Cursor := crHandPoint
|
|
else
|
|
Cursor := crDefault;
|
|
|
|
// dragging scrollbar slider
|
|
if MouseCapture and fAnimationDraggingSlider then
|
|
begin
|
|
fAnimation.MoveScrollbarSliderTo(X);
|
|
SelectedImage := fAnimation.CurrentImage;
|
|
end;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
bCanSelect := (fHSIDXSelected = False) or not (iemoOptimizeForDragging in fMultiSelectionOptions);
|
|
|
|
// default mode
|
|
if MouseCapture and ( fResizingTextColIdx = -1 ) then
|
|
begin
|
|
if (mmiSelect in fMouseInteract) and fEnableMultiSelect then
|
|
begin
|
|
idx := ImageAtPosEx(fViewX + x, fViewY + y, False, False);
|
|
iRgnIdx := ImageAtPosEx(fViewX + x, fViewY + y, True, False);
|
|
|
|
if bCanSelect and (CheckSelectionChangingAllowed = False) then
|
|
bCanSelect := False;
|
|
|
|
if bCanSelect then
|
|
if ((idx <> fLHSIDX) and (idx <> -1)) or
|
|
((iemoRegion in fMultiSelectionOptions) and (iRgnIdx <> FLastRegionIdx)) then
|
|
begin
|
|
fLHSIDX := idx;
|
|
FLastRegionIdx := iRgnIdx;
|
|
idx := fHSIDX;
|
|
if idx < 0 then
|
|
idx := 0;
|
|
|
|
lSelectInclusive := fSelectInclusive;
|
|
lMultiSelecting := fMultiSelecting;
|
|
fMultiSelecting := (ssCtrl in Shift);
|
|
fSelectInclusive := true;
|
|
|
|
if not fMultiSelecting then
|
|
DeselectNU();
|
|
SetSelectedItemNU(idx);
|
|
fMultiSelecting := lMultiSelecting;
|
|
SelectAtPos(X, Y, [ssShift]);
|
|
fSelectInclusive := lSelectInclusive;
|
|
fHaveMultiselected := true;
|
|
end;
|
|
|
|
// Automatically scroll selection
|
|
if (mmiScroll in fMouseInteract) = False then
|
|
begin
|
|
iNewX := fViewX;
|
|
iNewY := fViewY;
|
|
|
|
AutoScrollProp := Auto_Scroll_Amount;
|
|
|
|
if Y < 0 then
|
|
AutoScrollProp := imax(Abs(Y) div Proportional_Scroll_Divisor, AutoScrollProp)
|
|
else
|
|
AutoScrollProp := imax(imax(0, Y-ClientHeight) div 2, AutoScrollProp);
|
|
if X < 0 then
|
|
AutoScrollProp := imax(Abs(X) div Proportional_Scroll_Divisor, AutoScrollProp)
|
|
else
|
|
AutoScrollProp := imax(imax(0, X-ClientWidth) div 2, AutoScrollProp);
|
|
|
|
|
|
if (Abs(fHSY1 - Y) > Mouse_Move_Threshold) and (Y < Scroll_Area_Size) and (fViewY > 0) then
|
|
Dec(iNewY, AutoScrollProp)
|
|
else
|
|
if (Abs(fHSY1 - Y) > Mouse_Move_Threshold) and (Y > ClientHeight - Scroll_Area_Size) and (ClientHeight < fVHeight) and (fViewY < fVHeight) then
|
|
Inc(iNewY, AutoScrollProp);
|
|
|
|
if (Abs(fHSX1 - X) > Mouse_Move_Threshold) and (X < Scroll_Area_Size) and (fViewX > 0) then
|
|
Dec(iNewX, AutoScrollProp)
|
|
else
|
|
if (Abs(fHSX1 - X) > Mouse_Move_Threshold) and (X > ClientWidth - Scroll_Area_Size) and (ClientWidth < fVWidth) and (fViewX < fVWidth) then
|
|
Inc(iNewX, AutoScrollProp);
|
|
|
|
if (iNewX <> fViewX) or (iNewY <> fViewY) then
|
|
begin
|
|
SetViewXY(iNewX, iNewY);
|
|
ViewChange(0);
|
|
PostMessage(Handle, IEM_AUTOSCROLL, 0, 0);
|
|
|
|
if fTrackMouseSelection = False then
|
|
Paint();
|
|
end;
|
|
end;
|
|
|
|
if fTrackMouseSelection and bCanSelect then
|
|
begin
|
|
fDrawMouseSelection := true;
|
|
Paint();
|
|
end;
|
|
end;
|
|
if mmiScroll in fMouseInteract then
|
|
begin
|
|
if ((X - fHSx1)<>0) or ((Y - fHSy1)<>0) then
|
|
begin
|
|
SetViewXY(fHSVX1 - (X - fHSx1), fHSVY1 - (Y - fHSy1));
|
|
ViewChange(0);
|
|
end;
|
|
end;
|
|
end // If MouseCapture...
|
|
else
|
|
if fShowThumbnailHint and (DisplayMode <> mdSingle) then
|
|
begin
|
|
idx := ImageAtPosEx(fViewX + x, fViewY + y, True, False);
|
|
sCurrentHint := GetHintStr(idx);
|
|
end;
|
|
|
|
// DRAW CHECKBOX IF HOVERING OVER THE MOUSE
|
|
if fHoverCheckLastPos.X = -1 then
|
|
fHoverCheckLastPos := Point(X, Y);
|
|
if (fCheckboxes = iecbShowOnHover) and
|
|
(fLockPaint <= 0) and
|
|
((abs(fHoverCheckLastPos.X - X) > Mouse_Move_Threshold) or (abs(fHoverCheckLastPos.Y - Y) > Mouse_Move_Threshold)) then
|
|
begin
|
|
idx := ImageAtPosEx(fViewX + x, fViewY + y, True, False);
|
|
if idx <> fHoverCheckLastIdx then
|
|
begin
|
|
if fHoverCheckLastIdx > -1 then
|
|
_UpdateImage(fHoverCheckLastIdx, True);
|
|
fHoverCheckLastIdx := idx;
|
|
DrawCheckbox(Canvas, idx, True, True);
|
|
end;
|
|
end;
|
|
|
|
|
|
// RESIZING OF TEXT COLUMNS IN COLUMNS STYLE
|
|
if ( fResizingTextColIdx > -1 ) and
|
|
( fResizingTextColClickX > -1 ) then
|
|
begin
|
|
// Lock the width of any columns to the left
|
|
if ( TIEMTextPos( fResizingTextColIdx ) in [ iemtpBottom, iemtpInfo ]) then
|
|
fTextColumnWidths[ iemtpTop ] := CurrentTextColumnWidths( iemtpTop );
|
|
if ( TIEMTextPos( fResizingTextColIdx ) = iemtpInfo ) then
|
|
fTextColumnWidths[ iemtpBottom ] := CurrentTextColumnWidths( iemtpBottom );
|
|
|
|
// Make any columns to the right auto
|
|
if ( TIEMTextPos( fResizingTextColIdx ) in [ iemtpTop, iemtpBottom ]) then
|
|
fTextColumnWidths[ iemtpInfo ] := -1;
|
|
if ( TIEMTextPos( fResizingTextColIdx ) = iemtpTop ) then
|
|
fTextColumnWidths[ iemtpBottom ] := -1;
|
|
|
|
iMaxWidth := ClientWidth - trunc(fThumbWidth * fZoom / 100.0) - 2 * fHorizBorder;
|
|
if fResizingTextColIdx > ord( iemtpTop ) then
|
|
for itt := iemtpTop to TIEMTextPos( fResizingTextColIdx - 1 ) do
|
|
Dec( iMaxWidth, fTextColumnWidths[ itt ]);
|
|
|
|
fTextColumnWidths[ TIEMTextPos( fResizingTextColIdx )] := imin( fResizingTextColWidth + x - fResizingTextColClickX, iMaxWidth );
|
|
if fTextColumnWidths[ TIEMTextPos( fResizingTextColIdx )] < 0 then
|
|
fTextColumnWidths[ TIEMTextPos( fResizingTextColIdx )] := 0;
|
|
Invalidate;
|
|
end
|
|
else
|
|
if y < CurrentHeaderRowHeight then
|
|
begin
|
|
for Itt := Low( fTextColsCurrentRight ) to High( fTextColsCurrentRight ) do
|
|
if ( fTextColsCurrentRight[ itt ] > 0 ) and ( abs( x - fTextColsCurrentRight[ itt ] ) < Column_Split_Width ) and
|
|
(( x < ThumbSizeInfo( itsCell ).X ) or ( fTextBlockWidth > -1 ) or ( CurrentTextColumnWidths( iemtpInfo ) = 0 )) then // if auto-sized to client width, can't drag rightmost column
|
|
begin
|
|
fResizingTextColIdx := ord( Itt );
|
|
Break;
|
|
end;
|
|
if fResizingTextColIdx > -1 then
|
|
Cursor := crHSplit
|
|
end;
|
|
|
|
end; // If Animation else
|
|
|
|
if (sCurrentHint <> Hint) then
|
|
begin
|
|
Application.CancelHint;
|
|
Hint := sCurrentHint;
|
|
end;
|
|
|
|
finally
|
|
fUserAction := false;
|
|
if ( fResizingTextColIdx = -1 ) and ( Cursor = crHSplit ) then
|
|
Cursor := crDefault;
|
|
end;
|
|
end;
|
|
|
|
procedure TImageEnMView.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
|
var
|
|
idx: Integer;
|
|
bCanSelect: Boolean;
|
|
Itt: TIEMTextPos;
|
|
begin
|
|
inherited;
|
|
fUserAction := true;
|
|
try
|
|
if fResizingTextColIdx > -1 then
|
|
begin
|
|
// Text column was being resized
|
|
fResizingTextColClickX := -1;
|
|
exit;
|
|
end;
|
|
|
|
if fTrackMouseSelection then
|
|
begin
|
|
fDrawMouseSelection := false;
|
|
Paint();
|
|
end;
|
|
|
|
if not fMDown then
|
|
exit;
|
|
fMDown := false;
|
|
|
|
if fDragging then
|
|
exit;
|
|
if fPlaying then
|
|
exit;
|
|
|
|
if (assigned(fAnimation) = False) and (iemoSelectOnRightClick in fMultiSelectionOptions) and (Button = mbRight) then
|
|
begin
|
|
// Make functionality much closer to Windows Explorer
|
|
idx := ImageAtPosWithCheckEvent(x, y, True);
|
|
if (idx >= 0) and (IsSelected(idx) = False) then
|
|
begin
|
|
Button := mbLeft;
|
|
Shift := [];
|
|
end;
|
|
end;
|
|
|
|
if Button = mbLeft then
|
|
begin
|
|
if assigned(fAnimation) then
|
|
begin
|
|
// animation mode
|
|
fAnimationDraggingSlider := false;
|
|
end
|
|
else
|
|
begin
|
|
if (iemoSelectOnMouseUp in fMultiSelectionOptions) and (CheckboxAtPos(X, Y) > -1) then
|
|
begin
|
|
ClickCheckboxAtPos(X, Y);
|
|
end
|
|
else
|
|
if (iemoSelectOnMouseUp in fMultiSelectionOptions) and (not fHaveMultiselected) and (mmiSelect in fMouseInteract) then
|
|
begin
|
|
// we select on "mouse up"
|
|
if CheckSelectionChangingAllowed then
|
|
SelectAtPos(X, Y, Shift);
|
|
end;
|
|
|
|
if not (iemoSelectOnMouseUp in fMultiSelectionOptions) and (fChangedSel = False) and (CheckboxAtPos(X, Y) = -1) then
|
|
begin
|
|
bCanSelect := (fHSIDXSelected = False) or not (iemoOptimizeForDragging in fMultiSelectionOptions);
|
|
|
|
if bCanSelect and (CheckSelectionChangingAllowed = False) then
|
|
begin
|
|
// Do nothing
|
|
end
|
|
else
|
|
// when we select on "mouse down", there is one case where we still need to select on mouse up
|
|
if bCanSelect then
|
|
SelectAtPos(X, Y, Shift)
|
|
else
|
|
if fSelectIdxOnMouseUp > -1 then
|
|
begin
|
|
DeselectNU;
|
|
SelectedImage := fSelectIdxOnMouseUp;
|
|
end;
|
|
end;
|
|
if (mmiScroll in fMouseInteract) then
|
|
SetViewXY(fHSVX1 - (X - fHSx1), fHSVY1 - (Y - fHSy1));
|
|
|
|
if y < CurrentHeaderRowHeight then
|
|
begin
|
|
// Clicked a header cell?
|
|
for Itt := Low( fTextColsCurrentRight ) to High( fTextColsCurrentRight ) do
|
|
if x < fTextColsCurrentRight[ itt ] then
|
|
begin
|
|
ClickColumnsHeaderRowCell( itt );
|
|
Break;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
finally
|
|
fUserAction := false;
|
|
DoAfterEvent(ieaeMouseUp);
|
|
end;
|
|
end;
|
|
|
|
procedure TImageEnMView.SelectAtPos(X, Y: integer; Shift: TShiftState);
|
|
var
|
|
idx, q, col, row: integer;
|
|
lMultiSelecting: boolean;
|
|
row1, row2, col1, col2: integer;
|
|
x1, y1, x2, y2: integer;
|
|
incx, incy: integer;
|
|
begin
|
|
// find the image where user has clicked (put in fSelectedItem)
|
|
lMultiSelecting := fMultiSelecting;
|
|
if (ssCtrl in Shift) or (ssShift in Shift) then
|
|
fMultiSelecting := true;
|
|
|
|
if (iemoRegion in fMultiSelectionOptions) and ((fHSX1 <> X) or (fHSY1 <> Y)) then
|
|
begin
|
|
if not fMultiSelecting then
|
|
DeselectNU();
|
|
|
|
x1 := imin(fHSVX1 + fHSX1, ViewX + X);
|
|
y1 := imin(fHSVY1 + fHSY1, ViewY + Y);
|
|
x2 := imax(fHSVX1 + fHSX1, ViewX + X);
|
|
y2 := imax(fHSVY1 + fHSY1, ViewY + Y);
|
|
|
|
// Check minimum bounds
|
|
x1 := imax(x1, 0);
|
|
y1 := imax(y1, 0);
|
|
|
|
|
|
row := y1;
|
|
while row <= y2 do
|
|
begin
|
|
incy := 0;
|
|
col := x1;
|
|
while col <= x2 do
|
|
begin
|
|
q := ImageAtPosWithCheckEvent(col, row, True, False);
|
|
if (q <> -1) and (fMultiSelectedImages.IndexOf(pointer(q)) = -1) then
|
|
SetSelectedItemNU(q);
|
|
incx := 0;
|
|
if q <> -1 then
|
|
begin
|
|
incx := ImageX[q] + ThumbSizeInfo( itsOuter ).X;
|
|
incy := ImageY[q] + ThumbSizeInfo( itsOuter ).Y;
|
|
end;
|
|
col := imax(col+1, incx);
|
|
end;
|
|
row := imax(row+1, incy);
|
|
end;
|
|
if fVisibleSelection then
|
|
UpdateEx(false);
|
|
CallBitmapChangeEvents;
|
|
end
|
|
else
|
|
begin
|
|
idx := ImageAtPosWithCheckEvent(x, y, fCheckThumbBoundsOnSelect);
|
|
if (idx >= 0) then
|
|
begin
|
|
if fEnableMultiSelect and ((idx <> fSelectedItem) or fMultiSelecting) then
|
|
begin
|
|
if ssShift in Shift then
|
|
begin
|
|
// SHIFT pressed, select range
|
|
if iemoRegionOnShift in fMultiSelectionOptions then
|
|
begin
|
|
row1 := ImageRow[fSelectedItem];
|
|
row2 := ImageRow[idx];
|
|
col1 := ImageCol[fSelectedItem];
|
|
col2 := ImageCol[idx];
|
|
if row1 > row2 then
|
|
iswap(row1, row2);
|
|
if col1 > col2 then
|
|
iswap(col1, col2);
|
|
for row := row1 to row2 do
|
|
for col := col1 to col2 do
|
|
begin
|
|
q := ImageAtGridPos(row, col);
|
|
if (q <> fSelectedItem) and (q <> idx) and (fMultiSelectedImages.IndexOf(pointer(q)) = -1) then
|
|
SetSelectedItemNU(q);
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
if fSelectedItem < idx then
|
|
begin
|
|
for q := fSelectedItem + 1 to idx - 1 do
|
|
if fMultiSelectedImages.IndexOf(pointer(q)) = -1 then
|
|
SetSelectedItemNU(q);
|
|
end
|
|
else
|
|
begin
|
|
for q := fSelectedItem - 1 downto idx + 1 do
|
|
if fMultiSelectedImages.IndexOf(pointer(q)) = -1 then
|
|
SetSelectedItemNU(q);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
SetSelectedItemNU(idx);
|
|
if fVisibleSelection then
|
|
UpdateEx(false);
|
|
CallBitmapChangeEvents;
|
|
end;
|
|
end;
|
|
fMultiSelecting := lMultiSelecting;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.VisibleSelection
|
|
|
|
<FM>Declaration<FC>
|
|
property VisibleSelection: boolean;
|
|
|
|
<FM>Description<FN>
|
|
When enabled the selected frame is marked. Otherwise selected and unselected frames look identical.
|
|
|
|
!!}
|
|
procedure TImageEnMView.SetVisibleSelection(v: boolean);
|
|
begin
|
|
fVisibleSelection := v;
|
|
Update;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.Checkboxes
|
|
|
|
<FM>Declaration<FC>
|
|
property Checkboxes: <A TIEMCheckboxType>;
|
|
|
|
<FM>Description<FN>
|
|
Displays a checkbox in each thumbnail box to provide an alternative method for users to select files (as opposed to <L TImageEnMView.EnableMultiSelect>multiple selection</L>).
|
|
|
|
Notes:
|
|
- Use <A TImageEnMView.CheckedCount> to return the number of checked items
|
|
- Read/write the checked status of each file using <A TImageEnMView.Checked>
|
|
- Set checked status en masse using <A TImageEnMView.CheckAll> or <A TImageEnMView.UncheckAll>
|
|
- Change the position and style of checkboxes with <A TImageEnMView.CheckBoxPos> and <A TImageEnMView.SetCheckboxParams>
|
|
- Access the event, <A TImageEnMView.OnCheckboxClick>, to determine when the user clicks a checkbox
|
|
|
|
<FM>Demo<FN>
|
|
<TABLE2>
|
|
<R> <C_IMG_DEMO> <C>Demos\Multi\Checkboxes\Checkboxes.dpr </C> </R>
|
|
</TABLE>
|
|
|
|
<FM>Example<FC>
|
|
// Copy all checked files to D:\Dest\
|
|
for I := 0 to ImageEnMView1.ImageCount - 1 do
|
|
if ImageEnMView1.Checked[I] then
|
|
WindowsCopy(Handle, ImageEnMView1.ImageFilename[I], 'D:\Dest\', True, True);
|
|
!!}
|
|
procedure TImageEnMView.SetCheckboxes(v: TIEMCheckboxType);
|
|
// NPC: 25/09/13
|
|
begin
|
|
if fCheckboxes <> v then
|
|
begin
|
|
fCheckboxes := v;
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.CheckboxPos
|
|
|
|
<FM>Declaration<FC>
|
|
property CheckboxPos : <A TIEMCheckboxPos>;
|
|
|
|
<FM>Description<FN>
|
|
Specify the corner of the thumbnail where the <L TImageEnMView.Checkboxes>checkbox</L> is displayed.
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.SetCheckboxParams>
|
|
|
|
<FM>Demo<FN>
|
|
<TABLE2>
|
|
<R> <C_IMG_DEMO> <C>Demos\Multi\Checkboxes\Checkboxes.dpr </C> </R>
|
|
</TABLE>
|
|
|
|
<FM>Example<FC>
|
|
// Show checkboxes on bottom left when the user hovers over the thumbnail
|
|
ImageEnMView1.Checkboxes := iecbShowOnHover;
|
|
ImageEnMView1.CheckboxPos := iecpBottomLeft;
|
|
!!}
|
|
procedure TImageEnMView.SetCheckboxPos(v: TIEMCheckboxPos);
|
|
// NPC: 23/06/14
|
|
begin
|
|
if fCheckboxPos <> v then
|
|
begin
|
|
fCheckboxPos := v;
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.CheckedCount
|
|
|
|
<FM>Declaration<FC>
|
|
function CheckedCount : Integer;
|
|
|
|
<FM>Description<FN>
|
|
Returns the number of items that have been checked (if <A TImageEnMView.Checkboxes> have been enabled).
|
|
|
|
<FM>Demo<FN>
|
|
<TABLE2>
|
|
<R> <C_IMG_DEMO> <C>Demos\Multi\Checkboxes\Checkboxes.dpr </C> </R>
|
|
</TABLE>
|
|
|
|
<FM>Example<FC>
|
|
// Note: Use OnClick, not OnCheckboxClick if need to read CheckedCount
|
|
procedure TfMain.ImageEnMView1Click(Sender: TObject);
|
|
begin
|
|
// Display the current count of checked items in the status bar
|
|
Statusbar1.SimpleText := 'Checked: ' + IntToStr(ImageEnMView1.CheckedCount);
|
|
end;
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.Checked>
|
|
!!}
|
|
function TImageEnMView.CheckedCount : Integer;
|
|
// NPC: 25/09/13
|
|
var
|
|
i: Integer;
|
|
begin
|
|
if fCheckedCount < 0 then
|
|
begin
|
|
fCheckedCount := 0;
|
|
for i := 0 to ImageCount - 1 do
|
|
if Checked[i] then
|
|
inc(fCheckedCount);
|
|
end;
|
|
Result := fCheckedCount;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.Checked
|
|
|
|
<FM>Declaration<FC>
|
|
property Checked[index : Integer] : Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Specifies the checked status for the item of the specified index (if <A TImageEnMView.Checkboxes> have been enabled).
|
|
|
|
<FM>Example<FC>
|
|
// Copy all checked files to D:\Dest\
|
|
for I := 0 to ImageEnMView1.ImageCount - 1 do
|
|
if ImageEnMView1.Checked[I] then
|
|
WindowsCopy(Handle, ImageEnMView1.ImageFilename[I], 'D:\Dest\', True, True);
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.CheckedCount>
|
|
!!}
|
|
function TImageEnMView.GetChecked(index: integer): Boolean;
|
|
// NPC: 25/09/13
|
|
begin
|
|
result := False;
|
|
if (index >= 0) and (index < fIEMBitmap.Count) then
|
|
result := fIEMBitmap.GetImageInfo( index ).Checked;
|
|
end;
|
|
|
|
procedure TImageEnMView.SetChecked(index: integer; v : Boolean);
|
|
// NPC: 25/09/13
|
|
var
|
|
bOldChecked: Boolean;
|
|
begin
|
|
if (index >= 0) and (index < fIEMBitmap.Count) then
|
|
begin
|
|
bOldChecked := fIEMBitmap.GetImageInfo( index ).Checked;
|
|
if bOldChecked <> v then
|
|
begin
|
|
fIEMBitmap.GetImageInfo( index ).Checked := v;
|
|
if fCheckedCount > -1 then
|
|
begin
|
|
if v then
|
|
inc(fCheckedCount)
|
|
else
|
|
dec(fCheckedCount);
|
|
end;
|
|
DrawCheckbox(Canvas, Index, True, True);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.SetCheckboxParams
|
|
|
|
<FM>Declaration<FC>
|
|
procedure SetCheckboxParams(iHorzMargin, iVertMargin : Integer; CustomCheckedImage : TBitmap = nil; CustomUncheckedImage : TBitmap = nil);
|
|
|
|
<FM>Description<FN>
|
|
Specifies the position and style of checkboxes (if <A TImageEnMView.Checkboxes> have been enabled).
|
|
|
|
<TABLE>
|
|
<R> <H>Parameter</H> <H>Description</H> </R>
|
|
<R> <C><FC>iHorzMargin<FN></C> <C>The position from the left (iecpTopLeft or iecpBottomLeft) or right (iecpTopRight or iecpBottomRight) of the thumbnail where the checkbox is positioned. Default: 4</C> </R>
|
|
<R> <C><FC>iVertMargin<FN></C> <C>The position from the top (iecpTopLeft or iecpTopRight) or bottom (iecpBottomLeft or iecpBottomRight) of the thumbnail where the checkbox is positioned. Default: 4</C> </R>
|
|
<R> <C><FC>CustomCheckedImage<FN></C> <C>If specified, it is the image that will be shown as the "checked" box. If <FC>nil<FN> the Windows standard checkbox image is used</C> </R>
|
|
<R> <C><FC>CustomUncheckedImage<FN></C> <C>If specified, it is the image that will be shown as the "unchecked" box. If <FC>nil<FN> the Windows standard checkbox image is used</C> </R>
|
|
</TABLE>
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.CheckboxPos>
|
|
|
|
<FM>Example<FC>
|
|
// Load custom checkbox images from file and position them at the very top left
|
|
CheckBmp := TBitmap.create;
|
|
UncheckBmp := TBitmap.create;
|
|
try
|
|
CheckBmp.LoadFromFile('C:\Images\Checked.bmp');
|
|
UncheckBmp.LoadFromFile('C:\Images\Unchecked.bmp');
|
|
ImageEnMView1.SetCheckboxParams(0, 0, CheckBmp, UncheckBmp);
|
|
ImageEnMView1.CheckboxPos := iecpTopLeft;
|
|
ImageEnMView1.Checkboxes := iecbAlways;
|
|
finally
|
|
CheckBmp.free;
|
|
UncheckBmp.free;
|
|
end;
|
|
!!}
|
|
procedure TImageEnMView.SetCheckboxParams(iHorzMargin, iVertMargin : Integer; CustomCheckedImage : TBitmap = nil; CustomUncheckedImage : TBitmap = nil);
|
|
// NPC: 25/09/13
|
|
begin
|
|
fCheckboxMargins := Point(iHorzMargin, iVertMargin);
|
|
|
|
if Assigned(CustomCheckedImage) = False then
|
|
FreeAndNil(fCheckedBitmap) // default thumbnail will be assigned at draw
|
|
else
|
|
begin
|
|
if fCheckedBitmap = nil then
|
|
fCheckedBitmap := TBitmap.create;
|
|
fCheckedBitmap.assign(CustomCheckedImage)
|
|
end;
|
|
|
|
if Assigned(CustomUncheckedImage) = False then
|
|
FreeAndNil(fUncheckedBitmap) // default thumbnail will be assigned at draw
|
|
else
|
|
begin
|
|
if fUncheckedBitmap = nil then
|
|
fUncheckedBitmap := TBitmap.create;
|
|
fUncheckedBitmap.assign(CustomUncheckedImage)
|
|
end;
|
|
|
|
Invalidate;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.CheckAll
|
|
|
|
<FM>Declaration<FC>
|
|
procedure CheckAll;
|
|
|
|
<FM>Description<FN>
|
|
Marks the checkbox status for all files to "Checked" (if <A TImageEnMView.Checkboxes> have been enabled).
|
|
!!}
|
|
procedure TImageEnMView.CheckAll;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
LockPaint;
|
|
try
|
|
for I := 0 to ImageCount - 1 do
|
|
Checked[i] := True;
|
|
finally
|
|
NPUnLockPaint;
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.UncheckAll
|
|
|
|
<FM>Declaration<FC>
|
|
procedure UncheckAll;
|
|
|
|
<FM>Description<FN>
|
|
Marks the checkbox status for all files to "Unchecked" (if <A TImageEnMView.Checkboxes> have been enabled).
|
|
!!}
|
|
procedure TImageEnMView.UncheckAll;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
LockPaint;
|
|
try
|
|
for I := 0 to ImageCount - 1 do
|
|
Checked[i] := False;
|
|
finally
|
|
NPUnLockPaint;
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
function TImageEnMView.ThumbToCheckboxRect(ThumbRect : TRect; bRelativeToView : Boolean = False) : TRect;
|
|
var
|
|
x1, y1 : integer;
|
|
begin
|
|
if fCheckboxPos in [iecpTopLeft, iecpBottomLeft] then
|
|
// Left Aligned
|
|
x1 := ThumbRect.Left + fCheckboxMargins.X
|
|
else
|
|
// Right aligned
|
|
x1 := ThumbRect.Right - fCheckedBitmap.Width - fCheckboxMargins.X;
|
|
|
|
if fCheckboxPos in [iecpTopLeft, iecpTopRight] then
|
|
// Top Aligned
|
|
y1 := ThumbRect.Top + fCheckboxMargins.Y
|
|
else
|
|
// Bottom aligned
|
|
y1 := ThumbRect.Bottom - fCheckedBitmap.Height - fCheckboxMargins.Y;
|
|
|
|
if bRelativeToView then
|
|
begin
|
|
x1 := x1 - ViewX;
|
|
y1 := y1 - ViewY;
|
|
end;
|
|
|
|
Result := Rect(x1, y1, x1 + fCheckedBitmap.Width, y1 + fCheckedBitmap.Height);
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure DrawCheckBoxToBitmap(Handle: THandle; DestBitmap: TBitmap; bChecked: Boolean);
|
|
var
|
|
{$IFDEF IEHASTHEMING} // From Delphi 7
|
|
h: HTHEME;
|
|
{$EndIf}
|
|
r: TRect;
|
|
s: TSize;
|
|
begin
|
|
{$IFDEF IEHASTHEMING} // From Delphi 7
|
|
if UseThemes then
|
|
begin
|
|
h := OpenThemeData(Handle, 'BUTTON');
|
|
if h <> 0 then
|
|
try
|
|
GetThemePartSize(h,
|
|
DestBitmap.Canvas.Handle,
|
|
BP_CHECKBOX,
|
|
CBS_CHECKEDNORMAL,
|
|
nil,
|
|
TS_DRAW,
|
|
s);
|
|
|
|
DestBitmap.Width := s.cx;
|
|
DestBitmap.Height := s.cy;
|
|
r := Rect(0, 0, s.cx, s.cy);
|
|
|
|
if bChecked then
|
|
DrawThemeBackground(h,
|
|
DestBitmap.Canvas.Handle,
|
|
BP_CHECKBOX,
|
|
CBS_CHECKEDNORMAL,
|
|
r,
|
|
nil)
|
|
else
|
|
DrawThemeBackground(h,
|
|
DestBitmap.Canvas.Handle,
|
|
BP_CHECKBOX,
|
|
CBS_UNCHECKEDNORMAL,
|
|
r,
|
|
nil);
|
|
finally
|
|
CloseThemeData(h);
|
|
end;
|
|
end
|
|
else
|
|
{$EndIf}
|
|
begin
|
|
s.cx := GetSystemMetrics(SM_CXMENUCHECK);
|
|
s.cy := GetSystemMetrics(SM_CYMENUCHECK);
|
|
DestBitmap.Width := s.cx;
|
|
DestBitmap.Height := s.cy;
|
|
r := Rect(0, 0, s.cx, s.cy);
|
|
if bChecked then
|
|
DrawFrameControl(DestBitmap.Canvas.Handle,
|
|
r,
|
|
DFC_BUTTON,
|
|
DFCS_CHECKED)
|
|
else
|
|
DrawFrameControl(DestBitmap.Canvas.Handle,
|
|
r,
|
|
DFC_BUTTON,
|
|
DFCS_BUTTONCHECK);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TImageEnMView.DrawCheckbox(ACanvas : TCanvas; Index : Integer; IsSelected : Boolean; bRelativeToView : Boolean = False);
|
|
var
|
|
ThumbRect: TRect;
|
|
begin
|
|
if Index > -1 then
|
|
begin
|
|
ThumbRect := Rect(ImageX[index], ImageY[index], ImageX[index] + ThumbSizeInfo( itsCell ).X, ImageY[index] + ThumbSizeInfo( itsCell ).Y );
|
|
DrawCheckbox(Canvas, Index, ThumbRect, IsSelected, True);
|
|
end;
|
|
end;
|
|
|
|
procedure TImageEnMView.DrawCheckbox(ACanvas : TCanvas; Index : Integer; ThumbRect : TRect; IsSelected : Boolean; bRelativeToView : Boolean = False);
|
|
var
|
|
CbxRect: TRect;
|
|
begin
|
|
if (fCheckboxes = iecbNone) or (fLockPaint > 0) then
|
|
exit;
|
|
|
|
if fCheckedBitmap = nil then
|
|
begin
|
|
fCheckedBitmap := TBitmap.create;
|
|
DrawCheckBoxToBitmap(Handle, fCheckedBitmap, True);
|
|
end;
|
|
|
|
if fUncheckedBitmap = nil then
|
|
begin
|
|
fUncheckedBitmap := TBitmap.create;
|
|
DrawCheckBoxToBitmap(Handle, fUncheckedBitmap, False);
|
|
end;
|
|
|
|
CbxRect := ThumbToCheckboxRect(ThumbRect, bRelativeToView);
|
|
if bRelativeToView then
|
|
begin
|
|
// check if off-screen
|
|
if (CbxRect.Right < 0) or (CbxRect.Left > ClientWidth) or
|
|
(CbxRect.Bottom < 0) or (CbxRect.Top > ClientHeight) then
|
|
exit;
|
|
end;
|
|
|
|
if Checked[index] then
|
|
ACanvas.Draw(CbxRect.Left, CbxRect.Top, fCheckedBitmap)
|
|
else
|
|
if IsSelected or (fCheckboxes = iecbAlways) then
|
|
ACanvas.Draw(CbxRect.Left, CbxRect.Top, fUncheckedBitmap);
|
|
end;
|
|
|
|
|
|
// If x, y is within a checkbox of a thumbnail its index is returned. Otherwise -1
|
|
function TImageEnMView.CheckboxAtPos(X, Y : Integer) : Integer;
|
|
var
|
|
ThumbRect, CbxRect: TRect;
|
|
idx: Integer;
|
|
begin
|
|
Result := -1;
|
|
|
|
if (fCheckboxes = iecbNone) or (fCheckedBitmap = nil) then
|
|
exit;
|
|
|
|
idx := ImageAtPos(X, Y);
|
|
if idx > -1 then
|
|
begin
|
|
ThumbRect := Rect( ImageX[idx], ImageY[idx], ImageX[idx] + ThumbSizeInfo( itsCell ).X, ImageY[idx] + ThumbSizeInfo( itsCell ).Y );
|
|
CbxRect := ThumbToCheckboxRect(ThumbRect);
|
|
|
|
if IEPointInRect(ViewX + x, ViewY + y, CbxRect) then
|
|
Result := idx
|
|
end;
|
|
end;
|
|
|
|
procedure TImageEnMView.ClickCheckboxAtPos(X, Y : Integer);
|
|
var
|
|
idx: Integer;
|
|
bNewChecked: Boolean;
|
|
begin
|
|
idx := CheckboxAtPos(X, Y);
|
|
if idx > -1 then
|
|
begin
|
|
bNewChecked := NOT Checked[idx];
|
|
if assigned(fOnCheckboxClick) then
|
|
OnCheckboxClick(Self, idx, bNewChecked);
|
|
Checked[idx] := bNewChecked;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.SelectionWidth
|
|
|
|
<FM>Declaration<FC>
|
|
property SelectionWidth: integer;
|
|
|
|
<FM>Description<FN>
|
|
Specifies the width (in pixels) of the border around selected frames.
|
|
|
|
Notes:
|
|
- If the control does not have focus, the selection width will be <A TImageEnMView.SelectionWidthNoFocus>
|
|
- This value must be less than <A TImageEnMView.HorizBorder> and <A TImageEnMView.VertBorder>.
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.SelectionColor>
|
|
- <A TImageEnMView.ThumbnailsBorderWidth>
|
|
- <A TImageEnMView.SelectedFontColor>
|
|
!!}
|
|
procedure TImageEnMView.SetSelectionBorderWidth(v: integer);
|
|
begin
|
|
fSelectionBorderWidth := v;
|
|
Update;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.SelectionWidthNoFocus
|
|
|
|
<FM>Declaration<FC>
|
|
property SelectionWidthNoFocus: integer;
|
|
|
|
<FM>Description<FN>
|
|
Specifies the width of the border around selected frames when the component doesn't have focus.
|
|
If the value is -1, it defaults to <A TImageEnMView.SelectionWidth>
|
|
|
|
Default: -1
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.SelectionWidth>
|
|
- <A TImageEnMView.SelectionColor>
|
|
- <A TImageEnMView.ThumbnailsBorderWidth>
|
|
- <A TImageEnMView.SelectedFontColor>
|
|
!!}
|
|
procedure TImageEnMView.SetSelectionBorderWidthNoFocus(v: integer);
|
|
begin
|
|
fSelectionBorderWidthNoFocus := v;
|
|
Update;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.SelectionColor
|
|
|
|
<FM>Declaration<FC>
|
|
property SelectionColor: TColor;
|
|
|
|
<FM>Description<FN>
|
|
Specifies the border color of selected cells.
|
|
|
|
Note: This value may be overridden if <A TIEImageEnGlobalSettings.EnableTheming> is enabled.
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.SelectionWidth>
|
|
- <A TImageEnMView.ThumbnailsBorderColor>
|
|
- <A TImageEnMView.SelectedFontColor>
|
|
!!}
|
|
procedure TImageEnMView.SetThumbnailsSelectedBorderColor(v: TColor);
|
|
begin
|
|
fThumbnailsSelectedBorderColor := v;
|
|
Update;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.BeginSelectImages
|
|
|
|
<FM>Declaration<FC>
|
|
procedure BeginSelectImages;
|
|
|
|
<FM>Description<FN>
|
|
Call BeginSelectImages and <A TImageEnMView.EndSelectImages> to select multiple images without refreshing the component's state.
|
|
|
|
Generally this will speed up the selection process.
|
|
|
|
<FM>Example<FC>
|
|
// select the first 100 images
|
|
ImageEnMView1.BeginSelectImages;
|
|
for i := 0 to 99 do
|
|
ImageEnMView1.SelectedImage := i;
|
|
ImageEnMView1.EndSelectImages;
|
|
|
|
!!}
|
|
procedure TImageEnMView.BeginSelectImages;
|
|
begin
|
|
DeselectNU;
|
|
fSelectImages := true;
|
|
fMultiSelecting := true;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.EndSelectImages
|
|
|
|
<FM>Declaration<FC>
|
|
procedure EndSelectImages;
|
|
|
|
<FM>Description<FN>
|
|
Call <A TImageEnMView.BeginSelectImages> and EndSelectImages to select multiple images without refreshing the component's state.
|
|
|
|
Generally this will speed up the selection process.
|
|
|
|
<FM>Example<FC>
|
|
// select the first 100 images
|
|
ImageEnMView1.BeginSelectImages;
|
|
for i := 0 to 99 do
|
|
ImageEnMView1.SelectedImage := i;
|
|
ImageEnMView1.EndSelectImages;
|
|
|
|
!!}
|
|
procedure TImageEnMView.EndSelectImages;
|
|
begin
|
|
fSelectImages := false;
|
|
fMultiSelecting := false;
|
|
if fMultiSelectedImages.Count > 0 then
|
|
begin
|
|
fSelectedItem := integer(fMultiSelectedImages[fMultiSelectedImages.Count - 1]); // select last selected image
|
|
fSelectedBitmap := nil;
|
|
fIEMBitmap.SetActiveImage( fSelectedItem );
|
|
end;
|
|
CallBitmapChangeEvents;
|
|
UpdateEx(false);
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.SelectedImage
|
|
|
|
<FM>Declaration<FC>
|
|
property SelectedImage: integer;
|
|
|
|
<FM>Description<FN>
|
|
Get or set the currently selected image (which will be drawn with a <L TImageEnMView.SelectionColor>colored border</L>.
|
|
|
|
You can get the bitmap of selected image using <A TImageEnMView.IEBitmap> or <A TImageEnMView.Bitmap>.
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.SelectedImageAlwaysVisible>
|
|
!!}
|
|
procedure TImageEnMView.SetSelectedItem(v: integer);
|
|
begin
|
|
if fPlaying then
|
|
exit;
|
|
if (not fMultiSelecting) and (v = fSelectedItem) then
|
|
exit;
|
|
if (v < fIEMBitmap.Count) and (v >= 0) then
|
|
begin
|
|
SetSelectedItemNU(v);
|
|
fPriorHSIDX := v;
|
|
if not fSelectImages then
|
|
UpdateEx(false, fSelectedImageAlwaysVisible);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TImageEnMView.SetMouseWheelParams(v: TIEMouseWheelParams);
|
|
begin
|
|
fMouseWheelParams.Assign( v );
|
|
end;
|
|
|
|
|
|
procedure TImageEnMView.SetMouseWheelParamsAlt(v: TIEMouseWheelParams);
|
|
begin
|
|
fMouseWheelParamsAlt.Assign( v );
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.SelectedImageAlwaysVisible
|
|
|
|
<FM>Declaration<FC>
|
|
property SelectedImageAlwaysVisible: Boolean; (Read/Write)
|
|
|
|
<FM>Description<FN>
|
|
Ensures that the selected cell is always visible when set using <A TImageEnMView.SelectedImage> or it changes due to <L TImageEnMView.AppendImage>appending</L> or <L TImageEnMView.DeleteImage>deleting</L> images.
|
|
|
|
Default: True
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.SelectedImage>
|
|
!!}
|
|
procedure TImageEnMView.SetSelectedImageAlwaysVisible(v: boolean);
|
|
begin
|
|
fSelectedImageAlwaysVisible := v;
|
|
if fSelectedImageAlwaysVisible then
|
|
CheckSelectedImageIsVisible;
|
|
end;
|
|
|
|
|
|
// doesn't call Update
|
|
// indexes which aren't inside bounds are ignored
|
|
procedure TImageEnMView.SetSelectedItemNU(v: integer);
|
|
var
|
|
i, q: integer;
|
|
begin
|
|
fChangedSel := false;
|
|
if fPlaying then
|
|
exit;
|
|
if (v < fIEMBitmap.Count) and (v >= 0) then
|
|
begin
|
|
if fSelectedItem >= 0 then
|
|
begin
|
|
if fSelectedBitmap <> nil then
|
|
fIEMBitmap.fImageList.ReleaseBitmap(fSelectedBitmap, true);
|
|
end;
|
|
if fEnableMultiSelect then
|
|
begin
|
|
if not fMultiSelecting then
|
|
begin
|
|
for i := 0 to fMultiSelectedImages.Count-1 do
|
|
DoImageDeselect( integer(fMultiSelectedImages[i]) );
|
|
fMultiSelectedImages.clear;
|
|
fChangedSel := true;
|
|
end
|
|
else
|
|
begin
|
|
if not fSelectImages then
|
|
begin
|
|
q := fMultiSelectedImages.IndexOf(pointer(v));
|
|
if (q > -1) and (not (iemoLeaveOneSelected in fMultiSelectionOptions) or (fMultiSelectedImages.Count > 1))then
|
|
begin
|
|
// item already selected, unselect when fMultiSelecting is True
|
|
DoImageDeselect( v );
|
|
fMultiSelectedImages.Delete(q);
|
|
fChangedSel := true;
|
|
if not fSelectInclusive then
|
|
begin
|
|
fSelectedItem := -1;
|
|
EXIT; // EXIT POINT!!
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
fMultiSelectedImages.Add(pointer(v));
|
|
fChangedSel := true;
|
|
end;
|
|
if fSelectImages then
|
|
begin
|
|
// inside BeginSelectImages...EndSelectimages the SelectedItem doesn't change (also fSelectedBitmap doesn't change)
|
|
fSelectedItem := -1;
|
|
fChangedSel := true;
|
|
end
|
|
else
|
|
begin
|
|
fSelectedItem := v;
|
|
fChangedSel := true;
|
|
fIEMBitmap.SetActiveImage( v );
|
|
fSelectedBitmap := nil;
|
|
CallBitmapChangeEvents;
|
|
DoImageSelect( fSelectedItem );
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.Deselect
|
|
|
|
<FM>Declaration<FC>
|
|
procedure Deselect;
|
|
|
|
<FM>Description<FN>
|
|
Remove selection from all selected images.
|
|
!!}
|
|
procedure TImageEnMView.DeSelect;
|
|
begin
|
|
DeselectNU;
|
|
UpdateEx(false);
|
|
end;
|
|
|
|
// doesn't call Update
|
|
procedure TImageEnMView.DeselectNU;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
if ( fSelectedItem >= 0 ) and ( fSelectedItem < ImageCount ) then
|
|
begin
|
|
fIEMBitmap.fImageList.ReleaseBitmapByImage(fIEMBitmap.GetImageInfo( fSelectedItem ).image, true);
|
|
end;
|
|
if fEnableMultiSelect then
|
|
begin
|
|
for i := 0 to fMultiSelectedImages.Count-1 do
|
|
DoImageDeselect( integer(fMultiSelectedImages[i]) );
|
|
fMultiSelectedImages.Clear();
|
|
end
|
|
else
|
|
DoImageDeselect( fSelectedItem );
|
|
fSelectedItem := -1;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.UnselectImage
|
|
|
|
<FM>Declaration<FC>
|
|
procedure UnselectImage(idx: Integer);
|
|
|
|
<FM>Description<FN>
|
|
Remove selection from the specified image (if multiselection is enabled).
|
|
|
|
!!}
|
|
procedure TImageEnMView.UnselectImage(idx: integer);
|
|
begin
|
|
if (idx >= 0) and (idx < ImageCount) and IsSelected(Idx) then
|
|
begin
|
|
if idx = fSelectedItem then
|
|
begin
|
|
fIEMBitmap.fImageList.ReleaseBitmapByImage( fIEMBitmap.GetImageInfo( fSelectedItem ).image, true );
|
|
ClearImageCache(fSelectedItem);
|
|
fMultiSelectedImages.Remove(pointer(idx));
|
|
fSelectedItem := -1;
|
|
end
|
|
else
|
|
begin
|
|
fMultiSelectedImages.Remove(pointer(idx));
|
|
end;
|
|
DoImageDeselect( fSelectedItem );
|
|
end;
|
|
UpdateEx(false);
|
|
end;
|
|
|
|
|
|
// Select image without affecting existing selection
|
|
procedure TImageEnMView.SelectImage(idx: integer);
|
|
begin
|
|
if (idx >= 0) and (idx < ImageCount) and (IsSelected(idx) = False) then
|
|
begin
|
|
fSelectImages := true;
|
|
fMultiSelecting := true;
|
|
|
|
SelectedImage := idx;
|
|
|
|
fSelectImages := false;
|
|
fMultiSelecting := false;
|
|
fSelectedItem := idx;
|
|
fSelectedBitmap := nil;
|
|
fIEMBitmap.SetActiveImage( idx );
|
|
CallBitmapChangeEvents;
|
|
end;
|
|
UpdateEx(false);
|
|
end;
|
|
|
|
// Selects an image if not selected, otherwise deselects. Does not change selection status of other files
|
|
procedure TImageEnMView.ToggleSelectImage(idx: integer);
|
|
begin
|
|
if (idx >= 0) and (idx < ImageCount) then
|
|
begin
|
|
if IsSelected(idx) then
|
|
UnselectImage(idx)
|
|
else
|
|
SelectImage(idx);
|
|
end;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.CopyToIEBitmap
|
|
|
|
<FM>Declaration<FC>
|
|
procedure CopyToIEBitmap(idx: Integer; bmp: <A TIEBitmap>);
|
|
|
|
<FM>Description<FN>
|
|
Copies the specified image, <FC>idx<FN>, to the destination <A TIEBitmap> object.
|
|
|
|
Note: If <A TImageEnMView.StoreType> is not ietNormal then the returned bmp will not be full resolution
|
|
|
|
<FM>Example<FC>
|
|
// Show the selected image in a TImageEnView
|
|
procedure TMainForm.ImageEnMView1ImageSelect(Sender: TObject; idx: Integer);
|
|
begin
|
|
ImageEnMView1.CopyToIEBitmap( idx, ImageEnView1.IEBitmap );
|
|
ImageEnVeiw1.Update;
|
|
end;
|
|
!!}
|
|
procedure TImageEnMView.CopyToIEBitmap(idx: integer; bmp: TIEBitmap);
|
|
begin
|
|
fThreadCS.Enter();
|
|
try
|
|
with fIEMBitmap.GetImageInfo( idx ) do
|
|
begin
|
|
// transform hbi to TBitmap object
|
|
if image = nil then
|
|
ObtainImageNow(idx);
|
|
if image <> nil then
|
|
begin
|
|
// image present
|
|
fIEMBitmap.fImageList.CopyToIEBitmap(image, bmp);
|
|
end;
|
|
end;
|
|
finally
|
|
fThreadCS.Leave();
|
|
end;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.GetBitmap
|
|
|
|
<FM>Declaration<FC>
|
|
function GetBitmap(idx: Integer): TBitmap;
|
|
|
|
<FM>Description<FN>
|
|
Creates a TBitmap object from the image at index, <FC>idx<FN>.
|
|
Any changes you make to the bitmap will be visible after you call the <A TImageEnMView.Update> method.
|
|
You will need to call <A TImageEnMView.ReleaseBitmap> to free the TBitmap object.
|
|
|
|
See also: <A TImageEnMView.GetTIEBitmap>.
|
|
|
|
<FM>Demo<FN>
|
|
<TABLE2>
|
|
<R> <C_IMG_DEMO> <C>Demos\Multi\Multiview_PrintFrame\Multiview.dpr </C> </R>
|
|
</TABLE>
|
|
|
|
<FM>Example<FC>
|
|
// Save the fifth image to file
|
|
bmp := ImageEnMView1.GetBitmap(4);
|
|
bmp.SaveToFile('alfa.bmp');
|
|
ImageEnMView1.ReleaseBitmap(4);
|
|
!!}
|
|
function TImageEnMView.GetBitmap(idx: integer): TBitmap;
|
|
begin
|
|
fThreadCS.Enter();
|
|
result := nil;
|
|
try
|
|
with fIEMBitmap.GetImageInfo( idx ) do
|
|
begin
|
|
// transform hbi to TBitmap object
|
|
if image = nil then
|
|
ObtainImageNow(idx);
|
|
if image <> nil then
|
|
begin
|
|
// image present
|
|
result := fIEMBitmap.fImageList.GetBitmap(image).VclBitmap;
|
|
end;
|
|
end;
|
|
finally
|
|
fThreadCS.Leave();
|
|
end;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.GetTIEBitmap
|
|
|
|
<FM>Declaration<FC>
|
|
function GetTIEBitmap(idx: Integer): <A TIEBitmap>;
|
|
|
|
<FM>Description<FN>
|
|
Creates a <A TIEBitmap> object from the image at index, <FC>idx<FN>.
|
|
Any changes you make to the bitmap will be visible after you call the <A TImageEnMView.Update> method.
|
|
You will need to call <A TImageEnMView.ReleaseBitmap> to free the <A TIEBitmap> object.
|
|
|
|
<FM>Example<FC>
|
|
// Save the fifth image to file
|
|
bmp := ImageEnMView1.GetTIEBitmap(4); // Note: bmp must be TIEBitmap type
|
|
bmp.Write('D:\alfa.png');
|
|
ImageEnMView1.ReleaseBitmap(4, False);
|
|
|
|
// Add copyright text to all images
|
|
for i := 0 to ImageEnMView1.ImageCount - 1 do
|
|
begin
|
|
bmp := ImageEnMView1.GetTIEBitmap( i );
|
|
with TImageEnProc.CreateFromBitmap( bmp ) do
|
|
begin
|
|
ConvertTo24Bit();
|
|
TextOut(Align_Text_Horz_Center, Align_Text_Near_Bottom, 'Copyright Skynet', 'Arial', 25, clRed, [fsBold], 0, True);
|
|
Free;
|
|
end;
|
|
|
|
ImageEnMView1.ReleaseBitmap( i, True );
|
|
ImageEnMView1.Update();
|
|
end;
|
|
!!}
|
|
function TImageEnMView.GetTIEBitmap(idx: integer): TIEBitmap;
|
|
begin
|
|
fThreadCS.Enter();
|
|
try
|
|
result := nil;
|
|
with fIEMBitmap.GetImageInfo( idx ) do
|
|
begin
|
|
// transform hbi to TBitmap object
|
|
if image = nil then
|
|
ObtainImageNow( idx );
|
|
if image <> nil then
|
|
begin
|
|
// image present
|
|
result := fIEMBitmap.fImageList.GetBitmap(image);
|
|
end;
|
|
end;
|
|
finally
|
|
fThreadCS.Leave();
|
|
end;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ReleaseBitmap
|
|
|
|
<FM>Declaration<FC>
|
|
procedure ReleaseBitmap(idx: Integer; saveChanges: Boolean = true);
|
|
|
|
<FM>Description<FN>
|
|
Releases the bitmap created with <A TImageEnMView.GetBitmap> or <A TImageEnMView.GetTIEBitmap> method.
|
|
|
|
<TABLE>
|
|
<R> <H>Parameter</H> <H>Description</H> </R>
|
|
<R> <C><FC>idx<FN></C> <C>The image index to release.</C> </R>
|
|
<R> <C><FC>saveChanges<FN></C> <C>If true (default) the bitmap will be written in the cache.</C> </R>
|
|
</TABLE>
|
|
|
|
<FM>Example<FC>
|
|
// Save the fifth image to file
|
|
bmp := ImageEnMView1.GetTIEBitmap(4); // Note: bmp must be TIEBitmap type
|
|
bmp.Write('D:\alfa.png');
|
|
ImageEnMView1.ReleaseBitmap(4, False);
|
|
|
|
// Add copyright text to all images
|
|
for i := 0 to ImageEnMView1.ImageCount - 1 do
|
|
begin
|
|
bmp := ImageEnMView1.GetTIEBitmap( i );
|
|
with TImageEnProc.CreateFromBitmap( bmp ) do
|
|
begin
|
|
ConvertTo24Bit();
|
|
TextOut(Align_Text_Horz_Center, Align_Text_Near_Bottom, 'Copyright Skynet', 'Arial', 25, clRed, [fsBold], 0, True);
|
|
Free;
|
|
end;
|
|
|
|
ImageEnMView1.ReleaseBitmap( i, True );
|
|
ImageEnMView1.Update();
|
|
end;
|
|
|
|
!!}
|
|
procedure TImageEnMView.ReleaseBitmap(idx: Integer; saveChanges: Boolean);
|
|
begin
|
|
fIEMBitmap.ReleaseBitmap( idx, saveChanges );
|
|
ClearImageCache(idx);
|
|
end;
|
|
|
|
procedure TImageEnMView.ClearOnDemandIOList;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
for i := 0 to fMultiOnDemands.Count-1 do
|
|
begin
|
|
TImageEnIO(fMultiOnDemands[i]).Free;
|
|
fMultiOnDemands[i] := nil;
|
|
end;
|
|
fMultiOnDemands.Clear;
|
|
end;
|
|
|
|
function TImageEnMView.GetOnDemandIO(const filename: WideString; var FrameIndex: Integer): TImageEnIO;
|
|
var
|
|
p: Integer;
|
|
realname: WideString;
|
|
begin
|
|
result := nil;
|
|
p := Pos(WideString(IEM_Path_Index_Delimiter), filename); // here the '::' must exist
|
|
realname := copy(filename, 1, p-1);
|
|
FrameIndex := StrToIntDef(Copy(filename, p+2, length(filename)), 0);
|
|
// search for already created on the same file
|
|
for p := 0 to fMultiOnDemands.Count-1 do
|
|
if TImageEnIO(fMultiOnDemands[p]).Params.FileName = realname then
|
|
begin
|
|
result := TImageEnIO(fMultiOnDemands[p]);
|
|
break;
|
|
end;
|
|
if result=nil then
|
|
begin
|
|
// create a new one
|
|
result := TImageEnIO.Create(self);
|
|
result.Params.FileName := realname;
|
|
fMultiOnDemands.Add( result );
|
|
end;
|
|
end;
|
|
|
|
procedure TImageEnMView.LoadMultiOnDemand(io: TImageEnIO; frameindex: Integer; var dt: Double);
|
|
var
|
|
FType : TIOFileType;
|
|
FileName: WideString;
|
|
begin
|
|
FileName := io.Params.FileName; // it is important that we don't pass io.Params.FileName as parameter
|
|
|
|
FType := IEExtToFileFormat(string(IEExtractFileExtW(FileName)));
|
|
if FType = ioUnknown then
|
|
FType := FindFileFormat(FileName, ffContentOnly);
|
|
|
|
dt := 0.0;
|
|
if (FType <> ioUnknown) and (FType <> ioAVI) and (FType <> ioWMV) and (FType <> ioMPEG) then
|
|
begin
|
|
io.Params.GIF_ImageIndex := frameindex;
|
|
io.Params.TIFF_ImageIndex := frameindex;
|
|
io.Params.DCX_ImageIndex := frameindex;
|
|
io.LoadFromFileAuto(FileName);
|
|
if FType = ioGIF then
|
|
dt := io.Params.GIF_DelayTime * 10;
|
|
end
|
|
else
|
|
begin
|
|
{$ifdef IEINCLUDEDIRECTSHOW}
|
|
if not io.IsOpenMediaFile then
|
|
io.OpenMediaFile(FileName);
|
|
io.LoadFromMediaFile(frameindex);
|
|
dt := io.Params.MEDIAFILE_FrameDelayTime * 10;
|
|
{$else}
|
|
if FType = ioAVI then
|
|
begin
|
|
if not io.IsOpenAVI then
|
|
io.OpenAVIFile(FileName);
|
|
io.LoadFromAVI(frameindex);
|
|
dt := io.Params.AVI_FrameDelayTime;
|
|
end;
|
|
{$endif}
|
|
end;
|
|
end;
|
|
|
|
function TImageEnMView.IsOnDemand(info: TIEImageInfo): Boolean;
|
|
begin
|
|
Result := False;
|
|
if info.Filename <> '' then
|
|
Result := True
|
|
else
|
|
if info.ID > -1 then
|
|
Result := assigned( fOnImageIDRequest ) or
|
|
assigned( fOnImageIDRequestEx ) or
|
|
fIEMBitmap.InternalLoadImageByID_Assigned();
|
|
end;
|
|
|
|
|
|
function IsMetaFile(const Filename: Widestring) : boolean;
|
|
begin
|
|
result := ( IEExtractFileExtW( Filename ) = '.emf' ) or
|
|
( IEExtractFileExtW( Filename ) = '.wmf' );
|
|
end;
|
|
|
|
|
|
// Make sure that at index "idx" there is a valid image (load from FileName or request it using ID).
|
|
// Returns true if the image load is ok, false otherwise
|
|
function TImageEnMView.ObtainImageNow(idx: integer): boolean;
|
|
var
|
|
info: TIEImageInfo;
|
|
bmp: TBitmap;
|
|
iebmp: TIEBitmap;
|
|
io: TImageEnIO;
|
|
bMultiOnDemand: Boolean;
|
|
frameindex: Integer; // used reading on demand multi pages
|
|
dt: Double;
|
|
ASource: TIESourceType;
|
|
IOParams: TIOParams;
|
|
begin
|
|
fThreadCS.Enter();
|
|
try
|
|
result := true;
|
|
bmp := nil;
|
|
IOParams := nil;
|
|
info := fIEMBitmap.GetImageInfo( idx );
|
|
ASource := info.SourceType;
|
|
|
|
if (info.ID > -1) and fIEMBitmap.InternalLoadImageByID_Assigned() then
|
|
try
|
|
// Internal request by ID
|
|
iebmp := nil;
|
|
IOParams := TIOParams.Create;
|
|
_SetLoadParams(Self, IOParams);
|
|
fIEMBitmap.InternalLoadImageByID( self, idx, info.ID, iebmp, IOParams );
|
|
|
|
// updates params of encapsulated TImageEnMIO object
|
|
StripOffIOParams( Self, IOParams );
|
|
GetImageEnMIO.Params[ idx ].Assign( IOParams ); // GetImageEnMIO creates TImageEnMIO if it doesn't exist
|
|
|
|
// set the image
|
|
SetIEBitmapEx( idx, iebmp );
|
|
ImageOriginalWidth [ idx ] := IOParams.OriginalWidth;
|
|
ImageOriginalHeight[ idx ] := IOParams.OriginalHeight;
|
|
if IOParams.EXIF_DateTimeOriginal2 > 0 then
|
|
info.CreateDate := IOParams.EXIF_DateTimeOriginal2;
|
|
if assigned( fOnImageLoaded ) then
|
|
fOnImageLoaded( self, idx );
|
|
except
|
|
result := false;
|
|
end
|
|
else
|
|
if (info.ID > -1) and assigned(fOnImageIDRequest) then
|
|
begin
|
|
// request by ID - BMP
|
|
bmp := nil;
|
|
fOnImageIDRequest( self, idx, info.ID, bmp );
|
|
SetImageEx( idx, bmp );
|
|
end
|
|
else
|
|
if (info.ID > -1) and assigned(fOnImageIDRequestEx) then
|
|
begin
|
|
// request by ID -IEBmp
|
|
iebmp := nil;
|
|
fOnImageIDRequestEx( self, idx, info.ID, iebmp );
|
|
SetIEBitmapEx( idx, iebmp );
|
|
end
|
|
else
|
|
if info.Filename <> '' then
|
|
begin
|
|
// load from File
|
|
bMultiOnDemand := Pos(WideString(IEM_Path_Index_Delimiter), WideString(info.Filename)) > 0; // this is the special syntax '::' to load multipages on demand, use ObtainImageNow
|
|
if bMultiOnDemand then
|
|
io := GetOnDemandIO(info.Filename, frameindex)
|
|
else
|
|
io := fImageEnIO;
|
|
|
|
iebmp := TIEBitmap.Create;
|
|
try
|
|
io.Background := info.Background;
|
|
io.AttachedIEBitmap := iebmp;
|
|
io.OnProgress := fOnIOProgress;
|
|
_SetLoadParams(Self, io.Params);
|
|
if assigned(fImageEnMIO) then
|
|
io.AutoAdjustDPI := fImageEnMIO.AutoAdjustDPI;
|
|
|
|
try
|
|
if fEnableLoadExplorerThumbnails and ( fStoreType in [ ietThumb, ietFastThumb ]) and
|
|
( not ( ietxOnlyShowIcons in fThumbnailOptionsEx )) and ( ASource <> iestFolderIcon )
|
|
{$IFDEF VIDEO_THUMBNAILS}
|
|
and ExtractExplorerThumbnail( info.Filename, iebmp, ThumbSizeInfo( itsImage ).X, ThumbSizeInfo( itsImage ).Y )
|
|
{$ENDIF}
|
|
then
|
|
begin
|
|
if ieixWantParams in fIOOptionsEx then
|
|
io.ParamsFromFile( info.Filename, True );
|
|
io.Aborting := False; // Image is valid, even if params are unavailable
|
|
end
|
|
else
|
|
if ietxOnlyShowIcons in fThumbnailOptionsEx then
|
|
begin
|
|
DoWrongImage(iebmp, idx, ASource);
|
|
if ieixWantParams in fIOOptionsEx then
|
|
io.ParamsFromFile( info.Filename, True );
|
|
io.Aborting := False; // Image is valid, even if params are unavailable
|
|
end
|
|
else
|
|
if bMultiOnDemand then
|
|
begin
|
|
// Has user aborted loading
|
|
if MIO.Aborting then
|
|
io.Aborting := true
|
|
else
|
|
LoadMultiOnDemand(io, frameindex, dt);
|
|
info.DTime := dt;
|
|
end
|
|
else
|
|
{$IFDEF VIDEO_THUMBNAILS}
|
|
if ( not fEnableLoadExplorerThumbnails ) and ( fStoreType in [ ietThumb, ietFastThumb ]) and UseThumbnailFromExplorer(info.Filename) then
|
|
io.Aborting := not ExtractExplorerThumbnail( info.Filename, iebmp, ThumbSizeInfo( itsImage ).X, ThumbSizeInfo( itsImage ).Y )
|
|
else
|
|
{$ENDIF}
|
|
if ( fStoreType in [ ietThumb, ietFastThumb ]) and IsMetaFile( info.Filename ) then
|
|
io.ImportMetafile(info.Filename, ThumbSizeInfo( itsImage ).X, -1, true)
|
|
else
|
|
begin
|
|
if ieixLoadOnlyByFileExt in fIOOptionsEx then
|
|
io.LoadFromFile( info.Filename, False )
|
|
else
|
|
io.LoadFromFileAuto( info.Filename );
|
|
if (iebmp.Width < 2) and
|
|
(iebmp.Height < 2) then
|
|
io.Aborting := true;
|
|
end;
|
|
except
|
|
io.Aborting := true;
|
|
end;
|
|
|
|
if io.Aborting then
|
|
begin
|
|
DoWrongImage(iebmp, idx, ASource);
|
|
result := false;
|
|
end;
|
|
|
|
// updates params of encapsulated TImageEnMIO object
|
|
StripOffIOParams(self, io.Params);
|
|
GetImageEnMIO.Params[idx].Assign(io.Params); // GetImageEnMIO creates TImageEnMIO if it doesn't exist
|
|
|
|
// set the image
|
|
info.Background := io.Background;
|
|
info.SourceType := ASource;
|
|
SetIEBitmapEx( idx, iebmp );
|
|
ImageOriginalWidth [ idx ] := io.Params.OriginalWidth;
|
|
ImageOriginalHeight[ idx ] := io.Params.OriginalHeight;
|
|
if io.Params.EXIF_DateTimeOriginal2 > 0 then
|
|
info.CreateDate := io.Params.EXIF_DateTimeOriginal2;
|
|
if assigned( fOnImageLoaded ) then
|
|
fOnImageLoaded( self, idx );
|
|
finally
|
|
io.AttachedIEBitmap := nil;
|
|
FreeAndNil(iebmp);
|
|
end;
|
|
|
|
end;
|
|
finally
|
|
FreeAndNil( IOParams );
|
|
fThreadCS.Leave();
|
|
end;
|
|
end;
|
|
|
|
// remove available threads or threads that want to load a no more visible image
|
|
procedure FreeUselessThreads(mview: TImageEnMView);
|
|
var
|
|
i: integer;
|
|
begin
|
|
i := 0;
|
|
with mview do
|
|
while i < fThreadPoolIO.Count do
|
|
begin
|
|
if TImageEnIO(fThreadPoolIO[i]).Tag = -1 then
|
|
begin
|
|
// finished thread
|
|
TImageEnIO(fThreadPoolIO[i]).IEBitmap.Free;
|
|
TImageEnIO(fThreadPoolIO[i]).IEBitmap := nil;
|
|
TImageEnIO(fThreadPoolIO[i]).AttachedIEBitmap := nil;
|
|
TImageEnIO(fThreadPoolIO[i]).Free;
|
|
fThreadPoolIO.delete(i);
|
|
end
|
|
else
|
|
if (TImageEnIO(fThreadPoolIO[i]).Tag >= 0) and (not IsVisible(TImageEnIO(fThreadPoolIO[i]).Tag)) and (not IsLookAhead(TImageEnIO(fThreadPoolIO[i]).Tag)) then
|
|
begin
|
|
// invisible image
|
|
TImageEnIO(fThreadPoolIO[i]).Tag := -2; // -2 controlled abort
|
|
TImageEnIO(fThreadPoolIO[i]).Aborting := true;
|
|
inc(i);
|
|
end
|
|
else
|
|
inc(i);
|
|
end;
|
|
end;
|
|
|
|
procedure FreeInvisibleRequests(mview: TImageEnMView);
|
|
var
|
|
i: integer;
|
|
begin
|
|
i := 0;
|
|
with mview do
|
|
if MaintainInvisibleImages <> -1 then
|
|
while i < fThreadRequests.Count do
|
|
begin
|
|
if (not IsVisible(integer(fThreadRequests[i]))) and (not IsLookAhead(integer(fThreadRequests[i]))) then
|
|
fThreadRequests.delete(i)
|
|
else
|
|
inc(i);
|
|
end;
|
|
end;
|
|
|
|
// -1 = not found, >-1 item index in fThreadRequests
|
|
function TImageEnMView.IsRequested(idx: Integer): Integer;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
result := -1;
|
|
fThreadCS.Enter();
|
|
try
|
|
for i := 0 to fThreadRequests.Count - 1 do
|
|
if integer(fThreadRequests[i]) = idx then
|
|
begin
|
|
result := i;
|
|
break;
|
|
end;
|
|
finally
|
|
fThreadCS.Leave();
|
|
end;
|
|
end;
|
|
|
|
// return false if info.ID > -1 and assigned OnImageIDRequest. Works only with info.Filename
|
|
// priority: -1 = lowest priority, 0..inf priority position
|
|
function TImageEnMView.ObtainImageThreaded(idx: integer; priority: Integer): boolean;
|
|
var
|
|
info: TIEImageInfo;
|
|
i: integer;
|
|
begin
|
|
result := false;
|
|
info := fIEMBitmap.GetImageInfo( idx );
|
|
|
|
// Is it the special syntax '::' to load multipages on demand? Use ObtainImageNow instead
|
|
if (info.Filename <> '') and (Pos(WideString(IEM_Path_Index_Delimiter), WideString(info.Filename)) > 0) then
|
|
exit;
|
|
|
|
// It is a folder icon? No advantage in threading
|
|
if info.SourceType = iestFolderIcon then
|
|
exit;
|
|
|
|
try
|
|
fThreadCS.Enter();
|
|
|
|
if info.image <> nil then
|
|
begin
|
|
result := true;
|
|
exit;
|
|
end;
|
|
|
|
// free no more visible requests
|
|
FreeInvisibleRequests(self);
|
|
|
|
if priority > -1 then
|
|
priority := imax(0, imin(priority, fThreadRequests.Count-1));
|
|
|
|
// check if already requested
|
|
i := IsRequested(idx);
|
|
if i > -1 then
|
|
begin
|
|
// already requested
|
|
if priority > -1 then
|
|
fThreadRequests.Move(i, priority);
|
|
result := true;
|
|
exit;
|
|
end;
|
|
|
|
// check if already processing it
|
|
for i := 0 to fThreadPoolIO.Count - 1 do
|
|
if TImageEnIO(fThreadPoolIO[i]).Tag = idx then
|
|
begin
|
|
// already in progress
|
|
result := true;
|
|
exit;
|
|
end;
|
|
|
|
// free available threads
|
|
FreeUseLessThreads(self);
|
|
|
|
if ( info.ID > -1 ) and ( assigned( fOnImageIDRequest ) or
|
|
assigned( fOnImageIDRequestEx ) or
|
|
fIEMBitmap.InternalLoadImageByID_Assigned() ) then
|
|
begin
|
|
// request by ID, it is better to use ObtainImageNow
|
|
exit;
|
|
end
|
|
else
|
|
if info.Filename <> '' then
|
|
begin
|
|
// Load from 'Name'.
|
|
// Add this request to the requests list.
|
|
if priority > -1 then
|
|
fThreadRequests.Insert(priority, pointer(idx))
|
|
else
|
|
fThreadRequests.Add(pointer(idx));
|
|
result := true;
|
|
exit;
|
|
end;
|
|
|
|
finally
|
|
Windows.SetEvent(fThreadStarter.resumeEvent);
|
|
fThreadCS.Leave();
|
|
end;
|
|
end;
|
|
|
|
{$IFDEF UNITTESTING}
|
|
function TImageEnMView.UnitTesting_ObtainImageThreaded(idx: integer): boolean;
|
|
begin
|
|
Result := ObtainImageThreaded( idx, -1 );
|
|
end;
|
|
{$ENDIF}
|
|
|
|
procedure _DoubleIconSize(ABitmap: TIEBitmap);
|
|
begin
|
|
_IEResampleIEBitmap2(ABitmap, rfNearest, ABitmap.Width * 2, ABitmap.Width * 2, nil, nil);
|
|
end;
|
|
|
|
|
|
function FileOrDirExists(const FileName: string): Boolean;
|
|
var
|
|
Code: Integer;
|
|
begin
|
|
Code := GetFileAttributes(PChar(FileName));
|
|
Result := Code <> -1;
|
|
end;
|
|
|
|
|
|
procedure TImageEnMView.DoWrongImage(OutBitmap: TIEBitmap; idx: integer; var ASourceType : TIESourceType);
|
|
var
|
|
OBitmap: TIEDibBitmap;
|
|
cv: TCanvas;
|
|
Handled: boolean;
|
|
ww, hh: integer;
|
|
iImgWidth, iImgHeight: Integer;
|
|
begin
|
|
Handled := false;
|
|
|
|
iImgHeight := ThumbSizeInfo( itsImage ).Y;
|
|
iImgWidth := ThumbSizeInfo( itsImage ).X;
|
|
|
|
if (ASourceType <> iestFolderIcon) and assigned(fOnWrongImage) and ( not ( ietxOnlyShowIcons in fThumbnailOptionsEx )) then
|
|
begin
|
|
OutBitmap.Allocate(iImgWidth, iImgHeight, ie24RGB);
|
|
fOnWrongImage(self, OutBitmap, idx, Handled);
|
|
if Handled then
|
|
ASourceType := iestCustomImage;
|
|
end;
|
|
|
|
if not Handled then
|
|
begin
|
|
// Note: For performance reasons ASourceType may not be iestFolderIcon even for folders
|
|
if ASourceType <> iestFolderIcon then
|
|
ASourceType := iestFileIcon;
|
|
{$ifdef VIDEO_THUMBNAILS}
|
|
if SameText( ImageFilename[idx], IEF_Drives_Folder ) then
|
|
begin
|
|
IEGetMyComputerIcon( OutBitmap );
|
|
if fEnableImageCaching then
|
|
fIconList.SaveToCache( OutBitmap, citIconOnly, ImageFilename[idx], False );
|
|
end
|
|
else
|
|
{$endif}
|
|
if ( (ASourceType = iestFolderIcon) or (ietxShowIconForUnknownFormat in fThumbnailOptionsEx) ) and
|
|
FileOrDirExists( ImageFilename[idx] ) then
|
|
begin
|
|
// LOAD SHELL ICON
|
|
|
|
if fIconList.RetrieveFromCache(citIconOnly, ImageFilename[idx], ASourceType = iestFolderIcon, OutBitmap, True) then
|
|
begin { OutBitmap now valid } end
|
|
else
|
|
{$IFDEF VIDEO_THUMBNAILS}
|
|
if IEIsWindowsVistaOrNewer and (fIconSize in [ieicStretchHD, ieicStretchAll]) then
|
|
begin
|
|
IEGetJumboFileIcon(ImageFileName[idx], OutBitmap);
|
|
if assigned( fOnImageOut ) then
|
|
fOnImageOut( Self, idx, OutBitmap );
|
|
if fEnableImageCaching then
|
|
fIconList.SaveToCache(OutBitmap, citIconOnly, ImageFilename[idx], ASourceType = iestFolderIcon);
|
|
end
|
|
else
|
|
{$ENDIF}
|
|
begin
|
|
IEGetFileIcon(ImageFileName[idx], OutBitmap);
|
|
if fIconSize <> ieicStandardSize then
|
|
_DoubleIconSize(OutBitmap);
|
|
if assigned( fOnImageOut ) then
|
|
fOnImageOut( Self, idx, OutBitmap );
|
|
if fEnableImageCaching then
|
|
fIconList.SaveToCache(OutBitmap, citIconOnly, ImageFilename[idx], ASourceType = iestFolderIcon);
|
|
end;
|
|
end
|
|
else
|
|
if ietxEnableInternalIcons in fThumbnailOptionsEx then
|
|
begin
|
|
// LOAD INTERNAL ICON
|
|
|
|
if ( (ietxShowIconForUnknownFormat in fThumbnailOptionsEx) = False ) and
|
|
FileOrDirExists( ImageFilename[idx] ) then
|
|
begin
|
|
// "Default" icon
|
|
if fDefaultFileIcon = nil then
|
|
fDefaultFileIcon := TIEBitmap.Create;
|
|
if ( fDefaultFileIcon.Width < iImgWidth ) or
|
|
( fDefaultFileIcon.Height < iImgHeight ) then
|
|
fDefaultFileIcon.LoadFromResource( HInstance, IMVRES_DEFAULT_IMAGE, RT_RCDATA, ioPNG );
|
|
|
|
OutBitmap.assign(fDefaultFileIcon);
|
|
end
|
|
else
|
|
begin
|
|
// "Broken" icon
|
|
if fMissingFileIcon = nil then
|
|
fMissingFileIcon := TIEBitmap.create;
|
|
if fMissingFileIcon.IsEmpty then
|
|
fMissingFileIcon.LoadFromResource( HInstance, IMVRES_BROKEN_IMAGE, RT_RCDATA, ioPNG );
|
|
|
|
OutBitmap.assign(fMissingFileIcon);
|
|
end
|
|
end
|
|
else
|
|
begin
|
|
// JUST SHOW A QUESTION MARK
|
|
OBitmap := TIEDibBitmap.Create;
|
|
OBitmap.AllocateBits(iImgWidth, iImgHeight, 24);
|
|
cv := TCanvas.Create;
|
|
cv.Handle := OBitmap.HDC;
|
|
cv.Brush.Color := clWhite;
|
|
cv.Brush.Style := bsSolid;
|
|
cv.FillRect(rect(0, 0, OBitmap.Width, OBitmap.Height));
|
|
cv.Font.Name := 'Arial';
|
|
cv.Font.Size := ThumbSizeInfo( itsCell ).Y;
|
|
cv.Font.Style := [fsBold];
|
|
ww := cv.TextWidth('?');
|
|
hh := cv.TextHeight('?');
|
|
cv.Font.Color := clGray;
|
|
cv.Brush.Style := bsClear;
|
|
cv.TextOut((integer(OBitmap.Width) - ww) div 2 + 3, (integer(OBitmap.Height) - hh) div 2 + 3, '?');
|
|
cv.Font.Color := clBlue;
|
|
cv.TextOut((integer(OBitmap.Width) - ww) div 2, (integer(OBitmap.Height) - hh) div 2, '?');
|
|
OutBitmap.CopyFromTDibBitmap(OBitmap);
|
|
FreeAndNil(cv);
|
|
FreeAndNil(OBitmap);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TImageEnMView.ThreadFinish(Sender: TObject);
|
|
var
|
|
io: TImageEnIO;
|
|
idx, ww, hh: integer;
|
|
bmp: TIEBitmap;
|
|
wDummy, hDummy : Integer;
|
|
ASourceType : TIESourceType;
|
|
bDoResample: Boolean;
|
|
begin
|
|
io := Sender as TImageEnIO;
|
|
ASourceType := iestDefault;
|
|
if io.IEBitmap.Width = 0 then
|
|
io.Aborting := True; // Deal with formats that do not require an image (meta-data only)
|
|
|
|
// prepare the thumbnail in this thread (instead of in SetIEBitmapEx that must be in monothread mode)
|
|
if (csDestroying in ComponentState) or (csDestroying in io.ComponentState) or (io.IEBitmap = nil) then
|
|
begin
|
|
fThreadCS.Enter();
|
|
try
|
|
io.Tag := -1;
|
|
Windows.SetEvent(fThreadStarter.resumeEvent);
|
|
finally
|
|
fThreadCS.Leave();
|
|
end;
|
|
exit;
|
|
end;
|
|
if ( ietxOnlyShowIcons in fThumbnailOptionsEx ) or io.Aborting then
|
|
begin
|
|
fThreadCS.Enter();
|
|
try
|
|
DoWrongImage(io.IEBitmap, io.Tag, ASourceType);
|
|
finally
|
|
fThreadCS.Leave();
|
|
end;
|
|
end;
|
|
if (fStoreType = ietThumb) and (GetEnableResamplingOnMinor or ( io.IEBitmap.Width > ThumbSizeInfo( itsImage ).X ) or ( io.IEBitmap.Height > ThumbSizeInfo( itsImage ).Y )) then
|
|
begin
|
|
if (io.IEBitmap.width = 0) or (io.IEBitmap.height = 0) then
|
|
begin
|
|
ww := ThumbSizeInfo( itsImage ).X;
|
|
hh := ThumbSizeInfo( itsImage ).Y;
|
|
end
|
|
else
|
|
begin
|
|
IEGetFitResampleSizeWithAutoCrop( io.IEBitmap.width, io.IEBitmap.height, ThumbSizeInfo( itsImage ).X, ThumbSizeInfo( itsImage ).Y, wDummy, hDummy, fThumbnailClipping, ww, hh );
|
|
end;
|
|
|
|
if GetEnableResamplingOnMinor then
|
|
bDoResample := (io.IEBitmap.Width <> ww) or (io.IEBitmap.Height <> hh)
|
|
else
|
|
bDoResample := (io.IEBitmap.Width > ww) or (io.IEBitmap.Height > hh);
|
|
|
|
if bDoResample then
|
|
begin
|
|
bmp := TIEBitmap.Create;
|
|
bmp.allocate(ww, hh, ie24RGB);
|
|
if io.IEBitmap.PixelFormat = ie1g then
|
|
begin
|
|
_SubResample1bitFilteredEx(io.IEBitmap, 0, 0, io.IEBitmap.width - 1, io.IEBitmap.height - 1, bmp)
|
|
end
|
|
else
|
|
begin
|
|
if (io.IEBitmap.PixelFormat <> ie24RGB) and (fThumbnailResampleFilter <> rfNone) then
|
|
io.IEBitmap.PixelFormat := ie24RGB;
|
|
if fThumbnailResampleFilter = rfNone then
|
|
begin
|
|
bmp.PixelFormat := io.IEBitmap.PixelFormat; // _IEBmpStretchEx supports multiple pixelformats, but input and output must have the same pixelformat
|
|
_IEBmpStretchEx(io.IEBitmap, bmp, nil, nil);
|
|
end
|
|
else
|
|
_ResampleEx(io.IEBitmap, bmp, nil, fThumbnailResampleFilter, nil, nil)
|
|
end;
|
|
if io.IEBitmap.HasAlphaChannel then
|
|
begin
|
|
if fThumbnailResampleFilter = rfNone then
|
|
_Resampleie8g(io.IEBitmap.AlphaChannel, bmp.AlphaChannel, rfFastLinear)
|
|
else
|
|
_Resampleie8g(io.IEBitmap.AlphaChannel, bmp.AlphaChannel, fThumbnailResampleFilter);
|
|
bmp.AlphaChannel.Full := io.IEBitmap.AlphaChannel.Full;
|
|
end;
|
|
end
|
|
else
|
|
bmp := io.IEBitmap;
|
|
end
|
|
else
|
|
bmp := io.IEBitmap;
|
|
|
|
fThreadCS.Enter();
|
|
try
|
|
idx := io.Tag;
|
|
if idx >= 0 then
|
|
begin
|
|
StripOffIOParams(self, io.Params);
|
|
GetImageEnMIO.Params[idx].Assign(io.Params);
|
|
fIEMBitmap.GetImageInfo( idx ).Background := io.Background;
|
|
if fIEMBitmap.GetImageInfo( idx ).SourceType <> iestFolderIcon then
|
|
fIEMBitmap.GetImageInfo( idx ).SourceType := ASourceType;
|
|
SetIEBitmapEx(idx, bmp);
|
|
ImageOriginalWidth[idx] := io.Params.OriginalWidth;
|
|
ImageOriginalHeight[idx] := io.Params.OriginalHeight;
|
|
if io.Params.EXIF_DateTimeOriginal2 > 0 then
|
|
ImageCreateDate[idx] := io.Params.EXIF_DateTimeOriginal2;
|
|
if assigned( fOnImageLoaded ) then
|
|
fOnImageLoaded( self, idx );
|
|
end;
|
|
if assigned(bmp) and (bmp <> io.IEBitmap) then
|
|
FreeAndNil(bmp);
|
|
io.Tag := -1;
|
|
Windows.SetEvent(fThreadStarter.resumeEvent);
|
|
finally
|
|
fThreadCS.Leave();
|
|
invalidate();
|
|
end;
|
|
end;
|
|
|
|
|
|
constructor TIEStarter.Create;
|
|
begin
|
|
resumeEvent := Windows.CreateEvent(nil, false, false, nil);
|
|
inherited Create(false); // create Not suspended
|
|
end;
|
|
|
|
destructor TIEStarter.Destroy;
|
|
begin
|
|
inherited;
|
|
Windows.CloseHandle(resumeEvent);
|
|
end;
|
|
|
|
procedure TIEStarter.Execute;
|
|
var
|
|
info: TIEImageInfo;
|
|
bmp: TIEBitmap;
|
|
io: TImageEnIO;
|
|
idx: integer;
|
|
begin
|
|
Windows.WaitForSingleObject(resumeEvent, INFINITE);
|
|
while not Terminated do
|
|
begin
|
|
mview.fThreadCS.Enter();
|
|
try
|
|
FreeUseLessThreads(mview);
|
|
FreeInvisibleRequests(mview);
|
|
while (not Terminated) and (mview.fThreadRequests.Count > 0) and (mview.fThreadPoolIO.Count < mview.fThreadPoolSize) do
|
|
try
|
|
idx := integer(mview.fThreadRequests[0]);
|
|
bmp := TIEBitmap.Create;
|
|
io := TImageEnIO.Create(nil);
|
|
io.Tag := idx;
|
|
mview.fThreadRequests.Delete(0);
|
|
mview.fThreadPoolIO.add(io);
|
|
io.AttachedIEBitmap := bmp;
|
|
info := mview.fIEMBitmap.GetImageInfo( idx );
|
|
io.Background := info.Background;
|
|
_SetLoadParams(mview, io.Params);
|
|
io.OnFinishWork := mview.ThreadFinish;
|
|
io.AsyncMode := true;
|
|
|
|
if mview.fEnableLoadExplorerThumbnails and ( mview.fStoreType in [ ietThumb, ietFastThumb ]) and
|
|
( not ( ietxOnlyShowIcons in mview.fThumbnailOptionsEx ))
|
|
{$IFDEF VIDEO_THUMBNAILS}
|
|
and ExtractExplorerThumbnail( info.Filename, bmp, mview.ThumbSizeInfo( itsImage ).X, mview.ThumbSizeInfo( itsImage ).Y )
|
|
{$ENDIF}
|
|
then
|
|
begin
|
|
if ieixWantParams in mview.fIOOptionsEx then
|
|
io.ParamsFromFile( info.Filename, True )
|
|
else
|
|
mview.ThreadFinish(io)
|
|
end
|
|
else
|
|
if ietxOnlyShowIcons in mview.fThumbnailOptionsEx then
|
|
begin
|
|
if ieixWantParams in mview.fIOOptionsEx then
|
|
io.ParamsFromFile( info.Filename, True )
|
|
else
|
|
mview.ThreadFinish(io);
|
|
end
|
|
else
|
|
{$IFDEF VIDEO_THUMBNAILS}
|
|
if ( not mview.fEnableLoadExplorerThumbnails ) and ( mview.fStoreType in [ ietThumb, ietFastThumb ]) and UseThumbnailFromExplorer(info.Filename) then
|
|
begin
|
|
io.Aborting := not ExtractExplorerThumbnail( info.Filename, bmp, mview.ThumbSizeInfo( itsImage ).X, mview.ThumbSizeInfo( itsImage ).Y );
|
|
mview.ThreadFinish(io);
|
|
end
|
|
else
|
|
{$ENDIF}
|
|
if ( mview.fStoreType in [ ietThumb, ietFastThumb ]) and IsMetaFile( info.Filename ) then
|
|
io.ImportMetafile(info.Filename, mview.ThumbSizeInfo( itsImage ).X, -1, true)
|
|
else
|
|
if ieixLoadOnlyByFileExt in mview.fIOOptionsEx then
|
|
io.LoadFromFile( info.Filename, False )
|
|
else
|
|
io.LoadFromFileAuto( info.Filename );
|
|
except
|
|
// Unexpected loading exception
|
|
end;
|
|
finally
|
|
mview.fThreadCS.Leave();
|
|
end;
|
|
if (not Terminated) and (mview.fThreadRequests.Count = 0) and (mview.fThreadPoolIO.Count=0) then
|
|
Windows.WaitForSingleObject(resumeEvent, INFINITE);
|
|
sleep(0); // allow other threads to execute
|
|
end;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.TextMargin
|
|
|
|
<FM>Declaration<FC>
|
|
property TextMargin : integer;
|
|
|
|
<FM>Description<FN>
|
|
Specifies the offset from the border that the text appears:
|
|
- Left and right side for all text types (or top and bottom if <A TImageEnMView.Style> is iemsFlatAndWide)
|
|
- From the top for <A TImageEnMView.ImageTopText>
|
|
- From the bottom for <A TImageEnMView.ImageBottomText>
|
|
|
|
Note: Setting TextMargin will automatically adjust <A TImageEnMView.UpperGap> and <A TImageEnMView.BottomGap>
|
|
|
|
Default: 0
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.UpperGap>
|
|
- <A TImageEnMView.BottomGap>
|
|
|
|
!!}
|
|
procedure TImageEnMView.SetTextMargin(v: integer);
|
|
begin
|
|
fTextMargin := v;
|
|
// Update fTopTextHeight and fBottomTextHeight
|
|
TopTextFontChange( nil );
|
|
BottomTextFontChange( nil );
|
|
Update;
|
|
end;
|
|
|
|
|
|
// If we are in Column mode return the height of the header area
|
|
// Note: Uses InfoTextFont for header text
|
|
function TImageEnMView.CurrentHeaderRowHeight : Integer;
|
|
begin
|
|
Result := 0;
|
|
|
|
if fInfoTextHeight = CALCULATE_NOW then
|
|
UpdateInfoTextHeight( True );
|
|
|
|
if ( fInfoTextHeight > 0 ) and ( fStyle = iemsColumns ) then
|
|
Result := fUpperGap + fInfoTextHeight + fBottomGap + 2;
|
|
end;
|
|
|
|
|
|
|
|
// If the style is set to iemsFlatAndWide then there is a text block on the RHS
|
|
// This function returns the width of that block, or 0 if style is not iemsFlatAndWide or iemsColumns
|
|
function TImageEnMView.CurrentTextBlockWidth() : integer;
|
|
var
|
|
iMaxWidth: Integer;
|
|
begin
|
|
if ( fStyle in [ iemsFlatAndWide, iemsColumns ]) = False then
|
|
Result := 0
|
|
else
|
|
begin
|
|
Result := fTextBlockWidth;
|
|
iMaxWidth := ClientWidth - trunc(fThumbWidth * fZoom / 100.0) - 2 * fHorizBorder;
|
|
if fTextBlockWidth < 0 then
|
|
begin
|
|
if fStyle = iemsColumns then
|
|
Result := CurrentTextColumnWidths( iemtpTop ) +
|
|
CurrentTextColumnWidths( iemtpBottom ) +
|
|
CurrentTextColumnWidths( iemtpInfo )
|
|
else
|
|
if fCurrentGridWidth = 1 then
|
|
Result := iMaxWidth
|
|
else
|
|
Result := 3 * trunc(fThumbWidth * fZoom / 100.0 );
|
|
end;
|
|
if Result > iMaxWidth then
|
|
Result := iMaxWidth;
|
|
end;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.TextBlockWidth
|
|
|
|
<FM>Declaration<FC>
|
|
property TextBlockWidth : integer;
|
|
|
|
<FM>Description<FN>
|
|
If <A TImageEnMView.Style> is set to iemsFlatAndWide or iemsColumns then all text is shown on the right-hand side of the thumbnail.
|
|
|
|
iemsFlatAndWide:
|
|
<IMG help_images\FlatWideThumb.jpg>
|
|
|
|
iemsColumns:
|
|
<IMG help_images\Columns.jpg>
|
|
|
|
<FC>TextBlockWidth<FN> specifies the width of the text block (Default: -1). If set to -1 then the value is automatic:
|
|
- If Style is iemsColumns then the width of all columns will match the width of the control (or the width of all column if custom widths <L TImageEnMView.TextColumnWidths>have been set</L>)
|
|
- If there is only one column (<A TImageEnMView.GridWidth> = 1) it will match the width of the control
|
|
- If there are multiple columns it will be three times the width of the thumbnail
|
|
|
|
Note: The actual TextBlockWidth will be automatically adjusted to ensure it fits within the display area
|
|
|
|
<FM>Example<FC>
|
|
// Display detail thumbnails to the width of the control
|
|
ImageEnMView1.LockUpdate;
|
|
ImageEnMView1.Style := iemsFlatAndWide;
|
|
ImageEnMView1.GridWidth := 1;
|
|
ImageEnMView1.TextBlockWidth := -1;
|
|
ImageEnMView1.UnlockUpdate;
|
|
|
|
// Display detail thumbnails 300 pixels wide
|
|
ImageEnMView1.LockUpdate;
|
|
ImageEnMView1.Style := iemsFlatAndWide;
|
|
ImageEnMView1.GridWidth := -1;
|
|
ImageEnMView1.TextBlockWidth := 300 - ImageEnMView1.ThumbWidth;
|
|
ImageEnMView1.UnlockUpdate;
|
|
|
|
// Display columns to the width of the control
|
|
ImageEnMView1.LockUpdate;
|
|
ImageEnMView1.Style := iemsColumns;
|
|
ImageEnMView1.TextBlockWidth := -1;
|
|
ImageEnMView1.UnlockUpdate;
|
|
|
|
// Display columns 300 pixels wide
|
|
ImageEnMView1.LockUpdate;
|
|
ImageEnMView1.Style := iemsColumns;
|
|
ImageEnMView1.TextBlockWidth := 300 - ImageEnMView1.ThumbWidth;
|
|
ImageEnMView1.UnlockUpdate;
|
|
!!}
|
|
procedure TImageEnMView.SetTextBlockWidth(v: integer);
|
|
begin
|
|
fTextBlockWidth := v;
|
|
Update;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.BottomGap
|
|
|
|
<FM>Declaration<FC>
|
|
property BottomGap: integer;
|
|
|
|
<FM>Description<FN>
|
|
Specifies the distance between the thumbnail image and its bottom border.
|
|
|
|
You can use BottomGap to reserve space for painting, e.g. custom text (with <A TImageEnMView.OnImageDraw>).
|
|
|
|
<FM>Compatibility Notes<FN>
|
|
In older versions, BottomGap would be internally increased to allow space for <L TImageEnMView.DefaultBottomText>bottom text</L>. This does not occur from v6.22.
|
|
To maintain consistent styling, an BottomGap of more than twelve is assumed to include text space (i.e. If BottomGap <= 12: ActualGap = BottomGap + Text_Height. If BottomGap > 12: ActualGap = BottomGap Only).
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.UpperGap>
|
|
- <A TImageEnMView.SideGap>
|
|
|
|
!!}
|
|
procedure TImageEnMView.SetBottomGap(v: integer);
|
|
begin
|
|
fBottomGap := v;
|
|
fIconList.Clear();
|
|
Update;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.UpperGap
|
|
|
|
<FM>Declaration<FC>
|
|
property UpperGap: integer;
|
|
|
|
<FM>Description<FN>
|
|
Specifies the distance between the thumbnail image and its top border.
|
|
|
|
You can use UpperGap to reserve space for painting, e.g. custom text (with <A TImageEnMView.OnImageDraw>).
|
|
|
|
<FM>Compatibility Notes<FN>
|
|
In older versions, UpperGap would be internally increased to allow space for <L TImageEnMView.DefaultTopText>top text</L>. This does not occur from v6.22.
|
|
To maintain consistent styling, an UpperGap of more than twelve is assumed to include text space (i.e. If UpperGap <= 12: ActualGap = UpperGap + Text_Height. If UpperGap > 12: ActualGap = UpperGap Only).
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.BottomGap>
|
|
- <A TImageEnMView.SideGap>
|
|
!!}
|
|
procedure TImageEnMView.SetUpperGap(v: integer);
|
|
begin
|
|
fUpperGap := v;
|
|
fIconList.Clear();
|
|
Update;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.SideGap
|
|
|
|
<FM>Declaration<FC>
|
|
property SideGap: integer;
|
|
|
|
<FM>Description<FN>
|
|
Specifies the distance between the thumbnail image and the borders on the left and right.
|
|
|
|
Note: Generally you will not need to use SideGap if you have enabled <L TImageEnMView.SoftShadow>soft shadows</L> which already include their own spacing.
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.UpperGap>
|
|
- <A TImageEnMView.BottomGap>
|
|
!!}
|
|
procedure TImageEnMView.SetSideGap(v: integer);
|
|
begin
|
|
fSideGap := v;
|
|
fIconList.Clear();
|
|
Update;
|
|
end;
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.Bitmap
|
|
|
|
<FM>Declaration<FC>
|
|
property Bitmap: TBitmap;
|
|
|
|
<FM>Description<FN>
|
|
The currently selected image as a TBitmap object.
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.IEBitmap>
|
|
- <A TImageEnMView.SelectedImage>
|
|
!!}
|
|
function TImageEnMView.GetFBitmap: TBitmap;
|
|
begin
|
|
result := nil;
|
|
if fSelectedItem >= 0 then
|
|
begin
|
|
if fSelectedBitmap = nil then
|
|
fSelectedBitmap := GetTIEBitmap(fSelectedItem);
|
|
if assigned(fSelectedBitmap) then
|
|
result := fSelectedBitmap.VclBitmap;
|
|
end;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.IEBitmap
|
|
|
|
<FM>Declaration<FC>
|
|
property IEBitmap: <A TIEBitmap>;
|
|
|
|
<FM>Description<FN>
|
|
The currently selected image as <A TIEBitmap> object.
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.Bitmap>
|
|
- <A TImageEnMView.SelectedImage>
|
|
!!}
|
|
function TImageEnMView.GetIEBitmap: TIEBitmap;
|
|
begin
|
|
if fSelectedItem >= 0 then
|
|
begin
|
|
if fSelectedBitmap = nil then
|
|
fSelectedBitmap := GetTIEBitmap(fSelectedItem);
|
|
result := fSelectedBitmap;
|
|
end
|
|
else
|
|
result := nil;
|
|
end;
|
|
|
|
procedure TImageEnMView.SetMouseInteract(v: TIEMMouseInteract);
|
|
begin
|
|
if v <> fMouseInteract then
|
|
fMouseInteract := v;
|
|
end;
|
|
|
|
procedure TImageEnMView.SetKeyInteract(v: TIEMKeyInteract);
|
|
begin
|
|
if v <> fKeyInteract then
|
|
fKeyInteract := v;
|
|
end;
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ThumbnailOptionsEx
|
|
|
|
<FM>Declaration<FC>
|
|
property ThumbnailOptionsEx: <A TIEMThumbnailOptionsEx>;
|
|
|
|
<FM>Description<FN>
|
|
Controls some <L TIEMThumbnailOptionsEx>advanced options</L> for the display of icons and thumbnails.
|
|
Default: [ietxShowIconForUnknownFormat, ietxShowIconWhileLoading, ietxEnableInternalIcons, ietxStretchSmallImages];
|
|
|
|
Note: You will need to update the display after changing ThumbnailOptionsEx, e.g. by calling ImageEnMView1.<A TImageEnMView.Update>;
|
|
!!}
|
|
|
|
procedure TImageEnMView.SetThumbnailOptionsEx(v: TIEMThumbnailOptionsEx);
|
|
begin
|
|
fThumbnailOptionsEx := v;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.IOOptionsEx
|
|
|
|
<FM>Declaration<FC>
|
|
property IOOptionsEx: <A TIEMIOOptionsEx>;
|
|
|
|
<FM>Description<FN>
|
|
Controls some <L TIEMIOOptionsEx>advanced options</L> for loading.
|
|
Default: [];
|
|
|
|
Note: You will need to update the display after changing IOOptionsEx, e.g. by calling ImageEnMView1.<A TImageEnMView.Update>;
|
|
!!}
|
|
|
|
procedure TImageEnMView.SetIOOptionsEx(v: TIEMIOOptionsEx);
|
|
begin
|
|
fIOOptionsEx := v;
|
|
end;
|
|
|
|
|
|
|
|
function TImageEnMView.ReplaceIEMConst(const DefaultText : TIEImageEnMViewDefaultText; idx : Integer) : WideString;
|
|
|
|
function ConcatAndIns(const Value1, Value2: string; const sDelimiter: string = ', '): string;
|
|
begin
|
|
if (Value1 <> '') and (Value2 <> '') then
|
|
Result := Value1 + sDelimiter + Value2
|
|
else
|
|
Result := Value1 + Value2;
|
|
end;
|
|
|
|
function _FileSize : string;
|
|
begin
|
|
Result := '';
|
|
if ImageFileSize[idx] > 0 then
|
|
Result := String(IEBytesToStr2(ImageFileSize[idx]));
|
|
end;
|
|
|
|
function _FileCreateDate(bIncludeTime : Boolean = False) : string;
|
|
var
|
|
ADateTime: TDateTime;
|
|
begin
|
|
ADateTime := ImageCreateDate[idx];
|
|
if ADateTime < 1 then
|
|
Result := ''
|
|
else
|
|
if bIncludeTime then
|
|
Result := DateTimeToStr(ADateTime)
|
|
else
|
|
Result := DateToStr(ADateTime)
|
|
end;
|
|
|
|
function _FileEditDate(bIncludeTime : Boolean = False) : string;
|
|
var
|
|
ADateTime: TDateTime;
|
|
begin
|
|
ADateTime := ImageEditDate[idx];
|
|
if ADateTime < 1 then
|
|
Result := ''
|
|
else
|
|
if bIncludeTime then
|
|
Result := DateTimeToStr(ADateTime)
|
|
else
|
|
Result := DateToStr(ADateTime)
|
|
end;
|
|
|
|
var
|
|
sDims: string;
|
|
begin
|
|
Result := '';
|
|
if DefaultText = iedtNone then
|
|
begin { // } end
|
|
else
|
|
if DefaultText = iedtFilename then
|
|
Result := GetDisplayName( ImageFileName[ idx ], True )
|
|
else
|
|
if DefaultText = iedtFilenameNoExt then
|
|
Result := IEExtractFilenameWithoutExt( GetDisplayName( ImageFilename[idx], True ))
|
|
else
|
|
if DefaultText = iedtFilePath then
|
|
Result := IEExtractFilePathW(ImageFilename[idx])
|
|
else
|
|
if DefaultText = iedtImageDimensions then
|
|
begin
|
|
if ImageOriginalWidth[idx] > 0 then
|
|
Result := IntToStr(ImageOriginalWidth[idx]) + ' x ' +
|
|
IntToStr(ImageOriginalHeight[idx]);
|
|
// REMOVED 6.2.2: 1bit or 24bit only: + ' x ' + IntToStr(ImageBitCount[idx]) + 'bit';
|
|
end
|
|
else
|
|
if DefaultText = iedtImageDimAndSize then
|
|
begin
|
|
sDims := '';
|
|
if ImageOriginalWidth[idx] > 0 then
|
|
sDims := IntToStr(ImageOriginalWidth[idx]) + ' x ' + IntToStr(ImageOriginalHeight[idx]);
|
|
Result := ConcatAndIns(sDims, _FileSize, ', ');
|
|
end
|
|
else
|
|
if DefaultText = iedtFileSize then
|
|
Result := _FileSize
|
|
else
|
|
if DefaultText = iedtFileCreateDate then
|
|
Result := _FileCreateDate
|
|
else
|
|
if DefaultText = iedtFileCreateDateTime then
|
|
Result := _FileCreateDate(True)
|
|
else
|
|
if DefaultText = iedtFileCreateDateAndSize then
|
|
Result := ConcatAndIns(_FileCreateDate, _FileSize, ', ')
|
|
else
|
|
if DefaultText = iedtFileEditDate then
|
|
Result := _FileEditDate
|
|
else
|
|
if DefaultText = iedtFileEditDateTime then
|
|
Result := _FileEditDate(True)
|
|
else
|
|
if DefaultText = iedtFileEditDateAndSize then
|
|
Result := ConcatAndIns(_FileEditDate, _FileSize, ', ')
|
|
else
|
|
if DefaultText = iedtFileType then
|
|
Result := GetImageFileType(idx)
|
|
else
|
|
if DefaultText = iedtFileExt then
|
|
Result := Uppercase( IEExtractFileExtS( GetDisplayName( ImageFilename[idx], True ) , False ));
|
|
end;
|
|
|
|
function TImageEnMView.ReplaceIEMConst(const ws : WideString; idx : Integer) : WideString;
|
|
var
|
|
DefaultText : TIEImageEnMViewDefaultText;
|
|
begin
|
|
Result := ws;
|
|
DefaultText := ConstToIEMDefaultText( ws );
|
|
if DefaultText <> iedtNone then
|
|
Result := ReplaceIEMConst( DefaultText, idx )
|
|
else
|
|
if Pos( IEM_ImageDict, Uppercase( Result )) = 1 then
|
|
try
|
|
// Text is $IEM_IMAGEDICT$"Key"
|
|
|
|
// Remove const
|
|
Delete( Result, 1, Length( IEM_ImageDict ));
|
|
|
|
// Remove quotes
|
|
if Result[ 1 ] = '"' then
|
|
Delete( Result, 1, 1 );
|
|
if Result[ Length( Result ) ] = '"' then
|
|
Delete( Result, Length( Result ), 1 );
|
|
|
|
Result := fIEMBitmap.ImageDictionary[ idx ].GetString( Result );
|
|
except
|
|
// Key not found
|
|
Result := '';
|
|
end;
|
|
end;
|
|
|
|
// info.image can be nil
|
|
procedure TImageEnMView.DrawImage(DestBitmap: TBitmap; info: TIEImageInfo; IsSelected: boolean; Index: integer);
|
|
const
|
|
Rounded_Corner_Size = 4;
|
|
var
|
|
ActThumbWidth, ActThumbHeight, ActTextBlockWidth: integer;
|
|
x1, y1: integer;
|
|
ActUpperGap, ActBottomGap: integer;
|
|
ith: integer; // infotext height
|
|
bFirstTextShown: Boolean;
|
|
sTopText, sInfoText, sBottomText: WideString;
|
|
iOverrideThumbWidth: Integer; // special handling of thumbnail size to output at width of only the displayed text
|
|
|
|
function _GetText(const Text: WideString; Position : TIEMTextPos; DefaultText: TIEImageEnMViewDefaultText) : WideString;
|
|
begin
|
|
Result := ReplaceIEMConst( Text, Index );
|
|
if Result = '' then
|
|
Result := ReplaceIEMConst( DefaultText, Index );
|
|
if assigned( fOnGetText ) then
|
|
begin
|
|
fOnGetText( Self, Index, Position, Result );
|
|
Result := ReplaceIEMConst( Result, Index );
|
|
end;
|
|
end;
|
|
|
|
// bCalculateOnly: Returns only the width of the cell with this text
|
|
function _OutputText(wsText: WideString; aFont: TFont; Position : TIEMTextPos; bCalculateOnly: Boolean = False) : Integer;
|
|
const
|
|
Text_Horz_Spacing = 2;
|
|
var
|
|
tw, th: integer;
|
|
iTextMaxWidth: Integer;
|
|
iTextLeft, iTextTop: Integer;
|
|
aBackgroundStyle: TBrushStyle;
|
|
aBGColor: TColor;
|
|
aTruncSide: TIEMTruncSide;
|
|
iBlockHeight: Integer;
|
|
iTextOffset: Integer;
|
|
fontColor: TColor;
|
|
begin
|
|
Result := 0;
|
|
|
|
// NO TEXT?
|
|
if wsText = '' then
|
|
exit;
|
|
|
|
DestBitmap.Canvas.Font.Assign( aFont );
|
|
aBackgroundStyle := fTextBackgroundStyle;
|
|
aBGColor := GetThemeColor( ietpThumbCellBackground, fTextBackgroundColor );
|
|
aTruncSide := fTextTruncSide;
|
|
|
|
if ( bCalculateOnly = False ) and assigned(fOnGetTextEx) then
|
|
begin
|
|
fOnGetTextEx(Self, Index, Position, wsText, DestBitmap.Canvas.Font,
|
|
aBackgroundStyle, aBGColor, aTruncSide);
|
|
if wsText = '' then exit;
|
|
end;
|
|
|
|
if Enabled = False then
|
|
fontColor := GetThemeColor( ietpThumbCellFontDisabled, Text_Color_When_Disabled )
|
|
else
|
|
if IsSelected then
|
|
fontColor := GetThemeColor( ietpThumbCellFontSelected, fSelectedFontColor )
|
|
else
|
|
fontColor := GetThemeColor( ietpThumbCellFont, aFont.Color );
|
|
if fontColor <> clNone_ then
|
|
DestBitmap.Canvas.Font.Color := fontColor;
|
|
|
|
DestBitmap.Canvas.Brush.Style := aBackgroundStyle;
|
|
if aBackgroundStyle <> bsClear then
|
|
DestBitmap.Canvas.Brush.Color := aBGColor;
|
|
|
|
// Truncate wide text
|
|
if CurrentTextBlockWidth = 0 then // Text not on RHS
|
|
iTextMaxWidth := ActThumbWidth - 2 * fTextMargin - Text_Horz_Spacing
|
|
else
|
|
if fStyle = iemsColumns then
|
|
begin
|
|
iTextMaxWidth := CurrentTextColumnWidths( Position ) - fTextMargin;
|
|
if bFirstTextShown = False then
|
|
dec( iTextMaxWidth, fTextMargin ); // need leading gap too
|
|
end
|
|
else
|
|
iTextMaxWidth := CurrentTextBlockWidth - 2 * fTextMargin;
|
|
if iTextMaxWidth <= 0 then
|
|
exit;
|
|
wsText := IETruncateStr(wsText, aTruncSide, DestBitmap.Canvas, iTextMaxWidth);
|
|
tw := IETextWidthW( DestBitmap.Canvas, wsText );
|
|
th := IETextHeightW( DestBitmap.Canvas, wsText );
|
|
|
|
// iemsFlat and iemsACD
|
|
if CurrentTextBlockWidth = 0 then // Text not on RHS
|
|
begin
|
|
iTextLeft := 1 + x1 + (ActThumbWidth - tw - 2) div 2;
|
|
case Position of
|
|
iemtpTop : iTextTop := y1 + fTextMargin;
|
|
iemtpInfo : iTextTop := y1 + ActThumbHeight - ActBottomGap - ith;
|
|
else { iemtpBottom } iTextTop := y1 + ActThumbHeight - th - 1 - fTextMargin;
|
|
end;
|
|
end
|
|
else
|
|
if fStyle = iemsColumns then
|
|
begin
|
|
iTextLeft := x1 + ActThumbWidth - ActTextBlockWidth;
|
|
if bFirstTextShown = False then
|
|
Inc( iTextLeft, fTextMargin ); // need leading gap too
|
|
if Position in [ iemtpBottom, iemtpInfo ] then
|
|
inc( iTextLeft, CurrentTextColumnWidths( iemtpTop ));
|
|
if Position in [ iemtpInfo ] then
|
|
inc( iTextLeft, CurrentTextColumnWidths( iemtpBottom ));
|
|
iTextTop := y1 + ( ActThumbHeight - th ) div 2;
|
|
end
|
|
else
|
|
// iemsFlatAndWide
|
|
begin
|
|
iTextLeft := x1 + ActThumbWidth + fTextMargin - ActTextBlockWidth;
|
|
iBlockHeight := ( ActThumbHeight - 2 * fTextMargin ) div 3;
|
|
iTextOffset := ( iBlockHeight - th ) div 2;
|
|
|
|
// Overlapping existing text? Reduce number of text blocks
|
|
if ( iTextOffset < 0 ) and ( Position <> iemtpBottom ) then
|
|
begin
|
|
iBlockHeight := ( ActThumbHeight - 2 * fTextMargin ) div 2;
|
|
iTextOffset := ( iBlockHeight - th ) div 2;
|
|
if ( iTextOffset < 0 ) and ( Position = iemtpTop ) then
|
|
begin
|
|
iBlockHeight := ( ActThumbHeight - 2 * fTextMargin ) div 1;
|
|
iTextOffset := ( iBlockHeight - th ) div 2;
|
|
end;
|
|
end;
|
|
|
|
// Still overlapping? Hide text
|
|
if ( iTextOffset < 0 ) then
|
|
begin
|
|
if bFirstTextShown then
|
|
exit
|
|
else
|
|
iTextOffset := 0;
|
|
end;
|
|
|
|
case Position of
|
|
iemtpTop : iTextTop := y1 + fTextMargin + iTextOffset;
|
|
iemtpInfo : iTextTop := y1 + fTextMargin + iBlockHeight + iTextOffset;
|
|
else { iemtpBottom } if bFirstTextShown = False then
|
|
iTextTop := y1 + ( ActThumbHeight - th ) div 2 // Vertically center it
|
|
else
|
|
iTextTop := y1 + fTextMargin + 2 * iBlockHeight + iTextOffset;
|
|
end;
|
|
end;
|
|
|
|
if bCalculateOnly then
|
|
Result := iTextLeft + tw + fSideGap - x1
|
|
else
|
|
begin
|
|
TextOutW(DestBitmap.Canvas.Handle, iTextLeft, iTextTop, @wsText[1], length(wsText));
|
|
if fStyle = iemsACD then
|
|
IEDraw3DRect(DestBitmap.Canvas, iTextLeft - 2, iTextTop, iTextLeft + tw + 1, iTextTop + th, clGray, clWhite);
|
|
end;
|
|
bFirstTextShown := True;
|
|
end;
|
|
|
|
// Return the minimum width of the thumbnail cell, if we cut it after the text
|
|
function _GetMinimumThumbWidth(): integer;
|
|
var
|
|
iWidth, iTotalWidth: Integer;
|
|
begin
|
|
Result := 0;
|
|
iTotalWidth := 0;
|
|
|
|
iWidth := _OutputText( sTopText, TopTextFont, iemtpTop, True );
|
|
if iWidth > iTotalWidth then
|
|
iTotalWidth := iWidth;
|
|
|
|
iWidth := _OutputText( sInfoText, InfoTextFont, iemtpInfo, True );
|
|
if iWidth > iTotalWidth then
|
|
iTotalWidth := iWidth;
|
|
|
|
iWidth := _OutputText( sBottomText, BottomTextFont, iemtpBottom, True );
|
|
if iWidth > iTotalWidth then
|
|
iTotalWidth := iWidth;
|
|
|
|
if ( iTotalWidth > 0 ) and ( iTotalWidth < ActThumbWidth ) then
|
|
Result := iTotalWidth;
|
|
end;
|
|
|
|
var
|
|
w, ww, hh, iw, ih, t1: integer;
|
|
cx1, cy1: integer;
|
|
iDrawImgW, iDrawImgH : integer;
|
|
pix, alpha: pbyte;
|
|
iebmp, ietmp: TIEBitmap;
|
|
filt: TResampleFilter;
|
|
backgroundColor: TColor;
|
|
ThumbRect: TRect;
|
|
ox, oy: Integer;
|
|
iec: TIECanvas;
|
|
iSoftShadowSize : Integer;
|
|
iFinalww, iFinalhh : Integer;
|
|
iThumbClipPercent: Integer;
|
|
bStretchSmallImages : Boolean;
|
|
bDoubleIconSize: Boolean;
|
|
bAddSoftShadow: Boolean;
|
|
borderWidth : integer;
|
|
begin
|
|
try
|
|
fThreadCS.Enter();
|
|
|
|
if fTopTextHeight = CALCULATE_NOW then
|
|
UpdateTopTextHeight( True );
|
|
if fInfoTextHeight = CALCULATE_NOW then
|
|
UpdateInfoTextHeight( True );
|
|
if fBottomTextHeight = CALCULATE_NOW then
|
|
UpdateBottomTextHeight( True );
|
|
|
|
if CurrentTextBlockWidth > 0 then // Text is on RHS of thumbnail
|
|
begin
|
|
ActUpperGap := (fUpperGap + fBottomGap ) div 2;
|
|
ActBottomGap := ActUpperGap;
|
|
end
|
|
else
|
|
if fShowText then
|
|
begin
|
|
{$ifdef IEIncludeDeprecatedInV6}
|
|
// Legacy Handling - Prior to v6.2.2 UpperGap was enlarged to handle text height
|
|
if fUpperGap > 12 then
|
|
ActUpperGap := fUpperGap
|
|
else
|
|
{$endif}
|
|
ActUpperGap := fUpperGap + fTopTextHeight;
|
|
|
|
{$ifdef IEIncludeDeprecatedInV6}
|
|
// Legacy Handling - Prior to v6.2.2 BottomGap was enlarged to handle text height
|
|
if fBottomGap > 12 then
|
|
ActBottomGap := fBottomGap
|
|
else
|
|
{$endif}
|
|
ActBottomGap := fBottomGap + fBottomTextHeight
|
|
end
|
|
else
|
|
begin
|
|
ActUpperGap := fUpperGap;
|
|
ActBottomGap := fBottomGap;
|
|
end;
|
|
ActThumbWidth := ThumbSizeInfo( itsCell ).X;
|
|
ActThumbHeight := ThumbSizeInfo( itsCell ).Y;
|
|
iOverrideThumbWidth := 0;
|
|
ActTextBlockWidth := CurrentTextBlockWidth;
|
|
x1 := info.X - fViewX;
|
|
y1 := info.Y - fViewY;
|
|
|
|
if assigned(fOnBeforeImageDraw) then
|
|
fOnBeforeImageDraw(self, Index, x1, y1, DestBitmap.Canvas);
|
|
|
|
if assigned(fThumbnailFrame) and assigned(fThumbnailFrameSelected) then
|
|
begin
|
|
ThumbRect := fThumbnailFrameRect;
|
|
if IsSelected then
|
|
fThumbnailFrameSelected.RenderToTBitmapEx(DestBitmap, x1, y1, ActThumbWidth - ActTextBlockWidth, ActThumbHeight, 0, 0, fThumbnailFrameSelected.Width, fThumbnailFrameSelected.Height)
|
|
else
|
|
fThumbnailFrame.RenderToTBitmapEx(DestBitmap, x1, y1, ActThumbWidth - ActTextBlockWidth, ActThumbHeight, 0, 0, fThumbnailFrame.Width, fThumbnailFrame.Height);
|
|
ActThumbWidth := ThumbRect.Right - ThumbRect.Left;
|
|
ActThumbHeight := ThumbRect.Bottom - ThumbRect.Top;
|
|
inc(x1, ThumbRect.Left);
|
|
inc(y1, ThumbRect.Top);
|
|
end;
|
|
|
|
if assigned(fOnBeforeImageDrawEx) then
|
|
begin
|
|
ThumbRect.Left := 0;
|
|
ThumbRect.Top := 0;
|
|
ThumbRect.Right := ActThumbWidth;
|
|
ThumbRect.Bottom := ActThumbHeight;
|
|
fOnBeforeImageDrawEx(self, Index, x1, y1, DestBitmap, ThumbRect);
|
|
ActThumbWidth := ThumbRect.Right - ThumbRect.Left;
|
|
ActThumbHeight := ThumbRect.Bottom - ThumbRect.Top;
|
|
inc(x1, ThumbRect.Left);
|
|
inc(y1, ThumbRect.Top);
|
|
end;
|
|
|
|
ith := 0;
|
|
if fShowText and ( CurrentTextBlockWidth = 0 ) then
|
|
ith := fInfoTextHeight;
|
|
iDrawImgH := ActThumbHeight - ActBottomGap - ActUpperGap - ith;
|
|
iDrawImgW := ActThumbWidth - ActTextBlockWidth - 2 * fSideGap;
|
|
cx1 := 0;
|
|
cy1 := 0;
|
|
ww := 0;
|
|
hh := 0;
|
|
|
|
if fShowText then
|
|
begin
|
|
bFirstTextShown := False;
|
|
|
|
// TOP TEXT
|
|
sTopText := _GetText(info.TopText, iemtpTop, fDefaultTopText );
|
|
|
|
// INFO TEXT
|
|
sInfoText := _GetText(info.InfoText, iemtpInfo, fDefaultInfoText );
|
|
|
|
// BOTTOM
|
|
sBottomText := _GetText(info.BottomText, iemtpBottom, fDefaultBottomText );
|
|
|
|
if fModernStyling and ( fStyle = iemsFlatAndWide ) and ( fThumbnailsBorderWidth = 0 ) then
|
|
iOverrideThumbWidth := _GetMinimumThumbWidth();
|
|
end;
|
|
|
|
if fFillThumbnail then
|
|
begin
|
|
// Image is background
|
|
if fDrawImageBackground then
|
|
backgroundColor := info.Background
|
|
else
|
|
// Normal (Unselected)
|
|
if IsSelected = False then
|
|
backgroundColor := GetThemeColor( ietpThumbCellBackground, fThumbnailsBackground )
|
|
else
|
|
// Selected
|
|
if Enabled then
|
|
backgroundColor := GetThemeColor( ietpThumbCellBackgroundSelected, fThumbnailsBackgroundSelected )
|
|
else
|
|
// Control Disabled
|
|
backgroundColor := GetThemeColor( ietpThumbCellBackgroundDisabledSelected, Thumbnail_Background_When_Disabled );
|
|
|
|
if iOverrideThumbWidth = 0 then
|
|
iOverrideThumbWidth := ActThumbWidth;
|
|
if fThumbnailsBorderCurved and ( fThumbnailsBackgroundStyle = iebsSolid ) then
|
|
begin
|
|
DestBitmap.Canvas.Pen.Style := psClear;
|
|
DestBitmap.Canvas.Brush.Color := backgroundColor;
|
|
DestBitmap.Canvas.Brush.Style := bsSolid;
|
|
DestBitmap.Canvas.RoundRect( x1, y1, x1 + iOverrideThumbWidth + 1, y1 +ActThumbHeight + 1, Rounded_Corner_Size, Rounded_Corner_Size );
|
|
DestBitmap.Canvas.Pen.Style := psSolid;
|
|
end
|
|
else
|
|
IEDrawBackground([], DestBitmap.Canvas, DestBitmap, fThumbnailsBackgroundStyle, backgroundColor, x1, y1, iOverrideThumbWidth, ActThumbHeight, x1, y1, x1 + iOverrideThumbWidth, y1 + ActThumbHeight, fChessboardSize, fChessboardBrushStyle, fChessboardColor2Customized,
|
|
GetThemeColor( ietpControlBackgroundGradientEnd, fGradientEndColor ),
|
|
nil, iewoNormal, nil);
|
|
end;
|
|
|
|
// paint the image
|
|
if (info.cacheImage = nil) and (info.image <> nil) then
|
|
begin
|
|
// cache empty
|
|
iw := fIEMBitmap.fImageList.GetImageWidth(info.image);
|
|
ih := fIEMBitmap.fImageList.GetImageHeight(info.image);
|
|
if (iw < 1) or (ih < 1) then
|
|
pix := nil
|
|
else
|
|
pix := fIEMBitmap.fImageList.GetImageBits(info.image);
|
|
alpha := fIEMBitmap.fImageList.GetAlphaBits(info.image);
|
|
|
|
iSoftShadowSize := 0;
|
|
bAddSoftShadow := False;
|
|
if fSoftShadow.Enabled then
|
|
case info.SourceType of
|
|
iestFolderIcon : bAddSoftShadow := ietxShowShadowForFolders in fThumbnailOptionsEx;
|
|
iestFileIcon : bAddSoftShadow := ietxShowShadowForIcons in fThumbnailOptionsEx;
|
|
else bAddSoftShadow := True;
|
|
end;
|
|
if bAddSoftShadow then
|
|
iSoftShadowSize := IESoftShadowSize(fSoftShadow.Radius, fSoftShadow.OffsetX, fSoftShadow.OffsetY);
|
|
if ( iSoftShadowSize > ActThumbHeight div 2 ) and ( ActThumbHeight < 50 ) then // No soft shadow for very small images
|
|
iSoftShadowSize := 0;
|
|
|
|
iThumbClipPercent := 0;
|
|
if (fThumbnailClipping > 0) and (info.SourceType in [iestDefault, iestCustomImage]) then
|
|
iThumbClipPercent := fThumbnailClipping;
|
|
|
|
IEGetFitResampleSizeWithAutoCrop(iw, ih, iDrawImgW - iSoftShadowSize, iDrawImgH - iSoftShadowSize, iFinalww, iFinalhh,
|
|
iThumbClipPercent, ww, hh);
|
|
|
|
bStretchSmallImages := False;
|
|
bDoubleIconSize := False;
|
|
if (info.SourceType in [iestFileIcon, iestFolderIcon]) = False then
|
|
bStretchSmallImages := GetEnableResamplingOnMinor
|
|
else
|
|
if IEIsWindowsVistaOrNewer and (fIconSize in [ieicStretchHD, ieicStretchAll]) then
|
|
begin
|
|
if ((iw > 32) and (ih > 32)) // HD Icon?
|
|
or (fIconSize = ieicStretchAll) then // Always stretch
|
|
bStretchSmallImages := True
|
|
else
|
|
bDoubleIconSize := ( iw * 2 < ww ) and ( ih * 2 < hh ) ;
|
|
end;
|
|
|
|
if (bStretchSmallImages = False) and (iw < iDrawImgW - iSoftShadowSize) and (ih < iDrawImgH - iSoftShadowSize) then
|
|
begin
|
|
ww := iw;
|
|
hh := ih;
|
|
iFinalww := iw;
|
|
iFinalhh := ih;
|
|
end;
|
|
|
|
if pix <> nil then
|
|
begin
|
|
ietmp := TIEBitmap.Create;
|
|
ietmp.EncapsulateMemory(pix, iw, ih, fIEMBitmap.fImageList.GetImagePixelFormat(info.image), false);
|
|
if alpha <> nil then
|
|
begin
|
|
ietmp.AlphaChannel.EncapsulateMemory(alpha, iw, ih, ie8g, true);
|
|
ietmp.AlphaChannel.Full := false;
|
|
end;
|
|
if ietmp.PixelFormat = ie8p then
|
|
CopyMemory(ietmp.PaletteBuffer, fIEMBitmap.fImageList.GetImagePalette(info.image), 256*SizeOf(TRGB));
|
|
|
|
if assigned( fOnImageOut ) then
|
|
begin
|
|
fOnImageOut( Self, Index, ietmp );
|
|
|
|
// Note: skip edge case: bStretchSmallImages = False
|
|
if ( ietmp.Width <> iw ) or ( ietmp.Height <> ih ) then
|
|
IEGetFitResampleSizeWithAutoCrop(ietmp.Width, ietmp.Height, iDrawImgW - iSoftShadowSize, iDrawImgH - iSoftShadowSize, iFinalww, iFinalhh,
|
|
iThumbClipPercent, ww, hh);
|
|
end;
|
|
|
|
|
|
iebmp := TIEBitmap.Create;
|
|
iebmp.Location := ieMemory;
|
|
|
|
if (ietmp.PixelFormat = ie1g) and ((ww < iw) or (hh < ih)) then
|
|
begin
|
|
filt := rfFastLinear;
|
|
iebmp.Allocate(ww, hh, ie24RGB);
|
|
end
|
|
else
|
|
begin
|
|
filt := fThumbnailDisplayFilter;
|
|
iebmp.Allocate(ww, hh, ietmp.PixelFormat);
|
|
end;
|
|
|
|
// Draw Wang and ImageEn annotations?
|
|
if fAnnotationsVisible and (fStoreType <> ietThumb) then
|
|
begin
|
|
iebmp.Assign( ietmp );
|
|
if GetImageEnMIO.Params[ Index ].ImageEnAnnot.IsEmpty = False then
|
|
GetImageEnMIO.Params[ Index ].ImageEnAnnot.DrawToBitmap( iebmp, True );
|
|
{$ifdef IEINCLUDEIMAGINGANNOT}
|
|
if GetImageEnMIO.Params[ Index ].ImagingAnnot.ObjectsCount > 0 then
|
|
GetImageEnMIO.Params[ Index ].ImagingAnnot.DrawToBitmap( iebmp, True );
|
|
{$endif}
|
|
_IEResampleIEBitmap2(iebmp, filt, ww, hh, nil, nil);
|
|
end
|
|
else
|
|
_IEResampleIEBitmap(ietmp, iebmp, filt, nil, nil);
|
|
|
|
if (iFinalww <> iebmp.Width) or (iFinalhh <> iebmp.Height) then
|
|
begin
|
|
iebmp.Resize(iFinalww, iFinalhh, 0, 255, iehCenter, ievCenter);
|
|
ww := iebmp.Width;
|
|
hh := iebmp.Height;
|
|
end
|
|
else
|
|
if bDoubleIconSize then
|
|
begin
|
|
_DoubleIconSize(iebmp);
|
|
ww := iebmp.Width;
|
|
hh := iebmp.Height;
|
|
end;
|
|
|
|
if fThumbsRounded > 0 then
|
|
begin
|
|
t1 := imin(ActThumbWidth - ActTextBlockWidth, ActThumbHeight) div fThumbsRounded;
|
|
_IERoundImage(iebmp, t1, t1, nil, nil);
|
|
end;
|
|
|
|
// draw shadow
|
|
if iSoftShadowSize > 0 then
|
|
begin
|
|
// deflate ww and hh to correct thumb size
|
|
ww := ww + iSoftShadowSize;
|
|
hh := hh + iSoftShadowSize;
|
|
|
|
with info.internalrect do
|
|
begin
|
|
ox := (ww - iebmp.Width) div 2;
|
|
oy := (hh - iebmp.Height) div 2;
|
|
Left := ox;
|
|
Top := oy;
|
|
Right := trunc(iebmp.Width + ox) + 1;
|
|
Bottom := trunc(iebmp.Height + oy) + 1;
|
|
end;
|
|
|
|
// APPLY SHADOW
|
|
_IEAddSoftShadow(iebmp, fSoftShadow.Radius, fSoftShadow.OffsetX, fSoftShadow.OffsetY, fSoftShadow.Intensity, true, fSoftShadow.ShadowColor, nil, nil);
|
|
end
|
|
else
|
|
begin
|
|
info.internalrect := Rect(0, 0, ww, hh);
|
|
end;
|
|
|
|
cx1 := x1 + (abs(ActThumbWidth - iebmp.Width) - ActTextBlockWidth) div 2;
|
|
cy1 := y1 + ActUpperGap + (abs(iDrawImgH - iebmp.Height)) div 2;
|
|
|
|
iebmp.RenderToTBitmapEx(DestBitmap, cx1, cy1, ww, hh, 0, 0, iebmp.Width, iebmp.Height, fEnableAlphaChannel, 255, filt, ielNormal);
|
|
if fEnableImageCaching then
|
|
begin
|
|
info.cacheImage := fCacheList.AddIEBitmap( iebmp );
|
|
fCacheList.SetImageOriginalWidth ( info.cacheImage, fIEMBitmap.fImageList.GetImageOriginalWidth ( info.image ));
|
|
fCacheList.SetImageOriginalHeight( info.cacheImage, fIEMBitmap.fImageList.GetImageOriginalHeight( info.image ));
|
|
if fImageCacheReusage = iecrStrict then
|
|
fCacheList.SetImageIdentifier( info.cacheImage, IntToStr( Index ) + '/' +info.Filename )
|
|
else
|
|
fCacheList.SetImageIdentifier( info.cacheImage, info.Filename );
|
|
|
|
if StoreType = ietFastThumb then
|
|
begin
|
|
fIEMBitmap.fImageList.Delete(info.image);
|
|
info.image := nil;
|
|
end;
|
|
end;
|
|
FreeAndNil(ietmp);
|
|
FreeAndNil(iebmp);
|
|
end;
|
|
end
|
|
else
|
|
if info.cacheImage <> nil then
|
|
begin
|
|
// use cached image
|
|
ww := fCacheList.GetImageWidth(info.cacheImage);
|
|
hh := fCacheList.GetImageHeight(info.cacheImage);
|
|
cx1 := x1 + abs(ActThumbWidth - ww - ActTextBlockWidth) div 2;
|
|
cy1 := y1 + ActUpperGap + abs(iDrawImgH - hh) div 2;
|
|
pix := fCacheList.GetImageBits(info.cacheImage);
|
|
alpha := fCacheList.GetAlphaBits(info.cacheImage);
|
|
ietmp := TIEBitmap.Create;
|
|
|
|
ietmp.EncapsulateMemory(pix, ww, hh, fCacheList.GetImagePixelFormat(info.cacheImage), false);
|
|
|
|
if ietmp.PixelFormat = ie8p then
|
|
CopyMemory(ietmp.PaletteBuffer, fCacheList.GetImagePalette(info.cacheImage), 256*SizeOf(TRGB));
|
|
|
|
if alpha <> nil then
|
|
begin
|
|
ietmp.AlphaChannel.EncapsulateMemory(alpha, ww, hh, ie8g, true);
|
|
ietmp.AlphaChannel.Full := false;
|
|
end;
|
|
|
|
ietmp.RenderToTBitmapEx(DestBitmap, cx1, cy1, ww, hh, 0, 0, ietmp.Width, ietmp.Height);
|
|
FreeAndNil(ietmp);
|
|
end
|
|
else
|
|
if ( ietxEnableInternalIcons in fThumbnailOptionsEx ) and
|
|
((( ietxShowIconWhileLoading in fThumbnailOptionsEx ) = False ) or // Don't show load icons
|
|
( ImageFilename[ Index ] = '' )) then // Don't have a file
|
|
begin
|
|
// Load embedded "Default" icon
|
|
if fDefaultFileIcon = nil then
|
|
fDefaultFileIcon := TIEBitmap.Create;
|
|
|
|
if ( fDefaultFileIcon.Width <> iDrawImgW ) or
|
|
( fDefaultFileIcon.Height <> iDrawImgH ) then
|
|
begin
|
|
// Load our "Default" icon from the application resource and resize it
|
|
fDefaultFileIcon.LoadFromResource( HInstance, 1000, RT_RCDATA, ioPNG );
|
|
IEGetFitResampleSize( fDefaultFileIcon.Width, fDefaultFileIcon.Height, iDrawImgW, iDrawImgH, ww, hh );
|
|
_IEResampleIEBitmap2( fDefaultFileIcon, fThumbnailDisplayFilter, ww, hh, nil, nil );
|
|
end;
|
|
|
|
cx1 := x1 + abs(ActThumbWidth - ActTextBlockWidth - fDefaultFileIcon.width) div 2;
|
|
cy1 := y1 + ActUpperGap + abs(iDrawImgH - fDefaultFileIcon.height) div 2;
|
|
ww := fDefaultFileIcon.Width;
|
|
hh := fDefaultFileIcon.Height;
|
|
|
|
fDefaultFileIcon.RenderToTBitmapEx(DestBitmap, cx1, cy1, ww, hh, 0, 0, fDefaultFileIcon.Width, fDefaultFileIcon.Height);
|
|
end
|
|
else
|
|
if ( ImageFilename[ Index ] <> '' ) and ( ietxShowIconWhileLoading in fThumbnailOptionsEx ) then
|
|
begin
|
|
// display shell icon while we are loading
|
|
|
|
if fIconList.RetrieveFromCache(citFullDraw, ImageFilename[Index], info.SourceType = iestFolderIcon, ietmp, False) then
|
|
begin
|
|
// Ietmp now points to a valid icon image (DON'T FREE)
|
|
cx1 := x1 + abs(ActThumbWidth - ActTextBlockWidth - ietmp.width) div 2;
|
|
cy1 := y1 + ActUpperGap + abs(iDrawImgH - ietmp.height) div 2;
|
|
ww := ietmp.Width;
|
|
hh := ietmp.Height;
|
|
|
|
ietmp.RenderToTBitmapEx(DestBitmap, cx1, cy1, ww, hh, 0, 0, ietmp.Width, ietmp.Height);
|
|
end
|
|
else
|
|
begin
|
|
ietmp := TIEBitmap.Create;
|
|
|
|
// Create icon image
|
|
if info.SourceType = iestFolderIcon then
|
|
bStretchSmallImages := IEIsWindowsVistaOrNewer and (fIconSize in [ieicStretchHD, ieicStretchAll])
|
|
else
|
|
bStretchSmallImages := IEIsWindowsVistaOrNewer and (fIconSize = ieicStretchAll);
|
|
IEGetFileIcon(ImageFilename[Index], ietmp);
|
|
if (bStretchSmallImages = False) and (fIconSize <> ieicStandardSize) then
|
|
_DoubleIconSize(ietmp);
|
|
|
|
if assigned( fOnImageOut ) then
|
|
fOnImageOut( Self, Index, ietmp );
|
|
|
|
iSoftShadowSize := 0;
|
|
if fSoftShadow.Enabled and (info.SourceType <> iestFolderIcon) then
|
|
iSoftShadowSize := IESoftShadowSize(fSoftShadow.Radius, fSoftShadow.OffsetX, fSoftShadow.OffsetY);
|
|
if ( iSoftShadowSize > ActThumbHeight div 2 ) and ( ActThumbHeight < 50 ) then // No soft shadow for very small images
|
|
iSoftShadowSize := 0;
|
|
|
|
IEGetFitResampleSize(ietmp.Width, ietmp.Height, iDrawImgW - iSoftShadowSize, iDrawImgH - iSoftShadowSize, ww, hh);
|
|
if (bStretchSmallImages = False) and ((ietmp.Width < iDrawImgW - iSoftShadowSize) or (ietmp.Height < iDrawImgH - iSoftShadowSize)) then
|
|
begin
|
|
ww := ietmp.Width;
|
|
hh := ietmp.Height;
|
|
end;
|
|
_IEResampleIEBitmap2(ietmp, fThumbnailDisplayFilter, ww, hh, nil, nil);
|
|
|
|
if iSoftShadowSize > 0 then
|
|
begin
|
|
// deflate ww and hh to correct thumb size
|
|
ww := ww + iSoftShadowSize;
|
|
hh := hh + iSoftShadowSize;
|
|
|
|
// APPLY SHADOW
|
|
_IEAddSoftShadow(ietmp, fSoftShadow.Radius, fSoftShadow.OffsetX, fSoftShadow.OffsetY, fSoftShadow.Intensity, true, fSoftShadow.ShadowColor, nil, nil);
|
|
end;
|
|
|
|
cx1 := x1 + (abs(ActThumbWidth - ww) - ActTextBlockWidth) div 2;
|
|
cy1 := y1 + ActUpperGap + (abs(iDrawImgH - hh)) div 2;
|
|
|
|
// Now save it to our cache for next time
|
|
if fEnableImageCaching then
|
|
fIconList.SaveToCache(ietmp, citFullDraw, ImageFilename[Index], info.SourceType = iestFolderIcon);
|
|
|
|
ietmp.RenderToTBitmapEx(DestBitmap, cx1, cy1, ww, hh, 0, 0, ietmp.Width, ietmp.Height);
|
|
FreeAndNil(ietmp);
|
|
end;
|
|
end;
|
|
|
|
if ((info.image <> nil) or (info.cacheImage <> nil)) and
|
|
(( cx1 <> 0 ) and (cy1 <> 0 )) then // 6.2.2 if info.image is not nil, but image is invalid (pix = nil) then we blank out areas of grid
|
|
begin
|
|
if fThumbnailsInternalBorder and not (info.SourceType in [iestFileIcon, iestFolderIcon]) then
|
|
begin
|
|
DestBitmap.Canvas.Pen.Color := fThumbnailsInternalBorderColor;
|
|
DestBitmap.Canvas.Pen.Width := 1;
|
|
DestBitmap.Canvas.Pen.Style := psSolid;
|
|
DestBitmap.Canvas.Brush.Style := bsClear;
|
|
with info.internalrect do
|
|
DestBitmap.Canvas.Rectangle(cx1 + Left, cy1 + Top, cx1 + Right, cy1 + Bottom);
|
|
end;
|
|
|
|
{ // REMOVED 7.0.0
|
|
// draw sides background (the area of the thumbnail where hte image is not painted)
|
|
if fFillThumbnail then
|
|
with DestBitmap.canvas do
|
|
begin
|
|
Brush.Color := backgroundColor;
|
|
|
|
if iOverrideThumbWidth = 0 then
|
|
iOverrideThumbWidth := ActThumbWidth;
|
|
Brush.Style := bsSolid;
|
|
FillRect(rect(x1, y1, cx1, y1 + ActThumbHeight)); // left
|
|
FillRect(rect(cx1 + ww, y1, x1 + iOverrideThumbWidth, y1 + ActThumbHeight)); // right
|
|
FillRect(rect(cx1, y1, cx1 + ww, cy1)); // up
|
|
FillRect(rect(cx1, cy1 + hh, cx1 + ww, y1 + ActThumbHeight)); // bottom
|
|
end; }
|
|
end;
|
|
|
|
// Draw top, bottom, info texts
|
|
if fShowText then
|
|
begin
|
|
bFirstTextShown := False;
|
|
|
|
// TOP TEXT
|
|
_OutputText( sTopText, TopTextFont, iemtpTop );
|
|
|
|
// INFO TEXT
|
|
_OutputText( sInfoText, InfoTextFont, iemtpInfo );
|
|
|
|
// BOTTOM
|
|
_OutputText( sBottomText, BottomTextFont, iemtpBottom );
|
|
end;
|
|
|
|
// iemsACD style
|
|
if fStyle = iemsACD then
|
|
IEDraw3DRect(DestBitmap.Canvas, cx1, cy1, cx1 + ww - 1, cy1 + hh - 1, clGray, clWhite); // 3D rect around the image
|
|
|
|
// Draw Checkbox
|
|
DrawCheckbox(DestBitmap.Canvas, Index, Rect(x1, y1, x1 + ActThumbWidth, y1 + ActThumbHeight), IsSelected);
|
|
|
|
// call OnImageDraw
|
|
if assigned(fOnImageDraw) then
|
|
fOnImageDraw(self, Index, x1, y1, DestBitmap.Canvas);
|
|
|
|
// call OnImageDraw2
|
|
if assigned(fOnImageDraw2) then
|
|
fOnImageDraw2(self, Index, x1, y1, Rect(cx1, cy1, cx1+ww, cy1+hh), DestBitmap.Canvas);
|
|
|
|
// THUMBNAIL BORDER
|
|
if IsSelected and Focused and ( fSelectionBorderWidth > -1 ) then
|
|
borderWidth := fSelectionBorderWidth
|
|
else
|
|
if IsSelected and ( fSelectionBorderWidthNoFocus > -1 ) then
|
|
borderWidth := fSelectionBorderWidthNoFocus
|
|
else
|
|
borderWidth := fThumbnailsBorderWidth;
|
|
|
|
if ( borderWidth > 0 ) {$ifndef OCXVERSION}and (not assigned(fOnBeforeImageDrawEx)){$endif} and ((fThumbnailFrame=nil) or (fThumbnailFrameSelected=nil)) then
|
|
begin
|
|
iec := TIECanvas.Create(DestBitmap.Canvas, true, true); // TIECanvas used to anti-alias the result look for -1
|
|
|
|
if Enabled = False then
|
|
iec.Pen.Color := GetThemeColor( ietpThumbCellBorderDisabled, Thumbnail_Border_When_Disabled )
|
|
else
|
|
if IsSelected then
|
|
iec.Pen.Color := GetThemeColor( ietpThumbCellBorderSelected, fThumbnailsSelectedBorderColor )
|
|
else
|
|
iec.Pen.Color := GetThemeColor( ietpThumbCellBorder, fThumbnailsBorderColor );
|
|
|
|
iec.Brush.Style := bsClear;
|
|
|
|
if iOverrideThumbWidth = 0 then
|
|
iOverrideThumbWidth := ActThumbWidth;
|
|
if fThumbnailsBorderCurved then
|
|
begin
|
|
iec.Pen.Width := borderWidth;
|
|
if borderWidth > 0 then
|
|
iec.RoundRect(x1 - borderWidth div 2, y1 - borderWidth div 2, x1 + iOverrideThumbWidth + borderWidth div 2, y1 + ActThumbHeight + borderWidth div 2, Rounded_Corner_Size, Rounded_Corner_Size);
|
|
end
|
|
else
|
|
begin
|
|
iec.Pen.Width := 1;
|
|
for w := 1 to borderWidth do
|
|
iec.Rectangle(x1 - w, y1 - w, x1 + iOverrideThumbWidth + w, y1 + ActThumbHeight + w);
|
|
end;
|
|
iec.Free;
|
|
end;
|
|
|
|
finally
|
|
fThreadCS.Leave();
|
|
end;
|
|
end;
|
|
|
|
|
|
// Return a description (Caption for column header) for a default text type
|
|
function IEMDefaultTextToStr(DefaultText: TIEImageEnMViewDefaultText): string;
|
|
begin
|
|
case DefaultText of
|
|
iedtFilename,
|
|
iedtFilenameNoExt : Result := iemsg( IEMsg_Filename );
|
|
iedtFilePath : Result := iemsg( IEMsg_Path );
|
|
iedtImageDimensions : Result := iemsg( IEMsg_ImageSize );
|
|
iedtImageDimAndSize : Result := iemsg( IEMsg_ImageProperties );
|
|
iedtFileSize : Result := iemsg( IEMsg_FileSize );
|
|
iedtFileCreateDate,
|
|
iedtFileCreateDateTime,
|
|
iedtFileCreateDateAndSize : Result := iemsg( IEMsg_CreateDate );
|
|
iedtFileEditDate,
|
|
iedtFileEditDateTime,
|
|
iedtFileEditDateAndSize : Result := iemsg( IEMsg_EditDate );
|
|
iedtFileType,
|
|
iedtFileExt : Result := iemsg( IEMsg_FileType );
|
|
|
|
// Handle custom captions
|
|
else { iedtNone } Result := iemsg( IEMsg_Caption );
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
// Used when fStyle is iemsColumns to draw a header (fixed) row at the top of the window
|
|
procedure TImageEnMView.DrawColumnsHeaderRow(DestBitmap: TBitmap);
|
|
var
|
|
ActThumbWidth, ActThumbHeight, ActTextBlockWidth: integer;
|
|
bFirstTextShown: Boolean;
|
|
iHeadHeight: Integer;
|
|
|
|
procedure _OutputText(DefaultText: TIEImageEnMViewDefaultText; Position : TIEMTextPos);
|
|
var
|
|
th: integer;
|
|
iTextMaxWidth: Integer;
|
|
iTextLeft, iTextTop: Integer;
|
|
aBackgroundStyle: TBrushStyle;
|
|
aBGColor: TColor;
|
|
aTruncSide: TIEMTruncSide;
|
|
wsText: WideString;
|
|
begin
|
|
wsText := IEMDefaultTextToStr( DefaultText );
|
|
|
|
if assigned( fOnGetText ) then
|
|
fOnGetText( Self, -1, Position, wsText );
|
|
|
|
// NO TEXT???
|
|
if wsText = '' then
|
|
begin
|
|
fTextColsCurrentRight[ Position ] := 0;
|
|
exit;
|
|
end;
|
|
|
|
DestBitmap.Canvas.Font.Assign( InfoTextFont ); // InfoTextFont used for all header captions
|
|
aBackgroundStyle := fTextBackgroundStyle;
|
|
aBGColor := GetThemeColor( ietpThumbCellBackground, fTextBackgroundColor );
|
|
aTruncSide := fTextTruncSide;
|
|
|
|
if assigned(fOnGetTextEx) then
|
|
begin
|
|
fOnGetTextEx(Self, -1, Position, wsText, DestBitmap.Canvas.Font,
|
|
aBackgroundStyle, aBGColor, aTruncSide);
|
|
if wsText = '' then exit;
|
|
end;
|
|
|
|
iTextLeft := ActThumbWidth - ActTextBlockWidth;
|
|
if Enabled = False then
|
|
DestBitmap.Canvas.Font.Color := Text_Color_When_Disabled;
|
|
|
|
DestBitmap.Canvas.Brush.Style := aBackgroundStyle;
|
|
if aBackgroundStyle <> bsClear then
|
|
DestBitmap.Canvas.Brush.Color := aBGColor;
|
|
|
|
// Truncate wide text
|
|
iTextMaxWidth := CurrentTextColumnWidths( Position ) - fTextMargin;
|
|
if bFirstTextShown = False then
|
|
dec( iTextMaxWidth, fTextMargin ); // need leading gap too
|
|
if iTextMaxWidth <= 0 then
|
|
begin
|
|
fTextColsCurrentRight[ Position ] := iTextLeft;
|
|
exit;
|
|
end;
|
|
|
|
wsText := IETruncateStr(wsText, aTruncSide, DestBitmap.Canvas, iTextMaxWidth);
|
|
th := IETextHeightW( DestBitmap.Canvas, wsText );
|
|
|
|
if bFirstTextShown = False then
|
|
Inc( iTextLeft, fTextMargin ); // need leading gap too
|
|
if Position in [ iemtpBottom, iemtpInfo ] then
|
|
inc( iTextLeft, CurrentTextColumnWidths( iemtpTop ));
|
|
if Position in [ iemtpInfo ] then
|
|
inc( iTextLeft, CurrentTextColumnWidths( iemtpBottom ));
|
|
iTextTop := ( ActThumbHeight - th ) div 2;
|
|
|
|
// For TImageEnFolderMView, draw a chevron to indicate sort order
|
|
DrawColumnsHeaderRowCell( DestBitmap.Canvas, Rect( iTextLeft, 0, iTextLeft + iTextMaxWidth, ActThumbHeight ), Position );
|
|
|
|
TextOutW(DestBitmap.Canvas.Handle, iTextLeft, iTextTop, @wsText[1], length(wsText));
|
|
bFirstTextShown := True;
|
|
|
|
fTextColsCurrentRight[ Position ] := iTextLeft + iTextMaxWidth;
|
|
end;
|
|
|
|
begin
|
|
iHeadHeight := CurrentHeaderRowHeight;
|
|
|
|
if iHeadHeight = 0 then
|
|
exit;
|
|
|
|
ActThumbWidth := ThumbSizeInfo( itsCell ).X;
|
|
ActThumbHeight := iHeadHeight;
|
|
ActTextBlockWidth := CurrentTextBlockWidth;
|
|
|
|
if fFillThumbnail then
|
|
IEDrawBackground([], DestBitmap.Canvas, DestBitmap, fBackgroundStyle,
|
|
GetThemeColor( ietpControlBackground, Background ),
|
|
0, 0, ActThumbWidth, ActThumbHeight, 0, 0, ActThumbWidth, ActThumbHeight, fChessboardSize, fChessboardBrushStyle, fChessboardColor2Customized,
|
|
GetThemeColor( ietpControlBackgroundGradientEnd, fGradientEndColor ),
|
|
nil, iewoNormal, nil);
|
|
|
|
if fShowText then
|
|
begin
|
|
bFirstTextShown := False;
|
|
|
|
// TOP TEXT
|
|
_OutputText( fDefaultTopText, iemtpTop );
|
|
|
|
// INFO TEXT
|
|
_OutputText( fDefaultInfoText, iemtpInfo );
|
|
|
|
// BOTTOM
|
|
_OutputText( fDefaultBottomText, iemtpBottom );
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.IsVisible
|
|
|
|
<FM>Declaration<FC>
|
|
function IsVisible(idx: Integer): Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Returns True if image, <FC>idx<FN>, is currently visible (i.e. not scrolled out of view).
|
|
|
|
Note: The result may not be valid if the control is not visible. Call Update() prior to <FC>IsVisible<FN> if you need to calculate for a non-visible control.
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.GetImageVisibility>
|
|
|
|
!!}
|
|
function TImageEnMView.IsVisible(idx: integer): boolean;
|
|
var
|
|
x1, y1: integer;
|
|
info: TIEImageInfo;
|
|
begin
|
|
info := fIEMBitmap.GetImageInfo( idx );
|
|
x1 := info.X - fViewX;
|
|
y1 := info.Y - fViewY;
|
|
result := _RectXRect(0, 0, width - 1, height - 1, x1, y1, x1 + ThumbSizeInfo( itsCell ).X - 1, y1 + ThumbSizeInfo( itsCell ).Y - 1);
|
|
end;
|
|
|
|
function TImageEnMView.IsLookAhead(idx: Integer): Boolean;
|
|
begin
|
|
result := fLookAheadList.IndexOf(pointer(idx)) > -1;
|
|
end;
|
|
|
|
|
|
procedure TImageEnMView.PaintBackgroundTo(DestBitmap: TBitmap);
|
|
begin
|
|
// draw global background
|
|
IEDrawBackground([], DestBitmap.Canvas, DestBitmap, fBackgroundStyle,
|
|
GetThemeColor( ietpControlBackground, fBackground ),
|
|
0, 0, ClientWidth, ClientHeight, 0, 0, 0, 0, fChessboardSize, fChessboardBrushStyle, fChessboardColor2Customized,
|
|
GetThemeColor( ietpControlBackgroundGradientEnd, fGradientEndColor ), nil, iewoNormal, nil);
|
|
// draw wallpaper
|
|
if assigned(fWallpaper.Graphic) then
|
|
case fWallpaperStyle of
|
|
iewoNormal : DestBitmap.Canvas.Draw(0, 0, fWallpaper.Graphic);
|
|
iewoStretch : DestBitmap.Canvas.StretchDraw(rect(0, 0, ClientWidth, ClientHeight), fWallpaper.Graphic);
|
|
iewoTile : TileBitmapOntoCanvas( DestBitmap.Canvas, ClientWidth, ClientHeight, fWallpaper.Graphic );
|
|
end;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.PaintTo
|
|
|
|
<FM>Declaration<FC>
|
|
procedure PaintTo(Canvas: TBitmap); virtual;
|
|
|
|
<FM>Description<FN>
|
|
Output the current view to a bitmap
|
|
!!}
|
|
procedure TImageEnMView.PaintTo(DestBitmap: TBitmap);
|
|
var
|
|
q, ne, nn, e: integer;
|
|
info: TIEImageInfo;
|
|
reloop: boolean;
|
|
xsel: boolean; // true if display as selected
|
|
firstvisible, lastvisible: Integer;
|
|
oldalldisplayed: Boolean;
|
|
displayPriority: Integer;
|
|
begin
|
|
PaintBackgroundTo(DestBitmap);
|
|
|
|
displayPriority := 0;
|
|
|
|
repeat
|
|
reloop := false;
|
|
|
|
if (fDisplayMode = mdSingle) and (fIEMBitmap.Count > 0) then
|
|
ne := 1 // one image at the time
|
|
else
|
|
ne := fIEMBitmap.Count;
|
|
|
|
if fPlaying or (fDisplayMode = mdSingle) then
|
|
begin
|
|
if fFrame >= fIEMBitmap.Count then
|
|
fFrame := fIEMBitmap.Count - 1;
|
|
if fFrame < 0 then
|
|
fFrame := 0;
|
|
q := fFrame;
|
|
end
|
|
else
|
|
q := 0;
|
|
|
|
oldalldisplayed := fAllDisplayed;
|
|
fAllDisplayed := true;
|
|
firstvisible := -1;
|
|
lastvisible := fIEMBitmap.Count-1;
|
|
|
|
for nn := 0 to ne - 1 do
|
|
begin
|
|
|
|
if assigned(fOnDrawProgress) and (ne > 1) then
|
|
fOnDrawProgress(Self, trunc(nn / ne * 100), q);
|
|
info := fIEMBitmap.GetImageInfo( q );
|
|
|
|
// check that the image is visible
|
|
if IsVisible(q) then
|
|
begin
|
|
if firstvisible = -1 then
|
|
firstvisible := q;
|
|
// try to obtain the image if not available
|
|
if (info.image = nil) and (info.cacheImage = nil) then
|
|
begin
|
|
oldalldisplayed := false;
|
|
if (fSelectedItem = q) or (fThreadPoolSize = 0) or (ObtainImageThreaded(q, displayPriority) = false) then
|
|
begin
|
|
if (not ObtainImageNow(q)) and ( ieixRemoveCorrupted in fIOOptionsEx ) then
|
|
begin
|
|
// remove corrupted image and re-loop
|
|
DeleteImageNU(nn);
|
|
reloop := true;
|
|
break;
|
|
end;
|
|
end;
|
|
end;
|
|
//
|
|
if fSelectedItem <> q then
|
|
begin
|
|
xsel := false;
|
|
if fEnableMultiSelect then
|
|
begin
|
|
e := fMultiSelectedImages.IndexOf(pointer(q));
|
|
xsel := e > -1;
|
|
end;
|
|
end
|
|
else
|
|
xsel := true;
|
|
xsel := xsel and (fVisibleSelection) and (fDisplayMode = mdGrid);
|
|
|
|
if (info.image = nil) and (info.cacheImage = nil) then
|
|
fAllDisplayed := false;
|
|
|
|
DrawImage( DestBitmap, info, xsel, q );
|
|
|
|
inc(displayPriority);
|
|
|
|
end
|
|
else
|
|
begin
|
|
if (firstvisible<>-1) and (lastvisible=fIEMBitmap.Count-1) then
|
|
lastvisible := q-1;
|
|
end;
|
|
|
|
inc(q);
|
|
if q = fIEMBitmap.Count then
|
|
q := 0;
|
|
end;
|
|
|
|
until not reloop;
|
|
|
|
DrawColumnsHeaderRow( DestBitmap );
|
|
|
|
// lookahead
|
|
if (fLookAhead>0) and (fThreadPoolSize>0) then
|
|
begin
|
|
if (lastvisible + 1 < fIEMBitmap.Count) then
|
|
begin
|
|
nn := fLookAhead;
|
|
fLookAheadList.Clear;
|
|
if lastvisible+nn>=fIEMBitmap.Count then
|
|
nn := fIEMBitmap.Count-1-lastvisible;
|
|
for q := lastvisible+1 to lastvisible+nn do
|
|
begin
|
|
info := fIEMBitmap.GetImageInfo( q );
|
|
if (info.image = nil) and (info.cacheImage = nil) then
|
|
begin
|
|
fLookAheadList.Add(pointer(q));
|
|
ObtainImageThreaded(q, -1);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
// discard invisible images
|
|
if fMaintainInvisibleImages >- 1 then
|
|
begin
|
|
nn := imax(fLookAhead, fMaintainInvisibleImages);
|
|
for q := 0 to fIEMBitmap.Count-1 do
|
|
if (q < firstvisible - nn) or (q > lastvisible + nn) then
|
|
begin
|
|
info := fIEMBitmap.GetImageInfo( q );
|
|
if IsOnDemand(info) and (info.image <> nil) then
|
|
begin
|
|
fIEMBitmap.fImageList.Delete(info.image);
|
|
info.image := nil;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
// draw done
|
|
if assigned(fOnDrawProgress) and (ne > 1) then
|
|
fOnDrawProgress(Self, 100, 0);
|
|
|
|
if fAllDisplayed and not oldalldisplayed and assigned(fOnAllDisplayed) then
|
|
fOnAllDisplayed(self);
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ReloadImage
|
|
|
|
<FM>Declaration<FC>
|
|
procedure ReloadImage(idx: Integer);
|
|
|
|
<FM>Description<FN>
|
|
Reloads the image at index, <FC>idx<FN>. Works only images loaded on demand (i.e. where you have set <A TImageEnMView.ImageFileName> or <A TImageEnMView.ImageID>).
|
|
!!}
|
|
procedure TImageEnMView.ReloadImage(idx: Integer);
|
|
var
|
|
info: TIEImageInfo;
|
|
begin
|
|
info := fIEMBitmap.GetImageInfo( idx );
|
|
if IsOnDemand(info) and (info.image<>nil) then
|
|
begin
|
|
fIEMBitmap.fImageList.Delete(info.image);
|
|
info.image := nil;
|
|
if info.cacheImage <> nil then
|
|
begin
|
|
fcacheList.Delete(info.cacheImage);
|
|
info.cacheImage := nil;
|
|
end;
|
|
end;
|
|
UpdateEx(false);
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.DisplayMode
|
|
|
|
<FM>Declaration<FC>
|
|
property DisplayMode: <A TIEMDisplayMode>;
|
|
|
|
<FM>Description<FN>
|
|
<TABLE>
|
|
<R> <H>View</H> <H>Method</H> </R>
|
|
<R> <C>Frame View</C> <C>To display a single frame of a multi-frame image (e.g. TIFF or AVI) set DisplayMode to mdSingle</C> </R>
|
|
<R> <C>Thumbnail View</C> <C>To display a vertically scrollable thumbnail grid set DisplayMode to mdGrid, and <A TImageEnMView.GridWidth> to -1</C> </R>
|
|
<R> <C>Single Row</C> <C>Set DisplayMode to mdGrid, and <A TImageEnMView.GridWidth> to 0</C> </R>
|
|
<R> <C>Single Column</C> <C>Set DisplayMode to mdGrid, and <A TImageEnMView.GridWidth> to 1</C> </R>
|
|
</TABLE>
|
|
|
|
Note: Animation display modes are also available using <A TImageEnMView.Animation>
|
|
|
|
<FM>Demo<FN>
|
|
<TABLE2>
|
|
<R> <C_IMG_DEMO> <C>Demos\Multi\Multiview\Multiview.dpr </C> </R>
|
|
</TABLE>
|
|
!!}
|
|
procedure TImageEnMView.SetDisplayMode(v: TIEMDisplayMode);
|
|
begin
|
|
if fShowThumbnailHint then
|
|
Hint := '';
|
|
if fPlaying then
|
|
fSaveDM := v
|
|
else
|
|
begin
|
|
fDisplayMode := v;
|
|
Update;
|
|
end;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.GridWidth
|
|
|
|
<FM>Declaration<FC>
|
|
property GridWidth: integer;
|
|
|
|
<FM>Description<FN>
|
|
GridWidth is the number of images per row. This property is active only when <A TImageEnMView.DisplayMode> is mdGrid.
|
|
|
|
Valid GridWidth values are:
|
|
|
|
<TABLE>
|
|
<R> <H>Value</H> <H>Description</H> </R>
|
|
<R> <C>-1</C> <C>Automatically adjust column count to match the component width (standard usage)</C> </R>
|
|
<R> <C>0</C> <C>Only one row</C> </R>
|
|
<R> <C>>0</C> <C>GridWidth images per row, e.g. set to 1 for a single vertical column</C> </R>
|
|
</TABLE>
|
|
|
|
You can center the thumbnail column(s) using <A TImageEnMView.ThumbnailOptionsEx>
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.DisplayMode>
|
|
|
|
!!}
|
|
procedure TImageEnMView.SetGridWidth(v: integer);
|
|
begin
|
|
fGridWidth := v;
|
|
fCurrentGridWidth := v;
|
|
Update;
|
|
end;
|
|
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.Playing
|
|
|
|
<FM>Declaration<FC>
|
|
property Playing: boolean;
|
|
|
|
<FM>Description<FN>
|
|
Enable Playing to display each image consecutively for its <A TImageEnMView.ImageDelayTime> time.
|
|
During playback, <A TImageEnMView.DisplayMode> property is set to mdSingle and the <A TImageEnMView.Deselect> method is called.
|
|
If <A TImageEnMView.PlayLoop> is enabled then the animation will replay continuously
|
|
|
|
!!}
|
|
procedure TImageEnMView.SetPlaying(v: boolean);
|
|
begin
|
|
if v = fPlaying then
|
|
exit;
|
|
if v then
|
|
begin
|
|
fSaveDM := fDisplayMode;
|
|
fSaveSel := fSelectedItem;
|
|
Deselect;
|
|
end;
|
|
fPlaying := v;
|
|
PlayFrame;
|
|
if not fPlaying then
|
|
begin
|
|
SetDisplayMode(fSaveDM);
|
|
SetSelectedItem(fSaveSel);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.CenterFrame
|
|
|
|
<FM>Declaration<FC>
|
|
procedure CenterFrame;
|
|
|
|
<FM>Description<FN>
|
|
Scrolls the view (by calling <A TImageEnMView.SetViewXY>) to display the current frame at a central position in the view.
|
|
|
|
Note: This method uses <A TImageEnMView.VisibleFrame> to determine the current frame, whereas <A TImageEnMView.CenterSelected> uses <A TImageEnMView.SelectedImage>.
|
|
!!}
|
|
// show the image indexed by VisibleFrame, put it at the center (when applicable)
|
|
procedure TImageEnMView.CenterFrame;
|
|
var
|
|
info: TIEImageInfo;
|
|
x, y: integer;
|
|
begin
|
|
if fSelectedItem >= 0 then
|
|
begin
|
|
info := fIEMBitmap.GetImageInfo( fFrame );
|
|
X := info.X - (( ClientWidth - ThumbSizeInfo( itsCell ).X ) div 2 );
|
|
Y := info.Y - (( ClientHeight - ThumbSizeInfo( itsCell ).Y ) div 2 );
|
|
SetViewXY(X, Y);
|
|
end;
|
|
end;
|
|
|
|
procedure TImageEnMView.PlayFrame;
|
|
var
|
|
info: TIEImageInfo;
|
|
rr: TRect;
|
|
iInterval: Integer;
|
|
bShowFrame : Boolean;
|
|
begin
|
|
if fTimerInProgress then
|
|
exit;
|
|
if csDestroying in ComponentState then
|
|
exit;
|
|
|
|
bShowFrame := True;
|
|
fTimerInProgress := true;
|
|
// remove timer
|
|
if fPlayTimer <> 0 then
|
|
begin
|
|
KillTimer(self.handle, 1);
|
|
fPlayTimer := 0;
|
|
end;
|
|
|
|
if fPlaying then
|
|
begin
|
|
if fDisplayMode <> mdSingle then
|
|
begin
|
|
fDisplayMode := mdSingle;
|
|
Update;
|
|
end;
|
|
if fFrame >= fIEMBitmap.Count then
|
|
fFrame := fIEMBitmap.Count - 1;
|
|
if fFrame < 0 then
|
|
exit;
|
|
info := fIEMBitmap.GetImageInfo( fFrame );
|
|
// show current frame
|
|
if assigned(fOnPlayFrame) then
|
|
fOnPlayFrame(self, fFrame, bShowFrame);
|
|
|
|
if bShowFrame then
|
|
begin
|
|
Paint;
|
|
rr := rect(0, 0, clientwidth, clientheight);
|
|
ValidateRect(self.handle, @rr); // cancel invalidate executed by CenterSelected
|
|
end;
|
|
|
|
// another loop
|
|
// prepare for next frame
|
|
if fFrame = fIEMBitmap.Count - 1 then
|
|
begin
|
|
fFrame := 0;
|
|
CallBitmapChangeEvents;
|
|
if not fPlayLoop then
|
|
begin
|
|
fPlaying := false;
|
|
fTimerInProgress := false;
|
|
exit; // EXIT!
|
|
end;
|
|
end
|
|
else
|
|
inc(fFrame);
|
|
|
|
if bShowFrame = False then
|
|
begin
|
|
// Skip this frame
|
|
PostMessage(Self.Handle, WM_TIMER, 0, 0);
|
|
end
|
|
else
|
|
begin
|
|
// run timer
|
|
iInterval := round(info.DTime);
|
|
if (iInterval < 1) and (IEExtractFileExtW(info.Filename) = '.gif') then
|
|
iInterval := Default_GIF_Animation_Delay_MS
|
|
else
|
|
if iInterval < 10 then
|
|
iInterval := 10; // compatibility with pre-v5.0.7 versions
|
|
fPlayTimer := SetTimer(self.handle, 1, iInterval, nil);
|
|
end;
|
|
end;
|
|
fTimerInProgress := false;
|
|
end;
|
|
|
|
procedure TImageEnMView.WMTimer(var Message: TWMTimer);
|
|
begin
|
|
PlayFrame;
|
|
end;
|
|
|
|
|
|
// look at fLastImOp
|
|
function TImageEnMView.GetLastOp(): integer;
|
|
begin
|
|
result := fLastImOp;
|
|
end;
|
|
|
|
|
|
// look at fLastImIdx
|
|
function TImageEnMView.GetLastOpIdx(): integer;
|
|
begin
|
|
result := fLastImIdx;
|
|
end;
|
|
|
|
|
|
// look at fLastImP1
|
|
function TImageEnMView.GetLastOpP1(): integer;
|
|
begin
|
|
result := fLastImP1;
|
|
end;
|
|
|
|
|
|
// look at fLastImGroup
|
|
function TImageEnMView.GetLastOpGroup(): TIEArrayOfInteger;
|
|
begin
|
|
result := fLastImGroup;
|
|
end;
|
|
|
|
|
|
// erase fLastImOp (in old versions this was done by GetLastOp)
|
|
procedure TImageEnMView.CallBitmapChangeEvents;
|
|
begin
|
|
inherited;
|
|
fLastImOp := IEM_OP_NONE;
|
|
end;
|
|
|
|
|
|
procedure TImageEnMView.SetLastImOp(LastImOp: integer; // last operation of insert(1)/delete(2)/move(3)/swap(4) (0=no op)
|
|
LastImIdx: integer; // index of processed image by fLastImOp
|
|
LastImP1: Integer); // param 1
|
|
begin
|
|
fLastImOp := LastImOp ;
|
|
fLastImIdx := LastImIdx ;
|
|
fLastImP1 := LastImP1 ;
|
|
SetLength(fLastImGroup, 0);
|
|
end;
|
|
|
|
procedure TImageEnMView.SetLastImOp(LastImOp: integer; // last operation of insert(1)/delete(2)/move(3)/swap(4) (0=no op)
|
|
LastImIdx: integer; // index of processed image by fLastImOp
|
|
LastImP1: Integer; // param 1
|
|
LastImGroup: TIEArrayOfInteger);
|
|
begin
|
|
SetLastImOp(LastImOp, LastImIdx, LastImP1);
|
|
fLastImGroup := LastImGroup;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.Clear
|
|
|
|
<FM>Declaration<FC>
|
|
procedure Clear;
|
|
|
|
<FM>Description<FN>
|
|
Removes all images from the TImageEnMView and releases any associated memory.
|
|
!!}
|
|
// recreate temp file (you can change the DefTEMPPATH and call Clear to make changes active)
|
|
procedure TImageEnMView.Clear;
|
|
begin
|
|
Reset( True );
|
|
end;
|
|
|
|
// Same as Clear, but doesn't clear the image list
|
|
procedure TImageEnMView.Reset(bClear: Boolean = False);
|
|
begin
|
|
Deselect;
|
|
ClearThreadsAndRequests;
|
|
if bClear then
|
|
begin
|
|
DeleteAllImages();
|
|
GetImageEnMIO.ParamsList.Clear;
|
|
fIEMBitmap.Clear;
|
|
end;
|
|
ClearOnDemandIOList;
|
|
|
|
ClearCache();
|
|
FreeAndNil(fCacheList);
|
|
fCacheList := TIEVirtualImageList.Create('ICACHE', GetImageCacheUseDisk);
|
|
|
|
fIconList.Clear();
|
|
Update;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.LockPaint
|
|
|
|
<FM>Declaration<FC>
|
|
procedure LockPaint;
|
|
|
|
<FM>Description<FN>
|
|
Increments the <L TImageEnMView.LockPaintCount>lock paint counter</L>. While <A TImageEnMView.LockPaintCount> is greater than zero all painting is disabled.
|
|
|
|
Use <A TImageEnMView.UnLockPaint> to unlock.
|
|
|
|
<FM>Example<FC>
|
|
// Disable painting of component
|
|
ImageEnMView1.LockPaint;
|
|
try
|
|
... Perform activities, e.g. appending many files
|
|
finally
|
|
// Re-enable painting and refresh view
|
|
ImageEnMView1.UnlockPaint;
|
|
end;
|
|
|
|
!!}
|
|
// increases fLockPaint
|
|
procedure TImageEnMView.LockPaint;
|
|
begin
|
|
inc(fLockPaint);
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.UnlockPaint
|
|
|
|
<FM>Declaration<FC>
|
|
function UnlockPaint: integer;
|
|
|
|
<FM>Description<FN>
|
|
Decrement the <L TImageEnMView.LockPaintCount>lock paint counter</L> (use after calling <A TImageEnMView.LockPaint>).
|
|
|
|
If the lock count is zero, then <A TImageEnMView.Update> is called to refresh the view.
|
|
|
|
Returns the lock count.
|
|
|
|
<FM>Example<FC>
|
|
// Disable painting of component
|
|
ImageEnMView1.LockPaint;
|
|
try
|
|
... Perform activities, e.g. appending many files
|
|
finally
|
|
// Re-enable painting and refresh view
|
|
ImageEnMView1.UnlockPaint;
|
|
end;
|
|
!!}
|
|
// decreases fLockPaint
|
|
// ret. current value (after the decrement)
|
|
function TImageEnMView.UnLockPaint: integer;
|
|
begin
|
|
if fLockPaint > 0 then
|
|
dec(fLockPaint);
|
|
if fLockPaint = 0 then
|
|
begin
|
|
if assigned(fAnimation) then
|
|
fAnimation.ImageCount := ImageCount;
|
|
UpdateEx(true, fSelectedImageAlwaysVisible);
|
|
end;
|
|
result := fLockPaint;
|
|
end;
|
|
|
|
// Decreases fLockPaint
|
|
// ret current value (after the decrement)
|
|
// doesn't call Update if fLockpaint=0
|
|
function TImageEnMView.NPUnLockPaint: integer;
|
|
begin
|
|
if fLockPaint > 0 then
|
|
dec(fLockPaint);
|
|
result := fLockPaint;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.LockUpdate
|
|
|
|
<FM>Declaration<FC>
|
|
procedure LockUpdate;
|
|
|
|
<FM>Description<FN>
|
|
Increments the <L TImageEnMView.LockUpdateCount>lock update counter</L>. While <A TImageEnMView.LockUpdateCount> is greater than zero all component updating is disabled.
|
|
|
|
Use <A TImageEnMView.UnLockUpdate> to unlock.
|
|
|
|
<FM>Example<FC>
|
|
// Disable updating of component
|
|
ImageEnMView1.LockUpdate;
|
|
try
|
|
... Perform activities, e.g. appending many files
|
|
finally
|
|
// Re-enable Updating and refresh view
|
|
ImageEnMView1.UnlockUpdate;
|
|
end;
|
|
|
|
!!}
|
|
// increases fLockUpdate
|
|
procedure TImageEnMView.LockUpdate;
|
|
begin
|
|
inc(fLockUpdate);
|
|
if IEMBitmap_IsTIEDBMultiBitmap and
|
|
( fIEMBitmap.fOwner = Self ) then
|
|
fIEMBitmap.LockUpdate;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.UnLockUpdate
|
|
|
|
<FM>Declaration<FC>
|
|
function UnlockUpdate: integer;
|
|
|
|
<FM>Description<FN>
|
|
Decrement the <L TImageEnMView.LockUpdateCount>lock update counter</L> (use after calling <A TImageEnMView.LockUpdate>).
|
|
|
|
If the lock count is zero, then <A TImageEnMView.Update> is called to refresh the view.
|
|
|
|
Returns the lock count.
|
|
|
|
<FM>Example<FC>
|
|
// Disable updating of component
|
|
ImageEnMView1.LockUpdate;
|
|
try
|
|
... Perform activities, e.g. appending many files
|
|
finally
|
|
// Re-enable updating and call update
|
|
ImageEnMView1.UnlockUpdate;
|
|
end;
|
|
|
|
!!}
|
|
// decreases fLockUpdate
|
|
// ret. current value (after the decrement)
|
|
function TImageEnMView.UnLockUpdate: integer;
|
|
begin
|
|
Result := UnLockUpdateEx;
|
|
end;
|
|
|
|
|
|
function TImageEnMView.UnLockUpdateEx: integer;
|
|
begin
|
|
if fLockUpdate > 0 then
|
|
dec(fLockUpdate);
|
|
if fLockUpdate = 0 then
|
|
begin
|
|
if assigned(fAnimation) then
|
|
fAnimation.ImageCount := ImageCount;
|
|
|
|
if IEMBitmap_IsTIEDBMultiBitmap and
|
|
( fIEMBitmap.fOwner = Self ) then
|
|
begin
|
|
fIEMBitmap.UnlockUpdate;
|
|
if fIEMBitmap.LockUpdateCount <> 0 then
|
|
UpdateEx(true, fSelectedImageAlwaysVisible); // Because UnlockUpdate will call TImageEnMView.Update anyway
|
|
end
|
|
else
|
|
UpdateEx(true, fSelectedImageAlwaysVisible);
|
|
end;
|
|
result := fLockUpdate;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.GetImageVisibility
|
|
|
|
<FM>Declaration<FC>
|
|
function GetImageVisibility(idx: Integer): Integer;
|
|
|
|
<FM>Description<FN>
|
|
Returns 0 if image, <FC>idx<FN>, is not visible, 1 if it's partially visible, or 2 if it's fully visible (i.e. not scrolled out of view).
|
|
|
|
Note: The result may not be valid if the control is not visible. Call Update() prior to <FC>IsVisible<FN> if you need to calculate for a non-visible control.
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.IsVisible>
|
|
!!}
|
|
function TImageEnMView.GetImageVisibility(idx: integer): integer;
|
|
var
|
|
x1, y1: integer;
|
|
info: TIEImageInfo;
|
|
begin
|
|
result := 0;
|
|
if (idx >= 0) and (idx < fIEMBitmap.Count) then
|
|
begin
|
|
info := fIEMBitmap.GetImageInfo( idx );
|
|
x1 := info.X - fViewX;
|
|
y1 := info.Y - fViewY;
|
|
result := _RectPRect(0, 0, clientwidth - 1, clientheight - 1, x1, y1, x1 + ThumbSizeInfo( itsCell ).X - 1, y1 + ThumbSizeInfo( itsCell ).Y - 1);
|
|
end;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.UpdateImage
|
|
|
|
<FM>Declaration<FC>
|
|
procedure UpdateImage(idx: Integer);
|
|
|
|
<FM>Description<FN>
|
|
Redraw the image, <FC>idx<FN>.
|
|
|
|
Whenever an image (Bitmap) within a TImageEnMView changes, you must update the component with <A TImageEnMView.Update> or <A TImageEnMView.UpdateImage>.
|
|
|
|
<FM>Example<FC>
|
|
// Draw a rectangle on the fourth image
|
|
var
|
|
bmp: TBitmap;
|
|
begin
|
|
bmp := ImageEnMView1.GetBitmap(3);
|
|
bmp.canvas.rectangle(0, 0, 10, 10);
|
|
ImageEnMView1.ReleaseBitmap(3);
|
|
UpdateImage(3);
|
|
end;
|
|
!!}
|
|
procedure TImageEnMView.UpdateImage(idx: integer);
|
|
begin
|
|
_UpdateImage(idx, False);
|
|
end;
|
|
|
|
procedure TImageEnMView._UpdateImage(idx: integer; bInvalidateOnly : Boolean);
|
|
var
|
|
rc: TRect;
|
|
x1, y1: integer;
|
|
info: TIEImageInfo;
|
|
begin
|
|
if (idx >= 0) and (idx < fIEMBitmap.Count) then
|
|
begin
|
|
if bInvalidateOnly = False then
|
|
begin
|
|
ClearImageCache(idx);
|
|
UpdateEx(false);
|
|
end;
|
|
ValidateRect(self.handle, nil);
|
|
|
|
if assigned(fAnimation) then
|
|
fAnimation.RestartAnimation();
|
|
|
|
info := fIEMBitmap.GetImageInfo( idx );
|
|
x1 := info.X - fViewX;
|
|
y1 := info.Y - fViewY;
|
|
rc := Rect( x1, y1, x1 + ThumbSizeInfo( itsCell ).X, y1 + ThumbSizeInfo( itsCell ).Y );
|
|
InvalidateRect(self.handle, @rc, false);
|
|
end;
|
|
end;
|
|
|
|
procedure TImageEnMView.CMWantSpecialKey(var Msg: TCMWantSpecialKey);
|
|
begin
|
|
inherited;
|
|
case msg.CharCode of
|
|
VK_LEFT, VK_RIGHT, VK_UP, VK_DOWN,
|
|
VK_PRIOR, VK_NEXT, VK_HOME, VK_END:
|
|
msg.Result := 1;
|
|
end;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.CenterSelected
|
|
|
|
<FM>Declaration<FC>
|
|
procedure CenterSelected;
|
|
|
|
<FM>Description<FN>
|
|
Scrolls the view (by calling <A TImageEnMView.SetViewXY>) to display the currently selected image at a central position in the view.
|
|
|
|
Note: This method uses <A TImageEnMView.SelectedImage> to determine the selection, whereas <A TImageEnMView.CenterFrame> uses <A TImageEnMView.VisibleFrame>.
|
|
|
|
<FM>Example<FC>
|
|
ImageEnMView1.SelectedImage := 10;
|
|
ImageEnMView1.CenterSelected;
|
|
!!}
|
|
procedure TImageEnMView.CenterSelected;
|
|
var
|
|
info: TIEImageInfo;
|
|
x, y: integer;
|
|
begin
|
|
if fSelectedItem >= 0 then
|
|
begin
|
|
info := fIEMBitmap.GetImageInfo( fSelectedItem );
|
|
X := info.X - (( ClientWidth - ThumbSizeInfo( itsCell ).X ) div 2 );
|
|
Y := info.Y - (( ClientHeight - ThumbSizeInfo( itsCell ).Y ) div 2 );
|
|
SetViewXY(X, Y);
|
|
end;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.SelectSeek
|
|
|
|
<FM>Declaration<FC>
|
|
procedure SelectSeek(pos: <A TIESeek>);
|
|
|
|
<FM>Description<FN>
|
|
Moves the selection by the method specified by <FC>pos<FN>. SelectSeek will scroll the view, where necessary, to ensure the newly selected image is visible.
|
|
|
|
<FM>Example<FC>
|
|
// This code loads "film.avi" and select the first image
|
|
ImageEnMView1.MIO.LoadFromFile('film.avi');
|
|
ImageEnMView1.SelectSeek(iskFirst);
|
|
|
|
!!}
|
|
procedure TImageEnMView.SelectSeek(pos: TIESeek);
|
|
var
|
|
info: TIEImageInfo;
|
|
gw, gh: integer;
|
|
begin
|
|
if fIEMBitmap.Count = 0 then
|
|
exit;
|
|
|
|
fHoverCheckLastPos.X := -1;
|
|
fHoverCheckLastIdx := -1;
|
|
|
|
gw := CalcGridWidth();
|
|
gh := (ClientHeight - fVertBorder) div ThumbSizeInfo( itsOuter ).Y;
|
|
|
|
if BiDiModeIsRTL() then
|
|
case pos of
|
|
iskLeft : pos := iskRight;
|
|
iskRight : pos := iskLeft;
|
|
end;
|
|
|
|
case pos of
|
|
iskLeft, iskPrior:
|
|
if fSelectedItem >= 0 then
|
|
begin
|
|
SetSelectedItem(fSelectedItem - 1);
|
|
if (fSelectedItem >= 0) and (GetImageVisibility(fSelectedItem) <> 2) then
|
|
begin
|
|
info := fIEMBitmap.GetImageInfo( fSelectedItem );
|
|
SetViewXY(info.X - fHorizBorder, info.Y - fVertBorder);
|
|
end;
|
|
end;
|
|
iskRight, iskNext:
|
|
if fSelectedItem >= -1 then
|
|
begin
|
|
SetSelectedItem(fSelectedItem + 1);
|
|
if (fSelectedItem >= 0) and (GetImageVisibility(fSelectedItem) <> 2) then
|
|
begin
|
|
info := fIEMBitmap.GetImageInfo( fSelectedItem );
|
|
SetViewXY( info.X - clientwidth + ThumbSizeInfo( itsOuter ).X, info.Y - clientheight + ThumbSizeInfo( itsOuter ).Y );
|
|
end;
|
|
end;
|
|
iskUp:
|
|
if fSelectedItem >= 0 then
|
|
begin
|
|
if fCurrentGridWidth = 0 then
|
|
// one row of infinite columns
|
|
SetSelectedItem(fSelectedItem - 1)
|
|
else
|
|
begin
|
|
// more rows of "gw" columns
|
|
if fSelectedItem - gw >= 0 then
|
|
SetSelectedItem(fSelectedItem - gw);
|
|
end;
|
|
if (fSelectedItem >= 0) and (GetImageVisibility(fSelectedItem) <> 2) then
|
|
begin
|
|
info := fIEMBitmap.GetImageInfo( fSelectedItem );
|
|
SetViewY(info.Y - fVertBorder);
|
|
if GetImageVisibility(fSelectedItem) <> 2 then
|
|
SetViewX(info.X - fHorizBorder);
|
|
end;
|
|
end;
|
|
iskDown:
|
|
if fSelectedItem >= -1 then
|
|
begin
|
|
if fCurrentGridWidth = 0 then
|
|
// one row of infinite columns
|
|
SetSelectedItem(fSelectedItem + 1)
|
|
else
|
|
begin
|
|
// more row of gw columns
|
|
if fSelectedItem + gw < fIEMBitmap.Count then
|
|
SetSelectedItem(fSelectedItem + gw);
|
|
end;
|
|
if (fSelectedItem >= 0) and (GetImageVisibility(fSelectedItem) <> 2) then
|
|
begin
|
|
info := fIEMBitmap.GetImageInfo( fSelectedItem );
|
|
SetViewY(info.Y - clientheight + ThumbSizeInfo( itsOuter ).Y);
|
|
if GetImageVisibility(fSelectedItem) <> 2 then
|
|
SetViewX( info.X - clientwidth + ThumbSizeInfo( itsOuter ).X );
|
|
end;
|
|
end;
|
|
iskFirst:
|
|
begin
|
|
SetSelectedItem(0);
|
|
if (fSelectedItem >= 0) and (GetImageVisibility(fSelectedItem) <> 2) then
|
|
SetViewXY(0, 0);
|
|
end;
|
|
iskLast:
|
|
begin
|
|
SetSelectedItem(fIEMBitmap.Count - 1);
|
|
if (fSelectedItem >= 0) and (GetImageVisibility(fSelectedItem) <> 2) then
|
|
begin
|
|
info := fIEMBitmap.GetImageInfo( fSelectedItem );
|
|
SetViewY(info.Y - clientheight + ThumbSizeInfo( itsOuter ).Y);
|
|
if GetImageVisibility(fSelectedItem) <> 2 then
|
|
SetViewX( info.X - clientwidth + ThumbSizeInfo( itsOuter ).X );
|
|
end;
|
|
end;
|
|
iskPagDown:
|
|
if fSelectedItem >= -1 then
|
|
begin
|
|
SetSelectedItem( imin(fSelectedItem + gw * gh , fIEMBitmap.Count-1) );
|
|
if (fSelectedItem >= 0) and (GetImageVisibility(fSelectedItem) <> 2) then
|
|
begin
|
|
info := fIEMBitmap.GetImageInfo( fSelectedItem );
|
|
SetViewY(info.Y - clientheight + ThumbSizeInfo( itsOuter ).Y);
|
|
if GetImageVisibility(fSelectedItem) <> 2 then
|
|
SetViewX( info.X - clientwidth + ThumbSizeInfo( itsOuter ).X );
|
|
end;
|
|
end;
|
|
iskPagUp:
|
|
if fSelectedItem >= 0 then
|
|
begin
|
|
SetSelectedItem( imax(fSelectedItem - gw * gh , 0) );
|
|
if (fSelectedItem >= 0) and (GetImageVisibility(fSelectedItem) <> 2) then
|
|
begin
|
|
info := fIEMBitmap.GetImageInfo( fSelectedItem );
|
|
SetViewY(info.Y - fVertBorder);
|
|
if GetImageVisibility(fSelectedItem) <> 2 then
|
|
SetViewX(info.X - fHorizBorder);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TImageEnMView.KeyDown(var Key: Word; Shift: TShiftState);
|
|
var
|
|
lMultiSelecting: boolean;
|
|
lSelectInclusive: boolean;
|
|
begin
|
|
inherited;
|
|
fUserAction := true;
|
|
try
|
|
if fPlaying then
|
|
exit;
|
|
if mkiMoveSelected in fKeyInteract then
|
|
begin
|
|
|
|
if assigned(fAnimation) then
|
|
begin
|
|
// in animation behavior
|
|
if (Key = VK_LEFT) or (Key = VK_UP) then
|
|
SelectedImage := SelectedImage - 1
|
|
else
|
|
if (Key = VK_RIGHT) or (Key = VK_DOWN) then
|
|
SelectedImage := SelectedImage + 1
|
|
end
|
|
else
|
|
if CheckSelectionChangingAllowed then
|
|
begin
|
|
// default behavior
|
|
lMultiSelecting := fMultiSelecting;
|
|
lSelectInclusive := fSelectInclusive;
|
|
if fEnableMultiSelect and ((ssCtrl in Shift) or (ssShift in Shift)) then
|
|
begin
|
|
fMultiSelecting := true;
|
|
fSelectInclusive := true;
|
|
end;
|
|
try
|
|
case Key of
|
|
VK_LEFT:
|
|
begin
|
|
SelectSeek(iskLeft);
|
|
ViewChange(0);
|
|
end;
|
|
VK_RIGHT:
|
|
begin
|
|
SelectSeek(iskRight);
|
|
ViewChange(0);
|
|
end;
|
|
VK_UP:
|
|
begin
|
|
SelectSeek(iskUp);
|
|
ViewChange(0);
|
|
end;
|
|
VK_DOWN:
|
|
begin
|
|
SelectSeek(iskDown);
|
|
ViewChange(0);
|
|
end;
|
|
VK_PRIOR:
|
|
begin
|
|
SelectSeek(iskPagUp);
|
|
ViewChange(0);
|
|
end;
|
|
VK_NEXT:
|
|
begin
|
|
SelectSeek(iskPagDown);
|
|
ViewChange(0);
|
|
end;
|
|
VK_HOME:
|
|
begin
|
|
SelectSeek(iskFirst);
|
|
ViewChange(0);
|
|
end;
|
|
VK_END:
|
|
begin
|
|
SelectSeek(iskLast);
|
|
ViewChange(0);
|
|
end;
|
|
else
|
|
exit;
|
|
end;
|
|
finally
|
|
fMultiSelecting := lMultiSelecting;
|
|
fSelectInclusive := lSelectInclusive;
|
|
end;
|
|
if fEnableMultiSelect and (Shift = []) then
|
|
fPriorHSIDX := fSelectedItem;
|
|
UpdateEx(false);
|
|
end;
|
|
end;
|
|
|
|
finally
|
|
fUserAction := false;
|
|
DoAfterEvent(ieaeKeyDown);
|
|
end;
|
|
end;
|
|
|
|
procedure TImageEnMView.KeyUp(var Key: Word; Shift: TShiftState);
|
|
begin
|
|
inherited;
|
|
DoAfterEvent(ieaeKeyUp);
|
|
end;
|
|
|
|
procedure TImageEnMView.WMKillFocus(var Msg: TWMKillFocus);
|
|
begin
|
|
inherited;
|
|
invalidate;
|
|
end;
|
|
|
|
procedure TImageEnMView.WMSetFocus(var Msg: TWMSetFocus);
|
|
begin
|
|
inherited;
|
|
invalidate;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.MouseInteract
|
|
|
|
<FM>Declaration<FC>
|
|
property MouseInteract: <A TIEMMouseInteract>;
|
|
|
|
<FM>Description<FN>
|
|
Specifies the effect of mouse actions upon the component.
|
|
!!}
|
|
function TImageEnMView.GetMouseInteract: TIEMMouseInteract;
|
|
begin
|
|
result := fMouseInteract;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.KeyInteract
|
|
|
|
<FM>Declaration<FC>
|
|
property KeyInteract: <A TIEMKeyInteract>
|
|
|
|
<FM>Description<FN>
|
|
Specifies which keyboard activities the component will handle automatically.
|
|
!!}
|
|
function TImageEnMView.GetKeyInteract: TIEMKeyInteract;
|
|
begin
|
|
result := fKeyInteract;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.DrawImageBackground
|
|
|
|
<FM>Declaration<FC>
|
|
property DrawImageBackground: boolean;
|
|
|
|
<FM>Description<FN>
|
|
If enabled, the background color of the thumbnail will be set to that of the current image. Otherwise it is set to <A TImageEnMView.ThumbnailsBackground>.
|
|
|
|
!!}
|
|
procedure TImageEnMView.SetDrawImageBackground(v: boolean);
|
|
begin
|
|
fDrawImageBackground := v;
|
|
Update;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ScrollBarsAlwaysVisible
|
|
|
|
<FM>Declaration<FC>
|
|
property ScrollBarsAlwaysVisible: Boolean;
|
|
|
|
<FM>Description<FN>
|
|
When enabled, the scrollbars specified by <A TImageEnMView.ScrollBars> will always be displayed even when not required.
|
|
|
|
!!}
|
|
function TImageEnMView.GetScrollBarsAlwaysVisible: boolean;
|
|
begin
|
|
result := fScrollBarsAlwaysVisible;
|
|
end;
|
|
|
|
procedure TImageEnMView.SetScrollBarsAlwaysVisible(v: boolean);
|
|
begin
|
|
fScrollBarsAlwaysVisible := v;
|
|
Update;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.SetImageFromFile
|
|
|
|
<FM>Declaration<FC>
|
|
function SetImageFromFile(idx: Integer; const FileName: WideString; SourceImageIndex: Integer = 0; FileFormat: <A TIOFileType> = ioUnknown): Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Loads an image from a file and assigns it to the TImageEnMView at index, <FC>idx<FN>.
|
|
Use SourceImageIndex to specify the image index if the source file is a multi-frame file (such as a TIFF or AVI).
|
|
Specify a <FC>FileFormat<FN> for the file if the extension does not match its type.
|
|
|
|
<FM>Example<FC>
|
|
idx := ImageEnMView1.AppendImage;
|
|
ImageEnMView1.SetImageFromFile(idx, 'D:\myfile.jpg');
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.SetImage>
|
|
- <A TImageEnMView.SetImageFromStream>
|
|
|
|
!!}
|
|
function TImageEnMView.SetImageFromFile(idx: integer; const FileName: WideString; SourceImageIndex: Integer = 0; FileFormat: TIOFileType = ioUnknown): boolean;
|
|
var
|
|
ms: TMemoryStream;
|
|
FileExt: string;
|
|
begin
|
|
if IEGetURLTypeW(FileName) <> ieurlUNKNOWN then
|
|
begin
|
|
// LOAD FROM URL
|
|
ms := TMemoryStream.Create;
|
|
try
|
|
Result := IEGetFromURL(FileName, ms, IEGlobalSettings().ProxyAddress, IEGlobalSettings().ProxyUser, IEGlobalSettings().ProxyPassword, nil, nil, @GetImageEnMIO.Aborting, FileExt);
|
|
if Result then
|
|
begin
|
|
ms.Position := 0;
|
|
Result := SetImageFromStreamOrFile( Idx, ms, '', SourceImageIndex, FileFormat );
|
|
end;
|
|
finally
|
|
FreeAndNil(ms);
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
// LOAD FROM FILE
|
|
result := SetImageFromStreamOrFile( idx, nil, FileName, SourceImageIndex, FileFormat );
|
|
end;
|
|
|
|
if assigned(fAnimation) then
|
|
fAnimation.RestartAnimation();
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.SetImageFromStream
|
|
|
|
<FM>Declaration<FC>
|
|
function SetImageFromStream(idx: Integer; Stream: TStream; SourceImageIndex: Integer = 0; FileFormat: <A TIOFileType> = ioUnknown): Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Loads an image from a stream and assigns it to the TImageEnMView at index, <FC>idx<FN>.
|
|
Use SourceImageIndex to specify the image index if the source file is a multi-frame file (such as a TIFF or AVI).
|
|
If <FC>FileFormat<FN> is ioUnknown the content will be examined to detect the image type.
|
|
|
|
<FM>Example<FC>
|
|
idx := ImageEnMView1.AppendImage;
|
|
ImageEnMView1.SetImageFromStream(idx, stream);
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.SetImage>
|
|
- <A TImageEnMView.SetImageFromFile>
|
|
|
|
!!}
|
|
function TImageEnMView.SetImageFromStream(idx: integer; Stream: TStream; SourceImageIndex: Integer = 0; FileFormat: TIOFileType = ioUnknown): boolean;
|
|
begin
|
|
result := SetImageFromStreamOrFile( idx, Stream, '', SourceImageIndex, FileFormat );
|
|
if assigned(fAnimation) then
|
|
fAnimation.RestartAnimation();
|
|
end;
|
|
|
|
function TImageEnMView.SetImageFromStreamOrFile(idx: integer; Stream: TStream; const FileName: WideString; SourceImageIndex: Integer; FileFormat: TIOFileType): boolean;
|
|
var
|
|
bmp: TIEBitmap;
|
|
info: TIEImageInfo;
|
|
ASourceType : TIESourceType;
|
|
begin
|
|
if IEMBitmap_IsTIEDBMultiBitmap then
|
|
begin
|
|
result := fIEMBitmap.SetImageFromStreamOrFile( idx, Stream, Filename, SourceImageIndex, FileFormat );
|
|
exit;
|
|
end;
|
|
|
|
|
|
result := False;
|
|
if idx >= fIEMBitmap.Count then
|
|
exit;
|
|
|
|
info := fIEMBitmap.GetImageInfo( idx );
|
|
ASourceType := info.SourceType;
|
|
bmp := TIEBitmap.Create;
|
|
try
|
|
fImageEnIO.Background := info.Background;
|
|
fImageEnIO.AttachedIEBitmap := bmp;
|
|
fImageEnIO.OnProgress := fOnIOProgress;
|
|
fImageEnIO.AutoAdjustDPI := MIO.AutoAdjustDPI;
|
|
fImageEnIO.Params.ImageIndex := SourceImageIndex;
|
|
_SetLoadParams(Self, fImageEnIO.Params);
|
|
try
|
|
if Stream <> nil then
|
|
fImageEnIO.LoadFromStream(Stream, FileFormat)
|
|
else
|
|
if ( fStoreType in [ ietThumb, ietFastThumb ]) and IsMetaFile( Filename ) then
|
|
fImageEnIO.ImportMetafile( Filename, ThumbSizeInfo( itsImage ).X, -1, true )
|
|
else
|
|
{$IFDEF VIDEO_THUMBNAILS}
|
|
if ( fStoreType in [ ietThumb, ietFastThumb ]) and UseThumbnailFromExplorer(FileName) then
|
|
fImageEnIO.LoadThumbnailFromExplorer( FileName, ThumbSizeInfo( itsImage ).X, ThumbSizeInfo( itsImage ).Y )
|
|
else
|
|
{$ENDIF}
|
|
begin
|
|
if FileFormat = ioUnknown then
|
|
FileFormat := FindFileFormat( FileName, ffFallbackToExtension );
|
|
fImageEnIO.LoadFromFile(FileName, FileFormat);
|
|
if ( not fImageEnIO.Aborting ) and ( ImageFileName[ idx ] = '' ) then
|
|
ImageFileName[ idx ] := FileName;
|
|
end;
|
|
except
|
|
fImageEnIO.Aborting := true;
|
|
end;
|
|
|
|
if fImageEnIO.Aborting then
|
|
DoWrongImage(bmp, idx, ASourceType);
|
|
|
|
result := not fImageEnIO.Aborting;
|
|
|
|
// updates params of encapsulated TImageEnMIO object
|
|
StripOffIOParams(self, fImageEnIO.Params);
|
|
GetImageEnMIO.Params[idx].Assign(fImageEnIO.Params); // GetImageEnMIO creates TImageEnMIO if it doesn't exist
|
|
info.Background := fImageEnIO.Background;
|
|
info.SourceType := ASourceType;
|
|
SetIEBitmapEx(idx, bmp);
|
|
|
|
ImageOriginalWidth [idx] := fImageEnIO.Params.OriginalWidth;
|
|
ImageOriginalHeight[idx] := fImageEnIO.Params.OriginalHeight;
|
|
if fImageEnIO.Params.EXIF_DateTimeOriginal2 > 0 then
|
|
ImageCreateDate[idx] := fImageEnIO.Params.EXIF_DateTimeOriginal2;
|
|
if assigned( fOnImageLoaded ) then
|
|
fOnImageLoaded( self, idx );
|
|
finally
|
|
fImageEnIO.attachediebitmap := nil;
|
|
FreeAndNil(bmp);
|
|
end;
|
|
ClearImageCache(idx);
|
|
UpdateEx(false);
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.GetImageToFile
|
|
|
|
<FM>Declaration<FC>
|
|
procedure GetImageToFile(idx: Integer; const FileName: WideString);
|
|
|
|
<FM>Description<FN>
|
|
Saves the image at index, <FC>idx<FN>, to file. The file format is determined by the file extension.
|
|
|
|
<TABLE>
|
|
<R> <H>Parameter</H> <H>Description</H> </R>
|
|
<R> <C><FC>idx<FN></C> <C>The image index (0=first image)</C> </R>
|
|
<R> <C><FC>FileName<FN></C> <C>The destination path and file name</C> </R>
|
|
</TABLE>
|
|
|
|
|
|
<FM>Example<FC>
|
|
// Separate the pages of a multipage TIFF
|
|
ImageEnMView1.MIO.LoadFromFile('multipage.tif');
|
|
ImageEnMView1.GetImageToFile(0, 'page1.tif');
|
|
ImageEnMView1.GetImageToFile(1, 'page2.tif');
|
|
|
|
// Save the first image to a JPEG file (at 80% quality)
|
|
ImageEnMView1.MIO.Params[0].JPEG_Quality := 80;
|
|
ImageEnMView1.GetImageToFile(0, 'D:\MyImage.jpg');
|
|
!!}
|
|
procedure TImageEnMView.GetImageToFile(idx: Integer; const FileName: WideString);
|
|
var
|
|
bmp: TIEBitmap;
|
|
begin
|
|
fImageEnIO.Params.Assign( GetImageEnMIO.Params[idx] );
|
|
bmp := GetTIEBitmap(idx);
|
|
try
|
|
fImageEnIO.AttachedIEBitmap := bmp;
|
|
fImageEnIO.SaveToFile(FileName);
|
|
finally
|
|
fImageEnIO.AttachedIEBitmap := nil;
|
|
ReleaseBitmap(idx, false);
|
|
end;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.GetImageToStream
|
|
|
|
<FM>Declaration<FC>
|
|
procedure GetImageToStream(idx: Integer; Stream: TStream; ImageFormat: <A TIOFileType>);
|
|
|
|
<FM>Description<FN>
|
|
Saves the image at index, <FC>idx<FN>, to a stream.
|
|
|
|
<TABLE>
|
|
<R> <H>Parameter</H> <H>Description</H> </R>
|
|
<R> <C><FC>idx<FN></C> <C>The image index (Where 0 is the first image)</C> </R>
|
|
<R> <C><FC>Stream<FN></C> <C>The destination stream</C> </R>
|
|
<R> <C><FC>ImageFormat<FN></C> <C>The output file format (e.g. ioTiff or ioJpeg)</C> </R>
|
|
</TABLE>
|
|
|
|
<FM>Example<FC>
|
|
// Save the first image to a stream in JPEG format (at 80% quality)
|
|
ImageEnMView1.MIO.Params[0].JPEG_Quality := 80;
|
|
ImageEnMView1.GetImageToFile(0, MyStream, ioJPEG);
|
|
|
|
!!}
|
|
procedure TImageEnMView.GetImageToStream(idx: Integer; Stream: TStream; ImageFormat: TIOFileType);
|
|
var
|
|
bmp: TIEBitmap;
|
|
begin
|
|
fImageEnIO.Params.Assign( GetImageEnMIO.Params[idx] );
|
|
bmp := GetTIEBitmap(idx);
|
|
try
|
|
fImageEnIO.AttachedIEBitmap := bmp;
|
|
fImageEnIO.SaveToStream(Stream, ImageFormat);
|
|
finally
|
|
fImageEnIO.AttachedIEBitmap := nil;
|
|
ReleaseBitmap(idx, false);
|
|
end;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.PrepareSpaceFor
|
|
|
|
<FM>Declaration<FC>
|
|
procedure PrepareSpaceFor(Width, Height: Integer; Bitcount: Integer; ImageCount: Integer);
|
|
|
|
<FM>Description<FN>
|
|
Allocates enough space within the temporary file for <FC>ImageCount><FN> images of size <FC>Width<FN> * <FC>Height<FN> * <FC>BitCount<FN>.
|
|
|
|
Use this method to improve performance only when you plan to add many images of the same size.
|
|
|
|
!!}
|
|
procedure TImageEnMView.PrepareSpaceFor(Width, Height: integer; Bitcount: integer; ImageCount: integer);
|
|
begin
|
|
fIEMBitmap.PrepareSpaceFor(Width, Height, Bitcount, ImageCount);
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ImageCacheSize
|
|
|
|
<FM>Declaration<FC>
|
|
property ImageCacheSize: Integer;
|
|
|
|
<FM>Description<FN>
|
|
Specifies the number of images to be stored in memory, rather than in a memory mapped file. For example, if you know that a TImageEnMView will only contain 20 images then the ImageCacheSize could be set to 20 to disable all memory mapping.
|
|
|
|
Default: 10
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.ClearImageCache>
|
|
- <A TImageEnMView.EnableImageCaching>
|
|
- <A TImageEnMView.ImageCacheUseDisk>
|
|
!!}
|
|
|
|
function TImageEnMView.GetImageCacheSize : integer;
|
|
begin
|
|
Result := fIEMBitmap.ImageCacheSize;
|
|
end;
|
|
|
|
procedure TImageEnMView.SetImageCacheSize(v: integer);
|
|
begin
|
|
fIEMBitmap.ImageCacheSize := v;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ImageCacheUseDisk
|
|
|
|
<FM>Declaration<FC>
|
|
property ImageCacheUseDisk: Boolean;
|
|
|
|
<FM>Description<FN>
|
|
When enabled, a disk file is used to cache the images and view. Otherwise only system memory is used.
|
|
Disabling this option is useful if you have low disk space or don't want ImageEn to write to disk.
|
|
|
|
Warning: Setting this property will also call <A TImageEnMView.Clear>
|
|
|
|
Default: True
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.ClearImageCache>
|
|
- <A TImageEnMView.EnableImageCaching>
|
|
- <A TImageEnMView.ImageCacheSize>
|
|
!!}
|
|
function TImageEnMView.GetImageCacheUseDisk : boolean;
|
|
begin
|
|
Result := fIEMBitmap.ImageCacheUseDisk;
|
|
end;
|
|
|
|
procedure TImageEnMView.SetImageCacheUseDisk(v: boolean);
|
|
begin
|
|
if fIEMBitmap.ImageCacheUseDisk <> v then
|
|
begin
|
|
fIEMBitmap.ImageCacheUseDisk := v;
|
|
Clear;
|
|
end;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.VisibleFrame
|
|
|
|
<FM>Declaration<FC>
|
|
property VisibleFrame: Integer;
|
|
|
|
<FM>Description<FN>
|
|
Specifies the visible image when <A TImageEnMView.DisplayMode> is mdSingle or <A TImageEnMView.Playing> is <FC>True<FN>.
|
|
!!}
|
|
procedure TImageEnMView.SetVisibleFrame(v: integer);
|
|
begin
|
|
if (v = fFrame) or (v < 0) or (v >= fIEMBitmap.Count) then
|
|
exit;
|
|
if fTransitionEffect <> iettNone then
|
|
begin
|
|
fTransition.Transition := fTransitionEffect;
|
|
fTransition.Duration := fTransitionDuration;
|
|
fTransition.SetSizes( ThumbSizeInfo( itsCell ).X, ThumbSizeInfo( itsCell ).Y );
|
|
PaintTo(fTransition.SourceShot);
|
|
fFrame := v;
|
|
PaintTo(fTransition.TargetShot);
|
|
fTransition.Run(true);
|
|
end
|
|
else
|
|
begin
|
|
fFrame := v;
|
|
UpdateEx(false);
|
|
end;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.TransitionRunning
|
|
|
|
<FM>Declaration<FC>
|
|
property TransitionRunning: Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Returns <FC>true<FN> when a transition is running.
|
|
|
|
<FM>Example<FC>
|
|
// Design time properties...
|
|
ImageEnMView1.DisplayMode := mdSingle;
|
|
ImageEnMView1.TransitionEffect := iettCrossDissolve;
|
|
ImageEnMView1.TransitionDuration := 1500;
|
|
|
|
// display next frame using cross dissolve
|
|
ImageEnMView1.VisibleFrame := ImageEnMView1.VisibleFrame + 1;
|
|
|
|
// wait for the transition to end
|
|
While ImageEnMView1.TransitionRunning do
|
|
Application.processmessages;
|
|
ShowMessage('transition done!');
|
|
|
|
!!}
|
|
function TImageEnMView.GetTransitionRunning: boolean;
|
|
begin
|
|
result := fTransition.Running;
|
|
end;
|
|
|
|
procedure TImageEnMView.RemoveAlphaChannel(Merge: boolean);
|
|
begin
|
|
// nothing
|
|
end;
|
|
|
|
// return nil
|
|
|
|
function TImageEnMView.GetAlphaChannel: TIEBitmap;
|
|
begin
|
|
result := nil;
|
|
end;
|
|
|
|
function TImageEnMView.GetHasAlphaChannel: boolean;
|
|
begin
|
|
result := false;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.Style
|
|
|
|
<FM>Declaration<FC>
|
|
property Style: <A TIEMStyle>;
|
|
|
|
<FM>Description<FN>
|
|
Specifies the thumbnail style.
|
|
<FC>
|
|
ImageEnMView1.Style := iemsFlat;
|
|
<IMG help_images\FlatThumb.jpg>
|
|
|
|
ImageEnMView1.Style := iemsACD;
|
|
<IMG help_images\3DThumb.jpg>
|
|
|
|
ImageEnMView1.Style := iemsFlatAndWide;
|
|
<IMG help_images\FlatWideThumb.jpg>
|
|
|
|
ImageEnMView1.Style := iemsColumns;
|
|
<IMG help_images\Columns.jpg>
|
|
|
|
<FM>Notes on iemsColumns<FN>
|
|
A header row is displayed with the <FC>iemsColumns<FN> style. <A TImageEnMView.InfoTextFont> is used for the font formatting, but this can be overriden in the <A TImageEnMView.OnGetTextEx> event. The header row caption is based on the <L TImageEnMView.DefaultTopText>default text</L>, but can be overriden in <A TImageEnMView.OnGetText> or <A TImageEnMView.OnGetTextEx>.
|
|
Columns will be shown for text fields which have text specified (e.g. using <A TImageEnMView.DefaultTopText>) and a valid <L TImageEnMView.TextColumnWidths>width</L>. Columns are displayed in the order: <A TImageEnMView.DefaultTopText>, <A TImageEnMView.DefaultBottomText>, <A TImageEnMView.DefaultInfoText>.
|
|
|
|
<FM>Example<FC>
|
|
procedure TForm1.rdbShowThumbsClick(Sender: TObject);
|
|
begin
|
|
IEFolderMView.LockUpdate;
|
|
try
|
|
IEFolderMView.Style := iemsFlat;
|
|
IEFolderMView.Zoom := 100;
|
|
IEFolderMView.TopTextFont.Style := [];
|
|
IEFolderMView.DefaultTopText := iedtNone;
|
|
IEFolderMView.DefaultInfoText := iedtNone;
|
|
IEFolderMView.DefaultBottomText := iedtFileName;
|
|
IEFolderMView.ThumbnailsBorderWidth := 1;
|
|
IEFolderMView.VertBorder := 8;
|
|
IEFolderMView.HorizBorder := 8;
|
|
finally
|
|
IEFolderMView.UnlockUpdate;
|
|
InitializeControls;
|
|
end;
|
|
end;
|
|
|
|
procedure TForm1.rdbShowDetailsClick(Sender: TObject);
|
|
begin
|
|
IEFolderMView.LockUpdate;
|
|
try
|
|
IEFolderMView.Style := iemsFlatAndWide;
|
|
IEFolderMView.Zoom := 50;
|
|
IEFolderMView.TopTextFont.Style := [ fsBold ];
|
|
IEFolderMView.DefaultTopText := iedtFileName;
|
|
IEFolderMView.DefaultInfoText := iedtFilePath;
|
|
IEFolderMView.DefaultBottomText := iedtImageDimAndSize;
|
|
IEFolderMView.ThumbnailsBorderWidth := 1;
|
|
IEFolderMView.VertBorder := 8;
|
|
IEFolderMView.HorizBorder := 8;
|
|
finally
|
|
IEFolderMView.UnlockUpdate;
|
|
InitializeControls;
|
|
end;
|
|
end;
|
|
|
|
procedure TForm1.rdbShowColumnsClick(Sender: TObject);
|
|
begin
|
|
IEFolderMView.LockUpdate;
|
|
try
|
|
IEFolderMView.Style := iemsColumns;
|
|
IEFolderMView.Zoom := 17;
|
|
IEFolderMView.TopTextFont.Style := [];
|
|
IEFolderMView.DefaultTopText := iedtFileName;
|
|
IEFolderMView.DefaultInfoText := iedtImageDimAndSize;
|
|
IEFolderMView.DefaultBottomText := iedtFileCreateDate;
|
|
IEFolderMView.ThumbnailsBorderWidth := 0;
|
|
IEFolderMView.VertBorder := 0;
|
|
IEFolderMView.HorizBorder := 0;
|
|
finally
|
|
IEFolderMView.UnlockUpdate;
|
|
InitializeControls;
|
|
end;
|
|
end;
|
|
|
|
<FM>Demo<FN>
|
|
<TABLE2>
|
|
<R> <C_IMG_DEMO> <C>Demos\Multi\MViewStyles\MViewStyles.dpr </C> </R>
|
|
</TABLE>
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.SetStyleEx>
|
|
- <A TImageEnMView.SetModernStyling>
|
|
- <A TImageEnMView.TextBlockWidth>
|
|
!!}
|
|
procedure TImageEnMView.SetStyle(value: TIEMStyle);
|
|
begin
|
|
if fStyle <> value then
|
|
begin
|
|
fStyle := value;
|
|
ClearCache;
|
|
Update;
|
|
end;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.SetStyleEx
|
|
|
|
<FM>Declaration<FC>
|
|
procedure SetStyleEx(aStyle: <A TIEMStyle>;
|
|
TopText : <A TIEImageEnMViewDefaultText>;
|
|
InfoText : <A TIEImageEnMViewDefaultText>;
|
|
BottomText : <A TIEImageEnMViewDefaultText>;
|
|
iThumbZoom: Double = 0;
|
|
bAdjustSpacing: Boolean = True;
|
|
bAdjustStyle: Boolean = True;
|
|
bAdjustFont: Boolean = True);
|
|
|
|
<FM>Description<FN>
|
|
Provides a shortcut method to set the style of the control to several predefined styles:
|
|
<FC>
|
|
ImageEnMView1.SetStyleEx( iemsFlat, iedtNone, iedtNone, iedtFileName );
|
|
<IMG help_images\FlatThumb.jpg>
|
|
|
|
ImageEnMView1.SetStyleEx( iemsFlatAndWide, iedtFileName, iedtFilePath, iedtImageDimAndSize );
|
|
<IMG help_images\FlatWideThumb.jpg>
|
|
|
|
ImageEnMView1.SetStyleEx( iemsColumns, iedtFileName, iedtImageDimAndSize, iedtFileCreateDate );
|
|
<IMG help_images\Columns.jpg>
|
|
|
|
ImageEnMView1.GridWidth := 1;
|
|
ImageEnMView1.SetStyleEx( iemsFlatAndWide, iedtNone, iedtNone, iedtFileName, -24 );
|
|
<IMG help_images\FileList.jpg>
|
|
<FN>
|
|
|
|
<TABLE>
|
|
<R> <H>Parameter</H> <H>Description</H> </R>
|
|
<R> <C><FC>aStyle<FN></C> <C>Sets <A TImageEnMView.Style> to one of iemsFlat, iemsFlatAndWide or iemsColumns</C> </R>
|
|
<R> <C><FC>TopText<FN></C> <C>Sets <A TImageEnMView.DefaultTopText></C> </R>
|
|
<R> <C><FC>InfoText<FN></C> <C>Sets <A TImageEnMView.DefaultInfoText></C> </R>
|
|
<R> <C><FC>BottomText<FN></C> <C>Sets <A TImageEnMView.DefaultBottomText></C> </R>
|
|
<R> <C><FC>iThumbZoom<FN></C> <C>Sets <A TImageEnMView.Zoom>. If a negative value is specified then <A TImageEnMView.Zoom> will be set to give a thumbnail of that height in pixels (i.e. -22 would set the thumbnail height to 22 pixels). If 0 is specified, then actual zoom will depend on the specified <FC>aStyle<FN> </C> </R>
|
|
<R> <C><FC>bAdjustSpacing<FN></C> <C>Sets the following properties with values best for the specified <FC>aStyle<FN> (and considering <A TImageEnMView.SoftShadow>):
|
|
- <A TImageEnMView.UpperGap>
|
|
- <A TImageEnMView.BottomGap>
|
|
- <A TImageEnMView.SideGap>
|
|
- <A TImageEnMView.TextMargin>
|
|
- <A TImageEnMView.TextBlockWidth>
|
|
- <A TImageEnMView.VertBorder>
|
|
- <A TImageEnMView.HorizBorder></C> </R>
|
|
<R> <C><FC>bAdjustStyle<FN></C> <C>Sets the <A TImageEnMView.ThumbnailsBorderWidth> to 0 if <FC>aStyle<FN> is <FC>iemsColumns<FN></C> </R>
|
|
<R> <C><FC>bAdjustFont<FN></C> <C>Sets the <A TImageEnMView.TopTextFont> to <FC>[fsBold]<FN> if <FC>aStyle<FN> is <FC>iemsFlatAndWide<FN></C> </R>
|
|
</TABLE>
|
|
|
|
Note: If you have already set text for your images then you won't see the default text values you've specified above
|
|
|
|
<FM>Example<FC>
|
|
// An application with menu items to change the view style
|
|
procedure TForm1.FormCreate(Sender: TObject);
|
|
begin
|
|
IEFolderMView.SetModernStyling( True );
|
|
end;
|
|
|
|
// Show Large Thumbs
|
|
procedure TForm1.rdbShowLargeThumbsClick(Sender: TObject);
|
|
begin
|
|
ImageEnMView1.GridWidth := -1;
|
|
ImageEnMView1.ThumbnailOptionsEx := ImageEnMView1.ThumbnailOptionsEx - [ ietxOnlyShowIcons ];
|
|
ImageEnMView1.SetStyleEx( iemsFlat, iedtNone, iedtNone, iedtFileName, 200 );
|
|
end;
|
|
|
|
// Show Thumbs
|
|
procedure TForm1.rdbShowThumbsClick(Sender: TObject);
|
|
begin
|
|
ImageEnMView1.GridWidth := -1;
|
|
ImageEnMView1.ThumbnailOptionsEx := ImageEnMView1.ThumbnailOptionsEx - [ ietxOnlyShowIcons ];
|
|
ImageEnMView1.SetStyleEx( iemsFlat, iedtNone, iedtNone, iedtFileName );
|
|
end;
|
|
|
|
// Show Small Thumbs with Detail
|
|
procedure TForm1.rdbShowDetailsClick(Sender: TObject);
|
|
begin
|
|
ImageEnMView1.GridWidth := -1;
|
|
ImageEnMView1.ThumbnailOptionsEx := ImageEnMView1.ThumbnailOptionsEx - [ ietxOnlyShowIcons ];
|
|
ImageEnMView1.SetStyleEx( iemsFlatAndWide, iedtFileName, iedtFilePath, iedtImageDimAndSize );
|
|
end;
|
|
|
|
// Show File List
|
|
procedure TForm1.rdbShowDetailsClick(Sender: TObject);
|
|
begin
|
|
ImageEnMView1.GridWidth := 1;
|
|
ImageEnMView1.ThumbnailOptionsEx := ImageEnMView1.ThumbnailOptionsEx + [ ietxOnlyShowIcons ];
|
|
ImageEnMView1.SetStyleEx( iemsFlatAndWide, iedtNone, iedtNone, iedtFileName, -24 );
|
|
end;
|
|
|
|
// Show Text Columns
|
|
procedure TForm1.rdbShowColumnsClick(Sender: TObject);
|
|
begin
|
|
ImageEnMView1.GridWidth := -1;
|
|
ImageEnMView1.ThumbnailOptionsEx := ImageEnMView1.ThumbnailOptionsEx + [ ietxOnlyShowIcons ];
|
|
ImageEnMView1.SetStyleEx( iemsColumns, iedtFileName, iedtImageDimAndSize, iedtFileCreateDate );
|
|
end;
|
|
|
|
<FM>Demo<FN>
|
|
<TABLE2>
|
|
<R> <C_IMG_DEMO> <C>Demos\Multi\MViewStyles\MViewStyles.dpr </C> </R>
|
|
</TABLE>
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.Style>
|
|
- <A TImageEnMView.SetModernStyling>
|
|
- <A TImageEnMView.ThumbnailOptionsEx>
|
|
!!}
|
|
const
|
|
Gap_For_Details_Style = 4;
|
|
Gap_For_Thumbs_Style = 6;
|
|
Gap_For_Columns_Style = 2;
|
|
Gap_When_Soft_Shadow = 0;
|
|
Default_Text_Margin = 4;
|
|
Columns_Text_Margin = 6;
|
|
Default_Cell_Spacing = 8;
|
|
Columns_Cell_Spacing = 0;
|
|
|
|
procedure TImageEnMView.SetStyleEx(aStyle: TIEMStyle;
|
|
TopText : TIEImageEnMViewDefaultText;
|
|
InfoText : TIEImageEnMViewDefaultText;
|
|
BottomText : TIEImageEnMViewDefaultText;
|
|
iThumbZoom: Double = 0;
|
|
bAdjustSpacing: Boolean = True;
|
|
bAdjustStyle: Boolean = True;
|
|
bAdjustFont: Boolean = True);
|
|
var
|
|
iGap: Integer;
|
|
bFileListView: Boolean;
|
|
begin
|
|
LockUpdate;
|
|
try
|
|
Style := aStyle;
|
|
|
|
if iThumbZoom = 0 then
|
|
case aStyle of
|
|
iemsFlatAndWide : iThumbZoom := 50;
|
|
iemsColumns : iThumbZoom := -24;
|
|
else iThumbZoom := 100;
|
|
end;
|
|
if iThumbZoom < 0 then
|
|
Zoom := abs( iThumbZoom ) / ThumbHeight * 100
|
|
else
|
|
Zoom := iThumbZoom;
|
|
|
|
bFileListView := ( aStyle = iemsFlatAndWide ) and
|
|
( ThumbSizeInfo( itsCell ).Y < 30 ) and // Less than 30 pixels high
|
|
( TopText = iedtNone ) and ( InfoText = iedtNone ) and ( BottomText <> iedtNone );
|
|
|
|
if bAdjustFont then
|
|
begin
|
|
if ( aStyle = iemsFlatAndWide ) and ( InfoText <> iedtNone ) and ( BottomText <> iedtNone ) then
|
|
TopTextFont.Style := TopTextFont.Style + [fsBold]
|
|
else
|
|
TopTextFont.Style := TopTextFont.Style - [fsBold];
|
|
end;
|
|
|
|
if bAdjustStyle then
|
|
begin
|
|
if ( aStyle = iemsColumns ) or bFileListView then
|
|
ThumbnailsBorderWidth := 0
|
|
else
|
|
if ThumbnailsBorderWidth = 0 then
|
|
ThumbnailsBorderWidth := 1;
|
|
end;
|
|
|
|
if bAdjustSpacing then
|
|
begin
|
|
if ( aStyle = iemsColumns ) or bFileListView then
|
|
iGap := Gap_For_Columns_Style
|
|
else
|
|
if SoftShadow.Enabled then
|
|
iGap := Gap_When_Soft_Shadow
|
|
else
|
|
if aStyle = iemsFlatAndWide then
|
|
iGap := Gap_For_Details_Style
|
|
else
|
|
iGap := Gap_For_Thumbs_Style;
|
|
UpperGap := iGap;
|
|
BottomGap := iGap;
|
|
SideGap := iGap;
|
|
|
|
if ( aStyle = iemsColumns ) or bFileListView then
|
|
begin
|
|
VertBorder := Columns_Cell_Spacing;
|
|
HorizBorder := Columns_Cell_Spacing;
|
|
if TextMargin < Columns_Text_Margin then
|
|
TextMargin := Columns_Text_Margin;
|
|
end
|
|
else
|
|
begin
|
|
if VertBorder = Columns_Cell_Spacing then
|
|
VertBorder := Default_Cell_Spacing;
|
|
if HorizBorder = Columns_Cell_Spacing then
|
|
HorizBorder := Default_Cell_Spacing;
|
|
if TextMargin > Default_Text_Margin then
|
|
TextMargin := Default_Text_Margin;
|
|
end;
|
|
|
|
TextBlockWidth := -1;
|
|
end;
|
|
|
|
DefaultTopText := TopText;
|
|
DefaultInfoText := InfoText;
|
|
DefaultBottomText := BottomText;
|
|
finally
|
|
UnlockUpdate;
|
|
end;
|
|
end;
|
|
|
|
const
|
|
Column_View = 0;
|
|
File_List = 1;
|
|
Detail_View = 2;
|
|
Thumb_View = 3; // or > 4+ for zoom levels > 100%
|
|
|
|
// Return the current layout in use
|
|
function TImageEnMView.GetStyleInt() : Integer;
|
|
begin
|
|
case fStyle of
|
|
iemsColumns : Result := Column_View;
|
|
iemsFlatAndWide : if GridWidth = 1 then
|
|
Result := File_List
|
|
else
|
|
Result := Detail_View;
|
|
else { iemsFlat, iemsACD }
|
|
Result := Thumb_View + imax( 0, Trunc(( Zoom - 100 ) / 50 ));
|
|
end;
|
|
end;
|
|
|
|
// Cycles through 4 built-in layouts + extra zoom levels
|
|
procedure TImageEnMView.SetStyleInt(v : Integer);
|
|
var
|
|
iZoom: Integer;
|
|
begin
|
|
if ( v < 0 ) or ( v > 11 { 500% zoom } ) then
|
|
exit;
|
|
|
|
LockUpdate;
|
|
|
|
case v of
|
|
|
|
Column_View:
|
|
begin
|
|
GridWidth := -1;
|
|
SetStyleEx( iemsColumns, iedtFilename, iedtFileCreateDateTime, iedtImageDimAndSize );
|
|
ThumbnailOptionsEx := ThumbnailOptionsEx + [ ietxOnlyShowIcons ];
|
|
end;
|
|
|
|
File_List:
|
|
begin
|
|
GridWidth := 1;
|
|
SetStyleEx( iemsFlatAndWide, iedtNone, iedtNone, iedtFilename, -24 );
|
|
ThumbnailOptionsEx := ThumbnailOptionsEx + [ ietxOnlyShowIcons ];
|
|
end;
|
|
|
|
Detail_View:
|
|
begin
|
|
GridWidth := -1;
|
|
SetStyleEx( iemsFlatAndWide, iedtFilename, iedtFileCreateDateTime, iedtImageDimAndSize );
|
|
ThumbnailOptionsEx := ThumbnailOptionsEx - [ ietxOnlyShowIcons ];
|
|
end;
|
|
|
|
else { Thumb_View }
|
|
begin
|
|
// v=3, zoom = 100%. v=4, zoom = 150%. v=5, zoom = 200%. etc.
|
|
iZoom := 100 + (v - Thumb_View) * 50;
|
|
GridWidth := -1;
|
|
SetStyleEx( iemsFlat, iedtNone, iedtNone, iedtFilename, iZoom );
|
|
ThumbnailOptionsEx := ThumbnailOptionsEx - [ ietxOnlyShowIcons ];
|
|
end;
|
|
end;
|
|
UnlockUpdate;
|
|
end;
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.SetModernStyling
|
|
|
|
<FM>Declaration<FC>
|
|
procedure SetModernStyling(bAutoGridWidth : Boolean = False; iThumbWidth : Integer = 0; iThumbHeight : Integer = 0; bSoftShadow: Boolean = True);
|
|
|
|
<FM>Description<FN>
|
|
Call SetModernStyling in FormCreate to update the control with the settings which closely match the current Windows styling.
|
|
|
|
if bAutoGridWidth is enabled then <A TImageEnMView.GridWidth> is set to -1. You can also optionally specify default values for <A TImageEnMView.GridWidth> and <A TImageEnMView.GridWidth> and add a <A TImageEnMView.SoftShadow>.
|
|
|
|
The current implementation of SetModernStyling makes the following changes:
|
|
<FC>
|
|
<A TImageEnMView.Style> := iemsFlat;
|
|
<A TImageEnMView.Background> := clWindow;
|
|
<A TImageEnMView.ThumbnailsBackground> := clWindow;
|
|
<A TImageEnMView.ThumbnailsBackgroundSelected> := $00FCEADA;
|
|
<A TImageEnMView.SelectionColor> := $00CEA27D;
|
|
<A TImageEnMView.SelectionWidth> := 1;
|
|
<A TImageEnMView.TextMargin> := 4;
|
|
<A TImageEnMView.HorizBorder> := 8;
|
|
<A TImageEnMView.VertBorder> := 8;
|
|
<A TImageEnMView.UpperGap> := 0; (or 4 if bSoftShadow = False)
|
|
<A TImageEnMView.BottomGap> := 0; (or 4 if bSoftShadow = False)
|
|
<A TImageEnMView.SideGap> := 0; (or 4 if bSoftShadow = False)
|
|
<A TImageEnMView.TextBackgroundStyle> := bsClear;
|
|
<A TImageEnMView.ThumbnailDisplayFilter> := rfFastLinear;
|
|
<A TImageEnMView.ThumbnailsBorderWidth> := 1;
|
|
<L TIEVSoftShadow.Radius>SoftShadow.Radius</L> := 2;
|
|
<L TIEVSoftShadow.OffsetX>SoftShadow.OffsetX</L> := 2;
|
|
<L TIEVSoftShadow.OffsetY>SoftShadow.OffsetY</L> := 2;
|
|
<L TIEVSoftShadow.Intensity>SoftShadow.Intensity</L> := 70;
|
|
<L TIEVSoftShadow.Enabled>SoftShadow.Enabled</L> := bSoftShadow;
|
|
<FN>
|
|
|
|
<FM>Example<FC>
|
|
procedure TForm1.FormCreate(Sender: TObject);
|
|
begin
|
|
ImageEnMView1.SetModernStyling( True );
|
|
end;
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.Style>
|
|
- <A TImageEnMView.SetStyleEx>
|
|
- <A TIEImageEnGlobalSettings.EnableTheming>
|
|
!!}
|
|
procedure TImageEnMView.SetModernStyling(bAutoGridWidth : Boolean = False; iThumbWidth : Integer = 0; iThumbHeight : Integer = 0; bSoftShadow: Boolean = True);
|
|
var
|
|
iGap: Integer;
|
|
begin
|
|
LockUpdate;
|
|
try
|
|
fModernStyling := True;
|
|
fStyle := iemsFlat;
|
|
SoftShadow.Radius := 2;
|
|
SoftShadow.OffsetX := 2;
|
|
SoftShadow.OffsetY := 2;
|
|
SoftShadow.Intensity := 70;
|
|
SoftShadow.Enabled := bSoftShadow;
|
|
fBackground := clWindow;
|
|
fThumbnailsBackground := clWindow;
|
|
fThumbnailsBackgroundSelected := clExplorer_Selection_Background_Color;
|
|
fThumbnailsSelectedBorderColor := clExplorer_Selection_Border_Color;
|
|
fSelectionBorderWidth := 1;
|
|
fSelectionBorderWidthNoFocus := -1;
|
|
fTextMargin := Default_Text_Margin;
|
|
fHorizBorder := Default_Cell_Spacing;
|
|
fVertBorder := Default_Cell_Spacing;
|
|
ParentCtl3D := False;
|
|
Ctl3D := False;
|
|
if bSoftShadow then
|
|
iGap := Gap_When_Soft_Shadow
|
|
else
|
|
iGap := Gap_For_Thumbs_Style;
|
|
fUpperGap := iGap;
|
|
fBottomGap := iGap;
|
|
fSideGap := iGap;
|
|
fThumbnailsBorderWidth := 1;
|
|
fThumbnailsBorderColor := clBtnFace;
|
|
fTextBackgroundStyle := bsClear;
|
|
fThumbnailsInternalBorder := False;
|
|
if fThumbnailDisplayFilter = rfNone then
|
|
fThumbnailDisplayFilter := rfFastLinear;
|
|
if iThumbWidth > 0 then
|
|
begin
|
|
ThumbWidth := iThumbWidth;
|
|
ClearCache;
|
|
end;
|
|
if iThumbHeight > 0 then
|
|
begin
|
|
ThumbHeight := iThumbHeight;
|
|
ClearCache;
|
|
end;
|
|
if bAutoGridWidth then
|
|
begin
|
|
fGridWidth := -1;
|
|
fCurrentGridWidth := -1;
|
|
end;
|
|
finally
|
|
UnlockUpdate;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.EnableMultiSelect
|
|
|
|
<FM>Declaration<FC>
|
|
property EnableMultiSelect: Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Specify whether the user is able to select multiple images.
|
|
|
|
Default: false (i.e. multi-selection is disabled)
|
|
|
|
<FM>Example<FC>
|
|
// select images 0 and 1 (assumes you have set at design time ImageEnMView1.EnableMultiSelect := True)
|
|
ImageEnMView1.Deselect;
|
|
ImageEnMView1.MultiSelecting := True;
|
|
ImageEnMView1.SelectedImage := 0;
|
|
ImageEnMView1.SelectedImage := 1;
|
|
ImageEnMView1.MultiSelecting := False;
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.MultiSelectedImagesCount>
|
|
- <A TImageEnMView.MultiSelectedImages>
|
|
!!}
|
|
procedure TImageEnMView.SetEnableMultiSelect(Value: boolean);
|
|
begin
|
|
if fEnableMultiSelect <> Value then
|
|
begin
|
|
fEnableMultiSelect := Value;
|
|
Update;
|
|
end;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ThumbnailsBorderWidth
|
|
|
|
<FM>Declaration<FC>
|
|
property ThumbnailsBorderWidth: Integer;
|
|
|
|
<FM>Description<FN>
|
|
Specifies the width (in pixels) of the thumbnail border.
|
|
|
|
Default: 0
|
|
|
|
This value should be less than <A TImageEnMView.ThumbWidth> and <A TImageEnMView.ThumbHeight>. Specify the color of the border using <A TImageEnMView.ThumbnailsBorderColor>.
|
|
|
|
<FM>Example<FC>
|
|
// Draw a thin green border around all thumbnails
|
|
ImageEnMView1.ThumbnailsBorderWidth := 1;
|
|
ImageEnMView1.ThumbnailsBorderColor := clGreen;
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.SelectionWidth>
|
|
- <A TImageEnMView.SelectionWidthNoFocus>
|
|
- <A TImageEnMView.ThumbnailsBorderCurved>
|
|
!!}
|
|
procedure TImageEnMView.SetThumbnailsBorderWidth(Value: integer);
|
|
begin
|
|
if fThumbnailsBorderWidth <> Value then
|
|
begin
|
|
fThumbnailsBorderWidth := Value;
|
|
Update;
|
|
end;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ThumbnailsBorderColor
|
|
|
|
<FM>Declaration<FC>
|
|
property ThumbnailsBorderColor: TColor;
|
|
|
|
<FM>Description<FN>
|
|
Specifies the color of the thumbnail border.
|
|
|
|
Note: This value may be overridden if <A TIEImageEnGlobalSettings.EnableTheming> is enabled.
|
|
|
|
<FM>Example<FC>
|
|
// draw a thin green border to all thumbnails
|
|
ImageEnMView1.ThumbnailsBorderWidth := 1;
|
|
ImageEnMView1.ThumbnailsBorderColor := clGreen;
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.ThumbnailsBorderWidth>
|
|
- <A TImageEnMView.SelectionColor>
|
|
!!}
|
|
procedure TImageEnMView.SetThumbnailsBorderColor(Value: TColor);
|
|
begin
|
|
if fThumbnailsBorderColor <> Value then
|
|
begin
|
|
fThumbnailsBorderColor := Value;
|
|
Update;
|
|
end;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ThumbnailsBorderCurved
|
|
|
|
<FM>Declaration<FC>
|
|
property ThumbnailsBorderCurved: Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Specifies the width (in pixels) of the thumbnail border.
|
|
|
|
Default: True
|
|
|
|
<FM>Example<FC>
|
|
// Draw rectangular borders for thumbnails
|
|
ImageEnMView1.ThumbnailsBorderCurved := False;
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.ThumbnailsBorderWidth>
|
|
- <A TImageEnMView.SelectionWidth>
|
|
- <A TImageEnMView.SelectionWidthNoFocus>
|
|
!!}
|
|
procedure TImageEnMView.SetThumbnailsBorderCurved(Value: Boolean);
|
|
begin
|
|
if fThumbnailsBorderCurved <> Value then
|
|
begin
|
|
fThumbnailsBorderCurved := Value;
|
|
Update;
|
|
end;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ThumbnailsInternalBorder
|
|
|
|
<FM>Declaration<FC>
|
|
property ThumbnailsInternalBorder: boolean;
|
|
|
|
<FM>Description<FN>
|
|
If enabled, a border is drawn around the thumbnail interior. Specify the color using <A TImageEnMView.ThumbnailsInternalBorderColor>.
|
|
!!}
|
|
procedure TImageEnMView.SetThumbnailsInternalBorder(Value: boolean);
|
|
begin
|
|
if fThumbnailsInternalBorder <> Value then
|
|
begin
|
|
fThumbnailsInternalBorder := Value;
|
|
Update;
|
|
end;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ThumbnailsInternalBorderColor
|
|
|
|
<FM>Declaration<FC>
|
|
property ThumbnailsInternalBorderColor: TColor;
|
|
|
|
<FM>Description<FN>
|
|
Specifies the border color when <A TImageEnMView.ThumbnailsInternalBorder> is True.
|
|
|
|
!!}
|
|
procedure TImageEnMView.SetThumbnailsInternalBorderColor(Value: TColor);
|
|
begin
|
|
if fThumbnailsInternalBorderColor <> Value then
|
|
begin
|
|
fThumbnailsInternalBorderColor := Value;
|
|
Update;
|
|
end;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.TextColumnWidths
|
|
|
|
<FM>Declaration<FC>
|
|
property TextColumnWidths[Col : <A TIEMTextPos>] : Integer;
|
|
|
|
<FM>Description<FN>
|
|
Specifies the width of each column when <A TImageEnMView.Style> is set to <FC>iemsColumns<FN>.
|
|
|
|
<IMG help_images\Columns.jpg>
|
|
|
|
With the <FC>iemsColumns<FN> display style, data is shown in four columns:
|
|
- Thumbnail
|
|
- <A TImageEnMView.DefaultTopText>
|
|
- <A TImageEnMView.DefaultBottomText>
|
|
- <A TImageEnMView.DefaultInfoText>
|
|
|
|
The width of the thumbnail is set by <A TImageEnMView.ThumbWidth> whereas the width of each column can be specified by <FC>TextColumnWidths<FN>. If a column width is set to -1, then it will be automatically calculated. <FC>TextColumnWidths<FN> set to zero will be hidden (also if the <L TImageEnMView.DefaultTopText>text</L> is set to iedtNone).
|
|
|
|
Notes:
|
|
- Column widths will automatically be adjusted if they are too wide to fit in the available area
|
|
- Users can also manually resize column widths by clicking the header area with the mouse
|
|
|
|
<FM>Examples<FC>
|
|
// Display to the full width of the control with each column width auto-calculated
|
|
ImageEnMView1.LockUpdate;
|
|
ImageEnMView1.Style := iemsColumns;
|
|
ImageEnMView1.TextBlockWidth := -1;
|
|
ImageEnMView1.TextColumnWidths[ iemtpTop ] := -1;
|
|
ImageEnMView1.TextColumnWidths[ iemtpBottom ] := -1;
|
|
ImageEnMView1.TextColumnWidths[ iemtpInfo ] := -1;
|
|
ImageEnMView1.UnlockUpdate;
|
|
|
|
// Display to the full width of the control with the first column 100 pixels wide, the center column hidden, and the last column width auto-calculated
|
|
ImageEnMView1.LockUpdate;
|
|
ImageEnMView1.Style := iemsColumns;
|
|
ImageEnMView1.TextBlockWidth := -1;
|
|
ImageEnMView1.TextColumnWidths[ iemtpTop ] := 100;
|
|
ImageEnMView1.TextColumnWidths[ iemtpBottom ] := -1;
|
|
ImageEnMView1.TextColumnWidths[ iemtpInfo ] := 0;
|
|
ImageEnMView1.UnlockUpdate;
|
|
|
|
// Display to a total width of 300 with each column width auto-calculated
|
|
ImageEnMView1.LockUpdate;
|
|
ImageEnMView1.Style := iemsColumns;
|
|
ImageEnMView1.TextBlockWidth := 300;
|
|
ImageEnMView1.TextColumnWidths[ iemtpTop ] := -1;
|
|
ImageEnMView1.TextColumnWidths[ iemtpBottom ] := -1;
|
|
ImageEnMView1.TextColumnWidths[ iemtpInfo ] := -1;
|
|
ImageEnMView1.UnlockUpdate;
|
|
|
|
// Display to a total width of 300 with the first column 200 wide, and the remaining ones auto-calculated
|
|
ImageEnMView1.LockUpdate;
|
|
ImageEnMView1.Style := iemsColumns;
|
|
ImageEnMView1.TextBlockWidth := 300;
|
|
ImageEnMView1.TextColumnWidths[ iemtpTop ] := 200;
|
|
ImageEnMView1.TextColumnWidths[ iemtpBottom ] := -1;
|
|
ImageEnMView1.TextColumnWidths[ iemtpInfo ] := -1;
|
|
ImageEnMView1.UnlockUpdate;
|
|
|
|
// Display to a total width of 300 by setting specific widths for each column
|
|
ImageEnMView1.LockUpdate;
|
|
ImageEnMView1.Style := iemsColumns;
|
|
ImageEnMView1.TextBlockWidth := -1;
|
|
ImageEnMView1.TextColumnWidths[ iemtpTop ] := 200;
|
|
ImageEnMView1.TextColumnWidths[ iemtpBottom ] := 50;
|
|
ImageEnMView1.TextColumnWidths[ iemtpInfo ] := 50;
|
|
ImageEnMView1.UnlockUpdate;
|
|
|
|
<FM>Demo<FN>
|
|
<TABLE2>
|
|
<R> <C_IMG_DEMO> <C>\Demos\Multi\MViewStyles\MViewStyles.dpr </C> </R>
|
|
</TABLE>
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.TextBlockWidth>
|
|
- <A TImageEnMView.Style>
|
|
!!}
|
|
function TImageEnMView.GetTextColumnWidths(Col: TIEMTextPos): integer;
|
|
begin
|
|
Result := fTextColumnWidths[ Col ];
|
|
end;
|
|
|
|
procedure TImageEnMView.SetTextColumnWidths(Col: TIEMTextPos; value: integer);
|
|
begin
|
|
if fTextColumnWidths[ Col ] <> value then
|
|
begin
|
|
fTextColumnWidths[ Col ] := value;
|
|
Update;
|
|
end;
|
|
end;
|
|
|
|
function TImageEnMView.CurrentTextColumnWidths(Col: TIEMTextPos): integer;
|
|
var
|
|
iMaxWidth, iAvailWidth: Integer;
|
|
itt: TIEMTextPos;
|
|
ColText : TIEImageEnMViewDefaultText;
|
|
CurrColWidths : array[ iemtpTop .. iemtpInfo ] of Integer;
|
|
iUnknownCount: Integer;
|
|
iTotalWidth: Integer;
|
|
begin
|
|
Result := 0;
|
|
|
|
iAvailWidth := ClientWidth - trunc(fThumbWidth * fZoom / 100.0) - 2 * fHorizBorder;
|
|
iMaxWidth := fTextBlockWidth;
|
|
if ( iMaxWidth <= 0 ) or ( iMaxWidth > iAvailWidth ) then
|
|
iMaxWidth := iAvailWidth;
|
|
if iMaxWidth < 1 then
|
|
exit;
|
|
|
|
// Get all widths
|
|
iUnknownCount := 0;
|
|
iTotalWidth := 0;
|
|
for itt := iemtpTop to iemtpInfo do
|
|
begin
|
|
case itt of
|
|
iemtpTop : ColText := DefaultTopText;
|
|
iemtpBottom : ColText := DefaultBottomText;
|
|
else { iemtpInfo } ColText := DefaultInfoText;
|
|
end;
|
|
|
|
if ColText = iedtNone then
|
|
CurrColWidths[ itt ] := 0
|
|
else
|
|
CurrColWidths[ itt ] := fTextColumnWidths[ itt ];
|
|
if CurrColWidths[ itt ] = -1 then
|
|
inc( iUnknownCount )
|
|
else
|
|
inc( iTotalWidth, CurrColWidths[ itt ] );
|
|
end;
|
|
|
|
// Are we wider than available space? Proportionally reduce all cells
|
|
if iTotalWidth > iMaxWidth then
|
|
begin
|
|
for itt := iemtpTop to iemtpInfo do
|
|
if CurrColWidths[ itt ] > 0 then
|
|
CurrColWidths[ itt ] := Trunc( CurrColWidths[ itt ] * iMaxWidth / iTotalWidth );
|
|
iTotalWidth := iMaxWidth;
|
|
end;
|
|
|
|
Result := CurrColWidths[ Col ];
|
|
if Result = -1 then
|
|
Result := ( iMaxWidth - iTotalWidth ) div iUnknownCount;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.MultiSelectedImages
|
|
|
|
<FM>Declaration<FC>
|
|
property MultiSelectedImages[index: Integer]: Integer;
|
|
|
|
<FM>Description<FN>
|
|
Returns the index of all selected images, where MultiSelectedImages[0] returns the index of the first selected image, MultiSelectedImages[1] returns the second, etc.
|
|
|
|
Notes:
|
|
- Use <A TImageEnMView.MultiSelectedImagesCount> to know how many images are selected
|
|
- The index returned by MultiSelectedImages is not in any particular order unless <A TImageEnMView.MultiSelectSortList> is called
|
|
- This property is valid even if <L TImageEnMView.EnableMultiSelect>multiple selection</L> is not enabled (i.e. returning <A TImageEnMView.SelectedImage>).
|
|
|
|
<FM>Example 1<FC>
|
|
// replaces all selected images with 'new.jpg'
|
|
for i := 0 to ImageEnMView1.MultiSelectedImagesCount - 1 do
|
|
begin
|
|
iSelIndex := ImageEnMView1.MultiSelectedImages[ i ];
|
|
ImageEnMView1.SetImageFromFile(iSelIndex , 'new.jpg');
|
|
end;
|
|
|
|
<FM>Example 2<FC>
|
|
// Get filenames of all selected files
|
|
|
|
// Sort them by image index
|
|
ImageEnMView1.MultiSelectSortList;
|
|
lbxFilenames.clear;
|
|
|
|
for i := 0 to ImageEnMView1.MultiSelectedImagesCount - 1 do
|
|
begin
|
|
iSelIndex := ImageEnMView1.MultiSelectedImages[ i ];
|
|
lbxFilenames.Items.Add(ImageEnMView1.ImageFileName[iSelIndex]);
|
|
end;
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.MultiSelectSortList>
|
|
- <A TImageEnMView.MultiSelectedImagesCount>
|
|
- <A TImageEnMView.IsSelected>
|
|
|
|
!!}
|
|
function TImageEnMView.GetMultiSelectedImages(index: integer): integer;
|
|
begin
|
|
result := -1;
|
|
if EnableMultiSelect and (index >= 0) and (index < fMultiSelectedImages.Count) then
|
|
result := integer(fMultiSelectedImages[index])
|
|
else
|
|
if (EnableMultiSelect = False) and (index = 0) and (fSelectedItem > -1) then
|
|
Result := fSelectedItem;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.MultiSelectedImagesCount
|
|
|
|
<FM>Declaration<FC>
|
|
property MultiSelectedImagesCount: Integer;
|
|
|
|
<FM>Description<FN>
|
|
MultiSelectedImagesCount returns the number of selected images. Selected indexes are returned by <A TImageEnMView.MultiSelectedImages>.
|
|
|
|
Note: This property is valid even if <L TImageEnMView.EnableMultiSelect>multiple selection</L> is not enabled (i.e. returning either 0 or 1).
|
|
|
|
<FM>Example<FC>
|
|
// replaces all selected images with 'new.jpg'
|
|
for i := 0 to ImageEnMView1.MultiSelectedImagesCount - 1 do
|
|
begin
|
|
iSelIndex := ImageEnMView1.MultiSelectedImages[ i ];
|
|
ImageEnMView1.SetImageFromFile(iSelIndex , 'new.jpg');
|
|
end;
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.MultiSelectSortList>
|
|
- <A TImageEnMView.MultiSelectedImages>
|
|
- <A TImageEnMView.IsSelected>
|
|
!!}
|
|
function TImageEnMView.GetMultiSelectedImagesCount: integer;
|
|
begin
|
|
Result := 0;
|
|
if EnableMultiSelect then
|
|
result := fMultiSelectedImages.Count
|
|
else
|
|
if fSelectedItem > -1 then
|
|
Result := 1;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.MultiSelectedImagesList
|
|
|
|
<FM>Declaration<FC>
|
|
property MultiSelectedImagesList: <A TIEArrayOfInteger>;
|
|
|
|
<FM>Description<FN>
|
|
Returns an array of integers representing the indexes of all selected images. Changing the content of this list doesn't change the actual selected images.
|
|
|
|
Notes:
|
|
- The index returned by MultiSelectedImagesList is not in any particular order unless <A TImageEnMView.MultiSelectSortList> is called
|
|
- This property is valid even if <L TImageEnMView.EnableMultiSelect>multiple selection</L> is not enabled (i.e. returning <A TImageEnMView.SelectedImage>).
|
|
|
|
!!}
|
|
// returns a readonly list of selected images
|
|
function TImageEnMView.GetMultiSelectedImagesList(): TIEArrayOfInteger;
|
|
var
|
|
i: integer;
|
|
begin
|
|
SetLength(result, MultiSelectedImagesCount);
|
|
for i := 0 to length(result) - 1 do
|
|
result[i] := MultiSelectedImages[i];
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.Wallpaper
|
|
|
|
<FM>Declaration<FC>
|
|
property Wallpaper: TPicture;
|
|
|
|
<FM>Description<FN>
|
|
Sets a background image that appears behind the thumbnails. Use <A TImageEnMView.WallpaperStyle> to specify how the wallpaper is painted.
|
|
|
|
<FM>Demo<FN>
|
|
<TABLE2>
|
|
<R> <C_IMG_DEMO> <C>Demos\Multi\Thumbnails2\Thumbnails2.dpr </C> </R>
|
|
</TABLE>
|
|
|
|
<FM>Example<FC>
|
|
// Tile a bitmap over the background
|
|
ImageEnMView1.WallpaperStyle := iewoTile
|
|
ImageEnMView1.Wallpaper.LoadFromFile('D:\MyWallpaper.bmp');
|
|
!!}
|
|
procedure TImageEnMView.SetWallpaper(Value: TPicture);
|
|
begin
|
|
fWallpaper.Assign(Value);
|
|
Update;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.WallpaperStyle
|
|
|
|
<FM>Declaration<FC>
|
|
property WallpaperStyle: <A TIEWallpaperStyle>;
|
|
|
|
<FM>Description<FN>
|
|
Determines how the wallpaper (specified by <A TImageEnMView.Wallpaper>) is painted.
|
|
|
|
<FM>Example<FC>
|
|
// Tile a bitmap over the background
|
|
ImageEnMView1.WallpaperStyle := iewoTile
|
|
ImageEnMView1.Wallpaper.LoadFromFile('D:\MyWallpaper.bmp');
|
|
|
|
<IMG help_images\Thumbnails.gif>
|
|
!!}
|
|
procedure TImageEnMView.SetWallpaperStyle(Value: TIEWallpaperStyle);
|
|
begin
|
|
if Value <> fWallpaperStyle then
|
|
begin
|
|
fWallpaperStyle := Value;
|
|
Update;
|
|
end;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.SelectAll
|
|
|
|
<FM>Declaration<FC>
|
|
procedure SelectAll;
|
|
|
|
<FM>Description<FN>
|
|
Selects all images (if <A TImageEnMView.EnableMultiSelect> is true).
|
|
!!}
|
|
procedure TImageEnMView.SelectAll;
|
|
var
|
|
q: integer;
|
|
lMultiSelecting: boolean;
|
|
begin
|
|
if fEnableMultiSelect then
|
|
begin
|
|
DeselectNU;
|
|
lMultiSelecting := fMultiSelecting;
|
|
fMultiSelecting := true;
|
|
for q := 0 to fIEMBitmap.Count - 2 do
|
|
fMultiSelectedImages.Add(pointer(q));
|
|
SetSelectedItemNU(fIEMBitmap.Count - 1); // last item also is current selected item (own Bitmap object)
|
|
fMultiSelecting := lMultiSelecting;
|
|
UpdateEx(false);
|
|
end;
|
|
end;
|
|
|
|
function TImageEnMView.GetEnableResamplingOnMinor : boolean;
|
|
begin
|
|
Result := ietxStretchSmallImages in fThumbnailOptionsEx;
|
|
end;
|
|
|
|
{$ifdef IEIncludeDeprecatedInV5}
|
|
// Deprecated in 6.0.0 (2015-03-06)
|
|
procedure TImageEnMView.SetEnableResamplingOnMinor(Value: boolean);
|
|
begin
|
|
if value then
|
|
fThumbnailOptionsEx := fThumbnailOptionsEx + [ ietxStretchSmallImages ]
|
|
else
|
|
fThumbnailOptionsEx := fThumbnailOptionsEx - [ ietxStretchSmallImages ];
|
|
Update;
|
|
end;
|
|
{$endif}
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.IconSize
|
|
|
|
<FM>Declaration<FC>
|
|
property IconSize : <A TIEImageEnMViewIconSize>;
|
|
|
|
<FM>Description<FN>
|
|
For non-image types a system icon is displayed. The default setting is _icoHDStretch which means that a high quality icon is stretched to the display size. On Windows XP and older versions, it automatically downgrades to ieicDoubleSize.
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.ThumbnailOptionsEx>
|
|
!!}
|
|
procedure TImageEnMView.SetIconSize(Value: TIEImageEnMViewIconSize);
|
|
begin
|
|
if fIconSize <> Value then
|
|
begin
|
|
fIconSize := Value;
|
|
ClearCache;
|
|
Update;
|
|
end;
|
|
end;
|
|
|
|
|
|
function TImageEnMView.GetImageEnMIO: TImageEnMIO;
|
|
begin
|
|
if not assigned(fImageEnMIO) then
|
|
begin
|
|
fImageEnMIO := TImageEnMIO.Create(self);
|
|
fImageEnMIO.AttachedMView := self;
|
|
fImageEnMIO.OnProgress := fOnProgress;
|
|
fImageEnMIO.OnFinishWork := fOnFinishWork;
|
|
fImageEnMIO.OnAcquireBitmap := fOnAcquireBitmap;
|
|
end;
|
|
result := fImageEnMIO;
|
|
end;
|
|
|
|
function TImageEnMView.GetImageEnProc: TImageEnProc;
|
|
begin
|
|
if fSelectedItem = -1 then
|
|
SelectedImage := 0;
|
|
|
|
if not assigned(fImageEnProc) then
|
|
begin
|
|
fImageEnProc := TImageEnProc.Create(self);
|
|
fImageEnProc.AttachedImageEn := self;
|
|
fImageEnProc.OnProgress := fOnProgress;
|
|
fImageEnProc.OnFinishWork := fOnFinishWork;
|
|
fImageEnProc.fOnUndoRedoEvent := ProcessUndoRedo;
|
|
end;
|
|
|
|
fImageEnProc.fMViewIndex := fSelectedItem;
|
|
result := fImageEnProc;
|
|
|
|
if not assigned(fSelectedBitmap) then
|
|
fImageEnProc.AttachedImageEn := self; // refresh bitmap if fSelectedBitmap=nil
|
|
end;
|
|
|
|
|
|
function TImageEnMView.CheckSelectionChangingAllowed : Boolean;
|
|
begin
|
|
Result := True;
|
|
if (fDestroying = False) and assigned(fOnSelectionChanging) then
|
|
fOnSelectionChanging(self, Result);
|
|
end;
|
|
|
|
procedure TImageEnMView.ProcessUndoRedo(Sender : TObject; bIsUndo : Boolean; Source : TIEUndoSource; UndoObj : TObject; iIndex : Integer; var bHandled : Boolean);
|
|
var
|
|
bmp: TIEBitmap;
|
|
begin
|
|
if (Source <> ieuImage) or (iIndex < 0) then
|
|
exit;
|
|
|
|
bHandled := True;
|
|
if iIndex = fSelectedItem then
|
|
IEBitmap.assign(TIEBitmap(UndoObj))
|
|
else
|
|
begin
|
|
bmp := GetTIEBitmap(iIndex);
|
|
bmp.assign(TIEBitmap(UndoObj));
|
|
ReleaseBitmap(iIndex);
|
|
end;
|
|
Update;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.OnAcquireBitmap
|
|
|
|
<FM>Declaration<FC>
|
|
property OnAcquireBitmap: <A TIEAcquireBitmapEvent>;
|
|
|
|
<FM>Description<FN>
|
|
Occurs whenever a new bitmap is acquired during a multi-page Twain acquisition.
|
|
<TABLE>
|
|
<R> <H>Parameter</H> <H>Description</H> </R>
|
|
<R> <C>Sender</C> <C>Will be either a TImageEnIO or TImageEnMIO control</C> </R>
|
|
<R> <C>ABitmap</C> <C>A <A TIEBitmap> object that contains the acquired image</C> </R>
|
|
<R> <C>DpiX, DpiY</C> <C>Tne DPI of the acquired image</C> </R>
|
|
<R> <C>Handled</C> <C>Setting Handled to True causes ImageEn to ignore this image (i.e. the current image won't be inserted into the <A TImageEnMView> control, if attached). Handled has no effect when acquiring via a TImageEnView/TImageEnIO</C> </R>
|
|
</TABLE>
|
|
|
|
Note: Handled defaults to False.
|
|
|
|
<FM>Example<FC>
|
|
procedure TForm1.ImageEnMView1AcquireBitmap(Sender: TObject; ABitmap: TIEBitmap; DpiX, DpiY: Integer; var Handled: boolean);
|
|
begin
|
|
// Skip retrieval of images that are less than 500x500 pixels
|
|
If ( ABitmap.Width < 500 ) or ( ABitmap.Height < 500 ) then
|
|
Handled := True;
|
|
end;
|
|
!!}
|
|
function TImageEnMView.GetOnAcquireBitmap: TIEAcquireBitmapEvent;
|
|
begin
|
|
result := fOnAcquireBitmap;
|
|
end;
|
|
|
|
procedure TImageEnMView.SetOnAcquireBitmap(v: TIEAcquireBitmapEvent);
|
|
begin
|
|
fOnAcquireBitmap := v;
|
|
if assigned(fImageEnIO) then
|
|
fImageEnIO.OnAcquireBitmap := v;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.OnFinishWork
|
|
|
|
<FM>Declaration<FC>
|
|
property OnFinishWork: TNotifyEvent;
|
|
|
|
<FM>Description<FN>
|
|
Occurs whenever an image processing or input/output task terminates.
|
|
|
|
It is always called after <A TImageEnMView.OnProgress> so can be used to reset your progress bar.
|
|
!!}
|
|
|
|
function TImageEnMView.GetOnFinishWork: TNotifyEvent;
|
|
begin
|
|
result := fOnFinishWork;
|
|
end;
|
|
|
|
procedure TImageEnMView.SetOnFinishWork(v: TNotifyEvent);
|
|
begin
|
|
fOnFinishWork := v;
|
|
if assigned(fImageEnMIO) then
|
|
fImageEnMIO.OnFinishWork := v;
|
|
if assigned(fImageEnProc) then
|
|
fImageEnProc.OnFinishWork := v;
|
|
end;
|
|
|
|
|
|
procedure TImageEnMView.SetOnProgress(v: TIEProgressEvent);
|
|
begin
|
|
fOnProgress := v;
|
|
if assigned(fImageEnMIO) then
|
|
fImageEnMIO.OnProgress := v;
|
|
if assigned(fImageEnProc) then
|
|
fImageEnProc.OnProgress := v;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.OnProgress
|
|
|
|
<FM>Declaration<FC>
|
|
property OnProgress: <A TIEProgressEvent>;
|
|
|
|
<FM>Description<FN>
|
|
Occurs during image processing or input/output operations. It is useful to display progress to the user of the current task.
|
|
|
|
You can use <A TImageEnMView.OnFinishWork> to reset the progress when the task has completed.
|
|
|
|
!!}
|
|
function TImageEnMView.GetOnProgress: TIEProgressEvent;
|
|
begin
|
|
result := fOnProgress;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.MaximumViewX
|
|
|
|
<FM>Declaration<FC>
|
|
property MaximumViewX: Integer;
|
|
|
|
<FM>Description<FN>
|
|
Returns the maximum value that you can specify for <A TImageEnMView.ViewX> (naturally "MinimumViewX" is zero).
|
|
|
|
See also: <A TImageEnMView.MaximumViewY>.
|
|
|
|
!!}
|
|
function TImageEnMView.GetMaximumViewX: integer;
|
|
begin
|
|
result := imax(fVWidth - ClientWidth, 0);
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.MaximumViewY
|
|
|
|
<FM>Declaration<FC>
|
|
property MaximumViewY: Integer;
|
|
|
|
<FM>Description<FN>
|
|
Returns the maximum value that you can specify for <A TImageEnMView.ViewY> (naturally "MinimumViewY" is zero).
|
|
|
|
See also: <A TImageEnMView.MaximumViewX>.
|
|
!!}
|
|
function TImageEnMView.GetMaximumViewY: integer;
|
|
begin
|
|
result := imax(fVHeight - ClientHeight, 0);
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.DefaultTopText
|
|
|
|
<FM>Declaration<FC>
|
|
property DefaultTopText: <A TIEImageEnMViewDefaultText>;
|
|
|
|
<FM>Description<FN>
|
|
The text that will display above the thumbnail for images that do not have a value specified for <A TImageEnMView.ImageTopText>.
|
|
|
|
Default: iedtNone
|
|
|
|
You can also set: <A TImageEnMView.DefaultTopText> and <A TImageEnMView.DefaultInfoText>
|
|
|
|
<FM>Example<FC>
|
|
// Display the filename and details for each image
|
|
ImageEnMView1.DefaultImageTopText := iedtFilename;
|
|
ImageEnMView1.DefaultImageInfoText := iedtImageDimensions;
|
|
ImageEnMView1.DefaultImageBottomText := iedtFileEditDateAndSize;
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.OnGetText>
|
|
- <A TImageEnMView.OnGetTextEx>
|
|
!!}
|
|
procedure TImageEnMView.SetDefaultTopText(Value : TIEImageEnMViewDefaultText);
|
|
begin
|
|
if fDefaultTopText <> Value then
|
|
begin
|
|
fDefaultTopText := Value;
|
|
UpdateTopTextHeight( fDefaultTopText <> iedtNone );
|
|
Update;
|
|
end;
|
|
end;
|
|
|
|
procedure TImageEnMView.UpdateTopTextHeight(bHasText: Boolean);
|
|
begin
|
|
fTopTextHeight := 0;
|
|
if bHasText = False then
|
|
exit;
|
|
|
|
if not HandleAllocated then
|
|
begin
|
|
fTopTextHeight := CALCULATE_NOW;
|
|
end
|
|
else
|
|
begin
|
|
Canvas.Font.Assign( fTopTextFont );
|
|
fTopTextHeight := IETextHeightW( Canvas, 'Xy' ) + 2 + fTextMargin;
|
|
end;
|
|
end;
|
|
|
|
procedure TImageEnMView.TopTextFontChange(Sender: TObject);
|
|
begin
|
|
UpdateTopTextHeight(( fDefaultTopText <> iedtNone ) or (fTopTextHeight > 0 ));
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.DefaultInfoText
|
|
|
|
<FM>Declaration<FC>
|
|
property DefaultInfoText: <A TIEImageEnMViewDefaultText>;
|
|
|
|
<FM>Description<FN>
|
|
The text that will display directly below the thumbnail (above <A TImageEnMView.DefaultBottomText>) for images that do not have a value specified for <A TImageEnMView.ImageInfoText>.
|
|
|
|
Default: iedtNone
|
|
|
|
You can also set: <A TImageEnMView.DefaultTopText> and <A TImageEnMView.DefaultInfoText>
|
|
|
|
<FM>Example<FC>
|
|
// Display the filename and details for each image
|
|
ImageEnMView1.DefaultImageTopText := iedtFilename;
|
|
ImageEnMView1.DefaultImageInfoText := iedtImageDimensions;
|
|
ImageEnMView1.DefaultImageBottomText := iedtFileEditDateAndSize;
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.OnGetText>
|
|
- <A TImageEnMView.OnGetTextEx>
|
|
!!}
|
|
procedure TImageEnMView.SetDefaultInfoText(Value : TIEImageEnMViewDefaultText);
|
|
begin
|
|
if fDefaultInfoText <> Value then
|
|
begin
|
|
fDefaultInfoText := Value;
|
|
UpdateInfoTextHeight( fDefaultInfoText <> iedtNone );
|
|
Update;
|
|
end;
|
|
end;
|
|
|
|
procedure TImageEnMView.UpdateInfoTextHeight(bHasText: Boolean);
|
|
begin
|
|
fInfoTextHeight := 0;
|
|
if bHasText = False then
|
|
exit;
|
|
|
|
if not HandleAllocated then
|
|
begin
|
|
fInfoTextHeight := CALCULATE_NOW;
|
|
end
|
|
else
|
|
begin
|
|
Canvas.Font.Assign( fInfoTextFont );
|
|
fInfoTextHeight := IETextHeightW( Canvas, 'Xy' );
|
|
end;
|
|
end;
|
|
|
|
procedure TImageEnMView.InfoTextFontChange(Sender: TObject);
|
|
begin
|
|
UpdateInfoTextHeight(( fDefaultInfoText <> iedtNone ) or (fInfoTextHeight > 0 ));
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.DefaultBottomText
|
|
|
|
<FM>Declaration<FC>
|
|
property DefaultBottomText: <A TIEImageEnMViewDefaultText>;
|
|
|
|
<FM>Description<FN>
|
|
The text that will display below the thumbnail (below <A TImageEnMView.DefaultInfoText>) for images that do not have a value specified for <A TImageEnMView.ImageBottomText>.
|
|
|
|
TImageEnMView Default: iedtNone
|
|
TImageEnFolderMView Default: iedtFilename
|
|
|
|
You can also set: <A TImageEnMView.DefaultTopText> and <A TImageEnMView.DefaultInfoText>
|
|
|
|
<FM>Example<FC>
|
|
// Display the filename and details for each image
|
|
ImageEnMView1.DefaultImageTopText := iedtFilename;
|
|
ImageEnMView1.DefaultImageInfoText := iedtImageDimensions;
|
|
ImageEnMView1.DefaultImageBottomText := iedtFileEditDateAndSize;
|
|
|
|
// Replace existing bottom text and display the file date and size
|
|
for I := 0 to ImageEnMView1.ImageCount - 1 do
|
|
ImageEnMView1.ImageBottomText[ i ] := '' ;
|
|
ImageEnMView1.DefaultImageBottomText := iedtFileEditDateAndSize;
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.OnGetText>
|
|
- <A TImageEnMView.OnGetTextEx>
|
|
!!}
|
|
procedure TImageEnMView.SetDefaultBottomText(Value : TIEImageEnMViewDefaultText);
|
|
begin
|
|
if fDefaultBottomText <> Value then
|
|
begin
|
|
fDefaultBottomText := Value;
|
|
UpdateBottomTextHeight( fDefaultBottomText <> iedtNone );
|
|
Update;
|
|
end;
|
|
end;
|
|
|
|
procedure TImageEnMView.UpdateBottomTextHeight(bHasText: Boolean);
|
|
begin
|
|
fBottomTextHeight := 0;
|
|
if bHasText = False then
|
|
exit;
|
|
|
|
if not HandleAllocated then
|
|
begin
|
|
fBottomTextHeight := CALCULATE_NOW;
|
|
end
|
|
else
|
|
begin
|
|
Canvas.Font.Assign( fBottomTextFont );
|
|
fBottomTextHeight := IETextHeightW( Canvas, 'Xy' ) + 2 + fTextMargin;
|
|
if fStyle = iemsACD then
|
|
Inc( fBottomTextHeight, 2 );
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TImageEnMView.BottomTextFontChange(Sender: TObject);
|
|
begin
|
|
UpdateBottomTextHeight(( fDefaultBottomText <> iedtNone ) or ( fBottomTextHeight > 0 ));
|
|
end;
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ClearImageCache
|
|
|
|
<FM>Declaration<FC>
|
|
procedure ClearImageCache(idx: Integer);
|
|
|
|
<FM>Description<FN>
|
|
Clears the cache for image, <FC>idx<FN>.
|
|
|
|
Image caching allows you to speed up the thumbnail painting by saving the view of each image to an internal cache. You should call this method only if you have refreshing problems.
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.EnableImageCaching>
|
|
- <A TImageEnMView.ImageCacheSize>
|
|
- <A TImageEnMView.ImageCacheUseDisk>
|
|
!!}
|
|
procedure TImageEnMView.ClearImageCache(idx: integer);
|
|
var
|
|
info: TIEImageInfo;
|
|
begin
|
|
info := fIEMBitmap.GetImageInfo( idx );
|
|
if ( info <> nil ) and ( info.cacheImage <> nil ) then
|
|
begin
|
|
fcacheList.Delete(info.cacheImage);
|
|
info.cacheImage := nil;
|
|
end;
|
|
end;
|
|
|
|
procedure TImageEnMView.ClearCache;
|
|
var
|
|
i: integer;
|
|
begin
|
|
for i := 0 to fIEMBitmap.Count - 1 do
|
|
ClearImageCache(i);
|
|
fIconList.Clear();
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.EnableImageCaching
|
|
|
|
<FM>Declaration<FC>
|
|
property EnableImageCaching: Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Speeds up thumbnail painting by saving the view of each image to an internal cache. This is enabled by default.
|
|
|
|
Set to false to disable image caching.
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.ClearImageCache>
|
|
- <A TImageEnMView.ImageCacheSize>
|
|
- <A TImageEnMView.ImageCacheUseDisk>
|
|
!!}
|
|
procedure TImageEnMView.SetEnableImageCaching(v: boolean);
|
|
begin
|
|
fEnableImageCaching := v;
|
|
if not fEnableImageCaching then
|
|
begin
|
|
if fStoreType = ietFastThumb then
|
|
fStoreType := ietThumb;
|
|
ClearCache;
|
|
update;
|
|
end;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.IsSelected
|
|
|
|
<FM>Declaration<FC>
|
|
function IsSelected(idx: Integer): Boolean;
|
|
|
|
<FM>Description<FN>
|
|
IsSelected returns true if the image, <FC>idx<FN>, is currently selected.
|
|
|
|
<FM>Example<FC>
|
|
// replaces all selected images with 'new.jpg'
|
|
for idx := 0 to ImageEnMView1.ImageCount - 1 do
|
|
if ImageEnMView1.IsSelected(idx) then
|
|
ImageEnMView1.SetImageFromFile(idx, 'new.jpg');
|
|
end;
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.MultiSelectedImages>
|
|
|
|
!!}
|
|
function TImageEnMView.IsSelected(idx: integer): boolean;
|
|
begin
|
|
result := (fSelectedItem = idx) or (fMultiSelectedImages.IndexOf(pointer(idx)) > -1);
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.MultiSelectSortList
|
|
|
|
<FM>Declaration<FC>
|
|
procedure MultiSelectSortList;
|
|
|
|
<FM>Description<FN>
|
|
Sorts the selected items list (<A TImageEnMView.MultiSelectedImages>) by image index.
|
|
|
|
<FM>Example<FC>
|
|
// Get filenames of all selected files in the order they are displayed
|
|
ImageEnMView1.MultiSelectSortList;
|
|
lbxFilenames.clear;
|
|
for i := 0 to ImageEnMView1.MultiSelectedImagesCount - 1 do
|
|
begin
|
|
iSelIndex := ImageEnMView1.MultiSelectedImages[ i ];
|
|
lbxFilenames.Items.Add(ImageFileName[iSelIndex]);
|
|
end;
|
|
|
|
!!}
|
|
procedure TImageEnMView.MultiSelectSortList;
|
|
begin
|
|
fMultiSelectedImages.Sort(@ComparePointers);
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.EnableAlphaChannel
|
|
|
|
<FM>Declaration<FC>
|
|
property EnableAlphaChannel: Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Set EnableAlphaChannel to True to enable the alpha channel of thumbnails (e.g. for the display of <L TImageEnMView.SoftShadow>soft shadows</L>).
|
|
!!}
|
|
procedure TImageEnMView.SetEnableAlphaChannel(v: boolean);
|
|
begin
|
|
fEnableAlphaChannel := v;
|
|
Update;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.BackgroundStyle
|
|
|
|
<FM>Declaration<FC>
|
|
property BackgroundStyle: <A TIEBackgroundStyle>;
|
|
|
|
<FM>Description<FN>
|
|
Specifies the style of the background (the component region behind the thumbnails).
|
|
|
|
<FM>Example<FC>
|
|
// Small chessboard background
|
|
ImageEnMView1.BackgroundStyle := iebsChessboard;
|
|
ImageEnMView1.SetChessboardStyle(5, bsSolid);
|
|
|
|
// Solid white background
|
|
ImageEnMView1.BackgroundStyle := iebsSolid;
|
|
ImageEnMView1.Background := clWhite;
|
|
|
|
// Navy -> Black gradient background
|
|
ImageEnMView1.BackgroundStyle := iebsGradient;
|
|
ImageEnMView1.Background := clNavy;
|
|
ImageEnMView1.GradientEndColor := clBlack;
|
|
|
|
!!}
|
|
procedure TImageEnMView.SetBackgroundStyle(v: TIEBackgroundStyle);
|
|
begin
|
|
fBackgroundStyle := v;
|
|
Update;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ThumbnailsBackgroundStyle
|
|
|
|
<FM>Declaration<FC>
|
|
property ThumbnailsBackgroundStyle: <A TIEBackgroundStyle>
|
|
|
|
<FM>Description<FN>
|
|
Specifies the style of the thumbnail background (the region of the thumbnail that does not contain the image).
|
|
|
|
Note: Only applicable when <A TImageEnMView.EnableAlphaChannel> is true and the image has an alpha channel to make it transparent.
|
|
|
|
!!}
|
|
procedure TImageEnMView.SetThumbnailsBackgroundStyle(v: TIEBackgroundStyle);
|
|
begin
|
|
fThumbnailsBackgroundStyle := v;
|
|
Update;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.SetChessboardStyle
|
|
|
|
<FM>Declaration<FC>
|
|
procedure SetChessboardStyle(Size: Integer; BrushStyle: TBrushStyle = bsSolid; Color1: TColor = clNone; Color2: TColor = clNone);
|
|
|
|
<FM>Description<FN>
|
|
Sets the size and brush of the chessboard background (when <A TImageEnMView.BackgroundStyle> is iebsChessboard).
|
|
|
|
<TABLE>
|
|
<R> <H>Parameter</H> <H>Description</H> </R>
|
|
<R> <C><FC>Size<FN></C> <C>Specifies the box size (default 16)</C> </R>
|
|
<R> <C><FC>BrushStyle<FN></C> <C>Specifies the brush style of the boxes (default bsSolid)</C> </R>
|
|
<R> <C><FC>Color1<FN></C> <C>Color 1 of chessboard. Specifying this as something other than clNone will set <A TImageEnView.Background></C> </R>
|
|
<R> <C><FC>Color2<FN></C> <C>Color 2 of chessboard. If specified as clNone, then color 2 will be a reverse of Color 1</C> </R>
|
|
</TABLE>
|
|
|
|
<FM>Example<FC>
|
|
// Set small chessboard background of Yellow and Blue
|
|
ImageEnMView1.SetChessboardStyle( 5, bsSolid, clBlue, clYellow );
|
|
ImageEnMView1.BackgroundStyle := iebsChessboard;
|
|
|
|
!!}
|
|
procedure TImageEnMView.SetChessboardStyle(Size: Integer; BrushStyle: TBrushStyle = bsSolid; Color1: TColor = clNone_; Color2: TColor = clNone_);
|
|
begin
|
|
fChessboardSize := Size;
|
|
fChessboardBrushStyle := BrushStyle;
|
|
fChessboardColor2Customized := Color2 <> clNone_;
|
|
if Color1 <> clNone_ then
|
|
Background := Color1;
|
|
if Color2 <> clNone_ then
|
|
GradientEndColor := Color2;
|
|
end;
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.GradientEndColor
|
|
|
|
<FM>Declaration<FC>
|
|
property GradientEndColor: TColor
|
|
|
|
<FM>Description<FN>
|
|
Specifies the ending color of the gradient when <A TImageEnMView.BackgroundStyle> is iebsGradient. <A TImageEnMView.Background> specifies the starting color.
|
|
|
|
Note: This value may be overridden if <A TIEImageEnGlobalSettings.EnableTheming> is enabled.
|
|
|
|
Default: clBtnShadow
|
|
|
|
<FM>Example<FC>
|
|
// Set Navy -> Black gradient background
|
|
ImageEnMView1.BackgroundStyle := iebsGradient;
|
|
ImageEnMView1.Background := clNavy;
|
|
ImageEnMView1.GradientEndColor := clBlack;
|
|
|
|
!!}
|
|
procedure TImageEnMView.SetGradientEndColor(Value: TColor);
|
|
begin
|
|
fGradientEndColor := Value;
|
|
Update;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.FillThumbnail
|
|
|
|
<FM>Declaration<FC>
|
|
property FillThumbnail: Boolean;
|
|
|
|
<FM>Description<FN>
|
|
When enabled, the thumbnail background is filled with the background color. Generally an unselected image is filled with <A TImageEnMView.ThumbnailsBackground>, and selected one filled with <A TImageEnMView.ThumbnailsBackgroundSelected>.
|
|
|
|
Default: True
|
|
|
|
See also: <A TImageEnMView.ThumbnailsBackgroundStyle>
|
|
!!}
|
|
procedure TImageEnMView.SetFillThumbnail(Value: boolean);
|
|
begin
|
|
fFillThumbnail := Value;
|
|
Update;
|
|
end;
|
|
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.AnnotationsVisible
|
|
|
|
<FM>Declaration<FC>
|
|
property AnnotationsVisible: Boolean;
|
|
|
|
<FM>Description<FN>
|
|
When enabled, <L TIOParams.ImagingAnnot>Wang annotations</L> and <L TIOParams.ImageEnAnnot>ImageEn annotations</L> of the image are shown on the thumbnail.
|
|
|
|
Default: False
|
|
|
|
Notes:
|
|
- This property has no effect if <A TImageEnMView.StoreType> is ietThumb. It is only supported by ietNormal and ietFastThumb.
|
|
- This will slow performance so is only recommended for annotation-specific applications.
|
|
|
|
<FM>Example<FC>
|
|
// Test application with a TImageEnMView that loads and saves a multiple page TIFF file, and TImageEnVect that allows annotation editing
|
|
|
|
// Show annotations of selected frame
|
|
procedure TForm1.ImageEnMView1ImageSelect(Sender: TObject; idx: Integer);
|
|
begin
|
|
// Clear TImageEnVect
|
|
ImageEnVect1.RemoveAllObjects;
|
|
ImageEnVect1.Clear;
|
|
|
|
// Get selected image
|
|
ImageEnMView1.CopyToIEBitmap( idx, ImageEnVect1.IEBitmap );
|
|
|
|
// Get ImageEn annotations
|
|
if ImageEnMView1.MIO.Params[ idx ].ImageEnAnnot.IsEmpty = False then
|
|
ImageEnMView1.MIO.Params[ idx ].ImageEnAnnot.CopyToTImageEnVect( ImageEnVect1 );
|
|
|
|
// Refresh the TImageEnVect
|
|
ImageEnVect1.Update;
|
|
end;
|
|
|
|
// Save the annotations
|
|
procedure TForm1.btnSaveAnnotClick(Sender: TObject);
|
|
begin
|
|
if ImageEnMView1.SelectedImage > -1 then
|
|
begin
|
|
ImageEnMView1.MIO.Params[ ImageEnMView1.SelectedImage ].ImageEnAnnot.CopyFromTImageEnVect( ImageEnVect1 );
|
|
ImageEnMView1.UpdateImage( ImageEnMView1.SelectedImage );
|
|
end;
|
|
end;
|
|
!!}
|
|
procedure TImageEnMView.SetAnnotationsVisible(Value: boolean);
|
|
begin
|
|
if fAnnotationsVisible <> Value then
|
|
begin
|
|
fAnnotationsVisible := Value;
|
|
Update;
|
|
end;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ShowText
|
|
|
|
<FM>Declaration<FC>
|
|
property ShowText: Boolean;
|
|
|
|
<FM>Description<FN>
|
|
If enabled, the <A TImageEnMView.ImageTopText>, <A TImageEnMView.ImageBottomText> and <A TImageEnMView.ImageInfoText> are displayed.
|
|
|
|
Default: True
|
|
!!}
|
|
procedure TImageEnMView.SetShowText(Value: boolean);
|
|
begin
|
|
fShowText := Value;
|
|
Update;
|
|
end;
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ThumbnailClipping
|
|
|
|
<FM>Declaration<FC>
|
|
property ThumbnailClipping: Integer;
|
|
|
|
<FM>Description<FN>
|
|
Automatically clips the sides of the thumbnail when displaying it so that it more closely matches the size of the grid cell, for example, if you have a tall/portrait image the top and bottom would not be shown so that the thumbnail is as wide as the display area.
|
|
|
|
ThumbnailClipping is a percentage so the valid range is 0 to 100.
|
|
|
|
Possible values
|
|
<TABLE>
|
|
<R> <H>Value</H> <H>Description</H> </R>
|
|
<R> <C>0</C> <C>The entire image will be displayed as a thumbnail pointer.</C> </R>
|
|
<R> <C>1 - 99</C> <C>The percentage of permissible clipping. E.g. 10 would mean that up 10% of the image can be clipped.</C> </R>
|
|
<R> <C>100</C> <C>The maximum clipping will be performed so that the thumbnail has no border space (and all thumbnails will be displayed at an identical size)</C> </R>
|
|
</TABLE>
|
|
!!}
|
|
|
|
procedure TImageEnMView.SetThumbnailClipping(Value: Integer);
|
|
begin
|
|
if fThumbnailClipping <> Value then
|
|
begin
|
|
fThumbnailClipping := Value;
|
|
ClearCache;
|
|
Update;
|
|
end;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.FillFromDirectory
|
|
|
|
<FM>Declaration<FC>
|
|
procedure FillFromDirectory(const Directory: WideString; Limit : integer = -1; AllowUnknownFormats : boolean = false; const ExcludeExtensions : WideString = '';
|
|
DetectFileFormat : boolean = false; const FilterMask : WideString = ''; IncludeVideoFiles : Boolean = False;
|
|
LoadOnDemand : boolean = true;
|
|
DefaultTopText : <A TIEImageEnMViewDefaultText> = iedtNone;
|
|
DefaultInfoText : <A TIEImageEnMViewDefaultText> = iedtNone;
|
|
DefaultBottomText : <A TIEImageEnMViewDefaultText> = iedtFilename;
|
|
bShowHiddenFiles : Boolean = False;
|
|
bShowFolders : Boolean = False);
|
|
|
|
<FM>Description<FN>
|
|
Fills the ImageEnMView with files from the specified <FC>Directory<FN>. For each file <A TImageEnMView.ImageFileName> will be set with the full path and <A TImageEnMView.ImageBottomText> with the filename.
|
|
You can cancel the insertion of files by setting MIO.Aborting := True;
|
|
|
|
<TABLE>
|
|
<R> <H>Parameter</H> <H>Description</H> </R>
|
|
<R> <C><FC>Directory<FN></C> <C>The folder to search for files</C> </R>
|
|
<R> <C><FC>Limit<FN></C> <C>The maximum number of images to load. Use -1 to retrieve all files</C> </R>
|
|
<R> <C><FC>AllowUnknownFormats<FN></C> <C>If false (default) only known and supported file formats are loaded. Otherwise all files are loaded</C> </R>
|
|
<R> <C><FC>ExcludeExtensions<FN></C> <C>A comma separated list of file extensions to skip (e.g. 'lyr,all,iev')</C> </R>
|
|
<R> <C><FC>DetectFileFormat<FN></C> <C>If true then the image type is detected by reading the header (which can be slow). Otherwise ImageEn only checks the file extension</C> </R>
|
|
<R> <C><FC>FilterMask<FN></C> <C>Limits the fill to file extensions found in a comma separated list (e.g. 'jpg,jpeg,jpe'). Specify an empty string to return all supported extensions</C> </R>
|
|
<R> <C><FC>bIncludeVideoFiles<FN></C> <C>If AllowUnknownFormats is false then video files are excluded by default. Set to true to include supported video file types such as AVI and MPEG. Thumbnails for video files will be retrieved from Windows Explorer if the format is specified in <A TIEImageEnGlobalSettings.MViewExplorerThumbnailExts></C> </R>
|
|
<R> <C><FC>LoadOnDemand<FN></C> <C>If True (Default), images are only loaded as they are displayed (i.e. not until they are scrolled into view). Set to false to load all images immediately</C> </R>
|
|
<R> <C><FC>DefaultTopText<FN></C> <C>Specify <L TIEImageEnMViewDefaultText>the text</L> that is applied to <A TImageEnMView.ImageTopText></C> </R>
|
|
<R> <C><FC>DefaultInfoText<FN></C> <C>Specify <L TIEImageEnMViewDefaultText>the text</L> that is applied to <A TImageEnMView.ImageInfoText></C> </R>
|
|
<R> <C><FC>DefaultBottomText<FN></C> <C>Specify <L TIEImageEnMViewDefaultText>the text</L> that is applied to <A TImageEnMView.ImageBottomText> (defaults to the filename)</C> </R>
|
|
<R> <C><FC>bShowHiddenFiles<FN></C> <C>Enable to include hidden and system files (default is false)</C> </R>
|
|
<R> <C><FC>bShowFolders<FN></C> <C>Enable to include folders (default is false)</C> </R>
|
|
</TABLE>
|
|
|
|
Notes:
|
|
- Does NOT clear existing content. Use <A TImageEnMView.Clear> first to replace existing content
|
|
- More functionality for the display of thumbnails of file folders is available with <A TImageEnFolderMView>.
|
|
|
|
<FM>Demo<FN>
|
|
<TABLE2>
|
|
<R> <C_IMG_DEMO> <C>Demos\Multi\Thumbnails\Thumbnails.dpr </C> </R>
|
|
</TABLE>
|
|
|
|
<FM>Example<FC>
|
|
ImageEnMView1.Clear;
|
|
ImageEnMView1.StoreType := ietFastThumb;
|
|
ImageEnMView1.FillFromDirectory('C:\images');
|
|
!!}
|
|
procedure TImageEnMView.FillFromDirectory(const Directory: WideString; Limit : integer = -1; AllowUnknownFormats : boolean = false; const ExcludeExtensions : WideString = '';
|
|
DetectFileFormat : boolean = false; const FilterMask : WideString = ''; IncludeVideoFiles : Boolean = False;
|
|
LoadOnDemand : boolean = true;
|
|
DefaultTopText : TIEImageEnMViewDefaultText = iedtNone;
|
|
DefaultInfoText : TIEImageEnMViewDefaultText = iedtNone;
|
|
DefaultBottomText : TIEImageEnMViewDefaultText = iedtFilename;
|
|
bShowHiddenFiles : Boolean = False;
|
|
bShowFolders : Boolean = False);
|
|
var
|
|
l, idx: Integer;
|
|
fpath, fname: WideString;
|
|
iAdded: Integer;
|
|
sep: WideString;
|
|
excList: TStringList;
|
|
mskList: TStringList;
|
|
dir: TIEDirContent;
|
|
ext: WideString;
|
|
lAnimation: TIEAnimation;
|
|
bInclude: Boolean;
|
|
bAllowAddition: Boolean;
|
|
iTotal: Integer;
|
|
iRead: Integer;
|
|
begin
|
|
lAnimation := Animation;
|
|
fAnimation := nil;
|
|
LockPaint();
|
|
dir := nil;
|
|
excList := TStringList.Create;
|
|
mskList := TStringList.Create;
|
|
MIO.Aborting := False;
|
|
try
|
|
excList.CommaText := LowerCase( ExcludeExtensions );
|
|
mskList.CommaText := LowerCase( FilterMask );
|
|
l := length( Directory );
|
|
if ( l = 0 ) or ( Directory[ l ] = '\' ) then
|
|
sep := ''
|
|
else
|
|
sep := '\';
|
|
|
|
// NEED FILE COUNT FOR PROGRESS??? (Only useful when not loading on demand)
|
|
iTotal := 0;
|
|
if ( LoadOnDemand = False ) and assigned( fOnProgress ) then
|
|
begin
|
|
dir := TIEDirContent.Create( Directory + sep + '*.*' );
|
|
while dir.GetItem( fname, True, bShowFolders, bShowHiddenFiles ) do
|
|
begin
|
|
Inc( iTotal );
|
|
if (Limit > -1) and ( iTotal = Limit ) then
|
|
break;
|
|
end;
|
|
dir.Free;
|
|
end;
|
|
|
|
iAdded := 0;
|
|
iRead := 0;
|
|
dir := TIEDirContent.Create( Directory + sep + '*.*' );
|
|
while dir.GetItem( fname, True, bShowFolders, bShowHiddenFiles ) do
|
|
begin
|
|
if ( LoadOnDemand = False ) and assigned( fOnProgress ) then
|
|
fOnProgress( Self, MulDiv( iRead, 100, iTotal ));
|
|
Inc( iRead );
|
|
|
|
fpath := Directory + sep + fname;
|
|
ext := IEExtractFileExtW( fname, false );
|
|
if dir.IsFolder then
|
|
bInclude := True
|
|
else
|
|
bInclude := ( AllowUnknownFormats or ( DetectFileFormat and ( FindFileFormat( fpath, ffContentOnly ) <> ioUnknown )) or IsKnownFormat( fpath, IncludeVideoFiles )) and
|
|
( excList.IndexOf( ext ) = -1) and
|
|
(( mskList.Count = 0 ) or ( mskList.IndexOf( ext ) > -1 ));
|
|
|
|
if bInclude then
|
|
begin
|
|
if ( Limit > -1 ) and ( iAdded = Limit ) then
|
|
break
|
|
else
|
|
if MIO.Aborting then
|
|
break;
|
|
|
|
bAllowAddition := True;
|
|
if assigned( fOnImageAdd ) then
|
|
fOnImageAdd( self,
|
|
fIEMBitmap.Count,
|
|
fpath,
|
|
dir.IsFolder,
|
|
dir.IsHiddenFile,
|
|
dir.FileSizeBytes,
|
|
dir.CreateDate,
|
|
dir.EditDate,
|
|
bAllowAddition );
|
|
|
|
if bAllowAddition then
|
|
begin
|
|
idx := AppendImage( fpath, LoadOnDemand, DefaultTopText, DefaultInfoText, DefaultBottomText, False );
|
|
|
|
ImageFileSize[idx] := dir.FileSizeBytes;
|
|
ImageCreateDate[idx] := dir.CreateDate;
|
|
ImageEditDate[idx] := dir.EditDate;
|
|
If dir.IsFolder then
|
|
fIEMBitmap.GetImageInfo( idx ).SourceType := iestFolderIcon;
|
|
|
|
inc(iAdded);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{$ifdef IEIncludeDeprecatedInV5}
|
|
// Legacy support: select last added item
|
|
SetSelectedItemNU( fIEMBitmap.Count - 1 );
|
|
{$endif}
|
|
finally
|
|
dir.Free;
|
|
mskList.Free;
|
|
excList.Free;
|
|
fAnimation := lAnimation;
|
|
UnLockPaint();
|
|
Update;
|
|
end;
|
|
fCurrentOrderBy := iesbFilename;
|
|
fCurrentAscending := True;
|
|
|
|
if ( LoadOnDemand = False ) and assigned( fOnFinishWork ) then
|
|
fOnFinishWork( Self );
|
|
end;
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.EnsureImageLoaded
|
|
|
|
<FM>Declaration<FC>
|
|
procedure TImageEnMView.EnsureImageLoaded(idx: integer);
|
|
|
|
<FM>Description<FN>
|
|
If the content of the TImageEnMView is being loaded on demand (e.g. because you are using <A TImageEnMView.LoadFromFileOnDemand>) then the image properties such as <A TImageEnMView.ImageWidth> and <A TImageEnMView.ImageHeight>, and <L TImageEnMIO.Params>I/O parameters</L> will not be valid until the image has loaded. Calling <FC>EnsureImageLoaded<FN> will force an image to be loaded so you can access its properties.
|
|
Naturally calling <FC>EnsureImageLoaded<FN> too often (e.g. for all images) would defeat the purpose of loading on demand and affect performance.
|
|
|
|
<FM>Example<FC>
|
|
// Get the dimensions of the selected image
|
|
if ImageEnMView1.SelectedImage >= 0 then
|
|
begin
|
|
ImageEnMView1.EnsureImageLoaded( ImageEnMView1.SelectedImage );
|
|
StatusBar.Text [ 0 ] := ImageEnMView1.ImageWidth[ ImageEnMView1.SelectedImage ] + ' x ' + ImageEnMView1.ImageHeight[ ImageEnMView1.SelectedImage ];
|
|
end;
|
|
|
|
// Read the Photoshop description of the selected image
|
|
if ImageEnMView1.SelectedImage >= 0 then
|
|
begin
|
|
ImageEnMView1.EnsureImageLoaded( ImageEnMView1.SelectedImage );
|
|
StatusBar.Text [ 1 ] := ImageEnMView1.MIO.Params[ ImageEnMView1.SelectedImage ].ReadIPTCField(PhotoShop_IPTC_Records, IPTC_PS_Caption);
|
|
end;
|
|
!!}
|
|
procedure TImageEnMView.EnsureImageLoaded(idx: integer);
|
|
begin
|
|
fThreadCS.Enter();
|
|
try
|
|
if fIEMBitmap.GetImageInfo( idx ).image = nil then
|
|
ObtainImageNow(idx);
|
|
finally
|
|
fThreadCS.Leave();
|
|
end;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.MoveImage
|
|
|
|
<FM>Declaration<FC>
|
|
procedure MoveImage(idx: Integer; destination: Integer);
|
|
|
|
<FM>Description<FN>
|
|
Moves an image from the index position <FC>idx<FN> to the <FC>destination<FN> position.
|
|
|
|
If the destination index is greater than or equal to the image count, the image is moved to the position after the last image.
|
|
|
|
Notes:
|
|
- If you have images of the order ABCD, then calling MoveImage(0, 2) would change it to BCAD
|
|
- Cannot be used if a <A TIEDBMultiBitmap> is <L TImageEnMView.SetExternalMBitmap>attached to the control</L>
|
|
|
|
<FM>Example<FC>
|
|
// Exchange first and second images
|
|
ImageEnMView1.MoveImage(0, 1);
|
|
|
|
// Move first image to the end of the grid
|
|
ImageEnMView1.MoveImage(0, ImageEnMView1.ImageCount);
|
|
|
|
!!}
|
|
// move image idx to destination index
|
|
procedure TImageEnMView.MoveImage(idx: integer; destination: integer);
|
|
var
|
|
psel: integer;
|
|
mm: TList;
|
|
i, p: Integer;
|
|
begin
|
|
if IEMBitmap_IsTIEDBMultiBitmap then
|
|
raise EIEException.create('Not available when attached to TIEDBMultiBitmap');
|
|
|
|
if (idx >= 0) and (idx < fIEMBitmap.Count) and (destination >= 0) and (destination <> idx) then
|
|
begin
|
|
SetPlaying(false);
|
|
|
|
psel := fSelectedItem;
|
|
mm := TList.Create;
|
|
|
|
try
|
|
for i := 0 to fMultiSelectedImages.Count-1 do
|
|
begin
|
|
p := integer( fMultiSelectedImages[i] );
|
|
if p = idx then
|
|
p := destination
|
|
else
|
|
begin
|
|
if p > idx then dec(p);
|
|
if p >= destination then inc(p);
|
|
end;
|
|
mm.Add( pointer(p) );
|
|
end;
|
|
|
|
TIEMultiBitmap( fIEMBitmap ).MoveImage( idx, destination );
|
|
CallBitmapChangeEvents;
|
|
|
|
if (mm.Count > 0) and ((idx = psel) or (fMultiSelectedImages.Count > 0)) then
|
|
begin
|
|
fSelectedItem := integer(mm[0]);
|
|
fIEMBitmap.SetActiveImage( fSelectedItem );
|
|
for i := 0 to fMultiSelectedImages.Count-1 do
|
|
fMultiSelectedImages[i] := mm[i];
|
|
end
|
|
else
|
|
begin
|
|
DeselectNU;
|
|
SetSelectedItemNU(psel);
|
|
end;
|
|
|
|
UpdateEx(false);
|
|
|
|
finally
|
|
mm.free;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.MoveSelectedImagesTo
|
|
|
|
<FM>Declaration<FC>
|
|
procedure MoveSelectedImagesTo(beforeImage: Integer; bUseDisplayOrder: Boolean = true);
|
|
|
|
<FM>Description<FN>
|
|
Moves all selected images to the postion prior to <FC>beforeImage<FN>.
|
|
|
|
To move images after last image set <FC>beforeImage<FN> to <A TImageEnMView.ImageCount>.
|
|
|
|
if bUseDisplayOrder is true, then <A TImageEnMView.MultiSelectSortList> will be called so that multiple selected files will be inserted in their new position in the order they are displayed. When false, they are inserted in the order that they were selected.
|
|
|
|
<FM>Example<FC>
|
|
// Move all selected images to the start of the grid
|
|
ImageEnMView1.MoveSelectedImagesTo(0);
|
|
|
|
// Move all selected images to the end of the grid
|
|
ImageEnMView1.MoveSelectedImagesTo(ImageEnMView1.ImageCount);
|
|
!!}
|
|
// beforeImage can be 0 up to imagecount
|
|
procedure TImageEnMView.MoveSelectedImagesTo(beforeImage: Integer; bUseDisplayOrder: Boolean = true);
|
|
var
|
|
mm: array of TIEImageInfo;
|
|
i: Integer;
|
|
sn: Boolean;
|
|
ImGroup: TIEArrayOfInteger;
|
|
begin
|
|
if (beforeImage < 0) or (beforeImage > fIEMBitmap.Count) then
|
|
exit;
|
|
|
|
SetPlaying(false);
|
|
|
|
if bUseDisplayOrder then
|
|
MultiSelectSortList;
|
|
|
|
sn := (fSelectedItem > -1) and (fMultiSelectedImages.Count = 0);
|
|
if sn then
|
|
fMultiSelectedImages.Add(pointer(fSelectedItem));
|
|
|
|
SetLength( ImGroup, fMultiSelectedImages.Count );
|
|
for i := 0 to fMultiSelectedImages.Count - 1 do
|
|
ImGroup[i] := MultiSelectedImages[i];
|
|
SetLastImOp( IEM_OP_MOVEGROUP, fSelectedItem, beforeImage, ImGroup);
|
|
|
|
SetLength(mm, fIEMBitmap.Count);
|
|
for i := 0 to fIEMBitmap.Count - 1 do
|
|
mm[i] := fIEMBitmap.fImageInfo[ i ];
|
|
|
|
for i := 0 to fMultiSelectedImages.Count - 1 do
|
|
begin
|
|
fIEMBitmap.fImageInfo[ fIEMBitmap.fImageInfo.IndexOf( mm[MultiSelectedImages[i]] ) ] := nil; // mark as to remove
|
|
fIEMBitmap.fImageInfo.Insert( beforeImage, mm[MultiSelectedImages[i]] );
|
|
inc(beforeImage);
|
|
end;
|
|
for i := fIEMBitmap.Count - 1 downto 0 do
|
|
if fIEMBitmap.fImageInfo[ i ] = nil then
|
|
fIEMBitmap.fImageInfo.Delete( i );
|
|
for i := 0 to fMultiSelectedImages.Count - 1 do
|
|
fMultiSelectedImages[i] := pointer(fIEMBitmap.fImageInfo.IndexOf( mm[MultiSelectedImages[i]] ));
|
|
|
|
CallBitmapChangeEvents;
|
|
|
|
fSelectedItem := MultiSelectedImages[0];
|
|
fIEMBitmap.SetActiveImage( fSelectedItem );
|
|
|
|
if sn then
|
|
fMultiSelectedImages.Clear;
|
|
|
|
UpdateEx(false);
|
|
end;
|
|
|
|
// no image must be selected
|
|
// doesn't restore selected image
|
|
// doesn't update
|
|
procedure TImageEnMView.SwapImages(idx1, idx2: Integer);
|
|
begin
|
|
if IEMBitmap_IsTIEDBMultiBitmap then
|
|
raise EIEException.create('Not available when attached to TIEDBMultiBitmap');
|
|
|
|
TIEMultiBitmap( fIEMBitmap ).SwapImages( idx1, idx2 );
|
|
CallBitmapChangeEvents;
|
|
end;
|
|
|
|
function TImageEnMView.SortCompareFunction(index1, index2: Integer): Integer;
|
|
begin
|
|
if assigned(fCurrentCompare) then
|
|
result := fCurrentCompare(index1, index2)
|
|
else
|
|
result := fCurrentCompareEx(index1, index2)
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.Sort
|
|
|
|
<FM>Declaration<FC>
|
|
procedure Sort(Compare: <A TIEImageEnMViewSortCompare>);
|
|
procedure Sort(Compare: <A TIEImageEnMViewSortCompareEx>);
|
|
procedure Sort(OrderBy: <A TIEImageEnMViewSortBy>; Ascending: boolean = true; CaseSensitive: boolean = true);
|
|
|
|
<FM>Description<FN>
|
|
Sorts all images in the TImageEnMView by property (filename, dimensions, etc) or using a custom comparison function.
|
|
|
|
<FM>Example 1<FC>
|
|
// sort by filename
|
|
ImageEnMView1.Sort( iesbFilename );
|
|
|
|
<FM>Example 2<FC>
|
|
// sort by filename even if files come from different folders
|
|
ImageEnMView1.Sort( iesbFilenameWithoutPath );
|
|
|
|
<FM>Example 3<FC>
|
|
// custom sort function (by DPI)
|
|
function XCompareDPI(i1, i2: Integer): Integer;
|
|
var
|
|
s1, s2: Integer;
|
|
begin
|
|
s1 := Form1.ImageEnMView1.Params[i1].DPI;
|
|
s2 := Form1.ImageEnMView1.Params[i2].DPI;
|
|
|
|
if s1 < s2 then
|
|
result := -1
|
|
else
|
|
if s1 > s2 then
|
|
result := 1
|
|
else
|
|
result := 0;
|
|
end;
|
|
|
|
// Sort By DPI
|
|
procedure TForm1.Button1Click(Sender: TObject);
|
|
begin
|
|
ImageEnMView1.Sort( XCompareDPI );
|
|
end;
|
|
|
|
!!}
|
|
procedure TImageEnMView.Sort(Compare: TIEImageEnMViewSortCompare);
|
|
begin
|
|
Sort2(Compare, nil);
|
|
fCurrentOrderBy := iesbCustom;
|
|
fCurrentAscending := True;
|
|
end;
|
|
|
|
procedure TImageEnMView.Sort(Compare: TIEImageEnMViewSortCompareEx);
|
|
begin
|
|
Sort2(nil, Compare);
|
|
fCurrentOrderBy := iesbCustom;
|
|
fCurrentAscending := True;
|
|
end;
|
|
|
|
function TImageEnMView.SortCompareBy(index1, index2: Integer): Integer;
|
|
|
|
function _DoCompareStr(const S1, S2: string): Integer;
|
|
begin
|
|
if fCurrentCaseSensitive then
|
|
Result := CompareStr(s1, s2)
|
|
else
|
|
Result := CompareText(s1, s2)
|
|
end;
|
|
|
|
function _GetText(const ws : WideString; idx : Integer; DefaultText : TIEImageEnMViewDefaultText):string;
|
|
begin
|
|
Result := ReplaceIEMConst( ws, idx );
|
|
if Result = '' then
|
|
Result := ReplaceIEMConst( DefaultText, idx );
|
|
end;
|
|
|
|
var
|
|
s1, s2 : integer;
|
|
u1, u2 : Int64;
|
|
d1, d2 : TDateTime;
|
|
bIndex1IsFolder, bIndex2IsFolder : Boolean;
|
|
begin
|
|
bIndex1IsFolder := fIEMBitmap.GetImageInfo( index1 ).SourceType = iestFolderIcon;
|
|
bIndex2IsFolder := fIEMBitmap.GetImageInfo( index2 ).SourceType = iestFolderIcon;
|
|
|
|
// Folders always appear before files
|
|
if bIndex1IsFolder <> bIndex2IsFolder then
|
|
begin
|
|
if bIndex1IsFolder then
|
|
Result := -1
|
|
else
|
|
Result := 1;
|
|
end
|
|
else
|
|
// Both files are folders, sort by name, if the sort type is not supported
|
|
if bIndex1IsFolder and (fCurrentOrderBy in [iesbFilename, iesbImageSize, iesbFilenameWithoutPath, iesbFileExtension, iesbFileSize, iesbFileType]) then
|
|
begin
|
|
if SameText( ImageFileName[index1], IEF_Drives_Folder ) then
|
|
Result := -1
|
|
else
|
|
if SameText( ImageFileName[index2], IEF_Drives_Folder ) then
|
|
Result := 1
|
|
else
|
|
result := _DoCompareStr(ImageFileName[index1], ImageFileName[index2]);
|
|
end
|
|
else
|
|
begin
|
|
// Normal sorting
|
|
case fCurrentOrderBy of
|
|
iesbFilename:
|
|
result := _DoCompareStr(ImageFileName[index1], ImageFileName[index2]);
|
|
iesbTopText:
|
|
result := _DoCompareStr( _GetText( ImageTopText[index1], index1, fDefaultTopText ), _GetText( ImageTopText[index2], index2, fDefaultTopText ));
|
|
iesbBottomText:
|
|
result := _DoCompareStr( _GetText( ImageBottomText[index1], index1, fDefaultBottomText ), _GetText(ImageBottomText[index2], index2, fDefaultBottomText ));
|
|
iesbInfoText:
|
|
result := _DoCompareStr( _GetText( ImageInfoText[index1], index1, fDefaultInfoText ), _GetText( ImageInfoText[index2], index2, fDefaultInfoText ));
|
|
iesbImageSize:
|
|
begin
|
|
s1 := ImageOriginalWidth[index1] * ImageOriginalHeight[index1];
|
|
s2 := ImageOriginalWidth[index2] * ImageOriginalHeight[index2];
|
|
if s1 < s2 then
|
|
result := -1
|
|
else
|
|
if s1 > s2 then
|
|
result := 1
|
|
else
|
|
result := 0;
|
|
end;
|
|
iesbFilenameWithoutPath:
|
|
result := _DoCompareStr(ExtractFilename(ImageFileName[index1]), ExtractFilename(ImageFileName[index2]));
|
|
iesbFileExtension:
|
|
result := CompareText(ExtractFileExt(ImageFileName[index1]), ExtractFileExt(ImageFileName[index2]));
|
|
iesbFileSize :
|
|
begin
|
|
u1 := ImageFileSize[index1];
|
|
u2 := ImageFileSize[index2];
|
|
if u1 < u2 then
|
|
result := -1
|
|
else
|
|
if u1 > u2 then
|
|
result := 1
|
|
else
|
|
result := 0;
|
|
end;
|
|
iesbCreateDate :
|
|
begin
|
|
d1 := ImageCreateDate[index1];
|
|
d2 := ImageCreateDate[index2];
|
|
if d1 < d2 then
|
|
result := -1
|
|
else
|
|
if d1 > d2 then
|
|
result := 1
|
|
else
|
|
result := 0;
|
|
end;
|
|
iesbEditDate :
|
|
begin
|
|
d1 := ImageEditDate[index1];
|
|
d2 := ImageEditDate[index2];
|
|
if d1 < d2 then
|
|
result := -1
|
|
else
|
|
if d1 > d2 then
|
|
result := 1
|
|
else
|
|
result := 0;
|
|
end;
|
|
iesbFileType :
|
|
result := CompareText(fFileTypeList[fIEMBitmap.GetImageInfo( index1 ).FileTypeIndex], fFileTypeList[fIEMBitmap.GetImageInfo( index2 ).FileTypeIndex]);
|
|
else
|
|
result := 0; // impossible
|
|
end;
|
|
|
|
// if files are identical then sort by name
|
|
if (Result = 0) and (fCurrentOrderBy in [iesbImageSize, iesbFileExtension, iesbFileSize, iesbCreateDate, iesbEditDate, iesbFileType]) then
|
|
Result := _DoCompareStr(ImageFileName[index1], ImageFileName[index2]);
|
|
end;
|
|
|
|
if not fCurrentAscending then
|
|
result := -result;
|
|
end;
|
|
|
|
procedure TImageEnMView.Sort(OrderBy: TIEImageEnMViewSortBy; Ascending: boolean = true; CaseSensitive: boolean = true);
|
|
var
|
|
I: Integer;
|
|
sFileType: string;
|
|
begin
|
|
if OrderBy = iesbFileType then
|
|
begin
|
|
fFileTypeList := TStringList.create;
|
|
for I := 0 to ImageCount - 1 do
|
|
begin
|
|
sFileType := GetImageFileType(I);
|
|
fFileTypeList.Add(sFileType);
|
|
fIEMBitmap.GetImageInfo( I ).FileTypeIndex := fFileTypeList.Count - 1;
|
|
end;
|
|
end;
|
|
|
|
fCurrentOrderBy := OrderBy;
|
|
fCurrentAscending := Ascending;
|
|
fCurrentCaseSensitive := CaseSensitive;
|
|
if (OrderBy <> iesbNone) and (OrderBy <> iesbCustom) then
|
|
Sort2(nil, SortCompareBy);
|
|
|
|
if OrderBy = iesbFileType then
|
|
FreeAndNil(fFileTypeList);
|
|
end;
|
|
|
|
procedure TImageEnMView.Sort2(Compare: TIEImageEnMViewSortCompare; CompareEx: TIEImageEnMViewSortCompareEx);
|
|
var
|
|
psel: integer;
|
|
begin
|
|
if fIEMBitmap.Count > 0 then
|
|
begin
|
|
SetPlaying(false);
|
|
psel := fSelectedItem;
|
|
DeselectNU;
|
|
fCurrentCompare := Compare;
|
|
fCurrentCompareEx := CompareEx;
|
|
try
|
|
fThreadCS.Enter();
|
|
IEQuickSort(fIEMBitmap.Count, SortCompareFunction, SwapImages);
|
|
finally
|
|
fThreadCS.Leave();
|
|
end;
|
|
SetSelectedItemNU(psel);
|
|
UpdateEx(false);
|
|
end;
|
|
end;
|
|
|
|
procedure TImageEnMView.DoImageSelect(idx: integer);
|
|
begin
|
|
if assigned(fOnImageSelect) and fUserAction then
|
|
fOnImageSelect(self, idx);
|
|
end;
|
|
|
|
procedure TImageEnMView.DoImageDeselect(idx: integer);
|
|
begin
|
|
if not fDestroying and assigned(fOnImageDeselect) and fUserAction then
|
|
fOnImageDeselect(self, idx);
|
|
end;
|
|
|
|
|
|
{$ifdef IEINCLUDEFLATSB}
|
|
{!!
|
|
<FS>TImageEnMView.FlatScrollBars
|
|
|
|
<FM>Declaration<FC>
|
|
property FlatScrollBars: Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Specifies whether the component's scrollbars are flat.
|
|
!!}
|
|
procedure TImageEnMView.SetFlatScrollBars(Value: Boolean);
|
|
begin
|
|
if Value<>fFlatScrollBars then
|
|
begin
|
|
fFlatScrollBars := Value;
|
|
if fFlatScrollBars then
|
|
begin
|
|
// Why calls to IESetScrollRange? Please ask Microsoft's programmers!
|
|
IESetScrollRange(Handle, SB_HORZ, 0, 65535, false, false);
|
|
IESetScrollRange(Handle, SB_VERT, 0, 65535, false, false);
|
|
InitializeFlatSB(Handle);
|
|
IEShowScrollBar(handle, SB_HORZ, false, true);
|
|
IEShowScrollBar(handle, SB_VERT, false, true);
|
|
end
|
|
else
|
|
UninitializeFlatSB(Handle);
|
|
end;
|
|
end;
|
|
{$endif}
|
|
|
|
{!!
|
|
<FS>TImageEnMView.SetPresetThumbnailFrame
|
|
|
|
<FM>Declaration<FC>
|
|
procedure SetPresetThumbnailFrame(PresetIndex: Integer; UnselectedColor: TColor; SelectedColor: TColor);
|
|
|
|
<FM>Description<FN>
|
|
Applies a background style to the thumbnails from an internal set
|
|
|
|
<TABLE>
|
|
<R> <H>Value</H> <H>Description</H> </R>
|
|
<R> <C>PresetIndex</C> <C>The style to use (-1: No custom style, 0: Photo, 1: Film, 2: Album, 3: Picture Frame)</C> </R>
|
|
<R> <C>UnselectedColor</C> <C>Color modification when frame is unselected</C> </R>
|
|
<R> <C>SelectedColor</C> <C>Color modification when frame is selected</C> </R>
|
|
</TABLE>
|
|
|
|
<FM>Examples<FC>
|
|
ImageEnMView1.SetPresetThumbnailFrame(0, clWhite, clGreen);
|
|
<IMG help_images\75.jpg>
|
|
|
|
ImageEnMView1.SetPresetThumbnailFrame(2, clWhite, clGreen);
|
|
<IMG help_images\76.jpg>
|
|
|
|
// Clear custom thumbs
|
|
ImageEnMView1.SetPresetThumbnailFrame(-1, clWhite, clWhite);
|
|
|
|
<FM>See demo<FN>
|
|
Multi\Thumbnails2
|
|
|
|
!!}
|
|
procedure TImageEnMView.SetPresetThumbnailFrame(PresetIndex: Integer; UnselectedColor: TColor; SelectedColor: TColor);
|
|
var
|
|
io: TImageEnIO;
|
|
proc: TImageEnProc;
|
|
rgb: TRGB;
|
|
begin
|
|
if assigned(fThumbnailFrame) then
|
|
FreeAndNil(fThumbnailFrame);
|
|
if assigned(fThumbnailFrameSelected) then
|
|
FreeAndNil(fThumbnailFrameSelected);
|
|
|
|
if (PresetIndex >= 0) and (PresetIndex < iegPresetImages.Count) then
|
|
begin
|
|
EnableAlphaChannel := true;
|
|
FillThumbnail := false;
|
|
SelectionWidth := 0;
|
|
ShowText := false;
|
|
Style := iemsFlat;
|
|
DrawImageBackground := false;
|
|
|
|
fThumbnailFrame := TIEBitmap.Create;
|
|
fThumbnailFrameSelected := TIEBitmap.Create;
|
|
|
|
io := TImageEnIO.CreateFromBitmap(fThumbnailFrame);
|
|
try
|
|
with TIEPresetImage(iegPresetImages[PresetIndex]) do
|
|
begin
|
|
io.LoadFromBuffer( Data, Size, FileFormat );
|
|
fThumbnailFrameRect := ThumbRect;
|
|
end;
|
|
finally
|
|
FreeAndNil(io);
|
|
end;
|
|
|
|
fThumbnailFrameSelected.Assign( fThumbnailFrame );
|
|
|
|
proc := TImageEnProc.CreateFromBitmap(fThumbnailFrameSelected);
|
|
|
|
// set selected color
|
|
rgb := TColor2TRGB(SelectedColor);
|
|
proc.IntensityRGBall(rgb.r-255, rgb.g-255, rgb.b-255);
|
|
|
|
// set unselected color
|
|
proc.AttachedIEBitmap := fThumbnailFrame;
|
|
rgb := TColor2TRGB(UnselectedColor);
|
|
proc.IntensityRGBall(rgb.r-255, rgb.g-255, rgb.b-255);
|
|
|
|
FreeAndNil(proc);
|
|
|
|
ThumbWidth := fThumbnailFrame.Width;
|
|
ThumbHeight := fThumbnailFrame.Height;
|
|
|
|
Update;
|
|
end;
|
|
end;
|
|
|
|
{$ifdef IEDOTNETVERSION}
|
|
procedure TImageEnMView.WMContextMenu(var Message: TWMContextMenu);
|
|
begin
|
|
// just to remove Delphi default behavior
|
|
end;
|
|
{$endif}
|
|
|
|
{!!
|
|
<FS>TImageEnMView.IEBeginDrag
|
|
|
|
<FM>Declaration<FC>
|
|
procedure IEBeginDrag(Immediate: Boolean; Threshold: Integer = -1);
|
|
|
|
<FM>Description<FN>
|
|
ImageEn's implementation of BeginDrag. You must use this for Drag/Drop operations in TImageEnMView
|
|
|
|
<FM>Demos<FN>
|
|
<TABLE2>
|
|
<R> <C_IMG_DEMO> <C>Demos\DragDrop\TImageEnMView_DragDrop\TImageEnMView_DragDrop.dpr </C> </R>
|
|
<R> <C_IMG_DEMO> <C>Demos\Multi\Multiview2\Multiview2.dpr </C> </R>
|
|
</TABLE>
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.IEEndDrag>
|
|
- <L TImageEnMView.MultiSelectionOptions>iemoOptimizeForDragging</L>
|
|
|
|
!!}
|
|
procedure TImageEnMView.IEBeginDrag(Immediate: Boolean; Threshold: Integer);
|
|
begin
|
|
// Why this? Because BeginDrag calls MouseUp, but "Dragging" of VCL is still not True and MouseUp must know we are dragging
|
|
fDragging := true;
|
|
BeginDrag(immediate, Threshold);
|
|
fDragging := Dragging; // get the official dragging value
|
|
InitializeDragScrollTimer;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.IEEndDrag
|
|
|
|
<FM>Declaration<FC>
|
|
procedure IEEndDrag;
|
|
|
|
<FM>Description<FN>
|
|
ImageEn's implementation of EndDrag. You must use this for Drag/Drop operations in TImageEnMView
|
|
|
|
<FM>Demos<FN>
|
|
<TABLE2>
|
|
<R> <C_IMG_DEMO> <C>Demos\DragDrop\TImageEnMView_DragDrop\TImageEnMView_DragDrop.dpr </C> </R>
|
|
<R> <C_IMG_DEMO> <C>Demos\Multi\Multiview2\Multiview2.dpr </C> </R>
|
|
</TABLE>
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.IEBeginDrag>
|
|
!!}
|
|
procedure TImageEnMView.IEEndDrag;
|
|
begin
|
|
EndDrag(true);
|
|
fDragging := false;
|
|
TerminateDragScrollTimer;
|
|
end;
|
|
|
|
|
|
// Handle automatic scrolling when we drag to the edges
|
|
procedure TImageEnMView.InitializeDragScrollTimer;
|
|
begin
|
|
{$ifndef DISABLE_AUTO_SCROLL_WHEN_DRAG}
|
|
if assigned(fDragScrollTimer) = False then
|
|
fDragScrollTimer := TTimer.create(Self);
|
|
fDragScrollCount := 0;
|
|
fDragScrollTimer.Interval := 250;
|
|
fDragScrollTimer.Enabled := True;
|
|
fDragScrollTimer.OnTimer := DragScrollTimer;
|
|
{$endif}
|
|
end;
|
|
|
|
// End automatic scrolling when dragging completes
|
|
procedure TImageEnMView.TerminateDragScrollTimer;
|
|
begin
|
|
if assigned(fDragScrollTimer) then
|
|
fDragScrollTimer.Enabled := False;
|
|
end;
|
|
|
|
// Handle automatic scrolling when we drag to the edges
|
|
procedure TImageEnMView.DragScrollTimer(Sender: TObject);
|
|
const
|
|
Scrollable_Area = 30;
|
|
Max_Speed_Up_Dragging_Pos = 50;
|
|
var
|
|
Pos: TPoint;
|
|
iLineStep: Integer;
|
|
bHaveScrolled: Boolean;
|
|
bHaveVertScrolling: Boolean;
|
|
bHaveHorzScrolling: Boolean;
|
|
iScrollBarHeight: Integer;
|
|
begin
|
|
// Are we still dragging? Dragging may have terminated without the user calling IEEndDrag
|
|
if Dragging = False then
|
|
begin
|
|
TerminateDragScrollTimer;
|
|
exit;
|
|
end;
|
|
|
|
GetCursorPos(Pos);
|
|
Pos := ScreenToClient(Pos);
|
|
|
|
// Still over the control?
|
|
if (Pos.X < 0) or (Pos.X > Width) or
|
|
(Pos.Y < 0) or (Pos.Y > Height) then
|
|
exit;
|
|
|
|
bHaveScrolled := False;
|
|
bHaveVertScrolling := (fCurrentGridWidth <> 0) and (fVHeight > ClientHeight);
|
|
bHaveHorzScrolling := (fCurrentGridWidth <> -1) and (fVWidth > ClientWidth);
|
|
|
|
// Vertical scrolling
|
|
if bHaveVertScrolling and (Pos.X > 0) and (Pos.X < Width) then
|
|
begin
|
|
if fVScrollBarParams.LineStep = -1 then
|
|
iLineStep := ThumbSizeInfo( itsCell ).Y - fVertBorder
|
|
else
|
|
iLineStep := fVScrollBarParams.LineStep;
|
|
|
|
// Is there a horizontal scrollbar?
|
|
iScrollBarHeight := 0;
|
|
if ((fScrollBars = ssHorizontal) or (fScrollBars = ssBoth)) and (fVWidth > ClientWidth) then
|
|
iScrollBarHeight := IEGlobalSettings().HScrollHeight;
|
|
|
|
if Pos.Y < Scrollable_Area then
|
|
begin
|
|
SetViewY(fViewY - iLineStep);
|
|
bHaveScrolled := True;
|
|
end
|
|
else
|
|
if Pos.Y > Height - Scrollable_Area - iScrollBarHeight then
|
|
begin
|
|
SetViewY(fViewY + iLineStep);
|
|
bHaveScrolled := True;
|
|
end;
|
|
end
|
|
else
|
|
// Horizontal scrolling
|
|
if bHaveHorzScrolling and (Pos.Y > 0) and (Pos.Y < Height) then
|
|
begin
|
|
if fHScrollBarParams.LineStep = -1 then
|
|
iLineStep := ThumbSizeInfo( itsCell ).X - fHorizBorder
|
|
else
|
|
iLineStep := fHScrollBarParams.LineStep;
|
|
|
|
if Pos.X < Scrollable_Area then
|
|
begin
|
|
SetViewX(fViewX - iLineStep);
|
|
bHaveScrolled := True;
|
|
end
|
|
else
|
|
if Pos.X > Width - Scrollable_Area then
|
|
begin
|
|
SetViewX(fViewX + iLineStep);
|
|
bHaveScrolled := True;
|
|
end;
|
|
end;
|
|
|
|
if bHaveScrolled then
|
|
begin
|
|
ViewChange(0);
|
|
if fDragScrollCount < Max_Speed_Up_Dragging_Pos then
|
|
begin
|
|
inc(fDragScrollCount);
|
|
if fDragScrollCount mod 5 = 0 then
|
|
fDragScrollTimer.Interval := MulDiv(fDragScrollTimer.Interval, 3, 4); // speed up the scrolling by reducing the timer interval
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
InitializeDragScrollTimer;
|
|
exit;
|
|
end;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.JobsRunning
|
|
|
|
<FM>Declaration<FC>
|
|
property JobsRunning: Integer;
|
|
|
|
<FM>Description<FN>
|
|
Returns the number of active threads which are loading thumbnails.
|
|
|
|
<FM>Demo<FN>
|
|
<TABLE2>
|
|
<R> <C_IMG_DEMO> <C>Demos\Multi\Thumbnails\Thumbnails.dpr </C> </R>
|
|
</TABLE>
|
|
|
|
!!}
|
|
function TImageEnMView.GetJobsRunning: Integer;
|
|
begin
|
|
result := fThreadPoolIO.Count;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.JobsWaiting
|
|
|
|
<FM>Declaration<FC>
|
|
property JobsWaiting: Integer;
|
|
|
|
<FM>Description<FN>
|
|
Returns the number of images/thumbnails waiting to be loaded.
|
|
|
|
<FM>Demo<FN>
|
|
<TABLE2>
|
|
<R> <C_IMG_DEMO> <C>Demos\Multi\Thumbnails\Thumbnails.dpr </C> </R>
|
|
</TABLE>
|
|
|
|
!!}
|
|
function TImageEnMView.GetJobsWaiting: Integer;
|
|
begin
|
|
result := fThreadRequests.Count;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.LoadFromFileOnDemand
|
|
|
|
<FM>Declaration<FC>
|
|
procedure LoadFromFileOnDemand(const FileName: WideString; Append: Boolean = false);
|
|
|
|
<FM>Description<FN>
|
|
Fills TImageEnMView with all frames of a multiple image file (AVI, MPEG, TIFF, etc.) by filling <A TImageEnMView.ImageFileName> with filenames and all indexes of its frames (in the format 'FileName::0', 'FileName::1', etc.).
|
|
|
|
In this way loading of individual frames will be delayed until they are required (i.e. frames are only loaded when they appear on-screen). It is mainly used for loading the frames of files with numerous frames (such as videos).
|
|
|
|
When Append is false, the existing content of the TImageEnMView is cleared.
|
|
|
|
Note: You can set TImageEnMView.MIO.Aborting := True to abort the loading of an OnDemand sequence
|
|
|
|
<FM>Example<FC>
|
|
ImageEnMView1.LoadFromFileOnDemand('C:\input.mpeg');
|
|
|
|
If input.mpeg has 1000 frames, then we will now have:
|
|
ImageEnMView1.ImageFileName[0] = 'C:\input.mpeg::0'
|
|
ImageEnMView1.ImageFileName[1] = 'C:\input.mpeg::1'
|
|
...
|
|
ImageEnMView1.ImageFileName[999] = 'C:\input.mpeg::999'
|
|
|
|
<FM>Demo<FN>
|
|
<TABLE2>
|
|
<R> <C_IMG_DEMO> <C>Demos\InputOutput\LargeVideos\LargeVideos.dpr </C> </R>
|
|
</TABLE>
|
|
|
|
!!}
|
|
procedure TImageEnMView.LoadFromFileOnDemand(const FileName: WideString; Append: Boolean);
|
|
var
|
|
FramesCount, i, ofs: Integer;
|
|
lAnimation: TIEAnimation;
|
|
begin
|
|
lAnimation := Animation;
|
|
fAnimation := nil;
|
|
LockPaint();
|
|
MIO.Aborting := False;
|
|
try
|
|
if Append then
|
|
begin
|
|
ofs := ImageCount;
|
|
end
|
|
else
|
|
begin
|
|
ofs := 0;
|
|
Clear();
|
|
end;
|
|
FramesCount := IEGetFileFramesCount(FileName);
|
|
for i := 0 to FramesCount - 1 do
|
|
begin
|
|
InsertImageEx( ofs + i );
|
|
ImageFileName[ ofs + i ] := Filename + IEM_Path_Index_Delimiter + IntToStr(i);
|
|
if assigned( fOnImageAdded ) then
|
|
fOnImageAdded( self, ofs + i );
|
|
end;
|
|
finally
|
|
fAnimation := lAnimation;
|
|
UnLockPaint();
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
function CreateLinesArray(vect: TImageEnVect): PIELineArray;
|
|
var
|
|
i, hobj: Integer;
|
|
r: TRect;
|
|
begin
|
|
getmem(result, SizeOf(TIELine) * vect.ObjectsCount);
|
|
for i := 0 to vect.ObjectsCount-1 do
|
|
begin
|
|
hobj := vect.GetObjFromIndex(i);
|
|
vect.GetObjRect(hobj, r);
|
|
result[i].P.x := r.Left;
|
|
result[i].P.y := r.Top;
|
|
result[i].Q.x := r.Right;
|
|
result[i].Q.y := r.Bottom;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.CreateMorphingSequence
|
|
|
|
<FM>Declaration<FC>
|
|
procedure CreateMorphingSequence(Source: <A TImageEnVect>; Target: <A TImageEnVect>; FramesCount: Integer);
|
|
|
|
<FM>Description<FN>
|
|
Creates a sequence of frames which are the transformation of the <FC>Source<FN> image to <FC>Target<FN> image. FramesCount specifies the number of frames to create.
|
|
|
|
Notes:
|
|
- The <A TIEBitmap.PixelFormat> of both images must be ie24RGB (true color)
|
|
- The dimension of the images must be identical
|
|
- The Source and Target must contain iekLINE objects to describe the transformation. The number of line objects must be identical and applied in the same order on both TImageEnVect components
|
|
- Does not call <A TImageEnMView.OnCreateImage>
|
|
|
|
<FM>Demo<FN>
|
|
<TABLE2>
|
|
<R> <C_IMG_DEMO> <C>Demos\Other\Morphing\Morphing.dpr </C> </R>
|
|
</TABLE>
|
|
|
|
!!}
|
|
procedure TImageEnMView.CreateMorphingSequence(Source: TImageEnVect; Target: TImageEnVect; FramesCount: Integer);
|
|
var
|
|
source_lines, dest_lines: PIELineArray;
|
|
outimages_src, outimages_trg: TList;
|
|
outcount, i: Integer;
|
|
ie: TImageEnView;
|
|
idx: Integer;
|
|
begin
|
|
if (Source.ObjectsCount=0) or (Target.ObjectsCount=0) or (Source.ObjectsCount<>Target.ObjectsCount) then
|
|
exit;
|
|
if (Source.IEBitmap = nil) or (Target.IEBitmap = nil) then
|
|
exit;
|
|
if (Source.IEBitmap.PixelFormat<>ie24RGB) or (Target.IEBitmap.PixelFormat<>ie24RGB) then
|
|
exit;
|
|
|
|
source_lines := nil;
|
|
dest_lines := nil;
|
|
outimages_src := nil;
|
|
outimages_trg := nil;
|
|
outcount := 0;
|
|
|
|
try
|
|
source_lines := CreateLinesArray(Source);
|
|
dest_lines := CreateLinesArray(Target);
|
|
outimages_src := TList.Create;
|
|
outimages_trg := TList.Create;
|
|
|
|
IEFields_warp( Source.IEBitmap, source_lines, dest_lines, Source.ObjectsCount, FramesCount, outimages_src);
|
|
IEFields_warp( Target.IEBitmap, dest_lines, source_lines, Target.ObjectsCount, FramesCount, outimages_trg);
|
|
|
|
idx := AppendImage;
|
|
SetIEBitmapEx( idx , Source.IEBitmap);
|
|
|
|
ie := TImageEnView.Create(nil);
|
|
try
|
|
outcount := outimages_src.Count;
|
|
for i := 0 to outcount-1 do
|
|
begin
|
|
ie.IEBitmap.Assign(outimages_src[i]);
|
|
ie.Update;
|
|
ie.Proc.Merge(TIEBitmap(outimages_trg[outcount - 1 - i]), trunc((outcount - i) / outcount * 100));
|
|
|
|
idx := AppendImage;
|
|
SetIEBitmapEx( idx , ie.IEBitmap );
|
|
end;
|
|
finally
|
|
FreeAndNil(ie);
|
|
end;
|
|
|
|
idx := AppendImage;
|
|
SetIEBitmapEx( idx , Target.IEBitmap);
|
|
|
|
finally
|
|
for i := 0 to outcount-1 do
|
|
TIEBitmap(outimages_src[i]).Free;
|
|
FreeAndNil(outimages_src);
|
|
for i := 0 to outcount-1 do
|
|
TIEBitmap(outimages_trg[i]).Free;
|
|
FreeAndNil(outimages_trg);
|
|
|
|
freemem(dest_lines);
|
|
freemem(source_lines);
|
|
end;
|
|
|
|
Update;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ImageEnVersion
|
|
|
|
<FM>Declaration<FC>
|
|
property ImageEnVersion: String;
|
|
|
|
<FM>Description<FN>
|
|
Returns the ImageEn version as a string.
|
|
|
|
!!}
|
|
function TImageEnMView.GetImageEnVersion: String;
|
|
begin
|
|
result := IEMAINVERSION;
|
|
end;
|
|
|
|
procedure TImageEnMView.SetImageEnVersion(Value: String);
|
|
begin
|
|
// this is a read-only property, but it must be displayed in object inspector
|
|
end;
|
|
|
|
procedure TImageEnMView.SaveSnapshot(FileName: WideString; SaveCache: Boolean; Compressed: Boolean; SaveParams: Boolean);
|
|
var
|
|
fs: TIEWideFileStream;
|
|
begin
|
|
fs := TIEWideFileStream.Create(FileName, fmCreate);
|
|
try
|
|
SaveSnapshot(fs, SaveCache, Compressed, SaveParams);
|
|
finally
|
|
fs.Free;
|
|
end;
|
|
end;
|
|
|
|
function TImageEnMView.LoadSnapshot(FileName: WideString): Boolean;
|
|
var
|
|
fs: TIEWideFileStream;
|
|
begin
|
|
fs := TIEWideFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
|
|
try
|
|
result := LoadSnapshot(fs);
|
|
finally
|
|
fs.Free;
|
|
end;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.SaveSnapshot
|
|
|
|
<FM>Declaration<FC>
|
|
procedure SaveSnapshot(FileName: WideString; SaveCache: Boolean = True; Compressed: Boolean = False; SaveParams: Boolean = False);
|
|
procedure SaveSnapshot(Stream: TStream; SaveCache: Boolean = True; Compressed: Boolean = False; SaveParams: Boolean = False);
|
|
|
|
<FM>Description<FN>
|
|
Saves the image, cache data, text and dimensions of all frames to the specified stream or file.
|
|
|
|
This can be used to create caching mechanism, like Windows .db files, to load quickly an entire directory of images.
|
|
|
|
<TABLE>
|
|
<R> <H>Value</H> <H>Description</H> </R>
|
|
<R> <C>Filename/Stream</C> <C>Destination for snapshot</C> </R>
|
|
<R> <C>SaveCache</C> <C>If enabled (default), the image cache is also saved. This will speed up display but require more disk space</C> </R>
|
|
<R> <C>Compressed</C> <C>If enabled, an LZ compression algorithm is used to reduce disk space (though saving will be slower)</C> </R>
|
|
<R> <C>SaveParams</C> <C>Enable to save the <L TImageEnMIO.Params>input/output parameters</L> for all images</C> </R>
|
|
</TABLE>
|
|
|
|
You can reload a saved snapshot using <A TImageEnMView.LoadSnapshot>.
|
|
!!}
|
|
procedure TImageEnMView.SaveSnapshot(Stream: TStream; SaveCache: Boolean; Compressed: Boolean; SaveParams: Boolean);
|
|
begin
|
|
SaveSnapshotEx(Stream, SaveCache, Compressed, SaveParams, nil);
|
|
end;
|
|
|
|
|
|
// versions (IEMVIEWSNAPSHOWVERSION):
|
|
// 2: 2.3.2
|
|
// 3: 3.0.0
|
|
// 4: 3.0.5
|
|
// 5: 4.0.3
|
|
// 6: 4.1.1-B
|
|
// 7: 5.0.1
|
|
// 8: 6.0.0 Move from TIEMText to Widesting for text
|
|
procedure TImageEnMView.SaveSnapshotEx(Stream: TStream; SaveCache: Boolean; Compressed: Boolean; SaveParams: Boolean; GetExtraParams: TIEProcessStreamEvent);
|
|
var
|
|
ver: byte;
|
|
i, i32: Integer;
|
|
LZStream: TZCompressionStream;
|
|
begin
|
|
// magic
|
|
IESaveStringToStream(Stream, 'MVIEWSNAPSHOT');
|
|
|
|
// version
|
|
ver := IEMVIEWSNAPSHOTVERSION;
|
|
Stream.Write(ver, SizeOf(byte));
|
|
|
|
Stream.Write(Compressed, SizeOf(boolean));
|
|
|
|
if Compressed then
|
|
begin
|
|
LZStream := TZCompressionStream.Create(Stream, zcDefault, 15);
|
|
Stream := LZStream;
|
|
end
|
|
else
|
|
LZStream := nil;
|
|
|
|
try
|
|
// fThumbWidth and fThumbHeight
|
|
Stream.Write(fThumbWidth, SizeOf(integer));
|
|
Stream.Write(fThumbHeight, SizeOf(integer));
|
|
|
|
// fUpperGap and fBottomGap
|
|
Stream.Write(fUpperGap, SizeOf(integer));
|
|
Stream.Write(fBottomGap, SizeOf(integer));
|
|
|
|
// SideGap and TextMargin
|
|
Stream.Write(fSideGap, SizeOf(integer));
|
|
Stream.Write(fTextMargin, SizeOf(integer));
|
|
|
|
// StoreType
|
|
Stream.Write(fStoreType, SizeOf(TIEStoreType));
|
|
|
|
// Parameters for descended components, such as TImageEnFolderMView
|
|
if assigned(GetExtraParams) then
|
|
GetExtraParams(Self, Stream, IEMVIEWSNAPSHOTVERSION);
|
|
|
|
// images
|
|
fIEMBitmap.fImageList.SaveToStream(Stream);
|
|
|
|
// caches
|
|
Stream.Write(SaveCache, SizeOf(boolean));
|
|
if SaveCache then
|
|
fCacheList.SaveToStream(Stream);
|
|
|
|
// images count
|
|
i32 := fIEMBitmap.Count;
|
|
Stream.Write(i32, SizeOf(integer));
|
|
|
|
// info
|
|
for i := 0 to fIEMBitmap.Count-1 do
|
|
begin
|
|
fIEMBitmap.GetImageInfo( i ).SaveToStream(Stream, SaveCache, fIEMBitmap.fImageList, fCacheList);
|
|
|
|
// I/O params (only of MIO embedded object)
|
|
Stream.Write(SaveParams, SizeOf(boolean));
|
|
if SaveParams then
|
|
MIO.Params[i].SaveToStream(Stream);
|
|
end;
|
|
|
|
finally
|
|
if Compressed then
|
|
LZStream.Free;
|
|
end;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.LoadSnapshot
|
|
|
|
<FM>Declaration<FC>
|
|
function LoadSnapshot(FileName: WideString): Boolean;
|
|
function LoadSnapshot(Stream: TStream): Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Loads the image, cache data, text and dimensions of frames that have been save to a stream or file using <A TImageEnMView.SaveSnapshot>.
|
|
|
|
This can be used to create caching mechanism, like Windows .db files, to load quickly an entire directory of images.
|
|
|
|
!!}
|
|
function TImageEnMView.LoadSnapshot(Stream: TStream): Boolean;
|
|
begin
|
|
result := LoadSnapshotEx(Stream, nil);
|
|
end;
|
|
|
|
function TImageEnMView.LoadSnapshotEx(Stream: TStream; SetExtraParams: TIEProcessStreamEvent): Boolean;
|
|
var
|
|
magicStr: AnsiString;
|
|
ver: byte;
|
|
i, i32: Integer;
|
|
LoadCache: Boolean;
|
|
LoadParams: Boolean;
|
|
Compressed: Boolean;
|
|
LZStream: TZDecompressionStream;
|
|
ii : TIEImageInfo;
|
|
bHaveTopText, bHaveInfoText, bHaveBottomText: Boolean;
|
|
begin
|
|
result := false;
|
|
bHaveTopText := False;
|
|
bHaveInfoText := False;
|
|
bHaveBottomText := False;
|
|
|
|
// magic
|
|
IELoadStringFromStream(Stream, magicStr);
|
|
if magicStr <> 'MVIEWSNAPSHOT' then
|
|
exit;
|
|
|
|
// version
|
|
Stream.Read(ver, SizeOf(byte));
|
|
|
|
Clear;
|
|
|
|
Stream.Read(Compressed, SizeOf(boolean));
|
|
if Compressed then
|
|
begin
|
|
LZStream := TZDecompressionStream.Create(Stream);
|
|
Stream := LZStream;
|
|
end
|
|
else
|
|
LZStream := nil;
|
|
|
|
try
|
|
// fThumbWidth and fThumbHeight
|
|
Stream.Read(fThumbWidth, SizeOf(integer));
|
|
Stream.Read(fThumbHeight, SizeOf(integer));
|
|
|
|
if ver >= 3 then
|
|
begin
|
|
// fUpperGap and fBottomGap
|
|
Stream.Read(fUpperGap, SizeOf(integer));
|
|
Stream.Read(fBottomGap, SizeOf(integer));
|
|
end;
|
|
|
|
if ver >= 7 then
|
|
begin
|
|
// SideGap and TextMargin
|
|
Stream.Read(fSideGap, SizeOf(integer));
|
|
Stream.Read(fTextMargin, SizeOf(integer));
|
|
end;
|
|
|
|
if ver >= 4 then
|
|
Stream.Read(fStoreType, SizeOf(TIEStoreType));
|
|
|
|
// Parameters for descended components, such as TImageEnFolderMView
|
|
if assigned(SetExtraParams) then
|
|
SetExtraParams(Self, Stream, ver);
|
|
|
|
// images
|
|
result := fIEMBitmap.fImageList.LoadFromStream(Stream);
|
|
if not result then exit;
|
|
|
|
// caches
|
|
Stream.Read(LoadCache, SizeOf(boolean));
|
|
if LoadCache then
|
|
result := fCacheList.LoadFromStream(Stream);
|
|
if not result then exit;
|
|
|
|
// images count
|
|
Stream.Read(i32, SizeOf(integer));
|
|
|
|
// info
|
|
for i := 0 to i32 - 1 do
|
|
begin
|
|
ii := TIEImageInfo.CreateFromStream( self, Stream, ver, LoadCache, fIEMBitmap.fImageList, fCacheList );
|
|
fIEMBitmap.fImageInfo.Add( ii );
|
|
if ( bHaveTopText = False ) and ( ii.TopText <> '' ) then
|
|
bHaveTopText := true;
|
|
if ( bHaveInfoText = False ) and ( ii.InfoText <> '' ) then
|
|
bHaveInfoText := true;
|
|
if ( bHaveBottomText = False ) and ( ii.BottomText <> '' ) then
|
|
bHaveBottomText := true;
|
|
|
|
SetLastImOp( IEM_OP_INSERT, i );
|
|
CallBitmapChangeEvents;
|
|
fCheckedCount := -1;
|
|
|
|
// I/O params (only of MIO embedded object)
|
|
if ver >= 4 then
|
|
begin
|
|
Stream.Read(LoadParams, SizeOf(boolean));
|
|
if LoadParams then
|
|
MIO.Params[i].LoadFromStream(Stream);
|
|
end;
|
|
end;
|
|
|
|
UpdateTopTextHeight(( fDefaultTopText <> iedtNone ) or bHaveTopText );
|
|
UpdateInfoTextHeight(( fDefaultInfoText <> iedtNone ) or bHaveInfoText );
|
|
UpdateBottomTextHeight(( fDefaultBottomText <> iedtNone ) or bHaveBottomText );
|
|
finally
|
|
if Compressed then
|
|
LZStream.Free;
|
|
end;
|
|
|
|
if LoadCache then
|
|
UpdateEx(false)
|
|
else
|
|
UpdateEx(true);
|
|
|
|
result := true;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.RemoveBlankPages
|
|
|
|
<FM>Declaration<FC>
|
|
function RemoveBlankPages(Tolerance: Double = 0.0; Complete: boolean = true; LeftToRight: boolean = true): Integer;
|
|
|
|
<FM>Description<FN>
|
|
Locate images in the TImageEnMView of a single color (i.e. blank images) and remove them.
|
|
|
|
<TABLE>
|
|
<R> <H>Parameter</H> <H>Description</H> </R>
|
|
<R> <C><FC>Tolerance<FN></C> <C>Determines how tolerant to be in checking color variance (in the range 0.0 to 1.0). For example, if tolerance is 0.1 then 10% of pixels can be of different color and the image would still be considered "blank"</C> </R>
|
|
<R> <C><FC>Complete<FN></C> <C>If true all images are checked. Otherwise the check stops once the first non blank image has been found and removed.</C> </R>
|
|
<R> <C><FC>LeftToRight<FN></C> <C>If true the scan starts at the first image and proceeds to the last (otherwise it proceeds in reverse order)</C> </R>
|
|
</TABLE>
|
|
|
|
Returns the number of removed pages.
|
|
|
|
Notes:
|
|
- Does not call <A TImageEnMView.OnDestroyImage>
|
|
- Cannot be used if a <A TIEDBMultiBitmap> is <L TImageEnMView.SetExternalMBitmap>attached to the control</L>
|
|
|
|
<FM>Examples<FC>
|
|
// Remove last blank pages
|
|
ImageEnMView1.RemoveBlankPages( 0.0, False, False );
|
|
|
|
// Remove any pages that are 95% blank
|
|
ImageEnMView1.RemoveBlankPages( 0.05 );
|
|
!!}
|
|
function TImageEnMView.RemoveBlankPages(Tolerance: Double = 0; Complete: boolean = true; LeftToRight: boolean = true): Integer;
|
|
begin
|
|
if IEMBitmap_IsTIEDBMultiBitmap then
|
|
raise EIEException.create('Not available when attached to TIEDBMultiBitmap');
|
|
|
|
LockPaint;
|
|
result := TIEMultiBitmap( fIEMBitmap ).RemoveBlankPages( Tolerance, Complete, LeftToRight );
|
|
if fSelectedItem > GetImageCount - 1 then
|
|
fSelectedItem := GetImageCount - 1;
|
|
UnlockPaint;
|
|
if Result > 0 then
|
|
Update;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.RemoveDuplicates
|
|
|
|
<FM>Declaration<FC>
|
|
function RemoveDuplicates(): Integer;
|
|
|
|
<FM>Description<FN>
|
|
Locate images with duplicate content in the TImageEnMView and remove other instances.
|
|
Returns the number of removed pages.
|
|
|
|
Notes:
|
|
- Does not call <A TImageEnMView.OnDestroyImage>
|
|
- Cannot be used if a <A TIEDBMultiBitmap> is <L TImageEnMView.SetExternalMBitmap>attached to the control</L>
|
|
|
|
<FM>Examples<FC>
|
|
// Ensure there are no blank images in our TImageEnMView after filling it from a folder
|
|
ImageEnMView1.Clear;
|
|
ImageEnMView1.StoreType := ietNormal;
|
|
ImageEnMView1.FillFromDirectory('C:\Images');
|
|
ImageEnMView1.RemoveDuplicates();
|
|
!!}
|
|
function TImageEnMView.RemoveDuplicates(): Integer;
|
|
begin
|
|
if IEMBitmap_IsTIEDBMultiBitmap then
|
|
raise EIEException.create('Not available when attached to TIEDBMultiBitmap');
|
|
|
|
LockPaint;
|
|
result := TIEMultiBitmap( fIEMBitmap ).RemoveDuplicates();
|
|
if fSelectedItem > GetImageCount - 1 then
|
|
fSelectedItem := GetImageCount - 1;
|
|
UnlockPaint;
|
|
if Result > 0 then
|
|
Update;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.DisplayImageAt
|
|
|
|
<FM>Declaration<FC>
|
|
procedure DisplayImageAt(idx: Integer; x, y: Integer);
|
|
|
|
<FM>Description<FN>
|
|
Scrolls the control to display image, <FC>idx<FN>, at specified position in the current view.
|
|
|
|
<TABLE>
|
|
<R> <H>Parameter</H> <H>Description</H> </R>
|
|
<R> <C><FC>idx<FN></C> <C>Index of the image to display</C> </R>
|
|
<R> <C><FC>x<FN></C> <C>Horizontal offset in client area</C> </R>
|
|
<R> <C><FC>y<FN></C> <C>Vertical offset in client area</C> </R>
|
|
</TABLE>
|
|
|
|
<FM>Example<FC>
|
|
// make then tenth image visible at 0, 0 (Top-left of control)
|
|
ImageEnMView1.DisplayImageAt(9, 0, 0);
|
|
!!}
|
|
procedure TImageEnMView.DisplayImageAt(idx: Integer; x, y: Integer);
|
|
var
|
|
newViewX, newViewY: Integer;
|
|
image: TIEImageInfo;
|
|
begin
|
|
image := fIEMBitmap.GetImageInfo( idx );
|
|
newViewX := image.X + x;
|
|
newViewY := image.Y + y;
|
|
SetViewXY(newViewX, newViewY);
|
|
end;
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Animation Support
|
|
|
|
{!!
|
|
<FS>TImageEnMView.Animation
|
|
|
|
<FM>Declaration<FC>
|
|
property Animation: <A TIEAnimation>;
|
|
|
|
<FM>Description<FN>
|
|
Uses a special animated mode to display your images. Two internal animations are available:
|
|
- <A TIEHorizontalFlow>: Coverflow style animation
|
|
- <A TIECircularFlow>: Circular flow animation
|
|
|
|
Setting Animation to nil disables animation.
|
|
|
|
Default: nil (no animation)
|
|
|
|
<FM>Example<FC>
|
|
ImageEnMView1.Animation := TIEHorizontalFlow.Create();
|
|
|
|
<IMG help_images\Coverflow.jpg>
|
|
|
|
<FM>Demo<FN>
|
|
<TABLE2>
|
|
<R> <C_IMG_DEMO> <C>Demos\Display\MviewFlow\MviewFlow.dpr </C> </R>
|
|
</TABLE>
|
|
|
|
<FM>See Also<FN>
|
|
- <A TImageEnMView.OnAnimationText>
|
|
!!}
|
|
procedure TImageEnMView.SetAnimation(value: TIEAnimation);
|
|
begin
|
|
if assigned(fAnimation) then
|
|
begin
|
|
fAnimationTimer.Enabled := false;
|
|
FreeAndNil(fAnimation);
|
|
end;
|
|
fAnimation := value;
|
|
if assigned(fAnimation) then
|
|
begin
|
|
// hide scroll bars
|
|
IEShowScrollBar(handle, SB_VERT, false, fFlatScrollBars);
|
|
IEShowScrollBar(handle, SB_HORZ, false, fFlatScrollBars);
|
|
UpdateEx(false);
|
|
|
|
fAnimation.SetupEvents(AnimGetImage, AnimReleaseImage, AnimGetImageInfo);
|
|
fAnimation.ViewWidth := ClientWidth;
|
|
fAnimation.ViewHeight := ClientHeight;
|
|
fAnimation.ImageCount := ImageCount;
|
|
|
|
fAnimationTimer.Interval := 10;
|
|
fAnimationTimer.OnTimer := AnimTimer;
|
|
fAnimationTimer.Enabled := true;
|
|
end;
|
|
Update();
|
|
end;
|
|
|
|
procedure TImageEnMView.AnimGetImageInfo(Sender: TObject; imageIndex: Integer; isVisible: Boolean; var ImageWidth: Integer; var ImageHeight: Integer; var text: WideString);
|
|
var
|
|
info: TIEImageInfo;
|
|
begin
|
|
ImageWidth := 0;
|
|
ImageHeight := 0;
|
|
|
|
info := fIEMBitmap.GetImageInfo( imageIndex );
|
|
if isVisible or // We need the actual image size
|
|
(( info <> nil ) and ( info.image <> nil )) then // Or image is already loaded
|
|
begin
|
|
// Image loading will be automatically forced if not yet loaded
|
|
ImageWidth := self.ImageWidth[imageIndex];
|
|
ImageHeight := self.ImageHeight[imageIndex];
|
|
end;
|
|
|
|
if (ImageWidth = 0) or (ImageHeight = 0) then
|
|
begin
|
|
// return thumb size (if still not loaded)
|
|
ImageWidth := self.ThumbSizeInfo( itsCell ).X;
|
|
ImageHeight := self.ThumbSizeInfo( itsCell ).Y;
|
|
end;
|
|
|
|
if assigned(fOnAnimationText) then
|
|
fOnAnimationText(self, imageIndex, text)
|
|
else
|
|
text := GetDisplayName( ImageFileName[ imageIndex ] );
|
|
end;
|
|
|
|
procedure TImageEnMView.AnimGetImage(Sender: TObject; imageIndex: Integer; var image: TIEBitmap; var text: WideString);
|
|
begin
|
|
image := GetTIEBitmap(imageIndex);
|
|
text := GetDisplayName( ImageFileName[ imageIndex ] );
|
|
end;
|
|
|
|
procedure TImageEnMView.AnimReleaseImage(Sender: TObject; imageIndex: Integer; var image: TIEBitmap);
|
|
begin
|
|
ReleaseBitmap(imageIndex, false);
|
|
end;
|
|
|
|
procedure TImageEnMView.AnimPaintTo(dest: TIEBitmap);
|
|
begin
|
|
if fAnimation.NeedRefresh then
|
|
begin
|
|
PaintBackgroundTo(dest.VclBitmap);
|
|
fAnimation.Display(dest);
|
|
end;
|
|
end;
|
|
|
|
procedure TImageEnMView.AnimTimer(Sender: TObject);
|
|
begin
|
|
Paint();
|
|
end;
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
// Copy selection from one TImageEnMView to another (assumes multiselction and that both have same image set)
|
|
procedure TImageEnMView.CopySelection(SourceMView : TImageEnMView);
|
|
var
|
|
q: integer;
|
|
lMultiSelecting: boolean;
|
|
begin
|
|
If ImageCount <> SourceMView.ImageCount then
|
|
exit;
|
|
|
|
if fEnableMultiSelect then
|
|
begin
|
|
DeselectNU;
|
|
lMultiSelecting := fMultiSelecting;
|
|
fMultiSelecting := true;
|
|
for q := 0 to SourceMView.ImageCount - 1 do
|
|
if SourceMView.IsSelected(q) then
|
|
SetSelectedItemNU(q);
|
|
fMultiSelecting := lMultiSelecting;
|
|
UpdateEx(false);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.CalcGridWidth
|
|
|
|
<FM>Declaration<FC>
|
|
function CalcGridWidth(): Integer;
|
|
|
|
<FM>Description<FN>
|
|
Returns the number of columns displayed in the grid. This is mainly used when the column count is automatically calculated (i.e. when <A TImageEnMView.GridWidth> = -1).
|
|
!!}
|
|
function TImageEnMView.CalcGridWidth(): Integer;
|
|
begin
|
|
if fStyle = iemsColumns then
|
|
Result := 1
|
|
else
|
|
case fCurrentGridWidth of
|
|
-1:
|
|
begin
|
|
result := (ClientWidth - fHorizBorder) div ThumbSizeInfo( itsOuter ).X;
|
|
if (result < 1) and (ImageCount > 0) then
|
|
result := 1;
|
|
end;
|
|
0:
|
|
result := ImageCount;
|
|
else
|
|
result := fCurrentGridWidth;
|
|
end;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.CalcGridHeight
|
|
|
|
<FM>Declaration<FC>
|
|
function CalcGridHeight(): Integer;
|
|
|
|
<FM>Description<FN>
|
|
Returns the number of rows displayed in the grid.
|
|
!!}
|
|
function TImageEnMView.CalcGridHeight(): Integer;
|
|
var
|
|
gw: integer;
|
|
begin
|
|
gw := CalcGridWidth();
|
|
if (ImageCount > 0) and (gw <> 0) then
|
|
result := Ceil(ImageCount / gw)
|
|
else
|
|
result := 0;
|
|
end;
|
|
|
|
procedure TImageEnMView.CheckSelectedImageIsVisible;
|
|
var
|
|
info: TIEImageInfo;
|
|
iViewX, iViewY : integer;
|
|
begin
|
|
if (fLockPaint > 0) or (fLockUpdate > 0) then
|
|
exit;
|
|
|
|
if fSelectedItem > GetImageCount - 1 then
|
|
fSelectedItem := GetImageCount - 1;
|
|
if assigned(Parent) and (fSelectedItem >= 0) and (fMultiSelecting = False) then
|
|
begin
|
|
iViewX := fViewX;
|
|
iViewY := fViewY;
|
|
info := fIEMBitmap.GetImageInfo( fSelectedItem );
|
|
|
|
if info.Col = 0 then
|
|
iViewX := 0
|
|
else
|
|
if info.X < iViewX then
|
|
iViewX := info.X
|
|
else
|
|
if info.X + ThumbSizeInfo( itsCell ).X > iViewX + ClientWidth then
|
|
iViewX := info.X - ClientWidth + ThumbSizeInfo( itsCell ).X;
|
|
|
|
if info.Row = 0 then
|
|
iViewY := 0
|
|
else
|
|
if info.Y < iViewY then
|
|
iViewY := info.Y
|
|
else
|
|
if info.Y + ThumbSizeInfo( itsCell ).Y > iViewY + ClientHeight then
|
|
iViewY := info.Y - ClientHeight + ThumbSizeInfo( itsCell ).Y;
|
|
|
|
SetViewXY(iViewX, iViewY);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.Seek
|
|
|
|
<FM>Declaration<FC>
|
|
function Seek(Page : <A TImageEnIO.TIEIOSeekDestination>) : integer;
|
|
|
|
<FM>Description<FN>
|
|
When <A TImageEnMView.DisplayMode> is mdSingle then Seek sets <A TImageEnMView.VisibleFrame> to display the first/previous/next/last image.
|
|
|
|
Otherwise it sets <A TImageEnMView.SelectedImage> to move the selection to the first/previous/next/last image.
|
|
|
|
Returns the new page index.
|
|
|
|
<FM>Example<FC>
|
|
// Display a single image
|
|
ImageEnMView1.DisplayMode := mdSingle;
|
|
..
|
|
// Advance to the next image
|
|
ImageEnMView1.IO.Seek(ieioSeekNext);
|
|
!!}
|
|
function TImageEnMView.Seek(Destination : TIEIOSeekDestination): Integer;
|
|
// NPC: 23/11/11
|
|
var
|
|
iIndex: Integer;
|
|
begin
|
|
Result := -1;
|
|
if fIEMBitmap.Count = 0 then
|
|
exit;
|
|
|
|
if fDisplayMode = mdSingle then
|
|
iIndex := VisibleFrame
|
|
else
|
|
iIndex := SelectedImage;
|
|
|
|
result := 0;
|
|
case Destination of
|
|
ieioSeekFirst:
|
|
result := 0;
|
|
ieioSeekPrior:
|
|
result := imax(0, iIndex - 1);
|
|
ieioSeekNext:
|
|
result := imin(fIEMBitmap.Count - 1, iIndex + 1);
|
|
ieioSeekLast:
|
|
result := fIEMBitmap.Count - 1;
|
|
end;
|
|
|
|
if fDisplayMode = mdSingle then
|
|
VisibleFrame := Result
|
|
else
|
|
begin
|
|
SelectedImage := Result;
|
|
CheckSelectedImageIsVisible;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TImageEnMView.DoAfterEvent(e: TIEAfterEvent);
|
|
begin
|
|
if assigned(fOnAfterEvent) then
|
|
fOnAfterEvent(self, e);
|
|
end;
|
|
|
|
procedure TImageEnMView.CNKEYUP(var Message: TMessage);
|
|
begin
|
|
inherited;
|
|
case Message.wParam of
|
|
VK_LEFT, VK_RIGHT, VK_UP, VK_DOWN, VK_PRIOR, VK_NEXT, VK_HOME, VK_END:
|
|
DoAfterEvent(ieaeKeyUp); // because no KeyUp event is generated on special keys
|
|
end;
|
|
end;
|
|
|
|
{!!
|
|
<FS>TImageEnMView.SetAllText
|
|
|
|
<FM>Declaration<FC>
|
|
procedure SetAllText(TopText : <A TIEImageEnMViewDefaultText>;
|
|
InfoText : <A TIEImageEnMViewDefaultText>;
|
|
BottomText : <A TIEImageEnMViewDefaultText>);;
|
|
|
|
<FM>Description<FN>
|
|
Set the values for <A TImageEnMView.ImageTopText>, <A TImageEnMView.ImageInfoText> and <A TImageEnMView.ImageBottomText>.
|
|
|
|
<FM>Example<FC>
|
|
// Show only the filename
|
|
ImageEnMView1.SetAllText( iedtNone, iedtNone, iedtFileName );
|
|
|
|
!!}
|
|
procedure TImageEnMView.SetAllText(TopText : TIEImageEnMViewDefaultText;
|
|
InfoText : TIEImageEnMViewDefaultText;
|
|
BottomText : TIEImageEnMViewDefaultText);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
LockUpdate;
|
|
try
|
|
for I := 0 to ImageCount - 1 do
|
|
begin
|
|
ImageTopText [ I ] := IEMDefaultTextToConst( TopText );
|
|
ImageInfoText [ I ] := IEMDefaultTextToConst( InfoText );
|
|
ImageBottomText [ I ] := IEMDefaultTextToConst( BottomText );
|
|
end;
|
|
finally
|
|
UnlockUpdate;
|
|
end;
|
|
end;
|
|
|
|
|
|
constructor TIECachedIcon.Create(aBmp: TIEBitmap; const sExt: string);
|
|
begin
|
|
inherited Create();
|
|
Bmp := TIEBitmap.Create(aBmp);
|
|
Ext := Uppercase(sExt);
|
|
end;
|
|
|
|
destructor TIECachedIcon.Destroy();
|
|
begin
|
|
Bmp.Free();
|
|
inherited;
|
|
end;
|
|
|
|
function TIECachedIcon.MatchesExt(const sExt : string) : Boolean;
|
|
begin
|
|
Result := Uppercase(sExt) = Ext;
|
|
end;
|
|
|
|
|
|
constructor TIECachedIconList.Create(Owner : TImageEnMView; iMaxIconCount : Integer);
|
|
begin
|
|
inherited Create;
|
|
fDataList := TList.create;
|
|
fOwner := Owner;
|
|
fMaxIconCount := iMaxIconCount;
|
|
end;
|
|
|
|
destructor TIECachedIconList.Destroy();
|
|
begin
|
|
Clear();
|
|
fDataList.free();
|
|
inherited;
|
|
end;
|
|
|
|
procedure TIECachedIconList.ClearLastItem;
|
|
var
|
|
Idx: Integer;
|
|
begin
|
|
Idx := fDataList.Count - 1;
|
|
TIECachedIcon(fDataList[Idx]).Free();
|
|
fDataList.Delete(Idx);
|
|
end;
|
|
|
|
|
|
procedure TIECachedIconList.Clear();
|
|
var
|
|
i: integer;
|
|
begin
|
|
for i := 0 to fDataList.Count - 1 do
|
|
TIECachedIcon(fDataList[i]).Free();
|
|
fDataList.Clear();
|
|
end;
|
|
|
|
|
|
function TIECachedIconList.GetCacheName(aType : TCachedIconType; const sFilename : string; bIsFolder : Boolean) : string;
|
|
const
|
|
_Folder_Item = '~FOLDER';
|
|
begin
|
|
if bIsFolder then
|
|
Result := _Folder_Item
|
|
else
|
|
Result := ExtractFileExt(sFilename);
|
|
|
|
if Result <> '' then
|
|
begin
|
|
if aType = citIconOnly then
|
|
Result := Result + '~I'
|
|
else
|
|
Result := Result + '~F';
|
|
end;
|
|
end;
|
|
|
|
|
|
function TIECachedIconList.LookUpExt(const sExt : string) : Integer;
|
|
var
|
|
i: integer;
|
|
begin
|
|
Result := -1;
|
|
|
|
// CHECK CACHE VALIDITY
|
|
// Most property changes will automatically reset the icon cache, but not changes to the soft shadow, so ensure properties still match
|
|
if (fOwner.SoftShadow.Enabled <> fOwnerSoftShadowEnabled) or
|
|
(fOwner.SoftShadow.Radius <> fOwnerSoftShadowRadius) then
|
|
begin
|
|
fOwnerSoftShadowEnabled := fOwner.SoftShadow.Enabled;
|
|
fOwnerSoftShadowRadius := fOwner.SoftShadow.Radius;
|
|
Clear();
|
|
exit;
|
|
end;
|
|
|
|
// Locate the extension in our list
|
|
for i := 0 to fDataList.Count - 1 do
|
|
if TIECachedIcon(fDataList[i]).MatchesExt(sExt) then
|
|
begin
|
|
Result := i;
|
|
Break;
|
|
end;
|
|
end;
|
|
|
|
|
|
// bWantCopy = True: Dest is pointer to Bitmap in list (don't create or free). bWantCopy = False: Copy of bitmap is made, must be created and freed
|
|
function TIECachedIconList.RetrieveFromCache(aType : TCachedIconType; const sFilename : string; bIsFolder : Boolean; var Dest : TIEBitmap; bWantCopy : Boolean): boolean;
|
|
const
|
|
File_Extensions_With_Custom_Icons = '*.exe;*.lnk;*.ico;';
|
|
Cache_Folder_Icons = False; // Folder icons can change by content
|
|
var
|
|
Idx: Integer;
|
|
sExt: string;
|
|
begin
|
|
Result := False;
|
|
|
|
// Is it a file type with a changeable icon?
|
|
if IEFilenameInExtensions( sFilename, File_Extensions_With_Custom_Icons ) then
|
|
exit;
|
|
if ( Cache_Folder_Icons = False ) and bIsFolder then
|
|
exit;
|
|
|
|
sExt := GetCacheName(aType, sFilename, bIsFolder);
|
|
Idx := LookUpExt(sExt);
|
|
if Idx >= 0 then
|
|
begin
|
|
if bWantCopy then
|
|
Dest. Assign( TIECachedIcon(fDataList[Idx]).Bmp )
|
|
else
|
|
Dest := TIECachedIcon(fDataList[Idx]).Bmp;
|
|
Result := True;
|
|
|
|
// Promote the item
|
|
if Idx <> 0 then
|
|
fDataList.Move(Idx, 0);
|
|
end;
|
|
end;
|
|
|
|
procedure TIECachedIconList.SaveToCache(Image : TIEBitmap; aType : TCachedIconType; const sFilename : string; bIsFolder : Boolean);
|
|
var
|
|
aItem : TIECachedIcon;
|
|
Idx: Integer;
|
|
sExt: string;
|
|
begin
|
|
sExt := GetCacheName(aType, sFilename, bIsFolder);
|
|
if (sExt = '') or (Image.Width < 2) then
|
|
exit;
|
|
|
|
Idx := LookUpExt(sExt);
|
|
if Idx = -1 then
|
|
begin
|
|
aItem := TIECachedIcon.Create(Image, sExt);
|
|
fDataList.Insert(0, aItem);
|
|
end
|
|
else
|
|
begin
|
|
// Promote the item
|
|
if Idx <> 0 then
|
|
fDataList.Move(Idx, 0);
|
|
end;
|
|
|
|
if (fMaxIconCount > 0) and (fDataList.Count > fMaxIconCount) then
|
|
ClearLastItem();
|
|
end;
|
|
|
|
|
|
function TImageEnMView.BiDiModeIsRTL : Boolean;
|
|
begin
|
|
Result := ( fDisplayMode <> mdSingle ) and
|
|
( BiDiMode in [ bdRightToLeft ]);
|
|
// Not: bdRightToLeftNoAlign, bdRightToLeftReadingOnly
|
|
end;
|
|
|
|
procedure TImageEnMView.ProbeLastSort(out OrderBy: TIEImageEnMViewSortBy; out Ascending: boolean; out CaseSensitive: Boolean);
|
|
begin
|
|
OrderBy := fCurrentOrderBy;
|
|
Ascending := fCurrentAscending;
|
|
CaseSensitive := fCurrentCaseSensitive;
|
|
end;
|
|
|
|
|
|
|
|
procedure TImageEnMView.WMEnabled(var Msg: TMessage);
|
|
begin
|
|
Invalidate;
|
|
inherited;
|
|
end;
|
|
|
|
procedure TImageEnMView.WMGestureNotify(var Msg: TIEWMGestureNotify);
|
|
var
|
|
c: integer;
|
|
gc: array of TIEGESTURECONFIG;
|
|
begin
|
|
inherited;
|
|
if fGestures.Enabled and IEHasGestures() then
|
|
begin
|
|
IEUnregisterTouchWindow(Handle);
|
|
if fGestures.fPan.Enabled then
|
|
begin
|
|
c := length(gc);
|
|
SetLength(gc, c + 1);
|
|
gc[c].dwID := IEGID_PAN;
|
|
gc[c].dwWant := IEGC_PAN or IEGC_PAN_WITH_INERTIA;
|
|
if fGestures.fPan.PanWithSingleFingerVertically then
|
|
gc[c].dwWant := gc[c].dwWant or IEGC_PAN_WITH_SINGLE_FINGER_VERTICALLY;
|
|
if fGestures.fPan.PanWithSingleFingerHorizontally then
|
|
gc[c].dwWant := gc[c].dwWant or IEGC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY;
|
|
gc[c].dwBlock := IEGC_PAN_WITH_GUTTER;
|
|
end;
|
|
if fGestures.fZoom.Enabled then
|
|
begin
|
|
c := length(gc);
|
|
SetLength(gc, c + 1);
|
|
gc[c].dwID := IEGID_ZOOM;
|
|
gc[c].dwWant := IEGC_ALLGESTURES;
|
|
gc[c].dwBlock := 0;
|
|
end;
|
|
IESetGestureConfig(Handle, 0, length(gc), @gc[0], sizeof(TIEGESTURECONFIG));
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TImageEnMView.DoImageEnGestureEvent(const GInfo: TIEGESTUREINFO; var Handled: boolean);
|
|
var
|
|
Flags: TIEGestureFlags;
|
|
ID: TIEGestureID;
|
|
begin
|
|
if assigned(fOnImageEnGesture) then
|
|
begin
|
|
Flags := [];
|
|
if (IEGF_BEGIN and GInfo.dwFlags) <> 0 then
|
|
Flags := Flags + [iegfBegin];
|
|
if (IEGF_INERTIA and GInfo.dwFlags) <> 0 then
|
|
Flags := Flags + [iegfInertia];
|
|
if (IEGF_END and GInfo.dwFlags) <> 0 then
|
|
Flags := Flags + [iegfEnd];
|
|
ID := TIEGestureID(GInfo.dwID - 1);
|
|
fOnImageEnGesture(self, Flags, ID, GInfo.ptsLocation,
|
|
GInfo.ullArguments and $FFFFFFFF,
|
|
(GInfo.ullArguments shr 32) and $FFFF,
|
|
(GInfo.ullArguments shr 48) and $FFFF,
|
|
(GInfo.ullArguments shr 32),
|
|
Handled);
|
|
end;
|
|
end;
|
|
|
|
|
|
function TImageEnMView.PerformZoomSnap(Value: double): double;
|
|
begin
|
|
result := Value;
|
|
if fGestures.fZoom.SnapValues then
|
|
begin
|
|
if abs(result - 100.0) <= fGestures.fZoom.SnapDelta then
|
|
result := 100;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TImageEnMView.WMGesture(var Msg: TMessage);
|
|
var
|
|
gInfo: TIEGESTUREINFO;
|
|
value: integer;
|
|
v: double;
|
|
isBegin: boolean;
|
|
isInertia: boolean;
|
|
handled: boolean;
|
|
begin
|
|
Msg.Result := 1; // not handled
|
|
if fGestures.Enabled and IEHasGestures() then
|
|
begin
|
|
FillChar(gInfo, sizeof(gInfo), 0);
|
|
gInfo.cbSize := sizeof(gInfo);
|
|
if IEGetGestureInfo(Msg.LParam, @gInfo) then
|
|
begin
|
|
try
|
|
handled := false;
|
|
DoImageEnGestureEvent(gInfo, handled);
|
|
|
|
if not handled then
|
|
begin
|
|
|
|
value := gInfo.ullArguments and $FFFFFFFF;
|
|
isBegin := (IEGF_BEGIN and gInfo.dwFlags) <> 0;
|
|
isInertia := (IEGF_INERTIA and gInfo.dwFlags) <> 0;
|
|
|
|
case gInfo.dwID of
|
|
IEGID_ZOOM:
|
|
begin
|
|
// begin zoom
|
|
if isBegin then
|
|
begin
|
|
fGestureStartValue := value;
|
|
fGestureBaseZoom := Zoom;
|
|
end
|
|
// perform zoom
|
|
else
|
|
if fGestures.fZoom.Enabled and (not isInertia or fGestures.fZoom.Inertia) then
|
|
begin
|
|
v := fGestureBaseZoom * (value / fGestureStartValue);
|
|
v := dmax(v, fGestures.fZoom.Min);
|
|
v := dmin(v, fGestures.fZoom.Max);
|
|
v := v * fGestures.fZoom.Multiplier;
|
|
Zoom := PerformZoomSnap(v);
|
|
Msg.Result := 0; // handled
|
|
end
|
|
end;
|
|
|
|
IEGID_PAN:
|
|
begin
|
|
// begin pan
|
|
if isBegin then
|
|
begin
|
|
fGestureStartX := gInfo.ptsLocation.x;
|
|
fGestureStartY := gInfo.ptsLocation.y;
|
|
fGestureBaseViewX := ViewX;
|
|
fGestureBaseViewY := ViewY;
|
|
end
|
|
// perform pan
|
|
else
|
|
|
|
if fGestures.fPan.Enabled and (not isInertia or fGestures.fPan.Inertia) then
|
|
begin
|
|
v := fGestureBaseViewX + (fGestureStartX - gInfo.ptsLocation.x);
|
|
v := dmax(v, fGestures.fPan.BoundingBox.Left);
|
|
v := dmin(v, fGestures.fPan.BoundingBox.Right);
|
|
v := v * fGestures.fPan.Multiplier;
|
|
ViewX := trunc(v);
|
|
|
|
v := fGestureBaseViewY + (fGestureStartY - gInfo.ptsLocation.y);
|
|
v := dmax(v, fGestures.fPan.BoundingBox.Top);
|
|
v := dmin(v, fGestures.fPan.BoundingBox.Bottom);
|
|
v := v * fGestures.fPan.Multiplier;
|
|
ViewY := trunc(v);
|
|
|
|
Msg.Result := 0; // handled
|
|
end;
|
|
end;
|
|
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
// handled by user (in OnImageEnGesture event)
|
|
Msg.Result := 0; // handled
|
|
end;
|
|
|
|
finally
|
|
if Msg.Result = 0 then
|
|
IECloseGestureInfoHandle(Msg.LParam);
|
|
end;
|
|
end
|
|
end;
|
|
if Msg.Result <> 0 then
|
|
inherited;
|
|
end;
|
|
|
|
|
|
constructor TIEMViewerGestures.Create();
|
|
begin
|
|
inherited;
|
|
fPan := TIEGesturePanOptions.Create();
|
|
fZoom := TIEGestureZoomOptions.Create();
|
|
|
|
// Pan defaults
|
|
fPan.Enabled := false;
|
|
fPan.Inertia := true;
|
|
fPan.BoundingBox := Rect(Low(integer), Low(integer), High(integer), High(integer));
|
|
fPan.Multiplier := 1.0;
|
|
fPan.SnapValues := false;
|
|
fPan.SnapDelta := 0.0;
|
|
fPan.PanWithSingleFingerVertically := True;
|
|
fPan.PanWithSingleFingerHorizontally := True;
|
|
|
|
// Zoom defaults
|
|
fZoom.Enabled := false;
|
|
fZoom.Inertia := true;
|
|
fZoom.Min := 1.0;
|
|
fZoom.Max := 8000.0;
|
|
fZoom.Multiplier := 1.0;
|
|
fZoom.SnapValues := true;
|
|
fZoom.SnapDelta := 5.0;
|
|
end;
|
|
|
|
|
|
destructor TIEMViewerGestures.Destroy();
|
|
begin
|
|
fPan.Free();
|
|
fZoom.Free();
|
|
inherited;
|
|
end;
|
|
|
|
|
|
function TIEMViewerGestures.GetEnabled(): boolean;
|
|
begin
|
|
result := fPan.Enabled or fZoom.Enabled;
|
|
end;
|
|
|
|
|
|
function TImageEnMView.GetIEMBitmap: TIECustomMultiBitmap;
|
|
begin
|
|
result := fIEMBitmap;
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.SetExternalMBitmap
|
|
|
|
<FM>Declaration<FC>
|
|
procedure SetExternalMBitmap(value : <A TIECustomMultiBitmap>);
|
|
|
|
<FM>Description<FN>
|
|
Allows a custom <A TIEMultiBitmap> or <A TIEDBMultiBitmap> object to be attached to the TImageEnMView. The TImageEnMView will automatically display changes to the attached Multi-Bitmap.
|
|
|
|
It is mainly used to make a TImageEnMView DB aware.
|
|
|
|
Notes:
|
|
- You must create and destroy the external multi-bitmap yourself
|
|
- Use SetExternalMBitmap( nil ) to reset usage to the internal <A TIEMultiBitmap>
|
|
|
|
<FM>Example<FC>
|
|
// Create DB Aware TImageEnMView
|
|
procedure TMainForm.FormCreate(Sender: TObject);
|
|
begin
|
|
... Open a database table ...
|
|
|
|
fDBMBitmap := TIEDBMultiBitmap.create( DataSource1, 'Name', 'Image' );
|
|
ImageEnMView1.SetExternalMBitmap( fDBMBitmap );
|
|
end;
|
|
|
|
procedure TMainForm.FormDestroy(Sender: TObject);
|
|
begin
|
|
ImageEnMView1.SetExternalMBitmap( nil );
|
|
FreeAndNil( fDBMBitmap );
|
|
end;
|
|
|
|
!!}
|
|
procedure TImageEnMView.SetExternalMBitmap(value : TIECustomMultiBitmap);
|
|
begin
|
|
if value = nil then
|
|
begin
|
|
// Use internal fIEMBitmap
|
|
if fIEMBitmapIsExternal then
|
|
begin
|
|
if assigned( fIEMBitmap ) then
|
|
begin
|
|
fIEMBitmap.OnUpdateParams := nil;
|
|
fIEMBitmap.fOwner := nil;
|
|
end;
|
|
fIEMBitmap := nil;
|
|
fIEMBitmap := TIEMultiBitmap.Create( True );
|
|
end;
|
|
fIEMBitmapIsExternal := False;
|
|
end
|
|
else
|
|
begin
|
|
// Use external IEMBitmap
|
|
if fIEMBitmapIsExternal = False then
|
|
FreeAndNil( fIEMBitmap );
|
|
fIEMBitmap := value;
|
|
fIEMBitmapIsExternal := True;
|
|
end;
|
|
|
|
fIEMBitmap.OnUpdateParams := UpdateParams;
|
|
fIEMBitmap.fOwner := Self;
|
|
|
|
// Free fImageEnMIO and fImageEnProc so that they use the newly attached TIEMultiBitmap
|
|
if assigned(fImageEnMIO) then
|
|
FreeAndNil(fImageEnMIO);
|
|
if assigned(fImageEnProc) then
|
|
FreeAndNil(fImageEnProc);
|
|
|
|
Reset;
|
|
end;
|
|
|
|
{$IFDEF UNITTESTING}
|
|
function TImageEnMView.UnitTesting_GetExternalMBitmap: TIECustomMultiBitmap;
|
|
begin
|
|
if fIEMBitmapIsExternal then
|
|
Result := fIEMBitmap
|
|
else
|
|
Result := nil;
|
|
end;
|
|
{$ENDIF}
|
|
|
|
// Called from attached TIEMultiBitmap when the params need to realigned
|
|
procedure TImageEnMView.UpdateParams(Sender : TObject; Operation : Integer; Idx : integer; ExtraParam: Integer);
|
|
begin
|
|
SetLastImOp( Operation, Idx, ExtraParam );
|
|
end;
|
|
|
|
|
|
function TImageEnMView.IEMBitmap_IsTIEDBMultiBitmap: Boolean;
|
|
begin
|
|
Result := fIEMBitmap.ClassName = 'TIEDBMultiBitmap';
|
|
end;
|
|
|
|
// Returns the pointer to the image of the specified filename (and optionally index) in the cache list
|
|
function TImageEnMView.FindImageInCache( idx: Integer; const sFilename: string ): Pointer;
|
|
begin
|
|
Result := nil;
|
|
if ( idx < 0 ) or ( sFilename = '' ) then
|
|
exit;
|
|
|
|
case fImageCacheReusage of
|
|
iecrLoose : Result := fCacheList.GetImageByIdentifier( sFilename );
|
|
iecrStrict : Result := fCacheList.GetImageByIdentifier( IntToStr( idx ) + '/' + sFilename )
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TImageEnMView.ClickColumnsHeaderRowCell(Col: TIEMTextPos);
|
|
begin
|
|
// Not implemented in TImageEnMView
|
|
end;
|
|
|
|
procedure TImageEnMView.DrawColumnsHeaderRowCell(Canvas: TCanvas; Rect: TRect; Col: TIEMTextPos);
|
|
begin
|
|
// Not implemented in TImageEnMView
|
|
end;
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.ShowThumbnailHint
|
|
|
|
<FM>Declaration<FC>
|
|
property ShowThumbnailHint : Boolean;
|
|
|
|
<FM>Description<FN>
|
|
Automatically fills the control's <FC>Hint<FN> property with full details of the thumbnail under the cursor.
|
|
|
|
You can specify the hint display time using <A TIEImageEnGlobalSettings.CustomHintTimeout>
|
|
!!}
|
|
procedure TImageEnMView.SetShowThumbnailHint(const Value: Boolean);
|
|
begin
|
|
if fShowThumbnailHint <> Value then
|
|
begin
|
|
fShowThumbnailHint := Value;
|
|
if fShowThumbnailHint then
|
|
ShowHint := True
|
|
else
|
|
Hint := '';
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
{!!
|
|
<FS>TImageEnMView.FilenameToIndex
|
|
|
|
<FM>Declaration<FC>
|
|
function FilenameToIndex(const sFilename : string) : integer;
|
|
|
|
<FM>Description<FN>
|
|
Returns the index of the specified filename or -1 if the file does not exist in the list.
|
|
|
|
<FC>sFilename<FN> must be a full path (file folder and name).
|
|
|
|
<FM>Example<FC>
|
|
// Set caption of "Image.jpg" to "Cool Image"
|
|
idx := IEFolderMView.FilenameToIndex('C:\My Images\Image.jpg');
|
|
if idx >=0 then
|
|
IEFolderMView.ImageInfoText[idx].Caption := 'Cool Image';
|
|
|
|
!!}
|
|
function TImageEnMView.FilenameToIndex(const sFilename : string) : integer;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := -1;
|
|
if sFilename = '' then
|
|
exit;
|
|
|
|
for I := 0 to ImageCount - 1 do
|
|
begin
|
|
if SameText(ImageFilename[I], sFilename) then
|
|
begin
|
|
Result := I;
|
|
Break;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TImageEnMView.CMHintShow(var Message: TMessage);
|
|
begin
|
|
if ShowHint and fShowThumbnailHint then
|
|
TCMHintShow(Message).HintInfo^.HideTimeout := IEGlobalSettings().CustomHintTimeout;
|
|
end;
|
|
|
|
|
|
{$ELSE} // {$ifdef IEINCLUDEMULTIVIEW}
|
|
|
|
interface
|
|
implementation
|
|
|
|
{$ENDIF}
|
|
|
|
|
|
end.
|
|
|
|
|
|
|