git-svn-id: https://192.168.0.254/svn/Componentes.Terceros.DevExpressVCL@35 05c56307-c608-d34a-929d-697000501d7a
12453 lines
370 KiB
ObjectPascal
12453 lines
370 KiB
ObjectPascal
{********************************************************************}
|
|
{ }
|
|
{ Developer Express Visual Component Library }
|
|
{ ExpressVerticalGrid }
|
|
{ }
|
|
{ Copyright (c) 1998-2009 Developer Express Inc. }
|
|
{ ALL RIGHTS RESERVED }
|
|
{ }
|
|
{ The entire contents of this file is protected by U.S. and }
|
|
{ International Copyright Laws. Unauthorized reproduction, }
|
|
{ reverse-engineering, and distribution of all or any portion of }
|
|
{ the code contained in this file is strictly prohibited and may }
|
|
{ result in severe civil and criminal penalties and will be }
|
|
{ prosecuted to the maximum extent possible under the law. }
|
|
{ }
|
|
{ RESTRICTIONS }
|
|
{ }
|
|
{ THIS SOURCE CODE AND ALL RESULTING INTERMEDIATE FILES }
|
|
{ (DCU, OBJ, DLL, ETC.) ARE CONFIDENTIAL AND PROPRIETARY TRADE }
|
|
{ SECRETS OF DEVELOPER EXPRESS INC. THE REGISTERED DEVELOPER IS }
|
|
{ LICENSED TO DISTRIBUTE THE EXPRESSVERTICALGRID AND ALL }
|
|
{ ACCOMPANYING VCL CONTROLS AS PART OF AN EXECUTABLE PROGRAM ONLY. }
|
|
{ }
|
|
{ THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED }
|
|
{ FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE }
|
|
{ COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE }
|
|
{ AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT }
|
|
{ AND PERMISSION FROM DEVELOPER EXPRESS INC. }
|
|
{ }
|
|
{ CONSULT THE END USER LICENSE AGREEMENT FOR INFORMATION ON }
|
|
{ ADDITIONAL RESTRICTIONS. }
|
|
{ }
|
|
{********************************************************************}
|
|
unit cxVGrid;
|
|
|
|
{$I cxVer.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
SysUtils, Classes, Windows, Controls, Messages, Forms, StdCtrls, ImgList,
|
|
ExtCtrls, ComCtrls,
|
|
dxCore, cxControls, Graphics, cxGraphics, cxClasses, cxStyles, cxEdit,
|
|
cxLookAndFeelPainters, cxLookAndFeels,
|
|
cxInplaceContainer, cxButtons, cxNavigator, cxFilterControl,
|
|
cxFilter, cxDataStorage, cxCustomData, cxStorage, cxVGridUtils;
|
|
|
|
const
|
|
cxvgMinValueWidth = 20;
|
|
|
|
// verticalgrid styles predefined indexes
|
|
// for row styles
|
|
vgrs_Header = 0;
|
|
vgrs_Content = 1;
|
|
|
|
// for control styles
|
|
vgs_Content = ecs_Content;
|
|
vgs_Category = ecs_EditingStylesMaxIndex + 1;
|
|
vgs_Header = ecs_EditingStylesMaxIndex + 2;
|
|
vgs_IncSearch = ecs_EditingStylesMaxIndex + 3;
|
|
|
|
// base constants for descendants
|
|
cxvgMaxControlStyleIndex = vgs_IncSearch;
|
|
cxvgMaxRowStyleIndex = vgrs_Content;
|
|
|
|
// hit codes
|
|
vghc_Base = 4;
|
|
vghc_HitAtBandSizing = vghc_Base;
|
|
vghc_HitAtButton = vghc_Base + 1;
|
|
vghc_HitAtCaption = vghc_Base + 2;
|
|
vghc_HitAtDivider = vghc_Base + 3;
|
|
vghc_HitAtEmpty = vghc_Base + 4;
|
|
vghc_HitAtImage = vghc_Base + 5;
|
|
vghc_HitAtIndent = vghc_Base + 6;
|
|
vghc_HitAtRowSizing = vghc_Base + 7;
|
|
vghc_HitAtValue = vghc_Base + 8;
|
|
vghc_HitAtCustomize = vghc_Base + 9;
|
|
vghc_HitAtSeparator = vghc_Base + 10;
|
|
|
|
type
|
|
{$IFNDEF DELPHI5}
|
|
TImageIndex = Integer;
|
|
{$ENDIF}
|
|
|
|
EcxVerticalGridError = class(EdxException);
|
|
|
|
TcxCustomRow = class;
|
|
TcxCustomRowHeaderInfo = class;
|
|
TcxCustomRowViewInfo = class;
|
|
TcxCustomVerticalGrid = class;
|
|
TcxVirtualVerticalGrid = class;
|
|
TcxRowCaptionInfo = class;
|
|
TcxRowValueInfo = class;
|
|
TcxRowValueInfoClass = class of TcxRowValueInfo;
|
|
TcxValueInfoList = class;
|
|
TcxCustomEditorRow = class;
|
|
TcxCustomMultiEditorRow = class;
|
|
TcxMultiEditorRow = class;
|
|
TcxVerticalGridCustomizing = class;
|
|
TcxVerticalGridCustomizingClass = class of TcxVerticalGridCustomizing;
|
|
TcxVerticalGridRows = class;
|
|
TcxvgCustomRowStyles = class;
|
|
TcxvgCustomRowStylesClass = class of TcxvgCustomRowStyles;
|
|
TcxCategoryRowStyles = class;
|
|
TcxEditorRowStyles = class;
|
|
TcxvgScroller = class;
|
|
TcxCellEdit = class;
|
|
TcxvgController = class;
|
|
TcxvgCustomPaintStyleCalcHelper = class;
|
|
TcxvgCustomPaintStyleCalcHelperClass = class of TcxvgCustomPaintStyleCalcHelper;
|
|
TcxvgCustomViewInfo = class;
|
|
TcxvgHitTest = class;
|
|
TcxvgPainter = class;
|
|
TcxVerticalGridStyles = class;
|
|
|
|
{ TcxvgOptionsBehavior }
|
|
|
|
TcxvgOptionsBehavior = class(TcxControlOptionsBehavior)
|
|
private
|
|
FAlwaysShowEditorAssigned: Boolean;
|
|
FBandSizing: Boolean;
|
|
FHeaderSizing: Boolean;
|
|
FRowSizing: Boolean;
|
|
FRowTracking: Boolean;
|
|
function GetAlwaysShowEditor: Boolean;
|
|
procedure SetAlwaysShowEditor(Value: Boolean);
|
|
protected
|
|
procedure InternalSetAlwaysShowEditor(Value: Boolean);
|
|
public
|
|
constructor Create(AOwner: TPersistent); override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
procedure RestoreDefaults; virtual;
|
|
published
|
|
property AlwaysShowEditor: Boolean read GetAlwaysShowEditor write SetAlwaysShowEditor stored FAlwaysShowEditorAssigned;
|
|
property BandSizing: Boolean read FBandSizing write FBandSizing default True;
|
|
property CellHints default True;
|
|
property HeaderSizing: Boolean read FHeaderSizing write FHeaderSizing default True;
|
|
property RowSizing: Boolean read FRowSizing write FRowSizing default False;
|
|
property RowTracking: Boolean read FRowTracking write FRowTracking default True;
|
|
end;
|
|
|
|
{ TcxvgMultiRecordsOptionsBehavior }
|
|
|
|
TcxvgMultiRecordsOptionsBehavior = class(TcxvgOptionsBehavior)
|
|
private
|
|
FAllowChangeRecord: Boolean;
|
|
function GetIncSearchItem: TcxCustomEditorRow;
|
|
procedure SetAllowChangeRecord(Value: Boolean);
|
|
procedure SetIncSearchItem(Value: TcxCustomEditorRow);
|
|
public
|
|
constructor Create(AOwner: TPersistent); override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
published
|
|
property AllowChangeRecord: Boolean read FAllowChangeRecord write SetAllowChangeRecord default True;
|
|
property FocusFirstCellOnNewRecord;
|
|
property IncSearch;
|
|
property IncSearchItem: TcxCustomEditorRow read GetIncSearchItem write SetIncSearchItem;
|
|
end;
|
|
|
|
{ TcxvgMultiRecordsOptionsData }
|
|
|
|
TcxvgMultiRecordsOptionsData = class(TcxControlOptionsData)
|
|
private
|
|
FAppending: Boolean;
|
|
FDeleting: Boolean;
|
|
FInserting: Boolean;
|
|
FDeletingConfirmation: Boolean;
|
|
procedure SetAppending(Value: Boolean);
|
|
procedure SetDeleting(Value: Boolean);
|
|
procedure SetInserting(Value: Boolean);
|
|
protected
|
|
procedure Changed; override;
|
|
public
|
|
constructor Create(AOwner: TPersistent); override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
published
|
|
property Appending: Boolean read FAppending write SetAppending default True;
|
|
property Deleting: Boolean read FDeleting write SetDeleting default True;
|
|
property DeletingConfirmation: Boolean read FDeletingConfirmation write FDeletingConfirmation default True;
|
|
property Inserting: Boolean read FInserting write SetInserting default True;
|
|
end;
|
|
|
|
{ TcxvgOptionsView }
|
|
|
|
TcxvgPaintStyle = (psdotNet, psDelphi);
|
|
TcxvgGridLines = (vglNone, vglHorizontal, vglVertical, vglBoth);
|
|
|
|
TcxvgOptionsView = class(TcxControlOptionsView)
|
|
private
|
|
FAutoScaleBands: Boolean;
|
|
FBandsInterval: Integer;
|
|
FCategoryExplorerStyle: Boolean;
|
|
FGridLineColor: TColor;
|
|
FGridLineColorAssigned: Boolean;
|
|
FValueWidth: Integer;
|
|
FPaintStyle: TcxvgPaintStyle;
|
|
FRowHeaderMinWidth: Integer;
|
|
FRowHeaderWidth: Integer;
|
|
FRowHeight: Integer;
|
|
FShowButtons: Boolean;
|
|
FShowHeaders: Boolean;
|
|
FShowEmptyRowImage: Boolean;
|
|
FGridLines: TcxvgGridLines;
|
|
FValueMinWidth: Integer;
|
|
function GetGridLineColor: TColor;
|
|
procedure SetAutoScaleBands(Value: Boolean);
|
|
procedure SetBandsInterval(Value: Integer);
|
|
procedure SetCategoryExplorerStyle(Value: Boolean);
|
|
procedure SetGridLineColor(Value: TColor);
|
|
procedure SetPaintStyle(Value: TcxvgPaintStyle);
|
|
procedure SetRowHeaderMinWidth(Value: Integer);
|
|
procedure SetRowHeaderWidth(Value: Integer);
|
|
procedure SetRowHeight(Value: Integer);
|
|
procedure SetShowButtons(Value: Boolean);
|
|
procedure SetShowEmptyRowImage(Value: Boolean);
|
|
procedure SetShowHeaders(Value: Boolean);
|
|
procedure SetGridLines(Value: TcxvgGridLines);
|
|
procedure SetValueMinWidth(Value: Integer);
|
|
procedure SetValueWidth(Value: Integer);
|
|
protected
|
|
procedure Changed; override;
|
|
procedure CheckRowHeaderWidth;
|
|
public
|
|
constructor Create(AOwner: TPersistent); override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
procedure RestoreDefaults; virtual;
|
|
published
|
|
property AutoScaleBands: Boolean read FAutoScaleBands write SetAutoScaleBands default True;
|
|
property BandsInterval: Integer read FBandsInterval write SetBandsInterval default 2;
|
|
property CategoryExplorerStyle: Boolean read FCategoryExplorerStyle write SetCategoryExplorerStyle default False;
|
|
property PaintStyle: TcxvgPaintStyle read FPaintStyle write SetPaintStyle default psDotNet;
|
|
property GridLineColor: TColor read GetGridLineColor write SetGridLineColor stored FGridLineColorAssigned;
|
|
property RowHeaderMinWidth: Integer read FRowHeaderMinWidth write SetRowHeaderMinWidth default 24;
|
|
property RowHeaderWidth: Integer read FRowHeaderWidth write SetRowHeaderWidth default 100;
|
|
property RowHeight: Integer read FRowHeight write SetRowHeight default -1;
|
|
property ShowButtons: Boolean read FShowButtons write SetShowButtons default True;
|
|
property ShowEditButtons;
|
|
property ShowEmptyRowImage: Boolean read FShowEmptyRowImage write SetShowEmptyRowImage default False;
|
|
property ShowHeaders: Boolean read FShowHeaders write SetShowHeaders default True;
|
|
property GridLines: TcxvgGridLines read FGridLines write SetGridLines default vglBoth;
|
|
property ValueWidth: Integer read FValueWidth write SetValueWidth default 100;
|
|
property ValueMinWidth: Integer read FValueMinWidth write SetValueMinWidth default 40;
|
|
end;
|
|
|
|
{ TcxvgMultiRecordsOptionsView }
|
|
|
|
TcxvgMultiRecordsOptionsView = class(TcxvgOptionsView)
|
|
private
|
|
FRecordsInterval: Integer;
|
|
procedure SetRecordsInterval(Value: Integer);
|
|
public
|
|
procedure Assign(Source: TPersistent); override;
|
|
procedure RestoreDefaults; override;
|
|
published
|
|
property RecordsInterval: Integer read FRecordsInterval write SetRecordsInterval default 0;
|
|
end;
|
|
|
|
{ TcxCustomRowProperties }
|
|
|
|
TcxCustomRowProperties = class(TcxInterfacedCollectionItem)
|
|
private
|
|
FCollection: TCollection;
|
|
FLocked: Boolean;
|
|
FRow: TcxCustomRow;
|
|
protected
|
|
procedure Changed; virtual;
|
|
function GetOwner: TPersistent; override;
|
|
|
|
property Locked: Boolean read FLocked;
|
|
public
|
|
constructor Create(Collection: TCollection); override;
|
|
constructor CreateEx(ARow: TcxCustomRow); virtual;
|
|
property Row: TcxCustomRow read FRow;
|
|
end;
|
|
|
|
TcxRowPropertiesClass = class of TcxCustomRowProperties;
|
|
|
|
{ TcxCaptionRowProperties }
|
|
|
|
TcxCaptionRowProperties = class(TcxCustomRowProperties)
|
|
private
|
|
FHeaderAlignmentHorz: TAlignment;
|
|
FHeaderAlignmentVert: TcxAlignmentVert;
|
|
FIsCaptionAssigned: Boolean;
|
|
FCaption: TCaption;
|
|
FImageIndex: TImageIndex;
|
|
FHint: string;
|
|
function GetCaption: TCaption;
|
|
function IsCaptionStored: Boolean;
|
|
procedure SetCaption(const Value: TCaption);
|
|
procedure SetImageIndex(const Value: TImageIndex);
|
|
procedure SetHeaderAlignmentHorz(const Value: TAlignment);
|
|
procedure SetHeaderAlignmentVert(const Value: TcxAlignmentVert);
|
|
protected
|
|
function DefaultCaption: string; virtual;
|
|
procedure RestoreDefaults; virtual;
|
|
public
|
|
constructor CreateEx(ARow: TcxCustomRow); override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
published
|
|
property Caption: TCaption read GetCaption write SetCaption
|
|
stored IsCaptionStored;
|
|
property HeaderAlignmentHorz: TAlignment read FHeaderAlignmentHorz
|
|
write SetHeaderAlignmentHorz default taLeftJustify;
|
|
property HeaderAlignmentVert: TcxAlignmentVert read FHeaderAlignmentVert
|
|
write SetHeaderAlignmentVert default vaTop;
|
|
property Hint: string read FHint write FHint;
|
|
property ImageIndex: TImageIndex read FImageIndex write SetImageIndex default -1;
|
|
end;
|
|
|
|
{ TcxRowOptions }
|
|
|
|
TcxRowOptions = class(TPersistent)
|
|
private
|
|
FCanAutoHeight: Boolean;
|
|
FCanMovedToCustomizationForm: Boolean;
|
|
FCanResized: Boolean;
|
|
FFocusing: Boolean;
|
|
FMoving: Boolean;
|
|
FRow: TcxCustomRow;
|
|
FShowExpandButton: Boolean;
|
|
FShowInCustomizationForm: Boolean;
|
|
FTabStop: Boolean;
|
|
procedure SetCanAutoHeight(Value: Boolean);
|
|
procedure SetFocusing(Value: Boolean);
|
|
procedure SetShowExpandButton(Value: Boolean);
|
|
procedure SetShowInCustomizationForm(Value: Boolean);
|
|
protected
|
|
procedure Changed; virtual;
|
|
property Row: TcxCustomRow read FRow;
|
|
public
|
|
constructor Create(ARow: TcxCustomRow); virtual;
|
|
procedure Assign(Source: TPersistent); override;
|
|
procedure RestoreDefaults; virtual;
|
|
published
|
|
property CanAutoHeight: Boolean read FCanAutoHeight write SetCanAutoHeight default True;
|
|
property CanMovedToCustomizationForm: Boolean read FCanMovedToCustomizationForm write FCanMovedToCustomizationForm default True;
|
|
property CanResized: Boolean read FCanResized write FCanResized default True;
|
|
property Focusing: Boolean read FFocusing write SetFocusing default True;
|
|
property Moving: Boolean read FMoving write FMoving default True;
|
|
property ShowExpandButton: Boolean read FShowExpandButton write SetShowExpandButton default True;
|
|
property ShowInCustomizationForm: Boolean read FShowInCustomizationForm write SetShowInCustomizationForm default True;
|
|
property TabStop: Boolean read FTabStop write FTabStop default True;
|
|
end;
|
|
|
|
TcxRowOptionsClass = class of TcxRowOptions;
|
|
|
|
{ TcxCustomRow }
|
|
|
|
TcxRowList = class(TList)
|
|
private
|
|
FOwner: TcxCustomRow;
|
|
protected
|
|
procedure Notify(Ptr: Pointer; Action: TListNotification); override;
|
|
procedure UpdateIndexes;
|
|
property Owner: TcxCustomRow read FOwner;
|
|
public
|
|
constructor Create(AOwner: TcxCustomRow);
|
|
end;
|
|
|
|
TcxCustomRow = class(TComponent, IUnknown, IcxStoredObject)
|
|
private
|
|
FExpanded: Boolean;
|
|
FHeight: Integer;
|
|
FID: Integer;
|
|
FIndex: Integer;
|
|
FLoadingIndex: Integer;
|
|
FLoadingParent: string;
|
|
FOptions: TcxRowOptions;
|
|
FParent: TcxCustomRow;
|
|
FRows: TcxRowList;
|
|
FStyles: TcxvgCustomRowStyles;
|
|
FVerticalGrid: TcxCustomVerticalGrid;
|
|
FViewInfo: TcxCustomRowViewInfo;
|
|
FVisible: Boolean;
|
|
FVisibleIndex: Integer;
|
|
function GetAbsoluteIndex: Integer;
|
|
function GetCount: Integer;
|
|
function GetFocused: Boolean;
|
|
function GetLevel: Integer;
|
|
function GetOwnerRows: TcxVerticalGridRows;
|
|
function GetParent: TcxCustomRow;
|
|
function GetRow(Index: Integer): TcxCustomRow;
|
|
function GetViewInfo: TcxCustomRowViewInfo;
|
|
procedure SetExpanded(Value: Boolean);
|
|
procedure SetFocused(Value: Boolean);
|
|
procedure SetHeight(Value: Integer);
|
|
procedure SetIndex(Value: Integer);
|
|
procedure SetOptions(Value: TcxRowOptions);
|
|
procedure SetParent(Value: TcxCustomRow);
|
|
procedure SetVisible(Value: Boolean);
|
|
protected
|
|
FProperties: TcxCustomRowProperties;
|
|
// IcxStoredObject
|
|
function GetObjectName: string; virtual;
|
|
function IcxStoredObject.GetProperties = GetStoredProperties;
|
|
function GetStoredProperties(AProperties: TStrings): Boolean; virtual;
|
|
procedure GetPropertyValue(const AName: string; var AValue: Variant); virtual;
|
|
procedure SetPropertyValue(const AName: string; const AValue: Variant); virtual;
|
|
// override TComponent
|
|
procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override;
|
|
procedure SetName(const NewName: TComponentName); override;
|
|
procedure SetParentComponent(Value: TComponent); override;
|
|
|
|
procedure Add(ARow: TcxCustomRow);
|
|
function CanFocus: Boolean; virtual;
|
|
procedure Changed(ARebuild: Boolean = False); virtual;
|
|
function CreateHeaderInfo: TcxCustomRowHeaderInfo; virtual; abstract;
|
|
function CreateViewInfo: TcxCustomRowViewInfo; virtual; abstract;
|
|
procedure Delete(AIndex: Integer);
|
|
function GetDefaultHeight: Integer; virtual;
|
|
function GetEditContainer(ACellIndex: Integer): TcxCellEdit; virtual;
|
|
function GetEditContainerCount: Integer; virtual;
|
|
function GetPropertiesClass: TcxRowPropertiesClass; virtual;
|
|
function GetRealHeight: Integer; virtual;
|
|
function GetOptionsClass: TcxRowOptionsClass; virtual;
|
|
function GetStylesClass: TcxvgCustomRowStylesClass; virtual;
|
|
procedure Insert(AIndex: Integer; ARow: TcxCustomRow);
|
|
function IsHeightAssigned: Boolean;
|
|
procedure Remove(ARow: TcxCustomRow);
|
|
procedure RemoveAll;
|
|
procedure RemoveChildren;
|
|
procedure ResetOwnerCount;
|
|
procedure SetVerticalGrid(Value: TcxCustomVerticalGrid); virtual;
|
|
property ID: Integer read FID;
|
|
property OwnerRows: TcxVerticalGridRows read GetOwnerRows;
|
|
property Styles: TcxvgCustomRowStyles read FStyles write FStyles;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
// override
|
|
function GetParentComponent: TComponent; override;
|
|
function HasParent: Boolean; override;
|
|
// visualization
|
|
procedure Collapse(ARecurse: Boolean);
|
|
procedure Expand(ARecurse: Boolean);
|
|
function GetFirstVisibleChild: TcxCustomRow;
|
|
function GetLastVisibleChild: TcxCustomRow;
|
|
function HasChildren: Boolean;
|
|
function HasVisibleChildren: Boolean;
|
|
function IndexOf(ARow: TcxCustomRow): Integer;
|
|
function IsChild(ARow: TcxCustomRow): Boolean;
|
|
function IsFirst: Boolean;
|
|
function IsFirstVisible: Boolean;
|
|
function IsLast: Boolean;
|
|
function IsLastVisible: Boolean;
|
|
function IsRootLevel: Boolean;
|
|
function IsParent(ARow: TcxCustomRow): Boolean;
|
|
procedure MakeVisible;
|
|
procedure RestoreDefaults;
|
|
property AbsoluteIndex: Integer read GetAbsoluteIndex;
|
|
property Count: Integer read GetCount;
|
|
property Expanded: Boolean read FExpanded write SetExpanded default True;
|
|
property Focused: Boolean read GetFocused write SetFocused;
|
|
property Height: Integer read FHeight write SetHeight default -1;
|
|
property Index: Integer read FIndex write SetIndex;
|
|
property Level: Integer read GetLevel;
|
|
property Options: TcxRowOptions read FOptions write SetOptions;
|
|
property Parent: TcxCustomRow read GetParent write SetParent;
|
|
property Rows[Index: Integer]: TcxCustomRow read GetRow;
|
|
property VerticalGrid: TcxCustomVerticalGrid read FVerticalGrid write SetVerticalGrid;
|
|
property ViewInfo: TcxCustomRowViewInfo read GetViewInfo;
|
|
property Visible: Boolean read FVisible write SetVisible default True;
|
|
property VisibleIndex: Integer read FVisibleIndex;
|
|
end;
|
|
|
|
TcxCustomRowClass = class of TcxCustomRow;
|
|
|
|
{ TcxCategoryRow }
|
|
|
|
TcxCategoryRow = class(TcxCustomRow)
|
|
private
|
|
function GetProperties: TcxCaptionRowProperties;
|
|
function GetStyles: TcxCategoryRowStyles;
|
|
procedure SetProperties(Value: TcxCaptionRowProperties);
|
|
procedure SetStyles(Value: TcxCategoryRowStyles);
|
|
protected
|
|
function GetStoredProperties(AProperties: TStrings): Boolean; override;
|
|
procedure GetPropertyValue(const AName: string; var AValue: Variant); override;
|
|
procedure SetPropertyValue(const AName: string; const AValue: Variant); override;
|
|
function GetDefaultHeight: Integer; override;
|
|
function GetStylesClass: TcxvgCustomRowStylesClass; override;
|
|
public
|
|
function CreateHeaderInfo: TcxCustomRowHeaderInfo; override;
|
|
function CreateViewInfo: TcxCustomRowViewInfo; override;
|
|
published
|
|
property Expanded;
|
|
property Height;
|
|
property Options;
|
|
property Properties: TcxCaptionRowProperties read GetProperties write SetProperties;
|
|
property Styles: TcxCategoryRowStyles read GetStyles write SetStyles;
|
|
property Visible;
|
|
end;
|
|
|
|
TcxCustomEditorRowProperties = class;
|
|
|
|
{ TcxEditorRowPropertiesOptions }
|
|
|
|
TcxEditorRowPropertiesOptions = class(TcxCustomEditContainerItemOptions)
|
|
published
|
|
property Editing;
|
|
property Filtering;
|
|
property IncSearch;
|
|
property ShowEditButtons;
|
|
end;
|
|
|
|
{ TcxCellEdit }
|
|
|
|
TcxCellEdit = class(TcxCustomInplaceEditContainer)
|
|
private
|
|
FCalculating: Boolean;
|
|
FEditRowProperties: TcxCustomEditorRowProperties;
|
|
FRow: TcxCustomRow;
|
|
function GetViewInfo: TcxCustomRowViewInfo;
|
|
protected
|
|
FCellIndex: Integer;
|
|
procedure Calculate(ACellViewInfo: TcxRowValueInfo);
|
|
function CanEdit: Boolean; override;
|
|
function CanFocus: Boolean; override;
|
|
function CanInitEditing: Boolean; override;
|
|
function CanTabStop: Boolean; override;
|
|
procedure DoGetDisplayText(ARecordIndex: Integer; var AText: string); override;
|
|
function DoGetPropertiesFromEvent(AEvent: TcxGetEditPropertiesEvent; AData: Pointer;
|
|
AProperties: TcxCustomEditProperties): TcxCustomEditProperties; override;
|
|
function GetCurrentValue: Variant; override;
|
|
function GetDataBindingClass: TcxItemDataBindingClass; override;
|
|
function GetDisplayValue(AProperties: TcxCustomEditProperties; ARecordIndex: Integer): Variant; override;
|
|
function GetEditValue: Variant; override;
|
|
function GetOptionsClass: TcxCustomEditContainerItemOptionsClass; override;
|
|
function GetValue(ARecordIndex: Integer): Variant; override;
|
|
function GetValueCount: Integer; override;
|
|
function HasDataTextHandler: Boolean; override;
|
|
procedure PropertiesChanged; override;
|
|
procedure SetCurrentValue(const Value: Variant); override;
|
|
procedure SetValue(ARecordIndex: Integer; const Value: Variant); override;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
property CellIndex: Integer read FCellIndex;
|
|
property EditRowProperties: TcxCustomEditorRowProperties read FEditRowProperties;
|
|
property Options;
|
|
property Row: TcxCustomRow read FRow;
|
|
property ViewInfo: TcxCustomRowViewInfo read GetViewInfo;
|
|
end;
|
|
|
|
TcxCellEditClass = class of TcxCellEdit;
|
|
|
|
{ TcxCustomEditorRowProperties }
|
|
|
|
TcxVerticalGridGetDisplayTextEvent = procedure(Sender: TcxCustomEditorRowProperties;
|
|
ARecord: Integer; var AText: string) of object;
|
|
TcxVerticalGridGetEditPropertiesEvent = procedure(Sender: TcxCustomEditorRowProperties;
|
|
ARecordIndex: Integer; var AProperties: TcxCustomEditProperties) of object;
|
|
|
|
TcxCustomEditorRowProperties = class(TcxCaptionRowProperties,
|
|
IcxEditorPropertiesContainer)
|
|
private
|
|
FEditContainer: TcxCellEdit;
|
|
FOnGetDisplayText: TcxVerticalGridGetDisplayTextEvent;
|
|
function GetDataBinding: TcxItemDataBinding;
|
|
function GetDisplayEditProperty(Index: Integer): TcxCustomEditProperties;
|
|
function GetDisplayText(Index: Integer): string;
|
|
function GetEditViewData: TcxCustomEditViewData;
|
|
function GetEditProperties: TcxCustomEditProperties;
|
|
function GetEditPropertiesClass: TcxCustomEditPropertiesClass;
|
|
function GetEditPropertiesClassName: string;
|
|
function GetIEditorPropertiesContainer: IcxEditorPropertiesContainer;
|
|
function GetItemIndex: Integer;
|
|
function GetItemLink: TObject;
|
|
function GetOptions: TcxEditorRowPropertiesOptions;
|
|
function GetRepositoryItem: TcxEditRepositoryItem;
|
|
function GetValue: Variant;
|
|
function GetValueByIndex(Index: Integer): Variant;
|
|
procedure SetDataBinding(Value: TcxItemDataBinding);
|
|
procedure SetEditProperties(Value: TcxCustomEditProperties);
|
|
procedure SetEditPropertiesClass(Value: TcxCustomEditPropertiesClass);
|
|
procedure SetEditPropertiesClassName(const Value: string);
|
|
procedure SetOptions(Value: TcxEditorRowPropertiesOptions);
|
|
procedure SetRepositoryItem(Value: TcxEditRepositoryItem);
|
|
procedure SetValue(const Value: Variant);
|
|
// events delegation
|
|
function GetOnGetEditingProperties: TcxVerticalGridGetEditPropertiesEvent;
|
|
function GetOnGetEditProperties: TcxVerticalGridGetEditPropertiesEvent;
|
|
procedure SetOnGetEditingProperties(Value: TcxVerticalGridGetEditPropertiesEvent);
|
|
procedure SetOnGetEditProperties(Value: TcxVerticalGridGetEditPropertiesEvent);
|
|
protected
|
|
function GetInplaceEditContainerClass: TcxCellEditClass; virtual;
|
|
procedure DoGetDisplayTextEvent(ARecordIndex: Integer; var Text: string); virtual;
|
|
property EditContainer: TcxCellEdit read FEditContainer;
|
|
property EditViewData: TcxCustomEditViewData read GetEditViewData;
|
|
property IEditorPropertiesContainer: IcxEditorPropertiesContainer
|
|
read GetIEditorPropertiesContainer implements IcxEditorPropertiesContainer;
|
|
property DataBinding: TcxItemDataBinding read GetDataBinding write SetDataBinding;
|
|
property Options: TcxEditorRowPropertiesOptions read GetOptions write SetOptions;
|
|
property Value: Variant read GetValue write SetValue;
|
|
property OnGetDisplayText: TcxVerticalGridGetDisplayTextEvent read FOnGetDisplayText write FOnGetDisplayText;
|
|
property OnGetEditProperties: TcxVerticalGridGetEditPropertiesEvent read GetOnGetEditProperties write SetOnGetEditProperties;
|
|
property OnGetEditingProperties: TcxVerticalGridGetEditPropertiesEvent read GetOnGetEditingProperties write SetOnGetEditingProperties;
|
|
public
|
|
constructor CreateEx(ARow: TcxCustomRow); override;
|
|
destructor Destroy; override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
property DisplayEditProperties[Index: Integer]: TcxCustomEditProperties read GetDisplayEditProperty;
|
|
property DisplayTexts[Index: Integer]: string read GetDisplayText;
|
|
property EditPropertiesClass: TcxCustomEditPropertiesClass read GetEditPropertiesClass write SetEditPropertiesClass;
|
|
property ItemIndex: Integer read GetItemIndex;
|
|
property ItemLink: TObject read GetItemLink;
|
|
property Values[Index: Integer]: Variant read GetValueByIndex;
|
|
published
|
|
property EditPropertiesClassName: string read GetEditPropertiesClassName write SetEditPropertiesClassName;
|
|
property EditProperties: TcxCustomEditProperties read GetEditProperties write SetEditProperties;
|
|
property RepositoryItem: TcxEditRepositoryItem read GetRepositoryItem write SetRepositoryItem;
|
|
end;
|
|
|
|
TcxEditorRowPropertiesClass = class of TcxCustomEditorRowProperties;
|
|
|
|
{ TcxEditorRowProperties }
|
|
|
|
TcxEditorRowProperties = class(TcxCustomEditorRowProperties)
|
|
public
|
|
procedure Assign(Source: TPersistent); override;
|
|
published
|
|
property DataBinding;
|
|
property Options;
|
|
property Value;
|
|
property OnGetDisplayText;
|
|
property OnGetEditProperties;
|
|
property OnGetEditingProperties;
|
|
end;
|
|
|
|
{ TcxCustomEditorRow }
|
|
|
|
TcxCustomEditorRow = class(TcxCustomRow)
|
|
private
|
|
FEditPropertiesEvents: TNotifyEvent;
|
|
FPropertiesEvents: TNotifyEvent;
|
|
function GetProperties: TcxCustomEditorRowProperties;
|
|
function GetStyles: TcxEditorRowStyles;
|
|
procedure SetProperties(Value: TcxCustomEditorRowProperties);
|
|
procedure SetStyles(Value: TcxEditorRowStyles);
|
|
protected
|
|
function CanFocus: Boolean; override;
|
|
function EditContainer: TcxCellEdit;
|
|
function GetDefaultHeight: Integer; override;
|
|
function GetEditContainer(ACellIndex: Integer): TcxCellEdit; override;
|
|
function GetEditContainerCount: Integer; override;
|
|
function GetPropertiesClass: TcxRowPropertiesClass; override;
|
|
function GetStylesClass: TcxvgCustomRowStylesClass; override;
|
|
procedure SetParentComponent(Value: TComponent); override;
|
|
procedure SetVerticalGrid(Value: TcxCustomVerticalGrid); override;
|
|
property Styles: TcxEditorRowStyles read GetStyles write SetStyles;
|
|
property Properties: TcxCustomEditorRowProperties read GetProperties write SetProperties;
|
|
public
|
|
function CreateHeaderInfo: TcxCustomRowHeaderInfo; override;
|
|
function CreateViewInfo: TcxCustomRowViewInfo; override;
|
|
published
|
|
property EditPropertiesEvents: TNotifyEvent read FEditPropertiesEvents write FEditPropertiesEvents;
|
|
property Options;
|
|
property PropertiesEvents: TNotifyEvent read FPropertiesEvents write FPropertiesEvents;
|
|
end;
|
|
|
|
{ TcxEditorRow }
|
|
|
|
TcxEditorRow = class(TcxCustomEditorRow)
|
|
private
|
|
function GetProperties: TcxEditorRowProperties;
|
|
procedure SetProperties(Value: TcxEditorRowProperties);
|
|
protected
|
|
function GetPropertiesClass: TcxRowPropertiesClass; override;
|
|
published
|
|
property Expanded;
|
|
property Height;
|
|
property Options;
|
|
property Properties: TcxEditorRowProperties read GetProperties write SetProperties;
|
|
property Styles;
|
|
property Visible;
|
|
end;
|
|
|
|
{ TcxMultiEditorRow }
|
|
|
|
TSeparatorKind = (skVertLine, skString);
|
|
|
|
{ TSeparatorInfo }
|
|
|
|
TSeparatorInfo = record
|
|
Width: Integer;
|
|
Kind: TSeparatorKind;
|
|
Caption: string;
|
|
TextFlags: Integer;
|
|
ViewParams: TcxViewParams;
|
|
end;
|
|
|
|
{ TcxMultiEditorRowPropertiesOptions }
|
|
|
|
TcxMultiEditorRowPropertiesOptions = class(TcxCustomEditContainerItemOptions)
|
|
published
|
|
property Editing;
|
|
property Filtering;
|
|
property Focusing;
|
|
property IncSearch;
|
|
property ShowEditButtons;
|
|
property TabStop;
|
|
end;
|
|
|
|
{ TcxCollectionItemEditorRowProperties }
|
|
|
|
TcxCollectionItemEditorRowProperties = class(TcxCustomEditorRowProperties)
|
|
private
|
|
FEditPropertiesEvents: TNotifyEvent;
|
|
FWidth: Integer;
|
|
function GetOptions: TcxMultiEditorRowPropertiesOptions;
|
|
procedure SetOptions(Value: TcxMultiEditorRowPropertiesOptions);
|
|
procedure SetWidth(Value: Integer);
|
|
protected
|
|
function GetDisplayName: string; override;
|
|
function GetOwner: TPersistent; override;
|
|
property Options: TcxMultiEditorRowPropertiesOptions read GetOptions write SetOptions;
|
|
public
|
|
constructor CreateEx(ARow: TcxCustomRow); override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
published
|
|
property EditPropertiesEvents: TNotifyEvent read FEditPropertiesEvents write FEditPropertiesEvents;
|
|
property Width: Integer read FWidth write SetWidth default 50;
|
|
end;
|
|
|
|
{ TcxEditorRowItemProperties }
|
|
|
|
TcxEditorRowItemProperties = class(TcxCollectionItemEditorRowProperties)
|
|
public
|
|
procedure Assign(Source: TPersistent); override;
|
|
published
|
|
property DataBinding;
|
|
property Options;
|
|
property Value;
|
|
property OnGetDisplayText;
|
|
property OnGetEditProperties;
|
|
property OnGetEditingProperties;
|
|
end;
|
|
|
|
{ TcxEditorPropertiesCollection }
|
|
|
|
TcxEditorPropertiesCollection = class(TCollection)
|
|
private
|
|
FRow: TcxCustomMultiEditorRow;
|
|
function GetItem(Index: Integer): TcxEditorRowItemProperties;
|
|
protected
|
|
function GetCollectionItemClass: TCollectionItemClass; virtual;
|
|
function GetOwner: TPersistent; override;
|
|
procedure Update(Item: TCollectionItem); override;
|
|
public
|
|
constructor Create(ARow: TcxCustomMultiEditorRow); reintroduce; virtual;
|
|
function Add: TcxEditorRowItemProperties;
|
|
function GetNamePath: string; override;
|
|
property Items[Index: Integer]: TcxEditorRowItemProperties read GetItem; default;
|
|
property Row: TcxCustomMultiEditorRow read FRow;
|
|
end;
|
|
|
|
TcxEditorPropertiesCollectionClass = class of TcxEditorPropertiesCollection;
|
|
|
|
{ TcxMultiEditorRowProperties }
|
|
|
|
TcxMultiEditorRowProperties = class(TcxCustomRowProperties)
|
|
private
|
|
FFixed: Boolean;
|
|
FEditors: TcxEditorPropertiesCollection;
|
|
FSeparatorAlignmentVert: TcxAlignmentVert;
|
|
FSeparatorKind: TSeparatorKind;
|
|
FSeparatorString: string;
|
|
procedure SetFixed(Value: Boolean);
|
|
procedure SetSeparatorAlignmentVert(Value: TcxAlignmentVert);
|
|
procedure SetSeparatorKind(Value: TSeparatorKind);
|
|
procedure SetSeparatorString(const Value: string);
|
|
protected
|
|
function GetCollectionClass: TcxEditorPropertiesCollectionClass; virtual;
|
|
function GetOwner: TPersistent; override;
|
|
public
|
|
constructor CreateEx(ARow: TcxCustomRow); override;
|
|
destructor Destroy; override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
published
|
|
property Editors: TcxEditorPropertiesCollection read FEditors write FEditors;
|
|
property Fixed: Boolean read FFixed write SetFixed default False;
|
|
property SeparatorAlignmentVert: TcxAlignmentVert read FSeparatorAlignmentVert
|
|
write SetSeparatorAlignmentVert default vaTop;
|
|
property SeparatorKind: TSeparatorKind read FSeparatorKind
|
|
write SetSeparatorKind default skVertLine;
|
|
property SeparatorString: string read FSeparatorString write SetSeparatorString;
|
|
end;
|
|
|
|
{ TcxCustomMultiEditorRow }
|
|
|
|
TcxCustomMultiEditorRow = class(TcxCustomRow)
|
|
private
|
|
function GetProperties: TcxMultiEditorRowProperties;
|
|
function GetStyles: TcxEditorRowStyles;
|
|
procedure SetProperties(const Value: TcxMultiEditorRowProperties);
|
|
procedure SetStyles(Value: TcxEditorRowStyles);
|
|
protected
|
|
function CanFocus: Boolean; override;
|
|
function GetDefaultHeight: Integer; override;
|
|
function GetEditContainer(ACellIndex: Integer): TcxCellEdit; override;
|
|
function GetEditContainerCount: Integer; override;
|
|
function GetPropertiesClass: TcxRowPropertiesClass; override;
|
|
function GetStylesClass: TcxvgCustomRowStylesClass; override;
|
|
property Styles: TcxEditorRowStyles read GetStyles write SetStyles;
|
|
property Properties: TcxMultiEditorRowProperties read GetProperties write SetProperties;
|
|
public
|
|
function CreateHeaderInfo: TcxCustomRowHeaderInfo; override;
|
|
function CreateViewInfo: TcxCustomRowViewInfo; override;
|
|
end;
|
|
|
|
{ TcxMultiEditorRow }
|
|
|
|
TcxMultiEditorRow = class(TcxCustomMultiEditorRow)
|
|
published
|
|
property Expanded;
|
|
property Height;
|
|
property Options;
|
|
property Properties;
|
|
property Styles;
|
|
property Visible;
|
|
end;
|
|
|
|
{ TcxVerticalGridRows }
|
|
|
|
TcxVerticalGridRows = class
|
|
private
|
|
FList: TList;
|
|
FLockCount: Integer;
|
|
FNextID: Integer;
|
|
FOwner: TcxCustomVerticalGrid;
|
|
FCount: Integer;
|
|
function GetCount: Integer;
|
|
function GetRoot: TcxCustomRow;
|
|
function GetRow(Index: Integer): TcxCustomRow;
|
|
procedure SetRow(Index: Integer; const Value: TcxCustomRow);
|
|
protected
|
|
procedure Add(ARow: TcxCustomRow);
|
|
procedure AddChild(AParent, ARow: TcxCustomRow);
|
|
procedure BeginUpdate;
|
|
procedure Changed(ARebuild: Boolean = False); virtual;
|
|
procedure CheckList;
|
|
procedure Clear;
|
|
procedure EndUpdate;
|
|
function FindRowByID(AID: Integer): TcxCustomRow;
|
|
function FindRowByStoredName(const AName: string): TcxCustomRow;
|
|
function GetNextID: Integer;
|
|
procedure PrepareList;
|
|
procedure Remove(ARow: TcxCustomRow);
|
|
procedure RestoreDefaults;
|
|
procedure UnprepareList;
|
|
property Root: TcxCustomRow read GetRoot;
|
|
property Owner: TcxCustomVerticalGrid read FOwner;
|
|
public
|
|
constructor Create(AOwner: TcxCustomVerticalGrid);
|
|
destructor Destroy; override;
|
|
procedure AssignRows(Source: TcxVerticalGridRows);
|
|
function IndexOf(ARow: TcxCustomRow): Integer;
|
|
property Count: Integer read GetCount;
|
|
property Items[Index: Integer]: TcxCustomRow read GetRow write SetRow; default;
|
|
end;
|
|
|
|
TcxvgUnboundLayoutStyle = (ulsBandsView, ulsSingleRecordView);
|
|
TcxvgLayoutStyle = (lsBandsView, lsSingleRecordView, lsMultiRecordView);
|
|
|
|
{ TBandInfoList }
|
|
|
|
TBandInfo = record
|
|
BandIndex: Integer;
|
|
RowsCount: Integer;
|
|
BandHeight: Integer;
|
|
FirstRow: TcxCustomRow;
|
|
end;
|
|
|
|
TBandInfoList = class(TcxDataList)
|
|
private
|
|
function GetItem(Index: Integer): TBandInfo;
|
|
public
|
|
constructor Create;
|
|
function Add(ABandIndex, ARowsCount, ABandHeight: Integer;
|
|
AFirstRow: TcxCustomRow): Integer;
|
|
property Items[Index: Integer]: TBandInfo read GetItem; default;
|
|
end;
|
|
|
|
{ TcxvgCustomScrollStrategy }
|
|
|
|
TcxvgCustomScrollStrategy = class
|
|
private
|
|
FBandsInfo: TBandInfoList;
|
|
FCheckingCoordinate: Boolean;
|
|
FLeftVisibleRecord: Integer;
|
|
FTopVisibleRowIndex: Integer;
|
|
FScroller: TcxvgScroller;
|
|
FViewInfo: TcxvgCustomViewInfo;
|
|
function GetController: TcxvgController;
|
|
function GetDataController: TcxCustomDataController;
|
|
function GetScrollBarPos: Integer;
|
|
function GetVerticalGrid: TcxCustomVerticalGrid;
|
|
function GetVisibleRowCount: Integer;
|
|
procedure SetScrollBarPos(Value: Integer);
|
|
procedure SetTopVisibleRowIndex(Value: Integer);
|
|
protected
|
|
function CanContinueForward(Index: Integer): Boolean; virtual;
|
|
function CanContinueBackward(Index: Integer): Boolean; virtual;
|
|
function CanCalcRowsOnTheNextBand(ALeft, ANextBandIndex: Integer): Boolean; virtual;
|
|
procedure CheckLeftVisibleRecord(var AValue: Integer); virtual;
|
|
function GetBandInterval: Integer; virtual; abstract;
|
|
function GetBandWidth: Integer;
|
|
function GetBottomVisibleChild(ARow: TcxCustomRow): TcxCustomRow;
|
|
function GetFullRowHeight(ARow: TcxCustomRow; out ChildCount: Integer): Integer;
|
|
function GetLeftVisibleBand: Integer; virtual; abstract;
|
|
function GetScrollBarOffsetBegin: Integer; virtual;
|
|
function GetScrollBarOffsetEnd: Integer; virtual;
|
|
function GetVisibleBandCount: Integer; virtual; abstract;
|
|
function GetVisibleCount(ABeginIndex, AAreaHeight, AStep: Integer;
|
|
AForward: Boolean): Integer; virtual;
|
|
function GetVisibleValueCount: Integer; virtual; abstract;
|
|
function IsBehindRightClientEdge(X: Integer): Boolean;
|
|
function IsHideHScrollBar: Boolean; virtual;
|
|
function IsHideVScrollBar: Boolean; virtual;
|
|
function IsRecordsScrollMode: Boolean; virtual;
|
|
procedure ScrollH(AScrollCode: TScrollCode; var AScrollPos: Integer); virtual;
|
|
procedure ScrollV(AScrollCode: TScrollCode; var AScrollPos: Integer); virtual;
|
|
procedure SetLeftVisibleBand(Value: Integer); virtual; abstract;
|
|
procedure SetLeftVisibleRecord(Value: Integer); virtual;
|
|
procedure SetTopVisibleRowIndexAndBand(Index: Integer);
|
|
property Scroller: TcxvgScroller read FScroller;
|
|
property ScrollBarPos: Integer read GetScrollBarPos write SetScrollBarPos;
|
|
public
|
|
constructor Create(AScroller: TcxvgScroller); virtual;
|
|
destructor Destroy; override;
|
|
procedure CheckDecreaseLeftIndex; virtual;
|
|
procedure CheckDecreaseTopIndex(AScrollRectHeight: Integer); virtual;
|
|
function CheckTopVisibleIndex(AIndex, AStep: Integer): Integer; virtual;
|
|
function FindNextCustomItem(AFocusedItemIndex, AItemCount: Integer;
|
|
AGoForward: Boolean; var AItemIndex: Integer): Boolean;
|
|
function FindNextRecord(AFocusedRecordIndex: Integer; AGoForward: Boolean): Integer;
|
|
function FocusNextRecord(AFocusedRecordIndex: Integer; AGoForward: Boolean): Boolean;
|
|
function GetBandIndexByRowIndex(ARowIndex: Integer): Integer; virtual; abstract;
|
|
function GetVisibleCountFromBottom(ABottomIndex, AHeight: Integer): Integer;
|
|
function GetVisibleCountFromTop(ATopIndex, AHeight: Integer): Integer;
|
|
function GetFirstRowByBandIndex(ABandIndex: Integer): TcxCustomRow; virtual;
|
|
procedure InitHScrollBarParameters; virtual;
|
|
procedure InitVScrollBarParameters; virtual;
|
|
procedure RecalcBandsInfo; virtual;
|
|
procedure ScrollRecords(AForward: Boolean; ACount: Integer);
|
|
procedure SetRowMaxVisible(ARow: TcxCustomRow); virtual;
|
|
property BandInterval: Integer read GetBandInterval;
|
|
property BandWidth: Integer read GetBandWidth;
|
|
property BandsInfo: TBandInfoList read FBandsInfo;
|
|
property Controller: TcxvgController read GetController;
|
|
property DataController: TcxCustomDataController read GetDataController;
|
|
property LeftVisibleBand: Integer read GetLeftVisibleBand write SetLeftVisibleBand;
|
|
property LeftVisibleRecord: Integer read FLeftVisibleRecord write SetLeftVisibleRecord;
|
|
property ScrollBarOffsetBegin: Integer read GetScrollBarOffsetBegin;
|
|
property ScrollBarOffsetEnd: Integer read GetScrollBarOffsetEnd;
|
|
property TopVisibleRowIndex: Integer read FTopVisibleRowIndex write SetTopVisibleRowIndex;
|
|
property VerticalGrid: TcxCustomVerticalGrid read GetVerticalGrid;
|
|
property ViewInfo: TcxvgCustomViewInfo read FViewInfo;
|
|
property VisibleBandCount: Integer read GetVisibleBandCount;
|
|
property VisibleRowCount: Integer read GetVisibleRowCount;
|
|
property VisibleValueCount: Integer read GetVisibleValueCount;
|
|
end;
|
|
|
|
TcxvgCustomScrollStrategyClass = class of TcxvgCustomScrollStrategy;
|
|
|
|
{ TcxvgSingleRecordScrollStrategy }
|
|
|
|
TcxvgSingleRecordScrollStrategy = class(TcxvgCustomScrollStrategy)
|
|
protected
|
|
function GetBandInterval: Integer; override;
|
|
function GetLeftVisibleBand: Integer; override;
|
|
function GetVisibleBandCount: Integer; override;
|
|
function GetVisibleValueCount: Integer; override;
|
|
procedure SetLeftVisibleBand(Value: Integer); override;
|
|
public
|
|
function GetBandIndexByRowIndex(ARowIndex: Integer): Integer; override;
|
|
end;
|
|
|
|
{ TcxvgMultiRecordsScrollStrategy }
|
|
|
|
TcxvgMultiRecordsScrollStrategy = class(TcxvgCustomScrollStrategy)
|
|
private
|
|
function GetRecordsInterval: Integer;
|
|
protected
|
|
function GetBandInterval: Integer; override;
|
|
function GetLeftVisibleBand: Integer; override;
|
|
function GetVisibleBandCount: Integer; override;
|
|
function GetVisibleValueCount: Integer; override;
|
|
procedure SetLeftVisibleBand(Value: Integer); override;
|
|
procedure SetLeftVisibleRecord(Value: Integer); override;
|
|
property RecordsInterval: Integer read GetRecordsInterval;
|
|
public
|
|
procedure CheckDecreaseLeftIndex; override;
|
|
function GetBandIndexByRowIndex(ARowIndex: Integer): Integer; override;
|
|
end;
|
|
|
|
{ TcxvgBandsScrollStrategy }
|
|
|
|
TcxvgBandsScrollStrategy = class(TcxvgCustomScrollStrategy)
|
|
private
|
|
FLeftVisibleBand: Integer;
|
|
protected
|
|
function CanCalcRowsOnTheNextBand(ALeft, ANextBandIndex: Integer): Boolean; override;
|
|
function GetBandInterval: Integer; override;
|
|
function GetBandViewRowMaxVisibleTopIndex(ARow: TcxCustomRow): Integer;
|
|
function GetLeftVisibleBand: Integer; override;
|
|
function GetVisibleBandCount: Integer; override;
|
|
function GetVisibleValueCount: Integer; override;
|
|
function IsRecordsScrollMode: Boolean; override;
|
|
procedure SetLeftVisibleBand(Value: Integer); override;
|
|
public
|
|
procedure CheckDecreaseTopIndex(AScrollRectHeight: Integer); override;
|
|
function CheckTopVisibleIndex(AIndex, AStep: Integer): Integer; override;
|
|
function GetBandIndexByRowIndex(ARowIndex: Integer): Integer; override;
|
|
procedure InitHScrollBarParameters; override;
|
|
function IsHideVScrollBar: Boolean; override;
|
|
procedure RecalcBandsInfo; override;
|
|
procedure SetRowMaxVisible(ARow: TcxCustomRow); override;
|
|
end;
|
|
|
|
{ TcxvgScroller }
|
|
|
|
TcxvgScroller = class
|
|
private
|
|
FCheckDecreaseLeftIndex: Boolean;
|
|
FCheckDecreaseTopIndex: Boolean;
|
|
FScrollStrategy: TcxvgCustomScrollStrategy;
|
|
FVerticalGrid: TcxCustomVerticalGrid;
|
|
procedure CheckDecreaseLeftIndex;
|
|
procedure CheckDecreaseTopIndex;
|
|
function GetBandsInfo: TBandInfoList;
|
|
function GetCheckDecrease: Boolean;
|
|
function GetFocusedRecordIndex: Integer;
|
|
function GetLeftVisibleBand: Integer;
|
|
function GetLeftVisibleRecord: Integer;
|
|
function GetTopVisibleRowIndex: Integer;
|
|
function GetViewInfo: TcxvgCustomViewInfo;
|
|
function GetVisibleCountFromBottom(ARowIndex: Integer): Integer;
|
|
function GetVisibleRowCount: Integer;
|
|
function GetVisibleValueCount: Integer;
|
|
procedure SetCheckDecrease(Value: Boolean);
|
|
procedure SetLeftVisibleBand(Value: Integer);
|
|
procedure SetLeftVisibleRecord(Value: Integer);
|
|
procedure SetTopVisibleRowIndex(Value: Integer);
|
|
protected
|
|
function CreateScrollStrategy(AScroller: TcxvgScroller): TcxvgCustomScrollStrategy; virtual;
|
|
procedure LayoutStyleChanged;
|
|
// other
|
|
property FocusedRecordIndex: Integer read GetFocusedRecordIndex;
|
|
property ScrollStrategy: TcxvgCustomScrollStrategy read FScrollStrategy;
|
|
property VerticalGrid: TcxCustomVerticalGrid read FVerticalGrid;
|
|
property ViewInfo: TcxvgCustomViewInfo read GetViewInfo;
|
|
public
|
|
constructor Create(AVerticalGrid: TcxCustomVerticalGrid); virtual;
|
|
destructor Destroy; override;
|
|
// navigation
|
|
function GoToFirst: Boolean;
|
|
function GoToLast: Boolean;
|
|
function GoToNext: Boolean;
|
|
function GoToPrev: Boolean;
|
|
|
|
function GetBandIndexByRowIndex(ARowIndex: Integer): Integer;
|
|
procedure InitScrollBarsParameters; virtual;
|
|
procedure RecalcBandsInfo;
|
|
procedure RecreateScrollStrategy;
|
|
procedure Scroll(AScrollBarKind: TScrollBarKind; AScrollCode: TScrollCode; var AScrollPos: Integer);
|
|
function SetRecordVisible(ARecordIndex: Integer): Boolean; virtual;
|
|
procedure SetRowVisible(ARow: TcxCustomRow); virtual;
|
|
procedure SetRowMaxVisible(ARow: TcxCustomRow);
|
|
property BandsInfo: TBandInfoList read GetBandsInfo;
|
|
property CheckDecrease: Boolean read GetCheckDecrease write SetCheckDecrease;
|
|
property LeftVisibleBand: Integer read GetLeftVisibleBand write SetLeftVisibleBand;
|
|
property LeftVisibleRecord: Integer read GetLeftVisibleRecord write SetLeftVisibleRecord;
|
|
property TopVisibleRowIndex: Integer read GetTopVisibleRowIndex write SetTopVisibleRowIndex;
|
|
property VisibleRowCount: Integer read GetVisibleRowCount;
|
|
property VisibleValueCount: Integer read GetVisibleValueCount;
|
|
end;
|
|
|
|
{ TcxvgHitTest }
|
|
|
|
TcxvgHitTest = class(TcxCustomHitTestController)
|
|
private
|
|
FHitInControl: Boolean;
|
|
FHitBandIndex: Integer;
|
|
FHitRow: TcxCustomRow;
|
|
FHitCellIndex: Integer;
|
|
function GetHitAtRowHeader: Boolean;
|
|
function GetVerticalGrid: TcxCustomVerticalGrid;
|
|
protected
|
|
FNewHitTestItem: TObject;
|
|
function AllowDesignMouseEvents(X, Y: Integer; AShift: TShiftState): Boolean; override;
|
|
procedure CalcBandsHitTest(AViewInfo: TcxvgCustomViewInfo); virtual;
|
|
function CalcCustomizingHitTest: Boolean; virtual;
|
|
function CalcRowHeaderHitTest(AHeaderInfo: TcxCustomRowHeaderInfo): Boolean; virtual;
|
|
function CalcRowHitTest(ARowViewInfo: TcxCustomRowViewInfo): Boolean;
|
|
procedure CalcRowValuesHitTest(ARowViewInfo: TcxCustomRowViewInfo); virtual;
|
|
procedure CalcRowsHitTest(AViewInfo: TcxvgCustomViewInfo);
|
|
function CanMoving: Boolean; virtual;
|
|
function CanSizing: Boolean; overload;
|
|
function CanSizing(var ASizeDirection: TcxDragSizingDirection): Boolean; overload; virtual;
|
|
function Check(const ARect: TRect): Boolean;
|
|
procedure DoCalculate; override;
|
|
function GetCurrentCursor: TCursor; override;
|
|
function GetState(Index: Integer): Boolean;
|
|
procedure SetHitState(Index: Integer; Value: Boolean);
|
|
property VerticalGrid: TcxCustomVerticalGrid read GetVerticalGrid;
|
|
public
|
|
property HitAtBandSizing: Boolean index vghc_HitAtBandSizing read GetState;
|
|
property HitAtButton: Boolean index vghc_HitAtButton read GetState;
|
|
property HitAtCaption: Boolean index vghc_HitAtCaption read GetState;
|
|
property HitAtCustomize: Boolean index vghc_HitAtCustomize read GetState;
|
|
property HitAtDivider: Boolean index vghc_HitAtDivider read GetState;
|
|
property HitAtEmpty: Boolean index vghc_HitAtEmpty read GetState;
|
|
property HitAtImage: Boolean index vghc_HitAtImage read GetState;
|
|
property HitAtIndent: Boolean index vghc_HitAtIndent read GetState;
|
|
property HitAtRowHeader: Boolean read GetHitAtRowHeader;
|
|
property HitAtRowSizing: Boolean index vghc_HitAtRowSizing read GetState;
|
|
property HitAtValue: Boolean index vghc_HitAtValue read GetState;
|
|
property HitBandIndex: Integer read FHitBandIndex;
|
|
property HitInControl: Boolean read FHitInControl;
|
|
property HitRow: TcxCustomRow read FHitRow;
|
|
property HitCellIndex: Integer read FHitCellIndex;
|
|
end;
|
|
|
|
{ TcxvgCellNavigator }
|
|
|
|
TcxvgCellNavigator = class(TcxCustomCellNavigator)
|
|
private
|
|
function GetController: TcxvgController;
|
|
function GetRecordCount: Integer;
|
|
function GetRow(Index: Integer): TcxCustomRow;
|
|
function GetValueCount: Integer;
|
|
protected
|
|
procedure CalcNextRow(AForward: Boolean; var ARowIndex, ACellIndex: Integer); override;
|
|
function FindNextRecord(AForward: Boolean): Boolean;
|
|
function GetCellContainer(ARowIndex, ACellIndex: Integer): TcxCustomInplaceEditContainer; override;
|
|
function GetContainerCount(ARowIndex: Integer): Integer;
|
|
function GetCount(ARowIndex: Integer): Integer; override;
|
|
procedure Init(var ARowIndex, ACellIndex, ARowCount: Integer); override;
|
|
function MayFocusedEmptyRow(ARowIndex: Integer): Boolean; override;
|
|
procedure SetFocusCell(ARowIndex, ACellIndex: Integer; AShift: TShiftState = []); override;
|
|
public
|
|
constructor Create(AController: TcxCustomControlController); override;
|
|
procedure FocusNextCell(AForward, ANextRow: Boolean; AShift: TShiftState = []); override;
|
|
property RecordCount: Integer read GetRecordCount;
|
|
property Rows[Index: Integer]: TcxCustomRow read GetRow;
|
|
property Controller: TcxvgController read GetController;
|
|
property ValueCount: Integer read GetValueCount;
|
|
end;
|
|
|
|
{ TcxvgDragImageHelper }
|
|
|
|
TcxvgDragImageHelper = class(TcxDragImageHelper)
|
|
protected
|
|
procedure DragAndDrop(const P: TPoint); override;
|
|
function GetCursor: TCursor; virtual;
|
|
end;
|
|
|
|
{ TcxvgController }
|
|
|
|
TcxvgResizeKind = (rkNone, rkRowSizing, rkDivider, rkBandSizing);
|
|
|
|
TcxvgController = class(TcxCustomControlController, IUnknown, IcxDragSizing)
|
|
private
|
|
FAutoScrollObject: TcxControllerAutoScrollingObject;
|
|
FCellIndex: Integer;
|
|
FDragFromCustomizingForm: Boolean;
|
|
FDragRow: TcxCustomRow;
|
|
FForceShowEditor: Boolean;
|
|
FFocusedRow: TcxCustomRow;
|
|
FLockIncSearch: Boolean;
|
|
FProcessMultiEditorRow: Boolean;
|
|
FResizeKind: TcxvgResizeKind;
|
|
FScrollDown: Boolean;
|
|
FScroller: TcxvgScroller;
|
|
FScrollTimer: TTimer;
|
|
FSizingRow: TcxCustomRow;
|
|
FSizingValue: Integer;
|
|
FTrackingEnabled: Boolean;
|
|
FWasScroll: Boolean;
|
|
procedure CheckMoveToCustomizationForm;
|
|
function GetFirstVisibleRow: TcxCustomRow;
|
|
function GetHitTest: TcxvgHitTest;
|
|
function GetVerticalGrid: TcxCustomVerticalGrid;
|
|
function GetViewInfo: TcxvgCustomViewInfo;
|
|
procedure SetFocusedRow(Value: TcxCustomRow);
|
|
procedure SetResizeKind(Value: TcxvgResizeKind);
|
|
procedure OnScrollTimer(Sender: TObject);
|
|
procedure StartScrollTimer;
|
|
procedure StopScrollTimer;
|
|
protected
|
|
FLockUpdate: Boolean;
|
|
ResizeDirection: TcxDragSizingDirection;
|
|
// IUnknown
|
|
function _AddRef: Integer; stdcall;
|
|
function _Release: Integer; stdcall;
|
|
// IcxDragSizing
|
|
function CanSizing(ADirection: TcxDragSizingDirection): Boolean; virtual;
|
|
function GetSizingBoundsRect(ADirection: TcxDragSizingDirection): TRect; virtual;
|
|
function GetSizingIncrement(ADirection: TcxDragSizingDirection): Integer; virtual;
|
|
function IsDynamicUpdate: Boolean; virtual;
|
|
procedure SetSizeDelta(ADirection: TcxDragSizingDirection; ADelta: Integer); virtual;
|
|
// drag'n'drop
|
|
procedure DragDrop(Source: TObject; X, Y: Integer); override;
|
|
procedure DragOver(Source: TObject; X, Y: Integer; State: TDragState;
|
|
var Accept: Boolean); override;
|
|
procedure EndDrag(Target: TObject; X, Y: Integer); override;
|
|
procedure StartDrag(var DragObject: TDragObject); override;
|
|
|
|
procedure BeforeMouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
|
|
procedure BehaviorChanged; override;
|
|
function CanAppend(ACheckOptions: Boolean): Boolean; virtual;
|
|
function CanChangeRecord: Boolean; virtual;
|
|
function CanDelete(ACheckOptions: Boolean): Boolean; virtual;
|
|
function CanInsert(ACheckOptions: Boolean): Boolean; virtual;
|
|
procedure CheckFocusFirstVisibleRow;
|
|
procedure CheckPostData;
|
|
procedure DoCancelMode; override;
|
|
procedure DoMouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
|
|
procedure DoMouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
|
|
procedure DoNextPage(AForward: Boolean; Shift: TShiftState); override;
|
|
procedure DoUpdateRowAndCell(ANewRow: TcxCustomRow; ANewCellIndex: Integer); virtual;
|
|
procedure FocusedItemChanged(APrevFocusedItem: TcxCustomInplaceEditContainer); override;
|
|
function GetCancelEditingOnExit: Boolean; override;
|
|
function GetDragAndDropObjectClass: TcxDragAndDropObjectClass; override;
|
|
function GetFocusedCellViewInfo(AEditContainer: TcxCustomInplaceEditContainer): TcxEditCellViewInfo; override;
|
|
function GetImmediateEditor: Boolean; override;
|
|
function GetNavigatorClass: TcxCustomCellNavigatorClass; override;
|
|
function GetPostDataOnChangeItem: Boolean; virtual;
|
|
function GetResizeDirection: TcxDragSizingDirection; override;
|
|
procedure InternalSetRowAndCell(ARow: TcxCustomRow; ACellIndex: Integer);
|
|
function IsImmediatePost: Boolean; override;
|
|
function IsInternalDragging: Boolean;
|
|
function IsKeyForController(AKey: Word; AShift: TShiftState): Boolean; override;
|
|
procedure RefreshFocusedRow; virtual;
|
|
procedure SetFocusedCellEdit(ACellEdit: TcxCellEdit);
|
|
procedure SetFocusedRowAndCell(Value: TcxCustomRow; ACellIndex: Integer); virtual;
|
|
procedure UpdatePaintStyle; virtual;
|
|
procedure UpdateRecord(ARecordIndex: Integer); override;
|
|
property DragRow: TcxCustomRow read FDragRow;
|
|
property DragFromCustomizingForm: Boolean read FDragFromCustomizingForm;
|
|
property ForceShowEditor: Boolean read FForceShowEditor;
|
|
property ProcessMultiEditorRow: Boolean read FProcessMultiEditorRow;
|
|
property ResizeKind: TcxvgResizeKind read FResizeKind write SetResizeKind;
|
|
public
|
|
// override
|
|
constructor Create(AOwner: TcxEditingControl); override;
|
|
destructor Destroy; override;
|
|
// IUnknown
|
|
function QueryInterface(const IID: TGUID; out Obj): HResult; virtual; stdcall;
|
|
|
|
procedure Clear; override;
|
|
procedure ControlFocusChanged; override;
|
|
function GetCursor(X, Y: Integer): TCursor; override;
|
|
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
|
|
procedure MakeFocusedItemVisible; override;
|
|
procedure MakeFocusedRecordVisible; override;
|
|
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
|
|
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
|
|
// drag and drop
|
|
function CanDrag(X, Y: Integer): Boolean; override;
|
|
procedure EndDragAndDrop(Accepted: Boolean); override;
|
|
function StartDragAndDrop(const P: TPoint): Boolean; override;
|
|
// scrolling
|
|
procedure InitScrollBarsParameters; override;
|
|
procedure Scroll(AScrollBarKind: TScrollBarKind; AScrollCode: TScrollCode;
|
|
var AScrollPos: Integer); override;
|
|
|
|
procedure AppendRecord; virtual;
|
|
procedure DeleteSelection; virtual;
|
|
procedure InsertRecord; virtual;
|
|
procedure MakeRowVisible(ARow: TcxCustomRow); virtual;
|
|
function MakeRecordVisible(AIndex: Integer): Boolean; virtual;
|
|
property CellIndex: Integer read FCellIndex;
|
|
property FocusedRow: TcxCustomRow read FFocusedRow write SetFocusedRow;
|
|
property HitTest: TcxvgHitTest read GetHitTest;
|
|
property Scroller: TcxvgScroller read FScroller;
|
|
property VerticalGrid: TcxCustomVerticalGrid read GetVerticalGrid;
|
|
property ViewInfo: TcxvgCustomViewInfo read GetViewInfo;
|
|
end;
|
|
|
|
{ TcxvgMultiRecordsController }
|
|
|
|
TcxvgMultiRecordsController = class(TcxvgController)
|
|
private
|
|
function GetOptionsBehavior: TcxvgMultiRecordsOptionsBehavior;
|
|
function GetOptionsData: TcxvgMultiRecordsOptionsData;
|
|
function GetVerticalGrid: TcxVirtualVerticalGrid;
|
|
protected
|
|
function CanAppend(ACheckOptions: Boolean): Boolean; override;
|
|
function CanChangeRecord: Boolean; override;
|
|
function CanDelete(ACheckOptions: Boolean): Boolean; override;
|
|
function CanInsert(ACheckOptions: Boolean): Boolean; override;
|
|
procedure FocusedRecordChanged(APrevFocusedRowIndex, AFocusedRowIndex: Integer); override;
|
|
function GetCancelEditingOnExit: Boolean; override;
|
|
function GetFocusedRecordIndex: Integer; override;
|
|
function GetPostDataOnChangeItem: Boolean; override;
|
|
function IncSearchKeyDown(AKey: Word; AShift: TShiftState): Word; override;
|
|
function IsImmediatePost: Boolean; override;
|
|
procedure RefreshIncSearchItem; virtual;
|
|
procedure SetFocusedRecordIndex(Value: Integer); override;
|
|
property OptionsBehavior: TcxvgMultiRecordsOptionsBehavior read GetOptionsBehavior;
|
|
property OptionsData: TcxvgMultiRecordsOptionsData read GetOptionsData;
|
|
property VerticalGrid: TcxVirtualVerticalGrid read GetVerticalGrid;
|
|
public
|
|
procedure DeleteSelection; override;
|
|
end;
|
|
|
|
{ TcxCustomVerticalGrid }
|
|
|
|
TcxVerticalGridDrawHeaderEvent = procedure(Sender: TObject;
|
|
ACanvas: TcxCanvas; APainter: TcxvgPainter;
|
|
AHeaderViewInfo: TcxCustomRowHeaderInfo;
|
|
var Done: Boolean) of object;
|
|
|
|
TcxVerticalGridDrawValueEvent = procedure(Sender: TObject;
|
|
ACanvas: TcxCanvas; APainter: TcxvgPainter;
|
|
AValueInfo: TcxRowValueInfo;
|
|
var Done: Boolean) of object;
|
|
|
|
TcxVerticalGridDrawBackgroundEvent = procedure(Sender: TObject;
|
|
ACanvas: TcxCanvas; const R: TRect; const AViewParams: TcxViewParams;
|
|
var Done: Boolean) of object;
|
|
|
|
TcxVerticalGridEditingEvent = procedure(Sender: TObject;
|
|
ARowProperties: TcxCustomEditorRowProperties; var Allow: Boolean) of object;
|
|
|
|
TcxVerticalGridChangedEvent = procedure(Sender: TObject;
|
|
ARowProperties: TcxCustomEditorRowProperties) of object;
|
|
|
|
TcxVerticalGridItemChangedEvent = procedure(Sender: TObject;
|
|
AOldRow: TcxCustomRow; AOldCellIndex: Integer) of object;
|
|
|
|
TcxCustomVerticalGrid = class(TcxExtEditingControl, IcxStoredObject,
|
|
IcxStoredParent, IdxSkinSupport)
|
|
private
|
|
FCategoryFont: TFont;
|
|
FClearingRows: Boolean;
|
|
FCustomizing: TcxVerticalGridCustomizing;
|
|
FImageChangeLink: TChangeLink;
|
|
FImages: TCustomImageList;
|
|
FNewLoadMode: Boolean;
|
|
FRootRow: TcxCustomRow;
|
|
FRows: TcxVerticalGridRows;
|
|
FSaveDragCursor: TCursor;
|
|
FStoringName: string;
|
|
FStylesEvents: TNotifyEvent;
|
|
FOnCustomizationVisibleChanged: TNotifyEvent;
|
|
FOnDrawBackground: TcxVerticalGridDrawBackgroundEvent;
|
|
FOnDrawRowHeader: TcxVerticalGridDrawHeaderEvent;
|
|
FOnDrawValue: TcxVerticalGridDrawValueEvent;
|
|
FOnEdited: TcxVerticalGridChangedEvent;
|
|
FOnEditing: TcxVerticalGridEditingEvent;
|
|
FOnEditValueChanged: TcxVerticalGridChangedEvent;
|
|
FOnItemChanged: TcxVerticalGridItemChangedEvent;
|
|
FOnLayoutChanged: TNotifyEvent;
|
|
FOnLeftVisibleBandIndexChanged: TNotifyEvent;
|
|
FOnLeftVisibleRecordIndexChanged: TNotifyEvent;
|
|
FOnTopRowIndexChanged: TNotifyEvent;
|
|
procedure CategoryFontChanged(Sender: TObject);
|
|
function GetController: TcxvgController;
|
|
function GetDragHeaderInfo: TcxCustomRowHeaderInfo;
|
|
function GetFocusedRow: TcxCustomRow;
|
|
function GetHitTest: TcxvgHitTest;
|
|
function GetInplaceEditor: TcxCustomEdit;
|
|
function GetIsEditing: Boolean;
|
|
function GetLeftVisibleBand: Integer;
|
|
function GetLeftVisibleRecord: Integer;
|
|
function GetOptionsBehavior: TcxvgOptionsBehavior;
|
|
function GetOptionsView: TcxvgOptionsView;
|
|
function GetPainter: TcxvgPainter;
|
|
function GetRecordCount: Integer;
|
|
function GetStyles: TcxVerticalGridStyles;
|
|
function GetTopVisibleRowIndex: Integer;
|
|
function GetViewInfo: TcxvgCustomViewInfo;
|
|
procedure ImageListChange(Sender: TObject);
|
|
procedure SetFocusedRow(Value: TcxCustomRow);
|
|
procedure SetImages(Value: TCustomImageList);
|
|
procedure SetLeftVisibleBand(Value: Integer);
|
|
procedure SetLeftVisibleRecord(Value: Integer);
|
|
procedure SetOptionsBehavior(Value: TcxvgOptionsBehavior);
|
|
procedure SetOptionsView(Value: TcxvgOptionsView);
|
|
procedure SetStyles(Value: TcxVerticalGridStyles);
|
|
procedure SetTopVisibleRowIndex(Value: Integer);
|
|
procedure CMDrag(var Message: TCMDrag); message CM_DRAG;
|
|
protected
|
|
// IcxStoredObject
|
|
function GetObjectName: string; virtual;
|
|
function GetProperties(AProperties: TStrings): Boolean; virtual;
|
|
procedure GetPropertyValue(const AName: string; var AValue: Variant); virtual;
|
|
procedure SetPropertyValue(const AName: string; const AValue: Variant); virtual;
|
|
// IcxStoredParent
|
|
function CreateChild(const AObjectName, AClassName: string): TObject; virtual;
|
|
procedure DeleteChild(const AObjectName: string; AObject: TObject); virtual;
|
|
procedure IcxStoredParent.GetChildren = GetStoredChildren;
|
|
procedure GetStoredChildren(AChildren: TStringList); virtual;
|
|
// vcl methods
|
|
procedure DoEndDrag(Target: TObject; X, Y: Integer); override;
|
|
{$IFNDEF DELPHI12}
|
|
procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override;
|
|
{$ENDIF}
|
|
procedure Loaded; override;
|
|
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
|
|
procedure SetName(const Value: TComponentName); override;
|
|
// cxControls
|
|
procedure BoundsChanged; override;
|
|
procedure FontChanged; override;
|
|
procedure InitControl; override;
|
|
procedure LookAndFeelChanged(Sender: TcxLookAndFeel;
|
|
AChangedValues: TcxLookAndFeelValues); override;
|
|
// cxControls - drag'n'drop
|
|
function GetDragObjectClass: TDragControlObjectClass; override;
|
|
// cxExtEditingControl
|
|
procedure CreateSubClasses; override;
|
|
procedure DataChanged; override;
|
|
procedure DestroySubClasses; override;
|
|
procedure DoEdited(AItem: TcxCustomInplaceEditContainer); override;
|
|
function DoEditing(AItem: TcxCustomInplaceEditContainer): Boolean; override;
|
|
procedure DoEditValueChanged(AItem: TcxCustomInplaceEditContainer); override;
|
|
procedure DoInplaceEditContainerItemRemoved(AItem: TcxCustomInplaceEditContainer); override;
|
|
procedure DoLayoutChanged; override;
|
|
function DragDropImageDisplayRect: TRect; override;
|
|
procedure DrawDragDropImage(ADragBitmap: TBitmap; ACanvas: TcxCanvas); override;
|
|
function GetControllerClass: TcxCustomControlControllerClass; override;
|
|
function GetControlStylesClass: TcxCustomControlStylesClass; override;
|
|
function GetDragImageHelperClass: TcxDragImageHelperClass; override;
|
|
function GetEditCellDataBindingClass: TcxItemDataBindingClass; virtual;
|
|
function GetHitTestControllerClass: TcxHitTestControllerClass; override;
|
|
function GetOptionsBehaviorClass: TcxControlOptionsBehaviorClass; override;
|
|
function GetOptionsViewClass: TcxControlOptionsViewClass; override;
|
|
function GetPainterClass: TcxCustomControlPainterClass; override;
|
|
function HasDragDropImages: Boolean; override;
|
|
procedure RecreateViewInfo; override;
|
|
// virtuals
|
|
procedure AfterLoadedRows;
|
|
procedure BeforeLoadedRows;
|
|
function CanBandSizing: Boolean; virtual;
|
|
procedure CheckRowClass(ARowClass: TcxCustomRowClass); virtual;
|
|
procedure CheckGridModeBufferCount;
|
|
procedure DoCustomizationVisibleChanged; virtual;
|
|
function DoDrawBackgroundPart(const R: TRect; const AViewParams: TcxViewParams): Boolean; virtual;
|
|
function DoDrawRowHeader(AHeaderViewInfo: TcxCustomRowHeaderInfo): Boolean; virtual;
|
|
function DoDrawValue(AValueInfo: TcxRowValueInfo): Boolean; virtual;
|
|
procedure DoItemChanged(AOldRow: TcxCustomRow; AOldCellIndex: Integer); virtual;
|
|
procedure DoLeftVisibleBandIndexChanged; virtual;
|
|
procedure DoLeftVisibleRecordIndexChanged; virtual;
|
|
procedure DoTopRowIndexChanged; virtual;
|
|
function GetCalcHelperClass: TcxvgCustomPaintStyleCalcHelperClass; virtual;
|
|
function GetCellAutoHeight: Boolean; virtual;
|
|
function GetCustomizingClass: TcxVerticalGridCustomizingClass; virtual;
|
|
procedure GetDefaultViewParams(Index: Integer; AData: TObject; out AParams: TcxViewParams); virtual;
|
|
function GetEditorRowClass: TcxCustomRowClass; virtual;
|
|
function GetMultiEditorRowClass: TcxCustomRowClass; virtual;
|
|
function GetScrollStrategyClass: TcxvgCustomScrollStrategyClass; virtual; abstract;
|
|
procedure InitDataController; virtual;
|
|
procedure RemoveRowFromVerticalGrid(ARow: TcxCustomRow);
|
|
procedure RowsChanged; virtual;
|
|
procedure UpdateDesignEditor; virtual;
|
|
property CategoryFont: TFont read FCategoryFont;
|
|
property Controller: TcxvgController read GetController;
|
|
property Customizing: TcxVerticalGridCustomizing read FCustomizing write FCustomizing;
|
|
property DragHeaderInfo: TcxCustomRowHeaderInfo read GetDragHeaderInfo;
|
|
property LeftVisibleRecord: Integer read GetLeftVisibleRecord write SetLeftVisibleRecord;
|
|
property Painter: TcxvgPainter read GetPainter;
|
|
property RecordCount: Integer read GetRecordCount;
|
|
property RootRow: TcxCustomRow read FRootRow;
|
|
property OnCustomizationFormVisibleChanged: TNotifyEvent read FOnCustomizationVisibleChanged write FOnCustomizationVisibleChanged;
|
|
property OnDrawBackground: TcxVerticalGridDrawBackgroundEvent read FOnDrawBackground write FOnDrawBackground;
|
|
property OnDrawRowHeader: TcxVerticalGridDrawHeaderEvent read FOnDrawRowHeader write FOnDrawRowHeader;
|
|
property OnDrawValue: TcxVerticalGridDrawValueEvent read FOnDrawValue write FOnDrawValue;
|
|
property OnEdited: TcxVerticalGridChangedEvent read FOnEdited write FOnEdited;
|
|
property OnEditing: TcxVerticalGridEditingEvent read FOnEditing write FOnEditing;
|
|
property OnEditValueChanged: TcxVerticalGridChangedEvent read FOnEditValueChanged write FOnEditValueChanged;
|
|
property OnItemChanged: TcxVerticalGridItemChangedEvent read FOnItemChanged write FOnItemChanged;
|
|
property OnLayoutChanged: TNotifyEvent read FOnLayoutChanged write FOnLayoutChanged;
|
|
property OnLeftVisibleBandIndexChanged: TNotifyEvent read FOnLeftVisibleBandIndexChanged write FOnLeftVisibleBandIndexChanged;
|
|
property OnLeftVisibleRecordIndexChanged: TNotifyEvent read FOnLeftVisibleRecordIndexChanged write FOnLeftVisibleRecordIndexChanged;
|
|
property OnTopRowIndexChanged: TNotifyEvent read FOnTopRowIndexChanged write FOnTopRowIndexChanged;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
// work with rows
|
|
function Add(ARowClass: TcxCustomRowClass): TcxCustomRow;
|
|
function AddChild(AParent: TcxCustomRow; ARowClass: TcxCustomRowClass): TcxCustomRow;
|
|
procedure AssignRows(Source: TcxCustomVerticalGrid); virtual;
|
|
procedure ClearRows;
|
|
function FirstRow: TcxCustomRow;
|
|
function FirstVisibleRow: TcxCustomRow;
|
|
procedure FocusRow(ARow: TcxCustomRow; ACellIndex: Integer = 0);
|
|
procedure FullCollapse;
|
|
procedure FullExpand;
|
|
{$IFDEF DELPHI12}
|
|
procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override;
|
|
{$ENDIF}
|
|
function HasRows: Boolean;
|
|
function HasVisibleRows: Boolean;
|
|
function IsInternalDragging: Boolean;
|
|
function IsRowVisible(ARow: TcxCustomRow): Boolean;
|
|
function LastRow: TcxCustomRow;
|
|
function LastVisibleRow: TcxCustomRow;
|
|
function NextRow(ARow: TcxCustomRow): TcxCustomRow;
|
|
function NextVisibleRow(ARow: TcxCustomRow): TcxCustomRow;
|
|
function PrevRow(ARow: TcxCustomRow): TcxCustomRow;
|
|
function PrevVisibleRow(ARow: TcxCustomRow): TcxCustomRow;
|
|
procedure Remove(ARow: TcxCustomRow);
|
|
function RowByCaption(const ACaption: string): TcxCustomRow;
|
|
function RowByName(const AName: string): TcxCustomRow;
|
|
// store/load
|
|
procedure RestoreFromIniFile(const AStorageName: string);
|
|
procedure RestoreFromRegistry(const AStorageName: string);
|
|
procedure RestoreFromStream(AStream: TStream);
|
|
procedure StoreToIniFile(const AStorageName: string; AReCreate: Boolean = True);
|
|
procedure StoreToRegistry(const AStorageName: string; AReCreate: Boolean = True);
|
|
procedure StoreToStream(AStream: TStream);
|
|
// edit control
|
|
procedure CancelEdit;
|
|
procedure HideEdit;
|
|
procedure ShowEdit;
|
|
procedure ShowEditByKey(AKey: Char);
|
|
procedure ShowEditByMouse(X, Y: Integer; AShift: TShiftState);
|
|
|
|
procedure RestoreDefaults; virtual;
|
|
// properties
|
|
property FocusedRow: TcxCustomRow read GetFocusedRow write SetFocusedRow;
|
|
property HitTest: TcxvgHitTest read GetHitTest;
|
|
property Images: TCustomImageList read FImages write SetImages;
|
|
property InplaceEditor: TcxCustomEdit read GetInplaceEditor;
|
|
property IsEditing: Boolean read GetIsEditing;
|
|
property LeftVisibleBand: Integer read GetLeftVisibleBand write SetLeftVisibleBand;
|
|
property LookAndFeel;
|
|
property OptionsBehavior: TcxvgOptionsBehavior read GetOptionsBehavior write SetOptionsBehavior;
|
|
property OptionsData;
|
|
property OptionsView: TcxvgOptionsView read GetOptionsView write SetOptionsView;
|
|
property Rows: TcxVerticalGridRows read FRows write FRows;
|
|
property StoringName: string read FStoringName write FStoringName;
|
|
property Styles: TcxVerticalGridStyles read GetStyles write SetStyles;
|
|
property TopVisibleRowIndex: Integer read GetTopVisibleRowIndex write SetTopVisibleRowIndex;
|
|
property ViewInfo: TcxvgCustomViewInfo read GetViewInfo;
|
|
published
|
|
property StylesEvents: TNotifyEvent read FStylesEvents write FStylesEvents;
|
|
end;
|
|
|
|
{ TcxUnboundVerticalGrid }
|
|
|
|
TcxUnboundVerticalGrid = class(TcxCustomVerticalGrid)
|
|
private
|
|
FLayoutStyle: TcxvgUnboundLayoutStyle;
|
|
procedure SetLayoutStyle(Value: TcxvgUnboundLayoutStyle);
|
|
protected
|
|
function CanBandSizing: Boolean; override;
|
|
function GetScrollStrategyClass: TcxvgCustomScrollStrategyClass; override;
|
|
function GetViewInfoClass: TcxCustomControlViewInfoClass; override;
|
|
property LayoutStyle: TcxvgUnboundLayoutStyle read FLayoutStyle write SetLayoutStyle default ulsSingleRecordView;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
end;
|
|
|
|
IcxVGridDesignerRows = interface
|
|
['{D77CC392-984F-4C1E-A41C-A341FEAC93EB}']
|
|
function GetEditorRowClass: TcxCustomRowClass;
|
|
function GetMultiEditorRowClass: TcxCustomRowClass;
|
|
end;
|
|
|
|
{ TcxVerticalGrid }
|
|
|
|
TcxVerticalGrid = class(TcxUnboundVerticalGrid, IcxVGridDesignerRows)
|
|
public
|
|
property Customizing;
|
|
published
|
|
property Align;
|
|
property Anchors;
|
|
property Constraints;
|
|
property DragCursor;
|
|
property DragKind;
|
|
property DragMode;
|
|
property Enabled;
|
|
property Font;
|
|
property Images;
|
|
property LayoutStyle;
|
|
property LookAndFeel;
|
|
property OptionsView; //before OptionsBehavior
|
|
property OptionsBehavior;
|
|
property OptionsData;
|
|
property ParentFont;
|
|
property PopupMenu;
|
|
property Styles;
|
|
property TabOrder;
|
|
property TabStop;
|
|
property Visible;
|
|
|
|
property OnClick;
|
|
{$IFDEF DELPHI5}
|
|
property OnContextPopup;
|
|
{$ENDIF}
|
|
property OnCustomizationFormVisibleChanged;
|
|
property OnDblClick;
|
|
property OnDragDrop;
|
|
property OnDragOver;
|
|
property OnDrawBackground;
|
|
property OnDrawRowHeader;
|
|
property OnDrawValue;
|
|
property OnEdited;
|
|
property OnEditing;
|
|
property OnEditValueChanged;
|
|
property OnEndDock;
|
|
property OnEndDrag;
|
|
property OnEnter;
|
|
property OnExit;
|
|
property OnInitEdit;
|
|
property OnItemChanged;
|
|
property OnKeyDown;
|
|
property OnKeyPress;
|
|
property OnKeyUp;
|
|
property OnLayoutChanged;
|
|
property OnLeftVisibleBandIndexChanged;
|
|
property OnMouseDown;
|
|
property OnMouseEnter;
|
|
property OnMouseLeave;
|
|
property OnMouseMove;
|
|
property OnMouseUp;
|
|
property OnMouseWheel;
|
|
property OnMouseWheelDown;
|
|
property OnMouseWheelUp;
|
|
property OnResize;
|
|
property OnStartDock;
|
|
property OnStartDrag;
|
|
property OnTopRowIndexChanged;
|
|
end;
|
|
|
|
{ TcxVirtualVerticalGrid }
|
|
|
|
TcxVerticalGridFocusedRecordChangedEvent = procedure(Sender: TcxVirtualVerticalGrid;
|
|
APrevFocusedRecord, AFocusedRecord: Integer) of object;
|
|
|
|
IcxVerticalGridDBDataContoller = interface
|
|
['{947072DE-3531-4010-8C44-D243FD289FDF}']
|
|
procedure CheckGridModeBufferCount;
|
|
function DoScroll(AForward: Boolean): Boolean;
|
|
function GetDataSetRecordCount: Integer;
|
|
function GetScrollBarPos: Integer;
|
|
function GetScrollBarRecordCount: Integer;
|
|
function SetScrollBarPos(APos: Integer): Boolean;
|
|
end;
|
|
|
|
TcxVirtualVerticalGrid = class(TcxCustomVerticalGrid, IcxVGridDesignerRows,
|
|
IcxNavigator, IcxFilterControl)
|
|
private
|
|
FNavigatorNotifier: TcxNavigatorControlNotifier;
|
|
FLayoutStyle: TcxvgLayoutStyle;
|
|
FOnFilterControlDialogShow: TNotifyEvent;
|
|
FOnFocusedRecordChanged: TcxVerticalGridFocusedRecordChangedEvent;
|
|
procedure ApplyFilter(Sender: TObject);
|
|
function GetFilterElementProperties(AIndex: Integer): TcxCustomEditorRowProperties;
|
|
function GetFilterRecordEvent: TcxDataFilterRecordEvent;
|
|
function GetFocusedRecordIndex: Integer;
|
|
function GetController: TcxvgMultiRecordsController;
|
|
function GetOptionsBehavior: TcxvgMultiRecordsOptionsBehavior;
|
|
function GetOptionsData: TcxvgMultiRecordsOptionsData;
|
|
function GetOptionsView: TcxvgMultiRecordsOptionsView;
|
|
procedure SetFilterRecordEvent(Value: TcxDataFilterRecordEvent);
|
|
procedure SetFocusedRecordIndex(Value: Integer);
|
|
procedure SetLayoutStyle(Value: TcxvgLayoutStyle);
|
|
procedure SetOptionsBehavior(Value: TcxvgMultiRecordsOptionsBehavior);
|
|
procedure SetOptionsData(Value: TcxvgMultiRecordsOptionsData);
|
|
procedure SetOptionsView(Value: TcxvgMultiRecordsOptionsView);
|
|
protected
|
|
// IcxFilterControl
|
|
function IcxFilterControl.GetCaption = GetFilterCaption;
|
|
function IcxFilterControl.GetCount = GetFilterCount;
|
|
function IcxFilterControl.GetCriteria = GetFilterCriteria;
|
|
function IcxFilterControl.GetFieldName = GetFilterFieldName;
|
|
function IcxFilterControl.GetItemLink = GetFilterItemLink;
|
|
function IcxFilterControl.GetItemLinkID = GetFilterItemLinkID;
|
|
function IcxFilterControl.GetProperties = GetFilterProperties;
|
|
function IcxFilterControl.GetValueType = GetFilterValueType;
|
|
function GetFilterCaption(Index: Integer): string;
|
|
function GetFilterCount: Integer;
|
|
function GetFilterCriteria: TcxFilterCriteria;
|
|
function GetFilterFieldName(Index: Integer): string;
|
|
function GetFilterItemLink(Index: Integer): TObject;
|
|
function GetFilterItemLinkID(Index: Integer): Integer;
|
|
function GetItemLinkName(Index: Integer): string;
|
|
function GetFilterProperties(Index: Integer): TcxCustomEditProperties;
|
|
function GetFilterValueType(Index: Integer): TcxValueTypeClass;
|
|
// IcxNavigator
|
|
function IcxNavigator.CanAppend = NavigatorCanAppend;
|
|
function IcxNavigator.CanDelete = NavigatorCanDelete;
|
|
function IcxNavigator.CanEdit = NavigatorCanEdit;
|
|
function IcxNavigator.CanInsert = NavigatorCanInsert;
|
|
function IcxNavigator.IsActive = NavigatorIsActive;
|
|
function IcxNavigator.IsBof = NavigatorIsBof;
|
|
function IcxNavigator.IsBookmarkAvailable = NavigatorIsBookmarkAvailable;
|
|
function IcxNavigator.IsEditing = NavigatorIsEditing;
|
|
function IcxNavigator.IsEof = NavigatorIsEof;
|
|
procedure IcxNavigator.ClearBookmark = NavigatorClearBookmark;
|
|
procedure IcxNavigator.DoAction = NavigatorDoAction;
|
|
function IcxNavigator.GetNotifier = NavigatorGetNotifier;
|
|
function IcxNavigator.IsActionSupported = NavigatorIsActionSupported;
|
|
function NavigatorCanAppend: Boolean;
|
|
function NavigatorCanDelete: Boolean;
|
|
function NavigatorCanEdit: Boolean;
|
|
function NavigatorCanInsert: Boolean;
|
|
function NavigatorIsActive: Boolean;
|
|
function NavigatorIsBof: Boolean;
|
|
function NavigatorIsBookmarkAvailable: Boolean;
|
|
function NavigatorIsEditing: Boolean;
|
|
function NavigatorIsEof: Boolean;
|
|
procedure NavigatorClearBookmark;
|
|
procedure NavigatorDoAction(AButtonIndex: Integer);
|
|
function NavigatorGetNotifier: TcxNavigatorControlNotifier;
|
|
function NavigatorIsActionSupported(AButtonIndex: Integer): Boolean;
|
|
procedure RefreshNavigators;
|
|
procedure CreateSubClasses; override;
|
|
procedure DestroySubClasses; override;
|
|
function CanBandSizing: Boolean; override;
|
|
procedure ControlUpdateData(AInfo: TcxUpdateControlInfo); override;
|
|
procedure DoFilterDialog; virtual;
|
|
procedure DoFocusedRecordChanged(APrevFocusedRecord, AFocusedRecord: Integer); virtual;
|
|
function GetCellAutoHeight: Boolean; override;
|
|
function GetControllerClass: TcxCustomControlControllerClass; override;
|
|
function GetOptionsBehaviorClass: TcxControlOptionsBehaviorClass; override;
|
|
function GetOptionsDataClass: TcxControlOptionsDataClass; override;
|
|
function GetOptionsViewClass: TcxControlOptionsViewClass; override;
|
|
function GetScrollStrategyClass: TcxvgCustomScrollStrategyClass; override;
|
|
function GetViewInfoClass: TcxCustomControlViewInfoClass; override;
|
|
procedure InitDataController; override;
|
|
procedure DataLayoutChanged; override;
|
|
property Controller: TcxvgMultiRecordsController read GetController;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
property Customizing;
|
|
property DataController;
|
|
property LeftVisibleRecord;
|
|
property FocusedRecordIndex: Integer read GetFocusedRecordIndex write SetFocusedRecordIndex;
|
|
property RecordCount;
|
|
published
|
|
property Align;
|
|
property Anchors;
|
|
property Constraints;
|
|
property DragCursor;
|
|
property DragKind;
|
|
property DragMode;
|
|
property Enabled;
|
|
property Font;
|
|
property Images;
|
|
property LayoutStyle: TcxvgLayoutStyle read FLayoutStyle write SetLayoutStyle default lsSingleRecordView;
|
|
property LookAndFeel;
|
|
//before OptionsBehavior
|
|
property OptionsView: TcxvgMultiRecordsOptionsView read GetOptionsView write SetOptionsView;
|
|
property OptionsBehavior: TcxvgMultiRecordsOptionsBehavior read GetOptionsBehavior write SetOptionsBehavior;
|
|
property OptionsData: TcxvgMultiRecordsOptionsData read GetOptionsData write SetOptionsData;
|
|
property ParentFont;
|
|
property PopupMenu;
|
|
property Styles;
|
|
property TabOrder;
|
|
property TabStop;
|
|
property Visible;
|
|
|
|
property OnClick;
|
|
{$IFDEF DELPHI5}
|
|
property OnContextPopup;
|
|
{$ENDIF}
|
|
property OnCustomizationFormVisibleChanged;
|
|
property OnDblClick;
|
|
property OnDragDrop;
|
|
property OnDragOver;
|
|
property OnDrawBackground;
|
|
property OnDrawRowHeader;
|
|
property OnDrawValue;
|
|
property OnEdited;
|
|
property OnEditing;
|
|
property OnEditValueChanged;
|
|
property OnEndDock;
|
|
property OnEndDrag;
|
|
property OnEnter;
|
|
property OnExit;
|
|
property OnFilterControlDialogShow: TNotifyEvent
|
|
read FOnFilterControlDialogShow write FOnFilterControlDialogShow;
|
|
property OnFilterRecord: TcxDataFilterRecordEvent
|
|
read GetFilterRecordEvent write SetFilterRecordEvent;
|
|
property OnFocusedRecordChanged: TcxVerticalGridFocusedRecordChangedEvent
|
|
read FOnFocusedRecordChanged write FOnFocusedRecordChanged;
|
|
property OnInitEdit;
|
|
property OnItemChanged;
|
|
property OnKeyDown;
|
|
property OnKeyPress;
|
|
property OnKeyUp;
|
|
property OnLayoutChanged;
|
|
property OnLeftVisibleBandIndexChanged;
|
|
property OnLeftVisibleRecordIndexChanged;
|
|
property OnMouseDown;
|
|
property OnMouseEnter;
|
|
property OnMouseLeave;
|
|
property OnMouseMove;
|
|
property OnMouseUp;
|
|
property OnMouseWheel;
|
|
property OnMouseWheelDown;
|
|
property OnMouseWheelUp;
|
|
property OnResize;
|
|
property OnStartDock;
|
|
property OnStartDrag;
|
|
property OnTopRowIndexChanged;
|
|
end;
|
|
|
|
{ TcxRowValueInfo }
|
|
|
|
TcxRowValueInfo = class(TcxEditCellViewInfo)
|
|
private
|
|
FFocusRect: TRect;
|
|
FRow: TcxCustomRow;
|
|
FRowCellIndex: Integer;
|
|
FRecordIndex: Integer;
|
|
function GetEditorRowProperties: TcxCustomEditorRowProperties;
|
|
protected
|
|
procedure DoCalculate; override;
|
|
function EditContainer: TcxCellEdit;
|
|
function GetButtonTransparency: TcxEditButtonTransparency; override;
|
|
function GetDisplayValue: Variant; override;
|
|
function GetEditViewParams: TcxViewParams; override;
|
|
function GetFocused: Boolean; override;
|
|
function GetRecordIndex: Integer; override;
|
|
function GetSelectedTextColor: Integer; override;
|
|
function GetSelectedBKColor: Integer; override;
|
|
function IncSearchParams: TcxViewParams;
|
|
function IsAutoHeight: Boolean; override;
|
|
property EditorRowProperties: TcxCustomEditorRowProperties read GetEditorRowProperties;
|
|
public
|
|
property Focused;
|
|
property FocusRect: TRect read FFocusRect write FFocusRect;
|
|
property Row: TcxCustomRow read FRow;
|
|
property RowCellIndex: Integer read FRowCellIndex;
|
|
property ViewParams;
|
|
end;
|
|
|
|
{ TcxRowCaptionInfo }
|
|
|
|
TcxRowCaptionInfo = class(TPersistent, IUnknown, IcxHotTrackElement)
|
|
private
|
|
FCaption: string;
|
|
FCaptionRect: TRect;
|
|
FCaptionTextRect: TRect;
|
|
FFocused: Boolean;
|
|
FImageIndex: Integer;
|
|
FImageRect: TRect;
|
|
FImages: TCustomImageList;
|
|
FRow: TcxCustomRow;
|
|
FRowCellIndex: Integer;
|
|
FViewParams: TcxViewParams;
|
|
FTextFlags: Integer;
|
|
function FindPropertiesHint(const P: TPoint): string;
|
|
protected
|
|
// IUnknown
|
|
function _AddRef: Integer; stdcall;
|
|
function _Release: Integer; stdcall;
|
|
// IcxHotTrackElement
|
|
function GetOrigin: TPoint; virtual;
|
|
function IsNeedHint(ACanvas: TcxCanvas; const P: TPoint;
|
|
out AText: TCaption;
|
|
out AIsMultiLine: Boolean;
|
|
out ATextRect: TRect; var IsNeedOffsetHint: Boolean): Boolean; virtual;
|
|
procedure UpdateHotTrackState(const APoint: TPoint);
|
|
public
|
|
constructor Create; virtual;
|
|
destructor Destroy; override;
|
|
// IUnknown
|
|
function QueryInterface(const IID: TGUID; out Obj): HResult; virtual; stdcall;
|
|
|
|
property Caption: string read FCaption write FCaption;
|
|
property CaptionRect: TRect read FCaptionRect;
|
|
property CaptionTextRect: TRect read FCaptionTextRect;
|
|
property Focused: Boolean read FFocused;
|
|
property ImageIndex: Integer read FImageIndex;
|
|
property ImageRect: TRect read FImageRect;
|
|
property Images: TCustomImageList read FImages;
|
|
property Row: TcxCustomRow read FRow;
|
|
property RowCellIndex: Integer read FRowCellIndex write FRowCellIndex;
|
|
property ViewParams: TcxViewParams read FViewParams;
|
|
property TextFlags: Integer read FTextFlags;
|
|
end;
|
|
|
|
{ TcxCaptionInfoList }
|
|
|
|
TcxCaptionInfoList = class(TcxObjectList)
|
|
private
|
|
function GetItem(Index: Integer): TcxRowCaptionInfo;
|
|
public
|
|
property Items[Index: Integer]: TcxRowCaptionInfo read GetItem; default;
|
|
end;
|
|
|
|
{ TcxValueInfoList }
|
|
|
|
TcxValueInfoList = class(TList)
|
|
private
|
|
FViewInfo: TcxvgCustomViewInfo;
|
|
function GetItem(Index: Integer): TcxRowValueInfo;
|
|
public
|
|
constructor Create(AViewInfo: TcxvgCustomViewInfo);
|
|
destructor Destroy; override;
|
|
procedure Trunc(ACount: Integer);
|
|
property Items[Index: Integer]: TcxRowValueInfo read GetItem; default;
|
|
end;
|
|
|
|
{ TcxCustomRowHeaderInfo }
|
|
|
|
TcxCustomRowHeaderInfo = class
|
|
private
|
|
FCaptionsInfo: TcxCaptionInfoList;
|
|
FCategoryIndents: TIndentInfoList;
|
|
FFocusRect: TRect;
|
|
FLinesInfo: TLineInfoList;
|
|
FRowIndents: TIndentInfoList;
|
|
FTransparent: Boolean;
|
|
FViewInfo: TcxvgCustomViewInfo;
|
|
function GetPaintStyle: TcxvgPaintStyle;
|
|
function GetSelected: Boolean;
|
|
function GetShowButton: Boolean;
|
|
function GetVerticalGrid: TcxCustomVerticalGrid;
|
|
protected
|
|
FButtonRect: TRect;
|
|
FButtonColor: TColor;
|
|
FFocused: Boolean;
|
|
FHeaderCellsRect: TRect;
|
|
FHeaderRect: TRect;
|
|
FIndentBounds: TRect;
|
|
FIndentViewParams: TcxViewParams;
|
|
FRow: TcxCustomRow;
|
|
FViewParams: TcxViewParams;
|
|
procedure AddBottomHorzLine(const R: TRect); virtual;
|
|
procedure AddBoundHeaderLines; virtual;
|
|
procedure AddNextIndentInfo(const ABounds: TRect;
|
|
const AViewParams: TcxViewParams;
|
|
AToCategories, AUnderline, AAddVertLine: Boolean);
|
|
procedure AddRightVertLine(const R: TRect); virtual;
|
|
procedure Calc(const AHeaderRect: TRect; AViewInfo: TcxvgCustomViewInfo;
|
|
ANextRow: TcxCustomRow; ACalcBounds: Boolean);
|
|
function CalcCaptionInfo(ARowProperties: TcxCaptionRowProperties;
|
|
const R: TRect): TcxRowCaptionInfo;
|
|
procedure CalcIndentBounds(ANextRow: TcxCustomRow; ACalculate: Boolean); virtual;
|
|
function CalcIndentsInfo(ALevelCount: Integer;
|
|
ANextRow: TcxCustomRow): TIndentRectInfoList; virtual;
|
|
procedure CalcExpandButton;
|
|
procedure CalcRowCaptionsInfo; virtual;
|
|
procedure CalcViewParams(AAllowFocus: Boolean); virtual;
|
|
procedure Clear; virtual;
|
|
procedure DoCalcExpandButton; virtual;
|
|
function GetButtonPlaceBackgroundWidth: Integer; virtual;
|
|
function GetCaptionViewParams: TcxViewParams; virtual;
|
|
function GetButtonColor: TColor; virtual;
|
|
function GetFocusRect: TRect; virtual;
|
|
function GetTopCentralPoint(AHeight: Integer; const R: TRect): Integer;
|
|
function IncreaseBoundsByLastVertLine: Boolean; virtual;
|
|
function LeftViewPoint: Integer; virtual;
|
|
property IndentViewParams: TcxViewParams read FIndentViewParams;
|
|
property PaintStyle: TcxvgPaintStyle read GetPaintStyle;
|
|
property Selected: Boolean read GetSelected;
|
|
property VerticalGrid: TcxCustomVerticalGrid read GetVerticalGrid;
|
|
property ViewInfo: TcxvgCustomViewInfo read FViewInfo;
|
|
public
|
|
constructor Create(ARow: TcxCustomRow); virtual;
|
|
destructor Destroy; override;
|
|
property CaptionsInfo: TcxCaptionInfoList read FCaptionsInfo;
|
|
property CategoryIndents: TIndentInfoList read FCategoryIndents;
|
|
property ButtonRect: TRect read FButtonRect;
|
|
property ButtonColor: TColor read FButtonColor;
|
|
property Focused: Boolean read FFocused;
|
|
property FocusRect: TRect read FFocusRect write FFocusRect;
|
|
property HeaderCellsRect: TRect read FHeaderCellsRect;
|
|
property HeaderRect: TRect read FHeaderRect write FHeaderRect;
|
|
property IndentBounds: TRect read FIndentBounds;
|
|
property LinesInfo: TLineInfoList read FLinesInfo;
|
|
property Row: TcxCustomRow read FRow;
|
|
property RowIndents: TIndentInfoList read FRowIndents;
|
|
property ShowButton: Boolean read GetShowButton;
|
|
property Transparent: Boolean read FTransparent write FTransparent;
|
|
property ViewParams: TcxViewParams read FViewParams write FViewParams;
|
|
end;
|
|
|
|
{ TcxCustomRowViewInfo }
|
|
|
|
TcxCustomRowViewInfo = class
|
|
private
|
|
FBandIndex: Integer;
|
|
FBandRowIndex: Integer;
|
|
FCalculatedHeight: Integer;
|
|
FHeaderInfo: TcxCustomRowHeaderInfo;
|
|
FRow: TcxCustomRow;
|
|
FRowRect: TRect;
|
|
FValuesInfo: TcxValueInfoList;
|
|
FValuesRect: TRect;
|
|
FViewInfo: TcxvgCustomViewInfo;
|
|
function GetRowValueInfo(ARecordIndex, ACellIndex: Integer): TcxRowValueInfo;
|
|
function GetVerticalGrid: TcxCustomVerticalGrid;
|
|
protected
|
|
procedure AddRectValueLines(R: TRect; ALast, ABottomLineNeeded: Boolean);
|
|
procedure CalcValuesInfo; virtual; abstract;
|
|
procedure CalcRowHeaderInfo(ANextRow: TcxCustomRow); virtual;
|
|
function CalcRowValueInfo(ARowProperties: TcxCustomRowProperties;
|
|
AViewInfo: TcxvgCustomViewInfo;
|
|
ARecordIndex, ACellIndex: Integer): TcxRowValueInfo;
|
|
procedure CalcPaintViewParamsLines(ANextRow: TcxCustomRow); virtual;
|
|
function GetValueHeight(ARecordIndex: Integer; AWidth: Integer;
|
|
AViewInfo: TcxvgCustomViewInfo): Integer; virtual;
|
|
function GetRowValueInfoClass: TcxRowValueInfoClass; virtual;
|
|
procedure ValidateViewInfo;
|
|
|
|
property ValuesInfo: TcxValueInfoList read FValuesInfo;
|
|
property ViewInfo: TcxvgCustomViewInfo read FViewInfo;
|
|
public
|
|
constructor Create(ARow: TcxCustomRow); virtual;
|
|
destructor Destroy; override;
|
|
procedure Calc(const ARowRect: TRect;
|
|
AViewInfo: TcxvgCustomViewInfo;
|
|
ANextRow: TcxCustomRow);
|
|
procedure Update;
|
|
procedure UpdateRecord(ARecordIndex: Integer);
|
|
property BandIndex: Integer read FBandIndex write FBandIndex;
|
|
property BandRowIndex: Integer read FBandRowIndex write FBandRowIndex;
|
|
property CalculatedHeight: Integer read FCalculatedHeight write FCalculatedHeight;
|
|
property HeaderInfo: TcxCustomRowHeaderInfo read FHeaderInfo;
|
|
property Row: TcxCustomRow read FRow;
|
|
property RowRect: TRect read FRowRect;
|
|
property RowValueInfo[ARecordIndex, ACellIndex: Integer]: TcxRowValueInfo read GetRowValueInfo;
|
|
property ValuesRect: TRect read FValuesRect write FValuesRect;
|
|
property VerticalGrid: TcxCustomVerticalGrid read GetVerticalGrid;
|
|
end;
|
|
|
|
{ TcxRowViewInfoList }
|
|
|
|
TcxRowViewInfoList = class(TList)
|
|
private
|
|
function GetItem(Index: Integer): TcxCustomRowViewInfo;
|
|
public
|
|
constructor Create;
|
|
function Find(ARow: TcxCustomRow): TcxCustomRowViewInfo;
|
|
property Items[Index: Integer]: TcxCustomRowViewInfo read GetItem; default;
|
|
end;
|
|
|
|
{ TcxvgCustomViewInfo }
|
|
|
|
TcxvgCustomViewInfo = class(TcxCustomControlViewInfo)
|
|
private
|
|
FBandBorderColor: TColor;
|
|
FBandMinWidth: Integer;
|
|
FBandsInterval: Integer;
|
|
FButtonSize: Integer;
|
|
FCalcHelper: TcxvgCustomPaintStyleCalcHelper;
|
|
FClipRect: TRect;
|
|
FDividerWidth: Integer;
|
|
FExplorerButtonSize: TSize;
|
|
FUseCategoryExplorerStyle: Boolean;
|
|
FFocusLinesInfo: TLineInfoList;
|
|
FFullHeaderWidth: Integer;
|
|
FHorzLineBrush: TBrush;
|
|
FHorzLineWidth: Integer;
|
|
FImageSize: TSize;
|
|
FLevelWidth: Integer;
|
|
FLinesInfo: TLineInfoList;
|
|
FLockDividerPos: Boolean;
|
|
FMaxVisibleLevel: Integer;
|
|
FRowHeaderMinWidth: Integer;
|
|
FRowIndentWidth: Integer;
|
|
FRowMinHeight: Integer;
|
|
FRowsViewInfo: TcxRowViewInfoList;
|
|
FShowHeaders: Boolean;
|
|
FVerticalGrid: TcxCustomVerticalGrid;
|
|
FVertLineBrush: TBrush;
|
|
FVertLineWidth: Integer;
|
|
FViewBandWidth: Integer;
|
|
FViewHeaderWidth: Integer;
|
|
FViewValueWidth: Integer;
|
|
FViewRects: TViewRects;
|
|
FVisibleRows: TList;
|
|
procedure ClearLinesAndRows;
|
|
function GetBandInfo: TBandInfoList;
|
|
function GetFirstVisibleRecordIndex: Integer;
|
|
function GetMinRowHeight: Integer;
|
|
function GetPainter: TcxvgPainter;
|
|
function GetScroller: TcxvgScroller;
|
|
function GetVisibleRow(Index: Integer): TcxCustomRow;
|
|
function GetVisibleRowCount: Integer;
|
|
procedure UpdateScroller;
|
|
protected
|
|
// overriding methods
|
|
function CalculateDefaultEditHeight: Integer; override;
|
|
procedure DoCalculate; override;
|
|
procedure UpdateSelection; override;
|
|
//
|
|
procedure AddBandRowsLines(const R: TRect); virtual;
|
|
procedure AddBottomValueSide(const R: TRect);
|
|
procedure AddEmptyRects; virtual; abstract;
|
|
procedure AddRightValueSide(const R: TRect; ALast: Boolean); virtual;
|
|
procedure CalcBandRects; virtual;
|
|
procedure CalcBandRowsViewInfo(var AFirstRowIndex: Integer;
|
|
const ABandRect: TRect; ABandIndex, ABandRowCount: Integer); virtual;
|
|
procedure CalcBandWidth; virtual;
|
|
procedure CalcEmpty; virtual;
|
|
procedure CalcCategoryExplorerStyle;
|
|
procedure CalcLayoutGeneral; virtual;
|
|
procedure CalcRowRects(ARowViewInfo: TcxCustomRowViewInfo); virtual;
|
|
procedure CalcRowsViewInfo; virtual;
|
|
procedure CalcViewRects; virtual;
|
|
function CanAddRowToBand(const ARowRect, ABandRect: TRect; ABandRowIndex: Integer): Boolean; virtual;
|
|
procedure CheckMaxRowHeaderWidth(var Value: Integer; AValueMinWidth: Integer); virtual;
|
|
function CheckShowRowHeader(ARowViewInfo: TcxCustomRowViewInfo): Boolean;
|
|
procedure Clear; virtual;
|
|
procedure CreateBand(ABandHeight, ABandWidth: Integer); virtual;
|
|
procedure CreateBrushes; virtual;
|
|
function CreateCalcHelper: TcxvgCustomPaintStyleCalcHelper; virtual;
|
|
procedure DestroyBrushes; virtual;
|
|
function GetBandSizeableRect(const ABandRect: TRect): TRect; virtual;
|
|
function GetRowAutoHeight(ARow: TcxCustomRow): Boolean; virtual;
|
|
function GetRowHeight(ARowViewInfo: TcxCustomRowViewInfo; ABandWidth: Integer): Integer; virtual;
|
|
function GetViewBandWidth: Integer; virtual;
|
|
function GetViewHeaderWidth: Integer; virtual;
|
|
function GetViewMinHeaderWidth: Integer; virtual;
|
|
function GetViewValueWidth: Integer; virtual;
|
|
function GetVisibleValueCount: Integer; virtual; abstract;
|
|
procedure LayoutStyleChanged; virtual;
|
|
procedure Reset; virtual;
|
|
function ScaleRowRects(ARowViewInfo: TcxCustomRowViewInfo): TRectScaler; virtual;
|
|
procedure SetDividerPos(APos: Integer); virtual;
|
|
procedure SetValueWidth(AWidth: Integer); virtual;
|
|
procedure UpdateVisibleRows;
|
|
property Scroller: TcxvgScroller read GetScroller;
|
|
property LockDividerPos: Boolean read FLockDividerPos;
|
|
property MaxVisibleLevel: Integer read FMaxVisibleLevel;
|
|
property ViewBandWidth: Integer read FViewBandWidth write FViewBandWidth;
|
|
property ViewHeaderWidth: Integer read FViewHeaderWidth write FViewHeaderWidth;
|
|
property ViewValueWidth: Integer read FViewValueWidth write FViewValueWidth;
|
|
public
|
|
constructor Create(AOwner: TcxEditingControl); override;
|
|
destructor Destroy; override;
|
|
procedure CalcEditCell(const ABounds: TRect; ARowValueInfo: TcxRowValueInfo); virtual;
|
|
function CalcRowHeight(ARow: TcxCustomRow): Integer;
|
|
procedure ChangeFocusedRow(ANewFocus, AOldFocus: TcxCustomRow); virtual;
|
|
function GetDefaultGridModeBufferCount: Integer; virtual;
|
|
function GetRowViewInfo(ARow: TcxCustomRow): TcxCustomRowViewInfo;
|
|
function GetValueRect(AValueIndex: Integer;
|
|
ARowViewInfo: TcxCustomRowViewInfo): TRect; virtual;
|
|
function GetValuesRect(ARowViewInfo: TcxCustomRowViewInfo): TRect; virtual;
|
|
procedure UpdateRecord(ARecordIndex: Integer); virtual;
|
|
// properties
|
|
property BandBorderColor: TColor read FBandBorderColor write FBandBorderColor;
|
|
property BandMinWidth: Integer read FBandMinWidth;
|
|
property BandInfo: TBandInfoList read GetBandInfo;
|
|
property BandsInterval: Integer read FBandsInterval;
|
|
property ButtonSize: Integer read FButtonSize write FButtonSize;
|
|
property CalcHelper: TcxvgCustomPaintStyleCalcHelper read FCalcHelper;
|
|
property ClipRect: TRect read FClipRect;
|
|
property DividerWidth: Integer read FDividerWidth write FDividerWidth;
|
|
property ExplorerButtonSize: TSize read FExplorerButtonSize;
|
|
property UseCategoryExplorerStyle: Boolean read FUseCategoryExplorerStyle;
|
|
property FirstVisibleRecordIndex: Integer read GetFirstVisibleRecordIndex;
|
|
property FocusLinesInfo: TLineInfoList read FFocusLinesInfo;
|
|
property FullHeaderWidth: Integer read FFullHeaderWidth;
|
|
property HorzLineBrush: TBrush read FHorzLineBrush write FHorzLineBrush;
|
|
property HorzLineWidth: Integer read FHorzLineWidth;
|
|
property ImageSize: TSize read FImageSize write FImageSize;
|
|
property LevelWidth: Integer read FLevelWidth write FLevelWidth;
|
|
property LinesInfo: TLineInfoList read FLinesInfo write FLinesInfo;
|
|
property Painter: TcxvgPainter read GetPainter;
|
|
property RowHeaderMinWidth: Integer read FRowHeaderMinWidth;
|
|
property RowIndentWidth: Integer read FRowIndentWidth;
|
|
property RowsViewInfo: TcxRowViewInfoList read FRowsViewInfo;
|
|
property ShowHeaders: Boolean read FShowHeaders;
|
|
property VerticalGrid: TcxCustomVerticalGrid read FVerticalGrid;
|
|
property VertLineBrush: TBrush read FVertLineBrush write FVertLineBrush;
|
|
property VertLineWidth: Integer read FVertLineWidth write FVertLineWidth;
|
|
property ViewRects: TViewRects read FViewRects;
|
|
property VisibleRows[Index: Integer]: TcxCustomRow read GetVisibleRow;
|
|
property VisibleRowCount: Integer read GetVisibleRowCount;
|
|
property VisibleValueCount: Integer read GetVisibleValueCount;
|
|
end;
|
|
|
|
{ TcxvgCustomPaintStyleCalcHelper }
|
|
|
|
TcxvgCustomPaintStyleCalcHelper = class
|
|
private
|
|
FScroller: TcxvgScroller;
|
|
FViewInfo: TcxvgCustomViewInfo;
|
|
FVerticalGrid: TcxCustomVerticalGrid;
|
|
protected
|
|
function CreateHorzLineBrush: TBrush; virtual; abstract;
|
|
function CreateVertLineBrush: TBrush; virtual; abstract;
|
|
function GetBandBorderColor: TColor; virtual;
|
|
function GetDividerWidth: Integer; virtual; abstract;
|
|
function GetIndentWidth: Integer; virtual; abstract;
|
|
public
|
|
constructor Create(AViewInfo: TcxvgCustomViewInfo); virtual;
|
|
procedure AddBoundHeaderLines(ARowHeaderInfo: TcxCustomRowHeaderInfo); virtual; abstract;
|
|
procedure AddDivider(ALinesInfo: TLineInfoList; const R: TRect;
|
|
AColor: TColor; AIsSeparator: Boolean); virtual; abstract;
|
|
procedure AddHeaderIndentLines(ARowHeaderInfo: TcxCustomRowHeaderInfo;
|
|
const R: TRect; const AViewParams: TcxViewParams;
|
|
AToCategories, AUnderline, AAddVertLine: Boolean); virtual; abstract;
|
|
procedure CalcPaintViewParamsLines(ARowViewInfo: TcxCustomRowViewInfo;
|
|
ANextRow: TcxCustomRow); virtual; abstract;
|
|
function ChangeFocusedRow(ANewFocus, AOldFocus: TcxCustomRow): TRect; virtual; abstract;
|
|
function GetBackgroundColor: TColor; virtual;
|
|
function GetCategoryColor: TColor; virtual; abstract;
|
|
function GetCategoryFocusRect(ARowHeaderInfo: TcxCustomRowHeaderInfo): TRect; virtual; abstract;
|
|
function GetCategoryTextColor: TColor; virtual; abstract;
|
|
function GetContentColor(AFocused: Boolean): TColor; virtual; abstract;
|
|
function GetContentTextColor: TColor; virtual; abstract;
|
|
function GetHeaderColor: TColor; virtual; abstract;
|
|
function GetHeaderTextColor: TColor; virtual; abstract;
|
|
function GetIndentViewParams(ARow, AParentIndentRow: TcxCustomRow): TcxViewParams; virtual; abstract;
|
|
function IsDrawValueFocusRect: Boolean; virtual; abstract;
|
|
property Scroller: TcxvgScroller read FScroller;
|
|
property ViewInfo: TcxvgCustomViewInfo read FViewInfo;
|
|
property VerticalGrid: TcxCustomVerticalGrid read FVerticalGrid;
|
|
end;
|
|
|
|
{ TcxvgDotNetStyleCalcHelper }
|
|
|
|
TcxvgDotNetStyleCalcHelper = class(TcxvgCustomPaintStyleCalcHelper)
|
|
protected
|
|
function CreateHorzLineBrush: TBrush; override;
|
|
function CreateVertLineBrush: TBrush; override;
|
|
function GetDividerWidth: Integer; override;
|
|
function GetIndentWidth: Integer; override;
|
|
public
|
|
procedure AddBoundHeaderLines(ARowHeaderInfo: TcxCustomRowHeaderInfo); override;
|
|
procedure AddDivider(ALinesInfo: TLineInfoList; const R: TRect;
|
|
AColor: TColor; AIsSeparator: Boolean); override;
|
|
procedure AddHeaderIndentLines(ARowHeaderInfo: TcxCustomRowHeaderInfo;
|
|
const R: TRect; const AViewParams: TcxViewParams;
|
|
AToCategories, AUnderline, AAddVertLine: Boolean); override;
|
|
procedure CalcPaintViewParamsLines(ARowViewInfo: TcxCustomRowViewInfo;
|
|
ANextRow: TcxCustomRow); override;
|
|
function ChangeFocusedRow(ANewFocus, AOldFocus: TcxCustomRow): TRect; override;
|
|
function GetCategoryColor: TColor; override;
|
|
function GetCategoryFocusRect(ARowHeaderInfo: TcxCustomRowHeaderInfo): TRect; override;
|
|
function GetCategoryTextColor: TColor; override;
|
|
function GetContentColor(AFocused: Boolean): TColor; override;
|
|
function GetContentTextColor: TColor; override;
|
|
function GetHeaderColor: TColor; override;
|
|
function GetHeaderTextColor: TColor; override;
|
|
function GetIndentViewParams(ARow, AParentIndentRow: TcxCustomRow): TcxViewParams; override;
|
|
function IsDrawValueFocusRect: Boolean; override;
|
|
end;
|
|
|
|
{ TcxvgStyle3DCalcHelper }
|
|
|
|
TcxvgStyle3DCalcHelper = class(TcxvgCustomPaintStyleCalcHelper)
|
|
protected
|
|
function CreateHorzLineBrush: TBrush; override;
|
|
function CreateVertLineBrush: TBrush; override;
|
|
function GetDividerWidth: Integer; override;
|
|
function GetIndentWidth: Integer; override;
|
|
public
|
|
procedure AddBoundHeaderLines(ARowHeaderInfo: TcxCustomRowHeaderInfo); override;
|
|
procedure AddHeaderIndentLines(ARowHeaderInfo: TcxCustomRowHeaderInfo;
|
|
const R: TRect; const AViewParams: TcxViewParams;
|
|
AToCategories, AUnderline, AAddVertLine: Boolean); override;
|
|
procedure AddDivider(ALinesInfo: TLineInfoList;
|
|
const R: TRect; AColor: TColor; AIsSeparator: Boolean); override;
|
|
procedure CalcPaintViewParamsLines(ARowViewInfo: TcxCustomRowViewInfo;
|
|
ANextRow: TcxCustomRow); override;
|
|
function ChangeFocusedRow(ANewFocus, AOldFocus: TcxCustomRow): TRect; override;
|
|
function GetCategoryColor: TColor; override;
|
|
function GetCategoryFocusRect(ARowHeaderInfo: TcxCustomRowHeaderInfo): TRect; override;
|
|
function GetCategoryTextColor: TColor; override;
|
|
function GetContentColor(AFocused: Boolean): TColor; override;
|
|
function GetContentTextColor: TColor; override;
|
|
function GetHeaderColor: TColor; override;
|
|
function GetHeaderTextColor: TColor; override;
|
|
function GetIndentViewParams(ARow, AParentIndentRow: TcxCustomRow): TcxViewParams; override;
|
|
function IsDrawValueFocusRect: Boolean; override;
|
|
end;
|
|
|
|
{ TcxvgStyle3DCalcHelper }
|
|
|
|
TcxvgSkinCalcHelper = class(TcxvgDotNetStyleCalcHelper)
|
|
protected
|
|
function CreateHorzLineBrush: TBrush; override;
|
|
function CreateVertLineBrush: TBrush; override;
|
|
function GetBandBorderColor: TColor; override;
|
|
public
|
|
procedure AddBoundHeaderLines(ARowHeaderInfo: TcxCustomRowHeaderInfo); override;
|
|
procedure AddHeaderIndentLines(ARowHeaderInfo: TcxCustomRowHeaderInfo;
|
|
const R: TRect; const AViewParams: TcxViewParams;
|
|
AToCategories, AUnderline, AAddVertLine: Boolean); override;
|
|
function GetBackgroundColor: TColor; override;
|
|
function GetCategoryColor: TColor; override;
|
|
function GetCategoryTextColor: TColor; override;
|
|
function GetHeaderColor: TColor; override;
|
|
function GetHeaderTextColor: TColor; override;
|
|
end;
|
|
|
|
{ TcxvgPainter }
|
|
|
|
TcxvgPainter = class(TcxCustomControlPainter)
|
|
private
|
|
function GetViewInfo: TcxvgCustomViewInfo;
|
|
function GetVerticalGrid: TcxCustomVerticalGrid;
|
|
protected
|
|
procedure DoPaint; override;
|
|
procedure DrawRows;
|
|
procedure DrawStyleFeatures; virtual;
|
|
public
|
|
constructor Create(AOwner: TcxEditingControl); override;
|
|
procedure DrawBackground; virtual;
|
|
procedure DrawButton(ARowHeader: TcxCustomRowHeaderInfo); virtual;
|
|
procedure DrawCategoryRowHeader(ARowHeader: TcxCustomRowHeaderInfo); virtual;
|
|
procedure DrawCategoryRowIndent(ARowHeader: TcxCustomRowHeaderInfo); virtual;
|
|
procedure DrawHeaderDragImage(ARowHeader: TcxCustomRowHeaderInfo); virtual;
|
|
procedure DrawHeaderSeparators(ARowHeader: TcxCustomRowHeaderInfo); virtual;
|
|
procedure DrawImage(ACaptionInfo: TcxRowCaptionInfo); virtual;
|
|
procedure DrawLines(ALinesInfo: TLineInfoList; R: TRect); virtual;
|
|
procedure DrawRow(ARowViewInfo: TcxCustomRowViewInfo); virtual;
|
|
procedure DrawRowHeader(ARowHeader: TcxCustomRowHeaderInfo); virtual;
|
|
procedure DrawRowHeaderCell(ACaptionInfo: TcxRowCaptionInfo; ATransparent: Boolean); virtual;
|
|
procedure DrawRowIndent(ARowHeader: TcxCustomRowHeaderInfo); virtual;
|
|
procedure DrawRowValueCell(AValueInfo: TcxRowValueInfo); virtual;
|
|
procedure DrawValuesSeparators(ARowViewInfo: TcxCustomRowViewInfo); virtual;
|
|
procedure FillRect(const R: TRect; ABitmap: TBitmap = nil);
|
|
property VerticalGrid: TcxCustomVerticalGrid read GetVerticalGrid;
|
|
property ViewInfo: TcxvgCustomViewInfo read GetViewInfo;
|
|
end;
|
|
|
|
{ TcxStyle3DPainter }
|
|
|
|
TcxStyle3DPainter = class(TcxvgPainter)
|
|
protected
|
|
procedure DrawStyleFeatures; override;
|
|
end;
|
|
|
|
// STYLES
|
|
PcxvgContentParamsData = ^TcxvgContentParamsData;
|
|
TcxvgContentParamsData = record
|
|
Row: TcxCustomRow;
|
|
Focused: Boolean;
|
|
end;
|
|
|
|
TcxvgOnGetItemStyleEvent = procedure(Sender: TObject; ARow: TcxCustomRow;
|
|
var AStyle: TcxStyle) of object;
|
|
TcxvgOnGetContentStyleEvent = procedure(Sender: TObject;
|
|
AEditProp: TcxCustomEditorRowProperties; AFocused: Boolean;
|
|
ARecordIndex: Integer; var AStyle: TcxStyle) of object;
|
|
|
|
{ TcxvgCustomRowStyles }
|
|
|
|
TcxvgCustomRowStyles = class(TcxStyles)
|
|
protected
|
|
procedure Changed(AIndex: Integer); override;
|
|
end;
|
|
|
|
{ TcxCategoryRowStyles }
|
|
|
|
TcxCategoryRowStyles = class(TcxvgCustomRowStyles)
|
|
public
|
|
procedure Assign(Source: TPersistent); override;
|
|
published
|
|
property Header: TcxStyle index vgrs_Header read GetValue write SetValue;
|
|
end;
|
|
|
|
{ TcxEditorRowStyles }
|
|
|
|
TcxEditorRowStyles = class(TcxCategoryRowStyles)
|
|
public
|
|
procedure Assign(Source: TPersistent); override;
|
|
published
|
|
property Content: TcxStyle index vgrs_Content read GetValue write SetValue;
|
|
property Header;
|
|
end;
|
|
|
|
{ TcxVerticalGridStyleSheet }
|
|
|
|
TcxVerticalGridStyleSheet = class(TcxCustomStyleSheet)
|
|
private
|
|
function GetStylesValue: TcxVerticalGridStyles;
|
|
procedure SetStylesValue(Value: TcxVerticalGridStyles);
|
|
public
|
|
class function GetStylesClass: TcxCustomStylesClass; override;
|
|
published
|
|
property Styles: TcxVerticalGridStyles read GetStylesValue write SetStylesValue;
|
|
end;
|
|
|
|
{ TcxVerticalGridStyles }
|
|
|
|
TcxVerticalGridStyles = class(TcxCustomControlStyles)
|
|
private
|
|
FOnGetCategoryStyle: TcxvgOnGetItemStyleEvent;
|
|
FOnGetHeaderStyle: TcxvgOnGetItemStyleEvent;
|
|
FOnGetContentStyle: TcxvgOnGetContentStyleEvent;
|
|
procedure CallInheritedDefaultViewParams(Index: Integer; AData: Pointer; out AParams: TcxViewParams);
|
|
protected
|
|
procedure GetDefaultViewParams(Index: Integer; AData: TObject; out AParams: TcxViewParams); override;
|
|
function GetStyleFromEvent(const AEvent: TcxvgOnGetItemStyleEvent; AItem: TcxCustomRow): TcxStyle;
|
|
public
|
|
procedure Assign(Source: TPersistent); override;
|
|
function GetCategoryParams(ARow: TcxCustomRow): TcxViewParams; virtual;
|
|
function GetContentParams(AEditProp: TcxCustomEditorRowProperties; AFocused: Boolean; ARecordIndex: Integer): TcxViewParams; virtual;
|
|
function GetHeaderParams(ARow: TcxCustomRow): TcxViewParams; virtual;
|
|
function GetIncSearchParams: TcxViewParams;
|
|
function GetSelectedHeaderParams(ARow: TcxCustomRow): TcxViewParams;
|
|
published
|
|
property Category: TcxStyle index vgs_Category read GetValue write SetValue;
|
|
property Header: TcxStyle index vgs_Header read GetValue write SetValue;
|
|
property IncSearch: TcxStyle index vgs_IncSearch read GetValue write SetValue;
|
|
property OnGetCategoryStyle: TcxvgOnGetItemStyleEvent read FOnGetCategoryStyle write FOnGetCategoryStyle;
|
|
property OnGetHeaderStyle: TcxvgOnGetItemStyleEvent read FOnGetHeaderStyle write FOnGetHeaderStyle;
|
|
property OnGetContentStyle: TcxvgOnGetContentStyleEvent read FOnGetContentStyle write FOnGetContentStyle;
|
|
property Background;
|
|
property Content;
|
|
property Inactive;
|
|
property Selection;
|
|
property StyleSheet;
|
|
end;
|
|
|
|
{ TcxVerticalGridItemsCustomizeListBox }
|
|
|
|
TcxVerticalGridItemsCustomizeListBox = class(TcxCustomizeListBox)
|
|
private
|
|
FCanvas: TcxCanvas;
|
|
FDragging: Boolean;
|
|
FIsCategoryListBox: Boolean;
|
|
FVerticalGrid: TcxCustomVerticalGrid;
|
|
FDragAndDropItemIndex: Integer;
|
|
FMouseDownPos: TPoint;
|
|
FOffset: TPoint;
|
|
function GetDragRow: TcxCustomRow;
|
|
function GetPainter: TcxvgPainter;
|
|
procedure CNDrawItem(var Message: TWMDrawItem); message CN_DRAWITEM;
|
|
procedure WMCancelMode(var Message: TWMCancelMode); message WM_CANCELMODE;
|
|
procedure WMPaint(var Message: TMessage); message WM_PAINT;
|
|
protected
|
|
IsPaint: Boolean;
|
|
procedure CalcHeaderViewInfo(const R: TRect; AHeaderInfo: TcxCustomRowHeaderInfo); virtual;
|
|
procedure DragOver(Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); override;
|
|
procedure DrawItem(Index: Integer; Rect: TRect; State: TOwnerDrawState); override;
|
|
procedure InitDragAndDropObject; virtual;
|
|
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
|
|
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
|
|
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
|
|
procedure RefreshList;
|
|
property Canvas: TcxCanvas read FCanvas;
|
|
property DragRow: TcxCustomRow read GetDragRow;
|
|
property VerticalGrid: TcxCustomVerticalGrid read FVerticalGrid;
|
|
property Painter: TcxvgPainter read GetPainter;
|
|
public
|
|
constructor CreateEx(AOwner: TComponent;
|
|
AVerticalGrid: TcxCustomVerticalGrid; IsCategoryListBox: Boolean);
|
|
procedure DragDrop(Source: TObject; X, Y: Integer); override;
|
|
destructor Destroy; override;
|
|
end;
|
|
|
|
{ TcxVerticalGridCustomizationForm }
|
|
|
|
TcxVerticalGridCustomizationForm = class(TForm)
|
|
private
|
|
FOwner: TcxVerticalGridCustomizing;
|
|
FHookTimer: TTimer;
|
|
function GetVerticalGrid: TcxCustomVerticalGrid;
|
|
procedure HookTimerHandler(Sender: TObject);
|
|
protected
|
|
procedure CreateParams(var Params: TCreateParams); override;
|
|
procedure DoClose(var Action: TCloseAction); override;
|
|
procedure DoShow; override;
|
|
|
|
property Customizing: TcxVerticalGridCustomizing read FOwner;
|
|
property VerticalGrid: TcxCustomVerticalGrid read GetVerticalGrid;
|
|
public
|
|
constructor CreateEx(AOwner: TcxVerticalGridCustomizing);
|
|
destructor Destroy; override;
|
|
end;
|
|
|
|
{ TcxVerticalGridCustomizing }
|
|
|
|
TcxVerticalGridCustomizing = class(TcxOwnedInterfacedPersistent)
|
|
private
|
|
FCategoryListBox: TcxVerticalGridItemsCustomizeListBox;
|
|
FForm: TcxVerticalGridCustomizationForm;
|
|
FRowListBox: TcxVerticalGridItemsCustomizeListBox;
|
|
FLastBandIndex: Integer;
|
|
FLastHeaderIndex: Integer;
|
|
FLastPosition: TPoint;
|
|
FLineHeight: Integer;
|
|
FPageControl: TPageControl;
|
|
FPanel: TPanel;
|
|
FButtonNew: TcxButton;
|
|
FButtonDelete: TcxButton;
|
|
FRowCount: Integer;
|
|
FSaveDragMode: TDragMode;
|
|
FShowCategoryButtons: Boolean;
|
|
FShowCategoryTab: Boolean;
|
|
FTabSheetCategories: TTabSheet;
|
|
FTabSheetRows: TTabSheet;
|
|
FVerticalGrid: TcxCustomVerticalGrid;
|
|
FVisible: Boolean;
|
|
procedure CreateCategoryClick(Sender: TObject);
|
|
procedure DeleteCategoryClick(Sender: TObject);
|
|
procedure SetRowCount(Value: Integer);
|
|
procedure SetShowCategoryButtons(const Value: Boolean);
|
|
procedure SetVisible(Value: Boolean);
|
|
procedure ShowCustomizingForm;
|
|
procedure UpdateButtons(Sender: TObject);
|
|
protected
|
|
procedure AdjustControls; virtual;
|
|
function CanDrop(const P: TPoint): Boolean; virtual;
|
|
procedure CreateCategoryPanel;
|
|
procedure CreateCategoryRow; virtual;
|
|
procedure CreateControls; virtual;
|
|
procedure CreateCustomizingForm;
|
|
procedure FormClose(Sender: TObject; var Action: TCloseAction); virtual;
|
|
procedure FormShow(Sender: TObject); virtual;
|
|
procedure LookAndFeelChanged; virtual;
|
|
procedure ReleaseControls;
|
|
procedure SetControlParent(AControl, AParent: TWinControl);
|
|
function SizeDelta: TSize; virtual;
|
|
procedure ValidateListBox(AListBox: TcxVerticalGridItemsCustomizeListBox; AIndex: Integer);
|
|
procedure Update; virtual;
|
|
// IcxVerticalGridDesigner
|
|
procedure ComponentRemoved(Sender: TObject); virtual;
|
|
procedure Modified; virtual;
|
|
property CategoryListBox: TcxVerticalGridItemsCustomizeListBox read FCategoryListBox;
|
|
property CustomizingPos: TPoint read FLastPosition write FLastPosition;
|
|
property RowListBox: TcxVerticalGridItemsCustomizeListBox read FRowListBox;
|
|
property VerticalGrid: TcxCustomVerticalGrid read FVerticalGrid;
|
|
public
|
|
constructor Create(AOwner: TPersistent); override;
|
|
destructor Destroy; override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
procedure MakeCategorySheetVisible;
|
|
procedure MakeRowSheetVisible;
|
|
property Form: TcxVerticalGridCustomizationForm read FForm;
|
|
property RowCount: Integer read FRowCount write SetRowCount default 10;
|
|
property ShowCategoryButtons: Boolean read FShowCategoryButtons write SetShowCategoryButtons;
|
|
property ShowCategoryTab: Boolean read FShowCategoryTab write FShowCategoryTab;
|
|
property Visible: Boolean read FVisible write SetVisible;
|
|
end;
|
|
|
|
function GetTextAligmentFlags(AProperties: TcxCaptionRowProperties): Integer; overload;
|
|
function GetTextAligmentFlags(AHorz: TAlignment; AVert: TcxAlignmentVert): Integer; overload;
|
|
procedure cxVerticalGridError(const Msg: string);
|
|
|
|
implementation
|
|
|
|
uses
|
|
{$IFDEF DELPHI6}
|
|
Variants, Types,
|
|
{$ELSE}
|
|
MultiMon,
|
|
{$ENDIF}
|
|
dxUxTheme, dxThemeManager, dxThemeConsts,
|
|
cxVGridConsts, cxVGridViewInfo, cxGeometry, cxVGridNewCategory,
|
|
cxFilterControlDialog, cxDataUtils, cxEditUtils, cxDrawTextUtils, cxContainer,
|
|
cxTextEdit, cxLibraryConsts;
|
|
|
|
{$R cxInsCur.res}
|
|
|
|
const
|
|
cxvgScrollDelta = 32;
|
|
|
|
// Cursors
|
|
cxInspectorInsertCursor = 'CXVG_INSERT';
|
|
cxInspectorAddChildCursor = 'CXVG_ADDCHILD';
|
|
cxInspectorAddCursor = 'CXVG_ADD';
|
|
cxInspectorHideCursor = 'CXVG_HIDE';
|
|
cxInspectorNoDragCursor = 'CXVG_NODRAG';
|
|
|
|
type
|
|
TControlAccess = class(TControl);
|
|
TcxEditingControllerAccess = class(TcxEditingController);
|
|
TcxHotTrackControllerAccess = class(TcxHotTrackController);
|
|
|
|
const
|
|
HorzAlignment: array[TAlignment] of Integer = (CXTO_LEFT, CXTO_RIGHT, CXTO_CENTER_HORIZONTALLY);
|
|
VertAlignment: array[TcxAlignmentVert] of Integer = (CXTO_TOP, CXTO_BOTTOM, CXTO_CENTER_VERTICALLY);
|
|
|
|
function GetTextAligmentFlags(AProperties: TcxCaptionRowProperties): Integer; overload;
|
|
begin
|
|
Result := HorzAlignment[AProperties.HeaderAlignmentHorz] or
|
|
VertAlignment[AProperties.HeaderAlignmentVert];
|
|
end;
|
|
|
|
function GetTextAligmentFlags(AHorz: TAlignment;
|
|
AVert: TcxAlignmentVert): Integer; overload;
|
|
begin
|
|
Result := HorzAlignment[AHorz] or VertAlignment[AVert];
|
|
end;
|
|
|
|
procedure cxVerticalGridError(const Msg: string);
|
|
begin
|
|
raise EcxVerticalGridError.Create(Msg);
|
|
end;
|
|
|
|
{ TcxvgOptionsBehavior }
|
|
|
|
constructor TcxvgOptionsBehavior.Create(AOwner: TPersistent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
FBandSizing := True;
|
|
FHeaderSizing := True;
|
|
FRowTracking := True;
|
|
CellHints := True;
|
|
end;
|
|
|
|
procedure TcxvgOptionsBehavior.Assign(Source: TPersistent);
|
|
begin
|
|
inherited Assign(Source);
|
|
if Source is TcxvgOptionsBehavior then
|
|
with TcxvgOptionsBehavior(Source) do
|
|
begin
|
|
Self.BandSizing := BandSizing;
|
|
Self.HeaderSizing := HeaderSizing;
|
|
Self.RowSizing := RowSizing;
|
|
Self.RowTracking := RowTracking;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgOptionsBehavior.RestoreDefaults;
|
|
begin
|
|
FAlwaysShowEditorAssigned := False;
|
|
end;
|
|
|
|
procedure TcxvgOptionsBehavior.InternalSetAlwaysShowEditor(Value: Boolean);
|
|
begin
|
|
inherited AlwaysShowEditor := Value;
|
|
end;
|
|
|
|
function TcxvgOptionsBehavior.GetAlwaysShowEditor: Boolean;
|
|
begin
|
|
if FAlwaysShowEditorAssigned then
|
|
Result := inherited AlwaysShowEditor
|
|
else
|
|
Result := TcxCustomVerticalGrid(EditingControl).OptionsView.PaintStyle = psDelphi;
|
|
end;
|
|
|
|
procedure TcxvgOptionsBehavior.SetAlwaysShowEditor(Value: Boolean);
|
|
begin
|
|
FAlwaysShowEditorAssigned := True;
|
|
InternalSetAlwaysShowEditor(Value);
|
|
end;
|
|
|
|
{ TcxvgMultiRecordsOptionsBehavior }
|
|
|
|
constructor TcxvgMultiRecordsOptionsBehavior.Create(AOwner: TPersistent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
FallowChangeRecord := True;
|
|
end;
|
|
|
|
procedure TcxvgMultiRecordsOptionsBehavior.Assign(Source: TPersistent);
|
|
begin
|
|
inherited Assign(Source);
|
|
if Source is TcxvgMultiRecordsOptionsBehavior then
|
|
AllowChangeRecord := TcxvgMultiRecordsOptionsBehavior(Source).AllowChangeRecord;
|
|
end;
|
|
|
|
function TcxvgMultiRecordsOptionsBehavior.GetIncSearchItem: TcxCustomEditorRow;
|
|
var
|
|
AItem: TcxCellEdit;
|
|
begin
|
|
AItem := TcxCellEdit(inherited IncSearchItem);
|
|
if AItem <> nil then
|
|
Result := TcxCustomEditorRow(AItem.Row)
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
procedure TcxvgMultiRecordsOptionsBehavior.SetAllowChangeRecord(Value: Boolean);
|
|
begin
|
|
if FAllowChangeRecord <> Value then
|
|
begin
|
|
FAllowChangeRecord := Value;
|
|
EditingControl.LayoutChanged;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgMultiRecordsOptionsBehavior.SetIncSearchItem(
|
|
Value: TcxCustomEditorRow);
|
|
begin
|
|
if Value <> nil then
|
|
inherited IncSearchItem := TcxCustomEditorRowProperties(Value.FProperties).EditContainer
|
|
else
|
|
inherited IncSearchItem := nil;
|
|
end;
|
|
|
|
{ TcxvgMultiRecordsOptionsData }
|
|
|
|
constructor TcxvgMultiRecordsOptionsData.Create(AOwner: TPersistent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
FAppending := True;
|
|
FDeletingConfirmation := True;
|
|
FDeleting := True;
|
|
FInserting := True;
|
|
end;
|
|
|
|
procedure TcxvgMultiRecordsOptionsData.Assign(Source: TPersistent);
|
|
begin
|
|
inherited Assign(Source);
|
|
if Source is TcxvgMultiRecordsOptionsData then
|
|
with TcxvgMultiRecordsOptionsData(Source) do
|
|
begin
|
|
Self.Appending := Appending;
|
|
Self.Deleting := Deleting;
|
|
Self.DeletingConfirmation := DeletingConfirmation;
|
|
Self.Inserting := Inserting;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgMultiRecordsOptionsData.Changed;
|
|
begin
|
|
if EditingControl is TcxVirtualVerticalGrid then
|
|
TcxVirtualVerticalGrid(EditingControl).RefreshNavigators;
|
|
end;
|
|
|
|
procedure TcxvgMultiRecordsOptionsData.SetAppending(Value: Boolean);
|
|
begin
|
|
if FAppending <> Value then
|
|
begin
|
|
FAppending := Value;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgMultiRecordsOptionsData.SetDeleting(Value: Boolean);
|
|
begin
|
|
if FDeleting <> Value then
|
|
begin
|
|
FDeleting := Value;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgMultiRecordsOptionsData.SetInserting(Value: Boolean);
|
|
begin
|
|
if FInserting <> Value then
|
|
begin
|
|
FInserting := Value;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
{ TcxvgOptionsView }
|
|
|
|
constructor TcxvgOptionsView.Create(AOwner: TPersistent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
FAutoScaleBands := True;
|
|
FGridLineColor := clBtnShadow;
|
|
FBandsInterval := 2;
|
|
FRowHeaderMinWidth := 24;
|
|
FRowHeaderWidth := 100;
|
|
FRowHeight := -1;
|
|
FShowButtons := True;
|
|
FShowHeaders := True;
|
|
FGridLines := vglBoth;
|
|
FValueMinWidth := 40;
|
|
FValueWidth := 100;
|
|
end;
|
|
|
|
procedure TcxvgOptionsView.Assign(Source: TPersistent);
|
|
begin
|
|
if Source is TcxvgOptionsView then
|
|
begin
|
|
EditingControl.BeginUpdate;
|
|
try
|
|
inherited Assign(Source);
|
|
with TcxvgOptionsView(Source) do
|
|
begin
|
|
Self.PaintStyle := PaintStyle;
|
|
Self.FGridLineColor := FGridLineColor;
|
|
Self.FGridLineColorAssigned := FGridLineColorAssigned;
|
|
Self.FRowHeaderMinWidth := RowHeaderMinWidth;
|
|
Self.FRowHeight := FRowHeight;
|
|
Self.FValueMinWidth := ValueMinWidth;
|
|
Self.FValueWidth := ValueWidth;
|
|
Self.FRowHeaderWidth := RowHeaderWidth;
|
|
Self.BandsInterval := BandsInterval;
|
|
Self.CategoryExplorerStyle := CategoryExplorerStyle;
|
|
Self.ShowButtons := ShowButtons;
|
|
Self.ShowEmptyRowImage := ShowEmptyRowImage;
|
|
Self.ShowHeaders := ShowHeaders;
|
|
Self.GridLines := GridLines;
|
|
Self.AutoScaleBands := AutoScaleBands;
|
|
end;
|
|
with TcxCustomVerticalGrid(EditingControl).ViewInfo do
|
|
begin
|
|
FViewBandWidth := 0;
|
|
FViewHeaderWidth := 0;
|
|
FViewValueWidth := 0;
|
|
end;
|
|
finally
|
|
EditingControl.EndUpdate;
|
|
end;
|
|
end
|
|
else
|
|
inherited Assign(Source);
|
|
end;
|
|
|
|
procedure TcxvgOptionsView.RestoreDefaults;
|
|
begin
|
|
FGridLineColorAssigned := False;
|
|
FRowHeight := -1;
|
|
FBandsInterval := 2;
|
|
Changed;
|
|
end;
|
|
|
|
procedure TcxvgOptionsView.Changed;
|
|
begin
|
|
TcxCustomVerticalGrid(EditingControl).CheckGridModeBufferCount;
|
|
inherited Changed;
|
|
end;
|
|
|
|
procedure TcxvgOptionsView.CheckRowHeaderWidth;
|
|
begin
|
|
RowHeaderWidth := RowHeaderWidth;
|
|
end;
|
|
|
|
function TcxvgOptionsView.GetGridLineColor: TColor;
|
|
const
|
|
Colors: array[TcxvgPaintStyle] of TColor = (clBtnFace, clBtnShadow);
|
|
begin
|
|
if FGridLineColorAssigned then
|
|
Result := FGridLineColor
|
|
else
|
|
Result := Colors[FPaintStyle];
|
|
end;
|
|
|
|
procedure TcxvgOptionsView.SetAutoScaleBands(Value: Boolean);
|
|
begin
|
|
if FAutoScaleBands <> Value then
|
|
begin
|
|
FAutoScaleBands := Value;
|
|
if Value then
|
|
with TcxCustomVerticalGrid(EditingControl) do
|
|
if Controller <> nil then
|
|
Controller.Scroller.ScrollStrategy.SetTopVisibleRowIndex(0);
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgOptionsView.SetShowButtons(Value: Boolean);
|
|
begin
|
|
if FShowButtons <> Value then
|
|
begin
|
|
FShowButtons := Value;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgOptionsView.SetBandsInterval(Value: Integer);
|
|
begin
|
|
if Value < 0 then Value := 0;
|
|
if FBandsInterval <> Value then
|
|
begin
|
|
FBandsInterval := Value;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgOptionsView.SetCategoryExplorerStyle(Value: Boolean);
|
|
begin
|
|
if FCategoryExplorerStyle <> Value then
|
|
begin
|
|
FCategoryExplorerStyle := Value;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgOptionsView.SetGridLineColor(Value: TColor);
|
|
begin
|
|
FGridLineColorAssigned := True;
|
|
FGridLineColor := Value;
|
|
Changed;
|
|
end;
|
|
|
|
procedure TcxvgOptionsView.SetPaintStyle(Value: TcxvgPaintStyle);
|
|
begin
|
|
if FPaintStyle <> Value then
|
|
begin
|
|
FPaintStyle := Value;
|
|
with TcxCustomVerticalGrid(EditingControl) do
|
|
begin
|
|
if ViewInfo <> nil then RecreateViewInfo;
|
|
if Controller <> nil then Controller.UpdatePaintStyle;
|
|
CheckRowHeaderWidth;
|
|
end;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgOptionsView.SetRowHeaderMinWidth(Value: Integer);
|
|
begin
|
|
if Value < 0 then Value := 0;
|
|
if FRowHeaderMinWidth <> Value then
|
|
begin
|
|
FRowHeaderMinWidth := Value;
|
|
RowHeaderWidth := RowHeaderWidth;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgOptionsView.SetRowHeaderWidth(Value: Integer);
|
|
begin
|
|
with TcxCustomVerticalGrid(EditingControl) do
|
|
if ViewInfo <> nil then
|
|
begin
|
|
Value := Max(ViewInfo.GetViewMinHeaderWidth, Value);
|
|
if not IsLoading then ViewInfo.CheckMaxRowHeaderWidth(Value, Max(FValueMinWidth, 4));
|
|
end;
|
|
if Value < FRowHeaderMinWidth then Value := FRowHeaderMinWidth;
|
|
if FRowHeaderWidth <> Value then
|
|
begin
|
|
FRowHeaderWidth := Value;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgOptionsView.SetRowHeight(Value: Integer);
|
|
begin
|
|
if Value < -1 then Value := -1;
|
|
if FRowHeight <> Value then
|
|
begin
|
|
FRowHeight := Value;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgOptionsView.SetShowEmptyRowImage(Value: Boolean);
|
|
begin
|
|
if FShowEmptyRowImage <> Value then
|
|
begin
|
|
FShowEmptyRowImage := Value;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgOptionsView.SetShowHeaders(Value: Boolean);
|
|
begin
|
|
if FShowHeaders <> Value then
|
|
begin
|
|
FShowHeaders := Value;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgOptionsView.SetGridLines(Value: TcxvgGridLines);
|
|
begin
|
|
if FGridLines <> Value then
|
|
begin
|
|
FGridLines := Value;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgOptionsView.SetValueMinWidth(Value: Integer);
|
|
begin
|
|
Value := Max(cxvgMinValueWidth, Value);
|
|
if FValueMinWidth <> Value then
|
|
begin
|
|
FValueMinWidth := Value;
|
|
ValueWidth := ValueWidth;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgOptionsView.SetValueWidth(Value: Integer);
|
|
begin
|
|
if Value < FValueMinWidth then Value := FValueMinWidth;
|
|
if FValueWidth <> Value then
|
|
begin
|
|
FValueWidth := Value;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
{ TcxvgMultiRecordsOptionsView }
|
|
|
|
procedure TcxvgMultiRecordsOptionsView.Assign(Source: TPersistent);
|
|
begin
|
|
if Source is TcxvgMultiRecordsOptionsView then
|
|
begin
|
|
EditingControl.BeginUpdate;
|
|
try
|
|
FRecordsInterval := TcxvgMultiRecordsOptionsView(Source).RecordsInterval;
|
|
inherited Assign(Source);
|
|
finally
|
|
EditingControl.EndUpdate;
|
|
end;
|
|
end
|
|
else
|
|
inherited Assign(Source);
|
|
end;
|
|
|
|
procedure TcxvgMultiRecordsOptionsView.RestoreDefaults;
|
|
begin
|
|
FRecordsInterval := 0;
|
|
inherited RestoreDefaults;
|
|
end;
|
|
|
|
procedure TcxvgMultiRecordsOptionsView.SetRecordsInterval(Value: Integer);
|
|
begin
|
|
if Value < 0 then Value := 0;
|
|
if FRecordsInterval <> Value then
|
|
begin
|
|
FRecordsInterval := Value;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
{ TcxCustomRowProperties }
|
|
|
|
constructor TcxCustomRowProperties.Create(Collection: TCollection);
|
|
begin
|
|
if Collection <> nil then
|
|
FRow := TcxEditorPropertiesCollection(Collection).Row;
|
|
FCollection := Collection;
|
|
CreateEx(FRow);
|
|
end;
|
|
|
|
constructor TcxCustomRowProperties.CreateEx(ARow: TcxCustomRow);
|
|
begin
|
|
FRow := ARow;
|
|
inherited Create(FCollection);
|
|
end;
|
|
|
|
procedure TcxCustomRowProperties.Changed;
|
|
begin
|
|
if FCollection <> nil then
|
|
inherited Changed(True)
|
|
else
|
|
if Row.Visible then Row.Changed;
|
|
end;
|
|
|
|
function TcxCustomRowProperties.GetOwner: TPersistent;
|
|
begin
|
|
Result := FRow;
|
|
end;
|
|
|
|
{ TcxCaptionRowProperties }
|
|
|
|
constructor TcxCaptionRowProperties.CreateEx(ARow: TcxCustomRow);
|
|
begin
|
|
inherited CreateEx(ARow);
|
|
FHeaderAlignmentHorz := taLeftJustify;
|
|
FHeaderAlignmentVert := vaTop;
|
|
FImageIndex := -1;
|
|
end;
|
|
|
|
function TcxCaptionRowProperties.DefaultCaption: string;
|
|
begin
|
|
Result := '';
|
|
end;
|
|
|
|
procedure TcxCaptionRowProperties.RestoreDefaults;
|
|
begin
|
|
FIsCaptionAssigned := False;
|
|
Row.Changed;
|
|
end;
|
|
|
|
function TcxCaptionRowProperties.GetCaption: TCaption;
|
|
begin
|
|
if FIsCaptionAssigned then
|
|
Result := FCaption
|
|
else
|
|
Result := DefaultCaption;
|
|
end;
|
|
|
|
function TcxCaptionRowProperties.IsCaptionStored: Boolean;
|
|
begin
|
|
Result := FIsCaptionAssigned and (FCaption <> DefaultCaption);
|
|
end;
|
|
|
|
procedure TcxCaptionRowProperties.SetCaption(
|
|
const Value: TCaption);
|
|
begin
|
|
if FIsCaptionAssigned and (Value = FCaption) then Exit;
|
|
FCaption := Value;
|
|
FIsCaptionAssigned := True;
|
|
Changed;
|
|
end;
|
|
|
|
procedure TcxCaptionRowProperties.SetHeaderAlignmentHorz(
|
|
const Value: TAlignment);
|
|
begin
|
|
if HeaderAlignmentHorz <> Value then
|
|
begin
|
|
FHeaderAlignmentHorz := Value;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCaptionRowProperties.SetHeaderAlignmentVert(
|
|
const Value: TcxAlignmentVert);
|
|
begin
|
|
if HeaderAlignmentVert <> Value then
|
|
begin
|
|
FHeaderAlignmentVert := Value;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCaptionRowProperties.SetImageIndex(
|
|
const Value: TImageIndex);
|
|
begin
|
|
if FImageIndex <> Value then
|
|
begin
|
|
FImageIndex := Value;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCaptionRowProperties.Assign(Source: TPersistent);
|
|
begin
|
|
if Source is TcxCaptionRowProperties then
|
|
begin
|
|
Row.OwnerRows.BeginUpdate;
|
|
try
|
|
with TcxCaptionRowProperties(Source) do
|
|
begin
|
|
Self.FCaption := FCaption;
|
|
Self.FIsCaptionAssigned := FIsCaptionAssigned;
|
|
Self.FImageIndex := FImageIndex;
|
|
Self.FHeaderAlignmentHorz := FHeaderAlignmentHorz;
|
|
Self.FHeaderAlignmentVert := FHeaderAlignmentVert;
|
|
Self.FHint := FHint;
|
|
end;
|
|
finally
|
|
Row.OwnerRows.EndUpdate;
|
|
end;
|
|
end
|
|
else
|
|
inherited Assign(Source);
|
|
end;
|
|
|
|
{ TcxRowOptions }
|
|
|
|
constructor TcxRowOptions.Create(ARow: TcxCustomRow);
|
|
begin
|
|
FRow := ARow;
|
|
FCanAutoHeight := True;
|
|
FCanMovedToCustomizationForm := True;
|
|
FCanResized := True;
|
|
FFocusing := True;
|
|
FMoving := True;
|
|
FShowExpandButton := True;
|
|
FShowInCustomizationForm := True;
|
|
FTabStop := True;
|
|
end;
|
|
|
|
procedure TcxRowOptions.Assign(Source: TPersistent);
|
|
begin
|
|
if Source is TcxRowOptions then
|
|
with TcxRowOptions(Source) do
|
|
begin
|
|
Self.FCanAutoHeight := CanAutoHeight;
|
|
Self.FCanMovedToCustomizationForm := CanMovedToCustomizationForm;
|
|
Self.FCanResized := CanResized;
|
|
Self.FFocusing := Focusing;
|
|
Self.FMoving := Moving;
|
|
Self.FShowExpandButton := ShowExpandButton;
|
|
Self.FShowInCustomizationForm := ShowInCustomizationForm;
|
|
Self.FTabStop := TabStop;
|
|
Self.Changed;
|
|
end
|
|
else
|
|
inherited Assign(Source);
|
|
end;
|
|
|
|
procedure TcxRowOptions.RestoreDefaults;
|
|
begin
|
|
FCanAutoHeight := True;
|
|
FCanMovedToCustomizationForm := True;
|
|
FCanResized := True;
|
|
FFocusing := True;
|
|
FMoving := True;
|
|
FShowExpandButton := True;
|
|
FShowInCustomizationForm := True;
|
|
FTabStop := True;
|
|
Changed;
|
|
end;
|
|
|
|
procedure TcxRowOptions.Changed;
|
|
begin
|
|
FRow.Changed;
|
|
end;
|
|
|
|
procedure TcxRowOptions.SetCanAutoHeight(Value: Boolean);
|
|
begin
|
|
if FCanAutoHeight <> Value then
|
|
begin
|
|
FCanAutoHeight := Value;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxRowOptions.SetFocusing(Value: Boolean);
|
|
begin
|
|
if FFocusing <> Value then
|
|
begin
|
|
FFocusing := Value;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxRowOptions.SetShowExpandButton(Value: Boolean);
|
|
begin
|
|
if FShowExpandButton <> Value then
|
|
begin
|
|
FShowExpandButton := Value;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxRowOptions.SetShowInCustomizationForm(Value: Boolean);
|
|
begin
|
|
if FShowInCustomizationForm <> Value then
|
|
begin
|
|
FShowInCustomizationForm := Value;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
{ TcxRowList }
|
|
|
|
constructor TcxRowList.Create(AOwner: TcxCustomRow);
|
|
begin
|
|
inherited Create;
|
|
FOwner := AOwner;
|
|
end;
|
|
|
|
procedure TcxRowList.Notify(Ptr: Pointer; Action: TListNotification);
|
|
begin
|
|
if (Action in [lnAdded, lnDeleted]) and not (csDestroying in Owner.ComponentState) then
|
|
UpdateIndexes;
|
|
end;
|
|
|
|
procedure TcxRowList.UpdateIndexes;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to Count - 1 do
|
|
TcxCustomRow(Items[I]).FIndex := I;
|
|
end;
|
|
|
|
{ TcxCustomRow }
|
|
|
|
constructor TcxCustomRow.Create(AOwner: TComponent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
FIndex := -1;
|
|
FExpanded := True;
|
|
FVisible := True;
|
|
FHeight := -1;
|
|
FStyles := GetStylesClass.Create(Self);
|
|
FProperties := GetPropertiesClass.CreateEx(Self);
|
|
FOptions := GetOptionsClass.Create(Self);
|
|
FVisibleIndex := -1;
|
|
end;
|
|
|
|
destructor TcxCustomRow.Destroy;
|
|
begin
|
|
VerticalGrid.RemoveRowFromVerticalGrid(Self);
|
|
FreeAndNil(FViewInfo);
|
|
FreeAndNil(FStyles);
|
|
FreeAndNil(FProperties);
|
|
FreeAndNil(FOptions);
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TcxCustomRow.Assign(Source: TPersistent);
|
|
begin
|
|
if Source is TcxCustomRow then
|
|
with TcxCustomRow(Source) do
|
|
begin
|
|
Self.FHeight := FHeight; //need a direct assign
|
|
Self.FVisible := FVisible;
|
|
Self.FExpanded := FExpanded;
|
|
Self.FProperties.Assign(FProperties);
|
|
Self.Styles.Assign(Styles);
|
|
end
|
|
else
|
|
inherited Assign(Source);
|
|
end;
|
|
|
|
function TcxCustomRow.GetParentComponent: TComponent;
|
|
begin
|
|
if FParent = nil then Result := VerticalGrid else Result := FParent;
|
|
end;
|
|
|
|
function TcxCustomRow.HasParent: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
procedure TcxCustomRow.Collapse(ARecurse: Boolean);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if HasChildren then
|
|
begin
|
|
OwnerRows.BeginUpdate;
|
|
try
|
|
FExpanded := False;
|
|
if ARecurse then
|
|
for I := 0 to Count - 1 do
|
|
Rows[I].Collapse(ARecurse);
|
|
finally
|
|
OwnerRows.EndUpdate;
|
|
end
|
|
end
|
|
else FExpanded := False;
|
|
end;
|
|
|
|
procedure TcxCustomRow.Expand(ARecurse: Boolean);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if HasChildren then
|
|
begin
|
|
OwnerRows.BeginUpdate;
|
|
try
|
|
FExpanded := True;
|
|
if ARecurse then
|
|
for I := 0 to Count - 1 do
|
|
Rows[I].Expand(ARecurse);
|
|
finally
|
|
OwnerRows.EndUpdate;
|
|
end;
|
|
end
|
|
else FExpanded := True;
|
|
end;
|
|
|
|
function TcxCustomRow.GetFirstVisibleChild: TcxCustomRow;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := nil;
|
|
for I := 0 to Count - 1 do
|
|
if Rows[I].Visible then
|
|
begin
|
|
Result := Rows[I];
|
|
break;
|
|
end;
|
|
end;
|
|
|
|
function TcxCustomRow.GetLastVisibleChild: TcxCustomRow;
|
|
var
|
|
I: Integer;
|
|
ARow: TcxCustomRow;
|
|
begin
|
|
Result := nil;
|
|
for I := Count - 1 downto 0 do
|
|
begin
|
|
ARow := Rows[I];
|
|
if ARow.Visible then
|
|
begin
|
|
if ARow.Expanded then ARow := ARow.GetLastVisibleChild;
|
|
if ARow <> nil then Result := ARow else Result := Rows[I];
|
|
break;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TcxCustomRow.HasChildren: Boolean;
|
|
begin
|
|
Result := Count > 0;
|
|
end;
|
|
|
|
function TcxCustomRow.HasVisibleChildren: Boolean;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := False;
|
|
for I := 0 to Count - 1 do
|
|
if Rows[I].Visible then
|
|
begin
|
|
Result := True;
|
|
break;
|
|
end;
|
|
end;
|
|
|
|
function TcxCustomRow.IndexOf(ARow: TcxCustomRow): Integer;
|
|
begin
|
|
Result := -1;
|
|
if FRows <> nil then Result := FRows.IndexOf(ARow);
|
|
end;
|
|
|
|
function TcxCustomRow.IsChild(ARow: TcxCustomRow): Boolean;
|
|
begin
|
|
Result := (ARow <> nil) and ARow.IsParent(Self)
|
|
end;
|
|
|
|
function TcxCustomRow.IsFirst: Boolean;
|
|
begin
|
|
Result := Index = 0;
|
|
end;
|
|
|
|
function TcxCustomRow.IsFirstVisible: Boolean;
|
|
begin
|
|
Result := Self = FParent.GetFirstVisibleChild;
|
|
end;
|
|
|
|
function TcxCustomRow.IsLast: Boolean;
|
|
begin
|
|
Result := Index = FParent.Count - 1;
|
|
end;
|
|
|
|
function TcxCustomRow.IsLastVisible: Boolean;
|
|
var
|
|
I: Integer;
|
|
ARow: TcxCustomRow;
|
|
begin
|
|
Result := False;
|
|
with FParent do
|
|
for I := Count - 1 downto 0 do
|
|
begin
|
|
ARow := Rows[I];
|
|
if ARow.Visible then
|
|
if ARow = Self then
|
|
begin
|
|
Result := True;
|
|
break;
|
|
end
|
|
else
|
|
break
|
|
end;
|
|
end;
|
|
|
|
function TcxCustomRow.IsRootLevel: Boolean;
|
|
begin
|
|
Result := FParent = VerticalGrid.RootRow;
|
|
end;
|
|
|
|
function TcxCustomRow.IsParent(ARow: TcxCustomRow): Boolean;
|
|
begin
|
|
Result := False;
|
|
while ARow <> nil do
|
|
begin
|
|
if ARow.FParent = Self then
|
|
begin
|
|
Result := True;
|
|
break;
|
|
end;
|
|
ARow := ARow.FParent;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomRow.MakeVisible;
|
|
begin
|
|
VerticalGrid.Controller.MakeRowVisible(Self);
|
|
end;
|
|
|
|
procedure TcxCustomRow.RestoreDefaults;
|
|
begin
|
|
FHeight := -1;
|
|
Options.RestoreDefaults; // indirect call the row's changed method
|
|
end;
|
|
|
|
function TcxCustomRow.GetObjectName: string;
|
|
begin
|
|
if VerticalGrid.FNewLoadMode then
|
|
begin
|
|
Result := Name;
|
|
if Result = '' then
|
|
Result := IntToStr(FID);
|
|
end
|
|
else
|
|
Result := IntToStr(FID);
|
|
end;
|
|
|
|
procedure TcxCustomRow.GetPropertyValue(const AName: string; var AValue: Variant);
|
|
begin
|
|
if AName = 'Visible' then
|
|
AValue := Visible
|
|
else
|
|
if AName = 'Height' then
|
|
AValue := Height
|
|
else
|
|
if AName = 'Expanded' then
|
|
AValue := Expanded
|
|
else
|
|
if AName = 'AParentID' then
|
|
begin
|
|
if VerticalGrid.FNewLoadMode then
|
|
AValue := FParent.GetObjectName
|
|
else
|
|
AValue := FParent.ID;
|
|
end
|
|
else
|
|
if AName = 'Index' then
|
|
AValue := Index
|
|
else
|
|
AValue := Null;
|
|
end;
|
|
|
|
function TcxCustomRow.GetStoredProperties(AProperties: TStrings): Boolean;
|
|
begin
|
|
with AProperties do
|
|
begin
|
|
Add('AParentID');
|
|
Add('Index');
|
|
Add('Visible');
|
|
Add('Height');
|
|
Add('Expanded');
|
|
end;
|
|
Result := True;
|
|
end;
|
|
|
|
procedure TcxCustomRow.SetPropertyValue(const AName: string; const AValue: Variant);
|
|
begin
|
|
if AName = 'Visible' then
|
|
Visible := AValue
|
|
else
|
|
if AName = 'Height' then
|
|
Height := AValue
|
|
else
|
|
if AName = 'Expanded' then
|
|
Expanded := AValue
|
|
else
|
|
if AName = 'AParentID' then
|
|
begin
|
|
if VerticalGrid.FNewLoadMode then
|
|
FLoadingParent := AValue
|
|
else
|
|
Parent := OwnerRows.FindRowByID(AValue);
|
|
end
|
|
else
|
|
if AName = 'Index' then
|
|
if VerticalGrid.FNewLoadMode then
|
|
FLoadingIndex := AValue
|
|
else
|
|
Index := AValue;
|
|
end;
|
|
|
|
procedure TcxCustomRow.GetChildren(Proc: TGetChildProc; Root: TComponent);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to Count - 1 do Proc(Rows[I])
|
|
end;
|
|
|
|
procedure TcxCustomRow.SetName(const NewName: TComponentName);
|
|
begin
|
|
inherited SetName(NewName);
|
|
if not (csLoading in ComponentState) then
|
|
Changed;
|
|
end;
|
|
|
|
procedure TcxCustomRow.SetParentComponent(Value: TComponent);
|
|
begin
|
|
if FParent <> nil then FParent.Remove(Self);
|
|
if Value <> nil then
|
|
if Value is TcxCustomVerticalGrid then
|
|
TcxCustomVerticalGrid(Value).FRootRow.Add(Self)
|
|
else
|
|
if Value is TcxCustomRow then
|
|
TcxCustomRow(Value).Add(Self);
|
|
end;
|
|
|
|
procedure TcxCustomRow.Add(ARow: TcxCustomRow);
|
|
begin
|
|
Insert(GetCount, ARow);
|
|
end;
|
|
|
|
function TcxCustomRow.CanFocus: Boolean;
|
|
begin
|
|
Result := Options.Focusing;
|
|
end;
|
|
|
|
procedure TcxCustomRow.Changed(ARebuild: Boolean = False);
|
|
begin
|
|
if OwnerRows <> nil then
|
|
OwnerRows.Changed(ARebuild);
|
|
end;
|
|
|
|
procedure TcxCustomRow.Delete(AIndex: Integer);
|
|
var
|
|
ARow: TcxCustomRow;
|
|
begin
|
|
if (AIndex < 0) or (FRows = nil) or (AIndex >= GetCount) then
|
|
cxVerticalGridError(cxSvgIndexError);
|
|
ARow := FRows[AIndex];
|
|
FRows.Delete(AIndex);
|
|
ARow.FParent := nil;
|
|
ResetOwnerCount;
|
|
end;
|
|
|
|
function TcxCustomRow.GetDefaultHeight: Integer;
|
|
begin
|
|
with VerticalGrid do
|
|
Result := Max(OptionsView.RowHeight,
|
|
cxScreenCanvas.FontHeight(Styles.GetHeaderParams(Self).Font) + cxTextOffset);
|
|
end;
|
|
|
|
function TcxCustomRow.GetEditContainer(ACellIndex: Integer): TcxCellEdit;
|
|
begin
|
|
Result := nil;
|
|
end;
|
|
|
|
function TcxCustomRow.GetEditContainerCount: Integer;
|
|
begin
|
|
Result := 0;
|
|
end;
|
|
|
|
function TcxCustomRow.GetPropertiesClass: TcxRowPropertiesClass;
|
|
begin
|
|
Result := TcxCaptionRowProperties;
|
|
end;
|
|
|
|
function TcxCustomRow.GetRealHeight: Integer;
|
|
begin
|
|
Result := Max(FHeight, GetDefaultHeight);
|
|
end;
|
|
|
|
function TcxCustomRow.GetOptionsClass: TcxRowOptionsClass;
|
|
begin
|
|
Result := TcxRowOptions;
|
|
end;
|
|
|
|
function TcxCustomRow.GetStylesClass: TcxvgCustomRowStylesClass;
|
|
begin
|
|
Result := TcxvgCustomRowStyles;
|
|
end;
|
|
|
|
procedure TcxCustomRow.Insert(AIndex: Integer; ARow: TcxCustomRow);
|
|
begin
|
|
if FRows = nil then
|
|
FRows := TcxRowList.Create(Self);
|
|
ARow.FParent := Self;
|
|
ARow.SetVerticalGrid(VerticalGrid);
|
|
FRows.Insert(AIndex, ARow);
|
|
ResetOwnerCount;
|
|
end;
|
|
|
|
function TcxCustomRow.IsHeightAssigned: Boolean;
|
|
begin
|
|
Result := FHeight >= 0;
|
|
end;
|
|
|
|
procedure TcxCustomRow.Remove(ARow: TcxCustomRow);
|
|
begin
|
|
Delete(IndexOf(ARow));
|
|
end;
|
|
|
|
procedure TcxCustomRow.RemoveAll;
|
|
begin
|
|
while Count > 0 do Rows[0].Free;
|
|
FreeAndNil(FRows);
|
|
ResetOwnerCount;
|
|
end;
|
|
|
|
procedure TcxCustomRow.RemoveChildren;
|
|
begin
|
|
if (FParent <> nil) then
|
|
begin
|
|
FParent.Remove(Self);
|
|
FParent := nil;
|
|
end;
|
|
RemoveAll;
|
|
end;
|
|
|
|
procedure TcxCustomRow.ResetOwnerCount;
|
|
begin
|
|
OwnerRows.FCount := -1;
|
|
end;
|
|
|
|
procedure TcxCustomRow.SetVerticalGrid(Value: TcxCustomVerticalGrid);
|
|
begin
|
|
if FVerticalGrid <> Value then
|
|
begin
|
|
FVerticalGrid := Value;
|
|
if Value <> nil then
|
|
FID := Value.Rows.GetNextID;
|
|
end;
|
|
end;
|
|
|
|
function TcxCustomRow.GetAbsoluteIndex: Integer;
|
|
begin
|
|
Result := OwnerRows.IndexOf(Self);
|
|
end;
|
|
|
|
function TcxCustomRow.GetCount: Integer;
|
|
begin
|
|
if FRows = nil then Result := 0 else Result := FRows.Count;
|
|
end;
|
|
|
|
function TcxCustomRow.GetFocused: Boolean;
|
|
begin
|
|
Result := VerticalGrid.FocusedRow = Self;
|
|
end;
|
|
|
|
function TcxCustomRow.GetLevel: Integer;
|
|
var
|
|
P: TcxCustomRow;
|
|
begin
|
|
Result := 0;
|
|
P := FParent;
|
|
while (P <> nil) and (P <> VerticalGrid.RootRow) do
|
|
begin
|
|
P := P.FParent;
|
|
Inc(Result);
|
|
end;
|
|
end;
|
|
|
|
function TcxCustomRow.GetOwnerRows: TcxVerticalGridRows;
|
|
begin
|
|
Result := FVerticalGrid.Rows;
|
|
end;
|
|
|
|
function TcxCustomRow.GetParent: TcxCustomRow;
|
|
begin
|
|
if FParent = FVerticalGrid.FRootRow then
|
|
Result := nil
|
|
else
|
|
Result := FParent;
|
|
end;
|
|
|
|
function TcxCustomRow.GetRow(Index: Integer): TcxCustomRow;
|
|
begin
|
|
if FRows = nil then
|
|
cxVerticalGridError(cxSvgIndexError);
|
|
Result := FRows[Index];
|
|
end;
|
|
|
|
function TcxCustomRow.GetViewInfo: TcxCustomRowViewInfo;
|
|
begin
|
|
if FViewInfo = nil then FViewInfo := CreateViewInfo;
|
|
Result := FViewInfo;
|
|
end;
|
|
|
|
procedure TcxCustomRow.SetExpanded(Value: Boolean);
|
|
begin
|
|
if FExpanded <> Value then
|
|
begin
|
|
FExpanded := Value;
|
|
Changed(HasChildren);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomRow.SetFocused(Value: Boolean);
|
|
begin
|
|
if Value <> Focused then
|
|
if Value then
|
|
VerticalGrid.FocusedRow := Self
|
|
else
|
|
VerticalGrid.FocusedRow := nil;
|
|
end;
|
|
|
|
procedure TcxCustomRow.SetHeight(Value: Integer);
|
|
begin
|
|
if Value < -1 then Value := -1;
|
|
if FHeight <> Value then
|
|
begin
|
|
FHeight := Value;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomRow.SetIndex(Value: Integer);
|
|
var
|
|
AIndex: Integer;
|
|
begin
|
|
if (FParent <> nil) and (Value >= 0) and (Value < FParent.GetCount) then
|
|
begin
|
|
AIndex := Index;
|
|
if Value <> AIndex then
|
|
begin
|
|
FParent.FRows.Move(AIndex, Value);
|
|
FParent.FRows.UpdateIndexes;
|
|
Changed(True);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomRow.SetOptions(Value: TcxRowOptions);
|
|
begin
|
|
FOptions.Assign(Value);
|
|
end;
|
|
|
|
procedure TcxCustomRow.SetParent(Value: TcxCustomRow);
|
|
begin
|
|
if Value = Self then Exit;
|
|
if Value = nil then
|
|
Value := FVerticalGrid.FRootRow;
|
|
if FParent <> Value then
|
|
begin
|
|
if FParent <> nil then
|
|
FParent.Remove(Self);
|
|
FParent := Value;
|
|
FParent.Add(Self);
|
|
Changed(True);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomRow.SetVisible(Value: Boolean);
|
|
begin
|
|
if FVisible <> Value then
|
|
begin
|
|
FVisible := Value;
|
|
Changed(True);
|
|
end;
|
|
end;
|
|
|
|
{ TcxCategoryRow }
|
|
|
|
function TcxCategoryRow.CreateHeaderInfo: TcxCustomRowHeaderInfo;
|
|
begin
|
|
Result := TcxCategoryRowHeaderInfo.Create(Self);
|
|
end;
|
|
|
|
function TcxCategoryRow.CreateViewInfo: TcxCustomRowViewInfo;
|
|
begin
|
|
Result := TcxCategoryRowViewInfo.Create(Self);
|
|
end;
|
|
|
|
function TcxCategoryRow.GetStoredProperties(AProperties: TStrings): Boolean;
|
|
begin
|
|
AProperties.Add('Caption');
|
|
Result := inherited GetStoredProperties(AProperties);
|
|
end;
|
|
|
|
procedure TcxCategoryRow.GetPropertyValue(const AName: string;
|
|
var AValue: Variant);
|
|
begin
|
|
if AName = 'Caption' then
|
|
AValue := Properties.Caption
|
|
else
|
|
inherited GetPropertyValue(AName, AValue);
|
|
end;
|
|
|
|
procedure TcxCategoryRow.SetPropertyValue(const AName: string;
|
|
const AValue: Variant);
|
|
begin
|
|
if (AName = 'Caption') and not VarIsEmpty(AValue) then
|
|
Properties.Caption := AValue
|
|
else
|
|
inherited SetPropertyValue(AName, AValue);
|
|
end;
|
|
|
|
function TcxCategoryRow.GetDefaultHeight: Integer;
|
|
begin
|
|
with VerticalGrid do
|
|
begin
|
|
Result := Max(OptionsView.RowHeight,
|
|
cxScreenCanvas.FontHeight(Styles.GetCategoryParams(Self).Font) + cxTextOffset * 2);
|
|
if ViewInfo.UseCategoryExplorerStyle and (LookAndFeel.SkinPainter = nil) then
|
|
Result := Max(Result, ViewInfo.ExplorerButtonSize.cy + 2);
|
|
end;
|
|
end;
|
|
|
|
function TcxCategoryRow.GetStylesClass: TcxvgCustomRowStylesClass;
|
|
begin
|
|
Result := TcxCategoryRowStyles;
|
|
end;
|
|
|
|
function TcxCategoryRow.GetProperties: TcxCaptionRowProperties;
|
|
begin
|
|
Result := TcxCaptionRowProperties(FProperties);
|
|
end;
|
|
|
|
function TcxCategoryRow.GetStyles: TcxCategoryRowStyles;
|
|
begin
|
|
Result := TcxCategoryRowStyles(FStyles);
|
|
end;
|
|
|
|
procedure TcxCategoryRow.SetProperties(Value: TcxCaptionRowProperties);
|
|
begin
|
|
FProperties.Assign(Value);
|
|
end;
|
|
|
|
procedure TcxCategoryRow.SetStyles(Value: TcxCategoryRowStyles);
|
|
begin
|
|
FStyles.Assign(Value);
|
|
Changed;
|
|
end;
|
|
|
|
{ TcxCellEdit }
|
|
|
|
constructor TcxCellEdit.Create(AOwner: TComponent);
|
|
begin
|
|
FRow := TcxCustomRow(AOwner);
|
|
inherited Create(AOwner);
|
|
end;
|
|
|
|
procedure TcxCellEdit.Calculate(ACellViewInfo: TcxRowValueInfo);
|
|
begin
|
|
FCalculating := True;
|
|
try
|
|
InitEditViewInfo(ACellViewInfo);
|
|
CalculateEditViewInfo(ACellViewInfo.CellValue, ACellViewInfo, cxInvalidPoint);
|
|
finally
|
|
FCalculating := False;
|
|
end;
|
|
end;
|
|
|
|
function TcxCellEdit.CanEdit: Boolean;
|
|
begin
|
|
Result := CanFocus and
|
|
TcxCustomVerticalGrid(EditingControl).OptionsData.Editing and
|
|
TcxEditorRowPropertiesOptions(Options).Editing and
|
|
(dceoShowEdit in DataController.EditOperations);
|
|
end;
|
|
|
|
function TcxCellEdit.CanFocus: Boolean;
|
|
begin
|
|
Result := Row.Options.Focusing and inherited CanFocus;
|
|
end;
|
|
|
|
function TcxCellEdit.CanInitEditing: Boolean;
|
|
begin
|
|
with TcxCustomVerticalGrid(EditingControl) do
|
|
begin
|
|
Result := inherited CanInitEditing and ((DragAndDropState = ddsNone) or
|
|
((DragMode <> dmAutomatic) or not HitTest.HitAtValue));
|
|
end;
|
|
end;
|
|
|
|
function TcxCellEdit.CanTabStop: Boolean;
|
|
begin
|
|
Result := Row.Options.TabStop and inherited CanTabStop;
|
|
end;
|
|
|
|
procedure TcxCellEdit.DoGetDisplayText(ARecordIndex: Integer; var AText: string);
|
|
begin
|
|
EditRowProperties.DoGetDisplayTextEvent(ARecordIndex, AText);
|
|
end;
|
|
|
|
function TcxCellEdit.DoGetPropertiesFromEvent(AEvent: TcxGetEditPropertiesEvent;
|
|
AData: Pointer; AProperties: TcxCustomEditProperties): TcxCustomEditProperties;
|
|
begin
|
|
Result := AProperties;
|
|
if Assigned(AEvent) then
|
|
begin
|
|
AEvent(FEditRowProperties, AData, Result);
|
|
if Result = nil then
|
|
Result := AProperties;
|
|
end;
|
|
InitProperties(Result);
|
|
end;
|
|
|
|
function TcxCellEdit.GetCurrentValue: Variant;
|
|
begin
|
|
with DataController do
|
|
if RowCount = 0 then
|
|
Value := Null
|
|
else
|
|
Result := Values[FilteredRecordIndex[FocusedRowIndex], ItemIndex];
|
|
end;
|
|
|
|
function TcxCellEdit.GetDataBindingClass: TcxItemDataBindingClass;
|
|
begin
|
|
Result := TcxItemDataBinding;
|
|
end;
|
|
|
|
function TcxCellEdit.GetDisplayValue(AProperties: TcxCustomEditProperties;
|
|
ARecordIndex: Integer): Variant;
|
|
begin
|
|
with DataController do
|
|
begin
|
|
if RowCount = 0 then
|
|
Result := ''
|
|
else
|
|
if AProperties.GetEditValueSource(False) = evsValue then
|
|
Result := GetValue(FilteredRecordIndex[ARecordIndex], ItemIndex)
|
|
else
|
|
Result := GetDisplayText(FilteredRecordIndex[ARecordIndex], ItemIndex);
|
|
end;
|
|
end;
|
|
|
|
function TcxCellEdit.GetEditValue: Variant;
|
|
begin
|
|
if Editing then
|
|
begin
|
|
if DataController.RowCount = 0 then
|
|
Result := Null
|
|
else
|
|
Result := DataController.GetEditValue(ItemIndex, EditValueSource);
|
|
end
|
|
else
|
|
Result := Unassigned;
|
|
end;
|
|
|
|
function TcxCellEdit.GetOptionsClass: TcxCustomEditContainerItemOptionsClass;
|
|
begin
|
|
if Row is TcxCustomMultiEditorRow then
|
|
Result := TcxMultiEditorRowPropertiesOptions
|
|
else
|
|
Result := TcxEditorRowPropertiesOptions;
|
|
end;
|
|
|
|
function TcxCellEdit.GetValue(ARecordIndex: Integer): Variant;
|
|
begin
|
|
with DataController do
|
|
if RowCount = 0 then
|
|
Value := Null
|
|
else
|
|
Result := Values[FilteredRecordIndex[ARecordIndex], ItemIndex];
|
|
end;
|
|
|
|
function TcxCellEdit.GetValueCount: Integer;
|
|
begin
|
|
Result := DataController.RowCount;
|
|
end;
|
|
|
|
function TcxCellEdit.HasDataTextHandler: Boolean;
|
|
begin
|
|
Result := Assigned(EditRowProperties.FOnGetDisplayText);
|
|
end;
|
|
|
|
procedure TcxCellEdit.PropertiesChanged;
|
|
begin
|
|
if (ViewInfo <> nil) and not FCalculating then
|
|
begin
|
|
ViewInfo.ValuesInfo.Trunc(0);
|
|
inherited PropertiesChanged;
|
|
if not TcxCustomVerticalGrid(EditingControl).IsLocked then
|
|
begin
|
|
ViewInfo.ValidateViewInfo;
|
|
ViewInfo.CalcValuesInfo;
|
|
end;
|
|
end
|
|
else
|
|
inherited PropertiesChanged;
|
|
end;
|
|
|
|
procedure TcxCellEdit.SetCurrentValue(const Value: Variant);
|
|
begin
|
|
with DataController do
|
|
if RowCount > 0 then
|
|
Values[FilteredRecordIndex[FocusedRowIndex], ItemIndex] := Value;
|
|
end;
|
|
|
|
procedure TcxCellEdit.SetValue(ARecordIndex: Integer; const Value: Variant);
|
|
begin
|
|
with DataController do
|
|
if RowCount > 0 then
|
|
Values[FilteredRecordIndex[ARecordIndex], ItemIndex] := Value;
|
|
end;
|
|
|
|
function TcxCellEdit.GetViewInfo: TcxCustomRowViewInfo;
|
|
begin
|
|
Result := FRow.ViewInfo;
|
|
end;
|
|
|
|
{ TcxCustomEditorRowProperties }
|
|
|
|
constructor TcxCustomEditorRowProperties.CreateEx(ARow: TcxCustomRow);
|
|
begin
|
|
//for the correct work with a collection
|
|
FEditContainer := GetInplaceEditContainerClass.Create(ARow);
|
|
FEditContainer.FEditRowProperties := Self;
|
|
inherited CreateEx(ARow);
|
|
end;
|
|
|
|
destructor TcxCustomEditorRowProperties.Destroy;
|
|
begin
|
|
FreeAndNil(FEditContainer);
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TcxCustomEditorRowProperties.Assign(Source: TPersistent);
|
|
begin
|
|
if Source is TcxCustomEditorRowProperties then
|
|
FEditContainer.Assign(TcxCustomEditorRowProperties(Source).FEditContainer);
|
|
inherited Assign(Source);
|
|
end;
|
|
|
|
function TcxCustomEditorRowProperties.GetInplaceEditContainerClass: TcxCellEditClass;
|
|
begin
|
|
Result := TcxCellEdit;
|
|
end;
|
|
|
|
procedure TcxCustomEditorRowProperties.DoGetDisplayTextEvent(
|
|
ARecordIndex: Integer; var Text: string);
|
|
begin
|
|
if Assigned(FOnGetDisplayText) then
|
|
FOnGetDisplayText(Self, ARecordIndex, Text);
|
|
end;
|
|
|
|
function TcxCustomEditorRowProperties.GetDataBinding: TcxItemDataBinding;
|
|
begin
|
|
Result := TcxItemDataBinding(EditContainer.FDataBinding);
|
|
end;
|
|
|
|
function TcxCustomEditorRowProperties.GetDisplayEditProperty(
|
|
Index: Integer): TcxCustomEditProperties;
|
|
begin
|
|
Result := FEditContainer.DoGetEditProperties(Pointer(Index));
|
|
end;
|
|
|
|
function TcxCustomEditorRowProperties.GetDisplayText(Index: Integer): string;
|
|
begin
|
|
with EditContainer do
|
|
Result := GetDisplayValue(DisplayEditProperties[Index], Index);
|
|
DoGetDisplayTextEvent(Index, Result);
|
|
end;
|
|
|
|
function TcxCustomEditorRowProperties.GetEditViewData: TcxCustomEditViewData;
|
|
begin
|
|
Result := EditContainer.EditViewData;
|
|
end;
|
|
|
|
function TcxCustomEditorRowProperties.GetEditProperties: TcxCustomEditProperties;
|
|
begin
|
|
Result := FEditContainer.Properties;
|
|
end;
|
|
|
|
function TcxCustomEditorRowProperties.GetEditPropertiesClass: TcxCustomEditPropertiesClass;
|
|
begin
|
|
Result := FEditContainer.PropertiesClass;
|
|
end;
|
|
|
|
function TcxCustomEditorRowProperties.GetEditPropertiesClassName: string;
|
|
begin
|
|
Result := FEditContainer.PropertiesClassName;
|
|
end;
|
|
|
|
function TcxCustomEditorRowProperties.GetIEditorPropertiesContainer: IcxEditorPropertiesContainer;
|
|
begin
|
|
Supports(TObject(FEditContainer), IcxEditorPropertiesContainer, Result);
|
|
end;
|
|
|
|
function TcxCustomEditorRowProperties.GetItemIndex: Integer;
|
|
begin
|
|
Result := FEditContainer.ItemIndex;
|
|
end;
|
|
|
|
function TcxCustomEditorRowProperties.GetItemLink: TObject;
|
|
begin
|
|
Result := FEditContainer;
|
|
end;
|
|
|
|
function TcxCustomEditorRowProperties.GetOptions: TcxEditorRowPropertiesOptions;
|
|
begin
|
|
Result := TcxEditorRowPropertiesOptions(FEditContainer.Options);
|
|
end;
|
|
|
|
function TcxCustomEditorRowProperties.GetRepositoryItem: TcxEditRepositoryItem;
|
|
begin
|
|
Result := FEditContainer.RepositoryItem;
|
|
end;
|
|
|
|
function TcxCustomEditorRowProperties.GetValue: Variant;
|
|
begin
|
|
Result := FEditContainer.Value;
|
|
end;
|
|
|
|
function TcxCustomEditorRowProperties.GetValueByIndex(Index: Integer): Variant;
|
|
begin
|
|
Result := FEditContainer.Values[Index];
|
|
end;
|
|
|
|
procedure TcxCustomEditorRowProperties.SetDataBinding(
|
|
Value: TcxItemDataBinding);
|
|
begin
|
|
FEditContainer.FDataBinding.Assign(Value);
|
|
end;
|
|
|
|
procedure TcxCustomEditorRowProperties.SetEditProperties(
|
|
Value: TcxCustomEditProperties);
|
|
begin
|
|
FEditContainer.Properties := Value;
|
|
end;
|
|
|
|
procedure TcxCustomEditorRowProperties.SetEditPropertiesClass(
|
|
Value: TcxCustomEditPropertiesClass);
|
|
begin
|
|
FEditContainer.PropertiesClass := Value;
|
|
end;
|
|
|
|
procedure TcxCustomEditorRowProperties.SetEditPropertiesClassName(
|
|
const Value: string);
|
|
begin
|
|
FEditContainer.PropertiesClassName := Value;
|
|
end;
|
|
|
|
procedure TcxCustomEditorRowProperties.SetOptions(
|
|
Value: TcxEditorRowPropertiesOptions);
|
|
begin
|
|
FEditContainer.Options.Assign(Value);
|
|
end;
|
|
|
|
procedure TcxCustomEditorRowProperties.SetRepositoryItem(
|
|
Value: TcxEditRepositoryItem);
|
|
begin
|
|
FEditContainer.RepositoryItem := Value;
|
|
end;
|
|
|
|
procedure TcxCustomEditorRowProperties.SetValue(const Value: Variant);
|
|
begin
|
|
with FEditContainer.DataController do
|
|
begin
|
|
if (RowCount = 0) or (FocusedRowIndex < 0) then Exit;
|
|
if dceEdit in EditState then
|
|
SetEditValue(FEditContainer.ItemIndex, Value, evsValue)
|
|
else
|
|
Values[FilteredRecordIndex[FocusedRowIndex], FEditContainer.ItemIndex] := Value;
|
|
end;
|
|
end;
|
|
|
|
function TcxCustomEditorRowProperties.GetOnGetEditingProperties: TcxVerticalGridGetEditPropertiesEvent;
|
|
begin
|
|
Result := TcxVerticalGridGetEditPropertiesEvent(EditContainer.OnGetEditingProperties);
|
|
end;
|
|
|
|
function TcxCustomEditorRowProperties.GetOnGetEditProperties: TcxVerticalGridGetEditPropertiesEvent;
|
|
begin
|
|
Result := TcxVerticalGridGetEditPropertiesEvent(EditContainer.OnGetEditProperties);
|
|
end;
|
|
|
|
procedure TcxCustomEditorRowProperties.SetOnGetEditProperties(
|
|
Value: TcxVerticalGridGetEditPropertiesEvent);
|
|
begin
|
|
EditContainer.OnGetEditProperties := TcxGetEditPropertiesEvent(Value);
|
|
end;
|
|
|
|
procedure TcxCustomEditorRowProperties.SetOnGetEditingProperties(
|
|
Value: TcxVerticalGridGetEditPropertiesEvent);
|
|
begin
|
|
EditContainer.OnGetEditingProperties := TcxGetEditPropertiesEvent(Value);
|
|
end;
|
|
|
|
{ TcxEditorRowProperties }
|
|
|
|
procedure TcxEditorRowProperties.Assign(Source: TPersistent);
|
|
begin
|
|
if Source is TcxEditorRowProperties then
|
|
begin
|
|
inherited Assign(Source);
|
|
if not (Row.VerticalGrid is TcxVirtualVerticalGrid) then
|
|
Value := TcxEditorRowProperties(Source).Value;
|
|
end
|
|
else
|
|
inherited Assign(Source);
|
|
end;
|
|
|
|
{ TcxCustomEditorRow }
|
|
|
|
function TcxCustomEditorRow.CreateHeaderInfo: TcxCustomRowHeaderInfo;
|
|
begin
|
|
Result := TcxEditorRowHeaderInfo.Create(Self);
|
|
end;
|
|
|
|
function TcxCustomEditorRow.CreateViewInfo: TcxCustomRowViewInfo;
|
|
begin
|
|
Result := TcxEditorRowViewInfo.Create(Self);
|
|
end;
|
|
|
|
function TcxCustomEditorRow.CanFocus: Boolean;
|
|
begin
|
|
Result := Options.Focusing and Properties.Options.Focusing;
|
|
end;
|
|
|
|
function TcxCustomEditorRow.EditContainer: TcxCellEdit;
|
|
begin
|
|
if FProperties <> nil then
|
|
Result := TcxCustomEditorRowProperties(FProperties).FEditContainer
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
function TcxCustomEditorRow.GetDefaultHeight: Integer;
|
|
var
|
|
AFont: TFont;
|
|
begin
|
|
AFont := VerticalGrid.Styles.GetContentParams(Properties, False, -1).Font;
|
|
Result := Max(inherited GetDefaultHeight, EditContainer.GetEditDefaultHeight(AFont) + cxTextOffset);
|
|
end;
|
|
|
|
function TcxCustomEditorRow.GetEditContainer(
|
|
ACellIndex: Integer): TcxCellEdit;
|
|
begin
|
|
Result := EditContainer;
|
|
end;
|
|
|
|
function TcxCustomEditorRow.GetEditContainerCount: Integer;
|
|
begin
|
|
Result := 1;
|
|
end;
|
|
|
|
function TcxCustomEditorRow.GetPropertiesClass: TcxRowPropertiesClass;
|
|
begin
|
|
Result := TcxCustomEditorRowProperties;
|
|
end;
|
|
|
|
function TcxCustomEditorRow.GetStylesClass: TcxvgCustomRowStylesClass;
|
|
begin
|
|
Result := TcxEditorRowStyles;
|
|
end;
|
|
|
|
procedure TcxCustomEditorRow.SetParentComponent(Value: TComponent);
|
|
begin
|
|
inherited SetParentComponent(Value);
|
|
if Value <> nil then
|
|
if Value is TcxCustomVerticalGrid then
|
|
EditContainer.EditingControl := TcxCustomVerticalGrid(Value)
|
|
else
|
|
EditContainer.EditingControl := (Value as TcxCustomRow).VerticalGrid;
|
|
end;
|
|
|
|
procedure TcxCustomEditorRow.SetVerticalGrid(Value: TcxCustomVerticalGrid);
|
|
begin
|
|
inherited SetVerticalGrid(Value);
|
|
EditContainer.EditingControl := Value
|
|
end;
|
|
|
|
function TcxCustomEditorRow.GetProperties: TcxCustomEditorRowProperties;
|
|
begin
|
|
Result := TcxCustomEditorRowProperties(FProperties);
|
|
end;
|
|
|
|
function TcxCustomEditorRow.GetStyles: TcxEditorRowStyles;
|
|
begin
|
|
Result := TcxEditorRowStyles(FStyles);
|
|
end;
|
|
|
|
procedure TcxCustomEditorRow.SetProperties(Value: TcxCustomEditorRowProperties);
|
|
begin
|
|
FProperties.Assign(Value);
|
|
end;
|
|
|
|
procedure TcxCustomEditorRow.SetStyles(Value: TcxEditorRowStyles);
|
|
begin
|
|
FStyles.Assign(Value);
|
|
Changed;
|
|
end;
|
|
|
|
{ TcxEditorRow }
|
|
|
|
function TcxEditorRow.GetPropertiesClass: TcxRowPropertiesClass;
|
|
begin
|
|
Result := TcxEditorRowProperties;
|
|
end;
|
|
|
|
function TcxEditorRow.GetProperties: TcxEditorRowProperties;
|
|
begin
|
|
Result := TcxEditorRowProperties(FProperties);
|
|
end;
|
|
|
|
procedure TcxEditorRow.SetProperties(Value: TcxEditorRowProperties);
|
|
begin
|
|
FProperties.Assign(Value);
|
|
end;
|
|
|
|
{ TcxCollectionItemEditorRowProperties }
|
|
|
|
constructor TcxCollectionItemEditorRowProperties.CreateEx(
|
|
ARow: TcxCustomRow);
|
|
begin
|
|
ARow.FProperties.FLocked := True;
|
|
inherited CreateEx(ARow);
|
|
FWidth := 50;
|
|
FEditContainer.EditingControl := ARow.VerticalGrid;
|
|
ARow.FProperties.FLocked := False;
|
|
end;
|
|
|
|
procedure TcxCollectionItemEditorRowProperties.Assign(Source: TPersistent);
|
|
begin
|
|
inherited Assign(Source);
|
|
if Source is TcxCollectionItemEditorRowProperties then
|
|
Width := TcxCollectionItemEditorRowProperties(Source).Width;
|
|
end;
|
|
|
|
function TcxCollectionItemEditorRowProperties.GetDisplayName: string;
|
|
begin
|
|
Result := Caption;
|
|
end;
|
|
|
|
function TcxCollectionItemEditorRowProperties.GetOwner: TPersistent;
|
|
begin
|
|
Result := Collection;
|
|
end;
|
|
|
|
function TcxCollectionItemEditorRowProperties.GetOptions: TcxMultiEditorRowPropertiesOptions;
|
|
begin
|
|
Result := TcxMultiEditorRowPropertiesOptions(FEditContainer.Options);
|
|
end;
|
|
|
|
procedure TcxCollectionItemEditorRowProperties.SetOptions(
|
|
Value: TcxMultiEditorRowPropertiesOptions);
|
|
begin
|
|
FEditContainer.Options.Assign(Value);
|
|
end;
|
|
|
|
procedure TcxCollectionItemEditorRowProperties.SetWidth(Value: Integer);
|
|
begin
|
|
if Value < cxvgMinValueWidth then Value := cxvgMinValueWidth;
|
|
if FWidth <> Value then
|
|
begin
|
|
FWidth := Value;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
{ TcxEditorRowItemProperties }
|
|
|
|
procedure TcxEditorRowItemProperties.Assign(Source: TPersistent);
|
|
begin
|
|
inherited Assign(Source);
|
|
if Source is TcxEditorRowItemProperties then
|
|
begin
|
|
Value := TcxEditorRowItemProperties(Source).Value;
|
|
Options := TcxEditorRowItemProperties(Source).Options;
|
|
DataBinding := TcxEditorRowItemProperties(Source).DataBinding;
|
|
end;
|
|
end;
|
|
|
|
{ TcxEditorPropertiesCollection }
|
|
|
|
constructor TcxEditorPropertiesCollection.Create(ARow: TcxCustomMultiEditorRow);
|
|
begin
|
|
inherited Create(GetCollectionItemClass);
|
|
FRow := ARow;
|
|
end;
|
|
|
|
function TcxEditorPropertiesCollection.Add: TcxEditorRowItemProperties;
|
|
begin
|
|
Result := TcxEditorRowItemProperties(inherited Add);
|
|
end;
|
|
|
|
function TcxEditorPropertiesCollection.GetNamePath: string;
|
|
var
|
|
S, P: string;
|
|
begin
|
|
S := Row.Name;
|
|
if S = '' then S := Row.GetNamePath;
|
|
P := PropName;
|
|
if P = '' then Exit;
|
|
Result := S + '.' + P;
|
|
end;
|
|
|
|
function TcxEditorPropertiesCollection.GetCollectionItemClass: TCollectionItemClass;
|
|
begin
|
|
Result := TcxEditorRowItemProperties;
|
|
end;
|
|
|
|
function TcxEditorPropertiesCollection.GetOwner: TPersistent;
|
|
begin
|
|
if FRow = nil then
|
|
Result := nil
|
|
else
|
|
Result := FRow.FProperties;
|
|
end;
|
|
|
|
procedure TcxEditorPropertiesCollection.Update(Item: TCollectionItem);
|
|
var
|
|
I: Integer;
|
|
ARowInfo: TcxCustomRowViewInfo;
|
|
begin
|
|
for I := 0 to Count - 1 do
|
|
GetItem(I).FEditContainer.FCellIndex := I;
|
|
ARowInfo := FRow.ViewInfo;
|
|
with FRow.VerticalGrid do
|
|
begin
|
|
if csLoading in ComponentState then Exit;
|
|
HideEdit;
|
|
if not FRow.Properties.Locked then
|
|
begin
|
|
ARowInfo.ValuesInfo.Trunc(0);
|
|
if FocusedRow = FRow then
|
|
FocusedRow := nil;
|
|
with ARowInfo do
|
|
begin
|
|
Update;
|
|
for I := 0 to ValuesInfo.Count - 1 do
|
|
ValuesInfo[I].UpdateEditRect;
|
|
end;
|
|
FRow.Changed;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TcxEditorPropertiesCollection.GetItem(
|
|
Index: Integer): TcxEditorRowItemProperties;
|
|
begin
|
|
Result := TcxEditorRowItemProperties(inherited Items[Index]);
|
|
end;
|
|
|
|
{ TcxMultiEditorRowProperties }
|
|
|
|
constructor TcxMultiEditorRowProperties.CreateEx(ARow: TcxCustomRow);
|
|
begin
|
|
inherited CreateEx(ARow);
|
|
FEditors := GetCollectionClass.Create(ARow as TcxCustomMultiEditorRow);
|
|
FSeparatorKind := skVertLine;
|
|
end;
|
|
|
|
destructor TcxMultiEditorRowProperties.Destroy;
|
|
begin
|
|
FreeAndNil(FEditors);
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TcxMultiEditorRowProperties.Assign(Source: TPersistent);
|
|
begin
|
|
if Source is TcxMultiEditorRowProperties then
|
|
with TcxMultiEditorRowProperties(Source) do
|
|
begin
|
|
Self.SeparatorAlignmentVert := SeparatorAlignmentVert;
|
|
Self.SeparatorKind := SeparatorKind;
|
|
Self.SeparatorString := SeparatorString;
|
|
Self.Fixed := Fixed;
|
|
Self.Editors.Assign(Editors);
|
|
end
|
|
else
|
|
inherited Assign(Source);
|
|
end;
|
|
|
|
function TcxMultiEditorRowProperties.GetCollectionClass: TcxEditorPropertiesCollectionClass;
|
|
begin
|
|
Result := TcxEditorPropertiesCollection;
|
|
end;
|
|
|
|
function TcxMultiEditorRowProperties.GetOwner: TPersistent;
|
|
begin
|
|
Result := Row;
|
|
end;
|
|
|
|
procedure TcxMultiEditorRowProperties.SetFixed(Value: Boolean);
|
|
begin
|
|
if FFixed <> Value then
|
|
begin
|
|
FFixed := Value;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxMultiEditorRowProperties.SetSeparatorAlignmentVert(
|
|
Value: TcxAlignmentVert);
|
|
begin
|
|
if FSeparatorAlignmentVert <> Value then
|
|
begin
|
|
FSeparatorAlignmentVert := Value;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxMultiEditorRowProperties.SetSeparatorKind(
|
|
Value: TSeparatorKind);
|
|
begin
|
|
if FSeparatorKind <> Value then
|
|
begin
|
|
FSeparatorKind := Value;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxMultiEditorRowProperties.SetSeparatorString(
|
|
const Value: string);
|
|
begin
|
|
if FSeparatorString <> Value then
|
|
begin
|
|
FSeparatorString := Value;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
{ TcxCustomMultiEditorRow }
|
|
|
|
function TcxCustomMultiEditorRow.CreateHeaderInfo: TcxCustomRowHeaderInfo;
|
|
begin
|
|
Result := TcxMultiEditorRowHeaderInfo.Create(Self);
|
|
end;
|
|
|
|
function TcxCustomMultiEditorRow.CreateViewInfo: TcxCustomRowViewInfo;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := TcxMultiEditorRowViewInfo.Create(Self);
|
|
with TcxMultiEditorRowProperties(FProperties) do
|
|
for I := 0 to Editors.Count - 1 do
|
|
Editors[I].EditContainer.FCellIndex := I;
|
|
end;
|
|
|
|
function TcxCustomMultiEditorRow.CanFocus: Boolean;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := inherited CanFocus;
|
|
if Result then
|
|
begin
|
|
Result := False;
|
|
for I := 0 to Properties.Editors.Count - 1 do
|
|
begin
|
|
Result := Result or Properties.Editors.GetItem(I).Options.Focusing;
|
|
if Result then break;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TcxCustomMultiEditorRow.GetDefaultHeight: Integer;
|
|
var
|
|
I: Integer;
|
|
AFont: TFont;
|
|
begin
|
|
Result := inherited GetDefaultHeight;
|
|
for I := 0 to Properties.Editors.Count - 1 do
|
|
begin
|
|
AFont := VerticalGrid.Styles.GetContentParams(Properties.Editors[I], False, -1).Font;
|
|
Result := Max(Result, Properties.Editors[I].EditContainer.GetEditDefaultHeight(AFont) + cxTextOffset);
|
|
end;
|
|
end;
|
|
|
|
function TcxCustomMultiEditorRow.GetEditContainer(
|
|
ACellIndex: Integer): TcxCellEdit;
|
|
begin
|
|
if (ACellIndex >= 0) and (ACellIndex < GetEditContainerCount) then
|
|
Result := Properties.Editors[ACellIndex].EditContainer
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
function TcxCustomMultiEditorRow.GetEditContainerCount: Integer;
|
|
begin
|
|
Result := Properties.Editors.Count;
|
|
end;
|
|
|
|
function TcxCustomMultiEditorRow.GetPropertiesClass: TcxRowPropertiesClass;
|
|
begin
|
|
Result := TcxMultiEditorRowProperties;
|
|
end;
|
|
|
|
function TcxCustomMultiEditorRow.GetStylesClass: TcxvgCustomRowStylesClass;
|
|
begin
|
|
Result := TcxEditorRowStyles;
|
|
end;
|
|
|
|
function TcxCustomMultiEditorRow.GetProperties: TcxMultiEditorRowProperties;
|
|
begin
|
|
Result := TcxMultiEditorRowProperties(FProperties);;
|
|
end;
|
|
|
|
function TcxCustomMultiEditorRow.GetStyles: TcxEditorRowStyles;
|
|
begin
|
|
Result := TcxEditorRowStyles(FStyles);
|
|
end;
|
|
|
|
procedure TcxCustomMultiEditorRow.SetProperties(
|
|
const Value: TcxMultiEditorRowProperties);
|
|
begin
|
|
FProperties.Assign(Value);
|
|
end;
|
|
|
|
procedure TcxCustomMultiEditorRow.SetStyles(Value: TcxEditorRowStyles);
|
|
begin
|
|
FStyles.Assign(Value);
|
|
Changed;
|
|
end;
|
|
|
|
{ TcxVerticalGridRows }
|
|
|
|
constructor TcxVerticalGridRows.Create(AOwner: TcxCustomVerticalGrid);
|
|
begin
|
|
inherited Create;
|
|
FOwner := AOwner;
|
|
FList := TList.Create;
|
|
FCount := -1;
|
|
end;
|
|
|
|
destructor TcxVerticalGridRows.Destroy;
|
|
begin
|
|
FreeAndNil(FList);
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TcxVerticalGridRows.AssignRows(Source: TcxVerticalGridRows);
|
|
|
|
procedure AddRowWithChildren(AParent: TcxCustomRow; ASourceRow: TcxCustomRow);
|
|
var
|
|
I: Integer;
|
|
AddedRow: TcxCustomRow;
|
|
begin
|
|
AddedRow := Owner.AddChild(AParent, TcxCustomRowClass(ASourceRow.ClassType));
|
|
AddedRow.FID := ASourceRow.ID;
|
|
AddedRow.Assign(ASourceRow);
|
|
for I := 0 to ASourceRow.Count - 1 do
|
|
AddRowWithChildren(AddedRow, ASourceRow.Rows[I]);
|
|
end;
|
|
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if not (Source is TcxVerticalGridRows) then
|
|
cxVerticalGridError(cxGetResourceString(@cxSvgAssignRowsError));
|
|
BeginUpdate;
|
|
try
|
|
Clear;
|
|
for I := 0 to Source.Root.Count - 1 do
|
|
AddRowWithChildren(Root, Source.Root.Rows[I]);
|
|
finally
|
|
EndUpdate;
|
|
end;
|
|
end;
|
|
|
|
function TcxVerticalGridRows.IndexOf(ARow: TcxCustomRow): Integer;
|
|
begin
|
|
CheckList;
|
|
Result := FList.IndexOf(ARow);
|
|
end;
|
|
|
|
procedure TcxVerticalGridRows.Add(ARow: TcxCustomRow);
|
|
begin
|
|
if Assigned(ARow) then
|
|
begin
|
|
FOwner.RootRow.Add(ARow);
|
|
UnprepareList;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxVerticalGridRows.AddChild(AParent,
|
|
ARow: TcxCustomRow);
|
|
begin
|
|
if Assigned(AParent) and Assigned(ARow) then
|
|
begin
|
|
AParent.Add(ARow);
|
|
UnprepareList;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxVerticalGridRows.BeginUpdate;
|
|
begin
|
|
Inc(FLockCount);
|
|
end;
|
|
|
|
procedure TcxVerticalGridRows.Changed(ARebuild: Boolean = False);
|
|
begin
|
|
if ARebuild then PrepareList;
|
|
if FLockCount = 0 then
|
|
begin
|
|
FOwner.RowsChanged;
|
|
FOwner.OptionsView.CheckRowHeaderWidth;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxVerticalGridRows.CheckList;
|
|
begin
|
|
if FCount = -1 then PrepareList;
|
|
end;
|
|
|
|
procedure TcxVerticalGridRows.Clear;
|
|
begin
|
|
BeginUpdate;
|
|
try
|
|
FOwner.FocusedRow := nil;
|
|
FOwner.RootRow.RemoveAll;
|
|
UnprepareList;
|
|
finally
|
|
EndUpdate;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxVerticalGridRows.EndUpdate;
|
|
begin
|
|
Dec(FLockCount);
|
|
if FLockCount = 0 then Changed(True);
|
|
end;
|
|
|
|
function TcxVerticalGridRows.FindRowByID(AID: Integer): TcxCustomRow;
|
|
var
|
|
I: Integer;
|
|
ARow: TcxCustomRow;
|
|
begin
|
|
if AID = -1 then
|
|
Result := FOwner.FRootRow
|
|
else
|
|
begin
|
|
Result := nil;
|
|
for I := 0 to Count - 1 do
|
|
begin
|
|
ARow := Items[I];
|
|
if ARow.ID = AID then
|
|
begin
|
|
Result := ARow;
|
|
break;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TcxVerticalGridRows.FindRowByStoredName(const AName: string): TcxCustomRow;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := FOwner.FRootRow;
|
|
for I := 0 to Count - 1 do
|
|
if CompareStr(Items[I].GetObjectName, AName) = 0 then
|
|
begin
|
|
Result := Items[I];
|
|
break;
|
|
end;
|
|
end;
|
|
|
|
function TcxVerticalGridRows.GetNextID: Integer;
|
|
begin
|
|
Result := FNextID;
|
|
Inc(FNextID);
|
|
end;
|
|
|
|
procedure TcxVerticalGridRows.PrepareList;
|
|
var
|
|
ARow: TcxCustomRow;
|
|
|
|
function NextRow: TcxCustomRow;
|
|
var
|
|
AIndex: Integer;
|
|
ATemp: TcxCustomRow;
|
|
begin
|
|
Result := nil;
|
|
AIndex := 0;
|
|
ATemp := ARow;
|
|
repeat
|
|
if ATemp.Count > AIndex then
|
|
Result := ATemp.Rows[AIndex]
|
|
else
|
|
begin
|
|
AIndex := Succ(ATemp.Index);
|
|
ATemp := ATemp.FParent;
|
|
end;
|
|
until (Result <> nil) or (ATemp = nil);
|
|
end;
|
|
|
|
begin
|
|
FList.Clear;
|
|
ARow := FOwner.FirstRow;
|
|
while ARow <> nil do
|
|
begin
|
|
FList.Add(ARow);
|
|
ARow := NextRow;
|
|
end;
|
|
FCount := FList.Count;
|
|
end;
|
|
|
|
procedure TcxVerticalGridRows.Remove(ARow: TcxCustomRow);
|
|
begin
|
|
FList.Remove(ARow);
|
|
UnprepareList;
|
|
end;
|
|
|
|
procedure TcxVerticalGridRows.RestoreDefaults;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to Count - 1 do
|
|
Items[I].RestoreDefaults;
|
|
end;
|
|
|
|
procedure TcxVerticalGridRows.UnprepareList;
|
|
begin
|
|
FCount := -1;
|
|
end;
|
|
|
|
function TcxVerticalGridRows.GetCount: Integer;
|
|
begin
|
|
CheckList;
|
|
Result := FList.Count;
|
|
end;
|
|
|
|
function TcxVerticalGridRows.GetRoot: TcxCustomRow;
|
|
begin
|
|
Result := FOwner.FRootRow;
|
|
end;
|
|
|
|
function TcxVerticalGridRows.GetRow(Index: Integer): TcxCustomRow;
|
|
begin
|
|
if (Index < 0) or (Index >= Count) then // call Count -> refresh if need
|
|
cxVerticalGridError(cxSvgIndexError);
|
|
Result := TcxCustomRow(FList.List^[Index]);
|
|
end;
|
|
|
|
procedure TcxVerticalGridRows.SetRow(Index: Integer;
|
|
const Value: TcxCustomRow);
|
|
begin
|
|
if (Index < 0) or (Index >= Count) then // call Count -> refresh if need
|
|
cxVerticalGridError(cxSvgIndexError);
|
|
FList[Index] := Value;
|
|
end;
|
|
|
|
{ TBandInfoList }
|
|
|
|
constructor TBandInfoList.Create;
|
|
begin
|
|
inherited Create(SizeOf(TBandInfo));
|
|
Delta := 32;
|
|
end;
|
|
|
|
function TBandInfoList.Add(ABandIndex, ARowsCount, ABandHeight: Integer;
|
|
AFirstRow: TcxCustomRow): Integer;
|
|
begin
|
|
CheckCapacity;
|
|
Result := FCount;
|
|
Inc(FCount);
|
|
with TBandInfo(Get(Result)^) do
|
|
begin
|
|
BandIndex := ABandIndex;
|
|
RowsCount := ARowsCount;
|
|
BandHeight := ABandHeight;
|
|
FirstRow := AFirstRow;
|
|
end;
|
|
end;
|
|
|
|
function TBandInfoList.GetItem(Index: Integer): TBandInfo;
|
|
begin
|
|
Result := TBandInfo(Get(Index)^);
|
|
end;
|
|
|
|
{ TcxvgCustomScrollStrategy }
|
|
|
|
constructor TcxvgCustomScrollStrategy.Create(
|
|
AScroller: TcxvgScroller);
|
|
begin
|
|
FBandsInfo := TBandInfoList.Create;
|
|
FScroller := AScroller;
|
|
FViewInfo := AScroller.ViewInfo;
|
|
end;
|
|
|
|
destructor TcxvgCustomScrollStrategy.Destroy;
|
|
begin
|
|
FBandsInfo.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TcxvgCustomScrollStrategy.CheckDecreaseLeftIndex;
|
|
begin
|
|
end;
|
|
|
|
procedure TcxvgCustomScrollStrategy.CheckDecreaseTopIndex(AScrollRectHeight: Integer);
|
|
var
|
|
ACount, ATotal: Integer;
|
|
begin
|
|
ATotal := FViewInfo.VisibleRowCount;
|
|
ACount := GetVisibleCountFromBottom(ATotal - 1, AScrollRectHeight);
|
|
if ATotal - ACount < FTopVisibleRowIndex then
|
|
FTopVisibleRowIndex := ATotal - ACount;
|
|
end;
|
|
|
|
function TcxvgCustomScrollStrategy.CheckTopVisibleIndex(AIndex, AStep: Integer): Integer;
|
|
var
|
|
ACount: Integer;
|
|
begin
|
|
Result := AIndex;
|
|
ACount := ViewInfo.VisibleRowCount;
|
|
cxRange(Result, 0, ACount -
|
|
GetVisibleCountFromBottom(ACount - 1, cxRectHeight(ViewInfo.ClientRect)));
|
|
end;
|
|
|
|
function TcxvgCustomScrollStrategy.FindNextCustomItem(AFocusedItemIndex, AItemCount: Integer;
|
|
AGoForward: Boolean; var AItemIndex: Integer): Boolean;
|
|
|
|
function GetFromIndex: Integer;
|
|
begin
|
|
if AFocusedItemIndex = -1 then
|
|
if AGoForward then
|
|
Result := 0
|
|
else
|
|
Result := -1
|
|
else
|
|
if AGoForward then
|
|
Result := AFocusedItemIndex + 1
|
|
else
|
|
Result := AFocusedItemIndex - 1;
|
|
end;
|
|
|
|
function CheckIndex(var AIndex: Integer): Boolean;
|
|
begin
|
|
Result := True;
|
|
if AGoForward then
|
|
if AIndex > AItemCount - 1 then
|
|
Result := False
|
|
else
|
|
else
|
|
if AIndex < 0 then
|
|
Result := False;
|
|
end;
|
|
begin
|
|
Result := False;
|
|
if AItemCount = 0 then Exit;
|
|
AItemIndex := GetFromIndex;
|
|
Result := CheckIndex(AItemIndex);
|
|
end;
|
|
|
|
function TcxvgCustomScrollStrategy.FindNextRecord(AFocusedRecordIndex: Integer;
|
|
AGoForward: Boolean): Integer;
|
|
begin
|
|
if DataController.IsGridMode then
|
|
if AGoForward then
|
|
if not DataController.IsEOF and (AFocusedRecordIndex = DataController.RowCount - 1) then
|
|
begin
|
|
DataController.Scroll(1);
|
|
if not DataController.IsEOF then
|
|
Dec(AFocusedRecordIndex);
|
|
end
|
|
else
|
|
else
|
|
if (AFocusedRecordIndex = 0) and not DataController.IsBOF then
|
|
begin
|
|
DataController.Scroll(-1);
|
|
if not DataController.IsBOF then
|
|
Inc(AFocusedRecordIndex);
|
|
end;
|
|
if not FindNextCustomItem(AFocusedRecordIndex, DataController.RowCount, AGoForward, Result) then
|
|
Result := -1;
|
|
end;
|
|
|
|
function TcxvgCustomScrollStrategy.FocusNextRecord(AFocusedRecordIndex: Integer;
|
|
AGoForward: Boolean): Boolean;
|
|
|
|
procedure CheckEditing;
|
|
begin
|
|
if DataController.IsEditing then
|
|
begin
|
|
TcxEditingControllerAccess(Controller.EditingController).UpdateValue;
|
|
if not (dceModified in DataController.EditState) then
|
|
begin
|
|
if DataController.EditState = [dceInsert] then
|
|
begin
|
|
Result := AGoForward xor DataController.IsEOF;
|
|
if Result then DataController.Cancel;
|
|
end;
|
|
Exit;
|
|
end;
|
|
DataController.Post;
|
|
AFocusedRecordIndex := DataController.FocusedRowIndex;
|
|
end;
|
|
end;
|
|
|
|
procedure CheckGridMode;
|
|
begin
|
|
if DataController.IsGridMode and (AFocusedRecordIndex = -1) and AGoForward then
|
|
DataController.GotoFirst
|
|
end;
|
|
|
|
var
|
|
ANewRecordIndex: Integer;
|
|
|
|
begin
|
|
Result := False;
|
|
CheckEditing;
|
|
if Result then Exit;
|
|
CheckGridMode;
|
|
ANewRecordIndex := FindNextRecord(AFocusedRecordIndex, AGoForward);
|
|
Result := ANewRecordIndex <> -1;
|
|
if Result then
|
|
DataController.FocusedRowIndex := ANewRecordIndex;
|
|
end;
|
|
|
|
function TcxvgCustomScrollStrategy.GetFirstRowByBandIndex(
|
|
ABandIndex: Integer): TcxCustomRow;
|
|
begin
|
|
if not cxInRange(ABandIndex, 0, BandsInfo.Count - 1) then
|
|
Result := nil
|
|
else
|
|
Result := FBandsInfo[ABandIndex].FirstRow;
|
|
end;
|
|
|
|
procedure TcxvgCustomScrollStrategy.InitHScrollBarParameters;
|
|
var
|
|
AScrollRecordCount, AScrollPos: Integer;
|
|
|
|
procedure GetScrollRecordParams;
|
|
var
|
|
AIntf: IcxVerticalGridDBDataContoller;
|
|
begin
|
|
if DataController.GetInterface(IcxVerticalGridDBDataContoller, AIntf) then
|
|
begin
|
|
AScrollRecordCount := AIntf.GetScrollBarRecordCount;
|
|
AScrollPos := AIntf.GetScrollBarPos;
|
|
end
|
|
else
|
|
begin
|
|
AScrollRecordCount := -1;
|
|
AScrollPos := -1;
|
|
end;
|
|
if AScrollRecordCount = -1 then
|
|
AScrollRecordCount := DataController.RowCount + ScrollBarOffsetBegin + ScrollBarOffsetEnd;
|
|
if AScrollPos = -1 then
|
|
AScrollPos := LeftVisibleRecord + ScrollBarOffsetBegin;
|
|
end;
|
|
|
|
begin
|
|
GetScrollRecordParams;
|
|
VerticalGrid.SetScrollBarInfo(sbHorizontal,
|
|
0, AScrollRecordCount - 1, 1, VisibleValueCount,
|
|
ScrollBarPos, not IsHideHScrollBar, True);
|
|
end;
|
|
|
|
procedure TcxvgCustomScrollStrategy.InitVScrollBarParameters;
|
|
begin
|
|
VerticalGrid.SetScrollBarInfo(sbVertical,
|
|
0, ViewInfo.VisibleRowCount - 1, //min max
|
|
1, VisibleRowCount, TopVisibleRowIndex, not IsHideVScrollBar, True);
|
|
end;
|
|
|
|
function TcxvgCustomScrollStrategy.GetVisibleCountFromBottom(
|
|
ABottomIndex, AHeight: Integer): Integer;
|
|
begin
|
|
Result := GetVisibleCount(ABottomIndex, AHeight, -1, False);
|
|
end;
|
|
|
|
function TcxvgCustomScrollStrategy.GetVisibleCountFromTop(
|
|
ATopIndex, AHeight: Integer): Integer;
|
|
begin
|
|
Result := GetVisibleCount(ATopIndex, AHeight, 1, True);
|
|
end;
|
|
|
|
procedure TcxvgCustomScrollStrategy.RecalcBandsInfo;
|
|
begin
|
|
FBandsInfo.Clear;
|
|
FBandsInfo.Add(0, FViewInfo.VisibleRowCount, -1, FViewInfo.VisibleRows[0]);
|
|
end;
|
|
|
|
procedure TcxvgCustomScrollStrategy.ScrollRecords(AForward: Boolean;
|
|
ACount: Integer);
|
|
var
|
|
AIntf: IcxVerticalGridDBDataContoller;
|
|
begin
|
|
if not DataController.GetInterface(IcxVerticalGridDBDataContoller, AIntf) or
|
|
not AIntf.DoScroll(AForward) then
|
|
if AForward then
|
|
Scroller.LeftVisibleRecord := LeftVisibleRecord + ACount
|
|
else
|
|
Scroller.LeftVisibleRecord := LeftVisibleRecord - ACount;
|
|
end;
|
|
|
|
procedure TcxvgCustomScrollStrategy.SetRowMaxVisible(ARow: TcxCustomRow);
|
|
var
|
|
N, ATopIndex, AChildCount, AGroupHeight, AClientHeight: Integer;
|
|
begin
|
|
if ARow = nil then Exit;
|
|
AGroupHeight := GetFullRowHeight(ARow, AChildCount);
|
|
AClientHeight := BandsInfo.Count * cxRectHeight(FViewInfo.ClientRect);
|
|
if AGroupHeight >= AClientHeight then
|
|
SetTopVisibleRowIndexAndBand(ARow.VisibleIndex)
|
|
else
|
|
begin
|
|
N := GetVisibleCountFromTop(FTopVisibleRowIndex, cxRectHeight(ViewInfo.ClientRect));
|
|
ATopIndex := ARow.VisibleIndex + AChildCount - N + 1;
|
|
if FTopVisibleRowIndex < ATopIndex then
|
|
SetTopVisibleRowIndexAndBand(ATopIndex);
|
|
end
|
|
end;
|
|
|
|
function TcxvgCustomScrollStrategy.CanContinueForward(Index: Integer): Boolean;
|
|
begin
|
|
Result := Index < FViewInfo.VisibleRowCount;
|
|
end;
|
|
|
|
function TcxvgCustomScrollStrategy.CanContinueBackward(Index: Integer): Boolean;
|
|
begin
|
|
Result := Index > -1;
|
|
end;
|
|
|
|
function TcxvgCustomScrollStrategy.CanCalcRowsOnTheNextBand(ALeft,
|
|
ANextBandIndex: Integer): Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
procedure TcxvgCustomScrollStrategy.CheckLeftVisibleRecord(var AValue: Integer);
|
|
var
|
|
AIsGridMode: Boolean;
|
|
AMaxValue: Integer;
|
|
begin
|
|
if FCheckingCoordinate then Exit;
|
|
FCheckingCoordinate := True;
|
|
with DataController do
|
|
try
|
|
AIsGridMode := IsGridMode;
|
|
if AValue < 0 then
|
|
begin
|
|
if AIsGridMode and not IsBOF then
|
|
Scroll(AValue);
|
|
AValue := 0;
|
|
end;
|
|
if AValue > RowCount - 1 then
|
|
begin
|
|
if AIsGridMode and not IsEOF then
|
|
Scroll(AValue - (RowCount - 1));
|
|
AValue := RowCount - 1;
|
|
end;
|
|
if AValue <= 0 then Exit;
|
|
AMaxValue := RowCount - VisibleValueCount;
|
|
if AValue > AMaxValue then
|
|
begin
|
|
if AIsGridMode and not IsEOF and not (dceInsert in EditState) then
|
|
Scroll(AValue - AMaxValue);
|
|
AValue := AMaxValue;
|
|
end;
|
|
finally
|
|
FCheckingCoordinate := False;
|
|
end;
|
|
end;
|
|
|
|
function TcxvgCustomScrollStrategy.GetBandWidth: Integer;
|
|
begin
|
|
Result := ViewInfo.FViewBandWidth;
|
|
end;
|
|
|
|
function TcxvgCustomScrollStrategy.GetBottomVisibleChild(
|
|
ARow: TcxCustomRow): TcxCustomRow;
|
|
begin
|
|
if (ARow = nil) or not (ARow.Expanded and ARow.Visible) then
|
|
begin
|
|
Result := nil;
|
|
Exit
|
|
end;
|
|
Result := ARow.GetLastVisibleChild;
|
|
end;
|
|
|
|
function TcxvgCustomScrollStrategy.GetFullRowHeight(ARow: TcxCustomRow;
|
|
out ChildCount: Integer): Integer;
|
|
var
|
|
I, AIndex: Integer;
|
|
AChild: TcxCustomRow;
|
|
begin
|
|
ChildCount := 0;
|
|
Result := 0;
|
|
if ARow = nil then Exit;
|
|
with ViewInfo do
|
|
begin
|
|
Result := ARow.ViewInfo.CalculatedHeight + HorzLineWidth;
|
|
AIndex := ARow.VisibleIndex;
|
|
if AIndex >= 0 then
|
|
for I := AIndex + 1 to VisibleRowCount - 1 do
|
|
begin
|
|
AChild := VisibleRows[I];
|
|
if ARow.IsParent(AChild) then
|
|
begin
|
|
Inc(ChildCount);
|
|
Inc(Result, AChild.ViewInfo.CalculatedHeight + HorzLineWidth);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TcxvgCustomScrollStrategy.GetScrollBarOffsetBegin: Integer;
|
|
begin
|
|
with DataController do
|
|
begin
|
|
if IsGridMode and IsRecordsScrollMode then
|
|
Result := Ord(not IsBOF)
|
|
else
|
|
Result := 0;
|
|
end;
|
|
end;
|
|
|
|
function TcxvgCustomScrollStrategy.GetScrollBarOffsetEnd: Integer;
|
|
begin
|
|
with DataController do
|
|
begin
|
|
if IsGridMode and IsRecordsScrollMode then
|
|
Result := Ord(not IsEOF)
|
|
else
|
|
Result := 0;
|
|
end;
|
|
end;
|
|
|
|
function TcxvgCustomScrollStrategy.GetVisibleCount(ABeginIndex, AAreaHeight,
|
|
AStep: Integer; AForward: Boolean): Integer;
|
|
|
|
function CheckContinue(AIndex: Integer): Boolean;
|
|
begin
|
|
if AForward then
|
|
Result := CanContinueForward(AIndex)
|
|
else
|
|
Result := CanContinueBackward(AIndex)
|
|
end;
|
|
|
|
var
|
|
ARowCount, ARowHeight, ABandCount, ALeft, ABandWidth, ABandHeight: Integer;
|
|
ARowViewInfo: TcxCustomRowViewInfo;
|
|
begin
|
|
Result := 0;
|
|
ARowCount := 0;
|
|
ABandCount := 0;
|
|
ABandWidth := BandWidth;
|
|
if ABandWidth <= 0 then Exit;
|
|
with ViewInfo do
|
|
begin
|
|
ABandHeight := HorzLineWidth;
|
|
ALeft := ClientRect.Left;
|
|
while CheckContinue(ABeginIndex) do
|
|
begin
|
|
ARowViewInfo := VisibleRows[ABeginIndex].ViewInfo;
|
|
if FRowsViewInfo.IndexOf(ARowViewInfo) = -1 then
|
|
ARowHeight := GetRowHeight(ARowViewInfo, ABandWidth)
|
|
else
|
|
ARowHeight := ARowViewInfo.CalculatedHeight;
|
|
if ABandHeight + ARowHeight + HorzLineWidth > AAreaHeight then
|
|
begin
|
|
if ARowCount = 0 then ARowCount := 1;
|
|
Inc(Result, ARowCount);
|
|
ARowCount := 0;
|
|
ABandHeight := HorzLineWidth;
|
|
Inc(ALeft, ABandWidth + BandInterval);
|
|
Inc(ABandCount);
|
|
if not CanCalcRowsOnTheNextBand(ALeft, ABandCount) then break;
|
|
end;
|
|
Inc(ABandHeight, ARowHeight + HorzLineWidth);
|
|
Inc(ARowCount);
|
|
Inc(ABeginIndex, AStep);
|
|
end;
|
|
end;
|
|
Inc(Result, ARowCount);
|
|
end;
|
|
|
|
function TcxvgCustomScrollStrategy.IsBehindRightClientEdge(X: Integer): Boolean;
|
|
begin
|
|
Result := X > (FViewInfo.ClientRect.Right - FViewInfo.VertLineWidth);
|
|
end;
|
|
|
|
function TcxvgCustomScrollStrategy.IsHideHScrollBar: Boolean;
|
|
begin
|
|
with VerticalGrid do
|
|
Result := (ClientHeight - 2 < HScrollBar.Height) or
|
|
(IsRecordsScrollMode and not Controller.CanChangeRecord);
|
|
end;
|
|
|
|
function TcxvgCustomScrollStrategy.IsHideVScrollBar: Boolean;
|
|
begin
|
|
with VerticalGrid do
|
|
Result := cxRectWidth(ViewInfo.ClientRect) - 2 < VScrollBar.Width;
|
|
end;
|
|
|
|
function TcxvgCustomScrollStrategy.IsRecordsScrollMode: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
procedure TcxvgCustomScrollStrategy.ScrollH(
|
|
AScrollCode: TScrollCode; var AScrollPos: Integer);
|
|
|
|
procedure DoScrollRecords;
|
|
begin
|
|
case AScrollCode of
|
|
scLineUp:
|
|
ScrollRecords(False, 1);
|
|
scLineDown:
|
|
ScrollRecords(True, 1);
|
|
scPageUp:
|
|
Scroller.LeftVisibleRecord := LeftVisibleRecord - VisibleValueCount;
|
|
scPageDown:
|
|
Scroller.LeftVisibleRecord := LeftVisibleRecord + VisibleValueCount;
|
|
scTrack:
|
|
if not DataController.IsGridMode then
|
|
ScrollBarPos := AScrollPos;
|
|
scPosition:
|
|
if DataController.IsGridMode then
|
|
ScrollBarPos := AScrollPos;
|
|
end;
|
|
AScrollPos := ScrollBarPos;
|
|
end;
|
|
|
|
procedure DoScrollBands;
|
|
begin
|
|
case AScrollCode of
|
|
scLineUp:
|
|
Scroller.LeftVisibleBand := LeftVisibleBand - 1;
|
|
scLineDown:
|
|
Scroller.LeftVisibleBand := LeftVisibleBand + 1;
|
|
scPageUp:
|
|
Scroller.LeftVisibleBand := LeftVisibleBand - VisibleBandCount;
|
|
scPageDown:
|
|
Scroller.LeftVisibleBand := LeftVisibleBand + VisibleBandCount;
|
|
scTrack:
|
|
Scroller.LeftVisibleBand := AScrollPos;
|
|
end;
|
|
AScrollPos := LeftVisibleBand;
|
|
end;
|
|
|
|
begin
|
|
if IsRecordsScrollMode then
|
|
DoScrollRecords
|
|
else
|
|
DoScrollBands;
|
|
end;
|
|
|
|
procedure TcxvgCustomScrollStrategy.ScrollV(
|
|
AScrollCode: TScrollCode; var AScrollPos: Integer);
|
|
begin
|
|
case AScrollCode of
|
|
scLineUp:
|
|
Scroller.TopVisibleRowIndex := TopVisibleRowIndex - 1;
|
|
scLineDown:
|
|
Scroller.TopVisibleRowIndex := TopVisibleRowIndex + 1;
|
|
scPageUp:
|
|
Scroller.TopVisibleRowIndex := TopVisibleRowIndex - VisibleRowCount;
|
|
scPageDown:
|
|
Scroller.TopVisibleRowIndex := TopVisibleRowIndex + VisibleRowCount;
|
|
scTrack:
|
|
Scroller.TopVisibleRowIndex := AScrollPos;
|
|
end;
|
|
AScrollPos := TopVisibleRowIndex;
|
|
end;
|
|
|
|
procedure TcxvgCustomScrollStrategy.SetLeftVisibleRecord(Value: Integer);
|
|
var
|
|
ARowIndex: Integer;
|
|
begin
|
|
ARowIndex := Value;
|
|
CheckLeftVisibleRecord(ARowIndex);
|
|
if FLeftVisibleRecord <> ARowIndex then
|
|
begin
|
|
FLeftVisibleRecord := ARowIndex;
|
|
VerticalGrid.LayoutChanged;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgCustomScrollStrategy.SetTopVisibleRowIndexAndBand(Index: Integer);
|
|
begin
|
|
SetTopVisibleRowIndex(Index);
|
|
end;
|
|
|
|
function TcxvgCustomScrollStrategy.GetController: TcxvgController;
|
|
begin
|
|
Result := FViewInfo.VerticalGrid.Controller;
|
|
end;
|
|
|
|
function TcxvgCustomScrollStrategy.GetDataController: TcxCustomDataController;
|
|
begin
|
|
Result := FViewInfo.VerticalGrid.DataController;
|
|
end;
|
|
|
|
function TcxvgCustomScrollStrategy.GetScrollBarPos: Integer;
|
|
var
|
|
AIntf: IcxVerticalGridDBDataContoller;
|
|
begin
|
|
if DataController.GetInterface(IcxVerticalGridDBDataContoller, AIntf) then
|
|
Result := AIntf.GetScrollBarPos
|
|
else
|
|
Result := -1;
|
|
if Result = -1 then
|
|
Result := LeftVisibleRecord + ScrollBarOffsetBegin;
|
|
end;
|
|
|
|
function TcxvgCustomScrollStrategy.GetVerticalGrid: TcxCustomVerticalGrid;
|
|
begin
|
|
Result := FViewInfo.VerticalGrid;
|
|
end;
|
|
|
|
function TcxvgCustomScrollStrategy.GetVisibleRowCount: Integer;
|
|
begin
|
|
with FViewInfo.ClientRect do
|
|
Result := GetVisibleCountFromTop(TopVisibleRowIndex, Bottom - Top);
|
|
end;
|
|
|
|
procedure TcxvgCustomScrollStrategy.SetScrollBarPos(Value: Integer);
|
|
var
|
|
AIntf: IcxVerticalGridDBDataContoller;
|
|
begin
|
|
if not DataController.GetInterface(IcxVerticalGridDBDataContoller, AIntf) or
|
|
not AIntf.SetScrollBarPos(Value) then
|
|
Scroller.LeftVisibleRecord := Value - ScrollBarOffsetBegin
|
|
end;
|
|
|
|
procedure TcxvgCustomScrollStrategy.SetTopVisibleRowIndex(Value: Integer);
|
|
begin
|
|
if FTopVisibleRowIndex <> Value then
|
|
begin
|
|
FTopVisibleRowIndex := Value;
|
|
VerticalGrid.LayoutChanged;
|
|
VerticalGrid.DoTopRowIndexChanged;
|
|
end;
|
|
end;
|
|
|
|
{ TcxvgSingleRecordScrollStrategy }
|
|
|
|
function TcxvgSingleRecordScrollStrategy.GetBandIndexByRowIndex(
|
|
ARowIndex: Integer): Integer;
|
|
begin
|
|
Result := 0;
|
|
end;
|
|
|
|
function TcxvgSingleRecordScrollStrategy.GetBandInterval: Integer;
|
|
begin
|
|
Result := 0;
|
|
end;
|
|
|
|
function TcxvgSingleRecordScrollStrategy.GetLeftVisibleBand: Integer;
|
|
begin
|
|
Result := 0;
|
|
end;
|
|
|
|
function TcxvgSingleRecordScrollStrategy.GetVisibleBandCount: Integer;
|
|
begin
|
|
Result := 1;
|
|
end;
|
|
|
|
function TcxvgSingleRecordScrollStrategy.GetVisibleValueCount: Integer;
|
|
begin
|
|
Result := 1;
|
|
end;
|
|
|
|
procedure TcxvgSingleRecordScrollStrategy.SetLeftVisibleBand(Value: Integer);
|
|
begin
|
|
end;
|
|
|
|
{ TcxvgMultiRecordsScrollStrategy }
|
|
|
|
procedure TcxvgMultiRecordsScrollStrategy.CheckDecreaseLeftIndex;
|
|
var
|
|
AVisibleCount: Integer;
|
|
begin
|
|
AVisibleCount := VisibleValueCount;
|
|
if LeftVisibleRecord + AVisibleCount > VerticalGrid.RecordCount then
|
|
FLeftVisibleRecord := Max(0, VerticalGrid.RecordCount - AVisibleCount);
|
|
end;
|
|
|
|
function TcxvgMultiRecordsScrollStrategy.GetBandIndexByRowIndex(
|
|
ARowIndex: Integer): Integer;
|
|
begin
|
|
Result := 0;
|
|
end;
|
|
|
|
function TcxvgMultiRecordsScrollStrategy.GetBandInterval: Integer;
|
|
begin
|
|
Result := 0;
|
|
end;
|
|
|
|
function TcxvgMultiRecordsScrollStrategy.GetLeftVisibleBand: Integer;
|
|
begin
|
|
Result := 0;
|
|
end;
|
|
|
|
function TcxvgMultiRecordsScrollStrategy.GetVisibleBandCount: Integer;
|
|
begin
|
|
Result := 1;
|
|
end;
|
|
|
|
function TcxvgMultiRecordsScrollStrategy.GetVisibleValueCount: Integer;
|
|
var
|
|
ACount, ARecordSpace, ARecordsWidth: Integer;
|
|
begin
|
|
with FViewInfo do
|
|
begin
|
|
ARecordSpace := cxSetValue(RecordsInterval = 0, VertLineWidth,
|
|
2 * VertLineWidth + RecordsInterval);
|
|
ARecordsWidth := cxRectWidth(ClientRect) - VertLineWidth -
|
|
FFullHeaderWidth + (ARecordSpace - VertLineWidth);
|
|
ACount := Max(1, ARecordsWidth div (ViewValueWidth + ARecordSpace));
|
|
end;
|
|
Result := Min(ACount, VerticalGrid.RecordCount);
|
|
end;
|
|
|
|
procedure TcxvgMultiRecordsScrollStrategy.SetLeftVisibleBand(Value: Integer);
|
|
begin
|
|
end;
|
|
|
|
procedure TcxvgMultiRecordsScrollStrategy.SetLeftVisibleRecord(Value: Integer);
|
|
var
|
|
ARecordIndex: Integer;
|
|
begin
|
|
ARecordIndex := Value;
|
|
CheckLeftVisibleRecord(ARecordIndex);
|
|
if FLeftVisibleRecord <> ARecordIndex then
|
|
begin
|
|
FLeftVisibleRecord := ARecordIndex;
|
|
VerticalGrid.LayoutChanged;
|
|
end;
|
|
end;
|
|
|
|
function TcxvgMultiRecordsScrollStrategy.GetRecordsInterval: Integer;
|
|
begin
|
|
Result := TcxMultiRecordViewInfo(ViewInfo).RecordsInterval;
|
|
end;
|
|
|
|
{ TcxvgBandsScrollStrategy }
|
|
|
|
procedure TcxvgBandsScrollStrategy.CheckDecreaseTopIndex(AScrollRectHeight: Integer);
|
|
var
|
|
ALeftBand: Integer;
|
|
begin
|
|
ALeftBand := Max(0, BandsInfo.Count - VisibleBandCount);
|
|
if ALeftBand < FLeftVisibleBand then
|
|
begin
|
|
FLeftVisibleBand := ALeftBand;
|
|
VerticalGrid.DoLeftVisibleBandIndexChanged;
|
|
end;
|
|
FTopVisibleRowIndex := GetFirstRowByBandIndex(FLeftVisibleBand).VisibleIndex;
|
|
end;
|
|
|
|
function TcxvgBandsScrollStrategy.CheckTopVisibleIndex(
|
|
AIndex, AStep: Integer): Integer;
|
|
var
|
|
ARow: TcxCustomRow;
|
|
ABandIndex: Integer;
|
|
begin
|
|
ARow := ViewInfo.VisibleRows[AIndex];
|
|
ABandIndex := GetBandIndexByRowIndex(AIndex);
|
|
if ARow <> GetFirstRowByBandIndex(ABandIndex) then
|
|
begin
|
|
Inc(ABandIndex, AStep);
|
|
ARow := GetFirstRowByBandIndex(ABandIndex);
|
|
end;
|
|
if ARow <> nil then
|
|
begin
|
|
AIndex := ARow.VisibleIndex;
|
|
if FLeftVisibleBand <> ABandIndex then
|
|
begin
|
|
FLeftVisibleBand := ABandIndex;
|
|
VerticalGrid.DoLeftVisibleBandIndexChanged;
|
|
end;
|
|
end;
|
|
Result := AIndex;
|
|
end;
|
|
|
|
function TcxvgBandsScrollStrategy.GetBandIndexByRowIndex(
|
|
ARowIndex: Integer): Integer;
|
|
var
|
|
I, AFirstIndex: Integer;
|
|
ABandInfo: TBandInfo;
|
|
begin
|
|
Result := -1;
|
|
for I := 0 to FBandsInfo.Count - 1 do
|
|
begin
|
|
ABandInfo := BandsInfo[I];
|
|
AFirstIndex := ABandInfo.FirstRow.VisibleIndex;
|
|
if (ARowIndex >= AFirstIndex) and (ARowIndex < AFirstIndex + ABandInfo.RowsCount) then
|
|
begin
|
|
Result := I;
|
|
break;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgBandsScrollStrategy.InitHScrollBarParameters;
|
|
begin
|
|
if IsRecordsScrollMode then
|
|
inherited InitHScrollBarParameters
|
|
else
|
|
VerticalGrid.SetScrollBarInfo(sbHorizontal, 0, BandsInfo.Count - 1, 1,
|
|
VisibleBandCount, LeftVisibleBand, not IsHideHScrollBar, True);
|
|
end;
|
|
|
|
function TcxvgBandsScrollStrategy.IsHideVScrollBar: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
procedure TcxvgBandsScrollStrategy.RecalcBandsInfo;
|
|
var
|
|
I, ARowCount, AHeight, ABandIndex, AClientHeight: Integer;
|
|
ARow, AFirstRow: TcxCustomRow;
|
|
ARowViewInfo: TcxCustomRowViewInfo;
|
|
begin
|
|
FBandsInfo.Clear;
|
|
ARowCount := 0;
|
|
ABandIndex := 0;
|
|
with ViewInfo do
|
|
begin
|
|
AHeight := HorzLineWidth;
|
|
ViewValueWidth := GetViewValueWidth;
|
|
AClientHeight := cxRectHeight(ClientRect); // for LayoutStyleChanged
|
|
I := 0;
|
|
while I < VisibleRowCount do
|
|
begin
|
|
ARow := VisibleRows[I];
|
|
ARowViewInfo := ARow.ViewInfo;
|
|
ARowViewInfo.CalculatedHeight := GetRowHeight(ARowViewInfo, ViewBandWidth);
|
|
if AHeight + ARowViewInfo.CalculatedHeight + HorzLineWidth > AClientHeight then
|
|
begin
|
|
AFirstRow := VisibleRows[I - ARowCount];
|
|
if ARowCount = 0 then
|
|
begin
|
|
ARowCount := 1;
|
|
AFirstRow := VisibleRows[I];
|
|
AHeight := ARowViewInfo.CalculatedHeight + HorzLineWidth;
|
|
end
|
|
else Dec(I);
|
|
BandsInfo.Add(ABandIndex, ARowCount, AHeight, AFirstRow);
|
|
AHeight := HorzLineWidth;
|
|
ARowCount := 0;
|
|
Inc(ABandIndex);
|
|
Inc(I);
|
|
continue;
|
|
end;
|
|
Inc(AHeight, ARowViewInfo.CalculatedHeight + HorzLineWidth);
|
|
Inc(ARowCount);
|
|
Inc(I);
|
|
end;
|
|
if ARowCount <> 0 then
|
|
BandsInfo.Add(ABandIndex, ARowCount, AHeight, VisibleRows[I - ARowCount]);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgBandsScrollStrategy.SetRowMaxVisible(ARow: TcxCustomRow);
|
|
begin
|
|
SetTopVisibleRowIndexAndBand(GetBandViewRowMaxVisibleTopIndex(ARow));
|
|
end;
|
|
|
|
function TcxvgBandsScrollStrategy.CanCalcRowsOnTheNextBand(
|
|
ALeft, ANextBandIndex: Integer): Boolean;
|
|
var
|
|
X: Integer;
|
|
begin
|
|
Result := True;
|
|
if IsBehindRightClientEdge(ALeft + BandWidth + FViewInfo.BandsInterval + 1) then
|
|
begin
|
|
if VerticalGrid.OptionsView.AutoScaleBands then
|
|
begin
|
|
X := (ALeft + BandWidth) - FViewInfo.ClientRect.Right;
|
|
if X > ANextBandIndex then Result := False;
|
|
end
|
|
else
|
|
Result := False;
|
|
end;
|
|
end;
|
|
|
|
function TcxvgBandsScrollStrategy.GetBandInterval: Integer;
|
|
begin
|
|
Result := FViewInfo.BandsInterval;
|
|
end;
|
|
|
|
function TcxvgBandsScrollStrategy.GetBandViewRowMaxVisibleTopIndex(
|
|
ARow: TcxCustomRow): Integer;
|
|
var
|
|
AFirstBandIndex, ALastBandIndex, AVisBandsCount: Integer;
|
|
ABottomChild: TcxCustomRow;
|
|
begin
|
|
AFirstBandIndex := GetBandIndexByRowIndex(ARow.VisibleIndex);
|
|
ABottomChild := GetBottomVisibleChild(ARow);
|
|
if (ABottomChild <> nil) and (ABottomChild <> ARow) then
|
|
begin
|
|
ALastBandIndex := GetBandIndexByRowIndex(ABottomChild.VisibleIndex);
|
|
AVisBandsCount := VisibleBandCount;
|
|
if ALastBandIndex - AFirstBandIndex > AVisBandsCount then
|
|
begin
|
|
Result := ARow.VisibleIndex;
|
|
Exit;
|
|
end;
|
|
if AFirstBandIndex + AVisBandsCount > ALastBandIndex then
|
|
begin
|
|
AFirstBandIndex := Max(0, ALastBandIndex - AVisBandsCount + 1);
|
|
Result := GetFirstRowByBandIndex(AFirstBandIndex).VisibleIndex;
|
|
Exit;
|
|
end;
|
|
end;
|
|
Result := ARow.VisibleIndex;
|
|
end;
|
|
|
|
function TcxvgBandsScrollStrategy.GetLeftVisibleBand: Integer;
|
|
begin
|
|
Result := FLeftVisibleBand;
|
|
end;
|
|
|
|
function TcxvgBandsScrollStrategy.GetVisibleBandCount: Integer;
|
|
var
|
|
W, AIndents: Integer;
|
|
begin
|
|
W := Max(1, ViewInfo.ViewBandWidth); // W = 0 ???
|
|
AIndents := FBandsInfo.Count - 1 * TcxBandsViewInfo(ViewInfo).BandsInterval;
|
|
Result := Min(BandsInfo.Count, Max(1, (cxRectWidth(ViewInfo.ClientRect) - AIndents) div W));
|
|
end;
|
|
|
|
function TcxvgBandsScrollStrategy.GetVisibleValueCount: Integer;
|
|
begin
|
|
Result := 1;
|
|
end;
|
|
|
|
function TcxvgBandsScrollStrategy.IsRecordsScrollMode: Boolean;
|
|
begin
|
|
Result := Controller.CanChangeRecord;
|
|
end;
|
|
|
|
procedure TcxvgBandsScrollStrategy.SetLeftVisibleBand(Value: Integer);
|
|
var
|
|
AFirstRow: TcxCustomRow;
|
|
begin
|
|
cxRange(Value, 0, BandsInfo.Count - VisibleBandCount);
|
|
if FLeftVisibleBand <> Value then
|
|
begin
|
|
FLeftVisibleBand := Value;
|
|
AFirstRow := GetFirstRowByBandIndex(Value);
|
|
if AFirstRow = nil then
|
|
FTopVisibleRowIndex := 0
|
|
else
|
|
FTopVisibleRowIndex := AFirstRow.VisibleIndex;
|
|
VerticalGrid.LayoutChanged;
|
|
end;
|
|
end;
|
|
|
|
{ TcxvgScroller }
|
|
|
|
constructor TcxvgScroller.Create(AVerticalGrid: TcxCustomVerticalGrid);
|
|
begin
|
|
FVerticalGrid := AVerticalGrid;
|
|
end;
|
|
|
|
destructor TcxvgScroller.Destroy;
|
|
begin
|
|
FreeAndNil(FScrollStrategy);
|
|
inherited Destroy;
|
|
end;
|
|
|
|
function TcxvgScroller.GoToFirst: Boolean;
|
|
begin
|
|
Result := ScrollStrategy.FocusNextRecord(-1, True);
|
|
end;
|
|
|
|
function TcxvgScroller.GoToLast: Boolean;
|
|
begin
|
|
Result := ScrollStrategy.FocusNextRecord(-1, False);
|
|
end;
|
|
|
|
function TcxvgScroller.GoToNext: Boolean;
|
|
begin
|
|
Result := ScrollStrategy.FocusNextRecord(FocusedRecordIndex, True);
|
|
end;
|
|
|
|
function TcxvgScroller.GoToPrev: Boolean;
|
|
begin
|
|
Result := ScrollStrategy.FocusNextRecord(FocusedRecordIndex, False);
|
|
end;
|
|
|
|
function TcxvgScroller.GetBandIndexByRowIndex(
|
|
ARowIndex: Integer): Integer;
|
|
begin
|
|
Result := FScrollStrategy.GetBandIndexByRowIndex(ARowIndex);
|
|
end;
|
|
|
|
procedure TcxvgScroller.InitScrollBarsParameters;
|
|
begin
|
|
with ScrollStrategy do
|
|
begin
|
|
InitHScrollBarParameters;
|
|
InitVScrollBarParameters;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgScroller.RecalcBandsInfo;
|
|
begin
|
|
FScrollStrategy.RecalcBandsInfo;
|
|
CheckDecreaseLeftIndex;
|
|
CheckDecreaseTopIndex;
|
|
end;
|
|
|
|
procedure TcxvgScroller.RecreateScrollStrategy;
|
|
begin
|
|
FreeAndNil(FScrollStrategy);
|
|
FScrollStrategy := CreateScrollStrategy(Self);
|
|
end;
|
|
|
|
procedure TcxvgScroller.Scroll(AScrollBarKind: TScrollBarKind;
|
|
AScrollCode: TScrollCode; var AScrollPos: Integer);
|
|
begin
|
|
if AScrollBarKind = sbHorizontal then
|
|
FScrollStrategy.ScrollH(AScrollCode, AScrollPos)
|
|
else
|
|
FScrollStrategy.ScrollV(AScrollCode, AScrollPos);
|
|
end;
|
|
|
|
function TcxvgScroller.SetRecordVisible(ARecordIndex: Integer): Boolean;
|
|
var
|
|
ACount, AOldLeftVisibleRecord: Integer;
|
|
begin
|
|
Result := False;
|
|
if (ARecordIndex < 0) or (ARecordIndex > VerticalGrid.RecordCount - 1) then Exit;
|
|
AOldLeftVisibleRecord := LeftVisibleRecord;
|
|
if (ARecordIndex < AOldLeftVisibleRecord) then
|
|
LeftVisibleRecord := ARecordIndex
|
|
else
|
|
begin
|
|
ACount := VisibleValueCount;
|
|
if AOldLeftVisibleRecord + ACount <= ARecordIndex then
|
|
LeftVisibleRecord := ARecordIndex - ACount + 1;
|
|
end;
|
|
Result := LeftVisibleRecord <> AOldLeftVisibleRecord;
|
|
end;
|
|
|
|
procedure TcxvgScroller.SetRowMaxVisible(ARow: TcxCustomRow);
|
|
begin
|
|
if (ARow = nil) or (ARow.VisibleIndex < 0) then Exit;
|
|
if not ARow.Expanded then
|
|
SetRowVisible(ARow)
|
|
else
|
|
ScrollStrategy.SetRowMaxVisible(ARow);
|
|
end;
|
|
|
|
procedure TcxvgScroller.SetRowVisible(ARow: TcxCustomRow);
|
|
var
|
|
AIndex, ATopIndex, ACount, AStep: Integer;
|
|
begin
|
|
AIndex := ARow.VisibleIndex;
|
|
ATopIndex := TopVisibleRowIndex;
|
|
AStep := 0;
|
|
if AIndex < TopVisibleRowIndex then
|
|
ATopIndex := AIndex
|
|
else
|
|
if TopVisibleRowIndex + VisibleRowCount <= AIndex then
|
|
begin
|
|
ACount := GetVisibleCountFromBottom(AIndex);
|
|
if AIndex + 1 - ACount > TopVisibleRowIndex then
|
|
ATopIndex := Max(0, AIndex - ACount + 1);
|
|
AStep := 1;
|
|
end;
|
|
with ScrollStrategy do
|
|
SetTopVisibleRowIndex(CheckTopVisibleIndex(ATopIndex, AStep));
|
|
end;
|
|
|
|
function TcxvgScroller.CreateScrollStrategy(
|
|
AScroller: TcxvgScroller): TcxvgCustomScrollStrategy;
|
|
begin
|
|
Result := VerticalGrid.GetScrollStrategyClass.Create(Self);
|
|
end;
|
|
|
|
procedure TcxvgScroller.LayoutStyleChanged;
|
|
begin
|
|
with VerticalGrid do
|
|
begin
|
|
BeginUpdate;
|
|
try
|
|
DoLayoutChanged;
|
|
LeftVisibleBand := 0;
|
|
FScrollStrategy.SetTopVisibleRowIndex(0);
|
|
if FocusedRow <> nil then SetRowVisible(FocusedRow);
|
|
finally
|
|
if HandleAllocated then
|
|
ViewInfo.FLockDividerPos := False;
|
|
EndUpdate;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgScroller.CheckDecreaseLeftIndex;
|
|
begin
|
|
if FCheckDecreaseLeftIndex then
|
|
begin
|
|
FScrollStrategy.CheckDecreaseLeftIndex;
|
|
FCheckDecreaseLeftIndex := False;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgScroller.CheckDecreaseTopIndex;
|
|
begin
|
|
if not FCheckDecreaseTopIndex or (TopVisibleRowIndex = 0) then Exit;
|
|
with ViewInfo.ClientRect do
|
|
FScrollStrategy.CheckDecreaseTopIndex(Bottom - Top);
|
|
FCheckDecreaseTopIndex := False;
|
|
end;
|
|
|
|
function TcxvgScroller.GetBandsInfo: TBandInfoList;
|
|
begin
|
|
Result := FScrollStrategy.FBandsInfo;
|
|
end;
|
|
|
|
function TcxvgScroller.GetCheckDecrease: Boolean;
|
|
begin
|
|
Result := FCheckDecreaseLeftIndex or FCheckDecreaseTopIndex;
|
|
end;
|
|
|
|
function TcxvgScroller.GetFocusedRecordIndex: Integer;
|
|
begin
|
|
Result := FVerticalGrid.DataController.FocusedRowIndex;
|
|
end;
|
|
|
|
function TcxvgScroller.GetLeftVisibleBand: Integer;
|
|
begin
|
|
Result := FScrollStrategy.LeftVisibleBand;
|
|
end;
|
|
|
|
function TcxvgScroller.GetLeftVisibleRecord: Integer;
|
|
begin
|
|
Result := FScrollStrategy.LeftVisibleRecord;
|
|
end;
|
|
|
|
function TcxvgScroller.GetTopVisibleRowIndex: Integer;
|
|
begin
|
|
Result := FScrollStrategy.TopVisibleRowIndex;
|
|
end;
|
|
|
|
function TcxvgScroller.GetViewInfo: TcxvgCustomViewInfo;
|
|
begin
|
|
Result := FVerticalGrid.ViewInfo;
|
|
end;
|
|
|
|
function TcxvgScroller.GetVisibleCountFromBottom(
|
|
ARowIndex: Integer): Integer;
|
|
begin
|
|
Result := FScrollStrategy.GetVisibleCountFromBottom(ARowIndex, cxRectHeight(ViewInfo.ClientRect));
|
|
end;
|
|
|
|
function TcxvgScroller.GetVisibleRowCount: Integer;
|
|
begin
|
|
Result := FScrollStrategy.GetVisibleRowCount;
|
|
end;
|
|
|
|
function TcxvgScroller.GetVisibleValueCount: Integer;
|
|
begin
|
|
Result := FScrollStrategy.GetVisibleValueCount;
|
|
end;
|
|
|
|
procedure TcxvgScroller.SetCheckDecrease(Value: Boolean);
|
|
begin
|
|
FCheckDecreaseTopIndex := Value;
|
|
FCheckDecreaseLeftIndex := Value;
|
|
end;
|
|
|
|
procedure TcxvgScroller.SetLeftVisibleBand(Value: Integer);
|
|
var
|
|
AOldValue: Integer;
|
|
begin
|
|
with FScrollStrategy do
|
|
begin
|
|
AOldValue := LeftVisibleBand;
|
|
LeftVisibleBand := Value;
|
|
if AOldValue <> LeftVisibleBand then
|
|
FVerticalGrid.DoLeftVisibleBandIndexChanged;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgScroller.SetLeftVisibleRecord(
|
|
Value: Integer);
|
|
var
|
|
AOldValue: Integer;
|
|
begin
|
|
with FScrollStrategy do
|
|
begin
|
|
AOldValue := LeftVisibleRecord;
|
|
LeftVisibleRecord := Value;
|
|
if AOldValue <> LeftVisibleRecord then
|
|
begin
|
|
FVerticalGrid.ViewInfo.Calculate;
|
|
FVerticalGrid.DoLeftVisibleRecordIndexChanged;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgScroller.SetTopVisibleRowIndex(Value: Integer);
|
|
begin
|
|
with ScrollStrategy do
|
|
SetTopVisibleRowIndex(CheckTopVisibleIndex(Value, 0));
|
|
end;
|
|
|
|
{ TcxCustomVerticalGrid }
|
|
|
|
constructor TcxCustomVerticalGrid.Create(AOwner: TComponent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
FImageChangeLink := TChangeLink.Create;
|
|
FImageChangeLink.OnChange := ImageListChange;
|
|
FCategoryFont := TFont.Create;
|
|
FCategoryFont.Style := [fsBold];
|
|
FCategoryFont.OnChange := CategoryFontChanged;
|
|
SetBounds(Left, Top, 150, 200);
|
|
end;
|
|
|
|
destructor TcxCustomVerticalGrid.Destroy;
|
|
begin
|
|
FreeAndNil(FImageChangeLink);
|
|
FreeAndNil(FCategoryFont);
|
|
inherited Destroy;
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.Add(ARowClass: TcxCustomRowClass): TcxCustomRow;
|
|
begin
|
|
CheckRowClass(ARowClass);
|
|
Result := ARowClass.Create(Owner);
|
|
Result.SetVerticalGrid(Self);
|
|
FRows.Add(Result);
|
|
LayoutChanged;
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.AddChild(AParent: TcxCustomRow;
|
|
ARowClass: TcxCustomRowClass): TcxCustomRow;
|
|
begin
|
|
if AParent = nil then
|
|
begin
|
|
Result := Add(ARowClass);
|
|
Exit;
|
|
end;
|
|
CheckRowClass(ARowClass);
|
|
Result := ARowClass.Create(Owner);
|
|
Result.SetVerticalGrid(Self);
|
|
FRows.AddChild(AParent, Result);
|
|
LayoutChanged;
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.AssignRows(Source: TcxCustomVerticalGrid);
|
|
begin
|
|
if Source <> nil then
|
|
Rows.AssignRows(Source.Rows);
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.ClearRows;
|
|
begin
|
|
FClearingRows := True;
|
|
BeginUpdate;
|
|
try
|
|
DataController.BeginUpdateFields;
|
|
try
|
|
Controller.Clear;
|
|
Rows.Clear;
|
|
finally
|
|
DataController.EndUpdateFields;
|
|
end;
|
|
finally
|
|
EndUpdate;
|
|
FClearingRows := False;
|
|
end;
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.FirstRow: TcxCustomRow;
|
|
begin
|
|
if HasRows then Result := FRootRow.Rows[0] else Result := nil;
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.FirstVisibleRow: TcxCustomRow;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := nil;
|
|
Rows.CheckList;
|
|
for I := 0 to FRootRow.Count - 1 do
|
|
if FRootRow.Rows[I].Visible then
|
|
begin
|
|
Result := FRootRow.Rows[I];
|
|
break;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.FocusRow(ARow: TcxCustomRow;
|
|
ACellIndex: Integer = 0);
|
|
begin
|
|
with Controller do
|
|
begin
|
|
SetFocusedRowAndCell(ARow, ACellIndex);
|
|
MakeFocusedItemVisible;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.FullCollapse;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if HasRows then
|
|
begin
|
|
BeginUpdate;
|
|
try
|
|
for I := 0 to FRootRow.Count - 1 do
|
|
FRootRow.Rows[I].Collapse(True);
|
|
finally
|
|
EndUpdate;
|
|
end;
|
|
end
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.FullExpand;
|
|
begin
|
|
if HasRows then
|
|
begin
|
|
BeginUpdate;
|
|
try
|
|
FRootRow.Expand(True);
|
|
finally
|
|
EndUpdate;
|
|
end;
|
|
end
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.HasRows: Boolean;
|
|
begin
|
|
Result := FRootRow.Count > 0
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.HasVisibleRows: Boolean;
|
|
begin
|
|
Result := FirstVisibleRow <> nil;
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.IsInternalDragging: Boolean;
|
|
begin
|
|
Result := Controller.IsInternalDragging;
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.IsRowVisible(ARow: TcxCustomRow): Boolean;
|
|
begin
|
|
Result := False;
|
|
Rows.CheckList;
|
|
if ARow.Visible then
|
|
repeat
|
|
ARow := ARow.FParent;
|
|
if (ARow = FRootRow) then
|
|
begin
|
|
Result := True;
|
|
Exit;
|
|
end
|
|
else
|
|
if not (ARow.Expanded and ARow.Visible) then Exit;
|
|
until False;
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.LastRow: TcxCustomRow;
|
|
begin
|
|
if Rows.Count > 0 then
|
|
Result := Rows.GetRow(Rows.Count - 1)
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.LastVisibleRow: TcxCustomRow;
|
|
var
|
|
I: Integer;
|
|
ARow: TcxCustomRow;
|
|
begin
|
|
Result := nil;
|
|
for I := Rows.Count - 1 downto 0 do
|
|
begin
|
|
ARow := Rows.GetRow(I);
|
|
if IsRowVisible(ARow) then
|
|
begin
|
|
Result := ARow;
|
|
break;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.NextRow(ARow: TcxCustomRow): TcxCustomRow;
|
|
var
|
|
AIndex: Integer;
|
|
begin
|
|
Rows.CheckList;
|
|
if ARow = nil then
|
|
Result := FirstRow
|
|
else
|
|
begin
|
|
AIndex := Rows.FList.IndexOf(ARow) + 1;
|
|
if (AIndex > 0) and (AIndex < Rows.Count) then
|
|
Result := Rows[AIndex]
|
|
else
|
|
Result := nil;
|
|
end;
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.NextVisibleRow(
|
|
ARow: TcxCustomRow): TcxCustomRow;
|
|
var
|
|
I, AIndex: Integer;
|
|
begin
|
|
Rows.CheckList;
|
|
if ARow = nil then
|
|
Result := FirstVisibleRow
|
|
else
|
|
begin
|
|
Result := nil;
|
|
AIndex := Rows.FList.IndexOf(ARow) + 1;
|
|
if AIndex > 0 then
|
|
for I := AIndex to Rows.Count - 1 do
|
|
begin
|
|
ARow := Rows[I];
|
|
if IsRowVisible(ARow) then
|
|
begin
|
|
Result := ARow;
|
|
break;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.PrevRow(ARow: TcxCustomRow): TcxCustomRow;
|
|
var
|
|
AIndex: Integer;
|
|
begin
|
|
Rows.CheckList;
|
|
if ARow = nil then
|
|
Result := LastRow
|
|
else
|
|
begin
|
|
AIndex := Rows.FList.IndexOf(ARow);
|
|
if (AIndex > 0) then Result := Rows[AIndex - 1] else Result := nil;
|
|
end;
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.PrevVisibleRow(ARow: TcxCustomRow): TcxCustomRow;
|
|
var
|
|
I, AIndex: Integer;
|
|
begin
|
|
Rows.CheckList;
|
|
if ARow = nil then
|
|
Result := LastVisibleRow
|
|
else
|
|
begin
|
|
Result := nil;
|
|
AIndex := Rows.FList.IndexOf(ARow);
|
|
if AIndex > 0 then
|
|
for I := AIndex - 1 downto 0 do
|
|
begin
|
|
ARow := Rows[I];
|
|
if IsRowVisible(ARow) then
|
|
begin
|
|
Result := ARow;
|
|
break;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.Remove(ARow: TcxCustomRow);
|
|
begin
|
|
FreeAndNil(ARow);
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.RowByCaption(const ACaption: string): TcxCustomRow;
|
|
|
|
function CheckCaption(ARow: TcxCustomRow): Boolean;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if ARow.FProperties is TcxCaptionRowProperties then
|
|
with TcxCaptionRowProperties(ARow.FProperties) do
|
|
Result := CompareText(Caption, ACaption) = 0
|
|
else
|
|
begin
|
|
Result := False;
|
|
if ARow.FProperties is TcxMultiEditorRowProperties then
|
|
with TcxMultiEditorRowProperties(ARow.FProperties) do
|
|
for I := 0 to Editors.Count - 1 do
|
|
if CompareText(Editors[I].Caption, ACaption) = 0 then
|
|
begin
|
|
Result := True;
|
|
break
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
var
|
|
I: Integer;
|
|
ARow: TcxCustomRow;
|
|
begin
|
|
Result := nil;
|
|
for I := 0 to Rows.Count - 1 do
|
|
begin
|
|
ARow := Rows[I];
|
|
if CheckCaption(ARow) then
|
|
begin
|
|
Result := ARow;
|
|
break;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.RowByName(const AName: string): TcxCustomRow;
|
|
var
|
|
I: Integer;
|
|
ARow: TcxCustomRow;
|
|
begin
|
|
Result := nil;
|
|
for I := 0 to Rows.Count - 1 do
|
|
begin
|
|
ARow := Rows[I];
|
|
if CompareText(ARow.Name, AName) = 0 then
|
|
begin
|
|
Result := ARow;
|
|
break;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.RestoreFromIniFile(const AStorageName: string);
|
|
var
|
|
AStorage: TcxStorage;
|
|
begin
|
|
FNewLoadMode := False;
|
|
AStorage := TcxStorage.Create(AStorageName);
|
|
try
|
|
BeginUpdate;
|
|
BeforeLoadedRows;
|
|
try
|
|
AStorage.Modes := [smChildrenCreating];
|
|
AStorage.RestoreFromIni(Self);
|
|
AfterLoadedRows;
|
|
finally
|
|
EndUpdate;
|
|
end;
|
|
finally
|
|
AStorage.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.RestoreFromRegistry(const AStorageName: string);
|
|
var
|
|
AStorage: TcxStorage;
|
|
begin
|
|
FNewLoadMode := False;
|
|
AStorage := TcxStorage.Create(AStorageName);
|
|
try
|
|
BeginUpdate;
|
|
BeforeLoadedRows;
|
|
try
|
|
AStorage.Modes := [smChildrenCreating];
|
|
AStorage.RestoreFromRegistry(Self);
|
|
AfterLoadedRows;
|
|
finally
|
|
EndUpdate;
|
|
end;
|
|
finally
|
|
AStorage.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.RestoreFromStream(AStream: TStream);
|
|
var
|
|
AStorage: TcxStorage;
|
|
begin
|
|
FNewLoadMode := False;
|
|
AStorage := TcxStorage.Create(AStream);
|
|
try
|
|
BeginUpdate;
|
|
BeforeLoadedRows;
|
|
try
|
|
AStorage.Modes := [smChildrenCreating];
|
|
AStorage.RestoreFromStream(Self);
|
|
AfterLoadedRows;
|
|
finally
|
|
EndUpdate;
|
|
end;
|
|
finally
|
|
AStorage.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.StoreToIniFile(const AStorageName: string;
|
|
AReCreate: Boolean = True);
|
|
var
|
|
AStorage: TcxStorage;
|
|
begin
|
|
FNewLoadMode := True;
|
|
AStorage := TcxStorage.Create(AStorageName);
|
|
try
|
|
BeginUpdate;
|
|
try
|
|
AStorage.ReCreate := AReCreate;
|
|
AStorage.StoreToIni(Self);
|
|
finally
|
|
EndUpdate;
|
|
end;
|
|
finally
|
|
AStorage.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.StoreToRegistry(const AStorageName: string;
|
|
AReCreate: Boolean = True);
|
|
var
|
|
AStorage: TcxStorage;
|
|
begin
|
|
FNewLoadMode := True;
|
|
AStorage := TcxStorage.Create(AStorageName);
|
|
try
|
|
BeginUpdate;
|
|
try
|
|
AStorage.ReCreate := AReCreate;
|
|
AStorage.StoreToRegistry(Self);
|
|
finally
|
|
EndUpdate;
|
|
end;
|
|
finally
|
|
AStorage.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.StoreToStream(AStream: TStream);
|
|
var
|
|
AStorage: TcxStorage;
|
|
begin
|
|
FNewLoadMode := True;
|
|
AStorage := TcxStorage.Create(AStream);
|
|
try
|
|
BeginUpdate;
|
|
try
|
|
AStorage.StoreToStream(Self);
|
|
finally
|
|
EndUpdate;
|
|
end;
|
|
finally
|
|
AStorage.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.CancelEdit;
|
|
begin
|
|
Controller.EditingController.HideEdit(False);
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.HideEdit;
|
|
begin
|
|
Controller.EditingController.HideEdit(True);
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.ShowEdit;
|
|
begin
|
|
if not OptionsData.Editing then Exit;
|
|
DataController.Edit;
|
|
if CanFocusEx then SetFocus;
|
|
Controller.EditingController.ShowEdit;
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.ShowEditByKey(AKey: Char);
|
|
begin
|
|
if not OptionsData.Editing then Exit;
|
|
DataController.Edit;
|
|
if CanFocusEx then SetFocus;
|
|
with Controller do
|
|
EditingController.ShowEdit(FocusedItem, AKey);
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.ShowEditByMouse(X, Y: Integer; AShift: TShiftState);
|
|
begin
|
|
if not OptionsData.Editing then Exit;
|
|
DataController.Edit;
|
|
if CanFocusEx then SetFocus;
|
|
with Controller do
|
|
EditingController.ShowEdit(FocusedItem, AShift, X, Y);
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.RestoreDefaults;
|
|
begin
|
|
BeginUpdate;
|
|
try
|
|
OptionsBehavior.RestoreDefaults;
|
|
OptionsView.RestoreDefaults;
|
|
Rows.RestoreDefaults;
|
|
finally
|
|
EndUpdate;
|
|
end;
|
|
Modified;
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.GetObjectName: string;
|
|
begin
|
|
if FStoringName <> '' then
|
|
Result := FStoringName
|
|
else
|
|
Result := Name;
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.GetProperties(AProperties: TStrings): Boolean;
|
|
begin
|
|
with AProperties do
|
|
begin
|
|
Add('PaintStyle');
|
|
Add('HeaderWidth');
|
|
Add('ValueWidth');
|
|
Add('NewLoad');
|
|
end;
|
|
Result := True;
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.GetPropertyValue(const AName: string;
|
|
var AValue: Variant);
|
|
begin
|
|
if AName = 'PaintStyle' then
|
|
AValue := OptionsView.PaintStyle
|
|
else
|
|
if AName = 'HeaderWidth' then
|
|
AValue := OptionsView.RowHeaderWidth
|
|
else
|
|
if AName = 'ValueWidth' then
|
|
AValue := OptionsView.ValueWidth
|
|
else
|
|
if AName = 'NewLoad' then
|
|
AValue := 1
|
|
else
|
|
AValue := Null;
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.SetPropertyValue(const AName: string;
|
|
const AValue: Variant);
|
|
begin
|
|
if AName = 'PaintStyle' then
|
|
OptionsView.PaintStyle := AValue
|
|
else
|
|
if AName = 'HeaderWidth' then
|
|
OptionsView.RowHeaderWidth := AValue
|
|
else
|
|
if AName = 'ValueWidth' then
|
|
OptionsView.ValueWidth := AValue
|
|
else
|
|
if AName = 'NewLoad' then
|
|
FNewLoadMode := True;
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.CreateChild(
|
|
const AObjectName, AClassName: string): TObject;
|
|
var
|
|
ARow: TcxCustomRow;
|
|
begin
|
|
if CompareText(AClassName, 'TcxCategoryRow') = 0 then
|
|
begin
|
|
ARow := Add(TcxCategoryRow);
|
|
ARow.Name := CreateUniqueName(Owner, Self, ARow, 'Tcx', 'RuntimeCreatedRow');
|
|
Result := ARow;
|
|
end
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.DeleteChild(const AObjectName: string;
|
|
AObject: TObject);
|
|
begin
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.GetStoredChildren(AChildren: TStringList);
|
|
|
|
function GetStoredRowName(ARow: TcxCustomRow): string;
|
|
begin
|
|
if FNewLoadMode then
|
|
Result := ARow.GetObjectName
|
|
else
|
|
Result := '';
|
|
end;
|
|
|
|
var
|
|
I: Integer;
|
|
begin
|
|
with Rows do
|
|
for I := 0 to Count - 1 do
|
|
AChildren.AddObject(GetStoredRowName(Items[I]), Items[I])
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.DoEndDrag(Target: TObject; X, Y: Integer);
|
|
begin
|
|
inherited DoEndDrag(Target, X, Y);
|
|
DragCursor := FSaveDragCursor;
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.GetChildren(Proc: TGetChildProc; Root: TComponent);
|
|
begin
|
|
FRootRow.GetChildren(Proc, Root);
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.Loaded;
|
|
var
|
|
ASaveLock: Boolean;
|
|
begin
|
|
// need a lock for AutoScaleBands and changing visibility HScrollBar
|
|
ASaveLock := ViewInfo.FLockDividerPos;
|
|
ViewInfo.FLockDividerPos := True;
|
|
try
|
|
inherited Loaded;
|
|
with OptionsBehavior do
|
|
if not FAlwaysShowEditorAssigned then
|
|
InternalSetAlwaysShowEditor(AlwaysShowEditor);
|
|
finally
|
|
ViewInfo.FLockDividerPos := ASaveLock;
|
|
LayoutChanged;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.Notification(AComponent: TComponent; Operation: TOperation);
|
|
begin
|
|
inherited Notification(AComponent, Operation);
|
|
if (Operation = opRemove) and (AComponent = Images) then
|
|
Images := nil;
|
|
end;
|
|
|
|
function cxVerticalGridGetItem(ACaller: TComponent;
|
|
Index: Integer): TComponent;
|
|
begin
|
|
Result := TcxCustomVerticalGrid(ACaller).Rows[Index];
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.SetName(const Value: TComponentName);
|
|
var
|
|
AOldName: TComponentName;
|
|
begin
|
|
AOldName := Name;
|
|
inherited SetName(Value);
|
|
if (Name <> AOldName) and (Name <> '') then
|
|
begin
|
|
RenameComponents(Self, Owner, Name, AOldName, Rows.Count, @cxVerticalGridGetItem);
|
|
if not IsLoading and (Rows.Count > 0) then
|
|
LayoutChanged;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.BoundsChanged;
|
|
begin
|
|
if CreatingWindow then //SC B92213
|
|
LockScrollBars;
|
|
try
|
|
inherited BoundsChanged;
|
|
CheckGridModeBufferCount;
|
|
LayoutChanged;
|
|
finally
|
|
if CreatingWindow then //SC B92213
|
|
UnlockScrollBars;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.FontChanged;
|
|
begin
|
|
Inc(FLockUpdate);
|
|
try
|
|
inherited FontChanged;
|
|
FCategoryFont.Assign(Font);
|
|
FCategoryFont.Style := Font.Style + [fsBold];
|
|
finally
|
|
Dec(FLockUpdate);
|
|
LayoutChanged;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.InitControl;
|
|
begin
|
|
ViewInfo.FLockDividerPos := False;
|
|
inherited InitControl;
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.LookAndFeelChanged(Sender: TcxLookAndFeel;
|
|
AChangedValues: TcxLookAndFeelValues);
|
|
begin
|
|
inherited LookAndFeelChanged(Sender, AChangedValues);
|
|
if lfvSkinName in AChangedValues then
|
|
begin
|
|
if ViewInfo <> nil then RecreateViewInfo;
|
|
if Controller <> nil then Controller.UpdatePaintStyle;
|
|
OptionsView.CheckRowHeaderWidth;
|
|
OptionsView.Changed;
|
|
end;
|
|
if OptionsView.CellAutoHeight then
|
|
LayoutChanged;
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.GetDragObjectClass: TDragControlObjectClass;
|
|
begin
|
|
Result := nil;
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.CreateSubClasses;
|
|
begin
|
|
FRows := TcxVerticalGridRows.Create(Self);
|
|
FRootRow := TcxCategoryRow.Create(nil);
|
|
FRootRow.FParent := nil;
|
|
FRootRow.FVerticalGrid := Self;
|
|
FRootRow.FID := -1;
|
|
inherited CreateSubClasses;
|
|
InitDataController;
|
|
FCustomizing := GetCustomizingClass.Create(Self);
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.DataChanged;
|
|
begin
|
|
if FLockUpdate > 0 then Exit;
|
|
Inc(FLockUpdate);
|
|
try
|
|
inherited DataChanged;
|
|
finally
|
|
Dec(FLockUpdate);
|
|
LayoutChanged;
|
|
end;
|
|
Controller.MakeFocusedRecordVisible;
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.DestroySubClasses;
|
|
begin
|
|
FreeAndNil(FCustomizing);
|
|
FreeAndNil(FRootRow);
|
|
FreeAndNil(FRows);
|
|
inherited DestroySubClasses;
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.DoEdited(
|
|
AItem: TcxCustomInplaceEditContainer);
|
|
begin
|
|
if Assigned(FOnEdited) then
|
|
FOnEdited(Self, TcxCellEdit(AItem).EditRowProperties);
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.DoEditing(
|
|
AItem: TcxCustomInplaceEditContainer): Boolean;
|
|
begin
|
|
Result := True;
|
|
if Assigned(FOnEditing) then
|
|
FOnEditing(Self, TcxCellEdit(AItem).EditRowProperties, Result);
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.DoEditValueChanged(
|
|
AItem: TcxCustomInplaceEditContainer);
|
|
begin
|
|
if Assigned(FOnEditValueChanged) then
|
|
if AItem <> nil then
|
|
FOnEditValueChanged(Self, TcxCellEdit(AItem).EditRowProperties)
|
|
else
|
|
FOnEditValueChanged(Self, nil);
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.DoInplaceEditContainerItemRemoved(
|
|
AItem: TcxCustomInplaceEditContainer);
|
|
begin
|
|
try
|
|
ContainerList.Remove(AItem);
|
|
DataController.RemoveItem(AItem);
|
|
UpdateIndexes;
|
|
finally
|
|
if not (AItem.Owner is TcxCustomMultiEditorRow) then
|
|
// for correct work with collection
|
|
LayoutChanged;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.DoLayoutChanged;
|
|
begin
|
|
if csUpdating in ComponentState then exit;
|
|
ViewInfo.Calculate;
|
|
if Controller <> nil then
|
|
with Controller.Scroller do
|
|
begin
|
|
CheckDecrease := True;
|
|
CheckDecreaseLeftIndex;
|
|
CheckDecreaseTopIndex;
|
|
end;
|
|
if Customizing.Visible then
|
|
Customizing.Update;
|
|
if Assigned(FOnLayoutChanged) then
|
|
FOnLayoutChanged(Self);
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.DragDropImageDisplayRect: TRect;
|
|
begin
|
|
Result := DragHeaderInfo.HeaderCellsRect;
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.DrawDragDropImage(ADragBitmap: TBitmap;
|
|
ACanvas: TcxCanvas);
|
|
var
|
|
AHeaderInfo: TcxCustomRowHeaderInfo;
|
|
ASaveCanvas: TcxCanvas;
|
|
ASaveOrg: TPoint;
|
|
begin
|
|
ASaveCanvas := Painter.FCanvas;
|
|
AHeaderInfo := DragHeaderInfo;
|
|
Painter.FCanvas := ACanvas;
|
|
try
|
|
ASaveOrg := ACanvas.WindowOrg;
|
|
ACanvas.WindowOrg := AHeaderInfo.HeaderCellsRect.TopLeft;
|
|
Painter.DrawHeaderDragImage(AHeaderInfo);
|
|
finally
|
|
ACanvas.WindowOrg := ASaveOrg;
|
|
Painter.FCanvas := ASaveCanvas;
|
|
end;
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.GetControllerClass: TcxCustomControlControllerClass;
|
|
begin
|
|
Result := TcxvgController;
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.GetControlStylesClass: TcxCustomControlStylesClass;
|
|
begin
|
|
Result := TcxVerticalGridStyles;
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.GetDragImageHelperClass: TcxDragImageHelperClass;
|
|
begin
|
|
Result := TcxvgDragImageHelper;
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.GetEditCellDataBindingClass: TcxItemDataBindingClass;
|
|
begin
|
|
Result := TcxItemDataBinding;
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.GetHitTestControllerClass: TcxHitTestControllerClass;
|
|
begin
|
|
Result := TcxvgHitTest;
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.GetOptionsBehaviorClass: TcxControlOptionsBehaviorClass;
|
|
begin
|
|
Result := TcxvgOptionsBehavior;
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.GetOptionsViewClass: TcxControlOptionsViewClass;
|
|
begin
|
|
Result := TcxvgOptionsView;
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.GetPainterClass: TcxCustomControlPainterClass;
|
|
begin
|
|
if OptionsView.PaintStyle = psdotNet then
|
|
Result := TcxvgPainter
|
|
else
|
|
Result := TcxStyle3DPainter
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.HasDragDropImages: Boolean;
|
|
begin
|
|
Result := DragHeaderInfo <> nil;
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.RecreateViewInfo;
|
|
var
|
|
AIndex: Integer;
|
|
begin
|
|
if ViewInfo <> nil then
|
|
begin
|
|
HideEdit;
|
|
AIndex := Controller.Scroller.TopVisibleRowIndex;
|
|
Inc(FLockUpdate);
|
|
try
|
|
inherited RecreateViewInfo;
|
|
finally
|
|
Dec(FLockUpdate);
|
|
Controller.Scroller.TopVisibleRowIndex := AIndex;
|
|
Controller.CheckEdit;
|
|
end;
|
|
end
|
|
else
|
|
inherited RecreateViewInfo;
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.InitDataController;
|
|
begin
|
|
DataController.AppendRecord;
|
|
Controller.FocusedRecordIndex := 0;
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.RemoveRowFromVerticalGrid(ARow: TcxCustomRow);
|
|
begin
|
|
Inc(FLockUpdate);
|
|
try
|
|
if not IsDestroying then
|
|
begin
|
|
if IsDesigning and (Controller.DesignSelectionHelper <> nil) then
|
|
Controller.DesignSelectionHelper.UnselectObject(ARow);
|
|
if ARow = FocusedRow then Controller.Clear;
|
|
end;
|
|
Rows.Remove(ARow);
|
|
ARow.RemoveChildren;
|
|
finally
|
|
Dec(FLockUpdate);
|
|
end;
|
|
LayoutChanged;
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.AfterLoadedRows;
|
|
|
|
procedure SetupIndexes(ARow: TcxCustomRow);
|
|
var
|
|
I, AIndex: Integer;
|
|
begin
|
|
if ARow.Count > 0 then
|
|
begin
|
|
AIndex := 0;
|
|
repeat
|
|
for I := AIndex to ARow.Count - 1 do
|
|
if ARow.Rows[I].FLoadingIndex = AIndex then
|
|
begin
|
|
ARow.Rows[I].Index := AIndex;
|
|
break;
|
|
end;
|
|
Inc(AIndex);
|
|
until AIndex = ARow.Count;
|
|
for I := 0 to ARow.Count - 1 do
|
|
SetupIndexes(ARow.Rows[I]);
|
|
end;
|
|
end;
|
|
|
|
var
|
|
L: TList;
|
|
I: Integer;
|
|
ARow: TcxCustomRow;
|
|
begin
|
|
if not FNewLoadMode then Exit;
|
|
L := TList.Create;
|
|
try
|
|
Rows.PrepareList;
|
|
{$IFDEF DELPHI6}
|
|
L.Assign(Rows.FList);
|
|
{$ELSE}
|
|
L.Capacity := Rows.FList.Capacity;
|
|
for I := 0 to Rows.FList.Count - 1 do
|
|
L.Add(Rows.FList[I]);
|
|
{$ENDIF}
|
|
for I := 0 to L.Count - 1 do
|
|
begin
|
|
ARow := L[I];
|
|
if ARow.FLoadingIndex <> MaxInt then
|
|
ARow.Parent := Rows.FindRowByStoredName(ARow.FLoadingParent);
|
|
end;
|
|
SetupIndexes(FRootRow);
|
|
finally
|
|
L.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.BeforeLoadedRows;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Rows.PrepareList;
|
|
for I := 0 to Rows.Count - 1 do
|
|
Rows[I].FLoadingIndex := MaxInt;
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.CanBandSizing: Boolean;
|
|
begin
|
|
Result := OptionsBehavior.BandSizing and not OptionsView.AutoScaleBands;
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.CheckRowClass(ARowClass: TcxCustomRowClass);
|
|
begin
|
|
if (ARowClass = nil) or not (ARowClass.InheritsFrom(GetEditorRowClass) or
|
|
ARowClass.InheritsFrom(TcxCategoryRow) or ARowClass.InheritsFrom(GetMultiEditorRowClass)) then
|
|
cxVerticalGridError(cxGetResourceString(@cxSvgInvalidRowClass));
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.CheckGridModeBufferCount;
|
|
var
|
|
AIntf: IcxVerticalGridDBDataContoller;
|
|
begin
|
|
if (DataController <> nil) and DataController.IsGridMode and
|
|
DataController.GetInterface(IcxVerticalGridDBDataContoller, AIntf) then
|
|
AIntf.CheckGridModeBufferCount;
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.DoCustomizationVisibleChanged;
|
|
begin
|
|
if Assigned(FOnCustomizationVisibleChanged) then
|
|
FOnCustomizationVisibleChanged(Self);
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.DoDrawBackgroundPart(const R: TRect;
|
|
const AViewParams: TcxViewParams): Boolean;
|
|
begin
|
|
Result := False;
|
|
if Assigned(FOnDrawBackground) then
|
|
FOnDrawBackground(Self, TcxvgPainter(Painter).Canvas, R, AViewParams, Result);
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.DoDrawRowHeader(
|
|
AHeaderViewInfo: TcxCustomRowHeaderInfo): Boolean;
|
|
begin
|
|
Result := False;
|
|
if Assigned(FOnDrawRowHeader) then
|
|
FOnDrawRowHeader(Self, TcxvgPainter(Painter).Canvas, TcxvgPainter(Painter),
|
|
AHeaderViewInfo, Result);
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.DoDrawValue(
|
|
AValueInfo: TcxRowValueInfo): Boolean;
|
|
begin
|
|
Result := False;
|
|
if Assigned(FOnDrawValue) then
|
|
FOnDrawValue(Self, TcxvgPainter(Painter).Canvas, TcxvgPainter(Painter),
|
|
AValueInfo, Result);
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.DoItemChanged(AOldRow: TcxCustomRow;
|
|
AOldCellIndex: Integer);
|
|
begin
|
|
if Assigned(FOnItemChanged) then
|
|
FOnItemChanged(Self, AOldRow, AOldCellIndex);
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.DoLeftVisibleBandIndexChanged;
|
|
begin
|
|
if Assigned(FOnLeftVisibleBandIndexChanged) then
|
|
FOnLeftVisibleBandIndexChanged(Self);
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.DoLeftVisibleRecordIndexChanged;
|
|
begin
|
|
if Assigned(FOnLeftVisibleRecordIndexChanged) then
|
|
FOnLeftVisibleRecordIndexChanged(Self);
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.DoTopRowIndexChanged;
|
|
begin
|
|
if Assigned(FOnTopRowIndexChanged) then
|
|
FOnTopRowIndexChanged(Self);
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.GetCalcHelperClass: TcxvgCustomPaintStyleCalcHelperClass;
|
|
begin
|
|
if LookAndFeel.SkinPainter <> nil then
|
|
Result := TcxvgSkinCalcHelper
|
|
else
|
|
if OptionsView.PaintStyle = psDotNet then
|
|
Result := TcxvgDotNetStyleCalcHelper
|
|
else
|
|
Result := TcxvgStyle3DCalcHelper
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.GetCellAutoHeight: Boolean;
|
|
begin
|
|
Result := OptionsView.CellAutoHeight;
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.GetCustomizingClass: TcxVerticalGridCustomizingClass;
|
|
begin
|
|
Result := TcxVerticalGridCustomizing;
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.GetDefaultViewParams(Index: Integer;
|
|
AData: TObject; out AParams: TcxViewParams);
|
|
|
|
function CalcHelper: TcxvgCustomPaintStyleCalcHelper;
|
|
begin
|
|
Result := ViewInfo.CalcHelper;
|
|
end;
|
|
|
|
begin
|
|
with AParams do
|
|
begin
|
|
Font := Self.Font;
|
|
TextColor := Font.Color;
|
|
Bitmap := nil;
|
|
case Index of
|
|
vgs_Content:
|
|
begin
|
|
Color := CalcHelper.GetContentColor(PcxvgContentParamsData(AData)^.Focused);
|
|
TextColor := CalcHelper.GetContentTextColor;
|
|
end;
|
|
vgs_Header:
|
|
begin
|
|
Color := CalcHelper.GetHeaderColor;
|
|
TextColor := CalcHelper.GetHeaderTextColor;
|
|
end;
|
|
vgs_Category:
|
|
begin
|
|
Font := FCategoryFont;
|
|
Color := CalcHelper.GetCategoryColor;
|
|
TextColor := CalcHelper.GetCategoryTextColor;
|
|
end;
|
|
vgs_IncSearch:
|
|
begin
|
|
Color := clDefault;
|
|
TextColor := clDefault;
|
|
end;
|
|
ecs_Background:
|
|
begin
|
|
Color := CalcHelper.GetBackgroundColor;
|
|
with Styles do
|
|
if (Background <> nil) and (Background.Bitmap <> nil) and not Background.Bitmap.Empty then
|
|
Bitmap := Background.Bitmap;
|
|
end;
|
|
else
|
|
Styles.CallInheritedDefaultViewParams(Index, nil, AParams);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.GetEditorRowClass: TcxCustomRowClass;
|
|
begin
|
|
Result := TcxEditorRow;
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.GetMultiEditorRowClass: TcxCustomRowClass;
|
|
begin
|
|
Result := TcxMultiEditorRow;
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.RowsChanged;
|
|
begin
|
|
if IsLocked then
|
|
begin
|
|
if ViewInfo <> nil then
|
|
ViewInfo.UpdateVisibleRows;
|
|
end
|
|
else
|
|
LayoutChanged;
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.UpdateDesignEditor;
|
|
begin
|
|
if not IsLocked and IsDesigning then
|
|
begin
|
|
LayoutChanged;
|
|
Modified;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.CategoryFontChanged(Sender: TObject);
|
|
begin
|
|
LayoutChanged;
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.GetController: TcxvgController;
|
|
begin
|
|
Result := TcxvgController(FController)
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.GetDragHeaderInfo: TcxCustomRowHeaderInfo;
|
|
begin
|
|
with Controller do
|
|
if DragRow <> nil then
|
|
Result := DragRow.ViewInfo.HeaderInfo
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.GetFocusedRow: TcxCustomRow;
|
|
begin
|
|
Result := Controller.FocusedRow;
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.GetHitTest: TcxvgHitTest;
|
|
begin
|
|
Result := TcxvgHitTest(Controller.HitTestController);
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.GetInplaceEditor: TcxCustomEdit;
|
|
begin
|
|
if IsEditing then
|
|
Result := Controller.EditingController.Edit
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.GetIsEditing: Boolean;
|
|
begin
|
|
Result := Controller.IsEditing;
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.GetLeftVisibleBand: Integer;
|
|
begin
|
|
Result := Controller.Scroller.LeftVisibleBand;
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.GetLeftVisibleRecord: Integer;
|
|
begin
|
|
Result := Controller.Scroller.LeftVisibleRecord;
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.GetOptionsBehavior: TcxvgOptionsBehavior;
|
|
begin
|
|
Result := TcxvgOptionsBehavior(inherited OptionsBehavior);
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.GetOptionsView: TcxvgOptionsView;
|
|
begin
|
|
Result := TcxvgOptionsView(inherited OptionsView);
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.GetPainter: TcxvgPainter;
|
|
begin
|
|
Result := TcxvgPainter(inherited Painter);
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.GetRecordCount: Integer;
|
|
begin
|
|
Result := DataController.RowCount;
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.GetStyles: TcxVerticalGridStyles;
|
|
begin
|
|
Result := TcxVerticalGridStyles(inherited Styles);
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.GetTopVisibleRowIndex: Integer;
|
|
begin
|
|
Result := Controller.Scroller.TopVisibleRowIndex;
|
|
end;
|
|
|
|
function TcxCustomVerticalGrid.GetViewInfo: TcxvgCustomViewInfo;
|
|
begin
|
|
Result := TcxvgCustomViewInfo(inherited ViewInfo);
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.ImageListChange(Sender: TObject);
|
|
begin
|
|
if HandleAllocated and (Sender = Images) then
|
|
LayoutChanged;
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.SetFocusedRow(Value: TcxCustomRow);
|
|
begin
|
|
with Controller do
|
|
begin
|
|
FocusedRow := Value;
|
|
MakeRowVisible(FocusedRow);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.SetImages(Value: TCustomImageList);
|
|
begin
|
|
BeginUpdate;
|
|
try
|
|
cxSetImageList(Value, FImages, FImageChangeLink, Self);
|
|
finally
|
|
EndUpdate;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.SetLeftVisibleBand(Value: Integer);
|
|
begin
|
|
if ViewInfo <> nil then ViewInfo.Calculate;
|
|
Controller.Scroller.LeftVisibleBand := Value;
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.SetLeftVisibleRecord(Value: Integer);
|
|
begin
|
|
if ViewInfo <> nil then ViewInfo.Calculate;
|
|
Controller.Scroller.LeftVisibleRecord := Value;
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.SetOptionsBehavior(Value: TcxvgOptionsBehavior);
|
|
begin
|
|
OptionsBehavior.Assign(Value);
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.SetOptionsView(Value: TcxvgOptionsView);
|
|
begin
|
|
OptionsView.Assign(Value);
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.SetStyles(Value: TcxVerticalGridStyles);
|
|
begin
|
|
Styles.Assign(Value);
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.SetTopVisibleRowIndex(Value: Integer);
|
|
begin
|
|
if ViewInfo <> nil then ViewInfo.Calculate;
|
|
Controller.Scroller.TopVisibleRowIndex := Value;
|
|
end;
|
|
|
|
procedure TcxCustomVerticalGrid.CMDrag(var Message: TCMDrag);
|
|
const
|
|
AcceptedCursors: array[Boolean] of TCursor = (crDrag, crDragCopy);
|
|
begin
|
|
if Controller.DragRow = nil then
|
|
DragCursor := AcceptedCursors[IsCtrlPressed];
|
|
inherited;
|
|
end;
|
|
|
|
{ TcxUnboundVerticalGrid }
|
|
|
|
constructor TcxUnboundVerticalGrid.Create(AOwner: TComponent);
|
|
begin
|
|
FLayoutStyle := ulsSingleRecordView;
|
|
inherited Create(AOwner);
|
|
end;
|
|
|
|
function TcxUnboundVerticalGrid.CanBandSizing: Boolean;
|
|
begin
|
|
Result := (FLayoutStyle <> ulsSingleRecordView) and inherited CanBandSizing;
|
|
end;
|
|
|
|
function TcxUnboundVerticalGrid.GetScrollStrategyClass: TcxvgCustomScrollStrategyClass;
|
|
begin
|
|
if FLayoutStyle = ulsSingleRecordView then
|
|
Result := TcxvgSingleRecordScrollStrategy
|
|
else
|
|
Result := TcxvgBandsScrollStrategy;
|
|
end;
|
|
|
|
function TcxUnboundVerticalGrid.GetViewInfoClass: TcxCustomControlViewInfoClass;
|
|
begin
|
|
if FLayoutStyle = ulsSingleRecordView then
|
|
Result := TcxInspectorViewInfo
|
|
else
|
|
Result := TcxBandsViewInfo;
|
|
end;
|
|
|
|
procedure TcxUnboundVerticalGrid.SetLayoutStyle(Value: TcxvgUnboundLayoutStyle);
|
|
begin
|
|
if FLayoutStyle <> Value then
|
|
begin
|
|
FLayoutStyle := Value;
|
|
RecreateViewInfo;
|
|
ViewInfo.LayoutStyleChanged;
|
|
end;
|
|
end;
|
|
|
|
{ TcxVirtualVerticalGrid }
|
|
|
|
constructor TcxVirtualVerticalGrid.Create(AOwner: TComponent);
|
|
begin
|
|
FLayoutStyle := lsSingleRecordView;
|
|
inherited Create(AOwner);
|
|
end;
|
|
|
|
procedure TcxVirtualVerticalGrid.Assign(Source: TPersistent);
|
|
begin
|
|
if Source is TcxVirtualVerticalGrid then
|
|
with TcxVirtualVerticalGrid(Source) do
|
|
begin
|
|
Self.BeginUpdate;
|
|
inherited Assign(Source);
|
|
try
|
|
Self.LayoutStyle := LayoutStyle;
|
|
finally
|
|
Self.EndUpdate;
|
|
end;
|
|
end
|
|
else
|
|
inherited Assign(Source);
|
|
end;
|
|
|
|
function TcxVirtualVerticalGrid.GetFilterCaption(Index: Integer): string;
|
|
var
|
|
AElement: TcxCustomEditorRowProperties;
|
|
begin
|
|
AElement := GetFilterElementProperties(Index);
|
|
if AElement = nil then
|
|
Result := ''
|
|
else
|
|
Result := AElement.Caption;
|
|
end;
|
|
|
|
function TcxVirtualVerticalGrid.GetFilterCount: Integer;
|
|
var
|
|
I, J: Integer;
|
|
ARow: TcxCustomRow;
|
|
AEditContainer: TcxCellEdit;
|
|
begin
|
|
Result := 0;
|
|
for I := 0 to Rows.Count - 1 do
|
|
begin
|
|
ARow := Rows[I];
|
|
for J := 0 to ARow.GetEditContainerCount - 1 do
|
|
begin
|
|
AEditContainer := ARow.GetEditContainer(J);
|
|
if TcxEditorRowPropertiesOptions(AEditContainer.Options).Filtering and
|
|
(esoFiltering in AEditContainer.PropertiesValue.GetSupportedOperations) then
|
|
Inc(Result);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TcxVirtualVerticalGrid.GetFilterCriteria: TcxFilterCriteria;
|
|
begin
|
|
Result := DataController.Filter;
|
|
end;
|
|
|
|
function TcxVirtualVerticalGrid.GetFilterFieldName(Index: Integer): string;
|
|
begin
|
|
Result := '';
|
|
end;
|
|
|
|
function TcxVirtualVerticalGrid.GetFilterItemLink(Index: Integer): TObject;
|
|
var
|
|
AElement: TcxCustomEditorRowProperties;
|
|
begin
|
|
AElement := GetFilterElementProperties(Index);
|
|
if AElement = nil then
|
|
Result := nil
|
|
else
|
|
Result := TObject(AElement.FEditContainer);
|
|
end;
|
|
|
|
function TcxVirtualVerticalGrid.GetFilterItemLinkID(Index: Integer): Integer;
|
|
var
|
|
AElement: TcxCustomEditorRowProperties;
|
|
begin
|
|
AElement := GetFilterElementProperties(Index);
|
|
if AElement = nil then
|
|
Result := -1
|
|
else
|
|
Result := AElement.FEditContainer.ItemIndex;
|
|
end;
|
|
|
|
function TcxVirtualVerticalGrid.GetItemLinkName(Index: Integer): string;
|
|
var
|
|
AElement: TcxCustomEditorRowProperties;
|
|
begin
|
|
AElement := GetFilterElementProperties(Index);
|
|
if AElement = nil then
|
|
Result := ''
|
|
else
|
|
Result := 'Item' + IntToStr(AElement.ID);
|
|
end;
|
|
|
|
function TcxVirtualVerticalGrid.GetFilterProperties(Index: Integer): TcxCustomEditProperties;
|
|
var
|
|
AElement: TcxCustomEditorRowProperties;
|
|
begin
|
|
AElement := GetFilterElementProperties(Index);
|
|
if AElement = nil then
|
|
Result := nil
|
|
else
|
|
Result := AElement.FEditContainer.PropertiesValue;
|
|
end;
|
|
|
|
function TcxVirtualVerticalGrid.GetFilterValueType(Index: Integer): TcxValueTypeClass;
|
|
var
|
|
AElement: TcxCustomEditorRowProperties;
|
|
begin
|
|
AElement := GetFilterElementProperties(Index);
|
|
if AElement = nil then
|
|
Result := nil
|
|
else
|
|
Result := AElement.FEditContainer.GetEditDataValueTypeClass;
|
|
end;
|
|
|
|
function TcxVirtualVerticalGrid.NavigatorCanAppend: Boolean;
|
|
begin
|
|
Result := Controller.CanAppend(True);
|
|
end;
|
|
|
|
function TcxVirtualVerticalGrid.NavigatorCanDelete: Boolean;
|
|
begin
|
|
Result := Controller.CanDelete(True);
|
|
end;
|
|
|
|
function TcxVirtualVerticalGrid.NavigatorCanEdit: Boolean;
|
|
begin
|
|
Result := OptionsData.Editing;
|
|
end;
|
|
|
|
function TcxVirtualVerticalGrid.NavigatorCanInsert: Boolean;
|
|
begin
|
|
Result := Controller.CanInsert(True);
|
|
end;
|
|
|
|
function TcxVirtualVerticalGrid.NavigatorIsActive: Boolean;
|
|
begin
|
|
Result := DataController.Active;
|
|
end;
|
|
|
|
function TcxVirtualVerticalGrid.NavigatorIsBof: Boolean;
|
|
begin
|
|
Result := DataController.IsBOF;
|
|
end;
|
|
|
|
function TcxVirtualVerticalGrid.NavigatorIsBookmarkAvailable: Boolean;
|
|
begin
|
|
Result := DataController.IsBookmarkAvailable;
|
|
end;
|
|
|
|
function TcxVirtualVerticalGrid.NavigatorIsEditing: Boolean;
|
|
begin
|
|
Result := DataController.IsEditing;
|
|
end;
|
|
|
|
function TcxVirtualVerticalGrid.NavigatorIsEof: Boolean;
|
|
begin
|
|
Result := DataController.IsEOF;
|
|
end;
|
|
|
|
procedure TcxVirtualVerticalGrid.NavigatorClearBookmark;
|
|
begin
|
|
DataController.ClearBookmark;
|
|
end;
|
|
|
|
procedure TcxVirtualVerticalGrid.NavigatorDoAction(AButtonIndex: Integer);
|
|
begin
|
|
with DataController do
|
|
case AButtonIndex of
|
|
NBDI_FIRST:
|
|
GotoFirst;
|
|
NBDI_PRIORPAGE:
|
|
if LayoutStyle = lsMultiRecordView then
|
|
MoveBy(-Controller.Scroller.VisibleValueCount)
|
|
else
|
|
GotoPrev;
|
|
NBDI_PRIOR:
|
|
GotoPrev;
|
|
NBDI_NEXT:
|
|
GotoNext;
|
|
NBDI_NEXTPAGE:
|
|
if LayoutStyle = lsMultiRecordView then
|
|
MoveBy(Controller.Scroller.VisibleValueCount)
|
|
else
|
|
GotoNext;
|
|
NBDI_LAST:
|
|
GotoLast;
|
|
NBDI_APPEND:
|
|
Controller.AppendRecord;
|
|
NBDI_INSERT:
|
|
Controller.InsertRecord;
|
|
NBDI_DELETE:
|
|
Controller.DeleteSelection;
|
|
NBDI_EDIT:
|
|
ShowEdit;
|
|
NBDI_POST:
|
|
begin
|
|
PostEditingData;
|
|
Post;
|
|
end;
|
|
NBDI_CANCEL:
|
|
Cancel;
|
|
NBDI_REFRESH:
|
|
Refresh;
|
|
NBDI_SAVEBOOKMARK:
|
|
SaveBookmark;
|
|
NBDI_GOTOBOOKMARK:
|
|
GotoBookmark;
|
|
NBDI_FILTER:
|
|
DoFilterDialog;
|
|
end;
|
|
end;
|
|
|
|
function TcxVirtualVerticalGrid.NavigatorGetNotifier: TcxNavigatorControlNotifier;
|
|
begin
|
|
Result := FNavigatorNotifier;
|
|
end;
|
|
|
|
function TcxVirtualVerticalGrid.NavigatorIsActionSupported(
|
|
AButtonIndex: Integer): Boolean;
|
|
begin
|
|
Result := AButtonIndex in [NBDI_FIRST..NBDI_FILTER];
|
|
end;
|
|
|
|
procedure TcxVirtualVerticalGrid.RefreshNavigators;
|
|
begin
|
|
if not IsDestroying then FNavigatorNotifier.RefreshNavigatorButtons;
|
|
end;
|
|
|
|
procedure TcxVirtualVerticalGrid.CreateSubClasses;
|
|
begin
|
|
inherited CreateSubClasses;
|
|
FNavigatorNotifier := TcxNavigatorControlNotifier.Create;
|
|
end;
|
|
|
|
procedure TcxVirtualVerticalGrid.DestroySubClasses;
|
|
begin
|
|
FreeAndNil(FNavigatorNotifier);
|
|
inherited DestroySubClasses;
|
|
end;
|
|
|
|
function TcxVirtualVerticalGrid.CanBandSizing: Boolean;
|
|
begin
|
|
Result := OptionsBehavior.BandSizing and
|
|
((FLayoutStyle = lsMultiRecordView) or
|
|
((FLayoutStyle = lsBandsView) and not OptionsView.AutoScaleBands));
|
|
end;
|
|
|
|
procedure TcxVirtualVerticalGrid.ControlUpdateData(AInfo: TcxUpdateControlInfo);
|
|
begin
|
|
if IsDestroying then Exit;
|
|
inherited ControlUpdateData(AInfo);
|
|
if (AInfo is TcxSearchChangedInfo) then
|
|
Controller.RefreshIncSearchItem;
|
|
RefreshNavigators;
|
|
end;
|
|
|
|
procedure TcxVirtualVerticalGrid.DoFilterDialog;
|
|
begin
|
|
ExecuteFilterControlDialog(Self, LookAndFeel, ApplyFilter, OnFilterControlDialogShow);
|
|
end;
|
|
|
|
procedure TcxVirtualVerticalGrid.DoFocusedRecordChanged(
|
|
APrevFocusedRecord, AFocusedRecord: Integer);
|
|
begin
|
|
if Assigned(FOnFocusedRecordChanged) then
|
|
FOnFocusedRecordChanged(Self, APrevFocusedRecord, AFocusedRecord);
|
|
end;
|
|
|
|
function TcxVirtualVerticalGrid.GetCellAutoHeight: Boolean;
|
|
begin
|
|
Result := (FLayoutStyle <> lsMultiRecordView) and inherited GetCellAutoHeight;
|
|
end;
|
|
|
|
function TcxVirtualVerticalGrid.GetControllerClass: TcxCustomControlControllerClass;
|
|
begin
|
|
Result := TcxvgMultiRecordsController;
|
|
end;
|
|
|
|
function TcxVirtualVerticalGrid.GetOptionsBehaviorClass: TcxControlOptionsBehaviorClass;
|
|
begin
|
|
Result := TcxvgMultiRecordsOptionsBehavior;
|
|
end;
|
|
|
|
function TcxVirtualVerticalGrid.GetOptionsDataClass: TcxControlOptionsDataClass;
|
|
begin
|
|
Result := TcxvgMultiRecordsOptionsData;
|
|
end;
|
|
|
|
function TcxVirtualVerticalGrid.GetOptionsViewClass: TcxControlOptionsViewClass;
|
|
begin
|
|
Result := TcxvgMultiRecordsOptionsView;
|
|
end;
|
|
|
|
procedure TcxVirtualVerticalGrid.InitDataController;
|
|
begin
|
|
end;
|
|
|
|
procedure TcxVirtualVerticalGrid.DataLayoutChanged;
|
|
begin
|
|
if not DataController.IsGridMode then
|
|
inherited DataLayoutChanged
|
|
else
|
|
LayoutChanged;
|
|
end;
|
|
|
|
function TcxVirtualVerticalGrid.GetScrollStrategyClass: TcxvgCustomScrollStrategyClass;
|
|
begin
|
|
case FLayoutStyle of
|
|
lsSingleRecordView: Result := TcxvgSingleRecordScrollStrategy;
|
|
lsBandsView: Result := TcxvgBandsScrollStrategy;
|
|
else
|
|
Result := TcxvgMultiRecordsScrollStrategy;
|
|
end;
|
|
end;
|
|
|
|
function TcxVirtualVerticalGrid.GetViewInfoClass: TcxCustomControlViewInfoClass;
|
|
begin
|
|
case FLayoutStyle of
|
|
lsSingleRecordView: Result := TcxInspectorViewInfo;
|
|
lsBandsView: Result := TcxBandsViewInfo;
|
|
else
|
|
Result := TcxMultiRecordViewInfo;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxVirtualVerticalGrid.ApplyFilter(Sender: TObject);
|
|
begin
|
|
DataController.Filter.Active := True;
|
|
end;
|
|
|
|
function TcxVirtualVerticalGrid.GetFilterElementProperties(
|
|
AIndex: Integer): TcxCustomEditorRowProperties;
|
|
var
|
|
I, J, K: Integer;
|
|
ARow: TcxCustomRow;
|
|
AEditContainer: TcxCellEdit;
|
|
begin
|
|
K := 0;
|
|
Result := nil;
|
|
for I := 0 to Rows.Count - 1 do
|
|
begin
|
|
ARow := Rows[I];
|
|
for J := 0 to ARow.GetEditContainerCount - 1 do
|
|
begin
|
|
AEditContainer := ARow.GetEditContainer(J);
|
|
if TcxEditorRowPropertiesOptions(AEditContainer.Options).Filtering and
|
|
(esoFiltering in AEditContainer.PropertiesValue.GetSupportedOperations) then
|
|
begin
|
|
if K = AIndex then
|
|
begin
|
|
Result := AEditContainer.FEditRowProperties;
|
|
Exit;
|
|
end;
|
|
Inc(K);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TcxVirtualVerticalGrid.GetFilterRecordEvent: TcxDataFilterRecordEvent;
|
|
begin
|
|
Result := DataController.OnFilterRecord;
|
|
end;
|
|
|
|
function TcxVirtualVerticalGrid.GetFocusedRecordIndex: Integer;
|
|
begin
|
|
Result := DataController.FocusedRowIndex;
|
|
end;
|
|
|
|
function TcxVirtualVerticalGrid.GetController: TcxvgMultiRecordsController;
|
|
begin
|
|
Result := TcxvgMultiRecordsController(FController);
|
|
end;
|
|
|
|
function TcxVirtualVerticalGrid.GetOptionsBehavior: TcxvgMultiRecordsOptionsBehavior;
|
|
begin
|
|
Result := TcxvgMultiRecordsOptionsBehavior(inherited OptionsBehavior);
|
|
end;
|
|
|
|
function TcxVirtualVerticalGrid.GetOptionsData: TcxvgMultiRecordsOptionsData;
|
|
begin
|
|
Result := TcxvgMultiRecordsOptionsData(inherited OptionsData);
|
|
end;
|
|
|
|
function TcxVirtualVerticalGrid.GetOptionsView: TcxvgMultiRecordsOptionsView;
|
|
begin
|
|
Result := TcxvgMultiRecordsOptionsView(inherited OptionsView);
|
|
end;
|
|
|
|
procedure TcxVirtualVerticalGrid.SetFilterRecordEvent(
|
|
Value: TcxDataFilterRecordEvent);
|
|
begin
|
|
DataController.OnFilterRecord := Value;
|
|
end;
|
|
|
|
procedure TcxVirtualVerticalGrid.SetFocusedRecordIndex(Value: Integer);
|
|
begin
|
|
DataController.FocusedRowIndex := Value;
|
|
end;
|
|
|
|
procedure TcxVirtualVerticalGrid.SetLayoutStyle(Value: TcxvgLayoutStyle);
|
|
begin
|
|
if FLayoutStyle <> Value then
|
|
begin
|
|
FLayoutStyle := Value;
|
|
RecreateViewInfo;
|
|
ViewInfo.LayoutStyleChanged;
|
|
CheckGridModeBufferCount;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxVirtualVerticalGrid.SetOptionsBehavior(
|
|
Value: TcxvgMultiRecordsOptionsBehavior);
|
|
begin
|
|
inherited OptionsBehavior.Assign(Value);
|
|
end;
|
|
|
|
procedure TcxVirtualVerticalGrid.SetOptionsData(
|
|
Value: TcxvgMultiRecordsOptionsData);
|
|
begin
|
|
inherited OptionsData.Assign(Value);
|
|
end;
|
|
|
|
procedure TcxVirtualVerticalGrid.SetOptionsView(
|
|
Value: TcxvgMultiRecordsOptionsView);
|
|
begin
|
|
inherited OptionsView.Assign(Value);
|
|
end;
|
|
|
|
{ TcxvgHitTest }
|
|
|
|
function TcxvgHitTest.AllowDesignMouseEvents(X, Y: Integer;
|
|
AShift: TShiftState): Boolean;
|
|
begin
|
|
// we must use GetAsyncKeyState
|
|
if (GetAsyncKeyState(VK_CONTROL) < 0) or (GetAsyncKeyState(VK_MENU) < 0) then
|
|
begin
|
|
Result := False;
|
|
Exit;
|
|
end;
|
|
RecalculateOnMouseEvent(X, Y, AShift);
|
|
Result := (VerticalGrid.DragAndDropState <> ddsNone) or CanSizing or
|
|
HitAtRowHeader;
|
|
end;
|
|
|
|
procedure TcxvgHitTest.CalcBandsHitTest(AViewInfo: TcxvgCustomViewInfo);
|
|
var
|
|
I: Integer;
|
|
R, CR: TRect;
|
|
ABandSizing, AHasDivider: Boolean;
|
|
begin
|
|
with AViewInfo do
|
|
begin
|
|
ABandSizing := VerticalGrid.CanBandSizing;
|
|
AHasDivider := (VerticalGrid.OptionsBehavior.HeaderSizing or
|
|
VerticalGrid.IsDesigning) and ShowHeaders;
|
|
CR := ClientRect;
|
|
for I := 0 to ViewRects.BandRects.Count - 1 do
|
|
begin
|
|
R := ViewRects.BandRects[I];
|
|
if AHasDivider and (I = 0) then
|
|
begin
|
|
// calc divider pos
|
|
CR.Left := R.Left + ViewHeaderWidth;
|
|
CR.Right := CR.Left + DividerWidth + 2;
|
|
if Check(CR) then SetHitState(vghc_HitAtDivider, True);
|
|
end;
|
|
// calc first band right side
|
|
if (I = 0) and ABandSizing and Check(GetBandSizeableRect(R)) then
|
|
SetHitState(vghc_HitAtBandSizing, True);
|
|
if Check(R) then
|
|
begin
|
|
FHitBandIndex := I;
|
|
break;
|
|
end;
|
|
end;
|
|
end;
|
|
CalcRowsHitTest(AViewInfo);
|
|
end;
|
|
|
|
function TcxvgHitTest.CalcCustomizingHitTest: Boolean;
|
|
begin
|
|
Result := False;
|
|
with VerticalGrid.Customizing do
|
|
begin
|
|
if not Visible then Exit;
|
|
Result := CanDrop(VerticalGrid.ClientToScreen(HitPoint));
|
|
if Result then
|
|
SetHitState(vghc_HitAtCustomize, True);
|
|
end;
|
|
end;
|
|
|
|
function TcxvgHitTest.CalcRowHeaderHitTest(
|
|
AHeaderInfo: TcxCustomRowHeaderInfo): Boolean;
|
|
var
|
|
I: Integer;
|
|
ACaptionInfo: TcxRowCaptionInfo;
|
|
begin
|
|
with AHeaderInfo do
|
|
begin
|
|
Result := Check(HeaderRect);
|
|
if not Result then Exit;
|
|
if Check(FButtonRect) then
|
|
SetHitState(vghc_HitAtButton, True)
|
|
else
|
|
if Check(FHeaderCellsRect) then
|
|
for I := 0 to CaptionsInfo.Count - 1 do
|
|
begin
|
|
ACaptionInfo := CaptionsInfo[I];
|
|
with ACaptionInfo do
|
|
begin
|
|
if Check(FImageRect) then
|
|
begin
|
|
FHitCellIndex := I;
|
|
SetHitState(vghc_HitAtImage, True);
|
|
end
|
|
else
|
|
if Check(FCaptionRect) then
|
|
begin
|
|
FNewHitTestItem := ACaptionInfo;
|
|
FHitCellIndex := I;
|
|
SetHitState(vghc_HitAtCaption, True);
|
|
end;
|
|
end;
|
|
end
|
|
else
|
|
SetHitState(vghc_HitAtIndent, True);
|
|
end;
|
|
end;
|
|
|
|
function TcxvgHitTest.CalcRowHitTest(
|
|
ARowViewInfo: TcxCustomRowViewInfo): Boolean;
|
|
begin
|
|
with ARowViewInfo do
|
|
begin
|
|
with RowRect do
|
|
Result := Check(cxRect(Left, Top, Right,
|
|
Bottom + TcxvgCustomViewInfo(ViewInfo).HorzLineWidth));
|
|
if not Result then Exit;
|
|
FHitRow := Row;
|
|
if not CalcRowHeaderHitTest(HeaderInfo) and Check(ValuesRect) then
|
|
CalcRowValuesHitTest(ARowViewInfo)
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgHitTest.CalcRowValuesHitTest(
|
|
ARowViewInfo: TcxCustomRowViewInfo);
|
|
var
|
|
I: Integer;
|
|
AValueInfo: TcxRowValueInfo;
|
|
AUseValue: Boolean;
|
|
begin
|
|
AUseValue := TcxvgController(Controller).ResizeKind = rkNone;
|
|
with ARowViewInfo do
|
|
for I := 0 to ValuesInfo.Count - 1 do
|
|
begin
|
|
AValueInfo := ValuesInfo[I];
|
|
if Check(AValueInfo.VisibleRect) then
|
|
begin
|
|
if AUseValue then
|
|
begin
|
|
FNewHitTestItem := AValueInfo;
|
|
FHitCellIndex := AValueInfo.RowCellIndex;
|
|
end;
|
|
SetHitState(vghc_HitAtValue, True);
|
|
break;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgHitTest.CalcRowsHitTest(
|
|
AViewInfo: TcxvgCustomViewInfo);
|
|
var
|
|
I: Integer;
|
|
ARowSizing: Boolean;
|
|
ARowViewInfo: TcxCustomRowViewInfo;
|
|
begin
|
|
with AViewInfo do
|
|
begin
|
|
ARowSizing := VerticalGrid.OptionsBehavior.RowSizing;
|
|
for I := 0 to RowsViewInfo.Count - 1 do
|
|
begin
|
|
ARowViewInfo := RowsViewInfo[I];
|
|
if ARowSizing and ARowViewInfo.Row.Options.CanResized then
|
|
with ARowViewInfo.RowRect do
|
|
if Check(cxRect(Left, Bottom - 1, Right, Min(Bottom + 1,
|
|
ClientRect.Bottom))) then
|
|
begin
|
|
FHitRow := ARowViewInfo.Row;
|
|
SetHitState(vghc_HitAtRowSizing, True);
|
|
Exit;
|
|
end;
|
|
if CalcRowHitTest(ARowViewInfo) then Exit;
|
|
end;
|
|
SetHitState(vghc_HitAtEmpty, True);
|
|
end;
|
|
end;
|
|
|
|
function TcxvgHitTest.CanMoving: Boolean;
|
|
var
|
|
ADirection: TcxDragSizingDirection;
|
|
begin
|
|
Result := ((VerticalGrid.DragMode = dmAutomatic)) and (HitRow <> nil) and
|
|
HitRow.Options.Moving and HitAtCaption and not CanSizing(ADirection);
|
|
end;
|
|
|
|
function TcxvgHitTest.CanSizing: Boolean;
|
|
var
|
|
ADirection: TcxDragSizingDirection;
|
|
begin
|
|
Result := CanSizing(ADirection);
|
|
end;
|
|
|
|
function TcxvgHitTest.CanSizing(var ASizeDirection: TcxDragSizingDirection): Boolean;
|
|
begin
|
|
Result := HitAtRowSizing or HitAtBandSizing or HitAtDivider;
|
|
if not Result then Exit;
|
|
if HitAtRowSizing then
|
|
ASizeDirection := dsdVert
|
|
else
|
|
ASizeDirection := dsdHorz;
|
|
end;
|
|
|
|
function TcxvgHitTest.Check(const ARect: TRect): Boolean;
|
|
begin
|
|
Result := cxRectPtIn(ARect, HitPoint);
|
|
end;
|
|
|
|
procedure TcxvgHitTest.DoCalculate;
|
|
begin
|
|
FHitRow := nil;
|
|
FNewHitTestItem := nil;
|
|
FHitBandIndex := -1;
|
|
FHitCellIndex := -1;
|
|
FHitState := FHitState and 3;
|
|
FHitInControl := Check(VerticalGrid.ClientBounds);
|
|
if not CalcCustomizingHitTest and FHitInControl then
|
|
CalcBandsHitTest(VerticalGrid.ViewInfo);
|
|
HitTestItem := FNewHitTestItem;
|
|
end;
|
|
|
|
function TcxvgHitTest.GetCurrentCursor: TCursor;
|
|
var
|
|
ADirection: TcxDragSizingDirection;
|
|
const
|
|
ACursors: array[TcxDragSizingDirection] of TCursor = (crHSplit, crVSplit);
|
|
begin
|
|
Result := inherited GetCurrentCursor;
|
|
if (VerticalGrid.DragAndDropState <> ddsNone) and
|
|
not (VerticalGrid.DragAndDropObject is TcxSizingDragAndDropObject) then Exit;
|
|
if Result = crDefault then
|
|
if CanSizing(ADirection) then Result := ACursors[ADirection];
|
|
end;
|
|
|
|
function TcxvgHitTest.GetState(Index: Integer): Boolean;
|
|
begin
|
|
Result := (FHitState and (1 shl Index)) <> 0;
|
|
end;
|
|
|
|
procedure TcxvgHitTest.SetHitState(Index: Integer; Value: Boolean);
|
|
begin
|
|
if Value then
|
|
FHitState := FHitState or (1 shl Index)
|
|
else
|
|
FHitState := FHitState and not (1 shl Index);
|
|
end;
|
|
|
|
function TcxvgHitTest.GetHitAtRowHeader: Boolean;
|
|
begin
|
|
Result := HitAtCaption or HitAtIndent or HitAtImage or HitAtButton;
|
|
end;
|
|
|
|
function TcxvgHitTest.GetVerticalGrid: TcxCustomVerticalGrid;
|
|
begin
|
|
// reduce calls
|
|
Result := TcxCustomVerticalGrid(TcxvgController(Controller).EditingControl);
|
|
end;
|
|
|
|
{ TcxvgCellNavigator }
|
|
|
|
constructor TcxvgCellNavigator.Create(AController: TcxCustomControlController);
|
|
begin
|
|
inherited Create(AController);
|
|
DownOnTab := True;
|
|
DownOnEnter := True;
|
|
end;
|
|
|
|
procedure TcxvgCellNavigator.FocusNextCell(AForward, ANextRow: Boolean;
|
|
AShift: TShiftState = []);
|
|
var
|
|
APrevRowIndex, APrevCellIndex, ARowIndex, ACellIndex: Integer;
|
|
|
|
function IsValidCellIndex(ACount: Integer): Boolean;
|
|
begin
|
|
Result := cxInRange(ACellIndex, 0, ACount - 1) or
|
|
(MayFocusedEmptyRow(ARowIndex) and (ACount = 0));
|
|
end;
|
|
|
|
begin
|
|
Init(APrevRowIndex, APrevCellIndex, RowCount);
|
|
ARowIndex := APrevRowIndex;
|
|
ACellIndex := APrevCellIndex;
|
|
if ANextRow then
|
|
CalcNextRow(AForward, ARowIndex, ACellIndex)
|
|
else
|
|
ACellIndex := APrevCellIndex + cxIntOffs[AForward];
|
|
SelectCell(AForward, ANextRow, ARowIndex, ACellIndex);
|
|
if (ACellIndex < 0) and FindNextRecord(False) then
|
|
ACellIndex := GetContainerCount(ARowIndex) - 1;
|
|
if not IsValidCellIndex(Count[ARowIndex]) then
|
|
begin
|
|
ACellIndex := APrevCellIndex;
|
|
ARowIndex := APrevRowIndex;
|
|
end;
|
|
if (ARowIndex <> APrevRowIndex) or (ACellIndex <> APrevCellIndex) then
|
|
SetFocusCell(ARowIndex, ACellIndex, AShift);
|
|
end;
|
|
|
|
procedure TcxvgCellNavigator.CalcNextRow(AForward: Boolean;
|
|
var ARowIndex, ACellIndex: Integer);
|
|
|
|
function CanCellTabStop(ARowIndex, AIndex: Integer): Boolean;
|
|
var
|
|
ACell: TcxCellEdit;
|
|
begin
|
|
ACell := TcxCellEdit(GetCellContainer(ARowIndex, AIndex));
|
|
Result := (ACell <> nil) and ACell.CanFocus;
|
|
if Result then
|
|
begin
|
|
if ACell.Options is TcxMultiEditorRowPropertiesOptions then
|
|
Result := TcxMultiEditorRowPropertiesOptions(ACell.Options).TabStop;
|
|
end;
|
|
end;
|
|
|
|
function NavigateMultiEditorRow(var AIndex: Integer): Boolean;
|
|
var
|
|
ACount, ARecordIndex: Integer;
|
|
begin
|
|
Result := False;
|
|
if ACellIndex < 0 then Exit;
|
|
ACount := GetContainerCount(ARowIndex);
|
|
ARecordIndex := Max(Controller.FocusedRecordIndex, 0);
|
|
AIndex := (ACellIndex mod ACount) + cxIntOffs[AForward];
|
|
while (AIndex >=0) and (AIndex < ACount) do
|
|
if CanCellTabStop(ARowIndex, AIndex) then
|
|
begin
|
|
Result := True;
|
|
Inc(AIndex, ARecordIndex * ACount);
|
|
break
|
|
end
|
|
else
|
|
Inc(AIndex, cxIntOffs[AForward]);
|
|
end;
|
|
|
|
var
|
|
AIndex, AMin, AMax: Integer;
|
|
begin
|
|
if Controller.ProcessMultiEditorRow and NavigateMultiEditorRow(AIndex) then
|
|
begin
|
|
ACellIndex := AIndex;
|
|
Exit;
|
|
end;
|
|
//calc valid row's index
|
|
AMin := 0;
|
|
AMax := RowCount - 1;
|
|
AIndex := ARowIndex;
|
|
repeat
|
|
Inc(AIndex, cxIntOffs[AForward]);
|
|
if not cxInRange(AIndex, AMin, AMax) then Exit;
|
|
until Rows[AIndex].CanFocus and Rows[AIndex].Options.TabStop;
|
|
ARowIndex := AIndex;
|
|
//calc valid cell's index
|
|
AMax := GetContainerCount(ARowIndex);
|
|
if (AMax = 0) or (Controller.FocusedRecordIndex < 0) then
|
|
Exit;
|
|
AIndex := AMax * Controller.FocusedRecordIndex;
|
|
if (AMax > 1) and not Controller.ProcessMultiEditorRow then
|
|
begin
|
|
//special case (multieditor row)
|
|
if not AForward then Inc(AIndex, AMax - 1);
|
|
while not CanCellTabStop(ARowIndex, AIndex) do
|
|
Inc(AIndex, cxIntOffs[AForward]);
|
|
end
|
|
else
|
|
while not CanCellTabStop(ARowIndex, AIndex) do
|
|
Inc(AIndex);
|
|
ACellIndex := AIndex;
|
|
end;
|
|
|
|
function TcxvgCellNavigator.FindNextRecord(AForward: Boolean): Boolean;
|
|
begin
|
|
Result := Controller.Scroller.ScrollStrategy.FindNextRecord(
|
|
DataController.FocusedRowIndex, AForward) <> -1;
|
|
end;
|
|
|
|
function TcxvgCellNavigator.GetCellContainer(ARowIndex,
|
|
ACellIndex: Integer): TcxCustomInplaceEditContainer;
|
|
var
|
|
ACount: Integer;
|
|
begin
|
|
Result := nil;
|
|
if cxInRange(ARowIndex, 0, RowCount - 1) then
|
|
with Rows[ARowIndex] do
|
|
begin
|
|
ACount := GetEditContainerCount;
|
|
if (ACount > 0) and (ACellIndex >= 0) then
|
|
Result := GetEditContainer(ACellIndex mod ACount);
|
|
end;
|
|
end;
|
|
|
|
function TcxvgCellNavigator.GetContainerCount(
|
|
ARowIndex: Integer): Integer;
|
|
begin
|
|
if cxInRange(ARowIndex, 0, RowCount - 1) then
|
|
Result := Rows[ARowIndex].GetEditContainerCount
|
|
else
|
|
Result := 0;
|
|
end;
|
|
|
|
function TcxvgCellNavigator.GetCount(
|
|
ARowIndex: Integer): Integer;
|
|
begin
|
|
Result := GetContainerCount(ARowIndex) * RecordCount;
|
|
end;
|
|
|
|
procedure TcxvgCellNavigator.Init(var ARowIndex, ACellIndex,
|
|
ARowCount: Integer);
|
|
var
|
|
ARecordIndex: Integer;
|
|
begin
|
|
with Controller do
|
|
begin
|
|
ARowCount := ViewInfo.VisibleRowCount;
|
|
ARecordIndex := Max(0, FocusedRecordIndex);
|
|
if FocusedRow = nil then
|
|
ARowIndex := -1
|
|
else
|
|
ARowIndex := FocusedRow.VisibleIndex;
|
|
if CellIndex < 0 then
|
|
ACellIndex := -1
|
|
else
|
|
ACellIndex := CellIndex + ARecordIndex * Max(1, GetContainerCount(ARowIndex));
|
|
end;
|
|
end;
|
|
|
|
function TcxvgCellNavigator.MayFocusedEmptyRow(ARowIndex: Integer): Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
procedure TcxvgCellNavigator.SetFocusCell(ARowIndex, ACellIndex: Integer; AShift: TShiftState = []);
|
|
var
|
|
ACount, AIndex, ARecord, AFocusedRecord: Integer;
|
|
begin
|
|
ACount := GetContainerCount(ARowIndex);
|
|
if Rows[ARowIndex] <> Controller.FocusedRow then
|
|
with Controller do
|
|
begin
|
|
if (FocusedRecordIndex < 0) and (DataController.RowCount > 0) then
|
|
FocusedRecordIndex := 0;
|
|
if (ACount > 0) then
|
|
AIndex := ACellIndex mod ACount
|
|
else
|
|
AIndex := ACellIndex;
|
|
SetFocusedRowAndCell(Rows[ARowIndex], AIndex);
|
|
end
|
|
else
|
|
begin
|
|
AFocusedRecord := Controller.FocusedRecordIndex;
|
|
ARecord := ACellIndex div Max(ACount, 1);
|
|
if ACount > 0 then AIndex := ACellIndex mod ACount else AIndex := 0;
|
|
if (AFocusedRecord <> -1) and (ARecord <> AFocusedRecord) then
|
|
begin
|
|
if ARecord < AFocusedRecord then
|
|
begin
|
|
if not FindNextRecord(False) then Exit;
|
|
while (AIndex >= 0) and (ACount > 0) and
|
|
not TcxCellEdit(GetCellContainer(ARowIndex, AIndex)).CanFocus do
|
|
Dec(AIndex);
|
|
if AIndex < 0 then Exit;
|
|
end
|
|
else
|
|
begin
|
|
if not FindNextRecord(True) then Exit;
|
|
while (AIndex < ACount) and (ACount > 0) and
|
|
not TcxCellEdit(GetCellContainer(ARowIndex, AIndex)).CanFocus do
|
|
Inc(AIndex);
|
|
if (ACount > 0) and (AIndex = ACount) then Exit;
|
|
end;
|
|
Controller.SetFocusedRecordItem(ARecord, GetCellContainer(ARowIndex, AIndex));
|
|
end
|
|
else
|
|
Controller.SetFocusedRowAndCell(Rows[ARowIndex], AIndex);
|
|
end;
|
|
end;
|
|
|
|
function TcxvgCellNavigator.GetController: TcxvgController;
|
|
begin
|
|
Result := TcxvgController(inherited Controller);
|
|
end;
|
|
|
|
function TcxvgCellNavigator.GetRecordCount: Integer;
|
|
var
|
|
AIntf: IcxVerticalGridDBDataContoller;
|
|
begin
|
|
if DataController.GetInterface(IcxVerticalGridDBDataContoller, AIntf) then
|
|
Result := AIntf.GetDataSetRecordCount
|
|
else
|
|
Result := DataController.RowCount;
|
|
end;
|
|
|
|
function TcxvgCellNavigator.GetRow(Index: Integer): TcxCustomRow;
|
|
begin
|
|
Result := Controller.ViewInfo.VisibleRows[Index];
|
|
end;
|
|
|
|
function TcxvgCellNavigator.GetValueCount: Integer;
|
|
begin
|
|
Result := Max(1, Controller.ViewInfo.VisibleValueCount)
|
|
end;
|
|
|
|
{ TcxvgDragImageHelper }
|
|
|
|
procedure TcxvgDragImageHelper.DragAndDrop(const P: TPoint);
|
|
var
|
|
CP: TPoint;
|
|
begin
|
|
inherited DragAndDrop(P);
|
|
with TcxCustomVerticalGrid(DragControl).Controller do
|
|
begin
|
|
CP := DragControl.ScreenToClient(P);
|
|
HitTest.RecalculateOnMouseEvent(CP.X, CP.Y, []);
|
|
if (FAutoScrollObject <> nil) and not HitTest.HitAtCustomize then
|
|
FAutoScrollObject.CheckBounds(CP);
|
|
end;
|
|
DragControl.DragCursor := GetCursor;
|
|
end;
|
|
|
|
function TcxvgDragImageHelper.GetCursor: TCursor;
|
|
begin
|
|
Result := crcxInspectorNoDrag;
|
|
with TcxCustomVerticalGrid(DragControl), HitTest do
|
|
begin
|
|
if HitAtCustomize then
|
|
Result := crDrag
|
|
else
|
|
if HitAtCaption then
|
|
Result := crcxInspectorAddChild
|
|
else
|
|
if HitAtEmpty then
|
|
Result := crcxInspectorAdd
|
|
else
|
|
if HitInControl then
|
|
Result := crcxInspectorInsert
|
|
end;
|
|
end;
|
|
|
|
{ TcxvgController }
|
|
|
|
constructor TcxvgController.Create(
|
|
AOwner: TcxEditingControl);
|
|
begin
|
|
inherited Create(AOwner);
|
|
FScroller := TcxvgScroller.Create(VerticalGrid);
|
|
FCellIndex := -1;
|
|
end;
|
|
|
|
destructor TcxvgController.Destroy;
|
|
begin
|
|
FScroller.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
function TcxvgController.QueryInterface(const IID: TGUID;
|
|
out Obj): HResult;
|
|
begin
|
|
if GetInterface(IID, Obj) then Result := 0 else Result := cxE_NOINTERFACE;
|
|
end;
|
|
|
|
function TcxvgController.GetCursor(X, Y: Integer): TCursor;
|
|
begin
|
|
if not VerticalGrid.IsDesigning then
|
|
begin
|
|
if Int64(Point(X, Y)) <> Int64(HitTestController.HitPoint) then
|
|
TcxvgHitTest(HitTestController).RecalculateOnMouseEvent(X, Y, []);
|
|
Result := TcxvgHitTest(HitTestController).GetCurrentCursor;
|
|
if Result = crDefault then
|
|
Result := inherited GetCursor(X, Y);
|
|
end
|
|
else
|
|
Result := inherited GetCursor(X, Y);
|
|
end;
|
|
|
|
procedure TcxvgController.KeyDown(var Key: Word;
|
|
Shift: TShiftState);
|
|
var
|
|
AIsMultiEditorRow: Boolean;
|
|
|
|
function CanProcessProcessMultiEditorRow: Boolean;
|
|
var
|
|
AIndex: Integer;
|
|
begin
|
|
Result := False;
|
|
if not AIsMultiEditorRow then Exit;
|
|
with TcxCustomMultiEditorRow(FocusedRow) do
|
|
begin
|
|
AIndex := CellIndex;
|
|
if Key = VK_LEFT then
|
|
begin
|
|
if AIndex > 0 then
|
|
repeat
|
|
Dec(AIndex);
|
|
with Properties.Editors[AIndex].EditContainer do
|
|
if CanFocus and CanTabStop then
|
|
begin
|
|
Result := True;
|
|
Exit;
|
|
end;
|
|
until AIndex = 0;
|
|
end
|
|
else
|
|
if AIndex < Properties.Editors.Count - 1 then
|
|
repeat
|
|
Inc(AIndex);
|
|
with Properties.Editors[AIndex].EditContainer do
|
|
if CanFocus and CanTabStop then
|
|
begin
|
|
Result := True;
|
|
Exit;
|
|
end;
|
|
until AIndex = Properties.Editors.Count - 1;
|
|
end;
|
|
end;
|
|
|
|
function CanChangeExpandedState: Boolean;
|
|
begin
|
|
Result := VerticalGrid.OptionsView.ShowButtons and (FocusedRow <> nil) and
|
|
FocusedRow.Options.ShowExpandButton and (FocusedRow.Count > 0) and not IsEditing;
|
|
end;
|
|
|
|
begin
|
|
FForceShowEditor := (Key = VK_RETURN) and GetGoToNextCellOnEnter;
|
|
AIsMultiEditorRow := (FocusedRow is TcxCustomMultiEditorRow) and
|
|
(TcxCustomMultiEditorRow(FocusedRow).Properties.Editors.Count > 0);
|
|
FProcessMultiEditorRow := AIsMultiEditorRow and
|
|
(ForceShowEditor or ((Key = VK_TAB) and GetGoToNextCellOnTab));
|
|
if ((Key = VK_LEFT) or (Key = VK_RIGHT)) and not CanProcessProcessMultiEditorRow then
|
|
begin
|
|
if not CanChangeRecord then
|
|
begin
|
|
if CanChangeExpandedState then
|
|
FocusedRow.Expanded := Key = VK_RIGHT;
|
|
EatKeyPress := True;
|
|
Key := 0;
|
|
end;
|
|
end;
|
|
inherited KeyDown(Key, Shift);
|
|
case Key of
|
|
VK_MULTIPLY:
|
|
if CanChangeExpandedState then
|
|
begin
|
|
FocusedRow.Expand(True);
|
|
EatKeyPress := True;
|
|
Key := 0;
|
|
end;
|
|
VK_ADD, VK_SUBTRACT:
|
|
if CanChangeExpandedState then
|
|
begin
|
|
FocusedRow.Expanded := Key = VK_ADD;
|
|
EatKeyPress := True;
|
|
Key := 0;
|
|
end;
|
|
VK_INSERT:
|
|
if (Shift = []) and CanInsert(True) then
|
|
begin
|
|
InsertRecord;
|
|
Key := 0;
|
|
end;
|
|
VK_DELETE:
|
|
if ((Shift = []) or (Shift = [ssCtrl])) and CanDelete(True) then
|
|
begin
|
|
DeleteSelection;
|
|
Key := 0;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgController.MakeFocusedItemVisible;
|
|
begin
|
|
if FLockUpdate or (FFocusedRow = nil) then Exit;
|
|
MakeRecordVisible(FocusedRecordIndex);
|
|
MakeRowVisible(FFocusedRow)
|
|
end;
|
|
|
|
procedure TcxvgController.MakeFocusedRecordVisible;
|
|
begin
|
|
MakeRecordVisible(FocusedRecordIndex);
|
|
end;
|
|
|
|
procedure TcxvgController.MouseDown(Button: TMouseButton;
|
|
Shift: TShiftState; X, Y: Integer);
|
|
|
|
function IsChangeExpandState(ARow: TcxCustomRow): Boolean;
|
|
begin
|
|
with HitTest do
|
|
Result := ARow.Options.ShowExpandButton and
|
|
(HitAtButton or (IsDblClick and HitAtCaption and ARow.HasVisibleChildren));
|
|
end;
|
|
|
|
procedure CheckDesignSelection(ARow: TcxCustomRow);
|
|
begin
|
|
if VerticalGrid.IsDesigning then
|
|
begin
|
|
with VerticalGrid.Controller do
|
|
if DesignSelectionHelper <> nil then
|
|
if ARow <> nil then
|
|
DesignSelectionHelper.Select(ARow, Shift)
|
|
else
|
|
DesignSelectionHelper.Select(VerticalGrid, Shift);
|
|
end;
|
|
end;
|
|
|
|
function CanChangeFocusedItem(ARow: TcxCustomRow): Boolean;
|
|
begin
|
|
with HitTest do
|
|
Result := (ARow <> nil) and ARow.CanFocus and
|
|
(not IsItemEditCell or not TcxRowValueInfo(EditCellViewInfo).EditContainer.CanFocus);
|
|
end;
|
|
|
|
procedure CheckFocusedRow;
|
|
var
|
|
ARow: TcxCustomRow;
|
|
begin
|
|
ARow := FocusedRow;
|
|
while (ARow <> nil) and not VerticalGrid.IsRowVisible(ARow) do
|
|
ARow := ARow.Parent;
|
|
if ARow <> FocusedRow then
|
|
if (ARow <> nil) and ARow.CanFocus then
|
|
FocusedRow := ARow
|
|
else
|
|
FocusedRow := nil;
|
|
end;
|
|
|
|
var
|
|
ARow: TcxCustomRow;
|
|
ACellIndex: Integer;
|
|
AChangeExpand: Boolean;
|
|
begin
|
|
ARow := HitTest.HitRow;
|
|
CheckDesignSelection(ARow);
|
|
AChangeExpand := (ARow <> nil) and IsChangeExpandState(ARow);
|
|
if (ResizeKind = rkNone) and CanChangeFocusedItem(ARow) then
|
|
begin
|
|
if HitTest.HitCellIndex >= 0 then
|
|
ACellIndex := HitTest.HitCellIndex
|
|
else
|
|
ACellIndex := cxSetValue(FocusedRow <> ARow, 0, CellIndex);
|
|
SetFocusedRowAndCell(ARow, ACellIndex);
|
|
AChangeExpand := AChangeExpand and (VerticalGrid.Rows.IndexOf(ARow) >= 0);
|
|
end;
|
|
if AChangeExpand then
|
|
begin
|
|
ARow.Expanded := not ARow.Expanded;
|
|
if ARow.Expanded then
|
|
Scroller.SetRowMaxVisible(ARow)
|
|
else
|
|
CheckFocusedRow;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgController.MouseMove(Shift: TShiftState; X, Y: Integer);
|
|
var
|
|
I: Integer;
|
|
ARow: TcxCustomRow;
|
|
begin
|
|
inherited MouseMove(Shift, X, Y);
|
|
if FTrackingEnabled and (VerticalGrid.DragAndDropState = ddsNone) and
|
|
not VerticalGrid.Dragging and not VerticalGrid.IsLocked then
|
|
begin
|
|
ARow := HitTest.HitRow;
|
|
if ARow <> nil then
|
|
begin
|
|
if ARow.CanFocus then
|
|
begin
|
|
StopScrollTimer;
|
|
SetFocusedRowAndCell(ARow, HitTest.HitCellIndex);
|
|
Exit;
|
|
end;
|
|
end
|
|
else
|
|
for I := 0 to ViewInfo.RowsViewInfo.Count - 1 do
|
|
with ViewInfo.RowsViewInfo[I] do
|
|
if cxRectPtIn(RowRect, X, Y) or ((Y >= RowRect.Top) and
|
|
(Y < RowRect.Bottom)) and Row.CanFocus then
|
|
begin
|
|
StopScrollTimer;
|
|
SetFocusedRowAndCell(Row, HitTest.HitCellIndex);
|
|
Exit;
|
|
end;
|
|
with VerticalGrid.ClientBounds do
|
|
begin
|
|
if Y <= Top then
|
|
begin
|
|
FScrollDown := False;
|
|
StartScrollTimer;
|
|
end;
|
|
if Y > Bottom then
|
|
begin
|
|
FScrollDown := True;
|
|
StartScrollTimer;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TcxvgController.CanDrag(X, Y: Integer): Boolean;
|
|
begin
|
|
with HitTest do
|
|
begin
|
|
HitPoint := Point(X, Y);
|
|
if HitAtValue and (dceModified in DataController.EditState) then
|
|
Result := False
|
|
else
|
|
Result := not FWasScroll and CanMoving;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgController.EndDragAndDrop(Accepted: Boolean);
|
|
begin
|
|
inherited EndDragAndDrop(Accepted);
|
|
ResizeKind := rkNone;
|
|
end;
|
|
|
|
function TcxvgController.StartDragAndDrop(const P: TPoint): Boolean;
|
|
begin
|
|
with HitTest do
|
|
begin
|
|
HitPoint := P;
|
|
Result := CanSizing;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgController.InitScrollBarsParameters;
|
|
begin
|
|
if VerticalGrid.HandleAllocated then
|
|
Scroller.InitScrollBarsParameters;
|
|
end;
|
|
|
|
procedure TcxvgController.Scroll(
|
|
AScrollBarKind: TScrollBarKind; AScrollCode: TScrollCode;
|
|
var AScrollPos: Integer);
|
|
begin
|
|
Scroller.Scroll(AScrollBarKind, AScrollCode, AScrollPos);
|
|
end;
|
|
|
|
procedure TcxvgController.AppendRecord;
|
|
begin
|
|
if not CanAppend(False) then Exit;
|
|
if VerticalGrid.OptionsBehavior.FocusFirstCellOnNewRecord then
|
|
FocusedRow := ViewInfo.VisibleRows[0];
|
|
DataController.Append;
|
|
end;
|
|
|
|
procedure TcxvgController.DeleteSelection;
|
|
begin
|
|
end;
|
|
|
|
procedure TcxvgController.InsertRecord;
|
|
begin
|
|
if not CanInsert(False) then Exit;
|
|
if VerticalGrid.OptionsBehavior.FocusFirstCellOnNewRecord then
|
|
FocusedRow := ViewInfo.VisibleRows[0];
|
|
DataController.Insert;
|
|
end;
|
|
|
|
procedure TcxvgController.MakeRowVisible(ARow: TcxCustomRow);
|
|
var
|
|
AParent: TcxCustomRow;
|
|
begin
|
|
if ARow = nil then Exit;
|
|
if VerticalGrid.IsRowVisible(ARow) then
|
|
Scroller.SetRowVisible(ARow)
|
|
else
|
|
with VerticalGrid do
|
|
begin
|
|
AParent := ARow.FParent;
|
|
BeginUpdate;
|
|
try
|
|
while AParent <> FRootRow do
|
|
begin
|
|
AParent.Visible := True;
|
|
AParent.Expanded := True;
|
|
AParent := AParent.FParent;
|
|
end;
|
|
Scroller.SetRowVisible(ARow);
|
|
finally
|
|
EndUpdate;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TcxvgController.MakeRecordVisible(AIndex: Integer): Boolean;
|
|
begin
|
|
Result := Scroller.SetRecordVisible(AIndex);
|
|
end;
|
|
|
|
function TcxvgController._AddRef: Integer;
|
|
begin
|
|
Result := -1;
|
|
end;
|
|
|
|
function TcxvgController._Release: Integer;
|
|
begin
|
|
Result := -1;
|
|
end;
|
|
|
|
function TcxvgController.CanSizing(
|
|
ADirection: TcxDragSizingDirection): Boolean;
|
|
begin
|
|
HitTest.Recalculate(Mouse.CursorPos);
|
|
Result := HitTest.CanSizing(ADirection);
|
|
end;
|
|
|
|
function TcxvgController.GetSizingBoundsRect(
|
|
ADirection: TcxDragSizingDirection): TRect;
|
|
begin
|
|
Result := ViewInfo.ClipRect;
|
|
Dec(Result.Bottom);
|
|
end;
|
|
|
|
function TcxvgController.GetSizingIncrement(
|
|
ADirection: TcxDragSizingDirection): Integer;
|
|
begin
|
|
Result := 1;
|
|
end;
|
|
|
|
function TcxvgController.IsDynamicUpdate: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
procedure TcxvgController.SetSizeDelta(
|
|
ADirection: TcxDragSizingDirection; ADelta: Integer);
|
|
begin
|
|
Inc(FSizingValue, ADelta);
|
|
case ResizeKind of
|
|
rkRowSizing:
|
|
FSizingRow.Height := Max(FSizingValue, ViewInfo.FRowMinHeight);
|
|
rkDivider:
|
|
ViewInfo.SetDividerPos(FSizingValue);
|
|
rkBandSizing:
|
|
ViewInfo.SetValueWidth(FSizingValue);
|
|
end;
|
|
VerticalGrid.Modified;
|
|
end;
|
|
|
|
procedure TcxvgController.DragDrop(Source: TObject; X, Y: Integer);
|
|
begin
|
|
if IsInternalDragging then
|
|
begin
|
|
with HitTest do
|
|
if (HitRow <> nil) or HitAtEmpty then
|
|
begin
|
|
VerticalGrid.BeginUpdate;
|
|
try
|
|
if HitRow = nil then
|
|
begin
|
|
DragRow.Parent := VerticalGrid.FRootRow;
|
|
DragRow.Index := VerticalGrid.FRootRow.Count - 1;
|
|
end
|
|
else
|
|
begin
|
|
if HitAtCaption then
|
|
DragRow.Parent := HitRow
|
|
else
|
|
DragRow.Parent := HitRow.Parent;
|
|
DragRow.Index := HitRow.Index;
|
|
end;
|
|
DragRow.Visible := True;
|
|
finally
|
|
VerticalGrid.EndUpdate;
|
|
end;
|
|
end
|
|
else
|
|
CheckMoveToCustomizationForm;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgController.DragOver(Source: TObject; X, Y: Integer;
|
|
State: TDragState; var Accept: Boolean);
|
|
begin
|
|
inherited DragOver(Source, X, Y, State, Accept);
|
|
if (not Assigned(VerticalGrid.OnDragOver) or Accept) and IsInternalDragging then
|
|
with HitTest do
|
|
begin
|
|
HitPoint := cxPoint(X, Y);
|
|
Accept := HitAtEmpty or
|
|
HitAtRowHeader and (DragRow <> HitRow) and not DragRow.IsParent(HitRow);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgController.EndDrag(Target: TObject; X, Y: Integer);
|
|
begin
|
|
FAutoScrollObject.Free;
|
|
FAutoScrollObject := nil;
|
|
FTrackingEnabled := False;
|
|
inherited EndDrag(Target, X, Y);
|
|
end;
|
|
|
|
procedure TcxvgController.StartDrag(var DragObject: TDragObject);
|
|
begin
|
|
inherited StartDrag(DragObject);
|
|
FAutoScrollObject := TcxControllerAutoScrollingObject.Create(Self);
|
|
FAutoScrollObject.SetBoundsParams(VerticalGrid.ClientBounds, False, True, 1);
|
|
HitTest.HitPoint := VerticalGrid.ScreenToClient(GetMouseCursorPos);
|
|
with VerticalGrid.Customizing do
|
|
begin
|
|
FDragFromCustomizingForm := Visible and HitTest.HitAtCustomize;
|
|
if Visible and (DragRow <> nil) then
|
|
begin
|
|
if DragRow is TcxCategoryRow then
|
|
MakeCategorySheetVisible
|
|
else
|
|
MakeRowSheetVisible;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgController.BeforeMouseDown(Button: TMouseButton;
|
|
Shift: TShiftState; X, Y: Integer);
|
|
begin
|
|
inherited BeforeMouseDown(Button, Shift, X, Y);
|
|
FDragRow := nil;
|
|
end;
|
|
|
|
procedure TcxvgController.BehaviorChanged;
|
|
begin
|
|
if not VerticalGrid.IsLocked then
|
|
inherited BehaviorChanged;
|
|
end;
|
|
|
|
function TcxvgController.CanAppend(ACheckOptions: Boolean): Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
function TcxvgController.CanChangeRecord: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
function TcxvgController.CanDelete(ACheckOptions: Boolean): Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
function TcxvgController.CanInsert(ACheckOptions: Boolean): Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
procedure TcxvgController.CheckFocusFirstVisibleRow;
|
|
begin
|
|
if VerticalGrid.IsFocused and (FocusedRow = nil) then
|
|
FocusedRow := GetFirstVisibleRow;
|
|
end;
|
|
|
|
procedure TcxvgController.CheckPostData;
|
|
begin
|
|
if [dceEdit, dceModified] * DataController.EditState <> [] then
|
|
DataController.Post;
|
|
end;
|
|
|
|
procedure TcxvgController.Clear;
|
|
begin
|
|
StopScrollTimer;
|
|
FTrackingEnabled := False;
|
|
inherited Clear;
|
|
EditingController.EditingItem := nil;
|
|
FocusedItem := nil;
|
|
FFocusedRow := nil;
|
|
end;
|
|
|
|
procedure TcxvgController.ControlFocusChanged;
|
|
begin
|
|
CheckFocusFirstVisibleRow;
|
|
inherited ControlFocusChanged;
|
|
end;
|
|
|
|
procedure TcxvgController.DoCancelMode;
|
|
begin
|
|
StopScrollTimer;
|
|
FTrackingEnabled := False;
|
|
inherited DoCancelMode;
|
|
end;
|
|
|
|
procedure TcxvgController.DoMouseDown(Button: TMouseButton;
|
|
Shift: TShiftState; X, Y: Integer);
|
|
var
|
|
ATopRow: Integer;
|
|
begin
|
|
if (VerticalGrid.DragAndDropState <> ddsNone) and HitTest.CanSizing then
|
|
begin
|
|
EditingController.HideEdit(True);
|
|
Exit;
|
|
end;
|
|
ATopRow := Scroller.TopVisibleRowIndex;
|
|
inherited DoMouseDown(Button, Shift, X, Y);
|
|
FWasScroll := ATopRow <> Scroller.TopVisibleRowIndex;
|
|
with VerticalGrid, HitTest do
|
|
begin
|
|
RecalculateOnMouseEvent(X, Y, Shift);
|
|
FTrackingEnabled := (Button = mbLeft) and (DragMode <> dmAutomatic) and
|
|
not FWasScroll and not HitAtEmpty and
|
|
not HitAtButton and OptionsBehavior.RowTracking and
|
|
not (IsItemEditCell and EditCellViewInfo.EditViewInfo.IsHotTrack(cxPoint(X, Y)));
|
|
if CanMoving and not FTrackingEnabled then
|
|
FDragRow := HitRow;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgController.DoMouseUp(Button: TMouseButton;
|
|
Shift: TShiftState; X, Y: Integer);
|
|
begin
|
|
StopScrollTimer;
|
|
FTrackingEnabled := False;
|
|
inherited DoMouseUp(Button, Shift, X, Y);
|
|
end;
|
|
|
|
procedure TcxvgController.DoNextPage(AForward: Boolean;
|
|
Shift: TShiftState);
|
|
const
|
|
Direction: array[Boolean] of TScrollCode = (scPageUp, scPageDown);
|
|
var
|
|
AIndex: Integer;
|
|
begin
|
|
if ViewInfo.VisibleRowCount = 0 then Exit;
|
|
if ssCtrl in Shift then
|
|
if AForward then
|
|
FocusedRow := VerticalGrid.LastVisibleRow
|
|
else
|
|
FocusedRow := VerticalGrid.FirstVisibleRow
|
|
else
|
|
begin
|
|
if FFocusedRow = nil then
|
|
AIndex := 0
|
|
else
|
|
AIndex := FFocusedRow.VisibleIndex;
|
|
if AForward then
|
|
Inc(AIndex, Scroller.VisibleRowCount)
|
|
else
|
|
Dec(AIndex, Scroller.VisibleRowCount);
|
|
cxRange(AIndex, 0, ViewInfo.VisibleRowCount - 1);
|
|
FocusedRow := ViewInfo.VisibleRows[AIndex];
|
|
end;
|
|
MakeFocusedItemVisible;
|
|
end;
|
|
|
|
procedure TcxvgController.DoUpdateRowAndCell(ANewRow: TcxCustomRow;
|
|
ANewCellIndex: Integer);
|
|
var
|
|
APrevFocusedRow: TcxCustomRow;
|
|
APrevCellIndex: Integer;
|
|
begin
|
|
APrevFocusedRow := FFocusedRow;
|
|
APrevCellIndex := FCellIndex;
|
|
if FFocusedRow <> ANewRow then
|
|
begin
|
|
FFocusedRow := ANewRow;
|
|
FCellIndex := cxSetValue(ANewRow = nil, -1, ANewCellIndex);
|
|
ViewInfo.ChangeFocusedRow(ANewRow, APrevFocusedRow)
|
|
end
|
|
else
|
|
if FCellIndex <> ANewCellIndex then
|
|
begin
|
|
FCellIndex := cxSetValue(FFocusedRow = nil, -1, ANewCellIndex);
|
|
RefreshFocusedRow;
|
|
end;
|
|
MakeFocusedItemVisible;
|
|
if (APrevFocusedRow <> FFocusedRow) or (APrevCellIndex <> FCellIndex) then
|
|
VerticalGrid.DoItemChanged(APrevFocusedRow, APrevCellIndex);
|
|
if VerticalGrid.IsLocked then Exit;
|
|
AllowCheckEdit := True;
|
|
if ForceShowEditor then
|
|
begin
|
|
FForceShowEditor := False;
|
|
EditingController.ShowEdit;
|
|
end
|
|
else
|
|
CheckEdit;
|
|
end;
|
|
|
|
procedure TcxvgController.FocusedItemChanged(
|
|
APrevFocusedItem: TcxCustomInplaceEditContainer);
|
|
var
|
|
ARow: TcxCustomRow;
|
|
ACellIndex: Integer;
|
|
begin
|
|
if EditingControl.ComponentState * [csLoading, csDestroying] <> [] then Exit;
|
|
if not FLockIncSearch then
|
|
CancelIncSearching;
|
|
if (APrevFocusedItem <> nil) and GetPostDataOnChangeItem then
|
|
CheckPostData;
|
|
AllowCheckEdit := False;
|
|
if FLockUpdate then Exit;
|
|
if FocusedItem = nil then
|
|
begin
|
|
if (FFocusedRow = nil) or (csDestroying in FFocusedRow.ComponentState) then
|
|
ARow := nil
|
|
else
|
|
ARow := FFocusedRow;
|
|
ACellIndex := FCellIndex;
|
|
end
|
|
else
|
|
with TcxCellEdit(FocusedItem) do
|
|
begin
|
|
ARow := Row;
|
|
ACellIndex := CellIndex;
|
|
end;
|
|
DoUpdateRowAndCell(ARow, ACellIndex);
|
|
end;
|
|
|
|
function TcxvgController.GetCancelEditingOnExit: Boolean;
|
|
begin
|
|
Result := [dceEdit, dceModified] * DataController.EditState = [];
|
|
end;
|
|
|
|
function TcxvgController.GetDragAndDropObjectClass: TcxDragAndDropObjectClass;
|
|
begin
|
|
FResizeKind := rkNone;
|
|
if HitTest.CanSizing(ResizeDirection) then
|
|
begin
|
|
if ResizeDirection = dsdHorz then
|
|
begin
|
|
if HitTest.HitAtDivider then
|
|
ResizeKind := rkDivider
|
|
else
|
|
ResizeKind := rkBandSizing;
|
|
end
|
|
else
|
|
ResizeKind := rkRowSizing;
|
|
Result := TcxSizingDragAndDropObject;
|
|
DragItem := Self;
|
|
end
|
|
else
|
|
Result := nil
|
|
end;
|
|
|
|
function TcxvgController.GetFocusedCellViewInfo(
|
|
AEditContainer: TcxCustomInplaceEditContainer): TcxEditCellViewInfo;
|
|
var
|
|
ARowViewInfo: TcxCustomRowViewInfo;
|
|
begin
|
|
Result := nil;
|
|
if AEditContainer = nil then Exit;
|
|
ARowViewInfo := TcxCellEdit(AEditContainer).ViewInfo;
|
|
if (ARowViewInfo <> nil) and (FCellIndex >= 0) then
|
|
Result := ARowViewInfo.RowValueInfo[FocusedRecordIndex, FCellIndex];
|
|
end;
|
|
|
|
function TcxvgController.GetImmediateEditor: Boolean;
|
|
begin
|
|
// ignore VerticalGrid.DragMode
|
|
with VerticalGrid.OptionsBehavior do
|
|
Result := ImmediateEditor or AlwaysShowEditor;
|
|
end;
|
|
|
|
function TcxvgController.GetNavigatorClass: TcxCustomCellNavigatorClass;
|
|
begin
|
|
Result := TcxvgCellNavigator;
|
|
end;
|
|
|
|
function TcxvgController.GetPostDataOnChangeItem: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
function TcxvgController.GetResizeDirection: TcxDragSizingDirection;
|
|
begin
|
|
if ResizeKind = rkRowSizing then Result := dsdVert else Result := dsdHorz;
|
|
end;
|
|
|
|
procedure TcxvgController.InternalSetRowAndCell(ARow: TcxCustomRow;
|
|
ACellIndex: Integer);
|
|
begin
|
|
FFocusedRow := ARow;
|
|
FCellIndex := ACellIndex;
|
|
end;
|
|
|
|
function TcxvgController.IsImmediatePost: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
function TcxvgController.IsInternalDragging: Boolean;
|
|
begin
|
|
Result := (VerticalGrid.DragMode = dmAutomatic) and (FDragRow <> nil);
|
|
end;
|
|
|
|
function TcxvgController.IsKeyForController(AKey: Word;
|
|
AShift: TShiftState): Boolean;
|
|
begin
|
|
Result := inherited IsKeyForController(AKey, AShift) or
|
|
(IsEditing and (ssCtrl in AShift) and (AKey in [VK_MULTIPLY, VK_ADD, VK_SUBTRACT]));
|
|
end;
|
|
|
|
procedure TcxvgController.RefreshFocusedRow;
|
|
begin
|
|
if not FLockUpdate and (FFocusedRow <> nil) and
|
|
not (csDestroying in FFocusedRow.ComponentState) and FFocusedRow.Visible then
|
|
FFocusedRow.ViewInfo.Update;
|
|
end;
|
|
|
|
procedure TcxvgController.SetFocusedCellEdit(ACellEdit: TcxCellEdit);
|
|
var
|
|
I: Integer;
|
|
ARow: TcxCustomRow;
|
|
ACellViewInfo: TcxEditCellViewInfo;
|
|
begin
|
|
if ACellEdit = nil then
|
|
FocusedRow := nil
|
|
else
|
|
begin
|
|
ARow := ACellEdit.Row;
|
|
for I := 0 to ARow.GetEditContainerCount - 1 do
|
|
if ARow.GetEditContainer(I) = ACellEdit then
|
|
begin
|
|
SetFocusedRowAndCell(ARow, I);
|
|
ACellViewInfo := GetFocusedCellViewInfo(ACellEdit);
|
|
if Assigned(ACellViewInfo) then
|
|
ACellViewInfo.Invalidate(True);
|
|
break;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgController.SetFocusedRowAndCell(
|
|
Value: TcxCustomRow; ACellIndex: Integer);
|
|
|
|
function CanCellFocus(AIndex: Integer): Boolean;
|
|
begin
|
|
Result := Value.GetEditContainer(AIndex).CanFocus;
|
|
end;
|
|
|
|
procedure CorrectCellIndex;
|
|
var
|
|
I, ACount: Integer;
|
|
begin
|
|
if Value = nil then
|
|
ACount := 0
|
|
else
|
|
ACount := Value.GetEditContainerCount;
|
|
if (ACellIndex >= ACount) or (ACellIndex < 0) then
|
|
ACellIndex := 0;
|
|
if (ACount > 0) and not CanCellFocus(ACellIndex) then
|
|
begin
|
|
ACellIndex := 0;
|
|
for I := 0 to ACount - 1 do
|
|
if CanCellFocus(I) then
|
|
begin
|
|
ACellIndex := I;
|
|
break;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
var
|
|
AEditContainer: TcxCustomInplaceEditContainer;
|
|
begin
|
|
if VerticalGrid.IsDesigning or Assigned(Value) and not Value.CanFocus then Exit;
|
|
CorrectCellIndex;
|
|
if (FCellIndex = ACellIndex) and (FFocusedRow = Value) then Exit;
|
|
FLockUpdate := True;
|
|
try
|
|
if Value <> nil then
|
|
AEditContainer := Value.GetEditContainer(ACellIndex)
|
|
else
|
|
AEditContainer := nil;
|
|
if FocusedItem <> AEditContainer then
|
|
FocusedItem := AEditContainer;
|
|
finally
|
|
FLockUpdate := False;
|
|
AllowCheckEdit := True;
|
|
end;
|
|
DoUpdateRowAndCell(Value, ACellIndex);
|
|
end;
|
|
|
|
procedure TcxvgController.UpdatePaintStyle;
|
|
begin
|
|
ViewInfo.LayoutStyleChanged;
|
|
end;
|
|
|
|
procedure TcxvgController.UpdateRecord(ARecordIndex: Integer);
|
|
begin
|
|
inherited UpdateRecord(ARecordIndex);
|
|
if not VerticalGrid.IsLocked then
|
|
ViewInfo.UpdateRecord(ARecordIndex);
|
|
end;
|
|
|
|
procedure TcxvgController.CheckMoveToCustomizationForm;
|
|
|
|
procedure HideWithChildren(ARow: TcxCustomRow);
|
|
begin
|
|
if not ARow.Options.CanMovedToCustomizationForm then
|
|
begin
|
|
if ARow.Parent <> nil then
|
|
ARow.Parent := ARow.Parent.Parent
|
|
else
|
|
ARow.Parent := nil;
|
|
end;
|
|
while ARow.Count > 0 do
|
|
HideWithChildren(ARow.Rows[0]);
|
|
if ARow.Options.CanMovedToCustomizationForm then
|
|
begin
|
|
ARow.Visible := False;
|
|
ARow.Parent := nil;
|
|
end;
|
|
end;
|
|
|
|
begin
|
|
if not DragFromCustomizingForm and HitTest.HitAtCustomize and
|
|
DragRow.Options.CanMovedToCustomizationForm then
|
|
begin
|
|
with VerticalGrid do
|
|
begin
|
|
BeginUpdate;
|
|
try
|
|
HideWithChildren(FDragRow);
|
|
FocusedRow := nil;
|
|
finally
|
|
EndUpdate;
|
|
end;
|
|
Customizing.Modified;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TcxvgController.GetFirstVisibleRow: TcxCustomRow;
|
|
begin
|
|
if ViewInfo.VisibleRowCount > 0 then
|
|
Result := ViewInfo.VisibleRows[0]
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
function TcxvgController.GetHitTest: TcxvgHitTest;
|
|
begin
|
|
Result := TcxvgHitTest(inherited HitTestController);
|
|
end;
|
|
|
|
function TcxvgController.GetVerticalGrid: TcxCustomVerticalGrid;
|
|
begin
|
|
Result := TcxCustomVerticalGrid(EditingControl);
|
|
end;
|
|
|
|
function TcxvgController.GetViewInfo: TcxvgCustomViewInfo;
|
|
begin
|
|
Result := VerticalGrid.ViewInfo;
|
|
end;
|
|
|
|
procedure TcxvgController.SetFocusedRow(Value: TcxCustomRow);
|
|
begin
|
|
SetFocusedRowAndCell(Value, 0);
|
|
end;
|
|
|
|
procedure TcxvgController.SetResizeKind(
|
|
Value: TcxvgResizeKind);
|
|
begin
|
|
FResizeKind := Value;
|
|
case Value of
|
|
rkDivider:
|
|
FSizingValue := VerticalGrid.OptionsView.RowHeaderWidth;
|
|
rkBandSizing:
|
|
FSizingValue := VerticalGrid.OptionsView.ValueWidth;
|
|
rkRowSizing:
|
|
begin
|
|
FSizingRow := HitTest.HitRow;
|
|
FSizingValue := FSizingRow.ViewInfo.CalculatedHeight;
|
|
end
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgController.OnScrollTimer(Sender: TObject);
|
|
var
|
|
ARow: TcxCustomRow;
|
|
begin
|
|
if FScrollDown then
|
|
ARow := VerticalGrid.NextVisibleRow(FocusedRow)
|
|
else
|
|
ARow := VerticalGrid.PrevVisibleRow(FocusedRow);
|
|
if ARow <> nil then FocusedRow := ARow;
|
|
end;
|
|
|
|
procedure TcxvgController.StartScrollTimer;
|
|
begin
|
|
if FScrollTimer <> nil then Exit;
|
|
FScrollTimer := TTimer.Create(nil);
|
|
FScrollTimer.Interval := 5;
|
|
FScrollTimer.OnTimer := OnScrollTimer;
|
|
end;
|
|
|
|
procedure TcxvgController.StopScrollTimer;
|
|
begin
|
|
FreeAndNil(FScrollTimer);
|
|
end;
|
|
|
|
{ TcxvgMultiRecordsController }
|
|
|
|
procedure TcxvgMultiRecordsController.DeleteSelection;
|
|
begin
|
|
if not CanDelete(False) then Exit;
|
|
if not OptionsData.DeletingConfirmation or
|
|
cxConfirmMessageBox(
|
|
PChar(cxGetResourceString(@cxSvgDeletingFocusedConfirmationText)),
|
|
PChar(cxGetResourceString(@cxSvgDeletingConfirmationCaption))) then
|
|
DataController.DeleteFocused;
|
|
end;
|
|
|
|
function TcxvgMultiRecordsController.CanAppend(ACheckOptions: Boolean): Boolean;
|
|
begin
|
|
Result := (dceoAppend in DataController.EditOperations) and
|
|
(not ACheckOptions or OptionsData.Appending);
|
|
end;
|
|
|
|
function TcxvgMultiRecordsController.CanChangeRecord: Boolean;
|
|
begin
|
|
Result := OptionsBehavior.AllowChangeRecord or
|
|
(VerticalGrid.LayoutStyle = lsMultiRecordView);
|
|
end;
|
|
|
|
function TcxvgMultiRecordsController.CanDelete(ACheckOptions: Boolean): Boolean;
|
|
begin
|
|
Result := (dceoDelete in DataController.EditOperations) and
|
|
(not ACheckOptions or OptionsData.Deleting) and (DataController.RowCount > 0);
|
|
end;
|
|
|
|
function TcxvgMultiRecordsController.CanInsert(ACheckOptions: Boolean): Boolean;
|
|
begin
|
|
Result := (dceoInsert in DataController.EditOperations) and
|
|
(not ACheckOptions or OptionsData.Inserting);
|
|
end;
|
|
|
|
procedure TcxvgMultiRecordsController.FocusedRecordChanged(APrevFocusedRowIndex,
|
|
AFocusedRowIndex: Integer);
|
|
begin
|
|
if APrevFocusedRowIndex <> -1 then
|
|
EditingController.HideEdit(True);
|
|
if not MakeRecordVisible(AFocusedRowIndex) then
|
|
begin
|
|
if VerticalGrid.OptionsView.CellAutoHeight then
|
|
ViewInfo.Calculate
|
|
else
|
|
begin
|
|
ViewInfo.UpdateRecord(APrevFocusedRowIndex);
|
|
ViewInfo.UpdateRecord(AFocusedRowIndex);
|
|
end;
|
|
end;
|
|
VerticalGrid.UpdateScrollBars;
|
|
CheckEdit;
|
|
TcxEditingControllerAccess(EditingController).UpdateEditValue;
|
|
VerticalGrid.DoFocusedRecordChanged(APrevFocusedRowIndex, AFocusedRowIndex);
|
|
VerticalGrid.Invalidate;
|
|
end;
|
|
|
|
function TcxvgMultiRecordsController.GetCancelEditingOnExit: Boolean;
|
|
begin
|
|
with VerticalGrid do
|
|
Result := OptionsData.CancelOnExit and
|
|
(DataController.EditState * [dceInsert, dceChanging, dceModified] = [dceInsert]);
|
|
end;
|
|
|
|
function TcxvgMultiRecordsController.GetFocusedRecordIndex: Integer;
|
|
begin
|
|
Result := DataController.GetFocusedRowIndex;
|
|
end;
|
|
|
|
function TcxvgMultiRecordsController.GetPostDataOnChangeItem: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
function TcxvgMultiRecordsController.IncSearchKeyDown(AKey: Word;
|
|
AShift: TShiftState): Word;
|
|
begin
|
|
if ItemForIncSearching = nil then
|
|
begin
|
|
Result := AKey;
|
|
Exit;
|
|
end
|
|
else
|
|
Result := 0;
|
|
case AKey of
|
|
VK_LEFT, VK_RIGHT:
|
|
if AShift = [ssCtrl] then
|
|
SearchLocateNext(ItemForIncSearching, AKey = VK_RIGHT)
|
|
else
|
|
begin
|
|
CancelIncSearching;
|
|
Result := AKey;
|
|
end;
|
|
VK_UP, VK_DOWN:
|
|
Result := AKey;
|
|
else
|
|
Result := inherited IncSearchKeyDown(AKey, AShift);
|
|
end;
|
|
end;
|
|
|
|
function TcxvgMultiRecordsController.IsImmediatePost: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
procedure TcxvgMultiRecordsController.RefreshIncSearchItem;
|
|
var
|
|
ACellEdit: TcxCellEdit;
|
|
begin
|
|
if IsIncSearching then
|
|
begin
|
|
ACellEdit := VerticalGrid.ContainerList.List^[DataController.Search.ItemIndex];
|
|
FLockIncSearch := True;
|
|
try
|
|
SetFocusedCellEdit(ACellEdit);
|
|
finally
|
|
FLockIncSearch := False;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgMultiRecordsController.SetFocusedRecordIndex(Value: Integer);
|
|
var
|
|
AIndexesAreEqual: Boolean;
|
|
begin
|
|
with DataController do
|
|
begin
|
|
if cxInRange(Value, 0, RowCount - 1) and
|
|
not (CanFocusedRecordIndex(Value) and ChangeFocusedRowIndex(Value)) then Exit;
|
|
end;
|
|
AIndexesAreEqual := FocusedRecordIndex = Value;
|
|
if AIndexesAreEqual then MakeFocusedRecordVisible;
|
|
end;
|
|
|
|
function TcxvgMultiRecordsController.GetOptionsBehavior: TcxvgMultiRecordsOptionsBehavior;
|
|
begin
|
|
Result := VerticalGrid.OptionsBehavior;
|
|
end;
|
|
|
|
function TcxvgMultiRecordsController.GetOptionsData: TcxvgMultiRecordsOptionsData;
|
|
begin
|
|
Result := VerticalGrid.OptionsData;
|
|
end;
|
|
|
|
function TcxvgMultiRecordsController.GetVerticalGrid: TcxVirtualVerticalGrid;
|
|
begin
|
|
Result := inherited VerticalGrid as TcxVirtualVerticalGrid;
|
|
end;
|
|
|
|
{ TcxRowValueInfo }
|
|
|
|
procedure TcxRowValueInfo.DoCalculate;
|
|
begin
|
|
EditContainer.Calculate(Self);
|
|
if Focused then
|
|
FFocusRect := DisplayRect
|
|
else
|
|
FFocusRect := cxNullRect;
|
|
end;
|
|
|
|
function TcxRowValueInfo.EditContainer: TcxCellEdit;
|
|
begin
|
|
Result := TcxCellEdit(inherited EditContainer);
|
|
end;
|
|
|
|
function TcxRowValueInfo.GetButtonTransparency: TcxEditButtonTransparency;
|
|
|
|
function NeedButton: Boolean;
|
|
begin
|
|
Result := Focused;
|
|
if not Result and (Control is TcxVirtualVerticalGrid) then
|
|
with TcxVirtualVerticalGrid(Control) do
|
|
Result := (LayoutStyle = lsMultiRecordView) and
|
|
(RecordIndex = DataController.FocusedRowIndex);
|
|
end;
|
|
|
|
var
|
|
B1: TcxEditingControlEditShowButtons;
|
|
B2: TcxEditItemShowEditButtons;
|
|
begin
|
|
B1 := TcxCustomVerticalGrid(Control).OptionsView.ShowEditButtons;
|
|
B2 := EditorRowProperties.Options.ShowEditButtons;
|
|
if (B2 = eisbAlways) or (B2 = eisbDefault) and
|
|
((B1 = ecsbAlways) or (B1 = ecsbFocused) and NeedButton) then
|
|
Result := ebtNone
|
|
else
|
|
Result := ebtHideInactive;
|
|
end;
|
|
|
|
function TcxRowValueInfo.GetDisplayValue: Variant;
|
|
begin
|
|
if (FRecordIndex < 0) or (FRecordIndex >= EditContainer.DataController.RowCount) then
|
|
Result := Null
|
|
else
|
|
Result := EditContainer.GetDisplayValue(Properties, FRecordIndex);
|
|
end;
|
|
|
|
function TcxRowValueInfo.GetEditViewParams: TcxViewParams;
|
|
begin
|
|
Result := Row.VerticalGrid.Styles.GetContentParams(EditorRowProperties,
|
|
Focused, FRecordIndex);
|
|
end;
|
|
|
|
function TcxRowValueInfo.GetFocused: Boolean;
|
|
begin
|
|
with EditContainer do
|
|
Result := (FocusedCellViewInfo = Self) and
|
|
(DataController.FocusedRowIndex = FRecordIndex) and
|
|
(FRow = FRow.VerticalGrid.FocusedRow);
|
|
end;
|
|
|
|
function TcxRowValueInfo.GetRecordIndex: Integer;
|
|
begin
|
|
Result := FRecordIndex;
|
|
end;
|
|
|
|
function TcxRowValueInfo.GetSelectedTextColor: Integer;
|
|
begin
|
|
Result := IncSearchParams.TextColor;
|
|
end;
|
|
|
|
function TcxRowValueInfo.GetSelectedBKColor: Integer;
|
|
begin
|
|
Result := IncSearchParams.Color
|
|
end;
|
|
|
|
function TcxRowValueInfo.IncSearchParams: TcxViewParams;
|
|
begin
|
|
Result := TcxCustomVerticalGrid(Control).Styles.GetIncSearchParams;
|
|
if Result.Color = clDefault then
|
|
Result.Color := inherited GetSelectedBKColor;
|
|
if Result.TextColor = clDefault then
|
|
Result.TextColor := inherited GetSelectedTextColor;
|
|
end;
|
|
|
|
function TcxRowValueInfo.IsAutoHeight: Boolean;
|
|
begin
|
|
Result := (Properties <> nil) and
|
|
(esoAutoHeight in Properties.GetSupportedOperations) and
|
|
TcxvgCustomViewInfo(ControlViewInfo).GetRowAutoHeight(Row);
|
|
end;
|
|
|
|
function TcxRowValueInfo.GetEditorRowProperties: TcxCustomEditorRowProperties;
|
|
begin
|
|
Result := EditContainer.FEditRowProperties;
|
|
end;
|
|
|
|
{ TcxRowCaptionInfo }
|
|
|
|
constructor TcxRowCaptionInfo.Create;
|
|
begin
|
|
inherited Create;
|
|
FImageIndex := -1;
|
|
end;
|
|
|
|
destructor TcxRowCaptionInfo.Destroy;
|
|
begin
|
|
with Row.VerticalGrid do
|
|
if not IsDestroying then
|
|
with TcxHotTrackControllerAccess(Controller.HotTrackController) do
|
|
if PrevElement = Self then
|
|
Clear;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
function TcxRowCaptionInfo.QueryInterface(const IID: TGUID;
|
|
out Obj): HResult;
|
|
begin
|
|
if GetInterface(IID, Obj) then Result := 0 else Result := cxE_NOINTERFACE;
|
|
end;
|
|
|
|
function TcxRowCaptionInfo._AddRef: Integer;
|
|
begin
|
|
Result := -1;
|
|
end;
|
|
|
|
function TcxRowCaptionInfo._Release: Integer;
|
|
begin
|
|
Result := -1;
|
|
end;
|
|
|
|
function TcxRowCaptionInfo.GetOrigin: TPoint;
|
|
begin
|
|
Result := CaptionRect.TopLeft;
|
|
end;
|
|
|
|
function TcxRowCaptionInfo.IsNeedHint(ACanvas: TcxCanvas; const P: TPoint;
|
|
out AText: TCaption;
|
|
out AIsMultiLine: Boolean;
|
|
out ATextRect: TRect; var IsNeedOffsetHint: Boolean): Boolean;
|
|
var
|
|
ASize: TSize;
|
|
begin
|
|
AText := FindPropertiesHint(P);
|
|
ACanvas.Font := ViewParams.Font;
|
|
if AText <> '' then
|
|
begin
|
|
ASize := ACanvas.TextExtent(AText);
|
|
ATextRect.TopLeft := CaptionRect.TopLeft;
|
|
with ATextRect do
|
|
begin
|
|
Right := Left + ASize.cx;
|
|
Bottom := Top + ASize.cy;
|
|
end;
|
|
IsNeedOffsetHint := True;
|
|
Result := True;
|
|
end
|
|
else
|
|
begin
|
|
AText := FCaption;
|
|
ASize := ACanvas.TextExtent(AText);
|
|
cxRectIntersect(ATextRect, CaptionTextRect, Row.ViewInfo.HeaderInfo.HeaderRect);
|
|
cxRectIntersect(ATextRect, ATextRect, Row.VerticalGrid.ClientBounds);
|
|
IsNeedOffsetHint := False;
|
|
Result := (cxRectWidth(ATextRect) < ASize.cx - 1)
|
|
or (cxRectHeight(ATextRect) < ASize.cy - 1);
|
|
end;
|
|
AIsMultiLine := False;
|
|
end;
|
|
|
|
procedure TcxRowCaptionInfo.UpdateHotTrackState(const APoint: TPoint);
|
|
begin
|
|
end;
|
|
|
|
function TcxRowCaptionInfo.FindPropertiesHint(const P: TPoint): string;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
Result := '';
|
|
if (Row.FProperties is TcxCaptionRowProperties) then
|
|
Result := TcxCaptionRowProperties(Row.FProperties).Hint
|
|
else
|
|
if (Row.FProperties is TcxMultiEditorRowProperties) then
|
|
with TcxMultiEditorRowProperties(Row.FProperties), Row.ViewInfo.HeaderInfo do
|
|
for I := 0 to CaptionsInfo.Count - 1 do
|
|
if cxRectPtIn(CaptionsInfo[I].CaptionRect, P) then
|
|
begin
|
|
Result := Editors[I].Hint;
|
|
break;
|
|
end;
|
|
end;
|
|
|
|
{ TcxCaptionInfoList }
|
|
|
|
function TcxCaptionInfoList.GetItem(Index: Integer): TcxRowCaptionInfo;
|
|
begin
|
|
{$IFDEF LABEL45}
|
|
Result := TcxRowCaptionInfo(inherited Items[Index]);
|
|
{$ELSE}
|
|
Result := TcxRowCaptionInfo(List^[Index]);
|
|
{$ENDIF}
|
|
end;
|
|
|
|
{ TcxValueInfoList }
|
|
|
|
constructor TcxValueInfoList.Create(AViewInfo: TcxvgCustomViewInfo);
|
|
begin
|
|
inherited Create;
|
|
Capacity := 64;
|
|
FViewInfo := AViewInfo;
|
|
end;
|
|
|
|
destructor TcxValueInfoList.Destroy;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to Count - 1 do
|
|
FViewInfo.RemoveEditCellViewInfo(GetItem(I));
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TcxValueInfoList.Trunc(ACount: Integer);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if ACount < Count then
|
|
begin
|
|
for I := ACount to Count - 1 do
|
|
FViewInfo.RemoveEditCellViewInfo(GetItem(I));
|
|
Count := ACount;
|
|
end;
|
|
end;
|
|
|
|
function TcxValueInfoList.GetItem(Index: Integer): TcxRowValueInfo;
|
|
begin
|
|
Result := TcxRowValueInfo(List^[Index]);
|
|
end;
|
|
|
|
{ TcxCustomRowHeaderInfo }
|
|
|
|
constructor TcxCustomRowHeaderInfo.Create(ARow: TcxCustomRow);
|
|
begin
|
|
FCaptionsInfo := TcxCaptionInfoList.Create;
|
|
FCategoryIndents := TIndentInfoList.Create;
|
|
FLinesInfo := TLineInfoList.Create;
|
|
FRow := ARow;
|
|
FRowIndents := TIndentInfoList.Create;
|
|
end;
|
|
|
|
destructor TcxCustomRowHeaderInfo.Destroy;
|
|
begin
|
|
FreeAndNil(FCaptionsInfo);
|
|
FreeAndNil(FLinesInfo);
|
|
FreeAndNil(FRowIndents);
|
|
FreeAndNil(FCategoryIndents);
|
|
inherited Destroy;
|
|
end;
|
|
|
|
function TcxCustomRowHeaderInfo.GetPaintStyle: TcxvgPaintStyle;
|
|
begin
|
|
Result := VerticalGrid.OptionsView.PaintStyle;
|
|
end;
|
|
|
|
function TcxCustomRowHeaderInfo.GetSelected: Boolean;
|
|
begin
|
|
with VerticalGrid.Controller do
|
|
Result := (DesignSelectionHelper <> nil) and
|
|
DesignSelectionHelper.IsObjectSelected(Row);
|
|
end;
|
|
|
|
function TcxCustomRowHeaderInfo.GetShowButton: Boolean;
|
|
begin
|
|
with VerticalGrid.OptionsView do
|
|
Result := ShowButtons and ShowHeaders and Row.Options.ShowExpandButton and
|
|
Row.HasVisibleChildren;
|
|
end;
|
|
|
|
function TcxCustomRowHeaderInfo.GetVerticalGrid: TcxCustomVerticalGrid;
|
|
begin
|
|
Result := Row.VerticalGrid;
|
|
end;
|
|
|
|
procedure TcxCustomRowHeaderInfo.AddBottomHorzLine(const R: TRect);
|
|
begin
|
|
with ViewInfo, R do
|
|
if HorzLineWidth > 0 then
|
|
Self.LinesInfo.Add(Left, Bottom, Right - Left, HorzLineWidth, HorzLineBrush);
|
|
end;
|
|
|
|
procedure TcxCustomRowHeaderInfo.AddBoundHeaderLines;
|
|
begin
|
|
ViewInfo.CalcHelper.AddBoundHeaderLines(Self);
|
|
end;
|
|
|
|
procedure TcxCustomRowHeaderInfo.AddNextIndentInfo(const ABounds: TRect;
|
|
const AViewParams: TcxViewParams;
|
|
AToCategories, AUnderline, AAddVertLine: Boolean);
|
|
begin
|
|
if AToCategories then
|
|
CategoryIndents.Add(ABounds, AViewParams)
|
|
else
|
|
RowIndents.Add(ABounds, AViewParams);
|
|
ViewInfo.CalcHelper.AddHeaderIndentLines(Self, ABounds, AViewParams,
|
|
AToCategories, AUnderline, AAddVertLine);
|
|
end;
|
|
|
|
procedure TcxCustomRowHeaderInfo.AddRightVertLine(const R: TRect);
|
|
begin
|
|
if ViewInfo.ShowHeaders then
|
|
ViewInfo.CalcHelper.AddDivider(LinesInfo, R, clNone, False);
|
|
end;
|
|
|
|
procedure TcxCustomRowHeaderInfo.Calc(const AHeaderRect: TRect;
|
|
AViewInfo: TcxvgCustomViewInfo; ANextRow: TcxCustomRow;
|
|
ACalcBounds: Boolean);
|
|
begin
|
|
FViewInfo := AViewInfo;
|
|
Clear;
|
|
FTransparent := False;
|
|
FHeaderRect := AHeaderRect;
|
|
FFocused := FRow = VerticalGrid.FocusedRow;
|
|
CalcViewParams(ACalcBounds);
|
|
CalcIndentBounds(ANextRow, ACalcBounds);
|
|
CalcExpandButton;
|
|
AddBoundHeaderLines;
|
|
FHeaderCellsRect := AHeaderRect;
|
|
FHeaderCellsRect.Left := IndentBounds.Right;
|
|
if not cxRectIsEmpty(FHeaderCellsRect) then
|
|
begin
|
|
AddRightVertLine(AHeaderRect);
|
|
CalcRowCaptionsInfo;
|
|
FFocusRect := GetFocusRect;
|
|
end
|
|
else
|
|
FHeaderCellsRect := cxNullRect;
|
|
end;
|
|
|
|
function TcxCustomRowHeaderInfo.CalcCaptionInfo(
|
|
ARowProperties: TcxCaptionRowProperties; const R: TRect): TcxRowCaptionInfo;
|
|
var
|
|
W: Integer;
|
|
AOffset: TRect;
|
|
begin
|
|
Result := TcxRowCaptionInfo.Create;
|
|
with Result do
|
|
begin
|
|
FRow := Self.Row;
|
|
FCaptionRect := R;
|
|
FImages := VerticalGrid.Images;
|
|
if FImages <> nil then
|
|
begin
|
|
W := ViewInfo.ImageSize.cx;
|
|
if (ARowProperties.ImageIndex >= 0) and (ARowProperties.ImageIndex < FImages.Count) then
|
|
FImageIndex := ARowProperties.ImageIndex
|
|
else
|
|
begin
|
|
if not VerticalGrid.OptionsView.FShowEmptyRowImage then W := 0;
|
|
FImageIndex := -1;
|
|
end;
|
|
end
|
|
else W := 0;
|
|
FImageRect := cxRectBounds(R.Left, GetTopCentralPoint(ViewInfo.ImageSize.cy, R), W, ViewInfo.ImageSize.cy);
|
|
with R do
|
|
begin
|
|
FCaptionTextRect := cxRect(FImageRect.Right + 1, Top,
|
|
FImageRect.Right + 1 + Max(0, Right - FImageRect.Right - 2), Bottom);
|
|
end;
|
|
AOffset := GetTextEditDrawTextOffset(ARowProperties.HeaderAlignmentHorz, True);
|
|
with FCaptionTextRect do
|
|
begin
|
|
Inc(Top, AOffset.Top + 1);
|
|
Inc(Left, AOffset.Left + 1);
|
|
Dec(Bottom, AOffset.Bottom + 1);
|
|
Dec(Right, AOffset.Right + 1);
|
|
end;
|
|
FTextFlags := GetTextAligmentFlags(ARowProperties);
|
|
if VerticalGrid.OptionsView.CellEndEllipsis then
|
|
FTextFlags := FTextFlags or CXTO_END_ELLIPSIS;
|
|
FViewParams := GetCaptionViewParams;
|
|
FCaption := ARowProperties.Caption;
|
|
FFocused := FRow = VerticalGrid.FocusedRow;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomRowHeaderInfo.CalcExpandButton;
|
|
begin
|
|
if GetShowButton then
|
|
begin
|
|
DoCalcExpandButton;
|
|
FButtonColor := GetButtonColor;
|
|
end;
|
|
end;
|
|
|
|
function TcxCustomRowHeaderInfo.CalcIndentsInfo(ALevelCount: Integer;
|
|
ANextRow: TcxCustomRow): TIndentRectInfoList;
|
|
var
|
|
ACurRow: TcxCustomRow;
|
|
AUnderline, AIsCategory: Boolean;
|
|
I, ANextRowLevel: Integer;
|
|
begin
|
|
Result := TIndentRectInfoList.Create;
|
|
if ANextRow = nil then ANextRowLevel := -1 else ANextRowLevel := ANextRow.Level;
|
|
ACurRow := Row;
|
|
for I := ALevelCount downto 0 do
|
|
begin
|
|
AIsCategory := ACurRow is TcxCategoryRow;
|
|
if AIsCategory then
|
|
AUnderline := (ANextRow = nil) or (ACurRow.Level >= ANextRowLevel)
|
|
else
|
|
AUnderline := I = ALevelCount;
|
|
Result.Add(cxSize(ViewInfo.RowIndentWidth, cxRectHeight(HeaderRect)),
|
|
AIsCategory, AUnderline, ViewInfo.CalcHelper.GetIndentViewParams(Row, ACurRow));
|
|
ACurRow := ACurRow.FParent;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomRowHeaderInfo.CalcIndentBounds(ANextRow: TcxCustomRow;
|
|
ACalculate: Boolean);
|
|
var
|
|
R: TRect;
|
|
I, J, W, ALevelCount, ANextLevel, AHeight, ABoundsWidth: Integer;
|
|
AIndents: TIndentRectInfoList;
|
|
begin
|
|
AHeight := cxRectHeight(HeaderRect);
|
|
R := cxRectBounds(HeaderRect.Left, HeaderRect.Top, 0, AHeight);
|
|
if not ACalculate then
|
|
begin
|
|
FIndentBounds := R;
|
|
Exit;
|
|
end;
|
|
ALevelCount := cxSetValue(ViewInfo.ShowHeaders, Row.Level, -1);
|
|
if ANextRow = nil then ANextLevel := -1 else ANextLevel := ANextRow.Level;
|
|
AIndents := CalcIndentsInfo(ALevelCount, ANextRow);
|
|
ABoundsWidth := 0;
|
|
W := ViewInfo.VertLineWidth;
|
|
J := 0;
|
|
try
|
|
for I := 0 to ALevelCount do
|
|
with AIndents[ALevelCount - I]^ do
|
|
begin
|
|
if IsCategory then
|
|
begin
|
|
if R.Right - R.Left > 0 then
|
|
begin
|
|
Inc(R.Right, W);
|
|
cxRectIntersect(R, R, HeaderRect);
|
|
if not cxRectIsEmpty(R) then
|
|
AddNextIndentInfo(R, AIndents[ALevelCount - J].ViewParams, False, ANextLevel - I <= 0, True);
|
|
Inc(ABoundsWidth, W);
|
|
end;
|
|
cxRectIntersect(R, cxRectBounds(HeaderRect.Left + ABoundsWidth,
|
|
HeaderRect.Top, Size.cx + W, Size.cy), HeaderRect);
|
|
if not cxRectIsEmpty(R) then
|
|
AddNextIndentInfo(cxRectBounds(HeaderRect.Left + ABoundsWidth, HeaderRect.Top,
|
|
Size.cx + W, Size.cy), ViewParams, True, Underline, I < ALevelCount);
|
|
Inc(ABoundsWidth, cxSetValue(I < ALevelCount, W, cxSetValue(IncreaseBoundsByLastVertLine, W, 0)));
|
|
R := cxRectBounds(HeaderRect.Left + ABoundsWidth + Size.cx, HeaderRect.Top, 0, AHeight);
|
|
end
|
|
else
|
|
begin
|
|
Inc(R.Right, Size.cx);
|
|
J := I;
|
|
end;
|
|
Inc(ABoundsWidth, Size.cx);
|
|
end;
|
|
cxRectIntersect(R, R, FHeaderRect);
|
|
if not cxRectIsEmpty(R) then
|
|
AddNextIndentInfo(R, AIndents[ALevelCount - J].ViewParams, False, True, False);
|
|
with HeaderRect do
|
|
FIndentBounds := cxRectBounds(Left, Top, ABoundsWidth, AHeight);
|
|
finally
|
|
AIndents.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomRowHeaderInfo.CalcRowCaptionsInfo;
|
|
var
|
|
ACaptionInfo: TcxRowCaptionInfo;
|
|
begin
|
|
ACaptionInfo := CalcCaptionInfo(TcxCaptionRowProperties(Row.FProperties), HeaderCellsRect);
|
|
CaptionsInfo.Add(ACaptionInfo);
|
|
end;
|
|
|
|
procedure TcxCustomRowHeaderInfo.CalcViewParams(AAllowFocus: Boolean);
|
|
begin
|
|
FIndentViewParams := VerticalGrid.Styles.GetHeaderParams(Row);
|
|
if AAllowFocus and Focused and (PaintStyle = psDotNet) then
|
|
begin
|
|
ViewParams := VerticalGrid.Styles.GetSelectedHeaderParams(Row)
|
|
end
|
|
else
|
|
ViewParams := IndentViewParams;
|
|
end;
|
|
|
|
procedure TcxCustomRowHeaderInfo.Clear;
|
|
begin
|
|
FCaptionsInfo.Clear;
|
|
FLinesInfo.Clear;
|
|
FRowIndents.Clear;
|
|
FCategoryIndents.Clear;
|
|
FButtonRect := cxNullRect;
|
|
FFocusRect := cxNullRect;
|
|
end;
|
|
|
|
procedure TcxCustomRowHeaderInfo.DoCalcExpandButton;
|
|
var
|
|
AWidth: Integer;
|
|
AButtonPlace: TRect;
|
|
begin
|
|
AWidth := GetButtonPlaceBackgroundWidth;
|
|
with IndentBounds do
|
|
AButtonPlace := cxRect(Right - AWidth, Top, Right, Bottom);
|
|
FButtonRect := cxRectCenter(AButtonPlace, ViewInfo.ButtonSize, ViewInfo.ButtonSize);
|
|
end;
|
|
|
|
function TcxCustomRowHeaderInfo.GetButtonPlaceBackgroundWidth: Integer;
|
|
begin
|
|
Result := ViewInfo.RowIndentWidth;
|
|
end;
|
|
|
|
function TcxCustomRowHeaderInfo.GetCaptionViewParams: TcxViewParams;
|
|
begin
|
|
Result := FViewParams;
|
|
end;
|
|
|
|
function TcxCustomRowHeaderInfo.GetButtonColor: TColor;
|
|
begin
|
|
Result := clWindow;
|
|
end;
|
|
|
|
function TcxCustomRowHeaderInfo.GetFocusRect: TRect;
|
|
begin
|
|
Result := cxNullRect;
|
|
end;
|
|
|
|
function TcxCustomRowHeaderInfo.GetTopCentralPoint(AHeight: Integer;
|
|
const R: TRect): Integer;
|
|
begin
|
|
Result := R.Top + (cxRectHeight(R) - AHeight) div 2;
|
|
end;
|
|
|
|
function TcxCustomRowHeaderInfo.IncreaseBoundsByLastVertLine: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
function TcxCustomRowHeaderInfo.LeftViewPoint: Integer;
|
|
begin
|
|
Result := FHeaderRect.Left;
|
|
if (PaintStyle = psDotNet) and (FRowIndents.Count > 0) then
|
|
Result := FRowIndents[FRowIndents.Count - 1].Bounds.Left;
|
|
end;
|
|
|
|
{ TcxCustomRowViewInfo }
|
|
|
|
constructor TcxCustomRowViewInfo.Create(ARow: TcxCustomRow);
|
|
begin
|
|
FRow := ARow;
|
|
FBandIndex := -1;
|
|
FBandRowIndex := -1;
|
|
FValuesInfo := TcxValueInfoList.Create(VerticalGrid.ViewInfo);
|
|
FHeaderInfo := Row.CreateHeaderInfo;
|
|
end;
|
|
|
|
destructor TcxCustomRowViewInfo.Destroy;
|
|
begin
|
|
FRow.FViewInfo := nil;
|
|
FreeAndNil(FValuesInfo);
|
|
FreeAndNil(FHeaderInfo);
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TcxCustomRowViewInfo.Calc(const ARowRect: TRect;
|
|
AViewInfo: TcxvgCustomViewInfo; ANextRow: TcxCustomRow);
|
|
begin
|
|
FViewInfo := AViewInfo;
|
|
FRowRect := ARowRect;
|
|
AViewInfo.CalcRowRects(Self);
|
|
CalcRowHeaderInfo(ANextRow);
|
|
CalcValuesInfo;
|
|
CalcPaintViewParamsLines(ANextRow);
|
|
end;
|
|
|
|
procedure TcxCustomRowViewInfo.Update;
|
|
begin
|
|
ValuesInfo.Trunc(0);
|
|
with VerticalGrid, ViewInfo do
|
|
begin
|
|
if Row = FocusedRow then
|
|
ChangeFocusedRow(Row, PrevVisibleRow(Row))
|
|
else
|
|
begin
|
|
LinesInfo.Locked := True;
|
|
FocusLinesInfo.Locked := True;
|
|
try
|
|
Self.Calc(RowRect, ViewInfo, NextVisibleRow(Row));
|
|
finally
|
|
LinesInfo.Locked := False;
|
|
FocusLinesInfo.Locked := False;
|
|
InvalidateRect(RowRect, False);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomRowViewInfo.UpdateRecord(ARecordIndex: Integer);
|
|
var
|
|
I: Integer;
|
|
ACellInfo: TcxRowValueInfo;
|
|
begin
|
|
ValidateViewInfo;
|
|
CalcValuesInfo;
|
|
for I := 0 to ValuesInfo.Count - 1 do
|
|
begin
|
|
ACellInfo := ValuesInfo[I];
|
|
if ACellInfo.FRecordIndex = ARecordIndex then
|
|
begin
|
|
ACellInfo.Invalidate(True);
|
|
ACellInfo.UpdateEditRect;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomRowViewInfo.AddRectValueLines(R: TRect;
|
|
ALast, ABottomLineNeeded: Boolean);
|
|
begin
|
|
with ViewInfo do
|
|
begin
|
|
if ALast then
|
|
begin
|
|
if R.Left > ClipRect.Right then Exit;
|
|
if R.Right > ClipRect.Right then R.Right := ClipRect.Right;
|
|
end;
|
|
if ABottomLineNeeded then
|
|
AddBottomValueSide(R);
|
|
AddRightValueSide(R, ALast);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxCustomRowViewInfo.CalcRowHeaderInfo(ANextRow: TcxCustomRow);
|
|
begin
|
|
HeaderInfo.Calc(HeaderInfo.HeaderRect, ViewInfo, ANextRow, True);
|
|
end;
|
|
|
|
function TcxCustomRowViewInfo.CalcRowValueInfo(
|
|
ARowProperties: TcxCustomRowProperties;
|
|
AViewInfo: TcxvgCustomViewInfo;
|
|
ARecordIndex, ACellIndex: Integer): TcxRowValueInfo;
|
|
var
|
|
AEditContainer: TcxCellEdit;
|
|
begin
|
|
FViewInfo := AViewInfo;
|
|
AEditContainer := FRow.GetEditContainer(ACellIndex);
|
|
if AEditContainer = nil then
|
|
begin
|
|
Result := nil;
|
|
Exit;
|
|
end;
|
|
Result := GetRowValueInfo(ARecordIndex, ACellIndex);
|
|
if Result = nil then
|
|
begin
|
|
Result := TcxRowValueInfo(AViewInfo.AddEditCellViewInfo(GetRowValueInfoClass, AEditContainer));
|
|
with Result do
|
|
begin
|
|
FRow := Self.Row;
|
|
FRecordIndex := ARecordIndex;
|
|
FRowCellIndex := ACellIndex;
|
|
end;
|
|
AEditContainer.InitEditViewInfo(Result);
|
|
FValuesInfo.Insert(0, Result);
|
|
end
|
|
else
|
|
with FValuesInfo do Move(IndexOf(Result), 0);
|
|
end;
|
|
|
|
procedure TcxCustomRowViewInfo.CalcPaintViewParamsLines(ANextRow: TcxCustomRow);
|
|
begin
|
|
ViewInfo.CalcHelper.CalcPaintViewParamsLines(Self, ANextRow);
|
|
end;
|
|
|
|
function TcxCustomRowViewInfo.GetValueHeight(ARecordIndex: Integer;
|
|
AWidth: Integer; AViewInfo: TcxvgCustomViewInfo): Integer;
|
|
begin
|
|
Result := -1;
|
|
end;
|
|
|
|
function TcxCustomRowViewInfo.GetRowValueInfoClass: TcxRowValueInfoClass;
|
|
begin
|
|
Result := TcxRowValueInfo;
|
|
end;
|
|
|
|
procedure TcxCustomRowViewInfo.ValidateViewInfo;
|
|
begin
|
|
if ViewInfo = nil then
|
|
FViewInfo := VerticalGrid.ViewInfo;
|
|
end;
|
|
|
|
function TcxCustomRowViewInfo.GetRowValueInfo(ARecordIndex,
|
|
ACellIndex: Integer): TcxRowValueInfo;
|
|
var
|
|
I: Integer;
|
|
ARowValueInfo: TcxRowValueInfo;
|
|
begin
|
|
Result := nil;
|
|
if ValuesInfo = nil then Exit;
|
|
for I := 0 to ValuesInfo.Count - 1 do
|
|
begin
|
|
ARowValueInfo := ValuesInfo[I];
|
|
with ARowValueInfo do
|
|
if (RecordIndex = ARecordIndex) and (RowCellIndex = ACellIndex) then
|
|
begin
|
|
Result := ARowValueInfo;
|
|
break
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TcxCustomRowViewInfo.GetVerticalGrid: TcxCustomVerticalGrid;
|
|
begin
|
|
Result := Row.VerticalGrid;
|
|
end;
|
|
|
|
{ TcxRowViewInfoList }
|
|
|
|
constructor TcxRowViewInfoList.Create;
|
|
begin
|
|
Capacity := 1024;
|
|
end;
|
|
|
|
function TcxRowViewInfoList.Find(ARow: TcxCustomRow): TcxCustomRowViewInfo;
|
|
var
|
|
I: Integer;
|
|
AViewInfo: TcxCustomRowViewInfo;
|
|
begin
|
|
Result := nil;
|
|
if ARow = nil then Exit;
|
|
for I := 0 to Count - 1 do
|
|
begin
|
|
AViewInfo := List^[I];
|
|
if AViewInfo.Row = ARow then
|
|
begin
|
|
Result := AViewInfo;
|
|
break;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TcxRowViewInfoList.GetItem(Index: Integer): TcxCustomRowViewInfo;
|
|
begin
|
|
Result := List^[Index];
|
|
end;
|
|
|
|
{ TcxvgCustomViewInfo }
|
|
|
|
constructor TcxvgCustomViewInfo.Create(
|
|
AOwner: TcxEditingControl);
|
|
begin
|
|
inherited Create(AOwner);
|
|
FVerticalGrid := TcxCustomVerticalGrid(AOwner);
|
|
FVisibleRows := TList.Create;
|
|
FLinesInfo := TLineInfoList.Create;
|
|
FFocusLinesInfo := TLineInfoList.Create;
|
|
FRowsViewInfo := TcxRowViewInfoList.Create;
|
|
FViewRects := TViewRects.Create;
|
|
FHorzLineWidth := 1;
|
|
FVertLineWidth := 1;
|
|
FCalcHelper := CreateCalcHelper;
|
|
FLockDividerPos := True;
|
|
CalcLayoutGeneral;
|
|
UpdateVisibleRows;
|
|
UpdateScroller;
|
|
end;
|
|
|
|
destructor TcxvgCustomViewInfo.Destroy;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
ClearLinesAndRows;
|
|
FreeAndNil(FCalcHelper);
|
|
FreeAndNil(FLinesInfo);
|
|
FreeAndNil(FFocusLinesInfo);
|
|
FreeAndNil(FRowsViewInfo);
|
|
FreeAndNil(FViewRects);
|
|
FreeAndNil(FVisibleRows);
|
|
// destroy rows viewinfos on RecreateViewInfo
|
|
with VerticalGrid do
|
|
if not IsDestroying then
|
|
for I := 0 to Rows.Count - 1 do Rows[I].ViewInfo.Free;
|
|
DestroyBrushes;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TcxvgCustomViewInfo.CalcEditCell(
|
|
const ABounds: TRect; ARowValueInfo: TcxRowValueInfo);
|
|
begin
|
|
if ARowValueInfo <> nil then
|
|
ARowValueInfo.SetBounds(ABounds, ClipRect);
|
|
end;
|
|
|
|
function TcxvgCustomViewInfo.CalcRowHeight(ARow: TcxCustomRow): Integer;
|
|
begin
|
|
Result := GetRowHeight(ARow.ViewInfo, ViewValueWidth);
|
|
end;
|
|
|
|
procedure TcxvgCustomViewInfo.ChangeFocusedRow(
|
|
ANewFocus, AOldFocus: TcxCustomRow);
|
|
var
|
|
R: TRect;
|
|
begin
|
|
if VerticalGrid.IsLocked then Exit;
|
|
LinesInfo.Locked := True;
|
|
try
|
|
R := CalcHelper.ChangeFocusedRow(ANewFocus, AOldFocus);
|
|
finally
|
|
LinesInfo.Locked := False;
|
|
end;
|
|
Inc(R.Bottom, HorzLineWidth); //
|
|
VerticalGrid.InvalidateRect(R, False);
|
|
end;
|
|
|
|
function TcxvgCustomViewInfo.GetDefaultGridModeBufferCount: Integer;
|
|
begin
|
|
Result := GetVisibleValueCount;
|
|
end;
|
|
|
|
function TcxvgCustomViewInfo.GetRowViewInfo(
|
|
ARow: TcxCustomRow): TcxCustomRowViewInfo;
|
|
begin
|
|
Result := RowsViewInfo.Find(ARow);
|
|
end;
|
|
|
|
function TcxvgCustomViewInfo.GetValueRect(AValueIndex: Integer;
|
|
ARowViewInfo: TcxCustomRowViewInfo): TRect;
|
|
begin
|
|
with ARowViewInfo, RowRect do
|
|
Result := cxRect(ValuesRect.Left, Top, Right, Bottom);
|
|
end;
|
|
|
|
function TcxvgCustomViewInfo.GetValuesRect(
|
|
ARowViewInfo: TcxCustomRowViewInfo): TRect;
|
|
begin
|
|
with ARowViewInfo, RowRect do
|
|
Result := cxRect(Left + ViewHeaderWidth + DividerWidth, Top, Right, Bottom);
|
|
end;
|
|
|
|
procedure TcxvgCustomViewInfo.UpdateRecord(ARecordIndex: Integer);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if (ARecordIndex < 0) or VerticalGrid.IsLocked then Exit;
|
|
for I := 0 to RowsViewInfo.Count - 1 do
|
|
RowsViewInfo[I].UpdateRecord(ARecordIndex);
|
|
end;
|
|
|
|
function TcxvgCustomViewInfo.CalculateDefaultEditHeight: Integer;
|
|
begin
|
|
Result := FRowMinHeight;
|
|
end;
|
|
|
|
procedure TcxvgCustomViewInfo.DoCalculate;
|
|
begin
|
|
Reset;
|
|
CalcLayoutGeneral;
|
|
UpdateVisibleRows;
|
|
Scroller.RecalcBandsInfo;
|
|
CalcBandWidth;
|
|
ClearLinesAndRows;
|
|
CalcViewRects;
|
|
CalcRowsViewInfo;
|
|
AddEmptyRects;
|
|
end;
|
|
|
|
procedure TcxvgCustomViewInfo.UpdateSelection;
|
|
begin
|
|
inherited UpdateSelection;
|
|
VerticalGrid.Controller.RefreshFocusedRow;
|
|
end;
|
|
|
|
procedure TcxvgCustomViewInfo.AddBandRowsLines(const R: TRect);
|
|
begin
|
|
with R do
|
|
begin
|
|
if HorzLineWidth > 0 then
|
|
begin
|
|
LinesInfo.Add(Left, Top, Right - Left, HorzLineWidth, BandBorderColor);
|
|
LinesInfo.Add(Left + VertLineWidth, Bottom - HorzLineWidth,
|
|
(Right - Left) - 2 * VertLineWidth, HorzLineWidth, BandBorderColor);
|
|
end;
|
|
if VertLineWidth > 0 then
|
|
LinesInfo.Add(Left, Top + HorzLineWidth, VertLineWidth,
|
|
(Bottom - Top) - HorzLineWidth, BandBorderColor);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgCustomViewInfo.AddBottomValueSide(const R: TRect);
|
|
begin
|
|
with R do
|
|
if HorzLineWidth > 0 then
|
|
LinesInfo.Add(Left, Bottom, Right - Left, HorzLineWidth, HorzLineBrush);
|
|
end;
|
|
|
|
procedure TcxvgCustomViewInfo.AddRightValueSide(const R: TRect;
|
|
ALast: Boolean);
|
|
begin
|
|
with R do
|
|
if VertLineWidth > 0 then
|
|
if ALast then
|
|
LinesInfo.Add(Right, Top, VertLineWidth, Bottom - Top + HorzLineWidth, BandBorderColor)
|
|
else
|
|
LinesInfo.Add(Right, Top, VertLineWidth, Bottom - Top + HorzLineWidth, VertLineBrush);
|
|
end;
|
|
|
|
procedure TcxvgCustomViewInfo.CalcBandRects;
|
|
var
|
|
ASumHeight: Integer;
|
|
I: Integer;
|
|
ARowViewInfo: TcxCustomRowViewInfo;
|
|
begin
|
|
ASumHeight := HorzLineWidth;
|
|
for I := Scroller.TopVisibleRowIndex to VisibleRowCount - 1 do
|
|
begin
|
|
ARowViewInfo := VisibleRows[I].ViewInfo;
|
|
ARowViewInfo.CalculatedHeight := GetRowHeight(ARowViewInfo, ViewBandWidth);
|
|
Inc(ASumHeight, ARowViewInfo.CalculatedHeight + HorzLineWidth);
|
|
end;
|
|
CreateBand(ASumHeight, ViewBandWidth);
|
|
end;
|
|
|
|
procedure TcxvgCustomViewInfo.CalcBandRowsViewInfo(
|
|
var AFirstRowIndex: Integer; const ABandRect: TRect;
|
|
ABandIndex, ABandRowCount: Integer);
|
|
var
|
|
ATop, AWidth, ABandRowIndex: Integer;
|
|
ARow, ANextRow: TcxCustomRow;
|
|
ARowRect: TRect;
|
|
ARowViewInfo: TcxCustomRowViewInfo;
|
|
begin
|
|
ABandRowIndex := 0;
|
|
ATop := ABandRect.Top + HorzLineWidth;
|
|
ARow := VisibleRows[AFirstRowIndex];
|
|
AWidth := cxRectWidth(ABandRect) - 2 * VertLineWidth;
|
|
if AWidth > 0 then
|
|
while AFirstRowIndex < VisibleRowCount do
|
|
begin
|
|
if ARow = nil then break;
|
|
ANextRow := VisibleRows[AFirstRowIndex + 1];
|
|
ARowViewInfo := ARow.ViewInfo;
|
|
ARowRect := cxRectBounds(ABandRect.Left + VertLineWidth, ATop, AWidth,
|
|
ARowViewInfo.CalculatedHeight);
|
|
if not CanAddRowToBand(ARowRect, ABandRect, ABandRowIndex) then break;
|
|
ARowViewInfo.BandIndex := ABandIndex;
|
|
ARowViewInfo.BandRowIndex := ABandRowIndex;
|
|
ARowViewInfo.Calc(ARowRect, Self, ANextRow);
|
|
RowsViewInfo.Add(ARowViewInfo);
|
|
AddBandRowsLines(ABandRect);
|
|
Inc(ATop, ARowViewInfo.CalculatedHeight + HorzLineWidth);
|
|
ARow := ANextRow;
|
|
Inc(AFirstRowIndex);
|
|
Inc(ABandRowIndex);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgCustomViewInfo.CalcBandWidth;
|
|
begin
|
|
FViewBandWidth := GetViewBandWidth;
|
|
FViewHeaderWidth := GetViewHeaderWidth;
|
|
FViewValueWidth := GetViewValueWidth;
|
|
end;
|
|
|
|
procedure TcxvgCustomViewInfo.CalcEmpty;
|
|
begin
|
|
if ShowHeaders then
|
|
with ClientRect do
|
|
FCalcHelper.AddDivider(LinesInfo, cxRect(Left, Top, Left + ViewHeaderWidth,
|
|
Bottom), clNone, False);
|
|
end;
|
|
|
|
procedure TcxvgCustomViewInfo.CalcCategoryExplorerStyle;
|
|
var
|
|
ATheme: TdxTheme;
|
|
begin
|
|
FUseCategoryExplorerStyle := VerticalGrid.OptionsView.CategoryExplorerStyle and
|
|
AreVisualStylesAvailable([totExplorerBar]) and
|
|
(VerticalGrid.LookAndFeel.SkinPainter = nil);
|
|
if FUseCategoryExplorerStyle then
|
|
begin
|
|
ATheme := OpenTheme(totExplorerBar);
|
|
if ATheme <> 0 then
|
|
GetThemePartSize(ATheme, 0, EBP_NORMALGROUPEXPAND,
|
|
EBNGE_NORMAL, nil, TS_TRUE, @FExplorerButtonSize)
|
|
else
|
|
begin
|
|
FExplorerButtonSize := cxSize(FButtonSize, FButtonSize);
|
|
FUseCategoryExplorerStyle := False;
|
|
end;
|
|
end
|
|
else
|
|
FExplorerButtonSize := cxSize(FButtonSize, FButtonSize);
|
|
end;
|
|
|
|
procedure TcxvgCustomViewInfo.CalcLayoutGeneral;
|
|
begin
|
|
with VerticalGrid do
|
|
begin
|
|
FClipRect := cxRectInflate(Self.ClientRect, -VertLineWidth, -FHorzLineWidth);
|
|
FBandsInterval := OptionsView.BandsInterval;
|
|
FRowHeaderMinWidth := OptionsView.RowHeaderMinWidth;
|
|
FShowHeaders := OptionsView.ShowHeaders;
|
|
FButtonSize := LookAndFeel.Painter.ExpandButtonSize;
|
|
FHorzLineWidth := Byte(OptionsView.GridLines in [vglHorizontal, vglBoth]);
|
|
FVertLineWidth := Byte(OptionsView.GridLines in [vglVertical, vglBoth]);
|
|
if Images <> nil then
|
|
FImageSize := cxSize(Images.Width, Images.Height)
|
|
else
|
|
FImageSize := cxNullSize;
|
|
if (FVertLineWidth > 0) and FShowHeaders then
|
|
DividerWidth := FCalcHelper.GetDividerWidth
|
|
else
|
|
DividerWidth := 0;
|
|
FBandBorderColor := FCalcHelper.GetBandBorderColor;
|
|
FRowIndentWidth := FCalcHelper.GetIndentWidth;
|
|
FBandMinWidth := FRowHeaderMinWidth + OptionsView.ValueMinWidth + DividerWidth;
|
|
FRowMinHeight := GetMinRowHeight;
|
|
if FShowHeaders then
|
|
FFullHeaderWidth := GetViewHeaderWidth + DividerWidth
|
|
else
|
|
FFullHeaderWidth := 0;
|
|
CreateBrushes;
|
|
CalcCategoryExplorerStyle;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgCustomViewInfo.CalcRowRects(ARowViewInfo: TcxCustomRowViewInfo);
|
|
begin
|
|
if not CheckShowRowHeader(ARowViewInfo) then Exit;
|
|
with ARowViewInfo, RowRect do
|
|
begin
|
|
FHeaderInfo.HeaderRect := cxRect(Left, Top, Left + ViewHeaderWidth, Bottom);
|
|
FValuesRect := cxRect(Left + ViewHeaderWidth + DividerWidth, Top, Right, Bottom);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgCustomViewInfo.CalcRowsViewInfo;
|
|
var
|
|
ARowIndex, ABandIndex, ALeftVisibleBand: Integer;
|
|
R: TRect;
|
|
begin
|
|
with Scroller do
|
|
begin
|
|
ARowIndex := TopVisibleRowIndex;
|
|
ALeftVisibleBand := LeftVisibleBand;
|
|
for ABandIndex := ALeftVisibleBand to BandsInfo.Count - 1 do
|
|
begin
|
|
if ABandIndex - ALeftVisibleBand > ViewRects.BandRects.Count - 1 then break;
|
|
R := ViewRects.BandRects[ABandIndex - ALeftVisibleBand];
|
|
if R.Left > ClientRect.Right then
|
|
break
|
|
else
|
|
CalcBandRowsViewInfo(ARowIndex, R, ABandIndex, BandsInfo[ABandIndex].RowsCount);
|
|
end;
|
|
end;
|
|
if VisibleRowCount = 0 then CalcEmpty;
|
|
end;
|
|
|
|
procedure TcxvgCustomViewInfo.CalcViewRects;
|
|
begin
|
|
ViewRects.Clear;
|
|
if VisibleRowCount = 0 then
|
|
begin
|
|
// make empty band
|
|
with ClientRect do
|
|
ViewRects.BandRects.Add(cxRect(Left, Top, Right, Top));
|
|
ViewRects.EmptyRects.Add(ClientRect);
|
|
end
|
|
else
|
|
CalcBandRects;
|
|
end;
|
|
|
|
function TcxvgCustomViewInfo.CanAddRowToBand(const ARowRect,
|
|
ABandRect: TRect; ABandRowIndex: Integer): Boolean;
|
|
begin
|
|
Result := ARowRect.Top < ABandRect.Bottom;
|
|
end;
|
|
|
|
procedure TcxvgCustomViewInfo.CheckMaxRowHeaderWidth(var Value: Integer; AValueMinWidth: Integer);
|
|
begin
|
|
end;
|
|
|
|
function TcxvgCustomViewInfo.CheckShowRowHeader(
|
|
ARowViewInfo: TcxCustomRowViewInfo): Boolean;
|
|
begin
|
|
Result := ShowHeaders;
|
|
if not Result then
|
|
begin
|
|
with ARowViewInfo.FHeaderInfo do
|
|
begin
|
|
FHeaderRect := ARowViewInfo.FRowRect;
|
|
FHeaderRect.Right := FHeaderRect.Left;
|
|
end;
|
|
ARowViewInfo.FValuesRect := ARowViewInfo.FRowRect;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgCustomViewInfo.CreateBand(ABandHeight,
|
|
ABandWidth: Integer);
|
|
var
|
|
ALeft, AClientHeight: Integer;
|
|
R: TRect;
|
|
begin
|
|
if ViewRects.BandRects.Count = 0 then
|
|
ALeft := ClientRect.Left
|
|
else
|
|
ALeft := ViewRects.BandRects.Rects[ViewRects.BandRects.Count - 1].Right;
|
|
AClientHeight := cxRectHeight(ClientRect);
|
|
R := cxRectBounds(ALeft, ClientRect.Top, ABandWidth, Min(ABandHeight, AClientHeight));
|
|
ViewRects.BandRects.Add(R);
|
|
with R do
|
|
if Bottom - Top < AClientHeight then
|
|
ViewRects.EmptyRects.Add(cxRectBounds(Left, Bottom, ABandWidth, AClientHeight - (Bottom - Top)));
|
|
end;
|
|
|
|
procedure TcxvgCustomViewInfo.CreateBrushes;
|
|
begin
|
|
DestroyBrushes;
|
|
FHorzLineBrush := FCalcHelper.CreateHorzLineBrush;
|
|
FVertLineBrush := FCalcHelper.CreateVertLineBrush;
|
|
end;
|
|
|
|
function TcxvgCustomViewInfo.CreateCalcHelper: TcxvgCustomPaintStyleCalcHelper;
|
|
begin
|
|
Result := VerticalGrid.GetCalcHelperClass.Create(Self);
|
|
end;
|
|
|
|
procedure TcxvgCustomViewInfo.DestroyBrushes;
|
|
|
|
procedure DestroyBrush(var ABrush: TBrush);
|
|
begin
|
|
if ABrush <> nil then
|
|
begin
|
|
if ABrush.Bitmap <> nil then ABrush.Bitmap.Free;
|
|
ABrush.Free;
|
|
ABrush := nil;
|
|
end;
|
|
end;
|
|
|
|
begin
|
|
DestroyBrush(FHorzLineBrush);
|
|
DestroyBrush(FVertLineBrush);
|
|
end;
|
|
|
|
function TcxvgCustomViewInfo.GetBandSizeableRect(const ABandRect: TRect): TRect;
|
|
begin
|
|
with ABandRect do
|
|
Result := cxRect(Right - 1, Top, Right + 2, ClientRect.Bottom);
|
|
end;
|
|
|
|
function TcxvgCustomViewInfo.GetRowAutoHeight(ARow: TcxCustomRow): Boolean;
|
|
begin
|
|
Result := VerticalGrid.OptionsView.CellAutoHeight;
|
|
if ARow <> nil then Result := Result and ARow.Options.CanAutoHeight and
|
|
not ARow.IsHeightAssigned;
|
|
end;
|
|
|
|
function TcxvgCustomViewInfo.GetRowHeight(
|
|
ARowViewInfo: TcxCustomRowViewInfo; ABandWidth: Integer): Integer;
|
|
begin
|
|
Result := Max(ARowViewInfo.Row.GetRealHeight, FRowMinHeight);
|
|
if GetRowAutoHeight(ARowViewInfo.Row) then
|
|
Result := Max(ARowViewInfo.GetValueHeight(FirstVisibleRecordIndex, ViewValueWidth, Self), Result);
|
|
end;
|
|
|
|
function TcxvgCustomViewInfo.GetViewBandWidth: Integer;
|
|
begin
|
|
Result := ClientRect.Right - ClientRect.Left;
|
|
end;
|
|
|
|
function TcxvgCustomViewInfo.GetViewHeaderWidth: Integer;
|
|
begin
|
|
if ShowHeaders then
|
|
Result := Max(GetViewMinHeaderWidth, VerticalGrid.OptionsView.RowHeaderWidth)
|
|
else
|
|
Result := 0;
|
|
end;
|
|
|
|
function TcxvgCustomViewInfo.GetViewMinHeaderWidth: Integer;
|
|
begin
|
|
Result := 1 + (RowIndentWidth + VertLineWidth) * (MaxVisibleLevel + 1);
|
|
end;
|
|
|
|
function TcxvgCustomViewInfo.GetViewValueWidth: Integer;
|
|
begin
|
|
Result := VerticalGrid.OptionsView.ValueWidth;
|
|
end;
|
|
|
|
procedure TcxvgCustomViewInfo.LayoutStyleChanged;
|
|
begin
|
|
Scroller.LayoutStyleChanged;
|
|
end;
|
|
|
|
procedure TcxvgCustomViewInfo.Reset;
|
|
var
|
|
AValueInfo: TcxRowValueInfo;
|
|
begin
|
|
with VerticalGrid.Controller do
|
|
begin
|
|
AValueInfo := TcxRowValueInfo(EditingViewInfo);
|
|
if AValueInfo <> nil then
|
|
begin
|
|
AValueInfo.CellEditRect := cxNullRect;
|
|
AValueInfo.ItemVisible := False;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TcxvgCustomViewInfo.ScaleRowRects(
|
|
ARowViewInfo: TcxCustomRowViewInfo): TRectScaler;
|
|
begin
|
|
Result := TRectScaler.Create;
|
|
with Result do
|
|
begin
|
|
Add(ViewHeaderWidth, RowHeaderMinWidth, DividerWidth);
|
|
Add(ViewBandWidth - ViewHeaderWidth, BandMinWidth);
|
|
ScaleRect(ARowViewInfo.RowRect);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgCustomViewInfo.SetDividerPos(APos: Integer);
|
|
var
|
|
AValueWidth: Integer;
|
|
begin
|
|
with VerticalGrid.OptionsView do
|
|
if APos <> RowHeaderWidth then
|
|
begin
|
|
AValueWidth := ViewBandWidth - (APos + DividerWidth);
|
|
if AValueWidth < ValueMinWidth then
|
|
APos := ViewBandWidth - ValueMinWidth;
|
|
RowHeaderWidth := APos;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgCustomViewInfo.SetValueWidth(AWidth: Integer);
|
|
begin
|
|
VerticalGrid.OptionsView.ValueWidth := AWidth;
|
|
end;
|
|
|
|
procedure TcxvgCustomViewInfo.UpdateVisibleRows;
|
|
var
|
|
ARow: TcxCustomRow;
|
|
I: Integer;
|
|
begin
|
|
FMaxVisibleLevel := 0;
|
|
FVisibleRows.Clear;
|
|
with FVerticalGrid do
|
|
for I := 0 to Rows.Count - 1 do
|
|
begin
|
|
ARow := TcxCustomRow(FRows.FList.List^[I]); // Rows[I];
|
|
if IsRowVisible(ARow) then
|
|
begin
|
|
FMaxVisibleLevel := Max(FMaxVisibleLevel, ARow.Level);
|
|
ARow.FVisibleIndex := FVisibleRows.Count;
|
|
FVisibleRows.Add(ARow);
|
|
end
|
|
else
|
|
ARow.FVisibleIndex := -1;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgCustomViewInfo.Clear;
|
|
begin
|
|
ClearLinesAndRows;
|
|
ViewRects.Clear;
|
|
end;
|
|
|
|
procedure TcxvgCustomViewInfo.ClearLinesAndRows;
|
|
begin
|
|
FLinesInfo.Clear;
|
|
FFocusLinesInfo.Clear;
|
|
FRowsViewInfo.Clear;
|
|
end;
|
|
|
|
function TcxvgCustomViewInfo.GetBandInfo: TBandInfoList;
|
|
begin
|
|
Result := Scroller.ScrollStrategy.BandsInfo;
|
|
end;
|
|
|
|
function TcxvgCustomViewInfo.GetFirstVisibleRecordIndex: Integer;
|
|
begin
|
|
if VerticalGrid.RecordCount = 0 then
|
|
Result := -1
|
|
else
|
|
Result := Scroller.LeftVisibleRecord;
|
|
end;
|
|
|
|
function TcxvgCustomViewInfo.GetMinRowHeight: Integer;
|
|
begin
|
|
Result := cxScreenCanvas.FontHeight(VerticalGrid.Font) + cxTextOffset;
|
|
with VerticalGrid.OptionsView do
|
|
if (FRowHeight >= 0) and (FRowHeight > Result) then Result := FRowHeight;
|
|
if FImageSize.cy + 2 > Result then
|
|
Result := FImageSize.cy + 2;
|
|
end;
|
|
|
|
function TcxvgCustomViewInfo.GetPainter: TcxvgPainter;
|
|
begin
|
|
Result := TcxvgPainter(inherited Painter);
|
|
end;
|
|
|
|
function TcxvgCustomViewInfo.GetScroller: TcxvgScroller;
|
|
begin
|
|
Result := VerticalGrid.Controller.Scroller;
|
|
end;
|
|
|
|
function TcxvgCustomViewInfo.GetVisibleRow(
|
|
Index: Integer): TcxCustomRow;
|
|
begin
|
|
if (Index >= 0) and (Index < FVisibleRows.Count) then
|
|
Result := TcxCustomRow(FVisibleRows.List^[Index])
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
function TcxvgCustomViewInfo.GetVisibleRowCount: Integer;
|
|
begin
|
|
Result := FVisibleRows.Count;
|
|
end;
|
|
|
|
procedure TcxvgCustomViewInfo.UpdateScroller;
|
|
begin
|
|
with FVerticalGrid.Controller.Scroller do
|
|
begin
|
|
RecreateScrollStrategy;
|
|
ScrollStrategy.FViewInfo := Self;
|
|
end;
|
|
end;
|
|
|
|
{ TcxvgCustomPaintStyleCalcHelper }
|
|
|
|
constructor TcxvgCustomPaintStyleCalcHelper.Create(
|
|
AViewInfo: TcxvgCustomViewInfo);
|
|
begin
|
|
FViewInfo := AViewInfo;
|
|
FVerticalGrid := AViewInfo.VerticalGrid;
|
|
FScroller := AViewInfo.Scroller;
|
|
end;
|
|
|
|
function TcxvgCustomPaintStyleCalcHelper.GetBandBorderColor: TColor;
|
|
begin
|
|
Result := VerticalGrid.OptionsView.GridLineColor;
|
|
end;
|
|
|
|
function TcxvgCustomPaintStyleCalcHelper.GetBackgroundColor: TColor;
|
|
begin
|
|
Result := GetHeaderColor;
|
|
end;
|
|
|
|
{ TcxvgDotNetStyleCalcHelper }
|
|
|
|
procedure TcxvgDotNetStyleCalcHelper.AddBoundHeaderLines(
|
|
ARowHeaderInfo: TcxCustomRowHeaderInfo);
|
|
begin
|
|
with ARowHeaderInfo, IndentBounds do
|
|
AddBottomHorzLine(cxRectBounds(Right, Top, HeaderRect.Right - Right, Bottom - Top));
|
|
end;
|
|
|
|
procedure TcxvgDotNetStyleCalcHelper.AddDivider(
|
|
ALinesInfo: TLineInfoList; const R: TRect; AColor: TColor; AIsSeparator: Boolean);
|
|
begin
|
|
with ViewInfo, R do
|
|
if DividerWidth > 0 then
|
|
ALinesInfo.Add(Right, Top, VertLineWidth, Bottom - Top + HorzLineWidth, VertLineBrush);
|
|
end;
|
|
|
|
procedure TcxvgDotNetStyleCalcHelper.AddHeaderIndentLines(
|
|
ARowHeaderInfo: TcxCustomRowHeaderInfo; const R: TRect;
|
|
const AViewParams: TcxViewParams;
|
|
AToCategories, AUnderline, AAddVertLine: Boolean);
|
|
var
|
|
W: Integer;
|
|
begin
|
|
with ViewInfo, R do
|
|
begin
|
|
if not ShowHeaders then Exit;
|
|
if AAddVertLine and (VertLineWidth > 0) then
|
|
ARowHeaderInfo.LinesInfo.Add(Right - VertLineWidth, Top, VertLineWidth,
|
|
Bottom - Top + HorzLineWidth, VertLineBrush);
|
|
if HorzLineWidth > 0 then
|
|
begin
|
|
W := Right - Left;
|
|
if AAddVertLine then Dec(W, VertLineWidth);
|
|
if AUnderline then
|
|
ARowHeaderInfo.LinesInfo.Add(Left, Bottom, W, HorzLineWidth, HorzLineBrush)
|
|
else
|
|
if (AViewParams.Bitmap <> nil) and not AViewParams.Bitmap.Empty then
|
|
ARowHeaderInfo.RowIndents.Add(cxRectBounds(Left, Bottom, W, HorzLineWidth), AViewParams)
|
|
else
|
|
ARowHeaderInfo.LinesInfo.Add(Left, Bottom, W, HorzLineWidth, AViewParams.Color);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgDotNetStyleCalcHelper.CalcPaintViewParamsLines(
|
|
ARowViewInfo: TcxCustomRowViewInfo; ANextRow: TcxCustomRow);
|
|
begin
|
|
end;
|
|
|
|
function TcxvgDotNetStyleCalcHelper.ChangeFocusedRow(
|
|
ANewFocus, AOldFocus: TcxCustomRow): TRect;
|
|
var
|
|
ARecalcChild: Boolean;
|
|
|
|
procedure ProcessRow(ARow: TcxCustomRow);
|
|
var
|
|
ARowViewInfo: TcxCustomRowViewInfo;
|
|
ASaveColor: TColor;
|
|
I: Integer;
|
|
ANextRow: TcxCustomRow;
|
|
begin
|
|
ARowViewInfo := ViewInfo.GetRowViewInfo(ARow);
|
|
if ARowViewInfo = nil then Exit;
|
|
with ARowViewInfo, ViewInfo do
|
|
begin
|
|
ASaveColor := HeaderInfo.IndentViewParams.Color;
|
|
Result := cxRectUnion(Result, RowRect);
|
|
ANextRow := VisibleRows[ARow.VisibleIndex + 1];
|
|
Calc(RowRect, Self.ViewInfo, VisibleRows[ARow.VisibleIndex + 1]);
|
|
ARecalcChild := ARecalcChild or
|
|
((ASaveColor <> HeaderInfo.IndentViewParams.Color) and (Row is TcxCategoryRow));
|
|
if ARecalcChild and (ANextRow <> nil) then
|
|
for I := ANextRow.VisibleIndex to VisibleRowCount - 1 do
|
|
if ARow.IsParent(VisibleRows[I]) then
|
|
with VisibleRows[I].ViewInfo, HeaderInfo do
|
|
begin
|
|
ANextRow := VisibleRows[ARow.VisibleIndex + 1];
|
|
HeaderInfo.Calc(HeaderRect, Self.ViewInfo, ANextRow, True);
|
|
Result := cxRectUnion(Result, HeaderRect);
|
|
end
|
|
else
|
|
break
|
|
end;
|
|
end;
|
|
|
|
begin
|
|
Result := cxNullRect;
|
|
ARecalcChild := False;
|
|
ProcessRow(ANewFocus);
|
|
ProcessRow(AOldFocus);
|
|
end;
|
|
|
|
function TcxvgDotNetStyleCalcHelper.GetCategoryColor: TColor;
|
|
begin
|
|
Result := ViewInfo.Painter.Painter.DefaultHeaderColor;
|
|
end;
|
|
|
|
function TcxvgDotNetStyleCalcHelper.GetCategoryFocusRect(
|
|
ARowHeaderInfo: TcxCustomRowHeaderInfo): TRect;
|
|
var
|
|
ATextRect: TRect;
|
|
ASize: TSize;
|
|
ACaption: string;
|
|
AHeaderInfo: TcxCategoryRowHeaderInfo;
|
|
AProperties: TcxCaptionRowProperties;
|
|
begin
|
|
Result := cxNullRect;
|
|
if VerticalGrid.FocusedRow <> ARowHeaderInfo.Row then Exit;
|
|
AHeaderInfo := TcxCategoryRowHeaderInfo(ARowHeaderInfo);
|
|
AProperties := AHeaderInfo.Row.Properties;
|
|
ACaption := AProperties.Caption;
|
|
if ACaption = '' then Exit;
|
|
ATextRect := AHeaderInfo.CaptionsInfo[0].CaptionTextRect;
|
|
ASize := cxTextExtent(AHeaderInfo.ViewParams.Font, ACaption);
|
|
with ATextRect do
|
|
begin
|
|
case AProperties.HeaderAlignmentHorz of
|
|
taLeftJustify: Right := Left + ASize.cx;
|
|
taRightJustify: Left := Right - ASize.cx;
|
|
else
|
|
ATextRect := cxRectCenter(ATextRect, ASize.cx, Bottom - Top);
|
|
end;
|
|
case AProperties.HeaderAlignmentVert of
|
|
vaTop: Bottom := Top + ASize.cy;
|
|
vaBottom: Top := Bottom - ASize.cy;
|
|
else
|
|
ATextRect := cxRectCenter(ATextRect, Right - Left, ASize.cy);
|
|
end;
|
|
end;
|
|
cxRectIntersect(Result, cxRectInflate(ATextRect, 1, 1), AHeaderInfo.HeaderRect);
|
|
end;
|
|
|
|
function TcxvgDotNetStyleCalcHelper.GetCategoryTextColor: TColor;
|
|
begin
|
|
Result := clGrayText;
|
|
end;
|
|
|
|
function TcxvgDotNetStyleCalcHelper.GetContentColor(AFocused: Boolean): TColor;
|
|
begin
|
|
Result := ViewInfo.Painter.Painter.DefaultContentColor;
|
|
end;
|
|
|
|
function TcxvgDotNetStyleCalcHelper.GetContentTextColor: TColor;
|
|
begin
|
|
Result := ViewInfo.Painter.Painter.DefaultContentTextColor;
|
|
end;
|
|
|
|
function TcxvgDotNetStyleCalcHelper.GetHeaderColor: TColor;
|
|
begin
|
|
Result := ViewInfo.Painter.Painter.DefaultContentColor;
|
|
end;
|
|
|
|
function TcxvgDotNetStyleCalcHelper.GetHeaderTextColor: TColor;
|
|
begin
|
|
Result := ViewInfo.Painter.Painter.DefaultContentTextColor;
|
|
end;
|
|
|
|
function TcxvgDotNetStyleCalcHelper.GetIndentViewParams(ARow,
|
|
AParentIndentRow: TcxCustomRow): TcxViewParams;
|
|
begin
|
|
if ARow <> AParentIndentRow then
|
|
with AParentIndentRow.ViewInfo.HeaderInfo do
|
|
begin
|
|
if AParentIndentRow.VisibleIndex < Scroller.TopVisibleRowIndex then
|
|
CalcViewParams(False);
|
|
Result := IndentViewParams;
|
|
end
|
|
else
|
|
Result := ARow.ViewInfo.HeaderInfo.ViewParams;
|
|
end;
|
|
|
|
function TcxvgDotNetStyleCalcHelper.IsDrawValueFocusRect: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
function TcxvgDotNetStyleCalcHelper.CreateHorzLineBrush: TBrush;
|
|
begin
|
|
Result := TBrush.Create;
|
|
Result.Color := VerticalGrid.OptionsView.GridLineColor;
|
|
end;
|
|
|
|
function TcxvgDotNetStyleCalcHelper.CreateVertLineBrush: TBrush;
|
|
begin
|
|
Result := TBrush.Create;
|
|
Result.Color := VerticalGrid.OptionsView.GridLineColor;
|
|
end;
|
|
|
|
function TcxvgDotNetStyleCalcHelper.GetDividerWidth: Integer;
|
|
begin
|
|
Result := 1;
|
|
end;
|
|
|
|
function TcxvgDotNetStyleCalcHelper.GetIndentWidth: Integer;
|
|
begin
|
|
Result := ViewInfo.Painter.Painter.ExpandButtonSize + 4;
|
|
end;
|
|
|
|
{ TcxvgStyle3DCalcHelper }
|
|
|
|
procedure TcxvgStyle3DCalcHelper.AddBoundHeaderLines(
|
|
ARowHeaderInfo: TcxCustomRowHeaderInfo);
|
|
begin
|
|
if ViewInfo.HorzLineWidth > 0 then
|
|
with ARowHeaderInfo, HeaderRect do
|
|
LinesInfo.Add(Left, Bottom, Right - Left,
|
|
ViewInfo.HorzLineWidth, ViewInfo.HorzLineBrush);
|
|
end;
|
|
|
|
procedure TcxvgStyle3DCalcHelper.AddHeaderIndentLines(
|
|
ARowHeaderInfo: TcxCustomRowHeaderInfo; const R: TRect;
|
|
const AViewParams: TcxViewParams;
|
|
AToCategories, AUnderline, AAddVertLine: Boolean);
|
|
begin
|
|
end;
|
|
|
|
procedure TcxvgStyle3DCalcHelper.AddDivider(ALinesInfo: TLineInfoList;
|
|
const R: TRect; AColor: TColor; AIsSeparator: Boolean);
|
|
begin
|
|
with ViewInfo, R do
|
|
if DividerWidth > 0 then
|
|
if AIsSeparator then
|
|
begin
|
|
ALinesInfo.Add(Right, Top, 2, 2, AColor);
|
|
ALinesInfo.Add(Right, Bottom - 2, 2, 2, AColor);
|
|
ALinesInfo.Add(Right, Top + 2, 1, Bottom - Top + HorzLineWidth - 5, clBtnShadow);
|
|
ALinesInfo.Add(Right + 1, Top + 2, 1, Bottom - Top + HorzLineWidth - 5, clBtnHighlight);
|
|
end
|
|
else
|
|
begin
|
|
ALinesInfo.Add(Right, Top, 1, Bottom - Top + HorzLineWidth, clBtnShadow);
|
|
ALinesInfo.Add(Right + 1, Top, 1, Bottom - Top + HorzLineWidth, clBtnHighlight);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgStyle3DCalcHelper.CalcPaintViewParamsLines(
|
|
ARowViewInfo: TcxCustomRowViewInfo; ANextRow: TcxCustomRow);
|
|
var
|
|
AFocusedRowBandIndex: Integer;
|
|
R: TRect;
|
|
begin
|
|
if VerticalGrid.FocusedRow = nil then Exit;
|
|
R := ARowViewInfo.RowRect;
|
|
with R do
|
|
begin
|
|
if ANextRow = VerticalGrid.FocusedRow then
|
|
begin
|
|
AFocusedRowBandIndex := Scroller.GetBandIndexByRowIndex(ANextRow.VisibleIndex);
|
|
if AFocusedRowBandIndex = ARowViewInfo.BandIndex then
|
|
begin
|
|
ViewInfo.FocusLinesInfo.Add(Left, Bottom - 1, Right - Left, 1, cl3DDkShadow);
|
|
ViewInfo.FocusLinesInfo.Add(Left + 1, Bottom, Right - Left - 1, 1, clBtnShadow);
|
|
end;
|
|
end;
|
|
if ARowViewInfo.Row = VerticalGrid.FocusedRow then
|
|
begin
|
|
ViewInfo.FocusLinesInfo.Add(Left, Bottom - 1, Right - Left, 1, clBtnFace);
|
|
ViewInfo.FocusLinesInfo.Add(Left, Bottom, Right - Left, 1, clBtnHighlight);
|
|
ViewInfo.FocusLinesInfo.Add(Left, Top - 1, 1, Bottom - Top + 1, cl3DDkShadow);
|
|
ViewInfo.FocusLinesInfo.Add(Left + 1, Top, 1, Bottom - Top - 1, clBtnShadow);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TcxvgStyle3DCalcHelper.ChangeFocusedRow(
|
|
ANewFocus, AOldFocus: TcxCustomRow): TRect;
|
|
|
|
procedure ProcessRow(ARow: TcxCustomRow);
|
|
var
|
|
ARowViewInfo: TcxCustomRowViewInfo;
|
|
begin
|
|
ARowViewInfo := ViewInfo.GetRowViewInfo(ARow);
|
|
if ARowViewInfo = nil then Exit;
|
|
with ViewInfo do
|
|
begin
|
|
with ARowViewInfo do
|
|
begin
|
|
Result := cxRectUnion(Result, RowRect);
|
|
Calc(RowRect, ViewInfo, VisibleRows[ARow.VisibleIndex + 1]);
|
|
end;
|
|
ARowViewInfo := GetRowViewInfo(VisibleRows[ARow.VisibleIndex - 1]);
|
|
if ARowViewInfo <> nil then
|
|
with ARowViewInfo do
|
|
begin
|
|
Calc(RowRect, ViewInfo, ARow);
|
|
Result := cxRectUnion(Result, RowRect);
|
|
end;
|
|
if HorzLineWidth = 0 then
|
|
Inc(Result.Bottom);
|
|
end;
|
|
end;
|
|
|
|
begin
|
|
Result := cxNullRect;
|
|
ViewInfo.FocusLinesInfo.Clear;
|
|
ProcessRow(ANewFocus);
|
|
ProcessRow(AOldFocus);
|
|
end;
|
|
|
|
function TcxvgStyle3DCalcHelper.GetCategoryColor: TColor;
|
|
begin
|
|
Result := ViewInfo.Painter.Painter.DefaultHeaderColor;
|
|
end;
|
|
|
|
function TcxvgStyle3DCalcHelper.GetCategoryFocusRect(
|
|
ARowHeaderInfo: TcxCustomRowHeaderInfo): TRect;
|
|
begin
|
|
Result := cxNullRect;
|
|
end;
|
|
|
|
function TcxvgStyle3DCalcHelper.GetCategoryTextColor: TColor;
|
|
begin
|
|
Result := ViewInfo.Painter.Painter.DefaultHeaderTextColor;
|
|
end;
|
|
|
|
function TcxvgStyle3DCalcHelper.GetContentColor(AFocused: Boolean): TColor;
|
|
begin
|
|
if AFocused then
|
|
Result := ViewInfo.Painter.Painter.DefaultContentColor
|
|
else
|
|
Result := ViewInfo.Painter.Painter.DefaultHeaderColor;
|
|
end;
|
|
|
|
function TcxvgStyle3DCalcHelper.GetContentTextColor: TColor;
|
|
begin
|
|
Result := clNavy;
|
|
end;
|
|
|
|
function TcxvgStyle3DCalcHelper.GetHeaderColor: TColor;
|
|
begin
|
|
Result := ViewInfo.Painter.Painter.DefaultHeaderColor;
|
|
end;
|
|
|
|
function TcxvgStyle3DCalcHelper.GetHeaderTextColor: TColor;
|
|
begin
|
|
Result := ViewInfo.Painter.Painter.DefaultHeaderTextColor;
|
|
end;
|
|
|
|
function TcxvgStyle3DCalcHelper.GetIndentViewParams(ARow,
|
|
AParentIndentRow: TcxCustomRow): TcxViewParams;
|
|
begin
|
|
Result := ARow.ViewInfo.HeaderInfo.ViewParams;
|
|
end;
|
|
|
|
function TcxvgStyle3DCalcHelper.IsDrawValueFocusRect: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
function TcxvgStyle3DCalcHelper.CreateHorzLineBrush: TBrush;
|
|
begin
|
|
Result := cxCreateHalftoneBrush(VerticalGrid.OptionsView.GridLineColor, clBtnFace);
|
|
end;
|
|
|
|
function TcxvgStyle3DCalcHelper.CreateVertLineBrush: TBrush;
|
|
begin
|
|
Result := cxCreateHalftoneBrush(VerticalGrid.OptionsView.GridLineColor, clBtnFace);
|
|
end;
|
|
|
|
function TcxvgStyle3DCalcHelper.GetDividerWidth: Integer;
|
|
begin
|
|
Result := 2;
|
|
end;
|
|
|
|
function TcxvgStyle3DCalcHelper.GetIndentWidth: Integer;
|
|
begin
|
|
Result := ViewInfo.Painter.Painter.ExpandButtonSize + 4;
|
|
end;
|
|
|
|
{ TcxvgSkinCalcHelper }
|
|
|
|
procedure TcxvgSkinCalcHelper.AddBoundHeaderLines(
|
|
ARowHeaderInfo: TcxCustomRowHeaderInfo);
|
|
begin
|
|
if ARowHeaderInfo is TcxCategoryRowHeaderInfo then
|
|
begin
|
|
if ARowHeaderInfo.ViewInfo.HorzLineWidth > 0 then
|
|
with ARowHeaderInfo, IndentBounds do
|
|
begin
|
|
ARowHeaderInfo.LinesInfo.Add(Right, Top - ViewInfo.HorzLineWidth,
|
|
HeaderRect.Right - Right, ViewInfo.HorzLineWidth, ViewInfo.BandBorderColor);
|
|
ARowHeaderInfo.LinesInfo.Add(Right, Bottom, HeaderRect.Right - Right,
|
|
ViewInfo.HorzLineWidth, ViewInfo.BandBorderColor);
|
|
end;
|
|
end else
|
|
inherited AddBoundHeaderLines(ARowHeaderInfo);
|
|
end;
|
|
|
|
procedure TcxvgSkinCalcHelper.AddHeaderIndentLines(ARowHeaderInfo: TcxCustomRowHeaderInfo;
|
|
const R: TRect; const AViewParams: TcxViewParams; AToCategories, AUnderline,
|
|
AAddVertLine: Boolean);
|
|
begin
|
|
inherited AddHeaderIndentLines(ARowHeaderInfo, R, AViewParams, AToCategories,
|
|
AUnderline, AAddVertLine);
|
|
if not ViewInfo.ShowHeaders then Exit;
|
|
if AToCategories and (ViewInfo.VertLineWidth > 0) then
|
|
begin
|
|
if ARowHeaderInfo is TcxCategoryRowHeaderInfo then
|
|
if ARowHeaderInfo.IndentBounds.Right = R.Right then
|
|
ARowHeaderInfo.LinesInfo.Add(R.Left, R.Top - ViewInfo.HorzLineWidth,
|
|
R.Right - R.Left, ViewInfo.HorzLineWidth, ViewInfo.BandBorderColor);
|
|
if AAddVertLine then
|
|
ARowHeaderInfo.LinesInfo.Add(R.Right - ViewInfo.VertLineWidth,
|
|
R.Top - ViewInfo.HorzLineWidth, ViewInfo.VertLineWidth,
|
|
R.Bottom - R.Top + ViewInfo.HorzLineWidth, ViewInfo.BandBorderColor);
|
|
if AUnderline then
|
|
ARowHeaderInfo.LinesInfo.Add(R.Left, R.Bottom, R.Right - R.Left,
|
|
ViewInfo.HorzLineWidth, ViewInfo.BandBorderColor);
|
|
end;
|
|
end;
|
|
|
|
function TcxvgSkinCalcHelper.GetBackgroundColor: TColor;
|
|
begin
|
|
Result := ViewInfo.Painter.Painter.DefaultContentColor;
|
|
end;
|
|
|
|
function TcxvgSkinCalcHelper.GetCategoryColor: TColor;
|
|
begin
|
|
Result := ViewInfo.Painter.Painter.DefaultVGridCategoryColor;
|
|
end;
|
|
|
|
function TcxvgSkinCalcHelper.GetCategoryTextColor: TColor;
|
|
begin
|
|
Result := ViewInfo.Painter.Painter.DefaultVGridCategoryTextColor;
|
|
if Result = clDefault then
|
|
Result := inherited GetCategoryTextColor;
|
|
end;
|
|
|
|
function TcxvgSkinCalcHelper.GetHeaderColor: TColor;
|
|
begin
|
|
Result := ViewInfo.Painter.Painter.DefaultHeaderColor;
|
|
if Result = clDefault then
|
|
Result := inherited GetHeaderColor;
|
|
end;
|
|
|
|
function TcxvgSkinCalcHelper.GetHeaderTextColor: TColor;
|
|
begin
|
|
Result := ViewInfo.Painter.Painter.DefaultHeaderTextColor;
|
|
if Result = clDefault then
|
|
Result := inherited GetHeaderTextColor;
|
|
end;
|
|
|
|
function TcxvgSkinCalcHelper.CreateHorzLineBrush: TBrush;
|
|
begin
|
|
Result := TBrush.Create;
|
|
Result.Color := ViewInfo.Painter.Painter.DefaultVGridLineColor;
|
|
end;
|
|
|
|
function TcxvgSkinCalcHelper.CreateVertLineBrush: TBrush;
|
|
begin
|
|
Result := TBrush.Create;
|
|
Result.Color := ViewInfo.Painter.Painter.DefaultVGridLineColor;
|
|
end;
|
|
|
|
function TcxvgSkinCalcHelper.GetBandBorderColor: TColor;
|
|
begin
|
|
Result := ViewInfo.Painter.Painter.DefaultVGridBandLineColor;
|
|
end;
|
|
|
|
{ TcxvgPainter }
|
|
|
|
constructor TcxvgPainter.Create(AOwner: TcxEditingControl);
|
|
begin
|
|
inherited Create(AOwner);
|
|
Buffered := True;
|
|
end;
|
|
|
|
procedure TcxvgPainter.DrawBackground;
|
|
var
|
|
I: Integer;
|
|
AParams: TcxViewParams;
|
|
R: TRect;
|
|
begin
|
|
AParams := VerticalGrid.Styles.GetBackgroundParams;
|
|
with ViewInfo.ViewRects.EmptyRects, VerticalGrid do
|
|
for I := 0 to Count - 1 do
|
|
begin
|
|
R := Rects[I];
|
|
if not DoDrawBackgroundPart(R, AParams) then
|
|
begin
|
|
Self.Canvas.Brush.Color := AParams.Color;
|
|
FillRect(R, AParams.Bitmap);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgPainter.DoPaint;
|
|
begin
|
|
DrawBackground;
|
|
DrawRows;
|
|
with ViewInfo do
|
|
DrawLines(LinesInfo, ClientRect);
|
|
DrawStyleFeatures;
|
|
end;
|
|
|
|
procedure TcxvgPainter.DrawButton(ARowHeader: TcxCustomRowHeaderInfo);
|
|
begin
|
|
with ARowHeader do
|
|
begin
|
|
if cxRectIsEmpty(ButtonRect) then Exit;
|
|
Painter.DrawExpandButton(Canvas, ButtonRect, Row.Expanded, ButtonColor);
|
|
if not Buffered then
|
|
Canvas.ExcludeClipRect(ButtonRect);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgPainter.DrawCategoryRowHeader(ARowHeader: TcxCustomRowHeaderInfo);
|
|
const
|
|
Parts: array[Boolean, 0..1] of Integer = (
|
|
(EBP_NORMALGROUPEXPAND, EBNGE_NORMAL),
|
|
(EBP_NORMALGROUPCOLLAPSE, EBNGC_NORMAL));
|
|
var
|
|
R: TRect;
|
|
ATheme: TdxTheme;
|
|
begin
|
|
if ViewInfo.UseCategoryExplorerStyle and (VerticalGrid.LookAndFeel.SkinPainter = nil) then
|
|
with ARowHeader do
|
|
begin
|
|
DrawCategoryRowIndent(ARowHeader);
|
|
Canvas.Brush.Style := bsSolid;
|
|
Canvas.Brush.Color := ViewParams.Color;
|
|
R := HeaderRect;
|
|
if (Row.Level > 0) and (PaintStyle = psDotNet) then
|
|
R.Left := IndentBounds.Right - (ViewInfo.RowIndentWidth + ViewInfo.VertLineWidth);
|
|
Canvas.FillRect(R);
|
|
ATheme := OpenTheme(totExplorerBar);
|
|
if ATheme <> 0 then
|
|
begin
|
|
DrawThemeBackground(ATheme, Canvas.Handle, EBP_NORMALGROUPHEAD, 0, @R);
|
|
if not cxRectIsEmpty(ButtonRect) and (ButtonRect.Left >= R.Left) then
|
|
begin
|
|
R := ButtonRect;
|
|
DrawThemeBackground(ATheme, Canvas.Handle, Parts[Row.Expanded, 0],
|
|
Parts[Row.Expanded, 1], @R);
|
|
end;
|
|
if CaptionsInfo.Count > 0 then
|
|
with CaptionsInfo[0] do
|
|
begin
|
|
Canvas.Brush.Style := bsClear;
|
|
Canvas.Font := ViewParams.Font;
|
|
Canvas.Font.Color := ViewParams.TextColor;
|
|
R := CaptionTextRect;
|
|
cxTextOut(Canvas.Canvas, Caption, R, TextFlags);
|
|
Canvas.Brush.Style := bsSolid;
|
|
DrawImage(CaptionsInfo[0]);
|
|
end;
|
|
DrawLines(LinesInfo, cxNullRect);
|
|
if not cxRectIsEmpty(FocusRect) and not VerticalGrid.IsDesigning then
|
|
Canvas.DrawFocusRect(FocusRect);
|
|
if Selected then
|
|
begin
|
|
Canvas.DrawFocusRect(HeaderRect);
|
|
Canvas.DrawFocusRect(cxRectInflate(HeaderRect, -1, -1));
|
|
end;
|
|
end
|
|
else
|
|
DrawRowHeader(ARowHeader);
|
|
end
|
|
else
|
|
DrawRowHeader(ARowHeader);
|
|
end;
|
|
|
|
procedure TcxvgPainter.DrawCategoryRowIndent(ARowHeader: TcxCustomRowHeaderInfo);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
with ARowHeader do
|
|
begin
|
|
if Transparent then Exit;
|
|
for I := 0 to CategoryIndents.Count - 2 do
|
|
with CategoryIndents[I]^ do
|
|
begin
|
|
Canvas.Brush.Color := ViewParams.Color;
|
|
Canvas.FillRect(Bounds);
|
|
end;
|
|
for I := 0 to RowIndents.Count - 1 do
|
|
with RowIndents[I]^ do
|
|
begin
|
|
Canvas.Brush.Color := ViewParams.Color;
|
|
Canvas.FillRect(Bounds);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgPainter.DrawHeaderDragImage(ARowHeader: TcxCustomRowHeaderInfo);
|
|
var
|
|
I: Integer;
|
|
R: TRect;
|
|
begin
|
|
with ARowHeader do
|
|
begin
|
|
for I := 0 to CaptionsInfo.Count - 1 do
|
|
DrawRowHeaderCell(CaptionsInfo[I], Transparent);
|
|
if ARowHeader is TcxMultiEditorRowHeaderInfo then
|
|
begin
|
|
DrawLines(LinesInfo, cxNullRect);
|
|
DrawHeaderSeparators(ARowHeader);
|
|
end;
|
|
R := HeaderRect;
|
|
R.Left := IndentBounds.Right;
|
|
Canvas.FrameRect(R, ViewInfo.BandBorderColor);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgPainter.DrawHeaderSeparators(ARowHeader: TcxCustomRowHeaderInfo);
|
|
var
|
|
I: Integer;
|
|
AOffset, R: TRect;
|
|
begin
|
|
if not (ARowHeader is TcxMultiEditorRowHeaderInfo) then Exit;
|
|
with TcxMultiEditorRowHeaderInfo(ARowHeader) do
|
|
begin
|
|
Canvas.Brush.Color := SeparatorInfo.ViewParams.Color;
|
|
Canvas.Font.Color := SeparatorInfo.ViewParams.TextColor;
|
|
AOffset := GetTextEditDrawTextOffset(taLeftJustify, True);
|
|
for I := 0 to SeparatorRects.Count - 1 do
|
|
begin
|
|
R := SeparatorRects[I];
|
|
if cxRectIsEmpty(R) then continue;
|
|
if not Transparent then
|
|
FillRect(R, SeparatorInfo.ViewParams.Bitmap);
|
|
with R do
|
|
begin
|
|
Inc(Top, AOffset.Top + 1);
|
|
Inc(Left, AOffset.Left + 1);
|
|
Dec(Bottom, AOffset.Bottom + 1);
|
|
Dec(Right, AOffset.Right + 1);
|
|
end;
|
|
cxTextOut(Canvas.Canvas, SeparatorInfo.Caption, R, SeparatorInfo.TextFlags);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgPainter.DrawImage(ACaptionInfo: TcxRowCaptionInfo);
|
|
var
|
|
ARgn: TcxRegion;
|
|
R: TRect;
|
|
begin
|
|
with ACaptionInfo do
|
|
begin
|
|
if ImageIndex = -1 then Exit;
|
|
ARgn := Canvas.GetClipRegion;
|
|
try
|
|
cxRectIntersect(R, ImageRect, CaptionRect);
|
|
Canvas.IntersectClipRect(R);
|
|
Canvas.DrawImage(Images, ImageRect.Left, ImageRect.Top, ImageIndex);
|
|
finally
|
|
Canvas.SetClipRegion(ARgn, roSet);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgPainter.DrawLines(ALinesInfo: TLineInfoList; R: TRect);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to ALinesInfo.Count - 1 do
|
|
with ALinesInfo[I]^ do
|
|
begin
|
|
if IsBrush then
|
|
Canvas.Brush.Assign(Brush)
|
|
else
|
|
Canvas.Brush.Color := Color;
|
|
Canvas.FillRect(Rect);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgPainter.DrawRow(ARowViewInfo: TcxCustomRowViewInfo);
|
|
var
|
|
I: Integer;
|
|
AValueInfo: TcxRowValueInfo;
|
|
begin
|
|
with ARowViewInfo do
|
|
begin
|
|
if ARowViewInfo is TcxCategoryRowViewInfo then
|
|
begin
|
|
if not VerticalGrid.DoDrawRowHeader(HeaderInfo) then
|
|
DrawCategoryRowHeader(HeaderInfo)
|
|
end
|
|
else
|
|
begin
|
|
if not VerticalGrid.DoDrawRowHeader(HeaderInfo) then
|
|
DrawRowHeader(HeaderInfo);
|
|
DrawHeaderSeparators(HeaderInfo);
|
|
DrawValuesSeparators(ARowViewInfo);
|
|
for I := 0 to ValuesInfo.Count - 1 do
|
|
begin
|
|
AValueInfo := ValuesInfo[I];
|
|
BeforeCustomDraw(AValueInfo);
|
|
if not VerticalGrid.DoDrawValue(AValueInfo) then
|
|
begin
|
|
AValueInfo.EditViewInfo.TextColor := Canvas.Font.Color;
|
|
AValueInfo.EditViewInfo.BackgroundColor := Canvas.Brush.Color;
|
|
DrawRowValueCell(AValueInfo);
|
|
end;
|
|
AfterCustomDraw(AValueInfo);
|
|
end;
|
|
end;
|
|
DrawLines(HeaderInfo.LinesInfo, cxNullRect);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgPainter.DrawRowHeader(ARowHeader: TcxCustomRowHeaderInfo);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
DrawRowIndent(ARowHeader);
|
|
with ARowHeader do
|
|
begin
|
|
for I := 0 to CaptionsInfo.Count - 1 do
|
|
DrawRowHeaderCell(CaptionsInfo[I], Transparent);
|
|
if not cxRectIsEmpty(FocusRect) then
|
|
Canvas.DrawFocusRect(FocusRect);
|
|
if Selected then
|
|
begin
|
|
Canvas.DrawFocusRect(HeaderRect);
|
|
Canvas.DrawFocusRect(cxRectInflate(HeaderRect, -1, -1));
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgPainter.DrawRowHeaderCell(
|
|
ACaptionInfo: TcxRowCaptionInfo; ATransparent: Boolean);
|
|
var
|
|
R: TRect;
|
|
begin
|
|
with ACaptionInfo do
|
|
begin
|
|
cxApplyViewParams(Canvas, ViewParams);
|
|
if not ATransparent then
|
|
FillRect(CaptionRect, ViewParams.Bitmap);
|
|
Canvas.Brush.Style := bsClear;
|
|
R := CaptionTextRect;
|
|
cxTextOut(Canvas.Canvas, Caption, R, TextFlags);
|
|
Canvas.Brush.Style := bsSolid;
|
|
DrawImage(ACaptionInfo);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgPainter.DrawRowIndent(
|
|
ARowHeader: TcxCustomRowHeaderInfo);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if ARowHeader.Transparent then Exit;
|
|
if not Buffered then DrawButton(ARowHeader);
|
|
with ARowHeader do
|
|
begin
|
|
for I := 0 to CategoryIndents.Count - 1 do
|
|
with CategoryIndents[I]^ do
|
|
begin
|
|
Canvas.Brush.Color := ViewParams.Color;
|
|
FillRect(Bounds, ViewParams.Bitmap);
|
|
end;
|
|
for I := 0 to RowIndents.Count - 1 do
|
|
with RowIndents[I]^ do
|
|
begin
|
|
Canvas.Brush.Color := ViewParams.Color;
|
|
FillRect(Bounds, ViewParams.Bitmap);
|
|
end;
|
|
end;
|
|
if Buffered then DrawButton(ARowHeader);
|
|
end;
|
|
|
|
procedure TcxvgPainter.DrawRows;
|
|
var
|
|
I: Integer;
|
|
ARowInfo: TcxCustomRowViewInfo;
|
|
begin
|
|
for I := 0 to ViewInfo.RowsViewInfo.Count - 1 do
|
|
begin
|
|
ARowInfo := ViewInfo.RowsViewInfo[I];
|
|
if Canvas.RectVisible(ARowInfo.RowRect) then
|
|
DrawRow(ARowInfo);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgPainter.DrawStyleFeatures;
|
|
begin
|
|
end;
|
|
|
|
procedure TcxvgPainter.DrawRowValueCell(AValueInfo: TcxRowValueInfo);
|
|
begin
|
|
with AValueInfo do
|
|
begin
|
|
if cxRectIsEmpty(DisplayRect) then Exit;
|
|
if ViewParams.Bitmap <> nil then
|
|
Canvas.FillRect(DisplayRect, ViewParams.Bitmap);
|
|
ViewInfo.PaintEx(Canvas);
|
|
if Focused and Self.ViewInfo.CalcHelper.IsDrawValueFocusRect and
|
|
not cxRectIsEmpty(FFocusRect) then
|
|
Canvas.DrawFocusRect(BoundsRect);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgPainter.DrawValuesSeparators(ARowViewInfo: TcxCustomRowViewInfo);
|
|
var
|
|
I, ASepPerRecord: Integer;
|
|
AViewParams: TcxViewParams;
|
|
ASeparatorInfo: TSeparatorInfo;
|
|
R, AOffset: TRect;
|
|
AStyle: TcxStyle;
|
|
AData: TcxvgContentParamsData;
|
|
begin
|
|
if not (ARowViewInfo is TcxMultiEditorRowViewInfo) then Exit;
|
|
with TcxMultiEditorRowViewInfo(ARowViewInfo) do
|
|
begin
|
|
if (FValuesInfo.Count = 0) or (SeparatorRects.Count = 0) then Exit;
|
|
ASeparatorInfo := TcxMultiEditorRowHeaderInfo(HeaderInfo).SeparatorInfo;
|
|
AOffset := GetTextEditDrawTextOffset(taLeftJustify, True);
|
|
ASepPerRecord := Row.Properties.Editors.Count - 1;
|
|
for I := 0 to SeparatorRects.Count - 1 do
|
|
begin
|
|
R := SeparatorRects[I];
|
|
if cxRectIsEmpty(R) then continue;
|
|
with VerticalGrid.Styles do
|
|
begin
|
|
AStyle := nil;
|
|
if Assigned(FOnGetContentStyle) then
|
|
FOnGetContentStyle(Control, nil, False,
|
|
ViewInfo.FirstVisibleRecordIndex + (I div ASepPerRecord), AStyle);
|
|
AData.Row := Row;
|
|
AData.Focused := False;
|
|
cxStylesToViewParams(VerticalGrid.Styles, vgs_Content, @AData,
|
|
[AStyle, Content], AViewParams);
|
|
end;
|
|
Canvas.Brush.Color := AViewParams.Color;
|
|
Canvas.Font.Color := AViewParams.TextColor;
|
|
FillRect(R, AViewParams.Bitmap);
|
|
with R do
|
|
begin
|
|
Inc(Top, AOffset.Top + 1);
|
|
Inc(Left, AOffset.Left + 1);
|
|
Dec(Bottom, AOffset.Bottom + 1);
|
|
Dec(Right, AOffset.Right + 1);
|
|
end;
|
|
cxTextOut(Canvas.Canvas, ASeparatorInfo.Caption, R,
|
|
ASeparatorInfo.TextFlags);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxvgPainter.FillRect(const R: TRect; ABitmap: TBitmap = nil);
|
|
begin
|
|
if (ABitmap = nil) or ABitmap.Empty then
|
|
Canvas.FillRect(R)
|
|
else
|
|
Canvas.FillRect(R, ABitmap);
|
|
end;
|
|
|
|
function TcxvgPainter.GetVerticalGrid: TcxCustomVerticalGrid;
|
|
begin
|
|
Result := TcxCustomVerticalGrid(Control);
|
|
end;
|
|
|
|
function TcxvgPainter.GetViewInfo: TcxvgCustomViewInfo;
|
|
begin
|
|
Result := TcxvgCustomViewInfo(inherited ViewInfo);
|
|
end;
|
|
|
|
{ TcxStyle3DPainter }
|
|
|
|
procedure TcxStyle3DPainter.DrawStyleFeatures;
|
|
begin
|
|
with ViewInfo do
|
|
DrawLines(FocusLinesInfo, ClientRect);
|
|
end;
|
|
|
|
{ TcxvgCustomRowStyles }
|
|
|
|
procedure TcxvgCustomRowStyles.Changed(AIndex: Integer);
|
|
begin
|
|
TcxCustomRow(GetOwner).Changed;
|
|
end;
|
|
|
|
{ TcxCategoryRowStyles }
|
|
|
|
procedure TcxCategoryRowStyles.Assign(Source: TPersistent);
|
|
begin
|
|
if Source is TcxCategoryRowStyles then
|
|
SetValue(vgrs_Header, TcxCategoryRowStyles(Source).GetValue(vgrs_Header));
|
|
inherited Assign(Source);
|
|
end;
|
|
|
|
{ TcxEditorRowStyles }
|
|
|
|
procedure TcxEditorRowStyles.Assign(Source: TPersistent);
|
|
begin
|
|
if Source is TcxEditorRowStyles then
|
|
SetValue(vgrs_Content, TcxCategoryRowStyles(Source).GetValue(vgrs_Content));
|
|
inherited Assign(Source);
|
|
end;
|
|
|
|
{ TcxVerticalGridStyleSheet }
|
|
|
|
function TcxVerticalGridStyleSheet.GetStylesValue: TcxVerticalGridStyles;
|
|
begin
|
|
Result := TcxVerticalGridStyles(GetStyles)
|
|
end;
|
|
|
|
procedure TcxVerticalGridStyleSheet.SetStylesValue(Value: TcxVerticalGridStyles);
|
|
begin
|
|
SetStyles(Value);
|
|
end;
|
|
|
|
class function TcxVerticalGridStyleSheet.GetStylesClass: TcxCustomStylesClass;
|
|
begin
|
|
Result := TcxVerticalGridStyles;
|
|
end;
|
|
|
|
{ TcxVerticalGridStyles }
|
|
|
|
procedure TcxVerticalGridStyles.Assign(Source: TPersistent);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
inherited Assign(Source);
|
|
if Source is TcxVerticalGridStyles then
|
|
for I := vgs_Category to vgs_IncSearch do
|
|
SetValue(I, TcxVerticalGridStyles(Source).GetValue(I));
|
|
end;
|
|
|
|
function TcxVerticalGridStyles.GetCategoryParams(
|
|
ARow: TcxCustomRow): TcxViewParams;
|
|
begin
|
|
cxStylesToViewParams(Self, vgs_Category, ARow,
|
|
[GetStyleFromEvent(FOnGetCategoryStyle, ARow),
|
|
TcxCategoryRowStyles(ARow.FStyles).Header, Category], Result)
|
|
end;
|
|
|
|
function TcxVerticalGridStyles.GetContentParams(
|
|
AEditProp: TcxCustomEditorRowProperties;
|
|
AFocused: Boolean; ARecordIndex: Integer): TcxViewParams;
|
|
var
|
|
AStyle: TcxStyle;
|
|
AData: TcxvgContentParamsData;
|
|
begin
|
|
AStyle := nil;
|
|
if Assigned(FOnGetContentStyle) then
|
|
FOnGetContentStyle(Control, AEditProp, AFocused, ARecordIndex, AStyle);
|
|
AData.Row := AEditProp.Row;
|
|
AData.Focused := AFocused;
|
|
cxStylesToViewParams(Self, vgs_Content, @AData, [AStyle,
|
|
TcxEditorRowStyles(AEditProp.Row.FStyles).Content, Content], Result);
|
|
end;
|
|
|
|
function TcxVerticalGridStyles.GetHeaderParams(
|
|
ARow: TcxCustomRow): TcxViewParams;
|
|
begin
|
|
cxStylesToViewParams(Self, vgs_Header, ARow,
|
|
[GetStyleFromEvent(FOnGetHeaderStyle, ARow),
|
|
TcxCategoryRowStyles(ARow.FStyles).Header, Header], Result)
|
|
end;
|
|
|
|
function TcxVerticalGridStyles.GetIncSearchParams: TcxViewParams;
|
|
begin
|
|
GetViewParams(vgs_IncSearch, nil, IncSearch, Result);
|
|
end;
|
|
|
|
function TcxVerticalGridStyles.GetSelectedHeaderParams(
|
|
ARow: TcxCustomRow): TcxViewParams;
|
|
begin
|
|
Result := GetSelectionParams;
|
|
CombineParamsWithStyle(GetStyleFromEvent(FOnGetHeaderStyle, ARow), [], Result)
|
|
end;
|
|
|
|
procedure TcxVerticalGridStyles.GetDefaultViewParams(Index: Integer;
|
|
AData: TObject; out AParams: TcxViewParams);
|
|
begin
|
|
TcxCustomVerticalGrid(Control).GetDefaultViewParams(Index, AData, AParams);
|
|
end;
|
|
|
|
function TcxVerticalGridStyles.GetStyleFromEvent(
|
|
const AEvent: TcxvgOnGetItemStyleEvent; AItem: TcxCustomRow): TcxStyle;
|
|
begin
|
|
Result := nil;
|
|
if Assigned(AEvent) then AEvent(Control, AItem, Result);
|
|
end;
|
|
|
|
procedure TcxVerticalGridStyles.CallInheritedDefaultViewParams(Index: Integer;
|
|
AData: Pointer; out AParams: TcxViewParams);
|
|
begin
|
|
inherited GetDefaultViewParams(Index, AData, AParams);
|
|
end;
|
|
|
|
{ TcxVerticalGridItemsCustomizeListBox }
|
|
|
|
constructor TcxVerticalGridItemsCustomizeListBox.CreateEx(AOwner: TComponent;
|
|
AVerticalGrid: TcxCustomVerticalGrid; IsCategoryListBox: Boolean);
|
|
begin
|
|
inherited Create(AOwner);
|
|
FVerticalGrid := AVerticalGrid;
|
|
FIsCategoryListBox := IsCategoryListBox;
|
|
Style := lbOwnerDrawFixed;
|
|
FCanvas := TcxCanvas.Create(inherited Canvas);
|
|
DoubleBuffered := True;
|
|
FDragAndDropItemIndex := -1;
|
|
end;
|
|
|
|
procedure TcxVerticalGridItemsCustomizeListBox.DragDrop(Source: TObject;
|
|
X, Y: Integer);
|
|
begin
|
|
if (Source = VerticalGrid) and (DragRow <> nil) then
|
|
VerticalGrid.DragDrop(Source, X, Y);
|
|
end;
|
|
|
|
destructor TcxVerticalGridItemsCustomizeListBox.Destroy;
|
|
begin
|
|
FreeAndNil(FCanvas);
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TcxVerticalGridItemsCustomizeListBox.CalcHeaderViewInfo(
|
|
const R: TRect; AHeaderInfo: TcxCustomRowHeaderInfo);
|
|
begin
|
|
AHeaderInfo.Row.ViewInfo.FViewInfo := VerticalGrid.ViewInfo;
|
|
AHeaderInfo.Calc(R, VerticalGrid.ViewInfo, nil, False);
|
|
end;
|
|
|
|
procedure TcxVerticalGridItemsCustomizeListBox.DragOver(Source: TObject;
|
|
X, Y: Integer; State: TDragState; var Accept: Boolean);
|
|
begin
|
|
Accept := (Source = VerticalGrid) and (DragRow <> nil) and
|
|
(DragRow.Options.CanMovedToCustomizationForm);
|
|
end;
|
|
|
|
procedure TcxVerticalGridItemsCustomizeListBox.DrawItem(
|
|
Index: Integer; Rect: TRect; State: TOwnerDrawState);
|
|
var
|
|
ACanvas: TcxCanvas;
|
|
AHeaderInfo: TcxCustomRowHeaderInfo;
|
|
begin
|
|
AHeaderInfo := TcxCustomRowHeaderInfo(Items.Objects[Index]);
|
|
with AHeaderInfo, Painter do
|
|
begin
|
|
ACanvas := FCanvas;
|
|
FCanvas := Self.Canvas;
|
|
try
|
|
CalcHeaderViewInfo(Rect, AHeaderInfo);
|
|
DrawHeaderDragImage(AHeaderInfo);
|
|
if ItemIndex = Index then FCanvas.InvertRect(Rect);
|
|
finally
|
|
FCanvas := ACanvas;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxVerticalGridItemsCustomizeListBox.InitDragAndDropObject;
|
|
var
|
|
AHeaderInfo: TcxCustomRowHeaderInfo;
|
|
R: TRect;
|
|
begin
|
|
with VerticalGrid.Controller do
|
|
if IsEditing then EditingController.HideEdit(False);
|
|
AHeaderInfo := TcxCustomRowHeaderInfo(Items.Objects[FDragAndDropItemIndex]);
|
|
R := cxRectOffset(ItemRect(FDragAndDropItemIndex), -FMouseDownPos.X, -FMouseDownPos.Y);
|
|
CalcHeaderViewInfo(R, AHeaderInfo);
|
|
VerticalGrid.Controller.FDragRow := AHeaderInfo.Row;
|
|
VerticalGrid.DragPos := cxPointOffset(R.TopLeft, FOffset);
|
|
VerticalGrid.BeginDrag(True);
|
|
end;
|
|
|
|
procedure TcxVerticalGridItemsCustomizeListBox.MouseDown(
|
|
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
|
var
|
|
AItem: Integer;
|
|
begin
|
|
inherited MouseDown(Button, Shift, X, Y);
|
|
if (Button = mbLeft) then
|
|
begin
|
|
AItem := ItemAtPos(Point(X, Y), True);
|
|
if AItem <> - 1 then
|
|
begin
|
|
with ItemRect(AItem) do
|
|
FOffset := Point(X - TopLeft.X, Y - TopLeft.Y);
|
|
FDragging := True;
|
|
FDragAndDropItemIndex := ItemIndex;
|
|
FMouseDownPos := Point(X, Y);
|
|
Invalidate;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxVerticalGridItemsCustomizeListBox.MouseMove(
|
|
Shift: TShiftState; X, Y: Integer);
|
|
begin
|
|
inherited MouseMove(Shift, X, Y);
|
|
if (FDragAndDropItemIndex <> -1) and not IsPointInDragDetectArea(FMouseDownPos, X, Y) then
|
|
begin
|
|
InitDragAndDropObject;
|
|
FDragAndDropItemIndex := -1;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxVerticalGridItemsCustomizeListBox.MouseUp(
|
|
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
|
begin
|
|
inherited MouseUp(Button, Shift, X, Y);
|
|
FDragging := False;
|
|
FDragAndDropItemIndex := -1;
|
|
Invalidate;
|
|
VerticalGrid.Controller.CheckEdit;
|
|
end;
|
|
|
|
procedure TcxVerticalGridItemsCustomizeListBox.RefreshList;
|
|
|
|
procedure CheckRow(ARow: TcxCustomRow; AIsCategory: Boolean);
|
|
begin
|
|
if ((ARow is TcxCategoryRow) = AIsCategory) and not ARow.Visible and
|
|
ARow.Options.ShowInCustomizationForm then
|
|
Items.AddObject('', ARow.ViewInfo.HeaderInfo);
|
|
end;
|
|
|
|
var
|
|
I: Integer;
|
|
ASaveIndex: Integer;
|
|
begin
|
|
ASaveIndex := ItemIndex;
|
|
Items.Clear;
|
|
Items.BeginUpdate;
|
|
with FVerticalGrid do
|
|
try
|
|
for I := 0 to Rows.Count - 1 do CheckRow(Rows[I], FIsCategoryListBox);
|
|
finally
|
|
if FDragging then ItemIndex := ASaveIndex;
|
|
Items.EndUpdate;
|
|
end;
|
|
Invalidate;
|
|
end;
|
|
|
|
procedure TcxVerticalGridItemsCustomizeListBox.CNDrawItem(
|
|
var Message: TWMDrawItem);
|
|
begin
|
|
if not IsPaint then Exit;
|
|
with Message.DrawItemStruct^ do
|
|
begin
|
|
Canvas.Canvas.Handle := hDC;
|
|
Canvas.Font := Font;
|
|
Canvas.Brush := Brush;
|
|
if Integer(itemID) >= 0 then
|
|
{$IFDEF DELPHI5}
|
|
DrawItem(itemID, rcItem, TOwnerDrawState(LongRec(itemState).Lo))
|
|
{$ELSE}
|
|
DrawItem(itemID, rcItem, TOwnerDrawState(Byte(itemState)))
|
|
{$ENDIF}
|
|
else
|
|
Canvas.FillRect(rcItem);
|
|
Canvas.Canvas.Handle := 0;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxVerticalGridItemsCustomizeListBox.WMCancelMode(
|
|
var Message: TWMCancelMode);
|
|
begin
|
|
inherited;
|
|
FDragging := False;
|
|
ItemIndex := -1;
|
|
FDragAndDropItemIndex := -1;
|
|
Invalidate;
|
|
end;
|
|
|
|
procedure TcxVerticalGridItemsCustomizeListBox.WMPaint(var Message: TMessage);
|
|
begin
|
|
IsPaint := True;
|
|
try
|
|
inherited;
|
|
finally
|
|
IsPaint := False;
|
|
end;
|
|
end;
|
|
|
|
function TcxVerticalGridItemsCustomizeListBox.GetDragRow: TcxCustomRow;
|
|
begin
|
|
Result := VerticalGrid.Controller.DragRow;
|
|
end;
|
|
|
|
function TcxVerticalGridItemsCustomizeListBox.GetPainter: TcxvgPainter;
|
|
begin
|
|
Result := VerticalGrid.Painter;
|
|
end;
|
|
|
|
{ TcxVerticalGridCustomizationForm }
|
|
|
|
constructor TcxVerticalGridCustomizationForm.CreateEx(
|
|
AOwner: TcxVerticalGridCustomizing);
|
|
begin
|
|
CreateNew(nil);
|
|
FOwner := AOwner;
|
|
end;
|
|
|
|
procedure TcxVerticalGridCustomizationForm.CreateParams(
|
|
var Params: TCreateParams);
|
|
begin
|
|
inherited;
|
|
with Params do
|
|
begin
|
|
Style := Style or WS_POPUP;
|
|
if not VerticalGrid.IsDestroying then
|
|
WndParent := VerticalGrid.Handle
|
|
else
|
|
WndParent := 0;
|
|
end;
|
|
end;
|
|
|
|
destructor TcxVerticalGridCustomizationForm.Destroy;
|
|
begin
|
|
FreeAndNil(FHookTimer);
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TcxVerticalGridCustomizationForm.DoClose(var Action: TCloseAction);
|
|
begin
|
|
FreeAndNil(FHookTimer);
|
|
inherited DoClose(Action);
|
|
end;
|
|
|
|
procedure TcxVerticalGridCustomizationForm.DoShow;
|
|
begin
|
|
if FHookTimer = nil then
|
|
begin
|
|
FHookTimer := TTimer.Create(nil);
|
|
with FHookTimer do
|
|
begin
|
|
Interval := 100;
|
|
OnTimer := HookTimerHandler;
|
|
end;
|
|
end;
|
|
inherited DoShow;
|
|
end;
|
|
|
|
function TcxVerticalGridCustomizationForm.GetVerticalGrid: TcxCustomVerticalGrid;
|
|
begin
|
|
Result := Customizing.VerticalGrid;
|
|
end;
|
|
|
|
procedure TcxVerticalGridCustomizationForm.HookTimerHandler(Sender: TObject);
|
|
begin
|
|
if IsIconic(Application.Handle) then
|
|
Visible := False
|
|
else
|
|
if not VerticalGrid.Visible or not IsWindowVisible(VerticalGrid.Handle) then
|
|
VerticalGrid.Customizing.Visible := False
|
|
else
|
|
if not Visible then
|
|
begin
|
|
ShowWindow(Handle, SW_SHOWNOACTIVATE);
|
|
Visible := True;
|
|
end;
|
|
end;
|
|
|
|
{ TcxVerticalGridCustomizing }
|
|
|
|
constructor TcxVerticalGridCustomizing.Create(AOwner: TPersistent);
|
|
begin
|
|
FVerticalGrid := TcxCustomVerticalGrid(AOwner);
|
|
FVisible := False;
|
|
FRowCount := 10;
|
|
FLastPosition := cxPoint(-10000, -10000);
|
|
FShowCategoryButtons := True;
|
|
FShowCategoryTab := True;
|
|
end;
|
|
|
|
destructor TcxVerticalGridCustomizing.Destroy;
|
|
begin
|
|
Visible := False;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TcxVerticalGridCustomizing.Assign(Source: TPersistent);
|
|
begin
|
|
if Source is TcxVerticalGridCustomizing then
|
|
begin
|
|
RowCount := TcxVerticalGridCustomizing(Source).RowCount;
|
|
Visible := TcxVerticalGridCustomizing(Visible).Visible;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxVerticalGridCustomizing.MakeCategorySheetVisible;
|
|
begin
|
|
if Visible and ((FTabSheetCategories <> nil) and (FCategoryListBox.Parent = FTabSheetCategories)) then
|
|
FPageControl.ActivePage := FTabSheetCategories;
|
|
end;
|
|
|
|
procedure TcxVerticalGridCustomizing.MakeRowSheetVisible;
|
|
begin
|
|
if Visible and (FRowListBox.Parent = FTabSheetRows) then
|
|
FPageControl.ActivePage := FTabSheetRows;
|
|
end;
|
|
|
|
procedure TcxVerticalGridCustomizing.AdjustControls;
|
|
begin
|
|
with VerticalGrid do
|
|
begin
|
|
SetControlParent(FPageControl, FForm);
|
|
SetControlParent(FTabSheetRows, FPageControl);
|
|
FTabSheetRows.PageControl := FPageControl;
|
|
SetControlParent(FRowListBox, FTabSheetRows);
|
|
if Assigned(FTabSheetCategories) then
|
|
begin
|
|
SetControlParent(FTabSheetCategories, FPageControl);
|
|
FTabSheetCategories.PageControl := FPageControl;
|
|
SetControlParent(FCategoryListBox, FTabSheetCategories);
|
|
end;
|
|
end;
|
|
ShowCustomizingForm;
|
|
end;
|
|
|
|
function TcxVerticalGridCustomizing.CanDrop(const P: TPoint): Boolean;
|
|
|
|
function CheckListBox(AListBox: TcxVerticalGridItemsCustomizeListBox): Boolean;
|
|
begin
|
|
if AListBox = nil then
|
|
Result := False
|
|
else
|
|
with AListBox do
|
|
Result := Visible and cxRectPtIn(ClientRect, ScreenToClient(P));
|
|
end;
|
|
|
|
var
|
|
ADragCategoryRow: Boolean;
|
|
begin
|
|
Result := False;
|
|
if not Visible then Exit;
|
|
ADragCategoryRow := VerticalGrid.Controller.DragRow is TcxCategoryRow;
|
|
if ADragCategoryRow then
|
|
Result := CheckListBox(FCategoryListBox)
|
|
else
|
|
Result := CheckListBox(FRowListBox);
|
|
end;
|
|
|
|
procedure TcxVerticalGridCustomizing.CreateCategoryPanel;
|
|
|
|
function CreateButton(ALeft, ATabOrder: Integer; const ACaption: string;
|
|
AOnClick: TNotifyEvent): TcxButton;
|
|
begin
|
|
Result := TcxButton.Create(nil);
|
|
with Result do
|
|
begin
|
|
Left := ALeft;
|
|
Top := 7;
|
|
Width := 75;
|
|
Height := 25;
|
|
Caption := ACaption;
|
|
TabOrder := ATabOrder;
|
|
LookAndFeel.MasterLookAndFeel := VerticalGrid.LookAndFeel;
|
|
Enabled := ATabOrder = 0;
|
|
OnClick := AOnClick;
|
|
Parent := FPanel;
|
|
end;
|
|
end;
|
|
|
|
begin
|
|
FPanel := TPanel.Create(nil);
|
|
FPanel.Align := alBottom;
|
|
FPanel.Height := 35;
|
|
FPanel.BevelOuter := bvNone;
|
|
FPanel.Visible := FShowCategoryButtons;
|
|
FPanel.Parent := FTabSheetCategories;
|
|
FButtonNew := CreateButton(7, 0,
|
|
cxGetResourceString(@cxSvgCustomizeNewCategory), CreateCategoryClick);
|
|
FButtonDelete := CreateButton(90, 1,
|
|
cxGetResourceString(@cxSvgCustomizeDeleteCategory), DeleteCategoryClick);
|
|
end;
|
|
|
|
procedure TcxVerticalGridCustomizing.CreateCategoryRow;
|
|
var
|
|
ARow: TcxCategoryRow;
|
|
S: string;
|
|
begin
|
|
if cxShowNewCategoryForm(Form, S, VerticalGrid.LookAndFeel) then
|
|
begin
|
|
VerticalGrid.BeginUpdate;
|
|
try
|
|
ARow := TcxCategoryRow(VerticalGrid.Add(TcxCategoryRow));
|
|
ARow.Visible := False;
|
|
ARow.Properties.Caption := S;
|
|
ARow.Name := CreateUniqueName(VerticalGrid.Owner,
|
|
VerticalGrid, ARow, 'Tcx', 'RuntimeCreatedRow');
|
|
finally
|
|
Modified;
|
|
VerticalGrid.EndUpdate;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxVerticalGridCustomizing.CreateControls;
|
|
begin
|
|
if FForm <> nil then Exit;
|
|
FSaveDragMode := VerticalGrid.DragMode;
|
|
VerticalGrid.DragMode := dmAutomatic;
|
|
CreateCustomizingForm;
|
|
FRowListBox := TcxVerticalGridItemsCustomizeListBox.CreateEx(nil, VerticalGrid, False);
|
|
FPageControl := TPageControl.Create(nil);
|
|
FPageControl.HotTrack := True;
|
|
FTabSheetRows := TTabSheet.Create(FPageControl);
|
|
FTabSheetRows.Caption := cxGetResourceString(@cxSvgCustomizeRowsCaption);
|
|
FTabSheetRows.TabVisible := True;
|
|
if FShowCategoryTab then
|
|
begin
|
|
FCategoryListBox := TcxVerticalGridItemsCustomizeListBox.CreateEx(nil, VerticalGrid, True);
|
|
FCategoryListBox.OnClick := UpdateButtons;
|
|
FTabSheetCategories := TTabSheet.Create(FPageControl);
|
|
FTabSheetCategories.Caption := cxGetResourceString(@cxSvgCustomizeCategoriesCaption);
|
|
FTabSheetCategories.TabVisible := True;
|
|
CreateCategoryPanel;
|
|
end;
|
|
AdjustControls;
|
|
end;
|
|
|
|
procedure TcxVerticalGridCustomizing.CreateCustomizingForm;
|
|
var
|
|
I: Integer;
|
|
const
|
|
UnusedItems: array[0..4, 0..1] of Integer =
|
|
((7, MF_BYPOSITION), (5, MF_BYPOSITION), (SC_MAXIMIZE, MF_BYCOMMAND),
|
|
(SC_MINIMIZE, MF_BYCOMMAND), (SC_RESTORE, MF_BYCOMMAND));
|
|
begin
|
|
FForm := TcxVerticalGridCustomizationForm.CreateEx(Self);
|
|
with FForm do
|
|
begin
|
|
Visible := False;
|
|
Caption := cxGetResourceString(@cxSvgCustomizeCaption);
|
|
BorderStyle := bsSizeToolWin;
|
|
BorderIcons := [biSystemMenu];
|
|
Font.Assign(VerticalGrid.Font);
|
|
ClientWidth := SizeDelta.cx * cxTextWidth(Font, '0');
|
|
FLineHeight := cxTextHeight(Font) + SizeDelta.cy;
|
|
ClientHeight := (RowCount + 1) * FLineHeight;
|
|
Constraints.MinWidth := Width;
|
|
Color := clBtnFace;
|
|
OnShow := FormShow;
|
|
OnClose := FormClose;
|
|
for I := 0 to High(UnusedItems) do
|
|
DeleteMenu(GetSystemMenu(Handle, False), UnusedItems[I, 0], UnusedItems[I, 1]);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxVerticalGridCustomizing.FormClose(Sender: TObject; var Action: TCloseAction);
|
|
|
|
function CheckIndex(AListBox: TListBox): Integer;
|
|
begin
|
|
if (AListBox = nil) or (AListBox.Parent = nil) then
|
|
Result := -1
|
|
else
|
|
Result := AListBox.ItemIndex;
|
|
end;
|
|
|
|
begin
|
|
FLastPosition := FForm.BoundsRect.TopLeft;
|
|
FLastHeaderIndex := CheckIndex(FRowListBox);
|
|
FLastBandIndex := CheckIndex(FCategoryListBox);
|
|
Visible := False;
|
|
VerticalGrid.DoCustomizationVisibleChanged;
|
|
end;
|
|
|
|
procedure TcxVerticalGridCustomizing.FormShow(Sender: TObject);
|
|
begin
|
|
VerticalGrid.DoCustomizationVisibleChanged;
|
|
end;
|
|
|
|
procedure TcxVerticalGridCustomizing.LookAndFeelChanged;
|
|
begin
|
|
FCategoryListBox.Invalidate;
|
|
FRowListBox.Invalidate;
|
|
FPageControl.Invalidate;
|
|
end;
|
|
|
|
procedure TcxVerticalGridCustomizing.ReleaseControls;
|
|
|
|
procedure ReleaseControl(var AControl: TControl);
|
|
begin
|
|
if AControl = nil then Exit;
|
|
AControl.Parent := nil;
|
|
FreeAndNil(AControl);
|
|
end;
|
|
|
|
begin
|
|
if FForm <> nil then
|
|
try
|
|
FLastPosition := Point(FForm.Left, FForm.Top);
|
|
ReleaseControl(TControl(FButtonNew));
|
|
ReleaseControl(TControl(FButtonDelete));
|
|
ReleaseControl(TControl(FPanel));
|
|
ReleaseControl(TControl(FRowListBox));
|
|
ReleaseControl(TControl(FCategoryListBox));
|
|
ReleaseControl(TControl(FTabSheetCategories));
|
|
ReleaseControl(TControl(FTabSheetRows));
|
|
ReleaseControl(TControl(FPageControl));
|
|
FLastBandIndex := -1;
|
|
FLastHeaderIndex := -1;
|
|
if not VerticalGrid.IsDestroying then
|
|
begin
|
|
VerticalGrid.DragMode := FSaveDragMode;
|
|
FForm.Release
|
|
end
|
|
else
|
|
FForm.Free;
|
|
finally
|
|
FForm := nil;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxVerticalGridCustomizing.SetControlParent(AControl, AParent: TWinControl);
|
|
begin
|
|
AControl.Parent := AParent;
|
|
if AParent <> nil then
|
|
begin
|
|
AControl.Align := alClient;
|
|
TControlAccess(AControl).ParentFont := True;
|
|
TControlAccess(AControl).ParentColor := True;
|
|
Visible := True;
|
|
end;
|
|
end;
|
|
|
|
function TcxVerticalGridCustomizing.SizeDelta: TSize;
|
|
begin
|
|
Result := cxSize(31, 4);
|
|
end;
|
|
|
|
procedure TcxVerticalGridCustomizing.ComponentRemoved(Sender: TObject);
|
|
begin
|
|
end;
|
|
|
|
procedure TcxVerticalGridCustomizing.Modified;
|
|
begin
|
|
Update;
|
|
end;
|
|
|
|
procedure TcxVerticalGridCustomizing.ValidateListBox(
|
|
AListBox: TcxVerticalGridItemsCustomizeListBox; AIndex: Integer);
|
|
begin
|
|
if (AListBox = nil) or (AListBox.Parent = nil) then Exit;
|
|
AListBox.RefreshList;
|
|
if (AIndex >= 0) and (AIndex < AListBox.Items.Count) then
|
|
AListBox.ItemIndex := AIndex;
|
|
end;
|
|
|
|
procedure TcxVerticalGridCustomizing.Update;
|
|
begin
|
|
if (FRowListBox <> nil) and (FRowListBox.Parent <> nil) then
|
|
FRowListBox.RefreshList;
|
|
if (FCategoryListBox <> nil) and (FCategoryListBox.Parent <> nil) then
|
|
begin
|
|
FCategoryListBox.RefreshList;
|
|
UpdateButtons(nil);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxVerticalGridCustomizing.CreateCategoryClick(Sender: TObject);
|
|
begin
|
|
CreateCategoryRow;
|
|
end;
|
|
|
|
procedure TcxVerticalGridCustomizing.DeleteCategoryClick(Sender: TObject);
|
|
var
|
|
ARowHeader: TcxCustomRowHeaderInfo;
|
|
begin
|
|
with CategoryListBox do
|
|
if ItemIndex >= 0 then
|
|
begin
|
|
ARowHeader := TcxCustomRowHeaderInfo(Items.Objects[ItemIndex]);
|
|
Items.Delete(ItemIndex);
|
|
ARowHeader.Row.Free;
|
|
end;
|
|
Modified;
|
|
end;
|
|
|
|
procedure TcxVerticalGridCustomizing.SetRowCount(Value: Integer);
|
|
begin
|
|
if Value < 2 then Value := 2;
|
|
FRowCount := Value;
|
|
end;
|
|
|
|
procedure TcxVerticalGridCustomizing.SetShowCategoryButtons(
|
|
const Value: Boolean);
|
|
begin
|
|
FShowCategoryButtons := Value;
|
|
if FPanel <> nil then FPanel.Visible := Value;
|
|
end;
|
|
|
|
procedure TcxVerticalGridCustomizing.SetVisible(Value: Boolean);
|
|
|
|
function CanVisible: Boolean;
|
|
begin
|
|
Result := VerticalGrid.Rows.Count > 0;
|
|
end;
|
|
|
|
begin
|
|
if Value <> FVisible then
|
|
begin
|
|
if Value and not CanVisible then Exit;
|
|
FVisible := Value;
|
|
if not Value then
|
|
ReleaseControls
|
|
else
|
|
CreateControls;
|
|
end;
|
|
end;
|
|
|
|
function GetDesktopRect: TRect;
|
|
begin
|
|
{$IFDEF DELPHI6}
|
|
Result := Screen.DesktopRect;
|
|
{$ELSE}
|
|
with Result do
|
|
begin
|
|
Top := GetSystemMetrics(SM_YVIRTUALSCREEN);
|
|
Left := GetSystemMetrics(SM_XVIRTUALSCREEN);
|
|
Bottom := Top + GetSystemMetrics(SM_CYVIRTUALSCREEN);
|
|
Right := Left + GetSystemMetrics(SM_CXVIRTUALSCREEN);
|
|
end;
|
|
{$ENDIF}
|
|
end;
|
|
|
|
procedure TcxVerticalGridCustomizing.ShowCustomizingForm;
|
|
var
|
|
P: TPoint;
|
|
R: TRect;
|
|
begin
|
|
if (CustomizingPos.X <> -10000) and (CustomizingPos.Y <> -10000) then
|
|
begin
|
|
FForm.Left := CustomizingPos.X;
|
|
FForm.Top := CustomizingPos.Y;
|
|
end
|
|
else
|
|
begin
|
|
R := GetDesktopRect;
|
|
P := VerticalGrid.ClientToScreen(cxPoint(VerticalGrid.Width, 0));
|
|
with FForm do
|
|
begin
|
|
if P.X + Width > R.Right then
|
|
P.X := R.Right - Width;
|
|
if P.Y + Height > R.Bottom then
|
|
P.Y := R.Bottom - Height;
|
|
if P.X < R.Left then
|
|
P.X := R.Left;
|
|
if P.Y < R.Top then
|
|
P.Y := R.Top;
|
|
SetBounds(P.X, P.Y, Width, Height);
|
|
end;
|
|
end;
|
|
ValidateListBox(FRowListBox, FLastHeaderIndex);
|
|
ValidateListBox(FCategoryListBox, FLastBandIndex);
|
|
FForm.Show;
|
|
end;
|
|
|
|
procedure TcxVerticalGridCustomizing.UpdateButtons(Sender: TObject);
|
|
begin
|
|
FButtonDelete.Enabled := FCategoryListBox.ItemIndex <> -1;
|
|
end;
|
|
|
|
initialization
|
|
RegisterClasses([TcxCategoryRow, TcxEditorRow, TcxMultiEditorRow]);
|
|
RegisterClasses([TcxCaptionRowProperties, TcxEditorRowProperties, TcxMultiEditorRowProperties]);
|
|
|
|
Screen.Cursors[crcxInspectorInsert] := LoadCursor(HInstance, cxInspectorInsertCursor);
|
|
Screen.Cursors[crcxInspectorAddChild] := LoadCursor(HInstance, cxInspectorAddChildCursor);
|
|
Screen.Cursors[crcxInspectorAdd] := LoadCursor(HInstance, cxInspectorAddCursor);
|
|
Screen.Cursors[crcxInspectorHide] := LoadCursor(HInstance, cxInspectorHideCursor);
|
|
Screen.Cursors[crcxInspectorNoDrag] := LoadCursor(HInstance, cxInspectorNoDragCursor);
|
|
|
|
finalization
|
|
{$IFDEF DELPHI4}
|
|
DestroyCursor(Screen.Cursors[crcxInspectorInsert]);
|
|
DestroyCursor(Screen.Cursors[crcxInspectorAddChild]);
|
|
DestroyCursor(Screen.Cursors[crcxInspectorAdd]);
|
|
DestroyCursor(Screen.Cursors[crcxInspectorHide]);
|
|
DestroyCursor(Screen.Cursors[crcxInspectorNoDrag]);
|
|
{$ENDIF}
|
|
end.
|
|
|