Componentes.Terceros.Mustan.../official/1.7.0/EasyListview/Source/EasyListview.pas
david 778b05bf9f Importación inicial
- Mustangpeak Common Library - 1.7.0
  - EasyListview - 1.7.0

git-svn-id: https://192.168.0.254/svn/Componentes.Terceros.Mustangpeak@2 60b41242-d4b9-2247-b156-4ccd40706241
2007-09-11 08:33:06 +00:00

29102 lines
1010 KiB
ObjectPascal

unit EasyListview;
// Version 1.7.0
//
// The contents of this file are subject to the Mozilla Public License
// Version 1.1 (the "License"); you maynot use this file except in compliance
// with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
//
// Alternatively, you may redistribute this library, use and/or modify it under the terms of the
// GNU Lesser General Public License as published by the Free Software Foundation;
// either version 2.1 of the License, or (at your option) any later version.
// You may obtain a copy of the LGPL at http://www.gnu.org/copyleft/.
//
// Software distributed under the License is distributed on an "AS IS" basis,
// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the
// specific language governing rights and limitations under the License.
//
// The initial developer of this code is Jim Kueneman <jimdk@mindspring.com>
//
// Special thanks to the following in no particular order for their help/support/code
// Danijel Malik, Robert Lee, Werner Lehmann, Alexey Torgashin, Milan Vandrovec,
// Stanly Xu
//
// NOTES:
// 1) If new properties are added to the TCollectionItems and published they
// need to be manually written/read from the stream. The items are not automatically
// saved to the DFM file. This was because mimicing TCollectionItem was not
// practical do to the way the VCL was designed.
//----------------------------------------------------------------------------
interface
{$IFDEF TNTSUPPORT}
// IMPORTANT - PLEASE READ then comment this line out.
// If using TNT you MUST include the TNT package for your specific compiler in the
// Requires section of this package. It may be possible to compile without doing
// this but you WILL eventually have strange crashes in your application that will
// be difficult to understand. The best way to do this in my opinion is to create
// a new folder in the package install directory called "Delphi_TNT" (or CBuilder_TNT)
// and copy all the files from the Delphi (or CBuilder) folder into it. Now open the
// EasyListviewDx.dpk (or bpk) file in the "Delphi_TNT" (or CBuilder_TNT) based on your compiler
// version in a text editor. In the "Requires" section add "TNTUnicodeVcl_Rx0", where
// the "x" is the version of Delphi you are using. Open the dpk (bpk) file in your
// IDE. Select the menu option Projects>Options>Directories/Conditionals>Conditional
// and enter TNTSUPPORT. Compile the package, then open the EasyListviewDxD.dpk (or bpk)
// and compile and press the Install button.
// Now when you update the packages you won't have to redo all this. Just install
// the update then compile the packages in the "Delphi_TNT" (or CBuilder_TNT) folders
// an you are done.
{$ENDIF}
{$B-}
{$I Compilers.inc}
{$I ..\Include\Debug.inc}
{$I Options.inc}
{$I ..\Include\Addins.inc}
{.$DEFINE GXDEBUG}
{$IFDEF GXDEBUG}
{$DEFINE LOADGXUNIT}
{$ENDIF}
{$IFDEF GXDEBUG_PAINT}
{$DEFINE LOADGXUNIT}
{$ENDIF GXDEBUG_PAINT}
{$IFDEF GXDEBUG_HINT}
{$DEFINE LOADGXUNIT}
{$ENDIF GXDEBUG_HINT}
uses
{$IFDEF COMPILER_9_UP}
Types, // This MUST come before Windows
{$ENDIF}
{$IFDEF COMPILER_6_UP}
Variants,
{$ENDIF}
Windows,
Messages,
SysUtils,
Classes,
Graphics,
Controls,
{$IFDEF LOADGXUNIT}
DbugIntf,
{$ENDIF LOADGXUNIT}
{$IFDEF COMPILER_7_UP}
Themes,
UxTheme,
{$ELSE}
{$IFDEF USETHEMES}
TmSchema,
UxTheme,
{$ENDIF}
{$ENDIF}
ExtCtrls,
Forms,
ImgList,
CommCtrl,
ActiveX,
Menus,
StdCtrls,
{$IFDEF COMPILER_6_UP}
RTLConsts,
{$ELSE}
Consts,
{$ENDIF}
{$IFDEF SpTBX}
TBX,
SpTBXItem,
{$ENDIF}
{$IFDEF TNTSUPPORT}
TntStdCtrls,
{$ENDIF}
EasyLVResources,
MPCommonUtilities,
MPShellTypes,
MPDataObject,
MPCommonObjects,
MPThreadManager,
EasyTaskPanelForm;
{$R EasyRes.res}
const
EGT_FIRSTLETTER = $FFFF;
IID_IEasyCellEditor = '{A1686E7E-7F39-4BD4-BE1F-9C20D7BC6EA0}';
IID_IEasyCellEditorSink = '{C0AAA3C0-AC98-43C8-8D9A-376A3F64FAD2}';
IID_IEasyCaptions = '{6C838C0E-22A5-48D4-80C6-E266E950D3CF}';
IID_IEasyCaptionsEditable = '{F1403B00-7163-4FB7-804F-1A5500CD980A}';
IID_IEasyImageList = '{298932FB-A0AE-4A0A-BE34-A782743A0579}';
IID_IEasyStateImageList = '{F0202D63-92A7-4C2F-9CA4-CBDE4DE0ED30}';
IID_IEasyImages = '{20C419F5-F3DD-40C4-8526-88322E182C49}';
IID_IEasyImagesEditable = '{DC580B13-1D19-46BB-885F-FC5CE9B2BE66}' ;
IID_IEasyThumbnail = '{F9CA8297-0CB3-4C47-905F-3D1497C4FC4D}';
IID_IEasyCustomImage = '{00260055-6915-43B5-9D43-379E7F61EEA9}';
IID_IEasyDetails = '{AE1D21EB-BA52-4C24-9EB1-B35733299489}';
IID_IEasyDetailsEditable = '{BBD853F9-D803-4478-B5A8-EE02FF47DC80}';
IID_IEasyChecks = '{E8820F40-2EE3-4718-B54A-39318D2D1232}';
IID_IEasyNotficationSink = '{E4F0D3DE-B2BD-4EC0-B24B-8A9B85B23A63}';
IID_IEasyNotifier = '{F10150F9-17E3-43B6-8C05-33283FF1B14E}';
IID_IEasyCompare = '{0761D4F5-D451-4A6D-BFDC-B3000FFD0299}';
IID_IEasyDividerPersist = '{EE6C3C89-7FAE-46CD-AD30-6954B4308721}';
IID_IEasyGroupKey = '{2B87BB19-A133-4D43-9164-AC456747EB19}';
IID_IEasyGroupKeyEditable = '{26EFE2C6-2DE2-4795-94E3-0DB0CAA38B09}';
// EASYLISTVIEW_STREAM_VERSION = 4;
EASYLISTVIEW_STREAM_VERSION = 5; // Fixed bug in Streaming any other types then TEasyXXXXStored
STREAM_ID_KEY = $CEFEFF;
_AUTOSCROLLDELAY = 500; // 500 ms
_AUTOSCROLLTIME = 50; // ms
CURSOR_VHEADERSPLIT = 'VEASYHEADERSPLIT';
BITMAP_DEFAULTGROUPEXPANDED = 'DEFAULTEXPANDED';
BITMAP_DEFAULTGROUPCOLLAPSED = 'DEFAULTCOLLAPSED';
BITMAP_SORTARROWUP = 'SORTARROWUP';
BITMAP_SORTARROWDOWN = 'SORTARROWDOWN';
BITMAP_DEFAULTColumnGLYPHS = 'ColumnGLYPHS';
BITMAP_DEFAULTColumnGLYPHSBKGND = $00FF00FF;
SELECTION_OFFSET = 0.15; // The selection rectangle will select an item +/- x% of the Caption width (like M$ Listview)
WM_HOOKAPPACTIVATE = WM_APP + 204;
WM_EDITORRESIZE = WM_APP + 205;
WM_TABMOVEFOCUS = WM_APP + 206;
RESIZEHITZONEMARGIN = 4;
// LABEL_MARGIN = 2;
crVHeaderSplit = 768;
DEFAULT_GROUP_NAME = 'Default Group'; // group default name used if a first group is automatically created
EASYLISTVIEW_HEADER_CLIPFORMAT = 'EasyListview.Header';
// Magic, mystical stuff for CBuilder
(*$HPPEMIT 'namespace Easylistview {'*)
{$HPPEMIT 'class DELPHICLASS TEasyItem;'}
{$HPPEMIT 'class DELPHICLASS TEasyGroup;'}
{$HPPEMIT 'class DELPHICLASS TEasyColumn;'}
{$HPPEMIT 'struct TGroupSortInfoRec;'}
{$HPPEMIT '__interface IEasyNotificationSink;'}
(*$HPPEMIT '}'*)
type
TCustomEasyListview = class;
TEasyItems = class;
TEasyItem = class;
TEasyItemInterfaced = class;
TEasyViewItem = class;
TEasyGroups = class;
TEasyGroup = class;
TEasyViewGroup = class;
TEasyColumns = class;
TEasyColumn = class;
TEasyCollectionItem = class;
TCustomEasyDragManagerBase = class;
TEasyCellSize = class;
TEasyHeader = class;
TEasyCollection = class;
TEasyPaintInfoBasic = class;
TEasyHintInfo = class;
TEasyOLEDragManager = class;
TEasyHotTrackManager = class;
TEasyViewColumn = class;
TEasyHeaderDragManager = class;
TEasySortManager = class;
TEasyAlphaBlender = class;
TEasyPaintInfoBaseGroup = class;
TEasyColumnStored = class;
TEasyBaseEditor = class;
TEasyCollectionItemClass = class of TEasyCollectionItem;
TEasyViewItemClass = class of TEasyViewItem;
TEasyViewColumnClass = class of TEasyViewColumn;
TEasyViewGroupClass = class of TEasyViewGroup;
TEasyGridGroupClass = class of TEasyGridGroup;
TEasyGroupClass = class of TEasyGroup;
TEasyItemClass = class of TEasyItem;
TEasyColumnClass = class of TEasyColumn;
TEasyColumnStoredClass = class of TEasyColumnStored;
TItemNextEnum = function(Item: TEasyItem): TEasyItem of object;
TItemEnumFirstLast = function: TEasyItem of object;
TRectArray = array of TRect;
TCommonMouseButtons = set of TCommonMouseButton;
TEasyItemArray = array of TEasyItem;
TEasyGroupArray = array of TEasyGroup;
TEasyColumnArray = array of TEasyColumn;
TEasyQueryDragResult = (
eqdrContinue, // The drag drop loop should contine
eqdrQuit, // The drag drop loop should end
eqdrDrop // The drag drop loop should drop the object where it is
);
TEasyCheckType = (
ectNone, // No Checks
ettNoneWithSpace, // No Checks but leave the space for the checkbox
ectBox, // Square Checkbox type checkbox
ectRadio // Round Radio button type checkbox
);
TEasyListStyle = (
elsIcon, // The Listview's Large Icon Mode
elsSmallIcon, // The Listview's Small Icon Mode
elsList, // The Listview's List Mode
elsReport, // The Listview's Report (Details) Mode
elsThumbnail, // The Listview's Thumbnail Mode
elsTile, // The Listview's Tile Mode
elsFilmStrip, // The Listview's FilmStrip Mode
elsGrid // The Listview's Grid Mode
);
TEasyGroupMarginEdge = (
egmeBackground, // Background of the entire Group
egmeTop, // Header of a Group
egmeBottom, // Footer of a Group
egmeLeft, // Left Margin area of a Group
egmeRight, // Right Margin area of a Group
egmeForeground // Foreground of the entire Group
);
TEasyHeaderType = (
ehtHeader, // Report view Header
ehtFooter // Report view Footer
);
TEasyHeaderButtonStyle = (
ehbsThick, // "Normal" raised button
ehbsFlat, // Flat style button
ehbsPlate, // Plate style button
ehbsThemed // Draw using current Activation Context theme
);
TEasyHeaderImagePosition = (
ehpLeft, // The image is to the left of the Text
ehpTop, // The image is to the Top of the Text
ehpRight, // The image is to the Right of the Text
ehpBottom // The image is to the Bottom of the Text
);
TEasySortDirection = (
esdNone,
esdAscending, // The sort is ascending
esdDescending // The sort is descending
);
TEasySortGlyphAlign = (
esgaLeft, // Column SortGlpyh placed to left of Caption
esgaRight // Column SortGlpyh placed to right of Caption
);
TEasyDragType = (
edtOLE, // OLE Dragging
edtVCL // VCL Dragging
);
TEasySelectionType = (
ecstSelect, // Select all objects
ecstUnSelect, // UnSelect all objects
ecstInvert // Invert the selection state of objects
);
TEasyColumnHitTestInfo = (
ectOnCheckbox, // Hit in the Checkbox
ectOnIcon, // Hit the icon
ectOnLabel, // Hit the Label
ectOnText // Hit in the current text in the label area
);
TEasyColumnHitTestInfoSet = set of TEasyColumnHitTestInfo;
TEasyHitInfoColumn = packed record
Column: TEasyColumn; // The object hit
HitInfo: TEasyColumnHitTestInfoSet; // Details of the hit
end;
TEasyGroupHitTestInfo = (
egtOnBand, // Hit the colored band
egtOnCheckbox, // Hit in the Checkbox
egtOnExpandButton, // Hit the ExpandButton
egtOnIcon, // Hit the icon
egtOnLabel, // Hit the Label
egtOnText, // Hit in the current text in the label area
egtOnHeader, // Hit in the header of the group
egtOnFooter, // Hit in the footer of the group
egtOnLeftMargin, // Hit in the Left Margin of the group
egtOnRightMargin // Hit in the Right Margin of the group
);
TEasyGroupHitTestInfoSet = set of TEasyGroupHitTestInfo;
TEasyDefaultWheelScroll = (
edwsHorz, // Mouse Wheel scrolls horizontal by default, vertical with shift pressed
edwsVert // Mouse Wheel scrolls vertical by default, horizontal with shift pressed
);
TEasyHitInfoGroup = packed record
Group: TEasyGroup; // The object hit
HitInfo: TEasyGroupHitTestInfoSet; // Details of the hit
end;
TEasyItemHitTestInfo = (
ehtStateIcon, // Hit the state icon
ehtOnIcon, // Hit the icon
ehtOnLabel, // Hit the label, the area available for the Text
ehtOnClickSelectBounds, // Hit the area defined as a selection area for a click
ehtOnDragSelectBounds, // Hit the area defined as a selection area for a drag select
ehtOnText, // Hit the area in the label that contains text
ehtOnCheck, // Hit the area where the check box is drawn
ehtOnEdit // Hit the area where the edit is started for the item
);
TEasyItemHitTestInfoSet = set of TEasyItemHitTestInfo;
TEasyHitInfoItem = packed record
Item: TEasyItem;
Group: TEasyGroup; // The group the object is in
Column: TEasyColumn; // The the Column hit (if applicable)
HitInfo: TEasyItemHitTestInfoSet; // Details of the hit
end;
// CAUTION ADD NEW STATES TO END TO PRESERVE STREAMING
TEasyStorageObjectState = (
esosChecked, // The object is checked
esosCheckPending, // The object has a check pending, the mouse has been pressed in the check area but not yet released
esosCheckHover, // The object has the mouse hovering over the checkbox (matters mostly themed)
esosClicking, // The object is being "clicked"
esosCut, // The object is being "cut"
esosDestroying, // The object is being destroyed
esosHilighted, // The object is currently hilighted, for an item this mean drop hilighed for a Column this means hot track hilighed
esosEnabled, // The object is enabled
esosFocused, // The object is focused, i.e. it will take the keyboard input
esosInitialized, // The object has been initialized
esosSelected, // The object is selected, i.e. it will be included for an operation on it
esosVisible, // The object is currently visible
esosHotTracking, // The object is currently in a hot track state
esosBold, // The object is in a Bold state
esosDropTarget, // The object is hilighted as a drop target
esosGhosted // The object image is drawn "ghosted" (blended with background)
);
TEasyStorageObjectStates = set of TEasyStorageObjectState;
TEasyGroupsState = (
egsRebuilding // GroupManager is rebuild the item layout
);
TEasyGroupsStates = set of TEasyGroupsState;
TEasySelectHitType = (
eshtClickSelect, // Test for a hit based on a mouse click
eshtDragSelect // Test for a hit based on a drag rectangle
);
TEasyCellRectType = (
ertBounds, // The bounds of the item minus the border
ertIcon, // The bounds of the icon image
ertLabel, // The bounds of the area dedicated to the text (will be static based on grid)
ertClickSelectBounds, // The bounds of the area dedicated to a click selection (usually the Text area)
ertDragSelectBounds, // The bounds of the area dedicated to a drag selection (depends on the view)
ertText, // The bounds of the text for the item (will be dynamic based on current text)
ertFullText // The bounds of the actual Complete text for the item independant of current state of control/item
);
TEasyImageSize = (
eisSmall, // Paint Small Images
eisLarge, // Paint Large Images
eisExtraLarge // Paint JumboImages
);
TEasyImageKind = (
eikNormal, // Normal image
eikOverlay, // Overlay for the Normal image
eikState // State image
);
TEasyDragManagerState = (
edmsDragging, // The Drag Manager is in the middle of a drag operation
edmsAutoScrolling // The Drag Manager is autoscrolling during a draw operation
);
TEasyDragManagerStates = set of TEasyDragManagerState;
TEasyControlState = (
ebcsLButtonDown, // The Left Mouse Button is down
ebcsRButtonDown, // The Right Mouse Button is down
ebcsMButtonDown, // The Middle Mouse Button is down
ebcsScrollButtonDown, // The scroll wheel is down
ebcsDragPending, // The mouse is down and we are ready to check for a drag of an object
ebcsDragging, // The control is in the middle of a dragging operation
ebcsVCLDrag, // The drag operation is a VCL drag
ebcsDragSelectPending, // The mouse is down and we are ready to check for a drag select
ebcsDragSelecting, // The control is in a drag selecting mode
ebcsThemesLoaded, // The control has loaded themes if avaiable
ebcsCheckboxClickPending, // The mouse is down over a checkbox and the box now has the attention of the mouse
ebcsGroupExpandPending,
ebcsHeaderCapture, // The Header area has captured the mouse
ebcsScrolling, // The control is scrolling
ebcsOLERegistered, // Registered for OLE Drag and Drop
ebcsCancelContextMenu // A right button drag drop should not show the context menu
);
TEasyControlStates = set of TEasyControlState;
TEasyHeaderState = (
ehsMouseCaptured, // The Header captured the mouse (drag column/row; resize column/row)
ehsResizing, // One of the columns/headers is resizing
ehsDragging, // One of the columns/headers is being dragged
ehsDragPending,
ehsClickPending, // One of the columns/headers was pressed and the mouse is being dragged around
ehsCheckboxClickPending,
ehsResizePending,
ehsLButtonDown,
ehsRButtonDown,
ehsMButtonDown
);
TEasyHeaderStates = set of TEasyHeaderState;
TEasyItemState = (
eisTextRectCached
);
TEasyItemStates = set of TEasyItemState;
TEasyRectArrayObject = packed record
LabelRect, // The bounds of the area dedicated to the text
// (will be static based on grid)
IconRect, // The bounds of the icon image
TextRect, // The bounds of the text for the item (will be
// dynamic based on current text)
// If TextRects is used then this is the Union of all
// the TextRects
// It will be calculated from LabelRect -2 pixels so that
// a Frame and a Focus Rect may be drawn around it and
// not extend past the Label Rect
CheckRect: TRect; // The rectangle used for the Checkbox of an item
BoundsRect, // The bounds of the item minus the border
ClickSelectBoundsRect, // The bounds of the area dedicated to a click
// selection (may be possible the area is not
// definable by a simple rectangle)
DragSelectBoundsRect, // The bounds of the area dedicated to a drag
// selection (may be possible the area is not
// definable by a simple rectangle)
FullTextRect: TRect; // The bounds of the largest rect of text that
// can be shown (Icon view when item has focus the
// entire text is shown, overlapping other items)
SelectionRect: TRect; // The bounds of the area that is painted in the
// hilighted selection color
FullFocusSelRect: TRect; // The bounds of the largest rect of selection that
// can be shown (Icon view when item has focus the
// entire text is shown, overlapping other items)
FocusChangeInvalidRect: TRect; // The Rectangle to Invalidate(True) if the item
// changes focus or selection
EditRect: TRect; // The rectangle used for the editor in Edit Mode
SortRect: TRect; // The rectangle used for the Sort Glyphs
StateRect: TRect; // The rectangle used for state images
TextRects: TRectArray; // Text rectangles for Details
ExpandButtonRect, // The rectangle available in the group for the Expand Button (Groups Only)
BandRect: TRect; // The rectangle available in the group for the Band stripe (Groups Only)
BackGndRect: TRect; // The background of the group minus the Margin area, includes the Border (Groups Only)
GroupRect: TRect; // The entire space the group occupies (Groups Only)
DropDownArrow: TRect; // The DropDown Button for Columns (Columns Only)
end;
TEasyRectArrayObjectArray = array of TEasyRectArrayObject;
TEasyMakeVisiblePos = (
emvTop, // Make visible with the top of the Client Window
emvMiddle, // Make visible with the middle of the Client Window
emvBottom, // Make visible with the bottom of the Client Window
emvAuto // Make visible and scroll based on if the item is above or below the current client window
);
TEasySearchDirection = (
esdForward,
esdBackward
);
TEasyAdjacentCellDir = (
acdLeft, // The cell that is to the left of a particular cell
acdRight, // The cell that is to the right of a particular cell
acdUp, // The cell that is above a particular cell
acdDown, // The cell that is below of a particular cell
acdPageDown, // The cell that is a single page down from a particular cell
acdPageUp // The cell that is a single page up from a particular cell
);
TEasyGridLayout = (
eglHorz, // The Grid is a Horizontal grid (scrolls horz sized to fit vert)
eglVert, // The Grid is a Vertical grid (scrolls vert, sized to fit horz)
eglGrid // The Grid can scroll either way (may not fit client window either way)
);
TEasyHintType = (
ehtText, // Shows the hint in the passed text parameter
ehtToolTip, // Shows entire caption text if it does not fit in the assigned caption area
ehtCustomDraw // The hint will callback when it needs drawing
);
PEasyHintInfoRec = ^TEasyHintInfoRec;
// The actual record is below due to a BDS C++ bug in generating the hpp file
TEasySortAlgorithm = (
esaQuickSort,
esaBubbleSort,
esaMergeSort
);
TEasyIncrementalSearchState = (
eissTimerRunning, // The Search timeout timer is running
eissSearching // Currently in a Search mode
);
TEasyIncrementalSearchStates = set of TEasyIncrementalSearchState;
TCoolIncrementalSearchStart = (
eissStartOver, // Always start a search from the beginning of the list
eissLastHit, // Start search from the last node found in the incremental search
eissFocusedNode // Start search from current focused node
);
TEasyIncrementalSearchItemType = (
eisiAll, // Search All items in list
eisiInitializedOnly, // Search only items with their initialized property set, this will include collapsed groups but not invisible groups
eisiVisible // Search only items with their visible property set, this will include collapsed groups but not invisible groups
);
TEasyIncrementalSearchDir = (
eisdForward, // Search Forward in the list
eisdBackward // Search Backward in the list
);
TEasyNextItemType = (
enitAny,
enitVisible,
enitInitialized,
enitVisibleInExpandedGroup,
enitEditable // Implies visible
);
TEasyScrollbarDir = (
esdVertical,
esdHorizontal,
esdBoth
);
TEasyHotTrackState = (
ehsEnable, // object becoming a hot track target
ehsDisable // object losing a hot track status
);
TEasyHotTrackRectItem = (
htiIcon, // Hot track is defined on the image
htiText, // Hot track is defined on the Text
htiAnyWhere // Hot track is defined on the entire cell
);
TEasyHotTrackRectItems = set of TEasyHotTrackRectItem;
TEasyHotTrackRectGroup = (
htgIcon, // Hot track is defined on the image
htgText, // Hot track is defined on the Text
htgTopMargin, // Hot track is defined on the Top Group Margin
htgBottomMargin,// Hot track is defined on the Bottom Group Margin
htgLeftMargin, // Hot track is defined on the Left Group Margin
htgRightMargin, // Hot track is defined on the Right Group Margin
htgAnyWhere // Hot track is defined on the entire cell
);
TEasyHotTrackRectGroups = set of TEasyHotTrackRectGroup;
TEasyHotTrackRectColumn = (
htcIcon, // Hot track is defined on the image
htcText, // Hot track is defined on the Text
htcAnyWhere // Hot track is defined on the entire cell
);
TEasyHotTrackRectColumns = set of TEasyHotTrackRectColumn;
// ****************************************************************
// Intefaces that EasyListview is aware of such that user data may implement these
// interfaces to present the data necessary for the control
// ****************************************************************
// Implements the read only Caption for the Control
IEasyCaptions = interface(IUnknown)
[IID_IEasyCaptions]
function GetCaption(Column: Integer): Variant;
property Captions[Column: Integer]: Variant read GetCaption;
end;
// Implements the Caption for the Control
IEasyCaptionsEditable = interface(IEasyCaptions)
[IID_IEasyCaptionsEditable]
function SetCaption(Column: Integer; const Value: Variant): Boolean;
end;
// Implements a custom ImageList on a per item/column basis for the Control
IEasyImageList = interface(IUnknown)
[IID_IEasyImageList]
function GetImageList(Column: Integer; IconSize: TEasyImageSize): TCustomImageList;
property ImageList[Column: Integer; IconSize: TEasyImageSize]: TCustomImageList read GetImageList;
end;
// Implements a custom State ImageList on a per item/column basis for the Control
IEasyStateImageList = interface(IUnknown)
[IID_IEasyStateImageList]
function GetImageList(Column: Integer): TCustomImageList;
property ImageList[Column: Integer]: TCustomImageList read GetImageList;
end;
// Implements the read only ImageIndex for the Control
IEasyImages = interface(IUnknown)
[IID_IEasyImages]
function GetImageIndex(Column: Integer; ImageKind: TEasyImageKind): Integer;
property ImageIndexes[Column: Integer; ImageKind: TEasyImageKind]: Integer read GetImageIndex;
end;
// Implements the ImageIndex for the Control
IEasyImagesEditable = interface(IEasyImages)
[IID_IEasyImagesEditable]
procedure SetImageIndex(Column: Integer; ImageKind: TEasyImageKind; const Value: Integer);
property ImageIndexes[Column: Integer; ImageKind: TEasyImageKind]: Integer read GetImageIndex write SetImageIndex;
end;
// Implements the Thumbnail (Bitmap) for the Control
IEasyThumbnail = interface(IUnknown)
[IID_IEasyThumbnail]
procedure ThumbnailDraw(ACanvas: TCanvas; ViewportRect: TRect; AlphaBlender: TEasyAlphaBlender; var DoDefault: Boolean);
end;
IEasyCustomImage = interface(IUnknown)
[IID_IEasyCustomImage]
procedure CustomDrawn(Column: TEasyColumn; var IsCustom: Boolean);
procedure DrawImage(Column: TEasyColumn; ACanvas: TCanvas; const RectArray: TEasyRectArrayObject; AlphaBlender: TEasyAlphaBlender);
procedure GetSize(Column: TEasyColumn; var ImageW, ImageH: Integer);
end;
// Implements the Tile Details for the Control
// Points to what Column to get the detail from
IEasyDetails = interface(IUnknown)
[IID_IEasyDetails]
function GetDetailCount: Integer;
function GetDetail(Line: Integer): Integer; // Return the Column to be used as the detail for the given line
property Detail[Line: Integer]: Integer read GetDetail;
property DetailCount: Integer read GetDetailCount;
end;
IEasyDetailsEditable = interface(IEasyDetails)
[IID_IEasyDetailsEditable]
procedure SetDetail(Line: Integer; Value: Integer);
procedure SetDetailCount(Value: Integer);
property Detail[Line: Integer]: Integer read GetDetail write SetDetail;
property DetailCount: Integer read GetDetailCount write SetDetailCount;
end;
// Implements the CheckState for the Control
IEasyChecks = interface(IUnknown)
[IID_IEasyChecks]
function GetChecked(Column: Integer): Boolean;
procedure SetChecked(Column: Integer; const Value: Boolean);
property Checked[Column: Integer]: Boolean read GetChecked write SetChecked;
end;
IEasyGroupKey = interface(IUnknown)
[IID_IEasyGroupKey]
function GetKey(FocusedColumn: Integer): LongWord;
property Key[FocusedColumn: Integer]: LongWord read GetKey; // Uniquely identifies the item in a particular group
end;
IEasyGroupKeyEditable = interface(IEasyGroupKey)
[IID_IEasyGroupKeyEditable]
procedure SetKey(FocusedColumn: Integer; Value: LongWord);
property Key[FocusedColumn: Integer]: LongWord read GetKey write SetKey;
end;
IEasyNotificationSink = interface(IUnknown)
[IID_IEasyNotficationSink]
procedure InvalidateItem(ImmediateRefresh: Boolean);
procedure UnRegister;
end;
IEasyNotifier = interface(IUnknown)
[IID_IEasyNotifier]
procedure OnRegisterNotify(const ANotifier: IEasyNotificationSink);
procedure OnUnRegisterNotify(const ANotifier: IEasyNotificationSink);
end;
IEasyCompare = interface
[IID_IEasyCompare]
function Compare(const Data: IUnknown; Column: TEasyColumn): Integer;
end;
// Interface for the EasyControl to communicate with a Cells Editor
IEasyCellEditor = interface(IUnknown)
[IID_IEasyCellEditor]
function AcceptEdit: Boolean;
function GetHandle: HWnd;
function GetModified: Boolean;
procedure ControlWndHookProc(var Message: TMessage);
procedure Hide;
procedure Initialize(AnItem: TEasyItem; Column: TEasyColumn);
procedure Finalize;
function PtInEditControl(WindowPt: TPoint): Boolean;
procedure SetEditorFocus;
procedure SelectAll;
procedure Show;
property Handle: HWnd read GetHandle;
property Modified: Boolean read GetModified;
end;
// ***************************************
// Event callback Definitions
// ***************************************
TAfterPaintEvent = procedure(Sender: TCustomEasyListview; ACanvas: TCanvas; ClipRect: TRect) of object;
TAutoGroupGetKeyEvent = procedure(Sender: TCustomEasyListview; Item: TEasyItem; ColumnIndex: Integer; Groups: TEasyGroups; var Key: LongWord) of object;
TAutoSortGroupCreateEvent = procedure(Sender: TCustomEasyListview; Item: TEasyItem; ColumnIndex: Integer; Groups: TEasyGroups; var Group: TEasyGroup; var DoDefaultAction: Boolean) of object;
TEasyClipboardEvent = procedure(Sender: TCustomEasyListview; var Handled: Boolean) of object;
TEasyClipboardCutEvent = procedure(Sender: TCustomEasyListview; var MarkAsCut, Handled: Boolean) of object;
TColumnCheckChangeEvent = procedure(Sender: TCustomEasyListview; Column: TEasyColumn) of object;
TColumnCheckChangingEvent = procedure(Sender: TCustomEasyListview; Column: TEasyColumn; var Allow: Boolean) of object;
TColumnClickEvent = procedure(Sender: TCustomEasyListview; Button: TCommonMouseButton; const Column: TEasyColumn) of object;
TColumnContextMenuEvent = procedure(Sender: TCustomEasyListview; HitInfo: TEasyHitInfoColumn; WindowPoint: TPoint; var Menu: TPopupMenu) of object;
// TColumnCreatePaintInfoEvent = procedure(Sender: TCustomEasyListview; var PaintInfo: TEasyColumnPaintInfo) of object;
TColumnDblClickEvent = procedure(Sender: TCustomEasyListview; Button: TCommonMouseButton; MousePos: TPoint; const Column: TEasyColumn) of object;
TColumnDropDownButtonClickEvent = procedure(Sender: TCustomEasyListview; Column: TEasyColumn; Button: TCommonMouseButton; ShiftState: TShiftState; WindowPt: TPoint; var DoDefault: Boolean) of object;
TColumnEnableChangeEvent = procedure(Sender: TCustomEasyListview; Column: TEasyColumn) of object;
TColumnEnableChangingEvent = procedure(Sender: TCustomEasyListview; Column: TEasyColumn; var Allow: Boolean) of object;
TColumnFocusChangeEvent = procedure(Sender: TCustomEasyListview; Column: TEasyColumn) of object;
TColumnFocusChangingEvent = procedure(Sender: TCustomEasyListview; Column: TEasyColumn; var Allow: Boolean) of object;
TColumnFreeingEvent = procedure(Sender: TCustomEasyListview; Column: TEasyColumn) of object;
TColumnGetCaptionEvent = procedure(Sender: TCustomEasyListview; Column: TEasyColumn; Line: Integer; var Caption: WideString) of object;
TColumnGetImageIndexEvent = procedure(Sender: TCustomEasyListview; Column: TEasyColumn; ImageKind: TEasyImageKind; var ImageIndex: TCommonImageIndexInteger) of object;
TColumnGetImageListEvent = procedure(Sender: TCustomEasyListview; Column: TEasyColumn; var ImageList: TCustomImageList) of object;
TColumnGetDetailCountEvent = procedure(Sender: TCustomEasyListview; Column: TEasyColumn; var Count: Integer) of object;
TColumnImageDrawEvent = procedure(Sender: TCustomEasyListview; Column: TEasyColumn; ACanvas: TCanvas; const RectArray: TEasyRectArrayObject; AlphaBlender: TEasyAlphaBlender) of object;
TColumnImageGetSizeEvent = procedure(Sender: TCustomEasyListview; Column: TEasyColumn; var ImageWidth, ImageHeight: Integer) of object;
TColumnImageDrawIsCustomEvent = procedure(Sender: TCustomEasyListview; Column: TEasyColumn; var IsCustom: Boolean) of object;
TColumnGetDetailEvent = procedure(Sender: TCustomEasyListview; Column: TEasyColumn; Line: Integer; var Detail: Integer) of object;
TColumnInitializeEvent = procedure(Sender: TCustomEasyListview; Column: TEasyColumn) of object;
TColumnPaintTextEvent = procedure(Sender: TCustomEasyListview; Column: TEasyColumn; ACanvas: TCanvas) of object;
TEasyColumnLoadFromStreamEvent = procedure(Sender: TCustomEasyListview; Column: TEasyColumn; S: TStream; Version: Integer) of object;
TEasyColumnSaveToStreamEvent = procedure(Sender: TCustomEasyListview; Column: TEasyColumn; S: TStream; Version: Integer) of object;
TColumnSelectionChangeEvent = procedure(Sender: TCustomEasyListview; Column: TEasyColumn) of object;
TColumnSelectionChangingEvent = procedure(Sender: TCustomEasyListview; Column: TEasyColumn; var Allow: Boolean) of object;
TColumnSetCaptionEvent = procedure(Sender: TCustomEasyListview; Column: TEasyColumn; Caption: WideString) of object;
TColumnSetImageIndexEvent = procedure(Sender: TCustomEasyListview; Column: TEasyColumn; ImageKind: TEasyImageKind; ImageIndex: Integer) of object;
TColumnSetDetailEvent = procedure(Sender: TCustomEasyListview; Column: TEasyColumn; Line: Integer; const Detail: Integer) of object;
TColumnSizeChangingEvent = procedure(Sender: TCustomEasyListview; Column: TEasyColumn; Width, NewWidth: Integer; var Allow: Boolean) of object;
TColumnSizeChangedEvent = procedure(Sender: TCustomEasyListview; Column: TEasyColumn) of object;
TColumnThumbnailDrawEvent = procedure(Sender: TCustomEasyListview; Column: TEasyColumn; ACanvas: TCanvas; ARect: TRect; var DoDefault: Boolean) of object;
TColumnVisibilityChangeEvent = procedure(Sender: TCustomEasyListview; Column: TEasyColumn) of object;
TColumnVisibilityChangingEvent = procedure(Sender: TCustomEasyListview; Column: TEasyColumn; var Allow: Boolean) of object;
TContextMenuEvent = procedure(Sender: TCustomEasyListview; MousePt: TPoint; var Handled: Boolean) of object;
TColumnCustomViewEvent = procedure(Sender: TCustomEasyListview; Column: TEasyColumn; var View: TEasyViewColumnClass) of object;
TCustomGridEvent = procedure(Sender: TCustomEasyListview; Group: TEasyGroup; ViewStyle: TEasyListStyle; var Grid: TEasyGridGroupClass) of object;
TDblClickEvent = procedure(Sender: TCustomEasyListview; Button: TCommonMouseButton; MousePos: TPoint; ShiftState: TShiftState) of object;
TGetDragImageEvent = procedure(Sender: TCustomEasyListview; Image: TBitmap; DragStartPt: TPoint; var HotSpot: TPoint; var TransparentColor: TColor; var Handled: Boolean) of object;
TEasyGestureEvent = procedure(Sender: TCustomEasyListview; Gesture: WideString; var DoDefaultMouseAction: Boolean) of object;
TGroupClickEvent = procedure(Sender: TCustomEasyListview; Group: TEasyGroup; KeyStates: TCommonKeyStates; HitTest: TEasyGroupHitTestInfoSet) of object;
TGroupCollapseEvent = procedure(Sender: TCustomEasyListview; Group: TEasyGroup) of object;
TGroupCollapsingEvent = procedure(Sender: TCustomEasyListview; Group: TEasyGroup; var Allow: Boolean) of object;
TGroupCompareEvent = function(Sender: TCustomEasyListview; Item1, Item2: TEasyGroup): Integer of object;
TGroupContextMenuEvent = procedure(Sender: TCustomEasyListview; HitInfo: TEasyHitInfoGroup; WindowPoint: TPoint; var Menu: TPopupMenu; var Handled: Boolean) of object;
TGroupCustomViewEvent = procedure(Sender: TCustomEasyListview; Group: TEasyGroup; ViewStyle: TEasyListStyle; var View: TEasyViewGroupClass) of object;
TGroupDblClickEvent = procedure(Sender: TCustomEasyListview; Button: TCommonMouseButton; MousePos: TPoint; HitInfo: TEasyHitInfoGroup) of object;
TGroupExpandEvent = procedure(Sender: TCustomEasyListview; Group: TEasyGroup) of object;
TGroupExpandingEvent = procedure(Sender: TCustomEasyListview; Group: TEasyGroup; var Allow: Boolean) of object;
TGroupFocusChangeEvent = procedure(Sender: TCustomEasyListview; Group: TEasyGroup) of object;
TGroupFocusChangingEvent = procedure(Sender: TCustomEasyListview; Group: TEasyGroup; var Allow: Boolean) of object;
TGroupFreeingEvent = procedure(Sender: TCustomEasyListview; Group: TEasyGroup) of object;
TGroupGetCaptionEvent = procedure(Sender: TCustomEasyListview; Group: TEasyGroup; var Caption: WideString) of object;
TGroupGetClassEvent = procedure(Sender: TCustomEasyListview; var GroupClass: TEasyCollectionItemClass) of object;
TGroupGetImageIndexEvent = procedure(Sender: TCustomEasyListview; Group: TEasyGroup; ImageKind: TEasyImageKind; var ImageIndex: TCommonImageIndexInteger) of object;
TGroupGetImageListEvent = procedure(Sender: TCustomEasyListview; Group: TEasyGroup; var ImageList: TCustomImageList) of object;
TGroupGetDetailCountEvent = procedure(Sender: TCustomEasyListview; Group: TEasyGroup; var Count: Integer) of object;
TGroupImageDrawEvent = procedure(Sender: TCustomEasyListview; Group: TEasyGroup; ACanvas: TCanvas; const RectArray: TEasyRectArrayObject; AlphaBlender: TEasyAlphaBlender) of object;
TGroupImageGetSizeEvent = procedure(Sender: TCustomEasyListview; Group: TEasyGroup; var ImageWidth, ImageHeight: Integer) of object;
TGroupImageDrawIsCustomEvent = procedure(Sender: TCustomEasyListview; Group: TEasyGroup; var IsCustom: Boolean) of object;
TGroupGetDetailEvent = procedure(Sender: TCustomEasyListview; Group: TEasyGroup; Line: Integer; var Detail: Integer) of object;
TGroupInitializeEvent = procedure(Sender: TCustomEasyListview; Group: TEasyGroup) of object;
TGroupHotTrackEvent = procedure(Sender: TCustomEasyListview; Group: TEasyGroup; State: TEasyHotTrackState; MousePos: TPoint) of object;
TGroupLoadFromStreamEvent = procedure(Sender: TCustomEasyListview; Group: TEasyGroup; S: TStream; Version: Integer) of object;
TGroupPaintTextEvent = procedure(Sender: TCustomEasyListview; Group: TEasyGroup; ACanvas: TCanvas) of object;
TGroupSaveToStreamEvent = procedure(Sender: TCustomEasyListview; Group: TEasyGroup; S: TStream; Version: Integer) of object;
TGroupSetCaptionEvent = procedure(Sender: TCustomEasyListview; Group: TEasyGroup; Caption: WideString) of object;
TGroupSetImageIndexEvent = procedure(Sender: TCustomEasyListview; Group: TEasyGroup; ImageKind: TEasyImageKind; ImageIndex: Integer) of object;
TGroupSetDetailEvent = procedure(Sender: TCustomEasyListview; Group: TEasyGroup; Line: Integer; const Detail: Integer) of object;
TGroupSelectionChangeEvent = procedure(Sender: TCustomEasyListview; Group: TEasyGroup) of object;
TGroupSelectionChangingEvent = procedure(Sender: TCustomEasyListview; Group: TEasyGroup; var Allow: Boolean) of object;
TGroupThumbnailDrawEvent = procedure(Sender: TCustomEasyListview; Group: TEasyGroup; ACanvas: TCanvas; ARect: TRect; AlphaBlender: TEasyAlphaBlender; var DoDefault: Boolean) of object;
TGroupVisibilityChangeEvent = procedure(Sender: TCustomEasyListview; Group: TEasyGroup) of object;
TGroupVisibilityChangingEvent = procedure(Sender: TCustomEasyListview; Group: TEasyGroup; var Allow: Boolean) of object;
THintCustomDrawEvent = procedure(Sender: TCustomEasyListview; TargetObj: TEasyCollectionItem; const Info: TEasyHintInfo) of object;
THintCustomizeInfoEvent = procedure(Sender: TCustomEasyListview; TargetObj: TEasyCollectionItem; Info: TEasyHintInfo) of object;
THintPauseTimeEvent = procedure(Sender: TCustomEasyListview; HintWindowShown: Boolean; var PauseDelay: Integer) of object;
THintPopupEvent = procedure(Sender: TCustomEasyListview; TargetObj: TEasyCollectionItem; HintType: TEasyHintType; MousePos: TPoint; var AText: WideString; var HideTimeout, ReShowTimeout: Integer; var Allow: Boolean) of object;
THeaderClickEvent = procedure(Sender: TCustomEasyListview; MouseButton: TCommonMouseButton; Column: TEasyColumn) of object;
THeaderDblClickEvent = procedure(Sender: TCustomEasyListview; MouseButton: TCommonMouseButton; MousePos: TPoint; ShiftState: TShiftState) of object;
THeaderMouseEvent = procedure(Sender: TCustomEasyListview; MouseButton: TCommonMouseButton; Shift: TShiftState; X, Y: Integer; Column: TEasyColumn) of object;
TIncrementalSearchEvent = procedure(Item: TEasyCollectionItem; const SearchBuffer: WideString; var Handled: Boolean; var CompareResult: Integer) of object;
TItemCheckChangeEvent = procedure(Sender: TCustomEasyListview; Item: TEasyItem) of object;
TItemCheckChangingEvent = procedure(Sender: TCustomEasyListview; Item: TEasyItem; var Allow: Boolean) of object;
TItemClickEvent = procedure(Sender: TCustomEasyListview; Item: TEasyItem; KeyStates: TCommonKeyStates; HitInfo: TEasyItemHitTestInfoSet) of object;
TItemCompareEvent = function(Sender: TCustomEasyListview; Column: TEasyColumn; Group: TEasyGroup; Item1, Item2: TEasyItem; var DoDefault: Boolean): Integer of object;
TItemContextMenuEvent = procedure(Sender: TCustomEasyListview; HitInfo: TEasyHitInfoItem; WindowPoint: TPoint; var Menu: TPopupMenu; var Handled: Boolean) of object;
TItemCreateEditorEvent = procedure(Sender: TCustomEasyListview; Item: TEasyItem; var Editor: IEasyCellEditor) of object;
TItemCustomViewEvent = procedure(Sender: TCustomEasyListview; Item: TEasyItem; ViewStyle: TEasyListStyle; var View: TEasyViewItemClass) of object;
TItemLoadFromStreamEvent = procedure(Sender: TCustomEasyListview; Item: TEasyItem; S: TStream; Version: Integer) of object;
TItemSaveToStreamEvent = procedure(Sender: TCustomEasyListview; Item: TEasyItem; S: TStream; Version: Integer) of object;
TItemDblClickEvent = procedure(Sender: TCustomEasyListview; Button: TCommonMouseButton; MousePos: TPoint; HitInfo: TEasyHitInfoItem) of object;
TItemEditBegin = procedure(Sender: TCustomEasyListview; Item: TEasyItem; var Column: Integer; var Allow: Boolean) of object;
TItemEditedEvent = procedure(Sender: TCustomEasyListview; Item: TEasyItem; var NewValue: Variant; var Accept: Boolean) of object;
TItemEditEnd = procedure(Sender: TCustomEasyListview; Item: TEasyItem) of object;
TItemEnableChangeEvent = procedure(Sender: TCustomEasyListview; Item: TEasyItem) of object;
TItemEnableChangingEvent = procedure(Sender: TCustomEasyListview; Item: TEasyItem; var Allow: Boolean) of object;
TItemFreeingEvent = procedure(Sender: TCustomEasyListview; Item: TEasyItem) of object;
TItemFocusChangeEvent = procedure(Sender: TCustomEasyListview; Item: TEasyItem) of object;
TItemFocusChangingEvent = procedure(Sender: TCustomEasyListview; Item: TEasyItem; var Allow: Boolean) of object;
TItemGetStreamingCreateClassEvent = procedure(Sender: TCustomEasyListview; var AClass: TEasyColumnStoredClass) of object;
TItemGetCaptionEvent = procedure(Sender: TCustomEasyListview; Item: TEasyItem; Column: Integer; var Caption: WideString) of object;
TEasyItemGetCaptionEvent = procedure(Sender: TCustomEasyListview; Item: TEasyItem; Column: TEasyColumn; var Caption: WideString) of object;
TItemGetEditMenuEvent = procedure(Sender: TCustomEasyListview; Editor: TEasyBaseEditor; var Menu: TPopupMenu) of object;
TItemGetClassEvent = procedure(Sender: TCustomEasyListview; var ItemClass: TEasyCollectionItemClass) of object;
TItemGetGroupKeyEvent = procedure(Sender: TCustomEasyListview; Item: TEasyItem; FocusedColumn: Integer; var GroupKey: LongWord) of object;
TItemGetImageIndexEvent = procedure(Sender: TCustomEasyListview; Item: TEasyItem; Column: Integer; ImageKind: TEasyImageKind; var ImageIndex: TCommonImageIndexInteger) of object;
TItemGetImageListEvent = procedure(Sender: TCustomEasyListview; Item: TEasyItem; Column: Integer; var ImageList: TCustomImageList) of object;
TEasyGetTaskPanelEvent = procedure(Sender: TCustomEasyListview; Group: TEasyGroup; var TaskPanel: TEasyTaskPanelFormClass) of object;
TItemGetTileDetailCountEvent = procedure(Sender: TCustomEasyListview; Item: TEasyItem; var Count: Integer) of object;
TItemImageDrawEvent = procedure(Sender: TCustomEasyListview; Item: TEasyItem; Column: TEasyColumn; ACanvas: TCanvas; const RectArray: TEasyRectArrayObject; AlphaBlender: TEasyAlphaBlender) of object;
TItemImageGetSizeEvent = procedure(Sender: TCustomEasyListview; Item: TEasyItem; Column: TEasyColumn; var ImageWidth, ImageHeight: Integer) of object;
TItemImageDrawIsCustomEvent = procedure(Sender: TCustomEasyListview; Item: TEasyItem; Column: TEasyColumn; var IsCustom: Boolean) of object;
TItemGetTileDetailEvent = procedure(Sender: TCustomEasyListview; Item: TEasyItem; Line: Integer; var Detail: Integer) of object;
TItemHotTrackEvent = procedure(Sender: TCustomEasyListview; Item: TEasyItem; State: TEasyHotTrackState; MousePos: TPoint) of object;
TItemInitializeEvent = procedure(Sender: TCustomEasyListview; Item: TEasyItem) of object;
TItemMouseDownEvent = procedure(Sender: TCustomEasyListview; Item: TEasyItem; Button: TCommonMouseButton; var DoDefault: Boolean) of object;
TItemMouseUpEvent = procedure(Sender: TCustomEasyListview; Item: TEasyItem; Button: TCommonMouseButton; var DoDefault: Boolean) of object;
TItemPaintTextEvent = procedure(Sender: TCustomEasyListview; Item: TEasyItem; Position: Integer; ACanvas: TCanvas) of object;
TItemSelectionChangeEvent = procedure(Sender: TCustomEasyListview; Item: TEasyItem) of object;
TItemSelectionChangingEvent = procedure(Sender: TCustomEasyListview; Item: TEasyItem; var Allow: Boolean) of object;
TEasyItemSelectionsChangedEvent = procedure(Sender: TCustomEasyListview) of object;
TItemSetCaptionEvent = procedure(Sender: TCustomEasyListview; Item: TEasyItem; Column: Integer; Caption: WideString) of object;
TItemSetGroupKeyEvent = procedure(Sender: TCustomEasyListview; Item: TEasyItem; Column: Integer; Key: LongWord) of object;
TItemSetImageIndexEvent = procedure(Sender: TCustomEasyListview; Item: TEasyItem; Column: Integer; ImageKind: TEasyImageKind; ImageIndex: Integer) of object;
TItemSetTileDetailEvent = procedure(Sender: TCustomEasyListview; Item: TEasyItem; Line: Integer; const Detail: Integer) of object;
TItemThumbnailDrawEvent = procedure(Sender: TCustomEasyListview; Item: TEasyItem; ACanvas: TCanvas; ARect: TRect; AlphaBlender: TEasyAlphaBlender; var DoDefault: Boolean) of object;
TItemVisibilityChangeEvent = procedure(Sender: TCustomEasyListview; Item: TEasyItem) of object;
TItemVisibilityChangingEvent = procedure(Sender: TCustomEasyListview; Item: TEasyItem; var Allow: Boolean) of object;
TEasyKeyActionEvent = procedure(Sender: TCustomEasyListview; var CharCode: Word; var Shift: TShiftState; var DoDefault: Boolean) of object;
TOLEDropSourceDragEndEvent = procedure(Sender: TCustomEasyListview; ADataObject: IDataObject; DragResult: TCommonOLEDragResult; ResultEffect: TCommonDropEffects; KeyStates: TCommonKeyStates) of object;
TOLEDropSourceDragStartEvent = procedure(Sender: TCustomEasyListview; ADataObject: IDataObject; var AvailableEffects: TCommonDropEffects; var AllowDrag: Boolean) of object;
TOLEDropSourceQueryContineDragEvent = procedure(Sender: TCustomEasyListview; EscapeKeyPressed: Boolean; KeyStates: TCommonKeyStates; var QueryResult: TEasyQueryDragResult) of object;
TOLEDropSourceGiveFeedbackEvent = procedure(Sender: TCustomEasyListview; Effect: TCommonDropEffects; var UseDefaultCursors: Boolean) of object;
TOLEDropTargetDragEnterEvent = procedure(Sender: TCustomEasyListview; DataObject: IDataObject; KeyState: TCommonKeyStates; WindowPt: TPoint; AvailableEffects: TCommonDropEffects; var DesiredDropEffect: TCommonDropEffect) of object;
TOLEDropTargetDragOverEvent = procedure(Sender: TCustomEasyListview; KeyState: TCommonKeyStates; WindowPt: TPoint; AvailableEffects: TCommonDropEffects; var DesiredDropEffect: TCommonDropEffect) of object;
TOLEDropTargetDragLeaveEvent = procedure(Sender: TCustomEasyListview) of object;
TOLEDropTargetDragDropEvent = procedure(Sender: TCustomEasyListview; DataObject: IDataObject; KeyState: TCommonKeyStates; WindowPt: TPoint; AvailableEffects: TCommonDropEffects; var DesiredDropEffect: TCommonDropEffect; var Handled: Boolean) of object;
TOLEGetCustomFormatsEvent = procedure(Sender: TCustomEasyListview; var Formats: TFormatEtcArray) of object;
TOLEGetDataEvent = procedure(Sender: TCustomEasyListview; const FormatEtcIn: TFormatEtc; var Medium: TStgMedium; var Handled: Boolean) of object;
FOLEGetDataObjectEvent = procedure(Sender: TCustomEasyListview; var DataObject: IDataObject) of object;
TOLEQueryDataEvent = procedure(Sender: TCustomEasyListview; const FormatEtcIn: TFormatEtc; var FormatAvailable: Boolean; var Handled: Boolean) of object;
TPaintBkGndEvent = procedure(Sender: TCustomEasyListview; ACanvas: TCanvas; AWindowRect: TRect; AlphaBlender: TEasyAlphaBlender; var DoDefault: Boolean) of object;
TPaintHeaderBkGndEvent = procedure(Sender: TCustomEasyListview; ACanvas: TCanvas; ARect: TRect; var Handled: Boolean) of object;
TViewChangingEvent = procedure(Sender: TCustomEasyListview; View: TEasyListStyle; var Allow: Boolean) of object;
TViewChangedEvent = procedure(Sender: TCustomEasyListview) of object;
TEasyScrollEvent = procedure(Sender: TCustomEasyListview; DeltaX, DeltaY: Integer) of object;
TEasyDoGroupCompare = function(Column: TEasyColumn; Group1, Group2: TEasyGroup): Integer of object;
TEasyDoItemCompare = function(Column: TEasyColumn; Group: TEasyGroup; Item1, Item2: TEasyItem): Integer of object;
// **************************************************************************
// TEasyMemo
// A class that uses TntMemo when TNTSUPPORT is defined
// **************************************************************************
{$IFDEF TNTSUPPORT}
TEasyMemo = class(TTntMemo);
TEasyEdit = class(TTntEdit);
{$ELSE}
TEasyMemo = class(TMemo);
TEasyEdit = class(TEdit);
{$ENDIF}
// **************************************************************************
// TEasyInterfacedPersistent
// A class that makes a TPersistent class that is an interfaced object
// **************************************************************************
TEasyInterfacedPersistent = class(TPersistent, IUnknown, ICommonExtractObj)
private
FRefCount: Integer;
protected
// IUnknown
function _AddRef: Integer; virtual; stdcall;
function _Release: Integer; virtual; stdcall;
function QueryInterface(const IID: TGUID; out Obj): HResult; virtual; stdcall;
// IEasyExtractObj
function GetObj: TObject;
public
procedure AfterConstruction; override;
procedure BeforeDestruction; override;
class function NewInstance: TObject; override;
property Obj: TObject read GetObj;
property RefCount: Integer read FRefCount;
end;
// **************************************************************************
// TEasyOwnedInterfacedPersistent
// A class that makes an interfaced object that has knowledge of the
// TEasyOwnerListview
// **************************************************************************
TEasyOwnedInterfacedPersistent = class(TEasyInterfacedPersistent)
private
FOwner: TCustomEasyListview;
public
constructor Create(AnOwner: TCustomEasyListview); virtual;
property Owner: TCustomEasyListview read FOwner;
end;
// **************************************************************************
// TEasyPersistent
// **************************************************************************
TEasyPersistent = class(TPersistent)
public
constructor Create; virtual;
destructor Destroy; override;
procedure Assign(Source: TPersistent); override;
end;
// **************************************************************************
// TEasyOwnedPersistent
// Basis for Managers and objects that need a link back to the Main Window
// **************************************************************************
TEasyOwnedPersistent = class(TEasyPersistent)
private
FOwnerListview: TCustomEasyListview;
protected
function GetOwner: TPersistent; override;
public
constructor Create(AnOwner: TCustomEasyListview); reintroduce; virtual;
procedure LoadFromStream(S: TStream; Version: Integer = EASYLISTVIEW_STREAM_VERSION); virtual;
procedure SaveToStream(S: TStream; Version: Integer = EASYLISTVIEW_STREAM_VERSION); virtual;
property OwnerListview: TCustomEasyListview read FOwnerListview;
end;
TEasyCanvasStore = class
protected
FBrush: TBrush;
FFont: TFont;
FPen: TPen;
public
destructor Destroy; override;
procedure RestoreCanvasState(Canvas: TCanvas);
procedure StoreCanvasState(Canvas: TCanvas);
property Brush: TBrush read FBrush write FBrush;
property Font: TFont read FFont write FFont;
property Pen: TPen read FPen write FPen;
end;
// **************************************************************************
// TEasyOwnerPersistentView
// Basis for any class that will become a view
// **************************************************************************
TEasyOwnedPersistentView = class(TEasyOwnedPersistent)
private
FCanvasStore: TEasyCanvasStore;
function GetCanvasStore: TEasyCanvasStore;
protected
procedure PaintCheckboxCore(CheckType: TEasyCheckType; OwnerListView: TCustomEasyListView; ACanvas: TCanvas; ARect: TRect; IsEnabled, IsChecked, IsHot, IsFlat, IsHovering, IsPending: Boolean; Obj: TEasyCollectionItem; Size: Integer);
property CanvasStore: TEasyCanvasStore read GetCanvasStore write FCanvasStore;
public
destructor Destroy; override;
published
end;
// **************************************************************************
// TEasyAlphaBlender
// Helper for Alpha blending a canvas
// **************************************************************************
TEasyAlphaBlender = class(TEasyPersistent)
public
destructor Destroy; override;
procedure BasicBlend(Listview: TCustomEasyListview; ACanvas: TCanvas; ViewportRect: TRect; Color: TColor; Alpha: Byte = 128; UseScrollPostion: Boolean = True); virtual;
procedure Blend(Listview: TCustomEasyListview; Obj: TEasyCollectionItem; ACanvas: TCanvas; ViewportRect: TRect; Image: TBitmap); virtual;
procedure GetBlendParams(Listview: TCustomEasyListview; Obj: TEasyCollectionItem; var BlendAlpha: Byte; var BlendColor: TColor; var DoBlend: Boolean);
end;
// **************************************************************************
// TEasyOwnedPersistentGroupItem
// Basis for any class property of a TEasyGroup that allows communication
// back to the TEasyGroups
// **************************************************************************
TEasyOwnedPersistentGroupItem = class(TEasyOwnedPersistentView)
private
FOwnerGroup: TEasyGroup;
public
constructor Create(AnOwner: TEasyGroup); reintroduce; virtual;
property OwnerGroup: TEasyGroup read FOwnerGroup;
end;
TEasySelectionGroupList = class
private
FDisplayRect: TRect;
FFirstItem: TEasyItem;
FList: TList;
FRefCount: Integer;
protected
function GetItems(Index: Integer): TEasyItem;
procedure SetItems(Index: Integer; Value: TEasyItem);
property List: TList read FList write FList;
property RefCount: Integer read FRefCount write FRefCount;
public
constructor Create;
destructor Destroy; override;
function Count: Integer;
procedure Add(Item: TEasyItem);
procedure Clear;
procedure DecRef;
procedure IncRef;
property DisplayRect: TRect read FDisplayRect write FDisplayRect;
property FirstItem: TEasyItem read FFirstItem write FFirstItem;
property Items[Index: Integer]: TEasyItem read GetItems write SetItems; default;
end;
// **************************************************************************
// TEasyMargin
// Property for TEasyGroupItem to set the attributes of the Group Margins
// **************************************************************************
TEasyMargin = class(TEasyOwnedPersistent)
private
FSize: Integer;
FVisible: Boolean;
procedure SetSize(Value: Integer);
procedure SetVisible(Value: Boolean);
protected
function RuntimeSize: Integer;
public
constructor Create(AnOwner: TCustomEasyListview); override;
destructor Destroy; override;
procedure Assign(Source: TPersistent); override;
published
property Size: Integer read FSize write SetSize default 30;
property Visible: Boolean read FVisible write SetVisible default False;
end;
// **************************************************************************
// TEasyHeaderMargin
// Property for TEasyGroupItem to set the attributes of the Header Group Margin
// **************************************************************************
TEasyHeaderMargin = class(TEasyMargin)
public
constructor Create(AnOwner: TCustomEasyListview); override;
published
property Visible default True;
end;
// **************************************************************************
// TCustomEasyFooterMargin
// Property for TEasyGroupItem to set the attributes of the Group Margins
// **************************************************************************
TCustomEasyFooterMargin = class(TEasyMargin)
private
FCaption: WideString;
FImageIndex: TCommonImageIndexInteger;
FImageOverlayIndex: TCommonImageIndexInteger;
FPaintInfo: TEasyPaintInfoBaseGroup;
function GetAlignment: TAlignment;
function GetCaptionIndent: Integer;
function GetCaptionLines: Integer;
function GetImageIndent: Integer;
function GetPaintInfo: TEasyPaintInfoBaseGroup;
function GetVAlignment: TCommonVAlignment;
procedure SetAlignment(Value: TAlignment);
procedure SetCaption(Value: WideString);
procedure SetCaptionIndent(Value: Integer);
procedure SetCaptionLines(Value: Integer);
procedure SetImageIndent(Value: Integer);
procedure SetImageIndex(const Value: TCommonImageIndexInteger);
procedure SetImageOveralyIndex(const Value: TCommonImageIndexInteger);
procedure SetPaintInfo(const Value: TEasyPaintInfoBaseGroup);
procedure SetVAlignment(Value: TCommonVAlignment);
protected
property Alignment: TAlignment read GetAlignment write SetAlignment default taLeftJustify;
property Caption: WideString read FCaption write SetCaption;
property CaptionIndent: Integer read GetCaptionIndent write SetCaptionIndent default 2;
property CaptionLines: Integer read GetCaptionLines write SetCaptionLines default 1;
property ImageIndent: Integer read GetImageIndent write SetImageIndent default 2;
property ImageIndex: TCommonImageIndexInteger read FImageIndex write SetImageIndex default -1;
property ImageOverlayIndex: TCommonImageIndexInteger read FImageOverlayIndex write SetImageOveralyIndex default -1;
property PaintInfo: TEasyPaintInfoBaseGroup read GetPaintInfo write SetPaintInfo;
property Size default 30;
property VAlignment: TCommonVAlignment read GetVAlignment write SetVAlignment default cvaCenter;
public
constructor Create(AnOwner: TCustomEasyListview); override;
destructor Destroy; override;
procedure Assign(Source: TPersistent); override;
end;
TEasyFooterMarginCustomClass = class of TCustomEasyFooterMargin;
// **************************************************************************
// TEasyFooterMargin
// Default Footer Margin PaintInfo that is global to all Groups. Defined under
// the EasyListview.PaintInfoGroup.MarginBottom property
// **************************************************************************
TEasyFooterMargin = class(TCustomEasyFooterMargin)
published
property Alignment;
property Caption;
property CaptionIndent;
property CaptionLines;
property ImageIndent;
property ImageIndex;
property ImageOverlayIndex;
property Size default 30;
property VAlignment;
end;
// **************************************************************************
// TEasyPaintInfoBasic
// Basic information that defines how a particular UI object is Painted
// **************************************************************************
TEasyPaintInfoBasic = class(TEasyOwnedPersistent)
private
FAlignment: TAlignment;
FBorder: Integer;
FBorderColor: TColor;
FCaptionIndent: Integer;
FCaptionLines: Integer;
FCheckFlat: Boolean;
FCheckIndent: Integer;
FCheckSize: Integer;
FCheckType: TEasyCheckType;
FImageIndent: Integer;
FShowBorder: Boolean;
FVAlignment: TCommonVAlignment;
procedure SetAlignment(Value: TAlignment);
procedure SetBorder(Value: Integer);
procedure SetBorderColor(Value: TColor);
procedure SetCaptionIndent(Value: Integer);
procedure SetCaptionLines(Value: Integer);
procedure SetCheckFlat(Value: Boolean);
procedure SetCheckIndent(Value: Integer);
procedure SetCheckSize(Value: Integer);
procedure SetCheckType(Value: TEasyCheckType);
procedure SetImageIndent(Value: Integer);
procedure SetShowBorder(const Value: Boolean);
procedure SetVAlignment(Value: TCommonVAlignment);
protected
procedure Invalidate(ImmediateUpdate: Boolean); virtual;
property Alignment: TAlignment read FAlignment write SetAlignment default taLeftJustify;
property Border: Integer read FBorder write SetBorder default 4;
property BorderColor: TColor read FBorderColor write SetBorderColor default clHighlight;
property CaptionIndent: Integer read FCaptionIndent write SetCaptionIndent default 4;
property CaptionLines: Integer read FCaptionLines write SetCaptionLines default 1;
property CheckFlat: Boolean read FCheckFlat write SetCheckFlat default False;
property CheckIndent: Integer read FCheckIndent write SetCheckIndent default 2;
property CheckSize: Integer read FCheckSize write SetCheckSize default 12;
property CheckType: TEasyCheckType read FCheckType write SetCheckType default ectNone;
property ImageIndent: Integer read FImageIndent write SetImageIndent default 2;
property ShowBorder: Boolean read FShowBorder write SetShowBorder default True;
property VAlignment: TCommonVAlignment read FVAlignment write SetVAlignment default cvaCenter;
public
constructor Create(AnOwner: TCustomEasyListview); override;
procedure Assign(Source: TPersistent); override;
end;
TEasyPaintInfoBasicClass = class of TEasyPaintInfoBasic;
// **************************************************************************
// TEasyPaintInfoBaseItem
// Information that defines how an Items UI object is Painted
// **************************************************************************
TEasyPaintInfoBaseItem = class(TEasyPaintInfoBasic)
private
FGridLineColor: TColor;
FGridLines: Boolean;
FHideCaption: Boolean;
FTileDetailCount: Integer;
procedure SetGridLineColor(const Value: TColor);
procedure SetGridLines(const Value: Boolean);
procedure SetHideCaption(const Value: Boolean);
procedure SetTileDetailCount(Value: Integer);
protected
property GridLineColor: TColor read FGridLineColor write SetGridLineColor default clBtnFace;
property GridLines: Boolean read FGridLines write SetGridLines default False;
property HideCaption: Boolean read FHideCaption write SetHideCaption default False;
property TileDetailCount: Integer read FTileDetailCount write SetTileDetailCount default 1;
public
constructor Create(AnOwner: TCustomEasyListview); override;
end;
TEasyPaintInfoItem = class(TEasyPaintInfoBaseItem)
published
property Border;
property BorderColor;
property CaptionIndent;
property CaptionLines;
property CheckFlat;
property CheckIndent;
property CheckSize;
property CheckType;
property GridLineColor;
property GridLines;
property HideCaption;
property ImageIndent;
property ShowBorder;
property TileDetailCount;
property VAlignment;
end;
TEasyPaintInfoTaskBandItem = class(TEasyPaintInfoBaseItem)
published
property CaptionIndent;
property CheckFlat;
property CheckIndent;
property CheckSize;
property CheckType;
property VAlignment;
end;
// **************************************************************************
// TEasyPaintInfoBaseColumn
// Information that defines how an Column UI object is Painted
// **************************************************************************
TEasyPaintInfoBaseColumn = class(TEasyPaintInfoBasic)
private
FColor: TColor;
FHilightFocused: Boolean;
FHilightFocusedColor: TColor;
FHotTrack: Boolean;
FImagePosition: TEasyHeaderImagePosition;
FSortGlyphAlign: TEasySortGlyphAlign;
FSortGlyphIndent: Integer;
FStyle: TEasyHeaderButtonStyle;
procedure SetColor(Value: TColor);
procedure SetHilightFocused(const Value: Boolean);
procedure SetHilightFocusedColor(const Value: TColor);
procedure SetImagePosition(Value: TEasyHeaderImagePosition);
procedure SetSortGlpyhAlign(Value: TEasySortGlyphAlign);
procedure SetSortGlyphIndent(Value: Integer);
procedure SetStyle(Value: TEasyHeaderButtonStyle);
protected
property Color: TColor read FColor write SetColor default clBtnFace;
property HilightFocused: Boolean read FHilightFocused write SetHilightFocused default False;
property HilightFocusedColor: TColor read FHilightFocusedColor write SetHilightFocusedColor default $00F7F7F7;
property HotTrack: Boolean read FHotTrack write FHotTrack default True;
property ImagePosition: TEasyHeaderImagePosition read FImagePosition write SetImagePosition default ehpLeft;
property SortGlyphAlign: TEasySortGlyphAlign read FSortGlyphAlign write SetSortGlpyhAlign default esgaRight;
property SortGlyphIndent: Integer read FSortGlyphIndent write SetSortGlyphIndent default 2;
property Style: TEasyHeaderButtonStyle read FStyle write SetStyle default ehbsThick;
public
constructor Create(AnOwner: TCustomEasyListview); override;
published
end;
TCustomEasyPaintInfoBaseColumn = class(TEasyPaintInfoBaseColumn)
end;
TEasyPaintInfoColumn = class(TCustomEasyPaintInfoBaseColumn)
private
published
property Border;
property BorderColor;
property CaptionIndent;
property CaptionLines;
property CheckFlat;
property CheckIndent;
property CheckSize;
property CheckType;
property Color;
property HilightFocused;
property HilightFocusedColor;
property HotTrack;
property ImageIndent;
property ImagePosition;
property SortGlyphAlign;
property SortGlyphIndent;
property Style;
property VAlignment;
end;
TEasyPaintInfoTaskBandColumn = class(TCustomEasyPaintInfoBaseColumn)
published
// Nothing published
end;
// **************************************************************************
// TEasyPaintInfoBasicGroup
// Basic information that defines how an Groups UI object is Painted
// **************************************************************************
TEasyPaintInfoBaseGroup = class(TEasyPaintInfoBasic)
private
FBandBlended: Boolean;
FBandColor: TColor;
FBandColorFade: TColor;
FBandEnabled: Boolean;
FBandFullWidth: Boolean;
FBandIndent: Integer;
FBandLength: Integer;
FBandMargin: Integer;
FBandRadius: Byte;
FBandThickness: Integer;
FExpandable: Boolean;
FExpanded: Boolean;
FExpandImageIndent: Integer;
FMarginBottom: TCustomEasyFooterMargin;
FMarginLeft: TEasyMargin;
FMarginRight: TEasyMargin;
FMarginTop: TEasyHeaderMargin;
function GetMarginBottom: TCustomEasyFooterMargin;
function GetMarginLeft: TEasyMargin;
function GetMarginRight: TEasyMargin;
function GetMarginTop: TEasyHeaderMargin;
procedure SetBandBlended(Value: Boolean);
procedure SetBandColor(Value: TColor);
procedure SetBandColorFade(Value: TColor);
procedure SetBandEnabled(Value: Boolean);
procedure SetBandFullWidth(Value: Boolean);
procedure SetBandIndent(Value: Integer);
procedure SetBandLength(Value: Integer);
procedure SetBandMargin(Value: Integer);
procedure SetBandRadius(Value: Byte);
procedure SetBandThickness(Value: Integer);
procedure SetExpandable(Value: Boolean);
procedure SetExpandImageIndent(Value: Integer);
procedure SetMarginBottom(Value: TCustomEasyFooterMargin);
procedure SetMarginLeft(Value: TEasyMargin);
procedure SetMarginRight(Value: TEasyMargin);
procedure SetMarginTop(Value: TEasyHeaderMargin);
protected
property BandBlended: Boolean read FBandBlended write SetBandBlended default True;
property BandColor: TColor read FBandColor write SetBandColor default clBlue;
property BandColorFade: TColor read FBandColorFade write SetBandColorFade default clWindow;
property BandEnabled: Boolean read FBandEnabled write SetBandEnabled default True;
property BandFullWidth: Boolean read FBandFullWidth write SetBandFullWidth default False;
property BandIndent: Integer read FBandIndent write SetBandIndent default 0;
property BandLength: Integer read FBandLength write SetBandLength default 300;
property BandMargin: Integer read FBandMargin write SetBandMargin default 2;
property BandRadius: Byte read FBandRadius write SetBandRadius default 4;
property BandThickness: Integer read FBandThickness write SetBandThickness default 3;
property Expandable: Boolean read FExpandable write SetExpandable default True;
property ExpandImageIndent: Integer read FExpandImageIndent write SetExpandImageIndent default 4;
property MarginBottom: TCustomEasyFooterMargin read GetMarginBottom write SetMarginBottom;
property MarginLeft: TEasyMargin read GetMarginLeft write SetMarginLeft;
property MarginRight: TEasyMargin read GetMarginRight write SetMarginRight;
property MarginTop: TEasyHeaderMargin read GetMarginTop write SetMarginTop;
public
constructor Create(AnOwner: TCustomEasyListview); override;
destructor Destroy; override;
procedure Assign(Source: TPersistent); override;
end;
// **************************************************************************
// TEasyPaintInfoGroup
// Information that defines how an Groups UI object is Painted
// **************************************************************************
TEasyPaintInfoGroup = class(TEasyPaintInfoBaseGroup)
published
property Alignment;
property BandBlended;
property BandColor;
property BandColorFade;
property BandEnabled;
property BandFullWidth;
property BandIndent;
property BandLength;
property BandMargin;
property BandRadius;
property BandThickness;
property Border;
property BorderColor;
property CaptionIndent;
property CaptionLines;
property CheckFlat;
property CheckIndent;
property CheckSize;
property CheckType;
property Expandable;
property ExpandImageIndent;
property ImageIndent;
property MarginBottom;
property MarginLeft;
property MarginRight;
property MarginTop;
property VAlignment;
end;
// **************************************************************************
// TEasyPaintInfoGroup
// Information that defines how an Groups UI object is Painted
// **************************************************************************
TEasyPaintInfoTaskbandGroup = class(TEasyPaintInfoBaseGroup)
published
property Alignment;
property CaptionIndent;
property CheckFlat;
property CheckIndent;
property CheckSize;
property CheckType;
property Expandable;
property MarginBottom;
property MarginLeft;
property MarginRight;
property MarginTop;
property VAlignment;
end;
// **************************************************************************
// TEasyDynamicDataHelper
// Helps with multiple captions/image storage for item/groups/columns
// **************************************************************************
TEasyDynamicDataHelper = class
private
FCaptionArray: TCommonWideStringDynArray;
FDetailArray: TCommonIntegerDynArray;
FGroupKeyArray: TCommonIntegerDynArray;
FImageIndexArray: TCommonIntegerDynArray;
FOverlayIndexArray: TCommonIntegerDynArray;
function GetCaptions(Index: Integer): Widestring;
function GetDetails(Index: Integer): Integer;
function GetImageIndexes(Index: Integer): Integer;
function GetImageOverlayIndexes(Index: Integer): Integer;
procedure LoadIntArrayFromStream(S: TStream; var AnArray: TCommonIntegerDynArray);
procedure LoadWideStrArrayFromStream(S: TStream; var AnArray: TCommonWideStringDynArray);
procedure SaveIntArrayToStream(S: TStream; var AnArray: TCommonIntegerDynArray);
procedure SaveWideStrArrayToStream(S: TStream; var AnArray: TCommonWideStringDynArray);
procedure SetCaptions(Index: Integer; Value: Widestring);
procedure SetDetails(Index: Integer; Value: Integer);
procedure SetImageIndexes(Index: Integer; Value: Integer);
procedure SetImageOverlayIndexes(Index: Integer; Value: Integer);
property CaptionArray: TCommonWideStringDynArray read FCaptionArray write FCaptionArray;
property DetailArray: TCommonIntegerDynArray read FDetailArray write FDetailArray;
property GroupKeyArray: TCommonIntegerDynArray read FGroupKeyArray write FGroupKeyArray;
property ImageIndexArray: TCommonIntegerDynArray read FImageIndexArray write FImageIndexArray;
property OverlayIndexArray: TCommonIntegerDynArray read FOverlayIndexArray write FOverlayIndexArray;
public
procedure Clear;
procedure LoadFromStream(S: TStream; Version: Integer); virtual;
procedure SaveToStream(S: TStream; Version: Integer); virtual;
property Captions[Index: Integer]: Widestring read GetCaptions write SetCaptions;
property Details[Index: Integer]: Integer read GetDetails write SetDetails;
property ImageIndexes[Index: Integer]: Integer read GetImageIndexes write SetImageIndexes;
property ImageOverlayIndexes[Index: Integer]: Integer read GetImageOverlayIndexes write SetImageOverlayIndexes;
end;
TEasyItemDynamicDataHelper = class(TEasyDynamicDataHelper)
private
FStateImageArray: TCommonIntegerDynArray;
function GetGroupKey(Index: Integer): LongWord;
function GetStateImageIndexes(Index: Integer): TCommonImageIndexInteger;
procedure SetGroupKey(Index: Integer; Value: LongWord);
procedure SetStateImageIndexes(Index: Integer; Value: TCommonImageIndexInteger);
protected
property StateImageArray: TCommonIntegerDynArray read FStateImageArray write FStateImageArray;
public
procedure LoadFromStream(S: TStream; Version: Integer); override;
procedure SaveToStream(S: TStream; Version: Integer); override;
property GroupKey[Index: Integer]: LongWord read GetGroupKey write SetGroupKey;
property StateImageIndexes[Index: Integer]: TCommonImageIndexInteger read GetStateImageIndexes write SetStateImageIndexes;
end;
// **************************************************************************
// TEasyCollectionItem
// Basis for Collection items (, TEasyGroup, TEasyColumn)
// This Item can access its data through the
// **************************************************************************
TEasyCollectionItem = class(TEasyPersistent, IUnknown, IEasyNotificationSink)
private
FCollection: TEasyCollection;
FData: TObject;
FDataInf: IUnknown;
FDisplayRect: TRect; // The viewport coordinates of the object
FIndex: Integer; // Absolute Index of the item within a particular collecton
FOwnsPaintInfo: Boolean;
FPaintInfo: TEasyPaintInfoBasic; // Information to draw the item
FRefCount: Integer;
FState: TEasyStorageObjectStates; // State of the item
FTag: Integer;
FVisibleIndex: Integer; // Index of the item across all collections (flat list across collection in group)
// See TEasyItem.VisibleIndexInGroup
function GetAlignment: TAlignment;
function GetBold: Boolean;
function GetBorder: Integer;
function GetBorderColor: TColor;
function GetCaptionIndent: Integer;
function GetCheckFlat: Boolean;
function GetCheckHovering: Boolean;
function GetCheckIndent: Integer;
function GetCheckPending: Boolean;
function GetCheckSize: Integer;
function GetCheckType: TEasyCheckType;
function GetClicking: Boolean;
function GetCut: Boolean;
function GetDataInf: IUnknown;
function GetDestroying: Boolean;
function GetGhosted: Boolean;
function GetHilighted: Boolean;
function GetEnabled: Boolean;
function GetFocused: Boolean;
function GetHotTracking(MousePos: TPoint): Boolean;
function GetImageIndent: Integer;
function GetInitialized: Boolean;
function GetOwnerListview: TCustomEasyListview;
function GetPaintInfo: TEasyPaintInfoBasic;
function GetSelected: Boolean;
function GetVAlignment: TCommonVAlignment;
function GetViewRect: TRect;
function GetVisible: Boolean;
procedure SetAlignment(Value: TAlignment);
procedure SetBold(const Value: Boolean);
procedure SetBorder(Value: Integer);
procedure SetBorderColor(Value: TColor);
procedure SetCaptionIndent(Value: Integer);
procedure SetCheckFlat(Value: Boolean);
procedure SetCheckHovering(Value: Boolean);
procedure SetCheckIndent(Value: Integer);
procedure SetCheckPending(Value: Boolean);
procedure SetCheckSize(Value: Integer);
procedure SetCheckType(Value: TEasyCheckType);
procedure SetClicking(Value: Boolean);
procedure SetCut(Value: Boolean);
procedure SetData(Value: TObject); virtual;
procedure SetDataInf(const Value: IUnknown);
procedure SetGhosted(const Value: Boolean);
procedure SetHilighted(Value: Boolean);
procedure SetEnabled(Value: Boolean);
procedure SetFocused(Value: Boolean);
procedure SetHotTracking(MousePos: TPoint; Value: Boolean);
procedure SetImageIndent(Value: Integer);
procedure SetInitialized(Value: Boolean); virtual;
procedure SetPaintInfo(Value: TEasyPaintInfoBasic);
procedure SetSelected(Value: Boolean);
procedure SetVAlignment(Value: TCommonVAlignment);
procedure SetVisible(Value: Boolean);
protected
function AllowDrag(ViewportPt: TPoint): Boolean; virtual;
// IUnknown
function _AddRef: Integer; virtual; stdcall;
function _Release: Integer; virtual; stdcall;
function QueryInterface(const IID: TGUID; out Obj): HResult; virtual; stdcall;
function CanChangeBold(NewValue: Boolean): Boolean; virtual; abstract;
function CanChangeCheck(NewValue: Boolean): Boolean; virtual; abstract;
function CanChangeEnable(NewValue: Boolean): Boolean; virtual; abstract;
function CanChangeFocus(NewValue: Boolean): Boolean; virtual; abstract;
function CanChangeHotTracking(NewValue: Boolean): Boolean; virtual; abstract;
function CanChangeSelection(NewValue: Boolean): Boolean; virtual; abstract;
function CanChangeVisibility(NewValue: Boolean): Boolean; virtual; abstract;
function DefaultImageList(ImageSize: TEasyImageSize): TCustomImageList; virtual;
function GetChecked: Boolean; virtual;
function GetDisplayName: WideString; virtual;
function LocalPaintInfo: TEasyPaintInfoBasic; virtual; abstract;
procedure Freeing; virtual; abstract;
procedure GainingBold; virtual; abstract;
procedure GainingCheck; virtual; abstract;
procedure GainingEnable; virtual; abstract;
procedure GainingFocus; virtual; abstract;
procedure GainingGhosted; virtual; abstract;
procedure GainingHilight; virtual; abstract;
procedure GainingHotTracking(MousePos: TPoint); virtual; abstract;
procedure GainingSelection; virtual; abstract;
procedure GainingVisibility; virtual; abstract;
function GetCaption: WideString; virtual;
function GetCaptions(Column: Integer): Widestring; virtual; abstract;
function GetImageIndex: TCommonImageIndexInteger; virtual;
function GetImageIndexes(Column: Integer): TCommonImageIndexInteger; virtual; abstract;
function GetImageOverlayIndex: TCommonImageIndexInteger; virtual;
function GetImageOverlayIndexes(Column: Integer): TCommonImageIndexInteger; virtual; abstract;
function GetOwner: TPersistent; override;
function GetImageList(Column: Integer; IconSize: TEasyImageSize): TCustomImageList; virtual; abstract;
function GetIndex: Integer; virtual;
function GetDetailCount: Integer; virtual; abstract;
function GetDetails(Line: Integer): Integer; virtual; abstract;
procedure ImageDraw(Column: TEasyColumn; ACanvas: TCanvas; const RectArray: TEasyRectArrayObject; AlphaBlender: TEasyAlphaBlender); virtual; abstract;
procedure ImageDrawGetSize(Column: TEasyColumn; var ImageW, ImageH: Integer); virtual; abstract;
procedure ImageDrawIsCustom(Column: TEasyColumn; var IsCustom: Boolean); virtual; abstract;
procedure InvalidateItem(ImmediateRefresh: Boolean); // IEasyNotificationSink
procedure LosingBold; virtual; abstract;
procedure LosingGhosted; virtual; abstract;
procedure LosingHotTracking; virtual; abstract;
procedure ThumbnailDraw(ACanvas: TCanvas; ARect: TRect; AlphaBlender: TEasyAlphaBlender; var DoDefault: Boolean); virtual; abstract;
procedure Initialize; virtual; abstract;
procedure LosingCheck; virtual; abstract;
procedure LosingEnable; virtual; abstract;
procedure LosingFocus; virtual; abstract;
procedure LosingHilight; virtual; abstract;
procedure LosingSelection; virtual; abstract;
procedure LosingVisibility; virtual; abstract;
procedure SetCaptions(Column: Integer; Value: Widestring); virtual; abstract;
procedure SetCaption(Value: WideString); virtual;
procedure SetChecked(Value: Boolean); virtual;
procedure SetDestroyFlags;
procedure SetDetailCount(Value: Integer); virtual; abstract;
procedure SetDetails(Line: Integer; Value: Integer); virtual; abstract;
procedure SetImageIndex(const Value: TCommonImageIndexInteger); virtual;
procedure SetImageIndexes(Column: Integer; Value: TCommonImageIndexInteger); virtual; abstract;
procedure SetImageOverlayIndex(const Value: TCommonImageIndexInteger); virtual;
procedure SetImageOverlayIndexes(Column: Integer; Value: TCommonImageIndexInteger); virtual; abstract;
procedure UnRegister; // IEasyNotificationSink
property Alignment: TAlignment read GetAlignment write SetAlignment default taLeftJustify;
property Bold: Boolean read GetBold write SetBold default False;
property Border: Integer read GetBorder write SetBorder default 0;
property BorderColor: TColor read GetBorderColor write SetBorderColor default clWindow;
property CaptionIndent: Integer read GetCaptionIndent write SetCaptionIndent default 2;
property Checked: Boolean read GetChecked write SetChecked default False;
property CheckFlat: Boolean read GetCheckFlat write SetCheckFlat default False;
property CheckHovering: Boolean read GetCheckHovering write SetCheckHovering;
property CheckIndent: Integer read GetCheckIndent write SetCheckIndent default 2;
property CheckPending: Boolean read GetCheckPending write SetCheckPending;
property CheckSize: Integer read GetCheckSize write SetCheckSize default 12;
property CheckType: TEasyCheckType read GetCheckType write SetCheckType default ectNone;
property Clicking: Boolean read GetClicking write SetClicking default False;
property Collection: TEasyCollection read FCollection write FCollection;
property Cut: Boolean read GetCut write SetCut default False;
property DataInf: IUnknown read GetDataInf write SetDataInf;
property Destroying: Boolean read GetDestroying;
property DisplayRect: TRect read FDisplayRect write FDisplayRect;
property Enabled: Boolean read GetEnabled write SetEnabled default True;
property Focused: Boolean read GetFocused write SetFocused default False;
property Ghosted: Boolean read GetGhosted write SetGhosted default False;
property Hilighted: Boolean read GetHilighted write SetHilighted default False;
property ImageIndent: Integer read GetImageIndent write SetImageIndent default 2;
property Initialized: Boolean read GetInitialized write SetInitialized;
property OwnsPaintInfo: Boolean read FOwnsPaintInfo write FOwnsPaintInfo default False;
property PaintInfo: TEasyPaintInfoBasic read GetPaintInfo write SetPaintInfo;
property Selected: Boolean read GetSelected write SetSelected default False;
property State: TEasyStorageObjectStates read FState write FState;// The State of the object, checked, selected, focused, etc.
property VAlignment: TCommonVAlignment read GetVAlignment write SetVAlignment;
property Visible: Boolean read GetVisible write SetVisible default True;
public
constructor Create(ACollection: TEasyCollection); reintroduce; virtual;
destructor Destroy; override;
function EditAreaHitPt(ViewportPoint: TPoint): Boolean; virtual; abstract;
function SelectionHit(SelectViewportRect: TRect; SelectType: TEasySelectHitType): Boolean; virtual; abstract;
function SelectionHitPt(ViewportPoint: TPoint; SelectType: TEasySelectHitType): Boolean; virtual; abstract;
procedure Invalidate(ImmediateUpdate: Boolean); virtual; // IEasyNotificationSink
procedure LoadFromStream(S: TStream; var Version: Integer); virtual;
procedure MakeVisible(Position: TEasyMakeVisiblePos); virtual;
procedure SaveToStream(S: TStream; Version: Integer = EASYLISTVIEW_STREAM_VERSION); virtual;
property Caption: WideString read GetCaption write SetCaption;
property Captions[Column: Integer]: Widestring read GetCaptions write SetCaptions;
property Data: TObject read FData write SetData;
property DetailCount: Integer read GetDetailCount write SetDetailCount;
property Details[Line: Integer]: Integer read GetDetails write SetDetails;
property HotTracking[MousePos: TPoint]: Boolean read GetHotTracking write SetHotTracking;
property ImageIndex: TCommonImageIndexInteger read GetImageIndex write SetImageIndex default -1;
property ImageIndexes[Column: Integer]: TCommonImageIndexInteger read GetImageIndexes write SetImageIndexes;
property ImageList[Column: Integer; IconSize: TEasyImageSize]: TCustomImageList read GetImageList;
property ImageOverlayIndex: TCommonImageIndexInteger read GetImageOverlayIndex write SetImageOverlayIndex default -1;
property ImageOverlayIndexes[Column: Integer]: TCommonImageIndexInteger read GetImageOverlayIndexes write SetImageOverlayIndexes;
property Index: Integer read GetIndex;
property OwnerListview: TCustomEasyListview read GetOwnerListview;
property RefCount: Integer read FRefCount;
property Tag: Integer read FTag write FTag default 0;
property ViewRect: TRect read GetViewRect;
property VisibleIndex: Integer read FVisibleIndex;
end;
// **************************************************************************
// TEasyItemBase
// Basis for any object that can be stored in a TEasyGroup. Implements the
// basic handling of interaction between the item and the Listview
// **************************************************************************
TEasyItem = class(TEasyCollectionItem)
private
FSelectionGroup: TEasySelectionGroupList; // If grouped selection is on this points to the selection group this item belongs to (nil if none)
FView: TEasyViewItem;
FVisibleIndexInGroup: Integer; // Index of visible item within a group
function GetColumnPos: Integer;
function GetOwnerGroup: TEasyGroup;
function GetOwnerItems: TEasyItems;
function GetPaintInfo: TEasyPaintInfoItem;
function GetRowPos: Integer;
function GetView: TEasyViewItem;
function GetViewClass: TEasyViewItemClass;
procedure SetPaintInfo(const Value: TEasyPaintInfoItem);
procedure SetSelectionGroup(Value: TEasySelectionGroupList);
protected
function AllowDrag(ViewportPt: TPoint): Boolean; override;
function CanChangeBold(NewValue: Boolean): Boolean; override;
function CanChangeCheck(NewValue: Boolean): Boolean; override;
function CanChangeEnable(NewValue: Boolean): Boolean; override;
function CanChangeFocus(NewValue: Boolean): Boolean; override;
function CanChangeHotTracking(NewValue: Boolean): Boolean; override;
function CanChangeSelection(NewValue: Boolean): Boolean; override;
function CanChangeVisibility(NewValue: Boolean): Boolean; override;
function DefaultStateImageList: TCustomImageList;
function GetDefaultViewClass: TEasyViewItemClass; virtual;
function GetGroupKey(FocusedColumn: Integer): LongWord; virtual;
function GetIndex: Integer; override;
function GetStateImageIndex: TCommonImageIndexInteger; virtual;
function GetStateImageIndexes(Column: Integer): TCommonImageIndexInteger; virtual; abstract;
function GetStateImageList(Column: Integer): TCustomImageList; virtual; abstract;
function LocalPaintInfo: TEasyPaintInfoBasic; override;
procedure Freeing; override;
procedure GainingBold; override;
procedure GainingCheck; override;
procedure GainingEnable; override;
procedure GainingFocus; override;
procedure GainingGhosted; override;
procedure GainingHilight; override;
procedure GainingHotTracking(MousePos: TPoint); override;
procedure GainingSelection; override;
procedure GainingVisibility; override;
procedure Initialize; override;
procedure LosingBold; override;
procedure LosingCheck; override;
procedure LosingEnable; override;
procedure LosingFocus; override;
procedure LosingGhosted; override;
procedure LosingHilight; override;
procedure LosingHotTracking; override;
procedure LosingSelection; override;
procedure LosingVisibility; override;
procedure ReleaseSelectionGroup;
procedure SetStateImageIndex(const Value: TCommonImageIndexInteger); virtual;
procedure SetStateImageIndexes(Column: Integer; Value: TCommonImageIndexInteger); virtual; abstract;
property SelectionGroup: TEasySelectionGroupList read FSelectionGroup write SetSelectionGroup;
procedure SetGroupKey(FocusedColumn: Integer; Value: LongWord); virtual;
public
constructor Create(ACollection: TEasyCollection); override;
destructor Destroy; override;
function EditAreaHitPt(ViewportPoint: TPoint): Boolean; override;
function HitTestAt(ViewportPoint: TPoint; var HitInfo: TEasyItemHitTestInfoSet): Boolean;
function SelectionHit(SelectViewportRect: TRect; SelectType: TEasySelectHitType): Boolean; override;
function SelectionHitPt(ViewportPoint: TPoint; SelectType: TEasySelectHitType): Boolean; override;
procedure Edit(Column: TEasyColumn = nil);
procedure Invalidate(ImmediateUpdate: Boolean); override;
procedure ItemRectArray(Column: TEasyColumn; ACanvas: TCanvas; var RectArray: TEasyRectArrayObject);
procedure LoadFromStream(S: TStream; var Version: Integer); override;
procedure MakeVisible(Position: TEasyMakeVisiblePos); override;
procedure Paint(ACanvas: TCanvas; ViewportClipRect: TRect; Column: TEasyColumn; ForceSelectionRectDraw: Boolean); virtual;
procedure SaveToStream(S: TStream; Version: Integer = EASYLISTVIEW_STREAM_VERSION); override;
property Alignment;
property Bold;
property Border;
property BorderColor;
property Caption;
property CaptionIndent;
property Captions;
property Checked;
property CheckFlat;
property CheckHovering;
property CheckIndent;
property CheckPending;
property CheckSize;
property CheckType;
property ColumnPos: Integer read GetColumnPos;
property Cut;
property Destroying;
property DetailCount;
property Details;
property Enabled;
property Focused;
property GroupKey[FocusedColumn: Integer]: LongWord read GetGroupKey write SetGroupKey;
property Hilighted;
property ImageIndent;
property ImageIndex;
property ImageIndexes;
property ImageList;
property ImageOverlayIndex;
property ImageOverlayIndexes;
property Initialized;
property OwnerGroup: TEasyGroup read GetOwnerGroup;
property OwnerItems: TEasyItems read GetOwnerItems;
property OwnsPaintInfo;
property PaintInfo: TEasyPaintInfoItem read GetPaintInfo write SetPaintInfo;
property RowPos: Integer read GetRowPos;
property Selected;
property State;
property StateImageIndex: TCommonImageIndexInteger read GetStateImageIndex write SetStateImageIndex default -1;
property StateImageIndexes[Column: Integer]: TCommonImageIndexInteger read GetStateImageIndexes write SetStateImageIndexes;
property StateImageList[Column: Integer]: TCustomImageList read GetStateImageList;
property VAlignment;
property View: TEasyViewItem read GetView;
property ViewClass: TEasyViewItemClass read GetViewClass;
property Visible;
property VisibleIndexInGroup: Integer read FVisibleIndexInGroup;
published
end;
// **************************************************************************
// TEasyItemInterfaced
// Uses interfaced based data extraction to extract the data from a data
// source. The data source can implement any of the following
// IEasyCaptions // Returns Captions for the control
// IEasyCaptionsEditable // Sets Captions in the data from the Control
// IEasyImages // Returns Images for the control
// IEasyImagesEditable // Sets Images in the data from the Control
// IEasyThumbnail // Returns Thumbnail for the control
// IEasyThumbnailEditable // Sets Thumbnail in the data from the Control
// IEasyChecks // Sets/Unsets the Checkbox State for the control
// IEasyNotifier // Returns an Inteterface to allow data to notify Control of changes in the data
// IEasyCompareData // Allows sorting of the data set
// **************************************************************************
TEasyItemInterfaced = class(TEasyItem)
private
function GetCommonImageIndex(Column: Integer; Kind: TEasyImageKind): TCommonImageIndexInteger;
procedure SetCommonImageIndex(Column: Integer; Kind: TEasyImageKind; Value: TCommonImageIndexInteger);
protected
function GetCaptions(Column: Integer): Widestring; override;
function GetChecked: Boolean; override;
function GetDetailCount: Integer; override;
function GetDetails(Line: Integer): Integer; override;
function GetGroupKey(FocusedColumn: Integer): LongWord; override;
function GetImageIndexes(Column: Integer): TCommonImageIndexInteger; override;
function GetImageList(Column: Integer; IconSize: TEasyImageSize): TCustomImageList; override;
function GetImageOverlayIndexes(Column: Integer): TCommonImageIndexInteger; override;
function GetStateImageIndexes(Column: Integer): TCommonImageIndexInteger; override;
function GetStateImageList(Column: Integer): TCustomImageList; override;
procedure ImageDraw(Column: TEasyColumn; ACanvas: TCanvas; const RectArray: TEasyRectArrayObject; AlphaBlender: TEasyAlphaBlender); override;
procedure ImageDrawGetSize(Column: TEasyColumn; var ImageW, ImageH: Integer); override;
procedure ImageDrawIsCustom(Column: TEasyColumn; var IsCustom: Boolean); override;
procedure SetCaptions(Column: Integer; Value: Widestring); override;
procedure SetChecked(Value: Boolean); override;
procedure SetDetailCount(Value: Integer); override;
procedure SetDetails(Line: Integer; Value: Integer); override;
procedure SetGroupKey(FocusedColumn: Integer; Value: LongWord); override;
procedure SetImageIndexes(Column: Integer; Value: TCommonImageIndexInteger); override;
procedure SetImageOverlayIndexes(Column: Integer; Value: TCommonImageIndexInteger); override;
procedure SetStateImageIndexes(Column: Integer; Value: TCommonImageIndexInteger); override;
procedure ThumbnailDraw(ACanvas: TCanvas; ARect: TRect; AlphaBlender: TEasyAlphaBlender; var DoDefault: Boolean); override;
public
function ExtractObject: TObject;
property DataInf;
end;
// **************************************************************************
// TEasyItemVirtual
// Calls back through the Controls Events for the data to display
// **************************************************************************
TEasyItemVirtual = class(TEasyItem)
protected
function GetCaptions(Column: Integer): Widestring; override;
function GetDetailCount: Integer; override;
function GetDetails(Line: Integer): Integer; override;
function GetGroupKey(FocusedColumn: Integer): LongWord; override;
function GetImageIndexes(Column: Integer): TCommonImageIndexInteger; override;
function GetImageList(Column: Integer; IconSize: TEasyImageSize): TCustomImageList; override;
function GetImageOverlayIndexes(Column: Integer): TCommonImageIndexInteger; override;
function GetStateImageIndexes(Column: Integer): TCommonImageIndexInteger; override;
function GetStateImageList(Column: Integer): TCustomImageList; override;
procedure ImageDraw(Column: TEasyColumn; ACanvas: TCanvas; const RectArray: TEasyRectArrayObject; AlphaBlender: TEasyAlphaBlender); override;
procedure ImageDrawGetSize(Column: TEasyColumn; var ImageW: Integer; var ImageH: Integer); override;
procedure ImageDrawIsCustom(Column: TEasyColumn; var IsCustom: Boolean); override;
procedure SetCaptions(Column: Integer; Value: Widestring); override;
procedure SetDetailCount(Value: Integer); override;
procedure SetDetails(Line: Integer; Value: Integer); override;
procedure SetGroupKey(FocusedColumn: Integer; Value: LongWord); override;
procedure SetImageIndexes(Column: Integer; Value: TCommonImageIndexInteger); override;
procedure SetImageOverlayIndexes(Column: Integer; Value: TCommonImageIndexInteger); override;
procedure SetStateImageIndexes(Column: Integer; Value: TCommonImageIndexInteger); override;
procedure ThumbnailDraw(ACanvas: TCanvas; ARect: TRect; AlphaBlender: TEasyAlphaBlender; var DoDefault: Boolean); override;
public
end;
// **************************************************************************
// TEasyItemStored
// Stores the data local to the Item instance
// **************************************************************************
TEasyItemStored = class(TEasyItem)
private
FDataHelper: TEasyItemDynamicDataHelper;
protected
function GetCaptions(Column: Integer): Widestring; override;
function GetDetailCount: Integer; override;
function GetDetails(Line: Integer): Integer; override;
function GetGroupKey(FocusedColumn: Integer): LongWord; override;
function GetImageIndexes(Column: Integer): TCommonImageIndexInteger; override;
function GetImageList(Column: Integer; IconSize: TEasyImageSize): TCustomImageList; override;
function GetImageOverlayIndexes(Column: Integer): TCommonImageIndexInteger; override;
function GetStateImageIndexes(Column: Integer): TCommonImageIndexInteger; override;
function GetStateImageList(Column: Integer): TCustomImageList; override;
procedure ImageDraw(Column: TEasyColumn; ACanvas: TCanvas; const RectArray: TEasyRectArrayObject; AlphaBlender: TEasyAlphaBlender); override;
procedure ImageDrawGetSize(Column: TEasyColumn; var ImageW: Integer; var ImageH: Integer); override;
procedure ImageDrawIsCustom(Column: TEasyColumn; var IsCustom: Boolean); override;
procedure SetCaptions(Column: Integer; Value: Widestring); override;
procedure SetDetailCount(Value: Integer); override;
procedure SetDetails(Column: Integer; Value: Integer); override;
procedure SetGroupKey(FocusedColumn: Integer; Value: LongWord); override;
procedure SetImageIndexes(Column: Integer; Value: TCommonImageIndexInteger); override;
procedure SetImageOverlayIndexes(Column: Integer; Value: TCommonImageIndexInteger); override;
procedure SetStateImageIndexes(Column: Integer; Value: TCommonImageIndexInteger); override;
procedure ThumbnailDraw(ACanvas: TCanvas; ARect: TRect; AlphaBlender: TEasyAlphaBlender; var DoDefault: Boolean); override;
property DataHelper: TEasyItemDynamicDataHelper read FDataHelper write FDataHelper;
public
constructor Create(ACollection: TEasyCollection); override;
destructor Destroy; override;
procedure LoadFromStream(S: TStream; var Version: Integer); override;
procedure SaveToStream(S: TStream; Version: Integer = EASYLISTVIEW_STREAM_VERSION); override;
published
property Bold;
property Caption;
property Checked;
property Enabled;
property Ghosted;
property ImageIndex;
property ImageOverlayIndex;
property Selected;
property StateImageIndex;
property Tag;
property Visible;
end;
TEasyItemStoredClass = class of TEasyItemStored;
// **************************************************************************
// TEasyCollection
// Basis for Collection (TEasyItems, TEasyGroups, TEasyColumns)
// **************************************************************************
TEasyCollection = class(TEasyOwnedPersistent)
private
FHideFromDFM: Boolean;
FList: TList;
FReIndexCount: Integer;
FTag: Integer;
FVisibleList: TList;
function GetCount: Integer;
function GetItem(Index: Integer): TEasyCollectionItem;
function GetOwnerListview: TCustomEasyListview;
function GetReIndexDisable: Boolean;
function GetVisibleCount: Integer;
procedure SetItem(Index: Integer; Value: TEasyCollectionItem);
procedure SetReIndexDisable(const Value: Boolean);
protected
FItemClass: TEasyCollectionItemClass;
function DoStore: Boolean; dynamic;
function GetOwner: TPersistent; override;
procedure DefineProperties(Filer: TFiler); override;
procedure DoItemAdd(Item: TEasyCollectionItem; Index: Integer); virtual;
procedure DoStructureChange; virtual;
property List: TList read FList write FList;
property ReIndexCount: Integer read FReIndexCount write FReIndexCount;
property VisibleList: TList read FVisibleList write FVisibleList;
public
constructor Create(AnOwner: TCustomEasyListview); override;
destructor Destroy; override;
function Add(Data: TObject = nil): TEasyCollectionItem;
function FirstVisible: TEasyColumn; virtual;
function LastVisible: TEasyColumn; virtual;
function NextVisible(Column: TEasyColumn): TEasyColumn; virtual;
function PrevVisible(Column: TEasyColumn): TEasyColumn; virtual;
procedure BeginUpdate(ReIndex: Boolean); virtual;
procedure Clear(FreeItems: Boolean = True); virtual;
procedure Delete(Index: Integer);
procedure EndUpdate(Invalidate: Boolean = True); virtual;
function Insert(Index: Integer; Data: TObject = nil): TEasyCollectionItem;
procedure Exchange(Index1, Index2: Integer);
procedure MakeAllVisible; virtual;
procedure ReadItems(Stream: TStream); virtual;
procedure ReIndexItems;
procedure WriteItems(Stream: TStream); virtual;
property Count: Integer read GetCount;
property HideFromDFM: Boolean read FHideFromDFM write FHideFromDFM default False;
property ItemClass: TEasyCollectionItemClass read FItemClass;
property Items[Index: Integer]: TEasyCollectionItem read GetItem write SetItem; default;
property OwnerListview: TCustomEasyListview read GetOwnerListview;
property ReIndexDisable: Boolean read GetReIndexDisable write SetReIndexDisable;
property VisibleCount: Integer read GetVisibleCount;
published
property Tag: Integer read FTag write FTag default 0;
end;
TEasyCollectionClass = class of TEasyCollection;
// **************************************************************************
// TEasyViewItem
// Basis for the UI (drawing, and mouse interaction) for a TEasyItem
// **************************************************************************
TEasyViewItem = class(TEasyOwnedPersistentGroupItem)
private
procedure PaintAlphaBlendedRoundRect(ACanvas: TCanvas; AlphaColor: TColor;
GradientBottom: TColor; GradientTop: TColor;
var LocalSelWindowClippedRect: TRect; var Rgn: HRGN);
procedure PaintAlphaBlendedSelection(ACanvas: TCanvas; AlphaColor: TColor;
HeaderClippedWindowRect: TRect; LocalSelRect: TRect);
procedure PaintAlphaBlendedGradientFill(ACanvas: TCanvas;
GradientBottom: TColor; GradientTop: TColor; LocalSelRect: TRect;
LocalSelWindowClippedRect: TRect; LocalSelClippedRect: TRect);
procedure PaintNonAlphaBlendedSelection(ACanvas: TCanvas;
LocalSelRect: TRect);
protected
function AllowDrag(Item: TEasyItem; ViewportPoint: TPoint): Boolean; virtual;
function PaintStateImage: Boolean; virtual;
function ValidateColumnIndex(Column: TEasyColumn): Integer;
public
procedure AfterSelRectCalc(Item: TEasyItem; Column: TEasyColumn; const Caption: WideString; var LocalSelRect: TRect); virtual;
procedure CalculateTextRect(Item: TEasyItem; Column: TEasyColumn; var TextR: TRect; ACanvas: TControlCanvas);
function EditAreaHitPt(Item: TEasyItem; ViewportPoint: TPoint): Boolean; virtual;
function ExpandIconR(Item: TEasyItem; RectArray: TEasyRectArrayObject; SelectType: TEasySelectHitType): TRect; virtual;
function ExpandTextR(Item: TEasyItem; RectArray: TEasyRectArrayObject; SelectType: TEasySelectHitType): TRect; virtual;
function FullRowSelect: Boolean; virtual;
function GetImageList(Column: TEasyColumn; Item: TEasyItem; Image: TEasyImageKind): TCustomImageList; virtual;
procedure GetImageSize(Item: TEasyItem; Column: TEasyColumn; var ImageW, ImageH: Integer; Image: TEasyImageKind); virtual;
function GetStateImageList(Column: TEasyColumn; Item: TEasyItem): TCustomImageList; virtual;
function ItemRect(Item: TEasyItem; Column: TEasyColumn; RectType: TEasyCellRectType): TRect; virtual;
procedure ItemRectArray(Item: TEasyItem; Column: TEasyColumn; ACanvas: TCanvas; const Caption: WideString; var RectArray: TEasyRectArrayObject); virtual;
procedure LoadTextFont(Item: TEasyItem; Position: Integer; ACanvas: TCanvas; Hilightable: Boolean); virtual;
function OverlappedFocus: Boolean; virtual;
procedure Paint(Item: TEasyItem; Column: TEasyColumn; ACanvas: TCanvas; ViewportClipRect: TRect; ForceSelectionRectDraw: Boolean); virtual;
procedure PaintAfter(Item: TEasyItem; Column: TEasyColumn; const Caption: WideString; ACanvas: TCanvas; RectArray: TEasyRectArrayObject); virtual;
procedure PaintBefore(Item: TEasyItem; Column: TEasyColumn; const Caption: WideString; ACanvas: TCanvas; RectArray: TEasyRectArrayObject; var Handled: Boolean); virtual;
procedure PaintCheckBox(Item: TEasyItem; Column: TEasyColumn; RectArray: TEasyRectArrayObject; ACanvas: TCanvas); virtual;
procedure PaintFocusRect(Item: TEasyItem; Column: TEasyColumn; const Caption: WideString; RectArray: TEasyRectArrayObject; ACanvas: TCanvas); virtual;
procedure PaintImage(Item: TEasyItem; Column: TEasyColumn; const Caption: WideString; RectArray: TEasyRectArrayObject; ImageSize: TEasyImageSize; ACanvas: TCanvas); virtual;
function PaintImageSize: TEasyImageSize; virtual;
procedure PaintSelectionRect(Item: TEasyItem; Column: TEasyColumn; const Caption: WideString; RectArray: TEasyRectArrayObject; ACanvas: TCanvas; ViewportClipRect: TRect; ForceSelectionRectDraw: Boolean); virtual;
procedure PaintText(Item: TEasyItem; Column: TEasyColumn; const Caption: WideString; RectArray: TEasyRectArrayObject; ACanvas: TCanvas; LinesToDraw: Integer); virtual;
function PaintTextAlignment(Item: TEasyItem; Column: TEasyColumn): TAlignment; virtual;
function PaintTextLineCount(Item: TEasyItem; Column: TEasyColumn): Integer; virtual;
function PaintTextVAlignment(Item: TEasyItem; Column: TEasyColumn): TCommonVAlignment; virtual;
function PtInRect(Item: TEasyItem; Column: TEasyColumn; Pt: TPoint): Integer; virtual;
procedure ReSizeRectArray(var RectArray: TEasyRectArrayObjectArray); virtual;
function SelectionHit(Item: TEasyItem; SelectViewportRect: TRect; SelectType: TEasySelectHitType): Boolean; virtual;
function SelectionHitPt(Item: TEasyItem; ViewportPoint: TPoint; SelectType: TEasySelectHitType): Boolean; virtual;
procedure TestAndClipImage(ACanvas: TCanvas; RectArray: TEasyRectArrayObject; var Rgn: HRgn);
procedure TestAndUnClipImage(ACanvas: TCanvas; RectArray: TEasyRectArrayObject; Rgn: HRgn);
end;
// **************************************************************************
// TEasyViewIconItem
// Basis for the UI (drawing, and mouse interaction) for a TEasyItem
// **************************************************************************
TEasyViewIconItem = class(TEasyViewItem)
public
function ExpandIconR(Item: TEasyItem; RectArray: TEasyRectArrayObject; SelectType: TEasySelectHitType): TRect; override;
function OverlappedFocus: Boolean; override;
function PaintImageSize: TEasyImageSize; override;
function PaintTextLineCount(Item: TEasyItem; Column: TEasyColumn): Integer; override;
procedure AfterSelRectCalc(Item: TEasyItem; Column: TEasyColumn; const Caption: WideString; var LocalSelRect: TRect); override;
procedure ItemRectArray(Item: TEasyItem; Column: TEasyColumn; ACanvas: TCanvas; const Caption: WideString; var RectArray: TEasyRectArrayObject); override;
procedure PaintBefore(Item: TEasyItem; Column: TEasyColumn; const Caption: WideString; ACanvas: TCanvas; RectArray: TEasyRectArrayObject; var Handled: Boolean); override;
end;
// **************************************************************************
// TEasyViewSmallIconItem
// Basis for the UI (drawing, and mouse interaction) for a TEasyItem
// **************************************************************************
TEasyViewSmallIconItem = class(TEasyViewItem)
public
function CalculateDisplayRect(Item: TEasyItem; Column: TEasyColumn): TRect; virtual;
function ExpandIconR(Item: TEasyItem; RectArray: TEasyRectArrayObject; SelectType: TEasySelectHitType): TRect; override;
function ExpandTextR(Item: TEasyItem; RectArray: TEasyRectArrayObject; SelectType: TEasySelectHitType): TRect; override;
procedure ItemRectArray(Item: TEasyItem; Column: TEasyColumn; ACanvas: TCanvas; const Caption: WideString; var RectArray: TEasyRectArrayObject); override;
procedure PaintBefore(Item: TEasyItem; Column: TEasyColumn; const Caption: WideString; ACanvas: TCanvas; RectArray: TEasyRectArrayObject; var Handled: Boolean); override;
function PaintTextAlignment(Item: TEasyItem; Column: TEasyColumn): TAlignment; override;
function PaintTextLineCount(Item: TEasyItem; Column: TEasyColumn): Integer; override;
function PaintTextVAlignment(Item: TEasyItem; Column: TEasyColumn): TCommonVAlignment; override;
end;
// **************************************************************************
// TEasyViewListItem
// Basis for the UI (drawing, and mouse interaction) for a TEasyItem
// **************************************************************************
TEasyViewListItem = class(TEasyViewSmallIconItem)
end;
// **************************************************************************
// TEasyViewReportItem
// Basis for the UI (drawing, and mouse interaction) for a TEasyItem
// **************************************************************************
TEasyViewReportItem = class(TEasyViewSmallIconItem)
protected
function AllowDrag(Item: TEasyItem; ViewportPoint: TPoint): Boolean; override;
function PaintStateImage: Boolean; override;
public
function CalculateDisplayRect(Item: TEasyItem; Column: TEasyColumn): TRect; override;
function ExpandTextR(Item: TEasyItem; RectArray: TEasyRectArrayObject; SelectType: TEasySelectHitType): TRect; override;
function FullRowSelect: Boolean; override;
function SelectionHit(Item: TEasyItem; SelectViewportRect: TRect; SelectType: TEasySelectHitType): Boolean; override;
function SelectionHitPt(Item: TEasyItem; ViewportPoint: TPoint; SelectType: TEasySelectHitType): Boolean; override;
end;
// **************************************************************************
// TEasyViewGridItem
// Basis for the UI (drawing, and mouse interaction) for a TEasyItem
// **************************************************************************
TEasyViewGridItem = class(TEasyViewSmallIconItem)
end;
// **************************************************************************
// TEasyViewThumbnailItem
// Basis for the UI (drawing, and mouse interaction) for a TEasyItem
// **************************************************************************
TEasyViewThumbnailItem = class(TEasyViewItem)
public
function ExpandTextR(Item: TEasyItem; RectArray: TEasyRectArrayObject; SelectType: TEasySelectHitType): TRect; override;
function GetImageList(Column: TEasyColumn; Item: TEasyItem; Image: TEasyImageKind): TCustomImageList; override;
function PaintImageSize: TEasyImageSize; override;
procedure AfterSelRectCalc(Item: TEasyItem; Column: TEasyColumn; const Caption: WideString; var LocalSelRect: TRect); override;
procedure ItemRectArray(Item: TEasyItem; Column: TEasyColumn; ACanvas: TCanvas; const Caption: WideString; var RectArray: TEasyRectArrayObject); override;
function OverlappedFocus: Boolean; override;
procedure PaintAfter(Item: TEasyItem; Column: TEasyColumn; const Caption: WideString; ACanvas: TCanvas; RectArray: TEasyRectArrayObject); override;
procedure PaintBefore(Item: TEasyItem; Column: TEasyColumn; const Caption: WideString; ACanvas: TCanvas; RectArray: TEasyRectArrayObject; var Handled: Boolean); override;
function PaintTextLineCount(Item: TEasyItem; Column: TEasyColumn): Integer; override;
function PaintTextVAlignment(Item: TEasyItem; Column: TEasyColumn): TCommonVAlignment; override;
function SelectionHit(Item: TEasyItem; SelectViewportRect: TRect; SelectType: TEasySelectHitType): Boolean; override;
function SelectionHitPt(Item: TEasyItem; ViewportPoint: TPoint; SelectType: TEasySelectHitType): Boolean; override;
end;
// **************************************************************************
// TEasyViewTileItem
// Basis for the UI (drawing, and mouse interaction) for a TEasyItem
// **************************************************************************
TEasyViewTileItem = class(TEasyViewItem)
public
function ExpandIconR(Item: TEasyItem; RectArray: TEasyRectArrayObject; SelectType: TEasySelectHitType): TRect; override;
function ExpandTextR(Item: TEasyItem; RectArray: TEasyRectArrayObject; SelectType: TEasySelectHitType): TRect; override;
function GetImageList(Column: TEasyColumn; Item: TEasyItem; Image: TEasyImageKind): TCustomImageList; override;
function PaintImageSize: TEasyImageSize; override;
function PaintTextAlignment(Item: TEasyItem; Column: TEasyColumn): TAlignment; override;
procedure AfterSelRectCalc(Item: TEasyItem; Column: TEasyColumn; const Caption: WideString; var LocalSelRect: TRect); override;
procedure ItemRectArray(Item: TEasyItem; Column: TEasyColumn; ACanvas: TCanvas; const Caption: WideString; var RectArray: TEasyRectArrayObject); override;
procedure PaintBefore(Item: TEasyItem; Column: TEasyColumn; const Caption: WideString; ACanvas: TCanvas; RectArray: TEasyRectArrayObject; var Handled: Boolean); override;
procedure PaintText(Item: TEasyItem; Column: TEasyColumn; const Caption: WideString; RectArray: TEasyRectArrayObject; ACanvas: TCanvas; LinesToDraw: Integer); override;
end;
// **************************************************************************
// TEasyViewFilmStripItem
// Basis for the UI (drawing, and mouse interaction) for a TEasyItem
// **************************************************************************
TEasyViewFilmStripItem = class(TEasyViewThumbnailItem)
end;
// **************************************************************************
// TEasyViewTaskBandItem
// Basis for the UI (drawing, and mouse interaction) for a TEasyItem in the
// Taskband control
// **************************************************************************
TEasyViewTaskBandItem = class(TEasyViewSmallIconItem)
public
end;
// **************************************************************************
// TEasyItems
// Collection that contains all the Items within a Group in the control
// **************************************************************************
TEasyItems = class(TEasyCollection)
private
FOwnerGroup: TEasyGroup;
function GetItem(Index: Integer): TEasyItem;
procedure SetItem(Index: Integer; Value: TEasyItem);
protected
procedure DoStructureChange; override;
public
constructor Create(AnOwner: TCustomEasyListview; AnOwnerGroup: TEasyGroup); reintroduce; virtual;
destructor Destroy; override;
function Add(Data: TObject = nil): TEasyItem;
function AddInterfaced(const DataInf: IUnknown; Data: TObject = nil): TEasyItemInterfaced;
function AddVirtual(Data: TObject = nil): TEasyItemVirtual;
function AddCustom(CustomItem: TEasyItemClass; Data: TObject = nil): TEasyItem;
procedure Clear(FreeItems: Boolean = True); override;
procedure Delete(Index: Integer); reintroduce;
procedure Exchange(Index1, Index2: Integer); reintroduce;
function Insert(Index: Integer; Data: TObject = nil): TEasyItem;
function InsertCustom(Index: Integer; CustomItem: TEasyItemClass; Data: TObject = nil): TEasyItem;
function InsertInterfaced(Index: Integer; const DataInf: IUnknown; Data: TObject = nil): TEasyItemInterfaced;
function InsertVirtual(Index: Integer; Data: TObject = nil): TEasyItemVirtual;
property Items[Index: Integer]: TEasyItem read GetItem write SetItem; default;
property OwnerGroup: TEasyGroup read FOwnerGroup;
end;
// **************************************************************************
// TEasyGlobalItems
// Convenience TListview migration items
// **************************************************************************
TEasyGlobalItems = class
private
FOwner: TCustomEasyListview;
function GetCount: Integer;
function GetItem(Index: Integer): TEasyItem;
function GetItemInternal(Index: Integer): TEasyItem;
function GetLastGroup: TEasyGroup;
procedure EnsureFirstGroup;
procedure IndexError(Index: Integer);
procedure SetItem(Index: Integer; const Value: TEasyItem);
procedure SetReIndexDisable(const Value: Boolean);
public
constructor Create(AnOwner: TCustomEasyListview);
function Add(Data: TObject = nil): TEasyItem;
function AddCustom(CustomItem: TEasyItemClass; Data: TObject = nil): TEasyItem;
function AddInterfaced(const DataInf: IUnknown; Data: TObject = nil): TEasyItemInterfaced;
function AddVirtual(Data: TObject = nil): TEasyItemVirtual;
function IndexOf(Item: TEasyItem): Integer;
function Insert(Index: Integer; Data: TObject = nil): TEasyItem;
function InsertCustom(Index: Integer; CustomItem: TEasyItemClass; Data: TObject = nil): TEasyItem;
function InsertInterfaced(Index: Integer; const DataInf: IUnknown; Data: TObject = nil): TEasyItemInterfaced;
function InsertVirtual(Index: Integer; Data: TObject = nil): TEasyItemVirtual;
procedure Clear;
procedure Delete(Index: Integer; ReIndex: Boolean = True);
procedure Exchange(Index1, Index2: Integer);
property Count: Integer read GetCount;
property Items[Index: Integer]: TEasyItem read GetItem write SetItem; default;
property OwnerListview: TCustomEasyListview read FOwner;
property ReIndexDisable: Boolean write SetReIndexDisable;
end;
// **************************************************************************
// TEasyGlobalImageManager
// Manages images and bitmaps that are used in the EasyControl such as
// expand "+" buttons, etc.
// **************************************************************************
TEasyGlobalImageManager = class(TEasyOwnedPersistent)
private
FGroupExpandButton: TBitmap;
FGroupCollapseButton: TBitmap;
FColumnSortUp: TBitmap;
FColumnSortDown: TBitmap;
function GetColumnSortDown: TBitmap;
function GetColumnSortUp: TBitmap;
function GetGroupCollapseImage: TBitmap;
function GetGroupExpandImage: TBitmap;
procedure SetColumnSortDown(Value: TBitmap);
procedure SetColumnSortUp(Value: TBitmap);
procedure SetGroupCollapseImage(const Value: TBitmap);
procedure SetGroupExpandImage(const Value: TBitmap);
protected
procedure MakeTransparent(Bits: TBitmap; TransparentColor: TColor);
public
constructor Create(AnOwner: TCustomEasyListview); override;
destructor Destroy; override;
published
property GroupExpandButton: TBitmap read GetGroupExpandImage write SetGroupExpandImage;
property GroupCollapseButton: TBitmap read GetGroupCollapseImage write SetGroupCollapseImage;
property ColumnSortUp: TBitmap read GetColumnSortUp write SetColumnSortUp;
property ColumnSortDown: TBitmap read GetColumnSortDown write SetColumnSortDown;
end;
// **************************************************************************
// TEasyGridGroup
// Builds the Grid for the Group, by default the grid fits in the OwnerWindow
// horizontally and wraps down
// **************************************************************************
TEasyGridGroup = class(TEasyOwnedPersistent)
private
FColumnCount: Integer; // Number of Columns in the grid
FLayout: TEasyGridLayout;
FOwnerGroup: TEasyGroup; // The group that the grid is attached to
FRowCount: Integer; // The number of Rows in the group
function GetOwnerGroups: TEasyGroups;
protected
function AdjacentItem(Item: TEasyItem; Direction: TEasyAdjacentCellDir): TEasyItem; virtual;
function GetCellSize: TEasyCellSize; virtual; abstract;
function GetMaxColumns(Group: TEasyGroup; WindowWidth: Integer): Integer; virtual;
function LastItemInNColumn(Group: TEasyGroup; N: Integer): TEasyItem;
function NextVisibleGroupWithNItems(StartGroup: TEasyGroup; N: Integer): TEasyGroup;
function PrevVisibleGroupWithNItems(StartGroup: TEasyGroup; N: Integer): TEasyGroup;
function SearchForHitRight(ColumnPos: Integer; Pt: TPoint): TEasyItem;
function StaticTopItemMargin: Integer; virtual;
function StaticTopMargin: Integer; virtual;
procedure AutoSizeCells; virtual;
procedure FindLongestCaption(Column: TEasyColumn; var Item: TEasyItem);
procedure SetCellSize(Value: TEasyCellSize); virtual; abstract;
public
constructor Create(AnOwner: TCustomEasyListview; AnOwnerGroup: TEasyGroup); reintroduce; virtual;
destructor Destroy; override;
procedure FindInsertPosition(ViewportPoint: TPoint; var Group: TEasyGroup; var Index: Integer); virtual;
procedure Rebuild(PrevGroup: TEasyGroup; var NextVisibleItemIndex: Integer); virtual;
property CellSize: TEasyCellSize read GetCellSize write SetCellSize;
property ColumnCount: Integer read FColumnCount;
property Layout: TEasyGridLayout read FLayout;
property OwnerGroup: TEasyGroup read FOwnerGroup;
property OwnerGroups: TEasyGroups read GetOwnerGroups;
property RowCount: Integer read FRowCount;
end;
// **************************************************************************
// TEasyGridIconGroup
// Builds the Large Icon Grid for the Group
// **************************************************************************
TEasyGridIconGroup = class(TEasyGridGroup)
protected
function GetCellSize: TEasyCellSize; override;
procedure AutoSizeCells; override;
procedure SetCellSize(Value: TEasyCellSize); override;
public
end;
// **************************************************************************
// TEasyGridSmallIconGroup
// Builds the Small Icon Grid for the Group
// **************************************************************************
TEasyGridSmallIconGroup = class(TEasyGridGroup)
protected
function GetCellSize: TEasyCellSize; override;
procedure SetCellSize(Value: TEasyCellSize); override;
public
end;
// **************************************************************************
// TEasyGridListGroup
// Builds the List Grid for the Group
// **************************************************************************
TEasyGridListGroup = class(TEasyGridGroup)
protected
function AdjacentItem(Item: TEasyItem; Direction: TEasyAdjacentCellDir): TEasyItem; override;
function GetCellSize: TEasyCellSize; override;
procedure SetCellSize(Value: TEasyCellSize); override;
public
constructor Create(AnOwner: TCustomEasyListview; AnOwnerGroup: TEasyGroup); override;
procedure FindInsertPosition(ViewportPoint: TPoint; var Group: TEasyGroup; var Index: Integer); override;
procedure Rebuild(PrevGroup: TEasyGroup; var NextVisibleItemIndex: Integer); override;
end;
// **************************************************************************
// TEasyGridReportGroup
// Builds the Report Grid for the Group
// **************************************************************************
TEasyGridReportGroup = class(TEasyGridGroup)
protected
function AdjacentItem(Item: TEasyItem; Direction: TEasyAdjacentCellDir): TEasyItem; override;
function GetCellSize: TEasyCellSize; override;
procedure SetCellSize(Value: TEasyCellSize); override;
public
constructor Create(AnOwner: TCustomEasyListview; AnOwnerGroup: TEasyGroup); override;
procedure FindInsertPosition(ViewportPoint: TPoint; var Group: TEasyGroup; var Index: Integer); override;
procedure Rebuild(PrevGroup: TEasyGroup; var NextVisibleItemIndex: Integer); override;
end;
// **************************************************************************
// TEasyGridThumbnailGroup
// Builds the Thumbnail Grid for the Group
// **************************************************************************
TEasyGridThumbnailGroup = class(TEasyGridGroup)
protected
function GetCellSize: TEasyCellSize; override;
procedure AutoSizeCells; override;
procedure SetCellSize(Value: TEasyCellSize); override;
public
end;
// **************************************************************************
// TEasyGridTileGroup
// Builds the Tile Grid for the Group
// **************************************************************************
TEasyGridTileGroup = class(TEasyGridGroup)
protected
function GetCellSize: TEasyCellSize; override;
procedure SetCellSize(Value: TEasyCellSize); override;
public
procedure FindInsertPosition(ViewportPoint: TPoint; var Group: TEasyGroup; var Index: Integer); override;
end;
// **************************************************************************
// TEasyGridFilmStripGroup
// Builds the List Grid for the Group
// **************************************************************************
TEasyGridFilmStripGroup = class(TEasyGridListGroup)
protected
function GetCellSize: TEasyCellSize; override;
procedure AutoSizeCells; override;
procedure SetCellSize(Value: TEasyCellSize); override;
end;
// **************************************************************************
// TEasyGridGridGroup
// Builds the Report Grid for the Group
// **************************************************************************
TEasyGridGridGroup = class(TEasyGridGroup)
protected
function GetCellSize: TEasyCellSize; override;
procedure SetCellSize(Value: TEasyCellSize); override;
public
constructor Create(AnOwner: TCustomEasyListview; AnOwnerGroup: TEasyGroup); override;
procedure Rebuild(PrevGroup: TEasyGroup; var NextVisibleItemIndex: Integer); override;
end;
TEasyGridSingleColumn = class(TEasyGridGroup)
protected
function GetCellSize: TEasyCellSize; override;
function GetMaxColumns(Group: TEasyGroup; WindowWidth: Integer): Integer; override;
procedure AutoSizeCells; override;
procedure SetCellSize(Value: TEasyCellSize); override;
public
procedure FindInsertPosition(ViewportPoint: TPoint; var Group: TEasyGroup; var Index: Integer); override;
end;
// **************************************************************************
// TGridTaskBandGroup
// Builds the Report Grid for the Group in the Taskband control
// **************************************************************************
TEasyGridTaskBandGroup = class(TEasyGridSingleColumn)
private
FCellSize: TEasyCellSize;
protected
function GetCellSize: TEasyCellSize; override;
function StaticTopItemMargin: Integer; override;
function StaticTopMargin: Integer; override;
procedure SetCellSize(Value: TEasyCellSize); override;
property CellSize: TEasyCellSize read FCellSize write FCellSize;
public
constructor Create(AnOwner: TCustomEasyListview; AnOwnerGroup: TEasyGroup); override;
destructor Destroy; override;
end;
// **************************************************************************
// Grid for the TEasyTaskPanel component
// **************************************************************************
TEasyGridGroupTaskPanel = class(TEasyGridSingleColumn)
private
FCellSize: TEasyCellSize;
protected
function GetCellSize: TEasyCellSize; override;
function StaticTopMargin: Integer; override;
procedure SetCellSize(Value: TEasyCellSize); override;
public
constructor Create(AnOwner: TCustomEasyListview; AnOwnerGroup: TEasyGroup); override;
destructor Destroy; override;
procedure Rebuild(PrevGroup: TEasyGroup; var NextVisibleItemIndex: Integer); override;
published
end;
// **************************************************************************
// TEasyGroupBase
// Collection Item that represents a single group in the Listview
// **************************************************************************
TEasyGroup = class(TEasyCollectionItem)
private
FExpanded: Boolean; // Is the group expanded/collapsed
FGrid: TEasyGridGroup; // The UI grid that defines the item positions
FItems: TEasyItems; // The List of Items (TEasyItems) in the group
FKey: LongWord;
FView: TEasyViewGroup;
FVisibleItems: TList;
function GetBandBlended: Boolean;
function GetBandColor: TColor;
function GetBandColorFade: TColor;
function GetBandEnabled: Boolean;
function GetBandFullWidth: Boolean;
function GetBandIndent: Integer;
function GetBandLength: Integer;
function GetBandMargin: Integer;
function GetBandRadius: Byte;
function GetBandThickness: Integer;
function GetClientRect: TRect;
function GetExpandable: Boolean;
function GetExpandImageIndent: Integer;
function GetGrid: TEasyGridGroup;
function GetGridClass: TEasyGridGroupClass;
function GetItem(Index: Integer): TEasyItem;
function GetItemCount: Integer;
function GetMarginBottom: TEasyFooterMargin;
function GetMarginLeft: TEasyMargin;
function GetMarginRight: TEasyMargin;
function GetMarginTop: TEasyHeaderMargin;
function GetOwnerGroups: TEasyGroups;
function GetOwnerListview: TCustomEasyListview;
function GetPaintInfo: TEasyPaintInfoBaseGroup;
function GetView: TEasyViewGroup;
function GetViewClass: TEasyViewGroupClass;
function GetVisibleCount: Integer;
function GetVisibleItem(Index: Integer): TEasyItem;
procedure SetBandBlended(Value: Boolean);
procedure SetBandColor(Value: TColor);
procedure SetBandColorFade(Value: TColor);
procedure SetBandEnabled(Value: Boolean);
procedure SetBandFullWidth(Value: Boolean);
procedure SetBandIndent(Value: Integer);
procedure SetBandLength(Value: Integer);
procedure SetBandMargin(Value: Integer);
procedure SetBandRadius(Value: Byte);
procedure SetBandThickness(Value: Integer);
procedure SetExpandable(Value: Boolean);
procedure SetExpanded(Value: Boolean); virtual;
procedure SetExpandImageIndent(Value: Integer);
procedure SetItem(Index: Integer; Value: TEasyItem);
procedure SetMarginBottom(Value: TEasyFooterMargin);
procedure SetMarginLeft(Value: TEasyMargin);
procedure SetMarginRight(Value: TEasyMargin);
procedure SetMarginTop(Value: TEasyHeaderMargin);
procedure SetPaintInfo(const Value: TEasyPaintInfoBaseGroup);
protected
function CanChangeBold(NewValue: Boolean): Boolean; override;
function CanChangeCheck(NewValue: Boolean): Boolean; override;
function CanChangeEnable(NewValue: Boolean): Boolean; override;
function CanChangeFocus(NewValue: Boolean): Boolean; override;
function CanChangeHotTracking(NewValue: Boolean): Boolean; override;
function CanChangeSelection(NewValue: Boolean): Boolean; override;
function CanChangeVisibility(NewValue: Boolean): Boolean; override;
function DefaultImageList(ImageSize: TEasyImageSize): TCustomImageList; override;
function GetDefaultGridClass: TEasyGridGroupClass; virtual;
function GetDefaultViewClass: TEasyViewGroupClass; virtual;
function LocalPaintInfo: TEasyPaintInfoBasic; override;
procedure Freeing; override;
procedure GainingBold; override;
procedure GainingCheck; override;
procedure GainingEnable; override;
procedure GainingFocus; override;
procedure GainingGhosted; override;
procedure GainingHilight; override;
procedure GainingHotTracking(MousePos: TPoint); override;
procedure GainingSelection; override;
procedure GainingVisibility; override;
procedure Initialize; override;
procedure LosingBold; override;
procedure LosingCheck; override;
procedure LosingEnable; override;
procedure LosingFocus; override;
procedure LosingGhosted; override;
procedure LosingHilight; override;
procedure LosingHotTracking; override;
procedure LosingSelection; override;
procedure LosingVisibility; override;
property Alignment;
property BandBlended: Boolean read GetBandBlended write SetBandBlended default True;
property BandColor: TColor read GetBandColor write SetBandColor default clBlue;
property BandColorFade: TColor read GetBandColorFade write SetBandColorFade default clWindow;
property BandEnabled: Boolean read GetBandEnabled write SetBandEnabled default True;
property BandFullWidth: Boolean read GetBandFullWidth write SetBandFullWidth default False;
property BandIndent: Integer read GetBandIndent write SetBandIndent default 0;
property BandLength: Integer read GetBandLength write SetBandLength default 300;
property BandMargin: Integer read GetBandMargin write SetBandMargin default 0;
property BandRadius: Byte read GetBandRadius write SetBandRadius default 4;
property BandThickness: Integer read GetBandThickness write SetBandThickness default 3;
property CaptionIndent;
property CheckFlat;
property CheckIndent;
property CheckSize;
property CheckType;
property Expandable: Boolean read GetExpandable write SetExpandable default True;
property ExpandImageIndent: Integer read GetExpandImageIndent write SetExpandImageIndent default 4;
property ImageIndent;
property Key: LongWord read FKey write FKey;
property MarginBottom: TEasyFooterMargin read GetMarginBottom write SetMarginBottom;
property MarginLeft: TEasyMargin read GetMarginLeft write SetMarginLeft;
property MarginRight: TEasyMargin read GetMarginRight write SetMarginRight;
property MarginTop: TEasyHeaderMargin read GetMarginTop write SetMarginTop;
property OwnsPaintInfo;
property PaintInfo: TEasyPaintInfoBaseGroup read GetPaintInfo write SetPaintInfo;
property VAlignment default cvaCenter;
property VisibleItem[Index: Integer]: TEasyItem read GetVisibleItem;
property VisibleItems: TList read FVisibleItems write FVisibleItems;
public
constructor Create(ACollection: TEasyCollection); override;
destructor Destroy; override;
function BoundsRectBkGnd: TRect;
function BoundsRectBottomMargin: TRect;
function BoundsRectLeftMargin: TRect;
function BoundsRectRightMargin: TRect;
function BoundsRectTopMargin: TRect;
function EditAreaHitPt(ViewportPoint: TPoint): Boolean; override;
function HitTestAt(ViewportPoint: TPoint; var HitInfo: TEasyGroupHitTestInfoSet): Boolean;
function ItemByPoint(ViewportPoint: TPoint): TEasyItem;
procedure LoadFromStream(S: TStream; var Version: Integer); override;
procedure Paint(MarginEdge: TEasyGroupMarginEdge; ObjRect: TRect; ACanvas: TCanvas);
procedure Rebuild(PrevGroup: TEasyGroup; var NextVisibleItemIndex: Integer);
function SelectionHit(SelectViewportRect: TRect; SelectType: TEasySelectHitType): Boolean; override;
function SelectionHitPt(ViewportPoint: TPoint; SelectType: TEasySelectHitType): Boolean; override;
procedure SaveToStream(S: TStream; Version: Integer = EASYLISTVIEW_STREAM_VERSION); override;
property Bold;
property Caption;
property Checked;
property ClientRect: TRect read GetClientRect;
property Cut;
property Enabled;
property Expanded: Boolean read FExpanded write SetExpanded default True;
property Focused;
property Grid: TEasyGridGroup read GetGrid;
property GridClass: TEasyGridGroupClass read GetGridClass;
property ImageIndex;
property ImageOverlayIndex;
property Item[Index: Integer]: TEasyItem read GetItem write SetItem; default;
property ItemCount: Integer read GetItemCount;
property Items: TEasyItems read FItems write FItems;
property OwnerListview: TCustomEasyListview read GetOwnerListview;
property OwnerGroups: TEasyGroups read GetOwnerGroups;
property View: TEasyViewGroup read GetView;
property ViewClass: TEasyViewGroupClass read GetViewClass;
property Visible;
property VisibleCount: Integer read GetVisibleCount;
end;
TEasyGroupInterfaced = class(TEasyGroup)
protected
function GetCaptions(Line: Integer): Widestring; override;
function GetDetailCount: Integer; override;
function GetDetails(Line: Integer): Integer; override;
function GetImageIndexes(Column: Integer): TCommonImageIndexInteger; override;
function GetImageList(Column: Integer; IconSize: TEasyImageSize): TCustomImageList; override;
function GetImageOverlayIndexes(Column: Integer): TCommonImageIndexInteger; override;
procedure ImageDraw(Column: TEasyColumn; ACanvas: TCanvas; const RectArray: TEasyRectArrayObject; AlphaBlender: TEasyAlphaBlender); override;
procedure ImageDrawGetSize(Column: TEasyColumn; var ImageW: Integer; var ImageH: Integer); override;
procedure ImageDrawIsCustom(Column: TEasyColumn; var IsCustom: Boolean); override;
procedure SetCaptions(Column: Integer; Value: Widestring); override;
procedure SetDetailCount(Value: Integer); override;
procedure SetDetails(Line: Integer; Value: Integer); override;
procedure SetImageIndexes(Column: Integer; Value: TCommonImageIndexInteger); override;
procedure SetImageOverlayIndexes(Column: Integer; Value: TCommonImageIndexInteger); override;
procedure ThumbnailDraw(ACanvas: TCanvas; ARect: TRect; AlphaBlender: TEasyAlphaBlender; var DoDefault: Boolean); override;
public
property DataInf;
end;
TEasyBaseGroupStored = class(TEasyGroup)
private
FDataHelper: TEasyDynamicDataHelper;
protected
function GetCaptions(Line: Integer): Widestring; override;
function GetDetailCount: Integer; override;
function GetDetails(Line: Integer): Integer; override;
function GetImageIndexes(Column: Integer): TCommonImageIndexInteger; override;
function GetImageList(Column: Integer; IconSize: TEasyImageSize): TCustomImageList; override;
function GetImageOverlayIndexes(Column: Integer): TCommonImageIndexInteger ; override;
procedure ImageDraw(Column: TEasyColumn; ACanvas: TCanvas; const RectArray: TEasyRectArrayObject; AlphaBlender: TEasyAlphaBlender); override;
procedure ImageDrawGetSize(Column: TEasyColumn; var ImageW: Integer; var ImageH: Integer); override;
procedure ImageDrawIsCustom(Column: TEasyColumn; var IsCustom: Boolean); override;
procedure SetCaptions(Column: Integer; Value: Widestring); override;
procedure SetDetailCount(Value: Integer); override;
procedure SetDetails(Line: Integer; Value: Integer); override;
procedure SetImageIndexes(Column: Integer; Value: TCommonImageIndexInteger); override;
procedure SetImageOverlayIndexes(Column: Integer; Value: TCommonImageIndexInteger); override;
procedure ThumbnailDraw(ACanvas: TCanvas; ARect: TRect; AlphaBlender: TEasyAlphaBlender; var DoDefault: Boolean); override;
property DataHelper: TEasyDynamicDataHelper read FDataHelper write FDataHelper;
public
constructor Create(ACollection: TEasyCollection); override;
destructor Destroy; override;
procedure LoadFromStream(S: TStream; var Version: Integer); override;
procedure SaveToStream(S: TStream; Version: Integer = EASYLISTVIEW_STREAM_VERSION); override;
end;
TEasyGroupStored = class(TEasyBaseGroupStored)
published
property Caption;
property Bold;
property Checked;
property Cut;
property Enabled;
property Expanded;
property ImageIndex;
property ImageOverlayIndex;
property Items;
property Tag;
property Visible;
end;
//
// Group for the TEasyTaskPanel component
//
TEasyGroupTaskPanel = class(TEasyBaseGroupStored)
private
FHeight: Integer;
FTaskPanel: TEasyTaskPanelForm;
function GetTaskWindowCreated: Boolean;
procedure SetExpanded(Value: Boolean); override;
procedure SetHeight(const Value: Integer);
procedure SetInitialized(Value: Boolean); override;
protected
procedure CreateTaskWindow;
public
constructor Create(ACollection: TEasyCollection); override;
destructor Destroy; override;
procedure LoadFromStream(S: TStream; var Version: Integer); override;
procedure SaveToStream(S: TStream; Version: Integer = EASYLISTVIEW_STREAM_VERSION); override;
property TaskPanel: TEasyTaskPanelForm read FTaskPanel;
published
property Caption;
property Bold;
property Checked;
property Cut;
property Enabled;
property Expanded;
property Height: Integer read FHeight write SetHeight default 100;
property ImageIndex;
property ImageOverlayIndex;
property Tag;
property TaskWindowCreated: Boolean read GetTaskWindowCreated;
property Visible;
end;
TEasyGroupVirtual = class(TEasyGroup)
protected
function GetCaptions(Line: Integer): Widestring; override;
function GetDetailCount: Integer; override;
function GetDetails(Line: Integer): Integer; override;
function GetImageIndexes(Column: Integer): TCommonImageIndexInteger; override;
function GetImageList(Column: Integer; IconSize: TEasyImageSize): TCustomImageList; override;
function GetImageOverlayIndexes(Column: Integer): TCommonImageIndexInteger; override;
procedure ImageDraw(Column: TEasyColumn; ACanvas: TCanvas; const RectArray: TEasyRectArrayObject; AlphaBlender: TEasyAlphaBlender); override;
procedure ImageDrawGetSize(Column: TEasyColumn; var ImageW: Integer; var ImageH: Integer); override;
procedure ImageDrawIsCustom(Column: TEasyColumn; var IsCustom: Boolean); override;
procedure SetCaptions(Column: Integer; Value: Widestring); override;
procedure SetDetailCount(Value: Integer); override;
procedure SetDetails(Line: Integer; Value: Integer); override;
procedure SetImageIndexes(Column: Integer; Value: TCommonImageIndexInteger); override;
procedure SetImageOverlayIndexes(Column: Integer; Value: TCommonImageIndexInteger); override;
procedure ThumbnailDraw(ACanvas: TCanvas; ARect: TRect; AlphaBlender: TEasyAlphaBlender; var DoDefault: Boolean); override;
end;
// **************************************************************************
// TEasyViewGroup
// Implements the basis for the UI (drawing, and mouse interaction) for a EasyGroup
// **************************************************************************
TEasyViewGroup = class(TEasyOwnedPersistentGroupItem)
protected
function CustomExpandImages: Boolean;
procedure GetCollapseExpandImages(var Expand, Collapse: TBitmap);
public
function EditAreaHitPt(Group: TEasyGroup; ViewportPoint: TPoint): Boolean; virtual;
function GetImageList(Group: TEasyGroup): TCustomImageList;
procedure GetExpandImageSize(Group: TEasyGroup; var ImageW, ImageH: Integer); virtual;
procedure GetImageSize(Group: TEasyGroup; var ImageW, ImageH: Integer); virtual;
procedure GroupRectArray(Group: TEasyGroup; MarginEdge: TEasyGroupMarginEdge; ObjRect: TRect; var RectArray: TEasyRectArrayObject); virtual;
procedure LoadTextFont(Group: TEasyGroup; ACanvas: TCanvas); virtual;
procedure Paint(Group: TEasyGroup; MarginEdge: TEasyGroupMarginEdge; ObjRect: TRect; ACanvas: TCanvas); virtual;
procedure PaintAfter(Group: TEasyGroup; ACanvas: TCanvas; MarginEdge: TEasyGroupMarginEdge; ObjRect: TRect; RectArray: TEasyRectArrayObject); virtual;
procedure PaintBackground(Group: TEasyGroup; ACanvas: TCanvas; MarginEdge: TEasyGroupMarginEdge; ObjRect: TRect; RectArray: TEasyRectArrayObject); virtual;
procedure PaintBand(Group: TEasyGroup; ACanvas: TCanvas; MarginEdge: TEasyGroupMarginEdge; ObjRect: TRect; RectArray: TEasyRectArrayObject); virtual;
procedure PaintBefore(Group: TEasyGroup; ACanvas: TCanvas; MarginEdge: TEasyGroupMarginEdge; ObjRect: TRect; RectArray: TEasyRectArrayObject); virtual;
procedure PaintCheckBox(Group: TEasyGroup; ACanvas: TCanvas; RectArray: TEasyRectArrayObject); virtual;
procedure PaintExpandButton(Group: TEasyGroup; ACanvas: TCanvas; MarginEdge: TEasyGroupMarginEdge; ObjRect: TRect; RectArray: TEasyRectArrayObject); virtual;
procedure PaintFocusRect(Group: TEasyGroup; ACanvas: TCanvas; MarginEdge: TEasyGroupMarginEdge; ObjRect: TRect; RectArray: TEasyRectArrayObject); virtual;
procedure PaintImage(Group: TEasyGroup; ACanvas: TCanvas; MarginEdge: TEasyGroupMarginEdge; ObjRect: TRect; RectArray: TEasyRectArrayObject); virtual;
procedure PaintSelectionRect(Group: TEasyGroup; ACanvas: TCanvas; ObjRect: TRect; RectArray: TEasyRectArrayObject); virtual;
procedure PaintText(Group: TEasyGroup; MarginEdge: TEasyGroupMarginEdge; ACanvas: TCanvas; ObjRect: TRect; RectArray: TEasyRectArrayObject); virtual;
function SelectionHit(Group: TEasyGroup; SelectViewportRect: TRect; SelectType: TEasySelectHitType): Boolean; virtual;
function SelectionHitPt(Group: TEasyGroup; ViewportPoint: TPoint; SelectType: TEasySelectHitType): Boolean; virtual;
end;
// **************************************************************************
// TEasyViewTaskBandGroup
// Implements the basis for the UI (drawing, and mouse interaction) for a EasyGroup
// in the TaskBand control
// **************************************************************************
TEasyViewTaskBandGroup = class(TEasyViewGroup)
protected
function DrawThemed: Boolean; virtual;
procedure PaintTextTopThemed(ACanvas: TCanvas; Group: TEasyGroup; ObjRect: TRect; RectArray: TEasyRectArrayObject); virtual;
public
procedure GetExpandImageSize(Group: TEasyGroup; var ImageW: Integer; var ImageH: Integer); override;
procedure GroupRectArray(Group: TEasyGroup; MarginEdge: TEasyGroupMarginEdge; ObjRect: TRect; var RectArray: TEasyRectArrayObject); override;
procedure LoadTextFont(Group: TEasyGroup; ACanvas: TCanvas); override;
procedure PaintBackground(Group: TEasyGroup; ACanvas: TCanvas; MarginEdge: TEasyGroupMarginEdge; ObjRect: TRect; RectArray: TEasyRectArrayObject); override;
procedure PaintBand(Group: TEasyGroup; ACanvas: TCanvas; MarginEdge: TEasyGroupMarginEdge; ObjRect: TRect; RectArray: TEasyRectArrayObject); override;
procedure PaintExpandButton(Group: TEasyGroup; ACanvas: TCanvas; MarginEdge: TEasyGroupMarginEdge; ObjRect: TRect; RectArray: TEasyRectArrayObject); override;
procedure PaintText(Group: TEasyGroup; MarginEdge: TEasyGroupMarginEdge; ACanvas: TCanvas; ObjRect: TRect; RectArray: TEasyRectArrayObject); override;
end;
// **************************************************************************
// TEasyViewTaskPanelGroup
// Implements the basis for the UI (drawing, and mouse interaction) for a EasyGroup
// in the TaskPanel control
// **************************************************************************
TEasyViewTaskPanelGroup = class(TEasyViewTaskBandGroup)
protected
public
procedure PaintBefore(Group: TEasyGroup; ACanvas: TCanvas; MarginEdge: TEasyGroupMarginEdge; ObjRect: TRect; RectArray: TEasyRectArrayObject); override;
end;
// **************************************************************************
// TEasyGroups
// Collection that contains all the Groups in the control
// **************************************************************************
TEasyGroups = class(TEasyCollection)
private
FGroupsState: TEasyGroupsStates;
FStreamGroups: Boolean;
function GetCellHeight: Integer;
function GetCellWidth: Integer;
function GetGroup(Index: Integer): TEasyGroup;
function GetItemCount: Integer;
function GetViewRect: TRect;
function GetVisibleGroup(Index: Integer): TEasyGroup;
procedure SetCellHeight(Value: Integer);
procedure SetCellWidth(Value: Integer);
procedure SetGroup(Index: Integer; Value: TEasyGroup);
protected
function FirstGroupInternal(VisibleOnly: Boolean): TEasyGroup;
function FirstInGroupInternal(Group: TEasyGroup; VisibleOnly: Boolean): TEasyItem;
function FirstItemInternal(NextItemType: TEasyNextItemType): TEasyItem;
function LastGroupInternal(VisibleOnly: Boolean): TEasyGroup;
function LastInGroupInternal(Group: TEasyGroup; VisibleOnly: Boolean): TEasyItem;
function LastItemInternal(NextItemType: TEasyNextItemType): TEasyItem;
function NavigateGroupInternal(Group: TEasyGroup; VisibleOnly: Boolean; Direction: TEasySearchDirection): TEasyGroup;
function NavigateInGroupInternal(Group: TEasyGroup; Item: TEasyItem; VisibleOnly: Boolean; Direction: TEasySearchDirection): TEasyItem;
function NavigateItemInternal(Item: TEasyItem; NextItemType: TEasyNextItemType; Direction: TEasySearchDirection): TEasyItem;
procedure DoStructureChange; override;
property GroupsState: TEasyGroupsStates read FGroupsState write FGroupsState;
property VisibleGroup[Index: Integer]: TEasyGroup read GetVisibleGroup;
public
constructor Create(AnOwner: TCustomEasyListview); reintroduce; virtual;
destructor Destroy; override;
function Add(Data: TObject = nil): TEasyGroup;
function AddInterfaced(const DataInf: IUnknown; Data: TObject = nil): TEasyGroupInterfaced;
function AddVirtual(Data: TObject = nil): TEasyGroupVirtual;
function AddCustom(CustomGroup: TEasyGroupClass; Data: TObject = nil): TEasyGroup;
function AdjacentItem(Item: TEasyItem; Direction: TEasyAdjacentCellDir): TEasyItem;
function CanMoveDown: Boolean;
function CanMoveUp: Boolean;
procedure Clear(FreeItems: Boolean = True); override;
procedure CollapseAll;
procedure DeleteGroup(Group: TEasyGroup);
procedure DeleteItem(Item: TEasyItem);
procedure DeleteItems(ItemArray: TEasyItemArray);
procedure ExpandAll;
function FirstGroup: TEasyGroup;
function FirstGroupInRect(ViewportRect: TRect): TEasyGroup;
function FirstInGroup(Group: TEasyGroup): TEasyItem;
function FirstInitializedItem: TEasyItem;
function FirstItem: TEasyItem;
function FirstItemInRect(ViewportRect: TRect): TEasyItem;
function FirstVisibleGroup: TEasyGroup;
function FirstVisibleInGroup(Group: TEasyGroup): TEasyItem;
function FirstVisibleItem: TEasyItem;
function GroupByPoint(ViewportPoint: TPoint): TEasyGroup;
function Insert(Index: Integer; Data: TObject = nil): TEasyGroup;
function InsertCustom(Index: Integer; CustomGroup: TEasyGroupClass; Data: TObject = nil): TEasyGroup;
function InsertInterfaced(Index: Integer; const DataInf: IUnknown; Data: TObject): TEasyGroupInterfaced;
function InsertVirtual(Index: Integer; Data: TObject = nil): TEasyGroupVirtual;
procedure InitializeAll;
procedure InvalidateItem(Item: TEasyCollectionItem; ImmediateUpdate: Boolean);
function LastGroup: TEasyGroup;
function LastInGroup(Group: TEasyGroup): TEasyItem;
function LastInitializedItem: TEasyItem;
function LastItem: TEasyItem;
function LastVisibleGroup: TEasyGroup;
function LastVisibleInGroup(Group: TEasyGroup): TEasyItem;
function LastVisibleItem: TEasyItem;
function ItemByPoint(ViewportPoint: TPoint): TEasyItem;
function MoveDown: Boolean;
function MoveUp: Boolean;
function NextEditableItem(Item: TEasyItem): TEasyItem;
function NextGroup(Group: TEasyGroup): TEasyGroup;
function NextGroupInRect(Group: TEasyGroup; ViewportRect: TRect): TEasyGroup;
function NextInitializedItem(Item: TEasyItem): TEasyItem;
function NextInGroup(Group: TEasyGroup; Item: TEasyItem): TEasyItem;
function NextItem(Item: TEasyItem): TEasyItem;
function NextItemInRect(Item: TEasyItem; ViewportRect: TRect): TEasyItem;
function NextVisibleGroup(Group: TEasyGroup): TEasyGroup;
function NextVisibleGroupWithVisibleItems(Group: TEasyGroup): TEasyGroup;
function NextVisibleInGroup(Group: TEasyGroup; Item: TEasyItem): TEasyItem;
function NextVisibleItem(Item: TEasyItem): TEasyItem;
function PrevEditableItem(Item: TEasyItem): TEasyItem;
function PrevGroup(Group: TEasyGroup): TEasyGroup;
function PrevInGroup(Group: TEasyGroup; Item: TEasyItem): TEasyItem;
function PrevInitializedItem(Item: TEasyItem): TEasyItem;
function PrevItem(Item: TEasyItem): TEasyItem;
function PrevVisibleGroup(Group: TEasyGroup): TEasyGroup;
function PrevVisibleGroupWithVisibleItems(Group: TEasyGroup): TEasyGroup;
function PrevVisibleInGroup(Group: TEasyGroup; Item: TEasyItem): TEasyItem;
function PrevVisibleItem(Item: TEasyItem): TEasyItem;
procedure LoadFromStream(S: TStream; Version: Integer = EASYLISTVIEW_STREAM_VERSION); override;
procedure MakeAllVisible; override;
procedure Move(Item: TEasyItem; NewGroup: TEasyGroup);
procedure Rebuild(Force: Boolean = False); virtual;
procedure SaveToStream(S: TStream; Version: Integer = EASYLISTVIEW_STREAM_VERSION); override;
procedure UnInitializeAll;
property CellHeight: Integer read GetCellHeight write SetCellHeight;
property CellWidth: Integer read GetCellWidth write SetCellWidth;
property Groups[Index: Integer]: TEasyGroup read GetGroup write SetGroup; default;
property ItemCount: Integer read GetItemCount;
property StreamGroups: Boolean read FStreamGroups write FStreamGroups default True;
property ViewRect: TRect read GetViewRect;
end;
// Specical Groups container and Groups for the TEasyTaskPanel component
TEasyGroupsTaskPanel = class(TEasyGroups)
private
function GetGroup(Index: Integer): TEasyGroupTaskPanel;
procedure SetGroup(Index: Integer; Value: TEasyGroupTaskPanel);
public
constructor Create(AnOwner: TCustomEasyListview); override;
property Groups[Index: Integer]: TEasyGroupTaskPanel read GetGroup write SetGroup; default;
end;
// **************************************************************************
// TEasyCellSize
// Maintains the default sizes for the Cells a single view (grid)
// **************************************************************************
TEasyCellSize = class(TEasyOwnedPersistent)
private
FAutoSize: Boolean;
FAutoSizeHeight: Integer; // Dynamic size that is reset with each rebuid of the Groups if the Grid is AutoSized
FAutoSizeWidth: Integer; // Dynamic size that is reset with each rebuid of the Groups if the Grid is AutoSized
FHeight: Integer; // Fixed size that remains constant with each rebuid of the Groups if the Grid is not AutoSized
FWidth: Integer; // Fixed size that remains constant with each rebuid of the Groups if the Grid is not AutoSized
function GetHeight: Integer;
function GetWidth: Integer;
procedure SetAutoSize(const Value: Boolean);
procedure SetHeight(Value: Integer);
procedure SetWidth(Value: Integer);
protected
property AutoSizeHeight: Integer read FAutoSizeHeight write FAutoSizeHeight;
property AutoSizeWidth: Integer read FAutoSizeWidth write FAutoSizeWidth;
public
constructor Create(AnOwner: TCustomEasyListview); override;
procedure Assign(Source: TPersistent); override;
procedure SetSize(AWidth, AHeight: Integer);
published
property AutoSize: Boolean read FAutoSize write SetAutoSize default False;
property Height: Integer read GetHeight write SetHeight default 75;
property Width: Integer read GetWidth write SetWidth default 75;
end;
// **************************************************************************
// TEasyCellSizeIcon
// Maintains the default sizes for the Cells a Icon view
// **************************************************************************
TEasyCellSizeIcon = class(TEasyCellSize)
end;
// **************************************************************************
// TEasyCellSizeSmallIcon
// Maintains the default sizes for the Cells a Small Icon view
// **************************************************************************
TEasyCellSizeSmallIcon = class(TEasyCellSize)
public
constructor Create(AnOwner: TCustomEasyListview); override;
published
property Width default 200;
property Height default 17;
end;
// **************************************************************************
// TEasyCellSizeThumbnail
// Maintains the default sizes for the Cells a Thumbnail view
// **************************************************************************
TEasyCellSizeThumbnail = class(TEasyCellSize)
public
constructor Create(AnOwner: TCustomEasyListview); override;
published
property Width default 125;
property Height default 143;
end;
// **************************************************************************
// TEasyCellSizeTile
// Maintains the default sizes for the Cells a Tile view
// **************************************************************************
TEasyCellSizeTile = class(TEasyCellSize)
public
constructor Create(AnOwner: TCustomEasyListview); override;
published
property Width default 218;
property Height default 58;
end;
// **************************************************************************
// TEasyCellSizeList
// Maintains the default sizes for the Cells a List view
// **************************************************************************
TEasyCellSizeList = class(TEasyCellSize)
public
constructor Create(AnOwner: TCustomEasyListview); override;
published
property Width default 200;
property Height default 17;
end;
// **************************************************************************
// TEasyCellSizeReport
// Maintains the default sizes for the Cells a Report view
// **************************************************************************
TEasyCellSizeReport = class(TEasyCellSize)
public
constructor Create(AnOwner: TCustomEasyListview); override;
published
property Width default 75;
property Height default 17;
end;
// **************************************************************************
// TEasyCellSizeFilmStrip
// Maintains the default sizes for the Cells a FilmStrip view
// **************************************************************************
TEasyCellSizeFilmStrip = class(TEasyCellSizeThumbnail)
end;
// **************************************************************************
// TEasyCellGrid
// Maintains the default sizes for the Cells a FilmStrip view
// **************************************************************************
TEasyCellGrid = class(TEasyCellSizeReport)
end;
// **************************************************************************
// TEasyCellSizes
// Maintains the default sizes for the Cells in each view
// **************************************************************************
TEasyCellSizes = class(TEasyOwnedPersistent)
private
FFilmStrip: TEasyCellSize;
FIcon: TEasyCellSize;
FList: TEasyCellSize;
FReport: TEasyCellSize;
FSmallIcon: TEasyCellSize;
FGrid: TEasyCellSize;
FThumbnail: TEasyCellSize;
FTile: TEasyCellSize;
public
constructor Create(AnOwner: TCustomEasyListview); override;
destructor Destroy; override;
published
property FilmStrip: TEasyCellSize read FFilmStrip write FFilmStrip;
property Icon: TEasyCellSize read FIcon write FIcon;
property SmallIcon: TEasyCellSize read FSmallIcon write FSmallIcon;
property Grid: TEasyCellSize read FGrid write FGrid;
property Thumbnail: TEasyCellSize read FThumbnail write FThumbnail;
property Tile: TEasyCellSize read FTile write FTile;
property List: TEasyCellSize read FList write FList;
property Report: TEasyCellSize read FReport write FReport;
end;
TEasyColumnDropDownButtonState = (
cdbsHovering, // Mouse is hovering over the button
cdbsDown, // Mouse is pressing the button
cdbsClickPending // Button was pressed down and held while on the button, may have been moved off the button
);
TEasyColumnDropDownButtonStates = set of TEasyColumnDropDownButtonState;
TEasyColumnDropDownButton = class(TPersistent)
private
FAlwaysShow: Boolean; // By default the button only shows when the mouse is hovering over the column header
FEnabled: Boolean;
FMenu: TPopupMenu;
FOwner: TEasyColumn;
FState: TEasyColumnDropDownButtonStates;
FVisible: Boolean;
procedure SetAlwaysShow(const Value: Boolean);
procedure SetEnabled(const Value: Boolean);
procedure SetVisible(const Value: Boolean);
public
property State: TEasyColumnDropDownButtonStates read FState write FState;
published
constructor Create(AnOwner: TEasyColumn);
property AlwaysShow: Boolean read FAlwaysShow write SetAlwaysShow default False;
property Enabled: Boolean read FEnabled write SetEnabled default True;
property Menu: TPopupMenu read FMenu write FMenu;
property Owner: TEasyColumn read FOwner;
property Visible: Boolean read FVisible write SetVisible default False;
end;
// **************************************************************************
// TEasyColumn
// Collection Item that represents a single column in the Listview
// **************************************************************************
TEasyColumn = class(TEasyCollectionItem)
private
FAlignment: TAlignment;
FAutoSizeOnDblClk: Boolean; // Autosizes column when double clicked in size area
FAutoSortOnClick: Boolean;
FAutoSpring: Boolean; // Sizes column based on width of window
FAutoToggleSortGlyph: Boolean;
FClickable: Boolean;
FDropDownButton: TEasyColumnDropDownButton;
FPosition: Integer;
FSortDirection: TEasySortDirection;
FSpringRest: Single;
FStyle: TEasyHeaderButtonStyle;
FView: TEasyViewColumn;
FWidth: Integer;
function GetAlignment: TAlignment;
function GetColor: TColor;
function GetHotTrack: Boolean;
function GetImagePosition: TEasyHeaderImagePosition;
function GetOwnerColumns: TEasyColumns;
function GetOwnerHeader: TEasyHeader;
function GetPaintInfo: TEasyPaintInfoColumn;
function GetSortGlyphAlign: TEasySortGlyphAlign;
function GetSortGlyphIndent: Integer;
function GetStyle: TEasyHeaderButtonStyle;
function GetView: TEasyViewColumn;
function GetViewClass: TEasyViewColumnClass;
procedure SetAlignment(Value: TAlignment);
procedure SetAutoSpring(const Value: Boolean);
procedure SetColor(Value: TColor);
procedure SetHotTrack(Value: Boolean);
procedure SetImagePosition(Value: TEasyHeaderImagePosition);
procedure SetPaintInfo(Value: TEasyPaintInfoColumn);
procedure SetPosition(Value: Integer);
procedure SetSortDirection(Value: TEasySortDirection);
procedure SetSortGlpyhAlign(Value: TEasySortGlyphAlign);
procedure SetSortGlyphIndent(Value: Integer);
procedure SetStyle(Value: TEasyHeaderButtonStyle);
procedure SetWidth(Value: Integer);
protected
function CanChangeBold(NewValue: Boolean): Boolean; override;
function CanChangeCheck(NewValue: Boolean): Boolean; override;
function CanChangeEnable(NewValue: Boolean): Boolean; override;
function CanChangeFocus(NewValue: Boolean): Boolean; override;
function CanChangeHotTracking(NewValue: Boolean): Boolean; override;
function CanChangeSelection(NewValue: Boolean): Boolean; override;
function CanChangeVisibility(NewValue: Boolean): Boolean; override;
function DefaultImageList(ImageSize: TEasyImageSize): TCustomImageList; override;
function GetDefaultViewClass: TEasyViewColumnClass; virtual;
function LocalPaintInfo: TEasyPaintInfoBasic; override;
procedure AutoSizeToFit; virtual;
procedure Freeing; override;
procedure GainingBold; override;
procedure GainingCheck; override;
procedure GainingEnable; override;
procedure GainingFocus; override;
procedure GainingGhosted; override;
procedure GainingHilight; override;
procedure GainingHotTracking(MousePos: TPoint); override;
procedure GainingSelection; override;
procedure GainingVisibility; override;
procedure Initialize; override;
procedure LosingBold; override;
procedure LosingCheck; override;
procedure LosingEnable; override;
procedure LosingFocus; override;
procedure LosingGhosted; override;
procedure LosingHilight; override;
procedure LosingHotTracking; override;
procedure LosingSelection; override;
procedure LosingVisibility; override;
property Color: TColor read GetColor write SetColor;
property HotTrack: Boolean read GetHotTrack write SetHotTrack;
property ImagePosition: TEasyHeaderImagePosition read GetImagePosition write SetImagePosition;
property SortGlyphAlign: TEasySortGlyphAlign read GetSortGlyphAlign write SetSortGlpyhAlign;
property SortGlyphIndent: Integer read GetSortGlyphIndent write SetSortGlyphIndent;
property SpringRest: Single read FSpringRest write FSpringRest;
property Style: TEasyHeaderButtonStyle read GetStyle write SetStyle;
public
constructor Create(ACollection: TEasyCollection); override;
destructor Destroy; override;
function EditAreaHitPt(ViewportPoint: TPoint): Boolean; override;
function HitTestAt(ViewportPoint: TPoint; var HitInfo: TEasyColumnHitTestInfoSet): Boolean;
function PaintMouseHovering: Boolean;
procedure Invalidate(ImmediateUpdate: Boolean); override;
procedure LoadFromStream(S: TStream; var Version: Integer); override;
procedure MakeVisible(Position: TEasyMakeVisiblePos); override;
procedure Paint(ACanvas: TCanvas; HeaderType: TEasyHeaderType);
function SelectionHit(SelectViewportRect: TRect; SelectType: TEasySelectHitType): Boolean; override;
function SelectionHitPt(ViewportPoint: TPoint; SelectType: TEasySelectHitType): Boolean; override;
procedure SaveToStream(S: TStream; Version: Integer = EASYLISTVIEW_STREAM_VERSION); override;
property Alignment: TAlignment read GetAlignment write SetAlignment default taLeftJustify;
property AutoSizeOnDblClk: Boolean read FAutoSizeOnDblClk write FAutoSizeOnDblClk default True;
property AutoSortOnClick: Boolean read FAutoSortOnClick write FAutoSortOnClick default False;
property AutoSpring: Boolean read FAutoSpring write SetAutoSpring default False;
property AutoToggleSortGlyph: Boolean read FAutoToggleSortGlyph write FAutoToggleSortGlyph default True;
property Bold;
property Caption;
property Checked;
property Clickable: Boolean read FClickable write FClickable default True;
property Clicking;
property DropDownButton: TEasyColumnDropDownButton read FDropDownButton write FDropDownButton;
property Enabled;
property ImageIndex;
property ImageOverlayIndex;
property OwnerColumns: TEasyColumns read GetOwnerColumns;
property OwnerHeader: TEasyHeader read GetOwnerHeader;
property OwnsPaintInfo;
property PaintInfo: TEasyPaintInfoColumn read GetPaintInfo write SetPaintInfo;
property Position: Integer read FPosition write SetPosition;
property Selected;
property SortDirection: TEasySortDirection read FSortDirection write SetSortDirection default esdNone;
property Tag;
property View: TEasyViewColumn read GetView;
property ViewClass: TEasyViewColumnClass read GetViewClass;
property Visible;
property Width: Integer read FWidth write SetWidth default 50;
end;
TEasyColumnInterfaced = class(TEasyColumn)
protected
function GetCaptions(Line: Integer): Widestring; override;
function GetDetailCount: Integer; override;
function GetDetails(Line: Integer): Integer; override;
function GetImageIndexes(Column: Integer): TCommonImageIndexInteger; override;
function GetImageList(Column: Integer; IconSize: TEasyImageSize): TCustomImageList; override;
function GetImageOverlayIndexes(Column: Integer): TCommonImageIndexInteger; override;
procedure ImageDraw(Column: TEasyColumn; ACanvas: TCanvas; const RectArray: TEasyRectArrayObject; AlphaBlender: TEasyAlphaBlender); override;
procedure ImageDrawGetSize(Column: TEasyColumn; var ImageW: Integer; var ImageH: Integer); override;
procedure ImageDrawIsCustom(Column: TEasyColumn; var IsCustom: Boolean); override;
procedure SetCaptions(Column: Integer; Value: Widestring); override;
procedure SetDetailCount(Value: Integer); override;
procedure SetDetails(Line: Integer; Value: Integer); override;
procedure SetImageIndexes(Column: Integer; Value: TCommonImageIndexInteger); override;
procedure SetImageOverlayIndexes(Column: Integer; Value: TCommonImageIndexInteger); override;
procedure ThumbnailDraw(ACanvas: TCanvas; ARect: TRect; AlphaBlender: TEasyAlphaBlender; var DoDefault: Boolean); override;
public
property DataInf;
end;
TEasyColumnStored = class(TEasyColumn)
private
FDataHelper: TEasyDynamicDataHelper;
protected
function GetCaptions(Line: Integer): Widestring; override;
function GetDetailCount: Integer; override;
function GetDetails(Line: Integer): Integer; override;
function GetImageIndexes(Column: Integer): TCommonImageIndexInteger; override;
function GetImageList(Column: Integer; IconSize: TEasyImageSize): TCustomImageList; override;
function GetImageOverlayIndexes(Column: Integer): TCommonImageIndexInteger; override;
procedure ImageDraw(Column: TEasyColumn; ACanvas: TCanvas; const RectArray: TEasyRectArrayObject; AlphaBlender: TEasyAlphaBlender); override;
procedure ImageDrawGetSize(Column: TEasyColumn; var ImageW: Integer; var ImageH: Integer); override;
procedure ImageDrawIsCustom(Column: TEasyColumn; var IsCustom: Boolean); override;
procedure SetCaptions(Column: Integer; Value: Widestring); override;
procedure SetDetailCount(Value: Integer); override;
procedure SetDetails(Line: Integer; Value: Integer); override;
procedure SetImageIndexes(Column: Integer; Value: TCommonImageIndexInteger); override;
procedure SetImageOverlayIndexes(Column: Integer; Value: TCommonImageIndexInteger); override;
procedure ThumbnailDraw(ACanvas: TCanvas; ARect: TRect; AlphaBlender: TEasyAlphaBlender; var DoDefault: Boolean); override;
property DataHelper: TEasyDynamicDataHelper read FDataHelper write FDataHelper;
public
constructor Create(ACollection: TEasyCollection); override;
destructor Destroy; override;
procedure LoadFromStream(S: TStream; var Version: Integer); override;
procedure SaveToStream(S: TStream; Version: Integer = EASYLISTVIEW_STREAM_VERSION); override;
published
property Alignment;
property AutoSizeOnDblClk;
property AutoSortOnClick;
property AutoSpring;
property AutoToggleSortGlyph;
property Bold;
property Caption;
property Checked;
property Clickable;
property Color;
property DropDownButton;
property Enabled;
property ImageIndex;
property ImageOverlayIndex;
property Position;
property Selected;
property SortDirection;
property Width;
property Visible;
end;
TEasyColumnVirtual = class(TEasyColumn)
protected
function GetCaptions(Line: Integer): Widestring; override;
function GetDetailCount: Integer; override;
function GetDetails(Line: Integer): Integer; override;
function GetImageIndexes(Column: Integer): TCommonImageIndexInteger; override;
function GetImageList(Column: Integer; IconSize: TEasyImageSize): TCustomImageList; override;
function GetImageOverlayIndexes(Column: Integer): TCommonImageIndexInteger; override;
procedure ImageDraw(Column: TEasyColumn; ACanvas: TCanvas; const RectArray: TEasyRectArrayObject; AlphaBlender: TEasyAlphaBlender); override;
procedure ImageDrawGetSize(Column: TEasyColumn; var ImageW: Integer; var ImageH: Integer); override;
procedure ImageDrawIsCustom(Column: TEasyColumn; var IsCustom: Boolean); override;
procedure SetCaptions(Column: Integer; Value: Widestring); override;
procedure SetDetailCount(Value: Integer); override;
procedure SetDetails(Line: Integer; Value: Integer); override;
procedure SetImageIndexes(Column: Integer; Value: TCommonImageIndexInteger); override;
procedure SetImageOverlayIndexes(Column: Integer; Value: TCommonImageIndexInteger); override;
procedure ThumbnailDraw(ACanvas: TCanvas; ARect: TRect;AlphaBlender: TEasyAlphaBlender; var DoDefault: Boolean); override;
end;
// **************************************************************************
// TEasyViewColumn
// Implements the basis for the UI (drawing, and mouse interaction) for a EasyColumn
// **************************************************************************
TEasyViewColumn = class(TEasyOwnedPersistentView)
public
function EditAreaHitPt(Column: TEasyColumn; ViewportPoint: TPoint): Boolean; virtual;
function GetImageList(Column: TEasyColumn): TCustomImageList;
procedure CalculateTextRect(Column: TEasyColumn; Canvas: TControlCanvas; var TextR: TRect); virtual;
procedure GetImageSize(Column: TEasyColumn; var ImageW, ImageH: Integer);
function ItemRect(Column: TEasyColumn; RectType: TEasyCellRectType): TRect; virtual;
procedure ItemRectArray(Column: TEasyColumn; var RectArray: TEasyRectArrayObject); virtual;
procedure LoadTextFont(Column: TEasyColumn; ACanvas: TCanvas); virtual;
procedure Paint(Column: TEasyColumn; ACanvas: TCanvas; HeaderType: TEasyHeaderType); virtual;
procedure PaintAfter(Column: TEasyColumn; ACanvas: TCanvas; HeaderType: TEasyHeaderType; RectArray: TEasyRectArrayObject); virtual;
procedure PaintBefore(Column: TEasyColumn; ACanvas: TCanvas; HeaderType: TEasyHeaderType; RectArray: TEasyRectArrayObject); virtual;
procedure PaintBkGnd(Column: TEasyColumn; ACanvas: TCanvas; HeaderType: TEasyHeaderType; RectArray: TEasyRectArrayObject); virtual;
procedure PaintCheckBox(Column: TEasyColumn; ACanvas: TCanvas; HeaderType: TEasyHeaderType; RectArray: TEasyRectArrayObject); virtual;
procedure PaintDropDownArrow(Column: TEasyColumn; ACanvas: TCanvas; HeaderType: TEasyHeaderType; RectArray: TEasyRectArrayObject); virtual;
procedure PaintDropGlyph(Column: TEasyColumn; ACanvas: TCanvas; HeaderType: TEasyHeaderType; RectArray: TEasyRectArrayObject); virtual;
procedure PaintFocusRect(Column: TEasyColumn; ACanvas: TCanvas; HeaderType: TEasyHeaderType; RectArray: TEasyRectArrayObject); virtual;
procedure PaintImage(Column: TEasyColumn; ACanvas: TCanvas; HeaderType: TEasyHeaderType; RectArray: TEasyRectArrayObject; ImageSize: TEasyImageSize); virtual;
function PaintImageSize(Column: TEasyColumn; HeaderType: TEasyHeaderType): TEasyImageSize; virtual;
procedure PaintSortGlyph(Column: TEasyColumn; ACanvas: TCanvas; HeaderType: TEasyHeaderType; RectArray: TEasyRectArrayObject); virtual;
procedure PaintText(Column: TEasyColumn; ACanvas: TCanvas; HeaderType: TEasyHeaderType; RectArray: TEasyRectArrayObject; LinesToDraw: Integer); virtual;
procedure ReSizeRectArray(var RectArray: TEasyRectArrayObjectArray); virtual;
function SelectionHit(Column: TEasyColumn; SelectViewportRect: TRect; SelectType: TEasySelectHitType): Boolean; virtual;
function SelectionHitPt(Column: TEasyColumn; ViewportPoint: TPoint; SelectType: TEasySelectHitType): Boolean; virtual;
end;
// **************************************************************************
// TEasyGroups
// Collection that contains all the Columns in the control
// **************************************************************************
TEasyColumns = class(TEasyCollection)
private
function GetColumns(Index: Integer): TEasyColumn;
function GetOwnerHeader: TEasyHeader;
procedure SetColumns(Index: Integer; Value: TEasyColumn);
protected
procedure DoItemAdd(Item: TEasyCollectionItem; Index: Integer); override;
procedure DoStructureChange; override;
public
constructor Create(AnOwner: TCustomEasyListview); reintroduce; virtual;
destructor Destroy; override;
function Add(Data: TObject = nil): TEasyColumn;
function AddInterfaced(const DataInf: IUnknown; Data: TObject): TEasyColumnInterfaced;
function AddVirtual(Data: TObject = nil): TEasyColumnVirtual;
function AddCustom(CustomItem: TEasyColumnClass; Data: TObject = nil): TEasyColumn;
function ColumnByPoint(ViewportPoint: TPoint): TEasyColumn;
function Insert(Index: Integer; Data: TObject = nil): TEasyColumn;
function InsertCustom(Index: Integer; CustomColumn: TEasyColumnClass; Data: TObject = nil): TEasyColumn;
function InsertInterfaced(Index: Integer; const DataInf: IUnknown; Data: TObject = nil): TEasyColumnInterfaced;
function InsertVirtual(Index: Integer; Data: TObject = nil): TEasyColumnVirtual;
procedure Clear(FreeItems: Boolean = True); override;
property Columns[Index: Integer]: TEasyColumn read GetColumns write SetColumns; default;
property OwnerHeader: TEasyHeader read GetOwnerHeader;
end;
TColumnPos = class(TList)
private
function Get(Index: Integer): TEasyColumn;
procedure Put(Index: Integer; Item: TEasyColumn);
public
property Items[Index: Integer]: TEasyColumn read Get write Put; default;
end;
// **************************************************************************
// TEasyHeader
// Header area of the Listview
// **************************************************************************
TEasyHeader = class(TEasyOwnedPersistent)
private
FAutoSizeHeight: Boolean;
FAutoSizeHeightMargin: Integer;
FCanvasStore: TEasyCanvasStore;
FColor: TColor; // Color of the header
FColumns: TEasyColumns; // The columns that define the header
FDisplayRect: TRect; // Rectangle occupied in the Client Window of the Listview, clips column not visible due to scrollbar position of LV
FDragManager: TEasyHeaderDragManager;
FDropDownHoverColumn: TEasyColumn; // Column that has the DropDownButton and the mouse over it (or button pressed)
FFixedSingleColumn: Boolean;
FFont: TFont; // The font the header text is drawn in
FHeight: Integer; // Height of the header
FHotTrackedColumn: TEasyColumn; // the column that is current in a hot tracked state
FImages: TCustomImageList; // Images for the header columns
FLastWidth: Integer;
FPositions: TColumnPos;
FPressColumn: TEasyColumn; // Column that currently pressed
FResizeColumn: TEasyColumn; // Column that is currently being resized
FShowInAllViews: Boolean;
FSizeable: Boolean; // The column widths are resizeable by the mouse
FState: TEasyHeaderStates; // Current state of the header
FStreamColumns: Boolean;
FViewRect: TRect; // The total size of the header including the column not visible in the current window
FVisible: Boolean; // Shows/Hides the header in the control
function GetCanvasStore: TEasyCanvasStore;
function GetDisplayRect: TRect;
function GetDraggable: Boolean;
function GetFixedSingleColumn: Boolean;
function GetHeight: Integer;
function GetMouseCaptured: Boolean;
function GetRuntimeHeight: Integer;
procedure SetAutoSizeHeight(const Value: Boolean);
procedure SetAutoSizeHeightMargin(const Value: Integer);
procedure SetColor(Value: TColor);
procedure SetDraggable(Value: Boolean);
procedure SetDropDownHoverColumn(const Value: TEasyColumn);
procedure SetFixedSingleColumn(const Value: Boolean);
procedure SetFont(Value: TFont);
procedure SetHeight(Value: Integer);
procedure SetHotTrackedColumn(const Value: TEasyColumn);
procedure SetImages(Value: TCustomImageList);
procedure SetShowInAllViews(const Value: Boolean);
procedure SetVisible(Value: Boolean);
function GetViewWidth: Integer;
protected
function InCheckZone(ViewportPt: TPoint; var Column: TEasyColumn): Boolean;
function InDropDownButtonZone(ViewportPt: TPoint; var Column: TEasyColumn): Boolean;
function InHotTrackZone(ViewportPt: TPoint; var Column: TEasyColumn): Boolean;
function InPressZone(ViewportPt: TPoint; var Column: TEasyColumn): Boolean;
function InResizeZone(ViewportPt: TPoint; var Column: TEasyColumn): Boolean;
function IsFontStored: Boolean;
procedure CaptureMouse;
procedure ClearStates;
procedure DoMouseDown(var Message: TWMMouse; Button: TCommonMouseButton; Shift: TShiftState; Column: TEasyColumn);
procedure DoMouseMove(var Message: TWMMouse; Shift: TShiftState);
procedure DoMouseUp(var Message: TWMMouse; Button: TCommonMouseButton; Shift: TShiftState; Column: TEasyColumn);
procedure HandleHotTrack(Msg: TWMMouse; ForceClear: Boolean);
procedure ReleaseMouse;
procedure SizeFixedSingleColumn(NewWidth: Integer);
procedure SpringColumns(NewWidth: Integer);
procedure WMContextMenu(var Msg: TMessage); message WM_CONTEXTMENU;
procedure WMLButtonDblClk(var Msg: TWMLButtonDblClk); message WM_LBUTTONDBLCLK;
procedure WMLButtonDown(var Msg: TWMLButtonDown); message WM_LBUTTONDOWN;
procedure WMLButtonUp(var Msg: TWMLButtonUp); message WM_LBUTTONUP;
procedure WMMouseMove(var Msg: TWMMouseMove); message WM_MOUSEMOVE;
procedure WMRButtonDown(var Msg: TWMRButtonDown); message WM_RBUTTONDOWN;
procedure WMRButtonUp(var Msg: TWMRButtonUp); message WM_RBUTTONUP;
procedure WMSize(var Msg: TWMSize); message WM_SIZE;
property CanvasStore: TEasyCanvasStore read GetCanvasStore write FCanvasStore;
property DropDownHoverColumn: TEasyColumn read FDropDownHoverColumn write SetDropDownHoverColumn;
property HotTrackedColumn: TEasyColumn read FHotTrackedColumn write SetHotTrackedColumn;
property LastWidth: Integer read FLastWidth write FLastWidth;
property Positions: TColumnPos read FPositions write FPositions;
property PressColumn: TEasyColumn read FPressColumn write FPressColumn;
property ResizeColumn: TEasyColumn read FResizeColumn write FResizeColumn;
property RuntimeHeight: Integer read GetRuntimeHeight;
property State: TEasyHeaderStates read FState write FState;
public
constructor Create(AnOwner: TCustomEasyListview); override;
destructor Destroy; override;
function FirstColumn: TEasyColumn;
function FirstColumnByPosition: TEasyColumn;
function FirstColumnInRect(ViewportRect: TRect): TEasyColumn;
function FirstVisibleColumn: TEasyColumn;
function LastColumn: TEasyColumn;
function LastVisibleColumn: TEasyColumn;
function NextColumn(AColumn: TEasyColumn): TEasyColumn;
function NextColumnByPosition(AColumn: TEasyColumn): TEasyColumn;
function NextVisibleColumn(Column: TEasyColumn): TEasyColumn;
function PrevColumn(AColumn: TEasyColumn): TEasyColumn;
function PrevColumnByPosition(AColumn: TEasyColumn): TEasyColumn;
function PrevVisibleColumn(Column: TEasyColumn): TEasyColumn;
procedure ClickColumn(Column: TEasyColumn);
procedure Invalidate(ImmediateUpdate: Boolean); virtual;
procedure InvalidateColumn(Item: TEasyColumn; ImmediateUpdate: Boolean); virtual;
function LastColumnByPosition: TEasyColumn;
function NextColumnInRect(Column: TEasyColumn; ViewportRect: TRect): TEasyColumn;
procedure LoadFromStream(S: TStream; Version: Integer = EASYLISTVIEW_STREAM_VERSION); override;
procedure PaintTo(ACanvas: TCanvas; ARect: TRect); virtual;
procedure Rebuild(Force: Boolean); virtual;
procedure SaveToStream(S: TStream; Version: Integer = EASYLISTVIEW_STREAM_VERSION); override;
property DisplayRect: TRect read GetDisplayRect write FDisplayRect;
property MouseCaptured: Boolean read GetMouseCaptured;
property StreamColumns: Boolean read FStreamColumns write FStreamColumns default True;
property ViewRect: TRect read FViewRect;
property ViewWidth: Integer read GetViewWidth;
published
property AutoSizeHeight: Boolean read FAutoSizeHeight write SetAutoSizeHeight default True;
property AutoSizeHeightMargin: Integer read FAutoSizeHeightMargin write SetAutoSizeHeightMargin default 8;
property Color: TColor read FColor write SetColor default clBtnFace;
property Columns: TEasyColumns read FColumns write FColumns;
property Draggable: Boolean read GetDraggable write SetDraggable default True;
property DragManager: TEasyHeaderDragManager read FDragManager write FDragManager;
property FixedSingleColumn: Boolean read GetFixedSingleColumn write SetFixedSingleColumn default False;
property Font: TFont read FFont write SetFont stored IsFontStored;
property Height: Integer read GetHeight write SetHeight default 21;
property Images: TCustomImageList read FImages write SetImages;
property ShowInAllViews: Boolean read FShowInAllViews write SetShowInAllViews default False;
property Sizeable: Boolean read FSizeable write FSizeable default True;
property Visible: Boolean read FVisible write SetVisible default False;
end;
// **************************************************************************
// TEasyEditManager
// EasyEditManager defines the base class to edit an item. The
// IEasyCellEditorSink allows the Editor to communicate back to the manager for
// event dispatching without the need for the Editor interface to have knowledge
// of the TManagerLink object.
// **************************************************************************
TEasyEditManager = class(TEasyOwnedPersistent)
private
FAppHooked: Boolean;
FAutoEditDelayTime: Integer; // Time (in milliseconds) before the object is edited
FAutoEditStartClickPt: TPoint; // This is in WINDOW coordinates, the point where the mouse is clicked. Used to determine if the AutoEdit should begin
FColor: TColor;
FEditColumn: TEasyColumn;
FEditFinished: Boolean; // Set when the edit is done
FEditing: Boolean; // Set when the edit is in progress
FEditItem: TEasyItem; // The Item that is being edited
FEditor: IEasyCellEditor;
FEnabled: Boolean; // The Edit Manager is enabled
FFont: TFont;
FTabEditColumns: Boolean;
FTabMoveFocus: Boolean; // If an item is begin edited a tab move the focus to the next item and puts it in edit
FTabMoveFocusColumn: TEasyColumn;
FTabMoveFocusItem: TEasyItem;
FTimer: TTimer; // The timer for auto Edit
FTimerRunning: Boolean; // True when the auto Edit is timing out
function GetEditing: Boolean;
procedure SetEnabled(const Value: Boolean);
procedure SetFont(const Value: TFont);
protected
function MainWindowHook(var Message: TMessage): Boolean;
procedure StartAutoEditTimer;
procedure StopAutoEditTimer;
procedure TimerEvent(Sender: TObject);
property AppHooked: Boolean read FAppHooked write FAppHooked;
property AutoEditStartClickPt: TPoint read FAutoEditStartClickPt write FAutoEditStartClickPt;
property EditColumn: TEasyColumn read FEditColumn write FEditColumn;
property TabEditColumns: Boolean read FTabEditColumns write FTabEditColumns default False;
property TabMoveFocusColumn: TEasyColumn read FTabMoveFocusColumn write FTabMoveFocusColumn;
property TabMoveFocusItem: TEasyItem read FTabMoveFocusItem write FTabMoveFocusItem;
property Timer: TTimer read FTimer write FTimer;
property TimerRunning: Boolean read FTimerRunning;
public
constructor Create(AnOwner: TCustomEasyListview); override;
destructor Destroy; override;
procedure BeginEdit(Item: TEasyItem; Column: TEasyColumn); virtual;
procedure EndEdit;
property Editing: Boolean read GetEditing;
property EditItem: TEasyItem read FEditItem;
property Editor: IEasyCellEditor read FEditor write FEditor;
published
property AutoEditDelayTime: Integer read FAutoEditDelayTime write FAutoEditDelayTime default 300;
property Color: TColor read FColor write FColor default clWindow;
property Enabled: Boolean read FEnabled write SetEnabled default False;
property Font: TFont read FFont write SetFont;
property TabMoveFocus: Boolean read FTabMoveFocus write FTabMoveFocus default False;
end;
// **************************************************************************
// TEasyEnumFormatEtcManager
// The EnumFormatEtc Manager encapsulates the IEnumFormatEtc interface for
// use with the IDataObject (below) interface for Drag/Drop and Clipboard
// operations.
// **************************************************************************
TEasyEnumFormatEtcManager = class(TEasyInterfacedPersistent, IEnumFormatEtc)
private
FInternalIndex: integer; // Keeps an internal reference to which format is being enumerated
FFormats: TFormatEtcArray; // Keeps a list of all formats that are avaialable in the IDataObject
protected
{ IEnumFormatEtc }
function Next(celt: Longint; out elt; pceltFetched: PLongint): HResult; stdcall;
function Skip(celt: Longint): HResult; stdcall;
function Reset: HResult; stdcall;
function Clone(out Enum: IEnumFormatEtc): HResult; stdcall;
property InternalIndex: integer read FInternalIndex write FInternalIndex;
public
constructor Create;
destructor Destroy; override;
property Formats: TFormatEtcArray read FFormats write FFormats;
end;
// **************************************************************************
// TEasyDataObjectManager
// The Data Object Manager encapsulates the IDataObject interface into a
// Delphi class. It is used for Drag/Drop and Clipboard operations
// **************************************************************************
TEasyDataObjectManager = class(TCommonDataObject, IDataObject, ICommonDataObject, ICommonExtractObj)
private
FListview: TCustomEasyListview;
protected
procedure DoGetCustomFormats(var Formats: TFormatEtcArray); override;
procedure DoOnGetData(const FormatEtcIn: TFormatEtc; var Medium: TStgMedium; var Handled: Boolean); override;
procedure DoOnQueryGetData(const FormatEtcIn: TFormatEtc; var FormatAvailable: Boolean; var Handled: Boolean); override;
public
property Listview: TCustomEasyListview read FListview write FListview;
end;
// **************************************************************************
// TEasyDragManagerBase
// Easy Base Drag Manager defines the common actions of the Drag Select
// and object Drag Manager, including autoscroll
// **************************************************************************
TCustomEasyDragManagerBase = class(TEasyOwnedPersistent)
private
FAutoScroll: Boolean;
FAutoScrollDelay: Integer;
FAutoScrollDelayMet: Boolean;
FAutoScrollTime: Integer;
FDataObject: IDataObject;
FMouseButton: TCommonMouseButtons; // Defines what mouse buttons are used for a drag
FRegistered: Boolean;
FTimer: TTimer;
FDragState: TEasyDragManagerStates;
FLastKeyState: TCommonKeyStates;
FEnabled: Boolean;
FAutoScrollAccelerator: Byte;
FAutoScrollMargin: Integer;
function GetAutoScrolling: Boolean;
function GetDragging: Boolean;
function GetTimer: TTimer;
procedure SetRegistered(Value: Boolean);
protected
procedure AutoScrollWindow; virtual;
procedure DoAfterAutoScroll; virtual;
procedure DoBeforeAutoScroll; virtual;
procedure DoAutoScroll(DeltaX, DeltaY: Integer); virtual;
procedure DoDrag(Canvas: TCanvas; WindowPoint: TPoint; KeyState: TCommonKeyStates; var Effects: TCommonDropEffect); virtual;
procedure DoDragBegin(WindowPoint: TPoint; KeyState: TCommonKeyStates); virtual;
procedure DoDragDrop(WindowPoint: TPoint; KeyState: TCommonKeyStates; var Effects: TCommonDropEffect); virtual;
procedure DoDragEnd(Canvas: TCanvas; WindowPoint: TPoint; KeyState: TCommonKeyStates); virtual;
procedure DoDragEnter(const DataObject: IDataObject; Canvas: TCanvas; WindowPoint: TPoint; KeyState: TCommonKeyStates; var Effects: TCommonDropEffect); virtual;
procedure DoGetDragImage(Bitmap: TBitmap; DragStartPt: TPoint; var HotSpot: TPoint; var TransparentColor: TColor; var Handled: Boolean); virtual;
procedure DoOLEDragEnd(const ADataObject: IDataObject; DragResult: TCommonOLEDragResult; ResultEffect: TCommonDropEffects; KeyStates: TCommonKeyStates); virtual;
procedure DoOLEDragStart(const ADataObject: IDataObject; var AvailableEffects: TCommonDropEffects; var AllowDrag: Boolean); virtual;
function DoPtInAutoScrollDownRegion(WindowPoint: TPoint): Boolean; virtual;
function DoPtInAutoScrollLeftRegion(WindowPoint: TPoint): Boolean; virtual;
function DoPtInAutoScrollRightRegion(WindowPoint: TPoint): Boolean; virtual;
function DoPtInAutoScrollUpRegion(WindowPoint: TPoint): Boolean; virtual;
procedure DoEnable(Enable: Boolean); virtual;
function PtInAutoScrollDownRegion(WindowPoint: TPoint): Boolean;
function PtInAutoScrollLeftRegion(WindowPoint: TPoint): Boolean;
function PtInAutoScrollRegion(WindowPoint: TPoint): Boolean;
function PtInAutoScrollRightRegion(WindowPoint: TPoint): Boolean;
function PtInAutoScrollUpRegion(WindowPoint: TPoint): Boolean;
function ScrollDeltaDown(WindowPoint: TPoint): Integer; virtual;
function ScrollDeltaLeft(WindowPoint: TPoint): Integer; virtual;
function ScrollDeltaRight(WindowPoint: TPoint): Integer; virtual;
function ScrollDeltaUp(WindowPoint: TPoint): Integer; virtual;
procedure RegisterOLEDragDrop(DoRegister: Boolean);
procedure SetEnabled(const Value: Boolean); virtual;
procedure UpdateAfterAutoScroll; virtual;
procedure VCLDragStart; virtual;
property DataObject: IDataObject read FDataObject write FDataObject;
property LastKeyState: TCommonKeyStates read FLastKeyState write FLastKeyState;
public
constructor Create(AnOwner: TCustomEasyListview); override;
destructor Destroy; override;
procedure BeginDrag(WindowPoint: TPoint; KeyState: TCommonKeyStates); virtual;
procedure Drag(Canvas: TCanvas; WindowPoint: TPoint; KeyState: TCommonKeyStates; var Effects: TCommonDropEffect);
procedure DragEnd(Canvas: TCanvas; WindowPoint: TPoint; KeyState: TCommonKeyStates);
procedure DragEnter(const ADataObject: IDataObject; Canvas: TCanvas; WindowPoint: TPoint; KeyState: TCommonKeyStates; var Effects: TCommonDropEffect);
procedure DragDrop(WindowPoint: TPoint; KeyState: TCommonKeyStates; var Effects: TCommonDropEffect);
procedure HandleTimer(Sender: TObject); virtual;
procedure WMKeyDown(var Msg: TWMKeyDown); virtual;
property AutoScroll: Boolean read FAutoScroll write FAutoScroll default True;
property AutoScrollAccelerator: Byte read FAutoScrollAccelerator write FAutoScrollAccelerator default 2;
property AutoScrollDelay: Integer read FAutoScrollDelay write FAutoScrollDelay default _AUTOSCROLLDELAY;
property AutoScrollDelayMet: Boolean read FAutoScrollDelayMet;
property AutoScrolling: Boolean read GetAutoScrolling;
property AutoScrollMargin: Integer read FAutoScrollMargin write FAutoScrollMargin default 15;
property AutoScrollTime: Integer read FAutoScrollTime write FAutoScrollTime default _AUTOSCROLLTIME;
property Dragging: Boolean read GetDragging;
property DragState: TEasyDragManagerStates read FDragState write FDragState;
property Enabled: Boolean read FEnabled write SetEnabled;
property MouseButton: TCommonMouseButtons read FMouseButton write FMouseButton default [cmbLeft];
property Timer: TTimer read GetTimer write FTimer;
property Registered: Boolean read FRegistered write SetRegistered;
published
end;
// **************************************************************************
// TEasyHeaderDragManager
// Drag Manager is associated with the Header in the EasyListview for
// dragging columns around
// **************************************************************************
TEasyHeaderDragManager = class(TCustomEasyDragManagerBase)
private
FAllowDrop: Boolean;
FColumn: TEasyColumn;
FDefaultImageEvent: TGetDragImageEvent;
FDragImageHeight: Integer;
FDragImageWidth: Integer;
FDragMode: TDragMode; // VCL Only
FDragType: TEasyDragType;
FEnableDragImage: Boolean;
FHeader: TEasyHeader;
FTargetColumn: TEasyColumn;
function GetDragCursor: TCursor;
function GetDragMode: TDragMode;
procedure SetDragCursor(Value: TCursor);
procedure SetDragMode(Value: TDragMode);
procedure SetDragType(Value: TEasyDragType);
protected
function DoPtInAutoScrollDownRegion(WindowPoint: TPoint): Boolean; override;
function DoPtInAutoScrollUpRegion(WindowPoint: TPoint): Boolean; override;
procedure DefaultImage(Sender: TCustomEasyListview; Image: TBitmap; DragStartPt: TPoint; var HotSpot: TPoint; var TransparentColor: TColor; var Handled: Boolean); virtual;
procedure DoDrag(Canvas: TCanvas; WindowPoint: TPoint; KeyState: TCommonKeyStates; var Effects: TCommonDropEffect); override;
procedure DoDragBegin(WindowPoint: TPoint; KeyStates: TCommonKeyStates); override;
procedure DoDragDrop(WindowPoint: TPoint; KeyState: TCommonKeyStates; var Effects: TCommonDropEffect); override;
procedure DoDragEnd(Canvas: TCanvas; WindowPoint: TPoint; KeyState: TCommonKeyStates); override;
procedure DoDragEnter(const DataObject: IDataObject; Canvas: TCanvas; WindowPoint: TPoint; KeyState: TCommonKeyStates; var Effects: TCommonDropEffect); override;
procedure DoOLEDragEnd(const ADataObject: IDataObject; DragResult: TCommonOLEDragResult; ResultEffect: TCommonDropEffects; KeyStates: TCommonKeyStates); override;
procedure DoOLEDragStart(const ADataObject: IDataObject; var AvailableEffects: TCommonDropEffects; var AllowDrag: Boolean); override;
function DoPtInAutoScrollLeftRegion(WindowPoint: TPoint): Boolean; override;
function DoPtInAutoScrollRightRegion(WindowPoint: TPoint): Boolean; override;
procedure ImageSize(var Width, Height: Integer); virtual;
property AllowDrop: Boolean read FAllowDrop write FAllowDrop;
property Column: TEasyColumn read FColumn write FColumn;
property DefaultImageEvent: TGetDragImageEvent read FDefaultImageEvent write FDefaultImageEvent;
property DragImageHeight: Integer read FDragImageHeight write FDragImageHeight default 300;
property DragImageWidth: Integer read FDragImageWidth write FDragImageWidth default 200;
property DragMode: TDragMode read GetDragMode write SetDragMode default dmManual;
property DragType: TEasyDragType read FDragType write SetDragType default edtOLE;
property Header: TEasyHeader read FHeader write FHeader;
property TargetColumn: TEasyColumn read FTargetColumn write FTargetColumn;
public
constructor Create(AnOwner: TCustomEasyListview); override;
published
property AutoScroll;
property AutoScrollAccelerator;
property AutoScrollDelay;
property AutoScrollMargin;
property AutoScrollTime;
property DragCursor: TCursor read GetDragCursor write SetDragCursor default crDrag;
property EnableDragImage: Boolean read FEnableDragImage write FEnableDragImage default True;
property MouseButton;
end;
// **************************************************************************
// TEasyDragManager
// Easy Drag Manager is associated with a TWinContol to track the
// dragging of the cells in a Easy Control
// **************************************************************************
TEasyOLEDragManager = class(TEasyHeaderDragManager)
private
FDragAnchorPt: TPoint;
FDragItem: TEasyItem;
FDragTarget: Boolean;
FDropTarget: TEasyItem;
FHilightDropTarget: Boolean;
protected
procedure ClearDragItem;
procedure ClearDropTarget;
procedure DefaultImage(Sender: TCustomEasyListview; Image: TBitmap; DragStartPt: TPoint; var HotSpot: TPoint; var TransparentColor: TColor; var Handled: Boolean); override;
procedure DoDrag(Canvas: TCanvas; WindowPoint: TPoint; KeyState: TCommonKeyStates; var Effects: TCommonDropEffect); override;
procedure DoDragDrop(WindowPoint: TPoint; KeyState: TCommonKeyStates; var Effects: TCommonDropEffect); override;
procedure DoDragEnd(Canvas: TCanvas; WindowPoint: TPoint; KeyState: TCommonKeyStates); override;
procedure DoDragEnter(const DataObject: IDataObject; Canvas: TCanvas; WindowPoint: TPoint; KeyState: TCommonKeyStates; var Effects: TCommonDropEffect); override;
procedure DoGetDragImage(Bitmap: TBitmap; DragStartPt: TPoint; var HotSpot: TPoint; var TransparentColor: TColor; var Handled: Boolean); override;
procedure DoOLEDragEnd(const ADataObject: IDataObject; DragResult: TCommonOLEDragResult; ResultEffect: TCommonDropEffects; KeyStates: TCommonKeyStates); override;
procedure DoOLEDragStart(const ADataObject: IDataObject; var AvailableEffects: TCommonDropEffects; var AllowDrag: Boolean); override;
function DoPtInAutoScrollDownRegion(WindowPoint: TPoint): Boolean; override;
function DoPtInAutoScrollUpRegion(WindowPoint: TPoint): Boolean; override;
procedure ImageSize(var Width: Integer; var Height: Integer); override;
procedure SetEnabled(const Value: Boolean); override;
procedure VCLDragStart; override;
public
constructor Create(AnOwner: TCustomEasyListview); override;
destructor Destroy; override;
procedure FinalizeDrag(KeyState: TCommonKeyStates);
function InitializeDrag(HitItem: TEasyItem; WindowPoint: TPoint; KeyState: TCommonKeyStates): Boolean;
property DragAnchorPt: TPoint read FDragAnchorPt write FDragAnchorPt;
property DragItem: TEasyItem read FDragItem;
property DragTarget: Boolean read FDragTarget;
property DropTarget: TEasyItem read FDropTarget;
published
property AutoScroll;
property AutoScrollAccelerator;
property AutoScrollDelay;
property AutoScrollMargin;
property AutoScrollTime;
property DragImageHeight;
property DragImageWidth;
property DragMode;
property DragType;
property Enabled default False;
property HilightDropTarget: Boolean read FHilightDropTarget write FHilightDropTarget default True;
property MouseButton;
end;
// **************************************************************************
// TEasySelectionManager
// Easy Select Manager is associated with a TWinContol to track the
// selection and focus of the cells in a Easy Control.
// **************************************************************************
TEasySelectionManager = class(TEasyOwnedPersistent)
private
FAlphaBlend: Boolean;
FAlphaBlendSelRect: Boolean;
FBlendAlphaImage: Byte;
FBlendAlphaSelRect: Byte;
FBlendAlphaTextRect: Byte;
FBlendColorIcon: TColor;
FBlendColorSelRect: TColor;
FBlendIcon: Boolean;
FBlurAlphaBkGnd: Boolean;
FBorderColor: TColor;
FBorderColorSelRect: TColor;
FColor: TColor;
FCount: Integer;
FFocusedColumn: TEasyColumn;
FFocusedItem: TEasyItem;
FAnchorItem: TEasyItem;
FFocusedGroup: TEasyGroup;
FEnabled: Boolean;
FForceDefaultBlend: Boolean;
FFullCellPaint: Boolean;
FFullItemPaint: Boolean;
FFullRowSelect: Boolean;
FGradient: Boolean;
FGradientColorBottom: TColor;
FGradientColorTop: TColor;
FGroupSelections: Boolean;
FGroupSelectUpdateCount: Integer;
FInactiveBorderColor: TColor;
FInactiveColor: TColor;
FInactiveTextColor: TColor;
FItemsToggled: Integer;
FMouseButton: TCommonMouseButtons;
FMultiChangeCount: Integer;
FMultiSelect: Boolean;
FPopupMode: Boolean;
FRectSelect: Boolean; // A Click-Shift Select will use the Rectangle of the click and the Anchor Item vs. Selecting all from the Anchor Item Index to the selected Item index
FResizeGroupOnFocus: Boolean; // If true and a focused caption will overlap next group, the group is resized to fit focused caption
FRoundRect: Boolean;
FRoundRectRadius: Byte;
FTextColor: TColor;
FUseFocusRect: Boolean;
function GetAutoScroll: Boolean;
function GetAutoScrollAccelerator: Byte;
function GetAutoScrollDelay: Integer;
function GetAutoScrollMargin: Integer;
function GetAutoScrollTime: Integer;
function GetEnableDragSelect: Boolean;
function GeTCommonMouseButton: TCommonMouseButtons;
function GetFocusedColumn: TEasyColumn;
function GetMouseButtonSelRect: TCommonMouseButtons;
function GetSelecting: Boolean;
procedure SetAutoScroll(Value: Boolean);
procedure SetAutoScrollAccelerator(Value: Byte);
procedure SetAutoScrollDelay(Value: Integer);
procedure SetAutoScrollMargin(Value: Integer);
procedure SetAutoScrollTime(Value: Integer);
procedure SetBlendIcon(Value: Boolean);
procedure SetBlurAlphaBkGnd(const Value: Boolean);
procedure SetEnableDragSelect(Value: Boolean);
procedure SetFocusedColumn(Value: TEasyColumn);
procedure SetFocusedItem(Value: TEasyItem);
procedure SetFocusedGroup(const Value: TEasyGroup);
procedure SetEnabled(const Value: Boolean);
procedure SeTCommonMouseButton(Value: TCommonMouseButtons);
procedure SetFullCellPaint(Value: Boolean);
procedure SetFullItemPaint(Value: Boolean);
procedure SetGradient(const Value: Boolean);
procedure SetGradientColorBottom(const Value: TColor);
procedure SetGradientColorTop(const Value: TColor);
procedure SetGroupSelections(Value: Boolean);
procedure SetMouseButtonSelRect(Value: TCommonMouseButtons);
procedure SetMultiSelect(const Value: Boolean);
procedure SetAnchorItem(Value: TEasyItem);
protected
procedure ActOnAll(SelectType: TEasySelectionType; ExceptItem: TEasyItem);
procedure BuildSelectionGroupings(Force: Boolean); virtual;
procedure DragSelect(KeyStates: TCommonKeyStates);
procedure GainingSelection(Item: TEasyItem);
procedure LosingSelection(Item: TEasyItem);
procedure NotifyOwnerListview;
property ItemsToggled: Integer read FItemsToggled write FItemsToggled;
property MultiChangeCount: Integer read FMultiChangeCount write FMultiChangeCount;
public
constructor Create(AnOwner: TCustomEasyListview); override;
destructor Destroy; override;
function SelectedToArray: TEasyItemArray;
procedure ClearAll;
procedure ClearAllExcept(Item: TEasyItem);
function First: TEasyItem;
function FirstInGroup(Group: TEasyGroup): TEasyItem;
procedure FocusFirst;
procedure DecMultiChangeCount;
procedure DeleteSelected(SelectPrevItem: Boolean = False);
procedure GroupSelectBeginUpdate;
procedure GroupSelectEndUpdate;
procedure IncMultiChangeCount;
procedure InvalidateVisibleSelected(ValidateWindow: Boolean);
procedure Invert;
function Next(Item: TEasyItem): TEasyItem;
function NextInGroup(Group: TEasyGroup; Item: TEasyItem): TEasyItem;
procedure SelectAll;
procedure SelectFirst;
procedure SelectGroupItems(Group: TEasyGroup; ClearOtherItems: Boolean);
procedure SelectRange(FromItem, ToItem: TEasyItem; RectSelect: Boolean; ClearFirst: Boolean);
procedure SelectRect(ViewportSelRect: TRect; ClearFirst: Boolean);
property AnchorItem: TEasyItem read FAnchorItem write SetAnchorItem;
property Count: Integer read FCount;
property FocusedColumn: TEasyColumn read GetFocusedColumn write SetFocusedColumn;
property FocusedItem: TEasyItem read FFocusedItem write SetFocusedItem;
property FocusedGroup: TEasyGroup read FFocusedGroup write SetFocusedGroup;
property Selecting: Boolean read GetSelecting;
published
property AlphaBlend: Boolean read FAlphaBlend write FAlphaBlend default False;
property AlphaBlendSelRect: Boolean read FAlphaBlendSelRect write FAlphaBlendSelRect default False;
property AutoScroll: Boolean read GetAutoScroll write SetAutoScroll default True;
property AutoScrollAccelerator: Byte read GetAutoScrollAccelerator write SetAutoScrollAccelerator default 2;
property AutoScrollDelay: Integer read GetAutoScrollDelay write SetAutoScrollDelay default _AUTOSCROLLDELAY;
property AutoScrollMargin: Integer read GetAutoScrollMargin write SetAutoScrollMargin default 15;
property AutoScrollTime: Integer read GetAutoScrollTime write SetAutoScrollTime default _AUTOSCROLLTIME;
property BlendAlphaImage: Byte read FBlendAlphaImage write FBlendAlphaImage default 128;
property BlendAlphaSelRect: Byte read FBlendAlphaSelRect write FBlendAlphaSelRect default 70;
property BlendAlphaTextRect: Byte read FBlendAlphaTextRect write FBlendAlphaTextRect default 128;
property BlendColorSelRect: TColor read FBlendColorSelRect write FBlendColorSelRect default clHighlight;
property BlendIcon: Boolean read FBlendIcon write SetBlendIcon default True;
property BlurAlphaBkGnd: Boolean read FBlurAlphaBkGnd write SetBlurAlphaBkGnd default False;
property BorderColor: TColor read FBorderColor write FBorderColor default clHighlight;
property BorderColorSelRect: TColor read FBorderColorSelRect write FBorderColorSelRect default clHighlight;
property Color: TColor read FColor write FColor default clHighlight;
property Enabled: Boolean read FEnabled write SetEnabled default True;
property EnableDragSelect: Boolean read GetEnableDragSelect write SetEnableDragSelect default False;
property ForceDefaultBlend: Boolean read FForceDefaultBlend write FForceDefaultBlend default False;
property FullCellPaint: Boolean read FFullCellPaint write SetFullCellPaint default False;
property FullItemPaint: Boolean read FFullItemPaint write SetFullItemPaint default False;
property FullRowSelect: Boolean read FFullRowSelect write FFullRowSelect default False;
property Gradient: Boolean read FGradient write SetGradient default False;
property GradientColorBottom: TColor read FGradientColorBottom write SetGradientColorBottom default $FCEFD5;
property GradientColorTop: TColor read FGradientColorTop write SetGradientColorTop default $FDF8F1;
property GroupSelections: Boolean read FGroupSelections write SetGroupSelections default False;
property InactiveBorderColor: TColor read FInactiveBorderColor write FInactiveBorderColor default clInactiveBorder;
property InactiveColor: TColor read FInactiveColor write FInactiveColor default clInactiveBorder;
property InactiveTextColor: TColor read FInactiveTextColor write FInactiveTextColor default clBlack;
property MouseButton: TCommonMouseButtons read GeTCommonMouseButton write SeTCommonMouseButton default [cmbLeft];
property MouseButtonSelRect: TCommonMouseButtons read GetMouseButtonSelRect write SetMouseButtonSelRect default [cmbLeft, cmbRight];
property MultiSelect: Boolean read FMultiSelect write SetMultiSelect default False;
property PopupMode: Boolean read FPopupMode write FPopupMode default False;
property RectSelect: Boolean read FRectSelect write FRectSelect default False;
property ResizeGroupOnFocus: Boolean read FResizeGroupOnFocus write FResizeGroupOnFocus default False;
property RoundRect: Boolean read FRoundRect write FRoundRect default False;
property RoundRectRadius: Byte read FRoundRectRadius write FRoundRectRadius default 4;
property TextColor: TColor read FTextColor write FTextColor default clHighlightText;
property UseFocusRect: Boolean read FUseFocusRect write FUseFocusRect default True;
end;
// **************************************************************************
// TEasyCheckManager
// Manages the check state of the items. The item carries the check state
// of itself but this manager allows manipulation of multiple items
// **************************************************************************
TEasyCheckManager = class(TEasyOwnedPersistent)
private
FCount: Integer; // Number of items with checks set
FPendingObject: TEasyCollectionItem; // When the mouse button is pressed over an item PendingCheckItem is set to that item
procedure SetPendingObject(Value: TEasyCollectionItem);
protected
property PendingObject: TEasyCollectionItem read FPendingObject write SetPendingObject;
public
function CheckedToArray: TEasyItemArray;
procedure CheckAll;
procedure CheckAllInGroup(Group: TEasyGroup);
function First: TEasyItem;
function FirstInGroup(Group: TEasyGroup): TEasyCollectionItem;
function Next(Item: TEasyItem): TEasyItem;
function NextInGroup(Item: TEasyItem): TEasyItem;
procedure DeleteChecked;
procedure UnCheckAll;
procedure UnCheckAllInGroup(Group: TEasyGroup);
property Count: Integer read FCount;
end;
TEasyHotTrackManager = class(TEasyOwnedPersistent)
private
FColor: TColor;
FColumnTrack: TEasyHotTrackRectColumns;
FEnabled: Boolean;
FCursor: TCursor;
FGroupTrack: TEasyHotTrackRectGroups;
FItemTrack: TEasyHotTrackRectItems;
FOnlyFocused: Boolean;
FPendingObject: TEasyCollectionItem;
FPendingObjectCheck: TEasyCollectionItem;
FUnderline: Boolean;
function GetPendingObject(MousePos: TPoint): TEasyCollectionItem;
procedure SetPendingObject(MousePos: TPoint; Value: TEasyCollectionItem);
procedure SetPendingObjectCheck(const Value: TEasyCollectionItem);
protected
property PendingObject[MousePos: TPoint]: TEasyCollectionItem read GetPendingObject write SetPendingObject;
property PendingObjectCheck: TEasyCollectionItem read FPendingObjectCheck write SetPendingObjectCheck;
public
constructor Create(AnOwner: TCustomEasyListview); override;
published
property Color: TColor read FColor write FColor default clHighlight;
// property ColumnTrack: TEasyHotTrackRectColumns read FColumnTrack write FColumnTrack default [htcImage, htcText];
property Enabled: Boolean read FEnabled write FEnabled default False;
property Cursor: TCursor read FCursor write FCursor default crHandPoint;
property GroupTrack: TEasyHotTrackRectGroups read FGroupTrack write FGroupTrack default [htgIcon, htgText];
property ItemTrack: TEasyHotTrackRectItems read FItemTrack write FItemTrack default [htiIcon, htiText];
property OnlyFocused: Boolean read FOnlyFocused write FOnlyFocused default False;
property Underline: Boolean read FUnderline write FUnderline default True;
end;
// **************************************************************************
// TEasyScrollbarManager
// ScrollManager is associated with a TWinContol to handle the
// controls scrollbars
// **************************************************************************
TEasyScrollbarManager = class(TEasyOwnedPersistent)
private
FHorzEnabled: Boolean;
FOffsetX: Integer;
FOffsetY: Integer;
FRebuilding: Boolean;
FSnapHorzView: Boolean; // Causes scroll to snap to column width
FVertEnabled: Boolean;
FViewRect: TRect;
function GetHorzBarVisible: Boolean;
function GetLine: Integer;
function GetMaxOffsetX: Integer;
function GetMaxOffsetY: Integer;
function GetVertBarVisible: Boolean;
function GetViewHeight: Integer;
function GetViewWidth: Integer;
procedure SetHorzEnabled(const Value: Boolean);
procedure SetOffsetX(const Value: Integer);
procedure SetOffsetY(const Value: Integer);
procedure SetVertEnabled(const Value: Boolean);
protected
public
constructor Create(AnOwner: TCustomEasyListview); override;
destructor Destroy; override;
function MapWindowToView(WindowPoint: TPoint; AccountForHeader: Boolean = True): TPoint; overload;
function MapWindowToView(WindowPoint: TSmallPoint; AccountForHeader: Boolean = True): TPoint; overload;
function MapWindowRectToViewRect(WindowRect: TRect; AccountForHeader: Boolean = True): TRect;
function MapViewToWindow(ViewportPoint: TPoint; AccountForHeader: Boolean = True): TPoint; overload;
function MapViewToWindow(ViewportPoint: TSmallPoint; AccountForHeader: Boolean = True): TPoint; overload;
function MapViewRectToWindowRect(ViewPortRect: TRect; AccountForHeader: Boolean = True): TRect;
procedure ReCalculateScrollbars(Redraw: Boolean; Force: Boolean);
procedure Scroll(DeltaX, DeltaY: Integer);
procedure SetViewRect(AViewRect: TRect; InvalidateWindow: Boolean);
procedure ValidateOffsets(var AnOffsetX, AnOffsetY: Integer);
function ViewableViewportRect: TRect;
procedure WMHScroll(var Msg: TWMVScroll);
procedure WMKeyDown(var Msg: TWMKeyDown);
procedure WMVScroll(var Msg: TWMVScroll);
property HorzBarVisible: Boolean read GetHorzBarVisible;
property Line: Integer read GetLine;
property MaxOffsetX: Integer read GetMaxOffsetX;
property MaxOffsetY: Integer read GetMaxOffsetY;
property OffsetX: Integer read FOffsetX write SetOffsetX;
property OffsetY: Integer read FOffsetY write SetOffsetY;
property Rebuilding: Boolean read FRebuilding;
property VertBarVisible: Boolean read GetVertBarVisible;
property ViewHeight: Integer read GetViewHeight;
property ViewRect: TRect read FViewRect;
property ViewWidth: Integer read GetViewWidth;
published
property HorzEnabled: Boolean read FHorzEnabled write SetHorzEnabled default True;
property SnapHorzView: Boolean read FSnapHorzView write FSnapHorzView default True;
property VertEnabled: Boolean read FVertEnabled write SetVertEnabled default True;
end;
// **************************************************************************
// TEasyBackgroundManager
// Easy Background handles the drawing of a background in Easy
// controls. It is a stand alone component that can be shared
// **************************************************************************
TEasyBackgroundManager = class(TEasyOwnedPersistent)
private
FAlphaBlend: Boolean;
FAlphaBlender: TEasyAlphaBlender;
FBlendAlpha: Integer;
FBlendMode: TCommonBlendMode;
FCaption: WideString;
FCaptionAlignment: TAlignment;
FCaptionShow: Boolean;
FCaptionShowOnlyWhenEmpty: Boolean;
FCaptionSingleLine: Boolean;
FCaptionVAlignment: TCommonVAlignment;
FEnabled: Boolean;
FImage: TBitmap;
FOffsetTrack: Boolean;
FOffsetX: Integer;
FOffsetY: Integer;
FTile: Boolean;
FTransparent: Boolean;
FAlphaImage: TBitmap;
procedure SetAlphaBlend(const Value: Boolean);
procedure SetAlphaImage(const Value: TBitmap);
procedure SetBlendAlpha(const Value: Integer);
procedure SetCaption(const Value: WideString);
procedure SetCaptionAlignment(const Value: TAlignment);
procedure SetCaptionShow(const Value: Boolean);
procedure SetCaptionShowOnlyWhenEmpty(const Value: Boolean);
procedure SetCaptionSingleLine(const Value: Boolean);
procedure SetCaptionVAlignment(const Value: TCommonVAlignment);
procedure SetCommonBlendMode(const Value: TCommonBlendMode);
procedure SetEnabled(const Value: Boolean);
procedure SetImage(const Value: TBitmap);
procedure SetOffsetX(const Value: Integer);
procedure SetOffsetY(const Value: Integer);
procedure SetTile(const Value: Boolean);
procedure SetTransparent(const Value: Boolean);
protected
procedure ChangeBitmapBits(Sender: TObject);
property AlphaBlender: TEasyAlphaBlender read FAlphaBlender write FAlphaBlender;
public
constructor Create(AnOwner: TCustomEasyListview); override;
destructor Destroy; override;
procedure Assign(Source: TPersistent); override;
procedure AssignTo(Target: TPersistent); override;
procedure PaintTo(ACanvas: TCanvas; ARect: TRect; PaintDefault: Boolean); virtual;
procedure WMWindowPosChanging(var Msg: TWMWindowPosChanging); virtual;
published
property AlphaBlend: Boolean read FAlphaBlend write SetAlphaBlend default False;
property AlphaImage: TBitmap read FAlphaImage write SetAlphaImage;
property BlendAlpha: Integer read FBlendAlpha write SetBlendAlpha default 128;
property BlendMode: TCommonBlendMode read FBlendMode write SetCommonBlendMode default cbmConstantAlphaAndColor;
property Caption: WideString read FCaption write SetCaption;
property CaptionAlignment: TAlignment read FCaptionAlignment write SetCaptionAlignment default taCenter;
property CaptionShow: Boolean read FCaptionShow write SetCaptionShow default False;
property CaptionShowOnlyWhenEmpty: Boolean read FCaptionShowOnlyWhenEmpty write SetCaptionShowOnlyWhenEmpty default True;
property CaptionSingleLine: Boolean read FCaptionSingleLine write SetCaptionSingleLine default True;
property CaptionVAlignment: TCommonVAlignment read FCaptionVAlignment write SetCaptionVAlignment default cvaCenter;
property Enabled: Boolean read FEnabled write SetEnabled default False;
property Image: TBitmap read FImage write SetImage;
property OffsetTrack: Boolean read FOffsetTrack write FOffsetTrack default False;
property OffsetX: Integer read FOffsetX write SetOffsetX default 0;
property OffsetY: Integer read FOffsetY write SetOffsetY default 0;
property Tile: Boolean read FTile write SetTile default True;
property Transparent: Boolean read FTransparent write SetTransparent default False;
end;
// **************************************************************************
// TEasyTaskBandBackgroundManager
// Easy Background handles the drawing of a background in Easy
// controls. It is a stand alone component that can be shared
// **************************************************************************
TEasyTaskBandBackgroundManager = class(TEasyBackgroundManager)
public
procedure PaintTo(ACanvas: TCanvas; ARect: TRect; PaintDefault: Boolean); override;
end;
// **************************************************************************
// TEasyDropTargetManager
// Implements the IDropTarget inteface to allow for the control to become
// a drag/drop target and accept drops.
// **************************************************************************
TEasyDropTargetManager = class(TEasyOwnedInterfacedPersistent, IDropTarget)
private
FDragManager: TCustomEasyDragManagerBase;
FDropTargetHelper: IDropTargetHelper; // Win2k and up drag image support built in to Windows
function GetDropTargetHelper: IDropTargetHelper;
protected
function DragEnter(const dataObj: IDataObject; grfKeyState: Longint; pt: TPoint; var dwEffect: Longint): HResult; stdcall;
function DragOver(grfKeyState: Longint; pt: TPoint; var dwEffect: Longint): HResult; stdcall;
function DragLeave: HResult; stdcall;
function Drop(const dataObj: IDataObject; grfKeyState: Longint; pt: TPoint; var dwEffect: Longint): HResult; stdcall;
property DragManager: TCustomEasyDragManagerBase read FDragManager write FDragManager;
property DropTargetHelper: IDropTargetHelper read GetDropTargetHelper;
public
end;
// **************************************************************************
// TEasyDropSourceManager
// Implements the IDropSource inteface to allow for the control to become
// a drag/drop source.
// **************************************************************************
TEasyDropSourceManager = class(TEasyOwnedInterfacedPersistent, IDropSource)
protected
function QueryContinueDrag(fEscapePressed: BOOL; grfKeyState: Longint): HResult; stdcall;
function GiveFeedback(dwEffect: Longint): HResult; stdcall;
end;
// **************************************************************************
// Drag TEasyDragRectManager Manager
// Easy DragRect Manager is associated with a TWinContol to handle the
// controls drag selection rectangle
// **************************************************************************
TEasyDragRectManager = class(TCustomEasyDragManagerBase)
private
FAnchorPoint: TPoint; // Anchor point in Viewport coordinates
FDragPoint: TPoint; // Dragging point in Viewport coordinates
FOldOffsets: TPoint;
FPrevRect: TRect;
function GetSelectionRect: TRect;
procedure PaintRect(Canvas: TCanvas);
procedure SetAnchorPoint(ViewportAnchor: TPoint);
procedure SetDragPoint(const Value: TPoint);
protected
procedure DoAfterAutoScroll; override;
procedure DoAutoScroll(DeltaX, DeltaY: Integer); override;
procedure DoBeforeAutoScroll; override;
procedure DoDrag(Canvas: TCanvas; WindowPoint: TPoint; KeyState: TCommonKeyStates; var Effects: TCommonDropEffect); override;
procedure DoDragBegin(WindowPoint: TPoint; KeyState: TCommonKeyStates); override;
procedure DoDragEnd(Canvas: TCanvas; WindowPoint: TPoint; KeyState: TCommonKeyStates); override;
procedure DoDragEnter(const DataObject: IDataObject; Canvas: TCanvas; WindowPoint: TPoint; KeyState: TCommonKeyStates; var Effects: TCommonDropEffect); override;
function DoPtInAutoScrollDownRegion(WindowPoint: TPoint): Boolean; override;
function DoPtInAutoScrollLeftRegion(WindowPoint: TPoint): Boolean; override;
function DoPtInAutoScrollRightRegion(WindowPoint: TPoint): Boolean; override;
function DoPtInAutoScrollUpRegion(WindowPoint: TPoint): Boolean; override;
procedure UpdateAfterAutoScroll; override;
property OldOffsets: TPoint read FOldOffsets write FOldOffsets;
public
constructor Create(AnOwner: TCustomEasyListview); override;
destructor Destroy; override;
procedure FinalizeDrag(KeyState: TCommonKeyStates);
function InitializeDrag(WindowPoint: TPoint; KeyState: TCommonKeyStates): Boolean;
procedure PaintSelectionRect(Canvas: TCanvas);
function SelRectInWindowCoords: TRect;
procedure WMKeyDown(var Msg: TWMKeyDown); override;
property AnchorPoint: TPoint read FAnchorPoint write SetAnchorPoint;
property DragPoint: TPoint read FDragPoint write SetDragPoint;
property PrevRect: TRect read FPrevRect;
property SelectionRect: TRect read GetSelectionRect;
end;
// > 0 (positive) Item1 is less than Item2
// 0 Item1 is equal to Item2
// < 0 (negative) Item1 is greater than Item2
TEasySortProc = function(Column: TEasyColumn; Item1, Item2: TEasyCollectionItem): Integer;
TEasySorter = class
private
FOwner: TEasySortManager;
public
constructor Create(AnOwner: TEasySortManager); virtual;
procedure Sort(Column: TEasyColumn; Collection: TEasyCollection; Min, Max: Integer; GroupCompare: TEasyDoGroupCompare; ItemCompare: TEasyDoItemCompare; UseInterfaces: Boolean); virtual; abstract;
property Owner: TEasySortManager read FOwner write FOwner;
end;
TEasyQuickSort = class(TEasySorter)
public
procedure Sort(Column: TEasyColumn; Collection: TEasyCollection; Min, Max: Integer; GroupCompare: TEasyDoGroupCompare; ItemCompare: TEasyDoItemCompare; UseInterfaces: Boolean); override;
end;
TEasyBubbleSort = class(TEasySorter)
public
procedure Sort(Column: TEasyColumn; Collection: TEasyCollection; Min, Max: Integer; GroupCompare: TEasyDoGroupCompare; ItemCompare: TEasyDoItemCompare; UseInterfaces: Boolean); override;
end;
TEasyMergeSort = class(TEasySorter)
private
FColumn: TEasyColumn;
FGroupCompareFunc: TEasyDoGroupCompare;
FItemCompareFunc: TEasyDoItemCompare;
FOwnerGroup: TEasyGroup;
protected
function CompareInterfaces(i1, i2: TEasyCollectionItem): Boolean;
function CompareGroup(i1, i2: TEasyCollectionItem): Boolean;
function CompareItem(i1, i2: TEasyCollectionItem): Boolean;
function CompareDefault(i1, i2: TEasyCollectionItem): Boolean;
property Column: TEasyColumn read FColumn write FColumn;
property GroupCompareFunc: TEasyDoGroupCompare read FGroupCompareFunc write FGroupCompareFunc;
property ItemCompareFunc: TEasyDoItemCompare read FItemCompareFunc write FItemCompareFunc;
property OwnerGroup: TEasyGroup read FOwnerGroup write FOwnerGroup;
public
procedure Sort(Column: TEasyColumn; Collection: TEasyCollection; Min, Max: Integer; GroupCompare: TEasyDoGroupCompare; ItemCompare: TEasyDoItemCompare; UseInterfaces: Boolean); override;
end;
TGroupSortInfoRec = record
Item: TEasyItem;
Key: LongWord;
end;
TGroupSortInfoArray = array of TGroupSortInfoRec;
// **************************************************************************
// TEasySortManager
// Manages the sorting of the Listview. Because of the way EasyListview
// works it is not feasable to try to add an AutoSort property. EasyListview
// can access a caption by a callback, storing it in the control, or through
// an interface. Due to the wildly varying ways of storing the caption it was
// decided to not try to find all the possible places it would be necessary to
// AutoSort. There are some scenarios, such as the interface access, where it
// is not possible to detect when an autosort should be carried out.
// **************************************************************************
TEasySortManager = class(TEasyOwnedPersistent)
private
FAlgorithm: TEasySortAlgorithm; // The algorithm used when sorting
FAutoRegroup: Boolean;
FAutoSort: Boolean; // Items and groups are resorted when any object is added/inserted
FLockoutSort: Boolean;
FSortList: TGroupSortInfoArray;
FSorter: TEasySorter; // The algorithm engine for the sort
FUpdateCount: Integer;
procedure SetAlgorithm(Value: TEasySortAlgorithm);
procedure SetAutoRegroup(Value: Boolean);
procedure SetAutoSort(Value: Boolean);
protected
function CollectionSupportsInterfaceSorting(Collection: TEasyCollection): Boolean;
procedure GroupItem(Item: TEasyItem; ColumnIndex: Integer; Key: LongWord);
property Sorter: TEasySorter read FSorter write FSorter;
property SortList: TGroupSortInfoArray read FSortList write FSortList;
property UpdateCount: Integer read FUpdateCount write FUpdateCount;
public
constructor Create(AnOwner: TCustomEasyListview); override;
destructor Destroy; override;
procedure BeginUpdate;
procedure EndUpdate;
procedure ReGroup(Column: TEasyColumn); virtual;
procedure SortAll(Force: Boolean = False);
property LockoutSort: Boolean read FLockoutSort write FLockoutSort;
published
property Algorithm: TEasySortAlgorithm read FAlgorithm write SetAlgorithm default esaMergeSort;
property AutoRegroup: Boolean read FAutoRegroup write SetAutoRegroup default False;
property AutoSort: Boolean read FAutoSort write SetAutoSort default False;
end;
// **************************************************************************
// TEasyHintInfo
// Custom hint information for the Unicode Hint Window
// **************************************************************************
TEasyHintInfo = class(TEasyOwnedPersistent)
private
FBounds: TRect;
FCanvas: TCanvas;
FColor: TColor;
FCursorPos: TPoint;
FHideTimeout: Integer;
FHintType: TEasyHintType;
FMaxWidth: Integer;
FReshowTimeout: Integer;
FText: WideString;
FWindowPos: TPoint;
public
property Canvas: TCanvas read FCanvas write FCanvas;
property Color: TColor read FColor write FColor;
property CursorPos: TPoint read FCursorPos write FCursorPos;
property Bounds: TRect read FBounds write FBounds;
property HideTimeout: Integer read FHideTimeout write FHideTimeout;
property HintType: TEasyHintType read FHintType write FHintType;
property MaxWidth: Integer read FMaxWidth write FMaxWidth;
property ReshowTimeout: Integer read FReshowTimeout write FReshowTimeout;
property Text: WideString read FText write FText;
property WindowPos: TPoint read FWindowPos write FWindowPos;
end;
// **************************************************************************
// TEasyHintWindow
// Custom hint window that supports Unicode and Custom Draw
// **************************************************************************
TEasyHintWindow = class(THintWindow)
protected
FEasyHintInfo: TEasyHintInfo;
FHintInfo: PEasyHintInfoRec;
procedure Paint; override;
property EasyHintInfo: TEasyHintInfo read FEasyHintInfo write FEasyHintInfo;
property HintInfo: PEasyHintInfoRec read FHintInfo write FHintInfo;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure ActivateHint(ARect: TRect; const AHint: string); override;
procedure ActivateHintData(ARect: TRect; const AHint: string; AData: Pointer); override;
function CalcHintRect(MaxWidth: Integer; const AHint: string; AData: Pointer): TRect; override;
function IsHintMsg(var Msg: TMsg): Boolean; override;
end;
TEasyHintWindowClass = class of TEasyHintWindow;
// **************************************************************************
// TEasyIncrementalSearchManager
// Implements the incremental search of the listview
// **************************************************************************
TEasyIncrementalSearchManager = class(TEasyOwnedPersistent)
private
FDirection: TEasyIncrementalSearchDir;
FEnabled: Boolean;
FhTimer: THandle;
FItemType: TEasyIncrementalSearchItemType;
FNextSearchItem: TEasyItem;
FResetTime: Integer;
FSearchBuffer: WideString;
FSearchItem: TEasyItem;
FStart: TCoolIncrementalSearchStart;
FState: TEasyIncrementalSearchStates;
FTimerStub: Pointer;
procedure SetSearchItem(Value: TEasyItem);
protected
procedure EndTimer;
function IsSearching: Boolean;
procedure HandleWMChar(var Msg: TWMChar); virtual;
procedure HandleWMKeyDown(var Msg: TWMKeyDown); virtual;
procedure LoadFutureItem;
procedure ResetTimer;
procedure SearchPreloadItem(Next, Prev: TItemNextEnum; First, Last: TItemEnumFirstLast; var SearchItem: TEasyItem);
procedure StartSearch;
procedure StartTimer;
procedure TimerProc(Window: HWnd; uMsg: UINT; idEvent: UINT; dwTime: DWORD); stdcall;
property hTimer: THandle read FhTimer write FhTimer;
property NextSearchItem: TEasyItem read FNextSearchItem write FNextSearchItem;
property SearchBuffer: WideString read FSearchBuffer write FSearchBuffer;
property SearchItem: TEasyItem read FSearchItem write SetSearchItem;
property TimerStub: Pointer read FTimerStub write FTimerStub;
public
constructor Create(AnOwner: TCustomEasyListview); override;
destructor Destroy; override;
procedure ClearSearch; virtual;
procedure ResetSearch;
property State: TEasyIncrementalSearchStates read FState write FState;
published
property Direction: TEasyIncrementalSearchDir read FDirection write FDirection default eisdForward;
property Enabled: Boolean read FEnabled write FEnabled default False;
property ResetTime: Integer read FResetTime write FResetTime default 2000;
property StartType: TCoolIncrementalSearchStart read FStart write FStart default eissStartOver;
property ItemType: TEasyIncrementalSearchItemType read FItemType write FItemType default eisiVisible;
end;
// **************************************************************************
// TEasyGestureManager
// Implements the Gesture feature of the listview
// **************************************************************************
TEasyGestureManager = class(TEasyOwnedPersistent)
private
FButton: TCommonMouseButtons;
FEnabled: Boolean;
FPath: WideString;
FTolerance: Integer;
protected
property Path: WideString read FPath write FPath;
public
constructor Create(AnOwner: TCustomEasyListview); override;
published
property Button: TCommonMouseButtons read FButton write FButton default [cmbRight];
property Enabled: Boolean read FEnabled write FEnabled default False;
property Tolerance: Integer read FTolerance write FTolerance default 3;
end;
// Down here due to a bug in C++ BDS2006 hpp generated files
TEasyHintInfoRec = record
HintControl: TControl;
HintWindowClass: THintWindowClass;
HintPos: TPoint;
HintMaxWidth: Integer;
HintColor: TColor;
HintType: TEasyHintType;
CursorRect: TRect;
CursorPos: TPoint;
ReshowTimeout: Integer;
HideTimeout: Integer;
HintStr: WideString;
HintData: Pointer;
Listview: TCustomEasyListview;
TargetObj: TEasyCollectionItem; // What the hint is being popped up over (EasyItem, EasyGroup, EasyColumn etc.)
ToolTipRect: TRect; // The size of the rect needed for a tool tip hint
end;
// **************************************************************************
// TCustomEasyListview
// **************************************************************************
TCustomEasyListview = class(TCommonCanvasControl)
private
FAllowInvisibleCheckedItems: Boolean;
FBackBits: TBitmap;
FBackGround: TEasyBackgroundManager;
FCacheDoubleBufferBits: Boolean;
FCellSizes: TEasyCellSizes;
FCheckManager: TEasyCheckManager;
FDisabledBlendAlpha: Byte;
FDisabledBlendColor: TColor;
FDragManager: TEasyOLEDragManager;
FDragRect: TEasyDragRectManager;
FDropTarget: IDropTarget;
FEditManager: TEasyEditManager;
FForcePaint: Boolean;
FGesture: TEasyGestureManager;
FGlobalImages: TEasyGlobalImageManager;
FGroupCollapseButton: TBitmap;
FGroupExpandButton: TBitmap;
FGroupFont: TFont;
FGroupImageGetSize: TGroupImageGetSizeEvent;
FGroups: TEasyGroups;
FHeader: TEasyHeader;
FHintAlignment: TAlignment;
FHintData: TEasyHintInfoRec;
FHintInfo: TEasyHintInfo;
FHotTrack: TEasyHotTrackManager;
FImagesExLarge: TCustomImageList;
FImagesGroup: TCustomImageList;
FImagesLarge: TCustomImageList;
FImagesSmall: TCustomImageList;
FImagesState: TCustomImageList;
FIncrementalSearch: TEasyIncrementalSearchManager;
FItems: TEasyGlobalItems;
FLastMousePos: TSmallPoint;
FNCCanvas: TCanvas;
FOnAfterPaint: TAfterPaintEvent;
FOnAutoGroupGetKey: TAutoGroupGetKeyEvent;
FOnAutoSortGroupCreate: TAutoSortGroupCreateEvent;
FOnClipboardCopy: TEasyClipboardEvent;
FOnClipboardCut: TEasyClipboardCutEvent;
FOnClipboardPaste: TEasyClipboardEvent;
FOnColumnCheckChange: TColumnCheckChangeEvent;
FOnColumnCheckChanging: TColumnCheckChangingEvent;
FOnColumnClick: TColumnClickEvent;
FOnColumnContextMenu: TColumnContextMenuEvent;
FOnColumnDblClick: TColumnDblClickEvent;
FOnColumnDropDownButtonClick: TColumnDropDownButtonClickEvent;
FOnColumnImageDrawIsCustom: TColumnImageDrawIsCustomEvent;
FOnColumnEnableChange: TColumnEnableChangeEvent;
FOnColumnEnableChanging: TColumnEnableChangingEvent;
FOnColumnFocusChanged: TColumnFocusChangeEvent;
FOnColumnFocusChanging: TColumnFocusChangingEvent;
FOnColumnFreeing: TColumnFreeingEvent;
FOnColumnGetCaption: TColumnGetCaptionEvent;
FOnColumnGetDetail: TColumnGetDetailEvent;
FOnColumnGetDetailCount: TColumnGetDetailCountEvent;
FOnColumnGetImageIndex: TColumnGetImageIndexEvent;
FOnColumnGetImageList: TColumnGetImageListEvent;
FOnColumnImageDraw: TColumnImageDrawEvent;
FOnColumnImageGetSize: TColumnImageGetSizeEvent;
FOnColumnInitialize: TColumnInitializeEvent;
FOnColumnLoadFromStream: TEasyColumnLoadFromStreamEvent;
FOnColumnPaintText: TColumnPaintTextEvent;
FOnColumnSaveToStream: TEasyColumnSaveToStreamEvent;
FOnColumnSelectionChanged: TColumnSelectionChangeEvent;
FOnColumnSelectionChanging: TColumnSelectionChangingEvent;
FOnColumnSetCaption: TColumnSetCaptionEvent;
FOnColumnSetDetail: TColumnSetDetailEvent;
FOnColumnSetImageIndex: TColumnSetImageIndexEvent;
FOnColumnSizeChanged: TColumnSizeChangedEvent;
FOnColumnSizeChanging: TColumnSizeChangingEvent;
FOnColumnStructureChange: TNotifyEvent;
FOnColumnThumbnailDraw: TColumnThumbnailDrawEvent;
FOnColumnVisibilityChanged: TColumnVisibilityChangeEvent;
FOnColumnVisibilityChanging: TColumnVisibilityChangingEvent;
FOnContextMenu: TContextMenuEvent;
FOnColumnCustomView: TColumnCustomViewEvent;
FOnCustomGrid: TCustomGridEvent;
FOnDblClick: TDblClickEvent;
FOnMouseGesture: TEasyGestureEvent;
FOnGetDragImage: TGetDragImageEvent;
FOnGroupClick: TGroupClickEvent;
FOnGroupCollapse: TGroupCollapseEvent;
FOnGroupCollapsing: TGroupCollapsingEvent;
FOnGroupCompare: TGroupCompareEvent;
FOnGroupContextMenu: TGroupContextMenuEvent;
FOnGroupCustomView: TGroupCustomViewEvent;
FOnGroupDblClick: TGroupDblClickEvent;
FOnGroupImageDrawIsCustom: TGroupImageDrawIsCustomEvent;
FOnGroupExpand: TGroupExpandEvent;
FOnGroupExpanding: TGroupExpandingEvent;
FOnGroupFocusChanged: TGroupFocusChangeEvent;
FOnGroupFocusChanging: TGroupFocusChangingEvent;
FOnGroupFreeing: TGroupFreeingEvent;
FOnGroupGetCaption: TGroupGetCaptionEvent;
FOnGroupGetDetailCount: TGroupGetDetailCountEvent;
FOnGroupGetDetailIndex: TGroupGetDetailEvent;
FOnGroupGetImageIndex: TGroupGetImageIndexEvent;
FOnGroupGetImageList: TGroupGetImageListEvent;
FOnGroupImageDrawEvent: TGroupImageDrawEvent;
FOnGroupInitialize: TGroupInitializeEvent;
FOnGroupHotTrack: TGroupHotTrackEvent;
FOnGroupLoadFromStream: TGroupLoadFromStreamEvent;
FOnGroupPaintText: TGroupPaintTextEvent;
FOnGroupSaveToStream: TGroupSaveToStreamEvent;
FOnGroupSelectionChanged: TGroupSelectionChangeEvent;
FOnGroupSelectionChanging: TGroupSelectionChangingEvent;
FOnGroupSetCaption: TGroupSetCaptionEvent;
FOnGroupSetImageIndex: TGroupSetImageIndexEvent;
FOnGroupSetDetail: TGroupSetDetailEvent;
FOnGroupStructureChange: TNotifyEvent;
FOnGroupThumbnailDraw: TGroupThumbnailDrawEvent;
FOnGroupVisibilityChanged: TGroupVisibilityChangeEvent;
FOnGroupVisibilityChanging: TGroupVisibilityChangingEvent;
FOnHeaderDblClick: THeaderDblClickEvent;
FOnHeaderMouseDown: THeaderMouseEvent;
FOnHeaderMouseMove: TMouseMoveEvent;
FOnHeaderMouseUp: THeaderMouseEvent;
FOnHintCustomDraw: THintCustomDrawEvent;
FOnHintCustomInfo: THintCustomizeInfoEvent;
FOnHintPauseTime: THintPauseTimeEvent;
FOnHintPopup: THintPopupEvent;
FOnIncrementalSearch: TIncrementalSearchEvent;
FOnItemCheckChange: TItemCheckChangeEvent;
FOnItemCheckChanging: TItemCheckChangingEvent;
FOnItemClick: TItemClickEvent;
FOnItemCompare: TItemCompareEvent;
FOnItemContextMenu: TItemContextMenuEvent;
FOnItemCreateEditor: TItemCreateEditorEvent;
FOnItemCustomView: TItemCustomViewEvent;
FOnItemDblClick: TItemDblClickEvent;
FOnItemGetEditCaption: TEasyItemGetCaptionEvent;
FOnItemGetEditMenu: TItemGetEditMenuEvent;
FOnItemGetStateImageList: TItemGetImageListEvent;
FOnItemImageDrawIsCustom: TItemImageDrawIsCustomEvent;
FOnItemEditBegin: TItemEditBegin;
FOnItemEdited: TItemEditedEvent;
FOnItemEditEnd: TItemEditEnd;
FOnItemEnableChange: TItemEnableChangeEvent;
FOnItemEnableChanging: TItemEnableChangingEvent;
FOnItemFocusChanged: TItemFocusChangeEvent;
FOnItemFocusChanging: TItemFocusChangingEvent;
FOnItemFreeing: TItemFreeingEvent;
FOnItemGetCaption: TItemGetCaptionEvent;
FOnItemGetGroupKey: TItemGetGroupKeyEvent;
FOnItemHotTrack: TItemHotTrackEvent;
FOnItemGetTileDetailIndex: TItemGetTileDetailEvent;
FOnItemGetImageIndex: TItemGetImageIndexEvent;
FOnItemGetImageList: TItemGetImageListEvent;
FOnItemGetTileDetailCount: TItemGetTileDetailCountEvent;
FOnItemImageDraw: TItemImageDrawEvent;
FOnItemImageGetSize: TItemImageGetSizeEvent;
FOnItemInitialize: TItemInitializeEvent;
FOnItemLoadFromStream: TItemLoadFromStreamEvent;
FOnItemMouseDown: TItemMouseDownEvent;
FOnItemMouseUp: TItemMouseUpEvent;
FOnItemPaintText: TItemPaintTextEvent;
FOnItemSaveToStream: TItemSaveToStreamEvent;
FOnItemSelectionChanged: TItemSelectionChangeEvent;
FOnItemSelectionChanging: TItemSelectionChangingEvent;
FOnItemSelectionsChanged: TEasyItemSelectionsChangedEvent;
FOnItemSetCaption: TItemSetCaptionEvent;
FOnItemSetGroupKey: TItemSetGroupKeyEvent;
FOnItemSetImageIndex: TItemSetImageIndexEvent;
FOnItemSetTileDetail: TItemSetTileDetailEvent;
FOnItemStructureChange: TNotifyEvent;
FOnItemThumbnailDraw: TItemThumbnailDrawEvent;
FOnItemVisibilityChanged: TItemVisibilityChangeEvent;
FOnItemVisibilityChanging: TItemVisibilityChangingEvent;
FOnKeyAction: TEasyKeyActionEvent;
FOnOLEDragDrop: TOLEDropTargetDragDropEvent;
FOnOLEDragEnd: TOLEDropSourceDragEndEvent;
FOnOLEDragEnter: TOLEDropTargetDragEnterEvent;
FOnOLEDragLeave: TOLEDropTargetDragLeaveEvent;
FOnOLEDragOver: TOLEDropTargetDragOverEvent;
FOnOLEDragStart: TOLEDropSourceDragStartEvent;
FOnOLEGetCustomFormats: TOLEGetCustomFormatsEvent;
FOnOLEGetData: TOLEGetDataEvent;
FOnOLEGetDataObject: FOLEGetDataObjectEvent;
FOnOLEGiveFeedback: TOLEDropSourceGiveFeedbackEvent;
FOnOLEQueryContineDrag: TOLEDropSourceQueryContineDragEvent;
FOnOLEQueryData: TOLEQueryDataEvent;
FOnPaintBkGnd: TPaintBkGndEvent;
FOnPaintHeaderBkGnd: TPaintHeaderBkGndEvent;
FOnScroll: TEasyScrollEvent;
FOnViewChange: TViewChangedEvent;
FPaintInfoColumn: TEasyPaintInfoBaseColumn;
FPaintInfoGroup: TEasyPaintInfoBaseGroup;
FPaintInfoItem: TEasyPaintInfoBaseItem;
FPopupMenuHeader: TPopupMenu;
FScratchCanvas: TControlCanvas;
FScrollbars: TEasyScrollbarManager;
FSelection: TEasySelectionManager;
FShowGroupMargins: Boolean;
FShowInactive: Boolean;
FShowThemedBorder: Boolean;
FSort: TEasySortManager;
FStates: TEasyControlStates;
FView: TEasyListStyle;
FWheelMouseDefaultScroll: TEasyDefaultWheelScroll;
FWheelMouseScrollModifierEnabled: Boolean;
function GetGroupCollapseImage: TBitmap;
function GetGroupExpandImage: TBitmap;
function GetHintType: TEasyHintType;
function GetPaintInfoColumn: TEasyPaintInfoBaseColumn; virtual;
function GetPaintInfoGroup: TEasyPaintInfoBaseGroup; virtual;
function GetPaintInfoItem: TEasyPaintInfoBaseItem; virtual;
function GetScratchCanvas: TControlCanvas;
function GetTopItem: TEasyItem;
procedure SetBackGround(const Value: TEasyBackgroundManager);
procedure SetCacheDoubleBufferBits(const Value: Boolean);
procedure SetGroupCollapseImage(Value: TBitmap);
procedure SetGroupExpandImage(Value: TBitmap);
procedure SetGroupFont(Value: TFont);
procedure SetHintType(Value: TEasyHintType);
procedure SetImagesExLarge(Value: TCustomImageList);
procedure SetImagesGroup(Value: TCustomImageList);
procedure SetImagesLarge(Value: TCustomImageList);
procedure SetImagesSmall(Value: TCustomImageList);
procedure SetImagesState(const Value: TCustomImageList);
procedure SetPaintInfoColumn(const Value: TEasyPaintInfoBaseColumn); virtual;
procedure SetPaintInfoGroup(const Value: TEasyPaintInfoBaseGroup); virtual;
procedure SetPaintInfoItem(const Value: TEasyPaintInfoBaseItem); virtual;
procedure SetSelection(Value: TEasySelectionManager);
procedure SetShowInactive(const Value: Boolean);
procedure SetShowThemedBorder(Value: Boolean);
procedure SetShowGroupMargins(const Value: Boolean);
protected
function CreateColumnPaintInfo: TEasyPaintInfoBaseColumn; virtual;
function CreateGroupPaintInfo: TEasyPaintInfoBaseGroup; virtual;
function CreateGroups: TEasyGroups; virtual;
function CreateItemPaintInfo: TEasyPaintInfoBaseItem; virtual;
function ExecuteDragDrop(AvailableEffects: TCommonDropEffects; DataObjectInf: IDataObject; DropSource: IDropSource; var dwEffect: Integer): HRESULT; virtual;
function GetSortColumn: TEasyColumn; virtual;
function GroupTestExpand(HitInfo: TEasyGroupHitTestInfoSet): Boolean; virtual;
function ToolTipNeeded(TargetObj: TEasyCollectionItem; var TipCaption: WideString): Boolean;
function UseInternalDragImage: Boolean; virtual;
function ViewSupportsHeader: Boolean;
procedure CancelCut;
procedure CheckFocus; virtual;
procedure ClearPendingDrags;
procedure ClearStates;
function ClickTestGroup(ViewportPoint: TPoint; KeyStates: TCommonKeyStates; var HitInfo: TEasyGroupHitTestInfoSet): TEasyGroup;
function ClickTestItem(ViewportPoint: TPoint; Group: TEasyGroup; KeyStates: TCommonKeyStates; var HitInfo: TEasyItemHitTestInfoSet): TEasyItem;
procedure ClipHeader(ACanvas: TCanvas; ResetClipRgn: Boolean);
procedure CMDrag(var Msg: TCMDrag); message CM_DRAG;
procedure CMHintShow(var Message: TCMHintShow); message CM_HINTSHOW;
procedure CMHintShowPause(var Message: TCMHintShow); message CM_HINTSHOWPAUSE;
procedure CMMouseWheel(var Msg: TWMMouseWheel); message CM_MOUSEWHEEL;
procedure CMParentFontChanged(var Msg: TMessage); message CM_PARENTFONTCHANGED;
procedure CopyToClipboard; virtual;
procedure CreateParams(var Params: TCreateParams); override;
procedure CreateWnd; override;
procedure CutToClipboard; virtual;
procedure DoAfterPaint(ACanvas: TCanvas; ClipRect: TRect);
procedure DoAutoGroupGetKey(Item: TEasyItem; ColumnIndex: Integer; Groups: TEasyGroups; var Key: LongWord); virtual;
procedure DoAutoSortGroupCreate(Item: TEasyItem; ColumnIndex: Integer; Groups: TEasyGroups; var Group: TEasyGroup; var DoDefaultAction: Boolean); virtual;
procedure DoClipboardCopy(var Handled: Boolean); virtual;
procedure DoClipboardCut(var MarkAsCut, Handled: Boolean); virtual;
procedure DoClipboardPaste(var Handled: Boolean); virtual;
procedure DoColumnCheckChanged(Column: TEasyColumn); virtual;
procedure DoColumnCheckChanging(Column: TEasyColumn; var Allow: Boolean); virtual;
procedure DoColumnClick(Button: TCommonMouseButton; const Column: TEasyColumn); virtual;
procedure DoColumnContextMenu(HitInfo: TEasyHitInfoColumn; WindowPoint: TPoint; var Menu: TPopupMenu); virtual;
procedure DoColumnCustomView(Column: TEasyColumn; var ViewClass: TEasyViewColumnClass); virtual;
procedure DoColumnDblClick(Button: TCommonMouseButton; ShiftState: TShiftState; MousePos: TPoint; Column: TEasyColumn); virtual;
procedure DoColumnDropDownButtonClick(Column: TEasyColumn; Button: TCommonMouseButton; ShiftState: TShiftState; MousePos: TPoint; var DoDefault: Boolean); virtual;
procedure DoColumnEnableChanged(Column: TEasyColumn); virtual;
procedure DoColumnEnableChanging(Column: TEasyColumn; var Allow: Boolean); virtual;
procedure DoColumnFocusChanged(Column: TEasyColumn); virtual;
procedure DoColumnFocusChanging(Column: TEasyColumn; var Allow: Boolean); virtual;
procedure DoColumnFreeing(Column: TEasyColumn); virtual;
procedure DoColumnGetCaption(Column: TEasyColumn; Line: Integer; var Caption: WideString); virtual;
procedure DoColumnGetImageIndex(Column: TEasyColumn; ImageKind: TEasyImageKind; var ImageIndex: TCommonImageIndexInteger); virtual;
procedure DoColumnGetImageList(Column: TEasyColumn; var ImageList: TCustomImageList); virtual;
procedure DoColumnGetDetail(Column: TEasyColumn; Line: Integer; var Detail: Integer); virtual;
procedure DoColumnGetDetailCount(Column: TEasyColumn; var Count: Integer); virtual;
procedure DoColumnImageDraw(Column: TEasyColumn; ACanvas: TCanvas; const RectArray: TEasyRectArrayObject; AlphaBlender: TEasyAlphaBlender); virtual;
procedure DoColumnImageGetSize(Column: TEasyColumn; var ImageWidth, ImageHeight: Integer); virtual;
procedure DoColumnImageDrawIsCustom(Column: TEasyColumn; var IsCustom: Boolean); virtual;
procedure DoColumnInitialize(Column: TEasyColumn); virtual;
procedure DoColumnLoadFromStream(Column: TEasyColumn; S: TStream; Version: Integer); virtual;
procedure DoColumnPaintText(Column: TEasyColumn; ACanvas: TCanvas); virtual;
procedure DoColumnSaveToStream(Column: TEasyColumn; S: TStream; Version: Integer); virtual;
procedure DoColumnSelectionChanged(Column: TEasyColumn); virtual;
procedure DoColumnSelectionChanging(Column: TEasyColumn; var Allow: Boolean); virtual;
procedure DoColumnSetCaption(Column: TEasyColumn; const Caption: WideString); virtual;
procedure DoColumnSetImageIndex(Column: TEasyColumn; ImageKind: TEasyImageKind; ImageIndex: Integer); virtual;
procedure DoColumnSetDetail(Column: TEasyColumn; Line: Integer; Detail: Integer); virtual;
procedure DoColumnSetDetailCount(Column: TEasyColumn; DetailCount: Integer); virtual;
procedure DoColumnStructureChange;
procedure DoColumnThumbnailDraw(Column: TEasyColumn; ACanvas: TCanvas; ARect: TRect; var DoDefault: Boolean); virtual;
procedure DoColumnSizeChanged(Column: TEasyColumn); virtual;
procedure DoColumnSizeChanging(Column: TEasyColumn; Size, NewSize: Integer; var Allow: Boolean); virtual;
procedure DoColumnVisibilityChanged(Column: TEasyColumn); virtual;
procedure DoColumnVisibilityChanging(Column: TEasyColumn; var Allow: Boolean); virtual;
procedure DoContextMenu(MousePt: TPoint; var Handled: Boolean); virtual;
procedure DoCustomGrid(Group: TEasyGroup; ViewStyle: TEasyListStyle; var Grid: TEasyGridGroupClass); virtual;
procedure DoDblClick(Button: TCommonMouseButton; MousePos: TPoint; ShiftState: TShiftState); virtual;
procedure DoGesture(Gesture: WideString; var Handled: Boolean); virtual;
procedure DoGetDragImage(Bitmap: TBitmap; DragStartPt: TPoint; var HotSpot: TPoint; var TransparentColor: TColor; var Handled: Boolean); virtual;
procedure DoGroupClick(Group: TEasyGroup; KeyStates: TCommonKeyStates; HitTest: TEasyGroupHitTestInfoSet); virtual;
procedure DoGroupCollapse(Group: TEasyGroup); virtual;
procedure DoGroupCollapsing(Group: TEasyGroup; var Allow: Boolean); virtual;
function DoGroupCompare(Column: TEasyColumn; Group1, Group2: TEasyGroup): Integer; virtual;
procedure DoGroupContextMenu(HitInfo: TEasyHitInfoGroup; WindowPoint: TPoint; var Menu: TPopupMenu; var Handled: Boolean); virtual;
procedure DoGroupCustomView(Group: TEasyGroup; ViewStyle: TEasyListStyle; var View: TEasyViewGroupClass); virtual;
procedure DoGroupDblClick(Button: TCommonMouseButton; MousePos: TPoint; HitInfo: TEasyHitInfoGroup); virtual;
procedure DoGroupExpand(Group: TEasyGroup); virtual;
procedure DoGroupExpanding(Group: TEasyGroup; var Allow: Boolean); virtual;
procedure DoGroupFreeing(Group: TEasyGroup); virtual;
procedure DoGroupGetCaption(Group: TEasyGroup; var Caption: WideString); virtual;
procedure DoGroupGetImageIndex(Group: TEasyGroup; ImageKind: TEasyImageKind; var ImageIndex: TCommonImageIndexInteger); virtual;
procedure DoGroupGetImageList(Group: TEasyGroup; var ImageList: TCustomImageList); virtual;
procedure DoGroupGetDetail(Group: TEasyGroup; Line: Integer; var Detail: Integer); virtual;
procedure DoGroupGetDetailCount(Group: TEasyGroup; var Count: Integer); virtual;
procedure DoGroupImageDraw(Group: TEasyGroup; ACanvas: TCanvas; const RectArray: TEasyRectArrayObject; AlphaBlender: TEasyAlphaBlender); virtual;
procedure DoGroupImageGetSize(Group: TEasyGroup; var ImageWidth, ImageHeight: Integer); virtual;
procedure DoGroupImageDrawIsCustom(Group: TEasyGroup; var IsCustom: Boolean); virtual;
procedure DoGroupInitialize(Group: TEasyGroup); virtual;
procedure DoGroupHotTrack(Group: TEasyGroup; State: TEasyHotTrackState; MousePos: TPoint); virtual;
procedure DoGroupLoadFromStream(Group: TEasyGroup; S: TStream; Version: Integer); virtual;
procedure DoGroupPaintText(Group: TEasyGroup; ACanvas: TCanvas); virtual;
procedure DoGroupSaveToStream(Group: TEasyGroup; S: TStream; Version: Integer); virtual;
procedure DoGroupSelectionChanged(Group: TEasyGroup); virtual;
procedure DoGroupSelectionChanging(Group: TEasyGroup; var Allow: Boolean); virtual;
procedure DoGroupSetCaption(Group: TEasyGroup; const Caption: WideString); virtual;
procedure DoGroupSetImageIndex(Group: TEasyGroup; ImageKind: TEasyImageKind; ImageIndex: Integer); virtual;
procedure DoGroupSetDetail(Group: TEasyGroup; Line: Integer; Detail: Integer); virtual;
procedure DoGroupSetDetailCount(Group: TEasyGroup; DetailCount: Integer); virtual;
procedure DoGroupStructureChange; virtual;
procedure DoGroupThumbnailDraw(Group: TEasyGroup; ACanvas: TCanvas; ARect: TRect; AlphaBlender: TEasyAlphaBlender; var DoDefault: Boolean); virtual;
procedure DoGroupVisibilityChanged(Group: TEasyGroup); virtual;
procedure DoGroupVisibilityChanging(Group: TEasyGroup; var Allow: Boolean); virtual;
procedure DoHeaderDblClick(Button: TCommonMouseButton; MousePos: TPoint; ShiftState: TShiftState); virtual;
procedure DoHintCustomInfo(TargetObj: TEasyCollectionItem; const Info: TEasyHintInfo); virtual;
procedure DoHintCustomDraw(TargetObj: TEasyCollectionItem; const Info: TEasyHintInfo); virtual;
procedure DoHintPopup(TargetObj: TEasyCollectionItem; HintType: TEasyHintType; MousePos: TPoint; var AText: WideString; var HideTimeout, ReshowTimeout: Integer; var Allow: Boolean); virtual;
procedure DoHintShowPause(HintShowingNow: Boolean; var PauseTime: Integer);
procedure DoIncrementalSearch(Item: TEasyItem; const SearchBuffer: WideString; var CompareResult: Integer); virtual;
procedure DoItemCheckChanged(Item: TEasyItem); virtual;
procedure DoItemCheckChanging(Item: TEasyItem; var Allow: Boolean); virtual;
procedure DoItemClick(Item: TEasyItem; KeyStates: TCommonKeyStates; HitInfo: TEasyItemHitTestInfoSet); virtual;
function DoItemCompare(Column: TEasyColumn; Group: TEasyGroup; Item1, Item2: TEasyItem): Integer; virtual;
procedure DoItemContextMenu(HitInfo: TEasyHitInfoItem; WindowPoint: TPoint; var Menu: TPopupMenu; var Handled: Boolean); virtual;
procedure DoItemCreateEditor(Item: TEasyItem; var Editor: IEasyCellEditor); virtual;
procedure DoItemCustomView(Item: TEasyItem; ViewStyle: TEasyListStyle; var View: TEasyViewItemClass); virtual;
procedure DoItemDblClick(Button: TCommonMouseButton; MousePos: TPoint; HitInfo: TEasyHitInfoItem); virtual;
procedure DoItemEditBegin(Item: TEasyItem; var Column: Integer; var Allow: Boolean); virtual;
procedure DoItemEdited(Item: TEasyItem; var NewValue: Variant; var Accept: Boolean); virtual;
procedure DoItemEditEnd(Item: TEasyItem); virtual;
procedure DoItemGetEditMenu(Editor: TEasyBaseEditor; var Menu: TPopupMenu); virtual;
procedure DoItemEnableChanged(Item: TEasyItem); virtual;
procedure DoItemEnableChanging(Item: TEasyItem; var Allow: Boolean); virtual;
procedure DoItemFreeing(Item: TEasyItem); virtual;
procedure DoItemFocusChanged(Item: TEasyItem); virtual;
procedure DoItemFocusChanging(Item: TEasyItem; var Allow: Boolean); virtual;
procedure DoItemGetCaption(Item: TEasyItem; Column: Integer; var ACaption: WideString); virtual;
procedure DoItemGetEditCaption(Item: TEasyItem; Column: TEasyColumn; var Caption: WideString); virtual;
procedure DoItemGetGroupKey(Item: TEasyItem; FocusedColumn: Integer; var Key: LongWord); virtual;
procedure DoItemGetImageIndex(Item: TEasyItem; Column: Integer; ImageKind: TEasyImageKind; var ImageIndex: TCommonImageIndexInteger); virtual;
procedure DoItemGetImageList(Item: TEasyItem; Column: Integer; var ImageList: TCustomImageList); virtual;
procedure DoItemGetStateImageList(Item: TEasyItem; Column: Integer; var ImageList: TCustomImageList); virtual;
procedure DoItemGetTileDetail(Item: TEasyItem; Line: Integer; var Detail: Integer); virtual;
procedure DoItemGetTileDetailCount(Item: TEasyItem; var Count: Integer); virtual;
procedure DoItemHotTrack(Item: TEasyItem; State: TEasyHotTrackState; MousePos: TPoint); virtual;
procedure DoItemImageDraw(Item: TEasyItem; Column: TEasyColumn; ACanvas: TCanvas; const RectArray: TEasyRectArrayObject; AlphaBlender: TEasyAlphaBlender); virtual;
procedure DoItemImageGetSize(Item: TEasyItem; Column: TEasyColumn; var ImageWidth, ImageHeight: Integer); virtual;
procedure DoItemImageDrawIsCustom(Column: TEasyColumn; Item: TEasyItem; var IsCustom: Boolean); virtual;
procedure DoItemInitialize(Item: TEasyItem); virtual;
procedure DoItemLoadFromStream(Item: TEasyItem; S: TStream; Version: Integer); virtual;
procedure DoItemMouseDown(Item: TEasyItem; Button: TCommonMouseButton; var DoDefault: Boolean); virtual;
procedure DoItemMouseUp(Item: TEasyItem; Button: TCommonMouseButton; var DoDefault: Boolean); virtual;
procedure DoItemPaintText(Item: TEasyItem; Position: Integer; ACanvas: TCanvas); virtual;
procedure DoItemSaveToStream(Item: TEasyItem; S: TStream; Version: Integer); virtual;
procedure DoItemSelectionChanged(Item: TEasyItem); virtual;
procedure DoItemSelectionChanging(Item: TEasyItem; var Allow: Boolean); virtual;
procedure DoItemSelectionsChanged; virtual;
procedure DoItemSetCaption(Item: TEasyItem; Column: Integer; const Caption: WideString); virtual;
procedure DoItemSetGroupKey(Item: TEasyItem; FocusedColumn: Integer; Key: LongWord); virtual;
procedure DoItemSetImageIndex(Item: TEasyItem; Column: Integer; ImageKind: TEasyImageKind; ImageIndex: Integer); virtual;
procedure DoItemSetTileDetail(Item: TEasyItem; Line: Integer; Detail: Integer); virtual;
procedure DoItemSetTileDetailCount(Item: TEasyItem; Detail: Integer); virtual;
procedure DoItemStructureChange; virtual;
procedure DoItemThumbnailDraw(Item: TEasyItem; ACanvas: TCanvas; ARect: TRect; AlphaBlender: TEasyAlphaBlender; var DoDefault: Boolean); virtual;
procedure DoItemVisibilityChanged(Item: TEasyItem); virtual;
procedure DoItemVisibilityChanging(Item: TEasyItem; var Allow: Boolean); virtual;
function DoMouseWheel(Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint): Boolean; override;
function DoMouseWheelDown(Shift: TShiftState; MousePos: TPoint): Boolean; override;
function DoMouseWheelUp(Shift: TShiftState; MousePos: TPoint): Boolean; override;
procedure DoKeyAction(var CharCode: Word; var Shift: TShiftState; var DoDefault: Boolean); virtual;
procedure DoOLEDragEnd(ADataObject: IDataObject; DragResult: TCommonOLEDragResult; ResultEffect: TCommonDropEffects; KeyStates: TCommonKeyStates); virtual;
procedure DoOLEDragStart(ADataObject: IDataObject; var AvailableEffects: TCommonDropEffects; var AllowDrag: Boolean); virtual;
procedure DoOLEDropSourceQueryContineDrag(EscapeKeyPressed: Boolean; KeyStates: TCommonKeyStates; var QueryResult: TEasyQueryDragResult); virtual;
procedure DoOLEDropSourceGiveFeedback(Effect: TCommonDropEffects; var UseDefaultCursors: Boolean); virtual;
procedure DoOLEDropTargetDragEnter(DataObject: IDataObject; KeyState: TCommonKeyStates; WindowPt: TPoint; AvailableEffects: TCommonDropEffects; var DesiredEffect: TCommonDropEffect); virtual;
procedure DoOLEDropTargetDragOver(KeyState: TCommonKeyStates; WindowPt: TPoint; AvailableEffects: TCommonDropEffects; var DesiredEffect: TCommonDropEffect); virtual;
procedure DoOLEDropTargetDragLeave; virtual;
procedure DoOLEDropTargetDragDrop(DataObject: IDataObject; KeyState: TCommonKeyStates; WindowPt: TPoint; AvailableEffects: TCommonDropEffects; var DesiredEffect: TCommonDropEffect; var Handled: Boolean); virtual;
procedure DoOLEGetCustomFormats(var Formats: TFormatEtcArray); virtual;
procedure DoOLEGetData(const FormatEtcIn: TFormatEtc; var Medium: TStgMedium; var Handled: Boolean); virtual;
procedure DoOLEGetDataObject(var DataObject: IDataObject); virtual;
procedure DoPaintBkGnd(ACanvas: TCanvas; AWindowRect: TRect; AlphaBlender: TEasyAlphaBlender; var DoDefault: Boolean); virtual;
procedure DoPaintHeaderBkGnd(ACanvas: TCanvas; ARect: TRect; var Handled: Boolean); virtual;
procedure DoPaintRect(ACanvas: TCanvas; WindowClipRect: TRect; SelectedOnly: Boolean); virtual;
procedure DoQueryOLEData(const FormatEtcIn: TFormatEtc; var FormatAvailable: Boolean; var Handled: Boolean); virtual;
procedure DoResize(DeltaX, DeltaY: Integer); virtual;
procedure DoScroll(DeltaX, DeltaY: Integer); virtual;
procedure DoThreadCallback(var Msg: TWMThreadRequest); virtual;
procedure DoUpdate; override;
procedure DoViewChange; virtual;
procedure DestroyWnd; override;
function DragInitiated: Boolean;
procedure FinalizeDrag(WindowPoint: TPoint; KeyState: TCommonKeyStates);
procedure HandleDblClick(Button: TCommonMouseButton; Msg: TWMMouse); virtual;
procedure HandleKeyDown(Msg: TWMKeyDown); virtual;
procedure HandleMouseDown(Button: TCommonMouseButton; Msg: TWMMouse); virtual;
procedure HandleMouseUp(Button: TCommonMouseButton; Msg: TWMMouse); virtual;
procedure InitializeDragPendings(HitItem: TEasyItem; WindowPoint: TPoint; KeyState: TCommonKeyStates; AllowDrag, AllowDragRect: Boolean);
function IsFontStored: Boolean;
function IsHeaderMouseMsg(MousePos: TSmallPoint; ForceTest: Boolean = False): Boolean;
procedure MarkSelectedCut;
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
procedure PasteFromClipboard; virtual;
procedure ResizeBackBits(NewWidth, NewHeight: Integer);
procedure SetView(Value: TEasyListStyle); virtual;
procedure WMChar(var Msg: TWMChar); message WM_CHAR;
procedure WMClose(var Msg: TWMClose); message WM_CLOSE;
procedure WMContextMenu(var Msg: TMessage); message WM_CONTEXTMENU;
procedure WMDestroy(var Msg: TMessage); message WM_DESTROY;
procedure WMEasyThreadCallback(var Msg: TWMThreadRequest); message WM_COMMONTHREADCALLBACK;
procedure WMEraseBkGnd(var Msg: TWMEraseBkGnd); message WM_ERASEBKGND;
procedure WMGetDlgCode(var Msg: TWMGetDlgCode); message WM_GETDLGCODE;
procedure WMHScroll(var Msg: TWMHScroll); message WM_HSCROLL;
procedure WMKeyDown(var Msg: TWMKeyDown); message WM_KEYDOWN;
procedure WMKillFocus(var Msg: TWMKillFocus); message WM_KILLFOCUS;
procedure WMLButtonDblClk(var Msg: TWMLButtonDblClk); message WM_LBUTTONDBLCLK;
procedure WMLButtonDown(var Msg: TWMLButtonDown); message WM_LBUTTONDOWN;
procedure WMLButtonUp(var Msg: TWMLButtonUp); message WM_LBUTTONUP;
procedure WMMButtonDblClk(var Msg: TWMMButtonDblClk); message WM_MBUTTONDBLCLK;
procedure WMMButtonDown(var Msg: TWMMButtonDown); message WM_MBUTTONDOWN;
procedure WMMButtonUp(var Msg: TWMMButtonUp); message WM_MBUTTONUP;
procedure WMMouseActivate(var Msg: TWMMouseActivate); message WM_MOUSEACTIVATE;
procedure WMMouseMove(var Msg: TWMMouseMove); message WM_MOUSEMOVE;
procedure WMPaint(var Msg: TWMPaint); message WM_PAINT;
procedure WMNCCalcSize(var Msg: TWMNCCalcSize); message WM_NCCALCSIZE;
procedure WMNCPaint(var Msg: TWMNCPaint); message WM_NCPAINT;
procedure WMRButtonDblClk(var Msg: TWMRButtonDblClk); message WM_RBUTTONDBLCLK;
procedure WMRButtonDown(var Msg: TWMRButtonDown); message WM_RBUTTONDOWN;
procedure WMRButtonUp(var Msg: TWMRButtonUp); message WM_RBUTTONUP;
procedure WMSetCursor(var Msg: TWMSetCursor); message WM_SETCURSOR;
procedure WMSetFocus(var Msg: TWMSetFocus); message WM_SETFOCUS;
procedure WMSize(var Msg: TWMSize); message WM_SIZE;
procedure WMTabMoveFocus(var Msg: TMessage); message WM_TABMOVEFOCUS;
procedure WMVScroll(var Msg: TWMVScroll); message WM_VSCROLL;
procedure WMWindowPosChanged(var Msg: TWMWindowPosChanged); message WM_WINDOWPOSCHANGED;
procedure WMWindowPosChanging(var Msg: TWMWindowPosChanging); message WM_WINDOWPOSCHANGING;
property AllowHiddenCheckedItems: Boolean read FAllowInvisibleCheckedItems write FAllowInvisibleCheckedItems default False;
property BackBits: TBitmap read FBackBits write FBackBits;
property BackGround: TEasyBackgroundManager read FBackGround write SetBackGround;
property BevelInner default bvLowered;
property CacheDoubleBufferBits: Boolean read FCacheDoubleBufferBits write SetCacheDoubleBufferBits;
property CheckManager: TEasyCheckManager read FCheckManager write FCheckManager;
property Color default clWindow;
property CellSizes: TEasyCellSizes read FCellSizes write FCellSizes;
property DisabledBlendAlpha: Byte read FDisabledBlendAlpha write FDisabledBlendAlpha default 128;
property DisabledBlendColor: TColor read FDisabledBlendColor write FDisabledBlendColor default clWindow;
property DragManager: TEasyOLEDragManager read FDragManager write FDragManager;
property DragRect: TEasyDragRectManager read FDragRect write FDragRect;
property DropTarget: IDropTarget read FDropTarget write FDropTarget;
property EditManager: TEasyEditManager read FEditManager write FEditManager;
property Gesture: TEasyGestureManager read FGesture write FGesture;
property GlobalImages: TEasyGlobalImageManager read FGlobalImages write FGlobalImages;
property GroupCollapseButton: TBitmap read GetGroupCollapseImage write SetGroupCollapseImage;
property GroupExpandButton: TBitmap read GetGroupExpandImage write SetGroupExpandImage;
property GroupFont: TFont read FGroupFont write SetGroupFont stored IsFontStored;
property Groups: TEasyGroups read FGroups write FGroups;
property Header: TEasyHeader read FHeader write FHeader;
property HintAlignment: TAlignment read FHintAlignment write FHintAlignment;
property HintData: TEasyHintInfoRec read FHintData write FHintData;
property HintInfo: TEasyHintInfo read FHintInfo write FHintInfo;
property HintType: TEasyHintType read GetHintType write SetHintType default ehtText;
property HotTrack: TEasyHotTrackManager read FHotTrack write FHotTrack;
property ImagesGroup: TCustomImageList read FImagesGroup write SetImagesGroup;
property ImagesSmall: TCustomImageList read FImagesSmall write SetImagesSmall;
property ImagesLarge: TCustomImageList read FImagesLarge write SetImagesLarge;
property ImagesExLarge: TCustomImageList read FImagesExLarge write SetImagesExLarge;
property ImagesState: TCustomImageList read FImagesState write SetImagesState;
property IncrementalSearch: TEasyIncrementalSearchManager read FIncrementalSearch write FIncrementalSearch;
property Items: TEasyGlobalItems read FItems;
property LastMousePos: TSmallPoint read FLastMousePos write FLastMousePos;
property NCCanvas: TCanvas read FNCCanvas write FNCCanvas;
property OnAfterPaint: TAfterPaintEvent read FOnAfterPaint write FOnAfterPaint;
property OnAutoGroupGetKey: TAutoGroupGetKeyEvent read FOnAutoGroupGetKey write FOnAutoGroupGetKey;
property OnAutoSortGroupCreate: TAutoSortGroupCreateEvent read FOnAutoSortGroupCreate write FOnAutoSortGroupCreate;
property OnClipboardCopy: TEasyClipboardEvent read FOnClipboardCopy write FOnClipboardCopy;
property OnClipboardCut: TEasyClipboardCutEvent read FOnClipboardCut write FOnClipboardCut;
property OnClipboardPaste: TEasyClipboardEvent read FOnClipboardPaste write FOnClipboardPaste;
property OnColumnCheckChanged: TColumnCheckChangeEvent read FOnColumnCheckChange write FOnColumnCheckChange;
property OnColumnCheckChanging: TColumnCheckChangingEvent read FOnColumnCheckChanging write FOnColumnCheckChanging;
property OnColumnClick: TColumnClickEvent read FOnColumnClick write FOnColumnClick;
property OnColumnContextMenu: TColumnContextMenuEvent read FOnColumnContextMenu write FOnColumnContextMenu;
property OnColumnCustomView: TColumnCustomViewEvent read FOnColumnCustomView write FOnColumnCustomView;
property OnColumnDblClick: TColumnDblClickEvent read FOnColumnDblClick write FOnColumnDblClick;
property OnColumnDropDownButtonClick: TColumnDropDownButtonClickEvent read FOnColumnDropDownButtonClick write FOnColumnDropDownButtonClick;
property OnColumnEnableChanged: TColumnEnableChangeEvent read FOnColumnEnableChange write FOnColumnEnableChange;
property OnColumnEnableChanging: TColumnEnableChangingEvent read FOnColumnEnableChanging write FOnColumnEnableChanging;
property OnColumnFocusChanged: TColumnFocusChangeEvent read FOnColumnFocusChanged write FOnColumnFocusChanged;
property OnColumnFocusChanging: TColumnFocusChangingEvent read FOnColumnFocusChanging write FOnColumnFocusChanging;
property OnColumnFreeing: TColumnFreeingEvent read FOnColumnFreeing write FOnColumnFreeing;
property OnColumnGetCaption: TColumnGetCaptionEvent read FOnColumnGetCaption write FOnColumnGetCaption;
property OnColumnGetImageIndex: TColumnGetImageIndexEvent read FOnColumnGetImageIndex write FOnColumnGetImageIndex;
property OnColumnGetImageList: TColumnGetImageListEvent read FOnColumnGetImageList write FOnColumnGetImageList;
property OnColumnGetDetail: TColumnGetDetailEvent read FOnColumnGetDetail write FOnColumnGetDetail;
property OnColumnGetDetailCount: TColumnGetDetailCountEvent read FOnColumnGetDetailCount write FOnColumnGetDetailCount;
property OnColumnImageDraw: TColumnImageDrawEvent read FOnColumnImageDraw write FOnColumnImageDraw;
property OnColumnImageGetSize: TColumnImageGetSizeEvent read FOnColumnImageGetSize write FOnColumnImageGetSize;
property OnColumnImageDrawIsCustom: TColumnImageDrawIsCustomEvent read FOnColumnImageDrawIsCustom write FOnColumnImageDrawIsCustom;
property OnColumnInitialize: TColumnInitializeEvent read FOnColumnInitialize write FOnColumnInitialize;
property OnColumnLoadFromStream: TEasyColumnLoadFromStreamEvent read FOnColumnLoadFromStream write FOnColumnLoadFromStream;
property OnColumnPaintText: TColumnPaintTextEvent read FOnColumnPaintText write FOnColumnPaintText;
property OnColumnSaveToStream: TEasyColumnSaveToStreamEvent read FOnColumnSaveToStream write FOnColumnSaveToStream;
property OnColumnSelectionChanged: TColumnSelectionChangeEvent read FOnColumnSelectionChanged write FOnColumnSelectionChanged;
property OnColumnSelectionChanging: TColumnSelectionChangingEvent read FOnColumnSelectionChanging write FOnColumnSelectionChanging;
property OnColumnSetCaption: TColumnSetCaptionEvent read FOnColumnSetCaption write FOnColumnSetCaption;
property OnColumnSetImageIndex: TColumnSetImageIndexEvent read FOnColumnSetImageIndex write FOnColumnSetImageIndex;
property OnColumnSetDetail: TColumnSetDetailEvent read FOnColumnSetDetail write FOnColumnSetDetail;
property OnColumnStructureChange: TNotifyEvent read FOnColumnStructureChange write FOnColumnStructureChange;
property OnColumnThumbnailDraw: TColumnThumbnailDrawEvent read FOnColumnThumbnailDraw write FOnColumnThumbnailDraw;
property OnColumnSizeChanged: TColumnSizeChangedEvent read FOnColumnSizeChanged write FOnColumnSizeChanged;
property OnColumnSizeChanging: TColumnSizeChangingEvent read FOnColumnSizeChanging write FOnColumnSizeChanging;
property OnColumnVisibilityChanged: TColumnVisibilityChangeEvent read FOnColumnVisibilityChanged write FOnColumnVisibilityChanged;
property OnColumnVisibilityChanging: TColumnVisibilityChangingEvent read FOnColumnVisibilityChanging write FOnColumnVisibilityChanging;
property OnContextMenu: TContextMenuEvent read FOnContextMenu write FOnContextMenu;
property OnCustomGrid: TCustomGridEvent read FOnCustomGrid write FOnCustomGrid;
property OnDblClick: TDblClickEvent read FOnDblClick write FOnDblClick;
property OnGetDragImage: TGetDragImageEvent read FOnGetDragImage write FOnGetDragImage;
property OnGroupClick: TGroupClickEvent read FOnGroupClick write FOnGroupClick;
property OnGroupCollapse: TGroupCollapseEvent read FOnGroupCollapse write FOnGroupCollapse;
property OnGroupCollapsing: TGroupCollapsingEvent read FOnGroupCollapsing write FOnGroupCollapsing;
property OnGroupCompare: TGroupCompareEvent read FOnGroupCompare write FOnGroupCompare;
property OnGroupContextMenu: TGroupContextMenuEvent read FOnGroupContextMenu write FOnGroupContextMenu;
property OnGroupCustomView: TGroupCustomViewEvent read FOnGroupCustomView write FOnGroupCustomView;
property OnGroupDblClick: TGroupDblClickEvent read FOnGroupDblClick write FOnGroupDblClick;
property OnGroupExpand: TGroupExpandEvent read FOnGroupExpand write FOnGroupExpand;
property OnGroupExpanding: TGroupExpandingEvent read FOnGroupExpanding write FOnGroupExpanding;
property OnGroupFocusChanged: TGroupFocusChangeEvent read FOnGroupFocusChanged write FOnGroupFocusChanged;
property OnGroupFocusChanging: TGroupFocusChangingEvent read FOnGroupFocusChanging write FOnGroupFocusChanging;
property OnGroupFreeing: TGroupFreeingEvent read FOnGroupFreeing write FOnGroupFreeing;
property OnGroupGetCaption: TGroupGetCaptionEvent read FOnGroupGetCaption write FOnGroupGetCaption;
property OnGroupGetImageIndex: TGroupGetImageIndexEvent read FOnGroupGetImageIndex write FOnGroupGetImageIndex;
property OnGroupGetImageList: TGroupGetImageListEvent read FOnGroupGetImageList write FOnGroupGetImageList;
property OnGroupGetDetail: TGroupGetDetailEvent read FOnGroupGetDetailIndex write FOnGroupGetDetailIndex;
property OnGroupGetDetailCount: TGroupGetDetailCountEvent read FOnGroupGetDetailCount write FOnGroupGetDetailCount;
property OnGroupHotTrack: TGroupHotTrackEvent read FOnGroupHotTrack write FOnGroupHotTrack;
property OnGroupImageDraw: TGroupImageDrawEvent read FOnGroupImageDrawEvent write FOnGroupImageDrawEvent;
property OnGroupImageGetSize: TGroupImageGetSizeEvent read FGroupImageGetSize write FGroupImageGetSize;
property OnGroupImageDrawIsCustom: TGroupImageDrawIsCustomEvent read FOnGroupImageDrawIsCustom write FOnGroupImageDrawIsCustom;
property OnGroupInitialize: TGroupInitializeEvent read FOnGroupInitialize write FOnGroupInitialize;
property OnGroupLoadFromStream: TGroupLoadFromStreamEvent read FOnGroupLoadFromStream write FOnGroupLoadFromStream;
property OnGroupPaintText: TGroupPaintTextEvent read FOnGroupPaintText write FOnGroupPaintText;
property OnGroupSaveToStream: TGroupSaveToStreamEvent read FOnGroupSaveToStream write FOnGroupSaveToStream;
property OnGroupSelectionChanged: TGroupSelectionChangeEvent read FOnGroupSelectionChanged write FOnGroupSelectionChanged;
property OnGroupSelectionChanging: TGroupSelectionChangingEvent read FOnGroupSelectionChanging write FOnGroupSelectionChanging;
property OnGroupSetCaption: TGroupSetCaptionEvent read FOnGroupSetCaption write FOnGroupSetCaption;
property OnGroupSetImageIndex: TGroupSetImageIndexEvent read FOnGroupSetImageIndex write FOnGroupSetImageIndex;
property OnGroupSetDetail: TGroupSetDetailEvent read FOnGroupSetDetail write FOnGroupSetDetail;
property OnGroupStructureChange: TNotifyEvent read FOnGroupStructureChange write FOnGroupStructureChange;
property OnGroupThumbnailDraw: TGroupThumbnailDrawEvent read FOnGroupThumbnailDraw write FOnGroupThumbnailDraw;
property OnGroupVisibilityChanged: TGroupVisibilityChangeEvent read FOnGroupVisibilityChanged write FOnGroupVisibilityChanged;
property OnGroupVisibilityChanging: TGroupVisibilityChangingEvent read FOnGroupVisibilityChanging write FOnGroupVisibilityChanging;
property OnHeaderDblClick: THeaderDblClickEvent read FOnHeaderDblClick write FOnHeaderDblClick;
property OnHeaderMouseDown: THeaderMouseEvent read FOnHeaderMouseDown write FOnHeaderMouseDown;
property OnHeaderMouseMove: TMouseMoveEvent read FOnHeaderMouseMove write FOnHeaderMouseMove;
property OnHeaderMouseUp: THeaderMouseEvent read FOnHeaderMouseUp write FOnHeaderMouseUp;
property OnHintCustomDraw: THintCustomDrawEvent read FOnHintCustomDraw write FOnHintCustomDraw;
property OnHintCustomInfo: THintCustomizeInfoEvent read FOnHintCustomInfo write FOnHintCustomInfo;
property OnHintPauseTime: THintPauseTimeEvent read FOnHintPauseTime write FOnHintPauseTime;
property OnHintPopup: THintPopupEvent read FOnHintPopup write FOnHintPopup;
property OnIncrementalSearch: TIncrementalSearchEvent read FOnIncrementalSearch write FOnIncrementalSearch;
property OnItemCheckChange: TItemCheckChangeEvent read FOnItemCheckChange write FOnItemCheckChange;
property OnItemCheckChanging: TItemCheckChangingEvent read FOnItemCheckChanging write FOnItemCheckChanging;
property OnItemClick: TItemClickEvent read FOnItemClick write FOnItemClick;
property OnItemCompare: TItemCompareEvent read FOnItemCompare write FOnItemCompare;
property OnItemContextMenu: TItemContextMenuEvent read FOnItemContextMenu write FOnItemContextMenu;
property OnItemCreateEditor: TItemCreateEditorEvent read FOnItemCreateEditor write FOnItemCreateEditor;
property OnItemCustomView: TItemCustomViewEvent read FOnItemCustomView write FOnItemCustomView;
property OnItemDblClick: TItemDblClickEvent read FOnItemDblClick write FOnItemDblClick;
property OnItemEditBegin: TItemEditBegin read FOnItemEditBegin write FOnItemEditBegin;
property OnItemEdited: TItemEditedEvent read FOnItemEdited write FOnItemEdited;
property OnItemEditEnd: TItemEditEnd read FOnItemEditEnd write FOnItemEditEnd;
property OnItemEnableChange: TItemEnableChangeEvent read FOnItemEnableChange write FOnItemEnableChange;
property OnItemEnableChanging: TItemEnableChangingEvent read FOnItemEnableChanging write FOnItemEnableChanging;
property OnItemFreeing: TItemFreeingEvent read FOnItemFreeing write FOnItemFreeing;
property OnItemFocusChanged: TItemFocusChangeEvent read FOnItemFocusChanged write FOnItemFocusChanged;
property OnItemFocusChanging: TItemFocusChangingEvent read FOnItemFocusChanging write FOnItemFocusChanging;
property OnItemGetCaption: TItemGetCaptionEvent read FOnItemGetCaption write FOnItemGetCaption;
property OnItemGetEditCaption: TEasyItemGetCaptionEvent read FOnItemGetEditCaption write FOnItemGetEditCaption;
property OnItemGetEditMenu: TItemGetEditMenuEvent read FOnItemGetEditMenu write FOnItemGetEditMenu;
property OnItemGetGroupKey: TItemGetGroupKeyEvent read FOnItemGetGroupKey write FOnItemGetGroupKey;
property OnItemHotTrack: TItemHotTrackEvent read FOnItemHotTrack write FOnItemHotTrack;
property OnItemGetImageIndex: TItemGetImageIndexEvent read FOnItemGetImageIndex write FOnItemGetImageIndex;
property OnItemGetImageList: TItemGetImageListEvent read FOnItemGetImageList write FOnItemGetImageList;
property OnItemGetStateImageList: TItemGetImageListEvent read FOnItemGetStateImageList write FOnItemGetStateImageList;
property OnItemGetTileDetail: TItemGetTileDetailEvent read FOnItemGetTileDetailIndex write FOnItemGetTileDetailIndex;
property OnItemGetTileDetailCount: TItemGetTileDetailCountEvent read FOnItemGetTileDetailCount write FOnItemGetTileDetailCount;
property OnItemImageDraw: TItemImageDrawEvent read FOnItemImageDraw write FOnItemImageDraw;
property OnItemImageGetSize: TItemImageGetSizeEvent read FOnItemImageGetSize write FOnItemImageGetSize;
property OnItemImageDrawIsCustom: TItemImageDrawIsCustomEvent read FOnItemImageDrawIsCustom write FOnItemImageDrawIsCustom;
property OnItemLoadFromStream: TItemLoadFromStreamEvent read FOnItemLoadFromStream write FOnItemLoadFromStream;
property OnItemInitialize: TItemInitializeEvent read FOnItemInitialize write FOnItemInitialize;
property OnItemMouseDown: TItemMouseDownEvent read FOnItemMouseDown write FOnItemMouseDown;
property OnItemMouseUp: TItemMouseUpEvent read FOnItemMouseUp write FOnItemMouseUp;
property OnItemPaintText: TItemPaintTextEvent read FOnItemPaintText write FOnItemPaintText;
property OnItemSaveToStream: TItemSaveToStreamEvent read FOnItemSaveToStream write FOnItemSaveToStream;
property OnItemSelectionChanged: TItemSelectionChangeEvent read FOnItemSelectionChanged write FOnItemSelectionChanged;
property OnItemSelectionChanging: TItemSelectionChangingEvent read FOnItemSelectionChanging write FOnItemSelectionChanging;
property OnItemSelectionsChanged: TEasyItemSelectionsChangedEvent read FOnItemSelectionsChanged write FOnItemSelectionsChanged;
property OnItemSetCaption: TItemSetCaptionEvent read FOnItemSetCaption write FOnItemSetCaption;
property OnItemSetGroupKey: TItemSetGroupKeyEvent read FOnItemSetGroupKey write FOnItemSetGroupKey;
property OnItemSetImageIndex: TItemSetImageIndexEvent read FOnItemSetImageIndex write FOnItemSetImageIndex;
property OnItemSetTileDetail: TItemSetTileDetailEvent read FOnItemSetTileDetail write FOnItemSetTileDetail;
property OnItemStructureChange: TNotifyEvent read FOnItemStructureChange write FOnItemStructureChange;
property OnItemThumbnailDraw: TItemThumbnailDrawEvent read FOnItemThumbnailDraw write FOnItemThumbnailDraw;
property OnItemVisibilityChanged: TItemVisibilityChangeEvent read FOnItemVisibilityChanged write FOnItemVisibilityChanged;
property OnItemVisibilityChanging: TItemVisibilityChangingEvent read FOnItemVisibilityChanging write FOnItemVisibilityChanging;
property OnKeyAction: TEasyKeyActionEvent read FOnKeyAction write FOnKeyAction;
property OnMouseGesture: TEasyGestureEvent read FOnMouseGesture write FOnMouseGesture;
property OnOLEDragEnd: TOLEDropSourceDragEndEvent read FOnOLEDragEnd write FOnOLEDragEnd;
property OnOLEDragStart: TOLEDropSourceDragStartEvent read FOnOLEDragStart write FOnOLEDragStart;
property OnOLEDragEnter: TOLEDropTargetDragEnterEvent read FOnOLEDragEnter write FOnOLEDragEnter;
property OnOLEDragOver: TOLEDropTargetDragOverEvent read FOnOLEDragOver write FOnOLEDragOver;
property OnOLEDragLeave: TOLEDropTargetDragLeaveEvent read FOnOLEDragLeave write FOnOLEDragLeave;
property OnOLEDragDrop: TOLEDropTargetDragDropEvent read FOnOLEDragDrop write FOnOLEDragDrop;
property OnOLEGetCustomFormats: TOLEGetCustomFormatsEvent read FOnOLEGetCustomFormats write FOnOLEGetCustomFormats;
property OnOLEGetData: TOLEGetDataEvent read FOnOLEGetData write FOnOLEGetData;
property OnOLEGetDataObject: FOLEGetDataObjectEvent read FOnOLEGetDataObject write FOnOLEGetDataObject;
property OnOLEQueryContineDrag: TOLEDropSourceQueryContineDragEvent read FOnOLEQueryContineDrag write FOnOLEQueryContineDrag;
property OnOLEGiveFeedback: TOLEDropSourceGiveFeedbackEvent read FOnOLEGiveFeedback write FOnOLEGiveFeedback;
property OnOLEQueryData: TOLEQueryDataEvent read FOnOLEQueryData write FOnOLEQueryData;
property OnPaintBkGnd: TPaintBkGndEvent read FOnPaintBkGnd write FOnPaintBkGnd;
property OnPaintHeaderBkGnd: TPaintHeaderBkGndEvent read FOnPaintHeaderBkGnd write FOnPaintHeaderBkGnd;
property OnScroll: TEasyScrollEvent read FOnScroll write FOnScroll;
property OnViewChange: TViewChangedEvent read FOnViewChange write FOnViewChange;
property PaintInfoColumn: TEasyPaintInfoBaseColumn read GetPaintInfoColumn write SetPaintInfoColumn;
property PaintInfoGroup: TEasyPaintInfoBaseGroup read GetPaintInfoGroup write SetPaintInfoGroup;
property PaintInfoItem: TEasyPaintInfoBaseItem read GetPaintInfoItem write SetPaintInfoItem;
{$IFDEF COMPILER_7_UP}property ParentBackground default False;{$ENDIF COMPILER_7_UP}
property ParentColor default False;
property PopupMenuHeader: TPopupMenu read FPopupMenuHeader write FPopupMenuHeader;
property ScratchCanvas: TControlCanvas read GetScratchCanvas write FScratchCanvas;
property Scrollbars: TEasyScrollbarManager read FScrollbars write FScrollbars;
property Selection: TEasySelectionManager read FSelection write SetSelection;
property ShowGroupMargins: Boolean read FShowGroupMargins write SetShowGroupMargins default False;
property ShowInactive: Boolean read FShowInactive write SetShowInactive default False;
property ShowThemedBorder: Boolean read FShowThemedBorder write SetShowThemedBorder default True;
property Sort: TEasySortManager read FSort write FSort;
property TabStop default True;
property View: TEasyListStyle read FView write SetView;
property WheelMouseDefaultScroll: TEasyDefaultWheelScroll read FWheelMouseDefaultScroll write FWheelMouseDefaultScroll default edwsVert;
property WheelMouseScrollModifierEnabled: Boolean read FWheelMouseScrollModifierEnabled write FWheelMouseScrollModifierEnabled default True;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function ClientInViewportCoords: TRect;
function IsGrouped: Boolean; virtual;
function IsThumbnailView: Boolean;
function IsVertView: Boolean;
function ScrollHeaderHorz: Boolean;
procedure AutoFitAllCells(VisibleOnly: Boolean);
procedure BeginUpdate; override;
procedure EndUpdate(Invalidate: Boolean = True); override;
procedure Loaded; override;
procedure LoadFromFile(FileName: WideString; Mode: Word);
procedure LoadFromStream(S: TStream); virtual;
procedure SaveToFile(FileName: WideString; Mode: Word);
procedure SaveToStream(S: TStream); virtual;
property ForcePaint: Boolean read FForcePaint write FForcePaint;
property States: TEasyControlStates read FStates write FStates;
property TopItem: TEasyItem read GetTopItem;
published
end;
TEasyBaseEditor = class(TEasyInterfacedPersistent, IEasyCellEditor)
private
FEditColumn: TEasyColumn;
FEditor: TWinControl;
FItem: TEasyItem;
FModified: Boolean;
FOldWndProc: TWndMethod;
FRectArray: TEasyRectArrayObject;
function GetEditor: TWinControl; virtual;
function GetListview: TCustomEasyListview;
procedure SetEditor(const Value: TWinControl); virtual;
protected
function EditText(Item: TEasyItem; Column: TEasyColumn): WideString; virtual;
function GetEditorColor: TColor;
procedure CalculateEditorRect(NewText: WideString; var NewRect: TRect); virtual; abstract;
procedure CreateEditor(var AnEditor: TWinControl; Column: TEasyColumn; Parent: TWinControl); virtual; abstract;
function GetEditorFont: TFont; virtual; abstract;
function GetText: Variant; virtual; abstract;
procedure ResizeEditor;
property EditColumn: TEasyColumn read FEditColumn write FEditColumn;
property Editor: TWinControl read GetEditor write SetEditor;
property Item: TEasyItem read FItem write FItem;
property Listview: TCustomEasyListview read GetListview;
property Modified: Boolean read FModified write FModified;
property OldWndProc: TWndMethod read FOldWndProc write FOldWndProc;
property RectArray: TEasyRectArrayObject read FRectArray write FRectArray;
public
function AcceptEdit: Boolean; {IEasyCellEditor}
procedure ControlWndHookProc(var Message: TMessage); {IEasyCellEditor}
function GetHandle: HWnd; {IEasyCellEditor}
function GetModified: Boolean; {IEasyCellEditor}
function PtInEditControl(WindowPt: TPoint): Boolean; {IEasyCellEditor}
procedure Finalize; {IEasyCellEditor}
procedure Hide; {IEasyCellEditor}
procedure Initialize(AnItem: TEasyItem; Column: TEasyColumn); {IEasyCellEditor}
procedure SelectAll; virtual; abstract;
procedure SetEditorFocus; virtual; {IEasyCellEditor}
procedure Show; {IEasyCellEditor}
property Handle: HWnd read GetHandle;
end;
TEasyStringEditor = class(TEasyBaseEditor)
protected
procedure CalculateEditorRect(NewText: WideString; var NewRect: TRect); override;
procedure CreateEditor(var AnEditor: TWinControl; Column: TEasyColumn; Parent: TWinControl); override;
function GetEditorFont: TFont; override;
function GetText: Variant; override;
procedure DoEditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState;
var DoDefault: Boolean); virtual;
procedure OnEditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
public
procedure SelectAll; override;
procedure SetEditorFocus; override;
end;
TEasyMemoEditor = class(TEasyBaseEditor)
protected
procedure CalculateEditorRect(NewText: WideString; var NewRect: TRect); override;
procedure CreateEditor(var AnEditor: TWinControl; Column: TEasyColumn; Parent: TWinControl); override;
function GetEditorFont: TFont; override;
function GetText: Variant; override;
procedure DoEditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState; var DoDefault: Boolean); virtual;
procedure OnEditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
public
procedure SelectAll; override;
procedure SetEditorFocus; override;
end;
TEasyListview = class(TCustomEasyListview)
private
function GetPaintInfoColumn: TEasyPaintInfoColumn; reintroduce; virtual;
function GetPaintInfoGroup: TEasyPaintInfoGroup; reintroduce; virtual;
function GetPaintInfoItem: TEasyPaintInfoItem; reintroduce; virtual;
procedure SetPaintInfoColumn(const Value: TEasyPaintInfoColumn); reintroduce; virtual;
procedure SetPaintInfoGroup(const Value: TEasyPaintInfoGroup); reintroduce; virtual;
procedure SetPaintInfoItem(const Value: TEasyPaintInfoItem); reintroduce; virtual;
public
property CheckManager;
property GlobalImages;
property Items;
property States;
published
property Align;
property AllowHiddenCheckedItems;
property Anchors;
property BackGround;
property BevelKind;
property BevelInner;
property BevelOuter;
property BevelWidth;
property BiDiMode;
property BorderWidth;
property CacheDoubleBufferBits;
property CellSizes;
property Color;
property Constraints;
property Ctl3D;
property DisabledBlendAlpha;
property DisabledBlendColor;
property EditManager;
property Gesture;
property ImagesState;
property UseDockManager default True;
property DragKind;
property DragManager;
property Font;
property GroupCollapseButton;
property GroupExpandButton;
property GroupFont;
property Groups;
property HintAlignment;
property HintType;
property Header;
property HotTrack;
property IncrementalSearch;
property ImagesGroup;
property ImagesSmall;
property ImagesLarge;
property ImagesExLarge;
property PaintInfoColumn: TEasyPaintInfoColumn read GetPaintInfoColumn write SetPaintInfoColumn;
property PaintInfoGroup: TEasyPaintInfoGroup read GetPaintInfoGroup write SetPaintInfoGroup;
property PaintInfoItem: TEasyPaintInfoItem read GetPaintInfoItem write SetPaintInfoItem;
property ParentBiDiMode;
{$IFDEF COMPILER_7_UP}property ParentBackground;{$ENDIF}
property ParentColor;
property ParentCtl3D;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property PopupMenuHeader;
property Scrollbars;
property ShowGroupMargins;
property ShowInactive;
property ShowThemedBorder;
property ShowHint;
property Selection;
property Sort;
property TabOrder;
property TabStop;
property Themed;
property View;
property Visible;
property WheelMouseDefaultScroll;
property WheelMouseScrollModifierEnabled;
property OnAfterPaint;
property OnCanResize;
property OnClick;
property OnConstrainedResize;
{$IFDEF COMPILER_5_UP}
property OnContextPopup;
{$ENDIF}
property OnAutoGroupGetKey;
property OnAutoSortGroupCreate;
property OnClipboardCopy;
property OnClipboardCut;
property OnClipboardPaste;
property OnColumnCheckChanged;
property OnColumnCheckChanging;
property OnColumnClick;
property OnColumnContextMenu;
property OnColumnCustomView;
property OnColumnDblClick;
property OnColumnDropDownButtonClick;
property OnColumnEnableChanged;
property OnColumnEnableChanging;
property OnColumnFreeing;
property OnColumnGetCaption;
property OnColumnGetImageIndex;
property OnColumnGetImageList;
property OnColumnGetDetail;
property OnColumnGetDetailCount;
property OnColumnImageDraw;
property OnColumnImageGetSize;
property OnColumnImageDrawIsCustom;
property OnColumnInitialize;
property OnColumnLoadFromStream;
property OnColumnPaintText;
property OnColumnSaveToStream;
property OnColumnSelectionChanged;
property OnColumnSelectionChanging;
property OnColumnSetCaption;
property OnColumnSetImageIndex;
property OnColumnSetDetail;
property OnColumnSizeChanged;
property OnColumnSizeChanging;
property OnColumnStructureChange;
property OnColumnVisibilityChanged;
property OnColumnVisibilityChanging;
property OnCustomGrid;
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnDockDrop;
property OnDockOver;
property OnEndDock;
property OnEndDrag;
property OnEndUpdate;
property OnEnter;
property OnExit;
property OnGetDragImage;
property OnGetSiteInfo;
property OnGroupClick;
property OnGroupCollapse;
property OnGroupCollapsing;
property OnGroupCompare;
property OnGroupContextMenu;
property OnGroupCustomView;
property OnGroupDblClick;
property OnGroupExpand;
property OnGroupExpanding;
property OnGroupFreeing;
property OnGroupGetCaption;
property OnGroupGetImageIndex;
property OnGroupGetImageList;
property OnGroupGetDetail;
property OnGroupGetDetailCount;
property OnGroupImageDraw;
property OnGroupImageGetSize;
property OnGroupImageDrawIsCustom;
property OnGroupInitialize;
property OnGroupLoadFromStream;
property OnGroupPaintText;
property OnGroupHotTrack;
property OnGroupSaveToStream;
property OnGroupSetCaption;
property OnGroupSetImageIndex;
property OnGroupSetDetail;
property OnGroupStructureChange;
property OnGroupVisibilityChanged;
property OnGroupVisibilityChanging;
property OnHeaderDblClick;
property OnHeaderMouseDown;
property OnHeaderMouseMove;
property OnHeaderMouseUp;
property OnHintCustomInfo;
property OnHintCustomDraw;
property OnHintPauseTime;
property OnHintPopup;
property OnIncrementalSearch;
property OnItemCheckChange;
property OnItemCheckChanging;
property OnItemClick;
property OnItemCompare;
property OnItemContextMenu;
property OnItemCreateEditor;
property OnItemCustomView;
property OnItemDblClick;
property OnItemEditBegin;
property OnItemEdited;
property OnItemEditEnd;
property OnItemEnableChange;
property OnItemEnableChanging;
property OnItemFreeing;
property OnItemFocusChanged;
property OnItemFocusChanging;
property OnItemGetCaption;
property OnItemGetEditCaption;
property OnItemGetEditMenu;
property OnItemGetGroupKey;
property OnItemGetImageIndex;
property OnItemGetImageList;
property OnItemGetTileDetail;
property OnItemGetTileDetailCount;
property OnItemHotTrack;
property OnItemImageDraw;
property OnItemImageGetSize;
property OnItemImageDrawIsCustom;
property OnItemInitialize;
property OnItemLoadFromStream;
property OnItemMouseDown;
property OnItemMouseUp;
property OnItemPaintText;
property OnItemSaveToStream;
property OnItemSelectionChanged;
property OnItemSelectionChanging;
property OnItemSelectionsChanged;
property OnItemSetCaption;
property OnItemSetGroupKey;
property OnItemSetImageIndex;
property OnItemSetTileDetail;
property OnItemStructureChange;
property OnItemThumbnailDraw;
property OnItemVisibilityChanged;
property OnItemVisibilityChanging;
property OnKeyAction;
property OnMouseGesture;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnMouseWheel;
property OnMouseWheelDown;
property OnMouseWheelUp;
property OnOLEDragEnd;
property OnOLEDragStart;
property OnOLEDragEnter;
property OnOLEDragOver;
property OnOLEDragLeave;
property OnOLEDragDrop;
property OnOLEGetCustomFormats;
property OnOLEGetData;
property OnOLEGetDataObject;
property OnOLEQueryContineDrag;
property OnOLEGiveFeedback;
property OnOLEQueryData;
property OnPaintHeaderBkGnd;
property OnPaintBkGnd;
property OnResize;
property OnScroll;
property OnStartDock;
property OnStartDrag;
property OnUnDock;
property OnViewChange;
end;
TEasyBaseTaskBand = class(TCustomEasyListview)
protected
function CreateColumnPaintInfo: TEasyPaintInfoBaseColumn; override;
function CreateGroupPaintInfo: TEasyPaintInfoBaseGroup; override;
function CreateItemPaintInfo: TEasyPaintInfoBaseItem; override;
function GetPaintInfoColumn: TEasyPaintInfoTaskBandColumn; reintroduce; virtual;
function GetPaintInfoGroup: TEasyPaintInfoTaskbandGroup; reintroduce; virtual;
function GetPaintInfoItem: TEasyPaintInfoTaskBandItem; reintroduce; virtual;
function GroupTestExpand(HitInfo: TEasyGroupHitTestInfoSet): Boolean; override;
procedure DoCustomGrid(Group: TEasyGroup; ViewStyle: TEasyListStyle; var Grid: TEasyGridGroupClass); override;
procedure DoGroupCustomView(Group: TEasyGroup; ViewStyle: TEasyListStyle; var View: TEasyViewGroupClass); override;
procedure DoItemCustomView(Item: TEasyItem; ViewStyle: TEasyListStyle; var View: TEasyViewItemClass); override;
procedure SetPaintInfoColumn(const Value: TEasyPaintInfoTaskBandColumn); reintroduce; virtual;
procedure SetPaintInfoGroup(const Value: TEasyPaintInfoTaskbandGroup); reintroduce; virtual;
procedure SetPaintInfoItem(const Value: TEasyPaintInfoTaskBandItem); reintroduce; virtual;
property PaintInfoColumn: TEasyPaintInfoTaskBandColumn read GetPaintInfoColumn write SetPaintInfoColumn;
public
constructor Create(AOwner: TComponent); override;
end;
TEasyTaskPanelBand = class(TEasyBaseTaskBand)
private
FAutoScrollPanels: Boolean;
FOnGetTaskPanel: TEasyGetTaskPanelEvent;
function GetGroups: TEasyGroupsTaskPanel;
procedure SetGroups(const Value: TEasyGroupsTaskPanel);
protected
function CreateGroups: TEasyGroups; override;
procedure CMMouseWheel(var Msg: TCMMouseWheel); message CM_MOUSEWHEEL;
procedure DoCustomGrid(Group: TEasyGroup; ViewStyle: TEasyListStyle; var Grid: TEasyGridGroupClass); override;
procedure DoGetTaskPanel(Sender: TEasyGroupTaskPanel; var TaskPanel: TEasyTaskPanelFormClass); virtual;
procedure DoGroupCustomView(Group: TEasyGroup; ViewStyle: TEasyListStyle; var View: TEasyViewGroupClass); override;
procedure DoGroupExpand(Group: TEasyGroup); override;
procedure PositionPanels;
procedure WMHScroll(var Msg: TWMHScroll); message WM_HSCROLL;
procedure WMVScroll(var Msg: TWMVScroll); message WM_VSCROLL;
procedure WMWindowPosChanging(var Msg: TWMWindowPosChanging); message WM_WINDOWPOSCHANGING;
public
constructor Create(AOwner: TComponent); override;
published
property Align;
property Anchors;
property AutoScrollPanels: Boolean read FAutoScrollPanels write FAutoScrollPanels default False;
property BackGround;
property BevelInner;
property BevelOuter;
property BevelWidth;
property BiDiMode;
property BorderWidth;
property Color;
property Constraints;
property Ctl3D;
property OnGetTaskPanel: TEasyGetTaskPanelEvent read FOnGetTaskPanel write FOnGetTaskPanel;
property UseDockManager default True;
property Font;
property GroupFont;
property Groups: TEasyGroupsTaskPanel read GetGroups write SetGroups;
property HintAlignment;
property HintType;
property HotTrack;
property IncrementalSearch;
property ImagesGroup;
property ImagesSmall;
property PaintInfoGroup;
property ParentBiDiMode;
{$IFDEF COMPILER_7_UP}property ParentBackground;{$ENDIF}
property ParentColor;
property ParentCtl3D;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property ShowThemedBorder;
property ShowHint;
property Selection;
property Sort;
property TabOrder;
property TabStop;
property Themed;
property Visible;
property WheelMouseDefaultScroll;
property WheelMouseScrollModifierEnabled;
property OnCanResize;
property OnClick;
property OnConstrainedResize;
{$IFDEF COMPILER_5_UP} property OnContextPopup; {$ENDIF}
property OnAutoSortGroupCreate;
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnDockDrop;
property OnDockOver;
property OnEndDock;
property OnEndDrag;
property OnEndUpdate;
property OnEnter;
property OnExit;
property OnGetSiteInfo;
property OnGroupClick;
property OnGroupCollapse;
property OnGroupCollapsing;
property OnGroupContextMenu;
property OnGroupCustomView;
property OnGroupDblClick;
property OnGroupExpand;
property OnGroupExpanding;
property OnGroupFreeing;
property OnGroupGetCaption;
property OnGroupGetImageIndex;
property OnGroupGetImageList;
property OnGroupImageDraw;
property OnGroupImageGetSize;
property OnGroupImageDrawIsCustom;
property OnGroupInitialize;
property OnGroupPaintText;
property OnGroupHotTrack;
property OnGroupSetCaption;
property OnGroupSetImageIndex;
property OnGroupVisibilityChanged;
property OnGroupVisibilityChanging;
property OnHintCustomInfo;
property OnHintCustomDraw;
property OnHintPauseTime;
property OnHintPopup;
property OnKeyAction;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnMouseWheel;
property OnMouseWheelDown;
property OnMouseWheelUp;
property OnPaintBkGnd;
property OnResize;
property OnStartDock;
property OnStartDrag;
property OnUnDock;
end;
TEasyTaskBand = class(TEasyBaseTaskBand)
protected
procedure DoGroupCollapse(Group: TEasyGroup); override;
procedure DoGroupExpand(Group: TEasyGroup); override;
public
property GlobalImages;
property Items;
property States;
property Scrollbars;
published
property Align;
property Anchors;
property BevelInner;
property BevelOuter;
property BevelWidth;
property BiDiMode;
property BorderWidth;
property CellSizes;
property Color;
property Constraints;
property Ctl3D;
property EditManager;
property UseDockManager default True;
property DragKind;
property DragManager;
property Font;
property GroupFont;
property Groups;
property HintAlignment;
property HintType;
property HotTrack;
property IncrementalSearch;
property ImagesGroup;
property ImagesSmall;
property PaintInfoGroup: TEasyPaintInfoTaskbandGroup read GetPaintInfoGroup write SetPaintInfoGroup;
property PaintInfoItem: TEasyPaintInfoTaskBandItem read GetPaintInfoItem write SetPaintInfoItem;
property ParentBiDiMode;
{$IFDEF COMPILER_7_UP}property ParentBackground;{$ENDIF}
property ParentColor;
property ParentCtl3D;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property PopupMenuHeader;
property ShowGroupMargins;
property ShowThemedBorder;
property ShowHint;
property Selection;
property Sort;
property TabOrder;
property TabStop;
property Themed;
property Visible;
property WheelMouseDefaultScroll;
property WheelMouseScrollModifierEnabled;
property OnCanResize;
property OnClick;
property OnConstrainedResize;
{$IFDEF COMPILER_5_UP}
property OnContextPopup;
{$ENDIF}
property OnAutoSortGroupCreate;
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnDockDrop;
property OnDockOver;
property OnEndDock;
property OnEndDrag;
property OnEndUpdate;
property OnEnter;
property OnExit;
property OnGetDragImage;
property OnGetSiteInfo;
property OnGroupClick;
property OnGroupCollapse;
property OnGroupCollapsing;
property OnGroupCompare;
property OnGroupContextMenu;
property OnGroupDblClick;
property OnGroupExpand;
property OnGroupExpanding;
property OnGroupFreeing;
property OnGroupGetCaption;
property OnGroupGetImageIndex;
property OnGroupGetImageList;
property OnGroupImageDraw;
property OnGroupImageGetSize;
property OnGroupImageDrawIsCustom;
property OnGroupInitialize;
property OnGroupPaintText;
property OnGroupHotTrack;
property OnGroupSetCaption;
property OnGroupSetImageIndex;
property OnGroupSetDetail;
property OnGroupVisibilityChanged;
property OnGroupVisibilityChanging;
property OnHeaderDblClick;
property OnHeaderMouseDown;
property OnHeaderMouseMove;
property OnHeaderMouseUp;
property OnHintCustomInfo;
property OnHintCustomDraw;
property OnHintPauseTime;
property OnHintPopup;
property OnIncrementalSearch;
property OnItemCheckChange;
property OnItemCheckChanging;
property OnItemClick;
property OnItemCompare;
property OnItemContextMenu;
property OnItemCreateEditor;
property OnItemDblClick;
property OnItemEditBegin;
property OnItemEdited;
property OnItemEditEnd;
property OnItemEnableChange;
property OnItemEnableChanging;
property OnItemFreeing;
property OnItemFocusChanged;
property OnItemFocusChanging;
property OnItemGetCaption;
property OnItemGetGroupKey;
property OnItemGetImageIndex;
property OnItemGetImageList;
property OnItemHotTrack;
property OnItemImageDraw;
property OnItemImageGetSize;
property OnItemImageDrawIsCustom;
property OnItemInitialize;
property OnItemMouseDown;
property OnItemPaintText;
property OnItemSelectionChanged;
property OnItemSelectionChanging;
property OnItemSetCaption;
property OnItemSetGroupKey;
property OnItemSetImageIndex;
property OnItemVisibilityChanged;
property OnItemVisibilityChanging;
property OnKeyAction;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnMouseWheel;
property OnMouseWheelDown;
property OnMouseWheelUp;
property OnOLEDragEnd;
property OnOLEDragStart;
property OnOLEDragEnter;
property OnOLEDragOver;
property OnOLEDragLeave;
property OnOLEDragDrop;
property OnOLEGetCustomFormats;
property OnOLEGetData;
property OnOLEQueryContineDrag;
property OnOLEGiveFeedback;
property OnOLEQueryData;
property OnPaintBkGnd;
property OnResize;
property OnStartDock;
property OnStartDrag;
property OnUnDock;
end;
const
EASYLISTSTYLETEXTS: array[TEasyListStyle] of string =
('Icon', 'Small Icon', 'List', 'Details', 'Thumbnail', 'Tile', 'FilmStrip', 'Grid');
EASYSORTALGORITHMS: array[TEasySortAlgorithm] of string =
('QuickSort', 'BubbleSort', 'MergeSort');
HEADERSUPPORTEDVIEWS = [elsReport, elsGrid];
VERTICALVIEWS = [elsIcon, elsSmallIcon, elsReport, elsThumbnail, elsTile, elsGrid];
THUMBNAILVIEWS = [elsThumbnail, elsFilmStrip];
MULTILINEVIEWS = [elsIcon, elsThumbnail, elsFilmStrip, elsTile];
procedure FillStringsWithEasyListStyles(Strings: TStrings);
procedure FillStringsWithEasySortAlgorithms(Strings: TStrings);
var
AlphaBlender: TEasyAlphaBlender;
implementation
uses
Math;
const
PERSISTENTOBJECTSTATES = [esosSelected, esosEnabled, esosVisible, esosChecked, esosBold]; // States that are stored to a stream for persistance
H_STRINGEDITORMARGIN = 12; // Margin for String Editors in the Horz direction
V_STRINGEDITORMARGIN = 2; // Margin for String Editors in the Vert direction
var
HeaderClipboardFormat: TClipFormat;
type
TWinControlHack = class(TWinControl);
type
PHeaderClipData = ^THeaderClipData;
THeaderClipData = record
Thread: THandle;
Listview: TCustomEasyListview;
Column: TEasyColumn;
end;
const
MaxPixelCount = 65536;
type
TRGBArray = array[0..MaxPixelCount-1] OF TRGBQuad;
pRGBArray = ^TRGBArray;
// Very simple implementation for saving/loading the tree to disk with a Unicode
// filename in NT. Use TnT Uniocode package for a full blown implementation
TWideFileStream = class(THandleStream)
public
constructor Create(const FileName: WideString; Mode: Word);
destructor Destroy; override;
end;
TWinControlCracker = class(TWinControl) end;
function WeightPixels (const pixelA, pixelB, pixelWeightA, pixelWeightB: Cardinal): Byte;
begin
Result := Byte((pixelWeightA*pixelA + pixelWeightB*pixelB) DIV (pixelWeightA + pixelWeightB))
end {WeightPixels};
procedure BlendBits(Bits1, Bits2: TBitmap; WeightA, WeightB: Integer; BlurBits2: Boolean);
var
y, x: Integer;
RowA, RowB, TargetRow, PrevRow, NextRow: pRGBArray;
RGBArrayA, RGBArrayB, PrevRGBArrayB, NextRGBArrayB, PrevRowRGBArrayB, NextRowRGBArrayB: TRGBQuad;
begin
if (Bits1.Height > 0) and (Bits1.Width = Bits2.Width) and (Bits1.Height = Bits2.Height) then
begin
PrevRow := nil;
for y := 0 to Bits1.Height - 1 do
begin
RowA := Bits1.ScanLine[y];
RowB := Bits2.ScanLine[y];
TargetRow := Bits2.ScanLine[y];
if y + 1 < Bits1.Height then
NextRow := Bits2.ScanLine[y+1]
else
NextRow := nil;
for x := 0 to Bits1.Width - 1 do
begin
RGBArrayA := RowA[x];
RGBArrayB := RowB[x];
if BlurBits2 and Assigned(NextRow) and Assigned(PrevRow) and (x > 0) and (x < Bits1.Width - 1) then
begin
PrevRGBArrayB := TargetRow[x-1];
NextRGBArrayB := TargetRow[x+1];
PrevRowRGBArrayB := PrevRow[x];
NextRowRGBArrayB := NextRow[x];
RGBArrayB.rgbBlue := (
PrevRow[x-1].rgbBlue +
PrevRow[x+1].rgbBlue +
NextRow[x-1].rgbBlue +
NextRow[x+1].rgbBlue +
PrevRowRGBArrayB.rgbBlue +
NextRowRGBArrayB.rgbBlue +
TargetRow[x].rgbBlue div 2+
PrevRGBArrayB.rgbBlue +
NextRGBArrayB.rgbBlue) div 9;
RGBArrayB.rgbGreen := (PrevRow[x-1].rgbGreen +
PrevRow[x+1].rgbGreen +
NextRow[x-1].rgbGreen +
NextRow[x+1].rgbGreen +
PrevRowRGBArrayB.rgbGreen +
NextRowRGBArrayB.rgbGreen +
TargetRow[x].rgbGreen div 2 +
PrevRGBArrayB.rgbGreen +
NextRGBArrayB.rgbGreen) div 9;
RGBArrayB.rgbRed := ( PrevRow[x-1].rgbRed +
PrevRow[x+1].rgbRed +
NextRow[x-1].rgbRed +
NextRow[x+1].rgbRed +
PrevRowRGBArrayB.rgbRed +
NextRowRGBArrayB.rgbRed +
TargetRow[x].rgbRed div 2 +
PrevRGBArrayB.rgbRed +
NextRGBArrayB.rgbRed) div 9;
end;
RGBArrayB.rgbBlue := WeightPixels(RGBArrayA.rgbBlue, RGBArrayB.rgbBlue, WeightA, WeightB);
RGBArrayB.rgbGreen := WeightPixels(RGBArrayA.rgbGreen, RGBArrayB.rgbGreen, WeightA, WeightB);
RGBArrayB.rgbRed := WeightPixels(RGBArrayA.rgbRed, RGBArrayB.rgbRed, WeightA, WeightB);
RowB[x] := RGBArrayB;
end;
PrevRow := TargetRow;
end;
end;
end;
function HeaderClipFormat: TFormatEtc;
begin
Result.cfFormat := HeaderClipboardFormat;
Result.ptd := nil;
Result.lindex := -1;
Result.dwAspect := -1;
Result.ptd := nil;
Result.tymed := TYMED_HGLOBAL
end;
function DefaultSort(Column: TEasyColumn; Item1, Item2: TEasyCollectionItem): Integer;
var
Index: Integer;
begin
if not Assigned(Column) then
Index := 0
else
Index := Column.Position;
Result := WideStrIComp(PWideChar(Item1.Captions[Index]), PWideChar( Item2.Captions[Index]));
if Assigned(Column) and (Column.SortDirection = esdDescending) then
Result := -Result
end;
procedure FillStringsWithEasyListStyles(Strings: TStrings);
var
ListStyle: TEasyListStyle;
begin
Strings.Clear;
for ListStyle := low(TEasyListStyle) to high(TEasyListStyle) do
Strings.Add(EASYLISTSTYLETEXTS[ListStyle]);
end;
procedure FillStringsWithEasySortAlgorithms(Strings: TStrings);
var
ListStyle: TEasySortAlgorithm;
begin
Strings.Clear;
for ListStyle := low(TEasySortAlgorithm) to high(TEasySortAlgorithm) do
Strings.Add(EASYSORTALGORITHMS[ListStyle]);
end;
function WideFileCreate(const FileName: WideString): Integer;
begin
if Win32Platform = VER_PLATFORM_WIN32_NT then
Result := Integer(CreateFileW(PWideChar(FileName), GENERIC_READ or GENERIC_WRITE, 0,
nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0))
else
Result := Integer(CreateFileA(PAnsiChar(AnsiString(PWideChar(FileName))), GENERIC_READ or GENERIC_WRITE, 0,
nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0));
end;
function WideFileOpen(const FileName: WideString; Mode: LongWord): Integer;
const
AccessMode: array[0..2] of LongWord = (
GENERIC_READ,
GENERIC_WRITE,
GENERIC_READ or GENERIC_WRITE);
ShareMode: array[0..4] of LongWord = (
0,
0,
FILE_SHARE_READ,
FILE_SHARE_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE);
begin
if Win32Platform = VER_PLATFORM_WIN32_NT then
Result := Integer(CreateFileW(PWideChar(FileName), AccessMode[Mode and 3], ShareMode[(Mode and $F0) shr 4],
nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0))
else
Result := Integer(CreateFileA(PAnsiChar(AnsiString(FileName)), AccessMode[Mode and 3], ShareMode[(Mode and $F0) shr 4],
nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0));
end;
{ TWideFileStream }
constructor TWideFileStream.Create(const FileName: WideString; Mode: Word);
var
CreateHandle: Integer;
begin
if Mode = fmCreate then
begin
CreateHandle := WideFileCreate(FileName);
if CreateHandle < 0 then
{$IFNDEF COMPILER_5_UP}
raise EFCreateError.Create('Can not create file: ' + FileName);
{$ELSE}
raise EFCreateError.CreateResFmt(PResStringRec(@SFCreateError), [FileName]);
{$ENDIF COMPILER_5_UP}
end else
begin
CreateHandle := WideFileOpen(FileName, Mode);
if CreateHandle < 0 then
{$IFNDEF COMPILER_5_UP}
raise EFCreateError.Create('Can not create file: ' + FileName);
{$ELSE}
raise EFCreateError.CreateResFmt(PResStringRec(@SFCreateError), [FileName]);
{$ENDIF COMPILER_5_UP}
end;
inherited Create(CreateHandle);
end;
destructor TWideFileStream.Destroy;
begin
if Handle >= 0 then FileClose(Handle);
inherited Destroy;
end;
{ TEasyGroupItemOwnedPersistent }
constructor TEasyOwnedPersistentGroupItem.Create(AnOwner: TEasyGroup);
begin
inherited Create(AnOwner.OwnerListview);
FOwnerGroup := AnOwner
end;
{ TEasyOwnedPersistent}
constructor TEasyOwnedPersistent.Create(AnOwner: TCustomEasyListview);
begin
inherited Create;
FOwnerListview := AnOwner;
end;
function TEasyOwnedPersistent.GetOwner: TPersistent;
begin
Result := FOwnerListview;
end;
procedure TEasyOwnedPersistent.LoadFromStream(S: TStream; Version: Integer = EASYLISTVIEW_STREAM_VERSION);
begin
end;
procedure TEasyOwnedPersistent.SaveToStream(S: TStream; Version: Integer = EASYLISTVIEW_STREAM_VERSION);
begin
end;
{ TEasyInterfacedPersistent }
function TEasyInterfacedPersistent.GetObj: TObject;
begin
Result := Self
end;
function TEasyInterfacedPersistent._AddRef: Integer;
begin
Result := InterlockedIncrement(FRefCount);
end;
function TEasyInterfacedPersistent._Release: Integer;
begin
Result := InterlockedDecrement(FRefCount);
if (Result = 0) then
Destroy;
end;
function TEasyInterfacedPersistent.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
if GetInterface(IID, Obj) then
Result := 0
else
Result := E_NOINTERFACE
end;
procedure TEasyInterfacedPersistent.AfterConstruction;
begin
// Release the constructor's implicit refcount
InterlockedDecrement(FRefCount);
end;
procedure TEasyInterfacedPersistent.BeforeDestruction;
begin
end;
class function TEasyInterfacedPersistent.NewInstance: TObject;
begin
// Set an implicit refcount so that refcounting
// during construction won't destroy the object.
Result := inherited NewInstance;
TEasyInterfacedPersistent(Result).FRefCount := 1;
end;
{ TEasyOwnedInterfacedPersistent }
constructor TEasyOwnedInterfacedPersistent.Create(AnOwner: TCustomEasyListview);
begin
inherited Create;
FOwner := AnOwner;
end;
{ TEasyMargins }
constructor TEasyMargin.Create(AnOwner: TCustomEasyListview);
begin
inherited;
FSize := 30;
end;
destructor TEasyMargin.Destroy;
begin
inherited Destroy;
end;
function TEasyMargin.RuntimeSize: Integer;
begin
if not Visible or not FOwnerListview.ShowGroupMargins then
Result := 0
else
Result := FSize
end;
procedure TEasyMargin.Assign(Source: TPersistent);
var
Temp: TEasyMargin;
begin
if Source is TEasyMargin then
begin
Temp := TEasyMargin(Source);
FSize := Temp.Size;
FVisible := Temp.Visible
end
end;
procedure TEasyMargin.SetSize(Value: Integer);
begin
if Value <> FSize then
begin
if Value < 0 then
FSize := 0
else
FSize := Value;
OwnerListview.Groups.Rebuild
end
end;
procedure TEasyMargin.SetVisible(Value: Boolean);
begin
if Value <> FVisible then
begin
FVisible := Value;
OwnerListview.Groups.Rebuild
end
end;
{ TEasyHeaderMargin }
constructor TEasyHeaderMargin.Create(AnOwner: TCustomEasyListview);
begin
inherited Create(AnOwner);
FVisible := True;
end;
function TEasyItems.Add(Data: TObject = nil): TEasyItem;
begin
Result := TEasyItem( inherited Add(Data))
end;
function TEasyItems.AddCustom(CustomItem: TEasyItemClass; Data: TObject = nil): TEasyItem;
begin
Result := nil;
if Assigned(CustomItem) then
begin
Result := CustomItem.Create(Self);
FList.Add(Result);
ReIndexItems;
DoItemAdd(Result, FList.Count - 1);
Result.Data := Data;
DoStructureChange
end
end;
function TEasyItems.AddInterfaced(const DataInf: IUnknown; Data: TObject = nil): TEasyItemInterfaced;
begin
Result := nil;
if Assigned(DataInf) then
begin
Result := TEasyItemInterfaced.Create(Self);
FList.Add(Result);
ReIndexItems;
DoItemAdd(Result, FList.Count - 1);
Result.DataInf := DataInf;
Result.Data := Data;
DoStructureChange
end
end;
function TEasyItems.AddVirtual(Data: TObject = nil): TEasyItemVirtual;
begin
Result := TEasyItemVirtual.Create(Self);
FList.Add(Result);
ReIndexItems;
DoItemAdd(Result, FList.Count - 1);
Result.Data := Data;
DoStructureChange
end;
constructor TEasyItems.Create(AnOwner: TCustomEasyListview; AnOwnerGroup: TEasyGroup);
begin
inherited Create(AnOwner);
FOwnerGroup := AnOwnerGroup;
FItemClass := TEasyItemStored;
end;
function TEasyItems.InsertCustom(Index: Integer; CustomItem: TEasyItemClass; Data: TObject = nil): TEasyItem;
begin
Result := CustomItem.Create(Self);
FList.Insert(Index, Result);
ReIndexItems;
DoItemAdd(Result, Index);
Result.Data := Data;
DoStructureChange
end;
function TEasyItems.InsertInterfaced(Index: Integer; const DataInf: IUnknown; Data: TObject = nil): TEasyItemInterfaced;
begin
Result := nil;
if Assigned(DataInf) then
begin
Result := TEasyItemInterfaced.Create(Self);
FList.Insert(Index, Result);
ReIndexItems;
DoItemAdd(Result, Index);
Result.DataInf := DataInf;
Result.Data := Data;
DoStructureChange
end
end;
function TEasyItems.InsertVirtual(Index: Integer; Data: TObject = nil): TEasyItemVirtual;
begin
Result := TEasyItemVirtual.Create(Self);
FList.Insert(Index, Result);
ReIndexItems;
DoItemAdd(Result, Index);
Result.Data := Data;
DoStructureChange
end;
procedure TEasyItems.Clear(FreeItems: Boolean = True);
begin
OwnerListview.Selection.IncMultiChangeCount;
OwnerListview.Selection.GroupSelectBeginUpdate;
inherited Clear(FreeItems);
OwnerListview.Selection.GroupSelectEndUpdate;
OwnerListview.Selection.DecMultiChangeCount;
end;
procedure TEasyItems.Delete(Index: Integer);
var
Temp: TEasyItem;
begin
// Find the next or prev visible item
Temp := nil;
if not (csDestroying in OwnerListview.ComponentState) and Items[Index].Focused then
begin
Temp := OwnerGroup.OwnerGroups.NextVisibleItem(Items[Index]);
if not Assigned(Temp) then
Temp := OwnerGroup.OwnerGroups.PrevVisibleItem(Items[Index]);
end;
// Delete the item, it will also unfocus the item
inherited;
// Focus the next or prev visible item
if Assigned(Temp) then
Temp.Focused := True;
end;
destructor TEasyItems.Destroy;
begin
inherited;
end;
procedure TEasyItems.DoStructureChange;
begin
OwnerListview.IncrementalSearch.ResetSearch;
OwnerListview.Groups.Rebuild(False);
if OwnerListview.Sort.AutoSort then
OwnerListview.Sort.SortAll;
OwnerListview.DoItemStructureChange;
end;
procedure TEasyItems.Exchange(Index1, Index2: Integer);
begin
inherited;
end;
function TEasyItems.GetItem(Index: Integer): TEasyItem;
begin
// This is a bottle neck for large data sets. Do this direct instead of inherited
Result := ( FList.List[Index])
end;
function TEasyItems.Insert(Index: Integer; Data: TObject = nil): TEasyItem;
begin
Result := TEasyItem( inherited Insert(Index));
end;
procedure TEasyItems.SetItem(Index: Integer; Value: TEasyItem);
begin
inherited Items[Index] := Value
end;
{ TEasyGlobalItems}
function TEasyGlobalItems.Add(Data: TObject = nil): TEasyItem;
begin
EnsureFirstGroup;
Result := TEasyItem(GetLastGroup.Items.Add(Data));
end;
function TEasyGlobalItems.AddCustom(CustomItem: TEasyItemClass; Data: TObject = nil): TEasyItem;
begin
EnsureFirstGroup;
Result := GetLastGroup.Items.AddCustom(CustomItem, Data);
end;
function TEasyGlobalItems.AddInterfaced(const DataInf: IUnknown; Data: TObject = nil): TEasyItemInterfaced;
begin
EnsureFirstGroup;
Result := GetLastGroup.Items.AddInterfaced(DataInf, Data);
end;
function TEasyGlobalItems.AddVirtual(Data: TObject = nil): TEasyItemVirtual;
begin
EnsureFirstGroup;
Result := GetLastGroup.Items.AddVirtual(Data);
end;
procedure TEasyGlobalItems.Clear;
begin
FOwner.Groups.Clear;
end;
constructor TEasyGlobalItems.Create(AnOwner: TCustomEasyListview);
begin
inherited Create;
FOwner := AnOwner;
end;
procedure TEasyGlobalItems.Delete(Index: Integer; ReIndex: Boolean = True);
var
Item: TEasyItem;
begin
// OwnerListview.Groups.Delete(Index);
Item := Items[Index];
Item.OwnerGroup.Items.Delete(Item.Index);
// OwnerListview.Groups.ReIndexItems(nil, ReIndex);
end;
procedure TEasyGlobalItems.EnsureFirstGroup;
begin
if FOwner.Groups.Count = 0 then
FOwner.Groups.Add.Caption := DEFAULT_GROUP_NAME;
end;
procedure TEasyGlobalItems.Exchange(Index1, Index2: Integer);
var
Item1, Item2: TEasyItem;
begin
Item1 := Items[Index1];
Item2 := Items[Index2];
if Item1.OwnerItems = Item2.OwnerItems then
Item1.OwnerItems.Exchange(Item1.Index, Item2.Index)
else
raise Exception.Create('exchange of items between different groups is not yet supported'); // TODO
end;
function TEasyGlobalItems.GetCount: Integer;
var
i: Integer;
begin
Result := 0;
for i := FOwner.Groups.Count - 1 downto 0 do
Inc(Result, FOwner.Groups[i].Items.Count);
end;
function TEasyGlobalItems.GetItem(Index: Integer): TEasyItem;
begin
Result := GetItemInternal(Index);
if Result = nil then // index too big
IndexError(Index);
end;
function TEasyGlobalItems.GetItemInternal(Index: Integer): TEasyItem;
var
i: Integer;
ItemCount: Integer;
begin
// GetItemInternal translates an absolute index into an item. It simply
// returns nil if the index is too big but raises an exception for negative
// indexes.
if Index < 0 then
IndexError(Index);
Result := nil;
for i := 0 to FOwner.Groups.Count - 1 do
begin
ItemCount := FOwner.Groups[i].Items.Count;
if Index < ItemCount then
begin
Result := FOwner.Groups[i].Items[Index];
break;
end;
Dec(Index, ItemCount);
end;
end;
function TEasyGlobalItems.GetLastGroup: TEasyGroup;
begin
if FOwner.Groups.Count > 0 then
Result := FOwner.Groups[FOwner.Groups.Count - 1]
else
Result := nil;
end;
procedure TEasyGlobalItems.IndexError(Index: Integer);
begin
{$IFDEF COMPILER_5_UP}
TList.Error(SListIndexError, Index);
{$ELSE}
TList.Error('List index out of bounds (%d)', Index);
{$ENDIF}
end;
function TEasyGlobalItems.IndexOf(Item: TEasyItem): Integer;
var
GroupIndex: Integer;
begin
Result := Item.Index;
for GroupIndex := Item.OwnerGroup.Index - 1 downto 0 do
Inc(Result, OwnerListview.Groups[GroupIndex].Items.Count);
end;
function TEasyGlobalItems.Insert(Index: Integer; Data: TObject = nil): TEasyItem;
var
Item: TEasyItem;
begin
Item := GetItemInternal(Index);
if Item = nil then
Result := Add
else
Result := Item.OwnerItems.Insert(Item.Index, Data);
end;
function TEasyGlobalItems.InsertCustom(Index: Integer; CustomItem: TEasyItemClass; Data: TObject = nil): TEasyItem;
var
Item: TEasyItem;
begin
Item := GetItemInternal(Index);
if Item = nil then
Result := AddCustom(CustomItem, Data)
else
Result := Item.OwnerItems.InsertCustom(Item.Index, CustomItem, Data);
end;
function TEasyGlobalItems.InsertInterfaced(Index: Integer; const DataInf: IUnknown; Data: TObject = nil): TEasyItemInterfaced;
var
Item: TEasyItem;
begin
Item := GetItemInternal(Index);
if Item = nil then
Result := AddInterfaced(DataInf, Data)
else
Result := Item.OwnerItems.InsertInterfaced(Item.Index, DataInf, Data);
end;
function TEasyGlobalItems.InsertVirtual(Index: Integer; Data: TObject = nil): TEasyItemVirtual;
var
Item: TEasyItem;
begin
Item := GetItemInternal(Index);
if Item = nil then
Result := AddVirtual
else
Result := Item.OwnerItems.InsertVirtual(Item.Index, Data);
end;
procedure TEasyGlobalItems.SetItem(Index: Integer; const Value: TEasyItem);
var
Item: TEasyItem;
begin
Item := Items[Index];
Item.OwnerItems[Item.Index] := Value;
end;
procedure TEasyGlobalItems.SetReIndexDisable(const Value: Boolean);
begin
EnsureFirstGroup;
FOwner.Groups.ReIndexDisable := Value;
end;
{ TEasyGroups }
constructor TEasyGroups.Create(AnOwner: TCustomEasyListview);
begin
inherited Create(AnOwner);
FItemClass := TEasyGroupStored;
FStreamGroups := True
end;
destructor TEasyGroups.Destroy;
begin
inherited Destroy;
end;
function TEasyGroups.Add(Data: TObject = nil): TEasyGroup;
begin
Result := TEasyGroup( inherited Add(Data));
end;
function TEasyGroups.AddCustom(CustomGroup: TEasyGroupClass; Data: TObject = nil): TEasyGroup;
begin
Result := nil;
if Assigned(CustomGroup) then
begin
Result := CustomGroup.Create(Self);
FList.Add(Result);
ReIndexItems;
Result.Data := Data;
DoItemAdd(Result, FList.Count - 1);
DoStructureChange
end
end;
function TEasyGroups.AddInterfaced(const DataInf: IUnknown; Data: TObject = nil): TEasyGroupInterfaced;
begin
Result := nil;
if Assigned(DataInf) then
begin
Result := TEasyGroupInterfaced.Create(Self);
FList.Add(Result);
ReIndexItems;
Result.DataInf := DataInf;
Result.Data := Data;
DoItemAdd(Result, FList.Count - 1);
DoStructureChange
end
end;
function TEasyGroups.AddVirtual(Data: TObject = nil): TEasyGroupVirtual;
begin
Result := TEasyGroupVirtual.Create(Self);
FList.Add(Result);
ReIndexItems;
Result.Data := Data;
DoItemAdd(Result, FList.Count - 1);
DoStructureChange
end;
function TEasyGroups.AdjacentItem(Item: TEasyItem;
Direction: TEasyAdjacentCellDir): TEasyItem;
begin
Result := nil;
if Assigned(Item) then
Result := Item.OwnerGroup.Grid.AdjacentItem(Item, Direction);
end;
function TEasyGroups.CanMoveDown: Boolean;
begin
Result := not OwnerListview.Sort.AutoSort and (Count > 0) and
((LastItem.Index < OwnerListview.Items.Count - 1) or (LastItem.Index - FirstItem.Index > Count - 1));
end;
function TEasyGroups.CanMoveUp: Boolean;
begin
Result := not OwnerListview.Sort.AutoSort and (Count > 0) and
((FirstItem.Index > 0) or (LastItem.Index - FirstItem.Index > Count - 1));
end;
function TEasyGroups.FirstGroup: TEasyGroup;
begin
Result := FirstGroupInternal(False)
end;
function TEasyGroups.FirstGroupInRect(ViewportRect: TRect): TEasyGroup;
//
// Find the first group in the passed rectangle. It implicitly assumes
// Visible Groups
//
var
i: Integer;
R: TRect;
begin
Result := nil;
i := 0;
while (i < Count) and not Assigned(Result) do
begin
if Groups[i].Visible then
if IntersectRect(R, Groups[i].DisplayRect, ViewportRect) then
Result := Groups[i];
Inc(i)
end
end;
function TEasyGroups.FirstGroupInternal(VisibleOnly: Boolean): TEasyGroup;
var
GroupIndex: Integer;
begin
Result := nil;
GroupIndex := 0;
if Count > 0 then
begin
while not Assigned(Result) and (GroupIndex < Count) do
begin
if VisibleOnly then
begin
if Groups[GroupIndex].Visible then
Result := Groups[GroupIndex]
end else
Result := Groups[GroupIndex];
Inc(GroupIndex)
end;
end
end;
function TEasyGroups.FirstInGroup(Group: TEasyGroup): TEasyItem;
begin
Result := FirstInGroupInternal(Group, False)
end;
function TEasyGroups.FirstInGroupInternal(Group: TEasyGroup; VisibleOnly: Boolean): TEasyItem;
var
ItemIndex: Integer;
begin
Result := nil;
ItemIndex := 0;
if Assigned(Group) then
begin
if Assigned(Group.Items) then
begin
if Group.Items.Count > 0 then
begin
if VisibleOnly then
begin
while not Assigned(Result) and (ItemIndex < Group.Items.Count) do
begin
if Group.Items[ItemIndex].Visible then
Result := Group.Items[ItemIndex];
Inc(ItemIndex)
end
end else
Result := Group.Items[ItemIndex]
end
end
end
end;
function TEasyGroups.FirstInitializedItem: TEasyItem;
begin
Result := FirstItemInternal(enitInitialized)
end;
function TEasyGroups.FirstItem: TEasyItem;
begin
Result := FirstItemInternal(enitAny)
end;
function TEasyGroups.FirstItemInRect(ViewportRect: TRect): TEasyItem;
//
// Find the first Item in the passed rectangle. It implicitly assumes
// Visible Items
//
var
Group: TEasyGroup;
i: Integer;
R, FullDisplayRect: TRect;
begin
Result := nil;
i := 0;
if OwnerListview.View = elsReport then
begin
Group := FirstGroupInRect(ViewportRect);
while not Assigned(Result) and Assigned(Group) do
begin
if (Group.Items.Count > 0) and Group.Expanded then
begin
while not Assigned(Result) and (i < Group.Items.Count) do
begin
FullDisplayRect := OwnerListview.Header.ViewRect;
FullDisplayRect.Top := Group.Items[i].DisplayRect.Top;
FullDisplayRect.Bottom := Group.Items[i].DisplayRect.Bottom;
if Group.Items[i].Visible and IntersectRect(R, FullDisplayRect, ViewportRect) then
Result := Group.Items[i]
else
Inc(i)
end
end;
i := 0;
Group := NextGroupInRect(Group, ViewportRect);
end
end else
begin
Group := FirstGroupInRect(ViewportRect);
while not Assigned(Result) and Assigned(Group) do
begin
if (Group.Items.Count > 0) and Group.Expanded then
begin
while not Assigned(Result) and (i < Group.Items.Count) do
begin
if Group.Items[i].Visible and IntersectRect(R, Group.Items[i].DisplayRect, ViewportRect) then
Result := Group.Items[i]
else
Inc(i)
end
end;
i := 0;
Group := NextGroupInRect(Group, ViewportRect);
end
end
end;
function TEasyGroups.FirstItemInternal(NextItemType: TEasyNextItemType): TEasyItem;
var
GroupIndex, ItemIndex: Integer;
begin
Result := nil;
GroupIndex := 0;
ItemIndex := 0;
if Count > 0 then
begin
while not Assigned(Result) and (GroupIndex < Count) do
begin
if Assigned(Groups[GroupIndex].Items) then
begin
if Groups[GroupIndex].Items.Count > 0 then
begin
case NextItemType of
enitVisible:
begin
while not Assigned(Result) and (ItemIndex < Groups[GroupIndex].Items.Count) do
begin
if Groups[GroupIndex].Items[ItemIndex].Visible then
Result := Groups[GroupIndex].Items[ItemIndex];
Inc(ItemIndex)
end
end;
enitInitialized:
begin
while not Assigned(Result) and (ItemIndex < Groups[GroupIndex].Items.Count) do
begin
if Groups[GroupIndex].Items[ItemIndex].Initialized then
Result := Groups[GroupIndex].Items[ItemIndex];
Inc(ItemIndex)
end
end;
else
Result := Groups[GroupIndex].Items[0];
end
end;
end;
ItemIndex := 0;
Inc(GroupIndex)
end
end
end;
function TEasyGroups.FirstVisibleGroup: TEasyGroup;
begin
Result := FirstGroupInternal(True)
end;
function TEasyGroups.FirstVisibleInGroup(Group: TEasyGroup): TEasyItem;
begin
Result := FirstInGroupInternal(Group, True)
end;
function TEasyGroups.FirstVisibleItem: TEasyItem;
begin
Result := FirstItemInternal(enitVisible)
end;
function TEasyGroups.GetCellHeight: Integer;
begin
if Count > 0 then
Result := Groups[0].Grid.CellSize.Height
else
Result := 0
end;
function TEasyGroups.GetCellWidth: Integer;
begin
if Count > 0 then
Result := Groups[0].Grid.CellSize.Width
else
Result := 0
end;
function TEasyGroups.GetGroup(Index: Integer): TEasyGroup;
begin
// Bottleneck, no inherited call
Result := TEasyGroup( FList.List[Index])
end;
function TEasyGroups.GetItemCount: Integer;
var
i: Integer;
begin
Result := 0;
for i := 0 to FList.Count - 1 do
Result := Result + TEasyGroup(FList[i]).ItemCount
end;
function TEasyGroups.GetViewRect: TRect;
begin
Result := Rect(0, 0, 0, 0);
if LastVisibleGroup <> nil then
Result.BottomRight := LastVisibleGroup.DisplayRect.BottomRight;
end;
function TEasyGroups.GetVisibleGroup(Index: Integer): TEasyGroup;
begin
Result := nil;
if (Index > -1) and (Index < VisibleCount) then
Result := TEasyGroup( VisibleList[Index])
end;
function TEasyGroups.GroupByPoint(ViewportPoint: TPoint): TEasyGroup;
var
i: Integer;
begin
Result := nil;
i := 0;
while (i < Count) and not Assigned(Result) do
begin
if Groups[i].Visible and Groups[i].Enabled then
if PtInRect(Groups[i].DisplayRect, ViewportPoint) then
Result := Groups[i];
Inc(i)
end
end;
function TEasyGroups.Insert(Index: Integer; Data: TObject = nil): TEasyGroup;
begin
Result := TEasyGroup( inherited Insert(Index, Data))
end;
function TEasyGroups.InsertCustom(Index: Integer; CustomGroup: TEasyGroupClass; Data: TObject = nil): TEasyGroup;
begin
Result := nil;
if Assigned(CustomGroup) then
begin
Result := CustomGroup.Create(Self);
FList.Insert(Index, Result);
ReIndexItems;
DoItemAdd(Result, Index);
Result.Data := Data;
DoStructureChange
end
end;
function TEasyGroups.InsertInterfaced(Index: Integer; const DataInf: IUnknown; Data: TObject): TEasyGroupInterfaced;
begin
Result := nil;
if Assigned(Data) then
begin
Result := TEasyGroupInterfaced.Create(Self);
FList.Insert(Index, Result);
ReIndexItems;
DoItemAdd(Result, Index);
Result.DataInf := DataInf;
Result.Data := Data;
DoStructureChange
end
end;
function TEasyGroups.InsertVirtual(Index: Integer; Data: TObject = nil): TEasyGroupVirtual;
begin
Result := TEasyGroupVirtual.Create(Self);
FList.Insert(Index, Result);
ReIndexItems;
DoItemAdd(Result, Index);
Result.Data := Data;
DoStructureChange
end;
function TEasyGroups.ItemByPoint(ViewportPoint: TPoint): TEasyItem;
var
Group: TEasyGroup;
begin
Result := nil;
Group := GroupByPoint(ViewportPoint);
if Assigned(Group) then
Result := Group.ItemByPoint(ViewportPoint)
end;
function TEasyGroups.LastGroup: TEasyGroup;
begin
Result := LastGroupInternal(False)
end;
function TEasyGroups.LastGroupInternal(VisibleOnly: Boolean): TEasyGroup;
var
GroupIndex: Integer;
begin
Result := nil;
if Count > 0 then
begin
if VisibleOnly then
begin
GroupIndex := Count - 1;
while not Assigned(Result) and (GroupIndex > -1) do
begin
if Groups[GroupIndex].Visible then
Result := Groups[GroupIndex]
else
Dec(GroupIndex)
end
end else
Result := Groups[Count - 1]
end
end;
function TEasyGroups.LastInGroup(Group: TEasyGroup): TEasyItem;
begin
Result := LastInGroupInternal(Group, False)
end;
function TEasyGroups.LastInGroupInternal(Group: TEasyGroup; VisibleOnly: Boolean): TEasyItem;
var
ItemIndex: Integer;
begin
Result := nil;
if Assigned(Group) then
begin
if Assigned(Group.Items) then
begin
ItemIndex := Group.Items.Count - 1;
if VisibleOnly then
begin
while not Assigned(Result) and (ItemIndex > -1) do
begin
if Group.Items[ItemIndex].Visible then
Result := Group.Items[ItemIndex]
else
Dec(ItemIndex)
end
end else
Result := Group.Items[Group.Items.Count - 1]
end
end
end;
function TEasyGroups.LastInitializedItem: TEasyItem;
begin
Result := LastItemInternal(enitInitialized)
end;
function TEasyGroups.LastItem: TEasyItem;
begin
Result := LastItemInternal(enitAny)
end;
function TEasyGroups.LastItemInternal(NextItemType: TEasyNextItemType): TEasyItem;
var
ItemIndex, GroupIndex: Integer;
begin
Result := nil;
if Count > 0 then
begin
GroupIndex := Count - 1;
while not Assigned(Result) and (GroupIndex > -1) do
begin
if Assigned(Groups[GroupIndex].Items) then
begin
ItemIndex := Groups[GroupIndex].Items.Count - 1;
while not Assigned(Result) and (ItemIndex > -1) do
begin
case NextItemType of
enitVisible:
begin
if Groups[GroupIndex].Items[ItemIndex].Visible then
Result := Groups[GroupIndex].Items[ItemIndex]
else
Dec(ItemIndex)
end;
enitInitialized:
begin
if Groups[GroupIndex].Items[ItemIndex].Visible then
Result := Groups[GroupIndex].Items[ItemIndex]
else
Dec(ItemIndex)
end
else
Result := Groups[GroupIndex].Items[ItemIndex]
end
end
end;
Dec(GroupIndex);
end
end
end;
function TEasyGroups.LastVisibleGroup: TEasyGroup;
begin
Result := LastGroupInternal(True)
end;
function TEasyGroups.LastVisibleInGroup(Group: TEasyGroup): TEasyItem;
begin
Result := LastInGroupInternal(Group, True)
end;
function TEasyGroups.LastVisibleItem: TEasyItem;
begin
Result := LastItemInternal(enitVisible)
end;
function TEasyGroups.MoveDown: Boolean;
var
AItem, ANextItem: TEasyItem;
begin
Result := CanMoveDown;
if not Result then
Exit;
OwnerListview.BeginUpdate;
try
AItem := LastItem;
while Assigned(AItem) do
begin
if AItem.Index < OwnerListview.Items.Count - 1 then
begin
ANextItem := OwnerListview.Items[AItem.Index + 1];
if not ANextItem.Selected then
OwnerListview.Items.Exchange(AItem.Index, ANextItem.Index);
end;
AItem := PrevItem(AItem);
end;
finally
OwnerListview.EndUpdate;
end;
LastItem.MakeVisible(emvAuto);
OwnerListview.DoItemSelectionsChanged;
end;
function TEasyGroups.MoveUp: Boolean;
var
AItem, APrevItem: TEasyItem;
begin
Result := CanMoveUp;
if not Result then
Exit;
OwnerListview.BeginUpdate;
try
AItem := FirstItem;
while Assigned(AItem) do
begin
if AItem.Index > 0 then
begin
APrevItem := OwnerListview.Items[AItem.Index - 1];
if not APrevItem.Selected then
OwnerListview.Items.Exchange(AItem.Index, APrevItem.Index);
end;
AItem := NextItem(AItem);
end;
finally
OwnerListview.EndUpdate;
end;
FirstItem.MakeVisible(emvAuto);
OwnerListview.DoItemSelectionsChanged;
end;
function TEasyGroups.NextEditableItem(Item: TEasyItem): TEasyItem;
begin
Result := NavigateItemInternal(Item, enitEditable, esdForward)
end;
function TEasyGroups.NextGroup(Group: TEasyGroup): TEasyGroup;
begin
Result := NavigateGroupInternal(Group, False, esdForward)
end;
function TEasyGroups.NextGroupInRect(Group: TEasyGroup; ViewportRect: TRect): TEasyGroup;
//
// Find the next Groups in the passed rectangle. It implicitly assumes
// Visible Groups
//
var
i: Integer;
ScratchR: TRect;
Done: Boolean;
begin
Result := nil;
Done := False;
if Assigned(Group) then
begin
i := Group.Index + 1;
while not Assigned(Result) and (i < Count) and not Done do
begin
if Groups[i].Visible then
begin
if IntersectRect(ScratchR, Groups[i].DisplayRect, ViewportRect) then
Result := Groups[i]
else
Done := True
end;
Inc(i)
end
end
end;
function TEasyGroups.NavigateGroupInternal(Group: TEasyGroup;
VisibleOnly: Boolean; Direction: TEasySearchDirection): TEasyGroup;
var
GroupIndex: Integer;
begin
Result := nil;
GroupIndex := Group.Index;
if Direction = esdForward then
Inc(GroupIndex)
else
Dec(GroupIndex);
while not Assigned(Result) and (GroupIndex < Count) and (GroupIndex > -1) do
begin
if VisibleOnly then
begin
if Groups[GroupIndex].Expanded and Groups[GroupIndex].Visible then
Result := Groups[GroupIndex]
else begin
if Direction = esdForward then
Inc(GroupIndex)
else
Dec(GroupIndex);
end
end else
Result := Groups[GroupIndex]
end
end;
function TEasyGroups.NextInitializedItem(Item: TEasyItem): TEasyItem;
begin
Result := NavigateItemInternal(Item, enitInitialized, esdForward)
end;
function TEasyGroups.NextVisibleGroupWithVisibleItems(Group: TEasyGroup): TEasyGroup;
//
// Returns the next Visible Group that has at least one Visible Item
//
var
Done: Boolean;
begin
Result := nil;
if Assigned(Group) then
begin
Done := False;
Result := Group;
while not Done do
begin
Result := NavigateGroupInternal(Result, True, esdForward);
if Assigned(Result) then
Done := Result.VisibleCount > 0
else
Done := True
end
end
end;
function TEasyGroups.NextInGroup(Group: TEasyGroup; Item: TEasyItem): TEasyItem;
begin
Result := NavigateInGroupInternal(Group, Item, False, esdForward)
end;
function TEasyGroups.NavigateInGroupInternal(Group: TEasyGroup; Item: TEasyItem;
VisibleOnly: Boolean; Direction: TEasySearchDirection): TEasyItem;
var
ItemIndex: Integer;
TempItem: TEasyItem;
Count: Integer;
begin
Result := nil;
if Assigned(Group) and Assigned(Item) then
begin
if Assigned(Group.Items) then
begin
ItemIndex := Item.FIndex; // Direct access for speed
if Direction = esdForward then
Inc(ItemIndex)
else
Dec(ItemIndex);
Count := Group.Items.FList.Count;
while not Assigned(Result) and (ItemIndex < Count) and (ItemIndex > -1) do
begin
// Direct Access for speed
TempItem := Group.Items.FList.List[ItemIndex];
if VisibleOnly then
begin
// Direct access for speed
if esosVisible in TempItem.State then
Result := TempItem
else begin
if Direction = esdForward then
Inc(ItemIndex)
else
Dec(ItemIndex)
end
end else
Result := TempItem
end
end
end
end;
function TEasyGroups.NextItem(Item: TEasyItem): TEasyItem;
begin
Result := NavigateItemInternal(Item, enitAny, esdForward)
end;
function TEasyGroups.NextItemInRect(Item: TEasyItem; ViewportRect: TRect): TEasyItem;
//
// Find the next Item in the passed rectangle. It implicitly assumes
// Visible Items
//
var
Group: TEasyGroup;
i: Integer;
R, FullDisplayRect: TRect;
Done: Boolean;
begin
Result := nil;
Done := False;
Group := Item.OwnerGroup;
i := Item.Index + 1;
if OwnerListview.View = elsReport then
begin
while not Assigned(Result) and Assigned(Group) and not Done do
begin
if (i < Group.Items.Count) and Group.Expanded and not Done then
begin
FullDisplayRect := OwnerListview.Header.ViewRect;
FullDisplayRect.Top := Group.Items[i].DisplayRect.Top;
FullDisplayRect.Bottom := Group.Items[i].DisplayRect.Bottom;
if Group.Items[i].Visible then
if IntersectRect(R, FullDisplayRect, ViewportRect) then
Result := Group.Items[i]
else
Done := True
else
Inc(i)
end else
begin
i := 0;
Group := NextGroupInRect(Group, ViewportRect)
end
end
end else
begin
while not Assigned(Result) and Assigned(Group) and not Done do
begin
if (i < Group.Items.Count) and Group.Expanded and not Done then
begin
if Group.Items[i].Visible then
begin
if IntersectRect(R, Group.Items[i].DisplayRect, ViewportRect) then
Result := Group.Items[i]
else begin
if OwnerListview.IsVertView then
Done := Group.Items[i].DisplayRect.Top > ViewportRect.Bottom
else
Done := Group.Items[i].DisplayRect.Left > ViewportRect.Right
end
end;
Inc(i)
end else
begin
i := 0;
Group := NextGroupInRect(Group, ViewportRect)
end
end
end
end;
function TEasyGroups.NavigateItemInternal(Item: TEasyItem; NextItemType: TEasyNextItemType; Direction: TEasySearchDirection): TEasyItem;
var
GroupIndex, ItemIndex, Column: Integer;
Allow: Boolean;
begin
Result := nil;
if Assigned(Item) then
begin
ItemIndex := Item.Index;
GroupIndex := Item.OwnerGroup.Index;
if Direction = esdForward then
Inc(ItemIndex)
else
Dec(ItemIndex);
while not Assigned(Result) and (GroupIndex < Count) and (GroupIndex > -1) do
begin
if Groups[GroupIndex].Expanded and Groups[GroupIndex].Enabled then
begin
while not Assigned(Result) and (ItemIndex < Groups[GroupIndex].Items.Count) and (ItemIndex > -1) do
begin
if NextItemType in [enitVisible, enitEditable] then
begin
if Assigned(Groups[GroupIndex].Items) then
begin
if Groups[GroupIndex].Items[ItemIndex].Visible then
begin
Result := Groups[GroupIndex].Items[ItemIndex];
if NextItemType = enitEditable then
begin
Allow := True;
OwnerListview.DoItemEditBegin(Result, Column, Allow);
if not Allow then
Result := nil;
end
end
end;
if Direction = esdForward then
Inc(ItemIndex)
else
Dec(ItemIndex)
end else
if NextItemType = enitInitialized then
begin
if Assigned(Groups[GroupIndex].Items) then
begin
if Groups[GroupIndex].Items[ItemIndex].Initialized then
Result := Groups[GroupIndex].Items[ItemIndex]
end;
if Direction = esdForward then
Inc(ItemIndex)
else
Dec(ItemIndex)
end else
Result := Groups[GroupIndex].Items[ItemIndex];
end;
if Direction = esdForward then
begin
Inc(GroupIndex);
ItemIndex := 0
end else
begin
Dec(GroupIndex);
if (GroupIndex > -1) and Assigned(Groups[GroupIndex].Items) then
ItemIndex := Groups[GroupIndex].Items.Count - 1;
end
end else
begin
ItemIndex := 0;
if Direction = esdForward then
Inc(GroupIndex)
else
Dec(GroupIndex);
end
end
end
end;
function TEasyGroups.NextVisibleGroup(Group: TEasyGroup): TEasyGroup;
begin
Result := NavigateGroupInternal(Group, True, esdForward)
end;
function TEasyGroups.NextVisibleInGroup(Group: TEasyGroup; Item: TEasyItem): TEasyItem;
begin
Result := NavigateInGroupInternal(Group, Item, True, esdForward)
end;
function TEasyGroups.NextVisibleItem(Item: TEasyItem): TEasyItem;
begin
Result := NavigateItemInternal(Item, enitVisible, esdForward)
end;
function TEasyGroups.PrevEditableItem(Item: TEasyItem): TEasyItem;
begin
Result := NavigateItemInternal(Item, enitEditable, esdBackward)
end;
function TEasyGroups.PrevGroup(Group: TEasyGroup): TEasyGroup;
begin
Result := NavigateGroupInternal(Group, False, esdBackward)
end;
function TEasyGroups.PrevInitializedItem(Item: TEasyItem): TEasyItem;
begin
Result := NavigateItemInternal(Item, enitInitialized, esdBackward)
end;
function TEasyGroups.PrevVisibleGroupWithVisibleItems(Group: TEasyGroup): TEasyGroup;
//
// Returns the prev Visible Group that has at least one Visible Item
//
var
Done: Boolean;
begin
Result := nil;
if Assigned(Group) then
begin
Done := False;
Result := Group;
while not Done do
begin
Result := NavigateGroupInternal(Result, True, esdBackward);
if Assigned(Result) then
Done := Result.VisibleCount > 0
else
Done := True
end
end
end;
function TEasyGroups.PrevInGroup(Group: TEasyGroup; Item: TEasyItem): TEasyItem;
begin
Result := NavigateInGroupInternal(Group, Item, False, esdBackward)
end;
function TEasyGroups.PrevItem(Item: TEasyItem): TEasyItem;
begin
Result := NavigateItemInternal(Item, enitAny, esdBackward)
end;
function TEasyGroups.PrevVisibleGroup(Group: TEasyGroup): TEasyGroup;
begin
Result := NavigateGroupInternal(Group, True, esdBackward)
end;
function TEasyGroups.PrevVisibleInGroup(Group: TEasyGroup; Item: TEasyItem): TEasyItem;
begin
Result := NavigateInGroupInternal(Group, Item, True, esdBackward)
end;
function TEasyGroups.PrevVisibleItem(Item: TEasyItem): TEasyItem;
begin
Result := NavigateItemInternal(Item, enitVisible, esdBackward)
end;
procedure TEasyGroups.Clear(FreeItems: Boolean = True);
begin
if Assigned(OwnerListview.Selection) then
begin
OwnerListview.Selection.IncMultiChangeCount;
OwnerListview.Selection.GroupSelectBeginUpdate;
end;
inherited Clear(FreeItems);
if Assigned(OwnerListview.Selection) then
begin
OwnerListview.Selection.DecMultiChangeCount;
OwnerListview.Selection.GroupSelectEndUpdate;
end;
end;
procedure TEasyGroups.CollapseAll;
var
i: Integer;
begin
OwnerListview.BeginUpdate;
try
for i := 0 to Count - 1 do
Groups[i].Expanded := False
finally
OwnerListview.EndUpdate
end
end;
procedure TEasyGroups.DeleteGroup(Group: TEasyGroup);
var
Done: Boolean;
TestGroup: TEasyGroup;
begin
Done := False;
TestGroup := FirstGroup;
while Assigned(TestGroup) and not Done do
begin
Done := TestGroup = Group;
if Done then
Delete(Group.Index)
else
TestGroup := NextGroup(TestGroup)
end
end;
procedure TEasyGroups.DeleteItem(Item: TEasyItem);
var
Done: Boolean;
TestItem: TEasyItem;
Group: TEasyGroup;
begin
Done := False;
TestItem := FirstItem;
while Assigned(TestItem) and not Done do
begin
Done := TestItem = Item;
if Done then
begin
Group := TestItem.OwnerGroup;
Group.Items.Delete(Item.Index);
end else
TestItem := NextItem(TestItem)
end
end;
procedure TEasyGroups.DeleteItems(ItemArray: TEasyItemArray);
//
// Optimized method of deleting multiple items, the items can be in any group
//
var
i: Integer;
Temp: TEasyItem;
begin
OwnerListview.Selection.IncMultiChangeCount;
OwnerListview.Selection.GroupSelectBeginUpdate;
try
for i := 0 to Length(ItemArray) - 1 do
begin
Temp := ItemArray[i].OwnerGroup.FItems[ItemArray[i].Index];
Temp.Focused := False;
Temp.Selected := False;
Temp.Visible := False;
end;
for i := 0 to Length(ItemArray) - 1 do
begin
Temp := ItemArray[i].OwnerGroup.FItems[ItemArray[i].Index];
ItemArray[i].OwnerGroup.FItems[ItemArray[i].Index] := nil;
Temp.Free;
end;
for i := 0 to Count - 1 do
begin
TEasyGroup( List[i]).FItems.FList.Pack;
TEasyGroup( List[i]).FItems.ReIndexItems
end
finally
OwnerListview.Selection.GroupSelectEndUpdate;
OwnerListview.Selection.DecMultiChangeCount
end
end;
procedure TEasyGroups.DoStructureChange;
begin
inherited DoStructureChange;
Rebuild(False)
end;
procedure TEasyGroups.ExpandAll;
var
i: Integer;
begin
OwnerListview.BeginUpdate;
try
for i := 0 to Count - 1 do
Groups[i].Expanded := True
finally
OwnerListview.EndUpdate
end
end;
procedure TEasyGroups.InitializeAll;
var
i, j: Integer;
begin
for i := 0 to Count - 1 do
begin
if Assigned(Groups[i].Items) then
begin
for j := 0 to Groups[i].Items.Count - 1 do
Groups[i][j].Initialized := True
end
end
end;
procedure TEasyGroups.InvalidateItem(Item: TEasyCollectionItem; ImmediateUpdate: Boolean);
begin
if Assigned(Item) then
Item.Invalidate(ImmediateUpdate)
end;
{$IFDEF COMPILER_6_UP}
{$ELSE}
{$ENDIF COMPILER_6_UP}
procedure TEasyGroups.LoadFromStream(S: TStream; Version: Integer = EASYLISTVIEW_STREAM_VERSION);
begin
inherited LoadFromStream(S, Version);
if StreamGroups then
ReadItems(S);
end;
procedure TEasyGroups.MakeAllVisible;
var
i, j: Integer;
begin
OwnerListview.BeginUpdate;
try
for i := 0 to Count - 1 do
begin
Groups[i].Visible := True;
for j := 0 to Groups[i].ItemCount - 1 do
Groups[i].Item[j].Visible := True
end
finally
OwnerListview.EndUpdate()
end
end;
procedure TEasyGroups.Move(Item: TEasyItem; NewGroup: TEasyGroup);
begin
if Assigned(Item) and Assigned(NewGroup) then
begin
Item.OwnerGroup.Items.Delete(Item.Index);
NewGroup.Items.Add(Item);
Item.FCollection := NewGroup.Items;
DoStructureChange;
end
end;
procedure TEasyGroups.Rebuild(Force: Boolean = False);
var
i, VisibleGroupIndex, VisibleItemIndex: Integer;
ViewRect: TRect;
begin
if ((OwnerListview.UpdateCount = 0) or Force) and not(csLoading in OwnerListview.ComponentState) and (OwnerListview.HandleAllocated) then
begin
Include(FGroupsState, egsRebuilding);
try
VisibleList.Clear;
VisibleList.Capacity := Count;
VisibleGroupIndex := 0;
VisibleItemIndex := 0;
OwnerListview.Header.Rebuild(Force);
SetRect(ViewRect, 0, 0, 0, 0);
for i := 0 to Count - 1 do
begin
if Groups[i].Visible then
begin
VisibleList.Add(Groups[i]);
Groups[i].FVisibleIndex := VisibleGroupIndex;
Inc(VisibleGroupIndex);
end else
Groups[i].FVisibleIndex := -1;
if i > 0 then
Groups[i].Rebuild(Groups[i-1], VisibleItemIndex)
else
Groups[i].Rebuild(nil, VisibleItemIndex);
UnionRect(ViewRect, ViewRect, Groups[i].DisplayRect);
ViewRect.Left := 0;
ViewRect.Top := 0;
Groups[i].Items.ReIndexItems
end;
if OwnerListview.Selection.GroupSelections then
OwnerListview.Selection.BuildSelectionGroupings(False);
OwnerListview.Scrollbars.SetViewRect(ViewRect, True);
finally
Exclude(FGroupsState, egsRebuilding);
end
end
end;
procedure TEasyGroups.SaveToStream(S: TStream; Version: Integer = EASYLISTVIEW_STREAM_VERSION);
begin
inherited SaveToStream(S, Version);
if StreamGroups then
WriteItems(S);
end;
procedure TEasyGroups.SetCellHeight(Value: Integer);
var
i: Integer;
begin
OwnerListview.BeginUpdate;
try
for i := 0 to Count - 1 do
Groups[i].Grid.CellSize.Height := Value
finally
OwnerListview.EndUpdate
end
end;
procedure TEasyGroups.SetCellWidth(Value: Integer);
var
i: Integer;
begin
OwnerListview.BeginUpdate;
try
for i := 0 to Count - 1 do
Groups[i].Grid.CellSize.Width := Value
finally
OwnerListview.EndUpdate
end
end;
procedure TEasyGroups.SetGroup(Index: Integer; Value: TEasyGroup);
begin
inherited Items[Index] := Value
end;
procedure TEasyGroups.UnInitializeAll;
var
i, j: Integer;
begin
for i := 0 to Count - 1 do
begin
if Assigned(Groups[i].Items) then
begin
for j := 0 to Groups[i].Items.Count - 1 do
Groups[i][j].Initialized := False
end
end
end;
{ TEasyColumns }
constructor TEasyColumns.Create(AnOwner: TCustomEasyListview);
begin
inherited;
FItemClass := TEasyColumnStored
end;
destructor TEasyColumns.Destroy;
begin
inherited;
end;
function TEasyColumns.Add(Data: TObject = nil): TEasyColumn;
begin
Result := TEasyColumn( inherited Add(Data));
Result.Color := OwnerListview.Header.Color;
end;
function TEasyColumns.AddCustom(CustomItem: TEasyColumnClass; Data: TObject = nil): TEasyColumn;
begin
Result := nil;
if Assigned(CustomItem) then
begin
Result := CustomItem.Create(Self);
FList.Add(Result);
Result.Color := OwnerListview.Header.Color;
ReIndexItems;
Result.Data := Data;
DoItemAdd(Result, FList.Count - 1);
DoStructureChange
end
end;
function TEasyColumns.AddInterfaced(const DataInf: IUnknown; Data: TObject): TEasyColumnInterfaced;
begin
Result := nil;
if Assigned(DataInf) then
begin
Result := TEasyColumnInterfaced.Create(Self);
FList.Add(Result);
Result.Color := OwnerListview.Header.Color;
ReIndexItems;
Result.DataInf := DataInf;
Result.Data := Data;
DoItemAdd(Result, FList.Count - 1);
DoStructureChange
end
end;
function TEasyColumns.AddVirtual(Data: TObject = nil): TEasyColumnVirtual;
begin
Result := TEasyColumnVirtual.Create(Self);
FList.Add(Result);
Result.Color := OwnerListview.Header.Color;
ReIndexItems;
Result.Data := Data;
DoItemAdd(Result, FList.Count - 1);
DoStructureChange
end;
function TEasyColumns.ColumnByPoint(ViewportPoint: TPoint): TEasyColumn;
var
i: Integer;
begin
Result := nil;
i := 0;
// Careful with a binary search here are the rectangles increase with Header.Postions not the Columns property
while not Assigned(Result) and (i < Count) do
begin
if PtInRect(Columns[i].DisplayRect, ViewportPoint) then
Result := Columns[i]
else
Inc(i)
end
end;
function TEasyColumns.GetColumns(Index: Integer): TEasyColumn;
begin
Result := TEasyColumn( FList.List[Index])
end;
function TEasyColumns.GetOwnerHeader: TEasyHeader;
begin
Result := OwnerListview.Header
end;
function TEasyColumns.Insert(Index: Integer; Data: TObject = nil): TEasyColumn;
begin
Result := TEasyColumn( inherited Insert(Index, Data))
end;
function TEasyColumns.InsertCustom(Index: Integer; CustomColumn: TEasyColumnClass; Data: TObject = nil): TEasyColumn;
begin
Result := nil;
if Assigned(CustomColumn) then
begin
Result := CustomColumn.Create(Self);
FList.Insert(Index, Result);
ReIndexItems;
DoItemAdd(Result, Index);
Result.Data := Data;
DoStructureChange
end
end;
function TEasyColumns.InsertInterfaced(Index: Integer; const DataInf: IUnknown; Data: TObject = nil): TEasyColumnInterfaced;
begin
Result := nil;
if Assigned(DataInf) then
begin
Result := TEasyColumnInterfaced.Create(Self);
FList.Insert(Index, Result);
ReIndexItems;
DoItemAdd(Result, Index);
Result.DataInf := DataInf;
Result.Data := Data;
DoStructureChange
end
end;
function TEasyColumns.InsertVirtual(Index: Integer; Data: TObject = nil): TEasyColumnVirtual;
begin
Result := TEasyColumnVirtual.Create(Self);
FList.Insert(Index, Result);
ReIndexItems;
DoItemAdd(Result, Index);
Result.Data := Data;
DoStructureChange
end;
procedure TEasyColumns.Clear(FreeItems: Boolean = True);
begin
inherited Clear(FreeItems);
if Assigned(OwnerHeader) and Assigned(OwnerHeader.Positions) then
begin
OwnerHeader.Positions.Clear;
OwnerHeader.Columns.VisibleList.Clear;
end
end;
procedure TEasyColumns.DoItemAdd(Item: TEasyCollectionItem; Index: Integer);
begin
inherited DoItemAdd(Item, Index);
end;
procedure TEasyColumns.DoStructureChange;
begin
inherited DoStructureChange;
OwnerListview.Header.Rebuild(False)
end;
procedure TEasyColumns.SetColumns(Index: Integer; Value: TEasyColumn);
begin
inherited Items[Index] := Value
end;
{ TEasyGlobalImageManager }
constructor TEasyGlobalImageManager.Create(AnOwner: TCustomEasyListview);
begin
inherited;
FGroupExpandButton := TBitmap.Create;
FGroupCollapseButton := TBitmap.Create;
FColumnSortUp := TBitmap.Create;
FColumnSortDown := TBitmap.Create;
end;
destructor TEasyGlobalImageManager.Destroy;
begin
inherited;
FreeAndNil(FGroupExpandButton);
FreeAndNil(FGroupCollapseButton);
FreeAndNil(FColumnSortUp);
FreeAndNil(FColumnSortDown);
end;
function TEasyGlobalImageManager.GetColumnSortDown: TBitmap;
begin
if FColumnSortDown.Empty then
begin
MakeTransparent(FColumnSortDown, clFuchsia);
FColumnSortDown.LoadFromResourceName(hInstance, BITMAP_SORTARROWDOWN);
end;
Result := FColumnSortDown
end;
function TEasyGlobalImageManager.GetColumnSortUp: TBitmap;
begin
if FColumnSortUp.Empty then
begin
MakeTransparent(FColumnSortUp, clFuchsia);
FColumnSortUp.LoadFromResourceName(hInstance, BITMAP_SORTARROWUP);
end;
Result := FColumnSortUp
end;
function TEasyGlobalImageManager.GetGroupCollapseImage: TBitmap;
begin
if FGroupCollapseButton.Empty then
begin
MakeTransparent(FGroupCollapseButton, clFuchsia);
FGroupCollapseButton.LoadFromResourceName(hInstance, BITMAP_DEFAULTGROUPCOLLAPSED);
end;
Result := FGroupCollapseButton
end;
function TEasyGlobalImageManager.GetGroupExpandImage: TBitmap;
begin
if FGroupExpandButton.Empty then
begin
MakeTransparent(FGroupExpandButton, clFuchsia);
FGroupExpandButton.LoadFromResourceName(hInstance, BITMAP_DEFAULTGROUPEXPANDED);
end;
Result := FGroupExpandButton
end;
procedure TEasyGlobalImageManager.MakeTransparent(Bits: TBitmap; TransparentColor: TColor);
begin
Bits.Transparent := True;
Bits.TransparentColor := TransparentColor
end;
procedure TEasyGlobalImageManager.SetColumnSortDown(Value: TBitmap);
begin
FColumnSortDown.Assign(Value)
end;
procedure TEasyGlobalImageManager.SetColumnSortUp(Value: TBitmap);
begin
FColumnSortUp.Assign(Value)
end;
procedure TEasyGlobalImageManager.SetGroupCollapseImage(const Value: TBitmap);
begin
FGroupExpandButton.Assign(Value);
end;
procedure TEasyGlobalImageManager.SetGroupExpandImage(const Value: TBitmap);
begin
GroupCollapseButton.Assign(Value);
end;
{ TEasyGroup }
constructor TEasyGroup.Create(ACollection: TEasyCollection);
begin
inherited;
FExpanded := True;
FItems := TEasyItems.Create(OwnerListview, Self);
FVisibleItems := TList.Create;
end;
destructor TEasyGroup.Destroy;
begin
SetDestroyFlags;
if OwnerListview.Selection.FocusedGroup = Self then
OwnerListview.Selection.FocusedGroup := nil;
Selected := False;
Focused := False;
FItems.Free; // don't nil the reference the items may need it as they are destroyed.
inherited;
FreeAndNil(FGrid);
FreeAndNil(FVisibleItems);
FreeAndNil(FView);
end;
function TEasyGroup.BoundsRectBottomMargin: TRect;
begin
if MarginBottom.Visible and OwnerListview.ShowGroupMargins then
begin
Result := DisplayRect;
Result.Top := Result.Bottom - MarginBottom.RuntimeSize;
Result.Right := Result.Right - MarginRight.RuntimeSize;
Result.Left := Result.Left + MarginLeft.RuntimeSize;
end else
Result := Rect(0, 0, 0, 0);
end;
function TEasyGroup.BoundsRectLeftMargin: TRect;
begin
if MarginLeft.Visible and OwnerListview.ShowGroupMargins then
begin
Result := DisplayRect;
Result.Right := Result.Left + MarginLeft.RuntimeSize
end else
Result := Rect(0, 0, 0, 0);
end;
function TEasyGroup.BoundsRectRightMargin: TRect;
begin
if MarginRight.Visible and OwnerListview.ShowGroupMargins then
begin
Result := DisplayRect;
Result.Left := Result.Right - MarginRight.RuntimeSize
end else
Result := Rect(0, 0, 0, 0);
end;
function TEasyGroup.BoundsRectTopMargin: TRect;
begin
if MarginTop.Visible and OwnerListview.ShowGroupMargins then
begin
Result := DisplayRect;
Result.Bottom := Result.Top + MarginTop.RuntimeSize;
Result.Right := Result.Right - MarginRight.RuntimeSize;
Result.Left := Result.Left + MarginLeft.RuntimeSize;
end else
Result := Rect(0, 0, 0, 0);
end;
function TEasyGroup.BoundsRectBkGnd: TRect;
begin
Result := DisplayRect;
Result.Left := Result.Left + MarginLeft.RuntimeSize;
Result.Right := Result.Right - MarginRight.RuntimeSize;
Result.Top := Result.Top + MarginTop.RuntimeSize;
Result.Bottom := Result.Bottom - MarginBottom.RuntimeSize;
if Result.Bottom < Result.Top then
Result.Bottom := Result.Top;
if Result.Right < Result.Left then
Result.Right := Result.Left
end;
function TEasyGroup.CanChangeBold(NewValue: Boolean): Boolean;
begin
Result := True
end;
function TEasyGroup.CanChangeCheck(NewValue: Boolean): Boolean;
begin
Result := Enabled;
end;
function TEasyGroup.CanChangeEnable(NewValue: Boolean): Boolean;
begin
Result := True;
end;
function TEasyGroup.CanChangeFocus(NewValue: Boolean): Boolean;
begin
// Unsupported
Result := False;
end;
function TEasyGroup.CanChangeHotTracking(NewValue: Boolean): Boolean;
begin
// Unsupported
Result := True;
end;
function TEasyGroup.CanChangeSelection(NewValue: Boolean): Boolean;
begin
Result := True;
OwnerListview.DoGroupSelectionChanging(Self, Result)
end;
function TEasyGroup.CanChangeVisibility(NewValue: Boolean): Boolean;
begin
Result := True;
OwnerListview.DoGroupVisibilityChanging(Self, Result)
end;
function TEasyGroup.DefaultImageList(ImageSize: TEasyImageSize): TCustomImageList;
begin
Result:= OwnerListview.ImagesGroup
end;
function TEasyGroup.EditAreaHitPt(ViewportPoint: TPoint): Boolean;
begin
Result := View.EditAreaHitPt(Self, ViewportPoint)
end;
function TEasyGroup.GetBandBlended: Boolean;
begin
Result := PaintInfo.BandBlended
end;
function TEasyGroup.GetBandColor: TColor;
begin
Result := PaintInfo.BandColor
end;
function TEasyGroup.GetBandColorFade: TColor;
begin
Result := PaintInfo.BandColorFade
end;
function TEasyGroup.GetBandEnabled: Boolean;
begin
Result := PaintInfo.BandEnabled
end;
function TEasyGroup.GetBandFullWidth: Boolean;
begin
Result := PaintInfo.BandFullWidth
end;
function TEasyGroup.GetBandIndent: Integer;
begin
Result := PaintInfo.BandIndent
end;
function TEasyGroup.GetBandLength: Integer;
begin
Result := PaintInfo.BandLength
end;
function TEasyGroup.GetBandMargin: Integer;
begin
Result := PaintInfo.BandMargin
end;
function TEasyGroup.GetBandRadius: Byte;
begin
Result := PaintInfo.BandRadius
end;
function TEasyGroup.GetBandThickness: Integer;
begin
Result := PaintInfo.BandThickness
end;
function TEasyGroup.GetClientRect: TRect;
begin
Result := Rect( FDisplayRect.Left + MarginLeft.RuntimeSize,
FDisplayRect.Top + MarginTop.RuntimeSize,
FDisplayRect.Right - MarginRight.RuntimeSize,
FDisplayRect.Bottom - MarginBottom.RuntimeSize)
end;
function TEasyGroup.GetDefaultGridClass: TEasyGridGroupClass;
begin
Result := nil;
case OwnerListview.View of
elsIcon: Result := TEasyGridIconGroup;
elsSmallIcon: Result := TEasyGridSmallIconGroup;
elsList: Result := TEasyGridListGroup;
elsReport: Result := TEasyGridReportGroup;
elsThumbnail: Result := TEasyGridThumbnailGroup;
elsTile: Result := TEasyGridTileGroup;
elsFilmStrip: Result := TEasyGridFilmStripGroup;
elsGrid: Result := TEasyGridGridGroup;
end
end;
function TEasyGroup.GetDefaultViewClass: TEasyViewGroupClass;
begin
Result := TEasyViewGroup
end;
function TEasyGroup.GetExpandable: Boolean;
begin
Result := PaintInfo.Expandable
end;
function TEasyGroup.GetExpandImageIndent: Integer;
begin
Result := PaintInfo.ExpandImageIndent
end;
function TEasyGroup.GetGrid: TEasyGridGroup;
begin
if Assigned(FGrid) then
begin
if FGrid.ClassType <> GridClass then
FreeAndNil(FGrid);
end;
if not Assigned(FGrid) then
begin
FGrid := GridClass.Create(OwnerListview, Self);
case OwnerListview.View of
elsIcon: FGrid.CellSize.Assign(OwnerListview.CellSizes.Icon);
elsSmallIcon: FGrid.CellSize.Assign(OwnerListview.CellSizes.SmallIcon);
elsList: FGrid.CellSize.Assign(OwnerListview.CellSizes.List);
elsReport: FGrid.CellSize.Assign(OwnerListview.CellSizes.Report);
elsThumbnail: FGrid.CellSize.Assign(OwnerListview.CellSizes.Thumbnail);
elsTile: FGrid.CellSize.Assign(OwnerListview.CellSizes.Tile);
elsFilmStrip: FGrid.CellSize.Assign(OwnerListview.CellSizes.FilmStrip);
elsGrid: FGrid.CellSize.Assign(OwnerListview.CellSizes.Grid);
end
end;
Result := FGrid;
end;
function TEasyGroup.GetGridClass: TEasyGridGroupClass;
begin
Result := nil;
OwnerListview.DoCustomGrid(Self, OwnerListview.View, Result);
if not Assigned(Result) then
Result := GetDefaultGridClass
end;
function TEasyGroup.GetItem(Index: Integer): TEasyItem;
begin
Result := Items[Index]
end;
function TEasyGroup.GetItemCount: Integer;
begin
Result := Items.Count
end;
function TEasyGroup.GetMarginBottom: TEasyFooterMargin;
begin
Result := PaintInfo.MarginBottom as TEasyFooterMargin
end;
function TEasyGroup.GetMarginLeft: TEasyMargin;
begin
Result := PaintInfo.MarginLeft
end;
function TEasyGroup.GetMarginRight: TEasyMargin;
begin
Result := PaintInfo.MarginRight
end;
function TEasyGroup.GetMarginTop: TEasyHeaderMargin;
begin
Result := PaintInfo.MarginTop
end;
function TEasyGroup.GetOwnerGroups: TEasyGroups;
begin
Result := TEasyGroups( Collection)
end;
function TEasyGroup.GetOwnerListview: TCustomEasyListview;
begin
Result := TEasyGroups( Collection).OwnerListview
end;
function TEasyGroup.GetPaintInfo: TEasyPaintInfoBaseGroup;
begin
Result := inherited PaintInfo as TEasyPaintInfoBaseGroup
end;
function TEasyGroup.GetView: TEasyViewGroup;
begin
if Assigned(FView) then
begin
if FView.ClassType <> ViewClass then
FreeAndNil(FView)
end;
if not Assigned(FView) then
FView := ViewClass.Create(Self);
Result := FView
end;
function TEasyGroup.GetViewClass: TEasyViewGroupClass;
begin
Result := nil;
if Assigned(OwnerListview) then
OwnerListview.DoGroupCustomView(Self, OwnerListview.View, Result);
if not Assigned(Result) then
Result := GetDefaultViewClass
end;
function TEasyGroup.GetVisibleCount: Integer;
begin
Result := FVisibleItems.Count
end;
function TEasyGroup.GetVisibleItem(Index: Integer): TEasyItem;
begin
Result := nil;
if (Index > -1) and (Index < VisibleItems.Count) then
Result := TEasyItem( VisibleItems[Index])
end;
function TEasyGroup.HitTestAt(ViewportPoint: TPoint;
var HitInfo: TEasyGroupHitTestInfoSet): Boolean;
///
// Returns information about what, if anything, was hit at the passed point in
// the group. Returns true if anything was hit.
//
var
RectArray: TEasyRectArrayObject;
R: TRect;
begin
HitInfo := [];
// First need to see what Frame of the group was hit, and then the individual
// rectangle for each element in the Frame is retrieved
if PtInRect(BoundsRectTopMargin, ViewportPoint) then
begin
Include(HitInfo, egtOnHeader);
View.GroupRectArray(Self, egmeTop, BoundsRectTopMargin, RectArray);
end else
if PtInRect(BoundsRectBottomMargin, ViewportPoint) then
begin
Include(HitInfo, egtOnFooter);
View.GroupRectArray(Self, egmeBottom, BoundsRectBottomMargin, RectArray);
end else
if PtInRect(BoundsRectLeftMargin, ViewportPoint) then
begin
Include(HitInfo, egtOnLeftMargin);
View.GroupRectArray(Self, egmeLeft, BoundsRectLeftMargin, RectArray);
end else
if PtInRect(BoundsRectRightMargin, ViewportPoint) then
begin
Include(HitInfo, egtOnRightMargin);
View.GroupRectArray(Self, egmeRight, BoundsRectRightMargin, RectArray);
end;
if HitInfo <> [] then
begin
R := RectArray.IconRect;
// Make the blank area between the image and text part of the image
R.Right := R.Right + OwnerListview.PaintInfoGroup.CaptionIndent;
if PtInRect(R, ViewportPoint) then
Include(HitInfo, egtOnIcon)
else
if PtInRect(RectArray.TextRect, ViewportPoint) then
Include(HitInfo, egtOnText)
else
if PtInRect(RectArray.LabelRect, ViewportPoint) then
Include(HitInfo, egtOnLabel)
else
if PtInRect(RectArray.ExpandButtonRect, ViewportPoint) then
Include(HitInfo, egtOnExpandButton)
else
if PtInRect(RectArray.BandRect, ViewportPoint) then
Include(HitInfo, egtOnBand)
else
if PtInRect(RectArray.CheckRect, ViewportPoint) then
Include(HitInfo, egtOnCheckbox);
end;
Result := HitInfo <> []
end;
function TEasyGroup.ItemByPoint(ViewportPoint: TPoint): TEasyItem;
var
i: Integer;
begin
Result := nil;
i := 0;
while not Assigned(Result) and (i < Items.Count) do
begin
if PtInRect(Items[i].DisplayRect, ViewportPoint) then
Result := Items[i];
Inc(i)
end;
end;
function TEasyGroup.LocalPaintInfo: TEasyPaintInfoBasic;
begin
Result := OwnerListview.PaintInfoGroup
end;
function TEasyGroup.SelectionHit(SelectViewportRect: TRect;
SelectType: TEasySelectHitType): Boolean;
begin
Result := View.SelectionHit(Self, SelectViewPortRect, SelectType)
end;
function TEasyGroup.SelectionHitPt(ViewportPoint: TPoint;
SelectType: TEasySelectHitType): Boolean;
begin
Result := View.SelectionHitPt(Self, ViewportPoint, SelectType)
end;
procedure TEasyGroup.Freeing;
begin
OwnerListview.DoGroupFreeing(Self)
end;
procedure TEasyGroup.GainingBold;
begin
Invalidate(False)
end;
procedure TEasyGroup.GainingCheck;
var
i: Integer;
begin
for i := 0 to Items.Count - 1 do
if Items[i].Visible then
Items[i].Checked := True;
if Visible then
Include(FState, esosChecked);
Invalidate(False)
end;
procedure TEasyGroup.GainingEnable;
var
i: Integer;
begin
for i := 0 to Items.Count - 1 do
Items[i].Enabled := True;
Include(FState, esosEnabled);
Invalidate(False)
end;
procedure TEasyGroup.GainingFocus;
begin
// Unsupported
end;
procedure TEasyGroup.GainingGhosted;
begin
Invalidate(False)
end;
procedure TEasyGroup.GainingHilight;
begin
// Unsupported
end;
procedure TEasyGroup.GainingHotTracking(MousePos: TPoint);
begin
OwnerListview.DoGroupHotTrack(Self, ehsEnable, MousePos);
Invalidate(True)
end;
procedure TEasyGroup.GainingSelection;
begin
OwnerListview.DoGroupSelectionChanged(Self)
end;
procedure TEasyGroup.GainingVisibility;
var
i: Integer;
begin
OwnerListview.DoGroupVisibilityChanged(Self);
for i := 0 to Items.Count - 1 do
Items[i].Visible := True
end;
procedure TEasyGroup.Initialize;
begin
OwnerListview.DoGroupInitialize(Self)
end;
procedure TEasyGroup.LoadFromStream(S: TStream; var Version: Integer);
begin
inherited LoadFromStream(S, Version);
if not Assigned(Items) then
Items := TEasyItems.Create(OwnerListview, Self)
else
Items.Clear;
Items.ReadItems(S);
OwnerListview.DoGroupLoadFromStream(Self, S, Version);
// For new objects test the stream version first
// if Version > X then
// begin
// ReadStream....
// end
end;
procedure TEasyGroup.LosingBold;
begin
Invalidate(False)
end;
procedure TEasyGroup.LosingCheck;
var
i: Integer;
begin
for i := 0 to Items.Count - 1 do
Items[i].Checked := False;
Exclude(FState, esosChecked);
Invalidate(False)
end;
procedure TEasyGroup.LosingEnable;
var
i: Integer;
begin
for i := 0 to Items.Count - 1 do
Items[i].Enabled := False;
Exclude(FState, esosEnabled);
Invalidate(False)
end;
procedure TEasyGroup.LosingFocus;
begin
// Unsupported
end;
procedure TEasyGroup.LosingGhosted;
begin
Invalidate(False)
end;
procedure TEasyGroup.LosingHilight;
begin
// Unsupported
end;
procedure TEasyGroup.LosingHotTracking;
begin
OwnerListview.DoGroupHotTrack(Self, ehsDisable, Point(0, 0));
Invalidate(True)
end;
procedure TEasyGroup.LosingSelection;
begin
OwnerListview.DoGroupSelectionChanged(Self)
end;
procedure TEasyGroup.LosingVisibility;
var
i: Integer;
begin
for i := 0 to Items.Count - 1 do
Items[i].Visible := False;
OwnerListview.DoGroupVisibilityChanged(Self);
end;
procedure TEasyGroup.Paint(MarginEdge: TEasyGroupMarginEdge; ObjRect: TRect; ACanvas: TCanvas);
begin
View.Paint(Self, MarginEdge, ObjRect, ACanvas)
end;
procedure TEasyGroup.Rebuild(PrevGroup: TEasyGroup; var NextVisibleItemIndex: Integer);
begin
if Assigned(Grid) then
Grid.Rebuild(PrevGroup, NextVisibleItemIndex)
end;
procedure TEasyGroup.SaveToStream(S: TStream; Version: Integer = EASYLISTVIEW_STREAM_VERSION);
begin
inherited SaveToStream(S);
Items.WriteItems(S);
OwnerListview.DoGroupSaveToStream(Self, S, Version);
// For new objects test the stream version first
// if Version > X then
// begin
// WriteStream....
// end
end;
procedure TEasyGroup.SetBandBlended(Value: Boolean);
begin
if Value <> BandBlended then
begin
PaintInfo.BandBlended := Value;
Invalidate(False)
end
end;
procedure TEasyGroup.SetBandColor(Value: TColor);
begin
if Value <> BandColor then
begin
PaintInfo.BandColor := Value;
Invalidate(False)
end
end;
procedure TEasyGroup.SetBandColorFade(Value: TColor);
begin
if Value <> BandColorFade then
begin
PaintInfo.BandColorFade := Value;
Invalidate(False)
end
end;
procedure TEasyGroup.SetBandEnabled(Value: Boolean);
begin
if Value <> BandEnabled then
begin
PaintInfo.BandEnabled := Value;
Invalidate(False)
end
end;
procedure TEasyGroup.SetBandFullWidth(Value: Boolean);
begin
if Value <> BandFullWidth then
begin
PaintInfo.BandFullWidth := Value;
Invalidate(False)
end
end;
procedure TEasyGroup.SetBandIndent(Value: Integer);
begin
if Value <> BandIndent then
begin
PaintInfo.BandIndent := Value;
Invalidate(False)
end
end;
procedure TEasyGroup.SetBandLength(Value: Integer);
begin
if Value <> BandLength then
begin
PaintInfo.BandLength := Value;
Invalidate(False)
end
end;
procedure TEasyGroup.SetBandMargin(Value: Integer);
begin
if Value <> BandMargin then
begin
PaintInfo.BandMargin := Value;
Invalidate(False)
end
end;
procedure TEasyGroup.SetBandRadius(Value: Byte);
begin
if Value <> BandRadius then
begin
PaintInfo.BandRadius:= Value;
Invalidate(False)
end
end;
procedure TEasyGroup.SetBandThickness(Value: Integer);
begin
if Value <> BandThickness then
begin
PaintInfo.BandThickness := Value;
Invalidate(False)
end
end;
procedure TEasyGroup.SetExpandable(Value: Boolean);
begin
if Value <> Expandable then
begin
PaintInfo.Expandable := Value;
Invalidate(False)
end
end;
procedure TEasyGroup.SetExpanded(Value: Boolean);
begin
if Value <> FExpanded then
begin
OwnerListview.BeginUpdate;
try
FExpanded := Value;
if Value then
OwnerListview.DoGroupExpand(Self)
else
OwnerListview.DoGroupCollapse(Self);
OwnerListview.Groups.Rebuild(True);
finally
OwnerListview.EndUpdate;
end
end
end;
procedure TEasyGroup.SetExpandImageIndent(Value: Integer);
begin
if Value <> ExpandImageIndent then
begin
PaintInfo.ExpandImageIndent := Value;
Invalidate(False)
end
end;
procedure TEasyGroup.SetItem(Index: Integer; Value: TEasyItem);
begin
if (Index > -1) and (Index < Items.Count) then
Items[Index] := Value
end;
procedure TEasyGroup.SetMarginBottom(Value: TEasyFooterMargin);
begin
if Value <> MarginBottom then
begin
PaintInfo.MarginBottom := Value;
Invalidate(False)
end
end;
procedure TEasyGroup.SetMarginLeft(Value: TEasyMargin);
begin
if Value <> MarginLeft then
begin
PaintInfo.MarginLeft := Value;
Invalidate(False)
end
end;
procedure TEasyGroup.SetMarginRight(Value: TEasyMargin);
begin
if Value <> MarginRight then
begin
PaintInfo.MarginRight := Value;
Invalidate(False)
end
end;
procedure TEasyGroup.SetMarginTop(Value: TEasyHeaderMargin);
begin
if Value <> MarginTop then
begin
PaintInfo.MarginTop := Value;
Invalidate(False)
end
end;
procedure TEasyGroup.SetPaintInfo(const Value: TEasyPaintInfoBaseGroup);
begin
inherited PaintInfo := Value
end;
function TEasyViewGroup.CustomExpandImages: Boolean;
begin
Result := not OwnerListview.GroupCollapseButton.Empty or not OwnerListview.GroupExpandButton.Empty
end;
function TEasyViewGroup.EditAreaHitPt(Group: TEasyGroup; ViewportPoint: TPoint): Boolean;
begin
Result := False
end;
function TEasyViewGroup.GetImageList(Group: TEasyGroup): TCustomImageList;
begin
Result := Group.ImageList[-1, eisSmall]
end;
function TEasyViewGroup.SelectionHit(Group: TEasyGroup;
SelectViewportRect: TRect; SelectType: TEasySelectHitType): Boolean;
begin
Result := False
end;
function TEasyViewGroup.SelectionHitPt(Group: TEasyGroup; ViewportPoint: TPoint;
SelectType: TEasySelectHitType): Boolean;
begin
Result := False
end;
{ TEasyGroupView }
procedure TEasyViewGroup.GetCollapseExpandImages(var Expand, Collapse: TBitmap);
begin
Expand := nil;
Collapse := nil;
if not OwnerListview.GroupCollapseButton.Empty then
Collapse := OwnerListview.GroupCollapseButton
else
Collapse := OwnerListview.GlobalImages.GroupCollapseButton;
if not OwnerListview.GroupExpandButton.Empty then
Expand := OwnerListview.GroupExpandButton
else
Expand := OwnerListview.GlobalImages.GroupExpandButton;
end;
procedure TEasyViewGroup.GetExpandImageSize(Group: TEasyGroup; var ImageW, ImageH: Integer);
var
ExpandImage, CollapseImage: TBitmap;
begin
ImageW := 0;
ImageH := 0;
GetCollapseExpandImages(ExpandImage, CollapseImage);
if Assigned(ExpandImage) and Assigned(CollapseImage) then
begin
ImageW := ExpandImage.Width;
ImageH := ExpandImage.Height;
if CollapseImage.Width > ImageW then
ImageW := CollapseImage.Width;
if CollapseImage.Height > ImageH then
ImageH := CollapseImage.Height
end
end;
procedure TEasyViewGroup.GetImageSize(Group: TEasyGroup; var ImageW, ImageH: Integer);
var
Images: TCustomImageList;
IsCustom: Boolean;
begin
ImageW := 0;
ImageH := 0;
Group.ImageDrawIsCustom(nil, IsCustom);
if IsCustom then
Group.ImageDrawGetSize(nil, ImageW, ImageH)
else begin
Images := GetImageList(Group);
if (Group.ImageIndexes[0] > -1) and Assigned(Images) then
begin
ImageW := Images.Width;
ImageH := Images.Height
end
end;
end;
procedure TEasyViewGroup.GroupRectArray(Group: TEasyGroup; MarginEdge: TEasyGroupMarginEdge;
ObjRect: TRect; var RectArray: TEasyRectArrayObject);
//
// Grabs all the rectangles for the items within a cell in one call
// If PaintInfo is nil then the information is fetched automaticlly
//
var
TextSize: TSize;
HeaderBand, FooterBand: TRect;
TempRectArray: TEasyRectArrayObject;
ImageW, ImageH, ExpandImageW, ExpandImageH, BandOffset: Integer;
begin
Group.Initialized := True;
FillChar(RectArray, SizeOf(RectArray), #0);
RectArray.GroupRect := ObjRect;
RectArray.BackGndRect := Group.BoundsRectBkGnd;
GetImageSize(Group, ImageW, ImageH);
GetExpandImageSize(Group, ExpandImageW, ExpandImageH);
ExpandImageW := Round( ExpandImageW + GetDeviceCaps(OwnerListview.Canvas.Handle, LOGPIXELSX)/96);
if MarginEdge in [egmeTop, egmeBottom] then
begin
if Group.BandEnabled then
BandOffset := Group.BandThickness + 2 * Group.BandMargin
else
BandOffset := 0;
// Calculate the Expansion button first for the Header only
if Group.Expandable and (MarginEdge = egmeTop) then
RectArray.ExpandButtonRect := Rect(RectArray.GroupRect.Left + Group.ExpandImageIndent,
RectArray.GroupRect.Top,
RectArray.GroupRect.Left + ExpandImageW + Group.ExpandImageIndent,
RectArray.GroupRect.Bottom - BandOffset)
else // Make the ExpandButton R a width of 0
RectArray.ExpandButtonRect := Rect(RectArray.GroupRect.Left,
RectArray.GroupRect.Top,
RectArray.GroupRect.Left,
RectArray.GroupRect.Bottom - BandOffset);
if (Group.CheckType <> ectNone) and (MarginEdge in [egmeTop]) then
begin
RectArray.CheckRect := Checks.Bound[Group.CheckSize];
case Group.VAlignment of
cvaTop: OffsetRect(RectArray.CheckRect, RectArray.ExpandButtonRect.Right + Group.CheckIndent, ObjRect.Top + 2);
cvaBottom: OffsetRect(RectArray.CheckRect, RectArray.ExpandButtonRect.Right + Group.CheckIndent, ObjRect.Bottom - BandOffset - RectHeight(RectArray.CheckRect) - 2);
cvaCenter: OffsetRect(RectArray.CheckRect, RectArray.ExpandButtonRect.Right + Group.CheckIndent,
(ObjRect.Top + ((RectHeight(ObjRect) - BandOffset) - RectHeight(RectArray.CheckRect)) div 2));
end
end else
begin
// CheckRect is a 0 width
RectArray.CheckRect := ObjRect;
RectArray.CheckRect.Left := RectArray.ExpandButtonRect.Right;
RectArray.CheckRect.Right := RectArray.ExpandButtonRect.Right;
end;
// Now Calculate the image for the header or the footer
if Group.ImageIndex > -1 then
RectArray.IconRect := Rect(RectArray.CheckRect.Right + Group.ImageIndent,
RectArray.GroupRect.Top,
RectArray.CheckRect.Right + ImageW + Group.ImageIndent,
RectArray.GroupRect.Bottom - BandOffset)
else // Make the IconR a width of 0
RectArray.IconRect := Rect(RectArray.CheckRect.Right,
RectArray.CheckRect.Top,
RectArray.CheckRect.Right,
RectArray.CheckRect.Bottom - BandOffset);
// Now the Label rect may be calculated for the header or footer
RectArray.LabelRect := Rect(RectArray.IconRect.Right + Group.CaptionIndent,
RectArray.ExpandButtonRect.Top,
RectArray.GroupRect.Right,
RectArray.ExpandButtonRect.Bottom);
// Calculate the text size for the text based on the above font
if Assigned(OwnerListview.ScratchCanvas) then
begin
LoadTextFont(Group, OwnerListview.ScratchCanvas);
TextSize := TextExtentW(Group.Caption, OwnerListview.ScratchCanvas.Font);
end else
begin
TextSize.cx := 0;
TextSize.cy := 0;
end;
// Use the calculated label rectangle to position where the text goes
RectArray.TextRect := Rect(RectArray.LabelRect.Left,
RectArray.LabelRect.Top,
RectArray.LabelRect.Left + TextSize.cx,
RectArray.LabelRect.Top + TextSize.cy);
if RectArray.TextRect.Right > RectArray.LabelRect.Right then
RectArray.TextRect.Right := RectArray.LabelRect.Right;
if RectArray.TextRect.Bottom > RectArray.LabelRect.Bottom then
RectArray.TextRect.Bottom := RectArray.LabelRect.Bottom;
case Group.Alignment of
taLeftJustify: OffsetRect(RectArray.TextRect, 0, 0);
taRightJustify: OffsetRect(RectArray.TextRect, RectWidth(RectArray.LabelRect) - (RectWidth(RectArray.TextRect)), 0);
taCenter: OffsetRect(RectArray.TextRect, (RectWidth(RectArray.LabelRect) - RectWidth(RectArray.TextRect)) div 2, 0);
end;
case Group.VAlignment of
cvaBottom: OffsetRect(RectArray.TextRect, 0, RectHeight(RectArray.GroupRect) - (RectHeight(RectArray.TextRect) + BandOffset));
cvaCenter: OffsetRect(RectArray.TextRect, 0, ((RectHeight(RectArray.GroupRect) - BandOffset) - RectHeight(RectArray.TextRect)) div 2);
end;
if Group.BandEnabled then
begin
if Group.BandFullWidth then
RectArray.BandRect := Rect(RectArray.GroupRect.Left,
RectArray.GroupRect.Bottom - Group.BandMargin - Group.BandThickness,
RectArray.GroupRect.Right,
RectArray.GroupRect.Bottom - Group.BandMargin)
else
RectArray.BandRect := Rect(RectArray.GroupRect.Left,
RectArray.GroupRect.Bottom - 2 * Group.BandMargin - Group.BandThickness,
RectArray.GroupRect.Left + Group.BandLength,
RectArray.GroupRect.Bottom - Group.BandMargin);
OffsetRect(RectArray.BandRect, Group.BandIndent, 0);
end;
end else
begin // Calculate the margin rectangles
// Need to send nil so the user attributes are fetched for the header
GroupRectArray(Group, egmeTop, Group.BoundsRectTopMargin, TempRectArray);
HeaderBand := TempRectArray.BandRect;
// Need to send nil so the user attributes are fetched for the footer
GroupRectArray(Group, egmeBottom, Group.BoundsRectBottomMargin, TempRectArray);
FooterBand := TempRectArray.BandRect;
if MarginEdge = egmeLeft then
RectArray.BandRect := Rect(RectArray.GroupRect.Left + (RectWidth(RectArray.GroupRect) - Group.BandThickness) div 2,
HeaderBand.Top,
RectArray.GroupRect.Right,
FooterBand.Bottom - 1);
if MarginEdge = egmeRight then
RectArray.BandRect := Rect(RectArray.GroupRect.Left,
HeaderBand.Top,
RectArray.GroupRect.Right - (RectWidth(RectArray.GroupRect) - Group.BandThickness) div 2,
FooterBand.Bottom - 1)
end;
end;
procedure TEasyViewGroup.LoadTextFont(Group: TEasyGroup; ACanvas: TCanvas);
begin
if Assigned(ACanvas) then
begin
ACanvas.Font.Assign(OwnerListview.GroupFont);
ACanvas.Brush.Style := bsClear;
if Group.Focused then
begin
if OwnerListview.Focused then
ACanvas.Font.Color := clHighlightText;
end;
if Group.Bold then
ACanvas.Font.Style := ACanvas.Font.Style + [fsBold];
OwnerListview.DoGroupPaintText(Group, ACanvas);
end
end;
procedure TEasyViewGroup.Paint(Group: TEasyGroup; MarginEdge: TEasyGroupMarginEdge; ObjRect: TRect; ACanvas: TCanvas);
//
// Calls the sub Paint methods to do a complete Paint cycle for the Group
//
var
RectArray: TEasyRectArrayObject;
begin
if not IsRectEmpty(ObjRect) then
begin
CanvasStore.StoreCanvasState(ACanvas);
try
GroupRectArray(Group, MarginEdge, ObjRect, RectArray);
PaintBefore(Group, ACanvas, MarginEdge, ObjRect, RectArray);
PaintBackground(Group, ACanvas, MarginEdge, ObjRect, RectArray);
if MarginEdge = egmeTop then
PaintCheckBox(Group, ACanvas, RectArray);
PaintSelectionRect(Group, ACanvas, ObjRect, RectArray);
PaintFocusRect(Group, ACanvas, MarginEdge, ObjRect, RectArray);
PaintText(Group, MarginEdge, ACanvas, ObjRect, RectArray);
PaintBand(Group, ACanvas, MarginEdge, ObjRect, RectArray);
PaintExpandButton(Group, ACanvas, MarginEdge, ObjRect, RectArray);
PaintImage(Group, ACanvas, MarginEdge, ObjRect, RectArray);
PaintAfter(Group, ACanvas, MarginEdge, ObjRect, RectArray);
finally
CanvasStore.RestoreCanvasState(ACanvas)
end
end
end;
procedure TEasyViewGroup.PaintAfter(Group: TEasyGroup; ACanvas: TCanvas;
MarginEdge: TEasyGroupMarginEdge; ObjRect: TRect; RectArray: TEasyRectArrayObject);
begin
end;
procedure TEasyViewGroup.PaintBackground(Group: TEasyGroup; ACanvas: TCanvas;
MarginEdge: TEasyGroupMarginEdge;ObjRect: TRect; RectArray: TEasyRectArrayObject);
begin
end;
procedure TEasyViewGroup.PaintBand(Group: TEasyGroup; ACanvas: TCanvas;
MarginEdge: TEasyGroupMarginEdge; ObjRect: TRect; RectArray: TEasyRectArrayObject);
//
// Paints the banding in none, one, ..., all margins of the Group
var
i: Integer;
Red1, Red2, Green1, Green2, Blue1, Blue2, RC, GC, BC, BandTop: Integer;
RStep, GStep, BStep : Double;
RGBVal, BlendStop: Longword;
CellR: TRect;
begin
if Group.BandEnabled and not IsRectEmpty(RectArray.BandRect) then
begin
CellR := ObjRect;
if MarginEdge in [egmeBottom, egmeTop] then
begin
BandTop := RectArray.BandRect.Top + Group.BandMargin;
// Draw the Banding
if Group.BandBlended then
begin
if (Group.BandLength > 0) then
begin
// Calulate the stepping to create the blended banding
RGBVal := ColorToRGB(Group.BandColor);
Red1 := GetRValue(RGBVal);
Green1 := GetGValue(RGBVal);
Blue1 := GetBValue(RGBVal);
RGBVal := ColorToRGB(Group.BandColorFade);
Red2 := GetRValue(RGBVal);
Green2 := GetGValue(RGBVal);
Blue2 := GetBValue(RGBVal);
if Group.BandFullWidth then
BlendStop := RectWidth(CellR)
else
BlendStop := Group.BandLength;
RStep := (Red2-Red1)/BlendStop;
GStep := (Green2-Green1)/BlendStop;
BStep := (Blue2-Blue1)/BlendStop;
ACanvas.Pen.Color := Group.BandColor;
// Draw the Banding
for i := 0 to BlendStop do
begin
if Group.BandFullWidth then
begin
ACanvas.MoveTo(CellR.Left + i, BandTop);
ACanvas.LineTo(CellR.Left + i, BandTop + Group.BandThickness);
end else
begin
ACanvas.MoveTo(RectArray.BandRect.Left + i, BandTop);
ACanvas.LineTo(RectArray.BandRect.Left + i, BandTop + Group.BandThickness);
end;
RC:=Round(Red1 + i*RStep);
GC:=Round(Green1 +i*GStep);
BC:=Round(Blue1 + i*BStep);
ACanvas.Pen.Color := RGB(RC, GC, BC);
end
end
end else
begin
ACanvas.Pen.Color := Group.BandColor;
if Group.BandFullWidth then
begin
for i := 0 to Group.BandThickness - 1 do
begin
ACanvas.MoveTo(CellR.Left, BandTop + i);
ACanvas.LineTo(CellR.Right, BandTop + i);
end
end else
begin
for i := 0 to Group.BandThickness - 1 do
begin
ACanvas.MoveTo(RectArray.BandRect.Left, BandTop + i);
ACanvas.LineTo(RectArray.BandRect.Left + Group.BandLength, BandTop + i);
end
end
end
end else
begin
if (MarginEdge in [egmeRight]) and Group.BandBlended then
ACanvas.Pen.Color := Group.BandColorFade
else
ACanvas.Pen.Color := Group.BandColor;
if MarginEdge = egmeLeft then
begin
// Draw the horizontal stubs on the top and bottom
for i := 0 to Group.BandThickness - 1 do
begin
ACanvas.MoveTo(RectArray.BandRect.Left + Group.BandRadius, RectArray.BandRect.Top + i);
ACanvas.LineTo(RectArray.BandRect.Right + 1, RectArray.BandRect.Top + i)
end;
for i := 0 to Group.BandThickness - 1 do
begin
ACanvas.MoveTo(RectArray.BandRect.Left + Group.BandRadius, RectArray.BandRect.Bottom - i);
ACanvas.LineTo(RectArray.BandRect.Right + 1, RectArray.BandRect.Bottom - i)
end;
for i := 0 to Group.BandThickness - 1 do
begin
ACanvas.MoveTo(RectArray.BandRect.Left + i, RectArray.BandRect.Top + Group.BandRadius);
ACanvas.LineTo(RectArray.BandRect.Left + i, RectArray.BandRect.Bottom - Group.BandRadius + 1)
end;
for i := 0 to Group.BandThickness - 1 do
begin
ACanvas.MoveTo(RectArray.BandRect.Left + Group.BandRadius, RectArray.BandRect.Top);
AngleArc(ACanvas.Handle,
RectArray.BandRect.Left + Group.BandRadius,
RectArray.BandRect.Top + Group.BandRadius,
Group.BandRadius - i,
90,
90);
ACanvas.MoveTo(RectArray.BandRect.Left, RectArray.BandRect.Bottom - Group.BandRadius);
AngleArc(ACanvas.Handle,
RectArray.BandRect.Left + Group.BandRadius,
RectArray.BandRect.Bottom - Group.BandRadius,
Group.BandRadius - i,
180,
90);
end
end else
begin
// Draw the horizontal stubs on the top and bottom
for i := 0 to Group.BandThickness - 1 do
begin
ACanvas.MoveTo(RectArray.BandRect.Left, RectArray.BandRect.Top + i);
ACanvas.LineTo(RectArray.BandRect.Right - Group.BandRadius + 1, RectArray.BandRect.Top + i)
end;
for i := 0 to Group.BandThickness - 1 do
begin
ACanvas.MoveTo(RectArray.BandRect.Left, RectArray.BandRect.Bottom - i);
ACanvas.LineTo(RectArray.BandRect.Right - Group.BandRadius + 1, RectArray.BandRect.Bottom - i)
end;
for i := 0 to Group.BandThickness - 1 do
begin
ACanvas.MoveTo(RectArray.BandRect.Right - i, RectArray.BandRect.Top + Group.BandRadius);
ACanvas.LineTo(RectArray.BandRect.Right - i, RectArray.BandRect.Bottom - Group.BandRadius + 1)
end;
for i := 0 to Group.BandThickness - 1 do
begin
ACanvas.MoveTo(RectArray.BandRect.Right, RectArray.BandRect.Top + Group.BandRadius);
AngleArc(ACanvas.Handle,
RectArray.BandRect.Right - Group.BandRadius,
RectArray.BandRect.Top + Group.BandRadius,
Group.BandRadius - i,
0,
90);
ACanvas.MoveTo(RectArray.BandRect.Right - Group.BandRadius, RectArray.BandRect.Bottom);
AngleArc(ACanvas.Handle,
RectArray.BandRect.Right - Group.BandRadius,
RectArray.BandRect.Bottom - Group.BandRadius,
Group.BandRadius - i,
270,
90);
end
end
end
end
end;
procedure TEasyViewGroup.PaintBefore(Group: TEasyGroup; ACanvas: TCanvas;
MarginEdge: TEasyGroupMarginEdge; ObjRect: TRect; RectArray: TEasyRectArrayObject);
begin
end;
procedure TEasyViewGroup.PaintCheckBox(Group: TEasyGroup; ACanvas: TCanvas;
RectArray: TEasyRectArrayObject);
begin
if not ((Group.CheckType = ectNone) or (Group.CheckType = ettNoneWithSpace)) then
PaintCheckboxCore(Group.CheckType, // TEasyCheckType
OwnerListview, // TCustomEasyListview
ACanvas, // TCanvas
RectArray.CheckRect, // TRect
Group.Enabled, // IsEnabled
Group.Checked, // IsChecked
Group.CheckPending and (ebcsCheckboxClickPending in OwnerListview.States), // IsHot
Group.CheckFlat, // IsFlat
Group.CheckHovering, // IsHovering
Group.CheckPending, // IsPending
Group,
Group.CheckSize);
end;
procedure TEasyViewGroup.PaintExpandButton(Group: TEasyGroup; ACanvas: TCanvas;
MarginEdge: TEasyGroupMarginEdge; ObjRect: TRect; RectArray: TEasyRectArrayObject);
//
// Paints the [+] button for collapable groups
//
var
Image, ExpandImage, CollapseImage: TBitmap;
{$IFDEF USETHEMES}
Part, uState: Longword;
R: TRect;
{$ENDIF}
begin
if MarginEdge in [egmeTop] then
begin
GetCollapseExpandImages(ExpandImage, CollapseImage);
{$IFDEF USETHEMES}
if Group.OwnerListview.DrawWithThemes and not CustomExpandImages then
begin
Part := TVP_GLYPH;
if Group.Expanded then
uState := GLPS_OPENED
else
uState := GLPS_CLOSED;
R := RectArray.ExpandButtonRect;
R.Top := R.Top + (RectHeight(RectArray.ExpandButtonRect) - RectWidth(RectArray.ExpandButtonRect)) div 2;
R.Bottom := R.Top + RectWidth(R);
DrawThemeBackground(Group.OwnerListview.Themes.TreeviewTheme, ACanvas.Handle,
Part, uState, R, nil);
Exit;
end;
{$ENDIF}
// If the border is the header and it is expandable then must draw the
// "+" expand box
if Group.Expandable and (MarginEdge = egmeTop) then
begin
// Choose correct image
if Group.Expanded then
Image := CollapseImage
else
Image := ExpandImage;
// Draw the image
if Assigned(Image) then
begin
case Group.VAlignment of
cvaTop: ACanvas.Draw(RectArray.ExpandButtonRect.Left + (RectWidth(RectArray.ExpandButtonRect) - Image.Width) div 2, RectArray.ExpandButtonRect.Top + 2, Image);
cvaBottom: ACanvas.Draw(RectArray.ExpandButtonRect.Left + (RectWidth(RectArray.ExpandButtonRect) - Image.Width) div 2, RectArray.ExpandButtonRect.Bottom - 2 - Image.Height, Image);
cvaCenter: ACanvas.Draw(RectArray.ExpandButtonRect.Left + (RectWidth(RectArray.ExpandButtonRect) - Image.Width) div 2,
RectArray.ExpandButtonRect.Top + (RectHeight(RectArray.ExpandButtonRect) - Image.Height) div 2, Image);
end
end
end
end else
begin
end
end;
procedure TEasyViewGroup.PaintFocusRect(Group: TEasyGroup; ACanvas: TCanvas;
MarginEdge: TEasyGroupMarginEdge; ObjRect: TRect; RectArray: TEasyRectArrayObject);
//
// Paint the caption area of a group margin for a focused state
//
var
R: TRect;
begin
if Group.Focused and (MarginEdge = egmeForeground) and not IsRectEmpty(RectArray.GroupRect) then
begin
R := RectArray.GroupRect;
InflateRect(R, -4, -4);
ACanvas.Brush.Color := Group.OwnerListview.Color;
ACanvas.Font.Color := clBlack;
DrawFocusRect(ACanvas.Handle, R);
end
end;
procedure TEasyViewGroup.PaintImage(Group: TEasyGroup; ACanvas: TCanvas;
MarginEdge: TEasyGroupMarginEdge; ObjRect: TRect; RectArray: TEasyRectArrayObject);
//
// Paints the Icon/Bitmap to the group margin
//
var
ImageIndex, OverlayIndex, fStyle: Integer;
Images: TCustomImageList;
IsCustom: Boolean;
begin
if MarginEdge in [egmeTop, egmeBottom] then
begin
Group.ImageDrawIsCustom(nil, IsCustom);
if IsCustom then
Group.ImageDraw(nil, ACanvas, RectArray, AlphaBlender)
else begin
Images := GetImageList(Group);
if MarginEdge = egmeTop then
begin
ImageIndex := Group.ImageIndex;
OverlayIndex := Group.ImageOverlayIndex
end else
begin
ImageIndex := Group.MarginBottom.ImageIndex;
OverlayIndex := Group.MarginBottom.ImageOverlayIndex
end;
// Draw the image in the ImageList if available
if Assigned(Images) and (Group.ImageIndex > -1) then
begin
fStyle := ILD_TRANSPARENT;
if OverlayIndex > -1 then
begin
ImageList_SetOverlayImage(Images.Handle, OverlayIndex, 1);
fStyle := fStyle or INDEXTOOVERLAYMASK(1)
end;
// Get the "normalized" rectangle for the image
RectArray.IconRect.Left := RectArray.IconRect.Left + (RectWidth(RectArray.IconRect) - Images.Width) div 2;
case Group.VAlignment of
cvaTop: RectArray.IconRect.Top := RectArray.IconRect.Top + 2;
cvaBottom: RectArray.IconRect.Top := RectArray.IconRect.Bottom - (Images.Height + 2);
cvaCenter: RectArray.IconRect.Top := RectArray.IconRect.Top + (RectHeight(RectArray.IconRect) - Images.Height) div 2;
end;
ImageList_DrawEx(Images.Handle,
ImageIndex,
ACanvas.Handle,
RectArray.IconRect.Left,
RectArray.IconRect.Top,
0,
0,
CLR_NONE,
CLR_NONE,
fStyle);
end
end
end
end;
procedure TEasyViewGroup.PaintSelectionRect(Group: TEasyGroup; ACanvas: TCanvas;
ObjRect: TRect; RectArray: TEasyRectArrayObject);
//
// Paint the caption area of a group margin for a selected state
//
begin
if Group.Selected and not IsRectEmpty(RectArray.TextRect) and (Group.Caption <> '') then
begin
ACanvas.Brush.Color := clHighlight;
InflateRect(RectArray.TextRect, 2, 2);
ACanvas.FillRect(RectArray.TextRect);
InflateRect(RectArray.TextRect, 2, 2);
end
end;
procedure TEasyViewGroup.PaintText(Group: TEasyGroup; MarginEdge: TEasyGroupMarginEdge;
ACanvas: TCanvas; ObjRect: TRect; RectArray: TEasyRectArrayObject);
//
// Paints the caption within the group margin
//
var
DrawTextFlags: TCommonDrawTextWFlags;
Caption: WideString;
Alignment: TAlignment;
VAlignment: TCommonVAlignment;
begin
if not IsRectEmpty(RectArray.TextRect) and (Group.Caption <> '') then
begin
LoadTextFont(Group, ACanvas);
if MarginEdge = egmeTop then
begin
Caption := Group.Caption;
Alignment := Group.Alignment;
VAlignment := Group.VAlignment;
end else
begin
Caption := Group.MarginBottom.Caption;
Alignment := Group.MarginBottom.Alignment;
VAlignment := Group.MarginBottom.VAlignment;
end;
DrawTextFlags := [dtEndEllipsis];
// if PaintInfo.Caption.RTLReading then
// Include(DrawTextFlags, dtRTLReading);
case Alignment of
taLeftJustify: Include(DrawTextFlags, dtLeft);
taRightJustify: Include(DrawTextFlags, dtRight);
taCenter: Include(DrawTextFlags, dtCenter);
end;
case VAlignment of
cvaTop: Include(DrawTextFlags, dtTop);
cvaCenter: Include(DrawTextFlags, dtVCenter);
cvaBottom: Include(DrawTextFlags, dtBottom);
end;
// if PaintInfo.Caption.RTLReading then
// Include(DrawTextFlags, dtRTLReading);
DrawTextFlags := DrawTextFlags + [dtSingleLine];
DrawTextWEx(ACanvas.Handle, Caption, RectArray.TextRect, DrawTextFlags, 1);
end
end;
{ TEasyColumn }
constructor TEasyColumn.Create(ACollection: TEasyCollection);
begin
inherited;
FDropDownButton := TEasyColumnDropDownButton.Create(Self);
FSortDirection := esdNone;
FAutoToggleSortGlyph := True;
FClickable := True;
FWidth := 50;
FPosition := OwnerColumns.Count;
AutoSizeOnDblClk := True;
end;
destructor TEasyColumn.Destroy;
begin
SetDestroyFlags;
if OwnerListview.Selection.FFocusedColumn = Self then
OwnerListview.Selection.FocusedColumn := nil;
if OwnerListview.Header.HotTrackedColumn = Self then
OwnerListview.Header.HotTrackedColumn := nil;
if OwnerListview.Header.PressColumn = Self then
OwnerListview.Header.PressColumn := nil;
if OwnerListview.EditManager.TabMoveFocusColumn = Self then
OwnerListview.EditManager.TabMoveFocusColumn := nil;
if OwnerListview.Selection.FocusedColumn = Self then
OwnerListview.Selection.FocusedColumn := nil;
if OwnerListview.Header.DropDownHoverColumn = Self then
OwnerListview.Header.DropDownHoverColumn := nil;
FreeAndNil(FDropDownButton);
inherited Destroy;
FreeAndNil(FView);
end;
function TEasyColumn.CanChangeBold(NewValue: Boolean): Boolean;
begin
Result := True
end;
function TEasyColumn.CanChangeCheck(NewValue: Boolean): Boolean;
begin
Result := True;
OwnerListview.DoColumnCheckChanging(Self, Result)
end;
function TEasyColumn.CanChangeEnable(NewValue: Boolean): Boolean;
begin
Result := True;
OwnerListview.DoColumnEnableChanging(Self, Result)
end;
function TEasyColumn.CanChangeFocus(NewValue: Boolean): Boolean;
begin
Result := True;
OwnerListview.DoColumnFocusChanging(Self, Result)
end;
function TEasyColumn.CanChangeHotTracking(NewValue: Boolean): Boolean;
begin
Result := True;
end;
function TEasyColumn.CanChangeSelection(NewValue: Boolean): Boolean;
begin
Result := True;
OwnerListview.DoColumnSelectionChanging(Self, Result)
end;
function TEasyColumn.CanChangeVisibility(NewValue: Boolean): Boolean;
begin
Result := True;
OwnerListview.DoColumnVisibilityChanging(Self, Result)
end;
function TEasyColumn.DefaultImageList(ImageSize: TEasyImageSize): TCustomImageList;
begin
Result := OwnerListview.Header.Images
end;
function TEasyColumn.EditAreaHitPt(ViewportPoint: TPoint): Boolean;
begin
Result := View.EditAreaHitPt(Self, ViewportPoint)
end;
function TEasyColumn.GetAlignment: TAlignment;
begin
Result := FAlignment
end;
function TEasyColumn.GetColor: TColor;
begin
Result := PaintInfo.Color
end;
function TEasyColumn.GetDefaultViewClass: TEasyViewColumnClass;
begin
Result := TEasyViewColumn
end;
function TEasyColumn.GetHotTrack: Boolean;
begin
Result := PaintInfo.HotTrack
end;
function TEasyColumn.GetImagePosition: TEasyHeaderImagePosition;
begin
Result := PaintInfo.ImagePosition
end;
function TEasyColumn.GetOwnerColumns: TEasyColumns;
begin
Result := TEasyColumns(Collection)
end;
function TEasyColumn.GetOwnerHeader: TEasyHeader;
begin
Result := OwnerListview.Header
end;
function TEasyColumn.GetPaintInfo: TEasyPaintInfoColumn;
begin
// Dangerous but necessary. The TaskPanel has its own PaintInfo to not publish
// any properites. It will have a class type error using "is". The two types
// are "equal" from a memory foot print so this will work.
Result := TEasyPaintInfoColumn( inherited PaintInfo)
end;
function TEasyColumn.GetSortGlyphAlign: TEasySortGlyphAlign;
begin
Result := PaintInfo.SortGlyphAlign
end;
function TEasyColumn.GetSortGlyphIndent: Integer;
begin
Result := PaintInfo.SortGlyphIndent
end;
function TEasyColumn.GetStyle: TEasyHeaderButtonStyle;
begin
Result := PaintInfo.Style
end;
function TEasyColumn.GetView: TEasyViewColumn;
begin
if Assigned(FView) then
begin
if ViewClass <> FView.ClassType then
FreeAndNil(FView)
end;
if not Assigned(FView) then
FView := ViewClass.Create(OwnerListview);
Result := FView;
end;
function TEasyColumn.GetViewClass: TEasyViewColumnClass;
begin
Result := nil;
if Assigned(OwnerListview) then
OwnerListview.DoColumnCustomView(Self, Result);
if not Assigned(Result) then
Result := GetDefaultViewClass
end;
function TEasyColumn.LocalPaintInfo: TEasyPaintInfoBasic;
begin
Result := OwnerListview.PaintInfoColumn
end;
function TEasyColumn.PaintMouseHovering: Boolean;
begin
Result := (OwnerListview.Header.HotTrackedColumn = Self) and
HotTrack and not (OwnerListview.DragManager.Dragging or
OwnerListview.DragRect.Dragging)
end;
function TEasyColumn.SelectionHit(SelectViewportRect: TRect;
SelectType: TEasySelectHitType): Boolean;
begin
Result := View.SelectionHit(Self, SelectViewportRect, SelectType)
end;
function TEasyColumn.SelectionHitPt(ViewportPoint: TPoint;
SelectType: TEasySelectHitType): Boolean;
begin
Result := View.SelectionHitPt(Self, ViewportPoint, SelectType)
end;
procedure TEasyColumn.AutoSizeToFit;
var
iIndex: Integer;
W, i, j: Integer;
Group: TEasyGroup;
Canvas: TCanvas;
Item: TEasyItem;
Caption: WideString;
Size: TSize;
ImageW, ImageH: Integer;
begin
iIndex := Index;
Canvas := OwnerListview.Canvas;
W := 0;
for i := 0 to OwnerListview.Groups.Count - 1 do
for j := 0 to OwnerListview.Groups[i].ItemCount - 1 do
begin
Group := OwnerListview.Groups[i];
Item := Group.Items[j];
Item.View.LoadTextFont(Item, iIndex, Canvas, False);
OwnerListview.DoItemPaintText(Item, Index, Canvas);
Caption := Item.Captions[iIndex];
Size := TextExtentW(Caption, Canvas);
Size.cx := Size.cx + {2 * LABEL_MARGIN +} 8;
Item.View.GetImageSize(Item, Self, ImageW, ImageH, eikNormal);
if ImageW > 0 then
Size.cx := Size.cx + ImageW + ImageIndent;
Item.View.GetImageSize(Item, Self, ImageW, ImageH, eikState);
if ImageW > 0 then
Size.cx := Size.cx + ImageW;
if CheckType <> ectNone then
Size.cx := Size.cx + CheckIndent + RectWidth(Checks.Bound[CheckSize]);
if Size.cx > W then
W := Size.cx;
end;
OwnerListview.Groups.BeginUpdate(False);
try
Width := W;
if OwnerListview.Selection.FullRowSelect then
OwnerListview.Groups.Rebuild(True);
finally
OwnerListview.Groups.EndUpdate;
end
end;
procedure TEasyColumn.Freeing;
begin
OwnerListview.DoColumnFreeing(Self)
end;
procedure TEasyColumn.GainingBold;
begin
Invalidate(False)
end;
procedure TEasyColumn.GainingCheck;
begin
OwnerListview.DoColumnCheckChanged(Self)
end;
procedure TEasyColumn.GainingEnable;
begin
OwnerListview.DoColumnEnableChanged(Self)
end;
procedure TEasyColumn.GainingFocus;
begin
OwnerListview.DoColumnFocusChanged(Self)
end;
procedure TEasyColumn.GainingGhosted;
begin
Invalidate(False)
end;
procedure TEasyColumn.GainingHilight;
begin
// Unsupported
end;
procedure TEasyColumn.GainingHotTracking(MousePos: TPoint);
begin
// Unsupported
end;
procedure TEasyColumn.GainingSelection;
begin
OwnerListview.DoColumnSelectionChanged(Self)
end;
procedure TEasyColumn.GainingVisibility;
begin
OwnerListview.BeginUpdate;
OwnerListview.DoColumnVisibilityChanged(Self);
OwnerListview.EndUpdate(False);
end;
function TEasyColumn.HitTestAt(ViewportPoint: TPoint; var HitInfo: TEasyColumnHitTestInfoSet): Boolean;
var
RectArray: TEasyRectArrayObject;
R: TRect;
begin
HitInfo := [];
if Assigned(View) then
begin
View.ItemRectArray(Self, RectArray);
R := RectArray.IconRect;
// Make the blank area between the image and text part of the image
R.Right := R.Right + OwnerListview.PaintInfoColumn.CaptionIndent;
if PtInRect(R, ViewportPoint) then
Include(HitInfo, ectOnText);
if PtInRect(RectArray.IconRect, ViewportPoint) then
Include(HitInfo, ectOnIcon);
if PtInRect(RectArray.CheckRect, ViewportPoint) then
Include(HitInfo, ectOnCheckbox);
if PtInRect(RectArray.LabelRect, ViewportPoint) then
Include(HitInfo, ectOnLabel);
end;
Result := HitInfo <> [];
end;
procedure TEasyColumn.Initialize;
begin
OwnerListview.DoColumnInitialize(Self)
end;
procedure TEasyColumn.Invalidate(ImmediateUpdate: Boolean);
var
R: TRect;
begin
if OwnerListview.UpdateCount = 0 then
begin
if OwnerListview.HandleAllocated then
begin
R := Rect(0, 0, OwnerListview.ClientWidth, OwnerHeader.Height);
OwnerListview.SafeInvalidateRect(@R, ImmediateUpdate);
end
end
end;
procedure TEasyColumn.LoadFromStream(S: TStream; var Version: Integer);
begin
inherited LoadFromStream(S, Version);
S.ReadBuffer(FAlignment, SizeOf(FAlignment));
S.ReadBuffer(FAutoSizeOnDblClk, SizeOf(FAutoSizeOnDblClk));
if Version > 1 then
S.ReadBuffer(FAutoSortOnClick, SizeOf(FAutoSortOnClick));
S.ReadBuffer(FAutoSpring, SizeOf(FAutoSpring));
S.ReadBuffer(FAutoToggleSortGlyph, SizeOf(FAutoToggleSortGlyph));
S.ReadBuffer(FPosition, SizeOf(FPosition));
S.ReadBuffer(FSortDirection, SizeOf(FSortDirection));
S.ReadBuffer(FStyle, SizeOf(FStyle));
S.ReadBuffer(FClickable, SizeOf(FClickable));
S.ReadBuffer(FWidth, SizeOf(FWidth));
OwnerListview.DoColumnLoadFromStream(Self, S, Version);
// For new objects test the stream version first
// if Version > X then
// begin
// ReadStream....
// end
end;
procedure TEasyColumn.LosingBold;
begin
Invalidate(False)
end;
procedure TEasyColumn.LosingCheck;
begin
OwnerListview.DoColumnCheckChanged(Self)
end;
procedure TEasyColumn.LosingEnable;
begin
OwnerListview.DoColumnEnableChanged(Self)
end;
procedure TEasyColumn.LosingFocus;
begin
OwnerListview.DoColumnFocusChanged(Self)
end;
procedure TEasyColumn.LosingGhosted;
begin
Invalidate(False)
end;
procedure TEasyColumn.LosingHilight;
begin
// Unsupported
end;
procedure TEasyColumn.LosingHotTracking;
begin
// Unsupported
end;
procedure TEasyColumn.LosingSelection;
begin
OwnerListview.DoColumnSelectionChanged(Self)
end;
procedure TEasyColumn.LosingVisibility;
begin
OwnerListview.BeginUpdate;
OwnerListview.DoColumnVisibilityChanged(Self);
OwnerListview.EndUpdate(False);
end;
procedure TEasyColumn.MakeVisible(Position: TEasyMakeVisiblePos);
var
RectArray: TEasyRectArrayObject;
ViewRect: TRect;
ColumnW, ViewW: Integer;
begin
if Visible then
begin
View.ItemRectArray(Self, RectArray);
ViewRect := OwnerListview.ClientInViewportCoords;
ColumnW := RectArray.BoundsRect.Right - RectArray.BoundsRect.Left;
ViewW := RectWidth(ViewRect);
if not ((RectArray.BoundsRect.Left >= ViewRect.Left) and ( RectArray.BoundsRect.Right <= ViewRect.Right)) then
begin
case Position of
emvTop: // or Left
begin
if ViewRect.Left < RectArray.BoundsRect.Left then
OwnerListview.Scrollbars.OffsetX := RectArray.BoundsRect.Left;
end;
emvMiddle:
begin
if ColumnW < ViewW then
OwnerListview.Scrollbars.OffsetX := RectArray.BoundsRect.Left - ((ViewW - ColumnW) div 2);
end;
emvBottom: // or right
begin
OwnerListview.Scrollbars.OffsetX := RectArray.BoundsRect.Right - ColumnW;
end;
emvAuto:
begin
if ViewRect.Left < RectArray.BoundsRect.Left then
OwnerListview.Scrollbars.OffsetX := RectArray.BoundsRect.Left;
end
end
end
end
end;
procedure TEasyColumn.Paint(ACanvas: TCanvas; HeaderType: TEasyHeaderType);
begin
View.Paint(Self, ACanvas, HeaderType)
end;
procedure TEasyColumn.SaveToStream(S: TStream; Version: Integer = EASYLISTVIEW_STREAM_VERSION);
begin
inherited SaveToStream(S);
S.WriteBuffer(FAlignment, SizeOf(FAlignment));
S.WriteBuffer(FAutoSizeOnDblClk, SizeOf(FAutoSizeOnDblClk));
S.WriteBuffer(FAutoSortOnClick, SizeOf(FAutoSortOnClick));
S.WriteBuffer(FAutoSpring, SizeOf(FAutoSpring));
S.WriteBuffer(FAutoToggleSortGlyph, SizeOf(FAutoToggleSortGlyph));
S.WriteBuffer(FPosition, SizeOf(FPosition));
S.WriteBuffer(FSortDirection, SizeOf(FSortDirection));
S.WriteBuffer(FStyle, SizeOf(FStyle));
S.WriteBuffer(FClickable, SizeOf(FClickable));
S.WriteBuffer(FWidth, SizeOf(FWidth));
OwnerListview.DoColumnSaveToStream(Self, S, Version);
// For new objects test the stream version first
// if Version > X then
// begin
// WriteStream....
// end
end;
procedure TEasyColumn.SetAlignment(Value: TAlignment);
begin
if Value <> FAlignment then
begin
FAlignment := Value;
Invalidate(False);
end
end;
procedure TEasyColumn.SetAutoSpring(const Value: Boolean);
begin
FAutoSpring := Value;
end;
procedure TEasyColumn.SetColor(Value: TColor);
begin
PaintInfo.Color := Value
end;
procedure TEasyColumn.SetHotTrack(Value: Boolean);
begin
PaintInfo.HotTrack := Value
end;
procedure TEasyColumn.SetImagePosition(Value: TEasyHeaderImagePosition);
begin
PaintInfo.ImagePosition := Value
end;
procedure TEasyColumn.SetPaintInfo(Value: TEasyPaintInfoColumn);
begin
inherited PaintInfo := Value
end;
procedure TEasyColumn.SetPosition(Value: Integer);
var
OldPos, i: Integer;
begin
if Value > OwnerColumns.Count - 1 then
Value := OwnerColumns.Count - 1
else
if Value < 0 then
Value := 0;
if OwnerColumns.Count = 1 then
FPosition := 0
else begin
if Value <> FPosition then
begin
OldPos := FPosition;
if Value > OldPos then
begin
for i := 0 to OwnerColumns.Count - 1 do
begin
if (OwnerColumns[i].FPosition >= OldPos) and (OwnerColumns[i].FPosition <= Value) then
Dec(OwnerColumns[i].FPosition)
end
end else
begin
for i := 0 to OwnerColumns.Count - 1 do
begin
if (OwnerColumns[i].FPosition >= Value) and (OwnerColumns[i].FPosition <= OldPos) then
Inc(OwnerColumns[i].FPosition)
end
end;
FPosition := Value;
end;
OwnerHeader.Rebuild(False);
OwnerHeader.Invalidate(False)
end
end;
procedure TEasyColumn.SetSortDirection(Value: TEasySortDirection);
begin
if Value <> FSortDirection then
begin
FSortDirection := Value;
OwnerHeader.Invalidate(False);
if FSortDirection <> esdNone then
begin
OwnerListview.Selection.FocusedColumn := Self;
if OwnerListview.Sort.AutoSort then
OwnerListview.Sort.SortAll
end
end
end;
procedure TEasyColumn.SetSortGlpyhAlign(Value: TEasySortGlyphAlign);
begin
PaintInfo.SortGlyphAlign := Value
end;
procedure TEasyColumn.SetSortGlyphIndent(Value: Integer);
begin
PaintInfo.SortGlyphIndent := Value
end;
procedure TEasyColumn.SetStyle(Value: TEasyHeaderButtonStyle);
begin
if FStyle <> Value then
begin
FStyle := Value;
Invalidate(False)
end
end;
procedure TEasyColumn.SetWidth(Value: Integer);
var
R: TRect;
begin
if FWidth <> Value then
begin
if Value < 0 then
Value := 0;
FWidth := Value;
OwnerHeader.Rebuild(False);
if OwnerListview.View = elsReport then
begin
// if OwnerHeader.ViewRect.Right > OwnerListview.ClientWidth then
begin
R := OwnerListview.Scrollbars.ViewRect;
R.Right := OwnerHeader.ViewRect.Right;
OwnerListview.Scrollbars.SetViewRect(R, True)
end;
end
end
end;
{ TEasyEditManager }
function TEasyEditManager.GetEditing: Boolean;
begin
Result := FEditing or Assigned(TabMoveFocusItem);
end;
procedure TEasyEditManager.BeginEdit(Item: TEasyItem; Column: TEasyColumn);
//
// Starts an editor within the passed Item
// We create a local message loop and break out of it when any of the normal
// conditions are met to stop the edit, such as: Hitting the Escape key,
// scrolling with the wheel, clicking out side of the editor and switching
// away from the application.
//
var
Msg: TMSG;
Pt: TPoint;
Allow, Dispatch, EditDone: Boolean;
NCHit: Longword;
OldFocus: TWinControl;
iColumn: Integer;
procedure FinishEdit;
begin
if not EditDone then
begin
Editor.Hide;
FEditing := False;
OwnerListview.DoItemEditEnd(Item);
Editor.Finalize;
FEditItem := nil;
FEditFinished := True;
EditDone := True
end
end;
function TestAcceptEdit: Boolean;
begin
Result := Editor.AcceptEdit;
if not Result then
Editor.SetEditorFocus
end;
begin
if not Editing and not (csDestroying in OwnerListview.ComponentState) then
begin
EditDone := False;
FEditFinished := False;
if Assigned(Item) and Enabled then
begin
Item.MakeVisible(emvAuto);
FEditItem := Item;
Allow := True;
if Assigned(Column) then
iColumn := Column.Index
else
iColumn := 0;
OwnerListview.DoItemEditBegin(Item, iColumn, Allow);
if (OwnerListview.View = elsReport) and (iColumn < OwnerListview.Header.Columns.Count) then
begin
OwnerListview.Header.Columns[iColumn].MakeVisible(emvAuto);
end else
iColumn := 0;
if OwnerListview.Header.Columns.Count > iColumn then
EditColumn := OwnerListview.Header.Columns[iColumn]
else
EditColumn := nil;
if Allow then
begin
Application.HookMainWindow(MainWindowHook);
AppHooked := True;
Editor := nil;
OwnerListview.DoItemCreateEditor(Item, FEditor);
if Assigned(Editor) then
begin
OldFocus := Screen.ActiveControl;
Editor.Initialize(Item, EditColumn);
FEditing := True;
Item.Invalidate(True);
Editor.Show;
Editor.SetEditorFocus;
try
while not FEditFinished do
begin
GetMessage(Msg, 0, 0, 0);
Dispatch := True;
if Msg.message = WM_SETFOCUS then
beep;
if not FEditFinished then
begin
if Msg.message = WM_KEYDOWN then
begin
if Msg.wParam = VK_ESCAPE then
FinishEdit
end
end;
// Need to pass the tab to the lsitview if TabMoveFocus is enabled
if Msg.message = WM_KEYDOWN then
begin
// This key combo selects all text in the interface objects, don't allow it to beep
if ((GetKeyState(VK_CONTROL) and $8000 <> 0) and ((Msg.wParam = Ord('a')) or (Msg.wParam = Ord('A')))) then
begin
Editor.SelectAll;
Dispatch := False;
end;
if (Msg.wParam = VK_TAB) and OwnerListview.EditManager.TabMoveFocus then
begin
if TestAcceptEdit then
begin
if GetAsyncKeyState(VK_CONTROL) and $8000 <> 0 then
begin
if OwnerListview.EditManager.TabEditColumns then
begin
OwnerListview.EditManager.TabMoveFocusColumn := OwnerListview.Header.PrevVisibleColumn(EditColumn);
// Stay on the same item if there is another column
if Assigned(OwnerListview.EditManager.TabMoveFocusColumn) then
OwnerListview.EditManager.TabMoveFocusItem := OwnerListview.EditManager.EditItem
else begin
OwnerListview.EditManager.TabMoveFocusItem := OwnerListview.Groups.PrevEditableItem(OwnerListview.EditManager.EditItem);
OwnerListview.EditManager.TabMoveFocusColumn := OwnerListview.Header.LastColumn;
end
end else
OwnerListview.EditManager.TabMoveFocusItem := OwnerListview.Groups.PrevEditableItem(OwnerListview.EditManager.EditItem);
end else
begin
if OwnerListview.EditManager.TabEditColumns then
begin
OwnerListview.EditManager.TabMoveFocusColumn := OwnerListview.Header.NextVisibleColumn(EditColumn);
// Stay on the same item if there is another column
if Assigned(OwnerListview.EditManager.TabMoveFocusColumn) then
OwnerListview.EditManager.TabMoveFocusItem := OwnerListview.EditManager.EditItem
else
OwnerListview.EditManager.TabMoveFocusItem := OwnerListview.Groups.NextEditableItem(OwnerListview.EditManager.EditItem);
end else
OwnerListview.EditManager.TabMoveFocusItem := OwnerListview.Groups.NextEditableItem(OwnerListview.EditManager.EditItem);
end;
EndEdit;
PostMessage(OwnerListview.Handle, WM_TABMOVEFOCUS, 0, 0);
Dispatch := False;
end
end
end;
if not FEditFinished then
if (Msg.message = WM_LBUTTONDOWN) or
(Msg.message = WM_MBUTTONDOWN) or
(Msg.message = WM_RBUTTONDOWN) then
begin
Pt := SmallPointToPoint(TSmallPoint(Msg.lParam));
ClientToScreen(Msg.hwnd, Pt);
ScreenToClient(OwnerListview.Handle, Pt);
if not Editor.PtInEditControl(Pt) then
begin
Dispatch := False;
if TestAcceptEdit then
begin
FinishEdit;
// Allow the default click action to occur after canceling the edit.
Dispatch := True
end
end;
end;
if not FEditFinished then
begin
if (Msg.message = WM_MOUSEWHEEL) or
(Msg.message = CM_MOUSEWHEEL) then
begin
FinishEdit
end
end;
if not FEditFinished then
if (Msg.message = WM_NCLBUTTONDOWN) or
(Msg.message = WM_NCMBUTTONDOWN) or
(Msg.message = WM_NCRBUTTONDOWN) then
begin
NCHit := SendMessage(Msg.hWnd, WM_NCHITTEST, Msg.wParam, Msg.lParam);
if not (NCHit = HTCAPTION) then
begin
FinishEdit;
end
end;
if not FEditFinished then
begin
if (Msg.message = WM_HOOKAPPACTIVATE) then
begin
FinishEdit
end
end;
if Dispatch then
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end
finally
if AppHooked then
Application.UnhookMainWindow(MainWindowHook);
AppHooked := False;
FinishEdit;
OldFocus.SetFocus;
Editor := nil;
EditColumn := nil;
end
end;
end
end
end;
end;
constructor TEasyEditManager.Create(AnOwner: TCustomEasyListview);
begin
inherited;
FFont := TFont.Create;
Color := clWindow;
Font.Assign(AnOwner.Font);
AutoEditDelayTime := 300;
end;
destructor TEasyEditManager.Destroy;
begin
FreeAndNil(FFont);
inherited;
end;
procedure TEasyEditManager.EndEdit;
//
// Flags the Edit Manager to stop editing. The local message loop in BeginEdit
// alway polls this flag to quit
//
begin
StopAutoEditTimer;
if AppHooked and not (csDestroying in OwnerListview.ComponentState) then
Application.UnhookMainWindow(MainWindowHook);
AppHooked := False;
FEditFinished := True
end;
function TEasyEditManager.MainWindowHook(var Message: TMessage): Boolean;
//
// Need to hook the Main so we can end the edit if the application is switched
// away from
//
begin
Result := False;
if Assigned(OwnerListview) then
begin
if (Message.Msg = WM_ACTIVATEAPP) and OwnerListview.HandleAllocated then
PostMessage(OwnerListview.Handle, WM_HOOKAPPACTIVATE, 0, 0)
end
end;
procedure TEasyEditManager.SetEnabled(const Value: Boolean);
begin
FEnabled := Value;
EndEdit;
end;
procedure TEasyEditManager.SetFont(const Value: TFont);
begin
Font.Assign(Value)
end;
procedure TEasyEditManager.StartAutoEditTimer;
//
// Starts the AutoEditTimer, the timer will be cancelled if the user moves the
// mouse a specified distance before the timer elapses
//
begin
StopAutoEditTimer;
if Enabled then
begin
Timer := TTimer.Create(nil);
Timer.OnTimer := TimerEvent;
Timer.Interval := AutoEditDelayTime;
Timer.Enabled := True;
FTimerRunning := True
end
end;
procedure TEasyEditManager.TimerEvent(Sender: TObject);
//
// The Timer Event method. If called the Focused Item will be edited.
//
begin
StopAutoEditTimer;
if Assigned(OwnerListview.Selection.FocusedItem) then
BeginEdit(OwnerListview.Selection.FocusedItem as TEasyItem, nil)
end;
procedure TEasyEditManager.StopAutoEditTimer;
//
// Shuts down the AutoEditTimer
//
begin
if TimerRunning then
begin
if Assigned(Timer) then
FreeAndNil(FTimer);
FTimerRunning := False
end
end;
{ TEasyEnumFormatEtcManager }
function TEasyEnumFormatEtcManager.Clone(out Enum: IEnumFormatEtc): HResult;
// Creates a exact copy of the current object.
var
EnumFormatEtc: TEasyEnumFormatEtcManager;
begin
Result := S_OK; // Think positive
EnumFormatEtc := TEasyEnumFormatEtcManager.Create; // Does not increase COM reference
if Assigned(EnumFormatEtc) then
begin
SetLength(EnumFormatEtc.FFormats, Length(Formats));
// Make copy of Format info
Move(FFormats[0], EnumFormatEtc.FFormats[0], Length(Formats) * SizeOf(TFormatEtc));
// Set COM reference to 1
Enum := EnumFormatEtc as IEnumFormatEtc;
end else
Result := E_UNEXPECTED
end;
constructor TEasyEnumFormatEtcManager.Create;
begin
inherited Create;
InternalIndex := 0;
end;
destructor TEasyEnumFormatEtcManager.Destroy;
begin
inherited;
end;
function TEasyEnumFormatEtcManager.Next(celt: Integer; out elt;
pceltFetched: PLongint): HResult;
// Another EnumXXXX function. This function returns the number of objects
// requested by the caller in celt. The return buffer, elt, is a pointer to an}
// array of, in this case, TFormatEtc structures. The total number of
// structures returned is placed in pceltFetched. pceltFetched may be nil if
// celt is only asking for one structure at a time.
var
i: integer;
begin
if Assigned(Formats) then
begin
i := 0;
while (i < celt) and (InternalIndex < Length(Formats)) do
begin
TeltArray( elt)[i] := Formats[InternalIndex];
inc(i);
inc(FInternalIndex);
end; // while
if assigned(pceltFetched) then
pceltFetched^ := i;
if i = celt then
Result := S_OK
else
Result := S_FALSE
end else
Result := E_UNEXPECTED
end;
function TEasyEnumFormatEtcManager.Reset: HResult;
begin
InternalIndex := 0;
Result := S_OK
end;
function TEasyEnumFormatEtcManager.Skip(celt: Integer): HResult;
// Allows the caller to skip over unwanted TFormatEtc structures. Simply adds
// celt to the index as long as it does not skip past the last structure in
// the list.
begin
if Assigned(Formats) then
begin
if InternalIndex + celt < Length(Formats) then
begin
InternalIndex := InternalIndex + celt;
Result := S_OK
end else
Result := S_FALSE
end else
Result := E_UNEXPECTED
end;
procedure TEasyDataObjectManager.DoGetCustomFormats(var Formats: TFormatEtcArray);
begin
if Assigned(Listview) then
Listview.DoOLEGetCustomFormats(Formats);
end;
procedure TEasyDataObjectManager.DoOnGetData(const FormatEtcIn: TFormatEtc; var Medium: TStgMedium; var Handled: Boolean);
begin
if Assigned(Listview) then
Listview.DoOLEGetData(FormatEtcIn, Medium, Handled);
end;
procedure TEasyDataObjectManager.DoOnQueryGetData(const FormatEtcIn: TFormatEtc; var FormatAvailable: Boolean; var Handled: Boolean);
begin
if Assigned(Listview) then
Listview.DoQueryOLEData(FormatEtcIn, FormatAvailable, Handled);
end;
procedure TEasyOLEDragManager.ClearDragItem;
begin
FDragItem := nil
end;
procedure TEasyOLEDragManager.ClearDropTarget;
begin
// Unhilight the current Drop Target
if Assigned(DropTarget) then
begin
DropTarget.Hilighted := False;
OwnerListview.Groups.InvalidateItem(DropTarget, True);
end;
FDropTarget := nil;
end;
constructor TEasyOLEDragManager.Create(AnOwner: TCustomEasyListview);
begin
inherited;
HilightDropTarget := True
end;
destructor TEasyOLEDragManager.Destroy;
begin
Registered := False;
inherited;
end;
procedure TEasyOLEDragManager.DefaultImage(Sender: TCustomEasyListview; Image: TBitmap; DragStartPt: TPoint; var HotSpot: TPoint; var TransparentColor: TColor; var Handled: Boolean);
var
R: TRect;
Bits: TBitmap;
begin
if Assigned(Image) then
begin
TransparentColor := OwnerListview.Color;
R := Rect(DragStartPt.X - (Image.Width div 2),
DragStartPt.Y - (Image.Height div 2),
DragStartPt.X + (Image.Width div 2),
DragStartPt.Y + (Image.Height div 2));
HotSpot.X := (R.Right - R.Left) div 2;
HotSpot.Y := (R.Bottom - R.Top) div 2;
if R.Left < 0 then
HotSpot.X := HotSpot.X + R.Left;
if R.Top < 0 then
HotSpot.Y := HotSpot.Y + R.Top;
IntersectRect(R, R, OwnerListview.ClientRect);
Bits := TBitmap.Create;
try
Bits.PixelFormat := pf32Bit;
Bits.Width := Sender.Width;
Bits.Height := Sender.Height;
Bits.Canvas.Brush.Color := OwnerListview.Color;
Bits.Canvas.FillRect(Rect(0, 0, Sender.Width, Sender.Height));
OwnerListview.DoPaintRect(Bits.Canvas, R, True);
BitBlt(Image.Canvas.Handle, 0, 0, Image.Width, Image.Height, Bits.Canvas.Handle, R.Left, R.Top, SRCCOPY);
finally
Bits.Free;
end;
Handled := True;
end
end;
procedure TEasyOLEDragManager.DoDrag(Canvas: TCanvas; WindowPoint: TPoint; KeyState: TCommonKeyStates; var Effects: TCommonDropEffect);
var
ViewPortPoint: TPoint;
Item: TEasyItem;
begin
if OwnerListview.IsHeaderMouseMsg(PointToSmallPoint(WindowPoint), True) then
Effects := cdeNone
else begin
ViewPortPoint := OwnerListview.Scrollbars.MapWindowToView(WindowPoint);
Item := OwnerListview.Groups.ItemByPoint(ViewportPoint);
if Assigned(Item) then
begin
if Item.SelectionHitPt(ViewportPoint, eshtClickSelect) then
begin
if Item <> DropTarget then
ClearDropTarget;
FDropTarget := Item;
if Assigned(DropTarget) then
begin
if HilightDropTarget then
Item.Hilighted := True;
OwnerListview.Groups.InvalidateItem(Item, True)
end
end else
ClearDropTarget
end else
ClearDropTarget
end
end;
procedure TEasyOLEDragManager.DoDragDrop(WindowPoint: TPoint; KeyState: TCommonKeyStates; var Effects: TCommonDropEffect);
begin
ClearDragItem;
ClearDropTarget;
FDragTarget := False;
end;
procedure TEasyOLEDragManager.DoDragEnd(Canvas: TCanvas; WindowPoint: TPoint; KeyState: TCommonKeyStates);
begin
ClearDropTarget;
FDragTarget := False;
end;
procedure TEasyOLEDragManager.DoDragEnter(const DataObject: IDataObject; Canvas: TCanvas; WindowPoint: TPoint; KeyState: TCommonKeyStates; var Effects: TCommonDropEffect);
begin
FDragTarget := True;
end;
procedure TEasyOLEDragManager.DoGetDragImage(Bitmap: TBitmap; DragStartPt: TPoint; var HotSpot: TPoint; var TransparentColor: TColor; var Handled: Boolean);
begin
OwnerListview.DoGetDragImage(Bitmap, DragStartPt, HotSpot, TransparentColor, Handled);
end;
procedure TEasyOLEDragManager.DoOLEDragEnd(const ADataObject: IDataObject; DragResult: TCommonOLEDragResult; ResultEffect: TCommonDropEffects; KeyStates: TCommonKeyStates);
begin
OwnerListview.DoOLEDragEnd(ADataObject, DragResult, ResultEffect, KeyStates);
DataObject := nil;
end;
procedure TEasyOLEDragManager.DoOLEDragStart(const ADataObject: IDataObject; var AvailableEffects: TCommonDropEffects; var AllowDrag: Boolean);
begin
OwnerListview.DoOLEDragStart(ADataObject, AvailableEffects, AllowDrag);
end;
function TEasyOLEDragManager.DoPtInAutoScrollDownRegion(WindowPoint: TPoint): Boolean;
begin
Result := WindowPoint.Y > OwnerListview.ClientHeight - AutoScrollMargin
end;
function TEasyOLEDragManager.DoPtInAutoScrollUpRegion(WindowPoint: TPoint): Boolean;
begin
Result := WindowPoint.Y - OwnerListview.Header.RuntimeHeight < AutoScrollMargin
end;
procedure TEasyOLEDragManager.FinalizeDrag(KeyState: TCommonKeyStates);
// Does not mean the action actually occured it means that InitializeDrag was
// called and this is it matching call. EndDrag means that the drag actually
// occured
begin
inherited;
ClearDragItem;
end;
function TEasyOLEDragManager.InitializeDrag(HitItem: TEasyItem; WindowPoint: TPoint;
KeyState: TCommonKeyStates): Boolean;
// Does not mean that the action will be a Drag, it just means get ready for one
// just in case.
begin
Result := False;
if Enabled then
begin
if Assigned(HitItem) and ( ((cksLButton in KeyState) and (cmbLeft in MouseButton)) or
((cksMButton in KeyState) and (cmbMiddle in MouseButton)) or
((cksRButton in KeyState) and (cmbRight in MouseButton))) then
begin
if HitItem.SelectionHitPt(OwnerListview.Scrollbars.MapWindowToView(WindowPoint), eshtClickSelect) then
begin
FDragItem := HitItem;
Result := True
end
end else
FDragItem := nil
end
end;
procedure TEasyOLEDragManager.ImageSize(var Width: Integer; var Height: Integer);
begin
Width := DragImageWidth;
Height := DragImageHeight
end;
procedure TEasyOLEDragManager.SetEnabled(const Value: Boolean);
begin
inherited;
Registered := Value;
end;
procedure TEasyOLEDragManager.VCLDragStart;
begin
FDragItem := OwnerListview.Selection.FocusedItem;
if DragMode = dmAutomatic then
OwnerListview.BeginDrag(True);
end;
{ TEasySelectionManager }
function TEasySelectionManager.GetFocusedColumn: TEasyColumn;
begin
if not Assigned(FFocusedColumn) then
FFocusedColumn := OwnerListview.Header.FirstColumn;
Result := FFocusedColumn;
end;
function TEasySelectionManager.SelectedToArray: TEasyItemArray;
var
Item: TEasyItem;
i: Integer;
begin
SetLength(Result, Count);
Item := First;
i := 0;
while Assigned(Item) do
begin
Result[i] := Item;
Inc(i);
Item := Next(Item)
end
end;
procedure TEasySelectionManager.ActOnAll(SelectType: TEasySelectionType;
ExceptItem: TEasyItem);
var
i, j: Integer;
begin
if Enabled then
begin
IncMultiChangeCount;
GroupSelectBeginUpdate;
try
// If unselecting we can optimize for the more common situation by stopping when
// there are no more selected items.
if SelectType = ecstUnSelect then
begin
i := 0;
while (i < OwnerListview.Groups.Count) and (Count > 0) do
begin
j := 0;
while (j < OwnerListview.Groups[i].Items.Count) and (Count > 0) do
begin
if ExceptItem <> OwnerListview.Groups[i].Items[j] then
OwnerListview.Groups[i].Items[j].Selected := False;
Inc(j)
end;
Inc(i)
end
end else
begin
for i := 0 to OwnerListview.Groups.Count - 1 do
begin
case SelectType of
ecstSelect:
begin
j := 0;
while (j < OwnerListview.Groups[i].Items.Count) do
begin
if ExceptItem <> OwnerListview.Groups[i].Items[j] then
OwnerListview.Groups[i].Items[j].Selected := True;
Inc(j)
end;
end;
ecstInvert:
begin
j := 0;
while (j < OwnerListview.Groups[i].Items.Count) do
begin
if ExceptItem <> OwnerListview.Groups[i].Items[j] then
OwnerListview.Groups[i].Items[j].Selected := not OwnerListview.Groups[i].Items[j].Selected;
Inc(j)
end;
end;
end
end
end;
OwnerListview.DragManager.ClearDragItem;
finally
GroupSelectEndUpdate;
DecMultiChangeCount
end
end
end;
procedure TEasySelectionManager.BuildSelectionGroupings(Force: Boolean);
//
// Builds the necessary information to group the selections like eMule, called
// for every selection change. This could get slow with thousands of items.
//
var
i: Integer;
GroupList: TEasySelectionGroupList;
Group: TEasyGroup;
Item, NextItem: TEasyItem;
begin
// It is possible that during streaming the items can be created but
if not (csLoading in OwnerListview.ComponentState) and
(Force or (GroupSelections and (FGroupSelectUpdateCount = 0){ and (OwnerListview.UpdateCount = 0) won't work with keyboard})) then
begin
// Windows.Beep(5000, 200);
GroupList := nil;
for i := 0 to OwnerListview.Groups.Count - 1 do
begin
Group := TEasyGroup( OwnerListview.Groups.List[i]);
Item := OwnerListview.Groups.FirstVisibleInGroup(Group);
while Assigned(Item) do
begin
// Do a ReleaseSelectionGroup directly for speed
if Assigned(Item) and Assigned(Item.SelectionGroup) then
begin
Item.FSelectionGroup.DecRef;
Item.FSelectionGroup := nil
end;
if (esosSelected in Item.State) then
begin
NextItem := OwnerListview.Groups.NextVisibleInGroup(Group, Item);
// Do a ReleaseSelectionGroup directly for speed
if Assigned(NextItem) and Assigned(NextItem.SelectionGroup) then
begin
NextItem.FSelectionGroup.DecRef;
NextItem.FSelectionGroup := nil
end;
// Direct access for speed
while Assigned(NextItem) and (esosSelected in NextItem.State) do
begin
if not Assigned(GroupList) then
begin
GroupList := TEasySelectionGroupList.Create;
GroupList.Add(Item);
GroupList.IncRef;
GroupList.DisplayRect := Item.DisplayRect;
GroupList.FirstItem := Item;
Item.SelectionGroup := GroupList;
end;
GroupList.Add(NextItem);
UnionRect(Item.SelectionGroup.FDisplayRect, Item.SelectionGroup.DisplayRect, NextItem.DisplayRect);
GroupList.IncRef;
NextItem.SelectionGroup := GroupList;
NextItem := OwnerListview.Groups.NextVisibleInGroup(Group, NextItem);
end;
GroupList := nil;
Item := NextItem;
end;
Item := OwnerListview.Groups.NextVisibleInGroup(Group, Item);
end;
end
end
end;
procedure TEasySelectionManager.ClearAll;
begin
ActOnAll(ecstUnSelect, nil);
end;
procedure TEasySelectionManager.ClearAllExcept(Item: TEasyItem);
begin
ActOnAll(ecstUnSelect, Item);
OwnerListview.DragManager.ClearDragItem;
end;
constructor TEasySelectionManager.Create(AnOwner: TCustomEasyListview);
begin
inherited;
FEnabled := True;
FColor := clHighlight;
FBorderColor := clHighlight;
FInactiveBorderColor := clInactiveBorder;
FInactiveColor := clInactiveBorder;
FInactiveTextColor := clBlack;
FTextColor := clHighlightText;
FRoundRectRadius := 4;
FBlendColorSelRect := clHighlight;
FBorderColorSelRect := clHighlight;
FBlendColorIcon := clHighlight;
BlendAlphaImage := 128;
BlendAlphaSelRect := 70;
BlendAlphaTextRect := 128;
FAlphaBlend := False;
FUseFocusRect := True;
FMouseButton := [cmbLeft];
MouseButtonSelRect := [cmbLeft, cmbRight];
FGradientColorBottom := $FCEFD5;
FGradientColorTop := $FDF8F1;
FBlendIcon := True
end;
destructor TEasySelectionManager.Destroy;
begin
inherited;
end;
procedure TEasySelectionManager.DecMultiChangeCount;
begin
Dec(FMultiChangeCount);
if MultiChangeCount <= 0 then
begin
MultiChangeCount := 0;
if ItemsToggled > 0 then
OwnerListview.DoItemSelectionsChanged
end
end;
procedure TEasySelectionManager.DeleteSelected(SelectPrevItem: Boolean = False);
var
NextToSelect: Integer;
AItem: TEasyItem;
begin
if Count <> 0 then
begin
NextToSelect := -1;
OwnerListview.BeginUpdate;
try
if SelectPrevItem then
NextToSelect := First.Index - 1;
OwnerListview.Groups.DeleteItems(SelectedToArray);
finally
OwnerListview.EndUpdate;
if SelectPrevItem and (OwnerListview.Groups.ItemCount > 0) then
begin
if NextToSelect < 0 then
NextToSelect := 0
else
if NextToSelect >= OwnerListview.Groups.ItemCount then
NextToSelect := OwnerListview.Groups.ItemCount - 1;
AItem := OwnerListview.Items[NextToSelect];
AItem.Selected := True;
AItem.Focused := True;
end
end
end
end;
procedure TEasySelectionManager.DragSelect(KeyStates: TCommonKeyStates);
// Handles the selection of items during a drag select operation
var
CoverR: TRect;
Item: TEasyItem;
begin
if Enabled and MultiSelect then
begin
IncMultiChangeCount;
GroupSelectBeginUpdate;
try
// Get the rectangle that covers any area that need to be tested for change
UnionRect(CoverR, OwnerListview.DragRect.PrevRect, OwnerListview.DragRect.SelectionRect);
if not IsRectEmpty(CoverR) then
begin
Item := OwnerListview.Groups.FirstItemInRect(CoverR);
while Assigned(Item) do
begin
if cksControl in KeyStates then
begin
if Item.SelectionHit( OwnerListview.DragRect.SelectionRect, eshtDragSelect) xor
Item.SelectionHit(OwnerListview.DragRect.PrevRect, eshtDragSelect)
then
Item.Selected := not Item.Selected;
end else
begin
// First see if we need to select an item
if Item.SelectionHit(OwnerListview.DragRect.SelectionRect, eshtDragSelect) then
Item.Selected := True
else begin
// If we did not select the item see if it is in the Previous rectanagle
// and it needs to be unselected
if Item.SelectionHit(OwnerListview.DragRect.PrevRect, eshtDragSelect) then
Item.Selected := False;
end
end;
Item := OwnerListview.Groups.NextItemInRect(Item, CoverR)
end
end
finally
GroupSelectEndUpdate;
DecMultiChangeCount
end
end
end;
function TEasySelectionManager.First: TEasyItem;
//
// Gets the first Selected item
//
var
Item: TEasyItem;
begin
Result := nil;
Item := OwnerListview.Groups.FirstVisibleItem;
while not Assigned(Result) and Assigned(Item) do
begin
if Item.Selected then
Result := Item;
Item := OwnerListview.Groups.NextVisibleItem(Item)
end
end;
function TEasySelectionManager.FirstInGroup(Group: TEasyGroup): TEasyItem;
//
// Gets the first Selected item in the specified group from UIObject list
//
var
Item: TEasyItem;
begin
Result := nil;
Item := OwnerListview.Groups.FirstInGroup(Group);
while not Assigned(Result) and Assigned(Item) do
begin
if Item.Selected then
Result := Item;
Item := OwnerListview.Groups.NextInGroup(Group, Item)
end
end;
procedure TEasySelectionManager.FocusFirst;
var
Item: TEasyItem;
begin
ClearAll;
Item := OwnerListview.Groups.FirstItem;
if Assigned(Item) and Enabled then
Item.Focused := True;
end;
procedure TEasySelectionManager.GainingSelection(Item: TEasyItem);
begin
if not MultiSelect then
ClearAllExcept(Item);
Inc(OwnerListview.Selection.FCount);
if not MultiSelect then
FocusedItem := Item;
Inc(FItemsToggled);
NotifyOwnerListview
end;
function TEasySelectionManager.GetAutoScroll: Boolean;
begin
Result := OwnerListview.DragRect.AutoScroll
end;
function TEasySelectionManager.GetAutoScrollAccelerator: Byte;
begin
Result := OwnerListview.DragRect.AutoScrollAccelerator
end;
function TEasySelectionManager.GetAutoScrollDelay: Integer;
begin
Result := OwnerListview.DragRect.AutoScrollDelay
end;
function TEasySelectionManager.GetAutoScrollMargin: Integer;
begin
Result := OwnerListview.DragRect.AutoScrollMargin
end;
function TEasySelectionManager.GetAutoScrollTime: Integer;
begin
Result := OwnerListview.DragRect.AutoScrollTime
end;
function TEasySelectionManager.GetEnableDragSelect: Boolean;
begin
Result := OwnerListview.DragRect.Enabled
end;
function TEasySelectionManager.GeTCommonMouseButton: TCommonMouseButtons;
begin
Result := FMouseButton
end;
function TEasySelectionManager.GetMouseButtonSelRect: TCommonMouseButtons;
begin
Result := OwnerListview.DragRect.MouseButton
end;
function TEasySelectionManager.GetSelecting: Boolean;
begin
Result := OwnerListview.DragRect.Dragging
end;
procedure TEasySelectionManager.GroupSelectBeginUpdate;
begin
Inc(FGroupSelectUpdateCount)
end;
procedure TEasySelectionManager.GroupSelectEndUpdate;
begin
Dec(FGroupSelectUpdateCount);
if FGroupSelectUpdateCount <= 0 then
begin
FGroupSelectUpdateCount := 0;
// OwnerListview.Groups.ReIndexItems(nil, True);
BuildSelectionGroupings(False);
end
end;
procedure TEasySelectionManager.IncMultiChangeCount;
begin
if MultiChangeCount = 0 then
ItemsToggled := 0;
Inc(FMultiChangeCount)
end;
procedure TEasySelectionManager.InvalidateVisibleSelected(ValidateWindow: Boolean);
var
Item: TEasyItem;
begin
if Enabled then
begin
Item := OwnerListview.Groups.FirstItemInRect(OwnerListview.ClientRect);
while Assigned(Item) do
begin
if Item.Selected or Item.Focused then
Item.Invalidate(False);
Item := OwnerListview.Groups.NextItemInRect(Item, OwnerListview.ClientRect)
end
end
end;
procedure TEasySelectionManager.Invert;
begin
ActOnAll(ecstInvert, nil);
end;
procedure TEasySelectionManager.LosingSelection(Item: TEasyItem);
begin
Dec(OwnerListview.Selection.FCount);
Item.ReleaseSelectionGroup;
Inc(FItemsToggled);
NotifyOwnerListview
end;
procedure TEasySelectionManager.NotifyOwnerListview;
begin
if (MultiChangeCount = 0) and (ItemsToggled > 0) then
begin
OwnerListview.DoItemSelectionsChanged;
ItemsToggled := 0
end
end;
procedure TEasySelectionManager.SelectAll;
begin
if MultiSelect then
ActOnAll(ecstSelect, nil);
end;
function TEasySelectionManager.Next(Item: TEasyItem): TEasyItem;
//
// Gets the next Selected item in the UIObject list
//
begin
Result := nil;
Item := OwnerListview.Groups.NextVisibleItem(Item);
while not Assigned(Result) and Assigned(Item) do
begin
if Item.Selected then
Result := Item;
Item := OwnerListview.Groups.NextVisibleItem(Item)
end
end;
function TEasySelectionManager.NextInGroup(Group: TEasyGroup;
Item: TEasyItem): TEasyItem;
//
// Gets the next Selected item in the specified group from UIObject list
//
begin
Result := nil;
Item := OwnerListview.Groups.NextInGroup(Group, Item);
while not Assigned(Result) and Assigned(Item) do
begin
if Item.Selected then
Result := Item;
Item := OwnerListview.Groups.NextInGroup(Group, Item)
end
end;
procedure TEasySelectionManager.SelectFirst;
var
Item: TEasyItem;
begin
ClearAll;
Item := OwnerListview.Groups.FirstItem;
if Assigned(Item) and Enabled then
begin
Item.Focused := True;
Item.Selected := True
end
end;
procedure TEasySelectionManager.SelectGroupItems(Group: TEasyGroup; ClearOtherItems: Boolean);
var
i, j: Integer;
begin
if Enabled and MultiSelect and Assigned(Group) then
begin
IncMultiChangeCount;
GroupSelectBeginUpdate;
try
if ClearOtherItems then
begin
for i := 0 to OwnerListview.Groups.Count - 1 do
begin
if OwnerListview.Groups[i] <> Group then
for j := 0 to OwnerListview.Groups[i].Items.Count - 1 do
OwnerListview.Groups[i].Items[j].Selected := False;
end;
end;
for i := 0 to Group.Items.Count - 1 do
Group.Items[i].Selected := True
finally
GroupSelectEndUpdate;
DecMultiChangeCount
end
end
end;
procedure TEasySelectionManager.SelectRange(FromItem, ToItem: TEasyItem; RectSelect: Boolean; ClearFirst: Boolean);
procedure SwapItems(var Item1, Item2: TEasyItem);
var
Temp: TEasyItem;
begin
Temp := Item1;
Item1 := Item2;
Item2 := Temp
end;
var
R: TRect;
begin
if Enabled and MultiSelect then
begin
IncMultiChangeCount;
GroupSelectBeginUpdate;
try
if ClearFirst then
ClearAll;
if Assigned(FromItem) and Assigned(ToItem) then
begin
if RectSelect then
begin
UnionRect(R, FromItem.DisplayRect, ToItem.DisplayRect);
SelectRect(R, False);
end else
begin
if FromItem.OwnerGroup = ToItem.OwnerGroup then
begin
if FromItem.Index > ToItem.Index then
SwapItems(FromItem, ToItem)
end else
begin
if FromItem.OwnerGroup.Index > ToItem.OwnerGroup.Index then
SwapItems(FromItem, ToItem)
end;
while Assigned(FromItem) and (FromItem <> ToItem) do
begin
FromItem.Selected := True;
FromItem := OwnerListview.Groups.NextVisibleItem(FromItem)
end;
ToItem.Selected := True;
end
end
finally
GroupSelectEndUpdate;
DecMultiChangeCount
end
end
end;
procedure TEasySelectionManager.SelectRect(ViewportSelRect: TRect; ClearFirst: Boolean);
var
Temp: TEasyItem;
begin
if Enabled and MultiSelect then
begin
GroupSelectBeginUpdate;
IncMultiChangeCount;
try
if ClearFirst then
ClearAll;
Temp := OwnerListview.Groups.FirstItemInRect(ViewportSelRect);
while Assigned(Temp) do
begin
Temp.Selected := True;
Temp := OwnerListview.Groups.NextItemInRect(Temp, ViewportSelRect);
end
finally
GroupSelectEndUpdate;
DecMultiChangeCount
end
end
end;
procedure TEasySelectionManager.SetAnchorItem(Value: TEasyItem);
begin
if Assigned(Value) then
begin
if Value.Visible and Value.Enabled then
FAnchorItem := Value;
end else
FAnchorItem := nil
end;
procedure TEasySelectionManager.SetAutoScroll(Value: Boolean);
begin
OwnerListview.DragRect.AutoScroll := Value
end;
procedure TEasySelectionManager.SetAutoScrollAccelerator(Value: Byte);
begin
OwnerListview.DragRect.AutoScrollAccelerator := Value
end;
procedure TEasySelectionManager.SetAutoScrollDelay(Value: Integer);
begin
OwnerListview.DragRect.AutoScrollDelay := Value
end;
procedure TEasySelectionManager.SetAutoScrollMargin(Value: Integer);
begin
OwnerListview.DragRect.AutoScrollMargin := Value
end;
procedure TEasySelectionManager.SetAutoScrollTime(Value: Integer);
begin
OwnerListview.DragRect.AutoScrollTime := Value
end;
procedure TEasySelectionManager.SetBlendIcon(Value: Boolean);
begin
if FBlendIcon <> Value then
begin
FBlendIcon := Value;
OwnerListview.SafeInvalidateRect(nil, False)
end
end;
procedure TEasySelectionManager.SetBlurAlphaBkGnd(const Value: Boolean);
begin
if FBlurAlphaBkGnd <> Value then
begin
FBlurAlphaBkGnd := Value;
OwnerListview.SafeInvalidateRect(nil, False)
end
end;
procedure TEasySelectionManager.SetEnabled(const Value: Boolean);
begin
if FEnabled <> Value then
begin
if not Value then
ClearAll;
FEnabled := Value;
end;
end;
procedure TEasySelectionManager.SetEnableDragSelect(Value: Boolean);
begin
OwnerListview.DragRect.Enabled := Value
end;
procedure TEasySelectionManager.SetFocusedColumn(Value: TEasyColumn);
var
OldFocused: TEasyColumn;
begin
if FFocusedColumn <> Value then
begin
OldFocused := FFocusedColumn;
FFocusedColumn := Value;
if Assigned(FFocusedColumn) then
FFocusedColumn.Invalidate(True);
if Assigned(OldFocused) then
OldFocused.Invalidate(True);
end
end;
procedure TEasySelectionManager.SetFocusedGroup(const Value: TEasyGroup);
//var
// ChangeFocus: Boolean;
// OldGroup: TEasyGroup;
begin
// OldGroup := FFocusedGroup;
(* if Assigned(Value) then
begin
if Value.Visible and Value.Enabled then
begin
if FFocusedGroup <> Value then
begin
if Assigned(OldGroup) then
OldGroup.Focused := False;
ChangeFocus := True;
// The user may not have allowed the focus to change
if Assigned(OldGroup) then
ChangeFocus := not OldGroup.Focused;
if ChangeFocus then
begin
Value.Focused := True;
FFocusedGroup := Value
end
end
end
end else
begin
FFocusedGroup := nil;
if Assigned(OldGroup) then
OldGroup.Focused := False;
end *)
end;
procedure TEasySelectionManager.SetFocusedItem(Value: TEasyItem);
var
ChangeFocus: Boolean;
OldItem: TEasyCollectionItem;
RectArray: TEasyRectArrayObject;
begin
OldItem := FFocusedItem;
if Assigned(Value) then
begin
if Value.Visible and Value.Enabled then
begin
if FFocusedItem <> Value then
begin
if Assigned(OldItem) then
OldItem.Focused := False;
ChangeFocus := True;
// The user may not have allowed the focus to change
if Assigned(OldItem) then
ChangeFocus := not OldItem.Focused;
if ChangeFocus then
begin
FFocusedItem := Value;
// Resize the Groups in case the full focus text was bigger than
// the group
Value.Focused := True;
// During Deletion this can lead to weird recurssion
if not Value.Destroying then
begin
Value.ItemRectArray(nil, OwnerListview.ScratchCanvas, RectArray);
// Rebuild the grid if the focused text will overlap the bottom of the
// group
if RectArray.FullTextRect.Bottom > Value.OwnerGroup.ClientRect.Bottom then
Value.OwnerListview.Groups.Rebuild(True);
end
end
end
end
end else
begin
FFocusedItem := nil;
if Assigned(OldItem) then
begin
if Assigned(OldItem) then
begin
OldItem.Focused := False;
// Resize the Groups in case the full focus text was bigger than
// the group
// During Deletion this can lead to weird recurssion
if not OldItem.Destroying then
begin
(* OwnerListview.Grid.CacheGroupInfo;
OwnerListview.Scrollbars.SetViewRect(OwnerListview.Grid.ViewRect, True); *)
end
end
end
end
end;
procedure TEasySelectionManager.SeTCommonMouseButton(Value: TCommonMouseButtons);
begin
FMouseButton := Value
end;
procedure TEasySelectionManager.SetFullCellPaint(Value: Boolean);
begin
if Value <> FFullCellPaint then
begin
FFullCellPaint := Value;
OwnerListview.SafeInvalidateRect(nil, False)
end
end;
procedure TEasySelectionManager.SetFullItemPaint(Value: Boolean);
begin
if Value <> FFullItemPaint then
begin
FFullItemPaint := Value;
OwnerListview.SafeInvalidateRect(nil, False)
end
end;
procedure TEasySelectionManager.SetGradient(const Value: Boolean);
begin
if FGradient <> Value then
begin
FGradient := Value;
OwnerListview.SafeInvalidateRect(nil, False)
end
end;
procedure TEasySelectionManager.SetGradientColorBottom(const Value: TColor);
begin
if FGradientColorBottom <> Value then
begin
FGradientColorBottom := Value;
OwnerListview.SafeInvalidateRect(nil, False)
end
end;
procedure TEasySelectionManager.SetGradientColorTop(const Value: TColor);
begin
if FGradientColorTop <> Value then
begin
FGradientColorTop := Value;
OwnerListview.SafeInvalidateRect(nil, False)
end
end;
procedure TEasySelectionManager.SetGroupSelections(Value: Boolean);
begin
if Value <> FGroupSelections then
begin
OwnerListview.BeginUpdate;
try
FGroupSelections := Value;
BuildSelectionGroupings(True)
finally
OwnerListview.EndUpdate
end
end
end;
procedure TEasySelectionManager.SetMouseButtonSelRect(Value: TCommonMouseButtons);
begin
OwnerListview.DragRect.MouseButton := Value
end;
procedure TEasySelectionManager.SetMultiSelect(const Value: Boolean);
begin
if FMultiSelect <> Value then
begin
FMultiSelect := Value;
ClearAll
end
end;
{ TEasyCheckManager }
function TEasyCheckManager.CheckedToArray: TEasyItemArray;
var
Item: TEasyItem;
i: Integer;
begin
SetLength(Result, Count);
Item := First;
i := 0;
while Assigned(Item) do
begin
Result[i] := Item;
Inc(i);
Item := Next(Item)
end
end;
procedure TEasyCheckManager.CheckAll;
//
// Checks all the Visible items in the EasyControl
//
var
i: Integer;
begin
for i := 0 to OwnerListview.Groups.Count - 1 do
OwnerListview.Groups.Groups[i].Checked := True
end;
procedure TEasyCheckManager.CheckAllInGroup(Group: TEasyGroup);
//
// Checks all the Visible items in a particular group
//
begin
Group.Checked := True
end;
function TEasyCheckManager.First: TEasyItem;
//
// Gets the first checked item in the control and prepares for the GetNext iteration
//
//var
// Found: Boolean;
// i: Integer;
begin
// Found := False;
// i := 0;
(* while (i < OwnerListview.UIObjects.ItemCount) and not Found do
begin
Result := OwnerListview.UIObjects.Items[i];
Found := Result.Checked;
if not Found then
Inc(i)
end;
if not Found then *)
Result := nil;
end;
function TEasyCheckManager.FirstInGroup(Group: TEasyGroup): TEasyCollectionItem;
//
// Gets the first checked item in a particular grouip and prepares for the GetNextInGroup iteration
//
var
Found: Boolean;
i: Integer;
begin
Result := nil;
Exit;
Found := False;
i := 0;
while (i < Group.Items.Count) and not Found do
begin
Result := Group.Items[i];
// By definition if the item is checked is must be visible
Found := Result.Checked;
if not Found then
Inc(i)
end;
if not Found then
Result := nil;
end;
function TEasyCheckManager.Next(Item: TEasyItem): TEasyItem;
//
// Gets the next checked item in the control, depends on GetFirst to be called first
//
//var
// Found: Boolean;
// i: Integer;
begin
// Found := False;
(* i := Item.VisibleIndex;
Inc(i);
while (i < OwnerListview.UIObjects.ItemCount) and not Found do
begin
Result := OwnerListview.UIObjects.Items[i];
Found := Result.Checked;
if not Found then
Inc(i)
end;
if not Found then *)
Result := nil;
end;
function TEasyCheckManager.NextInGroup(Item: TEasyItem): TEasyItem;
//
// Gets the next checked item in a particular group, depends on GetFirstInGroup to be called first
//
begin
Result := nil;
Assert(True = False, 'TEasyCheckManager.GetNextCheckedInGroup not implemented yet');
Exit;
end;
procedure TEasyCheckManager.DeleteChecked;
var
Items: TEasyItemArray;
i: Integer;
begin
OwnerListview.BeginUpdate;
try
Items := CheckedToArray;
// Set the item in the list to nil and free the item
try
for i := 0 to Length(Items) - 1 do
begin
Items[i].OwnerGroup.Items[Items[i].Index] := nil;
Items[i].Free;
end;
finally
// now pack the group lists to elimiate the nil pointers
for i := 0 to OwnerListview.Groups.Count - 1 do
OwnerListview.Groups[i].Items.FList.Pack;
end;
finally
OwnerListview.EndUpdate;
end
end;
procedure TEasyCheckManager.SetPendingObject(Value: TEasyCollectionItem);
begin
if Value <> FPendingObject then
begin
if Assigned(FPendingObject) then
FPendingObject.CheckPending := False;
FPendingObject := Value;
if Assigned(FPendingObject) then
FPendingObject.CheckPending := True;
end
end;
procedure TEasyCheckManager.UnCheckAll;
//
// Unchecks all Visible items in the control
//
var
i: Integer;
begin
OwnerListview.BeginUpdate;
try
for i := 0 to OwnerListview.Groups.Count - 1 do
OwnerListview.Groups.Groups[i].Checked := False;
finally
OwnerListview.EndUpdate;
end
end;
procedure TEasyCheckManager.UnCheckAllInGroup(Group: TEasyGroup);
//
// Unchecks all Visible items in a particular group
//
begin
OwnerListview.BeginUpdate;
try
Group.Checked := False
finally
OwnerListview.EndUpdate;
end
end;
{ TEasyScrollbarManager }
constructor TEasyScrollbarManager.Create(AnOwner: TCustomEasyListview);
begin
inherited;
FHorzEnabled := True;
FVertEnabled := True;
FSnapHorzView := True;
end;
destructor TEasyScrollbarManager.Destroy;
begin
inherited;
end;
function TEasyScrollbarManager.GetHorzBarVisible: Boolean;
begin
if Assigned(OwnerListview) and OwnerListview.HandleAllocated then
Result := GetWindowLong(OwnerListview.Handle, GWL_STYLE) and WS_HSCROLL <> 0
else
Result := False;
end;
function TEasyScrollbarManager.GetLine: Integer;
begin
Result := OwnerListview.Groups.CellHeight
end;
function TEasyScrollbarManager.GetMaxOffsetX: Integer;
var
ScrollTmp: Integer;
begin
Result := ViewWidth - OwnerListview.ClientWidth;
if (not OwnerListview.IsVertView) and (HorzBarVisible) then
begin
ScrollTmp := Result - (Result mod OwnerListview.CellSizes.List.Width);
Result := ScrollTmp + OwnerListview.CellSizes.List.Width;
end;
if Result < 0 then
Result := 0;
end;
function TEasyScrollbarManager.GetMaxOffsetY: Integer;
begin
Result := ViewHeight -
OwnerListview.ClientHeight +
OwnerListview.Header.RuntimeHeight {+
OwnerListview.Columns.Footer.SizeTotal};
if Result < 0 then
Result := 0;
end;
function TEasyScrollbarManager.GetVertBarVisible: Boolean;
begin
if Assigned(OwnerListview) and OwnerListview.HandleAllocated then
Result := GetWindowLong(OwnerListview.Handle, GWL_STYLE) and WS_VSCROLL <> 0
else
Result := False;
end;
function TEasyScrollbarManager.GetViewHeight: Integer;
begin
Result := ViewRect.Bottom - ViewRect.Top
end;
function TEasyScrollbarManager.GetViewWidth: Integer;
begin
Result := ViewRect.Right - ViewRect.Left
end;
function TEasyScrollbarManager.MapViewToWindow(ViewportPoint: TPoint; AccountForHeader: Boolean = True): TPoint;
begin
Result.X := ViewportPoint.X -
OffsetX;
Result.Y := ViewportPoint.Y -
OffsetY;
if AccountForHeader then
Inc(Result.Y, OwnerListview.Header.RuntimeHeight)
end;
function TEasyScrollbarManager.MapViewRectToWindowRect(ViewPortRect: TRect; AccountForHeader: Boolean = True): TRect;
begin
Result.TopLeft := MapViewToWindow(ViewPortrect.TopLeft, AccountForHeader);
Result.BottomRight := MapViewToWindow(ViewPortRect.BottomRight, AccountForHeader);
end;
function TEasyScrollbarManager.MapViewToWindow(ViewportPoint: TSmallPoint; AccountForHeader: Boolean = True): TPoint;
begin
Result := MapViewToWindow(SmallPointToPoint(ViewportPoint), AccountForHeader)
end;
function TEasyScrollbarManager.MapWindowToView(WindowPoint: TPoint; AccountForHeader: Boolean = True): TPoint;
begin
Result.X := WindowPoint.X + OffsetX;
Result.Y := WindowPoint.Y + OffsetY;
if AccountForHeader then
Dec(Result.Y, OwnerListview.Header.RuntimeHeight)
end;
function TEasyScrollbarManager.MapWindowRectToViewRect(WindowRect: TRect; AccountForHeader: Boolean = True): TRect;
begin
Result.TopLeft := MapWindowToView(WindowRect.TopLeft, AccountForHeader);
Result.BottomRight := MapWindowToView(WindowRect.BottomRight, AccountForHeader);
end;
function TEasyScrollbarManager.MapWindowToView(WindowPoint: TSmallPoint; AccountForHeader: Boolean = True): TPoint;
begin
Result := MapWindowToView(SmallPointToPoint(WindowPoint), AccountForHeader);
end;
procedure TEasyScrollbarManager.ReCalculateScrollbars(Redraw: Boolean;
Force: Boolean);
const
ALL_SCROLLFLAGS = SIF_PAGE or SIF_POS or SIF_RANGE;
var
Info: TScrollInfo;
HorzWasVisible, VertWasVisible, HorzNeeded, VertNeeded, RebuildNeeded: Boolean;
R: TRect;
begin
// Performance hit if not checking for update.
if not Rebuilding and (Assigned(OwnerListview) and OwnerListview.HandleAllocated) and
((OwnerListview.UpdateCount = 0) or Force) then
begin
FRebuilding := True;
HorzWasVisible := False;
VertWasVisible := False;
try
// If the window is resizing our offset may become invalid and we need to
// "pull" the offset with the resize
ValidateOffsets(FOffsetX, FOffsetY);
HorzWasVisible := HorzBarVisible;
HorzNeeded := (ViewWidth - 1 > OwnerListview.ClientWidth) and (OwnerListview.Height > GetSystemMetrics(SM_CYHSCROLL));
VertWasVisible := VertBarVisible;
VertNeeded := (ViewHeight + OwnerListview.Header.RuntimeHeight - 1 > OwnerListview.ClientHeight) and (OwnerListview.Width > GetSystemMetrics(SM_CYVSCROLL));
GetClientRect(OwnerListview.Handle, R);
RebuildNeeded := False;
if HorzEnabled then
begin
if HorzWasVisible xor HorzNeeded then
begin
ShowScrollBar(OwnerListview.Handle, SB_HORZ, HorzNeeded);
RebuildNeeded := True;
end
end else
ShowScrollBar(OwnerListview.Handle, SB_HORZ, False);
if VertEnabled then
begin
if VertWasVisible xor VertNeeded then
begin
ShowScrollBar(OwnerListview.Handle, SB_VERT, VertNeeded);
RebuildNeeded := True;
end;
end else
ShowScrollBar(OwnerListview.Handle, SB_VERT, False);;
if RebuildNeeded then
OwnerListview.Groups.Rebuild(True);
FillChar(Info, SizeOf(Info), #0);
Info.cbSize := SizeOf(Info);
Info.fMask := ALL_SCROLLFLAGS;
Info.nMin := 0;
if VertEnabled and VertBarVisible then
begin
Info.nMax := ViewHeight + OwnerListview.Header.RuntimeHeight - 1;
Info.nPos := Abs(OffsetY);
if OwnerListview.ClientHeight < 0 then
Info.nPage := 0
else
Info.nPage := OwnerListview.ClientHeight;
end else
begin
Info.nMax := 0;
Info.nPos := 0;
Info.nPage := 0;
end;
SetScrollInfo(OwnerListview.Handle, SB_VERT, Info, Redraw);
FillChar(Info, SizeOf(Info), #0);
Info.cbSize := SizeOf(Info);
Info.fMask := ALL_SCROLLFLAGS;
Info.nMin := 0;
if HorzEnabled and HorzBarVisible then
begin
Info.nMax := ViewWidth - 1;
Info.nPos := Abs(OffsetX);
if OwnerListview.ClientWidth < 0 then
Info.nPage := 0
else
Info.nPage := OwnerListview.ClientWidth;
end else
begin
Info.nMax := 0;
Info.nPos := 0;
Info.nPage := 0;
end;
SetScrollInfo(OwnerListview.Handle, SB_HORZ, Info, Redraw);
// If the window is resizing our offset may become invalid and we need to
// "pull" the offset with the resize
ValidateOffsets(FOffsetX, FOffsetY);
finally
FRebuilding := False;
if (not HorzWasVisible and HorzBarVisible) or (not VertWasVisible and VertBarVisible) then
RedrawWindow(OwnerListview.Handle, nil, 0, RDW_FRAME or RDW_INVALIDATE or RDW_ERASENOW);
end
end
end;
procedure TEasyScrollbarManager.SetHorzEnabled(
const Value: Boolean);
begin
if FHorzEnabled <> Value then
begin
FHorzEnabled := Value;
ReCalculateScrollbars(True, False);
OwnerListview.SafeInvalidateRect(nil, False)
end
end;
procedure TEasyScrollbarManager.SetOffsetX(const Value: Integer);
begin
if FOffsetX <> Value then
Scroll(Value - OffsetX, 0);
end;
procedure TEasyScrollbarManager.SetOffsetY(const Value: Integer);
begin
if FOffsetY <> Value then
Scroll(0, Value - OffsetY);
end;
procedure TEasyScrollbarManager.SetVertEnabled(
const Value: Boolean);
begin
if FVertEnabled <> Value then
begin
FVertEnabled := Value;
ReCalculateScrollbars(True, False);
OwnerListview.SafeInvalidateRect(nil, False)
end
end;
procedure TEasyScrollbarManager.SetViewRect(AViewRect: TRect; InvalidateWindow: Boolean);
var
WasX, WasY: Boolean;
begin
if not EqualRect(AViewRect, FViewRect) then
begin
WasX := HorzBarVisible;
WasY := VertBarVisible;
FViewRect := AViewRect;
ReCalculateScrollbars(True, False);
if (InvalidateWindow or (WasX and not HorzBarVisible) or (WasY and not VertBarVisible)) then
OwnerListview.SafeInvalidateRect(nil, False);
end else
if InvalidateWindow then
OwnerListview.SafeInvalidateRect(nil, False);
end;
procedure TEasyScrollbarManager.ValidateOffsets(var AnOffsetX, AnOffsetY: Integer);
// "Pulls" the offset to keep in sync with the client window. This is especially
// for when the window is resizing and the offset is near the bottom of the page.
// Without this the Scroll Manager could detect that the scrollbars are not needed
// any more and hide them leaving the window scrolled to the last known point!
var
LastCol: Boolean;
begin
if Assigned(OwnerListview) then
begin
if SnapHorzView and not OwnerListview.IsVertView then
begin
LastCol := AnOffsetX > ViewWidth - OwnerListview.CellSizes.List.Width;
if AnOffsetX mod OwnerListview.CellSizes.List.Width <> 0 then
AnOffsetX := OwnerListview.CellSizes.List.Width * (AnOffsetX div OwnerListview.CellSizes.List.Width);
if (AnOffsetX mod OwnerListview.CellSizes.List.Width > OwnerListview.CellSizes.List.Width div 2) or LastCol then
AnOffsetX := AnOffsetX + OwnerListview.CellSizes.List.Width
end;
if AnOffsetY > MaxOffsetY then
AnOffsetY := MaxOffsetY;
if AnOffsetX > MaxOffsetX then
AnOffsetX := MaxOffsetX;
if AnOffsetY < 0 then
AnOffsetY := 0;
if AnOffsetX < 0 then
AnOffsetX := 0;
end else
begin
AnOffsetX := 0;
AnOffsetY := 0
end
end;
function TEasyScrollbarManager.ViewableViewportRect: TRect;
//
// Returns, in Viewport Coordinates, the rectangle that is current visible to
// the user in the window.
//
begin
Result := MapWindowRectToViewRect(OwnerListview.ClientRect)
end;
procedure TEasyScrollbarManager.WMHScroll(var Msg: TWMVScroll);
// Called from the WM_HSCROLL message of the owner window to implement the scroll
var
Info: TScrollInfo;
ClientR: TRect;
DeltaX: Integer;
begin
if Assigned(OwnerListview) then
begin
DeltaX := 0;
// Get the 32 Bit Position
FillChar(Info, SizeOf(Info), #0);
Info.cbSize := SizeOf(Info);
Info.fMask := SIF_POS or SIF_TRACKPOS;
GetScrollInfo(OwnerListview.Handle, SB_HORZ, Info);
ClientR :=OwnerListview.ClientRect;
if not OwnerListview.IsVertView and SnapHorzView then
begin
case Msg.ScrollCode of
SB_BOTTOM: DeltaX := (ViewRect.Right - ViewRect.Left) - OffsetX;
SB_ENDSCROLL: DeltaX := 0;
SB_LINEDOWN: DeltaX := OwnerListview.CellSizes.List.Width;
SB_LINEUP: DeltaX := -OwnerListview.CellSizes.List.Width;
SB_PAGEDOWN: DeltaX := OwnerListview.CellSizes.List.Width;
SB_PAGEUP: DeltaX := -OwnerListview.CellSizes.List.Width;
SB_THUMBPOSITION:
begin
DeltaX := Info.nPos - OffsetX;
DeltaX := (DeltaX - (DeltaX mod OwnerListview.CellSizes.List.Width));
end;
SB_THUMBTRACK:
begin
DeltaX := Info.nTrackPos - OffsetX;
if ((MaxOffsetX - Info.nTrackPos) < OwnerListview.CellSizes.List.Width) then
DeltaX := MaxOffsetX
else
DeltaX := (DeltaX - (DeltaX mod OwnerListview.CellSizes.List.Width));
end;
SB_TOP: DeltaX := -(ViewRect.Right - ViewRect.Left) - OffsetX;
end // case
end else
begin
case Msg.ScrollCode of
SB_BOTTOM: DeltaX := (ViewRect.Right - ViewRect.Left) - OffsetX;
SB_ENDSCROLL: DeltaX := 0;
SB_LINEDOWN: DeltaX := Line;
SB_LINEUP: DeltaX := -Line;
SB_PAGEDOWN: DeltaX := ClientR.Right - ClientR.Left;
SB_PAGEUP: DeltaX := -(ClientR.Right - ClientR.Left);
SB_THUMBPOSITION: DeltaX := Info.nTrackPos - OffsetX;
SB_THUMBTRACK: DeltaX := Info.nTrackPos - OffsetX;
SB_TOP: DeltaX := -OffsetY
end;
end;
Scroll(DeltaX, 0);
end else
OffsetX := 0
end;
procedure TEasyScrollbarManager.WMKeyDown(var Msg: TWMKeyDown);
// Call from the WM_KEYDOWN message of the owner window to check for keys that
// are related to scrolling the window
var
NewMsg: TWMScroll;
SkipScroll: Boolean;
begin
FillChar(NewMsg, SizeOf(NewMsg), #0);
SkipScroll := False;
case Msg.CharCode of
VK_HOME: NewMsg.ScrollCode := SB_TOP;
VK_END: NewMsg.ScrollCode := SB_BOTTOM;
VK_NEXT: NewMsg.ScrollCode := SB_PAGEDOWN;
VK_PRIOR: NewMsg.ScrollCode := SB_PAGEUP;
VK_UP: NewMsg.ScrollCode := SB_LINEUP;
VK_DOWN: NewMsg.ScrollCode := SB_LINEDOWN;
VK_LEFT: NewMsg.ScrollCode := SB_LINEUP;
VK_RIGHT: NewMsg.ScrollCode := SB_LINEDOWN;
else
SkipScroll := True;
end;
if not SkipScroll then
begin
if Msg.CharCode in [VK_LEFT, VK_RIGHT] then
WMHScroll(NewMsg)
else
WMVScroll(NewMsg)
end
end;
procedure TEasyScrollbarManager.WMVScroll(var Msg: TWMVScroll);
// Call from the WM_VSCROLL message of the owner window to implement the scroll
var
Info: TScrollInfo;
ClientR: TRect;
DeltaY: Integer;
begin
if Assigned(OwnerListview) then
begin
DeltaY := 0;
// Get the 32 Bit Position
FillChar(Info, SizeOf(Info), #0);
Info.cbSize := SizeOf(Info);
Info.fMask := SIF_TRACKPOS;
GetScrollInfo(OwnerListview.Handle, SB_VERT, Info);
ClientR := OwnerListview.ClientRect;
case Msg.ScrollCode of
SB_BOTTOM: DeltaY := (ViewRect.Bottom - ViewRect.Top) - OffsetY;
SB_ENDSCROLL: DeltaY := 0;
SB_LINEDOWN: DeltaY := Line;
SB_LINEUP: DeltaY := -Line;
SB_PAGEDOWN: DeltaY := (ClientR.Bottom - ClientR.Top);
SB_PAGEUP: DeltaY := -(ClientR.Bottom - ClientR.Top);
SB_THUMBPOSITION: DeltaY := Info.nTrackPos - OffsetY;
SB_THUMBTRACK: DeltaY := Info.nTrackPos - OffsetY;
SB_TOP: DeltaY := -OffsetY;
end;
Scroll(0, DeltaY);
end else
OffsetY := 0
end;
procedure TEasyScrollbarManager.Scroll(DeltaX, DeltaY: Integer);
var
OldOffsetX, OldOffsetY: Integer;
begin
OldOffsetY := OffsetY;
OldOffsetX := OffsetX;
FOffsetX := OffsetX + DeltaX;
FOffsetY := OffsetY + DeltaY;
ValidateOffsets(FOffsetX, FOffsetY);
if (OffsetX <> OldOffsetX) or (OffsetY <> OldOffsetY) then
begin
ReCalculateScrollbars(True, True);
OwnerListview.DoScroll(OldOffsetX - FOffsetX, OldOffsetY - FOffsetY);
OwnerListview.SafeInvalidateRect(nil, False);
end
end;
{ TEasyBackgroundManager }
procedure TEasyBackgroundManager.Assign(Source: TPersistent);
var
ASource: TEasyBackgroundManager;
begin
if Source is TEasyBackgroundManager then
begin
ASource := TEasyBackgroundManager(Source);
Image.Assign(ASource.Image);
FEnabled := ASource.Enabled;
FOffsetX := ASource.OffsetX;
FOffsetY := ASource.OffsetY;
FTile := ASource.Tile;
end
end;
procedure TEasyBackgroundManager.AssignTo(Target: TPersistent);
var
ATarget: TEasyBackgroundManager;
begin
if Target is TEasyBackgroundManager then
begin
ATarget := TEasyBackgroundManager(Target);
ATarget.Image.Assign(Image);
ATarget.FEnabled := Enabled;
ATarget.FOffsetX := OffsetX;
ATarget.FOffsetY := OffsetY;
ATarget.FTile := Tile;
end
end;
procedure TEasyBackgroundManager.ChangeBitmapBits(Sender: TObject);
begin
Image.PixelFormat := pf32Bit;
AlphaImage.PixelFormat := pf32Bit;
OwnerListview.SafeInvalidateRect(nil, False);
end;
constructor TEasyBackgroundManager.Create(AnOwner: TCustomEasyListview);
begin
inherited;
FImage := TBitmap.Create;
FImage.PixelFormat := pf32Bit;
FImage.OnChange := ChangeBitmapBits;
FAlphaImage := TBitmap.Create;
FAlphaImage.PixelFormat := pf32Bit;
FAlphaImage.OnChange := ChangeBitmapBits;
FTile := True;
FOffsetX := 0;
FOffsetY := 0;
FBlendMode := cbmConstantAlphaAndColor;
FBlendAlpha := 128;
FAlphaBlend := False;
FCaptionAlignment := taCenter;
FCaptionVAlignment := cvaCenter;
FCaptionSingleLine := True;
FCaptionShowOnlyWhenEmpty := True;
FAlphaBlender := TEasyAlphaBlender.Create;
end;
destructor TEasyBackgroundManager.Destroy;
begin
FImage.OnChange := nil;
FreeAndNil(FImage);
FreeAndNil(FAlphaImage);
FreeAndNil(FAlphaBlender);
inherited;
end;
procedure TEasyBackgroundManager.PaintTo(ACanvas: TCanvas; ARect: TRect; PaintDefault: Boolean);
var
Row, Column, X, Y: Integer;
BkGndR, TempR: TRect;
OldOrigin: TPoint;
Bitmap: TBitmap;
DrawTextFlags: TCommonDrawTextWFlags;
ShowCaption, DoDefault: Boolean;
begin
DoDefault := True;
OwnerListview.DoPaintBkGnd(ACanvas, ARect, AlphaBlender, DoDefault);
if DoDefault then
begin
if Assigned(Image) and not Image.Empty and Enabled then
begin
ACanvas.Brush.Color := OwnerListview.Color;
ACanvas.FillRect(ARect);
if AlphaBlend and HasMMX then
begin
Bitmap := TBitmap.Create;
Bitmap.Width := Image.Width;
Bitmap.Height := Image.Height;
Bitmap.PixelFormat := pf32Bit;
Bitmap.Assign(Image);
if BlendMode = cbmConstantAlphaAndColor then
MPCommonUtilities.AlphaBlend(0, Bitmap.Canvas.Handle,
Rect(0, 0, Bitmap.Width, Bitmap.Height), Point(0, 0),
BlendMode, BlendAlpha, ColorToRGB(OwnerListview.Color))
else
if (Image.Width = AlphaImage.Width) and (Image.Height = AlphaImage.Height)
then
// AlphaBlend it with the background bitmap
MPCommonUtilities.AlphaBlend(AlphaImage.Canvas.Handle, Bitmap.Canvas.Handle,
Rect(0, 0, Bitmap.Width, Bitmap.Height), Point(0, 0),
BlendMode, BlendAlpha, ColorToRGB(OwnerListview.Color));
end else
Bitmap := Image;
Bitmap.Canvas.Lock;
try
// Needed to make IntersectRect work correctly.
InflateRect(ARect, Bitmap.Width, Bitmap.Height);
if Tile then
begin
// Need to keep BitBlt from needing negative numbers. It will not work with them
X := OffsetX mod Bitmap.Width;
if OffsetX > 0 then
X := -(Bitmap.Width - X);
Y := OffsetY mod Bitmap.Height;
if OffsetY > 0 then
Y := -(Bitmap.Height - Y);
SetViewportOrgEx(ACanvas.Handle, X, Y, @OldOrigin);
try
BkGndR := Rect(0, 0, Bitmap.Width, Bitmap.Height);
for Row := 0 to (OwnerListview.ClientHeight div Bitmap.Height + 1) do
begin
for Column := 0 to (OwnerListview.ClientWidth div Bitmap.Width + 1) do
begin
if IntersectRect(TempR, ARect, BkGndR) then
begin
if Transparent then
ACanvas.Draw(BkGndR.Left, BkGndR.Top, Bitmap)
else
BitBlt(ACanvas.Handle, BkGndR.Left, BkGndR.Top, BkGndR.Right, BkGndR.Bottom,
Bitmap.Canvas.Handle, 0, 0, SRCCOPY)
end;
OffsetRect(BkGndR, Bitmap.Width, 0);
end;
OffsetRect(BkGndR, -BkGndR.Left, Bitmap.Height);
end;
finally
SetViewportOrgEx(ACanvas.Handle, OldOrigin.X, OldOrigin.Y, nil);
InflateRect(ARect, -Bitmap.Width, -Bitmap.Height);
end
end else
begin
SetViewportOrgEx(ACanvas.Handle, OffsetX, OffsetY, @OldOrigin);
BkGndR := Rect(0, 0, Bitmap.Width, Bitmap.Height);
if Transparent then
ACanvas.Draw(BkGndR.Left, BkGndR.Top, Bitmap)
else
BitBlt(ACanvas.Handle, BkGndR.Left, BkGndR.Top, BkGndR.Right, BkGndR.Bottom,
Bitmap.Canvas.Handle, 0, 0, SRCCOPY);
SetViewportOrgEx(ACanvas.Handle, OldOrigin.X, OldOrigin.Y, nil);
end
finally
Bitmap.Canvas.UnLock;
if AlphaBlend then
Bitmap.Free
end
end else
if PaintDefault then
begin
ACanvas.Brush.Color := OwnerListview.Color;
ACanvas.FillRect(ARect);
end;
if CaptionShow then
begin
if CaptionShowOnlyWhenEmpty then
ShowCaption := (OwnerListview.Groups.ItemCount = 0) and (Caption <> '')
else
ShowCaption := Caption <> '';
if ShowCaption then
begin
BkGndR := OwnerListview.ClientRect;
if IntersectRect(TempR, ARect, BkGndR) then
begin
InflateRect(BkGndR, -8, -8);
ACanvas.Font.Assign(OwnerListview.Font);
ACanvas.Brush.Style := bsClear;
DrawTextFlags := [dtEndEllipsis];
case CaptionAlignment of
taLeftJustify: Include(DrawTextFlags, dtLeft);
taRightJustify: Include(DrawTextFlags, dtRight);
taCenter: Include(DrawTextFlags, dtCenter);
end;
case CaptionVAlignment of
cvaTop: Include(DrawTextFlags, dtTop);
cvaBottom: Include(DrawTextFlags, dtBottom);
cvaCenter: Include(DrawTextFlags, dtVCenter);
end;
if CaptionSingleLine then
Include(DrawTextFlags, dtSingleLine);
DrawTextWEx(ACanvas.Handle, Caption, BkGndR, DrawTextFlags, -1);
end
end
end
end
end;
procedure TEasyBackgroundManager.SetAlphaBlend(const Value: Boolean);
begin
if FAlphaBlend <> Value then
begin
FAlphaBlend := Value;
OwnerListview.SafeInvalidateRect(nil, False)
end
end;
procedure TEasyBackgroundManager.SetAlphaImage(const Value: TBitmap);
begin
FAlphaImage.Assign(Value);
OwnerListview.SafeInvalidateRect(nil, False)
end;
procedure TEasyBackgroundManager.SetBlendAlpha(const Value: Integer);
begin
if FBlendAlpha <> Value then
begin
FBlendAlpha := Value;
OwnerListview.SafeInvalidateRect(nil, False)
end
end;
procedure TEasyBackgroundManager.SetCaption(const Value: WideString);
begin
if FCaption <> Value then
begin
FCaption := Value;
OwnerListview.SafeInvalidateRect(nil, False)
end
end;
procedure TEasyBackgroundManager.SetCaptionAlignment(const Value: TAlignment);
begin
if FCaptionAlignment <> Value then
begin
FCaptionAlignment := Value;
OwnerListview.SafeInvalidateRect(nil, False)
end
end;
procedure TEasyBackgroundManager.SetCaptionShow(const Value: Boolean);
begin
if FCaptionShow <> Value then
begin
FCaptionShow := Value;
OwnerListview.SafeInvalidateRect(nil, False)
end
end;
procedure TEasyBackgroundManager.SetCaptionShowOnlyWhenEmpty(const Value: Boolean);
begin
if FCaptionShowOnlyWhenEmpty <> Value then
begin
FCaptionShowOnlyWhenEmpty := Value;
OwnerListview.SafeInvalidateRect(nil, False)
end
end;
procedure TEasyBackgroundManager.SetCaptionSingleLine(const Value: Boolean);
begin
if FCaptionSingleLine <> Value then
begin
FCaptionSingleLine := Value;
OwnerListview.SafeInvalidateRect(nil, False)
end
end;
procedure TEasyBackgroundManager.SetCaptionVAlignment(const Value: TCommonVAlignment);
begin
if FCaptionVAlignment <> Value then
begin
FCaptionVAlignment := Value;
OwnerListview.SafeInvalidateRect(nil, False)
end
end;
procedure TEasyBackgroundManager.SetCommonBlendMode(const Value: TCommonBlendMode);
begin
if FBlendMode <> Value then
begin
FBlendMode := Value;
OwnerListview.SafeInvalidateRect(nil, False)
end
end;
procedure TEasyBackgroundManager.SetEnabled(const Value: Boolean);
begin
if FEnabled <> Value then
begin
FEnabled := Value;
OwnerListview.SafeInvalidateRect(nil, False)
end
end;
procedure TEasyBackgroundManager.SetImage(const Value: TBitmap);
begin
FImage.Assign(Value);
OwnerListview.SafeInvalidateRect(nil, False)
end;
procedure TEasyBackgroundManager.SetOffsetX(const Value: Integer);
begin
if FOffsetX <> Value then
begin
FOffsetX := Value;
OwnerListview.SafeInvalidateRect(nil, False)
end
end;
procedure TEasyBackgroundManager.SetOffsetY(const Value: Integer);
begin
if FOffsetY <> Value then
begin
FOffsetY := Value;
OwnerListview.SafeInvalidateRect(nil, False)
end
end;
procedure TEasyBackgroundManager.SetTile(const Value: Boolean);
begin
if FTile <> Value then
begin
FTile := Value;
OwnerListview.SafeInvalidateRect(nil, False)
end
end;
procedure TEasyBackgroundManager.SetTransparent(const Value: Boolean);
begin
if FTransparent <> Value then
begin
FTransparent := Value;
OwnerListview.SafeInvalidateRect(nil, False);
Image.Transparent := Value;
Image.TransparentMode := tmAuto;
end
end;
procedure TEasyBackgroundManager.WMWindowPosChanging(var Msg: TWMWindowPosChanging);
begin
if OffsetTrack then
begin
// If SWP_NOSIZE is in the flags then the cx, cy params can be garbage
if Msg.WindowPos.flags and SWP_NOSIZE = 0 then
begin
FOffsetX := FOffsetX + (Msg.WindowPos.cx - OwnerListview.Width);
FOffsetY := FOffsetY + (Msg.WindowPos.cy - OwnerListview.Height);
end
end
end;
function TEasyDropTargetManager.DragEnter(const dataObj: IDataObject;
grfKeyState: Integer; pt: TPoint; var dwEffect: Integer): HResult;
var
Effect: TCommonDropEffect;
Effects: TCommonDropEffects;
Keys: TCommonKeyStates;
StgMedium: TStgMedium;
begin
if Assigned(DropTargetHelper) then
DropTargetHelper.DragEnter(Owner.Handle, dataObj, Pt, dwEffect);
if Owner.DragManager.Enabled then
begin
Keys := KeyToKeyStates(grfKeyState);
Effects := DropEffectToDropEffectStates(dwEffect);
// Get the "Windows Style" effect with the key modifiers
Effect := KeyStateToDropEffect(Keys);
Owner.DoOLEDropTargetDragEnter(dataObj, KeyToKeyStates(grfKeyState), pt, DropEffectToDropEffectStates(dwEffect), Effect);
// Decide if this is a Header Drag and Drop or an Item Drag and Drop
// Note that if we use a Windows supplied IDataObject it will return TRUE for QueryGetData
// so we must really try to get the data to be sure
if Succeeded(dataObj.GetData(HeaderClipFormat, StgMedium)) then
DragManager := Owner.Header.DragManager
else
DragManager := Owner.DragManager;
if Assigned(DragManager) then
DragManager.DragEnter(dataObj, nil, Owner.ScreenToClient(pt), Keys, Effect);
dwEffect := DropEffectStateToDropEffect(Effect);
end else
dwEffect := DROPEFFECT_NONE;
Result := S_OK;
end;
function TEasyDropTargetManager.DragLeave: HResult;
begin
if Assigned(DropTargetHelper) then
DropTargetHelper.DragLeave;
Owner.DoOLEDropTargetDragLeave;
// Just pass some dummy parameters as they are not important for OLE drag drop
if Assigned(DragManager) then
DragManager.DragEnd(nil, Point(0, 0), []);
Result := S_OK
end;
function TEasyDropTargetManager.DragOver(grfKeyState: Integer; pt: TPoint;
var dwEffect: Integer): HResult;
var
Effect: TCommonDropEffect;
Effects: TCommonDropEffects;
Keys: TCommonKeyStates;
begin
if Assigned(DropTargetHelper) then
DropTargetHelper.DragOver(Pt, dwEffect);
if Owner.DragManager.Enabled then
begin
Keys := KeyToKeyStates(grfKeyState);
Effects := DropEffectToDropEffectStates(dwEffect);
// Get the "Windows Style" effect with the key modifiers
Effect := KeyStateToDropEffect(Keys);
Owner.DoOLEDropTargetDragOver(KeyToKeyStates(grfKeyState), pt, Effects, Effect);
if Assigned(DragManager) then
DragManager.Drag(nil, Owner.ScreenToClient(pt), Keys, Effect);
dwEffect := DropEffectStateToDropEffect(Effect);
end else
dwEffect := DROPEFFECT_NONE;
Result := S_OK
end;
function TEasyDropTargetManager.Drop(const dataObj: IDataObject;
grfKeyState: Integer; pt: TPoint; var dwEffect: Integer): HResult;
var
Effect: TCommonDropEffect;
Effects: TCommonDropEffects;
Keys: TCommonKeyStates;
Handled: Boolean;
begin
if Assigned(DropTargetHelper) then
DropTargetHelper.Drop(dataObj, Pt, dwEffect);
Keys := KeyToKeyStates(grfKeyState);
Effects := DropEffectToDropEffectStates(dwEffect);
// Get the "Windows Style" effect with the key modifiers
Effect := KeyStateToDropEffect(Keys);
Handled := False;
Owner.DoOLEDropTargetDragDrop(dataObj, KeyToKeyStates(grfKeyState), pt, DropEffectToDropEffectStates(dwEffect), Effect, Handled);
if Assigned(DragManager) and not Handled then
DragManager.DragDrop(Owner.ScreenToClient(pt), Keys, Effect);
dwEffect := DropEffectStateToDropEffect(Effect);
Result := S_OK
end;
function TEasyDropTargetManager.GetDropTargetHelper: IDropTargetHelper;
begin
if not Assigned(FDropTargetHelper) and IsWin2000 then
if CoCreateInstance(CLSID_DragDropHelper, nil, CLSCTX_INPROC_SERVER or CLSCTX_LOCAL_SERVER, IID_IDropTargetHelper, FDropTargetHelper) <> S_OK then
FDropTargetHelper := nil;
Result := FDropTargetHelper
end;
{ TEasyDropSourceManager }
function TEasyDropSourceManager.GiveFeedback(dwEffect: Integer): HResult;
var
UseDefaultCursors: Boolean;
begin
Result := DRAGDROP_S_USEDEFAULTCURSORS;
UseDefaultCursors := True;
Owner.DoOLEDropSourceGiveFeedback(DropEffectToDropEffectStates(dwEffect), UseDefaultCursors);
// The application has set the cursor style
if not UseDefaultCursors then
Result := S_OK
end;
function TEasyDropSourceManager.QueryContinueDrag(fEscapePressed: BOOL;
grfKeyState: Integer): HResult;
var
QueryResult: TEasyQueryDragResult;
KeyStates: TCommonKeyStates;
begin
KeyStates := KeyToKeyStates(grfKeyState);
if fEscapePressed then
QueryResult := eqdrQuit
else begin
if cksButton in KeyStates then
QueryResult := eqdrContinue
else
QueryResult := eqdrQuit
end;
// If no buttons are down anymore then the user dropped the objects
if not(cksButton in KeyStates) then
QueryResult := eqdrDrop;
// Allow the application to modify if desired
Owner.DoOLEDropSourceQueryContineDrag(fEscapePressed, KeyStates, QueryResult);
if QueryResult = eqdrQuit then
Result := DRAGDROP_S_CANCEL
else
if QueryResult = eqdrContinue then
Result := S_OK
else
if QueryResult = eqdrDrop then
Result := DRAGDROP_S_DROP
else
Result := E_UNEXPECTED
end;
function TCustomEasyDragManagerBase.DoPtInAutoScrollLeftRegion(WindowPoint: TPoint): Boolean;
begin
Result := False;
end;
function TCustomEasyDragManagerBase.DoPtInAutoScrollRightRegion(WindowPoint: TPoint): Boolean;
begin
Result := False;
end;
{ TEasyBaseDragManager }
procedure TCustomEasyDragManagerBase.AutoScrollWindow;
// This is called to autoscroll the window
var
Pt: TPoint;
begin
if Assigned(OwnerListview.Scrollbars) and OwnerListview.HandleAllocated then
begin
// Only scroll after an initial delay is met. This is defined as the mouse
// is in constantly the autoscroll area for AutoScrollDelay time
if AutoScrollDelayMet then
begin
// It is just easier to grab the mouse position on the screen to do the
// autoscroll for various operation (drag drop, drag select, etc.)
Pt := OwnerListview.ScreenToClient(Mouse.CursorPos);
if PtInAutoScrollUpRegion(Pt) then
DoAutoScroll(0, -(ScrollDeltaUp(Pt) * AutoScrollAccelerator))
else
if PtInAutoScrollDownRegion(Pt) then
DoAutoScroll(0, ScrollDeltaDown(Pt) * AutoScrollAccelerator);
if OwnerListview.Scrollbars.SnapHorzView then
begin
if PtInAutoScrollLeftRegion(Pt) then
DoAutoScroll(-(OwnerListview.CellSizes.List.Width), 0)
else
if PtInAutoScrollRightRegion(Pt) then
DoAutoScroll(OwnerListview.CellSizes.List.Width, 0)
end else
begin
if PtInAutoScrollLeftRegion(Pt) then
DoAutoScroll(-(ScrollDeltaLeft(Pt) * AutoScrollAccelerator), 0)
else
if PtInAutoScrollRightRegion(Pt) then
DoAutoScroll(ScrollDeltaRight(Pt) * AutoScrollAccelerator, 0)
end
end
end;
end;
procedure TCustomEasyDragManagerBase.BeginDrag(WindowPoint: TPoint; KeyState: TCommonKeyStates);
begin
DoDragBegin(WindowPoint, KeyState);
end;
constructor TCustomEasyDragManagerBase.Create(AnOwner: TCustomEasyListview);
begin
inherited;
FAutoScrollDelay := _AUTOSCROLLDELAY;
FAutoScrollTime := _AUTOSCROLLTIME;
FAutoScroll := True;
FAutoScrollAccelerator := 2;
FAutoScrollMargin := 15;
FMouseButton := [cmbLeft];
end;
destructor TCustomEasyDragManagerBase.Destroy;
begin
inherited;
end;
procedure TCustomEasyDragManagerBase.DoAfterAutoScroll;
begin
end;
procedure TCustomEasyDragManagerBase.DoAutoScroll(DeltaX, DeltaY: Integer);
var
Msg: TWMMouse;
// Usually called from AutoScrollWindow which calcualate how to do the scroll.
begin
// Need to flag the controls paint method to not worry about the selection
// rect as we take care of it in the auto scroll
DoBeforeAutoScroll;
Include(FDragState, edmsAutoScrolling);
OwnerListview.Scrollbars.Scroll(DeltaX, DeltaY);
UpdateAfterAutoScroll;
// Need to fake a mouse move to update any drag selection after a scroll
Msg.Pos := PointToSmallPoint( OwnerListview.ScreenToClient(Mouse.CursorPos));
Msg.Keys := 0;
Msg.Msg := WM_MOUSEMOVE;
OwnerListview.WMMouseMove(Msg);
Exclude(FDragState, edmsAutoScrolling);
DoAfterAutoScroll;
end;
procedure TCustomEasyDragManagerBase.DoBeforeAutoScroll;
begin
end;
procedure TCustomEasyDragManagerBase.DoDrag(Canvas: TCanvas; WindowPoint: TPoint; KeyState: TCommonKeyStates; var Effects: TCommonDropEffect);
begin
end;
procedure TCustomEasyDragManagerBase.DoDragBegin(WindowPoint: TPoint; KeyState: TCommonKeyStates);
begin
end;
procedure TCustomEasyDragManagerBase.DoDragDrop(WindowPoint: TPoint; KeyState: TCommonKeyStates; var Effects: TCommonDropEffect);
begin
end;
procedure TCustomEasyDragManagerBase.DoDragEnd(Canvas: TCanvas; WindowPoint: TPoint; KeyState: TCommonKeyStates);
begin
end;
procedure TCustomEasyDragManagerBase.DoDragEnter(const DataObject: IDataObject; Canvas: TCanvas; WindowPoint: TPoint; KeyState: TCommonKeyStates; var Effects: TCommonDropEffect);
begin
end;
procedure TCustomEasyDragManagerBase.DoEnable(Enable: Boolean);
begin
end;
procedure TCustomEasyDragManagerBase.DoGetDragImage(Bitmap: TBitmap; DragStartPt: TPoint; var HotSpot: TPoint; var TransparentColor: TColor; var Handled: Boolean);
begin
end;
procedure TCustomEasyDragManagerBase.DoOLEDragEnd(const ADataObject: IDataObject; DragResult: TCommonOLEDragResult; ResultEffect: TCommonDropEffects; KeyStates: TCommonKeyStates);
begin
end;
procedure TCustomEasyDragManagerBase.DoOLEDragStart(const ADataObject: IDataObject; var AvailableEffects: TCommonDropEffects; var AllowDrag: Boolean);
begin
end;
function TCustomEasyDragManagerBase.DoPtInAutoScrollDownRegion(WindowPoint: TPoint): Boolean;
begin
Result := False
end;
function TCustomEasyDragManagerBase.DoPtInAutoScrollUpRegion(WindowPoint: TPoint): Boolean;
begin
Result := False
end;
procedure TCustomEasyDragManagerBase.Drag(Canvas: TCanvas; WindowPoint: TPoint; KeyState: TCommonKeyStates; var Effects: TCommonDropEffect);
begin
// Watch for an auto scroll
if AutoScroll then
begin
// If the mouse is not in the window start the timer and prepare for autoscroll
// If is then reset the flags and wait for the next time the mouse leaves the window
if PtInAutoScrollRegion(WindowPoint) then
Timer.Enabled := True
else begin
FAutoScrollDelayMet := False;
Timer.Enabled := False
end;
end;
LastKeyState := KeyState;
DoDrag(Canvas, WindowPoint, KeyState, Effects)
end;
procedure TCustomEasyDragManagerBase.DragDrop(WindowPoint: TPoint; KeyState: TCommonKeyStates; var Effects: TCommonDropEffect);
begin
FreeAndNil(FTimer);
LastKeyState := [];
Exclude(FDragState, edmsDragging);
DoDragDrop(WindowPoint, KeyState, Effects);
DataObject := nil;
end;
procedure TCustomEasyDragManagerBase.DragEnd(Canvas: TCanvas; WindowPoint: TPoint; KeyState: TCommonKeyStates);
begin
FreeAndNil(FTimer);
LastKeyState := [];
Exclude(FDragState, edmsDragging);
DoDragEnd(Canvas, WindowPoint, KeyState);
DataObject := nil;
end;
procedure TCustomEasyDragManagerBase.DragEnter(const ADataObject: IDataObject; Canvas: TCanvas; WindowPoint: TPoint; KeyState: TCommonKeyStates; var Effects: TCommonDropEffect);
begin
Include(FDragState, edmsDragging);
DataObject := ADataObject;
Timer.Enabled := False;
Timer.OnTimer := HandleTimer;
Timer.Interval := AutoScrollDelay;
FAutoScrollDelayMet := False;
DoDragEnter(ADataObject, Canvas, WindowPoint, KeyState, Effects)
end;
function TCustomEasyDragManagerBase.GetAutoScrolling: Boolean;
begin
Result := edmsAutoScrolling in DragState
end;
function TCustomEasyDragManagerBase.GetDragging: Boolean;
begin
Result := edmsDragging in DragState
end;
function TCustomEasyDragManagerBase.GetTimer: TTimer;
begin
if not Assigned(FTimer) then
FTimer := TTimer.Create(nil);
Result := FTimer;
end;
procedure TCustomEasyDragManagerBase.HandleTimer(Sender: TObject);
begin
if AutoScrollDelayMet then
AutoScrollWindow
else begin
FAutoScrollDelayMet := True;
Timer.Interval := AutoScrollTime;
end
end;
function TCustomEasyDragManagerBase.PtInAutoScrollDownRegion(WindowPoint: TPoint): Boolean;
begin
Result := DoPtInAutoScrollDownRegion(WindowPoint)
end;
function TCustomEasyDragManagerBase.PtInAutoScrollLeftRegion(WindowPoint: TPoint): Boolean;
begin
Result := DoPtInAutoScrollLeftRegion(WindowPoint)
end;
function TCustomEasyDragManagerBase.PtInAutoScrollRegion(WindowPoint: TPoint): Boolean;
begin
Result := PtInAutoScrollDownRegion(WindowPoint) or PtInAutoScrollLeftRegion(WindowPoint) or
PtInAutoScrollRightRegion(WindowPoint) or PtInAutoScrollUpRegion(WindowPoint)
end;
function TCustomEasyDragManagerBase.PtInAutoScrollRightRegion(WindowPoint: TPoint): Boolean;
begin
Result := DoPtInAutoScrollRightRegion(WindowPoint)
end;
function TCustomEasyDragManagerBase.PtInAutoScrollUpRegion(WindowPoint: TPoint): Boolean;
begin
Result := DoPtInAutoScrollUpRegion(WindowPoint)
end;
function TCustomEasyDragManagerBase.ScrollDeltaDown(WindowPoint: TPoint): Integer;
begin
Result := Abs(OwnerListview.ClientHeight - WindowPoint.Y - AutoScrollMargin)
end;
function TCustomEasyDragManagerBase.ScrollDeltaLeft(WindowPoint: TPoint): Integer;
begin
Result := Abs(WindowPoint.X - AutoScrollMargin)
end;
function TCustomEasyDragManagerBase.ScrollDeltaRight(WindowPoint: TPoint): Integer;
begin
Result := Abs(OwnerListview.ClientWidth - WindowPoint.X - AutoScrollMargin )
end;
function TCustomEasyDragManagerBase.ScrollDeltaUp(WindowPoint: TPoint): Integer;
begin
Result := Abs(WindowPoint.Y - OwnerListview.Header.RuntimeHeight - AutoScrollMargin)
end;
procedure TCustomEasyDragManagerBase.RegisterOLEDragDrop(DoRegister: Boolean);
begin
if OwnerListview.HandleAllocated then
begin
if DoRegister then
begin
if not (ebcsOLERegistered in OwnerListview.States) then
begin
RegisterDragDrop(OwnerListview.Handle, OwnerListview.DropTarget);
Include(OwnerListview.FStates, ebcsOLERegistered)
end
end else
begin
if ebcsOLERegistered in OwnerListview.States then
begin
RevokeDragDrop(OwnerListview.Handle);
Exclude(OwnerListview.FStates, ebcsOLERegistered)
end
end;
end
end;
procedure TCustomEasyDragManagerBase.SetEnabled(const Value: Boolean);
begin
if FEnabled <> Value then
begin
DoEnable(Value);
FEnabled := Value;
end
end;
procedure TCustomEasyDragManagerBase.SetRegistered(Value: Boolean);
begin
if Value <> FRegistered then
begin
RegisterOLEDragDrop(Value);
FRegistered := Value;
end
end;
procedure TCustomEasyDragManagerBase.UpdateAfterAutoScroll;
begin
end;
procedure TCustomEasyDragManagerBase.VCLDragStart;
begin
end;
procedure TCustomEasyDragManagerBase.WMKeyDown(var Msg: TWMKeyDown);
begin
case Msg.CharCode of
VK_HOME: DoAutoScroll(-OwnerListview.Scrollbars.OffsetX, -OwnerListview.Scrollbars.OffsetY);
VK_END: DoAutoScroll(OwnerListview.Scrollbars.ViewWidth-OwnerListview.ClientWidth,
OwnerListview.Scrollbars.ViewHeight-OwnerListview.ClientHeight);
VK_NEXT: DoAutoScroll(0, OwnerListview.ClientHeight);
VK_PRIOR: DoAutoScroll(0, -OwnerListview.ClientHeight);
VK_UP: DoAutoScroll(0, -OwnerListview.Scrollbars.Line);
VK_DOWN: DoAutoScroll(0, OwnerListview.Scrollbars.Line);
VK_LEFT: DoAutoScroll(-OwnerListview.Scrollbars.Line, 0);
VK_RIGHT: DoAutoScroll(OwnerListview.Scrollbars.Line, 0);
end;
end;
constructor TEasyDragRectManager.Create(AnOwner: TCustomEasyListview);
begin
inherited;
FMouseButton := [cmbLeft, cmbRight];
FEnabled := False;
end;
destructor TEasyDragRectManager.Destroy;
begin
inherited;
end;
function TEasyDragRectManager.DoPtInAutoScrollDownRegion(WindowPoint: TPoint): Boolean;
begin
Result := (WindowPoint.Y > OwnerListview.ClientHeight - AutoScrollMargin) and
(OwnerListview.Scrollbars.OffsetY < OwnerListview.Scrollbars.MaxOffsetY)
end;
function TEasyDragRectManager.DoPtInAutoScrollLeftRegion(WindowPoint: TPoint): Boolean;
begin
Result := (WindowPoint.X < AutoScrollMargin) and (OwnerListview.Scrollbars.OffsetX > 0)
end;
function TEasyDragRectManager.DoPtInAutoScrollRightRegion(WindowPoint: TPoint): Boolean;
begin
Result := (WindowPoint.X > (OwnerListview.ClientWidth - AutoScrollMargin)) and
(OwnerListview.Scrollbars.OffsetX < OwnerListview.Scrollbars.MaxOffsetX)
end;
function TEasyDragRectManager.DoPtInAutoScrollUpRegion(WindowPoint: TPoint): Boolean;
begin
Result := (WindowPoint.Y - OwnerListview.Header.RuntimeHeight < AutoScrollMargin) and (OwnerListview.Scrollbars.OffsetY > 0)
end;
procedure TEasyDragRectManager.DoAfterAutoScroll;
begin
inherited;
end;
procedure TEasyDragRectManager.DoAutoScroll(DeltaX, DeltaY: Integer);
// Usually called from AutoScrollWindow which calcualate how to do the scroll.
// This method is usually overridden to perform the scroll in the passed direction
begin
inherited;
end;
procedure TEasyDragRectManager.DoBeforeAutoScroll;
begin
inherited;
// Keep the Dragpoint in sync with the current view
// Need to map the dragged point to a new point after a scroll
FOldOffsets.X := OwnerListview.Scrollbars.OffsetX;
FOldOffsets.Y := OwnerListview.Scrollbars.OffsetY;
end;
procedure TEasyDragRectManager.DoDrag(Canvas: TCanvas; WindowPoint: TPoint; KeyState: TCommonKeyStates; var Effects: TCommonDropEffect);
var
ARect: TRect;
begin
// Update the Selection due to this drag
OwnerListview.Selection.DragSelect(KeyState);
// Get the last rectangle
FPrevRect := SelectionRect;
inherited;
// Update the drag point
DragPoint := OwnerListview.Scrollbars.MapWindowToView(WindowPoint);
// Map it to the Client window coordinates
ARect := SelRectInWindowCoords;
// Make sure it is confined in the visible window
IntersectRect(ARect, ARect, OwnerListview.ClientRect);
// May need to update the last rectangle to if the drag rect is getting smaller
UnionRect(ARect, ARect, OwnerListview.Scrollbars.MapViewRectToWindowRect(PrevRect));
// Reentrant possibility
if not(edmsAutoScrolling in DragState) then
AutoScrollWindow;
// Always have to update if the selection rectangle if it gets smaller or full
// update if full row select (leaves white bands at the column interfaces)
if OwnerListview.Selection.FullRowSelect then
OwnerListview.SafeInvalidateRect(nil, True)
else
OwnerListview.SafeInvalidateRect(@ARect, True);
end;
procedure TEasyDragRectManager.DoDragBegin(WindowPoint: TPoint; KeyState: TCommonKeyStates);
begin
inherited;
FPrevRect := SelectionRect;
end;
procedure TEasyDragRectManager.DoDragEnd(Canvas: TCanvas; WindowPoint: TPoint; KeyState: TCommonKeyStates);
var
ARect: TRect;
begin
// Erase the selection rectangle, mainly for the XOR FocusRect when not DoubleBuffered
inherited;
// Get the last rectangle
ARect := SelRectInWindowCoords;
// Make sure it is confined in the visible window
IntersectRect(ARect, ARect, OwnerListview.ClientRect);
// Redraw the window
if OwnerListview.Selection.FullRowSelect then
OwnerListview.SafeInvalidateRect(nil, True)
else
OwnerListview.SafeInvalidateRect(@ARect, True);
AnchorPoint := Point(0, 0);
DragPoint := Point(0, 0);
FPrevRect := Rect(0, 0, 0, 0);
end;
procedure TEasyDragRectManager.DoDragEnter(const DataObject: IDataObject; Canvas: TCanvas; WindowPoint: TPoint; KeyState: TCommonKeyStates; var Effects: TCommonDropEffect);
begin
inherited DoDragEnter(DataObject, Canvas, WindowPoint, KeyState, Effects);
FDragPoint := WindowPoint
end;
procedure TEasyDragRectManager.FinalizeDrag(KeyState: TCommonKeyStates);
// Does not mean the action actually occured it means that InitializeDrag was
// called and this is it matching call. EndDrag means that the drag actually
// occured
begin
end;
function TEasyDragRectManager.GetSelectionRect: TRect;
begin
Result := ProperRect(Rect(AnchorPoint.X, AnchorPoint.Y, DragPoint.X, DragPoint.Y));
if Result.Top = Result.Bottom then // added
Inc(Result.Bottom);
if Result.Left = Result.Right then // added
Inc(Result.Right);
end;
function TEasyDragRectManager.InitializeDrag(WindowPoint: TPoint; KeyState: TCommonKeyStates): Boolean;
// Does not mean that the action will be a Selection Drag, it just means get
// ready for one just in case.
begin
Result := False;
if Enabled then
begin
if ((cksLButton in KeyState) and (cmbLeft in MouseButton)) or
((cksMButton in KeyState) and (cmbMiddle in MouseButton)) or
((cksRButton in KeyState) and (cmbRight in MouseButton))
then begin
AnchorPoint := OwnerListview.Scrollbars.MapWindowToView(WindowPoint);
DragPoint := AnchorPoint;
Result := True
end
end
end;
procedure TEasyDragRectManager.PaintRect(Canvas: TCanvas);
// Paints the selection rectangle to the canvas:
// NOTE: DO NOT USE THIS METHOD DIRECTLY use the PaintSelectionRect to draw
// the rectangle
// If not DoubleBuffered it is assumed that the Canvas is a Screen DC else it is
// assumed to be a Bitmap Compatiable Memory DC
var
SelectRect: TRect;
begin
SelectRect.TopLeft := OwnerListview.Scrollbars.MapViewToWindow(AnchorPoint);
SelectRect.BottomRight := OwnerListview.Scrollbars.MapViewToWindow(DragPoint);
SelectRect := ProperRect(SelectRect);
IntersectRect(SelectRect, SelectRect, OwnerListview.ClientRect);
if (OwnerListview.ViewSupportsHeader) and (OwnerListview.Header.Visible) then
begin
if SelectRect.Top < OwnerListview.Header.Height then
SelectRect.Top := OwnerListview.Header.Height;
end;
if OwnerListview.Selection.AlphaBlendSelRect and HasMMX then
begin
Canvas.Brush.Color := OwnerListview.Selection.BorderColorSelRect;
MPCommonUtilities.AlphaBlend(0, Canvas.Handle, SelectRect, Point(0, 0),
cbmConstantAlphaAndColor, OwnerListview.Selection.BlendAlphaSelRect,
ColorToRGB(OwnerListview.Selection.BlendColorSelRect));
Canvas.FrameRect(SelectRect);
end else
begin
Canvas.Font.Assign(OwnerListview.Font);
Canvas.Brush.Color := OwnerListview.Color;
Canvas.Font.Color := clBlack;
DrawFocusRect(Canvas.Handle, SelectRect);
end
end;
procedure TEasyDragRectManager.PaintSelectionRect(Canvas: TCanvas);
// Causes the Selection Rectangle to be drawn or "erased" (erased is just redrawn
// again in the same place so the XOR mode will clear the rectangle)
// NOTE: Use this method and not the PaintRect method directly
begin
PaintRect(Canvas);
end;
function TEasyDragRectManager.SelRectInWindowCoords: TRect;
// Gets the selection rectangle in the current Window coordinates then trims off
// the pieces that do not lie in the current window rectangle
begin
Result.TopLeft := OwnerListview.Scrollbars.MapViewToWindow(AnchorPoint);
Result.BottomRight := OwnerListview.Scrollbars.MapViewToWindow(DragPoint);
Result := ProperRect(Result);
end;
procedure TEasyDragRectManager.SetAnchorPoint(ViewportAnchor: TPoint);
begin
FAnchorPoint := ViewportAnchor
end;
procedure TEasyDragRectManager.SetDragPoint(const Value: TPoint);
begin
FDragPoint := Value
end;
procedure TEasyDragRectManager.UpdateAfterAutoScroll;
begin
inherited UpdateAfterAutoScroll;
// Keep the Dragpoint in sync with the current view
// Need to map the dragged point to a new point after a scroll
FDragPoint.X := DragPoint.X + (OwnerListview.Scrollbars.OffsetX - OldOffsets.X);
FDragPoint.Y := DragPoint.Y + (OwnerListview.Scrollbars.OffsetY - OldOffsets.Y);
end;
procedure TEasyDragRectManager.WMKeyDown(var Msg: TWMKeyDown);
begin
inherited;
end;
{ TCustomEasyListview }
constructor TCustomEasyListview.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FGesture := TEasyGestureManager.Create(Self);
NCCanvas := TCanvas.Create;
FGroupFont := TFont.Create;
FPaintInfoGroup := CreateGroupPaintInfo;
FPaintInfoItem := CreateItemPaintInfo;
FPaintInfoColumn := CreateColumnPaintInfo;
PaintInfoGroup.FMarginBottom.FPaintInfo := TEasyPaintInfoGroup.Create(Self);
FHotTrack := TEasyHotTrackManager.Create(Self);
Canvas.Control := Self;
ParentColor := False;
Brush.Color := clWindow;
Color := clWindow;
BevelInner := bvLowered;
BevelKind := bkTile;
ControlStyle := ControlStyle - [csCaptureMouse, csOpaque, csAcceptsControls]; // We will do this ourselves
FBackGround := TEasyBackgroundManager.Create(Self);
FScrollbars := TEasyScrollbarManager.Create(Self);
FDropTarget := TEasyDropTargetManager.Create(Self);
FDragRect := TEasyDragRectManager.Create(Self);
FDragManager := TEasyOLEDragManager.Create(Self);
FCheckManager := TEasyCheckManager.Create(Self);
FSelection := TEasySelectionManager.Create(Self);
FGroups := CreateGroups;
FHeader := TEasyHeader.Create(Self);
FEditManager := TEasyEditManager.Create(Self);
FGlobalImages := TEasyGlobalImageManager.Create(Self);
HintInfo := TEasyHintInfo.Create(Self);
FCellSizes := TEasyCellSizes.Create(Self);
FSort := TEasySortManager.Create(Self);
TabStop := True;
FWheelMouseDefaultScroll := edwsVert;
FWheelMouseScrollModifierEnabled := True;
FGroupCollapseButton := TBitmap.Create;
FGroupExpandButton := TBitmap.Create;
FItems := TEasyGlobalItems.Create(Self);
FShowGroupMargins := False;
FShowThemedBorder := True;
DisabledBlendAlpha := 128;
DisabledBlendColor := clWindow;
FIncrementalSearch := TEasyIncrementalSearchManager.Create(Self);
FScratchCanvas := TControlCanvas.Create;
FScratchCanvas.Control := Self;
{$IFNDEF COMPILER_6_UP}
Width := 100;
Height := 200;
{$ENDIF COMPILER_6_UP}
if IsUnicode then
begin
// GroupFont.Name := 'MS Shell Dlg 2';
// Font.Name := 'MS Shell Dlg 2';
// Header.Font.Name := 'MS Shell Dlg 2';
end
end;
destructor TCustomEasyListview.Destroy;
begin
Groups.Clear; // Clear the items first so there is no chance of trying to draw them after the window is destroyed
Header.Columns.Clear; // Clear the columns first so there is no chance of trying to draw them after the window is destroyed
inherited Destroy;
DropTarget := nil;
// Don't destroy these objects until the Window is destroyed
GroupExpandButton.Canvas.Unlock;
GroupCollapseButton.Canvas.Unlock;
FreeAndNil(FGesture);
FreeAndNil(FItems);
FreeAndNil(FNCCanvas);
FreeAndNil(FGroupExpandButton);
FreeAndNil(FGroupCollapseButton);
FreeAndNil(FBackGround);
FreeAndNil(FBackBits);
FreeAndNil(FScrollbars);
FreeAndNil(FDragRect);
FreeAndNil(FDragManager);
FreeAndNil(FCheckManager);
FreeAndNil(FSelection);
FreeAndNil(FHeader);
FreeAndNil(FEditManager);
FreeAndNil(FGlobalImages);
FreeAndNil(FCellSizes);
{$IFDEF COMPILER_5_UP}
FreeAndNil(FGroupFont); // Bug in D4
{$ENDIF COMPILER_5_UP}
FreeAndNil(FPaintInfoGroup);
FreeAndNil(FPaintInfoItem);
FreeAndNil(FPaintInfoColumn);
FreeAndNil(FHotTrack);
FreeAndNil(FHintInfo);
FreeAndNil(FSort);
FreeAndNil(FIncrementalSearch);
FreeAndNil(FScratchCanvas);
FreeAndNil(FGroups); // Always make Last
end;
function TCustomEasyListview.ClickTestGroup(ViewportPoint: TPoint;
KeyStates: TCommonKeyStates; var HitInfo: TEasyGroupHitTestInfoSet): TEasyGroup;
//
// Handles any default behavior of clicking on a group and returns true if the
// click was on a group object
//
begin
HitInfo := [];
Result := Groups.GroupByPoint(ViewportPoint);
if Assigned(Result) then
Result.HitTestAt(ViewportPoint, HitInfo);
end;
function TCustomEasyListview.ClickTestItem(ViewportPoint: TPoint;
Group: TEasyGroup; KeyStates: TCommonKeyStates;
var HitInfo: TEasyItemHitTestInfoSet): TEasyItem;
begin
Result := nil;
HitInfo := [];
if not Assigned(Group) then
Group := Groups.GroupByPoint(ViewportPoint);
if Assigned(Group) then
Result := Group.ItembyPoint(ViewportPoint);
// Result := Groups.ItcmbyPoint(ViewportPoint);
if Assigned(Result) then
Result.HitTestAt(ViewportPoint, HitInfo);
end;
function TCustomEasyListview.ClientInViewportCoords: TRect;
begin
Result := ClientRect;
Result.Top := Result.Top + Header.RuntimeHeight;
Result := Scrollbars.MapWindowRectToViewRect(Result)
end;
function TCustomEasyListview.CreateColumnPaintInfo: TEasyPaintInfoBaseColumn;
begin
Result := TEasyPaintInfoColumn.Create(Self)
end;
function TCustomEasyListview.CreateGroupPaintInfo: TEasyPaintInfoBaseGroup;
begin
Result := TEasyPaintInfoGroup.Create(Self)
end;
function TCustomEasyListview.CreateGroups: TEasyGroups;
begin
Result := TEasyGroups.Create(Self);
end;
function TCustomEasyListview.CreateItemPaintInfo: TEasyPaintInfoBaseItem;
begin
Result := TEasyPaintInfoItem.Create(Self);
end;
function TCustomEasyListview.DoMouseWheel(Shift: TShiftState;
WheelDelta: Integer; MousePos: TPoint): Boolean;
var
LocalMouseScroll: TEasyDefaultWheelScroll;
uiParam, pvParam: UINT;
IsNeg: Boolean;
begin
IsNeg := WheelDelta < 0;
uiParam := 0;
pvParam := 3;
if IsWinNT then
SystemParametersInfo(SPI_GETWHEELSCROLLLINES, uiParam, @pvParam, 0);
if WheelMouseDefaultScroll = edwsVert then
WheelDelta := Groups.CellHeight * Integer(pvParam) // Sroll down n Cells
else
WheelDelta := Groups.CellWidth {* Integer(pvParam)}; // Scroll sideways is different only one cell
if IsNeg then
WheelDelta := -WheelDelta;
Result := inherited DoMouseWheel(Shift, WheelDelta, MousePos);
LocalMouseScroll := WheelMouseDefaultScroll;
if WheelMouseScrollModifierEnabled then
begin
if (ssShift in Shift) then
begin
if WheelMouseDefaultScroll = edwsVert then
LocalMouseScroll := edwsHorz
else
LocalMouseScroll := edwsVert
end;
if ssCtrl in Shift then
begin
if LocalMouseScroll = edwsVert then
WheelDelta := ClientHeight - Header.RuntimeHeight
else
WheelDelta := ClientWidth;
if IsNeg then
WheelDelta := -WheelDelta;
end
end;
if LocalMouseScroll = edwsVert then
Scrollbars.Scroll(0, -WheelDelta)
else
if LocalMouseScroll = edwsHorz then
Scrollbars.Scroll(-WheelDelta, 0);
if not Result then
Result := True;
end;
function TCustomEasyListview.DoMouseWheelDown(Shift: TShiftState;
MousePos: TPoint): Boolean;
begin
Result := inherited DoMouseWheelDown(Shift, MousePos);
end;
function TCustomEasyListview.DoMouseWheelUp(Shift: TShiftState;
MousePos: TPoint): Boolean;
begin
Result := inherited DoMouseWheelUp(Shift, MousePos);
end;
function TCustomEasyListview.DragInitiated: Boolean;
begin
Result := [ebcsDragSelecting, ebcsDragging, ebcsDragSelectPending, ebcsDragPending] * States <> []
end;
function TCustomEasyListview.ExecuteDragDrop(AvailableEffects: TCommonDropEffects;
DataObjectInf: IDataObject; DropSource: IDropSource; var dwEffect: Integer): HRESULT;
begin
Result := ActiveX.DoDragDrop(DataObjectInf, DropSource, DropEffectStatesToDropEffect(AvailableEffects), dwEffect);
end;
function TCustomEasyListview.GetGroupCollapseImage: TBitmap;
begin
Result := FGroupCollapseButton
end;
function TCustomEasyListview.GetGroupExpandImage: TBitmap;
begin
Result := FGroupExpandButton
end;
function TCustomEasyListview.GetHintType: TEasyHintType;
begin
Result := HintInfo.HintType
end;
function TCustomEasyListview.GetPaintInfoColumn: TEasyPaintInfoBaseColumn;
begin
Result := FPaintInfoColumn;
end;
function TCustomEasyListview.GetPaintInfoGroup: TEasyPaintInfoBaseGroup;
begin
Result := FPaintInfoGroup;
end;
function TCustomEasyListview.GetPaintInfoItem: TEasyPaintInfoBaseItem;
begin
Result := FPaintInfoItem;
end;
function TCustomEasyListview.GetScratchCanvas: TControlCanvas;
begin
if HandleAllocated then
Result := FScratchCanvas
else
Result := nil
end;
function TCustomEasyListview.GetSortColumn: TEasyColumn;
begin
Result := Selection.FocusedColumn
end;
function TCustomEasyListview.GetTopItem: TEasyItem;
begin
Result := Groups.FirstItemInRect( Scrollbars.MapWindowRectToViewRect(ClientRect, False))
end;
function TCustomEasyListview.GroupTestExpand(HitInfo: TEasyGroupHitTestInfoSet): Boolean;
begin
Result := egtOnExpandButton in HitInfo
end;
function TCustomEasyListview.IsFontStored: Boolean;
begin
Result := not ParentFont and not DesktopFont;
end;
function TCustomEasyListview.IsHeaderMouseMsg(MousePos: TSmallPoint; ForceTest: Boolean = False): Boolean;
var
R: TRect;
begin
Result := False;
if not (DragRect.Dragging or DragManager.Dragging or Header.DragManager.Dragging) or ForceTest then
begin
R := Header.DisplayRect;
R.Bottom := Header.RuntimeHeight;
Result := (ViewSupportsHeader and PtInRect(R, SmallPointToPoint(MousePos))) or
(ebcsHeaderCapture in States) or Assigned(Header.HotTrackedColumn)
end
end;
function TCustomEasyListview.IsThumbnailView: Boolean;
begin
Result := View in THUMBNAILVIEWS
end;
function TCustomEasyListview.IsVertView: Boolean;
begin
Result := View in VERTICALVIEWS
end;
function TCustomEasyListview.ScrollHeaderHorz: Boolean;
begin
Result := not (Header.ShowInAllViews and (View = elsList))
end;
function TCustomEasyListview.ToolTipNeeded(TargetObj: TEasyCollectionItem;
var TipCaption: WideString): Boolean;
// Calcuates if the text is being truncated in the current view of the object
// If so the result is true.
var
TextFlags: TCommonDrawTextWFlags;
RectArray: TEasyRectArrayObject;
R: TRect;
LineCount: Integer;
Item: TEasyItem;
begin
Result := False;
TipCaption := '';
if TargetObj is TEasyItem then
begin
Item := TEasyItem( TargetObj);
if not Item.Focused then
begin
Item.ItemRectArray(nil, Canvas, RectArray);
TextFlags := [dtLeft, dtCalcRect, dtCalcRectAdjR];
R := RectArray.LabelRect;
LineCount := Item.View.PaintTextLineCount(Item, nil);
Item.View.LoadTextFont(Item, 0, Canvas, False);
DrawTextWEx(Canvas.Handle, Item.Caption, R, TextFlags, LineCount);
if (RectWidth(RectArray.TextRect) < RectWidth(R)) or
(RectHeight(RectArray.TextRect) < RectHeight(R)) then
begin
TipCaption := Item.Caption;
Result := True;
end
end
end
end;
function TCustomEasyListview.UseInternalDragImage: Boolean;
begin
Result := True
end;
function TCustomEasyListview.ViewSupportsHeader: Boolean;
begin
Result := (View in HEADERSUPPORTEDVIEWS) or Header.ShowInAllViews
end;
procedure TCustomEasyListview.AutoFitAllCells(VisibleOnly: Boolean);
var
i: Integer;
begin
case View of
elsReport:
begin
BeginUpdate;
try
for i := 0 to Header.Columns.Count - 1 do
begin
if VisibleOnly then
begin
if Header.Columns[i].Visible then
Header.Columns[i].AutoSizeToFit
end else
Header.Columns[i].AutoSizeToFit
end
finally
EndUpdate
end
end;
elsSmallIcon:
begin
BeginUpdate;
try
CellSizes.SmallIcon.AutoSize := True;
finally
EndUpdate
end
end;
elsList:
begin
BeginUpdate;
try
CellSizes.List.AutoSize := True;
finally
EndUpdate
end
end;
elsGrid:
begin
BeginUpdate;
try
CellSizes.Grid.AutoSize := True;
finally
EndUpdate
end
end;
end
end;
procedure TCustomEasyListview.BeginUpdate;
begin
inherited BeginUpdate;
// Sort.BeginUpdate;
end;
procedure TCustomEasyListview.CancelCut;
var
Item: TEasyItem;
begin
Item := Groups.FirstItem;
while Assigned(Item) do
begin
Item.Cut := False;
Item := Groups.NextItem(Item)
end
end;
procedure TCustomEasyListview.CheckFocus;
begin
if not Focused then
begin
if CanFocus and not (csDesigning in ComponentState) and HandleAllocated then
SetFocus;
end;
end;
procedure TCustomEasyListview.ClearPendingDrags;
begin
States := States - [ebcsDragPending, ebcsDragSelectPending];
DragManager.ClearDragItem;
end;
procedure TCustomEasyListview.ClearStates;
begin
Exclude(FStates, ebcsLButtonDown);
Exclude(FStates, ebcsMButtonDown);
Exclude(FStates, ebcsRButtonDown);
Exclude(FStates, ebcsDragSelecting);
Exclude(FStates, ebcsDragSelectPending);
Exclude(FStates, ebcsDragSelecting);
Exclude(FStates, ebcsDragPending);
Exclude(FStates, ebcsDragging);
Exclude(FStates, ebcsScrollButtonDown);
Exclude(FStates, ebcsVCLDrag);
Exclude(FStates, ebcsCheckboxClickPending);
Exclude(FStates, ebcsHeaderCapture);
Exclude(FStates, ebcsGroupExpandPending);
if not Themed then
CheckManager.PendingObject := nil;
end;
procedure TCustomEasyListview.ClipHeader(ACanvas: TCanvas; ResetClipRgn: Boolean);
var
OldOrg: TPoint;
begin
if ResetClipRgn then
SelectClipRgn(ACanvas.Handle, 0);
if Header.RuntimeHeight > 0 then
begin
SetWindowOrgEx(ACanvas.Handle, 0, 0, @OldOrg);
if ViewSupportsHeader and (Header.Visible) then
ExcludeClipRect(ACanvas.Handle, 0, 0, ClientWidth, Header.RuntimeHeight);
SetWindowOrgEx(ACanvas.Handle, OldOrg.X, OldOrg.Y, nil);
end
end;
procedure TCustomEasyListview.CMDrag(var Msg: TCMDrag);
// Called during a VCL drag and drop operation
var
Keys: TCommonKeyStates;
P: TPoint;
Effects: TCommonDropEffect;
{$IFDEF LOG_VCL_CMDRAG}
F: TFileStream;
S: string;
Buffer: array[0..MAX_PATH] of char;
{$ENDIF}
begin
{$IFDEF LOG_VCL_CMDRAG}
FillChar(Buffer, SizeOf(Buffer), #0);
GetModuleFileName(hInstance, Buffer, MAX_PATH);
S := ExtractFilePath(Buffer) + 'VCL Drag.log';
try
F := TFileStream.Create(S, fmOpenReadWrite or fmShareExclusive);
except
F := TFileStream.Create(S, fmCreate or fmShareExclusive);
end;
F.Seek(0, soFromEnd);
case Msg.DragMessage of
dmDragEnter: S := 'dmDragEnter';
dmDragLeave: S := 'dmDragLeave';
dmDragMove: S := 'dmDragMove';
dmDragDrop: S := 'dmDragDrop';
dmDragCancel: S := 'dmDragCancel';
dmFindTarget: S := 'dmFindTarget';
end;
S := S + #13+#10;
F.Write(PChar(S)^, Length(S));
F.Free;
{$ENDIF}
Keys := [];
Effects := cdeNone;
case Msg.DragMessage of
dmDragEnter:
begin
DragManager.DragEnter(nil, nil, ScreenToClient(Msg.DragRec^.Pos), Keys, Effects);
inherited;
end;
dmDragLeave:
begin
// The VCL DD stupidly sends a Drag Leave before the Drag Drop. This
// causes problems since I use DragEnd to reset a lot of the DragManagers
// flags. Check if the drop was on this window. If it was skip the
// Drag end and wait for the Drag Drop
GetCursorPos(P);
if WindowFromPoint(P) <> Handle then
begin
DragManager.DragEnd(nil, ScreenToClient(Msg.DragRec^.Pos), Keys);
ClearStates;
end;
inherited;
end;
dmDragMove:
begin
DragManager.Drag(nil, ScreenToClient(Msg.DragRec^.Pos), Keys, Effects);
inherited;
end;
dmDragDrop:
begin
inherited;
DragManager.DragDrop(ScreenToClient(Msg.DragRec^.Pos), Keys, Effects);
ClearStates;
end;
dmDragCancel:
begin
DragManager.DragEnd(nil, ScreenToClient(Msg.DragRec^.Pos), Keys);
inherited;
ClearStates;
end;
else
inherited;
end;
end;
procedure TCustomEasyListview.CMHintShow(var Message: TCMHintShow);
var
Allow: Boolean;
TargetObj: TEasyCollectionItem;
ItemHitInfo: TEasyItemHitTestInfoSet;
GroupHitInfo: TEasyGroupHitTestInfoSet;
ViewPt: TPoint;
begin
{$IFDEF GXDEBUG_HINT}
SendDebug('CMHintShow');
{$ENDIF GXDEBUG_HINT}
ViewPt := Scrollbars.MapWindowToView(Message.HintInfo^.CursorPos);
// See if we have hit any objects of interest
TargetObj := Groups.ItembyPoint(ViewPt);
if Assigned(TargetObj) then
begin
TEasyItem( TargetObj).HitTestAt(ViewPt, ItemHitInfo);
if not(ehtOnClickselectBounds in ItemHitInfo) then
TargetObj := nil
end;
if not Assigned(TargetObj) then
begin
TargetObj := Groups.GroupByPoint(ViewPt);
if Assigned(TargetObj) then
TEasyGroup( TargetObj).HitTestAt(ViewPt, GroupHitInfo);
end;
// Default hint type is Text
FHintData.HintType := HintInfo.HintType;
FHintData.HintStr := Hint;
FHintData.ReshowTimeout := Message.HintInfo^.ReshowTimeout;
FHintData.HideTimeout := Message.HintInfo^.HideTimeout;
// Allow the application to modify the HintData
Allow := False;
DoHintPopup(TargetObj, FHintData.HintType, Message.HintInfo^.CursorPos, FHintData.HintStr, FHintData.HideTimeout, FHintData.ReshowTimeout, Allow);
if FHintData.HintStr = '' then
Allow := False;
Message.HintInfo^.ReshowTimeout := FHintData.ReshowTimeout;
Message.HintInfo^.HideTimeout := FHintData.HideTimeout;
SetRect(FHintData.ToolTipRect, 0, 0, Screen.Width, 0);
// If the type is ToolTip then calculate if it is necessary
if (FHintData.HintType = ehtToolTip) then
begin
if TargetObj is TEasyItem then
Allow := ToolTipNeeded(TargetObj, FHintData.HintStr)
else
Allow := False;
end;
if Allow then
begin
Message.HintInfo.HintWindowClass := TEasyHintWindow;
// Send our HintData to the Hint Window through the supplied Data parameter
Message.HintInfo.HintData := @FHintData;
if Message.HintInfo.HintStr = '' then
Message.HintInfo.HintStr := 'Dummy';
// Area where the tip is defined, once outside the Hint testing will resume
if TargetObj is TEasyItem then
Message.HintInfo^.CursorRect := TargetObj.DisplayRect;
if TargetObj is TEasyGroup then
begin
if egtOnRightMargin in GroupHitInfo then
Message.HintInfo^.CursorRect := TEasyGroup( TargetObj).BoundsRectRightMargin
else
if egtOnLeftMargin in GroupHitInfo then
Message.HintInfo^.CursorRect := TEasyGroup( TargetObj).BoundsRectLeftMargin
else
if egtOnHeader in GroupHitInfo then
Message.HintInfo^.CursorRect := TEasyGroup( TargetObj).BoundsRectTopMargin
else
if egtOnFooter in GroupHitInfo then
Message.HintInfo^.CursorRect := TEasyGroup( TargetObj).BoundsRectBottomMargin;
end;
Message.HintInfo^.CursorRect := Scrollbars.MapViewRectToWindowRect(Message.HintInfo^.CursorRect);
FHintData.Listview := Self;
FHintData.HintControl := Message.HintInfo^.HintControl;
FHintData.HintWindowClass := Message.HintInfo^.HintWindowClass;
FHintData.HintPos := Message.HintInfo^.HintPos;
FHintData.HintMaxWidth := Message.HintInfo^.HintMaxWidth;
FHintData.HintColor := Message.HintInfo^.HintColor;
FHintData.CursorRect := Message.HintInfo^.CursorRect;
FHintData.CursorPos := Message.HintInfo^.CursorPos;
FHintData.HintData := nil;
FHintData.TargetObj := TargetObj;
inherited;
end else
Message.Result := 1; // Message is handled, don't show the hint
end;
procedure TCustomEasyListview.CMHintShowPause(var Message: TCMHintShow);
var
HintShowing: Boolean;
PauseTime: PInteger;
begin
{$IFDEF GXDEBUG_HINT}
SendDebug('CMHintShowPause');
{$ENDIF GXDEBUG_HINT}
PauseTime := PInteger(TMessage(Message).LParam);
HintShowing := Boolean( TMessage(Message).wParam);
DoHintShowPause(HintShowing, PauseTime^);
inherited
end;
procedure TCustomEasyListview.CMMouseWheel(var Msg: TWMMouseWheel);
begin
inherited
end;
procedure TCustomEasyListview.CMParentFontChanged(var Msg: TMessage);
begin
inherited;
if ParentFont then
begin
if Msg.wParam <> 0 then
begin
GroupFont.Assign(TFont(Msg.lParam));
Header.Font.Assign(TFont(Msg.lParam));
end else
begin
GroupFont.Assign(TWinControlCracker(Parent).Font);
Header.Font.Assign(TWinControlCracker(Parent).Font);
end
end
end;
procedure TCustomEasyListview.CopyToClipboard;
begin
end;
procedure TCustomEasyListview.CreateParams(var Params: TCreateParams);
begin
inherited;
Params.WindowClass.Style := Params.WindowClass.Style or CS_DBLCLKS and not (CS_HREDRAW or CS_VREDRAW);
Params.Style := Params.Style or WS_CLIPCHILDREN or WS_CLIPSIBLINGS;
AddBiDiModeExStyle(Params.ExStyle);
end;
procedure TCustomEasyListview.CreateWnd;
begin
inherited;
DoUpdate;
// The Window Handle is now valid
DragManager.Registered := DragManager.Enabled;
Header.DragManager.Registered := Header.DragManager.Enabled;
ResizeBackBits(ClientWidth, ClientHeight);
end;
procedure TCustomEasyListview.CutToClipboard;
var
Handled, Mark: Boolean;
begin
Handled := False;
Mark := True;
DoClipboardCut(Handled, Mark);
if Handled and Mark then
MarkSelectedCut
end;
procedure TCustomEasyListview.DestroyWnd;
begin
inherited;
end;
procedure TCustomEasyListview.DoAfterPaint(ACanvas: TCanvas; ClipRect: TRect);
begin
if Assigned(OnAfterPaint) then
OnAfterPaint(Self, ACanvas, ClipRect)
end;
procedure TCustomEasyListview.DoAutoGroupGetKey(Item: TEasyItem; ColumnIndex: Integer; Groups: TEasyGroups; var Key: LongWord);
begin
if Assigned(OnAutoGroupGetKey) then
OnAutoGroupGetKey(Self, Item, ColumnIndex, Groups, Key)
end;
procedure TCustomEasyListview.DoAutoSortGroupCreate(Item: TEasyItem; ColumnIndex: Integer; Groups: TEasyGroups; var Group: TEasyGroup; var DoDefaultAction: Boolean);
begin
if Assigned(OnAutoSortGroupCreate) then
OnAutoSortGroupCreate(Self, Item, ColumnIndex, Groups, Group, DoDefaultAction);
if not Assigned(Group) then
Group := Groups.Add
end;
procedure TCustomEasyListview.DoClipboardCopy(var Handled: Boolean);
begin
if Assigned(OnClipboardCopy) then
OnClipboardCopy(Self, Handled);
end;
procedure TCustomEasyListview.DoClipboardCut(var MarkAsCut, Handled: Boolean);
begin
if Assigned(OnClipboardCut) then
OnClipboardCut(Self, MarkAsCut, Handled);
end;
procedure TCustomEasyListview.DoClipboardPaste(var Handled: Boolean);
begin
if Assigned(OnClipboardPaste) then
OnClipboardPaste(Self, Handled);
end;
procedure TCustomEasyListview.DoColumnCheckChanged(Column: TEasyColumn);
begin
if Assigned(OnColumnCheckChanged) and not (csDestroying in ComponentState) then
OnColumnCheckChanged(Self, Column)
end;
procedure TCustomEasyListview.DoColumnCheckChanging(Column: TEasyColumn; var Allow: Boolean);
begin
if Assigned(OnColumnCheckChanging) and not (csDestroying in ComponentState) then
OnColumnCheckChanging(Self, Column, Allow)
end;
procedure TCustomEasyListview.DoColumnClick(Button: TCommonMouseButton;
const Column: TEasyColumn);
begin
if Assigned(OnColumnClick) then
OnColumnClick(Self, Button, Column)
end;
procedure TCustomEasyListview.DoColumnContextMenu(HitInfo: TEasyHitInfoColumn; WindowPoint: TPoint; var Menu: TPopupMenu);
begin
if Assigned(OnColumnContextMenu) then
OnColumnContextMenu(Self, HitInfo, WindowPoint, Menu);
end;
procedure TCustomEasyListview.DoColumnDblClick(Button: TCommonMouseButton; ShiftState: TShiftState; MousePos: TPoint; Column: TEasyColumn);
begin
if Assigned(OnColumnDblClick) then
OnColumnDblClick(Self, Button, MousePos, Column)
end;
procedure TCustomEasyListview.DoColumnDropDownButtonClick(Column: TEasyColumn; Button: TCommonMouseButton; ShiftState: TShiftState; MousePos: TPoint; var DoDefault: Boolean);
begin
if Assigned(OnColumnDropDownButtonClick) then
OnColumnDropDownButtonClick(Self, Column, Button, ShiftState, MousePos, DoDefault)
end;
procedure TCustomEasyListview.DoColumnEnableChanged(Column: TEasyColumn);
begin
if Assigned(OnColumnEnableChanged) and not (csDestroying in ComponentState) then
OnColumnEnableChanged(Self, Column)
end;
procedure TCustomEasyListview.DoColumnEnableChanging(Column: TEasyColumn; var Allow: Boolean);
begin
if Assigned(OnColumnEnableChanging) and not (csDestroying in ComponentState) then
OnColumnEnableChanging(Self, Column, Allow)
end;
procedure TCustomEasyListview.DoColumnFocusChanged(Column: TEasyColumn);
begin
if Assigned(OnColumnFocusChanged) and not (csDestroying in ComponentState) then
OnColumnFocusChanged(Self, Column)
end;
procedure TCustomEasyListview.DoColumnFocusChanging(Column: TEasyColumn; var Allow: Boolean);
begin
if Assigned(OnColumnFocusChanging) and not (csDestroying in ComponentState) then
OnColumnFocusChanging(Self, Column, Allow)
end;
procedure TCustomEasyListview.DoColumnFreeing(Column: TEasyColumn);
begin
if Assigned(OnColumnFreeing) then
OnColumnFreeing(Self, Column)
end;
procedure TCustomEasyListview.DoColumnGetCaption(Column: TEasyColumn; Line: Integer; var Caption: WideString);
begin
if Assigned(OnColumnGetCaption) then
OnColumnGetCaption(Self, Column, Line, Caption)
end;
procedure TCustomEasyListview.DoColumnGetDetail(Column: TEasyColumn; Line: Integer; var Detail: Integer);
begin
if Assigned(OnColumnGetDetail) then
OnColumnGetDetail(Self, Column, Line, Detail)
end;
procedure TCustomEasyListview.DoColumnGetDetailCount(Column: TEasyColumn; var Count: Integer);
begin
if Assigned(OnColumnGetDetailCount) then
OnColumnGetDetailCount(Self, Column, Count)
end;
procedure TCustomEasyListview.DoColumnGetImageIndex(Column: TEasyColumn; ImageKind: TEasyImageKind; var ImageIndex: TCommonImageIndexInteger);
begin
if Assigned(OnColumnGetImageIndex) then
OnColumnGetImageIndex(Self, Column, ImageKind, ImageIndex)
end;
procedure TCustomEasyListview.DoColumnGetImageList(Column: TEasyColumn; var ImageList: TCustomImageList);
begin
if Assigned(OnColumnGetImageList) then
OnColumnGetImageList(Self, Column, ImageList)
end;
procedure TCustomEasyListview.DoColumnImageDraw(Column: TEasyColumn; ACanvas: TCanvas; const RectArray: TEasyRectArrayObject; AlphaBlender: TEasyAlphaBlender);
begin
if Assigned(OnColumnImageDraw) then
OnColumnImageDraw(Self, Column, ACanvas, RectArray, AlphaBlender)
end;
procedure TCustomEasyListview.DoColumnImageGetSize(Column: TEasyColumn; var ImageWidth, ImageHeight: Integer);
begin
if Assigned(OnColumnImageGetSize) then
OnColumnImageGetSize(Self, Column, ImageWidth, ImageHeight)
end;
procedure TCustomEasyListview.DoColumnImageDrawIsCustom(Column: TEasyColumn;
var IsCustom: Boolean);
begin
if Assigned(OnColumnImageDrawIsCustom) then
OnColumnImageDrawIsCustom(Self, Column, IsCustom)
end;
procedure TCustomEasyListview.DoColumnInitialize(Column: TEasyColumn);
begin
if Assigned(OnColumnInitialize) then
OnColumnInitialize(Self, Column)
end;
procedure TCustomEasyListview.DoColumnLoadFromStream(Column: TEasyColumn; S: TStream; Version: Integer);
begin
if Assigned(OnColumnLoadFromStream) then
OnColumnLoadFromStream(Self, Column, S, Version);
end;
procedure TCustomEasyListview.DoColumnPaintText(Column: TEasyColumn;
ACanvas: TCanvas);
begin
if Assigned(OnColumnPaintText) then
OnColumnPaintText(Self, Column, ACanvas)
end;
procedure TCustomEasyListview.DoColumnSaveToStream(Column: TEasyColumn; S: TStream; Version: Integer);
begin
if Assigned(OnColumnSaveToStream) then
OnColumnSaveToStream(Self, Column, S, Version);
end;
procedure TCustomEasyListview.DoColumnSelectionChanged(Column: TEasyColumn);
begin
if Assigned(OnColumnSelectionChanged) and not (csDestroying in ComponentState) then
OnColumnSelectionChanged(Self, Column)
end;
procedure TCustomEasyListview.DoColumnSelectionChanging(Column: TEasyColumn; var Allow: Boolean);
begin
if Assigned(OnColumnSelectionChanging) and not (csDestroying in ComponentState) then
OnColumnSelectionChanging(Self, Column, Allow)
end;
procedure TCustomEasyListview.DoColumnSetCaption(Column: TEasyColumn; const Caption: WideString);
begin
if Assigned(OnColumnSetCaption) then
OnColumnSetCaption(Self, Column, Caption)
end;
procedure TCustomEasyListview.DoColumnSetDetail(Column: TEasyColumn; Line: Integer; Detail: Integer);
begin
if Assigned(OnColumnSetDetail) then
OnColumnSetDetail(Self, Column, Line, Detail)
end;
procedure TCustomEasyListview.DoColumnSetDetailCount(Column: TEasyColumn; DetailCount: Integer);
begin
///
end;
procedure TCustomEasyListview.DoColumnSetImageIndex(Column: TEasyColumn; ImageKind: TEasyImageKind; ImageIndex: Integer);
begin
if Assigned(OnColumnSetImageIndex) then
OnColumnSetImageIndex(Self, Column, ImageKind, ImageIndex)
end;
procedure TCustomEasyListview.DoColumnSizeChanged(Column: TEasyColumn);
begin
if Assigned(OnColumnSizeChanged) and not (csDestroying in ComponentState) then
OnColumnSizeChanged(Self, Column)
end;
procedure TCustomEasyListview.DoColumnSizeChanging(Column: TEasyColumn; Size, NewSize: Integer; var Allow: Boolean);
begin
if Assigned(OnColumnSizeChanging) and not (csDestroying in ComponentState) then
OnColumnSizeChanging(Self, Column, Size, NewSize, Allow)
end;
procedure TCustomEasyListview.DoColumnStructureChange;
begin
if Assigned(OnColumnStructureChange) then
OnColumnStructureChange(Self)
end;
procedure TCustomEasyListview.DoColumnThumbnailDraw(Column: TEasyColumn; ACanvas: TCanvas; ARect: TRect; var DoDefault: Boolean);
begin
end;
procedure TCustomEasyListview.DoColumnVisibilityChanged(Column: TEasyColumn);
begin
if Assigned(OnColumnVisibilityChanged) then
OnColumnVisibilityChanged(Self, Column)
end;
procedure TCustomEasyListview.DoColumnVisibilityChanging(Column: TEasyColumn; var Allow: Boolean);
begin
if Assigned(OnColumnVisibilityChanging) then
OnColumnVisibilityChanging(Self, Column, Allow)
end;
procedure TCustomEasyListview.DoContextMenu(MousePt: TPoint; var Handled: Boolean);
begin
if Assigned(OnContextMenu) then
OnContextMenu(Self, MousePt, Handled)
end;
procedure TCustomEasyListview.DoColumnCustomView(Column: TEasyColumn; var ViewClass: TEasyViewColumnClass);
begin
if Assigned(OnColumnCustomView) then
OnColumnCustomView(Self, Column, ViewClass);
end;
procedure TCustomEasyListview.DoCustomGrid(Group: TEasyGroup; ViewStyle: TEasyListStyle; var Grid: TEasyGridGroupClass);
begin
if Assigned(OnCustomGrid) then
OnCustomGrid(Self, Group, ViewStyle, Grid)
end;
procedure TCustomEasyListview.DoGesture(Gesture: WideString;
var Handled: Boolean);
begin
if Assigned(OnMouseGesture) then
OnMouseGesture(Self, Gesture, Handled)
end;
procedure TCustomEasyListview.DoGroupCustomView(Group: TEasyGroup; ViewStyle: TEasyListStyle; var View: TEasyViewGroupClass);
begin
if Assigned(OnGroupCustomView) then
OnGroupCustomView(Self, Group, ViewStyle, View)
end;
procedure TCustomEasyListview.DoGroupStructureChange;
begin
if Assigned(OnGroupStructureChange) then
OnGroupStructureChange(Self)
end;
procedure TCustomEasyListview.DoItemCustomView(Item: TEasyItem; ViewStyle: TEasyListStyle; var View: TEasyViewItemClass);
begin
if Assigned(OnItemCustomView) then
OnItemCustomView(Self, Item, ViewStyle, View)
end;
procedure TCustomEasyListview.DoDblClick(Button: TCommonMouseButton; MousePos: TPoint;
ShiftState: TShiftState);
begin
if Assigned(OnDblClick) then
OnDblClick(Self, Button, MousePos, ShiftState)
end;
procedure TCustomEasyListview.DoGetDragImage(Bitmap: TBitmap;
DragStartPt: TPoint; var HotSpot: TPoint; var TransparentColor: TColor;
var Handled: Boolean);
begin
if Assigned(OnGetDragImage) then
OnGetDragImage(Self, Bitmap, DragStartPt, HotSpot, TransparentColor, Handled);
end;
procedure TCustomEasyListview.DoGroupClick(Group: TEasyGroup; KeyStates: TCommonKeyStates; HitTest: TEasyGroupHitTestInfoSet);
begin
if Assigned(OnGroupClick) then
OnGroupClick(Self, Group, KeyStates, HitTest)
end;
procedure TCustomEasyListview.DoGroupCollapse(Group: TEasyGroup);
begin
if Assigned(OnGroupCollapse) and not (csDestroying in ComponentState) then
OnGroupCollapse(Self, Group);
end;
procedure TCustomEasyListview.DoGroupCollapsing(Group: TEasyGroup; var Allow: Boolean);
begin
if Assigned(OnGroupCollapsing) and not (csDestroying in ComponentState) then
OnGroupCollapsing(Self, Group, Allow);
end;
function TCustomEasyListview.DoGroupCompare(Column: TEasyColumn; Group1,
Group2: TEasyGroup): Integer;
begin
if Assigned(OnGroupCompare) then
Result := OnGroupCompare(Self, Group1, Group2)
else
Result := DefaultSort(Column, Group1, Group2)
end;
procedure TCustomEasyListview.DoGroupContextMenu(HitInfo: TEasyHitInfoGroup;
WindowPoint: TPoint; var Menu: TPopupMenu; var Handled: Boolean);
begin
if Assigned(OnGroupContextMenu) then
OnGroupContextMenu(Self, HitInfo, WindowPoint, Menu, Handled);
end;
procedure TCustomEasyListview.DoGroupDblClick(Button: TCommonMouseButton;
MousePos: TPoint; HitInfo: TEasyHitInfoGroup);
begin
if Assigned(OnGroupDblClick) then
OnGroupDblClick(Self, Button, MousePos, HitInfo)
end;
procedure TCustomEasyListview.DoGroupExpand(Group: TEasyGroup);
begin
Groups.Rebuild;
if Assigned(OnGroupExpand) then
OnGroupExpand(Self, Group)
end;
procedure TCustomEasyListview.DoGroupExpanding(Group: TEasyGroup; var Allow: Boolean);
begin
if Assigned(OnGroupExpanding) then
OnGroupExpanding(Self, Group, Allow)
end;
procedure TCustomEasyListview.DoGroupHotTrack(Group: TEasyGroup; State: TEasyHotTrackstate; MousePos: TPoint);
begin
if Assigned(OnGroupHotTrack) then
OnGroupHotTrack(Self, Group, State, MousePos)
end;
procedure TCustomEasyListview.DoGroupFreeing(Group: TEasyGroup);
begin
if Assigned(OnGroupFreeing) then
OnGroupFreeing(Self, Group)
end;
procedure TCustomEasyListview.DoGroupGetCaption(Group: TEasyGroup; var Caption: WideString);
begin
if Assigned(OnGroupGetCaption) then
OnGroupGetCaption(Self, Group, Caption)
end;
procedure TCustomEasyListview.DoGroupGetDetail(Group: TEasyGroup; Line: Integer; var Detail: Integer);
begin
if Assigned(OnGroupGetDetail) then
OnGroupGetDetail(Self, Group, Line, Detail)
end;
procedure TCustomEasyListview.DoGroupGetDetailCount(Group: TEasyGroup; var Count: Integer);
begin
if Assigned(OnGroupGetDetailCount) then
OnGroupGetDetailCount(Self, Group, Count)
end;
procedure TCustomEasyListview.DoGroupGetImageIndex(Group: TEasyGroup; ImageKind: TEasyImageKind; var ImageIndex: TCommonImageIndexInteger);
begin
if Assigned(OnGroupGetImageIndex) then
OnGroupGetImageIndex(Self, Group, ImageKind, ImageIndex)
end;
procedure TCustomEasyListview.DoGroupGetImageList(Group: TEasyGroup; var ImageList: TCustomImageList);
begin
if Assigned(OnGroupGetImageList) then
OnGroupGetImageList(Self, Group, ImageList)
end;
procedure TCustomEasyListview.DoGroupImageDraw(Group: TEasyGroup; ACanvas: TCanvas; const RectArray: TEasyRectArrayObject; AlphaBlender: TEasyAlphaBlender);
begin
if Assigned(OnGroupImageDraw) then
OnGroupImageDraw(Self, Group, ACanvas, RectArray, AlphaBlender)
end;
procedure TCustomEasyListview.DoGroupImageGetSize(Group: TEasyGroup; var ImageWidth, ImageHeight: Integer);
begin
if Assigned(OnGroupImageGetSize) then
OnGroupImageGetSize(Self, Group, ImageWidth, ImageHeight)
end;
procedure TCustomEasyListview.DoGroupImageDrawIsCustom(Group: TEasyGroup;
var IsCustom: Boolean);
begin
if Assigned(OnGroupImageDrawIsCustom) then
OnGroupImageDrawIsCustom(Self, Group, IsCustom)
end;
procedure TCustomEasyListview.DoGroupInitialize(Group: TEasyGroup);
begin
if Assigned(OnGroupInitialize) then
OnGroupInitialize(Self, Group)
end;
procedure TCustomEasyListview.DoGroupLoadFromStream(Group: TEasyGroup; S: TStream; Version: Integer);
begin
if Assigned(OnGroupLoadFromStream) then
OnGroupLoadFromStream(Self, Group, S, Version)
end;
procedure TCustomEasyListview.DoGroupPaintText(Group: TEasyGroup;
ACanvas: TCanvas);
begin
if Assigned(OnGroupPaintText) then
OnGroupPaintText(Self, Group, ACanvas)
end;
procedure TCustomEasyListview.DoGroupSaveToStream(Group: TEasyGroup; S: TStream; Version: Integer);
begin
if Assigned(OnGroupSaveToStream) then
OnGroupSaveToStream(Self, Group, S, Version)
end;
procedure TCustomEasyListview.DoGroupSelectionChanged(Group: TEasyGroup);
begin
if Assigned(OnGroupSelectionChanged) then
OnGroupSelectionChanged(Self, Group)
end;
procedure TCustomEasyListview.DoGroupSelectionChanging(Group: TEasyGroup; var Allow: Boolean);
begin
if Assigned(OnGroupSelectionChanging) then
OnGroupSelectionChanging(Self, Group, Allow)
end;
procedure TCustomEasyListview.DoGroupSetCaption(Group: TEasyGroup; const Caption: WideString);
begin
if Assigned(OnGroupSetCaption) then
OnGroupSetCaption(Self, Group, Caption)
end;
procedure TCustomEasyListview.DoGroupSetDetailCount(Group: TEasyGroup; DetailCount: Integer);
begin
///
end;
procedure TCustomEasyListview.DoGroupSetImageIndex(Group: TEasyGroup; ImageKind: TEasyImageKind; ImageIndex: Integer);
begin
if Assigned(OnGroupSetImageIndex) then
OnGroupSetImageIndex(Self, Group, ImageKind, ImageIndex)
end;
procedure TCustomEasyListview.DoGroupSetDetail(Group: TEasyGroup; Line: Integer; Detail: Integer);
begin
if Assigned(OnGroupSetDetail) then
OnGroupSetDetail(Self, Group, Line, Detail)
end;
procedure TCustomEasyListview.DoGroupThumbnailDraw(Group: TEasyGroup; ACanvas: TCanvas; ARect: TRect; AlphaBlender: TEasyAlphaBlender; var DoDefault: Boolean);
begin
// not implemented
end;
procedure TCustomEasyListview.DoGroupVisibilityChanged(Group: TEasyGroup);
begin
if Assigned(OnGroupVisibilityChanged) and not (csDestroying in ComponentState) then
OnGroupVisibilityChanged(Self, Group)
end;
procedure TCustomEasyListview.DoGroupVisibilityChanging(Group: TEasyGroup; var Allow: Boolean);
begin
if Assigned(OnGroupVisibilityChanging) and not (csDestroying in ComponentState) then
OnGroupVisibilityChanging(Self, Group, Allow)
end;
procedure TCustomEasyListview.DoHeaderDblClick(Button: TCommonMouseButton; MousePos: TPoint;
ShiftState: TShiftState);
begin
if Assigned(OnHeaderDblClick) then
OnHeaderDblClick(Self, Button, MousePos, ShiftState)
end;
procedure TCustomEasyListview.DoHintCustomInfo(TargetObj: TEasyCollectionItem; const Info: TEasyHintInfo);
begin
if Assigned(OnHintCustomInfo) then
OnHintCustomInfo(Self, TargetObj, Info);
end;
procedure TCustomEasyListview.DoHintCustomDraw(TargetObj: TEasyCollectionItem; const Info: TEasyHintInfo);
begin
if Assigned(OnHintCustomDraw) then
OnHintCustomDraw(Self, TargetObj, Info);
end;
procedure TCustomEasyListview.DoHintPopup(TargetObj: TEasyCollectionItem; HintType: TEasyHintType; MousePos: TPoint; var AText: WideString; var HideTimeout, ReshowTimeout: Integer; var Allow: Boolean);
begin
if Assigned(OnHintPopup) then
OnHintPopup(Self, TargetObj, HintType, MousePos, AText, HideTimeout, ReshowTimeout, Allow)
end;
procedure TCustomEasyListview.DoHintShowPause(HintShowingNow: Boolean;
var PauseTime: Integer);
begin
if Assigned(OnHintPauseTime) then
OnHintPauseTime(Self, HintShowingNow, PauseTime)
end;
procedure TCustomEasyListview.DoIncrementalSearch(Item: TEasyItem;
const SearchBuffer: WideString; var CompareResult: Integer);
var
Handled: Boolean;
begin
CompareResult := 0;
Handled := False;
if Assigned(OnIncrementalSearch) then
OnIncrementalSearch(Item, SearchBuffer, Handled, CompareResult);
if not Handled then
CompareResult := WideIncrementalSearch(Item.Caption, SearchBuffer)
end;
procedure TCustomEasyListview.DoItemCheckChanged(Item: TEasyItem);
begin
if Assigned(OnItemCheckChange) and not (csDestroying in ComponentState) then
OnItemCheckChange(Self, Item)
end;
procedure TCustomEasyListview.DoItemCheckChanging(Item: TEasyItem;
var Allow: Boolean);
begin
if Assigned(OnItemCheckChanging) and not (csDestroying in ComponentState) then
OnItemCheckChanging(Self, Item, Allow);
end;
procedure TCustomEasyListview.DoItemClick(Item: TEasyItem;
KeyStates: TCommonKeyStates; HitInfo: TEasyItemHitTestInfoSet);
begin
if Assigned(OnItemClick) then
OnItemClick(Self, Item, KeyStates, HitInfo)
end;
function TCustomEasyListview.DoItemCompare(Column: TEasyColumn;
Group: TEasyGroup; Item1, Item2: TEasyItem): Integer;
var
DoDefault: Boolean;
begin
Result := 0;
DoDefault := True;
if Assigned(OnItemCompare) then
Result := OnItemCompare(Self, Column, Group, Item1, Item2, DoDefault);
if DoDefault then
Result := DefaultSort(Column, Item1, Item2)
end;
procedure TCustomEasyListview.DoItemContextMenu(HitInfo: TEasyHitInfoItem;
WindowPoint: TPoint; var Menu: TPopupMenu; var Handled: Boolean);
begin
Menu := nil;
if Assigned(OnItemContextMenu) then
OnItemContextMenu(Self, HitInfo, WindowPoint, Menu, Handled);
end;
procedure TCustomEasyListview.DoItemCreateEditor(Item: TEasyItem;
var Editor: IEasyCellEditor);
begin
if Assigned(OnItemCreateEditor) then
OnItemCreateEditor(Self, Item, Editor);
if not Assigned(Editor) then
begin
if View in MULTILINEVIEWS then
Editor := TEasyMemoEditor.Create
else
Editor := TEasyStringEditor.Create;
end
end;
procedure TCustomEasyListview.DoItemDblClick(Button: TCommonMouseButton;
MousePos: TPoint; HitInfo: TEasyHitInfoItem);
begin
if Assigned(OnItemDblClick) then
OnItemDblClick(Self, Button, MousePos, HitInfo)
end;
procedure TCustomEasyListview.DoItemEditBegin(Item: TEasyItem; var Column: Integer; var Allow: Boolean);
begin
if Assigned(OnItemEditBegin) then
OnItemEditBegin(Self, Item, Column, Allow)
end;
procedure TCustomEasyListview.DoItemEdited(Item: TEasyItem;
var NewValue: Variant; var Accept: Boolean);
begin
if Assigned(OnItemEdited) then
OnItemEdited(Self, Item, NewValue, Accept);
end;
procedure TCustomEasyListview.DoItemEditEnd(Item: TEasyItem);
begin
if Assigned(OnItemEditEnd) then
OnItemEditEnd(Self, Item);
end;
procedure TCustomEasyListview.DoItemEnableChanged(Item: TEasyItem);
begin
if Assigned(OnItemEnableChange) then
OnItemEnableChange(Self, Item)
end;
procedure TCustomEasyListview.DoItemEnableChanging(Item: TEasyItem;
var Allow: Boolean);
begin
if Assigned(OnItemEnableChanging) then
OnItemEnableChanging(Self, Item, Allow)
end;
procedure TCustomEasyListview.DoItemFocusChanged(Item: TEasyItem);
begin
if Assigned(OnItemFocusChanged) then
OnItemFocusChanged(Self, Item)
end;
procedure TCustomEasyListview.DoItemFocusChanging(Item: TEasyItem;
var Allow: Boolean);
begin
if Assigned(OnItemFocusChanging) then
OnItemFocusChanging(Self, Item, Allow)
end;
procedure TCustomEasyListview.DoItemFreeing(Item: TEasyItem);
begin
if Assigned(OnItemFreeing) then
OnItemFreeing(Self, Item)
end;
procedure TCustomEasyListview.DoItemGetCaption(Item: TEasyItem; Column: Integer; var ACaption: WideString);
begin
if Assigned(OnItemGetCaption) then
OnItemGetCaption(Self, Item, Column, ACaption)
end;
procedure TCustomEasyListview.DoItemGetEditCaption(Item: TEasyItem; Column: TEasyColumn; var Caption: WideString);
begin
if Assigned(OnItemGetEditCaption) then
OnItemGetEditCaption(Self, Item, Column, Caption)
end;
procedure TCustomEasyListview.DoItemGetEditMenu(Editor: TEasyBaseEditor; var Menu: TPopupMenu);
begin
if Assigned(OnItemGetEditMenu) then
OnItemGetEditMenu(Self, Editor, Menu)
end;
procedure TCustomEasyListview.DoItemGetGroupKey(Item: TEasyItem;
FocusedColumn: Integer; var Key: LongWord);
begin
if Assigned(OnItemGetGroupKey) then
OnItemGetGroupKey(Self, Item, FocusedColumn, Key)
end;
procedure TCustomEasyListview.DoItemGetImageIndex(Item: TEasyItem; Column: Integer; ImageKind: TEasyImageKind; var ImageIndex: TCommonImageIndexInteger);
begin
if Assigned(OnItemGetImageIndex) then
OnItemGetImageIndex(Self, Item, Column, ImageKind, ImageIndex)
end;
procedure TCustomEasyListview.DoItemGetImageList(Item: TEasyItem; Column: Integer; var ImageList: TCustomImageList);
begin
if Assigned(OnItemGetImageList) then
OnItemGetImageList(Self, Item, Column, ImageList)
end;
procedure TCustomEasyListview.DoItemGetStateImageList(Item: TEasyItem; Column: Integer; var ImageList: TCustomImageList);
begin
if Assigned(OnItemGetStateImageList) then
OnItemGetStateImageList(Self, Item, Column, ImageList)
end;
procedure TCustomEasyListview.DoItemGetTileDetail(Item: TEasyItem; Line: Integer; var Detail: Integer);
begin
if Assigned(OnItemGetTileDetail) then
OnItemGetTileDetail(Self, Item, Line, Detail)
end;
procedure TCustomEasyListview.DoItemGetTileDetailCount(Item: TEasyItem; var Count: Integer);
begin
if Assigned(OnItemGetTileDetailCount) then
OnItemGetTileDetailCount(Self, Item, Count)
end;
procedure TCustomEasyListview.DoItemImageDraw(Item: TEasyItem; Column: TEasyColumn; ACanvas: TCanvas; const RectArray: TEasyRectArrayObject; AlphaBlender: TEasyAlphaBlender);
begin
if Assigned(OnItemImageDraw) then
OnItemImageDraw(Self, Item, Column, ACanvas, RectArray, AlphaBlender)
end;
procedure TCustomEasyListview.DoItemImageGetSize(Item: TEasyItem; Column: TEasyColumn; var ImageWidth, ImageHeight: Integer);
begin
if Assigned(OnItemImageGetSize) then
OnItemImageGetSize(Self, Item, Column, ImageWidth, ImageHeight)
end;
procedure TCustomEasyListview.DoItemImageDrawIsCustom(Column: TEasyColumn;
Item: TEasyItem; var IsCustom: Boolean);
begin
if Assigned(OnItemImageDrawIsCustom) then
OnItemImageDrawIsCustom(Self, Item, Column, IsCustom)
end;
procedure TCustomEasyListview.DoItemHotTrack(Item: TEasyItem; State: TEasyHotTrackstate; MousePos: TPoint);
begin
if HotTrack.Enabled then
if Assigned(OnItemHotTrack) then
OnItemHotTrack(Self, Item, State, MousePos)
end;
procedure TCustomEasyListview.DoItemInitialize(Item: TEasyItem);
begin
if Assigned(OnItemInitialize) then
OnItemInitialize(Self, Item)
end;
procedure TCustomEasyListview.DoItemLoadFromStream(Item: TEasyItem; S: TStream; Version: Integer);
begin
if Assigned(OnItemLoadFromStream) then
OnItemLoadFromStream(Self, Item, S, Version)
end;
procedure TCustomEasyListview.DoItemMouseDown(Item: TEasyItem; Button: TCommonMouseButton; var DoDefault: Boolean);
begin
if Assigned(OnItemMouseDown) then
OnItemMouseDown(Self, Item, Button, DoDefault)
end;
procedure TCustomEasyListview.DoItemMouseUp(Item: TEasyItem; Button: TCommonMouseButton; var DoDefault: Boolean);
begin
if Assigned(OnItemMouseUp) then
OnItemMouseUp(Self, Item, Button, DoDefault)
end;
procedure TCustomEasyListview.DoItemPaintText(Item: TEasyItem; Position: Integer; ACanvas: TCanvas);
begin
if Assigned(OnItemPaintText) then
OnItemPaintText(Self, Item, Position, ACanvas)
end;
procedure TCustomEasyListview.DoItemSaveToStream(Item: TEasyItem; S: TStream; Version: Integer);
begin
if Assigned(OnItemSaveToStream) then
OnItemSaveToStream(Self, Item, S, Version)
end;
procedure TCustomEasyListview.DoItemSelectionChanged(Item: TEasyItem);
begin
if Assigned(OnItemSelectionChanged) and not (csDestroying in ComponentState) then
OnItemSelectionChanged(Self, Item)
end;
procedure TCustomEasyListview.DoItemSelectionChanging(Item: TEasyItem;
var Allow: Boolean);
begin
if Assigned(OnItemSelectionChanging) and not (csDestroying in ComponentState) then
OnItemSelectionChanging(Self, Item, Allow)
end;
procedure TCustomEasyListview.DoItemSelectionsChanged;
begin
if Assigned(OnItemSelectionsChanged) and not (csDestroying in ComponentState) then
OnItemSelectionsChanged(Self)
end;
procedure TCustomEasyListview.DoItemSetCaption(Item: TEasyItem; Column: Integer; const Caption: WideString);
begin
if Assigned(OnItemSetCaption) then
OnItemSetCaption(Self, Item, Column, Caption)
end;
procedure TCustomEasyListview.DoItemSetGroupKey(Item: TEasyItem;
FocusedColumn: Integer; Key: LongWord);
begin
if Assigned(OnItemSetGroupKey) then
OnItemSetGroupKey(Self, Item, FocusedColumn, Key)
end;
procedure TCustomEasyListview.DoItemSetImageIndex(Item: TEasyItem; Column: Integer; ImageKind: TEasyImageKind; ImageIndex: Integer);
begin
if Assigned(OnItemSetImageIndex) then
OnItemSetImageIndex(Self, Item, Column, ImageKind, ImageIndex)
end;
procedure TCustomEasyListview.DoItemSetTileDetail(Item: TEasyItem; Line: Integer; Detail: Integer);
begin
if Assigned(OnItemSetTileDetail) then
OnItemSetTileDetail(Self, Item, Line, Detail)
end;
procedure TCustomEasyListview.DoItemSetTileDetailCount(Item: TEasyItem; Detail: Integer);
begin
//
end;
procedure TCustomEasyListview.DoItemStructureChange;
begin
if Assigned(OnItemStructureChange) then
OnItemStructureChange(Self)
end;
procedure TCustomEasyListview.DoItemThumbnailDraw(Item: TEasyItem;
ACanvas: TCanvas; ARect: TRect; AlphaBlender: TEasyAlphaBlender;
var DoDefault: Boolean);
begin
if Assigned(OnItemThumbnailDraw) then
OnItemThumbnailDraw(Self, Item, ACanvas, ARect, AlphaBlender, DoDefault)
end;
procedure TCustomEasyListview.DoItemVisibilityChanged(Item: TEasyItem);
begin
if Assigned(OnItemVisibilityChanged) and not (csDestroying in ComponentState) then
OnItemVisibilityChanged(Self, Item)
end;
procedure TCustomEasyListview.DoItemVisibilityChanging(Item: TEasyItem;
var Allow: Boolean);
begin
if Assigned(OnItemVisibilityChanging) and not (csDestroying in ComponentState)then
OnItemVisibilityChanging(Self, Item, Allow)
end;
procedure TCustomEasyListview.DoKeyAction(var CharCode: Word;
var Shift: TShiftState; var DoDefault: Boolean);
begin
if Assigned(OnKeyAction) then
OnKeyAction(Self, CharCode, Shift, DoDefault)
end;
procedure TCustomEasyListview.DoOLEDragEnd(ADataObject: IDataObject; DragResult: TCommonOLEDragResult; ResultEffect: TCommonDropEffects; KeyStates: TCommonKeyStates);
begin
if Assigned(OnOLEDragEnd) then
OnOLEDragEnd(Self, ADataObject, DragResult, ResultEffect, KeyStates);
end;
procedure TCustomEasyListview.DoOLEDragStart(ADataObject: IDataObject;
var AvailableEffects: TCommonDropEffects; var AllowDrag: Boolean);
begin
if Assigned(OnOLEDragStart) then
OnOLEDragStart(Self, ADataObject, AvailableEffects, AllowDrag);
end;
procedure TCustomEasyListview.DoOLEDropSourceGiveFeedback(
Effect: TCommonDropEffects; var UseDefaultCursors: Boolean);
// When the control is the OLE Drag source, this is called when OLE subsystem
// wants to display a different drag cursor (different than the drag image). By
// default the built in cursors are used but the application may set the cursors
// itself in this event
begin
if Assigned(OnOLEGiveFeedback) then
OnOLEGiveFeedback(Self, Effect, UseDefaultCursors)
end;
procedure TCustomEasyListview.DoOLEDropSourceQueryContineDrag(
EscapeKeyPressed: Boolean; KeyStates: TCommonKeyStates;
var QueryResult: TEasyQueryDragResult);
// When the control is the OLE Drag source the OLE subsystem calls back to the
// source to query if the source would like to contine the drag, quit the drag,
// or drop the object where it is.
begin
if Assigned(OnOLEQueryContineDrag) then
OnOLEQueryContineDrag(Self, EscapeKeyPressed, KeyStates, QueryResult)
end;
procedure TCustomEasyListview.DoOLEDropTargetDragDrop(DataObject: IDataObject;
KeyState: TCommonKeyStates; WindowPt: TPoint;
AvailableEffects: TCommonDropEffects; var DesiredEffect: TCommonDropEffect;
var Handled: Boolean);
// When the control is the OLE Drag target this is called when the data object is
// dropped on the control
begin
if Assigned(OnOLEDragDrop) then
OnOLEDragDrop(Self, DataObject, KeyState, WindowPt, AvailableEffects, DesiredEffect, Handled)
end;
procedure TCustomEasyListview.DoOLEDropTargetDragEnter(DataObject: IDataObject;
KeyState: TCommonKeyStates; WindowPt: TPoint; AvailableEffects: TCommonDropEffects;
var DesiredEffect: TCommonDropEffect);
// When the control is the OLE Drag target this is called when the drag object
// first enters the controls client window
begin
if Assigned(OnOLEDragEnter) then
OnOLEDragEnter(Self, DataObject, KeyState, WindowPt, AvailableEffects, DesiredEffect)
end;
procedure TCustomEasyListview.DoOLEDropTargetDragLeave;
// When the control is the OLE Drag target this is called when the data object
// leaves the controls client window
begin
if Assigned(OnOLEDragLeave) then
OnOLEDragLeave(Self)
end;
procedure TCustomEasyListview.DoOLEDropTargetDragOver(KeyState: TCommonKeyStates;
WindowPt: TPoint; AvailableEffects: TCommonDropEffects;
var DesiredEffect: TCommonDropEffect);
// When the control is the OLE Drag target this is called when the data object is
// moving over the controls client window
begin
if Assigned(OnOLEDragOver) then
OnOLEDragOver(Self, KeyState, WindowPt, AvailableEffects, DesiredEffect)
end;
procedure TCustomEasyListview.DoOLEGetCustomFormats(var Formats: TFormatEtcArray);
begin
if Assigned(OnOLEGetCustomFormats) then
OnOLEGetCustomFormats(Self, Formats)
end;
procedure TCustomEasyListview.DoOLEGetData(const FormatEtcIn: TFormatEtc;
var Medium: TStgMedium; var Handled: Boolean);
// Called from the IDataObject when a target wants the source (us) to give it the
// OLE data
begin
FillChar(Medium, SizeOf(Medium), #0);
Handled := False;
if Assigned(OnOLEGetData) then
OnOLEGetData(Self, FormatEtcIn, Medium, Handled);
end;
procedure TCustomEasyListview.DoOLEGetDataObject(var DataObject: IDataObject);
begin
DataObject := nil;
if Assigned(OnOLEGetDataObject) then
OnOLEGetDataObject(Self, DataObject)
end;
procedure TCustomEasyListview.DoPaintBkGnd(ACanvas: TCanvas; AWindowRect: TRect; AlphaBlender: TEasyAlphaBlender; var DoDefault: Boolean);
begin
if Assigned(OnPaintBkGnd) then
OnPaintBkGnd(Self, ACanvas, AWindowRect, AlphaBlender, DoDefault)
end;
procedure TCustomEasyListview.DoPaintHeaderBkGnd(ACanvas: TCanvas; ARect: TRect; var Handled: Boolean);
begin
if Assigned(OnPaintHeaderBkGnd) then
OnPaintHeaderBkGnd(Self, ACanvas, ARect, Handled)
end;
procedure TCustomEasyListview.DoPaintRect(ACanvas: TCanvas; WindowClipRect: TRect;
SelectedOnly: Boolean);
// Paints the control defined by Rect to the passed canvas. Called from the
// WM_PAINT message or can be called to make a snapshot of the control
// ARect is in Window coordinates.
procedure PaintAndGetNextColumn(var Column: TEasyColumn; Item: TEasyItem; ItemRect, ViewClipRect: TRect; OrgPt: TPoint; Clip, ForceSelectionRectDraw: Boolean);
begin
ClipHeader(ACanvas, True);
SetWindowOrgEx(ACanvas.Handle, Scrollbars.OffsetX, Scrollbars.OffsetY - Header.RuntimeHeight, nil);
if Clip then
begin
IntersectRect(ItemRect, ItemRect, ViewClipRect);
IntersectClipRect(ACanvas.Handle, ItemRect.Left, ItemRect.Top, ItemRect.Right, ItemRect.Bottom);
end;
Item.Paint(ACanvas, ViewClipRect, Column, ForceSelectionRectDraw);
Column := Header.NextColumnInRect(Column, ViewClipRect);
end;
procedure PaintReportView(Item: TEasyItem; ViewClipRect: TRect; OrgPt: TPoint);
var
R: TRect;
Column: TEasyColumn;
RectArray: TEasyRectArrayObject;
begin
Column := Header.FirstColumnInRect(ViewClipRect);
if Item.Selected or Item.Hilighted then
begin
if Selection.GroupSelections then
PaintAndGetNextColumn(Column, Item, Item.DisplayRect, ViewClipRect, OrgPt, False, True)
else
if Selection.FullRowSelect then
PaintAndGetNextColumn(Column, Item, Item.DisplayRect, ViewClipRect, OrgPt, True, True);
end;
while Assigned(Column) do
PaintAndGetNextColumn(Column, Item, Item.DisplayRect, ViewClipRect, OrgPt, False, False);
// Special processing for Full Row Select
if Selection.FullRowSelect and Focused and Selection.UseFocusRect and Item.Focused and not SelectedOnly then
begin
// Draw a Focus Rectangle around focused item
ClipHeader(ACanvas, True);
ACanvas.Brush.Color := Color;
ACanvas.Font.Color := clBlack;
Item.ItemRectArray(Header.FirstColumnByPosition, ACanvas, RectArray);
R := Selection.FocusedItem.DisplayRect;
if not Selection.FullCellPaint then
if not Selection.FullItemPaint then
R.Left := RectArray.SelectionRect.Left;
DrawFocusRect(ACanvas.Handle, R);
end
end;
var
Group, FirstVisibleGroup: TEasyGroup;
Item: TEasyItem;
Column: TEasyColumn;
OrgPt: TPoint;
ViewClipRect, R: TRect;
begin
GroupCollapseButton.Canvas.Lock;
GroupExpandButton.Canvas.Lock;
GetWindowOrgEx(Canvas.Handle, OrgPt);
try
// Header accounted for in the DC Offset
ViewClipRect := Scrollbars.MapWindowRectToViewRect(WindowClipRect, True);
if not SelectedOnly then
begin
if Assigned(Background) and not SelectedOnly then
BackGround.PaintTo(ACanvas, WindowClipRect, False);
SelectClipRgn(Canvas.Handle, 0);
if ScrollHeaderHorz then
begin
SetWindowOrgEx(ACanvas.Handle, Scrollbars.OffsetX, 0, nil);
if ViewSupportsHeader and Header.Visible then
Header.PaintTo(ACanvas, ViewClipRect);
end else
begin
if ViewSupportsHeader and Header.Visible then
Header.PaintTo(ACanvas, Rect(0, 0, ClientWidth, Header.RuntimeHeight));
end;
ClipHeader(ACanvas, True);
SetWindowOrgEx(ACanvas.Handle, Scrollbars.OffsetX, Scrollbars.OffsetY - Header.RuntimeHeight, nil);
Group := Groups.FirstGroupInRect(ViewClipRect);
while Assigned(Group) do
begin
Group.Paint(egmeBackground, Group.DisplayRect, ACanvas);
Group.Paint(egmeTop, Group.BoundsRectTopMargin, ACanvas);
Group.Paint(egmeBottom, Group.BoundsRectBottomMargin, ACanvas);
Group.Paint(egmeLeft, Group.BoundsRectLeftMargin, ACanvas);
Group.Paint(egmeRight, Group.BoundsRectRightMargin, ACanvas);
Group.Paint(egmeForeground, Group.DisplayRect, ACanvas);
Group := Groups.NextGroupInRect(Group, ViewClipRect)
end;
end;
SetWindowOrgEx(ACanvas.Handle, Scrollbars.OffsetX, Scrollbars.OffsetY - Header.RuntimeHeight, nil);
SelectClipRgn(ACanvas.Handle, 0);
// Paint the colored column background for the focused node
if not SelectedOnly and ((View = elsReport) or (View = elsGrid)) then
begin
if PaintInfoColumn.HilightFocused and Assigned(Selection.FocusedColumn) then
begin
if Selection.FocusedColumn.SortDirection <> esdNone then
begin
ACanvas.Brush.Color := PaintInfoColumn.HilightFocusedColor;
Group := Groups.FirstVisibleGroup;
while Assigned(Group) do
begin
R := Selection.FocusedColumn.DisplayRect;
R.Top := Scrollbars.OffsetY;
R.Bottom := Scrollbars.OffsetY + (ClientHeight - Header.RuntimeHeight);
if IntersectRect(R, ViewClipRect, R) then
if IntersectRect(R, R, Group.BoundsRectBkGnd) then
ACanvas.FillRect(R);
Group := Groups.NextVisibleGroup(Group)
end
end
end
end;
Item := Groups.FirstItemInRect(ViewClipRect);
// If GroupSelection we always need to paint the first item
if Assigned(Item) and (View = elsReport) and Selection.GroupSelections then
begin
// Need to paint the first item in a selection group
if Assigned(Item.SelectionGroup) then
begin
if not SelectedOnly or (SelectedOnly and Item.Selected) then
begin
PaintReportView(Item.SelectionGroup.FirstItem, ViewClipRect, OrgPt);
// Don't Repaint it
if Item.SelectionGroup.FirstItem = Item then
Item := Groups.NextItemInRect(Item, ViewClipRect);
end
end
end;
while Assigned(Item) do
begin
ClipHeader(ACanvas, True);
// Need to paint the focused item last if its text may overlap another cell when focused
if not Item.Focused or not Item.View.OverlappedFocus then
begin
if not SelectedOnly or (SelectedOnly and Item.Selected) then
begin
if View = elsReport then
PaintReportView(Item, ViewClipRect, OrgPt)
else
Item.Paint(ACanvas, ViewClipRect, nil, False);
end
end;
Item := Groups.NextItemInRect(Item, ViewClipRect);
end;
if Assigned(Selection.FocusedItem) then
if Selection.FocusedItem.View.OverlappedFocus then
Selection.FocusedItem.Paint(ACanvas, ViewClipRect, nil, False);
if not SelectedOnly and ((View = elsReport) or (View = elsGrid)) then
begin
// Paint the Grid Lines
if PaintInfoItem.GridLines then
begin
ClipHeader(ACanvas, True);
FirstVisibleGroup := Groups.FirstVisibleGroup;
ACanvas.Pen.Color := PaintInfoItem.GridLineColor;
Column := Header.FirstColumnInRect(ViewClipRect);
while Assigned(Column) do
begin
Group := FirstVisibleGroup;
while Assigned(Group) do
begin
R := Column.DisplayRect;
ACanvas.MoveTo(R.Right, Group.BoundsRectBkGnd.Top);
ACanvas.LineTo(R.Right, Group.BoundsRectBkGnd.Bottom);
Group := Groups.NextVisibleGroup(Group)
end;
Column := Header.NextColumnInRect(Column, ViewClipRect);
end;
Item := Groups.FirstItemInRect(ViewClipRect);
while Assigned(Item) do
begin
R := Item.DisplayRect;
ACanvas.MoveTo(Scrollbars.OffsetX, R.Bottom-1);
ACanvas.LineTo(Scrollbars.OffsetX + ClientWidth, R.Bottom-1);
Item := Groups.NextItemInRect(Item, ViewClipRect)
end
end
end;
finally
SetWindowOrgEx(ACanvas.Handle, OrgPt.X, OrgPt.Y, nil);
GroupCollapseButton.Canvas.UnLock;
GroupExpandButton.Canvas.UnLock;
end
end;
procedure TCustomEasyListview.DoQueryOLEData(const FormatEtcIn: TFormatEtc;
var FormatAvailable: Boolean; var Handled: Boolean);
// Called from the IDataObject when a target wants the source (us) to tell it
// what formats the DataObject supports
begin
Handled := False;
FormatAvailable := False;
if Assigned(OnOLEQueryData) then
OnOLEQueryData(Self, FormatEtcIn, FormatAvailable, Handled)
end;
procedure TCustomEasyListview.DoResize(DeltaX, DeltaY: Integer);
begin
end;
procedure TCustomEasyListview.DoScroll(DeltaX, DeltaY: Integer);
begin
if Assigned(OnScroll) then
OnScroll(Self, DeltaX, DeltaY)
end;
procedure TCustomEasyListview.DoThreadCallback(var Msg: TWMThreadRequest);
begin
end;
procedure TCustomEasyListview.DoUpdate;
begin
if not(csDestroying in ComponentState) then
begin
Groups.Rebuild(True);
Scrollbars.ReCalculateScrollbars(True, False);
end;
end;
procedure TCustomEasyListview.DoViewChange;
begin
if Assigned(OnViewChange) then
OnViewChange(Self)
end;
procedure TCustomEasyListview.EndUpdate(Invalidate: Boolean = True);
begin
// Sort.EndUpdate;
inherited EndUpdate(Invalidate);
end;
procedure TCustomEasyListview.FinalizeDrag(WindowPoint: TPoint;
KeyState: TCommonKeyStates);
// Called after the mouse is released and a Drag Selection or a D&D operation
// was completed. It cleans up and resets the flags.
begin
// Do these after the flags have been reset in case a resulting operation of
// these calls checks if the dragging is still occuring
if ebcsDragging in States then
begin
Exclude(FStates, ebcsDragging);
DragManager.DragEnd(Canvas, WindowPoint, KeyState);
end;
if ebcsDragSelecting in States then
begin
Exclude(FStates, ebcsDragSelecting);
DragRect.DragEnd(Canvas, WindowPoint, KeyState);
end;
ClearStates;
Mouse.Capture := 0;
end;
procedure TCustomEasyListview.HandleDblClick(Button: TCommonMouseButton; Msg: TWMMouse);
var
Group: TEasyGroup;
Keys: TCommonKeyStates;
GroupHitInfo: TEasyGroupHitTestInfoSet;
GroupInfo: TEasyHitInfoGroup;
Item: TEasyItem;
ItemHitInfo: TEasyItemHitTestInfoSet;
ItemInfo: TEasyHitInfoItem;
ViewPt: TPoint;
begin
Keys := KeyToKeyStates(Msg.Keys);
ViewPt := Scrollbars.MapWindowToView(Msg.Pos);
if ViewSupportsHeader and (Header.Visible) and (Msg.YPos < Header.Height) then
Header.WMLButtonDblClk(Msg)
else begin
Item := Groups.ItembyPoint(ViewPt);
DoDblClick(Button, SmallPointToPoint(Msg.Pos), KeysToShiftState(Msg.Keys));
if Assigned(Item) then
begin
Item.HitTestAt(ViewPt, ItemHitInfo);
ItemInfo.Group := Item.OwnerGroup;
ItemInfo.Item := Item;
if ViewSupportsHeader then
ItemInfo.Column := Header.Columns.ColumnByPoint(ViewPt)
else
ItemInfo.Column := nil;
ItemInfo.HitInfo := ItemHitInfo;
DoItemDblClick(Button, SmallPointToPoint(Msg.Pos), ItemInfo)
end else
begin
Group := Groups.GroupByPoint(ViewPt);
if Assigned(Group) then
begin
Group.HitTestAt(ViewPt, GroupHitInfo);
GroupInfo.Group := Group;
GroupInfo.HitInfo := GroupHitInfo;
DoGroupDblClick(Button, SmallPointToPoint(Msg.Pos), GroupInfo)
end
end
end
end;
procedure TCustomEasyListview.HandleKeyDown(Msg: TWMKeyDown);
procedure MoveFocus(KeyStates: TShiftState; Item: TEasyItem);
begin
if Assigned(Item) then
begin
// Do this underhanded so we don't cause a grid rebuild but will keep the
// window from getting WM_PAINT messages until we are done
Inc(FUpdateCount);
try
if Selection.FocusedItem <> Item then
begin
if not Selection.Enabled and Selection.UseFocusRect then
Selection.FocusedItem := Item
else
if ssCtrl in KeyStates then
Selection.FocusedItem := Item
else
if ssShift in KeyStates then
begin
if Assigned(Selection.AnchorItem) then
begin
Selection.SelectRange(Selection.AnchorItem, Item, Selection.RectSelect, True);
Selection.FocusedItem := Item;
Selection.FocusedItem.Selected := True;
end else
begin
Selection.ClearAll;
Selection.FocusedItem := Item;
Selection.FocusedItem.Selected := True;
end
end else
begin
Selection.ClearAll;
Selection.FocusedItem := Item;
Selection.FocusedItem.Selected := True;
Selection.AnchorItem := Selection.FocusedItem;
end;
end;
finally
if Assigned(Selection.FocusedItem) then
begin
if Selection.FocusedItem.DisplayRect.Top < ClientInViewportCoords.Top + (RectHeight(ClientInViewportCoords) div 2) then
Selection.FocusedItem.MakeVisible(emvAuto {emvTop})
else
Selection.FocusedItem.MakeVisible(emvAuto{emvBottom});
end;
Dec(FUpdateCount);
UpdateWindow(Handle);
end
end
end;
function FocusFirst: Boolean;
var
Item: TEasyItem;
begin
Result := False;
if not Assigned(Selection.FocusedItem) then
begin
Item := Groups.FirstVisibleItem;
if Assigned(Item) then
begin
Selection.FocusedItem := Item;
Result := True
end
end
end;
var
Item: TEasyItem;
KeyStates: TShiftState;
Handled, Mark: Boolean;
begin
KeyStates := KeyDataToShiftState(Msg.KeyData);
Selection.IncMultiChangeCount;
try
case Msg.CharCode of
VK_RIGHT:
begin
if Selection.Enabled or Selection.UseFocusRect then
begin
if not FocusFirst then
begin
Item := Groups.AdjacentItem(Selection.FocusedItem, acdRight);
MoveFocus(KeyStates, Item);
end
end else
Scrollbars.OffsetX := Scrollbars.OffsetX + 1;
end;
VK_LEFT:
begin
if Selection.Enabled or Selection.UseFocusRect then
begin
if not FocusFirst then
begin
Item := Groups.AdjacentItem(Selection.FocusedItem, acdLeft);
MoveFocus(KeyStates, Item);
end
end else
Scrollbars.OffsetX := Scrollbars.OffsetX - 1;
end;
VK_UP:
begin
if Selection.Enabled or Selection.UseFocusRect then
begin
if not FocusFirst then
begin
Item := Groups.AdjacentItem(Selection.FocusedItem, acdUp);
MoveFocus(KeyStates, Item);
end
end else
Scrollbars.OffsetY := Scrollbars.OffsetY + 1;
end;
VK_DOWN:
begin
if Selection.Enabled or Selection.UseFocusRect then
begin
if not FocusFirst then
begin
Item := Groups.AdjacentItem(Selection.FocusedItem, acdDown);
// Special case with one item
if not Assigned(Item) and (Selection.Count = 0) and (Groups.ItemCount = 1) then
begin
Selection.FocusedItem := nil;
Item := Groups.FirstItem;
end;
MoveFocus(KeyStates, Item);
end
end else
Scrollbars.OffsetY := Scrollbars.OffsetY + 1;
end;
VK_HOME:
begin
if Selection.Enabled or Selection.UseFocusRect then
begin
if not FocusFirst then
begin
Item := Groups.FirstVisibleItem;
MoveFocus(KeyStates, Item);
end
end else
begin
Scrollbars.OffsetX := 0;
Scrollbars.OffsetY := 0;
end
end;
VK_END:
begin
if Selection.Enabled or Selection.UseFocusRect then
begin
if not FocusFirst then
begin
Item := Groups.LastVisibleItem;
MoveFocus(KeyStates, Item);
end
end else
begin
Scrollbars.OffsetX := Scrollbars.MaxOffsetX;
Scrollbars.OffsetY := Scrollbars.MaxOffsetY;
end
end;
VK_NEXT:
begin
if Selection.Enabled or Selection.UseFocusRect then
begin
if not FocusFirst then
begin
Item := Groups.AdjacentItem(Selection.FocusedItem, acdPageDown);
MoveFocus(KeyStates, Item);
end
end else
Scrollbars.OffsetY := Scrollbars.OffsetY + ClientHeight;
end;
VK_PRIOR:
begin
if Selection.Enabled or Selection.UseFocusRect then
begin
if not FocusFirst then
begin
Item := Groups.AdjacentItem(Selection.FocusedItem, acdPageUp);
MoveFocus(KeyStates, Item);
end
end else
Scrollbars.OffsetY := Scrollbars.OffsetY - ClientHeight;
end;
VK_F2:
begin
if Assigned(Selection.FocusedItem) then
begin
EditManager.BeginEdit(Selection.FocusedItem, nil)
end;
end;
VK_SPACE:
begin
if Assigned(Selection.FocusedItem) then
if Selection.FocusedItem.PaintInfo.CheckType in [ectBox, ectRadio] then
Selection.FocusedItem.Checked := not Selection.FocusedItem.Checked
end;
VK_ADD:
begin
if (ssCtrl in KeyStates) then
AutoFitAllCells(True)
end;
Ord('A'),
Ord('a'):
begin
if ssCtrl in KeyStates then
Selection.SelectAll
end;
Ord('C'), Ord('c'): // Ctrl + 'C' Copy
begin
if ssCtrl in KeyStates then
begin
Handled := False;
DoClipboardCopy(Handled);
if not Handled then
CopyToClipboard;
end
end;
Ord('X'), Ord('x'): // Ctrl + 'X' Cut
begin
if ssCtrl in KeyStates then
begin
Handled := False;
Mark := True;
DoClipboardCut(Mark, Handled);
if not Handled then
CutToClipboard
else
if Mark then
MarkSelectedCut
end
end;
Ord('V'), Ord('v'): // // Ctrl + 'V' Paste
begin
if ssCtrl in KeyStates then
begin
Handled := False;
DoClipboardPaste(Handled);
if not Handled then
PasteFromClipboard;
end
end;
VK_ESCAPE:
begin
CancelCut;
Invalidate;
end;
end
finally
Selection.DecMultiChangeCount
end
end;
procedure TCustomEasyListview.HandleMouseDown(Button: TCommonMouseButton; Msg: TWMMouse);
var
WindowPt: TPoint;
KeyState: TCommonKeyStates;
Group: TEasyGroup;
Item: TEasyItem;
GroupHitInfo: TEasyGroupHitTestInfoSet;
ItemHitInfo: TEasyItemHitTestInfoSet;
MouseDown, StartTimer, CtlDown, ShiftDown: Boolean;
Allow, DoDefaultItemDown: Boolean;
begin
Item := nil;
KeyState := KeyToKeyStates(Msg.Keys);
WindowPt := Scrollbars.MapWindowToView(Msg.Pos);
MouseDown := KeyState * [cksLButton, cksMButton, cksRButton] <> [];
CtlDown := cksControl in KeyState;
ShiftDown := cksShift in KeyState;
Gesture.Path := '';
Group := ClickTestGroup(WindowPt, KeyState, GroupHitInfo);
if Assigned(Group) then
begin
// First see if the group expand button or checkbox was hit
if GroupTestExpand(GroupHitInfo) then
begin
// Only the left button can expand
if Button = cmbLeft then
begin
// Deal with the expansion in the mouse down
Allow := True;
if Group.Expanded then
DoGroupCollapsing(Group, Allow)
else
DoGroupExpanding(Group, Allow);
if Allow then
begin
BeginUpdate;
try
Include(FStates, ebcsGroupExpandPending);
Group.Expanded := not Group.Expanded;
// Need to make sure focused item is not in the collapsed group.
if not Group.Expanded and Assigned(Selection.FocusedItem) then
begin
if Selection.FocusedItem.OwnerGroup = Group then
begin
Item := Groups.NextVisibleItem(Selection.FocusedItem);
while Assigned(Item) do
begin
if Item.Enabled then
Break
else
Item := Groups.NextVisibleItem(Item)
end;
Selection.FocusedItem := Item;
end
end
finally
EndUpdate
end
end;
end
end else
// Next see if it hit the Group CheckBox
if egtOnCheckbox in GroupHitInfo then
begin
// Only the left button can Check Groups
if Button = cmbLeft then
begin
Include(FStates, ebcsCheckboxClickPending);
HotTrack.PendingObjectCheck := nil;
CheckManager.PendingObject := Group;
end
end else
begin
if Group.Expanded then
begin
// Exhausted Group hit tests, move into Item level testing
Item := ClickTestItem(WindowPt, Group, KeyState, ItemHitInfo);
if Assigned(Item) then
begin
DoDefaultItemDown := True;
DoItemMouseDown(Item, Button, DoDefaultItemDown);
if DoDefaultItemDown then
begin
// First see it the hit was on the items check box
if ehtOnCheck in ItemHitInfo then
begin
// Only the left button can Check Items
if Button = cmbLeft then
begin
Include(FStates, ebcsCheckboxClickPending);
HotTrack.PendingObjectCheck := nil;
CheckManager.PendingObject := Item;
end
end else
// Next see if Selection is enabled and if so handle item selection
// through direct hit or drag rectangle
if Selection.Enabled then
begin
Selection.IncMultiChangeCount;
Selection.GroupSelectBeginUpdate;
try
if Item.SelectionHitPt(WindowPt, eshtClickselect) then
begin
if MouseDown and (Button in Selection.MouseButton) then
begin
// See if the user click on the item a second time, if so get ready for
// an edit
StartTimer := (Button = cmbLeft) and ((Selection.Count = 1) and ((Selection.FocusedItem = Item) and Item.EditAreaHitPt(WindowPt) and Item.Selected)) and Focused;
if Selection.MultiSelect then
begin
// Multi Selection Mode.........
if not Item.Selected and not(CtlDown or ShiftDown) then
Selection.ClearAll;
// Focus the item if the Ctl key is not down. It will be done in the ButtonUp event
if (Selection.FocusedItem <> Item) and not CtlDown then
Selection.FocusedItem := Item;
if not( CtlDown or ShiftDown) then
begin
Selection.AnchorItem := Item;
end else
begin
if not ShiftDown then
Selection.AnchorItem := Item
else
Selection.SelectRange(Selection.AnchorItem, Item, Selection.RectSelect, not CtlDown);
end
end else
begin
// Single Selection Mode.........
// Set the Focus to the hit item
if (Selection.FocusedItem <> Item) then
Selection.FocusedItem := Item;
Selection.AnchorItem := Item;
Selection.ClearAll;
end;
// CtlClick then it will be selected in the Mouse Up
if not CtlDown then
Item.Selected := True;
// This test allows descendent to cancel out of drags incase they do something in the Focus or Selection Changing events
if (((Button in DragRect.MouseButton) or (Button in DragManager.MouseButton)) and (States * [ebcsLButtonDown, ebcsRButtonDown, ebcsMButtonDown] <> [])) then
InitializeDragPendings(Item, SmallPointToPoint(Msg.Pos), KeyToKeyStates(Msg.Keys), Item.AllowDrag(WindowPt), True);
if StartTimer then
begin
EditManager.AutoEditStartClickPt := WindowPt;
EditManager.StartAutoEditTimer;
end
end else
begin
if (Button in DragManager.MouseButton) and (States * [ebcsLButtonDown, ebcsRButtonDown, ebcsMButtonDown] <> []) then
InitializeDragPendings(Item, SmallPointToPoint(Msg.Pos), KeyToKeyStates(Msg.Keys), True, False);
end
end else
begin
// All mouse button down actions trigger the same events
// Since it is unknown what the user is trying to do yet
if (Button in DragRect.MouseButton) and (States * [ebcsLButtonDown, ebcsRButtonDown, ebcsMButtonDown] <> []) then
InitializeDragPendings(Item, SmallPointToPoint(Msg.Pos), KeyToKeyStates(Msg.Keys), False, True);
end
finally
Selection.GroupSelectEndUpdate;
Selection.DecMultiChangeCount
end
end else
if Selection.UseFocusRect then
begin
if Item.SelectionHitPt(WindowPt, eshtClickselect) then
Selection.FocusedItem := Item
end
end
end else
begin
// All mouse button down actions trigger the same events
// Since it is unknown what the user is trying to do yet
if (Button in DragRect.MouseButton) and (States * [ebcsLButtonDown, ebcsRButtonDown, ebcsMButtonDown] <> []) then
InitializeDragPendings(Item, SmallPointToPoint(Msg.Pos), KeyToKeyStates(Msg.Keys), False, True);
end
end else
// Did not hit an anything so get ready for a drag rectangle
if (Button in DragRect.MouseButton) and (States * [ebcsLButtonDown, ebcsRButtonDown, ebcsMButtonDown] <> []) then
InitializeDragPendings(Item, SmallPointToPoint(Msg.Pos), KeyToKeyStates(Msg.Keys), False, True);
end;
end else
begin
// All mouse button down actions trigger the same events
// Since it is unknown what the user is trying to do yet
// Did not hit a group so get ready for a drag rectangle
if (Button in DragRect.MouseButton) and (States * [ebcsLButtonDown, ebcsRButtonDown, ebcsMButtonDown] <> []) then
InitializeDragPendings(Item, SmallPointToPoint(Msg.Pos), KeyToKeyStates(Msg.Keys), False, True);
end;
end;
procedure TCustomEasyListview.HandleMouseUp(Button: TCommonMouseButton; Msg: TWMMouse);
// Called when the Left Mouse button is released
var
Pt: TPoint;
KeyState: TCommonKeyStates;
GroupHitInfo: TEasyGroupHitTestInfoSet;
ItemHitInfo: TEasyItemHitTestInfoSet;
Group: TEasyGroup;
Item: TEasyItem;
GesturedHandled: Boolean;
CtlDown, ShiftDown, DoDefaultItemUp: Boolean;
begin
Group := nil;
KeyState := KeyToKeyStates(Msg.Keys);
CtlDown := cksControl in KeyState;
ShiftDown := cksShift in KeyState;
Pt := Scrollbars.MapWindowToView(Msg.Pos);
GesturedHandled := False;
if Gesture.Enabled and (Gesture.Path <> '') and ([ebcsGroupExpandPending, ebcsCheckboxClickPending, ebcsDragSelecting, ebcsDragging] * States = []) then
DoGesture(Gesture.Path, GesturedHandled);
// In some cases we can get a mouse up message without a corresponding mouse
// down message. For example if we full expand the application if the mouse
// is over the Easy window after the expand we get a mouse up message
if ([ebcsLButtonDown, ebcsRButtonDown, ebcsMButtonDown] * States <> []) then
begin
if ebcsGroupExpandPending in States then
begin
// Don't do any other processing if the group expand button was clicked
end else
if ebcsCheckboxClickPending in States then
begin
Group := ClickTestGroup(Pt, KeyState, GroupHitInfo);
if CheckManager.PendingObject is TEasyGroup then
begin
if (egtOnCheckbox in GroupHitInfo) and Assigned(Group) then
Group.Checked := not Group.Checked;
end else
if CheckManager.PendingObject is TEasyItem then
begin
Item := ClickTestItem(Pt, Group, KeyState, ItemHitInfo);
if (ehtOnCheck in ItemHitInfo) and Assigned(Item) then
Item.Checked := not Item.Checked
end;
CheckManager.PendingObject.CheckHovering := False;
CheckManager.PendingObject.CheckPending := False;
CheckManager.PendingObject := nil;
end else
if ebcsDragSelecting in States then
begin
FinalizeDrag(SmallPointToPoint(Msg.Pos), KeyToKeyStates(Msg.Keys));
end else
if ebcsDragging in States then
begin
// The VCL will send us a fake mouse button up when the drag starts.
// This screws everything. We will send a mouse up after the drag ends
// with the cbcsVCLDrag cleared
if not(ebcsVCLDrag in States) then
FinalizeDrag(SmallPointToPoint(Msg.Pos), KeyToKeyStates(Msg.Keys));
end else
begin
// If not dragging or drag selecting then check if it is necessary to unselect
// the items
if not GesturedHandled then
begin
Item := ClickTestItem(Pt, Group, KeyState, ItemHitInfo);
if Assigned(Item) then
begin
DoDefaultItemUp := True;
DoItemMouseUp(Item, Button, DoDefaultItemUp);
if DoDefaultItemUp then
begin
DoItemClick(Item, KeyToKeyStates(Msg.Keys), ItemHitInfo);
if not Item.SelectionHitPt(Pt, eshtClickselect) then
Selection.ClearAll
else begin
// Allow MultiSelect
if Selection.MultiSelect then
begin
if not (ShiftDown or CtlDown) and (not Item.Selected or (Button = cmbLeft)) then
Selection.ClearAllExcept(Item)
else begin
if CtlDown then
begin
EditManager.StopAutoEditTimer;
if not ShiftDown then
Item.Selected := not Item.Selected;
Item.Focused := True;
end
end
end
end
end
end else
begin
Group := ClickTestGroup(Pt, KeyToKeyStates(Msg.Keys), GroupHitInfo);
if Assigned(Group) then
DoGroupClick(Group, KeyToKeyStates(Msg.Keys), GroupHitInfo);
Selection.ClearAll
end
end
end
end;
end;
procedure TCustomEasyListview.InitializeDragPendings(HitItem: TEasyItem; WindowPoint: TPoint; KeyState: TCommonKeyStates; AllowDrag, AllowDragRect: Boolean);
// Called from the mouse down messages. It initializes the DragManager and the
// DragSelection Manager to prepare for a possible action. If the click was not
// on an item then it is interperted as a drag select. If it hit an item it
// is interperted as a D&D action.
var
StartSelectDrag, StartDrag: Boolean;
Pt: TPoint;
begin
// At least NT4 does not set the focus on a mouse click
CheckFocus;
Mouse.Capture := Handle;
// Initialize both Drag Select and Drag object just in case
StartSelectDrag := AllowDragRect and DragRect.InitializeDrag(WindowPoint, KeyState);
StartDrag := AllowDrag and DragManager.InitializeDrag(HitItem, WindowPoint, KeyState);
Pt := Scrollbars.MapWindowToView(WindowPoint);
if Assigned(DragManager.DragItem) and StartDrag then
begin
Include(FStates, ebcsDragPending);
DragRect.FinalizeDrag(KeyState)
end else
if StartSelectDrag then
begin
Include(FStates, ebcsDragSelectPending);
DragManager.FinalizeDrag(KeyState)
end;
end;
function TCustomEasyListview.IsGrouped: Boolean;
begin
// Default definition that the control is in grouped mode is if the Top Margin is enabled
Result := PaintInfoGroup.MarginTop.Visible
end;
procedure TCustomEasyListview.Loaded;
begin
inherited;
DoUpdate;
end;
procedure TCustomEasyListview.LoadFromFile(FileName: WideString; Mode: Word);
var
F: TWideFileStream;
begin
F := TWideFileStream.Create(FileName, Mode);
try
LoadFromStream(F)
finally
F.Free
end
end;
procedure TCustomEasyListview.LoadFromStream(S: TStream);
var
Version: Integer;
AView: TEasyListStyle;
begin
BeginUpdate;
try
S.Read(Version, SizeOf(Version));
if Version > 0 then
begin
S.Read(AView, SizeOf(AView));
View := AView;
Groups.LoadFromStream(S, Version);
Header.LoadFromStream(S, Version);
Groups.Rebuild(True);
end;
{ if Version > n then
begin
end; }
finally
EndUpdate
end
end;
procedure TCustomEasyListview.MarkSelectedCut;
var
Item: TEasyItem;
begin
CancelCut;
Item := Selection.First;
while Assigned(Item) do
begin
Item.Cut := True;
Item := Selection.Next(Item)
end
end;
procedure TCustomEasyListview.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited;
if Operation = opRemove then
begin
if AComponent = FImagesGroup then
FImagesGroup := nil;
if AComponent = FImagesExLarge then
FImagesExLarge := nil;
if AComponent = FImagesLarge then
FImagesLarge := nil;
if AComponent = FImagesSmall then
FImagesSmall := nil;
if AComponent = FImagesState then
FImagesState := nil;
if AComponent = Header.Images then
Header.Images := nil;
end
end;
procedure TCustomEasyListview.PasteFromClipboard;
var
Handled: Boolean;
begin
Handled := False;
DoClipboardPaste(Handled)
end;
procedure TCustomEasyListview.ResizeBackBits(NewWidth, NewHeight: Integer);
// Resizes the Bitmap for the DoubleBuffering. Called mainly when the window
// is resized. Note the bitmap only gets larger to maximize speed during dragging
begin
if CacheDoubleBufferBits and Assigned(BackBits) then
begin
// The Backbits grow to the largest window size
if (NewWidth > BackBits.Width) then
begin
if NewWidth > 0 then
BackBits.Width := NewWidth
else
BackBits.Width := 1
end;
if NewHeight > BackBits.Height then
begin
if NewHeight > 0 then
BackBits.Height := NewHeight
else
BackBits.Height := 1;
end
end
end;
procedure TCustomEasyListview.SaveToFile(FileName: WideString; Mode: Word);
var
F: TWideFileStream;
begin
F := TWideFileStream.Create(FileName, Mode);
try
SaveToStream(F)
finally
F.Free
end
end;
procedure TCustomEasyListview.SaveToStream(S: TStream);
var
Version: Integer;
begin
Version := EASYLISTVIEW_STREAM_VERSION;
S.Write(Version, SizeOf(Version));
S.Write(View, SizeOf(View));
Groups.SaveToStream(S, Version);
Header.SaveToStream(S, Version)
end;
procedure TCustomEasyListview.SetBackGround(const Value: TEasyBackgroundManager);
begin
if Assigned(FBackGround) then
FreeAndNil(FBackGround);
FBackGround := Value;
end;
procedure TCustomEasyListview.SetCacheDoubleBufferBits(const Value: Boolean);
begin
if FCacheDoubleBufferBits <> Value then
begin
FCacheDoubleBufferBits := Value;
if Value then
begin
if not Assigned(FBackBits) then
begin
FBackBits := TBitmap.Create;
FBackBits.PixelFormat := pf32Bit
end
end else
FreeAndNil(FBackBits)
end
end;
procedure TCustomEasyListview.SetGroupCollapseImage(Value: TBitmap);
begin
FGroupCollapseButton.Assign(Value);
if Assigned(FGroupCollapseButton) then
FGroupCollapseButton.PixelFormat := pf32Bit
end;
procedure TCustomEasyListview.SetGroupExpandImage(Value: TBitmap);
begin
FGroupExpandButton.Assign(Value);
if Assigned(FGroupExpandButton) then
FGroupExpandButton.PixelFormat := pf32Bit
end;
procedure TCustomEasyListview.SetGroupFont(Value: TFont);
begin
FGroupFont.Assign(Value)
end;
procedure TCustomEasyListview.SetHintType(Value: TEasyHintType);
begin
HintInfo.HintType := Value
end;
procedure TCustomEasyListview.SetImagesExLarge(Value: TCustomImageList);
begin
if Value <> FImagesExLarge then
begin
FImagesExLarge := Value;
SafeInvalidateRect(nil, False);
end
end;
procedure TCustomEasyListview.SetImagesGroup(Value: TCustomImageList);
begin
if Value <> FImagesGroup then
begin
FImagesGroup := Value;
SafeInvalidateRect(nil, False);
end
end;
procedure TCustomEasyListview.SetImagesLarge(Value: TCustomImageList);
begin
if Value <> FImagesLarge then
begin
FImagesLarge := Value;
SafeInvalidateRect(nil, False);
end
end;
procedure TCustomEasyListview.SetImagesSmall(Value: TCustomImageList);
begin
if Value <> FImagesSmall then
begin
FImagesSmall := Value;
SafeInvalidateRect(nil, False);
end
end;
procedure TCustomEasyListview.SetImagesState(const Value: TCustomImageList);
begin
if Value <> FImagesState then
begin
FImagesState := Value;
SafeInvalidateRect(nil, False);
end
end;
procedure TCustomEasyListview.SetPaintInfoColumn(const Value: TEasyPaintInfoBaseColumn);
begin
if Value <> FPaintInfoColumn then
begin
FreeAndNil(FPaintInfoColumn);
FPaintInfoColumn := Value;
end
end;
procedure TCustomEasyListview.SetPaintInfoGroup(const Value: TEasyPaintInfoBaseGroup);
begin
if Value <> FPaintInfoGroup then
begin
FreeAndNil(FPaintInfoGroup);
FPaintInfoGroup := Value;
end
end;
procedure TCustomEasyListview.SetPaintInfoItem(const Value: TEasyPaintInfoBaseItem);
begin
if Value <> FPaintInfoItem then
begin
FreeAndNil(FPaintInfoItem);
FPaintInfoItem := Value;
end
end;
procedure TCustomEasyListview.SetSelection(Value: TEasySelectionManager);
begin
if Value <> FSelection then
begin
FreeAndNil(FSelection);
FSelection := Value
end
end;
procedure TCustomEasyListview.SetShowGroupMargins(const Value: Boolean);
begin
if FShowGroupMargins <> Value then
begin
FShowGroupMargins := Value;
DoUpdate;
end;
end;
procedure TCustomEasyListview.SetShowInactive(const Value: Boolean);
begin
if FShowInactive <> Value then
begin
FShowInactive := Value;
SafeInvalidateRect(nil, True)
end
end;
procedure TCustomEasyListview.SetShowThemedBorder(Value: Boolean);
begin
if Value <> FShowThemedBorder then
begin
FShowThemedBorder := Value;
// Need to modify the NonClient area
RecreateWnd;
end
end;
procedure TCustomEasyListview.SetView(Value: TEasyListStyle);
begin
if FView <> Value then
begin
FView := Value;
Groups.Rebuild(True);
if IsVertView then
WheelMouseDefaultScroll := edwsVert
else
WheelMouseDefaultScroll := edwsHorz;
end
end;
procedure TCustomEasyListview.WMChar(var Msg: TWMChar);
begin
inherited;
IncrementalSearch.HandleWMChar(Msg);
end;
procedure TCustomEasyListview.WMClose(var Msg: TWMClose);
begin
EditManager.EndEdit;
inherited;
end;
procedure TCustomEasyListview.WMContextMenu(var Msg: TMessage);
var
Item: TEasyItem;
Group: TEasyGroup;
Pt: TPoint;
HitInfoGroup: TEasyHitInfoGroup;
HitInfoItem: TEasyHitInfoItem;
Menu: TPopupMenu;
Handled, SkipHitTest, MenuKey: Boolean;
begin
if not EditManager.Editing and not (Gesture.Enabled and (Gesture.Path <> '')) then
begin
Handled := False;
MenuKey := False;
if not (ebcsCancelContextMenu in States) then
begin
SkipHitTest := False;
// Support Dual monitors with SmallPointToPoint
Pt:= SmallPointToPoint(SmallPoint(Msg.LParamLo, Msg.LParamHi));
if ((Pt.X = 65535) and (Pt.Y = 65535)) or ((Pt.X = -1) and (Pt.Y = -1)) then
begin
MenuKey := True;
Pt := ScreenToClient(Mouse.CursorPos);
if not PtInRect(ClientRect, Pt) or (Selection.Count = 0) then
begin
Pt.X := 0;
Pt.Y := 0;
SkipHitTest := True;
end;
Pt := ClientToScreen(Pt);
end;
if MenuKey and (Selection.Count > 0) then
begin
HitInfoItem.Item := Selection.First;
Pt := ClientToScreen(HitInfoItem.Item.DisplayRect.TopLeft);
Pt.Y := Pt.Y + Header.RuntimeHeight;
HitInfoItem.Column := nil;
HitInfoItem.Group := HitInfoItem.Item.OwnerGroup;
HitInfoItem.HitInfo := [ehtOnLabel, ehtOnIcon];
DoItemContextMenu(HitInfoItem, Pt, Menu, Handled)
end else
if not SkipHitTest then
begin
if IsHeaderMouseMsg(PointToSmallPoint( ScreenToClient(Pt))) then
begin
Pt := ClientToScreen(Pt);
Header.WMContextMenu(Msg);
Handled := True;
end else
begin
Menu := nil;
Exclude(FStates, ebcsDragSelectPending);
Exclude(FStates, ebcsDragPending);
Handled := False;
Group := Groups.GroupByPoint(Scrollbars.MapWindowToView(ScreenToClient(Pt)));
if Assigned(Group) then
begin
// The hit was in a group so now see if it was in an item
Item := Group.ItembyPoint(Scrollbars.MapWindowToView( ScreenToClient(Pt)));
if Assigned(Item) then
begin
if Item.HitTestAt(Scrollbars.MapWindowToView( ScreenToClient(Pt)), HitInfoItem.HitInfo) then
begin
HitInfoItem.Column := nil;
HitInfoItem.Group := Group;
HitInfoItem.Item := Item;
DoItemContextMenu(HitInfoItem, Pt, Menu, Handled)
end
end;
if not Assigned(Menu) and not Handled then
begin
HitInfoGroup.Group := Group;
Group.HitTestAt(Scrollbars.MapWindowToView(ScreenToClient(Pt)), HitInfoGroup.HitInfo);
DoGroupContextMenu(HitInfoGroup, Pt, Menu, Handled)
end
end
end
end;
if not Handled then
DoContextMenu(Pt, Handled);
if Assigned(Menu) and not Handled then
begin
Menu.Popup(Msg.LParamLo, Msg.LParamHi);
Msg.Result := 1
end else
if not Handled then
inherited // Use the PopupMenu property from TControl
end;
end else
begin
Msg.Result := 1;
inherited
end;
Exclude(FStates, ebcsCancelContextMenu);
end;
procedure TCustomEasyListview.WMDestroy(var Msg: TMessage);
begin
EditManager.EndEdit;
DragManager.Registered := False;
Header.DragManager.Registered := False;
inherited;
end;
procedure TCustomEasyListview.WMEasyThreadCallback(var Msg: TWMThreadRequest);
begin
DoThreadCallback(Msg)
end;
procedure TCustomEasyListview.WMEraseBkGnd(var Msg: TWMEraseBkGnd);
begin
Msg.Result := 1;
end;
procedure TCustomEasyListview.WMGetDlgCode(var Msg: TWMGetDlgCode);
// The VCL forms use the Dialog Window Proc so we need to tell windows we want
// the arrow keys for navigation
begin
Msg.Result := Msg.Result or DLGC_WANTALLKEYS or DLGC_WANTARROWS or DLGC_WANTCHARS;
end;
procedure TCustomEasyListview.WMHScroll(var Msg: TWMHScroll);
// Called to scroll the Window, the Window is responsible for actually performing
// the scroll
begin
inherited;
if Msg.ScrollCode <> SB_ENDSCROLL then
Include(FStates, ebcsScrolling)
else
Exclude(FStates, ebcsScrolling);
ScrollBars.WMHScroll(Msg);
SafeInvalidateRect(nil, False);
end;
procedure TCustomEasyListview.WMKeyDown(var Msg: TWMKeyDown);
// Called when the user pressed a key on the keyboard. The Scrollbars need to
// know in case the user is scrolling using the keys.
var
Shift: TShiftState;
DoDefault: Boolean;
begin
inherited;
if (ebcsDragSelecting in States) then
begin
DragRect.WMKeyDown(Msg);
end else
begin
IncrementalSearch.HandleWMKeyDown(Msg);
Shift := KeyDataToShiftState(Msg.KeyData);
DoDefault := True;
DoKeyAction(Msg.CharCode, Shift, DoDefault);
if DoDefault then
HandleKeyDown(Msg);
end;
end;
procedure TCustomEasyListview.WMKillFocus(var Msg: TWMKillFocus);
begin
inherited;
if HotTrack.OnlyFocused then
HotTrack.PendingObject[Point(0, 0)] := nil;
SafeInvalidateRect(nil, True);
end;
procedure TCustomEasyListview.WMLButtonDblClk(var Msg: TWMLButtonDblClk);
begin
// Cancel the edit (called in WMLButtonDown)
EditManager.EndEdit;
inherited;
HandleDblClick(cmbLeft, Msg);
end;
procedure TCustomEasyListview.WMLButtonDown(var Msg: TWMLButtonDown);
// Called when the Left Mouse button is pressed
begin
Include(FStates, ebcsLButtonDown);
CheckFocus;
if IsHeaderMouseMsg(Msg.Pos) then
begin
// Should this call a Column manager or a Column?
if Assigned(Header) then
begin
Header.CaptureMouse;
Header.WMLButtonDown(Msg);
end
end else
begin
inherited;
HandleMouseDown(cmbLeft, Msg)
end;
LastMousePos := Msg.Pos
end;
procedure TCustomEasyListview.WMLButtonUp(var Msg: TWMLButtonUp);
// Called when the Left Mouse button is released
begin
if IsHeaderMouseMsg(Msg.Pos) then
begin
// Should this call a Column manager or a Column?
if Assigned(Header) then
begin
Header.WMLButtonUp(Msg);
// Need to allow HotTracking to finish up.
Header.WMMouseMove(Msg);
Header.ReleaseMouse;
end
end else
begin
// The VCL D&D will "Perform" a Left Button Up when StartDrag is called. As such
// a lot of the State Flags get prematurely reset.
if not (ebcsVCLDrag in States) then
ClearPendingDrags;
inherited;
HandleMouseUp(cmbLeft, Msg);
Mouse.Capture := 0;
end;
// ClearStates will get called from the VCL end Drag event
if not (ebcsVCLDrag in States) then
ClearStates;
end;
procedure TCustomEasyListview.WMMButtonDblClk(var Msg: TWMMButtonDblClk);
begin
inherited;
HandleDblClick(cmbMiddle, Msg)
end;
procedure TCustomEasyListview.WMMButtonDown(var Msg: TWMMButtonDown);
begin
Include(FStates, ebcsMButtonDown);
CheckFocus;
inherited;
HandleMouseDown(cmbMiddle, Msg);
LastMousePos := Msg.Pos
end;
procedure TCustomEasyListview.WMMButtonUp(var Msg: TWMMButtonUp);
begin
HandleMouseUp(cmbMiddle, Msg);
ClearPendingDrags;
inherited;
Mouse.Capture := 0;
ClearStates;
end;
procedure TCustomEasyListview.WMMouseActivate(var Msg: TWMMouseActivate);
// Called when the mouse is clicked in a window and the window does not have
// focus. By responding MA_ACTIVATE the window should recieve focus but this
// does not seem to happen on NT4. Necded a SetFocus when the mouse is pressed
begin
inherited;
if not EditManager.Editing then
begin
CheckFocus;
Msg.Result := MA_ACTIVATE;
end else
Msg.Result := MA_NOACTIVATE;
end;
procedure TCustomEasyListview.WMMouseMove(var Msg: TWMMouseMove);
// Called when the mouse is moved
var
KeyState: TCommonKeyStates;
GroupHitInfo: TEasyGroupHitTestInfoSet;
ItemHitInfo: TEasyItemHitTestInfoSet;
Effects: TCommonDropEffect;
Group: TEasyGroup;
HotTrackCheckObj, HotTrackObj: TEasyCollectionItem;
Item: TEasyItem;
Pt: TPoint;
Dx, Dy: Integer;
LocalGesture: WideChar;
begin
KeyState := KeyToKeyStates(Msg.Keys);
Pt := Scrollbars.MapWindowToView(Msg.Pos);
HotTrackCheckObj := nil;
if Gesture.Enabled then
begin
Dx := Msg.XPos - LastMousePos.x;
Dy := Msg.YPos - LastMousePos.y;
if ((cksLButton in KeyState) and (cmbLeft in Gesture.Button)) or
((cksRButton in KeyState) and (cmbRight in Gesture.Button)) or
((cksMButton in KeyState) and (cmbMiddle in Gesture.Button)) then
begin
LocalGesture := '*';
if (Dx > Gesture.Tolerance) and (Abs(Dy) < 2 * Gesture.Tolerance) then
LocalGesture := 'R'
else if (-Dx > Gesture.Tolerance) and (Abs(Dy) < 2 * Gesture.Tolerance) then
LocalGesture := 'L'
else if (Dy > Gesture.Tolerance) and (Abs(Dx) < 2 * Gesture.Tolerance) then
LocalGesture := 'D'
else if (-Dy > Gesture.Tolerance) and (Abs(Dx) < 2 * Gesture.Tolerance) then
LocalGesture := 'U';
if LocalGesture <> '*' then
begin
if Length(Gesture.Path) > 0 then
begin
if Gesture.Path[Length(Gesture.Path)] <> LocalGesture then
Gesture.Path := Gesture.Path + LocalGesture
end else
Gesture.Path := LocalGesture
end
end
end;
if IsHeaderMouseMsg(Msg.Pos) then
begin
HotTrack.PendingObject[Point(0, 0)] := nil;
Header.WMMouseMove(Msg)
end else
begin
if not Assigned(HotTrack.PendingObject[Point(0,0)]) then
Cursor := crDefault;
// First see if there is any kind of drag operation pending or occuring
if DragInitiated then
begin
// First check for special cases, such as when the drag selection rectangle
// is active or an item is being dragged in a D&D operation. If not see if
// this is the first move after a mouse press and one of the above cases is
// pending. If we then detect a drag start then setup the flags and initialize
// the action with the appropiate mananger.
if ebcsDragSelecting in States then
DragRect.Drag(Canvas, SmallPointToPoint(Msg.Pos), KeyState, Effects)
else
if ebcsDragging in States then
// his only works for VCL drag and drop. The System takes the mouse for OLE
DragManager.Drag(Canvas, SmallPointToPoint(Msg.Pos), KeyState, Effects)
else
// We are not drag selecting; check if we have a drag pending
if [ebcsDragSelectPending, ebcsDragPending] * States <> [] then
begin
if DragDetectPlus(Handle, SmallPointToPoint(Msg.Pos)) then
begin
// The decision to if the mouse was a drag or a select was made when the
// mouse was pressed, based on the area of the control the click occured
if ebcsDragSelectPending in States then
begin
// We are now drag selecting so update the states
Include(FStates, ebcsDragSelecting);
Exclude(FStates, ebcsDragSelectPending);
if KeyState * [cksShift, cksControl] = [] then
Include(FStates, ebcsDragSelecting);
Exclude(FStates, ebcsDragSelectPending);
if KeyState * [cksShift, cksControl] = [] then
Selection.ClearAll;
EditManager.StopAutoEditTimer;
DragRect.BeginDrag(SmallPointToPoint(Msg.Pos), KeyState);
// Since for a selection rect we have the mouse captured we can just
// call DragEnter once here and be done with it
DragRect.DragEnter(nil, Canvas, ScreenToClient(Mouse.CursorPos), KeyState, Effects);
end else
if ebcsDragPending in States then
begin
Item := Groups.ItembyPoint(Scrollbars.MapWindowToView(SmallPointToPoint(Msg.Pos)));
if Assigned(Item) then
begin
// Since we don't select until a MouseUp on Ctl-Click we must do it here just in case
if cksControl in KeyState then
begin
Item.Selected := True;
Item.Focused := True;
end;
Include(FStates, ebcsDragging);
if edtVCL = DragManager.DragType then
Include(FStates, ebcsVCLDrag);
Exclude(FStates, ebcsDragPending);
EditManager.StopAutoEditTimer;
try
DragManager.BeginDrag(SmallPointToPoint(Msg.Pos), KeyState);
finally
// If was an OLE drag then the subsystem has taken the mouse and we
// will never get a mouse up so fake it, the VCL system fakes it on
// its own but if the drag/drop is not enabled then it never will so
// fake it for all cases
if not(ebcsVCLDrag in States) then
begin
if ebcsLButtonDown in States then
Perform(WM_LBUTTONUP, TMessage(Msg).wParam, TMessage(Msg).LParam)
else
if ebcsRButtonDown in States then
begin
// Don't want to show the context menu after a drag drop with
// the right button
Include(FStates, ebcsCancelContextMenu);
Perform(WM_RBUTTONUP, TMessage(Msg).wParam, TMessage(Msg).LParam)
end else
if ebcsMButtonDown in States then
Perform(WM_MBUTTONUP, TMessage(Msg).wParam, TMessage(Msg).LParam)
end
end
end else
begin
Selection.ClearAll;
// Switch from a DragDrop Pending to a DragSelect Pending
Exclude(FStates, ebcsDragPending);
if DragRect.Enabled then
Include(FStates, ebcsDragSelectPending);
end
end
end
end
end else // Not DragInitiated
begin
HotTrackObj := nil;
Group := Groups.GroupByPoint(Pt);
if Assigned(Group) then
begin
if Group.HitTestAt(Pt, GroupHitInfo) then
// See if it is in a Group Check box first
if egtOnCheckbox in GroupHitInfo then
HotTrackCheckObj := Group
else begin
if (htgAnyWhere in HotTrack.GroupTrack) or
((htgIcon in HotTrack.GroupTrack) and (egtOnIcon in GroupHitInfo)) or
((htgText in HotTrack.GroupTrack) and (egtOnText in GroupHitInfo)) or
((htgTopMargin in HotTrack.GroupTrack) and (egtOnHeader in GroupHitInfo)) or
((htgBottomMargin in HotTrack.GroupTrack) and (egtOnFooter in GroupHitInfo)) or
((htgLeftMargin in HotTrack.GroupTrack) and (egtOnLeftMargin in GroupHitInfo)) or
((htgRightMargin in HotTrack.GroupTrack) and (egtOnRightMargin in GroupHitInfo)) then
HotTrackObj := Group;
end
end;
// Next See if it is in an Item Check box
if not (Assigned(HotTrackCheckObj) or Assigned(HotTrackObj)) then
begin
Item := Groups.ItembyPoint(Pt);
if Assigned(Item) then
begin
if Item.HitTestAt(Pt, ItemHitInfo) then
begin
if ehtOnCheck in ItemHitInfo then
HotTrackCheckObj := Item
else begin
if (htiAnyWhere in HotTrack.ItemTrack) or
((htiIcon in HotTrack.ItemTrack) and (ehtOnIcon in ItemHitInfo)) or
((htiText in HotTrack.ItemTrack) and (ehtOnText in ItemHitInfo)) then
HotTrackObj := Item
end
end
end
end;
if (ebcsCheckboxClickPending in States) then
begin
if Assigned(HotTrackCheckObj) then
begin
if CheckManager.PendingObject <> HotTrackCheckObj then
begin
CheckManager.PendingObject.CheckHovering := True;
HotTrackCheckObj := nil
end else
CheckManager.PendingObject.CheckHovering := False;
end else
begin
CheckManager.PendingObject.CheckHovering := True;
end;
if HotTrackCheckObj <> nil then
HotTrackCheckObj := nil;
end;
if not Assigned(CheckManager.PendingObject) and (Self.Focused or not HotTrack.OnlyFocused) and
PtInRect(ClientRect, SmallPointToPoint(Msg.Pos)) and (Assigned(HotTrackObj) and (HotTrackObj.Enabled)) then
HotTrack.PendingObject[SmallPointToPoint(Msg.Pos)] := HotTrackObj
else
HotTrack.PendingObject[SmallPointToPoint(Msg.Pos)] := nil;
HotTrack.PendingObjectCheck := HotTrackCheckObj;
// We are not drag selecting and do not have a drag pending so it is a normal
// mouse move
inherited;
end
end;
LastMousePos := Msg.Pos;
end;
procedure TCustomEasyListview.WMNCCalcSize(var Msg: TWMNCCalcSize);
{$IFDEF USETHEMES}
var
R: TRect;
{$ENDIF USETHEMES}
begin
if DrawWithThemes then
begin
DefaultHandler(Msg);
{$IFDEF USETHEMES}
if succeeded(GetThemeBackgroundContentRect(Themes.ListviewTheme, Canvas.Handle, LVP_EMPTYTEXT, LIS_NORMAL, Msg.CalcSize_Params^.rgrc[0], @R)) then
begin
InflateRect(R, -1-BorderWidth, -1-BorderWidth);
Msg.CalcSize_Params^.rgrc[0] := R;
end
{$ENDIF USETHEMES}
end else
begin
inherited;
end
end;
procedure TCustomEasyListview.WMNCPaint(var Msg: TWMNCPaint);
// The VCL screws this up and draws over the scrollbars making them flicker and
// be covered up by backgound painting when dragging the the window from off the
// screen
const
InnerStyles: array[TBevelCut] of Integer = (0, BDR_SUNKENINNER, BDR_RAISEDINNER, 0);
OuterStyles: array[TBevelCut] of Integer = (0, BDR_SUNKENOUTER, BDR_RAISEDOUTER, 0);
EdgeStyles: array[TBevelKind] of Integer = (0, 0, BF_SOFT, BF_FLAT);
Ctl3DStyles: array[Boolean] of Integer = (BF_MONO, 0);
var
ClientR, WindowR, WindowROrig, Filler: TRect;
DC: HDC;
Style, StyleEx: Longword;
Pt: TPoint;
{$IFDEF USETHEMES}
R: TRect;
{$ENDIF USETHEMES}
begin
// Let Windows paint the scrollbars first
DefaultHandler(Msg);
// Always paint the NC area as refreshing it can be tricky and it sometimes
// is not redrawn on startup
// if UpdateCount = 0 then
begin
DC := GetWindowDC(Handle);
try
NCCanvas.Handle := DC;
if (BevelKind <> bkNone) or (BorderWidth > 0){ or DrawWithThemes} then
begin
Windows.GetClientRect(Handle, ClientR);
Windows.GetWindowRect(Handle, WindowR);
Pt := WindowR.TopLeft;
Windows.ScreenToClient(Handle, Pt);
// Map the screen coordinates of the WindowRect to a 0,0 offset
OffsetRect(WindowR, -WindowR.Left, -WindowR.Top);
// Make a copy
WindowROrig := WindowR;
// Map the ClientRect to Window coordinates
OffsetRect(ClientR, -Pt.X, -Pt.Y);
Style := GetWindowLong(Handle, GWL_STYLE);
if (Style and WS_VSCROLL) <> 0 then
begin
StyleEx := GetWindowLong(Handle, GWL_EXSTYLE);
if (StyleEx and WS_EX_LEFTSCROLLBAR) <> 0 then
Dec(ClientR.Left, GetSystemMetrics(SM_CYVSCROLL))
else
Inc(ClientR.Right, GetSystemMetrics(SM_CYVSCROLL))
end;
if (Style and WS_HSCROLL) <> 0 then
Inc(ClientR.Bottom, GetSystemMetrics(SM_CYHSCROLL));
// Paint the little square in the corner made by the scroll bars
if ((Style and WS_VSCROLL) <> 0) and ((Style and WS_HSCROLL) <> 0) then
begin
Filler := ClientR;
Filler.Left := Filler.Right - GetSystemMetrics(SM_CYVSCROLL);
Filler.Top := Filler.Bottom - GetSystemMetrics(SM_CYHSCROLL);
NCCanvas.Brush.Color := clBtnFace;
NCCanvas.FillRect(Filler);
end;
// if not DrawWithThemes then
// Punch out the client area and the scroll bar area
ExcludeClipRect(DC, ClientR.Left, ClientR.Top, ClientR.Right, ClientR.Bottom);
if DrawWithThemes then
begin
{$IFDEF USETHEMES}
if not ShowThemedBorder then
begin
R := Rect(0, 0, 0, 0);
GetThemeBackgroundExtent(Themes.ListviewTheme, NCCanvas.Handle, LVP_EMPTYTEXT, LIS_NORMAL, ClientRect, R);
InflateRect(WindowROrig, R.Left - ClientRect.Left, R.Top - ClientRect.Top);
end;
DrawThemeBackground(Themes.ListviewTheme, NCCanvas.Handle, LVP_EMPTYTEXT, LIS_NORMAL, WindowROrig, nil);
{$ENDIF USETHEMES}
end else
begin
Windows.FillRect(DC, WindowR, Brush.Handle);
DrawEdge(DC, WindowROrig, InnerStyles[BevelInner] or OuterStyles[BevelOuter],
Byte(BevelEdges) or EdgeStyles[BevelKind] or Ctl3DStyles[Ctl3D] or BF_ADJUST);
end
end else
begin
Windows.GetWindowRect(Handle, WindowR);
end;
finally
NCCanvas.Handle := 0;
ReleaseDC(Handle, DC);
end
end
end;
procedure TCustomEasyListview.WMPaint(var Msg: TWMPaint);
// The VCL does a poor job at optimizing the paint messages. It does not look
// to see what rectangle the system actually needs painted. Sometimes it only
// needs a small slice of the window painted, why paint it all? This implementation
// also handles DoubleBuffering better
var
PaintInfo: TPaintStruct;
ClientR: TRect;
begin
BeginPaint(Handle, PaintInfo);
try
if (UpdateCount = 0) or ForcePaint then
begin
try
if not CacheDoubleBufferBits then
begin
BackBits := TBitmap.Create;
BackBits.PixelFormat := pf32Bit;
Windows.GetClientRect(Handle, ClientR);
if ClientWidth > 0 then
BackBits.Width := ClientWidth
else
BackBits.Width := 1;
if ClientHeight > 0 then
BackBits.Height := ClientHeight
else
BackBits.Height := 1;
end;
BackBits.Canvas.Lock;
try
if not IsRectEmpty(PaintInfo.rcPaint) and (ClientWidth > 0) and (ClientHeight > 0) then
begin
// Assign attributes to the Canvas used
BackBits.Canvas.Font.Assign(Font);
BackBits.Canvas.Brush.Color := Color;
BackBits.Canvas.Brush.Assign(Brush);
SetWindowOrgEx(BackBits.Canvas.Handle, 0, 0, nil);
SetViewportOrgEx(BackBits.Canvas.Handle, 0, 0, nil);
FillRect(BackBits.Canvas.Handle, PaintInfo.rcPaint, Brush.Handle);
SelectClipRgn(BackBits.Canvas.Handle, 0); // Remove the clipping region we created
// Paint the rectangle that is needed
DoPaintRect(BackBits.Canvas, PaintInfo.rcPaint, False);
// Remove any clipping regions applied by the views.
SelectClipRgn(BackBits.Canvas.Handle, 0);
// Redraw the drag selecting rectangle
if (ebcsDragSelecting in States) then
DragRect.PaintSelectionRect(BackBits.Canvas);
DoAfterPaint(BackBits.Canvas, PaintInfo.rcPaint);
// Blast the bits to the screen
BitBlt(PaintInfo.hdc, PaintInfo.rcPaint.Left, PaintInfo.rcPaint.Top,
PaintInfo.rcPaint.Right - PaintInfo.rcPaint.Left,
PaintInfo.rcPaint.Bottom - PaintInfo.rcPaint.Top,
BackBits.Canvas.Handle, PaintInfo.rcPaint.Left, PaintInfo.rcPaint.Top, SRCCOPY);
end
finally
BackBits.Canvas.Unlock;
end;
finally
if not CacheDoubleBufferBits then
FreeAndNil(FBackBits)
end;
end
finally
EndPaint(Handle, PaintInfo);
end
end;
procedure TCustomEasyListview.WMRButtonDblClk(var Msg: TWMRButtonDblClk);
begin
inherited;
HandleDblClick(cmbRight, Msg)
end;
procedure TCustomEasyListview.WMRButtonDown(var Msg: TWMRButtonDown);
begin
Include(FStates, ebcsRButtonDown);
CheckFocus;
if IsHeaderMouseMsg(Msg.Pos) then
begin
// Should this call a Column manager or a Column?
if Assigned(Header) then
begin
Header.WMRButtonDown(Msg);
Header.ReleaseMouse;
end
end else
begin
inherited;
HandleMouseDown(cmbRight, Msg)
end;
LastMousePos := Msg.Pos
end;
procedure TCustomEasyListview.WMRButtonUp(var Msg: TWMRButtonUp);
begin
if IsHeaderMouseMsg(Msg.Pos) then
begin
// Should this call a Column manager or a Column?
if Assigned(Header) then
begin
inherited;
// ContextMenu handled it
if Msg.Result = 0 then
Header.WMRButtonUp(Msg);
// Need to allow HotTracking to finish up.
if Assigned(Header.HotTrackedColumn) then
Header.WMMouseMove(Msg);
Header.ReleaseMouse;
end
end else
begin
if [ebcsDragSelecting, ebcsDragging, ebcsVCLDrag] * States <> [] then
Include(FStates, ebcsCancelContextMenu);
if Msg.Result = 0 then
HandleMouseUp(cmbRight, Msg);
ClearPendingDrags;
inherited; // Handles the context menu
Mouse.Capture := 0;
end;
ClearStates;
end;
procedure TCustomEasyListview.WMSetCursor(var Msg: TWMSetCursor);
begin
inherited;
end;
procedure TCustomEasyListview.WMSetFocus(var Msg: TWMSetFocus);
begin
inherited;
SafeInvalidateRect(nil, True);
//Selection.Invalidate(False)VisibleSelected(False);
end;
procedure TCustomEasyListview.WMSize(var Msg: TWMSize);
begin
{$IFDEF GXDEBUG}
SendDebug('TCustomEasyListview.WMSize');
{$ENDIF GXDEBUG}
Header.WMSize(Msg); // do it first
inherited;
end;
procedure TCustomEasyListview.WMTabMoveFocus(var Msg: TMessage);
var
NextItem: TEasyItem;
JumpToNextItem: Boolean;
NextColumn: TEasyColumn;
begin
JumpToNextItem := True;
NextItem := EditManager.TabMoveFocusItem;
if EditManager.TabEditColumns then
begin
NextColumn := EditManager.TabMoveFocusColumn;
if Assigned(NextColumn) then
begin
EditManager.TabMoveFocusItem := nil;
JumpToNextItem := False;
NextColumn.MakeVisible(emvTop);
EditManager.BeginEdit(NextItem, NextColumn);
end
end;
if JumpToNextItem then
begin
EditManager.TabMoveFocusItem := nil;
if Assigned(NextItem) then
begin
NextItem.Focused := True;
NextItem.MakeVisible(emvAuto);
EditManager.BeginEdit(NextItem, nil)
end;
end
end;
procedure TCustomEasyListview.WMVScroll(var Msg: TWMVScroll);
// Called to scroll the Window, the Window is responsible for actually performing
// the scroll
begin
inherited;
if Msg.ScrollCode <> SB_ENDSCROLL then
Include(FStates, ebcsScrolling)
else
Exclude(FStates, ebcsScrolling);
ScrollBars.WMVScroll(Msg);
SafeInvalidateRect(nil, False);
end;
procedure TCustomEasyListview.WMWindowPosChanged(var Msg: TWMWindowPosChanged);
// Called after the window has changed size
var
YChanged, XChanged: Boolean;
begin
{$IFDEF GXDEBUG}
SendDebug('TCustomEasyListview.WMWindowPosChanged');
{$ENDIF GXDEBUG}
YChanged := False;
XChanged := False;
// Only use cx and cy if NOSIZE is not used
if Msg.WindowPos^.flags and SWP_NOSIZE = 0 then
begin
YChanged := Height <> Msg.WindowPos.cy;
XChanged := Width <> Msg.WindowPos.cx;
end;
inherited;
if YChanged or XChanged then
begin
try
Groups.Rebuild(True);
ScrollBars.ReCalculateScrollbars(True, False);
finally
ResizeBackBits(Msg.WindowPos.cx, Msg.WindowPos.cy);
end;
end
end;
procedure TCustomEasyListview.WMWindowPosChanging(var Msg: TWMWindowPosChanging);
// Called when the window is changing size
var
YChanged, XChanged: Boolean;
begin
{$IFDEF GXDEBUG}
SendDebug('TCustomEasyListview.WMWindowPosChanging');
{$ENDIF GXDEBUG}
YChanged := False;
XChanged := False;
// Only use cx and cy if NOSIZE is not used
if Msg.WindowPos^.flags and SWP_NOSIZE = 0 then
begin
YChanged := Height <> Msg.WindowPos.cy;
XChanged := Width <> Msg.WindowPos.cx;
end;
// Track the offset of the background image if desired before the control size is updated
BackGround.WMWindowPosChanging(Msg);
inherited;
if YChanged or XChanged then
DoResize(Msg.WindowPos.cx - Width, Msg.WindowPos.cy - Height)
end;
{ TEasyItem }
constructor TEasyCollectionItem.Create(ACollection: TEasyCollection);
begin
inherited Create();
Collection := ACollection;
Include(FState, esosVisible);
Include(FState, esosEnabled);
FVisibleIndex := -1;
end;
destructor TEasyCollectionItem.Destroy;
begin
SetDestroyFlags;
DataInf := nil;
if Assigned(OwnerListview) then
begin
if OwnerListview.HotTrack.PendingObjectCheck = Self then
OwnerListview.HotTrack.PendingObjectCheck := nil;
if OwnerListview.HotTrack.FPendingObject = Self then
OwnerListview.HotTrack.FPendingObject := nil;
end;
Freeing;
inherited;
if OwnsPaintInfo then
FreeAndNil(FPaintInfo);
end;
function TEasyCollectionItem.AllowDrag(ViewportPt: TPoint): Boolean;
begin
Result := True
end;
function TEasyCollectionItem.DefaultImageList(ImageSize: TEasyImageSize): TCustomImageList;
begin
Result := nil;
case ImageSize of
eisSmall: Result := OwnerListview.ImagesSmall;
eisLarge: Result := OwnerListview.ImagesLarge;
eisExtraLarge: Result := OwnerListview.ImagesExLarge;
end
end;
function TEasyCollectionItem.GetAlignment: TAlignment;
begin
Result := PaintInfo.Alignment
end;
function TEasyCollectionItem.GetBold: Boolean;
begin
Result := esosBold in State
end;
function TEasyCollectionItem.GetBorder: Integer;
begin
Result := PaintInfo.Border
end;
function TEasyCollectionItem.GetBorderColor: TColor;
begin
Result := PaintInfo.BorderColor
end;
function TEasyCollectionItem.GetCaption: WideString;
begin
Result := GetCaptions(0)
end;
function TEasyCollectionItem.GetCaptionIndent: Integer;
begin
Result := PaintInfo.CaptionIndent
end;
function TEasyCollectionItem.GetChecked: Boolean;
begin
Result := esosChecked in State
end;
function TEasyCollectionItem.GetCheckFlat: Boolean;
begin
Result := PaintInfo.CheckFlat
end;
function TEasyCollectionItem.GetCheckHovering: Boolean;
begin
Result := esosCheckHover in FState
end;
function TEasyCollectionItem.GetCheckIndent: Integer;
begin
Result := PaintInfo.CheckIndent
end;
function TEasyCollectionItem.GetCheckPending: Boolean;
begin
Result := esosCheckPending in FState
end;
function TEasyCollectionItem.GetChecksize: Integer;
begin
Result := PaintInfo.Checksize
end;
function TEasyCollectionItem.GetCheckType: TEasyCheckType;
begin
Result := PaintInfo.CheckType
end;
function TEasyCollectionItem.GetClicking: Boolean;
begin
Result := esosClicking in State
end;
function TEasyCollectionItem.GetCut: Boolean;
begin
Result := esosCut in State
end;
function TEasyCollectionItem.GetDataInf: IUnknown;
begin
Result := FDataInf;
end;
function TEasyCollectionItem.GetDestroying: Boolean;
begin
Result := esosDestroying in State
end;
function TEasyCollectionItem.GetDisplayName: WideString;
begin
if Caption <> '' then
Result := Caption
else
Result:= ClassName;
end;
function TEasyCollectionItem.GetEnabled: Boolean;
begin
Result := esosEnabled in State
end;
function TEasyCollectionItem.GetFocused: Boolean;
begin
Result := esosFocused in State
end;
function TEasyCollectionItem.GetGhosted: Boolean;
begin
Result := esosGhosted in State
end;
function TEasyCollectionItem.GetHilighted: Boolean;
begin
Result := esosHilighted in State
end;
function TEasyCollectionItem.GetHotTracking(MousePos: TPoint): Boolean;
begin
Result := esosHotTracking in State
end;
function TEasyCollectionItem.GetImageIndent: Integer;
begin
Result := PaintInfo.ImageIndent
end;
function TEasyCollectionItem.GetImageIndex: TCommonImageIndexInteger;
begin
Result := GetImageIndexes(0)
end;
function TEasyCollectionItem.GetImageOverlayIndex: TCommonImageIndexInteger;
begin
Result := GetImageOverlayIndexes(0)
end;
function TEasyCollectionItem.GetIndex: Integer;
begin
Result := Collection.FList.IndexOf(Self)
end;
function TEasyCollectionItem.GetInitialized: Boolean;
begin
Result := esosInitialized in State
end;
function TEasyCollectionItem.GetOwner: TPersistent;
begin
Result := FCollection
end;
function TEasyCollectionItem.GetOwnerListview: TCustomEasyListview;
begin
Result := TEasyCollection( Collection).FOwnerListview
end;
function TEasyCollectionItem.GetPaintInfo: TEasyPaintInfoBasic;
begin
if Assigned(FPaintInfo) then
Result := FPaintInfo
else
Result := LocalPaintInfo
end;
function TEasyCollectionItem.GetSelected: Boolean;
begin
Result := esosSelected in State
end;
function TEasyCollectionItem.GetVAlignment: TCommonVAlignment;
begin
Result := PaintInfo.VAlignment
end;
function TEasyCollectionItem.GetViewRect: TRect;
begin
Result := DisplayRect
end;
function TEasyCollectionItem.GetVisible: Boolean;
begin
Result := esosVisible in State
end;
function TEasyCollectionItem.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
Result := E_NOINTERFACE
end;
function TEasyCollectionItem._AddRef: Integer;
begin
Result := -1
end;
function TEasyCollectionItem._Release: Integer;
begin
Result := -1
end;
procedure TEasyCollectionItem.Invalidate(ImmediateUpdate: Boolean);
var
R: TRect;
begin
if OwnerListview.UpdateCount = 0 then
begin
R := OwnerListview.Scrollbars.MapViewRectToWindowRect(DisplayRect);
if IntersectRect(R, R, OwnerListview.ClientRect) then
OwnerListview.SafeInvalidateRect(@R, ImmediateUpdate);
end
end;
procedure TEasyCollectionItem.InvalidateItem(ImmediateRefresh: Boolean);
begin
Invalidate(ImmediateRefresh)
end;
procedure TEasyCollectionItem.LoadFromStream(S: TStream; var Version: Integer);
var
Temp: TEasyStorageObjectStates;
T: Longword;
begin
S.Read(T, SizeOf(T));
// See if we have an old style stream
if T <> STREAM_ID_KEY then
begin
// Old poor way
S.Seek(-SizeOf(T), soFromCurrent);
Version := 2 // Use to be Collection.StreamVersion but we can hard code 2 since that appeared in version 2 only
end else
S.Read(Version, SizeOf(Version));
S.Read(Temp, SizeOf(Temp));
// Add back in the stored persisted states
Selected := esosSelected in Temp;
Enabled := esosEnabled in Temp;
Visible := esosVisible in Temp;
Checked := esosChecked in Temp;
Bold := esosBold in Temp;
// For new objects test the stream version first
// if Version > X then
// begin
// ReadStream....
// end
end;
procedure TEasyCollectionItem.MakeVisible(Position: TEasyMakeVisiblePos);
begin
end;
procedure TEasyCollectionItem.SaveToStream(S: TStream; Version: Integer = EASYLISTVIEW_STREAM_VERSION);
var
Temp: TEasyStorageObjectStates;
Key: Integer;
begin
Key := STREAM_ID_KEY;
S.Write(Key, SizeOf(Key));
S.Write(Version, SizeOf(Version));
Temp := State;
// Only save certin states that should be persistent
Temp := State * PERSISTENTOBJECTSTATES;
S.Write(Temp, SizeOf(Temp));
// For new objects test the stream version first
// if Version then
// begin
// WriteStream....
// end
end;
procedure TEasyCollectionItem.SetAlignment(Value: TAlignment);
begin
if Value <> Alignment then
begin
PaintInfo.Alignment := Value;
Invalidate(False)
end
end;
procedure TEasyCollectionItem.SetBold(const Value: Boolean);
begin
if Value xor (esosBold in FState) then
begin
if State * [esosDestroying] <> [] then
begin
Exclude(FState, esosBold);
LosingBold
end else
begin
if CanChangeBold(Value) then
begin
if Value then
begin
Include(FState, esosBold);
GainingBold
end else
begin
Exclude(FState, esosBold);
LosingBold
end
end
end
end
end;
procedure TEasyCollectionItem.SetBorder(Value: Integer);
begin
if Value <> Border then
begin
if Value < 0 then
PaintInfo.Border := 0
else
PaintInfo.Border := Value;
Invalidate(False)
end
end;
procedure TEasyCollectionItem.SetBorderColor(Value: TColor);
begin
if Value <> BorderColor then
begin
if Value < 0 then
PaintInfo.BorderColor := 0
else
PaintInfo.BorderColor := Value;
Invalidate(False)
end
end;
procedure TEasyCollectionItem.SetCaption(Value: WideString);
begin
Captions[0] := Value
end;
procedure TEasyCollectionItem.SetCaptionIndent(Value: Integer);
begin
if Value <> CaptionIndent then
begin
if Value < 0 then
PaintInfo.CaptionIndent := 0
else
PaintInfo.CaptionIndent := Value;
Invalidate(False)
end
end;
procedure TEasyCollectionItem.SetChecked(Value: Boolean);
begin
if Value xor (esosChecked in FState) then
begin
if State * [esosDestroying] <> [] then
begin
Exclude(FState, esosChecked);
LosingCheck
end else
begin
if CanChangeCheck(Value) then
begin
if Value then
begin
Include(FState, esosChecked);
GainingCheck
end else
begin
Exclude(FState, esosChecked);
LosingCheck
end
end
end
end
end;
procedure TEasyCollectionItem.SetCheckFlat(Value: Boolean);
begin
if Value <> CheckFlat then
begin
PaintInfo.CheckFlat := Value;
Invalidate(False)
end
end;
procedure TEasyCollectionItem.SetCheckHovering(Value: Boolean);
begin
if Value xor (esosCheckHover in FState) then
begin
if Value then
Include(FState,esosCheckHover)
else
Exclude(FState, esosCheckHover);
Invalidate(False)
end
end;
procedure TEasyCollectionItem.SetCheckIndent(Value: Integer);
begin
if Value <> CheckIndent then
begin
if Value < 1 then
PaintInfo.CheckIndent := 0
else
PaintInfo.CheckIndent := Value;
Invalidate(False)
end;
end;
procedure TEasyCollectionItem.SetCheckPending(Value: Boolean);
begin
if Value xor (esosCheckPending in FState) then
begin
if Value then
Include(FState,esosCheckPending)
else
Exclude(FState, esosCheckPending);
Invalidate(False)
end
end;
procedure TEasyCollectionItem.SetChecksize(Value: Integer);
begin
if Value <> Checksize then
begin
if Value < 0 then
PaintInfo.Checksize := 0
else
PaintInfo.Checksize := Value;
Invalidate(False)
end
end;
procedure TEasyCollectionItem.SetCheckType(Value: TEasyCheckType);
begin
if Value <> CheckType then
begin
PaintInfo.CheckType := Value;
Invalidate(False)
end
end;
procedure TEasyCollectionItem.SetClicking(Value: Boolean);
begin
if Value then
Include(FState, esosClicking)
else
Exclude(FState, esosClicking)
end;
procedure TEasyCollectionItem.SetCut(Value: Boolean);
begin
if Value xor (esosCut in State) then
begin
if Value then
Include(FState, esosCut)
else
Exclude(FState, esosCut);
Invalidate(False)
end
end;
procedure TEasyCollectionItem.SetData(Value: TObject);
begin
FData := Value
end;
procedure TEasyCollectionItem.SetDataInf(const Value: IUnknown);
var
Notifier: IEasyNotifier;
begin
if Value <> FDataInf then
begin
if Supports(DataInf, IEasyNotifier, Notifier) then
Notifier.OnUnRegisterNotify(Self);
FDataInf := Value;
if Supports(DataInf, IEasyNotifier, Notifier) then
Notifier.OnRegisterNotify(Self)
end
end;
procedure TEasyCollectionItem.SetDestroyFlags;
begin
Include(FState, esosDestroying);
end;
procedure TEasyCollectionItem.SetEnabled(Value: Boolean);
begin
if Value xor (esosEnabled in FState) then
begin
if State * [esosDestroying] <> [] then
begin
// Disabled items can't have the focus or selection
Focused := False;
Selected := False;
Exclude(FState, esosEnabled);
LosingEnable
end else
begin
if CanChangeEnable(Value) then
begin
if Value then
begin
Include(FState, esosEnabled);
GainingEnable
end else
begin
// Disabled items can't have the focus or selection
Focused := False;
Selected := False;
Exclude(FState, esosEnabled);
LosingEnable
end
end
end
end
end;
procedure TEasyCollectionItem.SetFocused(Value: Boolean);
begin
if Visible and Enabled then
begin
if Value xor (esosFocused in State) then
begin
if State * [esosDestroying] <> [] then
begin
Exclude(FState, esosFocused);
LosingFocus
end else
begin
if CanChangeFocus(Value) then
begin
if Value then
begin
Include(FState, esosFocused);
GainingFocus
end else
begin
Exclude(FState, esosFocused);
LosingFocus
end
end
end
end
end
end;
procedure TEasyCollectionItem.SetGhosted(const Value: Boolean);
begin
if Value xor (esosGhosted in FState) then
begin
if State * [esosDestroying] <> [] then
begin
Exclude(FState, esosGhosted);
LosingGhosted
end else
begin
if Value then
begin
Include(FState, esosGhosted);
GainingGhosted
end else
begin
Exclude(FState, esosGhosted);
LosingGhosted
end
end
end
end;
procedure TEasyCollectionItem.SetHilighted(Value: Boolean);
begin
if Value xor (esosHilighted in FState) then
begin
if State * [esosDestroying] <> [] then
begin
// Disabled items can't have the focus or selection
Focused := False;
Selected := False;
Exclude(FState, esosHilighted);
LosingHilight
end else
begin
if Value then
begin
Include(FState, esosHilighted);
GainingHilight
end else
begin
Exclude(FState, esosHilighted);
LosingHilight
end
end
end
end;
procedure TEasyCollectionItem.SetHotTracking(MousePos: TPoint; Value: Boolean);
begin
if Value xor (esosHotTracking in FState) then
begin
if State * [esosDestroying] <> [] then
begin
Exclude(FState, esosHotTracking);
LosingHotTracking
end else
begin
if CanChangeHotTracking(Value) then
begin
if Value then
begin
Include(FState, esosHotTracking);
GainingHotTracking(MousePos)
end else
begin
Exclude(FState, esosHotTracking);
LosingHotTracking
end
end
end
end
end;
procedure TEasyCollectionItem.SetImageIndent(Value: Integer);
begin
if Value <> ImageIndent then
begin
if Value < 0 then
PaintInfo.ImageIndent := 0
else
PaintInfo.ImageIndent := Value;
Invalidate(False)
end
end;
procedure TEasyCollectionItem.SetImageIndex(const Value: TCommonImageIndexInteger);
begin
ImageIndexes[0] := Value
end;
procedure TEasyCollectionItem.SetImageOverlayIndex(const Value: TCommonImageIndexInteger);
begin
ImageOverlayIndexes[0] := Value
end;
procedure TEasyCollectionItem.SetInitialized(Value: Boolean);
begin
if Value xor (esosInitialized in State) then
begin
if Value then
begin
Include(FState, esosInitialized);
Initialize;
end else
Exclude(FState, esosInitialized)
end
end;
procedure TEasyCollectionItem.SetPaintInfo(Value: TEasyPaintInfoBasic);
begin
FPaintInfo := Value
end;
procedure TEasyCollectionItem.SetSelected(Value: Boolean);
begin
if Visible and Enabled then
begin
if Value xor (esosSelected in State) then
begin
if State * [esosDestroying] <> [] then
begin
Exclude(FState, esosSelected);
LosingSelection
end else
begin
if CanChangeSelection(Value) then
begin
if Value then
begin
Include(FState, esosSelected);
GainingSelection
end else
begin
Exclude(FState, esosSelected);
LosingSelection
end
end
end
end
end
end;
procedure TEasyCollectionItem.SetVAlignment(Value: TCommonVAlignment);
begin
if Value <> VAlignment then
begin
PaintInfo.VAlignment := Value;
Invalidate(False)
end
end;
procedure TEasyCollectionItem.SetVisible(Value: Boolean);
begin
if Value xor (esosVisible in State) then
begin
if State * [esosDestroying] <> [] then
begin
// Invisible Objects can't be focused or selected
Focused := False;
Selected := False;
if not OwnerListview.AllowHiddenCheckedItems then
Checked := False;
Exclude(FState, esosVisible);
LosingVisibility;
end else
begin
if CanChangeVisibility(Value) then
begin
if Value then
begin
Include(FState, esosVisible);
GainingVisibility
end else
begin
// Invisible Objects can't be focused or selected or Focused
Focused := False;
Selected := False;
if not OwnerListview.AllowHiddenCheckedItems then
Checked := False;
Exclude(FState, esosVisible);
LosingVisibility;
end
end
end
end
end;
procedure TEasyCollectionItem.UnRegister;
begin
FDataInf := nil
end;
{ TEasyCollection }
constructor TEasyCollection.Create(AnOwner: TCustomEasyListview);
begin
inherited Create(AnOwner);
FItemClass := TEasyCollectionItem;
FList := TList.Create;
VisibleList := TList.Create;
end;
destructor TEasyCollection.Destroy;
begin
Clear;
inherited;
FreeAndNil(FVisibleList);
FreeAndNil(FList);
end;
function TEasyCollection.Add(Data: TObject = nil): TEasyCollectionItem;
begin
Result := ItemClass.Create(Self);
if Assigned(Result) then
begin
FList.Add(Result);
ReIndexItems;
DoItemAdd(Result, FList.Count - 1);
Result.Data := Data;
DoStructureChange
end
end;
function TEasyCollection.DoStore: Boolean;
begin
Result := (FList.Count > 0) and not HideFromDFM
end;
function TEasyCollection.FirstVisible: TEasyColumn;
begin
if VisibleList.Count > 0 then
Result := TEasyColumn( VisibleList[0])
else
Result := nil
end;
function TEasyCollection.GetCount: Integer;
begin
Result := FList.Count
end;
function TEasyCollection.GetItem(Index: Integer): TEasyCollectionItem;
begin
Result := TEasyCollectionItem(FList.List[Index])
end;
function TEasyCollection.GetOwner: TPersistent;
begin
Result:= FOwnerListview
end;
function TEasyCollection.GetOwnerListview: TCustomEasyListview;
begin
Result := FOwnerListview
end;
function TEasyCollection.GetReIndexDisable: Boolean;
begin
Result := FReIndexCount > 0
end;
function TEasyCollection.GetVisibleCount: Integer;
begin
Result := FVisibleList.Count
end;
function TEasyCollection.Insert(Index: Integer; Data: TObject = nil): TEasyCollectionItem;
begin
Result := ItemClass.Create(Self);
if Assigned(Result) then
begin
FList.Insert(Index, Result);
ReIndexItems;
DoItemAdd(Result, Index);
Result.Data := Data;
DoStructureChange
end
end;
function TEasyCollection.LastVisible: TEasyColumn;
begin
if VisibleList.Count > 0 then
Result := TEasyColumn( VisibleList[VisibleList.Count - 1])
else
Result := nil
end;
function TEasyCollection.NextVisible(Column: TEasyColumn): TEasyColumn;
var
i: Integer;
begin
Result := nil;
if Assigned(Column) then
begin
i := Column.Index + 1;
while not Assigned(Result) and (i < Count) do
begin
if Items[i].Visible then
Result := TEasyColumn( Items[i]);
Inc(i)
end
end
end;
function TEasyCollection.PrevVisible(Column: TEasyColumn): TEasyColumn;
var
i: Integer;
begin
Result := nil;
if Assigned(Column) then
begin
i := Column.Index - 1;
while not Assigned(Result) and (i < Count) do
begin
if Items[i].Visible then
Result := TEasyColumn( Items[i]);
Dec(i)
end
end
end;
procedure TEasyCollection.Clear(FreeItems: Boolean = True);
var
i: Integer;
begin
if FList.Count > 0 then
begin
BeginUpdate(False);
try
// Need to make sure all items are valid so nothing unexpected happens in the
// controls events when the item state changes
for i := 0 to FList.Count - 1 do
begin
TEasyCollectionItem(FList[i]).SetDestroyFlags;
TEasyCollectionItem(FList[i]).Focused := False;
TEasyCollectionItem(FList[i]).Selected := False;
end;
if FreeItems then
for i := FList.Count - 1 downto 0 do // Walk backwords
TEasyCollectionItem(FList[i]).Free;
finally
FList.Clear;
FVisibleList.Clear;
// The scrollbars do not update correctly on nested BeginUpdate/EndUpdate
if Assigned(OwnerListview) and OwnerListview.HandleAllocated then
begin
OwnerListview.Scrollbars.OffsetX := 0;
OwnerListview.Scrollbars.OffsetY := 0;
end;
EndUpdate;
end;
end;
end;
procedure TEasyCollection.DefineProperties(Filer: TFiler);
begin
inherited DefineProperties(Filer);
Filer.DefineBinaryProperty('Items', ReadItems, WriteItems, DoStore);
end;
procedure TEasyCollection.Delete(Index: Integer);
var
Item: TEasyCollectionItem;
begin
Item := FList[Index];
Item.SetDestroyFlags;
Item.Focused := False;
Item.Selected := False;
FList.Delete(Index);
Item.Free;
ReIndexItems;
DoStructureChange
end;
procedure TEasyCollection.DoItemAdd(Item: TEasyCollectionItem; Index: Integer);
begin
end;
procedure TEasyCollection.DoStructureChange;
begin
end;
procedure TEasyCollection.EndUpdate(Invalidate: Boolean = True);
begin
inherited;
OwnerListview.EndUpdate(Invalidate);
end;
procedure TEasyCollection.BeginUpdate(ReIndex: Boolean);
begin
inherited;
OwnerListview.BeginUpdate;
end;
procedure TEasyCollection.Exchange(Index1, Index2: Integer);
var
Temp: TEasyCollectionItem;
begin
Temp := TEasyCollectionItem( FList[Index1]);
FList[Index1] := FList[Index2];
FList[Index2] := Temp;
ReIndexItems;
DoStructureChange
end;
procedure TEasyCollection.MakeAllVisible;
var
i: Integer;
begin
for i := 0 to Count - 1 do
Items[i].Visible := True
end;
procedure TEasyCollection.ReadItems(Stream: TStream);
var
i, ItemCount: Integer;
StreamVersion: Integer;
Cls: TClass;
begin
Clear;
StreamVersion := StreamHelper.ReadInteger(Stream);
ItemCount := StreamHelper.ReadInteger(Stream);
if StreamVersion > 4 then
begin
// Since ELV can store more than one class type of Collection Items the streaming
// must be more sophisticated (i.e. it can have virtual, custom, and stored items
// all in the listview at the same time) It must check the class type of every
// object to make sure it creates the correct item type
for i := 0 to ItemCount - 1 do
begin
Cls := GetClass(StreamHelper.ReadString(Stream));
Assert(Cls <> nil, 'If using custom item types for Item, Groups or Columns you must register them with the streaming system with RegisterClass(TMyEasyClassItemType)');
if Assigned(Cls) then
begin
FItemClass := TEasyCollectionItemClass( Cls);
Add.LoadFromStream(Stream, StreamVersion);
end
end
end else
begin
// Stream will fill version in on first read
for i := 0 to ItemCount - 1 do
Add.LoadFromStream(Stream, StreamVersion);
end
end;
procedure TEasyCollection.ReIndexItems;
var
i: Integer;
begin
if not OwnerListview.Groups.ReIndexDisable then
begin
for i := 0 to List.Count - 1 do
TEasyCollectionItem( List[i]).FIndex := i
end
end;
procedure TEasyCollection.SetItem(Index: Integer; Value: TEasyCollectionItem);
begin
FList[Index] := Value
end;
procedure TEasyCollection.SetReIndexDisable(const Value: Boolean);
begin
if Value then
begin
Inc(FReIndexCount)
end else
begin
Dec(FReIndexCount);
if ReIndexCount <=0 then
begin
ReIndexCount := 0;
ReIndexItems
end
end
end;
procedure TEasyCollection.WriteItems(Stream: TStream);
var
i: Integer;
begin
// Write the Current Stream Version to the stream
StreamHelper.WriteInteger(Stream, EASYLISTVIEW_STREAM_VERSION);
// Store the number of items we are storing
StreamHelper.WriteInteger(Stream, FList.Count);
for i := 0 to FList.Count - 1 do
begin
StreamHelper.WriteString(Stream, TEasyCollectionItem( Items[i]).ClassName);
TEasyCollectionItem( Items[i]).SaveToStream(Stream); // Write custom data to the stream
end
end;
{ TEasyHeader }
constructor TEasyHeader.Create(AnOwner: TCustomEasyListview);
begin
inherited;
FColumns := TEasyColumns.Create(AnOwner);
FPositions := TColumnPos.Create;
FDragManager := TEasyHeaderDragManager.Create(AnOwner);
DragManager.Header := Self;
FFont := TFont.Create;
FHeight := 21;
FColor := clBtnFace;
FSizeable := True;
Draggable := True;
LastWidth := -1;
FStreamColumns := True;
FAutoSizeHeight := True;
FAutoSizeHeightMargin := 8;
end;
destructor TEasyHeader.Destroy;
begin
Columns.Clear;
FreeAndNil(FCanvasStore);
inherited;
FreeAndNil(FColumns);
FreeAndNil(FPositions);
FreeAndNil(FFont);
FreeAndNil(FDragManager);
end;
function TEasyHeader.FirstColumn: TEasyColumn;
begin
if Columns.Count > 0 then
Result := Columns[0]
else
Result := nil
end;
function TEasyHeader.FirstColumnByPosition: TEasyColumn;
begin
if Positions.Count > 0 then
Result := Positions[0]
else
Result := nil
end;
function TEasyHeader.FirstColumnInRect(ViewportRect: TRect): TEasyColumn;
//
// Always assumes by Position as this is a UI function
//
var
i: Integer;
ScratchR: TRect;
begin
Result := nil;
i := 0;
OffsetRect(ViewportRect, 0, -ViewportRect.Top);
while (i < Positions.Count) and not Assigned(Result) do
begin
if Positions[i].Visible then
if IntersectRect(ScratchR, Positions[i].DisplayRect, ViewportRect) then
Result := Positions[i];
Inc(i)
end
end;
function TEasyHeader.FirstVisibleColumn: TEasyColumn;
var
i: Integer;
Column: TEasyColumn;
begin
Result := nil;
Column := FirstColumn;
i := 0;
while not Assigned(Result) and (i < Columns.Count) do
begin
if Assigned(Column) then
begin
if Column.Visible then
Result := Column
else begin
Column := NextColumn(Column);
Inc(i)
end;
end
end
end;
function TEasyHeader.GetCanvasStore: TEasyCanvasStore;
begin
if not Assigned(FCanvasStore) then
FCanvasStore := TEasyCanvasStore.Create;
Result := FCanvasStore
end;
function TEasyHeader.GetDisplayRect: TRect;
begin
Result := Rect(0, 0, OwnerListview.ClientWidth, RuntimeHeight)
end;
function TEasyHeader.GetDraggable: Boolean;
begin
Result := DragManager.Enabled
end;
function TEasyHeader.GetFixedSingleColumn: Boolean;
begin
if OwnerListview.HandleAllocated then
begin
if Columns.Count = 0 then
Columns.Add.Width := OwnerListview.ClientWidth - 1
end;
Result := FFixedSingleColumn;
end;
function TEasyHeader.GetHeight: Integer;
var
TextMetrics: TTextMetric;
DC: HDC;
OldFont: THandle;
begin
Result := FHeight;
if AutoSizeHeight then
begin
DC := GetDC(0);
OldFont := SelectObject(DC, Font.Handle);
try
if GetTextMetrics(DC, TextMetrics) then
if TextMetrics.tmHeight + AutoSizeHeightMargin > FHeight then
Result := TextMetrics.tmHeight + AutoSizeHeightMargin;
ReleaseDC(0, DC);
finally
if OldFont <> 0 then
SelectObject(DC, OldFont);
end
end
end;
function TEasyHeader.GetMouseCaptured: Boolean;
begin
Result := (ebcsHeaderCapture in OwnerListview.States) and (ehsMouseCaptured in State)
end;
function TEasyHeader.GetRuntimeHeight: Integer;
begin
if OwnerListview.ViewSupportsHeader and Visible then
Result := Height
else
Result := 0;
end;
function TEasyHeader.InCheckZone(ViewportPt: TPoint; var Column: TEasyColumn): Boolean;
var
RectArray: TEasyRectArrayObject;
begin
Result := False;
Column := Columns.ColumnByPoint(ViewportPt);
if Assigned(Column) then
begin
Column.View.ItemRectArray(Column, RectArray);
Result := PtInRect(RectArray.CheckRect, ViewportPt)
end
end;
function TEasyHeader.InDropDownButtonZone(ViewportPt: TPoint; var Column: TEasyColumn): Boolean;
var
RectArray: TEasyRectArrayObject;
begin
Result := False;
Column := Columns.ColumnByPoint(ViewportPt);
if Assigned(Column) then
begin
Column.View.ItemRectArray(Column, RectArray);
Result := PtInRect(RectArray.DropDownArrow, ViewportPt)
end
end;
function TEasyHeader.InHotTrackZone(ViewportPt: TPoint; var Column: TEasyColumn): Boolean;
var
i: Integer;
R, ClientR: TRect;
begin
Result := False;
if OwnerListview.PaintInfoColumn.HotTrack then
begin
Column := nil;
ClientR := OwnerListview.ClientRect;
if OwnerListview.ScrollHeaderHorz then
OffsetRect(ClientR, OwnerListview.Scrollbars.OffsetX, 0);
i := 0;
while not Result and (i < OwnerListview.Header.Positions.Count) do
begin
R := OwnerListview.Header.Positions[i].DisplayRect;
// Don't switch hottracking column until done with resize arrow
Inc(R.Right, RESIZEHITZONEMARGIN + 1);
IntersectRect(R, R, ClientR);
if PtInRect(R, ViewportPt) then
begin
Column := OwnerListview.Header.Positions[i];
Result := True
end;
Inc(i)
end;
if not Result then
Result := Assigned(HotTrackedColumn);
end
end;
function TEasyHeader.InPressZone(ViewportPt: TPoint; var Column: TEasyColumn): Boolean;
var
i: Integer;
R: TRect;
begin
Result := False;
Column := nil;
i := OwnerListview.Header.Positions.Count - 1;
while not Result and (i > -1) do
begin
R := OwnerListview.Header.Positions[i].DisplayRect;
if PtInRect(R, ViewportPt) then
begin
Column := OwnerListview.Header.Positions[i];
if Assigned(Column) then
Result := Column.Clickable
end;
Dec(i)
end
end;
function TEasyHeader.InResizeZone(ViewportPt: TPoint; var Column: TEasyColumn): Boolean;
var
i: Integer;
R, ClientR: TRect;
begin
Result := False;
if Sizeable then
begin
Column := nil;
i := OwnerListview.Header.Positions.Count - 1;
ClientR := OwnerListview.ClientRect;
if OwnerListview.ScrollHeaderHorz then
OffsetRect(ClientR, OwnerListview.Scrollbars.OffsetX, 0);
while not Result and (i > -1) do
begin
if Positions[i].Visible then
begin
R := Positions[i].DisplayRect;
if (ViewportPt.X <= R.Right + RESIZEHITZONEMARGIN) and (ViewportPt.X > R.Right - RESIZEHITZONEMARGIN)
and (ViewportPt.Y < Height) and (ViewportPt.Y > 0) and (R.Right <= ClientR.Right) then
begin
Column := OwnerListview.Header.Positions[i];
Result := True
end;
end;
Dec(i)
end
end
end;
function TEasyHeader.IsFontStored: Boolean;
begin
Result := not OwnerListview.ParentFont and not OwnerListview.DesktopFont;
end;
function TEasyHeader.LastColumn: TEasyColumn;
begin
if Columns.Count > 0 then
Result := Columns[Columns.Count - 1]
else
Result := nil
end;
function TEasyHeader.LastColumnByPosition: TEasyColumn;
begin
if Positions.Count > 0 then
Result := Positions[Positions.Count - 1]
else
Result := nil
end;
function TEasyHeader.LastVisibleColumn: TEasyColumn;
var
i: Integer;
Column: TEasyColumn;
begin
Result := nil;
Column := LastColumn;
i := Columns.Count - 1;
while not Assigned(Result) and (i > -1 ) do
begin
if Assigned(Column) then
begin
if Column.Visible then
Result := Column
else begin
Column := PrevColumn(Column);
Dec(i)
end;
end
end
end;
function TEasyHeader.NextColumn(AColumn: TEasyColumn): TEasyColumn;
begin
Result := nil;
if AColumn.Index < Columns.Count - 1 then
Result := Columns[AColumn.Index + 1]
end;
function TEasyHeader.NextColumnByPosition(AColumn: TEasyColumn): TEasyColumn;
begin
Result := nil;
if AColumn.Position < Columns.Count - 1 then
Result := Positions[AColumn.Position + 1]
end;
function TEasyHeader.NextColumnInRect(Column: TEasyColumn; ViewportRect: TRect): TEasyColumn;
//
// Always assumes by Position as this is a UI function
//
var
i: Integer;
ScratchR: TRect;
Done: Boolean;
begin
Result := nil;
Done := False;
if Assigned(Column) then
begin
i := Column.Position + 1;
OffsetRect(ViewportRect, 0, -ViewportRect.Top);
while not Assigned(Result) and (i < Positions.Count) and not Done do
begin
if Positions[i].Visible and (Positions[i].Width > 0) then
begin
if IntersectRect(ScratchR, Positions[i].DisplayRect, ViewportRect) then
Result := Positions[i]
else
Done := True
end;
Inc(i)
end
end
end;
function TEasyHeader.NextVisibleColumn(Column: TEasyColumn): TEasyColumn;
var
i: Integer;
begin
Result := nil;
Column := NextColumn(Column);
if Assigned(Column) then
begin
i := Column.Index;
while not Assigned(Result) and (i < Columns.Count) do
begin
if Column.Visible then
Result := Column
else begin
Column := NextColumn(Column);
Inc(i)
end;
end
end
end;
function TEasyHeader.PrevColumn(AColumn: TEasyColumn): TEasyColumn;
begin
Result := nil;
if AColumn.Index > 0 then
Result := Columns[AColumn.Index - 1]
end;
function TEasyHeader.PrevColumnByPosition(AColumn: TEasyColumn): TEasyColumn;
begin
Result := nil;
if AColumn.Position > 0 then
Result := Positions[AColumn.Position - 1]
end;
function TEasyHeader.PrevVisibleColumn(Column: TEasyColumn): TEasyColumn;
var
i: Integer;
begin
Result := nil;
Column := PrevColumn(Column);
if Assigned(Column) then
begin
i := Column.Index;
while not Assigned(Result) and (i > -1 ) do
begin
if Column.Visible then
Result := Column
else begin
Column := PrevColumn(Column);
Dec(i)
end
end
end
end;
procedure TEasyHeader.CaptureMouse;
begin
Include(OwnerListview.FStates, ebcsHeaderCapture);
Include(FState, ehsMouseCaptured);
SetCapture(OwnerListview.Handle);
end;
procedure TEasyHeader.ClearStates;
begin
Exclude(FState, ehsMouseCaptured);
Exclude(FState, ehsResizing);
Exclude(FState, ehsDragging);
Exclude(FState, ehsDragPending);
Exclude(FState, ehsClickPending);
Exclude(FState, ehsResizePending);
Exclude(FState, ehsLButtonDown);
Exclude(FState, ehsRButtonDown);
Exclude(FState, ehsMButtonDown);
ReleaseMouse;
end;
procedure TEasyHeader.ClickColumn(Column: TEasyColumn);
const
NEXT_SORT_DIRECTION: array[TEasySortDirection] of TEasySortDirection =
(esdAscending, esdDescending, esdAscending);
var
PreviousFocusedColumn: TEasyColumn;
begin
Exclude(Column.FState, esosClicking);
if Column.AutoToggleSortGlyph then
begin
// If sorting takes a bit it is better to "freeze" the painting
// so the sort arrows don't show the "wrong" way then change when
// the sort is done.
OwnerListview.BeginUpdate;
try
PreviousFocusedColumn := OwnerListview.Selection.FocusedColumn;
OwnerListview.Selection.FocusedColumn := Column;
// If the column has changed the previous column must forget its
// sort direction. When it is clicked on next time it will start
// again with SortDirection = esdAscending.
if PreviousFocusedColumn <> Column then
PreviousFocusedColumn.SortDirection := esdNone;
// Now toggle new column's sort direction and regroup / resort
// if necded.
Column.SortDirection := NEXT_SORT_DIRECTION[Column.SortDirection];
if OwnerListview.Sort.AutoReGroup and OwnerListview.IsGrouped then
OwnerListview.Sort.ReGroup(Column)
else if (OwnerListview.Sort.AutoSort) or (Column.AutoSortOnClick) then
OwnerListview.Sort.SortAll(Column.AutoSortOnClick);
finally
OwnerListview.EndUpdate
end;
end;
end;
procedure TEasyHeader.DoMouseDown(var Message: TWMMouse; Button: TCommonMouseButton;
Shift: TShiftState; Column: TEasyColumn);
begin
if Assigned(OwnerListview.OnHeaderMouseDown) then
OwnerListview.OnHeaderMouseDown(OwnerListview, Button, Shift, Message.XPos, Message.YPos, Column)
end;
procedure TEasyHeader.DoMouseMove(var Message: TWMMouse; Shift: TShiftState);
begin
if Assigned(OwnerListview.OnHeaderMouseUp) then
OwnerListview.OnHeaderMouseMove(OwnerListview, Shift, Message.XPos, Message.YPos)
end;
procedure TEasyHeader.DoMouseUp(var Message: TWMMouse; Button: TCommonMouseButton;
Shift: TShiftState; Column: TEasyColumn);
begin
if Assigned(OwnerListview.OnHeaderMouseUp) then
OwnerListview.OnHeaderMouseUp(OwnerListview, Button, Shift, Message.XPos, Message.YPos, Column)
end;
procedure TEasyHeader.HandleHotTrack(Msg: TWMMouse; ForceClear: Boolean);
var
TempColumn, OldColumn: TEasyColumn;
DropDownButtonPending: Boolean;
begin
if ForceClear then
begin
if Assigned(HotTrackedColumn) then
begin
ReleaseMouse;
OldColumn := HotTrackedColumn;
HotTrackedColumn := nil;
OldColumn.Invalidate(True)
end;
end else
begin
DropDownButtonPending := False;
if Assigned(DropDownHoverColumn) then
DropDownButtonPending := cdbsClickPending in DropDownHoverColumn.DropDownButton.State;
if not DropDownButtonPending then
begin
if OwnerListview.ScrollHeaderHorz then
Inc(Msg.Pos.x, OwnerListview.Scrollbars.OffsetX);
if not ([ehsResizing, ehsResizePending, ehsClickPending, ehsDragging, ehsClickPending] * State <> []) {and not DropDownButtonPending} then
if InHotTrackZone(SmallPointToPoint(Msg.Pos), TempColumn) or Assigned(HotTrackedColumn) then
begin
if TempColumn <> HotTrackedColumn then
begin
if Assigned(HotTrackedColumn) then
begin
ReleaseMouse;
OldColumn := HotTrackedColumn;
HotTrackedColumn := nil;
OldColumn.Invalidate(True)
end;
HotTrackedColumn := TempColumn;
if Assigned(HotTrackedColumn) then
begin
CaptureMouse;
HotTrackedColumn.Invalidate(True)
end
end
end
end
end
end;
procedure TEasyHeader.Invalidate(ImmediateUpdate: Boolean);
begin
if OwnerListview.UpdateCount = 0 then
OwnerListview.SafeInvalidateRect(nil, ImmediateUpdate)
end;
procedure TEasyHeader.InvalidateColumn(Item: TEasyColumn;
ImmediateUpdate: Boolean);
begin
end;
procedure TEasyHeader.LoadFromStream(S: TStream; Version: Integer = EASYLISTVIEW_STREAM_VERSION);
begin
inherited LoadFromStream(S, Version);
if StreamColumns then
Columns.ReadItems(S)
end;
procedure TEasyHeader.PaintTo(ACanvas: TCanvas; ARect: TRect);
var
Column: TEasyColumn;
Handled: Boolean;
{$IFDEF USETHEMES}
PartID,
StateID: LongWord;
{$ENDIF}
begin
Handled := False;
CanvasStore.StoreCanvasState(ACanvas);
OwnerListview.DoPaintHeaderBkGnd(ACanvas, ViewRect, Handled);
CanvasStore.RestoreCanvasState(ACanvas);
if not Handled then
begin
{$IFDEF USETHEMES}
if OwnerListview.DrawWithThemes then
begin
PartID := HP_HEADERITEM;
StateID := HIS_NORMAL;
DrawThemeBackground(OwnerListview.Themes.HeaderTheme, ACanvas.Handle, PartID, StateID, ViewRect, nil);
end else
{$ENDIF USETHEMES}
begin
ACanvas.Brush.Color := Color;
ACanvas.FillRect(DisplayRect);
end;
end;
Column := FirstColumnInRect(ARect);
while Assigned(Column) do
begin
// Reset the clipping region
SelectClipRgn(ACanvas.Handle, 0);
Column.Paint(ACanvas, ehtHeader);
Column := NextColumnInRect(Column, ARect);
end
end;
procedure TEasyHeader.SaveToStream(S: TStream; Version: Integer = EASYLISTVIEW_STREAM_VERSION);
begin
inherited SaveToStream(S, Version);
if StreamColumns then
Columns.WriteItems(S)
end;
procedure TEasyHeader.SetAutoSizeHeight(const Value: Boolean);
begin
if FAutoSizeHeight <> Value then
begin
FAutoSizeHeight := Value;
OwnerListview.Groups.Rebuild(False)
end
end;
procedure TEasyHeader.SetAutoSizeHeightMargin(const Value: Integer);
begin
if FAutoSizeHeightMargin <> Value then
begin
FAutoSizeHeightMargin := Value;
if FAutoSizeHeightMargin < 0 then
FAutoSizeHeightMargin := 0;
if AutoSizeHeight then
OwnerListview.Groups.Rebuild(False)
end
end;
procedure TEasyHeader.SetDraggable(Value: Boolean);
begin
DragManager.Enabled := Value
end;
procedure TEasyHeader.SetDropDownHoverColumn(const Value: TEasyColumn);
begin
if FDropDownHoverColumn <> Value then
begin
if Assigned(FDropDownHoverColumn) then
begin
Exclude(FDropDownHoverColumn.DropDownButton.FState, cdbsHovering);
Exclude(FDropDownHoverColumn.DropDownButton.FState, cdbsDown);
Exclude(FDropDownHoverColumn.DropDownButton.FState, cdbsClickPending);
FDropDownHoverColumn.Invalidate(True);
end;
FDropDownHoverColumn := Value;
if Assigned(FDropDownHoverColumn) then
begin
Include(FDropDownHoverColumn.DropDownButton.FState, cdbsHovering);
FDropDownHoverColumn.Invalidate(True);
end;
end
end;
procedure TEasyHeader.SetFixedSingleColumn(const Value: Boolean);
var
i: Integer;
begin
// Columns.Clear;
if Value <> FFixedSingleColumn then
begin
if OwnerListview.HandleAllocated then
begin
for i := 1 to Columns.Count - 1 do
Columns[i].Visible := not Value;
if Value then
begin
if Columns.Count = 0 then
Columns.Add.Width := OwnerListview.ClientWidth - 1
else
Columns[0].Width := OwnerListview.ClientWidth - 1;
end;
OwnerListview.Groups.Rebuild;
end;
FFixedSingleColumn := Value;
end
end;
procedure TEasyHeader.SetHotTrackedColumn(const Value: TEasyColumn);
var
Pt: TPoint;
begin
if Value <> FHotTrackedColumn then
begin
Pt.x := 0;
Pt.y := 0;
if Assigned(HotTrackedColumn) then
HotTrackedColumn.HotTracking[Pt] := False;
if Assigned(Value) then
Value.HotTracking[Pt] := True;
FHotTrackedColumn := Value;
end
end;
procedure TEasyHeader.SetShowInAllViews(const Value: Boolean);
begin
if Value <> FShowInAllViews then
begin
FShowInAllViews := Value;
OwnerListview.Groups.Rebuild
end;
end;
procedure TEasyHeader.SizeFixedSingleColumn(NewWidth: Integer);
begin
if Columns.Count > 0 then
begin
if Columns[0].Width <> NewWidth then
begin
Columns[0].Width := NewWidth;
OwnerListview.Groups.Rebuild(True);
end
end
end;
procedure TEasyHeader.SpringColumns(NewWidth: Integer);
//
// Credit goes to VirtualTreeview by Mike Lischke
var
I: Integer;
SpringCount: Integer;
Sign: Integer;
ChangeBy: Single;
Difference: Single;
NewAccumulator: Single;
begin
ChangeBy := RectWidth(DisplayRect) - FLastWidth;
if (ChangeBy <> 0) then
begin
// Stay positive if downsizing the control.
if ChangeBy < 0 then
Sign := -1
else
Sign := 1;
ChangeBy := Abs(ChangeBy);
// Count how many columns have spring enabled.
SpringCount := 0;
for I := 0 to Columns.Count-1 do
if Columns[i].AutoSpring and Columns[i].Visible then
Inc(SpringCount);
if SpringCount > 0 then
begin
// Calculate the size to add/sub to each columns.
Difference := ChangeBy / SpringCount;
// Adjust the column's size accumulators and resize if the result is >= 1.
for I := 0 to Columns.Count - 1 do
if Columns[i].AutoSpring and Columns[i].Visible then
begin
// Sum up rest changes from previous runs and the amount from this one and store it in the
// column. If there is at least one pixel difference then do a resize and reset the accumulator.
NewAccumulator := Columns[I].FSpringRest + Difference;
// Set new width if at least one pixel size difference is reached.
if NewAccumulator >= 1 then
FColumns[I].SetWidth(FColumns[I].FWidth + (Trunc(NewAccumulator) * Sign));
FColumns[I].FSpringRest := Frac(NewAccumulator);
// Keep track of the size count.
ChangeBy := ChangeBy - Difference;
// Exit loop if resize count drops below freezing point.
if ChangeBy < 0 then
Break;
end;
end;
end;
end;
procedure TEasyHeader.WMContextMenu(var Msg: TMessage);
var
Column: TEasyColumn;
ViewPt, Pt: TPoint;
HitInfoColumn: TEasyHitInfoColumn;
Menu: TPopupMenu;
begin
Menu := OwnerListview.PopupMenuHeader;
Pt := OwnerListview.ScreenToClient(Point( Msg.LParamLo, Msg.LParamHi));
if OwnerListview.ScrollHeaderHorz then
ViewPt := OwnerListview.Scrollbars.MapWindowToView(Pt, False);
HitInfoColumn.Column := Columns.ColumnByPoint(ViewPt);
Column := Columns.ColumnByPoint(ViewPt);
if Assigned(HitInfoColumn.Column) then
Column.HitTestAt(ViewPt, HitInfoColumn.HitInfo)
else
HitInfoColumn.HitInfo := [];
// HitInfoColumn.Column will be nil if it hits the backgound of the header
OwnerListview.DoColumnContextMenu(HitInfoColumn, Pt, Menu);
if Assigned(Menu) then
begin
Menu.Popup(Msg.LParamLo, Msg.LParamHi);
Msg.Result := 1
end else
inherited;
end;
procedure TEasyHeader.WMSize(var Msg: TWMSize);
begin
{$IFDEF GXDEBUG}
SendDebug('Header WMSize');
{$ENDIF GXDEBUG}
if LastWidth < 0 then
LastWidth := RectWidth(DisplayRect);
if FixedSingleColumn then
SizeFixedSingleColumn(Msg.Width - 1)
else
SpringColumns(Msg.Width);
LastWidth := RectWidth(DisplayRect)
end;
function SortByPosition(Item1, Item2: Pointer): Integer;
begin
Result := TEasyColumn(Item1).Position - TEasyColumn(Item2).Position
end;
procedure TEasyHeader.Rebuild(Force: Boolean);
var
i: Integer;
begin
if Force or ((OwnerListview.UpdateCount = 0) and not(csLoading in OwnerListview.ComponentState) and (OwnerListview.HandleAllocated)) then
begin
Positions.Clear;
Columns.VisibleList.Clear;
Positions.Capacity := Positions.Count;
for i := 0 to Columns.Count - 1 do
Positions.Add(Columns[i]);
Positions.Sort(SortByPosition);
for i := 0 to Columns.Count - 1 do
Positions[i].FPosition := i;
for i := 0 to Columns.Count - 1 do
begin
if Columns[i].Visible then
begin
Columns.VisibleList.Add(Columns[i]);
if FixedSingleColumn then
Columns[i].FWidth := OwnerListview.ClientWidth; // do this direct so not to fire events
end
end;
SetRect(FViewRect, 0, 0, 0, 0);
for i := 0 to Positions.Count - 1 do
begin
if i > 0 then
begin
Positions[i].FDisplayRect := Positions[i-1].FDisplayRect;
Positions[i].FDisplayRect.Left := Positions[i].FDisplayRect.Right;
if Positions[i].Visible then
Positions[i].FDisplayRect.Right := Positions[i].FDisplayRect.Left + Positions[i].Width
else
Positions[i].FDisplayRect.Right := Positions[i].FDisplayRect.Left;
end else
begin
if Positions[i].Visible then
Positions[i].FDisplayRect := Rect(0, 0, Positions[i].Width, Height)
else
Positions[i].FDisplayRect := Rect(0, 0, 0, Height)
end;
UnionRect(FViewRect, ViewRect, Positions[i].DisplayRect);
if RectWidth(ViewRect) < OwnerListview.Width then
FViewRect.Right := OwnerListview.ClientWidth;
end;
end
end;
procedure TEasyHeader.ReleaseMouse;
begin
Exclude(FState, ehsMouseCaptured);
Exclude(OwnerListview.FStates, ebcsHeaderCapture);
if GetCapture = OwnerListview.Handle then
ReleaseCapture
end;
procedure TEasyHeader.SetColor(Value: TColor);
begin
if FColor <> Value then
begin
FColor := Value;
Invalidate(False);
end
end;
procedure TEasyHeader.SetFont(Value: TFont);
begin
Font.Assign(Value)
end;
procedure TEasyHeader.SetHeight(Value: Integer);
begin
if FHeight <> Value then
begin
if Value > -1 then
FHeight := Value
else
FHeight := 0;
OwnerListview.Groups.Rebuild
end
end;
procedure TEasyHeader.SetImages(Value: TCustomImageList);
begin
if Value <> FImages then
begin
FImages := Value;
OwnerListview.SafeInvalidateRect(nil, False)
end
end;
procedure TEasyHeader.SetVisible(Value: Boolean);
begin
if Value <> FVisible then
begin
FVisible := Value;
OwnerListview.Groups.Rebuild
end;
end;
{ TEasyItemView }
procedure TEasyHeader.WMLButtonDblClk(var Msg: TWMLButtonDblClk);
var
ViewPt: TPoint;
Column: TEasyColumn;
Button: TCommonMouseButton;
begin
Button := KeyStatesToMouseButton(Msg.Keys);
ViewPt := SmallPointToPoint(Msg.Pos);
if OwnerListview.ScrollHeaderHorz then
Inc(ViewPt.X, OwnerListview.Scrollbars.OffsetX);
if InResizeZone(ViewPt, Column) and (ehsResizePending in State) then
begin
if Column.AutoSizeOnDblClk then
Column.AutoSizeToFit
end;
Column := Columns.ColumnByPoint(ViewPt);
OwnerListview.DoHeaderDblClick(Button, SmallPointToPoint(Msg.Pos), KeysToShiftState(Msg.Keys));
if Assigned(Column) then
OwnerListview.DoColumnDblClick(Button, KeysToShiftState(Msg.Keys), SmallPointToPoint(Msg.Pos), Column);
end;
procedure TEasyHeader.WMLButtonDown(var Msg: TWMLButtonDown);
var
ViewPt: TPoint;
TempColumn: TEasyColumn;
begin
ViewPt := SmallPointToPoint(Msg.Pos);
if OwnerListview.ScrollHeaderHorz then
Inc(ViewPt.X, OwnerListview.Scrollbars.OffsetX);
Include(FState, ehsLButtonDown);
if ehsResizePending in State then
begin
Exclude(FState, ehsResizePending);
Include(FState, ehsResizing);
end else
if InCheckZone(ViewPt, TempColumn) then
begin
Include(FState, ehsCheckboxClickPending);
OwnerListview.HotTrack.PendingObjectCheck := nil;
OwnerListview.CheckManager.PendingObject := TempColumn;
end else
if InDropDownButtonZone(ViewPt, TempColumn) then
begin
if TempColumn.DropDownButton.Enabled then
begin
DropDownHoverColumn := TempColumn;
Include(DropDownHoverColumn.DropDownButton.FState, cdbsClickPending);
Include(DropDownHoverColumn.DropDownButton.FState, cdbsDown);
DropDownHoverColumn.Invalidate(True)
end
end else
if InPressZone(ViewPt, FPressColumn) then
begin
// Clear the Hottrack item
if OwnerListview.PaintInfoColumn.HotTrack then
HandleHotTrack(Msg, True);
CaptureMouse;
if PressColumn.Clickable then
begin
Include(FState, ehsClickPending);
Include(PressColumn.FState, esosClicking);
end;
if Draggable then
Include(FState, ehsDragPending);
PressColumn.Invalidate(True);
DoMouseDown(Msg, cmbLeft, KeysToShiftState(Msg.Keys), Columns.ColumnByPoint(ViewPt));
end
end;
procedure TEasyHeader.WMLButtonUp(var Msg: TWMLButtonUp);
const
NEXT_SORT_DIRECTION: array[TEasySortDirection] of TEasySortDirection =
(esdAscending, esdDescending, esdAscending);
var
ViewPt, Pt: TPoint;
PreviousFocusedColumn: TEasyColumn;
DoDefault: Boolean;
RectArray: TEasyRectArrayObject;
begin
ViewPt := SmallPointToPoint(Msg.Pos);
if OwnerListview.ScrollHeaderHorz then
Inc(ViewPt.X, OwnerListview.Scrollbars.OffsetX);
if ehsCheckboxClickPending in State then
begin
if InCheckZone(ViewPt, PreviousFocusedColumn) then
PreviousFocusedColumn.Checked := not PreviousFocusedColumn.Checked;
OwnerListview.CheckManager.PendingObject.CheckHovering := False;
OwnerListview.CheckManager.PendingObject.CheckPending := False;
OwnerListview.CheckManager.PendingObject := nil;
end else
if ehsResizing in State then
begin
OwnerListview.DoColumnSizeChanged(ResizeColumn);
end else
if Assigned(DropDownHoverColumn) and (cdbsClickPending in DropDownHoverColumn.DropDownButton.State) then
begin
// NEED SHORT CIRCUIT BOOLEAN EVALUATION for this to work
if cdbsDown in DropDownHoverColumn.DropDownButton.State then
begin
DoDefault := True;
OwnerListview.DoColumnDropDownButtonClick(DropDownHoverColumn, cmbLeft, KeysToShiftState(Msg.Keys), SmallPointToPoint(Msg.Pos), DoDefault);
if DoDefault then
begin
if Assigned(DropDownHoverColumn.DropDownButton.Menu) then
begin
DropDownHoverColumn.View.ItemRectArray(DropDownHoverColumn, RectArray);
Pt.x := RectArray.DropDownArrow.Left;
Pt.y := RectArray.DropDownArrow.Bottom;
Pt := OwnerListview.Scrollbars.MapViewToWindow(Pt, False);
Pt := OwnerListview.ClientToScreen(Pt);
DropDownHoverColumn.DropDownButton.Menu.Popup(Pt.x, Pt.y)
end
end
end;
Exclude(DropDownHoverColumn.DropDownButton.FState, cdbsClickPending);
DropDownHoverColumn := nil;
end else
if Assigned(PressColumn) then
begin
if esosClicking in PressColumn.State then
begin
ClickColumn(PressColumn);
OwnerListview.DoColumnClick(cmbLeft, PressColumn);
end else
PressColumn.Invalidate(True);
end;
if [ehsResizing, ehsDragging] * FState = [] then
DoMouseUp(Msg, cmbLeft, KeysToShiftState(Msg.Keys), Columns.ColumnByPoint(ViewPt));
Exclude(FState, ehsLButtonDown);
Exclude(FState, ehsResizing);
Exclude(FState, ehsClickPending);
Exclude(FState, ehsDragging);
Exclude(FState, ehsDragPending);
Exclude(FState, ehsCheckboxClickPending);
end;
procedure TEasyHeader.WMMouseMove(var Msg: TWMMouseMove);
procedure Press(Column: TEasyColumn; Pressed: Boolean);
begin
if Assigned(Column) then
begin
if Pressed then
Include(Column.FState, esosClicking)
else
Exclude(Column.FState, esosClicking);
Column.Invalidate(True);
end;
end;
var
ViewPt: TPoint;
Allow, ClearDropDownBtn: Boolean;
TempColumn: TEasyColumn;
ClientR: TRect;
HotTrackCheckObj: TEasyCollectionItem;
Effects: TCommonDropEffect;
begin
ClearDropDownBtn := True;
ClientR := ViewRect;
ViewPt := SmallPointToPoint(Msg.Pos);
if OwnerListview.ScrollHeaderHorz then
begin
ViewPt.X := ViewPt.X + OwnerListview.Scrollbars.OffsetX;
OffsetRect(ClientR, OwnerListview.Scrollbars.OffsetX, 0);
end;
if not MouseCaptured and Assigned(Self.HotTrackedColumn) then
CaptureMouse;
HotTrackCheckObj := nil;
if OwnerListview.PaintInfoColumn.HotTrack then
HandleHotTrack(Msg, False);
if ehsResizing in State then
begin
Allow := True;
OwnerListview.DoColumnSizeChanging(ResizeColumn, ResizeColumn.Width, ViewPt.X - ResizeColumn.DisplayRect.Left, Allow);
if Allow then
begin
ResizeColumn.Width := ViewPt.X - ResizeColumn.DisplayRect.Left;
OwnerListview.Groups.Rebuild(True)
end
end else
if ehsDragging in State then
begin
Effects := cdeMove;
DragManager.Drag(OwnerListview.Canvas, ViewPt, KeyToKeyStates(Msg.Keys), Effects);
end else
if ehsResizePending in State then
begin
if not InResizeZone(ViewPt, FResizeColumn) then
begin
FResizeColumn := nil;
Exclude(FState, ehsResizePending);
ReleaseMouse;
OwnerListview.Cursor := crDefault;
if Assigned(HotTrackedColumn) then
CaptureMouse
end
end else
if (ehsDragPending in State) and DragManager.Enabled then
begin
if DragDetectPlus(OwnerListview.Handle, SmallPointToPoint(Msg.Pos)) then
begin
Exclude(FState, ehsDragPending);
Exclude(FState, ehsClickPending);
Include(FState, ehsDragging);
DragManager.Column := PressColumn;
Press(PressColumn, False);
PressColumn := nil;
DragManager.BeginDrag(ViewPt, KeyToKeyStates(Msg.Keys));
end
end else
if ehsClickPending in State then
begin
//
end else
if Assigned(DropDownHoverColumn) and (cdbsClickPending in DropDownHoverColumn.DropDownButton.State) then
begin
// NEED SHORT CIRCUIT BOOLEAN EVALUATION for this to work
if InDropDownButtonZone(ViewPt, TempColumn) and (TempColumn = DropDownHoverColumn) then
begin
Include(DropDownHoverColumn.DropDownButton.FState, cdbsDown);
DropDownHoverColumn.Invalidate(True)
end else
begin
Exclude(DropDownHoverColumn.DropDownButton.FState, cdbsDown);
DropDownHoverColumn.Invalidate(True)
end;
ClearDropDownBtn := False;
end else
if InCheckZone(ViewPt, TempColumn) then
begin
HotTrackCheckObj := TempColumn;
end else
if InResizeZone(ViewPt, FResizeColumn) then
begin
Allow := True;
OwnerListview.DoColumnSizeChanging(ResizeColumn, ResizeColumn.Width, ResizeColumn.Width, Allow);
if Allow then
begin
// Some other thing may have the mouse captured and the Cursor won't take
ReleaseCapture;
Include(FState, ehsResizePending);
OwnerListview.Cursor := crVHeaderSplit;
CaptureMouse;
end
end else
if InDropDownButtonZone(ViewPt, TempColumn) then
begin
DropDownHoverColumn := TempColumn;
ClearDropDownBtn := False;
end else
begin
OwnerListview.Cursor := crDefault;
DoMouseMove(Msg, KeysToShiftState(Msg.Keys));
end;
if (ehsCheckboxClickPending in State) then
begin
if Assigned(HotTrackCheckObj) then
begin
if OwnerListview.CheckManager.PendingObject <> HotTrackCheckObj then
begin
OwnerListview.CheckManager.PendingObject.CheckHovering := True;
HotTrackCheckObj := nil
end else
OwnerListview.CheckManager.PendingObject.CheckHovering := False;
end else
begin
OwnerListview.CheckManager.PendingObject.CheckHovering := True;
end;
if HotTrackCheckObj <> nil then
HotTrackCheckObj := nil;
end;
if OwnerListview.CheckManager.PendingObject = HotTrackCheckObj then
HotTrackCheckObj := nil;
OwnerListview.HotTrack.PendingObjectCheck := HotTrackCheckObj;
if ClearDropDownBtn then
DropDownHoverColumn := nil;
end;
procedure TEasyHeader.WMRButtonDown(var Msg: TWMRButtonDown);
var
ViewPt: TPoint;
begin
ViewPt := SmallPointToPoint(Msg.Pos);
if OwnerListview.ScrollHeaderHorz then
Inc(ViewPt.X, OwnerListview.Scrollbars.OffsetX);
Include(FState, ehsRButtonDown);
DoMouseDown(Msg, cmbRight, KeysToShiftState(Msg.Keys), Columns.ColumnByPoint(ViewPt));
end;
procedure TEasyHeader.WMRButtonUp(var Msg: TWMRButtonUp);
var
ViewPt: TPoint;
begin
ViewPt := SmallPointToPoint(Msg.Pos);
if OwnerListview.ScrollHeaderHorz then
Inc(ViewPt.X, OwnerListview.Scrollbars.OffsetX);
Exclude(FState, ehsRButtonDown);
Exclude(FState, ehsResizing);
Exclude(FState, ehsClickPending);
Exclude(FState, ehsDragging);
Exclude(FState, ehsDragPending);
DoMouseUp(Msg, cmbRight, KeysToShiftState(Msg.Keys), Columns.ColumnByPoint(ViewPt));
end;
function TEasyViewItem.AllowDrag(Item: TEasyItem; ViewportPoint: TPoint): Boolean;
begin
Result := True;
end;
function TEasyViewItem.EditAreaHitPt(Item: TEasyItem; ViewportPoint: TPoint): Boolean;
var
RectArray: TEasyRectArrayObject;
begin
Result := False;
if Item.Enabled then
begin
ItemRectArray(Item, OwnerListview.Header.FirstColumn, Item.OwnerListview.ScratchCanvas, '', RectArray);
Result := Windows.PtInRect(RectArray.TextRect, ViewportPoint);
end
end;
function TEasyViewItem.ExpandIconR(Item: TEasyItem; RectArray: TEasyRectArrayObject; SelectType: TEasySelectHitType): TRect;
begin
Result := RectArray.IconRect
end;
function TEasyViewItem.ExpandTextR(Item: TEasyItem; RectArray: TEasyRectArrayObject; SelectType: TEasySelectHitType): TRect;
begin
if Item.Focused and (OwnerListview.Focused or Item.OwnerListview.Selection.PopupMode) then
Result := RectArray.FullTextRect
else
Result := RectArray.TextRect;
end;
function TEasyViewItem.FullRowSelect: Boolean;
begin
Result := False;
end;
function TEasyViewItem.GetImageList(Column: TEasyColumn; Item: TEasyItem; Image: TEasyImageKind): TCustomImageList;
begin
if Image = eikNormal then
Result := Item.ImageList[ValidateColumnIndex(Column), PaintImageSize]
else
Result := Item.StateImageList[ValidateColumnIndex(Column)];
end;
function TEasyViewItem.OverlappedFocus: Boolean;
//
// Returns true if the view will overlap another cell when the object has the focus
begin
Result := False
end;
function TEasyViewItem.PaintImageSize: TEasyImageSize;
begin
Result := eisSmall
end;
function TEasyViewItem.PaintStateImage: Boolean;
begin
Result := False
end;
function TEasyViewItem.SelectionHit(Item: TEasyItem; SelectViewportRect: TRect;
SelectType: TEasySelectHitType): Boolean;
var
R: TRect;
RectArray: TEasyRectArrayObject;
begin
Result := False;
if Item.Enabled then
begin
ItemRectArray(Item, nil, OwnerListview.ScratchCanvas, '', RectArray);
Result := IntersectRect(R, SelectViewportRect, ExpandTextR(Item, RectArray, SelectType)) or
IntersectRect(R, SelectViewportRect, ExpandIconR(Item, RectArray, SelectType))
end
end;
function TEasyViewItem.SelectionHitPt(Item: TEasyItem; ViewportPoint: TPoint;
SelectType: TEasySelectHitType): Boolean;
var
RectArray: TEasyRectArrayObject;
begin
Result := False;
if Item.Enabled then
begin
ItemRectArray(Item, nil, OwnerListview.ScratchCanvas, '', RectArray);
Result := Windows.PtInRect(ExpandTextR(Item, RectArray, SelectType), ViewportPoint) or
Windows.PtInRect(ExpandIconR(Item, RectArray, SelectType), ViewportPoint)
end
end;
function TEasyViewItem.ValidateColumnIndex(Column: TEasyColumn): Integer;
begin
if Assigned(Column) then
Result := Column.Index
else
Result := 0
end;
procedure TEasyViewItem.AfterSelRectCalc(Item: TEasyItem; Column: TEasyColumn;
const Caption: WideString; var LocalSelRect: TRect);
begin
end;
procedure TEasyViewItem.CalculateTextRect(Item: TEasyItem; Column: TEasyColumn;
var TextR: TRect; ACanvas: TControlCanvas);
// Fits the Text in the PaintInfo.Caption.Text field into the TextR based
// on the values in the PaintInfo record. If Canvas is nil then a temporary
// canvas is created to fit the text based on the Font in the PaintInfo
var
DrawTextFlags: TCommonDrawTextWFlags;
LocalCanvas: TControlCanvas;
begin
case PaintTextAlignment(Item, Column) of
taLeftJustify: Include(DrawTextFlags, dtLeft);
taRightJustify: Include(DrawTextFlags, dtRight);
taCenter: Include(DrawTextFlags, dtCenter);
end;
case PaintTextVAlignment(Item, Column) of
cvaTop: Include(DrawTextFlags, dtTop);
cvaBottom: Include(DrawTextFlags, dtBottom);
cvaCenter: Include(DrawTextFlags, dtVCenter);
end;
if not Assigned(ACanvas) then
begin
LocalCanvas := TControlCanvas.Create;
LocalCanvas.Control := OwnerListview
end else
LocalCanvas := ACanvas;
try
LoadTextFont(Item, 0, LocalCanvas, False);
DrawTextFlags := DrawTextFlags + [dtCalcRectAdjR, dtCalcRect, dtCalcRectAlign];
DrawTextWEx(LocalCanvas.Handle, Item.Captions[0], TextR, DrawTextFlags, 1);
finally
if not Assigned(ACanvas) then
LocalCanvas.Free
end;
end;
function TEasyViewItem.ItemRect(Item: TEasyItem; Column: TEasyColumn;
RectType: TEasyCellRectType): TRect;
var
RectArray: TEasyRectArrayObject;
begin
Result := Rect(0, 0, 0, 0);
// First look for cached rectangles during a drag
(* CacheRectangle(Item, RectType, Result, cdrRetrieve); *)
if IsRectEmpty(Result) then
begin
ItemRectArray(Item, Column, OwnerListview.ScratchCanvas, '', RectArray);
case RectType of
ertBounds: Result := RectArray.BoundsRect;
ertIcon: Result := RectArray.IconRect;
ertLabel: Result := RectArray.LabelRect;
ertClickselectBounds: Result := RectArray.ClickselectBoundsRect;
ertDragSelectBounds: Result := RectArray.DragSelectBoundsRect;
ertText: Result := RectArray.TextRect;
ertFullText: Result := RectArray.FullTextRect;
end;
(* CacheRectangle(Item, RectType, Result, cdrStore); *)
end;
end;
procedure TEasyViewItem.GetImageSize(Item: TEasyItem; Column: TEasyColumn; var ImageW, ImageH: Integer; Image: TEasyImageKind);
var
Images: TCustomImageList;
ColumnPos: Integer;
IsCustom: Boolean;
begin
ImageW := 0;
ImageH := 0;
ColumnPos := ValidateColumnIndex(Column);
if Image = eikNormal then
begin
if Item.ImageIndexes[ColumnPos] > -1 then
begin
Item.ImageDrawIsCustom(Column, IsCustom);
if IsCustom then
Item.ImageDrawGetSize(Column, ImageW, ImageH)
else begin
Images := GetImageList(Column, Item, Image);
if Assigned(Images) then
begin
ImageW := Images.Width;
ImageH := Images.Height
end
end
end
end else
begin
Images := GetImageList(Column, Item, Image);
if Assigned(Images) then
begin
ImageW := Images.Width;
ImageH := Images.Height
end
end
end;
function TEasyViewItem.GetStateImageList(Column: TEasyColumn; Item: TEasyItem): TCustomImageList;
begin
Result := Item.StateImageList[Column.Index]
end;
procedure TEasyViewItem.ItemRectArray(Item: TEasyItem; Column: TEasyColumn; ACanvas: TCanvas; const Caption: WideString; var RectArray: TEasyRectArrayObject);
//
// Grabs all the rectangles for the items within a cell in one call
//
begin
Item.Initialized := True;
FillChar(RectArray, SizeOf(RectArray), #0);
RectArray.BoundsRect := Item.DisplayRect;
InflateRect(RectArray.BoundsRect, -Item.Border, -Item.Border);
RectArray.IconRect := RectArray.BoundsRect;
RectArray.LabelRect := RectArray.BoundsRect;
RectArray.ClickselectBoundsRect := RectArray.BoundsRect;
RectArray.DragSelectBoundsRect := RectArray.BoundsRect;
RectArray.TextRect := RectArray.BoundsRect;
RectArray.SelectionRect := RectArray.BoundsRect;
RectArray.FocusChangeInvalidRect := RectArray.BoundsRect;
RectArray.EditRect := RectArray.FullTextRect;
SetRect(RectArray.CheckRect, 0, 0, 0, 0);
end;
procedure TEasyViewItem.LoadTextFont(Item: TEasyItem; Position: Integer; ACanvas: TCanvas; Hilightable: Boolean);
begin
ACanvas.Font.Assign(OwnerListview.Font);
ACanvas.Brush.Style := bsClear;
if not OwnerListview.ShowInactive then
begin
if Hilightable then
begin
if OwnerListview.Focused or Item.OwnerListview.Selection.PopupMode or Item.Hilighted then
ACanvas.Font.Color := OwnerListview.Selection.TextColor
else
ACanvas.Font.Color := OwnerListview.Selection.InactiveTextColor
end;
if OwnerListview.HotTrack.Enabled and not Item.Hilighted then
begin
if (OwnerListview.HotTrack.FPendingObject = Item) and not Item.Selected then
begin
ACanvas.Font.Color := OwnerListview.HotTrack.Color;
if OwnerListview.HotTrack.Underline then
ACanvas.Font.Style := ACanvas.Font.Style + [fsUnderline]
end
end
end else
ACanvas.Font.Color := clGrayText;
if Item.Bold then
ACanvas.Font.Style := ACanvas.Font.Style + [fsBold];
OwnerListview.DoItemPaintText(Item, Position, ACanvas);
end;
procedure TEasyViewItem.Paint(Item: TEasyItem; Column: TEasyColumn; ACanvas: TCanvas; ViewportClipRect: TRect; ForceSelectionRectDraw: Boolean);
// The Canvas's DC offset has been shifted on entry so that the viewport coords
// of the item can be use direct within the method
var
RectArray: TEasyRectArrayObject;
Caption: WideString;
Handled: Boolean;
begin
if Item.Visible then
begin
CanvasStore.StoreCanvasState(ACanvas);
try
if Assigned(Column) then
Caption := Item.Captions[Column.Index]
else
Caption := Item.Caption;
ItemRectArray(Item, Column, ACanvas, Caption, RectArray);
Handled := False;
// First allow decendents a crack at the painting
PaintBefore(Item, Column, Caption, ACanvas, RectArray, Handled);
if not Handled then
begin
// Paint the Selection Rectangle
// *************************
if not(OwnerListview.EditManager.Editing and (OwnerListview.EditManager.EditItem = Item)) then
PaintSelectionRect(Item, Column, Caption, RectArray, ACanvas, ViewportClipRect, ForceSelectionRectDraw);
// Next Paint the Icon or Bitmap Image
// *************************
PaintImage(Item, Column, Caption, RectArray, eisSmall, ACanvas);
// Now lets paint the Text
// *************************
// If focused then show as many lines as necessary
// Decendents should override PaintText to change the number of lines
// as necessary
if not(OwnerListview.EditManager.Editing and (OwnerListview.EditManager.EditItem = Item)) or ((OwnerListview.View = elsReport) and (Column <> OwnerListview.EditManager.EditColumn)) then
begin
PaintText(Item, Column, Caption, RectArray, ACanvas, PaintTextLineCount(Item, Column));
// Now lets paint Focus Rectangle
// *************************
if OwnerListview.Selection.UseFocusRect then
PaintFocusRect(Item, Column, Caption, RectArray, ACanvas);
end;
// Now Paint the Checkbox if applicable
PaintCheckBox(Item, Column, RectArray, ACanvas);
// Now give decentant a chance to paint anything
PaintAfter(Item, Column, Caption, ACanvas, RectArray);
end
finally
CanvasStore.RestoreCanvasState(ACanvas)
end
end
end;
procedure TEasyViewItem.PaintAfter(Item: TEasyItem; Column: TEasyColumn; const Caption: WideString; ACanvas: TCanvas; RectArray: TEasyRectArrayObject);
begin
//
// Called after all other drawing is done
//
end;
procedure TEasyViewItem.PaintAlphaBlendedRoundRect(ACanvas: TCanvas;
AlphaColor: TColor; GradientBottom: TColor; GradientTop: TColor;
var LocalSelWindowClippedRect: TRect; var Rgn: HRGN);
var
Bits: TBitmap;
GlassBits: TBitmap;
begin
// If it is a round rectangle then we need to create a round region
// to "clip" the square Alpha Blended memory bitmap to the round rectangle
Bits := TBitmap.Create;
try
Bits.PixelFormat := pf32Bit;
Bits.Width := RectWidth(LocalSelWindowClippedRect);
Bits.Height := RectHeight(LocalSelWindowClippedRect);
// Make a copy of the background image behind the square text rect
BitBlt(Bits.Canvas.Handle, 0, 0, Bits.Width, Bits.Height, ACanvas.Handle,
LocalSelWindowClippedRect.Left, LocalSelWindowClippedRect.Top, SRCCOPY);
Bits.Canvas.Pen.Color := ACanvas.Pen.Color;
// Draw the rectangle to it with a clear center
Bits.Canvas.Brush.Style := bsClear;
RoundRect(Bits.Canvas.Handle, 0, 0, Bits.Width, Bits.Height,
OwnerListview.Selection.RoundRectRadius,
OwnerListview.Selection.RoundRectRadius);
if OwnerListview.Selection.Gradient then
begin
GlassBits := TBitmap.Create;
GlassBits.Width := RectWidth(LocalSelWindowClippedRect);
GlassBits.Height := RectHeight(LocalSelWindowClippedRect);
GlassBits.PixelFormat := pf32Bit;
FillGradient(0, 0, GlassBits.Width, GlassBits.Height,
GradientTop, GradientBottom,
0, GlassBits.Height, GlassBits.Canvas);
BlendBits(GlassBits, Bits, 80, 20, OwnerListview.Selection.BlurAlphaBkGnd);
GlassBits.Free;
end
else
// AlphaBlend the memory bitmap
AlphaBlend(0, Bits.Canvas.Handle, Rect(0, 0, Bits.Width, Bits.Height), Point(0, 0),
cbmConstantAlphaAndColor, OwnerListview.Selection.BlendAlphaTextRect,
ColorToRGB(AlphaColor));
LocalSelWindowClippedRect := OwnerListview.Scrollbars.MapViewRectToWindowRect(LocalSelWindowClippedRect);
// Create a round rect region in the Canvas DC to blast the alpha
// blended memory bitmap to. The Alpha blending also blended the
// corners where we do not need it so we must only copy the actual
// round rect area to the Canvas
Rgn := CreateRoundRectRgn(
LocalSelWindowClippedRect.Left,
LocalSelWindowClippedRect.Top,
LocalSelWindowClippedRect.Right + 1,
LocalSelWindowClippedRect.Bottom + 1,
OwnerListview.Selection.RoundRectRadius,
OwnerListview.Selection.RoundRectRadius);
LocalSelWindowClippedRect := OwnerListview.Scrollbars.MapWindowRectToViewRect(LocalSelWindowClippedRect);
// Select the new User round rect region to the DC
SelectClipRgn(ACanvas.Handle, Rgn);
OwnerListview.ClipHeader(ACanvas, False);
BitBlt(ACanvas.Handle,
LocalSelWindowClippedRect.Left,
LocalSelWindowClippedRect.Top,
RectWidth(LocalSelWindowClippedRect),
RectHeight(LocalSelWindowClippedRect),
Bits.Canvas.Handle,
0,
0,
SRCCOPY);
OwnerListview.ClipHeader(ACanvas, True);
finally
// Remove the User clipping region from the DC
if Rgn <> 0 then
DeleteObject(Rgn);
Bits.Free;
end;
end;
procedure TEasyViewItem.PaintAlphaBlendedSelection(ACanvas: TCanvas;
AlphaColor: TColor; HeaderClippedWindowRect: TRect; LocalSelRect: TRect);
begin
// AlphaBlend does not clip and does not use the DC Origins, must be absolute to physical screen pixels
AlphaBlend(0, ACanvas.Handle, HeaderClippedWindowRect, Point(0, 0),
cbmConstantAlphaAndColor, OwnerListview.Selection.BlendAlphaTextRect, ColorToRGB(AlphaColor));
ACanvas.Brush.Style := bsClear;
Rectangle(ACanvas.Handle, LocalSelRect.Left, LocalSelRect.Top, LocalSelRect.Right, LocalSelRect.Bottom);
end;
procedure TEasyViewItem.PaintBefore(Item: TEasyItem; Column: TEasyColumn; const Caption: WideString; ACanvas: TCanvas; RectArray: TEasyRectArrayObject; var Handled: Boolean);
//
// Called before all other drawing is done
//
begin
if Item.Border > 0 then
begin
ACanvas.Brush.Color := Item.BorderColor;
ACanvas.FrameRect(RectArray.BoundsRect);
end
end;
procedure TEasyViewItem.PaintCheckBox(Item: TEasyItem; Column: TEasyColumn;
RectArray: TEasyRectArrayObject; ACanvas: TCanvas);
var
PaintCheckBox: Boolean;
AbsIndex: Integer;
begin
PaintCheckBox := not ((Item.CheckType = ectNone) or (Item.CheckType = ettNoneWithSpace));
if Assigned(Column) then
begin
AbsIndex := Column.Index;
if AbsIndex > 0 then
PaintCheckBox := False;
// Future inhancement, checkboxes in columns
// PaintCheckBox := not ((Item.Details[ColumnIndex].CheckType = ectNone) or (Item.Details[ColumnIndex].CheckType = ettNoneWithSpace));
end;
if PaintCheckBox then
PaintCheckboxCore(Item.CheckType, // TEasyCheckType
OwnerListview, // TCustomEasyListview
ACanvas, // TCanvas
RectArray.CheckRect, // TRect
Item.Enabled, // IsEnabled
Item.Checked, // IsChecked
OwnerListview.CheckManager.PendingObject = Item, // IsHot
Item.CheckFlat, // IsFlat
Item.CheckHovering, // IsHovering
Item.CheckPending, // IsPending
Item,
Item.Checksize);
end;
procedure TEasyViewItem.PaintFocusRect(Item: TEasyItem; Column: TEasyColumn; const Caption: WideString; RectArray: TEasyRectArrayObject; ACanvas: TCanvas);
var
AbsIndex: Integer;
LocalFocusRect: TRect;
begin
if not FullRowSelect then
begin
AbsIndex := ValidateColumnIndex(Column);
// Only draw the focus rect if the window has focus
if Item.Focused and OwnerListview.Focused and ((AbsIndex < 1)) then
begin
if OwnerListview.Selection.FullCellPaint then
begin
LocalFocusRect := Item.DisplayRect;
UnionRect(LocalFocusRect, LocalFocusRect, RectArray.FullFocusSelRect);
if (OwnerListview.View = elsReport) and (OwnerListview.Header.Columns.Count > 0) then
begin
LocalFocusRect.Left := OwnerListview.Header.Columns[0].DisplayRect.Left;
LocalFocusRect.Right := LocalFocusRect.Left + OwnerListview.Header.Columns[0].Width;
end
end else
begin
LocalFocusRect := RectArray.FullFocusSelRect;
if OwnerListview.Selection.FullItemPaint then
UnionRect(LocalFocusRect, LocalFocusRect, RectArray.IconRect);
end;
ACanvas.Brush.Color := OwnerListview.Color;
ACanvas.Font.Color := clBlack;
DrawFocusRect(ACanvas.Handle, LocalFocusRect);
end
end
end;
procedure TEasyViewItem.PaintAlphaBlendedGradientFill(ACanvas: TCanvas;
GradientBottom: TColor; GradientTop: TColor; LocalSelRect: TRect;
LocalSelWindowClippedRect: TRect; LocalSelClippedRect: TRect);
var
Bits: TBitmap;
GlassBits: TBitmap;
begin
Bits := TBitmap.Create;
GlassBits := TBitmap.Create;
try
GlassBits.Width := RectWidth(LocalSelWindowClippedRect);
GlassBits.Height := RectHeight(LocalSelWindowClippedRect);
GlassBits.PixelFormat := pf32Bit;
Bits.Width := GlassBits.Width;
Bits.Height := GlassBits.Height;
Bits.PixelFormat := pf32Bit;
BitBlt(Bits.Canvas.Handle, 0, 0, Bits.Width, Bits.Height,
ACanvas.Handle, LocalSelWindowClippedRect.Left, LocalSelWindowClippedRect.Top, SRCCOPY);
FillGradient(0, 0, GlassBits.Width, GlassBits.Height, GradientTop, GradientBottom,
0, GlassBits.Height, GlassBits.Canvas);
BlendBits(GlassBits, Bits, 80, 20, OwnerListview.Selection.BlurAlphaBkGnd);
BitBlt(ACanvas.Handle, LocalSelRect.Left, LocalSelWindowClippedRect.Top,
Bits.Width, Bits.Height, Bits.Canvas.Handle, 0, 0, SRCCOPY);
finally
GlassBits.Free;
Bits.Free;
end;
end;
procedure TEasyViewItem.PaintImage(Item: TEasyItem; Column: TEasyColumn; const Caption: WideString; RectArray: TEasyRectArrayObject; ImageSize: TEasyImageSize; ACanvas: TCanvas);
var
rgbBk, rgbFg: Longword;
fStyle: Integer;
OverlayIndex, ImageIndex, PositionIndex, AbsIndex, StateImageIndex: Integer;
Images, StateImages: TCustomImageList;
DoDefault, IsCustom: Boolean;
Rgn: HRgn;
TmpBits: TBitmap;
R: TRect;
W, H, Scale: Double;
begin
TestAndClipImage(ACanvas, RectArray, Rgn);
try
if Assigned(Column) then
begin
AbsIndex := Column.Index;
PositionIndex := Column.Position
end else
begin
AbsIndex := 0;
PositionIndex := 0;
end;
DoDefault := True;
Images := GetImageList(Column, Item, eikNormal);
if OwnerListview.IsThumbnailView then
begin
InflateRect(RectArray.IconRect, -Item.Border, -Item.Border);
Item.ThumbnailDraw(ACanvas, RectArray.IconRect, AlphaBlender, DoDefault);
end;
// If not using the thumbnail then get the information for the ImageList Indexes
if DoDefault then
begin
Item.ImageDrawIsCustom(Column, IsCustom);
if IsCustom then
begin
Item.ImageDraw(Column, ACanvas, RectArray, AlphaBlender);
end else
if DoDefault then
begin
ImageIndex := Item.ImageIndexes[AbsIndex];
OverlayIndex := Item.ImageOverlayIndexes[AbsIndex];
if PaintStateImage then
begin
StateImageIndex := Item.StateImageIndexes[AbsIndex];
StateImages := GetImageList(Column, Item, eikState);
if Assigned(StateImages) and (StateImageIndex > -1) then
begin
// Set up a normal Imagelist icon
fStyle := ILD_TRANSPARENT;
rgbBk := CLR_NONE;
rgbFg := CLR_NONE;
RectArray.StateRect.Left := RectArray.StateRect.Left + (RectWidth(RectArray.StateRect) - Images.Width) div 2;
RectArray.StateRect.Top := RectArray.StateRect.Top + (RectHeight(RectArray.StateRect) - Images.Height) div 2;
ImageList_DrawEx(StateImages.Handle, StateImageIndex, ACanvas.Handle, RectArray.StateRect.Left,
RectArray.StateRect.Top, 0, 0, rgbBk, rgbFg, fStyle);
end
end;
if Assigned(Images) and (ImageIndex > -1) then
begin
// Set up a normal Imagelist icon
fStyle := ILD_TRANSPARENT;
rgbBk := CLR_NONE;
rgbFg := CLR_NONE;
// Set up to blend the Imagelist icon
// The param is to allow Thumbnail view to use this paint method and not blend
// the image
if OwnerListview.Selection.BlendIcon and
(((OwnerListview.Focused or Item.OwnerListview.Selection.PopupMode) and Item.Selected) or Item.Hilighted and
(PositionIndex < 1)) then
begin
fStyle := fStyle or ILD_SELECTED;
if OwnerListview.Selection.ForceDefaultBlend then
rgbFg := CLR_DEFAULT
else
rgbFg := ColorToRGB(OwnerListview.Selection.Color)
end;
if not Item.Enabled or Item.Cut or Item.Ghosted or Item.OwnerListview.ShowInactive then
begin
fStyle := fStyle or ILD_SELECTED;
rgbFg := ColorToRGB(OwnerListview.DisabledBlendColor)
end;
if OverlayIndex > -1 then
fStyle := FStyle or IndexToOverLayMask(OverlayIndex);
if (RectWidth(RectArray.IconRect) < Images.Width) or (RectHeight(RectArray.IconRect) < Images.Height) then
begin
if (Images.Width > 0) and (Images.Height > 0) then
begin
TmpBits := TBitmap.Create;
try
TmpBits.PixelFormat := pf32Bit;
TmpBits.Width := Images.Width;
TmpBits.Height := Images.Height;
ImageList_DrawEx(Images.Handle, ImageIndex, TmpBits.Canvas.Handle, 0, 0, 0, 0, rgbBk, rgbFg, fStyle);
W := RectWidth(RectArray.IconRect)/Images.Width;
H := RectHeight(RectArray.IconRect)/Images.Height;
if W > H then
Scale := H
else
Scale := W;
R := Rect(0, 0, Round(Images.Width*Scale), Round(Images.Height*Scale));
StretchBlt(ACanvas.Handle,
RectArray.IconRect.Left + ((RectWidth(RectArray.IconRect) - RectWidth(R)) div 2),
RectArray.IconRect.Top + ((RectHeight(RectArray.IconRect) - RectHeight(R)) div 2),
RectWidth(R),
RectHeight(R),
TmpBits.Canvas.Handle,
0, 0,
TmpBits.Width,
TmpBits.Height,
SRCCOPY);
finally
TmpBits.Free
end
end
end else
begin
RectArray.IconRect.Left := RectArray.IconRect.Left + (RectWidth(RectArray.IconRect) - Images.Width) div 2;
RectArray.IconRect.Top := RectArray.IconRect.Top + (RectHeight(RectArray.IconRect) - Images.Height) div 2;
ImageList_DrawEx(Images.Handle, ImageIndex, ACanvas.Handle, RectArray.IconRect.Left,
RectArray.IconRect.Top, 0, 0, rgbBk, rgbFg, fStyle);
end
end
end
end
finally
TestAndUnClipImage(ACanvas, RectArray, Rgn);
end
end;
procedure TEasyViewItem.PaintNonAlphaBlendedSelection(ACanvas: TCanvas;
LocalSelRect: TRect);
begin
// Not AlphaBlended is much easier
if OwnerListview.Selection.RoundRect then
RoundRect(ACanvas.Handle,
LocalSelRect.Left,
LocalSelRect.Top,
LocalSelRect.Right,
LocalSelRect.Bottom,
OwnerListview.Selection.RoundRectRadius,
OwnerListview.Selection.RoundRectRadius)
else
Rectangle(ACanvas.Handle,
LocalSelRect.Left,
LocalSelRect.Top,
LocalSelRect.Right,
LocalSelRect.Bottom);
end;
procedure TEasyViewItem.PaintSelectionRect(Item: TEasyItem; Column: TEasyColumn; const Caption: WideString; RectArray: TEasyRectArrayObject; ACanvas: TCanvas; ViewportClipRect: TRect; ForceSelectionRectDraw: Boolean);
var
Rgn: HRGN;
// All these rectangles are necessary because the AlphaBlend routine does not respect DC origins and clipping regions.
LocalSelRect, // The true Viewpoint Rectangle of the Selection Rectangle, including the Header area if applicable
LocalSelWindowClippedRect, // The true Viewpoint Rectangle of the Selection Rectangle, Clipped to the current Physical Window Coordinates
LocalSelClippedRect, // The true Viewpoint Rectangle of the Selection Rectangle, excluding the Header area if applicable
HeaderClippedWindowRect: TRect; // Rectangle containing the Selection Rectangle that has been translated to Physical Window Coordinates and the Header area clipped off it if necesasry. This rectangle is also clipped to the ClientWindow rectangle
AlphaColor,
GradientTop,
GradientBottom: TColor;
DoDraw: Boolean;
begin
DoDraw := Item.Selected or Item.Hilighted;
if DoDraw and Assigned(Column) then
DoDraw := (Column.Index < 1);
if (DoDraw and not FullRowSelect) or ForceSelectionRectDraw then
begin
Rgn := 0;
// If the Window control is not focused show the selection with innactive colors
if OwnerListview.Focused or Item.Hilighted and not Item.OwnerListview.ShowInactive or Item.OwnerListview.Selection.PopupMode then
begin
ACanvas.Font.Color := OwnerListview.Selection.TextColor;
if (Item <> OwnerListview.Selection.FocusedItem) or not OwnerListview.Selection.UseFocusRect then
ACanvas.Pen.Color := OwnerListview.Selection.BorderColor
else
ACanvas.Pen.Color := clLtGray;
ACanvas.Brush.Color := OwnerListview.Selection.Color;
AlphaColor := OwnerListview.Selection.Color;
GradientTop := OwnerListview.Selection.GradientColorTop;
GradientBottom := OwnerListview.Selection.GradientColorBottom;
end else
begin
ACanvas.Font.Color := OwnerListview.Selection.InactiveTextColor;
ACanvas.Pen.Color := OwnerListview.Selection.InactiveBorderColor;
ACanvas.Brush.Color := OwnerListview.Selection.InactiveColor;
AlphaColor := OwnerListview.Selection.InactiveColor;
GradientTop := OwnerListview.Color;
GradientBottom := OwnerListview.Selection.InactiveColor
end;
if OwnerListview.Selection.GroupSelections and (OwnerListview.View = elsReport) and (Item.Selected or Item.Hilighted or Item.Selected) then
begin
SetRect(LocalSelRect, 0, 0, 0, 0);
if Assigned(Item.SelectionGroup) then
begin
if Item.Hilighted then
begin
LocalSelRect := Item.DisplayRect;
if not ((OwnerListview.Selection.FullItemPaint) or (OwnerListview.Selection.FullCellPaint) or (OwnerListview.Selection.FullItemPaint)) then
LocalSelRect.Left := RectArray.TextRect.Left
end else
begin
if Item.SelectionGroup.FirstItem = Item then
begin
LocalSelRect := Item.SelectionGroup.DisplayRect;
if not(OwnerListview.Selection.FullItemPaint or OwnerListview.Selection.FullCellPaint) then
LocalSelRect.Left := RectArray.SelectionRect.Left
end
end
end else
begin
LocalSelRect := Item.DisplayRect;
if not(OwnerListview.Selection.FullItemPaint or OwnerListview.Selection.FullCellPaint) then
LocalSelRect.Left := RectArray.SelectionRect.Left
end
end else
if FullRowSelect and (Item.Selected or Item.Hilighted or Item.Selected) then
begin
// If full row select then the First Column paints the entire row
if OwnerListview.Selection.FullCellPaint then
LocalSelRect := Item.DisplayRect
else begin
LocalSelRect := Item.DisplayRect;
if not OwnerListview.Selection.FullItemPaint then
LocalSelRect.Left := RectArray.SelectionRect.Left;
end
end else
begin
if Item.Focused and (OwnerListview.Focused or Item.OwnerListview.Selection.PopupMode) then
begin
if OwnerListview.Selection.FullCellPaint then
begin
LocalSelRect := Item.DisplayRect;
UnionRect(LocalSelRect, LocalSelRect, RectArray.FullFocusSelRect);
if (OwnerListview.View = elsReport) and (OwnerListview.Header.Columns.Count > 0) then
begin
LocalSelRect.Left := OwnerListview.Header.Columns[0].DisplayRect.Left;
LocalSelRect.Right := LocalSelRect.Left + OwnerListview.Header.Columns[0].Width;
end
end else
begin
LocalSelRect := RectArray.FullFocusSelRect;
// Cover the Icon if FullItemPaint
if OwnerListview.Selection.FullItemPaint then
UnionRect(LocalSelRect, LocalSelRect, RectArray.IconRect);
end
end else
begin
if OwnerListview.Selection.FullCellPaint then
begin
LocalSelRect := Item.DisplayRect;
if (OwnerListview.View = elsReport) and (OwnerListview.Header.Positions.Count > 0) then
begin
LocalSelRect.Left := OwnerListview.Header.Columns[0].DisplayRect.Left;
LocalSelRect.Right := LocalSelRect.Left + OwnerListview.Header.Columns[0].Width;
end
end else
begin
LocalSelRect := RectArray.SelectionRect;
// Cover the Icon if FullItemPaint
if OwnerListview.Selection.FullItemPaint then
UnionRect(LocalSelRect, LocalSelRect, RectArray.IconRect);
end
end
end;
// LocalSelRect is now set up
AfterSelRectCalc(Item, Column, Caption, LocalSelRect);
// Clip out the header from the Selection Rectangle, don't need to account for Header
// as the DC is offset to take it into account
LocalSelClippedRect := LocalSelRect;
HeaderClippedWindowRect := OwnerListview.Scrollbars.MapViewRectToWindowRect(LocalSelClippedRect);
LocalSelWindowClippedRect := HeaderClippedWindowRect;
if HeaderClippedWindowRect.Top < OwnerListview.Header.RuntimeHeight then
begin
HeaderClippedWindowRect.Top := OwnerListview.Header.RuntimeHeight;
// Make it a 0 height rect if it is an improper rect after adjustment
if HeaderClippedWindowRect.Top > HeaderClippedWindowRect.Bottom then
HeaderClippedWindowRect.Top := HeaderClippedWindowRect.Bottom;
LocalSelClippedRect := OwnerListview.Scrollbars.MapViewRectToWindowRect(HeaderClippedWindowRect);
end;
IntersectRect(LocalSelWindowClippedRect, LocalSelWindowClippedRect, OwnerListview.ClientRect);
LocalSelWindowClippedRect := OwnerListview.Scrollbars.MapWindowRectToViewRect(LocalSelWindowClippedRect);
IntersectRect(HeaderClippedWindowRect, HeaderClippedWindowRect, OwnerListview.ClientRect);
// Stop right side from having rounded corners if extends past right edge of window,
// but don't go past the actual width
Inc(LocalSelWindowClippedRect.Right, OwnerListview.Selection.RoundRectRadius);
if LocalSelWindowClippedRect.Right > LocalSelRect.Right then
LocalSelWindowClippedRect.Right := LocalSelRect.Right;
if not IsRectEmpty(LocalSelRect) then
begin
if OwnerListview.Selection.Gradient and not OwnerListview.Selection.AlphaBlend then
begin
if RectHeight(LocalSelWindowClippedRect) > 0 then
begin
FillGradient(LocalSelRect.Left, LocalSelWindowClippedRect.Top, LocalSelWindowClippedRect.Right,
LocalSelWindowClippedRect.Bottom, GradientTop, GradientBottom,
LocalSelWindowClippedRect.Top, LocalSelWindowClippedRect.Bottom, ACanvas);
ACanvas.FrameRect(LocalSelRect);
end
end else
if HasMMX and OwnerListview.Selection.AlphaBlend then
begin
if OwnerListview.Selection.RoundRect then
PaintAlphaBlendedRoundRect(ACanvas, AlphaColor, GradientBottom, GradientTop, LocalSelWindowClippedRect, Rgn)
else begin
if OwnerListview.Selection.Gradient then
PaintAlphaBlendedGradientFill(ACanvas, GradientBottom, GradientTop, LocalSelRect, LocalSelWindowClippedRect, LocalSelClippedRect)
else
PaintAlphaBlendedSelection(ACanvas, AlphaColor, HeaderClippedWindowRect, LocalSelRect);
end
end else
PaintNonAlphaBlendedSelection(ACanvas, LocalSelRect);
end
end
end;
procedure TEasyViewItem.PaintText(Item: TEasyItem; Column: TEasyColumn; const Caption: WideString; RectArray: TEasyRectArrayObject; ACanvas: TCanvas; LinesToDraw: Integer);
var
DrawTextFlags: TCommonDrawTextWFlags;
AbsIndex: Integer;
Hilightable: Boolean;
begin
if not IsRectEmpty(RectArray.TextRect) then
begin
AbsIndex := ValidateColumnIndex(Column);
Hilightable := (Item.Selected or Item.Hilighted) and ((AbsIndex = 0) or (FullRowSelect or OwnerListview.Selection.GroupSelections));
LoadTextFont(Item, AbsIndex, ACanvas, Hilightable);
DrawTextFlags := [dtEndEllipsis];
if LinesToDraw = 1 then
Include(DrawTextFlags, dtSingleLine);
case PaintTextAlignment(Item, Column) of
taLeftJustify: Include(DrawTextFlags, dtLeft);
taRightJustify: Include(DrawTextFlags, dtRight);
taCenter: Include(DrawTextFlags, dtCenter);
end;
case PaintTextVAlignment(Item, Column) of
cvaTop: Include(DrawTextFlags, dtTop);
cvaCenter: Include(DrawTextFlags, dtVCenter);
cvaBottom: Include(DrawTextFlags, dtBottom);
end;
OwnerListview.ClipHeader(ACanvas, False);
if Item.Focused and (OwnerListview.Focused or Item.OwnerListview.Selection.PopupMode) then
DrawTextWEx(ACanvas.Handle, Caption, RectArray.TextRect, DrawTextFlags, LinesToDraw)
else
DrawTextWEx(ACanvas.Handle, Caption, RectArray.TextRect, DrawTextFlags, LinesToDraw)
end
end;
function TEasyViewItem.PaintTextAlignment(Item: TEasyItem; Column: TEasyColumn): TAlignment;
begin
Result := taCenter
end;
function TEasyViewItem.PaintTextLineCount(Item: TEasyItem; Column: TEasyColumn): Integer;
begin
Result := 2
end;
function TEasyViewItem.PaintTextVAlignment(Item: TEasyItem; Column: TEasyColumn): TCommonVAlignment;
begin
Result := cvaTop
end;
function TEasyViewItem.PtInRect(Item: TEasyItem; Column: TEasyColumn;
Pt: TPoint): Integer;
// Compares the passed point with the rectangle of the item.
//
// If Rect > Pt then Result = 1
// If Rect < Pt then Result = -1
// If Rect = Pt (i.e. the point is within the rect) then Result = 0
//
// This code works if the layout of the items is vertical with item numbering
// increasing from Left to Right in each Row
var
CellRect: TRect;
begin
CellRect := Item.DisplayRect;
if Pt.y < CellRect.Top then
Result := 1
else
if Pt.y > CellRect.Bottom then
Result := -1
else
if Pt.x < CellRect.Left then
begin
Result := 1
end
else
if Pt.x > CellRect.Right then
Result := -1
else
Result := 0
end;
procedure TEasyViewItem.ReSizeRectArray(
var RectArray: TEasyRectArrayObjectArray);
var
OldLen, i: Integer;
begin
if Length(RectArray) < OwnerListview.Header.Positions.Count then
begin
OldLen := Length(RectArray);
SetLength(RectArray, OwnerListview.Header.Positions.Count);
for i := OldLen to OwnerListview.Header.Positions.Count - 1 do
FillChar(RectArray[i], SizeOf(RectArray[i]), #0);
end else
if Length(RectArray) > OwnerListview.Header.Positions.Count then
SetLength(RectArray, OwnerListview.Header.Positions.Count);
if Length(RectArray) = 0 then
begin
SetLength(RectArray, 1);
FillChar(RectArray[0], SizeOf(RectArray[0]), #0);
end
end;
procedure TEasyViewItem.TestAndClipImage(ACanvas: TCanvas; RectArray: TEasyRectArrayObject; var Rgn: HRgn);
var
R, ImageRect: TRect;
begin
Rgn := 0;
UnionRect(ImageRect, RectArray.IconRect, RectArray.StateRect);
if not ContainsRect(RectArray.BoundsRect, ImageRect) then
begin
// I was hoping that IntersectClipRect would set a clipping region when
// I clipped the header in the main control. Then I would get it here and
// resort it later. Unfortunately it does not and GetClipRgn returns 0 so
// I have to call ClipHeader explicitly.
GetClipRgn(ACanvas.Handle, Rgn);
IntersectRect(R, ImageRect, RectArray.BoundsRect);
IntersectClipRect(ACanvas.Handle, R.Left, R.Top, R.Right, R.Bottom);
OwnerListview.ClipHeader(ACanvas, False)
end;
end;
procedure TEasyViewItem.TestAndUnClipImage(ACanvas: TCanvas; RectArray: TEasyRectArrayObject; Rgn: HRgn);
var
ImageRect: TRect;
begin
UnionRect(ImageRect, RectArray.IconRect, RectArray.StateRect);
if not ContainsRect(RectArray.BoundsRect, ImageRect) then
begin
if Rgn <> 0 then
begin
SelectClipRgn(ACanvas.Handle, Rgn);
DeleteObject(Rgn)
end
else begin
SelectClipRgn(ACanvas.Handle, 0);
OwnerListview.ClipHeader(ACanvas, False)
end
end;
end;
function TEasyHeader.GetViewWidth: Integer;
begin
if Positions.Count > 0 then
Result := Positions[Positions.Count - 1].DisplayRect.Right
else
Result := 0
end;
{ TEasyDefaultCellSize }
constructor TEasyCellSize.Create(AnOwner: TCustomEasyListview);
begin
inherited Create(AnOwner);
FWidth := 75;
FHeight := 75;
FAutoSizeHeight := 75;
FAutoSizeWidth := 75;
end;
function TEasyCellSize.GetHeight: Integer;
begin
if AutoSize then
Result := FAutoSizeHeight
else begin
Result := FHeight;
if Result < 1 then
Result := 1
end
end;
function TEasyCellSize.GetWidth: Integer;
begin
if AutoSize then
Result := FAutoSizeWidth
else begin
Result := FWidth;
if Result < 1 then
Result := 1
end
end;
procedure TEasyCellSize.Assign(Source: TPersistent);
begin
if Source is TEasyCellSize then
begin
FHeight := TEasyCellSize(Source).Height;
FWidth := TEasyCellSize(Source).Width;
// OwnerListview.Groups.Rebuild;
end;
end;
procedure TEasyCellSize.SetAutoSize(const Value: Boolean);
begin
if Value <> FAutoSize then
begin
FAutoSize := Value;
if not FAutoSize then
begin
FAutoSizeWidth := FWidth;
FAutoSizeHeight := FHeight
end;
OwnerListview.Groups.Rebuild;
end
end;
procedure TEasyCellSize.SetSize(AWidth, AHeight: Integer);
begin
if AWidth < 0 then AWidth := 0;
if AHeight < 0 then AHeight := 0;
if AutoSize then
begin
if (AWidth <> FWidth) or (AHeight <> FHeight) then
begin
FAutoSizeWidth := AWidth;
FAutoSizeHeight := AHeight;
end;
end else
begin
if (AWidth <> FWidth) or (AHeight <> FHeight) then
begin
FWidth := AWidth;
FHeight := AHeight;
end;
OwnerListview.Groups.Rebuild;
end
end;
procedure TEasyCellSize.SetHeight(Value: Integer);
begin
if AutoSize then
SetSize(FAutoSizeWidth, Value)
else
SetSize(FWidth, Value);
end;
procedure TEasyCellSize.SetWidth(Value: Integer);
begin
if AutoSize then
SetSize(Value, FAutoSizeHeight)
else
SetSize(Value, FHeight);
end;
{ TEasyIconItemView}
function TEasyViewIconItem.ExpandIconR(Item: TEasyItem; RectArray: TEasyRectArrayObject; SelectType: TEasySelectHitType): TRect;
begin
Result := RectArray.IconRect;
end;
function TEasyViewIconItem.OverlappedFocus: Boolean;
begin
Result:= True
end;
function TEasyViewIconItem.PaintImageSize: TEasyImageSize;
begin
Result := eisLarge
end;
function TEasyViewIconItem.PaintTextLineCount(Item: TEasyItem;
Column: TEasyColumn): Integer;
begin
if Item.Focused and OwnerListview.Focused then
Result := -1
else
Result := 2
end;
procedure TEasyViewIconItem.AfterSelRectCalc(Item: TEasyItem;
Column: TEasyColumn; const Caption: WideString; var LocalSelRect: TRect);
begin
if OwnerListview.Selection.FullCellPaint then
InflateRect(LocalSelRect, -2, -2)
end;
procedure TEasyViewIconItem.ItemRectArray(Item: TEasyItem; Column: TEasyColumn; ACanvas: TCanvas; const Caption: WideString; var RectArray: TEasyRectArrayObject);
var
ImageW, ImageH, Left: Integer;
DrawTextFlags: TCommonDrawTextWFlags;
R: TRect;
PositionIndex, AbsIndex: Integer;
ACaption: WideString;
begin
if Assigned(Item) then
begin
if not Item.Initialized then
Item.Initialized := True;
if Assigned(Column) then
begin
AbsIndex := Column.Index;
PositionIndex := Column.Position
end else
begin
AbsIndex := 0;
PositionIndex := 0
end;
if PositionIndex > -1 then
begin
FillChar(RectArray, SizeOf(RectArray), #0);
GetImageSize(Item, Column, ImageW, ImageH, eikNormal);
// Calcuate the Bounds of the Cell that is allowed to be drawn in
// **********
RectArray.BoundsRect := Item.DisplayRect;
Inc(RectArray.BoundsRect.Left);
// Calculate where the Icon is positioned
// **********
// Center Icon horziontally and a few pixels from the top of the cell
Left := RectArray.BoundsRect.Left + ((RectWidth(RectArray.BoundsRect) - ImageW) div 2);
RectArray.IconRect := Rect(Left,
RectArray.BoundsRect.Top + 2,
Left + ImageW,
RectArray.BoundsRect.Top + 2 + ImageH);
// Some margin between the Icon and the Text that belongs to the Icon Rect
Inc(RectArray.IconRect.Bottom, 4);
// Calculate area that the Checkbox may be drawn
// **********
if Item.CheckType <> ectNone then
begin
R := Checks.Bound[Item.Checksize];
RectArray.CheckRect.Top := RectArray.IconRect.Bottom + 1; // This looks better than centered
RectArray.CheckRect.Left := RectArray.BoundsRect.Left + Item.CheckIndent;
RectArray.CheckRect.Bottom := RectArray.CheckRect.Top + R.Bottom;
RectArray.CheckRect.Right := RectArray.CheckRect.Left + R.Right;
end else
begin
RectArray.CheckRect.Top := RectArray.IconRect.Bottom;
RectArray.CheckRect.Left := RectArray.BoundsRect.Left;
RectArray.CheckRect.Bottom := RectArray.BoundsRect.Bottom;
RectArray.CheckRect.Right := RectArray.BoundsRect.Left;
end;
// Calculate area that the label may be drawn
// **********
// The Label Rect is the remaining area between the Icon Rect and the Bottom
// of the Bounds Rect
RectArray.LabelRect := Rect(RectArray.CheckRect.Right,
RectArray.IconRect.Bottom + 1,
RectArray.BoundsRect.Right,
RectArray.BoundsRect.Bottom);
// Calculate the portion of the Label Rect that the current Text will use
// **********
RectArray.TextRect := RectArray.LabelRect;
RectArray.FullTextRect := RectArray.LabelRect;
// Leave room for a small border between edge of the selection rect and text
InflateRect(RectArray.TextRect, -2, -2);
InflateRect(RectArray.FullTextRect, -2, -2);
DrawTextFlags := [dtCalcRect, dtCalcRectAlign];
DrawTextFlags := DrawTextFlags + [dtCenter];
case PaintTextAlignment(Item, Column) of
taCenter: DrawTextFlags := DrawTextFlags + [dtCenter];
taLeftJustify: DrawTextFlags := DrawTextFlags + [dtLeft];
taRightJustify: DrawTextFlags := DrawTextFlags + [dtRight];
end;
case PaintTextVAlignment(Item, Column) of
cvaCenter: DrawTextFlags := DrawTextFlags + [dtVCenter];
cvaTop: DrawTextFlags := DrawTextFlags + [dtTop];
cvaBottom: DrawTextFlags := DrawTextFlags + [dtBottom];
end;
if Assigned(OwnerListview.ScratchCanvas) then
begin
ACaption := Item.Captions[AbsIndex];
if ACaption = '' then
ACaption := ' ';
LoadTextFont(Item, PositionIndex, OwnerListview.ScratchCanvas, Item.Selected);
DrawTextWEx(OwnerListview.ScratchCanvas.Handle, ACaption, RectArray.FullTextRect, DrawTextFlags, -1);
DrawTextWEx(OwnerListview.ScratchCanvas.Handle, ACaption, RectArray.TextRect, DrawTextFlags, 2);
end;
// Calculate Selection rectangle paint box
// **********
RectArray.SelectionRect := RectArray.TextRect;
InflateRect(RectArray.SelectionRect, 2, 2);
RectArray.FullFocusSelRect := RectArray.FullTextRect;
InflateRect(RectArray.FullFocusSelRect, 2, 2);
UnionRect(RectArray.ClickselectBoundsRect, RectArray.IconRect, RectArray.TextRect);
RectArray.DragSelectBoundsRect := RectArray.ClickselectBoundsRect;
UnionRect(RectArray.FocusChangeInvalidRect, RectArray.IconRect, RectArray.FullFocusSelRect);
RectArray.EditRect := RectArray.FullTextRect;
end
end
end;
procedure TEasyViewIconItem.PaintBefore(Item: TEasyItem; Column: TEasyColumn; const Caption: WideString; ACanvas: TCanvas; RectArray: TEasyRectArrayObject; var Handled: Boolean);
begin
// Skip inherited
end;
{ TEasySmallIconItemView }
function TEasyViewSmallIconItem.CalculateDisplayRect(Item: TEasyItem;
Column: TEasyColumn): TRect;
begin
Result := Item.DisplayRect
end;
function TEasyViewSmallIconItem.ExpandIconR(Item: TEasyItem; RectArray: TEasyRectArrayObject; SelectType: TEasySelectHitType): TRect;
begin
Result := Rect(0, 0, 0, 0)
end;
function TEasyViewSmallIconItem.ExpandTextR(Item: TEasyItem; RectArray: TEasyRectArrayObject; SelectType: TEasySelectHitType): TRect;
begin
UnionRect(Result, RectArray.IconRect, RectArray.TextRect);
Result.Top := RectArray.BoundsRect.Top;
Result.Bottom := RectArray.BoundsRect.Bottom;
end;
procedure TEasyViewSmallIconItem.ItemRectArray(Item: TEasyItem; Column: TEasyColumn; ACanvas: TCanvas; const Caption: WideString; var RectArray: TEasyRectArrayObject);
var
TextSize: TSize;
SelectW, BoundsH, CheckH: Integer;
CheckType: TEasyCheckType;
R: TRect;
CheckIndent, CaptionIndent, Checksize, ImageIndex, ImageIndent, PositionIndex, AbsIndex, StateImageIndex: Integer;
ImageW, ImageH: Integer;
ACaption: WideString;
begin
if Assigned(Item) then
begin
// This is faster
if not Item.Initialized then
Item.Initialized := True;
if Assigned(Column) then
begin
AbsIndex := Column.Index;
PositionIndex := Column.Position
end else
begin
AbsIndex := 0;
PositionIndex := 0
end;
if PositionIndex > -1 then
begin
FillChar(RectArray, SizeOf(RectArray), #0);
// Calcuate the Bounds of the Cell that is allowed to be drawn in
// **********
// Report view is based on this class so take care if that possibility too.
if not Assigned(Column) and (OwnerListview.Header.Positions.Count > 0) then
RectArray.BoundsRect := CalculateDisplayRect(Item, OwnerListview.Header.Positions[0])
else
RectArray.BoundsRect := CalculateDisplayRect(Item, Column);
CheckType := Item.CheckType;
Checksize := Item.Checksize;
ImageIndex := Item.ImageIndexes[AbsIndex];
StateImageIndex := Item.StateImageIndexes[AbsIndex];
CaptionIndent := Item.CaptionIndent;
CheckIndent := Item.CheckIndent;
ImageIndent := Item.ImageIndent;
// Calculate the space necded for the CheckBox, if enabled
if (CheckType <> ectNone) and (AbsIndex = 0) then
begin
R := Checks.Bound[Checksize];
BoundsH := RectHeight(RectArray.BoundsRect);
CheckH := RectHeight(R);
RectArray.CheckRect := Rect(RectArray.BoundsRect.Left + CheckIndent,
RectArray.BoundsRect.Top + (BoundsH - CheckH) div 2,
RectArray.BoundsRect.Left + CheckIndent + R.Right,
RectArray.BoundsRect.Top + CheckH + (BoundsH - CheckH) div 2)
end else
RectArray.CheckRect := Rect(RectArray.BoundsRect.Left,
RectArray.BoundsRect.Top,
RectArray.BoundsRect.Left,
RectArray.BoundsRect.Bottom); // Check Rect has a width of 0
// Set the rectangle of the Image if avaialable, note Bitmap is not supported
if PaintStateImage and ((StateImageIndex > -1) or (GetImageList(Column, Item, eikState) <> nil)) then
begin
GetImageSize(Item, Column, ImageW, ImageH, eikState);
RectArray.StateRect.Top := RectArray.BoundsRect.Top + (RectHeight(RectArray.BoundsRect) - ImageH) div 2;
RectArray.StateRect.Left := RectArray.CheckRect.Right + ImageIndent;
// State Images must be the same size as the main image
RectArray.StateRect.Bottom := RectArray.StateRect.Top + ImageH;
RectArray.StateRect.Right := RectArray.StateRect.Left + ImageW;
end else
RectArray.StateRect := Rect(RectArray.CheckRect.Right,
RectArray.CheckRect.Top,
RectArray.CheckRect.Right,
RectArray.CheckRect.Bottom);
// Set the rectangle of the Image if avaialable, note Bitmap is not supported
if (ImageIndex > -1) then
begin
GetImageSize(Item, Column, ImageW, ImageH, eikNormal);
RectArray.IconRect.Top := RectArray.BoundsRect.Top + (RectHeight(RectArray.BoundsRect) - ImageH) div 2;
RectArray.IconRect.Left := RectArray.StateRect.Right + ImageIndent;
RectArray.IconRect.Bottom := RectArray.IconRect.Top + ImageH;
RectArray.IconRect.Right := RectArray.IconRect.Left + ImageW;
end else
RectArray.IconRect := Rect(RectArray.StateRect.Right,
RectArray.StateRect.Top,
RectArray.StateRect.Right,
RectArray.StateRect.Bottom);
// Calculate where the Label is positioned
// **********
// The Cell may be narrow enough that only the image will fit. If that is
// the case leave the LabelR a Zero sized rect
if RectArray.BoundsRect.Right - 1 > RectArray.IconRect.Right + CaptionIndent {+ (2*LABEL_MARGIN) }then
RectArray.LabelRect := Rect(RectArray.IconRect.Right + CaptionIndent {+ LABEL_MARGIN},
RectArray.BoundsRect.Top,
RectArray.BoundsRect.Right {- 2*LABEL_MARGIN},
RectArray.BoundsRect.Bottom);
// Calculate Text based rectangles
// **********
if Assigned(OwnerListview.ScratchCanvas) then
begin
LoadTextFont(Item, PositionIndex, OwnerListview.ScratchCanvas, Item.Selected);
ACaption := Item.Captions[AbsIndex];
if ACaption = '' then
ACaption := ' ';
TextSize := TextExtentW(ACaption, OwnerListview.ScratchCanvas);
end else
begin
TextSize.cx := 0;
TextSize.cy := 0
end;
// Calculate Text Rectangle
// **********
RectArray.TextRect := RectArray.LabelRect;
InflateRect(RectArray.TextRect, -2, -2);
// Center it horz and vert to start with
// This will also clip the text rect to to size of the Label if necessary
RectArray.TextRect := CenterRectInRect(RectArray.TextRect, Rect(0, 0, TextSize.cx, TextSize.cy));
case PaintTextAlignment(Item, Column) of
taLeftJustify: OffsetRect(RectArray.TextRect, -(RectArray.TextRect.Left - RectArray.LabelRect.Left), 0);
taRightJustify: OffsetRect(RectArray.TextRect, (RectArray.LabelRect.Right - RectArray.TextRect.Right - 8), 0);
end;
// Calculate Focus Text Rectangle
// **********
RectArray.FullTextRect := RectArray.TextRect;
// Calculate Selection Rectangle
// **********
RectArray.SelectionRect := RectArray.TextRect;
InflateRect(RectArray.SelectionRect, 2, 2);
RectArray.FullFocusSelRect := RectArray.SelectionRect;
// Calculate Rectangle used for Clickselecting
// **********
UnionRect(RectArray.ClickselectBoundsRect, RectArray.IconRect, RectArray.SelectionRect);
// Calculate Rectangle used for DragSelecting
// **********
// During a drag selection the hit area is only a fraction of the Click bounds
RectArray.DragSelectBoundsRect := RectArray.ClickselectBoundsRect;
SelectW := Round(RectWidth(RectArray.DragSelectBoundsRect) * SELECTION_OFFSET);
InflateRect(RectArray.DragSelectBoundsRect, -SelectW, 0);
UnionRect(RectArray.FocusChangeInvalidRect, RectArray.IconRect, RectArray.FullTextRect);
RectArray.EditRect := RectArray.FullTextRect;
end
end
end;
procedure TEasyViewSmallIconItem.PaintBefore(Item: TEasyItem; Column: TEasyColumn; const Caption: WideString; ACanvas: TCanvas; RectArray: TEasyRectArrayObject; var Handled: Boolean);
begin
// Don't do default
end;
function TEasyViewSmallIconItem.PaintTextAlignment(Item: TEasyItem; Column: TEasyColumn): TAlignment;
begin
if Assigned(Column) then
Result := Column.Alignment
else
Result := taLeftJustify
end;
function TEasyViewSmallIconItem.PaintTextLineCount(Item: TEasyItem; Column: TEasyColumn): Integer;
begin
Result := 1
end;
function TEasyViewSmallIconItem.PaintTextVAlignment(Item: TEasyItem; Column: TEasyColumn): TCommonVAlignment;
begin
if Assigned(Column) then
Result := Column.VAlignment
else
Result := cvaCenter
end;
{ TEasyDefaultCellSizes }
constructor TEasyCellSizes.Create(AnOwner: TCustomEasyListview);
begin
inherited Create(AnOwner);
FIcon := TEasyCellSizeIcon.Create(AnOwner);
FSmallIcon := TEasyCellSizeSmallIcon.Create(AnOwner);
FThumbnail := TEasyCellSizeThumbnail.Create(AnOwner);
FTile := TEasyCellSizeTile.Create(AnOwner);
FList := TEasyCellSizeList.Create(AnOwner);
FReport := TEasyCellSizeReport.Create(AnOwner);
FFilmStrip := TEasyCellSizeFilmStrip.Create(AnOwner);
FGrid := TEasyCellGrid.Create(AnOwner);
end;
destructor TEasyCellSizes.Destroy;
begin
FreeAndNil(FIcon);
FreeAndNil(FSmallIcon);
FreeAndNil(FThumbnail);
FreeAndNil(FTile);
FreeAndNil(FList);
FreeAndNil(FReport);
FreeAndNil(FFilmStrip);
FreeAndNil(FGrid);
inherited Destroy;
end;
{ TEasyDefaultSmallIconCellSize }
constructor TEasyCellSizeSmallIcon.Create(
AnOwner: TCustomEasyListview);
begin
inherited Create(AnOwner);
FWidth := 200;
FHeight := 17;
FAutoSizeHeight := 17;
FAutoSizeWidth := 200;
end;
{ TEasyDefaultThumbnailCellSize }
constructor TEasyCellSizeThumbnail.Create(
AnOwner: TCustomEasyListview);
begin
inherited Create(AnOwner);
FWidth := 125;
FHeight := 143;
FAutoSizeHeight := 143;
FAutoSizeWidth := 125;
end;
{ TEasyDefaultTileCellSize }
constructor TEasyCellSizeTile.Create(
AnOwner: TCustomEasyListview);
begin
inherited Create(AnOwner);
FWidth := 218;
FHeight := 58;
FAutoSizeHeight := 58;
FAutoSizeWidth := 218;
end;
{ TEasyDefaultListCellSize }
constructor TEasyCellSizeList.Create(
AnOwner: TCustomEasyListview);
begin
inherited Create(AnOwner);
FWidth := 200;
FHeight := 17;
FAutoSizeHeight := 17;
FAutoSizeWidth := 200;
end;
{ TEasyDefaultReportCellSize }
constructor TEasyCellSizeReport.Create(
AnOwner: TCustomEasyListview);
begin
inherited Create(AnOwner);
FWidth := 75;
FHeight := 17;
FAutoSizeHeight := 17;
FAutoSizeWidth := 75;
end;
function TEasyViewTileItem.ExpandIconR(Item: TEasyItem; RectArray: TEasyRectArrayObject; SelectType: TEasySelectHitType): TRect;
begin
Result := Rect(0, 0, 0, 0)
end;
function TEasyViewTileItem.ExpandTextR(Item: TEasyItem; RectArray: TEasyRectArrayObject; SelectType: TEasySelectHitType): TRect;
begin
UnionRect(Result, RectArray.IconRect, RectArray.TextRect);
Result.Top := RectArray.BoundsRect.Top + 2;
Result.Bottom := RectArray.BoundsRect.Bottom - 2;
end;
function TEasyViewTileItem.GetImageList(Column: TEasyColumn; Item: TEasyItem; Image: TEasyImageKind): TCustomImageList;
begin
Result := inherited GetImageList(Column, Item, Image);
if not Assigned(Result) then
Result := Item.ImageList[ValidateColumnIndex(Column), eisLarge]
end;
function TEasyViewTileItem.PaintImageSize: TEasyImageSize;
begin
Result := eisExtraLarge
end;
function TEasyViewTileItem.PaintTextAlignment(Item: TEasyItem;
Column: TEasyColumn): TAlignment;
begin
Result := taLeftJustify
end;
procedure TEasyViewTileItem.AfterSelRectCalc(Item: TEasyItem;
Column: TEasyColumn; const Caption: WideString; var LocalSelRect: TRect);
begin
InflateRect(LocalSelRect, -2, -2)
end;
procedure TEasyViewTileItem.ItemRectArray(Item: TEasyItem; Column: TEasyColumn; ACanvas: TCanvas; const Caption: WideString; var RectArray: TEasyRectArrayObject);
var
ACaption: WideString;
PositionIndex, i, YOffset, ImageW, ImageH, DetailCount: Integer;
DrawTextFlags: TCommonDrawTextWFlags;
R: TRect;
Done: Boolean;
begin
if Assigned(Item) then
begin
if not Item.Initialized then
Item.Initialized := True;
PositionIndex := ValidateColumnIndex(Column);
if PositionIndex > -1 then
begin
FillChar(RectArray, SizeOf(RectArray), #0);
GetImageSize(Item, Column, ImageW, ImageH, eikNormal);
// Get the cell size for the main caption, aligned with the top
case PaintTextAlignment(Item, Column) of
taLeftJustify: Include(DrawTextFlags, dtLeft);
taRightJustify: Include(DrawTextFlags, dtRight);
taCenter: Include(DrawTextFlags, dtCenter);
end;
DrawTextFlags := [dtCalcRect, dtCalcRectAlign, dtEndEllipsis, dtTop];
// Calcuate the Bounds of the Cell that is allowed to be drawn in
// **********
RectArray.BoundsRect := Item.DisplayRect;
InflateRect(RectArray.BoundsRect, -Item.Border, -Item.Border);
// Calculate where the Checkbox is positioned
// **********
if Item.CheckType <> ectNone then
begin
R := Checks.Bound[Item.Checksize];
RectArray.CheckRect.Left := RectArray.BoundsRect.Left + Item.CheckIndent;
RectArray.CheckRect.Top := RectArray.BoundsRect.Top + (RectHeight(RectArray.BoundsRect) - R.Bottom) div 2;
RectArray.CheckRect.Right := RectArray.CheckRect.Left + R.Right;
RectArray.CheckRect.Bottom := RectArray.CheckRect.Top + R.Bottom;
end else
SetRect(RectArray.CheckRect, RectArray.BoundsRect.Left,
RectArray.BoundsRect.Top,
RectArray.BoundsRect.Left,
RectArray.BoundsRect.Bottom);
// Calculate where the Icon is positioned
// **********
RectArray.IconRect := Rect(RectArray.CheckRect.Right + Item.ImageIndent,
RectArray.BoundsRect.Top,
RectArray.CheckRect.Right + Item.ImageIndent + ImageW + 4,
RectArray.BoundsRect.Bottom);
// Calculate where the Label Rect is positioned
// **********
RectArray.LabelRect := RectArray.BoundsRect;
RectArray.LabelRect.Left := RectArray.IconRect.Right + Item.CaptionIndent;
InflateRect(RectArray.LabelRect, -2, 0);
// Calculate the Text Rectangles
// **********
RectArray.TextRect := RectArray.LabelRect;
// Leave border for the Selection Painted rectangle around text
InflateRect(RectArray.TextRect, -2, -2);
DetailCount := Item.DetailCount;
// Assume that there is enough room for all the Captions to be show that the user desired
SetLength(RectArray.TextRects, DetailCount);
for i := 0 to Length(RectArray.TextRects) - 1 do
RectArray.TextRects[i] := Rect(0, 0, 0, 0);
if Length(RectArray.TextRects) > 0 then
begin
// Lets work on the Main Caption, it gets the full LabelR to use
RectArray.TextRects[0] := RectArray.LabelRect;
// TextRects[0] is the main caption that can fill more then one line if necessary
// if it does then details are omitted as necded
if Item.Details[0] > -1 then
ACaption := Item.Captions[Item.Details[0]]
else
ACaption := '';
// Make the first line contain something
if ACaption = '' then
ACaption := ' ';
if Assigned(OwnerListview.ScratchCanvas) then
begin
LoadTextFont(Item, PositionIndex, OwnerListview.ScratchCanvas, Item.Selected);
DrawTextWEx(OwnerListview.ScratchCanvas.Handle, ACaption, RectArray.TextRects[0], DrawTextFlags, PaintTextLineCount(Item, Column));
end;
if RectArray.TextRects[0].Bottom > RectArray.LabelRect.Bottom then
RectArray.TextRects[0] := Rect(0, 0, 0, 0)
else begin
// Only fill in as many detail lines that fit based on if the caption
// necded two lines or not
Done := False;
i := 1;
while not Done and (i < Length(RectArray.TextRects)) do
begin
if RectArray.TextRects[i - 1].Bottom < RectArray.LabelRect.Bottom then
begin
if Item.Details[i] > -1 then
ACaption := Item.Captions[Item.Details[i]]
else
ACaption := '';
RectArray.TextRects[i] := RectArray.LabelRect;
RectArray.TextRects[i].Top := RectArray.TextRects[i - 1].Bottom;
if Assigned(OwnerListview.ScratchCanvas) then
begin
LoadTextFont(Item, i, OwnerListview.ScratchCanvas, Item.Selected);
// Details only get one line
DrawTextWEx(OwnerListview.ScratchCanvas.Handle, ACaption, RectArray.TextRects[i], DrawTextFlags, 1);
end;
if RectArray.TextRects[i].Bottom > RectArray.LabelRect.Bottom then
begin
RectArray.TextRects[i] := Rect(0, 0, 0, 0);
Done := True
end else
Inc(i)
end else
begin
RectArray.TextRects[i] := Rect(0, 0, 0, 0);
Done := True;
end
end;
end;
RectArray.TextRect := Rect(0, 0, 0, 0);
Done := False;
i := 0;
while not Done and (i < Length(RectArray.TextRects)) do
begin
if not IsRectEmpty(RectArray.TextRects[i]) then
begin
UnionRect(RectArray.TextRect, RectArray.TextRect, RectArray.TextRects[i]);
Inc(i)
end else
Done := True
end;
if Done then
SetLength(RectArray.TextRects, i);
YOffset := 0;
if Item.VAlignment = cvaCenter then
YOffset := (RectHeight(RectArray.LabelRect)-RectHeight(RectArray.TextRect)) div 2
else
if Item.VAlignment = cvaBottom then
YOffset := RectArray.LabelRect.Bottom - RectHeight(RectArray.TextRect);
for i := 0 to Length(RectArray.TextRects) - 1 do
begin
if Item.VAlignment = cvaCenter then
OffsetRect(RectArray.TextRects[i], 0, YOffset)
else
if Item.VAlignment = cvaBottom then
OffsetRect(RectArray.TextRects[i], 0, YOffset);
end;
if Item.VAlignment = cvaCenter then
OffsetRect(RectArray.TextRect, 0, YOffset)
else
if Item.VAlignment = cvaBottom then
OffsetRect(RectArray.TextRect, 0, YOffset);
end;
RectArray.FullTextRect := RectArray.TextRect;
RectArray.SelectionRect := RectArray.TextRect;
InflateRect(RectArray.SelectionRect, 2, 2);
RectArray.FullFocusSelRect := RectArray.SelectionRect;
RectArray.ClickselectBoundsRect := RectArray.IconRect;
RectArray.ClickselectBoundsRect.Right := RectArray.TextRect.Right;
RectArray.DragSelectBoundsRect := RectArray.TextRect;
RectArray.DragSelectBoundsRect.Right := RectArray.DragSelectBoundsRect.Right - Round(RectWidth(RectArray.DragSelectBoundsRect)*0.20);
UnionRect(RectArray.FocusChangeInvalidRect, RectArray.IconRect, RectArray.FullTextRect);
RectArray.EditRect := RectArray.FullTextRect;
end
end
end;
procedure TEasyViewTileItem.PaintBefore(Item: TEasyItem; Column: TEasyColumn; const Caption: WideString; ACanvas: TCanvas; RectArray: TEasyRectArrayObject; var Handled: Boolean);
begin
end;
procedure TEasyViewTileItem.PaintText(Item: TEasyItem; Column: TEasyColumn; const Caption: WideString; RectArray: TEasyRectArrayObject; ACanvas: TCanvas; LinesToDraw: Integer);
//
// Need to handle this paint directly
//
var
DrawTextFlags: TCommonDrawTextWFlags;
i: Integer;
begin
DrawTextFlags := [dtEndEllipsis, dtTop];
case PaintTextAlignment(Item, Column) of
taLeftJustify: Include(DrawTextFlags, dtLeft);
taRightJustify: Include(DrawTextFlags, dtRight);
taCenter: Include(DrawTextFlags, dtCenter);
end;
if Length(RectArray.TextRects) > 0 then
begin
if Item.Details[0] > -1 then
begin
LoadTextFont(Item, 0, ACanvas, Item.Selected);
DrawTextWEx(ACanvas.Handle, Item.Captions[Item.Details[0]], RectArray.TextRects[0], DrawTextFlags, PaintTextLineCount(Item, Column));
end;
for i := 1 to Length(RectArray.TextRects) - 1 do
begin
if Item.Details[i] > -1 then
begin
LoadTextFont(Item, i, ACanvas, Item.Selected);
DrawTextWEx(ACanvas.Handle, Item.Captions[Item.Details[i]], RectArray.TextRects[i], DrawTextFlags, 1);
end
end
end
end;
function TEasyViewThumbnailItem.ExpandTextR(Item: TEasyItem; RectArray: TEasyRectArrayObject; SelectType: TEasySelectHitType): TRect;
begin
Result := inherited ExpandTextR(Item, RectArray, SelectType);
Result.Top := RectArray.IconRect.Bottom
end;
function TEasyViewThumbnailItem.GetImageList(Column: TEasyColumn; Item: TEasyItem; Image: TEasyImageKind): TCustomImageList;
begin
Result := inherited GetImageList(Column, Item, Image);
if not Assigned(Result) then
Result := Item.ImageList[ValidateColumnIndex(Column), eisLarge]
end;
{ TEasyThumbnailItemView}
function TEasyViewThumbnailItem.OverlappedFocus: Boolean;
begin
Result := True
end;
function TEasyViewThumbnailItem.PaintImageSize: TEasyImageSize;
begin
Result := eisExtraLarge
end;
function TEasyViewThumbnailItem.SelectionHit(Item: TEasyItem; SelectViewportRect: TRect; SelectType: TEasySelectHitType): Boolean;
var
R: TRect;
RectArray: TEasyRectArrayObject;
SelectMargin: Integer;
begin
Result := False;
if Item.Enabled then
begin
ItemRectArray(Item, nil, OwnerListview.ScratchCanvas,'', RectArray);
if SelectType = eshtClickselect then
Result := IntersectRect(R, SelectViewportRect, ExpandTextR(Item, RectArray, SelectType)) or
IntersectRect(R, SelectViewportRect, ExpandIconR(Item, RectArray, SelectType))
else begin
R := ExpandIconR(Item, RectArray, SelectType);
SelectMargin := Round( RectWidth(R) * 0.10);
InflateRect(R, -SelectMargin, -SelectMargin);
Result := IntersectRect(R, SelectViewportRect, R)
end
end
end;
function TEasyViewThumbnailItem.SelectionHitPt(Item: TEasyItem; ViewportPoint: TPoint; SelectType: TEasySelectHitType): Boolean;
var
RectArray: TEasyRectArrayObject;
R: TRect;
SelectMargin: Integer;
begin
Result := False;
if Item.Enabled then
begin
ItemRectArray(Item, nil, OwnerListview.ScratchCanvas, '', RectArray);
if SelectType = eshtClickselect then
Result := Windows.PtInRect(ExpandTextR(Item, RectArray, SelectType), ViewportPoint) or
Windows.PtInRect(ExpandIconR(Item, RectArray, SelectType), ViewportPoint)
else
begin
R := ExpandIconR(Item, RectArray, SelectType);
SelectMargin := Round( RectWidth(R) * 0.10);
InflateRect(R, -SelectMargin, -SelectMargin);
Result := Windows.PtInRect(R, ViewportPoint)
end
end
end;
procedure TEasyViewThumbnailItem.AfterSelRectCalc(Item: TEasyItem;
Column: TEasyColumn; const Caption: WideString; var LocalSelRect: TRect);
begin
InflateRect(LocalSelRect, -2, -2)
end;
procedure TEasyViewThumbnailItem.ItemRectArray(Item: TEasyItem; Column: TEasyColumn; ACanvas: TCanvas; const Caption: WideString; var RectArray: TEasyRectArrayObject);
var
DrawTextFlags: TCommonDrawTextWFlags;
Canvas: TControlCanvas;
R: TRect;
PositionIndex, AbsIndex: Integer;
Metrics: TTextMetric;
ACaption: WideString;
begin
if Assigned(Item) then
begin
if not Item.Initialized then
Item.Initialized := True;
if Assigned(Column) then
begin
AbsIndex := Column.Index;
PositionIndex := Column.Position
end else
begin
AbsIndex := 0;
PositionIndex := 0
end;
if PositionIndex > -1 then
begin
FillChar(RectArray, SizeOf(RectArray), #0);
Canvas := TControlCanvas.Create;
try
Canvas.Control := OwnerListview;
Canvas.Lock;
// Calcuate the Bounds of the Cell that is allowed to be drawn in
// **********
RectArray.BoundsRect := Item.DisplayRect;
InflateRect(RectArray.BoundsRect, -Item.Border, -Item.Border);
// Calcuate the Bounds of the Cell that is allowed to be drawn in
// **********
RectArray.IconRect := RectArray.BoundsRect;
if not OwnerListview.PaintInfoItem.HideCaption then
begin
GetTextMetrics(Canvas.Handle, Metrics);
RectArray.IconRect.Bottom := RectArray.IconRect.Bottom - Metrics.tmHeight * 2
end else
if Item.CheckType <> ectNone then
RectArray.IconRect.Bottom := RectArray.IconRect.Bottom - (RectHeight(Checks.Bound[Item.Checksize]) + 2);
// Calculate area that the Checkbox may be drawn
// **********
if Item.CheckType <> ectNone then
begin
R := Checks.Bound[Item.Checksize];
RectArray.CheckRect.Top := RectArray.IconRect.Bottom + 1; // Looks best here not centered
RectArray.CheckRect.Left := RectArray.BoundsRect.Left + Item.CheckIndent;
RectArray.CheckRect.Bottom := RectArray.CheckRect.Top + R.Bottom;
RectArray.CheckRect.Right := RectArray.CheckRect.Left + R.Right;
end else
begin
RectArray.CheckRect.Top := RectArray.IconRect.Bottom;
RectArray.CheckRect.Left := RectArray.BoundsRect.Left;
RectArray.CheckRect.Bottom := RectArray.BoundsRect.Bottom;
RectArray.CheckRect.Right := RectArray.CheckRect.Left;
end;
// Calcuate the Bounds of the Cell that is allowed to be drawn in
// **********
if not OwnerListview.PaintInfoItem.HideCaption then
begin
RectArray.LabelRect.Left := RectArray.CheckRect.Right + Item.CaptionIndent;
RectArray.LabelRect.Top := RectArray.IconRect.Bottom + 1;
RectArray.LabelRect.Right := RectArray.BoundsRect.Right;
RectArray.LabelRect.Bottom := RectArray.BoundsRect.Bottom;
// Calcuate the Text rectangle based on the current text
// **********
RectArray.TextRect := RectArray.LabelRect;
RectArray.FullTextRect := RectArray.LabelRect;
// Leave room for a small border between edge of the selection rect and text
InflateRect(RectArray.TextRect, -2, -2);
InflateRect(RectArray.FullTextRect, -2, -2);
DrawTextFlags := [dtCalcRect, dtCalcRectAlign];
case PaintTextAlignment(Item, Column) of
taLeftJustify: Include(DrawTextFlags, dtLeft);
taRightJustify: Include(DrawTextFlags, dtRight);
taCenter: Include(DrawTextFlags, dtCenter);
end;
case PaintTextVAlignment(Item, Column) of
cvaTop: Include(DrawTextFlags, dtTop);
cvaBottom: Include(DrawTextFlags, dtBottom);
cvaCenter: Include(DrawTextFlags, dtCenter);
end;
LoadTextFont(Item, PositionIndex, Canvas, Item.Selected);
ACaption := Item.Captions[AbsIndex];
DrawTextWEx(Canvas.Handle, ACaption, RectArray.FullTextRect, DrawTextFlags, -1);
DrawTextWEx(Canvas.Handle, ACaption, RectArray.TextRect, DrawTextFlags, 2);
// Calculate Selection rectangle paint box
// **********
RectArray.SelectionRect := RectArray.TextRect;
InflateRect(RectArray.SelectionRect, 2, 2);
RectArray.FullFocusSelRect := RectArray.FullTextRect;
InflateRect(RectArray.FullFocusSelRect, 2, 2);
UnionRect(RectArray.FocusChangeInvalidRect, RectArray.IconRect, RectArray.FullFocusSelRect);
if Item.Focused then
UnionRect(RectArray.ClickselectBoundsRect, RectArray.IconRect, RectArray.FullFocusSelRect)
else
UnionRect(RectArray.ClickselectBoundsRect, RectArray.IconRect, RectArray.SelectionRect);
RectArray.ClickselectBoundsRect := RectArray.ClickselectBoundsRect;
RectArray.DragSelectBoundsRect := RectArray.TextRect;
RectArray.EditRect := RectArray.FullTextRect;
end else
begin
RectArray.SelectionRect := RectArray.IconRect;
RectArray.FullFocusSelRect := RectArray.IconRect;
RectArray.FocusChangeInvalidRect := RectArray.IconRect;
RectArray.ClickselectBoundsRect := RectArray.IconRect;
RectArray.DragSelectBoundsRect := RectArray.IconRect;
RectArray.EditRect := Rect(0, 0, 0, 0);
RectArray.LabelRect := Rect(0, 0, 0, 0);
RectArray.TextRect := Rect(0, 0, 0, 0);
RectArray.FullTextRect := Rect(0, 0, 0, 0);
end;
finally
Canvas.UnLock;
Canvas.Free;
end;
end
end
end;
function TEasyViewThumbnailItem.PaintTextLineCount(Item: TEasyItem; Column: TEasyColumn): Integer;
begin
if Item.Focused and OwnerListview.Focused then
Result := -1
else
Result := 2
end;
function TEasyViewThumbnailItem.PaintTextVAlignment(Item: TEasyItem; Column: TEasyColumn): TCommonVAlignment;
begin
Result := cvaCenter
end;
procedure TEasyViewThumbnailItem.PaintAfter(Item: TEasyItem; Column: TEasyColumn; const Caption: WideString; ACanvas: TCanvas; RectArray: TEasyRectArrayObject);
begin
if OwnerListview.PaintInfoItem.ShowBorder then
begin
// Paint the Frame around the Thumbnail
if (Item.Selected or Item.Hilighted) and not OwnerListview.Selection.Gradient then
begin
if OwnerListview.Focused or Item.OwnerListview.Selection.PopupMode or Item.Hilighted then
ACanvas.Brush.Color := OwnerListview.Selection.Color
else
ACanvas.Brush.Color := OwnerListview.Selection.InactiveColor;
ACanvas.FrameRect(RectArray.IconRect);
InflateRect(RectArray.IconRect, -1, -1);
ACanvas.FrameRect(RectArray.IconRect);
InflateRect(RectArray.IconRect, -1, -1);
ACanvas.FrameRect(RectArray.IconRect);
end else
begin
ACanvas.Brush.Color := Item.BorderColor;
ACanvas.FrameRect(RectArray.IconRect);
end
end
end;
procedure TEasyViewThumbnailItem.PaintBefore(Item: TEasyItem; Column: TEasyColumn; const Caption: WideString; ACanvas: TCanvas; RectArray: TEasyRectArrayObject; var Handled: Boolean);
begin
// Skip inherited
end;
{ TColumnView }
function TEasyViewColumn.EditAreaHitPt(Column: TEasyColumn;
ViewportPoint: TPoint): Boolean;
begin
Result := False
end;
function TEasyViewColumn.GetImageList(Column: TEasyColumn): TCustomImageList;
begin
Result := Column.OwnerHeader.Images
end;
function TEasyViewColumn.ItemRect(Column: TEasyColumn; RectType: TEasyCellRectType): TRect;
var
RectArray: TEasyRectArrayObject;
begin
Result := Rect(0, 0, 0, 0);
if IsRectEmpty(Result) then
begin
ItemRectArray(Column, RectArray);
case RectType of
ertBounds: Result := RectArray.BoundsRect;
ertIcon: Result := RectArray.IconRect;
ertLabel: Result := RectArray.LabelRect;
ertClickselectBounds: Result := RectArray.ClickselectBoundsRect;
ertDragSelectBounds: Result := RectArray.DragSelectBoundsRect;
ertText: Result := RectArray.TextRect;
ertFullText: Result := RectArray.FullTextRect;
end;
end;
end;
function TEasyViewColumn.PaintImageSize(Column: TEasyColumn;
HeaderType: TEasyHeaderType): TEasyImageSize;
begin
Result := eisSmall
end;
function TEasyViewColumn.SelectionHit(Column: TEasyColumn;
SelectViewportRect: TRect; SelectType: TEasySelectHitType): Boolean;
begin
Result := False
end;
function TEasyViewColumn.SelectionHitPt(Column: TEasyColumn;
ViewportPoint: TPoint; SelectType: TEasySelectHitType): Boolean;
begin
Result := False
end;
procedure TEasyViewColumn.CalculateTextRect(Column: TEasyColumn; Canvas: TControlCanvas;
var TextR: TRect);
// Fits the Text in the PaintInfo.Caption.Text field into the TextR based
// on the values in the PaintInfo record. If Canvas is nil then a temporary
// canvas is created to fit the text based on the Font in the PaintInfo
var
DrawTextFlags: TCommonDrawTextWFlags;
LocalCanvas: TControlCanvas;
begin
case Column.Alignment of
taLeftJustify: Include(DrawTextFlags, dtLeft);
taRightJustify: Include(DrawTextFlags, dtRight);
taCenter: Include(DrawTextFlags, dtCenter);
end;
case Column.VAlignment of
cvaTop: Include(DrawTextFlags, dtTop);
cvaBottom: Include(DrawTextFlags, dtBottom);
cvaCenter: Include(DrawTextFlags, dtVCenter);
end;
if not Assigned(Canvas) then
begin
LocalCanvas := TControlCanvas.Create;
LocalCanvas.Control := OwnerListview
end else
LocalCanvas := Canvas;
try
LoadTextFont(Column, LocalCanvas);
DrawTextFlags := DrawTextFlags + [dtCalcRectAdjR, dtCalcRect, dtCalcRectAlign];
DrawTextWEx(LocalCanvas.Handle, Column.Caption, TextR, DrawTextFlags, 1);
finally
if not Assigned(Canvas) then
LocalCanvas.Free
end;
end;
procedure TEasyViewColumn.GetImageSize(Column: TEasyColumn; var ImageW, ImageH: Integer);
var
Images: TCustomImageList;
IsCustom: Boolean;
begin
ImageW := 0;
ImageH := 0;
Column.ImageDrawIsCustom(Column, IsCustom);
if IsCustom then
Column.ImageDrawGetSize(Column, ImageW, ImageH)
else begin
Images := GetImageList(Column);
if (Column.ImageIndexes[0] > -1) and Assigned(Images) then
begin
ImageW := Images.Width;
ImageH := Images.Height
end
end
end;
procedure TEasyViewColumn.ItemRectArray(Column: TEasyColumn; var RectArray: TEasyRectArrayObject);
var
DrawTextFlags: TCommonDrawTextWFlags;
i, CaptionLines: integer;
R: TRect;
ImageW, ImageH: Integer;
Pt: TPoint;
begin
Pt.x := 0;
Pt.y := 0;
if Assigned(Column) then
begin
if not Column.Initialized then
Column.Initialized := True;
FillChar(RectArray, SizeOf(RectArray), #0);
GetImageSize(Column, ImageW, ImageH);
RectArray.BoundsRect := Column.DisplayRect;
InflateRect(RectArray.BoundsRect, -2, -2);
// Make the CheckRect 0 width to initialize it
RectArray.CheckRect := RectArray.BoundsRect;
RectArray.CheckRect.Right := RectArray.CheckRect.Left;
// Make the DropDownArrow 0 width to initialize it to the right side
RectArray.DropDownArrow := RectArray.BoundsRect;
RectArray.DropDownArrow.Left := RectArray.DropDownArrow.Right;
// First calculate where the CheckRect goes
if Column.CheckType <> ectNone then
begin
R := Checks.Bound[Column.Checksize];
RectArray.CheckRect.Left := RectArray.CheckRect.Left + Column.CheckIndent;
RectArray.CheckRect.Top := RectArray.CheckRect.Top + (RectHeight(RectArray.BoundsRect) - RectHeight(R)) div 2;
RectArray.CheckRect.Right := RectArray.CheckRect.Left + RectWidth(R);
RectArray.CheckRect.Bottom := RectArray.CheckRect.Top + RectHeight(R);
end;
// Initialize IconRect to 0 width
RectArray.IconRect := RectArray.BoundsRect;
RectArray.IconRect.Left := RectArray.CheckRect.Right;
RectArray.IconRect.Right := RectArray.CheckRect.Right;
// Next comes the State Image if enabled
if Column.ImageIndex > -1 then
begin
case Column.ImagePosition of
ehpLeft:
begin
RectArray.IconRect.Left := RectArray.CheckRect.Right + Column.ImageIndent;
RectArray.IconRect.Right := RectArray.IconRect.Left + ImageW;
RectArray.IconRect.Top := RectArray.BoundsRect.Top + (RectHeight(RectArray.BoundsRect) - ImageH) div 2;
RectArray.IconRect.Bottom := RectArray.IconRect.Top + ImageH;
RectArray.LabelRect := RectArray.BoundsRect;
RectArray.LabelRect.Left := RectArray.IconRect.Right + Column.CaptionIndent;
end;
ehpTop:
begin
RectArray.IconRect.Top := RectArray.BoundsRect.Top + Column.ImageIndent;
RectArray.IconRect.Bottom := RectArray.IconRect.Top + ImageH;
RectArray.IconRect.Left := RectArray.BoundsRect.Left;
RectArray.IconRect.Right := RectArray.BoundsRect.Right;
RectArray.LabelRect := RectArray.BoundsRect;
RectArray.LabelRect.Left := RectArray.CheckRect.Right;
RectArray.LabelRect.Top := RectArray.IconRect.Bottom + Column.CaptionIndent;
end;
ehpRight:
begin
RectArray.IconRect.Right := RectArray.BoundsRect.Right - Column.ImageIndent;
RectArray.IconRect.Left := RectArray.IconRect.Right - ImageW;
RectArray.IconRect.Top := RectArray.BoundsRect.Top + (RectHeight(RectArray.BoundsRect) - ImageH) div 2;
RectArray.IconRect.Bottom := RectArray.IconRect.Top + ImageH;
RectArray.LabelRect := RectArray.BoundsRect;
RectArray.LabelRect.Left := RectArray.CheckRect.Right;
RectArray.LabelRect.Right := RectArray.IconRect.Left - Column.CaptionIndent;
end;
ehpBottom:
begin
RectArray.IconRect.Bottom := RectArray.BoundsRect.Bottom - Column.ImageIndent;
RectArray.IconRect.Top := RectArray.IconRect.Bottom - ImageH;
RectArray.IconRect.Left := RectArray.BoundsRect.Left;
RectArray.IconRect.Right := RectArray.BoundsRect.Right;
RectArray.LabelRect := RectArray.BoundsRect;
RectArray.LabelRect.Left := RectArray.CheckRect.Right;
RectArray.LabelRect.Bottom := RectArray.IconRect.Top - Column.CaptionIndent;
end;
end
end else
begin
RectArray.LabelRect := RectArray.BoundsRect;
RectArray.LabelRect.Left := RectArray.IconRect.Right;
end;
if Column.SortDirection <> esdNone then
begin
case Column.SortGlyphAlign of
esgaLeft:
begin
RectArray.SortRect := RectArray.BoundsRect;
RectArray.SortRect.Left := RectArray.LabelRect.Left;
RectArray.LabelRect.Left := RectArray.LabelRect.Left + Column.SortGlyphIndent + OwnerListview.GlobalImages.ColumnSortUp.Width;
RectArray.SortRect.Right := RectArray.SortRect.Left + OwnerListview.GlobalImages.ColumnSortUp.Width;
RectArray.SortRect.Top := RectArray.SortRect.Top + (RectHeight(RectArray.SortRect) - OwnerListview.GlobalImages.ColumnSortUp.Height) div 2;
RectArray.SortRect.Bottom := RectArray.SortRect.Top + OwnerListview.GlobalImages.ColumnSortUp.Height
end;
esgaRight:
begin
RectArray.SortRect := RectArray.BoundsRect;
RectArray.SortRect.Right := RectArray.LabelRect.Right;
RectArray.LabelRect.Right := RectArray.LabelRect.Right - Column.SortGlyphIndent - OwnerListview.GlobalImages.ColumnSortUp.Width;
RectArray.SortRect.Left := RectArray.SortRect.Right - OwnerListview.GlobalImages.ColumnSortUp.Width;
RectArray.SortRect.Top := RectArray.SortRect.Top + (RectHeight(RectArray.SortRect) - OwnerListview.GlobalImages.ColumnSortUp.Height) div 2;
RectArray.SortRect.Bottom := RectArray.SortRect.Top + OwnerListview.GlobalImages.ColumnSortUp.Height
end
else
// no Sort Glyph
RectArray.SortRect := RectArray.LabelRect;
RectArray.SortRect.Right := RectArray.SortRect.Left;
end
end;
if Column.DropDownButton.Visible then
begin
if RectWidth(RectArray.LabelRect) > RectHeight(RectArray.BoundsRect) + 10 then
begin
if Column.DropDownButton.AlwaysShow or Column.HotTracking[Pt] then
begin
RectArray.LabelRect.Right := RectArray.LabelRect.Right - RectHeight(RectArray.BoundsRect);
RectArray.DropDownArrow.Left := RectArray.DropDownArrow.Right - RectHeight(RectArray.BoundsRect)
end
end
end;
// See if there is enough room for the label
if IsRectProper(RectArray.LabelRect) then
begin
RectArray.TextRect := RectArray.LabelRect;
case Column.Alignment of
taLeftJustify:
begin
RectArray.TextRect.Left := RectArray.TextRect.Left + Column.CaptionIndent;
RectArray.TextRect.Right := RectArray.TextRect.Right - 4;
end;
taRightJustify:
begin
RectArray.TextRect.Right := RectArray.TextRect.Right - Column.CaptionIndent;
RectArray.TextRect.Left := RectArray.TextRect.Left + 4;
end;
end;
// Leave room for a small border between edge of the selection rect and text
InflateRect(RectArray.TextRect, -2, -2);
DrawTextFlags := [dtCalcRect, dtCalcRectAlign];
case Column.Alignment of
taCenter: DrawTextFlags := DrawTextFlags + [dtCenter];
taLeftJustify: DrawTextFlags := DrawTextFlags + [dtLeft];
taRightJustify: DrawTextFlags := DrawTextFlags + [dtRight];
end;
// Vertical Alignment has no meaning in mulitiple line output need to calculate
// the entire text block then vert align it
DrawTextFlags := DrawTextFlags + [dtTop];
CaptionLines := OwnerListview.PaintInfoColumn.CaptionLines;
// Make enough room for the Details and the Caption Rect
SetLength(RectArray.TextRects, CaptionLines + 1);
// Get the Caption Rect
RectArray.TextRects[0] := RectArray.TextRect;
LoadTextFont(Column, OwnerListview.ScratchCanvas);
DrawTextWEx(OwnerListview.ScratchCanvas.Handle, Column.Caption, RectArray.TextRects[0], DrawTextFlags, CaptionLines);
RectArray.TextRect := Rect(0, 0, 0, 0);
for i := 0 to Length(RectArray.TextRects) - 1 do
UnionRect(RectArray.TextRect, RectArray.TextRect, RectArray.TextRects[i]);
case Column.VAlignment of
cvaCenter: OffsetRect(RectArray.TextRect, 0, (RectHeight(RectArray.LabelRect) - RectHeight(RectArray.TextRect)) div 2);
cvaBottom: OffsetRect(RectArray.TextRect, 0, (RectHeight(RectArray.LabelRect) - RectHeight(RectArray.TextRect)));
end;
for i := 0 to Length(RectArray.TextRects) - 1 do
begin
case Column.VAlignment of
cvaCenter: OffsetRect(RectArray.TextRects[i], 0, ((RectHeight(RectArray.LabelRect) - 4) - RectHeight(RectArray.TextRect)) div 2);
cvaBottom: OffsetRect(RectArray.TextRects[i], 0, ((RectHeight(RectArray.LabelRect) - 4) - RectHeight(RectArray.TextRect)));
end;
end;
end else
RectArray.TextRect := Rect(0, 0, 0, 0);
// Put the Sort Arrow right next to the Text
OffsetRect(RectArray.SortRect, RectArray.TextRect.Right - RectArray.SortRect.Left, 0);
RectArray.ClickselectBoundsRect := RectArray.BoundsRect;
RectArray.DragSelectBoundsRect := RectArray.BoundsRect;
RectArray.SelectionRect := RectArray.BoundsRect;
RectArray.FullTextRect := RectArray.BoundsRect;
RectArray.FullTextRect := RectArray.BoundsRect;
RectArray.FocusChangeInvalidRect := RectArray.BoundsRect;
RectArray.EditRect := RectArray.BoundsRect;
InflateRect(RectArray.BoundsRect, 2, 2);
end
end;
procedure TEasyViewColumn.LoadTextFont(Column: TEasyColumn; ACanvas: TCanvas);
begin
ACanvas.Font.Assign(OwnerListview.Header.Font);
if Column.Bold then
ACanvas.Font.Style := ACanvas.Font.Style +[fsBold];
end;
procedure TEasyViewColumn.Paint(Column: TEasyColumn; ACanvas: TCanvas;
HeaderType: TEasyHeaderType);
procedure AlphaBlendColumn(AColor: TColor; R: TRect);
var
Bitmap: TBitmap;
begin
Bitmap := TBitmap.Create;
try
Bitmap.PixelFormat := pf32Bit;
Bitmap.Width := RectWidth(R);
Bitmap.Height := RectHeight(R);
if (Bitmap.Width > 0) and (Bitmap.Height > 0) then
begin
BitBlt(Bitmap.Canvas.Handle, 0, 0, Bitmap.Width, Bitmap.Height, ACanvas.Handle, R.Left, R.Top, srcCopy);
MPCommonUtilities.AlphaBlend(0, Bitmap.Canvas.Handle, Bitmap.Canvas.ClipRect, Point(0, 0),
cbmConstantAlphaAndColor, 128, ColorToRGB(AColor));
BitBlt(ACanvas.Handle, R.Left, R.Top, Bitmap.Width, Bitmap.Height, Bitmap.Canvas.Handle, 0, 0, srcCopy);
end
finally
Bitmap.Free
end
end;
var
RectArray: TEasyRectArrayObject;
begin
ItemRectArray(Column, RectArray);
with RectArray.BoundsRect do
IntersectClipRect(ACanvas.Handle, Left, Top, Right, Bottom);
// First allow decendents a crack at the painting
PaintBefore(Column, ACanvas, HeaderType, RectArray);
// Paint the Background button
PaintBkGnd(Column, ACanvas, HeaderType, RectArray);
// Paint the Selection Rectangle
// *************************
// PaintSelectionRect(Column, RectArray, ACanvas);
// Next Paint the Icon or Bitmap Image
// *************************
PaintImage(Column, ACanvas, HeaderType, RectArray, PaintImageSize(Column, HeaderType));
// Now lets paint the Text
// *************************
// If focused then show as many lines as necessary
// Decendents should override PaintText to change the number of lines
// as necessary
PaintText(Column, ACanvas, HeaderType, RectArray, OwnerListview.PaintInfoColumn.CaptionLines);
PaintSortGlyph(Column, ACanvas, HeaderType, RectArray);
// Now lets paint Focus Rectangle
// *************************
PaintFocusRect(Column, ACanvas, HeaderType, RectArray);
// Now Paint the Checkbox if applicable
PaintCheckBox(Column, ACanvas, HeaderType, RectArray);
PaintDropGlyph(Column, ACanvas, HeaderType, RectArray);
PaintDropDownArrow(Column, ACanvas, HeaderType, RectArray);
// Now give decentant a chance to paint anything
PaintAfter(Column, ACanvas, HeaderType, RectArray);
end;
procedure TEasyViewColumn.PaintAfter(Column: TEasyColumn; ACanvas: TCanvas;
HeaderType: TEasyHeaderType; RectArray: TEasyRectArrayObject);
begin
end;
procedure TEasyViewColumn.PaintBefore(Column: TEasyColumn; ACanvas: TCanvas;
HeaderType: TEasyHeaderType; RectArray: TEasyRectArrayObject);
begin
end;
procedure TEasyViewColumn.PaintBkGnd(Column: TEasyColumn; ACanvas: TCanvas;
HeaderType: TEasyHeaderType; RectArray: TEasyRectArrayObject);
procedure SpiegelnHorizontal(Bitmap:TBitmap);
type
TRGBArray = array[0..0] OF TRGBQuad;
pRGBArray = ^TRGBArray;
var
i, j, w : Integer;
RowIn : pRGBArray;
RowOut: pRGBArray;
begin
w := Bitmap.Width*SizeOf(TRGBQuad);
GetMem(RowIn, w);
for j := 0 to Bitmap.Height-1 do
begin
Move(Bitmap.Scanline[j]^, RowIn^,w);
RowOut := Bitmap.Scanline[j];
for i := 0 to Bitmap.Width-1 do
RowOut[i] := RowIn[Bitmap.Width-1-i];
end;
Bitmap.Assign(Bitmap);
Freemem(RowIn);
end;
var
NormalButtonFlags, NormalButtonStyle, PressedButtonStyle, PressedButtonFlags,
RaisedButtonStyle, RaisedButtonFlags: LongWord;
R: TRect;
Pt: TPoint;
{$IFDEF USETHEMES}
PartID,
StateID: LongWord;
Bits: TBitmap;
{$ENDIF}
begin
Pt.x := 0;
Pt.y := 0;
{$IFDEF USETHEMES}
if OwnerListview.DrawWithThemes then
begin
PartID := HP_HEADERITEM;
if Column.Clicking then
StateID := HIS_PRESSED
else
if Column.HotTracking[Pt] then
StateID := HIS_HOT
else
StateID := HIS_NORMAL;
if HeaderType = ehtFooter then
begin
Bits := TBitmap.Create;
try
Bits.Width := RectWidth(Column.DisplayRect);
Bits.Height := RectHeight(Column.DisplayRect);
Bits.PixelFormat := pf32Bit;
DrawThemeBackground(OwnerListview.Themes.HeaderTheme, Bits.Canvas.Handle, PartID, StateID, Rect(0, 0, Bits.Width, Bits.Height), nil);
SpiegelnHorizontal(Bits);
BitBlt(ACanvas.Handle, Column.DisplayRect.Left, Column.DisplayRect.Top, Bits.Width, Bits.Height, Bits.Canvas.Handle, 0, 0, SRCCOPY);
finally
Bits.Free
end;
end else
begin
R := Column.DisplayRect;
// The divider is drawn by this as well and if shorted the divider is before the button
// if Column.HotTracking[Pt] and Column.DropDownButton.Visible and (RectWidth(RectArray.DropDownArrow) > 0) then
// R.Right := RectArray.DropDownArrow.Left;
DrawThemeBackground(OwnerListview.Themes.HeaderTheme, ACanvas.Handle, PartID, StateID, R, nil);
end;
Exit;
end;
{$ENDIF USETHEMES}
{ if Column.Selected then
begin
if OwnerListview.Focused then
ACanvas.Brush.Color := Column.Selection.Color
else
ACanvas.Brush.Color := Column.Selection.InactiveColor
end else
if Column.HotTrack and Column.Hilighted then
ACanvas.Brush.Color := PaintInfo.HotTrack.Color
else }
ACanvas.Brush.Color := Column.Color;
ACanvas.FillRect(Column.DisplayRect);
RaisedButtonStyle := 0;
RaisedButtonFlags := 0;
case Column.Style of
ehbsThick:
begin
NormalButtonStyle := BDR_RAISEDINNER or BDR_RAISEDOUTER;
NormalButtonFlags := BF_LEFT or BF_TOP or BF_BOTTOM or BF_RIGHT or BF_SOFT or BF_ADJUST;
PressedButtonStyle := BDR_RAISEDINNER or BDR_RAISEDOUTER;
PressedButtonFlags := NormalButtonFlags or BF_RIGHT or BF_FLAT or BF_ADJUST;
end;
ehbsFlat:
begin
NormalButtonStyle := BDR_RAISEDINNER;
NormalButtonFlags := BF_LEFT or BF_TOP or BF_BOTTOM or BF_RIGHT or BF_ADJUST;
PressedButtonStyle := BDR_SUNKENOUTER;
PressedButtonFlags := BF_RECT or BF_ADJUST;
end;
else
begin
NormalButtonStyle := BDR_RAISEDINNER;
NormalButtonFlags := BF_RECT or BF_SOFT or BF_ADJUST;
PressedButtonStyle := BDR_SUNKENOUTER;
PressedButtonFlags := BF_RECT or BF_ADJUST;
RaisedButtonStyle := BDR_RAISEDINNER;
RaisedButtonFlags := BF_LEFT or BF_TOP or BF_BOTTOM or BF_RIGHT or BF_ADJUST;
end;
end;
R := Column.DisplayRect;
if Column.Clicking then
DrawEdge(ACanvas.Handle, R, PressedButtonStyle, PressedButtonFlags)
else begin
if (Column.Hilighted) and (Column.Style = ehbsPlate) then
DrawEdge(ACanvas.Handle, R, RaisedButtonStyle, RaisedButtonFlags)
else
DrawEdge(ACanvas.Handle, R, NormalButtonStyle, NormalButtonFlags)
end
end;
procedure TEasyViewColumn.PaintCheckBox(Column: TEasyColumn; ACanvas: TCanvas;
HeaderType: TEasyHeaderType; RectArray: TEasyRectArrayObject);
begin
if not ((Column.CheckType = ectNone) or (Column.CheckType = ettNoneWithSpace)) then
PaintCheckboxCore(Column.CheckType, // TEasyCheckType
OwnerListview, // TCustomEasyListview
ACanvas, // TCanvas
RectArray.CheckRect, // TRect
Column.Enabled, // IsEnabled
Column.Checked, // IsChecked
False, // IsHot
Column.CheckFlat, // IsFlat
Column.CheckHovering, // IsHovering
Column.CheckPending, // IsPending
Column,
Column.Checksize);
end;
procedure TEasyViewColumn.PaintDropDownArrow(Column: TEasyColumn; ACanvas: TCanvas; HeaderType: TEasyHeaderType; RectArray: TEasyRectArrayObject);
var
CtlState, CtlType: Longword;
R: TRect;
begin
if Column.DropDownButton.Visible and (RectWidth(RectArray.DropDownArrow) > 0) then
begin
R := RectArray.DropDownArrow;
{$IFDEF USETHEMES}
if OwnerListview.DrawWithThemes then
begin
{ Draw the DropDown Button }
CtlType := CP_DROPDOWNBUTTON;
if Column.DropDownButton.Enabled then
begin
CtlState := CBXS_NORMAL;
if cdbsDown in Column.DropDownButton.State then
CtlState := CBXS_PRESSED
else
if cdbsHovering in Column.DropDownButton.State then
CtlState := CBXS_HOT;
end else
CtlState := CBXS_DISABLED;
DrawThemeBackground(OwnerListview.Themes.ComboBoxTheme, ACanvas.Handle, CtlType, CtlState, R, nil)
end else
{$ENDIF USETHEMES}
begin
InflateRect(R, -1, -1); // Looks better
{ Draw the DropDown Button }
CtlType := DFC_SCROLL;
CtlState := DFCS_SCROLLCOMBOBOX or DFCS_FLAT;
if Column.DropDownButton.Enabled then
begin
if cdbsHovering in Column.DropDownButton.State then
CtlState := CtlState or DFCS_HOT;
if cdbsDown in Column.DropDownButton.State then
CtlState := CtlState or DFCS_PUSHED;
end else
CtlState := CtlState or DFCS_INACTIVE;
DrawFrameControl(ACanvas.Handle, R, CtlType, CtlState);
end
end
end;
procedure TEasyViewColumn.PaintDropGlyph(Column: TEasyColumn; ACanvas: TCanvas;
HeaderType: TEasyHeaderType; RectArray: TEasyRectArrayObject);
var
R: TRect;
begin
if esosDropTarget in Column.State then
begin
ACanvas.Brush.Color := clblue;
R := Column.DisplayRect;
R.Left := R.Right - 2;
ACanvas.FillRect(R);
end
end;
procedure TEasyViewColumn.PaintFocusRect(Column: TEasyColumn; ACanvas: TCanvas;
HeaderType: TEasyHeaderType; RectArray: TEasyRectArrayObject);
begin
end;
procedure TEasyViewColumn.PaintImage(Column: TEasyColumn; ACanvas: TCanvas;
HeaderType: TEasyHeaderType; RectArray: TEasyRectArrayObject;
ImageSize: TEasyImageSize);
//
// Paints the Icon/Bitmap to the Column
//
var
fStyle: Integer;
Images: TCustomImageList;
IsCustom: Boolean;
begin
Column.ImageDrawIsCustom(Column, IsCustom);
if IsCustom then
Column.ImageDraw(Column, ACanvas, RectArray, AlphaBlender)
else begin
Images := GetImageList(Column);
// Draw the image in the ImageList if available
if Assigned(Column.OwnerHeader.Images) and (Column.ImageIndex > -1) then
begin
fStyle := ILD_TRANSPARENT;
if Column.ImageOverlayIndex > -1 then
begin
ImageList_SetOverlayImage(Images.Handle, Column.ImageOverlayIndex, 1);
fStyle := fStyle or INDEXTOOVERLAYMASK(1);
end;
// Get the "normalized" rectangle for the image
RectArray.IconRect.Left := RectArray.IconRect.Left + (RectWidth(RectArray.IconRect) - Images.Width) div 2;
RectArray.IconRect.Top := RectArray.IconRect.Top + (RectHeight(RectArray.IconRect) - Images.Height) div 2;
ImageList_DrawEx(Images.Handle,
Column.ImageIndex,
ACanvas.Handle,
RectArray.IconRect.Left,
RectArray.IconRect.Top,
0,
0,
CLR_NONE,
CLR_NONE,
fStyle);
end
end
end;
procedure TEasyViewColumn.PaintSortGlyph(Column: TEasyColumn; ACanvas: TCanvas;
HeaderType: TEasyHeaderType; RectArray: TEasyRectArrayObject);
var
Image: TBitmap;
begin
if Column.SortDirection <> esdNone then
begin
if Column.SortDirection = esdAscending then
Image := OwnerListview.GlobalImages.ColumnSortUp
else
Image := OwnerListview.GlobalImages.ColumnSortDown;
ACanvas.Draw(RectArray.SortRect.Left, RectArray.SortRect.Top, Image);
end
end;
procedure TEasyViewColumn.PaintText(Column: TEasyColumn; ACanvas: TCanvas;
HeaderType: TEasyHeaderType; RectArray: TEasyRectArrayObject;
LinesToDraw: Integer);
var
DrawTextFlags: TCommonDrawTextWFlags;
begin
if not IsRectEmpty(RectArray.TextRect) then
begin
ACanvas.Brush.Style := bsClear;
DrawTextFlags := [dtEndEllipsis];
if LinesToDraw = 1 then
Include(DrawTextFlags, dtSingleLine);
case Column.Alignment of
taLeftJustify: Include(DrawTextFlags, dtLeft);
taRightJustify: Include(DrawTextFlags, dtRight);
taCenter: Include(DrawTextFlags, dtCenter);
end;
// Vertical Alignment is accounted for in the Text Rects
LoadTextFont(Column, ACanvas);
if Column.Bold then
ACanvas.Font.Style := ACanvas.Font.Style + [fsBold];
OwnerListview.DoColumnPaintText(Column, ACanvas);
DrawTextWEx(ACanvas.Handle, Column.Caption, RectArray.TextRects[0], DrawTextFlags, OwnerListview.PaintInfoColumn.CaptionLines);
end;
end;
procedure TEasyViewColumn.ReSizeRectArray(
var RectArray: TEasyRectArrayObjectArray);
var
OldLen, i: Integer;
begin
if Length(RectArray) < OwnerListview.Header.Positions.Count then
begin
OldLen := Length(RectArray);
SetLength(RectArray, OwnerListview.Header.Positions.Count);
for i := OldLen to OwnerListview.Header.Positions.Count - 1 do
FillChar(RectArray[i], SizeOf(RectArray[i]), #0);
end else
if Length(RectArray) > OwnerListview.Header.Positions.Count then
SetLength(RectArray, OwnerListview.Header.Positions.Count);
if Length(RectArray) = 0 then
begin
SetLength(RectArray, 1);
FillChar(RectArray[0], SizeOf(RectArray[0]), #0);
end
end;
{ TEasyGroupGrid }
constructor TEasyGridGroup.Create(AnOwner: TCustomEasyListview; AnOwnerGroup: TEasyGroup);
begin
inherited Create(AnOwner);
FOwnerGroup := AnOwnerGroup;
FLayout := eglVert // Default orientation
end;
destructor TEasyGridGroup.Destroy;
begin
inherited;
end;
function TEasyGridGroup.AdjacentItem(Item: TEasyItem; Direction: TEasyAdjacentCellDir): TEasyItem;
var
ColumnPos: Integer;
TestPt: TPoint;
LastItem: TEasyItem;
RectArray: TEasyRectArrayObject;
AdjacentGroup: TEasyGroup;
begin
Result := nil;
if Assigned(Item) then
begin
Assert(Item.Visible, 'Can not find TEasyGroups.AdjacentItem of an Invisible Item');
case Direction of
acdLeft:
begin
Result := Item;
if Item.VisibleIndexInGroup > 0 then
Result := OwnerGroup.VisibleItem[Item.VisibleIndexInGroup - 1]
else begin
AdjacentGroup := PrevVisibleGroupWithNItems(OwnerGroup, 0);
if Assigned(AdjacentGroup) then
Result := AdjacentGroup.VisibleItem[AdjacentGroup.VisibleCount - 1]
end
end;
acdRight:
begin
Result := Item;
if Item.VisibleIndexInGroup < OwnerGroup.VisibleCount - 1 then
Result := OwnerGroup.VisibleItem[Item.VisibleIndexInGroup + 1]
else begin
AdjacentGroup := NextVisibleGroupWithNItems(OwnerGroup, 0);
if Assigned(AdjacentGroup) then
Result := AdjacentGroup.VisibleItem[0]
end
end;
acdUp:
begin
// First see if we can stay in the same group
if Item.VisibleIndexInGroup - ColumnCount >= 0 then
Result := OwnerGroup.VisibleItems[Item.VisibleIndexInGroup - ColumnCount]
else begin
ColumnPos := Item.ColumnPos;
while not Assigned(Result) and (ColumnPos > -1) do
begin
AdjacentGroup := PrevVisibleGroupWithNItems(OwnerGroup, ColumnPos);
if Assigned(AdjacentGroup) then
Result := LastItemInNColumn(AdjacentGroup, ColumnPos);
Dec(ColumnPos)
end
end
end;
acdDown:
begin
// First see if we can stay in the same group
if Item.VisibleIndexInGroup + ColumnCount < OwnerGroup.VisibleCount then
Result := OwnerGroup.VisibleItems[Item.VisibleIndexInGroup + ColumnCount]
else begin
ColumnPos := Item.ColumnPos;
while not Assigned(Result) and (ColumnPos > -1) do
begin
AdjacentGroup := NextVisibleGroupWithNItems(OwnerGroup, ColumnPos);
if Assigned(AdjacentGroup) then
Result := AdjacentGroup.VisibleItem[ColumnPos];
Dec(ColumnPos)
end
end
end;
acdPageUp:
begin
TestPt := Item.DisplayRect.BottomRight;
// The Right is actually the Left of the next object
Dec(TestPt.X);
Dec(TestPt.Y, OwnerListview.ClientHeight);
// Make sure we don't run past the last row of items.
AdjacentGroup := OwnerGroups.FirstVisibleGroup;
if Assigned(AdjacentGroup) then
if TestPt.Y < AdjacentGroup.DisplayRect.Top + OwnerGroup.Grid.StaticTopItemMargin then
TestPt.Y := AdjacentGroup.BoundsRectBkGnd.Top + OwnerGroup.Grid.StaticTopItemMargin;
Result := OwnerGroups.ItembyPoint(TestPt);
if not Assigned(Result) then
begin
Result := SearchForHitRight(Item.ColumnPos, TestPt);
while not Assigned(Result) and (TestPt.Y > OwnerGroups.ViewRect.Top) do
begin
Inc(TestPt.Y, CellSize.Height);
Result := SearchForHitRight(Item.ColumnPos, TestPt);
end
end
end;
acdPageDown:
begin
TestPt := Item.DisplayRect.TopLeft;
Inc(TestPt.Y, OwnerListview.ClientHeight);
// Make sure we don't run past the last row of items.
LastItem := OwnerGroups.LastItem;
if Assigned(LastItem) then
begin
LastItem.View.ItemRectArray(LastItem, nil, nil, Item.Caption, RectArray);
if TestPt.Y > RectArray.LabelRect.Bottom - 1 then
TestPt.Y := RectArray.LabelRect.Bottom - 1;
end;
// Look for an item directly below the currently selected item
Result := OwnerGroups.ItembyPoint(TestPt);
// If not found then look to the right until we find an item
if not Assigned(Result) then
begin
Result := SearchForHitRight(Item.ColumnPos, TestPt);
while not Assigned(Result) and (TestPt.Y < OwnerGroups.ViewRect.Bottom) do
begin
Inc(TestPt.Y, CellSize.Height);
Result := SearchForHitRight(Item.ColumnPos, TestPt);
end
end
end
end
end
end;
procedure TEasyGridGroup.AutoSizeCells;
var
Item: TEasyItem;
RectArray: TEasyRectArrayObject;
ACanvas: TCanvas;
TextSize: TSize;
begin
if CellSize.AutoSize then
begin
FindLongestCaption(nil, Item);
if Assigned(Item) then
begin
ACanvas := TCanvas.Create;
try
ACanvas.Handle := GetDC(0);
Item.View.ItemRectArray(Item, nil, ACanvas, '', RectArray);
Item.View.LoadTextFont(Item, 0, ACanvas, True);
TextSize := TextExtentW(Item.Caption, ACanvas);
CellSize.AutoSizeWidth := RectWidth(RectArray.CheckRect) +
RectWidth(RectArray.IconRect) +
RectWidth(RectArray.StateRect) +
TextSize.cx + 18;
finally
ReleaseDC(0, ACanvas.Handle);
ACanvas.Handle := 0;
ACanvas.Free;
end
end
end
end;
procedure TEasyGridGroup.FindInsertPosition(ViewportPoint: TPoint; var Group: TEasyGroup; var Index: Integer);
//
// The default implementation assumes a "grid" type arrangement of the grid
//
var
Item: TEasyItem;
begin
Index := -1;
Group := OwnerGroups.GroupByPoint(ViewportPoint);
if Assigned(Group) then
begin
Item := Group.ItemByPoint(ViewportPoint);
if Assigned(Item) then
begin
if ViewportPoint.X < RectWidth( Item.DisplayRect) div 2 then
Index := Item.Index
else
Index := Item.Index + 1
end
end
end;
function TEasyGridGroup.GetMaxColumns(Group: TEasyGroup; WindowWidth: Integer): Integer;
begin
Result := (WindowWidth -
(Group.MarginLeft.RuntimeSize + Group.MarginRight.RuntimeSize)) div CellSize.Width;
if FColumnCount = 0 then
Inc(FColumnCount);
end;
function TEasyGridGroup.GetOwnerGroups: TEasyGroups;
begin
Result := OwnerGroup.OwnerGroups
end;
function TEasyGridGroup.LastItemInNColumn(Group: TEasyGroup; N: Integer): TEasyItem;
//
// Finds the last item in the group in the specified column. It assumes
// that the item does exist (N >= Group.ItemCount)
//
var
RowPos: Integer;
begin
RowPos := Group.VisibleCount div Group.Grid.ColumnCount;
if RowPos * ColumnCount + N >= Group.VisibleCount then
Dec(RowPos);
Result := Group.Items[RowPos * ColumnCount + N]
end;
function TEasyGridGroup.NextVisibleGroupWithNItems(StartGroup: TEasyGroup; N: Integer): TEasyGroup;
//
// Returns the first next group encountered when at least N items in it
//
var
i: Integer;
begin
Result := nil;
i := StartGroup.VisibleIndex + 1;
while not Assigned(Result) and (i < OwnerGroups.VisibleCount) do
begin
if OwnerGroups.VisibleGroup[i].VisibleCount > N then
Result := OwnerGroups.VisibleGroup[i];
Inc(i)
end
end;
function TEasyGridGroup.PrevVisibleGroupWithNItems(StartGroup: TEasyGroup; N: Integer): TEasyGroup;
//
// Returns the first prev group encountered when at least N items in it
//
var
i: Integer;
begin
Result := nil;
i := StartGroup.VisibleIndex - 1;
while not Assigned(Result) and (i >= 0) do
begin
if OwnerGroups.VisibleGroup[i].VisibleCount > N then
Result := OwnerGroups.VisibleGroup[i];
Dec(i)
end
end;
function TEasyGridGroup.SearchForHitRight(ColumnPos: Integer; Pt: TPoint): TEasyItem;
begin
Result := nil;
while not Assigned(Result) and (ColumnPos >= 0) do
begin
Result := OwnerGroups.ItembyPoint(Pt);
Dec(Pt.X, CellSize.Width);
Dec(ColumnPos)
end;
end;
function TEasyGridGroup.StaticTopItemMargin: Integer;
// Distance added between the bottom of the top margin and the first
// item, and the distance between the bottom of the last item and the
// top of the bottom margin
begin
Result := 0
end;
function TEasyGridGroup.StaticTopMargin: Integer;
// Distance added from top of control to the top of the first group
begin
Result := 0;
end;
procedure TEasyGridGroup.FindLongestCaption(Column: TEasyColumn; var Item: TEasyItem);
var
TempItem: TEasyItem;
ColumnIndex, i: Integer;
begin
Item := nil;
if Assigned(Column) then
ColumnIndex := Column.Index
else
ColumnIndex := 0;
// can't use enumerators here as the list is not reindexed yet
for i := 0 to OwnerGroup.Items.Count - 1 do
begin
TempItem := TEasyItem( OwnerGroup.Items[i]);
if TempItem.Visible then
begin
if not Assigned(Item) then
Item := TempItem
else begin
if Length(TempItem.Captions[ColumnIndex]) > Length(Item.Captions[ColumnIndex]) then
Item := TempItem;
end
end
end
end;
procedure TEasyGridGroup.Rebuild(PrevGroup: TEasyGroup; var NextVisibleItemIndex: Integer);
var
TopLeft: TPoint;
i, LeftEdge, BottomEdge, ItemGroupVisibleIndex: Integer;
RectArray: TEasyRectArrayObject;
WndWidth, VisibleCount, ItemMargin, GroupMargin, MarginTop, MarginLeft, MarginRight: Integer;
FocusedItem, Item: TEasyItem;
LocalCellSize: TEasyCellSize;
begin
AutoSizeCells;
BottomEdge := 0;
GroupMargin := StaticTopMargin;
ItemMargin := StaticTopItemMargin;
LocalCellSize := CellSize;
MarginLeft := OwnerGroup.MarginLeft.RuntimeSize;
MarginTop := OwnerGroup.MarginTop.RuntimeSize;
MarginRight := OwnerGroup.MarginRight.RuntimeSize;
// First calculate the Width of the group box. The height will be dynamically
// calculated during the enumeration of the items
WndWidth := OwnerListview.ClientWidth - 1;
if not OwnerListview.Scrollbars.VertBarVisible then
WndWidth := WndWidth - GetSystemMetrics(SM_CYVSCROLL);
if WndWidth < MarginRight + MarginLeft + LocalCellSize.Width then
WndWidth := MarginRight + MarginLeft + LocalCellSize.Width;
OwnerGroup.FDisplayRect := Rect(0, StaticTopMargin, WndWidth, GroupMargin);
VisibleCount := 0;
FocusedItem := nil;
// Prepare the VisibleList for the worse case, all are visible
OwnerGroup.VisibleItems.Clear;
OwnerGroup.VisibleItems.Capacity := OwnerGroup.Items.Count;
ItemGroupVisibleIndex := 0;
if OwnerGroup.Visible then
begin
if OwnerGroup.Expanded and (OwnerGroup.Items.Count > 0) then
begin
// First calculate the number of columns we can accommodate
FColumnCount := GetMaxColumns(OwnerGroup, WndWidth);
TopLeft := Point(0, 0);
LeftEdge := ColumnCount * LocalCellSize.Width;
for i := 0 to OwnerGroup.Items.Count - 1 do
begin
if TopLeft.X + LocalCellSize.Width > LeftEdge then
begin
TopLeft.X := 0;
Inc(TopLeft.Y, LocalCellSize.Height);
end;
Item := OwnerGroup.Items[i];
if Item.Visible then
begin
Item.FVisibleIndexInGroup := ItemGroupVisibleIndex;
Item.FVisibleIndex := NextVisibleItemIndex;
Inc(NextVisibleItemIndex);
Inc(ItemGroupVisibleIndex);
OwnerGroup.VisibleItems.Add(Item);
BottomEdge := TopLeft.Y + LocalCellSize.Height;
Item.FDisplayRect := Rect(TopLeft.X, TopLeft.Y, TopLeft.X + LocalCellSize.Width, BottomEdge);
Inc(TopLeft.X, LocalCellSize.Width);
Inc(VisibleCount);
end else
begin
Item.FDisplayRect := Rect(TopLeft.X, TopLeft.Y, TopLeft.X, TopLeft.Y + LocalCellSize.Height);
Item.FVisibleIndexInGroup := -1;
end;
OffsetRect(Item.FDisplayRect, MarginLeft, MarginTop + GroupMargin + ItemMargin);
if Item.Focused then
FocusedItem := Item;
if Assigned(PrevGroup) then
OffsetRect(Item.FDisplayRect, 0, PrevGroup.DisplayRect.Bottom);
end
end else
begin
// Collapsed group can't have focused item, move it to the next Visible item
FocusedItem := OwnerListview.Selection.FocusedItem;
if Assigned(FocusedItem) then
if FocusedItem.OwnerGroup = OwnerGroup then
OwnerListview.Selection.FocusedItem := Self.OwnerGroups.NextVisibleItem(FocusedItem)
end;
if ColumnCount > 0 then
FRowCount := OwnerGroup.Items.Count div ColumnCount
else
FRowCount := 0;
if ColumnCount > 0 then
if OwnerGroup.Items.Count mod ColumnCount > 0 then
Inc(FRowCount);
if OwnerGroup.Expanded then
Inc(OwnerGroup.FDisplayRect.Bottom, OwnerGroup.MarginBottom.RuntimeSize + OwnerGroup.MarginTop.RuntimeSize + BottomEdge + ItemMargin * 2)
else
Inc(OwnerGroup.FDisplayRect.Bottom, OwnerGroup.MarginBottom.RuntimeSize + OwnerGroup.MarginTop.RuntimeSize + BottomEdge)
end;
// Take care of the items in groups that are not visible or expanded
// If the Group's is not visible then its items can not be selected.
// Current it is allowed to have selected items in collapsed groups
if not OwnerGroup.Visible then
begin
i := 0;
while (i < OwnerGroup.Items.Count) and (OwnerListview.Selection.Count > 0) do
begin
OwnerGroup.Items[i].Selected := False;
Inc(i)
end;
if Assigned(OwnerListview.Selection.FocusedItem) then
if OwnerListview.Selection.FocusedItem.OwnerGroup = OwnerGroup then
OwnerListview.Selection.FocusedItem := nil;
end;
// Special case if all the items are not visible
if VisibleCount = 0 then
begin
FColumnCount := 0;
FRowCount := 0;
end;
if Assigned(PrevGroup) then
OffsetRect(OwnerGroup.FDisplayRect, 0, PrevGroup.DisplayRect.Bottom);
// Always resize the group if on the bottom the the control
if Assigned(FocusedItem) and (OwnerListview.Selection.ResizeGroupOnFocus or (OwnerGroup.Index + 1 = OwnerGroups.Count)) then
begin
FocusedItem.ItemRectArray(nil, OwnerListview.ScratchCanvas, RectArray);
if RectArray.FullTextRect.Bottom > OwnerGroup.FDisplayRect.Bottom - OwnerGroup.MarginBottom.RuntimeSize then
Inc(OwnerGroup.FDisplayRect.Bottom, RectArray.FullTextRect.Bottom - FocusedItem.DisplayRect.Bottom);
end
end;
constructor TEasyGridReportGroup.Create(AnOwner: TCustomEasyListview;
AnOwnerGroup: TEasyGroup);
begin
inherited Create(AnOwner, AnOwnerGroup);
FLayout := eglGrid
end;
function TEasyGridReportGroup.AdjacentItem(Item: TEasyItem;
Direction: TEasyAdjacentCellDir): TEasyItem;
var
TestPt: TPoint;
begin
Result := nil;
if Assigned(Item) then
begin
case Direction of
acdUp: Result := OwnerGroups.PrevVisibleItem(Item);
acdDown: Result := OwnerGroups.NextVisibleItem(Item);
acdPageUp: // WL, 05/01/05
begin
// Look for first visible item at top.
// The Makevisible offsets a bit to deal with the inplace editor
TestPt := Point(0, OwnerListview.ClientInViewportCoords.Top + V_STRINGEDITORMARGIN div 2);
repeat
Result := OwnerGroups.ItembyPoint(TestPt);
Inc(TestPt.Y, CellSize.Height);
until (Result <> nil) or (Result = Item) or (TestPt.Y >= OwnerListview.ClientInViewportCoords.Bottom);
// If first visible item is the parameter Item already we must look one
// page further up. Find the furthest item which still allows Result
// and item to be on one page.
if (Result <> nil) and (Result = Item) then
begin
TestPt := Point(0, Item.DisplayRect.Bottom - RectHeight(OwnerListview.ClientInViewportCoords) - 1);
repeat
Result := OwnerGroups.ItembyPoint(TestPt);
Inc(TestPt.Y, CellSize.Height);
until Result <> nil; // loop terminates at Item at the latest (which must be below)
if Result = Item then
Result := nil; // no adjacent page-down item found, Item was already the first one
end;
end;
acdPageDown: // WL, 05/01/05
begin
// Look for last visible item at bottom.
// The Makevisible offsets a bit to deal with the inplace editor
TestPt := Point(0, OwnerListview.ClientInViewportCoords.Bottom - 1 - V_STRINGEDITORMARGIN div 2);
repeat
Result := OwnerGroups.ItembyPoint(TestPt);
Dec(TestPt.Y, CellSize.Height);
until (Result <> nil) or (Result = Item) or (TestPt.Y < OwnerListview.ClientInViewportCoords.Top);
// If last visible item is the parameter Item already we must look one
// page further down. Find the furthest item which still allows Result
// and item to be on one page.
if (Result <> nil) and (Result = Item) then
begin
TestPt := Point(0, Item.DisplayRect.Top + RectHeight(OwnerListview.ClientInViewportCoords) - 1);
repeat
Result := OwnerGroups.ItembyPoint(TestPt);
Dec(TestPt.Y, CellSize.Height);
until Result <> nil; // loop terminates at Item at the latest (which must be above)
if Result = Item then
Result := nil; // no adjacent page-down item found, Item was already the last one
end;
end
else
Result := inherited AdjacentItem(Item, Direction);
end
end
end;
procedure TEasyGridReportGroup.FindInsertPosition(ViewportPoint: TPoint; var Group: TEasyGroup; var Index: Integer);
begin
end;
function TEasyGridReportGroup.GetCellSize: TEasyCellSize;
begin
Result := OwnerListview.CellSizes.Report
end;
{ TEasyReportGroupGrid }
procedure TEasyGridReportGroup.Rebuild(PrevGroup: TEasyGroup; var NextVisibleItemIndex: Integer);
var
i, Top, Bottom, Width, Left, Offset, TopMargin,
BottomMargin, VisibleCount: Integer;
Item: TEasyItem;
begin
AutoSizeCells;
if CellSize.AutoSize and (OwnerListview.Header.Columns.Count > 0) then
OwnerListview.Header.Columns[0].Width := CellSize.Width;
if Assigned(PrevGroup) then
Offset := PrevGroup.DisplayRect.Bottom
else
Offset := V_STRINGEDITORMARGIN;
OwnerGroup.FDisplayRect := Rect(0, Offset, OwnerListview.Header.ViewWidth, Offset);
// Prepare the VisibleList for the worse case, all are visible
OwnerGroup.VisibleItems.Clear;
OwnerGroup.VisibleItems.Capacity := OwnerGroup.Items.Count;
Left := OwnerGroup.MarginLeft.RuntimeSize;
if OwnerListview.Header.LastColumnByPosition <> nil then
begin
Width := OwnerListview.Header.LastColumnByPosition.DisplayRect.Right;
Width := Width - OwnerGroup.MarginRight.RuntimeSize
end else
Width := 0;
TopMargin := OwnerGroup.MarginTop.RuntimeSize;
BottomMargin := OwnerGroup.MarginBottom.RuntimeSize;
if OwnerGroup.Visible then
begin
if OwnerGroup.Expanded and (OwnerGroup.Items.Count > 0) then
begin
VisibleCount := 0;
Top := Offset + TopMargin;
Bottom := Offset + CellSize.Height + TopMargin;
for i := 0 to OwnerGroup.Items.Count - 1 do
begin
Item := OwnerGroup.Items.List.List[i]; // Direct Access for Speed
if Item.Visible then
begin
Item.FVisibleIndex := NextVisibleItemIndex;
Item.FVisibleIndexInGroup := VisibleCount;
Item.FDisplayRect := Rect(Left, Top, Width, Bottom);
OwnerGroup.VisibleItems.Add(Item);
Inc(Top, CellSize.Height);
Inc(Bottom, CellSize.Height);
Inc(VisibleCount);
Inc(NextVisibleItemIndex);
end else
Item.FDisplayRect := Rect(Left, Top, Width, Top);
OwnerGroup.FDisplayRect.Bottom := Item.FDisplayRect.Bottom + BottomMargin;
if OwnerGroups.LastGroup = OwnerGroup then
OwnerGroup.FDisplayRect.Bottom := Item.FDisplayRect.Bottom + V_STRINGEDITORMARGIN * 2;
end
end else
OwnerGroup.FDisplayRect := Rect(0, Offset, OwnerListview.Header.ViewWidth, Offset + TopMargin + BottomMargin);
end;
// Column Count does not relate to Report view columns. It is a more primitive
// and the Report columns are within the Grid Column
FColumnCount := 1;
end;
procedure TEasyGridReportGroup.SetCellSize(Value: TEasyCellSize);
begin
OwnerListview.CellSizes.Report.Assign(Value)
end;
constructor TEasyGridListGroup.Create(AnOwner: TCustomEasyListview; AnOwnerGroup: TEasyGroup);
begin
inherited Create(AnOwner, AnOwnerGroup);
FLayout := eglHorz
end;
function TEasyGridListGroup.AdjacentItem(Item: TEasyItem;
Direction: TEasyAdjacentCellDir): TEasyItem;
function NextVisibleGroupWithNItems(StartGroup: TEasyGroup; N: Integer): TEasyGroup;
//
// Returns the first next group encountered when at least N items in it
//
var
i: Integer;
begin
Result := nil;
i := StartGroup.VisibleIndex + 1;
while not Assigned(Result) and (i < OwnerGroups.VisibleCount) do
begin
if OwnerGroups.VisibleGroup[i].VisibleCount > N then
Result := OwnerGroups.VisibleGroup[i];
Inc(i)
end
end;
function PrevVisibleGroupWithNItems(StartGroup: TEasyGroup; N: Integer): TEasyGroup;
//
// Returns the first prev group encountered when at least N items in it
//
var
i: Integer;
begin
Result := nil;
i := StartGroup.VisibleIndex - 1;
while not Assigned(Result) and (i >= 0) do
begin
if OwnerGroups.VisibleGroup[i].VisibleCount > N then
Result := OwnerGroups.VisibleGroup[i];
Dec(i)
end
end;
function LastItemInNRow(Group: TEasyGroup; N: Integer): TEasyItem;
//
// Finds the last item in the group in the specified column. It assumes
// that the item does exist (N >= Group.ItemCount)
//
var
ColumnPos: Integer;
begin
ColumnPos := Group.VisibleCount div Group.Grid.RowCount;
if ColumnPos * RowCount + N >= Group.VisibleCount then
Dec(ColumnPos);
Result := Group.Items[ColumnPos * RowCount + N]
end;
function SearchForHitRight(ColumnPos: Integer; Pt: TPoint): TEasyItem;
begin
Result := nil;
while not Assigned(Result) and (ColumnPos >= 0) do
begin
Result := OwnerGroups.ItembyPoint(Pt);
Dec(Pt.X, CellSize.Width);
Dec(ColumnPos)
end;
end;
var
RowPos, ItemIndex: Integer;
AdjacentGroup: TEasyGroup;
begin
Result := nil;
if Assigned(Item) then
begin
Assert(Item.Visible, 'Can not find TEasyGroups.AdjacentItem of an Invisible Item');
case Direction of
acdUp:
begin
Result := Item;
if Item.VisibleIndexInGroup > 0 then
Result := OwnerGroup.VisibleItem[Item.VisibleIndexInGroup - 1]
else begin
AdjacentGroup := PrevVisibleGroupWithNItems(OwnerGroup, 0);
if Assigned(AdjacentGroup) then
Result := AdjacentGroup.VisibleItem[AdjacentGroup.VisibleCount - 1]
end
end;
acdDown:
begin
Result := Item;
if Item.VisibleIndexInGroup < OwnerGroup.VisibleCount - 1 then
Result := OwnerGroup.VisibleItem[Item.VisibleIndexInGroup + 1]
else begin
AdjacentGroup := NextVisibleGroupWithNItems(OwnerGroup, 0);
if Assigned(AdjacentGroup) then
Result := AdjacentGroup.VisibleItem[0]
end
end;
acdLeft:
begin
// First see if we can stay in the same group
if Item.VisibleIndexInGroup - RowCount >= 0 then
Result := OwnerGroup.VisibleItems[Item.VisibleIndexInGroup - RowCount]
else begin
RowPos := Item.RowPos;
while not Assigned(Result) and (RowPos > -1) do
begin
AdjacentGroup := PrevVisibleGroupWithNItems(OwnerGroup, RowPos);
if Assigned(AdjacentGroup) then
Result := LastItemInNRow(AdjacentGroup, RowPos);
Dec(RowPos)
end
end
end;
acdRight:
begin
// First see if we can stay in the same group
if Item.VisibleIndexInGroup + RowCount < OwnerGroup.VisibleCount then
Result := OwnerGroup.VisibleItems[Item.VisibleIndexInGroup + RowCount]
else begin
RowPos := Item.RowPos;
while not Assigned(Result) and (RowPos > -1) do
begin
AdjacentGroup := NextVisibleGroupWithNItems(OwnerGroup, RowPos);
if Assigned(AdjacentGroup) then
Result := AdjacentGroup.VisibleItem[RowPos];
Dec(RowPos)
end
end
end;
acdPageUp:
begin
ItemIndex := Item.VisibleIndexInGroup;
while (ItemIndex > 0) and (ItemIndex mod RowCount <> 0) do
Dec(ItemIndex);
Result := OwnerGroup.Items[ItemIndex]
end;
acdPageDown:
begin
ItemIndex := Item.VisibleIndexInGroup;
while (ItemIndex < Item.OwnerGroup.Items.Count - 1) and (ItemIndex mod RowCount <> RowCount - 1) do
Inc(ItemIndex);
Result := OwnerGroup.Items[ItemIndex]
end
end
end
end;
procedure TEasyGridListGroup.FindInsertPosition(ViewportPoint: TPoint; var Group: TEasyGroup; var Index: Integer);
begin
end;
function TEasyGridListGroup.GetCellSize: TEasyCellSize;
begin
Result := OwnerListview.CellSizes.List
end;
{ TEasyListGroupGrid }
procedure TEasyGridListGroup.Rebuild(PrevGroup: TEasyGroup;
var NextVisibleItemIndex: Integer);
var
ScrollSize, ClientHeight: Integer;
TopLeft: TPoint;
i, Offset, VisibleCount, Height: Integer;
RectArray: TEasyRectArrayObject;
TextSize: TSize;
R: TRect;
Item: TEasyItem;
begin
AutoSizeCells;
VisibleCount := 0;
// Always assume a scroll bar
ScrollSize := GetSystemMetrics(SM_CXHSCROLL);
ClientHeight := OwnerListview.ClientHeight;
if Assigned(PrevGroup) then
Offset := PrevGroup.DisplayRect.Right
else
Offset := 0;
Height := ClientHeight - ScrollSize - OwnerListview.Header.RuntimeHeight;
// May have to show a vertical scrollbar if the entire thing won't fit in the window
if Height < OwnerGroup.MarginBottom.RuntimeSize + OwnerGroup.MarginTop.RuntimeSize + CellSize.Height then
Height := OwnerGroup.MarginBottom.RuntimeSize + OwnerGroup.MarginTop.RuntimeSize + CellSize.Height;
OwnerGroup.FDisplayRect := Rect(Offset, 0, Offset, Height);
// Prepare the VisibleList for the worse case, all are visible
OwnerGroup.VisibleItems.Clear;
OwnerGroup.VisibleItems.Capacity := OwnerGroup.Items.Count;
if OwnerGroup.Visible then
begin
if OwnerGroup.Expanded and (OwnerGroup.Items.Count > 0) then
begin
// First calculate the number of rows we can accommodate
FRowCount := (Height - 1 - (OwnerGroup.MarginBottom.RuntimeSize + OwnerGroup.MarginTop.RuntimeSize)) div CellSize.Height;
if FRowCount = 0 then
Inc(FRowCount);
FColumnCount := 1;
TopLeft := Point(Offset + OwnerGroup.MarginLeft.RuntimeSize, OwnerGroup.MarginTop.RuntimeSize);
for i := 0 to OwnerGroup.Items.Count - 1 do
begin
Item := OwnerGroup.Items[i];
if Item.Visible then
begin
Item.FVisibleIndex := NextVisibleItemIndex;
Item.FVisibleIndexInGroup := VisibleCount;
OwnerGroup.VisibleItems.Add(Item);
R := Rect(TopLeft.X, TopLeft.Y, TopLeft.X + CellSize.Width, TopLeft.Y + CellSize.Height);
Inc(TopLeft.Y, CellSize.Height);
Inc(VisibleCount)
end else
R := Rect(TopLeft.X, TopLeft.Y, TopLeft.X, TopLeft.Y + CellSize.Height);
if R.Bottom > Height - OwnerGroup.MarginBottom.RuntimeSize then
begin
OffsetRect(R, CellSize.Width, -(TopLeft.Y - CellSize.Height - OwnerGroup.MarginTop.RuntimeSize));
TopLeft.Y := OwnerGroup.MarginTop.RuntimeSize + CellSize.Height;
Inc(TopLeft.X, CellSize.Width);
Inc(FColumnCount);
end;
OwnerGroup.Items[i].FDisplayRect := R
end;
OwnerGroup.FDisplayRect.Right := TopLeft.X + CellSize.Width + OwnerGroup.MarginRight.RuntimeSize;
end;
// Special case if all the items are not visible
if VisibleCount = 0 then
begin
TextSize := TextExtentW(OwnerGroup.Caption, OwnerListview.GroupFont);
OwnerGroup.View.GroupRectArray(OwnerGroup, egmeTop, OwnerGroup.BoundsRectTopMargin, RectArray);
FColumnCount := 0;
FRowCount := 0;
OwnerGroup.FDisplayRect.Right := OwnerGroup.MarginLeft.RuntimeSize +
OwnerGroup.MarginRight.RuntimeSize + RectArray.IconRect.Right +
OwnerGroup.CaptionIndent + TextSize.cx;
end;
end;
end;
procedure TEasyGridListGroup.SetCellSize(Value: TEasyCellSize);
begin
OwnerListview.CellSizes.List.Assign(Value)
end;
{ TEasyFooterMargin }
constructor TCustomEasyFooterMargin.Create(AnOwner: TCustomEasyListview);
begin
inherited;
FImageIndex := -1;
FImageOverlayIndex := -1;
FSize := 30;
end;
destructor TCustomEasyFooterMargin.Destroy;
begin
FreeAndNil(FPaintInfo);
inherited;
end;
function TCustomEasyFooterMargin.GetAlignment: TAlignment;
begin
Result := PaintInfo.Alignment
end;
function TCustomEasyFooterMargin.GetCaptionIndent: Integer;
begin
Result := PaintInfo.CaptionIndent
end;
function TCustomEasyFooterMargin.GetCaptionLines: Integer;
begin
Result := PaintInfo.CaptionLines
end;
function TCustomEasyFooterMargin.GetImageIndent: Integer;
begin
Result := PaintInfo.ImageIndent
end;
function TCustomEasyFooterMargin.GetPaintInfo: TEasyPaintInfoBaseGroup;
begin
if not Assigned(FPaintInfo) then
Result := OwnerListview.PaintInfoGroup.MarginBottom.FPaintInfo
else
Result := FPaintInfo
end;
function TCustomEasyFooterMargin.GetVAlignment: TCommonVAlignment;
begin
Result := PaintInfo.VAlignment
end;
procedure TCustomEasyFooterMargin.Assign(Source: TPersistent);
var
Temp: TCustomEasyFooterMargin;
begin
inherited Assign(Source);
if Source is TCustomEasyFooterMargin then
begin
Temp := TCustomEasyFooterMargin(Source);
FCaption := Temp.Caption;
end
end;
procedure TCustomEasyFooterMargin.SetAlignment(Value: TAlignment);
begin
if Alignment <> Value then
begin
PaintInfo.Alignment := Value;
OwnerListview.Groups.Rebuild
end;
end;
procedure TCustomEasyFooterMargin.SetCaption(Value: WideString);
begin
if FCaption <> Value then
begin
FCaption := Value;
OwnerListview.Groups.Rebuild
end;
end;
procedure TCustomEasyFooterMargin.SetCaptionIndent(Value: Integer);
begin
if CaptionIndent <> Value then
begin
PaintInfo.CaptionIndent := Value;
OwnerListview.SafeInvalidateRect(nil, False)
end
end;
procedure TCustomEasyFooterMargin.SetCaptionLines(Value: Integer);
begin
if CaptionLines <> Value then
begin
PaintInfo.CaptionLines := Value;
OwnerListview.SafeInvalidateRect(nil, False)
end
end;
procedure TCustomEasyFooterMargin.SetImageIndent(Value: Integer);
begin
if ImageIndent <> Value then
begin
PaintInfo.ImageIndent := Value;
OwnerListview.SafeInvalidateRect(nil, False)
end
end;
procedure TCustomEasyFooterMargin.SetImageIndex(const Value: TCommonImageIndexInteger);
begin
if FImageIndex <> Value then
begin
FImageIndex := Value;
OwnerListview.SafeInvalidateRect(nil, False)
end
end;
procedure TCustomEasyFooterMargin.SetImageOveralyIndex(const Value: TCommonImageIndexInteger);
begin
if FImageOverlayIndex <> Value then
begin
FImageOverlayIndex := Value;
OwnerListview.SafeInvalidateRect(nil, False)
end
end;
procedure TCustomEasyFooterMargin.SetPaintInfo(const Value: TEasyPaintInfoBaseGroup);
begin
if not Assigned(FPaintInfo) then
OwnerListview.PaintInfoGroup.Assign(Value)
else
FPaintInfo.Assign(Value)
end;
procedure TCustomEasyFooterMargin.SetVAlignment(
Value: TCommonVAlignment);
begin
if VAlignment <> Value then
begin
PaintInfo.VAlignment := Value;
OwnerListview.SafeInvalidateRect(nil, False)
end;
end;
{ TEasyBasicItemPaintInfo }
constructor TEasyPaintInfoBasic.Create(AnOwner: TCustomEasyListview);
begin
inherited Create(AnOwner);
FImageIndent := 2;
FCaptionIndent := 4;
FCaptionLines := 1;
FBorder := 4;
FBorderColor := clHighlight;
FCheckIndent := 2;
FChecksize := 12;
FVAlignment := cvaCenter;
FShowBorder := True;
end;
procedure TEasyPaintInfoBasic.Assign(Source: TPersistent);
var
Temp: TEasyPaintInfoBasic;
begin
if Source is TEasyPaintInfoBasic then
begin
Temp := TEasyPaintInfoBasic(Source);
FAlignment := Temp.Alignment;
FBorder := Temp.Border;
FBorderColor := Temp.BorderColor;
FCaptionIndent := Temp.CaptionIndent;
FCaptionLines := Temp.CaptionLines;
FCheckFlat := Temp.CheckFlat;
FCheckIndent := Temp.CheckIndent;
FChecksize := Temp.Checksize;
FCheckType := Temp.CheckType;
FImageIndent := Temp.ImageIndent;
FVAlignment := Temp.VAlignment;
end
end;
procedure TEasyPaintInfoBasic.Invalidate(ImmediateUpdate: Boolean);
begin
OwnerListview.SafeInvalidateRect(nil, ImmediateUpdate)
end;
procedure TEasyPaintInfoBasic.SetAlignment(Value: TAlignment);
begin
if Value <> FAlignment then
begin
FAlignment := Value;
Invalidate(False)
end
end;
procedure TEasyPaintInfoBasic.SetBorder(Value: Integer);
begin
if Value <> FBorder then
begin
FBorder := Value;
Invalidate(False)
end
end;
procedure TEasyPaintInfoBasic.SetBorderColor(Value: TColor);
begin
if Value <> FBorderColor then
begin
FBorderColor := Value;
Invalidate(False)
end
end;
procedure TEasyPaintInfoBasic.SetCaptionIndent(Value: Integer);
begin
if Value <> FCaptionIndent then
begin
FCaptionIndent := Value;
Invalidate(False)
end
end;
procedure TEasyPaintInfoBasic.SetCaptionLines(Value: Integer);
begin
if Value <> FCaptionLines then
begin
FCaptionLines := Value;
Invalidate(False)
end
end;
procedure TEasyPaintInfoBasic.SetCheckFlat(Value: Boolean);
begin
if Value <> FCheckFlat then
begin
FCheckFlat := Value;
Invalidate(False)
end
end;
procedure TEasyPaintInfoBasic.SetCheckIndent(Value: Integer);
begin
if Value <> FCheckIndent then
begin
FCheckIndent := Value;
Invalidate(False)
end
end;
procedure TEasyPaintInfoBasic.SetChecksize(Value: Integer);
begin
if Value <> FChecksize then
begin
FChecksize := Value;
Invalidate(False)
end
end;
procedure TEasyPaintInfoBasic.SetCheckType(Value: TEasyCheckType);
begin
if Value <> FCheckType then
begin
FCheckType := Value;
Invalidate(False)
end
end;
procedure TEasyPaintInfoBasic.SetImageIndent(Value: Integer);
begin
if Value <> FImageIndent then
begin
FImageIndent := Value;
Invalidate(False)
end
end;
procedure TEasyPaintInfoBasic.SetShowBorder(const Value: Boolean);
begin
FShowBorder := Value;
end;
procedure TEasyPaintInfoBasic.SetVAlignment(Value: TCommonVAlignment);
begin
if Value <> FVAlignment then
begin
FVAlignment := Value;
Invalidate(False)
end
end;
{ TEasyBasicGroupPaintInfo }
constructor TEasyPaintInfoBaseGroup.Create(AnOwner: TCustomEasyListview);
begin
inherited Create(AnOwner);
FBandBlended := True;
FBandColor := clBlue;
FBandColorFade := clWindow;
FBandEnabled := True;
FBandLength := 300;
FBandMargin := 2;
FBandRadius := 4;
FBandThickness := 3;
FExpandable := True;
FExpanded := True;
FExpandImageIndent := 4;
FMarginBottom := TEasyFooterMargin.Create(AnOwner);
FMarginLeft := TEasyMargin.Create(AnOwner);
FMarginRight := TEasyMargin.Create(AnOwner);
FMarginTop := TEasyHeaderMargin.Create(AnOwner);
end;
destructor TEasyPaintInfoBaseGroup.Destroy;
begin
inherited;
FreeAndNil(FMarginBottom);
FreeAndNil(FMarginLeft);
FreeAndNil(FMarginRight);
FreeAndNil(FMarginTop);
end;
function TEasyPaintInfoBaseGroup.GetMarginBottom: TCustomEasyFooterMargin;
begin
Result := FMarginBottom
end;
function TEasyPaintInfoBaseGroup.GetMarginLeft: TEasyMargin;
begin
Result := FMarginLeft
end;
function TEasyPaintInfoBaseGroup.GetMarginRight: TEasyMargin;
begin
Result := FMarginRight
end;
function TEasyPaintInfoBaseGroup.GetMarginTop: TEasyHeaderMargin;
begin
Result := FMarginTop
end;
procedure TEasyPaintInfoBaseGroup.Assign(Source: TPersistent);
var
Temp: TEasyPaintInfoBaseGroup;
begin
inherited Assign(Source);
if Source is TEasyPaintInfoBaseGroup then
begin
Temp := TEasyPaintInfoBaseGroup(Source);
FBandBlended := Temp.BandBlended;
FBandColor := Temp.BandColor;
FBandColorFade := Temp.BandColorFade;
FBandEnabled := Temp.BandEnabled;
FBandFullWidth := Temp.BandFullWidth;
FBandIndent := Temp.BandIndent;
FBandLength := Temp.BandLength;
FBandMargin := Temp.BandMargin;
FBandRadius := Temp.BandRadius;
FBandThickness := Temp.BandThickness;
FExpandable := Temp.Expandable;
FExpandImageIndent := Temp.ExpandImageIndent;
MarginBottom.Assign(Temp.MarginBottom);
MarginLeft.Assign(Temp.MarginLeft);
MarginRight.Assign(Temp.MarginRight);
MarginTop.Assign(Temp.MarginTop);
end
end;
procedure TEasyPaintInfoBaseGroup.SetBandBlended(Value: Boolean);
begin
if Value <> FBandBlended then
begin
FBandBlended := Value;
Invalidate(False)
end
end;
procedure TEasyPaintInfoBaseGroup.SetBandColor(Value: TColor);
begin
if Value <> FBandColor then
begin
FBandColor := Value;
Invalidate(False)
end
end;
procedure TEasyPaintInfoBaseGroup.SetBandColorFade(Value: TColor);
begin
if Value <> FBandColorFade then
begin
FBandColorFade := Value;
Invalidate(False)
end
end;
procedure TEasyPaintInfoBaseGroup.SetBandEnabled(Value: Boolean);
begin
if Value <> FBandEnabled then
begin
FBandEnabled := Value;
Invalidate(False)
end
end;
procedure TEasyPaintInfoBaseGroup.SetBandFullWidth(Value: Boolean);
begin
if Value <> FBandFullWidth then
begin
FBandFullWidth := Value;
Invalidate(False)
end
end;
procedure TEasyPaintInfoBaseGroup.SetBandIndent(Value: Integer);
begin
if Value <> FBandIndent then
begin
FBandIndent := Value;
Invalidate(False)
end
end;
procedure TEasyPaintInfoBaseGroup.SetBandLength(Value: Integer);
begin
if Value <> FBandLength then
begin
FBandLength := Value;
Invalidate(False)
end
end;
procedure TEasyPaintInfoBaseGroup.SetBandMargin(Value: Integer);
begin
if Value <> FBandMargin then
begin
FBandMargin := Value;
Invalidate(False)
end
end;
procedure TEasyPaintInfoBaseGroup.SetBandRadius(Value: Byte);
begin
if Value <> FBandRadius then
begin
FBandRadius := Value;
Invalidate(False)
end
end;
procedure TEasyPaintInfoBaseGroup.SetBandThickness(Value: Integer);
begin
if Value <> FBandThickness then
begin
FBandThickness := Value;
Invalidate(False)
end
end;
procedure TEasyPaintInfoBaseGroup.SetExpandable(Value: Boolean);
begin
if Value <> FExpandable then
begin
FExpandable := Value;
Invalidate(False)
end
end;
procedure TEasyPaintInfoBaseGroup.SetExpandImageIndent(Value: Integer);
begin
if Value <> FExpandImageIndent then
begin
FExpandImageIndent := Value;
Invalidate(False)
end
end;
procedure TEasyPaintInfoBaseGroup.SetMarginBottom(
Value: TCustomEasyFooterMargin);
begin
if Value <> FMarginBottom then
begin
FreeAndNil(FMarginBottom);
FMarginBottom := Value
end
end;
procedure TEasyPaintInfoBaseGroup.SetMarginLeft(Value: TEasyMargin);
begin
if Value <> FMarginLeft then
begin
FreeAndNil(FMarginLeft);
FMarginLeft := Value
end
end;
procedure TEasyPaintInfoBaseGroup.SetMarginRight(Value: TEasyMargin);
begin
if Value <> FMarginRight then
begin
FreeAndNil(FMarginRight);
FMarginRight := Value
end
end;
procedure TEasyPaintInfoBaseGroup.SetMarginTop(Value: TEasyHeaderMargin);
begin
if Value <> FMarginTop then
begin
FreeAndNil(FMarginTop);
FMarginTop := Value
end
end;
{ TEasyHotTrackManager}
constructor TEasyHotTrackManager.Create(AnOwner: TCustomEasyListview);
begin
inherited Create(AnOwner);
FColor := clHighlight;
FUnderLine := True;
FCursor := crHandPoint;
FGroupTrack := [htgIcon, htgText];
FItemTrack := [htiIcon, htiText];
FColumnTrack := [htcIcon, htcText]
end;
function TEasyHotTrackManager.GetPendingObject(MousePos: TPoint): TEasyCollectionItem;
begin
Result := FPendingObject
end;
procedure TEasyHotTrackManager.SetPendingObject(MousePos: TPoint; Value: TEasyCollectionItem);
var
TempOldItem: TEasyCollectionItem;
OldCapture: HWnd;
begin
if FPendingObject <> Value then
begin
TempOldItem := FPendingObject;
FPendingObject := nil;
if Enabled or (Value = nil) then
begin
if Assigned(OwnerListview) and OwnerListview.HandleAllocated then
begin
// Make sure the hot track will end
if Assigned(Value) then
Mouse.Capture := OwnerListview.Handle
else
if Mouse.Capture = OwnerListview.Handle then
Mouse.Capture := 0;
// Cursor only works if no Window is captured
OldCapture := Mouse.Capture;
Mouse.Capture := 0;
if Assigned(Value) then
OwnerListview.Cursor := Cursor
else
OwnerListview.Cursor := crDefault;
Mouse.Capture := OldCapture;
end
end;
// PendingObject must be nil when this is executed
// Always fire the event for custom hottracking
if Assigned(TempOldItem) then
TempOldItem.HotTracking[MousePos] := False;
FPendingObject := Value;
if Assigned(FPendingObject) then
FPendingObject.HotTracking[MousePos] := True;
end
end;
procedure TEasyHotTrackManager.SetPendingObjectCheck(const Value: TEasyCollectionItem);
begin
if Value <> FPendingObjectCheck then
begin
if Assigned(FPendingObjectCheck) then
FPendingObjectCheck.CheckHovering := False;
FPendingObjectCheck := Value;
if Assigned(FPendingObjectCheck) then
FPendingObjectCheck.CheckHovering := True;
end
end;
{ TEasyPaintInfoBaseColumn }
constructor TEasyPaintInfoBaseColumn.Create(AnOwner: TCustomEasyListview);
begin
inherited;
FColor := clBtnFace;
FSortGlyphAlign := esgaRight;
FSortGlyphIndent := 2;
FHotTrack := True;
FStyle := ehbsThick;
FImagePosition := ehpLeft;
FHilightFocusedColor := $00F7F7F7;
end;
procedure TEasyPaintInfoBaseColumn.SetColor(Value: TColor);
begin
if Value <> FColor then
begin
FColor := Value;
OwnerListview.Header.Invalidate(False);
end
end;
procedure TEasyPaintInfoBaseColumn.SetHilightFocused(const Value: Boolean);
begin
if FHilightFocused <> Value then
begin
FHilightFocused := Value;
if Assigned(OwnerListview) then
OwnerListview.SafeInvalidateRect(nil, False)
end
end;
procedure TEasyPaintInfoBaseColumn.SetHilightFocusedColor(const Value: TColor);
begin
if FHilightFocusedColor <> Value then
begin
FHilightFocusedColor := Value;
if Assigned(OwnerListview) then
OwnerListview.SafeInvalidateRect(nil, False)
end
end;
procedure TEasyPaintInfoBaseColumn.SetImagePosition(Value: TEasyHeaderImagePosition);
begin
if Value <> FImagePosition then
begin
FImagePosition := Value;
OwnerListview.Header.Invalidate(False);
end
end;
procedure TEasyPaintInfoBaseColumn.SetSortGlpyhAlign(Value: TEasySortGlyphAlign);
begin
if Value <> FSortGlyphAlign then
begin
FSortGlyphAlign := Value;
OwnerListview.Header.Invalidate(False);
end
end;
procedure TEasyPaintInfoBaseColumn.SetSortGlyphIndent(Value: Integer);
begin
if Value <> FSortGlyphIndent then
begin
FSortGlyphIndent := Value;
OwnerListview.Header.Invalidate(False)
end
end;
procedure TEasyPaintInfoBaseColumn.SetStyle(Value: TEasyHeaderButtonStyle);
begin
if Value <> FStyle then
begin
FStyle := Value;
OwnerListview.Header.Invalidate(False)
end
end;
{ TEasyViewReportItem}
function TEasyViewReportItem.AllowDrag(Item: TEasyItem; ViewportPoint: TPoint): Boolean;
var
RectArray: TEasyRectArrayObject;
R: TRect;
begin
if FullRowSelect then
begin
ItemRectArray(Item, nil, OwnerListview.ScratchCanvas, Item.Caption, RectArray);
UnionRect(R, RectArray.TextRect, RectArray.IconRect);
if Item.Selected and Windows.PtInRect(R, ViewportPoint) then
Result := True
else
Result := False
end else
Result := inherited AllowDrag(Item, ViewportPoint);
end;
function TEasyViewReportItem.CalculateDisplayRect(Item: TEasyItem;
Column: TEasyColumn): TRect;
begin
Result := Item.DisplayRect;
if Assigned(Column) then
begin
Result.Left := Column.DisplayRect.Left;
Result.Right := Column.DisplayRect.Right;
if Column.Position = 0 then
Result.Left := Item.OwnerGroup.MarginLeft.RuntimeSize;
if Column.Position = Column.OwnerColumns.Count - 1 then
Result.Right := Result.Right - Item.OwnerGroup.MarginRight.RuntimeSize
end
end;
function TEasyViewReportItem.ExpandTextR(Item: TEasyItem; RectArray: TEasyRectArrayObject; SelectType: TEasySelectHitType): TRect;
begin
Result := inherited ExpandTextR(Item, RectArray, SelectType);
// If dragging and dropping only concider the basic ReportView item as the drop target.
if FullRowSelect and not Assigned(OwnerListview.DragManager.DragItem) {and (SelectType = eshtClickselect)} then
begin
Result.Left := Item.OwnerGroup.MarginLeft.RunTimeSize;
Result.Right := Item.DisplayRect.Right;
end
end;
function TEasyViewReportItem.FullRowSelect: Boolean;
begin
Result := False;
if Assigned(OwnerListview) then
Result := OwnerListview.Selection.FullRowSelect
end;
function TEasyViewReportItem.PaintStateImage: Boolean;
begin
Result := True
end;
function TEasyViewReportItem.SelectionHit(Item: TEasyItem; SelectViewportRect: TRect; SelectType: TEasySelectHitType): Boolean;
var
R: TRect;
RectArray: TEasyRectArrayObject;
begin
Result := False;
if Item.Enabled and not IsRectEmpty(SelectViewportRect) then
begin
// Selection is always based on the first column
ItemRectArray(Item, OwnerListview.Header.FirstColumn, OwnerListview.ScratchCanvas, '', RectArray);
Result := IntersectRect(R, SelectViewportRect, ExpandTextR(Item, RectArray, SelectType)) or
IntersectRect(R, SelectViewportRect, ExpandIconR(Item, RectArray, SelectType))
end
end;
function TEasyViewReportItem.SelectionHitPt(Item: TEasyItem; ViewportPoint: TPoint; SelectType: TEasySelectHitType): Boolean;
var
RectArray: TEasyRectArrayObject;
begin
Result := False;
if Item.Enabled then
begin
// Selection is always based on the first column
ItemRectArray(Item, OwnerListview.Header.FirstColumn, OwnerListview.ScratchCanvas, '', RectArray);
Result := Windows.PtInRect(ExpandTextR(Item, RectArray, SelectType), ViewportPoint) or
Windows.PtInRect(ExpandIconR(Item, RectArray, SelectType), ViewportPoint)
end
end;
{ TEasyHintWindow }
constructor TEasyHintWindow.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
{$IFDEF GXDEBUG_HINT}
SendDebug('TEasyHintWindow.Create');
{$ENDIF GXDEBUG_HINT}
end;
destructor TEasyHintWindow.Destroy;
begin
{$IFDEF GXDEBUG_HINT}
SendDebug('TEasyHintWindow.Destroy');
{$ENDIF GXDEBUG_HINT}
inherited Destroy;
end;
procedure TEasyHintWindow.ActivateHint(ARect: TRect; const AHint: string);
begin
{$IFDEF GXDEBUG_HINT}
SendDebug('TEasyHintWindow.ActivateHint');
{$ENDIF GXDEBUG_HINT}
inherited;
end;
procedure TEasyHintWindow.ActivateHintData(ARect: TRect;
const AHint: string; AData: Pointer);
begin
{$IFDEF GXDEBUG_HINT}
SendDebug('TEasyHintWindow.ActivateHintData');
{$ENDIF GXDEBUG_HINT}
inherited;
end;
function TEasyHintWindow.CalcHintRect(MaxWidth: Integer;
const AHint: string; AData: Pointer): TRect;
var
TextFlags: TCommonDrawTextWFlags;
begin
{$IFDEF GXDEBUG_HINT}
SendDebug('TEasyHintWindow.CalcHintRect');
{$ENDIF GXDEBUG_HINT}
// We passed in our HintInfo through the AData parameter
HintInfo := PEasyHintInfoRec(AData);
EasyHintInfo := HintInfo.Listview.HintInfo;
EasyHintInfo.FCanvas := Canvas;
EasyHintInfo.FHintType := HintInfo.HintType;
EasyHintInfo.FText := HintInfo.HintStr;
EasyHintInfo.FColor := HintInfo.HintColor;
EasyHintInfo.FCursorPos := HintInfo.CursorPos;
EasyHintInfo.FHideTimeout := HintInfo.HideTimeout;
EasyHintInfo.FMaxWidth := HintInfo.HintMaxWidth;
EasyHintInfo.FReshowTimeout := HintInfo.ReshowTimeout;
EasyHintInfo.FWindowPos := HintInfo.HintPos;
EasyHintInfo.FBounds := Rect(0, 0, MaxWidth, 0);
HintInfo.Listview.DoHintCustomInfo(HintInfo.TargetObj, EasyHintInfo);
HintInfo.HintStr := FEasyHintInfo.Text;
HintInfo.HintType := EasyHintInfo.FHintType;
HintInfo.HintColor := EasyHintInfo.FColor;
HintInfo.CursorPos := EasyHintInfo.FCursorPos;
HintInfo.HideTimeout := EasyHintInfo.FHideTimeout;
HintInfo.HintMaxWidth := EasyHintInfo.FMaxWidth;
HintInfo.ReshowTimeout := EasyHintInfo.FReshowTimeout;
HintInfo.HintPos := EasyHintInfo.FWindowPos;
if (HintInfo.HintType = ehtText) or (HintInfo.HintType = ehtToolTip) then
begin
case PEasyHintInfoRec( HintInfo)^.Listview.HintAlignment of
taLeftJustify: TextFlags := [dtLeft, dtCalcRect, dtCalcRectAdjR, dtWordBreak];
taRightJustify: TextFlags := [dtRight, dtCalcRect, dtCalcRectAdjR, dtWordBreak];
taCenter: TextFlags := [dtCenter, dtCalcRect, dtCalcRectAdjR, dtWordBreak];
end;
DrawTextWEx(Canvas.Handle, HintInfo.HintStr, EasyHintInfo.FBounds, TextFlags, -1);
Inc(EasyHintInfo.FBounds.Right, 6);
Inc(EasyHintInfo.FBounds.Bottom, 2)
end;
Result := EasyHintInfo.FBounds;
end;
function TEasyHintWindow.IsHintMsg(var Msg: TMsg): Boolean;
begin
{$IFDEF GXDEBUG_HINT}
// SendDebug('TEasyHintWindow.IsHintMsg');
{$ENDIF GXDEBUG_HINT}
Result := inherited IsHintMsg(Msg)
end;
procedure TEasyHintWindow.Paint;
var
TextFlags: TCommonDrawTextWFlags;
R: TRect;
begin
{$IFDEF GXDEBUG_HINT}
SendDebug('TEasyHintWindow.IsHintMsg');
{$ENDIF GXDEBUG_HINT}
if HintInfo.HintType <> ehtCustomDraw then
begin
case PEasyHintInfoRec( HintInfo)^.Listview.HintAlignment of
taLeftJustify: TextFlags := [dtLeft, dtVCenter];
taRightJustify: TextFlags := [dtRight, dtVCenter];
taCenter: TextFlags := [dtCenter, dtVCenter];
end;
R := FEasyHintInfo.Bounds;
InflateRect(R, -2, -2);
DrawTextWEx(Canvas.Handle, HintInfo.HintStr, R, TextFlags, -1);
end else
begin
R := ClientRect;
InflateRect(R, -2, -2);
HintInfo.Listview.DoHintCustomDraw(HintInfo.TargetObj, FEasyHintInfo)
end
end;
{ TEasySortManager }
constructor TEasySortManager.Create(AnOwner: TCustomEasyListview);
begin
inherited Create(AnOwner);
FAlgorithm := esaMergeSort;
FSorter := TEasyMergeSort.Create(Self);
end;
destructor TEasySortManager.Destroy;
begin
FreeAndNil(FSorter);
inherited Destroy;
end;
function TEasySortManager.CollectionSupportsInterfaceSorting(Collection: TEasyCollection): Boolean;
var
i: Integer;
begin
Result := True;
i := 0;
while (i < Collection.Count) and Result do
begin
Result := CommonSupports(Collection[i].DataInf, IEasyCompare);
Inc(i)
end
end;
procedure TEasySortManager.BeginUpdate;
begin
InterlockedIncrement(FUpdateCount);
end;
procedure TEasySortManager.EndUpdate;
begin
InterlockedDecrement(FUpdateCount);
if (UpdateCount <= 0) and AutoSort then
begin
UpdateCount := 0;
SortAll
end
end;
procedure TEasySortManager.GroupItem(Item: TEasyItem; ColumnIndex: Integer;
Key: LongWord);
//
// WARNING: Do not access the items OwnerListview property as it is an orphaned
// item when it is passed to this method (the collection property is nil)
//
var
i: Integer;
Done, DefaultAction: Boolean;
Groups: TEasyGroups;
Group: TEasyGroup;
begin
i := 0;
Done := False;
Groups := OwnerListview.Groups;
while not Done and (i < Groups.Count) do
begin
if Key = Groups[i].Key then
begin
Groups[i].Items.List.Add(Item);
Item.FCollection := Groups[i].Items;
Done := True;
end;
Inc(i)
end;
if not Done then
begin
Group := nil;
DefaultAction := True;
OwnerListview.DoAutoSortGroupCreate(Item, ColumnIndex, Groups, Group, DefaultAction);
if DefaultAction then
begin
if Key > 0 then
Group.Caption := UpperCase( WideChar(Key))
end;
Group.Key := Key;
Group.Items.List.Add(Item);
Item.FCollection := Groups[i].Items;
end
end;
procedure TEasySortManager.ReGroup(Column: TEasyColumn);
var
Groups: TEasyGroups;
Item: TEasyItem;
i, j, ColumnIndex, Index: Integer;
Key: Integer;
Caption: WideString;
begin
OwnerListview.BeginUpdate;
try
if Assigned(Column) then
ColumnIndex := Column.Index
else
ColumnIndex := 0;
// Move the items into a temporary storage structure
Groups := OwnerListview.Groups;
SetLength(FSortList, Groups.ItemCount);
Index := 0;
for i := 0 to Groups.Count - 1 do
for j := 0 to Groups[i].ItemCount - 1 do
begin
Item := Groups[i][j];
if OwnerListview.Sort.AutoRegroup then
begin
SortList[Index].Key := $FFFF;
OwnerListview.DoAutoGroupGetKey(Item, ColumnIndex, Groups, SortList[Index].Key);
if SortList[Index].Key = $FFFF then
begin
Caption := Item.Caption;
if Length(Caption) = 0 then
SortList[Index].Key := 0
else
SortList[Index].Key := Ord(WideLowerCase(Caption)[1])
end else
Item.GroupKey[ColumnIndex] := SortList[Index].Key;
end;
SortList[Index].Item := Item;
Item.FCollection := nil; // Orphan the item from the collection
Groups[i].Item[j] := nil;
Inc(Index)
end;
for i := 0 to Groups.Count - 1 do
Groups[i].FItems.FList.Pack;
// Clear the control of items
Groups.Clear;
for i := 0 to Length(SortList) - 1 do
begin
Item := TEasyItem( SortList[i].Item);
Key := SortList[i].Key;
GroupItem(Item, ColumnIndex, Key);
end;
OwnerListview.Sort.SortAll;
finally
// done with SortList
SetLength(FSortList, 0);
OwnerListview.EndUpdate(True)
end
end;
procedure TEasySortManager.SetAlgorithm(Value: TEasySortAlgorithm);
begin
if FAlgorithm <> Value then
begin
FreeAndNil(FSorter);
case Value of
esaQuicksort: FSorter := TEasyQuicksort.Create(Self);
esaBubbleSort: FSorter := TEasyBubbleSort.Create(Self);
esaMergeSort: FSorter := TEasyMergeSort.Create(Self);
end;
FAlgorithm := Value
end
end;
procedure TEasySortManager.SetAutoRegroup(Value: Boolean);
begin
if Value <> FAutoRegroup then
begin
OwnerListview.BeginUpdate;
try
OwnerListview.ShowGroupMargins := Value;
FAutoRegroup := Value;
ReGroup(OwnerListview.Selection.FocusedColumn);
finally
OwnerListview.EndUpdate(True);
end
end
end;
procedure TEasySortManager.SetAutoSort(Value: Boolean);
begin
if Value <> FAutoSort then
begin
FAutoSort := Value;
if not Assigned(OwnerListview.Selection.FocusedColumn) then
OwnerListview.Selection.FocusedColumn := OwnerListview.Header.FirstColumn;
if Value then
SortAll
end
end;
procedure TEasySortManager.SortAll(Force: Boolean = False);
var
i: Integer;
SupportsInterfaces: Boolean;
begin
if Assigned(Sorter) and Assigned(OwnerListview) and (({(OwnerListview.UpdateCount = 0) and} (UpdateCount = 0) and not LockoutSort) or Force) then
begin
SupportsInterfaces := CollectionSupportsInterfaceSorting(OwnerListview.Groups);
Sorter.Sort(nil, OwnerListview.Groups, 0, OwnerListview.Groups.Count - 1, OwnerListview.DoGroupCompare, nil, SupportsInterfaces);
for i := 0 to OwnerListview.Groups.Count - 1 do
begin
SupportsInterfaces := CollectionSupportsInterfaceSorting(OwnerListview.Groups[i].Items);
Sorter.Sort(OwnerListview.GetSortColumn, OwnerListview.Groups[i].Items, 0, OwnerListview.Groups[i].ItemCount - 1, nil, OwnerListview.DoItemCompare, SupportsInterfaces);
end;
if not (egsRebuilding in OwnerListview.Groups.GroupsState) then
OwnerListview.Groups.Rebuild(True)
end
end;
{ TEasyQuicksort}
procedure TEasyQuicksort.Sort(Column: TEasyColumn; Collection: TEasyCollection; Min, Max: Integer; GroupCompare: TEasyDoGroupCompare; ItemCompare: TEasyDoItemCompare; UseInterfaces: Boolean);
var
I, J: Integer;
P, Temp: TEasyCollectionItem;
begin
// Quicksort is not Stable, i.e. duplicate items may not be in the same
// order with each pass of the sort.
if Max > Collection.Count - 1 then
Max := Collection.Count - 1;
if Max > Min then
begin
repeat
I := Min;
J := Max;
P := Collection.Items[(Min + Max) shr 1];
repeat
if UseInterfaces then
begin
while (P.DataInf as IEasyCompare).Compare(Collection.Items[I].DataInf, Column) < 0 do
Inc(I);
while (P.DataInf as IEasyCompare).Compare(Collection.Items[J].DataInf, Column) > 0 do
Dec(J);
end else
if Assigned(GroupCompare) then
begin
while GroupCompare(Column, TEasyGroup(Collection.Items[I]), TEasyGroup(P)) < 0 do
Inc(I);
while GroupCompare(Column, TEasyGroup(Collection.Items[J]), TEasyGroup(P)) > 0 do
Dec(J);
end else
if Assigned(ItemCompare) then
begin
while ItemCompare(Column, TEasyItems(Collection).OwnerGroup, TEasyItem(Collection.Items[I]), TEasyItem(P)) < 0 do
Inc(I);
while ItemCompare(Column, TEasyItems(Collection).OwnerGroup, TEasyItem(Collection.Items[J]), TEasyItem(P)) > 0 do
Dec(J);
end else
begin
while DefaultSort(Column, Collection.Items[I], P) < 0 do
Inc(I);
while DefaultSort(Column, Collection.Items[J], P) > 0 do
Dec(J);
end;
if I <= J then
begin
Temp := Collection.Items[I];
Collection.Items[I] := Collection.Items[J];
Collection.Items[J] := Temp;
Inc(I);
Dec(J);
end;
until I > J;
if Min < J then Sort(Column, Collection, Min, J, GroupCompare, ItemCompare, UseInterfaces);
Min := I;
until I >= Max;
end
end;
{ TEasyBubbleSort}
procedure TEasyBubbleSort.Sort(Column: TEasyColumn; Collection: TEasyCollection; Min, Max: Integer; GroupCompare: TEasyDoGroupCompare; ItemCompare: TEasyDoItemCompare; UseInterfaces: Boolean);
var
LastSwap, i, j, SortResult : Integer;
Tmp: TEasyCollectionItem;
begin
// During this loop, min and max are the smallest and largest
// indexes of items that might still be out of order.
// Repeat until we are done.
while (Min < Max) do
begin
// Bubble up.
LastSwap := Min - 1;
// for i := min + 1 to max
i := min + 1;
while (i <= Max) do
begin
// Find a bubble.
if UseInterfaces then
SortResult := (Collection.Items[i].DataInf as IEasyCompare).Compare(Collection.Items[i - 1].DataInf, Column)
else
if Assigned(GroupCompare) then
SortResult := GroupCompare(Column, TEasyGroup(Collection.Items[i - 1]), TEasyGroup(Collection.Items[i]))
else
if Assigned(ItemCompare) then
SortResult := ItemCompare(Column, TEasyItems(Collection).OwnerGroup, TEasyItem(Collection.Items[i - 1]), TEasyItem(Collection.Items[i]))
else
SortResult := DefaultSort(Column, Collection.Items[i - 1], Collection.Items[i]);
if SortResult > 0 then
begin
// See where to drop the bubble.
Tmp := Collection.Items[i - 1];
j := i;
repeat
Collection.Items[j - 1] := Collection.Items[j];
j := j + 1;
if (j > max) then
Break;
if UseInterfaces then
SortResult := (Tmp.DataInf as IEasyCompare).Compare(Collection.Items[j].DataInf, Column)
else
if Assigned(GroupCompare) then
SortResult := GroupCompare(Column, TEasyGroup(Collection.Items[j]), TEasyGroup(Tmp))
else
if Assigned(ItemCompare) then
SortResult := ItemCompare(Column, TEasyItems(Collection).OwnerGroup, TEasyItem(Collection.Items[j]), TEasyItem(Tmp))
else
SortResult := DefaultSort(Column, Collection.Items[j], Tmp);
until SortResult >= 0;
Collection.Items[j - 1] := Tmp;
LastSwap := j - 1;
i := j + 1;
end else
i := i + 1;
end;
// End bubbling up.
// Update max.
Max := LastSwap - 1;
// Bubble down.
LastSwap := Max + 1;
// for i := max - 1 downto min
i := Max - 1;
while (i >= Min) do
begin
// Find a bubble.
if UseInterfaces then
SortResult := (Collection.Items[i].DataInf as IEasyCompare).Compare(Collection.Items[i + 1].DataInf, Column)
else
if Assigned(GroupCompare) then
SortResult := GroupCompare(Column, TEasyGroup(Collection.Items[i + 1]), TEasyGroup(Collection.Items[i]))
else
if Assigned(ItemCompare) then
SortResult := ItemCompare(Column, TEasyItems(Collection).OwnerGroup, TEasyItem(Collection.Items[i + 1]), TEasyItem(Collection.Items[i]))
else
SortResult := DefaultSort(Column, Collection.Items[i + 1], Collection.Items[i]);
if SortResult < 0 then
begin
// See where to drop the bubble.
Tmp := Collection.Items[i + 1];
j := i;
repeat
Collection.Items[j + 1] := Collection.Items[j];
j := j - 1;
if j < Min then
Break;
if UseInterfaces then
SortResult := (Tmp.DataInf as IEasyCompare).Compare(Collection.Items[j].DataInf, Column)
else
if Assigned(GroupCompare) then
SortResult := GroupCompare(Column, TEasyGroup(Collection.Items[j]), TEasyGroup(Tmp))
else
if Assigned(ItemCompare) then
SortResult := ItemCompare(Column, TEasyItems(Collection).OwnerGroup, TEasyItem(Collection.Items[j]), TEasyItem(Tmp))
else
SortResult := DefaultSort(Column, Collection.Items[j], Tmp);
until SortResult <= 0;
Collection.Items[j + 1] := Tmp;
LastSwap := j + 1;
i := j - 1;
end else
i := i - 1;
end;
// End bubbling down.
// Update min.
Min := LastSwap + 1;
end;
end;
{ TEasyMergeSort }
function TEasyMergeSort.CompareDefault(i1, i2: TEasyCollectionItem): Boolean;
begin
Result := DefaultSort(Column, i1, i2) <= 0;
end;
function TEasyMergeSort.CompareGroup(i1, i2: TEasyCollectionItem): Boolean;
begin
Result := GroupCompareFunc(Column, TEasyGroup(i1), TEasyGroup(i2)) <= 0;
end;
function TEasyMergeSort.CompareInterfaces(i1, i2: TEasyCollectionItem): Boolean;
begin
Result:=(i2.DataInf as IEasyCompare).Compare(i1.DataInf, Column) <= 0;
end;
function TEasyMergeSort.CompareItem(i1, i2: TEasyCollectionItem): Boolean;
begin
Result := ItemCompareFunc(Column, OwnerGroup, TEasyItem(i1), TEasyItem(i2)) <= 0;
end;
procedure TEasyMergeSort.Sort(Column: TEasyColumn; Collection: TEasyCollection; Min, Max: Integer; GroupCompare: TEasyDoGroupCompare; ItemCompare: TEasyDoItemCompare; UseInterfaces: Boolean);
type
TEasyMergeSortCompare=function (i1, i2: TEasyCollectionItem): Boolean of object;
var
CompareFunc: TEasyMergeSortCompare;
procedure subMerge(dst: TEasyCollection; ld, md, hd: Integer; src: TEasyCollection; ls, ms: Integer);
{ dst src
hd
aa
md ms
xx bb bb+aa->xxaa
ld ls }
var
i, j, d: Integer;
begin
i := ls;
j := md;
d := ld;
while i< ms do
begin
if (j = hd) or (compareFunc(src[i], dst[j])) then
begin
dst[d] := src[i];
Inc(i);
end
else
begin
dst[d] := dst[j];
Inc(j);
end;
Inc(d);
end;
end;
procedure subSortM(dst: TEasyCollection; ld, hd: Integer; src: TEasyCollection; ls, hs: Integer); forward;
procedure subSortI(dst: TEasyCollection; ld, hd: Integer; tmp: TEasyCollection; lt, ht: Integer);
var
m2: Integer; //I for Inplace
x3: Pointer;
{ - hd
| A inplace AA->AA
m2 A ht move bbb->ccc
b c merge ccc+AA->bbbAA
b c
ld b lt c ht-lt>=hd-m2-ld ! }
begin
if (hd >= ld + 3) then
begin
m2 := (hd - ld) div 2;
subSortI(dst, hd-m2, hd, tmp, lt, lt + m2); //sort random AA->sorted AA, using cc as scratchpad
subSortM(tmp, lt, lt+(hd-ld-m2), dst, ld, hd -m2); //sort random bbb->sorted ccc
subMerge(dst, ld, hd - m2, hd, tmp, lt, lt + (hd - ld - m2)); //merge sorted ccc+sorted AA->bbbAA
end
else if (hd = ld + 2) then
begin
if not compareFunc(dst[ld], dst[ld + 1]) then
begin
x3 := dst[ld];
dst[ld] := dst[ld + 1];
dst[ld + 1] := x3;
end;
end;
end;
procedure subSortM(dst: TEasyCollection; ld, hd: Integer; src: TEasyCollection; ls, hs: Integer);
var m2: Integer; //M for Move
{ hd hs hd hs
c A c b
c A c b
m2 c a m2 c A
d b d a
ld d ls b ld d ls a }
begin
if (hs >= ls + 3) then
begin
m2 := (hs - ls) div 2;
subSortM(dst, ld +m2, hd, src, ls + m2, hs); //sort random aAA->sorted ccc
subSortI(src, ls, ls + m2, dst, ld, ld + m2); //sort random bb->sorted bb, using dd as scratchpad
subMerge(dst, ld, ld + m2, hd, src, ls, ls + m2); //merge bb+ccc->ddccc
end
else if (hs = ls + 2) then
begin
if not compareFunc(src[ls], src[ls+1]) then
begin
dst[ld] := src[ls + 1];
dst[ld+1] := src[ls];
end
else
begin
dst[ld] := src[ls];
dst[ld + 1] := src[ls + 1];
end
end
else if (hs = ls + 1) then
dst[ld] := src[ls];
end;
var m: Integer;
TempList: TEasyCollection;
begin
if Max > Collection.Count - 1 then
Max := Collection.Count - 1;
if (Max <= Min) then
Exit;
Self.Column := Column;
OwnerGroup := TEasyItems(Collection).OwnerGroup;
GroupCompareFunc := GroupCompare;
ItemCompareFunc := ItemCompare;
TempList := TEasyCollection.Create(nil);
m:=(Max - Min + 2) div 2;
TempList.List.Capacity := m;
TempList.List.Count := m;
if (UseInterfaces) then
CompareFunc := CompareInterfaces
else if Assigned(GroupCompareFunc) then
CompareFunc := CompareGroup
else if Assigned(ItemCompareFunc) then
CompareFunc := CompareItem
else
CompareFunc := CompareDefault;
subSortI(Collection, Min, Max + 1, TempList, Min, (Min + Max + 2) div 2);
TempList.List.Count := 0;
TempList.List.Capacity := 0;
FreeAndNil(TempList);
end;
{ TEasyStringEditor }
function TEasyBaseEditor.AcceptEdit: Boolean;
var
WS: Variant;
begin
Result := True;
WS := GetText;
Listview.DoItemEdited(Item, WS, Result);
if Result then
begin
if Assigned(EditColumn) then
Item.Captions[EditColumn.Index] := WS
else
Item.Caption := WS;
Listview.EditManager.EndEdit
end
end;
function TEasyBaseEditor.GetEditor: TWinControl;
begin
Result := FEditor;
end;
function TEasyBaseEditor.GetEditorColor: TColor;
begin
Result := Listview.EditManager.Color
end;
function TEasyBaseEditor.GetHandle: HWnd;
begin
if Assigned(FEditor) and (FEditor.HandleAllocated) then
Result := FEditor.Handle
else
Result := 0;
end;
function TEasyBaseEditor.GetListview: TCustomEasyListview;
begin
Result := nil;
if Assigned(Item) then
Result := Item.OwnerListview
end;
function TEasyBaseEditor.GetModified: Boolean;
begin
Result := Modified
end;
function TEasyBaseEditor.PtInEditControl(WindowPt: TPoint): Boolean;
begin
Result := PtInRect(Editor.BoundsRect, WindowPt)
end;
procedure TEasyBaseEditor.ControlWndHookProc(var Message: TMessage);
//
// Window procedure hook for the Edit box, allows autosizing of edit during user
// input
//
var
Menu: TPopupMenu;
begin
case Message.Msg of
WM_EDITORRESIZE:
begin
ResizeEditor;
end;
WM_CHAR:
begin
if Message.WParam = VK_TAB then
Message.WParam := Ord(' ');
end;
WM_CONTEXTMENU:
begin
Menu := nil;
Listview.DoItemGetEditMenu(Self, Menu);
if Assigned(Menu) then
Menu.Popup(LOWORD(Message.LParam), HIWORD(Message.LParam))
else
// Don't let the VCL hook the parent window background menu to the editor
CallWindowProc(TWinControlHack(Editor).DefWndProc, Editor.Handle, Message.Msg, Message.wParam, Message.lParam);
Message.Result := 1;
end;
end;
FOldWndProc(Message)
end;
function TEasyBaseEditor.EditText(Item: TEasyItem; Column: TEasyColumn): WideString;
begin
Result := '';
Item.OwnerListview.DoItemGetEditCaption(Item, Column, Result);
if Result = '' then
begin
if Assigned(Column) then
Result := Item.Captions[Column.Index]
else
Result := Item.Caption
end
end;
procedure TEasyBaseEditor.Finalize;
begin
EditColumn := nil;
// Only unhook if it is our hook
if EqualWndMethod(Editor.WindowProc, ControlWndHookProc) then
Editor.WindowProc := OldWndProc;
FreeAndNil(FEditor)
end;
procedure TEasyBaseEditor.Hide;
begin
Editor.Visible := False
end;
procedure TEasyBaseEditor.Initialize(AnItem: TEasyItem; Column: TEasyColumn);
begin
FItem := AnItem;
FEditColumn := Column;
CreateEditor(FEditor, Column, Listview);
Editor.Visible := False;
OldWndProc := Editor.WindowProc;
Editor.WindowProc := ControlWndHookProc;
Editor.DoubleBuffered := True;
TWinControlHack( Editor).Color := GetEditorColor;
GetEditorFont.Assign(Listview.EditManager.Font);
Item.ItemRectArray(Column, AnItem.OwnerListview.ScratchCanvas, FRectArray);
ResizeEditor;
SetWindowLong(Editor.Handle, GWL_EXSTYLE, GetWindowLong(Editor.Handle, GWL_EXSTYLE) or WS_EX_TOPMOST);
end;
procedure TEasyBaseEditor.ResizeEditor;
var
R: TRect;
begin
CalculateEditorRect(GetText, R);
Editor.SetBounds(R.Left,
R.Top,
RectWidth(R),
RectHeight(R));
end;
procedure TEasyBaseEditor.SetEditor(const Value: TWinControl);
begin
FEditor := Value;
end;
procedure TEasyBaseEditor.SetEditorFocus;
begin
Editor.SetFocus;
end;
procedure TEasyBaseEditor.Show;
begin
Editor.Visible := True;
end;
{ TEasySelectionGroupList }
constructor TEasySelectionGroupList.Create;
begin
FList := TList.Create
end;
destructor TEasySelectionGroupList.Destroy;
begin
FreeAndNil(FList);
inherited
end;
function TEasySelectionGroupList.Count: Integer;
begin
Result := List.Count
end;
function TEasySelectionGroupList.GetItems(Index: Integer): TEasyItem;
begin
Result := TEasyItem( List.Items[Index])
end;
procedure TEasySelectionGroupList.Add(Item: TEasyItem);
begin
List.Add(Item)
end;
procedure TEasySelectionGroupList.Clear;
begin
List.Clear
end;
procedure TEasySelectionGroupList.DecRef;
begin
Dec(FRefCount);
if FRefCount = 0 then
Destroy
end;
procedure TEasySelectionGroupList.IncRef;
begin
Inc(FRefCount)
end;
procedure TEasySelectionGroupList.SetItems(Index: Integer; Value: TEasyItem);
begin
List.Items[Index] := Value
end;
function TEasyGridIconGroup.GetCellSize: TEasyCellSize;
begin
Result := OwnerListview.CellSizes.Icon
end;
procedure TEasyGridIconGroup.AutoSizeCells;
begin
// Do nothing
end;
procedure TEasyGridIconGroup.SetCellSize(Value: TEasyCellSize);
begin
OwnerListview.CellSizes.Icon.Assign(Value)
end;
function TEasyGridSmallIconGroup.GetCellSize: TEasyCellSize;
begin
Result := OwnerListview.CellSizes.SmallIcon
end;
procedure TEasyGridSmallIconGroup.SetCellSize(Value: TEasyCellSize);
begin
OwnerListview.CellSizes.SmallIcon.Assign(Value)
end;
function TEasyGridThumbnailGroup.GetCellSize: TEasyCellSize;
begin
Result := OwnerListview.CellSizes.Thumbnail
end;
procedure TEasyGridThumbnailGroup.AutoSizeCells;
begin
// Do nothing
end;
procedure TEasyGridThumbnailGroup.SetCellSize(Value: TEasyCellSize);
begin
OwnerListview.CellSizes.Thumbnail.Assign(Value)
end;
{ TEasyGridTileGroup}
procedure TEasyGridTileGroup.FindInsertPosition(ViewportPoint: TPoint; var Group: TEasyGroup; var Index: Integer);
begin
end;
function TEasyGridTileGroup.GetCellSize: TEasyCellSize;
begin
Result := OwnerListview.CellSizes.Tile
end;
procedure TEasyGridTileGroup.SetCellSize(Value: TEasyCellSize);
begin
OwnerListview.CellSizes.Tile.Assign(Value)
end;
{ TEasyItemInterfaced}
function TEasyItemInterfaced.ExtractObject: TObject;
begin
if Supports(DataInf, ICommonExtractObj) then
Result := (DataInf as ICommonExtractObj).Obj
else
Result := nil
end;
function TEasyItemInterfaced.GetCaptions(Column: Integer): Widestring;
var
CaptionInf: IEasyCaptions;
begin
CaptionInf := nil;
if Supports(DataInf, IEasyCaptions, CaptionInf) then
Result := CaptionInf.Captions[Column]
end;
function TEasyItemInterfaced.GetChecked: Boolean;
var
Checks: IEasyChecks;
begin
Result := False;
Checks := nil;
if Supports(DataInf, IEasyChecks, Checks) then
Result := Checks.GetChecked(0)
end;
function TEasyItemInterfaced.GetCommonImageIndex(Column: Integer; Kind: TEasyImageKind): TCommonImageIndexInteger;
var
ImageInf: IEasyImages;
begin
Result := -1;
ImageInf := nil;
if Supports(DataInf, IEasyImages, ImageInf) then
Result := ImageInf.ImageIndexes[Column, Kind]
end;
function TEasyItemInterfaced.GetDetailCount: Integer;
var
TileInf: IEasyDetails;
begin
Result := 1;
TileInf := nil;
if Supports(DataInf, IEasyDetails, TileInf) then
Result := TileInf.GetDetailCount
end;
function TEasyItemInterfaced.GetDetails(Line: Integer): Integer;
var
TileInf: IEasyDetails;
begin
Result := 0;
TileInf := nil;
if Supports(DataInf, IEasyDetails, TileInf) then
Result := TileInf.Detail[Line]
end;
function TEasyItemInterfaced.GetGroupKey(FocusedColumn: Integer): LongWord;
var
KeyInf: IEasyGroupKey;
begin
Result := 0;
KeyInf := nil;
if Supports(DataInf, IEasyGroupKey, KeyInf) then
Result := KeyInf.Key[FocusedColumn]
end;
function TEasyItemInterfaced.GetImageIndexes(Column: Integer): TCommonImageIndexInteger;
begin
Result := GetCommonImageIndex(Column, eikNormal);
end;
function TEasyItemInterfaced.GetImageList(Column: Integer; IconSize: TEasyImageSize): TCustomImageList;
var
ImageList: IEasyImageList;
begin
Result := nil;
if Supports(DataInf, IEasyImageList, ImageList) then
Result := ImageList.ImageList[Column, IconSize];
if not Assigned(Result) then
Result := DefaultImageList(IconSize)
end;
function TEasyItemInterfaced.GetImageOverlayIndexes(Column: Integer): TCommonImageIndexInteger;
begin
Result := GetCommonImageIndex(Column, eikOverlay);
end;
function TEasyItemInterfaced.GetStateImageIndexes(Column: Integer): TCommonImageIndexInteger;
begin
Result := GetCommonImageIndex(Column, eikState);
end;
function TEasyItemInterfaced.GetStateImageList(Column: Integer): TCustomImageList;
var
ImageList: IEasyStateImageList;
begin
Result := nil;
if Supports(DataInf, IEasyStateImageList, ImageList) then
Result := ImageList.ImageList[Column];
if not Assigned(Result) then
Result := DefaultStateImageList
end;
procedure TEasyItemInterfaced.ImageDraw(Column: TEasyColumn; ACanvas: TCanvas; const RectArray: TEasyRectArrayObject; AlphaBlender: TEasyAlphaBlender);
var
ImageInf: IEasyCustomImage;
begin
if Supports(DataInf, IEasyCustomImage, ImageInf) then
ImageInf.DrawImage(Column, ACanvas, RectArray, AlphaBlender)
end;
procedure TEasyItemInterfaced.ImageDrawGetSize(Column: TEasyColumn; var ImageW, ImageH: Integer);
var
ImageInf: IEasyCustomImage;
begin
if Supports(DataInf, IEasyCustomImage, ImageInf) then
ImageInf.GetSize(Column, ImageW, ImageH)
end;
procedure TEasyItemInterfaced.ImageDrawIsCustom(Column: TEasyColumn;
var IsCustom: Boolean);
var
ImageInf: IEasyCustomImage;
begin
IsCustom := False;
if Supports(DataInf, IEasyCustomImage, ImageInf) then
ImageInf.CustomDrawn(Column, IsCustom)
end;
procedure TEasyItemInterfaced.SetCaptions(Column: Integer; Value: Widestring);
var
CaptionInf: IEasyCaptionsEditable;
begin
CaptionInf := nil;
if Supports(DataInf, IEasyCaptionsEditable, CaptionInf) then
begin
CaptionInf.SetCaption(Column, Value);
Invalidate(False)
end
end;
procedure TEasyItemInterfaced.SetChecked(Value: Boolean);
var
Checks: IEasyChecks;
begin
Checks := nil;
if Supports(DataInf, IEasyChecks, Checks) then
begin
Checks.SetChecked(0, Value);
Invalidate(False)
end
end;
procedure TEasyItemInterfaced.SetCommonImageIndex(Column: Integer; Kind: TEasyImageKind; Value: TCommonImageIndexInteger);
var
ImageInf: IEasyImagesEditable;
begin
ImageInf := nil;
if Supports(DataInf, IEasyImagesEditable, ImageInf) then
ImageInf.SetImageIndex(Column, Kind, Value)
end;
procedure TEasyItemInterfaced.SetDetailCount(Value: Integer);
var
DetailsInf: IEasyDetailsEditable;
begin
DetailsInf := nil;
if Supports(DataInf, IEasyDetailsEditable, DetailsInf) then
begin
DetailsInf.DetailCount := Value;
Invalidate(False)
end
end;
procedure TEasyItemInterfaced.SetDetails(Line: Integer; Value: Integer);
var
DetailsInf: IEasyDetailsEditable;
begin
DetailsInf := nil;
if Supports(DataInf, IEasyDetailsEditable, DetailsInf) then
begin
DetailsInf.Detail[Line] := Value;
Invalidate(False)
end
end;
procedure TEasyItemInterfaced.SetGroupKey(FocusedColumn: Integer;
Value: LongWord);
var
KeyInf: IEasyGroupKeyEditable;
begin
KeyInf := nil;
if Supports(DataInf, IEasyGroupKeyEditable, KeyInf) then
KeyInf.Key[FocusedColumn] := Value;
end;
procedure TEasyItemInterfaced.SetImageIndexes(Column: Integer; Value: TCommonImageIndexInteger);
begin
SetCommonImageIndex(Column, eikNormal, Value)
end;
procedure TEasyItemInterfaced.SetImageOverlayIndexes(Column: Integer; Value: TCommonImageIndexInteger);
begin
SetCommonImageIndex(Column, eikOverlay, Value)
end;
procedure TEasyItemInterfaced.SetStateImageIndexes(Column: Integer; Value: TCommonImageIndexInteger);
begin
SetCommonImageIndex(Column, eikState, Value)
end;
procedure TEasyItemInterfaced.ThumbnailDraw(ACanvas: TCanvas; ARect: TRect;
AlphaBlender: TEasyAlphaBlender; var DoDefault: Boolean);
var
ThumbInf: IEasyThumbnail;
begin
if Supports(DataInf, IEasyThumbnail, ThumbInf) then
ThumbInf.ThumbnailDraw(ACanvas, ARect, AlphaBlender, DoDefault)
end;
{ TEasyItem }
constructor TEasyItem.Create(ACollection: TEasyCollection);
begin
inherited Create(ACollection);
FVisibleIndexInGroup := -1;
end;
destructor TEasyItem.Destroy;
begin
SetDestroyFlags;
if Assigned(OwnerListview) then
begin
if OwnerListview.DragManager.DropTarget = Self then
OwnerListview.DragManager.FDropTarget := nil;
if OwnerListview.EditManager.TabMoveFocusItem = Self then
OwnerListview.EditManager.TabMoveFocusItem := nil;
if OwnerListview.Selection.AnchorItem = Self then
OwnerListview.Selection.AnchorItem := nil;
if OwnerListview.Selection.FocusedItem = Self then
OwnerListview.Selection.FocusedItem := nil;
if OwnerListview.IncrementalSearch.SearchItem = Self then
OwnerListview.IncrementalSearch.SearchItem := nil;
if OwnerListview.IncrementalSearch.NextSearchItem = Self then
OwnerListview.IncrementalSearch.NextSearchItem := nil;
end;
Visible := False; // will UnSelect and UnFocus if necessary
inherited;
ReleaseSelectionGroup;
FreeAndNil(FView);
end;
function TEasyItem.AllowDrag(ViewportPt: TPoint): Boolean;
begin
Result := View.AllowDrag(Self, ViewportPt)
end;
function TEasyItem.CanChangeBold(NewValue: Boolean): Boolean;
begin
Result := True
end;
function TEasyItem.CanChangeCheck(NewValue: Boolean): Boolean;
begin
if Enabled then
begin
Result := True;
OwnerListview.DoItemCheckChanging(Self, Result);
end
else
Result := False;
end;
function TEasyItem.CanChangeEnable(NewValue: Boolean): Boolean;
begin
Result := True;
OwnerListview.DoItemEnableChanging(Self, Result)
end;
function TEasyItem.CanChangeFocus(NewValue: Boolean): Boolean;
begin
Result := True;
OwnerListview.DoItemFocusChanging(Self, Result)
end;
function TEasyItem.CanChangeHotTracking(NewValue: Boolean): Boolean;
begin
Result := True
end;
function TEasyItem.CanChangeSelection(NewValue: Boolean): Boolean;
begin
Result := True;
OwnerListview.DoItemSelectionChanging(Self, Result)
end;
function TEasyItem.CanChangeVisibility(NewValue: Boolean): Boolean;
begin
if OwnerGroup.Visible or not NewValue then
begin
Result := True;
OwnerListview.DoItemVisibilityChanging(Self, Result);
end else
Result := False
end;
function TEasyItem.DefaultStateImageList: TCustomImageList;
begin
Result := OwnerListview.ImagesState
end;
function TEasyItem.EditAreaHitPt(ViewportPoint: TPoint): Boolean;
// Returns true if the passed point is in an area where the Item conciders it a
// place where inplace editing can be activated.
//
begin
Result := View.EditAreaHitPt(Self, ViewportPoint)
end;
function TEasyItem.GetColumnPos: Integer;
//
// Returns the current column that the item is in within the grid or -1 if it
// is not visible
//
begin
Result := -1;
if Visible then
Result := VisibleIndexInGroup mod OwnerGroup.Grid.ColumnCount
end;
function TEasyItem.GetDefaultViewClass: TEasyViewItemClass;
begin
Result := TEasyViewItem;
if Assigned(OwnerListview) then
begin
case OwnerListview.View of
elsIcon: Result := TEasyViewIconItem;
elsSmallIcon: Result := TEasyViewSmallIconItem;
elsList: Result := TEasyViewListItem;
elsReport: Result := TEasyViewReportItem;
elsThumbnail: Result := TEasyViewThumbnailItem;
elsTile: Result := TEasyViewTileItem;
elsFilmStrip: Result := TEasyViewFilmStripItem;
elsGrid: Result := TEasyViewGridItem;
end
end
end;
function TEasyItem.GetGroupKey(FocusedColumn: Integer): LongWord;
begin
Result := 0
end;
function TEasyItem.GetIndex: Integer;
begin
Result := FIndex
end;
function TEasyItem.GetOwnerGroup: TEasyGroup;
begin
Result := OwnerItems.OwnerGroup
end;
function TEasyItem.GetOwnerItems: TEasyItems;
begin
Result := TEasyItems(Collection)
end;
function TEasyItem.GetPaintInfo: TEasyPaintInfoItem;
begin
Result := TEasyPaintInfoItem( inherited PaintInfo)
end;
function TEasyItem.GetRowPos: Integer;
//
// Returns the current column that the item is in within the grid or -1 if it
// is not visible
//
begin
Result := -1;
if Visible then
Result := VisibleIndexInGroup mod OwnerGroup.Grid.RowCount
end;
function TEasyItem.GetStateImageIndex: TCommonImageIndexInteger;
begin
Result := GetStateImageIndexes(0)
end;
function TEasyItem.GetView: TEasyViewItem;
begin
if Assigned(FView) then
begin
if FView.ClassType <> ViewClass then
FreeAndNil(FView);
end;
if not Assigned(FView) then
FView := ViewClass.Create(OwnerGroup);
Result := FView
end;
function TEasyItem.GetViewClass: TEasyViewItemClass;
begin
Result := nil;
if Assigned(OwnerListview) then
OwnerListview.DoItemCustomView(Self, OwnerListview.View, Result);
if not Assigned(Result) then
Result := GetDefaultViewClass;
end;
function TEasyItem.HitTestAt(ViewportPoint: TPoint; var HitInfo: TEasyItemHitTestInfoSet): Boolean;
var
RectArray: TEasyRectArrayObject;
R: TRect;
begin
HitInfo := [];
ItemRectArray(OwnerListview.Header.FirstColumn, OwnerListview.ScratchCanvas, RectArray);
R := RectArray.IconRect;
// Make the blank area between the image and text part of the image
if OwnerListview.IsVertView then
R.Bottom := R.Bottom + OwnerListview.PaintInfoItem.CaptionIndent
else
R.Right := R.Right + OwnerListview.PaintInfoItem.CaptionIndent;
if PtInRect(R, ViewportPoint) then
Include(HitInfo, ehtOnIcon);
if PtInRect(RectArray.CheckRect, ViewportPoint) then
Include(HitInfo, ehtOnCheck);
if PtInRect(RectArray.FullFocusSelRect, ViewportPoint) then
Include(HitInfo, ehtOnText);
if PtInRect(RectArray.LabelRect, ViewportPoint) then
Include(HitInfo, ehtOnLabel);
if PtInRect(RectArray.ClickselectBoundsRect, ViewportPoint) then
Include(HitInfo, ehtOnClickselectBounds);
if PtInRect(RectArray.DragSelectBoundsRect, ViewportPoint) then
Include(HitInfo, ehtOnDragSelectBounds);
if PtInRect(RectArray.DragSelectBoundsRect, ViewportPoint) then
Include(HitInfo, ehtOnDragSelectBounds);
if PtInRect(RectArray.StateRect, ViewportPoint) then
Include(HitInfo, ehtStateIcon);
Result := HitInfo <> [];
end;
function TEasyItem.LocalPaintInfo: TEasyPaintInfoBasic;
begin
Result := OwnerListview.PaintInfoItem
end;
function TEasyItem.SelectionHit(SelectViewportRect: TRect; SelectType: TEasySelectHitType): Boolean;
begin
Result := View.SelectionHit(Self, SelectViewportRect, SelectType)
end;
function TEasyItem.SelectionHitPt(ViewportPoint: TPoint; SelectType: TEasySelectHitType): Boolean;
begin
Result := View.SelectionHitPt(Self, ViewportPoint, SelectType)
end;
procedure TEasyItem.Edit(Column: TEasyColumn = nil);
begin
OwnerListview.EditManager.BeginEdit(Self, Column)
end;
procedure TEasyItem.Freeing;
begin
OwnerListview.DoItemFreeing(Self)
end;
procedure TEasyItem.GainingBold;
begin
Invalidate(False)
end;
procedure TEasyItem.GainingCheck;
begin
Inc(OwnerListview.CheckManager.FCount);
OwnerListview.DoItemCheckChanged(Self);
Invalidate(False);
end;
procedure TEasyItem.GainingEnable;
begin
OwnerListview.DoItemEnableChanged(Self);
Invalidate(False);
end;
procedure TEasyItem.GainingFocus;
begin
OwnerListview.DoItemFocusChanged(Self);
OwnerListview.Selection.FocusedItem := Self;
Invalidate(False);
if OwnerListview.Selection.GroupSelections then
begin
OwnerListview.Selection.BuildSelectionGroupings(False);
OwnerListview.SafeInvalidateRect(nil, False);
end
end;
procedure TEasyItem.GainingGhosted;
begin
// OwnerListview.DoItemCheckChanged(Self);
if State * [esosDestroying] = [] then
Invalidate(False);
end;
procedure TEasyItem.GainingHilight;
begin
Invalidate(True);
end;
procedure TEasyItem.GainingHotTracking(MousePos: TPoint);
begin
OwnerListview.DoItemHotTrack(Self, ehsEnable, MousePos);
Invalidate(True)
end;
procedure TEasyItem.GainingSelection;
begin
OwnerListview.Selection.GainingSelection(Self);
OwnerListview.DoItemSelectionChanged(Self);
if OwnerListview.Selection.GroupSelections then
begin
OwnerListview.Selection.BuildSelectionGroupings(False);
OwnerListview.SafeInvalidateRect(nil, False);
end else
Invalidate(False);
end;
procedure TEasyItem.GainingVisibility;
begin
// Inc(OwnerGroup.FVisibleCount);
OwnerListview.Groups.Rebuild;
OwnerListview.DoItemVisibilityChanged(Self);
end;
procedure TEasyItem.Initialize;
begin
OwnerListview.DoItemInitialize(Self);
Include(FState, esosInitialized);
end;
procedure TEasyItem.Invalidate(ImmediateUpdate: Boolean);
var
RectArray: TEasyRectArrayObject;
R: TRect;
Listview: TCustomEasyListview;
begin
Listview := TEasyCollection( Collection).FOwnerListview;
if Listview.HandleAllocated then
begin
R := Listview.Scrollbars.MapWindowRectToViewRect(Listview.ClientRect, True);
// This is a bit odd as a long text caption is scrolled off the top of the window
if IntersectRect(R, R, DisplayRect) then
begin
View.ItemRectArray(Self, nil, OwnerListview.ScratchCanvas, '', RectArray);
UnionRect(R, RectArray.FocusChangeInvalidRect, DisplayRect);
R := Listview.Scrollbars.MapViewRectToWindowRect(R, True);
Listview.SafeInvalidateRect(@R, ImmediateUpdate);
end
end
end;
procedure TEasyItem.ItemRectArray(Column: TEasyColumn; ACanvas: TCanvas; var RectArray: TEasyRectArrayObject);
begin
if Assigned(View) then
View.ItemRectArray(Self, Column, ACanvas, '', RectArray)
else
FillChar(RectArray, SizeOf(RectArray), #0)
end;
procedure TEasyItem.LoadFromStream(S: TStream; var Version: Integer);
begin
inherited LoadFromStream(S, Version);
OwnerListview.DoItemLoadFromStream(Self, S, Version);
// For new objects test the stream version first
// if Version > X then
// begin
// ReadStream....
// end
end;
procedure TEasyItem.LosingBold;
begin
Invalidate(False)
end;
procedure TEasyItem.LosingCheck;
begin
Dec(OwnerListview.CheckManager.FCount);
OwnerListview.DoItemCheckChanged(Self);
if State * [esosDestroying] = [] then
Invalidate(False);
end;
procedure TEasyItem.LosingEnable;
begin
ReleaseSelectionGroup;
OwnerListview.DoItemEnableChanged(Self);
if State * [esosDestroying] = [] then
Invalidate(False);
end;
procedure TEasyItem.LosingFocus;
begin
if OwnerListview.Selection.FocusedItem = Self then
OwnerListview.Selection.FocusedItem := nil;
OwnerListview.DoItemFocusChanged(Self);
// Need to repaint before Losing the focus
if State * [esosDestroying] = [] then
begin
Include(FState, esosFocused);
Invalidate(False);
Exclude(FState, esosFocused);
if OwnerListview.Selection.GroupSelections then
OwnerListview.SafeInvalidateRect(nil, False);
end;
end;
procedure TEasyItem.LosingGhosted;
begin
// OwnerListview.DoItemCheckChanged(Self);
if State * [esosDestroying] = [] then
Invalidate(False);
end;
procedure TEasyItem.LosingHilight;
begin
Invalidate(True);
end;
procedure TEasyItem.LosingHotTracking;
begin
OwnerListview.DoItemHotTrack(Self, ehsDisable, Point(0, 0));
Invalidate(True)
end;
procedure TEasyItem.LosingSelection;
begin
OwnerListview.Selection.LosingSelection(Self);
OwnerListview.DoItemSelectionChanged(Self);
// Need to repaint before Losing the focus
if State * [esosDestroying] = [] then
begin
if OwnerListview.Selection.GroupSelections then
begin
OwnerListview.Selection.BuildSelectionGroupings(False);
OwnerListview.SafeInvalidateRect(nil, False);
end else
Invalidate(False);
end
end;
procedure TEasyItem.LosingVisibility;
begin
// Dec(OwnerGroup.FVisibleCount);
ReleaseSelectionGroup;
OwnerListview.Groups.Rebuild;
OwnerListview.DoItemVisibilityChanged(Self);
end;
procedure TEasyItem.MakeVisible(Position: TEasyMakeVisiblePos);
var
RectArray: TEasyRectArrayObject;
R: TRect;
begin
if Visible then
begin
View.ItemRectArray(Self, OwnerListview.Header.FirstVisibleColumn, OwnerListview.ScratchCanvas, '', RectArray);
R := RectArray.BoundsRect;
// UnionRect(R, RectArray.FullFocusSelRect, RectArray.IconRect); // WL, 01/10/05: bottom line of focus rect was missing if item was made visible at the bottom of the window
// InflateRect(R, H_STRINGEDITORMARGIN div 2, V_STRINGEDITORMARGIN div 2);
if not ContainsRect(OwnerListview.ClientInViewportCoords, R) then
begin
case Position of
emvTop:
begin
OwnerListview.Scrollbars.OffsetY := R.Top;
OwnerListview.Scrollbars.OffsetX := R.Left;
end;
emvMiddle:
begin
OwnerListview.Scrollbars.OffsetY := R.Top + OwnerListview.ClientHeight div 2;
OwnerListview.Scrollbars.OffsetX := R.Left + OwnerListview.ClientWidth div 2;
end;
emvBottom:
begin
OwnerListview.Scrollbars.OffsetY := R.Bottom - OwnerListview.ClientHeight + OwnerListview.Header.RuntimeHeight;
OwnerListview.Scrollbars.OffsetX := R.Right - OwnerListview.ClientWidth;
end;
emvAuto:
begin
if R.Bottom > OwnerListview.ClientInViewportCoords.Bottom then
OwnerListview.Scrollbars.OffsetY := R.Bottom - OwnerListview.ClientHeight + OwnerListview.Header.RuntimeHeight
else
if R.Top < OwnerListview.ClientInViewportCoords.Top then
OwnerListview.Scrollbars.OffsetY := R.Top;
if R.Right > OwnerListview.ClientInViewportCoords.Right then
OwnerListview.Scrollbars.OffsetX := R.Left
else
if R.Left < OwnerListview.ClientInViewportCoords.Left then
OwnerListview.Scrollbars.OffsetX := R.Left;
end
end
end
end
end;
procedure TEasyItem.Paint(ACanvas: TCanvas; ViewportClipRect: TRect; Column: TEasyColumn; ForceSelectionRectDraw: Boolean);
begin
View.Paint(Self, Column, ACanvas, ViewportClipRect, ForceSelectionRectDraw)
end;
procedure TEasyItem.ReleaseSelectionGroup;
var
Temp: TEasySelectionGroupList;
begin
if Assigned(FSelectionGroup) then
begin
Temp := FSelectionGroup;
FSelectionGroup := nil;
Temp.DecRef
end
end;
procedure TEasyItem.SaveToStream(S: TStream; Version: Integer = EASYLISTVIEW_STREAM_VERSION);
begin
inherited SaveToStream(S);
OwnerListview.DoItemSaveToStream(Self, S, Version);
// For new objects test the stream version first
// if Version > X then
// begin
// WriteStream....
// end
end;
procedure TEasyItem.SetGroupKey(FocusedColumn: Integer; Value: LongWord);
begin
end;
procedure TEasyItem.SetPaintInfo(const Value: TEasyPaintInfoItem);
begin
inherited PaintInfo := Value
end;
procedure TEasyItem.SetSelectionGroup(Value: TEasySelectionGroupList);
begin
if Value <> FSelectionGroup then
begin
if Assigned(FSelectionGroup) then
FSelectionGroup.DecRef;
FSelectionGroup := Value
end
end;
procedure TEasyItem.SetStateImageIndex(const Value: TCommonImageIndexInteger);
begin
SetStateImageIndexes(0, Value)
end;
{ TEasyItemVirtual}
function TEasyItemVirtual.GetCaptions(Column: Integer): Widestring;
begin
Result := '';
OwnerListview.DoItemGetCaption(Self, Column, Result)
end;
function TEasyItemVirtual.GetDetailCount: Integer;
begin
Result := 0;
OwnerListview.DoItemGetTileDetailCount(Self, Result)
end;
function TEasyItemVirtual.GetDetails(Line: Integer): Integer;
begin
Result := 0;
OwnerListview.DoItemGetTileDetail(Self, Line, Result)
end;
function TEasyItemVirtual.GetGroupKey(FocusedColumn: Integer): LongWord;
begin
Result := 0;
OwnerListview.DoItemGetGroupKey(Self, FocusedColumn, Result)
end;
function TEasyItemVirtual.GetImageIndexes(Column: Integer): TCommonImageIndexInteger;
begin
Result := -1;
OwnerListview.DoItemGetImageIndex(Self, Column, eikNormal, Result)
end;
function TEasyItemVirtual.GetImageList(Column: Integer; IconSize: TEasyImageSize): TCustomImageList;
begin
Result := nil;
OwnerListview.DoItemGetImageList(Self, Column, Result);
if not Assigned(Result) then
Result := DefaultImageList(IconSize)
end;
function TEasyItemVirtual.GetImageOverlayIndexes(Column: Integer): TCommonImageIndexInteger;
begin
Result := -1;
OwnerListview.DoItemGetImageIndex(Self, Column, eikOverlay, Result)
end;
function TEasyItemVirtual.GetStateImageIndexes(Column: Integer): TCommonImageIndexInteger;
begin
Result := -1;
OwnerListview.DoItemGetImageIndex(Self, Column, eikState, Result)
end;
function TEasyItemVirtual.GetStateImageList(Column: Integer): TCustomImageList;
begin
Result := nil;
OwnerListview.DoItemGetStateImageList(Self, Column, Result);
if not Assigned(Result) then
Result := DefaultStateImageList
end;
procedure TEasyItemVirtual.ImageDrawIsCustom(Column: TEasyColumn; var IsCustom: Boolean);
begin
IsCustom := False;
OwnerListview.DoItemImageDrawIsCustom(Column, Self, IsCustom)
end;
procedure TEasyItemVirtual.ImageDraw(Column: TEasyColumn; ACanvas: TCanvas; const RectArray: TEasyRectArrayObject; AlphaBlender: TEasyAlphaBlender);
begin
OwnerListview.DoItemImageDraw(Self, Column, ACanvas, RectArray, AlphaBlender)
end;
procedure TEasyItemVirtual.ImageDrawGetSize(Column: TEasyColumn; var ImageW: Integer; var ImageH: Integer);
begin
OwnerListview.DoItemImageGetSize(Self, Column, ImageW, ImageH)
end;
procedure TEasyItemVirtual.SetCaptions(Column: Integer; Value: Widestring);
begin
OwnerListview.DoItemSetCaption(Self, Column, Value);
Invalidate(False)
end;
procedure TEasyItemVirtual.SetDetailCount(Value: Integer);
begin
OwnerListview.DoItemSetTileDetailCount(Self, Value);
Invalidate(False)
end;
procedure TEasyItemVirtual.SetDetails(Line: Integer; Value: Integer);
begin
OwnerListview.DoItemSetTileDetail(Self, Line, Value);
Invalidate(False)
end;
procedure TEasyItemVirtual.SetGroupKey(FocusedColumn: Integer; Value: LongWord);
begin
OwnerListview.DoItemSetGroupKey(Self, FocusedColumn, Value);
end;
procedure TEasyItemVirtual.SetImageIndexes(Column: Integer; Value: TCommonImageIndexInteger);
begin
OwnerListview.DoItemSetImageIndex(Self, Column, eikNormal, Value);
Invalidate(False)
end;
procedure TEasyItemVirtual.SetImageOverlayIndexes(Column: Integer; Value: TCommonImageIndexInteger);
begin
OwnerListview.DoItemSetImageIndex(Self, Column, eikOverlay, Value);
Invalidate(False)
end;
procedure TEasyItemVirtual.SetStateImageIndexes(Column: Integer; Value: TCommonImageIndexInteger);
begin
OwnerListview.DoItemSetImageIndex(Self, Column, eikState, Value);
Invalidate(False)
end;
procedure TEasyItemVirtual.ThumbnailDraw(ACanvas: TCanvas; ARect: TRect;
AlphaBlender: TEasyAlphaBlender; var DoDefault: Boolean);
begin
OwnerListview.DoItemThumbnailDraw(Self, ACanvas, ARect, AlphaBlender, DoDefault)
end;
{ TEasyItemStored }
constructor TEasyItemStored.Create(ACollection: TEasyCollection);
begin
inherited Create(ACollection);
FDataHelper := TEasyItemDynamicDataHelper.Create;
end;
destructor TEasyItemStored.Destroy;
begin
SetDestroyFlags;
inherited Destroy;
FreeAndNil(FDataHelper);
end;
function TEasyItemStored.GetCaptions(Column: Integer): Widestring;
begin
Result := '';
if Assigned(DataHelper) then
Result := DataHelper.Captions[Column]
end;
function TEasyItemStored.GetDetailCount: Integer;
begin
Result := OwnerListview.PaintInfoItem.TileDetailCount
end;
function TEasyItemStored.GetDetails(Line: Integer): Integer;
begin
Result := 0;
if Assigned(DataHelper) then
Result := DataHelper.Details[Line]
end;
function TEasyItemStored.GetGroupKey(FocusedColumn: Integer): LongWord;
begin
Result := 0;
if Assigned(DataHelper) then
Result := DataHelper.GroupKey[FocusedColumn]
end;
function TEasyItemStored.GetImageIndexes(Column: Integer): TCommonImageIndexInteger;
begin
Result := -1;
if Assigned(DataHelper) then
Result := DataHelper.ImageIndexes[Column]
end;
function TEasyItemStored.GetImageList(Column: Integer; IconSize: TEasyImageSize): TCustomImageList;
begin
Result := DefaultImageList(IconSize)
end;
function TEasyItemStored.GetImageOverlayIndexes(Column: Integer): TCommonImageIndexInteger;
begin
Result := -1;
if Assigned(DataHelper) then
Result := DataHelper.ImageOverlayIndexes[Column]
end;
function TEasyItemStored.GetStateImageIndexes(Column: Integer): TCommonImageIndexInteger;
begin
Result := -1;
if Assigned(DataHelper) then
Result := DataHelper.StateImageIndexes[Column]
end;
function TEasyItemStored.GetStateImageList(Column: Integer): TCustomImageList;
begin
Result := DefaultStateImageList
end;
procedure TEasyItemStored.ImageDraw(Column: TEasyColumn; ACanvas: TCanvas; const RectArray: TEasyRectArrayObject; AlphaBlender: TEasyAlphaBlender);
begin
OwnerListview.DoItemImageDraw(Self, Column, ACanvas, RectArray, AlphaBlender)
end;
procedure TEasyItemStored.ImageDrawGetSize(Column: TEasyColumn; var ImageW: Integer; var ImageH: Integer);
begin
OwnerListview.DoItemImageGetSize(Self, Column, ImageW, ImageH)
end;
procedure TEasyItemStored.ImageDrawIsCustom(Column: TEasyColumn;
var IsCustom: Boolean);
begin
IsCustom := False;
OwnerListview.DoItemImageDrawIsCustom(Column, Self, IsCustom)
end;
procedure TEasyItemStored.LoadFromStream(S: TStream; var Version: Integer);
begin
inherited LoadFromStream(S, Version);
if Assigned(DataHelper) then
DataHelper.LoadFromStream(S, Version);
// For new objects test the stream version first
// if Version > X then
// begin
// ReadStream....
// end
end;
procedure TEasyItemStored.SaveToStream(S: TStream; Version: Integer = EASYLISTVIEW_STREAM_VERSION);
begin
inherited SaveToStream(S);
if Assigned(DataHelper) then
DataHelper.SaveToStream(S, Version);
// For new objects test the stream version first
// if Version > X then
// begin
// WriteStream....
// end
end;
procedure TEasyItemStored.SetCaptions(Column: Integer; Value: Widestring);
begin
if Assigned(DataHelper) then
begin
DataHelper.Captions[Column] := Value;
Invalidate(False);
end;
end;
procedure TEasyItemStored.SetDetailCount(Value: Integer);
begin
OwnerListview.PaintInfoItem.TileDetailCount := Value
end;
procedure TEasyItemStored.SetDetails(Column: Integer; Value: Integer);
begin
if Assigned(DataHelper) then
begin
DataHelper.Details[Column] := Value;
Invalidate(False);
end;
end;
procedure TEasyItemStored.SetGroupKey(FocusedColumn: Integer; Value: LongWord);
begin
if Assigned(DataHelper) then
DataHelper.GroupKey[FocusedColumn] := Value;
end;
procedure TEasyItemStored.SetImageIndexes(Column: Integer; Value: TCommonImageIndexInteger);
begin
if Assigned(DataHelper) then
begin
DataHelper.ImageIndexes[Column] := Value;
Invalidate(False);
end;
end;
procedure TEasyItemStored.SetImageOverlayIndexes(Column: Integer; Value: TCommonImageIndexInteger);
begin
if Assigned(DataHelper) then
begin
DataHelper.ImageOverlayIndexes[Column] := Value;
Invalidate(False);
end;
end;
procedure TEasyItemStored.SetStateImageIndexes(Column: Integer; Value: TCommonImageIndexInteger);
begin
if Assigned(DataHelper) then
begin
DataHelper.StateImageIndexes[Column] := Value;
Invalidate(False);
end;
end;
procedure TEasyItemStored.ThumbnailDraw(ACanvas: TCanvas; ARect: TRect;
AlphaBlender: TEasyAlphaBlender; var DoDefault: Boolean);
begin
OwnerListview.DoItemThumbnailDraw(Self, ACanvas, ARect, AlphaBlender, DoDefault)
end;
{ TEasyDynamicDataHelper}
function TEasyDynamicDataHelper.GetCaptions(Index: Integer): Widestring;
begin
if Index < Length(CaptionArray) then
Result := CaptionArray[Index]
else
Result := ''
end;
function TEasyDynamicDataHelper.GetDetails(Index: Integer): Integer;
begin
if Index < Length(DetailArray) then
Result := DetailArray[Index]
else
Result := 0
end;
function TEasyDynamicDataHelper.GetImageIndexes(Index: Integer): Integer;
begin
if Index < Length(ImageIndexArray) then
Result := ImageIndexArray[Index]
else
Result := -1
end;
function TEasyDynamicDataHelper.GetImageOverlayIndexes(Index: Integer): Integer;
begin
if Index < Length(OverlayIndexArray) then
Result := OverlayIndexArray[Index]
else
Result := -1
end;
procedure TEasyDynamicDataHelper.Clear;
begin
SetLength(FCaptionArray, 0);
SetLength(FDetailArray, 0);
SetLength(FImageIndexArray, 0);
SetLength(FOverlayIndexArray, 0);
end;
procedure TEasyDynamicDataHelper.LoadFromStream(S: TStream; Version: Integer);
begin
LoadWideStrArrayFromStream(S, FCaptionArray);
LoadIntArrayFromStream(S, FDetailArray);
LoadIntArrayFromStream(S, FImageIndexArray);
LoadIntArrayFromStream(S, FOverlayIndexArray);
end;
procedure TEasyDynamicDataHelper.LoadIntArrayFromStream(S: TStream; var AnArray: TCommonIntegerDynArray);
var
Len, i: Integer;
begin
Setlength(AnArray, 0);
S.ReadBuffer(Len, SizeOf(Len));
Setlength(AnArray, Len);
for i := 0 to Len - 1 do
S.ReadBuffer(AnArray[i], SizeOf(Integer))
end;
procedure TEasyDynamicDataHelper.LoadWideStrArrayFromStream(S: TStream; var AnArray: TCommonWideStringDynArray);
var
Len, Count, i: Integer;
begin
Setlength(AnArray, 0);
S.ReadBuffer(Len, SizeOf(Len));
Setlength(AnArray, Len);
for i := 0 to Len - 1 do
begin
S.ReadBuffer(Count, SizeOf(Count));
SetLength(AnArray[i], Count);
S.ReadBuffer(PWideChar(AnArray[i])^, Count * 2);
end
end;
procedure TEasyDynamicDataHelper.SaveIntArrayToStream(S: TStream; var AnArray: TCommonIntegerDynArray);
var
Len, i: Integer;
begin
Len := Length(AnArray);
S.WriteBuffer(Len, SizeOf(Len));
for i := 0 to Len - 1 do
S.WriteBuffer(AnArray[i], SizeOf(Integer))
end;
procedure TEasyDynamicDataHelper.SaveWideStrArrayToStream(S: TStream; var AnArray: TCommonWideStringDynArray);
var
Len, i, Count: Integer;
begin
Len := Length(AnArray);
S.WriteBuffer(Len, SizeOf(Len));
for i := 0 to Len - 1 do
begin
Count := Length(AnArray[i]);
S.WriteBuffer(Count, SizeOf(Count));
S.WriteBuffer(PWideChar(AnArray[i])^, Count * 2);
end
end;
procedure TEasyDynamicDataHelper.SaveToStream(S: TStream; Version: Integer);
begin
SaveWideStrArrayToStream(S, FCaptionArray);
SaveIntArrayToStream(S, FDetailArray);
SaveIntArrayToStream(S, FImageIndexArray);
SaveIntArrayToStream(S, FOverlayIndexArray);
end;
procedure TEasyDynamicDataHelper.SetCaptions(Index: Integer; Value: Widestring);
var
OldLen, i: Integer;
begin
if Index >= Length(CaptionArray) then
begin
OldLen := Length(CaptionArray);
SetLength(FCaptionArray, Index + 1);
for i := OldLen to Length(CaptionArray) - 1 do
CaptionArray[i] := ''
end;
CaptionArray[Index] := Value
end;
procedure TEasyDynamicDataHelper.SetDetails(Index: Integer; Value: Integer);
var
OldLen, i: Integer;
begin
if Index >= Length(DetailArray) then
begin
OldLen := Length(DetailArray);
SetLength(FDetailArray, Index + 1);
for i := OldLen to Length(DetailArray) - 1 do
DetailArray[i] := 0
end;
DetailArray[Index] := Value
end;
procedure TEasyDynamicDataHelper.SetImageIndexes(Index: Integer; Value: Integer);
var
OldLen, i: Integer;
begin
if Index >= Length(ImageIndexArray) then
begin
OldLen := Length(ImageIndexArray);
SetLength(FImageIndexArray, Index + 1);
for i := OldLen to Length(ImageIndexArray) - 1 do
ImageIndexArray[i] := -1
end;
ImageIndexArray[Index] := Value
end;
procedure TEasyDynamicDataHelper.SetImageOverlayIndexes(Index: Integer; Value: Integer);
var
OldLen, i: Integer;
begin
if Index >= Length(OverlayIndexArray) then
begin
OldLen := Length(OverlayIndexArray);
SetLength(FOverlayIndexArray, Index + 1);
for i := OldLen to Length(OverlayIndexArray) - 1 do
OverlayIndexArray[i] := -1
end;
OverlayIndexArray[Index] := Value
end;
{ TEasyGroupStored }
constructor TEasyBaseGroupStored.Create(ACollection: TEasyCollection);
begin
inherited Create(ACollection);
FDataHelper := TEasyDynamicDataHelper.Create;
end;
destructor TEasyBaseGroupStored.Destroy;
begin
SetDestroyFlags;
inherited Destroy;
FreeAndNil(FDataHelper);
end;
function TEasyBaseGroupStored.GetCaptions(Line: Integer): Widestring;
begin
Result := DataHelper.Captions[Line]
end;
function TEasyBaseGroupStored.GetDetailCount: Integer;
begin
Result := OwnerListview.PaintInfoGroup.CaptionLines
end;
function TEasyBaseGroupStored.GetDetails(Line: Integer): Integer;
begin
Result := DataHelper.Details[Line]
end;
function TEasyBaseGroupStored.GetImageIndexes(Column: Integer): TCommonImageIndexInteger;
begin
Result := DataHelper.ImageIndexes[Column]
end;
function TEasyBaseGroupStored.GetImageList(Column: Integer; IconSize: TEasyImageSize): TCustomImageList;
begin
Result := DefaultImageList(IconSize)
end;
function TEasyBaseGroupStored.GetImageOverlayIndexes(Column: Integer): TCommonImageIndexInteger;
begin
Result := DataHelper.ImageOverlayIndexes[Column]
end;
procedure TEasyBaseGroupStored.ImageDraw(Column: TEasyColumn; ACanvas: TCanvas; const RectArray: TEasyRectArrayObject; AlphaBlender: TEasyAlphaBlender);
begin
OwnerListview.DoGroupImageDraw(Self, ACanvas, RectArray, AlphaBlender)
end;
procedure TEasyBaseGroupStored.ImageDrawGetSize(Column: TEasyColumn; var ImageW: Integer; var ImageH: Integer);
begin
OwnerListview.DoGroupImageGetSize(Self, ImageW, ImageH)
end;
procedure TEasyBaseGroupStored.ImageDrawIsCustom(Column: TEasyColumn;
var IsCustom: Boolean);
begin
IsCustom := False;
OwnerListview.DoGroupImageDrawIsCustom(Self, IsCustom)
end;
procedure TEasyBaseGroupStored.LoadFromStream(S: TStream; var Version: Integer);
begin
inherited LoadFromStream(S, Version);
DataHelper.LoadFromStream(S, Version);
// For new objects test the stream version first
// if Version > X then
// begin
// ReadStream....
// end
end;
procedure TEasyBaseGroupStored.SaveToStream(S: TStream; Version: Integer = EASYLISTVIEW_STREAM_VERSION);
begin
inherited SaveToStream(S);
DataHelper.SaveToStream(S, Version);
// For new objects test the stream version first
// if Version > X then
// begin
// WriteStream....
// end
end;
procedure TEasyBaseGroupStored.SetCaptions(Column: Integer; Value: Widestring);
begin
DataHelper.Captions[Column] := Value;
Invalidate(False)
end;
procedure TEasyBaseGroupStored.SetDetailCount(Value: Integer);
begin
OwnerListview.PaintInfoGroup.CaptionLines := Value
end;
procedure TEasyBaseGroupStored.SetDetails(Line: Integer; Value: Integer);
begin
DataHelper.Details[Line] := Value;
Invalidate(False)
end;
procedure TEasyBaseGroupStored.SetImageIndexes(Column: Integer; Value: TCommonImageIndexInteger);
begin
DataHelper.ImageIndexes[Column] := Value;
Invalidate(False)
end;
procedure TEasyBaseGroupStored.SetImageOverlayIndexes(Column: Integer; Value: TCommonImageIndexInteger);
begin
DataHelper.ImageOverlayIndexes[Column] := Value;
Invalidate(False)
end;
procedure TEasyBaseGroupStored.ThumbnailDraw(ACanvas: TCanvas; ARect: TRect;
AlphaBlender: TEasyAlphaBlender; var DoDefault: Boolean);
begin
// not implemented
end;
{ TEasyGroupVirtual}
function TEasyGroupVirtual.GetCaptions(Line: Integer): Widestring;
begin
Result := '';
OwnerListview.DoGroupGetCaption(Self, Result)
end;
function TEasyGroupVirtual.GetDetailCount: Integer;
begin
Result := 0;
OwnerListview.DoGroupGetDetailCount(Self, Result)
end;
function TEasyGroupVirtual.GetDetails(Line: Integer): Integer;
begin
Result := 0;
OwnerListview.DoGroupGetDetail(Self, Line, Result)
end;
function TEasyGroupVirtual.GetImageIndexes(Column: Integer): TCommonImageIndexInteger;
begin
Result := -1;
OwnerListview.DoGroupGetImageIndex(Self, eikNormal, Result)
end;
function TEasyGroupVirtual.GetImageList(Column: Integer; IconSize: TEasyImageSize): TCustomImageList;
begin
Result := nil;
OwnerListview.DoGroupGetImageList(Self, Result);
if not Assigned(Result) then
Result := DefaultImageList(IconSize)
end;
function TEasyGroupVirtual.GetImageOverlayIndexes(Column: Integer): TCommonImageIndexInteger;
begin
OwnerListview.DoGroupGetImageIndex(Self, eikOverlay, Result)
end;
procedure TEasyGroupVirtual.ImageDraw(Column: TEasyColumn; ACanvas: TCanvas; const RectArray: TEasyRectArrayObject; AlphaBlender: TEasyAlphaBlender);
begin
OwnerListview.DoGroupImageDraw(Self, ACanvas, RectArray, AlphaBlender)
end;
procedure TEasyGroupVirtual.ImageDrawGetSize(Column: TEasyColumn; var ImageW: Integer; var ImageH: Integer);
begin
OwnerListview.DoGroupImageGetSize(Self, ImageW, ImageH)
end;
procedure TEasyGroupVirtual.ImageDrawIsCustom(Column: TEasyColumn;
var IsCustom: Boolean);
begin
IsCustom := False;
OwnerListview.DoGroupImageDrawIsCustom(Self, IsCustom)
end;
procedure TEasyGroupVirtual.SetCaptions(Column: Integer; Value: Widestring);
begin
OwnerListview.DoGroupSetCaption(Self, Value);
Invalidate(False)
end;
procedure TEasyGroupVirtual.SetDetailCount(Value: Integer);
begin
OwnerListview.DoGroupSetDetailCount(Self, Value);
Invalidate(False)
end;
procedure TEasyGroupVirtual.SetDetails(Line: Integer; Value: Integer);
begin
OwnerListview.DoGroupSetDetail(Self, Line, Value);
Invalidate(False)
end;
procedure TEasyGroupVirtual.SetImageIndexes(Column: Integer; Value: TCommonImageIndexInteger);
begin
OwnerListview.DoGroupSetImageIndex(Self, eikNormal, Value);
Invalidate(False)
end;
procedure TEasyGroupVirtual.SetImageOverlayIndexes(Column: Integer; Value: TCommonImageIndexInteger);
begin
OwnerListview.DoGroupSetImageIndex(Self, eikOverlay, Value);
Invalidate(False)
end;
procedure TEasyGroupVirtual.ThumbnailDraw(ACanvas: TCanvas; ARect: TRect;
AlphaBlender: TEasyAlphaBlender; var DoDefault: Boolean);
begin
// not Implemented
end;
{ TEasyGroupInterfaced}
function TEasyGroupInterfaced.GetCaptions(Line: Integer): Widestring;
var
CaptionInf: IEasyCaptions;
begin
CaptionInf := nil;
if Supports(DataInf, IEasyCaptions, CaptionInf) then
Result := CaptionInf.Captions[Line]
end;
function TEasyGroupInterfaced.GetDetailCount: Integer;
var
DetailInf: IEasyDetails;
begin
Result := 0;
DetailInf := nil;
if Supports(DataInf, IEasyDetails, DetailInf) then
Result := DetailInf.GetDetailCount
end;
function TEasyGroupInterfaced.GetDetails(Line: Integer): Integer;
var
DetailInf: IEasyDetails;
begin
Result := 0;
DetailInf := nil;
if Supports(DataInf, IEasyDetails, DetailInf) then
Result := DetailInf.Detail[Line]
end;
function TEasyGroupInterfaced.GetImageIndexes(Column: Integer): TCommonImageIndexInteger;
var
ImageInf: IEasyImages;
begin
Result := -1;
ImageInf := nil;
if Supports(DataInf, IEasyImages, ImageInf) then
Result := ImageInf.ImageIndexes[Column, eikNormal]
end;
function TEasyGroupInterfaced.GetImageList(Column: Integer; IconSize: TEasyImageSize): TCustomImageList;
var
ImageList: IEasyImageList;
begin
Result := nil;
if Supports(DataInf, IEasyImageList, ImageList) then
Result := ImageList.ImageList[Column, IconSize];
if not Assigned(Result) then
Result := DefaultImageList(IconSize)
end;
function TEasyGroupInterfaced.GetImageOverlayIndexes(Column: Integer): TCommonImageIndexInteger;
var
ImageInf: IEasyImages;
begin
Result := -1;
ImageInf := nil;
if Supports(DataInf, IEasyImages, ImageInf) then
Result := ImageInf.ImageIndexes[Column, eikOverlay]
end;
procedure TEasyGroupInterfaced.ImageDraw(Column: TEasyColumn; ACanvas: TCanvas; const RectArray: TEasyRectArrayObject; AlphaBlender: TEasyAlphaBlender);
var
ImageInf: IEasyCustomImage;
begin
if Supports(DataInf, IEasyCustomImage, ImageInf) then
ImageInf.DrawImage(Column, ACanvas, RectArray, AlphaBlender)
end;
procedure TEasyGroupInterfaced.ImageDrawGetSize(Column: TEasyColumn; var ImageW: Integer; var ImageH: Integer);
var
ImageInf: IEasyCustomImage;
begin
if Supports(DataInf, IEasyCustomImage, ImageInf) then
ImageInf.GetSize(Column, ImageW, ImageH)
end;
procedure TEasyGroupInterfaced.ImageDrawIsCustom(Column: TEasyColumn;
var IsCustom: Boolean);
var
ImageInf: IEasyCustomImage;
begin
IsCustom := False;
if Supports(DataInf, IEasyCustomImage, ImageInf) then
ImageInf.CustomDrawn(Column, IsCustom)
end;
procedure TEasyGroupInterfaced.SetCaptions(Column: Integer; Value: Widestring);
var
CaptionInf: IEasyCaptionsEditable;
begin
CaptionInf := nil;
if Supports(DataInf, IEasyCaptionsEditable, CaptionInf) then
begin
CaptionInf.SetCaption(Column, Value);
Invalidate(False)
end
end;
procedure TEasyGroupInterfaced.SetDetailCount(Value: Integer);
var
DetailsInf: IEasyDetailsEditable;
begin
DetailsInf := nil;
if Supports(DataInf, IEasyDetailsEditable, DetailsInf) then
begin
DetailsInf.DetailCount := Value;
Invalidate(False)
end
end;
procedure TEasyGroupInterfaced.SetDetails(Line: Integer; Value: Integer);
var
DetailsInf: IEasyDetailsEditable;
begin
DetailsInf := nil;
if Supports(DataInf, IEasyDetailsEditable, DetailsInf) then
begin
DetailsInf.Detail[Line] := Value;
Invalidate(False)
end
end;
procedure TEasyGroupInterfaced.SetImageIndexes(Column: Integer; Value: TCommonImageIndexInteger);
var
ImageInf: IEasyImagesEditable;
begin
ImageInf := nil;
if Supports(DataInf, IEasyImagesEditable, ImageInf) then
begin
ImageInf.ImageIndexes[Column, eikNormal] := Value;
Invalidate(False)
end
end;
procedure TEasyGroupInterfaced.SetImageOverlayIndexes(Column: Integer; Value: TCommonImageIndexInteger);
var
ImageInf: IEasyImagesEditable;
begin
ImageInf := nil;
if Supports(DataInf, IEasyImagesEditable, ImageInf) then
begin
ImageInf.ImageIndexes[Column, eikOverlay] := Value;
Invalidate(False)
end
end;
procedure TEasyGroupInterfaced.ThumbnailDraw(ACanvas: TCanvas; ARect: TRect;
AlphaBlender: TEasyAlphaBlender; var DoDefault: Boolean);
begin
// not supported
end;
{ TEasyColumnStored }
constructor TEasyColumnStored.Create(ACollection: TEasyCollection);
begin
inherited Create(ACollection);
FDataHelper := TEasyDynamicDataHelper.Create;
end;
destructor TEasyColumnStored.Destroy;
begin
SetDestroyFlags;
inherited Destroy;
FreeAndNil(FDataHelper);
end;
function TEasyColumnStored.GetCaptions(Line: Integer): Widestring;
begin
Result := DataHelper.Captions[Line]
end;
function TEasyColumnStored.GetDetailCount: Integer;
begin
Result := OwnerListview.PaintInfoColumn.CaptionLines
end;
function TEasyColumnStored.GetDetails(Line: Integer): Integer;
begin
Result := DataHelper.Details[Index]
end;
function TEasyColumnStored.GetImageIndexes(Column: Integer): TCommonImageIndexInteger;
begin
Result := DataHelper.ImageIndexes[Column]
end;
function TEasyColumnStored.GetImageList(Column: Integer; IconSize: TEasyImageSize): TCustomImageList;
begin
Result := DefaultImageList(IconSize)
end;
function TEasyColumnStored.GetImageOverlayIndexes(Column: Integer): TCommonImageIndexInteger;
begin
Result := DataHelper.ImageOverlayIndexes[Column]
end;
procedure TEasyColumnStored.ImageDraw(Column: TEasyColumn; ACanvas: TCanvas; const RectArray: TEasyRectArrayObject; AlphaBlender: TEasyAlphaBlender);
begin
OwnerListview.DoColumnImageDraw(Self, ACanvas, RectArray, AlphaBlender)
end;
procedure TEasyColumnStored.ImageDrawGetSize(Column: TEasyColumn; var ImageW: Integer; var ImageH: Integer);
begin
OwnerListview.DoColumnImageGetSize(Self, ImageW, ImageH)
end;
procedure TEasyColumnStored.ImageDrawIsCustom(Column: TEasyColumn;
var IsCustom: Boolean);
begin
IsCustom := False;
OwnerListview.DoColumnImageDrawIsCustom(Self, IsCustom)
end;
procedure TEasyColumnStored.LoadFromStream(S: TStream; var Version: Integer);
begin
inherited LoadFromStream(S, Version);
DataHelper.LoadFromStream(S, Version);
// For new objects test the stream version first
// if Version > X then
// begin
// ReadStream....
// end
end;
procedure TEasyColumnStored.SaveToStream(S: TStream; Version: Integer = EASYLISTVIEW_STREAM_VERSION);
begin
inherited SaveToStream(S);
DataHelper.SaveToStream(S, Version);
// For new objects test the stream version first
// if Version > X then
// begin
// WriteStream....
// end
end;
procedure TEasyColumnStored.SetCaptions(Column: Integer; Value: Widestring);
begin
DataHelper.Captions[Column] := Value;
Invalidate(False)
end;
procedure TEasyColumnStored.SetDetailCount(Value: Integer);
begin
OwnerListview.PaintInfoColumn.CaptionLines := Value;
end;
procedure TEasyColumnStored.SetDetails(Line: Integer; Value: Integer);
begin
DataHelper.Details[Line] := Value;
Invalidate(False)
end;
procedure TEasyColumnStored.SetImageIndexes(Column: Integer; Value: TCommonImageIndexInteger);
begin
DataHelper.ImageIndexes[Column] := Value;
Invalidate(False)
end;
procedure TEasyColumnStored.SetImageOverlayIndexes(Column: Integer; Value: TCommonImageIndexInteger);
begin
DataHelper.ImageOverlayIndexes[Column] := Value;
Invalidate(False)
end;
procedure TEasyColumnStored.ThumbnailDraw(ACanvas: TCanvas; ARect: TRect;
AlphaBlender: TEasyAlphaBlender; var DoDefault: Boolean);
begin
// not implemented
end;
function TEasyColumnInterfaced.GetCaptions(Line: Integer): Widestring;
var
CaptionInf: IEasyCaptions;
begin
CaptionInf := nil;
if Supports(DataInf, IEasyCaptions, CaptionInf) then
Result := CaptionInf.Captions[Line]
end;
function TEasyColumnInterfaced.GetDetailCount: Integer;
var
DetailInf: IEasyDetails;
begin
Result := 0;
DetailInf := nil;
if Supports(DataInf, IEasyDetails, DetailInf) then
Result := DetailInf.GetDetailCount
end;
function TEasyColumnInterfaced.GetDetails(Line: Integer): Integer;
var
DetailInf: IEasyDetails;
begin
Result := 0;
DetailInf := nil;
if Supports(DataInf, IEasyDetails, DetailInf) then
Result := DetailInf.Detail[Line]
end;
function TEasyColumnInterfaced.GetImageIndexes(Column: Integer): TCommonImageIndexInteger;
var
ImageInf: IEasyImages;
begin
Result := -1;
ImageInf := nil;
if Supports(DataInf, IEasyImages, ImageInf) then
Result := ImageInf.ImageIndexes[Column, eikNormal]
end;
function TEasyColumnInterfaced.GetImageList(Column: Integer; IconSize: TEasyImageSize): TCustomImageList;
var
ImageList: IEasyImageList;
begin
Result := nil;
if Supports(DataInf, IEasyImageList, ImageList) then
Result := ImageList.ImageList[Column, IconSize];
if not Assigned(Result) then
Result := DefaultImageList(IconSize)
end;
function TEasyColumnInterfaced.GetImageOverlayIndexes(Column: Integer): TCommonImageIndexInteger;
var
ImageInf: IEasyImages;
begin
Result := -1;
ImageInf := nil;
if Supports(DataInf, IEasyImages, ImageInf) then
Result := ImageInf.ImageIndexes[Column, eikOverlay]
end;
procedure TEasyColumnInterfaced.ImageDraw(Column: TEasyColumn; ACanvas: TCanvas; const RectArray: TEasyRectArrayObject; AlphaBlender: TEasyAlphaBlender);
var
ImageInf: IEasyCustomImage;
begin
if Supports(DataInf, IEasyCustomImage, ImageInf) then
ImageInf.DrawImage(Column, ACanvas, RectArray, AlphaBlender)
end;
procedure TEasyColumnInterfaced.ImageDrawGetSize(Column: TEasyColumn; var ImageW: Integer; var ImageH: Integer);
var
ImageInf: IEasyCustomImage;
begin
if Supports(DataInf, IEasyCustomImage, ImageInf) then
ImageInf.GetSize(Column, ImageW, ImageH)
end;
procedure TEasyColumnInterfaced.ImageDrawIsCustom(Column: TEasyColumn;
var IsCustom: Boolean);
var
ImageInf: IEasyCustomImage;
begin
IsCustom := False;
if Supports(DataInf, IEasyCustomImage, ImageInf) then
ImageInf.CustomDrawn(Column, IsCustom)
end;
procedure TEasyColumnInterfaced.SetCaptions(Column: Integer; Value: Widestring);
var
CaptionInf: IEasyCaptionsEditable;
begin
CaptionInf := nil;
if Supports(DataInf, IEasyCaptionsEditable, CaptionInf) then
CaptionInf.SetCaption(Column, Value);
Invalidate(False);
end;
procedure TEasyColumnInterfaced.SetDetailCount(Value: Integer);
var
DetailsInf: IEasyDetailsEditable;
begin
DetailsInf := nil;
if Supports(DataInf, IEasyDetailsEditable, DetailsInf) then
begin
DetailsInf.DetailCount := Value;
Invalidate(False)
end
end;
procedure TEasyColumnInterfaced.SetDetails(Line: Integer; Value: Integer);
var
DetailsInf: IEasyDetailsEditable;
begin
DetailsInf := nil;
if Supports(DataInf, IEasyDetailsEditable, DetailsInf) then
begin
DetailsInf.Detail[Line] := Value;
Invalidate(False)
end
end;
procedure TEasyColumnInterfaced.SetImageIndexes(Column: Integer; Value: TCommonImageIndexInteger);
var
ImageInf: IEasyImagesEditable;
begin
ImageInf := nil;
if Supports(DataInf, IEasyImagesEditable, ImageInf) then
begin
ImageInf.ImageIndexes[Column, eikNormal] := Value;
Invalidate(False)
end
end;
procedure TEasyColumnInterfaced.SetImageOverlayIndexes(Column: Integer; Value: TCommonImageIndexInteger);
var
ImageInf: IEasyImagesEditable;
begin
ImageInf := nil;
if Supports(DataInf, IEasyImagesEditable, ImageInf) then
begin
ImageInf.ImageIndexes[Column, eikOverlay] := Value;
Invalidate(False)
end
end;
procedure TEasyColumnInterfaced.ThumbnailDraw(ACanvas: TCanvas; ARect: TRect;
AlphaBlender: TEasyAlphaBlender; var DoDefault: Boolean);
begin
// not implemented
end;
{ TEasyColumnVirtual}
function TEasyColumnVirtual.GetCaptions(Line: Integer): Widestring;
begin
Result := '';
OwnerListview.DoColumnGetCaption(Self, Line, Result)
end;
function TEasyColumnVirtual.GetDetailCount: Integer;
begin
Result := 0;
OwnerListview.DoColumnGetDetailCount(Self, Result)
end;
function TEasyColumnVirtual.GetDetails(Line: Integer): Integer;
begin
Result := 0;
OwnerListview.DoColumnGetDetail(Self, Line, Result)
end;
function TEasyColumnVirtual.GetImageIndexes(Column: Integer): TCommonImageIndexInteger;
begin
Result := -1;
OwnerListview.DoColumnGetImageIndex(Self, eikNormal, Result)
end;
function TEasyColumnVirtual.GetImageList(Column: Integer; IconSize: TEasyImageSize): TCustomImageList;
begin
Result := nil;
OwnerListview.DoColumnGetImageList(Self, Result);
if not Assigned(Result) then
Result := DefaultImageList(IconSize)
end;
function TEasyColumnVirtual.GetImageOverlayIndexes(Column: Integer): TCommonImageIndexInteger;
begin
Result := -1;
OwnerListview.DoColumnGetImageIndex(Self, eikOverlay, Result)
end;
procedure TEasyColumnVirtual.ImageDraw(Column: TEasyColumn; ACanvas: TCanvas; const RectArray: TEasyRectArrayObject; AlphaBlender: TEasyAlphaBlender);
begin
OwnerListview.DoColumnImageDraw(Self, ACanvas, RectArray, AlphaBlender)
end;
procedure TEasyColumnVirtual.ImageDrawGetSize(Column: TEasyColumn; var ImageW: Integer; var ImageH: Integer);
begin
OwnerListview.DoColumnImageGetSize(Self, ImageW, ImageH)
end;
procedure TEasyColumnVirtual.ImageDrawIsCustom(Column: TEasyColumn;
var IsCustom: Boolean);
begin
IsCustom := False;
OwnerListview.DoColumnImageDrawIsCustom(Self, IsCustom)
end;
procedure TEasyColumnVirtual.SetCaptions(Column: Integer; Value: Widestring);
begin
OwnerListview.DoColumnSetCaption(Self, Value);
Invalidate(False)
end;
procedure TEasyColumnVirtual.SetDetailCount(Value: Integer);
begin
OwnerListview.DoColumnSetDetailCount(Self, Value);
Invalidate(False)
end;
procedure TEasyColumnVirtual.SetDetails(Line: Integer; Value: Integer);
begin
OwnerListview.DoColumnSetDetail(Self, Line, Value);
Invalidate(False)
end;
procedure TEasyColumnVirtual.SetImageIndexes(Column: Integer; Value: TCommonImageIndexInteger);
begin
OwnerListview.DoColumnSetImageIndex(Self, eikNormal, Value);
Invalidate(False)
end;
procedure TEasyColumnVirtual.SetImageOverlayIndexes(Column: Integer; Value: TCommonImageIndexInteger);
begin
OwnerListview.DoColumnSetImageIndex(Self, eikOverlay, Value);
Invalidate(False)
end;
procedure TEasyColumnVirtual.ThumbnailDraw(ACanvas: TCanvas; ARect: TRect;
AlphaBlender: TEasyAlphaBlender; var DoDefault: Boolean);
begin
// not Implemented
end;
{ TEasyPaintInfoBaseItem }
constructor TEasyPaintInfoBaseItem.Create(AnOwner: TCustomEasyListview);
begin
inherited Create(AnOwner);
FTileDetailCount := 1;
FGridLineColor := clBtnFace;
end;
procedure TEasyPaintInfoBaseItem.SetGridLineColor(const Value: TColor);
begin
if FGridLineColor <> Value then
begin
FGridLineColor := Value;
OwnerListview.SafeInvalidateRect(nil, False)
end
end;
procedure TEasyPaintInfoBaseItem.SetGridLines(const Value: Boolean);
begin
if FGridLines <> Value then
begin
FGridLines := Value;
OwnerListview.SafeInvalidateRect(nil, False)
end
end;
procedure TEasyPaintInfoBaseItem.SetHideCaption(const Value: Boolean);
begin
if FHideCaption <> Value then
begin
FHideCaption := Value;
OwnerListview.SafeInvalidateRect(nil, False)
end
end;
procedure TEasyPaintInfoBaseItem.SetTileDetailCount(Value: Integer);
begin
if Value <> FTileDetailCount then
begin
FTileDetailCount := Value;
OwnerListview.SafeInvalidateRect(nil, False)
end
end;
{ TColumnPos }
function TColumnPos.Get(Index: Integer): TEasyColumn;
begin
Result := inherited Get(Index)
end;
procedure TColumnPos.Put(Index: Integer; Item: TEasyColumn);
begin
inherited Put(Index, Item)
end;
{ TEasyHeaderDragManager }
constructor TEasyHeaderDragManager.Create(AnOwner: TCustomEasyListview);
begin
inherited Create(AnOwner);
FEnableDragImage := True;
FDragImageWidth := 200;
FDragImageHeight := 300;
FEnabled := False;
DefaultImageEvent := DefaultImage;
DragMode := dmManual;
DragCursor := crDrag
end;
function TEasyHeaderDragManager.DoPtInAutoScrollDownRegion(WindowPoint: TPoint): Boolean;
begin
Result := False
end;
function TEasyHeaderDragManager.DoPtInAutoScrollLeftRegion(WindowPoint: TPoint): Boolean;
begin
Result := (WindowPoint.X < AutoScrollMargin) and (OwnerListview.View = elsReport)
end;
function TEasyHeaderDragManager.DoPtInAutoScrollRightRegion(WindowPoint: TPoint): Boolean;
begin
Result := (WindowPoint.X > (OwnerListview.ClientWidth - AutoScrollMargin)) and (OwnerListview.View = elsReport)
end;
function TEasyHeaderDragManager.DoPtInAutoScrollUpRegion(WindowPoint: TPoint): Boolean;
begin
Result := False
end;
function TEasyHeaderDragManager.GetDragCursor: TCursor;
begin
Result := OwnerListview.DragCursor
end;
function TEasyHeaderDragManager.GetDragMode: TDragMode;
begin
Result := FDragMode;
end;
procedure TEasyHeaderDragManager.DefaultImage(Sender: TCustomEasyListview; Image: TBitmap; DragStartPt: TPoint; var HotSpot: TPoint; var TransparentColor: TColor; var Handled: Boolean);
// Generates the drag image for the dragging items from the Easy Control
var
R, ViewR: TRect;
Pt: TPoint;
begin
if Assigned(Image) then
begin
TransparentColor := OwnerListview.Color;
Image.Canvas.Brush.Color := Header.Color;
Image.Canvas.FillRect(Rect(0, 0, Image.Width, Image.Height));
R := Column.DisplayRect;
HotSpot.X := DragStartPt.X - Column.DisplayRect.Left;
HotSpot.Y := DragStartPt.Y - Column.DisplayRect.Top;
if R.Left < 0 then
HotSpot.X := HotSpot.X + R.Left;
if R.Top < 0 then
HotSpot.Y := HotSpot.Y + R.Top;
ViewR := OwnerListview.ClientRect;
OffsetRect(ViewR, OwnerListview.Scrollbars.OffsetX, 0);
IntersectRect(R, R, ViewR);
SetViewPortOrgEx(Image.Canvas.Handle, -R.Left, 0, @Pt);
Header.PaintTo(Image.Canvas, R);
SetViewPortOrgEx(Image.Canvas.Handle, Pt.X, Pt.Y, nil);
Handled := True;
end
end;
procedure TEasyHeaderDragManager.DoDrag(Canvas: TCanvas; WindowPoint: TPoint; KeyState: TCommonKeyStates; var Effects: TCommonDropEffect);
var
Temp: TEasyColumn;
begin
Effects := cdeNone;
if AllowDrop then
begin
if WindowPoint.Y < Header.Height then
begin
Effects := cdeMove;
if OwnerListview.ScrollHeaderHorz then
Inc(WindowPoint.X, OwnerListview.Scrollbars.OffsetX);
Temp := Header.Columns.ColumnByPoint(WindowPoint);
if Temp <> TargetColumn then
begin
if Assigned(TargetColumn) then
begin
Exclude(TargetColumn.FState, esosDropTarget);
TargetColumn.Invalidate(True);
end;
TargetColumn := Temp;
if Assigned(TargetColumn) then
begin
Include(TargetColumn.FState, esosDropTarget);
TargetColumn.Invalidate(True);
end
end
end else
begin
if Assigned(TargetColumn) then
begin
Exclude(TargetColumn.FState, esosDropTarget);
TargetColumn.Invalidate(True);
TargetColumn := nil;
end;
end
end
end;
procedure TEasyHeaderDragManager.DoDragBegin(WindowPoint: TPoint; KeyStates: TCommonKeyStates);
var
DropSource: IDropSource;
DataObject: TEasyDataObjectManager;
DataObjInf: ICommonExtractObj;
Image: TBitmap;
TransparentColor: TColor;
dwEffect, ImageWidth, ImageHeight: Integer;
AvailableEffects: TCommonDropEffects;
DragResultEffect: TCommonOLEDragResult;
AllowDrag, Handled: Boolean;
DragResult: HRESULT;
HotPtOffset: TPoint;
DataObjectInf: IDataObject;
begin
if Enabled then
begin
inherited;
if DragType = edtOLE then
begin
DataObjectInf := nil;
DataObject := nil;
AvailableEffects := [cdeNone];
dwEffect := 0;
AllowDrag := False;
if Self is TEasyOLEDragManager then
OwnerListview.DoOLEGetDataObject(DataObjectInf);
if not Assigned(DataObjectInf) then
begin
DataObject := TEasyDataObjectManager.Create;
// Get a reference right away so it won't be freed from under us
DataObjectInf := DataObject as IDataObject;
DataObject.Listview := OwnerListview;
end;
DoOLEDragStart(DataObjectInf, AvailableEffects, AllowDrag);
if AllowDrag then
begin
if (DataObjectInf.QueryInterface(ICommonExtractObj, DataObjInf) = S_OK) then
DataObject := DataObjInf.GetObj as TEasyDataObjectManager;
if EnableDragImage and Assigned(DataObject) and OwnerListview.UseInternalDragImage then
begin
Image := TBitmap.Create;
try
ImageWidth := 0;
ImageHeight := 0;
ImageSize(ImageWidth, ImageHeight);
Image.Width := ImageWidth;
Image.Height := ImageHeight;
Image.PixelFormat := pf32Bit;
TransparentColor := clWindow;
Handled := False;
DoGetDragImage(Image, WindowPoint, HotPtOffset, TransparentColor, Handled);
if not Handled and Assigned(DefaultImageEvent) then
DefaultImageEvent(OwnerListview, Image, WindowPoint, HotPtOffset, TransparentColor, Handled);
if Handled then
DataObject.AssignDragImage(Image, HotPtOffset, TransparentColor);
finally
Image.Free
end
end;
DropSource := TEasyDropSourceManager.Create(OwnerListview);
DragResult := OwnerListview.ExecuteDragDrop(AvailableEffects, DataObjectInf, DropSource, dwEffect);
if DragResult = DRAGDROP_S_DROP then
DragResultEffect := cdrDrop
else
if DragResult = DRAGDROP_S_CANCEL then
DragResultEffect := cdrCancel
else
DragResultEffect := cdrError;
// Set it back to the default drag manager to be ready for a drop
DoOLEDragEnd(DataObjectInf, DragResultEffect, DropEffectToDropEffectStates(dwEffect), KeyStates);
DataObject.Listview := nil;
end
end else
VCLDragStart
end;
DataObjectInf := nil
end;
procedure TEasyHeaderDragManager.DoDragDrop(WindowPoint: TPoint; KeyState: TCommonKeyStates; var Effects: TCommonDropEffect);
begin
if Assigned(TargetColumn) then
Column.Position := TargetColumn.Position;
DoDragEnd(nil, WindowPoint, KeyState);
end;
procedure TEasyHeaderDragManager.DoDragEnd(Canvas: TCanvas; WindowPoint: TPoint; KeyState: TCommonKeyStates);
begin
if Assigned(TargetColumn) then
begin
Exclude(TargetColumn.FState, esosDropTarget);
TargetColumn.Invalidate(True);
end;
TargetColumn := nil;
end;
procedure TEasyHeaderDragManager.DoDragEnter(const DataObject: IDataObject; Canvas: TCanvas; WindowPoint: TPoint; KeyState: TCommonKeyStates; var Effects: TCommonDropEffect);
var
Medium: TStgMedium;
DataPtr: PHeaderClipData;
begin
AllowDrop := False;
Effects := cdeNone;
if Succeeded(DataObject.GetData(HeaderClipFormat, Medium)) then
begin
DataPtr := GlobalLock(Medium.hGlobal);
try
AllowDrop := (DataPtr^.Thread = GetCurrentThread) and (DataPtr^.Listview = OwnerListview)
finally
GlobalUnlock(Medium.hGlobal);
ReleaseStgMedium(Medium)
end
end;
end;
procedure TEasyHeaderDragManager.DoOLEDragEnd(const ADataObject: IDataObject; DragResult: TCommonOLEDragResult; ResultEffect: TCommonDropEffects; KeyStates: TCommonKeyStates);
begin
Header.ClearStates
end;
procedure TEasyHeaderDragManager.DoOLEDragStart(const ADataObject: IDataObject; var AvailableEffects: TCommonDropEffects; var AllowDrag: Boolean);
var
Medium: TStgMedium;
DataPtr: PHeaderClipData;
begin
AllowDrag := Enabled;
AvailableEffects := [cdeMove];
FillChar(Medium, SizeOf(Medium), #0);
Medium.tymed := TYMED_HGLOBAL;
Medium.hGlobal := GlobalAlloc(GHND, SizeOf(THeaderClipData));
try
DataPtr := GlobalLock(Medium.hGlobal);
DataPtr^.Column := Column;
DataPtr^.Listview := Header.OwnerListview;
DataPtr^.Thread := GetCurrentThread;
finally
GlobalUnLock(Medium.hGlobal)
end;
// Give the block to the IDataObject to dispose of
ADataObject.SetData(HeaderClipFormat, Medium, True);
end;
procedure TEasyHeaderDragManager.ImageSize(var Width, Height: Integer);
begin
Width := Column.Width;
Height := OwnerListview.Header.Height
end;
procedure TEasyHeaderDragManager.SetDragCursor(Value: TCursor);
begin
OwnerListview.DragCursor := Value
end;
procedure TEasyHeaderDragManager.SetDragMode(Value: TDragMode);
begin
FDragMode := Value
end;
procedure TEasyHeaderDragManager.SetDragType(Value: TEasyDragType);
begin
if FDragType <> Value then
begin
if Value = edtVCL then
Registered := False;
FDragType := Value;
end
end;
{ TEasyItemDynamicDataHelper }
function TEasyItemDynamicDataHelper.GetGroupKey(Index: Integer): LongWord;
begin
if Index < Length(GroupKeyArray) then
Result := GroupKeyArray[Index]
else
Result := EGT_FIRSTLETTER
end;
function TEasyItemDynamicDataHelper.GetStateImageIndexes(Index: Integer): TCommonImageIndexInteger;
begin
if Index < Length(StateImageArray) then
Result := StateImageArray[Index]
else
Result := -1
end;
procedure TEasyItemDynamicDataHelper.LoadFromStream(S: TStream; Version: Integer);
begin
inherited LoadFromStream(S, Version);
LoadIntArrayFromStream(S, FGroupKeyArray);
if Version > 2 then
begin
LoadIntArrayFromStream(S, FStateImageArray);
end
end;
procedure TEasyItemDynamicDataHelper.SaveToStream(S: TStream; Version: Integer);
begin
inherited SaveToStream(S, Version);
SaveIntArrayToStream(S, FGroupKeyArray);
SaveIntArrayToStream(S, FStateImageArray);
end;
procedure TEasyItemDynamicDataHelper.SetGroupKey(Index: Integer;
Value: LongWord);
var
OldLen, i: Integer;
begin
if Index >= Length(GroupKeyArray) then
begin
OldLen := Length(GroupKeyArray);
SetLength(FGroupKeyArray, Index + 1);
for i := OldLen to Length(GroupKeyArray) - 1 do
GroupKeyArray[i] := EGT_FIRSTLETTER
end;
GroupKeyArray[Index] := Value
end;
procedure TEasyItemDynamicDataHelper.SetStateImageIndexes(Index: Integer; Value: TCommonImageIndexInteger);
var
OldLen, i: Integer;
begin
if Index >= Length(StateImageArray) then
begin
OldLen := Length(StateImageArray);
SetLength(FStateImageArray, Index + 1);
for i := OldLen to Length(StateImageArray) - 1 do
StateImageArray[i] := -1
end;
StateImageArray[Index] := Value
end;
{ TEasySorter}
constructor TEasySorter.Create(AnOwner: TEasySortManager);
begin
inherited Create;
FOwner := AnOwner;
end;
destructor TEasyOwnedPersistentView.Destroy;
begin
FreeAndNil(FCanvasStore);
inherited Destroy;
end;
function TEasyOwnedPersistentView.GetCanvasStore: TEasyCanvasStore;
begin
if not Assigned(FCanvasStore) then
FCanvasStore := TEasyCanvasStore.Create;
Result := FCanvasStore
end;
procedure TEasyOwnedPersistentView.PaintCheckboxCore(CheckType: TEasyCheckType;
OwnerListView: TCustomEasyListView; ACanvas: TCanvas; ARect: TRect; IsEnabled,
IsChecked, IsHot, IsFlat, IsHovering, IsPending: Boolean; Obj: TEasyCollectionItem; Size: Integer);
var
{$IFDEF SpTBX}
CheckState: TCheckBoxState;
{$ENDIF}
{$IFDEF USETHEMES}
uState: Longword;
Part: BUTTONPARTS;
{$ENDIF}
Pt: TPoint;
begin
{$IFDEF SpTBX}
if not ((CheckType = ectNone) or (CheckType = ettNoneWithSpace)) then
begin
if CurrentTheme.Name <> 'Default' then
begin
if IsChecked then
CheckState := cbChecked
else
CheckState := cbUnChecked;
InflateRect(ARect, -1, -1);
SpDrawXPCheckBoxGlyph(ACanvas, ARect, IsEnabled, CheckState, IsHovering, IsPending, True, thtTBX);
Exit;
end
end;
{$ENDIF}
{$IFDEF USETHEMES}
if OwnerListview.DrawWithThemes then
begin
uState := 0;
Part := 0;
case CheckType of
ectBox:
begin
Part := BP_CHECKBOX;
if IsEnabled then
begin
if IsHovering then
begin
if IsChecked then
uState := CBS_CHECKEDHOT
else
uState := CBS_UNCHECKEDHOT
end else
if IsPending then
begin
if IsChecked then
uState := CBS_CHECKEDPRESSED
else
uState := CBS_UNCHECKEDPRESSED
end else
begin
if IsChecked then
uState := CBS_CHECKEDNORMAL
else
uState := CBS_UNCHECKEDNORMAL
end
end else
begin
if IsChecked then
uState := CBS_CHECKEDDISABLED
else
uState := CBS_UNCHECKEDDISABLED
end
end;
ectRadio:
begin
Part := BP_RADIOBUTTON;
if IsEnabled then
begin
if IsHovering then
begin
if IsChecked then
uState := RBS_CHECKEDHOT
else
uState := RBS_UNCHECKEDHOT
end else
if IsPending then
begin
if IsChecked then
uState := RBS_CHECKEDPRESSED
else
uState := RBS_UNCHECKEDPRESSED
end else
begin
if IsChecked then
uState := RBS_CHECKEDNORMAL
else
uState := RBS_UNCHECKEDNORMAL
end
end else
begin
if IsChecked then
uState := RBS_CHECKEDDISABLED
else
uState := RBS_UNCHECKEDDISABLED
end
end
end;
DrawThemeBackground(OwnerListview.Themes.ButtonTheme, ACanvas.Handle, Part, uState, ARect, nil);
Exit;
end;
{$ENDIF}
case CheckType of
ectBox:
begin
Pt := ARect.TopLeft;
if IsEnabled then
begin
if IsFlat then
DrawCheckBox(ACanvas, Pt, Size, clWhite, clBtnFace, clBlack, clBlack, clBlack, clBlack, IsChecked, IsEnabled, IsHot)
else
DrawCheckBox(ACanvas, Pt, Size, clWhite, clBtnFace, clBtnShadow, clBtnHighlight, cl3DDkShadow, cl3DLight, IsChecked, IsEnabled, IsHot)
end else
begin
if IsFlat then
DrawCheckBox(ACanvas, Pt, Size, clBtnFace, clBtnFace, clBtnShadow, clBtnShadow, clBtnShadow, clBtnShadow, IsChecked, IsEnabled, IsHot)
else
DrawCheckBox(ACanvas, Pt, Size, clBtnFace, clBtnFace, clBtnShadow, clBtnHighlight, cl3DDkShadow, cl3DLight, IsChecked, IsEnabled, IsHot)
end;
end;
ectRadio:
begin
Pt :=ARect.TopLeft;
if IsEnabled then
begin
if IsFlat then
DrawRadioButton(ACanvas, Pt, Size, clWhite, clBtnFace, clBlack, clBlack, clBlack, clBlack, IsChecked, IsEnabled, IsHot)
else
DrawRadioButton(ACanvas, Pt, Size, clWhite, clBtnFace, clBtnShadow, clBtnHighlight, cl3DDkShadow, cl3DLight, IsChecked, IsEnabled, IsHot)
end else
begin
if IsFlat then
DrawRadioButton(ACanvas, Pt, Size, clBtnFace, clBtnFace, clBtnShadow, clBtnShadow, clBtnShadow, clBtnShadow, IsChecked, IsEnabled, IsHot)
else
DrawRadioButton(ACanvas, Pt, Size, clBtnFace, clBtnFace, clBtnShadow, clBtnHighlight, cl3DDkShadow, cl3DLight, IsChecked, IsEnabled, IsHot)
end;
end
end
end;
constructor TEasyIncrementalSearchManager.Create(AnOwner: TCustomEasyListview);
begin
inherited Create(AnOwner);
FItemType := eisiVisible;
FResetTime := 2000;
end;
destructor TEasyIncrementalSearchManager.Destroy;
begin
EndTimer;
inherited
end;
function TEasyIncrementalSearchManager.IsSearching: Boolean;
//
// Returns true if the manager is in within a search sequence
//
begin
Result := eissSearching in State
end;
procedure TEasyIncrementalSearchManager.ClearSearch;
//
// Clears the search item and does any necessary clean up
begin
FSearchItem := nil;
FNextSearchItem := nil;
end;
procedure TEasyIncrementalSearchManager.EndTimer;
//
// Kills and destroys the Timer
//
begin
if eissTimerRunning in State then
begin
if KillTimer(0, hTimer) then
begin
hTimer := 0;
Exclude(FState, eissTimerRunning);
DisposeStub(FTimerStub);
end else
Exception.Create('Can not Destroy Incremental Search Timer');
end
end;
procedure TEasyIncrementalSearchManager.HandleWMChar(var Msg: TWMChar);
//
// The WM_CHAR message is passed to the manager to handle the incremental
// search
//
function CodePageFromLocale(Language: LCID): Integer;
var
Buf: array[0..6] of Char;
begin
// Determines the code page for a given locale.
// Unfortunately there is no easier way than this, currently.
GetLocaleInfo(Language, LOCALE_IDEFAULTANSICODEPAGE, Buf, 6);
Result := StrToIntDef(Buf, GetACP);
end;
function KeyUnicode(C: Char): WideChar;
// Converts the given character into its corresponding Unicode character
// depending on the active keyboard layout.
begin
MultiByteToWideChar(CodePageFromLocale(GetKeyboardLayout(0) and $FFFF),
MB_USEGLYPHCHARS, @C, 1, @Result, 1);
end;
procedure WrapToListStart(First, Last: TItemEnumFirstLast; var SearchItem: TEasyItem);
begin
case Direction of
eisdForward: SearchItem := First;
eisdBackward: SearchItem := Last;
end;
end;
procedure SearchToListEnd(Next, Prev :TItemNextEnum; var SearchItem: TEasyItem);
var
CompareResult: Integer;
begin
CompareResult := -1;
while (CompareResult <> 0) and Assigned(SearchItem) do
begin
if Assigned(SearchItem) and (SearchBuffer <> #13) then
OwnerListview.DoIncrementalSearch(SearchItem, SearchBuffer, CompareResult);
if CompareResult <> 0 then
begin
case Direction of
eisdForward: SearchItem := Next(SearchItem);
eisdBackward: SearchItem := Prev(SearchItem);
end;
end
end;
end;
procedure SearchToItem(Next, Prev :TItemNextEnum; TargetItem: TEasyItem; var SearchItem: TEasyItem);
var
CompareResult: Integer;
begin
CompareResult := -1;
while (CompareResult <> 0) and (SearchItem <> TargetItem) do
begin
if Assigned(SearchItem) and (SearchBuffer <> #13) then
OwnerListview.DoIncrementalSearch(SearchItem, SearchBuffer, CompareResult);
if CompareResult <> 0 then
begin
case Direction of
eisdForward: SearchItem := OwnerListview.Groups.NextItem(SearchItem);
eisdBackward: SearchItem := OwnerListview.Groups.PrevItem(SearchItem);
end
end
end;
if CompareResult <> 0 then
SearchItem := nil
end;
procedure SearchList(Next, Prev :TItemNextEnum; First, Last: TItemEnumFirstLast; var SearchItem: TEasyItem);
var
StartItem: TEasyItem;
begin
StartItem := SearchItem;
SearchToListEnd(Next, Prev, SearchItem);
// Keep wrapping if not found
if not Assigned(SearchItem) then
begin
WrapToListStart(First, Last, SearchItem);
SearchToItem(Next, Prev, StartItem, SearchItem);
end
end;
var
CompareResult: Integer;
Shift: TShiftState;
begin
if Enabled and IsSearching then
begin
ResetTimer;
Shift := KeyDataToShiftState(Msg.KeyData);
if ((Shift * [ssAlt, ssCtrl]) = []) and (Msg.CharCode > 31) then
begin
CompareResult := 0;
SearchBuffer := SearchBuffer + KeyUnicode(Char( Msg.CharCode));
if not Assigned(NextSearchItem) then
LoadFutureItem;
// Mimic how Explorer works
if Length(SearchBuffer) >= 2 then
begin
if SearchBuffer[1] = SearchBuffer[2] then
begin
SearchBuffer := SearchBuffer[1];
if (StartType <> eissStartOver) and Assigned(NextSearchItem) then
SearchItem := NextSearchItem
end
end else
begin
if (Length(SearchBuffer) = 1) and (StartType <> eissStartOver) and Assigned(NextSearchItem) then
SearchItem := NextSearchItem
end;
if Assigned(SearchItem) then
begin
if SearchBuffer <> #13 then
OwnerListview.DoIncrementalSearch(SearchItem, SearchBuffer, CompareResult);
ResetTimer;
if CompareResult <> 0 then
begin
case ItemType of
eisiAll: // Search All items in list
begin
SearchList(OwnerListview.Groups.NextItem,
OwnerListview.Groups.PrevItem,
OwnerListview.Groups.FirstItem,
OwnerListview.Groups.LastItem,
FSearchItem);
end;
eisiInitializedOnly: // Search only initialized items
begin
SearchList(OwnerListview.Groups.NextInitializedItem,
OwnerListview.Groups.PrevInitializedItem,
OwnerListview.Groups.FirstInitializedItem,
OwnerListview.Groups.LastInitializedItem,
FSearchItem);
end;
eisiVisible: // Search only visible items
begin
SearchList(OwnerListview.Groups.NextVisibleItem,
OwnerListview.Groups.PrevVisibleItem,
OwnerListview.Groups.FirstVisibleItem,
OwnerListview.Groups.LastVisibleItem,
FSearchItem);
end
end
end;
if Assigned(SearchItem) then
begin
// Found the item
OwnerListview.Selection.ClearAll;
OwnerListview.Selection.FocusedItem := SearchItem;
if Assigned(SearchItem) then
begin
SearchItem.Selected := True;
SearchItem.MakeVisible(emvAuto)
end;
if StartType <> eissStartOver then
LoadFutureItem;
end
end
end else
ClearSearch
end
end;
procedure TEasyIncrementalSearchManager.HandleWMKeyDown(var Msg:
TWMKeyDown);
//
// The WM_KEYDOWN message is passed to the manager to handle the incremental
// search
//
var
Shift: TShiftState;
begin
if Enabled then
begin
Shift := KeyDataToShiftState(Msg.KeyData);
// if (Shift * [ssCtrl, ssAlt] = []) and ((Msg.CharCode > VK_HELP) and (Msg.CharCode < VK_LWIN)) or ((Msg.CharCode > VK_APPS) and (Msg.CharCode < VK_F1) ) then
StartSearch
end
end;
procedure TEasyIncrementalSearchManager.LoadFutureItem;
begin
NextSearchItem := SearchItem;
case ItemType of
eisiAll:
begin
SearchPreloadItem(OwnerListview.Groups.NextItem,
OwnerListview.Groups.PrevItem,
OwnerListview.Groups.FirstItem,
OwnerListview.Groups.LastItem,
FNextSearchItem);
end;
eisiInitializedOnly: // Search only initialized items
begin
SearchPreloadItem(OwnerListview.Groups.NextInitializedItem,
OwnerListview.Groups.PrevInitializedItem,
OwnerListview.Groups.FirstInitializedItem,
OwnerListview.Groups.LastInitializedItem,
FNextSearchItem);
end;
eisiVisible: // Search only visible items
begin
SearchPreloadItem(OwnerListview.Groups.NextVisibleItem,
OwnerListview.Groups.PrevVisibleItem,
OwnerListview.Groups.FirstVisibleItem,
OwnerListview.Groups.LastVisibleItem,
FNextSearchItem);
end;
end;
end;
procedure TEasyIncrementalSearchManager.ResetSearch;
//
// Ends and resets all search criteria
//
begin
SearchBuffer := '';
if StartType <> eissLastHit then
ClearSearch;
Exclude(FState, eissSearching);
EndTimer;
end;
procedure TEasyIncrementalSearchManager.ResetTimer;
//
// Resets the timer to another FResetTime interval without stopping the current
// search process
//
begin
EndTimer;
StartTimer;
end;
procedure TEasyIncrementalSearchManager.SearchPreloadItem(Next,
Prev: TItemNextEnum; First, Last: TItemEnumFirstLast;
var SearchItem: TEasyItem);
begin
case Direction of
eisdForward: SearchItem := Next(SearchItem);
eisdBackward: SearchItem := Prev(SearchItem);
end;
if not Assigned(SearchItem) then
begin
case Direction of
eisdForward: SearchItem := First;
eisdBackward: SearchItem := Last;
end;
end
end;
procedure TEasyIncrementalSearchManager.SetSearchItem(Value: TEasyItem);
begin
if Value <> FSearchItem then
begin
ClearSearch;
FSearchItem := Value
end
end;
procedure TEasyIncrementalSearchManager.StartSearch;
procedure SetupStartOver;
begin
case ItemType of
eisiAll: // Search All items in list
begin
if Direction = eisdForward then
SearchItem := OwnerListview.Groups.FirstItem
else
SearchItem := OwnerListview.Groups.LastItem
end;
eisiInitializedOnly: // Search only initialized items
begin
if Direction = eisdForward then
SearchItem := OwnerListview.Groups.FirstInitializedItem
else
SearchItem := OwnerListview.Groups.LastInitializedItem
end;
eisiVisible: // Search only visible items
begin
if Direction = eisdForward then
SearchItem := OwnerListview.Groups.FirstVisibleItem
else
SearchItem := OwnerListview.Groups.LastVisibleItem
end;
end
end;
//
// Initializes the search called on WMKEYDOWN
//
begin
// Only call once during a Search Sequence
if not (eissSearching in State) then
begin
case StartType of
eissStartOver:
begin
SetupStartOver;
end;
eissLastHit:
begin
// The Search Item is already set up, or not
if not Assigned(SearchItem) then
SetupStartOver;
LoadFutureItem;
end;
eissFocusedNode:
begin
// By definition the Focused Item is Visible and Initalized so
// no other checks are necessary
if Assigned(OwnerListview.Selection.FocusedItem) then
begin
SearchItem := OwnerListview.Selection.FocusedItem;
LoadFutureItem;
end else
SetupStartOver;
end;
end;
StartTimer; // JDK 5.3.05
Include(FState, eissSearching);
end;
end;
procedure TEasyIncrementalSearchManager.StartTimer;
//
// Starts the Timer for the search
//
begin
if Enabled and not(eissTimerRunning in State) then
begin
TimerStub := CreateStub(Self, @TEasyIncrementalSearchManager.TimerProc);
hTimer := SetTimer(0, 0, ResetTime, TimerStub);
Include(FState, eissTimerRunning);
end
end;
procedure TEasyIncrementalSearchManager.TimerProc(Window: HWnd; uMsg: UINT;
idEvent: UINT; dwTime: DWORD);
//
// The callback for the Timer. A callback is not effected by any blocked message
// handler taking their sweet time.
//
begin
ResetSearch;
end;
{ TEasyGridFilmStripGroup }
function TEasyGridFilmStripGroup.GetCellSize: TEasyCellSize;
begin
Result := OwnerListview.CellSizes.FilmStrip
end;
procedure TEasyGridFilmStripGroup.AutoSizeCells;
begin
// Do nothing
end;
procedure TEasyGridFilmStripGroup.SetCellSize(Value: TEasyCellSize);
begin
OwnerListview.CellSizes.FilmStrip.Assign(Value)
end;
{ TEasyPersistent }
constructor TEasyPersistent.Create;
begin
inherited Create;
end;
destructor TEasyPersistent.Destroy;
begin
inherited Destroy;
end;
procedure TEasyPersistent.Assign(Source: TPersistent);
begin
inherited Assign(Source);
end;
{ TEasyGridGridGroup }
constructor TEasyGridGridGroup.Create(AnOwner: TCustomEasyListview; AnOwnerGroup: TEasyGroup);
begin
inherited Create(AnOwner, AnOwnerGroup);
FLayout := eglGrid
end;
function TEasyGridGridGroup.GetCellSize: TEasyCellSize;
begin
Result := OwnerListview.CellSizes.Grid
end;
procedure TEasyGridGridGroup.Rebuild(PrevGroup: TEasyGroup; var NextVisibleItemIndex: Integer);
var
i, Top, Bottom, Left, Offset, TopMargin,
BottomMargin, VisibleCount, ColumnIndex, ColumnLeft: Integer;
Item: TEasyItem;
Columns: TEasyColumns;
begin
AutoSizeCells;
if Assigned(PrevGroup) then
Offset := PrevGroup.DisplayRect.Bottom
else
Offset := 0;
ColumnIndex := 0;
Columns := OwnerListview.Header.Columns;
OwnerGroup.FDisplayRect := Rect(0, Offset, OwnerListview.Header.ViewWidth, Offset);
// Prepare the VisibleList for the worse case, all are visible
OwnerGroup.VisibleItems.Clear;
OwnerGroup.VisibleItems.Capacity := OwnerGroup.Items.Count;
Left := OwnerGroup.MarginLeft.RuntimeSize;
TopMargin := OwnerGroup.MarginTop.RuntimeSize;
BottomMargin := OwnerGroup.MarginBottom.RuntimeSize;
if OwnerGroup.Visible then
begin
if OwnerGroup.Expanded and (OwnerGroup.Items.Count > 0) then
begin
VisibleCount := 0;
Top := Offset + TopMargin;
Bottom := Offset + CellSize.Height + TopMargin;
for i := 0 to OwnerGroup.Items.Count - 1 do
begin
Item := OwnerGroup.Items.List.List[i]; // Direct Access for Speed
if Item.Visible then
begin
Item.FVisibleIndex := NextVisibleItemIndex;
Item.FVisibleIndexInGroup := VisibleCount;
ColumnLeft := Columns[ColumnIndex].DisplayRect.Left;
Item.FDisplayRect := Rect(Left + ColumnLeft, Top, Left + ColumnLeft + Columns[ColumnIndex].Width, Bottom);
OwnerGroup.VisibleItems.Add(Item);
Inc(ColumnIndex);
if ColumnIndex >= Columns.Count then
begin
ColumnIndex := 0;
Inc(Top, CellSize.Height);
Inc(Bottom, CellSize.Height);
end;
Inc(VisibleCount);
Inc(NextVisibleItemIndex);
end else
Item.FDisplayRect := Rect(Left, Top, Left, Top);
OwnerGroup.FDisplayRect.Bottom := Item.FDisplayRect.Bottom + BottomMargin;
end
end else
OwnerGroup.FDisplayRect := Rect(0, Offset, OwnerListview.Header.ViewWidth, Offset + TopMargin + BottomMargin);
end;
// Column Count does not relate to Report view columns. It is a more primitive
// and the Report columns are within the Grid Column
FColumnCount := Columns.Count;
if FColumnCount > 0 then
begin
FRowCount := OwnerGroup.VisibleItems.Count div FColumnCount;
if OwnerGroup.VisibleItems.Count mod FColumnCount > 0 then
Inc(FRowCount)
end else
FRowCount := 0
end;
procedure TEasyGridGridGroup.SetCellSize(Value: TEasyCellSize);
begin
OwnerListview.CellSizes.Grid := Value
end;
{ TEasyAlphaBlender}
destructor TEasyAlphaBlender.Destroy;
begin
inherited Destroy;
end;
procedure TEasyAlphaBlender.BasicBlend(Listview: TCustomEasyListview; ACanvas: TCanvas; ViewportRect: TRect; Color: TColor; Alpha: Byte = 128; UseScrollPostion: Boolean = True);
var
R: TRect;
Obj: THandle;
Bits: Windows.BITMAP;
begin
if Assigned(ACanvas) and Assigned(Listview) and not IsRectEmpty(ViewportRect) then
begin
Obj := GetCurrentObject(ACanvas.Handle, OBJ_BITMAP);
if Obj <> 0 then
if GetObject(Obj, SizeOf(Windows.BITMAP), @Bits) > 0 then
begin
if UseScrollPostion then
begin
R := Listview.Scrollbars.MapWindowRectToViewRect(Rect(0, 0, Bits.bmWidth, Bits.bmHeight));
IntersectRect(R, ViewportRect, R);
R := Listview.Scrollbars.MapViewRectToWindowRect(R);
AlphaBlend(0, ACanvas.Handle, R, Point(0, 0), cbmConstantAlphaAndColor, Alpha, ColorToRGB(Color))
end else
begin
IntersectRect(R, ViewportRect, Listview.ClientRect);
AlphaBlend(0, ACanvas.Handle, R, Point(0, 0), cbmConstantAlphaAndColor, Alpha, ColorToRGB(Color))
end
end
end
end;
procedure TEasyAlphaBlender.Blend(Listview: TCustomEasyListview; Obj: TEasyCollectionItem; ACanvas: TCanvas; ViewportRect: TRect; Image: TBitmap);
var
BlendColor: TColor;
BlendAlpha: Byte;
Scratch: TBitmap;
DoBlend: Boolean;
begin
if not IsRectEmpty(ViewportRect) then
begin
GetBlendParams(Listview, Obj, BlendAlpha, BlendColor, DoBlend);
if DoBlend and HasMMX then
begin
Scratch := TBitmap.Create;
try
Scratch.Width := Image.Width;
Scratch.Height := Image.Height;
Scratch.Assign(Image);
Scratch.PixelFormat := pf32Bit;
Scratch.TransparentMode := Image.TransparentMode;
Scratch.TransparentColor := Image.TransparentColor;
Scratch.Transparent := True;
// Now force the bitmap to create a mask based on the transparent color
Scratch.MaskHandle;
// The AlphaBlend function is low level so TBitmap does not know anything happened to it
AlphaBlend(0, Scratch.Canvas.Handle, Rect(0, 0, Scratch.Width, Scratch.Height), Point(0, 0), cbmConstantAlphaAndColor, BlendAlpha, ColorToRGB(BlendColor));
// Since we got the mask before the AlphaBlend occured the original mask is
// used and all is correct.
ACanvas.Draw(ViewportRect.Left + (RectWidth(ViewportRect) - Scratch.Width) div 2,
ViewportRect.Top + (RectHeight(ViewportRect) - Scratch.Height) div 2,
Scratch);
finally
Scratch.Free
end
end else
ACanvas.Draw(ViewportRect.Left + (RectWidth(ViewportRect) - Image.Width) div 2,
ViewportRect.Top + (RectHeight(ViewportRect) - Image.Height) div 2,
Image);
end
end;
procedure TEasyAlphaBlender.GetBlendParams(Listview: TCustomEasyListview; Obj: TEasyCollectionItem; var BlendAlpha: Byte; var BlendColor: TColor; var DoBlend: Boolean);
begin
DoBlend := False;
if Assigned(Listview) then
begin
if Listview.Focused then
begin
if Obj.Enabled then
begin
BlendAlpha := Listview.Selection.BlendAlphaImage;
BlendColor := Listview.Selection.Color
end else
begin
BlendAlpha := Listview.DisabledBlendAlpha;
BlendColor := Listview.DisabledBlendColor;
end
end else
begin
BlendAlpha := Listview.DisabledBlendAlpha;
BlendColor := Listview.Selection.InactiveColor;
end;
DoBlend := Obj.Selected or Obj.Hilighted or (not Obj.Enabled and Listview.Focused)
end
end;
{ TEasyBaseTaskBand }
constructor TEasyBaseTaskBand.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
BackGround := TEasyTaskBandBackgroundManager.Create(Self);
HotTrack.Enabled := True;
PaintInfoGroup.CaptionIndent := 9;
PaintInfoGroup.MarginBottom.Size := 3;
PaintInfoGroup.MarginBottom.Visible := True;
PaintInfoGroup.MarginLeft.Size := 11;
PaintInfoGroup.MarginLeft.Visible := True;
PaintInfoGroup.MarginRight.Size := 11;
PaintInfoGroup.MarginRight.Visible := True;
PaintInfoGroup.MarginTop.Size := 26;
ShowGroupMargins := True;
Selection.Enabled := False;
HotTrack.GroupTrack := HotTrack.GroupTrack + [htgTopMargin]
end;
function TEasyBaseTaskBand.CreateColumnPaintInfo: TEasyPaintInfoBaseColumn;
begin
Result:= TEasyPaintInfoTaskBandColumn.Create(Self)
end;
function TEasyBaseTaskBand.CreateGroupPaintInfo: TEasyPaintInfoBaseGroup;
begin
Result := TEasyPaintInfoTaskBandGroup.Create(Self)
end;
function TEasyBaseTaskBand.CreateItemPaintInfo: TEasyPaintInfoBaseItem;
begin
Result:= TEasyPaintInfoTaskBandItem.Create(Self)
end;
function TEasyBaseTaskBand.GetPaintInfoColumn: TEasyPaintInfoTaskBandColumn;
begin
Result := inherited PaintInfoColumn as TEasyPaintInfoTaskbandColumn
end;
function TEasyBaseTaskBand.GetPaintInfoGroup: TEasyPaintInfoTaskbandGroup;
begin
Result := inherited PaintInfoGroup as TEasyPaintInfoTaskbandGroup
end;
function TEasyBaseTaskBand.GetPaintInfoItem: TEasyPaintInfoTaskBandItem;
begin
Result := inherited PaintInfoItem as TEasyPaintInfoTaskbandItem
end;
function TEasyBaseTaskBand.GroupTestExpand(HitInfo: TEasyGroupHitTestInfoSet): Boolean;
begin
Result:= egtOnHeader in HitInfo
end;
procedure TEasyBaseTaskBand.DoCustomGrid(Group: TEasyGroup; ViewStyle: TEasyListStyle; var Grid: TEasyGridGroupClass);
begin
if Assigned(OnCustomGrid) then
OnCustomGrid(Self, Group, ViewStyle, Grid);
if not Assigned(Grid) then
Grid := TEasyGridTaskBandGroup
end;
procedure TEasyBaseTaskBand.DoGroupCustomView(Group: TEasyGroup; ViewStyle: TEasyListStyle; var View: TEasyViewGroupClass);
begin
if Assigned(OnGroupCustomView) then
OnGroupCustomView(Self, Group, ViewStyle, View);
if not Assigned(View) then
View := TEasyViewTaskBandGroup
end;
procedure TEasyBaseTaskBand.DoItemCustomView(Item: TEasyItem; ViewStyle: TEasyListStyle; var View: TEasyViewItemClass);
begin
if Assigned(OnItemCustomView) then
OnItemCustomView(Self, Item, ViewStyle, View);
if not Assigned(View) then
View := TEasyViewTaskBandItem
end;
procedure TEasyBaseTaskBand.SetPaintInfoColumn(const Value: TEasyPaintInfoTaskBandColumn);
begin
inherited PaintInfoColumn := Value
end;
procedure TEasyBaseTaskBand.SetPaintInfoGroup(const Value: TEasyPaintInfoTaskbandGroup);
begin
inherited PaintInfoGroup := Value
end;
procedure TEasyBaseTaskBand.SetPaintInfoItem(const Value: TEasyPaintInfoTaskBandItem);
begin
inherited PaintInfoItem := Value
end;
{ TGridTaskBandGroup }
constructor TEasyGridTaskBandGroup.Create(AnOwner: TCustomEasyListview; AnOwnerGroup: TEasyGroup);
begin
inherited Create(AnOwner, AnOwnerGroup);
CellSize := TEasyCellSize.Create(AnOwner)
end;
destructor TEasyGridTaskBandGroup.Destroy;
begin
inherited Destroy;
FreeAndNil(FCellSize);
end;
function TEasyGridTaskBandGroup.GetCellSize: TEasyCellSize;
begin
FCellSize.FWidth := OwnerListview.ClientWidth - 1 - OwnerListview.PaintInfoGroup.MarginLeft.Size - OwnerListview.PaintInfoGroup.MarginRight.Size;
// if OwnerListview.Scrollbars.VertBarVisible then
// Dec(FCellSize.FWidth, GetSystemMetrics(SM_CXVSCROLL));
FCellSize.FHeight := 24;
Result := FCellSize
end;
function TEasyGridTaskBandGroup.StaticTopItemMargin: Integer;
begin
Result := 10;
end;
function TEasyGridTaskBandGroup.StaticTopMargin: Integer;
begin
Result := 11;
end;
procedure TEasyGridTaskBandGroup.SetCellSize(Value: TEasyCellSize);
begin
end;
procedure TEasyGridSingleColumn.AutoSizeCells;
begin
// Do nothing
end;
procedure TEasyGridSingleColumn.FindInsertPosition(ViewportPoint: TPoint; var Group: TEasyGroup; var Index: Integer);
begin
Group := nil;
Index := -1
end;
function TEasyGridSingleColumn.GetCellSize: TEasyCellSize;
begin
Result := nil
end;
{ TGridSingleColumn }
function TEasyGridSingleColumn.GetMaxColumns(Group: TEasyGroup; WindowWidth: Integer): Integer;
begin
Result := 1;
end;
procedure TEasyGridSingleColumn.SetCellSize(Value: TEasyCellSize);
begin
end;
{ TEasyViewTaskBandGroup}
function TEasyViewTaskBandGroup.DrawThemed: Boolean;
begin
Result := True
end;
procedure TEasyViewTaskBandGroup.GetExpandImageSize(Group: TEasyGroup; var ImageW: Integer; var ImageH: Integer);
{$IFDEF USETHEMES}
var
PartID, StateID: LongWord;
R: TRect;
{$ENDIF}
begin
ImageW := 0;
ImageH := 0;
if Group.Expandable then
begin
{$IFDEF USETHEMES}
if Group.OwnerListview.DrawWithThemes then
begin
StateID := EBNGC_NORMAL;
if Group.Expanded then
PartID := EBP_NORMALGROUPCOLLAPSE
else
PartID := EBP_NORMALGROUPEXPAND;
if Group.Hilighted then
StateID := StateID or EBNGC_HOT;
R := Rect(0, 0, 0, 0);
// If too small it returns the negative rectangle of the ideal size
if Succeeded(GetThemeBackgroundExtent(OwnerListview.Themes.ExplorerBarTheme, 0, PartID, StateID, R, R)) then
begin
ImageW := Abs(RectWidth(R));
ImageH := Abs(RectHeight(R));
end
end else
begin
ImageW := 16;
ImageH := 16;
end;
{$ELSE}
ImageW := 16;
ImageH := 16;
{$ENDIF}
end;
end;
procedure TEasyViewTaskBandGroup.GroupRectArray(Group: TEasyGroup; MarginEdge: TEasyGroupMarginEdge; ObjRect: TRect; var RectArray: TEasyRectArrayObject);
//
// Grabs all the rectangles for the items within a cell in one call
// If PaintInfo is nil then the information is fetched automaticlly
//
var
TextSize: TSize;
HeaderBand, FooterBand: TRect;
TempRectArray: TEasyRectArrayObject;
ImageW, ImageH, ExpandImageW, ExpandImageH: Integer;
begin
Group.Initialized := True;
FillChar(RectArray, SizeOf(RectArray), #0);
RectArray.GroupRect := ObjRect;
RectArray.BackGndRect := Group.BoundsRectBkGnd;
GetExpandImageSize(Group, ExpandImageW, ExpandImageH);
GetImageSize(Group, ImageW, ImageH);
if MarginEdge in [egmeTop, egmeBottom] then
begin
// Calculate the Expansion button first for the Header only
if Group.Expandable and (MarginEdge = egmeTop) then
RectArray.ExpandButtonRect := Rect(RectArray.BackGndRect.Right - Group.ExpandImageIndent - ExpandImageW,
RectArray.GroupRect.Top,
RectArray.BackGndRect.Right,
RectArray.GroupRect.Bottom)
else // Make the ExpandButton R a width of 0
RectArray.ExpandButtonRect := Rect(RectArray.GroupRect.Left,
RectArray.GroupRect.Top,
RectArray.GroupRect.Left,
RectArray.GroupRect.Bottom);
if (Group.CheckType <> ectNone) and (MarginEdge in [egmeTop]) then
begin
RectArray.CheckRect := Checks.Bound[Group.Checksize];
OffsetRect(RectArray.CheckRect, RectArray.BackGndRect.Left + Group.CheckIndent, ObjRect.Top + (RectHeight(ObjRect) - RectHeight(RectArray.CheckRect)) div 2);
end else
begin
// CheckRect is a 0 width
RectArray.CheckRect := ObjRect;
RectArray.CheckRect.Left := RectArray.BackGndRect.Left;
RectArray.CheckRect.Right := RectArray.BackGndRect.Left;
end;
// Now Calculate the image for the header or the footer
if Group.ImageIndex > -1 then
RectArray.IconRect := Rect(RectArray.CheckRect.Right + Group.ImageIndent,
RectArray.GroupRect.Top,
RectArray.CheckRect.Right + ImageW + Group.ImageIndent,
RectArray.GroupRect.Bottom)
else // Make the IconR a width of 0
RectArray.IconRect := Rect(RectArray.CheckRect.Right,
RectArray.CheckRect.Top,
RectArray.CheckRect.Right,
RectArray.CheckRect.Bottom);
// Now the Label rect may be calculated for the header or footer
RectArray.LabelRect := Rect(RectArray.IconRect.Right + Group.CaptionIndent,
RectArray.ExpandButtonRect.Top,
RectArray.ExpandButtonRect.Left,
RectArray.ExpandButtonRect.Bottom);
// Calculate the text size for the text based on the above font
if Assigned(OwnerListview.ScratchCanvas) then
begin
LoadTextFont(Group, OwnerListview.ScratchCanvas);
TextSize := TextExtentW(Group.Caption, OwnerListview.ScratchCanvas.Font);
end else
begin
TextSize.cx := 0;
TextSize.cy := 0
end;
RectArray.TextRect := Rect(RectArray.LabelRect.Left,
RectArray.LabelRect.Top,
RectArray.LabelRect.Left + TextSize.cx,
RectArray.LabelRect.Top + TextSize.cy);
if RectArray.TextRect.Right > RectArray.LabelRect.Right then
RectArray.TextRect.Right := RectArray.LabelRect.Right;
if RectArray.TextRect.Bottom > RectArray.LabelRect.Bottom then
RectArray.TextRect.Bottom := RectArray.LabelRect.Bottom;
case Group.Alignment of
taLeftJustify: OffsetRect(RectArray.TextRect, 0, 0);
taRightJustify: OffsetRect(RectArray.TextRect, RectWidth(RectArray.LabelRect) - (RectWidth(RectArray.TextRect)), 0);
taCenter: OffsetRect(RectArray.TextRect, (RectWidth(RectArray.LabelRect) - RectWidth(RectArray.TextRect)) div 2, 0);
end;
case Group.VAlignment of
cvaBottom: OffsetRect(RectArray.TextRect, 0, RectHeight(RectArray.GroupRect) - (RectHeight(RectArray.TextRect) + Group.BandThickness + Group.BandMargin));
cvaCenter: OffsetRect(RectArray.TextRect, 0, (RectHeight(RectArray.GroupRect) - RectHeight(RectArray.TextRect)) div 2);
end;
// Use the calculated label rectangle to position where the text goes
if Group.BandEnabled then
begin
if Group.BandFullWidth then
RectArray.BandRect := Rect(RectArray.GroupRect.Left,
RectArray.GroupRect.Bottom - Group.BandMargin - Group.BandThickness,
RectArray.GroupRect.Right,
RectArray.GroupRect.Bottom - Group.BandMargin)
else
RectArray.BandRect := Rect(RectArray.GroupRect.Left,
RectArray.GroupRect.Bottom - Group.BandMargin - Group.BandThickness,
RectArray.GroupRect.Left + Group.BandLength,
RectArray.GroupRect.Bottom - Group.BandMargin);
OffsetRect(RectArray.BandRect, Group.BandIndent, Group.BandMargin);
end;
end else
begin // Calculate the margin rectangles
// Need to send nil so the user attributes are fetched for the header
GroupRectArray(Group, egmeTop, Group.BoundsRectTopMargin, TempRectArray);
HeaderBand := TempRectArray.BandRect;
// Need to send nil so the user attributes are fetched for the footer
GroupRectArray(Group, egmeBottom, Group.BoundsRectBottomMargin, TempRectArray);
FooterBand := TempRectArray.BandRect;
if MarginEdge = egmeLeft then
RectArray.BandRect := Rect(RectArray.GroupRect.Left + (RectWidth(RectArray.GroupRect) - Group.BandThickness) div 2,
HeaderBand.Top,
RectArray.GroupRect.Right,
FooterBand.Bottom - 1);
if MarginEdge = egmeRight then
RectArray.BandRect := Rect(RectArray.GroupRect.Left,
HeaderBand.Top,
RectArray.GroupRect.Right - (RectWidth(RectArray.GroupRect) - Group.BandThickness) div 2,
FooterBand.Bottom - 1)
end;
end;
procedure TEasyViewTaskBandGroup.LoadTextFont(Group: TEasyGroup; ACanvas: TCanvas);
begin
{$IFDEF USETHEMES}
inherited LoadTextFont(Group, ACanvas);
if not(Group.OwnerListview.DrawWithThemes) then
begin
if Group.Bold then
ACanvas.Font.Color := clHighlightText
end;
{$ELSE}
inherited LoadTextFont(Group, ACanvas);
if Group.Bold then
ACanvas.Font.Color := clHighlightText
{$ENDIF}
end;
procedure TEasyViewTaskBandGroup.PaintBackground(Group: TEasyGroup; ACanvas: TCanvas; MarginEdge: TEasyGroupMarginEdge; ObjRect: TRect; RectArray: TEasyRectArrayObject);
procedure DrawNonThemed;
begin
if Group.Bold then
ACanvas.Brush.Color := clHighlight
else
ACanvas.Brush.Color := clBtnFace;
case MarginEdge of
egmeBackground: ACanvas.FrameRect(RectArray.BackGndRect);
egmeTop: ACanvas.FillRect(RectArray.GroupRect);
end
end;
{$IFDEF USETHEMES}
var
PartID, StateID: LongWord;
R, HeaderR: TRect;
{$ENDIF}
begin
{$IFDEF USETHEMES}
if Group.OwnerListview.DrawWithThemes then
begin
case MarginEdge of
egmeBackground:
begin
// Draw the group background
R := RectArray.BackGndRect;
if Group.Bold then
PartID := EBP_SPECIALGROUPBACKGROUND
else
PartID := EBP_NORMALGROUPBACKGROUND;
StateID := 0;
DrawThemeBackground(OwnerListview.Themes.ExplorerBarTheme, ACanvas.Handle, PartID, StateID, R, nil);
end;
egmeTop:
begin
// Draw the group header
HeaderR := RectArray.BackGndRect;
HeaderR.Bottom := HeaderR.Top - 1;
HeaderR.Top := HeaderR.Top - OwnerListview.PaintInfoGroup.MarginTop.RuntimeSize;
if Group.Bold then
PartID := EBP_SPECIALGROUPHEAD
else
PartID := EBP_NORMALGROUPHEAD;
StateID := 0;
DrawThemeBackground(OwnerListview.Themes.ExplorerBarTheme, ACanvas.Handle, PartID, StateID, HeaderR, nil);
end
end
end else
DrawNonThemed;
Exit;
{$ELSE}
DrawNonThemed;
{$ENDIF}
end;
procedure TEasyViewTaskBandGroup.PaintBand(Group: TEasyGroup; ACanvas: TCanvas; MarginEdge: TEasyGroupMarginEdge; ObjRect: TRect; RectArray: TEasyRectArrayObject);
begin
// Don't do inherited
end;
procedure TEasyViewTaskBandGroup.PaintExpandButton(Group: TEasyGroup; ACanvas: TCanvas; MarginEdge: TEasyGroupMarginEdge; ObjRect: TRect; RectArray: TEasyRectArrayObject);
procedure DrawNonThemed;
var
RCenterX, RCenterY, RCenterY1, RCenterY2: Integer;
ExpandW, ExpandH: Integer;
R: TRect;
begin
GetExpandImageSize(Group, ExpandW, ExpandH);
if Group.Bold then
ACanvas.Pen.Color := clHighlightText
else
ACanvas.Pen.Color := clBlack;
ACanvas.Pen.Width := 1;
RCenterX := RectArray.ExpandButtonRect.Left + ExpandW div 2;
RCenterY := RectArray.ExpandButtonRect.Top + ((RectHeight(RectArray.ExpandButtonRect)-ExpandH) div 2) + (ExpandH div 2);
if Group.Expanded then
begin
RCenterY2 := RCenterY;
RCenterY1 := RCenterY2 - 4;
ACanvas.MoveTo(RCenterX, RCenterY1);
ACanvas.LineTo(RCenterX - 4, RCenterY1 + 4);
ACanvas.MoveTo(RCenterX, RCenterY1);
ACanvas.LineTo(RCenterX + 4, RCenterY1 + 4);
ACanvas.MoveTo(RCenterX, RCenterY2);
ACanvas.LineTo(RCenterX - 4, RCenterY2 + 4);
ACanvas.MoveTo(RCenterX, RCenterY2);
ACanvas.LineTo(RCenterX + 4, RCenterY2 + 4);
Inc(RCenterY1);
Inc(RCenterY2);
ACanvas.MoveTo(RCenterX, RCenterY1);
ACanvas.LineTo(RCenterX - 3, RCenterY1 + 3);
ACanvas.MoveTo(RCenterX, RCenterY1);
ACanvas.LineTo(RCenterX + 3, RCenterY1 + 3);
ACanvas.MoveTo(RCenterX, RCenterY2);
ACanvas.LineTo(RCenterX - 3, RCenterY2 + 3);
ACanvas.MoveTo(RCenterX, RCenterY2);
ACanvas.LineTo(RCenterX + 3, RCenterY2 + 3);
end else
begin
RCenterY2 := RCenterY;
RCenterY1 := RCenterY2 + 4;
ACanvas.MoveTo(RCenterX, RCenterY1);
ACanvas.LineTo(RCenterX - 4, RCenterY1 - 4);
ACanvas.MoveTo(RCenterX, RCenterY1);
ACanvas.LineTo(RCenterX + 4, RCenterY1 - 4);
ACanvas.MoveTo(RCenterX, RCenterY2);
ACanvas.LineTo(RCenterX - 4, RCenterY2 - 4);
ACanvas.MoveTo(RCenterX, RCenterY2);
ACanvas.LineTo(RCenterX + 4, RCenterY2 - 4);
Dec(RCenterY1);
Dec(RCenterY2);
ACanvas.MoveTo(RCenterX, RCenterY1);
ACanvas.LineTo(RCenterX - 3, RCenterY1 - 3);
ACanvas.MoveTo(RCenterX, RCenterY1);
ACanvas.LineTo(RCenterX + 3, RCenterY1 - 3);
ACanvas.MoveTo(RCenterX, RCenterY2);
ACanvas.LineTo(RCenterX - 3, RCenterY2 - 3);
ACanvas.MoveTo(RCenterX, RCenterY2);
ACanvas.LineTo(RCenterX + 3, RCenterY2 - 3);
end;
if Group.Hilighted then
begin
R := Rect(RCenterX - ExpandW div 2,
RCenterY - ExpandH div 2,
RCenterX + ExpandW div 2,
RCenterY + ExpandH div 2);
DrawEdge(ACanvas.Handle, R, BDR_RAISEDOUTER, BF_RECT);
end
end;
{$IFDEF USETHEMES}
var
PartID, StateID: LongWord;
{$ENDIF}
begin
if (MarginEdge = egmeTop) and Group.Expandable then
begin
{$IFDEF USETHEMES}
if Group.OwnerListview.DrawWithThemes then
begin
StateID := EBNGC_NORMAL;
if Group.Bold then
begin
if Group.Expanded then
PartID := EBP_SPECIALGROUPCOLLAPSE
else
PartID := EBP_SPECIALGROUPEXPAND;
end else
begin
if Group.Expanded then
PartID := EBP_NORMALGROUPCOLLAPSE
else
PartID := EBP_NORMALGROUPEXPAND;
end;
if Group.Hilighted then
StateID := StateID or EBNGC_HOT;
DrawThemeBackground(OwnerListview.Themes.ExplorerBarTheme, ACanvas.Handle, PartID, StateID, RectArray.ExpandButtonRect, nil);
end else
DrawNonThemed;
{$ELSE}
DrawNonThemed;
{$ENDIF}
end
end;
procedure TEasyViewTaskBandGroup.PaintText(Group: TEasyGroup; MarginEdge: TEasyGroupMarginEdge; ACanvas: TCanvas; ObjRect: TRect; RectArray: TEasyRectArrayObject);
begin
{$IFDEF USETHEMES}
if DrawThemed and (MarginEdge = egmeTop) and Group.OwnerListview.DrawWithThemes then
begin
PaintTextTopThemed(ACanvas, Group, ObjRect, RectArray);
end else
inherited;
{$ELSE}
inherited;
{$ENDIF}
end;
procedure TEasyViewTaskBandGroup.PaintTextTopThemed(ACanvas: TCanvas; Group: TEasyGroup; ObjRect: TRect; RectArray: TEasyRectArrayObject);
{$IFDEF USETHEMES}
var
PartID, StateID: LongWord;
Flags, Flags2: DWORD;
{$ENDIF}
begin
{$IFDEF USETHEMES}
if Group.Bold then
PartID := EBP_SPECIALGROUPHEAD
else
PartID := EBP_NORMALGROUPHEAD;
StateID := 0;
Flags := 0;
case Group.Alignment of
taLeftJustify: Flags := Flags or DT_LEFT;
taRightJustify: Flags := Flags or DT_RIGHT;
taCenter: Flags := Flags or DT_CENTER;
end;
case Group.VAlignment of
cvaTop: Flags := Flags or DT_TOP;
cvaCenter: Flags := Flags or DT_VCENTER;
cvaBottom: Flags := Flags or DT_BOTTOM;
end;
Flags := Flags or DT_SINGLELINE or DT_END_ELLIPSIS;
if Group.Enabled then
Flags2 := 0
else
Flags2 := 1;
DrawThemeText(OwnerListview.Themes.ExplorerBarTheme, ACanvas.Handle, PartID, StateID, PWideChar(Group.Caption), -1, Flags, Flags2, RectArray.LabelRect);
{$ENDIF USETHEMES}
end;
{ TEasyTaskBandBackgroundManager }
procedure TEasyTaskBandBackgroundManager.PaintTo(ACanvas: TCanvas; ARect: TRect; PaintDefault: Boolean);
{$IFDEF USETHEMES}
var
PartID, StateID: LongWord;
R: TRect;
Theme: HTheme;
{$ENDIF}
begin
{$IFDEF USETHEMES}
Theme := OwnerListview.Themes.ExplorerBarTheme;
if OwnerListview.DrawWithThemes then
begin
// Draw the blue background
R := OwnerListview.ClientRect;
PartID := 0;
StateID := 0;
DrawThemeBackground(Theme, ACanvas.Handle, PartID, StateID, R, nil);
end
{$ENDIF}
end;
function TEasyListview.GetPaintInfoColumn: TEasyPaintInfoColumn;
begin
Result := inherited PaintInfoColumn as TEasyPaintInfoColumn
end;
function TEasyListview.GetPaintInfoGroup: TEasyPaintInfoGroup;
begin
Result := inherited PaintInfoGroup as TEasyPaintInfoGroup
end;
function TEasyListview.GetPaintInfoItem: TEasyPaintInfoItem;
begin
Result := inherited PaintInfoItem as TEasyPaintInfoItem
end;
procedure TEasyListview.SetPaintInfoColumn(const Value: TEasyPaintInfoColumn);
begin
inherited PaintInfoColumn := Value
end;
procedure TEasyListview.SetPaintInfoGroup(const Value: TEasyPaintInfoGroup);
begin
inherited PaintInfoGroup := Value
end;
procedure TEasyListview.SetPaintInfoItem(const Value: TEasyPaintInfoItem);
begin
inherited PaintInfoItem := Value
end;
{ TCanvasStore }
destructor TEasyCanvasStore.Destroy;
begin
FreeAndNil(FFont);
FreeAndNil(FBrush);
FreeAndNil(FPen);
inherited Destroy;
end;
procedure TEasyCanvasStore.RestoreCanvasState(Canvas: TCanvas);
begin
Canvas.Pen.Assign(Pen);
Canvas.Brush.Assign(Brush);
Canvas.Font.Assign(Font);
end;
procedure TEasyCanvasStore.StoreCanvasState(Canvas: TCanvas);
begin
if not Assigned(Pen) then
Pen := TPen.Create;
if not Assigned(Brush) then
Brush := TBrush.Create;
if not Assigned(Font) then
Font := TFont.Create;
Pen.Assign(Canvas.Pen);
Brush.Assign(Canvas.Brush);
Font.Assign(Canvas.Font)
end;
procedure TEasyMemoEditor.CalculateEditorRect(NewText: WideString; var NewRect: TRect);
var
DrawFlags: TCommonDrawTextWFlags;
DC: HDC;
Font, OldFont: HFont;
TextM: TTextMetric;
begin
OldFont := 0;
if NewText = '' then
NewText := ' ';
Font := GetEditorFont.Handle;
DrawFlags := [dtCalcRectAdjR, dtCalcRect, dtCalcRectAlign];
// Center horizontally for multi-line edits
DrawFlags := DrawFlags + [dtCenter];
DC := GetDC(Editor.Handle);
try
OldFont := SelectObject(DC, Font);
NewRect := RectArray.LabelRect;
InflateRect(NewRect, -4, -2);
NewRect := Listview.Scrollbars.MapViewRectToWindowRect(NewRect);
DrawTextWEx(DC, NewText, NewRect, DrawFlags, -1);
InflateRect(NewRect, H_STRINGEDITORMARGIN, V_STRINGEDITORMARGIN + 1);
GetTextMetrics(DC, TextM);
if NewRect.Right > Listview.ClientWidth - TextM.tmAveCharWidth + H_STRINGEDITORMARGIN then
NewRect.Right := Listview.ClientWidth - TextM.tmAveCharWidth + H_STRINGEDITORMARGIN;
if NewRect.Bottom > Listview.ClientHeight - V_STRINGEDITORMARGIN then
NewRect.Bottom := Listview.ClientHeight - V_STRINGEDITORMARGIN;
// Center horizontally for multi-line edits
NewRect.Right := NewRect.Left + RectWidth(NewRect)
finally
if OldFont <> 0 then
SelectObject(DC, OldFont);
ReleaseDC(Editor.Handle, DC);
end
end;
procedure TEasyMemoEditor.CreateEditor(var AnEditor: TWinControl; Column: TEasyColumn; Parent: TWinControl);
var
Memo: TEasyMemo;
begin
AnEditor := TEasyMemo.Create(nil);
Memo := (AnEditor as TEasyMemo);
Memo.Visible := False;
Memo.Parent := Listview; // Do this first or it resets at least BorderStyle to True
Memo.Alignment := taCenter;
Memo.Text := EditText(Item, Column);
Memo.OnKeyDown := OnEditKeyDown;
{$IFDEF USETHEMES}
if not Listview.Themed then
{$ENDIF USETHEMES}
begin
Memo.Ctl3D := False;
Memo.BorderStyle := bsSingle;
{$IFDEF COMPILER_6_UP}
Memo.BevelInner := bvNone;
Memo.BevelOuter := bvNone;
Memo.BevelKind := bkNone;
{$ENDIF}
end
end;
function TEasyMemoEditor.GetEditorFont: TFont;
begin
Result := (Editor as TEasyMemo).Font
end;
function TEasyMemoEditor.GetText: VAriant;
begin
Result := (Editor as TEasyMemo).Text
end;
procedure TEasyMemoEditor.DoEditKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState; var DoDefault: Boolean);
begin
end;
procedure TEasyMemoEditor.OnEditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
//
// Check to see if the user is finished, if not test to see if the edit needs
// to be resized to reflect the new text
//
var
DoDefault: Boolean;
begin
DoDefault := True;
DoEditKeyDown(Sender, Key, Shift, DoDefault);
if DoDefault then
begin
if Key = VK_RETURN then
begin
Key := 0;
AcceptEdit;
end else
if Key = VK_F2 then
begin
SelectAll
end else
PostMessage(Editor.Handle, WM_EDITORRESIZE, 0, 0);
end;
FModified := True;
end;
procedure TEasyMemoEditor.SelectAll;
begin
(Editor as TEasyMemo).SelectAll;
end;
procedure TEasyMemoEditor.SetEditorFocus;
begin
inherited SetEditorFocus;
SelectAll;
end;
{ TEasyStringEditor}
procedure TEasyStringEditor.CalculateEditorRect(NewText: WideString; var NewRect: TRect);
var
DrawFlags: TCommonDrawTextWFlags;
DC: HDC;
Font, OldFont: HFont;
TextM: TTextMetric;
begin
OldFont := 0;
if NewText = '' then
NewText := ' ';
Font := GetEditorFont.Handle;
DrawFlags := [dtCalcRectAdjR, dtCalcRect, dtCalcRectAlign];
DrawFlags := DrawFlags + [dtLeft, dtVCenter];
DC := GetDC(Editor.Handle);
try
OldFont := SelectObject(DC, Font);
NewRect := RectArray.LabelRect;
InflateRect(NewRect, -4, -2);
NewRect := Listview.Scrollbars.MapViewRectToWindowRect(NewRect);
DrawTextWEx(DC, NewText, NewRect, DrawFlags, 1);
InflateRect(NewRect, H_STRINGEDITORMARGIN div 2, V_STRINGEDITORMARGIN);
GetTextMetrics(DC, TextM);
if NewRect.Right > Listview.ClientWidth - TextM.tmAveCharWidth + H_STRINGEDITORMARGIN then
NewRect.Right := Listview.ClientWidth - TextM.tmAveCharWidth + H_STRINGEDITORMARGIN;
if NewRect.Bottom > Listview.ClientHeight - V_STRINGEDITORMARGIN then
NewRect.Bottom := Listview.ClientHeight - V_STRINGEDITORMARGIN;
NewRect.Right := NewRect.Left + RectWidth(NewRect) + TextM.tmAveCharWidth;
finally
if OldFont <> 0 then
SelectObject(DC, OldFont);
ReleaseDC(Editor.Handle, DC);
end
end;
procedure TEasyStringEditor.CreateEditor(var AnEditor: TWinControl; Column: TEasyColumn; Parent: TWinControl);
var
Edit: TEasyEdit;
begin
AnEditor := TEasyEdit.Create(nil);
Edit := AnEditor as TEasyEdit;
Edit.Visible := False;
Edit.Parent := Listview; // Do this first or it resets at least BorderStyle to True
Edit.Text := EditText(Item, Column);
Edit.OnKeyDown := OnEditKeyDown;
{$IFDEF USETHEMES}
if not Listview.Themed then
{$ENDIF USETHEMES}
begin
Edit.Ctl3D := False;
Edit.BorderStyle := bsSingle;
{$IFDEF COMPILER_6_UP}
Edit.BevelInner := bvNone;
Edit.BevelOuter := bvNone;
Edit.BevelKind := bkNone;
{$ENDIF}
end
end;
function TEasyStringEditor.GetEditorFont: TFont;
begin
Result := (Editor as TEasyEdit).Font
end;
function TEasyStringEditor.GetText: Variant;
begin
Result := (Editor as TEasyEdit).Text
end;
procedure TEasyStringEditor.DoEditKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState; var DoDefault: Boolean);
begin
end;
procedure TEasyStringEditor.OnEditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
//
// Check to see if the user is finished, if not test to see if the edit needs
// to be resized to reflect the new text
//
var
DoDefault: Boolean;
begin
DoDefault := True;
DoEditKeyDown(Sender, Key, Shift, DoDefault);
if DoDefault then
begin
if Key = VK_RETURN then
begin
Key := 0;
AcceptEdit;
end else
if Key = VK_F2 then
begin
SelectAll
end else
PostMessage(Editor.Handle, WM_EDITORRESIZE, 0, 0);
end;
FModified := True;
end;
procedure TEasyStringEditor.SelectAll;
begin
(Editor as TEasyEdit).SelectAll;
end;
procedure TEasyStringEditor.SetEditorFocus;
begin
inherited SetEditorFocus;
SelectAll;
end;
{ TEasyTaskPanelBand }
constructor TEasyTaskPanelBand.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
Groups.FItemClass := TEasyGroupTaskPanel;
end;
function TEasyTaskPanelBand.CreateGroups: TEasyGroups;
begin
Result := TEasyGroupsTaskPanel.Create(Self)
end;
function TEasyTaskPanelBand.GetGroups: TEasyGroupsTaskPanel;
begin
Result := inherited Groups as TEasyGroupsTaskPanel
end;
procedure TEasyTaskPanelBand.CMMouseWheel(var Msg: TCMMouseWheel);
begin
inherited;
PositionPanels
end;
procedure TEasyTaskPanelBand.DoCustomGrid(Group: TEasyGroup; ViewStyle: TEasyListStyle; var Grid: TEasyGridGroupClass);
begin
if Assigned(OnCustomGrid) then
OnCustomGrid(Self, Group, ViewStyle, Grid);
if not Assigned(Grid) then
Grid := TEasyGridGroupTaskPanel
end;
procedure TEasyTaskPanelBand.DoGroupCustomView(Group: TEasyGroup; ViewStyle: TEasyListStyle; var View: TEasyViewGroupClass);
begin
if Assigned(OnGroupCustomView) then
OnGroupCustomView(Self, Group, ViewStyle, View);
if not Assigned(View) then
View := TEasyViewTaskPanelGroup
end;
procedure TEasyTaskPanelBand.DoGetTaskPanel(Sender: TEasyGroupTaskPanel; var TaskPanel: TEasyTaskPanelFormClass);
begin
if Assigned(OnGetTaskPanel) then
OnGetTaskPanel(Self, Sender, TaskPanel)
end;
procedure TEasyTaskPanelBand.DoGroupExpand(Group: TEasyGroup);
begin
inherited DoGroupExpand(Group);
PositionPanels;
end;
procedure TEasyTaskPanelBand.PositionPanels;
var
i: Integer;
DeferHandle: THandle;
TaskPanel: TEasyTaskPanelForm;
MappedR: TRect;
begin
SendMessage(Handle, WM_SETREDRAW, 0, 0);
try
Groups.Rebuild(True);
// MUST MAKE SURE NEVER TO MAKE THE PANELS NOT VISIBLE FOR THIS TO WORK
DeferHandle := BeginDeferWindowPos(Groups.Count);
for i := 0 to Groups.Count - 1 do
begin
if not (Groups[i] as TEasyGroupTaskPanel).TaskWindowCreated then
(Groups[i] as TEasyGroupTaskPanel).CreateTaskWindow;
TaskPanel := (Groups[i] as TEasyGroupTaskPanel).TaskPanel;
MappedR := Scrollbars.MapViewRectToWindowRect(Groups[i].BoundsRectBkGnd, True);
if (DeferHandle <> 0) and Assigned(TaskPanel) and not IsRectEmpty(MappedR) then
begin
if not TaskPanel.Themed then
InflateRect(MappedR, -1, -1); // Make sure the frame shows
TaskPanel.Visible := True;
if (MappedR.Left <> TaskPanel.Left) or (MappedR.Top <> TaskPanel.Top) or
(TaskPanel.Width <> RectWidth(MappedR)) or (TaskPanel.Height <> RectHeight(MappedR)) then
begin
DeferHandle := DeferWindowPos(DeferHandle, TaskPanel.Handle, 0,
MappedR.Left, MappedR.Top,
RectWidth(MappedR), RectHeight(MappedR),
SWP_NOACTIVATE or SWP_NOOWNERZORDER or SWP_NOZORDER);
end
end
end;
if (DeferHandle <> 0) then
EndDeferWindowPos(DeferHandle)
finally
SendMessage(Handle, WM_SETREDRAW, 1, 0);
RedrawWindow(Handle, nil, 0, RDW_ERASE or RDW_INVALIDATE or RDW_ERASENOW or
RDW_UPDATENOW or RDW_ALLCHILDREN or RDW_FRAME);
end
end;
procedure TEasyTaskPanelBand.SetGroups(const Value: TEasyGroupsTaskPanel);
begin
inherited Groups := Value
end;
procedure TEasyTaskPanelBand.WMHScroll(var Msg: TWMHScroll);
begin
inherited;
PositionPanels;
end;
procedure TEasyTaskPanelBand.WMVScroll(var Msg: TWMVScroll);
begin
inherited;
PositionPanels;
end;
procedure TEasyTaskPanelBand.WMWindowPosChanging(var Msg: TWMWindowPosChanging);
begin
inherited;
PositionPanels
end;
{ TEasyGroupsTaskPanel }
constructor TEasyGroupsTaskPanel.Create(AnOwner: TCustomEasyListview);
begin
inherited Create(AnOwner);
end;
function TEasyGroupsTaskPanel.GetGroup(Index: Integer): TEasyGroupTaskPanel;
begin
Result := inherited Groups[Index] as TEasyGroupTaskPanel
end;
procedure TEasyGroupsTaskPanel.SetGroup(Index: Integer; Value: TEasyGroupTaskPanel);
begin
inherited Groups[Index] := Value
end;
{ TEasyGridGroupPanel }
constructor TEasyGridGroupTaskPanel.Create(AnOwner: TCustomEasyListview; AnOwnerGroup: TEasyGroup);
begin
inherited Create(AnOwner, AnOwnerGroup);
FCellSize := TEasyCellSize.Create(AnOwner);
end;
destructor TEasyGridGroupTaskPanel.Destroy;
begin
FreeAndNil(FCellSize);
inherited Destroy;
end;
function TEasyGridGroupTaskPanel.GetCellSize: TEasyCellSize;
begin
Result := FCellSize
end;
function TEasyGridGroupTaskPanel.StaticTopMargin: Integer;
begin
Result := 10;
end;
procedure TEasyGridGroupTaskPanel.Rebuild(PrevGroup: TEasyGroup; var NextVisibleItemIndex: Integer);
var
Top: Integer;
TaskGroup: TEasyGroupTaskPanel;
begin
AutoSizeCells;
if Assigned(PrevGroup) then
Top := PrevGroup.DisplayRect.Bottom
else
Top := StaticTopMargin;
TaskGroup := FOwnerGroup as TEasyGroupTaskPanel;
if FOwnerGroup.Expanded then
TaskGroup.DisplayRect := Rect(0, Top, OwnerListview.ClientWidth, Top + TaskGroup.Height + TaskGroup.MarginBottom.Size + TaskGroup.MarginTop.Size)
else
FOwnerGroup.DisplayRect := Rect(0, Top, OwnerListview.ClientWidth, Top + TaskGroup.MarginTop.Size + TaskGroup.MarginBottom.Size);
end;
procedure TEasyGridGroupTaskPanel.SetCellSize(Value: TEasyCellSize);
begin
CellSize.Width := Value.Width;
CellSize.Height := Value.Height
end;
{ TEasyGroupTaskPanel }
constructor TEasyGroupTaskPanel.Create(ACollection: TEasyCollection);
begin
inherited Create(ACollection);
FHeight := 200;
end;
destructor TEasyGroupTaskPanel.Destroy;
begin
if Assigned(TaskPanel) then
TaskPanel.Free; //Close;
FTaskPanel := nil;
inherited Destroy;
end;
function TEasyGroupTaskPanel.GetTaskWindowCreated: Boolean;
begin
Result := Assigned(FTaskPanel)
end;
procedure TEasyGroupTaskPanel.CreateTaskWindow;
var
TaskPanelClass: TEasyTaskPanelFormClass;
begin
if (not Assigned(TaskPanel)) and not (csDesigning in OwnerListview.ComponentState) then
begin
TaskPanelClass := nil;
TEasyTaskPanelBand(OwnerListview).DoGetTaskPanel(Self, TaskPanelClass);
if Assigned(TaskPanelClass) then
begin
FTaskPanel := TaskPanelClass.Create(nil); // the Group owns the panel
TForm( TaskPanel).AutoScroll := (OwnerListview as TEasyTaskPanelBand).AutoScrollPanels;
TaskPanel.Themed := OwnerListview.Themed;
TaskPanel.Width := RectWidth(BoundsRectBkGnd);
TaskPanel.Height := RectHeight(BoundsRectBkGnd);
TaskPanel.Top := BoundsRectBkGnd.Top;
TaskPanel.Left := BoundsRectBkGnd.Left;
TaskPanel.Visible := False;
TaskPanel.Parent := OwnerListview;
// Make it visible when the grid is rebuilt so it won't flicker
end
end;
end;
procedure TEasyGroupTaskPanel.LoadFromStream(S: TStream; var Version: Integer);
begin
inherited LoadFromStream(S, Version);
S.Read(FHeight, SizeOf(FHeight));
// For new objects test the stream version first
// if Version > X then
// begin
// ReadStream....
// end
end;
procedure TEasyGroupTaskPanel.SaveToStream(S: TStream; Version: Integer = EASYLISTVIEW_STREAM_VERSION);
begin
inherited SaveToStream(S);
S.Write(FHeight, SizeOf(FHeight));
// For new objects test the stream version first
// if Version > X then
// begin
// WriteStream....
// end
end;
procedure TEasyGroupTaskPanel.SetExpanded(Value: Boolean);
begin
inherited SetExpanded(Value);
if Assigned(TaskPanel) then
begin
if Expanded then
TaskPanel.Height := Height
else
TaskPanel.Height := 0
end
end;
procedure TEasyGroupTaskPanel.SetHeight(const Value: Integer);
begin
if FHeight <> Value then
begin
FHeight := Value;
OwnerGroups.Rebuild(True)
end
end;
procedure TEasyGroupTaskPanel.SetInitialized(Value: Boolean);
begin
inherited SetInitialized(Value);
end;
{ TEasyViewTaskPanelGroup }
procedure TEasyViewTaskPanelGroup.PaintBefore(Group: TEasyGroup; ACanvas: TCanvas; MarginEdge: TEasyGroupMarginEdge; ObjRect: TRect; RectArray: TEasyRectArrayObject);
begin
inherited PaintBefore(Group, ACanvas, MarginEdge, ObjRect, RectArray);
end;
{ TEasyTaskBand }
procedure TEasyTaskBand.DoGroupCollapse(Group: TEasyGroup);
begin
// PositionPanels;
inherited DoGroupCollapse(Group);
end;
procedure TEasyTaskBand.DoGroupExpand(Group: TEasyGroup);
begin
// PositionPanels;
inherited DoGroupExpand(Group);
end;
{ TEasyGestureManager }
constructor TEasyGestureManager.Create(AnOwner: TCustomEasyListview);
begin
inherited Create(AnOwner);
FTolerance := 3;
FButton := [cmbRight]
end;
{ TEasyColumnDropDownButton}
constructor TEasyColumnDropDownButton.Create(AnOwner: TEasyColumn);
begin
inherited Create;
FOwner := AnOwner;
FEnabled := True
end;
procedure TEasyColumnDropDownButton.SetAlwaysShow(const Value: Boolean);
begin
if Value <> FAlwaysShow then
begin
FAlwaysShow := Value;
Owner.Invalidate(False)
end;
end;
procedure TEasyColumnDropDownButton.SetEnabled(const Value: Boolean);
begin
if Value <> FEnabled then
begin
FEnabled := Value;
Owner.Invalidate(False)
end;
end;
procedure TEasyColumnDropDownButton.SetVisible(const Value: Boolean);
begin
if Value <> FVisible then
begin
FVisible := Value;
Owner.Invalidate(False)
end;
end;
initialization
OleInitialize(nil);
Screen.Cursors[crVHeaderSplit] := LoadCursor(hInstance, CURSOR_VHEADERSPLIT);
HeaderClipboardFormat := RegisterClipboardFormat(EASYLISTVIEW_HEADER_CLIPFORMAT);
AlphaBlender := TEasyAlphaBlender.Create;
RegisterClass(TEasyGroup);
RegisterClass(TEasyGroupVirtual);
RegisterClass(TEasyGroupInterfaced);
RegisterClass(TEasyGroupStored);
RegisterClass(TEasyGroupTaskPanel);
RegisterClass(TEasyItem);
RegisterClass(TEasyItemVirtual);
RegisterClass(TEasyItemInterfaced);
RegisterClass(TEasyItemStored);
RegisterClass(TEasyColumn);
RegisterClass(TEasyColumnVirtual);
RegisterClass(TEasyColumnInterfaced);
RegisterClass(TEasyColumnStored);
finalization
FreeAndNil(AlphaBlender);
OleUnInitialize();
end.