{********************************************************************} { } { Developer Express Visual Component Library } { Express Cross Platform Common Editing Library } { } { Copyright (c) 2000-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 COMMONEDITINGLIBRARY 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 cxInplaceContainer; {$I cxVer.inc} interface uses Classes, SysUtils, Windows, Messages, {$IFDEF DELPHI6} Variants, Types, {$ENDIF} Forms, Controls, StdCtrls, Graphics, cxVariants, cxClasses, cxControls, cxGraphics, cxStyles, cxContainer, cxEdit, cxTextEdit, cxData, cxCustomData, cxDataUtils, cxDataStorage, cxLookAndFeels, cxLookAndFeelPainters, cxEditDataRegisteredRepositoryItems, cxGeometry, cxLibraryConsts; const ecs_Content = 0; ecs_Background = 1; ecs_Inactive = 2; ecs_Selection = 3; ecs_EditContainerStylesMaxIndex = ecs_Content; ecs_EditingStylesMaxIndex = ecs_Selection; // predefined hit codes echc_Empty = 0; echc_IsMouseEvent = 1; // viewinfo states cvis_IsDirty = 1; cvis_StyleInvalid = 2; cxSizingMarkWidth = 1; cxScrollWidthDragInterval = 50; type TcxDragSizingDirection = (dsdHorz, dsdVert); TcxGetEditPropertiesEvent = procedure(Sender: TObject; AData: Pointer; var AEditProperties: TcxCustomEditProperties) of object; TcxOnGetContentStyleEvent = procedure(Sender: TObject; AData: Pointer; out AStyle: TcxStyle) of object; TcxInplaceEditContainerClass = class of TcxCustomInplaceEditContainer; TcxCustomInplaceEditContainer = class; TcxItemDataBindingClass = class of TcxCustomItemDataBinding; TcxCustomControlDragAndDropObjectClass = class of TcxCustomControlDragAndDropObject; TcxEditingController = class; TcxEditingControllerClass = class of TcxEditingController; TcxCustomEditStyleClass = class of TcxCustomEditStyle; TcxCustomControlControllerClass = class of TcxCustomControlController; TcxCustomControlController = class; TcxControlDataController = class; TcxCustomControlPainter = class; TcxEditingControl = class; TcxHotTrackControllerClass = class of TcxHotTrackController; TcxCustomHitTestController = class; TcxEditItemShowEditButtons = (eisbDefault, eisbNever, eisbAlways); TcxEditingControlEditShowButtons = (ecsbAlways, ecsbFocused, ecsbNever); TcxCustomControlViewInfo = class; TcxCustomControlStyles = class; TcxCustomViewInfoItem = class; TcxCustomCellViewInfoClass = class of TcxCustomViewInfoItem; TcxEditCellViewInfo = class; TcxEditCellViewInfoClass = class of TcxEditCellViewInfo; TcxHitCode = type Int64; { TcxContainerItemDefaultValuesProvider } TcxContainerItemDefaultValuesProvider = class(TcxCustomEditDefaultValuesProvider) function IsDisplayFormatDefined(AIsCurrencyValueAccepted: Boolean): Boolean; override; end; { TcxCustomItemDataBinding } TcxCustomItemDataBinding = class(TcxOwnedPersistent) private FDefaultValuesProvider: TcxCustomEditDefaultValuesProvider; FData: Pointer; function GetDataController: TcxCustomDataController; function GetEditContainer: TcxCustomInplaceEditContainer; protected function DefaultRepositoryItem: TcxEditRepositoryItem; virtual; function GetDefaultCaption: string; virtual; function GetDefaultValuesProvider(AProperties: TcxCustomEditProperties): IcxEditDefaultValuesProvider; virtual; function GetDefaultValuesProviderClass: TcxCustomEditDefaultValuesProviderClass; virtual; function GetValueTypeClass: TcxValueTypeClass; virtual; procedure Init; virtual; function IsDisplayFormatDefined(AIsCurrencyValueAccepted: Boolean): Boolean; procedure ValueTypeClassChanged; virtual; property DataController: TcxCustomDataController read GetDataController; property DefaultValuesProvider: TcxCustomEditDefaultValuesProvider read FDefaultValuesProvider; property EditContainer: TcxCustomInplaceEditContainer read GetEditContainer; public constructor Create(AOwner: TPersistent); override; destructor Destroy; override; property Data: Pointer read FData write FData; end; { TcxItemDataBinding } TcxItemDataBinding = class(TcxCustomItemDataBinding) private FValueTypeClass: TcxValueTypeClass; function GetValueType: string; procedure SetValueType(const Value: string); procedure SetValueTypeClass(Value: TcxValueTypeClass); protected function GetValueTypeClass: TcxValueTypeClass; override; function IsValueTypeStored: Boolean; virtual; public procedure Assign(Source: TPersistent); override; property ValueTypeClass: TcxValueTypeClass read GetValueTypeClass write SetValueTypeClass; published property ValueType: string read GetValueType write SetValueType stored IsValueTypeStored; end; { TcxControlDataController } TcxControlDataController = class(TcxDataController) private function GetControl: TcxEditingControl; protected procedure UpdateControl(AInfo: TcxUpdateControlInfo); override; public function GetItem(Index: Integer): TObject; override; function GetItemID(AItem: TObject): Integer; override; function GetItemValueSource(AItemIndex: Integer): TcxDataEditValueSource; override; procedure UpdateData; override; procedure UpdateItemIndexes; override; end; { TcxCustomEditContainerItemOptions } TcxCustomEditContainerItemOptionsClass = class of TcxCustomEditContainerItemOptions; TcxCustomEditContainerItemOptions = class(TcxOwnedPersistent) private FCustomizing: Boolean; FEditing: Boolean; FFiltering: Boolean; FFocusing: Boolean; FIncSearch: Boolean; FMoving: Boolean; FShowEditButtons: TcxEditItemShowEditButtons; FSorting: Boolean; FTabStop: Boolean; function GetEditContainer: TcxCustomInplaceEditContainer; procedure SetEditing(Value: Boolean); procedure SetFiltering(Value: Boolean); procedure SetFocusing(Value: Boolean); procedure SetIncSearch(Value: Boolean); procedure SetShowEditButtons(Value: TcxEditItemShowEditButtons); protected procedure Changed; virtual; property EditContainer: TcxCustomInplaceEditContainer read GetEditContainer; property Moving: Boolean read FMoving write FMoving default True; property Customizing: Boolean read FCustomizing write FCustomizing default True; property Sorting: Boolean read FSorting write FSorting default True; property Editing: Boolean read FEditing write SetEditing default True; property Filtering: Boolean read FFiltering write SetFiltering default True; property Focusing: Boolean read FFocusing write SetFocusing default True; property IncSearch: Boolean read FIncSearch write SetIncSearch default True; property ShowEditButtons: TcxEditItemShowEditButtons read FShowEditButtons write SetShowEditButtons default eisbDefault; property TabStop: Boolean read FTabStop write FTabStop default True; public constructor Create(AOwner: TPersistent); override; procedure Assign(AOwner: TPersistent); override; end; { TcxControlOptionsView } TcxControlOptionsViewClass = class of TcxControlOptionsView; TcxControlOptionsView = class(TcxOwnedPersistent) private FCellAutoHeight: Boolean; FCellEndEllipsis: Boolean; FCellTextMaxLineCount: Integer; FShowEditButtons: TcxEditingControlEditShowButtons; function GetEditingControl: TcxEditingControl; function GetScrollBars: TScrollStyle; procedure SetCellAutoHeight(const Value: Boolean); procedure SetCellEndEllipsis(const Value: Boolean); procedure SetCellTextMaxLineCount(const Value: Integer); procedure SetScrollBars(const Value: TScrollStyle); procedure SetShowEditButtons(const Value: TcxEditingControlEditShowButtons); protected procedure Changed; virtual; property EditingControl: TcxEditingControl read GetEditingControl; public constructor Create(AOwner: TPersistent); override; procedure Assign(Source: TPersistent); override; published property CellAutoHeight: Boolean read FCellAutoHeight write SetCellAutoHeight default False; property CellEndEllipsis: Boolean read FCellEndEllipsis write SetCellEndEllipsis default False; property CellTextMaxLineCount: Integer read FCellTextMaxLineCount write SetCellTextMaxLineCount default 0; property ScrollBars: TScrollStyle read GetScrollBars write SetScrollBars default ssBoth; property ShowEditButtons: TcxEditingControlEditShowButtons read FShowEditButtons write SetShowEditButtons default ecsbNever; end; { TcxControlOptionsData } TcxControlOptionsDataClass = class of TcxControlOptionsData; TcxControlOptionsData = class(TcxOwnedPersistent) private FCancelOnExit: Boolean; FEditing: Boolean; function GetEditingControl: TcxEditingControl; procedure SetEditing(Value: Boolean); protected procedure Changed; virtual; public constructor Create(AOwner: TPersistent); override; procedure Assign(Source: TPersistent); override; property EditingControl: TcxEditingControl read GetEditingControl; published property CancelOnExit: Boolean read FCancelOnExit write FCancelOnExit default True; property Editing: Boolean read FEditing write SetEditing default True; end; { TcxControlOptionsBehavior } TcxControlOptionsBehaviorClass = class of TcxControlOptionsBehavior; TcxControlOptionsBehavior = class(TcxOwnedPersistent) private FAlwaysShowEditor: Boolean; FCellHints: Boolean; FDragDropText: Boolean; FFocusCellOnCycle: Boolean; FFocusFirstCellOnNewRecord: Boolean; FGoToNextCellOnEnter: Boolean; FGoToNextCellOnTab: Boolean; FImmediateEditor: Boolean; FIncSearch: Boolean; FIncSearchItem: TcxCustomInplaceEditContainer; function GetEditingControl: TcxEditingControl; procedure SetAlwaysShowEditor(Value: Boolean); procedure SetCellHints(Value: Boolean); procedure SetFocusCellOnCycle(Value: Boolean); procedure SetFocusFirstCellOnNewRecord(Value: Boolean); procedure SetGoToNextCellOnEnter(Value: Boolean); procedure SetGoToNextCellOnTab(Value: Boolean); procedure SetImmediateEditor(Value: Boolean); procedure SetIncSearch(Value: Boolean); procedure SetIncSearchItem(Value: TcxCustomInplaceEditContainer); protected procedure Changed; virtual; property DragDropText: Boolean read FDragDropText write FDragDropText default False; property EditingControl: TcxEditingControl read GetEditingControl; property FocusCellOnCycle: Boolean read FFocusCellOnCycle write SetFocusCellOnCycle default False; property FocusFirstCellOnNewRecord: Boolean read FFocusFirstCellOnNewRecord write SetFocusFirstCellOnNewRecord default False; property IncSearch: Boolean read FIncSearch write SetIncSearch default False; property IncSearchItem: TcxCustomInplaceEditContainer read FIncSearchItem write SetIncSearchItem; public constructor Create(AOwner: TPersistent); override; procedure Assign(Source: TPersistent); override; published property AlwaysShowEditor: Boolean read FAlwaysShowEditor write SetAlwaysShowEditor default False; property CellHints: Boolean read FCellHints write SetCellHints default False; property GoToNextCellOnEnter: Boolean read FGoToNextCellOnEnter write SetGoToNextCellOnEnter default False; property GoToNextCellOnTab: Boolean read FGoToNextCellOnTab write SetGoToNextCellOnTab default False; property ImmediateEditor: Boolean read FImmediateEditor write SetImmediateEditor default True; end; { TcxEditContainerStyles } TcxEditContainerStylesClass = class of TcxEditContainerStyles; TcxEditContainerStyles = class(TcxStyles) private function GetContainer: TcxCustomInplaceEditContainer; function GetControl: TcxEditingControl; function GetControlStyles: TcxCustomControlStyles; protected procedure Changed(AIndex: Integer); override; public procedure Assign(Source: TPersistent); override; property Container: TcxCustomInplaceEditContainer read GetContainer; property Control: TcxEditingControl read GetControl; property ControlStyles: TcxCustomControlStyles read GetControlStyles; published property Content: TcxStyle index ecs_Content read GetValue write SetValue; end; { TcxCustomInplaceEditContainer } IcxEditorPropertiesContainer = interface ['{9F0CD5D9-A3D1-44B7-82DC-CAEAC1367C5D}'] function GetProperties: TcxCustomEditProperties; function GetPropertiesClass: TcxCustomEditPropertiesClass; procedure SetPropertiesClass(Value: TcxCustomEditPropertiesClass); end; TcxCustomInplaceEditContainer = class(TComponent, IUnknown, IcxEditRepositoryItemListener, IcxEditorPropertiesContainer) private FData: Pointer; FEditData: TcxCustomEditData; FEditingControl: TcxEditingControl; FEditViewData: TcxCustomEditViewData; FEditValueSource: TcxDataEditValueSource; FItemIndex: Integer; FOptions: TcxCustomEditContainerItemOptions; FProperties: TcxCustomEditProperties; FPropertiesClass: TcxCustomEditPropertiesClass; FPropertiesEvents: TNotifyEvent; FPropertiesValue: TcxCustomEditProperties; FRepositoryItem: TcxEditRepositoryItem; FStyles: TcxEditContainerStyles; FOnGetEditProperties: TcxGetEditPropertiesEvent; FOnGetEditingProperties: TcxGetEditPropertiesEvent; procedure IcxEditRepositoryItemListener.PropertiesChanged = RepositoryItemPropertiesChanged; procedure IcxEditRepositoryItemListener.ItemRemoved = RepositoryItemRemoved; function GetDataController: TcxCustomDataController; function GetFocused: Boolean; function GetFocusedCellViewInfo: TcxEditCellViewInfo; function GetIncSearching: Boolean; function GetProperties: TcxCustomEditProperties; function GetPropertiesClass: TcxCustomEditPropertiesClass; function GetPropertiesClassName: string; function GetPropertiesValue: TcxCustomEditProperties; procedure SetDataBinding(Value: TcxCustomItemDataBinding); procedure SetFocused(Value: Boolean); procedure SetOptions(Value: TcxCustomEditContainerItemOptions); procedure SetProperties(Value: TcxCustomEditProperties); procedure SetPropertiesClass(Value: TcxCustomEditPropertiesClass); procedure SetPropertiesClassName(const Value: string); procedure SetRepositoryItem(Value: TcxEditRepositoryItem); procedure SetStyles(Value: TcxEditContainerStyles); procedure CreateProperties; procedure DestroyProperties; procedure RecreateProperties; procedure RepositoryItemPropertiesChanged(Sender: TcxEditRepositoryItem); procedure RepositoryItemRemoved(Sender: TcxEditRepositoryItem); protected FDataBinding: TcxCustomItemDataBinding; procedure CalculateEditViewInfo(const AValue: Variant; AEditViewInfo: TcxEditCellViewInfo; const APoint: TPoint); virtual; function CanEdit: Boolean; virtual; function CanFocus: Boolean; virtual; procedure CancelIncSearching; function CanInitEditing: Boolean; virtual; function CanIncSearch: Boolean; virtual; function CanTabStop: Boolean; virtual; procedure Changed; virtual; function CreateEditViewData(AProperties: TcxCustomEditProperties; AEditStyleData: Pointer): TcxCustomEditViewData; virtual; procedure DataChanged; virtual; procedure DoGetDisplayText(ARecordIndex: Integer; var AText: string); virtual; function DoGetEditProperties(AData: Pointer): TcxCustomEditProperties; virtual; procedure DoGetEditingProperties(AData: Pointer; var AProperties: TcxCustomEditProperties); virtual; function DoGetPropertiesFromEvent(AEvent: TcxGetEditPropertiesEvent; AData: Pointer; AProperties: TcxCustomEditProperties): TcxCustomEditProperties; virtual; procedure DoOnPropertiesChanged(Sender: TObject); virtual; procedure EditViewDataGetDisplayTextHandler(Sender: TcxCustomEditViewData; var AText: string); virtual; function GetControlCanvas: TcxCanvas; virtual; function GetController: TcxCustomControlController; virtual; function GetCurrentValue: Variant; virtual; function GetDataBindingClass: TcxItemDataBindingClass; virtual; function GetDefaultCaption: string; virtual; function GetDefaultEditProperties: TcxCustomEditProperties; virtual; function GetDisplayValue(AProperties: TcxCustomEditProperties; ARecordIndex: Integer): Variant; virtual; function GetEditDataValueTypeClass: TcxValueTypeClass; virtual; // todo: function GetEditDefaultHeight(AFont: TFont): Integer; virtual; function GetEditHeight(AEditViewInfo: TcxEditCellViewInfo): Integer; virtual; function GetEditing: Boolean; virtual; function GetEditStyle(AData: Pointer): TcxCustomEditStyle; virtual; function GetEditValue: Variant; virtual; function GetEditWidth(AEditViewInfo: TcxEditCellViewInfo): Integer; virtual; function GetOptionsClass: TcxCustomEditContainerItemOptionsClass; virtual; function GetStylesClass: TcxEditContainerStylesClass; virtual; function GetValue(ARecordIndex: Integer): Variant; virtual; function GetValueCount: Integer; virtual; function HasDataTextHandler: Boolean; virtual; procedure InitEditViewInfo(AEditViewInfo: TcxEditCellViewInfo); virtual; procedure InitProperties(AProperties: TcxCustomEditProperties); virtual; procedure InternalPropertiesChanged; function IsDestroying: Boolean; function IsEditPartVisible: Boolean; procedure PropertiesChanged; virtual; procedure SetCurrentValue(const Value: Variant); virtual; procedure SetEditing(Value: Boolean); virtual; procedure SetEditingControl(Value: TcxEditingControl); virtual; procedure SetEditValue(const Value: Variant); virtual; procedure SetValue(ARecordIndex: Integer; const Value: Variant); virtual; property Controller: TcxCustomControlController read GetController; property DataBinding: TcxCustomItemDataBinding read FDataBinding write SetDataBinding; property DataController: TcxCustomDataController read GetDataController; // todo: should be protected property IncSearching: Boolean read GetIncSearching; property EditData: TcxCustomEditData read FEditData; property Editing: Boolean read GetEditing write SetEditing; property EditingControl: TcxEditingControl read FEditingControl write SetEditingControl; property EditValue: Variant read GetEditValue write SetEditValue; property EditValueSource: TcxDataEditValueSource read FEditValueSource; property EditViewData: TcxCustomEditViewData read FEditViewData; property Focused: Boolean read GetFocused write SetFocused; property FocusedCellViewInfo: TcxEditCellViewInfo read GetFocusedCellViewInfo; property Options: TcxCustomEditContainerItemOptions read FOptions write SetOptions; property PropertiesValue: TcxCustomEditProperties read GetPropertiesValue; property Value: Variant read GetCurrentValue write SetCurrentValue; property ValueCount: Integer read GetValueCount; property Values[ARecordIndex: Integer]: Variant read GetValue write SetValue; property OnGetEditProperties: TcxGetEditPropertiesEvent read FOnGetEditProperties write FOnGetEditProperties; property OnGetEditingProperties: TcxGetEditPropertiesEvent read FOnGetEditingProperties write FOnGetEditingProperties; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; procedure Assign(Source: TPersistent); override; property Data: Pointer read FData write FData; property ItemIndex: Integer read FItemIndex; property PropertiesClass: TcxCustomEditPropertiesClass read FPropertiesClass write SetPropertiesClass; published property PropertiesClassName: string read GetPropertiesClassName write SetPropertiesClassName; property Properties: TcxCustomEditProperties read GetProperties write SetProperties; property PropertiesEvents: TNotifyEvent read FPropertiesEvents write FPropertiesEvents; property RepositoryItem: TcxEditRepositoryItem read FRepositoryItem write SetRepositoryItem; property Styles: TcxEditContainerStyles read FStyles write SetStyles; end; { IcxHotTrackElement } IcxHotTrackElement = interface ['{E7171E58-276E-499B-9DDF-298D850883C9}'] function GetOrigin: TPoint; function IsNeedHint(ACanvas: TcxCanvas; const P: TPoint; out AText: TCaption; out AIsMultiLine: Boolean; out ATextRect: TRect; var IsNeedOffsetHint: Boolean): Boolean; procedure UpdateHotTrackState(const APoint: TPoint); end; { TcxHotTrackController } TcxHotTrackController = class private FControl: TcxEditingControl; FShowHint: Boolean; procedure InternalHideHint(Sender: TObject); procedure InternalShowHint(Sender: TObject); procedure ResetTimer; protected Hint: TCaption; HintIsMultiLine: Boolean; HintTimer: TcxTimer; HintRect: TRect; HintVisible: Boolean; HintElement: TObject; HintWindow: THintWindow; PrevHitPoint: TPoint; PrevElement: TObject; function CanShowHint: Boolean; procedure CheckDestroyingElement(AElement: TObject); procedure CheckHintClass; procedure DoHideHint; virtual; procedure DoShowHint; virtual; function HintNeeded: Boolean; procedure InitTimer(AInterval: Integer; AEnabled: Boolean; const AHandler: TNotifyEvent); public constructor Create(AControl: TcxEditingControl); virtual; destructor Destroy; override; procedure CancelHint; procedure Clear; procedure SetHotElement(AElement: TObject; const APoint: TPoint); property Control: TcxEditingControl read FControl write FControl; property ShowHint: Boolean read FShowHint write FShowHint; end; { IcxDragSizing } IcxDragSizing = interface ['{5EA02F4E-E367-4E4D-A26D-000B5E5CD434}'] function CanSizing(ADirection: TcxDragSizingDirection): Boolean; function GetSizingBoundsRect(ADirection: TcxDragSizingDirection): TRect; function GetSizingIncrement(ADirection: TcxDragSizingDirection): Integer; function IsDynamicUpdate: Boolean; procedure SetSizeDelta(ADirection: TcxDragSizingDirection; ADelta: Integer); end; { TcxSizingDragAndDropObject } TcxSizingDragAndDropObject = class(TcxDragAndDropObject) private FDelta: Integer; FDirection: TcxDragSizingDirection; FDragBounds: TRect; FDragPos: TPoint; FDynamicUpdate: Boolean; FStartPos: TPoint; FSizeDelta: Integer; function GetCanvas: TcxCanvas; function GetController: TcxCustomControlController; function GetDragCoord(APoint: TPoint): Integer; function GetDragItem: TObject; function GetDragSizing: IcxDragSizing; function GetIsSizingKind(Index: Integer): Boolean; protected procedure BeginDragAndDrop; override; procedure DirtyChanged; override; procedure DragAndDrop(const P: TPoint; var Accepted: Boolean); override; procedure EndDragAndDrop(Accepted: Boolean); override; function GetDragAndDropCursor(Accepted: Boolean): TCursor; override; function GetDragPos(const APoint: TPoint): TPoint; virtual; function GetImmediateStart: Boolean; override; function GetSizingMarkBounds: TRect; virtual; property StartPos: TPoint read FStartPos; property Controller: TcxCustomControlController read GetController; property Delta: Integer read FDelta; property DragCoord[Point: TPoint]: Integer read GetDragCoord; property DragPos: TPoint read FDragPos; property DragSizing: IcxDragSizing read GetDragSizing; property Direction: TcxDragSizingDirection read FDirection; public property Canvas: TcxCanvas read GetCanvas; property DragBounds: TRect read FDragBounds; property DragItem: TObject read GetDragItem; property DynamicUpdate: Boolean read FDynamicUpdate; property IsHorzSizing: Boolean index 0 read GetIsSizingKind; property IsVertSizing: Boolean index 1 read GetIsSizingKind; property SizeDelta: Integer read FSizeDelta; end; { TcxAutoScrollingObject } TcxAutoScrollingObject = class private FArea: TRect; FCode: TScrollCode; FIncrement: Integer; FKind: TScrollBarKind; FOwner: TObject; FTimer: TcxTimer; protected procedure DoScrollInspectingControl; virtual; function GetControl: TcxEditingControl; virtual; function GetScrollBar(AKind: TScrollBarKind): TcxControlScrollBar; virtual; procedure TimerHandler(Sender: TObject); virtual; public constructor Create(AOwner: TObject); virtual; destructor Destroy; override; function Check(APos: TPoint): Boolean; procedure SetParams(const Area: TRect; AKind: TScrollBarKind; ACode: TScrollCode; AIncrement: Integer); procedure Stop; property Code: TScrollCode read FCode; property Control: TcxEditingControl read GetControl; property Increment: Integer read FIncrement; property Kind: TScrollBarKind read FKind; property Owner: TObject read FOwner; property Timer: TcxTimer read FTimer; end; { TcxDragDropAutoScrollingObject } TcxDragDropObjectAutoScrollingObject = class(TcxAutoScrollingObject) protected function GetControl: TcxEditingControl; override; end; { TcxControllerAutoScrollingObject } TcxControllerAutoScrollingObject = class(TcxAutoScrollingObject) private FBoundsMode: Boolean; FCheckHorz: Boolean; FCheckVert: Boolean; FDirections: TcxNeighbors; protected procedure DoScrollInspectingControl; override; function GetControl: TcxEditingControl; override; public function CheckBounds(APos: TPoint): Boolean; procedure SetBoundsParams(const AClientArea: TRect; ACheckHorz, ACheckVert: Boolean; AIncrement: Integer); end; TcxAutoScrollingObjectClass = class of TcxAutoScrollingObject; { TcxBaseDragAndDropObject } TcxBaseDragAndDropObject = class(TcxDragAndDropObject) private function GetEditingControl: TcxEditingControl; protected function GetDragAndDropCursor(Accepted: Boolean): TCursor; override; property EditingControl: TcxEditingControl read GetEditingControl; end; { TcxDragImage } TcxDragImage = class(cxControls.TcxDragImage) public property Image; property WindowCanvas; end; { TcxPlaceArrows } TcxPlaceArrows = class(TcxDragImage) private FBorderColor: TColor; FColor: TColor; FPrevRect: TRect; FPrevSide: TcxBorder; FWindowRegion: HRGN; procedure SetWindowRegion(ARegion: HRGN); protected function CreateArrowsRgns(const ARect: TRect; ASide: TcxBorder): HRGN; property BorderColor: TColor read FBorderColor; property Color: TColor read FColor; property WindowRegion: HRGN read FWindowRegion write SetWindowRegion; public constructor CreateArrows(AColor: TColor; ABorderColor: TColor = clDefault); virtual; function MoveTo(ARect: TRect; ASide: TcxBorder): Boolean; end; { TcxCustomControlDragAndDropObject } TcxCustomControlDragAndDropObject = class(TcxBaseDragAndDropObject) private FAutoScrollObjects: TList; FCanDrop: Boolean; FDragImage: TcxDragImage; FHotSpot: TPoint; FOrgOffset: TPoint; FPictureSize: TRect; function CheckScrolling(const P: TPoint): Boolean; function GetAutoScrollObject(Index: Integer): TcxAutoScrollingObject; function GetAutoScrollObjectCount: Integer; function GetCanvas: TcxCanvas; function GetHitTestController: TcxCustomHitTestController; protected procedure AddAutoScrollingObject(const ARect: TRect; AKind: TScrollBarKind; ACode: TScrollCode); procedure BeginDragAndDrop; override; procedure DragAndDrop(const P: TPoint; var Accepted: Boolean); override; procedure DrawDragImage; virtual; procedure DrawImage(const APoint: TPoint); procedure EndDragAndDrop(Accepted: Boolean); override; function GetAcceptedRect: TRect; virtual; function GetAutoScrollingObjectClass: TcxAutoScrollingObjectClass; virtual; function GetDisplayRect: TRect; virtual; function GetDragAndDropCursor(Accepted: Boolean): TCursor; override; function GetHorzScrollInc: Integer; virtual; function GetVertScrollInc: Integer; virtual; procedure OwnerImageChanged; virtual; procedure OwnerImageChanging; virtual; procedure Paint; virtual; procedure StopScrolling; // screen image working property AcceptedRect: TRect read GetAcceptedRect; property AutoScrollObjectCount: Integer read GetAutoScrollObjectCount; property AutoScrollObjects[Index: Integer]: TcxAutoScrollingObject read GetAutoScrollObject; property Canvas: TcxCanvas read GetCanvas; property CanDrop: Boolean read FCanDrop; property DisplayRect: TRect read GetDisplayRect; property DragImage: TcxDragImage read FDragImage; property HitTestController: TcxCustomHitTestController read GetHitTestController; property HotSpot: TPoint read FHotSpot; property OrgOffset: TPoint read FOrgOffset write FOrgOffset; property PictureSize: TRect read FPictureSize; public constructor Create(AControl: TcxControl); override; destructor Destroy; override; end; { TcxDragImageHelper } TcxDragImageHelperClass = class of TcxDragImageHelper; TcxDragImageHelper = class private FDragControl: TcxEditingControl; FDragImageVisible: Boolean; FDragPos: TPoint; function GetImageRect: TRect; procedure SetDragImageVisible(Value: Boolean); protected DragImage: TcxDragImage; HotSpot: TPoint; DragPictureBounds: TRect; MousePos: TPoint; procedure DragAndDrop(const P: TPoint); virtual; function GetDisplayRect: TRect; virtual; procedure InitDragImage; virtual; // working with screen procedure DrawImage(const APoint: TPoint); virtual; public constructor Create(AControl: TcxEditingControl; ADragPos: TPoint); virtual; destructor Destroy; override; procedure Hide; virtual; procedure Show; virtual; property DragControl: TcxEditingControl read FDragControl; property DragImageRect: TRect read GetImageRect; property DragImageVisible: Boolean read FDragImageVisible write SetDragImageVisible; end; { TcxCustomHitTestController } TcxHitTestControllerClass = class of TcxCustomHitTestController; TcxCustomHitTestController = class private FController: TcxCustomControlController; FHitPoint: TPoint; FHitTestItem: TObject; FShift: TShiftState; function GetControl: TcxEditingControl; function GetCoordinate(AIndex: Integer): Integer; function GetEditCellViewInfo: TcxEditCellViewInfo; function GetHasCode(Mask: TcxHitCode): Boolean; function GetHotTrackController: TcxHotTrackController; function GetIsItemEditCell: Boolean; function GetIsMouseEvent: Boolean; function GetViewInfo: TcxCustomControlViewInfo; procedure SetCoordinate(AIndex: Integer; Value: Integer); procedure SetHasCode(ACode: TcxHitCode; AValue: Boolean); procedure SetHitPoint(const APoint: TPoint); procedure SetHitTestItem(AItem: TObject); procedure SetIsMouseEvent(Value: Boolean); protected FHitState: TcxHitCode; function AllowDesignMouseEvents(X, Y: Integer; AShift: TShiftState): Boolean; virtual; function CanShowHint(AItem: TObject): Boolean; virtual; procedure ClearState; procedure DestroyingItem(AItem: TObject); procedure DoCalculate; virtual; function GetCurrentCursor: TCursor; virtual; procedure HitCodeChanged(APrevCode: Integer); virtual; procedure HitTestItemChanged(APrevHitTestItem: TObject); virtual; procedure RecalculateOnMouseEvent(X, Y: Integer; AShift: TShiftState); property Control: TcxEditingControl read GetControl; property Controller: TcxCustomControlController read FController; property HotTrackController: TcxHotTrackController read GetHotTrackController; property IsMouseEvent: Boolean read GetIsMouseEvent write SetIsMouseEvent; property Shift: TShiftState read FShift; property ViewInfo: TcxCustomControlViewInfo read GetViewInfo; public constructor Create(AOwner: TcxCustomControlController); virtual; destructor Destroy; override; procedure ReCalculate; overload; procedure ReCalculate(const APoint: TPoint); overload; property EditCellViewInfo: TcxEditCellViewInfo read GetEditCellViewInfo; property HitPoint: TPoint read FHitPoint write SetHitPoint; property HitX: Integer index 0 read GetCoordinate write SetCoordinate; property HitY: Integer index 1 read GetCoordinate write SetCoordinate; property HitState: TcxHitCode read FHitState; property HitCode[ACode: TcxHitCode]: Boolean read GetHasCode write SetHasCode; property HitTestItem: TObject read FHitTestItem write SetHitTestItem; property IsItemEditCell: Boolean read GetIsItemEditCell; end; { TcxCustomCellNavigator } TcxCustomCellNavigator = class private FController: TcxCustomControlController; FEatKeyPress: Boolean; FDownOnEnter: Boolean; FDownOnTab: Boolean; function GetDataController: TcxCustomDataController; protected RowCount: Integer; function SelectCell(AForward, ANextRow: Boolean; var ARowIndex, ACellIndex: Integer): TcxCustomInplaceEditContainer; virtual; procedure CalcNextRow(AForward: Boolean; var ARowIndex, ACellIndex: Integer); virtual; function GetCellContainer(ARowIndex, ACellIndex: Integer): TcxCustomInplaceEditContainer; virtual; function GetCount(ARowIndex: Integer): Integer; virtual; procedure Init(var ARowIndex, ACellIndex, ARowCount: Integer); virtual; function MayFocusedEmptyRow(ARowIndex: Integer): Boolean; virtual; procedure SetFocusCell(ARowIndex, ACellIndex: Integer; AShift: TShiftState); virtual; procedure DoKeyPress(var Key: Char); virtual; property DownOnEnter: Boolean read FDownOnEnter write FDownOnEnter; property DownOnTab: Boolean read FDownOnTab write FDownOnTab; public constructor Create(AController: TcxCustomControlController); virtual; procedure FocusNextCell(AForward, ANextRow: Boolean; AShift: TShiftState = []); virtual; procedure KeyDown(var Key: Word; Shift: TShiftState); virtual; procedure KeyPress(var Key: Char); virtual; procedure Refresh; virtual; property Count[ARowIndex: Integer]: Integer read GetCount; property Controller: TcxCustomControlController read FController; property DataController: TcxCustomDataController read GetDataController; property EatKeyPress: Boolean read FEatKeyPress write FEatKeyPress; end; TcxCustomCellNavigatorClass = class of TcxCustomCellNavigator; { TcxDesignSelectionHelper } TcxCustomDesignSelectionHelper = class private FControl: TcxEditingControl; function GetController: TcxCustomControlController; protected property Control: TcxEditingControl read FControl; property Controller: TcxCustomControlController read GetController; public constructor Create(AControl: TcxEditingControl); virtual; function IsObjectSelected(AObject: TPersistent): Boolean; virtual; abstract; procedure Select(AObject: TPersistent; AShift: TShiftState); virtual; abstract; procedure SetSelection(AList: TList); virtual; abstract; procedure UnselectObject(AObject: TPersistent); virtual; abstract; end; TcxCustomDesignSelectionHelperClass = class of TcxCustomDesignSelectionHelper; { TcxCustomControlController } TcxCustomControlController = class private FAllowCheckEdit: Boolean; FBlockRecordKeyboardHandling: Boolean; FCheckEditNeeded: Boolean; FDisableCellsRefresh: Boolean; FDragCancel: Boolean; FDragItem: TObject; FEatKeyPress: Boolean; FEditingBeforeDrag: Boolean; FEditingController: TcxEditingController; FEditingControl: TcxEditingControl; FFocused: Boolean; FFocusedItem: TcxCustomInplaceEditContainer; FHitTestController: TcxCustomHitTestController; FHotTrackController: TcxHotTrackController; FIsDblClick: Boolean; FIsHandleTabStop: Boolean; FLockShowHint: Boolean; FNavigator: TcxCustomCellNavigator; FWasFocusedBeforeClick: Boolean; function GetDataController: TcxCustomDataController; function GetDesignSelectionHelper: TcxCustomDesignSelectionHelper; function GetEditingItem: TcxCustomInplaceEditContainer; function GetIsEditing: Boolean; function GetItemForIncSearching: TcxCustomInplaceEditContainer; procedure SetEditingItem(Value: TcxCustomInplaceEditContainer); procedure SetIncSearchingText(const Value: string); protected procedure MouseEnter; virtual; procedure MouseLeave; virtual; procedure DoCancelMode; virtual; procedure AfterPaint; virtual; procedure BeforeEditKeyDown(var Key: Word; var Shift: TShiftState); virtual; procedure BeforeMouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); virtual; procedure BeforePaint; virtual; procedure BeforeShowEdit; virtual; procedure BehaviorChanged; virtual; procedure CancelCheckEditPost; function CanFocusedRecordIndex(AIndex: Integer): Boolean; virtual; procedure CheckEdit; virtual; procedure DoEditDblClick(Sender: TObject); virtual; procedure DoMouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); virtual; procedure DoMouseMove(Shift: TShiftState; X, Y: Integer); virtual; procedure DoMouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); virtual; procedure DoNextPage(AForward: Boolean; Shift: TShiftState); virtual; function GetEditingViewInfo: TcxEditCellViewInfo; virtual; function GetFocused: Boolean; virtual; function GetFocusedCellViewInfo(AEditContainer: TcxCustomInplaceEditContainer): TcxEditCellViewInfo; virtual; function GetFocusedRecordIndex: Integer; virtual; function GetResizeDirection: TcxDragSizingDirection; virtual; procedure FocusedItemChanged(APrevFocusedItem: TcxCustomInplaceEditContainer); virtual; procedure FocusedRecordChanged(APrevFocusedRecordIndex, AFocusedRecordIndex: Integer); virtual; function HasFocusedControls: Boolean; virtual; procedure HideHint; virtual; function IncSearchKeyDown(AKey: Word; AShift: TShiftState): Word; virtual; procedure InternalSetFocusedItem(Value: TcxCustomInplaceEditContainer); function IsImmediatePost: Boolean; virtual; function IsKeyForController(AKey: Word; AShift: TShiftState): Boolean; virtual; procedure PostCheckEdit; procedure PostShowEdit; procedure ProcessCheckEditPost; procedure RefreshFocusedCellViewInfo(AItem: TcxCustomInplaceEditContainer); virtual; procedure RefreshFocusedRecord; virtual; procedure SetFocused(Value: Boolean); virtual; procedure SetFocusedItem(Value: TcxCustomInplaceEditContainer); virtual; procedure SetFocusedRecordIndex(Value: Integer); virtual; // behavior options function GetAlwaysShowEditor: Boolean; virtual; function GetCancelEditingOnExit: Boolean; virtual; function GetFocusCellOnCycle: Boolean; virtual; function GetGoToNextCellOnEnter: Boolean; virtual; function GetGoToNextCellOnTab: Boolean; virtual; function GetImmediateEditor: Boolean; virtual; // drag'n'drop procedure BeforeStartDrag; virtual; function CanDrag(X, Y: Integer): Boolean; virtual; procedure DragDrop(Source: TObject; X, Y: Integer); virtual; procedure DragOver(Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); virtual; procedure EndDrag(Target: TObject; X, Y: Integer); virtual; function GetDragAndDropObject: TcxCustomControlDragAndDropObject; function GetDragAndDropObjectClass: TcxDragAndDropObjectClass; virtual; function GetIsDragging: Boolean; virtual; function GetNavigatorClass: TcxCustomCellNavigatorClass; virtual; procedure StartDrag(var DragObject: TDragObject); virtual; // scrolling function GetMouseWheelScrollingKind: TcxMouseWheelScrollingKind; virtual; function IsPixelScrollBar(AKind: TScrollBarKind): Boolean; virtual; // focus procedure DoEnter; virtual; procedure DoExit; virtual; function MayFocus: Boolean; virtual; procedure FocusChanged; virtual; procedure RemoveFocus; virtual; procedure SetFocus; virtual; // incremental search procedure CancelIncSearching; virtual; function GetIncSearchingItem: TcxCustomInplaceEditContainer; virtual; function GetIncSearchingText: string; virtual; function GetIsIncSearching: Boolean; virtual; procedure SearchLocate(AItem: TcxCustomInplaceEditContainer; const Value: string); virtual; procedure SearchLocateNext(AItem: TcxCustomInplaceEditContainer; AForward: Boolean); virtual; procedure UpdateRecord(ARecordIndex: Integer); virtual; procedure ViewInfoChanged; virtual; property AllowCheckEdit: Boolean read FAllowCheckEdit write FAllowCheckEdit; property BlockRecordKeyboardHandling: Boolean read FBlockRecordKeyboardHandling write FBlockRecordKeyboardHandling; property DesignSelectionHelper: TcxCustomDesignSelectionHelper read GetDesignSelectionHelper; property DisableCellsRefresh: Boolean read FDisableCellsRefresh write FDisableCellsRefresh; property DragAndDropObject: TcxCustomControlDragAndDropObject read GetDragAndDropObject; property DragCancel: Boolean read FDragCancel write FDragCancel; property DragItem: TObject read FDragItem write FDragItem; property EatKeyPress: Boolean read FEatKeyPress write FEatKeyPress; property EditingControl: TcxEditingControl read FEditingControl; property EditingController: TcxEditingController read FEditingController; property EditingItem: TcxCustomInplaceEditContainer read GetEditingItem write SetEditingItem; property EditingViewInfo: TcxEditCellViewInfo read GetEditingViewInfo; property HotTrackController: TcxHotTrackController read FHotTrackController; property HitTestController: TcxCustomHitTestController read FHitTestController; property IncSearchingText: string read GetIncSearchingText write SetIncSearchingText; property IncSearchingItem: TcxCustomInplaceEditContainer read GetIncSearchingItem; property IsHandleTabStop: Boolean read FIsHandleTabStop write FIsHandleTabStop; property IsDragging: Boolean read GetIsDragging; property IsIncSearching: Boolean read GetIsIncSearching; property ItemForIncSearching: TcxCustomInplaceEditContainer read GetItemForIncSearching; property LockShowHint: Boolean read FLockShowHint write FLockShowHint; property Navigator: TcxCustomCellNavigator read FNavigator; property WasFocusedBeforeClick: Boolean read FWasFocusedBeforeClick write FWasFocusedBeforeClick; public constructor Create(AOwner: TcxEditingControl); reintroduce; virtual; destructor Destroy; override; procedure Clear; virtual; procedure ControlFocusChanged; virtual; procedure DblClick; virtual; function GetCursor(X, Y: Integer): TCursor; virtual; procedure KeyDown(var Key: Word; Shift: TShiftState); virtual; procedure KeyPress(var Key: Char); virtual; procedure KeyUp(var Key: Word; Shift: TShiftState); virtual; procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); virtual; procedure MouseMove(Shift: TShiftState; X, Y: Integer); virtual; procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); virtual; procedure Reset; procedure WndProc(var Message: TMessage); virtual; // drag'n'drop procedure BeginDragAndDrop; virtual; procedure DragAndDrop(const P: TPoint; var Accepted: Boolean); virtual; procedure EndDragAndDrop(Accepted: Boolean); virtual; function StartDragAndDrop(const P: TPoint): Boolean; virtual; // scrolling procedure InitScrollBarsParameters; virtual; procedure Scroll(AScrollBarKind: TScrollBarKind; AScrollCode: TScrollCode; var AScrollPos: Integer); virtual; procedure SetFocusedRecordItem(ARecordIndex: Integer; AItem: TcxCustomInplaceEditContainer); virtual; procedure SetScrollBarInfo(AScrollBarKind: TScrollBarKind; AMin, AMax, AStep, APage, APos: Integer; AAllowShow, AAllowHide: Boolean); procedure MakeFocusedItemVisible; virtual; procedure MakeFocusedRecordVisible; virtual; property DataController: TcxCustomDataController read GetDataController; property Focused: Boolean read GetFocused write SetFocused; property FocusedItem: TcxCustomInplaceEditContainer read FFocusedItem write SetFocusedItem; property FocusedRecordIndex: Integer read GetFocusedRecordIndex write SetFocusedRecordIndex; property IsDblClick: Boolean read FIsDblClick; property IsEditing: Boolean read GetIsEditing; end; { TcxEditingController } TcxEditingController = class private FController: TcxCustomControlController; FEdit: TcxCustomEdit; FEditHiding: Boolean; FEditingItem: TcxCustomInplaceEditContainer; FEditingItemSetting: Boolean; FEditList: TcxInplaceEditList; FEditPreparing: Boolean; FEditShowingTimer: TcxTimer; FEditShowingTimerItem: TcxCustomInplaceEditContainer; FEditUpdateNeeded: Boolean; FInitiatingEditing: Boolean; FIsEditPlaced: Boolean; FIsErrorOnEditExit: Boolean; FPrevEditOnChange: TNotifyEvent; FPrevEditOnEditValueChanged: TNotifyEvent; function GetEditingControl: TcxEditingControl; function GetEditingProperties: TcxCustomEditProperties; function GetIsDragging: Boolean; function GetIsEditing: Boolean; procedure SetEditingItem(Value: TcxCustomInplaceEditContainer); procedure EditShowingTimerHandler(Sender: TObject); protected procedure AfterViewInfoCalculate; virtual; procedure BeforeViewInfoCalculate; virtual; procedure CancelEditUpdatePost; function CanRemoveEditFocus: Boolean; virtual; function CanUpdateEditValue: Boolean; virtual; procedure CheckEditUpdatePost; procedure AssignEditEvents; virtual; procedure UnassignEditEvents; virtual; procedure DoUpdateEdit; function GetHideEditOnExit: Boolean; virtual; function GetHideEditOnFocusedRecordChange: Boolean; virtual; procedure HideInplaceEditor; procedure InitEdit; virtual; function PrepareEdit(AItem: TcxCustomInplaceEditContainer; AIsMouseEvent: Boolean): Boolean; virtual; procedure UpdateEdit; procedure UpdateEditValue; procedure UpdateValue; procedure EditAfterKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); virtual; procedure EditChanged(Sender: TObject); virtual; procedure EditDblClick(Sender: TObject); virtual; procedure EditEditing(Sender: TObject; var CanEdit: Boolean); virtual; procedure EditEnter(Sender: TObject); virtual; procedure EditExit(Sender: TObject); virtual; procedure EditFocusChanged(Sender: TObject); virtual; procedure EditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); virtual; procedure EditKeyPress(Sender: TObject; var Key: Char); virtual; procedure EditKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); virtual; procedure EditPostEditValue(Sender: TObject); virtual; procedure EditValueChanged(Sender: TObject); virtual; property Controller: TcxCustomControlController read FController; property EditingControl: TcxEditingControl read GetEditingControl; property EditHiding: Boolean read FEditHiding write FEditHiding; property EditingProperties: TcxCustomEditProperties read GetEditingProperties; property EditList: TcxInplaceEditList read FEditList; property EditUpdateNeeded: Boolean read FEditUpdateNeeded; property HideEditOnExit: Boolean read GetHideEditOnExit; property HideEditOnFocusedRecordChange: Boolean read GetHideEditOnFocusedRecordChange; property InitiatingEditing: Boolean read FInitiatingEditing; property IsEditPlaced: Boolean read FIsEditPlaced; property IsErrorOnEditExit: Boolean read FIsErrorOnEditExit write FIsErrorOnEditExit; public constructor Create(AController: TcxCustomControlController); virtual; destructor Destroy; override; procedure HideEdit(Accept: Boolean); virtual; procedure PostEditUpdate; procedure RemoveEdit(AProperties: TcxCustomEditProperties); virtual; procedure ShowEdit(AItem: TcxCustomInplaceEditContainer = nil); overload; procedure ShowEdit(AItem: TcxCustomInplaceEditContainer; Key: Char); overload; procedure ShowEdit(AItem: TcxCustomInplaceEditContainer; Shift: TShiftState; X, Y: Integer); overload; procedure StartEditShowingTimer(AItem: TcxCustomInplaceEditContainer); procedure StopEditShowingTimer; property Edit: TcxCustomEdit read FEdit; property EditingItem: TcxCustomInplaceEditContainer read FEditingItem write SetEditingItem; property IsDragging: Boolean read GetIsDragging; property IsEditing: Boolean read GetIsEditing; end; { TcxCustomControlViewInfo } TcxCustomControlViewInfo = class private FControl: TcxEditingControl; FClientRect: TRect; FDefaultEditHeight: Integer; FEditCellViewInfoList: TList; FPainter: TcxCustomControlPainter; FState: Integer; function GetLookAndFeelPainter: TcxCustomLookAndFeelPainterClass; function GetState(AMask: Integer): Boolean; procedure SetState(AMask: Integer; Value: Boolean); procedure UpdateSelectionParams; protected Brush: TBrush; SelectionBrush: TBrush; SelectionParams: TcxViewParams; function AddEditCellViewInfo(AViewInfoClass: TcxEditCellViewInfoClass; AEditContainer: TcxCustomInplaceEditContainer): TcxEditCellViewInfo; function CalculateDefaultEditHeight: Integer; virtual; procedure CalculateDefaultHeights; virtual; procedure ClearEditCellViewInfos; procedure CreatePainter; virtual; procedure DoCalculate; virtual; procedure RemoveEditCellViewInfo(AViewInfo: TcxEditCellViewInfo); procedure UpdateSelection; virtual; property IsDirty: Boolean index cvis_IsDirty read GetState write SetState; property State[AMask: Integer]: Boolean read GetState write SetState; public ViewParams: TcxViewParams; constructor Create(AOwner: TcxEditingControl); virtual; destructor Destroy; override; procedure Calculate; procedure Invalidate(ARecalculate: Boolean = False); virtual; procedure ValidateDirty; property ClientRect: TRect read FClientRect; property Control: TcxEditingControl read FControl; property DefaultEditHeight: Integer read FDefaultEditHeight; property LookAndFeelPainter: TcxCustomLookAndFeelPainterClass read GetLookAndFeelPainter; property Painter: TcxCustomControlPainter read FPainter write FPainter; end; { TcxCustomControlCells } TcxCustomDrawCellEvent = procedure(ACanvas: TcxCanvas; ACell: TcxCustomViewInfoItem; var ADone: Boolean) of object; TcxCustomControlCells = class(TcxObjectList) private function GetItem(AIndex: Integer): TcxCustomViewInfoItem; public procedure BeforePaint; function CalculateHitTest(AHitTest: TcxCustomHitTestController): Boolean; procedure DeleteAll; procedure ExcludeFromClipping(ACanvas: TcxCanvas); procedure Paint(ACanvas: TcxCanvas; AHandler: TcxCustomDrawCellEvent); virtual; property Items[Index: Integer]: TcxCustomViewInfoItem read GetItem; default; end; TcxCustomControlViewInfoClass = class of TcxCustomControlViewInfo; { TcxCustomViewInfoItem } TcxCustomViewInfoItem = class private FHasClipping: Boolean; FOwner: TObject; FTransparent: Boolean; FVisibleInfoCalculated: Boolean; function GetBitmap: TBitmap; function GetControlViewInfo: TcxCustomControlViewInfo; function GetPainter: TcxCustomLookAndFeelPainterClass; protected ClipRect: TRect; ControlCanvas: TcxCanvas; DisplayRect: TRect; ItemViewParams: TcxViewParams; ItemVisible: Boolean; VisibleBounds: TRect; procedure AfterCustomDraw(ACanvas: TcxCanvas); virtual; procedure BeforeCustomDraw(ACanvas: TcxCanvas); virtual; procedure CheckClipping(const ADisplayRect, AAvailableRect: TRect); overload; virtual; procedure CheckClipping(const ADisplayRect: TRect); overload; virtual; procedure DoCalculate; virtual; procedure DoDraw(ACanvas: TcxCanvas); virtual; procedure DoHorzOffset(AShift: Integer); virtual; procedure DoVertOffset(AShift: Integer); virtual; function DrawBackgroundHandler(ACanvas: TcxCanvas; const ABounds: TRect): Boolean; function GetControl: TcxEditingControl; virtual; function GetHitTest(AHitTest: TcxCustomHitTestController): Boolean; virtual; function IsTransparent: Boolean; virtual; function ExcludeFromPaint(ACanvas: TcxCanvas): Boolean; procedure Scroll(const DX, DY: Integer); virtual; procedure UpdateEditRect; property Owner: TObject read FOwner; property ControlViewInfo: TcxCustomControlViewInfo read GetControlViewInfo; public constructor Create(AOwner: TObject); virtual; procedure Assign(Source: TcxCustomViewInfoItem); virtual; procedure CheckVisibleInfo; class function CustomDrawID: Integer; virtual; procedure Draw(ACanvas: TcxCanvas); procedure Invalidate(ARecalculate: Boolean = False); property Bitmap: TBitmap read GetBitmap; property BoundsRect: TRect read DisplayRect; property Control: TcxEditingControl read GetControl; property HasClipping: Boolean read FHasClipping; property Painter: TcxCustomLookAndFeelPainterClass read GetPainter; property LookAndFeelPainterClass: TcxCustomLookAndFeelPainterClass read GetPainter; // todo: deprecated, for backward capability only property Transparent: Boolean read FTransparent write FTransparent; property Visible: Boolean read ItemVisible; property VisibleInfoCalculated: Boolean read FVisibleInfoCalculated write FVisibleInfoCalculated; property VisibleRect: TRect read ClipRect; property ViewParams: TcxViewParams read ItemViewParams; end; { TcxEditCellViewInfo } TcxEditCellViewInfo = class(TcxCustomViewInfoItem, IUnknown, IcxHotTrackElement) private function GetTransparent: Boolean; procedure SetTransparent(Value: Boolean); protected CellBorders: TcxBorders; CellContentRect: TRect; CellEditRect: TRect; CellHeight: Integer; CellTransparent: Boolean; CellValue: Variant; IsViewDataCreated: Boolean; Properties: TcxCustomEditProperties; ViewInfo: TcxCustomEditViewInfo; ViewData: TcxCustomEditViewData; // 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); virtual; function CalculateEditHeight: Integer; function CalculateEditWidth: Integer; function ChangedHeight(APrevHeight, ANewHeight: Integer): Boolean; virtual; procedure CheckClipping(const ADisplayRect, AAvailableRect: TRect); override; function ContentOffset: TRect; virtual; function CorrectHotTrackPoint(const APoint: TPoint): TPoint; virtual; procedure DoCalculate; override; function GetButtonTransparency: TcxEditButtonTransparency; virtual; function GetCellOrg: TPoint; virtual; function GetControl: TcxEditingControl; override; function GetDisplayValue: Variant; virtual; function GetEditContainer: TcxCustomInplaceEditContainer; virtual; function GetEditRect: TRect; virtual; function GetEditViewParams: TcxViewParams; virtual; function GetFocused: Boolean; virtual; function GetInplaceEditPosition: TcxInplaceEditPosition; function GetMaxLineCount: Integer; virtual; function GetRecordIndex: Integer; virtual; function GetSelectedTextColor: Integer; virtual; function GetSelectedBKColor: Integer; virtual; function GetViewInfoData: Pointer; virtual; function IsAutoHeight: Boolean; virtual; function IsEndEllipsis: Boolean; virtual; function IsSupportedHotTrack: Boolean; virtual; procedure SetBounds(const ABounds: TRect; const ADisplayRect: TRect); property EditContainer: TcxCustomInplaceEditContainer read GetEditContainer; property EditRect: TRect read GetEditRect; public destructor Destroy; override; procedure Assign(Source: TcxCustomViewInfoItem); override; // IUnknown function QueryInterface(const IID: TGUID; out Obj): HResult; virtual; stdcall; function Refresh(ARecalculate: Boolean): Boolean; virtual; property Borders: TcxBorders read CellBorders; property ContentRect: TRect read CellContentRect; property DisplayValue: Variant read CellValue; property EditViewInfo: TcxCustomEditViewInfo read ViewInfo; property Focused: Boolean read GetFocused; property MaxLineCount: Integer read GetMaxLineCount; property RecordIndex: Integer read GetRecordIndex; property Transparent: Boolean read GetTransparent write SetTransparent; property BoundsRect; property Control; property ViewParams; property VisibleRect; end; { TcxCustomControlPainter } TcxCustomDrawViewInfoItemEvent = procedure(Sender: TObject; Canvas: TcxCanvas; AViewInfo: TcxCustomViewInfoItem; var ADone: Boolean) of object; TcxCustomControlPainter = class private FSaveViewParams: TcxViewParams; FBitmap: TBitmap; FBitmapCanvas: TcxCanvas; FBuffered: Boolean; FControl: TcxEditingControl; function GetPainter: TcxCustomLookAndFeelPainterClass; function GetViewInfo: TcxCustomControlViewInfo; protected FCanvas: TcxCanvas; procedure AfterCustomDraw(AViewInfo: TcxCustomViewInfoItem); overload; virtual; procedure BeforeCustomDraw(AViewInfo: TcxCustomViewInfoItem); overload; virtual; function DoCustomDraw(AViewInfoItem: TcxCustomViewInfoItem; AEvent: TcxCustomDrawViewInfoItemEvent): Boolean; procedure DoPaintEditCell(ACellViewInfo: TcxEditCellViewInfo; AIsExcludeRect: Boolean = True); virtual; procedure DoPaint; virtual; procedure SetBuffered(Value: Boolean); virtual; property Bitmap: TBitmap read FBitmap; property BitmapCanvas: TcxCanvas read FBitmapCanvas; public constructor Create(AOwner: TcxEditingControl); virtual; destructor Destroy; override; procedure Paint; virtual; property Buffered: Boolean read FBuffered write SetBuffered; property Canvas: TcxCanvas read FCanvas; property Control: TcxEditingControl read FControl; property Painter: TcxCustomLookAndFeelPainterClass read GetPainter; property ViewInfo: TcxCustomControlViewInfo read GetViewInfo; end; TcxCustomControlPainterClass = class of TcxCustomControlPainter; { TcxCustomControlStyles } TcxCustomControlStylesClass = class of TcxCustomControlStyles; TcxCustomControlStyles = class(TcxStyles) private FDefaultStyle: TcxStyle; FOnGetContentStyle: TcxOnGetContentStyleEvent; function GetControl: TcxEditingControl; function GetPainter: TcxCustomLookAndFeelPainterClass; protected procedure Changed(AIndex: Integer); override; function GetDefaultStyle(Index: Integer; AData: Pointer): TcxStyle; procedure GetDefaultViewParams(Index: Integer; AData: TObject; out AParams: TcxViewParams); override; public constructor Create(AOwner: TPersistent); override; destructor Destroy; override; procedure Assign(Source: TPersistent); override; function GetBackgroundParams: TcxViewParams; function GetSelectionParams: TcxViewParams; property Control: TcxEditingControl read GetControl; property LookAndFeelPainter: TcxCustomLookAndFeelPainterClass read GetPainter; published property Background: TcxStyle index ecs_Background read GetValue write SetValue; property Content: TcxStyle index ecs_Content read GetValue write SetValue; property Inactive: TcxStyle index ecs_Inactive read GetValue write SetValue; property Selection: TcxStyle index ecs_Selection read GetValue write SetValue; property OnGetContentStyle: TcxOnGetContentStyleEvent read FOnGetContentStyle write FOnGetContentStyle; property StyleSheet; end; { TcxEditingControl } IcxEditingControlOptions = interface ['{6A041541-53E2-413B-8377-0D249356B5DF}'] function GetOptionsBehavior: TcxControlOptionsBehavior; function GetOptionsData: TcxControlOptionsData; function GetOptionsView: TcxControlOptionsView; property OptionsBehavior: TcxControlOptionsBehavior read GetOptionsBehavior; property OptionsData: TcxControlOptionsData read GetOptionsData; property OptionsView: TcxControlOptionsView read GetOptionsView; end; TcxecEditingEvent = procedure(Sender, AItem: TObject; var Allow: Boolean) of object; TcxecInitEditEvent = procedure(Sender, AItem: TObject; AEdit: TcxCustomEdit) of object; TcxecItemEvent = procedure(Sender: TObject; AItem: TcxCustomInplaceEditContainer) of object; TcxEditingControl = class(TcxControl, IcxMouseTrackingCaller) private FBrushCache: TcxBrushCache; FChangesCount: Integer; FContainerList: TList; FDesignSelectionHelper: TcxCustomDesignSelectionHelper; FDragHelper: TcxDragImageHelper; FDragPos: TPoint; FEditStyle: TcxCustomEditStyle; FIsLayoutChanged: Boolean; FStyles: TcxCustomControlStyles; FViewInfo: TcxCustomControlViewInfo; FOnCustomDrawCell: TcxCustomDrawViewInfoItemEvent; FOnEditChanged: TcxecItemEvent; FOnEdited: TcxecItemEvent; FOnEditing: TcxecEditingEvent; FOnEditValueChanged: TcxecItemEvent; FOnInitEdit: TcxecInitEditEvent; procedure IcxMouseTrackingCaller.MouseLeave = DoMouseLeave; function GetBufferedPaint: Boolean; function GetPainter: TcxCustomControlPainter; procedure DoMouseLeave; procedure SetBufferedPaint(Value: Boolean); procedure SetEditStyle(Value: TcxCustomEditStyle); procedure SetStyles(Value: TcxCustomControlStyles); procedure WMCancelMode(var Message: TWMCancelMode); message WM_CANCELMODE; procedure WMSetCursor(var Message: TWMSetCursor); message WM_SetCursor; protected FController: TcxCustomControlController; FDataController: TcxCustomDataController; FLockUpdate: Integer; procedure AfterLayoutChanged; virtual; procedure BeginAutoDrag; override; procedure BeforeUpdate; virtual; procedure CheckCreateDesignSelectionHelper; virtual; procedure CreateSubClasses; virtual; procedure ControlUpdateData(AInfo: TcxUpdateControlInfo); virtual; procedure DataChanged; virtual; procedure DataLayoutChanged; virtual; procedure DestroyDesignSelectionHelper; procedure DestroySubClasses; virtual; procedure DoBeginUpdate; virtual; procedure DoEndUpdate; virtual; procedure DoEditChanged(AItem: TcxCustomInplaceEditContainer); virtual; procedure DoEdited(AItem: TcxCustomInplaceEditContainer); virtual; function DoEditing(AItem: TcxCustomInplaceEditContainer): Boolean; virtual; procedure DoEditValueChanged(AItem: TcxCustomInplaceEditContainer); virtual; procedure DoGetCellHint(ACell: TObject; var AText: string; var ANeedShow: Boolean); virtual; procedure DoInitEdit(AItem: TcxCustomInplaceEditContainer; AEdit: TcxCustomEdit); virtual; procedure DoInplaceEditContainerItemAdded(AItem: TcxCustomInplaceEditContainer); virtual; procedure DoInplaceEditContainerItemRemoved(AItem: TcxCustomInplaceEditContainer); virtual; procedure DoLayoutChanged; virtual; // function GetControllerClass: TcxCustomControlControllerClass; virtual; // TODO: need overriding function GetControlStylesClass: TcxCustomControlStylesClass; virtual; function GetDataControllerClass: TcxCustomDataControllerClass; virtual; function GetDragImageHelperClass: TcxDragImageHelperClass; virtual; function GetEditStyleClass: TcxCustomEditStyleClass; virtual; function GetEditingControllerClass: TcxEditingControllerClass; virtual; function GetHitTestControllerClass: TcxHitTestControllerClass; virtual; function GetHotTrackControllerClass: TcxHotTrackControllerClass; virtual; function GetViewInfoClass: TcxCustomControlViewInfoClass; virtual; function GetOptions: IcxEditingControlOptions; virtual; function GetPainterClass: TcxCustomControlPainterClass; virtual; function IsLocked: Boolean; virtual; procedure InvalidateRectEx(const R: TRect; EraseBackground: Boolean); virtual; procedure RecreateViewInfo; virtual; procedure SelectionChanged(AInfo: TcxSelectionChangedInfo); virtual; procedure UpdateIndexes; procedure UpdateViewStyles; procedure UpdateData; virtual; // VCL methods procedure CreateParams(var Params: TCreateParams); override; procedure CreateWnd; override; procedure DestroyWnd; override; procedure AlignControls(AControl: TControl; var Rect: TRect); override; procedure DoExit; override; procedure DblClick; override; procedure FocusChanged; override; procedure KeyDown(var Key: Word; Shift: TShiftState); override; procedure KeyPress(var Key: Char); override; procedure KeyUp(var Key: Word; Shift: TShiftState); override; procedure Loaded; override; 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 MouseEnter(AControl: TControl); override; procedure MouseLeave(AControl: TControl); override; procedure Paint; override; procedure WndProc(var Message: TMessage); override; // cxControl's procedure AfterMouseDown(AButton: TMouseButton; X, Y: Integer); override; procedure BoundsChanged; override; function CanDrag(X, Y: Integer): Boolean; override; procedure DoCancelMode; override; procedure FontChanged; override; function GetCursor(X, Y: Integer): TCursor; override; function GetDesignHitTest(X, Y: Integer; Shift: TShiftState): Boolean; override; function GetIsFocused: Boolean; override; function GetMouseWheelScrollingKind: TcxMouseWheelScrollingKind; override; procedure InitControl; override; function IsPixelScrollBar(AKind: TScrollBarKind): Boolean; override; procedure LookAndFeelChanged(Sender: TcxLookAndFeel; AChangedValues: TcxLookAndFeelValues); override; function MayFocus: Boolean; override; // drag'n'drop procedure DoEndDrag(Target: TObject; X, Y: Integer); override; procedure DoStartDrag(var DragObject: TDragObject); override; procedure DragOver(Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); override; function DragDropImageDisplayRect: TRect; virtual; procedure DrawDragDropImage(ADragBitmap: TBitmap; ACanvas: TcxCanvas); virtual; procedure FinishDragImages; function HasDragDropImages: Boolean; virtual; // scrollbars procedure InitScrollBarsParameters; override; procedure Scroll(AScrollBarKind: TScrollBarKind; AScrollCode: TScrollCode; var AScrollPos: Integer); override; procedure DragAndDrop(const P: TPoint; var Accepted: Boolean); override; procedure EndDragAndDrop(Accepted: Boolean); override; function GetDragAndDropObjectClass: TcxDragAndDropObjectClass; override; function StartDragAndDrop(const P: TPoint): Boolean; override; property BrushCache: TcxBrushCache read FBrushCache; property ContainerList: TList read FContainerList; property Controller: TcxCustomControlController read FController; property ChangesCount: Integer read FChangesCount; property DragPos: TPoint read FDragPos write FDragPos; property DataController: TcxCustomDataController read FDataController; property DesignSelectionHelper: TcxCustomDesignSelectionHelper read FDesignSelectionHelper; property DragHelper: TcxDragImageHelper read FDragHelper; property EditStyle: TcxCustomEditStyle read FEditStyle write SetEditStyle; property IsLayoutChanged: Boolean read FIsLayoutChanged write FIsLayoutChanged; property Options: IcxEditingControlOptions read GetOptions; property Painter: TcxCustomControlPainter read GetPainter; property Styles: TcxCustomControlStyles read FStyles write SetStyles; property ViewInfo: TcxCustomControlViewInfo read FViewInfo write FViewInfo; property OnCustomDrawCell: TcxCustomDrawViewInfoItemEvent read FOnCustomDrawCell write FOnCustomDrawCell; property OnEditChanged: TcxecItemEvent read FOnEditChanged write FOnEditChanged; property OnEdited: TcxecItemEvent read FOnEdited write FOnEdited; property OnEditing: TcxecEditingEvent read FOnEditing write FOnEditing; property OnEditValueChanged: TcxecItemEvent read FOnEditValueChanged write FOnEditValueChanged; property OnInitEdit: TcxecInitEditEvent read FOnInitEdit write FOnInitEdit; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; procedure BeginUpdate; procedure BeginDragAndDrop; override; procedure CancelUpdate; procedure EndUpdate; function ExecuteAction(Action: TBasicAction): Boolean; override; procedure DragDrop(Source: TObject; X, Y: Integer); override; procedure LayoutChanged; function UpdateAction(Action: TBasicAction): Boolean; override; property BufferedPaint: Boolean read GetBufferedPaint write SetBufferedPaint; property LockUpdate: Integer read FLockUpdate; property DragCursor default crDefault; property TabStop default True; published property BorderStyle default cxcbsDefault; end; { TcxExtEditingControl } TcxExtEditingControl = class(TcxEditingControl, IcxEditingControlOptions) private FOptionsBehavior: TcxControlOptionsBehavior; FOptionsData: TcxControlOptionsData; FOptionsView: TcxControlOptionsView; // IcxEditingControlOptions function GetOptionsBehavior: TcxControlOptionsBehavior; function GetOptionsData: TcxControlOptionsData; function GetOptionsView: TcxControlOptionsView; procedure SetOptionsBehavior(Value: TcxControlOptionsBehavior); procedure SetOptionsData(Value: TcxControlOptionsData); procedure SetOptionsView(Value: TcxControlOptionsView); protected procedure CreateSubClasses; override; procedure DestroySubClasses; override; function GetOptions: IcxEditingControlOptions; override; function GetOptionsBehaviorClass: TcxControlOptionsBehaviorClass; virtual; function GetOptionsDataClass: TcxControlOptionsDataClass; virtual; function GetOptionsViewClass: TcxControlOptionsViewClass; virtual; property OptionsBehavior: TcxControlOptionsBehavior read GetOptionsBehavior write SetOptionsBehavior; property OptionsData: TcxControlOptionsData read GetOptionsData write SetOptionsData; property OptionsView: TcxControlOptionsView read GetOptionsView write SetOptionsView; end; { TcxValueTypeClassRepository } TcxValueTypeClassRepository = class private FList: TStringList; function GetCount: Integer; function GetValueTypeClass(AIndex: Integer): TcxValueTypeClass; function GetDescription(AIndex: Integer): string; public constructor Create; destructor Destroy; override; function FindByClassType(ATypeClass: TcxValueTypeClass): string; function FindByDescription(const ADescription: string): TcxValueTypeClass; procedure RegisterValueTypeClass(const ADescription: string; ATypeClass: TcxValueTypeClass); procedure UnRegisterValueTypeClass(ATypeClass: TcxValueTypeClass); property Count: Integer read GetCount; property Description[AIndex: Integer]: string read GetDescription; property ValueTypeClass[AIndex: Integer]: TcxValueTypeClass read GetValueTypeClass; end; function cxieValueTypeClassRepository: TcxValueTypeClassRepository; procedure cxieRegisterValueTypeClass(const ADescription: string; ATypeClass: TcxValueTypeClass); procedure cxieUnRegisterValueTypeClass(ATypeClass: TcxValueTypeClass); procedure cxAssignEditStyle(AViewInfo: TcxEditCellViewInfo); function cxPtInViewInfoItem(AItem: TcxCustomViewInfoItem; const APoint: TPoint): Boolean; procedure cxStylesToViewParams(AMasterStyles: TcxCustomControlStyles; AIndex: Integer; AData: Pointer; const AStyles: array of TcxStyle; out AParams: TcxViewParams); function cxInRange(Value: Integer; AMin, AMax: Integer): Boolean; function cxRange(var Value: Integer; AMin, AMax: Integer): Boolean; function cxSetValue(Condition: Boolean; ATrueValue, AFalseValue: Integer): Integer; function cxConfirmMessageBox(const AText, ACaption: string): Boolean; procedure cxAbstractError; {$IFNDEF DELPHI5} function Supports(const Instance: TObject; const IID: TGUID; out Intf): Boolean; {$ENDIF} const cxIntOffs: array[Boolean] of Integer = (-1, 1); cxDefaultEditSizeProp: TcxEditSizeProperties = (Height: -1; MaxLineCount: 0; Width: -1); cxDesignSelectionHelperClass: TcxCustomDesignSelectionHelperClass = nil; implementation uses dxCore; type TControlAccess = class(TControl); THintWindowAccess = class(THintWindow); TcxCustomEditStyleAccess = class(TcxCustomEditStyle); TcxCustomEditViewDataAccess = class(TcxCustomEditViewData); TcxDragAndDropObjectAccess = class(TcxDragAndDropObject); PIntArray = ^TIntArray; TIntArray = array[0..MaxInt div SizeOf(Integer) - 1] of Integer; var ValueTypeClassRepository: TcxValueTypeClassRepository; cxDragControl: TcxEditingControl; cxDragPrevHook: HHook; const cxInvisibleCoordinate = 30000; procedure cxAbstractError; begin RunError(210); end; {$IFNDEF DELPHI5} function Supports(const Instance: TObject; const IID: TGUID; out Intf): Boolean; begin Result := (Instance <> nil) and Instance.GetInterface(IID, Intf); end; {$ENDIF} procedure cxAssignEditStyle(AViewInfo: TcxEditCellViewInfo); var AStyle: TcxCustomEditStyleAccess; begin AStyle := TcxCustomEditStyleAccess(AViewInfo.Control.EditStyle); with AViewInfo do begin AStyle.FAssignedValues := AStyle.FAssignedValues - [svFont] + [svColor, svButtonTransparency]; if ViewParams.Font = nil then AStyle.StyleData.Font := GetEditViewParams.Font else AStyle.StyleData.Font := ViewParams.Font; AStyle.StyleData.Color := ViewParams.Color; AStyle.StyleData.FontColor := ViewParams.TextColor; AStyle.ButtonTransparency := GetButtonTransparency; AStyle.Changed; ViewInfo.Transparent := IsTransparent; end; end; function MouseMsgHookProcForDragDrop(Code: Integer; WParam, LParam: Longint): Longint stdcall; begin Result := CallNextHookEx(cxDragPrevHook, Code, WParam, LParam); if (cxDragControl <> nil) then begin case WParam of WM_MOUSEMOVE: begin with cxDragControl do if Dragging then DragHelper.DragAndDrop(PMouseHookStruct(LParam).Pt); end; WM_LBUTTONUP, WM_RBUTTONUP: cxDragControl.FinishDragImages; end; end; end; procedure cxInstallMouseHookForDragControl(AControl: TcxEditingControl); begin cxDragControl := AControl; cxDragPrevHook := SetWindowsHookEx(WH_MOUSE, @MouseMsgHookProcForDragDrop, 0, GetCurrentThreadID); end; procedure cxResetMouseHookForDragControl; begin try if cxDragPrevHook <> 0 then UnhookWindowsHookEx(cxDragPrevHook); finally cxDragControl := nil; cxDragPrevHook := 0; end; end; { TcxCustomItemDataBinding } constructor TcxCustomItemDataBinding.Create(AOwner: TPersistent); begin inherited Create(AOwner); FDefaultValuesProvider := GetDefaultValuesProviderClass.Create(Self); end; destructor TcxCustomItemDataBinding.Destroy; begin FreeAndNil(FDefaultValuesProvider); inherited Destroy; end; function TcxCustomItemDataBinding.DefaultRepositoryItem: TcxEditRepositoryItem; begin Result := GetDefaultEditDataRepositoryItems.GetItem(GetValueTypeClass); end; function TcxCustomItemDataBinding.GetDefaultCaption: string; begin Result := ''; end; function TcxCustomItemDataBinding.GetDefaultValuesProvider( AProperties: TcxCustomEditProperties): IcxEditDefaultValuesProvider; begin Result := DefaultValuesProvider; end; function TcxCustomItemDataBinding.GetDefaultValuesProviderClass: TcxCustomEditDefaultValuesProviderClass; begin Result := TcxContainerItemDefaultValuesProvider; end; function TcxCustomItemDataBinding.GetValueTypeClass: TcxValueTypeClass; begin Result := TcxStringValueType; end; procedure TcxCustomItemDataBinding.Init; begin end; function TcxCustomItemDataBinding.IsDisplayFormatDefined( AIsCurrencyValueAccepted: Boolean): Boolean; begin Result := DataController.IsDisplayFormatDefined(EditContainer.ItemIndex, not AIsCurrencyValueAccepted) or EditContainer.HasDataTextHandler; end; procedure TcxCustomItemDataBinding.ValueTypeClassChanged; begin DataController.ChangeValueTypeClass(EditContainer.ItemIndex, GetValueTypeClass); EditContainer.InternalPropertiesChanged; end; function TcxCustomItemDataBinding.GetDataController: TcxCustomDataController; begin Result := EditContainer.EditingControl.DataController; end; function TcxCustomItemDataBinding.GetEditContainer: TcxCustomInplaceEditContainer; begin Result := TcxCustomInplaceEditContainer(GetOwner); end; { TcxItemDataBinding } procedure TcxItemDataBinding.Assign(Source: TPersistent); begin if Source is TcxItemDataBinding then begin ValueType := TcxItemDataBinding(Source).ValueType; ValueTypeClass := TcxItemDataBinding(Source).ValueTypeClass; end; end; function TcxItemDataBinding.GetValueTypeClass: TcxValueTypeClass; begin if FValueTypeClass = nil then Result := inherited GetValueTypeClass else Result := FValueTypeClass; end; function TcxItemDataBinding.IsValueTypeStored: Boolean; begin Result := FValueTypeClass <> inherited GetValueTypeClass; end; function TcxItemDataBinding.GetValueType: string; begin Result := ValueTypeClassRepository.FindByClassType(ValueTypeClass); end; procedure TcxItemDataBinding.SetValueType(const Value: string); var ATypeClass: TcxValueTypeClass; begin ATypeClass := ValueTypeClassRepository.FindByDescription(Value); if ATypeClass <> nil then ValueTypeClass := ATypeClass; end; procedure TcxItemDataBinding.SetValueTypeClass(Value: TcxValueTypeClass); begin if ValueTypeClass <> Value then begin FValueTypeClass := Value; ValueTypeClassChanged; end; end; { TcxControlDataController } procedure TcxControlDataController.UpdateData; begin GetControl.UpdateData; end; procedure TcxControlDataController.UpdateItemIndexes; begin GetControl.UpdateIndexes; inherited UpdateItemIndexes; end; function TcxControlDataController.GetItem(Index: Integer): TObject; begin Result := GetControl.FContainerList[Index]; end; function TcxControlDataController.GetItemID(AItem: TObject): Integer; begin if AItem is TcxCustomInplaceEditContainer then Result := TcxCustomInplaceEditContainer(AItem).ItemIndex else Result := -1; end; function TcxControlDataController.GetItemValueSource( AItemIndex: Integer): TcxDataEditValueSource; begin with TcxCustomInplaceEditContainer(GetControl.FContainerList[AItemIndex]) do Result := PropertiesValue.GetEditValueSource(True); end; procedure TcxControlDataController.UpdateControl(AInfo: TcxUpdateControlInfo); begin GetControl.ControlUpdateData(AInfo); end; function TcxControlDataController.GetControl: TcxEditingControl; begin Result := TcxEditingControl(GetOwner); end; { TcxContainerItemDefaultValuesProvider } function TcxContainerItemDefaultValuesProvider.IsDisplayFormatDefined( AIsCurrencyValueAccepted: Boolean): Boolean; begin Result := False; end; { TcxCustomEditContainerItemOptions } constructor TcxCustomEditContainerItemOptions.Create(AOwner: TPersistent); begin inherited Create(AOwner); FMoving := True; FCustomizing := True; FSorting := True; FEditing := True; FFiltering := True; FFocusing := True; FIncSearch := True; FShowEditButtons := eisbDefault; FTabStop := True; end; procedure TcxCustomEditContainerItemOptions.Assign(AOwner: TPersistent); begin if AOwner is TcxCustomEditContainerItemOptions then with TcxCustomEditContainerItemOptions(AOwner) do begin Self.Customizing := Customizing; Self.Editing := Editing; Self.Filtering := Filtering; Self.Focusing := Focusing; Self.IncSearch := IncSearch; Self.Moving := Moving; Self.ShowEditButtons := ShowEditButtons; Self.Sorting := Sorting; Self.TabStop := TabStop; end; end; procedure TcxCustomEditContainerItemOptions.Changed; begin EditContainer.Changed; end; function TcxCustomEditContainerItemOptions.GetEditContainer: TcxCustomInplaceEditContainer; begin Result := TcxCustomInplaceEditContainer(GetOwner); end; procedure TcxCustomEditContainerItemOptions.SetEditing(Value: Boolean); begin if FEditing <> Value then begin FEditing := Value; if not Value then EditContainer.Editing := False; end; end; procedure TcxCustomEditContainerItemOptions.SetFiltering(Value: Boolean); begin if FFiltering <> Value then begin FFiltering := Value; Changed; end; end; procedure TcxCustomEditContainerItemOptions.SetFocusing(Value: Boolean); begin if FFocusing <> Value then begin FFocusing := Value; if not Value then EditContainer.Focused := False; end; end; procedure TcxCustomEditContainerItemOptions.SetIncSearch(Value: Boolean); begin if FIncSearch <> Value then begin if not Value and EditContainer.IncSearching then EditContainer.CancelIncSearching; FIncSearch := Value; end; end; procedure TcxCustomEditContainerItemOptions.SetShowEditButtons( Value: TcxEditItemShowEditButtons); begin if Value <> FShowEditButtons then begin FShowEditButtons := Value; Changed; end; end; { TcxControlOptionsView } constructor TcxControlOptionsView.Create(AOwner: TPersistent); begin inherited Create(AOwner); FShowEditButtons := ecsbNever; end; procedure TcxControlOptionsView.Assign(Source: TPersistent); begin if Source is TcxControlOptionsView then with TcxControlOptionsView(Source) do begin Self.CellAutoHeight := CellAutoHeight; Self.CellEndEllipsis := CellEndEllipsis; Self.CellTextMaxLineCount := CellTextMaxLineCount; Self.ScrollBars := ScrollBars; Self.ShowEditButtons := ShowEditButtons; end end; procedure TcxControlOptionsView.Changed; begin EditingControl.LayoutChanged; end; function TcxControlOptionsView.GetEditingControl: TcxEditingControl; begin Result := TcxEditingControl(GetOwner); end; function TcxControlOptionsView.GetScrollBars: TScrollStyle; begin Result := EditingControl.ScrollBars; end; procedure TcxControlOptionsView.SetCellAutoHeight(const Value: Boolean); begin if FCellAutoHeight <> Value then begin FCellAutoHeight := Value; Changed; end; end; procedure TcxControlOptionsView.SetCellEndEllipsis(const Value: Boolean); begin if FCellEndEllipsis <> Value then begin FCellEndEllipsis := Value; Changed; end; end; procedure TcxControlOptionsView.SetCellTextMaxLineCount( const Value: Integer); begin if FCellTextMaxLineCount <> Value then begin FCellTextMaxLineCount := Value; Changed; end; end; procedure TcxControlOptionsView.SetScrollBars(const Value: TScrollStyle); begin EditingControl.ScrollBars := Value; end; procedure TcxControlOptionsView.SetShowEditButtons( const Value: TcxEditingControlEditShowButtons); begin if FShowEditButtons <> Value then begin FShowEditButtons := Value; Changed; end; end; { TcxControlOptionsData } constructor TcxControlOptionsData.Create(AOwner: TPersistent); begin inherited Create(AOwner); FCancelOnExit := True; FEditing := True; end; procedure TcxControlOptionsData.Assign(Source: TPersistent); begin if Source is TcxControlOptionsData then with TcxControlOptionsData(Source) do begin Self.CancelOnExit := CancelOnExit; Self.Editing := Editing; end end; procedure TcxControlOptionsData.Changed; begin end; function TcxControlOptionsData.GetEditingControl: TcxEditingControl; begin Result := TcxEditingControl(GetOwner) end; procedure TcxControlOptionsData.SetEditing(Value: Boolean); begin if FEditing <> Value then begin FEditing := Value; if not Value then EditingControl.Controller.EditingItem := nil; Changed; end; end; { TcxControlOptionsBehavior } constructor TcxControlOptionsBehavior.Create(AOwner: TPersistent); begin inherited Create(AOwner); FImmediateEditor := True; end; procedure TcxControlOptionsBehavior.Assign(Source: TPersistent); begin if Source is TcxControlOptionsBehavior then with TcxControlOptionsBehavior(Source) do begin Self.AlwaysShowEditor := AlwaysShowEditor; Self.CellHints := CellHints; Self.FocusCellOnCycle := FocusCellOnCycle; Self.FocusFirstCellOnNewRecord := FocusFirstCellOnNewRecord; Self.GoToNextCellOnEnter := GoToNextCellOnEnter; Self.GoToNextCellOnTab := GoToNextCellOnTab; Self.ImmediateEditor := ImmediateEditor; end end; procedure TcxControlOptionsBehavior.Changed; begin if EditingControl.Controller <> nil then EditingControl.Controller.BehaviorChanged; end; function TcxControlOptionsBehavior.GetEditingControl: TcxEditingControl; begin Result := TcxEditingControl(GetOwner); end; procedure TcxControlOptionsBehavior.SetAlwaysShowEditor(Value: Boolean); begin if FAlwaysShowEditor <> Value then begin FAlwaysShowEditor := Value; Changed; end; end; procedure TcxControlOptionsBehavior.SetCellHints(Value: Boolean); begin if FCellHints <> Value then begin FCellHints := Value; Changed; end; end; procedure TcxControlOptionsBehavior.SetFocusCellOnCycle(Value: Boolean); begin if FFocusCellOnCycle <> Value then begin FFocusCellOnCycle := Value; Changed; end; end; procedure TcxControlOptionsBehavior.SetFocusFirstCellOnNewRecord( Value: Boolean); begin if FFocusFirstCellOnNewRecord <> Value then begin FFocusFirstCellOnNewRecord := Value; Changed; end; end; procedure TcxControlOptionsBehavior.SetGoToNextCellOnEnter(Value: Boolean); begin if FGoToNextCellOnEnter <> Value then begin FGoToNextCellOnEnter := Value; Changed; end; end; procedure TcxControlOptionsBehavior.SetGoToNextCellOnTab(Value: Boolean); begin if FGoToNextCellOnTab <> Value then begin FGoToNextCellOnTab := Value; with EditingControl do if Value then Keys := Keys + [kTab] else Keys := Keys - [kTab]; Changed; end; end; procedure TcxControlOptionsBehavior.SetImmediateEditor(Value: Boolean); begin if FImmediateEditor <> Value then begin FImmediateEditor := Value; Changed; end; end; procedure TcxControlOptionsBehavior.SetIncSearch(Value: Boolean); begin if Value <> FIncSearch then begin FIncSearch := Value; if not Value then EditingControl.Controller.CancelIncSearching; end; end; procedure TcxControlOptionsBehavior.SetIncSearchItem(Value: TcxCustomInplaceEditContainer); begin if Value <> FIncSearchItem then begin FIncSearchItem := Value; EditingControl.Controller.CancelIncSearching; end; end; { TcxEditContainerStyles } procedure TcxEditContainerStyles.Assign(Source: TPersistent); begin if Source is TcxEditContainerStyles then Content := TcxEditContainerStyles(Source).Content; inherited Assign(Source); end; procedure TcxEditContainerStyles.Changed(AIndex: Integer); begin inherited Changed(AIndex); Control.UpdateViewStyles; end; function TcxEditContainerStyles.GetContainer: TcxCustomInplaceEditContainer; begin Result := TcxCustomInplaceEditContainer(GetOwner); end; function TcxEditContainerStyles.GetControl: TcxEditingControl; begin Result := Container.EditingControl; end; function TcxEditContainerStyles.GetControlStyles: TcxCustomControlStyles; begin Result := Control.Styles; end; { TcxCustomInplaceEditContainer } constructor TcxCustomInplaceEditContainer.Create(AOwner: TComponent); begin inherited Create(AOwner); FDataBinding := GetDataBindingClass.Create(Self); FOptions := GetOptionsClass.Create(Self); FStyles := GetStylesClass.Create(Self); end; destructor TcxCustomInplaceEditContainer.Destroy; begin if not EditingControl.IsDestroying and EditingControl.IsDesigning and (Controller.DesignSelectionHelper <> nil) then Controller.DesignSelectionHelper.UnselectObject(Self); RepositoryItem := nil; EditingControl := nil; FOptions.Free; FDataBinding.Free; FStyles.Free; DestroyProperties; inherited Destroy; end; procedure TcxCustomInplaceEditContainer.Assign(Source: TPersistent); begin if Source is TcxCustomInplaceEditContainer then with TcxCustomInplaceEditContainer(Source) do begin Self.DataBinding := DataBinding; Self.PropertiesClassName := PropertiesClassName; Self.Properties := Properties; Self.RepositoryItem := RepositoryItem; Self.Styles := Styles; Self.OnGetEditProperties := OnGetEditProperties; end end; procedure TcxCustomInplaceEditContainer.CalculateEditViewInfo( const AValue: Variant; AEditViewInfo: TcxEditCellViewInfo; const APoint: TPoint); var ACanvas: TcxCanvas; begin ACanvas := GetControlCanvas; cxAssignEditStyle(AEditViewInfo); with AEditViewInfo do begin if IncSearching and (Controller.IncSearchingItem = Self) and (Controller.FocusedRecordIndex = RecordIndex) then with ViewData do begin SelTextColor := GetSelectedTextColor; SelBackgroundColor := GetSelectedBKColor; SelStart := 0; SelLength := Length(Controller.IncSearchingText); end else ViewData.SelLength := 0; ViewData.MaxLineCount := AEditViewInfo.MaxLineCount; ViewData.InplaceEditParams.Position.RecordIndex := RecordIndex; ViewData.EditValueToDrawValue(ACanvas, AValue, ViewInfo); ViewData.ContentOffset := ContentOffset; ViewData.CalculateEx(ACanvas, ContentRect, APoint, cxmbNone, [], ViewInfo, False); end; end; function TcxCustomInplaceEditContainer.CanEdit: Boolean; begin Result := CanFocus and EditingControl.Options.OptionsData.Editing and FOptions.Editing and (dceoShowEdit in DataController.EditOperations) and (DataController.RecordCount > 0); end; function TcxCustomInplaceEditContainer.CanFocus: Boolean; begin Result := Options.FFocusing; end; procedure TcxCustomInplaceEditContainer.CancelIncSearching; begin Controller.CancelIncSearching; end; function TcxCustomInplaceEditContainer.CanInitEditing: Boolean; begin Result := DataController.CanInitEditing(ItemIndex); end; function TcxCustomInplaceEditContainer.CanIncSearch: Boolean; begin Result := (esoIncSearch in FPropertiesValue.GetSupportedOperations) and EditingControl.Options.OptionsBehavior.IncSearch and Options.IncSearch; end; function TcxCustomInplaceEditContainer.CanTabStop: Boolean; begin Result := Options.TabStop; end; procedure TcxCustomInplaceEditContainer.Changed; begin if EditingControl <> nil then EditingControl.UpdateViewStyles; end; function TcxCustomInplaceEditContainer.CreateEditViewData( AProperties: TcxCustomEditProperties; AEditStyleData: Pointer): TcxCustomEditViewData; begin Result := AProperties.CreateViewData(GetEditStyle(AEditStyleData), True); Result.OnGetDisplayText := EditViewDataGetDisplayTextHandler; end; procedure TcxCustomInplaceEditContainer.DataChanged; begin FDataBinding.Init; InternalPropertiesChanged; end; procedure TcxCustomInplaceEditContainer.DoGetDisplayText( ARecordIndex: Integer; var AText: string); begin end; function TcxCustomInplaceEditContainer.DoGetEditProperties( AData: Pointer): TcxCustomEditProperties; begin Result := DoGetPropertiesFromEvent(FOnGetEditProperties, AData, FPropertiesValue); end; procedure TcxCustomInplaceEditContainer.DoGetEditingProperties(AData: Pointer; var AProperties: TcxCustomEditProperties); begin AProperties := DoGetPropertiesFromEvent(FOnGetEditingProperties, AData, AProperties); end; function TcxCustomInplaceEditContainer.DoGetPropertiesFromEvent( AEvent: TcxGetEditPropertiesEvent; AData: Pointer; AProperties: TcxCustomEditProperties): TcxCustomEditProperties; begin Result := AProperties; if Assigned(AEvent) then begin AEvent(Self, AData, Result); if Result = nil then Result := AProperties; end; InitProperties(Result); end; procedure TcxCustomInplaceEditContainer.DoOnPropertiesChanged(Sender: TObject); begin InternalPropertiesChanged; end; procedure TcxCustomInplaceEditContainer.EditViewDataGetDisplayTextHandler( Sender: TcxCustomEditViewData; var AText: string); begin if Sender <> nil then DoGetDisplayText(Sender.InplaceEditParams.Position.RecordIndex, AText); end; function TcxCustomInplaceEditContainer.GetDefaultEditProperties: TcxCustomEditProperties; begin if FRepositoryItem <> nil then Result := FRepositoryItem.Properties else if FProperties <> nil then Result := FProperties else Result := DataBinding.DefaultRepositoryItem.Properties; end; function TcxCustomInplaceEditContainer.GetControlCanvas: TcxCanvas; begin if (EditingControl <> nil) and EditingControl.HandleAllocated then Result := EditingControl.Canvas else Result := cxScreenCanvas; end; function TcxCustomInplaceEditContainer.GetController: TcxCustomControlController; begin Result := EditingControl.Controller; end; function TcxCustomInplaceEditContainer.GetCurrentValue: Variant; begin with DataController do Result := Values[FocusedRecordIndex, ItemIndex]; end; function TcxCustomInplaceEditContainer.GetDataBindingClass: TcxItemDataBindingClass; begin Result := TcxItemDataBinding; end; function TcxCustomInplaceEditContainer.GetDefaultCaption: string; begin Result := DataBinding.GetDefaultCaption; end; function TcxCustomInplaceEditContainer.GetDisplayValue( AProperties: TcxCustomEditProperties; ARecordIndex: Integer): Variant; begin if AProperties.GetEditValueSource(False) = evsValue then Result := Values[ARecordIndex] else Result := DataController.DisplayTexts[ARecordIndex, ItemIndex]; end; function TcxCustomInplaceEditContainer.GetEditDataValueTypeClass: TcxValueTypeClass; begin Result := FDataBinding.GetValueTypeClass; end; function TcxCustomInplaceEditContainer.GetEditDefaultHeight(AFont: TFont): Integer; var ASizeProp: TcxEditSizeProperties; begin ASizeProp := cxDefaultEditSizeProp; EditViewData.Style.Font := AFont; if AFont = nil then EditViewData.Style.Font := EditingControl.Font; EditViewData.ContentOffset := cxNullRect; Result := EditViewData.GetEditSize(GetControlCanvas, Null, ASizeProp).cy; end; function TcxCustomInplaceEditContainer.GetEditHeight( AEditViewInfo: TcxEditCellViewInfo): Integer; var ASizeProp: TcxEditSizeProperties; begin ASizeProp := cxDefaultEditSizeProp; with AEditViewInfo do begin ViewData.Style.Font := ViewParams.Font; if ViewParams.Font = nil then EditViewData.Style.Font := EditingControl.Font; ViewData.ContentOffset := ContentOffset; ASizeProp.Width := cxRectWidth(ContentRect); ASizeProp.MaxLineCount := MaxLineCount; Result := ViewData.GetEditSize(GetControlCanvas, DisplayValue, ASizeProp).cy; Inc(Result, Byte(bBottom in Borders)); Inc(Result, Byte(bTop in Borders)); end; end; function TcxCustomInplaceEditContainer.GetEditWidth( AEditViewInfo: TcxEditCellViewInfo): Integer; var ASizeProp: TcxEditSizeProperties; begin ASizeProp := cxDefaultEditSizeProp; with AEditViewInfo do begin ViewData.Style.Font := ViewParams.Font; ViewData.ContentOffset := ContentOffset; ASizeProp.MaxLineCount := MaxLineCount; Result := ViewData.GetEditSize(GetControlCanvas, DisplayValue, ASizeProp).cx; end; end; function TcxCustomInplaceEditContainer.GetOptionsClass: TcxCustomEditContainerItemOptionsClass; begin Result := TcxCustomEditContainerItemOptions; end; function TcxCustomInplaceEditContainer.GetStylesClass: TcxEditContainerStylesClass; begin Result := TcxEditContainerStyles; end; function TcxCustomInplaceEditContainer.GetValue(ARecordIndex: Integer): Variant; begin Result := DataController.Values[ARecordIndex, ItemIndex]; end; function TcxCustomInplaceEditContainer.GetValueCount: Integer; begin if FEditingControl <> nil then Result := DataController.RecordCount else Result := 0; end; function TcxCustomInplaceEditContainer.HasDataTextHandler: Boolean; begin Result := False; end; function TcxCustomInplaceEditContainer.GetEditing: Boolean; begin Result := Controller.EditingItem = Self; end; function TcxCustomInplaceEditContainer.GetEditStyle(AData: Pointer): TcxCustomEditStyle; begin Result := EditingControl.EditStyle end; function TcxCustomInplaceEditContainer.GetEditValue: Variant; begin if Editing then begin if DataController.RecordCount = 0 then Result := Null else Result := DataController.GetEditValue(ItemIndex, FEditValueSource); end else Result := Unassigned; end; procedure TcxCustomInplaceEditContainer.PropertiesChanged; begin Changed; end; procedure TcxCustomInplaceEditContainer.SetCurrentValue(const Value: Variant); begin with DataController do Values[FocusedRecordIndex, ItemIndex] := Value; end; procedure TcxCustomInplaceEditContainer.SetEditing(Value: Boolean); begin if Value then Controller.EditingItem := Self else if Editing then Controller.EditingItem := nil; end; procedure TcxCustomInplaceEditContainer.SetEditingControl( Value: TcxEditingControl); begin if FEditingControl <> Value then begin if Value <> nil then Value.ViewInfo.State[cvis_StyleInvalid] := True; if FEditingControl <> nil then FEditingControl.DoInplaceEditContainerItemRemoved(Self); FEditingControl := Value; if FEditingControl <> nil then begin FEditingControl.BeginUpdate; try FEditingControl.DoInplaceEditContainerItemAdded(Self); DataBinding.ValueTypeClassChanged; finally FEditingControl.CancelUpdate; InternalPropertiesChanged; end; end; end; end; procedure TcxCustomInplaceEditContainer.SetEditValue(const Value: Variant); begin if Editing then DataController.SetEditValue(ItemIndex, Value, FEditValueSource); end; procedure TcxCustomInplaceEditContainer.SetValue( ARecordIndex: Integer; const Value: Variant); begin DataController.Values[ARecordIndex, ItemIndex] := Value; end; function TcxCustomInplaceEditContainer.GetDataController: TcxCustomDataController; begin Result := FEditingControl.DataController; end; function TcxCustomInplaceEditContainer.GetFocused: Boolean; begin Result := Controller.FocusedItem = Self; end; function TcxCustomInplaceEditContainer.GetFocusedCellViewInfo: TcxEditCellViewInfo; begin Result := Controller.GetFocusedCellViewInfo(Self); end; function TcxCustomInplaceEditContainer.GetIncSearching: Boolean; begin Result := Controller.IncSearchingItem = Self; end; function TcxCustomInplaceEditContainer.GetProperties: TcxCustomEditProperties; begin Result := FProperties; end; function TcxCustomInplaceEditContainer.GetPropertiesClass: TcxCustomEditPropertiesClass; begin Result := FPropertiesClass; end; function TcxCustomInplaceEditContainer.GetPropertiesClassName: string; begin if FProperties = nil then Result := '' else Result := FProperties.ClassName; end; function TcxCustomInplaceEditContainer.GetPropertiesValue: TcxCustomEditProperties; begin Result := FPropertiesValue; Result.LockUpdate(True); if FDataBinding = nil then Result.IDefaultValuesProvider := nil else Result.IDefaultValuesProvider := FDataBinding.DefaultValuesProvider; Result.LockUpdate(False); end; procedure TcxCustomInplaceEditContainer.SetDataBinding(Value: TcxCustomItemDataBinding); begin FDataBinding.Assign(Value); end; procedure TcxCustomInplaceEditContainer.SetFocused(Value: Boolean); begin if Value then Controller.FocusedItem := Self else if Focused then // TODO: { if not Controller.FocusNextItem(VisibleIndex, True, True, False) then Controller.FocusedItem := nil;} end; procedure TcxCustomInplaceEditContainer.SetOptions( Value: TcxCustomEditContainerItemOptions); begin FOptions.Assign(Value); end; procedure TcxCustomInplaceEditContainer.SetProperties( Value: TcxCustomEditProperties); begin if (FProperties <> nil) and (Value <> nil) then FProperties.Assign(Value); end; procedure TcxCustomInplaceEditContainer.SetPropertiesClass( Value: TcxCustomEditPropertiesClass); begin if FPropertiesClass <> Value then begin FPropertiesClass := Value; RecreateProperties; end; end; procedure TcxCustomInplaceEditContainer.SetPropertiesClassName( const Value: string); begin if PropertiesClassName <> Value then begin with GetRegisteredEditProperties do PropertiesClass := TcxCustomEditPropertiesClass(FindByClassName(Value)); end; end; procedure TcxCustomInplaceEditContainer.SetRepositoryItem( Value: TcxEditRepositoryItem); begin if FRepositoryItem <> Value then begin if FRepositoryItem <> nil then begin FRepositoryItem.RemoveListener(Self); Controller.EditingController.RemoveEdit(FRepositoryItem.Properties); end; FRepositoryItem := Value; if FRepositoryItem <> nil then FRepositoryItem.AddListener(Self); InternalPropertiesChanged; end; end; procedure TcxCustomInplaceEditContainer.SetStyles( Value: TcxEditContainerStyles); begin FStyles.Assign(Value); end; procedure TcxCustomInplaceEditContainer.CreateProperties; begin if FPropertiesClass <> nil then FProperties := FPropertiesClass.Create(Self); InternalPropertiesChanged; end; procedure TcxCustomInplaceEditContainer.DestroyProperties; begin FreeAndNil(FEditData); FreeAndNil(FEditViewData); FreeAndNil(FProperties); end; procedure TcxCustomInplaceEditContainer.InitEditViewInfo( AEditViewInfo: TcxEditCellViewInfo); procedure CheckOption(IsSetValue: Boolean; Value: TcxEditPaintOption); begin if IsSetValue then Include(AEditViewInfo.ViewData.PaintOptions, Value) else Exclude(AEditViewInfo.ViewData.PaintOptions, Value); end; var AProp: TcxCustomEditProperties; begin with AEditViewInfo do begin AProp := Properties; Properties := DoGetEditProperties(GetViewInfoData); CellValue := GetDisplayValue; ItemViewParams := GetEditViewParams; if (AProp = nil) or (AProp <> Properties) then begin try if IsViewDataCreated then FreeAndNil(ViewData); FreeAndNil(ViewInfo); finally if Properties = FPropertiesValue then ViewData := EditViewData else ViewData := CreateEditViewData(Properties, GetViewInfoData); IsViewDataCreated := ViewData <> EditViewData; ViewInfo := TcxCustomEditViewInfo(Properties.GetViewInfoClass.Create); if not IsViewDataCreated then TcxCustomEditViewDataAccess(ViewData).InitCacheData; end; end else if not IsViewDataCreated then ViewData := EditViewData; CheckOption(IsAutoHeight, epoAutoHeight); CheckOption(IsEndEllipsis, epoShowEndEllipsis); ViewData.InplaceEditParams.Position.RecordIndex := RecordIndex; ViewData.InplaceEditParams.Position.Item := Self; end; end; procedure TcxCustomInplaceEditContainer.InitProperties( AProperties: TcxCustomEditProperties); begin with AProperties do begin LockUpdate(True); try IDefaultValuesProvider := DataBinding.GetDefaultValuesProvider(AProperties); finally LockUpdate(False); end; end; end; procedure TcxCustomInplaceEditContainer.InternalPropertiesChanged; begin if IsDestroying then Exit; Controller.ViewInfoChanged; if not Controller.IsEditing and not Controller.FEditingController.FEditHiding then FreeAndNil(FEditData); FreeAndNil(FEditViewData); FPropertiesValue := GetDefaultEditProperties; InitProperties(FPropertiesValue); if EditingControl <> nil then FEditViewData := CreateEditViewData(FPropertiesValue, nil); with FPropertiesValue do begin if not Assigned(OnPropertiesChanged) then OnPropertiesChanged := DoOnPropertiesChanged; end; PropertiesChanged; end; function TcxCustomInplaceEditContainer.IsDestroying: Boolean; begin Result := csDestroying in ComponentState; end; function TcxCustomInplaceEditContainer.IsEditPartVisible: Boolean; begin Result := (FocusedCellViewInfo <> nil) and not IsRectEmpty(FocusedCellViewInfo.VisibleRect); end; procedure TcxCustomInplaceEditContainer.RecreateProperties; begin DestroyProperties; CreateProperties; end; procedure TcxCustomInplaceEditContainer.RepositoryItemPropertiesChanged( Sender: TcxEditRepositoryItem); begin DoOnPropertiesChanged(Sender); end; procedure TcxCustomInplaceEditContainer.RepositoryItemRemoved(Sender: TcxEditRepositoryItem); begin RepositoryItem := nil; end; { TcxHotTrackController } constructor TcxHotTrackController.Create(AControl: TcxEditingControl); begin FControl := AControl; HintTimer := TcxTimer.Create(nil); HintWindow := HintWindowClass.Create(nil); HintWindow.Color := Application.HintColor; ResetTimer; end; destructor TcxHotTrackController.Destroy; begin HintWindow.Free; HintTimer.Free; inherited Destroy; end; procedure TcxHotTrackController.CancelHint; begin InternalHideHint(HintTimer); end; procedure TcxHotTrackController.Clear; begin PrevHitPoint := cxInvalidPoint; PrevElement := nil; end; procedure TcxHotTrackController.SetHotElement(AElement: TObject; const APoint: TPoint); procedure CalculateHotState(AObject: TObject; const P: TPoint); var AIntf: IcxHotTrackElement; begin if Supports(AObject, IcxHotTrackElement, AIntf) then AIntf.UpdateHotTrackState(P); end; begin if Control.IsLocked then Clear else try if AElement <> PrevElement then begin HintElement := PrevElement; CalculateHotState(PrevElement, cxInvalidPoint); CalculateHotState(AElement, APoint); end else if Int64(PrevHitPoint) <> Int64(APoint) then CalculateHotState(AElement, APoint); finally PrevHitPoint := APoint; PrevElement := AElement; if AElement <> HintElement then CancelHint; if HintNeeded then InternalShowHint(Self); end; end; type TCustomFormAccess = class(TCustomForm); function TcxHotTrackController.CanShowHint: Boolean; var AForm: TCustomForm; begin Result := FShowHint and not Control.Controller.LockShowHint; if Result then begin AForm := GetParentForm(Control); Result := ((AForm = nil) or Application.Active and (AForm.Active or (TCustomFormAccess(AForm).FormStyle = fsMDIForm))) and not Control.IsDesigning and not Control.Dragging and (Control.DragAndDropState = ddsNone) and not ((Control.Controller.GetEditingViewInfo = PrevElement) and Control.Controller.IsEditing); end; end; procedure TcxHotTrackController.CheckDestroyingElement(AElement: TObject); begin if (AElement = PrevElement) or (AElement = HintElement) then begin if AElement = PrevElement then PrevElement := nil; if AElement = HintElement then begin CancelHint; HintElement := nil; end; SetHotElement(nil, cxInvalidPoint); end; end; procedure TcxHotTrackController.CheckHintClass; begin if HintWindow.ClassType <> HintWindowClass then begin HintWindow.Free; HintWindow := HintWindowClass.Create(nil); end; end; procedure TcxHotTrackController.DoHideHint; begin end; procedure TcxHotTrackController.DoShowHint; begin end; function TcxHotTrackController.HintNeeded: Boolean; var P: TPoint; AIntf: IcxHotTrackElement; AIsNeedOffsetHint: Boolean; begin Result := Supports(PrevElement, IcxHotTrackElement, AIntf) and CanShowHint; if Result then begin CheckHintClass; AIsNeedOffsetHint := False; P := cxPoint(PrevHitPoint.X, PrevHitPoint.Y); Result := AIntf.IsNeedHint(cxScreenCanvas, P, Hint, HintIsMultiLine, HintRect, AIsNeedOffsetHint); Control.DoGetCellHint(PrevElement, string(Hint), Result); if Result then begin P := Control.ClientToScreen(AIntf.GetOrigin); if AIsNeedOffsetHint then Inc(P.Y, cxGetCursorSize.cy); THintWindowAccess(HintWindow).Canvas.Font.Assign(cxScreenCanvas.Font); if PrevElement is TcxEditCellViewInfo then begin Dec(P.X); Dec(P.Y); end; HintRect := cxRectOffset(HintWindow.CalcHintRect(Screen.Width, Hint, nil), P.X, P.Y); end; cxScreenCanvas.Dormant; end; end; procedure TcxHotTrackController.InitTimer( AInterval: Integer; AEnabled: Boolean; const AHandler: TNotifyEvent); begin with HintTimer do begin Enabled := False; Interval := AInterval; OnTimer := AHandler; Enabled := AEnabled; end; end; procedure TcxHotTrackController.InternalHideHint(Sender: TObject); begin if HintVisible then try DoHideHint; finally HintVisible := False; ShowWindow(HintWindow.Handle, SW_HIDE); //MUST USE ShowWindow - WIN32 BUG ResetTimer; end; end; procedure TcxHotTrackController.InternalShowHint(Sender: TObject); var AHintInfo: THintInfo; begin if not HintVisible and (HintElement <> PrevElement) then begin if cxProcessControlHintInfo(AHintInfo, HintWindow, Control, Hint, HintRect, HintElement) then begin DoShowHint; HintElement := PrevElement; HintVisible := True; Hint := AHintInfo.HintStr; cxActivateHint(HintWindow, HintRect, Hint); InitTimer(AHintInfo.HideTimeout, (AHintInfo.HideTimeout > 0), InternalHideHint); end; end; end; procedure TcxHotTrackController.ResetTimer; begin InitTimer(Application.HintPause, False, InternalShowHint); end; { TcxEditingController } constructor TcxEditingController.Create(AController: TcxCustomControlController); begin inherited Create; FController := AController; FEditList := TcxInplaceEditList.Create(Controller.EditingControl); end; destructor TcxEditingController.Destroy; begin StopEditShowingTimer; FEditList.Free; inherited Destroy; end; function TcxEditingController.GetEditingControl: TcxEditingControl; begin Result := FController.EditingControl; end; function TcxEditingController.GetEditingProperties: TcxCustomEditProperties; begin if IsEditing and not EditingControl.IsDestroying then with Controller.EditingViewInfo do begin Result := EditContainer.DoGetEditProperties(GetViewInfoData); EditContainer.DoGetEditingProperties(GetViewInfoData, Result); end else Result := nil; end; function TcxEditingController.GetIsDragging: Boolean; begin with EditingControl do Result := Dragging or (DragAndDropState = ddsInProcess); end; function TcxEditingController.GetIsEditing: Boolean; begin Result := FEditingItem <> nil; end; procedure TcxEditingController.SetEditingItem(Value: TcxCustomInplaceEditContainer); begin if FEditingItem <> Value then begin if FEditingItemSetting then Exit; FEditingItemSetting := True; try if Value <> nil then begin if not Value.CanEdit or not EditingControl.DoEditing(Value) then Exit; Value.Focused := True; end; HideEdit(False); FEditingItem := Value; if IsEditing then try ShowEdit(Value); if not FEditPreparing and (FEdit = nil) then FEditingItem := nil; except FEditingItem := nil; raise; end; finally FEditingItemSetting := False; end; end; end; procedure TcxEditingController.EditShowingTimerHandler(Sender: TObject); begin StopEditShowingTimer; FEditShowingTimerItem.Editing := True; Controller.FEditingBeforeDrag := Controller.IsEditing; end; procedure TcxEditingController.AfterViewInfoCalculate; begin if IsEditing and (not FIsEditPlaced or FEditingItem.IsEditPartVisible) then begin CancelEditUpdatePost; FEdit.Left := cxInvisibleCoordinate; end; end; procedure TcxEditingController.BeforeViewInfoCalculate; begin FIsEditPlaced := False; end; procedure TcxEditingController.CancelEditUpdatePost; begin FEditUpdateNeeded := False; end; function TcxEditingController.CanRemoveEditFocus: Boolean; begin Result := not (IsEditing and FEdit.IsFocused and not FEditHiding); end; function TcxEditingController.CanUpdateEditValue: Boolean; begin Result := IsEditing and not FEditHiding and not FInitiatingEditing and not FEdit.IsPosting; end; procedure TcxEditingController.CheckEditUpdatePost; begin if FEditUpdateNeeded then DoUpdateEdit; end; procedure TcxEditingController.AssignEditEvents; begin with FEdit do begin OnAfterKeyDown := EditAfterKeyDown; OnEditing := EditEditing; OnPostEditValue := EditPostEditValue; OnExit := EditExit; OnDblClick := EditDblClick; OnFocusChanged := EditFocusChanged; OnKeyDown := EditKeyDown; OnKeyPress := EditKeyPress; OnKeyUp := EditKeyUp; InternalProperties.OnChange := EditChanged; InternalProperties.OnEditValueChanged := EditValueChanged; end; end; procedure TcxEditingController.UnassignEditEvents; begin with FEdit do begin OnAfterKeyDown := nil; OnEditing := nil; OnPostEditValue := nil; OnExit := nil; OnDblClick := nil; OnFocusChanged := nil; OnKeyDown := nil; OnKeyPress := nil; OnKeyUp := nil; InternalProperties.OnChange := FPrevEditOnChange; InternalProperties.OnEditValueChanged := FPrevEditOnEditValueChanged; end; end; procedure TcxEditingController.DoUpdateEdit; var AEditViewInfo: TcxEditCellViewInfo; begin CancelEditUpdatePost; if IsEditing and (FEdit <> nil) then begin with Controller do begin BeforeShowEdit; AEditViewInfo := GetFocusedCellViewInfo(FFocusedItem); end; if (AEditViewInfo = nil) or not AEditViewInfo.Visible or cxRectIsEmpty(AEditViewInfo.EditRect) then FEdit.Left := cxInvisibleCoordinate else begin if FEditPreparing then begin AEditViewInfo.Refresh(False); cxAssignEditStyle(AEditViewInfo); FEdit.Style.Assign(EditingControl.EditStyle); end; FEdit.BoundsRect := AEditViewInfo.EditRect; FEdit.Visible := True; end; end; end; function TcxEditingController.GetHideEditOnExit: Boolean; begin Result := not Controller.GetAlwaysShowEditor or Controller.EditingControl.IsFocused; end; function TcxEditingController.GetHideEditOnFocusedRecordChange: Boolean; begin //TODO Result := not FController.GetAlwaysShowEditor or (FEditingItem <> nil) and Assigned(FEditingItem.OnGetEditProperties) {or FEditingItem.ShowButtons(False)} or // (esoAlwaysHotTrack in FEditingItem.FocusedCellViewInfo.Properties.GetSupportedOperations)) or // TODO: HitTestController Assigned(EditingControl.OnEditing) or Assigned(EditingControl.OnInitEdit); end; procedure TcxEditingController.HideInplaceEditor; begin if FEdit <> nil then begin UnassignEditEvents; FEdit.EditModified := False; FController.AllowCheckEdit := False; try FController.SetFocus; finally FController.AllowCheckEdit := True; end; FEdit.Visible := False; FEdit.RepositoryItem := nil; FEdit := nil; end; end; procedure TcxEditingController.InitEdit; begin with FEdit.InternalProperties do begin FPrevEditOnChange := OnChange; FPrevEditOnEditValueChanged := OnEditValueChanged; OnChange := nil; OnEditValueChanged := nil; end; FEdit.InplaceParams.Position := FEditingItem.FocusedCellViewInfo.GetInplaceEditPosition; UpdateEdit; UpdateEditValue; AssignEditEvents; EditingControl.DoInitEdit(FEditingItem, FEdit); end; function TcxEditingController.PrepareEdit(AItem: TcxCustomInplaceEditContainer; AIsMouseEvent: Boolean): Boolean; var AEditCellViewInfo: TcxEditCellViewInfo; AProperties: TcxCustomEditProperties; AAssignRepositoryItem: Boolean; begin Result := False; Controller.CancelCheckEditPost; if FEditPreparing or FEditHiding or (AItem = nil) or IsDragging then Exit; if AItem.Editing and not FEditingItemSetting then begin Result := (FEdit <> nil) and (FController.EditingControl.Focused and not FEdit.IsFocused or AIsMouseEvent); Exit; end; EditingControl.ViewInfo.ValidateDirty; FEditPreparing := True; try Result := FController.EditingControl.Focused; if not Result then Exit; Controller.BeforeShowEdit; AEditCellViewInfo := Controller.GetFocusedCellViewInfo(AItem); AItem.Editing := AEditCellViewInfo <> nil; Result := AItem.Editing; EditingControl.ViewInfo.ValidateDirty; if not Result then Exit; try AItem.FEditValueSource := EditingProperties.GetEditValueSource(True); AProperties := EditingProperties; if (AItem.Properties <> nil) and (AItem.RepositoryItem <> nil) and (AProperties = AItem.RepositoryItem.Properties) then begin AProperties := AItem.Properties; AAssignRepositoryItem := True; end else AAssignRepositoryItem := False; FEdit := FEditList.GetEdit(AProperties); if AAssignRepositoryItem then FEdit.RepositoryItem := AItem.RepositoryItem; FEdit.Visible := False; FEdit.Parent := nil; FEdit.Parent := EditingControl; except AItem.Editing := False; Result := False; raise; end; FEditingItem.FocusedCellViewInfo.Invalidate; InitEdit; finally FEditPreparing := False; end; end; procedure TcxEditingController.UpdateEdit; begin if (FEdit = nil) or (FEditingItem.FocusedCellViewInfo = nil) then Exit; if FEditPreparing then DoUpdateEdit else PostEditUpdate; FIsEditPlaced := True; end; procedure TcxEditingController.UpdateEditValue; begin if CanUpdateEditValue then begin FEdit.LockChangeEvents(True); try FEdit.EditValue := EditingItem.EditValue; finally FEdit.LockChangeEvents(False, False); end; FEdit.SelectAll; end; end; procedure TcxEditingController.UpdateValue; begin if IsEditing and FEdit.EditModified then begin FEdit.ValidateEdit(True); FEditingItem.EditValue := FEdit.EditValue; if FEdit <> nil then FEdit.ModifiedAfterEnter := False; end; end; procedure TcxEditingController.EditAfterKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin if FController.IsKeyForController(Key, Shift) then FController.KeyDown(Key, Shift); end; procedure TcxEditingController.EditChanged(Sender: TObject); begin if Assigned(FPrevEditOnChange) then FPrevEditOnChange(Sender); EditingControl.DoEditChanged(FEditingItem); end; procedure TcxEditingController.EditDblClick(Sender: TObject); begin Controller.DoEditDblClick(Sender); end; procedure TcxEditingController.EditEditing(Sender: TObject; var CanEdit: Boolean); begin FInitiatingEditing := True; try CanEdit := (EditingItem <> nil) and EditingItem.CanInitEditing; finally FInitiatingEditing := False; end; end; procedure TcxEditingController.EditEnter(Sender: TObject); begin if not Controller.Focused then begin Controller.Focused := True; Controller.ControlFocusChanged; end; end; procedure TcxEditingController.EditExit(Sender: TObject); begin if HideEditOnExit then try HideEdit(not FController.GetCancelEditingOnExit); except if IsEditing then begin FEdit.SetFocus; FIsErrorOnEditExit := True; end; raise; end; FController.EditingControl.FocusChanged; end; procedure TcxEditingController.EditFocusChanged(Sender: TObject); begin Controller.FFocused := EditingControl.IsFocused or (IsEditing and (Edit <> nil) and Edit.Focused); Controller.EditingControl.ViewInfo.UpdateSelection; end; procedure TcxEditingController.EditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); var AModified: Boolean; begin if Assigned(EditingControl.OnKeyDown) then EditingControl.OnKeyDown(EditingControl, Key, Shift); with FController do begin BeforeEditKeyDown(Key, Shift); if not EditingControl.IsScrollingContent and IsKeyForController(Key, Shift) then FController.MakeFocusedItemVisible; end; case Key of VK_RETURN: begin HideEdit(True); if FController.GetGoToNextCellOnEnter then begin FController.BlockRecordKeyboardHandling := True; try FController.KeyDown(Key, Shift); finally FController.BlockRecordKeyboardHandling := False; end; ShowEdit; end else FController.CheckEdit; Key := 0; end; VK_ESCAPE: begin AModified := FEdit.EditModified; HideEdit(False); FController.CheckEdit; if AModified then Key := 0; end; VK_DELETE: if Shift = [ssCtrl] then begin FController.KeyDown(Key, Shift); Key := 0; end; end; end; procedure TcxEditingController.EditKeyPress(Sender: TObject; var Key: Char); begin if Assigned(EditingControl.OnKeyPress) then EditingControl.OnKeyPress(EditingControl, Key); if Key = #27 then Key := #0; FController.MakeFocusedItemVisible; end; procedure TcxEditingController.EditKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); begin if Assigned(EditingControl.OnKeyUp) then EditingControl.OnKeyUp(EditingControl, Key, Shift); end; procedure TcxEditingController.EditPostEditValue(Sender: TObject); begin UpdateValue; end; procedure TcxEditingController.EditValueChanged(Sender: TObject); begin if Assigned(FPrevEditOnEditValueChanged) then FPrevEditOnEditValueChanged(Sender); EditingControl.DoEditValueChanged(FEditingItem); end; procedure TcxEditingController.HideEdit(Accept: Boolean); var AEditViewInfo: TcxEditCellViewInfo; AItem: TcxCustomInplaceEditContainer; begin FController.CancelCheckEditPost; CancelEditUpdatePost; StopEditShowingTimer; if FEditHiding or not IsEditing or EditingControl.IsDestroying then Exit; FEditHiding := True; try if Accept then begin if not FEdit.Deactivate then raise EAbort.Create(''); EditingControl.DataController.PostEditingData; if FController.IsImmediatePost then EditingControl.DataController.Post; if FEditingItem = nil then Exit; AEditViewInfo := FEditingItem.FocusedCellViewInfo; if AEditViewInfo <> nil then FEdit.InternalProperties.Update(AEditViewInfo.Properties); end; AItem := EditingItem; if not EditingControl.IsDestroying then EditingControl.DoEdited(AItem); EditingItem := nil; Controller.RefreshFocusedCellViewInfo(AItem); HideInplaceEditor; FIsErrorOnEditExit := False; finally FEditHiding := False; if EditingControl.ViewInfo.IsDirty then EditingControl.LayoutChanged; end; end; procedure TcxEditingController.PostEditUpdate; begin FEditUpdateNeeded := True; end; procedure TcxEditingController.RemoveEdit(AProperties: TcxCustomEditProperties); begin if EditingProperties = AProperties then EditingItem := nil; FEditList.RemoveItem(AProperties); end; procedure TcxEditingController.ShowEdit(AItem: TcxCustomInplaceEditContainer = nil); begin if AItem = nil then AItem := FController.FocusedItem; if PrepareEdit(AItem, False) then FEdit.Activate(AItem.FEditData); end; procedure TcxEditingController.ShowEdit(AItem: TcxCustomInplaceEditContainer; Key: Char); begin if PrepareEdit(AItem, False) then FEdit.ActivateByKey(Key, AItem.FEditData); end; procedure TcxEditingController.ShowEdit(AItem: TcxCustomInplaceEditContainer; Shift: TShiftState; X, Y: Integer); begin if PrepareEdit(AItem, True) then FEdit.ActivateByMouse(Shift, X, Y, AItem.FEditData); end; procedure TcxEditingController.StartEditShowingTimer(AItem: TcxCustomInplaceEditContainer); begin StopEditShowingTimer; FEditShowingTimerItem := AItem; FEditShowingTimer := TcxTimer.Create(nil); with FEditShowingTimer do begin Interval := GetDblClickInterval; OnTimer := EditShowingTimerHandler; end; end; procedure TcxEditingController.StopEditShowingTimer; begin FreeAndNil(FEditShowingTimer); end; { TcxSizingDragAndDropObject } procedure TcxSizingDragAndDropObject.BeginDragAndDrop; begin if (DragItem = nil) or (DragSizing = nil) then raise EAbort.Create(''); FDirection := Controller.GetResizeDirection; FDragBounds := DragSizing.GetSizingBoundsRect(FDirection); FSizeDelta := DragSizing.GetSizingIncrement(FDirection); FStartPos := CurMousePos; FDragPos := GetDragPos(CurMousePos); FDynamicUpdate := DragSizing.IsDynamicUpdate; inherited BeginDragAndDrop; end; procedure TcxSizingDragAndDropObject.DirtyChanged; begin if not DynamicUpdate and cxRectIntersect(GetSizingMarkBounds, Control.ClientBounds) then Canvas.InvertRect(GetSizingMarkBounds); inherited DirtyChanged; end; procedure TcxSizingDragAndDropObject.DragAndDrop( const P: TPoint; var Accepted: Boolean); var ADragPos: TPoint; begin Accepted := True; ADragPos := GetDragPos(P); with FDragBounds do if (DragCoord[P] < DragCoord[TopLeft]) or (DragCoord[P] > DragCoord[BottomRight]) then Exit; if not DynamicUpdate then FDelta := Round((DragCoord[P] - DragCoord[StartPos]) / SizeDelta) else FDelta := Trunc((DragCoord[P] - DragCoord[StartPos]) / SizeDelta); if (FDelta = 0) and (DragCoord[ADragPos] = DragCoord[DragPos]) then Exit; Dirty := True; FDragPos := ADragPos; if DynamicUpdate then begin DragSizing.SetSizeDelta(Direction, Delta); FStartPos := P; end; inherited DragAndDrop(P, Accepted); end; procedure TcxSizingDragAndDropObject.EndDragAndDrop(Accepted: Boolean); begin inherited EndDragAndDrop(Accepted); if Accepted and not DynamicUpdate and (Delta <> 0) and not Controller.FDragCancel then DragSizing.SetSizeDelta(Direction, Delta); end; function TcxSizingDragAndDropObject.GetDragAndDropCursor( Accepted: Boolean): TCursor; begin if IsHorzSizing then Result := crHSplit else Result := crVSplit; end; function TcxSizingDragAndDropObject.GetDragCoord(APoint: TPoint): Integer; begin if IsHorzSizing then Result := APoint.X else Result := APoint.Y; end; function TcxSizingDragAndDropObject.GetDragPos(const APoint: TPoint): TPoint; begin Result := FStartPos; with Result do begin if IsHorzSizing then Inc(X, Round((DragCoord[APoint] - X) / SizeDelta) * SizeDelta) else Inc(Y, Round((DragCoord[APoint] - Y) / SizeDelta) * SizeDelta); end; end; function TcxSizingDragAndDropObject.GetImmediateStart: Boolean; begin Result := True; end; function TcxSizingDragAndDropObject.GetSizingMarkBounds: TRect; begin if IsHorzSizing then Result := cxRectSetLeft(FDragBounds, DragPos.X - cxSizingMarkWidth div 1, cxSizingMarkWidth) else Result := cxRectSetTop(FDragBounds, DragPos.Y - cxSizingMarkWidth div 1, cxSizingMarkWidth); end; function TcxSizingDragAndDropObject.GetCanvas: TcxCanvas; begin Result := TcxEditingControl(Control).Canvas; end; function TcxSizingDragAndDropObject.GetController: TcxCustomControlController; begin Result := TcxEditingControl(Control).Controller; end; function TcxSizingDragAndDropObject.GetDragItem: TObject; begin Result := Controller.DragItem; end; function TcxSizingDragAndDropObject.GetDragSizing: IcxDragSizing; begin Supports(DragItem, IcxDragSizing, Result); end; function TcxSizingDragAndDropObject.GetIsSizingKind(Index: Integer): Boolean; begin Result := TcxDragSizingDirection(Index) = FDirection; end; { TcxAutoScrollingObject } constructor TcxAutoScrollingObject.Create(AOwner: TObject); begin FOwner := AOwner; FTimer := TcxTimer.Create(nil); FTimer.Enabled := False; FTimer.Interval := cxScrollWidthDragInterval; FTimer.OnTimer := TimerHandler; end; destructor TcxAutoScrollingObject.Destroy; begin FTimer.Enabled := False; FTimer.Free; inherited Destroy; end; function TcxAutoScrollingObject.Check(APos: TPoint): Boolean; begin Result := cxRectPtIn(FArea, APos); FTimer.Enabled := Result; end; procedure TcxAutoScrollingObject.SetParams( const Area: TRect; AKind: TScrollBarKind; ACode: TScrollCode; AIncrement: Integer); begin FArea := Area; FCode := ACode; FKind := AKind; if ACode = scLineUp then AIncrement := -AIncrement; FIncrement := AIncrement; end; procedure TcxAutoScrollingObject.Stop; begin FTimer.Enabled := False; end; procedure TcxAutoScrollingObject.DoScrollInspectingControl; var AMin, AMax, APos, ANewPos: Integer; begin with GetScrollBar(FKind) do begin AMin := Min; AMax := Max - PageSize + 1; APos := Position; ANewPos := APos + FIncrement; if ANewPos < AMin then ANewPos := AMin else if ANewPos > AMax then ANewPos := AMax; end; if GetScrollBar(FKind).Visible and (ANewPos <> APos) then Control.Controller.Scroll(FKind, FCode, ANewPos); end; function TcxAutoScrollingObject.GetScrollBar(AKind: TScrollBarKind): TcxControlScrollBar; begin with Control do if AKind = sbHorizontal then Result := HScrollBar else Result := VScrollBar; end; procedure TcxAutoScrollingObject.TimerHandler(Sender: TObject); begin DoScrollInspectingControl; end; function TcxAutoScrollingObject.GetControl: TcxEditingControl; begin Result := nil; end; { TcxDragDropAutoScrollingObject } function TcxDragDropObjectAutoScrollingObject.GetControl: TcxEditingControl; begin Result := TcxEditingControl(TcxDragAndDropObjectAccess(FOwner).Control); end; { TcxControllerAutoScrollingObject } function TcxControllerAutoScrollingObject.CheckBounds(APos: TPoint): Boolean; begin FDirections := []; Result := not cxRectPtIn(FArea, APos); if Result then begin if FCheckHorz then if APos.X <= FArea.Left then Include(FDirections, nLeft) else if APos.X >= FArea.Right then Include(FDirections, nRight); if FCheckVert then if APos.Y <= FArea.Top then Include(FDirections, nTop) else if APos.Y >= FArea.Bottom then Include(FDirections, nBottom); Result := Result and (FDirections <> []); end; FTimer.Enabled := Result; end; procedure TcxControllerAutoScrollingObject.SetBoundsParams( const AClientArea: TRect; ACheckHorz, ACheckVert: Boolean; AIncrement: Integer); begin FArea := AClientArea; FCheckHorz := ACheckHorz; FCheckVert := ACheckVert; FIncrement := AIncrement; FBoundsMode := True; end; procedure TcxControllerAutoScrollingObject.DoScrollInspectingControl; procedure CheckDirection(ADir: TcxNeighbor); const Kinds: array[Boolean] of TScrollBarKind = (sbVertical, sbHorizontal); Codes: array[Boolean] of TScrollCode = (scLineDown, scLineUp); var AMin, AMax, APos, ANewPos: Integer; AKind: TScrollBarKind; ACode: TScrollCode; begin AKind := Kinds[ADir in [nLeft, nRight]]; with GetScrollBar(AKind) do begin if Visible then begin AMin := Min; AMax := Max - PageSize + 1; APos := Position; ACode := Codes[ADir in [nLeft, nTop]]; if ACode = scLineDown then ANewPos := APos + FIncrement else ANewPos := APos - FIncrement; if ANewPos < AMin then ANewPos := AMin else if ANewPos > AMax then ANewPos := AMax; if ANewPos <> APos then Control.Controller.Scroll(AKind, ACode, ANewPos); end; end; end; var I: TcxNeighbor; begin if not FBoundsMode then inherited DoScrollInspectingControl else for I := nLeft to nBottom do if I in FDirections then CheckDirection(I); end; function TcxControllerAutoScrollingObject.GetControl: TcxEditingControl; begin Result := TcxCustomControlController(FOwner).EditingControl; end; { TcxPlaceArrows } constructor TcxPlaceArrows.CreateArrows( AColor: TColor; ABorderColor: TColor = clDefault); begin inherited Create(); FBorderColor := ABorderColor; FColor := AColor; {$IFDEF DELPHI6} AlphaBlend := False; {$ENDIF} end; function TcxPlaceArrows.MoveTo(ARect: TRect; ASide: TcxBorder): Boolean; var R: TRect; ARgn: HRGN; begin HandleNeeded; Result := not EqualRect(ARect, FPrevRect) or (ASide <> FPrevSide) or not Visible; if Result then begin Hide; FPrevRect := ARect; FPrevSide := ASide; ARgn := CreateArrowsRgns(ARect, ASide); GetRgnBox(ARgn, R); SetBounds(R.Left, R.Top, R.Right - R.Left, R.Bottom - R.Top); OffsetRect(ARect, -R.Left, -R.Top); OffsetRgn(ARgn, -R.Left, -R.Top); cxDrawArrows(Canvas.Canvas, ARect, ASide, Color, BorderColor); WindowRegion := ARgn; Show; end; end; function TcxPlaceArrows.CreateArrowsRgns(const ARect: TRect; ASide: TcxBorder): HRGN; var ArrowRgns: array[0..1, 0..6, 0..1] of Integer; BaseLine: array[0..1, 0..1] of Integer; I, J, K: Integer; ArrowRgn: HRGN; const BaseRgns: array[0..3, 0..6, 0..1] of Integer = (((0, 0), (-5, -6), (-2, -6), (-2, -9), (3, -9), (3, -6), (6, -6)), ((0, -1), (6, 6), (3, 6), (3, 9), (-2, 9), (-2, 6), (-6, 6)), ((0, 0), (-6, -6), (-6, -2), (-9, -2), (-9, 3), (-6, 3), (-6, 6)), ((0, 0), (6, 6), (6, 3), (9, 3), (9, -2), (6, -2), (6, -6))); begin with ARect do begin BaseLine[0, 0] := Left; BaseLine[0, 1] := Top; BaseLine[1, 0] := Right; BaseLine[1, 1] := Bottom; end; if ASide in [bLeft, bBottom] then begin BaseLine[Byte(ASide = bLeft), 0] := ARect.Left; BaseLine[Byte(ASide = bLeft), 1] := ARect.Bottom; end else begin BaseLine[Byte(ASide = bTop), 0] := ARect.Right; BaseLine[Byte(ASide = bTop), 1] := ARect.Top; end; Move(BaseRgns[Byte(ASide in [bTop, bBottom]) shl 1], ArrowRgns, SizeOf(ArrowRgns)); for I := 0 to 1 do for J := 0 to 6 do for K := 0 to 1 do Inc(ArrowRgns[I, J, K], BaseLine[I, K]); Result := CreateRectRgn(0, 0, 0, 0); for I := 0 to 1 do begin ArrowRgn := CreatePolygonRgn(ArrowRgns[I], Length(ArrowRgns[I]), ALTERNATE); CombineRgn(Result, Result, ArrowRgn, RGN_OR); DeleteObject(ArrowRgn); end; end; procedure TcxPlaceArrows.SetWindowRegion(ARegion: HRGN); begin if FWindowRegion <> 0 then DeleteObject(FWindowRegion); FWindowRegion := ARegion; if ARegion <> 0 then SetWindowRgn(Handle, ARegion, False); end; { TcxBaseDragAndDropObject } function TcxBaseDragAndDropObject.GetDragAndDropCursor( Accepted: Boolean): TCursor; begin if Accepted then Result := EditingControl.DragCursor else Result := crNoDrop; end; function TcxBaseDragAndDropObject.GetEditingControl: TcxEditingControl; begin Result := TcxEditingControl(Control); end; { TcxCustomControlDragAndDropObject } constructor TcxCustomControlDragAndDropObject.Create(AControl: TcxControl); begin inherited Create(AControl); FAutoScrollObjects := TList.Create; end; destructor TcxCustomControlDragAndDropObject.Destroy; var I: Integer; begin for I := 0 to FAutoScrollObjects.Count - 1 do TObject(FAutoScrollObjects.List^[I]).Free; FAutoScrollObjects.Free; FDragImage.Free; inherited Destroy; end; procedure TcxCustomControlDragAndDropObject.AddAutoScrollingObject( const ARect: TRect; AKind: TScrollBarKind; ACode: TScrollCode); var AObj: TcxAutoScrollingObject; begin AObj := GetAutoScrollingObjectClass.Create(Self); if AKind = sbHorizontal then AObj.SetParams(ARect, AKind, ACode, GetHorzScrollInc) else AObj.SetParams(ARect, AKind, ACode, GetVertScrollInc); FAutoScrollObjects.Add(AObj); end; procedure TcxCustomControlDragAndDropObject.BeginDragAndDrop; begin inherited BeginDragAndDrop; DrawDragImage; end; procedure TcxCustomControlDragAndDropObject.DragAndDrop(const P: TPoint; var Accepted: Boolean); var R: TRect; begin inherited DragAndDrop(P, Accepted); R := cxRectOffset(PictureSize, [OrgOffset, HotSpot, CurMousePos]); DrawImage(R.TopLeft); //lcm if not CheckScrolling(P) then; // Accepted := cxRectPtIn(GetAcceptedRect, P); FCanDrop := Accepted; end; procedure TcxCustomControlDragAndDropObject.DrawDragImage; var AOrg: TRect; ASaveCanvas: TcxCanvas; begin AOrg := DisplayRect; with AOrg do FPictureSize := Rect(0, 0, Right - Left, Bottom - Top); FDragImage := TcxDragImage.Create; FDragImage.SetBounds(0, 0, FPictureSize.Right, FPictureSize.Bottom); FHotSpot.X := AOrg.Left - CurMousePos.X; FHotSpot.Y := AOrg.Top - CurMousePos.Y; cxSetCanvasOrg(FDragImage.Canvas.Canvas, AOrg); FOrgOffset := Control.ClientToScreen(FOrgOffset); ASaveCanvas := TcxEditingControl(Control).Painter.FCanvas; TcxEditingControl(Control).Painter.FCanvas := FDragImage.Canvas; try Paint; finally TcxEditingControl(Control).Painter.FCanvas := ASaveCanvas; cxSetCanvasOrg(FDragImage.Canvas.Canvas, AOrg); end; end; procedure TcxCustomControlDragAndDropObject.DrawImage( const APoint: TPoint); begin DragImage.MoveTo(APoint); DragImage.Show; end; procedure TcxCustomControlDragAndDropObject.EndDragAndDrop( Accepted: Boolean); begin StopScrolling; inherited EndDragAndDrop(Accepted); end; function TcxCustomControlDragAndDropObject.GetAcceptedRect: TRect; begin Result := cxNullRect; end; function TcxCustomControlDragAndDropObject.GetAutoScrollingObjectClass: TcxAutoScrollingObjectClass; begin Result := TcxDragDropObjectAutoScrollingObject; end; function TcxCustomControlDragAndDropObject.GetDisplayRect: TRect; begin cxAbstractError; end; function TcxCustomControlDragAndDropObject.GetDragAndDropCursor( Accepted: Boolean): TCursor; const DragCursors: array[Boolean] of TCursor = (crcxNoDrop, crDefault); begin Result := DragCursors[Accepted]; end; function TcxCustomControlDragAndDropObject.GetHorzScrollInc: Integer; begin Result := 1; end; function TcxCustomControlDragAndDropObject.GetVertScrollInc: Integer; begin Result := 1; end; procedure TcxCustomControlDragAndDropObject.OwnerImageChanged; begin DrawImage(cxPointOffset(cxPointOffset(CurMousePos, FOrgOffset), HotSpot)); end; procedure TcxCustomControlDragAndDropObject.OwnerImageChanging; begin end; procedure TcxCustomControlDragAndDropObject.Paint; begin cxAbstractError; end; procedure TcxCustomControlDragAndDropObject.StopScrolling; var I: Integer; begin for I := 0 to AutoScrollObjectCount - 1 do AutoScrollObjects[I].Stop; end; function TcxCustomControlDragAndDropObject.CheckScrolling( const P: TPoint): Boolean; var I: Integer; begin Result := False; for I := 0 to AutoScrollObjectCount - 1 do Result := Result or AutoScrollObjects[I].Check(P); end; function TcxCustomControlDragAndDropObject.GetAutoScrollObject( Index: Integer): TcxAutoScrollingObject; begin Result := TcxAutoScrollingObject(FAutoScrollObjects[Index]); end; function TcxCustomControlDragAndDropObject.GetAutoScrollObjectCount: Integer; begin Result := FAutoScrollObjects.Count; end; function TcxCustomControlDragAndDropObject.GetCanvas: TcxCanvas; begin Result := TcxEditingControl(Control).Painter.FCanvas; end; function TcxCustomControlDragAndDropObject.GetHitTestController: TcxCustomHitTestController; begin Result := TcxEditingControl(Control).Controller.HitTestController; end; constructor TcxDragImageHelper.Create(AControl: TcxEditingControl; ADragPos: TPoint); begin FDragControl := AControl; FDragPos := ADragPos; InitDragImage; end; destructor TcxDragImageHelper.Destroy; begin if DragImageVisible then Hide; FreeAndNil(DragImage); inherited Destroy; end; procedure TcxDragImageHelper.Hide; begin FDragImageVisible := False; DragImage.Hide; end; procedure TcxDragImageHelper.Show; begin FDragImageVisible := True; DrawImage(MousePos); DragImage.Show; end; procedure TcxDragImageHelper.DragAndDrop(const P: TPoint); var R: TRect; begin R := cxRectOffset(DragPictureBounds, [HotSpot, P]); MousePos := R.TopLeft; DrawImage(MousePos); end; function TcxDragImageHelper.GetDisplayRect: TRect; begin Result := DragControl.DragDropImageDisplayRect; end; procedure TcxDragImageHelper.InitDragImage; begin DragPictureBounds := GetDisplayRect; HotSpot := DragPictureBounds.TopLeft; DragPictureBounds := cxRectOffset(DragPictureBounds, cxPointInvert(HotSpot)); with FDragPos do HotSpot := cxPoint(HotSpot.X - X, HotSpot.Y - Y); DragImage := TcxDragImage.Create; with cxRectSize(DragPictureBounds) do DragImage.SetBounds(0, 0, Cx, Cy); DragControl.DrawDragDropImage(DragImage.Image, DragImage.Canvas); end; procedure TcxDragImageHelper.DrawImage( const APoint: TPoint); begin DragImage.MoveTo(APoint); if not DragImage.Visible then DragImage.Show; end; function TcxDragImageHelper.GetImageRect: TRect; begin Result := cxRectOffset(DragPictureBounds, MousePos) end; procedure TcxDragImageHelper.SetDragImageVisible(Value: Boolean); begin if Value <> FDragImageVisible then begin FDragImageVisible := Value; if Value then Show else Hide; end; end; { TcxCustomHitTestController } constructor TcxCustomHitTestController.Create(AOwner: TcxCustomControlController); begin FController := AOwner; FHitPoint := cxInvalidPoint; end; destructor TcxCustomHitTestController.Destroy; begin end; procedure TcxCustomHitTestController.ReCalculate; begin Recalculate(FHitPoint); end; procedure TcxCustomHitTestController.ReCalculate(const APoint: TPoint); begin ClearState; if Control.IsLocked then Exit; FHitPoint := APoint; ViewInfo.ValidateDirty; DoCalculate; end; function TcxCustomHitTestController.AllowDesignMouseEvents( X, Y: Integer; AShift: TShiftState): Boolean; begin RecalculateOnMouseEvent(X, Y, AShift); Result := False; end; function TcxCustomHitTestController.CanShowHint(AItem: TObject): Boolean; begin Result := Control.Options.OptionsBehavior.CellHints; end; procedure TcxCustomHitTestController.ClearState; begin FHitState := FHitState and echc_IsMouseEvent; end; procedure TcxCustomHitTestController.DestroyingItem(AItem: TObject); begin if FHitTestItem = AItem then begin FHitTestItem := nil; ClearState; Controller.HotTrackController.CheckDestroyingElement(AItem); end; end; procedure TcxCustomHitTestController.DoCalculate; var I: Integer; AItem: TcxEditCellViewInfo; begin with ViewInfo do for I := 0 to FEditCellViewInfoList.Count - 1 do begin AItem := FEditCellViewInfoList.List^[I]; if AItem.Visible and cxRectPtIn(AItem.ClipRect, HitPoint) then begin HitTestItem := AItem; Exit; end; end; HitTestItem := nil; end; function TcxCustomHitTestController.GetCurrentCursor: TCursor; begin Result := crDefault; end; procedure TcxCustomHitTestController.HitCodeChanged(APrevCode: Integer); begin end; procedure TcxCustomHitTestController.HitTestItemChanged(APrevHitTestItem: TObject); begin end; procedure TcxCustomHitTestController.RecalculateOnMouseEvent(X, Y: Integer; AShift: TShiftState); begin FShift := AShift; IsMouseEvent := True; try ReCalculate(cxPoint(X, Y)); finally IsMouseEvent := False; end; end; function TcxCustomHitTestController.GetControl: TcxEditingControl; begin Result := Controller.EditingControl; end; function TcxCustomHitTestController.GetCoordinate(AIndex: Integer): Integer; begin Result := PIntArray(@FHitPoint)^[AIndex]; end; function TcxCustomHitTestController.GetEditCellViewInfo: TcxEditCellViewInfo; begin if IsItemEditCell then Result := TcxEditCellViewInfo(FHitTestItem) else Result := nil; end; function TcxCustomHitTestController.GetHasCode(Mask: TcxHitCode): Boolean; begin Result := FHitState and Mask <> 0; end; function TcxCustomHitTestController.GetHotTrackController: TcxHotTrackController; begin Result := FController.HotTrackController; end; function TcxCustomHitTestController.GetIsItemEditCell: Boolean; begin Result := FHitTestItem is TcxEditCellViewInfo; end; function TcxCustomHitTestController.GetIsMouseEvent: Boolean; begin Result := FHitState and echc_IsMouseEvent <> 0; end; function TcxCustomHitTestController.GetViewInfo: TcxCustomControlViewInfo; begin Result := Control.ViewInfo; end; procedure TcxCustomHitTestController.SetCoordinate(AIndex: Integer; Value: Integer); begin PIntArray(@FHitPoint)^[AIndex] := Value; Recalculate; end; procedure TcxCustomHitTestController.SetHasCode(ACode: TcxHitCode; AValue: Boolean); var APrevState: TcxHitCode; begin if (FHitState and ACode <> 0) <> AValue then begin APrevState := FHitState; if AValue then FHitState := FHitState or ACode else FHitState := FHitState and not ACode; HitCodeChanged(APrevState); end; end; procedure TcxCustomHitTestController.SetHitPoint(const APoint: TPoint); begin Recalculate(APoint); end; procedure TcxCustomHitTestController.SetHitTestItem(AItem: TObject); var APrevItem: TObject; begin APrevItem := FHitTestItem; FHitTestItem := AItem; if IsMouseEvent then with Controller.HotTrackController do begin ShowHint := Self.CanShowHint(AItem); SetHotElement(AItem, HitPoint); end; if APrevItem <> AItem then HitTestItemChanged(APrevItem); end; procedure TcxCustomHitTestController.SetIsMouseEvent(Value: Boolean); begin if Value then FHitState := FHitState or echc_IsMouseEvent else FHitState := FHitState and not echc_IsMouseEvent; end; { TcxCustomCellNavigator } constructor TcxCustomCellNavigator.Create(AController: TcxCustomControlController); begin FController := AController; end; procedure TcxCustomCellNavigator.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 not IsValidCellIndex(Count[ARowIndex]) then begin ACellIndex := APrevCellIndex; ARowIndex := APrevRowIndex; end; if (ARowIndex <> APrevRowIndex) or (ACellIndex <> APrevCellIndex) then SetFocusCell(ARowIndex, ACellIndex, AShift); end; procedure TcxCustomCellNavigator.KeyDown(var Key: Word; Shift: TShiftState); begin case Key of VK_LEFT, VK_RIGHT: begin FocusNextCell(Key = VK_RIGHT, False, Shift); Key := 0; end; VK_TAB: begin FocusNextCell(not (ssShift in Shift), DownOnTab, Shift); Key := 0; end; VK_RETURN, VK_F2: if (Controller.FocusedItem <> nil) and (Shift = []) then begin Controller.FocusedItem.Editing := True; if Controller.FocusedItem.Editing then Key := 0; end; VK_UP, VK_DOWN: begin FocusNextCell(Key = VK_DOWN, True, Shift); Key := 0; end; end; end; procedure TcxCustomCellNavigator.KeyPress(var Key: Char); begin if IsEditStartChar(Key) and (Controller.FocusedItem <> nil) then begin Controller.EditingController.ShowEdit(Controller.FocusedItem, Key); Key := #0; end; end; procedure TcxCustomCellNavigator.Refresh; begin // todo: msn !!! need synchronize focused cell and row {Init(ARowIndex, ACellIndex, ARowCount); SetFocusCell(ARowIndex, ACellIndex);} end; function TcxCustomCellNavigator.SelectCell(AForward, ANextRow: Boolean; var ARowIndex, ACellIndex: Integer): TcxCustomInplaceEditContainer; var ACurRow, ACurCell, ARow: Integer; AItemFound: Boolean; begin Result := nil; ACurRow := ARowIndex; ACurCell := ACellIndex; repeat AItemFound := False; while not AItemFound do begin Result := GetCellContainer(ACurRow, ACurCell); AItemFound := (Result = nil) or Result.CanFocus and Result.CanTabStop; if not AItemFound then Inc(ACurCell, cxIntOffs[AForward]); end; if Result = nil then begin ACurCell := ACellIndex; ARow := ACurRow; if Controller.GetFocusCellOnCycle and not ANextRow then CalcNextRow(AForward, ACurRow, ACurCell); if (ARow <> ACurRow) and not ((Count[ACurRow] = 0) and MayFocusedEmptyRow(ACurRow)) then ACurCell := cxSetValue(AForward, 0, Count[ACurRow] - 1) else break; end else if MayFocusedEmptyRow(ARowIndex) then break; until Result <> nil; ARowIndex := ACurRow; ACellIndex := ACurCell; end; procedure TcxCustomCellNavigator.CalcNextRow(AForward: Boolean; var ARowIndex, ACellIndex: Integer); begin cxAbstractError; end; function TcxCustomCellNavigator.GetCellContainer( ARowIndex, ACellIndex: Integer): TcxCustomInplaceEditContainer; begin Result := nil; cxAbstractError; end; function TcxCustomCellNavigator.GetCount(ARowIndex: Integer): Integer; begin Result := -1; cxAbstractError; end; procedure TcxCustomCellNavigator.Init( var ARowIndex, ACellIndex, ARowCount: Integer); begin cxAbstractError; end; function TcxCustomCellNavigator.MayFocusedEmptyRow(ARowIndex: Integer): Boolean; begin Result := False end; procedure TcxCustomCellNavigator.SetFocusCell( ARowIndex, ACellIndex: Integer; AShift: TShiftState); begin cxAbstractError; end; procedure TcxCustomCellNavigator.DoKeyPress(var Key: Char); begin if FEatKeyPress then FEatKeyPress := False else KeyPress(Key); end; function TcxCustomCellNavigator.GetDataController: TcxCustomDataController; begin Result := FController.DataController; end; { TcxCustomDesignSelectionHelper } constructor TcxCustomDesignSelectionHelper.Create(AControl: TcxEditingControl); begin inherited Create; FControl := AControl; end; function TcxCustomDesignSelectionHelper.GetController: TcxCustomControlController; begin Result := FControl.Controller; end; { TcxCustomControlController } constructor TcxCustomControlController.Create(AOwner: TcxEditingControl); begin inherited Create; FEditingControl := AOwner; FAllowCheckEdit := True; with EditingControl do begin FEditingController := GetEditingControllerClass.Create(Self); FHitTestController := GetHitTestControllerClass.Create(Self); FHotTrackController := GetHotTrackControllerClass.Create(FEditingControl); end; FNavigator := GetNavigatorClass.Create(Self); end; destructor TcxCustomControlController.Destroy; begin FNavigator.Free; FEditingController.Free; FHotTrackController.Free; FHitTestController.Free; inherited Destroy; end; procedure TcxCustomControlController.Clear; begin HitTestController.ClearState; HotTrackController.Clear; end; procedure TcxCustomControlController.DblClick; begin end; function TcxCustomControlController.GetCursor(X, Y: Integer): TCursor; begin Result := crDefault; end; procedure TcxCustomControlController.KeyDown(var Key: Word; Shift: TShiftState); begin if not BlockRecordKeyboardHandling then begin if IsIncSearching then Key := IncSearchKeyDown(Key, Shift); FNavigator.KeyDown(Key, Shift); end; case Key of VK_ESCAPE: EditingControl.DataController.Cancel; VK_RETURN: if GetGoToNextCellOnEnter and ((Shift = []) or (Shift = [ssShift])) then Navigator.FocusNextCell(Shift = [], Navigator.DownOnEnter, Shift); VK_TAB: if GetGoToNextCellOnTab and ((Shift = []) or (Shift = [ssShift])) then begin Navigator.FocusNextCell(Shift = [], Navigator.DownOnTab, Shift); Key := 0; end; VK_PRIOR, VK_NEXT: DoNextPage(Key = VK_NEXT, Shift); end; end; procedure TcxCustomControlController.KeyPress(var Key: Char); begin if FEatKeyPress then begin FEatKeyPress := False; Exit; end; if IsIncSearchStartChar(Key) and (ItemForIncSearching <> nil) and ItemForIncSearching.CanIncSearch and (DataController.EditState * [dceInsert, dceEdit] = []) then begin if Key <> #8 then IncSearchingText := IncSearchingText + Key; Key := #0; end; FNavigator.DoKeyPress(Key); end; procedure TcxCustomControlController.KeyUp(var Key: Word; Shift: TShiftState); begin end; procedure TcxCustomControlController.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin end; procedure TcxCustomControlController.MouseMove( Shift: TShiftState; X, Y: Integer); begin end; procedure TcxCustomControlController.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin end; procedure TcxCustomControlController.Reset; begin EditingController.PostEditUpdate; FHitTestController.ClearState; FHitTestController.FHitTestItem := nil; FHotTrackController.Clear; end; procedure TcxCustomControlController.WndProc(var Message: TMessage); begin case Message.Msg of WM_IME_STARTCOMPOSITION: EditingController.ShowEdit; end; end; // drag'n'drop procedure TcxCustomControlController.BeginDragAndDrop; begin EditingController.HideEdit(True); end; procedure TcxCustomControlController.DragAndDrop(const P: TPoint; var Accepted: Boolean); begin end; procedure TcxCustomControlController.EndDragAndDrop(Accepted: Boolean); begin if EditingControl.DragAndDropState = ddsNone then CheckEdit; end; function TcxCustomControlController.StartDragAndDrop( const P: TPoint): Boolean; begin Result := False; end; procedure TcxCustomControlController.MouseEnter; begin HitTestController.ReCalculate; end; procedure TcxCustomControlController.MouseLeave; begin HideHint; HitTestController.IsMouseEvent := True; HitTestController.HitTestItem := nil; HitTestController.IsMouseEvent := False; end; procedure TcxCustomControlController.DoCancelMode; begin FocusChanged; end; procedure TcxCustomControlController.AfterPaint; begin with EditingControl do begin if DragAndDropState = ddsInProcess then if DragAndDropObject is TcxCustomControlDragAndDropObject then TcxCustomControlDragAndDropObject(DragAndDropObject).OwnerImageChanged; end; ProcessCheckEditPost; end; procedure TcxCustomControlController.BeforeEditKeyDown(var Key: Word; var Shift: TShiftState); begin end; procedure TcxCustomControlController.BeforeMouseDown( Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin FEditingBeforeDrag := IsEditing; end; procedure TcxCustomControlController.BeforePaint; begin with EditingControl do begin EditingController.CheckEditUpdatePost; if DragAndDropState = ddsInProcess then if DragAndDropObject is TcxCustomControlDragAndDropObject then TcxCustomControlDragAndDropObject(DragAndDropObject).OwnerImageChanging; end; end; procedure TcxCustomControlController.BeforeShowEdit; begin end; procedure TcxCustomControlController.BehaviorChanged; begin EditingControl.ViewInfo.UpdateSelection; end; procedure TcxCustomControlController.CancelCheckEditPost; begin FCheckEditNeeded := False; end; function TcxCustomControlController.CanFocusedRecordIndex( AIndex: Integer): Boolean; begin Result := True; end; procedure TcxCustomControlController.CancelIncSearching; var AItem: TcxCustomInplaceEditContainer; begin AItem := ItemForIncSearching; DataController.Search.Cancel; if (AItem <> nil) and (AItem.FocusedCellViewInfo <> nil) then AItem.FocusedCellViewInfo.Refresh(True); end; function TcxCustomControlController.GetIncSearchingItem: TcxCustomInplaceEditContainer; begin if IsIncSearching then Result := TcxCustomInplaceEditContainer(EditingControl.ContainerList[DataController.Search.ItemIndex]) else Result := nil; end; function TcxCustomControlController.GetIncSearchingText: string; begin Result := DataController.Search.SearchText; end; function TcxCustomControlController.GetIsIncSearching: Boolean; begin Result := DataController.Search.Searching end; procedure TcxCustomControlController.SearchLocate( AItem: TcxCustomInplaceEditContainer; const Value: string); begin DataController.Search.Locate(AItem.ItemIndex, Value); end; procedure TcxCustomControlController.SearchLocateNext( AItem: TcxCustomInplaceEditContainer; AForward: Boolean); begin DataController.Search.LocateNext(AForward); end; procedure TcxCustomControlController.UpdateRecord(ARecordIndex: Integer); begin EditingController.UpdateEditValue; end; procedure TcxCustomControlController.ViewInfoChanged; begin HitTestController.FHitTestItem := nil; HotTrackController.SetHotElement(nil, HitTestController.HitPoint); end; procedure TcxCustomControlController.CheckEdit; begin CancelCheckEditPost; if FAllowCheckEdit and GetAlwaysShowEditor then FEditingController.ShowEdit; end; procedure TcxCustomControlController.DoEditDblClick(Sender: TObject); begin EditingControl.DblClick; end; procedure TcxCustomControlController.DoMouseDown( Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var APrevFocusedRecord: Integer; APrevFocusedItem: TcxCustomInplaceEditContainer; APrevEditViewInfo, AEditViewInfo: TcxEditCellViewInfo; AButtonClick: Boolean; procedure DoShowEdit; begin if Button <> mbLeft then Exit; with FEditingController, AEditViewInfo do begin if AButtonClick then ShowEdit(EditContainer, Shift, X, Y) else ShowEdit(EditContainer, [], -1, -1) end; end; begin APrevFocusedRecord := FocusedRecordIndex; APrevFocusedItem := FocusedItem; FIsDblClick := ssDouble in Shift; FWasFocusedBeforeClick := False; EditingController.StopEditShowingTimer; with HitTestController do begin AButtonClick := HitTestController.IsItemEditCell and EditCellViewInfo.ViewInfo.IsHotTrack(Point(X, Y)) {and (EditingControl.DragMode = dmManual)}; if AButtonClick then APrevEditViewInfo := EditCellViewInfo else APrevEditViewInfo := nil; end; MouseDown(Button, Shift, X, Y); HitTestController.RecalculateOnMouseEvent(X, Y, Shift); if (Button <> mbMiddle) and HitTestController.IsItemEditCell then begin AEditViewInfo := HitTestController.EditCellViewInfo; SetFocusedRecordItem(AEditViewInfo.RecordIndex, AEditViewInfo.EditContainer); HitTestController.RecalculateOnMouseEvent(X, Y, Shift); if HitTestController.IsItemEditCell then begin AEditViewInfo := HitTestController.EditCellViewInfo; if GetImmediateEditor then DoShowEdit else begin if AButtonClick and (AEditViewInfo = APrevEditViewInfo) then DoShowEdit else begin FWasFocusedBeforeClick := (APrevFocusedRecord = FocusedRecordIndex) and (APrevFocusedItem = FocusedItem) and (FocusedItem <> nil); if not FWasFocusedBeforeClick and (FocusedItem <> nil) then FocusedItem.CancelIncSearching; end; end; end; end; end; procedure TcxCustomControlController.DoMouseMove( Shift: TShiftState; X, Y: Integer); begin MouseMove(Shift, X, Y); HitTestController.RecalculateOnMouseEvent(X, Y, Shift); end; procedure TcxCustomControlController.DoMouseUp( Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin MouseUp(Button, Shift, X, Y); if WasFocusedBeforeClick then begin with HitTestController do if not IsEditing and not IsDblClick and IsItemEditCell and (Button = mbLeft) then FEditingController.StartEditShowingTimer(EditCellViewInfo.EditContainer); end; HitTestController.RecalculateOnMouseEvent(X, Y, Shift); with HitTestController do if not IsEditing and not IsDblClick and IsItemEditCell and GetImmediateEditor then begin FEditingController.StopEditShowingTimer; if Button = mbLeft then FEditingController.ShowEdit(EditCellViewInfo.EditContainer) end end; procedure TcxCustomControlController.DoNextPage(AForward: Boolean; Shift: TShiftState); begin end; function TcxCustomControlController.GetEditingViewInfo: TcxEditCellViewInfo; begin Result := GetFocusedCellViewInfo(EditingItem); end; function TcxCustomControlController.GetFocused: Boolean; begin Result := FFocused; end; function TcxCustomControlController.GetFocusedCellViewInfo( AEditContainer: TcxCustomInplaceEditContainer): TcxEditCellViewInfo; begin Result := nil; cxAbstractError; end; function TcxCustomControlController.GetFocusedRecordIndex: Integer; begin Result := EditingControl.DataController.GetFocusedRecordIndex; end; function TcxCustomControlController.GetResizeDirection: TcxDragSizingDirection; begin Result := dsdHorz; end; procedure TcxCustomControlController.FocusedItemChanged( APrevFocusedItem: TcxCustomInplaceEditContainer); procedure RefreshCells(APrevViewInfo, ACurViewInfo: TcxEditCellViewInfo); begin if (APrevViewInfo = ACurViewInfo) or DisableCellsRefresh then Exit; if APrevViewInfo <> nil then APrevViewInfo.Refresh(False); if ACurViewInfo <> nil then ACurViewInfo.Refresh(False); end; begin if EditingControl.ComponentState * [csLoading, csDestroying] <> [] then Exit; CancelIncSearching; MakeFocusedItemVisible; RefreshCells(GetFocusedCellViewInfo(APrevFocusedItem), GetFocusedCellViewInfo(FocusedItem)); Navigator.Refresh; end; procedure TcxCustomControlController.FocusedRecordChanged( APrevFocusedRecordIndex, AFocusedRecordIndex: Integer); begin with EditingController do if HideEditOnFocusedRecordChange then HideEdit(True); CheckEdit; EditingController.UpdateEditValue; end; function TcxCustomControlController.HasFocusedControls: Boolean; begin with FEditingController do Result := (Edit <> nil) and Edit.IsFocused; end; procedure TcxCustomControlController.HideHint; begin HotTrackController.CancelHint; end; function TcxCustomControlController.IncSearchKeyDown(AKey: Word; AShift: TShiftState): Word; begin if ItemForIncSearching = nil then begin Result := AKey; Exit; end else Result := 0; case AKey of VK_ESCAPE: ItemForIncSearching.CancelIncSearching; VK_BACK: IncSearchingText := Copy(IncSearchingText, 1, Length(IncSearchingText) - 1); VK_UP, VK_DOWN: if AShift = [ssCtrl] then SearchLocateNext(ItemForIncSearching, AKey = VK_DOWN) else Result := AKey; else Result := AKey; end; end; procedure TcxCustomControlController.InternalSetFocusedItem( Value: TcxCustomInplaceEditContainer); begin FFocusedItem := Value; end; function TcxCustomControlController.IsImmediatePost: Boolean; begin Result := False; end; function TcxCustomControlController.IsKeyForController( AKey: Word; AShift: TShiftState): Boolean; begin Result := ((AKey = VK_TAB) and GetGoToNextCellOnTab) or (AKey = VK_UP) or (AKey = VK_DOWN) or (AKey = VK_PRIOR) or (AKey = VK_NEXT) or (AKey = VK_INSERT) or (AKey = VK_ESCAPE) or (AKey = VK_LEFT) or (AKey = VK_RIGHT); end; procedure TcxCustomControlController.PostCheckEdit; begin if FAllowCheckEdit then FCheckEditNeeded := True; end; procedure TcxCustomControlController.ProcessCheckEditPost; begin if FCheckEditNeeded then CheckEdit; end; procedure TcxCustomControlController.PostShowEdit; begin with EditingControl.Options.OptionsBehavior do begin if not IsEditing and (ImmediateEditor or AlwaysShowEditor) and (EditingControl.DragAndDropState = ddsNone) then if HitTestController.IsItemEditCell then PostCheckEdit; end; end; procedure TcxCustomControlController.RefreshFocusedCellViewInfo( AItem: TcxCustomInplaceEditContainer); var ACellViewInfo: TcxEditCellViewInfo; begin if DisableCellsRefresh then Exit; ACellViewInfo := GetFocusedCellViewInfo(AItem); if (ACellViewInfo <> nil) and (ACellViewInfo.Refresh(True)) then EditingControl.LayoutChanged; end; procedure TcxCustomControlController.RefreshFocusedRecord; var I: Integer; ANeedUpdate: Boolean; ACellViewInfo: TcxEditCellViewInfo; begin with EditingControl do begin Inc(FLockUpdate); ANeedUpdate := False; try for I := 0 to FContainerList.Count - 1 do with TcxCustomInplaceEditContainer(FContainerList.List^[I]) do begin ACellViewInfo := FocusedCellViewInfo; ANeedUpdate := ANeedUpdate or ((ACellViewInfo <> nil) and ACellViewInfo.Refresh(True)); end; finally Dec(FLockUpdate); if ANeedUpdate and not IsLocked then begin BeforeUpdate; LayoutChanged; end; end; end; end; procedure TcxCustomControlController.SetFocused(Value: Boolean); begin FFocused := Value; end; procedure TcxCustomControlController.SetFocusedItem( Value: TcxCustomInplaceEditContainer); var APrevFocusedItem: TcxCustomInplaceEditContainer; begin if IsEditing then EditingController.HideEdit(True); if (Value <> nil) and not Value.CanFocus then Exit; if FFocusedItem <> Value then begin APrevFocusedItem := FFocusedItem; if (FFocusedItem <> nil) and not FEditingController.FEditingItemSetting then FEditingController.HideEdit(True); FFocusedItem := Value; FocusedItemChanged(APrevFocusedItem); end else if Assigned(Value) then MakeFocusedItemVisible; PostCheckEdit; end; procedure TcxCustomControlController.SetFocusedRecordIndex( Value: Integer); var AIndexesAreEqual: Boolean; begin with DataController do begin if cxInRange(Value, 0, RecordCount - 1) and not (CanFocusedRecordIndex(Value) and ChangeFocusedRowIndex(Value)) then Exit; end; AIndexesAreEqual := FocusedRecordIndex = Value; if AIndexesAreEqual then MakeFocusedRecordVisible; end; function TcxCustomControlController.GetAlwaysShowEditor: Boolean; begin Result := EditingControl.Options.OptionsBehavior.AlwaysShowEditor; end; function TcxCustomControlController.GetCancelEditingOnExit: Boolean; begin with EditingControl do Result := Options.OptionsData.CancelOnExit and (DataController.EditState * [dceInsert, dceChanging, dceModified] = [dceInsert]); end; function TcxCustomControlController.GetFocusCellOnCycle: Boolean; begin Result := EditingControl.Options.OptionsBehavior.FocusCellOnCycle; end; function TcxCustomControlController.GetGoToNextCellOnEnter: Boolean; begin Result := EditingControl.Options.OptionsBehavior.GoToNextCellOnEnter; end; function TcxCustomControlController.GetGoToNextCellOnTab: Boolean; begin Result := EditingControl.Options.OptionsBehavior.GoToNextCellOnTab; end; function TcxCustomControlController.GetImmediateEditor: Boolean; begin with EditingControl.Options.OptionsBehavior do Result := (ImmediateEditor or AlwaysShowEditor) and (EditingControl.DragMode = dmManual); end; procedure TcxCustomControlController.BeforeStartDrag; begin end; function TcxCustomControlController.CanDrag(X, Y: Integer): Boolean; begin Result := False; end; procedure TcxCustomControlController.DragDrop(Source: TObject; X, Y: Integer); begin end; procedure TcxCustomControlController.DragOver(Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); begin EditingController.HideEdit(True); end; procedure TcxCustomControlController.EndDrag(Target: TObject; X, Y: Integer); begin HitTestController.ReCalculate(Point(X, Y)); if FEditingBeforeDrag or EditingControl.Options.OptionsBehavior.AlwaysShowEditor then EditingController.ShowEdit; end; function TcxCustomControlController.GetDragAndDropObject: TcxCustomControlDragAndDropObject; begin Result := EditingControl.DragAndDropObject as TcxCustomControlDragAndDropObject; end; function TcxCustomControlController.GetDragAndDropObjectClass: TcxDragAndDropObjectClass; begin Result := nil; end; function TcxCustomControlController.GetIsDragging: Boolean; begin Result := False; end; function TcxCustomControlController.GetNavigatorClass: TcxCustomCellNavigatorClass; begin Result := TcxCustomCellNavigator; end; procedure TcxCustomControlController.StartDrag(var DragObject: TDragObject); begin end; function TcxCustomControlController.GetMouseWheelScrollingKind: TcxMouseWheelScrollingKind; begin Result := mwskNone; end; function TcxCustomControlController.IsPixelScrollBar( AKind: TScrollBarKind): Boolean; begin Result := False; end; procedure TcxCustomControlController.InitScrollBarsParameters; begin end; procedure TcxCustomControlController.Scroll(AScrollBarKind: TScrollBarKind; AScrollCode: TScrollCode; var AScrollPos: Integer); begin end; procedure TcxCustomControlController.SetFocusedRecordItem( ARecordIndex: Integer; AItem: TcxCustomInplaceEditContainer); begin EditingController.HideEdit(True); AllowCheckEdit := False; try DisableCellsRefresh := (FocusedRecordIndex = ARecordIndex); FocusedRecordIndex := ARecordIndex; DisableCellsRefresh := DisableCellsRefresh and (FocusedItem = AItem); FocusedItem := AItem; finally AllowCheckEdit := True; CheckEdit; DisableCellsRefresh := False; end; end; procedure TcxCustomControlController.SetScrollBarInfo( AScrollBarKind: TScrollBarKind; AMin, AMax, AStep, APage, APos: Integer; AAllowShow, AAllowHide: Boolean); begin EditingControl.SetScrollBarInfo(AScrollBarKind, AMin, AMax, AStep, APage, APos, AAllowShow, AAllowHide); end; procedure TcxCustomControlController.MakeFocusedItemVisible; begin cxAbstractError; end; procedure TcxCustomControlController.MakeFocusedRecordVisible; begin cxAbstractError; end; procedure TcxCustomControlController.FocusChanged; var AFocused: Boolean; begin AFocused := EditingControl.IsFocused; with EditingController do begin AFocused := AFocused or (IsEditing and (Edit <> nil) and Edit.Focused); if AFocused then begin CheckEdit; if IsEditing and (Edit <> nil) and GetAlwaysShowEditor and not Edit.Focused and Edit.CanFocus then Edit.SetFocus else if (Edit <> nil) and not Edit.Focused and not GetAlwaysShowEditor then HideEdit(True) else if GetAlwaysShowEditor and not IsEditing and GetImmediateEditor then ShowEdit; end; end; if FFocused <> AFocused then begin FFocused := AFocused; ControlFocusChanged; end; end; procedure TcxCustomControlController.DoEnter; begin end; procedure TcxCustomControlController.DoExit; begin if GetCancelEditingOnExit then EditingControl.DataController.Cancel else begin EditingControl.DataController.PostEditingData; if IsImmediatePost then EditingControl.DataController.Post; end; end; function TcxCustomControlController.MayFocus: Boolean; begin Result := not EditingControl.IsFocused or not IsEditing or not GetAlwaysShowEditor and FEditingController.Edit.ValidateEdit(True); end; procedure TcxCustomControlController.RemoveFocus; begin end; procedure TcxCustomControlController.SetFocus; begin if not FEditingController.CanRemoveEditFocus then Exit; with EditingControl do if CanFocusEx and IsFocused then SetFocus; PostCheckEdit; end; procedure TcxCustomControlController.ControlFocusChanged; begin with EditingController do if not Self.Focused and HideEditOnExit then HideEdit(True); EditingControl.ViewInfo.UpdateSelection; end; function TcxCustomControlController.GetDataController: TcxCustomDataController; begin Result := EditingControl.DataController; end; function TcxCustomControlController.GetDesignSelectionHelper: TcxCustomDesignSelectionHelper; begin Result := EditingControl.DesignSelectionHelper; end; function TcxCustomControlController.GetEditingItem: TcxCustomInplaceEditContainer; begin Result := FEditingController.EditingItem; end; function TcxCustomControlController.GetIsEditing: Boolean; begin Result := FEditingController.IsEditing; end; procedure TcxCustomControlController.SetEditingItem( Value: TcxCustomInplaceEditContainer); begin FEditingController.EditingItem := Value; end; function TcxCustomControlController.GetItemForIncSearching: TcxCustomInplaceEditContainer; begin Result := nil; if EditingControl.Options.OptionsBehavior.IncSearch then Result := EditingControl.Options.OptionsBehavior.IncSearchItem; if Result = nil then Result := FocusedItem; end; procedure TcxCustomControlController.SetIncSearchingText(const Value: string); var AItem: TcxCustomInplaceEditContainer; function GetItemIndex: Integer; begin AItem := nil; if IsIncSearching then AItem := IncSearchingItem else AItem := ItemForIncSearching; if AItem <> nil then Result := AItem.ItemIndex else Result := -1; end; begin if (IncSearchingText = Value) or (GetItemIndex = -1) then Exit; if Value = '' then CancelIncSearching else SearchLocate(AItem, Value); if (ItemForIncSearching <> nil) and (ItemForIncSearching.FocusedCellViewInfo <> nil) then ItemForIncSearching.FocusedCellViewInfo.Invalidate(True); end; { TcxCustomControlViewInfo } constructor TcxCustomControlViewInfo.Create(AOwner: TcxEditingControl); begin FControl := AOwner; FState := FState or cvis_StyleInvalid; CreatePainter; FEditCellViewInfoList := TList.Create; FEditCellViewInfoList.Capacity := 1024; Brush := TBrush.Create; SelectionBrush := TBrush.Create; end; destructor TcxCustomControlViewInfo.Destroy; begin with FControl do if Assigned(FController) then FController.Reset; FPainter.Free; FEditCellViewInfoList.Free; Brush.Free; SelectionBrush.Free; inherited Destroy; end; procedure TcxCustomControlViewInfo.Calculate; begin with Control.FBrushCache do begin BeginUpdate; try if State[cvis_StyleInvalid] then begin State[cvis_StyleInvalid] := False; CalculateDefaultHeights; ViewParams := Control.Styles.GetBackgroundParams; Brush.Color := ViewParams.Color; UpdateSelectionParams; Control.Invalidate; end; FClientRect := Control.ClientBounds; DoCalculate; IsDirty := False; finally EndUpdate; end; end; end; procedure TcxCustomControlViewInfo.Invalidate(ARecalculate: Boolean = False); begin if ARecalculate then Control.LayoutChanged else Control.InvalidateRectEx(ClientRect, False); end; procedure TcxCustomControlViewInfo.ValidateDirty; begin if IsDirty then Calculate; end; function TcxCustomControlViewInfo.AddEditCellViewInfo( AViewInfoClass: TcxEditCellViewInfoClass; AEditContainer: TcxCustomInplaceEditContainer): TcxEditCellViewInfo; begin Result := AViewInfoClass.Create(AEditContainer); FEditCellViewInfoList.Add(Result); IsDirty := True; end; function TcxCustomControlViewInfo.CalculateDefaultEditHeight: Integer; begin Result := -1; cxAbstractError; end; procedure TcxCustomControlViewInfo.CalculateDefaultHeights; begin FDefaultEditHeight := CalculateDefaultEditHeight; end; procedure TcxCustomControlViewInfo.ClearEditCellViewInfos; var I: Integer; begin for I := 0 to FEditCellViewInfoList.Count - 1 do TcxEditCellViewInfo(FEditCellViewInfoList.List^[I]).Free; FEditCellViewInfoList.Clear; IsDirty := True; end; procedure TcxCustomControlViewInfo.CreatePainter; begin FPainter := Control.GetPainterClass.Create(Control); end; procedure TcxCustomControlViewInfo.DoCalculate; var I: Integer; begin Control.Controller.ViewInfoChanged; for I := 0 to FEditCellViewInfoList.Count - 1 do with TcxEditCellViewInfo(FEditCellViewInfoList.List^[I]) do if Visible then DoCalculate; end; procedure TcxCustomControlViewInfo.RemoveEditCellViewInfo( AViewInfo: TcxEditCellViewInfo); begin FEditCellViewInfoList.Remove(AViewInfo); AViewInfo.Free; IsDirty := True; end; procedure TcxCustomControlViewInfo.UpdateSelection; begin UpdateSelectionParams; end; function TcxCustomControlViewInfo.GetLookAndFeelPainter: TcxCustomLookAndFeelPainterClass; begin Result := FPainter.Painter; end; function TcxCustomControlViewInfo.GetState(AMask: Integer): Boolean; begin Result := FState and AMask = AMask; end; procedure TcxCustomControlViewInfo.SetState(AMask: Integer; Value: Boolean); begin if Value then FState := FState or AMask else FState := FState and not AMask; end; procedure TcxCustomControlViewInfo.UpdateSelectionParams; begin SelectionParams := Control.Styles.GetSelectionParams; SelectionBrush.Color := SelectionParams.Color; end; { TcxCustomControlCells } procedure TcxCustomControlCells.BeforePaint; var I: Integer; begin for I := 0 to Count - 1 do Items[I].CheckVisibleInfo; end; function TcxCustomControlCells.CalculateHitTest( AHitTest: TcxCustomHitTestController): Boolean; var I: Integer; begin Result := False; for I := Count - 1 downto 0 do begin Result := Items[I].GetHitTest(AHitTest); if Result then Exit; end; end; procedure TcxCustomControlCells.DeleteAll; begin SetCount(0); end; procedure TcxCustomControlCells.ExcludeFromClipping(ACanvas: TcxCanvas); var I: Integer; begin for I := 0 to Count - 1 do Items[I].ExcludeFromPaint(ACanvas); end; procedure TcxCustomControlCells.Paint(ACanvas: TcxCanvas; AHandler: TcxCustomDrawCellEvent); procedure DoDrawItem(AItem: TcxCustomViewInfoItem); var ADone: Boolean; begin AItem.BeforeCustomDraw(ACanvas); AHandler(ACanvas, AItem, ADone); if not ADone then begin AItem.AfterCustomDraw(ACanvas); AItem.Draw(ACanvas); end; end; var I: Integer; AClipRgn: TcxRegion; AItem: TcxCustomViewInfoItem; begin for I := 0 to Count - 1 do begin AItem := Items[I]; AItem.CheckVisibleInfo; if (AItem.Visible and RectVisible(ACanvas.Handle, AItem.ClipRect)) then if AItem.HasClipping then begin AClipRgn := ACanvas.GetClipRegion; ACanvas.IntersectClipRect(AItem.ClipRect); DoDrawItem(AItem); ACanvas.SetClipRegion(AClipRgn, roSet); end else DoDrawItem(AItem); end; end; function TcxCustomControlCells.GetItem(AIndex: Integer): TcxCustomViewInfoItem; begin Result := TcxCustomViewInfoItem(List^[AIndex]); end; { TcxCustomViewInfoItem } constructor TcxCustomViewInfoItem.Create(AOwner: TObject); begin FOwner := AOwner; end; procedure TcxCustomViewInfoItem.Assign(Source: TcxCustomViewInfoItem); begin DisplayRect := Source.DisplayRect; ClipRect := Source.ClipRect; ItemVisible := Source.ItemVisible; ItemViewParams := Source.ItemViewParams; end; procedure TcxCustomViewInfoItem.CheckVisibleInfo; begin if Visible and not FVisibleInfoCalculated then begin DoCalculate; FVisibleInfoCalculated := True; end; end; class function TcxCustomViewInfoItem.CustomDrawID: Integer; begin Result := 0; end; procedure TcxCustomViewInfoItem.Draw(ACanvas: TcxCanvas); var FPrevCanvas: TcxCanvas; begin CheckVisibleInfo; FPrevCanvas := ControlCanvas; try ControlCanvas := ACanvas; DoDraw(ControlCanvas); finally ControlCanvas := FPrevCanvas; end; end; procedure TcxCustomViewInfoItem.Invalidate(ARecalculate: Boolean = False); begin if ARecalculate then DoCalculate; if Visible then Control.InvalidateRectEx(VisibleRect, False); end; procedure TcxCustomViewInfoItem.CheckClipping( const ADisplayRect: TRect); begin CheckClipping(ADisplayRect, ControlViewInfo.FClientRect); end; procedure TcxCustomViewInfoItem.DoCalculate; begin cxAbstractError; end; procedure TcxCustomViewInfoItem.DoDraw(ACanvas: TcxCanvas); begin if not Transparent then ACanvas.FillRect(ClipRect, ViewParams); end; procedure TcxCustomViewInfoItem.DoHorzOffset(AShift: Integer); begin cxAbstractError; end; procedure TcxCustomViewInfoItem.DoVertOffset(AShift: Integer); begin cxAbstractError; end; function TcxCustomViewInfoItem.DrawBackgroundHandler( ACanvas: TcxCanvas; const ABounds: TRect): Boolean; begin Result := (Bitmap <> nil) and not Bitmap.Empty; if Result and not Transparent then ACanvas.FillRect(ABounds, Bitmap) else Result := Transparent; end; function TcxCustomViewInfoItem.ExcludeFromPaint( ACanvas: TcxCanvas): Boolean; begin Result := Visible; if Result then ACanvas.ExcludeClipRect(ClipRect); end; function TcxCustomViewInfoItem.GetControl: TcxEditingControl; begin Result := nil; cxAbstractError; end; function TcxCustomViewInfoItem.GetHitTest( AHitTest: TcxCustomHitTestController): Boolean; begin Result := False; end; function TcxCustomViewInfoItem.IsTransparent: Boolean; begin with ItemViewParams do Result := (Bitmap <> nil) and not Bitmap.Empty; end; procedure TcxCustomViewInfoItem.Scroll(const DX, DY: Integer); begin if (DX = 0) and (DY = 0) then Exit; OffsetRect(DisplayRect, DX, DY); CheckClipping(DisplayRect, VisibleBounds); VisibleInfoCalculated := False; end; procedure TcxCustomViewInfoItem.UpdateEditRect; begin CheckClipping(DisplayRect); end; procedure TcxCustomViewInfoItem.AfterCustomDraw(ACanvas: TcxCanvas); begin ItemViewParams.Color := ACanvas.Brush.Color; ItemViewParams.TextColor := ACanvas.Font.Color; end; procedure TcxCustomViewInfoItem.BeforeCustomDraw(ACanvas: TcxCanvas); begin ACanvas.SetParams(ViewParams); end; procedure TcxCustomViewInfoItem.CheckClipping( const ADisplayRect, AAvailableRect: TRect); begin DisplayRect := ADisplayRect; VisibleBounds := AAvailableRect; ItemVisible := cxRectIntersect(ClipRect, AAvailableRect, DisplayRect); FHasClipping := not cxRectIsEqual(ClipRect, DisplayRect); end; function TcxCustomViewInfoItem.GetBitmap: TBitmap; begin Result := ViewParams.Bitmap; end; function TcxCustomViewInfoItem.GetControlViewInfo: TcxCustomControlViewInfo; begin Result := Control.ViewInfo; end; function TcxCustomViewInfoItem.GetPainter: TcxCustomLookAndFeelPainterClass; begin Result := Control.LookAndFeelPainter; end; { TcxEditCellViewInfo } destructor TcxEditCellViewInfo.Destroy; begin if (EditContainer <> nil) and not EditContainer.IsDestroying then Control.Controller.HitTestController.DestroyingItem(Self); ViewInfo.Free; if IsViewDataCreated then ViewData.Free; inherited Destroy; end; procedure TcxEditCellViewInfo.Assign(Source: TcxCustomViewInfoItem); begin if Source is TcxCustomViewInfoItem then begin CellEditRect := TcxEditCellViewInfo(Source).CellEditRect; CellContentRect := TcxEditCellViewInfo(Source).CellContentRect; CellBorders := TcxEditCellViewInfo(Source).CellBorders; end; inherited Assign(Source); end; function TcxEditCellViewInfo.QueryInterface(const IID: TGUID; out Obj): HResult; begin if GetInterface(IID, Obj) then Result := 0 else Result := cxE_NOINTERFACE; end; function TcxEditCellViewInfo.Refresh(ARecalculate: Boolean): Boolean; begin Result := False; if EditContainer = nil then Exit; if ARecalculate then begin if IsAutoHeight then Result := ChangedHeight(CellHeight, CalculateEditHeight); if not Result then DoCalculate; end else if ViewInfo <> nil then begin ItemViewParams := GetEditViewParams; ViewInfo.TextColor := ItemViewParams.TextColor; ViewInfo.Font := ItemViewParams.Font; ViewInfo.BackgroundColor := ItemViewParams.Color; ViewInfo.Transparent := IsTransparent; end; if not Result then Invalidate; end; function TcxEditCellViewInfo._AddRef: Integer; begin Result := -1; end; function TcxEditCellViewInfo._Release: Integer; begin Result := -1; end; function TcxEditCellViewInfo.GetOrigin: TPoint; begin Result := cxPoint(ViewInfo.Left, ViewInfo.Top); end; function TcxEditCellViewInfo.IsNeedHint(ACanvas: TcxCanvas; const P: TPoint; out AText: TCaption; out AIsMultiLine: Boolean; out ATextRect: TRect; var IsNeedOffsetHint: Boolean): Boolean; begin Result := Visible and ViewInfo.NeedShowHint(ACanvas, P, GetControl.ClientBounds, AText, AIsMultiLine, ATextRect); IsNeedOffsetHint := False; end; procedure TcxEditCellViewInfo.UpdateHotTrackState(const APoint: TPoint); var ATempViewInfo: TcxCustomEditViewInfo; begin if not IsSupportedHotTrack then Exit; ATempViewInfo := TcxCustomEditViewInfo(Properties.GetViewInfoClass.Create); try ATempViewInfo.Assign(ViewInfo); cxAssignEditStyle(Self); ViewData.ContentOffset := ContentOffset; ViewData.CalculateEx(EditContainer.GetControlCanvas, ContentRect, cxPointOffset(APoint, cxPointInvert(GetCellOrg)), cxmbNone, [], ViewInfo, False); if (EditContainer <> nil) and (EditContainer.EditingControl.DragAndDropState = ddsNone) then begin if ViewInfo.Repaint(Control, ATempViewInfo) and (Control.Painter.Buffered or ((GetCellOrg.X <> 0) or (GetCellOrg.Y <> 0))) then Control.InvalidateRectEx(cxRectOffset(ContentRect, GetCellOrg), False); end; finally ATempViewInfo.Free; end; end; function TcxEditCellViewInfo.CalculateEditHeight: Integer; begin if IsAutoHeight then begin with EditContainer do begin InitEditViewInfo(Self); Result := GetEditHeight(Self); end; end else Result := ControlViewInfo.DefaultEditHeight; end; function TcxEditCellViewInfo.CalculateEditWidth: Integer; begin Result := EditContainer.GetEditHeight(Self); end; function TcxEditCellViewInfo.ChangedHeight(APrevHeight, ANewHeight: Integer): Boolean; begin Result := APrevHeight <> ANewHeight; CellHeight := ANewHeight; end; procedure TcxEditCellViewInfo.CheckClipping( const ADisplayRect, AAvailableRect: TRect); begin inherited CheckClipping(ADisplayRect, AAvailableRect); CellContentRect := DisplayRect; if CellBorders = [] then with ContentOffset do CellEditRect := cxRectInflate(VisibleRect, -Left, -Top, -Right, -Bottom) else begin with CellContentRect do begin Inc(Left, Byte(bLeft in CellBorders)); Inc(Top, Byte(bTop in CellBorders)); Dec(Right, Byte(bRight in CellBorders)); Dec(Bottom, Byte(bBottom in CellBorders)); end; if cxRectIntersect(CellEditRect, VisibleRect, CellContentRect) then with ContentOffset do CellEditRect := cxRectInflate(CellEditRect, -Left, -Top, -Right, -Bottom); end; end; function TcxEditCellViewInfo.ContentOffset: TRect; begin Result := cxSimpleRect; end; function TcxEditCellViewInfo.CorrectHotTrackPoint( const APoint: TPoint): TPoint; begin Result := APoint; end; procedure TcxEditCellViewInfo.DoCalculate; begin with EditContainer do begin if not IsAutoHeight then InitEditViewInfo(Self) else begin ViewData.InplaceEditParams.Position.RecordIndex := RecordIndex; ViewData.InplaceEditParams.Position.Item := Self; end; CalculateEditViewInfo(CellValue, Self, cxInvalidPoint); end; end; function TcxEditCellViewInfo.GetButtonTransparency: TcxEditButtonTransparency; var B1: TcxEditingControlEditShowButtons; B2: TcxEditItemShowEditButtons; begin B1 := Control.Options.OptionsView.ShowEditButtons; B2 := EditContainer.Options.ShowEditButtons; if (B2 = eisbAlways) or (B2 = eisbDefault) and ((B1 = ecsbAlways) or (B1 = ecsbFocused) and Focused) then Result := ebtNone else Result := ebtHideInactive; end; function TcxEditCellViewInfo.GetCellOrg: TPoint; begin Result := cxNullPoint; end; function TcxEditCellViewInfo.GetControl: TcxEditingControl; begin if EditContainer = nil then Result := nil else Result := EditContainer.EditingControl; end; function TcxEditCellViewInfo.GetDisplayValue: Variant; begin with EditContainer.DataController do begin if (RecordIndex >= 0) and (RecordIndex < RecordCount) then Result := EditContainer.GetDisplayValue(Properties, RecordIndex) else Result := Null end; end; function TcxEditCellViewInfo.GetEditContainer: TcxCustomInplaceEditContainer; begin Result := TcxCustomInplaceEditContainer(Owner); end; function TcxEditCellViewInfo.GetEditRect: TRect; begin Result := CellEditRect; end; function TcxEditCellViewInfo.GetEditViewParams: TcxViewParams; begin Result := Control.Styles.GetBackgroundParams; end; function TcxEditCellViewInfo.GetFocused: Boolean; begin with EditContainer do Result := (FocusedCellViewInfo = Self) and (DataController.FocusedRecordIndex = RecordIndex); end; function TcxEditCellViewInfo.GetInplaceEditPosition: TcxInplaceEditPosition; begin Result.Item := EditContainer; Result.RecordIndex := RecordIndex; end; function TcxEditCellViewInfo.GetMaxLineCount: Integer; begin Result := Control.Options.OptionsView.CellTextMaxLineCount; end; function TcxEditCellViewInfo.GetRecordIndex: Integer; begin Result := 0; end; function TcxEditCellViewInfo.GetSelectedTextColor: Integer; begin Result := $FFFFFF xor ColorToRgb(ViewParams.TextColor); end; function TcxEditCellViewInfo.GetSelectedBKColor: Integer; begin Result := $FFFFFF xor ColorToRgb(ViewParams.Color); end; function TcxEditCellViewInfo.GetViewInfoData: Pointer; begin Result := Pointer(RecordIndex); end; function TcxEditCellViewInfo.IsAutoHeight: Boolean; begin Result := Control.Options.OptionsView.CellAutoHeight; end; function TcxEditCellViewInfo.IsEndEllipsis: Boolean; begin Result := Control.Options.OptionsView.CellEndEllipsis; end; function TcxEditCellViewInfo.IsSupportedHotTrack: Boolean; begin Result := not Control.IsDesigning and (esoHotTrack in Properties.GetSupportedOperations) and ViewData.Style.LookAndFeel.Painter.IsButtonHotTrack; end; procedure TcxEditCellViewInfo.SetBounds(const ABounds: TRect; const ADisplayRect: TRect); begin CheckClipping(ABounds, ADisplayRect); DoCalculate; end; function TcxEditCellViewInfo.GetTransparent: Boolean; begin Result := ViewInfo.Transparent or CellTransparent; end; procedure TcxEditCellViewInfo.SetTransparent(Value: Boolean); begin CellTransparent := Value; ViewInfo.Transparent := Value; end; { TcxCustomControlPainter } constructor TcxCustomControlPainter.Create( AOwner: TcxEditingControl); begin FControl := AOwner; FCanvas := FControl.Canvas; end; destructor TcxCustomControlPainter.Destroy; begin FBitmap.Free; FBitmapCanvas.Free; inherited Destroy; end; procedure TcxCustomControlPainter.Paint; var ACanvas: TcxCanvas; begin ACanvas := FCanvas; if not Canvas.RectVisible(ViewInfo.ClientRect) then Exit; try if Buffered then begin FBitmap.Width := FControl.Width; FBitmap.Height := FControl.Height; if not Control.IsLayoutChanged then FBitmapCanvas.SetClipRegion(FCanvas.GetClipRegion, roSet) else begin FBitmapCanvas.SetClipRegion(TcxRegion.Create(ViewInfo.ClientRect), roSet); Control.IsLayoutChanged := False; end; FCanvas := FBitmapCanvas; end; DoPaint; finally FCanvas := ACanvas; if Buffered then Canvas.Draw(0, 0, FBitmap); end; end; procedure TcxCustomControlPainter.AfterCustomDraw( AViewInfo: TcxCustomViewInfoItem); begin AViewInfo.ItemViewParams := FSaveViewParams; // synchronize EditViewInfo with ViewParams if AViewInfo is TcxEditCellViewInfo then with TcxEditCellViewInfo(AViewInfo).EditViewInfo do begin Font := FSaveViewParams.Font; TextColor := FSaveViewParams.TextColor; BackgroundColor := FSaveViewParams.Color; end; end; procedure TcxCustomControlPainter.BeforeCustomDraw(AViewInfo: TcxCustomViewInfoItem); begin with AViewInfo do begin FSaveViewParams := ItemViewParams; cxApplyViewParams(Canvas, ItemViewParams); ItemViewParams.Font := Canvas.Font; end; if AViewInfo is TcxEditCellViewInfo then TcxEditCellViewInfo(AViewInfo).EditViewInfo.Font := AViewInfo.ItemViewParams.Font; end; function TcxCustomControlPainter.DoCustomDraw( AViewInfoItem: TcxCustomViewInfoItem; AEvent: TcxCustomDrawViewInfoItemEvent): Boolean; begin if (AViewInfoItem <> nil) and AViewInfoItem.Visible and Canvas.RectVisible(AViewInfoItem.VisibleRect) then begin Result := False; if Assigned(AEvent) then begin // BeforeCustomDraw(AViewInfoItem); AEvent(Control, Canvas, AViewInfoItem, Result); // AfterCustomDraw(AViewInfoItem); end; end else Result := True; end; procedure TcxCustomControlPainter.DoPaintEditCell( ACellViewInfo: TcxEditCellViewInfo; AIsExcludeRect: Boolean = True); begin if not DoCustomDraw(ACellViewInfo, Control.OnCustomDrawCell) then ACellViewInfo.ViewInfo.PaintEx(Canvas); if AIsExcludeRect then Canvas.ExcludeClipRect(ACellViewInfo.ClipRect); end; procedure TcxCustomControlPainter.DoPaint; begin with ViewInfo do begin FCanvas.Brush.Assign(Brush); FCanvas.FillRect(ClientRect); end; end; procedure TcxCustomControlPainter.SetBuffered(Value: Boolean); begin if Value <> FBuffered then begin FBuffered := Value; if not Value then begin FreeAndNil(FBitmap); FreeAndNil(FBitmapCanvas); end else begin FBitmap := TBitmap.Create; FBitmapCanvas := TcxCanvas.Create(FBitmap.Canvas); end; if ViewInfo <> nil then ViewInfo.Invalidate; end; end; function TcxCustomControlPainter.GetPainter: TcxCustomLookAndFeelPainterClass; begin Result := Control.LookAndFeelPainter; end; function TcxCustomControlPainter.GetViewInfo: TcxCustomControlViewInfo; begin Result := Control.FViewInfo; end; { TcxCustomControlStyles } constructor TcxCustomControlStyles.Create(AOwner: TPersistent); begin inherited Create(AOwner); FDefaultStyle := TcxStyle.Create(nil); end; destructor TcxCustomControlStyles.Destroy; begin FDefaultStyle.Free; inherited Destroy; end; procedure TcxCustomControlStyles.Assign(Source: TPersistent); var I: Integer; begin if Source is TcxCustomControlStyles then begin for I := ecs_Content to ecs_Selection do SetValue(I, TcxCustomControlStyles(Source).GetValue(I)); end; inherited Assign(Source); Changed(ecs_Content); end; function TcxCustomControlStyles.GetBackgroundParams: TcxViewParams; begin GetViewParams(ecs_Background, nil, nil, Result); end; function TcxCustomControlStyles.GetSelectionParams: TcxViewParams; const AStyleIndexes: array[Boolean] of Integer = (ecs_Inactive, ecs_Selection); begin GetViewParams(AStyleIndexes[Control.Controller.Focused or Control.IsFocused], nil, nil, Result); end; procedure TcxCustomControlStyles.Changed(AIndex: Integer); begin inherited Changed(AIndex); if GetOwner is TcxEditingControl then Control.UpdateViewStyles; end; function TcxCustomControlStyles.GetDefaultStyle(Index: Integer; AData: Pointer): TcxStyle; var AParams: TcxViewParams; begin GetDefaultViewParams(Index, AData, AParams); with FDefaultStyle do begin Color := AParams.Color; Font := AParams.Font; TextColor := AParams.TextColor; // todo: enumeration names equal cxStyles. and cxEditors AssignedValues := [cxStyles.svColor, cxStyles.svFont, cxStyles.svTextColor]; end; Result := FDefaultStyle; end; procedure TcxCustomControlStyles.GetDefaultViewParams( Index: Integer; AData: TObject; out AParams: TcxViewParams); begin inherited GetDefaultViewParams(Index, AData, AParams); with AParams, LookAndFeelPainter do begin Bitmap := nil; Font := Control.Font; case Index of ecs_Background, ecs_Content: begin Color := DefaultContentColor; TextColor := DefaultContentTextColor; end; ecs_Selection: begin Color := DefaultSelectionColor; TextColor := DefaultSelectionTextColor; end; ecs_Inactive: begin Color := DefaultInactiveColor; TextColor := DefaultInactiveTextColor; end; else inherited GetDefaultViewParams(Index, AData, AParams); end; end; end; function TcxCustomControlStyles.GetControl: TcxEditingControl; begin Result := TcxEditingControl(GetOwner); end; function TcxCustomControlStyles.GetPainter: TcxCustomLookAndFeelPainterClass; begin Result := Control.LookAndFeelPainter; end; { TcxEditingControl } constructor TcxEditingControl.Create(AOwner: TComponent); begin inherited Create(AOwner); FContainerList := TList.Create; CreateSubClasses; Keys := [kArrows, kChars]; BorderStyle := cxcbsDefault; DragCursor := crDefault; end; destructor TcxEditingControl.Destroy; begin DestroyDesignSelectionHelper; EndMouseTracking(Self); DestroySubClasses; FreeAndNil(FContainerList); inherited Destroy; end; procedure TcxEditingControl.BeginUpdate; begin DoBeginUpdate; end; procedure TcxEditingControl.BeginDragAndDrop; begin Controller.BeginDragAndDrop; inherited; end; procedure TcxEditingControl.CancelUpdate; begin DataController.EndUpdate; Dec(FLockUpdate); end; procedure TcxEditingControl.EndUpdate; begin DoEndUpdate; end; function TcxEditingControl.ExecuteAction(Action: TBasicAction): Boolean; begin Result := inherited ExecuteAction(Action) or DataController.ExecuteAction(Action); end; procedure TcxEditingControl.DragDrop(Source: TObject; X, Y: Integer); begin Controller.DragDrop(Source, X, Y); inherited DragDrop(Source, X, Y); end; procedure TcxEditingControl.LayoutChanged; begin if ViewInfo <> nil then ViewInfo.IsDirty := True; if IsLocked then Exit; Inc(FChangesCount); Controller.Reset; BeginUpdate; try DoLayoutChanged; finally ViewInfo.IsDirty := False; CancelUpdate; SetInternalControlsBounds; //TODO: need validation scrollbars visible UpdateScrollBars; Dec(FChangesCount); if FChangesCount = 0 then begin Controller.HitTestController.ReCalculate; Controller.EditingController.PostEditUpdate; FIsLayoutChanged := True; AfterLayoutChanged; Invalidate; end; end; end; function TcxEditingControl.UpdateAction(Action: TBasicAction): Boolean; begin Result := inherited UpdateAction(Action) or DataController.UpdateAction(Action); end; procedure TcxEditingControl.AfterLayoutChanged; begin end; procedure TcxEditingControl.BeginAutoDrag; begin Controller.HideHint; if Controller.IsEditing then Controller.EditingController.HideEdit(True); // ControlState := ControlState - [csLButtonDown]; BeginDrag(False, Mouse.DragThreshold); // ControlState := ControlState + [csLButtonDown]; end; procedure TcxEditingControl.BeforeUpdate; begin end; procedure TcxEditingControl.CheckCreateDesignSelectionHelper; begin if (FDesignSelectionHelper = nil) and (cxDesignSelectionHelperClass <> nil) and IsDesigning then FDesignSelectionHelper := cxDesignSelectionHelperClass.Create(Self); end; procedure TcxEditingControl.CreateSubClasses; begin FStyles := GetControlStylesClass.Create(Self); FBrushCache := TcxBrushCache.Create; FEditStyle := GetEditStyleClass.Create(nil, True); FEditStyle.LookAndFeel.MasterLookAndFeel := LookAndFeel; FController := GetControllerClass.Create(Self); FDataController := GetDataControllerClass.Create(Self); RecreateViewInfo; end; procedure TcxEditingControl.ControlUpdateData(AInfo: TcxUpdateControlInfo); begin if AInfo is TcxDataChangedInfo then DataChanged else if AInfo is TcxLayoutChangedInfo then DataLayoutChanged else if AInfo is TcxFocusedRecordChangedInfo then with TcxFocusedRecordChangedInfo(AInfo) do begin // need use row index instead of record index Controller.FocusedRecordChanged(PrevFocusedRowIndex, FocusedRowIndex); Controller.Navigator.Refresh; end else if AInfo is TcxSelectionChangedInfo then SelectionChanged(TcxSelectionChangedInfo(AInfo)) else if AInfo is TcxUpdateRecordInfo then Controller.UpdateRecord(TcxUpdateRecordInfo(AInfo).RecordIndex); end; procedure TcxEditingControl.DataChanged; var I: Integer; begin Inc(FLockUpdate); try for I := 0 to FContainerList.Count - 1 do TcxCustomInplaceEditContainer(FContainerList.List^[I]).DataChanged; finally Dec(FLockUpdate); if not IsLocked then Controller.RefreshFocusedRecord; end; end; procedure TcxEditingControl.DataLayoutChanged; begin Controller.EditingController.UpdateEditValue; Controller.RefreshFocusedRecord; end; procedure TcxEditingControl.DestroyDesignSelectionHelper; begin FreeAndNil(FDesignSelectionHelper); end; procedure TcxEditingControl.DestroySubClasses; begin FreeAndNil(FViewInfo); FreeAndNil(FBrushCache); FreeAndNil(FController); FreeAndNil(FEditStyle); FreeAndNil(FDataController); FreeAndNil(FStyles); end; procedure TcxEditingControl.DoBeginUpdate; begin Inc(FLockUpdate); DataController.BeginUpdate; end; procedure TcxEditingControl.DoEndUpdate; begin DataController.EndUpdate; Dec(FLockUpdate); if FLockUpdate = 0 then BeforeUpdate; LayoutChanged; end; procedure TcxEditingControl.DoEditChanged( AItem: TcxCustomInplaceEditContainer); begin if Assigned(FOnEditChanged) then FOnEditChanged(Self, AItem); end; procedure TcxEditingControl.DoEdited( AItem: TcxCustomInplaceEditContainer); begin if Assigned(FOnEdited) then FOnEdited(Self, AItem); end; function TcxEditingControl.DoEditing( AItem: TcxCustomInplaceEditContainer): Boolean; begin Result := True; if Assigned(FOnEditing) then FOnEditing(Self, AItem, Result); end; procedure TcxEditingControl.DoEditValueChanged( AItem: TcxCustomInplaceEditContainer); begin if Assigned(FOnEditValueChanged) then FOnEditValueChanged(Self, AItem); end; procedure TcxEditingControl.DoGetCellHint(ACell: TObject; var AText: string; var ANeedShow: Boolean); begin end; procedure TcxEditingControl.DoInitEdit( AItem: TcxCustomInplaceEditContainer; AEdit: TcxCustomEdit); begin if Assigned(FOnInitEdit) then FOnInitEdit(Self, AItem, AEdit); end; procedure TcxEditingControl.DoInplaceEditContainerItemAdded( AItem: TcxCustomInplaceEditContainer); begin try with DataController do begin FContainerList.Add(AItem); UpdateIndexes; AddItem(AItem); end; finally LayoutChanged; end; end; procedure TcxEditingControl.DoInplaceEditContainerItemRemoved( AItem: TcxCustomInplaceEditContainer); begin try FContainerList.Remove(AItem); DataController.RemoveItem(AItem); UpdateIndexes; finally LayoutChanged; end; end; procedure TcxEditingControl.DoLayoutChanged; begin ViewInfo.Calculate; end; function TcxEditingControl.GetControllerClass: TcxCustomControlControllerClass; begin Result := TcxCustomControlController; end; function TcxEditingControl.GetControlStylesClass: TcxCustomControlStylesClass; begin Result := TcxCustomControlStyles; end; function TcxEditingControl.GetDataControllerClass: TcxCustomDataControllerClass; begin Result := TcxControlDataController; end; function TcxEditingControl.GetDragImageHelperClass: TcxDragImageHelperClass; begin Result := TcxDragImageHelper; end; function TcxEditingControl.GetEditStyleClass: TcxCustomEditStyleClass; begin Result := TcxEditStyle; end; function TcxEditingControl.GetEditingControllerClass: TcxEditingControllerClass; begin Result := TcxEditingController; end; function TcxEditingControl.GetHitTestControllerClass: TcxHitTestControllerClass; begin Result := TcxCustomHitTestController; end; function TcxEditingControl.GetHotTrackControllerClass: TcxHotTrackControllerClass; begin Result := TcxHotTrackController; end; function TcxEditingControl.GetViewInfoClass: TcxCustomControlViewInfoClass; begin Result := TcxCustomControlViewInfo; end; function TcxEditingControl.GetOptions: IcxEditingControlOptions; begin cxAbstractError; end; function TcxEditingControl.GetPainterClass: TcxCustomControlPainterClass; begin Result := TcxCustomControlPainter; end; function TcxEditingControl.IsLocked: Boolean; begin Result := (FLockUpdate <> 0) or IsLoading or IsDestroying or not HandleAllocated; end; procedure TcxEditingControl.InvalidateRectEx( const R: TRect; EraseBackground: Boolean); begin InvalidateRect(R, EraseBackground); end; procedure TcxEditingControl.RecreateViewInfo; begin if Controller <> nil then begin Controller.EditingController.EditingItem := nil; Controller.Clear; FreeAndNil(FViewInfo); FViewInfo := GetViewInfoClass.Create(Self); end else begin FreeAndNil(FViewInfo); FViewInfo := GetViewInfoClass.Create(Self); end; end; procedure TcxEditingControl.SelectionChanged(AInfo: TcxSelectionChangedInfo); begin end; procedure TcxEditingControl.UpdateIndexes; var I: Integer; begin for I := 0 to FContainerList.Count - 1 do TcxCustomInplaceEditContainer(FContainerList.List^[I]).FItemIndex := I; end; procedure TcxEditingControl.UpdateViewStyles; begin if ViewInfo <> nil then ViewInfo.State[cvis_StyleInvalid] := True; LayoutChanged; end; procedure TcxEditingControl.UpdateData; begin Controller.EditingController.UpdateValue; end; procedure TcxEditingControl.AlignControls(AControl: TControl; var Rect: TRect); begin if not (AControl is TcxCustomEdit) then inherited AlignControls(AControl, Rect); end; procedure TcxEditingControl.CreateParams(var Params: TCreateParams); begin inherited CreateParams(Params); with Params do WindowClass.style := WindowClass.style and not (CS_HREDRAW or CS_VREDRAW); end; procedure TcxEditingControl.CreateWnd; begin DestroyDesignSelectionHelper; inherited CreateWnd; CheckCreateDesignSelectionHelper; end; procedure TcxEditingControl.DestroyWnd; begin DestroyDesignSelectionHelper; inherited DestroyWnd; end; procedure TcxEditingControl.DoExit; begin if Controller <> nil then Controller.DoExit; inherited DoExit; end; procedure TcxEditingControl.DblClick; begin Controller.DblClick; inherited DblClick; end; procedure TcxEditingControl.KeyDown(var Key: Word; Shift: TShiftState); begin Controller.FDragCancel := Key = VK_ESCAPE; try inherited KeyDown(Key, Shift); Controller.KeyDown(Key, Shift); finally Controller.FDragCancel := False; end; end; procedure TcxEditingControl.FocusChanged; begin inherited FocusChanged; if not IsDestroying then Controller.FocusChanged; end; procedure TcxEditingControl.KeyPress(var Key: Char); begin inherited KeyPress(Key); Controller.KeyPress(Key); end; procedure TcxEditingControl.KeyUp(var Key: Word; Shift: TShiftState); begin inherited KeyUp(Key, Shift); Controller.KeyUp(Key, Shift); end; procedure TcxEditingControl.Loaded; begin inherited Loaded; DataController.Loaded; LayoutChanged; CheckCreateDesignSelectionHelper; end; procedure TcxEditingControl.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin with Controller do begin HideHint; LockShowHint := True; BeforeMouseDown(Button, Shift, X, Y); inherited MouseDown(Button, Shift, X, Y); HitTestController.RecalculateOnMouseEvent(X, Y, Shift); if not EditingController.IsErrorOnEditExit then DoMouseDown(Button, Shift, X, Y); end; end; procedure TcxEditingControl.MouseMove(Shift: TShiftState; X, Y: Integer); begin inherited MouseMove(Shift, X, Y); Controller.HitTestController.RecalculateOnMouseEvent(X, Y, Shift); if DragAndDropState = ddsNone then //??? Controller.DoMouseMove(Shift, X, Y); end; procedure TcxEditingControl.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin Controller.LockShowHint := False; Controller.HitTestController.RecalculateOnMouseEvent(X, Y, Shift); if DragAndDropState = ddsNone then begin Controller.DoMouseUp(Button, Shift, X, Y); inherited MouseUp(Button, Shift, X, Y); end else begin inherited MouseUp(Button, Shift, X, Y); Controller.DoMouseUp(Button, Shift, X, Y); end; Controller.PostShowEdit; end; procedure TcxEditingControl.MouseEnter(AControl: TControl); begin inherited MouseEnter(AControl); BeginMouseTracking(Self, Bounds, Self); Controller.MouseEnter; end; procedure TcxEditingControl.MouseLeave(AControl: TControl); begin EndMouseTracking(Self); Controller.MouseLeave; inherited MouseLeave(AControl); end; procedure TcxEditingControl.Paint; begin Controller.BeforePaint; try inherited Paint; Painter.Paint; finally Controller.AfterPaint; end; end; procedure TcxEditingControl.WndProc(var Message: TMessage); begin if Controller <> nil then Controller.WndProc(Message); inherited WndProc(Message); end; procedure TcxEditingControl.AfterMouseDown(AButton: TMouseButton; X, Y: Integer); begin FDragPos := cxPoint(X, Y); inherited AfterMouseDown(AButton, X, Y); end; procedure TcxEditingControl.BoundsChanged; begin LayoutChanged; inherited BoundsChanged; end; function TcxEditingControl.CanDrag(X, Y: Integer): Boolean; begin if Controller <> nil then Result := Controller.CanDrag(X, Y) else Result := False; end; procedure TcxEditingControl.DoCancelMode; begin inherited DoCancelMode; Controller.DoCancelMode; end; procedure TcxEditingControl.FontChanged; begin inherited FontChanged; UpdateViewStyles; end; function TcxEditingControl.GetCursor(X, Y: Integer): TCursor; begin Result := Controller.GetCursor(X, Y); if Result = crDefault then Result := inherited GetCursor(X, Y); end; function TcxEditingControl.GetDesignHitTest( X, Y: Integer; Shift: TShiftState): Boolean; begin Result := Controller.HitTestController.AllowDesignMouseEvents(X, Y, Shift); end; function TcxEditingControl.GetIsFocused: Boolean; begin Result := inherited GetIsFocused or Controller.HasFocusedControls; end; function TcxEditingControl.GetMouseWheelScrollingKind: TcxMouseWheelScrollingKind; begin Result := inherited GetMouseWheelScrollingKind; if Result = mwskNone then Result := Controller.GetMouseWheelScrollingKind; end; procedure TcxEditingControl.InitControl; begin inherited InitControl; LayoutChanged; end; function TcxEditingControl.IsPixelScrollBar(AKind: TScrollBarKind): Boolean; begin Result := Controller.IsPixelScrollBar(AKind); end; procedure TcxEditingControl.LookAndFeelChanged(Sender: TcxLookAndFeel; AChangedValues: TcxLookAndFeelValues); var I: Integer; AIsEditing: Boolean; begin AIsEditing := (Controller <> nil) and Controller.IsEditing; if AIsEditing then Controller.EditingController.HideEdit(True); inherited LookAndFeelChanged(Sender, AChangedValues); BeginUpdate; try for I := 0 to FContainerList.Count - 1 do TcxCustomInplaceEditContainer(FContainerList[I]).InternalPropertiesChanged; finally UpdateViewStyles; EndUpdate; if AIsEditing then Controller.EditingController.ShowEdit; end; end; function TcxEditingControl.MayFocus: Boolean; begin Result := inherited MayFocus; if Controller <> nil then Result := Result and Controller.MayFocus; end; // drag'n'drop procedure TcxEditingControl.DoEndDrag(Target: TObject; X, Y: Integer); begin Controller.EndDrag(Target, X, Y); inherited DoEndDrag(Target, X, Y); Controller.LockShowHint := False; Controller.PostShowEdit; FinishDragImages; FDragPos := cxNullPoint; end; procedure TcxEditingControl.DoStartDrag(var DragObject: TDragObject); begin Controller.HitTestController.HitPoint := FDragPos; Controller.BeforeStartDrag; inherited DoStartDrag(DragObject); Controller.StartDrag(DragObject); FinishDragImages; if HasDragDropImages then begin FDragHelper := GetDragImageHelperClass.Create(Self, FDragPos); cxInstallMouseHookForDragControl(Self); end; end; procedure TcxEditingControl.DragOver(Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); begin inherited DragOver(Source, X, Y, State, Accept); Controller.DragOver(Source, X, Y, State, Accept); end; function TcxEditingControl.DragDropImageDisplayRect: TRect; begin Result := cxNullRect; end; procedure TcxEditingControl.DrawDragDropImage( ADragBitmap: TBitmap; ACanvas: TcxCanvas); begin end; procedure TcxEditingControl.FinishDragImages; begin if FDragHelper <> nil then begin cxResetMouseHookForDragControl; FreeAndNil(FDragHelper); end; end; function TcxEditingControl.HasDragDropImages: Boolean; begin Result := Options.OptionsBehavior.DragDropText; end; // scrollbars procedure TcxEditingControl.InitScrollBarsParameters; begin if Controller <> nil then Controller.InitScrollBarsParameters; end; procedure TcxEditingControl.Scroll(AScrollBarKind: TScrollBarKind; AScrollCode: TScrollCode; var AScrollPos: Integer); begin Controller.EditingController.PostEditUpdate; Controller.Scroll(AScrollBarKind, AScrollCode, AScrollPos); end; procedure TcxEditingControl.DragAndDrop(const P: TPoint; var Accepted: Boolean); begin inherited DragAndDrop(P, Accepted); Controller.DragAndDrop(P, Accepted); end; procedure TcxEditingControl.EndDragAndDrop(Accepted: Boolean); begin inherited EndDragAndDrop(Accepted); Controller.EndDragAndDrop(Accepted); FDragPos := cxNullPoint; end; function TcxEditingControl.GetDragAndDropObjectClass: TcxDragAndDropObjectClass; begin Result := Controller.GetDragAndDropObjectClass; end; function TcxEditingControl.StartDragAndDrop(const P: TPoint): Boolean; begin Result := Controller.StartDragAndDrop(P); if Result then Controller.HideHint; end; function TcxEditingControl.GetBufferedPaint: Boolean; begin Result := GetPainter.Buffered; end; function TcxEditingControl.GetPainter: TcxCustomControlPainter; begin Result := ViewInfo.FPainter; end; procedure TcxEditingControl.DoMouseLeave; begin MouseLeave(Self); end; procedure TcxEditingControl.SetBufferedPaint(Value: Boolean); begin Painter.Buffered := Value; end; procedure TcxEditingControl.SetEditStyle(Value: TcxCustomEditStyle); begin FEditStyle.Assign(Value); end; procedure TcxEditingControl.SetStyles(Value: TcxCustomControlStyles); begin FStyles.Assign(Value); end; procedure TcxEditingControl.WMCancelMode(var Message: TWMCancelMode); begin Controller.FDragCancel := True; try inherited; finally Controller.FDragCancel := False; end; end; procedure TcxEditingControl.WMSetCursor(var Message: TWMSetCursor); var P: TPoint; begin GetCursorPos(P); P := ScreenToClient(P); with Controller.HitTestController do begin if IsDesigning and (DragAndDropState = ddsNone) and AllowDesignMouseEvents(P.X, P.Y, [ssLeft]) then SetCursor(Screen.Cursors[GetCurrentCursor]) else inherited; end; end; { TcxExtEditingControl } procedure TcxExtEditingControl.CreateSubClasses; begin FOptionsBehavior := GetOptionsBehaviorClass.Create(Self); FOptionsData := GetOptionsDataClass.Create(Self); FOptionsView := GetOptionsViewClass.Create(Self); inherited CreateSubClasses; end; procedure TcxExtEditingControl.DestroySubClasses; begin inherited DestroySubClasses; FOptionsBehavior.Free; FOptionsData.Free; FOptionsView.Free; end; function TcxExtEditingControl.GetOptions: IcxEditingControlOptions; begin Result := Self; end; function TcxExtEditingControl.GetOptionsBehaviorClass: TcxControlOptionsBehaviorClass; begin Result := TcxControlOptionsBehavior; end; function TcxExtEditingControl.GetOptionsDataClass: TcxControlOptionsDataClass; begin Result := TcxControlOptionsData; end; function TcxExtEditingControl.GetOptionsViewClass: TcxControlOptionsViewClass; begin Result := TcxControlOptionsView; end; function TcxExtEditingControl.GetOptionsBehavior: TcxControlOptionsBehavior; begin Result := FOptionsBehavior; end; function TcxExtEditingControl.GetOptionsData: TcxControlOptionsData; begin Result := FOptionsData; end; function TcxExtEditingControl.GetOptionsView: TcxControlOptionsView; begin Result := FOptionsView; end; procedure TcxExtEditingControl.SetOptionsBehavior( Value: TcxControlOptionsBehavior); begin FOptionsBehavior.Assign(Value); end; procedure TcxExtEditingControl.SetOptionsData( Value: TcxControlOptionsData); begin FOptionsData.Assign(Value); end; procedure TcxExtEditingControl.SetOptionsView( Value: TcxControlOptionsView); begin FOptionsView.Assign(Value); end; { TcxValueTypeClassRepository } constructor TcxValueTypeClassRepository.Create; begin FList := TStringList.Create; end; destructor TcxValueTypeClassRepository.Destroy; begin FList.Free; inherited Destroy; end; function TcxValueTypeClassRepository.FindByClassType(ATypeClass: TcxValueTypeClass): string; var I: Integer; begin I := FList.IndexOfObject(TObject(ATypeClass)); if I >= 0 then Result := FList[I] else Result := ''; end; function TcxValueTypeClassRepository.FindByDescription(const ADescription: string): TcxValueTypeClass; var I: Integer; begin I := FList.IndexOf(ADescription); if I >= 0 then Result := TcxValueTypeClass(FList.Objects[I]) else Result := nil; end; procedure TcxValueTypeClassRepository.RegisterValueTypeClass(const ADescription: string; ATypeClass: TcxValueTypeClass); begin if FList.IndexOfObject(TObject(ATypeClass)) < 0 then FList.AddObject(ADescription, TObject(ATypeClass)); end; procedure TcxValueTypeClassRepository.UnRegisterValueTypeClass(ATypeClass: TcxValueTypeClass); var I: Integer; begin I := FList.IndexOfObject(TObject(ATypeClass)); if I >= 0 then FList.Delete(I); end; function TcxValueTypeClassRepository.GetCount: Integer; begin Result := FList.Count; end; function TcxValueTypeClassRepository.GetValueTypeClass(AIndex: Integer): TcxValueTypeClass; begin Result := TcxValueTypeClass(FList.Objects[AIndex]); end; function TcxValueTypeClassRepository.GetDescription(AIndex: Integer): string; begin Result := FList[AIndex]; end; function cxieValueTypeClassRepository: TcxValueTypeClassRepository; begin Result := ValueTypeClassRepository; end; procedure cxieRegisterValueTypeClass( const ADescription: string; ATypeClass: TcxValueTypeClass); begin ValueTypeClassRepository.RegisterValueTypeClass(ADescription, ATypeClass); end; procedure cxieUnRegisterValueTypeClass(ATypeClass: TcxValueTypeClass); begin ValueTypeClassRepository.UnRegisterValueTypeClass(ATypeClass); end; function cxPtInViewInfoItem(AItem: TcxCustomViewInfoItem; const APoint: TPoint): Boolean; begin Result := (AItem <> nil) and AItem.Visible and cxRectPtIn(AItem.ClipRect, APoint); end; procedure RegisterDefaultValueTypeClasses; begin cxieRegisterValueTypeClass('Boolean', TcxBooleanValueType); cxieRegisterValueTypeClass('String', TcxStringValueType); cxieRegisterValueTypeClass('Integer', TcxIntegerValueType); cxieRegisterValueTypeClass('Currency', TcxCurrencyValueType); cxieRegisterValueTypeClass('Float', TcxFloatValueType); cxieRegisterValueTypeClass('DateTime', TcxDateTimeValueType); cxieRegisterValueTypeClass('Variant', TcxVariantValueType); end; procedure cxStylesToViewParams(AMasterStyles: TcxCustomControlStyles; AIndex: Integer; AData: Pointer; const AStyles: array of TcxStyle; out AParams: TcxViewParams); var I: Integer; IsColorAssigned, IsFontAssigned, IsFontColorAssigned, IsBitmapAssigned: Boolean; function NeedValueAssign(var AFlag: Boolean; IsValueAssigned: Boolean): Boolean; begin Result := not AFlag and IsValueAssigned; if Result then AFlag := True; end; function AssignStyle(AStyle: TcxStyle): Boolean; begin Result := False; if not Assigned(AStyle) or (csDestroying in AStyle.ComponentState) then Exit; with AStyle do begin if NeedValueAssign(IsColorAssigned, cxStyles.svColor in AssignedValues) then AParams.Color := Color; if NeedValueAssign(IsFontAssigned, cxStyles.svFont in AssignedValues) then AParams.Font := Font; if NeedValueAssign(IsFontColorAssigned, cxStyles.svTextColor in AssignedValues) then AParams.TextColor := TextColor; if NeedValueAssign(IsBitmapAssigned, cxStyles.svBitmap in AssignedValues) then AParams.Bitmap := Bitmap; end; Result := IsFontColorAssigned and IsFontAssigned and IsColorAssigned and IsBitmapAssigned; end; procedure AssignDefaultViewParams; var ADefParams: TcxViewParams; begin AMasterStyles.GetDefaultViewParams(AIndex, AData, ADefParams); if not IsColorAssigned then AParams.Color := ADefParams.Color; if not IsFontAssigned then AParams.Font := ADefParams.Font; if not IsFontColorAssigned then AParams.TextColor := ADefParams.TextColor; if not IsBitmapAssigned then AParams.Bitmap := ADefParams.Bitmap; end; begin IsColorAssigned := False; IsFontAssigned := False; IsFontColorAssigned := False; IsBitmapAssigned := False; FillChar(AParams, SizeOf(AParams), 0); for I := Low(AStyles) to High(AStyles) do if AssignStyle(AStyles[I]) then Exit; AssignDefaultViewParams; end; function cxInRange(Value: Integer; AMin, AMax: Integer): Boolean; begin Result := (Value >= AMin) and (Value <= AMax); end; function cxRange(var Value: Integer; AMin, AMax: Integer): Boolean; begin Result := (Value >= AMin) and (Value <= AMax); if not Result then begin if Value < AMin then Value := AMin else Value := AMax end; end; function cxSetValue(Condition: Boolean; ATrueValue, AFalseValue: Integer): Integer; begin if Condition then Result := ATrueValue else Result := AFalseValue; end; function cxConfirmMessageBox(const AText, ACaption: string): Boolean; begin Result := Application.MessageBox(PChar(AText), PChar(ACaption), MB_ICONQUESTION or MB_OKCANCEL) = ID_OK end; initialization ValueTypeClassRepository := TcxValueTypeClassRepository.Create; RegisterDefaultValueTypeClasses; finalization cxResetMouseHookForDragControl; FreeAndNil(ValueTypeClassRepository); end.